diff -u --recursive --new-file v2.3.24/linux/CREDITS linux/CREDITS --- v2.3.24/linux/CREDITS Fri Oct 22 13:21:43 1999 +++ linux/CREDITS Mon Nov 1 10:31:34 1999 @@ -31,6 +31,12 @@ S: University of Limerick S: Ireland +N: Tigran A. Aivazian +E: tigran@ocston.org +W: http://www.ocston.org/~tigran +D: BFS filesystem +S: United Kingdom + N: Werner Almesberger E: werner.almesberger@lrc.di.epfl.ch D: dosfs, LILO, some fd features, various other hacks here and there @@ -280,6 +286,10 @@ D: Configuration help text support D: Linux CD and Support Giveaway List +N: Erik Inge Bolsų +E: knan@mo.himolde.no +D: Misc kernel hacks + N: Zoltan Boszormenyi E: zboszor@mol.hu D: MTRR emulation with Cyrix style ARR registers @@ -1772,8 +1782,8 @@ S: Germany N: Stephen Rothwell -E: Stephen.Rothwell@canb.auug.org.au -W: http://www.canb.auug.org.au/~sfr +E: sfr@linuxcare.com +W: http://linuxcare.com.au/sfr P: 1024/BD8C7805 CD A4 9D 01 10 6E 7E 3B 91 88 FA D9 C8 40 AA 02 D: Boot/setup/build work for setup > 2K D: Author, APM driver @@ -2207,9 +2217,10 @@ N: Tim Waugh E: tim@cyberelk.demon.co.uk D: Co-architect of the parallel-port sharing system -S: 4 Fox Close -S: Bishopstoke -S: SO50 8NB +S: 34 Bladon Close +S: GUILDFORD +S: Surrey +S: GU1 1TY S: United Kingdom N: Juergen Weigert diff -u --recursive --new-file v2.3.24/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.3.24/linux/Documentation/Configure.help Wed Oct 27 16:34:12 1999 +++ linux/Documentation/Configure.help Fri Oct 29 13:19:49 1999 @@ -7970,6 +7970,21 @@ compiled as a module, and so this could be dangerous. Most everyone wants to say Y here. +SCO UnixWare BFS Support +CONFIG_BFS_FS + Boot Filesystem (BFS) is a filesystem used under SCO UnixWare to + allow bootloader access the kernel image and other important files + during the boot process. It is usually mounted under /stand and + corresponds to the slice marked as "STAND" in the UnixWare + partition. This is useful if you want to access files on your /stand + slice from Linux. If you don't know what it is, say N. + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read Documentation/modules.txt. The module will be + called bfs.o. Note that the filesystem of your root partition (the + one containing the directory /) cannot be compiled as a module. + ISO 9660 CDROM filesystem support CONFIG_ISO9660_FS This is the standard filesystem used on CDROMs. It was previously @@ -9881,7 +9896,7 @@ lead to all sorts of problems. You can safely say Y even if your machine doesn't have MTRRs, you'll - just add about 3k to your kernel. + just add about 9K to your kernel. See Documentation/mtrr.txt for more information. @@ -9938,9 +9953,15 @@ APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with APM compliant BIOSes. If you say Y here, the system time will be - reset after a USER RESUME operation, the /proc/apm device will - provide battery status information, and user-space programs will - receive notification of APM "events" (e.g., battery status change). + reset after a RESUME operation, the /proc/apm device will provide + battery status information, and user-space programs will receive + notification of APM "events" (e.g. battery status change). + + If you select "Y" here, you can disable actual use of the APM + BIOS by passing the "apm=off" option to the kernel at boot time. + + Note that the APM support is almost completely disabled for + machines with more than one CPU. Supporting software is available; for more information, read the Battery Powered Linux mini-HOWTO, available from @@ -9953,9 +9974,7 @@ This driver does not support the TI 4000M TravelMate and the ACER 486/DX4/75 because they don't have compliant BIOSes. Many "green" desktop machines also don't have compliant BIOSes, and this driver - will cause those machines to panic during the boot phase (typically, - these machines are using a data segment of 0040, which is reserved - for the Linux kernel). + may cause those machines to panic during the boot phase. If you are running Linux on a laptop, you may also want to read the Linux Laptop home page on the WWW at @@ -13030,7 +13049,7 @@ # LocalWords: EBSA chattr RiscOS Winmodem AGP Atomwide DUALSP pcsp robinson CT # LocalWords: SGALAXY Waverider DSPxxx TRXPRO AudioTrix OSWF MOT CFB DSY kbps # LocalWords: tuwien kkudielk LVD mega lun MAXTAGS Gbps arcnet Olicom SKTR SNA -# LocalWords: SysKonnect sktr sna etherboot ufs NetBEUI MultiSound MSNDCLAS GX +# LocalWords: SysKonnect tms380tr sna etherboot ufs NetBEUI MultiSound MSNDCLAS GX # LocalWords: MSNDINIT MSNDPERM MSNDPIN PNDSPINI PNDSPERM Ensoniq's RetinaZ SS # LocalWords: AudioPCI lspci SonicVibes sonicvibes SPARCs roadrunner CLgen UPA # LocalWords: swansea shtml Zoltrix zoltrix BINUTILS EGCS binutils VIDC DACs diff -u --recursive --new-file v2.3.24/linux/Documentation/filesystems/00-INDEX linux/Documentation/filesystems/00-INDEX --- v2.3.24/linux/Documentation/filesystems/00-INDEX Tue Sep 7 12:14:05 1999 +++ linux/Documentation/filesystems/00-INDEX Thu Oct 28 14:45:16 1999 @@ -4,6 +4,8 @@ - info and mount options for the Acorn Advanced Disc Filing System. affs.txt - info and mount options for the Amiga Fast File System. +bfs.txt + - info for the SCO UnixWare Boot Filesystem (BFS). coda.txt - description of the CODA filesystem. fat_cvf.txt diff -u --recursive --new-file v2.3.24/linux/Documentation/filesystems/bfs.txt linux/Documentation/filesystems/bfs.txt --- v2.3.24/linux/Documentation/filesystems/bfs.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/filesystems/bfs.txt Thu Oct 28 14:45:16 1999 @@ -0,0 +1,54 @@ +The BFS filesystem is used on SCO UnixWare machines for /stand slice. +There are no special mount options supported by bfs at this time. +You can mount it only read-only at this stage. Even if you attempt to +mount it read-write it will be automatically mounted read-only, unless +you have enabled "BFS write support" when configuring the kernel. + +In order to access /stand partition under Linux you obviously need to +know the partition number and the kernel must support UnixWare disk slices +(CONFIG_UNIXWARE_DISKLABEL config option). However BFS support does not +depend on having UnixWare disklabel support because one can also mount +BFS filesystem via loopback: + +# losetup /dev/loop0 stand.img +# mount -t bfs /dev/loop0 /mnt/stand + +where stand.img is a file containing the image of BFS filesystem. +When you have finished using it and umounted you need to also deallocate +/dev/loop0 device by: + +# losetup -d /dev/loop0 + +You can simplify mounting by just typing: + +# mount -t bfs -o loop stand.img /mnt/stand + +this will allocate the first available loopback device (and load loop.o +kernel module if necessary) automatically. Beware that umount will not +deallocate /dev/loopN device if /etc/mtab file on your system is a +symbolic link to /proc/mounts. You will need to do it manually using +"-d" switch of losetup(8). Read losetup(8) manpage for more info. + +To create the BFS image under UnixWare you need to find out first which +slice contains it. The command prtvtoc(1M) is your friend: + +# prtvtoc /dev/rdsk/c0b0t0d0s0 + +(assuming your root disk is on target=0, lun=0, bus=0, controller=0). Then you +look for the slice with tag "STAND", which is usually slice 10. With this +information you can use dd(1) to create the BFS image: + +# umount /stand +# dd if=/dev/rdsk/c0b0t0d0sa of=stand.img bs=512 + +Just in case, you can verify that you have done the right thing by checking +the magic number: + +# od -Ad -tx4 stand.img | more + +The first 4 bytes should be 0x1BADFACE. + +If you have any questions or suggestions regarding this BFS implementation +please contact me: + +Tigran A. Aivazian . diff -u --recursive --new-file v2.3.24/linux/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt --- v2.3.24/linux/Documentation/kernel-parameters.txt Sat Oct 9 11:47:50 1999 +++ linux/Documentation/kernel-parameters.txt Mon Nov 1 10:31:34 1999 @@ -11,7 +11,7 @@ restrictions referred to are that the relevant option is valid if: APIC APIC support is enabled. - APM Automatic Power Management support is enabled. + APM Advanced Power Management support is enabled. AX25 Appropriate AX.25 support is enabled. CD Appropriate CD support is enabled. EIDE EIDE/ATAPI support is enabled. @@ -20,6 +20,7 @@ ISDN Appropriate ISDN support is enabled. JOY Appropriate joystick support is enabled. LP Printer support is enabled. + LOOP Loopback device support is enabled. MCA MCA bus support is enabled. MDA The MDA console is enabled. MOUSE Appropriate mouse support is enabled. @@ -65,7 +66,7 @@ AM53C974= [HW,SCSI] - apm= [APM] Automatic Power Management. + apm= [APM] Advanced Power Management. arcrimi= [HW,NET] @@ -207,6 +208,9 @@ ltpc= [HW] mac5380= [HW,SCSI] + + max_loop=[0-255] [LOOP] States the maximum number of loopback devices + that can be mounted. maxcpus= [SMP] States the maximum number of processors that an SMP kernel should make use of. diff -u --recursive --new-file v2.3.24/linux/MAINTAINERS linux/MAINTAINERS --- v2.3.24/linux/MAINTAINERS Wed Oct 27 16:34:12 1999 +++ linux/MAINTAINERS Sat Oct 30 09:42:30 1999 @@ -128,9 +128,10 @@ APM DRIVER P: Stephen Rothwell -M: Stephen.Rothwell@canb.auug.org.au +M: sfr@linuxcare.com L: linux-laptop@vger.rutgers.edu -S: Maintained +W: http://linuxcare.com.au/apm/ +S: Supported APPLETALK NETWORK LAYER P: Jay Schulist @@ -145,10 +146,9 @@ ARM PORT P: Russell King -M: linux@arm.uk.linux.org +M: linux@arm.linux.org.uk L: linux-arm@vger.rutgers.edu -L: arm-linux@tardis.ed.ac.uk -W: http://www.arm.uk.linux.org/~rmk/armlinux.html +W: http://www.arm.linux.org.uk/~rmk/armlinux.html S: Maintained ARPD SUPPORT @@ -176,6 +176,13 @@ W: http://ftp.bitgate.com/pcwd/ S: Maintained +BFS FILE SYSTEM +P: Tigran A. Aivazian +M: tigran@ocston.org +L: linux-kernel@vger.rutgers.edu +W: http://www.ocston.org/~tigran/patches/bfs +S: Maintained + BUSLOGIC SCSI DRIVER P: Leonard N. Zubkoff M: Leonard N. Zubkoff @@ -896,6 +903,8 @@ UDF FILESYSTEM P: Ben Fennema M: bfennema@falcon.csc.calpoly.edu +P: Dave Boynton +M: dave@trylinux.com L: linux_udf@hootie.lvld.hp.com W: http://www.trylinux.com/projects/udf/index.html S: Maintained diff -u --recursive --new-file v2.3.24/linux/Makefile linux/Makefile --- v2.3.24/linux/Makefile Wed Oct 27 16:34:12 1999 +++ linux/Makefile Fri Oct 29 15:38:02 1999 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 24 +SUBLEVEL = 25 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) @@ -250,9 +250,6 @@ symlinks: rm -f include/asm ( cd include ; ln -sf asm-$(ARCH) asm) - @if [ ! -d modules ]; then \ - mkdir modules; \ - fi @if [ ! -d include/linux/modules ]; then \ mkdir include/linux/modules; \ fi @@ -331,7 +328,11 @@ modules: $(patsubst %, _mod_%, $(SUBDIRS)) -$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h include/config/MARKER +modules/MARKER: + mkdir modules + touch modules/MARKER + +$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h include/config/MARKER modules/MARKER $(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules modules_install: @@ -392,10 +393,8 @@ rm -f drivers/sound/bin2hex drivers/sound/hex2hex rm -f net/khttpd/make_times_h rm -f net/khttpd/times.h - if [ -d modules ]; then \ - rm -f core `find modules/ -type f -print`; \ - fi rm -f submenu* + rm -rf modules mrproper: clean archmrproper rm -f include/linux/autoconf.h include/linux/version.h @@ -416,7 +415,6 @@ rm -f .hdepend scripts/mkdep scripts/split-include rm -f $(TOPDIR)/include/linux/modversions.h rm -rf $(TOPDIR)/include/linux/modules - rm -rf modules distclean: mrproper rm -f core `find . \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ diff -u --recursive --new-file v2.3.24/linux/arch/arm/Makefile linux/arch/arm/Makefile --- v2.3.24/linux/arch/arm/Makefile Fri Oct 22 13:21:43 1999 +++ linux/arch/arm/Makefile Thu Oct 28 10:16:02 1999 @@ -16,10 +16,10 @@ OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S CPP := $(CC) -E PERL := perl -LINKFLAGS := -X -T arch/arm/vmlinux.lds +LINKFLAGS := -p -X -T arch/arm/vmlinux.lds ARCHCC := $(word 1,$(CC)) - +AFLAGS += -mno-fpu CFLAGS_PIPE := -pipe CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) @@ -31,6 +31,15 @@ CFLAGS += -g endif +# Ensure this is ld "2.9.4" or later +NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi) + +ifneq ($(NEW_LINKER),y) +dummy:; @echo '*** 2.3 kernels no longer build correctly with old versions of binutils.' + @echo '*** Please upgrade your binutils to 2.9.5.' + @false +endif + # GCC 2.7 uses different options to later compilers; sort out which we have NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi) @@ -55,21 +64,6 @@ CFLAGS_SA110 := -m6 endif -# See if this is ld "2.9.4" or later -NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi) - -ifeq ($(NEW_LINKER),y) -AFLAGS += -mno-fpu -AFLAGS_PROC_CPU_26 := -mapcs-26 -AFLAGS_PROC_CPU_32v3 := -mapcs-32 -marmv3m -AFLAGS_PROC_CPU_32v4 := -mapcs-32 -marmv4t -LINKFLAGS := -p $(LINKFLAGS) -else -AFLAGS_PROC_CPU_26 := -m3 -AFLAGS_PROC_CPU_32v3 := -m6 -AFLAGS_PROC_CPU_32v4 := -m6 -endif - # # Select CPU dependent flags # @@ -77,7 +71,7 @@ PROCESSOR = armo TEXTADDR = 0x02080000 CFLAGS += $(CFLAGS_PROC_CPU_26) - AFLAGS += $(AFLAGS_PROC_CPU_26) + AFLAGS += -mapcs-26 endif ifeq ($(CONFIG_CPU_32),y) @@ -85,10 +79,10 @@ TEXTADDR = 0xC0008000 ifeq ($(CONFIG_CPU_32v4),y) CFLAGS += $(CFLAGS_PROC_CPU_32v4) - AFLAGS += $(AFLAGS_PROC_CPU_32v4) + AFLAGS += -mapcs-32 -marmv4 else CFLAGS += $(CFLAGS_PROC_CPU_32v3) - AFLAGS += $(AFLAGS_PROC_CPU_32v3) + AFLAGS += -mapcs-32 -marmv3m endif # # Exactly one of the following must be selected @@ -156,7 +150,7 @@ DRIVERS += arch/arm/special/special.a ifeq ($(CONFIG_NWFPE),y) -CORE_FILES += arch/arm/nwfpe/math-emu.o +LIBS := arch/arm/nwfpe/math-emu.o $(LIBS) endif ifeq ($(CONFIG_ARCH_ACORN),y) @@ -173,7 +167,7 @@ # to date before starting compilation CONSTANTS := constants -constants: dummy +constants: $(TOPDIR)/include/asm-arm/proc-fns.h dummy @$(MAKE) -C arch/arm/lib constants.h symlinks: archsymlinks diff -u --recursive --new-file v2.3.24/linux/arch/arm/boot/compressed/Makefile linux/arch/arm/boot/compressed/Makefile --- v2.3.24/linux/arch/arm/boot/compressed/Makefile Fri Oct 22 13:21:43 1999 +++ linux/arch/arm/boot/compressed/Makefile Thu Oct 28 10:16:02 1999 @@ -8,7 +8,7 @@ SYSTEM = $(TOPDIR)/vmlinux CFLAGS = -O2 -DSTDC_HEADERS $(CFLAGS_PROC) FONTC = $(TOPDIR)/drivers/video/font_acorn_8x8.c -ZLDFLAGS = -X -T vmlinux.lds +ZLDFLAGS = -p -X -T vmlinux.lds # # Architecture dependencies diff -u --recursive --new-file v2.3.24/linux/arch/arm/boot/compressed/head.S linux/arch/arm/boot/compressed/head.S --- v2.3.24/linux/arch/arm/boot/compressed/head.S Fri Oct 22 13:21:43 1999 +++ linux/arch/arm/boot/compressed/head.S Thu Oct 28 10:16:02 1999 @@ -96,6 +96,8 @@ */ reloc_start: add r8, r5, r0 #if 0 + mov r0, #'\n' + bl putc mov r0, r6 mov r1, #8 bl phex @@ -139,8 +141,8 @@ bl phex mov r0, #'\n' bl putc - mov r0, r4 - bl memdump + mov r0, r4 + bl memdump #endif eor r0, r6, #0x44 << 24 @ SA-110? eor r0, r0, #0x01 << 16 @@ -155,6 +157,25 @@ phexbuf: .space 12 +#if 0 + .macro loadsp, rb + mov \rb, #0x7c000000 + .endm + + .macro writeb, rb + strb \rb, [r3, #0x3f8] + .endm +#else + .macro loadsp, rb + mov \rb, #0x03000000 + orr \rb, \rb, #0x00010000 + .endm + + .macro writeb, rb + strb \rb, [r3, #0x3f8 << 2] + .endm +#endif + phex: adr r3, phexbuf mov r2, #0 strb r2, [r3, r1] @@ -169,11 +190,11 @@ strb r2, [r3, r1] b 1b -puts: mov r3, #0x7c000000 +puts: loadsp r3 1: ldrb r2, [r0], #1 teq r2, #0 moveq pc, lr -2: strb r2, [r3, #0x3f8] +2: writeb r2 mov r1, #0x00020000 3: subs r1, r1, #1 bne 3b @@ -186,7 +207,7 @@ putc: mov r2, r0 mov r0, #0 - mov r3, #0x7c000000 + loadsp r3 b 2b memdump: mov r12, r0 diff -u --recursive --new-file v2.3.24/linux/arch/arm/config.in linux/arch/arm/config.in --- v2.3.24/linux/arch/arm/config.in Wed Oct 27 16:34:12 1999 +++ linux/arch/arm/config.in Thu Oct 28 10:45:51 1999 @@ -21,6 +21,7 @@ EBSA-110 CONFIG_ARCH_EBSA110 \ FootBridge-based CONFIG_FOOTBRIDGE" RiscPC # SA1100-based CONFIG_ARCH_SA1100 + if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then bool 'FootBridge in HOST mode' CONFIG_HOST_FOOTBRIDGE if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then @@ -45,13 +46,13 @@ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then define_bool CONFIG_CPU_SA1100 y choice 'SA1100 implementation' \ - "Brutus CONFIG_SA1100_BRUTUS \ - empeg CONFIG_SA1100_EMPEG \ - Itsy CONFIG_SA1100_ITSY \ - LART CONFIG_SA1100_LART \ - PLEB CONFIG_SA1100_PLEB \ - Victor CONFIG_SA1100_VICTOR \ - Tifon CONFIG_SA1100_TIFON" Brutus + "Brutus CONFIG_SA1100_BRUTUS \ + Empeg CONFIG_SA1100_EMPEG \ + Itsy CONFIG_SA1100_ITSY \ + LART CONFIG_SA1100_LART \ + PLEB CONFIG_SA1100_PLEB \ + Victor CONFIG_SA1100_VICTOR \ + Tifon CONFIG_SA1100_TIFON" Brutus fi # @@ -120,8 +121,6 @@ else define_bool CONFIG_ISA_DMA n fi - -endmenu if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'Enable kernel-mode alignment trap handler (EXPERIMENTAL)' CONFIG_ALIGNMENT_TRAP diff -u --recursive --new-file v2.3.24/linux/arch/arm/kernel/armksyms.c linux/arch/arm/kernel/armksyms.c --- v2.3.24/linux/arch/arm/kernel/armksyms.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/armksyms.c Thu Oct 28 10:16:02 1999 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -98,7 +99,8 @@ EXPORT_SYMBOL(system_rev); EXPORT_SYMBOL(system_serial_low); EXPORT_SYMBOL(system_serial_high); - +EXPORT_SYMBOL(__bug); +EXPORT_SYMBOL(__readwrite_bug); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); @@ -152,8 +154,8 @@ #ifndef CONFIG_NO_PGT_CACHE EXPORT_SYMBOL(quicklists); #endif -EXPORT_SYMBOL(__bad_pmd); -EXPORT_SYMBOL(__bad_pmd_kernel); +EXPORT_SYMBOL(__handle_bad_pmd); +EXPORT_SYMBOL(__handle_bad_pmd_kernel); /* string / mem functions */ EXPORT_SYMBOL_NOVERS(strcpy); diff -u --recursive --new-file v2.3.24/linux/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c --- v2.3.24/linux/arch/arm/kernel/bios32.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/bios32.c Thu Oct 28 10:16:02 1999 @@ -13,16 +13,14 @@ #include #include -int have_isa_bridge; +#include "bios32.h" -int (*pci_irq_fixup)(struct pci_dev *dev); +static int debug_pci; +int have_isa_bridge; -extern struct pci_ops *dc21285_init(int pass); -extern void pcibios_fixup_ebsa285(struct pci_dev *dev); extern void hw_init(void); -void -pcibios_report_device_errors(void) +void pcibios_report_device_errors(void) { struct pci_dev *dev; @@ -31,16 +29,17 @@ pci_read_config_word(dev, PCI_STATUS, &status); - if (status & 0xf900) { - pci_write_config_word(dev, PCI_STATUS, status & 0xf900); - printk(KERN_DEBUG "PCI: %02x:%02x status = %X\n", - dev->bus->number, dev->devfn, status); - } + if ((status & 0xf900) == 0) + continue; + + pci_write_config_word(dev, PCI_STATUS, status & 0xf900); + printk(KERN_DEBUG "PCI: status %04X on %s\n", + status, dev->name); } } /* - * We don't use this to fix the device, but more our initialisation. + * We don't use this to fix the device, but initialisation of it. * It's not the correct use for this, but it works. The actions we * take are: * - enable only IO @@ -68,196 +67,108 @@ pci_write_config_byte(dev, 0x81, 0x01); } -struct pci_fixup pcibios_fixups[] = { - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, pci_fixup_83c553 }, - { 0 } -}; - -/* - * Assign new address to PCI resource. We hope our resource information - * is complete. On the PC, we don't re-assign resources unless we are - * forced to do so. - * - * Expects start=0, end=size-1, flags=resource type. - */ - -int __init pcibios_assign_resource(struct pci_dev *dev, int i) +static void __init pci_fixup_unassign(struct pci_dev *dev) { - struct resource *r = &dev->resource[i]; - struct resource *pr = pci_find_parent_resource(dev, r); - unsigned long size = r->end + 1; - unsigned long flags = 0; - - if (!pr) - return -EINVAL; - if (r->flags & IORESOURCE_IO) { - if (size > 0x100) - return -EFBIG; - if (allocate_resource(pr, r, size, 0x9000, ~0, 1024)) - return -EBUSY; - flags = PCI_BASE_ADDRESS_SPACE_IO; - } else { - if (allocate_resource(pr, r, size, 0x00100000, 0x7fffffff, size)) - return -EBUSY; - } - if (i < 6) - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4*i, r->start | flags); - return 0; + dev->resource[0].end -= dev->resource[0].start; + dev->resource[0].start = 0; } /* - * Assign an address to an I/O range. + * PCI IDE controllers use non-standard I/O port + * decoding, respect it. */ -static void __init pcibios_fixup_io_addr(struct pci_dev *dev, struct resource *r, int idx) +static void __init pci_fixup_ide_bases(struct pci_dev *dev) { - unsigned int reg = PCI_BASE_ADDRESS_0 + (idx << 2); - unsigned int size = r->end - r->start + 1; - u32 try; + struct resource *r; + int i; - /* - * We need to avoid collisions with `mirrored' VGA ports and other strange - * ISA hardware, so we always want the addresses kilobyte aligned. - */ - if (!size || size > 256) { - printk(KERN_ERR "PCI: Cannot assign I/O space to %s, " - "%d bytes are too much.\n", dev->name, size); + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) return; - } - if (allocate_resource(&ioport_resource, r, size, 0x9000, ~0, 1024)) { - printk(KERN_ERR "PCI: Unable to find free %d bytes of I/O " - "space for %s.\n", size, dev->name); - return; - } - - printk("PCI: Assigning I/O space %04lx-%04lx to %s\n", - r->start, r->end, dev->name); - - pci_write_config_dword(dev, reg, r->start | PCI_BASE_ADDRESS_SPACE_IO); - pci_read_config_dword(dev, reg, &try); - - if ((try & PCI_BASE_ADDRESS_IO_MASK) != r->start) { - r->start = 0; - pci_write_config_dword(dev, reg, 0); - printk(KERN_ERR "PCI: I/O address setup failed, got %04x\n", try); + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + r = dev->resource + i; + if ((r->start & ~0x80) == 0x374) { + r->start |= 2; + r->end = r->start; + } } } +struct pci_fixup pcibios_fixups[] = { + { + PCI_FIXUP_HEADER, + PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, + pci_fixup_83c553 + }, { + PCI_FIXUP_HEADER, + PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F, + pci_fixup_unassign + }, { + PCI_FIXUP_HEADER, + PCI_ANY_ID, PCI_ANY_ID, + pci_fixup_ide_bases + }, { 0 } +}; + /* - * Assign an address to an memory range. + * Allocate resources for all PCI devices that have been enabled. + * We need to do that before we try to fix up anything. */ -static void __init pcibios_fixup_mem_addr(struct pci_dev *dev, struct resource *r, int idx) +static void __init pcibios_claim_resources(void) { - unsigned int reg = PCI_BASE_ADDRESS_0 + (idx << 2); - unsigned int size = r->end - r->start + 1; - u32 try; - - if (!size) { - printk(KERN_ERR "PCI: Cannot assign memory space to %s, " - "%d bytes are too much.\n", dev->name, size); - return; - } - - if (allocate_resource(&iomem_resource, r, size, - 0x00100000, 0x0fffffff, 1024)) { - printk(KERN_ERR "PCI: Unable to find free %d bytes of memory " - "space for %s.\n", size, dev->name); - return; - } - - printk("PCI: Assigning memory space %08lx-%08lx to %s\n", - r->start, r->end, dev->name); - - pci_write_config_dword(dev, reg, r->start); - pci_read_config_dword(dev, reg, &try); + struct pci_dev *dev; + int idx; - if (try != r->start) { - r->start = 0; - pci_write_config_dword(dev, reg, 0); - printk(KERN_ERR "PCI: memory address setup failed, " - "got %08x\n", try); - } + for (dev = pci_devices; dev; dev = dev->next) + for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) + if (dev->resource[idx].flags && + dev->resource[idx].start) + pci_claim_resource(dev, idx); } -#define _PCI_REGION_IO 1 -#define _PCI_REGION_MEM 2 +void __init +pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + unsigned long where, size; + u32 reg; + + if (debug_pci) + printk("PCI: Assigning %3s %08lx to %s\n", + res->flags & IORESOURCE_IO ? "IO" : "MEM", + res->start, dev->name); + + where = PCI_BASE_ADDRESS_0 + resource * 4; + size = res->end - res->start; + + pci_read_config_dword(dev, where, ®); + reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); + pci_write_config_dword(dev, where, reg); +} -/* - * Fix up one PCI devices regions, enables and interrupt lines - */ -static void __init pcibios_fixup_device(struct pci_dev *dev, u16 *cmd) +void __init pcibios_update_irq(struct pci_dev *dev, int irq) { - int i, has_regions = 0; - - /* - * Fix up the regions. Any regions which aren't allocated - * are given a free region. - */ - for (i = 0; i < 6; i++) { - struct resource *r = dev->resource + i; - - if (r->flags & IORESOURCE_IO) { - has_regions |= _PCI_REGION_IO; - - if (!r->start || r->end == 0xffffffff) - pcibios_fixup_io_addr(dev, r, i); - } else if (r->end) { - has_regions |= _PCI_REGION_MEM; - - if (!r->start) - pcibios_fixup_mem_addr(dev, r, i); - } - } - - switch (dev->class >> 8) { - case PCI_CLASS_BRIDGE_ISA: - case PCI_CLASS_BRIDGE_EISA: - /* - * If this device is an ISA bridge, set the have_isa_bridge - * flag. We will then go looking for things like keyboard, - * etc - */ - have_isa_bridge = !0; - /* FALL THROUGH */ - - default: - /* - * Don't enable VGA-compatible cards since they have - * fixed I/O and memory space. - * - * Don't enabled disabled IDE interfaces either because - * some BIOSes may reallocate the same address when they - * find that no devices are attached. - */ - if (has_regions & _PCI_REGION_IO && - !((*cmd) & PCI_COMMAND_IO)) { - printk("PCI: Enabling I/O for %s\n", dev->name); - *cmd |= PCI_COMMAND_IO; - } - - if (has_regions & _PCI_REGION_MEM && - !((*cmd) & PCI_COMMAND_MEMORY)) { - printk("PCI: Enabling memory for %s\n", dev->name); - *cmd |= PCI_COMMAND_MEMORY; - } - } + if (debug_pci) + printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } /* - * Fix base addresses, I/O and memory enables and IRQ's + * Called after each bus is probed, but before its children + * are examined. */ -static void __init pcibios_fixup_devices(void) +void __init pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev; - for (dev = pci_devices; dev; dev = dev->next) { + for (dev = bus->devices; dev; dev = dev->sibling) { u16 cmd; /* - * architecture specific hacks. - * I don't really want this here, - * but I don't see any other place - * for it to live. + * architecture specific hacks. I don't really want + * this here, but I don't see any other place for it + * to live. Shame the device doesn't support + * capabilities */ if (machine_is_netwinder() && dev->vendor == PCI_VENDOR_ID_DEC && @@ -266,119 +177,165 @@ pci_write_config_dword(dev, 0x40, 0x80000000); /* + * If this device is an ISA bridge, set the have_isa_bridge + * flag. We will then go looking for things like keyboard, + * etc + */ + if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA || + dev->class >> 8 == PCI_CLASS_BRIDGE_EISA) + have_isa_bridge = !0; + + /* * Set latency timer to 32, and a cache line size to 32 bytes. * Also, set system error enable, parity error enable, and * fast back to back transaction enable. Disable ROM. */ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32); pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8); - pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0); pci_read_config_word(dev, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_FAST_BACK | PCI_COMMAND_SERR | PCI_COMMAND_PARITY; - pcibios_fixup_device(dev, &cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0); + } +} - /* - * now fixup the IRQs, if required - */ - if (pci_irq_fixup) - dev->irq = pci_irq_fixup(dev); +static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin) +{ + return 0; +} - /* - * If any remaining IRQs are weird, fix it now. - */ - if (dev->irq >= NR_IRQS) - dev->irq = 0; +/* ebsa285 host-specific stuff */ +static int irqmap_ebsa285[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 }; - /* - * catch any drivers still reading this from the - * device itself. This can be removed once - * all drivers are fixed. (are there any?) - */ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } +static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin) +{ + return PCI_SLOT(dev->devfn); } -/* - * Allocate resources for all PCI devices that have been enabled. - * We need to do that before we try to fix up anything. - */ -static void __init pcibios_claim_resources(void) +static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - struct pci_dev *dev; - int idx; + return irqmap_ebsa285[(slot + pin) & 3]; +} - for (dev = pci_devices; dev; dev = dev->next) - for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { - struct resource *a, *r = &dev->resource[idx]; +static struct hw_pci ebsa285_pci __initdata = { + dc21285_init, + 0x9000, + 0x00100000, + ebsa285_swizzle, + ebsa285_map_irq +}; - /* - * Ignore regions that start at 0 or - * end at 0xffffffff - */ - if (!r->start || r->end == 0xffffffff) - continue; - - if (r->flags & IORESOURCE_IO) - a = &ioport_resource; - else - a = &iomem_resource; - - if (request_resource(a, r) < 0) - printk(KERN_ERR "PCI: Address space collision " - "on region %d of %s\n", - idx, dev->name); - /* We probably should disable the region, - * shouldn't we? - */ - } +/* cats host-specific stuff */ +static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; + +static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->irq >= 128) + return 16 + (dev->irq & 0x1f); + + if (dev->irq >= 1 && dev->irq <= 4) + return irqmap_cats[dev->irq - 1]; + + if (dev->irq != 0) + printk("PCI: device %02x:%02x has unknown irq line %x\n", + dev->bus->number, dev->devfn, dev->irq); + + return -1; } -/* - * Called after each bus is probed, but before its children - * are examined. - * - * No fixup of bus required - */ -void __init pcibios_fixup_bus(struct pci_bus *bus) +static struct hw_pci cats_pci __initdata = { + dc21285_init, + 0x9000, + 0x00100000, + no_swizzle, + cats_map_irq +}; + +/* netwinder host-specific stuff */ +static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { +#define DEV(v,d) ((v)<<16|(d)) + switch (DEV(dev->vendor, dev->device)) { + case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142): + return IRQ_NETWINDER_ETHER100; + + case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a): + return IRQ_NETWINDER_ETHER10; + + case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553): + return 0; + + case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105): + return IRQ_ISA_HARDDISK1; + + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000): + return IRQ_NETWINDER_VGA; + + default: + printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n", + dev->bus->number, dev->devfn, + dev->vendor, dev->device); + return 0; + } } +static struct hw_pci netwinder_pci __initdata = { + dc21285_init, + 0x9000, + 0x00100000, + no_swizzle, + netwinder_map_irq +}; + void __init pcibios_init(void) { - struct pci_ops *ops; + struct hw_pci *hw_pci = NULL; + + if (machine_is_ebsa285()) + hw_pci = &ebsa285_pci; + else if (machine_is_cats()) + hw_pci = &cats_pci; + else if (machine_is_netwinder()) + hw_pci = &netwinder_pci; + + if (hw_pci == NULL) + return; /* - * Pre-initialisation. Set up the host bridge. + * Set up the host bridge, and scan the bus. */ - ops = dc21285_init(0); + hw_pci->init(); - printk("PCI: Probing PCI hardware\n"); - - pci_scan_bus(0, ops, NULL); + /* + * Other architectures don't seem to do this... should we? + */ pcibios_claim_resources(); - pcibios_fixup_devices(); /* - * Now clear down any PCI error IRQs and - * register the error handler + * Assign any unassigned resources. Note that we really ought to + * have min/max stuff here - max mem address is 0x0fffffff */ - dc21285_init(1); + pci_assign_unassigned_resources(hw_pci->io_start, hw_pci->mem_start); + pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq); + pci_set_bus_ranges(); /* - * Initialise any other hardware after we've - * got the PCI bus initialised. We may need - * the PCI bus to talk to this other hardware. + * Initialise any other hardware after we've got the PCI bus + * initialised. We may need the PCI bus to talk to this other + * hardware. */ hw_init(); } char * __init pcibios_setup(char *str) { + if (!strcmp(str, "debug")) { + debug_pci = 1; + return NULL; + } return str; } diff -u --recursive --new-file v2.3.24/linux/arch/arm/kernel/dec21285.c linux/arch/arm/kernel/dec21285.c --- v2.3.24/linux/arch/arm/kernel/dec21285.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/dec21285.c Thu Oct 28 10:16:02 1999 @@ -18,11 +18,12 @@ #include #include +#include "bios32.h" + #define MAX_SLOTS 21 extern int setup_arm_irq(int, struct irqaction *); extern void pcibios_report_device_errors(void); -extern int (*pci_irq_fixup)(struct pci_dev *dev); static unsigned long dc21285_base_address(struct pci_dev *dev, int where) @@ -202,129 +203,53 @@ dc21285_error, SA_INTERRUPT, 0, "PCI error", NULL, NULL }; -static int irqmap_ebsa[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 }; - -static int __init ebsa_irqval(struct pci_dev *dev) -{ - u8 pin; - - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - - return irqmap_ebsa[(PCI_SLOT(dev->devfn) + pin) & 3]; -} - -static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; - -static int __init cats_irqval(struct pci_dev *dev) -{ - if (dev->irq >= 128) - return 16 + (dev->irq & 0x1f); - - switch (dev->irq) { - case 1 ... 4: - return irqmap_cats[dev->irq - 1]; - - default: - printk("PCI: device %02x:%02x has unknown irq line %x\n", - dev->bus->number, dev->devfn, dev->irq); - case 0: - break; - } - return 0; -} - -static int __init netwinder_irqval(struct pci_dev *dev) -{ -#define DEV(v,d) ((v)<<16|(d)) - switch (DEV(dev->vendor, dev->device)) { - case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142): - return IRQ_NETWINDER_ETHER100; - - case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a): - return IRQ_NETWINDER_ETHER10; - - case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553): - return 0; - - case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105): - return IRQ_ISA_HARDDISK1; - - case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000): - return IRQ_NETWINDER_VGA; - - default: - printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n", - dev->bus->number, dev->devfn, - dev->vendor, dev->device); - return 0; - } -} - -struct pci_ops * __init dc21285_init(int pass) +void __init dc21285_init(void) { unsigned int mem_size; unsigned long cntl; - if (pass == 0) { - mem_size = (unsigned int)high_memory - PAGE_OFFSET; - *CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000; - *CSR_SDRAMBASEOFFSET = 0; - *CSR_ROMBASEMASK = 0x80000000; - *CSR_CSRBASEMASK = 0; - *CSR_CSRBASEOFFSET = 0; - *CSR_PCIADDR_EXTN = 0; + mem_size = (unsigned int)high_memory - PAGE_OFFSET; + *CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000; + *CSR_SDRAMBASEOFFSET = 0; + *CSR_ROMBASEMASK = 0x80000000; + *CSR_CSRBASEMASK = 0; + *CSR_CSRBASEOFFSET = 0; + *CSR_PCIADDR_EXTN = 0; #ifdef CONFIG_HOST_FOOTBRIDGE - /* - * Map our SDRAM at a known address in PCI space, just in case - * the firmware had other ideas. Using a nonzero base is - * necessary, since some VGA cards forcefully use PCI addresses - * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards). - */ - *CSR_PCICACHELINESIZE = 0x00002008; - *CSR_PCICSRBASE = 0; - *CSR_PCICSRIOBASE = 0; - *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET); - *CSR_PCIROMBASE = 0; - *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | PCI_COMMAND_FAST_BACK | - PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | - (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24); + /* + * Map our SDRAM at a known address in PCI space, just in case + * the firmware had other ideas. Using a nonzero base is + * necessary, since some VGA cards forcefully use PCI addresses + * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards). + */ + *CSR_PCICACHELINESIZE = 0x00002008; + *CSR_PCICSRBASE = 0; + *CSR_PCICSRIOBASE = 0; + *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET); + *CSR_PCIROMBASE = 0; + *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_FAST_BACK | + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | + (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24); #endif - printk(KERN_DEBUG"PCI: DC21285 footbridge, revision %02lX\n", - *CSR_CLASSREV & 0xff); + printk(KERN_DEBUG"PCI: DC21285 footbridge, revision %02lX\n", + *CSR_CLASSREV & 0xff); - switch (machine_arch_type) { - case MACH_TYPE_EBSA285: - pci_irq_fixup = ebsa_irqval; - break; - - case MACH_TYPE_CATS: - pci_irq_fixup = cats_irqval; - break; - - case MACH_TYPE_NETWINDER: - pci_irq_fixup = netwinder_irqval; - break; - } - - return &dc21285_ops; - } else { - /* - * Clear any existing errors - we aren't - * interested in historical data... - */ - cntl = *CSR_SA110_CNTL & 0xffffde07; - *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR; - cntl = *CSR_PCICMD & 0x0000ffff; - *CSR_PCICMD = cntl | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24; - - /* - * Initialise PCI error IRQ after we've finished probing - */ - setup_arm_irq(IRQ_PCI_ERR, &dc21285_error_action); + pci_scan_bus(0, &dc21285_ops, NULL); - return NULL; - } + /* + * Clear any existing errors - we aren't + * interested in historical data... + */ + cntl = *CSR_SA110_CNTL & 0xffffde07; + *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR; + cntl = *CSR_PCICMD & 0x0000ffff; + *CSR_PCICMD = cntl | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24; + + /* + * Initialise PCI error IRQ after we've finished probing + */ + setup_arm_irq(IRQ_PCI_ERR, &dc21285_error_action); } diff -u --recursive --new-file v2.3.24/linux/arch/arm/kernel/ecard.c linux/arch/arm/kernel/ecard.c --- v2.3.24/linux/arch/arm/kernel/ecard.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/ecard.c Fri Oct 29 11:01:12 1999 @@ -888,19 +888,13 @@ return (count > cnt) ? cnt : count; } -static struct proc_dir_entry proc_ecard_devices = { - PROC_BUS_ECARD_DEVICES, 7, "devices", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - get_ecard_dev_info -}; - -static struct proc_dir_entry *proc_bus_ecard_dir; +static struct proc_dir_entry *proc_bus_ecard_dir = NULL; static void ecard_proc_init(void) { proc_bus_ecard_dir = create_proc_entry("ecard", S_IFDIR, proc_bus); - proc_register(proc_bus_ecard_dir, &proc_ecard_devices); + create_proc_info_entry("devices", 0, proc_bus_ecard_dir, + get_ecard_dev_info); } /* diff -u --recursive --new-file v2.3.24/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c --- v2.3.24/linux/arch/arm/kernel/setup.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/setup.c Thu Oct 28 10:16:02 1999 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -42,50 +43,74 @@ extern void reboot_setup(char *str, int *ints); extern void disable_hlt(void); - -struct drive_info_struct { char dummy[32]; } drive_info; -struct screen_info screen_info = { - orig_video_lines: 30, - orig_video_cols: 80, - orig_video_mode: 0, - orig_video_ega_bx: 0, - orig_video_isVGA: 1, - orig_video_points: 8 -}; - extern int root_mountflags; -extern int _text, _etext, _edata, _end; +extern int _stext, _text, _etext, _edata, _end; -unsigned char aux_device_present; - char elf_platform[ELF_PLATFORM_SIZE]; -unsigned int elf_hwcap; - -/* - * From head-armv.S - */ unsigned int processor_id; unsigned int __machine_arch_type; unsigned int vram_size; unsigned int system_rev; unsigned int system_serial_low; unsigned int system_serial_high; -#ifdef MULTI_CPU -struct processor processor; -#endif +unsigned int elf_hwcap; + #ifdef CONFIG_ARCH_ACORN unsigned int memc_ctrl_reg; unsigned int number_mfm_drives; #endif +struct meminfo meminfo; + +#ifdef MULTI_CPU +struct processor processor; +#endif + +struct drive_info_struct { char dummy[32]; } drive_info; + +struct screen_info screen_info = { + orig_video_lines: 30, + orig_video_cols: 80, + orig_video_mode: 0, + orig_video_ega_bx: 0, + orig_video_isVGA: 1, + orig_video_points: 8 +}; + +unsigned char aux_device_present; +char elf_platform[ELF_PLATFORM_SIZE]; +char saved_command_line[COMMAND_LINE_SIZE]; + static struct proc_info_item proc_info; +static char command_line[COMMAND_LINE_SIZE] = { 0, }; + +static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; #define ENDIANNESS ((char)endian_test.l) -/*------------------------------------------------------------------------- - * Early initialisation routines for various configurable items in the - * kernel. Each one either supplies a setup_ function, or defines this - * symbol to be empty if not configured. +/* + * Standard memory resources */ +static struct resource mem_res[] = { + { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY }, + { "Video RAM", 0, 0, IORESOURCE_MEM }, + { "Kernel code", 0, 0, IORESOURCE_MEM }, + { "Kernel data", 0, 0, IORESOURCE_MEM } +}; + +#define system_ram mem_res[0] +#define video_ram mem_res[1] +#define kernel_code mem_res[2] +#define kernel_data mem_res[3] + +static struct resource io_res[] = { + { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }, + { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY }, + { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY } +}; + +#define lp0 io_res[0] +#define lp1 io_res[1] +#define lp2 io_res[2] static void __init setup_processor(void) { @@ -124,55 +149,69 @@ cpu_proc_init(); } -static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; -static char command_line[COMMAND_LINE_SIZE] = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; +static unsigned long __init memparse(char *ptr, char **retptr) +{ + unsigned long ret = simple_strtoul(ptr, retptr, 0); + switch (**retptr) { + case 'M': + case 'm': + ret <<= 10; + case 'K': + case 'k': + ret <<= 10; + (*retptr)++; + default: + break; + } + return ret; +} + +/* + * Initial parsing of the command line. We need to pick out the + * memory size. We look for mem=size@start, where start and size + * are "size[KkMm]" + */ static void __init -setup_mem(char *cmd_line, unsigned long *mem_sz) +parse_cmdline(char **cmdline_p, char *from) { char c = ' ', *to = command_line; - int len = 0; - - if (!*mem_sz) - *mem_sz = MEM_SIZE; + int usermem = 0, len = 0; for (;;) { - if (c == ' ') { - if (cmd_line[0] == 'm' && - cmd_line[1] == 'e' && - cmd_line[2] == 'm' && - cmd_line[3] == '=') { - *mem_sz = simple_strtoul(cmd_line+4, &cmd_line, 0); - switch(*cmd_line) { - case 'M': - case 'm': - *mem_sz <<= 10; - case 'K': - case 'k': - *mem_sz <<= 10; - cmd_line++; - } - } - /* if there are two spaces, remove one */ - if (*cmd_line == ' ') { - cmd_line++; - continue; + if (c == ' ' && !memcmp(from, "mem=", 4)) { + unsigned long size, start; + + if (to != command_line) + to -= 1; + + /* If the user specifies memory size, we + * blow away any automatically generated + * size. + */ + if (usermem == 0) { + usermem = 1; + meminfo.nr_banks = 0; } + + start = 0; + size = memparse(from + 4, &from); + if (*from == '@') + start = memparse(from + 1, &from); + + meminfo.bank[meminfo.nr_banks].start = start; + meminfo.bank[meminfo.nr_banks].size = size; + meminfo.nr_banks += 1; } - c = *cmd_line++; + c = *from++; if (!c) break; if (COMMAND_LINE_SIZE <= ++len) break; *to++ = c; } - *to = '\0'; - - /* remove trailing spaces */ - while (*--to == ' ' && to != command_line) - *to = '\0'; + *cmdline_p = command_line; } static void __init @@ -199,51 +238,90 @@ static void __init setup_initrd(unsigned int start, unsigned int size) { #ifdef CONFIG_BLK_DEV_INITRD - if (start) { - initrd_start = start; - initrd_end = start + size; - } else { - initrd_start = 0; - initrd_end = 0; - } + if (start == 0) + size = 0; + initrd_start = start; + initrd_end = start + size; #endif } -static void __init check_initrd(unsigned long mem_end) +/* + * Work out our memory regions. Note that "pfn" is the physical page number + * relative to the first physical page, not the physical address itself. + */ +static void __init setup_bootmem(void) { + unsigned int end_pfn, bootmem_end; + int bank; + + /* + * Calculate the end of memory. + */ + for (bank = 0; bank < meminfo.nr_banks; bank++) { + if (meminfo.bank[bank].size) { + unsigned long end; + + end = meminfo.bank[bank].start + + meminfo.bank[bank].size; + if (meminfo.end < end) + meminfo.end = end; + } + } + + bootmem_end = __pa(PAGE_ALIGN((unsigned long)&_end)); + end_pfn = meminfo.end >> PAGE_SHIFT; + + /* + * Initialise the boot-time allocator + */ + bootmem_end += init_bootmem(bootmem_end >> PAGE_SHIFT, end_pfn); + + /* + * Register all available RAM with the bootmem allocator. + * The address is relative to the start of physical memory. + */ + for (bank = 0; bank < meminfo.nr_banks; bank ++) + free_bootmem(meminfo.bank[bank].start, meminfo.bank[bank].size); + + /* + * reserve the following regions: + * physical page 0 - it contains the exception vectors + * kernel and the bootmem structure + * swapper page directory (if any) + * initrd (if any) + */ + reserve_bootmem(0, PAGE_SIZE); +#ifdef CONFIG_CPU_32 + reserve_bootmem(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *)); +#endif + reserve_bootmem(__pa(&_stext), bootmem_end - __pa(&_stext)); #ifdef CONFIG_BLK_DEV_INITRD - if (initrd_end > mem_end) { + if (__pa(initrd_end) > (end_pfn << PAGE_SHIFT)) { printk ("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx) - disabling initrd\n", - initrd_end, mem_end); + "(0x%08lx > 0x%08x) - disabling initrd\n", + __pa(initrd_end), end_pfn << PAGE_SHIFT); initrd_start = 0; } + + if (initrd_start) + reserve_bootmem(__pa(initrd_start), + initrd_end - initrd_start); #endif } -/* - * Standard memory resources - */ -static struct resource system_ram = { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY }; -static struct resource video_ram = { "Video RAM", 0, 0, IORESOURCE_MEM }; -static struct resource kernel_code = { "Kernel code", 0, 0, IORESOURCE_MEM }; -static struct resource kernel_data = { "Kernel data", 0, 0, IORESOURCE_MEM }; -static struct resource lpt1 = { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }; -static struct resource lpt2 = { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY }; -static struct resource lpt3 = { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }; - -static void __init request_standard_resources(unsigned long end) +static void __init request_standard_resources(void) { kernel_code.start = __virt_to_bus((unsigned long) &_text); kernel_code.end = __virt_to_bus((unsigned long) &_etext - 1); kernel_data.start = __virt_to_bus((unsigned long) &_etext); kernel_data.end = __virt_to_bus((unsigned long) &_edata - 1); system_ram.start = __virt_to_bus(PAGE_OFFSET); - system_ram.end = __virt_to_bus(end - 1); + system_ram.end = __virt_to_bus(meminfo.end + PAGE_OFFSET - 1); request_resource(&iomem_resource, &system_ram); request_resource(&system_ram, &kernel_code); request_resource(&system_ram, &kernel_data); + if (video_ram.start != video_ram.end) request_resource(&iomem_resource, &video_ram); @@ -253,17 +331,16 @@ */ if (machine_is_ebsa110() || machine_is_riscpc() || machine_is_netwinder()) - request_resource(&ioport_resource, &lpt1); + request_resource(&ioport_resource, &lp0); if (machine_is_riscpc()) - request_resource(&ioport_resource, &lpt2); + request_resource(&ioport_resource, &lp1); if (machine_is_ebsa110() || machine_is_netwinder()) - request_resource(&ioport_resource, &lpt3); + request_resource(&ioport_resource, &lp2); } -void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p) +void __init setup_arch(char **cmdline_p) { struct param_struct *params = (struct param_struct *)PARAMS_BASE; - unsigned long memory_end = 0; char *from = default_command_line; #if defined(CONFIG_ARCH_ARC) @@ -296,10 +373,6 @@ case MACH_TYPE_RISCPC: /* RiscPC can't handle half-word loads and stores */ elf_hwcap &= ~HWCAP_HALF; - { - extern void init_dram_banks(struct param_struct *); - init_dram_banks(params); - } switch (params->u1.s.pages_in_vram) { case 512: @@ -309,6 +382,17 @@ default: break; } + { + int i; + + for (i = 0; i < 4; i++) { + meminfo.bank[i].start = i << 26; + meminfo.bank[i].size = + params->u1.s.pages_in_bank[i] * + params->u1.s.page_size; + } + meminfo.nr_banks = 4; + } #endif case MACH_TYPE_ARCHIMEDES: case MACH_TYPE_A5K: @@ -347,7 +431,7 @@ */ reboot_setup("s", NULL); params = NULL; - ORIG_VIDEO_LINES = 25; + ORIG_VIDEO_LINES = 25; ORIG_VIDEO_POINTS = 16; ORIG_Y = 24; video_ram.start = 0x0a0000; @@ -393,7 +477,11 @@ } if (params) { - memory_end = PAGE_SIZE * params->u1.s.nr_pages; + if (meminfo.nr_banks == 0) { + meminfo.nr_banks = 1; + meminfo.bank[0].start = 0; + meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT; + } ROOT_DEV = to_kdev_t(params->u1.s.rootdev); system_rev = params->u1.s.system_rev; system_serial_low = params->u1.s.system_serial_low; @@ -413,24 +501,23 @@ from = params->commandline; } - /* Save unparsed command line copy for /proc/cmdline */ - memcpy(saved_command_line, from, COMMAND_LINE_SIZE); - saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; - - setup_mem(from, &memory_end); - - memory_end += PAGE_OFFSET; + if (meminfo.nr_banks == 0) { + meminfo.nr_banks = 1; + meminfo.bank[0].start = 0; + meminfo.bank[0].size = MEM_SIZE; + } - *cmdline_p = command_line; init_mm.start_code = (unsigned long) &_text; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; - *memory_start_p = (unsigned long) &_end; - *memory_end_p = memory_end; - request_standard_resources(memory_end); - check_initrd(memory_end); + /* Save unparsed command line copy for /proc/cmdline */ + memcpy(saved_command_line, from, COMMAND_LINE_SIZE); + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; + parse_cmdline(cmdline_p, from); + setup_bootmem(); + request_standard_resources(); #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) diff -u --recursive --new-file v2.3.24/linux/arch/arm/kernel/sys_arm.c linux/arch/arm/kernel/sys_arm.c --- v2.3.24/linux/arch/arm/kernel/sys_arm.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/sys_arm.c Thu Oct 28 10:16:02 1999 @@ -29,8 +29,6 @@ /* * Constant strings used in inlined functions in header files */ -/* proc/system.h */ -const char xchg_str[] = "xchg"; /* * sys_pipe() is the normal C calling standard for creating diff -u --recursive --new-file v2.3.24/linux/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c --- v2.3.24/linux/arch/arm/kernel/traps.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/traps.c Thu Oct 28 10:16:02 1999 @@ -34,7 +34,10 @@ "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32" }; -static char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; +/* proc/system.h */ +const char xchg_str[] = "xchg"; + +static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; static inline void console_verbose(void) { @@ -335,10 +338,11 @@ } #ifdef CONFIG_DEBUG_USER - printk(KERN_ERR "[%d] %s: old system call.\n", current->pid, - current->comm); + printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", current->pid, + current->comm, n); #endif force_sig(SIGILL, current); + die_if_kernel("Oops", regs, n); } asmlinkage void arm_malalignedptr(const char *str, void *pc, volatile void *ptr) @@ -385,8 +389,37 @@ } #endif +void __bug(const char *file, int line, void *data) +{ + printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line); + if (data) + printk(KERN_CRIT"extra data = %p\n", data); + *(int *)0 = 0; +} + +void __readwrite_bug(const char *fn) +{ + printk("%s called, but not implemented", fn); + *(int *)0 = 0; +} + +void __pte_error(const char *file, int line, unsigned long val) +{ + printk("%s:%d: bad pte %08lx.\n", file, line, val); +} + +void __pmd_error(const char *file, int line, unsigned long val) +{ + printk("%s:%d: bad pmd %08lx.\n", file, line, val); +} + +void __pgd_error(const char *file, int line, unsigned long val) +{ + printk("%s:%d: bad pgd %08lx.\n", file, line, val); +} + asmlinkage void __div0(void) { - printk("Awooga, division by zero in kernel.\n"); + printk("Division by zero in kernel.\n"); __backtrace(); } diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c --- v2.3.24/linux/arch/arm/mm/fault-armv.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/fault-armv.c Thu Oct 28 14:34:45 1999 @@ -90,6 +90,7 @@ static unsigned long ai_word; static unsigned long ai_multi; +#ifdef CONFIG_SYSCTL static int proc_alignment_read(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -113,23 +114,18 @@ return len; } -#ifdef CONFIG_SYSCTL /* * This needs to be done after sysctl_init, otherwise sys/ * will be overwritten. */ void __init alignment_init(void) { - struct proc_dir_entry *e; - - e = create_proc_entry("sys/debug/alignment", S_IFREG | S_IRUGO, NULL); - - if (e) - e->read_proc = proc_alignment_read; + create_proc_read_entry("sys/debug/alignment", 0, NULL, + proc_alignment_read); } __initcall(alignment_init); -#endif +#endif /* CONFIG_SYSCTL */ static int do_alignment_exception(struct pt_regs *regs) diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/fault-common.c linux/arch/arm/mm/fault-common.c --- v2.3.24/linux/arch/arm/mm/fault-common.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/fault-common.c Thu Oct 28 10:16:02 1999 @@ -8,24 +8,6 @@ extern void die(char *msg, struct pt_regs *regs, unsigned int err); -void __bad_pmd(pmd_t *pmd) -{ - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); -#ifdef CONFIG_DEBUG_ERRORS - __backtrace(); -#endif - set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE)); -} - -void __bad_pmd_kernel(pmd_t *pmd) -{ - printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd)); -#ifdef CONFIG_DEBUG_ERRORS - __backtrace(); -#endif - set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE)); -} - /* * This is useful to dump out the page tables associated with * 'addr' in mm 'mm'. diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/init.c linux/arch/arm/mm/init.c --- v2.3.24/linux/arch/arm/mm/init.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/init.c Thu Oct 28 10:16:02 1999 @@ -1,7 +1,7 @@ /* * linux/arch/arm/mm/init.c * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-1999 Russell King */ #include @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_INITRD #include #endif @@ -27,74 +28,95 @@ #include #include #include +#include #include "map.h" +static unsigned long totalram_pages; pgd_t swapper_pg_dir[PTRS_PER_PGD]; -#ifndef CONFIG_NO_PGT_CACHE -struct pgtable_cache_struct quicklists; -#endif -extern unsigned long free_area_init(unsigned long, unsigned long); extern void show_net_buffers(void); -extern char _etext, _text, _edata, __bss_start, _end; -extern char __init_begin, __init_end; - -int do_check_pgt_cache(int low, int high) -{ - int freed = 0; -#ifndef CONFIG_NO_PGT_CACHE - if(pgtable_cache_size > high) { - do { - if(pgd_quicklist) - free_pgd_slow(get_pgd_fast()), freed++; - if(pmd_quicklist) - free_pmd_slow(get_pmd_fast()), freed++; - if(pte_quicklist) - free_pte_slow(get_pte_fast()), freed++; - } while(pgtable_cache_size > low); - } -#endif - return freed; -} - /* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a + * empty_bad_page is the page that is used for page faults when + * linux is out-of-memory. Older versions of linux just did a * do_exit(), but using this instead means there is less risk * for a process dying in kernel mode, possibly leaving a inode * unused etc.. * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. + * empty_bad_pte_table is the accompanying page-table: it is + * initialized to point to BAD_PAGE entries. * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. + * empty_zero_page is a special page that is used for + * zero-initialized data and COW. */ -pte_t *empty_bad_page_table; +struct page *empty_zero_page; +struct page *empty_bad_page; +pte_t *empty_bad_pte_table; -pte_t *__bad_pagetable(void) +pte_t *get_bad_pte_table(void) { - pte_t bad_page; + pte_t v; int i; - bad_page = BAD_PAGE; + v = pte_mkdirty(mk_pte(empty_bad_page, PAGE_SHARED)); + for (i = 0; i < PTRS_PER_PTE; i++) - set_pte(empty_bad_page_table + i, bad_page); + set_pte(empty_bad_pte_table + i, v); - return empty_bad_page_table; + return empty_bad_pte_table; } -unsigned long *empty_zero_page; -unsigned long *empty_bad_page; +void __handle_bad_pmd(pmd_t *pmd) +{ + pmd_ERROR(*pmd); +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif + set_pmd(pmd, mk_user_pmd(get_bad_pte_table())); +} -pte_t __bad_page(void) +void __handle_bad_pmd_kernel(pmd_t *pmd) { - memzero (empty_bad_page, PAGE_SIZE); - return pte_nocache(pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED))); + pmd_ERROR(*pmd); +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif + set_pmd(pmd, mk_kernel_pmd(get_bad_pte_table())); } +#ifndef CONFIG_NO_PGT_CACHE +struct pgtable_cache_struct quicklists; + +int do_check_pgt_cache(int low, int high) +{ + int freed = 0; + + if(pgtable_cache_size > high) { + do { + if(pgd_quicklist) { + free_pgd_slow(get_pgd_fast()); + freed++; + } + if(pmd_quicklist) { + free_pmd_slow(get_pmd_fast()); + freed++; + } + if(pte_quicklist) { + free_pte_slow(get_pte_fast()); + freed++; + } + } while(pgtable_cache_size > low); + } + return freed; +} +#else +int do_check_pgt_cache(int low, int high) +{ + return 0; +} +#endif + void show_mem(void) { int free = 0, total = 0, reserved = 0; @@ -104,23 +126,28 @@ printk("Mem-info:\n"); show_free_areas(); printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); - for (page = mem_map, end = mem_map + max_mapnr; - page < end; page++) { + + page = mem_map; + end = mem_map + max_mapnr; + + do { if (PageSkip(page)) { - if (page->next_hash < page) - break; page = page->next_hash; + if (page == NULL) + break; } total++; if (PageReserved(page)) reserved++; else if (PageSwapCache(page)) cached++; - else if (!atomic_read(&page->count)) + else if (!page_count(page)) free++; else shared += atomic_read(&page->count) - 1; - } + page++; + } while (page < end); + printk("%d pages of RAM\n", total); printk("%d free pages\n", free); printk("%d reserved pages\n", reserved); @@ -138,31 +165,42 @@ /* * paging_init() sets up the page tables... */ -unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem) +void __init paging_init(void) { - start_mem = PAGE_ALIGN(start_mem); - - empty_zero_page = (unsigned long *)start_mem; - memzero(empty_zero_page, PAGE_SIZE); - start_mem += PAGE_SIZE; - - empty_bad_page = (unsigned long *)start_mem; - start_mem += PAGE_SIZE; + void *zero_page, *bad_page, *bad_table; #ifdef CONFIG_CPU_32 - start_mem += PTRS_PER_PTE * BYTES_PER_PTR; +#define TABLE_OFFSET (PTRS_PER_PTE) +#else +#define TABLE_OFFSET 0 #endif - empty_bad_page_table = (pte_t *)start_mem; - start_mem += PTRS_PER_PTE * BYTES_PER_PTR; - - start_mem = setup_page_tables(start_mem, end_mem); +#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *)) + /* + * allocate what we need for the bad pages + */ + zero_page = alloc_bootmem_low_pages(PAGE_SIZE); + bad_page = alloc_bootmem_low_pages(PAGE_SIZE); + bad_table = alloc_bootmem_low_pages(TABLE_SIZE); + + /* + * initialise the page tables + */ + pagetable_init(); flush_tlb_all(); - end_mem &= PAGE_MASK; - high_memory = (void *)end_mem; + free_area_init(max_low_pfn); - return free_area_init(start_mem, end_mem); + /* + * finish off the bad pages once + * the mem_map is initialised + */ + memzero(zero_page, PAGE_SIZE); + memzero(bad_page, PAGE_SIZE); + + empty_zero_page = mem_map + MAP_NR(zero_page); + empty_bad_page = mem_map + MAP_NR(bad_page); + empty_bad_pte_table = ((pte_t *)bad_table) + TABLE_OFFSET; } static inline void free_unused_mem_map(void) @@ -184,7 +222,7 @@ high = ((unsigned long)page->next_hash) & PAGE_MASK; while (low < high) { - clear_bit(PG_reserved, &mem_map[MAP_NR(low)].flags); + ClearPageReserved(mem_map + MAP_NR(low)); low += PAGE_SIZE; } } @@ -195,67 +233,35 @@ * memory is free. This is done after various parts of the system have * claimed their memory after the kernel image. */ -void __init mem_init(unsigned long start_mem, unsigned long end_mem) +void __init mem_init(void) { int codepages = 0; int reservedpages = 0; int datapages = 0; int initpages = 0, i, min_nr; - unsigned long tmp; - end_mem &= PAGE_MASK; - high_memory = (void *)end_mem; - max_mapnr = MAP_NR(end_mem); - num_physpages = 0; + max_mapnr = max_low_pfn; + high_memory = (void *)__va(max_low_pfn * PAGE_SIZE); - /* setup address validity bitmap */ - start_mem = create_mem_holes(start_mem, end_mem); - - start_mem = PAGE_ALIGN(start_mem); - - /* mark usable pages in the mem_map[] */ - mark_usable_memory_areas(start_mem, end_mem); - - /* free unused mem_map[] entries */ - free_unused_mem_map(); - -#define BETWEEN(w,min,max) ((w) >= (unsigned long)(min) && \ - (w) < (unsigned long)(max)) - - for (tmp = PAGE_OFFSET; tmp < end_mem ; tmp += PAGE_SIZE) { - if (PageSkip(mem_map+MAP_NR(tmp))) { - unsigned long next; - - next = mem_map[MAP_NR(tmp)].next_hash - mem_map; - - next = (next << PAGE_SHIFT) + PAGE_OFFSET; - - if (next < tmp || next >= end_mem) - break; - tmp = next; - } - num_physpages++; - if (PageReserved(mem_map+MAP_NR(tmp))) { - if (BETWEEN(tmp, &__init_begin, &__init_end)) - initpages++; - else if (BETWEEN(tmp, &_text, &_etext)) - codepages++; - else if (BETWEEN(tmp, &_etext, &_edata)) - datapages++; - else if (BETWEEN(tmp, &__bss_start, start_mem)) - datapages++; - else - reservedpages++; - continue; - } - atomic_set(&mem_map[MAP_NR(tmp)].count, 1); -#ifdef CONFIG_BLK_DEV_INITRD - if (!initrd_start || !BETWEEN(tmp, initrd_start, initrd_end)) +#ifdef CONFIG_CPU_32 + /* + * We may have non-contiguous memory. Setup the PageSkip stuff, + * and mark the areas of mem_map which can be freed + */ + if (meminfo.nr_banks != 1) + create_memmap_holes(); #endif - free_page(tmp); - } -#undef BETWEEN + /* this will put all unused low memory onto the freelists */ + totalram_pages += free_all_bootmem(); + + /* + * Since our memory may not be contiguous, calculate the + * real number of pages we have in this system + */ + num_physpages = 0; + for (i = 0; i < meminfo.nr_banks; i++) + num_physpages += meminfo.bank[i].size >> PAGE_SHIFT; printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n", (unsigned long) nr_free_pages << (PAGE_SHIFT-10), @@ -265,6 +271,9 @@ datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10)); + /* + * Correct freepages watermarks + */ i = nr_free_pages >> 7; if (PAGE_SIZE < 32768) min_nr = 10; @@ -288,22 +297,26 @@ #endif } -static void free_area(unsigned long addr, unsigned long end, char *s) +static inline void free_area(unsigned long addr, unsigned long end, char *s) { unsigned int size = (end - addr) >> 10; + struct page *page = mem_map + MAP_NR(addr); - for (; addr < end; addr += PAGE_SIZE) { - mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); - atomic_set(&mem_map[MAP_NR(addr)].count, 1); + for (; addr < end; addr += PAGE_SIZE, page ++) { + ClearPageReserved(page); + set_page_count(page, 1); free_page(addr); + totalram_pages++; } if (size) printk(" %dk %s", size, s); } -void free_initmem (void) +void free_initmem(void) { + extern char __init_begin, __init_end; + printk("Freeing unused kernel memory:"); free_area((unsigned long)(&__init_begin), @@ -333,28 +346,11 @@ void si_meminfo(struct sysinfo *val) { - struct page *page, *end; - - val->totalram = 0; + val->totalram = totalram_pages; val->sharedram = 0; - val->freeram = nr_free_pages << PAGE_SHIFT; - val->bufferram = atomic_read(&buffermem); - for (page = mem_map, end = mem_map + max_mapnr; - page < end; page++) { - if (PageSkip(page)) { - if (page->next_hash < page) - break; - page = page->next_hash; - } - if (PageReserved(page)) - continue; - val->totalram++; - if (!atomic_read(&page->count)) - continue; - val->sharedram += atomic_read(&page->count) - 1; - } - val->totalram <<= PAGE_SHIFT; - val->sharedram <<= PAGE_SHIFT; - val->totalbig = 0; - val->freebig = 0; + val->freeram = nr_free_pages; + val->bufferram = atomic_read(&buffermem_pages); + val->totalhigh = 0; + val->freehigh = 0; + val->mem_unit = PAGE_SIZE; } diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/map.h linux/arch/arm/mm/map.h --- v2.3.24/linux/arch/arm/mm/map.h Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/map.h Thu Oct 28 10:16:02 1999 @@ -16,17 +16,9 @@ bufferable:1; }; -struct mem_desc { - unsigned long virt_start; - unsigned long virt_end; -}; - extern struct map_desc io_desc[]; extern unsigned int io_desc_size; -extern struct mem_desc mem_desc[]; -extern unsigned int mem_desc_size; -extern void mark_usable_memory_areas(unsigned long start, unsigned long end); -extern unsigned long create_mem_holes(unsigned long start, unsigned long end); -extern unsigned long setup_page_tables(unsigned long start, unsigned long end); +extern void create_memmap_holes(void); +extern void pagetable_init(void); diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/mm-armo.c linux/arch/arm/mm/mm-armo.c --- v2.3.24/linux/arch/arm/mm/mm-armo.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/mm-armo.c Thu Oct 28 10:16:02 1999 @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -18,40 +19,54 @@ #define MEMC_TABLE_SIZE (256*sizeof(unsigned long)) #define PGD_TABLE_SIZE (PTRS_PER_PGD * BYTES_PER_PTR) -/* - * FIXME: the following over-allocates by 6400% - */ -static inline void *alloc_table(int size, int prio) -{ - if (size != 128) - printk("invalid table size\n"); - return (void *)get_page_8k(prio); -} +int page_nr; + +extern unsigned long get_page_2k(int prio); +extern void free_page_2k(unsigned long); +extern pte_t *get_bad_pte_table(void); /* * Allocate a page table. Note that we place the MEMC * table before the page directory. This means we can * easily get to both tightly-associated data structures - * with a single pointer. This function is slightly - * better - it over-allocates by only 711% + * with a single pointer. + * + * We actually only need 1152 bytes, 896 bytes is wasted. + * We could try to fit 7 PTEs into that slot somehow. */ static inline void *alloc_pgd_table(int priority) { - unsigned long pg8k; + unsigned long pg2k; - pg8k = get_page_8k(priority); - if (pg8k) - pg8k += MEMC_TABLE_SIZE; + pg2k = get_page_2k(priority); + if (pg2k) + pg2k += MEMC_TABLE_SIZE; - return (void *)pg8k; + return (void *)pg2k; } -void free_table(void *table) +void free_pgd_slow(pgd_t *pgd) { - unsigned long tbl = (unsigned long)table; + unsigned long tbl = (unsigned long)pgd; + + tbl -= MEMC_TABLE_SIZE; + free_page_2k(tbl); +} + +/* + * FIXME: the following over-allocates by 1600% + */ +static inline void *alloc_pte_table(int size, int prio) +{ + if (size != 128) + printk("invalid table size\n"); + return (void *)get_page_2k(prio); +} - tbl &= ~8191; - free_page_8k(tbl); +void free_pte_slow(pte_t *pte) +{ + unsigned long tbl = (unsigned long)pte; + free_page_2k(tbl); } pgd_t *get_pgd_slow(void) @@ -62,9 +77,9 @@ if (pgd) { pgd_t *init = pgd_offset(&init_mm, 0); - memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR); + memzero(pgd, USER_PTRS_PER_PGD * sizeof(pgd_t)); memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR); + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); /* * On ARM, first page must always be allocated @@ -92,7 +107,7 @@ nomem_pmd: pmd_free(new_pmd); nomem: - free_table(pgd); + free_pgd_slow(pgd); return NULL; } @@ -100,19 +115,19 @@ { pte_t *pte; - pte = (pte_t *)alloc_table(PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL); + pte = (pte_t *)alloc_pte_table(PTRS_PER_PTE * sizeof(pte_t), GFP_KERNEL); if (pmd_none(*pmd)) { if (pte) { - memzero(pte, PTRS_PER_PTE * BYTES_PER_PTR); - set_pmd(pmd, mk_pmd(pte)); + memzero(pte, PTRS_PER_PTE * sizeof(pte_t)); + set_pmd(pmd, mk_user_pmd(pte)); return pte + offset; } - set_pmd(pmd, mk_pmd(BAD_PAGETABLE)); + set_pmd(pmd, mk_user_pmd(get_bad_pte_table())); return NULL; } - free_table((void *)pte); + free_pte_slow(pte); if (pmd_bad(*pmd)) { - __bad_pmd(pmd); + __handle_bad_pmd(pmd); return NULL; } return (pte_t *) pmd_page(*pmd) + offset; @@ -124,47 +139,22 @@ * some more work to get it to fit into our separate processor and * architecture structure. */ -int page_nr; - -#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR) - -static inline void setup_swapper_dir (int index, pte_t *ptep) +void __init pagetable_init(void) { - set_pmd (pmd_offset (swapper_pg_dir + index, 0), mk_pmd (ptep)); -} - -unsigned long __init -setup_page_tables(unsigned long start_mem, unsigned long end_mem) -{ - unsigned int i; - union { unsigned long l; pte_t *pte; } u; + pte_t *pte; + int i; - page_nr = MAP_NR(end_mem); + page_nr = max_low_pfn; - /* map in pages for (0x0000 - 0x8000) */ - u.l = ((start_mem + (PTE_SIZE-1)) & ~(PTE_SIZE-1)); - start_mem = u.l + PTE_SIZE; - memzero (u.pte, PTE_SIZE); - u.pte[0] = mk_pte(PAGE_OFFSET + 491520, PAGE_READONLY); - setup_swapper_dir (0, u.pte); + pte = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t)); + memzero(pte, PTRS_PER_PTE * sizeof(pte_t)); + pte[0] = mk_pte_phys(PAGE_OFFSET + 491520, PAGE_READONLY); + set_pmd(pmd_offset(swapper_pg_dir, 0), mk_kernel_pmd(pte)); for (i = 1; i < PTRS_PER_PGD; i++) pgd_val(swapper_pg_dir[i]) = 0; - - return start_mem; } -unsigned long __init -create_mem_holes(unsigned long start, unsigned long end) +void __init create_memmap_holes(void) { - return start; -} - -void __init -mark_usable_memory_areas(unsigned long start_mem, unsigned long end_mem) -{ - while (start_mem < end_mem) { - clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags); - start_mem += PAGE_SIZE; - } } diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c --- v2.3.24/linux/arch/arm/mm/mm-armv.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/mm-armv.c Thu Oct 28 10:16:02 1999 @@ -1,22 +1,28 @@ /* - * arch/arm/mm/mm-armv.c + * linux/arch/arm/mm/mm-armv.c * - * Page table sludge for ARM v3 and v4 processor architectures. + * Page table sludge for ARM v3 and v4 processor architectures. * - * Copyright (C) 1998-1999 Russell King + * Copyright (C) 1998-1999 Russell King */ #include #include #include +#include #include #include #include +#include #include "map.h" unsigned long *valid_addr_bitmap; +extern unsigned long get_page_2k(int priority); +extern void free_page_2k(unsigned long page); +extern pte_t *get_bad_pte_table(void); + /* * need to get a 16k page for level 1 */ @@ -26,12 +32,12 @@ pmd_t *new_pmd; if (pgd) { - pgd_t *init = pgd_offset(&init_mm, 0); + pgd_t *init = pgd_offset_k(0); - memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR); + memzero(pgd, USER_PTRS_PER_PGD * sizeof(pgd_t)); memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR); - clean_cache_area(pgd, PTRS_PER_PGD * BYTES_PER_PTR); + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + clean_cache_area(pgd, PTRS_PER_PGD * sizeof(pgd_t)); /* * On ARM, first page must always be allocated @@ -48,7 +54,7 @@ pte_t *new_pte = pte_offset(new_pmd, 0); pte_t *old_pte = pte_offset(old_pmd, 0); - set_pte (new_pte, *old_pte); + set_pte(new_pte, *old_pte); } } } @@ -61,6 +67,31 @@ return NULL; } +void free_pgd_slow(pgd_t *pgd) +{ + if (pgd) { /* can pgd be NULL? */ + pmd_t *pmd; + pte_t *pte; + + /* pgd is always present and good */ + pmd = (pmd_t *)pgd; + if (pmd_none(*pmd)) + goto free; + if (pmd_bad(*pmd)) { + pmd_ERROR(*pmd); + pmd_clear(pmd); + goto free; + } + + pte = pte_offset(pmd, 0); + pmd_clear(pmd); + pte_free(pte); + pmd_free(pmd); + } +free: + free_pages((unsigned long) pgd, 2); +} + pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) { pte_t *pte; @@ -68,18 +99,18 @@ pte = (pte_t *)get_page_2k(GFP_KERNEL); if (pmd_none(*pmd)) { if (pte) { - memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR); - clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR); + memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t)); + clean_cache_area(pte, PTRS_PER_PTE * sizeof(pte_t)); pte += PTRS_PER_PTE; set_pmd(pmd, mk_user_pmd(pte)); return pte + offset; } - set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE)); + set_pmd(pmd, mk_user_pmd(get_bad_pte_table())); return NULL; } free_page_2k((unsigned long)pte); if (pmd_bad(*pmd)) { - __bad_pmd(pmd); + __handle_bad_pmd(pmd); return NULL; } return (pte_t *) pmd_page(*pmd) + offset; @@ -92,23 +123,28 @@ pte = (pte_t *)get_page_2k(GFP_KERNEL); if (pmd_none(*pmd)) { if (pte) { - memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR); - clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR); + memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t)); + clean_cache_area(pte, PTRS_PER_PTE * sizeof(pte_t)); pte += PTRS_PER_PTE; set_pmd(pmd, mk_kernel_pmd(pte)); return pte + offset; } - set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE)); + set_pmd(pmd, mk_kernel_pmd(get_bad_pte_table())); return NULL; } free_page_2k((unsigned long)pte); if (pmd_bad(*pmd)) { - __bad_pmd_kernel(pmd); + __handle_bad_pmd_kernel(pmd); return NULL; } return (pte_t *) pmd_page(*pmd) + offset; } +void free_pte_slow(pte_t *pte) +{ + free_page_2k((unsigned long)(pte - PTRS_PER_PTE)); +} + /* * Create a SECTION PGD between VIRT and PHYS in domain * DOMAIN with protection PROT @@ -131,34 +167,22 @@ * the hardware pte table. */ static inline void -alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot) +alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot) { pmd_t *pmdp; pte_t *ptep; pmdp = pmd_offset(pgd_offset_k(virt), virt); -#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR) - if (pmd_none(*pmdp)) { - unsigned long memory = *mem; - - memory = (memory + PTE_SIZE - 1) & ~(PTE_SIZE - 1); + pte_t *ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * + sizeof(pte_t)); - ptep = (pte_t *)memory; - memzero(ptep, PTE_SIZE); - memory += PTE_SIZE; - - ptep = (pte_t *)memory; - memzero(ptep, PTE_SIZE); + memzero(ptep, 2 * PTRS_PER_PTE * sizeof(pte_t)); + ptep += PTRS_PER_PTE; set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain))); - - *mem = memory + PTE_SIZE; } - -#undef PTE_SIZE - ptep = pte_offset(pmdp, virt); set_pte(ptep, mk_pte_phys(phys, __pgprot(prot))); @@ -169,8 +193,7 @@ * the clearance is done by the middle-level functions (pmd) * rather than the top-level (pgd) functions. */ -static inline void -free_init_section(unsigned long virt) +static inline void free_init_section(unsigned long virt) { pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); } @@ -181,8 +204,7 @@ * are able to cope here with varying sizes and address * offsets, and we take full advantage of sections. */ -static void __init -create_mapping(unsigned long *mem_ptr, struct map_desc *md) +static void __init create_mapping(struct map_desc *md) { unsigned long virt, length; int prot_sect, prot_pte; @@ -205,7 +227,7 @@ length = md->length; while ((virt & 1048575 || (virt + off) & 1048575) && length >= PAGE_SIZE) { - alloc_init_page(mem_ptr, virt, virt + off, md->domain, prot_pte); + alloc_init_page(virt, virt + off, md->domain, prot_pte); virt += PAGE_SIZE; length -= PAGE_SIZE; @@ -219,7 +241,7 @@ } while (length >= PAGE_SIZE) { - alloc_init_page(mem_ptr, virt, virt + off, md->domain, prot_pte); + alloc_init_page(virt, virt + off, md->domain, prot_pte); virt += PAGE_SIZE; length -= PAGE_SIZE; @@ -227,17 +249,15 @@ } /* - * Initial boot-time mapping. This covers just the - * zero page, kernel and the flush area. NB: it - * must be sorted by virtual address, and no + * Initial boot-time mapping. This covers just the zero page, kernel and + * the flush area. NB: it must be sorted by virtual address, and no * virtual address overlaps. - * init_map[2..4] are for architectures with small - * amounts of banked memory. + * init_map[2..4] are for architectures with banked memory. */ static struct map_desc init_map[] __initdata = { { 0, 0, PAGE_SIZE, DOMAIN_USER, 0, 0, 1, 0 }, /* zero page */ { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* kernel memory */ - { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, + { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* (4 banks) */ { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, { 0, 0, PGDIR_SIZE, DOMAIN_KERNEL, 1, 0, 1, 1 }, /* cache flush 1 */ @@ -246,19 +266,15 @@ #define NR_INIT_MAPS (sizeof(init_map) / sizeof(init_map[0])) -unsigned long __init -setup_page_tables(unsigned long start_mem, unsigned long end_mem) +void __init pagetable_init(void) { unsigned long address = 0; - int idx = 0; + int i; /* - * Correct the above mappings + * Setup the above mappings */ - init_map[0].physical = - init_map[1].physical = __virt_to_phys(PAGE_OFFSET); - init_map[1].virtual = PAGE_OFFSET; - init_map[1].length = end_mem - PAGE_OFFSET; + init_map[0].physical = PHYS_OFFSET; init_map[5].physical = FLUSH_BASE_PHYS; init_map[5].virtual = FLUSH_BASE; #ifdef FLUSH_BASE_MINICACHE @@ -267,109 +283,108 @@ init_map[6].length = PGDIR_SIZE; #endif + for (i = 0; i < meminfo.nr_banks; i++) { + init_map[i+1].physical = PHYS_OFFSET + meminfo.bank[i].start; + init_map[i+1].virtual = PAGE_OFFSET + meminfo.bank[i].start; + init_map[i+1].length = meminfo.bank[i].size; + } + /* - * Firstly, go through the initial mappings, - * but clear out any pgdir entries that are - * not in the description. + * Go through the initial mappings, but clear out any + * pgdir entries that are not in the description. */ + i = 0; do { - if (address < init_map[idx].virtual || idx == NR_INIT_MAPS) { + if (address < init_map[i].virtual || i == NR_INIT_MAPS) { free_init_section(address); address += PGDIR_SIZE; } else { - create_mapping(&start_mem, init_map + idx); + create_mapping(init_map + i); - address = init_map[idx].virtual + init_map[idx].length; + address = init_map[i].virtual + init_map[i].length; address = (address + PGDIR_SIZE - 1) & PGDIR_MASK; do { - idx += 1; - } while (init_map[idx].length == 0 && idx < NR_INIT_MAPS); + i += 1; + } while (init_map[i].length == 0 && i < NR_INIT_MAPS); } } while (address != 0); /* - * Now, create the architecture specific mappings + * Create the architecture specific mappings */ - for (idx = 0; idx < io_desc_size; idx++) - create_mapping(&start_mem, io_desc + idx); + for (i = 0; i < io_desc_size; i++) + create_mapping(io_desc + i); flush_cache_all(); - - return start_mem; } /* - * The mem_map array can get very big. Mark the end of the - * valid mem_map banks with PG_skip, and setup the address - * validity bitmap. + * The mem_map array can get very big. Mark the end of the valid mem_map + * banks with PG_skip, and setup the address validity bitmap. */ -unsigned long __init -create_mem_holes(unsigned long start_mem, unsigned long end_mem) +void __init create_memmap_holes(void) { + unsigned int start_pfn, end_pfn = -1; struct page *pg = NULL; unsigned int sz, i; - if (!machine_is_riscpc()) - return start_mem; + for (i = 0; i < meminfo.nr_banks; i++) { + if (meminfo.bank[i].size == 0) + continue; - sz = (end_mem - PAGE_OFFSET) >> 20; - sz = (sz + 31) >> 3; - - valid_addr_bitmap = (unsigned long *)start_mem; - start_mem += sz; + start_pfn = meminfo.bank[i].start >> PAGE_SHIFT; - memset(valid_addr_bitmap, 0, sz); + /* + * subtle here - if we have a full bank, then + * start_pfn == end_pfn, and we don't want to + * set PG_skip, or next_hash + */ + if (pg && start_pfn != end_pfn) { + set_bit(PG_skip, &pg->flags); + pg->next_hash = mem_map + start_pfn; - if (start_mem > mem_desc[0].virt_end) - printk(KERN_CRIT "*** Error: RAM bank 0 too small\n"); + start_pfn = PAGE_ALIGN(__pa(pg + 1)); + end_pfn = __pa(pg->next_hash) & PAGE_MASK; - for (i = 0; i < mem_desc_size; i++) { - unsigned int idx, end; + if (end_pfn != start_pfn) + free_bootmem(start_pfn, end_pfn - start_pfn); - if (pg) { - pg->next_hash = mem_map + - MAP_NR(mem_desc[i].virt_start); pg = NULL; } - idx = __kern_valid_idx(mem_desc[i].virt_start); - end = __kern_valid_idx(mem_desc[i].virt_end); - - do - set_bit(idx, valid_addr_bitmap); - while (++idx < end); - - if (mem_desc[i].virt_end < end_mem) { - pg = mem_map + MAP_NR(mem_desc[i].virt_end); + end_pfn = (meminfo.bank[i].start + + meminfo.bank[i].size) >> PAGE_SHIFT; - set_bit(PG_skip, &pg->flags); - } + if (end_pfn != meminfo.end >> PAGE_SHIFT) + pg = mem_map + end_pfn; } - if (pg) + if (pg) { + set_bit(PG_skip, &pg->flags); pg->next_hash = NULL; - - return start_mem; -} - -void __init -mark_usable_memory_areas(unsigned long start_mem, unsigned long end_mem) -{ - /* - * Mark all of memory from the end of kernel to end of memory - */ - while (start_mem < end_mem) { - clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags); - start_mem += PAGE_SIZE; } +#if 0 /* - * Mark memory from page 1 to start of the swapper page directory + * setup address validity map + * - don't think this is used anymore? */ - start_mem = PAGE_OFFSET + PAGE_SIZE; - while (start_mem < (unsigned long)&swapper_pg_dir) { - clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags); - start_mem += PAGE_SIZE; + sz = meminfo.end >> (PAGE_SHIFT + 8); /* in MB */ + sz = (sz + 31) >> 3; + + valid_addr_bitmap = alloc_bootmem(sz); + memzero(valid_addr_bitmap, sz); + + for (i = 0; i < meminfo.nr_banks; i++) { + int idx, end; + + idx = meminfo.bank[i].start >> 20; + end = (meminfo.bank[i].start + + meminfo.bank[i].size) >> 20; + do + set_bit(idx, valid_addr_bitmap); + while (++idx < end); } -} +#endif +} diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/mm-ebsa110.c linux/arch/arm/mm/mm-ebsa110.c --- v2.3.24/linux/arch/arm/mm/mm-ebsa110.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/mm-ebsa110.c Fri Oct 29 11:42:57 1999 @@ -13,17 +13,11 @@ #include "map.h" -struct mem_desc mem_desc[] __initdata = { - 0, 0 -}; - -unsigned int __initdata mem_desc_size = 0; +#define SIZE(x) (sizeof(x) / sizeof(x[0])) const struct map_desc io_desc[] __initdata = { { IO_BASE - PGDIR_SIZE, 0xc0000000, PGDIR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 } }; -#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0])) - -unsigned int __initdata io_desc_size = SIZEOFMAP; +unsigned int __initdata io_desc_size = SIZE(io_desc); diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/mm-footbridge.c linux/arch/arm/mm/mm-footbridge.c --- v2.3.24/linux/arch/arm/mm/mm-footbridge.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/mm-footbridge.c Fri Oct 29 11:42:57 1999 @@ -17,6 +17,8 @@ #include "map.h" +#define SIZE(x) (sizeof(x) / sizeof(x[0])) + /* * The first entry allows us to fiddle with the EEPROM from user-space. * This entry will go away in time, once the fmu32 can mmap() the @@ -89,17 +91,9 @@ #endif -struct mem_desc mem_desc[] __initdata = { - 0, 0 -}; - -unsigned int __initdata mem_desc_size = 0; - struct map_desc io_desc[] __initdata = { MAPPING }; - -#define SIZE(x) (sizeof(x) / sizeof(x[0])) unsigned int __initdata io_desc_size = SIZE(io_desc); diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/mm-nexuspci.c linux/arch/arm/mm/mm-nexuspci.c --- v2.3.24/linux/arch/arm/mm/mm-nexuspci.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/mm-nexuspci.c Fri Oct 29 11:42:57 1999 @@ -18,11 +18,7 @@ #include "map.h" -struct mem_desc mem_desc[] __initdata = { - 0, 0 -}; - -unsigned int __initdata mem_desc_size = 0; +#define SIZE(x) (sizeof(x) / sizeof(x[0])) const struct map_desc io_desc[] __initdata = { { 0xfff00000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, @@ -32,6 +28,4 @@ { 0xfd000000, 0x88000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 } }; -#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0])) - -unsigned int __initdata io_desc_size = SIZEOFMAP; +unsigned int __initdata io_desc_size = SIZE(io_desc); diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/mm-rpc.c linux/arch/arm/mm/mm-rpc.c --- v2.3.24/linux/arch/arm/mm/mm-rpc.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/mm-rpc.c Thu Oct 28 10:16:02 1999 @@ -16,28 +16,6 @@ #define SIZE(x) (sizeof(x) / sizeof(x[0])) -struct mem_desc mem_desc[] __initdata = { - { 0xc0000000, 0xc0000000 }, - { 0xc4000000, 0xc4000000 }, - { 0xc8000000, 0xc8000000 }, - { 0xcc000000, 0xcc000000 } -}; - -unsigned int __initdata mem_desc_size = SIZE(mem_desc); - -void __init -init_dram_banks(struct param_struct *params) -{ - unsigned int bank; - - for (bank = 0; bank < mem_desc_size; bank++) - mem_desc[bank].virt_end += PAGE_SIZE * - params->u1.s.pages_in_bank[bank]; - - params->u1.s.nr_pages = mem_desc[3].virt_end - PAGE_OFFSET; - params->u1.s.nr_pages /= PAGE_SIZE; -} - struct map_desc io_desc[] __initdata = { /* VRAM */ { SCREEN2_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 }, diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/mm-tbox.c linux/arch/arm/mm/mm-tbox.c --- v2.3.24/linux/arch/arm/mm/mm-tbox.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/mm-tbox.c Fri Oct 29 11:42:57 1999 @@ -18,11 +18,7 @@ #include "map.h" -struct mem_desc mem_desc[] __initdata = { - 0, 0 -}; - -unsigned int __initdata mem_desc_size = 0; +#define SIZE(x) (sizeof(x) / sizeof(x[0])) /* Logical Physical * 0xffff1000 0x00100000 DMA registers @@ -60,6 +56,4 @@ { 0xffffe000, 0x00e00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 } }; -#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0])) - -unsigned int __initdata io_desc_size = SIZEOFMAP; +unsigned int __initdata io_desc_size = SIZE(io_desc); diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/proc-arm2,3.S linux/arch/arm/mm/proc-arm2,3.S --- v2.3.24/linux/arch/arm/mm/proc-arm2,3.S Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/proc-arm2,3.S Thu Oct 28 10:16:02 1999 @@ -327,7 +327,7 @@ arm3_elf_name: .asciz "v2" .align - .section ".proc.info", #alloc + .section ".proc.info", #alloc, #execinstr .long 0x41560200 .long 0xfffffff0 diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/proc-arm6,7.S linux/arch/arm/mm/proc-arm6,7.S --- v2.3.24/linux/arch/arm/mm/proc-arm6,7.S Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/proc-arm6,7.S Thu Oct 28 10:16:02 1999 @@ -532,7 +532,7 @@ .size cpu_elf_name, . - cpu_elf_name .align - .section ".proc.info", #alloc + .section ".proc.info", #alloc, #execinstr .type __arm6_proc_info, #object __arm6_proc_info: diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/proc-sa110.S linux/arch/arm/mm/proc-sa110.S --- v2.3.24/linux/arch/arm/mm/proc-sa110.S Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/mm/proc-sa110.S Thu Oct 28 10:16:02 1999 @@ -446,7 +446,8 @@ bl cpu_sa110_flush_tlb_all mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches mrc p15, 0, r0, c1, c0, 0 @ ctrl register - bic r0, r0, #1 @ ...............m + bic r0, r0, #0x000f @ ............wcam + bic r0, r0, #0x1100 @ ...i...s........ ldmfd sp!, {r1, pc} /* * Purpose : Function pointers used to access above functions - all calls @@ -546,6 +547,7 @@ .align .section ".proc.info", #alloc, #execinstr + .type __sa110_proc_info,#object __sa110_proc_info: .long 0x4401a100 diff -u --recursive --new-file v2.3.24/linux/arch/arm/mm/small_page.c linux/arch/arm/mm/small_page.c --- v2.3.24/linux/arch/arm/mm/small_page.c Sat May 8 11:06:57 1999 +++ linux/arch/arm/mm/small_page.c Thu Oct 28 10:16:02 1999 @@ -21,205 +21,201 @@ #include #include -#if PAGE_SIZE == 4096 -/* 2K blocks */ -#define SMALL_ALLOC_SHIFT (11) -#define NAME(x) x##_2k -#elif PAGE_SIZE == 32768 || PAGE_SIZE == 16384 -/* 8K blocks */ -#define SMALL_ALLOC_SHIFT (13) -#define NAME(x) x##_8k -#endif +#include +#include -#define SMALL_ALLOC_SIZE (1 << SMALL_ALLOC_SHIFT) -#define NR_BLOCKS (PAGE_SIZE / SMALL_ALLOC_SIZE) -#define BLOCK_MASK ((1 << NR_BLOCKS) - 1) - -#define USED(pg) ((atomic_read(&(pg)->count) >> 8) & BLOCK_MASK) -#define SET_USED(pg,off) (atomic_read(&(pg)->count) |= 256 << off) -#define CLEAR_USED(pg,off) (atomic_read(&(pg)->count) &= ~(256 << off)) -#define ALL_USED BLOCK_MASK -#define IS_FREE(pg,off) (!(atomic_read(&(pg)->count) & (256 << off))) -#define SM_PAGE_PTR(page,block) ((struct free_small_page *)((page) + \ - ((block) << SMALL_ALLOC_SHIFT))) +#define PEDANTIC -#if NR_BLOCKS != 2 && NR_BLOCKS != 4 -#error I only support 2 or 4 blocks per page -#endif +/* + * Requirement: + * We need to be able to allocate naturally aligned memory of finer + * granularity than the page size. This is typically used for the + * second level page tables on 32-bit ARMs. + * + * Theory: + * We "misuse" the Linux memory management system. We use __get_pages + * to allocate a page and then mark it as reserved. The Linux memory + * management system will then ignore the "offset", "next_hash" and + * "pprev_hash" entries in the mem_map for this page. + * + * We then use a bitstring in the "offset" field to mark which segments + * of the page are in use, and manipulate this as required during the + * allocation and freeing of these small pages. + * + * We also maintain a queue of pages being used for this purpose using + * the "next_hash" and "pprev_hash" entries of mem_map; + */ -struct free_small_page { - unsigned long next; - unsigned long prev; +struct order { + struct page *queue; + unsigned int mask; /* (1 << shift) - 1 */ + unsigned int shift; /* (1 << shift) size of page */ + unsigned int block_mask; /* nr_blocks - 1 */ + unsigned int all_used; /* (1 << nr_blocks) - 1 */ }; -/* - * To handle allocating small pages, we use the main get_free_page routine, - * and split the page up into 4. The page is marked in mem_map as reserved, - * so it can't be free'd by free_page. The count field is used to keep track - * of which sections of this page are allocated. - */ -static unsigned long small_page_ptr; -static unsigned char offsets[1<next = fsp->prev = 0; - } -} +#define USED_MAP(pg) ((pg)->offset) +#define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &(pg)->offset)) +#define SET_USED(pg,off) (set_bit(off, &(pg)->offset)) -static inline void set_page_links_prev(unsigned long page, unsigned long prev) +static void add_page_to_queue(struct page *page, struct page **p) { - struct free_small_page *fsp; - unsigned int mask; - int i; - - if (!page) - return; - - mask = USED(&mem_map[MAP_NR(page)]); - for (i = 0; i < NR_BLOCKS; i++) { - if (mask & (1 << i)) - continue; - fsp = SM_PAGE_PTR(page, i); - fsp->prev = prev; - } +#ifdef PEDANTIC + if (page->pprev_hash) + PAGE_BUG(page); +#endif + page->next_hash = *p; + if (*p) + (*p)->pprev_hash = &page->next_hash; + *p = page; + page->pprev_hash = p; } -static inline void set_page_links_next(unsigned long page, unsigned long next) +static void remove_page_from_queue(struct page *page) { - struct free_small_page *fsp; - unsigned int mask; - int i; - - if (!page) - return; - - mask = USED(&mem_map[MAP_NR(page)]); - for (i = 0; i < NR_BLOCKS; i++) { - if (mask & (1 << i)) - continue; - fsp = SM_PAGE_PTR(page, i); - fsp->next = next; + if (page->pprev_hash) { + if (page->next_hash) + page->next_hash->pprev_hash = page->pprev_hash; + *page->pprev_hash = page->next_hash; + page->pprev_hash = NULL; } } -unsigned long NAME(get_page)(int priority) +static unsigned long __get_small_page(int priority, struct order *order) { - struct free_small_page *fsp; - unsigned long new_page; unsigned long flags; struct page *page; int offset; save_flags(flags); - if (!small_page_ptr) + if (!order->queue) goto need_new_page; + cli(); + page = order->queue; again: - page = mem_map + MAP_NR(small_page_ptr); - offset = offsets[USED(page)]; +#ifdef PEDANTIC + if (USED_MAP(page) & ~order->all_used) + PAGE_BUG(page); +#endif + offset = ffz(USED_MAP(page)); SET_USED(page, offset); - new_page = (unsigned long)SM_PAGE_PTR(small_page_ptr, offset); - if (USED(page) == ALL_USED) { - fsp = (struct free_small_page *)new_page; - set_page_links_prev (fsp->next, 0); - small_page_ptr = fsp->next; - } + if (USED_MAP(page) == order->all_used) + remove_page_from_queue(page); restore_flags(flags); - return new_page; + + return page_address(page) + (offset << order->shift); need_new_page: - new_page = __get_free_page(priority); - if (!small_page_ptr) { - if (new_page) { - set_bit (PG_reserved, &mem_map[MAP_NR(new_page)].flags); - clear_page_links (new_page); - cli(); - small_page_ptr = new_page; - goto again; - } - restore_flags(flags); - return 0; + page = __get_pages(priority, 0); + if (!order->queue) { + if (!page) + goto no_page; + SetPageReserved(page); + USED_MAP(page) = 0; + cli(); + add_page_to_queue(page, &order->queue); + } else { + __free_page(page); + cli(); + page = order->queue; } - free_page(new_page); - cli(); goto again; + +no_page: + restore_flags(flags); + return 0; } -void NAME(free_page)(unsigned long spage) +static void __free_small_page(unsigned long spage, struct order *order) { - struct free_small_page *ofsp, *cfsp; unsigned long flags; + unsigned long nr; struct page *page; - int offset, oldoffset; - if (!spage) - goto none; + nr = MAP_NR(spage); + if (nr < max_mapnr) { + page = mem_map + nr; + + /* + * The container-page must be marked Reserved + */ + if (!PageReserved(page) || spage & order->mask) + goto non_small; + +#ifdef PEDANTIC + if (USED_MAP(page) & ~order->all_used) + PAGE_BUG(page); +#endif + + spage = spage >> order->shift; + spage &= order->block_mask; + + /* + * the following must be atomic wrt get_page + */ + save_flags_cli(flags); - offset = (spage >> SMALL_ALLOC_SHIFT) & (NR_BLOCKS - 1); - spage -= offset << SMALL_ALLOC_SHIFT; + if (USED_MAP(page) == order->all_used) + add_page_to_queue(page, &order->queue); + + if (!TEST_AND_CLEAR_USED(page, spage)) + goto already_free; + + if (USED_MAP(page) == 0) + goto free_page; - page = mem_map + MAP_NR(spage); - if (!PageReserved(page) || !USED(page)) - goto non_small; - - if (IS_FREE(page, offset)) - goto free; - - save_flags_cli (flags); - oldoffset = offsets[USED(page)]; - CLEAR_USED(page, offset); - ofsp = SM_PAGE_PTR(spage, oldoffset); - cfsp = SM_PAGE_PTR(spage, offset); - - if (oldoffset == NR_BLOCKS) { /* going from totally used to mostly used */ - cfsp->prev = 0; - cfsp->next = small_page_ptr; - set_page_links_prev (small_page_ptr, spage); - small_page_ptr = spage; - } else if (!USED(page)) { - set_page_links_prev (ofsp->next, ofsp->prev); - set_page_links_next (ofsp->prev, ofsp->next); - if (spage == small_page_ptr) - small_page_ptr = ofsp->next; - clear_bit (PG_reserved, &page->flags); restore_flags(flags); - free_page (spage); - } else - *cfsp = *ofsp; + } + return; + +free_page: + /* + * unlink the page from the small page queue and free it + */ + remove_page_from_queue(page); restore_flags(flags); + ClearPageReserved(page); + __free_page(page); return; non_small: - printk ("Trying to free non-small page from %p\n", __builtin_return_address(0)); - return; -free: - printk ("Trying to free free small page from %p\n", __builtin_return_address(0)); -none: + printk("Trying to free non-small page from %p\n", __builtin_return_address(0)); return; +already_free: + printk("Trying to free free small page from %p\n", __builtin_return_address(0)); +} + +unsigned long get_page_2k(int priority) +{ + return __get_small_page(priority, orders+0); +} + +void free_page_2k(unsigned long spage) +{ + __free_small_page(spage, orders+0); } + +#if PAGE_SIZE > 8192 +unsigned long get_page_8k(int priority) +{ + return __get_small_page(priority, orders+1); +} + +void free_page_8k(unsigned long spage) +{ + __free_small_page(spage, orders+1); +} +#endif diff -u --recursive --new-file v2.3.24/linux/arch/arm/vmlinux-armo.lds.in linux/arch/arm/vmlinux-armo.lds.in --- v2.3.24/linux/arch/arm/vmlinux-armo.lds.in Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/vmlinux-armo.lds.in Thu Oct 28 10:16:02 1999 @@ -7,7 +7,8 @@ SECTIONS { . = TEXTADDR; - __init_begin = .; + + __init_begin = .; /* Init code and data */ .text.init : { *(.text.init) } __proc_info_begin = .; .proc.info : { *(.proc.info) } @@ -27,43 +28,44 @@ *(.init.task) } - _text = .; /* Text and read-only data */ + _text = .; /* Text and read-only data */ .text : { *(.text) *(.fixup) *(.gnu.warning) } + .text.lock : { *(.text.lock) } /* out-of-line lock text */ .rodata : { *(.rodata) } .kstrtab : { *(.kstrtab) } - . = ALIGN(16); /* Exception table */ + . = ALIGN(16); /* Exception table */ __start___ex_table = .; __ex_table : { *(__ex_table) } __stop___ex_table = .; - __start___ksymtab = .; /* Kernel symbol table */ + __start___ksymtab = .; /* Kernel symbol table */ __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; - .got : { *(.got) } /* Global offset table */ + .got : { *(.got) } /* Global offset table */ - _etext = .; /* End of text section */ + _etext = .; /* End of text section */ - .data : { /* Data */ + .data : { /* Data */ *(.data) CONSTRUCTORS } - _edata = .; /* End of data section */ + _edata = .; /* End of data section */ - __bss_start = .; /* BSS */ + __bss_start = .; /* BSS */ .bss : { *(.bss) } _end = . ; - /* Stabs debugging sections. */ + /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } diff -u --recursive --new-file v2.3.24/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c --- v2.3.24/linux/arch/i386/kernel/apm.c Mon Oct 11 15:38:14 1999 +++ linux/arch/i386/kernel/apm.c Mon Nov 1 13:33:04 1999 @@ -1,8 +1,8 @@ /* -*- linux-c -*- * APM BIOS driver for Linux - * Copyright 1994-1998 Stephen Rothwell - * (Stephen.Rothwell@canb.auug.org.au) - * Development of this driver was funded by NEC Australia P/L + * Copyright 1994-1999 Stephen Rothwell (sfr@linuxcare.com) + * + * Initial development of this driver was funded by NEC Australia P/L * and NEC Corporation * * This program is free software; you can redistribute it and/or modify it @@ -133,6 +133,12 @@ #include #include +/* + * Make APM look as much as just another ACPI module as possible.. + */ +#include + + EXPORT_SYMBOL(apm_register_callback); EXPORT_SYMBOL(apm_unregister_callback); @@ -1400,6 +1406,11 @@ apm_bios_info.flags &= ~APM_BIOS_DISENGAGED; } +/* Install our power off handler.. */ +#ifdef CONFIG_APM_POWER_OFF + acpi_power_off = apm_power_off; +#endif + apm_mainloop(); return 0; } @@ -1441,8 +1452,6 @@ */ static int __init apm_init(void) { - static struct proc_dir_entry *ent; - if (apm_bios_info.version == 0) { printk(KERN_INFO "apm: BIOS not found.\n"); return -1; @@ -1536,9 +1545,7 @@ } #endif - ent = create_proc_entry("apm", 0, 0); - if (ent != NULL) - ent->get_info = apm_get_info; + create_proc_info_entry("apm", 0, 0, apm_get_info); misc_register(&apm_device); diff -u --recursive --new-file v2.3.24/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- v2.3.24/linux/arch/i386/kernel/entry.S Fri Oct 15 15:25:13 1999 +++ linux/arch/i386/kernel/entry.S Fri Oct 29 13:19:49 1999 @@ -476,7 +476,7 @@ .long SYMBOL_NAME(sys_sigpending) .long SYMBOL_NAME(sys_sethostname) .long SYMBOL_NAME(sys_setrlimit) /* 75 */ - .long SYMBOL_NAME(sys_getrlimit) + .long SYMBOL_NAME(sys_old_getrlimit) .long SYMBOL_NAME(sys_getrusage) .long SYMBOL_NAME(sys_gettimeofday) .long SYMBOL_NAME(sys_settimeofday) @@ -591,6 +591,7 @@ .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */ .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */ .long SYMBOL_NAME(sys_vfork) /* 190 */ + .long SYMBOL_NAME(sys_getrlimit) /* * NOTE!! This doesn't have to be exact - we just have @@ -598,6 +599,6 @@ * entries. Don't panic if you notice that this hasn't * been shrunk every time we add a new system call. */ - .rept NR_syscalls-190 + .rept NR_syscalls-191 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -u --recursive --new-file v2.3.24/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.3.24/linux/arch/i386/kernel/i386_ksyms.c Wed Oct 27 16:34:12 1999 +++ linux/arch/i386/kernel/i386_ksyms.c Mon Nov 1 13:28:43 1999 @@ -45,6 +45,7 @@ EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(acpi_idle); +EXPORT_SYMBOL(acpi_power_off); EXPORT_SYMBOL_NOVERS(__down_failed); EXPORT_SYMBOL_NOVERS(__down_failed_interruptible); diff -u --recursive --new-file v2.3.24/linux/arch/i386/kernel/mca.c linux/arch/i386/kernel/mca.c --- v2.3.24/linux/arch/i386/kernel/mca.c Wed Aug 18 11:25:29 1999 +++ linux/arch/i386/kernel/mca.c Thu Oct 28 14:34:45 1999 @@ -705,11 +705,11 @@ if(mca_info == NULL) return; /* Should never happen */ - proc_register(&proc_mca, &(struct proc_dir_entry) { + proc_register(proc_mca, &(struct proc_dir_entry) { PROC_MCA_REGISTERS, 3, "pos", S_IFREG|S_IRUGO, 1, 0, 0, 0, &proc_mca_inode_operations,}); - proc_register(&proc_mca, &(struct proc_dir_entry) { + proc_register(proc_mca, &(struct proc_dir_entry) { PROC_MCA_MACHINE, 7, "machine", S_IFREG|S_IRUGO, 1, 0, 0, 0, &proc_mca_inode_operations,}); @@ -745,7 +745,7 @@ node->name = mca_info->slot[i].procname; node->mode = S_IFREG | S_IRUGO; node->ops = &proc_mca_inode_operations; - proc_register(&proc_mca, node); + proc_register(proc_mca, node); } } /* mca_do_proc_init() */ diff -u --recursive --new-file v2.3.24/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c --- v2.3.24/linux/arch/i386/kernel/mtrr.c Sat Oct 9 11:47:50 1999 +++ linux/arch/i386/kernel/mtrr.c Thu Oct 28 14:34:45 1999 @@ -1516,7 +1516,7 @@ }; static struct proc_dir_entry proc_root_mtrr = { - PROC_MTRR, 4, "mtrr", + 0, 4, "mtrr", S_IFREG | S_IWUSR | S_IRUGO, 1, 0, 0, 0, &proc_mtrr_inode_operations }; diff -u --recursive --new-file v2.3.24/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.3.24/linux/arch/i386/kernel/process.c Wed Oct 27 16:34:12 1999 +++ linux/arch/i386/kernel/process.c Mon Nov 1 13:32:10 1999 @@ -29,9 +29,6 @@ #include #include #include -#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF) -#include -#endif #include #include @@ -67,6 +64,11 @@ void (*acpi_idle)(void) = NULL; /* + * Power off function, if any + */ +void (*acpi_power_off)(void) = NULL; + +/* * The idle thread. There's no useful work to be * done, so just try to conserve power and have a * low exit latency (ie sit in a loop waiting for @@ -310,9 +312,8 @@ void machine_power_off(void) { -#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF) - apm_power_off(); -#endif + if (acpi_power_off) + acpi_power_off(); } diff -u --recursive --new-file v2.3.24/linux/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c --- v2.3.24/linux/arch/i386/kernel/smpboot.c Fri Oct 22 13:21:45 1999 +++ linux/arch/i386/kernel/smpboot.c Wed Oct 27 18:40:00 1999 @@ -821,8 +821,9 @@ * could use the real zero-page, but it's safer * this way if some buggy code writes to this page ... */ - apic_phys = __pa(alloc_bootmem_pages(PAGE_SIZE)); + apic_phys = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); memset((void *)apic_phys, 0, PAGE_SIZE); + apic_phys = __pa(apic_phys); } set_fixmap(FIX_APIC_BASE, apic_phys); dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys); @@ -836,8 +837,9 @@ if (smp_found_config) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; } else { - ioapic_phys = __pa(alloc_bootmem_pages(PAGE_SIZE)); + ioapic_phys = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); memset((void *)ioapic_phys, 0, PAGE_SIZE); + ioapic_phys = __pa(ioapic_phys); } set_fixmap(idx,ioapic_phys); dprintk("mapped IOAPIC to %08lx (%08lx)\n", diff -u --recursive --new-file v2.3.24/linux/arch/i386/lib/mmx.c linux/arch/i386/lib/mmx.c --- v2.3.24/linux/arch/i386/lib/mmx.c Mon Oct 11 15:38:14 1999 +++ linux/arch/i386/lib/mmx.c Wed Oct 27 18:30:39 1999 @@ -89,7 +89,7 @@ return p; } -static void fast_clear_page(long page) +static void fast_clear_page(void *page) { int i; if (!(current->flags & PF_USEDFPU)) @@ -129,7 +129,7 @@ stts(); } -static void fast_copy_page(long to, long from) +static void fast_copy_page(void *to, void *from) { int i; if (!(current->flags & PF_USEDFPU)) @@ -196,7 +196,7 @@ * Favour MMX for page clear and copy. */ -static void slow_zero_page(long page) +static void slow_zero_page(void * page) { int d0, d1; __asm__ __volatile__( \ @@ -207,7 +207,7 @@ :"memory"); } -void mmx_clear_page(long page) +void mmx_clear_page(void * page) { if(in_interrupt()) slow_zero_page(page); @@ -215,7 +215,7 @@ fast_clear_page(page); } -static void slow_copy_page(long to, long from) +static void slow_copy_page(void *to, void *from) { int d0, d1, d2; __asm__ __volatile__( \ @@ -227,7 +227,7 @@ } -void mmx_copy_page(long to, long from) +void mmx_copy_page(void *to, void *from) { if(in_interrupt()) slow_copy_page(to, from); diff -u --recursive --new-file v2.3.24/linux/arch/m68k/mac/iop.c linux/arch/m68k/mac/iop.c --- v2.3.24/linux/arch/m68k/mac/iop.c Tue Sep 7 12:14:06 1999 +++ linux/arch/m68k/mac/iop.c Thu Oct 28 14:34:45 1999 @@ -125,21 +125,9 @@ int iop_scc_present,iop_ism_present; #ifdef CONFIG_PROC_FS - -/* - * sneaky reuse of the PROC_MAC_VIA inode. It's not needed by via.c - * anymore so we'll use it to debut the IOPs. - */ - -int iop_get_proc_info(char *, char **, off_t, int, int); - -static struct proc_dir_entry proc_mac_iop = { - PROC_MAC_VIA, 7, "mac_iop", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - &iop_get_proc_info -}; - +static int iop_get_proc_info(char *, char **, off_t, int, int); +#else +static int iop_get_proc_info(char *, char **, off_t, int, int) {} #endif /* CONFIG_PROC_FS */ /* structure for tracking channel listeners */ @@ -315,9 +303,7 @@ iop_listeners[IOP_NUM_ISM][i].handler = NULL; } -#ifdef CONFIG_PROC_FS - proc_register(&proc_root, &proc_mac_iop); -#endif + create_proc_info_entry("mac_iop",0,0,iop_get_proc_info); } /* @@ -722,4 +708,5 @@ } return (count > cnt) ? cnt : count; } + #endif /* CONFIG_PROC_FS */ diff -u --recursive --new-file v2.3.24/linux/arch/mips/config.in linux/arch/mips/config.in --- v2.3.24/linux/arch/mips/config.in Sat Oct 9 11:47:50 1999 +++ linux/arch/mips/config.in Thu Oct 28 10:45:51 1999 @@ -177,13 +177,12 @@ if [ "$CONFIG_SGI" = "y" ]; then bool ' SGI Seeq ethernet controller support' CONFIG_SGISEEQ fi - if [ "$CONFIG_DECSTATION" = "y" ]; then - bool ' DEC LANCE ethernet controller support' CONFIG_DECLANCE - fi - if [ "$CONFIG_BAGET_MIPS" = "y" ]; then - tristate ' Baget AMD LANCE support' CONFIG_BAGETLANCE - tristate ' Baget Backplane Shared Memory support' CONFIG_BAGETBSM - fi + if [ "$CONFIG_DECSTATION" = "y" ]; then + bool ' DEC LANCE ethernet controller support' CONFIG_DECLANCE + fi + if [ "$CONFIG_BAGET_MIPS" = "y" ]; then + tristate ' Baget AMD LANCE support' CONFIG_BAGETLANCE + tristate ' Baget Backplane Shared Memory support' CONFIG_BAGETBSM fi fi endmenu @@ -206,7 +205,7 @@ mainmenu_option next_comment - comment comment 'Old CD-ROM drivers (not SCSI, not IDE)' + comment 'Old CD-ROM drivers (not SCSI, not IDE)' bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then diff -u --recursive --new-file v2.3.24/linux/arch/ppc/config.in linux/arch/ppc/config.in --- v2.3.24/linux/arch/ppc/config.in Fri Oct 15 15:25:13 1999 +++ linux/arch/ppc/config.in Thu Oct 28 10:45:51 1999 @@ -5,6 +5,11 @@ mainmenu_name "Linux/PowerPC Kernel Configuration" mainmenu_option next_comment +comment 'Code maturity level options' +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL +endmenu + +mainmenu_option next_comment comment 'Platform support' define_bool CONFIG_PPC y choice 'Processor type' \ @@ -53,14 +58,16 @@ endmenu mainmenu_option next_comment -comment 'General setup' - -bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL +comment 'Loadable module support' bool 'Enable loadable module support' CONFIG_MODULES if [ "$CONFIG_MODULES" = "y" ]; then - bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool 'Kernel module loader' CONFIG_KMOD + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD fi +endmenu + +mainmenu_option next_comment +comment 'General setup' if [ "$CONFIG_APUS" = "y" ]; then define_bool CONFIG_PCI n diff -u --recursive --new-file v2.3.24/linux/arch/sparc/config.in linux/arch/sparc/config.in --- v2.3.24/linux/arch/sparc/config.in Tue Aug 31 17:29:13 1999 +++ linux/arch/sparc/config.in Mon Nov 1 10:31:28 1999 @@ -10,62 +10,55 @@ endmenu mainmenu_option next_comment -comment 'Loadable module support' -bool 'Enable loadable module support' CONFIG_MODULES -if [ "$CONFIG_MODULES" = "y" ]; then - bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool 'Kernel module loader' CONFIG_KMOD -fi -endmenu - -mainmenu_option next_comment comment 'General setup' define_bool CONFIG_VT y define_bool CONFIG_VT_CONSOLE y -bool 'Support for AP1000 multicomputer' CONFIG_AP1000 bool 'Symmetric multi-processing support (does not work on sun4/sun4c)' CONFIG_SMP +bool 'Support for AP1000 multicomputer' CONFIG_AP1000 if [ "$CONFIG_AP1000" = "y" ]; then - define_bool CONFIG_NO_KEYBOARD y - define_bool CONFIG_FDDI y - define_bool CONFIG_APFDDI y - define_bool CONFIG_APBLOCK y - define_bool CONFIG_APBIF y - tristate 'OPIU DDV Driver' CONFIG_DDV + define_bool CONFIG_NO_KEYBOARD y + define_bool CONFIG_FDDI y + define_bool CONFIG_APFDDI y + define_bool CONFIG_APBLOCK y + define_bool CONFIG_APBIF y + tristate ' OPIU DDV Driver' CONFIG_DDV else - bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4 - if [ "$CONFIG_SUN4" != "y" ]; then - bool 'Support for PCI and PS/2 keyboard/mouse' CONFIG_PCI - fi - - mainmenu_option next_comment - comment 'Console drivers' - bool 'PROM console' CONFIG_PROM_CONSOLE - bool 'Support Frame buffer devices' CONFIG_FB - source drivers/video/Config.in - endmenu - - # Global things across all Sun machines. - define_bool CONFIG_SBUS y - define_bool CONFIG_SBUSCHAR y - define_bool CONFIG_BUSMOUSE y - define_bool CONFIG_SUN_MOUSE y - define_bool CONFIG_SERIAL y - define_bool CONFIG_SUN_SERIAL y - define_bool CONFIG_SERIAL_CONSOLE y - define_bool CONFIG_SUN_KEYBOARD y - define_bool CONFIG_SUN_CONSOLE y - define_bool CONFIG_SUN_AUXIO y - define_bool CONFIG_SUN_IO y - if [ "$CONFIG_SUN4" != "y" ]; then - source drivers/sbus/char/Config.in - source drivers/sbus/audio/Config.in - fi + bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4 + if [ "$CONFIG_SUN4" != "y" ]; then + bool ' Support for PCI and PS/2 keyboard/mouse' CONFIG_PCI + fi + + mainmenu_option next_comment + comment 'Console drivers' + bool 'PROM console' CONFIG_PROM_CONSOLE + bool 'Support Frame buffer devices' CONFIG_FB + source drivers/video/Config.in + endmenu + + # Global things across all Sun machines. + define_bool CONFIG_SBUS y + define_bool CONFIG_SBUSCHAR y + define_bool CONFIG_BUSMOUSE y + define_bool CONFIG_SUN_MOUSE y + define_bool CONFIG_SERIAL y + define_bool CONFIG_SUN_SERIAL y + define_bool CONFIG_SERIAL_CONSOLE y + define_bool CONFIG_SUN_KEYBOARD y + define_bool CONFIG_SUN_CONSOLE y + define_bool CONFIG_SUN_AUXIO y + define_bool CONFIG_SUN_IO y + if [ "$CONFIG_SUN4" != "y" ]; then + source drivers/sbus/char/Config.in + source drivers/sbus/audio/Config.in + fi fi -tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS +fi bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT @@ -78,21 +71,30 @@ endmenu mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment comment 'Floppy, IDE, and other block devices' bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then - tristate ' Linear (append) mode' CONFIG_MD_LINEAR - tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED - tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING - tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 + tristate ' Linear (append) mode' CONFIG_MD_LINEAR + tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED + tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING + tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 fi tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then - bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD + bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD fi tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP @@ -101,7 +103,7 @@ endmenu if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in + source net/Config.in fi mainmenu_option next_comment @@ -109,7 +111,7 @@ tristate 'ISDN support' CONFIG_ISDN if [ "$CONFIG_ISDN" != "n" ]; then - source drivers/isdn/Config.in + source drivers/isdn/Config.in fi endmenu @@ -119,65 +121,65 @@ tristate 'SCSI support' CONFIG_SCSI if [ "$CONFIG_SCSI" != "n" ]; then - comment 'SCSI support type (disk, tape, CDrom)' + comment 'SCSI support type (disk, tape, CDrom)' - dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI - dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI - dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI - if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then - bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR - fi - dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI + dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI + dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI + dep_tristate ' SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI + if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then + bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR + fi + dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI - comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' + comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' - bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN + bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN - bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS + bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS - mainmenu_option next_comment - comment 'SCSI low-level drivers' + mainmenu_option next_comment + comment 'SCSI low-level drivers' - bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI - tristate 'PTI Qlogic,ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI - endmenu + bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI + tristate 'PTI Qlogic,ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI + endmenu fi endmenu source drivers/fc4/Config.in if [ "$CONFIG_NET" = "y" ]; then - mainmenu_option next_comment - comment 'Network device support' + mainmenu_option next_comment + comment 'Network device support' - bool 'Network device support' CONFIG_NETDEVICES - if [ "$CONFIG_NETDEVICES" = "y" ]; then - tristate 'Dummy net driver support' CONFIG_DUMMY - tristate 'PPP (point-to-point) support' CONFIG_PPP - if [ ! "$CONFIG_PPP" = "n" ]; then - comment 'CCP compressors for PPP are only built as modules.' - fi - tristate 'SLIP (serial line) support' CONFIG_SLIP - if [ "$CONFIG_SLIP" != "n" ]; then - bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED - bool ' Keepalive and linefill' CONFIG_SLIP_SMART - bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 - fi - tristate 'Sun LANCE support' CONFIG_SUNLANCE - tristate 'Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Sun BigMAC 10/100baseT support' CONFIG_SUNBMAC - fi - tristate 'Sun QuadEthernet support' CONFIG_SUNQE - tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS -# bool 'FDDI driver support' CONFIG_FDDI -# if [ "$CONFIG_FDDI" = "y" ]; then -# fi - if [ "$CONFIG_ATM" = "y" ]; then - source drivers/atm/Config.in - fi - fi - endmenu + bool 'Network device support' CONFIG_NETDEVICES + if [ "$CONFIG_NETDEVICES" = "y" ]; then + tristate ' Dummy net driver support' CONFIG_DUMMY + tristate ' PPP (point-to-point) support' CONFIG_PPP + if [ ! "$CONFIG_PPP" = "n" ]; then + comment 'CCP compressors for PPP are only built as modules.' + fi + tristate ' SLIP (serial line) support' CONFIG_SLIP + if [ "$CONFIG_SLIP" != "n" ]; then + bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED + bool ' Keepalive and linefill' CONFIG_SLIP_SMART + bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 + fi + tristate ' Sun LANCE support' CONFIG_SUNLANCE + tristate ' Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Sun BigMAC 10/100baseT support (EXPERIMENTAL)' CONFIG_SUNBMAC + fi + tristate ' Sun QuadEthernet support' CONFIG_SUNQE + tristate ' MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS +# bool ' FDDI driver support' CONFIG_FDDI +# if [ "$CONFIG_FDDI" = "y" ]; then +# fi + if [ "$CONFIG_ATM" = "y" ]; then + source drivers/atm/Config.in + fi + fi + endmenu fi # This one must be before the filesystem configs. -DaveM @@ -185,7 +187,7 @@ comment 'Unix98 PTY support' bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then - int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 + int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 fi endmenu @@ -202,4 +204,3 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu - diff -u --recursive --new-file v2.3.24/linux/arch/sparc64/config.in linux/arch/sparc64/config.in --- v2.3.24/linux/arch/sparc64/config.in Sat Oct 9 11:47:50 1999 +++ linux/arch/sparc64/config.in Mon Nov 1 10:31:28 1999 @@ -10,15 +10,6 @@ endmenu mainmenu_option next_comment -comment 'Loadable module support' -bool 'Enable loadable module support' CONFIG_MODULES -if [ "$CONFIG_MODULES" = "y" ]; then - bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool 'Kernel module loader' CONFIG_KMOD -fi -endmenu - -mainmenu_option next_comment comment 'General setup' define_bool CONFIG_VT y @@ -49,25 +40,36 @@ source drivers/sbus/char/Config.in source drivers/sbus/audio/Config.in -tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS +fi bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT bool 'Sysctl support' CONFIG_SYSCTL bool 'Kernel support for Linux/Sparc 32bit binary compatibility' CONFIG_SPARC32_COMPAT -tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF if [ "$CONFIG_SPARC32_COMPAT" != "n" ]; then - tristate 'Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32 - bool 'Kernel support for 32-bit (ie. SunOS) a.out binaries' CONFIG_BINFMT_AOUT32 + tristate ' Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32 + bool ' Kernel support for 32-bit (ie. SunOS) a.out binaries' CONFIG_BINFMT_AOUT32 fi +tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Solaris binary emulation' CONFIG_SOLARIS_EMUL + tristate 'Solaris binary emulation (EXPERIMENTAL)' CONFIG_SOLARIS_EMUL fi source drivers/parport/Config.in dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT if [ "$CONFIG_PCI" = "y" ]; then - tristate 'SUNW,envctrl support' CONFIG_ENVCTRL + tristate 'SUNW, envctrl support' CONFIG_ENVCTRL +fi +endmenu + +mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD fi endmenu @@ -78,41 +80,41 @@ bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then - tristate ' Linear (append) mode' CONFIG_MD_LINEAR - tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED - tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING - tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 + tristate ' Linear (append) mode' CONFIG_MD_LINEAR + tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED + tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING + tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 fi tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then - bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD + bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD fi tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP tristate 'Network block device support' CONFIG_BLK_DEV_NBD if [ "$CONFIG_PCI" = "y" ]; then - tristate 'Ultra/PCI IDE disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE - if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then - dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE - dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE - dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE - dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE - dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE - define_bool CONFIG_BLK_DEV_IDEPCI y - define_bool CONFIG_BLK_DEV_IDEDMA y - define_bool CONFIG_IDEDMA_AUTO y - define_bool IDEDMA_NEW_DRIVE_LISTINGS y - define_bool CONFIG_BLK_DEV_NS87415 y - define_bool CONFIG_BLK_DEV_CMD646 y - fi + tristate 'Ultra/PCI IDE disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE + if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then + dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE + dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE + dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE + dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE + dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE + define_bool CONFIG_BLK_DEV_IDEPCI y + define_bool CONFIG_BLK_DEV_IDEDMA y + define_bool CONFIG_IDEDMA_AUTO y + define_bool CONFIG_IDEDMA_NEW_DRIVE_LISTINGS y + define_bool CONFIG_BLK_DEV_NS87415 y + define_bool CONFIG_BLK_DEV_CMD646 y + fi fi endmenu if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in + source net/Config.in fi mainmenu_option next_comment @@ -121,95 +123,95 @@ tristate 'SCSI support' CONFIG_SCSI if [ "$CONFIG_SCSI" != "n" ]; then - comment 'SCSI support type (disk, tape, CDrom)' + comment 'SCSI support type (disk, tape, CDrom)' - dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI - dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI - dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI - if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then - bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR - fi - dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI - - comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' - - bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN - - bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS - - mainmenu_option next_comment - comment 'SCSI low-level drivers' - - bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI - tristate 'PTI Qlogic,ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI - - if [ "$CONFIG_PCI" != "n" ]; then - dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI - if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then - bool ' Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT - int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8 - bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N - int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5 - fi - dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI - if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then - int ' default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8 - int ' maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32 - int ' synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 10 - bool ' enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE - if [ "$CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS" = "0" ]; then - bool ' not allow targets to disconnect' CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' assume boards are SYMBIOS compatible' CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT - fi - fi - dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI - fi + dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI + dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI + dep_tristate ' SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI + if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then + bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR + fi + dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI + + comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' + + bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN + + bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS + + mainmenu_option next_comment + comment 'SCSI low-level drivers' + + bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI + tristate 'PTI Qlogic, ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI + + if [ "$CONFIG_PCI" != "n" ]; then + dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI + if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then + bool ' Enable tagged command queueing (TCQ) by default' CONFIG_AIC7XXX_TAGGED_QUEUEING Y + int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8 + bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N + int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5 + fi + dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI + if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then + int 'default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8 + int 'maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32 + int 'synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 10 + bool ' enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE + if [ "$CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS" = "0" ]; then + bool ' not allow targets to disconnect' CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' assume boards are SYMBIOS compatible (EXPERIMENTAL)' CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT + fi + fi + dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI + fi - endmenu + endmenu fi endmenu source drivers/fc4/Config.in if [ "$CONFIG_NET" = "y" ]; then - mainmenu_option next_comment - comment 'Network device support' + mainmenu_option next_comment + comment 'Network device support' - bool 'Network device support' CONFIG_NETDEVICES - if [ "$CONFIG_NETDEVICES" = "y" ]; then - tristate 'Dummy net driver support' CONFIG_DUMMY - tristate 'PPP (point-to-point) support' CONFIG_PPP - if [ ! "$CONFIG_PPP" = "n" ]; then - comment 'CCP compressors for PPP are only built as modules.' - fi - tristate 'SLIP (serial line) support' CONFIG_SLIP - if [ "$CONFIG_SLIP" != "n" ]; then - bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED - bool ' Keepalive and linefill' CONFIG_SLIP_SMART - bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 - fi - bool 'Sun LANCE support' CONFIG_SUNLANCE - tristate 'Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Sun BigMAC 10/100baseT support' CONFIG_SUNBMAC - fi - tristate 'Sun QuadEthernet support' CONFIG_SUNQE - tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS - if [ "$CONFIG_PCI" = "y" ]; then - tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5 - tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX - tristate 'RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139 - tristate 'PCI NE2000 support' CONFIG_NE2K_PCI - tristate 'EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100 - tristate 'Adaptec Starfire support' CONFIG_ADAPTEC_STARFIRE - fi -# bool 'FDDI driver support' CONFIG_FDDI -# if [ "$CONFIG_FDDI" = "y" ]; then -# fi - fi - endmenu + bool 'Network device support' CONFIG_NETDEVICES + if [ "$CONFIG_NETDEVICES" = "y" ]; then + tristate ' Dummy net driver support' CONFIG_DUMMY + tristate ' PPP (point-to-point) support' CONFIG_PPP + if [ ! "$CONFIG_PPP" = "n" ]; then + comment ' CCP compressors for PPP are only built as modules.' + fi + tristate ' SLIP (serial line) support' CONFIG_SLIP + if [ "$CONFIG_SLIP" != "n" ]; then + bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED + bool ' Keepalive and linefill' CONFIG_SLIP_SMART + bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 + fi + bool ' Sun LANCE support' CONFIG_SUNLANCE + tristate ' Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Sun BigMAC 10/100baseT support (EXPERIMENTAL)' CONFIG_SUNBMAC + fi + tristate ' Sun QuadEthernet support' CONFIG_SUNQE + tristate ' MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS + if [ "$CONFIG_PCI" = "y" ]; then + tristate ' Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5 + tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX + tristate ' RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139 + tristate ' PCI NE2000 support' CONFIG_NE2K_PCI + tristate ' EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100 + tristate ' Adaptec Starfire support' CONFIG_ADAPTEC_STARFIRE + fi +# bool ' FDDI driver support' CONFIG_FDDI +# if [ "$CONFIG_FDDI" = "y" ]; then +# fi + fi +endmenu fi # This one must be before the filesystem configs. -DaveM @@ -217,7 +219,7 @@ comment 'Unix 98 PTY support' bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then - int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 + int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 fi endmenu @@ -225,9 +227,9 @@ comment 'Video For Linux' tristate 'Video For Linux' CONFIG_VIDEO_DEV if [ "$CONFIG_VIDEO_DEV" != "n" ]; then - if [ "$CONFIG_PCI" != "n" ]; then - dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV - fi + if [ "$CONFIG_PCI" != "n" ]; then + dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV + fi fi endmenu diff -u --recursive --new-file v2.3.24/linux/drivers/acorn/net/Config.in linux/drivers/acorn/net/Config.in --- v2.3.24/linux/drivers/acorn/net/Config.in Mon Feb 16 15:49:47 1998 +++ linux/drivers/acorn/net/Config.in Thu Oct 28 10:16:02 1999 @@ -2,6 +2,6 @@ # Acorn Network device configuration # These are for Acorn's Expansion card network interfaces # -tristate 'Acorn Ether1 (82586) support' CONFIG_ARM_ETHER1 -tristate 'Acorn/ANT Ether3 (NQ8005) support' CONFIG_ARM_ETHER3 -tristate 'I-cubed EtherH (NS8390) support' CONFIG_ARM_ETHERH +tristate ' Acorn Ether1 (82586) support' CONFIG_ARM_ETHER1 +tristate ' Acorn/ANT Ether3 (NQ8005) support' CONFIG_ARM_ETHER3 +tristate ' I-cubed EtherH (NS8390) support' CONFIG_ARM_ETHERH diff -u --recursive --new-file v2.3.24/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c --- v2.3.24/linux/drivers/block/DAC960.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/block/DAC960.c Thu Oct 28 14:34:46 1999 @@ -95,11 +95,11 @@ /* - DAC960_ProcDirectoryEntry is the DAC960 /proc/rd directory entry. + DAC960_ProcDirectoryEntry is the DAC960 /proc/driver/rd directory entry. */ -static PROC_DirectoryEntry_T - DAC960_ProcDirectoryEntry; +static PROC_DirectoryEntry_T * + DAC960_ProcDirectoryEntry = NULL; /* @@ -3466,23 +3466,18 @@ /* - DAC960_CreateProcEntries creates the /proc/rd/... entries for the DAC960 - Driver. + DAC960_CreateProcEntries creates the /proc/driver/rd/... entries + for the DAC960 Driver. */ static void DAC960_CreateProcEntries(void) { - static PROC_DirectoryEntry_T StatusProcEntry; + static PROC_DirectoryEntry_T *StatusProcEntry; int ControllerNumber; - DAC960_ProcDirectoryEntry.name = "rd"; - DAC960_ProcDirectoryEntry.namelen = strlen(DAC960_ProcDirectoryEntry.name); - DAC960_ProcDirectoryEntry.mode = S_IFDIR | S_IRUGO | S_IXUGO; - proc_register(&proc_root, &DAC960_ProcDirectoryEntry); - StatusProcEntry.name = "status"; - StatusProcEntry.namelen = strlen(StatusProcEntry.name); - StatusProcEntry.mode = S_IFREG | S_IRUGO; - StatusProcEntry.read_proc = DAC960_ProcReadStatus; - proc_register(&DAC960_ProcDirectoryEntry, &StatusProcEntry); + DAC960_ProcDirectoryEntry = create_proc_entry("driver/rd", S_IFDIR, NULL); + StatusProcEntry = create_proc_read_entry("status", 0, + DAC960_ProcDirectoryEntry, + DAC960_ProcReadStatus, NULL); for (ControllerNumber = 0; ControllerNumber < DAC960_ControllerCount; ControllerNumber++) @@ -3495,7 +3490,7 @@ ControllerProcEntry->name = Controller->ControllerName; ControllerProcEntry->namelen = strlen(ControllerProcEntry->name); ControllerProcEntry->mode = S_IFDIR | S_IRUGO | S_IXUGO; - proc_register(&DAC960_ProcDirectoryEntry, ControllerProcEntry); + proc_register(DAC960_ProcDirectoryEntry, ControllerProcEntry); InitialStatusProcEntry = &Controller->InitialStatusProcEntry; InitialStatusProcEntry->name = "initial_status"; InitialStatusProcEntry->namelen = strlen(InitialStatusProcEntry->name); @@ -3529,7 +3524,7 @@ static void DAC960_DestroyProcEntries(void) { - proc_unregister(&proc_root, DAC960_ProcDirectoryEntry.low_ino); + remove_proc_entry("driver/rd", NULL); } diff -u --recursive --new-file v2.3.24/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c --- v2.3.24/linux/drivers/block/cpqarray.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/block/cpqarray.c Thu Oct 28 14:34:46 1999 @@ -161,8 +161,14 @@ static int revalidate_logvol(kdev_t dev, int maxusage); static int revalidate_allvol(kdev_t dev); +#ifdef CONFIG_PROC_FS static void ida_procinit(int i); static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data); +#else +static void ida_procinit(int i) {} +static int ida_proc_get_info(char *buffer, char **start, off_t offset, + int length, int *eof, void *data) {} +#endif static void ida_geninit(struct gendisk *g) { @@ -207,26 +213,21 @@ }; +#ifdef CONFIG_PROC_FS + /* * Get us a file in /proc/array that says something about each controller. * Create /proc/array if it doesn't exist yet. */ -static void ida_procinit(int i) +static void __init ida_procinit(int i) { -#ifdef CONFIG_PROC_FS - struct proc_dir_entry *pd; - if (proc_array == NULL) { - proc_array = create_proc_entry("array", S_IFDIR|S_IRUGO|S_IXUGO, - &proc_root); + proc_array = create_proc_entry("driver/array", S_IFDIR, NULL); if (!proc_array) return; } - pd = create_proc_entry(hba[i]->devname, S_IFREG|S_IRUGO, proc_array); - if (!pd) return; - pd->read_proc = ida_proc_get_info; - pd->data = hba[i]; -#endif + create_proc_read_entry(hba[i]->devname, 0, proc_array, + ida_proc_get_info, hba[i]); } /* @@ -311,6 +312,7 @@ len = length; return len; } +#endif /* CONFIG_PROC_FS */ #ifdef MODULE @@ -318,7 +320,7 @@ EXPORT_NO_SYMBOLS; /* This is a bit of a hack... */ -int init_module(void) +int __init init_module(void) { int i, j; cpqarray_init(); @@ -333,11 +335,14 @@ } return 0; } + void cleanup_module(void) { int i; struct gendisk *g; + remove_proc_entry("driver/array", NULL); + for(i=0; iaccess.set_intr_mask(hba[i], 0); free_irq(hba[i]->intr, hba[i]); @@ -359,15 +364,11 @@ } } } -#ifdef CONFIG_PROC_FS - remove_proc_entry("array", &proc_root); -#endif + kfree(ida); kfree(ida_sizes); kfree(ida_hardsizes); kfree(ida_blocksizes); - - } #endif /* MODULE */ @@ -375,7 +376,7 @@ * This is it. Find all the controllers and register them. I really hate * stealing all these major device numbers. */ -void cpqarray_init(void) +void __init cpqarray_init(void) { void (*request_fns[MAX_CTLR])(void) = { do_ida_request0, do_ida_request1, diff -u --recursive --new-file v2.3.24/linux/drivers/block/ide-geometry.c linux/drivers/block/ide-geometry.c --- v2.3.24/linux/drivers/block/ide-geometry.c Fri Oct 22 13:21:47 1999 +++ linux/drivers/block/ide-geometry.c Thu Oct 28 16:11:27 1999 @@ -81,7 +81,6 @@ */ static void ontrack(ide_drive_t *drive, int heads, int *c, int *h, int *s) { - struct hd_driveid *id = drive->id; static const byte dm_head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}; const byte *headp = dm_head_vals; unsigned long total, tracks; @@ -92,10 +91,7 @@ * 1024*255*63. Now take S=63, H the first in the sequence * 4, 8, 16, 32, 64, 128, 255 such that 63*H*1024 >= total. */ - if (id) - total = id->cyls * id->heads * id->sectors; - else - total = drive->cyl * drive->head * drive->sect; + total = DRIVER(drive)->capacity(drive); *s = 63; diff -u --recursive --new-file v2.3.24/linux/drivers/block/ide-proc.c linux/drivers/block/ide-proc.c --- v2.3.24/linux/drivers/block/ide-proc.c Fri Oct 22 13:21:47 1999 +++ linux/drivers/block/ide-proc.c Thu Oct 28 14:34:46 1999 @@ -769,31 +769,25 @@ void proc_ide_create(void) { - struct proc_dir_entry *ent; proc_ide_root = create_proc_entry("ide", S_IFDIR, 0); if (!proc_ide_root) return; + create_proc_ide_interfaces(); - ent = create_proc_entry("drivers", 0, proc_ide_root); - if (!ent) return; - ent->read_proc = proc_ide_read_drivers; + create_proc_read_entry("drivers",0,proc_ide_root, + proc_ide_read_drivers, NULL); + #ifdef CONFIG_BLK_DEV_ALI15X3 - if ((ali_display_info) && (ali_proc)) { - ent = create_proc_entry("ali", 0, proc_ide_root); - ent->get_info = ali_display_info; - } + if ((ali_display_info) && (ali_proc)) + create_proc_info_entry("ali", 0, proc_ide_root, ali_display_info); #endif /* CONFIG_BLK_DEV_ALI15X3 */ #ifdef CONFIG_BLK_DEV_SIS5513 - if ((sis_display_info) && (sis_proc)) { - ent = create_proc_entry("sis", 0, proc_ide_root); - ent->get_info = sis_display_info; - } + if ((sis_display_info) && (sis_proc)) + create_proc_info_entry("sis", 0, proc_ide_root, sis_display_info); #endif /* CONFIG_BLK_DEV_SIS5513 */ #ifdef CONFIG_BLK_DEV_VIA82CXXX - if ((via_display_info) && (via_proc)) { - ent = create_proc_entry("via", 0, proc_ide_root); - ent->get_info = via_display_info; - } + if ((via_display_info) && (via_proc)) + create_proc_info_entry("via", 0, proc_ide_root, via_display_info); #endif /* CONFIG_BLK_DEV_VIA82CXXX */ } diff -u --recursive --new-file v2.3.24/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.3.24/linux/drivers/block/ll_rw_blk.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/block/ll_rw_blk.c Fri Oct 29 10:59:17 1999 @@ -388,9 +388,12 @@ /* * Has to be called with the request spinlock aquired */ -static inline void attempt_merge (struct request *req, int max_sectors) +static inline void attempt_merge (struct request *req, + int max_sectors, + int max_segments) { struct request *next = req->next; + int total_segments; if (!next) return; @@ -398,9 +401,15 @@ return; if (next->sem || req->cmd != next->cmd || req->rq_dev != next->rq_dev || req->nr_sectors + next->nr_sectors > max_sectors) return; + total_segments = req->nr_segments + next->nr_segments; + if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) + total_segments--; + if (total_segments > max_segments) + return; req->bhtail->b_reqnext = next->bh; req->bhtail = next->bhtail; req->nr_sectors += next->nr_sectors; + req->nr_segments = total_segments; next->rq_status = RQ_INACTIVE; req->next = next->next; wake_up (&wait_for_request); @@ -410,7 +419,7 @@ { unsigned int sector, count; struct request * req; - int rw_ahead, max_req, max_sectors; + int rw_ahead, max_req, max_sectors, max_segments; unsigned long flags; count = bh->b_size >> 9; @@ -493,6 +502,7 @@ * Try to coalesce the new request with old requests */ max_sectors = get_max_sectors(bh->b_rdev); + max_segments = get_max_segments(bh->b_rdev); /* * Now we acquire the request spinlock, we have to be mega careful @@ -572,14 +582,26 @@ continue; /* Can we add it to the end of this request? */ if (req->sector + req->nr_sectors == sector) { + if (req->bhtail->b_data + req->bhtail->b_size + != bh->b_data) { + if (req->nr_segments < max_segments) + req->nr_segments++; + else continue; + } req->bhtail->b_reqnext = bh; req->bhtail = bh; req->nr_sectors += count; drive_stat_acct(req, count, 0); /* Can we now merge this req with the next? */ - attempt_merge(req, max_sectors); + attempt_merge(req, max_sectors, max_segments); /* or to the beginning? */ } else if (req->sector - count == sector) { + if (bh->b_data + bh->b_size + != req->bh->b_data) { + if (req->nr_segments < max_segments) + req->nr_segments++; + else continue; + } bh->b_reqnext = req->bh; req->bh = bh; req->buffer = bh->b_data; @@ -613,6 +635,7 @@ req->errors = 0; req->sector = sector; req->nr_sectors = count; + req->nr_segments = 1; req->current_nr_sectors = count; req->buffer = bh->b_data; req->sem = NULL; diff -u --recursive --new-file v2.3.24/linux/drivers/block/loop.c linux/drivers/block/loop.c --- v2.3.24/linux/drivers/block/loop.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/block/loop.c Mon Nov 1 10:31:34 1999 @@ -23,9 +23,12 @@ * Reed H. Petty, rhp@draper.net * * Maximum number of loop devices now dynamic via max_loop module parameter. - * Still fixed at 8 devices when compiled into the kernel normally. * Russell Kroll 19990701 * + * Maximum number of loop devices when compiled-in now selectable by passing + * max_loop=<1-255> to the kernel on boot. + * Erik I. Bolsų, , Oct 31, 1999 + * * Still To Fix: * - Advisory locking is ignored here. * - Should use an own CAP_* category instead of CAP_SYS_ADMIN @@ -723,15 +726,12 @@ } if ((max_loop < 1) || (max_loop > 255)) { - printk (KERN_WARNING "loop: max_loop must be between 1 and 255\n"); - return -EINVAL; + printk (KERN_WARNING "loop: invalid max_loop (must be between 1 and 255), using default (8)\n"); + max_loop = 8; } -#ifndef MODULE printk(KERN_INFO "loop: registered device at major %d\n", MAJOR_NR); -#else printk(KERN_INFO "loop: enabling %d loop devices\n", max_loop); -#endif loop_dev = kmalloc (max_loop * sizeof(struct loop_device), GFP_KERNEL); if (!loop_dev) { @@ -777,4 +777,14 @@ kfree (loop_sizes); kfree (loop_blksizes); } +#endif + +#ifndef MODULE +static int __init max_loop_setup(char *str) +{ + max_loop = simple_strtol(str,NULL,0); + return 1; +} + +__setup("max_loop=", max_loop_setup); #endif diff -u --recursive --new-file v2.3.24/linux/drivers/block/md.c linux/drivers/block/md.c --- v2.3.24/linux/drivers/block/md.c Fri Oct 15 15:25:13 1999 +++ linux/drivers/block/md.c Thu Oct 28 14:34:46 1999 @@ -872,11 +872,74 @@ EXPORT_SYMBOL(md_do_sync); #ifdef CONFIG_PROC_FS -static struct proc_dir_entry proc_md = { - PROC_MD, 6, "mdstat", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, -}; +static int md_status_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int sz = 0, i, j, size; + int begin = 0; + + sz=sprintf( page, "Personalities : "); + for (i=0; iname); + page[sz-1]='\n'; + + sz+=sprintf (page+sz, "read_ahead "); + if (read_ahead[MD_MAJOR]==INT_MAX) + sz+=sprintf (page+sz, "not set\n"); + else + sz+=sprintf (page+sz, "%d sectors\n", read_ahead[MD_MAJOR]); + + for (i=0; i= off+count) { + *eof = 1; + break; + } + sz+=sprintf (page+sz, "md%d : %sactive", + i, md_dev[i].pers ? "" : "in"); + + if (md_dev[i].pers) + sz+=sprintf (page+sz, " %s", md_dev[i].pers->name); + + for (j=0, size=0; jmax_invalid_dev) + sz+=sprintf (page+sz, " maxfault=%ld", + MAX_FAULT(md_dev+i)); + + sz+=md_dev[i].pers->status (page+sz, i, md_dev+i); + sz+=sprintf (page+sz, "\n"); + } + + sz -= off; + *start = page + off; + if (sz>count) + sz = count; + if (sz<0) + sz = 0; + return sz; +} #endif static void md_geninit (struct gendisk *gdisk) @@ -896,7 +959,7 @@ max_readahead[MD_MAJOR] = md_maxreadahead; #ifdef CONFIG_PROC_FS - proc_register(&proc_root, &proc_md); + create_proc_read_entry("mdstat", 0, NULL, md_status_read_proc, NULL); #endif } @@ -917,61 +980,6 @@ return rc; } return 0; -} - -int get_md_status (char *page) -{ - int sz=0, i, j, size; - - sz+=sprintf( page+sz, "Personalities : "); - for (i=0; iname); - - page[sz-1]='\n'; - - sz+=sprintf (page+sz, "read_ahead "); - if (read_ahead[MD_MAJOR]==INT_MAX) - sz+=sprintf (page+sz, "not set\n"); - else - sz+=sprintf (page+sz, "%d sectors\n", read_ahead[MD_MAJOR]); - - for (i=0; iname); - - size=0; - for (j=0; jmax_invalid_dev) - sz+=sprintf (page+sz, " maxfault=%ld", MAX_FAULT(md_dev+i)); - - sz+=md_dev[i].pers->status (page+sz, i, md_dev+i); - sz+=sprintf (page+sz, "\n"); - } - - return (sz); } int register_md_personality (int p_num, struct md_personality *p) diff -u --recursive --new-file v2.3.24/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v2.3.24/linux/drivers/char/Config.in Fri Oct 22 13:21:47 1999 +++ linux/drivers/char/Config.in Fri Oct 29 10:59:17 1999 @@ -148,6 +148,10 @@ if [ "$CONFIG_RADIO_TERRATEC" = "y" ]; then hex ' Terratec i/o port (normally 0x590)' CONFIG_RADIO_TERRATEC_PORT 590 fi + dep_tristate 'Trust FM radio card' CONFIG_RADIO_TRUST $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_TRUST" = "y" ]; then + hex ' Trust i/o port (usually 0x350 or 0x358)' CONFIG_RADIO_TRUST_PORT 350 + fi if [ "$CONFIG_PCI" != "n" ]; then dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV fi diff -u --recursive --new-file v2.3.24/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.3.24/linux/drivers/char/Makefile Fri Oct 22 13:21:47 1999 +++ linux/drivers/char/Makefile Fri Oct 29 10:59:17 1999 @@ -261,7 +261,7 @@ else ifeq ($(CONFIG_SOFT_WATCHDOG),m) M_OBJS += softdog.o - endif + endif endif ifeq ($(CONFIG_PCWATCHDOG),y) @@ -452,7 +452,15 @@ ifeq ($(CONFIG_RADIO_AZTECH),m) M_OBJS += radio-aztech.o endif -endif +endif + +ifeq ($(CONFIG_RADIO_RTRACK2),y) +O_OBJS += radio-rtrack2.o +else + ifeq ($(CONFIG_RADIO_RTRACK2),m) + M_OBJS += radio-rtrack2.o + endif +endif ifeq ($(CONFIG_RADIO_SF16FMI),y) O_OBJS += radio-sf16fmi.o @@ -460,23 +468,15 @@ ifeq ($(CONFIG_RADIO_SF16FMI),m) M_OBJS += radio-sf16fmi.o endif -endif - -ifeq ($(CONFIG_RADIO_RTRACK),y) -O_OBJS += radio-aimslab.o -else - ifeq ($(CONFIG_RADIO_RTRACK),m) - M_OBJS += radio-aimslab.o - endif -endif +endif -ifeq ($(CONFIG_RADIO_RTRACK2),y) -O_OBJS += radio-rtrack2.o +ifeq ($(CONFIG_RADIO_CADET),y) +O_OBJS += radio-cadet.o else - ifeq ($(CONFIG_RADIO_RTRACK2),m) - M_OBJS += radio-rtrack2.o + ifeq ($(CONFIG_RADIO_CADET),m) + M_OBJS += radio-cadet.o endif -endif +endif ifeq ($(CONFIG_RADIO_TYPHOON),y) O_OBJS += radio-typhoon.o @@ -484,7 +484,23 @@ ifeq ($(CONFIG_RADIO_TYPHOON),m) M_OBJS += radio-typhoon.o endif -endif +endif + +ifeq ($(CONFIG_RADIO_TERRATEC),y) +O_OBJS += radio-terratec.o +else + ifeq ($(CONFIG_RADIO_TERRATEC),m) + M_OBJS += radio-terratec.o + endif +endif + +ifeq ($(CONFIG_RADIO_RTRACK),y) +O_OBJS += radio-aimslab.o +else + ifeq ($(CONFIG_RADIO_RTRACK),m) + M_OBJS += radio-aimslab.o + endif +endif ifeq ($(CONFIG_RADIO_ZOLTRIX),y) O_OBJS += radio-zoltrix.o @@ -492,15 +508,7 @@ ifeq ($(CONFIG_RADIO_ZOLTRIX),m) M_OBJS += radio-zoltrix.o endif -endif - -ifeq ($(CONFIG_RADIO_CADET),y) -O_OBJS += radio-cadet.o -else - ifeq ($(CONFIG_RADIO_CADET),m) - M_OBJS += radio-cadet.o - endif -endif +endif ifeq ($(CONFIG_RADIO_MIROPCM20),y) O_OBJS += radio-miropcm20.o @@ -516,13 +524,13 @@ ifeq ($(CONFIG_RADIO_GEMTEK),m) M_OBJS += radio-gemtek.o endif -endif +endif -ifeq ($(CONFIG_RADIO_TERRATEC),y) -O_OBJS += radio-terratec.o +ifeq ($(CONFIG_RADIO_TRUST),y) +O_OBJS += radio-trust.o else - ifeq ($(CONFIG_RADIO_TERRATEC),m) - M_OBJS += radio-terratec.o + ifeq ($(CONFIG_RADIO_TRUST),m) + M_OBJS += radio-trust.o endif endif diff -u --recursive --new-file v2.3.24/linux/drivers/char/h8.c linux/drivers/char/h8.c --- v2.3.24/linux/drivers/char/h8.c Sat May 15 15:05:36 1999 +++ linux/drivers/char/h8.c Thu Oct 28 14:34:46 1999 @@ -3,6 +3,9 @@ * * The H8 is used to deal with the power and thermal environment * of a system. + * + * Fixes: + * June 1999, AV added releasing /proc/driver/h8 */ #include @@ -18,10 +21,8 @@ #include #include #include -#ifdef CONFIG_PROC_FS #include #include -#endif #include #include #include @@ -58,6 +59,8 @@ #ifdef CONFIG_PROC_FS static int h8_get_info(char *, char **, off_t, int, int); +#else +static int h8_get_info(char *, char **, off_t, int, int) {} #endif /* @@ -125,12 +128,6 @@ &h8_fops }; -#ifdef CONFIG_PROC_FS -static struct proc_dir_entry h8_proc_entry = { - 0, 3, "h8", S_IFREG | S_IRUGO, 1, 0, 0, 0, 0, h8_get_info -}; -#endif - union intr_buf intrbuf; int intr_buf_ptr; union intr_buf xx; @@ -321,9 +318,7 @@ misc_register(&h8_device); request_region(h8_base, 8, "h8"); -#ifdef CONFIG_PROC_FS - proc_register(&proc_root, &h8_proc_entry); -#endif + create_proc_info_entry("driver/h8", 0, NULL, h8_get_info); QUEUE_INIT(&h8_actq, link, h8_cmd_q_t *); QUEUE_INIT(&h8_cmdq, link, h8_cmd_q_t *); @@ -339,6 +334,7 @@ void cleanup_module(void) { + remove_proc_entry("driver/h8", NULL); misc_deregister(&h8_device); release_region(h8_base, 8); free_irq(h8_irq, NULL); @@ -355,9 +351,7 @@ } printk("H8 at 0x%x IRQ %d\n", h8_base, h8_irq); -#ifdef CONFIG_PROC_FS - proc_register(&proc_root, &h8_proc_entry); -#endif + create_proc_info_entry("driver/h8", 0, NULL, h8_get_info); misc_register(&h8_device); request_region(h8_base, 8, "h8"); diff -u --recursive --new-file v2.3.24/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.3.24/linux/drivers/char/mem.c Fri Oct 22 13:21:48 1999 +++ linux/drivers/char/mem.c Thu Oct 28 13:03:38 1999 @@ -190,10 +190,7 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) { - unsigned long offset = vma->vm_offset; - - if (offset & ~PAGE_MASK) - return -ENXIO; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; /* * Accessing memory above the top the kernel knows about or diff -u --recursive --new-file v2.3.24/linux/drivers/char/misc.c linux/drivers/char/misc.c --- v2.3.24/linux/drivers/char/misc.c Mon Oct 11 15:38:14 1999 +++ linux/drivers/char/misc.c Thu Oct 28 14:34:46 1999 @@ -76,7 +76,6 @@ extern int rtc_DP8570A_init(void); extern int rtc_MK48T08_init(void); extern int dsp56k_init(void); -extern int nvram_init(void); extern int radio_init(void); extern int pc110pad_init(void); extern int pmu_device_init(void); @@ -180,13 +179,9 @@ EXPORT_SYMBOL(misc_register); EXPORT_SYMBOL(misc_deregister); -static struct proc_dir_entry *proc_misc; - int __init misc_init(void) { - proc_misc = create_proc_entry("misc", 0, 0); - if (proc_misc) - proc_misc->read_proc = misc_read_proc; + create_proc_read_entry("misc", 0, 0, misc_read_proc, NULL); #ifdef CONFIG_BUSMOUSE bus_mouse_init(); #endif @@ -234,9 +229,6 @@ #endif #ifdef CONFIG_ATARI_DSP56K dsp56k_init(); -#endif -#ifdef CONFIG_NVRAM - nvram_init(); #endif #ifdef CONFIG_MISC_RADIO radio_init(); diff -u --recursive --new-file v2.3.24/linux/drivers/char/nvram.c linux/drivers/char/nvram.c --- v2.3.24/linux/drivers/char/nvram.c Thu Aug 5 14:34:01 1999 +++ linux/drivers/char/nvram.c Fri Oct 29 10:58:00 1999 @@ -95,9 +95,7 @@ #include #include #include -#ifdef CONFIG_PROC_FS #include -#endif #include #include @@ -351,9 +349,10 @@ } -#ifdef CONFIG_PROC_FS - -struct proc_dir_entry *proc_nvram; +#ifndef CONFIG_PROC_FS +static int nvram_read_proc( char *buffer, char **start, off_t offset, + int size, int *eof, void *data) { return 0; } +#else static int nvram_read_proc( char *buffer, char **start, off_t offset, int size, int *eof, void *data ) @@ -391,7 +390,7 @@ } \ } while(0) -#endif +#endif /* CONFIG_PROC_FS */ static struct file_operations nvram_fops = { nvram_llseek, @@ -413,7 +412,7 @@ }; -int __init nvram_init(void) +static int __init nvram_init(void) { /* First test whether the driver should init at all */ if (!CHECK_DRIVER_INIT()) @@ -421,29 +420,18 @@ printk(KERN_INFO "Non-volatile memory driver v%s\n", NVRAM_VERSION ); misc_register( &nvram_dev ); -#ifdef CONFIG_PROC_FS - if ((proc_nvram = create_proc_entry( "nvram", 0, 0 ))) - proc_nvram->read_proc = nvram_read_proc; -#endif - + create_proc_read_entry("driver/nvram",0,0,nvram_read_proc,NULL); return( 0 ); } -#ifdef MODULE -int init_module (void) -{ - return( nvram_init() ); -} - -void cleanup_module (void) +static void __exit nvram_cleanup_module (void) { -#ifdef CONFIG_PROC_FS - if (proc_nvram) - remove_proc_entry( "nvram", 0 ); -#endif + remove_proc_entry( "driver/nvram", 0 ); misc_deregister( &nvram_dev ); } -#endif + +module_init(nvram_init); +module_exit(nvram_cleanup_module); /* diff -u --recursive --new-file v2.3.24/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c --- v2.3.24/linux/drivers/char/ppdev.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/char/ppdev.c Fri Oct 29 11:05:08 1999 @@ -509,6 +509,7 @@ if (!pp) return -ENOMEM; + memset (pp, 0, sizeof (struct pp_struct)); pp->state.mode = IEEE1284_MODE_COMPAT; pp->state.phase = init_phase (pp->state.mode); pp->flags = 0; diff -u --recursive --new-file v2.3.24/linux/drivers/char/radio-cadet.c linux/drivers/char/radio-cadet.c --- v2.3.24/linux/drivers/char/radio-cadet.c Fri Oct 22 13:21:48 1999 +++ linux/drivers/char/radio-cadet.c Thu Oct 28 16:12:52 1999 @@ -39,7 +39,6 @@ static __u8 rdsin=0,rdsout=0,rdsstat=0; static unsigned char rdsbuf[RDS_BUFFER]; static int cadet_lock=0; -static int cadet_probe(void); /* * Signal Strength Threshold Values @@ -543,22 +542,6 @@ NULL }; -int __init cadet_init(struct video_init *v) -{ -#ifndef MODULE - if(cadet_probe()<0) { - return EINVAL; - } -#endif - if(video_register_device(&cadet_radio,VFL_TYPE_RADIO)==-1) - return -EINVAL; - - request_region(io,2,"cadet"); - printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io); - return 0; -} - - #ifndef MODULE static int cadet_probe(void) { @@ -578,9 +561,27 @@ } #endif +int __init cadet_init(void) +{ +#ifndef MODULE + io = cadet_probe (); +#endif + + if(io < 0) { +#ifdef MODULE + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); +#endif + return EINVAL; + } + if(video_register_device(&cadet_radio,VFL_TYPE_RADIO)==-1) + return -EINVAL; + + request_region(io,2,"cadet"); + printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io); + return 0; +} -#ifdef MODULE MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card."); @@ -589,21 +590,12 @@ EXPORT_NO_SYMBOLS; -int init_module(void) -{ - if(io==-1) - { - printk(KERN_ERR "You must set an I/O address with io=0x???\n"); - return -EINVAL; - } - return cadet_init(NULL); -} - -void cleanup_module(void) +static void __exit cadet_cleanup_module(void) { video_unregister_device(&cadet_radio); release_region(io,2); } -#endif +module_init(cadet_init); +module_exit(cadet_cleanup_module); diff -u --recursive --new-file v2.3.24/linux/drivers/char/radio-rtrack2.c linux/drivers/char/radio-rtrack2.c --- v2.3.24/linux/drivers/char/radio-rtrack2.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/char/radio-rtrack2.c Thu Oct 28 16:12:56 1999 @@ -228,8 +228,13 @@ NULL }; -int __init rtrack2_init(struct video_init *v) +static int __init rtrack2_init(void) { + if(io==-1) + { + printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n"); + return -EINVAL; + } if (check_region(io, 4)) { printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io); @@ -252,8 +257,6 @@ return 0; } -#ifdef MODULE - MODULE_AUTHOR("Ben Pfaff"); MODULE_DESCRIPTION("A driver for the RadioTrack II radio card."); MODULE_PARM(io, "i"); @@ -261,23 +264,14 @@ EXPORT_NO_SYMBOLS; -int init_module(void) -{ - if(io==-1) - { - printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n"); - return -EINVAL; - } - return rtrack2_init(NULL); -} - -void cleanup_module(void) +static void __exit rtrack2_cleanup_module(void) { video_unregister_device(&rtrack2_radio); release_region(io,4); } -#endif +module_init(rtrack2_init); +module_exit(rtrack2_cleanup_module); /* Local variables: diff -u --recursive --new-file v2.3.24/linux/drivers/char/radio-sf16fmi.c linux/drivers/char/radio-sf16fmi.c --- v2.3.24/linux/drivers/char/radio-sf16fmi.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/char/radio-sf16fmi.c Thu Oct 28 16:13:00 1999 @@ -289,8 +289,13 @@ NULL }; -int __init fmi_init(struct video_init *v) +static int __init fmi_init(void) { + if(io==-1) + { + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); + return -EINVAL; + } if (check_region(io, 2)) { printk(KERN_ERR "fmi: port 0x%x already in use\n", io); @@ -316,8 +321,6 @@ return 0; } -#ifdef MODULE - MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood"); MODULE_DESCRIPTION("A driver for the SF16MI radio."); MODULE_PARM(io, "i"); @@ -325,20 +328,12 @@ EXPORT_NO_SYMBOLS; -int init_module(void) -{ - if(io==-1) - { - printk(KERN_ERR "You must set an I/O address with io=0x???\n"); - return -EINVAL; - } - return fmi_init(NULL); -} - -void cleanup_module(void) +static void __exit fmi_cleanup_module(void) { video_unregister_device(&fmi_radio); release_region(io,2); } -#endif +module_init(fmi_init); +module_exit(fmi_cleanup_module); + diff -u --recursive --new-file v2.3.24/linux/drivers/char/radio-terratec.c linux/drivers/char/radio-terratec.c --- v2.3.24/linux/drivers/char/radio-terratec.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/char/radio-terratec.c Thu Oct 28 16:13:03 1999 @@ -307,8 +307,13 @@ NULL }; -int __init terratec_init(struct video_init *v) +static int __init terratec_init(void) { + if(io==-1) + { + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); + return -EINVAL; + } if (check_region(io, 2)) { printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io); @@ -334,8 +339,6 @@ return 0; } -#ifdef MODULE - MODULE_AUTHOR("R.OFFERMANNS & others"); MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card."); MODULE_PARM(io, "i"); @@ -343,21 +346,13 @@ EXPORT_NO_SYMBOLS; -int init_module(void) -{ - if(io==-1) - { - printk(KERN_ERR "You must set an I/O address with io=0x???\n"); - return -EINVAL; - } - return terratec_init(NULL); -} - -void cleanup_module(void) +static void __exit terratec_cleanup_module(void) { video_unregister_device(&terratec_radio); release_region(io,2); printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n"); } -#endif +module_init(terratec_init); +module_exit(terratec_cleanup_module); + diff -u --recursive --new-file v2.3.24/linux/drivers/char/radio-trust.c linux/drivers/char/radio-trust.c --- v2.3.24/linux/drivers/char/radio-trust.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/char/radio-trust.c Thu Oct 28 16:13:07 1999 @@ -333,16 +333,12 @@ return 0; } -#ifdef MODULE - MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath"); MODULE_DESCRIPTION("A driver for the Trust FM Radio card."); MODULE_PARM(io, "i"); MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)"); EXPORT_NO_SYMBOLS; - -#endif /* MODULE */ static void __exit cleanup_trust_module(void) { diff -u --recursive --new-file v2.3.24/linux/drivers/char/radio-typhoon.c linux/drivers/char/radio-typhoon.c --- v2.3.24/linux/drivers/char/radio-typhoon.c Mon May 10 13:00:10 1999 +++ linux/drivers/char/radio-typhoon.c Fri Oct 29 10:59:17 1999 @@ -72,15 +72,8 @@ static int typhoon_open(struct video_device *dev, int flags); static void typhoon_close(struct video_device *dev); #ifdef CONFIG_RADIO_TYPHOON_PROC_FS -static int typhoon_read_proc(char *buf, char **start, off_t offset, int len, - int unused); -#endif -#ifdef MODULE -int init_module(void); -void cleanup_module(void); -int typhoon_init(struct video_init *v); -#else -int typhoon_init(struct video_init *v) __init; +static int typhoon_get_info(char *buf, char **start, off_t offset, int len, + int unused); #endif static void typhoon_setvol_generic(struct typhoon_device *dev, int vol) @@ -306,8 +299,8 @@ #ifdef CONFIG_RADIO_TYPHOON_PROC_FS -static int typhoon_read_proc(char *buf, char **start, off_t offset, int len, - int unused) +static int typhoon_get_info(char *buf, char **start, off_t offset, int len, + int unused) { #ifdef MODULE #define MODULEPROCSTRING "Driver loaded as a module" @@ -337,53 +330,8 @@ return len; } -static struct proc_dir_entry typhoon_proc_entry = { - 0, /* low_ino: inode is dynamic */ - 13, "radio-typhoon", /* length of name and name */ - S_IFREG | S_IRUGO, /* mode */ - 1, 0, 0, /* nlinks, owner, group */ - 0, /* size -- not used */ - NULL, /* operations -- use default */ - &typhoon_read_proc, /* function used to read data */ - /* nothing more */ -}; - #endif /* CONFIG_RADIO_TYPHOON_PROC_FS */ -int typhoon_init(struct video_init *v) -{ - printk(KERN_INFO BANNER); - if (check_region(typhoon_unit.iobase, 8)) { - printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n", - typhoon_unit.iobase); - return -EBUSY; - } - - typhoon_radio.priv = &typhoon_unit; - if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO) == -1) - return -EINVAL; - - request_region(typhoon_unit.iobase, 8, "typhoon"); - printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase); - printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n", - typhoon_unit.mutefreq); - typhoon_unit.mutefreq <<= 4; - - /* mute card - prevents noisy bootups */ - typhoon_mute(&typhoon_unit); - -#ifdef CONFIG_RADIO_TYPHOON_PROC_FS - - if (proc_register(&proc_root, &typhoon_proc_entry)) - printk(KERN_ERR "radio-typhoon: registering /proc/radio-typhoon failed\n"); - -#endif - - return 0; -} - -#ifdef MODULE - MODULE_AUTHOR("Dr. Henrik Seidel"); MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio)."); MODULE_PARM(io, "i"); @@ -394,10 +342,14 @@ EXPORT_NO_SYMBOLS; static int io = -1; + +#ifdef MODULE static unsigned long mutefreq = 0; +#endif -int init_module(void) +static int __init typhoon_init(void) { +#ifdef MODULE if (io == -1) { printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n"); return -EINVAL; @@ -410,24 +362,49 @@ return -EINVAL; } typhoon_unit.mutefreq = mutefreq; +#endif /* MODULE */ - return typhoon_init(NULL); -} + printk(KERN_INFO BANNER); + io = typhoon_unit.iobase; + if (check_region(io, 8)) { + printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n", + typhoon_unit.iobase); + return -EBUSY; + } -void cleanup_module(void) -{ + typhoon_radio.priv = &typhoon_unit; + if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO) == -1) + return -EINVAL; + + request_region(typhoon_unit.iobase, 8, "typhoon"); + printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase); + printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n", + typhoon_unit.mutefreq); + typhoon_unit.mutefreq <<= 4; + + /* mute card - prevents noisy bootups */ + typhoon_mute(&typhoon_unit); #ifdef CONFIG_RADIO_TYPHOON_PROC_FS + if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL, + typhoon_get_info)) + printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n"); +#endif + + return 0; +} - if (proc_unregister(&proc_root, typhoon_proc_entry.low_ino)) - printk(KERN_ERR "radio-typhoon: unregistering /proc/radio-typhoon failed\n"); +static void __exit typhoon_cleanup_module(void) +{ +#ifdef CONFIG_RADIO_TYPHOON_PROC_FS + remove_proc_entry("driver/radio-typhoon", NULL); #endif video_unregister_device(&typhoon_radio); release_region(io, 8); } -#endif - +module_init(typhoon_init); +module_exit(typhoon_cleanup_module); diff -u --recursive --new-file v2.3.24/linux/drivers/char/radio-zoltrix.c linux/drivers/char/radio-zoltrix.c --- v2.3.24/linux/drivers/char/radio-zoltrix.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/char/radio-zoltrix.c Thu Oct 28 16:13:13 1999 @@ -354,8 +354,12 @@ NULL }; -int __init zoltrix_init(struct video_init *v) +static int __init zoltrix_init(void) { + if (io == -1) { + printk(KERN_ERR "You must set an I/O address with io=0x???\n"); + return -EINVAL; + } if (check_region(io, 2)) { printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io); return -EBUSY; @@ -390,8 +394,6 @@ return 0; } -#ifdef MODULE - MODULE_AUTHOR("C.van Schaik"); MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus."); MODULE_PARM(io, "i"); @@ -399,19 +401,12 @@ EXPORT_NO_SYMBOLS; -int init_module(void) -{ - if (io == -1) { - printk(KERN_ERR "You must set an I/O address with io=0x???\n"); - return -EINVAL; - } - return zoltrix_init(NULL); -} - -void cleanup_module(void) +static void __exit zoltrix_cleanup_module(void) { video_unregister_device(&zoltrix_radio); release_region(io, 2); } -#endif +module_init(zoltrix_init); +module_exit(zoltrix_cleanup_module); + diff -u --recursive --new-file v2.3.24/linux/drivers/char/riscom8.c linux/drivers/char/riscom8.c --- v2.3.24/linux/drivers/char/riscom8.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/char/riscom8.c Thu Oct 28 10:42:02 1999 @@ -75,6 +75,8 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif +#define RS_EVENT_WRITE_WAKEUP 0 + DECLARE_TASK_QUEUE(tq_riscom); #define RISCOM_TYPE_NORMAL 1 diff -u --recursive --new-file v2.3.24/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v2.3.24/linux/drivers/char/serial.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/char/serial.c Thu Oct 28 10:45:51 1999 @@ -152,12 +152,12 @@ #endif #endif /* NEW_MODULES */ #include - +#include #ifdef LOCAL_HEADERS #include "serial_local.h" #else -#include #include +#include #include #include static char *serial_version = "4.30"; diff -u --recursive --new-file v2.3.24/linux/drivers/char/specialix.c linux/drivers/char/specialix.c --- v2.3.24/linux/drivers/char/specialix.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/char/specialix.c Thu Oct 28 10:42:02 1999 @@ -171,7 +171,8 @@ DECLARE_TASK_QUEUE(tq_specialix); - +#undef RS_EVENT_WRITE_WAKEUP +#define RS_EVENT_WRITE_WAKEUP 0 #define SPECIALIX_TYPE_NORMAL 1 #define SPECIALIX_TYPE_CALLOUT 2 diff -u --recursive --new-file v2.3.24/linux/drivers/char/sx.c linux/drivers/char/sx.c --- v2.3.24/linux/drivers/char/sx.c Thu Aug 5 14:47:44 1999 +++ linux/drivers/char/sx.c Thu Oct 28 10:42:02 1999 @@ -340,6 +340,8 @@ #endif +#undef RS_EVENT_WRITE_WAKEUP +#define RS_EVENT_WRITE_WAKEUP 0 #include "generic_serial.h" diff -u --recursive --new-file v2.3.24/linux/drivers/char/videodev.c linux/drivers/char/videodev.c --- v2.3.24/linux/drivers/char/videodev.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/char/videodev.c Thu Oct 28 16:13:20 1999 @@ -57,21 +57,6 @@ #ifdef CONFIG_VIDEO_PLANB extern int init_planbs(struct video_init *); #endif -#ifdef CONFIG_RADIO_RTRACK2 -extern int rtrack2_init(struct video_init *); -#endif -#ifdef CONFIG_RADIO_SF16FMI -extern int fmi_init(struct video_init *); -#endif -#ifdef CONFIG_RADIO_TYPHOON -extern int typhoon_init(struct video_init *); -#endif -#ifdef CONFIG_RADIO_CADET -extern int cadet_init(struct video_init *); -#endif -#ifdef CONFIG_RADIO_TERRATEC -extern int terratec_init(struct video_init *); -#endif #ifdef CONFIG_VIDEO_ZORAN extern int init_zoran_cards(struct video_init *); #endif @@ -92,21 +77,6 @@ #endif #ifdef CONFIG_VIDEO_PLANB {"planb", init_planbs}, -#endif -#ifdef CONFIG_RADIO_RTRACK2 - {"RTrack2", rtrack2_init}, -#endif -#ifdef CONFIG_RADIO_SF16FMI - {"SF16FMI", fmi_init}, -#endif -#ifdef CONFIG_RADIO_CADET - {"Cadet", cadet_init}, -#endif -#ifdef CONFIG_RADIO_TYPHOON - {"radio-typhoon", typhoon_init}, -#endif -#ifdef CONFIG_RADIO_TERRATEC - {"radio-terratec", terratec_init}, #endif #ifdef CONFIG_VIDEO_ZORAN {"zoran", init_zoran_cards}, diff -u --recursive --new-file v2.3.24/linux/drivers/misc/acpi.c linux/drivers/misc/acpi.c --- v2.3.24/linux/drivers/misc/acpi.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/misc/acpi.c Mon Nov 1 13:28:43 1999 @@ -74,6 +74,7 @@ static struct acpi_facp *acpi_facp = NULL; static int acpi_fake_facp = 0; +static struct acpi_facs *acpi_facs = NULL; static unsigned long acpi_facp_addr = 0; static unsigned long acpi_dsdt_addr = 0; @@ -88,8 +89,19 @@ static unsigned long acpi_p_lvl3_lat = ~0UL; /* Initialize to guaranteed harmless port read */ -static unsigned long acpi_p_lvl2 = 0x80; -static unsigned long acpi_p_lvl3 = 0x80; +static unsigned long acpi_p_lvl2 = ACPI_P_LVL_DISABLED; +static unsigned long acpi_p_lvl3 = ACPI_P_LVL_DISABLED; + +// bits 8-15 are SLP_TYPa, bits 0-7 are SLP_TYPb +static unsigned long acpi_slp_typ[] = +{ + ACPI_SLP_TYP_DISABLED, /* S0 */ + ACPI_SLP_TYP_DISABLED, /* S1 */ + ACPI_SLP_TYP_DISABLED, /* S2 */ + ACPI_SLP_TYP_DISABLED, /* S3 */ + ACPI_SLP_TYP_DISABLED, /* S4 */ + ACPI_SLP_TYP_DISABLED /* S5 */ +}; static struct ctl_table acpi_table[] = { @@ -125,10 +137,14 @@ {ACPI_P_LVL2_LAT, "p_lvl2_lat", &acpi_p_lvl2_lat, sizeof(acpi_p_lvl2_lat), - 0600, NULL, &acpi_do_ulong}, + 0644, NULL, &acpi_do_ulong}, {ACPI_P_LVL3_LAT, "p_lvl3_lat", &acpi_p_lvl3_lat, sizeof(acpi_p_lvl3_lat), + 0644, NULL, &acpi_do_ulong}, + + {ACPI_S5_SLP_TYP, "s5_slp_typ", + &acpi_slp_typ[5], sizeof(acpi_slp_typ[5]), 0600, NULL, &acpi_do_ulong}, {0} @@ -136,7 +152,7 @@ static struct ctl_table acpi_dir_table[] = { - {CTL_ACPI, "acpi", NULL, 0, 0500, acpi_table}, + {CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table}, {0} }; @@ -379,6 +395,11 @@ acpi_facp = (struct acpi_facp*) dt; acpi_facp_addr = *rsdt_entry; acpi_dsdt_addr = acpi_facp->dsdt; + + if (acpi_facp->facs) { + acpi_facs = (struct acpi_facs*) + acpi_map_table(acpi_facp->facs); + } } else { acpi_unmap_table(dt); @@ -405,6 +426,7 @@ acpi_unmap_table((struct acpi_table*) acpi_facp); else kfree(acpi_facp); + acpi_unmap_table((struct acpi_table*) acpi_facs); } /* @@ -575,8 +597,8 @@ case 3: pm2_cnt = acpi_facp->pm2_cnt; if (pm2_cnt) { - /* Disable PCI arbitration while sleeping, - to avoid DMA corruption? */ + /* Disable PCI arbitration while sleeping, + to avoid DMA corruption? */ outb(inb(pm2_cnt) | ACPI_ARB_DIS, pm2_cnt); inb(acpi_p_lvl3); outb(inb(pm2_cnt) & ~ACPI_ARB_DIS, pm2_cnt); @@ -602,6 +624,42 @@ } /* + * Enter system sleep state + */ +static void acpi_enter_sx(int state) +{ + unsigned long slp_typ = acpi_slp_typ[state]; + if (slp_typ != ACPI_SLP_TYP_DISABLED) { + u16 typa, typb, value; + + // bits 8-15 are SLP_TYPa, bits 0-7 are SLP_TYPb + typa = (slp_typ >> 8) & 0xff; + typb = slp_typ & 0xff; + + typa = ((typa << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK); + typb = ((typb << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK); + + // set SLP_TYPa/b and SLP_EN + if (acpi_facp->pm1a_cnt) { + value = inw(acpi_facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK; + outw(value | typa | ACPI_SLP_EN, acpi_facp->pm1a_cnt); + } + if (acpi_facp->pm1b_cnt) { + value = inw(acpi_facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK; + outw(value | typb | ACPI_SLP_EN, acpi_facp->pm1b_cnt); + } + } +} + +/* + * Enter soft-off (S5) + */ +static void acpi_power_off_handler(void) +{ + acpi_enter_sx(5); +} + +/* * Claim ACPI I/O ports */ static int acpi_claim_ioports(struct acpi_facp *facp) @@ -806,7 +864,7 @@ size_t *len) { u32 pm1_status = 0, gpe_status = 0; - char str[4 * sizeof(u32) + 6]; + char str[4 * sizeof(u32) + 7]; int size; if (write) @@ -879,6 +937,7 @@ return 0; #endif + acpi_power_off = acpi_power_off_handler; acpi_idle = acpi_idle_handler; return 0; @@ -890,6 +949,7 @@ static void __exit acpi_exit(void) { acpi_idle = NULL; + acpi_power_off = NULL; unregister_sysctl_table(acpi_sysctl); acpi_disable(acpi_facp); diff -u --recursive --new-file v2.3.24/linux/drivers/net/3c503.c linux/drivers/net/3c503.c --- v2.3.24/linux/drivers/net/3c503.c Wed Aug 18 11:36:41 1999 +++ linux/drivers/net/3c503.c Thu Oct 28 16:13:20 1999 @@ -449,7 +449,7 @@ if (dev->mem_start) { /* Shared memory transfer */ unsigned long dest_addr = dev->mem_start + ((start_page - ei_status.tx_start_page) << 8); - memcpy_toio(dest_addr, buf, count); + isa_memcpy_toio(dest_addr, buf, count); outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */ return; } @@ -514,7 +514,7 @@ unsigned short word; if (dev->mem_start) { /* Use the shared memory. */ - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); return; } @@ -560,12 +560,12 @@ if (dev->mem_start + ring_offset + count > end_of_ring) { /* We must wrap the input move. */ int semi_count = end_of_ring - (dev->mem_start + ring_offset); - memcpy_fromio(skb->data, dev->mem_start + ring_offset, semi_count); + isa_memcpy_fromio(skb->data, dev->mem_start + ring_offset, semi_count); count -= semi_count; - memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } else { /* Packet is in one chunk -- we can copy + cksum. */ - eth_io_copy_and_sum(skb, dev->mem_start + ring_offset, count, 0); + isa_eth_io_copy_and_sum(skb, dev->mem_start + ring_offset, count, 0); } return; } diff -u --recursive --new-file v2.3.24/linux/drivers/net/3c507.c linux/drivers/net/3c507.c --- v2.3.24/linux/drivers/net/3c507.c Fri Sep 10 23:57:29 1999 +++ linux/drivers/net/3c507.c Fri Oct 29 13:19:49 1999 @@ -462,7 +462,7 @@ return 1; if (net_debug > 1) printk("%s: transmit timed out, %s? ", dev->name, - readw(shmem+iSCB_STATUS) & 0x8000 ? "IRQ conflict" : + isa_readw(shmem+iSCB_STATUS) & 0x8000 ? "IRQ conflict" : "network cable problem"); /* Try to restart the adaptor. */ if (lp->last_restart == lp->stats.tx_packets) { @@ -472,7 +472,7 @@ } else { /* Issue the channel attention signal and hope it "gets better". */ if (net_debug > 1) printk("Kicking board.\n"); - writew(0xf000|CUC_START|RX_START,shmem+iSCB_CMD); + isa_writew(0xf000|CUC_START|RX_START,shmem+iSCB_CMD); outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */ lp->last_restart = lp->stats.tx_packets; } @@ -533,7 +533,7 @@ spin_lock(&lp->lock); - status = readw(shmem+iSCB_STATUS); + status = isa_readw(shmem+iSCB_STATUS); if (net_debug > 4) { printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status); @@ -544,7 +544,7 @@ /* Reap the Tx packet buffers. */ while (lp->tx_reap != lp->tx_head) { - unsigned short tx_status = readw(shmem+lp->tx_reap); + unsigned short tx_status = isa_readw(shmem+lp->tx_reap); if (tx_status == 0) { if (net_debug > 5) printk("Couldn't reap %#x.\n", lp->tx_reap); @@ -599,11 +599,11 @@ printk("%s: Rx unit stopped, status %04x, restarting.\n", dev->name, status); init_rx_bufs(dev); - writew(RX_BUF_START,shmem+iSCB_RFA); + isa_writew(RX_BUF_START,shmem+iSCB_RFA); ack_cmd |= RX_START; } - writew(ack_cmd,shmem+iSCB_CMD); + isa_writew(ack_cmd,shmem+iSCB_CMD); outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */ /* Clear the latched interrupt. */ @@ -625,7 +625,7 @@ dev->start = 0; /* Flush the Tx and disable Rx. */ - writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD); + isa_writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD); outb(0, ioaddr + SIGNAL_CA); /* Disable the 82586's input to the interrupt line. */ @@ -665,24 +665,24 @@ write_ptr = dev->mem_start + cur_rxbuf; - writew(0x0000,write_ptr); /* Status */ - writew(0x0000,write_ptr+=2); /* Command */ - writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2); /* Link */ - writew(cur_rxbuf + 22,write_ptr+=2); /* Buffer offset */ - writew(0x0000,write_ptr+=2); /* Pad for dest addr. */ - writew(0x0000,write_ptr+=2); - writew(0x0000,write_ptr+=2); - writew(0x0000,write_ptr+=2); /* Pad for source addr. */ - writew(0x0000,write_ptr+=2); - writew(0x0000,write_ptr+=2); - writew(0x0000,write_ptr+=2); /* Pad for protocol. */ - - writew(0x0000,write_ptr+=2); /* Buffer: Actual count */ - writew(-1,write_ptr+=2); /* Buffer: Next (none). */ - writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */ - writew(0x0000,write_ptr+=2); + isa_writew(0x0000,write_ptr); /* Status */ + isa_writew(0x0000,write_ptr+=2); /* Command */ + isa_writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2); /* Link */ + isa_writew(cur_rxbuf + 22,write_ptr+=2); /* Buffer offset */ + isa_writew(0x0000,write_ptr+=2); /* Pad for dest addr. */ + isa_writew(0x0000,write_ptr+=2); + isa_writew(0x0000,write_ptr+=2); + isa_writew(0x0000,write_ptr+=2); /* Pad for source addr. */ + isa_writew(0x0000,write_ptr+=2); + isa_writew(0x0000,write_ptr+=2); + isa_writew(0x0000,write_ptr+=2); /* Pad for protocol. */ + + isa_writew(0x0000,write_ptr+=2); /* Buffer: Actual count */ + isa_writew(-1,write_ptr+=2); /* Buffer: Next (none). */ + isa_writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */ + isa_writew(0x0000,write_ptr+=2); /* Finally, the number of bytes in the buffer. */ - writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2); + isa_writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2); lp->rx_tail = cur_rxbuf; cur_rxbuf += RX_BUF_SIZE; @@ -691,8 +691,8 @@ /* Terminate the list by setting the EOL bit, and wrap the pointer to make the list a ring. */ write_ptr = dev->mem_start + lp->rx_tail + 2; - writew(0xC000,write_ptr); /* Command, mark as last. */ - writew(lp->rx_head,write_ptr+2); /* Link */ + isa_writew(0xC000,write_ptr); /* Command, mark as last. */ + isa_writew(lp->rx_head,write_ptr+2); /* Link */ } static void init_82586_mem(struct net_device *dev) @@ -710,13 +710,13 @@ init_words[7] = SCB_BASE; /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */ - memcpy_toio(dev->mem_end-10, init_words, 10); + isa_memcpy_toio(dev->mem_end-10, init_words, 10); /* Write the words at 0x0000. */ - memcpy_toio(dev->mem_start, init_words + 5, sizeof(init_words) - 10); + isa_memcpy_toio(dev->mem_start, init_words + 5, sizeof(init_words) - 10); /* Fill in the station address. */ - memcpy_toio(dev->mem_start+SA_OFFSET, dev->dev_addr, + isa_memcpy_toio(dev->mem_start+SA_OFFSET, dev->dev_addr, sizeof(dev->dev_addr)); /* The Tx-block list is written as needed. We just set up the values. */ @@ -734,11 +734,11 @@ { int boguscnt = 50; - while (readw(shmem+iSCB_STATUS) == 0) + while (isa_readw(shmem+iSCB_STATUS) == 0) if (--boguscnt == 0) { printk("%s: i82586 initialization timed out with status %04x," "cmd %04x.\n", dev->name, - readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD)); + isa_readw(shmem+iSCB_STATUS), isa_readw(shmem+iSCB_CMD)); break; } /* Issue channel-attn -- the 82586 won't start. */ @@ -749,7 +749,7 @@ outb(0x84, ioaddr + MISC_CTRL); if (net_debug > 4) printk("%s: Initialized 82586, status %04x.\n", dev->name, - readw(shmem+iSCB_STATUS)); + isa_readw(shmem+iSCB_STATUS)); return; } @@ -761,27 +761,27 @@ unsigned long write_ptr = dev->mem_start + tx_block; /* Set the write pointer to the Tx block, and put out the header. */ - writew(0x0000,write_ptr); /* Tx status */ - writew(CMD_INTR|CmdTx,write_ptr+=2); /* Tx command */ - writew(tx_block+16,write_ptr+=2); /* Next command is a NoOp. */ - writew(tx_block+8,write_ptr+=2); /* Data Buffer offset. */ + isa_writew(0x0000,write_ptr); /* Tx status */ + isa_writew(CMD_INTR|CmdTx,write_ptr+=2); /* Tx command */ + isa_writew(tx_block+16,write_ptr+=2); /* Next command is a NoOp. */ + isa_writew(tx_block+8,write_ptr+=2); /* Data Buffer offset. */ /* Output the data buffer descriptor. */ - writew(length | 0x8000,write_ptr+=2); /* Byte count parameter. */ - writew(-1,write_ptr+=2); /* No next data buffer. */ - writew(tx_block+22+SCB_BASE,write_ptr+=2); /* Buffer follows the NoOp command. */ - writew(0x0000,write_ptr+=2); /* Buffer address high bits (always zero). */ + isa_writew(length | 0x8000,write_ptr+=2); /* Byte count parameter. */ + isa_writew(-1,write_ptr+=2); /* No next data buffer. */ + isa_writew(tx_block+22+SCB_BASE,write_ptr+=2); /* Buffer follows the NoOp command. */ + isa_writew(0x0000,write_ptr+=2); /* Buffer address high bits (always zero). */ /* Output the Loop-back NoOp command. */ - writew(0x0000,write_ptr+=2); /* Tx status */ - writew(CmdNOp,write_ptr+=2); /* Tx command */ - writew(tx_block+16,write_ptr+=2); /* Next is myself. */ + isa_writew(0x0000,write_ptr+=2); /* Tx status */ + isa_writew(CmdNOp,write_ptr+=2); /* Tx command */ + isa_writew(tx_block+16,write_ptr+=2); /* Next is myself. */ /* Output the packet at the write pointer. */ - memcpy_toio(write_ptr+2, buf, length); + isa_memcpy_toio(write_ptr+2, buf, length); /* Set the old command link pointing to this send packet. */ - writew(tx_block,dev->mem_start + lp->tx_cmd_link); + isa_isa_writew(tx_block,dev->mem_start + lp->tx_cmd_link); lp->tx_cmd_link = tx_block + 20; /* Set the next free tx region. */ @@ -807,13 +807,13 @@ ushort boguscount = 10; short frame_status; - while ((frame_status = readw(shmem+rx_head)) < 0) { /* Command complete */ + while ((frame_status = isa_readw(shmem+rx_head)) < 0) { /* Command complete */ unsigned long read_frame = dev->mem_start + rx_head; - ushort rfd_cmd = readw(read_frame+2); - ushort next_rx_frame = readw(read_frame+4); - ushort data_buffer_addr = readw(read_frame+6); + ushort rfd_cmd = isa_readw(read_frame+2); + ushort next_rx_frame = isa_readw(read_frame+4); + ushort data_buffer_addr = isa_readw(read_frame+6); unsigned long data_frame = dev->mem_start + data_buffer_addr; - ushort pkt_len = readw(data_frame); + ushort pkt_len = isa_readw(data_frame); if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22 || (pkt_len & 0xC000) != 0xC000) { @@ -845,7 +845,7 @@ skb->dev = dev; /* 'skb->data' points to the start of sk_buff data area. */ - memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len); + isa_memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); @@ -853,10 +853,10 @@ } /* Clear the status word and set End-of-List on the rx frame. */ - writew(0,read_frame); - writew(0xC000,read_frame+2); + isa_writew(0,read_frame); + isa_writew(0xC000,read_frame+2); /* Clear the end-of-list on the prev. RFD. */ - writew(0x0000,dev->mem_start + rx_tail + 2); + isa_writew(0x0000,dev->mem_start + rx_tail + 2); rx_tail = rx_head; rx_head = next_rx_frame; diff -u --recursive --new-file v2.3.24/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c --- v2.3.24/linux/drivers/net/ac3200.c Wed Aug 18 11:36:41 1999 +++ linux/drivers/net/ac3200.c Fri Oct 29 13:19:49 1999 @@ -293,7 +293,7 @@ ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8); - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); } /* Block input and output are easy on shared memory ethercards, the only @@ -307,12 +307,12 @@ if (xfer_start + count > dev->rmem_end) { /* We must wrap the input move. */ int semi_count = dev->rmem_end - xfer_start; - memcpy_fromio(skb->data, xfer_start, semi_count); + isa_memcpy_fromio(skb->data, xfer_start, semi_count); count -= semi_count; - memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } else { /* Packet is in one chunk -- we can copy + cksum. */ - eth_io_copy_and_sum(skb, xfer_start, count, 0); + isa_eth_io_copy_and_sum(skb, xfer_start, count, 0); } } @@ -321,7 +321,7 @@ { unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8); - memcpy_toio(shmem, buf, count); + isa_memcpy_toio(shmem, buf, count); } static int ac_close_card(struct net_device *dev) diff -u --recursive --new-file v2.3.24/linux/drivers/net/bmac.c linux/drivers/net/bmac.c --- v2.3.24/linux/drivers/net/bmac.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/net/bmac.c Thu Oct 28 14:34:46 1999 @@ -3,6 +3,9 @@ * Apple Powermacs. Assumes it's under a DBDMA controller. * * Copyright (C) 1998 Randy Gobbel. + * + * May 1999, Al Viro: proper release of /proc/net/bmac entry, switched to + * dynamic procfs inode. */ #include #include @@ -1378,14 +1381,7 @@ if (!bmac_reset_and_enable(dev, 0)) return -ENOMEM; -#ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_BMAC, 4, "bmac", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - bmac_proc_info - }); -#endif + proc_net_create ("bmac", 0, bmac_proc_info); return 0; } @@ -1627,6 +1623,7 @@ bp = (struct bmac_data *) bmac_devs->priv; unregister_netdev(bmac_devs); + proc_net_remove("bmac"); free_irq(bmac_devs->irq, bmac_misc_intr); free_irq(bp->tx_dma_intr, bmac_txdma_intr); diff -u --recursive --new-file v2.3.24/linux/drivers/net/es3210.c linux/drivers/net/es3210.c --- v2.3.24/linux/drivers/net/es3210.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/es3210.c Fri Oct 29 13:19:49 1999 @@ -321,7 +321,7 @@ es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - ES_START_PG)<<8); - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ } @@ -339,12 +339,12 @@ if (xfer_start + count > dev->rmem_end) { /* Packet wraps over end of ring buffer. */ int semi_count = dev->rmem_end - xfer_start; - memcpy_fromio(skb->data, xfer_start, semi_count); + isa_memcpy_fromio(skb->data, xfer_start, semi_count); count -= semi_count; - memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } else { /* Packet is in one chunk. */ - memcpy_fromio(skb->data, xfer_start, count); + isa_eth_io_copy_and_csum(skb, xfer_start, count, 0); } } @@ -354,7 +354,7 @@ unsigned long shmem = dev->mem_start + ((start_page - ES_START_PG)<<8); count = (count + 3) & ~3; /* Round up to doubleword */ - memcpy_toio(shmem, buf, count); + isa_memcpy_toio(shmem, buf, count); } static int es_open(struct net_device *dev) diff -u --recursive --new-file v2.3.24/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c --- v2.3.24/linux/drivers/net/ewrk3.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/net/ewrk3.c Fri Oct 29 13:19:49 1999 @@ -829,16 +829,16 @@ writeb(0x04, (char *) buf); /* index byte */ buf += 1; writeb(0x00, (char *) (buf + skb->len)); /* Write the XCT flag */ - memcpy_toio(buf, skb->data, PRELOAD); /* Write PRELOAD bytes */ + isa_memcpy_toio(buf, skb->data, PRELOAD); /* Write PRELOAD bytes */ outb(page, EWRK3_TQ); /* Start sending pkt */ - memcpy_toio(buf + PRELOAD, skb->data + PRELOAD, skb->len - PRELOAD); + isa_memcpy_toio(buf + PRELOAD, skb->data + PRELOAD, skb->len - PRELOAD); writeb(0xff, (char *) (buf + skb->len)); /* Write the XCT flag */ } else { writeb((char) ((skb->len >> 8) & 0xff), (char *) buf); buf += 1; writeb(0x04, (char *) buf); /* index byte */ buf += 1; - memcpy_toio((char *) buf, skb->data, skb->len); /* Write data bytes */ + isa_memcpy_toio(buf, skb->data, skb->len); /* Write data bytes */ outb(page, EWRK3_TQ); /* Start sending pkt */ } } @@ -1012,7 +1012,7 @@ *p++ = inb(EWRK3_DATA); } } else { - memcpy_fromio(p, buf, pkt_len); + isa_memcpy_fromio(p, buf, pkt_len); } /* @@ -1737,7 +1737,7 @@ } } else { outb(0, EWRK3_MPR); - memcpy_fromio(tmp.addr, (char *) (lp->shmem_base + PAGE0_HTE), (HASH_TABLE_LEN >> 3)); + isa_memcpy_fromio(tmp.addr, lp->shmem_base + PAGE0_HTE, (HASH_TABLE_LEN >> 3)); } ioc->len = (HASH_TABLE_LEN >> 3); if (copy_to_user(ioc->data, tmp.addr, ioc->len)) { diff -u --recursive --new-file v2.3.24/linux/drivers/net/hamradio/bpqether.c linux/drivers/net/hamradio/bpqether.c --- v2.3.24/linux/drivers/net/hamradio/bpqether.c Thu Aug 26 13:05:38 1999 +++ linux/drivers/net/hamradio/bpqether.c Thu Oct 28 14:34:46 1999 @@ -632,14 +632,7 @@ printk(KERN_INFO "AX.25 ethernet driver version 0.01\n"); -#ifdef CONFIG_PROC_FS - proc_net_register(&(struct proc_dir_entry) { - PROC_NET_AX25_BPQETHER, 8, "bpqether", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_net_inode_operations, - bpq_get_info - }); -#endif + proc_net_create ("bpqether", 0, bpq_get_info); read_lock_bh(&dev_base_lock); for (dev = dev_base; dev != NULL; dev = dev->next) { @@ -673,9 +666,7 @@ unregister_netdevice_notifier(&bpq_dev_notifier); -#ifdef CONFIG_PROC_FS - proc_net_unregister(PROC_NET_AX25_BPQETHER); -#endif + proc_net_remove ("bpqether"); for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next) unregister_netdev(&bpq->axdev); diff -u --recursive --new-file v2.3.24/linux/drivers/net/hamradio/scc.c linux/drivers/net/hamradio/scc.c --- v2.3.24/linux/drivers/net/hamradio/scc.c Wed Aug 18 11:38:50 1999 +++ linux/drivers/net/hamradio/scc.c Thu Oct 28 14:34:46 1999 @@ -2174,15 +2174,8 @@ } #ifdef CONFIG_PROC_FS - -struct proc_dir_entry scc_proc_dir_entry = -{ - PROC_NET_Z8530, 8, "z8530drv", S_IFREG | S_IRUGO, 1, 0, 0, 0, - &proc_net_inode_operations, scc_net_get_info -}; - -#define scc_net_procfs_init() proc_net_register(&scc_proc_dir_entry); -#define scc_net_procfs_remove() proc_net_unregister(PROC_NET_Z8530); +#define scc_net_procfs_init() proc_net_create("z8530drv",0,scc_net_get_info) +#define scc_net_procfs_remove() proc_net_remove("z8530drv") #else #define scc_net_procfs_init() #define scc_net_procfs_remove() diff -u --recursive --new-file v2.3.24/linux/drivers/net/hamradio/yam.c linux/drivers/net/hamradio/yam.c --- v2.3.24/linux/drivers/net/hamradio/yam.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/net/hamradio/yam.c Thu Oct 28 14:34:46 1999 @@ -893,28 +893,17 @@ } #ifdef CONFIG_INET - -#ifndef PROC_NET_YAM -#define PROC_NET_YAM (PROC_NET_LAST+10) /* Sorry again... */ -#endif - #ifdef CONFIG_PROC_FS -struct proc_dir_entry yam_proc_dir_entry = -{ - PROC_NET_YAM, 3, "yam", S_IFREG | S_IRUGO, 1, 0, 0, 0, - &proc_net_inode_operations, yam_net_get_info -}; - -#define yam_net_procfs_init() proc_net_register(&yam_proc_dir_entry); -#define yam_net_procfs_remove() proc_net_unregister(PROC_NET_YAM); +#define yam_net_procfs_init() proc_net_create("yam",0,yam_net_get_info) +#define yam_net_procfs_remove() proc_net_remove("yam") #else #define yam_net_procfs_init() #define yam_net_procfs_remove() -#endif +#endif /* CONFIG_PROC_FS */ #else #define yam_net_procfs_init() #define yam_net_procfs_remove() -#endif +#endif /* CONFIG_INET */ /* --------------------------------------------------------------------- */ diff -u --recursive --new-file v2.3.24/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c --- v2.3.24/linux/drivers/net/hp-plus.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/hp-plus.c Fri Oct 29 13:20:35 1999 @@ -361,7 +361,7 @@ outw((ring_page<<8), ioaddr + HPP_IN_ADDR); outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION); - memcpy_fromio(hdr, dev->mem_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, dev->mem_start, sizeof(struct e8390_pkt_hdr)); outw(option_reg, ioaddr + HPP_OPTION); hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ } @@ -380,7 +380,7 @@ Also note that we *can't* use eth_io_copy_and_sum() because it will not always copy "count" bytes (e.g. padded IP). */ - memcpy_fromio(skb->data, dev->mem_start, count); + isa_memcpy_fromio(skb->data, dev->mem_start, count); outw(option_reg, ioaddr + HPP_OPTION); } @@ -405,7 +405,7 @@ outw(start_page << 8, ioaddr + HPP_OUT_ADDR); outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION); - memcpy_toio(dev->mem_start, buf, (count + 3) & ~3); + isa_memcpy_toio(dev->mem_start, buf, (count + 3) & ~3); outw(option_reg, ioaddr + HPP_OPTION); return; diff -u --recursive --new-file v2.3.24/linux/drivers/net/lne390.c linux/drivers/net/lne390.c --- v2.3.24/linux/drivers/net/lne390.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/lne390.c Fri Oct 29 13:20:35 1999 @@ -316,7 +316,7 @@ lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - LNE390_START_PG)<<8); - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ } @@ -334,12 +334,12 @@ if (xfer_start + count > dev->rmem_end) { /* Packet wraps over end of ring buffer. */ int semi_count = dev->rmem_end - xfer_start; - memcpy_fromio(skb->data, xfer_start, semi_count); + isa_memcpy_fromio(skb->data, xfer_start, semi_count); count -= semi_count; - memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } else { /* Packet is in one chunk. */ - memcpy_fromio(skb->data, xfer_start, count); + isa_memcpy_fromio(skb->data, xfer_start, count); } } @@ -349,7 +349,7 @@ unsigned long shmem = dev->mem_start + ((start_page - LNE390_START_PG)<<8); count = (count + 3) & ~3; /* Round up to doubleword */ - memcpy_toio(shmem, buf, count); + isa_memcpy_toio(shmem, buf, count); } static int lne390_open(struct net_device *dev) diff -u --recursive --new-file v2.3.24/linux/drivers/net/ne3210.c linux/drivers/net/ne3210.c --- v2.3.24/linux/drivers/net/ne3210.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/ne3210.c Fri Oct 29 13:20:35 1999 @@ -307,7 +307,7 @@ ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { unsigned long hdr_start = dev->mem_start + ((ring_page - NE3210_START_PG)<<8); - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ } @@ -325,12 +325,12 @@ if (xfer_start + count > dev->rmem_end) { /* Packet wraps over end of ring buffer. */ int semi_count = dev->rmem_end - xfer_start; - memcpy_fromio(skb->data, xfer_start, semi_count); + isa_memcpy_fromio(skb->data, xfer_start, semi_count); count -= semi_count; - memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } else { /* Packet is in one chunk. */ - memcpy_fromio(skb->data, xfer_start, count); + isa_memcpy_fromio(skb->data, xfer_start, count); } } @@ -340,7 +340,7 @@ unsigned long shmem = dev->mem_start + ((start_page - NE3210_START_PG)<<8); count = (count + 3) & ~3; /* Round up to doubleword */ - memcpy_toio(shmem, buf, count); + isa_memcpy_toio(shmem, buf, count); } static int ne3210_open(struct net_device *dev) diff -u --recursive --new-file v2.3.24/linux/drivers/net/sk_mca.c linux/drivers/net/sk_mca.c --- v2.3.24/linux/drivers/net/sk_mca.c Mon Oct 11 15:38:15 1999 +++ linux/drivers/net/sk_mca.c Fri Oct 29 13:20:35 1999 @@ -306,7 +306,7 @@ descr.Flags = 0; descr.Len = 0xf000; descr.Status = 0; - memcpy_toio(dev->mem_start + RAM_TXBASE + (z * sizeof(LANCE_TxDescr)), + isa_memcpy_toio(dev->mem_start + RAM_TXBASE + (z * sizeof(LANCE_TxDescr)), &descr, sizeof(LANCE_TxDescr)); memset_io(dev->mem_start + bufaddr, 0, RAM_BUFSIZE); bufaddr += RAM_BUFSIZE; @@ -325,9 +325,9 @@ descr.Flags = RXDSCR_FLAGS_OWN; descr.MaxLen = -RAM_BUFSIZE; descr.Len = 0; - memcpy_toio(dev->mem_start + RAM_RXBASE + (z * sizeof(LANCE_RxDescr)), + isa_memcpy_toio(dev->mem_start + RAM_RXBASE + (z * sizeof(LANCE_RxDescr)), &descr, sizeof(LANCE_RxDescr)); - memset_io(dev->mem_start + bufaddr, 0, RAM_BUFSIZE); + isa_memset_io(dev->mem_start + bufaddr, 0, RAM_BUFSIZE); bufaddr += RAM_BUFSIZE; } } @@ -450,7 +450,7 @@ block.RdrP = (RAM_RXBASE & 0xffffff) | (LRXCOUNT << 29); block.TdrP = (RAM_TXBASE & 0xffffff) | (LTXCOUNT << 29); - memcpy_toio(dev->mem_start + RAM_INITBASE, &block, sizeof(block)); + isa_memcpy_toio(dev->mem_start + RAM_INITBASE, &block, sizeof(block)); /* initialize LANCE. Implicitly sets up other structures in RAM. */ @@ -507,7 +507,7 @@ while (1) { /* read descriptor */ - memcpy_fromio(&descr, dev->mem_start + descraddr, sizeof(LANCE_RxDescr)); + isa_memcpy_fromio(&descr, dev->mem_start + descraddr, sizeof(LANCE_RxDescr)); /* if we reach a descriptor we do not own, we're done */ if ((descr.Flags & RXDSCR_FLAGS_OWN) != 0) @@ -539,7 +539,7 @@ priv->stat.rx_dropped++; else { - memcpy_fromio(skb_put(skb, descr.Len), + isa_memcpy_fromio(skb_put(skb, descr.Len), dev->mem_start + descr.LowAddr, descr.Len); skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); @@ -557,7 +557,7 @@ descr.Flags |= RXDSCR_FLAGS_OWN; /* update descriptor in shared RAM */ - memcpy_toio(dev->mem_start + descraddr, &descr, sizeof(LANCE_RxDescr)); + isa_memcpy_toio(dev->mem_start + descraddr, &descr, sizeof(LANCE_RxDescr)); /* go to next descriptor */ priv->nextrx++; descraddr += sizeof(LANCE_RxDescr); @@ -588,7 +588,7 @@ while (priv->txbusy > 0) { /* read descriptor */ - memcpy_fromio(&descr, dev->mem_start + descraddr, sizeof(LANCE_TxDescr)); + isa_memcpy_fromio(&descr, dev->mem_start + descraddr, sizeof(LANCE_TxDescr)); /* if the LANCE still owns this one, we've worked out all sent packets */ if ((descr.Flags & TXDSCR_FLAGS_OWN) != 0) @@ -798,7 +798,7 @@ /* get TX descriptor */ address = RAM_TXBASE + (priv->nexttxput * sizeof(LANCE_TxDescr)); - memcpy_fromio(&descr, dev->mem_start + address, sizeof(LANCE_TxDescr)); + isa_memcpy_fromio(&descr, dev->mem_start + address, sizeof(LANCE_TxDescr)); /* enter packet length as 2s complement - assure minimum length */ tmplen = skb->len; @@ -816,13 +816,13 @@ while (destoffs < tmplen) { - memcpy_toio(dev->mem_start + descr.LowAddr + destoffs, fill, l); + isa_memcpy_toio(dev->mem_start + descr.LowAddr + destoffs, fill, l); destoffs += l; } } /* do the real data copying */ - memcpy_toio(dev->mem_start + descr.LowAddr, skb->data, skb->len); + isa_memcpy_toio(dev->mem_start + descr.LowAddr, skb->data, skb->len); /* hand descriptor over to LANCE - this is the first and last chunk */ descr.Flags = TXDSCR_FLAGS_OWN | TXDSCR_FLAGS_STP | TXDSCR_FLAGS_ENP; @@ -841,7 +841,7 @@ dev->tbusy = (priv->txbusy >= TXCOUNT); /* write descriptor back to RAM */ - memcpy_toio(dev->mem_start + address, &descr, sizeof(LANCE_TxDescr)); + isa_memcpy_toio(dev->mem_start + address, &descr, sizeof(LANCE_TxDescr)); /* if no descriptors were active, give the LANCE a hint to read it immediately */ @@ -891,7 +891,7 @@ StopLANCE(dev); /* ...then modify the initialization block... */ - memcpy_fromio(&block, dev->mem_start + RAM_INITBASE, sizeof(block)); + isa_memcpy_fromio(&block, dev->mem_start + RAM_INITBASE, sizeof(block)); if (dev->flags & IFF_PROMISC) block.Mode |= LANCE_INIT_PROM; else @@ -914,7 +914,7 @@ } } - memcpy_toio(dev->mem_start + RAM_INITBASE, &block, sizeof(block)); + isa_memcpy_toio(dev->mem_start + RAM_INITBASE, &block, sizeof(block)); /* ...then reinit LANCE with the correct flags */ InitLANCE(dev); diff -u --recursive --new-file v2.3.24/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c --- v2.3.24/linux/drivers/net/smc-ultra.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/smc-ultra.c Fri Oct 29 13:20:35 1999 @@ -312,9 +312,9 @@ outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */ #ifdef notdef /* Officially this is what we are doing, but the readl() is faster */ - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); #else - ((unsigned int*)hdr)[0] = readl(hdr_start); + ((unsigned int*)hdr)[0] = isa_readl(hdr_start); #endif outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */ } @@ -333,12 +333,12 @@ if (xfer_start + count > dev->rmem_end) { /* We must wrap the input move. */ int semi_count = dev->rmem_end - xfer_start; - memcpy_fromio(skb->data, xfer_start, semi_count); + isa_memcpy_fromio(skb->data, xfer_start, semi_count); count -= semi_count; - memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } else { /* Packet is in one chunk -- we can copy + cksum. */ - eth_io_copy_and_sum(skb, xfer_start, count, 0); + isa_eth_io_copy_and_sum(skb, xfer_start, count, 0); } outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ @@ -353,7 +353,7 @@ /* Enable shared memory. */ outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); - memcpy_toio(shmem, buf, count); + isa_memcpy_toio(shmem, buf, count); outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ } diff -u --recursive --new-file v2.3.24/linux/drivers/net/smc-ultra32.c linux/drivers/net/smc-ultra32.c --- v2.3.24/linux/drivers/net/smc-ultra32.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/smc-ultra32.c Fri Oct 29 13:20:35 1999 @@ -314,9 +314,9 @@ #ifdef notdef /* Officially this is what we are doing, but the readl() is faster */ - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); #else - ((unsigned int*)hdr)[0] = readl(hdr_start); + ((unsigned int*)hdr)[0] = isa_readl(hdr_start); #endif } @@ -335,21 +335,21 @@ if ((ring_offset & ~0x1fff) != ((ring_offset + count - 1) & ~0x1fff)) { int semi_count = 8192 - (ring_offset & 0x1FFF); - memcpy_fromio(skb->data, xfer_start, semi_count); + isa_memcpy_fromio(skb->data, xfer_start, semi_count); count -= semi_count; if (ring_offset < 96*256) { /* Select next 8KB Window. */ ring_offset += semi_count; outb(ei_status.reg0 | ((ring_offset & 0x6000) >> 13), RamReg); - memcpy_fromio(skb->data + semi_count, dev->mem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->mem_start, count); } else { /* Select first 8KB Window. */ outb(ei_status.reg0, RamReg); - memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } } else { /* Packet is in one chunk -- we can copy + cksum. */ - eth_io_copy_and_sum(skb, xfer_start, count, 0); + isa_eth_io_copy_and_sum(skb, xfer_start, count, 0); } } @@ -364,7 +364,7 @@ /* Select first 8KB Window. */ outb(ei_status.reg0, RamReg); - memcpy_toio(xfer_start, buf, count); + isa_memcpy_toio(xfer_start, buf, count); } #ifdef MODULE diff -u --recursive --new-file v2.3.24/linux/drivers/net/strip.c linux/drivers/net/strip.c --- v2.3.24/linux/drivers/net/strip.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/net/strip.c Thu Oct 28 14:34:46 1999 @@ -118,8 +118,8 @@ #include #include #include -#include #include +#include #include #include @@ -1270,25 +1270,6 @@ return(calc_start_len(buffer, start, req_offset, req_len, total, buf)); } -static const char proc_strip_status_name[] = "strip"; - -#ifdef CONFIG_PROC_FS -static struct proc_dir_entry proc_strip_get_status_info = -{ - PROC_NET_STRIP_STATUS, /* unsigned short low_ino */ - sizeof(proc_strip_status_name)-1, /* unsigned short namelen */ - proc_strip_status_name, /* const char *name */ - S_IFREG | S_IRUGO, /* mode_t mode */ - 1, /* nlink_t nlink */ - 0, 0, 0, /* uid_t uid, gid_t gid, unsigned long size */ - &proc_net_inode_operations, /* struct inode_operations * ops */ - &get_status_info, /* int (*get_info)(...) */ - NULL, /* void (*fill_inode)(struct inode *); */ - NULL, NULL, NULL, /* struct proc_dir_entry *next, *parent, *subdir; */ - NULL /* void *data; */ -}; -#endif /* CONFIG_PROC_FS */ - /************************************************************************/ /* Sending routines */ @@ -2885,12 +2866,7 @@ /* * Register the status file with /proc */ -#ifdef CONFIG_PROC_FS - if (proc_net_register(&proc_strip_get_status_info) != 0) - { - printk(KERN_ERR "strip: status proc_net_register() failed.\n"); - } -#endif + proc_net_create ("strip", S_IFREG | S_IRUGO, get_status_info); #ifdef MODULE return status; @@ -2921,9 +2897,7 @@ strip_free(struct_strip_list); /* Unregister with the /proc/net file here. */ -#ifdef CONFIG_PROC_FS - proc_net_unregister(PROC_NET_STRIP_STATUS); -#endif + proc_net_remove ("strip"); if ((i = tty_register_ldisc(N_STRIP, NULL))) printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i); diff -u --recursive --new-file v2.3.24/linux/drivers/net/wan/cycx_drv.c linux/drivers/net/wan/cycx_drv.c --- v2.3.24/linux/drivers/net/wan/cycx_drv.c Mon Oct 11 15:38:15 1999 +++ linux/drivers/net/wan/cycx_drv.c Sun Oct 31 00:19:22 1999 @@ -1,9 +1,8 @@ /* -* cycx_drv.c cycx Support Module. +* cycx_drv.c Cyclom 2X Support Module. * * This module is a library of common hardware-specific -* functions used by all Cyclades sync and some async (8x & 16x) -* drivers. +* functions used by the Cyclades Cyclom 2X sync card. * * Copyright: (c) 1998, 1999 Arnaldo Carvalho de Melo * @@ -16,6 +15,11 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 1999/10/26 acme use isa_read[bw], isa_write[bw] and isa_memcpy_to +* and fromio +* 1999/10/23 acme cleanup to only supports cyclom2x: all the other +* boards are no longer manufactured by cyclades, if +* someone wants to support them... be my guest! * 1999/05/28 acme cycx_intack & cycx_intde gone for good * 1999/05/18 acme lots of unlogged work, submitting to Linus... * 1999/01/03 acme more judicious use of data types @@ -27,16 +31,16 @@ * to ack an int in cycx_drv.c, only handle it in * cyx_isr (or in the other protocols: cyp_isr, * cyf_isr, when they get implemented. -* Dec 31, 1998 Arnaldo cycx_data_boot & cycx_code_boot fixed, crossing +* Dec 31, 1998 acme cycx_data_boot & cycx_code_boot fixed, crossing * fingers to see x25_configure in cycx_x25.c * work... :) -* Dec 26, 1998 Arnaldo load implementation fixed, seems to work! :) +* Dec 26, 1998 acme load implementation fixed, seems to work! :) * cycx_2x_dpmbase_options with all the possible * DPM addresses (20). * cycx_intr implemented (test this!) * general code cleanup * Dec 8, 1998 Ivan Passos Cyclom-2X firmware load implementation. -* Aug 8, 1998 Arnaldo Initial version. +* Aug 8, 1998 acme Initial version. */ #ifdef MODULE @@ -57,11 +61,11 @@ #include /* for inb(), outb(), etc. */ #define MOD_VERSION 0 -#define MOD_RELEASE 2 +#define MOD_RELEASE 3 #ifdef MODULE MODULE_AUTHOR("Arnaldo Carvalho de Melo"); -MODULE_DESCRIPTION("Cyclades Sync Cards Driver."); +MODULE_DESCRIPTION("Cyclom 2x Sync Card Driver"); #endif /* Function Prototypes */ @@ -70,15 +74,12 @@ void cleanup_module (void); /* Hardware-specific functions */ -static int cycx_detect (cycxhw_t *hw); -static int cycx_load (cycxhw_t *hw, cfm_t *cfm, u32 len); -static int cycx_init (cycxhw_t *hw); -static int cycx_reset (cycxhw_t *hw); +static int load_cyc2x (cycxhw_t *hw, cfm_t *cfm, u32 len); static void cycx_bootcfg (cycxhw_t *hw); -static int init_cycx_2x (cycxhw_t *hw); -static int reset_cycx_2x (u32 addr); -static int detect_cycx_2x (u32 addr); +static int init_cyc2x (cycxhw_t *hw); +static int reset_cyc2x (u32 addr); +static int detect_cyc2x (u32 addr); /* Miscellaneous functions */ static void delay_cycx (int sec); @@ -87,19 +88,25 @@ #define wait_cyc(addr) cycx_exec(addr + CMD_OFFSET) -/* Global Data - * Note: All data must be explicitly initialized!!! */ +#define cyc2x_readb(b) isa_readb(b) +#define cyc2x_readw(b) isa_readw(b) +#define cyc2x_writeb(b, addr) isa_writeb(b, addr) +#define cyc2x_writew(w, addr) isa_writew(w, addr) +#define cyc2x_memcpy_toio(addr, buf, len) isa_memcpy_toio((addr), buf, len) +#define cyc2x_memcpy_fromio(buf, addr, len) isa_memcpy_fromio(buf, (addr), len) + +/* Global Data */ /* private data */ static char modname[] = "cycx_drv"; -static char fullname[] = "Cyclom X Support Module"; +static char fullname[] = "Cyclom 2X Support Module"; static char copyright[] = "(c) 1998, 1999 Arnaldo Carvalho de Melo"; /* Hardware configuration options. * These are arrays of configuration options used by verification routines. * The first element of each array is its size (i.e. number of options). */ -static u32 cycx_2x_dpmbase_options[] = +static u32 cyc2x_dpmbase_options[] = { 20, 0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, 0xB8000, @@ -143,32 +150,18 @@ EXPORT_SYMBOL(cycx_setup); int cycx_setup (cycxhw_t *hw, void *cfm, u32 len) { - u32 *irq_opt = NULL; /* IRQ options */ - u32 *dpmbase_opt = NULL;/* DPM window base options */ - int err = 0; - - if (cycx_detect(hw)) { - printk(KERN_ERR "%s: adapter Cyclom %uX not found at " + if (!detect_cyc2x(hw->dpmbase)) { + printk(KERN_ERR "%s: adapter Cyclom 2X not found at " "address 0x%lX!\n", - modname, hw->type, (unsigned long) hw->dpmbase); + modname, (unsigned long) hw->dpmbase); return -EINVAL; } - printk(KERN_INFO "%s: found Cyclom %uX card at address 0x%lx.\n", - modname, hw->type, (unsigned long) hw->dpmbase); - - switch (hw->type) { - case CYCX_2X: - irq_opt = cycx_2x_irq_options; - dpmbase_opt = cycx_2x_dpmbase_options; - break; - default: - printk(KERN_ERR "%s: unknown card.\n", modname); - return -EINVAL; - } + printk(KERN_INFO "%s: found Cyclom 2X card at address 0x%lx.\n", + modname, (unsigned long) hw->dpmbase); /* Verify IRQ configuration options */ - if (!get_option_index(irq_opt, hw->irq)) { + if (!get_option_index(cycx_2x_irq_options, hw->irq)) { printk (KERN_ERR "%s: IRQ %d is illegal!\n", modname, hw->irq); return -EINVAL; } @@ -179,60 +172,35 @@ modname); return -EINVAL; } - else if (!get_option_index(dpmbase_opt, hw->dpmbase)) { + else if (!get_option_index(cyc2x_dpmbase_options, hw->dpmbase)) { printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n", modname, (unsigned long) hw->dpmbase); return -EINVAL; } hw->dpmsize = CYCX_WINDOWSIZE; - /* FIXME! Is this the only amount ever available? */ - hw->memory = 0x40000; - cycx_init(hw); + init_cyc2x(hw); printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n", modname, (unsigned long) hw->dpmbase); - printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n", - modname, (unsigned long) hw->memory / 1024); /* Load firmware. If loader fails then shut down adapter */ - err = cycx_load(hw, cfm, len); - if (err) cycx_down(hw); /* shutdown adapter */ - return err; + return load_cyc2x(hw, cfm, len); } -/* Shut down CYCX: disable shared memory access and interrupts, stop CPU,etc.*/ -EXPORT_SYMBOL(cycx_down); -int cycx_down (cycxhw_t *hw) -{ - return 0; /* FIXME: anything needed here? */ -} - /* Enable interrupt generation. */ EXPORT_SYMBOL(cycx_inten); -int cycx_inten (cycxhw_t *hw) +void cycx_inten (cycxhw_t *hw) { - switch (hw->type) { - case CYCX_2X: writeb (0, hw->dpmbase); break; - default: return -EINVAL; - } - - return 0; + cyc2x_writeb (0, hw->dpmbase); } /* Generate an interrupt to adapter's CPU. */ EXPORT_SYMBOL(cycx_intr); -int cycx_intr (cycxhw_t *hw) +void cycx_intr (cycxhw_t *hw) { - switch (hw->type) { - case CYCX_2X: - writew(0, hw->dpmbase + GEN_CYCX_INTR); - return 0; - default: return -EINVAL; - } - - return 0; + cyc2x_writew(0, hw->dpmbase + GEN_CYCX_INTR); } /* Execute Adapter Command. @@ -244,7 +212,7 @@ u16 i = 0; /* wait till addr content is zeroed */ - while (readw(addr) != 0) { + while (cyc2x_readw(addr)) { udelay(1000); if (++i > 50) return -1; } @@ -257,8 +225,8 @@ EXPORT_SYMBOL(cycx_peek); int cycx_peek (cycxhw_t *hw, u32 addr, void *buf, u32 len) { - if (len == 1) *(u8*)buf = readb (hw->dpmbase + addr); - else memcpy_fromio(buf, hw->dpmbase + addr, len); + if (len == 1) *(u8*)buf = cyc2x_readb (hw->dpmbase + addr); + else cyc2x_memcpy_fromio(buf, hw->dpmbase + addr, len); return 0; } @@ -268,38 +236,13 @@ EXPORT_SYMBOL(cycx_poke); int cycx_poke (cycxhw_t *hw, u32 addr, void *buf, u32 len) { - if (len == 1) writeb (*(u8*)buf, hw->dpmbase + addr); - else memcpy_toio(hw->dpmbase + addr, buf, len); + if (len == 1) cyc2x_writeb (*(u8*)buf, hw->dpmbase + addr); + else cyc2x_memcpy_toio(hw->dpmbase + addr, buf, len); return 0; } /* Hardware-Specific Functions */ -/* Detect adapter type. - * o if adapter type is specified then call detection routine for that adapter - * type. Otherwise call detection routines for every adapter types until - * adapter is detected. - * - * Notes: - * 1) Detection tests are destructive! Adapter will be left in shutdown state - * after the test. */ -static int cycx_detect (cycxhw_t *hw) -{ - int err = 0; - - if (!hw->dpmbase) return -EFAULT; - - switch (hw->type) { - case CYCX_2X: - if (!detect_cycx_2x(hw->dpmbase)) err = -ENODEV; - break; - default: - if (detect_cycx_2x(hw->dpmbase)) hw->type = CYCX_2X; - else err = -ENODEV; - } - - return err; -} /* Load Aux Routines */ /* Reset board hardware. @@ -309,10 +252,10 @@ int timeout = 0; for (; timeout < 3 ; timeout++) { - writew (TEST_PATTERN, addr + 0x10); + cyc2x_writew (TEST_PATTERN, addr + 0x10); - if (readw (addr + 0x10) == TEST_PATTERN) - if (readw (addr + 0x10) == TEST_PATTERN) return 1; + if (cyc2x_readw (addr + 0x10) == TEST_PATTERN) + if (cyc2x_readw (addr + 0x10) == TEST_PATTERN) return 1; delay_cycx(1); } @@ -320,17 +263,6 @@ return 0; } -/* Reset board hardware. */ -static int cycx_reset(cycxhw_t *hw) -{ - /* Reset board */ - switch (hw->type) { - case CYCX_2X: return reset_cycx_2x(hw->dpmbase); - } - - return -EINVAL; -} - /* Load reset code. */ static void reset_load(u32 addr, u8 *buffer, u32 cnt) { @@ -339,7 +271,7 @@ for ( i = 0 ; i < cnt ; i++) { for (j = 0 ; j < 50 ; j++); /* Delay - FIXME busy waiting... */ - writeb(*buffer++, pt_code++); + cyc2x_writeb(*buffer++, pt_code++); } } @@ -348,8 +280,8 @@ * o wait for reset code to copy it to right portion of memory */ static int buffer_load(u32 addr, u8 *buffer, u32 cnt) { - memcpy_toio(addr + DATA_OFFSET, buffer, cnt); - writew(GEN_BOOT_DAT, addr + CMD_OFFSET); + cyc2x_memcpy_toio(addr + DATA_OFFSET, buffer, cnt); + cyc2x_writew(GEN_BOOT_DAT, addr + CMD_OFFSET); return wait_cyc(addr); } @@ -357,14 +289,14 @@ static void cycx_start (u32 addr) { /* put in 0x30 offset the jump instruction to the code entry point */ - writeb(0xea, addr + 0x30); - writeb(0x00, addr + 0x31); - writeb(0xc4, addr + 0x32); - writeb(0x00, addr + 0x33); - writeb(0x00, addr + 0x34); + cyc2x_writeb(0xea, addr + 0x30); + cyc2x_writeb(0x00, addr + 0x31); + cyc2x_writeb(0xc4, addr + 0x32); + cyc2x_writeb(0x00, addr + 0x33); + cyc2x_writeb(0x00, addr + 0x34); /* cmd to start executing code */ - writew(GEN_START, addr + CMD_OFFSET); + cyc2x_writew(GEN_START, addr + CMD_OFFSET); } /* Load and boot reset code. */ @@ -372,15 +304,15 @@ { u32 pt_start = addr + START_OFFSET; - writeb(0xea, pt_start++); /* jmp to f000:3f00 */ - writeb(0x00, pt_start++); - writeb(0xfc, pt_start++); - writeb(0x00, pt_start++); - writeb(0xf0, pt_start); + cyc2x_writeb(0xea, pt_start++); /* jmp to f000:3f00 */ + cyc2x_writeb(0x00, pt_start++); + cyc2x_writeb(0xfc, pt_start++); + cyc2x_writeb(0x00, pt_start++); + cyc2x_writeb(0xf0, pt_start); reset_load(addr, code, len); /* 80186 was in hold, go */ - writeb(0, addr + START_CPU); + cyc2x_writeb(0, addr + START_CPU); delay_cycx(1); } @@ -391,14 +323,14 @@ u32 i; /* boot buffer lenght */ - writew(CFM_LOAD_BUFSZ, pt_boot_cmd + sizeof(u16)); - writew(GEN_DEFPAR, pt_boot_cmd); + cyc2x_writew(CFM_LOAD_BUFSZ, pt_boot_cmd + sizeof(u16)); + cyc2x_writew(GEN_DEFPAR, pt_boot_cmd); if (wait_cyc(addr) < 0) return 2; - writew(0, pt_boot_cmd + sizeof(u16)); - writew(0x4000, pt_boot_cmd + 2 * sizeof(u16)); - writew(GEN_SET_SEG, pt_boot_cmd); + cyc2x_writew(0, pt_boot_cmd + sizeof(u16)); + cyc2x_writew(0x4000, pt_boot_cmd + 2 * sizeof(u16)); + cyc2x_writew(GEN_SET_SEG, pt_boot_cmd); if (wait_cyc(addr) < 0) return 2; @@ -420,14 +352,14 @@ u32 i; /* boot buffer lenght */ - writew(CFM_LOAD_BUFSZ, pt_boot_cmd + sizeof(u16)); - writew(GEN_DEFPAR, pt_boot_cmd); + cyc2x_writew(CFM_LOAD_BUFSZ, pt_boot_cmd + sizeof(u16)); + cyc2x_writew(GEN_DEFPAR, pt_boot_cmd); if (wait_cyc(addr) == -1) return 2; - writew(0x0000, pt_boot_cmd + sizeof(u16)); - writew(0xc400, pt_boot_cmd + 2 * sizeof(u16)); - writew(GEN_SET_SEG, pt_boot_cmd); + cyc2x_writew(0x0000, pt_boot_cmd + sizeof(u16)); + cyc2x_writew(0xc400, pt_boot_cmd + 2 * sizeof(u16)); + cyc2x_writew(GEN_SET_SEG, pt_boot_cmd); if (wait_cyc(addr) == -1) return 1; @@ -440,22 +372,12 @@ return 0; } -/* Initialize CYCX hardware: setup memory window, IRQ, etc. */ -static int cycx_init (cycxhw_t *hw) -{ - switch (hw->type) { - case CYCX_2X: return init_cycx_2x(hw); - } - - return -EINVAL; -} - /* Load adapter from the memory image of the CYCX firmware module. * o verify firmware integrity and compatibility * o start adapter up */ -static int cycx_load (cycxhw_t *hw, cfm_t *cfm, u32 len) +static int load_cyc2x (cycxhw_t *hw, cfm_t *cfm, u32 len) { - int i, j, status; + int i, j; cycx_header_t *img_hdr; u8 *reset_image, *data_image, @@ -469,7 +391,7 @@ /* Verify firmware signature */ if (strcmp(cfm->signature, CFM_SIGNATURE)) { - printk(KERN_ERR "%s:cycx_load: not Cyclom-2X firmware!\n", + printk(KERN_ERR "%s:load_cyc2x: not Cyclom-2X firmware!\n", modname); return -EINVAL; } @@ -478,7 +400,7 @@ /* Verify firmware module format version */ if (cfm->version != CFM_VERSION) { - printk(KERN_ERR "%s:cycx_load: firmware format %u rejected! " + printk(KERN_ERR "%s:" __FUNCTION__ ": firmware format %u rejected! " "Expecting %u.\n", modname, cfm->version, CFM_VERSION); return -EINVAL; @@ -492,7 +414,7 @@ if (((len - sizeof(cfm_t) - 1) != cfm->info.codesize) || */ if (cksum != cfm->checksum) { - printk(KERN_ERR "%s:cycx_load: firmware corrupted!\n", modname); + printk(KERN_ERR "%s:" __FUNCTION__ ": firmware corrupted!\n", modname); printk(KERN_ERR " cdsize = 0x%x (expected 0x%lx)\n", len - sizeof(cfm_t) - 1, cfm->info.codesize); printk(KERN_ERR " chksum = 0x%x (expected 0x%x)\n", @@ -504,7 +426,7 @@ img_hdr = (cycx_header_t*)(((u8*) cfm) + sizeof(cfm_t) - 1); #ifdef FIRMWARE_DEBUG - printk(KERN_INFO "%s:cycx_load: image sizes\n", modname); + printk(KERN_INFO "%s:" __FUNCTION__ ": image sizes\n", modname); printk(KERN_INFO " reset=%lu\n", img_hdr->reset_size); printk(KERN_INFO " data=%lu\n", img_hdr->data_size); printk(KERN_INFO " code=%lu\n", img_hdr->code_size); @@ -521,20 +443,20 @@ for (i = 0 ; i < 5 ; i++) { /* Reset Cyclom hardware */ - if ((status = cycx_reset(hw)) != 0) { + if (!reset_cyc2x(hw->dpmbase)) { printk(KERN_ERR "%s: dpm problem or board not " - "found (%d).\n", modname, status); + "found.\n", modname); return -EINVAL; } /* Load reset.bin */ cycx_reset_boot(hw->dpmbase, reset_image, img_hdr->reset_size); /* reset is waiting for boot */ - writew(GEN_POWER_ON, pt_cycld); + cyc2x_writew(GEN_POWER_ON, pt_cycld); delay_cycx(1); for (j = 0 ; j < 3 ; j++) - if (!readw(pt_cycld)) goto reset_loaded; + if (!cyc2x_readw(pt_cycld)) goto reset_loaded; else delay_cycx(1); } @@ -542,18 +464,16 @@ return -EINVAL; reset_loaded: /* Load data.bin */ - if((status = cycx_data_boot(hw->dpmbase, data_image, - img_hdr->data_size)) != 0) { - printk(KERN_ERR "%s: cannot load data file (%d).\n", - modname, status); + if(cycx_data_boot(hw->dpmbase, data_image, + img_hdr->data_size)) { + printk(KERN_ERR "%s: cannot load data file.\n", modname); return -EINVAL; } /* Load code.bin */ - if((status = cycx_code_boot(hw->dpmbase, code_image, - img_hdr->code_size)) != 0) { - printk(KERN_ERR "%s: cannot load code file (%d).\n", - modname, status); + if(cycx_code_boot(hw->dpmbase, code_image, + img_hdr->code_size)) { + printk(KERN_ERR "%s: cannot load code file.\n", modname); return -EINVAL; } @@ -569,10 +489,7 @@ printk(KERN_INFO "%s: firmware loaded!\n", modname); /* enable interrupts */ - if (cycx_inten(hw)) { - printk(KERN_ERR "%s: adapter hardware failure!\n", modname); - return -EIO; - } + cycx_inten(hw); return 0; } @@ -586,13 +503,15 @@ static void cycx_bootcfg (cycxhw_t *hw) { /* use fixed buffers */ - writeb(FIXED_BUFFERS, hw->dpmbase + CONF_OFFSET); + cyc2x_writeb(FIXED_BUFFERS, hw->dpmbase + CONF_OFFSET); } /* Initialize CYCX_2X adapter. */ -static int init_cycx_2x (cycxhw_t *hw) +static int init_cyc2x (cycxhw_t *hw) { - if (!detect_cycx_2x(hw->dpmbase)) return -ENODEV; + if (!detect_cyc2x(hw->dpmbase)) + return -ENODEV; + return 0; } @@ -602,12 +521,12 @@ * Return 1 if detected o.k. or 0 if failed. * Note: This test is destructive! Adapter will be left in shutdown * state after the test. */ -static int detect_cycx_2x (u32 addr) +static int detect_cyc2x (u32 addr) { printk(KERN_INFO "%s: looking for a cyclom 2x at 0x%lX...\n", modname, (unsigned long) addr); - reset_cycx_2x(addr); + reset_cyc2x(addr); return memory_exists(addr); } @@ -622,11 +541,11 @@ } /* Reset adapter's CPU. */ -static int reset_cycx_2x (u32 addr) +static int reset_cyc2x (u32 addr) { - writeb (0, addr + RST_ENABLE); delay_cycx (2); - writeb (0, addr + RST_DISABLE); delay_cycx (2); - return memory_exists(addr) ? 0 : 1; + cyc2x_writeb (0, addr + RST_ENABLE); delay_cycx (2); + cyc2x_writeb (0, addr + RST_DISABLE); delay_cycx (2); + return memory_exists(addr); } /* Delay */ diff -u --recursive --new-file v2.3.24/linux/drivers/net/wan/cycx_main.c linux/drivers/net/wan/cycx_main.c --- v2.3.24/linux/drivers/net/wan/cycx_main.c Mon Oct 11 15:38:15 1999 +++ linux/drivers/net/wan/cycx_main.c Sun Oct 31 00:19:22 1999 @@ -1,5 +1,5 @@ /* -* cycx_main.c Cyclades Cyclom X Multiprotocol WAN Link Driver. Main module. +* cycx_main.c Cyclades Cyclom 2X WAN Link Driver. Main module. * * Author: Arnaldo Carvalho de Melo * @@ -40,7 +40,7 @@ #ifdef MODULE MODULE_AUTHOR("Arnaldo Carvalho de Melo"); -MODULE_DESCRIPTION("Cyclades Sync Cards Driver."); +MODULE_DESCRIPTION("Cyclom 2X Sync Card Driver."); #endif /* Defines & Macros */ @@ -73,7 +73,7 @@ /* private data */ static char drvname[] = "cyclomx"; -static char fullname[] = "CYCLOM X(tm) Multiprotocol Driver"; +static char fullname[] = "CYCLOM 2X(tm) Sync Card Driver"; static char copyright[] = "(c) 1998, 1999 Arnaldo Carvalho de Melo"; static int ncards = CONFIG_CYCLOMX_CARDS; static cycx_t *card_array = NULL; /* adapter data space */ @@ -214,7 +214,6 @@ card->hw.irq = (conf->irq == 9) ? 2 : conf->irq; card->hw.dpmbase = conf->maddr; card->hw.dpmsize = CYCX_WINDOWSIZE; - card->hw.type = conf->hw_opt[0]; card->hw.fwid = CFID_X25_2X; card->lock = SPIN_LOCK_UNLOCKED; #if LINUX_VERSION_CODE >= 0x020300 @@ -234,9 +233,7 @@ wandev->dma = wandev->ioport = 0; wandev->maddr = (unsigned long*)card->hw.dpmbase; wandev->msize = card->hw.dpmsize; - wandev->hw_opt[0] = card->hw.type; - wandev->hw_opt[1] = card->hw.pclk; - wandev->hw_opt[2] = card->hw.memory; + wandev->hw_opt[2] = 0; wandev->hw_opt[3] = card->hw.fwid; /* Protocol-specific initialization */ @@ -251,7 +248,6 @@ } if (err) { - cycx_down(&card->hw); free_irq(irq, card); return err; } @@ -278,7 +274,6 @@ card = wandev->private; wandev->state = WAN_UNCONFIGURED; - cycx_down(&card->hw); printk(KERN_INFO "%s: irq %d being freed!\n", wandev->name,wandev->irq); free_irq(wandev->irq, card); return 0; diff -u --recursive --new-file v2.3.24/linux/drivers/net/wan/cycx_x25.c linux/drivers/net/wan/cycx_x25.c --- v2.3.24/linux/drivers/net/wan/cycx_x25.c Fri Oct 15 15:25:13 1999 +++ linux/drivers/net/wan/cycx_x25.c Sun Oct 31 00:19:22 1999 @@ -1,5 +1,5 @@ /* -* cycx_x25.c CYCLOM X Multiprotocol WAN Link Driver. X.25 module. +* cycx_x25.c CYCLOM X WAN Link Driver. X.25 module. * * Author: Arnaldo Carvalho de Melo * Copyright: (c) 1998, 1999 Arnaldo Carvalho de Melo @@ -11,6 +11,13 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* 1999/10/27 acme use ARPHRD_HWX25 so that the x25 stack know +* that we have a X.25 stack implemented in +* firmware onboard +* 1999/10/18 acme support for X.25 sockets in if_send, +* beware: socket(AF_X25...) IS WORK IN PROGRESS, +* TCP/IP over X.25 via wanrouter not affected, +* working. * 1999/10/09 acme chan_disc renamed to chan_disconnect, * began adding support for X.25 sockets: * conf->protocol in new_if @@ -52,14 +59,14 @@ * memset is put into the unresolved symbols * instead of using the inline memset functions... * 1999/01/02 acme began chan_connect, chan_send, x25_send -* Dec 31, 1998 Arnaldo x25_configure +* 1998/12/31 acme x25_configure * this code can be compiled as non module -* Dec 27, 1998 Arnaldo code cleanup +* 1998/12/27 acme code cleanup * IPX code wiped out! let's decrease code * complexity for now, remember: I'm learning! :) * bps_to_speed_code OK -* Dec 26, 1998 Arnaldo Minimal debug code cleanup -* Aug 08, 1998 Arnaldo Initial version. +* 1998/12/26 acme Minimal debug code cleanup +* 1998/08/08 acme Initial version. */ #define CYCLOMX_X25_DEBUG 1 @@ -71,7 +78,7 @@ #include /* kmalloc(), kfree() */ #include /* WAN router definitions */ #include /* htons(), etc. */ -#include /* ARPHRD_X25 */ +#include /* ARPHRD_HWX25 */ #include /* CYCLOM X common user API definitions */ #include /* X.25 firmware API definitions */ @@ -137,10 +144,11 @@ x25_disconnect_response (cycx_t *card, u8 link, u8 lcn); /* channel functions */ -int chan_connect (struct net_device *dev), - chan_send (struct net_device *dev, struct sk_buff *skb); +static int chan_connect (struct net_device *dev), + chan_send (struct net_device *dev, struct sk_buff *skb); -static void chan_disconnect (struct net_device *dev); +static void chan_disconnect (struct net_device *dev), + chan_x25_send_event(struct net_device *dev, u8 event); /* Miscellaneous functions */ static void set_chan_state (struct net_device *dev, u8 state), @@ -288,11 +296,11 @@ card->wandev.interface = conf->interface; card->wandev.clocking = conf->clocking; card->wandev.station = conf->station; - card->isr = &cyx_isr; + card->isr = cyx_isr; card->exec = NULL; - card->wandev.update = &update; - card->wandev.new_if = &new_if; - card->wandev.del_if = &del_if; + card->wandev.update = update; + card->wandev.new_if = new_if; + card->wandev.del_if = del_if; card->wandev.state = WAN_DISCONNECTED; return 0; } @@ -328,7 +336,7 @@ x25_channel_t *chan; int err = 0; - if (conf->name[0] == '\0' || strlen(conf->name) > WAN_IFNAME_SZ) { + if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) { printk(KERN_INFO "%s: invalid interface name!\n",card->devname); return -EINVAL; } @@ -403,7 +411,7 @@ /* prepare network device data space for registration */ dev->name = chan->name; - dev->init = &if_init; + dev->init = if_init; dev->priv = chan; return 0; } @@ -411,11 +419,6 @@ /* Delete logical channel. */ static int del_if (wan_device_t *wandev, struct net_device *dev) { - if (!dev) { - printk(KERN_ERR "cycx_x25:del_if:dev == NULL!\n"); - return 0; - } - if (dev->priv) { x25_channel_t *chan = dev->priv; @@ -447,16 +450,16 @@ wan_device_t *wandev = &card->wandev; /* Initialize device driver entry points */ - dev->open = &if_open; - dev->stop = &if_close; - dev->hard_header = &if_header; - dev->rebuild_header = &if_rebuild_hdr; - dev->hard_start_xmit = &if_send; - dev->get_stats = &if_stats; + dev->open = if_open; + dev->stop = if_close; + dev->hard_header = if_header; + dev->rebuild_header = if_rebuild_hdr; + dev->hard_start_xmit = if_send; + dev->get_stats = if_stats; /* Initialize media-specific parameters */ dev->mtu = X25_CHAN_MTU; - dev->type = ARPHRD_X25; /* ARP h/w type */ + dev->type = ARPHRD_HWX25; /* ARP h/w type */ dev->hard_header_len = 0; /* media header length */ dev->addr_len = 0; /* hardware address length */ @@ -577,27 +580,57 @@ "%s: unsupported Ethertype 0x%04X on interface %s!\n", card->devname, skb->protocol, dev->name); ++chan->ifstats.tx_errors; - } else switch (chan->state) { - case WAN_DISCONNECTED: - if (chan_connect(dev)) { + } else if (chan->protocol == ETH_P_IP) { + switch (chan->state) { + case WAN_DISCONNECTED: + if (chan_connect(dev)) { + dev->tbusy = 1; + return -EBUSY; + } + /* fall thru */ + case WAN_CONNECTED: + reset_timer(dev); + dev->trans_start = jiffies; dev->tbusy = 1; - return -EBUSY; - } - /* fall thru */ - case WAN_CONNECTED: - reset_timer(dev); - dev->trans_start = jiffies; - dev->tbusy = 1; - if (chan_send(dev, skb)) { - return -EBUSY; - } - break; - default: - ++chan->ifstats.tx_dropped; - ++card->wandev.stats.tx_dropped; + if (chan_send(dev, skb)) + return -EBUSY; + + break; + default: + ++chan->ifstats.tx_dropped; + ++card->wandev.stats.tx_dropped; + } + } else { /* chan->protocol == ETH_P_X25 */ + switch (skb->data[0]) { + case 0: break; + case 1: /* Connect request */ + chan_connect(dev); + goto free_packet; + case 2: /* Disconnect request */ + chan_disconnect(dev); + goto free_packet; + default: + printk(KERN_INFO + "%s: unknown %d x25-iface request on %s!\n", + card->devname, skb->data[0], dev->name); + ++chan->ifstats.tx_errors; + goto free_packet; + } + + skb_pull(skb, 1); /* Remove control byte */ + reset_timer(dev); + dev->trans_start = jiffies; + dev->tbusy = 1; + + if (chan_send(dev, skb)) { + /* prepare for future retransmissions */ + skb_push(skb, 1); + return -EBUSY; + } } +free_packet: dev_kfree_skb(skb); return 0; } @@ -733,7 +766,8 @@ /* Allocate new socket buffer */ int bufsize = bitm ? dev->mtu : pktlen; - if ((skb = dev_alloc_skb(bufsize + + if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) + + bufsize + dev->hard_header_len)) == NULL) { printk(KERN_INFO "%s: no socket buffers available!\n", card->devname); @@ -742,6 +776,10 @@ return; } + if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */ + /* 0 = data packet (dev_alloc_skb zeroed skb->data) */ + skb_put(skb, 1); + skb->dev = dev; skb->protocol = htons(chan->protocol); chan->rx_skb = skb; @@ -770,12 +808,11 @@ dev->last_rx = jiffies; /* timestamp */ chan->rx_skb = NULL; /* dequeue packet */ - skb->protocol = htons(chan->protocol); - skb->dev = dev; - skb->mac.raw = skb->data; - netif_rx(skb); ++chan->ifstats.rx_packets; chan->ifstats.rx_bytes += skb->len; + + skb->mac.raw = skb->data; + netif_rx(skb); } /* Connect interrupt handler. */ @@ -1236,7 +1273,7 @@ * Return: 0 connected * >0 connection in progress * <0 failure */ -int chan_connect (struct net_device *dev) +static int chan_connect (struct net_device *dev) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -1307,6 +1344,10 @@ *(u16*)dev->dev_addr = htons(chan->lcn); dev->tbusy = 0; reset_timer(dev); + + if (chan->protocol == ETH_P_X25) + chan_x25_send_event(dev, 1); + break; case WAN_CONNECTING: @@ -1329,6 +1370,10 @@ *(unsigned short*)dev->dev_addr = 0; chan->lcn = 0; } + + if (chan->protocol == ETH_P_X25) + chan_x25_send_event(dev, 2); + dev->tbusy = 0; break; } @@ -1352,7 +1397,7 @@ * the packet into 'complete sequence' using M-bit. * 2. When transmission is complete, an event notification should be issued * to the router. */ -int chan_send (struct net_device *dev, struct sk_buff *skb) +static int chan_send (struct net_device *dev, struct sk_buff *skb) { x25_channel_t *chan = dev->priv; cycx_t *card = chan->card; @@ -1375,6 +1420,29 @@ ++chan->ifstats.tx_packets; chan->ifstats.tx_bytes += len; return 0; +} + +/* Send event (connection, disconnection, etc) to X.25 socket layer */ + +static void chan_x25_send_event(struct net_device *dev, u8 event) +{ + struct sk_buff *skb; + unsigned char *ptr; + + if ((skb = dev_alloc_skb(1)) == NULL) { + printk(KERN_ERR __FUNCTION__ ": out of memory\n"); + return; + } + + ptr = skb_put(skb, 1); + *ptr = event; + + skb->dev = dev; + skb->protocol = htons(ETH_P_X25); + skb->mac.raw = skb->data; + skb->pkt_type = PACKET_HOST; + + netif_rx(skb); } /* Convert line speed in bps to a number used by cyclom 2x code. */ diff -u --recursive --new-file v2.3.24/linux/drivers/net/wd.c linux/drivers/net/wd.c --- v2.3.24/linux/drivers/net/wd.c Wed Aug 18 11:36:43 1999 +++ linux/drivers/net/wd.c Fri Oct 29 13:20:35 1999 @@ -367,9 +367,9 @@ #ifdef notdef /* Officially this is what we are doing, but the readl() is faster */ - memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); + isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); #else - ((unsigned int*)hdr)[0] = readl(hdr_start); + ((unsigned int*)hdr)[0] = isa_readl(hdr_start); #endif } @@ -387,12 +387,12 @@ if (xfer_start + count > dev->rmem_end) { /* We must wrap the input move. */ int semi_count = dev->rmem_end - xfer_start; - memcpy_fromio(skb->data, xfer_start, semi_count); + isa_memcpy_fromio(skb->data, xfer_start, semi_count); count -= semi_count; - memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); + isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } else { /* Packet is in one chunk -- we can copy + cksum. */ - eth_io_copy_and_sum(skb, xfer_start, count, 0); + isa_eth_io_copy_and_sum(skb, xfer_start, count, 0); } /* Turn off 16 bit access so that reboot works. ISA brain-damage */ @@ -411,10 +411,10 @@ if (ei_status.word16) { /* Turn on and off 16 bit access so that reboot works. */ outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5); - memcpy_toio(shmem, buf, count); + isa_memcpy_toio(shmem, buf, count); outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5); } else - memcpy_toio(shmem, buf, count); + isa_memcpy_toio(shmem, buf, count); } diff -u --recursive --new-file v2.3.24/linux/drivers/nubus/nubus.c linux/drivers/nubus/nubus.c --- v2.3.24/linux/drivers/nubus/nubus.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/nubus/nubus.c Thu Oct 28 14:34:46 1999 @@ -963,37 +963,39 @@ return strlen(ptr); } -/* We're going to have to be a bit more sophisticated about this, I - think, because it doesn't really seem to work right when you do a - full listing of boards and devices */ -int get_nubus_list(char *buf) +static int nubus_read_proc(char *buf, char **start, off_t off, + int count, int *eof, void *data) { - int nprinted, len, size; - struct nubus_board* board; -#define MSG "\nwarning: page-size limit reached!\n" - - /* reserve same for truncation warning message: */ - size = PAGE_SIZE - (strlen(MSG) + 1); - len = sprintf(buf, "Nubus boards found:\n"); + int nprinted, len, begin = 0; + int slot; + len = sprintf(buf, "Nubus devices found:\n"); /* Walk the list of NuBus boards */ for (board = nubus_boards; board != NULL; board = board->next) { nprinted = sprint_nubus_board(board, buf + len, size - len); - if (nprinted < 0) { - return len + sprintf(buf + len, MSG); - } + if (nprinted < 0) + break; len += nprinted; + if (len+begin < off) { + begin += len; + len = 0; + } + if (len+begin >= off+count) + break; } + if (slot==16 || len+begin < off) + *eof = 1; + off -= begin; + *strat = buf + off; + len -= off; + if (len>count) + len = count; + if (len<0) + len = 0; return len; } - -static struct proc_dir_entry proc_old_nubus = { - PROC_NUBUS, 5, "nubus", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations -}; -#endif /* CONFIG_PROC_FS */ +#endif void __init nubus_scan_bus(void) { @@ -1034,7 +1036,7 @@ nubus_scan_bus(); #ifdef CONFIG_PROC_FS - proc_register(&proc_root, &proc_old_nubus); + create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL); nubus_proc_init(); #endif } diff -u --recursive --new-file v2.3.24/linux/drivers/nubus/proc.c linux/drivers/nubus/proc.c --- v2.3.24/linux/drivers/nubus/proc.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/nubus/proc.c Thu Oct 28 14:34:46 1999 @@ -60,13 +60,6 @@ return (count > cnt) ? cnt : count; } -static struct proc_dir_entry proc_nubus_devices = { - PROC_BUS_NUBUS_DEVICES, 7, "devices", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - get_nubus_dev_info -}; - static struct proc_dir_entry *proc_bus_nubus_dir; static void nubus_proc_subdir(struct nubus_dev* dev, @@ -178,6 +171,7 @@ if (!MACH_IS_MAC) return; proc_bus_nubus_dir = create_proc_entry("nubus", S_IFDIR, proc_bus); - proc_register(proc_bus_nubus_dir, &proc_nubus_devices); + create_proc_info_entry("devices", 0, proc_bus_nubus_dir, + get_nubus_dev_info); proc_bus_nubus_add_devices(); } diff -u --recursive --new-file v2.3.24/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c --- v2.3.24/linux/drivers/parport/parport_pc.c Fri Oct 15 15:25:14 1999 +++ linux/drivers/parport/parport_pc.c Fri Oct 29 11:05:08 1999 @@ -1782,6 +1782,9 @@ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_B, PCI_ANY_ID, PCI_ANY_ID, 1, { { 0, -1 }, } }, + { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_BOCA_IOPPAR, + PCI_ANY_ID, PCI_ANY_ID, + 1, { { 0, -1 }, } }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_SUBVENDOR_ID_EXSYS, PCI_SUBDEVICE_ID_EXSYS_4014, 2, { { 4, -1 }, { 5, -1 }, } }, diff -u --recursive --new-file v2.3.24/linux/drivers/pci/devlist.h linux/drivers/pci/devlist.h --- v2.3.24/linux/drivers/pci/devlist.h Fri Oct 15 15:25:14 1999 +++ linux/drivers/pci/devlist.h Fri Oct 29 11:05:08 1999 @@ -844,6 +844,13 @@ DEVICE( MOTOROLA_OOPS, MOTOROLA_FALCON,"Falcon") ENDVENDOR() +VENDOR( LAVA, "Lava Computer MFG" ) + DEVICE( LAVA, LAVA_PARALLEL, "Lava Parallel") + DEVICE( LAVA, LAVA_DUAL_PAR_A,"Lava Dual Parallel (A)") + DEVICE( LAVA, LAVA_DUAL_PAR_B,"Lava Dual Parallel (B)") + DEVICE( LAVA, LAVA_BOCA_IOPPAR,"BOCA Research IOPPAR") +ENDVENDOR() + VENDOR( SYMPHONY, "Symphony" ) DEVICE( SYMPHONY, SYMPHONY_101, "82C101") ENDVENDOR() diff -u --recursive --new-file v2.3.24/linux/drivers/pci/helper.c linux/drivers/pci/helper.c --- v2.3.24/linux/drivers/pci/helper.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/pci/helper.c Thu Oct 28 17:32:25 1999 @@ -13,11 +13,12 @@ #include -int pci_simple_probe (struct pci_simple_probe_entry *list, size_t match_limit, - pci_simple_probe_callback cb, void *drvr_data) +int pci_simple_probe (const struct pci_simple_probe_entry *list, + size_t match_limit, pci_simple_probe_callback cb, + void *drvr_data) { struct pci_dev *dev; - struct pci_simple_probe_entry *ent; + const struct pci_simple_probe_entry *ent; size_t matches = 0; unsigned short vendor, device; int rc; diff -u --recursive --new-file v2.3.24/linux/drivers/pci/pcisyms.c linux/drivers/pci/pcisyms.c --- v2.3.24/linux/drivers/pci/pcisyms.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/pci/pcisyms.c Thu Oct 28 16:18:46 1999 @@ -24,6 +24,7 @@ EXPORT_SYMBOL(pci_find_device); EXPORT_SYMBOL(pci_find_slot); EXPORT_SYMBOL(pci_set_master); +EXPORT_SYMBOL(pci_simple_probe); #ifdef CONFIG_PROC_FS EXPORT_SYMBOL(pci_proc_attach_device); EXPORT_SYMBOL(pci_proc_detach_device); diff -u --recursive --new-file v2.3.24/linux/drivers/pci/proc.c linux/drivers/pci/proc.c --- v2.3.24/linux/drivers/pci/proc.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/pci/proc.c Thu Oct 28 14:34:46 1999 @@ -271,13 +271,6 @@ return (count > cnt) ? cnt : count; } -static struct proc_dir_entry proc_pci_devices = { - PROC_BUS_PCI_DEVICES, 7, "devices", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - get_pci_dev_info -}; - static struct proc_dir_entry *proc_bus_pci_dir; int pci_proc_attach_device(struct pci_dev *dev) @@ -498,37 +491,39 @@ return len; } - -static struct proc_dir_entry proc_old_pci = { - PROC_PCI, 3, "pci", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations -}; - /* * Return list of PCI devices as a character string for /proc/pci. * BUF is a buffer that is PAGE_SIZE bytes long. */ -int get_pci_list(char *buf) +static int pci_read_proc(char *buf, char **start, off_t off, + int count, int *eof, void *data) { - int nprinted, len, size; + int nprinted, len, begin = 0; struct pci_dev *dev; -# define MSG "\nwarning: page-size limit reached!\n" - /* reserve same for truncation warning message: */ - size = PAGE_SIZE - (strlen(MSG) + 1); len = sprintf(buf, "PCI devices found:\n"); for (dev = pci_devices; dev; dev = dev->next) { - nprinted = sprint_dev_config(dev, buf + len, size - len); - if (nprinted < 0) { - len += sprintf(buf + len, MSG); - proc_old_pci.size = len; - return len; - } + nprinted = sprint_dev_config(dev, buf + len, count - len); + if (nprinted < 0) + break; len += nprinted; + if (len+begin < off) { + begin += len; + len = 0; + } + if (len+begin >= off+count) + break; } - proc_old_pci.size = len; + if (!dev || len+begin < off) + *eof = 1; + off -= begin; + *start = buf + off; + len -= off; + if (len>count) + len = count; + if (len<0) + len = 0; return len; } @@ -536,9 +531,10 @@ { if (pci_present()) { proc_bus_pci_dir = create_proc_entry("pci", S_IFDIR, proc_bus); - proc_register(proc_bus_pci_dir, &proc_pci_devices); + create_proc_info_entry("devices",0, proc_bus_pci_dir, + get_pci_dev_info); proc_bus_pci_add(pci_root); - proc_register(&proc_root, &proc_old_pci); + create_proc_read_entry("pci", 0, NULL, pci_read_proc, NULL); } return 0; } diff -u --recursive --new-file v2.3.24/linux/drivers/sbus/audio/Config.in linux/drivers/sbus/audio/Config.in --- v2.3.24/linux/drivers/sbus/audio/Config.in Wed Nov 18 09:06:05 1998 +++ linux/drivers/sbus/audio/Config.in Mon Nov 1 10:31:28 1999 @@ -4,11 +4,11 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - comment 'Linux/SPARC audio subsystem (EXPERIMENTAL)' + comment 'Linux/SPARC audio subsystem (EXPERIMENTAL)' - tristate 'Audio support (EXPERIMENTAL)' CONFIG_SPARCAUDIO - dep_tristate ' AMD7930 Lowlevel Driver' CONFIG_SPARCAUDIO_AMD7930 $CONFIG_SPARCAUDIO - dep_tristate ' CS4231 Lowlevel Driver' CONFIG_SPARCAUDIO_CS4231 $CONFIG_SPARCAUDIO - dep_tristate ' DBRI Lowlevel Driver' CONFIG_SPARCAUDIO_DBRI $CONFIG_SPARCAUDIO - dep_tristate ' Dummy Lowlevel Driver' CONFIG_SPARCAUDIO_DUMMY $CONFIG_SPARCAUDIO + tristate 'Audio support (EXPERIMENTAL)' CONFIG_SPARCAUDIO + dep_tristate ' AMD7930 Lowlevel Driver' CONFIG_SPARCAUDIO_AMD7930 $CONFIG_SPARCAUDIO + dep_tristate ' CS4231 Lowlevel Driver' CONFIG_SPARCAUDIO_CS4231 $CONFIG_SPARCAUDIO + dep_tristate ' DBRI Lowlevel Driver' CONFIG_SPARCAUDIO_DBRI $CONFIG_SPARCAUDIO + dep_tristate ' Dummy Lowlevel Driver' CONFIG_SPARCAUDIO_DUMMY $CONFIG_SPARCAUDIO fi diff -u --recursive --new-file v2.3.24/linux/drivers/sbus/char/Config.in linux/drivers/sbus/char/Config.in --- v2.3.24/linux/drivers/sbus/char/Config.in Fri Sep 10 23:57:30 1999 +++ linux/drivers/sbus/char/Config.in Mon Nov 1 10:31:28 1999 @@ -2,21 +2,21 @@ tristate '/dev/openprom device support' CONFIG_SUN_OPENPROMIO tristate 'Mostek real time clock support' CONFIG_SUN_MOSTEK_RTC if [ "$ARCH" = "sparc64" ]; then - if [ "$CONFIG_PCI" = "y" ]; then - tristate 'Siemens SAB82532 serial support' CONFIG_SAB82532 - fi - tristate 'OBP Flash Device support' CONFIG_OBP_FLASH + if [ "$CONFIG_PCI" = "y" ]; then + tristate 'Siemens SAB82532 serial support' CONFIG_SAB82532 + fi + tristate 'OBP Flash Device support' CONFIG_OBP_FLASH fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Bidirectional parallel port support (obsolete)' CONFIG_SUN_BPP - tristate 'Videopix Frame Grabber (EXPERIMENTAL)' CONFIG_SUN_VIDEOPIX - tristate 'Aurora Multiboard 1600se (EXPERIMENTAL)' CONFIG_SUN_AURORA - tristate 'Tadpole TS102 Microcontroller support' CONFIG_TADPOLE_TS102_UCTRL + tristate 'Bidirectional parallel port support (OBSOLETE)' CONFIG_SUN_BPP + tristate 'Videopix Frame Grabber (EXPERIMENTAL)' CONFIG_SUN_VIDEOPIX + tristate 'Aurora Multiboard 1600se (EXPERIMENTAL)' CONFIG_SUN_AURORA + tristate 'Tadpole TS102 Microcontroller support (EXPERIMENTAL)' CONFIG_TADPOLE_TS102_UCTRL - # XXX Why don't we do "source drivers/char/Config.in" somewhere? - if [ "$CONFIG_PCI" = "y" ]; then - define_bool CONFIG_APM_RTC_IS_GMT y # no shit - bool 'PC-style RTC' CONFIG_RTC - fi + # XXX Why don't we do "source drivers/char/Config.in" somewhere? + if [ "$CONFIG_PCI" = "y" ]; then + define_bool CONFIG_APM_RTC_IS_GMT y # no shit + bool 'PC-style RTC' CONFIG_RTC + fi fi diff -u --recursive --new-file v2.3.24/linux/drivers/sbus/char/flash.c linux/drivers/sbus/char/flash.c --- v2.3.24/linux/drivers/sbus/char/flash.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/sbus/char/flash.c Fri Oct 29 11:00:57 1999 @@ -37,9 +37,6 @@ unsigned long addr; unsigned long size; - if (vma->vm_offset & ~(PAGE_MASK)) - return -ENXIO; - if (flash.read_base == flash.write_base) { addr = flash.read_base; size = flash.read_size; diff -u --recursive --new-file v2.3.24/linux/drivers/scsi/53c8xx_d.h linux/drivers/scsi/53c8xx_d.h --- v2.3.24/linux/drivers/scsi/53c8xx_d.h Mon May 11 12:49:02 1998 +++ linux/drivers/scsi/53c8xx_d.h Fri Oct 29 10:53:32 1999 @@ -1,4 +1,4 @@ -u32 SCRIPT[] = { +static u32 SCRIPT[] = { /* @@ -2179,40 +2179,40 @@ }; #define A_NCR53c7xx_msg_abort 0x00000000 -u32 A_NCR53c7xx_msg_abort_used[] = { +static u32 A_NCR53c7xx_msg_abort_used[] __attribute((unused)) = { 0x00000249, }; #define A_NCR53c7xx_msg_reject 0x00000000 -u32 A_NCR53c7xx_msg_reject_used[] = { +static u32 A_NCR53c7xx_msg_reject_used[] __attribute((unused)) = { 0x00000172, }; #define A_NCR53c7xx_sink 0x00000000 -u32 A_NCR53c7xx_sink_used[] = { +static u32 A_NCR53c7xx_sink_used[] __attribute((unused)) = { 0x00000233, 0x00000239, 0x0000023f, }; #define A_NCR53c7xx_zero 0x00000000 -u32 A_NCR53c7xx_zero_used[] = { +static u32 A_NCR53c7xx_zero_used[] __attribute((unused)) = { 0x0000022f, 0x00000245, }; #define A_NOP_insn 0x00000000 -u32 A_NOP_insn_used[] = { +static u32 A_NOP_insn_used[] __attribute((unused)) = { 0x00000010, }; #define A_addr_reconnect_dsa_head 0x00000000 -u32 A_addr_reconnect_dsa_head_used[] = { +static u32 A_addr_reconnect_dsa_head_used[] __attribute((unused)) = { 0x000001a7, }; #define A_addr_scratch 0x00000000 -u32 A_addr_scratch_used[] = { +static u32 A_addr_scratch_used[] __attribute((unused)) = { 0x00000004, 0x0000001b, 0x00000046, @@ -2227,13 +2227,13 @@ }; #define A_addr_temp 0x00000000 -u32 A_addr_temp_used[] = { +static u32 A_addr_temp_used[] __attribute((unused)) = { 0x00000025, 0x00000034, }; #define A_dmode_memory_to_memory 0x00000000 -u32 A_dmode_memory_to_memory_used[] = { +static u32 A_dmode_memory_to_memory_used[] __attribute((unused)) = { 0x00000005, 0x0000001c, 0x00000027, @@ -2251,7 +2251,7 @@ }; #define A_dmode_memory_to_ncr 0x00000000 -u32 A_dmode_memory_to_ncr_used[] = { +static u32 A_dmode_memory_to_ncr_used[] __attribute((unused)) = { 0x00000000, 0x00000017, 0x00000030, @@ -2260,7 +2260,7 @@ }; #define A_dmode_ncr_to_memory 0x00000000 -u32 A_dmode_ncr_to_memory_used[] = { +static u32 A_dmode_ncr_to_memory_used[] __attribute((unused)) = { 0x00000022, 0x00000064, 0x00000070, @@ -2272,161 +2272,161 @@ }; #define A_dsa_check_reselect 0x00000000 -u32 A_dsa_check_reselect_used[] = { +static u32 A_dsa_check_reselect_used[] __attribute((unused)) = { 0x000001bd, }; #define A_dsa_cmdout 0x00000048 -u32 A_dsa_cmdout_used[] = { +static u32 A_dsa_cmdout_used[] __attribute((unused)) = { 0x00000094, }; #define A_dsa_cmnd 0x00000038 -u32 A_dsa_cmnd_used[] = { +static u32 A_dsa_cmnd_used[] __attribute((unused)) = { }; #define A_dsa_datain 0x00000054 -u32 A_dsa_datain_used[] = { +static u32 A_dsa_datain_used[] __attribute((unused)) = { 0x000000bb, }; #define A_dsa_dataout 0x00000050 -u32 A_dsa_dataout_used[] = { +static u32 A_dsa_dataout_used[] __attribute((unused)) = { 0x000000a5, }; #define A_dsa_end 0x00000070 -u32 A_dsa_end_used[] = { +static u32 A_dsa_end_used[] __attribute((unused)) = { }; #define A_dsa_fields_start 0x00000000 -u32 A_dsa_fields_start_used[] = { +static u32 A_dsa_fields_start_used[] __attribute((unused)) = { }; #define A_dsa_msgin 0x00000058 -u32 A_dsa_msgin_used[] = { +static u32 A_dsa_msgin_used[] __attribute((unused)) = { 0x00000188, }; #define A_dsa_msgout 0x00000040 -u32 A_dsa_msgout_used[] = { +static u32 A_dsa_msgout_used[] __attribute((unused)) = { 0x00000086, }; #define A_dsa_msgout_other 0x00000068 -u32 A_dsa_msgout_other_used[] = { +static u32 A_dsa_msgout_other_used[] __attribute((unused)) = { 0x00000180, }; #define A_dsa_next 0x00000030 -u32 A_dsa_next_used[] = { +static u32 A_dsa_next_used[] __attribute((unused)) = { 0x0000005c, }; #define A_dsa_restore_pointers 0x00000000 -u32 A_dsa_restore_pointers_used[] = { +static u32 A_dsa_restore_pointers_used[] __attribute((unused)) = { 0x0000012e, }; #define A_dsa_save_data_pointer 0x00000000 -u32 A_dsa_save_data_pointer_used[] = { +static u32 A_dsa_save_data_pointer_used[] __attribute((unused)) = { 0x00000115, }; #define A_dsa_select 0x0000003c -u32 A_dsa_select_used[] = { +static u32 A_dsa_select_used[] __attribute((unused)) = { 0x00000081, }; #define A_dsa_status 0x00000060 -u32 A_dsa_status_used[] = { +static u32 A_dsa_status_used[] __attribute((unused)) = { 0x00000184, }; #define A_dsa_temp_addr_array_value 0x00000000 -u32 A_dsa_temp_addr_array_value_used[] = { +static u32 A_dsa_temp_addr_array_value_used[] __attribute((unused)) = { }; #define A_dsa_temp_addr_dsa_value 0x00000000 -u32 A_dsa_temp_addr_dsa_value_used[] = { +static u32 A_dsa_temp_addr_dsa_value_used[] __attribute((unused)) = { 0x00000003, }; #define A_dsa_temp_addr_new_value 0x00000000 -u32 A_dsa_temp_addr_new_value_used[] = { +static u32 A_dsa_temp_addr_new_value_used[] __attribute((unused)) = { }; #define A_dsa_temp_addr_next 0x00000000 -u32 A_dsa_temp_addr_next_used[] = { +static u32 A_dsa_temp_addr_next_used[] __attribute((unused)) = { 0x00000015, 0x0000004e, }; #define A_dsa_temp_addr_residual 0x00000000 -u32 A_dsa_temp_addr_residual_used[] = { +static u32 A_dsa_temp_addr_residual_used[] __attribute((unused)) = { 0x0000002a, 0x00000039, }; #define A_dsa_temp_addr_saved_pointer 0x00000000 -u32 A_dsa_temp_addr_saved_pointer_used[] = { +static u32 A_dsa_temp_addr_saved_pointer_used[] __attribute((unused)) = { 0x00000026, 0x00000033, }; #define A_dsa_temp_addr_saved_residual 0x00000000 -u32 A_dsa_temp_addr_saved_residual_used[] = { +static u32 A_dsa_temp_addr_saved_residual_used[] __attribute((unused)) = { 0x0000002b, 0x00000038, }; #define A_dsa_temp_lun 0x00000000 -u32 A_dsa_temp_lun_used[] = { +static u32 A_dsa_temp_lun_used[] __attribute((unused)) = { 0x0000004b, }; #define A_dsa_temp_next 0x00000000 -u32 A_dsa_temp_next_used[] = { +static u32 A_dsa_temp_next_used[] __attribute((unused)) = { 0x0000001a, }; #define A_dsa_temp_sync 0x00000000 -u32 A_dsa_temp_sync_used[] = { +static u32 A_dsa_temp_sync_used[] __attribute((unused)) = { 0x00000053, }; #define A_dsa_temp_target 0x00000000 -u32 A_dsa_temp_target_used[] = { +static u32 A_dsa_temp_target_used[] __attribute((unused)) = { 0x00000040, }; #define A_int_debug_break 0x03000000 -u32 A_int_debug_break_used[] = { +static u32 A_int_debug_break_used[] __attribute((unused)) = { 0x00000217, }; #define A_int_debug_panic 0x030b0000 -u32 A_int_debug_panic_used[] = { +static u32 A_int_debug_panic_used[] __attribute((unused)) = { 0x000001e8, 0x000001f8, }; #define A_int_err_check_condition 0x00030000 -u32 A_int_err_check_condition_used[] = { +static u32 A_int_err_check_condition_used[] __attribute((unused)) = { 0x00000194, }; #define A_int_err_no_phase 0x00040000 -u32 A_int_err_no_phase_used[] = { +static u32 A_int_err_no_phase_used[] __attribute((unused)) = { }; #define A_int_err_selected 0x00010000 -u32 A_int_err_selected_used[] = { +static u32 A_int_err_selected_used[] __attribute((unused)) = { 0x000001da, }; #define A_int_err_unexpected_phase 0x00000000 -u32 A_int_err_unexpected_phase_used[] = { +static u32 A_int_err_unexpected_phase_used[] __attribute((unused)) = { 0x0000008c, 0x00000092, 0x0000009a, @@ -2444,67 +2444,67 @@ }; #define A_int_err_unexpected_reselect 0x00020000 -u32 A_int_err_unexpected_reselect_used[] = { +static u32 A_int_err_unexpected_reselect_used[] __attribute((unused)) = { 0x000001ba, }; #define A_int_msg_1 0x01020000 -u32 A_int_msg_1_used[] = { +static u32 A_int_msg_1_used[] __attribute((unused)) = { 0x0000010e, 0x00000110, }; #define A_int_msg_sdtr 0x01010000 -u32 A_int_msg_sdtr_used[] = { +static u32 A_int_msg_sdtr_used[] __attribute((unused)) = { 0x0000016c, }; #define A_int_msg_wdtr 0x01000000 -u32 A_int_msg_wdtr_used[] = { +static u32 A_int_msg_wdtr_used[] __attribute((unused)) = { 0x00000160, }; #define A_int_norm_aborted 0x02040000 -u32 A_int_norm_aborted_used[] = { +static u32 A_int_norm_aborted_used[] __attribute((unused)) = { 0x0000024d, }; #define A_int_norm_command_complete 0x02020000 -u32 A_int_norm_command_complete_used[] = { +static u32 A_int_norm_command_complete_used[] __attribute((unused)) = { }; #define A_int_norm_disconnected 0x02030000 -u32 A_int_norm_disconnected_used[] = { +static u32 A_int_norm_disconnected_used[] __attribute((unused)) = { }; #define A_int_norm_reselect_complete 0x02010000 -u32 A_int_norm_reselect_complete_used[] = { +static u32 A_int_norm_reselect_complete_used[] __attribute((unused)) = { }; #define A_int_norm_reset 0x02050000 -u32 A_int_norm_reset_used[] = { +static u32 A_int_norm_reset_used[] __attribute((unused)) = { }; #define A_int_norm_select_complete 0x02000000 -u32 A_int_norm_select_complete_used[] = { +static u32 A_int_norm_select_complete_used[] __attribute((unused)) = { }; #define A_int_test_1 0x04000000 -u32 A_int_test_1_used[] = { +static u32 A_int_test_1_used[] __attribute((unused)) = { 0x000001fd, }; #define A_int_test_2 0x04010000 -u32 A_int_test_2_used[] = { +static u32 A_int_test_2_used[] __attribute((unused)) = { 0x00000215, }; #define A_int_test_3 0x04020000 -u32 A_int_test_3_used[] = { +static u32 A_int_test_3_used[] __attribute((unused)) = { }; #define A_msg_buf 0x00000000 -u32 A_msg_buf_used[] = { +static u32 A_msg_buf_used[] __attribute((unused)) = { 0x00000102, 0x0000014e, 0x00000158, @@ -2514,24 +2514,24 @@ }; #define A_reconnect_dsa_head 0x00000000 -u32 A_reconnect_dsa_head_used[] = { +static u32 A_reconnect_dsa_head_used[] __attribute((unused)) = { 0x0000006c, 0x00000074, 0x000001a0, }; #define A_reselected_identify 0x00000000 -u32 A_reselected_identify_used[] = { +static u32 A_reselected_identify_used[] __attribute((unused)) = { 0x00000045, 0x0000019c, }; #define A_reselected_tag 0x00000000 -u32 A_reselected_tag_used[] = { +static u32 A_reselected_tag_used[] __attribute((unused)) = { }; #define A_schedule 0x00000000 -u32 A_schedule_used[] = { +static u32 A_schedule_used[] __attribute((unused)) = { 0x0000007e, 0x00000192, 0x000001e2, @@ -2539,12 +2539,12 @@ }; #define A_test_dest 0x00000000 -u32 A_test_dest_used[] = { +static u32 A_test_dest_used[] __attribute((unused)) = { 0x000001fb, }; #define A_test_src 0x00000000 -u32 A_test_src_used[] = { +static u32 A_test_src_used[] __attribute((unused)) = { 0x000001fa, }; @@ -2582,7 +2582,7 @@ #define Ent_test_2 0x000007f8 #define Ent_test_2_msgout 0x00000810 #define Ent_wait_reselect 0x00000654 -u32 LABELPATCHES[] = { +static u32 LABELPATCHES[] __attribute((unused)) = { 0x00000008, 0x0000000a, 0x00000013, @@ -2666,12 +2666,12 @@ 0x00000243, }; -struct { +static struct { u32 offset; void *address; -} EXTERNAL_PATCHES[] = { +} EXTERNAL_PATCHES[] __attribute((unused)) = { }; -u32 INSTRUCTIONS = 301; -u32 PATCHES = 81; -u32 EXTERNAL_PATCHES_LEN = 0; +static u32 INSTRUCTIONS __attribute((unused)) = 301; +static u32 PATCHES __attribute((unused)) = 81; +static u32 EXTERNAL_PATCHES_LEN __attribute((unused)) = 0; diff -u --recursive --new-file v2.3.24/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.3.24/linux/drivers/scsi/scsi.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/scsi/scsi.c Mon Nov 1 11:37:00 1999 @@ -263,6 +263,7 @@ * SCSI code to reset bus.*/ {"QUANTUM", "LPS525S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */ {"QUANTUM", "PD1225S", "3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */ + {"QUANTUM", "FIREBALL ST4.3S", "0F0C", BLIST_NOLUN}, /* Locks up when polled for lun != 0 */ {"MEDIAVIS", "CDR-H93MV", "1.31", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */ {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */ diff -u --recursive --new-file v2.3.24/linux/drivers/scsi/sim710_d.h linux/drivers/scsi/sim710_d.h --- v2.3.24/linux/drivers/scsi/sim710_d.h Sat Oct 9 11:47:50 1999 +++ linux/drivers/scsi/sim710_d.h Fri Oct 29 10:53:32 1999 @@ -1,4 +1,4 @@ -u32 SCRIPT[] = { +static u32 SCRIPT[] = { /* @@ -1776,12 +1776,12 @@ }; #define A_dsa_cmnd 0x00000010 -u32 A_dsa_cmnd_used[] = { +static u32 A_dsa_cmnd_used[] __attribute((unused)) = { 0x0000001d, }; #define A_dsa_datain 0x00000028 -u32 A_dsa_datain_used[] = { +static u32 A_dsa_datain_used[] __attribute((unused)) = { 0x0000003d, 0x0000003f, 0x00000041, @@ -1913,7 +1913,7 @@ }; #define A_dsa_dataout 0x00000428 -u32 A_dsa_dataout_used[] = { +static u32 A_dsa_dataout_used[] __attribute((unused)) = { 0x00000143, 0x00000145, 0x00000147, @@ -2045,12 +2045,12 @@ }; #define A_dsa_msgin 0x00000020 -u32 A_dsa_msgin_used[] = { +static u32 A_dsa_msgin_used[] __attribute((unused)) = { 0x0000002f, }; #define A_dsa_msgout 0x00000008 -u32 A_dsa_msgout_used[] = { +static u32 A_dsa_msgout_used[] __attribute((unused)) = { 0x00000013, 0x00000285, 0x000002c5, @@ -2058,50 +2058,50 @@ }; #define A_dsa_select 0x00000000 -u32 A_dsa_select_used[] = { +static u32 A_dsa_select_used[] __attribute((unused)) = { 0x00000006, }; #define A_dsa_size 0x00000828 -u32 A_dsa_size_used[] = { +static u32 A_dsa_size_used[] __attribute((unused)) = { }; #define A_dsa_status 0x00000018 -u32 A_dsa_status_used[] = { +static u32 A_dsa_status_used[] __attribute((unused)) = { 0x0000002b, }; #define A_had_cmdout 0x00000004 -u32 A_had_cmdout_used[] = { +static u32 A_had_cmdout_used[] __attribute((unused)) = { 0x0000001a, }; #define A_had_datain 0x00000008 -u32 A_had_datain_used[] = { +static u32 A_had_datain_used[] __attribute((unused)) = { 0x00000038, }; #define A_had_dataout 0x00000010 -u32 A_had_dataout_used[] = { +static u32 A_had_dataout_used[] __attribute((unused)) = { 0x0000013e, }; #define A_had_extmsg 0x00000080 -u32 A_had_extmsg_used[] = { +static u32 A_had_extmsg_used[] __attribute((unused)) = { 0x0000025a, 0x0000029a, 0x000002da, }; #define A_had_msgin 0x00000040 -u32 A_had_msgin_used[] = { +static u32 A_had_msgin_used[] __attribute((unused)) = { 0x00000248, 0x00000288, 0x000002c8, }; #define A_had_msgout 0x00000002 -u32 A_had_msgout_used[] = { +static u32 A_had_msgout_used[] __attribute((unused)) = { 0x00000010, 0x00000282, 0x000002c2, @@ -2109,161 +2109,161 @@ }; #define A_had_select 0x00000001 -u32 A_had_select_used[] = { +static u32 A_had_select_used[] __attribute((unused)) = { 0x0000000c, }; #define A_had_status 0x00000020 -u32 A_had_status_used[] = { +static u32 A_had_status_used[] __attribute((unused)) = { }; #define A_int_bad_extmsg1a 0xab930000 -u32 A_int_bad_extmsg1a_used[] = { +static u32 A_int_bad_extmsg1a_used[] __attribute((unused)) = { 0x00000263, }; #define A_int_bad_extmsg1b 0xab930001 -u32 A_int_bad_extmsg1b_used[] = { +static u32 A_int_bad_extmsg1b_used[] __attribute((unused)) = { 0x0000026b, }; #define A_int_bad_extmsg2a 0xab930002 -u32 A_int_bad_extmsg2a_used[] = { +static u32 A_int_bad_extmsg2a_used[] __attribute((unused)) = { 0x000002a3, }; #define A_int_bad_extmsg2b 0xab930003 -u32 A_int_bad_extmsg2b_used[] = { +static u32 A_int_bad_extmsg2b_used[] __attribute((unused)) = { 0x000002ab, }; #define A_int_bad_extmsg3a 0xab930004 -u32 A_int_bad_extmsg3a_used[] = { +static u32 A_int_bad_extmsg3a_used[] __attribute((unused)) = { 0x000002e3, }; #define A_int_bad_extmsg3b 0xab930005 -u32 A_int_bad_extmsg3b_used[] = { +static u32 A_int_bad_extmsg3b_used[] __attribute((unused)) = { 0x000002eb, }; #define A_int_bad_msg1 0xab930006 -u32 A_int_bad_msg1_used[] = { +static u32 A_int_bad_msg1_used[] __attribute((unused)) = { 0x00000255, }; #define A_int_bad_msg2 0xab930007 -u32 A_int_bad_msg2_used[] = { +static u32 A_int_bad_msg2_used[] __attribute((unused)) = { 0x00000295, }; #define A_int_bad_msg3 0xab930008 -u32 A_int_bad_msg3_used[] = { +static u32 A_int_bad_msg3_used[] __attribute((unused)) = { 0x000002d5, }; #define A_int_cmd_bad_phase 0xab930009 -u32 A_int_cmd_bad_phase_used[] = { +static u32 A_int_cmd_bad_phase_used[] __attribute((unused)) = { 0x00000027, }; #define A_int_cmd_complete 0xab93000a -u32 A_int_cmd_complete_used[] = { +static u32 A_int_cmd_complete_used[] __attribute((unused)) = { 0x00000037, }; #define A_int_data_bad_phase 0xab93000b -u32 A_int_data_bad_phase_used[] = { +static u32 A_int_data_bad_phase_used[] __attribute((unused)) = { 0x00000247, }; #define A_int_disc1 0xab930019 -u32 A_int_disc1_used[] = { +static u32 A_int_disc1_used[] __attribute((unused)) = { 0x00000277, }; #define A_int_disc2 0xab93001a -u32 A_int_disc2_used[] = { +static u32 A_int_disc2_used[] __attribute((unused)) = { 0x000002b7, }; #define A_int_disc3 0xab93001b -u32 A_int_disc3_used[] = { +static u32 A_int_disc3_used[] __attribute((unused)) = { 0x000002f7, }; #define A_int_msg_sdtr1 0xab93000c -u32 A_int_msg_sdtr1_used[] = { +static u32 A_int_msg_sdtr1_used[] __attribute((unused)) = { 0x00000271, }; #define A_int_msg_sdtr2 0xab93000d -u32 A_int_msg_sdtr2_used[] = { +static u32 A_int_msg_sdtr2_used[] __attribute((unused)) = { 0x000002b1, }; #define A_int_msg_sdtr3 0xab93000e -u32 A_int_msg_sdtr3_used[] = { +static u32 A_int_msg_sdtr3_used[] __attribute((unused)) = { 0x000002f1, }; #define A_int_no_msgout1 0xab93000f -u32 A_int_no_msgout1_used[] = { +static u32 A_int_no_msgout1_used[] __attribute((unused)) = { 0x00000281, }; #define A_int_no_msgout2 0xab930010 -u32 A_int_no_msgout2_used[] = { +static u32 A_int_no_msgout2_used[] __attribute((unused)) = { 0x000002c1, }; #define A_int_no_msgout3 0xab930011 -u32 A_int_no_msgout3_used[] = { +static u32 A_int_no_msgout3_used[] __attribute((unused)) = { 0x00000301, }; #define A_int_not_cmd_complete 0xab930012 -u32 A_int_not_cmd_complete_used[] = { +static u32 A_int_not_cmd_complete_used[] __attribute((unused)) = { 0x00000031, }; #define A_int_not_rej 0xab93001c -u32 A_int_not_rej_used[] = { +static u32 A_int_not_rej_used[] __attribute((unused)) = { 0x0000030d, }; #define A_int_resel_not_msgin 0xab930016 -u32 A_int_resel_not_msgin_used[] = { +static u32 A_int_resel_not_msgin_used[] __attribute((unused)) = { 0x00000317, }; #define A_int_reselected 0xab930017 -u32 A_int_reselected_used[] = { +static u32 A_int_reselected_used[] __attribute((unused)) = { 0x0000031b, }; #define A_int_sel_no_ident 0xab930013 -u32 A_int_sel_no_ident_used[] = { +static u32 A_int_sel_no_ident_used[] __attribute((unused)) = { 0x0000000f, }; #define A_int_sel_not_cmd 0xab930014 -u32 A_int_sel_not_cmd_used[] = { +static u32 A_int_sel_not_cmd_used[] __attribute((unused)) = { 0x00000019, }; #define A_int_selected 0xab930018 -u32 A_int_selected_used[] = { +static u32 A_int_selected_used[] __attribute((unused)) = { 0x0000032d, }; #define A_int_status_not_msgin 0xab930015 -u32 A_int_status_not_msgin_used[] = { +static u32 A_int_status_not_msgin_used[] __attribute((unused)) = { 0x0000002d, }; #define A_msgin_buf 0x00000000 -u32 A_msgin_buf_used[] = { +static u32 A_msgin_buf_used[] __attribute((unused)) = { 0x0000024b, 0x0000025f, 0x00000267, @@ -2280,7 +2280,7 @@ }; #define A_reselected_identify 0x00000000 -u32 A_reselected_identify_used[] = { +static u32 A_reselected_identify_used[] __attribute((unused)) = { 0x00000319, }; @@ -2304,7 +2304,7 @@ #define Ent_wait_disc2 0x00000ad0 #define Ent_wait_disc3 0x00000bd0 #define Ent_wait_disc_complete 0x000000d0 -u32 LABELPATCHES[] = { +static u32 LABELPATCHES[] __attribute((unused)) = { 0x00000007, 0x00000009, 0x00000015, @@ -2349,12 +2349,12 @@ 0x0000032b, }; -struct { +static struct { u32 offset; void *address; -} EXTERNAL_PATCHES[] = { +} EXTERNAL_PATCHES[] __attribute((unused)) = { }; -u32 INSTRUCTIONS = 407; -u32 PATCHES = 42; -u32 EXTERNAL_PATCHES_LEN = 0; +static u32 INSTRUCTIONS __attribute((unused)) = 407; +static u32 PATCHES __attribute((unused)) = 42; +static u32 EXTERNAL_PATCHES_LEN __attribute((unused)) = 0; diff -u --recursive --new-file v2.3.24/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c --- v2.3.24/linux/drivers/sound/cmpci.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/sound/cmpci.c Mon Nov 1 10:31:28 1999 @@ -1333,7 +1333,7 @@ db = &s->dma_adc; } else return -EINVAL; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) diff -u --recursive --new-file v2.3.24/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c --- v2.3.24/linux/drivers/sound/es1370.c Fri Sep 10 23:57:35 1999 +++ linux/drivers/sound/es1370.c Sat Oct 30 09:45:36 1999 @@ -113,6 +113,7 @@ * replaced current->state = x with set_current_state(x) * 03.09.99 0.30 change read semantics for MIDI to match * OSS more closely; remove possible wakeup race + * 28.10.99 0.31 More waitqueue races fixed * * some important things missing in Ensoniq documentation: * @@ -1064,9 +1065,9 @@ if (s->dma_dac1.mapped || !s->dma_dac1.ready) return 0; - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac1.wait, &wait); for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->dma_dac1.count; spin_unlock_irqrestore(&s->lock, flags); @@ -1100,9 +1101,9 @@ if (s->dma_dac2.mapped || !s->dma_dac2.ready) return 0; - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac2.wait, &wait); for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->dma_dac2.count; spin_unlock_irqrestore(&s->lock, flags); @@ -1133,6 +1134,7 @@ static ssize_t es1370_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct es1370_state *s = (struct es1370_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned swptr; @@ -1148,26 +1150,38 @@ if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; ret = 0; + add_wait_queue(&s->dma_adc.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); swptr = s->dma_adc.swptr; cnt = s->dma_adc.dmasize-swptr; if (s->dma_adc.count < cnt) cnt = s->dma_adc.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_adc(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_adc.wait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_adc.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_adc.swptr = swptr; @@ -1178,12 +1192,15 @@ ret += cnt; start_adc(s); } + remove_wait_queue(&s->dma_adc.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } static ssize_t es1370_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct es1370_state *s = (struct es1370_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned swptr; @@ -1199,6 +1216,7 @@ if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; ret = 0; + add_wait_queue(&s->dma_dac2.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); if (s->dma_dac2.count < 0) { @@ -1209,20 +1227,31 @@ cnt = s->dma_dac2.dmasize-swptr; if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize) cnt = s->dma_dac2.dmasize - s->dma_dac2.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_dac2(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_dac2.wait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_dac2.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_dac2.swptr = swptr; @@ -1234,6 +1263,8 @@ ret += cnt; start_dac2(s); } + remove_wait_queue(&s->dma_dac2.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } @@ -1285,7 +1316,7 @@ db = &s->dma_adc; } else return -EINVAL; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) @@ -1608,6 +1639,7 @@ static int es1370_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct es1370_state *s = devs; unsigned long flags; @@ -1624,8 +1656,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -1676,8 +1712,8 @@ dealloc_dmabuf(&s->dma_adc); } s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -1705,6 +1741,7 @@ static ssize_t es1370_write_dac(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct es1370_state *s = (struct es1370_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret = 0; unsigned long flags; unsigned swptr; @@ -1719,6 +1756,7 @@ return ret; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; + add_wait_queue(&s->dma_dac1.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); if (s->dma_dac1.count < 0) { @@ -1729,20 +1767,31 @@ cnt = s->dma_dac1.dmasize-swptr; if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize) cnt = s->dma_dac1.dmasize - s->dma_dac1.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_dac1(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_dac1.wait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_dac1.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_dac1.swptr = swptr; @@ -1754,6 +1803,8 @@ ret += cnt; start_dac1(s); } + remove_wait_queue(&s->dma_dac1.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } @@ -1789,7 +1840,7 @@ return -EINVAL; if ((ret = prog_dmabuf_dac1(s)) != 0) return ret; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << s->dma_dac1.buforder)) @@ -1991,6 +2042,7 @@ static int es1370_open_dac(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct es1370_state *s = devs; unsigned long flags; @@ -2014,8 +2066,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -2047,8 +2103,8 @@ stop_dac1(s); dealloc_dmabuf(&s->dma_dac1); s->open_mode &= ~FMODE_DAC; - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -2097,6 +2153,8 @@ cnt = MIDIINBUF - ptr; if (s->midi.icnt < cnt) cnt = s->midi.icnt; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -2106,7 +2164,6 @@ ret = -EAGAIN; break; } - __set_current_state(TASK_INTERRUPTIBLE); schedule(); if (signal_pending(current)) { if (!ret) @@ -2159,8 +2216,10 @@ cnt = MIDIOUTBUF - ptr; if (s->midi.ocnt + cnt > MIDIOUTBUF) cnt = MIDIOUTBUF - s->midi.ocnt; - if (cnt <= 0) + if (cnt <= 0) { + __set_current_state(TASK_INTERRUPTIBLE); es1370_handle_midi(s); + } spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -2170,7 +2229,6 @@ ret = -EAGAIN; break; } - __set_current_state(TASK_INTERRUPTIBLE); schedule(); if (signal_pending(current)) { if (!ret) @@ -2228,6 +2286,7 @@ static int es1370_midi_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct es1370_state *s = devs; unsigned long flags; @@ -2244,8 +2303,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -2284,9 +2347,9 @@ VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->midi.ocnt; spin_unlock_irqrestore(&s->lock, flags); @@ -2314,8 +2377,8 @@ outl(s->ctrl, s->io+ES1370_REG_CONTROL); } spin_unlock_irqrestore(&s->lock, flags); - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -2389,7 +2452,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1370: version v0.29 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "es1370: version v0.31 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) { if (!RSRCISIOREGION(pcidev, 0)) diff -u --recursive --new-file v2.3.24/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c --- v2.3.24/linux/drivers/sound/es1371.c Fri Sep 10 23:57:35 1999 +++ linux/drivers/sound/es1371.c Sat Oct 30 09:45:36 1999 @@ -86,7 +86,14 @@ * replaced current->state = x with set_current_state(x) * 03.09.99 0.18 change read semantics for MIDI to match * OSS more closely; remove possible wakeup race - * + * 21.10.99 0.19 Round sampling rates, requested by + * Kasamatsu Kenichi + * 27.10.99 0.20 Added SigmaTel 3D enhancement string + * Codec ID printing changes + * 28.10.99 0.21 More waitqueue races fixed + * Joe Cotellese + * Changed PCI detection routine so we can more easily + * detect ES137x chip and derivatives. */ /*****************************************************************************/ @@ -116,16 +123,31 @@ #undef OSS_DOCUMENTED_MIXER_SEMANTICS #define ES1371_DEBUG +#define DBG(x) {} +/*#define DBG(x) {x}*/ /* --------------------------------------------------------------------- */ #ifndef PCI_VENDOR_ID_ENSONIQ #define PCI_VENDOR_ID_ENSONIQ 0x1274 #endif + +#ifndef PCI_VENDOR_ID_ECTIVA +#define PCI_VENDOR_ID_ECTIVA 0x1102 +#endif + #ifndef PCI_DEVICE_ID_ENSONIQ_ES1371 #define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 #endif +#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880 +#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 +#endif + +#ifndef PCI_DEVICE_ID_ECTIVA_EV1938 +#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 +#endif + /* ES1371 chip ID */ /* This is a little confusing because all ES1371 compatible chips have the same DEVICE_ID, the only thing differentiating them is the REV_ID field. @@ -135,8 +157,9 @@ #define ES1371REV_ES1373_A 0x04 #define ES1371REV_ES1373_B 0x06 #define ES1371REV_CT5880_A 0x07 +#define CT5880REV_CT5880_C 0x02 #define ES1371REV_ES1371_B 0x09 - +#define EV1938REV_EV1938_A 0x00 #define ES1371_MAGIC ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371) @@ -144,7 +167,7 @@ #define JOY_EXTENT 8 #define ES1371_REG_CONTROL 0x00 -#define ES1371_REG_STATUS 0x04 +#define ES1371_REG_STATUS 0x04 /* on the 5880 it is control/status */ #define ES1371_REG_UART_DATA 0x08 #define ES1371_REG_UART_STATUS 0x09 #define ES1371_REG_UART_CONTROL 0x09 @@ -212,6 +235,7 @@ #define STAT_INTR 0x80000000 /* wired or of all interrupt bits */ +#define CSTAT_5880_AC97_RST 0x20000000 /* CT5880 Reset bit */ #define STAT_EN_SPDIF 0x00040000 /* enable S/PDIF circuitry */ #define STAT_TS_SPDIF 0x00020000 /* test S/PDIF circuitry */ #define STAT_TESTMODE 0x00010000 /* test ASIC */ @@ -370,7 +394,13 @@ "NVidea 3D Stereo Enhancement", "Philips Incredible Sound", "Texas Instruments 3D Stereo Enhancement", - "VLSI Technology 3D Stereo Enhancement" + "VLSI Technology 3D Stereo Enhancement", + NULL, + NULL, + NULL, + NULL, + NULL, + "SigmaTel SS3D" }; /* --------------------------------------------------------------------- */ @@ -391,8 +421,12 @@ /* hardware resources */ unsigned long io; /* long for SPARC */ unsigned int irq; + + /* PCI ID's */ + u16 vendor; + u16 device; u8 rev; /* the chip revision */ - + #ifdef ES1371_DEBUG /* debug /proc entry */ struct proc_dir_entry *ps; @@ -591,8 +625,8 @@ rate = 48000; if (rate < 4000) rate = 4000; - freq = (rate << 15) / 3000; - s->dac1rate = (freq * 3000) >> 15; + freq = ((rate << 15) + 1500) / 3000; + s->dac1rate = (freq * 3000 + 16384) >> 15; spin_lock_irqsave(&s->lock, flags); r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC)) | SRC_DDAC1; outl(r, s->io + ES1371_REG_SRCONV); @@ -614,9 +648,8 @@ rate = 48000; if (rate < 4000) rate = 4000; - freq = (rate << 15) / 3000; - s->dac2rate = (freq * 3000) >> 15; - printk (KERN_DEBUG "dac2 freq: %d\n", freq); + freq = ((rate << 15) + 1500) / 3000; + s->dac2rate = (freq * 3000 + 16384) >> 15; spin_lock_irqsave(&s->lock, flags); r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)) | SRC_DDAC2; outl(r, s->io + ES1371_REG_SRCONV); @@ -1612,10 +1645,9 @@ if (s->dma_dac1.mapped || !s->dma_dac1.ready) return 0; - - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac1.wait, &wait); for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->dma_dac1.count; spin_unlock_irqrestore(&s->lock, flags); @@ -1631,7 +1663,7 @@ tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate; tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; if (!schedule_timeout(tmo + 1)) - printk(KERN_DEBUG "es1371: dac1 dma timed out??\n"); + DBG(printk(KERN_DEBUG "es1371: dac1 dma timed out??\n");) } remove_wait_queue(&s->dma_dac1.wait, &wait); set_current_state(TASK_RUNNING); @@ -1648,10 +1680,9 @@ if (s->dma_dac2.mapped || !s->dma_dac2.ready) return 0; - - __set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&s->dma_dac2.wait, &wait); for (;;) { + __set_current_state(TASK_UNINTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->dma_dac2.count; spin_unlock_irqrestore(&s->lock, flags); @@ -1667,7 +1698,7 @@ tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate; tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; if (!schedule_timeout(tmo + 1)) - printk(KERN_DEBUG "es1371: dac2 dma timed out??\n"); + DBG(printk(KERN_DEBUG "es1371: dac2 dma timed out??\n");) } remove_wait_queue(&s->dma_dac2.wait, &wait); set_current_state(TASK_RUNNING); @@ -1681,6 +1712,7 @@ static ssize_t es1371_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned swptr; @@ -1696,26 +1728,38 @@ if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; ret = 0; + add_wait_queue(&s->dma_adc.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); swptr = s->dma_adc.swptr; cnt = s->dma_adc.dmasize-swptr; if (s->dma_adc.count < cnt) cnt = s->dma_adc.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_adc(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_adc.wait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_adc.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_adc.swptr = swptr; @@ -1726,12 +1770,15 @@ ret += cnt; start_adc(s); } + remove_wait_queue(&s->dma_adc.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } static ssize_t es1371_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned swptr; @@ -1747,6 +1794,7 @@ if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; ret = 0; + add_wait_queue(&s->dma_dac2.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); if (s->dma_dac2.count < 0) { @@ -1757,20 +1805,31 @@ cnt = s->dma_dac2.dmasize-swptr; if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize) cnt = s->dma_dac2.dmasize - s->dma_dac2.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_dac2(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_dac2.wait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_dac2.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_dac2.swptr = swptr; @@ -1782,6 +1841,8 @@ ret += cnt; start_dac2(s); } + remove_wait_queue(&s->dma_dac2.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } @@ -1833,7 +1894,7 @@ db = &s->dma_adc; } else return -EINVAL; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) @@ -1894,7 +1955,6 @@ if (file->f_mode & FMODE_WRITE) { stop_dac2(s); s->dma_dac2.ready = 0; - printk (KERN_DEBUG "es137x: setting DAC2 rate: %d\n", val); set_dac2_rate(s, val); } } @@ -2152,6 +2212,7 @@ static int es1371_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct es1371_state *s = devs; unsigned long flags; @@ -2168,8 +2229,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -2251,6 +2316,7 @@ static ssize_t es1371_write_dac(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret = 0; unsigned long flags; unsigned swptr; @@ -2265,6 +2331,7 @@ return ret; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; + add_wait_queue(&s->dma_dac1.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); if (s->dma_dac1.count < 0) { @@ -2275,20 +2342,31 @@ cnt = s->dma_dac1.dmasize-swptr; if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize) cnt = s->dma_dac1.dmasize - s->dma_dac1.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_dac1(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_dac1.wait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_dac1.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_dac1.swptr = swptr; @@ -2300,6 +2378,8 @@ ret += cnt; start_dac1(s); } + remove_wait_queue(&s->dma_dac1.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } @@ -2335,7 +2415,7 @@ return -EINVAL; if ((ret = prog_dmabuf_dac1(s)) != 0) return ret; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << s->dma_dac1.buforder)) @@ -2528,6 +2608,7 @@ static int es1371_open_dac(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct es1371_state *s = devs; unsigned long flags; @@ -2551,8 +2632,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -2633,6 +2718,8 @@ cnt = MIDIINBUF - ptr; if (s->midi.icnt < cnt) cnt = s->midi.icnt; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -2642,7 +2729,6 @@ ret = -EAGAIN; break; } - __set_current_state(TASK_INTERRUPTIBLE); schedule(); if (signal_pending(current)) { if (!ret) @@ -2695,8 +2781,10 @@ cnt = MIDIOUTBUF - ptr; if (s->midi.ocnt + cnt > MIDIOUTBUF) cnt = MIDIOUTBUF - s->midi.ocnt; - if (cnt <= 0) + if (cnt <= 0) { + __set_current_state(TASK_INTERRUPTIBLE); es1371_handle_midi(s); + } spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -2706,7 +2794,6 @@ ret = -EAGAIN; break; } - __set_current_state(TASK_INTERRUPTIBLE); schedule(); if (signal_pending(current)) { if (!ret) @@ -2764,6 +2851,7 @@ static int es1371_midi_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct es1371_state *s = devs; unsigned long flags; @@ -2780,8 +2868,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -2819,9 +2911,9 @@ VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->midi.ocnt; spin_unlock_irqrestore(&s->lock, flags); @@ -2952,162 +3044,212 @@ ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) #define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start) +static int __init probe_chip(struct pci_dev *pcidev, int index) +{ + struct es1371_state *s; + mm_segment_t fs; + int i, val, val2; + unsigned char id[4]; + unsigned long tmo; + signed long tmo2; + unsigned int cssr; + + if (!RSRCISIOREGION(pcidev, 0)) + return -1; + if (pcidev->irq == 0) + return -1; + if (!(s = kmalloc(sizeof(struct es1371_state), GFP_KERNEL))) { + printk(KERN_WARNING "es1371: out of memory\n"); + return -1; + } + memset(s, 0, sizeof(struct es1371_state)); + init_waitqueue_head(&s->dma_adc.wait); + init_waitqueue_head(&s->dma_dac1.wait); + init_waitqueue_head(&s->dma_dac2.wait); + init_waitqueue_head(&s->open_wait); + init_waitqueue_head(&s->midi.iwait); + init_waitqueue_head(&s->midi.owait); + init_MUTEX(&s->open_sem); + spin_lock_init(&s->lock); + s->magic = ES1371_MAGIC; + s->io = RSRCADDRESS(pcidev, 0); + s->irq = pcidev->irq; + s->vendor = pcidev->vendor; + s->device = pcidev->device; + pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev); + printk(KERN_INFO "es1371: found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n", + s->vendor, s->device, s->rev); + if (check_region(s->io, ES1371_EXTENT)) { + printk(KERN_ERR "es1371: io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1); + goto err_region; + } + request_region(s->io, ES1371_EXTENT, "es1371"); + if (request_irq(s->irq, es1371_interrupt, SA_SHIRQ, "es1371", s)) { + printk(KERN_ERR "es1371: irq %u in use\n", s->irq); + goto err_irq; + } + printk(KERN_INFO "es1371: found es1371 rev %d at io %#lx irq %u\n" + KERN_INFO "es1371: features: joystick 0x%x\n", s->rev, s->io, s->irq, joystick[index]); + /* register devices */ + if ((s->dev_audio = register_sound_dsp(&es1371_audio_fops, -1)) < 0) + goto err_dev1; + if ((s->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1)) < 0) + goto err_dev2; + if ((s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1)) < 0) + goto err_dev3; + if ((s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)) < 0) + goto err_dev4; +#ifdef ES1371_DEBUG + /* intialize the debug proc device */ + s->ps = create_proc_entry("es1371", S_IFREG | S_IRUGO, NULL); + if (s->ps) + s->ps->read_proc = proc_es1371_dump; +#endif /* ES1371_DEBUG */ + + /* initialize codec registers */ + s->ctrl = 0; + if ((joystick[index] & ~0x18) == 0x200) { + if (check_region(joystick[index], JOY_EXTENT)) + printk(KERN_ERR "es1371: joystick address 0x%x already in use\n", joystick[index]); + else { + s->ctrl |= CTRL_JYSTK_EN | (((joystick[index] >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT); + } + } + s->sctrl = 0; + cssr = 0; + /* check to see if s/pdif mode is being requested */ + if (spdif[index]) { + if (s->rev >= 4) { + printk(KERN_INFO "es1371: enabling S/PDIF output\n"); + cssr |= STAT_EN_SPDIF; + s->ctrl |= CTRL_SPDIFEN_B; + } else { + printk(KERN_ERR "es1371: revision %d does not support S/PDIF\n", s->rev); + } + } + /* initialize the chips */ + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + outl(0, s->io+ES1371_REG_LEGACY); + pci_set_master(pcidev); /* enable bus mastering */ + /* if we are a 5880 turn on the AC97 */ + if (s->vendor == PCI_VENDOR_ID_ENSONIQ && + s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && + s->rev == CT5880REV_CT5880_C) { + cssr |= CSTAT_5880_AC97_RST; + outl(cssr, s->io+ES1371_REG_STATUS); + /* need to delay around 20ms(bleech) to give + some CODECs enough time to wakeup */ + tmo = jiffies + (HZ / 50) + 1; + for (;;) { + tmo2 = tmo - jiffies; + if (tmo2 <= 0) + break; + schedule_timeout(tmo2); + } + } + /* AC97 warm reset to start the bitclk */ + outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL); + udelay(2); + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + /* init the sample rate converter */ + src_init(s); + /* codec init */ + wrcodec(s, AC97_RESET, 0); /* reset codec */ + s->mix.codec_id = rdcodec(s, AC97_RESET); /* get codec ID */ + val = rdcodec(s, AC97_VENDOR_ID1); + val2 = rdcodec(s, AC97_VENDOR_ID2); + id[0] = val >> 8; + id[1] = val; + id[2] = val2 >> 8; + id[3] = 0; + if (id[0] <= ' ' || id[0] > 0x7f) + id[0] = ' '; + if (id[1] <= ' ' || id[1] > 0x7f) + id[1] = ' '; + if (id[2] <= ' ' || id[2] > 0x7f) + id[2] = ' '; + printk(KERN_INFO "es1371: codec vendor %s (0x%04x%02x) revision %d (0x%02x)\n", + id, val & 0xffff, (val2 >> 8) & 0xff, val2 & 0xff, val2 & 0xff); + printk(KERN_INFO "es1371: codec features"); + if (s->mix.codec_id & CODEC_ID_DEDICATEDMIC) + printk(" dedicated MIC PCM in"); + if (s->mix.codec_id & CODEC_ID_MODEMCODEC) + printk(" Modem Line Codec"); + if (s->mix.codec_id & CODEC_ID_BASSTREBLE) + printk(" Bass & Treble"); + if (s->mix.codec_id & CODEC_ID_SIMULATEDSTEREO) + printk(" Simulated Stereo"); + if (s->mix.codec_id & CODEC_ID_HEADPHONEOUT) + printk(" Headphone out"); + if (s->mix.codec_id & CODEC_ID_LOUDNESS) + printk(" Loudness"); + if (s->mix.codec_id & CODEC_ID_18BITDAC) + printk(" 18bit DAC"); + if (s->mix.codec_id & CODEC_ID_20BITDAC) + printk(" 20bit DAC"); + if (s->mix.codec_id & CODEC_ID_18BITADC) + printk(" 18bit ADC"); + if (s->mix.codec_id & CODEC_ID_20BITADC) + printk(" 20bit ADC"); + printk("%s\n", (s->mix.codec_id & 0x3ff) ? "" : " none"); + val = (s->mix.codec_id >> CODEC_ID_SESHIFT) & CODEC_ID_SEMASK; + printk(KERN_INFO "es1371: stereo enhancement: %s\n", + (val <= 26 && stereo_enhancement[val]) ? stereo_enhancement[val] : "unknown"); + + fs = get_fs(); + set_fs(KERNEL_DS); + val = SOUND_MASK_LINE; + mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); + for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) { + val = initvol[i].vol; + mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); + } + set_fs(fs); + /* turn on S/PDIF output driver if requested */ + outl(cssr, s->io+ES1371_REG_STATUS); + /* queue it for later freeing */ + s->next = devs; + devs = s; + return 0; + + err_dev4: + unregister_sound_dsp(s->dev_dac); + err_dev3: + unregister_sound_mixer(s->dev_mixer); + err_dev2: + unregister_sound_dsp(s->dev_audio); + err_dev1: + printk(KERN_ERR "es1371: cannot register misc device\n"); + free_irq(s->irq, s); + err_irq: + release_region(s->io, ES1371_EXTENT); + err_region: + kfree_s(s, sizeof(struct es1371_state)); + return -1; +} + static int __init init_es1371(void) { - struct es1371_state *s; struct pci_dev *pcidev = NULL; - mm_segment_t fs; - int i, val, val2, index = 0; - unsigned cssr; + int index = 0; if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "es1371: version v0.17 time " __TIME__ " " __DATE__ "\n"); - while (index < NR_DEVICE && - (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) { - if (!RSRCISIOREGION(pcidev, 0)) - continue; - if (pcidev->irq == 0) - continue; - if (!(s = kmalloc(sizeof(struct es1371_state), GFP_KERNEL))) { - printk(KERN_WARNING "es1371: out of memory\n"); + printk(KERN_INFO "es1371: version v0.22 time " __TIME__ " " __DATE__ "\n"); + while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pcidev))) { + if (pcidev->vendor == PCI_VENDOR_ID_ENSONIQ) { + if (pcidev->device != PCI_DEVICE_ID_ENSONIQ_ES1371 && + pcidev->device != PCI_DEVICE_ID_ENSONIQ_CT5880) + continue; + } else if (pcidev->vendor == PCI_VENDOR_ID_ECTIVA) { + if (pcidev->device != PCI_DEVICE_ID_ECTIVA_EV1938) + continue; + } else continue; - } - memset(s, 0, sizeof(struct es1371_state)); - init_waitqueue_head(&s->dma_adc.wait); - init_waitqueue_head(&s->dma_dac1.wait); - init_waitqueue_head(&s->dma_dac2.wait); - init_waitqueue_head(&s->open_wait); - init_waitqueue_head(&s->midi.iwait); - init_waitqueue_head(&s->midi.owait); - init_MUTEX(&s->open_sem); - spin_lock_init(&s->lock); - s->magic = ES1371_MAGIC; - s->io = RSRCADDRESS(pcidev, 0); - s->irq = pcidev->irq; - pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev); - if (check_region(s->io, ES1371_EXTENT)) { - printk(KERN_ERR "es1371: io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1); - goto err_region; - } - request_region(s->io, ES1371_EXTENT, "es1371"); - if (request_irq(s->irq, es1371_interrupt, SA_SHIRQ, "es1371", s)) { - printk(KERN_ERR "es1371: irq %u in use\n", s->irq); - goto err_irq; - } - printk(KERN_INFO "es1371: found es1371 rev %d at io %#lx irq %u\n" - KERN_INFO "es1371: features: joystick 0x%x\n", s->rev, s->io, s->irq, joystick[index]); - /* register devices */ - if ((s->dev_audio = register_sound_dsp(&es1371_audio_fops, -1)) < 0) - goto err_dev1; - if ((s->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1)) < 0) - goto err_dev2; - if ((s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1)) < 0) - goto err_dev3; - if ((s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)) < 0) - goto err_dev4; -#ifdef ES1371_DEBUG - /* intialize the debug proc device */ - s->ps = create_proc_entry("es1371", S_IFREG | S_IRUGO, NULL); - if (s->ps) - s->ps->read_proc = proc_es1371_dump; -#endif /* ES1371_DEBUG */ - - /* initialize codec registers */ - s->ctrl = 0; - if ((joystick[index] & ~0x18) == 0x200) { - if (check_region(joystick[index], JOY_EXTENT)) - printk(KERN_ERR "es1371: joystick address 0x%x already in use\n", joystick[index]); - else { - s->ctrl |= CTRL_JYSTK_EN | (((joystick[index] >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT); - } - } - s->sctrl = 0; - cssr = 0; - /* check to see if s/pdif mode is being requested */ - if (spdif[index]) { - if (s->rev >= 4) { - printk(KERN_INFO "es1371: enabling S/PDIF output\n"); - cssr |= STAT_EN_SPDIF; - s->ctrl |= CTRL_SPDIFEN_B; - } else { - printk(KERN_ERR "es1371: revision %d does not support S/PDIF\n", s->rev); - } - } - /* initialize the chips */ - outl(s->ctrl, s->io+ES1371_REG_CONTROL); - outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); - outl(0, s->io+ES1371_REG_LEGACY); - pci_set_master(pcidev); /* enable bus mastering */ - /* AC97 warm reset to start the bitclk */ - outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL); - udelay(2); - outl(s->ctrl, s->io+ES1371_REG_CONTROL); - /* init the sample rate converter */ - src_init(s); - /* codec init */ - wrcodec(s, AC97_RESET, 0); /* reset codec */ - s->mix.codec_id = rdcodec(s, AC97_RESET); /* get codec ID */ - val = rdcodec(s, AC97_VENDOR_ID1); - val2 = rdcodec(s, AC97_VENDOR_ID2); - printk(KERN_INFO "es1371: codec vendor %c%c%c revision %d\n", - (val >> 8) & 0xff, val & 0xff, (val2 >> 8) & 0xff, val2 & 0xff); - printk(KERN_INFO "es1371: codec features"); - if (s->mix.codec_id & CODEC_ID_DEDICATEDMIC) - printk(" dedicated MIC PCM in"); - if (s->mix.codec_id & CODEC_ID_MODEMCODEC) - printk(" Modem Line Codec"); - if (s->mix.codec_id & CODEC_ID_BASSTREBLE) - printk(" Bass & Treble"); - if (s->mix.codec_id & CODEC_ID_SIMULATEDSTEREO) - printk(" Simulated Stereo"); - if (s->mix.codec_id & CODEC_ID_HEADPHONEOUT) - printk(" Headphone out"); - if (s->mix.codec_id & CODEC_ID_LOUDNESS) - printk(" Loudness"); - if (s->mix.codec_id & CODEC_ID_18BITDAC) - printk(" 18bit DAC"); - if (s->mix.codec_id & CODEC_ID_20BITDAC) - printk(" 20bit DAC"); - if (s->mix.codec_id & CODEC_ID_18BITADC) - printk(" 18bit ADC"); - if (s->mix.codec_id & CODEC_ID_20BITADC) - printk(" 20bit ADC"); - printk("%s\n", (s->mix.codec_id & 0x3ff) ? "" : " none"); - val = (s->mix.codec_id >> CODEC_ID_SESHIFT) & CODEC_ID_SEMASK; - printk(KERN_INFO "es1371: stereo enhancement: %s\n", (val <= 20) ? stereo_enhancement[val] : "unknown"); - - fs = get_fs(); - set_fs(KERNEL_DS); - val = SOUND_MASK_LINE; - mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); - for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) { - val = initvol[i].vol; - mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); - } - set_fs(fs); - /* turn on S/PDIF output driver if requested */ - outl(cssr, s->io+ES1371_REG_STATUS); - /* queue it for later freeing */ - s->next = devs; - devs = s; - index++; - continue; - - err_dev4: - unregister_sound_dsp(s->dev_dac); - err_dev3: - unregister_sound_mixer(s->dev_mixer); - err_dev2: - unregister_sound_dsp(s->dev_audio); - err_dev1: - printk(KERN_ERR "es1371: cannot register misc device\n"); - free_irq(s->irq, s); - err_irq: - release_region(s->io, ES1371_EXTENT); - err_region: - kfree_s(s, sizeof(struct es1371_state)); + if (!probe_chip(pcidev, index)) + index++; } if (!devs) return -ENODEV; diff -u --recursive --new-file v2.3.24/linux/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c --- v2.3.24/linux/drivers/sound/esssolo1.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/sound/esssolo1.c Sat Oct 30 09:45:36 1999 @@ -60,6 +60,7 @@ * OSS more closely; remove possible wakeup race * 07.10.99 0.9 Fix initialization; complain if sequencer writes time out * Revised resource grabbing for the FM synthesizer + * 28.10.99 0.10 More waitqueue races fixed * */ @@ -101,7 +102,7 @@ #define SOLO1_MAGIC ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1) -#define DDMABASE_OFFSET 0x10 /* chip bug workaround kludge */ +#define DDMABASE_OFFSET 0 /* chip bug workaround kludge */ #define DDMABASE_EXTENT 16 #define IOBASE_EXTENT 16 @@ -939,9 +940,9 @@ if (s->dma_dac.mapped) return 0; - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac.wait, &wait); for (;;) { + set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->dma_dac.count; spin_unlock_irqrestore(&s->lock, flags); @@ -974,6 +975,7 @@ static ssize_t solo1_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct solo1_state *s = (struct solo1_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned swptr; @@ -989,12 +991,15 @@ if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; ret = 0; + add_wait_queue(&s->dma_adc.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); swptr = s->dma_adc.swptr; cnt = s->dma_adc.dmasize-swptr; if (s->dma_adc.count < cnt) cnt = s->dma_adc.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -1015,9 +1020,12 @@ #endif if (inb(s->ddmabase+15) & 1) printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n"); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_adc.wait); + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); #ifdef DEBUGREC printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" KERN_DEBUG "solo1_read: regs: B1: 0x%02x B2: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n" @@ -1027,12 +1035,18 @@ read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt); #endif - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_adc.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_adc.swptr = swptr; @@ -1047,12 +1061,15 @@ read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc)); #endif } + remove_wait_queue(&s->dma_adc.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } static ssize_t solo1_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct solo1_state *s = (struct solo1_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned swptr; @@ -1076,6 +1093,7 @@ read_mixer(s, 0x78), read_mixer(s, 0x7a), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc)); #endif ret = 0; + add_wait_queue(&s->dma_dac.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); if (s->dma_dac.count < 0) { @@ -1086,20 +1104,31 @@ cnt = s->dma_dac.dmasize-swptr; if (s->dma_dac.count + cnt > s->dma_dac.dmasize) cnt = s->dma_dac.dmasize - s->dma_dac.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_dac(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_dac.wait); - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_dac.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_dac.swptr = swptr; @@ -1111,6 +1140,8 @@ ret += cnt; start_dac(s); } + remove_wait_queue(&s->dma_dac.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } @@ -1168,7 +1199,7 @@ db = &s->dma_adc; } else return -EINVAL; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) @@ -1473,8 +1504,8 @@ dealloc_dmabuf(&s->dma_adc); } s->open_mode &= ~(FMODE_READ | FMODE_WRITE); - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -1482,6 +1513,7 @@ static int solo1_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct solo1_state *s = devs; while (s && ((s->dev_audio ^ minor) & ~0xf)) @@ -1497,8 +1529,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -1630,6 +1666,8 @@ cnt = MIDIINBUF - ptr; if (s->midi.icnt < cnt) cnt = s->midi.icnt; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -1639,7 +1677,6 @@ ret = -EAGAIN; break; } - __set_current_state(TASK_INTERRUPTIBLE); schedule(); if (signal_pending(current)) { if (!ret) @@ -1692,8 +1729,10 @@ cnt = MIDIOUTBUF - ptr; if (s->midi.ocnt + cnt > MIDIOUTBUF) cnt = MIDIOUTBUF - s->midi.ocnt; - if (cnt <= 0) + if (cnt <= 0) { + __set_current_state(TASK_INTERRUPTIBLE); solo1_handle_midi(s); + } spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -1703,7 +1742,6 @@ ret = -EAGAIN; break; } - __set_current_state(TASK_INTERRUPTIBLE); schedule(); if (signal_pending(current)) { if (!ret) @@ -1761,6 +1799,7 @@ static int solo1_midi_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct solo1_state *s = devs; unsigned long flags; @@ -1777,8 +1816,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -1822,9 +1865,9 @@ VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->midi.ocnt; spin_unlock_irqrestore(&s->lock, flags); @@ -1852,8 +1895,8 @@ del_timer(&s->midi.timer); } spin_unlock_irqrestore(&s->lock, flags); - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -1978,6 +2021,7 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct solo1_state *s = devs; while (s && s->dev_dmfm != minor) @@ -1993,8 +2037,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -2033,8 +2081,8 @@ outb(0, s->sbbase+3); } release_region(s->sbbase, FMSYNTH_EXTENT); - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -2094,7 +2142,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "solo1: version v0.7 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "solo1: version v0.10 time " __TIME__ " " __DATE__ "\n"); while (index < NR_DEVICE && (pcidev = pci_find_device(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_SOLO1, pcidev))) { if (!RSRCISIOREGION(pcidev, 0) || diff -u --recursive --new-file v2.3.24/linux/drivers/sound/maestro.c linux/drivers/sound/maestro.c --- v2.3.24/linux/drivers/sound/maestro.c Fri Oct 22 13:21:50 1999 +++ linux/drivers/sound/maestro.c Mon Nov 1 10:31:28 1999 @@ -2339,7 +2339,7 @@ db = &s->dma_adc; } else return -EINVAL; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) diff -u --recursive --new-file v2.3.24/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c --- v2.3.24/linux/drivers/sound/sonicvibes.c Fri Sep 10 23:57:35 1999 +++ linux/drivers/sound/sonicvibes.c Sat Oct 30 09:45:36 1999 @@ -81,6 +81,7 @@ * replaced current->state = x with set_current_state(x) * 03.09.99 0.21 change read semantics for MIDI to match * OSS more closely; remove possible wakeup race + * 28.10.99 0.22 More waitqueue races fixed * */ @@ -1267,9 +1268,9 @@ if (s->dma_dac.mapped || !s->dma_dac.ready) return 0; - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->dma_dac.wait, &wait); for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->dma_dac.count; spin_unlock_irqrestore(&s->lock, flags); @@ -1299,6 +1300,7 @@ static ssize_t sv_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct sv_state *s = (struct sv_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned swptr; @@ -1315,24 +1317,30 @@ return -EFAULT; ret = 0; #if 0 - spin_lock_irqsave(&s->lock, flags); - sv_update_ptr(s); - spin_unlock_irqrestore(&s->lock, flags); + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + spin_unlock_irqrestore(&s->lock, flags); #endif + add_wait_queue(&s->dma_adc.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); swptr = s->dma_adc.swptr; cnt = s->dma_adc.dmasize-swptr; if (s->dma_adc.count < cnt) cnt = s->dma_adc.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_adc(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) { + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + if (!schedule_timeout(HZ)) { printk(KERN_DEBUG "sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, s->dma_adc.hwptr, s->dma_adc.swptr); @@ -1345,12 +1353,18 @@ s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0; spin_unlock_irqrestore(&s->lock, flags); } - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) - return ret ? ret : -EFAULT; + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_adc.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_adc.swptr = swptr; @@ -1361,12 +1375,15 @@ ret += cnt; start_adc(s); } + remove_wait_queue(&s->dma_adc.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } static ssize_t sv_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct sv_state *s = (struct sv_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); ssize_t ret; unsigned long flags; unsigned swptr; @@ -1383,10 +1400,11 @@ return -EFAULT; ret = 0; #if 0 - spin_lock_irqsave(&s->lock, flags); - sv_update_ptr(s); - spin_unlock_irqrestore(&s->lock, flags); + spin_lock_irqsave(&s->lock, flags); + sv_update_ptr(s); + spin_unlock_irqrestore(&s->lock, flags); #endif + add_wait_queue(&s->dma_dac.wait, &wait); while (count > 0) { spin_lock_irqsave(&s->lock, flags); if (s->dma_dac.count < 0) { @@ -1397,14 +1415,19 @@ cnt = s->dma_dac.dmasize-swptr; if (s->dma_dac.count + cnt > s->dma_dac.dmasize) cnt = s->dma_dac.dmasize - s->dma_dac.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; if (cnt <= 0) { start_dac(s); - if (file->f_flags & O_NONBLOCK) - return ret ? ret : -EAGAIN; - if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) { + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + if (!schedule_timeout(HZ)) { printk(KERN_DEBUG "sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, s->dma_dac.hwptr, s->dma_dac.swptr); @@ -1417,12 +1440,18 @@ s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0; spin_unlock_irqrestore(&s->lock, flags); } - if (signal_pending(current)) - return ret ? ret : -ERESTARTSYS; + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } continue; } - if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) - return ret ? ret : -EFAULT; + if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } swptr = (swptr + cnt) % s->dma_dac.dmasize; spin_lock_irqsave(&s->lock, flags); s->dma_dac.swptr = swptr; @@ -1434,6 +1463,8 @@ ret += cnt; start_dac(s); } + remove_wait_queue(&s->dma_dac.wait, &wait); + set_current_state(TASK_RUNNING); return ret; } @@ -1485,7 +1516,7 @@ db = &s->dma_adc; } else return -EINVAL; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) @@ -1798,6 +1829,7 @@ static int sv_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct sv_state *s = devs; unsigned char fmtm = ~0, fmts = 0; @@ -1814,8 +1846,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -1858,8 +1894,8 @@ dealloc_dmabuf(&s->dma_adc); } s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -1908,6 +1944,8 @@ cnt = MIDIINBUF - ptr; if (s->midi.icnt < cnt) cnt = s->midi.icnt; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -1917,7 +1955,6 @@ ret = -EAGAIN; break; } - __set_current_state(TASK_INTERRUPTIBLE); schedule(); if (signal_pending(current)) { if (!ret) @@ -1970,8 +2007,10 @@ cnt = MIDIOUTBUF - ptr; if (s->midi.ocnt + cnt > MIDIOUTBUF) cnt = MIDIOUTBUF - s->midi.ocnt; - if (cnt <= 0) + if (cnt <= 0) { + __set_current_state(TASK_INTERRUPTIBLE); sv_handle_midi(s); + } spin_unlock_irqrestore(&s->lock, flags); if (cnt > count) cnt = count; @@ -1981,7 +2020,6 @@ ret = -EAGAIN; break; } - __set_current_state(TASK_INTERRUPTIBLE); schedule(); if (signal_pending(current)) { if (!ret) @@ -2039,6 +2077,7 @@ static int sv_midi_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct sv_state *s = devs; unsigned long flags; @@ -2055,8 +2094,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -2103,9 +2146,9 @@ VALIDATE_STATE(s); if (file->f_mode & FMODE_WRITE) { - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&s->lock, flags); count = s->midi.ocnt; spin_unlock_irqrestore(&s->lock, flags); @@ -2133,8 +2176,8 @@ del_timer(&s->midi.timer); } spin_unlock_irqrestore(&s->lock, flags); - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -2259,6 +2302,7 @@ static int sv_dmfm_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); + DECLARE_WAITQUEUE(wait, current); struct sv_state *s = devs; while (s && s->dev_dmfm != minor) @@ -2274,8 +2318,12 @@ up(&s->open_sem); return -EBUSY; } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); up(&s->open_sem); - interruptible_sleep_on(&s->open_wait); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; down(&s->open_sem); @@ -2307,8 +2355,8 @@ outb(regb, s->iosynth+2); outb(0, s->iosynth+3); } - up(&s->open_sem); wake_up(&s->open_wait); + up(&s->open_sem); MOD_DEC_USE_COUNT; return 0; } @@ -2385,7 +2433,7 @@ if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; - printk(KERN_INFO "sv: version v0.20 time " __TIME__ " " __DATE__ "\n"); + printk(KERN_INFO "sv: version v0.22 time " __TIME__ " " __DATE__ "\n"); #if 0 if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT))) printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); diff -u --recursive --new-file v2.3.24/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v2.3.24/linux/drivers/sound/soundcard.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/sound/soundcard.c Thu Oct 28 14:34:46 1999 @@ -297,14 +297,6 @@ return len; } -#ifdef CONFIG_PROC_FS -static struct proc_dir_entry proc_root_sound = { - PROC_SOUND, 5, "sound", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, NULL, sound_proc_get_info -}; -#endif - #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif @@ -756,7 +748,7 @@ /* printk("Sound: mmap() called twice for the same DMA buffer\n");*/ return -EIO; } - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) { /* printk("Sound: mmap() offset must be 0.\n");*/ return -EINVAL; @@ -855,7 +847,7 @@ } #endif #ifdef CONFIG_PROC_FS - if (proc_register(&proc_root, &proc_root_sound)) + if (!create_proc_info_entry("sound", 0, NULL, sound_proc_get_info)) printk(KERN_ERR "sound: registering /proc/sound failed\n"); #endif } @@ -935,10 +927,7 @@ { return; } -#ifdef CONFIG_PROC_FS - if (proc_unregister(&proc_root, PROC_SOUND)) - printk(KERN_ERR "sound: unregistering /proc/sound failed\n"); -#endif + remove_proc_entry("sound", NULL); if (chrdev_registered) destroy_special_devices(); diff -u --recursive --new-file v2.3.24/linux/drivers/usb/acm.c linux/drivers/usb/acm.c --- v2.3.24/linux/drivers/usb/acm.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/usb/acm.c Thu Oct 28 12:54:35 1999 @@ -73,6 +73,8 @@ #define CTRL_STAT_DTR 1 #define CTRL_STAT_RTS 2 +static struct usb_driver acm_driver; + static int acm_refcount; static struct tty_driver acm_tty_driver; @@ -83,6 +85,7 @@ struct acm_state { struct usb_device *dev; //the coresponding usb device + int cfgnum; //configuration number on this device struct tty_struct *tty; //the coresponding tty char present; //a device for this struct was detected => this tty is used char active; //someone has this acm's device open @@ -194,7 +197,7 @@ info("ACM_READ_IRQ: state %d, %d bytes\n", state, count); if (state) { printk( "acm_read_irq: strange state received: %x\n", state ); - return 1; + return 0; } if (!ACM_READY) @@ -204,7 +207,7 @@ tty_insert_flip_char(tty,data[i],0); tty_flip_buffer_push(tty); - return 1; /* continue transfer */ + return 0; /* Never return 1 from this routine. It makes uhci do bad things. */ } static int acm_write_irq(int state, void *__buffer, int count, void *dev_id) @@ -382,7 +385,7 @@ return -1; } -static int acm_probe(struct usb_device *dev) +static void * acm_probe(struct usb_device *dev, unsigned int ifnum) { struct acm_state *acm; struct usb_interface_descriptor *interface; @@ -394,7 +397,7 @@ if (0>(acmno=get_free_acm())) { info("Too many acm devices connected\n"); - return -1; + return NULL; } acm = &acm_state_table[acmno]; @@ -402,10 +405,14 @@ if (dev->descriptor.bDeviceClass != 2 || dev->descriptor.bDeviceSubClass != 0 || dev->descriptor.bDeviceProtocol != 0) - return -1; + return NULL; #define IFCLASS(if) ((if->bInterfaceClass << 24) | (if->bInterfaceSubClass << 16) | (if->bInterfaceProtocol << 8) | (if->bNumEndpoints)) + /* FIXME: should the driver really be doing the configuration + * selecting or should the usbcore? [different configurations + * can have different bandwidth requirements] -greg */ + /* Now scan all configs for a ACM configuration*/ for (cfgnum=0;cfgnumdescriptor.bNumConfigurations;cfgnum++) { /* The first one should be Communications interface? */ @@ -425,7 +432,14 @@ interface->bNumEndpoints != 2) continue; - /* if ((endpoint->bEndpointAddress & 0x80) == 0x80) */ + /* make sure both interfaces are available for our use */ + if (usb_interface_claimed(&dev->config[cfgnum].interface[0]) || + usb_interface_claimed(&dev->config[cfgnum].interface[1])) { + printk("usb-acm: required interface already has a driver\n"); + continue; + } + + endpoint = &interface->endpoint[0]; if ((endpoint->bEndpointAddress & 0x80) != 0x80) swapped = 1; @@ -445,7 +459,6 @@ usb_set_configuration(dev, dev->config[cfgnum].bConfigurationValue); acm->dev=dev; - dev->private=acm; acm->readendp=dev->config[cfgnum].interface[1].altsetting[0].endpoint[0^swapped].bEndpointAddress; acm->readpipe=usb_rcvbulkpipe(dev,acm->readendp); @@ -453,7 +466,7 @@ acm->reading=0; if (!acm->readbuffer) { printk("ACM: Couldn't allocate readbuffer\n"); - return -1; + return NULL; } acm->writeendp=dev->config[cfgnum].interface[1].altsetting[0].endpoint[1^swapped].bEndpointAddress; @@ -463,23 +476,29 @@ if (!acm->writebuffer) { printk("ACM: Couldn't allocate writebuffer\n"); kfree(acm->readbuffer); - return -1; + return NULL; } acm->ctrlendp=dev->config[cfgnum].interface[0].altsetting[0].endpoint[0].bEndpointAddress; acm->ctrlpipe=usb_rcvctrlpipe(acm->dev,acm->ctrlendp); acm->ctrlinterval=dev->config[cfgnum].interface[0].altsetting[0].endpoint[0].bInterval; + acm->cfgnum = cfgnum; acm->present=1; MOD_INC_USE_COUNT; - return 0; + + usb_driver_claim_interface(&acm_driver, + &dev->config[cfgnum].interface[0], acm); + usb_driver_claim_interface(&acm_driver, + &dev->config[cfgnum].interface[1], acm); + return acm; } - return -1; + return NULL; } -static void acm_disconnect(struct usb_device *dev) +static void acm_disconnect(struct usb_device *dev, void *ptr) { - struct acm_state *acm = (struct acm_state *) dev->private; + struct acm_state *acm = ptr; info("acm_disconnect\n"); @@ -501,6 +520,12 @@ kfree(acm->writebuffer); kfree(acm->readbuffer); + /* release the interfaces so that other drivers can have at them */ + usb_driver_release_interface(&acm_driver, + &dev->config[acm->cfgnum].interface[0]); + usb_driver_release_interface(&acm_driver, + &dev->config[acm->cfgnum].interface[1]); + MOD_DEC_USE_COUNT; } @@ -584,7 +609,7 @@ acm=&acm_state_table[i]; if (acm->present) { printk("disconnecting %d\n",i); - acm_disconnect(acm->dev); + acm_disconnect(acm->dev, acm); } } tty_unregister_driver(&acm_tty_driver); diff -u --recursive --new-file v2.3.24/linux/drivers/usb/audio.c linux/drivers/usb/audio.c --- v2.3.24/linux/drivers/usb/audio.c Mon Oct 11 15:38:15 1999 +++ linux/drivers/usb/audio.c Sun Oct 31 15:01:59 1999 @@ -33,6 +33,22 @@ * wants to use an Asynch out pipe. usb_audio_state now basically * only contains lists of mixer and wave devices. We can therefore * now have multiple mixer/wave devices per USB device. + * 1999-10-31: Thomas Sailer + * Audio can now be unloaded if it is not in use by any mixer + * or dsp client (formerly you had to disconnect the audio devices + * from the USB port) + * Finally, about three months after ordering, my "Maxxtro SPK222" + * speakers arrived, isn't disdata a great mail order company 8-) + * Parse class specific endpoint descriptor of the audiostreaming + * interfaces and take the endpoint attributes from there. + * Unbelievably, the Philips USB DAC has a sampling rate range + * of over a decade, yet does not support the sampling rate control! + * No wonder it sounds so bad, has very audible sampling rate + * conversion distortion. Don't try to listen to it using + * decent headphones! + * "Let's make things better" -> but please Philips start with your + * own stuff!!!! + * * */ @@ -182,6 +198,7 @@ unsigned int sratelo; unsigned int sratehi; unsigned char altsetting; + unsigned char attributes; }; struct dmabuf { @@ -542,11 +559,24 @@ i = u->flags; spin_unlock_irqrestore(&as->lock, flags); while (i & (FLG_ID0RUNNING|FLG_ID1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) { + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); + if (signal_pending(current)) { + if (i & FLG_ID0RUNNING) + usb_kill_isoc(u->dataiso[0]); + if (i & FLG_ID1RUNNING) + usb_kill_isoc(u->dataiso[1]); + if (i & FLG_SYNC0RUNNING) + usb_kill_isoc(u->synciso[0]); + if (i & FLG_SYNC1RUNNING) + usb_kill_isoc(u->synciso[1]); + break; + } spin_lock_irqsave(&as->lock, flags); i = u->flags; spin_unlock_irqrestore(&as->lock, flags); } + set_current_state(TASK_RUNNING); if (u->dataiso[0]) usb_free_isoc(u->dataiso[0]); if (u->dataiso[1]) @@ -801,6 +831,7 @@ printk(KERN_DEBUG "usbin_completed: killing id\n"); usb_kill_isoc(id); printk(KERN_DEBUG "usbin_completed: id killed\n"); + wake_up(&u->dma.wait); } spin_unlock_irqrestore(&as->lock, flags); return 0; @@ -873,6 +904,7 @@ printk(KERN_DEBUG "usbin_sync_completed: killing id\n"); usb_kill_isoc(id); printk(KERN_DEBUG "usbin_sync_completed: id killed\n"); + wake_up(&u->dma.wait); } spin_unlock_irqrestore(&as->lock, flags); return 0; @@ -1005,12 +1037,25 @@ spin_unlock_irqrestore(&as->lock, flags); printk(KERN_DEBUG "usb_audio: usbout_stop (2) flags 0x%04x\n", i); while (i & (FLG_ID0RUNNING|FLG_ID1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) { + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); + if (signal_pending(current)) { + if (i & FLG_ID0RUNNING) + usb_kill_isoc(u->dataiso[0]); + if (i & FLG_ID1RUNNING) + usb_kill_isoc(u->dataiso[1]); + if (i & FLG_SYNC0RUNNING) + usb_kill_isoc(u->synciso[0]); + if (i & FLG_SYNC1RUNNING) + usb_kill_isoc(u->synciso[1]); + break; + } spin_lock_irqsave(&as->lock, flags); i = u->flags; spin_unlock_irqrestore(&as->lock, flags); printk(KERN_DEBUG "usb_audio: usbout_stop (3) flags 0x%04x\n", i); } + set_current_state(TASK_RUNNING); if (u->dataiso[0]) usb_free_isoc(u->dataiso[0]); if (u->dataiso[1]) @@ -1272,6 +1317,7 @@ printk(KERN_DEBUG "usbout_completed: killing id\n"); usb_kill_isoc(id); printk(KERN_DEBUG "usbout_completed: id killed\n"); + wake_up(&u->dma.wait); } spin_unlock_irqrestore(&as->lock, flags); return 0; @@ -1347,6 +1393,7 @@ printk(KERN_DEBUG "usbout_sync_completed: killing id\n"); usb_kill_isoc(id); printk(KERN_DEBUG "usbout_sync_completed: id killed\n"); + wake_up(&u->dma.wait); } spin_unlock_irqrestore(&as->lock, flags); return 0; @@ -1500,6 +1547,7 @@ struct audioformat *fmt; unsigned int fmtnr, ep; unsigned char data[3]; + int ret; if (u->interface < 0 || u->interface >= config->bNumInterfaces) return 0; @@ -1515,7 +1563,7 @@ alts->endpoint[1].bmAttributes != 0x01 || alts->endpoint[1].bSynchAddress != 0 || alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress & 0x7f)) { - printk(KERN_ERR "usb_audio: device %d interface %d altsetting %d invalid synch pipe\n", + printk(KERN_ERR "usbaudio: device %d interface %d altsetting %d invalid synch pipe\n", dev->devnum, u->interface, fmt->altsetting); return -1; } @@ -1533,25 +1581,38 @@ } if (fmt->sratelo == fmt->sratehi) return 0; - data[0] = d->srate; - data[1] = d->srate >> 8; - data[2] = d->srate >> 16; ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN); - if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, - SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) { - printk(KERN_ERR "usbaudio: failure to set input sampling frequency device %d endpoint 0x%x to %u\n", - dev->devnum, ep, d->srate); - return -1; + /* if endpoint has pitch control, enable it */ + if (fmt->attributes & 0x02) { + data[0] = 1; + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n", + ret, dev->devnum, u->interface, ep, d->srate); + return -1; + } } - if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, - SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) { - printk(KERN_ERR "usbaudio: failure to get input sampling frequency device %d endpoint 0x%x\n", - dev->devnum, ep); - return -1; + /* if endpoint has sampling rate control, set it */ + if (fmt->attributes & 0x01) { + data[0] = d->srate; + data[1] = d->srate >> 8; + data[2] = d->srate >> 16; + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to set input sampling frequency device %d interface %u endpoint 0x%x to %u\n", + ret, dev->devnum, u->interface, ep, d->srate); + return -1; + } + if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to get input sampling frequency device %d interface %u endpoint 0x%x\n", + ret, dev->devnum, u->interface, ep); + return -1; + } + printk(KERN_DEBUG "usbaudio: set_format_in: device %d interface %d altsetting %d srate req: %u real %u\n", + dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)); + d->srate = data[0] | (data[1] << 8) | (data[2] << 16); } - printk(KERN_DEBUG "usb_audio: set_format_in: device %d interface %d altsetting %d srate req: %u real %u\n", - dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)); - d->srate = data[0] | (data[1] << 8) | (data[2] << 16); return 0; } @@ -1566,6 +1627,7 @@ struct audioformat *fmt; unsigned int fmtnr, ep; unsigned char data[3]; + int ret; if (u->interface < 0 || u->interface >= config->bNumInterfaces) return 0; @@ -1581,7 +1643,7 @@ alts->endpoint[1].bmAttributes != 0x01 || alts->endpoint[1].bSynchAddress != 0 || alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress | 0x80)) { - printk(KERN_ERR "usb_audio: device %d interface %d altsetting %d invalid synch pipe\n", + printk(KERN_ERR "usbaudio: device %d interface %d altsetting %d invalid synch pipe\n", dev->devnum, u->interface, fmt->altsetting); return -1; } @@ -1599,25 +1661,38 @@ } if (fmt->sratelo == fmt->sratehi) return 0; - data[0] = d->srate; - data[1] = d->srate >> 8; - data[2] = d->srate >> 16; ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN); - if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, - SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) { - printk(KERN_ERR "usbaudio: failure to set output sampling frequency device %d endpoint 0x%x to %u\n", - dev->devnum, ep, d->srate); - return -1; + /* if endpoint has pitch control, enable it */ + if (fmt->attributes & 0x02) { + data[0] = 1; + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to set output pitch control device %d interface %u endpoint 0x%x to %u\n", + ret, dev->devnum, u->interface, ep, d->srate); + return -1; + } } - if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, - SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) { - printk(KERN_ERR "usbaudio: failure to get output sampling frequency device %d endpoint 0x%x\n", - dev->devnum, ep); - return -1; + /* if endpoint has sampling rate control, set it */ + if (fmt->attributes & 0x01) { + data[0] = d->srate; + data[1] = d->srate >> 8; + data[2] = d->srate >> 16; + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to set output sampling frequency device %d interface %u endpoint 0x%x to %u\n", + ret, dev->devnum, u->interface, ep, d->srate); + return -1; + } + if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { + printk(KERN_ERR "usbaudio: failure (error %d) to get output sampling frequency device %d interface %u endpoint 0x%x\n", + ret, dev->devnum, u->interface, ep); + return -1; + } + printk(KERN_DEBUG "usbaudio: set_format_out: device %d interface %d altsetting %d srate req: %u real %u\n", + dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)); + d->srate = data[0] | (data[1] << 8) | (data[2] << 16); } - printk(KERN_DEBUG "usb_audio: set_format_out: device %d interface %d altsetting %d srate req: %u real %u\n", - dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)); - d->srate = data[0] | (data[1] << 8) | (data[2] << 16); return 0; } @@ -1736,7 +1811,7 @@ return 0; err: - printk(KERN_ERR "usb_audio: mixer request device %u if %u unit %u ch %u selector %u failed\n", + printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n", dev->devnum, ms->iface, ch->unitid, ch->chnum, ch->selector); return -1; } @@ -1775,7 +1850,6 @@ kfree(ms); } kfree(s); - MOD_DEC_USE_COUNT; } extern inline int prog_dmabuf_in(struct usb_audiodev *as) @@ -1825,6 +1899,7 @@ } file->private_data = ms; s->count++; + MOD_INC_USE_COUNT; up(&open_sem); return 0; } @@ -1836,6 +1911,7 @@ down(&open_sem); release(s); + MOD_DEC_USE_COUNT; return 0; } @@ -1952,10 +2028,10 @@ if (as->usbout.dma.mapped || !as->usbout.dma.ready) return 0; - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&as->usbout.dma.wait, &wait); for (;;) { - spin_lock_irqsave(&as->lock, flags); + __set_current_state(TASK_INTERRUPTIBLE); + spin_lock_irqsave(&as->lock, flags); count = as->usbout.dma.count; spin_unlock_irqrestore(&as->lock, flags); if (count <= 0) @@ -1969,8 +2045,10 @@ } tmo = 3 * HZ * count / as->usbout.dma.srate; tmo >>= AFMT_BYTESSHIFT(as->usbout.dma.format); - if (!schedule_timeout(tmo + 1)) + if (!schedule_timeout(tmo + 1)) { printk(KERN_DEBUG "usbaudio: dma timed out??\n"); + break; + } } remove_wait_queue(&as->usbout.dma.wait, &wait); set_current_state(TASK_RUNNING); @@ -1998,12 +2076,14 @@ return ret; if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&as->usbin.dma.wait, &wait); while (count > 0) { spin_lock_irqsave(&as->lock, flags); ptr = as->usbin.dma.rdptr; cnt = as->usbin.dma.count; + /* set task state early to avoid wakeup races */ + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&as->lock, flags); if (cnt > count) cnt = count; @@ -2060,9 +2140,13 @@ return ret; if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; - __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&as->usbout.dma.wait, &wait); while (count > 0) { +#if 0 + printk(KERN_DEBUG "usb_audio_write: count %u dma: count %u rdptr %u wrptr %u dmasize %u fragsize %u flags 0x%02x taskst 0x%x\n", + count, as->usbout.dma.count, as->usbout.dma.rdptr, as->usbout.dma.wrptr, as->usbout.dma.dmasize, as->usbout.dma.fragsize, + as->usbout.flags, current->state); +#endif spin_lock_irqsave(&as->lock, flags); if (as->usbout.dma.count < 0) { as->usbout.dma.count = 0; @@ -2070,6 +2154,9 @@ } ptr = as->usbout.dma.wrptr; cnt = as->usbout.dma.dmasize - as->usbout.dma.count; + /* set task state early to avoid wakeup races */ + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore(&as->lock, flags); if (cnt > count) cnt = count; @@ -2160,7 +2247,7 @@ db = &as->usbin.dma; } else return -EINVAL; - if (vma->vm_offset != 0) + if (vma->vm_pgoff != 0) return -EINVAL; return dmabuf_mmap(db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot); } @@ -2469,6 +2556,7 @@ file->private_data = as; as->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); s->count++; + MOD_INC_USE_COUNT; up(&open_sem); return 0; } @@ -2498,6 +2586,7 @@ as->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); release(s); wake_up(&open_wait); + MOD_DEC_USE_COUNT; return 0; } @@ -2532,14 +2621,16 @@ * zero bandwidth (idle) config and one or more live one pers interface. */ -static int usb_audio_probe(struct usb_device *dev); -static void usb_audio_disconnect(struct usb_device *dev); +static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum); +static void usb_audio_disconnect(struct usb_device *dev, void *ptr); static struct usb_driver usb_audio_driver = { "audio", usb_audio_probe, usb_audio_disconnect, - { NULL, NULL } + /*{ NULL, NULL }, */ LIST_HEAD_INIT(usb_audio_driver.driver_list), + NULL, + 0 }; @@ -2620,7 +2711,7 @@ struct usb_interface_descriptor *alts; struct usb_interface *iface; struct audioformat *fp; - unsigned char *fmt; + unsigned char *fmt, *csep; unsigned int i, j, k, format; if (!(as = kmalloc(sizeof(struct usb_audiodev), GFP_KERNEL))) @@ -2640,44 +2731,50 @@ if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2) continue; if (alts->bNumEndpoints < 1) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u does not have an endpoint\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n", dev->devnum, asifin, i); continue; } if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 || !(alts->endpoint[0].bEndpointAddress & 0x80)) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u first endpoint not isochronous in\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous in\n", dev->devnum, asifin, i); continue; } fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifin, i); if (!fmt) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", dev->devnum, asifin, i); continue; } if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u format not supported\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u format not supported\n", dev->devnum, asifin, i); continue; } format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8); fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifin, i); if (!fmt) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", dev->devnum, asifin, i); continue; } if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n", dev->devnum, asifin, i); continue; } if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n", dev->devnum, asifin, i, fmt[4], fmt[5]); continue; } + csep = find_descriptor(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, asifin, i); + if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u no or invalid class specific endpoint descriptor\n", + dev->devnum, asifin, i); + continue; + } if (as->numfmtin >= MAXFORMATS) continue; fp = &as->fmtin[as->numfmtin++]; @@ -2697,8 +2794,9 @@ if (k < fp->sratelo) fp->sratelo = k; } - printk(KERN_INFO "usb_audio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u\n", - dev->devnum, asifin, i, fp->format, fp->sratelo, fp->sratehi); + fp->attributes = csep[3]; + printk(KERN_INFO "usbaudio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u attributes 0x%02x\n", + dev->devnum, asifin, i, fp->format, fp->sratelo, fp->sratehi, fp->attributes); } } /* search for output formats */ @@ -2709,44 +2807,50 @@ if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2) continue; if (alts->bNumEndpoints < 1) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u does not have an endpoint\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n", dev->devnum, asifout, i); continue; } if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 || (alts->endpoint[0].bEndpointAddress & 0x80)) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u first endpoint not isochronous out\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u first endpoint not isochronous out\n", dev->devnum, asifout, i); continue; } fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifout, i); if (!fmt) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", dev->devnum, asifout, i); continue; } if (fmt[0] < 7 || fmt[6] != 0 || (fmt[5] != 1 && fmt[5] != 2)) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u format not supported\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u format not supported\n", dev->devnum, asifout, i); continue; } format = (fmt[5] == 2) ? (AFMT_U16_LE | AFMT_U8) : (AFMT_S16_LE | AFMT_S8); fmt = find_csinterface_descriptor(buffer, buflen, NULL, FORMAT_TYPE, asifout, i); if (!fmt) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n", dev->devnum, asifout, i); continue; } if (fmt[0] < 8+3*(fmt[7] ? fmt[7] : 2) || fmt[3] != 1) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not supported\n", dev->devnum, asifout, i); continue; } if (fmt[4] < 1 || fmt[4] > 2 || fmt[5] < 1 || fmt[5] > 2) { - printk(KERN_ERR "usb_audio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n", + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u unsupported channels %u framesize %u\n", dev->devnum, asifout, i, fmt[4], fmt[5]); continue; } + csep = find_descriptor(buffer, buflen, NULL, USB_DT_CS_ENDPOINT, asifout, i); + if (!csep || csep[0] < 7 || csep[2] != EP_GENERAL) { + printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u no or invalid class specific endpoint descriptor\n", + dev->devnum, asifout, i); + continue; + } if (as->numfmtout >= MAXFORMATS) continue; fp = &as->fmtout[as->numfmtout++]; @@ -2766,8 +2870,9 @@ if (k < fp->sratelo) fp->sratelo = k; } - printk(KERN_INFO "usb_audio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u\n", - dev->devnum, asifout, i, fp->format, fp->sratelo, fp->sratehi); + fp->attributes = csep[3]; + printk(KERN_INFO "usbaudio: device %u interface %u altsetting %u: format 0x%08x sratelo %u sratehi %u attributes 0x%02x\n", + dev->devnum, asifout, i, fp->format, fp->sratelo, fp->sratehi, fp->attributes); } } if (as->numfmtin == 0 && as->numfmtout == 0) { @@ -2775,7 +2880,7 @@ return; } if ((as->dev_audio = register_sound_dsp(&usb_audio_fops, -1)) < 0) { - printk(KERN_ERR "usb_audio: cannot register dsp\n"); + printk(KERN_ERR "usbaudio: cannot register dsp\n"); kfree(as); return; } @@ -2803,11 +2908,11 @@ struct mixerchannel *c; if (nr >= SOUND_MIXER_NRDEVICES) { - printk(KERN_ERR "usb_audio: invalid OSS mixer channel %u\n", nr); + printk(KERN_ERR "usbaudio: invalid OSS mixer channel %u\n", nr); return NULL; } if (!(state->mixchmask & (1 << nr))) { - printk(KERN_WARNING "usb_audio: OSS mixer channel %u already in use\n", nr); + printk(KERN_WARNING "usbaudio: OSS mixer channel %u already in use\n", nr); return NULL; } c = &state->mixch[state->nrmixch++]; @@ -2973,7 +3078,7 @@ return; err: - printk(KERN_ERR "usb_audio: mixer request device %u if %u unit %u ch %u selector %u failed\n", + printk(KERN_ERR "usbaudio: mixer request device %u if %u unit %u ch %u selector %u failed\n", dev->devnum, state->ctrlif, ch->unitid, ch->chnum, ch->selector); if (state->nrmixch) state->nrmixch--; @@ -3009,11 +3114,11 @@ unsigned int i; if (!mixer[4]) { - printk(KERN_ERR "usb_audio: unit %u invalid MIXER_UNIT descriptor\n", mixer[3]); + printk(KERN_ERR "usbaudio: unit %u invalid MIXER_UNIT descriptor\n", mixer[3]); return; } if (mixer[4] > SOUND_MIXER_NRDEVICES) { - printk(KERN_ERR "usb_audio: mixer unit %u: too many input pins\n", mixer[3]); + printk(KERN_ERR "usbaudio: mixer unit %u: too many input pins\n", mixer[3]); return; } chidx[0] = 0; @@ -3027,7 +3132,7 @@ bmapsize = (nroutch * chidx[mixer[4]] + 7) >> 3; bmap += bmapsize - 1; if (mixer[0] < 10+mixer[4]+bmapsize) { - printk(KERN_ERR "usb_audio: unit %u invalid MIXER_UNIT descriptor (bitmap too small)\n", mixer[3]); + printk(KERN_ERR "usbaudio: unit %u invalid MIXER_UNIT descriptor (bitmap too small)\n", mixer[3]); return; } for (i = 0; i < mixer[4]; i++) { @@ -3066,7 +3171,7 @@ unsigned int chnum, i; if (!selector[4]) { - printk(KERN_ERR "usb_audio: unit %u invalid SELECTOR_UNIT descriptor\n", selector[3]); + printk(KERN_ERR "usbaudio: unit %u invalid SELECTOR_UNIT descriptor\n", selector[3]); return; } usb_audio_recurseunit(state, selector[5]); @@ -3074,7 +3179,7 @@ for (i = 1; i < selector[4]; i++) { usb_audio_recurseunit(state, selector[5+i]); if (chnum != state->nrchannels) { - printk(KERN_ERR "usb_audio: selector unit %u: input pins with varying channel numbers\n", selector[3]); + printk(KERN_ERR "usbaudio: selector unit %u: input pins with varying channel numbers\n", selector[3]); state->termtype = 0; state->chconfig = 0; state->nrchannels = 0; @@ -3100,18 +3205,20 @@ static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr) { + struct usb_device *dev = state->s->usbdev; struct mixerchannel *ch; unsigned short chftr, mchftr; + unsigned char data[1]; usb_audio_recurseunit(state, ftr[4]); if (state->nrchannels == 0) { - printk(KERN_ERR "usb_audio: feature unit %u source has no channels\n", ftr[3]); + printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]); return; } if (state->nrchannels > 2) - printk(KERN_WARNING "usb_audio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]); + printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]); if (ftr[0] < 7+ftr[5]*(1+state->nrchannels)) { - printk(KERN_ERR "usb_audio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]); + printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]); return; } mchftr = ftr[6]; @@ -3149,7 +3256,7 @@ prepmixch(state); } } else if (mchftr & 4) { - ch = getmixchannel(state, getvolchannel(state)); + ch = getmixchannel(state, SOUND_MIXER_BASS); if (ch) { ch->unitid = ftr[3]; ch->selector = BASS_CONTROL; @@ -3169,7 +3276,7 @@ prepmixch(state); } } else if (mchftr & 16) { - ch = getmixchannel(state, getvolchannel(state)); + ch = getmixchannel(state, SOUND_MIXER_TREBLE); if (ch) { ch->unitid = ftr[3]; ch->selector = TREBLE_CONTROL; @@ -3178,6 +3285,14 @@ prepmixch(state); } } + /* if there are mute controls, unmute them */ + if ((chftr & 1) || (mchftr & 1)) { + printk(KERN_DEBUG "usbaudio: unmuting feature unit %u interface %u\n", ftr[3], state->ctrlif); + data[0] = 0; + if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + (MUTE_CONTROL << 8) | 0xff, state->ctrlif | (ftr[3] << 8), data, 1, HZ) < 0) + printk(KERN_WARNING "usbaudio: failure to unmute feature unit %u interface %u\n", ftr[3], state->ctrlif); + } } static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid) @@ -3186,12 +3301,12 @@ unsigned int i, j; if (test_and_set_bit(unitid, &state->unitbitmap)) { - printk(KERN_ERR "usb_audio: mixer path recursion detected, unit %d!\n", unitid); + printk(KERN_ERR "usbaudio: mixer path recursion detected, unit %d!\n", unitid); return; } p1 = find_audiocontrol_unit(state->buffer, state->buflen, NULL, unitid, state->ctrlif); if (!p1) { - printk(KERN_ERR "usb_audio: unit %d not found!\n", unitid); + printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid); return; } state->nrchannels = 0; @@ -3200,7 +3315,7 @@ switch (p1[2]) { case INPUT_TERMINAL: if (p1[0] < 12) { - printk(KERN_ERR "usb_audio: unit %u: invalid INPUT_TERMINAL descriptor\n", unitid); + printk(KERN_ERR "usbaudio: unit %u: invalid INPUT_TERMINAL descriptor\n", unitid); return; } state->nrchannels = p1[7]; @@ -3210,7 +3325,7 @@ case MIXER_UNIT: if (p1[0] < 10 || p1[0] < 10+p1[4]) { - printk(KERN_ERR "usb_audio: unit %u: invalid MIXER_UNIT descriptor\n", unitid); + printk(KERN_ERR "usbaudio: unit %u: invalid MIXER_UNIT descriptor\n", unitid); return; } usb_audio_mixerunit(state, p1); @@ -3218,7 +3333,7 @@ case SELECTOR_UNIT: if (p1[0] < 6 || p1[0] < 6+p1[4]) { - printk(KERN_ERR "usb_audio: unit %u: invalid SELECTOR_UNIT descriptor\n", unitid); + printk(KERN_ERR "usbaudio: unit %u: invalid SELECTOR_UNIT descriptor\n", unitid); return; } usb_audio_selectorunit(state, p1); @@ -3226,7 +3341,7 @@ case FEATURE_UNIT: if (p1[0] < 7 || p1[0] < 7+p1[5]) { - printk(KERN_ERR "usb_audio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid); + printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid); return; } usb_audio_featureunit(state, p1); @@ -3234,7 +3349,7 @@ case PROCESSING_UNIT: if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]] || p1[0] < 13+p1[6]+p1[11+p1[6]]+p1[13+p1[6]+p1[11+p1[6]]]) { - printk(KERN_ERR "usb_audio: unit %u: invalid PROCESSING_UNIT descriptor\n", unitid); + printk(KERN_ERR "usbaudio: unit %u: invalid PROCESSING_UNIT descriptor\n", unitid); return; } usb_audio_processingunit(state, p1); @@ -3242,7 +3357,7 @@ case EXTENSION_UNIT: if (p1[0] < 13 || p1[0] < 13+p1[6] || p1[0] < 13+p1[6]+p1[11+p1[6]]) { - printk(KERN_ERR "usb_audio: unit %u: invalid EXTENSION_UNIT descriptor\n", unitid); + printk(KERN_ERR "usbaudio: unit %u: invalid EXTENSION_UNIT descriptor\n", unitid); return; } for (j = i = 0; i < p1[6]; i++) { @@ -3258,7 +3373,7 @@ return; default: - printk(KERN_ERR "usb_audio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); + printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); return; } } @@ -3276,11 +3391,11 @@ state.buflen = buflen; state.ctrlif = ctrlif; set_bit(oterm[3], &state.unitbitmap); /* mark terminal ID as visited */ - printk(KERN_INFO "usb_audio: constructing mixer for Terminal %u type 0x%04x\n", + printk(KERN_INFO "usbaudio: constructing mixer for Terminal %u type 0x%04x\n", oterm[3], oterm[4] | (oterm[5] << 8)); usb_audio_recurseunit(&state, oterm[7]); if (!state.nrmixch) { - printk(KERN_INFO "usb_audio: no mixer controls found for Terminal %u\n", oterm[3]); + printk(KERN_INFO "usbaudio: no mixer controls found for Terminal %u\n", oterm[3]); return; } if (!(ms = kmalloc(sizeof(struct usb_mixerdev)+state.nrmixch*sizeof(struct mixerchannel), GFP_KERNEL))) @@ -3291,14 +3406,14 @@ ms->iface = ctrlif; ms->numch = state.nrmixch; if ((ms->dev_mixer = register_sound_mixer(&usb_mixer_fops, -1)) < 0) { - printk(KERN_ERR "usb_audio: cannot register mixer\n"); + printk(KERN_ERR "usbaudio: cannot register mixer\n"); kfree(ms); return; } list_add_tail(&ms->list, &s->mixerlist); } -static int usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif) +static void * usb_audio_parsecontrol(struct usb_device *dev, unsigned char *buffer, unsigned int buflen, unsigned int ctrlif) { struct usb_audio_state *s; struct usb_config_descriptor *config = dev->actconfig; @@ -3308,7 +3423,7 @@ unsigned int i, j, numifin = 0, numifout = 0; if (!(s = kmalloc(sizeof(struct usb_audio_state), GFP_KERNEL))) - return -1; + return NULL; memset(s, 0, sizeof(struct usb_audio_state)); INIT_LIST_HEAD(&s->audiolist); INIT_LIST_HEAD(&s->mixerlist); @@ -3316,63 +3431,67 @@ s->count = 1; /* find audiocontrol interface */ if (!(p1 = find_csinterface_descriptor(buffer, buflen, NULL, HEADER, ctrlif, -1))) { - printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u no HEADER found\n", + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u no HEADER found\n", dev->devnum, ctrlif); goto ret; } if (p1[0] < 8 + p1[7]) { - printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u HEADER error\n", + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u HEADER error\n", dev->devnum, ctrlif); goto ret; } if (!p1[7]) - printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u has no AudioStreaming and MidiStreaming interfaces\n", + printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u has no AudioStreaming and MidiStreaming interfaces\n", dev->devnum, ctrlif); for (i = 0; i < p1[7]; i++) { j = p1[8+i]; if (j >= config->bNumInterfaces) { - printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u does not exist\n", + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u does not exist\n", dev->devnum, ctrlif, j); continue; } iface = &config->interface[j]; if (iface->altsetting[0].bInterfaceClass != USB_CLASS_AUDIO) { - printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u is not an AudioClass interface\n", + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u is not an AudioClass interface\n", dev->devnum, ctrlif, j); continue; } if (iface->altsetting[0].bInterfaceSubClass == 3) { - printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u interface %u MIDIStreaming not supported\n", + printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u interface %u MIDIStreaming not supported\n", dev->devnum, ctrlif, j); continue; } if (iface->altsetting[0].bInterfaceSubClass != 2) { - printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u invalid AudioClass subtype\n", + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u invalid AudioClass subtype\n", dev->devnum, ctrlif, j); continue; } if (iface->num_altsetting < 2 || iface->altsetting[0].bNumEndpoints > 0) { - printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u altsetting 0 not zero bandwidth\n", + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u altsetting 0 not zero bandwidth\n", dev->devnum, ctrlif); continue; } if (iface->altsetting[1].bNumEndpoints < 1) { - printk(KERN_ERR "usb_audio: device %d audiocontrol interface %u interface %u has no endpoint\n", + printk(KERN_ERR "usbaudio: device %d audiocontrol interface %u interface %u has no endpoint\n", dev->devnum, ctrlif, j); continue; } /* note: this requires the data endpoint to be ep0 and the optional sync ep to be ep1, which seems to be the case */ if (iface->altsetting[1].endpoint[0].bEndpointAddress & USB_DIR_IN) { - if (numifin < USB_MAXINTERFACES) + if (numifin < USB_MAXINTERFACES) { ifin[numifin++] = j; + usb_driver_claim_interface(&usb_audio_driver, iface, s); + } } else { - if (numifout < USB_MAXINTERFACES) + if (numifout < USB_MAXINTERFACES) { ifout[numifout++] = j; + usb_driver_claim_interface(&usb_audio_driver, iface, s); + } } } - printk(KERN_INFO "usb_audio: device %d audiocontrol interface %u has %u input and %u output AudioStreaming interfaces\n", + printk(KERN_INFO "usbaudio: device %d audiocontrol interface %u has %u input and %u output AudioStreaming interfaces\n", dev->devnum, ctrlif, numifin, numifout); for (i = 0; i < numifin && i < numifout; i++) usb_audio_parsestreaming(s, buffer, buflen, ifin[i], ifout[i]); @@ -3391,20 +3510,18 @@ ret: if (list_empty(&s->audiolist) && list_empty(&s->mixerlist)) { kfree(s); - return -1; + return NULL; } /* everything successful */ - dev->private = s; down(&open_sem); list_add_tail(&s->audiodev, &audiodevs); up(&open_sem); - MOD_INC_USE_COUNT; - return 0; + return s; } /* we only care for the currently active configuration */ -static int usb_audio_probe(struct usb_device *dev) +static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum) { struct usb_config_descriptor *config = dev->actconfig; unsigned char *buffer; @@ -3416,40 +3533,36 @@ if (config->interface[i].altsetting[0].bInterfaceClass == USB_CLASS_AUDIO && config->interface[i].altsetting[0].bInterfaceSubClass == 1) /* audiocontrol interface found */ goto audioctrlfound; - printk(KERN_DEBUG "usb_audio: vendor id 0x%04x, product id 0x%04x contains no AudioControl interface\n", + printk(KERN_DEBUG "usbaudio: vendor id 0x%04x, product id 0x%04x contains no AudioControl interface\n", dev->descriptor.idVendor, dev->descriptor.idProduct); - return -1; + return NULL; audioctrlfound: /* find which configuration number is active */ for (i = 0; i < dev->descriptor.bNumConfigurations; i++) if (dev->config+i == config) goto configfound; - printk(KERN_ERR "usb_audio: cannot find active configuration number of device %d\n", dev->devnum); - return -1; + printk(KERN_ERR "usbaudio: cannot find active configuration number of device %d\n", dev->devnum); + return NULL; configfound: - if (usb_set_configuration(dev, config->bConfigurationValue) < 0) { - printk(KERN_ERR "usb_audio: set_configuration failed (ConfigValue 0x%x)\n", config->bConfigurationValue); - return -1; - } ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8); if (ret) { - printk(KERN_ERR "usb_audio: cannot get first 8 bytes of config descriptor %d of device %d\n", i, dev->devnum); - return -1; + printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d\n", i, dev->devnum); + return NULL; } if (buf[1] != USB_DT_CONFIG || buf[0] < 9) { - printk(KERN_ERR "usb_audio: invalid config descriptor %d of device %d\n", i, dev->devnum); - return -1; + printk(KERN_ERR "usbaudio: invalid config descriptor %d of device %d\n", i, dev->devnum); + return NULL; } buflen = buf[2] | (buf[3] << 8); if (!(buffer = kmalloc(buflen, GFP_KERNEL))) - return -1; + return NULL; ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buffer, buflen); if (ret) { kfree(buffer); - printk(KERN_ERR "usb_audio: cannot get config descriptor %d of device %d\n", i, dev->devnum); - return -1; + printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d\n", i, dev->devnum); + return NULL; } /* find first audio control interface; we currently cannot handle more than one */ for (i = 0; i < config->bNumInterfaces; i++) { @@ -3457,18 +3570,17 @@ config->interface[i].altsetting[0].bInterfaceSubClass != 1) continue; /* audiocontrol interface found */ - if (!usb_audio_parsecontrol(dev, buffer, buflen, i)) - return 0; + return usb_audio_parsecontrol(dev, buffer, buflen, i); } - return -1; + return NULL; } /* a revoke facility would make things simpler */ -static void usb_audio_disconnect(struct usb_device *dev) +static void usb_audio_disconnect(struct usb_device *dev, void *ptr) { - struct usb_audio_state *s = (struct usb_audio_state *)dev->private; + struct usb_audio_state *s = (struct usb_audio_state *)ptr; struct list_head *list; struct usb_audiodev *as; struct usb_mixerdev *ms; @@ -3496,7 +3608,6 @@ #endif release(s); wake_up(&open_wait); - dev->private = NULL; } int usb_audio_init(void) diff -u --recursive --new-file v2.3.24/linux/drivers/usb/cpia.c linux/drivers/usb/cpia.c --- v2.3.24/linux/drivers/usb/cpia.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/usb/cpia.c Mon Nov 1 11:30:29 1999 @@ -29,6 +29,7 @@ #define CPIA_DEBUG /* Gobs of debugging info */ /* Video Size 384 x 288 x 3 bytes for RGB */ +/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */ #define MAX_FRAME_SIZE (384 * 288 * 3) /*******************************/ @@ -37,6 +38,8 @@ #define MDEBUG(x) do { } while(0) /* Debug memory management */ +static struct usb_driver cpia_driver; + /* Given PGD from the address space's page table, return the kernel * virtual mapping of the physical memory mapped at ADR. */ @@ -207,8 +210,8 @@ static int usb_cpia_upload_frame(struct usb_device *dev, int forceupload) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_CPIA_UPLOAD_FRAME, - USB_TYPE_VENDOR | USB_RECIP_DEVICE, forceupload, 0, NULL, 0, HZ); + USB_REQ_CPIA_UPLOAD_FRAME, USB_TYPE_VENDOR | USB_RECIP_DEVICE, + forceupload, 0, NULL, 0, HZ); } static int usb_cpia_set_grab_mode(struct usb_device *dev, int continuousgrab) @@ -245,6 +248,16 @@ } #ifdef NOTUSED +static int usb_cpia_set_compression_target(struct usb_device *dev, int target, int targetfr, int targetq) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_CPIA_SET_COMPRESSION_TARGET, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (targetfr << 8) + target, targetq, NULL, 0, HZ); +} +#endif + +#ifdef NOTUSED static int usb_cpia_initstreamcap(struct usb_device *dev, int skipframes, int streamstartline) { return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -284,6 +297,7 @@ unsigned char *data = cpia->scratch; unsigned long l; + /* Grab the current frame and the previous frame */ frame = &cpia->frame[cpia->curframe]; pframe = &cpia->frame[(cpia->curframe - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES]; @@ -314,9 +328,9 @@ /* See if we found the end of the frame */ while (scratch_left(data) >= 4) { if (*((__u32 *)data) == 0xFFFFFFFF) { -printk("found end of frame\n"); data += 4; -goto error; + printk(KERN_INFO "cpia: EOF while scanning for magic\n"); + goto error; } data++; } @@ -347,7 +361,6 @@ frame->scanstate = STATE_LINES; frame->curline = 0; - break; case STATE_LINES: { @@ -363,10 +376,9 @@ /* Grab the length */ len = data[0] + (data[1] << 8); -printk("line %d, %d bytes long\n", frame->curline, len); /* Check to make sure it's nothing outrageous */ if (len > (frame->hdrwidth * 2) + 1) { - printk(KERN_INFO "cpia: bad length, resynching\n"); + printk(KERN_INFO "cpia: bad length, resynching (expected %d, got %d)\n", (frame->hdrwidth * 2) + 1, len); goto error; } @@ -380,12 +392,6 @@ /* Is the end of the line there */ if (data[len - 1] != 0xFD) { printk(KERN_INFO "cpia: lost synch\n"); -end = data + len - 1 - 4; -printk("%02X %02X %02X %02X %02X %02X %02X %02X\n", -end[0], end[1], -end[2], end[3], -end[4], end[5], -end[6], end[7]); goto error; } @@ -426,12 +432,6 @@ *f++ = LIMIT(b + y); *f++ = LIMIT(g + y); *f++ = LIMIT(r + y); *f++ = LIMIT(b + y1); *f++ = LIMIT(g + y1); *f++ = LIMIT(r + y1); fp += 6; -/* - f[0] = f[1] = f[2] = *data; - f += 3; - data += 2; - fp += 3; -*/ } } } else { @@ -469,10 +469,11 @@ } nextframe: - if (scratch_left(data) >= 4 && *((__u32 *)data) == 0xFFFFFFFF) { +#ifdef CPIA_DEBUG + printk("cpia: marking as success\n"); +#endif + if (scratch_left(data) >= 4 && *((__u32 *)data) == 0xFFFFFFFF) data += 4; -printk("end of frame found normally\n"); -} frame->grabstate = FRAME_DONE; cpia->curframe = -1; @@ -484,6 +485,9 @@ goto out; error: +#ifdef CPIA_DEBUG + printk("cpia: marking as error\n"); +#endif frame->grabstate = FRAME_ERROR; cpia->curframe = -1; cpia->compress = 0; @@ -493,7 +497,6 @@ wake_up_interruptible(&frame->wq); out: -printk("scanned %d bytes, %d left\n", data - cpia->scratch, scratch_left(data)); /* Grab the remaining */ l = scratch_left(data); memmove(cpia->scratch, data, l); @@ -544,7 +547,7 @@ int i; if (!cpia->streaming) { - printk("oops, not streaming, but interrupt\n"); + printk("cpia: oops, not streaming, but interrupt\n"); return 0; } @@ -554,7 +557,6 @@ /* Copy the data received into our scratch buffer */ len = cpia_compress_isochronous(cpia, sbuf->isodesc); -printk("%d bytes received\n", len); /* If we don't have a frame we're current working on, complain */ if (len) { if (cpia->curframe < 0) @@ -587,7 +589,7 @@ /* Alternate interface 3 is is the biggest frame size */ if (usb_set_interface(cpia->dev, 1, 3) < 0) { - printk("usb_set_interface error\n"); + printk(KERN_ERR "usb_set_interface error\n"); return -EBUSY; } @@ -642,21 +644,7 @@ if (err) printk(KERN_ERR "CPiA USB driver error (%d) on usb_run_isoc\n", err); -#ifdef CPIA_DEBUG - printk("done scheduling\n"); -#endif - -#if 0 - if (usb_cpia_grab_frame(dev, 120) < 0) { - printk(KERN_INFO "cpia_grab_frame error\n"); - return -EBUSY; - } -#endif - cpia->streaming = 1; -#ifdef CPIA_DEBUG - printk("now streaming\n"); -#endif return 0; } @@ -666,21 +654,12 @@ if (!cpia->streaming) return; - cpia->streaming = 0; - /* Turn off continuous grab */ if (usb_cpia_set_grab_mode(cpia->dev, 0) < 0) { printk(KERN_INFO "cpia_set_grab_mode error\n"); return /* -EBUSY */; } -#if 0 - if (usb_cpia_grab_frame(cpia->dev, 0) < 0) { - printk(KERN_INFO "cpia_grab_frame error\n"); - return /* -EBUSY */; - } -#endif - /* Set packet size to 0 */ if (usb_set_interface(cpia->dev, 1, 0) < 0) { printk(KERN_INFO "usb_set_interface error\n"); @@ -691,6 +670,8 @@ usb_kill_isoc(cpia->sbuf[1].isodesc); usb_kill_isoc(cpia->sbuf[0].isodesc); + cpia->streaming = 0; + /* Delete them all */ usb_free_isoc(cpia->sbuf[1].isodesc); usb_free_isoc(cpia->sbuf[0].isodesc); @@ -701,29 +682,23 @@ struct cpia_frame *frame; int width, height; -printk("new frame %d\n", framenum); - if (framenum == -1) { - int i; - for (i = 0; i < CPIA_NUMFRAMES; i++) - if (cpia->frame[i].grabstate == FRAME_READY) - break; - - if (i >= CPIA_NUMFRAMES) { - printk("no frame ready\n"); - return 0; - } - - framenum = i; -printk("using frame %d\n", framenum); - } - - if (cpia->curframe != -1 && cpia->curframe != framenum) + /* If we're not grabbing a frame right now and the other frame is */ + /* ready to be grabbed into, then use it instead */ + if (cpia->curframe == -1) { + if (cpia->frame[(framenum - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES].grabstate == FRAME_READY) + framenum = (framenum - 1 + CPIA_NUMFRAMES) % CPIA_NUMFRAMES; + } else return 0; frame = &cpia->frame[framenum]; width = frame->width; height = frame->height; + frame->grabstate = FRAME_GRABBING; + frame->scanstate = STATE_SCANNING; + + cpia->curframe = framenum; + /* Make sure it's not too big */ if (width > 352) width = 352; @@ -737,7 +712,8 @@ if (usb_cpia_set_roi(cpia->dev, 0, width / 8, 0, height / 4) < 0) return -EBUSY; - if (usb_cpia_set_compression(cpia->dev, cpia->compress ? 1 : 0, 0) < 0) { + if (usb_cpia_set_compression(cpia->dev, cpia->compress ? + COMP_AUTO : COMP_DISABLED, DONT_DECIMATE) < 0) { printk(KERN_INFO "cpia_set_compression error\n"); return -EBUSY; } @@ -746,16 +722,11 @@ cpia->compress = (cpia->compress + 1) % 30; /* Grab the frame */ - if (usb_cpia_upload_frame(cpia->dev, 1) < 0) { + if (usb_cpia_upload_frame(cpia->dev, WAIT_FOR_NEXT_FRAME) < 0) { printk(KERN_INFO "cpia_upload_frame error\n"); return -EBUSY; } - frame->grabstate = FRAME_GRABBING; - frame->scanstate = STATE_SCANNING; - - cpia->curframe = framenum; - return 0; } @@ -862,8 +833,8 @@ b.audios = 0; b.maxwidth = 352; /* CIF */ b.maxheight = 288; /* " */ - b.minwidth = 176; /* QCIF */ - b.minheight = 144; /* " */ + b.minwidth = 8; + b.minheight = 4; if (copy_to_user(arg, &b, sizeof(b))) return -EFAULT; @@ -1065,11 +1036,11 @@ return -EINVAL; case FRAME_READY: case FRAME_GRABBING: + case FRAME_ERROR: redo: do { -printk("enter sleeping\n"); + init_waitqueue_head(&cpia->frame[frame].wq); interruptible_sleep_on(&cpia->frame[frame].wq); -printk("back from sleeping\n"); if (signal_pending(current)) return -EINTR; } while (cpia->frame[frame].grabstate == @@ -1091,8 +1062,9 @@ #ifdef CPIA_DEBUG printk("cpia: finished, synced to frame %d\n", frame); #endif + cpia->frame[frame].grabstate = FRAME_UNUSED; - return cpia_new_frame(cpia, -1); + return 0; } case VIDIOCGFBUF: { @@ -1195,12 +1167,11 @@ struct usb_device *dev = cpia->dev; unsigned char version[4]; - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue) < 0) { - printk(KERN_INFO "cpia: usb_set_configuration failed\n"); - return -EBUSY; - } + /* claim interface 1 */ + usb_driver_claim_interface(&cpia_driver, + &dev->actconfig->interface[1], cpia); - /* Set packet size to 0 */ + /* Set altsetting 0 on interface 1 */ if (usb_set_interface(dev, 1, 0) < 0) { printk(KERN_INFO "usb_set_interface error\n"); return -EBUSY; @@ -1211,7 +1182,7 @@ return -EBUSY; } - printk("cpia: Firmware v%d.%d, VC Hardware v%d.%d\n", + printk(KERN_DEBUG "cpia: Firmware v%d.%d, VC Hardware v%d.%d\n", version[0], version[1], version[2], version[3]); memcpy(&cpia->vdev, &cpia_template, sizeof(cpia_template)); @@ -1234,8 +1205,8 @@ goto error; } - printk("cpia: VP v%d rev %d\n", version[0], version[1]); - printk("cpia: Camera Head ID %04X\n", (version[3] << 8) + version[2]); + printk(KERN_DEBUG "cpia: VP v%d rev %d\n", version[0], version[1]); + printk(KERN_DEBUG "cpia: Camera Head ID %04X\n", (version[3] << 8) + version[2]); /* Turn on continuous grab */ if (usb_cpia_set_grab_mode(dev, 1) < 0) { @@ -1250,13 +1221,14 @@ } /* Set video into CIF mode, and order into YUYV mode */ - if (usb_cpia_set_format(dev, CPIA_CIF, 1, CPIA_YUYV) < 0) { + if (usb_cpia_set_format(dev, FORMAT_CIF, FORMAT_422, + FORMAT_YUYV) < 0) { printk(KERN_INFO "cpia_set_format error\n"); goto error; } /* Turn off compression */ - if (usb_cpia_set_compression(dev, 0, 0) < 0) { + if (usb_cpia_set_compression(dev, COMP_DISABLED, DONT_DECIMATE) < 0) { printk(KERN_INFO "cpia_set_compression error\n"); goto error; } @@ -1267,56 +1239,62 @@ error: video_unregister_device(&cpia->vdev); + usb_driver_release_interface(&cpia_driver, + &dev->actconfig->interface[1]); kfree(cpia); return -EBUSY; } -static int cpia_probe(struct usb_device *dev) +static void * cpia_probe(struct usb_device *dev, unsigned int ifnum) { struct usb_interface_descriptor *interface; struct usb_cpia *cpia; /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) - return -1; + return NULL; - interface = &dev->config[0].interface[0].altsetting[0]; + interface = &dev->actconfig->interface[ifnum].altsetting[0]; /* Is it a CPiA? */ if (dev->descriptor.idVendor != 0x0553) - return -1; + return NULL; if (dev->descriptor.idProduct != 0x0002) - return -1; + return NULL; /* Checking vendor/product should be enough, but what the hell */ if (interface->bInterfaceClass != 0xFF) - return -1; + return NULL; if (interface->bInterfaceSubClass != 0x00) - return -1; + return NULL; /* We found a CPiA */ - printk("USB CPiA camera found\n"); + printk(KERN_INFO "USB CPiA camera found\n"); if ((cpia = kmalloc(sizeof(*cpia), GFP_KERNEL)) == NULL) { - printk("couldn't kmalloc cpia struct\n"); - return -1; + printk(KERN_ERR "couldn't kmalloc cpia struct\n"); + return NULL; } memset(cpia, 0, sizeof(*cpia)); - dev->private = cpia; cpia->dev = dev; - return usb_cpia_configure(cpia); + if (!usb_cpia_configure(cpia)) { + return cpia; + } else return NULL; } -static void cpia_disconnect(struct usb_device *dev) +static void cpia_disconnect(struct usb_device *dev, void *ptr) { - struct usb_cpia *cpia = dev->private; + struct usb_cpia *cpia = (struct usb_cpia *) ptr; video_unregister_device(&cpia->vdev); + + usb_driver_release_interface(&cpia_driver, + &cpia->dev->actconfig->interface[1]); /* Free the memory */ kfree(cpia); diff -u --recursive --new-file v2.3.24/linux/drivers/usb/cpia.h linux/drivers/usb/cpia.h --- v2.3.24/linux/drivers/usb/cpia.h Sat Oct 9 11:47:50 1999 +++ linux/drivers/usb/cpia.h Mon Nov 1 11:30:29 1999 @@ -50,15 +50,30 @@ #define USB_REQ_CPIA_GRAB_FRAME 0xC1 #define USB_REQ_CPIA_UPLOAD_FRAME 0xC2 +#define WAIT_FOR_NEXT_FRAME 0 +#define FORCE_FRAME_UPLOAD 1 #define USB_REQ_CPIA_SET_GRAB_MODE 0xC3 #define USB_REQ_CPIA_INIT_STREAM_CAP 0xC4 #define USB_REQ_CPIA_FINI_STREAM_CAP 0xC5 #define USB_REQ_CPIA_START_STREAM_CAP 0xC6 #define USB_REQ_CPIA_END_STREAM_CAP 0xC7 #define USB_REQ_CPIA_SET_FORMAT 0xC8 +#define FORMAT_QCIF 0 +#define FORMAT_CIF 1 +#define FORMAT_YUYV 0 +#define FORMAT_UYVY 1 +#define FORMAT_420 0 +#define FORMAT_422 1 #define USB_REQ_CPIA_SET_ROI 0xC9 #define USB_REQ_CPIA_SET_COMPRESSION 0xCA +#define COMP_DISABLED 0 +#define COMP_AUTO 1 +#define COMP_MANUAL 2 +#define DONT_DECIMATE 0 +#define DECIMATE 1 #define USB_REQ_CPIA_SET_COMPRESSION_TARGET 0xCB +#define TARGET_QUALITY 0 +#define TARGET_FRAMERATE 1 #define USB_REQ_CPIA_SET_YUV_THRESH 0xCC #define USB_REQ_CPIA_SET_COMPRESSION_PARAMS 0xCD #define USB_REQ_CPIA_DISCARD_FRAME 0xCE @@ -71,12 +86,6 @@ #define USB_REQ_CPIA_ABORT_STREAM 0xE9 #define USB_REQ_CPIA_DOWNLOAD_DRAM 0xEA /* #define USB_REQ_CPIA_NULL_CMD 0x?? */ - -#define CPIA_QCIF 0 -#define CPIA_CIF 1 - -#define CPIA_YUYV 0 -#define CPIA_UYVY 1 #define STREAM_BUF_SIZE (PAGE_SIZE * 4) /* #define STREAM_BUF_SIZE (FRAMES_PER_DESC * FRAME_SIZE_PER_DESC) */ diff -u --recursive --new-file v2.3.24/linux/drivers/usb/ezusb.c linux/drivers/usb/ezusb.c --- v2.3.24/linux/drivers/usb/ezusb.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/usb/ezusb.c Thu Oct 28 12:53:26 1999 @@ -968,7 +968,7 @@ /* --------------------------------------------------------------------- */ -static int ezusb_probe(struct usb_device *usbdev) +static void * ezusb_probe(struct usb_device *usbdev, unsigned int ifnum) { struct ezusb *ez = &ezusb[0]; struct usb_interface_descriptor *interface; @@ -982,56 +982,49 @@ /* the 1234:5678 is just a self assigned test ID */ if ((usbdev->descriptor.idVendor != 0x0547 || usbdev->descriptor.idProduct != 0x2131) && (usbdev->descriptor.idVendor != 0x1234 || usbdev->descriptor.idProduct != 0x5678)) - return -1; + return NULL; /* We don't handle multiple configurations */ if (usbdev->descriptor.bNumConfigurations != 1) - return -1; + return NULL; #if 0 /* We don't handle multiple interfaces */ - if (usbdev->config[0].bNumInterfaces != 1) - return -1; + if (usbdev->actconfig.bNumInterfaces != 1) + return NULL; #endif down(&ez->mutex); if (ez->usbdev) { up(&ez->mutex); printk(KERN_INFO "ezusb: device already used\n"); - return -1; + return NULL; } ez->usbdev = usbdev; - usbdev->private = ez; - if (usb_set_configuration(usbdev, usbdev->config[0].bConfigurationValue) < 0) { - printk(KERN_ERR "ezusb: set_configuration failed\n"); - goto err; - } - interface = &usbdev->config[0].interface[0].altsetting[1]; - if (usb_set_interface(usbdev, 0, 1) < 0) { + interface = &usbdev->actconfig->interface[ifnum].altsetting[1]; + if (usb_set_interface(usbdev, ifnum, 1) < 0) { printk(KERN_ERR "ezusb: set_interface failed\n"); goto err; } up(&ez->mutex); MOD_INC_USE_COUNT; - return 0; + return ez; err: up(&ez->mutex); ez->usbdev = NULL; - usbdev->private = NULL; - return -1; + return NULL; } -static void ezusb_disconnect(struct usb_device *usbdev) +static void ezusb_disconnect(struct usb_device *usbdev, void *ptr) { - struct ezusb *ez = (struct ezusb *)usbdev->private; + struct ezusb *ez = (struct ezusb *) ptr; down(&ez->mutex); destroy_all_async(ez); ez->usbdev = NULL; up(&ez->mutex); wake_up(&ez->wait); - usbdev->private = NULL; MOD_DEC_USE_COUNT; } diff -u --recursive --new-file v2.3.24/linux/drivers/usb/hp_scanner.c linux/drivers/usb/hp_scanner.c --- v2.3.24/linux/drivers/usb/hp_scanner.c Fri Oct 22 13:21:51 1999 +++ linux/drivers/usb/hp_scanner.c Thu Oct 28 12:53:26 1999 @@ -217,8 +217,8 @@ return read_count; } -static int -probe_scanner(struct usb_device *dev) +static void * +probe_scanner(struct usb_device *dev, unsigned int ifnum) { struct hpscan_usb_data *hps = &hpscan; @@ -228,41 +228,36 @@ * soon. */ if (dev->descriptor.idVendor != 0x3f0 ) { printk(KERN_INFO "Scanner is not an HP Scanner.\n"); - return -1; + return NULL; } if (dev->descriptor.idProduct != 0x101 && /* HP 4100C */ dev->descriptor.idProduct != 0x202 && /* HP 5100C */ dev->descriptor.idProduct != 0x601) { /* HP 6300C */ printk(KERN_INFO "Scanner model not supported/tested.\n"); - return -1; + return NULL; } printk(KERN_DEBUG "USB Scanner found at address %d\n", dev->devnum); - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { - printk(KERN_DEBUG "Failed to set configuration\n"); - return -1; - } - hps->present = 1; hps->hpscan_dev = dev; if (!(hps->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) { - return -ENOMEM; + return NULL; } if (!(hps->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) { - return -ENOMEM; + return NULL; } - return 0; + return hps; } static void -disconnect_scanner(struct usb_device *dev) +disconnect_scanner(struct usb_device *dev, void *ptr) { - struct hpscan_usb_data *hps = &hpscan; + struct hpscan_usb_data *hps = (struct hpscan_usb_data *) ptr; if (hps->isopen) { /* better let it finish - the release will do whats needed */ @@ -272,7 +267,6 @@ kfree(hps->ibuf); kfree(hps->obuf); - dev->private = NULL; /* just in case */ hps->present = 0; } diff -u --recursive --new-file v2.3.24/linux/drivers/usb/hub.c linux/drivers/usb/hub.c --- v2.3.24/linux/drivers/usb/hub.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/usb/hub.c Thu Oct 28 12:53:26 1999 @@ -22,7 +22,6 @@ /* Wakes up khubd */ static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED; -static spinlock_t hub_list_lock = SPIN_LOCK_UNLOCKED; static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */ static LIST_HEAD(hub_list); /* List containing all of the hubs (for cleanup) */ @@ -105,9 +104,6 @@ struct usb_hub_status *hubsts; int i; - /* Set it to the first configuration */ - usb_set_configuration(dev, dev->config[0].bConfigurationValue); - /* Get the length first */ if (usb_get_hub_descriptor(dev, buffer, 4)) return -1; @@ -188,7 +184,7 @@ return 0; } -static int hub_probe(struct usb_device *dev) +static void * hub_probe(struct usb_device *dev, unsigned int i) { struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; @@ -196,60 +192,50 @@ unsigned long flags; int ret; - /* We don't handle multi-config hubs */ - if (dev->descriptor.bNumConfigurations != 1) - return -1; - - /* We don't handle multi-interface hubs */ - if (dev->config[0].bNumInterfaces != 1) - return -1; - - interface = &dev->config[0].interface[0].altsetting[0]; + interface = &dev->actconfig->interface[i].altsetting[0]; /* Is it a hub? */ if (interface->bInterfaceClass != USB_CLASS_HUB) - return -1; + return NULL; /* Some hubs have a subclass of 1, which AFAICT according to the */ /* specs is not defined, but it works */ if ((interface->bInterfaceSubClass != 0) && (interface->bInterfaceSubClass != 1)) - return -1; + return NULL; /* Multiple endpoints? What kind of mutant ninja-hub is this? */ if (interface->bNumEndpoints != 1) - return -1; + return NULL; endpoint = &interface->endpoint[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & USB_DIR_IN)) - return -1; + return NULL; /* If it's not an interrupt endpoint, we'd better punt! */ if ((endpoint->bmAttributes & 3) != 3) - return -1; + return NULL; /* We found a hub */ printk(KERN_INFO "USB hub found\n"); if ((hub = kmalloc(sizeof(*hub), GFP_KERNEL)) == NULL) { printk(KERN_ERR "couldn't kmalloc hub struct\n"); - return -1; + return NULL; } memset(hub, 0, sizeof(*hub)); - dev->private = hub; - INIT_LIST_HEAD(&hub->event_list); hub->dev = dev; /* Record the new hub's existence */ - spin_lock_irqsave(&hub_list_lock, flags); + spin_lock_irqsave(&hub_event_lock, flags); INIT_LIST_HEAD(&hub->hub_list); list_add(&hub->hub_list, &hub_list); - spin_unlock_irqrestore(&hub_list_lock, flags); + spin_unlock_irqrestore(&hub_event_lock, flags); if (usb_hub_configure(hub) >= 0) { hub->irqpipe = usb_rcvctrlpipe(dev, endpoint->bEndpointAddress); @@ -258,20 +244,32 @@ hub, &hub->irq_handle); if (ret) { printk (KERN_WARNING "usb-hub: usb_request_irq failed (0x%x)\n", ret); - /* FIXME: need to free but first clean up its list. */ - return -1; + /* free hub, but first clean up its list. */ + spin_lock_irqsave(&hub_event_lock, flags); + + /* Delete it and then reset it */ + list_del(&hub->event_list); + INIT_LIST_HEAD(&hub->event_list); + list_del(&hub->hub_list); + INIT_LIST_HEAD(&hub->hub_list); + + spin_unlock_irqrestore(&hub_event_lock, flags); + + kfree(hub); + + return NULL; } /* Wake up khubd */ wake_up(&khubd_wait); } - return 0; + return hub; } -static void hub_disconnect(struct usb_device *dev) +static void hub_disconnect(struct usb_device *dev, void *ptr) { - struct usb_hub *hub = dev->private; + struct usb_hub *hub = ptr; unsigned long flags; spin_lock_irqsave(&hub_event_lock, flags); diff -u --recursive --new-file v2.3.24/linux/drivers/usb/inits.h linux/drivers/usb/inits.h --- v2.3.24/linux/drivers/usb/inits.h Fri Oct 22 13:21:51 1999 +++ linux/drivers/usb/inits.h Thu Oct 28 10:20:36 1999 @@ -4,6 +4,7 @@ void usb_hub_cleanup(void); int usb_kbd_init(void); void usb_major_init(void); +void usb_major_cleanup(void); void usb_mouse_cleanup(void); int usb_hp_scanner_init(void); void usb_hp_scanner_cleanup(void); diff -u --recursive --new-file v2.3.24/linux/drivers/usb/keyboard.c linux/drivers/usb/keyboard.c --- v2.3.24/linux/drivers/usb/keyboard.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/usb/keyboard.c Thu Oct 28 12:53:26 1999 @@ -45,8 +45,8 @@ extern unsigned char usb_kbd_map[]; -static int usb_kbd_probe(struct usb_device *dev); -static void usb_kbd_disconnect(struct usb_device *dev); +static void * usb_kbd_probe(struct usb_device *dev, unsigned int i); +static void usb_kbd_disconnect(struct usb_device *dev, void *ptr); static void usb_kbd_repeat(unsigned long dummy); static LIST_HEAD(usb_kbd_list); @@ -190,25 +190,22 @@ return 1; } -static int -usb_kbd_probe(struct usb_device *dev) +static void * +usb_kbd_probe(struct usb_device *dev, unsigned int i) { struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct usb_keyboard *kbd; int ret; - if (dev->descriptor.bNumConfigurations < 1) - return -1; - - interface = &dev->config[0].interface[0].altsetting[0]; + interface = &dev->actconfig->interface[i].altsetting[0]; endpoint = &interface->endpoint[0]; if(interface->bInterfaceClass != 3 || interface->bInterfaceSubClass != 1 || interface->bInterfaceProtocol != 1) { - return -1; + return NULL; } printk(KERN_INFO "USB HID boot protocol keyboard detected.\n"); @@ -218,12 +215,7 @@ { memset(kbd, 0, sizeof(*kbd)); kbd->dev = dev; - dev->private = kbd; - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { - printk (KERN_INFO " Failed usb_set_configuration: kbd\n"); - goto probe_err; - } usb_set_protocol(dev, 0); usb_set_idle(dev, 0, 0); @@ -238,23 +230,22 @@ list_add(&kbd->list, &usb_kbd_list); - return 0; + return kbd; } probe_err: if (kbd) kfree (kbd); - return -1; + return NULL; } static void -usb_kbd_disconnect(struct usb_device *dev) +usb_kbd_disconnect(struct usb_device *dev, void *ptr) { - struct usb_keyboard *kbd = (struct usb_keyboard*) dev->private; + struct usb_keyboard *kbd = (struct usb_keyboard*) ptr; if (kbd) { usb_release_irq(dev, kbd->irq_handler, kbd->irqpipe); - dev->private = NULL; list_del(&kbd->list); del_timer(&kbd->repeat_timer); kfree(kbd); diff -u --recursive --new-file v2.3.24/linux/drivers/usb/mouse.c linux/drivers/usb/mouse.c --- v2.3.24/linux/drivers/usb/mouse.c Fri Oct 15 15:25:14 1999 +++ linux/drivers/usb/mouse.c Thu Oct 28 12:53:26 1999 @@ -316,51 +316,38 @@ fasync_mouse, }; -static int mouse_probe(struct usb_device *dev) +static void* mouse_probe(struct usb_device *dev, unsigned int i) { struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct mouse_state *mouse = &static_mouse_state; int ret; - /* We don't handle multi-config mice */ - if (dev->descriptor.bNumConfigurations != 1) - return -1; - - /* We don't handle multi-interface mice */ - if (dev->config[0].bNumInterfaces != 1) - return -1; - /* Is it a mouse interface? */ - interface = &dev->config[0].interface[0].altsetting[0]; + interface = &dev->actconfig->interface[i].altsetting[0]; if (interface->bInterfaceClass != 3) - return -1; + return NULL; if (interface->bInterfaceSubClass != 1) - return -1; + return NULL; if (interface->bInterfaceProtocol != 2) - return -1; + return NULL; /* Multiple endpoints? What kind of mutant ninja-mouse is this? */ if (interface->bNumEndpoints != 1) - return -1; + return NULL; endpoint = &interface->endpoint[0]; /* Output endpoint? Curiousier and curiousier.. */ if (!(endpoint->bEndpointAddress & 0x80)) - return -1; + return NULL; /* If it's not an interrupt endpoint, we'd better punt! */ if ((endpoint->bmAttributes & 3) != 3) - return -1; + return NULL; printk("USB mouse found\n"); - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { - printk (KERN_INFO " Failed usb_set_configuration: mouse\n"); - return -1; - } - /* these are used to request the irq when the mouse is opened */ mouse->dev = dev; mouse->bEndpointAddress = endpoint->bEndpointAddress; @@ -379,17 +366,17 @@ NULL, &mouse->irq_handle); if (ret) { printk (KERN_WARNING "usb-mouse: usb_request_irq failed (0x%x)\n", ret); - return ret; + return NULL; } mouse->suspended = 0; } - return 0; + return mouse; } -static void mouse_disconnect(struct usb_device *dev) +static void mouse_disconnect(struct usb_device *dev, void *ptr) { - struct mouse_state *mouse = &static_mouse_state; + struct mouse_state *mouse = ptr; /* stop the usb interrupt transfer */ if (mouse->present) { @@ -402,7 +389,7 @@ /* this might need work */ mouse->present = 0; - printk("Mouse disconnected\n"); + printk("USB Mouse disconnected\n"); } static struct usb_driver mouse_driver = { diff -u --recursive --new-file v2.3.24/linux/drivers/usb/ohci-hcd.c linux/drivers/usb/ohci-hcd.c --- v2.3.24/linux/drivers/usb/ohci-hcd.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/usb/ohci-hcd.c Thu Oct 28 10:45:51 1999 @@ -1540,8 +1540,8 @@ # endif while(!list_empty(&ohci_hcd_list)) { ohci = list_entry(ohci_hcd_list.next, struct ohci, ohci_hcd_list); - list_del(ohci->ohci_hcd_list); - INIT_LIST_HEAD(ohci->ohci_hcd_list); + list_del(&ohci->ohci_hcd_list); + INIT_LIST_HEAD(&ohci->ohci_hcd_list); release_ohci(ohci); } } diff -u --recursive --new-file v2.3.24/linux/drivers/usb/printer.c linux/drivers/usb/printer.c --- v2.3.24/linux/drivers/usb/printer.c Fri Oct 22 13:21:51 1999 +++ linux/drivers/usb/printer.c Thu Oct 28 12:53:26 1999 @@ -254,9 +254,10 @@ return read_count; } -static int printer_probe(struct usb_device *dev) +static void * printer_probe(struct usb_device *dev, unsigned int ifnum) { struct usb_interface_descriptor *interface; + struct pp_usb_data *pp; int i; /* @@ -265,29 +266,29 @@ if ((dev->descriptor.bDeviceClass != USB_CLASS_PRINTER && dev->descriptor.bDeviceClass != 0) || dev->descriptor.bNumConfigurations != 1 || - dev->config[0].bNumInterfaces != 1) { - return -1; + dev->actconfig->bNumInterfaces != 1) { + return NULL; } - interface = &dev->config[0].interface[0].altsetting[0]; + interface = &dev->actconfig->interface[ifnum].altsetting[0]; /* Let's be paranoid (for the moment). */ if (interface->bInterfaceClass != USB_CLASS_PRINTER || interface->bInterfaceSubClass != 1 || (interface->bInterfaceProtocol != 2 && interface->bInterfaceProtocol != 1) || interface->bNumEndpoints > 2) { - return -1; + return NULL; } /* Does this (these) interface(s) support bulk transfers? */ if ((interface->endpoint[0].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) { - return -1; + return NULL; } if ((interface->bNumEndpoints > 1) && ((interface->endpoint[1].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK)) { - return -1; + return NULL; } /* @@ -299,7 +300,7 @@ (interface->bNumEndpoints > 1 && (interface->endpoint[1].bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT)) { - return -1; + return NULL; } for (i=0; i= MAX_PRINTERS) { printk("No minor table space available for USB Printer\n"); - return -1; + return NULL; } printk(KERN_INFO "USB Printer found at address %d\n", dev->devnum); - if (!(dev->private = kmalloc(sizeof(struct pp_usb_data), GFP_KERNEL))) { + if (!(pp = kmalloc(sizeof(struct pp_usb_data), GFP_KERNEL))) { printk(KERN_DEBUG "usb_printer: no memory!\n"); - return -1; + return NULL; } - memset(dev->private, 0, sizeof(struct pp_usb_data)); - minor_data[i] = PPDATA(dev->private); + memset(pp, 0, sizeof(struct pp_usb_data)); + minor_data[i] = PPDATA(pp); minor_data[i]->minor = i; minor_data[i]->pusb_dev = dev; minor_data[i]->maxout = (BIG_BUF_SIZE > PAGE_SIZE) ? PAGE_SIZE : BIG_BUF_SIZE; @@ -342,11 +343,6 @@ interface->endpoint[minor_data[i]->bulk_in_index].wMaxPacketSize; } - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { - printk(KERN_INFO " Failed usb_set_configuration: printer\n"); - return -1; - } - printk(KERN_INFO "USB Printer Summary:\n"); printk(KERN_INFO "index=%d, maxout=%d, noinput=%d\n", i, minor_data[i]->maxout, minor_data[i]->noinput); @@ -374,19 +370,19 @@ printk(KERN_INFO " USB Printer ID is %s\n", &ieee_id[2]); } - status = printer_read_status(PPDATA(dev->private)); + status = printer_read_status(PPDATA(pp)); printk(KERN_INFO " Status is %s,%s,%s\n", (status & LP_PSELECD) ? "Selected" : "Not Selected", (status & LP_POUTPA) ? "No Paper" : "Paper", (status & LP_PERRORP) ? "No Error" : "Error"); } #endif - return 0; + return pp; } -static void printer_disconnect(struct usb_device *dev) +static void printer_disconnect(struct usb_device *dev, void *ptr) { - struct pp_usb_data *pp = dev->private; + struct pp_usb_data *pp = ptr; if (pp->isopen) { /* better let it finish - the release will do whats needed */ @@ -395,7 +391,6 @@ } minor_data[pp->minor] = NULL; kfree(pp); - dev->private = NULL; /* just in case */ } static struct file_operations usb_printer_fops = { diff -u --recursive --new-file v2.3.24/linux/drivers/usb/proc_usb.c linux/drivers/usb/proc_usb.c --- v2.3.24/linux/drivers/usb/proc_usb.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/usb/proc_usb.c Thu Oct 28 14:34:46 1999 @@ -62,8 +62,8 @@ static char *format_topo = -/* T: Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd If#=ddd MxCh=dd Driver=%s */ - "T: Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s If#=%3d MxCh=%2d Driver=%s\n"; +/* T: Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ + "T: Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; static char *format_bandwidth = /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ @@ -83,7 +83,7 @@ static char *format_iface = /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx */ - "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n"; + "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; static char *format_endpt = /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms */ @@ -161,9 +161,12 @@ return 0; } -static int usb_dump_interface_descriptor (const struct usb_interface_descriptor *desc, - char *buf, int *len) +static int usb_dump_interface_descriptor (const struct usb_interface *iface, + int setno, char *buf, int *len) { + struct usb_interface_descriptor *desc = + &iface->altsetting[setno]; + *len += sprintf (buf + *len, format_iface, desc->bInterfaceNumber, desc->bAlternateSetting, @@ -171,22 +174,25 @@ desc->bInterfaceClass, class_decode (desc->bInterfaceClass), desc->bInterfaceSubClass, - desc->bInterfaceProtocol + desc->bInterfaceProtocol, + iface->driver ? iface->driver->name : "(none)" ); return (*len >= DUMP_LIMIT) ? -1 : 0; } -static int usb_dump_interface (const struct usb_interface_descriptor *interface, - char *buf, int *len) +static int usb_dump_interface (const struct usb_interface *iface, + int setno, char *buf, int *len) { int i; + struct usb_interface_descriptor *desc = + &iface->altsetting[setno]; - if (usb_dump_interface_descriptor (interface, buf, len) < 0) + if (usb_dump_interface_descriptor (iface, setno, buf, len) < 0) return -1; - for (i = 0; i < interface->bNumEndpoints; i++) { - if (usb_dump_endpoint (interface->endpoint + i, buf, len) < 0) + for (i = 0; i < desc->bNumEndpoints; i++) { + if (usb_dump_endpoint (desc->endpoint + i, buf, len) < 0) return -1; } @@ -234,7 +240,7 @@ break; for (j = 0; j < interface->num_altsetting; j++) - if (usb_dump_interface (interface->altsetting + j, buf, len) < 0) + if (usb_dump_interface (interface, j, buf, len) < 0) return -1; } @@ -349,9 +355,7 @@ level, parent_devnum, index, count, usbdev->devnum, usbdev->slow ? "1.5" : "12 ", - usbdev->ifnum, usbdev->maxchild, - usbdev->driver ? usbdev->driver->name : - (level == 0) ? "(root hub)" : "(none)" + usbdev->maxchild ); /* * level = topology-tier level; @@ -1036,21 +1040,21 @@ return -1; } - driversdir = create_proc_entry ("drivers", 0, usbdir); + driversdir = create_proc_read_entry("drivers", 0, usbdir, + usb_driver_list_dump, NULL); if (!driversdir) { printk ("proc_usb: cannot create /proc/bus/usb/drivers entry\n"); proc_usb_cleanup (); return -1; } - driversdir->read_proc = usb_driver_list_dump; - devicesdir = create_proc_entry ("devices", 0, usbdir); + devicesdir = create_proc_read_entry ("devices", 0, usbdir, + usb_bus_list_dump_devices, NULL); if (!devicesdir) { printk ("proc_usb: cannot create /proc/bus/usb/devices entry\n"); proc_usb_cleanup (); return -1; } - devicesdir->read_proc = usb_bus_list_dump_devices; return 0; } diff -u --recursive --new-file v2.3.24/linux/drivers/usb/usb-core.c linux/drivers/usb/usb-core.c --- v2.3.24/linux/drivers/usb/usb-core.c Fri Oct 15 15:25:14 1999 +++ linux/drivers/usb/usb-core.c Thu Oct 28 10:20:36 1999 @@ -83,6 +83,7 @@ */ void cleanup_drivers(void) { + usb_major_cleanup(); #ifdef CONFIG_USB_PROC proc_usb_cleanup (); #endif diff -u --recursive --new-file v2.3.24/linux/drivers/usb/usb-serial.c linux/drivers/usb/usb-serial.c --- v2.3.24/linux/drivers/usb/usb-serial.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/usb/usb-serial.c Thu Oct 28 12:53:26 1999 @@ -67,8 +67,8 @@ /* into dynamically creating them at insertion time. */ -static int usb_serial_probe(struct usb_device *dev); -static void usb_serial_disconnect(struct usb_device *dev); +static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum); +static void usb_serial_disconnect(struct usb_device *dev, void *ptr); typedef enum { unknown = 0, @@ -441,7 +441,7 @@ } -static int usb_serial_probe(struct usb_device *dev) +static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) { struct usb_serial_state *serial; struct usb_interface_descriptor *interface; @@ -466,18 +466,13 @@ } if (type == unknown) - return (-1); + return NULL; printk (KERN_INFO "USB serial converter detected.\n"); - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { - printk (KERN_INFO " Failed usb_set_configuration: serial\n"); - return (-1); - } - if (0>(serial_num = Get_Free_Serial())) { debug_info("USB Serial: Too many devices connected\n"); - return (-1); + return NULL; } serial = &serial_state_table[serial_num]; @@ -485,10 +480,9 @@ memset(serial, 0, sizeof(serial)); serial->dev = dev; serial->type = type; - dev->private = serial; /* we should have 1 bulk in, 1 bulk out, and 1 interrupt in endpoints */ - interface = &dev->config[0].interface[0].altsetting[0]; + interface = &dev->actconfig->interface[ifnum].altsetting[0]; for (i = 0; i < interface->bNumEndpoints; ++i) { endpoint = &interface->endpoint[i]; @@ -564,7 +558,7 @@ serial->present = 1; MOD_INC_USE_COUNT; - return (0); + return serial; probe_error: if (serial) { @@ -575,13 +569,13 @@ if (serial->interrupt_in_buffer) kfree (serial->interrupt_in_buffer); } - return (-1); + return NULL; } -static void usb_serial_disconnect(struct usb_device *dev) +static void usb_serial_disconnect(struct usb_device *dev, void *ptr) { - struct usb_serial_state *serial = (struct usb_serial_state *)dev->private; + struct usb_serial_state *serial = (struct usb_serial_state *) ptr; if (serial) { if (!serial->present) { @@ -610,7 +604,6 @@ serial->present = 0; serial->active = 0; } - dev->private = NULL; MOD_DEC_USE_COUNT; diff -u --recursive --new-file v2.3.24/linux/drivers/usb/usb.c linux/drivers/usb/usb.c --- v2.3.24/linux/drivers/usb/usb.c Fri Oct 22 13:21:51 1999 +++ linux/drivers/usb/usb.c Thu Oct 28 12:53:26 1999 @@ -3,6 +3,8 @@ * * (C) Copyright Linus Torvalds 1999 * (C) Copyright Johannes Erdfelt 1999 + * (C) Copyright Andreas Gal 1999 + * (C) Copyright Gregory P. Smith 1999 * * NOTE! This is not actually a driver at all, rather this is * just a collection of helper routines that implement the @@ -27,9 +29,12 @@ #include "usb.h" -static int usb_find_driver(struct usb_device *); +/* + * Prototypes for the device driver probing/loading functions + */ +static void usb_find_drivers(struct usb_device *); +static int usb_find_interface_driver(struct usb_device *, unsigned int); static void usb_check_support(struct usb_device *); -static void usb_driver_purge(struct usb_driver *, struct usb_device *); /* * We have a per-interface "registered driver" list. @@ -37,6 +42,8 @@ static LIST_HEAD(usb_driver_list); static LIST_HEAD(usb_bus_list); +static struct usb_busmap busmap; + static struct usb_driver *usb_minors[16]; int usb_register(struct usb_driver *new_driver) @@ -70,6 +77,44 @@ return 0; } +/* + * This function is part of a depth-first search down the device tree, + * removing any instances of a device driver. + */ +static void usb_drivers_purge(struct usb_driver *driver,struct usb_device *dev) +{ + int i; + + if (!dev) { + printk(KERN_ERR "usbcore: null device being purged!!!\n"); + return; + } + + for (i=0; ichildren[i]) + usb_drivers_purge(driver, dev->children[i]); + + if (!dev->actconfig) + return; + + for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + struct usb_interface *interface = &dev->actconfig->interface[i]; + + if (interface->driver == driver) { + driver->disconnect(dev, interface->private_data); + usb_driver_release_interface(driver, interface); + /* + * This will go through the list looking for another + * driver that can handle the device + */ + usb_find_interface_driver(dev, i); + } + } +} + +/* + * Unlink a driver from the driver list when it is unloaded + */ void usb_deregister(struct usb_driver *driver) { struct list_head *tmp; @@ -89,45 +134,10 @@ struct usb_bus *bus = list_entry(tmp,struct usb_bus,bus_list); tmp = tmp->next; - usb_driver_purge(driver, bus->root_hub); + usb_drivers_purge(driver, bus->root_hub); } } -/* - * This function is part of a depth-first search down the device tree, - * removing any instances of a device driver. - */ -static void usb_driver_purge(struct usb_driver *driver,struct usb_device *dev) -{ - int i; - - if (!dev) { - printk(KERN_ERR "usbcore: null device being purged!!!\n"); - return; - } - - for (i=0; ichildren[i]) - usb_driver_purge(driver, dev->children[i]); - - /* now we check this device */ - if (dev->driver == driver) { - /* - * Note: this is not the correct way to do this, this - * uninitializes and reinitializes EVERY driver - */ - printk(KERN_INFO "disconnect driverless device %d\n", - dev->devnum); - dev->driver->disconnect(dev); - dev->driver = NULL; - - /* - * This will go back through the list looking for a driver - * that can handle the device - */ - usb_find_driver(dev); - } -} /* * calc_bus_time: @@ -222,6 +232,7 @@ bus->op = op; bus->root_hub = NULL; bus->hcpriv = NULL; + bus->busnum = -1; bus->bandwidth_allocated = 0; bus->bandwidth_int_reqs = 0; bus->bandwidth_isoc_reqs = 0; @@ -241,16 +252,27 @@ void usb_register_bus(struct usb_bus *bus) { + int busnum; + + busnum = find_next_zero_bit(busmap.busmap, USB_MAXBUS, 1); + if (busnum < USB_MAXBUS) { + set_bit(busnum, busmap.busmap); + bus->busnum = busnum; + } else + printk(KERN_INFO "usb: too many bus'\n"); + proc_usb_add_bus(bus); /* Add it to the list of buses */ list_add(&bus->bus_list, &usb_bus_list); - printk("New USB bus registered\n"); + printk("New USB bus registered, assigned bus number %d\n", bus->busnum); } void usb_deregister_bus(struct usb_bus *bus) { + printk("usbcore: USB bus %d deregistered\n", bus->busnum); + /* * NOTE: make sure that all the devices are removed by the * controller code, as well as having it call this when cleaning @@ -259,6 +281,8 @@ list_del(&bus->bus_list); proc_usb_remove_bus(bus); + + clear_bit(bus->busnum, busmap.busmap); } /* @@ -278,37 +302,123 @@ if (dev->children[i]) usb_check_support(dev->children[i]); + if (!dev->actconfig) + return; + /* now we check this device */ - if (!dev->driver && dev->devnum > 0) - usb_find_driver(dev); + if (dev->devnum > 0) + for (i = 0; i < dev->actconfig->bNumInterfaces; i++) + usb_find_interface_driver(dev, i); +} + + +/* + * This is intended to be used by usb device drivers that need to + * claim more than one interface on a device at once when probing + * (audio and acm are good examples). No device driver should have + * to mess with the internal usb_interface or usb_device structure + * members. + */ +void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv) +{ + if (!iface || !driver) + return; + + printk(KERN_DEBUG "usbcore: %s driver claimed interface %p\n", driver->name, iface); + + iface->driver = driver; + iface->private_data = priv; +} /* usb_driver_claim_interface() */ + +/* + * This should be used by drivers to check other interfaces to see if + * they are available or not. + */ +int usb_interface_claimed(struct usb_interface *iface) +{ + if (!iface) + return 0; + + return (iface->driver != NULL); +} /* usb_interface_claimed() */ + +/* + * This should be used by drivers to release their claimed interfaces + */ +void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface) +{ + /* this should never happen, don't release something that's not ours */ + if (iface->driver != driver || !iface) + return; + + iface->driver = NULL; + iface->private_data = NULL; } /* * This entrypoint gets called for each new device. * * We now walk the list of registered USB drivers, - * looking for one that will accept this device as - * his.. + * looking for one that will accept this interface. + * + * The probe return value is changed to be a private pointer. This way + * the drivers don't have to dig around in our structures to set the + * private pointer if they only need one interface. + * + * Returns: 0 if a driver accepted the interface, -1 otherwise */ -static int usb_find_driver(struct usb_device *dev) +static int usb_find_interface_driver(struct usb_device *dev, unsigned ifnum) { struct list_head *tmp = usb_driver_list.next; - - while (tmp != &usb_driver_list) { - struct usb_driver *driver = list_entry(tmp, struct usb_driver, - driver_list); - tmp = tmp->next; - if (driver->probe(dev)) - continue; - dev->driver = driver; - return 1; + struct usb_interface *interface; + + if ((!dev) || (ifnum >= dev->actconfig->bNumInterfaces)) { + printk(KERN_ERR "usb-core: bad find_interface_driver params\n"); + return -1; } - /* - * Ok, no driver accepted the device, so show the info - * for debugging.. - */ - return 0; + interface = &dev->actconfig->interface[ifnum]; + + if (usb_interface_claimed(interface)) + return -1; + + while (tmp != &usb_driver_list) { + void *private; + struct usb_driver *driver = list_entry(tmp, struct usb_driver, + driver_list); + + tmp = tmp->next; + if (!(private = driver->probe(dev, ifnum))) + continue; + usb_driver_claim_interface(driver, interface, private); + + return 0; + } + + return -1; +} + +/* + * This entrypoint gets called for each new device. + * + * All interfaces are scanned for matching drivers. + */ +static void usb_find_drivers(struct usb_device *dev) +{ + unsigned ifnum; + unsigned rejected = 0; + + for (ifnum = 0; ifnum < dev->actconfig->bNumInterfaces; ifnum++) { + /* if this interface hasn't already been claimed */ + if (!usb_interface_claimed(dev->actconfig->interface)) { + if (usb_find_interface_driver(dev, ifnum)) + rejected++; + } + } + + if (rejected) { + printk(KERN_DEBUG "usbcore: unhandled interfaces on device.\n"); + } } /* @@ -631,6 +741,7 @@ { dev->devnum = -1; dev->slow = 0; + dev->actconfig = NULL; } /* @@ -646,10 +757,18 @@ *pdev = NULL; - printk("USB disconnect on device %d\n", dev->devnum); + printk("usbcore: USB disconnect on device %d\n", dev->devnum); - if (dev->driver) - dev->driver->disconnect(dev); + if (dev->actconfig) { + for (i = 0; i < dev->actconfig->bNumInterfaces; i++) { + struct usb_interface *interface = &dev->actconfig->interface[i]; + struct usb_driver *driver = interface->driver; + if (driver) { + driver->disconnect(dev, interface->private_data); + usb_driver_release_interface(driver, interface); + } + } + } /* Free up all the children.. */ for (i = 0; i < USB_MAXCHILDREN; i++) { @@ -894,7 +1013,6 @@ if (err) return err; - dev->ifnum = interface; dev->actconfig->interface[interface].act_altsetting = alternate; usb_set_maxpacket(dev); return 0; @@ -1113,9 +1231,14 @@ } dev->actconfig = dev->config; - dev->ifnum = 0; usb_set_maxpacket(dev); + /* we set the default configuration here */ + if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) { + printk(KERN_ERR "usbcore: failed to set default configuration\n"); + return -1; + } + usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer); usb_show_string(dev, "Product", dev->descriptor.iProduct); usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber); @@ -1123,14 +1246,8 @@ /* now that the basic setup is over, add a /proc/bus/usb entry */ proc_usb_add_device(dev); - if (!usb_find_driver(dev)) { - /* - * Ok, no driver accepted the device, so show the info for - * debugging - */ - printk(KERN_DEBUG "Unknown new USB device:\n"); - usb_show_device(dev); - } + /* find drivers willing to handle this device */ + usb_find_drivers(dev); return 0; } @@ -1226,12 +1343,12 @@ * returns the current frame number for the parent USB bus/controller * of the given USB device. */ -int usb_get_current_frame_number (struct usb_device *usb_dev) +int usb_get_current_frame_number(struct usb_device *usb_dev) { return usb_dev->bus->op->get_frame_number (usb_dev); } -int usb_init_isoc (struct usb_device *usb_dev, +int usb_init_isoc(struct usb_device *usb_dev, unsigned int pipe, int frame_count, void *context, @@ -1302,7 +1419,7 @@ struct usb_driver *c = usb_minors[minor/16]; file->f_op = NULL; - if ((file->f_op = c->fops) && file->f_op->open) + if (c && (file->f_op = c->fops) && file->f_op->open) return file->f_op->open(inode,file); else return -ENODEV; @@ -1323,10 +1440,15 @@ void usb_major_init(void) { - if (register_chrdev(180,"usb",&usb_fops)) { + if (register_chrdev(USB_MAJOR,"usb",&usb_fops)) { printk("unable to get major %d for usb devices\n", - MISC_MAJOR); + USB_MAJOR); } +} + +void usb_major_cleanup(void) +{ + unregister_chrdev(USB_MAJOR, "usb"); } diff -u --recursive --new-file v2.3.24/linux/drivers/usb/usb.h linux/drivers/usb/usb.h --- v2.3.24/linux/drivers/usb/usb.h Fri Oct 22 13:21:51 1999 +++ linux/drivers/usb/usb.h Thu Oct 28 12:53:26 1999 @@ -175,6 +175,8 @@ #include #include +#define USB_MAJOR 180 + extern int usb_hub_init(void); extern int usb_kbd_init(void); extern int usb_cpia_init(void); @@ -235,6 +237,12 @@ unsigned long devicemap[128 / (8*sizeof(unsigned long))]; }; +#define USB_MAXBUS 64 + +struct usb_busmap { + unsigned long busmap[USB_MAXBUS / (8*sizeof(unsigned long))]; +}; + /* * This is a USB device descriptor. * @@ -320,6 +328,9 @@ int act_altsetting; /* active alternate setting */ int num_altsetting; /* number of alternate settings */ + + struct usb_driver *driver; /* driver */ + void *private_data; }; /* Configuration descriptor information.. */ @@ -348,8 +359,8 @@ struct usb_driver { const char *name; - int (*probe)(struct usb_device *); - void (*disconnect)(struct usb_device *); + void * (*probe)(struct usb_device *, unsigned int); + void (*disconnect)(struct usb_device *, void *); struct list_head driver_list; @@ -476,6 +487,8 @@ * Allocated per bus we have */ struct usb_bus { + int busnum; /* Bus number (in order of reg) */ + struct usb_devmap devmap; /* Device map */ struct usb_operations *op; /* Operations (specific to the HC) */ struct usb_device *root_hub; /* Root hub */ @@ -510,11 +523,9 @@ struct usb_config_descriptor *actconfig;/* the active configuration */ int epmaxpacketin[16]; /* INput endpoint specific maximums */ int epmaxpacketout[16]; /* OUTput endpoint specific maximums */ - int ifnum; /* active interface number */ struct usb_device *parent; struct usb_bus *bus; /* Bus we're part of */ - struct usb_driver *driver; /* Driver */ struct usb_device_descriptor descriptor;/* Descriptor */ struct usb_config_descriptor *config; /* All of the configs */ @@ -523,7 +534,6 @@ int string_langid; /* language ID for strings */ void *hcpriv; /* Host Controller private data */ - void *private; /* Upper layer private data */ void *audiopriv; /* May be both audio and HID */ /* procfs entry */ struct proc_dir_entry *proc_entry; @@ -543,6 +553,11 @@ extern int usb_register(struct usb_driver *); extern void usb_deregister(struct usb_driver *); +/* used these for multi-interface device registration */ +extern void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv); +extern int usb_interface_claimed(struct usb_interface *iface); +extern void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface); + extern struct usb_bus *usb_alloc_bus(struct usb_operations *); extern void usb_free_bus(struct usb_bus *); extern void usb_register_bus(struct usb_bus *); @@ -620,6 +635,11 @@ #define PIPE_INTERRUPT 1 #define PIPE_CONTROL 2 #define PIPE_BULK 3 + +#define USB_ISOCHRONOUS 0 +#define USB_INTERRUPT 1 +#define USB_CONTROL 2 +#define USB_BULK 3 #define usb_maxpacket(dev, pipe, out) (out \ ? (dev)->epmaxpacketout[usb_pipeendpoint(pipe)] \ diff -u --recursive --new-file v2.3.24/linux/drivers/usb/usb_scsi.c linux/drivers/usb/usb_scsi.c --- v2.3.24/linux/drivers/usb/usb_scsi.c Fri Oct 15 15:25:14 1999 +++ linux/drivers/usb/usb_scsi.c Thu Oct 28 12:53:26 1999 @@ -69,6 +69,7 @@ struct usb_scsi_filter *filter; /* filter driver */ void *fdata; /* filter data */ unsigned int flags; /* from filter initially*/ + __u8 ifnum; /* interface number */ __u8 ep_in; /* in endpoint */ __u8 ep_out; /* out ....... */ __u8 ep_int; /* interrupt . */ @@ -118,8 +119,8 @@ static struct usb_scsi_filter *filters; -static int scsi_probe(struct usb_device *dev); -static void scsi_disconnect(struct usb_device *dev); +static void * scsi_probe(struct usb_device *dev, unsigned int ifnum); +static void scsi_disconnect(struct usb_device *dev, void *ptr); static struct usb_driver scsi_driver = { "usb_scsi", scsi_probe, @@ -269,7 +270,7 @@ cmd[1] = 4; result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE, - 0, us->pusb_dev->ifnum, cmd, sizeof(cmd), HZ*5); + 0, us->ifnum, cmd, sizeof(cmd), HZ*5); /* long wait for reset */ @@ -324,7 +325,7 @@ } result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE, - 0, us->pusb_dev->ifnum, + 0, us->ifnum, cmd, us->fixedlength, HZ*5); if (!done_start && (us->subclass == US_SC_UFI /*|| us->subclass == US_SC_8070*/) && cmd[0] == TEST_UNIT_READY && result) { @@ -336,7 +337,7 @@ cmd[4] = 1; /* start */ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE, - 0, us->pusb_dev->ifnum, + 0, us->ifnum, cmd, us->fixedlength, HZ*5); wait_ms(100); retry++; @@ -345,7 +346,7 @@ } else { result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE, - 0, us->pusb_dev->ifnum, + 0, us->ifnum, srb->cmnd, srb->cmd_len, HZ*5); } if (/*result != USB_ST_STALL &&*/ result != USB_ST_TIMEOUT) @@ -374,7 +375,7 @@ while (retry--) { result = usb_control_msg(us->pusb_dev, usb_rcvctrlpipe(us->pusb_dev,0), USB_REQ_GET_STATUS, USB_DIR_IN | USB_TYPE_STANDARD | USB_RT_DEVICE, - 0, 0, + 0, us->ifnum, status, sizeof(status), HZ*5); if (result != USB_ST_TIMEOUT) break; @@ -479,7 +480,7 @@ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_BULK_RESET, USB_TYPE_CLASS | USB_RT_INTERFACE, - US_BULK_RESET_HARD, 0, + US_BULK_RESET_HARD, us->ifnum, NULL, 0, HZ*5); if (result) US_DEBUGP("Bulk hard reset failed %d\n", result); @@ -1052,7 +1053,7 @@ return 0; } -static int scsi_probe(struct usb_device *dev) +static void * scsi_probe(struct usb_device *dev, unsigned int ifnum) { struct usb_interface_descriptor *interface; int i; @@ -1098,11 +1099,11 @@ protocol = US_PR_CB; subclass = US_SC_8070; /* an assumption */ } else if (dev->descriptor.bDeviceClass != 0 || - dev->config[0].interface[0].altsetting[0].bInterfaceClass != + dev->actconfig->interface[ifnum].altsetting[0].bInterfaceClass != USB_CLASS_MASS_STORAGE || - dev->config[0].interface[0].altsetting[0].bInterfaceSubClass < US_SC_MIN || - dev->config[0].interface[0].altsetting[0].bInterfaceSubClass > US_SC_MAX) { - return -1; + dev->actconfig->interface[ifnum].altsetting[0].bInterfaceSubClass < US_SC_MIN || + dev->actconfig->interface[ifnum].altsetting[0].bInterfaceSubClass > US_SC_MAX) { + return NULL; } /* now check if we have seen it before */ @@ -1130,12 +1131,12 @@ printk(KERN_WARNING USB_SCSI "Out of memory\n"); if (filter) filter->release(fdata); - return -1; + return NULL; } memset(ss, 0, sizeof(struct us_data)); } - interface = &dev->config[0].interface[0].altsetting[0]; + interface = &dev->actconfig->interface[ifnum].altsetting[0]; ss->filter = filter; ss->fdata = fdata; ss->flags = flags; @@ -1195,10 +1196,12 @@ US_DEBUGP("Endpoints In %d Out %d Int %d\n", ss->ep_in, ss->ep_out, ss->ep_int); + /* save the interface number */ + ss->ifnum = ifnum; + /* exit if strange looking */ - if (usb_set_configuration(dev, dev->config[0].bConfigurationValue) || - usb_set_interface(dev, interface->bInterfaceNumber, 0) || + if (usb_set_interface(dev, interface->bInterfaceNumber, 0) || !ss->ep_in || !ss->ep_out || (ss->protocol == US_PR_CBI && ss->ep_int == 0)) { US_DEBUGP("Problems with device\n"); if (ss->host) { @@ -1209,12 +1212,12 @@ if (filter) filter->release(fdata); kfree(ss); - return -1; /* no endpoints */ + return NULL; /* no endpoints */ } - if (dev->config[0].iConfiguration && usb_string(dev, dev->config[0].iConfiguration)) + if (dev->actconfig->iConfiguration && usb_string(dev, dev->actconfig->iConfiguration)) US_DEBUGP("Configuration %s\n", - usb_string(dev, dev->config[0].iConfiguration)); + usb_string(dev, dev->actconfig->iConfiguration)); if (interface->iInterface && usb_string(dev, interface->iInterface)) US_DEBUGP("Interface %s\n", usb_string(dev, interface->iInterface)); @@ -1268,7 +1271,7 @@ if (filter) filter->release(fdata); kfree(ss); - return -1; + return NULL; } memcpy(htmplt, &my_host_template, sizeof(my_host_template)); ss->host_number = my_host_number++; @@ -1284,7 +1287,7 @@ /* shuttle E-USB */ result = usb_control_msg(ss->pusb_dev, usb_rcvctrlpipe(dev,0), 1, 0xC0, - 0, 0, + 0, ss->ifnum, qstat, 2, HZ*5); US_DEBUGP("C0 status %x %x\n", qstat[0], qstat[1]); init_waitqueue_head(&ss->ip_waitq); @@ -1292,7 +1295,7 @@ result = usb_request_irq(ss->pusb_dev, ss->irqpipe, pop_CBI_irq, 0, (void *)ss, &ss->irq_handle); if (result) - return -1; + return NULL; interruptible_sleep_on_timeout(&ss->ip_waitq, HZ*6); } else if (ss->protocol == US_PR_CBI) @@ -1314,7 +1317,7 @@ if (filter) filter->release(fdata); kfree(ss); - return -1; + return NULL; } /* wait for it to start */ @@ -1336,20 +1339,18 @@ printk(KERN_INFO "USB SCSI device found at address %d\n", dev->devnum); - dev->private = ss; - return 0; + return ss; } -static void scsi_disconnect(struct usb_device *dev) +static void scsi_disconnect(struct usb_device *dev, void *ptr) { - struct us_data *ss = dev->private; + struct us_data *ss = ptr; if (!ss) return; if (ss->filter) ss->filter->release(ss->fdata); ss->pusb_dev = NULL; - dev->private = NULL; /* just in case */ MOD_DEC_USE_COUNT; } diff -u --recursive --new-file v2.3.24/linux/drivers/usb/uss720.c linux/drivers/usb/uss720.c --- v2.3.24/linux/drivers/usb/uss720.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/usb/uss720.c Thu Oct 28 12:53:26 1999 @@ -538,7 +538,7 @@ /* --------------------------------------------------------------------- */ -static int uss720_probe(struct usb_device *usbdev) +static void * uss720_probe(struct usb_device *usbdev, unsigned int ifnum) { struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; @@ -552,31 +552,16 @@ if ((usbdev->descriptor.idVendor != 0x047e || usbdev->descriptor.idProduct != 0x1001) && (usbdev->descriptor.idVendor != 0x0557 || usbdev->descriptor.idProduct != 0x2001) && (usbdev->descriptor.idVendor != 0x0729 || usbdev->descriptor.idProduct != 0x1284)) - return -1; + return NULL; - /* We don't handle multiple configurations */ - if (usbdev->descriptor.bNumConfigurations != 1) - return -1; + /* our known interfaces have 3 alternate settings */ + if (usbdev->actconfig->interface[ifnum].num_altsetting != 3) + return NULL; - /* We don't handle multiple interfaces */ - if (usbdev->config[0].bNumInterfaces != 1) - return -1; - - /* We don't handle multiple interfaces */ - if (usbdev->config[0].interface[0].num_altsetting != 3) - return -1; - - printk(KERN_DEBUG "uss720: set configuration\n"); - usb_set_configuration(usbdev, usbdev->config[0].bConfigurationValue); - - i = usb_set_interface(usbdev, 0, 2); + i = usb_set_interface(usbdev, ifnum, 2); printk(KERN_DEBUG "uss720: set inteface result %d\n", i); - interface = &usbdev->config[0].interface[0].altsetting[2]; - - //printk(KERN_DEBUG "uss720: get interface\n"); - //i = usb_get_interface(usbdev, 0); - //printk(KERN_DEBUG "uss720: is in alternate setting %d\n", i); + interface = &usbdev->actconfig->interface[ifnum].altsetting[2]; /* * Allocate parport interface @@ -584,13 +569,13 @@ printk(KERN_INFO "uss720: (C) 1999 by Thomas Sailer, \n"); if (!(priv = kmalloc(sizeof(struct parport_uss720_private), GFP_KERNEL))) - return -1; + return NULL; if (!(pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops))) { - kfree(priv); - return -1; + printk(KERN_WARNING "usb-uss720: could not register parport\n"); + goto probe_abort; } + pp->private_data = priv; - usbdev->private = pp; priv->usbdev = usbdev; pp->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP | PARPORT_MODE_ECP | PARPORT_MODE_COMPAT; @@ -612,26 +597,28 @@ pp, &priv->irqhandle); if (i) { printk (KERN_WARNING "usb-uss720: usb_request_irq failed (0x%x)\n", i); - /* FIXME: undo some stuff and free some memory. */ - return -1; + goto probe_abort_port; } #endif parport_proc_register(pp); parport_announce_port(pp); MOD_INC_USE_COUNT; - return 0; + return pp; + +probe_abort_port: + parport_unregister_port(pp); +probe_abort: + kfree(priv); + return NULL; } -static void uss720_disconnect(struct usb_device *usbdev) +static void uss720_disconnect(struct usb_device *usbdev, void *ptr) { - struct parport *pp = (struct parport *)usbdev->private; + struct parport *pp = (struct parport *)ptr; struct parport_uss720_private *priv = pp->private_data; -#if 0 usb_release_irq(usbdev, priv->irqhandle, priv->irqpipe); -#endif - usbdev->private = NULL; priv->usbdev = NULL; parport_proc_unregister(pp); parport_unregister_port(pp); diff -u --recursive --new-file v2.3.24/linux/drivers/video/acornfb.c linux/drivers/video/acornfb.c --- v2.3.24/linux/drivers/video/acornfb.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/video/acornfb.c Thu Oct 28 10:16:02 1999 @@ -1,5 +1,5 @@ /* - * linux/drivers/video/acorn.c + * linux/drivers/video/acornfb.c * * Copyright (C) 1998,1999 Russell King * @@ -36,6 +36,8 @@ #include