diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/CREDITS linux.ac/CREDITS --- linux.vanilla/CREDITS Thu May 25 17:46:15 2000 +++ linux.ac/CREDITS Thu May 25 23:36:46 2000 @@ -38,10 +38,11 @@ S: Ireland N: Tigran A. Aivazian -E: tigran@ocston.org +E: tigran@veritas.com W: http://www.ocston.org/~tigran D: BFS filesystem D: Intel P6 CPU microcode update support +D: Various kernel patches S: United Kingdom N: Werner Almesberger @@ -2102,6 +2103,15 @@ S: 9725 GA Groningen S: The Netherlands +N: Pekka Riikonen +E: priikone@poseidon.pspt.fi +E: priikone@ssh.com +D: Random kernel hacking and bug fixes +D: International kernel patch project +S: Kasarmikatu 11 A4 +S: 70110 Kuopio +S: Finland + N: William E. Roadcap E: roadcapw@cfw.com W: http://www.cfw.com/~roadcapw @@ -2154,6 +2164,14 @@ S: Research School of Information Science and Engineering S: The Australian National University, ACT 0200 S: Australia + +N: Aristeu Sergio Rozanski Filho +E: aris@conectiva.com.br +D: Support for EtherExpress 10 ISA (i82595) in eepro driver +S: Conectiva S.A. +S: R. Tocantins, 89 - Cristo Rei +S: 80050-430 - Curitiba - Paraná +S: Brazil N: Alessandro Rubini E: rubini@ipvvis.unipv.it diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/Configure.help linux.ac/Documentation/Configure.help --- linux.vanilla/Documentation/Configure.help Thu May 25 17:46:15 2000 +++ linux.ac/Documentation/Configure.help Sat May 27 15:36:00 2000 @@ -2729,24 +2729,23 @@ all x86 CPU types (albeit not optimally fast), you can specify "386" here. - If you specify one of "486" or "586" or "Pentium" or "PPro" or - "Athlon", then the kernel will not necessarily run on earlier - architectures (e.g. a Pentium optimized kernel will run on a PPro, - but not necessarily on a i486). + The kernel will not necessarily run on earlier architectures than + the one you have chosen, e.g. a Pentium optimized kernel will run on + a PPro, but not necessarily on a i486. Here are the settings recommended for greatest speed: - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI - 486DLC/DLC2 and UMC 486SX-S. Only "386" kernels will run on a 386 - class machine. + 486DLC/DLC2, UMC 486SX-S and NexGen Nx586. Only "386" kernels will + run on a 386 class machine. - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or - SL/SLC/SLC2/SLC3/SX/SX2, AMD/Cyrix 5x86, NexGen Nx586 and - UMC U5D or U5S. + SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S. - "586" for generic Pentium CPUs, possibly lacking the TSC (time stamp counter) register. - - "Pentium" for the Intel Pentium/Pentium MMX, and AMD K5. - - "PPro" for the Cyrix/IBM/National Semiconductor 6x86MX, MII and - Intel Pentium Pro/Celeron/Pentium II/Pentium III. - - "K6/II/III" for the AMD K6, K6-II and K6-III (aka K6-3D). + - "Pentium" for the Intel Pentium/Pentium MMX. + - "Pentium-Pro" for the Intel Pentium Pro/Celeron/Pentium II. + - "Pentium-III" for the Intel Pentium III. + - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D). + - "Crusoe" for the Transmeta Crusoe series. - "Athlon" for the AMD Athlon (K7). If you don't know what to do, choose "386". @@ -8527,9 +8526,10 @@ EtherExpress PRO support CONFIG_EEXPRESS_PRO - If you have a network (Ethernet) card of this type, say Y. Note - however that the EtherExpress PRO/100 Ethernet card has its own - separate driver. Please read the Ethernet-HOWTO, available from + If you have a network (Ethernet) card of this type, say Y. This + driver supports intel i82595{FX,TX} based boards. Note however + that the EtherExpress PRO/100 Ethernet card has its own separate + driver. Please read the Ethernet-HOWTO, available from http://www.linuxdoc.org/docs.html#howto . This driver is also available as a module ( = code which can be diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/filesystems/bfs.txt linux.ac/Documentation/filesystems/bfs.txt --- linux.vanilla/Documentation/filesystems/bfs.txt Thu May 25 17:38:37 2000 +++ linux.ac/Documentation/filesystems/bfs.txt Thu May 25 23:36:46 2000 @@ -54,4 +54,4 @@ If you have any patches, questions or suggestions regarding this BFS implementation please contact the author: -Tigran A. Aivazian . +Tigran A. Aivazian diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/networking/sk98lin.txt linux.ac/Documentation/networking/sk98lin.txt --- linux.vanilla/Documentation/networking/sk98lin.txt Thu May 25 17:38:38 2000 +++ linux.ac/Documentation/networking/sk98lin.txt Thu May 25 01:40:13 2000 @@ -3,7 +3,7 @@ sk98lin.txt created 11-Nov-1999 -Readme File for sk98lin.o v3.02 +Readme File for sk98lin.o v3.04 SK-NET Gigabit Ethernet Adapter SK-98xx Driver for Linux This file contains @@ -24,8 +24,8 @@ ============ The sk98lin driver supports the SysKonnect SK-NET Gigabit Ethernet -Adapter SK-98xx family on Linux 2.2.x. -It has been tested with Linux on Intel/x86 and ALPHA machines. +Adapter SK-98xx family on Linux 2.2.x and above. +It has been tested with Linux on Intel/x86, ALPHA and UltraSPARC machines. From v3.02 on, the driver is integrated in the linux kernel source. *** @@ -132,7 +132,8 @@ module with 'insmod'. The configuration tools of some distributions can also give parameters to the driver module. If you use the kernel module loader, you can set driver parameters -in the file /etc/conf.modules. Insert a line of the form: +in the file /etc/modules.conf (or old name: /etc/conf.modules). +Insert a line of the form: options sk98lin ... @@ -281,14 +282,12 @@ the large frames. If one adapter is not set to receive large frames, it will simply drop them. -NOTE: If you look at the statistics (with netstat) in large frame - mode while there is traffic on the net, you will see the - RX error counter go up. This is because the adapter hardware - counts received large frames as errors, although they are - received correctly. So ignore this counter in that case. - You can switch back to the standard ethernet frame size with: ifconfig eth0 mtu 1500 + +To make this setting persitent, add a script with the 'ifconfig' +line to the system startup sequence (named something like "S99sk98lin" +in /etc/rc.d/rc2.d). *** @@ -374,15 +373,27 @@ (8) HISTORY =========== -VERSION 3.02 +VERSION 3.04 (In-Kernel version) +Problems fixed: +- Driver start failed on UltraSPARC +- Rx checksum calculation for big endian machines did not work +- Jumbo frames were counted as input-errors in netstat + +VERSION 3.03 (Standalone version) +Problems fixed: +- Compilation did not find script "printver.sh" if "." not in PATH +Known limitations: +- None + +VERSION 3.02 (In-Kernel version) Problems fixed: - None New Features: -- Integration in linux kernel source. +- Integration in Linux kernel source (2.2.14 and 2.3.29) Known limitations: - None -VERSION 3.02 +VERSION 3.01 Problems fixed: - None New Features: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/networking/tlan.txt linux.ac/Documentation/networking/tlan.txt --- linux.vanilla/Documentation/networking/tlan.txt Thu May 25 17:38:38 2000 +++ linux.ac/Documentation/networking/tlan.txt Mon May 29 19:34:42 2000 @@ -2,7 +2,10 @@ (C) 1998 James Banks (C) 1999-2000 Torben Mathiasen -TLAN driver for Linux, version 1.5 +For driver information/updates visit http://tlan.kernel.dk + + +TLAN driver for Linux, version 1.8a README @@ -65,12 +68,15 @@ if a card which only supports 10Mbs is forced into 100Mbs mode.) - 5. If the driver is built into the kernel, you can use the 3rd + 5. You have to use speed=X duplex=Y together now. If you just + do "insmod tlan.o speed=100" the driver will do Auto-Neg. + To force a 10Mbps Half-Duplex link do "insmod tlan.o speed=10 + duplex=1". + + 6. If the driver is built into the kernel, you can use the 3rd and 4th parameters to set aui and debug respectively. For example: -/* kernel-parameters are currently not supported. I will fix this asap. */ - ether=0,0,0x1,0x7,eth0 This sets aui to 0x1 and debug to 0x7, assuming eth0 is a @@ -79,11 +85,14 @@ The bits in the third byte are assigned as follows: 0x01 = aui - 0x04 = use half duplex - 0x08 = use full duplex - 0x10 = use 10BaseT - 0x20 = use 100BaseTx - + 0x02 = use half duplex + 0x04 = use full duplex + 0x08 = use 10BaseT + 0x10 = use 100BaseTx + + You also need to set both speed and duplex settings when forcing + speeds with kernel-parameters. + ether=0,0,0x12,0,eth0 will force link to 100Mbps Half-Duplex. III. Things to try if you have problems. 1. Make sure your card's PCI id is among those listed in @@ -94,5 +103,5 @@ There is also a tlan mailing list which you can join by sending "subscribe tlan" in the body of an email to majordomo@vuser.vu.union.edu. - +There is also a tlan website at http://tlan.kernel.dk diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/sound/Maestro linux.ac/Documentation/sound/Maestro --- linux.vanilla/Documentation/sound/Maestro Thu May 25 17:38:40 2000 +++ linux.ac/Documentation/sound/Maestro Sat May 27 15:32:55 2000 @@ -6,7 +6,7 @@ ------------------------------ The most recent version of this driver will hopefully always be available at - http://people.redhat.com/zab/maestro/ + http://www.zabbo.net/maestro/ I will try and maintain the most recent stable version of the driver in both the stable and development kernel lines. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/sound/via82cxxx.txt linux.ac/Documentation/sound/via82cxxx.txt --- linux.vanilla/Documentation/sound/via82cxxx.txt Thu May 25 17:38:41 2000 +++ linux.ac/Documentation/sound/via82cxxx.txt Sat May 27 15:21:47 2000 @@ -48,6 +48,15 @@ Driver notes ------------------------------------------------------------------------ +Two /proc pseudo-files provide diagnostic information. This is generally +not useful to most users. Power users can disable VIA_PROC_FS macro in the +driver source code, and remove the /proc support code. In any case, once +version 2.0.0 is released, the /proc support code will be disabled by +default. Available /proc pseudo-files: + + /proc/driver/via/0/info + /proc/driver/via/0/ac97 + This driver by default supports all PCI audio devices which report a vendor id of 0x1106, and a device id of 0x3058. Subsystem vendor and device ids are not examined. @@ -110,7 +119,8 @@ 1) Volume too low on many systems. Workaround: use mixer program such as xmixer to increase volume. -2) RealPlayer output very scratchy. +2) RealPlayer output very scratchy. Workaround: use esd, and +configure RealPlayer to output to esd. 3) Applications which attempt to open the sound device in read/write mode (O_RDWR) will fail. This is incorrect OSS behavior, but since @@ -137,5 +147,30 @@ If you wish to increase the size of the buffer displayed by 'dmesg', then change the LOG_BUF_LEN macro at the top of linux/kernel/printk.c, recompile your kernel, and pass the "-s " option to 'dmesg'. + + + +Change history +------------------------------------------------------------------------ +Version 1.1.7: +* Fix module unload bug where mixer device left registers + after driver exit + +Version 1.1.6: +* Rewrite via_set_rate to mimic ALSA basic AC97 rate setting +* Remove much dead code +* Complete spin_lock_irqsave -> spin_lock_irq conversion in via_dsp_ioctl +* Fix build problem in via_dsp_ioctl +* Optimize included headers to eliminate headers found in linux/drivers/sound + +Version 1.1.5: +* Disable some overly-verbose debugging code +* Remove unnecessary sound locks +* Fix some ioctls for better time resolution +* Begin spin_lock_irqsave -> spin_lock_irq conversion in via_dsp_ioctl + +Version 1.1.4: +* Completed rewrite of driver. Eliminated SoundBlaster compatibility + completely, and now uses the much-faster scatter-gather DMA engine. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/MAINTAINERS linux.ac/MAINTAINERS --- linux.vanilla/MAINTAINERS Thu May 25 17:46:15 2000 +++ linux.ac/MAINTAINERS Mon May 29 19:34:42 2000 @@ -178,7 +178,7 @@ BFS FILE SYSTEM P: Tigran A. Aivazian -M: tigran@ocston.org +M: tigran@veritas.com L: linux-kernel@vger.rutgers.edu W: http://www.ocston.org/~tigran/patches/bfs S: Maintained @@ -234,6 +234,11 @@ W: http://www.fi.muni.cz/~kas/cosa/ S: Maintained +CPUID/MSR DRIVER +P: H. Peter Anvin +M: hpa@zytor.com +S: Maintained + CREDITS FILE P: John A. Martin M: jam@acm.org @@ -540,7 +545,7 @@ INTEL P6 MICROCODE UPDATE SUPPORT P: Tigran Aivazian -M: tigran@sco.com +M: tigran@veritas.com S: Maintained IP MASQUERADING: @@ -793,7 +798,7 @@ P: Andrea Arcangeli M: andrea@e-mind.com L: linux-parport@torque.net -W: http://www.cyberelk.demon.co.uk/parport.html +W: http://people.redhat.com/twaugh/parport/ S: Maintained PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES @@ -1051,6 +1056,8 @@ M: torben.mathiasen@compaq.com M: tmm@image.dk L: tlan@vuser.vu.union.edu +L: linux-net@vger.rutgers.edu +W: http://tlan.kernel.dk S: Maintained TOKEN-RING NETWORK DRIVER diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Makefile linux.ac/Makefile --- linux.vanilla/Makefile Thu May 25 17:46:15 2000 +++ linux.ac/Makefile Mon May 29 20:22:22 2000 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -test1 +EXTRAVERSION = -test1-ac5 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -142,7 +142,7 @@ DRIVERS-$(CONFIG_WAN) += drivers/net/wan/wan.a DRIVERS-$(CONFIG_ARCNET) += drivers/net/arcnet/arcnet.a DRIVERS-$(CONFIG_ATM) += drivers/atm/atm.o -DRIVERS-$(CONFIG_IDE) += drivers/ide/ide.a +DRIVERS-$(CONFIG_IDE) += drivers/ide/idedriver.o DRIVERS-$(CONFIG_SCSI) += drivers/scsi/scsi.a DRIVERS-$(CONFIG_IEEE1394) += drivers/ieee1394/ieee1394.a diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/alpha/defconfig linux.ac/arch/alpha/defconfig --- linux.vanilla/arch/alpha/defconfig Thu May 25 17:38:24 2000 +++ linux.ac/arch/alpha/defconfig Mon May 29 19:25:14 2000 @@ -83,10 +83,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/config.in linux.ac/arch/arm/config.in --- linux.vanilla/arch/arm/config.in Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/config.in Fri May 26 15:25:23 2000 @@ -189,7 +189,7 @@ "$CONFIG_ARCH_NETWINDER" = "y" -o \ "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \ "$CONFIG_ARCH_CATS" = "y" ]; then - string 'Initial kernel command string' CONFIG_CMDLINE + string 'Initial kernel command string' CONFIG_CMDLINE "" fi if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \ "$CONFIG_ARCH_EBSA110" = "y" -o \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/a5k linux.ac/arch/arm/def-configs/a5k --- linux.vanilla/arch/arm/def-configs/a5k Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/a5k Mon May 29 19:25:14 2000 @@ -94,10 +94,6 @@ # CONFIG_BLK_DEV_IDEDMA_ICS is not set # CONFIG_BLK_DEV_IDE_RAPIDE is not set # CONFIG_IDE_CHIPSETS is not set - -# -# Additional Block Devices -# CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/assabet linux.ac/arch/arm/def-configs/assabet --- linux.vanilla/arch/arm/def-configs/assabet Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/assabet Mon May 29 19:25:14 2000 @@ -91,10 +91,6 @@ # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_MD is not set CONFIG_BLK_DEV_RAM=y diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/brutus linux.ac/arch/arm/def-configs/brutus --- linux.vanilla/arch/arm/def-configs/brutus Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/brutus Mon May 29 19:25:14 2000 @@ -95,10 +95,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/ebsa110 linux.ac/arch/arm/def-configs/ebsa110 --- linux.vanilla/arch/arm/def-configs/ebsa110 Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/ebsa110 Mon May 29 19:25:14 2000 @@ -90,10 +90,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/footbridge linux.ac/arch/arm/def-configs/footbridge --- linux.vanilla/arch/arm/def-configs/footbridge Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/footbridge Mon May 29 19:25:14 2000 @@ -138,10 +138,6 @@ CONFIG_PARIDE_ON26=m # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/graphicsclient linux.ac/arch/arm/def-configs/graphicsclient --- linux.vanilla/arch/arm/def-configs/graphicsclient Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/graphicsclient Mon May 29 19:25:14 2000 @@ -84,10 +84,6 @@ # Please see Documentation/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_HD_ONLY is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/lart linux.ac/arch/arm/def-configs/lart --- linux.vanilla/arch/arm/def-configs/lart Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/lart Mon May 29 19:25:14 2000 @@ -85,10 +85,6 @@ # # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/lusl7200 linux.ac/arch/arm/def-configs/lusl7200 --- linux.vanilla/arch/arm/def-configs/lusl7200 Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/lusl7200 Mon May 29 19:25:14 2000 @@ -79,10 +79,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/rpc linux.ac/arch/arm/def-configs/rpc --- linux.vanilla/arch/arm/def-configs/rpc Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/rpc Mon May 29 19:25:14 2000 @@ -91,10 +91,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/thinclient linux.ac/arch/arm/def-configs/thinclient --- linux.vanilla/arch/arm/def-configs/thinclient Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/thinclient Mon May 29 19:25:14 2000 @@ -94,10 +94,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/def-configs/victor linux.ac/arch/arm/def-configs/victor --- linux.vanilla/arch/arm/def-configs/victor Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/def-configs/victor Mon May 29 19:25:14 2000 @@ -80,10 +80,6 @@ # CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_IDE_CHIPSETS is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/defconfig linux.ac/arch/arm/defconfig --- linux.vanilla/arch/arm/defconfig Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/defconfig Mon May 29 19:25:14 2000 @@ -134,10 +134,6 @@ CONFIG_PARIDE_ON26=m # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_MD=y diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/config.in linux.ac/arch/i386/config.in --- linux.vanilla/arch/i386/config.in Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/config.in Sat May 27 15:36:00 2000 @@ -19,14 +19,14 @@ comment 'Processor type and features' choice 'Processor family' \ "386 CONFIG_M386 \ - 486/Cx486 CONFIG_M486 \ + 486 CONFIG_M486 \ 586/K5/5x86/6x86/6x86MX CONFIG_M586 \ - Pentium/TSC CONFIG_M586TSC \ - PPro/Pentium-II CONFIG_M686 \ + Pentium/Pentium-MMX CONFIG_M586TSC \ + Pentium-Pro/Celeron/Pentium-II CONFIG_M686 \ Pentium-III CONFIG_M686FX \ K6/K6-II/K6-III CONFIG_MK6 \ - Athlon CONFIG_MK7 \ - Crusoe CONFIG_MCRUSOE" PPro + Athlon/K7 CONFIG_MK7 \ + Crusoe CONFIG_MCRUSOE" Pentium-Pro # # Define implied options from the CPU selection here # diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/defconfig linux.ac/arch/i386/defconfig --- linux.vanilla/arch/i386/defconfig Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/defconfig Mon May 29 19:25:14 2000 @@ -105,10 +105,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/acpi.c linux.ac/arch/i386/kernel/acpi.c --- linux.vanilla/arch/i386/kernel/acpi.c Thu May 25 17:38:24 2000 +++ linux.ac/arch/i386/kernel/acpi.c Sat May 27 15:38:12 2000 @@ -1169,6 +1169,8 @@ acpi_sleep_start = get_cmos_time(); acpi_enter_dx(ACPI_D3); + // disable interrupts globally while suspended + cli(); acpi_sleep_state = state; facp = (struct acpi_facp*) acpi_facp.table; @@ -1191,6 +1193,8 @@ // finished sleeping, update system time acpi_update_clock(); acpi_enter_dx(ACPI_D0); + // reenable interrupts globally after resume + sti(); acpi_sleep_state = ACPI_S0; return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/apic.c linux.ac/arch/i386/kernel/apic.c --- linux.vanilla/arch/i386/kernel/apic.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/apic.c Mon May 29 19:44:19 2000 @@ -701,7 +701,7 @@ ack_APIC_irq(); /* see sw-dev-man vol 3, chapter 7.4.13.5 */ - printk("spurious APIC interrupt on CPU#%d, should never happen.\n", + printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n", smp_processor_id()); } @@ -718,32 +718,32 @@ spin_lock(&err_lock); v = apic_read(APIC_ESR); - printk("APIC error interrupt on CPU#%d, should never happen.\n", + printk(KERN_INFO "APIC error interrupt on CPU#%d, should never happen.\n", smp_processor_id()); - printk("... APIC ESR0: %08lx\n", v); + printk(KERN_INFO "... APIC ESR0: %08lx\n", v); apic_write(APIC_ESR, 0); v |= apic_read(APIC_ESR); - printk("... APIC ESR1: %08lx\n", v); + printk(KERN_INFO "... APIC ESR1: %08lx\n", v); /* * Be a bit more verbose. (multiple bits can be set) */ if (v & 0x01) - printk("... bit 0: APIC Send CS Error (hw problem).\n"); + printk(KERN_INFO "... bit 0: APIC Send CS Error (hw problem).\n"); if (v & 0x02) - printk("... bit 1: APIC Receive CS Error (hw problem).\n"); + printk(KERN_INFO "... bit 1: APIC Receive CS Error (hw problem).\n"); if (v & 0x04) - printk("... bit 2: APIC Send Accept Error.\n"); + printk(KERN_INFO "... bit 2: APIC Send Accept Error.\n"); if (v & 0x08) - printk("... bit 3: APIC Receive Accept Error.\n"); + printk(KERN_INFO "... bit 3: APIC Receive Accept Error.\n"); if (v & 0x10) - printk("... bit 4: Reserved!.\n"); + printk(KERN_INFO "... bit 4: Reserved!.\n"); if (v & 0x20) - printk("... bit 5: Send Illegal Vector (kernel bug).\n"); + printk(KERN_INFO "... bit 5: Send Illegal Vector (kernel bug).\n"); if (v & 0x40) - printk("... bit 6: Received Illegal Vector.\n"); + printk(KERN_INFO "... bit 6: Received Illegal Vector.\n"); if (v & 0x80) - printk("... bit 7: Illegal Register Address.\n"); + printk(KERN_INFO "... bit 7: Illegal Register Address.\n"); ack_APIC_irq(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/apm.c linux.ac/arch/i386/kernel/apm.c --- linux.vanilla/arch/i386/kernel/apm.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/apm.c Fri May 26 14:27:53 2000 @@ -135,6 +135,13 @@ * Fix the Thinkpad (again) :-( (CONFIG_APM_IGNORE_MULTIPLE_SUSPENDS * is now the way life works). * Fix thinko in suspend() (wrong return). + * Notify drivers on critical suspend. + * Make kapmd absorb more idle time (Pavel Machek + * modified by sfr). + * Disable interrupts while we are suspended (Andy Henroid + * fixed by sfr). + * Make power off work on SMP again (Tony Hoyle + * and ) modified by sfr. * * APM 1.1 Reference: * @@ -864,19 +871,51 @@ #endif } +static int send_event(apm_event_t event) +{ + switch (event) { + case APM_SYS_SUSPEND: + case APM_CRITICAL_SUSPEND: + case APM_USER_SUSPEND: + /* map all suspends to ACPI D3 */ + if (pm_send_all(PM_SUSPEND, (void *)3)) { + if (event == APM_CRITICAL_SUSPEND) { + printk(KERN_CRIT "apm: Critical suspend was vetoed, expect armageddon\n" ); + return 0; + } + if (apm_bios_info.version > 0x100) + apm_set_power_state(APM_STATE_REJECT); + return 0; + } + break; + case APM_NORMAL_RESUME: + case APM_CRITICAL_RESUME: + /* map all resumes to ACPI D0 */ + (void) pm_send_all(PM_RESUME, (void *)0); + break; + } + + return 1; +} + static int suspend(void) { int err; struct apm_user *as; get_time_diff(); + cli(); err = apm_set_power_state(APM_STATE_SUSPEND); reinit_timer(); set_time(); if (err == APM_NO_ERROR) err = APM_SUCCESS; - if (err != APM_SUCCESS) + if (err != APM_SUCCESS) { apm_error("suspend", err); + send_event(APM_NORMAL_RESUME); + sti(); + queue_event(APM_NORMAL_RESUME, NULL); + } for (as = user_list; as != NULL; as = as->next) { as->suspend_wait = 0; as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO); @@ -914,33 +953,6 @@ return 0; } -static int send_event(apm_event_t event, struct apm_user *sender) -{ - switch (event) { - case APM_SYS_SUSPEND: - case APM_CRITICAL_SUSPEND: - case APM_USER_SUSPEND: - /* map all suspends to ACPI D3 */ - if (pm_send_all(PM_SUSPEND, (void *)3)) { - if (event == APM_CRITICAL_SUSPEND) { - printk(KERN_CRIT "apm: Critical suspend was vetoed, expect armagedon\n" ); - return 0; - } - if (apm_bios_info.version > 0x100) - apm_set_power_state(APM_STATE_REJECT); - return 0; - } - break; - case APM_NORMAL_RESUME: - case APM_CRITICAL_RESUME: - /* map all resumes to ACPI D0 */ - (void) pm_send_all(PM_RESUME, (void *)0); - break; - } - - return 1; -} - static void check_events(void) { apm_event_t event; @@ -966,7 +978,7 @@ switch (event) { case APM_SYS_STANDBY: case APM_USER_STANDBY: - if (send_event(event, NULL)) { + if (send_event(event)) { queue_event(event, NULL); if (standbys_pending <= 0) standby(); @@ -984,17 +996,17 @@ if (ignore_bounce) break; #endif - /* - * If we are already processing a SUSPEND, - * then further SUSPEND events from the BIOS - * will be ignored. We also return here to - * cope with the fact that the Thinkpads keep - * sending a SUSPEND event until something else - * happens! - */ + /* + * If we are already processing a SUSPEND, + * then further SUSPEND events from the BIOS + * will be ignored. We also return here to + * cope with the fact that the Thinkpads keep + * sending a SUSPEND event until something else + * happens! + */ if (waiting_for_resume) - return; - if (send_event(event, NULL)) { + return; + if (send_event(event)) { queue_event(event, NULL); waiting_for_resume = 1; if (suspends_pending <= 0) @@ -1011,14 +1023,16 @@ ignore_bounce = 1; #endif set_time(); - send_event(event, NULL); + send_event(event); + sti(); queue_event(event, NULL); break; case APM_CAPABILITY_CHANGE: case APM_LOW_BATTERY: case APM_POWER_STATUS_CHANGE: - send_event(event, NULL); + send_event(event); + queue_event(event, NULL); break; case APM_UPDATE_TIME: @@ -1026,7 +1040,11 @@ break; case APM_CRITICAL_SUSPEND: - send_event(event, NULL); /* We can only hope it worked; critical suspend may not fail */ + send_event(event); + /* + * We can only hope it worked - we are not allowed + * to reject a critical suspend. + */ (void) suspend(); break; } @@ -1066,11 +1084,8 @@ int timeout = HZ; DECLARE_WAITQUEUE(wait, current); - if (smp_num_cpus > 1) - return; - add_wait_queue(&apm_waitqueue, &wait); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); for (;;) { /* Nothing to do, just sleep for the timeout */ timeout = 2*timeout; @@ -1084,7 +1099,7 @@ * Ok, check all events, check for idle (and mark us sleeping * so as not to count towards the load average).. */ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); apm_event_handler(); #ifdef CONFIG_APM_CPU_IDLE if (!system_idle()) @@ -1093,7 +1108,7 @@ unsigned long start = jiffies; while ((!exit_kapmd) && system_idle()) { apm_do_idle(); - if (jiffies - start > (5*APM_CHECK_TIMEOUT)) { + if ((jiffies - start) > APM_CHECK_TIMEOUT) { apm_event_handler(); start = jiffies; } @@ -1137,7 +1152,7 @@ schedule(); goto repeat; } - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&apm_waitqueue, &wait); } i = count; @@ -1199,8 +1214,10 @@ as->standbys_read--; as->standbys_pending--; standbys_pending--; - } else if (!send_event(APM_USER_STANDBY, as)) + } else if (!send_event(APM_USER_STANDBY)) return -EAGAIN; + else + queue_event(APM_USER_STANDBY, as); if (standbys_pending <= 0) standby(); break; @@ -1209,8 +1226,10 @@ as->suspends_read--; as->suspends_pending--; suspends_pending--; - } else if (!send_event(APM_USER_SUSPEND, as)) + } else if (!send_event(APM_USER_SUSPEND)) return -EAGAIN; + else + queue_event(APM_USER_SUSPEND, as); if (suspends_pending <= 0) { if (suspend() != APM_SUCCESS) return -EIO; @@ -1224,7 +1243,7 @@ break; schedule(); } - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&apm_suspend_waitqueue, &wait); return as->suspend_result; } @@ -1403,6 +1422,7 @@ strcpy(current->comm, "kapmd"); sigfillset(¤t->blocked); + current->tty = NULL; /* get rid of controlling tty */ if (apm_bios_info.version > 0x100) { /* @@ -1487,27 +1507,15 @@ #ifdef CONFIG_MAGIC_SYSRQ sysrq_power_off = apm_power_off; #endif + if (smp_num_cpus == 1) { #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) - if (smp_num_cpus == 1) console_blank_hook = apm_console_blank; #endif - - pm_active = 1; - - apm_mainloop(); - - pm_active = 0; - + apm_mainloop(); #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) - if (smp_num_cpus == 1) console_blank_hook = NULL; #endif -#ifdef CONFIG_MAGIC_SYSRQ - sysrq_power_off = NULL; -#endif - if (power_off) - pm_power_off = NULL; - + } kapmd_running = 0; return 0; @@ -1618,6 +1626,7 @@ printk(KERN_NOTICE "apm: overridden by ACPI.\n"); APM_INIT_ERROR_RETURN; } + pm_active = 1; /* * Set up a segment that references the real mode segment 0x40 @@ -1676,9 +1685,15 @@ { misc_deregister(&apm_device); remove_proc_entry("apm", NULL); +#ifdef CONFIG_MAGIC_SYSRQ + sysrq_power_off = NULL; +#endif + if (power_off) + pm_power_off = NULL; exit_kapmd = 1; while (kapmd_running) schedule(); + pm_active = 0; } module_init(apm_init); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/cpuid.c linux.ac/arch/i386/kernel/cpuid.c --- linux.vanilla/arch/i386/kernel/cpuid.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/cpuid.c Thu May 25 23:33:29 2000 @@ -64,11 +64,11 @@ if ( cpu == smp_processor_id() ) { cpuid(reg, &data[0], &data[1], &data[2], &data[3]); } else { - cmd->cpu = cpu; - cmd->reg = reg; - cmd->data = data; + cmd.cpu = cpu; + cmd.reg = reg; + cmd.data = data; - smp_call_function(cpuid_smp_cpuid, (void *)cmd, 1, 1); + smp_call_function(cpuid_smp_cpuid, &cmd, 1, 1); } } #else /* ! CONFIG_SMP */ @@ -120,9 +120,12 @@ static int cpuid_open(struct inode *inode, struct file *file) { int cpu = MINOR(file->f_dentry->d_inode->i_rdev); - + struct cpuinfo_x86 *c = &(cpu_data)[cpu]; + if ( !(cpu_online_map & (1UL << cpu)) ) - return -ENXIO; /* No such CPU */ + return -ENXIO; /* No such CPU */ + if ( c->cpuid_level < 0 ) + return -EIO; /* CPUID not supported */ MOD_INC_USE_COUNT; return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/msr.c linux.ac/arch/i386/kernel/msr.c --- linux.vanilla/arch/i386/kernel/msr.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/msr.c Sat May 27 15:39:35 2000 @@ -40,44 +40,47 @@ #include #include +/* Note: "err" is handled in a funny way below. Otherwise one version + of gcc or another breaks. */ + extern inline int wrmsr_eio(u32 reg, u32 eax, u32 edx) { - int err = 0; + int err; asm volatile( "1: wrmsr\n" "2:\n" ".section .fixup,\"ax\"\n" "3: movl %4,%0\n" - " jmp 1b\n" + " jmp 2b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,3b\n" ".previous" - : "+r" (err) - : "a" (eax), "d" (edx), "c" (reg), "i" (-EIO)); + : "=&bDS" (err) + : "a" (eax), "d" (edx), "c" (reg), "i" (-EIO), "0" (0)); return err; } extern inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx) { - int err = 0; + int err; asm volatile( "1: rdmsr\n" "2:\n" ".section .fixup,\"ax\"\n" "3: movl %4,%0\n" - " jmp 1b\n" + " jmp 2b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b,3b\n" ".previous" - : "+r" (err), "=a" (*eax), "=d" (*eax) - : "c" (reg), "i" (-EIO)); + : "=&bDS" (err), "=a" (*eax), "=d" (*edx) + : "c" (reg), "i" (-EIO), "0" (0)); return err; } @@ -96,7 +99,7 @@ struct msr_command *cmd = (struct msr_command *) cmd_block; if ( cmd->cpu == smp_processor_id() ) - cmd->err = wrmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]); + cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]); } static void msr_smp_rdmsr(void *cmd_block) @@ -119,7 +122,7 @@ cmd.data[0] = eax; cmd.data[1] = edx; - smp_call_function(msr_smp_wrmsr, (void *)cmd, 1, 1); + smp_call_function(msr_smp_wrmsr, &cmd, 1, 1); return cmd.err; } } @@ -134,7 +137,7 @@ cmd.cpu = cpu; cmd.reg = reg; - smp_call_function(msr_smp_rdmsr, (void *)cmd, 1, 1); + smp_call_function(msr_smp_rdmsr, &cmd, 1, 1); *eax = cmd.data[0]; *edx = cmd.data[1]; @@ -224,10 +227,12 @@ static int msr_open(struct inode *inode, struct file *file) { int cpu = MINOR(file->f_dentry->d_inode->i_rdev); + struct cpuinfo_x86 *c = &(cpu_data)[cpu]; - if ( !(cpu_online_map & (1UL << cpu)) || - !((cpu_data)[cpu].x86_capability & X86_FEATURE_MSR) ) - return -ENXIO; /* No such CPU */ + if ( !(cpu_online_map & (1UL << cpu)) ) + return -ENXIO; /* No such CPU */ + if ( !(c->x86_capability & X86_FEATURE_MSR) ) + return -EIO; /* MSR not supported */ MOD_INC_USE_COUNT; return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/setup.c linux.ac/arch/i386/kernel/setup.c --- linux.vanilla/arch/i386/kernel/setup.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/setup.c Sat May 27 15:20:41 2000 @@ -41,6 +41,10 @@ * Dave Jones , April 2000 * Pentium-III code by Ingo Molnar and modifications by Goutham Rao * + * Added proper Cascades CPU and L2 cache detection for Cascades + * and 8-way type cache happy bunch from Intel:^) + * Dragan Stancevic , May 2000 + * */ /* @@ -1337,8 +1341,8 @@ { X86_VENDOR_INTEL, 6, { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)", NULL, "Pentium II (Deschutes)", "Mobile Pentium II", - "Pentium III (Katmai)", "Pentium III (Coppermine)", NULL, NULL, - NULL, NULL, NULL, NULL }}, + "Pentium III (Katmai)", "Pentium III (Coppermine)", NULL, + "Pentium III (Cascades)", NULL, NULL, NULL, NULL }}, { X86_VENDOR_AMD, 4, { NULL, NULL, NULL, "486 DX/2", NULL, NULL, NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT", @@ -1422,24 +1426,26 @@ c->x86_cache_size = 0; break; - case 0x41: + case 0x41: /* 4-way 128 */ c->x86_cache_size = 128; break; - case 0x42: - case 0x82: /*Detect 256-Kbyte cache on Coppermine*/ + case 0x42: /* 4-way 256 */ + case 0x82: /* 8-way 256 */ c->x86_cache_size = 256; break; - case 0x43: + case 0x43: /* 4-way 512 */ c->x86_cache_size = 512; break; - case 0x44: + case 0x44: /* 4-way 1024 */ + case 0x84: /* 8-way 1024 */ c->x86_cache_size = 1024; break; - case 0x45: + case 0x45: /* 4-way 2048 */ + case 0x85: /* 8-way 2048 */ c->x86_cache_size = 2048; break; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ia64/defconfig linux.ac/arch/ia64/defconfig --- linux.vanilla/arch/ia64/defconfig Thu May 25 17:38:35 2000 +++ linux.ac/arch/ia64/defconfig Mon May 29 19:25:14 2000 @@ -59,10 +59,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/m68k/defconfig linux.ac/arch/m68k/defconfig --- linux.vanilla/arch/m68k/defconfig Thu May 25 17:38:33 2000 +++ linux.ac/arch/m68k/defconfig Mon May 29 19:25:14 2000 @@ -67,10 +67,6 @@ # CONFIG_AMIGA_Z2RAM is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/mips/defconfig linux.ac/arch/mips/defconfig --- linux.vanilla/arch/mips/defconfig Thu May 25 17:38:28 2000 +++ linux.ac/arch/mips/defconfig Mon May 29 19:25:14 2000 @@ -72,10 +72,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/mips/defconfig-decstation linux.ac/arch/mips/defconfig-decstation --- linux.vanilla/arch/mips/defconfig-decstation Thu May 25 17:38:29 2000 +++ linux.ac/arch/mips/defconfig-decstation Mon May 29 19:25:14 2000 @@ -70,10 +70,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/mips/defconfig-ip22 linux.ac/arch/mips/defconfig-ip22 --- linux.vanilla/arch/mips/defconfig-ip22 Thu May 25 17:38:29 2000 +++ linux.ac/arch/mips/defconfig-ip22 Mon May 29 19:25:15 2000 @@ -72,10 +72,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/mips64/defconfig linux.ac/arch/mips64/defconfig --- linux.vanilla/arch/mips64/defconfig Thu May 25 17:38:35 2000 +++ linux.ac/arch/mips64/defconfig Mon May 29 19:25:15 2000 @@ -66,10 +66,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/mips64/defconfig-ip22 linux.ac/arch/mips64/defconfig-ip22 --- linux.vanilla/arch/mips64/defconfig-ip22 Thu May 25 17:38:35 2000 +++ linux.ac/arch/mips64/defconfig-ip22 Mon May 29 19:25:15 2000 @@ -57,10 +57,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/mips64/defconfig-ip27 linux.ac/arch/mips64/defconfig-ip27 --- linux.vanilla/arch/mips64/defconfig-ip27 Thu May 25 17:38:35 2000 +++ linux.ac/arch/mips64/defconfig-ip27 Mon May 29 19:25:15 2000 @@ -66,10 +66,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/config.in linux.ac/arch/ppc/config.in --- linux.vanilla/arch/ppc/config.in Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/config.in Fri May 26 15:25:23 2000 @@ -161,7 +161,7 @@ if [ "$CONFIG_PREP" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL y if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then - string 'Initial kernel command string' CONFIG_CMDLINE console=ttyS0,9600 console=tty0 root=/dev/sda2 + string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2" fi fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/configs/apus_defconfig linux.ac/arch/ppc/configs/apus_defconfig --- linux.vanilla/arch/ppc/configs/apus_defconfig Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/configs/apus_defconfig Mon May 29 19:25:15 2000 @@ -78,10 +78,6 @@ CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_PMAC_AUTO=y # CONFIG_IDE_CHIPSETS is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/configs/gemini_defconfig linux.ac/arch/ppc/configs/gemini_defconfig --- linux.vanilla/arch/ppc/configs/gemini_defconfig Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/configs/gemini_defconfig Mon May 29 19:25:15 2000 @@ -77,10 +77,6 @@ # # CONFIG_BLK_DEV_HD_ONLY is not set # CONFIG_BLK_CPQ_DA is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/configs/oak_defconfig linux.ac/arch/ppc/configs/oak_defconfig --- linux.vanilla/arch/ppc/configs/oak_defconfig Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/configs/oak_defconfig Mon May 29 19:25:15 2000 @@ -69,10 +69,6 @@ # Please see Documentation/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_HD_ONLY is not set - -# -# Additional Block Devices -# CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/configs/walnut_defconfig linux.ac/arch/ppc/configs/walnut_defconfig --- linux.vanilla/arch/ppc/configs/walnut_defconfig Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/configs/walnut_defconfig Mon May 29 19:25:15 2000 @@ -69,10 +69,6 @@ # Please see Documentation/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_HD_ONLY is not set - -# -# Additional Block Devices -# CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sh/defconfig linux.ac/arch/sh/defconfig --- linux.vanilla/arch/sh/defconfig Thu May 25 17:38:34 2000 +++ linux.ac/arch/sh/defconfig Mon May 29 19:25:15 2000 @@ -59,10 +59,6 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_DEV_DAC960 is not set - -# -# Additional Block Devices -# # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_LVM is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sparc64/solaris/timod.c linux.ac/arch/sparc64/solaris/timod.c --- linux.vanilla/arch/sparc64/solaris/timod.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/sparc64/solaris/timod.c Sat May 27 22:00:30 2000 @@ -151,8 +151,10 @@ SOLD("wakeing socket"); sock = ¤t->files->fd[fd]->f_dentry->d_inode->u.socket_i; wake_up_interruptible(&sock->wait); + read_lock(&sock->callback_lock); if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) - kill_fasync(sock->fasync_list, SIGIO, POLL_IN); + __kill_fasync(sock->fasync_list, SIGIO, POLL_IN); + read_unlock(&sock->callback_lock); SOLD("done"); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/atm/Config.in linux.ac/drivers/atm/Config.in --- linux.vanilla/drivers/atm/Config.in Thu May 25 17:38:18 2000 +++ linux.ac/drivers/atm/Config.in Fri May 26 15:25:23 2000 @@ -59,7 +59,7 @@ if [ "$CONFIG_ATM_FORE200E_PCA" = "y" ]; then bool ' Use default PCA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_PCA_DEFAULT_FW if [ "$CONFIG_ATM_FORE200E_PCA_DEFAULT_FW" = "n" ]; then - string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_PCA_FW + string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_PCA_FW "" fi fi fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/atm/Makefile linux.ac/drivers/atm/Makefile --- linux.vanilla/drivers/atm/Makefile Thu May 25 17:38:18 2000 +++ linux.ac/drivers/atm/Makefile Sat May 27 15:45:07 2000 @@ -45,7 +45,7 @@ NEED_SUNI_MX = suni.o endif ifeq ($(CONFIG_ATM_NICSTAR_USE_IDT77105),y) - NEED_SUNI_MX = idt77105.o + NEED_IDT77105_MX = idt77105.o endif endif endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/atm/atmtcp.c linux.ac/drivers/atm/atmtcp.c --- linux.vanilla/drivers/atm/atmtcp.c Thu May 25 17:38:18 2000 +++ linux.ac/drivers/atm/atmtcp.c Sat May 27 15:49:40 2000 @@ -330,14 +330,20 @@ struct atmtcp_dev_data *dev_data; struct atm_dev *dev; + MOD_INC_USE_COUNT; + dev_data = kmalloc(sizeof(*dev_data),GFP_KERNEL); - if (!dev_data) return -ENOMEM; + if (!dev_data) { + MOD_DEC_USE_COUNT; + return -ENOMEM; + } + dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL); if (!dev) { kfree(dev_data); + MOD_DEC_USE_COUNT; return itf == -1 ? -ENOMEM : -EBUSY; } - MOD_INC_USE_COUNT; dev->ci_range.vpi_bits = MAX_VPI_BITS; dev->ci_range.vci_bits = MAX_VCI_BITS; PRIV(dev) = dev_data; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/atm/eni.c linux.ac/drivers/atm/eni.c --- linux.vanilla/drivers/atm/eni.c Thu May 25 17:38:18 2000 +++ linux.ac/drivers/atm/eni.c Sat May 27 15:48:59 2000 @@ -2246,8 +2246,16 @@ int error = -ENOMEM; DPRINTK("eni_init_one\n"); + + MOD_INC_USE_COUNT; /* @@@ we don't support unloading yet */ + + if (pci_enable_device(pci_dev)) { + error = -EIO; + goto out0; + } + eni_dev = (struct eni_dev *) kmalloc(sizeof(struct eni_dev),GFP_KERNEL); - if (!eni_dev) return -ENOMEM; + if (!eni_dev) goto out0; if (!cpu_zeroes) { cpu_zeroes = pci_alloc_consistent(pci_dev,ENI_ZEROES_SIZE, &zeroes); @@ -2265,7 +2273,6 @@ if (error) goto out3; eni_dev->more = eni_boards; eni_boards = dev; - MOD_INC_USE_COUNT; /* @@@ we don't support unloading yet */ return 0; out3: atm_dev_deregister(dev); @@ -2274,6 +2281,8 @@ cpu_zeroes = NULL; out1: kfree(eni_dev); +out0: + MOD_DEC_USE_COUNT; /* @@@ we don't support unloading yet */ return error; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/atm/fore200e.c linux.ac/drivers/atm/fore200e.c --- linux.vanilla/drivers/atm/fore200e.c Thu May 25 17:38:19 2000 +++ linux.ac/drivers/atm/fore200e.c Sat May 27 15:49:23 2000 @@ -1409,6 +1409,8 @@ struct fore200e* fore200e = FORE200E_DEV(vcc->dev); struct fore200e_vcc* fore200e_vcc; + MOD_INC_USE_COUNT; + /* find a free VPI/VCI */ fore200e_walk_vccs(vcc, &vpi, &vci); @@ -1416,8 +1418,10 @@ vcc->vci = vci; /* ressource checking only? */ - if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) + if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) { + MOD_DEC_USE_COUNT; return 0; + } set_bit(ATM_VF_ADDR, &vcc->flags); vcc->itf = vcc->dev->number; @@ -1435,6 +1439,7 @@ down(&fore200e->rate_sf); if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) { up(&fore200e->rate_sf); + MOD_DEC_USE_COUNT; return -EAGAIN; } /* reserving the pseudo-CBR bandwidth at this point grants us @@ -1451,6 +1456,7 @@ down(&fore200e->rate_sf); fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; up(&fore200e->rate_sf); + MOD_DEC_USE_COUNT; return -ENOMEM; } @@ -1461,13 +1467,10 @@ down(&fore200e->rate_sf); fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; up(&fore200e->rate_sf); + MOD_DEC_USE_COUNT; return -EBUSY; } -#ifdef MODULE - MOD_INC_USE_COUNT; -#endif - /* compute rate control parameters */ if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) { @@ -2598,6 +2601,10 @@ printk(FORE200E "FORE Systems 200E-series driver - version " FORE200E_VERSION "\n"); +#if 0 /* XXX uncomment this to forbid module unloading */ + MOD_INC_USE_COUNT; +#endif + /* for each configured bus interface */ for (link = 0, bus = fore200e_bus; bus->model_name; bus++) { @@ -2624,10 +2631,8 @@ } #if 0 /* XXX uncomment this to forbid module unloading */ -#ifdef MODULE - if (link > 0) - MOD_INC_USE_COUNT; -#endif + if (link <= 0) + MOD_DEC_USE_COUNT; #endif return link; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/atm/idt77105.c linux.ac/drivers/atm/idt77105.c --- linux.vanilla/drivers/atm/idt77105.c Thu May 25 17:38:19 2000 +++ linux.ac/drivers/atm/idt77105.c Sat May 27 15:34:04 2000 @@ -334,9 +334,7 @@ int __init idt77105_init(struct atm_dev *dev) { -#ifdef MODULE MOD_INC_USE_COUNT; -#endif /* MODULE */ dev->phy = &idt77105_ops; return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/atm/nicstar.c linux.ac/drivers/atm/nicstar.c --- linux.vanilla/drivers/atm/nicstar.c Thu May 25 17:38:19 2000 +++ linux.ac/drivers/atm/nicstar.c Sat May 27 15:34:46 2000 @@ -893,10 +893,9 @@ #ifdef CONFIG_ATM_NICSTAR_USE_SUNI if (card->max_pcr == ATM_OC3_PCR) { suni_init(card->atmdev); -#ifdef MODULE + MOD_INC_USE_COUNT; /* Can't remove the nicstar driver or the suni driver would oops */ -#endif /* MODULE */ } #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/Config.in linux.ac/drivers/block/Config.in --- linux.vanilla/drivers/block/Config.in Thu May 25 17:37:59 2000 +++ linux.ac/drivers/block/Config.in Sat May 27 15:47:31 2000 @@ -36,8 +36,6 @@ dep_tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA $CONFIG_PCI dep_tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960 $CONFIG_PCI -comment 'Additional Block Devices' - tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/nbd.c linux.ac/drivers/block/nbd.c --- linux.vanilla/drivers/block/nbd.c Thu May 25 17:37:59 2000 +++ linux.ac/drivers/block/nbd.c Mon May 29 19:35:38 2000 @@ -38,6 +38,8 @@ #include #include +#include + #include #include #include @@ -53,6 +55,7 @@ static u64 nbd_bytesizes[MAX_NBD]; static struct nbd_device nbd_dev[MAX_NBD]; +static devfs_handle_t devfs_handle = NULL; #define DEBUG( s ) /* #define DEBUG( s ) printk( s ) @@ -514,12 +517,20 @@ register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &nbd_fops, nbd_bytesizes[i]>>9); } + devfs_handle = devfs_mk_dir (NULL, "nbd", 0, NULL); + devfs_register_series (devfs_handle, "%u", MAX_NBD, + DEVFS_FL_DEFAULT, MAJOR_NR, 0, + S_IFBLK | S_IRUSR | S_IWUSR, 0, 0, + &nbd_fops, NULL); + return 0; } #ifdef MODULE void cleanup_module(void) { + devfs_unregister (devfs_handle); + if (unregister_blkdev(MAJOR_NR, "nbd") != 0) printk("nbd: cleanup_module failed\n"); else diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/rd.c linux.ac/drivers/block/rd.c --- linux.vanilla/drivers/block/rd.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/block/rd.c Tue May 9 23:07:40 2000 @@ -107,7 +107,11 @@ * architecture-specific setup routine (from the stored boot sector * information). */ +#if defined(CONFIG_ARCH_S390) +int rd_size = 8192; /* Size of the RAM disks */ +#else int rd_size = 4096; /* Size of the RAM disks */ +#endif /* * It would be very desiderable to have a soft-blocksize (that in the case * of the ramdisk driver is also the hardblocksize ;) of PAGE_SIZE because diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/xd.c linux.ac/drivers/block/xd.c --- linux.vanilla/drivers/block/xd.c Thu May 25 17:37:59 2000 +++ linux.ac/drivers/block/xd.c Sat May 27 15:51:09 2000 @@ -258,20 +258,19 @@ { int dev = DEVICE_NR(inode->i_rdev); + MOD_INC_USE_COUNT; + if (dev < xd_drives) { while (!xd_valid[dev]) sleep_on(&xd_wait_open); -#ifdef MODULE - MOD_INC_USE_COUNT; -#endif /* MODULE */ - xd_access[dev]++; return (0); } - else - return -ENXIO; + + MOD_DEC_USE_COUNT; + return -ENXIO; } /* do_xd_request: handle an incoming request */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/z2ram.c linux.ac/drivers/block/z2ram.c --- linux.vanilla/drivers/block/z2ram.c Thu May 25 17:37:59 2000 +++ linux.ac/drivers/block/z2ram.c Sat May 27 15:51:06 2000 @@ -165,12 +165,16 @@ sizeof( z2ram_map[0] ); int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) * sizeof( z2ram_map[0] ); + int rc = -ENOMEM; + + MOD_INC_USE_COUNT; device = DEVICE_NR( inode->i_rdev ); if ( current_device != -1 && current_device != device ) { - return -EBUSY; + rc = -EBUSY; + goto err_out; } if ( current_device == -1 ) @@ -188,7 +192,7 @@ if (index >= m68k_realnum_memory) { printk( KERN_ERR DEVICE_NAME ": no such entry in z2ram_map\n" ); - return -ENOMEM; + goto err_out; } paddr = m68k_memory[index].addr; @@ -215,7 +219,7 @@ { printk( KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n" ); - return -ENOMEM; + goto err_out; } while (size) { @@ -240,7 +244,7 @@ { printk( KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n" ); - return -ENOMEM; + goto err_out; } get_z2ram(); @@ -261,7 +265,7 @@ { printk( KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n" ); - return -ENOMEM; + goto err_out; } get_z2ram(); @@ -279,7 +283,7 @@ { printk( KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n" ); - return -ENOMEM; + goto err_out; } get_chipram(); @@ -292,15 +296,17 @@ break; default: - return -ENODEV; + rc = -ENODEV; + goto err_out; + + break; } if ( z2ram_size == 0 ) { - kfree( z2ram_map ); printk( KERN_NOTICE DEVICE_NAME ": no unused ZII/Chip RAM found\n" ); - return -ENOMEM; + goto err_out_kfree; } current_device = device; @@ -309,9 +315,13 @@ blk_size[ MAJOR_NR ] = z2_sizes; } - MOD_INC_USE_COUNT; - return 0; + +err_out_kfree: + kfree( z2ram_map ); +err_out: + MOD_DEC_USE_COUNT; + return rc; } static int diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/cdrom/aztcd.c linux.ac/drivers/cdrom/aztcd.c --- linux.vanilla/drivers/cdrom/aztcd.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/cdrom/aztcd.c Sat May 27 15:49:55 2000 @@ -1543,14 +1543,17 @@ #ifdef AZT_DEBUG printk("aztcd: starting aztcd_open\n"); #endif + if (aztPresent == 0) return -ENXIO; /* no hardware */ + MOD_INC_USE_COUNT; + if (!azt_open_count && azt_state == AZT_S_IDLE) { azt_invalidate_buffers(); st = getAztStatus(); /* check drive status */ - if (st == -1) return -EIO; /* drive doesn't respond */ + if (st == -1) goto err_out; /* drive doesn't respond */ if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */ @@ -1563,18 +1566,20 @@ { printk("aztcd: Disk Changed or No Disk in Drive?\n"); aztTocUpToDate=0; } - if (aztUpdateToc()) return -EIO; + if (aztUpdateToc()) goto err_out; } ++azt_open_count; - MOD_INC_USE_COUNT; aztLockDoor(); - #ifdef AZT_DEBUG printk("aztcd: exiting aztcd_open\n"); #endif return 0; + +err_out: + MOD_DEC_USE_COUNT; + return -EIO; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/cdrom/cdrom.c linux.ac/drivers/cdrom/cdrom.c --- linux.vanilla/drivers/cdrom/cdrom.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/cdrom/cdrom.c Thu May 25 20:32:58 2000 @@ -211,10 +211,15 @@ dvd_do_auth passed uninitialized data to drive because init_cdrom_command did not clear a 0 sized buffer. + 3.09 May 12, 2000 - Jens Axboe + -- Fix Video-CD on SCSI drives that don't support READ_CD command. In + that case switch block size and issue plain READ_10 again, then switch + back. + -------------------------------------------------------------------------*/ -#define REVISION "Revision: 3.08" -#define VERSION "Id: cdrom.c 3.08 2000/05/01" +#define REVISION "Revision: 3.09" +#define VERSION "Id: cdrom.c 3.09 2000/05/12" /* I use an error-log mask to give fine grain control over the type of messages dumped to the system logs. The available masks include: */ @@ -465,7 +470,7 @@ if ((cdi = cdrom_find_device(dev)) == NULL) return -ENODEV; - if (fp->f_mode & FMODE_WRITE) + if ((fp->f_mode & FMODE_WRITE) && !CDROM_CAN(CDC_DVD_RAM)) return -EROFS; /* if this was a O_NONBLOCK open and we should honor the flags, @@ -1371,6 +1376,28 @@ return 0; } +/* + * Specific READ_10 interface + */ +static int cdrom_read_cd(struct cdrom_device_info *cdi, + struct cdrom_generic_command *cgc, int lba, + int blocksize, int nblocks) +{ + struct cdrom_device_ops *cdo = cdi->ops; + + memset(&cgc->cmd, 0, sizeof(cgc->cmd)); + cgc->cmd[0] = GPCMD_READ_10; + cgc->cmd[2] = (lba >> 24) & 0xff; + cgc->cmd[3] = (lba >> 16) & 0xff; + cgc->cmd[4] = (lba >> 8) & 0xff; + cgc->cmd[5] = lba & 0xff; + cgc->cmd[6] = (nblocks >> 16) & 0xff; + cgc->cmd[7] = (nblocks >> 8) & 0xff; + cgc->cmd[8] = nblocks & 0xff; + cgc->buflen = blocksize * nblocks; + return cdo->generic_packet(cdi, cgc); +} + /* very generic interface for reading the various types of blocks */ static int cdrom_read_block(struct cdrom_device_info *cdi, struct cdrom_generic_command *cgc, @@ -1787,6 +1814,43 @@ return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET; } +/* + * Required when we need to use READ_10 to issue other than 2048 block + * reads + */ +static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size) +{ + struct cdrom_device_ops *cdo = cdi->ops; + struct cdrom_generic_command cgc; + struct modesel_head mh; + int ret; + + memset(&mh, 0, sizeof(mh)); + mh.block_desc_length = 0x08; + mh.block_length_med = (size >> 8) & 0xff; + mh.block_length_lo = size & 0xff; + + memset(&cgc, 0, sizeof(cgc)); + cgc.cmd[0] = 0x15; + cgc.cmd[1] = 1 << 4; + cgc.cmd[4] = 12; + cgc.buflen = sizeof(mh); + cgc.buffer = (char *) &mh; + cgc.data_direction = CGC_DATA_WRITE; + mh.block_desc_length = 0x08; + mh.block_length_med = (size >> 8) & 0xff; + mh.block_length_lo = size & 0xff; + + ret = cdo->generic_packet(cdi, &cgc); + if (ret) { + printk("switch_blocksize failed, ret %x ", ret); + if (cgc.sense) + printk("sense %02x.%02x.%02x", cgc.sense->sense_key, cgc.sense->asc, cgc.sense->ascq); + printk("\n"); + } + return ret; +} + static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, unsigned long arg) { @@ -1829,8 +1893,27 @@ return -ENOMEM; cgc.data_direction = CGC_DATA_READ; ret = cdrom_read_block(cdi, &cgc, lba, 1, format, blocksize); - if (!ret) - if (copy_to_user((char *)arg, cgc.buffer, blocksize)) + if (ret) { + /* + * SCSI-II devices are not required to support + * READ_CD, so let's try switching block size + */ + /* FIXME: switch back again... */ + if ((ret = cdrom_switch_blocksize(cdi, blocksize))) { + kfree(cgc.buffer); + return ret; + } + cgc.sense = NULL; + ret = cdrom_read_cd(cdi, &cgc, lba, blocksize, 1); + if (ret) { + printk("read_cd failed, ret %x ", ret); + if (cgc.sense) + printk("sense %02x.%02x.%02x", cgc.sense->sense_key, cgc.sense->asc, cgc.sense->ascq); + printk("\n"); + } + ret |= cdrom_switch_blocksize(cdi, blocksize); + } + if (!ret && copy_to_user((char *)arg, cgc.buffer, blocksize)) ret = -EFAULT; kfree(cgc.buffer); return ret; @@ -1867,8 +1950,7 @@ } cgc.data_direction = CGC_DATA_READ; while (ra.nframes > 0) { - ret = cdrom_read_block(cdi, &cgc, lba, frames, 1, - CD_FRAMESIZE_RAW); + ret = cdrom_read_block(cdi, &cgc, lba, frames, 1, CD_FRAMESIZE_RAW); if (ret) break; __copy_to_user(ra.buf, cgc.buffer, CD_FRAMESIZE_RAW * frames); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/cdrom/cm206.c linux.ac/drivers/cdrom/cm206.c --- linux.vanilla/drivers/cdrom/cm206.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/cdrom/cm206.c Sat May 27 15:50:10 2000 @@ -736,13 +736,14 @@ static int cm206_open(struct cdrom_device_info * cdi, int purpose) { + MOD_INC_USE_COUNT; if (!cd->openfiles) { /* reset only first time */ cd->background=0; reset_cm260(); cd->adapter_last = -1; /* invalidate adapter memory */ cd->sector_last = -1; } - ++cd->openfiles; MOD_INC_USE_COUNT; + ++cd->openfiles; stats(open); return 0; } @@ -757,7 +758,8 @@ cd->sector_last = -1; /* Make our internal buffer invalid */ FIRST_TRACK = 0; /* No valid disc status */ } - --cd->openfiles; MOD_DEC_USE_COUNT; + --cd->openfiles; + MOD_DEC_USE_COUNT; } /* Empty buffer empties $sectors$ sectors of the adapter card buffer, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/cdrom/mcd.c linux.ac/drivers/cdrom/mcd.c --- linux.vanilla/drivers/cdrom/mcd.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/cdrom/mcd.c Sat May 27 15:50:27 2000 @@ -1110,12 +1110,16 @@ if (mcdPresent == 0) return -ENXIO; /* no hardware */ - if (!mcd_open_count && mcd_state == MCD_S_IDLE) { + MOD_INC_USE_COUNT; + + if (mcd_open_count || mcd_state != MCD_S_IDLE) + goto bump_count; + mcd_invalidate_buffers(); do { st = statusCmd(); /* check drive status */ if (st == -1) - return -EIO; /* drive doesn't respond */ + goto err_out; /* drive doesn't respond */ if ((st & MST_READY) == 0) { /* no disk? wait a sec... */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(HZ); @@ -1123,11 +1127,15 @@ } while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS); if (updateToc() < 0) - return -EIO; - } + goto err_out; + +bump_count: ++mcd_open_count; - MOD_INC_USE_COUNT; return 0; + +err_out: + MOD_DEC_USE_COUNT; + return -EIO; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/cdrom/optcd.c linux.ac/drivers/cdrom/optcd.c --- linux.vanilla/drivers/cdrom/optcd.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/cdrom/optcd.c Sat May 27 15:50:42 2000 @@ -1871,6 +1871,8 @@ { DEBUG((DEBUG_VFS, "starting opt_open")); + MOD_INC_USE_COUNT; + if (!open_count && state == S_IDLE) { int status; @@ -1885,12 +1887,12 @@ status = drive_status(); if (status < 0) { DEBUG((DEBUG_VFS, "drive_status: %02x", -status)); - return -EIO; + goto err_out; } DEBUG((DEBUG_VFS, "status: %02x", status)); if ((status & ST_DOOR_OPEN) || (status & ST_DRVERR)) { printk(KERN_INFO "optcd: no disk or door open\n"); - return -EIO; + goto err_out; } status = exec_cmd(COMLOCK); /* Lock door */ if (status < 0) { @@ -1904,15 +1906,18 @@ DEBUG((DEBUG_VFS, "exec_cmd COMUNLOCK: %02x", -status)); } - return -EIO; + goto err_out; } open_count++; } - MOD_INC_USE_COUNT; DEBUG((DEBUG_VFS, "exiting opt_open")); return 0; + +err_out: + MOD_DEC_USE_COUNT; + return -EIO; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/cdrom/sjcd.c linux.ac/drivers/cdrom/sjcd.c --- linux.vanilla/drivers/cdrom/sjcd.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/cdrom/sjcd.c Sat May 27 22:04:47 2000 @@ -58,10 +58,7 @@ #define SJCD_VERSION_MAJOR 1 #define SJCD_VERSION_MINOR 7 -#ifdef MODULE #include -#endif /* MODULE */ - #include #include #include @@ -1339,6 +1336,8 @@ */ if( fp->f_mode & 2 ) return( -EROFS ); + MOD_INC_USE_COUNT; + if( sjcd_open_count == 0 ){ int s, sjcd_open_tries; /* We don't know that, do we? */ @@ -1360,7 +1359,7 @@ #if defined( SJCD_DIAGNOSTIC ) printk( "SJCD: open: timed out when check status.\n" ); #endif - return( -EIO ); + goto err_out; } else if( !sjcd_media_is_available ){ #if defined( SJCD_DIAGNOSTIC ) printk("SJCD: open: no disk in drive\n"); @@ -1375,10 +1374,10 @@ #if defined( SJCD_DIAGNOSTIC ) printk("SJCD: open: tray close attempt failed\n"); #endif - return( -EIO ); + goto err_out; } continue; - } else return( -EIO ); + } else goto err_out; } break; } @@ -1387,17 +1386,19 @@ #if defined( SJCD_DIAGNOSTIC ) printk("SJCD: open: tray lock attempt failed\n"); #endif - return( -EIO ); + goto err_out; } #if defined( SJCD_TRACE ) printk( "SJCD: open: done\n" ); #endif } -#ifdef MODULE - MOD_INC_USE_COUNT; -#endif + ++sjcd_open_count; return( 0 ); + +err_out: + MOD_DEC_USE_COUNT; + return( -EIO ); } /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/Makefile linux.ac/drivers/char/Makefile --- linux.vanilla/drivers/char/Makefile Thu May 25 17:37:59 2000 +++ linux.ac/drivers/char/Makefile Mon May 29 19:24:37 2000 @@ -134,39 +134,21 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_SPECIALIX) += specialix.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o -obj-$(CONFIG_SX) += sx.o -# If either SX or RIO is in the kernel, generic_serial goes in the -# kernel, and the module is no longer required. The "in kernel" case -# is last to be able to override the module case.... This is an -# example of the new "makefile automatically figures out the -# dependencies".... -- REW +# After much ado, we found that an object can safely be declared as +# both a module and into the kernel. Below that is filtered out. +# So this should simply provide the wanted functionality! +obj-$(CONFIG_SX) += sx.o generic_serial.o +obj-$(CONFIG_RIO) += rio/rio.o generic_serial.o -GS=n -ifeq ($(CONFIG_RIO),m) - M_OBJS += generic_serial.o - MOD_SUB_DIRS += rio - GS = m -endif - -ifeq ($(CONFIG_SX),m) - GS = m - M_OBJS += sx.o -endif ifeq ($(CONFIG_RIO),y) - L_OBJS += rio/rio.o generic_serial.o SUB_DIRS += rio - MOD_SUB_DIRS += rio - GS = y +else + ifeq ($(CONFIG_RIO),m) + MOD_SUB_DIRS += rio + endif endif - -ifeq ($(CONFIG_SX),y) - L_OBJS += sx.o - GS = y -endif - -obj-$(GS) += generic_serial.o obj-$(CONFIG_ATIXL_BUSMOUSE) += atixlmouse.o obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/adbmouse.c linux.ac/drivers/char/adbmouse.c --- linux.vanilla/drivers/char/adbmouse.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/adbmouse.c Sun Mar 19 18:23:12 2000 @@ -132,6 +132,10 @@ static int release_mouse(struct inode *inode, struct file *file) { adb_mouse_interrupt_hook = NULL; + /* + * FIXME?: adb_mouse_interrupt_hook may still be executing + * on another CPU. + */ MOD_DEC_USE_COUNT; return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/agp/agp.h linux.ac/drivers/char/agp/agp.h --- linux.vanilla/drivers/char/agp/agp.h Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/agp/agp.h Thu May 25 20:43:08 2000 @@ -151,6 +151,9 @@ #ifndef PCI_DEVICE_ID_INTEL_810_0 #define PCI_DEVICE_ID_INTEL_810_0 0x7120 #endif +#ifndef PCI_DEVICE_ID_INTEL_840_0 +#define PCI_DEVICE_ID_INTEL_840_0 0x1a21 +#endif #ifndef PCI_DEVICE_ID_INTEL_810_DC100_0 #define PCI_DEVICE_ID_INTEL_810_DC100_0 0x7122 #endif @@ -189,6 +192,10 @@ #define INTEL_AGPCTRL 0xb0 #define INTEL_NBXCFG 0x50 #define INTEL_ERRSTS 0x91 + +/* intel i840 registers */ +#define INTEL_I840_MCHCFG 0x50 +#define INTEL_I840_ERRSTS 0xc8 /* intel i810 registers */ #define I810_GMADDR 0x10 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/agp/agpgart_be.c linux.ac/drivers/char/agp/agpgart_be.c --- linux.vanilla/drivers/char/agp/agpgart_be.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/agp/agpgart_be.c Thu May 25 20:43:15 2000 @@ -1126,6 +1126,38 @@ return 0; } +static int intel_840_configure(void) +{ + u32 temp; + u16 temp2; + aper_size_info_16 *current_size; + + current_size = A_SIZE_16(agp_bridge.current_size); + + /* aperture size */ + pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, + (char)current_size->size_value); + + /* address to map to */ + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp); + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); + + /* attbase - aperture base */ + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, + agp_bridge.gatt_bus_addr); + + /* agpctrl */ + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); + + /* mcgcfg */ + pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2); + pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, + temp2 | (1 << 9)); + /* clear any possible error conditions */ + pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000); + return 0; +} + static unsigned long intel_mask_memory(unsigned long addr, int type) { /* Memory type is ignored */ @@ -1179,6 +1211,34 @@ (void) pdev; /* unused */ } +static int __init intel_840_setup (struct pci_dev *pdev) +{ + agp_bridge.masks = intel_generic_masks; + agp_bridge.num_of_masks = 1; + agp_bridge.aperture_sizes = (void *) intel_generic_sizes; + agp_bridge.size_type = U16_APER_SIZE; + agp_bridge.num_aperture_sizes = 7; + agp_bridge.dev_private_data = NULL; + agp_bridge.needs_scratch_page = FALSE; + agp_bridge.configure = intel_840_configure; + agp_bridge.fetch_size = intel_fetch_size; + agp_bridge.cleanup = intel_cleanup; + agp_bridge.tlb_flush = intel_tlbflush; + agp_bridge.mask_memory = intel_mask_memory; + agp_bridge.agp_enable = agp_generic_agp_enable; + agp_bridge.cache_flush = global_cache_flush; + agp_bridge.create_gatt_table = agp_generic_create_gatt_table; + agp_bridge.free_gatt_table = agp_generic_free_gatt_table; + agp_bridge.insert_memory = agp_generic_insert_memory; + agp_bridge.remove_memory = agp_generic_remove_memory; + agp_bridge.alloc_by_type = agp_generic_alloc_by_type; + agp_bridge.free_by_type = agp_generic_free_by_type; + + return 0; + + (void) pdev; /* unused */ +} + #endif /* CONFIG_AGP_INTEL */ #ifdef CONFIG_AGP_VIA @@ -1755,6 +1815,12 @@ "Intel", "440GX", intel_generic_setup }, + { PCI_DEVICE_ID_INTEL_840_0, + PCI_VENDOR_ID_INTEL, + INTEL_I840, + "Intel", + "i840", + intel_840_setup }, { 0, PCI_VENDOR_ID_INTEL, INTEL_GENERIC, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/agp/agpgart_fe.c linux.ac/drivers/char/agp/agpgart_fe.c --- linux.vanilla/drivers/char/agp/agpgart_fe.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/agp/agpgart_fe.c Sat May 27 15:49:10 2000 @@ -697,19 +697,18 @@ int minor = MINOR(inode->i_rdev); agp_file_private *priv; agp_client *client; + int rc = -ENXIO; AGP_LOCK(); + MOD_INC_USE_COUNT; + + if (minor != AGPGART_MINOR) + goto err_out; - if (minor != AGPGART_MINOR) { - AGP_UNLOCK(); - return -ENXIO; - } priv = kmalloc(sizeof(agp_file_private), GFP_KERNEL); + if (priv == NULL) + goto err_out_nomem; - if (priv == NULL) { - AGP_UNLOCK(); - return -ENOMEM; - } memset(priv, 0, sizeof(agp_file_private)); set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags); priv->my_pid = current->pid; @@ -726,9 +725,15 @@ } file->private_data = (void *) priv; agp_insert_file_private(priv); - MOD_INC_USE_COUNT; AGP_UNLOCK(); return 0; + +err_out_nomem: + rc = -ENOMEM; +err_out: + MOD_DEC_USE_COUNT; + AGP_UNLOCK(); + return rc; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/atarimouse.c linux.ac/drivers/char/atarimouse.c --- linux.vanilla/drivers/char/atarimouse.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/atarimouse.c Tue Mar 21 21:35:30 2000 @@ -39,37 +39,36 @@ static void atari_mouse_interrupt(char *buf) { - int buttons; + int buttons; -/* ikbd_mouse_disable(); */ +/* ikbd_mouse_disable(); */ - buttons = ((buf[0] & 1) + buttons = ((buf[0] & 1) | ((buf[0] & 2) << 1) | (atari_mouse_buttons & 2)); - atari_mouse_buttons = buttons; + atari_mouse_buttons = buttons; - busmouse_add_movementbuttons(msedev, buf[1], -buf[2], buttons ^ 7); -/* ikbd_mouse_rel_pos(); */ + busmouse_add_movementbuttons(msedev, buf[1], -buf[2], buttons ^ 7); +/* ikbd_mouse_rel_pos(); */ } static int release_mouse(struct inode *inode, struct file *file) { - ikbd_mouse_disable(); - - atari_mouse_interrupt_hook = NULL; - MOD_DEC_USE_COUNT; - return 0; + ikbd_mouse_disable(); + atari_mouse_interrupt_hook = NULL; + MOD_DEC_USE_COUNT; + return 0; } static int open_mouse(struct inode *inode, struct file *file) { - atari_mouse_buttons = 0; - ikbd_mouse_y0_top (); - ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]); - ikbd_mouse_rel_pos(); - MOD_INC_USE_COUNT; - atari_mouse_interrupt_hook = atari_mouse_interrupt; - return 0; + atari_mouse_buttons = 0; + ikbd_mouse_y0_top (); + ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]); + ikbd_mouse_rel_pos(); + MOD_INC_USE_COUNT; + atari_mouse_interrupt_hook = atari_mouse_interrupt; + return 0; } static struct busmouse atarimouse = { @@ -78,14 +77,14 @@ static int __init atari_mouse_init(void) { - if (!MACH_IS_ATARI) - return -ENODEV; - msedev = register_busmouse(&atarimouse); - if (msedev < 0) - printk(KERN_WARNING "Unable to register Atari mouse driver.\n"); - else - printk(KERN_INFO "Atari mouse installed.\n"); - return msedev < 0 ? msedev : 0; + if (!MACH_IS_ATARI) + return -ENODEV; + msedev = register_busmouse(&atarimouse); + if (msedev < 0) + printk(KERN_WARNING "Unable to register Atari mouse driver.\n"); + else + printk(KERN_INFO "Atari mouse installed.\n"); + return msedev < 0 ? msedev : 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/busmouse.c linux.ac/drivers/char/busmouse.c --- linux.vanilla/drivers/char/busmouse.c Thu May 25 17:38:00 2000 +++ linux.ac/drivers/char/busmouse.c Sat May 27 22:00:30 2000 @@ -110,8 +110,7 @@ if (changed) { wake_up(&mse->wait); - if (mse->fasyncptr) - kill_fasync(mse->fasyncptr, SIGIO, POLL_IN); + kill_fasync(&mse->fasyncptr, SIGIO, POLL_IN); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/c-qcam.c linux.ac/drivers/char/c-qcam.c --- linux.vanilla/drivers/char/c-qcam.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/c-qcam.c Mon May 29 19:42:50 2000 @@ -12,9 +12,15 @@ * probe=1 -- use IEEE-1284 autoprobe data only (default) * probe=2 -- probe aggressively for cameras * + * force_rgb=1 -- force data format to RGB (default is BGR) + * * The parport parameter controls which parports will be scanned. * Scanning all parports causes some printers to print a garbage page. * -- March 14, 1999 Billy Donahue + * + * Fixed data format to BGR, added force_rgb parameter. Added missing + * parport_unregister_driver() on module removal. + * -- May 28, 2000 Claudio Matsuoka */ #include @@ -62,6 +68,7 @@ static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; static int probe = 2; +static int force_rgb = 0; static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) { @@ -278,6 +285,7 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes) { unsigned int bytes = 0; + qcam_set_ack(q, 0); if (q->bidirectional) { @@ -285,6 +293,8 @@ while (bytes < nbytes) { unsigned int lo1, hi1, lo2, hi2; + unsigned char r, g, b; + if (qcam_await_ready2(q, 1)) return bytes; lo1 = parport_read_data(q->pport) >> 1; hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; @@ -293,17 +303,30 @@ lo2 = parport_read_data(q->pport) >> 1; hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; qcam_set_ack(q, 0); - buf[bytes++] = (lo1 | ((hi1 & 1)<<7)); - buf[bytes++] = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1); - buf[bytes++] = (lo2 | ((hi2 & 1)<<7)); + r = (lo1 | ((hi1 & 1)<<7)); + g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1); + b = (lo2 | ((hi2 & 1)<<7)); + if (force_rgb) { + buf[bytes++] = r; + buf[bytes++] = g; + buf[bytes++] = b; + } else { + buf[bytes++] = b; + buf[bytes++] = g; + buf[bytes++] = r; + } } } else { /* It's a unidirectional port */ + int i = 0, n = bytes; + unsigned char rgb[3]; + while (bytes < nbytes) { unsigned int hi, lo; + if (qcam_await_ready1(q, 1)) return bytes; hi = (parport_read_status(q->pport) & 0xf0); qcam_set_ack(q, 1); @@ -311,7 +334,23 @@ lo = (parport_read_status(q->pport) & 0xf0); qcam_set_ack(q, 0); /* flip some bits */ - buf[bytes++] = (hi | (lo >> 4)) ^ 0x88; + rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88; + if (i >= 2) { +get_fragment: + if (force_rgb) { + buf[n++] = rgb[0]; + buf[n++] = rgb[1]; + buf[n++] = rgb[2]; + } else { + buf[n++] = rgb[2]; + buf[n++] = rgb[1]; + buf[n++] = rgb[0]; + } + } + } + if (i) { + i = 0; + goto get_fragment; } } return bytes; @@ -408,8 +447,13 @@ if (current->need_resched) schedule(); } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e)); - if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) - printk("qcam: bad EOF\n"); + if (force_rgb) { + if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) + printk("qcam: bad EOF\n"); + } else { + if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) + printk("qcam: bad EOF\n"); + } qcam_set_ack(q, 0); if (qcam_await_ready1(q, 1)) { @@ -437,8 +481,13 @@ schedule(); } while (l && tmpbuf[0] == 0x7e); l = qcam_read_bytes(q, tmpbuf+1, 2); - if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) - printk("qcam: bad EOF\n"); + if (force_rgb) { + if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) + printk("qcam: bad EOF\n"); + } else { + if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) + printk("qcam: bad EOF\n"); + } } qcam_write_data(q, 0); @@ -829,19 +878,24 @@ return parport_register_driver(&cqcam_driver); } -MODULE_AUTHOR("Philip Blundell "); -MODULE_DESCRIPTION(BANNER); -MODULE_PARM_DESC(parport ,"parport= for port detection method \n\ -probe=<0|1|2> # for camera detection method"); -MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i"); -MODULE_PARM(probe, "i"); - static void __exit cqcam_cleanup (void) { unsigned int i; + for (i = 0; i < num_cams; i++) close_cqcam(qcams[i]); + + parport_unregister_driver(&cqcam_driver); } + +MODULE_AUTHOR("Philip Blundell "); +MODULE_DESCRIPTION(BANNER); +MODULE_PARM_DESC(parport ,"parport= for port detection method\n\ +probe=<0|1|2> for camera detection method\n\ +force_rgb=<0|1> for RGB data format (default BGR)"); +MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i"); +MODULE_PARM(probe, "i"); +MODULE_PARM(force_rgb, "i"); module_init(cqcam_init); module_exit(cqcam_cleanup); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/dn_keyb.c linux.ac/drivers/char/dn_keyb.c --- linux.vanilla/drivers/char/dn_keyb.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/dn_keyb.c Sat May 27 22:00:30 2000 @@ -357,17 +357,14 @@ mouse_dy+=mouse_packet[2] == 0xff ? 0 : (signed char)mouse_packet[2]; wake_up_interruptible(&mouse_wait); if (mouse_dx < -2048) - mouse_dx = -2048; - else - if (mouse_dx > 2048) - mouse_dx = 2048; - if (mouse_dy < -2048) - mouse_dy = -2048; - else - if (mouse_dy > 2048) - mouse_dy = 2048; - if (mouse_fasyncptr) - kill_fasync(mouse_fasyncptr, SIGIO, POLL_IN); + mouse_dx = -2048; + else if (mouse_dx > 2048) + mouse_dx = 2048; + if (mouse_dy < -2048) + mouse_dy = -2048; + else if (mouse_dy > 2048) + mouse_dy = 2048; + kill_fasync(&mouse_fasyncptr, SIGIO, POLL_IN); } mouse_byte_count=0; /* printk("mouse: %d, %d, %x\n",mouse_x,mouse_y,buttons); */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/drm/fops.c linux.ac/drivers/char/drm/fops.c --- linux.vanilla/drivers/char/drm/fops.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/drm/fops.c Sat May 27 22:00:30 2000 @@ -216,7 +216,7 @@ if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO); #else /* Parameter added in 2.3.21 */ - if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN); + kill_fasync(&dev->buf_async, SIGIO, POLL_IN); #endif DRM_DEBUG("waking\n"); wake_up_interruptible(&dev->buf_readers); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/epca.c linux.ac/drivers/char/epca.c --- linux.vanilla/drivers/char/epca.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/epca.c Sat May 27 15:29:11 2000 @@ -4007,6 +4007,9 @@ int board_idx, info_idx = ent->driver_data; unsigned long addr; + if (pci_enable_device(pdev)) + return -EIO; + board_num++; board_idx = board_num + num_cards; if (board_idx >= MAXBOARDS) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/joystick/joy-pci.c linux.ac/drivers/char/joystick/joy-pci.c --- linux.vanilla/drivers/char/joystick/joy-pci.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/joystick/joy-pci.c Sat May 27 15:27:29 2000 @@ -243,7 +243,8 @@ for (i = 0; js_pci_data[i].vendor; i++) for (j = 0; (pci_p = pci_find_device(js_pci_data[i].vendor, js_pci_data[i].model, pci_p)); j++) - js_pci_port = js_pci_probe(js_pci_port, i, j, pci_p, js_pci_data + i); + if (pci_enable_device(pci_p) == 0) + js_pci_port = js_pci_probe(js_pci_port, i, j, pci_p, js_pci_data + i); if (!js_pci_port) { #ifdef MODULE diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/mxser.c linux.ac/drivers/char/mxser.c --- linux.vanilla/drivers/char/mxser.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/mxser.c Sat May 27 15:26:52 2000 @@ -618,6 +618,8 @@ mxser_pcibrds[b].device_id, pdev); if (!pdev) break; + if (pci_enable_device(pdev)) + continue; b++; hwconf.pdev = pdev; printk("Found MOXA %s board(BusNo=%d,DevNo=%d)\n", diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/n_hdlc.c linux.ac/drivers/char/n_hdlc.c --- linux.vanilla/drivers/char/n_hdlc.c Thu May 25 17:38:00 2000 +++ linux.ac/drivers/char/n_hdlc.c Sat May 27 22:00:30 2000 @@ -663,7 +663,7 @@ #if LINUX_VERSION_CODE < VERSION(2,3,0) kill_fasync (n_hdlc->tty->fasync, SIGIO); #else - kill_fasync (n_hdlc->tty->fasync, SIGIO, POLL_IN); + kill_fasync(&n_hdlc->tty->fasync, SIGIO, POLL_IN); #endif } /* end of n_hdlc_tty_receive() */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/n_tty.c linux.ac/drivers/char/n_tty.c --- linux.vanilla/drivers/char/n_tty.c Thu May 25 17:38:00 2000 +++ linux.ac/drivers/char/n_tty.c Sat May 27 22:00:30 2000 @@ -630,8 +630,7 @@ put_tty_queue(c, tty); tty->canon_head = tty->read_head; tty->canon_data++; - if (tty->fasync) - kill_fasync(tty->fasync, SIGIO, POLL_IN); + kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); return; @@ -735,8 +734,7 @@ } if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { - if (tty->fasync) - kill_fasync(tty->fasync, SIGIO, POLL_IN); + kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/pc110pad.c linux.ac/drivers/char/pc110pad.c --- linux.vanilla/drivers/char/pc110pad.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/pc110pad.c Sat May 27 22:00:30 2000 @@ -83,8 +83,7 @@ static void wake_readers(void) { wake_up_interruptible(&queue); - if(asyncptr) - kill_fasync(asyncptr, SIGIO, POLL_IN); + kill_fasync(&asyncptr, SIGIO, POLL_IN); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/pc_keyb.c linux.ac/drivers/char/pc_keyb.c --- linux.vanilla/drivers/char/pc_keyb.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/pc_keyb.c Sat May 27 22:00:30 2000 @@ -415,8 +415,7 @@ head = (head + 1) & (AUX_BUF_SIZE-1); if (head != queue->tail) { queue->head = head; - if (queue->fasync) - kill_fasync(queue->fasync, SIGIO, POLL_IN); + kill_fasync(&queue->fasync, SIGIO, POLL_IN); wake_up_interruptible(&queue->proc_list); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/pcmcia/serial_cb.c linux.ac/drivers/char/pcmcia/serial_cb.c --- linux.vanilla/drivers/char/pcmcia/serial_cb.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/pcmcia/serial_cb.c Sat May 27 15:25:59 2000 @@ -92,6 +92,7 @@ if (loc->bus != LOC_PCI) goto err_out; pdev = pci_find_slot (loc->b.pci.bus, loc->b.pci.devfn); if (!pdev) goto err_out; + if (pci_enable_device(pdev)) goto err_out; printk(KERN_INFO "serial_attach(bus %d, fn %d)\n", pdev->bus->number, pdev->devfn); io = pci_resource_start (pdev, 0); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/qpmouse.c linux.ac/drivers/char/qpmouse.c --- linux.vanilla/drivers/char/qpmouse.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/qpmouse.c Sat May 27 22:00:30 2000 @@ -133,8 +133,7 @@ head &= QP_BUF_SIZE-1; } queue->head = head; - if (queue->fasync) - kill_fasync(queue->fasync, SIGIO, POLL_IN); + kill_fasync(&queue->fasync, SIGIO, POLL_IN); wake_up_interruptible(&queue->proc_list); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/rio/rio_linux.c linux.ac/drivers/char/rio/rio_linux.c --- linux.vanilla/drivers/char/rio/rio_linux.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/rio/rio_linux.c Sat May 27 15:31:06 2000 @@ -1149,6 +1149,7 @@ while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { + if (pci_enable_device(pdev)) continue; #else for (i=0;i< RIO_NBOARDS;i++) { if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, @@ -1234,6 +1235,7 @@ while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { + if (pci_enable_device(pdev)) continue; #else for (i=0;i< RIO_NBOARDS;i++) { if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/rocket.c linux.ac/drivers/char/rocket.c --- linux.vanilla/drivers/char/rocket.c Thu May 25 17:38:00 2000 +++ linux.ac/drivers/char/rocket.c Sat May 27 15:26:22 2000 @@ -1957,7 +1957,10 @@ if (!dev) return 0; - rcktpt_io_addr[i] = dev->resource[0].start; + if (pci_enable_device(dev)) + return 0; + + rcktpt_io_addr[i] = pci_resource_start (dev, 0); switch(dev->device) { case PCI_DEVICE_ID_RP4QUAD: str = "Quadcable"; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/rtc.c linux.ac/drivers/char/rtc.c --- linux.vanilla/drivers/char/rtc.c Thu May 25 17:38:01 2000 +++ linux.ac/drivers/char/rtc.c Sat May 27 22:00:30 2000 @@ -179,8 +179,7 @@ /* Now do the rest of the actions */ wake_up_interruptible(&rtc_wait); - if (rtc_async_queue) - kill_fasync (rtc_async_queue, SIGIO, POLL_IN); + kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); } #endif @@ -781,8 +780,7 @@ /* Now we have new data */ wake_up_interruptible(&rtc_wait); - if (rtc_async_queue) - kill_fasync (rtc_async_queue, SIGIO, POLL_IN); + kill_fasync (&rtc_async_queue, SIGIO, POLL_IN); } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/tty_io.c linux.ac/drivers/char/tty_io.c --- linux.vanilla/drivers/char/tty_io.c Thu May 25 17:37:59 2000 +++ linux.ac/drivers/char/tty_io.c Sat May 27 22:00:30 2000 @@ -1427,49 +1427,6 @@ return 0; } -/* - * fasync_helper() is used by some character device drivers (mainly mice) - * to set up the fasync queue. It returns negative on error, 0 if it did - * no changes and positive if it added/deleted the entry. - */ -int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) -{ - struct fasync_struct *fa, **fp; - unsigned long flags; - - for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) { - if (fa->fa_file == filp) - break; - } - - if (on) { - if (fa) { - fa->fa_fd = fd; - return 0; - } - fa = (struct fasync_struct *)kmalloc(sizeof(struct fasync_struct), GFP_KERNEL); - if (!fa) - return -ENOMEM; - fa->magic = FASYNC_MAGIC; - fa->fa_file = filp; - fa->fa_fd = fd; - save_flags(flags); - cli(); - fa->fa_next = *fapp; - *fapp = fa; - restore_flags(flags); - return 1; - } - if (!fa) - return 0; - save_flags(flags); - cli(); - *fp = fa->fa_next; - restore_flags(flags); - kfree(fa); - return 1; -} - static int tty_fasync(int fd, struct file * filp, int on) { struct tty_struct * tty; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/wdt_pci.c linux.ac/drivers/char/wdt_pci.c --- linux.vanilla/drivers/char/wdt_pci.c Thu May 25 17:38:03 2000 +++ linux.ac/drivers/char/wdt_pci.c Fri May 26 14:31:59 2000 @@ -28,6 +28,7 @@ * Parameterized timeout * JP Nollmann : Added support for PCI wdt501p * Alan Cox : Split ISA and PCI cards into two drivers + * Jeff Garzik : PCI cleanups */ #include @@ -53,6 +54,8 @@ #include +#define PFX "wdt_pci: " + /* * Until Access I/O gets their application for a PCI vendor ID approved, * I don't think that it's appropriate to move these constants into the @@ -487,12 +490,86 @@ 0 }; -#ifdef MODULE -#define wdtpci_init init_module +static int __init wdtpci_init_one (struct pci_dev *dev, + const struct pci_device_id *ent) +{ + static int dev_count = 0; + + dev_count++; + if (dev_count > 1) { + printk (KERN_ERR PFX + "this driver only supports 1 device\n"); + return -ENODEV; + } + + irq = dev->irq; + io = pci_resource_start (dev, 2); + printk ("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X " + "(Interrupt %d)\n", io, irq); + + if (pci_enable_device (dev)) + goto err_out; + + if (request_region (io, 16, "wdt-pci") == NULL) { + printk (KERN_ERR PFX "I/O %d is not free.\n", io); + goto err_out; + } + + if (request_irq (irq, wdtpci_interrupt, SA_INTERRUPT | SA_SHIRQ, + "wdt-pci", &wdtpci_miscdev)) { + printk (KERN_ERR PFX "IRQ %d is not free.\n", irq); + goto err_out_free_res; + } + + misc_register (&wdtpci_miscdev); + +#ifdef CONFIG_WDT_501 + misc_register (&temp_miscdev); +#endif + + register_reboot_notifier (&wdtpci_notifier); + + return 0; + +err_out_free_res: + release_region (io, 16); +err_out: + return -EIO; +} + + +static void __exit wdtpci_remove_one (struct pci_dev *pdev) +{ + /* here we assume only one device will ever have + * been picked up and registered by probe function */ + unregister_reboot_notifier(&wdtpci_notifier); +#ifdef CONFIG_WDT_501_PCI + misc_deregister(&temp_miscdev); +#endif + misc_deregister(&wdtpci_miscdev); + free_irq(irq, &wdtpci_miscdev); + release_region(io, 16); +} + + +static struct pci_device_id wdtpci_pci_tbl[] __initdata = { + { PCI_VENDOR_ID_ACCESSIO, PCI_DEVICE_ID_WDG_CSM, }, + { 0, }, /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl); + + +static struct pci_driver wdtpci_driver = { + name: "wdt-pci", + id_table: wdtpci_pci_tbl, + probe: wdtpci_init_one, + remove: wdtpci_remove_one, +}; + /** - * cleanup_module: + * wdtpci_cleanup: * * Unload the watchdog. You cannot do this with any file handles open. * If your watchdog is set to continue ticking on close and you unload @@ -501,18 +578,11 @@ * module in 60 seconds or reboot. */ -void cleanup_module(void) +static void __exit wdtpci_cleanup(void) { - misc_deregister(&wdtpci_miscdev); -#ifdef CONFIG_WDT_501_PCI - misc_deregister(&temp_miscdev); -#endif - unregister_reboot_notifier(&wdtpci_notifier); - release_region(io,16); - free_irq(irq, &wdtpci_miscdev); + pci_unregister_driver (&wdtpci_driver); } -#endif /** * wdtpci_init: @@ -522,37 +592,16 @@ * The open() function will actually kick the board off. */ -int __init wdtpci_init(void) +static int __init wdtpci_init(void) { - struct pci_dev *dev = NULL; - - if (pci_present()) - { - while ((dev = pci_find_device(PCI_VENDOR_ID_ACCESSIO, - PCI_DEVICE_ID_WDG_CSM, dev))) { - /* See if we can do this device */ - irq = dev->irq; - io = dev->resource[2].start; - printk("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X " - "(Interrupt %d)\n", io, irq); - } - } - if(request_region(io, 16, "wdt-pci")==NULL) - { - printk(KERN_ERR "I/O %d is not free.\n", io); - return -EIO; - } - if(request_irq(irq, wdtpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "wdt-pci", &wdtpci_miscdev)) - { - printk(KERN_ERR "IRQ %d is not free.\n", irq); - release_region(io, 16); - return -EIO; - } - misc_register(&wdtpci_miscdev); -#ifdef CONFIG_WDT_501 - misc_register(&temp_miscdev); -#endif - register_reboot_notifier(&wdtpci_notifier); + int rc = pci_register_driver (&wdtpci_driver); + + if (rc < 1) + return -ENODEV; + return 0; } + +module_init(wdtpci_init); +module_exit(wdtpci_cleanup); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/i2o/README linux.ac/drivers/i2o/README --- linux.vanilla/drivers/i2o/README Thu May 25 17:38:17 2000 +++ linux.ac/drivers/i2o/README Fri May 26 14:21:11 2000 @@ -92,7 +92,6 @@ Lan: o Performance tuning o Test Fibre Channel code -o Fix lan_set_mc_list() Tape: o Anyone seen anything implementing this ? diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/i2o/i2o_config.c linux.ac/drivers/i2o/i2o_config.c --- linux.vanilla/drivers/i2o/i2o_config.c Thu May 25 17:38:18 2000 +++ linux.ac/drivers/i2o/i2o_config.c Sat May 27 22:00:30 2000 @@ -161,8 +161,7 @@ // printk(KERN_INFO "File %p w/id %d has %d events\n", // inf->fp, inf->q_id, inf->q_len); - if(inf->fasync) - kill_fasync(inf->fasync, SIGIO, POLL_IN); + kill_fasync(&inf->fasync, SIGIO, POLL_IN); } return; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/i2o/i2o_core.c linux.ac/drivers/i2o/i2o_core.c --- linux.vanilla/drivers/i2o/i2o_core.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/i2o/i2o_core.c Fri May 26 14:21:11 2000 @@ -189,7 +189,8 @@ * I2O configuration spinlock. This isnt a big deal for contention * so we have one only */ -static struct semaphore i2o_configuration_lock; + +static DECLARE_MUTEX(i2o_configuration_lock); /* * Event spinlock. Used to keep event queue sane and from @@ -883,11 +884,11 @@ switch(msg[4]) { case I2O_EVT_IND_EXEC_RESOURCE_LIMITS: - printk(KERN_ERR "iop%d: Out of resources\n", c->unit); + printk(KERN_ERR "%s: Out of resources\n", c->name); break; case I2O_EVT_IND_EXEC_POWER_FAIL: - printk(KERN_ERR "iop%d: Power failure\n", c->unit); + printk(KERN_ERR "%s: Power failure\n", c->name); break; case I2O_EVT_IND_EXEC_HW_FAIL: @@ -1027,12 +1028,12 @@ entries -= 3; entries /= 9; - dprintk(KERN_INFO "I2O: Dynamic LCT Update\n"); - dprintk(KERN_INFO "I2O: Dynamic LCT contains %d entries\n", entries); + dprintk(KERN_INFO "%s: Dynamic LCT Update\n",c->name); + dprintk(KERN_INFO "%s: Dynamic LCT contains %d entries\n", c->name, entries); if(!entries) { - printk(KERN_INFO "iop%d: Empty LCT???\n", c->unit); + printk(KERN_INFO "%s: Empty LCT???\n", c->name); continue; } @@ -1059,7 +1060,7 @@ } if(!found) { - dprintk(KERN_INFO "Deleted device!\n"); + dprintk(KERN_INFO "i2o_core: Deleted device!\n"); spin_lock(&i2o_dev_lock); i2o_delete_device(d); spin_unlock(&i2o_dev_lock); @@ -1111,7 +1112,6 @@ struct i2o_message *m; u32 mv; u32 *msg; - int count = 0; /* * Old 960 steppings had a bug in the I2O unit that caused @@ -1126,8 +1126,6 @@ m=(struct i2o_message *)bus_to_virt(mv); msg=(u32*)m; - count++; - /* * Temporary Debugging */ @@ -1148,7 +1146,6 @@ /* That 960 bug again... */ if((mv=I2O_REPLY_READ32(c))==0xFFFFFFFF) mv=I2O_REPLY_READ32(c); - } } @@ -1281,7 +1278,6 @@ } if((ret=i2o_query_scalar(c, unit, 0xF100, 4, buf, 16))>=0) { - buf[16]=0; printk(KERN_INFO " Device: %s\n", buf); } @@ -1657,7 +1653,8 @@ * time, we assume the IOP could not reboot properly. */ - dprintk(KERN_INFO "Reset in progress, waiting for reboot\n"); + dprintk(KERN_INFO "%s: Reset in progress, waiting for reboot...\n", + c->name); time = jiffies; m = I2O_POST_READ32(c); @@ -1733,8 +1730,7 @@ m=i2o_wait_message(c, "StatusGet"); if(m==0xFFFFFFFF) - return -ETIMEDOUT; - + return -ETIMEDOUT; msg=(u32 *)(c->mem_offset+m); msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0; @@ -1897,12 +1893,12 @@ { struct i2o_controller *iop, *niop = NULL; - printk(KERN_INFO "Activating I2O controllers\n"); + printk(KERN_INFO "Activating I2O controllers...\n"); printk(KERN_INFO "This may take a few minutes if there are many devices\n"); /* In INIT state, Activate IOPs */ for (iop = i2o_controller_chain; iop; iop = niop) { - dprintk(KERN_INFO "Calling i2o_activate_controller for %s\n", + dprintk(KERN_INFO "Calling i2o_activate_controller for %s...\n", iop->name); niop = iop->next; if (i2o_activate_controller(iop) < 0) @@ -1919,7 +1915,7 @@ * If build_sys_table fails, we kill everything and bail * as we can't init the IOPs w/o a system table */ - dprintk(KERN_INFO "calling i2o_build_sys_table\n"); + dprintk(KERN_INFO "i2o_core: Calling i2o_build_sys_table...\n"); if (i2o_build_sys_table() < 0) { i2o_sys_shutdown(); return; @@ -1928,7 +1924,7 @@ /* If IOP don't get online, we need to rebuild the System table */ for (iop = i2o_controller_chain; iop; iop = niop) { niop = iop->next; - dprintk(KERN_INFO "Calling i2o_online_controller for %s\n", iop->name); + dprintk(KERN_INFO "Calling i2o_online_controller for %s...\n", iop->name); if (i2o_online_controller(iop) < 0) { i2o_delete_controller(iop); goto rebuild_sys_tab; @@ -1992,7 +1988,8 @@ /* In READY state, Get status */ if (i2o_status_get(iop) < 0) { - printk(KERN_INFO "Unable to obtain status of IOP, attempting a reset.\n"); + printk(KERN_INFO "Unable to obtain status of %s, " + "attempting a reset.\n", iop->name); if (i2o_reset_controller(iop) < 0) return -1; } @@ -2002,13 +1999,19 @@ return -1; } + if (iop->status_block->i2o_version > I2OVER15) { + printk(KERN_ERR "%s: Not running vrs. 1.5. of the I2O Specification.\n", + iop->name); + return -1; + } + if (iop->status_block->iop_state == ADAPTER_STATE_READY || iop->status_block->iop_state == ADAPTER_STATE_OPERATIONAL || iop->status_block->iop_state == ADAPTER_STATE_HOLD || iop->status_block->iop_state == ADAPTER_STATE_FAILED) { u32 m[MSG_FRAME_SIZE]; - dprintk(KERN_INFO "%s: Already running, trying to reset\n", + dprintk(KERN_INFO "%s: Already running, trying to reset...\n", iop->name); i2o_init_outbound_q(iop); @@ -2048,7 +2051,7 @@ u32 *msg; u32 time; - dprintk(KERN_INFO "%s: Initializing Outbound Queue\n", c->name); + dprintk(KERN_INFO "%s: Initializing Outbound Queue...\n", c->name); m=i2o_wait_message(c, "OutboundInit"); if(m==0xFFFFFFFF) return -ETIMEDOUT; @@ -2217,13 +2220,13 @@ /* In READY state */ - dprintk(KERN_INFO "Attempting to enable iop%d\n", iop->unit); + dprintk(KERN_INFO "%s: Attempting to enable...\n", iop->name); if (i2o_enable_controller(iop) < 0) return -1; /* In OPERATIONAL state */ - dprintk(KERN_INFO "Attempting to get/parse lct iop%d\n", iop->unit); + dprintk(KERN_INFO "%s: Attempting to get/parse lct...\n", iop->name); if (i2o_lct_get(iop) < 0) return -1; @@ -2275,7 +2278,7 @@ */ if(i2o_status_get(iop)) { printk(KERN_ERR "%s: Deleting b/c could not get status while" - "attempting to build system table", iop->name); + "attempting to build system table\n", iop->name); i2o_delete_controller(iop); sys_tbl->num_entries--; continue; // try the next one @@ -2338,7 +2341,6 @@ } while(m==0xFFFFFFFF && (jiffies-t)= 0xA0 && cmd <= 0xEF)) - i2o_report_common_dsc(detailed_status); - - if (h->class == I2O_CLASS_LAN && cmd >= 0x30 && cmd <= 0x3F) + i2o_report_common_dsc(detailed_status); + else if (h->class == I2O_CLASS_LAN && cmd >= 0x30 && cmd <= 0x3F) i2o_report_lan_dsc(detailed_status); else printk(" / DetailedStatus = %0#4x.\n", detailed_status); @@ -3189,7 +3190,7 @@ return 0; } else - printk(KERN_INFO "event thread created as pid %d\n", evt_pid); + printk(KERN_INFO "I2O: Event thread created as pid %d\n", evt_pid); if(i2o_num_controllers) i2o_sys_init(); @@ -3246,8 +3247,6 @@ int __init i2o_init(void) { printk(KERN_INFO "Loading I2O Core - (c) Copyright 1999 Red Hat Software\n"); - - init_MUTEX(&i2o_configuration_lock); if (i2o_install_handler(&i2o_core_handler) < 0) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/i2o/i2o_lan.c linux.ac/drivers/i2o/i2o_lan.c --- linux.vanilla/drivers/i2o/i2o_lan.c Thu May 25 17:38:18 2000 +++ linux.ac/drivers/i2o/i2o_lan.c Fri May 26 14:21:11 2000 @@ -1,7 +1,7 @@ /* * drivers/i2o/i2o_lan.c * - * I2O LAN CLASS OSM May 4th 2000 + * I2O LAN CLASS OSM May 26th 2000 * * (C) Copyright 1999, 2000 University of Helsinki, * Department of Computer Science @@ -68,9 +68,7 @@ static struct net_device *i2o_landevs[MAX_LAN_CARDS+1]; static int unit = -1; /* device unit number */ -extern rwlock_t dev_mc_lock; - -static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m); +static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m); static void i2o_lan_send_post_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m); static int i2o_lan_receive_post(struct net_device *dev); static void i2o_lan_receive_post_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m); @@ -86,7 +84,7 @@ NULL, NULL, NULL, - "I2O Lan OSM send", + "I2O LAN OSM send", -1, I2O_CLASS_LAN }; @@ -97,7 +95,7 @@ NULL, NULL, NULL, - "I2O Lan OSM receive", + "I2O LAN OSM receive", -1, I2O_CLASS_LAN }; @@ -108,7 +106,7 @@ NULL, NULL, NULL, - "I2O Lan OSM", + "I2O LAN OSM", -1, I2O_CLASS_LAN }; @@ -133,7 +131,6 @@ struct i2o_controller *iop = i2o_dev->controller; u32 *preserved_msg = (u32*)(iop->mem_offset + msg[7]); - // FIXME on 64-bit host u32 *sgl_elem = &preserved_msg[4]; struct sk_buff *skb = NULL; u8 le_flag; @@ -259,11 +256,13 @@ i2o_report_status(KERN_INFO, dev->name, msg); #endif - /* DDM has handled transmit request(s), free sk_buffs */ - + /* DDM has handled transmit request(s), free sk_buffs. + * We get similar single transaction reply also in error cases + * (except if msg failure or transaction error). + */ while (trl_count) { dev_kfree_skb_irq((struct sk_buff *)msg[4 + trl_count]); - dprintk(KERN_INFO "%s: Request skb freed (trl_count=%d).\n", + dprintk(KERN_INFO "%s: tx skb freed (trl_count=%d).\n", dev->name, trl_count); atomic_dec(&priv->tx_out); trl_count--; @@ -296,15 +295,8 @@ if (i2o_lan_handle_status(dev, msg)) return; - /* Getting unused buckets back? */ - - if (msg[4] & I2O_LAN_DSC_CANCELED || - msg[4] & I2O_LAN_DSC_RECEIVE_ABORTED) { - i2o_lan_release_buckets(dev, msg); - return; - } - - /* If other DetailedStatusCodes need special code, add it here */ + i2o_lan_release_buckets(dev, msg); + return; } #ifdef DRIVERDEBUG @@ -410,26 +402,43 @@ if (i2o_lan_handle_status(dev, msg)) return; - /* This should NOT be reached */ + /* In other error cases just report and continue */ + + i2o_report_status(KERN_INFO, dev->name, msg); } #ifdef DRIVERDEBUG i2o_report_status(KERN_INFO, dev->name, msg); #endif - switch (msg[1] >> 24) { - case LAN_RESET: - case LAN_SUSPEND: - /* default reply without payload */ + case LAN_RESET: + case LAN_SUSPEND: + /* default reply without payload */ break; - case I2O_CMD_UTIL_EVT_REGISTER: - case I2O_CMD_UTIL_EVT_ACK: - i2o_lan_handle_event(dev, msg); + + case I2O_CMD_UTIL_EVT_REGISTER: + case I2O_CMD_UTIL_EVT_ACK: + i2o_lan_handle_event(dev, msg); break; - default: - printk(KERN_ERR "%s: No handler for the reply.\n", - dev->name); - i2o_report_status(KERN_INFO, dev->name, msg); + + case I2O_CMD_UTIL_PARAMS_SET: + /* default reply, results in ReplyPayload (not examined) */ + switch (msg[3] >> 16) { + case 1: dprintk(KERN_INFO "%s: Reply to set MAC filter mask.\n", + dev->name); + break; + case 2: dprintk(KERN_INFO "%s: Reply to set MAC table.\n", + dev->name); + break; + default: printk(KERN_WARNING "%s: Bad group 0x%04X\n", + dev->name,msg[3] >> 16); + } + break; + + default: + printk(KERN_ERR "%s: No handler for the reply.\n", + dev->name); + i2o_report_status(KERN_INFO, dev->name, msg); } } @@ -446,7 +455,7 @@ u32 *pskb = &msg[6]; while (trl_count--) { - dprintk(KERN_DEBUG "%s: Releasing unused sk_buff %p (trl_count=%d).\n", + dprintk(KERN_DEBUG "%s: Releasing unused rx skb %p (trl_count=%d).\n", dev->name, (struct sk_buff*)(*pskb),trl_count+1); dev_kfree_skb_irq((struct sk_buff *)(*pskb)); pskb += 1 + trl_elem_size; @@ -464,22 +473,15 @@ struct i2o_controller *iop = i2o_dev->controller; u32 max_evt_data_size =iop->status_block->inbound_frame_size-5; struct i2o_reply { - u8 version_offset; - u8 msg_flags; - u16 msg_size; - u32 tid:12; - u32 initiator:12; - u32 function:8; - u32 initiator_context; - u32 transaction_context; + u32 header[4]; u32 evt_indicator; - u32 data[max_evt_data_size]; /* max */ + u32 data[max_evt_data_size]; } *evt = (struct i2o_reply *)msg; - int evt_data_len = (evt->msg_size - 5) * 4; /* real */ + int evt_data_len = ((msg[0]>>16) - 5) * 4; /* real size*/ printk(KERN_INFO "%s: I2O event - ", dev->name); - if (evt->function == I2O_CMD_UTIL_EVT_ACK) { + if (msg[1]>>24 == I2O_CMD_UTIL_EVT_ACK) { printk("Event acknowledgement reply.\n"); return; } @@ -505,17 +507,19 @@ break; } - case I2O_EVT_IND_GENERAL_WARNING: - printk("General warning 0x%04x.\n", evt->data[0]); - break; - - case I2O_EVT_IND_CONFIGURATION_FLAG: - printk("Configuration requested.\n"); + case I2O_EVT_IND_FIELD_MODIFIED: { + u16 *work16 = (u16 *)evt->data; + printk("Group 0x%04x, field %d changed.\n", work16[0], work16[1]); break; + } - case I2O_EVT_IND_CAPABILITY_CHANGE: - printk("Capability change 0x%04x.\n", evt->data[0]); + case I2O_EVT_IND_VENDOR_EVT: { + int i; + printk("Vendor event:\n"); + for (i = 0; i < evt_data_len / 4; i++) + printk(" 0x%08x\n", evt->data[i]); break; + } case I2O_EVT_IND_DEVICE_RESET: /* Spec 2.0 p. 6-121: @@ -526,48 +530,43 @@ printk("%s: Event Acknowledge timeout.\n", dev->name); break; +#if 0 case I2O_EVT_IND_EVT_MASK_MODIFIED: printk("Event mask modified, 0x%08x.\n", evt->data[0]); break; - case I2O_EVT_IND_FIELD_MODIFIED: { - u16 *work16 = (u16 *)evt->data; - printk("Group 0x%04x, field %d changed.\n", work16[0], work16[1]); + case I2O_EVT_IND_GENERAL_WARNING: + printk("General warning 0x%04x.\n", evt->data[0]); + break; + case I2O_EVT_IND_CONFIGURATION_FLAG: + printk("Configuration requested.\n"); break; - } - case I2O_EVT_IND_VENDOR_EVT: { - int i; - printk("Vendor event:\n"); - for (i = 0; i < evt_data_len / 4; i++) - printk(" 0x%08x\n", evt->data[i]); + case I2O_EVT_IND_CAPABILITY_CHANGE: + printk("Capability change 0x%04x.\n", evt->data[0]); break; - } case I2O_EVT_IND_DEVICE_STATE: printk("Device state changed 0x%08x.\n", evt->data[0]); break; - +#endif case I2O_LAN_EVT_LINK_DOWN: + netif_carrier_off(dev); printk("Link to the physical device is lost.\n"); break; case I2O_LAN_EVT_LINK_UP: + netif_carrier_on(dev); printk("Link to the physical device is (re)established.\n"); break; case I2O_LAN_EVT_MEDIA_CHANGE: printk("Media change.\n"); break; - default: printk("0x%08x. No handler.\n", evt->evt_indicator); } - - /* Note: EventAck necessary only for events that cause the device to - * syncronize with the user. - */ } /* @@ -722,7 +721,7 @@ printk(KERN_WARNING "%s: Unable to set RxMaxPacketsBucket.\n", dev->name); else - dprintk(KERN_INFO "%s: RxMaxPacketsBucket set to &d.\n", + dprintk(KERN_INFO "%s: RxMaxPacketsBucket set to %d.\n", dev->name, val); return; } @@ -739,6 +738,7 @@ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; struct i2o_controller *iop = i2o_dev->controller; + u32 mc_addr_group[64]; MOD_INC_USE_COUNT; @@ -756,6 +756,18 @@ i2o_lan_reset(dev); + /* Get the max number of multicast addresses */ + + if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0001, -1, + &mc_addr_group, sizeof(mc_addr_group)) < 0 ) { + printk(KERN_WARNING "%s: Unable to query LAN_MAC_ADDRESS group.\n", dev->name); + MOD_DEC_USE_COUNT; + return -EAGAIN; + } + priv->max_size_mc_table = mc_addr_group[8]; + + /* Malloc space for free bucket list to resuse reveive post buckets */ + priv->i2o_fbl = kmalloc(priv->max_buckets_out * sizeof(struct sk_buff *), GFP_KERNEL); if (priv->i2o_fbl == NULL) { @@ -819,9 +831,6 @@ /* * i2o_lan_batch_send(): Send packets in batch. * Both i2o_lan_sdu_send and i2o_lan_packet_send use this. - * - * This is a coarse first approximation for the tx_batching. - * If you come up with something better, please tell me. -taneli */ static void i2o_lan_batch_send(struct net_device *dev) { @@ -864,7 +873,7 @@ * If tx_batch_mode = 0x01 forced to batch mode * If tx_batch_mode = 0x10 switch automatically, current mode immediate * If tx_batch_mode = 0x11 switch automatically, current mode batch - * If gap between two packets is > 2 ticks, switch to immediate + * If gap between two packets is > 0 ticks, switch to immediate */ if (priv->tx_batch_mode >> 1) // switch automatically priv->tx_batch_mode = tickssofar ? 0x02 : 0x03; @@ -996,7 +1005,7 @@ if (!(priv->tx_batch_mode & 0x01) || priv->tx_count == priv->sgl_max) { dev->trans_start = jiffies; i2o_post_message(iop, priv->m); - dprintk(KERN_DEBUG"%s: %d packets sent.\n", dev->name, priv->tx_count); + dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count); priv->tx_count = 0; } @@ -1134,100 +1143,90 @@ return (struct net_device_stats *)&priv->stats; } -/* - * i2o_lan_set_mc_list(): Enable a network device to receive packets - * not send to the protocol address. +/* + * i2o_lan_set_mc_filter(): Post a request to set multicast filter. */ - -static void i2o_lan_set_mc_list(struct net_device *dev) +int i2o_lan_set_mc_filter(struct net_device *dev, u32 filter_mask) { - struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; + struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; struct i2o_controller *iop = i2o_dev->controller; - u32 filter_mask; - u32 max_size_mc_table; - u32 mc_addr_group[64]; + u32 msg[10]; -// This isn't safe yet in SMP. Needs to be async. -// Seems to work in uniprocessor environment. + msg[0] = TEN_WORD_MSG_SIZE | SGL_OFFSET_5; + msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid; + msg[2] = priv->unit << 16 | lan_context; + msg[3] = 0x0001 << 16 | 3 ; // TransactionContext: group&field + msg[4] = 0; + msg[5] = 0xCC000000 | 16; // Immediate data SGL + msg[6] = 1; // OperationCount + msg[7] = 0x0001<<16 | I2O_PARAMS_FIELD_SET; // Group, Operation + msg[8] = 3 << 16 | 1; // FieldIndex, FieldCount + msg[9] = filter_mask; // Value -return; - -// read_lock_bh(&dev_mc_lock); - spin_lock(&dev->xmit_lock); - dev->xmit_lock_owner = smp_processor_id(); + return i2o_post_this(iop, msg, sizeof(msg)); +} - if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0001, -1, - &mc_addr_group, sizeof(mc_addr_group)) < 0 ) { - printk(KERN_WARNING "%s: Unable to query LAN_MAC_ADDRESS group.\n", dev->name); - return; +/* + * i2o_lan_set_mc_table(): Post a request to set LAN_MULTICAST_MAC_ADDRESS table. + */ +int i2o_lan_set_mc_table(struct net_device *dev) +{ + struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; + struct i2o_device *i2o_dev = priv->i2o_dev; + struct i2o_controller *iop = i2o_dev->controller; + struct dev_mc_list *mc; + u32 msg[10 + 2 * dev->mc_count]; + u8 *work8 = (u8 *)(msg + 10); + + msg[0] = I2O_MESSAGE_SIZE(10 + 2 * dev->mc_count) | SGL_OFFSET_5; + msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid; + msg[2] = priv->unit << 16 | lan_context; // InitiatorContext + msg[3] = 0x0002 << 16 | (u16)-1; // TransactionContext + msg[4] = 0; // OperationFlags + msg[5] = 0xCC000000 | (16 + 8 * dev->mc_count); // Immediate data SGL + msg[6] = 2; // OperationCount + msg[7] = 0x0002 << 16 | I2O_PARAMS_TABLE_CLEAR; // Group, Operation + msg[8] = 0x0002 << 16 | I2O_PARAMS_ROW_ADD; // Group, Operation + msg[9] = dev->mc_count << 16 | (u16)-1; // RowCount, FieldCount + + for (mc = dev->mc_list; mc ; mc = mc->next, work8 += 8) { + memset(work8, 0, 8); + memcpy(work8, mc->dmi_addr, mc->dmi_addrlen); // Values } - max_size_mc_table = mc_addr_group[8]; + return i2o_post_this(iop, msg, sizeof(msg)); +} + +/* + * i2o_lan_set_multicast_list(): Enable a network device to receive packets + * not send to the protocol address. + */ +static void i2o_lan_set_multicast_list(struct net_device *dev) +{ + struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; + u32 filter_mask; if (dev->flags & IFF_PROMISC) { filter_mask = 0x00000002; - printk(KERN_INFO "%s: Enabling promiscuous mode...\n", dev->name); - } else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > max_size_mc_table) { + dprintk(KERN_INFO "%s: Enabling promiscuous mode...\n", dev->name); + } else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > priv->max_size_mc_table) { filter_mask = 0x00000004; - printk(KERN_INFO "%s: Enabling all multicast mode...\n", dev->name); + dprintk(KERN_INFO "%s: Enabling all multicast mode...\n", dev->name); } else if (dev->mc_count) { - struct dev_mc_list *mc; - u8 mc_table[2 + 8 * dev->mc_count]; // RowCount, Addresses - u64 *work64 = (u64 *)(mc_table + 2); - filter_mask = 0x00000000; - printk(KERN_INFO "%s: Enabling multicast mode...\n", dev->name); - - /* Fill multicast addr table */ - - memset(mc_table, 0, sizeof(mc_table)); - memcpy(mc_table, &dev->mc_count, 2); - for (mc = dev->mc_list; mc ; mc = mc->next, work64++ ) - memcpy(work64, mc->dmi_addr, mc->dmi_addrlen); - - /* Clear old mc table, copy new table to */ - - if (i2o_clear_table(iop, i2o_dev->lct_data.tid, 0x0002) < 0) - printk(KERN_INFO "%s: Unable to clear LAN_MULTICAST_MAC_ADDRESS table.\n", dev->name); - - if ((i2o_row_add_table(iop, i2o_dev->lct_data.tid, 0x0002, -1, - mc_table, sizeof(mc_table))) < 0) - printk(KERN_INFO "%s: Unable to set LAN_MULTICAST_MAC_ADDRESS table.\n", dev->name); + dprintk(KERN_INFO "%s: Enabling multicast mode...\n", dev->name); + if (i2o_lan_set_mc_table(dev) < 0) + printk(KERN_WARNING "%s: Unable to send MAC table.\n", dev->name); } else { filter_mask = 0x00000300; // Broadcast, Multicast disabled - printk(KERN_INFO "%s: Enabling unicast mode...\n", dev->name); + dprintk(KERN_INFO "%s: Enabling unicast mode...\n", dev->name); } - /* Finally copy new FilterMask to */ - - if (i2o_set_scalar(iop, i2o_dev->lct_data.tid, 0x0001, 3, - &filter_mask, sizeof(filter_mask)) <0) - printk(KERN_WARNING "%s: Unable to set MAC FilterMask.\n", dev->name); - - dev->xmit_lock_owner = -1; - spin_unlock(&dev->xmit_lock); -// read_unlock_bh(&dev_mc_lock); - - return; -} - -static struct tq_struct i2o_lan_set_mc_list_task = { - 0, 0, (void (*)(void *))i2o_lan_set_mc_list, (void *) 0 -}; + /* Finally copy new FilterMask to DDM */ -/* - * i2o_lan_set_multicast_list(): - * Queue routine i2o_lan_set_mc_list() to be called later. - * Needs to be async. - */ -static void i2o_lan_set_multicast_list(struct net_device *dev) -{ - if (in_interrupt()) { - i2o_lan_set_mc_list_task.data = (void *)dev; - queue_task(&i2o_lan_set_mc_list_task, &tq_scheduler); - } else - i2o_lan_set_mc_list(dev); + if (i2o_lan_set_mc_filter(dev, filter_mask) < 0) + printk(KERN_WARNING "%s: Unable to send MAC FilterMask.\n", dev->name); } /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/i2o/i2o_lan.h linux.ac/drivers/i2o/i2o_lan.h --- linux.vanilla/drivers/i2o/i2o_lan.h Thu May 25 17:38:18 2000 +++ linux.ac/drivers/i2o/i2o_lan.h Mon May 29 20:35:36 2000 @@ -1,7 +1,7 @@ /* * i2o_lan.h I2O LAN Class definitions * - * I2O LAN CLASS OSM April 3rd 2000 + * I2O LAN CLASS OSM May 26th 2000 * * (C) Copyright 1999, 2000 University of Helsinki, * Department of Computer Science @@ -23,7 +23,7 @@ #define I2O_LAN_RX_COPYBREAK 200 #define I2O_LAN_TX_TIMEOUT (1*HZ) #define I2O_LAN_TX_BATCH_MODE 2 /* 2=automatic, 1=on, 0=off */ -#define I2O_LAN_EVENT_MASK 0; /* 0=None, 0xFFC00002=All */ +#define I2O_LAN_EVENT_MASK 0 /* 0=None, 0xFFC00002=All */ /* LAN types */ #define I2O_LAN_ETHERNET 0x0030 @@ -100,7 +100,7 @@ #define I2O_LAN_DSC_DEST_ADDRESS_DETECTED 0x0E #define I2O_LAN_DSC_DEST_ADDRESS_OMITTED 0x0F #define I2O_LAN_DSC_PARTIAL_PACKET_RETURNED 0x10 -#define I2O_LAN_DSC_TEMP_SUSPENDED_STATE 0x11 +#define I2O_LAN_DSC_SUSPENDED 0x11 struct i2o_packet_info { u32 offset : 24; @@ -143,6 +143,8 @@ spinlock_t fbl_lock; spinlock_t tx_lock; + + u32 max_size_mc_table; /* max number of multicast addresses */ /* LAN OSM configurable parameters are here: */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/i2o/i2o_pci.c linux.ac/drivers/i2o/i2o_pci.c --- linux.vanilla/drivers/i2o/i2o_pci.c Thu May 25 17:38:18 2000 +++ linux.ac/drivers/i2o/i2o_pci.c Sat May 27 15:28:44 2000 @@ -132,9 +132,9 @@ for(i=0; i<6; i++) { /* Skip I/O spaces */ - if(!(dev->resource[i].flags&PCI_BASE_ADDRESS_SPACE)) + if(!(pci_resource_flags(dev, i) & IORESOURCE_IO)) { - memptr=dev->resource[i].start; + memptr = pci_resource_start(dev, i); break; } } @@ -256,6 +256,8 @@ printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n"); continue; } + if (pci_enable_device(dev)) + continue; printk(KERN_INFO "i2o: I2O controller on bus %d at %d.\n", dev->bus->number, dev->devfn); pci_set_master(dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/Makefile linux.ac/drivers/ide/Makefile --- linux.vanilla/drivers/ide/Makefile Thu May 25 17:46:15 2000 +++ linux.ac/drivers/ide/Makefile Mon May 29 20:22:16 2000 @@ -18,11 +18,11 @@ MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) -L_TARGET := ide.a -L_OBJS := ide-geometry.o +O_TARGET := idedriver.o +O_OBJS := ide-geometry.o M_OBJS := MOD_LIST_NAME := IDE_MODULES -LX_OBJS := +OX_OBJS := MX_OBJS := ifeq ($(CONFIG_BLK_DEV_AEC62XX),y) @@ -78,7 +78,7 @@ endif ifeq ($(CONFIG_BLK_DEV_HD),y) -L_OBJS += hd.o +O_OBJS += hd.o endif ifeq ($(CONFIG_BLK_DEV_HPT34X),y) @@ -178,8 +178,8 @@ ###Collect ifeq ($(CONFIG_BLK_DEV_IDE),y) - LX_OBJS += ide.o ide-features.o - L_OBJS += ide-probe.o $(IDE_OBJS) + OX_OBJS += ide.o ide-features.o + O_OBJS += ide-probe.o $(IDE_OBJS) else ifeq ($(CONFIG_BLK_DEV_IDE),m) MIX_OBJS += ide.o ide-features.o $(IDE_OBJS) @@ -190,7 +190,7 @@ ############ ifeq ($(CONFIG_BLK_DEV_IDECS),y) -L_OBJS += ide-cs.o +O_OBJS += ide-cs.o else ifeq ($(CONFIG_BLK_DEV_IDECS),m) M_OBJS += ide-cs.o @@ -198,7 +198,7 @@ endif ifeq ($(CONFIG_BLK_DEV_IDEDISK),y) -L_OBJS += ide-disk.o +O_OBJS += ide-disk.o else ifeq ($(CONFIG_BLK_DEV_IDEDISK),m) M_OBJS += ide-disk.o @@ -206,7 +206,7 @@ endif ifeq ($(CONFIG_BLK_DEV_IDECD),y) -L_OBJS += ide-cd.o +O_OBJS += ide-cd.o else ifeq ($(CONFIG_BLK_DEV_IDECD),m) M_OBJS += ide-cd.o @@ -214,7 +214,7 @@ endif ifeq ($(CONFIG_BLK_DEV_IDETAPE),y) -L_OBJS += ide-tape.o +O_OBJS += ide-tape.o else ifeq ($(CONFIG_BLK_DEV_IDETAPE),m) M_OBJS += ide-tape.o @@ -222,7 +222,7 @@ endif ifeq ($(CONFIG_BLK_DEV_IDEFLOPPY),y) -L_OBJS += ide-floppy.o +O_OBJS += ide-floppy.o else ifeq ($(CONFIG_BLK_DEV_IDEFLOPPY),m) M_OBJS += ide-floppy.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/ide-cd.c linux.ac/drivers/ide/ide-cd.c --- linux.vanilla/drivers/ide/ide-cd.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/ide-cd.c Sat May 27 15:37:02 2000 @@ -1524,7 +1524,7 @@ memset(&pc, 0, sizeof(pc)); pc.sense = sense; pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; - pc.c[4] = lockflag ? 3 : 0; + pc.c[4] = lockflag ? 1 : 0; stat = cdrom_queue_packet_command (drive, &pc); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/ide-disk.c linux.ac/drivers/ide/ide-disk.c --- linux.vanilla/drivers/ide/ide-disk.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/ide-disk.c Sat May 27 22:02:17 2000 @@ -519,7 +519,6 @@ /* * Compute drive->capacity, the full capacity of the drive - * Called with drive->id != NULL. */ static void init_idedisk_capacity (ide_drive_t *drive) { @@ -529,7 +528,7 @@ drive->select.b.lba = 0; /* Determine capacity, and use LBA if the drive properly supports it */ - if ((id->capability & 2) && lba_capacity_is_ok(id)) { + if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) { capacity = id->lba_capacity; drive->cyl = capacity / (drive->head * drive->sect); drive->select.b.lba = 1; @@ -759,8 +758,10 @@ idedisk_add_settings(drive); - if (id == NULL) + if (id == NULL) { /* Old, non-IDE drive */ + init_idedisk_capacity(drive); return; + } /* * CompactFlash cards and their brethern look just like hard drives diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/ide-geometry.c linux.ac/drivers/ide/ide-geometry.c --- linux.vanilla/drivers/ide/ide-geometry.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/ide/ide-geometry.c Sat May 27 22:02:17 2000 @@ -43,6 +43,8 @@ * may be SCSI disks (even when IDE disks are present), so that * the geometry we read here from BIOS is attributed to the wrong disks. * Consequently, also the "drive->present = 1" below is a mistake. + * Setting it only for 17 and 26 sector devices (allows 99% of stone + * age MFM and RLL drives to be detected) mimimizes this problem. * * Eventually the entire routine below should be removed. */ @@ -73,6 +75,8 @@ drive->head = drive->bios_head = head; drive->sect = drive->bios_sect = sect; drive->ctl = *(BIOS+8); + if (sect == 17 || sect == 26) + drive->present = 1; } else { printk("hd%d: C/H/S=%d/%d/%d from BIOS ignored\n", unit, cyl, head, sect); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/ieee1394_syms.c linux.ac/drivers/ieee1394/ieee1394_syms.c --- linux.vanilla/drivers/ieee1394/ieee1394_syms.c Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/ieee1394_syms.c Sat May 27 16:02:11 2000 @@ -8,6 +8,7 @@ #include #include +#include #include "ieee1394_types.h" #include "hosts.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/isdn/avmb1/kcapi.c linux.ac/drivers/isdn/avmb1/kcapi.c --- linux.vanilla/drivers/isdn/avmb1/kcapi.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/isdn/avmb1/kcapi.c Thu May 25 00:15:35 2000 @@ -281,7 +281,7 @@ *eof = 1; if (off >= len+begin) return 0; - *start = page + (off-begin); + *start = page + (begin-off); return ((count < begin+len-off) ? count : begin+len-off); } @@ -320,7 +320,7 @@ *eof = 1; if (off >= len+begin) return 0; - *start = page + (off-begin); + *start = page + (begin-off); return ((count < begin+len-off) ? count : begin+len-off); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/isdn/isdn_tty.c linux.ac/drivers/isdn/isdn_tty.c --- linux.vanilla/drivers/isdn/isdn_tty.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/isdn/isdn_tty.c Mon May 29 19:21:40 2000 @@ -381,8 +381,14 @@ #define MODEM_PARANOIA_CHECK #define MODEM_DO_RESTART +#ifdef CONFIG_DEVFS_FS +static char *isdn_ttyname_ttyI = "isdn/ttyI%d"; +static char *isdn_ttyname_cui = "isdn/cui%d"; +#else static char *isdn_ttyname_ttyI = "ttyI"; static char *isdn_ttyname_cui = "cui"; +#endif + static int bit2si[8] = {1, 5, 7, 7, 7, 7, 7, 7}; static int si2bit[8] = diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/Config.in linux.ac/drivers/net/Config.in --- linux.vanilla/drivers/net/Config.in Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/Config.in Sat May 27 22:03:39 2000 @@ -49,7 +49,7 @@ tristate ' MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC fi if [ "$CONFIG_SGI_IP27" = "y" ]; then - bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH + bool ' SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH fi if [ "$CONFIG_SUPERH" = "y" -a "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then tristate ' National DP83902AV support' CONFIG_STNIC @@ -60,14 +60,14 @@ tristate ' 3c503 "EtherLink II" support' CONFIG_EL2 tristate ' 3c505 "EtherLink Plus" support' CONFIG_ELPLUS if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate ' 3c507 support (EXPERIMENTAL)' CONFIG_EL16 + tristate ' 3c507 "EtherLink 16" support (EXPERIMENTAL)' CONFIG_EL16 fi tristate ' 3c509/3c529 (MCA)/3c579 "EtherLink III" support' CONFIG_EL3 - tristate ' 3c515 ISA Fast EtherLink' CONFIG_3C515 + tristate ' 3c515 ISA "Fast EtherLink"' CONFIG_3C515 if [ "$CONFIG_MCA" = "y" ]; then - tristate ' 3c523 EtherLinkMC support' CONFIG_ELMC + tristate ' 3c523 "EtherLink/MC" support' CONFIG_ELMC if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate ' 3c527 EtherLink/MC 32 support (EXPERIMENTAL)' CONFIG_ELMC_II + tristate ' 3c527 "EtherLink/MC 32" support (EXPERIMENTAL)' CONFIG_ELMC_II fi fi tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX @@ -104,7 +104,7 @@ tristate ' EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3 fi tristate ' EtherExpress 16 support' CONFIG_EEXPRESS - tristate ' EtherExpressPro support' CONFIG_EEXPRESS_PRO + tristate ' EtherExpressPro support/EtherExpress 10 (i82595) support' CONFIG_EEXPRESS_PRO if [ "$CONFIG_OBSOLETE" = "y" ]; then tristate ' FMV-181/182/183/184 support' CONFIG_FMV18X fi @@ -182,15 +182,16 @@ mainmenu_option next_comment comment 'Ethernet (1000 Mbit)' - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - # tristate 'Packet Engines Hamachi GNIC-II support (EXPERIMENTAL)' CONFIG_HAMACHI - tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN - fi - tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC - if [ "$CONFIG_ACENIC" != "n" ]; then - bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I - fi - tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + # tristate 'Packet Engines Hamachi GNIC-II support (EXPERIMENTAL)' CONFIG_HAMACHI + tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN +fi +tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC +if [ "$CONFIG_ACENIC" != "n" ]; then + bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I +fi +tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN + endmenu bool 'FDDI driver support' CONFIG_FDDI @@ -223,7 +224,7 @@ dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP + dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP fi fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/Makefile linux.ac/drivers/net/Makefile --- linux.vanilla/drivers/net/Makefile Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/Makefile Mon May 29 19:25:15 2000 @@ -83,16 +83,8 @@ endif endif -ifeq ($(CONFIG_ISDN),y) - ifeq ($(CONFIG_ISDN_PPP),y) - obj-y += slhc.o ppp_deflate.o - endif -else - ifeq ($(CONFIG_ISDN),m) - ifeq ($(CONFIG_ISDN_PPP),y) - obj-m += slhc.o ppp_deflate.o - endif - endif +ifeq ($(CONFIG_ISDN_PPP),y) + obj-$(CONFIG_ISDN) += slhc.o endif ifeq ($(CONFIG_ARCNET),y) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/aironet4500_card.c linux.ac/drivers/net/aironet4500_card.c --- linux.vanilla/drivers/net/aironet4500_card.c Thu May 25 17:37:58 2000 +++ linux.ac/drivers/net/aironet4500_card.c Fri May 26 14:36:50 2000 @@ -98,6 +98,8 @@ pdev = pci_find_slot(awc_pci_bus, awc_pci_dev); if (!pdev) continue; + if (pci_enable_device(pdev)) + continue; vendor = pdev->vendor; device = pdev->device; pci_irq_line = pdev->irq; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/defxx.c linux.ac/drivers/net/defxx.c --- linux.vanilla/drivers/net/defxx.c Thu May 25 17:37:53 2000 +++ linux.ac/drivers/net/defxx.c Fri May 26 14:36:50 2000 @@ -500,6 +500,9 @@ printk(version); /* we only display this string ONCE */ } + if (pci_enable_device(pdev)) + continue; + /* Verify that I/O enable bit is set (PCI slot is enabled) */ pci_read_config_word(pdev, PCI_COMMAND, &command); @@ -515,7 +518,7 @@ /* Get I/O base address from PCI Configuration Space */ - port = pdev->resource[1].start; + port = pci_resource_start (pdev, 1); /* Verify port address range is not already being used */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/dmfe.c linux.ac/drivers/net/dmfe.c --- linux.vanilla/drivers/net/dmfe.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/dmfe.c Fri May 26 14:36:50 2000 @@ -359,15 +359,16 @@ if (pci_read_config_dword(net_dev, PCI_VENDOR_ID, &pci_id) != DMFE_SUCC) continue; - if ((pci_id != PCI_DM9102_ID) && (pci_id != PCI_DM9132_ID)) + if ((net_dev->device != PCI_DM9102_ID) && (net_dev->device != PCI_DM9132_ID)) continue; - pci_iobase = net_dev->resource[0].start; + pci_iobase = pci_resource_start (net_dev, 0); pci_irqline = net_dev->irq; /* Enable Master/IO access, Disable memory access */ - pci_enable_device (net_dev); /* XXX check return val */ + if (pci_enable_device(net_dev)) + continue; pci_set_master(net_dev); /* Set Latency Timer 80h */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/eepro.c linux.ac/drivers/net/eepro.c --- linux.vanilla/drivers/net/eepro.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/eepro.c Thu May 25 23:55:42 2000 @@ -23,6 +23,8 @@ This is a compatibility hardware problem. Versions: + 0.12a port of version 0.12a of 2.2.x kernels to 2.3.x + (aris (aris@conectiva.com.br), 05/19/2000) 0.11e some tweaks about multiple cards support (PdP, jul/aug 1999) 0.11d added __initdata, __init stuff; call spin_lock_init in eepro_probe1. Replaced "eepro" by dev->name. Augmented @@ -93,7 +95,7 @@ */ static const char *version = - "eepro.c: v0.11d 08/12/1998 dupuis@lei.ucl.ac.be\n"; + "eepro.c: v0.12a 04/26/2000 aris@conectiva.com.br\n"; #include @@ -174,6 +176,7 @@ #define LAN595 0 #define LAN595TX 1 #define LAN595FX 2 +#define LAN595FX_10ISA 3 /* Information that need to be kept for each board. */ struct eepro_local { @@ -293,7 +296,7 @@ static void set_multicast_list(struct net_device *dev); static void eepro_tx_timeout (struct net_device *dev); -static int read_eeprom(int ioaddr, int location); +static int read_eeprom(int ioaddr, int location, struct net_device *dev); static void hardware_send_packet(struct net_device *dev, void *buf, short length); static int eepro_grab_irq(struct net_device *dev); @@ -327,18 +330,32 @@ buffer (transmit-buffer = 32K - receive-buffer). */ -#define RAM_SIZE 0x8000 -#define RCV_HEADER 8 -#define RCV_RAM 0x6000 /* 24KB default for RCV buffer */ -#define RCV_LOWER_LIMIT 0x00 /* 0x0000 */ -/* #define RCV_UPPER_LIMIT ((RCV_RAM - 2) >> 8) */ /* 0x5ffe */ -#define RCV_UPPER_LIMIT (((rcv_ram) - 2) >> 8) -/* #define XMT_RAM (RAM_SIZE - RCV_RAM) */ /* 8KB for XMT buffer */ -#define XMT_RAM (RAM_SIZE - (rcv_ram)) /* 8KB for XMT buffer */ -/* #define XMT_LOWER_LIMIT (RCV_RAM >> 8) */ /* 0x6000 */ -#define XMT_LOWER_LIMIT ((rcv_ram) >> 8) -#define XMT_UPPER_LIMIT ((RAM_SIZE - 2) >> 8) /* 0x7ffe */ -#define XMT_HEADER 8 +/* now this section could be used by both boards: the oldies and the ee10: + * ee10 uses tx buffer before of rx buffer and the oldies the inverse. + * (aris) + */ +#define RAM_SIZE 0x8000 + +#define RCV_HEADER 8 +#define RCV_DEFAULT_RAM 0x6000 +#define RCV_RAM rcv_ram + +static unsigned rcv_ram = RCV_DEFAULT_RAM; + +#define XMT_HEADER 8 +#define XMT_RAM (RAM_SIZE - RCV_RAM) + +#define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE) + +#define RCV_LOWER_LIMIT (rcv_start >> 8) +#define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8) +#define XMT_LOWER_LIMIT (XMT_START >> 8) +#define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8) + +#define RCV_START_PRO 0x00 +#define RCV_START_10 XMT_RAM + /* by default the old driver */ +static unsigned rcv_start = RCV_START_PRO; #define RCV_DONE 0x0008 #define RX_OK 0x2000 @@ -384,7 +401,11 @@ #define IO_32_BIT 0x10 #define RCV_BAR 0x04 /* The following are word (16-bit) registers */ #define RCV_STOP 0x06 -#define XMT_BAR 0x0a + +#define XMT_BAR_PRO 0x0a +#define XMT_BAR_10 0x0b +static unsigned xmt_bar = XMT_BAR_PRO; + #define HOST_ADDRESS_REG 0x0c #define IO_PORT 0x0e #define IO_PORT_32_BIT 0x0c @@ -396,8 +417,13 @@ #define INT_NO_REG 0x02 #define RCV_LOWER_LIMIT_REG 0x08 #define RCV_UPPER_LIMIT_REG 0x09 -#define XMT_LOWER_LIMIT_REG 0x0a -#define XMT_UPPER_LIMIT_REG 0x0b + +#define XMT_LOWER_LIMIT_REG_PRO 0x0a +#define XMT_UPPER_LIMIT_REG_PRO 0x0b +#define XMT_LOWER_LIMIT_REG_10 0x0b +#define XMT_UPPER_LIMIT_REG_10 0x0a +static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO; +static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO; /* Bank 2 registers */ #define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */ @@ -420,12 +446,68 @@ #define I_ADD_REG4 0x08 #define I_ADD_REG5 0x09 -#define EEPROM_REG 0x0a +#define EEPROM_REG_PRO 0x0a +#define EEPROM_REG_10 0x0b +static unsigned eeprom_reg = EEPROM_REG_PRO; + #define EESK 0x01 #define EECS 0x02 #define EEDI 0x04 #define EEDO 0x08 +/* do a full reset */ +#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr) + +/* do a nice reset */ +#define eepro_sel_reset(ioaddr) { \ + outb(SEL_RESET_CMD, ioaddr); \ + SLOW_DOWN; \ + SLOW_DOWN; \ + } + +/* disable all interrupts */ +#define eepro_dis_int(ioaddr) outb(ALL_MASK, ioaddr + INT_MASK_REG) + +/* clear all interrupts */ +#define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG) + +/* enable tx/rx */ +#define eepro_en_int(ioaddr) outb(ALL_MASK & ~(RX_MASK | TX_MASK), \ + ioaddr + INT_MASK_REG) + +/* enable exec event interrupt */ +#define eepro_en_intexec(ioaddr) outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG) + +/* enable rx */ +#define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr) + +/* disable rx */ +#define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr) + +/* switch bank */ +#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr) +#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr) +#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr) + +/* enable interrupt line */ +#define eepro_en_intline(ioaddr) outb(inb(ioaddr + REG1) | INT_ENABLE,\ + ioaddr + REG1) + +/* disable interrupt line */ +#define eepro_dis_intline(ioaddr) outb(inb(ioaddr + REG1) & 0x7f, \ + ioaddr + REG1); + +/* set diagnose flag */ +#define eepro_diag(ioaddr) outb(DIAGNOSE_CMD, ioaddr) + +/* ack for rx/tx int */ +#define eepro_ack_rxtx(ioaddr) outb (RX_INT | TX_INT, ioaddr + STATUS_REG) + +/* ack for rx int */ +#define eepro_ack_rx(ioaddr) outb (RX_INT, ioaddr + STATUS_REG) + +/* ack for tx int */ +#define eepro_ack_tx(ioaddr) outb (TX_INT, ioaddr + STATUS_REG) /* Check for a network adaptor of this type, and return '0' if one exists. If dev->base_addr == 0, probe all likely locations. @@ -494,16 +576,16 @@ } #endif -void printEEPROMInfo(short ioaddr) +void printEEPROMInfo(short ioaddr, struct net_device *dev) { unsigned short Word; int i,j; for (i=0, j=ee_Checksum; i>ee_IO0)<<4); if (net_debug>4) { - Word=read_eeprom(ioaddr, 1); + Word=read_eeprom(ioaddr, 1, dev); printk(KERN_DEBUG "Word1:\n"); printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask); printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI)); @@ -522,7 +604,7 @@ printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex)); } - Word=read_eeprom(ioaddr, 5); + Word=read_eeprom(ioaddr, 5, dev); printk(KERN_DEBUG "Word5:\n"); printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE)); printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn)); @@ -532,12 +614,12 @@ if (GetBit(Word,ee_PortAUI)) printk("AUI "); printk("port(s) \n"); - Word=read_eeprom(ioaddr, 6); + Word=read_eeprom(ioaddr, 6, dev); printk(KERN_DEBUG "Word6:\n"); printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask); printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID); - Word=read_eeprom(ioaddr, 7); + Word=read_eeprom(ioaddr, 7, dev); printk(KERN_DEBUG "Word7:\n"); printk(KERN_DEBUG " INT to IRQ:\n"); @@ -557,7 +639,8 @@ { unsigned short station_addr[6], id, counter; int i,j, irqMask; - int eepro; + int eepro = 0; + struct eepro_local *lp; const char *ifmap[] = {"AUI", "10Base2", "10BaseT"}; enum iftype { AUI=0, BNC=1, TPE=2 }; @@ -566,9 +649,6 @@ id=inb(ioaddr + ID_REG); - printk(KERN_DEBUG " id: %#x ",id); - printk(" io: %#x ",ioaddr); - if (((id) & ID_REG_MASK) == ID_REG_SIG) { /* We seem to have the 82595 signature, let's @@ -580,19 +660,45 @@ (counter + 0x40)) { /* Yes, the 82595 has been found */ + printk(KERN_DEBUG " id: %#x ",id); + printk(" io: %#x ",ioaddr); + + /* Initialize the device structure */ + dev->priv = kmalloc(sizeof(struct eepro_local), GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct eepro_local)); + + lp = (struct eepro_local *)dev->priv; /* Now, get the ethernet hardware address from the EEPROM */ - station_addr[0] = read_eeprom(ioaddr, 2); - station_addr[1] = read_eeprom(ioaddr, 3); - station_addr[2] = read_eeprom(ioaddr, 4); + station_addr[0] = read_eeprom(ioaddr, 2, dev); - /* Check the station address for the manufacturer's code */ - if (net_debug>3) - printEEPROMInfo(ioaddr); - - if (read_eeprom(ioaddr,7)== ee_FX_INT2IRQ) { /* int to IRQ Mask */ + /* FIXME - find another way to know that we've found + * an Etherexpress 10 + */ + if (station_addr[0] == 0x0000 || + station_addr[0] == 0xffff) { + eepro = 3; + lp->eepro = LAN595FX_10ISA; + eeprom_reg = EEPROM_REG_10; + rcv_start = RCV_START_10; + xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10; + xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10; + + station_addr[0] = read_eeprom(ioaddr, 2, dev); + } + + station_addr[1] = read_eeprom(ioaddr, 3, dev); + station_addr[2] = read_eeprom(ioaddr, 4, dev); + + if (eepro) { + printk("%s: Intel EtherExpress 10 ISA\n at %#x,", + dev->name, ioaddr); + } else if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ) { + /* int to IRQ Mask */ eepro = 2; printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", dev->name, ioaddr); @@ -615,13 +721,21 @@ dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i]; printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); } + + dev->mem_start = (RCV_LOWER_LIMIT << 8); if ((dev->mem_end & 0x3f) < 3 || /* RX buffer must be more than 3K */ (dev->mem_end & 0x3f) > 29) /* and less than 29K */ - dev->mem_end = RCV_RAM; /* or it will be set to 24K */ - else dev->mem_end = 1024*dev->mem_end; /* Maybe I should shift << 10 */ + dev->mem_end = (RCV_UPPER_LIMIT << 8); + else { + dev->mem_end = (dev->mem_end * 1024) + + (RCV_LOWER_LIMIT << 8); + rcv_ram = dev->mem_end - (RCV_LOWER_LIMIT << 8); + } - /* From now on, dev->mem_end contains the actual size of rx buffer */ + /* From now on, dev->mem_end - dev->mem_start contains + * the actual size of rx buffer + */ if (net_debug > 3) printk(", %dK RCV buffer", (int)(dev->mem_end)/1024); @@ -629,7 +743,7 @@ /* ............... */ - if (GetBit( read_eeprom(ioaddr, 5),ee_BNC_TPE)) + if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE)) dev->if_port = BNC; else dev->if_port = TPE; @@ -637,8 +751,8 @@ if ((dev->irq < 2) && (eepro!=0)) { - i = read_eeprom(ioaddr, 1); - irqMask = read_eeprom(ioaddr, 7); + i = read_eeprom(ioaddr, 1, dev); + irqMask = read_eeprom(ioaddr, 7, dev); i &= 0x07; /* Mask off INT number */ for (j=0; ((j<16) && (i>=0)); j++) { @@ -650,15 +764,13 @@ i--; /* count bits set in irqMask */ } } - if (dev -> irq<2) { + if (dev->irq < 2) { printk(" Duh! illegal interrupt vector stored in EEPROM.\n"); return ENODEV; } else - if (dev->irq==2) dev->irq = 9; - - else if (dev->irq == 2) - dev->irq = 9; + if (dev->irq==2) + dev->irq = 9; } if (dev->irq > 2) { @@ -671,7 +783,7 @@ net_debug = dev->mem_start & 7; /* still useful or not */ if (net_debug > 3) { - i = read_eeprom(ioaddr, 5); + i = read_eeprom(ioaddr, 5, dev); if (i & 0x2000) /* bit 13 of EEPROM word 5 */ printk(KERN_DEBUG "%s: Concurrent Processing is enabled but not used!\n", dev->name); @@ -683,12 +795,6 @@ /* Grab the region so we can find another board if autoIRQ fails. */ request_region(ioaddr, EEPRO_IO_EXTENT, dev->name); - /* Initialize the device structure */ - dev->priv = kmalloc(sizeof(struct eepro_local), GFP_KERNEL); - if (dev->priv == NULL) - return -ENOMEM; - memset(dev->priv, 0, sizeof(struct eepro_local)); - ((struct eepro_local *)dev->priv)->lock = SPIN_LOCK_UNLOCKED; dev->open = eepro_open; @@ -704,7 +810,12 @@ ether_setup(dev); - outb(RESET_CMD, ioaddr); /* RESET the 82595 */ + /* Check the station address for the manufacturer's code */ + if (net_debug>3) + printEEPROMInfo(ioaddr, dev); + + /* RESET the 82595 */ + eepro_reset(ioaddr); return 0; } @@ -730,55 +841,54 @@ int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 }; int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr; - outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */ + eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */ /* Enable the interrupt line. */ - temp_reg = inb(ioaddr + REG1); - outb(temp_reg | INT_ENABLE, ioaddr + REG1); + eepro_en_intline(ioaddr); + + /* be CAREFUL, BANK 0 now */ + eepro_sw2bank0(ioaddr); - outb(BANK0_SELECT, ioaddr); /* be CAREFUL, BANK 0 now */ - /* clear all interrupts */ - outb(ALL_MASK, ioaddr + STATUS_REG); + eepro_clear_int(ioaddr); /* Let EXEC event to interrupt */ - outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG); + eepro_en_intexec(ioaddr); do { - outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */ + eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */ temp_reg = inb(ioaddr + INT_NO_REG); outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG); - outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */ + eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */ if (request_irq (*irqp, NULL, 0, "bogus", dev) != EBUSY) { /* Twinkle the interrupt, and check if it's seen */ autoirq_setup(0); - outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */ + eepro_diag(ioaddr); /* RESET the 82595 */ if (*irqp == autoirq_report(2)) /* It's a good IRQ line */ break; /* clear all interrupts */ - outb(ALL_MASK, ioaddr + STATUS_REG); + eepro_clear_int(ioaddr); } } while (*++irqp); - outb(BANK1_SELECT, ioaddr); /* Switch back to Bank 1 */ + eepro_sw2bank1(ioaddr); /* Switch back to Bank 1 */ /* Disable the physical interrupt line. */ - temp_reg = inb(ioaddr + REG1); - outb(temp_reg & 0x7f, ioaddr + REG1); + eepro_dis_intline(ioaddr); - outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */ + eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */ /* Mask all the interrupts. */ - outb(ALL_MASK, ioaddr + INT_MASK_REG); + eepro_dis_int(ioaddr); /* clear all interrupts */ - outb(ALL_MASK, ioaddr + STATUS_REG); + eepro_clear_int(ioaddr); return dev->irq; } @@ -787,13 +897,18 @@ { unsigned short temp_reg, old8, old9; int irqMask; - int i, ioaddr = dev->base_addr, rcv_ram = dev->mem_end; + int i, ioaddr = dev->base_addr; struct eepro_local *lp = (struct eepro_local *)dev->priv; if (net_debug > 3) printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name); - if ((irqMask=read_eeprom(ioaddr,7))== ee_FX_INT2IRQ) /* INT to IRQ Mask */ + irqMask = read_eeprom(ioaddr,7,dev); + + if (lp->eepro == LAN595FX_10ISA) { + if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n"); + } + else if (irqMask == ee_FX_INT2IRQ) /* INT to IRQ Mask */ { lp->eepro = 2; /* Yes, an Intel EtherExpress Pro/10+ */ if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 2;\n"); @@ -831,8 +946,8 @@ /* Initialize the 82595. */ - outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */ - temp_reg = inb(ioaddr + EEPROM_REG); + eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */ + temp_reg = inb(ioaddr + eeprom_reg); lp->stepping = temp_reg >> 5; /* Get the stepping number of the 595 */ @@ -840,7 +955,7 @@ printk(KERN_DEBUG "The stepping of the 82595 is %d\n", lp->stepping); if (temp_reg & 0x10) /* Check the TurnOff Enable bit */ - outb(temp_reg & 0xef, ioaddr + EEPROM_REG); + outb(temp_reg & 0xef, ioaddr + eeprom_reg); for (i=0; i < 6; i++) outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i); @@ -855,17 +970,17 @@ outb(temp_reg & 0x3f, ioaddr + REG3); /* clear test mode */ /* Set the receiving mode */ - outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */ + eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */ /* Set the interrupt vector */ temp_reg = inb(ioaddr + INT_NO_REG); - if (lp->eepro == 2) + if (lp->eepro == 2 || lp->eepro == LAN595FX_10ISA) outb((temp_reg & 0xf8) | irqrmap2[dev->irq], ioaddr + INT_NO_REG); else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG); temp_reg = inb(ioaddr + INT_NO_REG); - if (lp->eepro == 2) + if (lp->eepro == 2 || lp->eepro == LAN595FX_10ISA) outb((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08,ioaddr+INT_NO_REG); else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG); @@ -876,20 +991,20 @@ /* Initialize the RCV and XMT upper and lower limits */ outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG); outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG); - outb(XMT_LOWER_LIMIT, ioaddr + XMT_LOWER_LIMIT_REG); - outb(XMT_UPPER_LIMIT, ioaddr + XMT_UPPER_LIMIT_REG); + outb(XMT_LOWER_LIMIT, ioaddr + xmt_lower_limit_reg); + outb(XMT_UPPER_LIMIT, ioaddr + xmt_upper_limit_reg); /* Enable the interrupt line. */ - temp_reg = inb(ioaddr + REG1); - outb(temp_reg | INT_ENABLE, ioaddr + REG1); + eepro_en_intline(ioaddr); - outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */ + /* Switch back to Bank 0 */ + eepro_sw2bank0(ioaddr); /* Let RX and TX events to interrupt */ - outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); + eepro_en_int(ioaddr); /* clear all interrupts */ - outb(ALL_MASK, ioaddr + STATUS_REG); + eepro_clear_int(ioaddr); /* Initialize RCV */ outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR); @@ -897,7 +1012,7 @@ outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP); /* Initialize XMT */ - outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR); + outw(XMT_LOWER_LIMIT << 8, ioaddr + xmt_bar); /* Check for the i82595TX and i82595FX */ old8 = inb(ioaddr + 8); @@ -927,12 +1042,12 @@ if (dev->if_port != TPE) { /* Hopefully, this will fix the problem of using Pentiums and pro/10 w/ BNC. */ - outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */ + eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */ temp_reg = inb(ioaddr + REG13); /* disable the full duplex mode since it is not applicable with the 10Base2 cable. */ outb(temp_reg & ~(FDX | A_N_ENABLE), REG13); - outb(BANK0_SELECT, ioaddr); /* be CAREFUL, BANK 0 now */ + eepro_sw2bank0(ioaddr); /* be CAREFUL, BANK 0 now */ } } else if (net_debug > 3) { @@ -941,13 +1056,9 @@ } } - outb(SEL_RESET_CMD, ioaddr); + eepro_sel_reset(ioaddr); - /* We are supposed to wait for 2 us after a SEL_RESET */ - SLOW_DOWN; - SLOW_DOWN; - - lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8; /* or = RCV_RAM */ + lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8; lp->tx_last = 0; netif_start_queue(dev); @@ -955,7 +1066,8 @@ if (net_debug > 3) printk(KERN_DEBUG "%s: exiting eepro_open routine.\n", dev->name); - outb(RCV_ENABLE_CMD, ioaddr); + /* enabling rx */ + eepro_en_rx(ioaddr); MOD_INC_USE_COUNT; return 0; @@ -965,7 +1077,6 @@ { struct eepro_local *lp = (struct eepro_local *) dev->priv; int ioaddr = dev->base_addr; - int rcv_ram = dev->mem_end; /* if (net_debug > 1) */ printk (KERN_ERR "%s: transmit timed out, %s?\n", dev->name, @@ -977,19 +1088,20 @@ lp->stats.tx_errors++; /* Try to restart the adaptor. */ - outb (SEL_RESET_CMD, ioaddr); - /* We are supposed to wait for 2 us after a SEL_RESET */ - SLOW_DOWN; - SLOW_DOWN; - + eepro_sel_reset(ioaddr); + /* Do I also need to flush the transmit buffers here? YES? */ - lp->tx_start = lp->tx_end = rcv_ram; + lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT; lp->tx_last = 0; dev->trans_start = jiffies; netif_wake_queue (dev); - outb (RCV_ENABLE_CMD, ioaddr); + /* enabling interrupts */ + eepro_en_int(ioaddr); + + /* enabling rx */ + eepro_en_rx(ioaddr); } @@ -1012,6 +1124,7 @@ lp->stats.tx_bytes+=skb->len; hardware_send_packet(dev, buf, length); + dev->trans_start = jiffies; } @@ -1053,31 +1166,34 @@ ioaddr = dev->base_addr; - do { - status = inb(ioaddr + STATUS_REG); - + while (((status = inb(ioaddr + STATUS_REG)) & 0x06) && (boguscount--)) + { + switch (status & (RX_INT | TX_INT)) { + case (RX_INT | TX_INT): + eepro_ack_rxtx(ioaddr); + break; + case RX_INT: + eepro_ack_rx(ioaddr); + break; + case TX_INT: + eepro_ack_tx(ioaddr); + break; + } if (status & RX_INT) { if (net_debug > 4) - printk(KERN_DEBUG "%s: packet received interrupt.\n", dev->name); + printk(KERN_DEBUG "%s: packet received interrupt.\n", dev->name); - /* Acknowledge the RX_INT */ - outb(RX_INT, ioaddr + STATUS_REG); /* Get the received packets */ eepro_rx(dev); } - - else if (status & TX_INT) { + if (status & TX_INT) { if (net_debug > 4) - printk(KERN_DEBUG "%s: packet transmit interrupt.\n", dev->name); - - /* Acknowledge the TX_INT */ - outb(TX_INT, ioaddr + STATUS_REG); + printk(KERN_DEBUG "%s: packet transmit interrupt.\n", dev->name); /* Process the status of transmitted packets */ eepro_transmit_interrupt(dev); } - - } while ((boguscount-- > 0) && (status & 0x06)); + } if (net_debug > 5) printk(KERN_DEBUG "%s: exiting eepro_interrupt routine.\n", dev->name); @@ -1090,32 +1206,31 @@ { struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr = dev->base_addr; - int rcv_ram = dev->mem_end; short temp_reg; netif_stop_queue(dev); - outb(BANK1_SELECT, ioaddr); /* Switch back to Bank 1 */ + eepro_sw2bank1(ioaddr); /* Switch back to Bank 1 */ /* Disable the physical interrupt line. */ temp_reg = inb(ioaddr + REG1); outb(temp_reg & 0x7f, ioaddr + REG1); - outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */ + eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */ /* Flush the Tx and disable Rx. */ outb(STOP_RCV_CMD, ioaddr); - lp->tx_start = lp->tx_end = rcv_ram ; + lp->tx_start = lp->tx_end = (XMT_LOWER_LIMIT << 8); lp->tx_last = 0; /* Mask all the interrupts. */ - outb(ALL_MASK, ioaddr + INT_MASK_REG); + eepro_dis_int(ioaddr); /* clear all interrupts */ - outb(ALL_MASK, ioaddr + STATUS_REG); + eepro_clear_int(ioaddr); /* Reset the 82595 */ - outb(RESET_CMD, ioaddr); + eepro_reset(ioaddr); /* release the interrupt */ free_irq(dev->irq, dev); @@ -1126,10 +1241,6 @@ /* Update the statistics here. What statistics? */ - /* We are supposed to wait for 200 us after a RESET */ - SLOW_DOWN; - SLOW_DOWN; /* May not be enough? */ - MOD_DEC_USE_COUNT; return 0; } @@ -1164,23 +1275,23 @@ */ dev->flags|=IFF_PROMISC; - outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */ + eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */ mode = inb(ioaddr + REG2); outb(mode | PRMSC_Mode, ioaddr + REG2); mode = inb(ioaddr + REG3); outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */ - outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */ + eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */ printk("%s: promiscuous mode enabled.\n", dev->name); } else if (dev->mc_count==0 ) { - outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */ + eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */ mode = inb(ioaddr + REG2); outb(mode & 0xd6, ioaddr + REG2); /* Turn off Multi-IA and PRMSC_Mode bits */ mode = inb(ioaddr + REG3); outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */ - outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */ + eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */ } else @@ -1191,14 +1302,14 @@ /* Disable RX and TX interrupts. Necessary to avoid corruption of the HOST_ADDRESS_REG by interrupt service routines. */ - outb(ALL_MASK, ioaddr + INT_MASK_REG); + eepro_dis_int(ioaddr); - outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */ + eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */ mode = inb(ioaddr + REG2); outb(mode | Multi_IA, ioaddr + REG2); mode = inb(ioaddr + REG3); outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */ - outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */ + eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */ outw(lp->tx_end, ioaddr + HOST_ADDRESS_REG); outw(MC_SETUP, ioaddr + IO_PORT); outw(0, ioaddr + IO_PORT); @@ -1218,7 +1329,7 @@ outw(eaddrs[0], ioaddr + IO_PORT); outw(eaddrs[1], ioaddr + IO_PORT); outw(eaddrs[2], ioaddr + IO_PORT); - outw(lp->tx_end, ioaddr + XMT_BAR); + outw(lp->tx_end, ioaddr + xmt_bar); outb(MC_SETUP, ioaddr); /* Update the transmit queue */ @@ -1262,10 +1373,9 @@ } while (++boguscount < 100); /* Re-enable RX and TX interrupts */ - outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); - + eepro_en_int(ioaddr); } - outb(RCV_ENABLE_CMD, ioaddr); + eepro_en_rx(ioaddr); } /* The horrible routine to read a word from the serial EEPROM. */ @@ -1276,15 +1386,25 @@ #define EE_READ_CMD (6 << 6) int -read_eeprom(int ioaddr, int location) +read_eeprom(int ioaddr, int location, struct net_device *dev) { int i; unsigned short retval = 0; - short ee_addr = ioaddr + EEPROM_REG; + short ee_addr = ioaddr + eeprom_reg; + struct eepro_local *lp = (struct eepro_local *)dev->priv; int read_cmd = location | EE_READ_CMD; short ctrl_val = EECS ; + + /* XXXX - this is not the final version. We must test this on other + * boards other than eepro10. I think that it won't let other + * boards to fail. (aris) + */ + if (lp->eepro == LAN595FX_10ISA) { + eepro_sw2bank1(ioaddr); + outb(0x00, ioaddr + STATUS_REG); + } - outb(BANK2_SELECT, ioaddr); + eepro_sw2bank2(ioaddr); outb(ctrl_val, ee_addr); /* Shift the read command bits out. */ @@ -1311,7 +1431,7 @@ eeprom_delay(); outb(ctrl_val, ee_addr); eeprom_delay(); - outb(BANK0_SELECT, ioaddr); + eepro_sw2bank0(ioaddr); return retval; } @@ -1320,7 +1440,6 @@ { struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; - int rcv_ram = dev->mem_end; unsigned status, tx_available, last, end, boguscount = 100; if (net_debug > 5) @@ -1331,7 +1450,7 @@ /* Disable RX and TX interrupts. Necessary to avoid corruption of the HOST_ADDRESS_REG by interrupt service routines. */ - outb(ALL_MASK, ioaddr + INT_MASK_REG); + eepro_dis_int(ioaddr); /* determine how much of the transmit buffer space is available */ if (lp->tx_end > lp->tx_start) @@ -1346,26 +1465,24 @@ eepro_transmit_interrupt(dev); /* Clean up the transmiting queue */ /* Enable RX and TX interrupts */ - outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); + eepro_en_int(ioaddr); continue; } last = lp->tx_end; end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; - if (end >= RAM_SIZE) { /* the transmit buffer is wrapped around */ - - if ((RAM_SIZE - last) <= XMT_HEADER) { + if (end >= (XMT_UPPER_LIMIT << 8)) { /* the transmit buffer is wrapped around */ + if (((XMT_UPPER_LIMIT << 8) - last) <= XMT_HEADER) { /* Arrrr!!!, must keep the xmt header together, several days were lost to chase this one down. */ - last = rcv_ram; + last = (XMT_LOWER_LIMIT << 8); end = last + (((length + 3) >> 1) << 1) + XMT_HEADER; } - else end = rcv_ram + (end - RAM_SIZE); + else end = (XMT_LOWER_LIMIT << 8) + (end - XMT_RAM); } - outw(last, ioaddr + HOST_ADDRESS_REG); outw(XMT_CMD, ioaddr + IO_PORT); outw(0, ioaddr + IO_PORT); @@ -1385,7 +1502,7 @@ status = inw(ioaddr + IO_PORT); if (lp->tx_start == lp->tx_end) { - outw(last, ioaddr + XMT_BAR); + outw(last, ioaddr + xmt_bar); outb(XMT_CMD, ioaddr); lp->tx_start = last; /* I don't like to change tx_start here */ } @@ -1411,15 +1528,22 @@ if (netif_queue_stopped(dev)) netif_wake_queue(dev); + + /* now we are serializing tx. queue won't come back until + * the tx interrupt + */ + if (lp->eepro == LAN595FX_10ISA) + netif_stop_queue(dev); /* Enable RX and TX interrupts */ - outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); + eepro_en_int(ioaddr); if (net_debug > 5) printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name); return; } - + eepro_en_int(ioaddr); + netif_stop_queue(dev); if (net_debug > 5) printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name); @@ -1429,13 +1553,16 @@ eepro_rx(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; - short ioaddr = dev->base_addr, rcv_ram = dev->mem_end; + short ioaddr = dev->base_addr; short boguscount = 20; - short rcv_car = lp->rx_start; + unsigned rcv_car = lp->rx_start; unsigned rcv_event, rcv_status, rcv_next_frame, rcv_size; if (net_debug > 5) printk(KERN_DEBUG "%s: entering eepro_rx routine.\n", dev->name); + + /* clear all interrupts */ + eepro_clear_int(ioaddr); /* Set the read pointer to the start of the RCV */ outw(rcv_car, ioaddr + HOST_ADDRESS_REG); @@ -1515,6 +1642,9 @@ if (net_debug > 5) printk(KERN_DEBUG "%s: exiting eepro_rx routine.\n", dev->name); + + /* enable tx/rx interrupts */ + eepro_en_int(ioaddr); } static void @@ -1523,7 +1653,7 @@ struct eepro_local *lp = (struct eepro_local *)dev->priv; short ioaddr = dev->base_addr; short boguscount = 20; - short xmt_status; + unsigned xmt_status; /* if (dev->tbusy == 0) { @@ -1533,31 +1663,67 @@ dev->name); } */ + while (lp->tx_start != lp->tx_end && boguscount) { - while (lp->tx_start != lp->tx_end) { - outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG); xmt_status = inw(ioaddr+IO_PORT); - if ((xmt_status & TX_DONE_BIT) == 0) break; + if ((xmt_status & TX_DONE_BIT) == 0) { + udelay(40); + boguscount--; + continue; + } xmt_status = inw(ioaddr+IO_PORT); lp->tx_start = inw(ioaddr+IO_PORT); + if (lp->eepro == LAN595FX_10ISA) { + lp->tx_start = (XMT_LOWER_LIMIT << 8); + lp->tx_end = lp->tx_start; + + /* yeah, black magic :( */ + eepro_sw2bank0(ioaddr); + eepro_en_int(ioaddr); + + /* disabling rx */ + eepro_dis_rx(ioaddr); + + /* enabling rx */ + eepro_en_rx(ioaddr); + } + netif_wake_queue (dev); if (xmt_status & 0x2000) lp->stats.tx_packets++; else { lp->stats.tx_errors++; - if (xmt_status & 0x0400) + if (xmt_status & 0x0400) { lp->stats.tx_carrier_errors++; - printk("%s: XMT status = %#x\n", - dev->name, xmt_status); - printk(KERN_DEBUG "%s: XMT status = %#x\n", - dev->name, xmt_status); + printk(KERN_DEBUG "%s: carrier error\n", + dev->name); + printk(KERN_DEBUG "%s: XMT status = %#x\n", + dev->name, xmt_status); + } + else { + printk(KERN_DEBUG "%s: XMT status = %#x\n", + dev->name, xmt_status); + printk(KERN_DEBUG "%s: XMT status = %#x\n", + dev->name, xmt_status); + } + if (lp->eepro == LAN595FX_10ISA) { + /* Try to restart the adaptor. */ + /* We are supposed to wait for 2 us after a SEL_RESET */ + eepro_sel_reset(ioaddr); + + /* first enable interrupts */ + eepro_sw2bank0(ioaddr); + outb(ALL_MASK & ~(RX_INT | TX_INT), ioaddr + STATUS_REG); + + /* enabling rx */ + eepro_en_rx(ioaddr); + } } - if (xmt_status & 0x000f) { lp->stats.collisions += (xmt_status & 0x000f); } @@ -1566,25 +1732,19 @@ lp->stats.tx_heartbeat_errors++; } - if (--boguscount == 0) - break; + boguscount--; } } #define MAX_EEPRO 8 static struct net_device dev_eepro[MAX_EEPRO]; -static int io[MAX_EEPRO] = { -#ifdef PnPWakeup - 0x210, /*: default for PnP enabled FX chips */ -#else - 0x200, /* Why? */ -#endif - [1 ... MAX_EEPRO - 1] = -1 }; +static int io[MAX_EEPRO]; static int irq[MAX_EEPRO] = { [0 ... MAX_EEPRO-1] = 0 }; static int mem[MAX_EEPRO] = { /* Size of the rx buffer in KB */ - [0 ... MAX_EEPRO-1] = RCV_RAM/1024 + [0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024 }; +static int autodetect; static int n_eepro = 0; /* For linux 2.1.xx */ @@ -1594,19 +1754,30 @@ MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i"); MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i"); MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i"); +MODULE_PARM(autodetect, "1-" __MODULE_STRING(1) "i"); #ifdef MODULE int init_module(void) { - if (io[0] == 0) - printk("eepro_init_module: You should not use auto-probing with insmod!\n"); + int i; + if (io[0] == 0 && autodetect == 0) { + printk("eepro_init_module: Probe is very dangerous in ISA boards!\n"); + printk("eepro_init_module: Please add \"autodetect=1\" to force probe\n"); + return 1; + } + else if (autodetect) { + /* if autodetect is set then we must force detection */ + io[0] = 0; + + printk("eepro_init_module: Auto-detecting boards (May God protect us...)\n"); + } - while (n_eepro < MAX_EEPRO && io[n_eepro] >= 0) { + for (i = 0; i < MAX_EEPRO; i++) { struct net_device *d = &dev_eepro[n_eepro]; d->mem_end = mem[n_eepro]; - d->base_addr = io[n_eepro]; + d->base_addr = io[0]; d->irq = irq[n_eepro]; d->init = eepro_probe; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/fc/iph5526.c linux.ac/drivers/net/fc/iph5526.c --- linux.vanilla/drivers/net/fc/iph5526.c Thu May 25 17:37:58 2000 +++ linux.ac/drivers/net/fc/iph5526.c Fri May 26 14:36:51 2000 @@ -3771,7 +3771,9 @@ for (i = 0; i < clone_list[i].vendor_id != 0; i++) while ((pdev = pci_find_device(clone_list[i].vendor_id, clone_list[i].device_id, pdev))) { - unsigned short pci_command; + unsigned short pci_command; + if (pci_enable_device(pdev)) + continue; if (count < MAX_FC_CARDS) { fc[count] = kmalloc(sizeof(struct fc_info), GFP_ATOMIC); if (fc[count] == NULL) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/ioc3-eth.c linux.ac/drivers/net/ioc3-eth.c --- linux.vanilla/drivers/net/ioc3-eth.c Thu May 25 17:37:58 2000 +++ linux.ac/drivers/net/ioc3-eth.c Mon May 29 19:29:10 2000 @@ -38,7 +38,6 @@ * - Free rings and buffers when closing or before re-initializing rings. * - Handle allocation failures in ioc3_alloc_skb() more gracefully. * - Handle allocation failures in ioc3_init_rings(). - * - Maybe implement private_ioctl(). * - Use prefetching for large packets. What is a good lower limit for * prefetching? * - We're probably allocating a bit too much memory. @@ -75,6 +74,17 @@ /* 32 RX buffers. This is tunable in the range of 16 <= x < 512. */ #define RX_BUFFS 32 +/* Private ioctls that de facto are well known and used for examply + by mii-tool. */ +#define SIOCGMIIPHY (SIOCDEVPRIVATE) /* Read from current PHY */ +#define SIOCGMIIREG (SIOCDEVPRIVATE+1) /* Read any PHY register */ +#define SIOCSMIIREG (SIOCDEVPRIVATE+2) /* Write any PHY register */ + +/* These exist in other drivers; we don't use them at this time. */ +#define SIOCGPARAMS (SIOCDEVPRIVATE+3) /* Read operational parameters */ +#define SIOCSPARAMS (SIOCDEVPRIVATE+4) /* Set operational parameters */ + +static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void ioc3_set_multicast_list(struct net_device *dev); static int ioc3_open(struct net_device *dev); static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev); @@ -97,6 +107,7 @@ int rx_pi; /* RX producer index */ int tx_ci; /* TX consumer index */ int tx_pi; /* TX producer index */ + int txqlen; spinlock_t ioc3_lock; }; @@ -124,17 +135,6 @@ #define BARRIER() \ __asm__("sync" ::: "memory") -/* This El Cheapo implementatin of TX_BUFFS_AVAIL may leave on entry unused. - Since the TX ring has 128 entries which is fairly large we don't care and - use this, more efficient implementation. */ -#define TX_BUFFS_AVAIL(ip) \ -({ \ - struct ioc3_private *_ip = (ip); \ - ((512 + _ip->tx_ci + 1) - _ip->tx_pi) & 511; \ -}) -//#undef TX_BUFFS_AVAIL -//#define TX_BUFFS_AVAIL(ip) (1) - #define IOC3_SIZE 0x100000 @@ -276,6 +276,8 @@ printk(".\n"); } +/* Caller must hold the ioc3_lock ever for MII readers. This is also + used to protect the transmitter side but it's low contention. */ static u16 mii_read(struct ioc3 *ioc3, int phy, int reg) { while (ioc3->micr & MICR_BUSY); @@ -385,8 +387,9 @@ } static inline void -ioc3_tx(struct ioc3_private *ip, struct ioc3 *ioc3) +ioc3_tx(struct net_device *dev, struct ioc3_private *ip, struct ioc3 *ioc3) { + unsigned long packets, bytes; int tx_entry, o_entry; struct sk_buff *skb; u32 etcir; @@ -395,14 +398,16 @@ etcir = ioc3->etcir; tx_entry = (etcir >> 7) & 127; o_entry = ip->tx_ci; + packets = 0; + bytes = 0; while (o_entry != tx_entry) { ioc3->eisr = EISR_TXEXPLICIT; /* Ack */ ioc3->eisr; /* Flush */ + packets++; + bytes += skb->len; skb = ip->tx_skbs[o_entry]; - ip->stats.tx_packets++; - ip->stats.tx_bytes += skb->len; dev_kfree_skb_irq(skb); ip->tx_skbs[o_entry] = NULL; @@ -411,6 +416,14 @@ etcir = ioc3->etcir; /* More pkts sent? */ tx_entry = (etcir >> 7) & 127; } + + ip->stats.tx_packets += packets; + ip->stats.tx_bytes += bytes; + ip->txqlen -= packets; + + if (ip->txqlen < 128) + netif_wake_queue(dev); + ip->tx_ci = o_entry; spin_unlock(&ip->ioc3_lock); } @@ -454,24 +467,20 @@ ioc3_rx(dev, ip, ioc3); } if (eisr & EISR_TXEXPLICIT) { - ioc3_tx(ip, ioc3); + ioc3_tx(dev, ip, ioc3); } if (eisr & (EISR_RXMEMERR | EISR_TXMEMERR)) { ioc3_error(dev, ip, ioc3, eisr); } - if ((TX_BUFFS_AVAIL(ip) >= 0) && netif_queue_stopped(dev)) { - netif_wake_queue(dev); - } - __cli(); ioc3->eier = eier; return; } -int -ioc3_eth_init(struct net_device *dev, struct ioc3_private *p, struct ioc3 *ioc3) +int ioc3_eth_init(struct net_device *dev, struct ioc3_private *ip, + struct ioc3 *ioc3) { u16 word, mii0, mii_status, mii2, mii3, mii4; u32 vendor, model, rev; @@ -482,6 +491,7 @@ udelay(4); /* Give it time ... */ ioc3->emcr = 0; + spin_lock_irq(&ip->ioc3_lock); phy = -1; for (i = 0; i < 32; i++) { word = mii_read(ioc3, i, 2); @@ -491,10 +501,11 @@ } } if (phy == -1) { + spin_unlock_irq(&ip->ioc3_lock); printk("Didn't find a PHY, goodbye.\n"); return -ENODEV; } - p->phy = phy; + ip->phy = phy; mii0 = mii_read(ioc3, phy, 0); mii_status = mii_read(ioc3, phy, 1); @@ -512,8 +523,13 @@ /* Autonegotiate 100mbit and fullduplex. */ mii_write(ioc3, phy, 0, mii0 | 0x3100); - mdelay(1000); + + spin_unlock_irq(&ip->ioc3_lock); + mdelay(1000); /* XXX Yikes XXX */ + spin_lock_irq(&ip->ioc3_lock); + mii_status = mii_read(ioc3, phy, 1); + spin_unlock_irq(&ip->ioc3_lock); return 0; /* XXX */ } @@ -629,6 +645,7 @@ ioc3_init_rings(dev, ip, ioc3); spin_lock_init(&ip->ioc3_lock); + ip->txqlen = 0; /* Misc registers */ ioc3->erbar = 0; @@ -644,13 +661,14 @@ //ioc3->erpir = ERPIR_ARM; /* The IOC3-specific entries in the device structure. */ - dev->open = &ioc3_open; - dev->hard_start_xmit = &ioc3_start_xmit; + dev->open = ioc3_open; + dev->hard_start_xmit = ioc3_start_xmit; dev->tx_timeout = ioc3_timeout; dev->watchdog_timeo = (400 * HZ) / 1000; - dev->stop = &ioc3_close; - dev->get_stats = &ioc3_get_stats; - dev->set_multicast_list = &ioc3_set_multicast_list; + dev->stop = ioc3_close; + dev->get_stats = ioc3_get_stats; + dev->do_ioctl = ioc3_ioctl; + dev->set_multicast_list = ioc3_set_multicast_list; } int @@ -664,7 +682,11 @@ return 0; initialized++; - nid = get_nasid(); +#if 0 + nid = get_nasid(); /* Never assume we are on master cpu */ +#else + nid = 0; +#endif ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base; ioc3_probe1(dev, ioc3); @@ -693,7 +715,7 @@ ioc3->eier = EISR_RXTIMERINT | EISR_TXEXPLICIT | /* Interrupts ... */ EISR_RXMEMERR | EISR_TXMEMERR; - netif_wake_queue(dev); + netif_start_queue(dev); restore_flags(flags); MOD_INC_USE_COUNT; @@ -711,11 +733,8 @@ struct ioc3_etxd *desc; int produce; - if (!TX_BUFFS_AVAIL(ip)) { - return 1; - } - spin_lock_irq(&ip->ioc3_lock); + data = (unsigned long) skb->data; len = skb->len; @@ -759,8 +778,11 @@ ip->tx_pi = produce; ioc3->etpir = produce << 7; /* Fire ... */ - if (TX_BUFFS_AVAIL(ip)) - netif_wake_queue(dev); + ip->txqlen++; + + if (ip->txqlen > 127) + netif_stop_queue(dev); + spin_unlock_irq(&ip->ioc3_lock); return 0; @@ -853,6 +875,40 @@ return temp; } +/* Provide ioctl() calls to examine the MII xcvr state. */ +static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct ioc3_private *ip = (struct ioc3_private *) dev->priv; + u16 *data = (u16 *)&rq->ifr_data; + struct ioc3 *ioc3 = ip->regs; + int phy = ip->phy; + + switch (cmd) { + case SIOCGMIIPHY: /* Get the address of the PHY in use. */ + if (phy == -1) + return -ENODEV; + data[0] = phy; + return 0; + + case SIOCGMIIREG: /* Read any PHY register. */ + spin_lock_irq(&ip->ioc3_lock); + data[3] = mii_read(ioc3, data[0], data[1]); + spin_unlock_irq(&ip->ioc3_lock); + return 0; + + case SIOCSMIIREG: /* Write any PHY register. */ + spin_lock_irq(&ip->ioc3_lock); + mii_write(ioc3, data[0], data[1], data[2]); + spin_unlock_irq(&ip->ioc3_lock); + return 0; + + default: + return -EOPNOTSUPP; + } + + return -EOPNOTSUPP; +} + static void ioc3_set_multicast_list(struct net_device *dev) { struct dev_mc_list *dmi = dev->mc_list; @@ -905,6 +961,8 @@ struct pci_dev *dev = NULL; while ((dev = pci_find_device(PCI_VENDOR_ID_SGI, 0x0003, dev))) { + if (pci_enable_device(dev)) + continue; ioc3_init(&p, dev); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/irda/Makefile linux.ac/drivers/net/irda/Makefile --- linux.vanilla/drivers/net/irda/Makefile Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/irda/Makefile Sat May 27 15:29:39 2000 @@ -52,22 +52,6 @@ endif endif -ifeq ($(CONFIG_TOSHIBA_FIR),y) -L_OBJS += toshoboe.o -else - ifeq ($(CONFIG_TOSHIBA_FIR),m) - M_OBJS += toshoboe.o - endif -endif - -ifeq ($(CONFIG_TOSHIBA_FIR),y) -L_OBJS += toshoboe.o -else - ifeq ($(CONFIG_TOSHIBA_FIR),m) - M_OBJS += toshoboe.o - endif -endif - ifeq ($(CONFIG_SMC_IRCC_FIR),y) L_OBJS += smc-ircc.o LX_OBJS += irport.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/irda/toshoboe.c linux.ac/drivers/net/irda/toshoboe.c --- linux.vanilla/drivers/net/irda/toshoboe.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/irda/toshoboe.c Fri May 26 14:36:51 2000 @@ -717,7 +717,7 @@ self->open = 0; self->stopped = 0; self->pdev = pci_dev; - self->base = pci_dev->resource[0].start; + self->base = pci_resource_start (pci_dev, 0); self->io.sir_base = self->base; self->io.irq = pci_dev->irq; @@ -900,7 +900,6 @@ static void toshoboe_wakeup (struct toshoboe_cb *self) { - struct net_device *dev = self->netdev; unsigned long flags; if (!self->stopped) @@ -952,36 +951,26 @@ struct pci_dev *pci_dev = NULL; int found = 0; - do - { - pci_dev = pci_find_device (PCI_VENDOR_ID_TOSHIBA, - PCI_DEVICE_ID_FIR701, pci_dev); - if (pci_dev) - { + while ((pci_dev = pci_find_device (PCI_VENDOR_ID_TOSHIBA, + PCI_DEVICE_ID_FIR701, pci_dev)) != NULL) { + if (pci_enable_device(pci_dev)) + continue; printk (KERN_WARNING "ToshOboe: Found 701 chip at 0x%0lx irq %d\n", - pci_dev->resource[0].start, + pci_resource_start (pci_dev, 0), pci_dev->irq); if (!toshoboe_open (pci_dev)) found++; - } - - } - while (pci_dev); - + } if (found) - { return 0; - } return -ENODEV; } -#ifdef MODULE -static void -toshoboe_cleanup (void) +static void __exit toshoboe_cleanup (void) { int i; @@ -997,19 +986,8 @@ } - -int -init_module (void) -{ - return toshoboe_init (); -} - - -void -cleanup_module (void) -{ - toshoboe_cleanup (); -} - - +#ifdef MODULE +module_init(toshoboe_init); #endif +module_exit(toshoboe_cleanup); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/lance.c linux.ac/drivers/net/lance.c --- linux.vanilla/drivers/net/lance.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/lance.c Fri May 26 14:36:51 2000 @@ -361,7 +361,6 @@ lance_need_isa_bounce_buffers = 0; #if defined(CONFIG_PCI) - if (pci_present()) { struct pci_dev *pdev = NULL; if (lance_debug > 1) @@ -369,20 +368,12 @@ while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, pdev))) { unsigned int pci_ioaddr; - unsigned short pci_command; + if (pci_enable_device(pdev)) + continue; + pci_set_master(pdev); pci_irq_line = pdev->irq; - pci_ioaddr = pdev->resource[0].start; - /* PCI Spec 2.1 states that it is either the driver or PCI card's - * responsibility to set the PCI Master Enable Bit if needed. - * (From Mark Stockton ) - */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_command); - if ( ! (pci_command & PCI_COMMAND_MASTER)) { - printk("PCI Master Bit has not been set. Setting...\n"); - pci_command |= PCI_COMMAND_MASTER; - pci_write_config_word(pdev, PCI_COMMAND, pci_command); - } + pci_ioaddr = pci_resource_start (pdev, 0); printk("Found PCnet/PCI at %#x, irq %d.\n", pci_ioaddr, pci_irq_line); result = lance_probe1(dev, pci_ioaddr, pci_irq_line, 0); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/ne.c linux.ac/drivers/net/ne.c --- linux.vanilla/drivers/net/ne.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/ne.c Fri May 26 14:36:51 2000 @@ -195,7 +195,7 @@ if (base_addr > 0x1ff) /* Check a single specified location. */ return ne_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ - return ENXIO; + return -ENXIO; #ifdef CONFIG_PCI /* Then look for any installed PCI clones */ @@ -218,7 +218,7 @@ } #endif - return ENODEV; + return -ENODEV; } #endif @@ -232,7 +232,9 @@ unsigned int pci_ioaddr; while ((pdev = pci_find_device(pci_clone_list[i].vendor, pci_clone_list[i].dev_id, pdev))) { - pci_ioaddr = pdev->resource[0].start; + if (pci_enable_device(pdev)) + continue; + pci_ioaddr = pci_resource_start (pdev, 0); /* Avoid already found cards from previous calls */ if (check_region(pci_ioaddr, NE_IO_EXTENT)) continue; @@ -309,7 +311,7 @@ static unsigned version_printed = 0; if (reg0 == 0xFF) - return ENODEV; + return -ENODEV; /* Do a preliminary verification that we have a 8390. */ { @@ -322,7 +324,7 @@ if (inb_p(ioaddr + EN0_COUNTER0) != 0) { outb_p(reg0, ioaddr); outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */ - return ENODEV; + return -ENODEV; } } @@ -364,7 +366,7 @@ break; } else { printk(" not found (no reset ack).\n"); - return ENODEV; + return -ENODEV; } } @@ -466,11 +468,11 @@ { printk(" not found (invalid signature %2.2x %2.2x).\n", SA_prom[14], SA_prom[15]); - return ENXIO; + return -ENXIO; } #else printk(" not found.\n"); - return ENXIO; + return -ENXIO; #endif } @@ -496,7 +498,7 @@ if (! dev->irq) { printk(" failed to detect IRQ line.\n"); - return EAGAIN; + return -EAGAIN; } /* Allocate dev->priv and fill in 8390 specific dev fields. */ @@ -516,7 +518,7 @@ printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); kfree(dev->priv); dev->priv = NULL; - return EAGAIN; + return -EAGAIN; } } dev->base_addr = ioaddr; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/net_init.c linux.ac/drivers/net/net_init.c --- linux.vanilla/drivers/net/net_init.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/net_init.c Thu May 25 20:28:46 2000 @@ -115,14 +115,17 @@ * Allocate a name */ - if (dev->name[0] == '\0' || dev->name[0] == ' ') - { - if(dev_alloc_name(dev, mask)<0) - { - if(new_device) - kfree(dev); - return NULL; + if (dev->name[0] == '\0' || dev->name[0] == ' ') { + strcpy(dev->name, mask); + if (!netdev_boot_setup_check(dev)) { + if (dev_alloc_name(dev, mask)<0) { + if (new_device) + kfree(dev); + return NULL; + } } + } else { + netdev_boot_setup_check(dev); } /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/pcmcia/Config.in linux.ac/drivers/net/pcmcia/Config.in --- linux.vanilla/drivers/net/pcmcia/Config.in Thu May 25 17:37:58 2000 +++ linux.ac/drivers/net/pcmcia/Config.in Sat May 27 22:03:39 2000 @@ -21,12 +21,12 @@ tristate ' Xircom Tulip-like CardBus support' CONFIG_PCMCIA_XIRTULIP fi - bool 'Pcmcia Wireless LAN' CONFIG_NET_PCMCIA_RADIO + bool ' Pcmcia Wireless LAN' CONFIG_NET_PCMCIA_RADIO if [ "$CONFIG_NET_PCMCIA_RADIO" = "y" ]; then - dep_tristate ' Aviator/Raytheon 2.4MHz wireless support' CONFIG_PCMCIA_RAYCS $CONFIG_PCMCIA - dep_tristate ' Xircom Netwave AirSurfer wireless support' CONFIG_PCMCIA_NETWAVE $CONFIG_PCMCIA - dep_tristate ' AT&T/Lucent Wavelan wireless support' CONFIG_PCMCIA_WAVELAN $CONFIG_PCMCIA - dep_tristate ' Aironet 4500/4800 PCMCIA support' CONFIG_AIRONET4500_CS $CONFIG_AIRONET4500 $CONFIG_PCMCIA + dep_tristate ' Aviator/Raytheon 2.4MHz wireless support' CONFIG_PCMCIA_RAYCS $CONFIG_PCMCIA + dep_tristate ' Xircom Netwave AirSurfer wireless support' CONFIG_PCMCIA_NETWAVE $CONFIG_PCMCIA + dep_tristate ' AT&T/Lucent Wavelan wireless support' CONFIG_PCMCIA_WAVELAN $CONFIG_PCMCIA + dep_tristate ' Aironet 4500/4800 PCMCIA support' CONFIG_AIRONET4500_CS $CONFIG_AIRONET4500 $CONFIG_PCMCIA fi fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/pcnet32.c linux.ac/drivers/net/pcnet32.c --- linux.vanilla/drivers/net/pcnet32.c Thu May 25 17:37:54 2000 +++ linux.ac/drivers/net/pcnet32.c Fri May 26 14:36:51 2000 @@ -311,21 +311,6 @@ int (*probe1) (unsigned long, unsigned char, int, int, struct pci_dev *); }; -static struct pcnet32_pci_id_info pcnet32_tbl[] = { - { "AMD PCnetPCI series", - PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0, 0, - PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, - pcnet32_probe1}, - { "AMD PCnetPCI series (IBM)", - PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0x1014, 0x2000, - PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, - pcnet32_probe1}, - { "AMD PCnetHome series", - PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_PCNETHOME, 0, 0, - PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, - pcnet32_probe1}, - {0,} -}; /* * PCI device identifiers for "new style" Linux PCI Device Drivers @@ -751,7 +736,7 @@ } if (pcnet32_debug > 0) - printk(KERN_INFO, version); + printk(KERN_INFO "%s", version); /* The PCNET32-specific entries in the device structure. */ dev->open = &pcnet32_open; @@ -1257,8 +1242,7 @@ lp->stats.rx_errors++; } else { int rx_in_place = 0; - dma_addr_t rx_dma_addr = lp->rx_dma_addr[entry]; - + if (pkt_len > rx_copybreak) { struct sk_buff *newskb; @@ -1524,7 +1508,7 @@ /* find the PCI devices */ #define USE_PCI_REGISTER_DRIVER #ifdef USE_PCI_REGISTER_DRIVER - if (err = pci_module_init(&pcnet32_driver) < 0 ) + if ((err = pci_module_init(&pcnet32_driver)) < 0 ) return err; #else { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/rcpci45.c linux.ac/drivers/net/rcpci45.c --- linux.vanilla/drivers/net/rcpci45.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/rcpci45.c Fri May 26 14:36:51 2000 @@ -205,7 +205,7 @@ !((pdev = pci_find_slot(pci_bus, pci_device_fn)))) break; pci_irq_line = pdev->irq; - pci_ioaddr = pdev->resource[0].start; + pci_ioaddr = pci_resource_start (pdev, 0); #ifdef RCDEBUG printk("rc: Found RedCreek PCI adapter\n"); @@ -214,6 +214,8 @@ printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr); #endif + if (pci_enable_device(pdev)) + break; pci_set_master(pdev); if (!RCfound_device(pci_ioaddr, pci_irq_line, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/rrunner.c linux.ac/drivers/net/rrunner.c --- linux.vanilla/drivers/net/rrunner.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/rrunner.c Fri May 26 14:36:51 2000 @@ -146,6 +146,9 @@ PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER, pdev))) { + if (pci_enable_device(pdev)) + continue; + if (pdev == opdev) return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/rtl8129.c linux.ac/drivers/net/rtl8129.c --- linux.vanilla/drivers/net/rtl8129.c Thu May 25 17:37:58 2000 +++ linux.ac/drivers/net/rtl8129.c Fri May 26 14:36:51 2000 @@ -356,6 +356,9 @@ ioaddr = pdev->resource[0].start; irq = pdev->irq; + if (pci_enable_device(pdev)) + continue; + if ((pci_tbl[chip_idx].flags & PCI_USES_IO) && check_region(ioaddr, pci_tbl[chip_idx].io_size)) continue; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/sis900.c linux.ac/drivers/net/sis900.c --- linux.vanilla/drivers/net/sis900.c Thu May 25 17:37:54 2000 +++ linux.ac/drivers/net/sis900.c Fri May 26 14:17:27 2000 @@ -1,6 +1,6 @@ /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux. Copyright 1999 Silicon Integrated System Corporation - Revision: 1.06.04 Feb 11 2000 + Revision: 1.07 Mar. 07 2000 Modified from the driver which is originally written by Donald Becker. @@ -18,6 +18,7 @@ preliminary Rev. 1.0 Jan. 18, 1998 http://www.sis.com.tw/support/databook.htm + Rev 1.07 Mar. 07 2000 Ollie Lho bug fix in Rx buffer ring Rev 1.06.04 Feb. 11 2000 Jeff Garzik softnet and init for kernel 2.4 Rev 1.06.03 Dec. 23 1999 Ollie Lho Third release Rev 1.06.02 Nov. 23 1999 Ollie Lho bug in mac probing fixed @@ -69,17 +70,17 @@ char *card_name); enum { SIS_900 = 0, - SIS_7018 + SIS_7016 }; static char * card_names[] = { "SiS 900 PCI Fast Ethernet", "SiS 7016 PCI Fast Ethernet" }; -static struct pci_device_id sis900_pci_tbl [] __initdata = { +static struct pci_device_id sis900_pci_tbl [] __devinitdata = { {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_900}, {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7016, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018}, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7016}, {0,} }; MODULE_DEVICE_TABLE (pci, sis900_pci_tbl); @@ -123,6 +124,7 @@ unsigned int cur_phy; struct timer_list timer; /* Link status detection timer. */ + unsigned int cur_rx, dirty_rx; unsigned int cur_tx, dirty_tx; @@ -131,8 +133,8 @@ struct sk_buff *rx_skbuff[NUM_RX_DESC]; BufferDesc tx_ring[NUM_TX_DESC]; BufferDesc rx_ring[NUM_RX_DESC]; - unsigned int tx_full; /* The Tx queue is full. */ + unsigned int tx_full; /* The Tx queue is full. */ int LinkOn; }; @@ -175,7 +177,7 @@ return -ENODEV; } - pci_io_base = pci_dev->resource[0].start; + pci_io_base = pci_resource_start(pci_dev, 0); if (check_region(pci_io_base, SIS900_TOTAL_SIZE)) { printk(KERN_ERR "sis900.c: can't allocate I/O space at 0x%08x\n", pci_io_base); @@ -189,7 +191,7 @@ /* do the real low level jobs */ if (sis900_mac_probe(pci_dev, card_names[pci_id->driver_data]) == NULL) - return -1; + return -ENODEV; return 0; } @@ -197,7 +199,7 @@ static struct net_device * __init sis900_mac_probe (struct pci_dev * pci_dev, char * card_name) { struct sis900_private *sis_priv; - long ioaddr = pci_dev->resource[0].start; + long ioaddr = pci_resource_start(pci_dev, 0); struct net_device *net_dev = NULL; int irq = pci_dev->irq; u16 signature; @@ -472,15 +474,16 @@ struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv; long ioaddr = net_dev->base_addr; + MOD_INC_USE_COUNT; + /* Soft reset the chip. */ sis900_reset(net_dev); if (request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ, net_dev->name, net_dev)) { + MOD_DEC_USE_COUNT; return -EAGAIN; } - MOD_INC_USE_COUNT; - sis900_init_rxfilter(net_dev); sis900_init_tx_ring(net_dev); @@ -1256,8 +1259,7 @@ struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv; unregister_netdev(net_dev); - release_region(net_dev->base_addr, - SIS900_TOTAL_SIZE); + release_region(net_dev->base_addr, SIS900_TOTAL_SIZE); kfree(sis_priv); kfree(net_dev); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/sk98lin/skge.c linux.ac/drivers/net/sk98lin/skge.c --- linux.vanilla/drivers/net/sk98lin/skge.c Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/sk98lin/skge.c Fri May 26 14:36:51 2000 @@ -369,24 +369,18 @@ if (!pci_present()) /* is PCI support present? */ return -ENODEV; - while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) - { - dev = NULL; - - if (pdev->vendor != PCI_VENDOR_ID_SYSKONNECT || - pdev->device != PCI_DEVICE_ID_SYSKONNECT_GE) { + while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT, + PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) { + if (pci_enable_device(pdev)) continue; - } dev = init_etherdev(dev, sizeof(SK_AC)); - if (dev == NULL || dev->priv == NULL){ + if (dev == NULL) { printk(KERN_ERR "Unable to allocate etherdev " "structure!\n"); break; } - memset(dev->priv, 0, sizeof(SK_AC)); - pAC = dev->priv; pAC->PciDev = *pdev; pAC->PciDevId = pdev->device; @@ -412,7 +406,7 @@ pci_set_master(pdev); - base_address = pdev->resource[0].start; + base_address = pci_resource_start (pdev, 0); #ifdef SK_BIG_ENDIAN /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tlan.c linux.ac/drivers/net/tlan.c --- linux.vanilla/drivers/net/tlan.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/tlan.c Mon May 29 19:34:42 2000 @@ -72,6 +72,31 @@ * - TODO: Port completely to new PCI/DMA API * Auto-Neg fallback. * + * v1.6 April 04, 2000 - Fixed driver support for kernel-parameters. Haven't + * tested it though, as the kernel support is currently + * broken (2.3.99p4p3). + * - Updated tlan.txt accordingly. + * - Adjusted minimum/maximum frame length. + * - There is now a TLAN website up at + * http://tlan.kernel.dk + * + * v1.7 April 07, 2000 - Started to implement custom ioctls. Driver now + * reports PHY information when used with Donald + * Beckers userspace MII diagnostics utility. + * + * v1.8 April 23, 2000 - Fixed support for forced speed/duplex settings. + * - Added link information to Auto-Neg and forced + * modes. When NIC operates with auto-neg the driver + * will report Link speed & duplex modes as well as + * link partner abilities. When forced link is used, + * the driver will report status of the established + * link. + * Please read tlan.txt for additional information. + * - Removed call to check_region(), and used + * return value of request_region() instead. + * + * v1.8a May 28, 2000 - Minor updates. + * *******************************************************************************/ @@ -99,6 +124,8 @@ static int duplex = 0; static int speed = 0; +MODULE_AUTHOR("Maintainer: Torben Mathiasen "); +MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); MODULE_PARM(aui, "i"); MODULE_PARM(duplex, "i"); MODULE_PARM(speed, "i"); @@ -111,9 +138,14 @@ static int bbuf = 0; static u8 *TLanPadBuffer; static char TLanSignature[] = "TLAN"; -static int TLanVersionMajor = 1; -static int TLanVersionMinor = 5; +static const char *tlan_banner = "ThunderLAN driver v1.8a\n"; +const char *media[] = { + "10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ", + "100baseTx-FD", "100baseT4", 0 +}; + +int media_map[] = { 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,}; static TLanAdapterEntry TLanAdapterList[] __initdata = { { PCI_VENDOR_ID_COMPAQ, @@ -211,6 +243,7 @@ static int TLan_Close(struct net_device *); static struct net_device_stats *TLan_GetStats( struct net_device * ); static void TLan_SetMulticastList( struct net_device * ); +static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static u32 TLan_HandleInvalid( struct net_device *, u16 ); static u32 TLan_HandleTxEOF( struct net_device *, u16 ); @@ -371,9 +404,7 @@ u32 io_base, index; int found; - printk(KERN_INFO "ThunderLAN driver v%d.%d\n", - TLanVersionMajor, - TLanVersionMinor); + printk(KERN_INFO "%s", tlan_banner); TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE, (GFP_KERNEL | GFP_DMA)); @@ -404,17 +435,36 @@ dev->irq = irq; priv->adapter = &TLanAdapterList[index]; priv->adapterRev = rev; - priv->aui = aui; - if ( ( duplex != 1 ) && ( duplex != 2 ) ) - duplex = 0; - priv->duplex = duplex; + + /* Kernel parameters */ + if (dev->mem_start) { + priv->aui = dev->mem_start & 0x01; + priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1; + priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3; + + if (priv->speed == 0x1) { + priv->speed = TLAN_SPEED_10; + } else if (priv->speed == 0x2) { + priv->speed = TLAN_SPEED_100; + } + debug = priv->debug = dev->mem_end; + } else { - if ( ( speed != 10 ) && ( speed != 100 ) ) - speed = 0; + if ( ( duplex != 1 ) && ( duplex != 2 ) ) + duplex = 0; + + priv->duplex = duplex; - priv->speed = speed; - priv->debug = debug; + if ( ( speed != 10 ) && ( speed != 100 ) ) + speed = 0; + + priv->aui = aui; + priv->speed = speed; + priv->debug = debug; + + } + spin_lock_init(&priv->lock); if (TLan_Init(dev)) { @@ -495,8 +545,11 @@ TLanAdapterList[dl_index].deviceId ); + if (pci_enable_device(pdev)) + continue; + *pci_irq = pdev->irq; - *pci_io_base = pdev->resource[0].start; + *pci_io_base = pci_resource_start (pdev, 0); *pci_dfn = pdev->devfn; pci_read_config_byte ( pdev, PCI_REVISION_ID, pci_rev); pci_read_config_word ( pdev, PCI_COMMAND, &pci_command); @@ -554,13 +607,13 @@ static int TLan_Init( struct net_device *dev ) { int dma_size; - int err; + int err; int i; TLanPrivateInfo *priv; priv = (TLanPrivateInfo *) dev->priv; - err = check_region( dev->base_addr, 0x10 ); - if ( err ) { + + if (!request_region( dev->base_addr, 0x10, TLanSignature )) { printk(KERN_ERR "TLAN: %s: Io port region 0x%lx size 0x%x in use.\n", dev->name, dev->base_addr, @@ -568,7 +621,6 @@ return -EIO; } - request_region( dev->base_addr, 0x10, TLanSignature ); if ( bbuf ) { dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS ) @@ -611,7 +663,7 @@ dev->stop = &TLan_Close; dev->get_stats = &TLan_GetStats; dev->set_multicast_list = &TLan_SetMulticastList; - + dev->do_ioctl = &TLan_ioctl; return 0; @@ -669,6 +721,49 @@ + /************************************************************** + * TLan_ioctl + * + * Returns: + * 0 on success, error code otherwise + * Params: + * dev structure of device to receive ioctl. + * + * rq ifreq structure to hold userspace data. + * + * cmd ioctl command. + * + * + *************************************************************/ + +static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; + u16 *data = (u16 *)&rq->ifr_data; + u32 phy = priv->phy[priv->phyNum]; + + if (!priv->phyOnline) + return -EAGAIN; + + switch(cmd) { + case SIOCDEVPRIVATE: + data[0] = phy; + + case SIOCDEVPRIVATE+1: /* Read MII register */ + TLan_MiiReadReg(dev, data[0], data[1], &data[3]); + return 0; + + case SIOCDEVPRIVATE+2: /* Write MII register */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + TLan_MiiWriteReg(dev, data[0], data[1], data[2]); + return 0; + default: + return -EOPNOTSUPP; + } +} /* tlan_ioctl */ + + /*************************************************************** * TLan_StartTx @@ -1898,7 +1993,10 @@ u32 phy; u8 sio; u16 status; + u16 partner; u16 tlphy_ctl; + u16 tlphy_par; + int i; phy = priv->phy[priv->phyNum]; @@ -1922,7 +2020,26 @@ udelay( 1000 ); TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); if ( status & MII_GS_LINK ) { - printk( "TLAN: %s: Link active.\n", dev->name ); + TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner ); + TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par ); + + printk( "TLAN: %s: Link active with ", dev->name ); + if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) { + printk( "forced 10%sMbps %s-Duplex\n", + tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0", + tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half"); + } else { + printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n", + tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0", + tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half"); + + printk("TLAN: Partner capability: "); + for (i = 5; i <= 10; i++) + if (partner & (1<base_addr, TLAN_LED_REG, TLAN_LED_LINK ); } } @@ -1946,7 +2063,7 @@ outl( virt_to_bus( priv->rxList ), dev->base_addr + TLAN_CH_PARM ); outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD ); } else { - printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name ); + printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name ); TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET ); return; } @@ -2149,10 +2266,10 @@ TLan_MiiSync( dev->base_addr ); value = MII_GC_LOOPBK; TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value ); - + TLan_MiiSync(dev->base_addr); /* Wait for 500 ms and reset the * tranceiver. The TLAN docs say both 50 ms and - * 500 ms, so do the longer, just in case + * 500 ms, so do the longer, just in case. */ TLan_SetTimer( dev, (HZ/2), TLAN_TIMER_PHY_RESET ); @@ -2177,12 +2294,12 @@ while ( value & MII_GC_RESET ) { TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value ); } - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0 ); /* Wait for 500 ms and initialize. * I don't remember why I wait this long. + * I've changed this to 50ms, as it seems long enough. */ - TLan_SetTimer( dev, (HZ/2), TLAN_TIMER_PHY_START_LINK ); + TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK ); } /* TLan_PhyReset */ @@ -2200,52 +2317,56 @@ u16 tctl; phy = priv->phy[priv->phyNum]; - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name ); TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status ); + TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability ); if ( ( status & MII_GS_AUTONEG ) && - ( priv->duplex == TLAN_DUPLEX_DEFAULT ) && - ( priv->speed == TLAN_SPEED_DEFAULT ) && ( ! priv->aui ) ) { - ability = status >> 11; - - if ( priv->speed == TLAN_SPEED_10 ) { - ability &= 0x0003; - } else if ( priv->speed == TLAN_SPEED_100 ) { - ability &= 0x001C; - } - - if ( priv->duplex == TLAN_DUPLEX_FULL ) { - ability &= 0x000A; - } else if ( priv->duplex == TLAN_DUPLEX_HALF ) { - ability &= 0x0005; - } - - TLan_MiiWriteReg( dev, phy, MII_AN_ADV, ( ability << 5 ) | 1 ); - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 ); - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 ); - - /* Wait for 4 sec for autonegotiation - * to complete. The max spec time is less than this - * but the card need additional time to start AN. - * .5 sec should be plenty extra. - */ - printk( "TLAN: %s: Starting autonegotiation.\n", dev->name ); - TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_PHY_FINISH_AN ); - return; - } + ability = status >> 11; + if ( priv->speed == TLAN_SPEED_10 && + priv->duplex == TLAN_DUPLEX_HALF) { + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000); + } else if ( priv->speed == TLAN_SPEED_10 && + priv->duplex == TLAN_DUPLEX_FULL) { + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100); + } else if ( priv->speed == TLAN_SPEED_100 && + priv->duplex == TLAN_DUPLEX_HALF) { + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000); + } else if ( priv->speed == TLAN_SPEED_100 && + priv->duplex == TLAN_DUPLEX_FULL) { + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100); + } else { + + /* Set Auto-Neg advertisement */ + TLan_MiiWriteReg( dev, phy, MII_AN_ADV, (ability << 5) | 1); + /* Enablee Auto-Neg */ + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 ); + /* Restart Auto-Neg */ + TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 ); + /* Wait for 4 sec for autonegotiation + * to complete. The max spec time is less than this + * but the card need additional time to start AN. + * .5 sec should be plenty extra. + */ + printk( "TLAN: %s: Starting autonegotiation.\n", dev->name ); + TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_PHY_FINISH_AN ); + return; + } + + } + if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) { priv->phyNum = 0; data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data ); - TLan_SetTimer( dev, (4*(HZ/1000)), TLAN_TIMER_PHY_PDOWN ); + TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN ); return; - } else if ( priv->phyNum == 0 ) { + } else if ( priv->phyNum == 0 ) { TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl ); if ( priv->aui ) { tctl |= TLAN_TC_AUISEL; - } else { + } else { tctl &= ~TLAN_TC_AUISEL; control = 0; if ( priv->duplex == TLAN_DUPLEX_FULL ) { @@ -2260,10 +2381,10 @@ TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl ); } - /* Wait for 1 sec to give the tranceiver time + /* Wait for 2 sec to give the tranceiver time * to establish link. */ - TLan_SetTimer( dev, HZ, TLAN_TIMER_FINISH_RESET ); + TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_FINISH_RESET ); } /* TLan_PhyStartLink */ @@ -2306,14 +2427,14 @@ priv->phyNum = 0; data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN; TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data ); - TLan_SetTimer( dev, (400*(HZ/1000)), TLAN_TIMER_PHY_PDOWN ); + TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN ); return; } if ( priv->phyNum == 0 ) { if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) { TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX ); - printk( "TLAN: Starting internal PHY with DUPLEX\n" ); + printk( "TLAN: Starting internal PHY with FULL-DUPLEX\n" ); } else { TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB ); printk( "TLAN: Starting internal PHY with HALF-DUPLEX\n" ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tlan.h linux.ac/drivers/net/tlan.h --- linux.vanilla/drivers/net/tlan.h Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/tlan.h Mon May 29 20:29:39 2000 @@ -36,8 +36,8 @@ #define FALSE 0 #define TRUE 1 -#define TLAN_MIN_FRAME_SIZE 64 -#define TLAN_MAX_FRAME_SIZE 1600 +#define TLAN_MIN_FRAME_SIZE 60 +#define TLAN_MAX_FRAME_SIZE 1536 #define TLAN_NUM_RX_LISTS 4 #define TLAN_NUM_TX_LISTS 8 @@ -404,7 +404,11 @@ #define TLAN_TS_POLOK 0x2000 #define TLAN_TS_TPENERGY 0x1000 #define TLAN_TS_RESERVED 0x0FFF - +#define TLAN_TLPHY_PAR 0x19 +#define TLAN_PHY_CIM_STAT 0x0020 +#define TLAN_PHY_SPEED_100 0x0040 +#define TLAN_PHY_DUPLEX_FULL 0x0080 +#define TLAN_PHY_AN_EN_STAT 0x0400 #define CIRC_INC( a, b ) if ( ++a >= b ) a = 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tokenring/lanstreamer.c linux.ac/drivers/net/tokenring/lanstreamer.c --- linux.vanilla/drivers/net/tokenring/lanstreamer.c Thu May 25 17:37:53 2000 +++ linux.ac/drivers/net/tokenring/lanstreamer.c Fri May 26 14:36:51 2000 @@ -207,12 +207,14 @@ { while ((pci_device = pci_find_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, pci_device))) { + if (pci_enable_device(pci_device)) + continue; pci_set_master(pci_device); /* Check to see if io has been allocated, if so, we've already done this card, so continue on the card discovery loop */ - if (check_region(pci_device->resource[0].start & (~3), STREAMER_IO_SPACE)) + if (check_region(pci_resource_start(pci_device,0), STREAMER_IO_SPACE)) { card_no++; continue; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tokenring/olympic.c linux.ac/drivers/net/tokenring/olympic.c --- linux.vanilla/drivers/net/tokenring/olympic.c Thu May 25 17:37:52 2000 +++ linux.ac/drivers/net/tokenring/olympic.c Fri May 26 14:36:51 2000 @@ -170,12 +170,14 @@ while((pci_device=pci_find_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR_WAKE, pci_device))) { + if (pci_enable_device(pci_device)) + continue; pci_set_master(pci_device); /* Check to see if io has been allocated, if so, we've already done this card, so continue on the card discovery loop */ - if (check_region(pci_device->resource[0].start, OLYMPIC_IO_SPACE)) { + if (check_region(pci_resource_start(pci_device, 0), OLYMPIC_IO_SPACE)) { card_no++ ; continue ; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/wan/comx.c linux.ac/drivers/net/wan/comx.c --- linux.vanilla/drivers/net/wan/comx.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/wan/comx.c Thu May 25 20:47:55 2000 @@ -81,6 +81,10 @@ static struct comx_hardware *comx_channels = NULL; static struct comx_protocol *comx_lines = NULL; +static int comx_mkdir(struct inode *, struct dentry *, int); +static int comx_rmdir(struct inode *, struct dentry *); +static struct dentry *comx_lookup(struct inode *, struct dentry *); + static struct inode_operations comx_root_inode_ops = { lookup: comx_lookup, mkdir: comx_mkdir, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/wan/sdladrv.c linux.ac/drivers/net/wan/sdladrv.c --- linux.vanilla/drivers/net/wan/sdladrv.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/wan/sdladrv.c Fri May 26 14:36:51 2000 @@ -1983,8 +1983,9 @@ while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev)) != NULL) { - pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD, - &PCI_subsys_vendor); + if (pci_enable_device(pci_dev)) + continue; + PCI_subsys_vendor = pci_dev->subsystem_vendor; if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR) continue; hw->pci_dev = pci_dev; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/parport/BUGS-parport linux.ac/drivers/parport/BUGS-parport --- linux.vanilla/drivers/parport/BUGS-parport Thu May 25 17:38:20 2000 +++ linux.ac/drivers/parport/BUGS-parport Mon May 29 19:31:42 2000 @@ -1,5 +1,6 @@ Currently known (or at least suspected) bugs in parport: -o lp doesn't allow you to read status while printing is in progress. +o lp doesn't allow you to read status while printing is in progress (is + this still true?). -See . +See . diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/parport/ChangeLog linux.ac/drivers/parport/ChangeLog --- linux.vanilla/drivers/parport/ChangeLog Thu May 25 17:38:22 2000 +++ linux.ac/drivers/parport/ChangeLog Mon May 29 19:33:02 2000 @@ -1,3 +1,8 @@ +2000-05-28 Tim Waugh + + * daisy.c (assign_addrs): Avoid double-probing daisy-chain devices + if the first probe succeeds. + 2000-05-16 Tim Waugh * share.c (parport_claim): Fix SMP race. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/parport/TODO-parport linux.ac/drivers/parport/TODO-parport --- linux.vanilla/drivers/parport/TODO-parport Thu May 25 17:38:20 2000 +++ linux.ac/drivers/parport/TODO-parport Mon May 29 19:32:05 2000 @@ -17,4 +17,4 @@ 4. A better PLIP (make use of bidirectional/ECP/EPP ports). -See . +See . diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/parport/daisy.c linux.ac/drivers/parport/daisy.c --- linux.vanilla/drivers/parport/daisy.c Thu May 25 17:38:22 2000 +++ linux.ac/drivers/parport/daisy.c Mon May 29 19:33:02 2000 @@ -428,6 +428,7 @@ unsigned char s, last_dev; unsigned char daisy; int thisdev = numdevs; + int detected; char *deviceid; parport_data_forward (port); @@ -484,8 +485,9 @@ } parport_write_data (port, 0xff); udelay (2); + detected = numdevs - thisdev; DPRINTK (KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name, - numdevs - thisdev); + detected); /* Ask the new devices to introduce themselves. */ deviceid = kmalloc (1000, GFP_KERNEL); @@ -495,7 +497,7 @@ parport_device_id (thisdev, deviceid, 1000); kfree (deviceid); - return numdevs - thisdev; + return detected; } /* Find a device with a particular manufacturer and model string, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/parport/parport_pc.c linux.ac/drivers/parport/parport_pc.c --- linux.vanilla/drivers/parport/parport_pc.c Thu May 25 17:38:22 2000 +++ linux.ac/drivers/parport/parport_pc.c Mon May 29 19:34:15 2000 @@ -2430,8 +2430,9 @@ def.) */ /* TODO: test if sharing interrupts works */ printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, " - "I/O at %#lx(%#lx)\n", parport_pc_pci_tbl[i].vendor, - parport_pc_pci_tbl[i].device, io_lo, io_hi); + "I/O at %#lx(%#lx)\n", + parport_pc_pci_tbl[i + last_sio].vendor, + parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi); if (parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, dev)) count++; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/parport/share.c linux.ac/drivers/parport/share.c --- linux.vanilla/drivers/parport/share.c Thu May 25 17:38:22 2000 +++ linux.ac/drivers/parport/share.c Mon May 29 19:38:55 2000 @@ -87,12 +87,14 @@ { struct parport_driver *drv; + spin_lock (&driverlist_lock); for (drv = driver_chain; drv; drv = drv->next) { if (attach) drv->attach (port); else drv->detach (port); } + spin_unlock (&driverlist_lock); } /* Ask kmod for some lowlevel drivers. */ @@ -126,8 +128,12 @@ driver_chain = drv; spin_unlock (&driverlist_lock); + /* We have to take the portlist lock for this to be sure + * that port is valid for the duration of the callback. */ + spin_lock (&parportlist_lock); for (port = portlist; port; port = port->next) drv->attach (port); + spin_unlock (&parportlist_lock); if (!portlist) get_lowlevel_driver (); @@ -171,8 +177,10 @@ /* Call the driver's detach routine for each * port to clean up any resources that the * attach routine acquired. */ + spin_lock (&parportlist_lock); for (port = portlist; port; port = port->next) drv->detach (port); + spin_unlock (&parportlist_lock); return; } @@ -195,6 +203,8 @@ struct parport *parport_enumerate(void) { + /* Don't use this: use parport_register_driver instead. */ + if (!portlist) get_lowlevel_driver (); @@ -297,7 +307,18 @@ * This function must not run from an irq handler so we don' t need * to clear irq on the local CPU. -arca */ + spin_lock(&parportlist_lock); + + /* We are locked against anyone else performing alterations, but + * because of parport_enumerate people can still _read_ the list + * while we are changing it; so be careful.. + * + * It's okay to have portlist_tail a little bit out of sync + * since it's only used for changing the list, not for reading + * from it. + */ + if (portlist_tail) portlist_tail->next = tmp; portlist_tail = tmp; @@ -403,6 +424,10 @@ #endif spin_lock(&parportlist_lock); + + /* We are protected from other people changing the list, but + * they can see see it (using parport_enumerate). So be + * careful about the order of writes.. */ if (portlist == port) { if ((portlist = port->next) == NULL) portlist_tail = NULL; @@ -418,6 +443,7 @@ } spin_unlock(&parportlist_lock); + /* Yes, parport_enumerate _is_ unsafe. Don't use it. */ if (!port->devices) free_port (port); } @@ -565,6 +591,9 @@ } tmp->next = port->physport->devices; + wmb(); /* Make sure that tmp->next is written before it's + added to the list; see comments marked 'no locking + required' */ if (port->physport->devices) port->physport->devices->prev = tmp; port->physport->devices = tmp; @@ -647,6 +676,11 @@ * free up the resources. */ if (port->ops == &dead_ops && !port->devices) free_port (port); + + /* Yes, that's right, someone _could_ still have a pointer to + * port, if they used parport_enumerate. That's why they + * shouldn't use it (and use parport_register_driver instead).. + */ } /** @@ -702,7 +736,7 @@ dev->waiting = 0; /* Take ourselves out of the wait list again. */ - spin_lock_irqsave (&port->waitlist_lock, flags); + spin_lock_irq (&port->waitlist_lock); if (dev->waitprev) dev->waitprev->waitnext = dev->waitnext; else @@ -711,7 +745,7 @@ dev->waitnext->waitprev = dev->waitprev; else port->waittail = dev->waitprev; - spin_unlock_irqrestore (&port->waitlist_lock, flags); + spin_unlock_irq (&port->waitlist_lock); dev->waitprev = dev->waitnext = NULL; } @@ -878,7 +912,7 @@ } /* Nobody was waiting, so walk the list to see if anyone is - interested in being woken up. */ + interested in being woken up. (Note: no locking required) */ for (pd = port->devices; (port->cad == NULL) && pd; pd = pd->next) { if (pd->wakeup && pd != dev) pd->wakeup(pd->private); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/pci/pci.c linux.ac/drivers/pci/pci.c --- linux.vanilla/drivers/pci/pci.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/pci/pci.c Sat May 27 15:40:24 2000 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/pci/pci.ids linux.ac/drivers/pci/pci.ids --- linux.vanilla/drivers/pci/pci.ids Thu May 25 17:46:15 2000 +++ linux.ac/drivers/pci/pci.ids Sat May 27 15:40:24 2000 @@ -238,11 +238,12 @@ 100a Phoenix Technologies 100b National Semiconductor Corporation 0001 DP83810 - 0002 87415 + 0002 87415/87560 IDE + 000e 87560 Legacy I/O 000f OHCI Compliant FireWire Controller 0011 National PCI System I/O 0012 USB Controller - d001 87410 + d001 87410 IDE 100c Tseng Labs Inc 3202 ET4000/W32p rev A 3205 ET4000/W32p rev B diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/pci/quirks.c linux.ac/drivers/pci/quirks.c --- linux.vanilla/drivers/pci/quirks.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/pci/quirks.c Sat May 27 15:31:45 2000 @@ -138,7 +138,7 @@ * 0xE0 (64 bytes of ACPI registers) * 0xE2 (32 bytes of SMB registers) */ -static void __init quirk_ali7101(struct pci_dev *dev) +static void __init quirk_ali7101_acpi(struct pci_dev *dev) { u16 region; @@ -153,7 +153,7 @@ * 0x40 (64 bytes of ACPI registers) * 0x90 (32 bytes of SMB registers) */ -static void __init quirk_piix4acpi(struct pci_dev *dev) +static void __init quirk_piix4_acpi(struct pci_dev *dev) { u32 region; @@ -209,10 +209,10 @@ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, quirk_natoma }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4acpi }, - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101 }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4_acpi }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi }, { 0 } }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sbus/char/pcikbd.c linux.ac/drivers/sbus/char/pcikbd.c --- linux.vanilla/drivers/sbus/char/pcikbd.c Thu May 25 17:38:10 2000 +++ linux.ac/drivers/sbus/char/pcikbd.c Sat May 27 22:00:30 2000 @@ -737,8 +737,7 @@ spin_unlock_irqrestore(&pcikbd_lock, flags); - if (queue->fasync) - kill_fasync(queue->fasync, SIGIO, POLL_IN); + kill_fasync(&queue->fasync, SIGIO, POLL_IN); wake_up_interruptible(&queue->proc_list); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sbus/char/sunkbd.c linux.ac/drivers/sbus/char/sunkbd.c --- linux.vanilla/drivers/sbus/char/sunkbd.c Thu May 25 17:38:10 2000 +++ linux.ac/drivers/sbus/char/sunkbd.c Sat May 27 22:00:30 2000 @@ -1310,8 +1310,7 @@ } spin_unlock_irqrestore(&kbd_queue_lock, flags); - if (kb_fasync) - kill_fasync (kb_fasync, SIGIO, POLL_IN); + kill_fasync (&kb_fasync, SIGIO, POLL_IN); wake_up_interruptible (&kbd_wait); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sbus/char/sunmouse.c linux.ac/drivers/sbus/char/sunmouse.c --- linux.vanilla/drivers/sbus/char/sunmouse.c Thu May 25 17:38:10 2000 +++ linux.ac/drivers/sbus/char/sunmouse.c Sat May 27 22:00:30 2000 @@ -147,8 +147,7 @@ spin_unlock_irqrestore(&sunmouse.lock, flags); - if (sunmouse.fasync) - kill_fasync (sunmouse.fasync, SIGIO, POLL_IN); + kill_fasync (&sunmouse.fasync, SIGIO, POLL_IN); wake_up_interruptible (&sunmouse.proc_list); } @@ -382,8 +381,7 @@ /* We just completed a transaction, wake up whoever is awaiting * this event. */ - if (sunmouse.fasync) - kill_fasync (sunmouse.fasync, SIGIO, POLL_IN); + kill_fasync (&sunmouse.fasync, SIGIO, POLL_IN); wake_up_interruptible(&sunmouse.proc_list); } return; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/3w-xxxx.c linux.ac/drivers/scsi/3w-xxxx.c --- linux.vanilla/drivers/scsi/3w-xxxx.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/3w-xxxx.c Fri May 26 14:34:11 2000 @@ -565,6 +565,8 @@ dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n"); while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, TW_DEVICE_ID, tw_pci_dev))) { + if (pci_enable_device(tw_pci_dev)) + continue; /* Prepare temporary device extension */ tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC); if (tw_dev == NULL) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/AM53C974.c linux.ac/drivers/scsi/AM53C974.c --- linux.vanilla/drivers/scsi/AM53C974.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/AM53C974.c Fri May 26 14:34:11 2000 @@ -616,27 +616,23 @@ * * Returns : number of host adapters detected **************************************************************************/ -static __inline__ int AM53C974_pci_detect(Scsi_Host_Template * tpnt) +static inline int AM53C974_pci_detect(Scsi_Host_Template * tpnt) { int count = 0; /* number of boards detected */ struct pci_dev *pdev = NULL; unsigned short command; while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SCSI, pdev))) { + if (pci_enable_device(pdev)) + continue; pci_read_config_word(pdev, PCI_COMMAND, &command); /* check whether device is I/O mapped -- should be */ if (!(command & PCI_COMMAND_IO)) continue; - /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility - to set the PCI Master Enable Bit if needed. - (from Mark Stockton ) */ - if (!(command & PCI_COMMAND_MASTER)) { - command |= PCI_COMMAND_MASTER; - printk("PCI Master Bit has not been set. Setting...\n"); - pci_write_config_word(pdev, PCI_COMMAND, command); - } + pci_set_master (pdev); + /* everything seems OK now, so initialize */ if (AM53C974_init(tpnt, pdev)) count++; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/BusLogic.c linux.ac/drivers/scsi/BusLogic.c --- linux.vanilla/drivers/scsi/BusLogic.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/BusLogic.c Fri May 26 14:34:11 2000 @@ -775,6 +775,9 @@ unsigned long BaseAddress1 = PCI_Device->resource[1].start; BusLogic_IO_Address_T IO_Address = BaseAddress0; BusLogic_PCI_Address_T PCI_Address = BaseAddress1; + + if (pci_enable_device(PCI_Device)) + continue; if (!(PCI_Device->resource[0].flags & PCI_BASE_ADDRESS_SPACE_IO)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/NCR53C9x.c linux.ac/drivers/scsi/NCR53C9x.c --- linux.vanilla/drivers/scsi/NCR53C9x.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/NCR53C9x.c Sat May 27 16:02:11 2000 @@ -3578,7 +3578,7 @@ } #else /* For SMP we only service one ESP on the list list at our IRQ level! */ -static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs) +void esp_intr(int irq, void *dev_id, struct pt_regs *pregs) { struct NCR_ESP *esp; unsigned long flags; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/advansys.c linux.ac/drivers/scsi/advansys.c --- linux.vanilla/drivers/scsi/advansys.c Thu May 25 17:38:03 2000 +++ linux.ac/drivers/scsi/advansys.c Fri May 26 14:34:11 2000 @@ -4699,7 +4699,8 @@ NULL) { pci_device_id_cnt++; } else { - pci_devicep[pci_card_cnt_max++] = pci_devp; + if (pci_enable_device(pci_devp) == 0) + pci_devicep[pci_card_cnt_max++] = pci_devp; } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/aic7xxx.c linux.ac/drivers/scsi/aic7xxx.c --- linux.vanilla/drivers/scsi/aic7xxx.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/aic7xxx.c Fri May 26 14:34:11 2000 @@ -9551,14 +9551,15 @@ pdev = NULL; while ((pdev = pci_find_device(aic_pdevs[i].vendor_id, aic_pdevs[i].device_id, - pdev))) + pdev))) { + if (pci_enable_device(pdev)) + continue; #else index = 0; while (!(pcibios_find_device(aic_pdevs[i].vendor_id, aic_pdevs[i].device_id, - index++, &pci_bus, &pci_devfn)) ) + index++, &pci_bus, &pci_devfn)) ) { #endif - { if ( i == 0 ) /* We found one, but it's the 7810 RAID cont. */ { if (aic7xxx_verbose & (VERBOSE_PROBE|VERBOSE_PROBE2)) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/atp870u.c linux.ac/drivers/scsi/atp870u.c --- linux.vanilla/drivers/scsi/atp870u.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/atp870u.c Fri May 26 14:34:11 2000 @@ -1615,7 +1615,7 @@ h = 0; while (devid[h] != 0) { pdev[2] = pci_find_device(0x1191, devid[h], pdev[2]); - if (pdev[2] == NULL) { + if (pdev[2] == NULL || pci_enable_device(pdev[2])) { h++; index = 0; continue; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/dmx3191d.c linux.ac/drivers/scsi/dmx3191d.c --- linux.vanilla/drivers/scsi/dmx3191d.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/dmx3191d.c Fri May 26 14:34:11 2000 @@ -68,11 +68,10 @@ while ((pdev = pci_find_device(PCI_VENDOR_ID_DOMEX, PCI_DEVICE_ID_DOMEX_DMX3191D, pdev))) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13) - unsigned long port = pdev->base_address[0] & PCI_IOADDRESS_MASK; -#else - unsigned long port = pdev->resource[0].start; -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13) */ + unsigned long port = pci_resource_start (pdev, 0); + + if (pci_enable_device(pdev)) + continue; if (check_region(port, DMX3191D_REGION)) { dmx3191d_printk("region 0x%lx-0x%lx already reserved\n", diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/eata.c linux.ac/drivers/scsi/eata.c --- linux.vanilla/drivers/scsi/eata.c Thu May 25 17:38:03 2000 +++ linux.ac/drivers/scsi/eata.c Fri May 26 14:34:11 2000 @@ -829,7 +829,9 @@ if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break; - if (pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &addr)) continue; + addr = pci_resource_start (dev, 0); + + pci_enable_device (dev); /* XXX handle error */ #if defined(DEBUG_PCI_DETECT) printk("%s: tune_pci_port, bus %d, devfn 0x%x, addr 0x%x.\n", diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/eata_dma.c linux.ac/drivers/scsi/eata_dma.c --- linux.vanilla/drivers/scsi/eata_dma.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/eata_dma.c Fri May 26 14:34:11 2000 @@ -1388,13 +1388,15 @@ #ifndef CONFIG_PCI printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n"); #else - struct pci_dev *dev; + struct pci_dev *dev = NULL; u32 base, x; u8 pal1, pal2, pal3; - for(dev=NULL; dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev);) { + while ((dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) { DBG(DBG_PROBE && DBG_PCI, printk("eata_dma: find_PCI, HBA at %s\n", dev->name)); + if (pci_enable_device(dev)) + continue; pci_set_master(dev); base = dev->resource[0].flags; if (!(base & PCI_BASE_ADDRESS_SPACE_IO)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/eata_pio.c linux.ac/drivers/scsi/eata_pio.c --- linux.vanilla/drivers/scsi/eata_pio.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/eata_pio.c Fri May 26 14:34:11 2000 @@ -878,12 +878,14 @@ #ifndef CONFIG_PCI printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n"); #else - struct pci_dev *dev; + struct pci_dev *dev = NULL; u32 base, x; - for(dev=NULL; dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev);) { + while ((dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) { DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", dev->name)); + if (pci_enable_device(dev)) + continue; pci_set_master(dev); base = dev->resource[0].flags; if (!(base & PCI_BASE_ADDRESS_SPACE_IO)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/fdomain.c linux.ac/drivers/scsi/fdomain.c --- linux.vanilla/drivers/scsi/fdomain.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/fdomain.c Fri May 26 14:34:11 2000 @@ -828,6 +828,7 @@ PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) return 0; + if (pci_enable_device(pdev)) return 0; #if DEBUG_DETECT printk( "scsi: TMC-3260 detect:" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/gdth.c linux.ac/drivers/scsi/gdth.c --- linux.vanilla/drivers/scsi/gdth.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/gdth.c Fri May 26 14:34:11 2000 @@ -533,6 +533,8 @@ pdev = NULL; while ((pdev = pci_find_device(PCI_VENDOR_ID_VORTEX,device_id,pdev)) != NULL) { + if (pci_enable_device(pdev)) + continue; if (cnt >= MAXHA) return cnt; /* GDT PCI controller found, resources are already in pdev */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/ini9100u.c linux.ac/drivers/scsi/ini9100u.c --- linux.vanilla/drivers/scsi/ini9100u.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/ini9100u.c Fri May 26 14:34:11 2000 @@ -290,6 +290,8 @@ for (i = 0; i < TULSZ(i91u_pci_devices); i++) { while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) { + if (pci_enable_device(pDev)) + continue; pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue); wBIOS = (UWORD) (dRegValue & 0xFF); if (((dRegValue & 0xFF00) >> 8) == 0xFF) @@ -377,8 +379,6 @@ pHCB->pSRB_head = NULL; /* Initial SRB save queue */ pHCB->pSRB_tail = NULL; /* Initial SRB save queue */ pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED; /* SRB save queue lock */ - request_region(pHCB->HCS_Base, 0x100, "i91u"); /* Register */ - get_tulipPCIConfig(pHCB, i); dBiosAdr = pHCB->HCS_BIOS; @@ -387,6 +387,8 @@ pbBiosAdr = phys_to_virt(dBiosAdr); init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10); + request_region(pHCB->HCS_Base, 256, "i91u"); /* Register */ + pHCB->HCS_Index = i; /* 7/29/98 */ hreg = scsi_register(tpnt, sizeof(HCS)); hreg->io_port = pHCB->HCS_Base; @@ -812,4 +814,14 @@ { printk("\ni91u_panic: %s\n", msg); panic("i91u panic"); +} + +/* + * Release ressources + */ +int i91u_release(struct Scsi_Host *hreg) +{ + free_irq(hreg->irq, hreg); + release_region(hreg->io_port, 256); + return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/ini9100u.h linux.ac/drivers/scsi/ini9100u.h --- linux.vanilla/drivers/scsi/ini9100u.h Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/ini9100u.h Mon May 29 20:35:55 2000 @@ -78,6 +78,7 @@ #include "sd.h" extern int i91u_detect(Scsi_Host_Template *); +extern int i91u_release(struct Scsi_Host *); extern int i91u_command(Scsi_Cmnd *); extern int i91u_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); extern int i91u_abort(Scsi_Cmnd *); @@ -93,7 +94,7 @@ proc_info: NULL, \ name: i91u_REVID, \ detect: i91u_detect, \ - release: NULL, \ + release: i91u_release, \ info: NULL, \ command: i91u_command, \ queuecommand: i91u_queue, \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/inia100.c linux.ac/drivers/scsi/inia100.c --- linux.vanilla/drivers/scsi/inia100.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/inia100.c Fri May 26 14:34:11 2000 @@ -247,6 +247,8 @@ inia100_pci_devices[i].device_id, pdev))) { + if (pci_enable_device(pdev)) + continue; if (iAdapters >= MAX_SUPPORTED_ADAPTERS) break; /* Never greater than maximum */ @@ -261,24 +263,23 @@ */ bPCIBusNum = pdev->bus->number; bPCIDeviceNum = pdev->devfn; - dRegValue = pdev->resource[0].start; + dRegValue = pci_resource_start(pdev, 0); if (dRegValue == -1) { /* Check return code */ printk("\n\rinia100: orchid read configuration error.\n"); return (0); /* Read configuration space error */ } + /* <02> read from base address + 0x50 offset to get the wBIOS balue. */ wBASE = (WORD) dRegValue; - /* Now read the interrupt line */ + /* Now read the interrupt line value */ dRegValue = pdev->irq; - bInterrupt = dRegValue & 0xFF; /* Assign interrupt line */ - pci_read_config_word(pdev, PCI_COMMAND, &command); - pci_write_config_word(pdev, PCI_COMMAND, - command | PCI_COMMAND_MASTER | PCI_COMMAND_IO); + bInterrupt = dRegValue; /* Assign interrupt line */ - wBASE &= PCI_BASE_ADDRESS_IO_MASK; wBIOS = ORC_RDWORD(wBASE, 0x50); + pci_set_master(pdev); + #ifdef MMAPIO base = wBASE & PAGE_MASK; page_offset = wBASE - base; @@ -370,7 +371,6 @@ memset((unsigned char *) pHCB->HCS_virEscbArray, 0, sz); pHCB->HCS_physEscbArray = (U32) VIRT_TO_BUS(pHCB->HCS_virEscbArray); - request_region(pHCB->HCS_Base, 0x100, "inia100"); /* Register */ get_orcPCIConfig(pHCB, i); dBiosAdr = pHCB->HCS_BIOS; @@ -382,6 +382,8 @@ printk("inia100: initial orchid fail!!\n"); return (0); } + request_region(pHCB->HCS_Base, 256, "inia100"); /* Register */ + hreg = scsi_register(tpnt, sizeof(ORC_HCS)); if (hreg == NULL) { printk("Invalid scsi_register pointer.\n"); @@ -411,28 +413,28 @@ /* Initial orc chip */ switch (i) { case 0: - ok = request_irq(pHCB->HCS_Intr, inia100_intr0, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + ok = request_irq(pHCB->HCS_Intr, inia100_intr0, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg); break; case 1: - ok = request_irq(pHCB->HCS_Intr, inia100_intr1, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + ok = request_irq(pHCB->HCS_Intr, inia100_intr1, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg); break; case 2: - ok = request_irq(pHCB->HCS_Intr, inia100_intr2, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + ok = request_irq(pHCB->HCS_Intr, inia100_intr2, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg); break; case 3: - ok = request_irq(pHCB->HCS_Intr, inia100_intr3, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + ok = request_irq(pHCB->HCS_Intr, inia100_intr3, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg); break; case 4: - ok = request_irq(pHCB->HCS_Intr, inia100_intr4, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + ok = request_irq(pHCB->HCS_Intr, inia100_intr4, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg); break; case 5: - ok = request_irq(pHCB->HCS_Intr, inia100_intr5, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + ok = request_irq(pHCB->HCS_Intr, inia100_intr5, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg); break; case 6: - ok = request_irq(pHCB->HCS_Intr, inia100_intr6, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + ok = request_irq(pHCB->HCS_Intr, inia100_intr6, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg); break; case 7: - ok = request_irq(pHCB->HCS_Intr, inia100_intr7, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); + ok = request_irq(pHCB->HCS_Intr, inia100_intr7, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg); break; default: inia100_panic("inia100: Too many host adapters\n"); @@ -784,5 +786,15 @@ printk("\ninia100_panic: %s\n", msg); panic("inia100 panic"); } + +/* + * Release ressources + */ +int inia100_release(struct Scsi_Host *hreg) +{ + free_irq(hreg->irq, hreg); + release_region(hreg->io_port, 256); + return 0; +} /*#include "inia100scsi.c" */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/inia100.h linux.ac/drivers/scsi/inia100.h --- linux.vanilla/drivers/scsi/inia100.h Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/inia100.h Mon May 29 20:35:55 2000 @@ -71,6 +71,7 @@ #include "sd.h" extern int inia100_detect(Scsi_Host_Template *); +extern int inia100_release(struct Scsi_Host *); extern int inia100_command(Scsi_Cmnd *); extern int inia100_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); extern int inia100_abort(Scsi_Cmnd *); @@ -87,7 +88,7 @@ proc_info: NULL, \ name: inia100_REVID, \ detect: inia100_detect, \ - release: NULL, \ + release: inia100_release, \ info: NULL, \ command: inia100_command, \ queuecommand: inia100_queue, \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/ips.c linux.ac/drivers/scsi/ips.c --- linux.vanilla/drivers/scsi/ips.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/ips.c Fri May 26 14:34:11 2000 @@ -325,7 +325,8 @@ if (!(dev = pci_find_device(IPS_VENDORID, IPS_DEVICEID, dev))) break; - + if (pci_enable_device(dev)) + break; /* stuff that we get in dev */ irq = dev->irq; bus = dev->bus->number; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/megaraid.c linux.ac/drivers/scsi/megaraid.c --- linux.vanilla/drivers/scsi/megaraid.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/megaraid.c Fri May 26 14:34:11 2000 @@ -1478,6 +1478,8 @@ struct pci_dev *pdev = NULL; while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) { + if (pci_enable_device(pdev)) + continue; if ((flag & BOARD_QUARTZ) && (skip_id == -1)) { u16 magic; pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic); @@ -1505,18 +1507,13 @@ } /* Read the base port and IRQ from PCI */ - megaBase = pdev->resource[0].start; + megaBase = pci_resource_start (pdev, 0); megaIrq = pdev->irq; - if (flag & BOARD_QUARTZ) { - - megaBase &= PCI_BASE_ADDRESS_MEM_MASK; + if (flag & BOARD_QUARTZ) megaBase = (long) ioremap (megaBase, 128); - } - else { - megaBase &= PCI_BASE_ADDRESS_IO_MASK; + else megaBase += 0x10; - } /* Initialize SCSI Host structure */ host = scsi_register (pHostTmpl, sizeof (mega_host_config)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/pci2000.c linux.ac/drivers/scsi/pci2000.c --- linux.vanilla/drivers/scsi/pci2000.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/pci2000.c Fri May 26 14:34:11 2000 @@ -679,10 +679,12 @@ while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_ROY_1, pdev)) != NULL ) { + if (pci_enable_device(pdev)) + continue; pshost = scsi_register (tpnt, sizeof(ADAPTER2000)); padapter = HOSTDATA(pshost); - padapter->basePort = pdev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; + padapter->basePort = pci_resource_start (pdev, 1); DEB (printk ("\nBase Regs = %#04X", padapter->basePort)); // get the base I/O port address padapter->mb0 = padapter->basePort + RTR_MAILBOX; // get the 32 bit mail boxes padapter->mb1 = padapter->basePort + RTR_MAILBOX + 4; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/pci2220i.c linux.ac/drivers/scsi/pci2220i.c --- linux.vanilla/drivers/scsi/pci2220i.c Thu May 25 17:38:05 2000 +++ linux.ac/drivers/scsi/pci2220i.c Fri May 26 14:34:11 2000 @@ -2386,8 +2386,8 @@ memset (&DaleSetup, 0, sizeof (DaleSetup)); memset (DiskMirror, 0, sizeof (DiskMirror)); - zr = pcidev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; - zl = pcidev->resource[2].start & PCI_BASE_ADDRESS_IO_MASK; + zr = pci_resource_start (pcidev, 1); + zl = pci_resource_start (pcidev, 2); padapter->basePort = zr; padapter->regRemap = zr + RTR_LOCAL_REMAP; // 32 bit local space remap @@ -2542,6 +2542,8 @@ while ( (pcidev = pci_find_device (VENDOR_PSI, DEVICE_DALE_1, pcidev)) != NULL ) { + if (pci_enable_device(pcidev)) + continue; pshost = scsi_register (tpnt, sizeof(ADAPTER2220I)); padapter = HOSTDATA(pshost); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/qla1280.c linux.ac/drivers/scsi/qla1280.c --- linux.vanilla/drivers/scsi/qla1280.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/qla1280.c Fri May 26 14:34:12 2000 @@ -801,13 +801,13 @@ for( i=0; bdp->device_id != 0 && i < NUM_OF_ISP_DEVICES; i++, bdp++ ) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) while ((pdev = pci_find_device(QLA1280_VENDOR_ID, - bdp->device_id, pdev ) )) + bdp->device_id, pdev ) )) { + if (pci_enable_device(pdev)) continue; #else while (!(pcibios_find_device(QLA1280_VENDOR_ID, bdp->device_id, - index++, &pci_bus, &pci_devfn)) ) + index++, &pci_bus, &pci_devfn)) ) { #endif - { /* found a adapter */ host = scsi_register(template, sizeof(scsi_qla_host_t)); ha = (scsi_qla_host_t *) host->hostdata; @@ -817,9 +817,7 @@ /* Sanitize the information from PCI BIOS. */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) host->irq = pdev->irq; -/* this depends on release 2.3.18 */ - host->io_port = pdev->resource[0].start; -/* MRS host->io_port = (unsigned int) pdev->base_address[0]; */ + host->io_port = pci_resource_start(pdev, 0); ha->pci_bus = pdev->bus->number; ha->pci_device_fn = pdev->devfn; ha->pdev = pdev; @@ -828,14 +826,13 @@ pcibios_read_config_dword(pci_bus, pci_devfn, OFFSET(cfgp->base_port), &piobase); host->irq = pci_irq; host->io_port = (unsigned int) piobase; + host->io_port &= PCI_BASE_ADDRESS_IO_MASK; ha->pci_bus = pci_bus; ha->pci_device_fn = pci_devfn; #endif ha->device_id = bdp->device_id; - host->io_port &= PCI_BASE_ADDRESS_IO_MASK; ha->devnum = i; - host->io_port &= PCI_BASE_ADDRESS_IO_MASK; if( qla1280_mem_alloc(ha) ) { printk(KERN_INFO "qla1280: Failed to allocate memory for adapter\n"); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/qlogicfc.c linux.ac/drivers/scsi/qlogicfc.c --- linux.vanilla/drivers/scsi/qlogicfc.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/qlogicfc.c Fri May 26 14:34:12 2000 @@ -746,6 +746,8 @@ for (i=0; i<2; i++){ while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, device_ids[i], pdev))) { + if (pci_enable_device(pdev)) + continue; host = scsi_register(tmpt, sizeof(struct isp2x00_hostdata)); host->max_id = QLOGICFC_MAX_ID + 1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/qlogicisp.c linux.ac/drivers/scsi/qlogicisp.c --- linux.vanilla/drivers/scsi/qlogicisp.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/qlogicisp.c Fri May 26 14:34:12 2000 @@ -678,6 +678,9 @@ while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020, pdev))) { + if (pci_enable_device(pdev)) + continue; + host = scsi_register(tmpt, sizeof(struct isp1020_hostdata)); hostdata = (struct isp1020_hostdata *) host->hostdata; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/scsi_scan.c linux.ac/drivers/scsi/scsi_scan.c --- linux.vanilla/drivers/scsi/scsi_scan.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/scsi/scsi_scan.c Mon May 29 19:40:47 2000 @@ -38,7 +38,6 @@ #define BLIST_MAX5LUN 0x080 #define BLIST_ISDISK 0x100 #define BLIST_ISROM 0x200 -#define BLIST_GHOST 0x400 static void print_inquiry(unsigned char *data); static int scan_scsis_single(int channel, int dev, int lun, int *max_scsi_dev, @@ -137,13 +136,7 @@ {"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, {"MATSHITA", "PD-1", "*", BLIST_FORCELUN | BLIST_SINGLELUN}, {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, - {"CREATIVE","DVD-RAM RAM","*", BLIST_GHOST}, - {"MATSHITA","PD-2 LF-D100","*", BLIST_GHOST}, - {"AOpen", "PD-2 DVD-520S", "*", BLIST_GHOST}, - {"HITACHI", "GF-1050","*", BLIST_GHOST}, /* Hitachi SCSI DVD-RAM */ {"TOSHIBA","CDROM","*", BLIST_ISROM}, - {"TOSHIBA","DVD-RAM SD-W1101","*", BLIST_GHOST}, - {"TOSHIBA","DVD-RAM SD-W1111","*", BLIST_GHOST}, {"MegaRAID", "LD", "*", BLIST_FORCELUN}, /* @@ -468,8 +461,6 @@ Scsi_Device *SDtail, *SDpnt = *SDpnt2; Scsi_Request * SRpnt; int bflags, type = -1; - static int ghost_channel=-1, ghost_dev=-1; - int org_lun = lun; extern devfs_handle_t scsi_devfs_handle; SDpnt->host = shpnt; @@ -480,13 +471,6 @@ scsi_build_commandblocks(SDpnt); - if ((channel == ghost_channel) && (dev == ghost_dev) && (lun == 1)) { - SDpnt->lun = 0; - } else { - ghost_channel = ghost_dev = -1; - } - - /* Some low level driver could use device->type (DB) */ SDpnt->type = -1; @@ -499,39 +483,14 @@ SDpnt->expecting_cc_ua = 0; SDpnt->starved = 0; - scsi_cmd[0] = TEST_UNIT_READY; - scsi_cmd[1] = lun << 5; - scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = 0; - SRpnt = scsi_allocate_request(SDpnt); - SRpnt->sr_data_direction = SCSI_DATA_NONE; - - scsi_wait_req (SRpnt, (void *) scsi_cmd, - (void *) NULL, - 0, SCSI_TIMEOUT + 4 * HZ, 5); - - SCSI_LOG_SCAN_BUS(3, printk("scsi: scan_scsis_single id %d lun %d. Return code 0x%08x\n", - dev, lun, SRpnt->sr_result)); - SCSI_LOG_SCAN_BUS(3, print_driverbyte(SRpnt->sr_result)); - SCSI_LOG_SCAN_BUS(3, print_hostbyte(SRpnt->sr_result)); - SCSI_LOG_SCAN_BUS(3, printk("\n")); + /* + * We used to do a TEST_UNIT_READY before the INQUIRY but that was + * not really necessary. Spec recommends using INQUIRY to scan for + * devices (and TEST_UNIT_READY to poll for media change). - Paul G. + */ - if (SRpnt->sr_result) { - if (((driver_byte(SRpnt->sr_result) & DRIVER_SENSE) || - (status_byte(SRpnt->sr_result) & CHECK_CONDITION)) && - ((SRpnt->sr_sense_buffer[0] & 0x70) >> 4) == 7) { - if (((SRpnt->sr_sense_buffer[2] & 0xf) != NOT_READY) && - ((SRpnt->sr_sense_buffer[2] & 0xf) != UNIT_ATTENTION) && - ((SRpnt->sr_sense_buffer[2] & 0xf) != ILLEGAL_REQUEST || lun > 0)) { - scsi_release_request(SRpnt); - return 1; - } - } else { - scsi_release_request(SRpnt); - return 0; - } - } SCSI_LOG_SCAN_BUS(3, printk("scsi: performing INQUIRY\n")); /* * Build an INQUIRY command block. @@ -588,18 +547,6 @@ scsi_result[1] |= 0x80; /* removable */ } - if (bflags & BLIST_GHOST) { - if ((ghost_channel == channel) && (ghost_dev == dev) && (org_lun == 1)) { - lun=1; - } else { - ghost_channel = channel; - ghost_dev = dev; - scsi_result[0] = TYPE_MOD; - scsi_result[1] |= 0x80; /* removable */ - } - } - - memcpy(SDpnt->vendor, scsi_result + 8, 8); memcpy(SDpnt->model, scsi_result + 16, 16); memcpy(SDpnt->rev, scsi_result + 32, 4); @@ -808,19 +755,9 @@ } /* - * If this device is Ghosted, scan upto two luns. (It physically only - * has one). -- REW - */ - if (bflags & BLIST_GHOST) { - *max_dev_lun = 2; - return 1; - } - - - /* - * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI - * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1 - * (ANSI SCSI Revision 1) and Response Data Format 0 + * We assume the device can't handle lun!=0 if: - it reports scsi-0 + * (ANSI SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it + * reports scsi-1 (ANSI SCSI Revision 1) and Response Data Format 0 */ if (((scsi_result[2] & 0x07) == 0) || diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/sg.c linux.ac/drivers/scsi/sg.c --- linux.vanilla/drivers/scsi/sg.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/sg.c Sat May 27 22:00:30 2000 @@ -1052,8 +1052,7 @@ if (sfp && srp) { /* Now wake up any sg_read() that is waiting for this packet. */ wake_up_interruptible(&sfp->read_wait); - if (sfp->async_qp) - kill_fasync(sfp->async_qp, SIGPOLL, POLL_IN); + kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); } } @@ -2429,8 +2428,7 @@ *eof = infofp(buffer, &len, &begin, offset, size); \ if (offset >= (begin + len)) \ return 0; \ - *start = buffer + ((begin > offset) ? \ - (begin - offset) : (offset - begin)); \ + *start = buffer + offset - begin; \ return (size < (begin + len - offset)) ? \ size : begin + len - offset; \ } while(0) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/sr.c linux.ac/drivers/scsi/sr.c --- linux.vanilla/drivers/scsi/sr.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/sr.c Thu May 25 20:32:58 2000 @@ -25,6 +25,9 @@ * * Modified by Richard Gooch to support devfs * + * Modified by Jens Axboe - support DVD-RAM + * transparently and loose the GHOST hack + * */ #include @@ -297,9 +300,10 @@ else printk("sr: can't switch blocksize: in interrupt\n"); } - if (SCpnt->request.cmd == WRITE) { + + if ((SCpnt->request.cmd == WRITE) && !scsi_CDs[dev].device->writeable) return 0; - } + if (scsi_CDs[dev].device->sector_size == 1024) { if ((block & 1) || (SCpnt->request.nr_sectors & 1)) { printk("sr.c:Bad 1K block number requested (%d %ld)", @@ -322,9 +326,6 @@ } switch (SCpnt->request.cmd) { case WRITE: - if (!scsi_CDs[dev].device->writeable) { - return 0; - } SCpnt->cmnd[0] = WRITE_10; SCpnt->sc_data_direction = SCSI_DATA_WRITE; break; @@ -591,6 +592,7 @@ ((buffer[n + 14] << 8) + buffer[n + 15]) / 176, scsi_CDs[i].cdi.speed, buffer[n + 3] & 0x01 ? "writer " : "", /* CD Writer */ + buffer[n + 3] & 0x20 ? "dvd-ram " : "", buffer[n + 2] & 0x02 ? "cd/rw " : "", /* can read rewriteable */ buffer[n + 4] & 0x20 ? "xa/form2 " : "", /* can read xa/from2 */ buffer[n + 5] & 0x01 ? "cdda " : "", /* can read audio data */ @@ -601,9 +603,12 @@ if ((buffer[n + 2] & 0x8) == 0) /* not a DVD drive */ scsi_CDs[i].cdi.mask |= CDC_DVD; - if ((buffer[n + 3] & 0x20) == 0) + if ((buffer[n + 3] & 0x20) == 0) { /* can't write DVD-RAM media */ scsi_CDs[i].cdi.mask |= CDC_DVD_RAM; + } else { + scsi_CDs[i].device->writeable = 1; + } if ((buffer[n + 3] & 0x10) == 0) /* can't write DVD-R media */ scsi_CDs[i].cdi.mask |= CDC_DVD_R; @@ -626,7 +631,6 @@ scsi_CDs[i].cdi.mask |= CDC_SELECT_DISC; /*else I don't think it can close its tray scsi_CDs[i].cdi.mask |= CDC_CLOSE_TRAY; */ - scsi_free(buffer, 512); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/tmscsim.c linux.ac/drivers/scsi/tmscsim.c --- linux.vanilla/drivers/scsi/tmscsim.c Thu May 25 17:38:05 2000 +++ linux.ac/drivers/scsi/tmscsim.c Fri May 26 14:34:12 2000 @@ -2002,6 +2002,8 @@ if ( PCI_PRESENT ) while (PCI_FIND_DEVICE (PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974)) { + if (pci_enable_device(pdev)) + continue; DC390_LOCK_IO; /* Remove this when going to new eh */ PCI_GET_IO_AND_IRQ; DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq);) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sgi/char/shmiq.c linux.ac/drivers/sgi/char/shmiq.c --- linux.vanilla/drivers/sgi/char/shmiq.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/sgi/char/shmiq.c Sat May 27 22:00:30 2000 @@ -118,8 +118,7 @@ e->data.device, e->data.which, e->data.type, e->data.flags); s->tail = tail_next; shmiqs [device].tail = tail_next; - if (shmiqs [device].fasync) - kill_fasync (shmiqs [device].fasync, SIGIO, POLL_IN); + kill_fasync (&shmiqs [device].fasync, SIGIO, POLL_IN); wake_up_interruptible (&shmiqs [device].proc_list); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/Config.in linux.ac/drivers/sound/Config.in --- linux.vanilla/drivers/sound/Config.in Thu May 25 17:38:07 2000 +++ linux.ac/drivers/sound/Config.in Sat May 27 22:02:57 2000 @@ -79,7 +79,7 @@ int 'MSND buffer size (kB)' CONFIG_MSND_FIFOSIZE 128 fi -tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX +dep_tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_PCI dep_tristate ' OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/ac97_codec.c linux.ac/drivers/sound/ac97_codec.c --- linux.vanilla/drivers/sound/ac97_codec.c Thu May 25 17:38:08 2000 +++ linux.ac/drivers/sound/ac97_codec.c Fri May 26 14:17:12 2000 @@ -21,7 +21,7 @@ * * History * v0.4 Mar 15 2000 Ollie Lho - * dual codec support verified with 4 channel output + * dual codecs support verified with 4 channels output * v0.3 Feb 22 2000 Ollie Lho * bug fix for record mask setting * v0.2 Feb 10 2000 Ollie Lho @@ -332,9 +332,10 @@ /* else, write the first set in the mask as the output */ /* clear out current set value first (AC97 supports only 1 input!) */ - val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT)&0x07]); - if (mask != val) mask &= ~val; - + val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT) & 0x07]); + if (mask != val) + mask &= ~val; + val = ffs(mask); val = ac97_oss_rm[val-1]; val |= val << 8; /* set both channels */ @@ -423,7 +424,7 @@ switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ if (!codec->recmask_io) return -EINVAL; - if(!val) return 0; + if (!val) return 0; if (!(val &= codec->record_sources)) return -EINVAL; codec->recmask_io(codec, 0, val); @@ -449,6 +450,7 @@ { int len = 0, cap, extid, val, id1, id2; struct ac97_codec *codec; + int is_ac97_20 = 0; if ((codec = data) == NULL) return -ENODEV; @@ -462,6 +464,7 @@ extid &= ~((1<<2)|(1<<4)|(1<<5)|(1<<10)|(1<<11)|(1<<12)|(1<<13)); len += sprintf (page+len, "AC97 Version : %s\n", extid ? "2.0 or later" : "1.0"); + if (extid) is_ac97_20 = 1; cap = codec->codec_read(codec, AC97_RESET); len += sprintf (page+len, "Capabilities :%s%s%s%s%s%s\n", @@ -500,6 +503,7 @@ val & 0x0100 ? "MIC2" : "MIC1", val & 0x0080 ? "on" : "off"); + extid = codec->codec_read(codec, AC97_EXTENDED_ID); cap = extid; len += sprintf (page+len, "Ext Capabilities :%s%s%s%s%s%s%s\n", cap & 0x0001 ? " -var rate PCM audio-" : "", @@ -509,6 +513,10 @@ cap & 0x0080 ? " -PCM surround DAC-" : "", cap & 0x0100 ? " -PCM LFE DAC-" : "", cap & 0x0200 ? " -slot/DAC mappings-" : ""); + if (is_ac97_20) { + len += sprintf (page+len, "Front DAC rate : %d\n", + codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE)); + } return len; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/cmpci.c linux.ac/drivers/sound/cmpci.c --- linux.vanilla/drivers/sound/cmpci.c Thu May 25 17:38:08 2000 +++ linux.ac/drivers/sound/cmpci.c Sat May 27 15:28:10 2000 @@ -2321,6 +2321,8 @@ (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)) || (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, pcidev)) || (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) { + if (pci_enable_device(pcidev)) + continue; if (pcidev->irq == 0) continue; if (!(s = kmalloc(sizeof(struct cm_state), GFP_KERNEL))) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/i810_audio.c linux.ac/drivers/sound/i810_audio.c --- linux.vanilla/drivers/sound/i810_audio.c Thu May 25 17:38:08 2000 +++ linux.ac/drivers/sound/i810_audio.c Fri May 26 15:21:27 2000 @@ -414,8 +414,8 @@ i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100); /* Load the rate and read the effective rate */ - i810_ac97_set(codec, AC97_PCM_LR_ADC_RATE, rate); - rp=i810_ac97_get(codec, AC97_PCM_LR_ADC_RATE); + i810_ac97_set(codec, AC97_PCM_LR_DAC_RATE, rate); + rp=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE); printk("ADC rate set to %d Returned %d\n", rate, (int)rp); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/maestro.c linux.ac/drivers/sound/maestro.c --- linux.vanilla/drivers/sound/maestro.c Thu May 25 17:38:08 2000 +++ linux.ac/drivers/sound/maestro.c Sat May 27 15:44:24 2000 @@ -3447,11 +3447,7 @@ return 1; } -#ifdef MODULE -int init_module(void) -#else -int SILLY_MAKE_INIT(init_maestro(void)) -#endif +int __init init_maestro(void) { struct pci_dev *pcidev = NULL; int foundone = 0; @@ -3558,8 +3554,6 @@ nuke_maestros(); } -#else /* MODULE */ -__initcall(init_maestro); #endif /* --------------------------------------------------------------------- */ @@ -3718,3 +3712,5 @@ out: return 0; } + +module_init(init_maestro); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/sb_card.c linux.ac/drivers/sound/sb_card.c --- linux.vanilla/drivers/sound/sb_card.c Thu May 25 17:38:07 2000 +++ linux.ac/drivers/sound/sb_card.c Fri May 26 14:30:20 2000 @@ -265,6 +265,11 @@ 0,0,0,0, 0,1,1,-1}, {"Sound Blaster 16", + ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0028), + ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), + 0,0,0,0, + 0,1,1,-1}, + {"Sound Blaster 16", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0,0,0,0, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/skeleton.c linux.ac/drivers/sound/skeleton.c --- linux.vanilla/drivers/sound/skeleton.c Thu May 25 17:38:08 2000 +++ linux.ac/drivers/sound/skeleton.c Sat May 27 15:25:29 2000 @@ -78,9 +78,9 @@ * For the example we will only initialise the MSS */ - iobase = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; - mssbase = pcidev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK; - mpubase = pcidev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK; + iobase = pci_resource_start(pcidev, 0); + mssbase = pci_resource_start(pcidev, 1); + mpubase = pci_resource_start(pcidev, 2); /* * Reset the board @@ -160,6 +160,8 @@ while((pcidev = pci_find_device(PCI_VENDOR_MYIDENT, PCI_DEVICE_ID_MYIDENT_MYCARD1, pcidev))!=NULL) { + if (pci_enable_device(pcidev)) + continue; count+=mycard_install(pcidev); if(count) return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/trident.c linux.ac/drivers/sound/trident.c --- linux.vanilla/drivers/sound/trident.c Thu May 25 17:38:08 2000 +++ linux.ac/drivers/sound/trident.c Fri May 26 14:17:12 2000 @@ -29,10 +29,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * History - * v0.14.3 May 20 2000 Aaron Holtzman - * Fix kfree'd memory access in release - * Fix race in open while looking for a free virtual channel slot - * remove open_wait wq (which appears to be unused) + * v0.14.5 May 23 2000 Ollie Lho + * Misc bug fix from the Net + * v0.14.4 May 20 2000 Aaron Holtzman + * Fix kfree'd memory access in release + * Fix race in open while looking for a free virtual channel slot + * remove open_wait wq (which appears to be unused) + * v0.14.3 May 10 2000 Ollie Lho + * fixed a small bug in trident_update_ptr, xmms 1.0.1 no longer uses 100% CPU * v0.14.2 Mar 29 2000 Ching Ling Lee * Add clear to silence advance in trident_update_ptr * fix invalid data of the end of the sound @@ -109,13 +113,13 @@ #include "trident.h" -#define DRIVER_VERSION "0.14" +#define DRIVER_VERSION "0.14.5" /* magic numbers to protect our data structures */ #define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */ #define TRIDENT_STATE_MAGIC 0x63657373 /* "cess" */ -#define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */ +#define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */ #define NR_HW_CH 32 @@ -151,7 +155,7 @@ "ALi Audio Accelerator" }; -static struct pci_device_id trident_pci_tbl [] __initdata = { +static struct pci_device_id trident_pci_tbl [] __devinitdata = { {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_DX}, {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX, @@ -438,16 +442,14 @@ #endif } -static u32 trident_get_interrupt_mask (struct trident_card * card, - unsigned int b) +static u32 trident_get_interrupt_mask (struct trident_card * card, unsigned int channel) { - struct trident_pcm_bank *bank = &card->banks[b]; + struct trident_pcm_bank *bank = &card->banks[channel]; u32 addr = bank->addresses->aint; return inl(TRID_REG(card, addr)); } -static int trident_check_channel_interrupt(struct trident_card * card, - unsigned int channel) +static int trident_check_channel_interrupt(struct trident_card * card, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); u32 reg = trident_get_interrupt_mask (card, channel >> 5); @@ -460,8 +462,7 @@ return (reg & mask) ? TRUE : FALSE; } -static void trident_ack_channel_interrupt(struct trident_card * card, - unsigned int channel) +static void trident_ack_channel_interrupt(struct trident_card * card, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); struct trident_pcm_bank *bank = &card->banks[channel >> 5]; @@ -537,8 +538,7 @@ } -static void trident_free_pcm_channel(struct trident_card *card, - unsigned int channel) +static void trident_free_pcm_channel(struct trident_card *card, int channel) { int bank; @@ -551,7 +551,7 @@ card->banks[bank].bitmap &= ~(1 << (channel)); } -static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel) +static void ali_free_pcm_channel(struct trident_card *card, int channel) { int bank; @@ -574,18 +574,16 @@ if (channel > 63) return FALSE; - /* select hardware channel to write */ + /* select hardware channel to write */ outb(channel, TRID_REG(card, T4D_LFO_GC_CIR)); /* Output the channel registers, but don't write register three to an ALI chip. */ - for (i = 0; i < CHANNEL_REGS; i++) { if (i == 3 && card->pci_id == PCI_DEVICE_ID_ALI_5451) continue; outl(data[i], TRID_REG(card, CHANNEL_START + 4*i)); } - return TRUE; } @@ -1141,7 +1139,7 @@ dmabuf->hwptr = hwptr; dmabuf->total_bytes += diff; - /* error handling and process wake up for DAC */ + /* error handling and process wake up for ADC */ if (dmabuf->enable == ADC_RUNNING) { if (dmabuf->mapped) { dmabuf->count -= diff; @@ -1171,7 +1169,10 @@ //there is invalid data in the end of half buffer if ((clear_cnt = half_dmasize - swptr) < 0) clear_cnt += half_dmasize; - memset (dmabuf->rawbuf + swptr, silence, clear_cnt); //clear the invalid data + //clear the invalid data + memset (dmabuf->rawbuf + swptr, + silence, clear_cnt); + dmabuf->endcleared = 1; } } else if (dmabuf->count < (signed) dmabuf->fragsize) { @@ -1181,12 +1182,15 @@ memset (dmabuf->rawbuf + swptr, silence, clear_cnt); dmabuf->endcleared = 1; } - } - /* since dma machine only interrupts at ESO and ESO/2, we sure have at - least half of dma buffer free, so wake up the process unconditionally */ - wake_up(&dmabuf->wait); + } + /* trident_update_ptr is called by interrupt handler or by process via + ioctl/poll, we only wake up the waiting process when we have more + than 1/2 buffer of data to process (always true for interrupt handler) */ + if (dmabuf->count > (signed)dmabuf->dmasize/2) + wake_up(&dmabuf->wait); } } + /* error handling and process wake up for DAC */ if (dmabuf->enable == DAC_RUNNING) { if (dmabuf->mapped) { @@ -1203,9 +1207,11 @@ __stop_dac(state); dmabuf->error++; } - /* since dma machine only interrupts at ESO and ESO/2, we sure have at - least half of dma buffer free, so wake up the process unconditionally */ - wake_up(&dmabuf->wait); + /* trident_update_ptr is called by interrupt handler or by process via + ioctl/poll, we only wake up the waiting process when we have more + than 1/2 buffer free (always true for interrupt handler) */ + if (dmabuf->count < (signed)dmabuf->dmasize/2) + wake_up(&dmabuf->wait); } } dmabuf->update_flag &= ~ALI_ADDRESS_INT_UPDATE; @@ -1336,7 +1342,8 @@ ret = 0; if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451) - outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) | ALI_PCM_IN_ENABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL)); + outl(inl(TRID_REG (state->card, ALI_GLOBAL_CONTROL)) | ALI_PCM_IN_ENABLE, + TRID_REG (state->card, ALI_GLOBAL_CONTROL)); while (count > 0) { spin_lock_irqsave(&state->card->lock, flags); @@ -1439,7 +1446,8 @@ if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451) if (dmabuf->channel->num == ALI_PCM_IN_CHANNEL) - outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) & ALI_PCM_IN_DISABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL)); + outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) & + ALI_PCM_IN_DISABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL)); while (count > 0) { spin_lock_irqsave(&state->card->lock, flags); @@ -1905,6 +1913,7 @@ struct trident_state *state = NULL; struct dmabuf *dmabuf = NULL; + MOD_INC_USE_COUNT; /* find an avaiable virtual channel (instance of /dev/dsp) */ while (card != NULL) { down(&card->open_sem); @@ -1912,8 +1921,10 @@ if (card->states[i] == NULL) { state = card->states[i] = (struct trident_state *) kmalloc(sizeof(struct trident_state), GFP_KERNEL); - if (state == NULL) + if (state == NULL) { + MOD_DEC_USE_COUNT; return -ENOMEM; + } memset(state, 0, sizeof(struct trident_state)); dmabuf = &state->dmabuf; goto found_virt; @@ -1923,9 +1934,10 @@ card = card->next; } /* no more virtual channel avaiable */ - if (!state) + if (!state) { + MOD_DEC_USE_COUNT; return -ENODEV; - + } found_virt: /* found a free virtual channel, allocate hardware channels */ if(file->f_mode & FMODE_READ) @@ -1936,6 +1948,7 @@ if (dmabuf->channel == NULL) { kfree (card->states[i]); card->states[i] = NULL; + MOD_DEC_USE_COUNT; return -ENODEV; } @@ -1946,7 +1959,6 @@ init_waitqueue_head(&dmabuf->wait); file->private_data = state; - /* set default sample format. According to OSS Programmer's Guide /dev/dsp should be default to unsigned 8-bits, mono, with sample rate 8kHz and /dev/dspW will accept 16-bits sample */ @@ -1991,11 +2003,10 @@ up(&card->open_sem); #ifdef DEBUG - printk(KERN_ERR "trident: open virtual channel %d, hard channel %d\n", - state->virt, - dmabuf->channel->num); + printk(KERN_ERR "trident: open virtual channel %d, hard channel %d\n", + state->virt, dmabuf->channel->num); #endif - MOD_INC_USE_COUNT; + return 0; } @@ -2020,7 +2031,6 @@ dealloc_dmabuf(state); state->card->free_pcm_channel(state->card, dmabuf->channel->num); } - if (file->f_mode & FMODE_READ) { stop_adc(state); dealloc_dmabuf(state); @@ -2255,19 +2265,21 @@ int minor = MINOR(inode->i_rdev); struct trident_card *card = devs; + MOD_INC_USE_COUNT; for (card = devs; card != NULL; card = card->next) for (i = 0; i < NR_AC97; i++) if (card->ac97_codec[i] != NULL && card->ac97_codec[i]->dev_mixer == minor) goto match; - if (!card) + if (!card) { + MOD_DEC_USE_COUNT; return -ENODEV; - + } match: file->private_data = card->ac97_codec[i]; - MOD_INC_USE_COUNT; + return 0; } @@ -2385,7 +2397,7 @@ } pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision); - iobase = pci_resource_start (pci_dev, 0); + iobase = pci_dev->resource[0].start; if (check_region(iobase, 256)) { printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n", iobase); @@ -2393,7 +2405,7 @@ } if (pci_enable_device(pci_dev)) - return -ENODEV; + return -ENODEV; if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) { printk(KERN_ERR "trident: out of memory\n"); @@ -2421,20 +2433,19 @@ printk(KERN_INFO "trident: %s found at IO 0x%04lx, IRQ %d\n", card_names[pci_id->driver_data], card->iobase, card->irq); - if(card->pci_id == PCI_DEVICE_ID_ALI_5451) - { + if(card->pci_id == PCI_DEVICE_ID_ALI_5451) { card->alloc_pcm_channel = ali_alloc_pcm_channel; card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel; card->free_pcm_channel = ali_free_pcm_channel; card->address_interrupt = ali_address_interrupt; } - else - { + else { card->alloc_pcm_channel = trident_alloc_pcm_channel; card->alloc_rec_pcm_channel = trident_alloc_pcm_channel; card->free_pcm_channel = trident_free_pcm_channel; card->address_interrupt = trident_address_interrupt; } + /* claim our iospace and irq */ request_region(card->iobase, 256, card_names[pci_id->driver_data]); if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ, @@ -2462,12 +2473,12 @@ } outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL)); - if (card->pci_id == PCI_DEVICE_ID_ALI_5451) - { + if (card->pci_id == PCI_DEVICE_ID_ALI_5451) { /* edited by HMSEO for GT sound */ #ifdef CONFIG_ALPHA_NAUTILUS ac97_data = trident_ac97_get (card->ac97_codec[0], AC97_POWER_CONTROL); - trident_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL, ac97_data | ALI_EAPD_POWER_DOWN); + trident_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL, + ac97_data | ALI_EAPD_POWER_DOWN); #endif /* edited by HMSEO for GT sound*/ } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/via82cxxx_audio.c linux.ac/drivers/sound/via82cxxx_audio.c --- linux.vanilla/drivers/sound/via82cxxx_audio.c Thu May 25 17:38:08 2000 +++ linux.ac/drivers/sound/via82cxxx_audio.c Sat May 27 15:22:14 2000 @@ -11,7 +11,7 @@ */ -#define VIA_VERSION "1.1.6" +#define VIA_VERSION "1.1.7" #include @@ -2331,6 +2331,7 @@ via_interrupt_cleanup (card); via_card_cleanup_proc (card); via_dsp_cleanup (card); + via_ac97_cleanup (card); release_region (pci_resource_start (pdev, 0), pci_resource_len (pdev, 0)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/telephony/ixj.c linux.ac/drivers/telephony/ixj.c --- linux.vanilla/drivers/telephony/ixj.c Thu May 25 17:38:23 2000 +++ linux.ac/drivers/telephony/ixj.c Sat May 27 22:00:30 2000 @@ -446,8 +446,7 @@ { j->m_hook = 0; j->ex.bits.hookstate = 1; - if (j->async_queue) - kill_fasync(j->async_queue, SIGIO, POLL_IN); // Send apps notice of change + kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change } goto timer_end; } @@ -536,8 +535,7 @@ j->proc_load = j->ssr.high << 8 | j->ssr.low; if (!j->m_hook) { j->m_hook = j->ex.bits.hookstate = 1; - if (j->async_queue) - kill_fasync(j->async_queue, SIGIO, POLL_IN); // Send apps notice of change + kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change } } else { if (j->dsp.low == 0x21 && @@ -552,8 +550,7 @@ if (j->m_hook) { j->m_hook = 0; j->ex.bits.hookstate = 1; - if (j->async_queue) - kill_fasync(j->async_queue, SIGIO, POLL_IN); // Send apps notice of change + kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change } } } @@ -642,8 +639,7 @@ } if (j->ex.bytes) { wake_up_interruptible(&j->poll_q); // Wake any blocked selects - if (j->async_queue) - kill_fasync(j->async_queue, SIGIO, POLL_IN); // Send apps notice of change + kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change } } else { break; @@ -917,8 +913,7 @@ j->r_hook = fOffHook; if (j->port != PORT_POTS) { j->ex.bits.hookstate = 1; - if (j->async_queue) - kill_fasync(j->async_queue, SIGIO, POLL_IN); // Send apps notice of change + kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change } } @@ -1471,8 +1466,7 @@ wake_up_interruptible(&j->poll_q); // Wake any blocked selects - if (j->async_queue) - kill_fasync(j->async_queue, SIGIO, POLL_IN); // Send apps notice of frame + kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of frame } } @@ -1557,8 +1551,7 @@ wake_up_interruptible(&j->poll_q); // Wake any blocked selects - if (j->async_queue) - kill_fasync(j->async_queue, SIGIO, POLL_IN); // Send apps notice of empty buffer + kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of empty buffer #ifdef PERFMON_STATS ++j->frameswritten; #endif @@ -4614,6 +4607,8 @@ for (i = 0; i < IXJMAX - cnt; i++) { pci = pci_find_device(0x15E2, 0x0500, pci); if (!pci) + break; + if (pci_enable_device(pci)) break; { ixj[cnt].DSPbase = pci->resource[0].start; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/telephony/ixj.h linux.ac/drivers/telephony/ixj.h --- linux.vanilla/drivers/telephony/ixj.h Thu May 25 17:38:23 2000 +++ linux.ac/drivers/telephony/ixj.h Mon May 29 20:35:29 2000 @@ -879,6 +879,7 @@ typedef struct { struct phone_device p; + struct semaphore mutex; unsigned int board; unsigned int DSPbase; unsigned int XILINXbase; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/acm.c linux.ac/drivers/usb/acm.c --- linux.vanilla/drivers/usb/acm.c Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/acm.c Sat May 27 15:43:57 2000 @@ -329,6 +329,7 @@ if (!ACM_READY(acm)) return -EINVAL; if (acm->writeurb.status == -EINPROGRESS) return 0; + if (!count) return 0; count = (count > acm->writesize) ? acm->writesize : count; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/audio.c linux.ac/drivers/usb/audio.c --- linux.vanilla/drivers/usb/audio.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/usb/audio.c Sat May 27 15:42:10 2000 @@ -1788,7 +1788,7 @@ dev->devnum, ms->iface, ms->ch[i].slctunitid & 0xff); continue; } - for (j = i; j < ms->numch; i++) { + for (j = i; j < ms->numch; j++) { if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff) continue; mask |= 1 << j; @@ -1821,7 +1821,7 @@ } /* first generate smask */ smask = bmask = 0; - for (j = i; j < ms->numch; i++) { + for (j = i; j < ms->numch; j++) { if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff) continue; smask |= 1 << ms->ch[j].osschannel; @@ -1835,7 +1835,7 @@ continue; if (j > 1) srcmask &= ~bmask; - for (j = i; j < ms->numch; i++) { + for (j = i; j < ms->numch; j++) { if ((ms->ch[i].slctunitid ^ ms->ch[j].slctunitid) & 0xff) continue; if (!(srcmask & (1 << ms->ch[j].osschannel))) @@ -3193,6 +3193,16 @@ state->termtype = 0; } +static struct mixerchannel *slctsrc_findunit(struct consmixstate *state, __u8 unitid) +{ + unsigned int i; + + for (i = 0; i < state->nrmixch; i++) + if (state->mixch[i].unitid == unitid) + return &state->mixch[i]; + return NULL; +} + static void usb_audio_selectorunit(struct consmixstate *state, unsigned char *selector) { unsigned int chnum, i, mixch; @@ -3206,7 +3216,9 @@ usb_audio_recurseunit(state, selector[5]); if (state->nrmixch != mixch) { mch = &state->mixch[state->nrmixch-1]; - mch->slctunitid = selector[5] | (1 << 8); + mch->slctunitid = selector[3] | (1 << 8); + } else if ((mch = slctsrc_findunit(state, selector[5]))) { + mch->slctunitid = selector[3] | (1 << 8); } else { printk(KERN_INFO "usbaudio: selector unit %u: ignoring channel 1\n", selector[3]); } @@ -3223,7 +3235,9 @@ } if (state->nrmixch != mixch) { mch = &state->mixch[state->nrmixch-1]; - mch->slctunitid = selector[5] | ((i + 1) << 8); + mch->slctunitid = selector[3] | ((i + 1) << 8); + } else if ((mch = slctsrc_findunit(state, selector[5+i]))) { + mch->slctunitid = selector[3] | ((i + 1) << 8); } else { printk(KERN_INFO "usbaudio: selector unit %u: ignoring channel %u\n", selector[3], i+1); } @@ -3604,8 +3618,10 @@ #endif if (config->interface[ifnum].altsetting[0].bInterfaceClass != USB_CLASS_AUDIO || config->interface[ifnum].altsetting[0].bInterfaceSubClass != 1) { +#if 0 printk(KERN_DEBUG "usbaudio: vendor id 0x%04x, product id 0x%04x contains no AudioControl interface\n", dev->descriptor.idVendor, dev->descriptor.idProduct); +#endif return NULL; } /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/devio.c linux.ac/drivers/usb/devio.c --- linux.vanilla/drivers/usb/devio.c Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/devio.c Sat May 27 15:41:34 2000 @@ -187,26 +187,60 @@ ssize_t ret = 0; unsigned len; loff_t pos; + int i; pos = *ppos; down_read(&ps->devsem); - if (!ps->dev) + if (!ps->dev) { ret = -ENODEV; - else if (pos < 0) + goto err; + } else if (pos < 0) { ret = -EINVAL; - else if (pos < sizeof(struct usb_device_descriptor)) { + goto err; + } + + if (pos < sizeof(struct usb_device_descriptor)) { len = sizeof(struct usb_device_descriptor) - pos; if (len > nbytes) len = nbytes; - if (copy_to_user(buf, ((char *)&ps->dev->descriptor) + pos, len)) + if (copy_to_user(buf, ((char *)&ps->dev->descriptor) + pos, len)) { ret = -EFAULT; - else { + goto err; + } + + *ppos += len; + buf += len; + nbytes -= len; + ret += len; + } + + pos = sizeof(struct usb_device_descriptor); + for (i = 0; nbytes && i < ps->dev->descriptor.bNumConfigurations; i++) { + struct usb_config_descriptor *config = + (struct usb_config_descriptor *)ps->dev->rawdescriptors[i]; + unsigned int length = le16_to_cpu(config->wTotalLength); + + if (*ppos < pos + length) { + len = length - (*ppos - pos); + if (len > nbytes) + len = nbytes; + + if (copy_to_user(buf, + ps->dev->rawdescriptors[i] + (*ppos - pos), len)) { + ret = -EFAULT; + goto err; + } + *ppos += len; buf += len; nbytes -= len; ret += len; } + + pos += length; } + +err: up_read(&ps->devsem); return ret; } @@ -376,12 +410,9 @@ } struct usb_driver usbdevfs_driver = { - "usbdevfs", - driver_probe, - driver_disconnect, - LIST_HEAD_INIT(usbdevfs_driver.driver_list), - NULL, - 0 + name: "usbdevfs", + probe: driver_probe, + disconnect: driver_disconnect, }; static int claimintf(struct dev_state *ps, unsigned int intf) @@ -481,6 +512,28 @@ return -ENOENT; } +extern struct list_head usb_driver_list; + +static int finddriver(struct usb_driver **driver, char *name) +{ + struct list_head *tmp; + + tmp = usb_driver_list.next; + while (tmp != &usb_driver_list) { + struct usb_driver *d = list_entry(tmp, struct usb_driver, + driver_list); + + if (!strcmp(d->name, name)) { + *driver = d; + return 0; + } + + tmp = tmp->next; + } + + return -EINVAL; +} + /* * file operations */ @@ -662,16 +715,51 @@ return 0; } +static int proc_getdriver(struct dev_state *ps, void *arg) +{ + struct usbdevfs_getdriver gd; + struct usb_interface *interface; + int ret; + + copy_from_user_ret(&gd, arg, sizeof(gd), -EFAULT); + if ((ret = findintfif(ps->dev, gd.interface)) < 0) + return ret; + interface = usb_ifnum_to_if(ps->dev, gd.interface); + if (!interface) + return -EINVAL; + if (!interface->driver) + return -ENODATA; + strcpy(gd.driver, interface->driver->name); + copy_to_user_ret(arg, &gd, sizeof(gd), -EFAULT); + return 0; +} + +static int proc_connectinfo(struct dev_state *ps, void *arg) +{ + struct usbdevfs_connectinfo ci; + + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->slow; + copy_to_user_ret(arg, &ci, sizeof(ci), -EFAULT); + return 0; +} + static int proc_setintf(struct dev_state *ps, void *arg) { struct usbdevfs_setinterface setintf; + struct usb_interface *interface; int ret; copy_from_user_ret(&setintf, arg, sizeof(setintf), -EFAULT); if ((ret = findintfif(ps->dev, setintf.interface)) < 0) return ret; - if ((ret = checkintf(ps, ret))) - return ret; + interface = usb_ifnum_to_if(ps->dev, setintf.interface); + if (!interface) + return -EINVAL; + if (interface->driver) { + if ((ret = checkintf(ps, ret))) + return ret; + } if (usb_set_interface(ps->dev, setintf.interface, setintf.altsetting)) return -EINVAL; return 0; @@ -942,6 +1030,14 @@ ret = proc_resetep(ps, (void *)arg); if (ret >= 0) inode->i_mtime = CURRENT_TIME; + break; + + case USBDEVFS_GETDRIVER: + ret = proc_getdriver(ps, (void *)arg); + break; + + case USBDEVFS_CONNECTINFO: + ret = proc_connectinfo(ps, (void *)arg); break; case USBDEVFS_SETINTERFACE: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/evdev.c linux.ac/drivers/usb/evdev.c --- linux.vanilla/drivers/usb/evdev.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/evdev.c Sat May 27 22:00:30 2000 @@ -72,8 +72,7 @@ list->buffer[list->head].value = value; list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); - if (list->fasync) - kill_fasync(list->fasync, SIGIO, POLL_IN); + kill_fasync(&list->fasync, SIGIO, POLL_IN); list = list->next; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/joydev.c linux.ac/drivers/usb/joydev.c --- linux.vanilla/drivers/usb/joydev.c Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/joydev.c Sat May 27 22:00:30 2000 @@ -139,8 +139,7 @@ if (list->tail == (list->head = (list->head + 1) & (JOYDEV_BUFFER_SIZE - 1))) list->startup = 0; - if (list->fasync) - kill_fasync(list->fasync, SIGIO, POLL_IN); + kill_fasync(&list->fasync, SIGIO, POLL_IN); list = list->next; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/mousedev.c linux.ac/drivers/usb/mousedev.c --- linux.vanilla/drivers/usb/mousedev.c Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/mousedev.c Sat May 27 22:00:30 2000 @@ -138,8 +138,7 @@ list->ready = 1; - if (list->fasync) - kill_fasync(list->fasync, SIGIO, POLL_IN); + kill_fasync(&list->fasync, SIGIO, POLL_IN); list = list->next; } @@ -311,8 +310,7 @@ list->buffer = list->bufsiz; } - if (list->fasync) - kill_fasync(list->fasync, SIGIO, POLL_IN); + kill_fasync(&list->fasync, SIGIO, POLL_IN); wake_up_interruptible(&list->mousedev->wait); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/pegasus.c linux.ac/drivers/usb/pegasus.c --- linux.vanilla/drivers/usb/pegasus.c Thu May 25 17:38:14 2000 +++ linux.ac/drivers/usb/pegasus.c Sat May 27 15:43:06 2000 @@ -16,7 +16,7 @@ #include -static const char *version = __FILE__ ": v0.3.12 2000/05/22 (C) 1999-2000 Petko Manolov (petkan@spct.net)\n"; +static const char *version = __FILE__ ": v0.3.13 2000/05/25 (C) 1999-2000 Petko Manolov (petkan@spct.net)\n"; #define PEGASUS_MTU 1500 @@ -71,6 +71,7 @@ {"Accton USB 10/100 Ethernet Adapter", 0x083a, 0x1046, NULL}, {"IO DATA USB ET/TX", 0x04bb, 0x0904, NULL}, {"LANEED USB Ethernet LD-USB/TX", 0x056e, 0x4002, NULL}, + {"Sony Ethernet USB", 0x05e9, 0x0009, NULL}, {NULL, 0, 0, NULL} }; @@ -223,7 +224,7 @@ __u16 pkt_len; if (urb->status) { - info("%s: RX status %d", net->name, urb->status); + dbg("%s: RX status %d", net->name, urb->status); goto goon; } @@ -369,9 +370,12 @@ netif_stop_queue(net); - usb_unlink_urb(&pegasus->rx_urb); - usb_unlink_urb(&pegasus->tx_urb); - usb_unlink_urb(&pegasus->intr_urb); + if ( pegasus->rx_urb.status == -EINPROGRESS ) + usb_unlink_urb(&pegasus->rx_urb); + if ( pegasus->tx_urb.status == -EINPROGRESS ) + usb_unlink_urb(&pegasus->tx_urb); + if ( pegasus->intr_urb.status == -EINPROGRESS ) + usb_unlink_urb(&pegasus->intr_urb); MOD_DEC_USE_COUNT; @@ -510,9 +514,12 @@ unregister_netdev(pegasus->net); - usb_unlink_urb(&pegasus->rx_urb); - usb_unlink_urb(&pegasus->tx_urb); - usb_unlink_urb(&pegasus->intr_urb); + if ( pegasus->rx_urb.status == -EINPROGRESS ) + usb_unlink_urb(&pegasus->rx_urb); + if ( pegasus->tx_urb.status == -EINPROGRESS ) + usb_unlink_urb(&pegasus->tx_urb); + if ( pegasus->intr_urb.status == -EINPROGRESS ) + usb_unlink_urb(&pegasus->intr_urb); kfree(pegasus); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/usb-core.c linux.ac/drivers/usb/usb-core.c --- linux.vanilla/drivers/usb/usb-core.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/usb-core.c Sat May 27 15:41:34 2000 @@ -65,7 +65,7 @@ #endif { usb_major_init(); - usbdevfs_init(); + usbdevfs_init(); usb_hub_init(); #ifndef CONFIG_USB_MODULE diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/usb.c linux.ac/drivers/usb/usb.c --- linux.vanilla/drivers/usb/usb.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/usb.c Sat May 27 15:41:34 2000 @@ -61,6 +61,9 @@ } info("registered new driver %s", new_driver->name); + + init_MUTEX(&new_driver->serialize); + /* Add it to the list of known drivers */ list_add(&new_driver->driver_list, &usb_driver_list); @@ -105,7 +108,9 @@ struct usb_interface *interface = &dev->actconfig->interface[i]; if (interface->driver == driver) { + down(&driver->serialize); driver->disconnect(dev, interface->private_data); + up(&driver->serialize); usb_driver_release_interface(driver, interface); /* * This will go through the list looking for another @@ -142,6 +147,16 @@ } } +struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum) +{ + int i; + + for (i = 0; i < dev->actconfig->bNumInterfaces; i++) + if (dev->actconfig->interface[i].altsetting[0].bInterfaceNumber == ifnum) + return &dev->actconfig->interface[i]; + + return NULL; +} /* * calc_bus_time: @@ -242,7 +257,7 @@ bus->bandwidth_isoc_reqs = 0; INIT_LIST_HEAD(&bus->bus_list); - INIT_LIST_HEAD(&bus->inodes); + INIT_LIST_HEAD(&bus->inodes); return bus; } @@ -393,7 +408,10 @@ driver_list); tmp = tmp->next; - if (!(private = driver->probe(dev, ifnum))) + down(&driver->serialize); + private = driver->probe(dev, ifnum); + up(&driver->serialize); + if (!private) continue; usb_driver_claim_interface(driver, interface, private); @@ -452,8 +470,8 @@ dev->bus = bus; dev->parent = parent; atomic_set(&dev->refcnt, 1); - INIT_LIST_HEAD(&dev->inodes); - INIT_LIST_HEAD(&dev->filelist); + INIT_LIST_HEAD(&dev->inodes); + INIT_LIST_HEAD(&dev->filelist); dev->bus->op->allocate(dev); @@ -826,7 +844,7 @@ begin = buffer; numskipped = 0; - /* Skip over at Interface class or vendor descriptors */ + /* Skip over any interface, class or vendor descriptors */ while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; @@ -987,6 +1005,13 @@ if (!dev->config) return; + if (dev->rawdescriptors) { + for (i = 0; i < dev->descriptor.bNumConfigurations; i++) + kfree(dev->rawdescriptors[i]); + + kfree(dev->rawdescriptors); + } + for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { struct usb_config_descriptor *cf = &dev->config[c]; @@ -1129,7 +1154,9 @@ struct usb_interface *interface = &dev->actconfig->interface[i]; struct usb_driver *driver = interface->driver; if (driver) { + down(&driver->serialize); driver->disconnect(dev, interface->private_data); + up(&driver->serialize); usb_driver_release_interface(driver, interface); } } @@ -1143,14 +1170,13 @@ } /* remove /proc/bus/usb entry */ - usbdevfs_remove_device(dev); + usbdevfs_remove_device(dev); /* Free up the device itself, including its device number */ if (dev->devnum > 0) clear_bit(dev->devnum, &dev->bus->devmap.devicemap); - + usb_free_dev(dev); - } /* @@ -1337,15 +1363,10 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) { - struct usb_interface *iface = NULL; - int ret, i; + struct usb_interface *iface; + int ret; - for (i=0; iactconfig->bNumInterfaces; i++) { - if (dev->actconfig->interface[i].altsetting->bInterfaceNumber == interface) { - iface = &dev->actconfig->interface[i]; - break; - } - } + iface = usb_ifnum_to_if(dev, interface); if (!iface) { warn("selecting invalid interface %d", interface); return -EINVAL; @@ -1407,11 +1428,10 @@ int usb_get_configuration(struct usb_device *dev) { - int result; - unsigned int cfgno; + int result; + unsigned int cfgno, length; unsigned char buffer[8]; unsigned char *bigbuffer; - unsigned int tmp; struct usb_config_descriptor *desc = (struct usb_config_descriptor *)buffer; @@ -1435,9 +1455,14 @@ memset(dev->config, 0, dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor)); - for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) { - + dev->rawdescriptors = (char **)kmalloc(sizeof(char *) * + dev->descriptor.bNumConfigurations, GFP_KERNEL); + if (!dev->rawdescriptors) { + err("out of memory"); + return -1; + } + for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) { /* We grab the first 8 bytes so we know how long the whole */ /* configuration is */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8); @@ -1445,41 +1470,41 @@ if (result < 0) err("unable to get descriptor"); else - err("config descriptor too short (expected %i, got %i)",8,result); + err("config descriptor too short (expected %i, got %i)", 8, result); goto err; } /* Get the full buffer */ - le16_to_cpus(&desc->wTotalLength); + length = le16_to_cpu(desc->wTotalLength); - bigbuffer = kmalloc(desc->wTotalLength, GFP_KERNEL); + bigbuffer = kmalloc(length, GFP_KERNEL); if (!bigbuffer) { err("unable to allocate memory for configuration descriptors"); - result=-ENOMEM; + result = -ENOMEM; goto err; } - tmp=desc->wTotalLength; + /* Now that we know the length, get the whole thing */ - result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, desc->wTotalLength); + result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length); if (result < 0) { err("couldn't get all of config descriptors"); kfree(bigbuffer); goto err; } - if (result < tmp) { - err("config descriptor too short (expected %i, got %i)",tmp,result); + if (result < length) { + err("config descriptor too short (expected %i, got %i)", length, result); kfree(bigbuffer); goto err; } - result = usb_parse_configuration(dev, &dev->config[cfgno], bigbuffer); - kfree(bigbuffer); + dev->rawdescriptors[cfgno] = bigbuffer; + + result = usb_parse_configuration(dev, &dev->config[cfgno], bigbuffer); if (result > 0) dbg("descriptor data left"); - else if (result < 0) - { - result=-1; + else if (result < 0) { + result = -1; goto err; } } @@ -1560,8 +1585,7 @@ */ int usb_new_device(struct usb_device *dev) { - int addr, err; - int tmp; + int err; info("USB new device connect, assigned device number %d", dev->devnum); @@ -1572,10 +1596,15 @@ dev->epmaxpacketin [0] = 8; dev->epmaxpacketout[0] = 8; - /* Even though we have assigned an address for the device, we */ - /* haven't told it what it's address is yet */ - addr = dev->devnum; - dev->devnum = 0; + err = usb_set_address(dev); + if (err < 0) { + err("USB device not accepting new address (error=%d)", err); + clear_bit(dev->devnum, &dev->bus->devmap.devicemap); + dev->devnum = -1; + return 1; + } + + wait_ms(10); /* Let the SET_ADDRESS settle */ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8); if (err < 8) { @@ -1583,34 +1612,19 @@ err("USB device not responding, giving up (error=%d)", err); else err("USB device descriptor short read (expected %i, got %i)",8,err); - clear_bit(addr, &dev->bus->devmap.devicemap); + clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; return 1; } dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; - dev->devnum = addr; - - err = usb_set_address(dev); - - if (err < 0) { - err("USB device not accepting new address (error=%d)", err); - clear_bit(dev->devnum, &dev->bus->devmap.devicemap); - dev->devnum = -1; - return 1; - } - - wait_ms(10); /* Let the SET_ADDRESS settle */ - - tmp = sizeof(dev->descriptor); - err = usb_get_device_descriptor(dev); - if (err < tmp) { + if (err < sizeof(dev->descriptor)) { if (err < 0) - err("unable to get device descriptor (error=%d)",err); + err("unable to get device descriptor (error=%d)", err); else - err("USB device descriptor short read (expected %i, got %i)",tmp,err); + err("USB device descriptor short read (expected %i, got %i)", sizeof(dev->descriptor), err); clear_bit(dev->devnum, &dev->bus->devmap.devicemap); dev->devnum = -1; @@ -1646,7 +1660,7 @@ #endif /* now that the basic setup is over, add a /proc/bus/usb entry */ - usbdevfs_add_device(dev); + usbdevfs_add_device(dev); /* find drivers willing to handle this device */ usb_find_drivers(dev); @@ -1704,6 +1718,8 @@ * into the kernel, and other device drivers are built as modules, * then these symbols need to be exported for the modules to use. */ +EXPORT_SYMBOL(usb_ifnum_to_if); + EXPORT_SYMBOL(usb_register); EXPORT_SYMBOL(usb_deregister); EXPORT_SYMBOL(usb_alloc_bus); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/video/clgenfb.c linux.ac/drivers/video/clgenfb.c --- linux.vanilla/drivers/video/clgenfb.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/video/clgenfb.c Sat May 27 15:32:25 2000 @@ -2504,6 +2504,8 @@ if (pdev) *btype = clgen_pci_probe_list[i - 1].btype; + if (pci_enable_device(pdev)) + return NULL; DPRINTK ("EXIT, returning %p\n", pdev); return pdev; @@ -2555,24 +2557,18 @@ } - - -/* clgen_pci_unmap only used in modules */ -#ifdef MODULE -static void clgen_pci_unmap (struct clgenfb_info *info) +static void __exit clgen_pci_unmap (struct clgenfb_info *info) { iounmap (info->fbmem); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13) release_mem_region(info->fbmem_phys, info->size); #if 0 /* if system didn't claim this region, we would... */ release_mem_region(0xA0000, 65535); #endif + if (release_io_ports) release_region(0x3C0, 32); -#endif } -#endif /* MODULE */ static int __init clgen_pci_setup (struct clgenfb_info *info, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/video/vga16fb.c linux.ac/drivers/video/vga16fb.c --- linux.vanilla/drivers/video/vga16fb.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/video/vga16fb.c Sat May 27 15:23:43 2000 @@ -387,7 +387,7 @@ if (pos & 0x200) r7 |= 0x80; pos += vslen; - par->crtc[VGA_CRTC_V_SYNC_END] = (pos & 0x0F) | 0x10; /* disabled IRQ */ + par->crtc[VGA_CRTC_V_SYNC_END] = (pos & 0x0F) & ~0x10; /* disabled IRQ */ pos += upper - 1; /* blank_end + 1 <= ytotal + 2 */ par->crtc[VGA_CRTC_V_BLANK_END] = pos & 0xFF; /* 0x7F for original VGA, but some SVGA chips requires all 8 bits to set */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/devfs/base.c linux.ac/fs/devfs/base.c --- linux.vanilla/fs/devfs/base.c Thu May 25 17:37:32 2000 +++ linux.ac/fs/devfs/base.c Mon May 29 19:23:51 2000 @@ -737,7 +737,8 @@ * @namelen: The number of characters in @name. * @traverse_symlink: If %TRUE then the entry is traversed if it is a symlink. * - * Returns a pointer to the entry on success, else %NULL. + * Search for a devfs entry inside another devfs entry and returns a pointer + * to the entry on success, else %NULL. */ static struct devfs_entry *search_for_entry_in_dir (struct devfs_entry *parent, @@ -902,6 +903,7 @@ /** * find_by_dev - Find a devfs entry in a directory. + * @dir: The directory where to search * @major: The major number to search for. * @minor: The minor number to search for. * @type: The type of special file to search for. This may be either @@ -1746,8 +1748,8 @@ /** * devfs_set_file_size - Set the file size for a devfs regular file. - * de: The handle to the device entry. - * size: The new file size. + * @de: The handle to the device entry. + * @size: The new file size. * * Returns 0 on success, else a negative error code. */ @@ -1788,6 +1790,7 @@ /** * devfs_set_info - Set the info pointer written to private_data upon open. * @de: The handle to the device entry. + * @info: pointer to the data * * Returns 0 on success, else a negative error code. */ @@ -1940,8 +1943,8 @@ /** * devfs_unregister_chrdev - Optionally unregister a conventional character driver. - * major: The major number for the driver. - * name: The name of the driver (as seen in /proc/devices). + * @major: The major number for the driver. + * @name: The name of the driver (as seen in /proc/devices). * * This function will unregister a character driver provided the "devfs=only" * option was not provided at boot time. @@ -1976,7 +1979,6 @@ /** * devfs_setup - Process kernel boot options. * @str: The boot options after the "devfs=". - * @unused: Unused. */ SETUP_STATIC int __init devfs_setup (char *str) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/exec.c linux.ac/fs/exec.c --- linux.vanilla/fs/exec.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/exec.c Thu May 25 20:57:53 2000 @@ -484,6 +484,8 @@ /* This is the point of no return */ release_old_signals(oldsig); + current->sas_ss_sp = current->sas_ss_size = 0; + if (current->euid == current->uid && current->egid == current->gid) current->dumpable = 1; name = bprm->filename; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/fcntl.c linux.ac/fs/fcntl.c --- linux.vanilla/fs/fcntl.c Thu May 25 17:46:16 2000 +++ linux.ac/fs/fcntl.c Sat May 27 22:00:30 2000 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -330,7 +331,52 @@ read_unlock(&tasklist_lock); } -void kill_fasync(struct fasync_struct *fa, int sig, int band) +/* + * fasync_helper() is used by some character device drivers (mainly mice) + * to set up the fasync queue. It returns negative on error, 0 if it did + * no changes and positive if it added/deleted the entry. + */ +static rwlock_t fasync_lock = RW_LOCK_UNLOCKED; +int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) +{ + struct fasync_struct *fa, **fp; + struct fasync_struct *new = NULL; + int result = 0; + + if (on) { + new = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL); + if (!new) + return -ENOMEM; + } + write_lock_irq(&fasync_lock); + for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) { + if (fa->fa_file == filp) { + if(on) { + fa->fa_fd = fd; + kfree(new); + } else { + *fp = fa->fa_next; + kfree(fa); + result = 1; + } + goto out; + } + } + + if (on) { + new->magic = FASYNC_MAGIC; + new->fa_file = filp; + new->fa_fd = fd; + new->fa_next = *fapp; + *fapp = new; + result = 1; + } +out: + write_unlock_irq(&fasync_lock); + return result; +} + +void __kill_fasync(struct fasync_struct *fa, int sig, int band) { while (fa) { struct fown_struct * fown; @@ -347,4 +393,11 @@ send_sigio(fown, fa, band); fa = fa->fa_next; } +} + +void kill_fasync(struct fasync_struct **fp, int sig, int band) +{ + read_lock(&fasync_lock); + __kill_fasync(*fp, sig, band); + read_unlock(&fasync_lock); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/file_table.c linux.ac/fs/file_table.c --- linux.vanilla/fs/file_table.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/file_table.c Thu May 25 23:36:46 2000 @@ -15,9 +15,7 @@ static kmem_cache_t *filp_cache; /* sysctl tunables... */ -int nr_files; /* read only */ -int nr_free_files; /* read only */ -int max_files = NR_FILE;/* tunable */ +struct files_stat_struct files_stat = {0, 0, NR_FILE}; /* Here the new files go */ static LIST_HEAD(anon_list); @@ -52,11 +50,11 @@ struct file * f; file_list_lock(); - if (nr_free_files > NR_RESERVED_FILES) { + if (files_stat.nr_free_files > NR_RESERVED_FILES) { used_one: f = list_entry(free_list.next, struct file, f_list); list_del(&f->f_list); - nr_free_files--; + files_stat.nr_free_files--; new_one: file_list_unlock(); memset(f, 0, sizeof(*f)); @@ -72,25 +70,25 @@ /* * Use a reserved one if we're the superuser */ - if (nr_free_files && !current->euid) + if (files_stat.nr_free_files && !current->euid) goto used_one; /* * Allocate a new one if we're below the limit. */ - if (nr_files < max_files) { + if (files_stat.nr_files < files_stat.max_files) { file_list_unlock(); f = kmem_cache_alloc(filp_cache, SLAB_KERNEL); file_list_lock(); if (f) { - nr_files++; + files_stat.nr_files++; goto new_one; } /* Big problems... */ printk("VFS: filp allocation failed\n"); - } else if (max_files > old_max) { - printk("VFS: file-max limit %d reached\n", max_files); - old_max = max_files; + } else if (files_stat.max_files > old_max) { + printk("VFS: file-max limit %d reached\n", files_stat.max_files); + old_max = files_stat.max_files; } file_list_unlock(); return NULL; @@ -146,7 +144,7 @@ file_list_lock(); list_del(&file->f_list); list_add(&file->f_list, &free_list); - nr_free_files++; + files_stat.nr_free_files++; file_list_unlock(); } @@ -158,7 +156,7 @@ file_list_lock(); list_del(&file->f_list); list_add(&file->f_list, &free_list); - nr_free_files++; + files_stat.nr_free_files++; file_list_unlock(); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/locks.c linux.ac/fs/locks.c --- linux.vanilla/fs/locks.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/locks.c Thu May 25 23:32:32 2000 @@ -111,33 +111,43 @@ #include -static int flock_make_lock(struct file *filp, struct file_lock *fl, - unsigned int cmd); -static int posix_make_lock(struct file *filp, struct file_lock *fl, - struct flock *l); -static int flock_locks_conflict(struct file_lock *caller_fl, - struct file_lock *sys_fl); -static int posix_locks_conflict(struct file_lock *caller_fl, - struct file_lock *sys_fl); -static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl); -static int flock_lock_file(struct file *filp, struct file_lock *caller, - unsigned int wait); -static int posix_locks_deadlock(struct file_lock *caller, - struct file_lock *blocker); - -static struct file_lock *locks_empty_lock(void); -static struct file_lock *locks_init_lock(struct file_lock *, - struct file_lock *); -static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl); -static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait); -static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx); - -static void locks_insert_block(struct file_lock *blocker, struct file_lock *waiter); -static void locks_delete_block(struct file_lock *blocker, struct file_lock *waiter); -static void locks_wake_up_blocks(struct file_lock *blocker, unsigned int wait); - struct file_lock *file_lock_table = NULL; +/* + * Allocate an empty lock structure. We can use GFP_KERNEL now that + * all allocations are done in advance. + */ +static struct file_lock *locks_empty_lock(void) +{ + /* Okay, let's make a new file_lock structure... */ + return ((struct file_lock *) kmalloc(sizeof(struct file_lock), + GFP_KERNEL)); +} + +/* + * Initialize a new lock from an existing file_lock structure. + */ +static struct file_lock *locks_init_lock(struct file_lock *new, + struct file_lock *fl) +{ + if (new) { + memset(new, 0, sizeof(*new)); + new->fl_owner = fl->fl_owner; + new->fl_pid = fl->fl_pid; + init_waitqueue_head(&new->fl_wait); + new->fl_file = fl->fl_file; + new->fl_flags = fl->fl_flags; + new->fl_type = fl->fl_type; + new->fl_start = fl->fl_start; + new->fl_end = fl->fl_end; + new->fl_notify = fl->fl_notify; + new->fl_insert = fl->fl_insert; + new->fl_remove = fl->fl_remove; + new->fl_u = fl->fl_u; + } + return new; +} + /* Allocate a new lock, and initialize its fields from fl. * The lock is not inserted into any lists until locks_insert_lock() or * locks_insert_block() are called. @@ -161,6 +171,92 @@ return; } +/* Verify a call to flock() and fill in a file_lock structure with + * an appropriate FLOCK lock. + */ +static int flock_make_lock(struct file *filp, struct file_lock *fl, + unsigned int cmd) +{ + memset(fl, 0, sizeof(*fl)); + + init_waitqueue_head(&fl->fl_wait); + + switch (cmd & ~LOCK_NB) { + case LOCK_SH: + fl->fl_type = F_RDLCK; + break; + case LOCK_EX: + fl->fl_type = F_WRLCK; + break; + case LOCK_UN: + fl->fl_type = F_UNLCK; + break; + default: + return (0); + } + + fl->fl_flags = FL_FLOCK; + fl->fl_start = 0; + fl->fl_end = OFFSET_MAX; + fl->fl_file = filp; + fl->fl_owner = NULL; + + return (1); +} + +/* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX + * style lock. + */ +static int posix_make_lock(struct file *filp, struct file_lock *fl, + struct flock *l) +{ + loff_t start; + + memset(fl, 0, sizeof(*fl)); + + init_waitqueue_head(&fl->fl_wait); + fl->fl_flags = FL_POSIX; + + switch (l->l_type) { + case F_RDLCK: + case F_WRLCK: + case F_UNLCK: + fl->fl_type = l->l_type; + break; + default: + return (0); + } + + switch (l->l_whence) { + case 0: /*SEEK_SET*/ + start = 0; + break; + case 1: /*SEEK_CUR*/ + start = filp->f_pos; + break; + case 2: /*SEEK_END*/ + start = filp->f_dentry->d_inode->i_size; + break; + default: + return (0); + } + + if (((start += l->l_start) < 0) || (l->l_len < 0)) + return (0); + fl->fl_end = start + l->l_len - 1; + if (l->l_len > 0 && fl->fl_end < 0) + return (0); + fl->fl_start = start; /* we record the absolute position */ + if (l->l_len == 0) + fl->fl_end = OFFSET_MAX; + + fl->fl_file = filp; + fl->fl_owner = current->files; + fl->fl_pid = current->pid; + + return (1); +} + /* Check if two locks overlap each other. */ static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2) @@ -181,6 +277,31 @@ (fl1->fl_pid == fl2->fl_pid); } +/* Remove waiter from blocker's block list. + * When blocker ends up pointing to itself then the list is empty. + */ +static void locks_delete_block(struct file_lock *blocker, + struct file_lock *waiter) +{ + struct file_lock *nextblock; + struct file_lock *prevblock; + + nextblock = waiter->fl_nextblock; + prevblock = waiter->fl_prevblock; + + if (nextblock == NULL) + return; + + nextblock->fl_prevblock = prevblock; + prevblock->fl_nextblock = nextblock; + + waiter->fl_prevblock = waiter->fl_nextblock = NULL; + if (blocker->fl_nextblock == blocker) + /* No more locks on blocker's blocked list */ + blocker->fl_prevblock = blocker->fl_nextblock = NULL; + return; +} + /* Insert waiter into blocker's block list. * We use a circular list so that processes can be easily woken up in * the order they blocked. The documentation doesn't require this but @@ -214,48 +335,6 @@ return; } -/* Remove waiter from blocker's block list. - * When blocker ends up pointing to itself then the list is empty. - */ -static void locks_delete_block(struct file_lock *blocker, - struct file_lock *waiter) -{ - struct file_lock *nextblock; - struct file_lock *prevblock; - - nextblock = waiter->fl_nextblock; - prevblock = waiter->fl_prevblock; - - if (nextblock == NULL) - return; - - nextblock->fl_prevblock = prevblock; - prevblock->fl_nextblock = nextblock; - - waiter->fl_prevblock = waiter->fl_nextblock = NULL; - if (blocker->fl_nextblock == blocker) - /* No more locks on blocker's blocked list */ - blocker->fl_prevblock = blocker->fl_nextblock = NULL; - return; -} - -/* The following two are for the benefit of lockd. - */ -void -posix_block_lock(struct file_lock *blocker, struct file_lock *waiter) -{ - locks_insert_block(blocker, waiter); - return; -} - -void -posix_unblock_lock(struct file_lock *waiter) -{ - if (waiter->fl_prevblock) - locks_delete_block(waiter->fl_prevblock, waiter); - return; -} - /* Wake up processes blocked waiting for blocker. * If told to wait then schedule the processes until the block list * is empty, otherwise empty the block list ourselves. @@ -285,256 +364,110 @@ return; } -/* flock() system call entry point. Apply a FL_FLOCK style lock to - * an open file descriptor. +/* Insert file lock fl into an inode's lock list at the position indicated + * by pos. At the same time add the lock to the global file lock list. */ -asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) +static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) { - struct file_lock file_lock; - struct file *filp; - int error; + fl->fl_nextlink = file_lock_table; + fl->fl_prevlink = NULL; + if (file_lock_table != NULL) + file_lock_table->fl_prevlink = fl; + file_lock_table = fl; + fl->fl_next = *pos; /* insert into file's list */ + *pos = fl; - lock_kernel(); - error = -EBADF; - filp = fget(fd); - if (!filp) - goto out; - error = -EINVAL; - if (!flock_make_lock(filp, &file_lock, cmd)) - goto out_putf; - error = -EBADF; - if ((file_lock.fl_type != F_UNLCK) && !(filp->f_mode & 3)) - goto out_putf; - error = flock_lock_file(filp, &file_lock, - (cmd & (LOCK_UN | LOCK_NB)) ? 0 : 1); -out_putf: - fput(filp); -out: - unlock_kernel(); - return (error); + if (fl->fl_insert) + fl->fl_insert(fl); + + return; } -/* Report the first existing lock that would conflict with l. - * This implements the F_GETLK command of fcntl(). +/* Delete a lock and free it. + * First remove our lock from the active lock lists. Then call + * locks_wake_up_blocks() to wake up processes that are blocked + * waiting for this lock. Finally free the lock structure. */ -int fcntl_getlk(unsigned int fd, struct flock *l) +static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait) { - struct file *filp; - struct file_lock *fl,file_lock; - struct flock flock; - int error; + struct file_lock *thisfl; + struct file_lock *prevfl; + struct file_lock *nextfl; + + thisfl = *thisfl_p; + *thisfl_p = thisfl->fl_next; - error = -EFAULT; - if (copy_from_user(&flock, l, sizeof(flock))) - goto out; - error = -EINVAL; - if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK)) - goto out; + prevfl = thisfl->fl_prevlink; + nextfl = thisfl->fl_nextlink; - error = -EBADF; - filp = fget(fd); - if (!filp) - goto out; + if (nextfl != NULL) + nextfl->fl_prevlink = prevfl; - if (!posix_make_lock(filp, &file_lock, &flock)) - goto out_putf; + if (prevfl != NULL) + prevfl->fl_nextlink = nextfl; + else + file_lock_table = nextfl; - if (filp->f_op->lock) { - error = filp->f_op->lock(filp, F_GETLK, &file_lock); - if (error < 0) - goto out_putf; - else if (error == LOCK_USE_CLNT) - /* Bypass for NFS with no locking - 2.0.36 compat */ - fl = posix_test_lock(filp, &file_lock); - else - fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock); - } else { - fl = posix_test_lock(filp, &file_lock); - } - - flock.l_type = F_UNLCK; - if (fl != NULL) { - flock.l_pid = fl->fl_pid; - flock.l_start = fl->fl_start; - flock.l_len = fl->fl_end == OFFSET_MAX ? 0 : - fl->fl_end - fl->fl_start + 1; - flock.l_whence = 0; - flock.l_type = fl->fl_type; - } - error = -EFAULT; - if (!copy_to_user(l, &flock, sizeof(flock))) - error = 0; - -out_putf: - fput(filp); -out: - return error; + if (thisfl->fl_remove) + thisfl->fl_remove(thisfl); + + locks_wake_up_blocks(thisfl, wait); + locks_free_lock(thisfl); + + return; } -/* Apply the lock described by l to an open file descriptor. - * This implements both the F_SETLK and F_SETLKW commands of fcntl(). +/* Determine if lock sys_fl blocks lock caller_fl. Common functionality + * checks for overlapping locks and shared/exclusive status. */ -int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l) +static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) { - struct file *filp; - struct file_lock file_lock; - struct flock flock; - struct inode *inode; - int error; - - /* - * This might block, so we do it before checking the inode. - */ - error = -EFAULT; - if (copy_from_user(&flock, l, sizeof(flock))) - goto out; - - /* Get arguments and validate them ... - */ - - error = -EBADF; - filp = fget(fd); - if (!filp) - goto out; - - error = -EINVAL; - inode = filp->f_dentry->d_inode; - - /* Don't allow mandatory locks on files that may be memory mapped - * and shared. - */ - if (IS_MANDLOCK(inode) && - (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) { - struct vm_area_struct *vma; - struct address_space *mapping = inode->i_mapping; - spin_lock(&mapping->i_shared_lock); - for(vma = mapping->i_mmap;vma;vma = vma->vm_next_share) { - if (!(vma->vm_flags & VM_MAYSHARE)) - continue; - spin_unlock(&mapping->i_shared_lock); - error = -EAGAIN; - goto out_putf; - } - spin_unlock(&mapping->i_shared_lock); - } + if (!locks_overlap(caller_fl, sys_fl)) + return (0); - error = -EINVAL; - if (!posix_make_lock(filp, &file_lock, &flock)) - goto out_putf; - - error = -EBADF; - switch (flock.l_type) { + switch (caller_fl->fl_type) { case F_RDLCK: - if (!(filp->f_mode & FMODE_READ)) - goto out_putf; - break; + return (sys_fl->fl_type == F_WRLCK); + case F_WRLCK: - if (!(filp->f_mode & FMODE_WRITE)) - goto out_putf; - break; - case F_UNLCK: - break; - case F_SHLCK: - case F_EXLCK: -#ifdef __sparc__ -/* warn a bit for now, but don't overdo it */ -{ - static int count = 0; - if (!count) { - count=1; - printk(KERN_WARNING - "fcntl_setlk() called by process %d (%s) with broken flock() emulation\n", - current->pid, current->comm); - } -} - if (!(filp->f_mode & 3)) - goto out_putf; - break; -#endif - default: - error = -EINVAL; - goto out_putf; - } + return (1); - if (filp->f_op->lock != NULL) { - error = filp->f_op->lock(filp, cmd, &file_lock); - if (error < 0) - goto out_putf; + default: + printk("locks_conflict(): impossible lock type - %d\n", + caller_fl->fl_type); + break; } - error = posix_lock_file(filp, &file_lock, cmd == F_SETLKW); - -out_putf: - fput(filp); -out: - return error; + return (0); /* This should never happen */ } -/* - * This function is called when the file is being removed - * from the task's fd array. +/* Determine if lock sys_fl blocks lock caller_fl. POSIX specific + * checking before calling the locks_conflict(). */ -void locks_remove_posix(struct file *filp, fl_owner_t owner) +static int posix_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) { - struct inode * inode = filp->f_dentry->d_inode; - struct file_lock file_lock, *fl; - struct file_lock **before; - - /* - * For POSIX locks we free all locks on this file for the given task. + /* POSIX locks owned by the same process do not conflict with + * each other. */ -repeat: - before = &inode->i_flock; - while ((fl = *before) != NULL) { - if ((fl->fl_flags & FL_POSIX) && fl->fl_owner == owner) { - int (*lock)(struct file *, int, struct file_lock *); - lock = filp->f_op->lock; - if (lock) { - file_lock = *fl; - file_lock.fl_type = F_UNLCK; - } - locks_delete_lock(before, 0); - if (lock) { - lock(filp, F_SETLK, &file_lock); - /* List may have changed: */ - goto repeat; - } - continue; - } - before = &fl->fl_next; - } + if (!(sys_fl->fl_flags & FL_POSIX) || + locks_same_owner(caller_fl, sys_fl)) + return (0); + + return (locks_conflict(caller_fl, sys_fl)); } -/* - * This function is called on the last close of an open file. +/* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific + * checking before calling the locks_conflict(). */ -void locks_remove_flock(struct file *filp) +static int flock_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) { - struct inode * inode = filp->f_dentry->d_inode; - struct file_lock file_lock, *fl; - struct file_lock **before; + /* FLOCK locks referring to the same filp do not conflict with + * each other. + */ + if (!(sys_fl->fl_flags & FL_FLOCK) || + (caller_fl->fl_file == sys_fl->fl_file)) + return (0); -repeat: - before = &inode->i_flock; - while ((fl = *before) != NULL) { - if ((fl->fl_flags & FL_FLOCK) && fl->fl_file == filp) { - int (*lock)(struct file *, int, struct file_lock *); - lock = NULL; - if (filp->f_op) - lock = filp->f_op->lock; - if (lock) { - file_lock = *fl; - file_lock.fl_type = F_UNLCK; - } - locks_delete_lock(before, 0); - if (lock) { - lock(filp, F_SETLK, &file_lock); - /* List may have changed: */ - goto repeat; - } - continue; - } - before = &fl->fl_next; - } + return (locks_conflict(caller_fl, sys_fl)); } struct file_lock * @@ -552,16 +485,65 @@ return (cfl); } -int locks_mandatory_locked(struct inode *inode) +/* This function tests for deadlock condition before putting a process to + * sleep. The detection scheme is no longer recursive. Recursive was neat, + * but dangerous - we risked stack corruption if the lock data was bad, or + * if the recursion was too deep for any other reason. + * + * We rely on the fact that a task can only be on one lock's wait queue + * at a time. When we find blocked_task on a wait queue we can re-search + * with blocked_task equal to that queue's owner, until either blocked_task + * isn't found, or blocked_task is found on a queue owned by my_task. + * + * Note: the above assumption may not be true when handling lock requests + * from a broken NFS client. But broken NFS clients have a lot more to + * worry about than proper deadlock detection anyway... --okir + */ +static int posix_locks_deadlock(struct file_lock *caller_fl, + struct file_lock *block_fl) { - fl_owner_t owner = current->files; struct file_lock *fl; + struct file_lock *bfl; + void *caller_owner, *blocked_owner; + unsigned int caller_pid, blocked_pid; - /* - * Search the lock list for this inode for any POSIX locks. - */ - lock_kernel(); - for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { + caller_owner = caller_fl->fl_owner; + caller_pid = caller_fl->fl_pid; + blocked_owner = block_fl->fl_owner; + blocked_pid = block_fl->fl_pid; + +next_task: + if (caller_owner == blocked_owner && caller_pid == blocked_pid) + return (1); + for (fl = file_lock_table; fl != NULL; fl = fl->fl_nextlink) { + if (fl->fl_owner == NULL || fl->fl_nextblock == NULL) + continue; + for (bfl = fl->fl_nextblock; bfl != fl; bfl = bfl->fl_nextblock) { + if (bfl->fl_owner == blocked_owner && + bfl->fl_pid == blocked_pid) { + if (fl->fl_owner == caller_owner && + fl->fl_pid == caller_pid) { + return (1); + } + blocked_owner = fl->fl_owner; + blocked_pid = fl->fl_pid; + goto next_task; + } + } + } + return (0); +} + +int locks_mandatory_locked(struct inode *inode) +{ + fl_owner_t owner = current->files; + struct file_lock *fl; + + /* + * Search the lock list for this inode for any POSIX locks. + */ + lock_kernel(); + for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { if (!(fl->fl_flags & FL_POSIX)) continue; if (fl->fl_owner != owner) @@ -634,194 +616,6 @@ return error; } -/* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX - * style lock. - */ -static int posix_make_lock(struct file *filp, struct file_lock *fl, - struct flock *l) -{ - loff_t start; - - memset(fl, 0, sizeof(*fl)); - - init_waitqueue_head(&fl->fl_wait); - fl->fl_flags = FL_POSIX; - - switch (l->l_type) { - case F_RDLCK: - case F_WRLCK: - case F_UNLCK: - fl->fl_type = l->l_type; - break; - default: - return (0); - } - - switch (l->l_whence) { - case 0: /*SEEK_SET*/ - start = 0; - break; - case 1: /*SEEK_CUR*/ - start = filp->f_pos; - break; - case 2: /*SEEK_END*/ - start = filp->f_dentry->d_inode->i_size; - break; - default: - return (0); - } - - if (((start += l->l_start) < 0) || (l->l_len < 0)) - return (0); - fl->fl_end = start + l->l_len - 1; - if (l->l_len > 0 && fl->fl_end < 0) - return (0); - fl->fl_start = start; /* we record the absolute position */ - if (l->l_len == 0) - fl->fl_end = OFFSET_MAX; - - fl->fl_file = filp; - fl->fl_owner = current->files; - fl->fl_pid = current->pid; - - return (1); -} - -/* Verify a call to flock() and fill in a file_lock structure with - * an appropriate FLOCK lock. - */ -static int flock_make_lock(struct file *filp, struct file_lock *fl, - unsigned int cmd) -{ - memset(fl, 0, sizeof(*fl)); - - init_waitqueue_head(&fl->fl_wait); - - switch (cmd & ~LOCK_NB) { - case LOCK_SH: - fl->fl_type = F_RDLCK; - break; - case LOCK_EX: - fl->fl_type = F_WRLCK; - break; - case LOCK_UN: - fl->fl_type = F_UNLCK; - break; - default: - return (0); - } - - fl->fl_flags = FL_FLOCK; - fl->fl_start = 0; - fl->fl_end = OFFSET_MAX; - fl->fl_file = filp; - fl->fl_owner = NULL; - - return (1); -} - -/* Determine if lock sys_fl blocks lock caller_fl. POSIX specific - * checking before calling the locks_conflict(). - */ -static int posix_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) -{ - /* POSIX locks owned by the same process do not conflict with - * each other. - */ - if (!(sys_fl->fl_flags & FL_POSIX) || - locks_same_owner(caller_fl, sys_fl)) - return (0); - - return (locks_conflict(caller_fl, sys_fl)); -} - -/* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific - * checking before calling the locks_conflict(). - */ -static int flock_locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) -{ - /* FLOCK locks referring to the same filp do not conflict with - * each other. - */ - if (!(sys_fl->fl_flags & FL_FLOCK) || - (caller_fl->fl_file == sys_fl->fl_file)) - return (0); - - return (locks_conflict(caller_fl, sys_fl)); -} - -/* Determine if lock sys_fl blocks lock caller_fl. Common functionality - * checks for overlapping locks and shared/exclusive status. - */ -static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl) -{ - if (!locks_overlap(caller_fl, sys_fl)) - return (0); - - switch (caller_fl->fl_type) { - case F_RDLCK: - return (sys_fl->fl_type == F_WRLCK); - - case F_WRLCK: - return (1); - - default: - printk("locks_conflict(): impossible lock type - %d\n", - caller_fl->fl_type); - break; - } - return (0); /* This should never happen */ -} - -/* This function tests for deadlock condition before putting a process to - * sleep. The detection scheme is no longer recursive. Recursive was neat, - * but dangerous - we risked stack corruption if the lock data was bad, or - * if the recursion was too deep for any other reason. - * - * We rely on the fact that a task can only be on one lock's wait queue - * at a time. When we find blocked_task on a wait queue we can re-search - * with blocked_task equal to that queue's owner, until either blocked_task - * isn't found, or blocked_task is found on a queue owned by my_task. - * - * Note: the above assumption may not be true when handling lock requests - * from a broken NFS client. But broken NFS clients have a lot more to - * worry about than proper deadlock detection anyway... --okir - */ -static int posix_locks_deadlock(struct file_lock *caller_fl, - struct file_lock *block_fl) -{ - struct file_lock *fl; - struct file_lock *bfl; - void *caller_owner, *blocked_owner; - unsigned int caller_pid, blocked_pid; - - caller_owner = caller_fl->fl_owner; - caller_pid = caller_fl->fl_pid; - blocked_owner = block_fl->fl_owner; - blocked_pid = block_fl->fl_pid; - -next_task: - if (caller_owner == blocked_owner && caller_pid == blocked_pid) - return (1); - for (fl = file_lock_table; fl != NULL; fl = fl->fl_nextlink) { - if (fl->fl_owner == NULL || fl->fl_nextblock == NULL) - continue; - for (bfl = fl->fl_nextblock; bfl != fl; bfl = bfl->fl_nextblock) { - if (bfl->fl_owner == blocked_owner && - bfl->fl_pid == blocked_pid) { - if (fl->fl_owner == caller_owner && - fl->fl_pid == caller_pid) { - return (1); - } - blocked_owner = fl->fl_owner; - blocked_pid = fl->fl_pid; - goto next_task; - } - } - } - return (0); -} - /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks at * the head of the list, but that's secret knowledge known only to the next * two functions. @@ -1091,91 +885,272 @@ return error; } -/* - * Allocate an empty lock structure. We can use GFP_KERNEL now that - * all allocations are done in advance. +/* flock() system call entry point. Apply a FL_FLOCK style lock to + * an open file descriptor. */ -static struct file_lock *locks_empty_lock(void) +asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) { - /* Okay, let's make a new file_lock structure... */ - return ((struct file_lock *) kmalloc(sizeof(struct file_lock), - GFP_KERNEL)); -} + struct file_lock file_lock; + struct file *filp; + int error; -/* - * Initialize a new lock from an existing file_lock structure. - */ -static struct file_lock *locks_init_lock(struct file_lock *new, - struct file_lock *fl) -{ - if (new) { - memset(new, 0, sizeof(*new)); - new->fl_owner = fl->fl_owner; - new->fl_pid = fl->fl_pid; - init_waitqueue_head(&new->fl_wait); - new->fl_file = fl->fl_file; - new->fl_flags = fl->fl_flags; - new->fl_type = fl->fl_type; - new->fl_start = fl->fl_start; - new->fl_end = fl->fl_end; - new->fl_notify = fl->fl_notify; - new->fl_insert = fl->fl_insert; - new->fl_remove = fl->fl_remove; - new->fl_u = fl->fl_u; - } - return new; + lock_kernel(); + error = -EBADF; + filp = fget(fd); + if (!filp) + goto out; + error = -EINVAL; + if (!flock_make_lock(filp, &file_lock, cmd)) + goto out_putf; + error = -EBADF; + if ((file_lock.fl_type != F_UNLCK) && !(filp->f_mode & 3)) + goto out_putf; + error = flock_lock_file(filp, &file_lock, + (cmd & (LOCK_UN | LOCK_NB)) ? 0 : 1); +out_putf: + fput(filp); +out: + unlock_kernel(); + return (error); } -/* Insert file lock fl into an inode's lock list at the position indicated - * by pos. At the same time add the lock to the global file lock list. +/* Report the first existing lock that would conflict with l. + * This implements the F_GETLK command of fcntl(). */ -static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) +int fcntl_getlk(unsigned int fd, struct flock *l) { - fl->fl_nextlink = file_lock_table; - fl->fl_prevlink = NULL; - if (file_lock_table != NULL) - file_lock_table->fl_prevlink = fl; - file_lock_table = fl; - fl->fl_next = *pos; /* insert into file's list */ - *pos = fl; + struct file *filp; + struct file_lock *fl,file_lock; + struct flock flock; + int error; - if (fl->fl_insert) - fl->fl_insert(fl); + error = -EFAULT; + if (copy_from_user(&flock, l, sizeof(flock))) + goto out; + error = -EINVAL; + if ((flock.l_type != F_RDLCK) && (flock.l_type != F_WRLCK)) + goto out; - return; + error = -EBADF; + filp = fget(fd); + if (!filp) + goto out; + + if (!posix_make_lock(filp, &file_lock, &flock)) + goto out_putf; + + if (filp->f_op->lock) { + error = filp->f_op->lock(filp, F_GETLK, &file_lock); + if (error < 0) + goto out_putf; + else if (error == LOCK_USE_CLNT) + /* Bypass for NFS with no locking - 2.0.36 compat */ + fl = posix_test_lock(filp, &file_lock); + else + fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock); + } else { + fl = posix_test_lock(filp, &file_lock); + } + + flock.l_type = F_UNLCK; + if (fl != NULL) { + flock.l_pid = fl->fl_pid; + flock.l_start = fl->fl_start; + flock.l_len = fl->fl_end == OFFSET_MAX ? 0 : + fl->fl_end - fl->fl_start + 1; + flock.l_whence = 0; + flock.l_type = fl->fl_type; + } + error = -EFAULT; + if (!copy_to_user(l, &flock, sizeof(flock))) + error = 0; + +out_putf: + fput(filp); +out: + return error; } -/* Delete a lock and free it. - * First remove our lock from the active lock lists. Then call - * locks_wake_up_blocks() to wake up processes that are blocked - * waiting for this lock. Finally free the lock structure. +/* Apply the lock described by l to an open file descriptor. + * This implements both the F_SETLK and F_SETLKW commands of fcntl(). */ -static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait) +int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l) { - struct file_lock *thisfl; - struct file_lock *prevfl; - struct file_lock *nextfl; - - thisfl = *thisfl_p; - *thisfl_p = thisfl->fl_next; + struct file *filp; + struct file_lock file_lock; + struct flock flock; + struct inode *inode; + int error; - prevfl = thisfl->fl_prevlink; - nextfl = thisfl->fl_nextlink; + /* + * This might block, so we do it before checking the inode. + */ + error = -EFAULT; + if (copy_from_user(&flock, l, sizeof(flock))) + goto out; - if (nextfl != NULL) - nextfl->fl_prevlink = prevfl; + /* Get arguments and validate them ... + */ - if (prevfl != NULL) - prevfl->fl_nextlink = nextfl; - else - file_lock_table = nextfl; + error = -EBADF; + filp = fget(fd); + if (!filp) + goto out; - if (thisfl->fl_remove) - thisfl->fl_remove(thisfl); + error = -EINVAL; + inode = filp->f_dentry->d_inode; + + /* Don't allow mandatory locks on files that may be memory mapped + * and shared. + */ + if (IS_MANDLOCK(inode) && + (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) { + struct vm_area_struct *vma; + struct address_space *mapping = inode->i_mapping; + spin_lock(&mapping->i_shared_lock); + for(vma = mapping->i_mmap;vma;vma = vma->vm_next_share) { + if (!(vma->vm_flags & VM_MAYSHARE)) + continue; + spin_unlock(&mapping->i_shared_lock); + error = -EAGAIN; + goto out_putf; + } + spin_unlock(&mapping->i_shared_lock); + } + + error = -EINVAL; + if (!posix_make_lock(filp, &file_lock, &flock)) + goto out_putf; - locks_wake_up_blocks(thisfl, wait); - locks_free_lock(thisfl); + error = -EBADF; + switch (flock.l_type) { + case F_RDLCK: + if (!(filp->f_mode & FMODE_READ)) + goto out_putf; + break; + case F_WRLCK: + if (!(filp->f_mode & FMODE_WRITE)) + goto out_putf; + break; + case F_UNLCK: + break; + case F_SHLCK: + case F_EXLCK: +#ifdef __sparc__ +/* warn a bit for now, but don't overdo it */ +{ + static int count = 0; + if (!count) { + count=1; + printk(KERN_WARNING + "fcntl_setlk() called by process %d (%s) with broken flock() emulation\n", + current->pid, current->comm); + } +} + if (!(filp->f_mode & 3)) + goto out_putf; + break; +#endif + default: + error = -EINVAL; + goto out_putf; + } + if (filp->f_op->lock != NULL) { + error = filp->f_op->lock(filp, cmd, &file_lock); + if (error < 0) + goto out_putf; + } + error = posix_lock_file(filp, &file_lock, cmd == F_SETLKW); + +out_putf: + fput(filp); +out: + return error; +} + +/* + * This function is called when the file is being removed + * from the task's fd array. + */ +void locks_remove_posix(struct file *filp, fl_owner_t owner) +{ + struct inode * inode = filp->f_dentry->d_inode; + struct file_lock file_lock, *fl; + struct file_lock **before; + + /* + * For POSIX locks we free all locks on this file for the given task. + */ +repeat: + before = &inode->i_flock; + while ((fl = *before) != NULL) { + if ((fl->fl_flags & FL_POSIX) && fl->fl_owner == owner) { + int (*lock)(struct file *, int, struct file_lock *); + lock = filp->f_op->lock; + if (lock) { + file_lock = *fl; + file_lock.fl_type = F_UNLCK; + } + locks_delete_lock(before, 0); + if (lock) { + lock(filp, F_SETLK, &file_lock); + /* List may have changed: */ + goto repeat; + } + continue; + } + before = &fl->fl_next; + } +} + +/* + * This function is called on the last close of an open file. + */ +void locks_remove_flock(struct file *filp) +{ + struct inode * inode = filp->f_dentry->d_inode; + struct file_lock file_lock, *fl; + struct file_lock **before; + +repeat: + before = &inode->i_flock; + while ((fl = *before) != NULL) { + if ((fl->fl_flags & FL_FLOCK) && fl->fl_file == filp) { + int (*lock)(struct file *, int, struct file_lock *); + lock = NULL; + if (filp->f_op) + lock = filp->f_op->lock; + if (lock) { + file_lock = *fl; + file_lock.fl_type = F_UNLCK; + } + locks_delete_lock(before, 0); + if (lock) { + lock(filp, F_SETLK, &file_lock); + /* List may have changed: */ + goto repeat; + } + continue; + } + before = &fl->fl_next; + } +} + +/* The following two are for the benefit of lockd. + */ +void +posix_block_lock(struct file_lock *blocker, struct file_lock *waiter) +{ + locks_insert_block(blocker, waiter); + return; +} + +void +posix_unblock_lock(struct file_lock *waiter) +{ + if (waiter->fl_prevblock) + locks_delete_block(waiter->fl_prevblock, waiter); return; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/minix/bitmap.c linux.ac/fs/minix/bitmap.c --- linux.vanilla/fs/minix/bitmap.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/minix/bitmap.c Mon May 29 19:37:55 2000 @@ -294,16 +294,13 @@ mark_inode_dirty(inode); unlock_super(sb); -printk("m_n_i: allocated inode "); if(DQUOT_ALLOC_INODE(sb, inode)) { -printk("fails quota test\n"); sb->dq_op->drop(inode); inode->i_nlink = 0; iput(inode); *error = -EDQUOT; return NULL; } -printk("is within quota\n"); *error = 0; return inode; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/select.c linux.ac/fs/select.c --- linux.vanilla/fs/select.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/select.c Sat May 27 15:45:55 2000 @@ -52,6 +52,7 @@ if(out==NULL) return NULL; out->nr = 0; + out->err = 0; out->entry = (struct poll_table_entry *)(out + 1); out->next = NULL; nfds -=__MAX_POLL_TABLE_ENTRIES; @@ -97,19 +98,36 @@ void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) { + poll_table* walk = p; for (;;) { - if (p->nr < __MAX_POLL_TABLE_ENTRIES) { + if (walk->nr < __MAX_POLL_TABLE_ENTRIES) { struct poll_table_entry * entry; - entry = p->entry + p->nr; +ok_table: + entry = walk->entry + walk->nr; get_file(filp); entry->filp = filp; entry->wait_address = wait_address; init_waitqueue_entry(&entry->wait, current); add_wait_queue(wait_address,&entry->wait); - p->nr++; + walk->nr++; return; } - p = p->next; + if (walk->next == NULL) { + poll_table *tmp; + current->state=TASK_RUNNING; + tmp = (poll_table *) __get_free_page(GFP_KERNEL); + if (!tmp) { + p->err=-ENOMEM; + return; + } + tmp->nr = 0; + tmp->entry = (struct poll_table_entry *)(tmp + 1); + tmp->next = NULL; + walk->next = tmp; + walk = tmp; + goto ok_table; + } + walk = walk->next; } } @@ -226,11 +244,16 @@ wait = NULL; } } - wait = NULL; if (retval || !__timeout || signal_pending(current)) break; + if(orig_wait->err) { + retval=orig_wait->err; + goto out; + } + wait = NULL; __timeout = schedule_timeout(__timeout); } +out: current->state = TASK_RUNNING; free_wait(orig_wait); @@ -382,6 +405,7 @@ struct pollfd *fds[], poll_table *wait, long timeout) { int count = 0; + poll_table* orig_wait = wait; for (;;) { unsigned int i; @@ -391,11 +415,16 @@ do_pollfd(POLLFD_PER_PAGE, fds[i], &wait, &count); if (nleft) do_pollfd(nleft, fds[nchunks], &wait, &count); - wait = NULL; if (count || !timeout || signal_pending(current)) break; + if(orig_wait->err) { + count=orig_wait->err; + goto out; + } + wait=NULL; timeout = schedule_timeout(timeout); } +out: current->state = TASK_RUNNING; return count; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-alpha/mc146818rtc.h linux.ac/include/asm-alpha/mc146818rtc.h --- linux.vanilla/include/asm-alpha/mc146818rtc.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-alpha/mc146818rtc.h Mon May 29 19:28:27 2000 @@ -0,0 +1,27 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef __ASM_ALPHA_MC146818RTC_H +#define __ASM_ALPHA_MC146818RTC_H + +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* __ASM_ALPHA_MC146818RTC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-alpha/socket.h linux.ac/include/asm-alpha/socket.h --- linux.vanilla/include/asm-alpha/socket.h Thu May 25 17:37:35 2000 +++ linux.ac/include/asm-alpha/socket.h Mon May 29 19:30:52 2000 @@ -50,4 +50,19 @@ #define SO_SECURITY_ENCRYPTION_TRANSPORT 20 #define SO_SECURITY_ENCRYPTION_NETWORK 21 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/mc146818rtc.h linux.ac/include/asm-arm/mc146818rtc.h --- linux.vanilla/include/asm-arm/mc146818rtc.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-arm/mc146818rtc.h Mon May 29 19:28:27 2000 @@ -0,0 +1,27 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* _ASM_MC146818RTC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/socket.h linux.ac/include/asm-arm/socket.h --- linux.vanilla/include/asm-arm/socket.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/socket.h Mon May 29 19:30:52 2000 @@ -41,4 +41,19 @@ #define SO_PEERNAME 28 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-i386/mc146818rtc.h linux.ac/include/asm-i386/mc146818rtc.h --- linux.vanilla/include/asm-i386/mc146818rtc.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-i386/mc146818rtc.h Mon May 29 20:04:28 2000 @@ -0,0 +1,27 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* _ASM_MC146818RTC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-i386/semaphore.h linux.ac/include/asm-i386/semaphore.h --- linux.vanilla/include/asm-i386/semaphore.h Thu May 25 17:37:34 2000 +++ linux.ac/include/asm-i386/semaphore.h Mon May 29 19:59:10 2000 @@ -3,6 +3,8 @@ #include +#ifdef __KERNEL__ + /* * SMP- and interrupt-safe semaphores.. * @@ -372,4 +374,5 @@ __up_write(sem); } +#endif #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-i386/socket.h linux.ac/include/asm-i386/socket.h --- linux.vanilla/include/asm-i386/socket.h Thu May 25 17:37:34 2000 +++ linux.ac/include/asm-i386/socket.h Mon May 29 19:30:52 2000 @@ -41,4 +41,19 @@ #define SO_PEERNAME 28 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-ia64/socket.h linux.ac/include/asm-ia64/socket.h --- linux.vanilla/include/asm-ia64/socket.h Thu May 25 17:37:37 2000 +++ linux.ac/include/asm-ia64/socket.h Mon May 29 19:30:52 2000 @@ -50,4 +50,19 @@ #define SO_PEERNAME 28 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_IA64_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-m68k/socket.h linux.ac/include/asm-m68k/socket.h --- linux.vanilla/include/asm-m68k/socket.h Thu May 25 17:37:35 2000 +++ linux.ac/include/asm-m68k/socket.h Mon May 29 19:30:52 2000 @@ -41,4 +41,19 @@ #define SO_PEERNAME 28 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-mips/socket.h linux.ac/include/asm-mips/socket.h --- linux.vanilla/include/asm-mips/socket.h Thu May 25 17:37:34 2000 +++ linux.ac/include/asm-mips/socket.h Mon May 29 19:30:52 2000 @@ -60,19 +60,19 @@ #define SO_PEERNAME 28 -/* Types of sockets. */ -#define SOCK_DGRAM 1 /* Connectionless, unreliable datagrams - of fixed maximum length. */ -#define SOCK_STREAM 2 /* Sequenced, reliable, connection-based - byte streams. */ -#define SOCK_RAW 3 /* Raw protocol interface. */ -#define SOCK_RDM 4 /* Reliably-delivered messages. */ -#define SOCK_SEQPACKET 5 /* Sequenced, reliable, connection-based, - datagrams of fixed maximum length. */ -#define SOCK_PACKET 10 /* Linux specific way of getting packets at - the dev level. For writing rarp and - other similar things on the user level. */ - -#endif /* __KERNEL__ */ +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_DGRAM 1 /* datagram (conn.less) socket */ +#define SOCK_STREAM 2 /* stream (connection) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-mips64/socket.h linux.ac/include/asm-mips64/socket.h --- linux.vanilla/include/asm-mips64/socket.h Thu May 25 17:37:37 2000 +++ linux.ac/include/asm-mips64/socket.h Mon May 29 19:30:52 2000 @@ -61,22 +61,21 @@ #define SO_ATTACH_FILTER 26 #define SO_DETACH_FILTER 27 -#ifdef __KERNEL__ - #define SO_PEERNAME 28 -/* Types of sockets. */ -#define SOCK_DGRAM 1 /* Connectionless, unreliable datagrams - of fixed maximum length. */ -#define SOCK_STREAM 2 /* Sequenced, reliable, connection-based - byte streams. */ -#define SOCK_RAW 3 /* Raw protocol interface. */ -#define SOCK_RDM 4 /* Reliably-delivered messages. */ -#define SOCK_SEQPACKET 5 /* Sequenced, reliable, connection-based, - datagrams of fixed maximum length. */ -#define SOCK_PACKET 10 /* Linux specific way of getting packets at - the dev level. For writing rarp and - other similar things on the user level. */ -#endif /* __KERNEL__ */ +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_DGRAM 1 /* datagram (conn.less) socket */ +#define SOCK_STREAM 2 /* stream (connection) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-ppc/mc146818rtc.h linux.ac/include/asm-ppc/mc146818rtc.h --- linux.vanilla/include/asm-ppc/mc146818rtc.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-ppc/mc146818rtc.h Mon May 29 19:28:27 2000 @@ -0,0 +1,27 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef __ASM_PPC_MC146818RTC_H +#define __ASM_PPC_MC146818RTC_H + +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* __ASM_PPC_MC146818RTC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-ppc/socket.h linux.ac/include/asm-ppc/socket.h --- linux.vanilla/include/asm-ppc/socket.h Thu May 25 17:37:35 2000 +++ linux.ac/include/asm-ppc/socket.h Mon May 29 19:30:52 2000 @@ -47,4 +47,19 @@ #define SO_PEERNAME 28 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-s390/socket.h linux.ac/include/asm-s390/socket.h --- linux.vanilla/include/asm-s390/socket.h Thu May 25 17:37:37 2000 +++ linux.ac/include/asm-s390/socket.h Mon May 29 19:30:52 2000 @@ -41,20 +41,6 @@ #define SO_SECURITY_ENCRYPTION_TRANSPORT 23 #define SO_SECURITY_ENCRYPTION_NETWORK 24 -#ifdef __KERNEL__ -/* Socket types. */ -#define SOCK_STREAM 1 /* stream (connection) socket */ -#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ -#define SOCK_RAW 3 /* raw socket */ -#define SOCK_RDM 4 /* reliably-delivered message */ -#define SOCK_SEQPACKET 5 /* sequential packet socket */ -#define SOCK_PACKET 10 /* linux specific way of */ - /* getting packets at the dev */ - /* level. For writing rarp and */ - /* other similar things on the */ - /* user level. */ -#endif - #define SO_BINDTODEVICE 25 /* Socket filtering */ @@ -62,5 +48,20 @@ #define SO_DETACH_FILTER 27 #define SO_PEERNAME 28 + +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-sh/socket.h linux.ac/include/asm-sh/socket.h --- linux.vanilla/include/asm-sh/socket.h Thu May 25 17:37:37 2000 +++ linux.ac/include/asm-sh/socket.h Mon May 29 19:30:52 2000 @@ -41,4 +41,19 @@ #define SO_PEERNAME 28 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* __ASM_SH_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-sparc/socket.h linux.ac/include/asm-sparc/socket.h --- linux.vanilla/include/asm-sparc/socket.h Thu May 25 17:37:35 2000 +++ linux.ac/include/asm-sparc/socket.h Mon May 29 19:30:52 2000 @@ -47,4 +47,19 @@ #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 #define SO_SECURITY_ENCRYPTION_NETWORK 0x5004 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-sparc64/socket.h linux.ac/include/asm-sparc64/socket.h --- linux.vanilla/include/asm-sparc64/socket.h Thu May 25 17:37:35 2000 +++ linux.ac/include/asm-sparc64/socket.h Mon May 29 19:30:52 2000 @@ -47,4 +47,19 @@ #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 #define SO_SECURITY_ENCRYPTION_NETWORK 0x5004 +/* Nast libc5 fixup - bletch */ +#if defined(__KERNEL__) +/* Socket types. */ +#define SOCK_STREAM 1 /* stream (connection) socket */ +#define SOCK_DGRAM 2 /* datagram (conn.less) socket */ +#define SOCK_RAW 3 /* raw socket */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequential packet socket */ +#define SOCK_PACKET 10 /* linux specific way of */ + /* getting packets at the dev */ + /* level. For writing rarp and */ + /* other similar things on the */ + /* user level. */ +#endif + #endif /* _ASM_SOCKET_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/ac97_codec.h linux.ac/include/linux/ac97_codec.h --- linux.vanilla/include/linux/ac97_codec.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/ac97_codec.h Mon May 29 20:32:20 2000 @@ -32,7 +32,7 @@ #define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */ #define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */ #define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */ -#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR ADC Rate */ +#define AC97_PCM_LR_DAC_RATE 0x0032 /* PCM LR DAC Rate */ #define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */ #define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */ #define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */ @@ -133,7 +133,7 @@ SOUND_MASK_LINE1| SOUND_MASK_LINE|\ SOUND_MASK_PHONEIN) -#define supported_mixer(CODEC,FOO) ( CODEC->supported_mixers & (1<supported_mixers & (1< -#include /* get the user-level API */ - -#ifndef RTC_PORT -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_ALWAYS_BCD 1 -#endif -#define CMOS_READ(addr) ({ \ -outb_p((addr),RTC_PORT(0)); \ -inb_p(RTC_PORT(1)); \ -}) -#define CMOS_WRITE(val, addr) ({ \ -outb_p((addr),RTC_PORT(0)); \ -outb_p((val),RTC_PORT(1)); \ -}) +#include +#include /* get the user-level API */ +#include /* register access macros */ /********************************************************************** * register summary diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/mm.h linux.ac/include/linux/mm.h --- linux.vanilla/include/linux/mm.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/mm.h Mon May 29 19:59:10 2000 @@ -153,6 +153,7 @@ struct buffer_head * buffers; unsigned long virtual; /* nonzero if kmapped */ struct zone_struct *zone; + unsigned int age; } mem_map_t; #define get_page(p) atomic_inc(&(p)->count) @@ -169,7 +170,7 @@ #define PG_dirty 4 #define PG_decr_after 5 #define PG_unused_01 6 -#define PG__unused_02 7 +#define PG_active 7 #define PG_slab 8 #define PG_swap_cache 9 #define PG_skip 10 @@ -185,6 +186,7 @@ #define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags) #define PageDirty(page) test_bit(PG_dirty, &(page)->flags) #define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags) +#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags) #define PageLocked(page) test_bit(PG_locked, &(page)->flags) #define LockPage(page) set_bit(PG_locked, &(page)->flags) #define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags) @@ -192,6 +194,9 @@ clear_bit(PG_locked, &(page)->flags); \ wake_up(&page->wait); \ } while (0) +#define PageActive(page) test_bit(PG_active, &(page)->flags) +#define SetPageActive(page) set_bit(PG_active, &(page)->flags) +#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags) #define PageError(page) test_bit(PG_error, &(page)->flags) #define SetPageError(page) set_bit(PG_error, &(page)->flags) #define ClearPageError(page) clear_bit(PG_error, &(page)->flags) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/netdevice.h linux.ac/include/linux/netdevice.h --- linux.vanilla/include/linux/netdevice.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/netdevice.h Mon May 29 19:59:10 2000 @@ -13,6 +13,7 @@ * Donald J. Becker, * Alan Cox, * Bjorn Ekwall. + * Pekka Riikonen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -193,6 +194,17 @@ /* + * This structure holds at boot time configured netdevice settings. They + * are then used in the device probing. + */ +struct netdev_boot_setup { + char name[IFNAMSIZ]; + struct ifmap map; +}; +#define NETDEV_BOOT_SETUP_MAX 8 + + +/* * The DEVICE structure. * Actually, this whole structure is a big mistake. It mixes I/O * data with strictly "high-level" data, and it has to know about @@ -389,8 +401,11 @@ extern struct net_device loopback_dev; /* The loopback */ extern struct net_device *dev_base; /* All devices */ -extern rwlock_t dev_base_lock; /* Device list lock */ +extern rwlock_t dev_base_lock; /* Device list lock */ +extern struct netdev_boot_setup dev_boot_setup[]; +extern int netdev_boot_setup_add(char *name, struct ifmap *map); +extern int netdev_boot_setup_check(struct net_device *dev); extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr); extern void dev_add_pack(struct packet_type *pt); extern void dev_remove_pack(struct packet_type *pt); @@ -414,7 +429,7 @@ typedef int gifconf_func_t(struct net_device * dev, char * bufptr, int len); extern int register_gifconf(unsigned int family, gifconf_func_t * gifconf); -extern __inline__ int unregister_gifconf(unsigned int family) +static inline int unregister_gifconf(unsigned int family) { return register_gifconf(family, 0); } @@ -437,7 +452,7 @@ #define HAVE_NETIF_QUEUE -extern __inline__ void __netif_schedule(struct net_device *dev) +static inline void __netif_schedule(struct net_device *dev) { if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) { unsigned long flags; @@ -451,34 +466,34 @@ } } -extern __inline__ void netif_schedule(struct net_device *dev) +static inline void netif_schedule(struct net_device *dev) { if (!test_bit(__LINK_STATE_XOFF, &dev->state)) __netif_schedule(dev); } -extern __inline__ void netif_start_queue(struct net_device *dev) +static inline void netif_start_queue(struct net_device *dev) { clear_bit(__LINK_STATE_XOFF, &dev->state); } -extern __inline__ void netif_wake_queue(struct net_device *dev) +static inline void netif_wake_queue(struct net_device *dev) { if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state)) __netif_schedule(dev); } -extern __inline__ void netif_stop_queue(struct net_device *dev) +static inline void netif_stop_queue(struct net_device *dev) { set_bit(__LINK_STATE_XOFF, &dev->state); } -extern __inline__ int netif_queue_stopped(struct net_device *dev) +static inline int netif_queue_stopped(struct net_device *dev) { return test_bit(__LINK_STATE_XOFF, &dev->state); } -extern __inline__ int netif_running(struct net_device *dev) +static inline int netif_running(struct net_device *dev) { return test_bit(__LINK_STATE_START, &dev->state); } @@ -486,7 +501,7 @@ /* Use this variant when it is known for sure that it * is executing from interrupt context. */ -extern __inline__ void dev_kfree_skb_irq(struct sk_buff *skb) +static inline void dev_kfree_skb_irq(struct sk_buff *skb) { if (atomic_dec_and_test(&skb->users)) { int cpu =smp_processor_id(); @@ -503,7 +518,7 @@ /* Use this variant in places where it could be invoked * either from interrupt or non-interrupt context. */ -extern __inline__ void dev_kfree_skb_any(struct sk_buff *skb) +static inline void dev_kfree_skb_any(struct sk_buff *skb) { if (in_irq()) dev_kfree_skb_irq(skb); @@ -522,14 +537,14 @@ extern int netdev_nit; -extern __inline__ void dev_init_buffers(struct net_device *dev) +static inline void dev_init_buffers(struct net_device *dev) { /* DO NOTHING */ } extern int netdev_finish_unregister(struct net_device *dev); -extern __inline__ void dev_put(struct net_device *dev) +static inline void dev_put(struct net_device *dev) { if (atomic_dec_and_test(&dev->refcnt)) netdev_finish_unregister(dev); @@ -543,32 +558,32 @@ * who is responsible for serialization of these calls. */ -extern __inline__ int netif_carrier_ok(struct net_device *dev) +static inline int netif_carrier_ok(struct net_device *dev) { return !test_bit(__LINK_STATE_NOCARRIER, &dev->state); } extern void __netdev_watchdog_up(struct net_device *dev); -extern __inline__ void netif_carrier_on(struct net_device *dev) +static inline void netif_carrier_on(struct net_device *dev) { clear_bit(__LINK_STATE_NOCARRIER, &dev->state); if (netif_running(dev)) __netdev_watchdog_up(dev); } -extern __inline__ void netif_carrier_off(struct net_device *dev) +static inline void netif_carrier_off(struct net_device *dev) { set_bit(__LINK_STATE_NOCARRIER, &dev->state); } /* Hot-plugging. */ -extern __inline__ int netif_device_present(struct net_device *dev) +static inline int netif_device_present(struct net_device *dev) { return test_bit(__LINK_STATE_PRESENT, &dev->state); } -extern __inline__ void netif_device_detach(struct net_device *dev) +static inline void netif_device_detach(struct net_device *dev) { if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) && netif_running(dev)) { @@ -576,7 +591,7 @@ } } -extern __inline__ void netif_device_attach(struct net_device *dev) +static inline void netif_device_attach(struct net_device *dev) { if (!test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) && netif_running(dev)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/pci_ids.h linux.ac/include/linux/pci_ids.h --- linux.vanilla/include/linux/pci_ids.h Thu May 25 17:46:16 2000 +++ linux.ac/include/linux/pci_ids.h Mon May 29 20:02:56 2000 @@ -190,6 +190,8 @@ #define PCI_VENDOR_ID_NS 0x100b #define PCI_DEVICE_ID_NS_87415 0x0002 +#define PCI_DEVICE_ID_NS_87560_LIO 0x000e +#define PCI_DEVICE_ID_NS_87560_USB 0x0012 #define PCI_DEVICE_ID_NS_87410 0xd001 #define PCI_VENDOR_ID_TSENG 0x100c @@ -545,6 +547,8 @@ #define PCI_DEVICE_ID_DATABOOK_87144 0xb106 #define PCI_VENDOR_ID_PLX 0x10b5 +#define PCI_VENDOR_ID_PLX_ROMULUS 0x106a +#define PCI_DEVICE_ID_PLX_SPCOM800 0x1076 #define PCI_DEVICE_ID_PLX_SPCOM200 0x1103 #define PCI_DEVICE_ID_PLX_9050 0x9050 #define PCI_DEVICE_ID_PLX_9060 0x9060 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/poll.h linux.ac/include/linux/poll.h --- linux.vanilla/include/linux/poll.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/poll.h Mon May 29 19:59:10 2000 @@ -20,6 +20,7 @@ typedef struct poll_table_struct { struct poll_table_struct * next; unsigned int nr; + int err; struct poll_table_entry * entry; } poll_table; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/swap.h linux.ac/include/linux/swap.h --- linux.vanilla/include/linux/swap.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/swap.h Mon May 29 19:59:14 2000 @@ -168,12 +168,15 @@ spin_lock(&pagemap_lru_lock); \ list_add(&(page)->lru, &lru_cache); \ nr_lru_pages++; \ + page->age = 2; \ + SetPageActive(page); \ spin_unlock(&pagemap_lru_lock); \ } while (0) #define __lru_cache_del(page) \ do { \ list_del(&(page)->lru); \ + ClearPageActive(page); \ nr_lru_pages--; \ } while (0) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/timer.h linux.ac/include/linux/timer.h --- linux.vanilla/include/linux/timer.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/timer.h Sat May 27 22:07:51 2000 @@ -1,6 +1,8 @@ #ifndef _LINUX_TIMER_H #define _LINUX_TIMER_H +#ifdef __KERNEL__ + #include #include @@ -111,4 +113,5 @@ #define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) #define time_before_eq(a,b) time_after_eq(b,a) +#endif #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/types.h linux.ac/include/linux/types.h --- linux.vanilla/include/linux/types.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/types.h Sat May 27 22:01:22 2000 @@ -1,7 +1,10 @@ #ifndef _LINUX_TYPES_H #define _LINUX_TYPES_H +#ifdef __KERNEL__ #include +#endif + #include #include diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/usb.h linux.ac/include/linux/usb.h --- linux.vanilla/include/linux/usb.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/usb.h Mon May 29 20:25:23 2000 @@ -307,6 +307,8 @@ struct file_operations *fops; int minor; + + struct semaphore serialize; }; /* @@ -492,7 +494,7 @@ int bandwidth_isoc_reqs; /* number of Isoc. requesters */ /* usbdevfs inode list */ - struct list_head inodes; + struct list_head inodes; }; #define USB_MAXCHILDREN (8) /* This is arbitrary */ @@ -506,7 +508,6 @@ unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */ unsigned int halted[2]; /* endpoint halts; one bit per endpoint # & direction; */ /* [0] = IN, [1] = OUT */ - struct usb_config_descriptor *actconfig;/* the active configuration */ int epmaxpacketin[16]; /* INput endpoint specific maximums */ int epmaxpacketout[16]; /* OUTput endpoint specific maximums */ @@ -515,6 +516,9 @@ struct usb_device_descriptor descriptor;/* Descriptor */ struct usb_config_descriptor *config; /* All of the configs */ + struct usb_config_descriptor *actconfig;/* the active configuration */ + + char **rawdescriptors; /* Raw descriptors for each config */ int have_langid; /* whether string_langid is valid yet */ int string_langid; /* language ID for strings */ @@ -522,8 +526,8 @@ void *hcpriv; /* Host Controller private data */ /* usbdevfs inode list */ - struct list_head inodes; - struct list_head filelist; + struct list_head inodes; + struct list_head filelist; /* * Child devices - these can be either new devices @@ -536,6 +540,8 @@ int maxchild; /* Number of ports if hub */ struct usb_device *children[USB_MAXCHILDREN]; }; + +extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum); extern int usb_register(struct usb_driver *); extern void usb_deregister(struct usb_driver *); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/usbdevice_fs.h linux.ac/include/linux/usbdevice_fs.h --- linux.vanilla/include/linux/usbdevice_fs.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/usbdevice_fs.h Mon May 29 20:35:12 2000 @@ -66,6 +66,18 @@ void *context; }; +#define USBDEVFS_MAXDRIVERNAME 255 + +struct usbdevfs_getdriver { + unsigned int interface; + char driver[USBDEVFS_MAXDRIVERNAME + 1]; +}; + +struct usbdevfs_connectinfo { + unsigned int devnum; + unsigned char slow; +}; + #define USBDEVFS_URB_DISABLE_SPD 1 #define USBDEVFS_URB_ISO_ASAP 2 @@ -101,6 +113,7 @@ #define USBDEVFS_RESETEP _IOR('U', 3, unsigned int) #define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface) #define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int) +#define USBDEVFS_GETDRIVER _IOW('U', 8, struct usbdevfs_getdriver) #define USBDEVFS_SUBMITURB _IOR('U', 10, struct usbdevfs_urb) #define USBDEVFS_DISCARDURB _IO('U', 11) #define USBDEVFS_REAPURB _IOW('U', 12, void *) @@ -108,6 +121,7 @@ #define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal) #define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int) #define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) +#define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo) /* --------------------------------------------------------------------- */ @@ -164,7 +178,6 @@ extern struct inode_operations usbdevfs_bus_inode_operations; extern struct file_operations usbdevfs_bus_file_operations; extern void usbdevfs_conn_disc_event(void); - #endif /* __KERNEL__ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/init/main.c linux.ac/init/main.c --- linux.vanilla/init/main.c Thu May 25 17:46:16 2000 +++ linux.ac/init/main.c Thu May 25 17:59:08 2000 @@ -737,7 +737,8 @@ #ifdef CONFIG_BLK_DEV_INITRD root_mountflags = real_root_mountflags; - if (mount_initrd && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) { + if (mount_initrd && ROOT_DEV != real_root_dev + && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) { int error; int i, pid; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/ksyms.c linux.ac/kernel/ksyms.c --- linux.vanilla/kernel/ksyms.c Thu May 25 17:46:17 2000 +++ linux.ac/kernel/ksyms.c Sat May 27 22:00:30 2000 @@ -294,6 +294,8 @@ EXPORT_SYMBOL(max_sectors); EXPORT_SYMBOL(max_readahead); EXPORT_SYMBOL(file_moveto); +EXPORT_SYMBOL(drive_stat_acct); +EXPORT_SYMBOL(set_bh_page); /* tty routines */ EXPORT_SYMBOL(tty_hangup); @@ -495,6 +497,7 @@ /* all busmice */ EXPORT_SYMBOL(fasync_helper); +EXPORT_SYMBOL(kill_fasync); #ifdef CONFIG_BLK_DEV_MD EXPORT_SYMBOL(disk_name); /* for md.c */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/sysctl.c linux.ac/kernel/sysctl.c --- linux.vanilla/kernel/sysctl.c Thu May 25 17:37:33 2000 +++ linux.ac/kernel/sysctl.c Thu May 25 23:36:46 2000 @@ -255,9 +255,9 @@ 0444, NULL, &proc_dointvec}, {FS_STATINODE, "inode-state", &inodes_stat, 7*sizeof(int), 0444, NULL, &proc_dointvec}, - {FS_NRFILE, "file-nr", &nr_files, 3*sizeof(int), + {FS_NRFILE, "file-nr", &files_stat, 3*sizeof(int), 0444, NULL, &proc_dointvec}, - {FS_MAXFILE, "file-max", &max_files, sizeof(int), + {FS_MAXFILE, "file-max", &files_stat.max_files, sizeof(int), 0644, NULL, &proc_dointvec}, {FS_NRSUPER, "super-nr", &nr_super_blocks, sizeof(int), 0444, NULL, &proc_dointvec}, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/mm/filemap.c linux.ac/mm/filemap.c --- linux.vanilla/mm/filemap.c Thu May 25 17:37:33 2000 +++ linux.ac/mm/filemap.c Sat May 27 21:58:35 2000 @@ -264,7 +264,16 @@ page = list_entry(page_lru, struct page, lru); list_del(page_lru); - if (PageTestandClearReferenced(page)) + if (PageTestandClearReferenced(page)) { + page->age += 3; + if (page->age > 10) + page->age = 10; + goto dispose_continue; + } + if (page->age) + page->age--; + + if (page->age) goto dispose_continue; count--; @@ -317,28 +326,34 @@ goto cache_unlock_continue; /* + * Page is from a zone we don't care about. + * Don't drop page cache entries in vain. + */ + if (page->zone->free_pages > page->zone->pages_high) + goto cache_unlock_continue; + + /* * Is it a page swap page? If so, we want to * drop it if it is no longer used, even if it * were to be marked referenced.. */ if (PageSwapCache(page)) { - spin_unlock(&pagecache_lock); - __delete_from_swap_cache(page); - goto made_inode_progress; - } - - /* - * Page is from a zone we don't care about. - * Don't drop page cache entries in vain. - */ - if (page->zone->free_pages > page->zone->pages_high) + if (!PageDirty(page)) { + spin_unlock(&pagecache_lock); + __delete_from_swap_cache(page); + goto made_inode_progress; + } + /* PageDeferswap -> we swap out the page now. */ + if (gfp_mask & __GFP_IO) + goto async_swap; goto cache_unlock_continue; + } /* is it a page-cache page? */ if (page->mapping) { if (!PageDirty(page) && !pgcache_under_min()) { - __remove_inode_page(page); spin_unlock(&pagecache_lock); + __remove_inode_page(page); goto made_inode_progress; } goto cache_unlock_continue; @@ -351,6 +366,14 @@ unlock_continue: spin_lock(&pagemap_lru_lock); UnlockPage(page); + page_cache_release(page); + goto dispose_continue; +async_swap: + spin_unlock(&pagecache_lock); + /* Do NOT unlock the page ... that is done after IO. */ + ClearPageDirty(page); + rw_swap_page(WRITE, page, 0); + spin_lock(&pagemap_lru_lock); page_cache_release(page); dispose_continue: list_add(page_lru, &lru_cache); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/mm/page_alloc.c linux.ac/mm/page_alloc.c --- linux.vanilla/mm/page_alloc.c Thu May 25 17:37:33 2000 +++ linux.ac/mm/page_alloc.c Sat May 27 21:58:35 2000 @@ -93,6 +93,8 @@ BUG(); if (PageDecrAfter(page)) BUG(); + if (PageDirty(page)) + BUG(); zone = page->zone; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/mm/swap_state.c linux.ac/mm/swap_state.c --- linux.vanilla/mm/swap_state.c Thu May 25 17:37:33 2000 +++ linux.ac/mm/swap_state.c Sat May 27 21:58:35 2000 @@ -73,6 +73,7 @@ PAGE_BUG(page); PageClearSwapCache(page); + ClearPageDirty(page); remove_inode_page(page); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/mm/vmscan.c linux.ac/mm/vmscan.c --- linux.vanilla/mm/vmscan.c Thu May 25 17:37:33 2000 +++ linux.ac/mm/vmscan.c Sat May 27 21:58:35 2000 @@ -62,6 +62,10 @@ goto out_failed; } + /* Can only do this if we age all active pages. */ + if (PageActive(page) && page->age > 1) + goto out_failed; + if (TryLockPage(page)) goto out_failed; @@ -74,6 +78,8 @@ * memory, and we should just continue our scan. */ if (PageSwapCache(page)) { + if (pte_dirty(pte)) + SetPageDirty(page); entry.val = page->index; swap_duplicate(entry); set_pte(page_table, swp_entry_to_pte(entry)); @@ -181,7 +187,10 @@ vmlist_access_unlock(vma->vm_mm); /* OK, do a physical asynchronous write to swap. */ - rw_swap_page(WRITE, page, 0); + // rw_swap_page(WRITE, page, 0); + /* Let shrink_mmap handle this swapout. */ + SetPageDirty(page); + UnlockPage(page); out_free_success: page_cache_release(page); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/core/dev.c linux.ac/net/core/dev.c --- linux.vanilla/net/core/dev.c Thu May 25 17:37:37 2000 +++ linux.ac/net/core/dev.c Thu May 25 20:28:46 2000 @@ -17,6 +17,7 @@ * David Hinds * Alexey Kuznetsov * Adam Sulmicki + * Pekka Riikonen * * Changes: * Alan Cox : device private ioctl copies fields back. @@ -56,6 +57,7 @@ * A network device unload needs to purge * the backlog queue. * Paul Rusty Russell : SIOCSIFNAME + * Pekka Riikonen : Netdev boot-time settings code */ #include @@ -249,6 +251,120 @@ printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt); } +/****************************************************************************** + + Device Boot-time Settings Routines + +*******************************************************************************/ + +/* Boot time configuration table */ +struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX]; + +/** + * netdev_boot_setup_add - add new setup entry + * @name: name of the device + * @map: configured settings for the device + * + * Adds new setup entry to the dev_boot_setup list. The function + * returns 0 on error and 1 on success. This is a generic routine to + * all netdevices. + */ +int netdev_boot_setup_add(char *name, struct ifmap *map) +{ + struct netdev_boot_setup *s; + int i; + + s = dev_boot_setup; + for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) { + if (s[i].name[0] == '\0' || s[i].name[0] == ' ') { + memset(s[i].name, 0, sizeof(s[i].name)); + strcpy(s[i].name, name); + memcpy(&s[i].map, map, sizeof(s[i].map)); + break; + } + } + + if (i >= NETDEV_BOOT_SETUP_MAX) + return 0; + + return 1; +} + +/** + * netdev_boot_setup_check - check boot time settings + * @dev: the netdevice + * + * Check boot time settings for the device. If device's name is a + * mask (eg. eth%d) and settings are found then this will allocate + * name for the device. The found settings are set for the device + * to be used later in the device probing. Returns 0 if no settings + * found, 1 if they are. + */ +int netdev_boot_setup_check(struct net_device *dev) +{ + struct netdev_boot_setup *s; + char buf[IFNAMSIZ + 1]; + int i, mask = 0; + + memset(buf, 0, sizeof(buf)); + strcpy(buf, dev->name); + if (strchr(dev->name, '%')) { + *strchr(buf, '%') = '\0'; + mask = 1; + } + + s = dev_boot_setup; + for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) { + if (s[i].name[0] != '\0' && s[i].name[0] != ' ' && + !strncmp(buf, s[i].name, mask ? strlen(buf) : + strlen(s[i].name))) { + if (__dev_get_by_name(s[i].name)) { + if (!mask) + return 0; + continue; + } + memset(dev->name, 0, IFNAMSIZ); + strcpy(dev->name, s[i].name); + dev->irq = s[i].map.irq; + dev->base_addr = s[i].map.base_addr; + dev->mem_start = s[i].map.mem_start; + dev->mem_end = s[i].map.mem_end; + return 1; + } + } + + return 0; +} + +/* + * Saves at boot time configured settings for any netdevice. + */ +static int __init netdev_boot_setup(char *str) +{ + int ints[5]; + struct ifmap map; + + str = get_options(str, ARRAY_SIZE(ints), ints); + if (!str || !*str) + return 0; + + /* Save settings */ + memset(&map, -1, sizeof(map)); + if (ints[0] > 0) + map.irq = ints[1]; + if (ints[0] > 1) + map.base_addr = ints[2]; + if (ints[0] > 2) + map.mem_start = ints[3]; + if (ints[0] > 3) + map.mem_end = ints[4]; + + /* Add new entry to the list */ + return netdev_boot_setup_add(str, &map); +} + +__setup("netdev=", netdev_boot_setup); + /***************************************************************************************** Device Interface Subroutines @@ -2364,12 +2480,19 @@ dev->xmit_lock_owner = -1; dev->iflink = -1; dev_hold(dev); - /* - * We can allocate the name ahead of time. If the - * init fails the name will be reissued correctly. + + /* + * Check boot time settings for the device. */ - if (strchr(dev->name, '%')) - dev_alloc_name(dev, dev->name); + if (!netdev_boot_setup_check(dev)) { + /* + * No settings found - allocate name. If the init() + * fails the name will be reissued correctly. + */ + if (strchr(dev->name, '%')) + dev_alloc_name(dev, dev->name); + } + if (dev->init && dev->init(dev)) { /* * It failed to come up. Unhook it. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/decnet/dn_nsp_in.c linux.ac/net/decnet/dn_nsp_in.c --- linux.vanilla/net/decnet/dn_nsp_in.c Thu May 25 17:37:38 2000 +++ linux.ac/net/decnet/dn_nsp_in.c Sat May 27 22:00:30 2000 @@ -440,7 +440,7 @@ wake_up_interruptible(sk->sleep); if (sock && sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) - kill_fasync(sock->fasync_list, sig, + __kill_fasync(sock->fasync_list, sig, (sig == SIGURG) ? POLL_PRI : POLL_IN); } read_unlock(&sk->callback_lock); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/ethernet/eth.c linux.ac/net/ethernet/eth.c --- linux.vanilla/net/ethernet/eth.c Thu May 25 17:37:37 2000 +++ linux.ac/net/ethernet/eth.c Thu May 25 20:28:46 2000 @@ -63,31 +63,25 @@ static int __init eth_setup(char *str) { int ints[5]; - struct net_device *d; + struct ifmap map; str = get_options(str, ARRAY_SIZE(ints), ints); - if (!str || !*str) return 0; - d = dev_base; - while (d) - { - if (!strcmp(str,d->name)) - { - if (ints[0] > 0) - d->irq=ints[1]; - if (ints[0] > 1) - d->base_addr=ints[2]; - if (ints[0] > 2) - d->mem_start=ints[3]; - if (ints[0] > 3) - d->mem_end=ints[4]; - break; - } - d=d->next; - } - return 1; + /* Save settings */ + memset(&map, -1, sizeof(map)); + if (ints[0] > 0) + map.irq = ints[1]; + if (ints[0] > 1) + map.base_addr = ints[2]; + if (ints[0] > 2) + map.mem_start = ints[3]; + if (ints[0] > 3) + map.mem_end = ints[4]; + + /* Add new entry to the list */ + return netdev_boot_setup_add(str, &map); } __setup("ether=", eth_setup); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/ipv4/netfilter/ipfwadm_core.c linux.ac/net/ipv4/netfilter/ipfwadm_core.c --- linux.vanilla/net/ipv4/netfilter/ipfwadm_core.c Thu May 25 17:37:38 2000 +++ linux.ac/net/ipv4/netfilter/ipfwadm_core.c Tue Apr 25 17:42:49 2000 @@ -1094,7 +1094,6 @@ } #endif /* CONFIG_IP_FIREWALL */ -#ifdef CONFIG_PROC_FS #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT) static int ip_chain_procinfo(int stage, char *buffer, char **start, @@ -1252,7 +1251,6 @@ return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length, reset); } -#endif #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/netsyms.c linux.ac/net/netsyms.c --- linux.vanilla/net/netsyms.c Thu May 25 17:37:38 2000 +++ linux.ac/net/netsyms.c Sat May 27 22:00:30 2000 @@ -196,7 +196,7 @@ /* Needed by unix.o */ EXPORT_SYMBOL(scm_fp_dup); -EXPORT_SYMBOL(max_files); +EXPORT_SYMBOL(files_stat); EXPORT_SYMBOL(memcpy_toiovec); EXPORT_SYMBOL(csum_partial); @@ -522,7 +522,7 @@ EXPORT_SYMBOL(dev_mc_upload); EXPORT_SYMBOL(n_tty_ioctl); EXPORT_SYMBOL(tty_register_ldisc); -EXPORT_SYMBOL(kill_fasync); +EXPORT_SYMBOL(__kill_fasync); EXPORT_SYMBOL(if_port_text); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/socket.c linux.ac/net/socket.c --- linux.vanilla/net/socket.c Thu May 25 17:37:37 2000 +++ linux.ac/net/socket.c Sat May 27 22:00:30 2000 @@ -697,10 +697,10 @@ /* fall through */ case 0: call_kill: - kill_fasync(sock->fasync_list, SIGIO, band); + __kill_fasync(sock->fasync_list, SIGIO, band); break; case 3: - kill_fasync(sock->fasync_list, SIGURG, band); + __kill_fasync(sock->fasync_list, SIGURG, band); } return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/unix/af_unix.c linux.ac/net/unix/af_unix.c --- linux.vanilla/net/unix/af_unix.c Thu May 25 17:37:37 2000 +++ linux.ac/net/unix/af_unix.c Thu May 25 23:36:46 2000 @@ -445,7 +445,7 @@ { struct sock *sk; - if (atomic_read(&unix_nr_socks) >= 2*max_files) + if (atomic_read(&unix_nr_socks) >= 2*files_stat.max_files) return NULL; MOD_INC_USE_COUNT; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/scripts/lxdialog/Makefile linux.ac/scripts/lxdialog/Makefile --- linux.vanilla/scripts/lxdialog/Makefile Thu May 25 17:38:37 2000 +++ linux.ac/scripts/lxdialog/Makefile Sat May 27 15:35:16 2000 @@ -1,20 +1,16 @@ -CC = $(HOSTCC) -CPP = $(HOSTCC) -E - -CFLAGS = $(HOSTCFLAGS) -DLOCALE -LDFLAGS = -s -L . -LDLIBS = -lncurses +HOSTCFLAGS += -DLOCALE +LIBS = -lncurses ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) - CFLAGS += -I/usr/include/ncurses -DCURSES_LOC="" + HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="" else ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) - CFLAGS += -I/usr/include/ncurses -DCURSES_LOC="" + HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="" else ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) - CFLAGS += -DCURSES_LOC="" + HOSTCFLAGS += -DCURSES_LOC="" else - CFLAGS += -DCURSES_LOC="" + HOSTCFLAGS += -DCURSES_LOC="" endif endif endif @@ -22,16 +18,18 @@ OBJS = checklist.o menubox.o textbox.o yesno.o inputbox.o \ util.o lxdialog.o msgbox.o -SRCS = $(OBJS:.o=.c) +%.o: %.c + $(HOSTCC) $(HOSTCFLAGS) -c -o $@ $< all: ncurses lxdialog lxdialog: $(OBJS) + $(HOSTCC) -o lxdialog $(OBJS) $(LIBS) ncurses: @echo "main() {}" > lxtemp.c - @if $(CC) -lncurses lxtemp.c ; then \ + @if $(HOSTCC) -lncurses lxtemp.c ; then \ rm -f lxtemp.c a.out; \ else \ rm -f lxtemp.c; \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/scripts/tkparse.c linux.ac/scripts/tkparse.c --- linux.vanilla/scripts/tkparse.c Thu May 25 17:38:37 2000 +++ linux.ac/scripts/tkparse.c Fri May 26 15:25:23 2000 @@ -173,6 +173,28 @@ /* + * Get a quoted or unquoted string. It is recognized by the first + * non-white character. '"' and '"' are not allowed inside the string. + */ +static const char * get_qnqstring( const char * pnt, char ** label ) +{ + char quote_char; + + while ( *pnt == ' ' || *pnt == '\t' ) + pnt++; + + if ( *pnt == '\0' ) + return pnt; + quote_char = *pnt; + if ( quote_char == '"' || quote_char == '\'' ) + return get_qstring( pnt, label ); + else + return get_string( pnt, label ); +} + + + +/* * Tokenize an 'if' statement condition. */ static struct condition * tokenize_if( const char * pnt ) @@ -505,6 +527,8 @@ if ( last_menuoption != NULL ) { pnt = get_qstring(pnt, &cfg->label); + if (cfg->label == NULL) + syntax_error( "missing comment text" ); last_menuoption->label = cfg->label; last_menuoption = NULL; } @@ -546,7 +570,9 @@ case token_define_string: pnt = get_string( pnt, &buffer ); cfg->nameindex = get_varnum( buffer ); - pnt = get_qstring( pnt, &cfg->value ); + pnt = get_qnqstring( pnt, &cfg->value ); + if (cfg->value == NULL) + syntax_error( "missing value" ); break; case token_dep_bool: @@ -659,7 +685,9 @@ pnt = get_qstring ( pnt, &cfg->label ); pnt = get_string ( pnt, &buffer ); cfg->nameindex = get_varnum( buffer ); - pnt = get_qstring ( pnt, &cfg->value ); + pnt = get_qnqstring ( pnt, &cfg->value ); + if (cfg->value == NULL) + syntax_error( "missing initial value" ); break; case token_if: