diff -u --recursive --new-file v1.3.18/linux/CREDITS linux/CREDITS --- v1.3.18/linux/CREDITS Sun Aug 13 14:45:27 1995 +++ linux/CREDITS Tue Aug 15 07:39:03 1995 @@ -708,7 +708,6 @@ N: David C. Niemi E: niemidc@clark.net -E: niemidc@slma.com D: FSSTND, The XFree86 Project D: DMA memory support, floppy driver S: 2364 Old Trail Drive @@ -943,6 +942,10 @@ S: Schleiermacherstrasse 12 S: 90491 Nuernberg S: Germany + +N: Dirk Verworner +D: Co-author of german book ``Linux-Kernel-Programmierung'' +D: Co-founder of Berlin Linux User Group N: Patrick Volkerding E: volkerdi@ftp.cdrom.com diff -u --recursive --new-file v1.3.18/linux/Configure linux/Configure --- v1.3.18/linux/Configure Thu Dec 29 19:58:40 1994 +++ linux/Configure Thu Jan 1 02:00:00 1970 @@ -1,147 +0,0 @@ -#! /bin/sh -# -# This script is used to configure the linux kernel. -# -# It was inspired by the challenge in the original Configure script -# to ``do something better'', combined with the actual need to ``do -# something better'' because the old configure script wasn't flexible -# enough. -# -# Please send comments / questions / bug fixes to raymondc@microsoft.com. -# -# Each line in the config file is a command. -# -# 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13 -# with an empty IFS. - -# -# Make sure we're really running bash. -# -# I would really have preferred to write this script in a language with -# better string handling, but alas, bash is the only scripting language -# that I can be reasonable sure everybody has on their linux machine. -# -[ -z "$BASH" ] && { echo "Configure requires bash" 1>&2; exit 1; } - -# Disable filename globbing once and for all. -# Enable function cacheing. -set -f -h - -# -# readln reads a line into $ans. -# -# readln prompt default -# -function readln () { - if [ "$DEFAULT" = "-d" ]; then - echo "$1" - ans=$2 - else - echo -n "$1" - IFS='@' read ans >$CONFIG - (echo "" ; echo "/*"; echo " * $1" ; echo " */") >>$CONFIG_H -} - -# -# bool processes a boolean argument -# -# bool question define default -# -function bool () { - ans="" - def=$(eval echo "\${$2:-$3}") - while [ "$ans" != "y" -a "$ans" != "n" ]; do - readln "$1 ($2) [$def] " "$def" - done - if [ "$ans" = "y" ]; then - echo "$2=y" >>$CONFIG - echo "#define $2 1" >>$CONFIG_H - else - echo "# $2 is not set" >>$CONFIG - echo "#undef $2" >>$CONFIG_H - fi - eval "$2=$ans" -} - -# -# int processes an integer argument -# -# int question define default -# -function int () { - # Slimier hack to get bash to rescan a line. - ans="x" - def=$(eval echo "\${$2:-$3}") - while [ $[$ans+0] != "$ans" ]; do - readln "$1 ($2) [$def] " "$def" - done - echo "$2=$ans" >>$CONFIG - echo "#define $2 ($ans)" >>$CONFIG_H - eval "$2=$ans" -} - -CONFIG=.tmpconfig -CONFIG_H=.tmpconfig.h -trap "rm -f $CONFIG $CONFIG_H ; exit 1" 1 2 - -# -# Make sure we start out with a clean slate. -# -echo "#" > $CONFIG -echo "# Automatically generated make config: don't edit" >> $CONFIG -echo "#" >> $CONFIG - -echo "/*" > $CONFIG_H -echo " * Automatically generated C config: don't edit" >> $CONFIG_H -echo " */" >> $CONFIG_H - -DEFAULT="" -if [ "$1" = "-d" ] ; then - DEFAULT="-d" - shift -fi - -CONFIG_IN=./config.in -if [ "$1" != "" ] ; then - CONFIG_IN=$1 -fi - -if [ -f ./.config ] ; then - . ./.config - sed -e 's/# \(.*\) is not.*/\1=n/' <./.config >/tmp/conf.$$ - . /tmp/conf.$$ - rm /tmp/conf.$$ -fi -. $CONFIG_IN - -if [ "$CONFIG_SOUND" = "y" ] ; then - $MAKE -C drivers/sound config || exit 1 -fi - -rm -f .config.old -if [ -f .config ]; then - mv .config .config.old -fi -mv .tmpconfig .config -mv .tmpconfig.h include/linux/autoconf.h - -echo -echo "The linux kernel is now hopefully configured for your setup." -echo "Check the top-level Makefile for additional configuration," -echo "and do a 'make dep ; make clean' if you want to be sure all" -echo "the files are correctly re-made" -echo - -exit 0 diff -u --recursive --new-file v1.3.18/linux/Makefile linux/Makefile --- v1.3.18/linux/Makefile Sun Aug 13 14:45:27 1995 +++ linux/Makefile Tue Aug 15 19:33:16 1995 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 18 +SUBLEVEL = 19 ARCH = i386 @@ -11,10 +11,11 @@ else echo sh; fi ; fi) TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) +HPATH = $(TOPDIR)/include AS =as LD =ld -HOSTCC =gcc -I$(TOPDIR)/include -CC =gcc -D__KERNEL__ -I$(TOPDIR)/include +HOSTCC =gcc -I$(HPATH) +CC =gcc -D__KERNEL__ -I$(HPATH) MAKE =make CPP =$(CC) -E AR =ar @@ -106,10 +107,6 @@ include arch/$(ARCH)/Makefile -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c -o $*.o $< .S.s: $(CC) -D__ASSEMBLY__ -traditional -E -o $*.s $< .S.o: @@ -134,10 +131,10 @@ ( cd include ; ln -sf asm-$(ARCH) asm) oldconfig: symlinks - $(CONFIG_SHELL) Configure -d arch/$(ARCH)/config.in + $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in config: symlinks - $(CONFIG_SHELL) Configure arch/$(ARCH)/config.in + $(CONFIG_SHELL) scripts/Configure arch/$(ARCH)/config.in linuxsubdirs: dummy set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done @@ -152,22 +149,25 @@ fi include/linux/version.h: $(CONFIGURATION) Makefile newversion - @echo \#define UTS_RELEASE \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)\" > include/linux/version.h + @echo \#define UTS_RELEASE \"$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)\" > .ver @if [ -f .name ]; then \ echo \#define UTS_VERSION \"\#`cat .version`-`cat .name` `date`\"; \ else \ echo \#define UTS_VERSION \"\#`cat .version` `date`\"; \ - fi >> include/linux/version.h - @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> include/linux/version.h - @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> include/linux/version.h - @echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> include/linux/version.h + fi >> .ver + @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver + @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver + @echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> .ver @if [ -x /bin/dnsdomainname ]; then \ echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname`\"; \ - else \ + elif [ -x /bin/domainname ]; then \ echo \#define LINUX_COMPILE_DOMAIN \"`domainname`\"; \ - fi >> include/linux/version.h - @echo \#define LINUX_COMPILER \"`$(HOSTCC) -v 2>&1 | tail -1`\" >> include/linux/version.h - @echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> include/linux/version.h + else \ + echo \#define LINUX_COMPILE_DOMAIN ; \ + fi >> .ver + @echo \#define LINUX_COMPILER \"`$(HOSTCC) -v 2>&1 | tail -1`\" >> .ver + @echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver + if [ ! -f $@ ]; then mv .ver $@; fi init/version.o: init/version.c include/linux/version.h $(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c @@ -236,10 +236,11 @@ rm -f include/linux/autoconf.h include/linux/version.h rm -f drivers/sound/local.h rm -f drivers/scsi/aic7xxx_asm drivers/scsi/aic7xxx_seq.h - rm -f drivers/char/uni_hash_tbl.h drivers/char/conmakehash + rm -f drivers/char/uni_hash.tbl drivers/char/conmakehash rm -f .version .config* config.in config.old rm -f include/asm rm -f .depend `find . -name .depend -print` + rm -f .hdepend rm -f $(TOPDIR)/include/linux/modversions.h rm -f $(TOPDIR)/include/linux/modules/* @@ -251,10 +252,11 @@ cd .. && tar cf - linux | gzip -9 > backup.gz sync -depend dep: archdep +#depend dep: .hdepend +depend dep: archdep .hdepend touch include/linux/version.h - for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .tmpdepend - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i dep; done + awk -f scripts/depend.awk init/*.c > .tmpdepend + set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done rm -f include/linux/version.h mv .tmpdepend .depend ifdef CONFIG_MODVERSIONS @@ -275,7 +277,8 @@ @echo exit 1 -dummy: ..$(CONFIGURATION) +#dummy: ..$(CONFIGURATION) +dummy: else @@ -284,3 +287,12 @@ endif include Rules.make + +# +# This generates dependencies for the .h files. +# + +.hdepend: dummy + rm -f $@ + awk -f scripts/depend.awk `find $(HPATH) -name \*.h -print` > .$@ + mv .$@ $@ diff -u --recursive --new-file v1.3.18/linux/Rules.make linux/Rules.make --- v1.3.18/linux/Rules.make Thu Jul 13 16:20:19 1995 +++ linux/Rules.make Tue Aug 15 15:07:01 1995 @@ -3,10 +3,105 @@ # # +# False targets. +# +.PHONY: dummy + +# +# Special variables which should not be exported +# +unexport EXTRA_ASFLAGS +unexport EXTRA_CFLAGS +unexport EXTRA_LDFLAGS +unexport EXTRA_ARFLAGS +unexport SUBDIRS +unexport SUB_DIRS +unexport ALL_SUB_DIRS +unexport MOD_SUB_DIRS +unexport O_TARGET +unexport O_OBJS +unexport L_OBJS +unexport M_OBJS +unexport MOD_LIST_NAME + +# +# Get things started. +# +first_rule: sub_dirs $(O_TARGET) $(L_TARGET) + +# # Common rules # .c.s: - $(CC) $(CFLAGS) -S $< -o $@ + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -S $< -o $@ + +.c.o: + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< + +.s.o: + $(AS) $(ASFLAGS) $(EXTRA_CFLAGS) -o $@ $< + +# +# Rule to compile a set of .o files into one .o file +# +ifdef O_TARGET +$(O_TARGET): $(O_OBJS) +ifdef O_OBJS + $(LD) $(EXTRA_LDFLAGS) -r -o $@ $(O_OBJS) +else + $(AR) rcs $@ +endif +endif + +# +# Rule to compile a set of .o files into one .a file +# +ifdef L_TARGET +$(L_TARGET): $(L_OBJS) + rm -f $@ + $(AR) $(EXTRA_ARFLAGS) rcs $@ $(L_OBJS) +endif + +# +# This make dependencies quickly +# +fastdep: dummy + if [ -n "$(wildcard *.[chS])" ]; then \ + awk -f $(TOPDIR)/scripts/depend.awk *.[chS] > .depend; fi + set -e; for i in $(ALL_SUB_DIRS); do $(MAKE) -C $$i fastdep; done + +# +# A rule to make subdirectories +# +sub_dirs: dummy +ifdef SUB_DIRS + set -e; for i in $(SUB_DIRS); do $(MAKE) -C $$i; done +endif + +# +# A rule to make modules +# +ifdef M_OBJS +PDWN=$(shell /bin/sh $(TOPDIR)/scripts/pathdown.sh) +endif +modules: $(M_OBJS) dummy +ifdef MOD_SUB_DIRS + set -e; for i in $(MOD_SUB_DIRS); do $(MAKE) -C $$i modules; done +endif +ifneq "$(strip $(MOD_LIST_NAME))" "" +ifndef M_OBJS # Hack for fs subdirectories + rm -f $$TOPDIR/modules/$(MOD_LIST_NAME) + for i in $(MOD_SUB_DIRS); do \ + echo `basename $$i`.o >> $$TOPDIR/modules/$(MOD_LIST_NAME); done +else + echo $(M_OBJS) > $$TOPDIR/modules/$(MOD_LIST_NAME) +endif +endif +ifdef M_OBJS + echo $(PDWN) + cd $$TOPDIR/modules; for i in $(M_OBJS); do \ + ln -sf ../$(PDWN)/$$i .; done +endif # # A rule to do nothing @@ -14,8 +109,17 @@ dummy: # -# include a dependency file if one exists +# This is useful for testing +# +script: + $(SCRIPT) +# +# include dependency files they exist # ifeq (.depend,$(wildcard .depend)) include .depend +endif + +ifeq ($(TOPDIR)/.hdepend,$(wildcard $(TOPDIR)/.hdepend)) +include $(TOPDIR)/.hdepend endif diff -u --recursive --new-file v1.3.18/linux/arch/alpha/boot/Makefile linux/arch/alpha/boot/Makefile --- v1.3.18/linux/arch/alpha/boot/Makefile Tue Jul 11 10:02:47 1995 +++ linux/arch/alpha/boot/Makefile Tue Aug 15 15:07:01 1995 @@ -8,10 +8,6 @@ # Copyright (C) 1994 by Linus Torvalds # -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c -o $*.o $< .S.s: $(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $< .S.o: diff -u --recursive --new-file v1.3.18/linux/arch/alpha/kernel/Makefile linux/arch/alpha/kernel/Makefile --- v1.3.18/linux/arch/alpha/kernel/Makefile Thu Jul 13 16:20:19 1995 +++ linux/arch/alpha/kernel/Makefile Tue Aug 15 15:07:01 1995 @@ -7,10 +7,6 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< .S.s: $(CPP) -D__ASSEMBLY__ -traditional $< -o $*.s .S.o: diff -u --recursive --new-file v1.3.18/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile --- v1.3.18/linux/arch/alpha/lib/Makefile Tue Jul 18 16:28:56 1995 +++ linux/arch/alpha/lib/Makefile Tue Aug 15 15:07:02 1995 @@ -2,11 +2,6 @@ # Makefile for alpha-specific library files.. # -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \ checksum.o strlen.o diff -u --recursive --new-file v1.3.18/linux/arch/alpha/mm/Makefile linux/arch/alpha/mm/Makefile --- v1.3.18/linux/arch/alpha/mm/Makefile Tue Jul 11 10:02:47 1995 +++ linux/arch/alpha/mm/Makefile Tue Aug 15 15:07:02 1995 @@ -7,19 +7,9 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - OBJS = init.o fault.o mm.o: $(OBJS) $(LD) -r -o mm.o $(OBJS) - -modules: - -dep: - $(CPP) -M *.c > .depend include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/arch/i386/boot/compressed/Makefile linux/arch/i386/boot/compressed/Makefile --- v1.3.18/linux/arch/i386/boot/compressed/Makefile Tue Jul 11 10:02:47 1995 +++ linux/arch/i386/boot/compressed/Makefile Tue Aug 15 15:07:02 1995 @@ -17,11 +17,6 @@ INPUT_LEN=input_len endif -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - all: vmlinux vmlinux: piggy.o $(OBJECTS) diff -u --recursive --new-file v1.3.18/linux/arch/i386/config.in linux/arch/i386/config.in --- v1.3.18/linux/arch/i386/config.in Tue Aug 8 12:31:32 1995 +++ linux/arch/i386/config.in Sun Aug 13 19:39:38 1995 @@ -72,7 +72,7 @@ comment 'SCSI support' -bool 'SCSI support?' CONFIG_SCSI y +bool 'SCSI support' CONFIG_SCSI y if [ "$CONFIG_SCSI" = "n" ]; then @@ -122,7 +122,7 @@ comment 'Network device support' -bool 'Network device support?' CONFIG_NETDEVICES y +bool 'Network device support' CONFIG_NETDEVICES y if [ "$CONFIG_NETDEVICES" = "n" ]; then comment 'Skipping network driver configuration options...' diff -u --recursive --new-file v1.3.18/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile --- v1.3.18/linux/arch/i386/kernel/Makefile Tue Jul 11 10:02:47 1995 +++ linux/arch/i386/kernel/Makefile Tue Aug 15 15:07:02 1995 @@ -7,33 +7,21 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< #.S.s: # $(CPP) -D__ASSEMBLY__ -traditional $< -o $*.s .S.o: $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o -OBJS = process.o signal.o entry.o traps.o irq.o vm86.o bios32.o ptrace.o \ - ioport.o ldt.o setup.o sys_i386.o - all: kernel.o head.o +O_TARGET := kernel.o +O_OBJS := process.o signal.o entry.o traps.o irq.o vm86.o bios32.o \ + ptrace.o ioport.o ldt.o setup.o sys_i386.o + #head.o: head.s head.o: head.S $(TOPDIR)/include/linux/tasks.h $(CC) -D__ASSEMBLY__ -traditional -c $*.S -o $*.o # $(CPP) -traditional -o $*.s $< - -kernel.o: $(OBJS) - $(LD) -r -o kernel.o $(OBJS) - sync - -dep: - $(CPP) -M *.c > .depend - -modules: include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/arch/i386/lib/Makefile linux/arch/i386/lib/Makefile --- v1.3.18/linux/arch/i386/lib/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/i386/lib/Makefile Tue Aug 15 15:07:02 1995 @@ -2,19 +2,7 @@ # Makefile for i386-specific library files.. # -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - -OBJS = checksum.o - -lib.a: $(OBJS) - $(AR) rcs lib.a $(OBJS) - sync - -dep: - -modules: +L_TARGET = lib.a +L_OBJS = checksum.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/arch/i386/math-emu/Makefile linux/arch/i386/math-emu/Makefile --- v1.3.18/linux/arch/i386/math-emu/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/i386/math-emu/Makefile Tue Aug 15 15:07:02 1995 @@ -2,21 +2,17 @@ # Makefile for wm-FPU-emu # +L_TARGET := math.a + #DEBUG = -DDEBUGGING DEBUG = PARANOID = -DPARANOID -CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin - -.c.o: - $(CC) $(CFLAGS) $(MATH_EMULATION) -c $< +CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION) .S.o: $(CC) -D__ASSEMBLY__ $(PARANOID) -c $< -.s.o: - $(CC) -c $< - -OBJS = fpu_entry.o div_small.o errors.o \ +L_OBJS =fpu_entry.o div_small.o errors.o \ fpu_arith.o fpu_aux.o fpu_etc.o fpu_trig.o \ load_store.o get_address.o \ poly_atan.o poly_l2.o poly_2xm1.o poly_sin.o poly_tan.o \ @@ -28,18 +24,7 @@ div_Xsig.o polynom_Xsig.o round_Xsig.o \ shr_Xsig.o mul_Xsig.o -math.a: $(OBJS) - rm -f math.a - $(AR) rcs math.a $(OBJS) - sync - -dep: - $(CPP) -M *.c > .depend - $(CPP) -D__ASSEMBLY__ -M *.S >> .depend +include $(TOPDIR)/Rules.make proto: cproto -e -DMAKING_PROTO *.c >fpu_proto.h - -modules: - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/arch/i386/mm/Makefile linux/arch/i386/mm/Makefile --- v1.3.18/linux/arch/i386/mm/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/i386/mm/Makefile Tue Aug 15 15:07:02 1995 @@ -7,19 +7,7 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS = init.o fault.o - -mm.o: $(OBJS) - $(LD) -r -o mm.o $(OBJS) - -modules: - -dep: - $(CPP) -M *.c > .depend +O_TARGET := mm.o +O_OBJS := init.o fault.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/arch/mips/Makefile linux/arch/mips/Makefile --- v1.3.18/linux/arch/mips/Makefile Wed Jan 25 08:54:22 1995 +++ linux/arch/mips/Makefile Tue Aug 15 15:07:02 1995 @@ -15,7 +15,7 @@ # AS = mips-linux-as -ASFLAGS = -mips3 -mcpu=r4000 +#ASFLAGS = -mips3 -mcpu=r4000 LD = mips-linux-ld LINKFLAGS = -Ttext 0xa0000000 #HOSTCC = gcc diff -u --recursive --new-file v1.3.18/linux/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile --- v1.3.18/linux/arch/mips/kernel/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/mips/kernel/Makefile Tue Aug 15 15:07:02 1995 @@ -7,15 +7,12 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.s.o: - $(AS) $(ASFLAGS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< .S.s: $(CPP) $(CFLAGS) -D__ASSEMBLY__ -traditional $< -o $*.s .S.o: $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o +EXTRA_ASFLAGS = -mips3 -mcpu=r4000 OBJS = process.o signal.o entry.o traps.o irq.o ptrace.o cache.o resume.o \ ioport.o setup.o bios32.o tynedma.o @@ -52,10 +49,5 @@ kernel.o: $(OBJS) $(LD) -r -o kernel.o $(OBJS) sync - -dep: - $(CPP) -M *.c > .depend - -modules: include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/arch/mips/mm/Makefile linux/arch/mips/mm/Makefile --- v1.3.18/linux/arch/mips/mm/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/mips/mm/Makefile Tue Aug 15 15:07:02 1995 @@ -7,19 +7,7 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS = fault.o init.o - -mm.o: $(OBJS) - $(LD) -r -o mm.o $(OBJS) - -modules: - -dep: - $(CPP) -M *.c > .depend +O_TARGET := mm.o +O_OBJS := fault.o init.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/arch/sparc/boot/Makefile linux/arch/sparc/boot/Makefile --- v1.3.18/linux/arch/sparc/boot/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/sparc/boot/Makefile Tue Aug 15 15:07:02 1995 @@ -5,10 +5,6 @@ OBJS =bare.o init_me.o ../kernel/promops.o ../lib/lib.a BOOTLINKFLAGS = -N -Ttext 0x200000 -e _first_adr_in_text -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c -o $*.o $< .S.s: $(CC) -D__ASSEMBLY__ -D__KERNEL__ -ansi -E -o $*.o $< .S.o: diff -u --recursive --new-file v1.3.18/linux/arch/sparc/kernel/Makefile linux/arch/sparc/kernel/Makefile --- v1.3.18/linux/arch/sparc/kernel/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/sparc/kernel/Makefile Tue Aug 15 15:07:02 1995 @@ -7,10 +7,6 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< .S.s: $(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s .S.o: diff -u --recursive --new-file v1.3.18/linux/arch/sparc/lib/Makefile linux/arch/sparc/lib/Makefile --- v1.3.18/linux/arch/sparc/lib/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/sparc/lib/Makefile Tue Aug 15 15:07:02 1995 @@ -4,11 +4,6 @@ CFLAGS := $(CFLAGS) -ansi -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - OBJS = mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o lib.a: $(OBJS) diff -u --recursive --new-file v1.3.18/linux/arch/sparc/mm/Makefile linux/arch/sparc/mm/Makefile --- v1.3.18/linux/arch/sparc/mm/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/sparc/mm/Makefile Tue Aug 15 15:07:02 1995 @@ -7,19 +7,7 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS = fault.o vac-flush.o init.o sun4c.o srmmu.o loadmmu.o - -mm.o: $(OBJS) - $(LD) -r -o mm.o $(OBJS) - -modules: - -dep: - $(CPP) -M *.c > .depend +O_TARGET := mm.o +O_OBJS := fault.o vac-flush.o init.o sun4c.o srmmu.o loadmmu.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/arch/sparc/prom/Makefile linux/arch/sparc/prom/Makefile --- v1.3.18/linux/arch/sparc/prom/Makefile Tue Jul 11 10:02:48 1995 +++ linux/arch/sparc/prom/Makefile Tue Aug 15 15:07:02 1995 @@ -8,9 +8,6 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< - OBJS = bootstr.o devmap.o devops.o init.o memory.o misc.o mp.o \ palloc.o ranges.o segment.o tree.o console.o printf.o diff -u --recursive --new-file v1.3.18/linux/drivers/Makefile linux/drivers/Makefile --- v1.3.18/linux/drivers/Makefile Tue Jul 18 16:28:56 1995 +++ linux/drivers/Makefile Tue Aug 15 15:07:02 1995 @@ -7,36 +7,24 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.S.s: - $(CPP) -traditional $< -o $*.s -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - -SUBDIRS = block char net #streams +SUB_DIRS := block char net #streams +MOD_SUB_DIRS := $(SUB_DIRS) +ALL_SUB_DIRS := $(SUB_DIRS) pci scsi sound ifdef CONFIG_PCI -SUBDIRS := $(SUBDIRS) pci +SUB_DIRS += pci endif ifdef CONFIG_SCSI -SUBDIRS := $(SUBDIRS) scsi +SUB_DIRS += scsi +MOD_SUB_DIRS += scsi endif +# I think this should have an else clause for modules, but the original +# makefile did not, so I am not adding it. +# -jln 12 Aug 1995 ifdef CONFIG_SOUND -SUBDIRS := $(SUBDIRS) sound +SUB_DIRS += sound endif - -all: driversubdirs - -driversubdirs: dummy - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done - -modules: dummy - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i modules; done - -dep: - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i dep; done include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/drivers/block/MAKEDEV.ide linux/drivers/block/MAKEDEV.ide --- v1.3.18/linux/drivers/block/MAKEDEV.ide Thu Jan 1 02:00:00 1970 +++ linux/drivers/block/MAKEDEV.ide Tue Aug 15 15:17:37 1995 @@ -0,0 +1,29 @@ +#!/bin/sh +# +# This script creates the proper /dev/ entries for IDE devices +# +makedev () { + rm -f /dev/$1 + echo mknod /dev/$1 b $2 $3 + mknod /dev/$1 b $2 $3 + chown root:disk /dev/$1 + chmod 660 /dev/$1 +} + +makedevs () { + rm -f /dev/$1* + makedev $1 $2 $3 + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + do + makedev $1$part $2 `expr $3 + $part` + done +} + +makedevs hda 3 0 +makedevs hdb 3 64 +makedevs hdc 22 0 +makedevs hdd 22 64 +makedevs hde 33 0 +makedevs hdf 33 64 +makedevs hdg 34 0 +makedevs hdh 34 64 diff -u --recursive --new-file v1.3.18/linux/drivers/block/MAKEDEV.ide1 linux/drivers/block/MAKEDEV.ide1 --- v1.3.18/linux/drivers/block/MAKEDEV.ide1 Sun Jan 1 16:28:19 1995 +++ linux/drivers/block/MAKEDEV.ide1 Thu Jan 1 02:00:00 1970 @@ -1,24 +0,0 @@ -#!/bin/sh -makedev () { - rm -f /dev/$1 - echo mknod /dev/$1 $2 $3 $4 && - mknod /dev/$1 $2 $3 $4 && - chown $5 /dev/$1 && - chmod $6 /dev/$1 -} - -# Create /dev/hdc* -makedev hdc b 22 0 root:$disk 660 -for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -do - makedev hdc$part b 22 `expr 0 + $part` root:$disk 660 -done -echo " " - -# Create /dev/hdd* -makedev hdd b 22 64 root:$disk 660 -for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -do - makedev hdd$part b 22 `expr 64 + $part` root:$disk 660 -done - diff -u --recursive --new-file v1.3.18/linux/drivers/block/Makefile linux/drivers/block/Makefile --- v1.3.18/linux/drivers/block/Makefile Wed Aug 9 14:55:38 1995 +++ linux/drivers/block/Makefile Tue Aug 15 15:13:57 1995 @@ -9,145 +9,109 @@ # parent makefile. # -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - # # Note : at this point, these files are compiled on all systems. # In the future, some of these should be built conditionally. # -OBJS := ll_rw_blk.o ramdisk.o genhd.o -SRCS := ll_rw_blk.c ramdisk.c genhd.c -BLOCK_MODULE_OBJS = + +L_TARGET := block.a +L_OBJS := ll_rw_blk.o ramdisk.o genhd.o +M_OBJS := +MOD_LIST_NAME := BLOCK_MODULES ifdef CONFIG_BLK_DEV_FD -OBJS := $(OBJS) floppy.o -SRCS := $(SRCS) floppy.c +L_OBJS += floppy.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) floppy.o +M_OBJS += floppy.o endif ifdef CONFIG_AZTCD -OBJS := $(OBJS) aztcd.o -SRCS := $(SRCS) aztcd.c +L_OBJS += aztcd.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) aztcd.o +M_OBJS += aztcd.o endif #CONFIG_AZTCD ifdef CONFIG_CDU31A -OBJS := $(OBJS) cdu31a.o -SRCS := $(SRCS) cdu31a.c +L_OBJS += cdu31a.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) cdu31a.o +M_OBJS += cdu31a.o endif #CONFIG_CDU31A ifdef CONFIG_MCD -OBJS := $(OBJS) mcd.o -SRCS := $(SRCS) mcd.c +L_OBJS += mcd.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) mcd.o +M_OBJS += mcd.o endif #CONFIG_MCD ifdef CONFIG_MCDX -OBJS := $(OBJS) mcdx.o -SRCS := $(SRCS) mcdx.c +L_OBJS += mcdx.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) mcdx.o +M_OBJS += mcdx.o endif #CONFIG_MCDX ifdef CONFIG_SBPCD -OBJS := $(OBJS) sbpcd.o -SRCS := $(SRCS) sbpcd.c +L_OBJS += sbpcd.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) sbpcd.o +M_OBJS += sbpcd.o endif #CONFIG_SBPCD ifdef CONFIG_SBPCD2 -OBJS := $(OBJS) sbpcd2.o -SRCS := $(SRCS) sbpcd2.c +L_OBJS += sbpcd2.o endif #CONFIG_SBPCD2 ifdef CONFIG_SBPCD3 -OBJS := $(OBJS) sbpcd3.o -SRCS := $(SRCS) sbpcd3.c +L_OBJS += sbpcd3.o endif #CONFIG_SBPCD3 ifdef CONFIG_SBPCD4 -OBJS := $(OBJS) sbpcd4.o -SRCS := $(SRCS) sbpcd4.c +L_OBJS += sbpcd4.o endif #CONFIG_SBPCD4 ifdef CONFIG_CDU535 -OBJS := $(OBJS) sonycd535.o -SRCS := $(SRCS) sonycd535.c +L_OBJS += sonycd535.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) sonycd535.o +M_OBJS += sonycd535.o endif #CONFIG_CDU535 ifdef CONFIG_GSCD -OBJS := $(OBJS) gscd.o -SRCS := $(SRCS) gscd.c +L_OBJS += gscd.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) gscd.o +M_OBJS += gscd.o endif #CONFIG_GSCD ifdef CONFIG_CM206 -OBJS := $(OBJS) cm206.o -SRCS := $(SRCS) cm206.c +L_OBJS += cm206.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) cm206.o +M_OBJS += cm206.o endif #CONFIG_CM206 ifdef CONFIG_OPTCD -OBJS := $(OBJS) optcd.o -SRCS := $(SRCS) optcd.c +L_OBJS += optcd.o else -BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) optcd.o +M_OBJS += optcd.o endif #CONFIG_OPTCD ifdef CONFIG_SJCD -OBJS := $(OBJS) sjcd.o -SRCS := $(SRCS) sjcd.c +L_OBJS += sjcd.o #else -#BLOCK_MODULE_OBJS := $(BLOCK_MODULE_OBJS) sjcd.o +#M_OBJS += sjcd.o endif #CONFIG_SJCD ifdef CONFIG_BLK_DEV_HD -OBJS := $(OBJS) hd.o -SRCS := $(SRCS) hd.c +L_OBJS += hd.o endif ifdef CONFIG_BLK_DEV_IDE -OBJS := ide.o $(OBJS) -SRCS := ide.c $(SRCS) +L_OBJS += ide.o endif -ifdef CONFIG_BLK_DEV_XD -OBJS := $(OBJS) xd.o -SRCS := $(SRCS) xd.c +ifdef CONFIG_BLK_DEV_IDECD +L_OBJS += ide-cd.o endif -all: block.a - -block.a: $(OBJS) - rm -f block.a - $(AR) rcs block.a $(OBJS) - sync - -ifdef BLOCK_MODULE_OBJS -dep: - $(CPP) -M $(SRCS) > .depend - $(CPP) -M -DMODULE $(BLOCK_MODULE_OBJS:.o=.c) >> .depend -else -dep: - $(CPP) -M $(SRCS) > .depend +ifdef CONFIG_BLK_DEV_XD +L_OBJS += xd.o endif - -modules: $(BLOCK_MODULE_OBJS) - echo $(BLOCK_MODULE_OBJS) > ../../modules/BLOCK_MODULES - (cd ../../modules;for i in $(BLOCK_MODULE_OBJS); do ln -sf ../drivers/block/$$i .; done) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/drivers/block/README.ide linux/drivers/block/README.ide --- v1.3.18/linux/drivers/block/README.ide Mon Jul 31 15:58:59 1995 +++ linux/drivers/block/README.ide Sun Aug 13 20:19:11 1995 @@ -7,12 +7,13 @@ Major features of ide.c & ide-cd.c: - - support for up to two IDE interfaces on one or two IRQs - - support for any mix of up to four disk and/or cdrom drives +NEW! - support for up to *four* IDE interfaces on one or more IRQs +NEW! - support for any mix of up to *eight* disk and/or cdrom drives - support for reading IDE ATAPI cdrom drives (NEC,MITSUMI,VERTOS,SONY) - support for audio functions - auto-detection of interfaces, drives, IRQs, and disk geometries - -- "single" drives should be jumpered as "master", not "slave" + - "single" drives should be jumpered as "master", not "slave" +NEW! (both are now probed for) - support for BIOSs which report "more than 16 heads" on disk drives - uses LBA (slightly faster) on disk drives which support it - support for lots of fancy (E)IDE drive functions with hdparm utility @@ -20,41 +21,58 @@ - support for IDE multiple (block) mode (same as hd.c) - support for interrupt unmasking during I/O (better than hd.c) - improved handshaking and error detection/recovery - - can co-exist with hd.c to control only the secondary interface + - can co-exist with hd.c controlling the first interface - support for reliable operation of buggy CMD-640 interfaces - - use kernel command line option: hda=serialize +NEW! - use kernel command line option: ide1=serialize - experimental support for DTC-2278D interfaces - - use kernel command line option: hda=dtc2278 +NEW! - use kernel command line option: ide1=dtc2278 - run-time selectable 32bit interface support (using hdparm-2.3) NEW! - support for drives with a stuck WRERR_STAT bit -NEW! - support for removeable devices +NEW! - support for removeable devices, including door lock/unlock NEW! - transparent support for DiskManager 6.0x and "Dynamic Disk Overlay" +NEW! - should work for for EZ-Drive disks as well (not verified) - works with Linux fdisk, LILO, loadlin, bootln, etc.. +NEW! - ide-cd.c now compiles separate from ide.c + +For a list of work underway, see the comments near the top of ide.c and ide-cd.c *** IMPORTANT NOTICE: "CMD" EIDE Interfaces will not (by default) work *reliably* when drives are attached to the second interface. To "fix" this, supply the -special kernel "command line" parameter to LILO: hda=serialize +special kernel "command line" parameter to LILO: ide1=serialize Failure to do so can cause severe data corruption! *** -To access devices on the second interface, device entries must first be +To access devices on the 2nd/3rd/4th interfaces, device entries must first be created in /dev for them. To create such entries, simply run the included -shell script: MAKEDEV.ide1 +shell script: MAKEDEV.ide -Apparently the early releases of Slackware 2.2 have incorrect entries -in /dev for hdc* and hdd* -- this can also be corrected by running MAKEDEV.ide1 +Apparently many releases of Slackware 2.2/2.3 have incorrect entries +in /dev for hdc* and hdd* -- this can also be corrected by running MAKEDEV.ide ide.c automatically probes for the primary and secondary interfaces, for the drives/geometries attached to those interfaces, and for the IRQ numbers being used by the interfaces (normally IRQ14 & IRQ15). -The primary and secondary interfaces may share a single IRQ if necessary, -at a slight performance penalty, whether on separate cards or a single VLB card. +Interfaces beyond the first two are not normally probed for, but may be +specified using kernel "command line" options. For example, + + ide3=0x1e8,0x3f0,11 /* ioports 0x1e8-0x1ef,0x3f0, irq 11 */ + +Normally the irq number need not be specified, as ide.c will probe for it: + + ide3=0x1e8,0x3f0 /* ioports 0x1e8-0x1ef,0x3f0 */ + +Any number of interfaces may share a single IRQ if necessary, at a slight +performance penalty, whether on separate cards or a single VLB card. +The IDE driver automatically detects and handles this. However, this may +or may not be harmful to your hardware.. two or more cards driving the same IRQ +can potentially burn each other's bus driver, though in practice this +seldom occurs. Be careful, and if in doubt, don't do it! Drives are normally found by auto-probing and/or examining the CMOS/BIOS data. For really weird situations, the apparent (fdisk) geometry can also be specified @@ -63,16 +81,14 @@ hdx=cyls,heads,sects,wpcom,irq or hdx=cdrom -where hdx can be any of {hda,hdb,hdc,hdd}, or simply hd, for the "next" drive -in sequence. Only the first three parameters are required (cyls,heads,sects), -and wpcom is ignored for IDE drives. For example: +where hdx can be any of hda through hdh, Three values are required +(cyls,heads,sects). For example: - hdc=1050,32,64 hdd=cdrom + hdc=1050,32,64 hdd=cdrom -If an irq number is given, it will apply to both drives on the same interface, either {hda,hdb} or {hdc,hdd}. The results of successful auto-probing may override the physical geometry/irq specified, though the "original" geometry -is retained as the "logical" geometry for partitioning purposes (fdisk). +may be retained as the "logical" geometry for partitioning purposes (fdisk). If the auto-probing during boot time confuses a drive (ie. the drive works with hd.c but not with ide.c), then an command line option may be specified @@ -85,18 +101,22 @@ hdc=noprobe Note that when only one IDE device is attached to an interface, -it must be jumpered as "single" or "master", *not* "slave". -Many folks have had "trouble" with cdroms because of this requirement -of the ATA (IDE) standard. +it should be jumpered as "single" or "master", *not* "slave". +Many folks have had "trouble" with cdroms because of this requirement, +so ide.c now probes for both units, though success is more likely +when the drive is jumpered correctly. -Courtesy of Scott Snyder, the driver now supports ATAPI cdrom drives +Courtesy of Scott Snyder, the driver supports ATAPI cdrom drives such as the NEC-260 and the new MITSUMI triple/quad speed drives. -Such drives will be identified at boot time, as hda,hdb,hdc or hdd, -just like a harddisk. +Such drives will be identified at boot time, just like a harddisk. If for some reason your cdrom drive is *not* found at boot time, you can force the probe to look harder by supplying a kernel command line parameter -via LILO, such as: hdc=cdrom +via LILO, such as: + + hdc=cdrom /* hdc = "master" on second interface */ +or + hdd=cdrom /* hdd = "slave" on second interface */ For example, a GW2000 system might have a harddrive on the primary interface (/dev/hda) and an IDE cdrom drive on the secondary interface @@ -106,11 +126,18 @@ mkdir /cd mount /dev/cdrom /cd -t iso9660 -o ro +The kernel is able to execute binaries directly off of the cdrom, +provided it is mounted with the default block size of 1024 (as above). + Please pass on any feedback on the cdrom stuff to the author & maintainer, Scott Snyder (snyder@fnald0.fnal.gov). -The kernel is now be able to execute binaries directly off of the cdrom, -provided it is mounted with the default block size of 1024. +Note that if BOTH hd.c and ide.c are configured into the kernel, +hd.c will normally be allowed to control the primary IDE interface. +This is useful for older hardware that may be incompatible with ide.c, +and still allows newer hardware to run on the 2nd/3rd/4th IDE ports +under control of ide.c. To have ide.c also "take over" the primary +IDE port in this situation, use the "command line" parameter: ide0=0x1f0 The hdparm.c program for controlling various IDE features is now packaged separately. Look for it on popular linux FTP sites. @@ -119,6 +146,34 @@ snyder@fnald0.fnal.gov ================================================================================ +Summary of ide driver parameters for kernel "command line": +---------------------------------------------------------- + + "hdx=" is recognized for all "x" from "a" to "h", such as "hdc". + "idex=" is recognized for all "x" from "0" to "3", such as "ide1". + + "hdx=noprobe" : drive may be present, but do not probe for it + "hdx=nowerr" : ignore the WRERR_STAT bit on this drive + "hdx=cdrom" : drive is present, and is a cdrom drive + "hdx=cyl,head,sect" : disk drive is present, with specified geometry + + "idex=noprobe" : do not attempt to access/use this interface + "idex=base" : probe for an interface at the addr specified, + where "base" is usually 0x1f0 or 0x170 + and "ctl" is assumed to be "base"+0x206 + and "irq" will be probed for + "idex=base,ctl" : specify both base and ctl + "idex=base,ctl,irq" : specify base, ctl, and irq number + +The following two are valid ONLY on ide0 or ide1: + + "idex=dtc2278" : look for and try to initialize a dtc2278 + "idex=serialize" : do not overlap operations on ide0 and ide1. + +Everything else is rejected with a "BAD OPTION" message. + +================================================================================ + Some Terminology ---------------- IDE = Integrated Drive Electronics, meaning that each drive has a built-in @@ -262,7 +317,7 @@ Note that when creating partitions that span beyond cylinder 1024, Linux fdisk will complain about "Partition X has different physical/logical endings" and emit messages such as "This is larger than 1024, and may cause -problems with some software". Ignore them for linux partitions. The "some +problems with some software". Ignore this for linux partitions. The "some software" refers to DOS, the BIOS, and LILO, as described previously. Western Digital ships a "DiskManager 6.03" diskette with all of their big @@ -272,3 +327,35 @@ with Linux 1.3.x in most cases. Let me know if you still have trouble. mlord@bnr.ca + +================================================================================ +EIDE card compatibility reports: +================================================================================ + +comp.os.linux.hardware #18483 (7 + 0 more) (1)--[1] +From: test +[1] Re: Promise EIDEMAX +Date: Fri Aug 11 23:17:39 EDT 1995 +Organization: Technical University of Brno, Czech Republic +Lines: 14 +Mime-Version: 1.0 +Content-Type: text/plain; charset=us-ascii +Content-Transfer-Encoding: 7bit +X-Mailer: Mozilla 1.1N (X11; I; Linux 1.2.11 i486) +To: rmorton@VNET.IBM.COM +X-URL: news:19950806.154256.872@almaden.ibm.com + +I have a Promise 2300 board with DX2/80 w/ 32Mb ram. + +This one is a bit schizophrenic - half (2 drives) at VLBUS and +the rest 2 on ISA. + +Works quite well, Linux works with it (4 HDDs), it +also supports its dual irq mechanism (14 & 15). +In the documentation I've found that there are certain things made about this +controller(in kernel). +My current kernel is 1.2.11 and Promise should be supported in all 1.2.xx +kernels I think. + + Vladimir Myslik + diff -u --recursive --new-file v1.3.18/linux/drivers/block/blk.h linux/drivers/block/blk.h --- v1.3.18/linux/drivers/block/blk.h Tue Aug 8 12:31:33 1995 +++ linux/drivers/block/blk.h Tue Aug 15 20:10:23 1995 @@ -332,12 +332,17 @@ #endif /* (MAJOR_NR != SCSI_TAPE_MAJOR) && !defined(IDE_DRIVER) */ /* end_request() - SCSI devices have their own version */ +/* - IDE drivers have their own copy too */ #if ! SCSI_MAJOR(MAJOR_NR) +#ifdef _IDE_CD_C /* ide-cd.c uses copy from ide.c */ +void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup); +#else + #ifdef IDE_DRIVER -static void end_request(byte uptodate, byte hwif) { - struct request *req = ide_cur_rq[HWIF]; +void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup) { + struct request *req = hwgroup->rq; #else static void end_request(int uptodate) { struct request *req = CURRENT; @@ -371,7 +376,7 @@ } } #ifdef IDE_DRIVER - ide_cur_rq[HWIF] = NULL; + hwgroup->rq = NULL; #else DEVICE_OFF(req->dev); CURRENT = req->next; @@ -381,6 +386,7 @@ req->dev = -1; wake_up(&wait_for_request); } +#endif /* ndef _IDE_CD_C */ #endif /* ! SCSI_MAJOR(MAJOR_NR) */ #endif /* defined(MAJOR_NR) || defined(IDE_DRIVER) */ diff -u --recursive --new-file v1.3.18/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v1.3.18/linux/drivers/block/genhd.c Tue Aug 8 12:31:33 1995 +++ linux/drivers/block/genhd.c Sun Aug 13 20:19:11 1995 @@ -17,11 +17,12 @@ * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1). */ +#include #include #include #include #include -#include +#include struct gendisk *gendisk_head = NULL; @@ -30,18 +31,37 @@ extern void rd_load(void); extern int ramdisk_size; -static char minor_name (struct gendisk *hd, int minor) +static void print_minor_name (struct gendisk *hd, int minor) { - char base_name = (hd->major == IDE1_MAJOR) ? 'c' : 'a'; - return base_name + (minor >> hd->minor_shift); + unsigned int unit = minor >> hd->minor_shift; + unsigned int part = minor & ((1 << hd->minor_shift) - 1); + +#ifdef CONFIG_BLK_DEV_IDE + /* + * IDE devices use multiple major numbers, but the drives + * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}.. + * This requires some creative handling here to find the + * correct name to use, with some help from ide.c + */ + if (!strcmp(hd->major_name,"ide")) { + char name[16]; /* more than large enough */ + strcpy(name, hd->real_devices); /* courtesy ide.c */ + name[strlen(name)-1] += unit; + printk(" %s", name); + } else +#endif + printk(" %s%c", hd->major_name, 'a' + unit); + if (part) + printk("%d", part); + else + printk(":"); } static void add_partition (struct gendisk *hd, int minor, int start, int size) { hd->part[minor].start_sect = start; hd->part[minor].nr_sects = size; - printk(" %s%c%d", hd->major_name, minor_name(hd, minor), - minor & ((1 << hd->minor_shift) - 1)); + print_minor_name(hd, minor); } #ifdef CONFIG_MSDOS_PARTITION @@ -100,7 +120,6 @@ !(hd->part[current_minor].nr_sects = p->nr_sects)) goto done; /* no more logicals in this partition */ hd->part[current_minor].start_sect = first_sector + p->start_sect; - hd->sizes[current_minor] = p->nr_sects >> (BLOCK_SIZE_BITS - 9); this_sector = first_sector + p->start_sect; dev = ((hd->major) << 8) | current_minor; brelse(bh); @@ -134,12 +153,14 @@ #ifdef CONFIG_BLK_DEV_IDE /* - * Check for Disk Manager v6.0x with geometry translation + * Check for Disk Manager v6.0x (or EZ-DRIVE) with geometry translation */ if (!tested_for_dm6++) { /* only check for DM6 *once* */ extern int ide_xlate_1024(dev_t, int, const char *); /* check for DM6 with Dynamic Drive Overlay (DDO) */ - if (p->sys_ind == DM6_PARTITION) { + if (p->sys_ind == DM6_PARTITION || p->sys_ind == EZD_PARTITION) { + const char *label = (p->sys_ind == DM6_PARTITION)?" [DM6:DDO]":" [EZDRIVE]"; + /* * Everything on the disk is offset by 63 sectors, * including a "new" MBR with its own partition table, @@ -150,7 +171,7 @@ * ide_xlate_1024() will take care of the necessary * adjustments to fool fdisk/LILO and partition check. */ - if (ide_xlate_1024(dev,1," [DM6:DDO]")) { + if (ide_xlate_1024(dev, 1, label)) { bh->b_dirt = 0; /* force re-read of MBR block */ bh->b_uptodate = 0; bh->b_req = 0; @@ -164,7 +185,7 @@ && *(unsigned short *)(bh->b_data + sig) == 0x55AA && (1 & *(unsigned char *)(bh->b_data + sig + 2)) ) { - (void)ide_xlate_1024(dev,0," [DM6:MBR]"); + (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]"); } else { /* look for DM6 AUX partition type in slot 1 */ if (p->sys_ind == DM6_AUX1PARTITION @@ -300,7 +321,8 @@ return; } - printk(" %s%c:", hd->major_name, minor_name(hd, MINOR(dev))); + printk(" "); + print_minor_name(hd, MINOR(dev)); #ifdef CONFIG_MSDOS_PARTITION if (msdos_partition(hd, dev, first_sector)) return; @@ -324,37 +346,43 @@ void resetup_one_dev(struct gendisk *dev, int drive) { int i; - int start = drive<minor_shift; - int j = start + dev->max_p; - int major = dev->major << 8; - - current_minor = 1+(drive<minor_shift); - check_partition(dev, major+(drive<minor_shift)); - - for (i=start ; i < j ; i++) - dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9); + int major = dev->major << 8; + int first_minor = drive << dev->minor_shift; + int end_minor = first_minor + dev->max_p; + + blk_size[dev->major] = NULL; + current_minor = 1 + first_minor; + check_partition(dev, major + first_minor); + + if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */ + for (i = first_minor; i < end_minor; i++) + dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9); + blk_size[dev->major] = dev->sizes; + } } static void setup_dev(struct gendisk *dev) { - int i; - int j = dev->max_nr * dev->max_p; - int major = dev->major << 8; - int drive; - + int i, drive; + int major = dev->major << 8; + int end_minor = dev->max_nr * dev->max_p; - for (i = 0 ; i < j; i++) { + blk_size[dev->major] = NULL; + for (i = 0 ; i < end_minor; i++) { dev->part[i].start_sect = 0; dev->part[i].nr_sects = 0; } - dev->init(); - for (drive=0 ; drivenr_real ; drive++) { - current_minor = 1+(drive<minor_shift); - check_partition(dev, major+(drive<minor_shift)); - } - for (i=0 ; i < j ; i++) - dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9); - blk_size[dev->major] = dev->sizes; + dev->init(dev); + for (drive = 0 ; drive < dev->nr_real ; drive++) { + int first_minor = drive << dev->minor_shift; + current_minor = 1 + first_minor; + check_partition(dev, major + first_minor); + } + if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */ + for (i = 0; i < end_minor; i++) + dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9); + blk_size[dev->major] = dev->sizes; + } } void device_setup(void) diff -u --recursive --new-file v1.3.18/linux/drivers/block/hd.c linux/drivers/block/hd.c --- v1.3.18/linux/drivers/block/hd.c Tue Aug 8 12:31:33 1995 +++ linux/drivers/block/hd.c Sun Aug 13 20:19:11 1995 @@ -44,8 +44,6 @@ #define MAJOR_NR HD_MAJOR #include "blk.h" -#define HD_IRQ 14 - static int revalidate_hddisk(int, int); #define HD_DELAY 0 @@ -915,7 +913,7 @@ } -static void hd_geninit(void); +static void hd_geninit(struct gendisk *); static struct gendisk hd_gendisk = { MAJOR_NR, /* Major number */ @@ -952,7 +950,7 @@ * We enable interrupts in some of the routines after making sure it's * safe. */ -static void hd_geninit(void) +static void hd_geninit(struct gendisk *ignored) { int i; diff -u --recursive --new-file v1.3.18/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c --- v1.3.18/linux/drivers/block/ide-cd.c Sun Jun 11 19:15:34 1995 +++ linux/drivers/block/ide-cd.c Mon Aug 14 07:44:04 1995 @@ -6,7 +6,7 @@ * cdrom_check_status. * 1.03 Nov 25, 1994 -- leaving unmask_intr[] as a user-setting (as for disks) * (from mlord) -- minor changes to cdrom_setup() - * -- renamed ide_dev_s to ide_dev_t, enable irq on command + * -- renamed ide_dev_s to ide_drive_t, enable irq on command * 2.00 Nov 27, 1994 -- Generalize packet command interface; * add audio ioctls. * 2.01 Dec 3, 1994 -- Rework packet command interface to handle devices @@ -39,7 +39,23 @@ * Properly supply the page number field in the * MODE_SELECT command. * PLAYAUDIO12 is broken on the Aztech; work around it. - * + * 2.05x Aug 11, 1995 -- lots of data structure renaming/restructuring in ide.c + * (my apologies to Scott, but now ide-cd.c is independent) + * + * FIX ME!! A day-one bug exists when the ide.c "serialize" option is used. + * For this to always work correctly, ide_set_handler() must be called + * *just before* the final trigger is given to the drive (to cause it to go + * off and get data and then interrupt us again). Otherwise, we may get the + * interrupt before set_handler() has actually run, resulting in "unexpected_intr". + * + * This can only happen in scenarios where we handle a "final" interrupt + * for one IDE port on, say irq14, and then initiate a new request for the + * other port on, say irq15, from the irq14 interrupt handler. If we are + * running with "unmask" on, or have done sti(), then Whammo -- we're exposed. + * + * Places where this needs fixing have been identified in the code with "BUG". + * -ml August 11, 1995 + * * * ATAPI cd-rom driver. To be used with ide.c. * @@ -49,6 +65,25 @@ */ +/***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _IDE_CD_C /* used in blk.h */ +#include "ide.h" + /* Turn this on to have the driver print out the meanings of the ATAPI error codes. This will use up additional kernel-space memory, though. */ @@ -57,10 +92,6 @@ #define VERBOSE_IDE_CD_ERRORS 0 #endif -/***************************************************************************/ - -#include - #define SECTOR_SIZE 512 #define SECTOR_BITS 9 #define SECTORS_PER_FRAME (CD_FRAMESIZE / SECTOR_SIZE) @@ -68,11 +99,11 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) #if 1 /* "old" method */ -#define OUT_WORDS(b,n) outsw (IDE_PORT (HD_DATA, DEV_HWIF), (b), (n)) -#define IN_WORDS(b,n) insw (IDE_PORT (HD_DATA, DEV_HWIF), (b), (n)) +#define OUT_WORDS(b,n) outsw (IDE_DATA_REG, (b), (n)) +#define IN_WORDS(b,n) insw (IDE_DATA_REG, (b), (n)) #else /* "new" method -- should really fix each instance instead of this */ -#define OUT_WORDS(b,n) output_ide_data(dev,b,(n)/2) -#define IN_WORDS(b,n) input_ide_data(dev,b,(n)/2) +#define OUT_WORDS(b,n) output_ide_data(drive,b,(n)/2) +#define IN_WORDS(b,n) input_ide_data(drive,b,(n)/2) #endif /* special command codes for strategy routine. */ @@ -105,34 +136,8 @@ #define ABORTED_COMMAND 0x0b #define MISCOMPARE 0x0e - -struct packet_command { - char *buffer; - int buflen; - int stat; - unsigned char c[12]; -}; - - -struct atapi_request_sense { - unsigned char error_code : 7; - unsigned char valid : 1; - byte reserved1; - unsigned char sense_key : 4; - unsigned char reserved2 : 1; - unsigned char ili : 1; - unsigned char reserved3 : 2; - byte info[4]; - byte sense_len; - byte command_info[4]; - byte asc; - byte ascq; - byte fru; - byte sense_key_specific[3]; -}; - /* We want some additional flags for cd-rom drives. - To save space in the ide_dev_t struct, use one of the fields which + To save space in the ide_drive_t struct, use one of the fields which doesn't make sense for cd-roms -- `bios_sect'. */ struct ide_cd_flags { @@ -147,69 +152,10 @@ unsigned reserved : 2; }; -#define CDROM_FLAGS(dev) ((struct ide_cd_flags *)&((dev)->bios_sect)) - - -/* Space to hold the disk TOC. */ - -#define MAX_TRACKS 99 -struct atapi_toc_header { - unsigned short toc_length; - byte first_track; - byte last_track; -}; - -struct atapi_toc_entry { - byte reserved1; - unsigned control : 4; - unsigned adr : 4; - byte track; - byte reserved2; - unsigned lba; -}; - -struct atapi_toc { - struct atapi_toc_header hdr; - struct atapi_toc_entry ent[MAX_TRACKS+1]; /* One extra for the leadout. */ -}; - +#define CDROM_FLAGS(drive) ((struct ide_cd_flags *)&((drive)->bios_sect)) #define SECTOR_BUFFER_SIZE CD_FRAMESIZE -/* Extra per-device info for cdrom drives. */ -struct cdrom_info { - - /* Buffer for table of contents. NULL if we haven't allocated - a TOC buffer for this device yet. */ - - struct atapi_toc *toc; - - /* Sector buffer. If a read request wants only the first part of a cdrom - block, we cache the rest of the block here, in the expectation that that - data is going to be wanted soon. SECTOR_BUFFERED is the number of the - first buffered sector, and NSECTORS_BUFFERED is the number of sectors - in the buffer. Before the buffer is allocated, we should have - SECTOR_BUFFER == NULL and NSECTORS_BUFFERED == 0. */ - - unsigned long sector_buffered; - unsigned long nsectors_buffered; - char *sector_buffer; - - /* The result of the last successful request sense command - on this device. */ - struct atapi_request_sense sense_data; -}; - - -static struct cdrom_info cdrom_info[2][MAX_DRIVES]; - -/* Statically allocate one request packet and one packet command struct - for each interface for retrieving sense data during error recovery. */ - -static struct request request_sense_request[2]; -static struct packet_command request_sense_pc[2]; - - /**************************************************************************** * Descriptions of ATAPI error codes. @@ -359,7 +305,7 @@ static -void cdrom_analyze_sense_data (ide_dev_t *dev, +void cdrom_analyze_sense_data (ide_drive_t *drive, struct atapi_request_sense *reqbuf, struct packet_command *failed_command) { @@ -377,7 +323,7 @@ char *s; char buf[80]; - printk ("ATAPI device %s:\n", dev->name); + printk ("ATAPI device %s:\n", drive->name); printk (" Error code: %x\n", reqbuf->error_code); @@ -437,7 +383,7 @@ #else printk ("%s: code: %x key: %x asc: %x ascq: %x\n", - dev->name, + drive->name, reqbuf->error_code, reqbuf->sense_key, reqbuf->asc, reqbuf->ascq); #endif } @@ -458,19 +404,19 @@ } -static void cdrom_queue_request_sense (ide_dev_t *dev) +static void cdrom_queue_request_sense (ide_drive_t *drive) { struct request *rq; struct packet_command *pc; struct atapi_request_sense *reqbuf; unsigned long flags; - int major = ide_major[DEV_HWIF]; + int major = HWIF(drive)->major; save_flags (flags); cli (); /* safety */ - rq = ide_cur_rq[DEV_HWIF]; + rq = HWGROUP(drive)->rq; /* If we're processing a request, put it back on the request queue. */ if (rq != NULL) @@ -478,15 +424,15 @@ restore_request (rq); rq->next = blk_dev[major].current_request; blk_dev[major].current_request = rq; - ide_cur_rq[DEV_HWIF] = NULL; + HWGROUP(drive)->rq = NULL; } restore_flags (flags); /* Make up a new request to retrieve sense information. */ - reqbuf = &cdrom_info[DEV_HWIF][dev->select.b.drive].sense_data; + reqbuf = &drive->cdrom_info.sense_data; - pc = &request_sense_pc[DEV_HWIF]; + pc = &HWIF(drive)->request_sense_pc; memset (pc, 0, sizeof (*pc)); pc->c[0] = REQUEST_SENSE; @@ -494,8 +440,8 @@ pc->buffer = (char *)reqbuf; pc->buflen = sizeof (*reqbuf); - rq = &request_sense_request[DEV_HWIF]; - rq->dev = MKDEV (major, (dev->select.b.drive) << PARTN_BITS); + rq = &HWIF(drive)->request_sense_request; + rq->dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS); rq->cmd = REQUEST_SENSE_COMMAND; rq->errors = 0; rq->sector = 0; @@ -518,9 +464,9 @@ } -static void cdrom_end_request (int uptodate, ide_dev_t *dev) +static void cdrom_end_request (int uptodate, ide_drive_t *drive) { - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; /* The code in blk.h can screw us up on error recovery if the block size is larger than 1k. Fix that up here. */ @@ -534,44 +480,44 @@ if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) { struct atapi_request_sense *reqbuf; - reqbuf = &cdrom_info[DEV_HWIF][dev->select.b.drive].sense_data; - cdrom_analyze_sense_data (dev, reqbuf, NULL); + reqbuf = &drive->cdrom_info.sense_data; + cdrom_analyze_sense_data (drive, reqbuf, NULL); } - end_request (uptodate, DEV_HWIF); + ide_end_request (uptodate, HWGROUP(drive)); } /* Mark that we've seen a media change, and invalidate our internal buffers. */ -static void cdrom_saw_media_change (ide_dev_t *dev) +static void cdrom_saw_media_change (ide_drive_t *drive) { - CDROM_FLAGS (dev)->media_changed = 1; - CDROM_FLAGS (dev)->toc_valid = 0; - cdrom_info[DEV_HWIF][dev->select.b.drive].nsectors_buffered = 0; + CDROM_FLAGS (drive)->media_changed = 1; + CDROM_FLAGS (drive)->toc_valid = 0; + drive->cdrom_info.nsectors_buffered = 0; } /* Returns 0 if the request should be continued. Returns 1 if the request was ended. */ -static int cdrom_decode_status (ide_dev_t *dev, int good_stat, int *stat_ret) +static int cdrom_decode_status (ide_drive_t *drive, int good_stat, int *stat_ret) { - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; int stat, err, sense_key, cmd; /* Check for errors. */ - stat = GET_STAT (DEV_HWIF); + stat = GET_STAT(); *stat_ret = stat; if (OK_STAT (stat, good_stat, BAD_R_STAT)) return 0; /* Got an error. */ - err = IN_BYTE (HD_ERROR, DEV_HWIF); + err = IN_BYTE (IDE_ERROR_REG); sense_key = err >> 4; if (rq == NULL) - printk ("%s : missing request in cdrom_decode_status\n", dev->name); + printk ("%s : missing request in cdrom_decode_status\n", drive->name); else { cmd = rq->cmd; @@ -580,13 +526,13 @@ if (sense_key == NOT_READY) { struct packet_command *pc; - cdrom_saw_media_change (dev); + cdrom_saw_media_change (drive); /* Fail the request if this is a read command. */ if (cmd == READ) { - printk ("%s : tray open\n", dev->name); - cdrom_end_request (0, dev); + printk ("%s : tray open\n", drive->name); + cdrom_end_request (0, drive); } else @@ -599,19 +545,19 @@ the syslog. */ pc = (struct packet_command *)rq->buffer; if (pc->c[0] != SCMD_READ_SUBCHANNEL) - printk ("%s : tray open\n", dev->name); + printk ("%s : tray open\n", drive->name); /* Set the error flag and complete the request. */ pc->stat = 1; - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); } } /* Check for media change. */ else if (sense_key == UNIT_ATTENTION) { - cdrom_saw_media_change (dev); - printk ("%s: media changed\n", dev->name); + cdrom_saw_media_change (drive); + printk ("%s: media changed\n", drive->name); /* Return failure for a packet command, so that cdrom_queue_packet_command can do a request sense before @@ -621,14 +567,14 @@ { struct packet_command *pc = (struct packet_command *)rq->buffer; pc->stat = 1; - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); } /* Otherwise, it's a block read. Arrange to retry it. But be sure to give up if we've retried too many times. */ else if ((++rq->errors > ERROR_MAX)) { - cdrom_end_request (0, dev); + cdrom_end_request (0, drive); } } @@ -636,28 +582,29 @@ else if (cmd == PACKET_COMMAND) { struct packet_command *pc = (struct packet_command *)rq->buffer; - dump_status (DEV_HWIF, "packet command error", stat); + ide_dump_status (drive, "packet command error", stat); pc->stat = 1; /* signal error */ - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); } /* No point in retrying after an illegal request or data protect error.*/ else if (sense_key == ILLEGAL_REQUEST || sense_key == DATA_PROTECT) { - dump_status (DEV_HWIF, "command error", stat); - cdrom_end_request (0, dev); + ide_dump_status (drive, "command error", stat); + cdrom_end_request (0, drive); } /* If there were other errors, go to the default handler. */ else if ((err & ~ABRT_ERR) != 0) { - ide_error (dev, "cdrom_decode_status", stat); + if (ide_error (drive, "cdrom_decode_status", stat)) + return 1; } /* Else, abort if we've racked up too many retries. */ else if ((++rq->errors > ERROR_MAX)) { - cdrom_end_request (0, dev); + cdrom_end_request (0, drive); } /* If we got a CHECK_STATUS condition, and this was a READ request, @@ -665,11 +612,11 @@ what went wrong (and clear a unit attention)? For packet commands, this is done separately in cdrom_queue_packet_command. */ if ((stat & ERR_STAT) != 0 && cmd == READ) - cdrom_queue_request_sense (dev); + cdrom_queue_request_sense (drive); } /* Retry, or handle the next request. */ - DO_REQUEST; + IDE_DO_REQUEST; return 1; } @@ -678,20 +625,20 @@ expecting to later transfer XFERLEN bytes. This should be followed by a call to cdrom_transfer_packet_command; however, if this is a drq_interrupt device, one must wait for an interrupt first. */ -static int cdrom_start_packet_command (ide_dev_t *dev, int xferlen) +static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen) { /* Wait for the controller to be idle. */ - if (wait_stat (dev, 0, BUSY_STAT, WAIT_READY)) return 1; + if (ide_wait_stat (drive, 0, BUSY_STAT, WAIT_READY)) return 1; /* Set up the controller registers. */ - OUT_BYTE (0, HD_FEATURE); - OUT_BYTE (0, HD_NSECTOR); - OUT_BYTE (0, HD_SECTOR); - - OUT_BYTE (xferlen & 0xff, HD_LCYL); - OUT_BYTE (xferlen >> 8 , HD_HCYL); - OUT_BYTE (dev->ctl, HD_CMD); - OUT_BYTE (WIN_PACKETCMD, HD_COMMAND); /* packet command */ + OUT_BYTE (0, IDE_FEATURE_REG); + OUT_BYTE (0, IDE_NSECTOR_REG); + OUT_BYTE (0, IDE_SECTOR_REG); + + OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG); + OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG); + OUT_BYTE (drive->ctl, IDE_CONTROL_REG); + OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ return 0; } @@ -700,22 +647,22 @@ /* Send a packet command to DEV described by CMD_BUF and CMD_LEN. The device registers must have already been prepared by cdrom_start_packet_command. */ -static int cdrom_transfer_packet_command (ide_dev_t *dev, +static int cdrom_transfer_packet_command (ide_drive_t *drive, char *cmd_buf, int cmd_len) { - if (CDROM_FLAGS (dev)->drq_interrupt) + if (CDROM_FLAGS (drive)->drq_interrupt) { /* Here we should have been called after receiving an interrupt from the device. DRQ should how be set. */ int stat_dum; /* Check for errors. */ - if (cdrom_decode_status (dev, DRQ_STAT, &stat_dum)) return 1; + if (cdrom_decode_status (drive, DRQ_STAT, &stat_dum)) return 1; } else { /* Otherwise, we must wait for DRQ to get set. */ - if (wait_stat (dev, DRQ_STAT, BUSY_STAT, WAIT_READY)) return 1; + if (ide_wait_stat (drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) return 1; } /* Send the command to the device. */ @@ -737,10 +684,10 @@ * sector added, SECTOR is its sector number. (SECTOR is then ignored until * the buffer is cleared.) */ -static void cdrom_buffer_sectors (ide_dev_t *dev, unsigned long sector, +static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector, int sectors_to_transfer) { - struct cdrom_info *info = &cdrom_info[DEV_HWIF][dev->select.b.drive]; + struct cdrom_info *info = &drive->cdrom_info; /* Number of sectors to read into the buffer. */ int sectors_to_buffer = MIN (sectors_to_transfer, @@ -792,7 +739,7 @@ * ok; nonzero if the request has been terminated. */ static inline -int cdrom_read_check_ireason (ide_dev_t *dev, int len, int ireason) +int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason) { ireason &= 3; if (ireason == 2) return 0; @@ -802,7 +749,7 @@ /* Whoops... The drive is expecting to receive data from us! */ printk ("%s: cdrom_read_intr: " "Drive wants to transfer data the wrong way!\n", - dev->name); + drive->name); /* Throw some data at the drive so it doesn't hang and quit this request. */ @@ -818,11 +765,11 @@ { /* Drive wants a command packet, or invalid ireason... */ printk ("%s: cdrom_read_intr: bad interrupt reason %d\n", - dev->name, ireason); + drive->name, ireason); } - cdrom_end_request (0, dev); - DO_REQUEST; + cdrom_end_request (0, drive); + IDE_DO_REQUEST; return -1; } @@ -830,19 +777,19 @@ /* * Interrupt routine. Called when a read request has completed. */ -static void cdrom_read_intr (ide_dev_t *dev) +static void cdrom_read_intr (ide_drive_t *drive) { int stat; int ireason, len, sectors_to_transfer, nskip; - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; /* Check for errors. */ - if (cdrom_decode_status (dev, 0, &stat)) return; + if (cdrom_decode_status (drive, 0, &stat)) return; /* Read the interrupt reason and the transfer length. */ - ireason = IN_BYTE (HD_NSECTOR, DEV_HWIF); - len = IN_BYTE (HD_LCYL, DEV_HWIF) + 256 * IN_BYTE (HD_HCYL, DEV_HWIF); + ireason = IN_BYTE (IDE_NSECTOR_REG); + len = IN_BYTE (IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG); /* If DRQ is clear, the command has completed. */ if ((stat & DRQ_STAT) == 0) @@ -852,28 +799,28 @@ if (rq->current_nr_sectors > 0) { printk ("%s: cdrom_read_intr: data underrun (%ld blocks)\n", - dev->name, rq->current_nr_sectors); - cdrom_end_request (0, dev); + drive->name, rq->current_nr_sectors); + cdrom_end_request (0, drive); } else - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); - DO_REQUEST; + IDE_DO_REQUEST; return; } /* Check that the drive is expecting to do the same thing that we are. */ - if (cdrom_read_check_ireason (dev, len, ireason)) return; + if (cdrom_read_check_ireason (drive, len, ireason)) return; /* Assume that the drive will always provide data in multiples of at least SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise. */ if ((len % SECTOR_SIZE) != 0) { printk ("%s: cdrom_read_intr: Bad transfer size %d\n", - dev->name, len); + drive->name, len); printk (" This drive is not supported by this version of the driver\n"); - cdrom_end_request (0, dev); - DO_REQUEST; + cdrom_end_request (0, drive); + IDE_DO_REQUEST; return; } @@ -904,13 +851,13 @@ buffer after it, move on. */ if (rq->current_nr_sectors == 0 && rq->nr_sectors > 0) - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); /* If the buffers are full, cache the rest of the data in our internal buffer. */ if (rq->current_nr_sectors == 0) { - cdrom_buffer_sectors (dev, rq->sector, sectors_to_transfer); + cdrom_buffer_sectors (drive, rq->sector, sectors_to_transfer); sectors_to_transfer = 0; } else @@ -937,7 +884,7 @@ /* Done moving data! Wait for another interrupt. */ - ide_handler[DEV_HWIF] = cdrom_read_intr; + ide_set_handler(drive, &cdrom_read_intr); /* this one is okay */ } @@ -945,10 +892,10 @@ * Try to satisfy some of the current read request from our cached data. * Returns nonzero if the request has been completed, zero otherwise. */ -static int cdrom_read_from_buffer (ide_dev_t *dev) +static int cdrom_read_from_buffer (ide_drive_t *drive) { - struct cdrom_info *info = &cdrom_info[DEV_HWIF][dev->select.b.drive]; - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct cdrom_info *info = &drive->cdrom_info; + struct request *rq = HWGROUP(drive)->rq; /* Can't do anything if there's no buffer. */ if (info->sector_buffer == NULL) return 0; @@ -960,7 +907,7 @@ rq->sector < info->sector_buffered + info->nsectors_buffered) { if (rq->current_nr_sectors == 0) - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); memcpy (rq->buffer, info->sector_buffer + @@ -975,13 +922,13 @@ /* If we've satisfied the current request, terminate it successfully. */ if (rq->nr_sectors == 0) { - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); return -1; } /* Move on to the next buffer if needed. */ if (rq->current_nr_sectors == 0) - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); /* If this condition does not hold, then the kluge i use to represent the number of sectors to skip at the start of a transfer @@ -991,8 +938,8 @@ (rq->sector % SECTORS_PER_FRAME) != 0) { printk ("%s: cdrom_read_from_buffer: buffer botch (%ld)\n", - dev->name, rq->sector); - cdrom_end_request (0, dev); + drive->name, rq->sector); + cdrom_end_request (0, drive); return -1; } @@ -1007,10 +954,10 @@ * However, for drq_interrupt devices, it is called from an interrupt * when the drive is ready to accept the command. */ -static int cdrom_start_read_continuation (ide_dev_t *dev) +static int cdrom_start_read_continuation (ide_drive_t *drive) { struct packet_command pc; - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; int nsect, sector, nframes, frame, nskip; @@ -1033,9 +980,9 @@ if (rq->current_nr_sectors != (rq->bh->b_size >> SECTOR_BITS)) { printk ("%s: cdrom_start_read_continuation: buffer botch (%ld)\n", - dev->name, rq->current_nr_sectors); - cdrom_end_request (0, dev); - DO_REQUEST; + drive->name, rq->current_nr_sectors); + cdrom_end_request (0, drive); + IDE_DO_REQUEST; return 1; } @@ -1071,11 +1018,11 @@ pc.c[5] = conv.b.b0; } - if (cdrom_transfer_packet_command (dev, pc.c, sizeof (pc.c))) + if (cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c))) return 1; /* Set up our interrupt handler and return. */ - ide_handler[DEV_HWIF] = cdrom_read_intr; + ide_set_handler(drive, &cdrom_read_intr); /* BUG: do this BEFORE triggering drive */ return 0; } @@ -1087,29 +1034,29 @@ * 1 if there was an error and we should either retry or move on to the * next request. */ -static int cdrom_start_read (ide_dev_t *dev, unsigned int block) +static int cdrom_start_read (ide_drive_t *drive, unsigned int block) { - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; /* We may be retrying this request after an error. Fix up any weirdness which might be present in the request packet. */ restore_request (rq); /* Satisfy whatever we can of this request from our cached sector. */ - if (cdrom_read_from_buffer (dev)) + if (cdrom_read_from_buffer (drive)) return 1; /* Clear the local sector buffer. */ - cdrom_info[DEV_HWIF][dev->select.b.drive].nsectors_buffered = 0; + drive->cdrom_info.nsectors_buffered = 0; - if (cdrom_start_packet_command (dev, 32768)) + if (cdrom_start_packet_command (drive, 32768)) return 1; - if (CDROM_FLAGS (dev)->drq_interrupt) - ide_handler[DEV_HWIF] = (void (*)(ide_dev_t *))cdrom_start_read_continuation; + if (CDROM_FLAGS (drive)->drq_interrupt) + ide_set_handler(drive, (ide_handler_t *)&cdrom_start_read_continuation); /* BUG: do this BEFORE triggering drive */ else { - if (cdrom_start_read_continuation (dev)) + if (cdrom_start_read_continuation (drive)) return 1; } @@ -1125,22 +1072,22 @@ /* Forward declaration */ static int -cdrom_request_sense (ide_dev_t *dev, struct atapi_request_sense *reqbuf); +cdrom_request_sense (ide_drive_t *drive, struct atapi_request_sense *reqbuf); /* Interrupt routine for packet command completion. */ -static void cdrom_pc_intr (ide_dev_t *dev) +static void cdrom_pc_intr (ide_drive_t *drive) { int ireason, len, stat, thislen; - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; struct packet_command *pc = (struct packet_command *)rq->buffer; /* Check for errors. */ - if (cdrom_decode_status (dev, 0, &stat)) return; + if (cdrom_decode_status (drive, 0, &stat)) return; /* Read the interrupt reason and the transfer length. */ - ireason = IN_BYTE (HD_NSECTOR, DEV_HWIF); - len = IN_BYTE (HD_LCYL, DEV_HWIF) + 256 * IN_BYTE (HD_HCYL, DEV_HWIF); + ireason = IN_BYTE (IDE_NSECTOR_REG); + len = IN_BYTE (IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG); /* If DRQ is clear, the command has completed. Complain if we still have data left to transfer. */ @@ -1156,15 +1103,15 @@ } if (pc->buflen == 0) - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); else { printk ("%s: cdrom_pc_intr: data underrun %d\n", - dev->name, pc->buflen); + drive->name, pc->buflen); pc->stat = 1; - cdrom_end_request (1, dev); + cdrom_end_request (1, drive); } - DO_REQUEST; + IDE_DO_REQUEST; return; } @@ -1180,7 +1127,7 @@ if (pc->buflen > 0) { printk ("%s: cdrom_pc_intr: Drive wants to transfer data the wrong way!\n", - dev->name); + drive->name); pc->stat = 1; thislen = 0; } @@ -1209,7 +1156,7 @@ if (pc->buflen < 0) { printk ("%s: cdrom_pc_intr: Drive wants to transfer data the wrong way!\n", - dev->name); + drive->name); pc->stat = 1; thislen = 0; } @@ -1234,34 +1181,34 @@ else { printk ("%s: cdrom_pc_intr: The drive appears confused (ireason = 0x%2x)\n", - dev->name, ireason); + drive->name, ireason); pc->stat = 1; } /* Now we wait for another interrupt. */ - ide_handler[DEV_HWIF] = cdrom_pc_intr; + ide_set_handler(drive, &cdrom_pc_intr); /* this one is okay */ } -static int cdrom_do_pc_continuation (ide_dev_t *dev) +static int cdrom_do_pc_continuation (ide_drive_t *drive) { - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; struct packet_command *pc = (struct packet_command *)rq->buffer; - if (cdrom_transfer_packet_command (dev, pc->c, sizeof (pc->c))) + if (cdrom_transfer_packet_command (drive, pc->c, sizeof (pc->c))) return 1; /* Set up our interrupt handler and return. */ - ide_handler[DEV_HWIF] = cdrom_pc_intr; + ide_set_handler(drive, &cdrom_pc_intr); /* BUG: do this BEFORE triggering drive */ return 0; } -static int cdrom_do_packet_command (ide_dev_t *dev) +static int cdrom_do_packet_command (ide_drive_t *drive) { int len; - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; struct packet_command *pc = (struct packet_command *)rq->buffer; len = pc->buflen; @@ -1269,14 +1216,14 @@ pc->stat = 0; - if (cdrom_start_packet_command (dev, len)) + if (cdrom_start_packet_command (drive, len)) return 1; - if (CDROM_FLAGS (dev)->drq_interrupt) - ide_handler[DEV_HWIF] = (void (*)(ide_dev_t *))cdrom_do_pc_continuation; + if (CDROM_FLAGS (drive)->drq_interrupt) + ide_set_handler(drive, (ide_handler_t *)&cdrom_do_pc_continuation); /* BUG: do this BEFORE triggering drive */ else { - if (cdrom_do_pc_continuation (dev)) + if (cdrom_do_pc_continuation (drive)) return 1; } @@ -1285,16 +1232,16 @@ static -int cdrom_queue_packet_command (ide_dev_t *dev, struct packet_command *pc) +int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc) { int retries = 3; unsigned long flags; struct request req, **p, **pfirst; struct semaphore sem = MUTEX_LOCKED; - int major = ide_major[DEV_HWIF]; + int major = HWIF(drive)->major; retry: - req.dev = MKDEV (major, (dev->select.b.drive) << PARTN_BITS); + req.dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS); req.cmd = PACKET_COMMAND; req.errors = 0; req.sector = 0; @@ -1330,15 +1277,14 @@ for this drive. Check to be sure that it wasn't a request sense request that failed, though, to prevent infinite loops. */ - struct atapi_request_sense *reqbuf = - &cdrom_info[DEV_HWIF][dev->select.b.drive].sense_data; + struct atapi_request_sense *reqbuf = &drive->cdrom_info.sense_data; - if (pc->c[0] == REQUEST_SENSE || cdrom_request_sense (dev, reqbuf)) + if (pc->c[0] == REQUEST_SENSE || cdrom_request_sense (drive, reqbuf)) { memset (reqbuf, 0, sizeof (*reqbuf)); reqbuf->asc = 0xff; } - cdrom_analyze_sense_data (dev, reqbuf, pc); + cdrom_analyze_sense_data (drive, reqbuf, pc); /* If the error was a unit attention (usually means media was changed), retry the command. */ @@ -1360,21 +1306,19 @@ * cdrom driver request routine. */ -static int do_rw_cdrom (ide_dev_t *dev, unsigned long block) +void ide_do_rw_cdrom (ide_drive_t *drive, unsigned long block) { - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; if (rq -> cmd == PACKET_COMMAND || rq -> cmd == REQUEST_SENSE_COMMAND) - return cdrom_do_packet_command (dev); - - if (rq -> cmd != READ) + cdrom_do_packet_command (drive); + else if (rq -> cmd != READ) { printk ("ide-cd: bad cmd %d\n", rq -> cmd); - cdrom_end_request (0, dev); - return 1; + cdrom_end_request (0, drive); } - - return cdrom_start_read (dev, block); + else + cdrom_start_read (drive, block); } @@ -1433,7 +1377,7 @@ static void -cdrom_check_status (ide_dev_t *dev) +cdrom_check_status (ide_drive_t *drive) { struct packet_command pc; @@ -1441,12 +1385,12 @@ pc.c[0] = TEST_UNIT_READY; - (void) cdrom_queue_packet_command (dev, &pc); + (void) cdrom_queue_packet_command (drive, &pc); } static int -cdrom_request_sense (ide_dev_t *dev, struct atapi_request_sense *reqbuf) +cdrom_request_sense (ide_drive_t *drive, struct atapi_request_sense *reqbuf) { struct packet_command pc; @@ -1457,14 +1401,14 @@ pc.buffer = (char *)reqbuf; pc.buflen = sizeof (*reqbuf); - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } #if 0 /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ static int -cdrom_lockdoor (ide_dev_t *dev, int lockflag) +cdrom_lockdoor (ide_drive_t *drive, int lockflag) { struct packet_command pc; @@ -1472,7 +1416,7 @@ pc.c[0] = ALLOW_MEDIUM_REMOVAL; pc.c[4] = (lockflag != 0); - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } #endif @@ -1480,7 +1424,7 @@ /* Eject the disk if EJECTFLAG is 0. If EJECTFLAG is 1, try to reload the disk. */ static int -cdrom_eject (ide_dev_t *dev, int ejectflag) +cdrom_eject (ide_drive_t *drive, int ejectflag) { struct packet_command pc; @@ -1488,12 +1432,12 @@ pc.c[0] = START_STOP; pc.c[4] = 2 + (ejectflag != 0); - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } static int -cdrom_pause (ide_dev_t *dev, int pauseflag) +cdrom_pause (ide_drive_t *drive, int pauseflag) { struct packet_command pc; @@ -1501,12 +1445,12 @@ pc.c[0] = SCMD_PAUSE_RESUME; pc.c[8] = !pauseflag; - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } static int -cdrom_startstop (ide_dev_t *dev, int startflag) +cdrom_startstop (ide_drive_t *drive, int startflag) { struct packet_command pc; @@ -1515,12 +1459,12 @@ pc.c[0] = START_STOP; pc.c[1] = 1; pc.c[4] = startflag; - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } static int -cdrom_read_tocentry (ide_dev_t *dev, int trackno, int msf_flag, +cdrom_read_tocentry (ide_drive_t *drive, int trackno, int msf_flag, char *buf, int buflen) { struct packet_command pc; @@ -1534,44 +1478,44 @@ pc.c[7] = (buflen >> 8); pc.c[8] = (buflen & 0xff); if (msf_flag) pc.c[1] = 2; - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } /* Try to read the entire TOC for the disk into our internal buffer. */ static int -cdrom_read_toc (ide_dev_t *dev) +cdrom_read_toc (ide_drive_t *drive) { int msf_flag; int stat, ntracks, i; - struct atapi_toc *toc = cdrom_info[DEV_HWIF][dev->select.b.drive].toc; + struct atapi_toc *toc = drive->cdrom_info.toc; if (toc == NULL) { /* Try to allocate space. */ toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc), GFP_KERNEL); - cdrom_info[DEV_HWIF][dev->select.b.drive].toc = toc; + drive->cdrom_info.toc = toc; } if (toc == NULL) { - printk ("%s: No cdrom TOC buffer!\n", dev->name); + printk ("%s: No cdrom TOC buffer!\n", drive->name); return -EIO; } /* Check to see if the existing data is still valid. If it is, just return. */ - if (CDROM_FLAGS (dev)->toc_valid) - cdrom_check_status (dev); + if (CDROM_FLAGS (drive)->toc_valid) + cdrom_check_status (drive); - if (CDROM_FLAGS (dev)->toc_valid) return 0; + if (CDROM_FLAGS (drive)->toc_valid) return 0; /* Some drives can't return TOC data in LBA format. */ - msf_flag = (CDROM_FLAGS (dev)->no_lba_toc); + msf_flag = (CDROM_FLAGS (drive)->no_lba_toc); /* First read just the header, so we know how long the TOC is. */ - stat = cdrom_read_tocentry (dev, 0, msf_flag, (char *)toc, + stat = cdrom_read_tocentry (drive, 0, msf_flag, (char *)toc, sizeof (struct atapi_toc_header) + sizeof (struct atapi_toc_entry)); if (stat) return stat; @@ -1581,7 +1525,7 @@ if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS; /* Now read the whole schmeer. */ - stat = cdrom_read_tocentry (dev, 0, msf_flag, (char *)toc, + stat = cdrom_read_tocentry (drive, 0, msf_flag, (char *)toc, sizeof (struct atapi_toc_header) + (ntracks+1) * sizeof (struct atapi_toc_entry)); if (stat) return stat; @@ -1598,14 +1542,14 @@ } /* Remember that we've read this stuff. */ - CDROM_FLAGS (dev)->toc_valid = 1; + CDROM_FLAGS (drive)->toc_valid = 1; return 0; } static int -cdrom_read_subchannel (ide_dev_t *dev, +cdrom_read_subchannel (ide_drive_t *drive, char *buf, int buflen) { struct packet_command pc; @@ -1619,13 +1563,13 @@ pc.c[3] = 0x01; /* Format 1: current position */ pc.c[7] = (buflen >> 8); pc.c[8] = (buflen & 0xff); - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } /* modeflag: 0 = current, 1 = changeable mask, 2 = default, 3 = saved */ static int -cdrom_mode_sense (ide_dev_t *dev, int pageno, int modeflag, +cdrom_mode_sense (ide_drive_t *drive, int pageno, int modeflag, char *buf, int buflen) { struct packet_command pc; @@ -1638,12 +1582,12 @@ pc.c[2] = pageno | (modeflag << 6); pc.c[7] = (buflen >> 8); pc.c[8] = (buflen & 0xff); - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } static int -cdrom_mode_select (ide_dev_t *dev, int pageno, char *buf, int buflen) +cdrom_mode_select (ide_drive_t *drive, int pageno, char *buf, int buflen) { struct packet_command pc; @@ -1656,12 +1600,12 @@ pc.c[2] = pageno; pc.c[7] = (buflen >> 8); pc.c[8] = (buflen & 0xff); - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } static int -cdrom_play_lba_range_play12 (ide_dev_t *dev, int lba_start, int lba_end) +cdrom_play_lba_range_play12 (ide_drive_t *drive, int lba_start, int lba_end) { struct packet_command pc; @@ -1673,12 +1617,12 @@ byte_swap_long ((int *)(&pc.c[2])); byte_swap_long ((int *)(&pc.c[6])); - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } static int -cdrom_play_lba_range_msf (ide_dev_t *dev, int lba_start, int lba_end) +cdrom_play_lba_range_msf (ide_drive_t *drive, int lba_start, int lba_end) { struct packet_command pc; @@ -1688,7 +1632,7 @@ lba_to_msf (lba_start, &pc.c[3], &pc.c[4], &pc.c[5]); lba_to_msf (lba_end-1, &pc.c[6], &pc.c[7], &pc.c[8]); - if (CDROM_FLAGS (dev)->msf_as_bcd) + if (CDROM_FLAGS (drive)->msf_as_bcd) { pc.c[3] = bin2bcd (pc.c[3]); pc.c[4] = bin2bcd (pc.c[4]); @@ -1698,14 +1642,14 @@ pc.c[8] = bin2bcd (pc.c[8]); } - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } /* Play audio starting at LBA LBA_START and finishing with the LBA before LBA_END. */ static int -cdrom_play_lba_range (ide_dev_t *dev, int lba_start, int lba_end) +cdrom_play_lba_range (ide_drive_t *drive, int lba_start, int lba_end) { /* This is rather annoying. My NEC-260 won't recognize group 5 commands such as PLAYAUDIO12; @@ -1718,27 +1662,27 @@ great. Otherwise, if the drive reports an illegal command code, try PLAYAUDIO_MSF using the NEC 260-style bcd parameters. */ - if (CDROM_FLAGS (dev)->no_playaudio12) - return cdrom_play_lba_range_msf (dev, lba_start, lba_end); + if (CDROM_FLAGS (drive)->no_playaudio12) + return cdrom_play_lba_range_msf (drive, lba_start, lba_end); else { int stat; struct atapi_request_sense *reqbuf; - stat = cdrom_play_lba_range_play12 (dev, lba_start, lba_end); + stat = cdrom_play_lba_range_play12 (drive, lba_start, lba_end); if (stat == 0) return 0; /* It failed. Try to find out why. */ - reqbuf = &cdrom_info[DEV_HWIF][dev->select.b.drive].sense_data; + reqbuf = &drive->cdrom_info.sense_data; if (reqbuf->sense_key == 0x05 && reqbuf->asc == 0x20) { /* The drive didn't recognize the command. Retry with the MSF variant. */ printk ("%s: Drive does not support PLAYAUDIO12; " - "trying PLAYAUDIO_MSF\n", dev->name); - CDROM_FLAGS (dev)->no_playaudio12 = 1; - CDROM_FLAGS (dev)->msf_as_bcd = 1; - return cdrom_play_lba_range_msf (dev, lba_start, lba_end); + "trying PLAYAUDIO_MSF\n", drive->name); + CDROM_FLAGS (drive)->no_playaudio12 = 1; + CDROM_FLAGS (drive)->msf_as_bcd = 1; + return cdrom_play_lba_range_msf (drive, lba_start, lba_end); } /* Failed for some other reason. Give up. */ @@ -1748,17 +1692,17 @@ static -int cdrom_get_toc_entry (ide_dev_t *dev, int track, +int cdrom_get_toc_entry (ide_drive_t *drive, int track, struct atapi_toc_entry **ent) { int stat, ntracks; struct atapi_toc *toc; /* Make sure our saved TOC is valid. */ - stat = cdrom_read_toc (dev); + stat = cdrom_read_toc (drive); if (stat) return stat; - toc = cdrom_info[DEV_HWIF][dev->select.b.drive].toc; + toc = drive->cdrom_info.toc; /* Check validity of requested track number. */ ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; @@ -1774,25 +1718,25 @@ } -static int ide_cdrom_ioctl (ide_dev_t *dev, struct inode *inode, +int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { case CDROMEJECT: - return cdrom_eject (dev, 0); + return cdrom_eject (drive, 0); case CDROMPAUSE: - return cdrom_pause (dev, 1); + return cdrom_pause (drive, 1); case CDROMRESUME: - return cdrom_pause (dev, 0); + return cdrom_pause (drive, 0); case CDROMSTART: - return cdrom_startstop (dev, 1); + return cdrom_startstop (drive, 1); case CDROMSTOP: - return cdrom_startstop (dev, 0); + return cdrom_startstop (drive, 0); case CDROMPLAYMSF: { @@ -1811,7 +1755,7 @@ if (lba_end <= lba_start) return -EINVAL; - return cdrom_play_lba_range (dev, lba_start, lba_end); + return cdrom_play_lba_range (drive, lba_start, lba_end); } /* Like just about every other Linux cdrom driver, we ignore the @@ -1827,9 +1771,9 @@ memcpy_fromfs (&ti, (void *) arg, sizeof(ti)); - stat = cdrom_get_toc_entry (dev, ti.cdti_trk0, &first_toc); + stat = cdrom_get_toc_entry (drive, ti.cdti_trk0, &first_toc); if (stat) return stat; - stat = cdrom_get_toc_entry (dev, ti.cdti_trk1, &last_toc); + stat = cdrom_get_toc_entry (drive, ti.cdti_trk1, &last_toc); if (stat) return stat; if (ti.cdti_trk1 != CDROM_LEADOUT) ++last_toc; @@ -1838,7 +1782,7 @@ if (lba_end <= lba_start) return -EINVAL; - return cdrom_play_lba_range (dev, lba_start, lba_end); + return cdrom_play_lba_range (drive, lba_start, lba_end); } case CDROMREADTOCHDR: @@ -1851,10 +1795,10 @@ if (stat) return stat; /* Make sure our saved TOC is valid. */ - stat = cdrom_read_toc (dev); + stat = cdrom_read_toc (drive); if (stat) return stat; - toc = cdrom_info[DEV_HWIF][dev->select.b.drive].toc; + toc = drive->cdrom_info.toc; tochdr.cdth_trk0 = toc->hdr.first_track; tochdr.cdth_trk1 = toc->hdr.last_track; @@ -1876,7 +1820,7 @@ memcpy_fromfs (&tocentry, (void *) arg, sizeof (tocentry)); - stat = cdrom_get_toc_entry (dev, tocentry.cdte_track, &toce); + stat = cdrom_get_toc_entry (drive, tocentry.cdte_track, &toce); if (stat) return stat; tocentry.cdte_ctrl = toce->control; @@ -1911,7 +1855,7 @@ memcpy_fromfs (&subchnl, (void *) arg, sizeof (subchnl)); - stat = cdrom_read_subchannel (dev, buffer, sizeof (buffer)); + stat = cdrom_read_subchannel (drive, buffer, sizeof (buffer)); if (stat) return stat; abs_lba = *(int *)&buffer[8]; @@ -1956,9 +1900,9 @@ if (stat) return stat; memcpy_fromfs (&volctrl, (void *) arg, sizeof (volctrl)); - stat = cdrom_mode_sense (dev, 0x0e, 0, buffer, sizeof (buffer)); + stat = cdrom_mode_sense (drive, 0x0e, 0, buffer, sizeof (buffer)); if (stat) return stat; - stat = cdrom_mode_sense (dev, 0x0e, 1, mask , sizeof (buffer)); + stat = cdrom_mode_sense (drive, 0x0e, 1, mask , sizeof (buffer)); if (stat) return stat; buffer[1] = buffer[2] = 0; @@ -1968,7 +1912,7 @@ buffer[21] = volctrl.channel2 & mask[21]; buffer[23] = volctrl.channel3 & mask[23]; - return cdrom_mode_select (dev, 0x0e, buffer, sizeof (buffer)); + return cdrom_mode_select (drive, 0x0e, buffer, sizeof (buffer)); } #ifdef TEST @@ -1983,7 +1927,7 @@ if (stat) return stat; memcpy_fromfs (&pc.c, (void *) arg, sizeof (pc.c)); - return cdrom_queue_packet_command (dev, &pc); + return cdrom_queue_packet_command (drive, &pc); } case 0x1235: @@ -1994,7 +1938,7 @@ stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (reqbuf)); if (stat) return stat; - stat = cdrom_request_sense (dev, &reqbuf); + stat = cdrom_request_sense (drive, &reqbuf); memcpy_tofs ((void *) arg, &reqbuf, sizeof (reqbuf)); @@ -2014,29 +1958,28 @@ * Other driver requests (open, close, check media change). */ -static int cdrom_check_media_change (ide_dev_t *dev) +int ide_cdrom_check_media_change (ide_drive_t *drive) { int retval; - cdrom_check_status (dev); + cdrom_check_status (drive); - retval = CDROM_FLAGS (dev)->media_changed; - CDROM_FLAGS (dev)->media_changed = 0; + retval = CDROM_FLAGS (drive)->media_changed; + CDROM_FLAGS (drive)->media_changed = 0; return retval; } -static int -cdrom_open (struct inode *ip, struct file *fp, ide_dev_t *dev) +int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive) { /* no write access */ if (fp->f_mode & 2) return -EROFS; #if 0 /* With this, one cannot eject a disk with workman */ /* If this is the first open, lock the door. */ - if (dev->usage == 1) - (void) cdrom_lockdoor (dev, 1); + if (drive->usage == 1) + (void) cdrom_lockdoor (drive, 1); #endif /* Should check that there's a disk in the drive? */ @@ -2048,16 +1991,15 @@ * Close down the device. Invalidate all cached blocks. */ -static void -cdrom_release (struct inode *inode, struct file *file, ide_dev_t *dev) +void ide_cdrom_release (struct inode *inode, struct file *file, ide_drive_t *drive) { - if (dev->usage == 0) + if (drive->usage == 0) { invalidate_buffers (inode->i_rdev); #if 0 /* Unlock the door. */ - (void) cdrom_lockdoor (dev, 0); + (void) cdrom_lockdoor (drive, 0); #endif } } @@ -2068,43 +2010,41 @@ * Device initialization. */ -static void cdrom_setup (ide_dev_t *dev) +void ide_cdrom_setup (ide_drive_t *drive) { - /* Just guess at capacity for now. */ - ide_capacity[DEV_HWIF][dev->select.b.drive] = 0x1fffff; - - ide_blksizes[DEV_HWIF][dev->select.b.drive << PARTN_BITS] = CD_FRAMESIZE; + blksize_size[HWIF(drive)->major][drive->select.b.unit << PARTN_BITS] = CD_FRAMESIZE; - dev->special.all = 0; + drive->special.all = 0; + drive->ready_stat = 0; - CDROM_FLAGS (dev)->media_changed = 0; - CDROM_FLAGS (dev)->toc_valid = 0; + CDROM_FLAGS (drive)->media_changed = 0; + CDROM_FLAGS (drive)->toc_valid = 0; - CDROM_FLAGS (dev)->no_playaudio12 = 0; - CDROM_FLAGS (dev)->no_lba_toc = 0; - CDROM_FLAGS (dev)->msf_as_bcd = 0; - CDROM_FLAGS (dev)->drq_interrupt = ((dev->id->config & 0x0060) == 0x20); + CDROM_FLAGS (drive)->no_playaudio12 = 0; + CDROM_FLAGS (drive)->no_lba_toc = 0; + CDROM_FLAGS (drive)->msf_as_bcd = 0; + CDROM_FLAGS (drive)->drq_interrupt = ((drive->id->config & 0x0060) == 0x20); /* Accommodate some broken drives... */ - if (strcmp (dev->id->model, "CD220E") == 0) /* Creative Labs */ - CDROM_FLAGS (dev)->no_lba_toc = 1; + if (strcmp (drive->id->model, "CD220E") == 0) /* Creative Labs */ + CDROM_FLAGS (drive)->no_lba_toc = 1; - else if (strcmp (dev->id->model, "TO-ICSLYAL") == 0 || /* Acer CD525E */ - strcmp (dev->id->model, "OTI-SCYLLA") == 0) - CDROM_FLAGS (dev)->no_lba_toc = 1; + else if (strcmp (drive->id->model, "TO-ICSLYAL") == 0 || /* Acer CD525E */ + strcmp (drive->id->model, "OTI-SCYLLA") == 0) + CDROM_FLAGS (drive)->no_lba_toc = 1; - else if (strcmp (dev->id->model, "CDA26803I SE") == 0) /* Aztech */ + else if (strcmp (drive->id->model, "CDA26803I SE") == 0) /* Aztech */ { - CDROM_FLAGS (dev)->no_lba_toc = 1; + CDROM_FLAGS (drive)->no_lba_toc = 1; /* This drive _also_ does not implement PLAYAUDIO12 correctly. */ - CDROM_FLAGS (dev)->no_playaudio12 = 1; + CDROM_FLAGS (drive)->no_playaudio12 = 1; } - cdrom_info[DEV_HWIF][dev->select.b.drive].toc = NULL; - cdrom_info[DEV_HWIF][dev->select.b.drive].sector_buffer = NULL; - cdrom_info[DEV_HWIF][dev->select.b.drive].sector_buffered = 0; - cdrom_info[DEV_HWIF][dev->select.b.drive].nsectors_buffered = 0; + drive->cdrom_info.toc = NULL; + drive->cdrom_info.sector_buffer = NULL; + drive->cdrom_info.sector_buffered = 0; + drive->cdrom_info.nsectors_buffered = 0; } diff -u --recursive --new-file v1.3.18/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v1.3.18/linux/drivers/block/ide.c Tue Aug 8 12:31:33 1995 +++ linux/drivers/block/ide.c Tue Aug 15 20:05:34 1995 @@ -1,17 +1,19 @@ /* - * linux/drivers/block/ide.c Version 4.11 Jul 29, 1995 + * linux/drivers/block/ide.c Version 5.03 Aug 13, 1995 * * Copyright (C) 1994, 1995 Linus Torvalds & authors (see below) */ /* - * This is the dual IDE interface driver, as evolved from hd.c. - * It supports up to two IDE interfaces, on one or two IRQs (usually 14 & 15). + * This is the multiple IDE interface driver, as evolved from hd.c. + * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). * There can be up to two drives per interface, as per the ATA-2 spec. * - * Primary i/f: ide0: major=3; (hda) minor=0, (hdb) minor=64 - * Secondary i/f: ide1: major=22; (hdc or hd1a) minor=0, (hdd or hd1b) minor=64 - * + * Primary i/f: ide0: major=3; (hda) minor=0; (hdb) minor=64 + * Secondary i/f: ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64 + * Tertiary i/f: ide2: major=33; (hde) minor=0; (hdf) minor=64 + * Quaternary i/f: ide3: major=34; (hdg) minor=0; (hdh) minor=64 + * * From hd.c: * | * | It traverses the request-list, using interrupts to jump between functions. @@ -60,7 +62,7 @@ * cdrom probe fixes, inspired by jprang@uni-duisburg.de * Version 3.9 don't use LBA if lba_capacity looks funny * correct the drive capacity calculations - * fix probing for old Seagates without HD_ALTSTATUS + * fix probing for old Seagates without IDE_ALTSTATUS_REG * fix byte-ordering for some NEC cdrom drives * Version 3.10 disable multiple mode by default; was causing trouble * Version 3.11 fix mis-identification of old WD disks as cdroms @@ -72,9 +74,9 @@ * ignore INDEX bit when checking the ALTSTATUS reg * Version 3.15 add SINGLE_THREADED flag for use with dual-CMD i/f * ignore WRERR_STAT for non-write operations - * added VLB_SYNC support for DC-2000A & others, + * added vlb_sync support for DC-2000A & others, * (incl. some Promise chips), courtesy of Frank Gockel - * Version 3.16 convert VLB_32BIT and VLB_SYNC into runtime flags + * Version 3.16 convert vlb_32bit and vlb_sync into runtime flags * add ioctls to get/set VLB flags (HDIO_[SG]ET_CHIPSET) * rename SINGLE_THREADED to SUPPORT_SERIALIZE, * add boot flag to "serialize" operation for CMD i/f @@ -86,7 +88,7 @@ * Version 4.00 tidy up verify_area() calls - heiko@colossus.escape.de * add flag to ignore WRERR_STAT for some drives * courtesy of David.H.West@um.cc.umich.edu - * assembly syntax tweak to VLB_SYNC + * assembly syntax tweak to vlb_sync * removeable drive support from scuba@cs.tu-berlin.de * add transparent support for DiskManager-6.0x "Dynamic * Disk Overlay" (DDO), most of this in in genhd.c @@ -95,312 +97,70 @@ * fix DM6:DDO support -- now works with LILO, fdisk, ... * don't treat some naughty WD drives as removeable * Version 4.11 updated DM6 support using info provided by OnTrack + * Version 5.00 major overhaul, multmode setting fixed, vlb_sync fixed + * added support for 3rd/4th/alternative IDE ports + * created ide.h; ide-cd.c now compiles separate from ide.c + * hopefully fixed infinite "unexpected_intr" from cdroms + * zillions of other changes and restructuring + * somehow reduced overall memory usage by several kB + * probably slowed things down slightly, but worth it + * Version 5.01 AT LAST!! Finally understood why "unexpected_intr" + * was happening at various times/places: whenever the + * ide-interface's ctl_port was used to "mask" the irq, + * it also would trigger an edge in the process of masking + * which would result in a self-inflicted interrupt!! + * (such a stupid way to build a hardware interrupt mask). + * This is now fixed (after a year of head-scratching). + * Version 5.02 got rid of need for {enable,disable}_irq_list() + * Version 5.03 tune-ups, comments, remove "busy wait" from drive resets + * removed PROBE_FOR_IRQS option -- no longer needed + * OOOPS! fixed "bad access" bug for 2nd drive on an i/f + * + * Driver compile-time options are in ide.h * - * To do: - * - add support for alternative IDE port addresses - * - refine the DiskManager-6.0x overlay support (special cases) - * - improved CMD support: tech info is in my hands for 640B chip - * - special 32-bit controller-type detection & support - * - figure out how to support oddball "intelligent" caching cards - * - reverse-engineer 3/4 drive support on fancy "Promise" cards + * To do, in likely order of completion: + * - add in several updates from my email collection (soon folks!) + * - add full support for Intel Triton chipset, including bus-mastered DMA + * - improved CMD support: handing this off to someone else * - find someone to work on IDE *tape drive* support */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include +#include #include -#include +#include +#include #include #include +#include #include -#include +#include +#include +#include +#include #include -#include -#include - -/***************************************************************************** - * IDE driver configuration options (play with these as desired): - */ -#define REALLY_SLOW_IO /* most systems can safely undef this */ -#include - -#ifdef __alpha__ -# ifndef SUPPORT_VLB_SYNC -# define SUPPORT_VLB_SYNC 0 -# endif -#endif - -#undef REALLY_FAST_IO /* define if ide ports are perfect */ -#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */ -#ifndef SUPPORT_VLB_32BIT /* 1 to support 32bit I/O on VLB */ -#define SUPPORT_VLB_32BIT 1 /* 0 to reduce kernel size */ -#endif -#ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */ -#define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */ -#endif -#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */ -#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */ -#endif -#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */ -#define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */ -#endif -#ifndef SUPPORT_TWO_INTERFACES /* 1 to support one/two interfaces */ -#define SUPPORT_TWO_INTERFACES 1 /* 0 for a smaller, faster kernel */ -#endif -#ifndef OPTIMIZE_IRQS /* 1 for slightly faster code */ -#define OPTIMIZE_IRQS 1 /* 0 to reduce kernel size */ -#endif -#ifndef SUPPORT_SERIALIZE /* 1 to support CMD dual interfaces */ -#define SUPPORT_SERIALIZE 1 /* 0 to reduce kernel size */ -#endif -#ifndef SUPPORT_SHARING_IRQ /* 1 to allow two IDE i/f on one IRQ */ -#define SUPPORT_SHARING_IRQ 1 /* 0 to reduce kernel size */ -#endif -#ifndef SUPPORT_DTC2278 /* 1 to support DTC2278 chipset */ -#define SUPPORT_DTC2278 1 /* 0 to reduce kernel size */ -#endif -#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */ -#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */ -#endif -#define PROBE_FOR_IRQS 1 /* 0 to force use of defaults below */ -#define DEFAULT_IDE0_IRQ 14 /* in case irq-probe fails */ -#define DEFAULT_IDE1_IRQ 15 /* in case irq-probe fails */ - -/* IDE_DRIVE_CMD is used to implement many features of the hdparm utility */ -#define IDE_DRIVE_CMD 99 /* (magic) undef to reduce kernel size*/ - -/* - * "No user-serviceable parts" beyond this point :) - ****************************************************************************** - */ - -/* - * Need to change these elsewhere in the kernel (someday) - */ -#ifndef IDE0_TIMER -#define IDE0_TIMER HD_TIMER -#define IDE1_TIMER HD_TIMER2 -#endif - -/* - * Ensure that various configuration flags have compatible settings - */ -#ifdef REALLY_SLOW_IO -#undef REALLY_FAST_IO -#endif -#ifdef CONFIG_BLK_DEV_HD -#undef SUPPORT_TWO_INTERFACES -#define SUPPORT_TWO_INTERFACES 0 -#endif /* CONFIG_BLK_DEV_HD */ - -#if SUPPORT_TWO_INTERFACES -#define HWIF hwif -#define DEV_HWIF (dev->hwif) -#if SUPPORT_SERIALIZE -#undef SUPPORT_SHARING_IRQ -#define SUPPORT_SHARING_IRQ 1 -#endif -#else -#undef SUPPORT_SERIALIZE -#define SUPPORT_SERIALIZE 0 -#undef OPTIMIZE_IRQS -#define OPTIMIZE_IRQS 0 -#undef SUPPORT_SHARING_IRQ -#define SUPPORT_SHARING_IRQ 0 -#ifdef CONFIG_BLK_DEV_HD -#define HWIF 1 -#else -#define HWIF 0 -#endif /* CONFIG_BLK_DEV_HD */ -#define DEV_HWIF HWIF -#endif /* SUPPORT_TWO_INTERFACES */ -/* - * Definitions for accessing IDE controller registers - */ -typedef unsigned char byte; /* used everywhere */ -#define IDE_PORT(p,hwif) ((p)^((hwif)<<7)) /* IDE0: p^0x00 , IDE1: p^0x80 */ +#include "ide.h" -#ifdef REALLY_FAST_IO -#define OUT_BYTE(b,p) outb((b),IDE_PORT(p,DEV_HWIF)) -#define IN_BYTE(p,hwif) (byte)inb(IDE_PORT(p,hwif)) -#else -#define OUT_BYTE(b,p) outb_p((b),IDE_PORT(p,DEV_HWIF)) -#define IN_BYTE(p,hwif) (byte)inb_p(IDE_PORT(p,hwif)) -#endif /* REALLY_FAST_IO */ - -#if SUPPORT_VLB_32BIT -#if SUPPORT_VLB_SYNC -#define VLB_SYNC __asm__ __volatile__ ("pusha\n movl $0x01f2,%edx\n inb %dx,%al\n inb %dx,%al\n inb %dx,%al\n popa\n") -#endif /* SUPPORT_VLB_SYNC */ -#endif /* SUPPORT_VLB_32BIT */ +static ide_hwif_t ide_hwifs[MAX_HWIFS]; /* hwif info */ +static ide_hwgroup_t *irq_to_hwgroup [16]; +static const byte ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR}; + +static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168}; +static const byte default_irqs[MAX_HWIFS] = {14, 15, 11, 10}; +static int single_threaded = 0; /* "serialize" option */ #if SUPPORT_DTC2278 -static uint probe_dtc2278 = 0; +static unsigned int probe_dtc2278 = 0; #endif -#define GET_ERR(hwif) IN_BYTE(HD_ERROR,hwif) -#define GET_STAT(hwif) IN_BYTE(HD_STATUS,hwif) -#define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good)) -#define BAD_R_STAT (BUSY_STAT | ERR_STAT) -#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) -#define BAD_STAT (BAD_R_STAT | DRQ_STAT) -#define DRIVE_READY (READY_STAT | SEEK_STAT) -#define DATA_READY (DRIVE_READY | DRQ_STAT) - -/* - * Some more useful definitions - */ -#define BIOS_SECTORS(dev) (dev->bios_head*dev->bios_sect*dev->bios_cyl) -#define HD_NAME "hd" /* the same for both i/f; see also genhd.c */ -#define PARTN_BITS 6 /* number of minor dev bits for partitions */ -#define PARTN_MASK ((1< 0) /* - * For really screwy hardware (hey, at least it *can* be used with Linux!) + * For really screwy hardware (hey, at least it *can* be used with Linux) + * we can enforce a minimum delay time between successive operations. */ -#if (DISK_RECOVERY_TIME > 0) -static unsigned long ide_lastreq[] = {0,0}; /* completion time of last I/O */ -#define SET_DISK_RECOVERY_TIMER ide_lastreq[DEV_HWIF] = read_timer(); static unsigned long read_timer(void) { unsigned long t, flags; @@ -415,140 +175,344 @@ restore_flags(flags); return (t - i); } -#else -#define SET_DISK_RECOVERY_TIMER /* nothing */ -#endif /* DISK_RECOVERY_TIME */ -/* - * The heart of the driver, referenced from lots of other routines: - */ -static void do_request (byte hwif); -#define DO_REQUEST {SET_DISK_RECOVERY_TIMER do_request(DEV_HWIF);} +void ide_set_recovery_timer (ide_hwif_t *hwif) +{ + hwif->last_time = read_timer(); +} +#endif /* DISK_RECOVERY_TIME */ /* - * This is a macro rather than an inline to permit better gcc code. - * Caller MUST do sti() before invoking WAIT_STAT() (for jiffies to work). + * init_ide_data() sets reasonable default values into all fields + * of all instances of the hwifs and drives, but only on the first call. + * Subsequent calls have no effect (they don't wipe out anything). * - * This routine should get fixed to not hog the cpu during extra long waits.. - * That could be done by busy-waiting for the first jiffy or two, and then - * setting a timer to wake up at half second intervals thereafter, - * until WAIT_WORSTCASE is achieved, before timing out. + * This routine is normally called at driver initialization time, + * but may also be called MUCH earlier during kernel "command-line" + * parameter processing. As such, we cannot depend on any other parts + * of the kernel (such as memory allocation) to be functioning yet. + * + * This is too bad, as otherwise we could dynamically allocate the + * ide_drive_t structs as needed, rather than always consuming memory + * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them. */ -#define WAIT_STAT(dev,good,bad,timeout,msg,label) \ -{ \ - byte stat; \ - udelay(1); /* spec allows drive 400ns to assert "BUSY" */ \ - if (GET_STAT(DEV_HWIF) & BUSY_STAT) { \ - unsigned long timer = jiffies + timeout; \ - do { \ - if ((GET_STAT(DEV_HWIF) & BUSY_STAT) == 0) \ - break; \ - } while (timer > jiffies); \ - } \ - udelay(1); /* spec allows 400ns for status to stabilize */ \ - if (!OK_STAT(stat=GET_STAT(DEV_HWIF), good, bad)) { \ - ide_error(dev, msg " error", stat); \ - goto label; \ - } \ +static void init_ide_data (void) +{ + unsigned int h, unit; + static unsigned long magic_cookie = 0x12345678; + + if (magic_cookie != 0x12345678) + return; /* already initialized */ + magic_cookie = 0; + + for (h = 0; h < 16; ++h) + irq_to_hwgroup[h] = NULL; + + for (h = 0; h < MAX_HWIFS; ++h) { + ide_hwif_t *hwif = &ide_hwifs[h]; + + hwif->noprobe = (h > 1); + hwif->hwgroup = NULL; + hwif->io_base = default_io_base[h]; + hwif->ctl_port = hwif->io_base ? hwif->io_base + 0x206 : 0x000; +#ifdef CONFIG_BLK_DEV_HD + if (hwif->io_base == HD_DATA) + hwif->noprobe = 1; /* may be overriden by ide_setup() */ +#endif /* CONFIG_BLK_DEV_HD */ + hwif->gd = NULL; + hwif->irq = 0; /* default_irqs[h] used when probe fails */ + hwif->major = ide_hwif_to_major[h]; + hwif->name[0] = 'i'; + hwif->name[1] = 'd'; + hwif->name[2] = 'e'; + hwif->name[3] = '0' + h; + hwif->name[4] = '\0'; + hwif->present = 0; + hwif->next = NULL; + hwif->reset_timeout = 0; + + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + + /* bulk initialize drive info with zeros */ + byte *p = ((byte *) drive) + sizeof(ide_drive_t); + do { + *--p = 0; + } while (p > (byte *) drive); + + /* fill in any non-zero initial values */ + drive->select.all = (unit<<4)|0xa0; + drive->hwif = hwif; + drive->ctl = 0x08; + drive->ready_stat = READY_STAT; + drive->bad_wstat = BAD_W_STAT; + drive->special.b.recalibrate = 1; + drive->special.b.set_geometry = 1; + drive->name[0] = 'h'; + drive->name[1] = 'd'; + drive->name[2] = 'a' + (h * MAX_DRIVES) + unit; + } + } +} + +#ifdef __i386__ +#define VLB_SYNC 1 + +static inline void do_vlb_sync (unsigned short port) { + unsigned int _v; + __asm__ __volatile__ ( + "inb %w1,%b0\n\t" + "inb %w1,%b0\n\t" + "inb %w1,%b0" + : "=&a" (_v) /* outputs */ + : "d" (port) ); /* inputs */ } +#endif /* __i386__ */ /* * This is used for all data transfers *from* the IDE interface */ -void input_ide_data (ide_dev_t *dev, void *buffer, uint wcount) +void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) { -#if SUPPORT_VLB_32BIT - if (dev->vlb_32bit) { -#if SUPPORT_VLB_SYNC - if (dev->vlb_sync) { + if (drive->vlb_32bit) { +#ifdef VLB_SYNC + if (drive->vlb_sync) { cli(); - VLB_SYNC; - insl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount); - if (dev->unmask) + do_vlb_sync(IDE_NSECTOR_REG); + insl(IDE_DATA_REG, buffer, wcount); + if (drive->unmask) sti(); } else -#endif /* SUPPORT_VLB_SYNC */ - insl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount); +#endif /* VLB_SYNC */ + insl(IDE_DATA_REG, buffer, wcount); } else -#endif /* SUPPORT_VLB_32BIT */ - insw(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount<<1); + insw(IDE_DATA_REG, buffer, wcount<<1); } /* * This is used for all data transfers *to* the IDE interface */ -void output_ide_data (ide_dev_t *dev, void *buffer, uint wcount) +void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) { -#if SUPPORT_VLB_32BIT - if (dev->vlb_32bit) { -#if SUPPORT_VLB_SYNC - if (dev->vlb_sync) { + if (drive->vlb_32bit) { +#ifdef VLB_SYNC + if (drive->vlb_sync) { cli(); - VLB_SYNC; - outsl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount); - if (dev->unmask) + do_vlb_sync(IDE_NSECTOR_REG); + outsl(IDE_DATA_REG, buffer, wcount); + if (drive->unmask) sti(); } else - outsl(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount); -#endif /* SUPPORT_VLB_SYNC */ +#endif /* VLB_SYNC */ + outsl(IDE_DATA_REG, buffer, wcount); } else -#endif /* SUPPORT_VLB_32BIT */ - outsw(IDE_PORT(HD_DATA,DEV_HWIF), buffer, wcount<<1); + outsw(IDE_DATA_REG, buffer, wcount<<1); +} + +/* + * This should get invoked any time we exit the driver to + * wait for an interrupt response from a drive. handler() points + * at the appropriate code to handle the next interrupt, and a + * timer is started to prevent us from waiting forever in case + * something goes wrong (see the timer_expiry() handler later on). + */ +void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler) +{ + ide_hwgroup_t *hwgroup = HWGROUP(drive); +#ifdef DEBUG + if (hwgroup->handler != NULL) + printk("%s: ide_set_handler: old handler not null\n", drive->name); +#endif + hwgroup->handler = handler; + hwgroup->timer.expires = jiffies + WAIT_CMD; + add_timer(&(hwgroup->timer)); +} + +/* + * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity" + * value for this drive (from its reported identification information). + * + * Returns: 1 if lba_capacity looks sensible + * 0 otherwise + */ +static int lba_capacity_is_ok (struct hd_driveid *id) +{ + unsigned long lba_sects = id->lba_capacity; + unsigned long chs_sects = id->cyls * id->heads * id->sectors; + unsigned long _10_percent = chs_sects / 10; + + /* perform a rough sanity check on lba_sects: within 10% is "okay" */ + if ((lba_sects - chs_sects) < _10_percent) + return 1; /* lba_capacity is good */ + + /* some drives have the word order reversed */ + lba_sects = (lba_sects << 16) | (lba_sects >> 16); + if ((lba_sects - chs_sects) < _10_percent) { + id->lba_capacity = lba_sects; /* fix it */ + return 1; /* lba_capacity is (now) good */ + } + return 0; /* lba_capacity value is bad */ } /* - * This should get invoked on every exit path from the driver. + * current_capacity() returns the capacity (in sectors) of a drive + * according to its current geometry/LBA settings. */ -static inline void start_ide_timer (byte hwif) +static unsigned long current_capacity (ide_drive_t *drive) { - if (ide_handler[HWIF] != NULL) { /* waiting for an irq? */ - timer_table[ide_timer[HWIF]].expires = jiffies + WAIT_CMD; - timer_active |= ide_timerbit[HWIF]; + struct hd_driveid *id = drive->id; + unsigned long capacity; + + if (!drive->present) + return 0; + if (drive->media != disk) + return 0x1fffff; /* cdrom */ + /* Determine capacity, and use LBA if the drive properly supports it */ + if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) { + drive->select.b.lba = 1; + capacity = id->lba_capacity; + } else { + drive->select.b.lba = 0; + capacity = drive->cyl * drive->head * drive->sect; } + return (capacity - drive->sect0); } -static void do_ide_reset (ide_dev_t *dev) +/* + * ide_geninit() is called exactly *once* for each major, from genhd.c, + * at the beginning of the initial partition check for the drives. + */ +static void ide_geninit (struct gendisk *gd) { - byte tmp; - unsigned long timer, flags; + unsigned int unit; + ide_hwif_t *hwif = gd->real_devices; - save_flags(flags); - sti(); - for (tmp = 0; tmp < MAX_DRIVES; tmp++) { - ide_dev_t *rdev = &ide_dev[DEV_HWIF][tmp]; - rdev->special.b.set_geometry = 1; - rdev->special.b.recalibrate = 1; - rdev->special.b.set_multmode = 0; - if (OK_TO_RESET_CONTROLLER) - rdev->mult_count = 0; - if (!rdev->keep_settings) { - rdev->mult_req = 0; - rdev->unmask = 0; + for (unit = 0; unit < gd->nr_real; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + drive->part[0].nr_sects = current_capacity(drive); + if (!drive->present || drive->media != disk) { + drive->part[0].start_sect = -1; /* skip partition check */ } - if (rdev->mult_req != rdev->mult_count) - rdev->special.b.set_multmode = 1; } + /* + * The partition check in genhd.c needs this string to identify + * our minor devices by name for display purposes. + * Note that doing this will prevent us from working correctly + * if ever called a second time for this major (never happens). + */ + gd->real_devices = hwif->drives[0].name; /* name of first drive */ +} -#if OK_TO_RESET_CONTROLLER - cli(); - OUT_BYTE(dev->ctl|6,HD_CMD); /* set nIEN, set SRST */ - udelay(10); /* more than enough time */ - OUT_BYTE(dev->ctl|2,HD_CMD); /* clear SRST */ - udelay(10); /* more than enough time */ - sti(); /* needed for jiffies */ - for (timer = jiffies + WAIT_WORSTCASE; timer > jiffies;) { - if ((GET_STAT(DEV_HWIF) & BUSY_STAT) == 0) +/* + * ide_alloc(): memory allocation for using during driver initialization. + */ +static unsigned long init_mem_start = 0uL; /* used by init routines */ + +static inline void *ide_alloc (unsigned long bytecount) +{ + unsigned long p = init_mem_start; + if (!p) panic("ide: ide_alloc() not valid now\n"); + init_mem_start += (bytecount + 3uL) & ~3uL; + return (void *) p; +} + +/* + * init_gendisk() (as opposed to ide_geninit) is called for each major device, + * after probing for drives, to allocate partition tables and other data + * structures needed for the routines in genhd.c. ide_geninit() gets called + * somewhat later, during the partition check. + */ +static void init_gendisk (ide_hwif_t *hwif) +{ + struct gendisk *gd; + unsigned int unit, units, minors; + int *bs; + + /* figure out maximum drive number on the interface */ + for (units = MAX_DRIVES; units > 0; --units) { + if (hwif->drives[units-1].present) break; } - printk("%s: do_ide_reset: ", ide_name[DEV_HWIF]); - /* ATAPI devices usually do *not* assert READY after a reset */ - if (!OK_STAT(tmp=GET_STAT(DEV_HWIF), 0, BUSY_STAT)) { - printk("timed-out, status=0x%02x\n", tmp); + minors = units * (1<sizes = ide_alloc(minors * sizeof(int)); + gd->part = ide_alloc(minors * sizeof(struct hd_struct)); + bs = ide_alloc(minors*sizeof(int)); + + /* cdroms and msdos f/s are examples of non-1024 blocksizes */ + blksize_size[hwif->major] = bs; + for (unit = 0; unit < minors; ++unit) + *bs++ = BLOCK_SIZE; + + for (unit = 0; unit < units; ++unit) + hwif->drives[unit].part = &gd->part[unit << PARTN_BITS]; + + gd->major = hwif->major; /* our major device number */ + gd->major_name = IDE_MAJOR_NAME; /* treated special in genhd.c */ + gd->minor_shift = PARTN_BITS; /* num bits for partitions */ + gd->max_p = 1<max_nr = units; /* max num real drives */ + gd->nr_real = units; /* current num real drives */ + gd->init = ide_geninit; /* initialization function */ + gd->real_devices= hwif; /* ptr to internal data */ + + gd->next = gendisk_head; /* link new major into list */ + hwif->gd = gendisk_head = gd; +} + +static void unexpected_intr (int, ide_hwgroup_t *); +/* + * reset_ihandler() is a dummy interrupt handler which we install during + * an ide interface reset operation. This prevents other devices in the + * same hwgroup from being serviced while we play around with shared resources. + * If it ever gets invoked, we call unexpected_intr(), which treats the event + * the same as a timer_expiry(). + */ +static void reset_ihandler (ide_drive_t *drive) +{ + unexpected_intr (HWIF(drive)->irq, HWGROUP(drive)); +} + +/* + * start_reset_timer() sets up a timer event for 50ms in the future, + * to poll for completion of an ide reset operation (no interrupt to help us). + */ +static void start_reset_timer (ide_hwif_t *hwif) +{ + ide_hwgroup_t *hwgroup = hwif->hwgroup; + + hwif->reset_timeout = jiffies + WAIT_WORSTCASE; /* max waiting time */ + hwgroup->handler = &reset_ihandler; /* dummy irq handler */ + hwgroup->timer.expires = jiffies + (HZ/20); /* polling interval */ + add_timer(&(hwgroup->timer)); +} + +/* + * reset_handler() gets invoked to poll the interface for completion every 50ms + * during an ide reset operation. If the drives have not not responded, + * and we have not yet hit our maximum waiting time, then the timer is restarted + * for another 50ms. + * + * Returns 1 if waiting for another 50ms, returns 0 otherwise. + */ +static int reset_handler (ide_hwgroup_t *hwgroup) +{ + ide_hwif_t *hwif = hwgroup->hwif; + ide_drive_t *drive = hwgroup->drive; + byte tmp; + + if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) { + if (jiffies < hwif->reset_timeout) { + start_reset_timer (hwif); + return 1; + } + printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp); } else { - if ((tmp = GET_ERR(DEV_HWIF)) == 1) + printk("%s: reset: ", hwif->name); + if ((tmp = GET_ERR()) == 1) printk("success\n"); else { - printk("%s: ", ide_devname[DEV_HWIF][0]); + printk("master: "); switch (tmp & 0x7f) { case 1: printk("passed"); break; @@ -563,51 +527,114 @@ default:printk("error (0x%02x?)", tmp); } if (tmp & 0x80) - printk("; %s: error", ide_devname[DEV_HWIF][1]); + printk("; slave: failed"); printk("\n"); } } + hwgroup->handler = NULL; /* allow new requests to be processed */ + hwif->reset_timeout = 0; /* signal end of ide reset operation */ + return 0; +} + +/* + * ide_do_reset() attempts to recover a confused drive by resetting it. + * Unfortunately, resetting a disk drive actually resets all devices on + * the same interface, so it can really be thought of as resetting the + * interface rather than resetting the drive. + * + * ATAPI devices have their own reset mechanism (not handled here), + * which allows them to be individually reset without clobbering other + * devices on the same interface. ide-cd.c will handle those separately. + * + * Unfortunately, the IDE interface does not generate an interrupt to let + * us know when the reset operation has finished, so we must poll for this. + * Equally poor, though, is the fact that this may a very long time to complete, + * (up to 30 seconds worstcase). So, instead of busy-waiting here for it, + * we set a timer to poll at 50ms intervals. + */ +static int ide_do_reset (ide_drive_t *drive) +{ + unsigned int unit; + unsigned long flags; + ide_hwif_t *hwif = HWIF(drive); + + save_flags(flags); + cli(); /* Why ? */ + + /* + * First, reset any device state data we were maintaining + * for any of the drives on this interface. + */ + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *rdrive = &hwif->drives[unit]; + rdrive->special.b.set_geometry = 1; + rdrive->special.b.recalibrate = 1; + rdrive->special.b.set_multmode = 0; + if (OK_TO_RESET_CONTROLLER) + rdrive->mult_count = 0; + if (!rdrive->keep_settings) { + rdrive->mult_req = 0; + rdrive->unmask = 0; + } + if (rdrive->mult_req != rdrive->mult_count) + rdrive->special.b.set_multmode = 1; + } + +#if OK_TO_RESET_CONTROLLER + /* + * Note that we also set nIEN while resetting the device, + * to mask unwanted interrupts from the interface during the reset. + * However, due to the design of PC hardware, this will cause an + * immediate interrupt due to the edge transition it produces. + * This single interrupt gives us a "fast poll" for drives that + * recover from reset very quickly, saving us the first 50ms wait time. + */ + OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG); /* set nIEN and SRST */ + udelay(5); /* more than enough time */ + OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */ + hwif->reset_timeout = jiffies + WAIT_WORSTCASE; + start_reset_timer (hwif); /* begin periodic polling */ #endif /* OK_TO_RESET_CONTROLLER */ - restore_flags(flags); + + restore_flags (flags); + return OK_TO_RESET_CONTROLLER; /* 1 = we are waiting, 0 = done */ } /* * Clean up after success/failure of an explicit (ioctl) drive cmd */ -static void end_drive_cmd (ide_dev_t *dev, byte stat, byte err) +static void end_drive_cmd (ide_drive_t *drive, byte stat, byte err) { unsigned long flags; - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; byte *args = (byte *) rq->buffer; rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); if (args) { args[0] = stat; args[1] = err; - args[2] = IN_BYTE(HD_NSECTOR,DEV_HWIF); + args[2] = IN_BYTE(IDE_NSECTOR_REG); } save_flags(flags); cli(); up(rq->sem); - ide_cur_rq[DEV_HWIF] = NULL; + HWGROUP(drive)->rq = NULL; restore_flags(flags); } /* * Error reporting, in human readable form (luxurious, but a memory hog). */ -static byte dump_status (byte hwif, const char *msg, byte stat) +byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat) { unsigned long flags; byte err = 0; - ide_dev_t *dev = ide_cur_dev[HWIF]; - const char *name = dev ? dev->name : ide_name[HWIF]; save_flags (flags); sti(); - printk("%s: %s: status=0x%02x", name, msg, stat); + printk("%s: %s: status=0x%02x", drive->name, msg, stat); #if FANCY_STATUS_DUMPS - if (dev && dev->type == disk) { + if (drive->media == disk) { printk(" { "); if (stat & BUSY_STAT) printk("Busy "); @@ -625,10 +652,10 @@ #endif /* FANCY_STATUS_DUMPS */ printk("\n"); if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { - err = GET_ERR(HWIF); - printk("%s: %s: error=0x%02x", name, msg, err); + err = GET_ERR(); + printk("%s: %s: error=0x%02x", drive->name, msg, err); #if FANCY_STATUS_DUMPS - if (dev && dev->type == disk) { + if (drive->media == disk) { printk(" { "); if (err & BBD_ERR) printk("BadSector "); if (err & ECC_ERR) printk("UncorrectableError "); @@ -638,22 +665,22 @@ if (err & MARK_ERR) printk("AddrMarkNotFound "); printk("}"); if (err & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) { - byte cur = IN_BYTE(HD_CURRENT,HWIF); + byte cur = IN_BYTE(IDE_SELECT_REG); if (cur & 0x40) { /* using LBA? */ printk(", LBAsect=%ld", (unsigned long) ((cur&0xf)<<24) - |(IN_BYTE(HD_HCYL,HWIF)<<16) - |(IN_BYTE(HD_LCYL,HWIF)<<8) - | IN_BYTE(HD_SECTOR,HWIF)); + |(IN_BYTE(IDE_HCYL_REG)<<16) + |(IN_BYTE(IDE_LCYL_REG)<<8) + | IN_BYTE(IDE_SECTOR_REG)); } else { printk(", CHS=%d/%d/%d", - (IN_BYTE(HD_HCYL,HWIF)<<8) + - IN_BYTE(HD_LCYL,HWIF), + (IN_BYTE(IDE_HCYL_REG)<<8) + + IN_BYTE(IDE_LCYL_REG), cur & 0xf, - IN_BYTE(HD_SECTOR,HWIF)); + IN_BYTE(IDE_SECTOR_REG)); } - if (ide_cur_rq[HWIF]) - printk(", sector=%ld", ide_cur_rq[HWIF]->sector); + if (HWGROUP(drive)->rq) + printk(", sector=%ld", HWGROUP(drive)->rq->sector); } } #endif /* FANCY_STATUS_DUMPS */ @@ -664,81 +691,103 @@ } /* + * try_to_flush_leftover_data() is invoked in response to a drive + * unexpectedly having its DRQ_STAT bit set. As an alternative to + * resetting the drive, this routine tries to clear the condition + * by read a sector's worth of data from the drive. Of course, + * this may not help if the drive is *waiting* for data from *us*. + */ +static void try_to_flush_leftover_data (ide_drive_t *drive) +{ + int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS; + + while (i > 0) { + unsigned long buffer[16]; + unsigned int wcount = (i > 16) ? 16 : i; + i -= wcount; + ide_input_data (drive, buffer, wcount); + } +} + +/* * ide_error() takes action based on the error returned by the controller. + * + * Returns 1 if an ide reset operation has been initiated, in which case + * the caller MUST simply return from the driver (through however many levels). + * Returns 0 otherwise. */ -#define ERROR_MAX 8 /* Max read/write errors per sector */ -#define ERROR_RESET 3 /* Reset controller every 4th retry */ -#define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ -static void ide_error (ide_dev_t *dev, const char *msg, byte stat) +int ide_error (ide_drive_t *drive, const char *msg, byte stat) { struct request *rq; byte err; - err = dump_status(DEV_HWIF, msg, stat); - if ((rq = ide_cur_rq[DEV_HWIF]) == NULL || dev == NULL) - return; + err = ide_dump_status(drive, msg, stat); + if ((rq = HWGROUP(drive)->rq) == NULL || drive == NULL) + return 0; #ifdef IDE_DRIVE_CMD if (rq->cmd == IDE_DRIVE_CMD) { /* never retry an explicit DRIVE_CMD */ - end_drive_cmd(dev, stat, err); - return; + end_drive_cmd(drive, stat, err); + return 0; } #endif /* IDE_DRIVE_CMD */ if (stat & BUSY_STAT) { /* other bits are useless when BUSY */ rq->errors |= ERROR_RESET; } else { - if (dev->type == disk && (stat & ERR_STAT)) { + if (drive->media == disk && (stat & ERR_STAT)) { /* err has different meaning on cdrom */ if (err & BBD_ERR) /* retries won't help this! */ rq->errors = ERROR_MAX; else if (err & TRK0_ERR) /* help it find track zero */ rq->errors |= ERROR_RECAL; } - if ((stat & DRQ_STAT) && rq->cmd == READ) { - int i = dev->mult_count ? dev->mult_count<<8 : 1<<8; - while (i-- > 0) /* try to flush data */ - (void) IN_BYTE(HD_DATA, dev->hwif); - } + if ((stat & DRQ_STAT) && rq->cmd != WRITE) + try_to_flush_leftover_data(drive); } - if (GET_STAT(dev->hwif) & (BUSY_STAT|DRQ_STAT)) + if (GET_STAT() & (BUSY_STAT|DRQ_STAT)) rq->errors |= ERROR_RESET; /* Mmmm.. timing problem */ if (rq->errors >= ERROR_MAX) - end_request(0, DEV_HWIF); + ide_end_request(0, HWGROUP(drive)); else { - if ((rq->errors & ERROR_RESET) == ERROR_RESET) - do_ide_reset(dev); - else if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) - dev->special.b.recalibrate = 1; + if ((rq->errors & ERROR_RESET) == ERROR_RESET) { + ++rq->errors; + return ide_do_reset(drive); + } else if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) + drive->special.b.recalibrate = 1; ++rq->errors; } + return 0; } -static void read_intr (ide_dev_t *dev) +/* + * read_intr() is the handler for disk read/multread interrupts + */ +static void read_intr (ide_drive_t *drive) { byte stat; int i; unsigned int msect, nsect; struct request *rq; - if (!OK_STAT(stat=GET_STAT(DEV_HWIF),DATA_READY,BAD_R_STAT)) { + if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { sti(); - ide_error(dev, "read_intr", stat); - DO_REQUEST; + if (!ide_error(drive, "read_intr", stat)) + IDE_DO_REQUEST; return; } - msect = dev->mult_count; + msect = drive->mult_count; read_next: - rq = ide_cur_rq[DEV_HWIF]; + rq = HWGROUP(drive)->rq; if (msect) { if ((nsect = rq->current_nr_sectors) > msect) nsect = msect; msect -= nsect; } else nsect = 1; - input_ide_data(dev, rq->buffer, nsect * SECTOR_WORDS); + ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); #ifdef DEBUG printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n", - dev->name, rq->sector, rq->sector+nsect-1, + drive->name, rq->sector, rq->sector+nsect-1, (unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect); #endif rq->sector += nsect; @@ -746,27 +795,29 @@ rq->errors = 0; i = (rq->nr_sectors -= nsect); if ((rq->current_nr_sectors -= nsect) <= 0) - end_request(1, DEV_HWIF); + ide_end_request(1, HWGROUP(drive)); if (i > 0) { if (msect) goto read_next; - ide_handler[DEV_HWIF] = &read_intr; + ide_set_handler (drive, &read_intr); return; } - /* (void) GET_STAT(DEV_HWIF); */ /* hd.c did this */ - DO_REQUEST; + IDE_DO_REQUEST; } -static void write_intr (ide_dev_t *dev) +/* + * write_intr() is the handler for disk write interrupts + */ +static void write_intr (ide_drive_t *drive) { byte stat; int i; - struct request *rq = ide_cur_rq[DEV_HWIF]; + struct request *rq = HWGROUP(drive)->rq; - if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,dev->bad_wstat)) { + if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) { #ifdef DEBUG printk("%s: write: sector %ld, buffer=0x%08lx, remaining=%ld\n", - dev->name, rq->sector, (unsigned long) rq->buffer, + drive->name, rq->sector, (unsigned long) rq->buffer, rq->nr_sectors-1); #endif if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT) != 0)) { @@ -776,25 +827,29 @@ i = --rq->nr_sectors; --rq->current_nr_sectors; if (rq->current_nr_sectors <= 0) - end_request(1, DEV_HWIF); + ide_end_request(1, HWGROUP(drive)); if (i > 0) { - ide_handler[DEV_HWIF] = &write_intr; - output_ide_data(dev, rq->buffer, SECTOR_WORDS); + ide_output_data (drive, rq->buffer, SECTOR_WORDS); + ide_set_handler (drive, &write_intr); return; } - DO_REQUEST; + IDE_DO_REQUEST; return; } } sti(); - ide_error(dev, "write_intr", stat); - DO_REQUEST; + if (!ide_error(drive, "write_intr", stat)) + IDE_DO_REQUEST; } -static void multwrite (ide_dev_t *dev) +/* + * multwrite() transfers a block of one or more sectors of data to a drive + * as part of a disk multwrite operation. + */ +static void multwrite (ide_drive_t *drive) { - struct request *rq = &ide_write_rq[DEV_HWIF]; - unsigned int mcount = dev->mult_count; + struct request *rq = &HWGROUP(drive)->wrq; + unsigned int mcount = drive->mult_count; do { unsigned int nsect = rq->current_nr_sectors; @@ -802,10 +857,10 @@ nsect = mcount; mcount -= nsect; - output_ide_data(dev, rq->buffer, nsect<<7); + ide_output_data(drive, rq->buffer, nsect<<7); #ifdef DEBUG printk("%s: multwrite: sector %ld, buffer=0x%08lx, count=%d, remaining=%ld\n", - dev->name, rq->sector, (unsigned long) rq->buffer, + drive->name, rq->sector, (unsigned long) rq->buffer, nsect, rq->nr_sectors - nsect); #endif if ((rq->nr_sectors -= nsect) <= 0) @@ -815,7 +870,7 @@ rq->current_nr_sectors = rq->bh->b_size>>9; rq->buffer = rq->bh->b_data; } else { - panic("%s: buffer list corrupted\n", dev->name); + panic("%s: buffer list corrupted\n", drive->name); break; } } else { @@ -824,415 +879,410 @@ } while (mcount); } -static void multwrite_intr (ide_dev_t *dev) +/* + * write_intr() is the handler for disk multwrite interrupts + */ +static void multwrite_intr (ide_drive_t *drive) { byte stat; int i; - struct request *rq = &ide_write_rq[DEV_HWIF]; + struct request *rq = &HWGROUP(drive)->wrq; - if (OK_STAT(stat=GET_STAT(DEV_HWIF),DRIVE_READY,dev->bad_wstat)) { + if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) { if (stat & DRQ_STAT) { if (rq->nr_sectors) { - if (dev->mult_count) - multwrite(dev); - ide_handler[DEV_HWIF] = &multwrite_intr; + multwrite(drive); + ide_set_handler (drive, &multwrite_intr); return; } } else { if (!rq->nr_sectors) { /* all done? */ - rq = ide_cur_rq[DEV_HWIF]; + rq = HWGROUP(drive)->rq; for (i = rq->nr_sectors; i > 0;){ i -= rq->current_nr_sectors; - end_request(1, DEV_HWIF); + ide_end_request(1, HWGROUP(drive)); } - DO_REQUEST; + IDE_DO_REQUEST; return; } } } sti(); - ide_error(dev, "multwrite_intr", stat); - DO_REQUEST; + if (!ide_error(drive, "multwrite_intr", stat)) + IDE_DO_REQUEST; } /* * Issue a simple drive command * The drive must be selected beforehand. */ -static inline void ide_cmd(ide_dev_t *dev, byte cmd, byte nsect, - void (*handler)(ide_dev_t *dev)) +static inline void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) { - OUT_BYTE(dev->ctl,HD_CMD); - OUT_BYTE(nsect,HD_NSECTOR); - OUT_BYTE(cmd,HD_COMMAND); - ide_handler[DEV_HWIF] = handler; + ide_set_handler (drive, handler); + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); + OUT_BYTE(nsect,IDE_NSECTOR_REG); + OUT_BYTE(cmd,IDE_COMMAND_REG); } -static void set_multmode_intr (ide_dev_t *dev) +static void set_multmode_intr (ide_drive_t *drive) { - byte stat = GET_STAT(DEV_HWIF); + byte stat = GET_STAT(); sti(); - if (!OK_STAT(stat,READY_STAT,BAD_STAT)) { - dev->mult_req = dev->mult_count = 0; - dev->special.b.recalibrate = 1; - (void) dump_status(DEV_HWIF, "set_multmode", stat); - } else if (!dev->be_quiet) { - if ((dev->mult_count = dev->mult_req)) - printk (" %s: enabled %d-sector multiple mode\n", - dev->name, dev->mult_count); - else - printk (" %s: multiple mode turned off\n", dev->name); + if (OK_STAT(stat,READY_STAT,BAD_STAT)) { + drive->mult_count = drive->mult_req; + } else { + drive->mult_req = drive->mult_count = 0; + drive->special.b.recalibrate = 1; + (void) ide_dump_status(drive, "set_multmode", stat); } - dev->be_quiet = 0; - DO_REQUEST; + IDE_DO_REQUEST; } -static void set_geometry_intr (ide_dev_t *dev) +static void set_geometry_intr (ide_drive_t *drive) { - byte stat = GET_STAT(DEV_HWIF); + byte stat = GET_STAT(); sti(); if (!OK_STAT(stat,READY_STAT,BAD_STAT)) - ide_error(dev, "set_geometry_intr", stat); - DO_REQUEST; + if (ide_error(drive, "set_geometry_intr", stat)) + return; + IDE_DO_REQUEST; } -static void recal_intr (ide_dev_t *dev) +static void recal_intr (ide_drive_t *drive) { - byte stat = GET_STAT(DEV_HWIF); + byte stat = GET_STAT(); sti(); if (!OK_STAT(stat,READY_STAT,BAD_STAT)) - ide_error(dev, "recal_intr", stat); - DO_REQUEST; + if (ide_error(drive, "recal_intr", stat)) + return; + IDE_DO_REQUEST; } -static void drive_cmd_intr (ide_dev_t *dev) +static void drive_cmd_intr (ide_drive_t *drive) { - byte stat = GET_STAT(DEV_HWIF); + byte stat = GET_STAT(); sti(); - if (!OK_STAT(stat,READY_STAT,BAD_STAT)) - ide_error(dev, "drive_cmd", stat); /* calls end_drive_cmd() */ - else - end_drive_cmd (dev, stat, GET_ERR(DEV_HWIF)); - DO_REQUEST; -} - -static void timer_expiry (byte hwif) -{ - unsigned long flags; - - save_flags(flags); - cli(); - - if (ide_handler[HWIF] == NULL || (timer_active & ide_timerbit[HWIF])) { - /* The drive must have responded just as the timer expired */ - sti(); - printk("%s: marginal timeout\n", ide_name[HWIF]); - } else { - ide_handler[HWIF] = NULL; - disable_irq(ide_irq[HWIF]); -#if SUPPORT_SERIALIZE - if (single_threaded && ide_irq[HWIF] != ide_irq[HWIF^1]) - disable_irq(ide_irq[HWIF^1]); -#endif /* SUPPORT_SERIALIZE */ - sti(); - ide_error(ide_cur_dev[HWIF], "timeout", GET_STAT(HWIF)); - do_request(HWIF); -#if SUPPORT_SHARING_IRQ - if (single_threaded) /* this line is indeed necessary */ - hwif = current_hwif; -#endif /* SUPPORT_SHARING_IRQ */ - cli(); - start_ide_timer(HWIF); - enable_irq(ide_irq[HWIF]); -#if SUPPORT_SERIALIZE - if (single_threaded && ide_irq[HWIF] != ide_irq[HWIF^1]) - enable_irq(ide_irq[HWIF^1]); -#endif /* SUPPORT_SERIALIZE */ - } - restore_flags(flags); -} - -static void ide0_timer_expiry (void) /* invoked from sched.c */ -{ - timer_expiry (0); -} - -static void ide1_timer_expiry (void) /* invoked from sched.c */ -{ - timer_expiry (1); + if (OK_STAT(stat,READY_STAT,BAD_STAT)) + end_drive_cmd (drive, stat, GET_ERR()); + else if (ide_error(drive, "drive_cmd", stat)) /* calls end_drive_cmd */ + return; + IDE_DO_REQUEST; } -static int do_special (ide_dev_t *dev) +static void do_special (ide_drive_t *drive) { - special_t *s = &dev->special; + special_t *s = &drive->special; #ifdef DEBUG - printk("%s: do_special: 0x%02x\n", dev->name, s->all); + printk("%s: do_special: 0x%02x\n", drive->name, s->all); #endif if (s->b.set_geometry) { s->b.set_geometry = 0; - if (dev->type == disk) { - OUT_BYTE(dev->sect,HD_SECTOR); - OUT_BYTE(dev->cyl,HD_LCYL); - OUT_BYTE(dev->cyl>>8,HD_HCYL); - OUT_BYTE(((dev->head-1)|dev->select.all)&0xBF,HD_CURRENT); - ide_cmd(dev, WIN_SPECIFY, dev->sect, &set_geometry_intr); + if (drive->media == disk) { + OUT_BYTE(drive->sect,IDE_SECTOR_REG); + OUT_BYTE(drive->cyl,IDE_LCYL_REG); + OUT_BYTE(drive->cyl>>8,IDE_HCYL_REG); + OUT_BYTE(((drive->head-1)|drive->select.all)&0xBF,IDE_SELECT_REG); + ide_cmd(drive, WIN_SPECIFY, drive->sect, &set_geometry_intr); } } else if (s->b.recalibrate) { s->b.recalibrate = 0; - if (dev->type == disk) - ide_cmd(dev,WIN_RESTORE,dev->sect,&recal_intr); - } else if (s->b.set_multmode) { - if (dev->type == disk) { - if (dev->id && dev->mult_req > dev->id->max_multsect) - dev->mult_req = dev->id->max_multsect; - ide_cmd(dev,WIN_SETMULT,dev->mult_req,&set_multmode_intr); - } else { - dev->mult_req = 0; - printk("%s: multmode not supported by this device\n", dev->name); + if (drive->media == disk) { + ide_cmd(drive, WIN_RESTORE, drive->sect, &recal_intr); } + } else if (s->b.set_multmode) { s->b.set_multmode = 0; - } else { - if (s->all) { - printk("%s: bad special flag: 0x%02x\n", dev->name, s->all); - s->all = 0; - } + if (drive->media == disk) { + if (drive->id && drive->mult_req > drive->id->max_multsect) + drive->mult_req = drive->id->max_multsect; + ide_cmd(drive, WIN_SETMULT, drive->mult_req, &set_multmode_intr); + } else + drive->mult_req = 0; + } else if (s->all) { + s->all = 0; + printk("%s: bad special flag: 0x%02x\n", drive->name, s->all); } - return (ide_handler[DEV_HWIF] == NULL) ? 1 : 0; } -#ifdef CONFIG_BLK_DEV_IDECD -static byte wait_stat (ide_dev_t *dev, byte good, byte bad, unsigned long timeout) +/* + * This routine busy-waits for the drive status to be not "busy". + * It then checks the status for all of the "good" bits and none + * of the "bad" bits, and if all is okay it returns 0. All other + * cases return 1 after invoking ide_error() + * + * This routine should get fixed to not hog the cpu during extra long waits.. + * That could be done by busy-waiting for the first jiffy or two, and then + * setting a timer to wake up at half second intervals thereafter, + * until WAIT_WORSTCASE is achieved, before timing out. + */ +int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeout) { - unsigned long flags; + byte stat; - save_flags(flags); - sti(); - WAIT_STAT(dev, good, bad, timeout, "status", error); - restore_flags(flags); - return 0; -error: - restore_flags(flags); + udelay(1); /* spec allows drive 400ns to assert "BUSY" */ + if (GET_STAT() & BUSY_STAT) { + unsigned long flags; + save_flags(flags); + sti(); + timeout += jiffies; + while (GET_STAT() & BUSY_STAT) { + if (jiffies > timeout) { + restore_flags(flags); + (void) ide_error(drive, "status timeout", GET_STAT()); + return 1; + } + } + restore_flags(flags); + udelay(1); /* spec allows 400ns for status to stabilize */ + } + if (OK_STAT(stat=GET_STAT(), good, bad)) + return 0; + (void) ide_error(drive, "status error", stat); return 1; } -#include "ide-cd.c" -#endif /* CONFIG_BLK_DEV_IDECD */ - -static inline int do_rw_disk (ide_dev_t *dev, struct request *rq, unsigned long block) +static inline void do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) { - OUT_BYTE(dev->ctl,HD_CMD); - OUT_BYTE(rq->nr_sectors,HD_NSECTOR); - if (dev->select.b.lba) { + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); + OUT_BYTE(rq->nr_sectors,IDE_NSECTOR_REG); + if (drive->select.b.lba) { #ifdef DEBUG printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n", - dev->name, (rq->cmd==READ)?"read":"writ", + drive->name, (rq->cmd==READ)?"read":"writ", block, rq->nr_sectors, (unsigned long) rq->buffer); #endif - OUT_BYTE(block,HD_SECTOR); - OUT_BYTE(block>>=8,HD_LCYL); - OUT_BYTE(block>>=8,HD_HCYL); - OUT_BYTE(((block>>8)&0x0f)|dev->select.all,HD_CURRENT); + OUT_BYTE(block,IDE_SECTOR_REG); + OUT_BYTE(block>>=8,IDE_LCYL_REG); + OUT_BYTE(block>>=8,IDE_HCYL_REG); + OUT_BYTE(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG); } else { unsigned int sect,head,cyl,track; - track = block / dev->sect; - sect = block % dev->sect + 1; - OUT_BYTE(sect,HD_SECTOR); - head = track % dev->head; - cyl = track / dev->head; - OUT_BYTE(cyl,HD_LCYL); - OUT_BYTE(cyl>>8,HD_HCYL); - OUT_BYTE(head|dev->select.all,HD_CURRENT); + track = block / drive->sect; + sect = block % drive->sect + 1; + OUT_BYTE(sect,IDE_SECTOR_REG); + head = track % drive->head; + cyl = track / drive->head; + OUT_BYTE(cyl,IDE_LCYL_REG); + OUT_BYTE(cyl>>8,IDE_HCYL_REG); + OUT_BYTE(head|drive->select.all,IDE_SELECT_REG); #ifdef DEBUG printk("%s: %sing: CHS=%d/%d/%d, sectors=%ld, buffer=0x%08lx\n", - dev->name, (rq->cmd==READ)?"read":"writ", cyl, + drive->name, (rq->cmd==READ)?"read":"writ", cyl, head, sect, rq->nr_sectors, (unsigned long) rq->buffer); #endif } if (rq->cmd == READ) { - OUT_BYTE(dev->mult_count ? WIN_MULTREAD : WIN_READ, HD_COMMAND); - ide_handler[DEV_HWIF] = &read_intr; - return 0; + ide_set_handler(drive, &read_intr); + OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG); + return; } if (rq->cmd == WRITE) { - OUT_BYTE(dev->wpcom,HD_PRECOMP); /* for ancient drives */ - OUT_BYTE(dev->mult_count ? WIN_MULTWRITE : WIN_WRITE, HD_COMMAND); - WAIT_STAT(dev,DATA_READY,dev->bad_wstat,WAIT_DRQ,"DRQ",error); - if (!dev->unmask) + OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, IDE_COMMAND_REG); + if (ide_wait_stat(drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) { + printk("%s: no DRQ after issuing %s\n", drive->name, + drive->mult_count ? "MULTWRITE" : "WRITE"); + return; + } + if (!drive->unmask) cli(); - if (dev->mult_count) { - ide_write_rq[DEV_HWIF] = *rq; /* scratchpad */ - multwrite(dev); - ide_handler[DEV_HWIF] = &multwrite_intr; + if (drive->mult_count) { + HWGROUP(drive)->wrq = *rq; /* scratchpad */ + ide_set_handler (drive, &multwrite_intr); + multwrite(drive); } else { - output_ide_data(dev, rq->buffer, SECTOR_WORDS); - ide_handler[DEV_HWIF] = &write_intr; + ide_set_handler (drive, &write_intr); + ide_output_data(drive, rq->buffer, SECTOR_WORDS); } - return 0; + return; } #ifdef IDE_DRIVE_CMD if (rq->cmd == IDE_DRIVE_CMD) { byte *args = rq->buffer; if (args) { - OUT_BYTE(args[2],HD_FEATURE); - ide_cmd(dev, args[0], args[1], &drive_cmd_intr); printk("%s: DRIVE_CMD cmd=0x%02x sc=0x%02x fr=0x%02x\n", - dev->name, args[0], args[1], args[2]); - return 0; + drive->name, args[0], args[1], args[2]); + OUT_BYTE(args[2],IDE_FEATURE_REG); + ide_cmd(drive, args[0], args[1], &drive_cmd_intr); + return; } else { #ifdef DEBUG - printk("%s: DRIVE_CMD (null)\n", dev->name); + printk("%s: DRIVE_CMD (null)\n", drive->name); #endif - end_drive_cmd(dev,GET_STAT(DEV_HWIF),GET_ERR(DEV_HWIF)); - return 1; + end_drive_cmd(drive, GET_STAT(), GET_ERR()); + return; } } #endif /* IDE_DRIVE_CMD */ - printk("%s: bad command: %d\n", dev->name, rq->cmd); - end_request(0, DEV_HWIF); -error: - return 1; + printk("%s: bad command: %d\n", drive->name, rq->cmd); + ide_end_request(0, HWGROUP(drive)); } -/* - * The driver enables interrupts as much as possible. In order to do this, - * (a) the device-interrupt is always masked before entry, and - * (b) the timeout-interrupt is always disabled before entry. - * - * Interrupts are still masked (by default) whenever we are exchanging - * data/cmds with a drive, because some drives seem to have very poor - * tolerance for latency during I/O. For devices which don't suffer from - * this problem (most don't), the ide_dev[][].unmask flag can be set to permit - * other interrupts during data/cmd transfers by using the "hdparm" utility. - */ -static void do_request (byte hwif) +static inline void do_request (ide_hwif_t *hwif, struct request *rq) { - unsigned int minor, drive; + unsigned int minor, unit; unsigned long block, blockend; - struct request *rq; - ide_dev_t *dev; -repeat: + ide_drive_t *drive; + sti(); -#if SUPPORT_SHARING_IRQ - current_hwif = hwif; /* used *only* when single_threaded==1 */ -#endif /* SUPPORT_SHARING_IRQ */ - if ((rq = ide_cur_rq[HWIF]) == NULL) { - rq = blk_dev[ide_major[HWIF]].current_request; - if ((rq == NULL) || (rq->dev < 0)) { -#if SUPPORT_SHARING_IRQ - if (single_threaded) { - if (sharing_single_irq && (dev = ide_cur_dev[hwif])) /* disable irq */ - OUT_BYTE(dev->ctl|2,HD_CMD); - rq = blk_dev[ide_major[hwif^=1]].current_request; - if ((rq != NULL) && (rq->dev >= 0)) - goto repeat; - } -#endif /* SUPPORT_SHARING_IRQ */ - return; - } - blk_dev[ide_major[HWIF]].current_request = rq->next; - ide_cur_rq[HWIF] = rq; - } #ifdef DEBUG - printk("%s: do_request: current=0x%08lx\n",ide_name[HWIF],(unsigned long)rq); + printk("%s: ide_do_request: current=0x%08lx\n", hwif->name, (unsigned long) rq); #endif minor = MINOR(rq->dev); - drive = minor >> PARTN_BITS; - ide_cur_dev[HWIF] = dev = &ide_dev[HWIF][drive]; - if ((MAJOR(rq->dev) != ide_major[HWIF]) || (drive >= MAX_DRIVES)) { - printk("%s: bad device number: 0x%04x\n", ide_name[HWIF], rq->dev); - end_request(0, HWIF); - goto repeat; + unit = minor >> PARTN_BITS; + if (MAJOR(rq->dev) != hwif->major || unit >= MAX_DRIVES) { + printk("%s: bad device number: 0x%04x\n", hwif->name, rq->dev); + goto kill_rq; } + drive = &hwif->drives[unit]; if (rq->bh && !rq->bh->b_lock) { - printk("%s: block not locked\n", ide_name[HWIF]); - end_request(0, HWIF); - goto repeat; + printk("%s: block not locked\n", drive->name); + goto kill_rq; } block = rq->sector; blockend = block + rq->nr_sectors; - if ((blockend < block) || (blockend > ide_hd[HWIF][minor].nr_sects)) { + if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) { printk("%s: bad access: block=%ld, count=%ld\n", - dev->name, block, rq->nr_sectors); - end_request(0, HWIF); - goto repeat; + drive->name, block, rq->nr_sectors); + goto kill_rq; } - block += ide_hd[HWIF][minor].start_sect + dev->sect0; + block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0; #if (DISK_RECOVERY_TIME > 0) - while ((read_timer() - ide_lastreq[HWIF]) < DISK_RECOVERY_TIME); + while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME); #endif - OUT_BYTE(dev->select.all,HD_CURRENT); -#ifdef CONFIG_BLK_DEV_IDECD - WAIT_STAT(dev, (dev->type == cdrom) ? 0 : READY_STAT, - BUSY_STAT|DRQ_STAT, WAIT_READY, "DRDY", repeat); -#else - WAIT_STAT(dev, READY_STAT, BUSY_STAT|DRQ_STAT, WAIT_READY, "DRDY", repeat); -#endif /* CONFIG_BLK_DEV_IDECD */ - if (!dev->special.all) { -#ifdef CONFIG_BLK_DEV_IDECD - if (dev->type == disk) { -#endif /* CONFIG_BLK_DEV_IDECD */ - if (do_rw_disk(dev, rq, block)) - goto repeat; + OUT_BYTE(drive->select.all,IDE_SELECT_REG); + if (ide_wait_stat(drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) { + printk("%s: drive not ready for command\n", drive->name); + return; + + } + ((ide_hwgroup_t *)hwif->hwgroup)->drive = drive; + if (!drive->special.all) { #ifdef CONFIG_BLK_DEV_IDECD - } else { - if (do_rw_cdrom(dev, block)) - goto repeat; + switch (drive->media) { + case disk: + do_rw_disk (drive, rq, block); + return; + case cdrom: + ide_do_rw_cdrom (drive, block); + return; + default: + printk("%s: media type %d not supported\n", + drive->name, drive->media); + goto kill_rq; } -#endif /* CONFIG_BLK_DEV_IDECD */ - } else { - if (do_special(dev)) - goto repeat; +#else + do_rw_disk (drive, rq, block); /* simpler and faster */ + return; +#endif; } + do_special(drive); + return; +kill_rq: + ide_end_request(0, hwif->hwgroup); } /* - * This is a macro rather than an inline function to - * prevent gcc from over-optimizing accesses to current_hwif, - * which may have a different value on exit from do_request(). + * The driver enables interrupts as much as possible. In order to do this, + * (a) the device-interrupt is always masked before entry, and + * (b) the timeout-interrupt is always disabled before entry. + * + * If we enter here from, say irq14, and then start a new request for irq15, + * (possible with "serialize" option) then we cannot ensure that we exit + * before the irq15 hits us. So, we must be careful not to let this bother us. + * + * Interrupts are still masked (by default) whenever we are exchanging + * data/cmds with a drive, because some drives seem to have very poor + * tolerance for latency during I/O. For devices which don't suffer from + * this problem (most don't), the unmask flag can be set using the "hdparm" + * utility, to permit other interrupts during data/cmd transfers. */ -#define DO_IDE_REQUEST(hwif) \ -{ \ - if (ide_handler[hwif] == NULL) { \ - disable_irq(ide_irq[hwif]); \ - if (single_threaded && ide_irq[hwif] != ide_irq[hwif^1]) \ - disable_irq(ide_irq[hwif^1]); \ - do_request(hwif); \ - cli(); \ - start_ide_timer(hwif); \ - enable_irq(ide_irq[hwif]); \ - if (single_threaded && ide_irq[hwif] != ide_irq[hwif^1]) \ - enable_irq(ide_irq[hwif^1]); \ - } \ +void ide_do_request (ide_hwgroup_t *hwgroup) +{ + cli(); /* paranoia */ + + if (hwgroup->handler != NULL) { + printk("%s: EEeekk!! handler not NULL in ide_do_request()\n", hwgroup->hwif->name); + return; + } + do { + ide_hwif_t *hwif = hwgroup->hwif; + struct request *rq; + if ((rq = hwgroup->rq) == NULL) { + hwgroup->drive = NULL; /* paranoia */ + do { + rq = blk_dev[hwif->major].current_request; + if (rq != NULL && rq->dev != -1) + goto got_rq; + } while ((hwif = hwif->next) != hwgroup->hwif); + return; /* no work left for this hwgroup */ + } + got_rq: + blk_dev[hwif->major].current_request = rq->next; + do_request(hwgroup->hwif = hwif, hwgroup->rq = rq); + cli(); + } while (hwgroup->handler == NULL); +} + +static void do_hwgroup_request (ide_hwgroup_t *hwgroup) +{ + if (hwgroup->handler == NULL) { + ide_hwif_t *hgif = hwgroup->hwif; + ide_hwif_t *hwif = hgif; + do { + disable_irq(hwif->irq); + } while ((hwif = hwif->next) != hgif); + ide_do_request (hwgroup); + do { + enable_irq(hwif->irq); + } while ((hwif = hwif->next) != hgif); + } } -#if SUPPORT_TWO_INTERFACES static void do_ide0_request (void) /* invoked with cli() */ { - DO_IDE_REQUEST(0); + do_hwgroup_request (ide_hwifs[0].hwgroup); } static void do_ide1_request (void) /* invoked with cli() */ { - DO_IDE_REQUEST(1); + do_hwgroup_request (ide_hwifs[1].hwgroup); } -#else -#define do_ide1_request do_ide0_request -static void do_ide0_request (void) /* invoked with cli() */ + +static void do_ide2_request (void) /* invoked with cli() */ { - DO_IDE_REQUEST(HWIF); + do_hwgroup_request (ide_hwifs[2].hwgroup); } -#endif /* SUPPORT_TWO_INTERFACES */ -#if SUPPORT_SHARING_IRQ -static void do_shared_request (void) /* invoked with cli() */ +static void do_ide3_request (void) /* invoked with cli() */ { - DO_IDE_REQUEST(current_hwif); + do_hwgroup_request (ide_hwifs[3].hwgroup); +} + +static void timer_expiry (unsigned long data) +{ + ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data; + ide_drive_t *drive = hwgroup->drive; + unsigned long flags; + + save_flags(flags); + cli(); + + if (hwgroup->hwif->reset_timeout != 0) { /* ide reset in progress? */ + if (!reset_handler(hwgroup)) + do_hwgroup_request (hwgroup); + } else if (hwgroup->handler == NULL) { /* not waiting for anything? */ + sti(); /* drive must have responded just as the timer expired */ + printk("%s: marginal timeout\n", drive->name); + } else { /* drive not responding */ + hwgroup->handler = NULL; + if (!ide_error(drive, "irq timeout", GET_STAT())) + do_hwgroup_request (hwgroup); + } + restore_flags(flags); } -#endif /* SUPPORT_SHARING_IRQ */ /* * There's nothing really useful we can do with an unexpected interrupt, @@ -1244,135 +1294,177 @@ * drive enters "idle", "standby", or "sleep" mode, so if the status looks * "good", we just ignore the interrupt completely. */ -static void unexpected_intr (byte hwif) +static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) { byte stat; + unsigned int unit; + ide_hwif_t *hwif = hwgroup->hwif; + unsigned long flags; + + save_flags(flags); + cli(); - if (!OK_STAT(stat=GET_STAT(HWIF), DRIVE_READY, BAD_STAT)) - (void) dump_status(HWIF, "unexpected_intr", stat); - outb_p(2,IDE_PORT(HD_CMD,hwif)); /* disable device irq */ -#if SUPPORT_SHARING_IRQ - if (single_threaded && ide_irq[hwif] == ide_irq[hwif^1]) { - if (!OK_STAT(stat=GET_STAT(hwif^1), DRIVE_READY, BAD_STAT)) - (void) dump_status(hwif^1, "unexpected_intr", stat); - outb_p(2,IDE_PORT(HD_CMD,hwif^1)); /* disable device irq */ + /* + * check for ide reset in progress + */ + if (hwif->reset_timeout != 0) { + if (!reset_handler(hwgroup)) + do_hwgroup_request (hwgroup); + restore_flags(flags); + return; } -#endif /* SUPPORT_SHARING_IRQ */ + + /* + * handle the unexpected interrupt + */ + do { + if (hwif->irq == irq) { + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + if (!drive->present) + continue; + if (!OK_STAT(stat=GET_STAT(), drive->ready_stat, BAD_STAT)) + (void) ide_dump_status(drive, "unexpected_intr", stat); + if ((stat & DRQ_STAT)) + try_to_flush_leftover_data(drive); + } + } + } while ((hwif = hwif->next) != hwgroup->hwif); + restore_flags(flags); } /* - * This is a macro rather than an inline function to - * prevent gcc from over-optimizing accesses to current_hwif, - * which may have a different value on exit from handler(). + * entry point for all interrupts, caller does cli() for us */ -#define IDE_INTR(hwif) \ -{ \ - ide_dev_t *dev; \ - void (*handler)(ide_dev_t *); \ - \ - timer_active &= ~ide_timerbit[hwif]; \ - if ((handler = ide_handler[hwif]) != NULL) { \ - ide_handler[hwif] = NULL; \ - dev = ide_cur_dev[hwif]; \ - if (dev->unmask) \ - sti(); \ - handler(dev); \ - } else \ - unexpected_intr(hwif); \ - cli(); \ -} - -#if SUPPORT_SERIALIZE -/* entry point for all interrupts when single_threaded==1 */ -static void ide_seq_intr (int irq, struct pt_regs *regs) +static void ide_intr (int irq, struct pt_regs *regs) { - byte hwif = (irq != ide_irq[0]); - IDE_INTR(HWIF); - start_ide_timer(current_hwif); + ide_hwgroup_t *hwgroup = irq_to_hwgroup[irq]; + ide_handler_t *handler; + if (irq != hwgroup->hwif->irq) { +#ifdef DEBUG + printk("ide_intr: expected ira %d, got irq %d instead\n", + hwgroup->hwif->irq, irq); +#endif + unexpected_intr(irq, hwgroup); + } else if ((handler = hwgroup->handler) != NULL) { + ide_drive_t *drive = hwgroup->drive; + hwgroup->handler = NULL; + del_timer(&(hwgroup->timer)); + if (drive->unmask) + sti(); + handler(drive); + } else { + sti(); + unexpected_intr(irq, hwgroup); + } + cli(); } -#endif /* SUPPORT_SERIALIZE */ - -#if OPTIMIZE_IRQS -/* entry point for all interrupts on ide0 when single_threaded==0 */ -static void ide0_intr (int irq, struct pt_regs *regs) +static ide_drive_t *get_info_ptr (int i_rdev) { - IDE_INTR(0); - start_ide_timer(0); -} + int major = MAJOR(i_rdev); + unsigned int h; -/* entry point for all interrupts on ide1 when single_threaded==0 */ -static void ide1_intr (int irq, struct pt_regs *regs) -{ - IDE_INTR(1); - start_ide_timer(1); + for (h = 0; h < MAX_HWIFS; ++h) { + ide_hwif_t *hwif = &ide_hwifs[h]; + if (hwif->present && major == hwif->major) { + unsigned unit = DEVICE_NR(i_rdev); + if (unit < MAX_DRIVES) { + ide_drive_t *drive = &hwif->drives[unit]; + if (drive->present) + return drive; + } + break; + } + } + return NULL; } -#else /* OPTIMIZE_IRQS */ - -#define ide0_intr ide_intr -#define ide1_intr ide_intr - -/* entry point for all interrupts when single_threaded==0 */ -static void ide_intr (int irq, struct pt_regs *regs) +#ifdef IDE_DRIVE_CMD +static int write_fs_long (unsigned long useraddr, long value) { -#if SUPPORT_TWO_INTERFACES - byte hwif = (irq != ide_irq[0]); -#endif /* SUPPORT_TWO_INTERFACES */ - IDE_INTR(HWIF); - start_ide_timer(HWIF); -} - -#endif /* OPTIMIZE_IRQS */ + int err; -#if SUPPORT_SHARING_IRQ -/* entry point for all interrupts on ide0/ide1 when sharing_single_irq==1 */ -static void ide_shared_intr (int irq, struct pt_regs * regs) -{ - IDE_INTR(current_hwif); - start_ide_timer(current_hwif); + if (NULL == (long *)useraddr) + return -EINVAL; + if ((err = verify_area(VERIFY_WRITE, (long *)useraddr, sizeof(long)))) + return err; + put_user((unsigned)value, (long *) useraddr); + return 0; } -#endif /* SUPPORT_SHARING_IRQ */ -static ide_dev_t *get_info_ptr (int i_rdev) +/* + * This function issues a specific IDE drive command onto the + * tail of the request queue, and waits for it to be completed. + * If arg is NULL, it goes through all the motions, + * but without actually sending a command to the drive. + */ +static int do_drive_cmd(int rdev, char *args) { - unsigned int drive = DEVICE_NR(i_rdev); - ide_dev_t *dev; + unsigned long flags; + unsigned int major = MAJOR(rdev); + struct request rq, *cur_rq; + struct blk_dev_struct *bdev; + struct semaphore sem = MUTEX_LOCKED; - if (drive < MAX_DRIVES) { - switch (MAJOR(i_rdev)) { -#ifndef CONFIG_BLK_DEV_HD - case IDE0_MAJOR: dev = &ide_dev[0][drive]; - if (dev->present) return dev; - break; -#endif /* CONFIG_BLK_DEV_HD */ - case IDE1_MAJOR: dev = &ide_dev[1][drive]; - if (dev->present) return dev; - break; - } + /* build up a special request, and add it to the queue */ + rq.buffer = args; + rq.cmd = IDE_DRIVE_CMD; + rq.errors = 0; + rq.sector = 0; + rq.nr_sectors = 0; + rq.current_nr_sectors = 0; + rq.sem = &sem; + rq.bh = NULL; + rq.bhtail = NULL; + rq.next = NULL; + rq.dev = rdev; + bdev = &blk_dev[major]; + + save_flags(flags); + cli(); + cur_rq = bdev->current_request; + if (cur_rq == NULL) { /* empty request list? */ + bdev->current_request = &rq; /* service ours immediately */ + bdev->request_fn(); + } else { + while (cur_rq->next != NULL) /* find end of request list */ + cur_rq = cur_rq->next; + cur_rq->next = &rq; /* add rq to the end */ } - return NULL; + + down(&sem); /* wait for it to be serviced */ + restore_flags(flags); + return rq.errors ? -EIO : 0; /* return -EIO if errors */ } +#endif /* IDE_DRIVE_CMD */ static int ide_open(struct inode * inode, struct file * filp) { - ide_dev_t *dev; + ide_drive_t *drive; unsigned long flags; - if ((dev = get_info_ptr(inode->i_rdev)) == NULL) + if ((drive = get_info_ptr(inode->i_rdev)) == NULL) return -ENODEV; save_flags(flags); cli(); - while (dev->busy) - sleep_on(&dev->wqueue); - dev->usage++; + while (drive->busy) + sleep_on(&drive->wqueue); + drive->usage++; restore_flags(flags); #ifdef CONFIG_BLK_DEV_IDECD - if (dev->type == cdrom) - return cdrom_open (inode, filp, dev); + if (drive->media == cdrom) + return ide_cdrom_open (inode, filp, drive); #endif /* CONFIG_BLK_DEV_IDECD */ - if (dev->removeable) /* for disks */ + if (drive->removeable) { check_disk_change(inode->i_rdev); +#ifdef IDE_DRIVE_CMD + { + byte door_lock[] = {WIN_DOORLOCK,0,0,0}; + do_drive_cmd(inode->i_rdev, door_lock); + } +#endif /* IDE_DRIVE_CMD */ + } return 0; } @@ -1382,15 +1474,25 @@ */ static void ide_release(struct inode * inode, struct file * file) { - ide_dev_t *dev; + ide_drive_t *drive; - if ((dev = get_info_ptr(inode->i_rdev)) != NULL) { + if ((drive = get_info_ptr(inode->i_rdev)) != NULL) { sync_dev(inode->i_rdev); - dev->usage--; + drive->usage--; #ifdef CONFIG_BLK_DEV_IDECD - if (dev->type == cdrom) - cdrom_release (inode, file, dev); + if (drive->media == cdrom) + ide_cdrom_release (inode, file, drive); + else #endif /* CONFIG_BLK_DEV_IDECD */ + if (drive->removeable) { + invalidate_buffers(inode->i_rdev); +#ifdef IDE_DRIVE_CMD + { + byte door_unlock[] = {WIN_DOORUNLOCK,0,0,0}; + do_drive_cmd(inode->i_rdev, door_unlock); + } +#endif /* IDE_DRIVE_CMD */ + } } } @@ -1404,100 +1506,37 @@ */ static int revalidate_disk(dev_t i_rdev) { - unsigned int i, major, start, drive = DEVICE_NR(i_rdev); - ide_dev_t *dev; - struct gendisk *gd; + ide_drive_t *drive; + unsigned int p, major, minor; long flags; - if ((dev = get_info_ptr(i_rdev)) == NULL) + if ((drive = get_info_ptr(i_rdev)) == NULL) return -ENODEV; + major = MAJOR(i_rdev); + minor = drive->select.b.unit << PARTN_BITS; save_flags(flags); cli(); - if (dev->busy || (dev->usage > 1)) { + if (drive->busy || (drive->usage > 1)) { restore_flags(flags); return -EBUSY; }; - dev->busy = 1; + drive->busy = 1; restore_flags(flags); - gd = &ide_gendisk[DEV_HWIF]; - major = ide_major[DEV_HWIF] << 8; - start = drive << PARTN_BITS; - - for (i = 0; i < (1<part[minor].start_sect = 0; - gd->part[minor].nr_sects = 0; + for (p = 0; p < (1<part[p].start_sect = 0; + drive->part[p].nr_sects = 0; }; - gd->part[start].nr_sects = ide_capacity[DEV_HWIF][drive]; - resetup_one_dev(gd, drive); - - dev->busy = 0; - wake_up(&dev->wqueue); - return 0; -} - -#ifdef IDE_DRIVE_CMD -/* - * This function issues a specific IDE drive command onto the - * tail of the request queue, and waits for it to be completed. - * If arg is NULL, it goes through all the motions, - * but without actually sending a command to the drive. - */ -static int do_drive_cmd(int dev, char *args) -{ - unsigned long flags; - unsigned int major = MAJOR(dev); - struct request rq, *cur_rq; - struct blk_dev_struct *bdev; - struct semaphore sem = MUTEX_LOCKED; - - /* build up a special request, and add it to the queue */ - rq.buffer = args; - rq.cmd = IDE_DRIVE_CMD; - rq.errors = 0; - rq.sector = 0; - rq.nr_sectors = 0; - rq.current_nr_sectors = 0; - rq.sem = &sem; - rq.bh = NULL; - rq.bhtail = NULL; - rq.next = NULL; - rq.dev = dev; - bdev = &blk_dev[major]; - - save_flags(flags); - cli(); - cur_rq = bdev->current_request; - if (cur_rq == NULL) { /* empty request list? */ - bdev->current_request = &rq; /* service ours immediately */ - bdev->request_fn(); - } else { - while (cur_rq->next != NULL) /* find end of request list */ - cur_rq = cur_rq->next; - cur_rq->next = &rq; /* add rq to the end */ - } - - down(&sem); /* wait for it to be serviced */ - restore_flags(flags); - return rq.errors ? -EIO : 0; /* return -EIO if errors */ -} -#endif /* IDE_DRIVE_CMD */ - -static int write_fs_long (unsigned long useraddr, long value) -{ - int err; + drive->part[0].nr_sects = current_capacity(drive); + resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit); - if (NULL == (long *)useraddr) - return -EINVAL; - if ((err = verify_area(VERIFY_WRITE, (long *)useraddr, sizeof(long)))) - return err; - put_user((unsigned)value, (long *) useraddr); + drive->busy = 0; + wake_up(&drive->wqueue); return 0; } @@ -1506,26 +1545,23 @@ { struct hd_geometry *loc = (struct hd_geometry *) arg; int err; - ide_dev_t *dev; + ide_drive_t *drive; unsigned long flags; if (!inode || !inode->i_rdev) return -EINVAL; - if ((dev = get_info_ptr(inode->i_rdev)) == NULL) + if ((drive = get_info_ptr(inode->i_rdev)) == NULL) return -ENODEV; switch (cmd) { case HDIO_GETGEO: - if (!loc || dev->type != disk) return -EINVAL; + if (!loc || drive->media != disk) return -EINVAL; err = verify_area(VERIFY_WRITE, loc, sizeof(*loc)); if (err) return err; - put_user(dev->bios_head, - (char *) &loc->heads); - put_user(dev->bios_sect, - (char *) &loc->sectors); - put_user(dev->bios_cyl, - (short *) &loc->cylinders); - put_user((unsigned)ide_hd[DEV_HWIF][MINOR(inode->i_rdev)].start_sect, - (long *) &loc->start); + put_user(drive->bios_head, (byte *) &loc->heads); + put_user(drive->bios_sect, (byte *) &loc->sectors); + put_user(drive->bios_cyl, (unsigned short *) &loc->cylinders); + put_user((unsigned)drive->part[inode->i_rdev&PARTN_MASK].start_sect, + (unsigned long *) &loc->start); return 0; case BLKFLSBUF: @@ -1544,34 +1580,34 @@ return write_fs_long(arg, read_ahead[MAJOR(inode->i_rdev)]); case BLKGETSIZE: /* Return device size */ - return write_fs_long(arg, ide_hd[DEV_HWIF][MINOR(inode->i_rdev)].nr_sects); + return write_fs_long(arg, drive->part[inode->i_rdev&PARTN_MASK].nr_sects); case BLKRRPART: /* Re-read partition tables */ return revalidate_disk(inode->i_rdev); case HDIO_GET_KEEPSETTINGS: - return write_fs_long(arg, dev->keep_settings); + return write_fs_long(arg, drive->keep_settings); case HDIO_GET_UNMASKINTR: - return write_fs_long(arg, dev->unmask); + return write_fs_long(arg, drive->unmask); case HDIO_GET_CHIPSET: - return write_fs_long(arg, dev->chipset); + return write_fs_long(arg, drive->chipset); case HDIO_GET_MULTCOUNT: - return write_fs_long(arg, dev->mult_count); + return write_fs_long(arg, drive->mult_count); case HDIO_GET_IDENTITY: - if (!arg || (MINOR(inode->i_rdev) & PARTN_MASK)) + if (!arg || (inode->i_rdev & PARTN_MASK)) return -EINVAL; - if (dev->id == NULL) + if (drive->id == NULL) return -ENOMSG; - err = verify_area(VERIFY_WRITE, (char *)arg, sizeof(*dev->id)); + err = verify_area(VERIFY_WRITE, (char *)arg, sizeof(*drive->id)); if (err) return err; - memcpy_tofs((char *)arg, (char *)dev->id, sizeof(*dev->id)); + memcpy_tofs((char *)arg, (char *)drive->id, sizeof(*drive->id)); return 0; case HDIO_GET_NOWERR: - return write_fs_long(arg, dev->bad_wstat == BAD_R_STAT); + return write_fs_long(arg, drive->bad_wstat == BAD_R_STAT); case HDIO_SET_KEEPSETTINGS: case HDIO_SET_UNMASKINTR: @@ -1581,24 +1617,28 @@ case HDIO_SET_CHIPSET: if (!suser()) return -EACCES; - if ((MINOR(inode->i_rdev) & PARTN_MASK)) + if ((inode->i_rdev & PARTN_MASK)) return -EINVAL; save_flags(flags); cli(); switch (cmd) { case HDIO_SET_KEEPSETTINGS: - dev->keep_settings = arg; + drive->keep_settings = arg; break; case HDIO_SET_UNMASKINTR: - dev->unmask = arg; + drive->unmask = arg; break; case HDIO_SET_NOWERR: - dev->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; + drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; break; case HDIO_SET_CHIPSET: - dev->chipset = arg; - dev->vlb_sync = (arg & 2) >> 1; - dev->vlb_32bit = (arg & 1); + drive->chipset = arg; + drive->vlb_32bit = (arg & 1); + drive->vlb_sync = (arg & 2) >> 1; +#ifndef VLB_SYNC + if (drive->vlb_sync) + printk("%s: VLB_SYNC not supported by this kernel\n", drive->name); +#endif break; } restore_flags(flags); @@ -1606,24 +1646,24 @@ case HDIO_SET_MULTCOUNT: if (!suser()) return -EACCES; - if (MINOR(inode->i_rdev) & PARTN_MASK) + if (inode->i_rdev & PARTN_MASK) return -EINVAL; - if ((dev->id != NULL) && (arg > dev->id->max_multsect)) + if ((drive->id != NULL) && (arg > drive->id->max_multsect)) return -EINVAL; save_flags(flags); cli(); - if (dev->special.b.set_multmode) { + if (drive->special.b.set_multmode) { restore_flags(flags); return -EBUSY; } - dev->mult_req = arg; - dev->special.b.set_multmode = 1; + drive->mult_req = arg; + drive->special.b.set_multmode = 1; restore_flags(flags); #ifndef IDE_DRIVE_CMD return 0; #else do_drive_cmd (inode->i_rdev, NULL); - return (dev->mult_count == arg) ? 0 : -EIO; + return (drive->mult_count == arg) ? 0 : -EIO; case HDIO_DRIVE_CMD: { @@ -1649,41 +1689,39 @@ default: #ifdef CONFIG_BLK_DEV_IDECD - if (dev->type == cdrom) - return ide_cdrom_ioctl(dev, inode, file, cmd, arg); + if (drive->media == cdrom) + return ide_cdrom_ioctl(drive, inode, file, cmd, arg); #endif /* CONFIG_BLK_DEV_IDECD */ return -EPERM; } } -static int ide_check_media_change (dev_t full_dev) +static int ide_check_media_change (dev_t i_rdev) { - ide_dev_t *dev; + ide_drive_t *drive; - if ((dev = get_info_ptr(full_dev)) == NULL) + if ((drive = get_info_ptr(i_rdev)) == NULL) return -ENODEV; #ifdef CONFIG_BLK_DEV_IDECD - if (dev->type == cdrom) - return cdrom_check_media_change (dev); + if (drive->media == cdrom) + return ide_cdrom_check_media_change (drive); #endif /* CONFIG_BLK_DEV_IDECD */ - if (dev->removeable) /* for disks */ + if (drive->removeable) /* for disks */ return 1; /* always assume it was changed */ return 0; } - -static void fixstring (byte *s, int bytecount, int byteswap) +static void fixstring (byte *s, const int bytecount, const int byteswap) { - byte *p, *end = &s[bytecount &= ~1]; /* bytecount must be even */ + byte *p = s, *end = &s[bytecount & ~1]; /* bytecount must be even */ if (byteswap) { - /* convert from big-endian to little-endian */ + /* convert from big-endian to host byte order */ for (p = end ; p != s;) { unsigned short *pp = (unsigned short *) (p -= 2); - *pp = (*pp >> 8) | (*pp << 8); + *pp = ntohs(*pp); } } - p = s; /* strip leading blanks */ while (s != end && *s == ' ') @@ -1700,40 +1738,14 @@ *p++ = '\0'; } -static int lba_capacity_is_ok (struct hd_driveid *id) -/* - * Returns: 1 if lba_capacity looks sensible - * 0 otherwise - */ -{ - unsigned long lba_sects = id->lba_capacity; - unsigned long chs_sects = id->cyls * id->heads * id->sectors; - unsigned long _10_percent = chs_sects / 10; - - /* perform a rough sanity check on lba_sects: within 10% is "okay" */ - if ((lba_sects - chs_sects) < _10_percent) - return 1; /* lba_capacity is good */ - - /* some drives have the word order reversed */ - lba_sects = (lba_sects << 16) | (lba_sects >> 16); - if ((lba_sects - chs_sects) < _10_percent) { - id->lba_capacity = lba_sects; /* fix it */ - return 1; /* lba_capacity is (now) good */ - } - return 0; /* lba_capacity value is bad */ -} - -static unsigned long probe_mem_start; /* used by drive/irq probing routines */ - -static void do_identify (ide_dev_t *dev, byte cmd) +static void do_identify (ide_drive_t *drive, byte cmd) { int bswap; struct hd_driveid *id; unsigned long capacity, check; - id = dev->id = (struct hd_driveid *) probe_mem_start; /* kmalloc() */ - probe_mem_start += 512; - input_ide_data(dev, id, SECTOR_WORDS); /* read 512 bytes of id info */ + id = drive->id = ide_alloc(SECTOR_WORDS*4); + ide_input_data(drive, id, SECTOR_WORDS); /* read 512 bytes of id info */ sti(); /* @@ -1741,8 +1753,8 @@ */ if ((id->model[0] == 'P' && id->model[1] == 'M') || (id->model[0] == 'S' && id->model[1] == 'K')) { - printk("%s: EATA SCSI HBA %.10s\n", dev->name, id->model); - dev->present = 0; + printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model); + drive->present = 0; return; } @@ -1768,17 +1780,17 @@ #ifdef CONFIG_BLK_DEV_IDECD byte type = (id->config >> 8) & 0x0f; #endif /* CONFIG_BLK_DEV_IDECD */ - printk("%s: %s, ATAPI,", dev->name, id->model); + printk("%s: %s, ATAPI, ", drive->name, id->model); + drive->media = cdrom; #ifdef CONFIG_BLK_DEV_IDECD if (type == 0 || type == 5) - printk(" CDROM drive\n"); + printk("CDROM drive\n"); else - printk(" UNKNOWN device\n"); - dev->type = cdrom; /* until we do it "correctly" above */ - dev->present = 1; - dev->removeable = 1; + printk("UNKNOWN device\n"); + drive->present = 1; + drive->removeable = 1; #else - printk(unsupported); + printk("not supported by this kernel\n"); #endif /* CONFIG_BLK_DEV_IDECD */ return; } @@ -1786,16 +1798,16 @@ /* check for removeable disks (eg. SYQUEST), ignore 'WD' drives */ if (id->config & (1<<7)) { /* removeable disk ? */ if (id->model[0] != 'W' || id->model[1] != 'D') - dev->removeable = 1; + drive->removeable = 1; } - dev->type = disk; + drive->media = disk; /* Extract geometry if we did not already have one for the drive */ - if (!dev->present) { - dev->present = 1; - dev->cyl = dev->bios_cyl = id->cyls; - dev->head = dev->bios_head = id->heads; - dev->sect = dev->bios_sect = id->sectors; + if (!drive->present) { + drive->present = 1; + drive->cyl = drive->bios_cyl = id->cyls; + drive->head = drive->bios_head = id->heads; + drive->sect = drive->bios_sect = id->sectors; } /* Handle logical geometry translation by the drive */ if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads @@ -1811,12 +1823,12 @@ * An exception to this is the cylinder count, * which we reexamine later on to correct for 1024 limitations. */ - dev->cyl = id->cur_cyls; - dev->head = id->cur_heads; - dev->sect = id->cur_sectors; - capacity = dev->cyl * dev->head * dev->sect; + drive->cyl = id->cur_cyls; + drive->head = id->cur_heads; + drive->sect = id->cur_sectors; /* check for word-swapped "capacity" field in id information */ + capacity = drive->cyl * drive->head * drive->sect; check = (id->cur_capacity0 << 16) | id->cur_capacity1; if (check == capacity) { /* was it swapped? */ /* yes, bring it into little-endian order: */ @@ -1825,39 +1837,31 @@ } } /* Use physical geometry if what we have still makes no sense */ - if ((!dev->head || dev->head > 16) && id->heads && id->heads <= 16) { - dev->cyl = id->cyls; - dev->head = id->heads; - dev->sect = id->sectors; + if ((!drive->head || drive->head > 16) && id->heads && id->heads <= 16) { + drive->cyl = id->cyls; + drive->head = id->heads; + drive->sect = id->sectors; } /* Correct the number of cyls if the bios value is too small */ - if (dev->sect == dev->bios_sect && dev->head == dev->bios_head) { - if (dev->cyl > dev->bios_cyl) - dev->bios_cyl = dev->cyl; - } - /* Determine capacity, and use LBA if the drive properly supports it */ - if ((id->capability & 2) && lba_capacity_is_ok(id)) { - dev->select.b.lba = 1; - capacity = id->lba_capacity; - } else { - capacity = dev->cyl * dev->head * dev->sect; + if (drive->sect == drive->bios_sect && drive->head == drive->bios_head) { + if (drive->cyl > drive->bios_cyl) + drive->bios_cyl = drive->cyl; } - ide_capacity[DEV_HWIF][dev->select.b.drive] = capacity; + (void) current_capacity (drive); /* initialize LBA selection */ + printk ("%s: %.40s, %ldMB w/%dKB Cache, %sCHS=%d/%d/%d", - dev->name, id->model, capacity/2048L, id->buf_size/2, - dev->select.b.lba ? "LBA, " : "", - dev->bios_cyl, dev->bios_head, dev->bios_sect); + drive->name, id->model, current_capacity(drive)/2048L, id->buf_size/2, + drive->select.b.lba ? "LBA, " : "", + drive->bios_cyl, drive->bios_head, drive->bios_sect); - dev->mult_count = 0; + drive->mult_count = 0; if (id->max_multsect) { - dev->mult_req = INITIAL_MULT_COUNT; - if (dev->mult_req > id->max_multsect) - dev->mult_req = id->max_multsect; - if (dev->mult_req || ((id->multsect_valid & 1) && id->multsect)) { - dev->special.b.set_multmode = 1; - dev->be_quiet = 1; - } + drive->mult_req = INITIAL_MULT_COUNT; + if (drive->mult_req > id->max_multsect) + drive->mult_req = id->max_multsect; + if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect)) + drive->special.b.set_multmode = 1; printk(", MaxMult=%d", id->max_multsect); } printk("\n"); @@ -1873,70 +1877,66 @@ while (timer > jiffies); } - -static int try_to_identify (ide_dev_t *dev, byte cmd) /* + * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive + * and waits for a response. It also monitors irqs while this is + * happening, in hope of automatically determining which one is + * being used by the interface. + * * Returns: 0 device was identified * 1 device timed-out (no response to identify request) * 2 device aborted the command (refused to identify itself) */ +static int try_to_identify (ide_drive_t *drive, byte cmd) { int hd_status, rc; unsigned long timeout; -#if PROBE_FOR_IRQS int irqs = 0; - static byte irq_probed[2] = {0,0}; -#endif /* PROBE_FOR_IRQS */ - OUT_BYTE(dev->ctl|2,HD_CMD); /* disable device irq */ -#if PROBE_FOR_IRQS - if (!irq_probed[DEV_HWIF]) { /* already probed for IRQ? */ + if (!HWIF(drive)->irq) { /* already got an IRQ? */ probe_irq_off(probe_irq_on()); /* clear dangling irqs */ irqs = probe_irq_on(); /* start monitoring irqs */ - OUT_BYTE(dev->ctl,HD_CMD); /* enable device irq */ + OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */ } -#endif /* PROBE_FOR_IRQS */ + delay_10ms(); /* take a deep breath */ - if ((IN_BYTE(HD_ALTSTATUS,DEV_HWIF) ^ IN_BYTE(HD_STATUS,DEV_HWIF)) & ~INDEX_STAT) { - hd_status = HD_STATUS; /* an ancient Seagate drive */ - printk("%s: probing with STATUS instead of ALTSTATUS\n", dev->name); + if ((IN_BYTE(IDE_ALTSTATUS_REG) ^ IN_BYTE(IDE_STATUS_REG)) & ~INDEX_STAT) { + printk("%s: probing with STATUS instead of ALTSTATUS\n", drive->name); + hd_status = IDE_STATUS_REG; /* ancient Seagate drives */ } else - hd_status = HD_ALTSTATUS; /* use non-intrusive polling */ - OUT_BYTE(cmd,HD_COMMAND); /* ask drive for ID */ + hd_status = IDE_ALTSTATUS_REG; /* use non-intrusive polling */ + + OUT_BYTE(cmd,IDE_COMMAND_REG); /* ask drive for ID */ timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; timeout += jiffies; do { if (jiffies > timeout) { -#if PROBE_FOR_IRQS - if (!irq_probed[DEV_HWIF]) + if (!HWIF(drive)->irq) (void) probe_irq_off(irqs); -#endif /* PROBE_FOR_IRQS */ return 1; /* drive timed-out */ } delay_10ms(); /* give drive a breather */ - } while (IN_BYTE(hd_status,DEV_HWIF) & BUSY_STAT); + } while (IN_BYTE(hd_status) & BUSY_STAT); + delay_10ms(); /* wait for IRQ and DRQ_STAT */ - if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_R_STAT)) { + if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { cli(); /* some systems need this */ - do_identify(dev, cmd); /* drive returned ID */ + do_identify(drive, cmd); /* drive returned ID */ rc = 0; /* success */ } else rc = 2; /* drive refused ID */ -#if PROBE_FOR_IRQS - if (!irq_probed[DEV_HWIF]) { + if (!HWIF(drive)->irq) { irqs = probe_irq_off(irqs); /* get irq number */ - if (irqs > 0) { - irq_probed[DEV_HWIF] = 1; - ide_irq[DEV_HWIF] = irqs; - } else /* Mmmm.. multiple IRQs */ - printk("%s: IRQ probe failed (%d)\n", dev->name, irqs); + if (irqs > 0) + HWIF(drive)->irq = irqs; + else /* Mmmm.. multiple IRQs */ + printk("%s: IRQ probe failed (%d)\n", drive->name, irqs); } -#endif /* PROBE_FOR_IRQS */ return rc; } /* - * This routine has the difficult job of finding a drive if it exists, + * do_probe() has the difficult job of finding a drive if it exists, * without getting hung up if it doesn't exist, without trampling on * ethernet cards, and without leaving any IRQs dangling to haunt us later. * @@ -1944,274 +1944,356 @@ * but does not respond right away, the probe will "hang in there" * for the maximum wait time (about 30 seconds), otherwise it will * exit much more quickly. - */ -static int do_probe (ide_dev_t *dev, byte cmd) -/* + * * Returns: 0 device was identified * 1 device timed-out (no response to identify request) * 2 device aborted the command (refused to identify itself) * 3 bad status from device (possible for ATAPI drives) - * 4 probe was not attempted + * 4 probe was not attempted because failure was obvious */ +static int do_probe (ide_drive_t *drive, byte cmd) { int rc; #ifdef CONFIG_BLK_DEV_IDECD - if (dev->present) { /* avoid waiting for inappropriate probes */ - if ((dev->type == disk) ^ (cmd == WIN_IDENTIFY)) + if (drive->present) { /* avoid waiting for inappropriate probes */ + if ((drive->media == disk) ^ (cmd == WIN_IDENTIFY)) return 4; } #endif /* CONFIG_BLK_DEV_IDECD */ -#if DEBUG +#ifdef DEBUG printk("probing for %s: present=%d, type=%s, probetype=%s\n", - dev->name, dev->present, dev->type ? "cdrom":"disk", + drive->name, drive->present, drive->media ? "cdrom":"disk", (cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI"); #endif - OUT_BYTE(dev->select.all,HD_CURRENT); /* select target drive */ + OUT_BYTE(drive->select.all,IDE_SELECT_REG); /* select target drive */ delay_10ms(); /* wait for BUSY_STAT */ - if (IN_BYTE(HD_CURRENT,DEV_HWIF) != dev->select.all && !dev->present) { - OUT_BYTE(0xa0,HD_CURRENT); /* exit with drive0 selected */ + if (IN_BYTE(IDE_SELECT_REG) != drive->select.all && !drive->present) { + OUT_BYTE(0xa0,IDE_SELECT_REG); /* exit with drive0 selected */ return 3; /* no i/f present: avoid killing ethernet cards */ } - if (OK_STAT(GET_STAT(DEV_HWIF),READY_STAT,BUSY_STAT) - || dev->present || cmd == WIN_PIDENTIFY) + if (OK_STAT(GET_STAT(),READY_STAT,BUSY_STAT) + || drive->present || cmd == WIN_PIDENTIFY) { - if ((rc = try_to_identify(dev, cmd))) /* send cmd and wait */ - rc = try_to_identify(dev, cmd); /* failed: try again */ + if ((rc = try_to_identify(drive,cmd))) /* send cmd and wait */ + rc = try_to_identify(drive,cmd); /* failed: try again */ if (rc == 1) - printk("%s: no response (status = 0x%02x)\n", - dev->name, GET_STAT(DEV_HWIF)); - OUT_BYTE(dev->ctl|2,HD_CMD); /* disable device irq */ - delay_10ms(); - (void) GET_STAT(DEV_HWIF); /* ensure drive irq is clear */ + printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT()); + (void) GET_STAT(); /* ensure drive irq is clear */ } else { rc = 3; /* not present or maybe ATAPI */ } - if (dev->select.b.drive == 1) { - OUT_BYTE(0xa0,HD_CURRENT); /* exit with drive0 selected */ - delay_10ms(); - OUT_BYTE(dev->ctl|2,HD_CMD); /* disable device irq */ + if (drive->select.b.unit != 0) { + OUT_BYTE(0xa0,IDE_SELECT_REG); /* exit with drive0 selected */ delay_10ms(); - (void) GET_STAT(DEV_HWIF); /* ensure drive irq is clear */ + (void) GET_STAT(); /* ensure drive irq is clear */ } return rc; } -static byte probe_for_drive (ide_dev_t *dev) /* + * probe_for_drive() tests for existance of a given drive using do_probe(). + * * Returns: 0 no device was found - * 1 device was found (note: dev->present might still be 0) + * 1 device was found (note: drive->present might still be 0) */ +static byte probe_for_drive (ide_drive_t *drive) { - if (dev->noprobe) /* skip probing? */ - return dev->present; - if (do_probe(dev, WIN_IDENTIFY) >= 2) { /* if !(success || timed-out) */ + if (drive->noprobe) /* skip probing? */ + return drive->present; + if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */ #ifdef CONFIG_BLK_DEV_IDECD - (void) do_probe(dev, WIN_PIDENTIFY); /* look for ATAPI device */ + (void) do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */ #endif /* CONFIG_BLK_DEV_IDECD */ } - if (!dev->present) + if (!drive->present) return 0; /* drive not found */ - if (dev->id == NULL) { /* identification failed? */ - if (dev->type == disk) { - printk ("%s: non-IDE device, CHS=%d/%d/%d\n", - dev->name, dev->cyl, dev->head, dev->sect); + if (drive->id == NULL) { /* identification failed? */ + if (drive->media == disk) { + printk ("%s: non-IDE drive, CHS=%d/%d/%d\n", + drive->name, drive->cyl, drive->head, drive->sect); } #ifdef CONFIG_BLK_DEV_IDECD - else if (dev->type == cdrom) { - printk("%s: ATAPI cdrom (?)\n", dev->name); + else if (drive->media == cdrom) { + printk("%s: ATAPI cdrom (?)\n", drive->name); } #endif /* CONFIG_BLK_DEV_IDECD */ else { - dev->present = 0; /* nuke it */ + drive->present = 0; /* nuke it */ return 1; /* drive was found */ } } -#ifdef CONFIG_BLK_DEV_IDECD - if (dev->type == cdrom) - cdrom_setup(dev); -#endif /* CONFIG_BLK_DEV_IDECD */ - if (dev->type == disk && !dev->select.b.lba) { - if (!dev->head || dev->head > 16) { - printk("%s: cannot handle disk with %d physical heads\n", - dev->name, dev->head); - dev->present = 0; + if (drive->media == disk && !drive->select.b.lba) { + if (!drive->head || drive->head > 16) { + printk("%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", + drive->name, drive->head); + drive->present = 0; } } return 1; /* drive was found */ } -static void probe_for_drives (byte hwif) +/* + * This routine only knows how to look for drive units 0 and 1 + * on an interface, so any setting of MAX_DRIVES > 2 won't work here. + */ +static void probe_for_drives (ide_hwif_t *hwif) { - ide_dev_t *devs = &ide_dev[HWIF][0]; /* for convenience */ + unsigned int unit; - if (check_region(IDE_PORT(HD_DATA,HWIF),8) - || check_region(IDE_PORT(HD_CMD,HWIF),1)) - { - if (devs[0].present || devs[1].present) - printk("ERROR: "); - printk("%s: port(s) already in use\n", ide_name[HWIF]); - devs[0].present = 0; - devs[1].present = 0; + if (check_region(hwif->io_base,8) || check_region(hwif->ctl_port,1)) { + int msgout = 0; + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + if (drive->present) { + drive->present = 0; + printk("%s: ERROR, PORTS ALREADY IN USE\n", drive->name); + msgout = 1; + } + } + if (!msgout) + printk("%s: ports already in use, skipping probe\n", hwif->name); } else { unsigned long flags; save_flags(flags); - sti(); /* needed for jiffies and irq probing */ - /* second drive should only exist if first drive was found */ - if (probe_for_drive(&devs[0]) || devs[1].present) - (void) probe_for_drive(&devs[1]); -#if PROBE_FOR_IRQS - (void) probe_irq_off(probe_irq_on()); /* clear dangling irqs */ -#endif /* PROBE_FOR_IRQS */ - if (devs[0].present || devs[1].present) { - request_region(IDE_PORT(HD_DATA,HWIF),8,ide_name[HWIF]); - request_region(IDE_PORT(HD_CMD,HWIF),1,ide_name[HWIF]); +#if (MAX_DRIVES > 2) + printk("%s: probing for first 2 of %d possible drives\n", hwif->name, MAX_DRIVES); +#endif + sti(); /* needed for jiffies and irq probing */ + /* + * Second drive should only exist if first drive was found, + * but a lot of cdrom drives seem to be configured as slave-only + */ + for (unit = 0; unit < 2; ++unit) /* note the hardcoded '2' */ + (void) probe_for_drive(&hwif->drives[unit]); + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + if (drive->present) { + hwif->present = 1; + request_region(hwif->io_base, 8, hwif->name); + request_region(hwif->ctl_port, 1, hwif->name); +#ifdef CONFIG_BLK_DEV_IDECD + if (drive->media == cdrom) + ide_cdrom_setup(drive); +#endif /* CONFIG_BLK_DEV_IDECD */ + break; + } } restore_flags(flags); } } -static int next_drive = 0; /* used by the ide_setup() routines below */ - -void ide_setup(char *str, int *ints) +/* + * stridx() returns the offset of c within s, + * or -1 if c is '\0' or not found within s. + */ +static int stridx (const char *s, char c) { - ide_dev_t *dev; - const char *p[] = {"cyls","heads","sects","wpcom","irq"}; - int i, hwif, drive = next_drive++; -#ifdef CONFIG_BLK_DEV_HD - extern void hd_setup(char *, int *); + char *i = strchr(s, c); + return (i && c) ? i - s : -1; +} - if (drive < 2) { - hd_setup (str, ints); - return; - } -#endif /* CONFIG_BLK_DEV_HD */ - hwif = (drive > 1); - printk("%s: ", ide_name[hwif]); - if (drive > 3) { - printk("too many drives defined\n"); - return; - } - drive = drive & 1; - printk("%s: ", ide_devname[hwif][drive]); - if (!SUPPORT_TWO_INTERFACES && hwif != HWIF) { - printk(unsupported); - return; - } - dev = &ide_dev[hwif][drive]; - if (dev->present) - printk("(redefined) "); - if (ints[0] == 0) { -#if SUPPORT_DTC2278 - if (!strcmp(str,"dtc2278")) { - printk("%s\n",str); - probe_dtc2278 = 1; /* try to init DTC-2278 at boot */ - return; - } -#endif /* SUPPORT_DTC2278 */ -#if SUPPORT_SERIALIZE - if (!strcmp(str,"serialize")) { - printk("%s\n",str); - single_threaded = 1; /* serialize all drive access */ - return; - } -#endif /* SUPPORT_SERIALIZE */ - if (!strcmp(str,"noprobe")) { - printk("%s\n",str); - dev->noprobe = 1; /* don't probe for this drive */ - return; - } - if (!strcmp(str,"nowerr")) { - printk("%s\n",str); - dev->bad_wstat = BAD_R_STAT; /* ignore WRERR_STAT */ - return; +/* + * match_parm() does parsing for ide_setup(): + * + * 1. the first char of s must be '='. + * 2. if the remainder matches one of the supplied keywords, + * the index (1 based) of the keyword is negated and returned. + * 3. if the remainder is a series of no more than max_vals numbers + * separated by commas, the numbers are saved in vals[] and a + * count of how many were saved is returned. Base10 is assumed, + * and base16 is allowed when prefixed with "0x". + * 4. otherwise, zero is returned. + */ +static int match_parm (char *s, const char *keywords[], int vals[], int max_vals) +{ + static const char *decimal = "0123456789"; + static const char *hex = "0123456789abcdef"; + int i, n; + + if (*s++ == '=') { + /* + * Try matching against the supplied keywords, + * and return -(index+1) if we match one + */ + for (i = 0; *keywords != NULL; ++i) { + if (!strcmp(s, *keywords++)) + return -(i+1); } -#ifdef CONFIG_BLK_DEV_IDECD - if (!strcmp(str,"cdrom")) { - printk("cdrom\n"); - dev->present = 1; /* force autoprobe to find it */ - dev->type = cdrom; - return; + /* + * Look for a series of no more than "max_vals" + * numeric values separated by commas, in base10, + * or base16 when prefixed with "0x". + * Return a count of how many were found. + */ + for (n = 0; (i = stridx(decimal, *s)) >= 0;) { + vals[n] = i; + while ((i = stridx(decimal, *++s)) >= 0) + vals[n] = (vals[n] * 10) + i; + if (*s == 'x' && !vals[n]) { + while ((i = stridx(hex, *++s)) >= 0) + vals[n] = (vals[n] * 0x10) + i; + } + if (++n == max_vals) + break; + if (*s == ',') + ++s; } -#endif /* CONFIG_BLK_DEV_IDECD */ + if (!*s) + return n; } - if (ints[0] < 3 || ints[0] > 5) { - printk("bad parms, expected: cyls,heads,sects[,wpcom[,irq]]\n"); - } else { - for (i=0; i++ < ints[0];) - printk("%s=%d%c",p[i-1],ints[i],itype = disk; - dev->cyl = dev->bios_cyl = ints[1]; - dev->head = dev->bios_head = ints[2]; - dev->ctl = (ints[2] > 8 ? 8 : 0); - dev->sect = dev->bios_sect = ints[3]; - dev->wpcom = (ints[0] >= 4) ? ints[4] : 0; - if (ints[0] >= 5) - ide_irq[HWIF] = ints[5]; - ide_capacity[HWIF][drive] = BIOS_SECTORS(dev); - dev->present = 1; - } -} - -void hda_setup(char *str, int *ints) -{ - next_drive = 0; - ide_setup (str, ints); -} - -void hdb_setup(char *str, int *ints) -{ - next_drive = 1; - ide_setup (str, ints); + return 0; /* zero = nothing matched */ } -void hdc_setup(char *str, int *ints) -{ - next_drive = 2; - ide_setup (str, ints); -} - -void hdd_setup(char *str, int *ints) +/* + * ide_setup() gets called VERY EARLY during initialization, + * to handle kernel "command line" strings beginning with "hdx=" + * or "ide". Here is the complete set currently supported: + * + * "hdx=" is recognized for all "x" from "a" to "h", such as "hdc". + * "idex=" is recognized for all "x" from "0" to "3", such as "ide1". + * + * "hdx=noprobe" : drive may be present, but do not probe for it + * "hdx=nowerr" : ignore the WRERR_STAT bit on this drive + * "hdx=cdrom" : drive is present, and is a cdrom drive + * "hdx=cyl,head,sect" : disk drive is present, with specified geometry + * + * "idex=noprobe" : do not attempt to access/use this interface + * "idex=base" : probe for an interface at the addr specified, + * where "base" is usually 0x1f0 or 0x170 + * and "ctl" is assumed to be "base"+0x206 + * "idex=base,ctl" : specify both base and ctl + * "idex=base,ctl,irq" : specify base, ctl, and irq number + * + * The following two are valid ONLY on ide0 or ide1: + * + * "idex=dtc2278" : look for and try to initialize a dtc2278 + * "idex=serialize" : do not overlap operations on ide0 and ide1. + */ +void ide_setup (char *s) { - next_drive = 3; - ide_setup (str, ints); + int vals[3]; + ide_drive_t *drive; + unsigned int unit, hwif; + const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1); + const char max_hwif = '0' + (MAX_HWIFS - 1); + + printk("ide_setup: %s", s); + init_ide_data (); + if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { + const char *hd_words[] = {"noprobe", "nowerr", "cdrom", "serialize", NULL}; + unit = s[2] - 'a'; + hwif = unit / MAX_DRIVES; + unit = unit % MAX_DRIVES; + drive = &ide_hwifs[hwif].drives[unit]; + switch (match_parm(&s[3], hd_words, vals, 3)) { + case -1: /* "noprobe" */ + drive->noprobe = 1; + goto done; + case -2: /* "nowerr" */ + drive->bad_wstat = BAD_R_STAT; + ide_hwifs[hwif].noprobe = 0; + goto done; + case -3: /* "cdrom" */ + drive->present = 1; + drive->media = cdrom; + ide_hwifs[hwif].noprobe = 0; + goto done; + case -4: /* "serialize" */ + printk(" -- USE ""ide%c=serialize"" INSTEAD", '0'+hwif); + goto do_serialize; + case 3: /* cyl,head,sect */ + drive->media = disk; + drive->cyl = drive->bios_cyl = vals[0]; + drive->head = drive->bios_head = vals[1]; + drive->sect = drive->bios_sect = vals[2]; + drive->present = 1; + ide_hwifs[hwif].noprobe = 0; + goto done; + default: + goto bad_option; + } + } + if (s[0] == 'i' && s[1] == 'd' && s[2] == 'e' && s[3] >= '0' && s[3] <= max_hwif) { + const char *ide_words[] = {"dtc2278", "serialize", "noprobe", NULL}; + hwif = s[3] - '0'; + switch (match_parm(&s[4], ide_words, vals, 3)) { +#if SUPPORT_DTC2278 + case -1: /* "dtc2278" */ + if (hwif > 1) goto bad_hwif; + probe_dtc2278 = 1; + ide_hwifs[hwif].noprobe = 0; + goto done; +#endif /* SUPPORT_DTC2278 */ + case -2: /* "serialize" */ + do_serialize: + if (hwif > 1) goto bad_hwif; + single_threaded = 1; + ide_hwifs[hwif].noprobe = 0; + goto done; + case -3: /* "noprobe" */ + ide_hwifs[hwif].noprobe = 1; + goto done; + case 1: /* base */ + vals[1] = vals[0] + 0x206; /* default ctl */ + case 2: /* base,ctl */ + vals[2] = 0; /* default irq = probe for it */ + case 3: /* base,ctl,irq */ + ide_hwifs[hwif].io_base = vals[0]; + ide_hwifs[hwif].ctl_port = vals[1]; + ide_hwifs[hwif].irq = vals[2]; + ide_hwifs[hwif].noprobe = 0; + goto done; + } + } +bad_option: + printk(" -- BAD OPTION\n"); + return; +bad_hwif: + printk("-- NOT SUPPORTED ON ide%d", hwif); +done: + printk("\n"); } -int ide_xlate_1024 (dev_t full_dev, int need_offset, const char *msg) -{ - ide_dev_t *dev; - byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}, *heads = head_vals; - unsigned long capacity; +/* + * This routine is called from the partition-table code in genhd.c + * to "convert" a drive to a logical geometry with fewer than 1024 cyls + * It mimics the method used by Ontrack Disk Manager. + */ +int ide_xlate_1024 (dev_t i_rdev, int need_offset, const char *msg) +{ + ide_drive_t *drive; + static const byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}; + const byte *heads = head_vals; + unsigned long tracks; - if ((dev = get_info_ptr(full_dev)) == NULL && dev->id == NULL) + if ((drive = get_info_ptr(i_rdev)) == NULL || drive->id == NULL) return 0; - dev->cyl = dev->bios_cyl = dev->id->cyls; - dev->head = dev->bios_head = dev->id->heads; - dev->sect = dev->bios_sect = dev->id->sectors; - dev->special.b.set_geometry = 1; - - capacity = dev->bios_cyl * dev->bios_head * dev->bios_sect / 63; - dev->bios_sect = 63; - do { - dev->bios_head = *heads; - dev->bios_cyl = capacity / dev->bios_head; - } while (dev->bios_cyl >= 1024 && *++heads); + drive->cyl = drive->bios_cyl = drive->id->cyls; + drive->head = drive->bios_head = drive->id->heads; + drive->sect = drive->bios_sect = drive->id->sectors; + drive->special.b.set_geometry = 1; + + tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63; + drive->bios_sect = 63; + while (drive->bios_cyl >= 1024) { + drive->bios_head = *heads; + drive->bios_cyl = tracks / drive->bios_head; + if (0 == *++heads) + break; + } if (need_offset) { - dev->sect0 = 63; - capacity -= 1; - dev->bios_cyl = capacity / dev->bios_head; - } - capacity = dev->bios_cyl * dev->bios_head * dev->bios_sect; - ide_capacity[DEV_HWIF][dev->select.b.drive] = capacity; - ide_hd[DEV_HWIF][MINOR(full_dev)].nr_sects = capacity; - printk("%s [+%d,%d/%d/%d]", msg, dev->sect0, dev->bios_cyl, dev->bios_head, dev->bios_sect); + drive->sect0 = 63; + drive->bios_cyl = (tracks - 1) / drive->bios_head; + } + drive->part[0].nr_sects = current_capacity(drive); + printk("%s [+%d,%d/%d/%d]", msg, drive->sect0, drive->bios_cyl, drive->bios_head, drive->bios_sect); return 1; } -#ifndef CONFIG_BLK_DEV_HD /* * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc * controller that is BIOS compatible with ST-506, and thus showing up in our @@ -2224,135 +2306,90 @@ * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS. A non-zero value * means we have an AT controller hard disk for that drive. */ -static void probe_cmos_for_drives (void) +static void probe_cmos_for_drives (ide_hwif_t *hwif) { #ifdef __i386__ extern struct drive_info_struct drive_info; - byte drive, cmos_disks, *BIOS = (byte *) &drive_info; + byte cmos_disks, *BIOS = (byte *) &drive_info; + int unit; outb_p(0x12,0x70); /* specify CMOS address 0x12 */ cmos_disks = inb_p(0x71); /* read the data from 0x12 */ /* Extract drive geometry from CMOS+BIOS if not already setup */ - for (drive = 0; drive < MAX_DRIVES; drive++) { - ide_dev_t *dev = &ide_dev[0][drive]; - if ((cmos_disks & (0xf0 >> (drive*4))) && !dev->present) { - dev->cyl = dev->bios_cyl = *(unsigned short *)BIOS; - dev->head = dev->bios_head = * (BIOS+2); - dev->sect = dev->bios_sect = * (BIOS+14); - dev->wpcom = (*(unsigned short *)(BIOS+5))>>2; - dev->ctl = *(BIOS+8); - dev->wpcom = 0; - dev->type = disk; - dev->present = 1; - ide_capacity[0][drive] = BIOS_SECTORS(dev); + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + if ((cmos_disks & (0xf0 >> (unit*4))) && !drive->present) { + drive->cyl = drive->bios_cyl = *(unsigned short *)BIOS; + drive->head = drive->bios_head = * (BIOS+2); + drive->sect = drive->bios_sect = * (BIOS+14); + drive->wpcom = (*(unsigned short *)(BIOS+5))>>2; + drive->ctl = *(BIOS+8); + drive->wpcom = 0; + drive->media = disk; + drive->present = 1; } BIOS += 16; } #endif } -#endif /* CONFIG_BLK_DEV_HD */ - -static void init_ide_data (byte hwif) -{ - int drive; - - for (drive = 0; drive < (MAX_DRIVES<select.all = (drive<<4)|0xa0; - dev->hwif = hwif; - dev->unmask = 0; - dev->busy = 0; - dev->mult_count = 0; /* set by do_identify() */ - dev->mult_req = 0; /* set by do_identify() */ - dev->usage = 0; - dev->vlb_32bit = 0; - dev->vlb_sync = 0; - dev->id = NULL; - dev->ctl = 0x08; - dev->wqueue = NULL; - dev->special.all = 0; - dev->special.b.recalibrate = 1; - dev->special.b.set_geometry = 1; - dev->keep_settings = 0; - dev->sect0 = 0; - dev->removeable = 0; - ide_hd[hwif][drive<name = ide_devname[hwif][drive]; - if (!dev->bad_wstat) - dev->bad_wstat = BAD_W_STAT; - } -} /* - * This is the harddisk IRQ description. The SA_INTERRUPT in sa_flags - * means we enter the IRQ-handler with interrupts disabled: this is bad for - * interrupt latency, but anything else has led to problems on some - * machines. We enable interrupts as much as we can safely do in most places. + * This routine sets up the irq for an ide interface, and creates a new + * hwgroup for the irq/hwif if none was previously assigned. + * + * The SA_INTERRUPT in sa_flags means ide_intr() is always entered with + * interrupts completely disabled. This can be bad for interrupt latency, + * but anything else has led to problems on some machines. We re-enable + * interrupts as much as we can safely do in most places. */ -static byte setup_irq (byte hwif) +static int init_irq (ide_hwif_t *hwif) { - static byte rc = 0; unsigned long flags; - const char *msg = "", *primary_secondary[] = {"primary", "secondary"}; - void (*handler)(int, struct pt_regs *) = HWIF ? &ide1_intr : &ide0_intr; + ide_hwgroup_t *hwgroup; -#if SUPPORT_SHARING_IRQ - if (sharing_single_irq) { - if (HWIF != 0 && !rc) { /* IRQ already allocated? */ - msg = " (shared with ide0)"; - goto done; - } - handler = &ide_shared_intr; - } -#if SUPPORT_SERIALIZE - else if (single_threaded) { - handler = &ide_seq_intr; - if (HWIF != 0) - msg = " (single-threaded with ide0)"; - } -#endif /* SUPPORT_SERIALIZE */ -#endif /* SUPPORT_SHARING_IRQ */ + /* + * First, we try to grab the irq + */ save_flags(flags); cli(); - if ((rc = request_irq(ide_irq[HWIF],handler,SA_INTERRUPT,ide_name[HWIF]))) - msg = ": FAILED! unable to allocate IRQ"; - restore_flags(flags); -#if SUPPORT_SHARING_IRQ -done: -#endif /* SUPPORT_SHARING_IRQ */ - printk("%s: %s interface on irq %d%s\n", - ide_name[HWIF], primary_secondary[HWIF], ide_irq[HWIF], msg); - return rc; -} + if (request_irq(hwif->irq, ide_intr, SA_INTERRUPT, hwif->name)) { + restore_flags(flags); + printk(" -- FAILED!"); + return 1; + } -static void ide_geninit(byte hwif) -{ - static int drive; - - for (drive = 0; drive < MAX_DRIVES; drive++) { - ide_dev_t *dev = &ide_dev[HWIF][drive]; - if (dev->present) { - ide_hd[HWIF][drive<type == cdrom) - ide_hd[HWIF][drive<irq]) == NULL) { + hwgroup = ide_alloc(sizeof(ide_hwgroup_t)); + irq_to_hwgroup[hwif->irq] = hwgroup; + hwgroup->hwif = hwif->next = hwif; + hwgroup->rq = NULL; + hwgroup->handler = NULL; + hwgroup->drive = NULL; + init_timer(&hwgroup->timer); + hwgroup->timer.function = &timer_expiry; + hwgroup->timer.data = (unsigned long) hwgroup; + } else { + hwif->next = hwgroup->hwif->next; + hwgroup->hwif->next = hwif; } -} + hwif->hwgroup = hwgroup; -static void ide0_geninit(void) -{ - ide_geninit(0); -} + restore_flags(flags); /* safe now that hwif->hwgroup is set up */ -static void ide1_geninit(void) -{ - ide_geninit(1); + printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name, + hwif->io_base, hwif->io_base + 7, hwif->ctl_port, hwif->irq); + if (hwgroup->hwif != hwif) { + char *name = hwgroup->hwif->name; + if (hwgroup->hwif->irq == hwif->irq) + printk(" (shared with %s)", name); + else + printk(" (serialized with %s)", name); + } + printk("\n"); + return 0; } static struct file_operations ide_fops = { @@ -2388,15 +2425,15 @@ { int i; - for(i = 0; i < 3; i++) { - __inb(0x3f6); + for(i = 0; i < 3; ++i) { + inb(0x3f6); outb_p(b,0xb0); - __inb(0x3f6); + inb(0x3f6); outb_p(c,0xb4); - __inb(0x3f6); - if(__inb(0xb4) == c) { + inb(0x3f6); + if(inb(0xb4) == c) { outb_p(7,0xb0); - __inb(0x3f6); + inb(0x3f6); return; /* success */ } } @@ -2413,9 +2450,9 @@ /* This enables the second interface */ outb_p(4,0xb0); - __inb(0x3f6); + inb(0x3f6); outb_p(0x20,0xb4); - __inb(0x3f6); + inb(0x3f6); } #endif /* SUPPORT_DTC2278 */ @@ -2424,76 +2461,81 @@ */ unsigned long ide_init (unsigned long mem_start, unsigned long mem_end) { - byte hwif; + int h; + init_mem_start = (mem_start + 3uL) & ~3uL; /* for ide_alloc() */ + init_ide_data (); + /* + * First, we determine what hardware is present + */ #if SUPPORT_DTC2278 if (probe_dtc2278) try_to_init_dtc2278(); #endif /* SUPPORT_DTC2278 */ - /* single_threaded = 0; */ /* zero by default, override at boot */ - for (hwif = 0; hwif < 2; hwif++) { - init_ide_data (hwif); - if (SUPPORT_TWO_INTERFACES || hwif == HWIF) { - if (hwif == 0) -#ifdef CONFIG_BLK_DEV_HD - continue; -#else - probe_cmos_for_drives (); -#endif /* CONFIG_BLK_DEV_HD */ - probe_mem_start = (mem_start + 3uL) & ~3uL; + for (h = 0; h < MAX_HWIFS; ++h) { + ide_hwif_t *hwif = &ide_hwifs[h]; + if (!hwif->noprobe) { + if (hwif->io_base == HD_DATA) + probe_cmos_for_drives (hwif); probe_for_drives (hwif); - mem_start = probe_mem_start; - } - } - - /* At this point, all methods of drive detection have completed */ - ide_gendisk[0].nr_real = ide_dev[0][0].present + ide_dev[0][1].present; - ide_gendisk[1].nr_real = ide_dev[1][0].present + ide_dev[1][1].present; - if (ide_gendisk[1].nr_real && (ide_irq[0] == ide_irq[1])) { - if (!ide_gendisk[0].nr_real) { - ide_irq[0] = 0; /* needed by ide_intr() */ - } else { -#if SUPPORT_SHARING_IRQ - sharing_single_irq = 1; - single_threaded = 1; -#else /* SUPPORT_SHARING_IRQ */ - printk("%s: ide irq-sharing%s", ide_name[1], unsupported); - return mem_start; -#endif /* SUPPORT_SHARING_IRQ */ } - } + if (hwif->present) { + if (!hwif->irq) { + if (!(hwif->irq = default_irqs[h])) { + printk("%s: DISABLED, NO IRQ\n", hwif->name); + hwif->present = 0; + continue; + } + } #ifdef CONFIG_BLK_DEV_HD -#if SUPPORT_SHARING_IRQ - if (ide_irq[1] == 14 || sharing_single_irq) { -#else - if (ide_irq[1] == 14) { -#endif /* SUPPORT_SHARING_IRQ */ - printk("%s: irq-sharing not possible with old harddisk driver (hd.c)\n", ide_name[1]); - return mem_start; - } + if (hwif->irq == HD_IRQ && hwif->io_base != HD_DATA) { + printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name); + hwif->present = 0; + } #endif /* CONFIG_BLK_DEV_HD */ + } + } - for (hwif = 2; hwif-- > 0;) { - if (ide_gendisk[hwif].nr_real != 0 && !setup_irq(hwif)) { - const char *name = ide_name[HWIF]; - unsigned int major = ide_major[HWIF]; - if (register_blkdev(major, name, &ide_fops)) { - printk("%s: unable to get major number %d\n", name, major); - } else { - timer_table[ide_timer[HWIF]].fn - = HWIF ? ide1_timer_expiry : ide0_timer_expiry; -#if SUPPORT_SHARING_IRQ - if (single_threaded) - blk_dev[major].request_fn = &do_shared_request; - else -#endif /* SUPPORT_SHARING_IRQ */ - blk_dev[major].request_fn = - HWIF ? &do_ide1_request : &do_ide0_request; - read_ahead[major] = 8; /* (4kB) */ - ide_gendisk[HWIF].next = gendisk_head; - gendisk_head = &ide_gendisk[HWIF]; + /* + * Now we try to set up irqs and major devices for what was found + */ + for (h = MAX_HWIFS-1; h >= 0; --h) { + void (*rfn)(void); + ide_hwif_t *hwif = &ide_hwifs[h]; + if (!hwif->present) + continue; + hwif->present = 0; /* we set it back to 1 if all is ok below */ + if (h == 0 && single_threaded) { + if (ide_hwifs[1].present) { + if (irq_to_hwgroup[hwif->irq] != NULL) { + printk("%s: SERIALIZE BUG!\n", hwif->name); + continue; + } + irq_to_hwgroup[hwif->irq] = irq_to_hwgroup[ide_hwifs[1].irq]; } } + switch (hwif->major) { + case IDE0_MAJOR: rfn = &do_ide0_request; break; + case IDE1_MAJOR: rfn = &do_ide1_request; break; + case IDE2_MAJOR: rfn = &do_ide2_request; break; + case IDE3_MAJOR: rfn = &do_ide3_request; break; + default: + printk("%s: request_fn NOT DEFINED\n", hwif->name); + continue; + } + if (register_blkdev (hwif->major, hwif->name, &ide_fops)) { + printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major); + } else if (init_irq (hwif)) { + printk("%s: UNABLE TO GET IRQ %d\n", hwif->name, hwif->irq); + (void) unregister_blkdev (hwif->major, hwif->name); + } else { + init_gendisk(hwif); + blk_dev[hwif->major].request_fn = rfn; + read_ahead[hwif->major] = 8; /* (4kB) */ + hwif->present = 1; /* success */ + } } + mem_start = init_mem_start; + init_mem_start = 0uL; /* prevent further use of ide_alloc() */ return mem_start; } diff -u --recursive --new-file v1.3.18/linux/drivers/block/ide.h linux/drivers/block/ide.h --- v1.3.18/linux/drivers/block/ide.h Thu Jan 1 02:00:00 1970 +++ linux/drivers/block/ide.h Tue Aug 15 20:10:48 1995 @@ -0,0 +1,376 @@ +/* + * linux/drivers/block/ide.h + * + * Copyright (C) 1994, 1995 Linus Torvalds & authors + */ + +/* + * This is the multiple IDE interface driver, as evolved from hd.c. + * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). + * There can be up to two drives per interface, as per the ATA-2 spec. + * + * Primary i/f: ide0: major=3; (hda) minor=0; (hdb) minor=64 + * Secondary i/f: ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64 + * Tertiary i/f: ide2: major=33; (hde) minor=0; (hdf) minor=64 + * Quaternary i/f: ide3: major=34; (hdg) minor=0; (hdh) minor=64 + */ + +/****************************************************************************** + * IDE driver configuration options (play with these as desired): + */ +#undef REALLY_SLOW_IO /* most systems can safely undef this */ +#include + +#define REALLY_FAST_IO /* define if ide ports are perfect */ +#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */ + +#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */ +#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */ +#endif +#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */ +#define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */ +#endif +#ifndef SUPPORT_DTC2278 /* 1 to support DTC2278 chipset */ +#define SUPPORT_DTC2278 1 /* 0 to reduce kernel size */ +#endif +#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */ +#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */ +#endif + +/* + * IDE_DRIVE_CMD is used to implement many features of the hdparm utility + */ +#define IDE_DRIVE_CMD 99 /* (magic) undef to reduce kernel size*/ + +/* + * "No user-serviceable parts" beyond this point :) + *****************************************************************************/ + +typedef unsigned char byte; /* used everywhere */ + +/* + * Probably not wise to fiddle with these + */ +#define ERROR_MAX 8 /* Max read/write errors per sector */ +#define ERROR_RESET 3 /* Reset controller every 4th retry */ +#define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ + +/* + * Ensure that various configuration flags have compatible settings + */ +#ifdef REALLY_SLOW_IO +#undef REALLY_FAST_IO +#endif + +/* + * Definitions for accessing IDE controller registers + */ + +#define HWIF(drive) ((ide_hwif_t *)drive->hwif) +#define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup)) + +#define IDE_DATA_REG (HWIF(drive)->io_base) +#define IDE_ERROR_REG (HWIF(drive)->io_base+1) +#define IDE_NSECTOR_REG (HWIF(drive)->io_base+2) +#define IDE_SECTOR_REG (HWIF(drive)->io_base+3) +#define IDE_LCYL_REG (HWIF(drive)->io_base+4) +#define IDE_HCYL_REG (HWIF(drive)->io_base+5) +#define IDE_SELECT_REG (HWIF(drive)->io_base+6) +#define IDE_STATUS_REG (HWIF(drive)->io_base+7) +#define IDE_CONTROL_REG (HWIF(drive)->ctl_port) +#define IDE_FEATURE_REG IDE_ERROR_REG +#define IDE_COMMAND_REG IDE_STATUS_REG +#define IDE_ALTSTATUS_REG IDE_CONTROL_REG + +#ifdef REALLY_FAST_IO +#define OUT_BYTE(b,p) outb((b),p) +#define IN_BYTE(p) (byte)inb(p) +#else +#define OUT_BYTE(b,p) outb_p((b),p) +#define IN_BYTE(p) (byte)inb_p(p) +#endif /* REALLY_FAST_IO */ + +#define GET_ERR() IN_BYTE(IDE_ERROR_REG) +#define GET_STAT() IN_BYTE(IDE_STATUS_REG) +#define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good)) +#define BAD_R_STAT (BUSY_STAT | ERR_STAT) +#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) +#define BAD_STAT (BAD_R_STAT | DRQ_STAT) +#define DRIVE_READY (READY_STAT | SEEK_STAT) +#define DATA_READY (DRIVE_READY | DRQ_STAT) + +/* + * Some more useful definitions + */ +#define IDE_MAJOR_NAME "ide" /* the same for all i/f; see also genhd.c */ +#define MAJOR_NAME IDE_MAJOR_NAME +#define PARTN_BITS 6 /* number of minor dev bits for partitions */ +#define PARTN_MASK ((1< 0) + unsigned long last_timer; /* time when previous rq was done */ +#endif +#ifdef CONFIG_BLK_DEV_IDECD + struct request request_sense_request; /* from ide-cd.c */ + struct packet_command request_sense_pc; /* from ide-cd.c */ +#endif /* CONFIG_BLK_DEV_IDECD */ + } ide_hwif_t; + +/* + * our internal interrupt handler type + */ +typedef void (ide_handler_t)(ide_drive_t *); + +typedef struct hwgroup_s { + ide_handler_t *handler;/* irq handler, if active */ + ide_drive_t *drive; /* current drive */ + ide_hwif_t *hwif; /* ptr to current hwif in linked-list */ + struct request *rq; /* current request */ + struct timer_list timer; /* failsafe timer */ + struct request wrq; /* local copy of current write rq */ + } ide_hwgroup_t; + +/* + * One final include file, which references some of the data/defns from above + */ +#define IDE_DRIVER /* "parameter" for blk.h */ +#include "blk.h" + +#if (DISK_RECOVERY_TIME > 0) +void ide_set_recovery_timer (ide_hwif_t *); +#define SET_RECOVERY_TIMER(drive) ide_set_recovery_timer (drive) +#else +#define SET_RECOVERY_TIMER(drive) +#endif + +/* + * The main (re-)entry point for handling a new request is IDE_DO_REQUEST. + * Note that IDE_DO_REQUEST should *only* ever be invoked from an interrupt + * handler. All others, such as a timer expiry handler, should call + * do_hwgroup_request() instead (currently local to ide.c). + */ +void ide_do_request (ide_hwgroup_t *); +#define IDE_DO_REQUEST { SET_RECOVERY_TIMER(HWIF(drive)); ide_do_request(HWGROUP(drive)); } + + +/* + * This is used for (nearly) all data transfers from the IDE interface + */ +void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); + +/* + * This is used for (nearly) all data transfers to the IDE interface + */ +void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); + +/* + * This is used on exit from the driver, to designate the next irq handler + * and also to start the safety timer. + */ +void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler); + +/* + * Error reporting, in human readable form (luxurious, but a memory hog). + */ +byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat); + +/* + * ide_error() takes action based on the error returned by the controller. + * + * Returns 1 if an ide reset operation has been initiated, in which case + * the caller MUST simply return from the driver (through however many levels). + * Returns 0 otherwise. + */ +int ide_error (ide_drive_t *drive, const char *msg, byte stat); + +/* + * This routine busy-waits for the drive status to be not "busy". + * It then checks the status for all of the "good" bits and none + * of the "bad" bits, and if all is okay it returns 0. All other + * cases return 1 after invoking ide_error() + * + */ +int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeout); + +/* + * This is called from genhd.c to correct DiskManager/EZ-Drive geometries + */ +int ide_xlate_1024(dev_t, int, const char *); + +#ifdef CONFIG_BLK_DEV_IDECD +/* + * These are routines in ide-cd.c invoked from ide.c + */ +void ide_do_rw_cdrom (ide_drive_t *, unsigned long); +int ide_cdrom_ioctl (ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); +int ide_cdrom_check_media_change (ide_drive_t *); +int ide_cdrom_open (struct inode *, struct file *, ide_drive_t *); +void ide_cdrom_release (struct inode *, struct file *, ide_drive_t *); +void ide_cdrom_setup (ide_drive_t *); +#endif /* CONFIG_BLK_DEV_IDECD */ diff -u --recursive --new-file v1.3.18/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v1.3.18/linux/drivers/block/ll_rw_blk.c Fri Jul 7 08:54:45 1995 +++ linux/drivers/block/ll_rw_blk.c Sun Aug 13 20:19:12 1995 @@ -243,7 +243,7 @@ if (disk_index < 4) kstat.dk_drive[disk_index]++; break; - case HD_MAJOR: + case IDE0_MAJOR: /* same as HD_MAJOR */ case XT_DISK_MAJOR: disk_index = (MINOR(req->dev) & 0x0040) >> 6; kstat.dk_drive[disk_index]++; break; @@ -305,6 +305,7 @@ if (blk_size[major][MINOR(bh->b_dev)] < (sector + count)>>1) { bh->b_dirt = bh->b_uptodate = 0; bh->b_req = 0; + printk("attempt to access beyond end of device\n"); return; } /* Uhhuh.. Nasty dead-lock possible here.. */ @@ -334,7 +335,9 @@ || major == IDE1_MAJOR || major == FLOPPY_MAJOR || major == SCSI_DISK_MAJOR - || major == SCSI_CDROM_MAJOR) + || major == SCSI_CDROM_MAJOR + || major == IDE2_MAJOR + || major == IDE3_MAJOR) && (req = blk_dev[major].current_request)) { #ifdef CONFIG_BLK_DEV_HD @@ -583,11 +586,11 @@ req->next = NULL; } memset(ro_bits,0,sizeof(ro_bits)); +#ifdef CONFIG_BLK_DEV_IDE + mem_start = ide_init(mem_start,mem_end); /* this MUST preceed hd_init */ +#endif #ifdef CONFIG_BLK_DEV_HD mem_start = hd_init(mem_start,mem_end); -#endif -#ifdef CONFIG_BLK_DEV_IDE - mem_start = ide_init(mem_start,mem_end); #endif #ifdef CONFIG_BLK_DEV_XD mem_start = xd_init(mem_start,mem_end); diff -u --recursive --new-file v1.3.18/linux/drivers/block/xd.c linux/drivers/block/xd.c --- v1.3.18/linux/drivers/block/xd.c Tue Jun 27 14:11:33 1995 +++ linux/drivers/block/xd.c Sun Aug 13 20:19:12 1995 @@ -153,7 +153,7 @@ /* xd_geninit: grab the IRQ and DMA channel, initialise the drives */ /* and set up the "raw" device entries in the table */ -static void xd_geninit (void) +static void xd_geninit (struct gendisk *ignored) { u_char i,controller,*address; diff -u --recursive --new-file v1.3.18/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v1.3.18/linux/drivers/char/Makefile Wed Aug 9 14:55:39 1995 +++ linux/drivers/char/Makefile Tue Aug 15 20:01:14 1995 @@ -9,52 +9,40 @@ # parent makes.. # -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - # # This file contains the font map for the default (hardware) font # FONTMAPFILE = cp437.uni -OBJS = tty_io.o n_tty.o console.o keyboard.o serial.o \ +L_TARGET := char.a +M_OBJS := +L_OBJS := tty_io.o n_tty.o console.o keyboard.o serial.o \ tty_ioctl.o pty.o vt.o mem.o vc_screen.o \ defkeymap.o consolemap.o vesa_blank.o selection.o -SRCS = tty_io.c n_tty.c console.c keyboard.c serial.c \ - tty_ioctl.c pty.c vt.c mem.c vc_screen.c \ - defkeymap.c consolemap.c vesa_blank.c selection.c - ifdef CONFIG_CYCLADES -OBJS := $(OBJS) cyclades.o -SRCS := $(SRCS) cyclades.c +L_OBJS += cyclades.o endif ifdef CONFIG_ATIXL_BUSMOUSE M = y -OBJS := $(OBJS) atixlmouse.o -SRCS := $(SRCS) atixlmouse.c +L_OBJS += atixlmouse.o endif ifdef CONFIG_BUSMOUSE M = y -OBJS := $(OBJS) busmouse.o -SRCS := $(SRCS) busmouse.c +L_OBJS += busmouse.o endif ifdef CONFIG_PRINTER -OBJS := $(OBJS) lp.o -SRCS := $(SRCS) lp.c +L_OBJS += lp.o else -MODULES := $(MODULES) lp.o +M_OBJS += lp.o endif ifdef CONFIG_MS_BUSMOUSE M = y -OBJS := $(OBJS) msbusmouse.o -SRCS := $(SRCS) msbusmouse.c +L_OBJS += msbusmouse.o endif ifdef CONFIG_82C710_MOUSE @@ -63,56 +51,29 @@ ifdef CONFIG_PSMOUSE M = y -OBJS := $(OBJS) psaux.o -SRCS := $(SRCS) psaux.c +L_OBJS += psaux.o endif ifdef CONFIG_QIC02_TAPE -OBJS := $(OBJS) tpqic02.o -SRCS := $(SRCS) tpqic02.c +L_OBJS += tpqic02.o endif ifdef M -OBJS := $(OBJS) mouse.o -SRCS := $(SRCS) mouse.c +L_OBJS += mouse.o endif ifdef CONFIG_SCC -OBJS := $(OBJS) scc.o -SRCS := $(SRCS) scc.c +L_OBJS += scc.o endif - - -all: uni_hash_tbl.h char.a - -char.a: $(OBJS) - $(AR) rcs char.a $(OBJS) - sync - -ifdef MODULES - -modules: $(MODULES) - (cd ../../modules;for i in $(MODULES); do ln -sf ../drivers/char/$$i .; done) - -else -modules: +include $(TOPDIR)/Rules.make -endif +fastdep: uni_hash.tbl -ifdef MODULES -dep: uni_hash_tbl.h - $(CPP) -M $(SRCS) > .depend - $(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend -else -dep: uni_hash_tbl.h - $(CPP) -M $(SRCS) > .depend -endif +consolemap.o: conmakehash: conmakehash.c $(HOSTCC) -o conmakehash conmakehash.c -uni_hash_tbl.h: $(FONTMAPFILE) conmakehash - ./conmakehash $(FONTMAPFILE) 641 283 6 > uni_hash_tbl.h - -include $(TOPDIR)/Rules.make +uni_hash.tbl: $(FONTMAPFILE) conmakehash + ./conmakehash $(FONTMAPFILE) 641 283 6 > uni_hash.tbl diff -u --recursive --new-file v1.3.18/linux/drivers/char/conmakehash.c linux/drivers/char/conmakehash.c --- v1.3.18/linux/drivers/char/conmakehash.c Tue Jun 13 15:40:16 1995 +++ linux/drivers/char/conmakehash.c Tue Aug 15 19:32:01 1995 @@ -306,11 +306,11 @@ printf("\ /*\n\ - * uni_hash_tbl.h\n\ + * uni_hash.tbl\n\ *\n\ * Do not edit this file; it was automatically generated by\n\ *\n\ - * conmakehash %s %d %d %d > uni_hash_tbl.h\n\ + * conmakehash %s %d %d %d > uni_hash.tbl\n\ *\n\ */\n\ \n\ diff -u --recursive --new-file v1.3.18/linux/drivers/char/consolemap.c linux/drivers/char/consolemap.c --- v1.3.18/linux/drivers/char/consolemap.c Thu Jun 29 19:02:40 1995 +++ linux/drivers/char/consolemap.c Tue Aug 15 19:32:01 1995 @@ -294,7 +294,7 @@ * Usually, the mapping will be loaded simultaneously with the font. */ -#include "uni_hash_tbl.h" /* Include hash tables & parameters */ +#include "uni_hash.tbl" /* Include hash tables & parameters */ int hashtable_contents_valid = 1; diff -u --recursive --new-file v1.3.18/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v1.3.18/linux/drivers/char/serial.c Sun Aug 13 14:45:29 1995 +++ linux/drivers/char/serial.c Tue Aug 15 07:05:35 1995 @@ -2442,7 +2442,7 @@ /* * This routine is called by rs_init() to initialize a specific serial - * port. It determines what type of UART ship this serial port is + * port. It determines what type of UART chip this serial port is * using: 8250, 16450, 16550, 16550A. The important question is * whether or not this UART is a 16550A or not, since this will * determine whether or not we can use its FIFO features or not. diff -u --recursive --new-file v1.3.18/linux/drivers/net/3c501.c linux/drivers/net/3c501.c --- v1.3.18/linux/drivers/net/3c501.c Wed Aug 2 13:21:02 1995 +++ linux/drivers/net/3c501.c Tue Aug 15 18:08:32 1995 @@ -676,11 +676,12 @@ } #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_3c501 = { - " " /*"3c501"*/, - 0, 0, 0, 0, - 0x280, 5, - 0, 0, 0, NULL, el1_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0x280, 5, + 0, 0, 0, NULL, el1_probe }; int io=0x280; int irq=5; diff -u --recursive --new-file v1.3.18/linux/drivers/net/3c503.c linux/drivers/net/3c503.c --- v1.3.18/linux/drivers/net/3c503.c Sun Aug 13 14:45:30 1995 +++ linux/drivers/net/3c503.c Tue Aug 15 18:08:32 1995 @@ -40,12 +40,11 @@ #include #include +#include #include "8390.h" #include "3c503.h" -extern struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp); int el2_probe(struct device *dev); int el2_pio_probe(struct device *dev); @@ -486,7 +485,7 @@ el2pio_drv.irq = irq; if (io == 0) - printk("3c503: You should not use auto-probing with insmod!\n"); + printk("3c503: You should not use auto-probing with insmod!\n"); rc2 = 0; no_pio = 1; @@ -507,11 +506,19 @@ if (MOD_IN_USE) printk("3c503: device busy, remove delayed\n"); else { + int ioaddr; + if (no_pio) { + ioaddr = el2_drv.base_addr; unregister_netdev(&el2_drv); } else { + ioaddr = el2pio_drv.base_addr; unregister_netdev(&el2pio_drv); } + + /* If we don't do this, we can't re-insmod it later. */ + release_region(ioaddr, EL2_IO_EXTENT); + } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/3c505.c linux/drivers/net/3c505.c --- v1.3.18/linux/drivers/net/3c505.c Sun Aug 13 14:45:30 1995 +++ linux/drivers/net/3c505.c Tue Aug 15 18:08:32 1995 @@ -1449,7 +1449,7 @@ /* * and reserve the address region */ - request_region(dev->base_addr,16,"3c505"); + request_region(dev->base_addr, ELP_IO_EXTENT, "3c505"); /* * initialise the device @@ -1459,8 +1459,12 @@ } #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_3c505 = { - " " /*"3c505"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, elplus_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, elplus_probe }; int io = 0x300; int irq = 0; @@ -1468,7 +1472,7 @@ int init_module(void) { if (io == 0) - printk("3c505: You should not use auto-probing with insmod!\n"); + printk("3c505: You should not use auto-probing with insmod!\n"); dev_3c505.base_addr = io; dev_3c505.irq = irq; if (register_netdev(&dev_3c505) != 0) { @@ -1486,6 +1490,9 @@ else { unregister_netdev(&dev_3c505); + + /* If we don't do this, we can't re-insmod it later. */ + release_region(dev_3c505.base_addr, ELP_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/3c505.h linux/drivers/net/3c505.h --- v1.3.18/linux/drivers/net/3c505.h Tue Jun 6 11:22:06 1995 +++ linux/drivers/net/3c505.h Tue Aug 15 18:08:32 1995 @@ -13,6 +13,8 @@ #define PORT_DATA 0x04 /* read/write, 16-bit */ #define PORT_CONTROL 0x06 /* read/write, 8-bit */ +#define ELP_IO_EXTENT 0x10 /* size of used IO registers */ + /* * host control registers bits */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/3c507.c linux/drivers/net/3c507.c --- v1.3.18/linux/drivers/net/3c507.c Sun Aug 13 14:45:30 1995 +++ linux/drivers/net/3c507.c Tue Aug 15 18:08:32 1995 @@ -65,9 +65,6 @@ #include #include -extern struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp); - /* use 0 for production, 1 for verification, 2..7 for debug */ #ifndef NET_DEBUG @@ -376,7 +373,7 @@ } /* We've committed to using the board, and can start filling in *dev. */ - request_region(ioaddr, EL16_IO_EXTENT,"3c507"); + request_region(ioaddr, EL16_IO_EXTENT, "3c507"); dev->base_addr = ioaddr; outb(0x01, ioaddr + MISC_CTRL); @@ -885,8 +882,13 @@ } #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_3c507 = { - " " /*"3c507"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, el16_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, el16_probe +}; int io = 0x300; int irq = 0; @@ -894,7 +896,7 @@ int init_module(void) { if (io == 0) - printk("3c507: You should not use auto-probing with insmod!\n"); + printk("3c507: You should not use auto-probing with insmod!\n"); dev_3c507.base_addr = io; dev_3c507.irq = irq; if (register_netdev(&dev_3c507) != 0) { @@ -912,6 +914,10 @@ else { unregister_netdev(&dev_3c507); + + /* If we don't do this, we can't re-insmod it later. */ + free_irq(dev_3c507.irq); + release_region(dev_3c507.base_addr, EL16_IO_EXTENT); } } #endif /* MODULE */ @@ -925,4 +931,3 @@ * c-indent-level: 4 * End: */ - diff -u --recursive --new-file v1.3.18/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v1.3.18/linux/drivers/net/3c509.c Sun Aug 13 14:45:30 1995 +++ linux/drivers/net/3c509.c Tue Aug 15 18:08:33 1995 @@ -65,6 +65,8 @@ #define ID_PORT 0x100 #define EEPROM_READ 0x80 +#define EL3_IO_EXTENT 16 + #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD) @@ -232,7 +234,7 @@ dev->base_addr = ioaddr; dev->irq = irq; dev->if_port = if_port; - request_region(dev->base_addr, 16,"3c509"); + request_region(dev->base_addr, EL3_IO_EXTENT, "3c509"); { const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"}; @@ -703,8 +705,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_3c509 = { - " " /*"3c509"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, el3_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, el3_probe }; int io = 0; int irq = 0; @@ -732,6 +738,8 @@ unregister_netdev(&dev_3c509); kfree_s(dev_3c509.priv,sizeof(struct el3_private)); dev_3c509.priv=NULL; + /* If we don't do this, we can't re-insmod it later. */ + release_region(dev_3c509.base_addr, EL3_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v1.3.18/linux/drivers/net/Makefile Wed Aug 9 14:55:39 1995 +++ linux/drivers/net/Makefile Tue Aug 15 15:07:02 1995 @@ -7,341 +7,320 @@ # are difficult for users to deal with. include CONFIG -# Build MODULES by appending to this string for every driver below -MODULES := - -NETDRV_OBJS := Space.o auto_irq.o net_init.o loopback.o - -.c.o: - $(CC) $(CFLAGS) -c $< - - -# The point of the makefile... -all: net.a - -Space.o: Space.c ../../include/linux/autoconf.h - $(CC) $(CFLAGS) $(OPTS) -c $< - -net_init.o: ../../include/linux/autoconf.h +L_TARGET := net.a +L_OBJS := Space.o auto_irq.o net_init.o loopback.o +M_OBJS := +MOD_LIST_NAME := NET_MODULES ifdef CONFIG_SEEQ8005 -NETDRV_OBJS := $(NETDRV_OBJS) seeq8005.o +L_OBJS += seeq8005.o endif ifdef CONFIG_IBMTR -NETDRV_OBJS := $(NETDRV_OBJS) ibmtr.o +L_OBJS += ibmtr.o else -MODULES := $(MODULES) ibmtr.o +M_OBJS += ibmtr.o endif ifdef CONFIG_SK_G16 -NETDRV_OBJS := $(NETDRV_OBJS) sk_g16.o +L_OBJS += sk_g16.o endif ifdef CONFIG_NET_IPIP -NETDRV_OBJS := $(NETDRV_OBJS) tunnel.o +L_OBJS += tunnel.o else -MODULES := $(MODULES) tunnel.o +M_OBJS += tunnel.o endif ifdef CONFIG_HP100 -NETDRV_OBJS := $(NETDRV_OBJS) hp100.o +L_OBJS += hp100.o else -MODULES := $(MODULES) hp100.o +M_OBJS += hp100.o endif ifdef CONFIG_WD80x3 -NETDRV_OBJS := $(NETDRV_OBJS) wd.o +L_OBJS += wd.o CONFIG_8390 = CONFIG_8390 else -MODULES := $(MODULES) wd.o +M_OBJS += wd.o endif -wd.o: wd.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(WD_OPTS) -c $< ifdef CONFIG_EL2 -NETDRV_OBJS := $(NETDRV_OBJS) 3c503.o +L_OBJS += 3c503.o CONFIG_8390 = CONFIG_8390 else -MODULES := $(MODULES) 3c503.o +M_OBJS += 3c503.o endif -3c503.o: 3c503.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(EL2_OPTS) -c $< ifdef CONFIG_NE2000 -NETDRV_OBJS := $(NETDRV_OBJS) ne.o +L_OBJS += ne.o CONFIG_8390 = CONFIG_8390 else -MODULES := $(MODULES) ne.o +M_OBJS += ne.o endif -ne.o: ne.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(NE_OPTS) -c $< ifdef CONFIG_HPLAN -NETDRV_OBJS := $(NETDRV_OBJS) hp.o +L_OBJS += hp.o CONFIG_8390 = CONFIG_8390 else -MODULES := $(MODULES) hp.o +M_OBJS += hp.o endif -hp.o: hp.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(HP_OPTS) -c $< ifdef CONFIG_HPLAN_PLUS -NETDRV_OBJS := $(NETDRV_OBJS) hp-plus.o +L_OBJS += hp-plus.o CONFIG_8390 = CONFIG_8390 else -MODULES := $(MODULES) hp-plus.o +M_OBJS += hp-plus.o endif ifdef CONFIG_ULTRA -NETDRV_OBJS := $(NETDRV_OBJS) smc-ultra.o +L_OBJS += smc-ultra.o CONFIG_8390 = CONFIG_8390 else -MODULES := $(MODULES) smc-ultra.o +M_OBJS += smc-ultra.o endif ifdef CONFIG_E2100 -NETDRV_OBJS := $(NETDRV_OBJS) e2100.o +L_OBJS += e2100.o CONFIG_8390 = CONFIG_8390 else -MODULES := $(MODULES) e2100.o +M_OBJS += e2100.o endif ifdef CONFIG_PLIP -NETDRV_OBJS := $(NETDRV_OBJS) plip.o +L_OBJS += plip.o else -MODULES := $(MODULES) plip.o +M_OBJS += plip.o endif -plip.o: plip.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(PLIP_OPTS) -c $< ifdef CONFIG_PPP -NETDRV_OBJS := $(NETDRV_OBJS) ppp.o +L_OBJS += ppp.o CONFIG_SLHC = CONFIG_SLHC else -MODULES := $(MODULES) ppp.o +M_OBJS += ppp.o endif ifdef CONFIG_SLIP -NETDRV_OBJS := $(NETDRV_OBJS) slip.o +L_OBJS += slip.o CONFIG_SLHC = CONFIG_SLHC else -MODULES := $(MODULES) slip.o +M_OBJS += slip.o endif -slip.o: slip.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) -c $< ifdef CONFIG_DE650 -ETDRV_OBJS := $(NETDRV_OBJS) de650.o +ETDRV_OBJS := $(L_OBJS) de650.o CONFIG_8390 = CONFIG_8390 endif ifdef CONFIG_3C589 -NETDRV_OBJS := $(NETDRV_OBJS) 3c589.o +L_OBJS += 3c589.o endif ifdef CONFIG_DUMMY -NETDRV_OBJS := $(NETDRV_OBJS) dummy.o +L_OBJS += dummy.o else -MODULES := $(MODULES) dummy.o +M_OBJS += dummy.o endif -dummy.o: dummy.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) -c $< ifdef CONFIG_DE600 -NETDRV_OBJS := $(NETDRV_OBJS) de600.o +L_OBJS += de600.o else -MODULES := $(MODULES) de600.o +M_OBJS += de600.o endif -de600.o: de600.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(DE600_OPTS) -c $< ifdef CONFIG_DE620 -NETDRV_OBJS := $(NETDRV_OBJS) de620.o +L_OBJS += de620.o else -MODULES := $(MODULES) de620.o +M_OBJS += de620.o endif -de620.o: de620.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(DE620_OPTS) -c $< ifdef CONFIG_AT1500 -NETDRV_OBJS := $(NETDRV_OBJS) lance.o +L_OBJS += lance.o endif ifdef CONFIG_LANCE -NETDRV_OBJS := $(NETDRV_OBJS) lance.o +L_OBJS += lance.o endif ifdef CONFIG_AT1700 -NETDRV_OBJS := $(NETDRV_OBJS) at1700.o +L_OBJS += at1700.o else -MODULES := $(MODULES) at1700.o +M_OBJS += at1700.o endif ifdef CONFIG_EL1 -NETDRV_OBJS := $(NETDRV_OBJS) 3c501.o +L_OBJS += 3c501.o else -MODULES := $(MODULES) 3c501.o +M_OBJS += 3c501.o endif ifdef CONFIG_EL16 -NETDRV_OBJS := $(NETDRV_OBJS) 3c507.o +L_OBJS += 3c507.o else -MODULES ;= $(MODULES 3c507.o +M_OBJS += 3c507.o endif ifdef CONFIG_EL3 -NETDRV_OBJS := $(NETDRV_OBJS) 3c509.o +L_OBJS += 3c509.o else -MODULES := $(MODULES) 3c509.o +M_OBJS += 3c509.o endif ifdef CONFIG_EEXPRESS -NETDRV_OBJS := $(NETDRV_OBJS) eexpress.o +L_OBJS += eexpress.o else -MODULES := $(MODULES) eexpress.o +M_OBJS += eexpress.o endif ifdef CONFIG_EEXPRESS_PRO -NETDRV_OBJS := $(NETDRV_OBJS) eepro.o +L_OBJS += eepro.o else -MODULES := $(MODULES) eepro.o +M_OBJS += eepro.o endif ifdef CONFIG_WAVELAN -NETDRV_OBJS := $(NETDRV_OBJS) wavelan.o +L_OBJS += wavelan.o else -MODULES := $(MODULES) wavelan.o +M_OBJS += wavelan.o endif ifdef CONFIG_ZNET -NETDRV_OBJS := $(NETDRV_OBJS) znet.o +L_OBJS += znet.o endif ifdef CONFIG_DEPCA -NETDRV_OBJS := $(NETDRV_OBJS) depca.o +L_OBJS += depca.o else -MODULES := $(MODULES) depca.o +M_OBJS += depca.o endif -depca.o: depca.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(DEPCA_OPTS) -c $< ifdef CONFIG_EWRK3 -NETDRV_OBJS := $(NETDRV_OBJS) ewrk3.o +L_OBJS += ewrk3.o else -MODULES := $(MODULES) ewrk3.o +M_OBJS += ewrk3.o endif -ewrk3.o: ewrk3.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(EWRK3_OPTS) -c $< ifdef CONFIG_ATP -NETDRV_OBJS := $(NETDRV_OBJS) atp.o +L_OBJS += atp.o endif ifdef CONFIG_DE4X5 -NETDRV_OBJS := $(NETDRV_OBJS) de4x5.o +L_OBJS += de4x5.o else -MODULES := $(MODULES) de4x5.o +M_OBJS += de4x5.o endif -de4x5.o: de4x5.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(DE4X5_OPTS) -c $< ifdef CONFIG_NI52 -NETDRV_OBJS := $(NETDRV_OBJS) ni52.o +L_OBJS += ni52.o endif ifdef CONFIG_NI65 -NETDRV_OBJS := $(NETDRV_OBJS) ni65.o +L_OBJS += ni65.o endif ifdef CONFIG_ELPLUS -NETDRV_OBJS := $(NETDRV_OBJS) 3c505.o +L_OBJS += 3c505.o else -MODULES := $(MODULES) 3c505.o +M_OBJS += 3c505.o endif -3c505.o: 3c505.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(ELP_OPTS) -c $< ifdef CONFIG_AC3200 -NETDRV_OBJS := $(NETDRV_OBJS) ac3200.o +L_OBJS += ac3200.o CONFIG_8390 = CONFIG_8390 else -MODULES := $(MODULES) ac3200.o +M_OBJS += ac3200.o endif ifdef CONFIG_APRICOT -NETDRV_OBJS := $(NETDRV_OBJS) apricot.o +L_OBJS += apricot.o else -MODULES := $(MODULES) apricot.o +M_OBJS += apricot.o endif ifdef CONFIG_DEC_ELCP -NETDRV_OBJS := $(NETDRV_OBJS) tulip.o +L_OBJS += tulip.o else -MODULES := $(MODULES) tulip.o +M_OBJS += tulip.o endif ifdef CONFIG_ARCNET -NETDRV_OBJS := $(NETDRV_OBJS) arcnet.o +L_OBJS += arcnet.o else -MODULES := $(MODULES) arcnet.o +M_OBJS += arcnet.o endif ifdef CONFIG_PI -NETDRV_OBJS := $(NETDRV_OBJS) pi2.o +L_OBJS += pi2.o CONFIG_PI = CONFIG_PI endif -pi2.o: pi2.c CONFIG - $(CC) $(CPPFLAGS) $(CFLAGS) $(PI_OPTS) -c $< ifdef CONFIG_SLHC -NETDRV_OBJS := $(NETDRV_OBJS) slhc.o +L_OBJS += slhc.o else -MODULES := slhc.o $(MODULES) +M_OBJS += slhc.o endif ifdef CONFIG_8390 -NETDRV_OBJS := $(NETDRV_OBJS) 8390.o +L_OBJS += 8390.o else -MODULES := 8390.o $(MODULES) +M_OBJS += 8390.o endif -8390.o: 8390.c 8390.h CONFIG ifdef CONFIG_EQUALIZER -NETDRV_OBJS := $(NETDRV_OBJS) eql.o +L_OBJS += eql.o else -MODULES := $(MODULES) eql.o +M_OBJS += eql.o endif -net.a: $(NETDRV_OBJS) - rm -f net.a - $(AR) rcs net.a $(NETDRV_OBJS) +include $(TOPDIR)/Rules.make clean: rm -f core *.o *.a *.s -ifdef MODULES -dep: - $(CPP) -M $(NETDRV_OBJS:.o=.c) > .depend - $(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend -else -dep: - $(CPP) -M $(NETDRV_OBJS:.o=.c) > .depend -endif +wd.o: wd.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(WD_OPTS) -c $< -tar: +3c503.o: 3c503.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(EL2_OPTS) -c $< + +pi2.o: pi2.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(PI_OPTS) -c $< -ifdef MODULES +3c505.o: 3c505.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(ELP_OPTS) -c $< -modules: $(MODULES) - echo $(MODULES) > ../../modules/NET_MODULES - cd ../../modules; \ - for i in $(MODULES); do ln -sf ../drivers/net/$$i .; done +de4x5.o: de4x5.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(DE4X5_OPTS) -c $< -else +ewrk3.o: ewrk3.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(EWRK3_OPTS) -c $< -modules: +depca.o: depca.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(DEPCA_OPTS) -c $< -endif +Space.o: ../../include/linux/autoconf.h -include $(TOPDIR)/Rules.make +net_init.o: ../../include/linux/autoconf.h + +ne.o: ne.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(NE_OPTS) -c $< + +hp.o: hp.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(HP_OPTS) -c $< + +plip.o: plip.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(PLIP_OPTS) -c $< + +slip.o: slip.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< + +dummy.o: dummy.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< + +de600.o: de600.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(DE600_OPTS) -c $< + +de620.o: de620.c CONFIG + $(CC) $(CPPFLAGS) $(CFLAGS) $(DE620_OPTS) -c $< + +8390.o: 8390.c 8390.h CONFIG diff -u --recursive --new-file v1.3.18/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c --- v1.3.18/linux/drivers/net/ac3200.c Wed Aug 9 14:55:39 1995 +++ linux/drivers/net/ac3200.c Tue Aug 15 18:08:33 1995 @@ -44,6 +44,15 @@ #define AC_ENABLE 0x01 #define AC_CONFIG 0xC90 /* The configuration port. */ +#define AC_IO_EXTENT 0x10 /* IS THIS REALLY TRUE ??? */ + /* Actually accessed is: + * AC_NIC_BASE (0-15) + * AC_SA_PROM (0-5) + * AC_ID_PORT (0-3) + * AC_RESET_PORT + * AC_CONFIG + */ + /* Decoding of the configuration register. */ static unsigned char config2irqmap[8] = {15, 12, 11, 10, 9, 7, 5, 3}; static int addrmap[8] = @@ -144,9 +153,11 @@ if (request_irq(dev->irq, ei_interrupt, 0, "ac3200")) { printk (" unable to get IRQ %d.\n", dev->irq); - return 0; + return EAGAIN; } + request_region(ioaddr, AC_IO_EXTENT, "ac3200"); + dev->base_addr = ioaddr; #ifdef notyet @@ -281,8 +292,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_ac3200 = { - " " /*"ac3200"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ac3200_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, ac3200_probe }; int io = 0; int irq = 0; @@ -306,6 +321,10 @@ else { unregister_netdev(&dev_ac3200); + + /* If we don't do this, we can't re-insmod it later. */ + free_irq(dev_ac3200.irq); + release_region(dev_ac3200.base_addr, AC_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/apricot.c linux/drivers/net/apricot.c --- v1.3.18/linux/drivers/net/apricot.c Wed Aug 9 14:55:39 1995 +++ linux/drivers/net/apricot.c Tue Aug 15 18:08:33 1995 @@ -714,7 +714,7 @@ if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0) return ENODEV; - request_region(ioaddr, APRICOT_TOTAL_SIZE,"apricot"); + request_region(ioaddr, APRICOT_TOTAL_SIZE, "apricot"); dev->base_addr = ioaddr; ether_setup(dev); @@ -1014,8 +1014,9 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_apricot = { - " ", /* device name inserted by /linux/drivers/net/net_init.c */ + devicename, /* device name inserted by /linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0x300, 10, 0, 0, 0, NULL, apricot_probe }; @@ -1043,6 +1044,9 @@ unregister_netdev(&dev_apricot); kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf); dev_apricot.priv = NULL; + + /* If we don't do this, we can't re-insmod it later. */ + release_region(dev_apricot.base_addr, APRICOT_TOTAL_SIZE); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c --- v1.3.18/linux/drivers/net/arcnet.c Sun Aug 13 14:45:31 1995 +++ linux/drivers/net/arcnet.c Tue Aug 15 18:50:14 1995 @@ -193,6 +193,7 @@ #include #include #include +#include #include #include @@ -2447,11 +2448,13 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device thiscard = { - " ",/* if blank, device name inserted by /linux/drivers/net/net_init.c */ + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0, 0, /* I/O address, IRQ */ - 0, 0, 0, NULL, arcnet_probe }; + 0, 0, 0, NULL, arcnet_probe +}; int io=0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/at1700.c linux/drivers/net/at1700.c --- v1.3.18/linux/drivers/net/at1700.c Sun Aug 13 14:45:31 1995 +++ linux/drivers/net/at1700.c Tue Aug 15 18:08:33 1995 @@ -629,8 +629,12 @@ } #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_at1700 = { - " " /*"at1700"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, at1700_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, at1700_probe }; int io = 0x260; int irq = 0; @@ -638,7 +642,7 @@ int init_module(void) { if (io == 0) - printk("at1700: You should not use auto-probing with insmod!\n"); + printk("at1700: You should not use auto-probing with insmod!\n"); dev_at1700.base_addr = io; dev_at1700.irq = irq; if (register_netdev(&dev_at1700) != 0) { @@ -656,6 +660,11 @@ else { unregister_netdev(&dev_at1700); + + /* If we don't do this, we can't re-insmod it later. */ + free_irq(dev_at1700.irq); + irq2dev_map[dev_at1700.irq] = NULL; + release_region(dev_at1700.base_addr, AT1700_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/auto_irq.c linux/drivers/net/auto_irq.c --- v1.3.18/linux/drivers/net/auto_irq.c Tue Jul 11 10:02:49 1995 +++ linux/drivers/net/auto_irq.c Tue Aug 15 18:08:33 1995 @@ -28,7 +28,7 @@ #ifdef version -static char *version= +static const char *version= "auto_irq.c:v1.11 Donald Becker (becker@cesdis.gsfc.nasa.gov)"; #endif diff -u --recursive --new-file v1.3.18/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c --- v1.3.18/linux/drivers/net/de4x5.c Tue Aug 8 12:31:35 1995 +++ linux/drivers/net/de4x5.c Tue Aug 15 18:08:33 1995 @@ -2735,8 +2735,9 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device thisDE4X5 = { - " ", /* device name inserted by /linux/drivers/net/net_init.c */ + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0x2000, 10, /* I/O address, IRQ */ 0, 0, 0, NULL, de4x5_probe }; diff -u --recursive --new-file v1.3.18/linux/drivers/net/depca.c linux/drivers/net/depca.c --- v1.3.18/linux/drivers/net/depca.c Sun Aug 13 14:45:31 1995 +++ linux/drivers/net/depca.c Tue Aug 15 18:08:33 1995 @@ -1817,8 +1817,9 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device thisDepca = { - " ", /* device name inserted by /linux/drivers/net/net_init.c */ + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0x200, 7, /* I/O address, IRQ */ 0, 0, 0, NULL, depca_probe }; diff -u --recursive --new-file v1.3.18/linux/drivers/net/e2100.c linux/drivers/net/e2100.c --- v1.3.18/linux/drivers/net/e2100.c Sun Aug 13 14:45:31 1995 +++ linux/drivers/net/e2100.c Tue Aug 15 18:08:33 1995 @@ -151,9 +151,6 @@ if (status != 0x21 && status != 0x23) return ENODEV; - /* Grab the region so we can find a different board if IRQ select fails. */ - request_region(ioaddr, E21_IO_EXTENT,"e2100"); - /* Read the station address PROM. */ for (i = 0; i < 6; i++) station_addr[i] = inb(ioaddr + E21_SAPROM + i); @@ -179,6 +176,9 @@ } else if (dev->irq == 2) /* Fixup luser bogosity: IRQ2 is really IRQ9 */ dev->irq = 9; + /* Grab the region so we can find a different board if IRQ select fails. */ + request_region(ioaddr, E21_IO_EXTENT, "e2100"); + /* The 8390 is at the base address. */ dev->base_addr = ioaddr; @@ -356,8 +356,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_e2100 = { - " " /*"e2100"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, e2100_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, e2100_probe }; int io = 0x300; int irq = 0; @@ -365,7 +369,7 @@ int init_module(void) { if (io == 0) - printk("e2100: You should not use auto-probing with insmod!\n"); + printk("e2100: You should not use auto-probing with insmod!\n"); dev_e2100.base_addr = io; dev_e2100.irq = irq; if (register_netdev(&dev_e2100) != 0) { @@ -383,6 +387,9 @@ else { unregister_netdev(&dev_e2100); + + /* If we don't do this, we can't re-insmod it later. */ + release_region(dev_e2100.base_addr, E21_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/eepro.c linux/drivers/net/eepro.c --- v1.3.18/linux/drivers/net/eepro.c Sun Aug 13 14:45:31 1995 +++ linux/drivers/net/eepro.c Tue Aug 15 18:08:33 1995 @@ -404,7 +404,7 @@ printk(version); /* Grab the region so we can find another board if autoIRQ fails. */ - request_region(ioaddr, EEPRO_IO_EXTENT,"eepro"); + request_region(ioaddr, EEPRO_IO_EXTENT, "eepro"); /* Initialize the device structure */ if (dev->priv == NULL) @@ -756,9 +756,6 @@ irq2dev_map[dev->irq] = 0; - /* release the ioport-region */ - release_region(ioaddr, 16); - /* Update the statistics here. What statistics? */ /* We are supposed to wait for 200 us after a RESET */ @@ -1133,8 +1130,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_eepro = { - " " /*"eepro"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, eepro_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, eepro_probe }; int io = 0x200; int irq = 0; @@ -1143,7 +1144,7 @@ init_module(void) { if (io == 0) - printk("eepro: You should not use auto-probing with insmod!\n"); + printk("eepro: You should not use auto-probing with insmod!\n"); dev_eepro.base_addr = io; dev_eepro.irq = irq; @@ -1162,6 +1163,9 @@ unregister_netdev(&dev_eepro); kfree_s(dev_eepro.priv,sizeof(struct eepro_local)); dev_eepro.priv=NULL; + + /* If we don't do this, we can't re-insmod it later. */ + release_region(dev_eepro.base_addr, EEPRO_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c --- v1.3.18/linux/drivers/net/eexpress.c Sun Aug 13 14:45:31 1995 +++ linux/drivers/net/eexpress.c Tue Aug 15 18:08:33 1995 @@ -1,4 +1,3 @@ - /* eexpress.c: Intel EtherExpress device driver for Linux. */ /* Written 1993 by Donald Becker. @@ -146,6 +145,8 @@ #define EEPROM_Ctrl 14 #define ID_PORT 15 +#define EEXPRESS_IO_EXTENT 16 + /* EEPROM_Ctrl bits. */ #define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */ @@ -363,7 +364,7 @@ } /* We've committed to using the board, and can start filling in *dev. */ - request_region(ioaddr, 16,"eexpress"); + request_region(ioaddr, EEXPRESS_IO_EXTENT, "eexpress"); dev->base_addr = ioaddr; for (i = 0; i < 6; i++) { @@ -654,9 +655,6 @@ irq2dev_map[dev->irq] = 0; - /* release the ioport-region */ - release_region(ioaddr, 16); - /* Update the statistics here. */ #ifdef MODULE @@ -1002,8 +1000,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_eexpress = { - " " /*"eexpress"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, express_probe }; int irq=0x300; @@ -1013,7 +1015,7 @@ init_module(void) { if (io == 0) - printk("eexpress: You should not use auto-probing with insmod!\n"); + printk("eexpress: You should not use auto-probing with insmod!\n"); dev_eexpress.base_addr=io; dev_eexpress.irq=irq; if (register_netdev(&dev_eexpress) != 0) @@ -1025,12 +1027,15 @@ cleanup_module(void) { if (MOD_IN_USE) - printk("express: device busy, remove delayed\n"); + printk("eexpress: device busy, remove delayed\n"); else { unregister_netdev(&dev_eexpress); kfree_s(dev_eexpress.priv,sizeof(struct net_local)); dev_eexpress.priv=NULL; + + /* If we don't do this, we can't re-insmod it later. */ + release_region(dev_eexpress.base_addr, EEXPRESS_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/eql.c linux/drivers/net/eql.c --- v1.3.18/linux/drivers/net/eql.c Wed Aug 9 14:55:40 1995 +++ linux/drivers/net/eql.c Tue Aug 15 18:50:52 1995 @@ -126,6 +126,7 @@ #include #include +#include #include #include diff -u --recursive --new-file v1.3.18/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c --- v1.3.18/linux/drivers/net/ewrk3.c Wed Aug 2 13:21:04 1995 +++ linux/drivers/net/ewrk3.c Tue Aug 15 18:08:33 1995 @@ -1855,8 +1855,9 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device thisEthwrk = { - " ", /* device name inserted by /linux/drivers/net/net_init.c */ + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ 0, 0, 0, 0, 0x300, 5, /* I/O address, IRQ */ 0, 0, 0, NULL, ewrk3_probe }; diff -u --recursive --new-file v1.3.18/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c --- v1.3.18/linux/drivers/net/hp-plus.c Sun Aug 13 14:45:31 1995 +++ linux/drivers/net/hp-plus.c Tue Aug 15 18:08:33 1995 @@ -367,8 +367,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_hp = { - " " /*"hp"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, hp_plus_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, hp_plus_probe }; int io = 0x200; int irq = 0; @@ -376,11 +380,11 @@ int init_module(void) { if (io == 0) - printk("HP-plus: You should not use auto-probing with insmod!\n"); + printk("HP-plus: You should not use auto-probing with insmod!\n"); dev_hp.base_addr = io; dev_hp.irq = irq; if (register_netdev(&dev_hp) != 0) { - printk("hp: register_netdev() returned non-zero.\n"); + printk("HP-plus: register_netdev() returned non-zero.\n"); return -EIO; } return 0; @@ -390,10 +394,15 @@ cleanup_module(void) { if (MOD_IN_USE) - printk("hp: device busy, remove delayed\n"); + printk("HP-plus: device busy, remove delayed\n"); else { + int ioaddr = dev_hp.base_addr - NIC_OFFSET; + unregister_netdev(&dev_hp); + + /* If we don't do this, we can't re-insmod it later. */ + release_region(ioaddr, HP_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/hp.c linux/drivers/net/hp.c --- v1.3.18/linux/drivers/net/hp.c Sun Aug 13 14:45:31 1995 +++ linux/drivers/net/hp.c Tue Aug 15 18:08:33 1995 @@ -35,11 +35,9 @@ #include #include +#include #include "8390.h" -extern struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp); - /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int hppclan_portlist[] = { 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0}; @@ -130,9 +128,6 @@ if (dev == NULL) dev = init_etherdev(0, sizeof(struct ei_device), 0); - /* Grab the region so we can find another board if something fails. */ - request_region(ioaddr, HP_IO_EXTENT,"hp"); - printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr); for(i = 0; i < ETHER_ADDR_LEN; i++) @@ -171,6 +166,9 @@ } } + /* Grab the region so we can find another board if something fails. */ + request_region(ioaddr, HP_IO_EXTENT,"hp"); + if (ei_debug > 1) printk(version); @@ -327,8 +325,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_hp = { - " " /*"hp"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, hp_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, hp_probe }; int io = 300; int irq = 0; @@ -336,7 +338,7 @@ int init_module(void) { if (io == 0) - printk("hp: You should not use auto-probing with insmod!\n"); + printk("hp: You should not use auto-probing with insmod!\n"); dev_hp.base_addr = io; dev_hp.irq = irq; if (register_netdev(&dev_hp) != 0) { @@ -353,7 +355,13 @@ printk("hp: device busy, remove delayed\n"); else { + int ioaddr = dev_hp.base_addr - NIC_OFFSET; + unregister_netdev(&dev_hp); + + /* If we don't do this, we can't re-insmod it later. */ + free_irq(dev_hp.irq); + release_region(ioaddr, HP_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/hp100.c linux/drivers/net/hp100.c --- v1.3.18/linux/drivers/net/hp100.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/hp100.c Tue Aug 15 18:08:33 1995 @@ -1129,8 +1129,12 @@ static int hp100_port = -1; +static char devicename[9] = { 0, }; static struct device dev_hp100 = { - " ", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, hp100_probe + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, hp100_probe }; int init_module( void ) diff -u --recursive --new-file v1.3.18/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c --- v1.3.18/linux/drivers/net/ibmtr.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/ibmtr.c Tue Aug 15 18:08:33 1995 @@ -144,7 +144,8 @@ which references it. */ -int tok_probe(struct device *dev) { +int tok_probe(struct device *dev) +{ unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0; @@ -166,11 +167,12 @@ PIOaddr=TokBaseAddrs[iAddr]; /* address to try */ TokBaseAddrs[iAddr] = 0; /* (and marked already used */ if (PIOaddr == 0) continue; /* already tried this addr */ - if ( check_region(PIOaddr,4) ) { /* Make sure PIO address not - already assigned elsewhere before - we muck with I/O addresses */ + if ( check_region(PIOaddr,TR_IO_EXTENT) ) { /* Make sure PIO address not + already assigned elsewhere + before we muck with I/O + addresses */ if (ibmtr_debug_trace & TRC_INIT) - DPRINTK("check_region(%4hx,4) failed.\n",PIOaddr); + DPRINTK("check_region(%4hx,%d) failed.\n",PIOaddr, TR_IO_EXTENT); PIOaddr = 0; continue; /* clear to flag fail and try next */ } /* Query the adapter PIO base port which will return @@ -247,12 +249,13 @@ } /*?? Now, allocate some of the pl0 buffers for this driver.. */ - /*?? Now, allocate some of the PIO PORTs for this driver.. */ - request_region(PIOaddr,4,"ibmtr"); /* record PIOaddr range as busy */ if (!badti) ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL); - else { ti = badti; badti = NULL; }/*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */ + else { + ti = badti; badti = NULL; + }/*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */ + memset(ti,0,sizeof(struct tok_info)); ti->mmio= t_mmio; @@ -303,17 +306,17 @@ printk(".\n"); } - DPRINTK("hw address: "); - /* Get hw address of token ring card */ - j=0; - for (i=0; i<0x18; i=i+2) { - temp = *(char *)((ulong)AIP + (ulong)i + ti->mmio) & 0x0f; /* Tech ref states must do this */ - printk("%1X",ti->hw_address[j]=temp); - if(j&1) - dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4); - ++j; - } - printk("\n"); + DPRINTK("hw address: "); + /* Get hw address of token ring card */ + j=0; + for (i=0; i<0x18; i=i+2) { + temp = *(char *)((ulong)AIP + (ulong)i + ti->mmio) & 0x0f; /* Tech ref states must do this */ + printk("%1X",ti->hw_address[j]=temp); + if(j&1) + dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4); + ++j; + } + printk("\n"); /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/ ti->adapter_type = *(char *)(ti->mmio + AIPADAPTYPE); @@ -337,9 +340,9 @@ /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */ ti->dhb_size16mb = *(char *)(ti->mmio + AIP16MBDHB); - DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type, - ti->data_rate, ti->token_release, ti->avail_shared_ram/2, ti->shared_ram_paging, ti->dhb_size4mb, - ti->dhb_size16mb); + DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type, + ti->data_rate, ti->token_release, ti->avail_shared_ram/2, ti->shared_ram_paging, + ti->dhb_size4mb, ti->dhb_size16mb); /* We must figure out how much shared memory space this adapter will occupy so that if there are two adapters we can fit both @@ -359,39 +362,45 @@ unsigned char pg_size; #endif - DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2); + DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2); #ifdef ENABLE_PAGING - switch(ti->shared_ram_paging) { - case 0xf: break; - case 0xe: ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; - pg_size=32; /* 16KB page size */ - break; - case 0xd: ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; - pg_size=64; /* 32KB page size */ - break; - case 0xc: ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; - ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; - DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n"); - /* nb/dwm: I did this because RRR (3,2) bits are documented as - R/O and I can't find how to select which page size */ - /* Also, the above conditional statement sequence is invalid */ - /* as page_mask will always be set by the second stmt */ - badti=ti; - break; - default: DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging); - badti=ti; /* bail out if bad code */ - break; - } - if(ti->page_mask) { - if(pg_size > ti->mapped_ram_size) { - DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n", - pg_size, ti->mapped_ram_size); - ti->page_mask = 0; /* reset paging */ - } else { - ti->mapped_ram_size=ti->avail_shared_ram; /****** ?????????? *******/ - DPRINTK("Shared RAM paging enabled. Page size : %uK\n",((ti->page_mask^ 0xff)+1)>>2); - } - } + switch(ti->shared_ram_paging) { + case 0xf: + break; + case 0xe: + ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; + pg_size=32; /* 16KB page size */ + break; + case 0xd: + ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; + pg_size=64; /* 32KB page size */ + break; + case 0xc: + ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; + ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; + DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n"); + /* nb/dwm: I did this because RRR (3,2) bits are documented as + * R/O and I can't find how to select which page size + * Also, the above conditional statement sequence is invalid + * as page_mask will always be set by the second stmt + */ + badti=ti; + break; + default: + DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging); + badti=ti; /* bail out if bad code */ + break; + } + if(ti->page_mask) { + if(pg_size > ti->mapped_ram_size) { + DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n", + pg_size, ti->mapped_ram_size); + ti->page_mask = 0; /* reset paging */ + } else { + ti->mapped_ram_size=ti->avail_shared_ram; /****** ?????????? *******/ + DPRINTK("Shared RAM paging enabled. Page size : %uK\n",((ti->page_mask^ 0xff)+1)>>2); + } + } #else #endif } @@ -431,20 +440,24 @@ } irq2dev_map[irq]=dev; + /*?? Now, allocate some of the PIO PORTs for this driver.. */ + request_region(PIOaddr,TR_IO_EXTENT,"ibmtr"); /* record PIOaddr range + as busy */ + DPRINTK("%s",version); /* As we have passed card identification, let the world know we're here! */ dev->base_addr=PIOaddr; /* set the value for device */ - dev->open=tok_open; - dev->stop=tok_close; - dev->hard_start_xmit=tok_send_packet; - dev->get_stats = NULL; - dev->get_stats = tok_get_stats; - dev->set_multicast_list = NULL; - tr_setup(dev); - tok_init_card((unsigned long)dev); + dev->open=tok_open; + dev->stop=tok_close; + dev->hard_start_xmit=tok_send_packet; + dev->get_stats = NULL; + dev->get_stats = tok_get_stats; + dev->set_multicast_list = NULL; + tr_setup(dev); + tok_init_card((unsigned long)dev); - return 0; /* Return 0 to indicate we have found a Token Ring card. */ + return 0; /* Return 0 to indicate we have found a Token Ring card. */ } /* query the adapter for the size of shared RAM */ @@ -1198,15 +1211,19 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_ibmtr = { - " " /*"ibmtr"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, tok_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, tok_probe }; int io = 0xa20; int init_module(void) { if (io == 0) - printk("ibmtr: You should not use auto-probing with insmod!\n"); + printk("ibmtr: You should not use auto-probing with insmod!\n"); dev_ibmtr.base_addr = io; dev_ibmtr.irq = 0; if (register_netdev(&dev_ibmtr) != 0) { @@ -1224,6 +1241,11 @@ else { unregister_netdev(&dev_ibmtr); + + /* If we don't do this, we can't re-insmod it later. */ + free_irq(dev_ibmtr.irq); + irq2dev_map[dev_ibmtr.irq] = NULL; + release_region(dev_ibmtr.base_addr, TR_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/ibmtr.h linux/drivers/net/ibmtr.h --- v1.3.18/linux/drivers/net/ibmtr.h Tue Jun 6 11:22:09 1995 +++ linux/drivers/net/ibmtr.h Tue Aug 15 18:08:33 1995 @@ -36,6 +36,8 @@ #define MMIOStartLocP 0x0a20 /* Primary adapter's starting MMIO area */ #define MMIOStartLocA 0x0a24 /* Alternate adapter's starting MMIO area */ +#define TR_IO_EXTENT 4 /* size of used IO range */ + #define GLOBAL_INT_ENABLE 0x02f0 /* MMIO bits 0-4 select register */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/lance.c linux/drivers/net/lance.c --- v1.3.18/linux/drivers/net/lance.c Tue Aug 8 12:31:36 1995 +++ linux/drivers/net/lance.c Tue Aug 15 18:08:33 1995 @@ -36,8 +36,6 @@ #include #include -struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp); static unsigned int lance_portlist[] = {0x300, 0x320, 0x340, 0x360, 0}; unsigned long lance_probe1(int ioaddr, unsigned long mem_start); diff -u --recursive --new-file v1.3.18/linux/drivers/net/loopback.c linux/drivers/net/loopback.c --- v1.3.18/linux/drivers/net/loopback.c Tue Jul 25 18:21:21 1995 +++ linux/drivers/net/loopback.c Tue Aug 15 18:51:43 1995 @@ -32,6 +32,7 @@ #include #include #include /* For the statistics structure. */ +#include /* For ARPHRD_ETHER */ #include #include diff -u --recursive --new-file v1.3.18/linux/drivers/net/ne.c linux/drivers/net/ne.c --- v1.3.18/linux/drivers/net/ne.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/ne.c Tue Aug 15 18:08:33 1995 @@ -42,6 +42,7 @@ #include #include +#include #include "8390.h" /* Some defines that people can play with if so inclined. */ @@ -57,10 +58,6 @@ /* ---- No user-serviceable parts below ---- */ -extern struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp); - - /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int netcard_portlist[] = { 0x300, 0x280, 0x320, 0x340, 0x360, 0}; @@ -540,8 +537,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_ne2000 = { - " " /*"ne2000"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ne_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, ne_probe }; int io = 0x300; int irq = 0; @@ -565,6 +566,10 @@ else { unregister_netdev(&dev_ne2000); + + /* If we don't do this, we can't re-insmod it later. */ + free_irq(dev_ne2000.irq); + release_region(dev_ne2000.base_addr, NE_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/net_init.c linux/drivers/net/net_init.c --- v1.3.18/linux/drivers/net/net_init.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/net_init.c Tue Aug 15 18:46:26 1995 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -114,8 +115,10 @@ dev->priv = (void*) *mem_startp; *mem_startp += sizeof_priv; } else - dev->priv = kmalloc(sizeof_priv, GFP_KERNEL); - memset(dev->priv, 0, sizeof_priv); + dev->priv = sizeof_priv + ? kmalloc(sizeof_priv, GFP_KERNEL) + : NULL; + if (dev->priv) memset(dev->priv, 0, sizeof_priv); goto found; } } diff -u --recursive --new-file v1.3.18/linux/drivers/net/pi2.c linux/drivers/net/pi2.c --- v1.3.18/linux/drivers/net/pi2.c Wed Aug 2 13:21:04 1995 +++ linux/drivers/net/pi2.c Tue Aug 15 18:56:20 1995 @@ -117,6 +117,7 @@ #include #include #include +#include #include "pi2.h" #include "z8530.h" #include diff -u --recursive --new-file v1.3.18/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v1.3.18/linux/drivers/net/plip.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/plip.c Mon Aug 14 12:57:49 1995 @@ -166,10 +166,10 @@ enum plip_nibble_state nibble; union { struct { -#if defined(LITTLE_ENDIAN) +#if defined(__LITTLE_ENDIAN) unsigned char lsb; unsigned char msb; -#elif defined(BIG_ENDIAN) +#elif defined(__BIG_ENDIAN) unsigned char msb; unsigned char lsb; #else diff -u --recursive --new-file v1.3.18/linux/drivers/net/skeleton.c linux/drivers/net/skeleton.c --- v1.3.18/linux/drivers/net/skeleton.c Fri Jun 30 16:22:28 1995 +++ linux/drivers/net/skeleton.c Tue Aug 15 18:08:33 1995 @@ -21,7 +21,7 @@ */ -static char *version = +static const char *version = "skeleton.c:v1.51 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; /* Always include 'config.h' first in case the user wants to turn on @@ -43,6 +43,14 @@ under the GPL. */ +#ifdef MODULE +#include +#include +#else +#define MOD_INC_USE_COUNT do {} while (0) +#define MOD_DEC_USE_COUNT do {} while (0) +#endif + #include #include #include @@ -62,8 +70,11 @@ #include #include #include -extern struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp); + +/* The name of the card. Is used for messages and in the requests for + * io regions, irqs and dma channels + */ +static const char* cardname = "netcard"; /* First, a few definitions that the brave might change. */ /* A zero-terminated list of I/O addresses to be probed. */ @@ -119,7 +130,7 @@ /* Support for a alternate probe manager, which will eliminate the boilerplate below. */ struct netdev_entry netcard_drv = -{"netcard", netcard_probe1, NETCARD_IO_EXTENT, netcard_portlist}; +{cardname, netcard_probe1, NETCARD_IO_EXTENT, netcard_portlist}; #else int netcard_probe(struct device *dev) @@ -130,7 +141,7 @@ if (base_addr > 0x1ff) /* Check a single specified location. */ return netcard_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ - return ENXIO; + return -ENXIO; for (i = 0; netcard_portlist[i]; i++) { int ioaddr = netcard_portlist[i]; @@ -140,7 +151,7 @@ return 0; } - return ENODEV; + return -ENODEV; } #endif @@ -153,23 +164,30 @@ static unsigned version_printed = 0; int i; - /* For ethernet adaptors the first three octets of the station address contains - the manufacturer's unique code. That might be a good probe method. - Ideally you would add additional checks. */ + /* For ethernet adaptors the first three octets of the station address + contains the manufacturer's unique code. That might be a good probe + method. Ideally you would add additional checks. */ if (inb(ioaddr + 0) != SA_ADDR0 || inb(ioaddr + 1) != SA_ADDR1 || inb(ioaddr + 2) != SA_ADDR2) { - return ENODEV; + return -ENODEV; } /* Allocate a new 'dev' if needed. */ - if (dev == NULL) - dev = init_etherdev(0, sizeof(struct net_local), 0); + if (dev == NULL) { + /* Don't allocate the private data here, it is done later + * This makes it easier to free the memory when this driver + * is used as a module. + */ + dev = init_etherdev(0, 0, 0); + if (dev == NULL) + return -ENOMEM; + } if (net_debug && version_printed++ == 0) - printk(version); + printk(KERN_DEBUG "%s", version); - printk("%s: %s found at %#3x, ", dev->name, "network card", ioaddr); + printk(KERN_INFO "%s: %s found at %#3x, ", dev->name, cardname, ioaddr); /* Fill in the 'dev' fields. */ dev->base_addr = ioaddr; @@ -194,26 +212,28 @@ dev->irq = autoirq_report(0); if (net_debug >= 2) printk(" autoirq is %d", dev->irq); - } else if (dev->irq == 2) - /* Fixup for users that don't know that IRQ 2 is really IRQ 9, - or don't know which one to set. */ - dev->irq = 9; - - { int irqval = request_irq(dev->irq, &net_interrupt, 0, "skeleton"); - if (irqval) { - printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, - dev->irq, irqval); - return EAGAIN; - } - } + } else if (dev->irq == 2) + /* Fixup for users that don't know that IRQ 2 is really IRQ 9, + * or don't know which one to set. + */ + dev->irq = 9; + + { + int irqval = request_irq(dev->irq, &net_interrupt, 0, cardname); + if (irqval) { + printk("%s: unable to get IRQ %d (irqval=%d).\n", + dev->name, dev->irq, irqval); + return -EAGAIN; + } + } #endif /* jumpered interrupt */ #ifdef jumpered_dma /* If we use a jumpered DMA channel, that should be probed for and allocated here as well. See lance.c for an example. */ if (dev->dma == 0) { - if (request_dma(dev->dma, "netcard")) { + if (request_dma(dev->dma, cardname)) { printk("DMA %d allocation failed.\n", dev->dma); - return EAGAIN; + return -EAGAIN; } else printk(", assigned DMA %d.\n", dev->dma); } else { @@ -231,29 +251,33 @@ new_dma_status ^= dma_status; new_dma_status &= ~0x10; for (i = 7; i > 0; i--) - if (test_bit(new_dma, &new_dma_status)) { + if (test_bit(i, &new_dma_status)) { dev->dma = i; break; } if (i <= 0) { printk("DMA probe failed.\n"); - return EAGAIN; + return -EAGAIN; } - if (request_dma(dev->dma, "netcard")) { + if (request_dma(dev->dma, cardname)) { printk("probed DMA %d allocation failed.\n", dev->dma); - return EAGAIN; + return -EAGAIN; } } #endif /* jumpered DMA */ - /* Grab the region so we can find another board if autoIRQ fails. */ - request_region(ioaddr, NETCARD_IO_EXTENT,"skeleton"); - /* Initialize the device structure. */ - if (dev->priv == NULL) + if (dev->priv == NULL) { dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; + } + memset(dev->priv, 0, sizeof(struct net_local)); + /* Grab the region so that no one else tries to probe our ioports. */ + request_region(ioaddr, NETCARD_IO_EXTENT, cardname); + dev->open = net_open; dev->stop = net_close; dev->hard_start_xmit = net_send_packet; @@ -282,12 +306,12 @@ /* This is used if the interrupt line can turned off (shared). See 3c503.c for an example of selecting the IRQ at config-time. */ - if (request_irq(dev->irq, &net_interrupt, 0, "skeleton")) { + if (request_irq(dev->irq, &net_interrupt, 0, cardname)) { return -EAGAIN; } /* Always snarf the DMA channel after the IRQ, and clean up on failure. */ - if (request_dma(dev->dma,"skeleton ethernet")) { + if (request_dma(dev->dma, cardname)) { free_irq(dev->irq); return -EAGAIN; } @@ -301,6 +325,9 @@ dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; + + MOD_INC_USE_COUNT; + return 0; } @@ -316,7 +343,7 @@ int tickssofar = jiffies - dev->trans_start; if (tickssofar < 5) return 1; - printk("%s: transmit timed out, %s?\n", dev->name, + printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, tx_done(dev) ? "IRQ conflict" : "network cable problem"); /* Try to restart the adaptor. */ chipset_init(dev, 1); @@ -335,7 +362,7 @@ /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (set_bit(0, (void*)&dev->tbusy) != 0) - printk("%s: Transmitter access conflict.\n", dev->name); + printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name); else { short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; @@ -362,7 +389,7 @@ int ioaddr, status, boguscount = 0; if (dev == NULL) { - printk ("net_interrupt(): irq %d for unknown device.\n", irq); + printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq); return; } dev->interrupt = 1; @@ -418,7 +445,8 @@ skb = dev_alloc_skb(pkt_len); if (skb == NULL) { - printk("%s: Memory squeeze, dropping packet.\n", dev->name); + printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", + dev->name); lp->stats.rx_dropped++; break; } @@ -467,6 +495,8 @@ /* Update the statistics here. */ + MOD_DEC_USE_COUNT; + return 0; } @@ -503,11 +533,70 @@ outw(99, ioaddr); /* Disable promiscuous mode, use normal mode */ } +#ifdef MODULE + +char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; +static struct device this_device = { + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, /* I/O address, IRQ */ + 0, 0, 0, NULL, netcard_probe }; + +int io = 0x300; +int irq = 0; +int dma = 0; +int mem = 0; + +int init_module(void) +{ + int result; + + if (io == 0) + printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n", + cardname); + + /* copy the parameters from insmod into the device structure */ + this_device.base_addr = io; + this_device.irq = irq; + this_device.dma = dma; + this_device.mem_start = mem; + + if ((result = register_netdev(&this_device)) != 0) + return result; + + return 0; +} + +void +cleanup_module(void) +{ + /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ + + unregister_netdev(&this_device); + + /* If we don't do this, we can't re-insmod it later. */ + /* Release irq/dma here, when you have jumpered versions and snarfed + * them in net_probe1(). + */ + /* + free_irq(this_device.irq); + free_dma(this_device.dma); + */ + release_region(this_device.base_addr, NETCARD_IO_EXTENT); + + if (this_device.priv) + kfree_s(this_device.priv, sizeof(struct net_local)); +} + +#endif /* MODULE */ + /* * Local variables: - * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c" + * compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -Wwrite-strings -Wredundant-decls -O2 -m486 -c skeleton.c" * version-control: t * kept-new-versions: 5 * tab-width: 4 + * c-indent-level: 4 * End: */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c --- v1.3.18/linux/drivers/net/smc-ultra.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/smc-ultra.c Tue Aug 15 18:08:33 1995 @@ -54,9 +54,8 @@ #include #include +#include #include "8390.h" -extern struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp); /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int ultra_portlist[] = @@ -325,8 +324,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_ultra = { - " " /*"smc-ultra"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, ultra_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, ultra_probe }; int io = 0x200; int irq = 0; @@ -334,7 +337,7 @@ int init_module(void) { if (io == 0) - printk("smc-ultra: You should not use auto-probing with insmod!\n"); + printk("smc-ultra: You should not use auto-probing with insmod!\n"); dev_ultra.base_addr = io; dev_ultra.irq = irq; if (register_netdev(&dev_ultra) != 0) { @@ -351,7 +354,12 @@ printk("smc-ultra: device busy, remove delayed\n"); else { + int ioaddr = dev_ultra.base_addr - ULTRA_NIC_OFFSET; + unregister_netdev(&dev_ultra); + + /* If we don't do this, we can't re-insmod it later. */ + release_region(ioaddr, ULTRA_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/tulip.c linux/drivers/net/tulip.c --- v1.3.18/linux/drivers/net/tulip.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/tulip.c Tue Aug 15 18:08:33 1995 @@ -745,8 +745,13 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_tulip = { - " " /*"tulip"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, tulip_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, tulip_probe +}; int io = 0; int irq = 0; diff -u --recursive --new-file v1.3.18/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c --- v1.3.18/linux/drivers/net/wavelan.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/wavelan.c Tue Aug 15 18:52:14 1995 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -838,9 +839,12 @@ { if (wavelan_debug > 0) printk("%s: <-wavelan_probe(): 0\n", dev->name); - proc_net_register(&(struct proc_dir_entry) - { PROC_NET_WAVELAN, 7, "wavelan", - wavelan_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_WAVELAN, 7, "wavelan", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + wavelan_get_info + }); return 0; } @@ -2170,10 +2174,13 @@ #if defined(MODULE) char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_wavelan = { - " " /* "wavelan" */, - 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, wavelan_probe + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, wavelan_probe }; int io = 0x390; /* Default from above.. */ diff -u --recursive --new-file v1.3.18/linux/drivers/net/wd.c linux/drivers/net/wd.c --- v1.3.18/linux/drivers/net/wd.c Sun Aug 13 14:45:32 1995 +++ linux/drivers/net/wd.c Tue Aug 15 18:08:34 1995 @@ -33,9 +33,8 @@ #include #include +#include #include "8390.h" -extern struct device *init_etherdev(struct device *dev, int sizeof_private, - unsigned long *mem_startp); /* A zero-terminated list of I/O addresses to be probed. */ static unsigned int wd_portlist[] = @@ -397,8 +396,12 @@ #ifdef MODULE char kernel_version[] = UTS_RELEASE; +static char devicename[9] = { 0, }; static struct device dev_wd80x3 = { - " " /*"wd80x3"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, wd_probe }; + devicename, /* device name is inserted by linux/drivers/net/net_init.c */ + 0, 0, 0, 0, + 0, 0, + 0, 0, 0, NULL, wd_probe }; int io = 0x300; int irq = 0; @@ -407,7 +410,7 @@ int init_module(void) { if (io == 0) - printk("wd: You should not use auto-probing with insmod!\n"); + printk("wd: You should not use auto-probing with insmod!\n"); dev_wd80x3.base_addr = io; dev_wd80x3.irq = irq; dev_wd80x3.mem_start = mem; @@ -425,10 +428,11 @@ { int ioaddr = dev_wd80x3.base_addr - WD_NIC_OFFSET; - free_irq(dev_wd80x3.irq); - release_region(ioaddr, WD_IO_EXTENT); - unregister_netdev(&dev_wd80x3); + + /* If we don't do this, we can't re-insmod it later. */ + free_irq(dev_wd80x3.irq); + release_region(ioaddr, WD_IO_EXTENT); } } #endif /* MODULE */ diff -u --recursive --new-file v1.3.18/linux/drivers/pci/Makefile linux/drivers/pci/Makefile --- v1.3.18/linux/drivers/pci/Makefile Tue Jul 11 10:02:50 1995 +++ linux/drivers/pci/Makefile Tue Aug 15 15:07:02 1995 @@ -9,24 +9,7 @@ # parent makefile. # -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - -OBJS := pci.o -SRCS := pci.c - -all: pci.a - -pci.a: $(OBJS) - rm -f pci.a - $(AR) rcs pci.a $(OBJS) - sync - -dep: - $(CPP) -M $(SRCS) > .depend - -modules: +L_OBJS := pci.o +L_TARGET := pci.a include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v1.3.18/linux/drivers/pci/pci.c Wed Aug 9 14:55:41 1995 +++ linux/drivers/pci/pci.c Sun Aug 13 20:19:10 1995 @@ -714,6 +714,7 @@ if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI) { unsigned int buses; + unsigned short cr; /* * Insert it into the tree of buses. @@ -735,6 +736,8 @@ * Clear all status bits and turn off memory, * I/O and master enables. */ + pcibios_read_config_word(bus->number, devfn, + PCI_COMMAND, &cr); pcibios_write_config_word(bus->number, devfn, PCI_COMMAND, 0x0000); pcibios_write_config_word(bus->number, devfn, @@ -763,6 +766,8 @@ | ((unsigned int)(child->subordinate) << 16); pcibios_write_config_dword(bus->number, devfn, 0x18, buses); + pcibios_write_config_word(bus->number, devfn, + PCI_COMMAND, cr); } } /* diff -u --recursive --new-file v1.3.18/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile --- v1.3.18/linux/drivers/scsi/Makefile Tue Jul 25 18:21:22 1995 +++ linux/drivers/scsi/Makefile Tue Aug 15 15:07:02 1995 @@ -6,16 +6,17 @@ # unless it's something special (ie not a .c file). # -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - ifdef CONFIG_KERNEL_ELF # This is used for ELF - it needs to migrate or be moved. LD_RFLAG = -m elf_i386 endif +L_TARGET := scsi.a +L_OBJS := +M_OBJS := +MOD_LIST_NAME := SCSI_MODULES +SCSI_SRCS = $(wildcard $(L_OBJS:%.o=%.c)) + AHA152X = -DDEBUG_AHA152X -DAUTOCONF -DSKIP_BIOSTEST -DIRQ=11 ifeq (${CFLAGS},) @@ -25,8 +26,6 @@ include ../../.config -.EXPORT_ALL_VARIABLES: - SYMTAB_OBJS = scsi_syms.o TOPDIR = ../.. @@ -34,195 +33,159 @@ endif -SCSI_OBJS = -SCSI_SRCS = -SCSI_DEP = -SCSI_MODULE_OBJS = - -SCSI_SRCS := hosts.c scsi.c scsi_ioctl.c constants.c scsicam.c scsi_proc.c - ifdef CONFIG_SCSI -SCSI_OBJS := hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o scsi_proc.o +L_OBJS := hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o scsi_proc.o else ifdef CONFIG_MODVERSIONS # Create this before we build anything else. SCSI_MODULE_VER := scsi_syms.ver endif -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) scsi_mod.o +M_OBJS += scsi_mod.o endif -SCSI_SRCS := $(SCSI_SRCS) st.c ifdef CONFIG_CHR_DEV_ST -SCSI_OBJS := $(SCSI_OBJS) st.o +L_OBJS += st.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) st.o +M_OBJS += st.o endif -SCSI_SRCS := $(SCSI_SRCS) sd.c sd_ioctl.c ifdef CONFIG_BLK_DEV_SD -SCSI_OBJS := $(SCSI_OBJS) sd.o sd_ioctl.o +L_OBJS += sd.o sd_ioctl.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) sd_mod.o +M_OBJS += sd_mod.o endif -SCSI_SRCS := $(SCSI_SRCS) sr.c sr_ioctl.c ifdef CONFIG_BLK_DEV_SR -SCSI_OBJS := $(SCSI_OBJS) sr.o sr_ioctl.o +L_OBJS += sr.o sr_ioctl.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) sr_mod.o +M_OBJS += sr_mod.o endif -SCSI_SRCS := $(SCSI_SRCS) sg.c ifdef CONFIG_CHR_DEV_SG -SCSI_OBJS := $(SCSI_OBJS) sg.o +L_OBJS += sg.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) sg.o +M_OBJS += sg.o endif -SCSI_SRCS := $(SCSI_SRCS) qlogic.c ifdef CONFIG_SCSI_QLOGIC -SCSI_OBJS := $(SCSI_OBJS) qlogic.o +L_OBJS += qlogic.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) qlogic.o +M_OBJS += qlogic.o endif -SCSI_SRCS := $(SCSI_SRCS) aha152x.c ifdef CONFIG_SCSI_AHA152X -SCSI_OBJS := $(SCSI_OBJS) aha152x.o +L_OBJS += aha152x.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) aha152x.o +M_OBJS += aha152x.o endif -SCSI_SRCS := $(SCSI_SRCS) aha1542.c ifdef CONFIG_SCSI_AHA1542 -SCSI_OBJS := $(SCSI_OBJS) aha1542.o +L_OBJS += aha1542.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) aha1542.o +M_OBJS += aha1542.o endif -SCSI_SRCS := $(SCSI_SRCS) aha1740.c ifdef CONFIG_SCSI_AHA1740 -SCSI_OBJS := $(SCSI_OBJS) aha1740.o +L_OBJS += aha1740.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) aha1740.o +M_OBJS += aha1740.o endif -SCSI_SRCS := $(SCSI_SRCS) aic7xxx.c -SCSI_DEP := $(SCSI_DEP) aic7xxx_seq.h ifdef CONFIG_SCSI_AIC7XXX -SCSI_OBJS := $(SCSI_OBJS) aic7xxx.o +L_OBJS += aic7xxx.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) aic7xxx.o +M_OBJS += aic7xxx.o endif -SCSI_SRCS := $(SCSI_SRCS) buslogic.c ifdef CONFIG_SCSI_BUSLOGIC -SCSI_OBJS := $(SCSI_OBJS) buslogic.o +L_OBJS += buslogic.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) buslogic.o +M_OBJS += buslogic.o endif -SCSI_SRCS := $(SCSI_SRCS) eata_dma.c ifdef CONFIG_SCSI_EATA_DMA -SCSI_OBJS := $(SCSI_OBJS) eata_dma.o +L_OBJS += eata_dma.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) eata_dma.o +M_OBJS += eata_dma.o endif -SCSI_SRCS := $(SCSI_SRCS) eata_pio.c ifdef CONFIG_SCSI_EATA_PIO -SCSI_OBJS := $(SCSI_OBJS) eata_pio.o +L_OBJS += eata_pio.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) eata_pio.o +M_OBJS += eata_pio.o endif -SCSI_SRCS := $(SCSI_SRCS) u14-34f.c ifdef CONFIG_SCSI_U14_34F -SCSI_OBJS := $(SCSI_OBJS) u14-34f.o +L_OBJS += u14-34f.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) u14-34f.o +M_OBJS += u14-34f.o endif -SCSI_SRCS := $(SCSI_SRCS) scsi_debug.c ifdef CONFIG_SCSI_DEBUG -SCSI_OBJS := $(SCSI_OBJS) scsi_debug.o +L_OBJS += scsi_debug.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) scsi_debug.o +M_OBJS += scsi_debug.o endif -SCSI_SRCS := $(SCSI_SRCS) fdomain.c ifdef CONFIG_SCSI_FUTURE_DOMAIN -SCSI_OBJS := $(SCSI_OBJS) fdomain.o +L_OBJS += fdomain.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) fdomain.o +M_OBJS += fdomain.o endif -SCSI_SRCS := $(SCSI_SRCS) in2000.c ifdef CONFIG_SCSI_IN2000 -SCSI_OBJS := $(SCSI_OBJS) in2000.o +L_OBJS += in2000.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) in2000.o +M_OBJS += in2000.o endif -SCSI_SRCS := $(SCSI_SRCS) g_NCR5380.c ifdef CONFIG_SCSI_GENERIC_NCR5380 -SCSI_OBJS := $(SCSI_OBJS) g_NCR5380.o +L_OBJS += g_NCR5380.o endif -SCSI_SRCS := $(SCSI_SRCS) 53c7,8xx.c ifdef CONFIG_SCSI_NCR53C7xx -SCSI_OBJS := $(SCSI_OBJS) 53c7,8xx.o +L_OBJS += 53c7,8xx.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) 53c7,8xx.o +M_OBJS += 53c7,8xx.o endif -SCSI_SRCS := $(SCSI_SRCS) pas16.c ifdef CONFIG_SCSI_PAS16 -SCSI_OBJS := $(SCSI_OBJS) pas16.o +L_OBJS += pas16.o endif -SCSI_SRCS := $(SCSI_SRCS) seagate.c ifdef CONFIG_SCSI_SEAGATE -SCSI_OBJS := $(SCSI_OBJS) seagate.o +L_OBJS += seagate.o else ifdef CONFIG_SCSI_FD_8xx -SCSI_OBJS := $(SCSI_OBJS) seagate.o +L_OBJS += seagate.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) seagate.o +M_OBJS += seagate.o endif endif -SCSI_SRCS := $(SCSI_SRCS) wd7000.c ifdef CONFIG_SCSI_7000FASST -SCSI_OBJS := $(SCSI_OBJS) wd7000.o +L_OBJS += wd7000.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) wd7000.o +M_OBJS += wd7000.o endif -SCSI_SRCS := $(SCSI_SRCS) t128.c ifdef CONFIG_SCSI_T128 -SCSI_OBJS := $(SCSI_OBJS) t128.o +L_OBJS += t128.o endif -SCSI_SRCS := $(SCSI_SRCS) ultrastor.c ifdef CONFIG_SCSI_ULTRASTOR -SCSI_OBJS := $(SCSI_OBJS) ultrastor.o +L_OBJS += ultrastor.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) ultrastor.o +M_OBJS += ultrastor.o endif -SCSI_SRCS := $(SCSI_SRCS) eata.c ifdef CONFIG_SCSI_EATA -SCSI_OBJS := $(SCSI_OBJS) eata.o +L_OBJS += eata.o else -SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) eata.o +M_OBJS += eata.o endif - -scsi.a: $(SCSI_OBJS) - rm -f scsi.a - $(AR) rcs scsi.a $(SCSI_OBJS) - sync +include $(TOPDIR)/Rules.make aha152x.o: aha152x.c $(CC) $(CFLAGS) $(AHA152X) -c aha152x.c @@ -230,6 +193,7 @@ aic7xxx_asm: aic7xxx_asm.c $(CC) $(CFLAGS) -o $@ aic7xxx_asm.c +aic7xxx.c: aic7xxx_seq.h aic7xxx_seq.h: aic7xxx_asm aic7xxx.seq ./aic7xxx_asm -o $@ aic7xxx.seq @@ -259,15 +223,4 @@ $(SYMTAB_OBJS): $(SYMTAB_OBJS:.o=.c) -modules: $(SCSI_MODULE_VER) $(SCSI_MODULE_OBJS) - echo $(SCSI_MODULE_OBJS) > ../../modules/SCSI_MODULES - (cd ../../modules;for i in $(SCSI_MODULE_OBJS); do ln -sf ../drivers/scsi/$$i .; done) - -dep: $(SCSI_DEP) - $(CPP) -M $(AHA152X) constants.c $(SCSI_OBJS:.o=.c) > .depend - $(CPP) -M -DMODULE $(patsubst scsi_mod.c,scsi.c hosts.c scsi_ioctl.c \ - constants.c scsicam.c scsi_proc.c, \ - $(patsubst sd_mod.c,sd.c sd_ioctl.c, \ - $(patsubst sr_mod.c,sr.c sr_ioctl.c, $(SCSI_MODULE_OBJS:.o=.c)))) >> .depend - -include $(TOPDIR)/Rules.make +modules: $(SCSI_MODULE_VER) diff -u --recursive --new-file v1.3.18/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- v1.3.18/linux/drivers/scsi/sd.c Tue Jul 11 10:02:51 1995 +++ linux/drivers/scsi/sd.c Sun Aug 13 20:19:12 1995 @@ -149,7 +149,7 @@ } } -static void sd_geninit(void); +static void sd_geninit(struct gendisk *); static struct file_operations sd_fops = { NULL, /* lseek - default */ @@ -181,7 +181,7 @@ NULL /* next */ }; -static void sd_geninit (void) +static void sd_geninit (struct gendisk *ignored) { int i; diff -u --recursive --new-file v1.3.18/linux/drivers/sound/Makefile linux/drivers/sound/Makefile --- v1.3.18/linux/drivers/sound/Makefile Tue Jul 11 10:02:51 1995 +++ linux/drivers/sound/Makefile Tue Aug 15 15:07:02 1995 @@ -9,11 +9,6 @@ TARGET_OS = linux USRINCDIR = /usr/include -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - OBJS = soundcard.o audio.o dmabuf.o sb_dsp.o dev_table.o \ opl3.o sequencer.o midibuf.o sb_card.o pas2_card.o adlib_card.o \ pas2_pcm.o pas2_mixer.o pas2_midi.o gus_card.o gus_wave.o mpu401.o \ diff -u --recursive --new-file v1.3.18/linux/fs/Makefile linux/fs/Makefile --- v1.3.18/linux/fs/Makefile Tue Jul 11 10:02:55 1995 +++ linux/fs/Makefile Tue Aug 15 15:07:02 1995 @@ -7,109 +7,85 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -SUBDIRS = minix ext ext2 msdos proc isofs nfs xiafs umsdos hpfs sysv smbfs +L_TARGET := filesystems.a +L_OBJS = $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o)) +O_TARGET := fs.o +O_OBJS = open.o read_write.o inode.o devices.o file_table.o buffer.o \ + super.o block_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ + ioctl.o readdir.o select.o fifo.o locks.o filesystems.o \ + dcache.o $(BINFMTS) + +MOD_LIST_NAME := FS_MODULES +ALL_SUB_DIRS = minix ext ext2 msdos proc isofs nfs xiafs umsdos hpfs sysv smbfs ifdef CONFIG_MINIX_FS -FS_SUBDIRS := $(FS_SUBDIRS) minix +SUB_DIRS += minix else -MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) minix +MOD_SUB_DIRS += minix endif ifdef CONFIG_EXT_FS -FS_SUBDIRS := $(FS_SUBDIRS) ext +SUB_DIRS += ext endif ifdef CONFIG_EXT2_FS -FS_SUBDIRS := $(FS_SUBDIRS) ext2 +SUB_DIRS += ext2 endif ifdef CONFIG_MSDOS_FS -FS_SUBDIRS := $(FS_SUBDIRS) msdos +SUB_DIRS += msdos else -MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) msdos +MOD_SUB_DIRS += msdos endif ifdef CONFIG_PROC_FS -FS_SUBDIRS := $(FS_SUBDIRS) proc +SUB_DIRS += proc endif ifdef CONFIG_ISO9660_FS -FS_SUBDIRS := $(FS_SUBDIRS) isofs +SUB_DIRS += isofs else -MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) isofs +MOD_SUB_DIRS += isofs endif ifdef CONFIG_NFS_FS -FS_SUBDIRS := $(FS_SUBDIRS) nfs +SUB_DIRS += nfs else -MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) nfs +MOD_SUB_DIRS += nfs endif ifdef CONFIG_XIA_FS -FS_SUBDIRS := $(FS_SUBDIRS) xiafs +SUB_DIRS += xiafs else -MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) xiafs +MOD_SUB_DIRS += xiafs endif ifdef CONFIG_UMSDOS_FS -FS_SUBDIRS := $(FS_SUBDIRS) umsdos +SUB_DIRS += umsdos else -MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) umsdos +MOD_SUB_DIRS += umsdos endif ifdef CONFIG_SYSV_FS -FS_SUBDIRS := $(FS_SUBDIRS) sysv +SUB_DIRS += sysv else -MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) sysv +MOD_SUB_DIRS += sysv endif ifdef CONFIG_SMB_FS -FS_SUBDIRS := $(FS_SUBDIRS) smbfs +SUB_DIRS += smbfs else -MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) smbfs +MOD_SUB_DIRS += smbfs endif ifdef CONFIG_HPFS_FS -FS_SUBDIRS := $(FS_SUBDIRS) hpfs +SUB_DIRS += hpfs endif ifdef CONFIG_BINFMT_ELF -BINFMTS := $(BINFMTS) binfmt_elf.o +BINFMTS += binfmt_elf.o else -MODULE_OBJS := $(MODULE_OBJS) binfmt_elf.o +MOD_SUB_DIRS += binfmt_elf.o endif - -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \ - block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o readdir.o \ - select.o fifo.o locks.o filesystems.o dcache.o $(BINFMTS) - -all: fs.o filesystems.a - -fs.o: $(OBJS) - $(LD) -r -o fs.o $(OBJS) - -filesystems.a: dummy - rm -f filesystems.a - set -e; for i in $(FS_SUBDIRS); do \ - test ! -d $$i || \ - { $(MAKE) -C $$i; $(AR) rcs filesystems.a $$i/$$i.o; }; done - -modules: $(MODULE_OBJS) - for i in $(MODULE_FS_SUBDIRS); do $(MAKE) -C $$i modules; done - cd ../modules;for i in $(MODULE_OBJS); do ln -sf ../fs/$$i .; done - cd ../modules;for i in $(MODULE_FS_SUBDIRS); \ - do echo $$i.o; ln -sf ../fs/$$i/$$i.o .; done > ../modules/FS_MODULES - -depend dep: - $(CPP) -M *.c > .depend - set -e; for i in $(FS_SUBDIRS); do \ - test ! -d $$i || $(MAKE) -C $$i dep; done - set -e; for i in $(MODULE_FS_SUBDIRS); do \ - test ! -d $$i || $(MAKE) -C $$i CFLAGS="$(CFLAGS) -DMODULE" dep; done include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/ext/Makefile linux/fs/ext/Makefile --- v1.3.18/linux/fs/ext/Makefile Tue Jul 11 10:02:55 1995 +++ linux/fs/ext/Makefile Tue Aug 15 15:07:02 1995 @@ -7,18 +7,9 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= freelists.o truncate.o namei.o inode.o \ - file.o dir.o symlink.o fsync.o - -ext.o: $(OBJS) - $(LD) -r -o ext.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend +O_TARGET := ext.o +O_OBJS := freelists.o truncate.o namei.o inode.o file.o dir.o \ + symlink.o fsync.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/ext2/Makefile linux/fs/ext2/Makefile --- v1.3.18/linux/fs/ext2/Makefile Tue Jul 11 10:02:57 1995 +++ linux/fs/ext2/Makefile Tue Aug 15 15:07:02 1995 @@ -7,18 +7,9 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= acl.o balloc.o bitmap.o dir.o file.o fsync.o ialloc.o \ - inode.o ioctl.o namei.o super.o symlink.o truncate.o - -ext2.o: $(OBJS) - $(LD) -r -o ext2.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend +O_TARGET := ext2.o +O_OBJS := acl.o balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ + ioctl.o namei.o super.o symlink.o truncate.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/ext2/dir.c linux/fs/ext2/dir.c --- v1.3.18/linux/fs/ext2/dir.c Wed Aug 2 13:21:15 1995 +++ linux/fs/ext2/dir.c Tue Aug 15 15:50:08 1995 @@ -104,7 +104,7 @@ struct buffer_head * bh, * tmp, * bha[16]; struct ext2_dir_entry * de; struct super_block * sb; - int err, version; + int err; if (!inode || !S_ISDIR(inode->i_mode)) return -EBADF; @@ -189,6 +189,8 @@ * version stamp to detect whether or * not the directory has been modified * during the copy operation. */ + unsigned long version; + dcache_add(inode, de->name, de->name_len, de->inode); version = inode->i_version; error = filldir(dirent, de->name, de->name_len, filp->f_pos, de->inode); if (error) diff -u --recursive --new-file v1.3.18/linux/fs/hpfs/Makefile linux/fs/hpfs/Makefile --- v1.3.18/linux/fs/hpfs/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/hpfs/Makefile Tue Aug 15 15:07:02 1995 @@ -7,17 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= hpfs_fs.o hpfs_caps.o - -hpfs.o: $(OBJS) - $(LD) -r -o hpfs.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend +O_TARGET := hpfs.o +O_OBJS := hpfs_fs.o hpfs_caps.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/isofs/Makefile linux/fs/isofs/Makefile --- v1.3.18/linux/fs/isofs/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/isofs/Makefile Tue Aug 15 15:07:02 1995 @@ -7,20 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= namei.o inode.o file.o dir.o util.o rock.o symlink.o - -isofs.o: $(OBJS) - $(LD) -r -o isofs.o $(OBJS) - -modules: isofs.o - ln -sf ../fs/isofs/isofs.o $(TOPDIR)/modules - -dep: - $(CPP) -M *.c > .depend +O_TARGET := isofs.o +O_OBJS := namei.o inode.o file.o dir.o util.o rock.o symlink.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/minix/Makefile linux/fs/minix/Makefile --- v1.3.18/linux/fs/minix/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/minix/Makefile Tue Aug 15 15:07:02 1995 @@ -7,20 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= bitmap.o truncate.o namei.o inode.o \ - file.o dir.o symlink.o fsync.o - -minix.o: $(OBJS) - $(LD) -r -o minix.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend - -modules: minix.o +O_TARGET := minix.o +O_OBJS := bitmap.o truncate.o namei.o inode.o file.o dir.o symlink.o fsync.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/msdos/Makefile linux/fs/msdos/Makefile --- v1.3.18/linux/fs/msdos/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/msdos/Makefile Tue Aug 15 15:07:02 1995 @@ -7,20 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= buffer.o namei.o inode.o file.o dir.o misc.o fat.o mmap.o - -msdos.o: $(OBJS) - $(LD) -r -o msdos.o $(OBJS) - -modules: msdos.o - ln -sf ../fs/msdos/msdos.o $(TOPDIR)/modules - -dep: - $(CPP) -M *.c > .depend +O_TARGET := msdos.o +O_OBJS := buffer.o namei.o inode.o file.o dir.o misc.o fat.o mmap.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/nfs/Makefile linux/fs/nfs/Makefile --- v1.3.18/linux/fs/nfs/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/nfs/Makefile Tue Aug 15 15:07:02 1995 @@ -7,20 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= proc.o sock.o inode.o file.o dir.o \ - symlink.o mmap.o - -nfs.o: $(OBJS) - $(LD) -r -o nfs.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend - -modules: nfs.o +O_TARGET := nfs.o +O_OBJS := proc.o sock.o inode.o file.o dir.o symlink.o mmap.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/proc/Makefile linux/fs/proc/Makefile --- v1.3.18/linux/fs/proc/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/proc/Makefile Tue Aug 15 15:07:02 1995 @@ -7,17 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= inode.o root.o base.o mem.o link.o fd.o array.o kmsg.o net.o scsi.o - -proc.o: $(OBJS) - $(LD) -r -o proc.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend +O_TARGET := proc.o +O_OBJS := inode.o root.o base.o mem.o link.o fd.o array.o kmsg.o net.o scsi.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/proc/base.c linux/fs/proc/base.c --- v1.3.18/linux/fs/proc/base.c Sun Aug 13 14:45:34 1995 +++ linux/fs/proc/base.c Tue Aug 15 14:40:41 1995 @@ -13,14 +13,11 @@ #include #include -static int proc_readbase(struct inode *, struct file *, void *, filldir_t); -static int proc_lookupbase(struct inode *,const char *,int,struct inode **); - static struct file_operations proc_base_operations = { NULL, /* lseek - default */ NULL, /* read - bad */ NULL, /* write - bad */ - proc_readbase, /* readdir */ + proc_readdir, /* readdir */ NULL, /* select - default */ NULL, /* ioctl - default */ NULL, /* mmap */ @@ -32,10 +29,10 @@ /* * proc directories can do almost nothing.. */ -struct inode_operations proc_base_inode_operations = { +static struct inode_operations proc_base_inode_operations = { &proc_base_operations, /* default base directory file-ops */ NULL, /* create */ - proc_lookupbase, /* lookup */ + proc_lookup, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ @@ -50,105 +47,97 @@ NULL /* permission */ }; -static struct proc_dir_entry base_dir[] = { - { PROC_PID_INO, 1, "." }, - { PROC_ROOT_INO, 2, ".." }, - { PROC_PID_MEM, 3, "mem" }, - { PROC_PID_CWD, 3, "cwd" }, - { PROC_PID_ROOT, 4, "root" }, - { PROC_PID_EXE, 3, "exe" }, - { PROC_PID_FD, 2, "fd" }, - { PROC_PID_ENVIRON, 7, "environ" }, - { PROC_PID_CMDLINE, 7, "cmdline" }, - { PROC_PID_STAT, 4, "stat" }, - { PROC_PID_STATM, 5, "statm" }, - { PROC_PID_MAPS, 4, "maps" } -}; - -#define NR_BASE_DIRENTRY ((sizeof (base_dir))/(sizeof (base_dir[0]))) - -int proc_match(int len,const char * name,struct proc_dir_entry * de) -{ - if (!de || !de->low_ino) - return 0; - /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ - if (!len && (de->name[0]=='.') && (de->name[1]=='\0')) - return 1; - if (de->namelen != len) - return 0; - return !memcmp(name, de->name, len); -} - -static int proc_lookupbase(struct inode * dir,const char * name, int len, - struct inode ** result) +static void proc_pid_fill_inode(struct inode * inode) { - struct proc_dir_entry * de = NULL; - unsigned int pid, ino; - int i; - - *result = NULL; - if (!dir) - return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return -ENOENT; - } - ino = dir->i_ino; - pid = ino >> 16; - for (i = 0; i < NR_BASE_DIRENTRY; i++) { - if (!proc_match(len, name, base_dir+i)) - continue; - de = base_dir+i; - break; - } - if (!de) { - iput(dir); - return -ENOENT; + struct task_struct * p; + int pid = inode->i_ino >> 16; + int ino = inode->i_ino & 0xffff; + + for_each_task(p) { + if (p->pid == pid) { + if (p->dumpable || ino == PROC_PID_INO) { + inode->i_uid = p->euid; + inode->i_gid = p->gid; + } + return; + } } - if (de->low_ino == 1) - ino = 1; - else - ino = (pid << 16) + de->low_ino; - for (i = 0 ; i < NR_TASKS ; i++) - if (task[i] && task[i]->pid == pid) - break; - if (!pid || i >= NR_TASKS) { - iput(dir); - return -ENOENT; - } - if (!(*result = iget(dir->i_sb,ino))) { - iput(dir); - return -ENOENT; - } - iput(dir); - (*result)->u.generic_ip = de; - return 0; } -static int proc_readbase(struct inode * inode, struct file * filp, - void * dirent, filldir_t filldir) -{ - struct proc_dir_entry * de; - unsigned int pid, ino; - int i; +/* + * This is really a pseudo-entry, and only links + * backwards to the parent with no link from the + * root directory to this. This way we can have just + * one entry for every /proc// directory. + */ +struct proc_dir_entry proc_pid = { + PROC_PID_INO, 5, "", + S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, + 0, &proc_base_inode_operations, + NULL, proc_pid_fill_inode, + NULL, &proc_root, NULL +}; - if (!inode || !S_ISDIR(inode->i_mode)) - return -EBADF; - ino = inode->i_ino; - pid = ino >> 16; - for (i = 0 ; i < NR_TASKS ; i++) - if (task[i] && task[i]->pid == pid) - break; - if (!pid || i >= NR_TASKS) - return 0; - while (((unsigned) filp->f_pos) < NR_BASE_DIRENTRY) { - de = base_dir + filp->f_pos; - ino = de->low_ino; - if (ino != 1) - ino |= (pid << 16); - if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino) < 0) - break; - filp->f_pos++; - } - return 0; -} +void proc_base_init(void) +{ + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_MEM, 3, "mem", + S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0, + 0, &proc_mem_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_CWD, 3, "cwd", + S_IFLNK | S_IRWXU, 1, 0, 0, + 0, &proc_link_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_ROOT, 4, "root", + S_IFLNK | S_IRWXU, 1, 0, 0, + 0, &proc_link_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_EXE, 3, "exe", + S_IFLNK | S_IRWXU, 1, 0, 0, + 0, &proc_link_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_FD, 2, "fd", + S_IFDIR | S_IRUSR | S_IXUSR, 1, 0, 0, + 0, &proc_fd_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_ENVIRON, 7, "environ", + S_IFREG | S_IRUSR, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_CMDLINE, 7, "cmdline", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_STAT, 4, "stat", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_STATM, 5, "statm", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_array_inode_operations, + NULL, proc_pid_fill_inode, + }); + proc_register(&proc_pid, &(struct proc_dir_entry) { + PROC_PID_MAPS, 4, "maps", + S_IFIFO | S_IRUGO, 1, 0, 0, + 0, &proc_arraylong_inode_operations, + NULL, proc_pid_fill_inode, + }); +}; diff -u --recursive --new-file v1.3.18/linux/fs/proc/fd.c linux/fs/proc/fd.c --- v1.3.18/linux/fs/proc/fd.c Thu Jun 8 20:06:10 1995 +++ linux/fs/proc/fd.c Tue Aug 15 10:52:03 1995 @@ -75,7 +75,7 @@ *result = dir; return 0; } - if (!(*result = iget(sb,(pid << 16)+PROC_PID_INO))) { + if (!(*result = proc_get_inode(sb, (pid << 16)+PROC_PID_INO, &proc_pid))) { iput(dir); return -ENOENT; } @@ -109,7 +109,7 @@ ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd; - if (!(*result = iget(sb,ino))) + if (!(*result = proc_get_inode(sb, ino, NULL))) return -ENOENT; return 0; } diff -u --recursive --new-file v1.3.18/linux/fs/proc/inode.c linux/fs/proc/inode.c --- v1.3.18/linux/fs/proc/inode.c Sun Aug 13 14:45:34 1995 +++ linux/fs/proc/inode.c Tue Aug 15 14:47:50 1995 @@ -18,16 +18,15 @@ #include extern unsigned long prof_len; -extern void proc_net_init(void); -void proc_put_inode(struct inode *inode) +static void proc_put_inode(struct inode *inode) { if (inode->i_nlink) return; inode->i_size = 0; } -void proc_put_super(struct super_block *sb) +static void proc_put_super(struct super_block *sb) { lock_super(sb); sb->s_dev = 0; @@ -75,23 +74,46 @@ return 1; } +struct inode * proc_get_inode(struct super_block * s, int ino, struct proc_dir_entry * de) +{ + struct inode * inode = iget(s, ino); + if (inode) { + inode->u.generic_ip = (void *) de; + if (de) { + if (de->mode) { + inode->i_mode = de->mode; + inode->i_uid = de->uid; + inode->i_gid = de->gid; + } + if (de->size) + inode->i_size = de->size; + if (de->ops) + inode->i_op = de->ops; + if (de->nlink) + inode->i_nlink = de->nlink; + if (de->fill_inode) + de->fill_inode(inode); + } + } + return inode; +} struct super_block *proc_read_super(struct super_block *s,void *data, int silent) { + proc_root_init(); lock_super(s); s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = PROC_SUPER_MAGIC; s->s_op = &proc_sops; unlock_super(s); - if (!(s->s_mounted = iget(s,PROC_ROOT_INO))) { + if (!(s->s_mounted = proc_get_inode(s, PROC_ROOT_INO, &proc_root))) { s->s_dev = 0; printk("get root inode failed\n"); return NULL; } parse_options(data, &s->s_mounted->i_uid, &s->s_mounted->i_gid); - proc_net_init(); return s; } @@ -139,31 +161,6 @@ for (i = 1 ; i < NR_TASKS ; i++) if (task[i]) inode->i_nlink++; - inode->i_op = &proc_root_inode_operations; - return; - } - -/* #ifdef CONFIG_IP_ACCT */ - /* this file may be opened R/W by root to reset the accounting */ - if (ino == PROC_NET_IPACCT) { - inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR; - inode->i_op = &proc_net_inode_operations; - return; - } -/* #endif */ -/* #ifdef CONFIG_IP_FIREWALL */ - /* these files may be opened R/W by root to reset the counters */ - if ((ino == PROC_NET_IPFWFWD) || (ino == PROC_NET_IPFWBLK)) { - inode->i_mode = S_IFREG | S_IRUGO | S_IWUSR; - inode->i_op = &proc_net_inode_operations; - return; - } -/* #endif */ - - /* other files within /proc/net */ - if ((ino >= PROC_NET_UNIX) && (ino < PROC_NET_LAST)) { - inode->i_mode = S_IFREG | S_IRUGO; - inode->i_op = &proc_net_inode_operations; return; } @@ -203,9 +200,7 @@ inode->i_op = &proc_kmsg_inode_operations; break; case PROC_NET: - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; inode->i_nlink = 2; - inode->i_op = &proc_netdir_inode_operations; break; case PROC_SCSI: inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; @@ -239,8 +234,6 @@ switch (ino) { case PROC_PID_INO: inode->i_nlink = 4; - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; - inode->i_op = &proc_base_inode_operations; return; case PROC_PID_MEM: inode->i_op = &proc_mem_inode_operations; diff -u --recursive --new-file v1.3.18/linux/fs/proc/net.c linux/fs/proc/net.c --- v1.3.18/linux/fs/proc/net.c Sun Aug 13 14:45:34 1995 +++ linux/fs/proc/net.c Tue Aug 15 14:41:48 1995 @@ -36,111 +36,48 @@ #include #include -static struct proc_dir_entry *net_dir = NULL; - -int proc_net_register(struct proc_dir_entry *dp) -{ - dp->next = net_dir; - net_dir = dp; - return 0; -} - -int proc_net_unregister(int ino) -{ - struct proc_dir_entry **p = &net_dir, *dp; - - while ((dp = *p) != NULL) { - if (dp->low_ino == ino) { - *p = dp->next; - dp->next = NULL; - return 0; - } - p = &dp->next; - } - return -EINVAL; -} - -static int dir_get_info(char * a, char ** b, off_t d, int e, int f) -{ - return -EISDIR; -} - -void proc_net_init(void) -{ - static struct proc_dir_entry - nd_thisdir = { PROC_NET, 1, ".", dir_get_info }, - nd_rootdir = { PROC_ROOT_INO, 2, "..", dir_get_info }; - static int already = 0; - - if (already) return; - already = 1; - - proc_net_register(&nd_thisdir); - proc_net_register(&nd_rootdir); -} - - -static int proc_lookupnet(struct inode * dir,const char * name, int len, - struct inode ** result) -{ - struct proc_dir_entry *de; - - *result = NULL; - if (!dir) - return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return -ENOENT; - } - for (de = net_dir ; de ; de = de->next) { - struct inode * inode; - if (!proc_match(len, name, de)) - continue; - inode = iget(dir->i_sb, de->low_ino); - iput(dir); - if (!inode) - return -ENOENT; - inode->u.generic_ip = de; - if (de->fill_inode) - de->fill_inode(inode); - *result = inode; - return 0; - } - iput(dir); - return -ENOENT; -} - -static int proc_readnetdir(struct inode * inode, struct file * filp, - void * dirent, filldir_t filldir) -{ - struct proc_dir_entry * de; - unsigned int ino; - int i; - - if (!inode || !S_ISDIR(inode->i_mode)) - return -EBADF; - ino = inode->i_ino; - de = net_dir; - i = filp->f_pos; - for (;;) { - if (!de) - return 0; - if (!i) - break; - de = de->next; - i--; - } - - do { - if (filldir(dirent, de->name, de->namelen, filp->f_pos, de->low_ino) < 0) - return 0; - filp->f_pos++; - de = de->next; - } while (de); +static struct file_operations proc_netdir_operations = { + NULL, /* lseek - default */ + NULL, /* read - bad */ + NULL, /* write - bad */ + proc_readdir, /* readdir */ + NULL, /* select - default */ + NULL, /* ioctl - default */ + NULL, /* mmap */ + NULL, /* no special open code */ + NULL, /* no special release code */ + NULL /* can't fsync */ +}; - return 0; -} +/* + * proc directories can do almost nothing.. + */ +static struct inode_operations proc_netdir_inode_operations = { + &proc_netdir_operations, /* default net directory file-ops */ + NULL, /* create */ + proc_lookup, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ +}; +struct proc_dir_entry proc_net = { + PROC_NET, 3, "net", + S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, + 0, &proc_netdir_inode_operations, + NULL, NULL, + NULL, + NULL, NULL +}; #define PROC_BLOCK_SIZE (3*1024) /* 4K page size but our output routines use some slack for overruns */ @@ -212,40 +149,6 @@ &proc_net_operations, /* default net file-ops */ NULL, /* create */ NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* bmap */ - NULL, /* truncate */ - NULL /* permission */ -}; - -static struct file_operations proc_netdir_operations = { - NULL, /* lseek - default */ - NULL, /* read - bad */ - NULL, /* write - bad */ - proc_readnetdir, /* readdir */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -/* - * proc directories can do almost nothing.. - */ -struct inode_operations proc_netdir_inode_operations = { - &proc_netdir_operations, /* default net directory file-ops */ - NULL, /* create */ - proc_lookupnet, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ diff -u --recursive --new-file v1.3.18/linux/fs/proc/root.c linux/fs/proc/root.c --- v1.3.18/linux/fs/proc/root.c Sun Aug 13 14:45:34 1995 +++ linux/fs/proc/root.c Tue Aug 15 14:55:47 1995 @@ -14,14 +14,19 @@ #include #include -static int proc_readroot(struct inode *, struct file *, void *, filldir_t); -static int proc_lookuproot(struct inode *,const char *,int,struct inode **); +/* + * Offset of the first process in the /proc root directory.. + */ +#define FIRST_PROCESS_ENTRY 256 + +static int proc_root_readdir(struct inode *, struct file *, void *, filldir_t); +static int proc_root_lookup(struct inode *,const char *,int,struct inode **); static struct file_operations proc_root_operations = { NULL, /* lseek - default */ NULL, /* read - bad */ NULL, /* write - bad */ - proc_readroot, /* readdir */ + proc_root_readdir, /* readdir */ NULL, /* select - default */ NULL, /* ioctl - default */ NULL, /* mmap */ @@ -33,10 +38,10 @@ /* * proc directories can do almost nothing.. */ -struct inode_operations proc_root_inode_operations = { +static struct inode_operations proc_root_inode_operations = { &proc_root_operations, /* default base directory file-ops */ NULL, /* create */ - proc_lookuproot, /* lookup */ + proc_root_lookup, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ @@ -51,125 +56,368 @@ NULL /* permission */ }; -static struct proc_dir_entry root_dir[] = { - { PROC_ROOT_INO, 1, "." }, - { PROC_ROOT_INO, 2, ".." }, - { PROC_LOADAVG, 7, "loadavg" }, - { PROC_UPTIME, 6, "uptime" }, - { PROC_MEMINFO, 7, "meminfo" }, - { PROC_KMSG, 4, "kmsg" }, - { PROC_VERSION, 7, "version" }, +/* + * This is the root "inode" in the /proc tree.. + */ +struct proc_dir_entry proc_root = { + PROC_ROOT_INO, 5, "/proc", + S_IFDIR | S_IRUGO | S_IXUGO, 3, 0, 0, + 0, &proc_root_inode_operations, + NULL, NULL, + NULL, + &proc_root, NULL +}; + +int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) +{ + dp->next = dir->subdir; + dp->parent = dir; + dir->subdir = dp; + if (S_ISDIR(dp->mode)) + dir->nlink++; + return 0; +} + +int proc_unregister(struct proc_dir_entry * dir, int ino) +{ + struct proc_dir_entry **p = &dir->subdir, *dp; + + while ((dp = *p) != NULL) { + if (dp->low_ino == ino) { + *p = dp->next; + dp->next = NULL; + if (S_ISDIR(dp->mode)) + dir->nlink--; + return 0; + } + p = &dp->next; + } + return -EINVAL; +} + +/* + * /proc/self: + */ +static int proc_self_followlink(struct inode * dir, struct inode * inode, + int flag, int mode, struct inode ** res_inode) +{ + iput(dir); + *res_inode = proc_get_inode(inode->i_sb, (current->pid << 16) + PROC_PID_INO, &proc_pid); + iput(inode); + if (!*res_inode) + return -ENOENT; + return 0; +} + +static int proc_self_readlink(struct inode * inode, char * buffer, int buflen) +{ + int len; + char tmp[30]; + + iput(inode); + len = 1 + sprintf(tmp, "%d", current->pid); + if (buflen < len) + len = buflen; + memcpy_tofs(buffer, tmp, len); + return len; +} + +static struct inode_operations proc_self_inode_operations = { + NULL, /* no file-ops */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + proc_self_readlink, /* readlink */ + proc_self_followlink, /* follow_link */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ +}; + +void proc_root_init(void) +{ + static int done = 0; + + if (done) + return; + done = 1; + proc_base_init(); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_LOADAVG, 7, "loadavg", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_UPTIME, 6, "uptime", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_MEMINFO, 7, "meminfo", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_KMSG, 4, "kmsg", + S_IFREG | S_IRUSR, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_VERSION, 7, "version", + S_IFREG | S_IRUGO, 1, 0, 0, + }); #ifdef CONFIG_PCI - { PROC_PCI, 3, "pci" }, + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_PCI, 3, "pci", + S_IFREG | S_IRUGO, 1, 0, 0, + }); #endif - { PROC_CPUINFO, 7, "cpuinfo" }, - { PROC_SELF, 4, "self" }, /* will change inode # */ - { PROC_NET, 3, "net" }, - { PROC_SCSI, 4, "scsi" }, + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_CPUINFO, 7, "cpuinfo", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_SELF, 4, "self", + S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0, + 64, &proc_self_inode_operations, + }); + proc_register(&proc_root, &proc_net); + proc_register(&proc_root, &proc_scsi); #ifdef CONFIG_DEBUG_MALLOC - { PROC_MALLOC, 6, "malloc" }, + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_MALLOC, 6, "malloc", + S_IFREG | S_IRUGO, 1, 0, 0, + }); #endif - { PROC_KCORE, 5, "kcore" }, - { PROC_MODULES, 7, "modules" }, - { PROC_STAT, 4, "stat" }, - { PROC_DEVICES, 7, "devices" }, - { PROC_INTERRUPTS, 10,"interrupts" }, - { PROC_FILESYSTEMS, 11,"filesystems" }, - { PROC_KSYMS, 5, "ksyms" }, - { PROC_DMA, 3, "dma" }, - { PROC_IOPORTS, 7, "ioports" }, + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_KCORE, 5, "kcore", + S_IFREG | S_IRUSR, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_MODULES, 7, "modules", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_STAT, 4, "stat", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_DEVICES, 7, "devices", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_INTERRUPTS, 10,"interrupts", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_FILESYSTEMS, 11,"filesystems", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_KSYMS, 5, "ksyms", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_DMA, 3, "dma", + S_IFREG | S_IRUGO, 1, 0, 0, + }); + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_IOPORTS, 7, "ioports", + S_IFREG | S_IRUGO, 1, 0, 0, + }); #ifdef CONFIG_PROFILE - { PROC_PROFILE, 7, "profile" }, + proc_register(&proc_root, &(struct proc_dir_entry) { + PROC_PROFILE, 7, "profile", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, + }); #endif -}; +} + -#define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0]))) +int proc_match(int len,const char * name,struct proc_dir_entry * de) +{ + if (!de || !de->low_ino) + return 0; + /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ + if (!len && (de->name[0]=='.') && (de->name[1]=='\0')) + return 1; + if (de->namelen != len) + return 0; + return !memcmp(name, de->name, len); +} -static int proc_lookuproot(struct inode * dir,const char * name, int len, +int proc_lookup(struct inode * dir,const char * name, int len, struct inode ** result) { - struct proc_dir_entry * de = NULL; - unsigned int pid, c; - int i, ino; + struct proc_dir_entry * de; + int ino; *result = NULL; - if (!dir) - return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { + if (!dir || !S_ISDIR(dir->i_mode)) { iput(dir); - return -ENOENT; - } - for (i = 0; i < NR_ROOT_DIRENTRY; i++) { - if (!proc_match(len,name,root_dir+i)) - continue; - de = root_dir + i; - break; + return -ENOTDIR; } - if (de) { - ino = de->low_ino; - if (ino == PROC_ROOT_INO) { - *result = dir; + + de = (struct proc_dir_entry *) dir->u.generic_ip; + if (!de) + return -EINVAL; + + /* Special case "." and "..": they aren't on the directory list */ + *result = dir; + if (!len) + return 0; + if (name[0] == '.') { + if (len == 1) + return 0; + if (name[1] == '.' && len == 2) { + struct inode * inode; + inode = proc_get_inode(dir->i_sb, de->parent->low_ino, de->parent); + iput(dir); + if (!inode) + return -EINVAL; + *result = inode; return 0; } - if (ino == PROC_SELF) /* self modifying inode ... */ - ino = (current->pid << 16) + 2; - } else { - pid = 0; - while (len-- > 0) { - c = *name - '0'; - name++; - if (c > 9) { - pid = 0; - break; - } - pid *= 10; - pid += c; - if (pid & 0xffff0000) { - pid = 0; - break; - } + } + + *result = NULL; + for (de = de->subdir; de ; de = de->next) { + if (proc_match(len, name, de)) + break; + } + if (!de) + return -ENOENT; + + ino = de->low_ino | (dir->i_ino & ~(0xffff)); + + if (!(*result = proc_get_inode(dir->i_sb, ino, de))) { + iput(dir); + return -EINVAL; + } + iput(dir); + return 0; +} + +static int proc_root_lookup(struct inode * dir,const char * name, int len, + struct inode ** result) +{ + unsigned int pid, c; + int i, ino; + + int retval = proc_lookup(dir, name, len, result); + if (retval != -ENOENT) + return retval; + + pid = 0; + while (len-- > 0) { + c = *name - '0'; + name++; + if (c > 9) { + pid = 0; + break; } - for (i = 0 ; i < NR_TASKS ; i++) - if (task[i] && task[i]->pid == pid) - break; - if (!pid || i >= NR_TASKS) { - iput(dir); - return -ENOENT; + pid *= 10; + pid += c; + if (pid & 0xffff0000) { + pid = 0; + break; } - ino = (pid << 16) + 2; } - if (!(*result = iget(dir->i_sb,ino))) { + for (i = 0 ; i < NR_TASKS ; i++) + if (task[i] && task[i]->pid == pid) + break; + if (!pid || i >= NR_TASKS) { iput(dir); return -ENOENT; } + ino = (pid << 16) + PROC_PID_INO; + if (!(*result = proc_get_inode(dir->i_sb, ino, &proc_pid))) { + iput(dir); + return -EINVAL; + } iput(dir); - (*result)->u.generic_ip = de; return 0; } +/* + * This returns non-zero if at EOF, so that the /proc + * root directory can use this and check if it should + * continue with the entries.. + * + * Note that the VFS-layer doesn't care about the return + * value of the readdir() call, as long as it's non-negative + * for success.. + */ +int proc_readdir(struct inode * inode, struct file * filp, + void * dirent, filldir_t filldir) +{ + struct proc_dir_entry * de; + unsigned int ino; + int i; + + if (!inode || !S_ISDIR(inode->i_mode)) + return -ENOTDIR; + ino = inode->i_ino; + de = (struct proc_dir_entry *) inode->u.generic_ip; + if (!de) + return -EINVAL; + i = filp->f_pos; + switch (i) { + case 0: + if (filldir(dirent, ".", 1, i, ino) < 0) + return 0; + i++; + filp->f_pos++; + /* fall through */ + case 1: + if (filldir(dirent, "..", 2, i, de->parent->low_ino) < 0) + return 0; + i++; + filp->f_pos++; + /* fall through */ + default: + ino &= ~0xffff; + de = de->subdir; + i -= 2; + for (;;) { + if (!de) + return 1; + if (!i) + break; + de = de->next; + i--; + } + + do { + if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0) + return 0; + filp->f_pos++; + de = de->next; + } while (de); + } + return 1; +} + #define NUMBUF 10 -static int proc_readroot(struct inode * inode, struct file * filp, +static int proc_root_readdir(struct inode * inode, struct file * filp, void * dirent, filldir_t filldir) { char buf[NUMBUF]; unsigned int nr,pid; unsigned long i,j; - if (!inode || !S_ISDIR(inode->i_mode)) - return -EBADF; - nr = filp->f_pos; - while (nr < NR_ROOT_DIRENTRY) { - struct proc_dir_entry * de = root_dir + nr; - - if (filldir(dirent, de->name, de->namelen, nr, de->low_ino) < 0) - return 0; - filp->f_pos++; - nr++; + if (nr < FIRST_PROCESS_ENTRY) { + int error = proc_readdir(inode, filp, dirent, filldir); + if (error <= 0) + return error; + filp->f_pos = nr = FIRST_PROCESS_ENTRY; } - for (nr -= NR_ROOT_DIRENTRY; nr < NR_TASKS; nr++, filp->f_pos++) { + for (nr -= FIRST_PROCESS_ENTRY; nr < NR_TASKS; nr++, filp->f_pos++) { struct task_struct * p = task[nr]; if (!p || !(pid = p->pid)) @@ -183,7 +431,7 @@ i /= 10; } while (i); - if (filldir(dirent, buf+j, NUMBUF-j, nr+NR_ROOT_DIRENTRY, (pid << 16)+2) < 0) + if (filldir(dirent, buf+j, NUMBUF-j, filp->f_pos, (pid << 16) + PROC_PID_INO) < 0) break; } return 0; diff -u --recursive --new-file v1.3.18/linux/fs/proc/scsi.c linux/fs/proc/scsi.c --- v1.3.18/linux/fs/proc/scsi.c Sun Aug 13 14:45:34 1995 +++ linux/fs/proc/scsi.c Tue Aug 15 14:41:58 1995 @@ -80,6 +80,15 @@ NULL /* permission */ }; +struct proc_dir_entry proc_scsi = { + PROC_SCSI, 4, "scsi", + S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, + 0, &proc_scsi_inode_operations, + NULL, NULL, + NULL, + &proc_root, NULL +}; + struct proc_dir_entry scsi_dir[PROC_SCSI_FILE - PROC_SCSI_SCSI + 3]; struct proc_dir_entry scsi_hba_dir[(PROC_SCSI_LAST - PROC_SCSI_FILE) * 4]; @@ -158,7 +167,7 @@ for (; de->name ; de++) { if (!proc_match(len, name, de)) continue; - *result = iget(dir->i_sb, de->low_ino); + *result = proc_get_inode(dir->i_sb, de->low_ino, de); iput(dir); if (!*result) return(-ENOENT); diff -u --recursive --new-file v1.3.18/linux/fs/smbfs/Makefile linux/fs/smbfs/Makefile --- v1.3.18/linux/fs/smbfs/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/smbfs/Makefile Tue Aug 15 15:07:02 1995 @@ -7,20 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= proc.o sock.o inode.o file.o dir.o \ - ioctl.o mmap.o - -smbfs.o: $(OBJS) - $(LD) -r -o smbfs.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend - -modules: smbfs.o +O_TARGET := smbfs.o +O_OBJS := proc.o sock.o inode.o file.o dir.o ioctl.o mmap.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/sysv/Makefile linux/fs/sysv/Makefile --- v1.3.18/linux/fs/sysv/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/sysv/Makefile Tue Aug 15 15:07:02 1995 @@ -7,21 +7,9 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= ialloc.o balloc.o inode.o file.o dir.o symlink.o namei.o \ - fsync.o truncate.o - -sysv.o: $(OBJS) - $(LD) -r -o sysv.o $(OBJS) - -modules: sysv.o - ln -sf ../fs/sysv/sysv.o $(TOPDIR)/modules - -dep: - $(CPP) -M *.c > .depend +O_TARGET := sysv.o +O_OBJS := ialloc.o balloc.o inode.o file.o dir.o symlink.o namei.o \ + fsync.o truncate.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/umsdos/Makefile linux/fs/umsdos/Makefile --- v1.3.18/linux/fs/umsdos/Makefile Tue Jul 11 10:02:58 1995 +++ linux/fs/umsdos/Makefile Tue Aug 15 15:07:02 1995 @@ -7,30 +7,18 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< +O_TARGET := umsdos.o +O_OBJS := dir.o emd.o file.o inode.o ioctl.o mangle.o namei.o \ + rdir.o symlink.o #check.o +M_OBJS := $(O_TARGET) -OBJS= dir.o emd.o file.o inode.o ioctl.o mangle.o namei.o\ - rdir.o symlink.o #check.o - -umsdos.o: $(OBJS) - $(LD) -r -o umsdos.o $(OBJS) - -modules: umsdos.o - ln -sf ../fs/umsdos/umsdos.o $(TOPDIR)/modules +include $(TOPDIR)/Rules.make clean: rm -f core *.o *.a *.s -dep: - $(CPP) -M *.c > .depend - p: proto *.c >/usr/include/linux/umsdos_fs.p doc: nadoc -i -p umsdos.doc - /tmp/umsdos.mpg - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/fs/xiafs/Makefile linux/fs/xiafs/Makefile --- v1.3.18/linux/fs/xiafs/Makefile Tue Jul 11 10:02:59 1995 +++ linux/fs/xiafs/Makefile Tue Aug 15 15:07:02 1995 @@ -7,21 +7,8 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= bitmap.o truncate.o namei.o inode.o \ - file.o dir.o symlink.o fsync.o - -xiafs.o: $(OBJS) - $(LD) -r -o xiafs.o $(OBJS) - -modules: xiafs.o - ln -sf ../fs/xiafs/xiafs.o $(TOPDIR)/modules - -dep: - $(CPP) -M *.c > .depend +O_TARGET := xiafs.o +O_OBJS := bitmap.o truncate.o namei.o inode.o file.o dir.o symlink.o fsync.o +M_OBJS := $(O_TARGET) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/include/asm-alpha/byteorder.h linux/include/asm-alpha/byteorder.h --- v1.3.18/linux/include/asm-alpha/byteorder.h Fri Jun 2 13:51:16 1995 +++ linux/include/asm-alpha/byteorder.h Mon Aug 14 12:57:03 1995 @@ -6,12 +6,12 @@ #undef htonl #undef htons -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN #endif -#ifndef LITTLE_ENDIAN_BITFIELD -#define LITTLE_ENDIAN_BITFIELD +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD #endif extern unsigned long int ntohl(unsigned long int); diff -u --recursive --new-file v1.3.18/linux/include/asm-i386/byteorder.h linux/include/asm-i386/byteorder.h --- v1.3.18/linux/include/asm-i386/byteorder.h Sat Apr 29 10:19:32 1995 +++ linux/include/asm-i386/byteorder.h Mon Aug 14 12:56:05 1995 @@ -6,12 +6,12 @@ #undef htonl #undef htons -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 #endif -#ifndef LITTLE_ENDIAN_BITFIELD -#define LITTLE_ENDIAN_BITFIELD +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD #endif extern unsigned long int ntohl(unsigned long int); diff -u --recursive --new-file v1.3.18/linux/include/asm-i386/io.h linux/include/asm-i386/io.h --- v1.3.18/linux/include/asm-i386/io.h Thu Jun 29 19:02:54 1995 +++ linux/include/asm-i386/io.h Mon Aug 14 07:36:45 1995 @@ -89,9 +89,9 @@ #define __OUT(s,s1,x) \ __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \ -__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "i" (port)); } \ +__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \ __OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \ -__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "i" (port)); SLOW_DOWN_IO; } +__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; } #define __IN1(s) \ extern inline unsigned int __in##s(unsigned short port) { unsigned int _v; @@ -101,9 +101,9 @@ #define __IN(s,s1,i...) \ __IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \ -__IN1(s##c) __IN2(s,s1,"") : "=a" (_v) : "i" (port) ,##i ); return _v; } \ +__IN1(s##c) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \ __IN1(s##_p) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \ -__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "i" (port) ,##i ); SLOW_DOWN_IO; return _v; } +__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; } #define __INS(s) \ extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \ diff -u --recursive --new-file v1.3.18/linux/include/asm-mips/byteorder.h linux/include/asm-mips/byteorder.h --- v1.3.18/linux/include/asm-mips/byteorder.h Mon Apr 17 13:47:56 1995 +++ linux/include/asm-mips/byteorder.h Mon Aug 14 12:56:33 1995 @@ -7,11 +7,11 @@ #undef htons #ifdef MIPSEL -#define LITTLE_ENDIAN -#define LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN +#define __LITTLE_ENDIAN_BITFIELD #elif MIPSEB -#define BIG_ENDIAN -#define BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN +#define __BIG_ENDIAN_BITFIELD #else #error "MIPS but neither MIPSEL nor MIPSEB?" #endif diff -u --recursive --new-file v1.3.18/linux/include/asm-sparc/bitops.h linux/include/asm-sparc/bitops.h --- v1.3.18/linux/include/asm-sparc/bitops.h Tue Jun 27 14:11:45 1995 +++ linux/include/asm-sparc/bitops.h Mon Aug 14 12:57:34 1995 @@ -35,13 +35,13 @@ * 31 24 23 16 15 8 7 0 */ -/* #define LITTLE_ENDIAN_BITOPS */ +/* #define __LITTLE_ENDIAN_BITOPS */ extern __inline__ unsigned int set_bit(unsigned int nr, void *vaddr) { -#ifdef LITTLE_ENDIAN_BITOPS +#ifdef __LITTLE_ENDIAN_BITOPS int retval; @@ -101,7 +101,7 @@ extern __inline__ unsigned int clear_bit(unsigned int nr, void *vaddr) { -#ifdef LITTLE_ENDIAN_BITOPS +#ifdef __LITTLE_ENDIAN_BITOPS int retval; @@ -162,7 +162,7 @@ extern __inline__ unsigned int change_bit(unsigned int nr, void *vaddr) { -#ifdef LITTLE_ENDIAN_BITOPS +#ifdef __LITTLE_ENDIAN_BITOPS int retval; @@ -225,7 +225,7 @@ extern __inline__ unsigned int test_bit(int nr, void *vaddr) { -#ifdef LITTLE_ENDIAN_BITOPS +#ifdef __LITTLE_ENDIAN_BITOPS unsigned char mask; unsigned char *addr = (unsigned char *)vaddr; @@ -254,7 +254,7 @@ cnt = 0; -#ifdef LITTLE_ENDIAN_BITOPS +#ifdef __LITTLE_ENDIAN_BITOPS for(int byte_bit = 24; byte_bit >=0; byte_bit -= 8) for(int bit = 0; bit<8; bit++) @@ -283,7 +283,7 @@ extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) { -#ifdef LITTLE_ENDIAN_BITOPS +#ifdef __LITTLE_ENDIAN_BITOPS /* FOO, needs to be written */ diff -u --recursive --new-file v1.3.18/linux/include/asm-sparc/byteorder.h linux/include/asm-sparc/byteorder.h --- v1.3.18/linux/include/asm-sparc/byteorder.h Mon Apr 17 13:47:56 1995 +++ linux/include/asm-sparc/byteorder.h Mon Aug 14 12:59:16 1995 @@ -6,8 +6,8 @@ #undef htonl #undef htons -#define BIG_ENDIAN -#define BIG_ENDIAN_BITFIELD +#define __BIG_ENDIAN +#define __BIG_ENDIAN_BITFIELD extern unsigned long int ntohl(unsigned long int); extern unsigned short int ntohs(unsigned short int); diff -u --recursive --new-file v1.3.18/linux/include/linux/genhd.h linux/include/linux/genhd.h --- v1.3.18/linux/include/linux/genhd.h Wed Aug 2 13:21:16 1995 +++ linux/include/linux/genhd.h Sun Aug 13 20:19:12 1995 @@ -18,6 +18,7 @@ #define EXTENDED_PARTITION 5 #define DM6_PARTITION 0x54 /* has DDO: use xlated geom & offset */ +#define EZD_PARTITION 0x55 /* EZ-DRIVE: same as DM6 (we think) */ #define DM6_AUX1PARTITION 0x51 /* no DDO: use xlated geom */ #define DM6_AUX3PARTITION 0x53 /* no DDO: use xlated geom */ @@ -47,9 +48,9 @@ int max_p; /* maximum partitions per device */ int max_nr; /* maximum number of real devices */ - void (*init)(void); /* Initialization called before we do our thing */ + void (*init)(struct gendisk *); /* Initialization called before we do our thing */ struct hd_struct *part; /* partition table */ - int *sizes; /* size of device in blocks */ + int *sizes; /* device size in blocks, copied to blk_size[] */ int nr_real; /* number of real devices */ void *real_devices; /* internal use */ diff -u --recursive --new-file v1.3.18/linux/include/linux/hdreg.h linux/include/linux/hdreg.h --- v1.3.18/linux/include/linux/hdreg.h Tue Jul 11 10:02:59 1995 +++ linux/include/linux/hdreg.h Tue Aug 15 20:09:43 1995 @@ -5,12 +5,14 @@ /* * This file contains some defines for the AT-hd-controller. - * Various sources. Check out some definitions (see comments with - * a ques). + * Various sources. */ +#define HD_IRQ 14 /* the standard disk interrupt */ + +/* ide.c has it's own port definitions in "ide.h" */ + /* Hd controller regs. Ref: IBM AT Bios-listing */ -/* For a second IDE interface, xor all addresses with 0x80 */ #define HD_DATA 0x1f0 /* _CTL when writing */ #define HD_ERROR 0x1f1 /* see err-bits */ #define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ @@ -26,6 +28,8 @@ #define HD_CMD 0x3f6 /* used for resets */ #define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ +/* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */ + /* Bits of HD_STATUS */ #define ERR_STAT 0x01 #define INDEX_STAT 0x02 @@ -45,10 +49,13 @@ #define WIN_INIT 0x60 #define WIN_SEEK 0x70 #define WIN_DIAGNOSE 0x90 -#define WIN_SPECIFY 0x91 +#define WIN_SPECIFY 0x91 /* set drive geometry translation */ #define WIN_SETIDLE1 0xE3 #define WIN_SETIDLE2 0x97 +#define WIN_DOORLOCK 0xde /* lock door on removeable drives */ +#define WIN_DOORUNLOCK 0xdf /* unlock door on removeable drives */ + #define WIN_PIDENTIFY 0xA1 /* identify ATA-PI device */ #define WIN_MULTREAD 0xC4 /* read multiple sectors */ #define WIN_MULTWRITE 0xC5 /* write multiple sectors */ @@ -147,11 +154,7 @@ void hd_setup(char *, int *); #endif /* CONFIG_BLK_DEV_HD */ #ifdef CONFIG_BLK_DEV_IDE -void ide_setup(char *, int *); -void hda_setup(char *, int *); -void hdb_setup(char *, int *); -void hdc_setup(char *, int *); -void hdd_setup(char *, int *); +void ide_setup(char *); #endif /* CONFIG_BLK_DEV_IDE */ #endif /* _LINUX_HDREG_H */ diff -u --recursive --new-file v1.3.18/linux/include/linux/if.h linux/include/linux/if.h --- v1.3.18/linux/include/linux/if.h Tue Jun 6 11:22:11 1995 +++ linux/include/linux/if.h Tue Aug 15 18:37:01 1995 @@ -148,9 +148,4 @@ #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ #define ifc_req ifc_ifcu.ifcu_req /* array of structures */ - -/* BSD UNIX expects to find these here, so here we go: */ -#include -#include - #endif /* _LINUX_IF_H */ diff -u --recursive --new-file v1.3.18/linux/include/linux/if_ether.h linux/include/linux/if_ether.h --- v1.3.18/linux/include/linux/if_ether.h Fri Jul 7 08:54:54 1995 +++ linux/include/linux/if_ether.h Tue Aug 15 18:45:49 1995 @@ -20,7 +20,6 @@ #ifndef _LINUX_IF_ETHER_H #define _LINUX_IF_ETHER_H - /* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble and FCS/CRC (frame check sequence). */ #define ETH_ALEN 6 /* Octets in one ethernet addr */ diff -u --recursive --new-file v1.3.18/linux/include/linux/in.h linux/include/linux/in.h --- v1.3.18/linux/include/linux/in.h Thu Jul 13 16:20:21 1995 +++ linux/include/linux/in.h Tue Aug 15 18:28:49 1995 @@ -108,6 +108,7 @@ /* Address to loopback in software to local host. */ #define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */ +#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000) /* Defines for Multicast INADDR */ #define INADDR_UNSPEC_GROUP 0xe0000000 /* 224.0.0.0 */ diff -u --recursive --new-file v1.3.18/linux/include/linux/ip.h linux/include/linux/ip.h --- v1.3.18/linux/include/linux/ip.h Mon Apr 17 13:47:56 1995 +++ linux/include/linux/ip.h Tue Aug 15 18:27:00 1995 @@ -34,10 +34,10 @@ __u8 len; __u8 ptr; union { -#if defined(LITTLE_ENDIAN_BITFIELD) +#if defined(__LITTLE_ENDIAN_BITFIELD) __u8 flags:4, overflow:4; -#elif defined(BIG_ENDIAN_BITFIELD) +#elif defined(__BIG_ENDIAN_BITFIELD) __u8 overflow:4, flags:4; #else @@ -72,10 +72,10 @@ struct iphdr { -#if defined(LITTLE_ENDIAN_BITFIELD) +#if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; -#elif defined (BIG_ENDIAN_BITFIELD) +#elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else diff -u --recursive --new-file v1.3.18/linux/include/linux/major.h linux/include/linux/major.h --- v1.3.18/linux/include/linux/major.h Fri Jul 7 08:54:54 1995 +++ linux/include/linux/major.h Sun Aug 13 20:19:12 1995 @@ -20,7 +20,7 @@ * 0 - unnamed unnamed minor 0 = true nodev * 1 - /dev/mem ramdisk * 2 - floppy - * 3 - hd + * 3 - ide0 or hd * 4 - /dev/tty* * 5 - /dev/tty; /dev/cua* * 6 - lp @@ -39,7 +39,7 @@ * 19 - cyclades /dev/ttyC* * 20 - cyclades /dev/cub* mitsumi (mcdx) cdrom * 21 - scsi generic - * 22 - (at2disk) + * 22 - ide1 * 23 - mitsumi cdrom * 24 - sony535 cdrom * 25 - matsushita cdrom minors 0..3 @@ -48,6 +48,8 @@ * 28 - matsushita cdrom 4 minors 0..3 * 29 - aztech/orchid/okano/wearnes cdrom * 32 - philips/lms cm206 cdrom + * 33 - ide2 + * 34 - ide3 */ #define UNNAMED_MAJOR 0 @@ -87,6 +89,8 @@ #define MATSUSHITA_CDROM4_MAJOR 28 #define AZTECH_CDROM_MAJOR 29 #define CM206_CDROM_MAJOR 32 +#define IDE2_MAJOR 33 +#define IDE3_MAJOR 34 /* * Tests for SCSI devices. diff -u --recursive --new-file v1.3.18/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h --- v1.3.18/linux/include/linux/proc_fs.h Sun Aug 13 14:45:35 1995 +++ linux/include/linux/proc_fs.h Tue Aug 15 20:10:20 1995 @@ -135,22 +135,57 @@ unsigned short low_ino; unsigned short namelen; const char *name; + mode_t mode; + nlink_t nlink; + uid_t uid; + gid_t gid; + unsigned long size; + struct inode_operations * ops; int (*get_info)(char *, char **, off_t, int, int); void (*fill_inode)(struct inode *); struct proc_dir_entry *next, *parent, *subdir; }; +extern struct proc_dir_entry proc_root; +extern struct proc_dir_entry proc_net; +extern struct proc_dir_entry proc_scsi; +extern struct proc_dir_entry proc_pid; +extern struct proc_dir_entry proc_pid_fd; + +extern void proc_root_init(void); +extern void proc_base_init(void); +extern void proc_net_init(void); + +extern int proc_register(struct proc_dir_entry *, struct proc_dir_entry *); +extern int proc_unregister(struct proc_dir_entry *, int); + +static inline int proc_net_register(struct proc_dir_entry * x) +{ + return proc_register(&proc_net, x); +} + +static inline int proc_net_unregister(int x) +{ + return proc_unregister(&proc_net, x); +} + extern struct super_block *proc_read_super(struct super_block *,void *,int); -extern void proc_put_inode(struct inode *); -extern void proc_put_super(struct super_block *); +extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *); extern void proc_statfs(struct super_block *, struct statfs *, int); extern void proc_read_inode(struct inode *); extern void proc_write_inode(struct inode *); extern int proc_match(int, const char *, struct proc_dir_entry *); -extern int proc_net_register(struct proc_dir_entry *); -extern int proc_net_unregister(int); -extern struct inode_operations proc_root_inode_operations; +/* + * These are generic /proc routines that use the internal + * "struct proc_dir_entry" tree to traverse the filesystem. + * + * The /proc root directory has extended versions to take care + * of the /proc/ subdirectories. + */ +extern int proc_readdir(struct inode *, struct file *, void *, filldir_t); +extern int proc_lookup(struct inode *, const char *, int, struct inode **); + extern struct inode_operations proc_base_inode_operations; extern struct inode_operations proc_net_inode_operations; extern struct inode_operations proc_netdir_inode_operations; diff -u --recursive --new-file v1.3.18/linux/include/linux/skbuff.h linux/include/linux/skbuff.h --- v1.3.18/linux/include/linux/skbuff.h Thu Jul 13 16:20:21 1995 +++ linux/include/linux/skbuff.h Tue Aug 15 20:10:20 1995 @@ -133,7 +133,7 @@ extern int skb_device_locked(struct sk_buff *skb); extern unsigned char * skb_put(struct sk_buff *skb, int len); extern unsigned char * skb_push(struct sk_buff *skb, int len); -extern int skb_pull(struct sk_buff *skb, int len); +extern unsigned char * skb_pull(struct sk_buff *skb, int len); extern int skb_headroom(struct sk_buff *skb); extern int skb_tailroom(struct sk_buff *skb); extern void skb_reserve(struct sk_buff *skb, int len); @@ -324,13 +324,13 @@ return skb->data; } -extern __inline__ int skb_pull(struct sk_buff *skb, int len) +extern __inline__ unsigned char * skb_pull(struct sk_buff *skb, int len) { - if(len>skb->len) - len=skb->len; + if(len > skb->len) + return NULL; skb->data+=len; skb->len-=len; - return len; + return skb->data; } extern __inline__ int skb_headroom(struct sk_buff *skb) diff -u --recursive --new-file v1.3.18/linux/include/linux/tcp.h linux/include/linux/tcp.h --- v1.3.18/linux/include/linux/tcp.h Mon Jun 12 12:27:28 1995 +++ linux/include/linux/tcp.h Mon Aug 14 12:59:16 1995 @@ -26,7 +26,7 @@ __u16 dest; __u32 seq; __u32 ack_seq; -#if defined(LITTLE_ENDIAN_BITFIELD) +#if defined(__LITTLE_ENDIAN_BITFIELD) __u16 res1:4, doff:4, fin:1, @@ -36,7 +36,7 @@ ack:1, urg:1, res2:2; -#elif defined(BIG_ENDIAN_BITFIELD) +#elif defined(__BIG_ENDIAN_BITFIELD) __u16 doff:4, res1:4, res2:2, diff -u --recursive --new-file v1.3.18/linux/include/linux/xd.h linux/include/linux/xd.h --- v1.3.18/linux/include/linux/xd.h Tue Aug 8 12:31:42 1995 +++ linux/include/linux/xd.h Sun Aug 13 20:19:12 1995 @@ -107,7 +107,7 @@ void xd_setup (char *command,int *integers); static u_char xd_detect (u_char *controller,u_char **address); static u_char xd_initdrives (void (*init_drive)(u_char drive)); -static void xd_geninit (void); +static void xd_geninit (struct gendisk *); static int xd_open (struct inode *inode,struct file *file); static void do_xd_request (void); diff -u --recursive --new-file v1.3.18/linux/include/net/ax25.h linux/include/net/ax25.h --- v1.3.18/linux/include/net/ax25.h Wed Aug 9 14:55:43 1995 +++ linux/include/net/ax25.h Tue Aug 15 20:12:07 1995 @@ -158,7 +158,7 @@ extern ax25_address *ax25_findbyuid(uid_t); extern void ax25_queue_xmit(struct sk_buff *, struct device *, int); -#include "ax25call.h" +#include /* ax25_in.c */ extern int ax25_process_rx_frame(ax25_cb *, struct sk_buff *, int); diff -u --recursive --new-file v1.3.18/linux/include/net/eth.h linux/include/net/eth.h --- v1.3.18/linux/include/net/eth.h Thu Jul 13 16:20:21 1995 +++ linux/include/net/eth.h Thu Jan 1 02:00:00 1970 @@ -1,37 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. NET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Definitions for the Ethernet handlers. - * - * Version: @(#)eth.h 1.0.4 05/13/93 - * - * Authors: Ross Biro, - * Fred N. van Kempen, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _ETH_H -#define _ETH_H - - -#include - - -extern char *eth_print(unsigned char *ptr); -extern void eth_dump(struct ethhdr *eth); -extern int eth_header(struct sk_buff *skb, struct device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len); -extern int eth_rebuild_header(void *buff, struct device *dev, - unsigned long dst, struct sk_buff *skb); -extern void eth_add_arp(unsigned long addr, struct sk_buff *skb, - struct device *dev); -extern unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev); -extern void eth_header_cache(struct device *dev, struct sock *sk, unsigned long saddr, unsigned long daddr); - -#endif /* _ETH_H */ diff -u --recursive --new-file v1.3.18/linux/include/net/ip.h linux/include/net/ip.h --- v1.3.18/linux/include/net/ip.h Wed Aug 9 14:55:43 1995 +++ linux/include/net/ip.h Tue Aug 15 20:16:43 1995 @@ -27,10 +27,10 @@ #include #ifndef _SNMP_H -#include "snmp.h" +#include #endif -#include "sock.h" /* struct sock */ +#include /* struct sock */ /* IP flags. */ #define IP_CE 0x8000 /* Flag: "Congestion" */ diff -u --recursive --new-file v1.3.18/linux/include/net/ipx.h linux/include/net/ipx.h --- v1.3.18/linux/include/net/ipx.h Tue Jun 6 11:22:17 1995 +++ linux/include/net/ipx.h Tue Aug 15 20:12:07 1995 @@ -12,7 +12,7 @@ #define _NET_INET_IPX_H_ #include -#include "datalink.h" +#include #include typedef struct @@ -44,7 +44,7 @@ typedef struct sock ipx_socket; -#include "ipxcall.h" +#include extern int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt); extern void ipxrtr_device_down(struct device *dev); diff -u --recursive --new-file v1.3.18/linux/include/net/netrom.h linux/include/net/netrom.h --- v1.3.18/linux/include/net/netrom.h Sun Aug 13 14:45:35 1995 +++ linux/include/net/netrom.h Tue Aug 15 15:22:24 1995 @@ -97,7 +97,7 @@ extern int nr_rx_ip(struct sk_buff *, struct device *); extern int nr_init(struct device *); -#include "nrcall.h" +#include /* nr_in.c */ extern int nr_process_rx_frame(struct sock *, struct sk_buff *); diff -u --recursive --new-file v1.3.18/linux/include/net/sock.h linux/include/net/sock.h --- v1.3.18/linux/include/net/sock.h Sun Aug 13 14:45:35 1995 +++ linux/include/net/sock.h Tue Aug 15 20:12:08 1995 @@ -37,15 +37,15 @@ #include #include /* struct sk_buff */ -#include "protocol.h" /* struct inet_protocol */ +#include /* struct inet_protocol */ #ifdef CONFIG_AX25 -#include "ax25.h" +#include #ifdef CONFIG_NETROM -#include "netrom.h" +#include #endif #endif #ifdef CONFIG_IPX -#include "ipx.h" +#include #endif #ifdef CONFIG_ATALK #include diff -u --recursive --new-file v1.3.18/linux/init/main.c linux/init/main.c --- v1.3.18/linux/init/main.c Tue Aug 8 12:31:42 1995 +++ linux/init/main.c Sun Aug 13 20:19:12 1995 @@ -160,13 +160,7 @@ #ifdef CONFIG_SCSI { "max_scsi_luns=", scsi_luns_setup }, #endif -#ifdef CONFIG_BLK_DEV_IDE - { "hda=", hda_setup }, - { "hdb=", hdb_setup }, - { "hdc=", hdc_setup }, - { "hdd=", hdd_setup }, - { "hd=", ide_setup }, -#elif defined(CONFIG_BLK_DEV_HD) +#if defined(CONFIG_BLK_DEV_HD) { "hd=", hd_setup }, #endif #ifdef CONFIG_CHR_DEV_ST @@ -253,6 +247,13 @@ int i = 0; int ints[11]; +#ifdef CONFIG_BLK_DEV_IDE + /* ide driver needs the basic string, rather than pre-processed values */ + if (!strncmp(line,"ide",3) || (!strncmp(line,"hd",2) && line[2] != '=')) { + ide_setup(line); + return 1; + } +#endif while (bootsetups[i].str) { int n = strlen(bootsetups[i].str); if (!strncmp(line,bootsetups[i].str,n)) { diff -u --recursive --new-file v1.3.18/linux/ipc/Makefile linux/ipc/Makefile --- v1.3.18/linux/ipc/Makefile Tue Jul 11 10:02:59 1995 +++ linux/ipc/Makefile Tue Aug 15 15:07:02 1995 @@ -7,25 +7,11 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS = util.o -SRCS = util.c +O_TARGET := ipc.o +O_OBJS := util.o ifdef CONFIG_SYSVIPC -OBJS := $(OBJS) msg.o sem.o shm.o -SRCS := $(SRCS) msg.c sem.c shm.c +O_OBJS += msg.o sem.o shm.o endif - -ipc.o: $(OBJS) - $(LD) -r -o ipc.o $(OBJS) - -dep: - $(CPP) -M $(SRCS) > .depend - -modules: include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/kernel/Makefile linux/kernel/Makefile --- v1.3.18/linux/kernel/Makefile Tue Jul 11 10:03:00 1995 +++ linux/kernel/Makefile Tue Aug 15 15:07:02 1995 @@ -9,31 +9,19 @@ .S.s: $(CPP) -traditional $< -o $*.s -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< -OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \ +O_TARGET := kernel.o +O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \ module.o exit.o signal.o itimer.o info.o time.o softirq.o \ resource.o - SYMTAB_OBJS = ksyms.o +O_OBJS += $(SYMTAB_OBJS) -all: kernel.o +$(O_TARGET): $(SYMTAB_OBJS:.o=.ver) -include ../versions.mk +include $(TOPDIR)/Rules.make -kernel.o: $(SYMTAB_OBJS:.o=.ver) $(SYMTAB_OBJS) $(OBJS) - $(LD) -r -o kernel.o $(SYMTAB_OBJS) $(OBJS) - sync +include ../versions.mk sched.o: sched.c $(CC) $(CFLAGS) $(PROFILING) -fno-omit-frame-pointer -c $< - -dep: - $(CPP) -M *.c > .depend - -modules: - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v1.3.18/linux/kernel/ksyms.c Wed Aug 9 14:55:43 1995 +++ linux/kernel/ksyms.c Tue Aug 15 18:08:34 1995 @@ -37,7 +37,6 @@ #ifdef CONFIG_NET #include #include -#include #ifdef CONFIG_INET #include #include @@ -458,8 +457,8 @@ X(msdos_write_inode), #endif #ifdef CONFIG_PROC_FS - X(proc_net_register), - X(proc_net_unregister), + X(proc_register), + X(proc_unregister), #endif /******************************************************** * Do not add anything below this line, diff -u --recursive --new-file v1.3.18/linux/kernel/ksyms.ver linux/kernel/ksyms.ver --- v1.3.18/linux/kernel/ksyms.ver Tue Jun 6 11:22:14 1995 +++ linux/kernel/ksyms.ver Tue Aug 15 15:07:03 1995 @@ -192,3 +192,197 @@ #define __down _set_ver(__down, 75aa9e96) #endif /* _KSYMS_VER_ */ #endif /* CONFIG_MODVERSIONS !__GENKSYMS__ */ +/**** This file is generated by genksyms DO NOT EDIT! ****/ +#if defined(CONFIG_MODVERSIONS) && !defined(__GENKSYMS__) +#ifndef _KSYMS_VER_ +#define _KSYMS_VER_ +#define rename_module_symbol _set_ver(rename_module_symbol, b81c73c1) +#define register_symtab _set_ver(register_symtab, e910ea66) +#define EISA_bus _set_ver(EISA_bus, 7e37737c) +#define wp_works_ok _set_ver(wp_works_ok, f37f99e9) +#define verify_area _set_ver(verify_area, 4cfda560) +#define do_mmap _set_ver(do_mmap, 677e7ee1) +#define do_munmap _set_ver(do_munmap, 6221f117) +#define zeromap_page_range _set_ver(zeromap_page_range, 7c395a26) +#define unmap_page_range _set_ver(unmap_page_range, 0110085f) +#define insert_vm_struct _set_ver(insert_vm_struct, 1f4e4882) +#define merge_segments _set_ver(merge_segments, 6854be5a) +#define __get_free_pages _set_ver(__get_free_pages, 5243d78b) +#define free_pages _set_ver(free_pages, 96448859) +#define kmalloc _set_ver(kmalloc, d31fb2cb) +#define kfree_s _set_ver(kfree_s, 1e72eb79) +#define vmalloc _set_ver(vmalloc, 667f3e25) +#define vfree _set_ver(vfree, 6df52add) +#define getname _set_ver(getname, 81487159) +#define putname _set_ver(putname, b19e8126) +#define __iget _set_ver(__iget, ee2b6320) +#define iput _set_ver(iput, 59241ced) +#define namei _set_ver(namei, 00478bcd) +#define lnamei _set_ver(lnamei, fcfddbb1) +#define open_namei _set_ver(open_namei, 414b2b0f) +#define close_fp _set_ver(close_fp, 1d4c15d8) +#define check_disk_change _set_ver(check_disk_change, b66ed457) +#define invalidate_buffers _set_ver(invalidate_buffers, c65255f1) +#define fsync_dev _set_ver(fsync_dev, a221190d) +#define permission _set_ver(permission, 0ebf7474) +#define inode_setattr _set_ver(inode_setattr, 0c80a3c1) +#define inode_change_ok _set_ver(inode_change_ok, 5d1cb326) +#define generic_mmap _set_ver(generic_mmap, d4ff59f3) +#define set_blocksize _set_ver(set_blocksize, f45fda38) +#define getblk _set_ver(getblk, d40228ac) +#define bread _set_ver(bread, c73bf0f0) +#define breada _set_ver(breada, eb8e858c) +#define brelse _set_ver(brelse, 4c27ac3d) +#define ll_rw_block _set_ver(ll_rw_block, f3aa4dd3) +#define __wait_on_buffer _set_ver(__wait_on_buffer, e8fcc968) +#define dcache_lookup _set_ver(dcache_lookup, 83336566) +#define dcache_add _set_ver(dcache_add, fe71f11e) +#define register_chrdev _set_ver(register_chrdev, da99513f) +#define unregister_chrdev _set_ver(unregister_chrdev, 61ea5ee8) +#define register_blkdev _set_ver(register_blkdev, 4699a621) +#define unregister_blkdev _set_ver(unregister_blkdev, d39bbca9) +#define tty_register_driver _set_ver(tty_register_driver, fcc8591c) +#define tty_unregister_driver _set_ver(tty_unregister_driver, c78132a8) +#define tty_std_termios _set_ver(tty_std_termios, cf350678) +#define block_read _set_ver(block_read, a7fe4f51) +#define block_write _set_ver(block_write, 902674c9) +#define block_fsync _set_ver(block_fsync, 182888d8) +#define wait_for_request _set_ver(wait_for_request, 9ca2932e) +#define blksize_size _set_ver(blksize_size, dea1eb55) +#define hardsect_size _set_ver(hardsect_size, ed1ee14f) +#define blk_size _set_ver(blk_size, f60b5398) +#define blk_dev _set_ver(blk_dev, dbf5fdd4) +#define is_read_only _set_ver(is_read_only, b0c5f83e) +#define set_device_ro _set_ver(set_device_ro, 8fb69e13) +#define bmap _set_ver(bmap, 73bb8bdd) +#define sync_dev _set_ver(sync_dev, 9bca536d) +#define get_blkfops _set_ver(get_blkfops, 83827791) +#define register_serial _set_ver(register_serial, 3425f38c) +#define unregister_serial _set_ver(unregister_serial, c013d717) +#define tty_hangup _set_ver(tty_hangup, e3487df0) +#define tty_wait_until_sent _set_ver(tty_wait_until_sent, da85d428) +#define tty_check_change _set_ver(tty_check_change, 705eaab0) +#define tty_hung_up_p _set_ver(tty_hung_up_p, f99ac1e4) +#define register_filesystem _set_ver(register_filesystem, 1c7110ef) +#define unregister_filesystem _set_ver(unregister_filesystem, 5e353af7) +#define register_binfmt _set_ver(register_binfmt, 66ece706) +#define unregister_binfmt _set_ver(unregister_binfmt, 41822618) +#define lookup_exec_domain _set_ver(lookup_exec_domain, 32f10d48) +#define register_exec_domain _set_ver(register_exec_domain, eda4711f) +#define unregister_exec_domain _set_ver(unregister_exec_domain, 78ea447c) +#define request_irq _set_ver(request_irq, 9e81629c) +#define free_irq _set_ver(free_irq, f487dc0c) +#define enable_irq _set_ver(enable_irq, 54e09f5f) +#define disable_irq _set_ver(disable_irq, b4449c1f) +#define bh_active _set_ver(bh_active, 98fb5ca1) +#define bh_mask _set_ver(bh_mask, 1abf3d3f) +#define add_timer _set_ver(add_timer, f13cb728) +#define del_timer _set_ver(del_timer, c7aff713) +#define tq_timer _set_ver(tq_timer, 46cf583e) +#define tq_immediate _set_ver(tq_immediate, 46cf583e) +#define tq_scheduler _set_ver(tq_scheduler, 46cf583e) +#define tq_last _set_ver(tq_last, 457cf547) +#define timer_active _set_ver(timer_active, 5a6747ee) +#define timer_table _set_ver(timer_table, 9e03b650) +#define request_dma _set_ver(request_dma, 2a687646) +#define free_dma _set_ver(free_dma, 5d4b914c) +#define disable_hlt _set_ver(disable_hlt, 794487ee) +#define enable_hlt _set_ver(enable_hlt, 9c7077bd) +#define check_region _set_ver(check_region, b91154fb) +#define request_region _set_ver(request_region, 138b0a1e) +#define release_region _set_ver(release_region, f41d6d31) +#define wake_up _set_ver(wake_up, e8d71419) +#define wake_up_interruptible _set_ver(wake_up_interruptible, 64c8cb92) +#define sleep_on _set_ver(sleep_on, 67a00cee) +#define interruptible_sleep_on _set_ver(interruptible_sleep_on, 6a5fc80d) +#define schedule _set_ver(schedule, 01000e51) +#define current _set_ver(current, fc1cb29b) +#define jiffies _set_ver(jiffies, 2f7c7437) +#define xtime _set_ver(xtime, e70c0be0) +#define loops_per_sec _set_ver(loops_per_sec, 40a14192) +#define need_resched _set_ver(need_resched, dfc016ea) +#define kill_proc _set_ver(kill_proc, 911f760a) +#define kill_pg _set_ver(kill_pg, 0a758a45) +#define kill_sl _set_ver(kill_sl, 49625e94) +#define panic _set_ver(panic, 400c0de3) +#define printk _set_ver(printk, ad1148ba) +#define sprintf _set_ver(sprintf, f9003107) +#define vsprintf _set_ver(vsprintf, e605cb6b) +#define simple_strtoul _set_ver(simple_strtoul, bdb8c1e3) +#define system_utsname _set_ver(system_utsname, 066845bc) +#define sys_call_table _set_ver(sys_call_table, 79fa4011) +#define do_signal _set_ver(do_signal, 86f9bc59) +#define send_sig _set_ver(send_sig, 5cddd8d9) +#define setup_arg_pages _set_ver(setup_arg_pages, fe68d94a) +#define copy_strings _set_ver(copy_strings, 232aee96) +#define create_tables _set_ver(create_tables, ba788fa2) +#define do_execve _set_ver(do_execve, 8c99dc0a) +#define flush_old_exec _set_ver(flush_old_exec, c737e178) +#define open_inode _set_ver(open_inode, 27302cb6) +#define read_exec _set_ver(read_exec, a80a2dd0) +#define si_meminfo _set_ver(si_meminfo, bb05fc9a) +#define sock_register _set_ver(sock_register, d68e1649) +#define sock_unregister _set_ver(sock_unregister, 72c332bd) +#define inet_add_protocol _set_ver(inet_add_protocol, 55292121) +#define inet_del_protocol _set_ver(inet_del_protocol, 73908a1b) +#define slhc_init _set_ver(slhc_init, e490a4b8) +#define slhc_free _set_ver(slhc_free, 39ab902b) +#define slhc_remember _set_ver(slhc_remember, db333be6) +#define slhc_compress _set_ver(slhc_compress, e753e2d2) +#define slhc_uncompress _set_ver(slhc_uncompress, 81cc1144) +#define register_netdevice_notifier _set_ver(register_netdevice_notifier, e7aace7c) +#define unregister_netdevice_notifier _set_ver(unregister_netdevice_notifier, be114416) +#define floppy_track_buffer _set_ver(floppy_track_buffer, c6e3f7c2) +#define register_netdev _set_ver(register_netdev, 0d8d1bb4) +#define unregister_netdev _set_ver(unregister_netdev, 25a99579) +#define ether_setup _set_ver(ether_setup, 4eafef91) +#define alloc_skb _set_ver(alloc_skb, b6b523ba) +#define kfree_skb _set_ver(kfree_skb, 0b938572) +#define dev_kfree_skb _set_ver(dev_kfree_skb, aa1fe7f4) +#define netif_rx _set_ver(netif_rx, d8051cb2) +#define dev_rint _set_ver(dev_rint, 040d3f4b) +#define dev_tint _set_ver(dev_tint, 860b350b) +#define irq2dev_map _set_ver(irq2dev_map, 10bdcd8a) +#define dev_add_pack _set_ver(dev_add_pack, 6d7d9be4) +#define dev_remove_pack _set_ver(dev_remove_pack, 784fa59f) +#define dev_get _set_ver(dev_get, 72ed90fd) +#define dev_ioctl _set_ver(dev_ioctl, 08760203) +#define dev_queue_xmit _set_ver(dev_queue_xmit, 4a478225) +#define dev_base _set_ver(dev_base, 0a8809f0) +#define dev_close _set_ver(dev_close, 9bdad56d) +#define arp_find _set_ver(arp_find, a141bd11) +#define n_tty_ioctl _set_ver(n_tty_ioctl, 538e5fa6) +#define tty_register_ldisc _set_ver(tty_register_ldisc, 8fdde939) +#define kill_fasync _set_ver(kill_fasync, 890501b6) +#define in_scan_scsis _set_ver(in_scan_scsis, 21874a88) +#define scsi_register_module _set_ver(scsi_register_module, 8eff1010) +#define scsi_unregister_module _set_ver(scsi_unregister_module, d913b8f0) +#define scsi_free _set_ver(scsi_free, 475dddfa) +#define scsi_malloc _set_ver(scsi_malloc, 1cce3f92) +#define scsi_register _set_ver(scsi_register, d6e77069) +#define scsi_unregister _set_ver(scsi_unregister, 3b0b616b) +#define scsicam_bios_param _set_ver(scsicam_bios_param, 3d965248) +#define scsi_init_malloc _set_ver(scsi_init_malloc, e5167cbc) +#define scsi_init_free _set_ver(scsi_init_free, 8b2721f8) +#define print_command _set_ver(print_command, 6f14cd75) +#define print_msg _set_ver(print_msg, 0465f877) +#define print_status _set_ver(print_status, 32f84646) +#define set_writetime _set_ver(set_writetime, 52131916) +#define sys_tz _set_ver(sys_tz, aa3c9782) +#define __wait_on_super _set_ver(__wait_on_super, 61a5c00a) +#define file_fsync _set_ver(file_fsync, d30a190f) +#define clear_inode _set_ver(clear_inode, da2b0e9f) +#define refile_buffer _set_ver(refile_buffer, 8c69e123) +#define ___strtok _set_ver(___strtok, 8b55d69c) +#define init_fifo _set_ver(init_fifo, 082629c7) +#define super_blocks _set_ver(super_blocks, e1f1ee99) +#define chrdev_inode_operations _set_ver(chrdev_inode_operations, 6ba1faa3) +#define blkdev_inode_operations _set_ver(blkdev_inode_operations, ed443696) +#define read_ahead _set_ver(read_ahead, bbcd3768) +#define get_hash_table _set_ver(get_hash_table, 3b5f3c55) +#define get_empty_inode _set_ver(get_empty_inode, 554bdc75) +#define insert_inode_hash _set_ver(insert_inode_hash, 59b8c371) +#define event _set_ver(event, a6aac9c1) +#define __down _set_ver(__down, 75aa9e96) +#endif /* _KSYMS_VER_ */ +#endif /* CONFIG_MODVERSIONS !__GENKSYMS__ */ diff -u --recursive --new-file v1.3.18/linux/lib/Makefile linux/lib/Makefile --- v1.3.18/linux/lib/Makefile Tue Jul 11 10:03:00 1995 +++ linux/lib/Makefile Tue Aug 15 15:07:03 1995 @@ -6,20 +6,8 @@ # unless it's something special (ie not a .c file). # -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c $< - -OBJS = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \ - execve.o wait.o string.o vsprintf.o - -lib.a: $(OBJS) - $(AR) rcs lib.a $(OBJS) - sync - -modules: -dep: - $(CPP) -M *.c > .depend +L_TARGET := lib.a +L_OBJS := ctype.o _exit.o open.o close.o errno.o write.o dup.o \ + setsid.o execve.o wait.o string.o vsprintf.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/mm/Makefile linux/mm/Makefile --- v1.3.18/linux/mm/Makefile Tue Jul 11 10:03:00 1995 +++ linux/mm/Makefile Tue Aug 15 15:07:03 1995 @@ -7,20 +7,7 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS = memory.o swap.o mmap.o filemap.o mprotect.o kmalloc.o vmalloc.o - -mm.o: $(OBJS) - $(LD) -r -o mm.o $(OBJS) - -modules: - -dep: - $(CPP) -M *.c > .depend - +O_TARGET := mm.o +O_OBJS := memory.o swap.o mmap.o filemap.o mprotect.o kmalloc.o vmalloc.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/802/Makefile linux/net/802/Makefile --- v1.3.18/linux/net/802/Makefile Wed Aug 9 14:55:43 1995 +++ linux/net/802/Makefile Tue Aug 15 15:07:03 1995 @@ -7,44 +7,24 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - - -OBJS := p8023.o +O_TARGET := 802.o +O_OBJS = p8023.o ifdef CONFIG_TR - -OBJS := $(OBJS) tr.o - +O_OBJS += tr.o endif ifdef CONFIG_IPX - -OBJS := $(OBJS) p8022.o psnap.o - +O_OBJS += p8022.o psnap.o endif ifdef CONFIG_ATALK ifndef CONFIG_IPX - -OBJS := $(OBJS) p8022.o psnap.o - +O_OBJS += p8022.o psnap.o endif endif -802.o: $(OBJS) - $(LD) -r -o 802.o $(OBJS) - - -dep: - $(CPP) -M *.c > .depend +include $(TOPDIR)/Rules.make tar: tar -cvf /dev/f1 . - -modules: - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/Makefile linux/net/Makefile --- v1.3.18/linux/net/Makefile Wed Aug 9 14:55:43 1995 +++ linux/net/Makefile Tue Aug 15 15:07:03 1995 @@ -7,32 +7,10 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -SUBDIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom - -SUBOBJS := $(foreach f,$(SUBDIRS),$f/$f.o) - -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS = socket.o protocols.o - -all: network.a - -network.a: subdirs $(OBJS) - rm -f $@ - $(AR) rcs $@ $(OBJS) $(SUBOBJS) - -subdirs: dummy - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done - -dep: - $(CPP) -M *.c > .depend - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i dep; done - -modules: dummy - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i modules; done - +MOD_SUB_DIRS := ipv4 +ALL_SUB_DIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom +SUB_DIRS := $(ALL_SUB_DIRS) +L_TARGET := network.a +L_OBJS := socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o)) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/appletalk/Makefile linux/net/appletalk/Makefile --- v1.3.18/linux/net/appletalk/Makefile Wed Aug 9 14:55:43 1995 +++ linux/net/appletalk/Makefile Tue Aug 15 15:07:03 1995 @@ -7,23 +7,10 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< +O_TARGET := appletalk.o +O_OBJS := aarp.o ddp.o - -OBJS := aarp.o ddp.o - - -appletalk.o: $(OBJS) - $(LD) -r -o appletalk.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend +include $(TOPDIR)/Rules.make tar: tar -cvf /dev/f1 . -modules: - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c --- v1.3.18/linux/net/appletalk/aarp.c Mon Jul 31 15:59:03 1995 +++ linux/net/appletalk/aarp.c Mon Aug 14 15:49:55 1995 @@ -584,7 +584,7 @@ * Frame size ok ? */ - if(skb_pull(skb,sizeof(*ea)) .depend +include $(TOPDIR)/Rules.make tar: tar -cvf /dev/f1 . - -modules: - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c --- v1.3.18/linux/net/ax25/af_ax25.c Sun Aug 13 14:45:35 1995 +++ linux/net/ax25/af_ax25.c Tue Aug 15 14:45:20 1995 @@ -2031,12 +2031,24 @@ dev_add_pack(&bpq_packet_type); register_netdevice_notifier(&ax25_dev_notifier); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_AX25_ROUTE, 10, "ax25_route", ax25_rt_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_AX25, 4, "ax25", ax25_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_AX25_CALLS, 10, "ax25_calls", ax25_cs_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_AX25_ROUTE, 10, "ax25_route", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ax25_rt_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_AX25, 4, "ax25", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ax25_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_AX25_CALLS, 10, "ax25_calls", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ax25_cs_get_info + }); printk("GW4PTS/G4KLX AX.25 for Linux. Version 0.30 ALPHA for Linux NET3.030 (Linux 1.3.0)\n"); } diff -u --recursive --new-file v1.3.18/linux/net/core/Makefile linux/net/core/Makefile --- v1.3.18/linux/net/core/Makefile Wed Aug 9 14:55:44 1995 +++ linux/net/core/Makefile Tue Aug 15 15:07:03 1995 @@ -7,32 +7,13 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - - -OBJS := sock.o dev.o dev_mcast.o skbuff.o datagram.o iovec.o +O_TARGET := core.o ifdef CONFIG_NET - -core.o: $(OBJS) - $(LD) -r -o core.o $(OBJS) - -else - -core.o: - $(AR) rcs core.o - +O_OBJS := sock.o dev.o dev_mcast.o skbuff.o datagram.o iovec.o endif -dep: - $(CPP) -M *.c > .depend +include $(TOPDIR)/Rules.make tar: tar -cvf /dev/f1 . - -modules: - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/core/dev.c linux/net/core/dev.c --- v1.3.18/linux/net/core/dev.c Sun Aug 13 14:45:36 1995 +++ linux/net/core/dev.c Tue Aug 15 14:45:20 1995 @@ -70,6 +70,7 @@ #include #include #include +#include /* * The list of packet types we will receive (as opposed to discard) @@ -1320,8 +1321,12 @@ dev2 = dev; } } -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_DEV, 3, "dev", dev_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_DEV, 3, "dev", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + dev_get_info + }); } diff -u --recursive --new-file v1.3.18/linux/net/core/skbuff.c linux/net/core/skbuff.c --- v1.3.18/linux/net/core/skbuff.c Fri Jul 7 13:42:58 1995 +++ linux/net/core/skbuff.c Mon Aug 14 15:49:05 1995 @@ -379,14 +379,14 @@ return skb->data; } -int skb_pull(struct sk_buff *skb, int len) +unsigned char * skb_pull(struct sk_buff *skb, int len) { IS_SKB(skb); if(len>skb->len) - len=skb->len; + return 0; skb->data+=len; skb->len-=len; - return len; + return skb->data; } int skb_headroom(struct sk_buff *skb) diff -u --recursive --new-file v1.3.18/linux/net/ethernet/Makefile linux/net/ethernet/Makefile --- v1.3.18/linux/net/ethernet/Makefile Wed Aug 9 14:55:44 1995 +++ linux/net/ethernet/Makefile Tue Aug 15 15:07:03 1995 @@ -7,46 +7,23 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - +O_TARGET := ethernet.o OBJS := eth.o ifdef CONFIG_IPX - OBJ2 := pe2.o - endif ifdef CONFIG_ATALK - OBJ2 := pe2.o - endif -OBJS := $(OBJS) $(OBJ2) - ifdef CONFIG_NET - -ethernet.o: $(OBJS) - $(LD) -r -o ethernet.o $(OBJS) - -else - -ethernet.o: - $(AR) rcs ethernet.o - +O_OBJS := $(OBJS) $(OBJ2) endif -dep: - $(CPP) -M *.c > .depend +include $(TOPDIR)/Rules.make tar: - tar -cvf /dev/f1 . - -modules: - -include $(TOPDIR)/Rules.make + tar -cvf /dev/f1 . diff -u --recursive --new-file v1.3.18/linux/net/ethernet/eth.c linux/net/ethernet/eth.c --- v1.3.18/linux/net/ethernet/eth.c Tue Jul 18 16:28:59 1995 +++ linux/net/ethernet/eth.c Mon Aug 14 12:24:22 1995 @@ -239,23 +239,27 @@ { struct ethhdr *eth; struct iphdr *iph; + int ip_length; IS_SKB(dest); eth=(struct ethhdr *)dest->data; - memcpy(dest->data,src,34); /* ethernet is always >= 60 */ - length-=34; if(eth->h_proto!=htons(ETH_P_IP)) { - memcpy(dest->data+34,src+34,length); + memcpy(dest->data,src,length); return; } /* * We have to watch for padded packets. The csum doesn't include the * padding, and there is no point in copying the padding anyway. + * We have to use the smaller of length and ip_length because it + * can happen that ip_length > length. */ + memcpy(dest->data,src,34); /* ethernet is always >= 34 */ + length -= 34; iph=(struct iphdr*)(src+14); /* 14 = Rx_addr+Tx_addr+type_field */ - if (ntohs(iph->tot_len)-sizeof(struct iphdr) <= length) - length=ntohs(iph->tot_len)-sizeof(struct iphdr); + ip_length = ntohs(iph->tot_len) - sizeof(struct iphdr); + if (ip_length <= length) + length=ip_length; dest->csum=csum_partial_copy(src+34,dest->data+34,length,base); dest->ip_summed=1; diff -u --recursive --new-file v1.3.18/linux/net/ipv4/Makefile linux/net/ipv4/Makefile --- v1.3.18/linux/net/ipv4/Makefile Wed Aug 9 14:55:44 1995 +++ linux/net/ipv4/Makefile Tue Aug 15 15:07:03 1995 @@ -7,58 +7,23 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - +O_TARGET := ipv4.o IPV4_OBJS := utils.o route.o proc.o timer.o protocol.o packet.o \ arp.o ip.o raw.o icmp.o tcp.o udp.o devinet.o af_inet.o \ igmp.o ip_fw.o ipip.o -MODULES := - ifdef CONFIG_INET_RARP IPV4_OBJS := $(IPV4_OBJS) rarp.o else -MODULES := $(MODULES) rarp.o +M_OBJS := rarp.o +MOD_LIST_NAME := IPV4_MODULES endif ifdef CONFIG_INET - -ipv4.o: $(IPV4_OBJS) - $(LD) -r -o ipv4.o $(IPV4_OBJS) - -else - -ipv4.o: - $(AR) rcs ipv4.o - +O_OBJS := $(IPV4_OBJS) endif -ifdef MODULES -dep: - $(CPP) -M $(IPV4_OBJS:.o=.c) > .depend - $(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend -else -dep: - $(CPP) -M $(IPV4_OBJS:.o=.c) > .depend -endif +include $(TOPDIR)/Rules.make tar: tar -cvf /dev/f1 . - -ifdef MODULES - -modules: $(MODULES) - echo $(MODULES) > ../../modules/IPV4_MODULES - cd ../../modules; \ - for i in $(MODULES); do ln -sf ../net/ipv4/$$i .; done - -else - -modules: - -endif - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c --- v1.3.18/linux/net/ipv4/af_inet.c Sun Aug 13 14:45:36 1995 +++ linux/net/ipv4/af_inet.c Tue Aug 15 14:45:20 1995 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -1607,20 +1608,48 @@ #endif #ifdef CONFIG_INET_RARP -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_RARP, 4, "rarp", rarp_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_RARP, 4, "rarp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + rarp_get_info + }); rarp_ioctl_hook = rarp_ioctl; #endif -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_RAW, 3, "raw", raw_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_SNMP, 4, "snmp", snmp_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_SOCKSTAT, 8, "sockstat", afinet_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_TCP, 3, "tcp", tcp_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_UDP, 3, "udp", udp_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_ROUTE, 5, "route", rt_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_RAW, 3, "raw", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + raw_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_SNMP, 4, "snmp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + snmp_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_SOCKSTAT, 8, "sockstat", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + afinet_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_TCP, 3, "tcp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + tcp_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_UDP, 3, "udp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + udp_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_ROUTE, 5, "route", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + rt_get_info + }); } diff -u --recursive --new-file v1.3.18/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v1.3.18/linux/net/ipv4/arp.c Sun Aug 13 14:45:36 1995 +++ linux/net/ipv4/arp.c Tue Aug 15 14:45:20 1995 @@ -87,6 +87,7 @@ #endif #endif #include +#include /* @@ -687,9 +688,10 @@ memcpy(&tip,arp_ptr,4); /* - * Check for bad requests for 127.0.0.1. If this is one such, delete it. + * Check for bad requests for 127.x.x.x and requests for multicast + * addresses. If this is one such, delete it. */ - if(tip == INADDR_LOOPBACK) + if (IN_LOOPBACK(tip) || IN_MULTICAST(tip)) { kfree_skb(skb, FREE_READ); return 0; @@ -1460,7 +1462,11 @@ /* Register for device down reports */ register_netdevice_notifier(&arp_dev_notifier); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_ARP, 3, "arp", arp_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_ARP, 3, "arp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + arp_get_info + }); } diff -u --recursive --new-file v1.3.18/linux/net/ipv4/ip.c linux/net/ipv4/ip.c --- v1.3.18/linux/net/ipv4/ip.c Sun Aug 13 14:45:36 1995 +++ linux/net/ipv4/ip.c Tue Aug 15 14:45:20 1995 @@ -2820,8 +2820,12 @@ ip_udp_init();*/ #ifdef CONFIG_IP_MULTICAST - proc_net_register(&(struct proc_dir_entry) - { PROC_NET_IGMP, 4, "igmp", ip_mc_procinfo }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_IGMP, 4, "igmp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_mc_procinfo + }); #endif } diff -u --recursive --new-file v1.3.18/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c --- v1.3.18/linux/net/ipv4/ip_fw.c Sun Aug 13 14:45:36 1995 +++ linux/net/ipv4/ip_fw.c Tue Aug 15 14:45:20 1995 @@ -1550,17 +1550,33 @@ void ip_fw_init(void) { #ifdef CONFIG_IP_ACCT -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_IPACCT, 7, "ip_acct", ip_acct_procinfo }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_IPACCT, 7, "ip_acct", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_acct_procinfo + }); #endif #ifdef CONFIG_IP_FIREWALL -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_IPFWBLK, 8, "ip_block", ip_fw_blk_procinfo }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_IPFWFWD, 10, "ip_forward", ip_fw_fwd_procinfo }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_IPFWBLK, 8, "ip_block", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_fw_blk_procinfo + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_IPFWFWD, 10, "ip_forward", + S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_fw_fwd_procinfo + }); #endif #ifdef CONFIG_IP_MASQUERADE -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_IPMSQHST, 13, "ip_masquerade", ip_msqhst_procinfo }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_IPMSQHST, 13, "ip_masquerade", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_msqhst_procinfo + }); #endif } diff -u --recursive --new-file v1.3.18/linux/net/ipv4/rarp.c linux/net/ipv4/rarp.c --- v1.3.18/linux/net/ipv4/rarp.c Sun Aug 13 14:45:36 1995 +++ linux/net/ipv4/rarp.c Tue Aug 15 14:45:20 1995 @@ -199,8 +199,8 @@ /* * We shouldn't use this type conversion. Check later. */ - struct arphdr *rarp = (struct arphdr *)skb_pull(skb,sizeof(struct arphdr)); - unsigned char *rarp_ptr = skb->data; + struct arphdr *rarp = (struct arphdr *) skb->data; + unsigned char *rarp_ptr = skb_pull(skb,sizeof(struct arphdr)); struct rarp_table *entry; long sip,tip; unsigned char *sha,*tha; /* s for "source", t for "target" */ @@ -545,8 +545,12 @@ void rarp_init(void) { - proc_net_register(&(struct proc_dir_entry) - { PROC_NET_RARP, 4, "rarp", rarp_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_RARP, 4, "rarp", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + rarp_get_info + }); rarp_ioctl_hook = rarp_ioctl; } diff -u --recursive --new-file v1.3.18/linux/net/ipx/Makefile linux/net/ipx/Makefile --- v1.3.18/linux/net/ipx/Makefile Wed Aug 9 14:55:45 1995 +++ linux/net/ipx/Makefile Tue Aug 15 15:07:03 1995 @@ -7,24 +7,10 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< +O_TARGET := ipx.o +O_OBJS := af_ipx.o - -OBJS := af_ipx.o - - -ipx.o: $(OBJS) - $(LD) -r -o ipx.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend +include $(TOPDIR)/Rules.make tar: tar -cvf /dev/f1 . - -modules: - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c --- v1.3.18/linux/net/ipx/af_ipx.c Sun Aug 13 14:45:36 1995 +++ linux/net/ipx/af_ipx.c Tue Aug 15 14:45:20 1995 @@ -1969,12 +1969,24 @@ register_netdevice_notifier(&ipx_dev_notifier); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_IPX, 3, "ipx", ipx_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_IPX_INTERFACE, 13, "ipx_interface", ipx_interface_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_IPX_ROUTE, 9, "ipx_route", ipx_rt_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_IPX, 3, "ipx", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ipx_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_IPX_INTERFACE, 13, "ipx_interface", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ipx_interface_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_IPX_ROUTE, 9, "ipx_route", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ipx_rt_get_info + }); printk("Swansea University Computer Society IPX 0.31 for NET3.030\n"); printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n"); diff -u --recursive --new-file v1.3.18/linux/net/netrom/Makefile linux/net/netrom/Makefile --- v1.3.18/linux/net/netrom/Makefile Wed Aug 9 14:55:45 1995 +++ linux/net/netrom/Makefile Tue Aug 15 15:07:03 1995 @@ -7,29 +7,14 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - - -OBJS := af_netrom.o +O_TARGET := netrom.o +O_OBJS := af_netrom.o ifdef CONFIG_AX25 - -OBJS := $(OBJS) nr_dev.o nr_in.o nr_out.o nr_route.o nr_subr.o nr_timer.o - +O_OBJS += nr_dev.o nr_in.o nr_out.o nr_route.o nr_subr.o nr_timer.o endif -netrom.o: $(OBJS) - $(LD) -r -o netrom.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend +include $(TOPDIR)/Rules.make tar: tar -cvf /dev/f1 . - -modules: - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c --- v1.3.18/linux/net/netrom/af_netrom.c Sun Aug 13 14:45:37 1995 +++ linux/net/netrom/af_netrom.c Tue Aug 15 14:45:20 1995 @@ -1392,13 +1392,21 @@ nr_default.tries = NR_DEFAULT_N2; nr_default.window = NR_DEFAULT_WINDOW; -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_NR, 2, "nr", nr_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_NR_NEIGH, 8, "nr_neigh", nr_neigh_get_info }); -proc_net_register(&(struct proc_dir_entry) - { PROC_NET_NR_NODES, 8, "nr_nodes", nr_nodes_get_info }); - + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_NR, 2, "nr", + S_IFREG | S_IRUGO, 1, 0, 0, + nr_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_NR_NEIGH, 8, "nr_neigh", + S_IFREG | S_IRUGO, 1, 0, 0, + nr_neigh_get_info + }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_NR_NODES, 8, "nr_nodes", + S_IFREG | S_IRUGO, 1, 0, 0, + nr_nodes_get_info + }); } #endif diff -u --recursive --new-file v1.3.18/linux/net/unix/Makefile linux/net/unix/Makefile --- v1.3.18/linux/net/unix/Makefile Wed Aug 9 14:55:45 1995 +++ linux/net/unix/Makefile Tue Aug 15 15:07:03 1995 @@ -7,24 +7,10 @@ # # Note 2! The CFLAGS definition is now in the main makefile... -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< +O_TARGET := unix.o +O_OBJS := af_unix.o +include $(TOPDIR)/Rules.make -OBJS := af_unix.o - - -unix.o: $(OBJS) - $(LD) -r -o unix.o $(OBJS) - -dep: - $(CPP) -M *.c > .depend - -modules: tar: tar -cvf /dev/f1 . - - -include $(TOPDIR)/Rules.make diff -u --recursive --new-file v1.3.18/linux/net/unix/af_unix.c linux/net/unix/af_unix.c --- v1.3.18/linux/net/unix/af_unix.c Sun Aug 13 14:45:37 1995 +++ linux/net/unix/af_unix.c Tue Aug 15 14:45:20 1995 @@ -1016,8 +1016,12 @@ { printk("NET3: Unix domain sockets 0.07 BETA for Linux NET3.030.\n"); sock_register(unix_proto_ops.family, &unix_proto_ops); - proc_net_register(&(struct proc_dir_entry) - { PROC_NET_UNIX, 4, "unix", unix_get_info }); + proc_net_register(&(struct proc_dir_entry) { + PROC_NET_UNIX, 4, "unix", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + unix_get_info + }); } /* * Local variables: diff -u --recursive --new-file v1.3.18/linux/scripts/Configure linux/scripts/Configure --- v1.3.18/linux/scripts/Configure Thu Jan 1 02:00:00 1970 +++ linux/scripts/Configure Tue Aug 15 15:07:03 1995 @@ -0,0 +1,147 @@ +#! /bin/sh +# +# This script is used to configure the linux kernel. +# +# It was inspired by the challenge in the original Configure script +# to ``do something better'', combined with the actual need to ``do +# something better'' because the old configure script wasn't flexible +# enough. +# +# Please send comments / questions / bug fixes to raymondc@microsoft.com. +# +# Each line in the config file is a command. +# +# 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13 +# with an empty IFS. + +# +# Make sure we're really running bash. +# +# I would really have preferred to write this script in a language with +# better string handling, but alas, bash is the only scripting language +# that I can be reasonable sure everybody has on their linux machine. +# +[ -z "$BASH" ] && { echo "Configure requires bash" 1>&2; exit 1; } + +# Disable filename globbing once and for all. +# Enable function cacheing. +set -f -h + +# +# readln reads a line into $ans. +# +# readln prompt default +# +function readln () { + if [ "$DEFAULT" = "-d" ]; then + echo "$1" + ans=$2 + else + echo -n "$1" + IFS='@' read ans >$CONFIG + (echo "" ; echo "/*"; echo " * $1" ; echo " */") >>$CONFIG_H +} + +# +# bool processes a boolean argument +# +# bool question define default +# +function bool () { + ans="" + def=$(eval echo "\${$2:-$3}") + while [ "$ans" != "y" -a "$ans" != "n" ]; do + readln "$1 ($2) [$def] " "$def" + done + if [ "$ans" = "y" ]; then + echo "$2=y" >>$CONFIG + echo "#define $2 1" >>$CONFIG_H + else + echo "# $2 is not set" >>$CONFIG + echo "#undef $2" >>$CONFIG_H + fi + eval "$2=$ans" +} + +# +# int processes an integer argument +# +# int question define default +# +function int () { + # Slimier hack to get bash to rescan a line. + ans="x" + def=$(eval echo "\${$2:-$3}") + while [ $[$ans+0] != "$ans" ]; do + readln "$1 ($2) [$def] " "$def" + done + echo "$2=$ans" >>$CONFIG + echo "#define $2 ($ans)" >>$CONFIG_H + eval "$2=$ans" +} + +CONFIG=.tmpconfig +CONFIG_H=.tmpconfig.h +trap "rm -f $CONFIG $CONFIG_H ; exit 1" 1 2 + +# +# Make sure we start out with a clean slate. +# +echo "#" > $CONFIG +echo "# Automatically generated make config: don't edit" >> $CONFIG +echo "#" >> $CONFIG + +echo "/*" > $CONFIG_H +echo " * Automatically generated C config: don't edit" >> $CONFIG_H +echo " */" >> $CONFIG_H + +DEFAULT="" +if [ "$1" = "-d" ] ; then + DEFAULT="-d" + shift +fi + +CONFIG_IN=./config.in +if [ "$1" != "" ] ; then + CONFIG_IN=$1 +fi + +if [ -f ./.config ] ; then + . ./.config + sed -e 's/# \(.*\) is not.*/\1=n/' <./.config >/tmp/conf.$$ + . /tmp/conf.$$ + rm /tmp/conf.$$ +fi +. $CONFIG_IN + +if [ "$CONFIG_SOUND" = "y" ] ; then + $MAKE -C drivers/sound config || exit 1 +fi + +rm -f .config.old +if [ -f .config ]; then + mv .config .config.old +fi +mv .tmpconfig .config +mv .tmpconfig.h include/linux/autoconf.h + +echo +echo "The linux kernel is now hopefully configured for your setup." +echo "Check the top-level Makefile for additional configuration," +echo "and do a 'make dep ; make clean' if you want to be sure all" +echo "the files are correctly re-made" +echo + +exit 0 diff -u --recursive --new-file v1.3.18/linux/scripts/depend.awk linux/scripts/depend.awk --- v1.3.18/linux/scripts/depend.awk Thu Jan 1 02:00:00 1970 +++ linux/scripts/depend.awk Tue Aug 15 19:26:55 1995 @@ -0,0 +1,101 @@ +# This is an awk script which does dependencies. We do NOT want it to +# recursivly follow #include directives. +# +# The HPATH environment variable should be set to indicate where to look +# for include files. The -I infront of the path is optional. + +# +# Surely there is a more elegant way to see if a file exists. Anyone know +# what it is? +# +function fileExists(f, TMP, dummy, result) { + if(result=FILEHASH[f]) { + if(result=="Yes") { + return "Yes" + } else {return ""} + } + ERRNO="" + getline dummy < f + if(!length(ERRNO)) { + close(f) + return FILEHASH[f]="Yes" + } else { + FILEHASH[f]="No" + return "" + } +} + +BEGIN{ + hasdep=0 + if(!(TOPDIR=ENVIRON["TOPDIR"])) { + print "Environment variable TOPDIR is not set" + exit 1 + } + split(ENVIRON["HPATH"],parray," ") + for(path in parray) { + sub("^-I","",parray[path]) + sub("[/ ]*$","",parray[path]) + } +} + +/^#[ ]*include[ ]*[<"][^ ]*[>"]/{ + found=0 + if(LASTFILE!=FILENAME) { + if (hasdep) { + print cmd + } + hasdep=0 + cmd="" + LASTFILE=FILENAME + depname=FILENAME + relpath=FILENAME + sub("\\.c",".o: ",depname) + sub("\\.S",".o: ",depname) + if (depname==FILENAME) { + cmd="\n\t@touch "depname + } + sub("\\.h",".h: ",depname) + if(relpath ~ "^\\." ) { + sub("[^/]*$","", relpath) + relpath=relpath"/" + sub("//","/", relpath) + } else { + relpath="" + } + } + fname=$0 + sub("^#[ ]*include[ ]*[<\"]","",fname) + sub("[>\"].*","",fname) + if(fileExists(relpath""fname)) { + found=1 + if (!hasdep) { + printf "%s", depname + } + hasdep=1 + printf " \\\n %s", relpath""fname + if(fname ~ "^\\." ) { + if(!relpath in ARGV) { + ARGV[ARGC]=relpath""fname + ++ARGC + } + } + } else { + for(path in parray) { + if(fileExists(parray[path]"/"fname)) { + shortp=parray[path] + found=1 + if (!hasdep) { + printf "%s", depname + } + hasdep=1 + printf " \\\n %s", parray[path]"/"fname + } + } + } +} + +END{ + if (hasdep) { + print cmd + } +} diff -u --recursive --new-file v1.3.18/linux/scripts/hfiles.sh linux/scripts/hfiles.sh --- v1.3.18/linux/scripts/hfiles.sh Thu Jan 1 02:00:00 1970 +++ linux/scripts/hfiles.sh Tue Aug 15 15:07:03 1995 @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script looks to see if a directory contains .h files +# +for dir in $@; do + for hfile in $dir/*.h; do + if [ -f $hfile ]; then echo $dir; fi + break + done +done +exit 0 diff -u --recursive --new-file v1.3.18/linux/scripts/pathdown.sh linux/scripts/pathdown.sh --- v1.3.18/linux/scripts/pathdown.sh Thu Jan 1 02:00:00 1970 +++ linux/scripts/pathdown.sh Tue Aug 15 15:07:03 1995 @@ -0,0 +1,13 @@ +#!/bin/sh +UP= +DN=${PWD:?} +TP=${TOPDIR:?} + +while [ ! $TP/$UP/. -ef $DN ] ;do + UP=`basename $PWD`/$UP + cd .. + if [ "$PWD" = "/" ]; then echo "Lost"; exit 1; fi +done + +echo $UP +exit 0