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 Tue May 30 16:49:42 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 @@ -1109,6 +1110,14 @@ S: D-71679 Asperg S: Germany +N: Gareth Hughes +E: gareth@valinux.com +E: gareth@precisioninsight.com +D: Pentium III FXSR, SSE support +S: 11/187 West Street +S: Crows Nest NSW 2065 +S: Australia + N: Kenn Humborg E: kenn@wombat.ie D: Mods to loop device to support sparse backing files @@ -2102,6 +2111,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 +2172,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/Changes linux.ac/Documentation/Changes --- linux.vanilla/Documentation/Changes Thu May 25 17:38:38 2000 +++ linux.ac/Documentation/Changes Tue May 30 14:43:44 2000 @@ -72,13 +72,6 @@ General Information =================== - To use System V shared memory, you have to mount the shm filesystem -somewhere. You can do that automatically by adding this line to /etc/fstab: - -none /var/shm shm defaults 0 0 - -Remember to create the mountpoint directory; it does not have to be /var/shm. - now performs a cold reboot instead of a warm reboot for increased hardware compatibility. If you want a warm reboot and know it works on your hardware, add a "reboot=warm" command line option 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 Tue May 30 21:28:07 2000 @@ -9,8 +9,8 @@ # http://www.linux.or.jp/JF/JFdocs/Configure.help/ # - Russian, by kaf@linux.nevod.perm.su, at # http://nevod.perm.su/service/linux/doc/kernel/Configure.help -# - French, by Tane Pierre (tanep@bigfoot.com), at -# http://www.kernelfr.org +# - French, by Pierre Tane (tanep@bigfoot.com), at +# http://www.traduc.org/kernelfr # - Spanish, by Carlos Perelló Marín (fperllo@ehome.encis.es), at # http://visar.csustan.edu/~carlos/ # - Italian, by Alessandro Rubini (rubini@linux.it), at @@ -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 @@ -9584,7 +9584,7 @@ USB Human Interface Device (HID) support CONFIG_USB_HID Say Y here if you want to connect keyboards, mice, joysticks, - graphic tablets, UPS's or any other HID based devices to your + graphic tablets, or any other HID based devices to your computer via USB. More information is available: Documentation/usb/input.txt. @@ -9616,16 +9616,16 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usbmouse.o. If you want to compile it as a - module, say M here and read Documentation/modules.txt. + The module will be called usbmouse.o. If you want to compile it as + a module, say M here and read Documentation/modules.txt. If unsure, say N. Wacom Intuos/Graphire tablet support CONFIG_USB_WACOM - Say Y here if you want to use the USB version of the Wacom Intuos or - Graphire tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and "Event interface support" + Say Y here if you want to use the USB version of the Wacom Intuos + or Graphire tablet. Make sure to say Y to "Mouse support" + (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. This driver is also available as a module ( = code which can be @@ -9636,7 +9636,7 @@ Logitech WingMan Force joystick support CONFIG_USB_WMFORCE Say Y here if you want to use the Logitech WingMan Force with Linux - on the USB port. No force-feedback support yet, but other than that, + on the USB port. No force-feedback support yet, but other than that it should work like a normal joystick. This driver is also available as a module ( = code which can be @@ -9657,31 +9657,35 @@ Mouse support CONFIG_INPUT_MOUSEDEV Say Y here if you want your USB HID mouse to be accessible as - misc devices 32+ under /dev/, as an emulated PS/2 mouse. That way, - all user space programs will be able to use your mouse. + char devices 13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice + as an emulated PS/2 mouse. That way, all user space programs will + be able to use your mouse. If unsure, say Y. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called mousedev.o. If you want to compile it as a - module, say M here and read Documentation/modules.txt. + The module will be called mousedev.o. If you want to compile it as + a module, say M here and read Documentation/modules.txt. Horizontal screen resolution CONFIG_INPUT_MOUSEDEV_SCREEN_X - For the mouse emulation to be correct, the mousedev driver needs to - know the screen resolution you are using (in the X window system). + If you're using a digitizer, or a graphic tablet, and want to use + it as a mouse then the mousedev driver needs to know the X window + screen resolution you are using to correctly scale the data. If + you're not using a digitizer, this value is ignored. Vertical screen resolution CONFIG_INPUT_MOUSEDEV_SCREEN_Y - For the mouse emulation to be correct, the mousedev driver needs to - know the screen resolution you are using (in the X window system). + If you're using a digitizer, or a graphic tablet, and want to use + it as a mouse then the mousedev driver needs to know the X window + screen resolution you are using to correctly scale the data. If + you're not using a digitizer, this value is ignored. Joystick support CONFIG_INPUT_JOYDEV Say Y here if you want your USB HID joystick or gamepad to be - accessible as a /dev/js device. You can't use a normal (non-USB) - joystick if you say Y here. + accessible as char device 13:0+ - /dev/input/jsX device. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -9691,7 +9695,7 @@ Event interface support CONFIG_INPUT_EVDEV Say Y here if you want your USB HID device events be accessible - under /dev/inputX (misc 64+) in a generic way. + under char device 13:64+ - /dev/inputX in a generic way. This is the future ... USB Scanner support diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/DocBook/Makefile linux.ac/Documentation/DocBook/Makefile --- linux.vanilla/Documentation/DocBook/Makefile Thu May 25 17:46:15 2000 +++ linux.ac/Documentation/DocBook/Makefile Tue May 30 21:03:32 2000 @@ -2,6 +2,10 @@ PS := $(patsubst %.sgml, %.ps, $(BOOKS)) PDF := $(patsubst %.sgml, %.pdf, $(BOOKS)) +HTML := $(patsubst %.sgml, %, $(BOOKS)) +IMG-parportbook := parport-share.fig parport-multi.fig parport-structure.fig +EPS-parportbook := $(patsubst %.fig, %.eps, $(IMG-parportbook)) +JPG-parportbook := $(patsubst %.fig, %.jpeg, $(IMG-parportbook)) $(BOOKS): $(TOPDIR)/scripts/docproc @@ -13,7 +17,9 @@ pdf: $(PDF) -db2ps db2pdf: +html: $(HTML) + +db2ps db2pdf db2html: @(which $@ > /dev/null 2>&1) || \ (echo "*** You need to install DocBook stylesheets ***"; \ exit 1) @@ -21,6 +27,9 @@ %.eps: %.fig -fig2dev -Leps $< $@ +%.jpeg: %.fig + -fig2dev -Ljpeg $< $@ + $(TOPDIR)/scripts/docproc: $(MAKE) -C $(TOPDIR)/scripts docproc @@ -66,6 +75,8 @@ $(TOPDIR)/net/netsyms.c \ kernel-api.sgml +parportbook: $(JPG-parportbook) +parportbook.ps: $(EPS-parportbook) parportbook.sgml: parportbook.tmpl $(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/parport/init.c \ parportbook.sgml @@ -79,18 +90,22 @@ -$(RM) core *~ -$(RM) $(BOOKS) -$(RM) $(DVI) $(AUX) $(TEX) $(LOG) - -$(RM) parport-share.eps parport-multi.eps parport-structure.eps + -$(RM) $(JPG-parportbook) $(EPS-parportbook) mrproper: clean -$(RM) $(PS) $(PDF) - -parportbook.ps: parport-share.eps parport-multi.eps parport-structure.eps + -$(RM) -r $(HTML) %.ps : %.sgml db2ps db2ps $< -%.pdf : %.sgml +%.pdf : %.sgml db2pdf db2pdf $< + +%: %.sgml db2html + -$(RM) -r $@ + db2html $< + if [ ! -z "$(JPG-$@)" ]; then cp $(JPG-$@) $@; fi include $(TOPDIR)/Rules.make 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/networking/tulip.txt linux.ac/Documentation/networking/tulip.txt --- linux.vanilla/Documentation/networking/tulip.txt Thu May 25 17:38:38 2000 +++ linux.ac/Documentation/networking/tulip.txt Tue May 30 21:05:51 2000 @@ -142,6 +142,20 @@ Version history =============== +0.9.5 (May 30, 2000): +* HPPA support (willy@puffingroup) +* CSR6 bits and tulip.h cleanup (Chris Smith) +* Improve debugging messages a bit +* Add delay after CSR13 write in t21142_start_nway +* Remove unused ETHER_STATS code +* Convert 'extern inline' to 'static inline' in tulip.h (Chris Smith) +* Update DS21143 support flags in tulip_chip_info[] +* Use spin_lock_irq, not _irqsave/restore, in tulip_start_xmit() +* Add locking to set_rx_mode() +* Fix race with chip setting DescOwned bit (Hal Murray) +* Request 100% of PIO and MMIO resource space assigned to card +* Remove error message from pci_enable_device failure + 0.9.4.3 (April 14, 2000): * mod_timer fix (Hal Murray) * PNIC2 resusitation (Chris Smith) 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/Documentation/usb/input.txt linux.ac/Documentation/usb/input.txt --- linux.vanilla/Documentation/usb/input.txt Thu May 25 17:38:41 2000 +++ linux.ac/Documentation/usb/input.txt Tue May 30 21:28:07 2000 @@ -1,6 +1,7 @@ - Linux Input drivers v0.9 - (c) 1999 Vojtech Pavlik + Linux Input drivers v1.0 + (c) 1999-2000 Vojtech Pavlik Sponsored by SuSE + $Id: input.txt,v 1.4 2000/05/28 17:57:22 vojtech Exp $ ---------------------------------------------------------------------------- 0. Disclaimer @@ -62,27 +63,27 @@ hid.o After this, the USB keyboard will work straight away, and the USB mouse -will be available as a character device on major 13, minor 32: +will be available as a character device on major 13, minor 63: - crw-r--r-- 1 root root 13, 32 Mar 28 22:45 mouse0 + crw-r--r-- 1 root root 13, 63 Mar 28 22:45 mice This device, has to be created, unless you use devfs, in which case it's created automatically. The commands to do that are: cd /dev mkdir input - mknod input/mouse0 c 13 32 + mknod input/mice c 13 63 After that you have to point GPM (the textmode mouse cut&paste tool) and XFree to this device to use it - GPM should be called like: - gpm -t ps2 -m /dev/input/mouse0 + gpm -t ps2 -m /dev/input/mice And in X: Section "Pointer" Protocol "ImPS/2" - Device "/dev/input/mouse0" + Device "/dev/input/mice" ZAxisMapping 4 5 EndSection @@ -199,10 +200,11 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_[XY] in the kernel configuration are the size of your screen (in pixels) in XFree86. This is needed if you want to use your digitizer in X, because it's movement is sent to X via a virtual PS/2 -mouse. These values won't be used if you use a mouse only. +mouse and thus needs to be scaled accordingly. These values won't be used if +you use a mouse only. - Mousedev.c will generate either PS/2, ImPS/2 (microsoft intellimouse) or -GenPS/2 (genius netmouse/netscroll) protocols, depending on what the program + Mousedev will generate either PS/2, ImPS/2 (Microsoft IntelliMouse) or +GenPS/2 (Genius NetMouse/NetScroll) protocols, depending on what the program reading the data wishes. You can set GPM and X to any of these. You'll need ImPS/2 if you want to make use of a wheel on a USB mouse and GenPS/2 if you want to use extra (up to 5) buttons. I'm not sure how much is GenPS/2 supported @@ -249,8 +251,12 @@ http://www.suse.cz/development/input/ -You'll find both the latest HID driver and the complete Input driver there. -There is also a mailing list for this: +You'll find both the latest HID driver and the complete Input driver there +as well as information how to access the CVS repository for latest revisions +of the drivers. + + + There is also a mailing list for this: majordomo@atrey.karlin.mff.cuni.cz @@ -278,8 +284,8 @@ to be extended, but not changed incompatibly as time goes: You can use blocking and nonblocking reads, also select() on the -/dev/inputX devices, and you'll always get a whole number of input events on -a read. Their layout is: +/dev/input/eventX devices, and you'll always get a whole number of input +events on a read. Their layout is: struct input_event { struct timeval time; 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 Tue May 30 21:03:32 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 @@ -421,7 +421,10 @@ pdfdocs: sgmldocs $(MAKE) -C Documentation/DocBook pdf - + +htmldocs: sgmldocs + $(MAKE) -C Documentation/DocBook html + sums: find . -type f -print | sort | xargs sum > .SUMS 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 Tue May 30 16:48:25 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-III CONFIG_M686FX \ + Pentium/Pentium-MMX CONFIG_M586TSC \ + Pentium-Pro/Celeron/Pentium-II CONFIG_M686 \ + Pentium-III CONFIG_M686FXSR \ 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 # @@ -62,13 +62,16 @@ define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi -if [ "$CONFIG_M686FX" = "y" ]; then +if [ "$CONFIG_M686FXSR" = "y" ]; then define_int CONFIG_X86_L1_CACHE_BYTES 32 define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y - define_bool CONFIG_X86_FX y + define_bool CONFIG_X86_FXSR y + define_bool CONFIG_X86_XMM y +else + define_bool CONFIG_X86_FXSR n fi if [ "$CONFIG_MK6" = "y" ]; then define_int CONFIG_X86_L1_CACHE_BYTES 32 @@ -105,7 +108,7 @@ define_bool CONFIG_X86_PAE y fi -if [ "$CONFIG_X86_FX" != "y" ]; then +if [ "$CONFIG_X86_FXSR" != "y" ]; then bool 'Math emulation' CONFIG_MATH_EMULATION fi bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR 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/entry.S linux.ac/arch/i386/kernel/entry.S --- linux.vanilla/arch/i386/kernel/entry.S Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/entry.S Tue May 30 16:47:56 2000 @@ -322,13 +322,20 @@ pushl $ SYMBOL_NAME(do_coprocessor_error) jmp error_code +#ifdef CONFIG_X86_XMM +ENTRY(simd_coprocessor_error) + pushl $0 + pushl $ SYMBOL_NAME(do_simd_coprocessor_error) + jmp error_code +#endif + ENTRY(device_not_available) pushl $-1 # mark this as an int SAVE_ALL GET_CURRENT(%ebx) pushl $ret_from_exception movl %cr0,%eax - testl $0x4,%eax # EM (math emulation bit) + testl $0x4,%eax # EM (math emulation bit) je SYMBOL_NAME(math_state_restore) pushl $0 # temporary storage for ORIG_EIP call SYMBOL_NAME(math_emulate) @@ -411,11 +418,6 @@ ENTRY(spurious_interrupt_bug) pushl $0 pushl $ SYMBOL_NAME(do_spurious_interrupt_bug) - jmp error_code - -ENTRY(xmm_fault) - pushl $0 - pushl $ SYMBOL_NAME(do_xmm_fault) jmp error_code .data 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/process.c linux.ac/arch/i386/kernel/process.c --- linux.vanilla/arch/i386/kernel/process.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/process.c Tue May 30 16:47:56 2000 @@ -2,8 +2,9 @@ * linux/arch/i386/kernel/process.c * * Copyright (C) 1995 Linus Torvalds - * Pentium III code by Ingo Molnar with changes and support for - * OS exception support by Goutham Rao + * + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 */ /* @@ -471,94 +472,6 @@ return; } -#ifdef CONFIG_X86_FX - -int i387_hard_to_user ( struct _fpstate * user, - struct i387_hard_struct * hard) -{ - int i, err = 0; - short *tmp, *tmp2; - long *ltmp1, *ltmp2; - - err |= put_user(hard->cwd, &user->cw); - err |= put_user(hard->swd, &user->sw); - err |= put_user(fputag_KNIto387(hard->twd), &user->tag); - err |= put_user(hard->fip, &user->ipoff); - err |= put_user(hard->fcs, &user->cssel); - err |= put_user(hard->fdp, &user->dataoff); - err |= put_user(hard->fds, &user->datasel); - err |= put_user(hard->mxcsr, &user->mxcsr); - - tmp = (short *)&user->_st; - tmp2 = (short *)&hard->st_space; - - /* - * Transform the two layouts: - * (we do not mix 32-bit access with 16-bit access because - * thats suboptimal on PPros) - */ - for (i = 0; i < 8; i++) - { - err |= put_user(*tmp2, tmp); tmp++; tmp2++; - err |= put_user(*tmp2, tmp); tmp++; tmp2++; - err |= put_user(*tmp2, tmp); tmp++; tmp2++; - err |= put_user(*tmp2, tmp); tmp++; tmp2++; - err |= put_user(*tmp2, tmp); tmp++; tmp2 += 3; - } - - ltmp1 = (unsigned long *)&(user->_xmm[0]); - ltmp2 = (unsigned long *)&(hard->xmm_space[0]); - for(i = 0; i < 88; i++) - { - err |= put_user(*ltmp2, ltmp1); - ltmp1++; ltmp2++; - } - - return err; -} - -int i387_user_to_hard (struct i387_hard_struct * hard, - struct _fpstate * user) -{ - int i, err = 0; - short *tmp, *tmp2; - long *ltmp1, *ltmp2; - - err |= get_user(hard->cwd, &user->cw); - err |= get_user(hard->swd, &user->sw); - err |= get_user(hard->twd, &user->tag); - hard->twd = fputag_387toKNI(hard->twd); - err |= get_user(hard->fip, &user->ipoff); - err |= get_user(hard->fcs, &user->cssel); - err |= get_user(hard->fdp, &user->dataoff); - err |= get_user(hard->fds, &user->datasel); - err |= get_user(hard->mxcsr, &user->mxcsr); - - tmp2 = (short *)&hard->st_space; - tmp = (short *)&user->_st; - - for (i = 0; i < 8; i++) - { - err |= get_user(*tmp2, tmp); tmp++; tmp2++; - err |= get_user(*tmp2, tmp); tmp++; tmp2++; - err |= get_user(*tmp2, tmp); tmp++; tmp2++; - err |= get_user(*tmp2, tmp); tmp++; tmp2++; - err |= get_user(*tmp2, tmp); tmp++; tmp2 += 3; - } - - ltmp1 = (unsigned long *)(&user->_xmm[0]); - ltmp2 = (unsigned long *)(&hard->xmm_space[0]); - for(i = 0; i < (88); i++) - { - err |= get_user(*ltmp2, ltmp1); - ltmp2++; ltmp1++; - } - - return err; -} - -#endif - /* * Save a segment. */ @@ -592,6 +505,9 @@ /* * fill in the FPU structure for a core dump. */ +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif int dump_fpu (struct pt_regs * regs, struct user_i387_struct* fpu) { int fpvalid; @@ -600,7 +516,14 @@ fpvalid = tsk->used_math; if (fpvalid) { unlazy_fpu(tsk); - memcpy(fpu,&tsk->thread.i387.hard,sizeof(*fpu)); + memcpy(fpu, &tsk->thread.i387.hard, + MIN(sizeof(struct user_i387_struct), + sizeof(struct i387_hard_struct))); +#ifdef CONFIG_X86_FXSR + fpu->magic = X86_FXSR_MAGIC; +#else + fpu->magic = 0; +#endif } return fpvalid; @@ -659,8 +582,8 @@ /* * switch_to(x,yn) should switch tasks from x to y. * - * We fsave/fwait so that an exception goes off at the right time - * (as a call from the fsave or fwait in effect) rather than to + * We f*save/fwait so that an exception goes off at the right time + * (as a call from the f*save or fwait in effect) rather than to * the wrong process. Lazy FP saving no longer makes any sense * with modern CPU's, and this simplifies a lot of things (SMP * and UP become the same). diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/ptrace.c linux.ac/arch/i386/kernel/ptrace.c --- linux.vanilla/arch/i386/kernel/ptrace.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/ptrace.c Tue May 30 16:47:56 2000 @@ -1,7 +1,9 @@ /* ptrace.c */ /* By Ross Biro 1/23/92 */ -/* FXSAVE/FXRSTOR support by Ingo Molnar and modifications by Goutham Rao */ -/* edited by Linus Torvalds */ +/* + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 + */ #include /* for CONFIG_MATH_EMULATION */ #include @@ -36,6 +38,10 @@ */ #define EFL_OFFSET ((EFL-2)*4-sizeof(struct pt_regs)) +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + /* * this routine will get a word off of the processes privileged stack. * the offset is how far from the base addr as stored in the TSS. @@ -392,31 +398,41 @@ } case PTRACE_GETFPREGS: { /* Get the child FPU state. */ - if (!access_ok(VERIFY_WRITE, (unsigned *)data, sizeof(struct user_i387_struct))) { + if (!access_ok(VERIFY_WRITE, (unsigned *)data, + sizeof(struct user_i387_struct))) { ret = -EIO; break; } ret = 0; if ( !child->used_math ) { /* Simulate an empty FPU. */ - i387_set_cwd(child->thread.i387.hard, 0x037f); - i387_set_swd(child->thread.i387.hard, 0x0000); - i387_set_twd(child->thread.i387.hard, 0xffff); - } + set_fpu_cwd(child, 0x037f); + set_fpu_swd(child, 0x0000); + set_fpu_twd(child, 0xffff); + } #ifdef CONFIG_MATH_EMULATION if ( boot_cpu_data.hard_math ) { #endif - i387_hard_to_user((struct _fpstate *)data, &child->thread.i387.hard); + __copy_to_user((void *)data, &child->thread.i387.hard, + MIN(sizeof(struct user_i387_struct), + sizeof(struct i387_hard_struct))); +#ifdef CONFIG_X86_FXSR + ((struct user_i387_struct *)data)->magic = X86_FXSR_MAGIC; +#else + ((struct user_i387_struct *)data)->magic = 0; +#endif #ifdef CONFIG_MATH_EMULATION } else { - save_i387_soft(&child->thread.i387.soft, (struct _fpstate *)data); + save_i387_soft(&child->thread.i387.soft, + (struct _fpstate *)data); } #endif break; } case PTRACE_SETFPREGS: { /* Set the child FPU state. */ - if (!access_ok(VERIFY_READ, (unsigned *)data, sizeof(struct user_i387_struct))) { + if (!access_ok(VERIFY_READ, (unsigned *)data, + sizeof(struct user_i387_struct))) { ret = -EIO; break; } @@ -424,10 +440,13 @@ #ifdef CONFIG_MATH_EMULATION if ( boot_cpu_data.hard_math ) { #endif - i387_user_to_hard(&child->thread.i387.hard,(struct _fpstate *)data); + __copy_from_user(&child->thread.i387.hard,(void *)data, + MIN(sizeof(struct user_i387_struct), + sizeof(struct i387_hard_struct))); #ifdef CONFIG_MATH_EMULATION } else { - restore_i387_soft(&child->thread.i387.soft, (struct _fpstate *)data); + restore_i387_soft(&child->thread.i387.soft, + (struct _fpstate *)data); } #endif ret = 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 Tue May 30 16:48:58 2000 @@ -40,6 +40,13 @@ * and a few other clean ups. * Dave Jones , April 2000 * Pentium-III code by Ingo Molnar and modifications by Goutham Rao + * Updated to: + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 + * + * Added proper Cascades CPU and L2 cache detection for Cascades + * and 8-way type cache happy bunch from Intel:^) + * Dragan Stancevic , May 2000 * */ @@ -528,6 +535,7 @@ else { start_at = HIGH_MEMORY; mem_size -= HIGH_MEMORY; + usermem=0; } add_memory_region(start_at, mem_size, E820_RAM); } @@ -801,20 +809,6 @@ conswitchp = &dummy_con; #endif #endif -#ifdef CONFIG_X86_FX - if (boot_cpu_data.x86_capability & X86_FEATURE_FXSR) - { - printk("Enabling extended fast FPU save and restore ... "); - set_in_cr4(X86_CR4_OSFXSR); - printk("done.\n"); - } - if (boot_cpu_data.x86_capability & X86_FEATURE_XMM) - { - printk("Enabling KNI unmasked exception support ... "); - set_in_cr4(X86_CR4_OSXMMEXCPT); - printk("done.\n"); - } -#endif } static int __init get_model_name(struct cpuinfo_x86 *c) @@ -1337,8 +1331,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 +1416,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/i386/kernel/signal.c linux.ac/arch/i386/kernel/signal.c --- linux.vanilla/arch/i386/kernel/signal.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/signal.c Tue May 30 16:47:56 2000 @@ -4,8 +4,7 @@ * Copyright (C) 1991, 1992 Linus Torvalds * * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson - * Pentium III support by Ingo Molnar, modifications and OS Exception support - * by Goutham Rao + * 2000-05-25 Pentium III FXSR, SSE support by Gareth Hughes */ #include @@ -187,12 +186,17 @@ char retcode[8]; }; +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif static inline int restore_i387_hard(struct _fpstate *buf) { struct task_struct *tsk = current; clear_fpu(tsk); - return i387_user_to_hard(&tsk->thread.i387.hard, buf); + return __copy_from_user(&tsk->thread.i387.hard, buf, + MIN(sizeof(struct _fpstate), + sizeof(struct i387_hard_struct))); } static inline int restore_i387(struct _fpstate *buf) @@ -346,8 +350,15 @@ unlazy_fpu(tsk); tsk->thread.i387.hard.status = tsk->thread.i387.hard.swd; - if (i387_hard_to_user(buf, &tsk->thread.i387.hard)) + if (__copy_to_user(buf, &tsk->thread.i387.hard, + MIN(sizeof(struct _fpstate), + sizeof(struct i387_hard_struct)))) return -1; +#ifdef CONFIG_X86_FXSR + buf->magic = X86_FXSR_MAGIC; +#else + buf->magic = 0; +#endif return 1; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/traps.c linux.ac/arch/i386/kernel/traps.c --- linux.vanilla/arch/i386/kernel/traps.c Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/kernel/traps.c Tue May 30 16:47:56 2000 @@ -2,12 +2,14 @@ * linux/arch/i386/traps.c * * Copyright (C) 1991, 1992 Linus Torvalds - * FXSAVE/FXRSTOR support by Ingo Molnar, OS exception support by Goutham Rao + * + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 */ /* * 'Traps.c' handles hardware traps and faults after we have saved some - * state in 'asm.s'. + * state in 'entry.S'. */ #include #include @@ -136,8 +138,6 @@ unlock_kernel(); \ } -void page_exception(void); - asmlinkage void divide_error(void); asmlinkage void debug(void); asmlinkage void nmi(void); @@ -154,10 +154,12 @@ asmlinkage void general_protection(void); asmlinkage void page_fault(void); asmlinkage void coprocessor_error(void); +#ifdef CONFIG_X86_XMM +asmlinkage void simd_coprocessor_error(void); +#endif asmlinkage void reserved(void); asmlinkage void alignment_check(void); asmlinkage void spurious_interrupt_bug(void); -asmlinkage void xmm_fault(void); int kstack_depth_to_print = 24; @@ -320,7 +322,6 @@ DO_ERROR(12, SIGBUS, "stack segment", stack_segment, current) DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, current, BUS_ADRALN, get_cr2()) DO_ERROR(18, SIGSEGV, "reserved", reserved, current) -DO_VM86_ERROR(19, SIGFPE, "XMM fault", xmm_fault, current) asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) { @@ -588,11 +589,10 @@ siginfo_t info; /* - * Save the info for the exception handler - * (this will also clear the error) + * Save the info for the exception handler and clear the error */ task = current; - save_fpu(task); + save_init_fpu(task); task->thread.trap_no = 16; task->thread.error_code = 0; info.si_signo = SIGFPE; @@ -643,6 +643,63 @@ math_error((void *)regs->eip); } +#ifdef CONFIG_X86_XMM +void simd_math_error(void *eip) +{ + struct task_struct * task; + siginfo_t info; + + /* + * Save the info for the exception handler and clear the error + */ + task = current; + save_init_fpu(task); + set_fpu_mxcsr(XMM_DEFAULT_MXCSR); + task->thread.trap_no = 19; + task->thread.error_code = 0; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_code = __SI_FAULT; + info.si_addr = eip; + /* + * The SIMD FPU exceptions are handled a little differently, as there + * is only a single status/control register. Thus, to determine which + * unmasked exception was caught we must mask the exception mask bits + * at 0x1f80, and then use these to mask the exception bits at 0x3f. + */ + switch (~((task->thread.i387.hard.mxcsr & 0x1f80) >> 7) & + (task->thread.i387.hard.mxcsr & 0x3f)) { + case 0x000: + default: + break; + case 0x001: /* Invalid Op */ + info.si_code = FPE_FLTINV; + break; + case 0x002: /* Denormalize */ + case 0x010: /* Underflow */ + info.si_code = FPE_FLTUND; + break; + case 0x004: /* Zero Divide */ + info.si_code = FPE_FLTDIV; + break; + case 0x008: /* Overflow */ + info.si_code = FPE_FLTOVF; + break; + case 0x020: /* Precision */ + info.si_code = FPE_FLTRES; + break; + } + force_sig_info(SIGFPE, &info, task); +} + +asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs, + long error_code) +{ + ignore_irq13 = 1; + simd_math_error((void *)regs->eip); +} +#endif /* CONFIG_X86_XMM */ + asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs, long error_code) { @@ -661,19 +718,18 @@ */ asmlinkage void math_state_restore(struct pt_regs regs) { - __asm__ __volatile__("clts"); /* Allow maths ops (or we recurse) */ + __asm__ __volatile__("clts"); /* Allow maths ops (or we recurse) */ - if(current->used_math) - i387_restore_hard(current->thread.i387); - else - { + if (current->used_math) { + restore_fpu(current); + } else { /* * Our first FPU usage, clean the chip. */ __asm__("fninit"); current->used_math = 1; } - current->flags|=PF_USEDFPU; /* So we fnsave on switch_to() */ + current->flags |= PF_USEDFPU; /* So we fnsave on switch_to() */ } #ifndef CONFIG_MATH_EMULATION @@ -907,8 +963,10 @@ set_trap_gate(15,&spurious_interrupt_bug); set_trap_gate(16,&coprocessor_error); set_trap_gate(17,&alignment_check); - set_trap_gate(19,&xmm_fault); - +#ifdef CONFIG_X86_XMM + if (cpu_has_xmm) + set_trap_gate(19,&simd_coprocessor_error); +#endif set_system_gate(SYSCALL_VECTOR,&system_call); /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/math-emu/get_address.c linux.ac/arch/i386/math-emu/get_address.c --- linux.vanilla/arch/i386/math-emu/get_address.c Thu May 25 17:38:23 2000 +++ linux.ac/arch/i386/math-emu/get_address.c Tue May 30 14:36:16 2000 @@ -155,6 +155,7 @@ { struct desc_struct descriptor; unsigned long base_address, limit, address, seg_top; + unsigned short selector; segment--; @@ -174,12 +175,15 @@ case PREFIX_FS_-1: /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register in the assembler statement. */ - __asm__("mov %%fs,%0":"=r" ((unsigned short)addr->selector)); + + __asm__("mov %%fs,%0":"=r" (selector)); + addr->selector = selector; break; case PREFIX_GS_-1: /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register in the assembler statement. */ - __asm__("mov %%gs,%0":"=r" ((unsigned short)addr->selector)); + __asm__("mov %%gs,%0":"=r" (selector)); + addr->selector = selector; break; default: addr->selector = PM_REG_(segment); 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/s390/config.in linux.ac/arch/s390/config.in --- linux.vanilla/arch/s390/config.in Thu May 25 17:38:35 2000 +++ linux.ac/arch/s390/config.in Tue May 30 14:52:16 2000 @@ -63,10 +63,6 @@ comment 'Kernel hacking' #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC -bool 'Kernel profiling support' CONFIG_PROFILE -if [ "$CONFIG_PROFILE" = "y" ]; then - int ' Profile shift count' CONFIG_PROFILE_SHIFT 2 -fi if [ "$CONFIG_CTC" = "y" ]; then bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/s390/defconfig linux.ac/arch/s390/defconfig --- linux.vanilla/arch/s390/defconfig Thu May 25 17:38:35 2000 +++ linux.ac/arch/s390/defconfig Tue May 30 14:52:23 2000 @@ -174,5 +174,4 @@ # # Kernel hacking # -# CONFIG_PROFILE is not set # CONFIG_REMOTE_DEBUG is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/s390/kernel/traps.c linux.ac/arch/s390/kernel/traps.c --- linux.vanilla/arch/s390/kernel/traps.c Thu May 25 17:38:35 2000 +++ linux.ac/arch/s390/kernel/traps.c Tue May 30 14:41:10 2000 @@ -62,9 +62,6 @@ force_sig(signr, tsk); \ } - -void page_exception(void); - /* TODO: define these as 'pgm_check_handler_t xxx;' asmlinkage void divide_error(void); asmlinkage void debug(void); 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/ambassador.c linux.ac/drivers/atm/ambassador.c --- linux.vanilla/drivers/atm/ambassador.c Thu May 25 17:38:18 2000 +++ linux.ac/drivers/atm/ambassador.c Tue May 30 14:37:11 2000 @@ -290,10 +290,12 @@ /********** microcode **********/ #ifdef AMB_NEW_MICROCODE -#define UCODE(x) "atmsar12" "." #x +#define UCODE(x) UCODE1(atmsar12.,x) #else -#define UCODE(x) "atmsar11" "." #x +#define UCODE(x) UCODE1(atmsar11.,x) #endif +#define UCODE2(x) #x +#define UCODE1(x,y) UCODE2(x ## y) static const u32 __initdata ucode_start = #include UCODE(start) @@ -326,45 +328,43 @@ /********** access to adapter **********/ -static inline void wr_plain (const amb_dev * dev, const u32 * addr, u32 data) { - PRINTD (DBG_FLOW|DBG_REGS, "wr: %p <- %08x", addr, data); +static inline void wr_plain (const amb_dev * dev, size_t addr, u32 data) { + PRINTD (DBG_FLOW|DBG_REGS, "wr: %08x <- %08x", addr, data); #ifdef AMB_MMIO - dev->membase[addr - (u32 *) 0] = data; + dev->membase[addr / sizeof(u32)] = data; #else - outl (data, dev->iobase + (addr - (u32 *) 0) * sizeof(u32)); + outl (data, dev->iobase + addr); #endif } -static inline u32 rd_plain (const amb_dev * dev, const u32 * addr) { +static inline u32 rd_plain (const amb_dev * dev, size_t addr) { #ifdef AMB_MMIO - u32 data = dev->membase[addr - (u32 *) 0]; + u32 data = dev->membase[addr / sizeof(u32)]; #else - u32 data = inl (dev->iobase + (addr - (u32 *) 0) * sizeof(u32)); + u32 data = inl (dev->iobase + addr); #endif - PRINTD (DBG_FLOW|DBG_REGS, "rd: %p -> %08x", addr, data); + PRINTD (DBG_FLOW|DBG_REGS, "rd: %08x -> %08x", addr, data); return data; } -static const amb_mem * const mem = 0; - -static inline void wr_mem (const amb_dev * dev, const u32 * addr, u32 data) { +static inline void wr_mem (const amb_dev * dev, size_t addr, u32 data) { u32 be = cpu_to_be32 (data); - PRINTD (DBG_FLOW|DBG_REGS, "wr: %p <- %08x b[%08x]", addr, data, be); + PRINTD (DBG_FLOW|DBG_REGS, "wr: %08x <- %08x b[%08x]", addr, data, be); #ifdef AMB_MMIO - dev->membase[addr - (u32 *) 0] = be; + dev->membase[addr / sizeof(u32)] = be; #else - outl (be, dev->iobase + (addr - (u32 *) 0) * sizeof(u32)); + outl (be, dev->iobase + addr); #endif } -static inline u32 rd_mem (const amb_dev * dev, const u32 * addr) { +static inline u32 rd_mem (const amb_dev * dev, size_t addr) { #ifdef AMB_MMIO - u32 be = dev->membase[addr - (u32 *) 0]; + u32 be = dev->membase[addr / sizeof(u32)]; #else - u32 be = inl (dev->iobase + (addr - (u32 *) 0) * sizeof(u32)); + u32 be = inl (dev->iobase + addr); #endif u32 data = be32_to_cpu (be); - PRINTD (DBG_FLOW|DBG_REGS, "rd: %p -> %08x b[%08x]", addr, data, be); + PRINTD (DBG_FLOW|DBG_REGS, "rd: %08x -> %08x b[%08x]", addr, data, be); return data; } @@ -600,7 +600,7 @@ ptrs->in = NEXTQ (ptrs->in, ptrs->start, ptrs->limit); // mail the command - wr_mem (dev, &mem->mb.adapter.cmd_address, virt_to_bus (ptrs->in)); + wr_mem (dev, offsetof(amb_mem, mb.adapter.cmd_address), virt_to_bus (ptrs->in)); // prepare to wait for cq->pending milliseconds // effectively one centisecond on i386 @@ -667,8 +667,8 @@ txq->pending++; txq->in.ptr = NEXTQ (txq->in.ptr, txq->in.start, txq->in.limit); // hand over the TX and ring the bell - wr_mem (dev, &mem->mb.adapter.tx_address, virt_to_bus (txq->in.ptr)); - wr_mem (dev, &mem->doorbell, TX_FRAME); + wr_mem (dev, offsetof(amb_mem, mb.adapter.tx_address), virt_to_bus (txq->in.ptr)); + wr_mem (dev, offsetof(amb_mem, doorbell), TX_FRAME); if (txq->pending > txq->high) txq->high = txq->pending; @@ -724,7 +724,7 @@ rxq->pending++; rxq->in.ptr = NEXTQ (rxq->in.ptr, rxq->in.start, rxq->in.limit); // hand over the RX buffer - wr_mem (dev, &mem->mb.adapter.rx_address[pool], virt_to_bus (rxq->in.ptr)); + wr_mem (dev, offsetof(amb_mem, mb.adapter.rx_address[pool]), virt_to_bus (rxq->in.ptr)); spin_unlock_irqrestore (&rxq->lock, flags); return 0; @@ -855,16 +855,16 @@ /********** enable host interrupts **********/ static inline void interrupts_on (amb_dev * dev) { - wr_plain (dev, &mem->interrupt_control, - rd_plain (dev, &mem->interrupt_control) + wr_plain (dev, offsetof(amb_mem, interrupt_control), + rd_plain (dev, offsetof(amb_mem, interrupt_control)) | AMB_INTERRUPT_BITS); } /********** disable host interrupts **********/ static inline void interrupts_off (amb_dev * dev) { - wr_plain (dev, &mem->interrupt_control, - rd_plain (dev, &mem->interrupt_control) + wr_plain (dev, offsetof(amb_mem, interrupt_control), + rd_plain (dev, offsetof(amb_mem, interrupt_control)) &~ AMB_INTERRUPT_BITS); } @@ -900,7 +900,7 @@ } { - u32 interrupt = rd_plain (dev, &mem->interrupt); + u32 interrupt = rd_plain (dev, offsetof(amb_mem, interrupt)); // for us or someone else sharing the same interrupt if (!interrupt) { @@ -910,7 +910,7 @@ // definitely for us PRINTD (DBG_IRQ, "FYI: interrupt was %08x", interrupt); - wr_plain (dev, &mem->interrupt, -1); + wr_plain (dev, offsetof(amb_mem, interrupt), -1); } { @@ -959,8 +959,8 @@ cli(); PRINTK (KERN_INFO, "don't panic - putting adapter into reset"); - wr_plain (dev, &mem->reset_control, - rd_plain (dev, &mem->reset_control) | AMB_RESET_BITS); + wr_plain (dev, offsetof(amb_mem, reset_control), + rd_plain (dev, offsetof(amb_mem, reset_control) | AMB_RESET_BITS); PRINTK (KERN_INFO, "marking all commands complete"); for (cmd = ptrs->start; cmd < ptrs->limit; ++cmd) @@ -1985,7 +1985,7 @@ lb->valid = cpu_to_be32 (DMA_VALID); // dump_registers (dev); // dump_loader_block (lb); - wr_mem (dev, &mem->doorbell, virt_to_bus (lb) & ~onegigmask); + wr_mem (dev, offsetof(amb_mem, doorbell), virt_to_bus (lb) & ~onegigmask); timeout = command_timeouts[cmd] * HZ/100; @@ -2002,7 +2002,7 @@ if (cmd == adapter_start) { // wait for start command to acknowledge... timeout = HZ/10; - while (rd_plain (dev, &mem->doorbell)) + while (rd_plain (dev, offsetof(amb_mem, doorbell))) if (timeout) { timeout = schedule_timeout (timeout); } else { @@ -2095,21 +2095,21 @@ PRINTD (DBG_FLOW|DBG_LOAD, "amb_reset"); - word = rd_plain (dev, &mem->reset_control); + word = rd_plain (dev, offsetof(amb_mem, reset_control)); // put card into reset state - wr_plain (dev, &mem->reset_control, word | AMB_RESET_BITS); + wr_plain (dev, offsetof(amb_mem, reset_control), word | AMB_RESET_BITS); // wait a short while udelay (10); #if 1 // put card into known good state - wr_plain (dev, &mem->interrupt_control, AMB_DOORBELL_BITS); + wr_plain (dev, offsetof(amb_mem, interrupt_control), AMB_DOORBELL_BITS); // clear all interrupts just in case - wr_plain (dev, &mem->interrupt, -1); + wr_plain (dev, offsetof(amb_mem, interrupt), -1); #endif // clear self-test done flag - wr_plain (dev, &mem->mb.loader.ready, 0); + wr_plain (dev, offsetof(amb_mem, mb.loader.ready), 0); // take card out of reset state - wr_plain (dev, &mem->reset_control, word &~ AMB_RESET_BITS); + wr_plain (dev, offsetof(amb_mem, reset_control), word &~ AMB_RESET_BITS); if (diags) { unsigned long timeout; @@ -2119,7 +2119,7 @@ timeout = schedule_timeout (timeout); // half second time-out timeout = HZ/2; - while (!rd_plain (dev, &mem->mb.loader.ready)) + while (!rd_plain (dev, offsetof(amb_mem, mb.loader.ready))) if (timeout) { timeout = schedule_timeout (timeout); } else { @@ -2129,7 +2129,7 @@ // get results of self-test // XXX double check byte-order - word = rd_mem (dev, &mem->mb.loader.result); + word = rd_mem (dev, offsetof(amb_mem, mb.loader.result)); if (word & SELF_TEST_FAILURE) { void sf (const char * msg) { PRINTK (KERN_ERR, "self-test failed: %s", msg); @@ -2235,7 +2235,7 @@ #endif // pass the structure - wr_mem (dev, &mem->doorbell, virt_to_bus (&a)); + wr_mem (dev, offsetof(amb_mem, doorbell), virt_to_bus (&a)); // 2.2 second wait (must not touch doorbell during 2 second DMA test) timeout = HZ*22/10; @@ -2243,7 +2243,7 @@ timeout = schedule_timeout (timeout); // give the adapter another half second? timeout = HZ/2; - while (rd_plain (dev, &mem->doorbell)) + while (rd_plain (dev, offsetof(amb_mem, doorbell))) if (timeout) { timeout = schedule_timeout (timeout); } else { @@ -2318,10 +2318,10 @@ u32 mapreg; blb = virt_to_bus (&lb); // the kernel stack had better not ever cross a 1Gb boundary! - mapreg = rd_plain (dev, &mem->stuff[10]); + mapreg = rd_plain (dev, offsetof(amb_mem, stuff[10])); mapreg &= ~onegigmask; mapreg |= blb & onegigmask; - wr_plain (dev, &mem->stuff[10], mapreg); + wr_plain (dev, offsetof(amb_mem, stuff[10]), mapreg); return; } 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 Tue May 30 15:17:17 2000 @@ -1711,7 +1711,7 @@ dev->link_rate = ATM_OC3_PCR; eni_dev = ENI_DEV(dev); pci_dev = eni_dev->pci_dev; - real_base = pci_dev->resource[0].start; + real_base = pci_resource_start(pci_dev, 0); eni_dev->irq = pci_dev->irq; error = pci_read_config_byte(pci_dev,PCI_REVISION_ID,&revision); if (error) { @@ -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 Tue May 30 15:17:17 2000 @@ -472,7 +472,7 @@ card->index = i; card->atmdev = NULL; card->pcidev = pcidev; - card->membase = pcidev->resource[1].start; + card->membase = pci_resource_start(pcidev, 1); #ifdef __powerpc__ /* Compensate for different memory map between host CPU and PCI bus. Shouldn't we use a macro for this? */ @@ -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/atm/zatm.c linux.ac/drivers/atm/zatm.c --- linux.vanilla/drivers/atm/zatm.c Thu May 25 17:38:19 2000 +++ linux.ac/drivers/atm/zatm.c Tue May 30 15:17:17 2000 @@ -1385,7 +1385,7 @@ DPRINTK(">zatm_init\n"); zatm_dev = ZATM_DEV(dev); pci_dev = zatm_dev->pci_dev; - zatm_dev->base = pci_dev->resource[0].start; + zatm_dev->base = pci_resource_start(pci_dev, 0); zatm_dev->irq = pci_dev->irq; if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command)) || (error = pci_read_config_byte(pci_dev,PCI_REVISION_ID,&revision))) { 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/serial.c linux.ac/drivers/char/serial.c --- linux.vanilla/drivers/char/serial.c Thu May 25 17:38:00 2000 +++ linux.ac/drivers/char/serial.c Tue May 30 14:56:41 2000 @@ -43,13 +43,16 @@ * few races on freeing buffers too. * Alan Modra * + * 5/00: Support for the RSA-DV II/S card added. + * Kiyokazu SUTO + * * This module exports the following rs232 io functions: * * int rs_init(void); */ -static char *serial_version = "4.93"; -static char *serial_revdate = "2000-03-20"; +static char *serial_version = "5.01"; +static char *serial_revdate = "2000-05-29"; /* * Serial driver configuration section. Here are the various options: @@ -134,6 +137,8 @@ #endif #endif +#define CONFIG_SERIAL_RSA + #define RS_STROBE_TIME (10*HZ) #define RS_ISR_PASS_LIMIT 256 @@ -277,9 +282,20 @@ UART_STARTECH }, { "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH }, + { "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO }, { 0, 0} }; +#if defined(CONFIG_SERIAL_RSA) && defined(MODULE) + +#define PORT_RSA_MAX 4 +static int probe_rsa[PORT_RSA_MAX]; +static int force_rsa[PORT_RSA_MAX]; + +MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i"); +MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i"); +#endif /* CONFIG_SERIAL_RSA */ + static struct serial_state rs_table[RS_TABLE_SIZE] = { SERIAL_PORT_DFNS /* Defined in serial.h */ }; @@ -293,11 +309,8 @@ static struct pci_board_inst serial_pci_board[NR_PCI_BOARDS]; static int serial_pci_board_idx = 0; #endif -#ifndef PCI_BASE_ADDRESS -#define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start) -#define PCI_BASE_REGION_SIZE(dev, r) ((dev)->resource[r].end - \ - (dev)->resource[r].start) -#define IS_PCI_REGION_IOPORT(dev, r) ((dev)->resource[r].flags & \ +#ifndef IS_PCI_REGION_IOPORT +#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \ IORESOURCE_IO) #endif #ifndef PCI_IRQ_RESOURCE @@ -314,7 +327,8 @@ #define ACTIVATE_FUNC(dev) (dev->activate) #define DEACTIVATE_FUNC(dev) (dev->deactivate) #endif - + +#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) static struct tty_struct *serial_table[NR_PORTS]; static struct termios *serial_termios[NR_PORTS]; @@ -996,6 +1010,9 @@ tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); wake_up_interruptible(&tty->write_wait); +#ifdef SERIAL_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif } } @@ -1090,6 +1107,50 @@ IRQ_timeout[irq] = timeout ? timeout : 1; } +#ifdef CONFIG_SERIAL_RSA +/* Attempts to turn on the RSA FIFO. Returns zero on failure */ +static int enable_rsa(struct async_struct *info) +{ + unsigned char mode; + int result; + unsigned long flags; + + save_flags(flags); cli(); + mode = serial_inp(info, UART_RSA_MSR); + result = mode & UART_RSA_MSR_FIFO; + + if (!result) { + serial_outp(info, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); + mode = serial_inp(info, UART_RSA_MSR); + result = mode & UART_RSA_MSR_FIFO; + } + + restore_flags(flags); + return result; +} + +/* Attempts to turn off the RSA FIFO. Returns zero on failure */ +static int disable_rsa(struct async_struct *info) +{ + unsigned char mode; + int result; + unsigned long flags; + + save_flags(flags); cli(); + mode = serial_inp(info, UART_RSA_MSR); + result = !(mode & UART_RSA_MSR_FIFO); + + if (!result) { + serial_outp(info, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); + mode = serial_inp(info, UART_RSA_MSR); + result = !(mode & UART_RSA_MSR_FIFO); + } + + restore_flags(flags); + return result; +} +#endif /* CONFIG_SERIAL_RSA */ + static int startup(struct async_struct * info) { unsigned long flags; @@ -1127,7 +1188,7 @@ printk("starting up ttys%d (irq %d)...", info->line, state->irq); #endif - if (uart_config[info->state->type].flags & UART_STARTECH) { + if (uart_config[state->type].flags & UART_STARTECH) { /* Wake up UART */ serial_outp(info, UART_LCR, 0xBF); serial_outp(info, UART_EFR, UART_EFR_ECB); @@ -1145,7 +1206,7 @@ /* * For a XR16C850, we need to set the trigger levels */ - if (info->state->type == PORT_16850) { + if (state->type == PORT_16850) { serial_outp(info, UART_FCTR, UART_FCTR_TRGD | UART_FCTR_RX); serial_outp(info, UART_TRG, UART_TRG_96); @@ -1156,12 +1217,12 @@ serial_outp(info, UART_LCR, 0); } - if (info->state->type == PORT_16750) { + if (state->type == PORT_16750) { /* Wake up UART */ serial_outp(info, UART_IER, 0); } - if (info->state->type == PORT_16C950) { + if (state->type == PORT_16C950) { /* Wake up and initialize UART */ info->ACR = 0; serial_outp(info, UART_LCR, 0xBF); @@ -1174,6 +1235,20 @@ serial_outp(info, UART_LCR, 0); } +#ifdef CONFIG_SERIAL_RSA + /* + * If this is an RSA port, see if we can kick it up to the + * higher speed clock. + */ + if (state->type == PORT_RSA) { + if (state->baud_base != SERIAL_RSA_BAUD_BASE && + enable_rsa(info)) + state->baud_base = SERIAL_RSA_BAUD_BASE; + if (state->baud_base == SERIAL_RSA_BAUD_BASE) + serial_outp(info, UART_RSA_FRR, 0); + } +#endif + /* * Clear the FIFO buffers and disable them * (they will be reenabled in change_speed()) @@ -1199,7 +1274,8 @@ * if it is, then bail out, because there's likely no UART * here. */ - if (serial_inp(info, UART_LSR) == 0xff) { + if (!(info->flags & ASYNC_BUGGY_UART) && + (serial_inp(info, UART_LSR) == 0xff)) { printk("LSR safety check engaged!\n"); if (capable(CAP_SYS_ADMIN)) { if (info->tty) @@ -1425,6 +1501,17 @@ UART_FCR_CLEAR_XMIT)); serial_outp(info, UART_FCR, 0); +#ifdef CONFIG_SERIAL_RSA + /* + * Reset the RSA board back to 115kbps compat mode. + */ + if ((state->type == PORT_RSA) && + (state->baud_base == SERIAL_RSA_BAUD_BASE && + disable_rsa(info))) + state->baud_base = SERIAL_RSA_BAUD_BASE_LO; +#endif + + (void)serial_in(info, UART_RX); /* read data port to reset things */ if (info->tty) @@ -1522,6 +1609,12 @@ baud = tty_get_baud_rate(info->tty); if (!baud) baud = 9600; /* B0 transition handled in rs_set_termios */ +#ifdef CONFIG_SERIAL_RSA + if ((info->state->type == PORT_RSA) && + (info->state->baud_base != SERIAL_RSA_BAUD_BASE) && + enable_rsa(info)) + info->state->baud_base = SERIAL_RSA_BAUD_BASE; +#endif baud_base = info->state->baud_base; if (info->state->type == PORT_16C950) { if (baud <= baud_base) @@ -1583,6 +1676,10 @@ if (uart_config[info->state->type].flags & UART_USE_FIFO) { if ((info->state->baud_base / quot) < 2400) fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; +#ifdef CONFIG_SERIAL_RSA + else if (info->state->type == PORT_RSA) + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14; +#endif else fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8; } @@ -1810,6 +1907,9 @@ info->xmit.head = info->xmit.tail = 0; restore_flags(flags); wake_up_interruptible(&tty->write_wait); +#ifdef SERIAL_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); @@ -1912,6 +2012,10 @@ tmp.type = state->type; tmp.line = state->line; tmp.port = state->port; + if (HIGH_BITS_OFFSET) + tmp.port_high = state->port >> HIGH_BITS_OFFSET; + else + tmp.port_high = 0; tmp.irq = state->irq; tmp.flags = state->flags; tmp.xmit_fifo_size = state->xmit_fifo_size; @@ -1933,14 +2037,19 @@ struct serial_state old_state, *state; unsigned int i,change_irq,change_port; int retval = 0; + unsigned long new_port; if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) return -EFAULT; state = info->state; old_state = *state; - + + new_port = new_serial.port; + if (HIGH_BITS_OFFSET) + new_port += new_serial.port_high << HIGH_BITS_OFFSET; + change_irq = new_serial.irq != state->irq; - change_port = (new_serial.port != state->port) || + change_port = (new_port != ((int) state->port)) || (new_serial.hub6 != state->hub6); if (!capable(CAP_SYS_ADMIN)) { @@ -1978,7 +2087,7 @@ if (new_serial.type) { for (i = 0 ; i < NR_PORTS; i++) if ((state != &rs_table[i]) && - (rs_table[i].port == new_serial.port) && + (rs_table[i].port == new_port) && rs_table[i].type) return -EADDRINUSE; } @@ -2005,8 +2114,14 @@ info->xmit_fifo_size = state->xmit_fifo_size = new_serial.xmit_fifo_size; - if ((state->type != PORT_UNKNOWN) && state->port) + if ((state->type != PORT_UNKNOWN) && state->port) { +#ifdef CONFIG_SERIAL_RSA + if (old_state.type == PORT_RSA) + release_region(state->port + UART_RSA_BASE, 16); + else +#endif release_region(state->port,8); + } state->type = new_serial.type; if (change_port || change_irq) { /* @@ -2015,15 +2130,22 @@ */ shutdown(info); state->irq = new_serial.irq; - info->port = state->port = new_serial.port; + info->port = state->port = new_port; info->hub6 = state->hub6 = new_serial.hub6; if (info->hub6) info->io_type = state->io_type = SERIAL_IO_HUB6; else if (info->io_type == SERIAL_IO_HUB6) info->io_type = state->io_type = SERIAL_IO_PORT; } - if ((state->type != PORT_UNKNOWN) && state->port) - request_region(state->port,8,"serial(set)"); + if ((state->type != PORT_UNKNOWN) && state->port) { +#ifdef CONFIG_SERIAL_RSA + if (state->type == PORT_RSA) + request_region(state->port + UART_RSA_BASE, + 16, "serial_rsa(set)"); + else +#endif + request_region(state->port,8,"serial(set)"); + } check_and_exit: @@ -2462,6 +2584,9 @@ /* note the counters on entry */ cprev = info->state->icount; restore_flags(flags); + /* Force modem status interrupts on */ + info->IER |= UART_IER_MSI; + serial_out(info, UART_IER, info->IER); while (1) { interruptible_sleep_on(&info->delta_msr_wait); /* see if a signal did it */ @@ -3348,6 +3473,16 @@ * LSR register (which serial_icr_read does) */ if (state->type == PORT_16550A) { + /* + * EFR [4] must be set else this test fails + * + * This shouldn't be necessary, but Mike Hudson + * (Exoray@isys.ca) claims that it's needed for 952 + * dual UART's (which are not recommended for new designs). + */ + serial_out(info, UART_LCR, 0xBF); + serial_out(info, UART_EFR, 0x10); + serial_out(info, UART_LCR, 0x00); /* Check for Oxford Semiconductor 16C950 */ scratch = serial_icr_read(info, UART_ID1); scratch2 = serial_icr_read(info, UART_ID2); @@ -3434,7 +3569,8 @@ save_flags(flags); cli(); - if (!state->iomem_base) { + if (!(state->flags & ASYNC_BUGGY_UART) && + !state->iomem_base) { /* * Do a simple existence test first; if we fail this, * there's no point trying anything else. @@ -3459,8 +3595,9 @@ serial_outp(info, UART_IER, scratch); if (scratch2 || scratch3 != 0x0F) { #ifdef SERIAL_DEBUG_AUTOCONF - printk("serial: ttyS%d: simple autoconfig failed\n", - state->line); + printk("serial: ttyS%d: simple autoconfig failed " + "(%02x, %02x)\n", state->line, + scratch2, scratch3); #endif restore_flags(flags); return; /* We failed; there's nothing here */ @@ -3545,6 +3682,25 @@ } serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); } +#if defined(CONFIG_SERIAL_RSA) && defined(MODULE) + if (state->type == PORT_16550A) { + int i; + + for (i = 0 ; i < PORT_RSA_MAX ; ++i) { + if (!probe_rsa[i] && !force_rsa[i]) + break; + if (((probe_rsa[i] != state->port) || + check_region(state->port + UART_RSA_BASE, 16)) && + (force_rsa[i] != state->port)) + continue; + if (!enable_rsa(info)) + continue; + state->type = PORT_RSA; + state->baud_base = SERIAL_RSA_BAUD_BASE; + break; + } + } +#endif serial_outp(info, UART_LCR, save_lcr); if (state->type == PORT_16450) { scratch = serial_in(info, UART_SCR); @@ -3564,12 +3720,23 @@ return; } - if (info->port) - request_region(info->port,8,"serial(auto)"); + if (info->port) { +#ifdef CONFIG_SERIAL_RSA + if (state->type == PORT_RSA) + request_region(info->port + UART_RSA_BASE, 16, + "serial_rsa(auto)"); + else +#endif + request_region(info->port,8,"serial(auto)"); + } /* * Reset the UART. */ +#ifdef CONFIG_SERIAL_RSA + if (state->type == PORT_RSA) + serial_outp(info, UART_RSA_FRR, 0); +#endif serial_outp(info, UART_MCR, save_mcr); serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | @@ -3614,7 +3781,7 @@ static _INLINE_ int get_pci_port(struct pci_dev *dev, struct pci_board *board, - struct serial_struct *state, + struct serial_struct *req, int idx) { unsigned long port; @@ -3626,24 +3793,28 @@ base_idx += idx; if (board->flags & SPCI_FL_REGION_SZ_CAP) { - max_port = PCI_BASE_REGION_SIZE(dev, base_idx) / 8; + max_port = pci_resource_len(dev, base_idx) / 8; if (idx >= max_port) return 1; } - port = PCI_BASE_ADDRESS(dev, base_idx) + board->first_uart_offset; + port = pci_resource_start(dev, base_idx) + board->first_uart_offset; if ((board->flags & SPCI_FL_BASE_TABLE) == 0) port += idx * (board->uart_offset ? board->uart_offset : 8); if (IS_PCI_REGION_IOPORT(dev, base_idx)) { - state->port = port; + req->port = port; + if (HIGH_BITS_OFFSET) + req->port_high = port >> HIGH_BITS_OFFSET; + else + req->port_high = 0; return 0; } - state->io_type = SERIAL_IO_MEM; - state->iomem_base = ioremap(port, board->uart_offset); - state->iomem_reg_shift = board->reg_shift; - state->port = 0; + req->io_type = SERIAL_IO_MEM; + req->iomem_base = ioremap(port, board->uart_offset); + req->iomem_reg_shift = board->reg_shift; + req->port = 0; return 0; } @@ -3670,23 +3841,28 @@ struct pci_board *board) { int k, line; - struct serial_struct fake_state; + struct serial_struct serial_req; int base_baud; if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) { - printk("SERIAL: PNP device '"); + printk("serial: PNP device '"); printk_pnp_dev_id(board->vendor, board->device); printk("' prepare failed\n"); return; } if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) { - printk("SERIAL: PNP device '"); + printk("serial: PNP device '"); printk_pnp_dev_id(board->vendor, board->device); printk("' activate failed\n"); return; } + if (!(board->flags & SPCI_FL_ISPNP) && pci_enable_device(dev)) { + printk("serial: PCI device enable failed\n"); + return; + } + /* * Run the initialization function, if any */ @@ -3710,18 +3886,18 @@ base_baud = board->base_baud; if (!base_baud) base_baud = BASE_BAUD; - memset(&fake_state, 0, sizeof(fake_state)); + memset(&serial_req, 0, sizeof(serial_req)); for (k=0; k < board->num_ports; k++) { - fake_state.irq = get_pci_irq(dev, board, k); - if (get_pci_port(dev, board, &fake_state, k)) + serial_req.irq = get_pci_irq(dev, board, k); + if (get_pci_port(dev, board, &serial_req, k)) break; - fake_state.flags = ASYNC_SKIP_TEST; + serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE; #ifdef SERIAL_DEBUG_PCI printk("Setup PCI/PNP port: port %x, irq %d, type %d\n", - fake_state.port, fake_state.irq, fake_state.io_type); + serial_req.port, serial_req.irq, serial_req.io_type); #endif - line = register_serial(&fake_state); + line = register_serial(&serial_req); if (line < 0) break; rs_table[line].baud_base = base_baud; @@ -3742,28 +3918,45 @@ #endif pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable) { - u8 data, *p, scratch; + u8 data, *p, irq_config; + int pci_config; + irq_config = 0x41; + pci_config = PCI_COMMAND_MEMORY; + if (dev->vendor == PCI_VENDOR_ID_PANACOM) + irq_config = 0x43; + if ((dev->vendor == PCI_VENDOR_ID_PLX) && + (dev->device == PCI_VENDOR_ID_PLX_ROMULUS)) { + /* + * As the megawolf cards have the int pins active + * high, and have 2 UART chips, both ints must be + * enabled on the 9050. Also, the UARTS are set in + * 16450 mode by default, so we have to enable the + * 16C950 'enhanced' mode so that we can use the deep + * FIFOs + */ + irq_config = 0x5b; + pci_config = PCI_COMMAND_MEMORY | PCI_COMMAND_IO; + } + pci_read_config_byte(dev, PCI_COMMAND, &data); if (enable) pci_write_config_byte(dev, PCI_COMMAND, - data | PCI_COMMAND_MEMORY); + data | pci_config); /* enable/disable interrupts */ - p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80); - scratch = 0x41; - if (dev->vendor == PCI_VENDOR_ID_PANACOM) - scratch = 0x43; - writel(enable ? scratch : 0x00, (unsigned long)p + 0x4c); + p = ioremap(pci_resource_start(dev, 0), 0x80); + writel(enable ? irq_config : 0x00, (unsigned long)p + 0x4c); iounmap(p); if (!enable) pci_write_config_byte(dev, PCI_COMMAND, - data & ~PCI_COMMAND_MEMORY); + data & ~pci_config); return 0; } + /* * SIIG serial cards have an PCI interface chip which also controls * the UART clocking frequency. Each UART can be clocked independently @@ -3796,7 +3989,7 @@ if (!enable) return 0; - p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80); + p = ioremap(pci_resource_start(dev, 0), 0x80); switch (dev->device & 0xfff8) { case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */ @@ -3841,6 +4034,36 @@ return 0; } +/* Added for EKF Intel i960 serial boards */ +static int +#ifndef MODULE +__init +#endif +pci_inteli960ni_fn(struct pci_dev *dev, + struct pci_board *board, + int enable) +{ + unsigned long oldval; + + if (!(board->subdevice & 0x1000)) + return(-1); + + if (!enable) /* is there something to deinit? */ + return(0); + +#ifdef SERIAL_DEBUG_PCI + printk(KERN_DEBUG " Subsystem ID %lx (intel 960)\n", + (unsigned long) board->subdevice); +#endif + /* is firmware started? */ + pci_read_config_dword(dev, 0x44, (void*) &oldval); + if (oldval == 0x00001000L) { /* RESET value */ + printk(KERN_DEBUG "Local i960 firmware missing"); + return(-1); + } + return(0); +} + /* * This is the configuration table for all of the PCI serial boards @@ -3851,8 +4074,9 @@ * Vendor ID, Device ID, * Subvendor ID, Subdevice ID, * PCI Flags, Number of Ports, Base (Maximum) Baud Rate, - * Offset to get to next UART's registers - * Register shift to use for memory-mapped I/O + * Offset to get to next UART's registers, + * Register shift to use for memory-mapped I/O, + * Initialization function, first UART offset */ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, PCI_SUBVENDOR_ID_CONNECT_TECH, @@ -3942,6 +4166,10 @@ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200, PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 }, + /* VScom SPCOM800, from sl@s.pl */ + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE2, 8, 921600 }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_SUBVENDOR_ID_KEYSPAN, PCI_SUBDEVICE_ID_KEYSPAN_SX2, @@ -3979,6 +4207,12 @@ PCI_SUBVENDOR_ID_CHASE_PCIRAS, PCI_SUBDEVICE_ID_CHASE_PCIRAS8, SPCI_FL_BASE2, 8, 460800 }, + /* Megawolf Romulus PCI Serial Card, from Mike Hudson */ + /* (Exoray@isys.ca) */ + { PCI_VENDOR_ID_PLX, PCI_VENDOR_ID_PLX_ROMULUS, + 0x10b5, 0x106a, + SPCI_FL_BASE2, 4, 921600, + 0x20, 2, pci_plx9050_fn, 0x03 }, { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE1, 4, 115200 }, @@ -4164,7 +4398,7 @@ PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600, 0, 0, pci_siig20x_fn }, - /* Computone devices submitted by Doug McNash dougm@computone.com */ + /* Computone devices submitted by Doug McNash dmcnash@computone.com */ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG, PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4, SPCI_FL_BASE0, 4, 921600, /* IOMEM */ @@ -4198,6 +4432,15 @@ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B, PCI_ANY_ID, PCI_ANY_ID, SPCI_FL_BASE0, 4, 921600 }, + /* EKF addition for i960 Boards form EKF with serial port */ + { PCI_VENDOR_ID_INTEL, 0x1960, + 0xE4BF, PCI_ANY_ID, + SPCI_FL_BASE0, 32, 921600, /* max 256 ports */ + 8<<2, 2, pci_inteli960ni_fn, 0x10000}, + /* RAStel 2 port modem, gerg@moreton.com.au */ + { PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT, + PCI_ANY_ID, PCI_ANY_ID, + SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* * Untested PCI modems, sent in from various folks... */ @@ -4221,12 +4464,12 @@ }; /* - * Given a complete unknown PCI device, try to use some hueristics to + * Given a complete unknown PCI device, try to use some heuristics to * guess what the configuration might be, based on the pitiful PCI * serial specs. Returns 0 on success, 1 on failure. */ -static int _INLINE_ serial_guess_board(struct pci_dev *dev, - struct pci_board *board) +static int _INLINE_ serial_pci_guess_board(struct pci_dev *dev, + struct pci_board *board) { int num_iomem = 0, num_port = 0, first_port = -1; int i; @@ -4281,13 +4524,6 @@ printk(KERN_DEBUG "Entered probe_serial_pci()\n"); #endif - if (!pcibios_present()) { -#ifdef SERIAL_DEBUG_PCI - printk(KERN_DEBUG "Leaving probe_serial_pci() (no pcibios)\n"); -#endif - return; - } - pci_for_each_dev(dev) { for (board = pci_boards; board->vendor; board++) { if (board->vendor != (unsigned short) PCI_ANY_ID && @@ -4305,7 +4541,7 @@ break; } - if (board->vendor == 0 && serial_guess_board(dev, board)) + if (board->vendor == 0 && serial_pci_guess_board(dev, board)) continue; start_pci_pnp_board(dev, board); @@ -4321,58 +4557,280 @@ #ifdef ENABLE_SERIAL_PNP -static struct pci_board pnp_devices[] __initdata = { - /* Motorola VoiceSURFR 56K Modem */ - { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15F0), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, +struct pnp_board { + unsigned short vendor; + unsigned short device; +}; + +static struct pnp_board pnp_devices[] __initdata = { + /* Archtek America Corp. */ + /* Archtek SmartLink Modem 3334BT Plug & Play */ + { ISAPNP_VENDOR('A', 'A', 'C'), ISAPNP_DEVICE(0x000F) }, + /* Anchor Datacomm BV */ + /* SXPro 144 External Data Fax Modem Plug & Play */ + { ISAPNP_VENDOR('A', 'D', 'C'), ISAPNP_DEVICE(0x0001) }, + /* SXPro 288 External Data Fax Modem Plug & Play */ + { ISAPNP_VENDOR('A', 'D', 'C'), ISAPNP_DEVICE(0x0002) }, /* Rockwell 56K ACF II Fax+Data+Voice Modem */ - { ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_NO_SHIRQ | SPCI_FL_PNPDEFAULT, - 1, 115200 }, + { ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021) }, /* AZT3005 PnP SOUND DEVICE */ - { ISAPNP_VENDOR('A', 'Z', 'T'), ISAPNP_DEVICE(0x4001), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { ISAPNP_VENDOR('A', 'Z', 'T'), ISAPNP_DEVICE(0x4001) }, /* Best Data Products Inc. Smart One 336F PnP Modem */ - { ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336) }, + /* Boca Research */ + /* Boca Complete Ofc Communicator 14.4 Data-FAX */ + { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x0A49) }, /* Boca Research 33,600 ACF Modem */ - { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x1400), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x1400) }, + /* Boca 33.6 Kbps Internal FD34FSVD */ + { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x3400) }, + /* Boca 33.6 Kbps Internal FD34FSVD */ + { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x0A49) }, + /* Best Data Products Inc. Smart One 336F PnP Modem */ + { ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336) }, + /* Computer Peripherals Inc */ + /* EuroViVa CommCenter-33.6 SP PnP */ + { ISAPNP_VENDOR('C', 'P', 'I'), ISAPNP_DEVICE(0x4050) }, + /* Creative Labs */ + /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */ + { ISAPNP_VENDOR('C', 'T', 'L'), ISAPNP_DEVICE(0x3001) }, + /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */ + { ISAPNP_VENDOR('C', 'T', 'L'), ISAPNP_DEVICE(0x3011) }, + /* Creative */ /* Creative Modem Blaster Flash56 DI5601-1 */ - { ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x1032), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x1032) }, /* Creative Modem Blaster V.90 DI5660 */ - { ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x2001), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x2001) }, + /* FUJITSU */ + /* Fujitsu 33600 PnP-I2 R Plug & Play */ + { ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0202) }, + /* Fujitsu FMV-FX431 Plug & Play */ + { ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0205) }, + /* Fujitsu 33600 PnP-I4 R Plug & Play */ + { ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0206) }, + /* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */ + { ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0209) }, + /* Archtek America Corp. */ + /* Archtek SmartLink Modem 3334BT Plug & Play */ + { ISAPNP_VENDOR('G', 'V', 'C'), ISAPNP_DEVICE(0x000F) }, + /* Hayes */ + /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */ + { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x0001) }, + /* Hayes Optima 336 V.34 + FAX + Voice PnP */ + { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x000C) }, + /* Hayes Optima 336B V.34 + FAX + Voice PnP */ + { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x000D) }, + /* Hayes Accura 56K Ext Fax Modem PnP */ + { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5670) }, + /* Hayes Accura 56K Ext Fax Modem PnP */ + { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5674) }, + /* Hayes Accura 56K Fax Modem PnP */ + { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5675) }, + /* Hayes 288, V.34 + FAX */ + { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0xF000) }, + /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */ + { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0xF001) }, + /* IBM */ + /* IBM Thinkpad 701 Internal Modem Voice */ + { ISAPNP_VENDOR('I', 'B', 'M'), ISAPNP_DEVICE(0x0033) }, + /* Intertex */ + /* Intertex 28k8 33k6 Voice EXT PnP */ + { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xC801) }, + /* Intertex 33k6 56k Voice EXT PnP */ + { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xC901) }, + /* Intertex 28k8 33k6 Voice SP EXT PnP */ + { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xD801) }, + /* Intertex 33k6 56k Voice SP EXT PnP */ + { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xD901) }, + /* Intertex 28k8 33k6 Voice SP INT PnP */ + { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF401) }, + /* Intertex 28k8 33k6 Voice SP EXT PnP */ + { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF801) }, + /* Intertex 33k6 56k Voice SP EXT PnP */ + { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF901) }, + /* Kortex International */ + /* KORTEX 28800 Externe PnP */ + { ISAPNP_VENDOR('K', 'O', 'R'), ISAPNP_DEVICE(0x4522) }, + /* KXPro 33.6 Vocal ASVD PnP */ + { ISAPNP_VENDOR('K', 'O', 'R'), ISAPNP_DEVICE(0xF661) }, + /* Lasat */ + /* LASAT Internet 33600 PnP */ + { ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x4040) }, + /* Lasat Safire 560 PnP */ + { ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x4540) }, + /* Lasat Safire 336 PnP */ + { ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x5440) }, + /* Microcom, Inc. */ + /* Microcom TravelPorte FAST V.34 Plug & Play */ + { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x281) }, + /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */ + { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0336) }, + /* Microcom DeskPorte FAST EP 28.8 Plug & Play */ + { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0339) }, + /* Microcom DeskPorte 28.8P Plug & Play */ + { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0342) }, + /* Microcom DeskPorte FAST ES 28.8 Plug & Play */ + { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0500) }, + /* Microcom DeskPorte FAST ES 28.8 Plug & Play */ + { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0501) }, + /* Microcom DeskPorte 28.8S Internal Plug & Play */ + { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0502) }, + /* Motorola */ + /* Motorola BitSURFR Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1105) }, + /* Motorola TA210 Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1111) }, + /* Motorola HMTA 200 (ISDN) Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1114) }, + /* Motorola BitSURFR Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1115) }, + /* Motorola Lifestyle 28.8 Internal */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1190) }, + /* Motorola V.3400 Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1501) }, + /* Motorola Lifestyle 28.8 V.34 Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1502) }, + /* Motorola Power 28.8 V.34 Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1505) }, + /* Motorola ModemSURFR External 28.8 Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1509) }, + /* Motorola Premier 33.6 Desktop Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x150A) }, + /* Motorola VoiceSURFR 56K External PnP */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x150F) }, + /* Motorola ModemSURFR 56K External PnP */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1510) }, + /* Motorola ModemSURFR 56K Internal PnP */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1550) }, + /* Motorola ModemSURFR Internal 28.8 Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1560) }, + /* Motorola Premier 33.6 Internal Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1580) }, + /* Motorola OnlineSURFR 28.8 Internal Plug & Play */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15B0) }, + /* Motorola VoiceSURFR 56K Internal PnP */ + { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15F0) }, + /* Com 1 */ + /* Deskline K56 Phone System PnP */ + { ISAPNP_VENDOR('M', 'V', 'X'), ISAPNP_DEVICE(0x00A1) }, + /* PC Rider K56 Phone System PnP */ + { ISAPNP_VENDOR('M', 'V', 'X'), ISAPNP_DEVICE(0x00F2) }, /* Pace 56 Voice Internal Plug & Play Modem */ - { ISAPNP_VENDOR('P', 'M', 'C'), ISAPNP_DEVICE(0x2430), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, - /* SupraExpress 28.8 Data/Fax PnP modem */ - { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1310), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, - /* US Robotics Sporster 33600 Modem */ - { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0006), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, - /* U.S. Robotics 56K FAX INT */ - { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3031), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, - /* Viking 56K FAX INT */ - { ISAPNP_VENDOR('R', 'S', 'S'), ISAPNP_DEVICE(0x0262), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, - - /* These ID's are taken from M$ documentation */ - /* Compaq 14400 Modem */ - { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC000), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, - /* Compaq 2400/9600 Modem */ - { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC001), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { ISAPNP_VENDOR('P', 'M', 'C'), ISAPNP_DEVICE(0x2430) }, + /* Generic */ /* Generic standard PC COM port */ - { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0500), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0500) }, /* Generic 16550A-compatible COM port */ - { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0501), 0, 0, - SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 }, + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0501) }, + /* Compaq 14400 Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC000) }, + /* Compaq 2400/9600 Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC001) }, + /* Dial-Up Networking Serial Cable between 2 PCs */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC031) }, + /* Dial-Up Networking Parallel Cable between 2 PCs */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC032) }, + /* Standard 9600 bps Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC100) }, + /* Standard 14400 bps Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC101) }, + /* Standard 28800 bps Modem*/ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC102) }, + /* Standard Modem*/ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC103) }, + /* Standard 9600 bps Modem*/ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC104) }, + /* Standard 14400 bps Modem*/ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC105) }, + /* Standard 28800 bps Modem*/ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC106) }, + /* Standard Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC107) }, + /* Standard 9600 bps Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC108) }, + /* Standard 14400 bps Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC109) }, + /* Standard 28800 bps Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10A) }, + /* Standard Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10B) }, + /* Standard 9600 bps Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10C) }, + /* Standard 14400 bps Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10D) }, + /* Standard 28800 bps Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10E) }, + /* Standard Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10F) }, + /* Standard PCMCIA Card Modem */ + { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x2000) }, + /* Rockwell */ + /* Modular Technology */ + /* Rockwell 33.6 DPF Internal PnP */ + /* Modular Technology 33.6 Internal PnP */ + { ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x0030) }, + /* Kortex International */ + /* KORTEX 14400 Externe PnP */ + { ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x0100) }, + /* Viking Components, Inc */ + /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */ + { ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x4920) }, + /* Rockwell */ + /* British Telecom */ + /* Modular Technology */ + /* Rockwell 33.6 DPF External PnP */ + /* BT Prologue 33.6 External PnP */ + /* Modular Technology 33.6 External PnP */ + { ISAPNP_VENDOR('R', 'S', 'S'), ISAPNP_DEVICE(0x00A0) }, + /* Viking 56K FAX INT */ + { ISAPNP_VENDOR('R', 'S', 'S'), ISAPNP_DEVICE(0x0262) }, + /* SupraExpress 28.8 Data/Fax PnP modem */ + { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1310) }, + /* SupraExpress 33.6 Data/Fax PnP modem */ + { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1421) }, + /* SupraExpress 33.6 Data/Fax PnP modem */ + { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1590) }, + /* SupraExpress 33.6 Data/Fax PnP modem */ + { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1760) }, + /* Phoebe Micro */ + /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */ + { ISAPNP_VENDOR('T', 'E', 'X'), ISAPNP_DEVICE(0x0011) }, + /* Archtek America Corp. */ + /* Archtek SmartLink Modem 3334BT Plug & Play */ + { ISAPNP_VENDOR('U', 'A', 'C'), ISAPNP_DEVICE(0x000F) }, + /* 3Com Corp. */ + /* Gateway Telepath IIvi 33.6 */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0000) }, + /* Sportster Vi 14.4 PnP FAX Voicemail */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0004) }, + /* U.S. Robotics 33.6K Voice INT PnP */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0006) }, + /* U.S. Robotics 33.6K Voice EXT PnP */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0007) }, + /* U.S. Robotics 33.6K Voice INT PnP */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2002) }, + /* U.S. Robotics 56K Voice INT PnP */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2070) }, + /* U.S. Robotics 56K Voice EXT PnP */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2080) }, + /* U.S. Robotics 56K FAX INT */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3031) }, + /* U.S. Robotics 56K Voice INT PnP */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3070) }, + /* U.S. Robotics 56K Voice EXT PnP */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3080) }, + /* U.S. Robotics 56K Voice INT PnP */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3090) }, + /* U.S. Robotics 56K Message */ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9100) }, + /* U.S. Robotics 56K FAX EXT PnP*/ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9160) }, + /* U.S. Robotics 56K FAX INT PnP*/ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9170) }, + /* U.S. Robotics 56K Voice EXT PnP*/ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9180) }, + /* U.S. Robotics 56K Voice INT PnP*/ + { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9190) }, { 0, } }; @@ -4394,10 +4852,80 @@ irq->map = map; } +static char *modem_names[] __initdata = { + "MODEM", "Modem", "modem", "FAX", "Fax", "fax", + "56K", "56k", "K56", "33.6", "28.8", "14.4", + "33,600", "28,800", "14,400", "33.600", "28.800", "14.400", + "33600", "28800", "14400", "V.90", "V.34", "V.32", 0 +}; + +static int __init check_name(char *name) +{ + char **tmp = modem_names; + + while (*tmp) { + if (strstr(name, *tmp)) + return 1; + tmp++; + } + return 0; +} + +static int inline check_compatible_id(struct pci_dev *dev) +{ + int i; + for (i = 0; i < DEVICE_COUNT_COMPATIBLE; i++) + if ((dev->vendor_compatible[i] == + ISAPNP_VENDOR('P', 'N', 'P')) && + (swab16(dev->device_compatible[i]) >= 0xc000) && + (swab16(dev->device_compatible[i]) <= 0xdfff)) + return 0; + return 1; +} + +/* + * Given a complete unknown ISA PnP device, try to use some heuristics to + * detect modems. Currently use such heuristic set: + * - dev->name or dev->bus->name must contain "modem" substring; + * - device must have only one IO region (8 byte long) with base adress + * 0x2e8, 0x3e8, 0x2f8 or 0x3f8. + * + * Such detection looks very ugly, but can detect at least some of numerous + * ISA PnP modems, alternatively we must hardcode all modems in pnp_devices[] + * table. + */ +static int _INLINE_ serial_pnp_guess_board(struct pci_dev *dev, + struct pci_board *board) +{ + struct isapnp_resources *res = (struct isapnp_resources *)dev->sysdata; + struct isapnp_resources *resa; + + if (!(check_name(dev->name) || check_name(dev->bus->name)) && + !(check_compatible_id(dev))) + return 1; + + if (res->next) + return 1; + + for (resa = res->alt; resa; resa = resa->alt) { + struct isapnp_port *port; + for (port = res->port; port; port = port->next) + if ((port->size == 8) && + ((port->min == 0x2f8) || + (port->min == 0x3f8) || + (port->min == 0x2e8) || + (port->min == 0x3e8))) + return 0; + } + + return 1; +} + static void __init probe_serial_pnp(void) { struct pci_dev *dev = NULL; - struct pci_board *board; + struct pnp_board *pnp_board; + struct pci_board board; #ifdef SERIAL_DEBUG_PNP printk("Entered probe_serial_pnp()\n"); @@ -4409,13 +4937,35 @@ return; } - for (board = pnp_devices; board->vendor; board++) { - while ((dev = isapnp_find_dev(NULL, board->vendor, - board->device, dev))) { - if (board->flags & SPCI_FL_NO_SHIRQ) - avoid_irq_share(dev); - start_pci_pnp_board(dev, board); - } + isapnp_for_each_dev(dev) { + if (dev->active) + continue; + + memset(&board, 0, sizeof(board)); + board.flags = SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT; + board.num_ports = 1; + board.base_baud = 115200; + + for (pnp_board = pnp_devices; pnp_board->vendor; pnp_board++) + if ((dev->vendor == pnp_board->vendor) && + (dev->device == pnp_board->device)) + break; + + if (pnp_board->vendor) { + board.vendor = pnp_board->vendor; + board.device = pnp_board->device; + /* Special case that's more efficient to hardcode */ + if ((board.vendor == ISAPNP_VENDOR('A', 'K', 'Y') && + board.device == ISAPNP_DEVICE(0x1021))) + board.flags |= SPCI_FL_NO_SHIRQ; + } else { + if (serial_pnp_guess_board(dev, &board)) + continue; + } + + if (board.flags & SPCI_FL_NO_SHIRQ) + avoid_irq_share(dev); + start_pci_pnp_board(dev, &board); } #ifdef SERIAL_DEBUG_PNP @@ -4477,7 +5027,7 @@ #if (LINUX_VERSION_CODE > 0x20100) serial_driver.driver_name = "serial"; #endif -#ifdef CONFIG_DEVFS_FS +#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) serial_driver.name = "tts/%d"; #else serial_driver.name = "ttyS"; @@ -4525,7 +5075,7 @@ * major number and the subtype code. */ callout_driver = serial_driver; -#ifdef CONFIG_DEVFS_FS +#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) callout_driver.name = "cua/%d"; #else callout_driver.name = "cua"; @@ -4615,14 +5165,25 @@ unsigned long flags; struct serial_state *state; struct async_struct *info; + unsigned long port; + + port = req->port; + if (HIGH_BITS_OFFSET) + port += req->port_high << HIGH_BITS_OFFSET; save_flags(flags); cli(); for (i = 0; i < NR_PORTS; i++) { - if ((rs_table[i].port == req->port) && + if ((rs_table[i].port == port) && (rs_table[i].iomem_base == req->iomem_base)) break; } if (i == NR_PORTS) { + for (i = 4; i < NR_PORTS; i++) + if ((rs_table[i].type == PORT_UNKNOWN) && + (rs_table[i].count == 0)) + break; + } + if (i == NR_PORTS) { for (i = 0; i < NR_PORTS; i++) if ((rs_table[i].type == PORT_UNKNOWN) && (rs_table[i].count == 0)) @@ -4636,11 +5197,11 @@ if (rs_table[i].count) { restore_flags(flags); printk("Couldn't configure serial #%d (port=%ld,irq=%d): " - "device already open\n", i, req->port, req->irq); + "device already open\n", i, port, req->irq); return -1; } state->irq = req->irq; - state->port = req->port; + state->port = port; state->flags = req->flags; state->io_type = req->io_type; state->iomem_base = req->iomem_base; @@ -4648,7 +5209,7 @@ if (req->baud_base) state->baud_base = req->baud_base; if ((info = state->info) != NULL) { - info->port = req->port; + info->port = port; info->flags = req->flags; info->io_type = req->io_type; info->iomem_base = req->iomem_base; @@ -4721,10 +5282,10 @@ timer_table[RS_TIMER].expires = 0; remove_bh(SERIAL_BH); if ((e1 = tty_unregister_driver(&serial_driver))) - printk("SERIAL: failed to unregister serial driver (%d)\n", + printk("serial: failed to unregister serial driver (%d)\n", e1); if ((e2 = tty_unregister_driver(&callout_driver))) - printk("SERIAL: failed to unregister callout driver (%d)\n", + printk("serial: failed to unregister callout driver (%d)\n", e2); restore_flags(flags); @@ -4733,8 +5294,15 @@ rs_table[i].info = NULL; kfree_s(info, sizeof(struct async_struct)); } - if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) - release_region(rs_table[i].port, 8); + if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) { +#ifdef CONFIG_SERIAL_RSA + if (rs_table[i].type == PORT_RSA) + release_region(rs_table[i].port + + UART_RSA_BASE, 16); + else +#endif + release_region(rs_table[i].port, 8); + } #if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP) if (rs_table[i].iomem_base) iounmap(rs_table[i].iomem_base); @@ -4992,7 +5560,7 @@ * Remember I/O port for kdb */ if (kdb_port == 0 ) - kdb_port = ser->port; + kdb_port = state->port; #endif /* CONFIG_KDB */ return 0; @@ -5023,6 +5591,6 @@ /* Local variables: - compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i686 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -DEXPORT_SYMTAB -c serial.c" + compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -D__SMP__ -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -DEXPORT_SYMTAB -c serial.c" End: */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/stradis.c linux.ac/drivers/char/stradis.c --- linux.vanilla/drivers/char/stradis.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/stradis.c Tue May 30 15:17:17 2000 @@ -2055,10 +2055,9 @@ saa->id = dev->device; saa->irq = dev->irq; saa->video_dev.minor = -1; - saa->saa7146_adr = dev->resource[0].start; + saa->saa7146_adr = pci_resource_start(dev, 0); pci_read_config_byte(dev, PCI_CLASS_REVISION, &saa->revision); - saa->saa7146_mem = ioremap(((saa->saa7146_adr) & - PCI_BASE_ADDRESS_MEM_MASK), 0x200); + saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200); memcpy(&(saa->i2c), &saa7146_i2c_bus_template, sizeof(struct i2c_bus)); memcpy(&saa->video_dev, &saa_template, sizeof(saa_template)); sprintf(saa->i2c.name, "stradis%d", num); 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 Tue May 30 17:35:45 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/aec62xx.c linux.ac/drivers/ide/aec62xx.c --- linux.vanilla/drivers/ide/aec62xx.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/aec62xx.c Tue May 30 15:17:17 2000 @@ -55,7 +55,7 @@ { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; u8 art = 0, uart = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/alim15x3.c linux.ac/drivers/ide/alim15x3.c --- linux.vanilla/drivers/ide/alim15x3.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/alim15x3.c Tue May 30 15:17:17 2000 @@ -508,13 +508,13 @@ unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name) { - unsigned long fixdma_base = dev->resource[4].start; + unsigned long fixdma_base = pci_resource_start(dev, 4); pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision); isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); - if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) { + if (!fixdma_base || (pci_resource_flags(dev, 4) & IORESOURCE_IO)) { /* * */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/amd7409.c linux.ac/drivers/ide/amd7409.c --- linux.vanilla/drivers/ide/amd7409.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/amd7409.c Tue May 30 15:17:17 2000 @@ -40,7 +40,7 @@ static int amd7409_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* @@ -372,9 +372,9 @@ unsigned int __init pci_init_amd7409 (struct pci_dev *dev, const char *name) { - unsigned long fixdma_base = dev->resource[4].start; + unsigned long fixdma_base = pci_resource_start(dev, 4); - if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) { + if (!fixdma_base || (pci_resource_flags(dev, 4) & IORESOURCE_IO)) { /* * */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/cs5530.c linux.ac/drivers/ide/cs5530.c --- linux.vanilla/drivers/ide/cs5530.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/cs5530.c Tue May 30 15:17:17 2000 @@ -43,7 +43,7 @@ static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/hpt34x.c linux.ac/drivers/ide/hpt34x.c --- linux.vanilla/drivers/ide/hpt34x.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/hpt34x.c Tue May 30 15:17:17 2000 @@ -62,7 +62,7 @@ static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* @@ -360,7 +360,7 @@ unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name) { int i = 0; - unsigned long hpt34xIoBase = dev->resource[4].start; + unsigned long hpt34xIoBase = pci_resource_start(dev, 4); unsigned short cmd; unsigned long flags; @@ -371,7 +371,7 @@ pci_read_config_word(dev, PCI_COMMAND, &cmd); if (cmd & PCI_COMMAND_MEMORY) { - if (dev->resource[PCI_ROM_RESOURCE].start) { + if (pci_resource_start(dev, PCI_ROM_RESOURCE)) { pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", dev->resource[PCI_ROM_RESOURCE].start); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/hpt366.c linux.ac/drivers/ide/hpt366.c --- linux.vanilla/drivers/ide/hpt366.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/hpt366.c Tue May 30 15:17:17 2000 @@ -137,8 +137,8 @@ static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; - u32 bibma2 = bmide2_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); + u32 bibma2 = pci_resource_start(bmide2_dev, 4); u8 c0 = 0, c1 = 0; /* 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-dma.c linux.ac/drivers/ide/ide-dma.c --- linux.vanilla/drivers/ide/ide-dma.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/ide-dma.c Tue May 30 15:17:17 2000 @@ -570,8 +570,8 @@ if (hwif->mate && hwif->mate->dma_base) { dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8); } else { - dma_base = dev->resource[4].start; - if (!dma_base || dma_base == PCI_BASE_ADDRESS_IO_MASK) { + dma_base = pci_resource_start(dev, 4); + if (!dma_base || (pci_resource_flags(dev, 4) & IORESOURCE_IO)) { printk("%s: dma_base is invalid (0x%04lx)\n", name, dma_base); dma_base = 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/pdc202xx.c linux.ac/drivers/ide/pdc202xx.c --- linux.vanilla/drivers/ide/pdc202xx.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/pdc202xx.c Tue May 30 15:17:17 2000 @@ -99,7 +99,7 @@ { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0; u16 reg50h = 0, pmask = (1<<10), smask = (1<<11); u8 c0 = 0, c1 = 0; @@ -408,7 +408,7 @@ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + unsigned long high_16 = pci_resource_start(dev, 4); unsigned long dma_base = hwif->dma_base; byte unit = (drive->select.b.unit & 0x01); @@ -612,7 +612,7 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) { - unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + unsigned long high_16 = pci_resource_start(dev, 4); byte udma_speed_flag = inb(high_16 + 0x001f); byte primary_mode = inb(high_16 + 0x001a); byte secondary_mode = inb(high_16 + 0x001b); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/piix.c linux.ac/drivers/ide/piix.c --- linux.vanilla/drivers/ide/piix.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/ide/piix.c Tue May 30 15:17:17 2000 @@ -83,7 +83,7 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0; u8 c0 = 0, c1 = 0; u8 reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/trm290.c linux.ac/drivers/ide/trm290.c --- linux.vanilla/drivers/ide/trm290.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/trm290.c Tue May 30 15:17:17 2000 @@ -224,10 +224,10 @@ struct pci_dev *dev = hwif->pci_dev; hwif->chipset = ide_trm290; - cfgbase = dev->resource[4].start; + cfgbase = pci_resource_start(dev, 4); if ((dev->class & 5) && cfgbase) { - hwif->config_data = cfgbase & PCI_BASE_ADDRESS_IO_MASK; + hwif->config_data = cfgbase; printk("TRM290: chip config base at 0x%04lx\n", hwif->config_data); } else { hwif->config_data = 0x3df0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/via82cxxx.c linux.ac/drivers/ide/via82cxxx.c --- linux.vanilla/drivers/ide/via82cxxx.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/ide/via82cxxx.c Tue May 30 14:45:15 2000 @@ -101,14 +101,14 @@ struct chipset_bus_clock_list_entry { byte xfer_speed; - byte chipset_settings_25; byte ultra_settings_25; - byte chipset_settings_33; + byte chipset_settings_25; byte ultra_settings_33; - byte chipset_settings_37; + byte chipset_settings_33; byte ultra_settings_37; - byte chipset_settings_41; + byte chipset_settings_37; byte ultra_settings_41; + byte chipset_settings_41; }; static struct chipset_bus_clock_list_entry * via82cxxx_table = NULL; 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/ieee1394/pcilynx.c linux.ac/drivers/ieee1394/pcilynx.c --- linux.vanilla/drivers/ieee1394/pcilynx.c Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/pcilynx.c Tue May 30 15:17:17 2000 @@ -1246,6 +1246,9 @@ lynx->id = num_of_cards-1; lynx->dev = dev; + if(pci_enable_device(dev)) + return -ENXIO; + pci_set_master(dev); if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ, @@ -1301,15 +1304,15 @@ lynx->local_ram = ioremap(dev->base_address[1], PCILYNX_MAX_MEMORY); lynx->aux_port = ioremap(dev->base_address[2], PCILYNX_MAX_MEMORY); #else - lynx->registers = ioremap_nocache(dev->resource[0].start, + lynx->registers = ioremap_nocache(pci_resource_start(dev,0), PCILYNX_MAX_REGISTER); - lynx->local_ram = ioremap(dev->resource[1].start, PCILYNX_MAX_MEMORY); - lynx->aux_port = ioremap(dev->resource[2].start, PCILYNX_MAX_MEMORY); + lynx->local_ram = ioremap(pci_resource_start(dev,1), PCILYNX_MAX_MEMORY); + lynx->aux_port = ioremap(pci_resource_start(dev,2), PCILYNX_MAX_MEMORY); #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,15) lynx->local_rom = ioremap(dev->rom_address, PCILYNX_MAX_MEMORY); #else - lynx->local_rom = ioremap(dev->resource[PCI_ROM_RESOURCE].start, + lynx->local_rom = ioremap(pci_resource_start(dev,PCI_ROM_RESOURCE), PCILYNX_MAX_MEMORY); #endif lynx->state = have_iomappings; 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/de4x5.c linux.ac/drivers/net/de4x5.c --- linux.vanilla/drivers/net/de4x5.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/de4x5.c Tue May 30 15:28:39 2000 @@ -2229,7 +2229,7 @@ lp->chipset = device; /* Get the board I/O address (64 bits on sparc64) */ - iobase = pdev->resource[0].start; + iobase = pci_resource_start(pdev, 0); /* Fetch the IRQ to be used */ irq = pdev->irq; @@ -2318,7 +2318,7 @@ lp->chipset = device; /* Get the board I/O address (64 bits on sparc64) */ - iobase = this_dev->resource[0].start; + iobase = pci_resource_start(this_dev, 0); /* Fetch the IRQ to be used */ irq = this_dev->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/eepro100.c linux.ac/drivers/net/eepro100.c --- linux.vanilla/drivers/net/eepro100.c Thu May 25 17:37:54 2000 +++ linux.ac/drivers/net/eepro100.c Tue May 30 15:01:18 2000 @@ -4,27 +4,17 @@ May not compile for kernels 2.3.43-47. Written 1996-1999 by Donald Becker. + The driver also contains updates by different kernel developers + (see incomplete list below). + Current maintainer is Andrey V. Savochkin . + Please use this email address and linux-kernel mailing list for bug reports. + This software may be used and distributed according to the terms of the GNU Public License, incorporated herein by reference. This driver is for the Intel EtherExpress Pro100 (Speedo3) design. It should work with all i82557/558/559 boards. - The author may be reached as becker@CESDIS.usra.edu, or C/O - Center of Excellence in Space Data and Information Sciences - Code 930.5, NASA Goddard Space Flight Center, Greenbelt MD 20771 - For updates see - http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html - For installation instructions - http://cesdis.gsfc.nasa.gov/linux/misc/modules.html - There is a Majordomo mailing list based at - linux-eepro100@cesdis.gsfc.nasa.gov - - The driver also contains updates by different kernel developers - (see incomplete list below). - This driver clone is maintained by Andrey V. Savochkin . - Please use this email address and linux-kernel mailing list for bug reports. - Version history: 1998 Apr - 2000 Feb Andrey V. Savochkin Serious fixes for multicast filter list setting, TX timeout routine; @@ -33,12 +23,11 @@ Convert to new PCI driver interface 2000 Mar 24 Dragan Stancevic Disabled FC and ER, to avoid lockups when when we get FCP interrupts. - Dragan Stancevic March 24th, 2000. */ static const char *version = "eepro100.c:v1.09j-t 9/29/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n" -"eepro100.c: $Revision: 1.29 $ 2000/03/30 Modified by Andrey V. Savochkin and others\n"; +"eepro100.c: $Revision: 1.33 $ 2000/05/24 Modified by Andrey V. Savochkin and others\n"; /* A few user-configurable values that apply to all boards. First set is undocumented and spelled per Intel recommendations. */ @@ -93,7 +82,6 @@ #error You must compile this driver with "-O". #endif -#include #include #include #if defined(MODVERSIONS) @@ -218,9 +206,13 @@ } #endif -/* The total I/O port extent of the board. - The registers beyond 0x18 only exist on the i82558. */ -#define SPEEDO3_TOTAL_SIZE 0x20 +#ifndef PCI_DEVICE_ID_INTEL_ID1029 +#define PCI_DEVICE_ID_INTEL_ID1029 0x1029 +#endif +#ifndef PCI_DEVICE_ID_INTEL_ID1030 +#define PCI_DEVICE_ID_INTEL_ID1030 0x1030 +#endif + int speedo_debug = 1; @@ -338,21 +330,22 @@ */ -static int speedo_found1(struct pci_dev *pdev, long ioaddr, int irq, int chip_idx, int fnd_cnt, int acpi_idle_state); - -#ifdef USE_IO -#define SPEEDO_IOTYPE PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR1 -#define SPEEDO_SIZE 32 -#else -#define SPEEDO_IOTYPE PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR0 -#define SPEEDO_SIZE 0x1000 -#endif +static int speedo_found1(struct pci_dev *pdev, long ioaddr, int fnd_cnt, int acpi_idle_state); enum pci_flags_bit { PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, }; +static inline unsigned int io_inw(unsigned long port) +{ + return inw(port); +} +static inline void io_outw(unsigned int val, unsigned long port) +{ + outw(val, port); +} + #ifndef USE_IO /* Currently alpha headers define in/out macros. Undefine them. 2000/03/30 SAW */ @@ -377,6 +370,10 @@ int wait = 1000; do ; while(inb(cmd_ioaddr) && --wait >= 0); +#ifndef final_version + if (wait < 0) + printk(KERN_ALERT "eepro100: wait_for_cmd_done timeout!\n"); +#endif } /* Offsets to the various registers. @@ -412,15 +409,15 @@ #endif enum SCBCmdBits { - SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000, - SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400, - SCBTriggerIntr=0x0200, SCBMaskAll=0x0100, - /* The rest are Rx and Tx commands. */ - CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050, - CUCmdBase=0x0060, /* CU Base address (set to zero) . */ - CUDumpStats=0x0070, /* Dump then reset stats counters. */ - RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006, - RxResumeNoResources=0x0007, + SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000, + SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400, + SCBTriggerIntr=0x0200, SCBMaskAll=0x0100, + /* The rest are Rx and Tx commands. */ + CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050, + CUCmdBase=0x0060, /* CU Base address (set to zero) . */ + CUDumpStats=0x0070, /* Dump then reset stats counters. */ + RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006, + RxResumeNoResources=0x0007, }; enum SCBPort_cmds { @@ -656,7 +653,7 @@ pci_set_master(pdev); - if (speedo_found1(pdev, ioaddr, irq, 0, cards_found, acpi_idle_state) == 0) + if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0) cards_found++; else goto err_out_iounmap; @@ -676,7 +673,7 @@ } static int speedo_found1(struct pci_dev *pdev, - long ioaddr, int irq, int chip_idx, int card_idx, int acpi_idle_state) + long ioaddr, int card_idx, int acpi_idle_state) { struct net_device *dev; struct speedo_private *sp; @@ -712,11 +709,15 @@ The size test is for 6 bit vs. 8 bit address serial EEPROMs. */ { - u16 sum = 0; - int j; + unsigned long iobase; int read_cmd, ee_size; + u16 sum; + int j; - if ((do_eeprom_cmd(ioaddr, EE_READ_CMD << 24, 27) & 0xffe0000) + /* Use IO only to avoid postponed writes and satisfy EEPROM timing + requirements. */ + iobase = pci_resource_start(pdev, 1); + if ((do_eeprom_cmd(iobase, EE_READ_CMD << 24, 27) & 0xffe0000) == 0xffe0000) { ee_size = 0x100; read_cmd = EE_READ_CMD << 24; @@ -725,8 +726,8 @@ read_cmd = EE_READ_CMD << 22; } - for (j = 0, i = 0; i < ee_size; i++) { - u16 value = do_eeprom_cmd(ioaddr, read_cmd | (i << 16), 27); + for (j = 0, i = 0, sum = 0; i < ee_size; i++) { + u16 value = do_eeprom_cmd(iobase, read_cmd | (i << 16), 27); eeprom[i] = value; sum += value; if (i < 3) { @@ -739,7 +740,8 @@ "check settings before activating this device!\n", dev->name, sum); /* Don't unregister_netdev(dev); as the EEPro may actually be - usable, especially if the MAC address is set later. */ + usable, especially if the MAC address is set later. + On the other hand, it may be unusable if MDI data is corrupted. */ } /* Reset the chip: stop Tx and Rx processes and clear counters. @@ -760,7 +762,7 @@ #ifdef USE_IO printk("I/O at %#3lx, ", ioaddr); #endif - printk("IRQ %d.\n", irq); + printk("IRQ %d.\n", pdev->irq); #if 1 || defined(kernel_bloat) /* OK, this is pure kernel bloat. I don't like it when other drivers @@ -839,7 +841,7 @@ pdev->driver_data = dev; dev->base_addr = ioaddr; - dev->irq = irq; + dev->irq = pdev->irq; sp = dev->priv; sp->pdev = pdev; @@ -887,30 +889,32 @@ #define EE_WRITE_1 0x4806 #define EE_OFFSET SCBeeprom -/* Delay between EEPROM clock transitions. - The code works with no delay on 33Mhz PCI. */ -#define eeprom_delay() inw(ee_addr) - +/* The fixes for the code were kindly provided by Dragan Stancevic + to strictly follow Intel specifications of EEPROM + access timing. + The publicly available sheet 64486302 (sec. 3.1) specifies 1us access + interval for serial EEPROM. However, it looks like that there is an + additional requirement dictating larger udelay's in the code below. + 2000/05/24 SAW */ static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len) { unsigned retval = 0; long ee_addr = ioaddr + SCBeeprom; - outw(EE_ENB | EE_SHIFT_CLK, ee_addr); + io_outw(EE_ENB, ee_addr); udelay(2); + io_outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2); /* Shift the command bits out. */ do { short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; - outw(dataval, ee_addr); - eeprom_delay(); - outw(dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(); - retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0); + io_outw(dataval, ee_addr); udelay(2); + io_outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2); + retval = (retval << 1) | ((io_inw(ee_addr) & EE_DATA_READ) ? 1 : 0); } while (--cmd_len >= 0); - outw(EE_ENB, ee_addr); + io_outw(EE_ENB, ee_addr); udelay(2); /* Terminate the EEPROM access. */ - outw(EE_ENB & ~EE_CS, ee_addr); + io_outw(EE_ENB & ~EE_CS, ee_addr); udelay(4); return retval; } @@ -1104,8 +1108,11 @@ int partner = mdio_read(ioaddr, phy_num, 5); if (partner != sp->partner) { int flow_ctrl = sp->advertising & partner & 0x0400 ? 1 : 0; - if (speedo_debug > 2) + if (speedo_debug > 2) { printk(KERN_DEBUG "%s: Link status change.\n", dev->name); + printk(KERN_DEBUG "%s: Old partner %x, new %x, adv %x.\n", + dev->name, sp->partner, partner, sp->advertising); + } sp->partner = partner; if (flow_ctrl != sp->flow_ctrl) { sp->flow_ctrl = flow_ctrl; @@ -1137,6 +1144,9 @@ /* We must continue to monitor the media. */ sp->timer.expires = RUN_AT(2*HZ); /* 2.0 sec. */ add_timer(&sp->timer); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,43) + timer_exit(&sp->timer); +#endif /* LINUX_VERSION_CODE */ } static void speedo_show_state(struct net_device *dev) @@ -1169,12 +1179,14 @@ i, (sp->rx_ringp[i] != NULL) ? (unsigned)sp->rx_ringp[i]->status : 0); +#if 0 for (i = 0; i < 16; i++) { /* FIXME: what does it mean? --SAW */ if (i == 6) i = 21; printk(KERN_DEBUG "%s: PHY index %d register %d is %4.4x.\n", dev->name, phy_num, i, mdio_read(ioaddr, phy_num, i)); } +#endif } @@ -1247,6 +1259,29 @@ netif_wake_queue(dev); } +static void reset_mii(struct net_device *dev) +{ + struct speedo_private *sp = (struct speedo_private *)dev->priv; + long ioaddr = dev->base_addr; + /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */ + if ((sp->phy[0] & 0x8000) == 0) { + int phy_addr = sp->phy[0] & 0x1f; + int advertising = mdio_read(ioaddr, phy_addr, 4); + int mii_bmcr = mdio_read(ioaddr, phy_addr, 0); + mdio_write(ioaddr, phy_addr, 0, 0x0400); + mdio_write(ioaddr, phy_addr, 1, 0x0000); + mdio_write(ioaddr, phy_addr, 4, 0x0000); + mdio_write(ioaddr, phy_addr, 0, 0x8000); +#ifdef honor_default_port + mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]); +#else + mdio_read(ioaddr, phy_addr, 0); + mdio_write(ioaddr, phy_addr, 0, mii_bmcr); + mdio_write(ioaddr, phy_addr, 4, advertising); +#endif + } +} + static void speedo_tx_timeout(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; @@ -1273,6 +1308,7 @@ outl(cpu_to_le32(TX_RING_ELEM_DMA(sp, dirty_tx % TX_RING_SIZE])), ioaddr + SCBPointer); outw(CUStart, ioaddr + SCBCmd); + reset_mii(dev); } else { #else { @@ -1283,11 +1319,7 @@ del_timer(&sp->timer); end_bh_atomic(); #else /* LINUX_VERSION_CODE */ -#ifdef CONFIG_SMP del_timer_sync(&sp->timer); -#else /* SMP */ - del_timer(&sp->timer); -#endif /* SMP */ #endif /* LINUX_VERSION_CODE */ /* Reset the Tx and Rx units. */ outl(PortReset, ioaddr + SCBPort); @@ -1310,26 +1342,12 @@ dev->trans_start = jiffies; spin_unlock_irqrestore(&sp->lock, flags); set_rx_mode(dev); /* it takes the spinlock itself --SAW */ + /* Reset MII transceiver. Do it before starting the timer to serialize + mdio_xxx operations. Yes, it's a paranoya :-) 2000/05/09 SAW */ + reset_mii(dev); sp->timer.expires = RUN_AT(2*HZ); add_timer(&sp->timer); } - /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */ - if ((sp->phy[0] & 0x8000) == 0) { - int phy_addr = sp->phy[0] & 0x1f; - int advertising = mdio_read(ioaddr, phy_addr, 4); - int mii_bmcr = mdio_read(ioaddr, phy_addr, 0); - mdio_write(ioaddr, phy_addr, 0, 0x0400); - mdio_write(ioaddr, phy_addr, 1, 0x0000); - mdio_write(ioaddr, phy_addr, 4, 0x0000); - mdio_write(ioaddr, phy_addr, 0, 0x8000); -#ifdef honor_default_port - mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]); -#else - mdio_read(ioaddr, phy_addr, 0); - mdio_write(ioaddr, phy_addr, 0, mii_bmcr); - mdio_write(ioaddr, phy_addr, 4, advertising); -#endif - } return; } @@ -1384,8 +1402,7 @@ sp->tx_ring[entry].link = cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE)); sp->tx_ring[entry].tx_desc_addr = - cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE) + - TX_DESCR_BUF_OFFSET); + cpu_to_le32(TX_RING_ELEM_DMA(sp, entry) + TX_DESCR_BUF_OFFSET); /* The data region is always in one buffer descriptor. */ sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold); sp->tx_ring[entry].tx_buf_addr0 = @@ -1913,7 +1930,7 @@ if (netif_running(dev)) { unsigned long flags; /* Take a spinlock to make wait_for_cmd_done and sending the - * command atomic. --SAW */ + command atomic. --SAW */ spin_lock_irqsave(&sp->lock, flags); wait_for_cmd_done(ioaddr + SCBCmd); outb(CUDumpStats, ioaddr + SCBCmd); @@ -1935,17 +1952,35 @@ case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ data[0] = phy; case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ - /* FIXME: these operations probably need to be serialized with MDIO - access from the timer routine and timeout handler. 2000/03/08 SAW */ + /* FIXME: these operations need to be serialized with MDIO + access from the timeout handler. + They are currently serialized only with MDIO access from the + timer routine. 2000/05/09 SAW */ saved_acpi = pci_set_power_state(sp->pdev, 0); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) + start_bh_atomic(); + data[3] = mdio_read(ioaddr, data[0], data[1]); + end_bh_atomic(); +#else /* LINUX_VERSION_CODE */ + del_timer_sync(&sp->timer); data[3] = mdio_read(ioaddr, data[0], data[1]); + add_timer(&sp->timer); /* may be set to the past --SAW */ +#endif /* LINUX_VERSION_CODE */ pci_set_power_state(sp->pdev, saved_acpi); return 0; case SIOCDEVPRIVATE+2: /* Write the specified MII register */ if (!capable(CAP_NET_ADMIN)) return -EPERM; saved_acpi = pci_set_power_state(sp->pdev, 0); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) + start_bh_atomic(); + mdio_write(ioaddr, data[0], data[1], data[2]); + end_bh_atomic(); +#else /* LINUX_VERSION_CODE */ + del_timer_sync(&sp->timer); mdio_write(ioaddr, data[0], data[1], data[2]); + add_timer(&sp->timer); /* may be set to the past --SAW */ +#endif /* LINUX_VERSION_CODE */ pci_set_power_state(sp->pdev, saved_acpi); return 0; default: @@ -2206,6 +2241,10 @@ PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER, PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029, + PCI_ANY_ID, PCI_ANY_ID, }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030, + PCI_ANY_ID, PCI_ANY_ID, }, { 0,} }; MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl); @@ -2256,6 +2295,7 @@ /* * Local variables: * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" * c-indent-level: 4 * c-basic-offset: 4 * tab-width: 4 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 Tue May 30 15:27:09 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) { @@ -3800,8 +3802,8 @@ host->hostt->use_new_eh_code = 1; host->this_id = tmpt->this_id; - pci_maddr = pdev->resource[0].start; - if ( (pdev->resource[0].flags & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) { + pci_maddr = pci_resource_start(pdev, 0); + if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { printk("iph5526.c : Cannot find proper PCI device base address.\n"); scsi_unregister(host); kfree(fc[count]); 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 Tue May 30 15:27:15 2000 @@ -353,8 +353,12 @@ continue; pdev = pci_find_slot(pci_bus, pci_device_fn); - ioaddr = pdev->resource[0].start; + + ioaddr = pci_resource_start(pdev, 0); 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)) 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/skfp/skfddi.c linux.ac/drivers/net/skfp/skfddi.c --- linux.vanilla/drivers/net/skfp/skfddi.c Thu May 25 17:37:55 2000 +++ linux.ac/drivers/net/skfp/skfddi.c Tue May 30 15:27:47 2000 @@ -305,6 +305,8 @@ pdev)) == 0) { break; } + if (pci_enable_device(pdev)) + continue; #ifndef MEM_MAPPED_IO /* Verify that I/O enable bit is set (PCI slot is enabled) */ @@ -352,7 +354,7 @@ command &= ~PCI_COMMAND_IO; pci_write_config_word(pdev, PCI_COMMAND, command); - port = pdev->resource[0].start; + port = pci_resource_start(pdev, 0); port = (unsigned long)ioremap(port, 0x4000); if (!port){ 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 Tue May 30 17:30:15 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 Tue May 30 15:18:35 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; @@ -242,10 +244,11 @@ pci_device, dev, dev->priv); #endif dev->irq = pci_device->irq; - dev->base_addr = pci_device->resource[0].start & (~3); + dev->base_addr = pci_resource_start(pci_device, 0); dev->init = &streamer_init; streamer_priv->streamer_card_name = (char *)pci_device->resource[0].name; - streamer_priv->streamer_mmio = ioremap(pci_device->resource[1].start, 256); + streamer_priv->streamer_mmio = + ioremap(pci_resource_start(pci_device, 1), 256); if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000)) streamer_priv->pkt_buf_sz = PKT_BUF_SZ; 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 Tue May 30 21:07:58 2000 @@ -29,6 +29,16 @@ * 2/23/00 - Updated to dev_kfree_irq * 3/10/00 - Fixed FDX enable which triggered other bugs also * squashed. + * 5/20/00 - Changes to handle Olympic on LinuxPPC. Endian changes. + * The odd thing about the changes is that the fix for + * endian issues with the big-endian data in the arb, asb... + * was to always swab() the bytes, no matter what CPU. + * That's because the read[wl]() functions always swap the + * bytes on the way in on PPC. + * Fixing the hardware descriptors was another matter, + * because they weren't going through read[wl](), there all + * the results had to be in memory in le32 values. kdaaker + * * * To Do: * @@ -169,13 +179,25 @@ if (pci_present()) { while((pci_device=pci_find_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR_WAKE, pci_device))) { + __u16 pci_command ; + + if (pci_enable_device(pci_device)) + continue; + /* These lines are needed by the PowerPC, it appears +that these flags + * are not being set properly for the PPC, this may +well be fixed with + * the new PCI code */ + pci_read_config_word(pci_device, PCI_COMMAND, &pci_command); + pci_command |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + pci_write_config_word(pci_device, PCI_COMMAND,pci_command); 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 ; } @@ -192,11 +214,13 @@ printk("pci_device: %p, dev:%p, dev->priv: %p\n", pci_device, dev, dev->priv); #endif dev->irq=pci_device->irq; - dev->base_addr=pci_device->resource[0].start; + dev->base_addr=pci_resource_start(pci_device, 0); dev->init=&olympic_init; olympic_priv->olympic_card_name = (char *)pci_device->resource[0].name ; - olympic_priv->olympic_mmio=ioremap(pci_device->resource[1].start,256); - olympic_priv->olympic_lap=ioremap(pci_device->resource[2].start,2048); + olympic_priv->olympic_mmio = + ioremap(pci_resource_start(pci_device,1),256); + olympic_priv->olympic_lap = + ioremap(pci_resource_start(pci_device,2),2048); if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) ) olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; @@ -329,7 +353,7 @@ } } - uaa_addr=ntohs(readw(init_srb+8)); + uaa_addr=swab16(readw(init_srb+8)); #if OLYMPIC_DEBUG printk("UAA resides at %x\n",uaa_addr); @@ -346,8 +370,8 @@ memcpy_fromio(&dev->dev_addr[0], adapter_addr,6); - olympic_priv->olympic_addr_table_addr = ntohs(readw(init_srb + 12)) ; - olympic_priv->olympic_parms_addr = ntohs(readw(init_srb + 14)) ; + olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12)); + olympic_priv->olympic_parms_addr = swab16(readw(init_srb + 14)); return 0; @@ -409,9 +433,9 @@ /* If Network Monitor, instruct card to copy MAC frames through the ARB */ #if OLYMPIC_NETWORK_MONITOR - writew(ntohs(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON),init_srb+8); + writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8); #else - writew(ntohs(OPEN_ADAPTER_ENABLE_FDX),init_srb+8); + writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8); #endif if (olympic_priv->olympic_laa[0]) { @@ -445,7 +469,7 @@ #if OLYMPIC_DEBUG printk("init_srb(%p): ",init_srb); for(i=0;i<20;i++) - printk("%x ",readb(init_srb+i)); + printk("%02x ",readb(init_srb+i)); printk("\n"); #endif @@ -504,10 +528,10 @@ if (olympic_priv->olympic_message_level) printk(KERN_INFO "%s: Opened in %d Mbps mode\n",dev->name, olympic_priv->olympic_ring_speed); - olympic_priv->asb=ntohs(readw(init_srb+8)); - olympic_priv->srb=ntohs(readw(init_srb+10)); - olympic_priv->arb=ntohs(readw(init_srb+12)); - olympic_priv->trb=ntohs(readw(init_srb+16)); + olympic_priv->asb = swab16(readw(init_srb+8)); + olympic_priv->srb = swab16(readw(init_srb+10)); + olympic_priv->arb = swab16(readw(init_srb+12)); + olympic_priv->trb = swab16(readw(init_srb+16)); olympic_priv->olympic_receive_options = 0x01 ; olympic_priv->olympic_copy_all_options = 0 ; @@ -528,8 +552,8 @@ skb->dev = dev; - olympic_priv->olympic_rx_ring[i].buffer=virt_to_bus(skb->data); - olympic_priv->olympic_rx_ring[i].res_length = olympic_priv->pkt_buf_sz ; + olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(virt_to_bus(skb->data)); + olympic_priv->olympic_rx_ring[i].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz); olympic_priv->rx_ring_skb[i]=skb; } @@ -539,17 +563,17 @@ return -EIO; } - writel(virt_to_bus(&olympic_priv->olympic_rx_ring[0]),olympic_mmio+RXDESCQ); - writel(virt_to_bus(&olympic_priv->olympic_rx_ring[0]),olympic_mmio+RXCDA); - writew(i,olympic_mmio+RXDESCQCNT); + writel(virt_to_bus(&olympic_priv->olympic_rx_ring[0]), olympic_mmio+RXDESCQ); + writel(virt_to_bus(&olympic_priv->olympic_rx_ring[0]), olympic_mmio+RXCDA); + writew(i, olympic_mmio+RXDESCQCNT); - writel(virt_to_bus(&olympic_priv->olympic_rx_status_ring[0]),olympic_mmio+RXSTATQ); - writel(virt_to_bus(&olympic_priv->olympic_rx_status_ring[0]),olympic_mmio+RXCSA); + writel(virt_to_bus(&olympic_priv->olympic_rx_status_ring[0]), olympic_mmio+RXSTATQ); + writel(virt_to_bus(&olympic_priv->olympic_rx_status_ring[0]), olympic_mmio+RXCSA); - olympic_priv->rx_ring_last_received=OLYMPIC_RX_RING_SIZE-1; /* last processed rx status */ - olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE-1; + olympic_priv->rx_ring_last_received = OLYMPIC_RX_RING_SIZE - 1; /* last processed rx status */ + olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE - 1; - writew(i,olympic_mmio+RXSTATQCNT); + writew(i, olympic_mmio+RXSTATQCNT); #if OLYMPIC_DEBUG printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ)); @@ -578,9 +602,9 @@ olympic_priv->olympic_tx_ring[i].buffer=0xdeadbeef; olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE; - writel(virt_to_bus(&olympic_priv->olympic_tx_ring[0]),olympic_mmio+TXDESCQ_1); - writel(virt_to_bus(&olympic_priv->olympic_tx_ring[0]),olympic_mmio+TXCDA_1); - writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXDESCQCNT_1); + writel(virt_to_bus(&olympic_priv->olympic_tx_ring[0]), olympic_mmio+TXDESCQ_1); + writel(virt_to_bus(&olympic_priv->olympic_tx_ring[0]), olympic_mmio+TXCDA_1); + writew(OLYMPIC_TX_RING_SIZE, olympic_mmio+TXDESCQCNT_1); writel(virt_to_bus(&olympic_priv->olympic_tx_status_ring[0]),olympic_mmio+TXSTATQ_1); writel(virt_to_bus(&olympic_priv->olympic_tx_status_ring[0]),olympic_mmio+TXCSA_1); @@ -654,34 +678,35 @@ rx_status=&(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received + 1) & (OLYMPIC_RX_RING_SIZE - 1)]) ; while (rx_status->status_buffercnt) { + __u32 l_status_buffercnt; olympic_priv->rx_status_last_received++ ; olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1); #if OLYMPIC_DEBUG printk(" stat_ring addr: %x \n", &(olympic_priv->olympic_rx_status_ring[olympic_priv->rx_status_last_received]) ); - printk("rx status: %x rx len: %x \n",rx_status->status_buffercnt,rx_status->fragmentcnt_framelen); + printk("rx status: %x rx len: %x \n", le32_to_cpu(rx_status->status_buffercnt), le32_to_cpu(rx_status->fragmentcnt_framelen)); #endif - length=rx_status->fragmentcnt_framelen & 0xffff; - buffer_cnt = rx_status->status_buffercnt & 0xffff ; + length = le32_to_cpu(rx_status->fragmentcnt_framelen) & 0xffff; + buffer_cnt = le32_to_cpu(rx_status->status_buffercnt) & 0xffff; i = buffer_cnt ; /* Need buffer_cnt later for rxenq update */ - frag_len = rx_status->fragmentcnt_framelen >> 16 ; + frag_len = le32_to_cpu(rx_status->fragmentcnt_framelen) >> 16; #if OLYMPIC_DEBUG - printk("length: %x, frag_len: %x, buffer_cnt: %x\n",length,frag_len,buffer_cnt); + printk("length: %x, frag_len: %x, buffer_cnt: %x\n", length, frag_len, buffer_cnt); #endif - - if(rx_status->status_buffercnt & 0xC0000000) { - if (rx_status->status_buffercnt & 0x3B000000) { + l_status_buffercnt = le32_to_cpu(rx_status->status_buffercnt); + if(l_status_buffercnt & 0xC0000000) { + if (l_status_buffercnt & 0x3B000000) { if (olympic_priv->olympic_message_level) { - if (rx_status->status_buffercnt & (1<<29)) /* Rx Frame Truncated */ + if (l_status_buffercnt & (1<<29)) /* Rx Frame Truncated */ printk(KERN_WARNING "%s: Rx Frame Truncated \n",dev->name); - if (rx_status->status_buffercnt & (1<<28)) /*Rx receive overrun */ + if (l_status_buffercnt & (1<<28)) /*Rx receive overrun */ printk(KERN_WARNING "%s: Rx Frame Receive overrun \n",dev->name); - if (rx_status->status_buffercnt & (1<<27)) /* No receive buffers */ + if (l_status_buffercnt & (1<<27)) /* No receive buffers */ printk(KERN_WARNING "%s: No receive buffers \n",dev->name); - if (rx_status->status_buffercnt & (1<<25)) /* Receive frame error detect */ + if (l_status_buffercnt & (1<<25)) /* Receive frame error detect */ printk(KERN_WARNING "%s: Receive frame error detect \n",dev->name); - if (rx_status->status_buffercnt & (1<<24)) /* Received Error Detect */ + if (l_status_buffercnt & (1<<24)) /* Received Error Detect */ printk(KERN_WARNING "%s: Received Error Detect \n",dev->name); } olympic_priv->rx_ring_last_received += i ; @@ -717,8 +742,8 @@ skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ; skb_put(skb2,length); skb2->protocol = tr_type_trans(skb2,dev); - olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer=virt_to_bus(skb->data); - olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = olympic_priv->pkt_buf_sz ; + olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer = cpu_to_le32(virt_to_bus(skb->data)); + olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz); olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ; netif_rx(skb2) ; } else { @@ -727,8 +752,8 @@ olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1); rx_ring_last_received = olympic_priv->rx_ring_last_received ; rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]); - cpy_length = (i == 1 ? frag_len : rx_desc->res_length); - memcpy(skb_put(skb, cpy_length), bus_to_virt(rx_desc->buffer), cpy_length) ; + cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length)); + memcpy(skb_put(skb, cpy_length), bus_to_virt(le32_to_cpu(rx_desc->buffer)), cpy_length) ; } while (--i) ; skb->protocol = tr_type_trans(skb,dev); @@ -849,8 +874,8 @@ netif_stop_queue(dev); if(olympic_priv->free_tx_ring_entries) { - olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer=virt_to_bus(skb->data); - olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length=skb->len | (0x80000000); + olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer = cpu_to_le32(virt_to_bus(skb->data)); + olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length = cpu_to_le32(skb->len | (0x80000000)); olympic_priv->tx_ring_skb[olympic_priv->tx_ring_free]=skb; olympic_priv->free_tx_ring_entries--; @@ -1205,9 +1230,9 @@ if (readb(arb_block+0) == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */ header_len = readb(arb_block+8) ; /* 802.5 Token-Ring Header Length */ - frame_len = ntohs(readw(arb_block + 10)) ; + frame_len = swab16(readw(arb_block + 10)) ; - buff_off = ntohs(readw(arb_block + 6)) ; + buff_off = swab16(readw(arb_block + 6)) ; buf_ptr = olympic_priv->olympic_lap + buff_off ; @@ -1229,7 +1254,7 @@ do { frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ; - buffer_len = ntohs(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); + buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ; next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next)); @@ -1271,7 +1296,7 @@ return ; } else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */ - lan_status = ntohs(readw(arb_block+6)); + lan_status = swab16(readw(arb_block+6)); fdx_prot_error = readb(arb_block+8) ; /* Issue ARB Free */ @@ -1535,9 +1560,9 @@ readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+3), readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+4), readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+5), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, att_code)))); + swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code)))); size += sprintf(buffer+size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name) ; @@ -1550,20 +1575,20 @@ readb(opt+offsetof(struct olympic_parameters_table, source_addr)+3), readb(opt+offsetof(struct olympic_parameters_table, source_addr)+4), readb(opt+offsetof(struct olympic_parameters_table, source_addr)+5), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, major_vector))), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, lan_status))), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, local_ring))), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, mon_error))), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, frame_correl)))); + swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, local_ring))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl)))); size += sprintf(buffer+size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n", dev->name) ; size += sprintf(buffer+size, "%6s: : %02x : %02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x : \n", dev->name, - ntohs(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))), - ntohs(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))), + swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+1), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+2), diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tokenring/olympic.h linux.ac/drivers/net/tokenring/olympic.h --- linux.vanilla/drivers/net/tokenring/olympic.h Thu May 25 17:37:52 2000 +++ linux.ac/drivers/net/tokenring/olympic.h Tue May 30 17:11:34 2000 @@ -207,6 +207,8 @@ /* Olympic data structures */ +/* xxxx These structures are all little endian in hardware. */ + struct olympic_tx_desc { __u32 buffer; __u32 status_length; @@ -218,13 +220,15 @@ struct olympic_rx_desc { __u32 buffer; - __u32 res_length ; + __u32 res_length; }; struct olympic_rx_status { __u32 fragmentcnt_framelen; __u32 status_buffercnt; }; +/* xxxx END These structures are all little endian in hardware. */ +/* xxxx There may be more, but I'm pretty sure about these */ struct mac_receive_buffer { __u16 next ; @@ -236,10 +240,10 @@ struct olympic_private { - __u16 srb; - __u16 trb; - __u16 arb; - __u16 asb; + __u16 srb; /* be16 */ + __u16 trb; /* be16 */ + __u16 arb; /* be16 */ + __u16 asb; /* be16 */ __u8 *olympic_mmio; __u8 *olympic_lap; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip/21142.c linux.ac/drivers/net/tulip/21142.c --- linux.vanilla/drivers/net/tulip/21142.c Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/tulip/21142.c Tue May 30 21:05:51 2000 @@ -14,14 +14,15 @@ */ #include "tulip.h" +#include +#include static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, }; -u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, }; +u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, }; static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; - /* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list of available transceivers. */ void t21142_timer(unsigned long data) @@ -82,8 +83,7 @@ tp->csr6 &= 0x00D5; tp->csr6 |= new_csr6; outl(0x0301, ioaddr + CSR12); - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); } next_tick = 3*HZ; } @@ -102,19 +102,22 @@ int csr14 = ((tp->to_advertise & 0x0780) << 9) | ((tp->to_advertise&0x0020)<<1) | 0xffbf; + DPRINTK("ENTER\n"); + dev->if_port = 0; tp->nway = tp->mediasense = 1; tp->nwayset = tp->lpar = 0; if (tulip_debug > 1) - printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, %8.8x.\n", + printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, csr14=%8.8x.\n", dev->name, csr14); outl(0x0001, ioaddr + CSR13); + udelay(100); outl(csr14, ioaddr + CSR14); if (tp->chip_id == PNIC2) tp->csr6 = 0x01a80000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0); else tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0); - tulip_outl_CSR6(tp, tp->csr6); + tulip_outl_csr(tp, tp->csr6, CSR6); if (tp->mtable && tp->mtable->csr15dir) { outl(tp->mtable->csr15dir, ioaddr + CSR15); outl(tp->mtable->csr15val, ioaddr + CSR15); @@ -180,12 +183,12 @@ outl(1, ioaddr + CSR13); } #if 0 /* Restart shouldn't be needed. */ - tulip_outl_CSR6(tp, tp->csr6 | 0x0000); + tulip_outl_csr(tp, tp->csr6 | csr6_sr, CSR6); if (tulip_debug > 2) printk(KERN_DEBUG "%s: Restarting Tx and Rx, CSR5 is %8.8x.\n", dev->name, inl(ioaddr + CSR5)); #endif - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6); if (tulip_debug > 2) printk(KERN_DEBUG "%s: Setting CSR6 %8.8x/%x CSR12 %8.8x.\n", dev->name, tp->csr6, inl(ioaddr + CSR6), @@ -231,8 +234,7 @@ tp->csr6 = 0x83860000; outl(0x0003FF7F, ioaddr + CSR14); outl(0x0301, ioaddr + CSR12); - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip/eeprom.c linux.ac/drivers/net/tulip/eeprom.c --- linux.vanilla/drivers/net/tulip/eeprom.c Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/tulip/eeprom.c Tue May 30 21:05:51 2000 @@ -162,6 +162,10 @@ if (tp->flags & CSR12_IN_SROM) csr12dir = *p++; count = *p++; + /* there is no phy information, don't even try to build mtable */ + if (count == 0) + return; + mtable = (struct mediatable *) kmalloc(sizeof(struct mediatable) + count*sizeof(struct medialeaf), GFP_KERNEL); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip/interrupt.c linux.ac/drivers/net/tulip/interrupt.c --- linux.vanilla/drivers/net/tulip/interrupt.c Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/tulip/interrupt.c Tue May 30 21:05:51 2000 @@ -178,7 +178,7 @@ int maxtx = TX_RING_SIZE; int maxoi = TX_RING_SIZE; int work_count = tulip_max_interrupt_work; - + tp->nir++; do { @@ -236,13 +236,7 @@ if (status & 0x0002) tp->stats.tx_fifo_errors++; if ((status & 0x0080) && tp->full_duplex == 0) tp->stats.tx_heartbeat_errors++; -#ifdef ETHER_STATS - if (status & 0x0100) tp->stats.collisions16++; -#endif } else { -#ifdef ETHER_STATS - if (status & 0x0001) tp->stats.tx_deferred++; -#endif tp->stats.tx_bytes += tp->tx_buffers[entry].skb->len; tp->stats.collisions += (status >> 3) & 15; @@ -280,8 +274,7 @@ printk(KERN_WARNING "%s: The transmitter stopped." " CSR5 is %x, CSR6 %x, new CSR6 %x.\n", dev->name, csr5, inl(ioaddr + CSR6), tp->csr6); - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); } spin_unlock(&tp->lock); } @@ -297,14 +290,13 @@ else tp->csr6 |= 0x00200000; /* Store-n-forward. */ /* Restart the transmit process. */ - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); outl(0, ioaddr + CSR1); } if (csr5 & RxDied) { /* Missed a Rx frame. */ tp->stats.rx_errors++; tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff; - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6); } if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) { if (tp->link_change) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip/media.c linux.ac/drivers/net/tulip/media.c --- linux.vanilla/drivers/net/tulip/media.c Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/tulip/media.c Tue May 30 21:05:51 2000 @@ -388,8 +388,7 @@ tp->csr6 &= ~0x00400000; if (tp->full_duplex) tp->csr6 |= 0x0200; else tp->csr6 &= ~0x0200; - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); if (tulip_debug > 0) printk(KERN_INFO "%s: Setting %s-duplex based on MII" "#%d link partner capability of %4.4x.\n", diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip/pnic.c linux.ac/drivers/net/tulip/pnic.c --- linux.vanilla/drivers/net/tulip/pnic.c Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/tulip/pnic.c Tue May 30 21:05:51 2000 @@ -44,8 +44,7 @@ if (tp->csr6 != new_csr6) { tp->csr6 = new_csr6; /* Restart Tx */ - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); dev->trans_start = jiffies; } } @@ -65,7 +64,7 @@ outl((inl(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7); if (! tp->nwayset || jiffies - dev->trans_start > 1*HZ) { tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff); - tulip_outl_CSR6(tp, tp->csr6); + tulip_outl_csr(tp, tp->csr6, CSR6); outl(0x30, ioaddr + CSR12); outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */ dev->trans_start = jiffies; @@ -128,8 +127,7 @@ if (tp->csr6 != new_csr6) { tp->csr6 = new_csr6; /* Restart Tx */ - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); dev->trans_start = jiffies; if (tulip_debug > 1) printk(KERN_INFO "%s: Changing PNIC configuration to %s " diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip/timer.c linux.ac/drivers/net/tulip/timer.c --- linux.vanilla/drivers/net/tulip/timer.c Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/tulip/timer.c Tue May 30 21:05:51 2000 @@ -154,8 +154,7 @@ medianame[tp->mtable->mleaf[tp->cur_index].media]); tulip_select_media(dev, 0); /* Restart the transmit process. */ - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); next_tick = (24*HZ)/10; break; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip/tulip.h linux.ac/drivers/net/tulip/tulip.h --- linux.vanilla/drivers/net/tulip/tulip.h Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/tulip/tulip.h Tue May 30 21:05:51 2000 @@ -169,31 +169,54 @@ csr6_ra = (1<<30), csr6_ign_dest_msb = (1<<26), csr6_mbo = (1<<25), - csr6_scr = (1<<24), - csr6_pcs = (1<<23), - csr6_ttm = (1<<22), - csr6_sf = (1<<21), - csr6_hbd = (1<<19), - csr6_ps = (1<<18), - csr6_ca = (1<<17), - csr6_st = (1<<13), - csr6_fc = (1<<12), - csr6_om_int_loop = (1<<10), - csr6_om_ext_loop = (1<<11), - csr6_fd = (1<<9), - csr6_pm = (1<<7), - csr6_pr = (1<<6), - csr6_sb = (1<<5), - csr6_if = (1<<4), - csr6_pb = (1<<3), - csr6_ho = (1<<2), - csr6_sr = (1<<1), - csr6_hp = (1<<0), + csr6_scr = (1<<24), /* scramble mode flag: can't be set */ + csr6_pcs = (1<<23), /* Enables PCS functions (symbol mode requires csr6_ps be set) default is set */ + csr6_ttm = (1<<22), /* Transmit Threshold Mode, set for 10baseT, 0 for 100BaseTX */ + csr6_sf = (1<<21), /* Store and forward. If set ignores TR bits */ + csr6_hbd = (1<<19), /* Heart beat disable. Disables SQE function in 10baseT */ + csr6_ps = (1<<18), /* Port Select. 0 (defualt) = 10baseT, 1 = 100baseTX: can't be set */ + csr6_ca = (1<<17), /* Collision Offset Enable. If set uses special algorithm in low collision situations */ + csr6_trh = (1<<15), /* Transmit Threshold high bit */ + csr6_trl = (1<<14), /* Transmit Threshold low bit */ + + /*************************************************************** + * This table shows transmit threshold values based on media * + * and these two registers (from PNIC1 & 2 docs) Note: this is * + * all meaningless if sf is set. * + ***************************************************************/ + + /*********************************** + * (trh,trl) * 100BaseTX * 10BaseT * + *********************************** + * (0,0) * 128 * 72 * + * (0,1) * 256 * 96 * + * (1,0) * 512 * 128 * + * (1,1) * 1024 * 160 * + ***********************************/ + + csr6_st = (1<<13), /* Transmit conrol: 1 = transmit, 0 = stop */ + csr6_fc = (1<<12), /* Forces a collision in next transmission (for testing in loopback mode) */ + csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */ + csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */ + /* set both and you get (PHY) loopback */ + csr6_fd = (1<<9), /* Full duplex mode, disables hearbeat, no loopback */ + csr6_pm = (1<<7), /* Pass All Multicast */ + csr6_pr = (1<<6), /* Promiscuous mode */ + csr6_sb = (1<<5), /* Start(1)/Stop(0) backoff counter */ + csr6_if = (1<<4), /* Inverse Filtering, rejects only addresses in address table: can't be set */ + csr6_pb = (1<<3), /* Pass Bad Frames, (1) causes even bad frames to be passed on */ + csr6_ho = (1<<2), /* Hash-only filtering mode: can't be set */ + csr6_sr = (1<<1), /* Start(1)/Stop(0) Receive */ + csr6_hp = (1<<0), /* Hash/Perfect Receive Filtering Mode: can't be set */ csr6_mask_capture = (csr6_sc | csr6_ca), csr6_mask_defstate = (csr6_mask_capture | csr6_mbo), - csr6_mask_fullcap = (csr6_mask_defstate | csr6_hbd | - csr6_ps | (3<<14) | csr6_fd), + csr6_mask_hdcap = (csr6_mask_defstate | csr6_hbd | csr6_ps), + csr6_mask_hdcaptt = (csr6_mask_hdcap | csr6_trh | csr6_trl), + csr6_mask_fullcap = (csr6_mask_hdcaptt | csr6_fd), + csr6_mask_fullpromisc = (csr6_pr | csr6_pm), + csr6_mask_filters = (csr6_hp | csr6_ho | csr6_if), + csr6_mask_100bt = (csr6_scr | csr6_pcs | csr6_hbd), }; @@ -397,11 +420,20 @@ extern u16 t21041_csr15[]; -extern inline void tulip_outl_CSR6 (struct tulip_private *tp, u32 newcsr6) +static inline void tulip_outl_csr (struct tulip_private *tp, u32 newValue, enum tulip_offsets offset) { - long ioaddr = tp->base_addr; + outl (newValue, tp->base_addr + offset); +} - outl (newcsr6, ioaddr + CSR6); +static inline void tulip_stop_rxtx(struct tulip_private *tp, u32 csr6mask) +{ + tulip_outl_csr(tp, csr6mask & ~(csr6_st | csr6_sr), CSR6); +} + +static inline void tulip_restart_rxtx(struct tulip_private *tp, u32 csr6mask) +{ + tulip_outl_csr(tp, csr6mask | csr6_sr, CSR6); + tulip_outl_csr(tp, csr6mask | csr6_st | csr6_sr, CSR6); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip/tulip_core.c linux.ac/drivers/net/tulip/tulip_core.c --- linux.vanilla/drivers/net/tulip/tulip_core.c Thu May 25 17:37:57 2000 +++ linux.ac/drivers/net/tulip/tulip_core.c Tue May 30 21:05:51 2000 @@ -19,7 +19,7 @@ */ -static const char version[] = "Linux Tulip driver version 0.9.4.3 (Apr 14, 2000)\n"; +static const char version[] = "Linux Tulip driver version 0.9.5 (May 30, 2000)\n"; #include #include "tulip.h" @@ -50,7 +50,8 @@ }; /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */ -#if defined(__alpha__) || defined(__arm__) || defined(__sparc__) +#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \ + || defined(__sparc_) static int rx_copybreak = 1518; #else static int rx_copybreak = 100; @@ -71,7 +72,7 @@ #if defined(__alpha__) static int csr0 = 0x01A00000 | 0xE000; -#elif defined(__i386__) || defined(__powerpc__) +#elif defined(__i386__) || defined(__powerpc__) || defined(__hppa__) static int csr0 = 0x01A00000 | 0x8000; #elif defined(__sparc__) /* The UltraSparc PCI controllers will disconnect at every 64-byte @@ -124,7 +125,7 @@ { "Digital DS21140 Tulip", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, tulip_timer }, { "Digital DS21143 Tulip", 128, 0x0801fbff, - HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY + HAS_MII | HAS_MEDIA_TABLE | HAS_NWAY | HAS_INTR_MITIGATION, t21142_timer }, { "Lite-On 82c168 PNIC", 256, 0x0001ebef, HAS_MII | HAS_PNICNWAY, pnic_timer }, @@ -210,13 +211,15 @@ int next_tick = 3*HZ; int i; + DPRINTK("ENTER\n"); + /* Wake the chip from sleep/snooze mode. */ if (tp->flags & HAS_ACPI) pci_write_config_dword(tp->pdev, 0x40, 0); /* On some chip revs we must set the MII/SYM port before the reset!? */ if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii)) - tulip_outl_CSR6 (tp, 0x00040000); + tulip_outl_csr (tp, 0x00040000, CSR6); /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ outl(0x00000001, ioaddr + CSR0); @@ -311,9 +314,9 @@ tp->csr6 = 0; tp->cur_index = i; tp->nwayset = 0; - if (dev->if_port == 0 && tp->chip_id == DC21041) { + if (dev->if_port == 0 && tp->chip_id == DC21041) tp->nway = 1; - } + if (dev->if_port == 0 && tp->chip_id == DC21142) { if (tp->mii_cnt) { tulip_select_media(dev, 1); @@ -321,8 +324,8 @@ printk(KERN_INFO "%s: Using MII transceiver %d, status " "%4.4x.\n", dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1)); - tulip_outl_CSR6(tp, 0x82020000); - tp->csr6 = 0x820E0000; + tulip_outl_csr(tp, csr6_mask_defstate, CSR6); + tp->csr6 = csr6_mask_hdcap; dev->if_port = 11; outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); @@ -371,13 +374,13 @@ tulip_select_media(dev, 1); /* Start the chip's Tx to process setup frame. */ - tulip_outl_CSR6(tp, tp->csr6); - tulip_outl_CSR6(tp, tp->csr6 | 0x2000); + tulip_outl_csr(tp, tp->csr6, CSR6); + tulip_outl_csr(tp, tp->csr6 | csr6_st, CSR6); /* Enable interrupts by setting the interrupt mask. */ outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5); outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_outl_csr(tp, tp->csr6 | csr6_st | csr6_sr, CSR6); outl(0, ioaddr + CSR2); /* Rx poll demand */ if (tulip_debug > 2) { @@ -421,6 +424,8 @@ long ioaddr = dev->base_addr; unsigned long flags; + DPRINTK("ENTER\n"); + spin_lock_irqsave (&tp->lock, flags); if (tulip_media_cap[dev->if_port] & MediaIsMII) { @@ -510,8 +515,7 @@ #endif /* Stop and restart the chip's Tx processes . */ - tulip_outl_CSR6(tp, tp->csr6 | 0x0002); - tulip_outl_CSR6(tp, tp->csr6 | 0x2002); + tulip_restart_rxtx(tp, tp->csr6); /* Trigger an immediate transmit demand. */ outl(0, ioaddr + CSR1); @@ -529,6 +533,8 @@ struct tulip_private *tp = (struct tulip_private *)dev->priv; int i; + DPRINTK("ENTER\n"); + tp->tx_full = 0; tp->cur_rx = tp->cur_tx = 0; tp->dirty_rx = tp->dirty_tx = 0; @@ -584,12 +590,11 @@ int entry; u32 flag; dma_addr_t mapping; - unsigned long cpuflags; /* Caution: the write order is important here, set the field with the ownership bits last. */ - spin_lock_irqsave(&tp->lock, cpuflags); + spin_lock_irq(&tp->lock); /* Calculate the next Tx descriptor entry. */ entry = tp->cur_tx % TX_RING_SIZE; @@ -621,7 +626,7 @@ /* Trigger an immediate transmit demand. */ outl(0, dev->base_addr + CSR1); - spin_unlock_irqrestore(&tp->lock, cpuflags); + spin_unlock_irq(&tp->lock); dev->trans_start = jiffies; @@ -642,7 +647,7 @@ outl (0x00000000, ioaddr + CSR7); /* Stop the Tx and Rx processes. */ - tulip_outl_CSR6 (tp, inl (ioaddr + CSR6) & ~0x2002); + tulip_stop_rxtx(tp, inl(ioaddr + CSR6)); /* 21040 -- Leave the card in 10baseT state. */ if (tp->chip_id == DC21040) @@ -839,7 +844,14 @@ { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; - int csr6 = inl(ioaddr + CSR6) & ~0x00D5; + int csr6, need_lock = 0; + unsigned long flags; + + DPRINTK("ENTER\n"); + + spin_lock_irqsave(&tp->lock, flags); + csr6 = inl(ioaddr + CSR6) & ~0x00D5; + spin_unlock_irqrestore(&tp->lock, flags); tp->csr6 &= ~0x00D5; if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ @@ -847,10 +859,14 @@ csr6 |= 0x00C0; /* Unconditionally log net taps. */ printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name); + + need_lock = 1; } else if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) { /* Too many to filter well -- accept all multicasts. */ tp->csr6 |= 0x0080; csr6 |= 0x0080; + + need_lock = 1; } else if (tp->flags & MC_HASH_ONLY) { /* Some work-alikes have only a 64-entry hash filter table. */ /* Should verify correctness on big-endian/__powerpc__ */ @@ -860,27 +876,35 @@ if (dev->mc_count > 64) { /* Arbitrary non-effective limit. */ tp->csr6 |= 0x0080; csr6 |= 0x0080; + need_lock = 1; } else { mc_filter[1] = mc_filter[0] = 0; for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, mc_filter); + if (tp->chip_id == AX88140) { + spin_lock_irqsave(&tp->lock, flags); outl(2, ioaddr + CSR13); outl(mc_filter[0], ioaddr + CSR14); outl(3, ioaddr + CSR13); outl(mc_filter[1], ioaddr + CSR14); + /* need_lock = 0; */ } else if (tp->chip_id == COMET) { /* Has a simple hash filter. */ + spin_lock_irqsave(&tp->lock, flags); outl(mc_filter[0], ioaddr + 0xAC); outl(mc_filter[1], ioaddr + 0xB0); + /* need_lock = 0; */ + } else { + need_lock = 1; } } + } else { u16 *eaddrs, *setup_frm = tp->setup_frame; struct dev_mc_list *mclist; u32 tx_flags = 0x08000000 | 192; int i; - unsigned long flags; /* Note that only the low-address shortword of setup_frame is valid! The values are doubled for big-endian architectures. */ @@ -923,7 +947,7 @@ if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) { /* Same setup recently queued, we need not add it. */ } else { - unsigned int entry; + unsigned int entry, dummy = -1; /* Now add this frame to the Tx list. */ @@ -936,7 +960,8 @@ tp->tx_ring[entry].length = (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0; tp->tx_ring[entry].buffer1 = 0; - tp->tx_ring[entry].status = cpu_to_le32(DescOwned); + /* Must set DescOwned later to avoid race with chip */ + dummy = entry; entry = tp->cur_tx++ % TX_RING_SIZE; } @@ -952,6 +977,8 @@ tp->tx_ring[entry].buffer1 = cpu_to_le32(tp->tx_buffers[entry].mapping); tp->tx_ring[entry].status = cpu_to_le32(DescOwned); + if (dummy >= 0) + tp->tx_ring[dummy].status = cpu_to_le32(DescOwned); if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) { netif_stop_queue(dev); tp->tx_full = 1; @@ -961,10 +988,15 @@ outl(0, ioaddr + CSR1); } - - spin_unlock_irqrestore(&tp->lock, flags); } - tulip_outl_CSR6(tp, csr6 | 0x0000); + + if (need_lock) + spin_lock_irqsave(&tp->lock, flags); + + /* Can someone explain to me what the OR here is supposed to accomplish???? */ + tulip_outl_csr(tp, csr6 | 0x0000, CSR6); + + spin_unlock_irqrestore(&tp->lock, flags); } @@ -999,29 +1031,33 @@ ioaddr = pci_resource_start (pdev, 0); irq = pdev->irq; - /* init_etherdev ensures qword aligned structures */ + /* init_etherdev ensures aligned and zeroed private structures */ dev = init_etherdev (NULL, sizeof (*tp)); if (!dev) { printk (KERN_ERR PFX "ether device alloc failed, aborting\n"); return -ENOMEM; } - /* We do a request_region() only to register /proc/ioports info. */ - /* Note that proper size is tulip_tbl[chip_idx].chip_name, but... */ - if (!request_region (ioaddr, tulip_tbl[chip_idx].io_size, dev->name)) { + /* grab all resources from both PIO and MMIO regions, as we + * don't want anyone else messing around with our hardware */ + if (!request_region (pci_resource_start (pdev, 0), + pci_resource_len (pdev, 0), + dev->name)) { printk (KERN_ERR PFX "I/O ports (0x%x@0x%lx) unavailable, " "aborting\n", tulip_tbl[chip_idx].io_size, ioaddr); goto err_out_free_netdev; } - - if (pci_enable_device(pdev)) { - printk (KERN_ERR PFX "cannot enable PCI device (id %04x:%04x, " - "bus %d, devfn %d), aborting\n", - pdev->vendor, pdev->device, - pdev->bus->number, pdev->devfn); - goto err_out_free_netdev; + if (!request_mem_region (pci_resource_start (pdev, 1), + pci_resource_len (pdev, 1), + dev->name)) { + printk (KERN_ERR PFX "MMIO resource (0x%x@0x%lx) unavailable, " + "aborting\n", tulip_tbl[chip_idx].io_size, ioaddr); + goto err_out_free_pio_res; } + if (pci_enable_device(pdev)) + goto err_out_free_mmio_res; + pci_set_master(pdev); pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev); @@ -1044,8 +1080,13 @@ tp->pdev = pdev; tp->base_addr = ioaddr; tp->revision = chip_rev; + tp->csr0 = csr0; spin_lock_init(&tp->lock); + dev->base_addr = ioaddr; + dev->irq = irq; + pdev->driver_data = dev; + #ifdef TULIP_FULL_DUPLEX tp->full_duplex = 1; tp->full_duplex_lock = 1; @@ -1060,8 +1101,17 @@ printk(KERN_INFO "%s: %s rev %d at %#3lx,", dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr); + /* bugfix: the ASIX must have a burst limit or horrible things happen. */ + if (chip_idx == AX88140) { + if ((tp->csr0 & 0x3f00) == 0) + tp->csr0 |= 0x2000; + } + else if (chip_idx == DC21143 && chip_rev == 65) + tp->csr0 &= ~0x01000000; + /* Stop the chip's Tx and Rx processes. */ - tulip_outl_CSR6(tp, inl(ioaddr + CSR6) & ~0x2002); + tulip_stop_rxtx(tp, inl(ioaddr + CSR6)); + /* Clear the missed-packet counter. */ (volatile int)inl(ioaddr + CSR8); @@ -1158,20 +1208,6 @@ printk(", IRQ %d.\n", irq); last_irq = irq; - pdev->driver_data = dev; - dev->base_addr = ioaddr; - dev->irq = irq; - tp->csr0 = csr0; - - /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles. - And the ASIX must have a burst limit or horrible things happen. */ - if (chip_idx == DC21143 && chip_rev == 65) - tp->csr0 &= ~0x01000000; - else if (chip_idx == AX88140) { - if ((tp->csr0 & 0x3f00) == 0) - tp->csr0 |= 0x2000; - } - /* The lower four bits are the media type. */ if (board_idx >= 0 && board_idx < MAX_UNITS) { tp->default_port = options[board_idx] & 15; @@ -1198,7 +1234,7 @@ else tp->to_advertise = 0x01e1; - /* This is logically part of probe1(), but too complex to write inline. */ + /* This is logically part of _init_one(), but too complex to write inline. */ if (tp->flags & HAS_MEDIA_TABLE) { memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom)); tulip_parse_eeprom(dev); @@ -1280,7 +1316,7 @@ outl(0x00000000, ioaddr + CSR13); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ - tulip_outl_CSR6(tp, inl(ioaddr + CSR6) | 0x0200); + tulip_outl_csr(tp, inl(ioaddr + CSR6) | csr6_fd, CSR6); outl(0x0000EF05, ioaddr + CSR13); break; case DC21040: @@ -1295,10 +1331,10 @@ case DC21142: case PNIC2: if (tp->mii_cnt || tulip_media_cap[dev->if_port] & MediaIsMII) { - tulip_outl_CSR6(tp, 0x82020000); + tulip_outl_csr(tp, csr6_mask_defstate, CSR6); outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); - tulip_outl_CSR6(tp, 0x820E0000); + tulip_outl_csr(tp, csr6_mask_hdcap, CSR6); } else t21142_start_nway(dev); break; @@ -1306,19 +1342,21 @@ if ( ! tp->mii_cnt) { tp->nway = 1; tp->nwayset = 0; - tulip_outl_CSR6(tp, 0x00420000); + tulip_outl_csr(tp, csr6_ttm | csr6_ca, CSR6); outl(0x30, ioaddr + CSR12); - tulip_outl_CSR6(tp, 0x0001F078); - tulip_outl_CSR6(tp, 0x0201F078); /* Turn on autonegotiation. */ + tulip_outl_csr(tp, 0x0001F078, CSR6); + tulip_outl_csr(tp, 0x0201F078, CSR6); /* Turn on autonegotiation. */ } break; - case MX98713: case COMPEX9881: - tulip_outl_CSR6(tp, 0x00000000); + case MX98713: + case COMPEX9881: + tulip_outl_csr(tp, 0x00000000, CSR6); outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */ outl(0x00000001, ioaddr + CSR13); break; - case MX98715: case MX98725: - tulip_outl_CSR6(tp, 0x01a80000); + case MX98715: + case MX98725: + tulip_outl_csr(tp, 0x01a80000, CSR6); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00001000, ioaddr + CSR12); break; @@ -1333,6 +1371,12 @@ return 0; +err_out_free_mmio_res: + release_mem_region (pci_resource_start (pdev, 1), + pci_resource_len (pdev, 1)); +err_out_free_pio_res: + release_region (pci_resource_start (pdev, 0), + pci_resource_len (pdev, 0)); err_out_free_netdev: unregister_netdev (dev); kfree (dev); @@ -1376,8 +1420,10 @@ tp->rx_ring, tp->rx_ring_dma); unregister_netdev(dev); - release_region(dev->base_addr, - tulip_tbl[tp->chip_id].io_size); + release_mem_region (pci_resource_start (pdev, 1), + pci_resource_len (pdev, 1)); + release_region (pci_resource_start (pdev, 0), + pci_resource_len (pdev, 0)); kfree(dev); } } 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/pcmcia/yenta.c linux.ac/drivers/pcmcia/yenta.c --- linux.vanilla/drivers/pcmcia/yenta.c Thu May 25 17:38:23 2000 +++ linux.ac/drivers/pcmcia/yenta.c Tue May 30 15:19:04 2000 @@ -788,7 +788,7 @@ */ if (pci_enable_device(dev)) return -1; - if (!dev->resource[0].start) { + if (!pci_resource_start(dev, 0)) { printk("No cardbus resource!\n"); return -1; } @@ -797,7 +797,7 @@ * Ok, start setup.. Map the cardbus registers, * and request the IRQ. */ - socket->base = ioremap(dev->resource[0].start, 0x1000); + socket->base = ioremap(pci_resource_start(dev, 0), 0x1000); if (!socket->base) return -1; 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 Tue May 30 15:21:26 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) { @@ -582,11 +584,11 @@ } /* Calculate the cards register addresses */ - tw_dev->registers.base_addr = tw_pci_dev->resource[0].start; - tw_dev->registers.control_reg_addr = (tw_pci_dev->resource[0].start & ~15); - tw_dev->registers.status_reg_addr = ((tw_pci_dev->resource[0].start & ~15) + 0x4); - tw_dev->registers.command_que_addr = ((tw_pci_dev->resource[0].start & ~15) + 0x8); - tw_dev->registers.response_que_addr = ((tw_pci_dev->resource[0].start & ~15) + 0xC); + tw_dev->registers.base_addr = pci_resource_start(tw_pci_dev, 0); + tw_dev->registers.control_reg_addr = pci_resource_start(tw_pci_dev, 0); + tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4; + tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8; + tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC; /* Save pci_dev struct to device extension */ tw_dev->tw_pci_dev = tw_pci_dev; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/53c7,8xx.c linux.ac/drivers/scsi/53c7,8xx.c --- linux.vanilla/drivers/scsi/53c7,8xx.c Thu May 25 17:38:04 2000 +++ linux.ac/drivers/scsi/53c7,8xx.c Tue May 30 15:21:26 2000 @@ -1412,8 +1412,10 @@ " perhaps you specified an incorrect PCI bus, device, or function.\n", error); return -1; } - io_port = pdev->resource[0].start; - base = pdev->resource[1].start; + if (pci_enable_device(pdev)) + return -1; + io_port = pci_resource_start(pdev, 0); + base = pci_resource_start(pdev, 1); irq = pdev->irq; /* If any one ever clones the NCR chips, this will have to change */ 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 Tue May 30 15:21:26 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++; @@ -696,7 +692,7 @@ instance = scsi_register(tpnt, sizeof(struct AM53C974_hostdata)); hostdata = (struct AM53C974_hostdata *) instance->hostdata; instance->base = 0; - instance->io_port = pdev->resource[0].start; + instance->io_port = pci_resource_start(pdev, 0); instance->irq = pdev->irq; instance->dma_channel = -1; AM53C974_setio(instance); 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 Tue May 30 15:21:26 2000 @@ -771,12 +771,15 @@ unsigned char Bus = PCI_Device->bus->number; unsigned char Device = PCI_Device->devfn >> 3; unsigned int IRQ_Channel = PCI_Device->irq; - unsigned long BaseAddress0 = PCI_Device->resource[0].start; - unsigned long BaseAddress1 = PCI_Device->resource[1].start; + unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0); + unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1); 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)) + if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, BaseAddress0); @@ -784,7 +787,7 @@ NULL, Bus, Device, IO_Address); continue; } - if (PCI_Device->resource[1].flags & PCI_BASE_ADDRESS_SPACE_IO) + if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO) { BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, BaseAddress1); @@ -973,7 +976,10 @@ unsigned char Bus = PCI_Device->bus->number; unsigned char Device = PCI_Device->devfn >> 3; unsigned int IRQ_Channel = PCI_Device->irq; - BusLogic_IO_Address_T IO_Address = PCI_Device->resource[0].start; + BusLogic_IO_Address_T IO_Address = pci_resource_start(PCI_Device, 0); + + if (pci_enable_device(PCI_Device)) + continue; if (IO_Address == 0 || IRQ_Channel == 0) continue; for (i = 0; i < BusLogic_ProbeInfoCount; i++) @@ -1017,12 +1023,16 @@ unsigned char Bus = PCI_Device->bus->number; unsigned char Device = PCI_Device->devfn >> 3; unsigned int IRQ_Channel = PCI_Device->irq; - unsigned long BaseAddress0 = PCI_Device->resource[0].start; - unsigned long BaseAddress1 = PCI_Device->resource[1].start; + unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0); + unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1); BusLogic_IO_Address_T IO_Address = BaseAddress0; BusLogic_PCI_Address_T PCI_Address = BaseAddress1; + + if (pci_enable_device(PCI_Device)) + continue; + #ifndef CONFIG_SCSI_OMIT_FLASHPOINT - if (!(PCI_Device->resource[0].flags & PCI_BASE_ADDRESS_SPACE_IO)) + if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0); @@ -1030,7 +1040,7 @@ NULL, Bus, Device, IO_Address); continue; } - if (PCI_Device->resource[1].flags & PCI_BASE_ADDRESS_SPACE_IO) + if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) { BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1); 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 Tue May 30 15:21:26 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; } } @@ -4739,7 +4740,7 @@ #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,13) iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK; #else /* version >= v2.3.13 */ - iop = pci_devp->resource[0].start & PCI_IOADDRESS_MASK; + iop = pci_resource_start(pci_devp, 0); #endif /* version >= v2.3.13 */ ASC_DBG2(1, "advansys_detect: vendorID %X, deviceID %X\n", @@ -4900,7 +4901,7 @@ #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,13) pci_memory_address = pci_devp->base_address[1]; #else /* version >= v2.3.13 */ - pci_memory_address = pci_devp->resource[1].start; + pci_memory_address = pci_resource_start(pci_devp, 1); #endif /* version >= v2.3.13 */ ASC_DBG1(1, "advansys_detect: pci_memory_address: %x\n", pci_memory_address); 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 Tue May 30 15:22:21 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)) @@ -9587,8 +9588,8 @@ temp_p->pdev = pdev; temp_p->pci_bus = pdev->bus->number; temp_p->pci_device_fn = pdev->devfn; - temp_p->base = pdev->resource[0].start; - temp_p->mbase = pdev->resource[1].start; + temp_p->base = pci_resource_start(pdev, 0); + temp_p->mbase = pci_resource_start(pdev, 1); current_p = list_p; while(current_p && temp_p) { 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 Tue May 30 15:22:21 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; @@ -1650,7 +1650,7 @@ } /* Found an atp870u/w. */ - base_io = pdev[h]->resource[0].start; + base_io = pci_resource_start(pdev[h], 0); irq = pdev[h]->irq; error = pci_read_config_byte(pdev[h],0x49,&host_id); 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 Tue May 30 15:22:21 2000 @@ -1388,20 +1388,22 @@ #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)) { + base = pci_resource_flags(dev, 0); + if (base & IORESOURCE_MEM) { printk("eata_dma: invalid base address of device %s\n", dev->name); continue; } - base = dev->resource[0].start; + base = pci_resource_start(dev, 0); /* EISA tag there ? */ pal1 = inb(base); pal2 = inb(base + 1); 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 Tue May 30 15:22:21 2000 @@ -878,19 +878,21 @@ #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)) { + base = pci_resource_flags(dev, 0); + if (base & IORESOURCE_MEM) { printk("eata_pio: invalid base address of device %s\n", dev->name); continue; } - base = dev->resource[0].start; + base = pci_resource_start(dev, 0); /* EISA tag there ? */ if ((inb(base) == 0x12) && (inb(base + 1) == 0x14)) continue; /* Jep, it's forced, so move on */ 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 Tue May 30 15:22:33 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:" @@ -840,7 +841,7 @@ /* We now have the appropriate device function for the FD board so we just read the PCI config info from the registers. */ - pci_base = pdev->resource[0].start; + pci_base = pci_resource_start(pdev, 0); pci_irq = pdev->irq; /* Now we have the I/O base address and interrupt from the PCI 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 Tue May 30 21:42:57 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 Tue May 30 21:42:57 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 Tue May 30 15:23:02 2000 @@ -325,12 +325,13 @@ 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; func = dev->devfn; - io_addr = dev->resource[0].start; + io_addr = pci_resource_start(dev, 0); /* get planer status */ if (pci_read_config_word(dev, 0x04, &planer)) { @@ -341,7 +342,7 @@ } /* check I/O address */ - if ((dev->resource[0].flags & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) + if (pci_resource_flags(dev, 0) & IORESOURCE_MEM) continue; /* check to see if an onboard planer controller is disabled */ 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 Tue May 30 15:23:41 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; @@ -2004,7 +2006,7 @@ printk("qlogicfc%d : error reading PCI configuration\n", hostdata->host_id); return 1; } - io_base = pdev->resource[0].start; + io_base = pci_resource_start(pdev, 0); irq = pdev->irq; 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 Tue May 30 15:23:41 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; @@ -1371,10 +1374,10 @@ return 1; } - io_base = pdev->resource[0].start; - mem_base = pdev->resource[1].start; - io_flags = pdev->resource[0].flags; - mem_flags = pdev->resource[1].flags; + io_base = pci_resource_start(pdev, 0); + mem_base = pci_resource_start(pdev, 1); + io_flags = pci_resource_flags(pdev, 0); + mem_flags = pci_resource_flags(pdev, 1); irq = pdev->irq; if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) { 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 Tue May 30 21:44:19 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; @@ -587,10 +588,11 @@ scsi_CDs[i].readcd_known = 1; scsi_CDs[i].readcd_cdda = buffer[n + 5] & 0x01; /* print some capability bits */ - printk("sr%i: scsi3-mmc drive: %dx/%dx %s%s%s%s%s\n", i, + printk("sr%i: scsi3-mmc drive: %dx/%dx %s%s%s%s%s%s\n", i, ((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 Tue May 30 15:23:41 2000 @@ -319,7 +319,7 @@ # define PCI_PRESENT pci_present () # define PCI_SET_MASTER pci_set_master (pdev) # define PCI_FIND_DEVICE(vend, id) (pdev = pci_find_device (vend, id, pdev)) -# define PCI_GET_IO_AND_IRQ io_port = pdev->resource[0].start; irq = pdev->irq +# define PCI_GET_IO_AND_IRQ io_port = pci_resource_start(pdev, 0); irq = pdev->irq; #else # include # define PDEV pbus, pdevfn @@ -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 Tue May 30 15:24:13 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))) { @@ -2345,7 +2347,7 @@ init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->magic = CM_MAGIC; - s->iobase = pcidev->resource[0].start; + s->iobase = pci_resource_start(pcidev, 0); s->iosynth = 0x388; s->iomidi = 0x330; spin_lock_init(&s->lock); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/emu10k1/main.c linux.ac/drivers/sound/emu10k1/main.c --- linux.vanilla/drivers/sound/emu10k1/main.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/sound/emu10k1/main.c Tue May 30 15:24:37 2000 @@ -622,7 +622,7 @@ pci_set_master(pci_dev); - card->iobase = pci_dev->resource[0].start; + card->iobase = pci_resource_start(pci_dev, 0); if (request_region(card->iobase, EMU10K1_EXTENT, card_names[pci_id->driver_data]) == NULL) { printk(KERN_ERR "emu10k1: IO space in use\n"); 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 Tue May 30 15:24:37 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_resource_start(pci_dev, 0); 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 Tue May 30 15:25:02 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 @@ -4615,10 +4608,12 @@ pci = pci_find_device(0x15E2, 0x0500, pci); if (!pci) break; + if (pci_enable_device(pci)) + break; { - ixj[cnt].DSPbase = pci->resource[0].start; + ixj[cnt].DSPbase = pci_resource_start(pci, 0); ixj[cnt].XILINXbase = ixj[cnt].DSPbase + 0x10; - ixj[cnt].serial = PCIEE_GetSerialNumber(pci->resource[2].start); + ixj[cnt].serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2); result = check_region(ixj[cnt].DSPbase, 16); if (result) { 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 Tue May 30 21:42:10 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 Tue May 30 21:28:10 2000 @@ -1,7 +1,7 @@ /* - * evdev.c Version 0.1 + * $Id: evdev.c,v 1.8 2000/05/29 09:01:52 vojtech Exp $ * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 1999-2000 Vojtech Pavlik * * Event char devices, giving access to raw input device events. * @@ -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; } @@ -207,14 +206,20 @@ struct evdev_list *list = file->private_data; struct evdev *evdev = list->evdev; struct input_dev *dev = evdev->handle.dev; + int retval; switch (cmd) { case EVIOCGVERSION: - return put_user(EV_VERSION, (__u32 *) arg); + return put_user(EV_VERSION, (int *) arg); + case EVIOCGID: - return copy_to_user(&dev->id, (void *) arg, - sizeof(struct input_id)) ? -EFAULT : 0; + if ((retval = put_user(dev->idbus, ((short *) arg) + 0))) return retval; + if ((retval = put_user(dev->idvendor, ((short *) arg) + 1))) return retval; + if ((retval = put_user(dev->idproduct, ((short *) arg) + 2))) return retval; + if ((retval = put_user(dev->idversion, ((short *) arg) + 3))) return retval; + return 0; + default: if (_IOC_TYPE(cmd) != 'E' || _IOC_DIR(cmd) != _IOC_READ) @@ -222,8 +227,8 @@ if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) { - long *bits = NULL; - int len = 0; + long *bits; + int len; switch (_IOC_NR(cmd) & EV_MAX) { case 0: bits = dev->evbit; len = EV_MAX; break; @@ -235,15 +240,34 @@ default: return -EINVAL; } len = NBITS(len) * sizeof(long); - if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - return copy_to_user((void *) arg, bits, len) ? -EFAULT : len; + if (len > _IOC_SIZE(cmd)) { + printk(KERN_WARNING "evdev.c: Truncating bitfield length from %d to %d\n", + len, _IOC_SIZE(cmd)); + len = _IOC_SIZE(cmd); + } + return copy_to_user((char *) arg, bits, len) ? -EFAULT : len; } if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { - int len = strlen(dev->name) + 1; + int len; + if (!dev->name) return 0; + len = strlen(dev->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); return copy_to_user((char *) arg, dev->name, len) ? -EFAULT : len; } + + if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { + + int t = _IOC_NR(cmd) & ABS_MAX; + + if ((retval = put_user(dev->abs[t], ((int *) arg) + 0))) return retval; + if ((retval = put_user(dev->absmin[t], ((int *) arg) + 1))) return retval; + if ((retval = put_user(dev->absmax[t], ((int *) arg) + 2))) return retval; + if ((retval = put_user(dev->absfuzz[t], ((int *) arg) + 3))) return retval; + if ((retval = put_user(dev->absflat[t], ((int *) arg) + 4))) return retval; + + return 0; + } } return -EINVAL; } @@ -286,7 +310,7 @@ evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE); - printk("event%d: Event device for input%d\n", minor, dev->number); + printk(KERN_INFO "event%d: Event device for input%d\n", minor, dev->number); return &evdev->handle; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/hid-debug.h linux.ac/drivers/usb/hid-debug.h --- linux.vanilla/drivers/usb/hid-debug.h Thu May 25 17:38:14 2000 +++ linux.ac/drivers/usb/hid-debug.h Tue May 30 21:28:10 2000 @@ -1,5 +1,5 @@ /* - * driver/usb/hid-debug.h + * $Id: hid-debug.h,v 1.2 2000/05/29 10:54:53 vojtech Exp $ * * (c) 1999 Andreas Gal * (c) 2000 Vojtech Pavlik diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/hid.c linux.ac/drivers/usb/hid.c --- linux.vanilla/drivers/usb/hid.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/hid.c Tue May 30 21:28:10 2000 @@ -1,5 +1,5 @@ /* - * hid.c Version 0.8 + * $Id: hid.c,v 1.6 2000/05/29 09:01:52 vojtech Exp $ * * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000 Vojtech Pavlik @@ -80,6 +80,9 @@ __s32 y; } hid_hat_to_axis[] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}, { 0, 0}}; +static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", + "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; + /* * Register a new report for a device. */ @@ -1259,6 +1262,27 @@ return 0; } +static int hid_open(struct input_dev *dev) +{ + struct hid_device *hid = dev->private; + + if (hid->open++) + return 0; + + if (usb_submit_urb(&hid->urb)) + return -EIO; + + return 0; +} + +static void hid_close(struct input_dev *dev) +{ + struct hid_device *hid = dev->private; + + if (!--hid->open) + usb_unlink_urb(&hid->urb); +} + /* * Configure the input layer interface * Read all reports and initalize the absoulte field values. @@ -1272,6 +1296,8 @@ hid->input.private = hid; hid->input.event = hid_event; + hid->input.open = hid_open; + hid->input.close = hid_close; for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { @@ -1313,7 +1339,7 @@ { 0, 0 } }; -static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum) +static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum, char *name) { struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0; struct hid_descriptor *hdesc; @@ -1380,11 +1406,6 @@ FILL_INT_URB(&hid->urb, dev, pipe, hid->buffer, maxp > 32 ? 32 : maxp, hid_irq, hid, endpoint->bInterval); - if (usb_submit_urb(&hid->urb)) { - dbg("submitting interrupt URB failed"); - continue; - } - break; } @@ -1405,6 +1426,20 @@ hid->dr.index = hid->ifnum; hid->dr.length = 1; + hid->input.name = hid->name; + hid->input.idbus = BUS_USB; + hid->input.idvendor = dev->descriptor.idVendor; + hid->input.idproduct = dev->descriptor.idProduct; + hid->input.idversion = dev->descriptor.bcdDevice; + + if (strlen(name)) + strcpy(hid->name, name); + else + sprintf(hid->name, "USB HID %s %04x:%04x", + ((hid->application >= 0x00010000) && (hid->application <= 0x00010008)) ? + hid_types[hid->application & 0xffff] : "Device", + hid->input.idvendor, hid->input.idproduct); + FILL_CONTROL_URB(&hid->urbout, dev, usb_sndctrlpipe(dev, 0), (void*) &hid->dr, hid->bufout, 1, hid_ctrl, hid); @@ -1416,13 +1451,27 @@ static void* hid_probe(struct usb_device *dev, unsigned int ifnum) { - char *hid_name[] = {"Device", "Pointer", "Mouse", "Device", "Joystick", - "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"}; struct hid_device *hid; + char name[128]; + char *buf; dbg("HID probe called for ifnum %d", ifnum); - if (!(hid = usb_hid_configure(dev, ifnum))) + name[0] = 0; + + if (!(buf = kmalloc(63, GFP_KERNEL))) + return NULL; + + if (dev->descriptor.iManufacturer && + usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strcat(name, buf); + if (dev->descriptor.iProduct && + usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + sprintf(name, "%s %s", name, buf); + + kfree(buf); + + if (!(hid = usb_hid_configure(dev, ifnum, name))) return NULL; hid_dump_device(hid); @@ -1430,10 +1479,18 @@ hid_init_input(hid); input_register_device(&hid->input); - printk(KERN_INFO "input%d: USB HID v%x.%02x %s\n", - hid->input.number, hid->version >> 8, hid->version & 0xff, + printk(KERN_INFO "input%d: USB HID v%x.%02x %s", + hid->input.number, + hid->version >> 8, hid->version & 0xff, ((hid->application >= 0x00010000) && (hid->application <= 0x00010008)) ? - hid_name[hid->application & 0xffff] : "device"); + hid_types[hid->application & 0xffff] : "Device"); + + if (strlen(name)) + printk(" [%s]", name); + else + printk(" [%04x:%04x]", hid->input.idvendor, hid->input.idproduct); + + printk(" on usb%d:%d.%d\n", dev->bus->busnum, dev->devnum, ifnum); return hid; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/hid.h linux.ac/drivers/usb/hid.h --- linux.vanilla/drivers/usb/hid.h Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/hid.h Tue May 30 21:28:10 2000 @@ -2,7 +2,7 @@ #define __HID_H /* - * drivers/usb/hid.h Version 0.8 + * $Id: hid.h,v 1.4 2000/05/29 09:01:52 vojtech Exp $ * * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000 Vojtech Pavlik @@ -292,7 +292,9 @@ struct urb urb; /* USB URB structure */ struct urb urbout; /* Output URB */ struct input_dev input; /* input device structure */ + int open; /* is the device open by input? */ int quirks; /* Various nasty tricks the device can pull on us */ + char name[128]; /* Device name */ }; #define HID_GLOBAL_STACK_SIZE 4 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/input.c linux.ac/drivers/usb/input.c --- linux.vanilla/drivers/usb/input.c Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/input.c Tue May 30 21:28:07 2000 @@ -1,7 +1,7 @@ /* - * input.c Version 0.1 + * $Id: input.c,v 1.7 2000/05/28 17:31:36 vojtech Exp $ * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 1999-2000 Vojtech Pavlik * * The input layer module itself * @@ -91,11 +91,27 @@ case EV_ABS: - if (code > ABS_MAX || !test_bit(code, dev->absbit) || (value == dev->abs[code])) + if (code > ABS_MAX || !test_bit(code, dev->absbit)) return; - dev->abs[code] = value; + if (dev->absfuzz[code]) { + if ((value > dev->abs[code] - (dev->absfuzz[code] >> 1)) && + (value < dev->abs[code] + (dev->absfuzz[code] >> 1))) + return; + + if ((value > dev->abs[code] - dev->absfuzz[code]) && + (value < dev->abs[code] + dev->absfuzz[code])) + value = (dev->abs[code] * 3 + value) >> 2; + + if ((value > dev->abs[code] - (dev->absfuzz[code] << 1)) && + (value < dev->abs[code] + (dev->absfuzz[code] << 1))) + value = (dev->abs[code] + value) >> 1; + } + if (dev->abs[code] == value) + return; + + dev->abs[code] = value; break; case EV_REL: 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 Tue May 30 21:28:10 2000 @@ -1,7 +1,7 @@ /* - * joydev.c Version 0.1 + * $Id: joydev.c,v 1.7 2000/05/29 09:01:52 vojtech Exp $ * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 1999-2000 Vojtech Pavlik * Copyright (c) 1999 Colin Van Dyke * * Joystick device driver for the input driver suite. @@ -53,7 +53,6 @@ int used; int open; int minor; - char name[32]; struct input_handle handle; wait_queue_head_t wait; devfs_handle_t devfs; @@ -139,8 +138,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; } @@ -322,6 +320,8 @@ { struct joydev_list *list = file->private_data; struct joydev *joydev = list->joydev; + struct input_dev *dev = joydev->handle.dev; + switch (cmd) { @@ -360,9 +360,11 @@ sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0; default: if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) { - int len = strlen(joydev->name) + 1; + int len; + if (!dev->name) return 0; + len = strlen(dev->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - if (copy_to_user((char *) arg, joydev->name, len)) return -EFAULT; + if (copy_to_user((char *) arg, dev->name, len)) return -EFAULT; return len; } } @@ -401,8 +403,6 @@ init_waitqueue_head(&joydev->wait); - sprintf(joydev->name, "joydev%d", joydev->minor); - joydev->minor = minor; joydev_table[minor] = joydev; @@ -449,7 +449,7 @@ joydev->devfs = input_register_minor("js%d", minor, JOYDEV_MINOR_BASE); - printk("js%d: Joystick device for input%d\n", minor, dev->number); + printk(KERN_INFO "js%d: Joystick device for input%d\n", minor, dev->number); return &joydev->handle; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/keybdev.c linux.ac/drivers/usb/keybdev.c --- linux.vanilla/drivers/usb/keybdev.c Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/keybdev.c Tue May 30 21:28:07 2000 @@ -1,7 +1,7 @@ /* - * keybdev.c Version 0.1 + * $Id: keybdev.c,v 1.3 2000/05/28 17:31:36 vojtech Exp $ * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 1999-2000 Vojtech Pavlik * * Input driver to keyboard driver binding. * @@ -162,14 +162,14 @@ input_open_device(handle); - printk("keybdev.c: Adding keyboard: input%d\n", dev->number); + printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number); return handle; } static void keybdev_disconnect(struct input_handle *handle) { - printk("keybdev.c: Removing keyboard: input%d\n", handle->dev->number); + printk(KERN_INFO "keybdev.c: Removing keyboard: input%d\n", handle->dev->number); input_close_device(handle); kfree(handle); } 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 Tue May 30 21:28:07 2000 @@ -1,7 +1,7 @@ /* - * mousedev.c Version 0.1 + * $Id: mousedev.c,v 1.8 2000/05/28 17:31:36 vojtech Exp $ * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 1999-2000 Vojtech Pavlik * * Input driver to PS/2 or ImPS/2 device driver module. * @@ -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); @@ -421,7 +419,7 @@ if (mousedev_mix.open) input_open_device(&mousedev->handle); - printk("mouse%d: PS/2 mouse device for input%d\n", minor, dev->number); + printk(KERN_INFO "mouse%d: PS/2 mouse device for input%d\n", minor, dev->number); return &mousedev->handle; } @@ -459,7 +457,7 @@ mousedev_mix.minor = MOUSEDEV_MIX; mousedev_mix.devfs = input_register_minor("mice", MOUSEDEV_MIX, MOUSEDEV_MINOR_BASE); - printk("mice: PS/2 mouse device common for all mice\n"); + printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n"); return 0; } 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-ohci.c linux.ac/drivers/usb/usb-ohci.c --- linux.vanilla/drivers/usb/usb-ohci.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/usb-ohci.c Tue May 30 15:25:11 2000 @@ -1974,7 +1974,7 @@ return -ENODEV; pci_set_master (dev); - mem_base = dev->resource[0].start; + mem_base = pci_resource_start(dev, 0); mem_base = (unsigned long) ioremap_nocache (mem_base, 4096); if (!mem_base) { 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/usb/usbkbd.c linux.ac/drivers/usb/usbkbd.c --- linux.vanilla/drivers/usb/usbkbd.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/usbkbd.c Tue May 30 21:28:10 2000 @@ -1,7 +1,7 @@ /* - * usbkbd.c Version 0.1 + * $Id: usbkbd.c,v 1.11 2000/05/29 09:01:52 vojtech Exp $ * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 1999-2000 Vojtech Pavlik * * USB HIDBP Keyboard support * @@ -63,6 +63,8 @@ struct urb irq, led; devrequest dr; unsigned char leds; + char name[128]; + int open; }; static void usb_kbd_irq(struct urb *urb) @@ -125,12 +127,34 @@ warn("led urb status %d received", urb->status); } +static int usb_kbd_open(struct input_dev *dev) +{ + struct usb_kbd *kbd = dev->private; + + if (kbd->open++) + return 0; + + if (usb_submit_urb(&kbd->irq)) + return -EIO; + + return 0; +} + +static void usb_kbd_close(struct input_dev *dev) +{ + struct usb_kbd *kbd = dev->private; + + if (!--kbd->open) + usb_unlink_urb(&kbd->irq); +} + static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) { struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct usb_kbd *kbd; - int i; + int i, pipe, maxp; + char *buf; if (dev->descriptor.bNumConfigurations != 1) return NULL; interface = dev->config[0].interface[ifnum].altsetting + 0; @@ -144,6 +168,9 @@ if (!(endpoint->bEndpointAddress & 0x80)) return NULL; if ((endpoint->bmAttributes & 3) != 3) return NULL; + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + usb_set_protocol(dev, interface->bInterfaceNumber, 0); usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); @@ -159,14 +186,11 @@ kbd->dev.private = kbd; kbd->dev.event = usb_kbd_event; + kbd->dev.open = usb_kbd_open; + kbd->dev.close = usb_kbd_close; - { - int pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - int maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - - FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, - usb_kbd_irq, kbd, endpoint->bInterval); - } + FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, + usb_kbd_irq, kbd, endpoint->bInterval); kbd->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE; kbd->dr.request = USB_REQ_SET_REPORT; @@ -174,18 +198,37 @@ kbd->dr.index = interface->bInterfaceNumber; kbd->dr.length = 1; - FILL_CONTROL_URB(&kbd->led, dev, usb_sndctrlpipe(dev, 0), - (void*) &kbd->dr, &kbd->leds, 1, usb_kbd_led, kbd); - - if (usb_submit_urb(&kbd->irq)) { + kbd->dev.name = kbd->name; + kbd->dev.idbus = BUS_USB; + kbd->dev.idvendor = dev->descriptor.idVendor; + kbd->dev.idproduct = dev->descriptor.idProduct; + kbd->dev.idversion = dev->descriptor.bcdDevice; + + if (!(buf = kmalloc(63, GFP_KERNEL))) { kfree(kbd); return NULL; } - input_register_device(&kbd->dev); + if (dev->descriptor.iManufacturer && + usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strcat(kbd->name, buf); + if (dev->descriptor.iProduct && + usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + sprintf(kbd->name, "%s %s", kbd->name, buf); + + if (!strlen(kbd->name)) + sprintf(kbd->name, "USB HIDBP Keyboard %04x:%04x", + kbd->dev.idvendor, kbd->dev.idproduct); + + kfree(buf); - printk(KERN_INFO "input%d: USB HIDBP keyboard\n", kbd->dev.number); + FILL_CONTROL_URB(&kbd->led, dev, usb_sndctrlpipe(dev, 0), + (void*) &kbd->dr, &kbd->leds, 1, usb_kbd_led, kbd); + + input_register_device(&kbd->dev); + printk(KERN_INFO "input%d: %s on on usb%d:%d.%d\n", + kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum); return kbd; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/usbmouse.c linux.ac/drivers/usb/usbmouse.c --- linux.vanilla/drivers/usb/usbmouse.c Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/usbmouse.c Tue May 30 21:28:10 2000 @@ -1,7 +1,7 @@ /* - * usbmouse.c Version 0.1 + * $Id: usbmouse.c,v 1.5 2000/05/29 09:01:52 vojtech Exp $ * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 1999-2000 Vojtech Pavlik * * USB HIDBP Mouse support * @@ -37,12 +37,12 @@ MODULE_AUTHOR("Vojtech Pavlik "); -#define USBMOUSE_EXTRA - struct usb_mouse { signed char data[8]; + char name[128]; struct input_dev dev; struct urb irq; + int open; }; static void usb_mouse_irq(struct urb *urb) @@ -53,16 +53,36 @@ if (urb->status) return; - input_report_key(dev, BTN_LEFT, !!(data[0] & 0x01)); - input_report_key(dev, BTN_RIGHT, !!(data[0] & 0x02)); - input_report_key(dev, BTN_MIDDLE, !!(data[0] & 0x04)); - input_report_rel(dev, REL_X, data[1]); - input_report_rel(dev, REL_Y, data[2]); -#ifdef USBMOUSE_EXTRA - input_report_key(dev, BTN_SIDE, !!(data[0] & 0x08)); - input_report_key(dev, BTN_EXTRA, !!(data[0] & 0x10)); + input_report_key(dev, BTN_LEFT, data[0] & 0x01); + input_report_key(dev, BTN_RIGHT, data[0] & 0x02); + input_report_key(dev, BTN_MIDDLE, data[0] & 0x04); + input_report_key(dev, BTN_SIDE, data[0] & 0x08); + input_report_key(dev, BTN_EXTRA, data[0] & 0x10); + + input_report_rel(dev, REL_X, data[1]); + input_report_rel(dev, REL_Y, data[2]); input_report_rel(dev, REL_WHEEL, data[3]); -#endif +} + +static int usb_mouse_open(struct input_dev *dev) +{ + struct usb_mouse *mouse = dev->private; + + if (mouse->open++) + return 0; + + if (usb_submit_urb(&mouse->irq)) + return -EIO; + + return 0; +} + +static void usb_mouse_close(struct input_dev *dev) +{ + struct usb_mouse *mouse = dev->private; + + if (!--mouse->open) + usb_unlink_urb(&mouse->irq); } static void *usb_mouse_probe(struct usb_device *dev, unsigned int ifnum) @@ -70,6 +90,8 @@ struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; struct usb_mouse *mouse; + int pipe, maxp; + char *buf; if (dev->descriptor.bNumConfigurations != 1) return NULL; interface = dev->config[0].interface[ifnum].altsetting + 0; @@ -83,9 +105,9 @@ if (!(endpoint->bEndpointAddress & 0x80)) return NULL; if ((endpoint->bmAttributes & 3) != 3) return NULL; -#ifndef USBMOUSE_EXTRA - usb_set_protocol(dev, interface->bInterfaceNumber, 0); -#endif + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL; @@ -94,27 +116,44 @@ mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); -#ifdef USBMOUSE_EXTRA mouse->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); mouse->dev.relbit[0] |= BIT(REL_WHEEL); -#endif - { - int pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); - int maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + mouse->dev.private = mouse; + mouse->dev.open = usb_mouse_open; + mouse->dev.close = usb_mouse_close; + + mouse->dev.name = mouse->name; + mouse->dev.idbus = BUS_USB; + mouse->dev.idvendor = dev->descriptor.idVendor; + mouse->dev.idproduct = dev->descriptor.idProduct; + mouse->dev.idversion = dev->descriptor.bcdDevice; - FILL_INT_URB(&mouse->irq, dev, pipe, mouse->data, maxp > 8 ? 8 : maxp, - usb_mouse_irq, mouse, endpoint->bInterval); - } - - if (usb_submit_urb(&mouse->irq)) { + if (!(buf = kmalloc(63, GFP_KERNEL))) { kfree(mouse); return NULL; } + if (dev->descriptor.iManufacturer && + usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strcat(mouse->name, buf); + if (dev->descriptor.iProduct && + usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + sprintf(mouse->name, "%s %s", mouse->name, buf); + + if (!strlen(mouse->name)) + sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x", + mouse->dev.idvendor, mouse->dev.idproduct); + + kfree(buf); + + FILL_INT_URB(&mouse->irq, dev, pipe, mouse->data, maxp > 8 ? 8 : maxp, + usb_mouse_irq, mouse, endpoint->bInterval); + input_register_device(&mouse->dev); - printk(KERN_INFO "input%d: USB HIDBP mouse\n", mouse->dev.number); + printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n", + mouse->dev.number, mouse->name, dev->bus->busnum, dev->devnum, ifnum); return mouse; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/wacom.c linux.ac/drivers/usb/wacom.c --- linux.vanilla/drivers/usb/wacom.c Thu May 25 17:38:14 2000 +++ linux.ac/drivers/usb/wacom.c Tue May 30 21:28:10 2000 @@ -1,5 +1,5 @@ /* - * wacom.c Version 0.5 + * $Id: wacom.c,v 1.9 2000/05/29 09:01:52 vojtech Exp $ * * Copyright (c) 2000 Vojtech Pavlik * Copyright (c) 2000 Andreas Bach Aaen @@ -18,6 +18,9 @@ * relative mode, proximity. * v0.5 (vp) - Big cleanup, nifty features removed, * they belong in userspace + * v1.8 (vp) - Submit URB only when operating, moved to CVS, + * use input_report_key instead of report_btn and + * other cleanups */ /* @@ -116,6 +119,7 @@ struct urb irq; struct wacom_features *features; int tool; + int open; }; static void wacom_graphire_irq(struct urb *urb) @@ -137,18 +141,18 @@ switch ((data[1] >> 5) & 3) { case 0: /* Pen */ - input_report_btn(dev, BTN_TOOL_PEN, data[1] & 0x80); + input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x80); break; case 1: /* Rubber */ - input_report_btn(dev, BTN_TOOL_RUBBER, data[1] & 0x80); + input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80); break; case 2: /* Mouse */ - input_report_btn(dev, BTN_TOOL_MOUSE, data[7] > 24); - input_report_btn(dev, BTN_LEFT, data[1] & 0x01); - input_report_btn(dev, BTN_RIGHT, data[1] & 0x02); - input_report_btn(dev, BTN_MIDDLE, data[1] & 0x04); + input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24); + input_report_key(dev, BTN_LEFT, data[1] & 0x01); + input_report_key(dev, BTN_RIGHT, data[1] & 0x02); + input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); input_report_abs(dev, ABS_DISTANCE, data[7]); input_report_rel(dev, REL_WHEEL, (signed char) data[6]); return; @@ -156,9 +160,9 @@ input_report_abs(dev, ABS_PRESSURE, data[6] | ((__u32)data[7] << 8)); - input_report_btn(dev, BTN_TOUCH, data[1] & 0x01); - input_report_btn(dev, BTN_STYLUS, data[1] & 0x02); - input_report_btn(dev, BTN_STYLUS2, data[1] & 0x04); + input_report_key(dev, BTN_TOUCH, data[1] & 0x01); + input_report_key(dev, BTN_STYLUS, data[1] & 0x02); + input_report_key(dev, BTN_STYLUS2, data[1] & 0x04); } static void wacom_intuos_irq(struct urb *urb) @@ -177,21 +181,23 @@ switch (((__u32)data[2] << 4) | (data[3] >> 4)) { case 0x012: wacom->tool = BTN_TOOL_PENCIL; break; /* Inking pen */ + case 0x822: case 0x022: wacom->tool = BTN_TOOL_PEN; break; /* Pen */ case 0x032: wacom->tool = BTN_TOOL_BRUSH; break; /* Stroke pen */ case 0x094: wacom->tool = BTN_TOOL_MOUSE; break; /* Mouse 4D */ case 0x096: wacom->tool = BTN_TOOL_LENS; break; /* Lens cursor */ + case 0x82a: case 0x0fa: wacom->tool = BTN_TOOL_RUBBER; break; /* Eraser */ case 0x112: wacom->tool = BTN_TOOL_AIRBRUSH; break; /* Airbrush */ default: wacom->tool = BTN_TOOL_PEN; break; /* Unknown tool */ } - input_report_btn(dev, wacom->tool, 1); + input_report_key(dev, wacom->tool, 1); return; } if ((data[1] | data[2] | data[3] | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) == 0x80) { /* Exit report */ - input_report_btn(dev, wacom->tool, 0); + input_report_key(dev, wacom->tool, 0); return; } @@ -202,29 +208,50 @@ input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); - input_report_btn(dev, BTN_STYLUS, data[1] & 2); - input_report_btn(dev, BTN_STYLUS2, data[1] & 4); - input_report_btn(dev, BTN_TOUCH, t > 10); + input_report_key(dev, BTN_STYLUS, data[1] & 2); + input_report_key(dev, BTN_STYLUS2, data[1] & 4); + input_report_key(dev, BTN_TOUCH, t > 10); } #define WACOM_INTUOS_TOOLS (BIT(BTN_TOOL_BRUSH) | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS)) struct wacom_features wacom_features[] = { - { "Graphire", 0x10, 8, 10206, 7422, 511, 32, wacom_graphire_irq, + { "Wacom Graphire", 0x10, 8, 10206, 7422, 511, 32, wacom_graphire_irq, BIT(EV_REL), 0, BIT(REL_WHEEL), BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE), 0 }, - { "Intuos 4x5", 0x20, 10, 12700, 10360, 1023, 15, wacom_intuos_irq, + { "Wacom Intuos 4x5", 0x20, 10, 12700, 10360, 1023, 15, wacom_intuos_irq, 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, - { "Intuos 6x8", 0x21, 10, 20320, 15040, 1023, 15, wacom_intuos_irq, + { "Wacom Intuos 6x8", 0x21, 10, 20320, 15040, 1023, 15, wacom_intuos_irq, 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, - { "Intuos 9x12", 0x22, 10, 30480, 23060, 1023, 15, wacom_intuos_irq, + { "Wacom Intuos 9x12", 0x22, 10, 30480, 23060, 1023, 15, wacom_intuos_irq, 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, - { "Intuos 12x12", 0x23, 10, 30480, 30480, 1023, 15, wacom_intuos_irq, + { "Wacom Intuos 12x12", 0x23, 10, 30480, 30480, 1023, 15, wacom_intuos_irq, 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, - { "Intuos 12x18", 0x24, 10, 47720, 30480, 1023, 15, wacom_intuos_irq, + { "Wacom Intuos 12x18", 0x24, 10, 47720, 30480, 1023, 15, wacom_intuos_irq, 0, BIT(ABS_TILT_X) | BIT(ABS_TILT_Y), 0, 0, WACOM_INTUOS_TOOLS }, { NULL , 0 } }; +static int wacom_open(struct input_dev *dev) +{ + struct wacom *wacom = dev->private; + + if (wacom->open++) + return 0; + + if (usb_submit_urb(&wacom->irq)) + return -EIO; + + return 0; +} + +static void wacom_close(struct input_dev *dev) +{ + struct wacom *wacom = dev->private; + + if (!--wacom->open) + usb_unlink_urb(&wacom->irq); +} + static void *wacom_probe(struct usb_device *dev, unsigned int ifnum) { struct usb_endpoint_descriptor *endpoint; @@ -256,17 +283,23 @@ wacom->dev.absmax[ABS_TILT_X] = 127; wacom->dev.absmax[ABS_TILT_Y] = 127; + wacom->dev.private = wacom; + wacom->dev.open = wacom_open; + wacom->dev.close = wacom_close; + + wacom->dev.name = wacom->features->name; + wacom->dev.idbus = BUS_USB; + wacom->dev.idvendor = dev->descriptor.idVendor; + wacom->dev.idproduct = dev->descriptor.idProduct; + wacom->dev.idversion = dev->descriptor.bcdDevice; + FILL_INT_URB(&wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), wacom->data, wacom->features->pktlen, wacom->features->irq, wacom, endpoint->bInterval); - if (usb_submit_urb(&wacom->irq)) { - kfree(wacom); - return NULL; - } - input_register_device(&wacom->dev); - printk(KERN_INFO "input%d: Wacom %s on usb%d\n", wacom->dev.number, wacom->features->name, dev->devnum); + printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n", + wacom->dev.number, wacom->features->name, dev->bus->busnum, dev->devnum, ifnum); return wacom; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/wmforce.c linux.ac/drivers/usb/wmforce.c --- linux.vanilla/drivers/usb/wmforce.c Thu May 25 17:38:14 2000 +++ linux.ac/drivers/usb/wmforce.c Tue May 30 21:28:10 2000 @@ -1,5 +1,5 @@ /* - * wmforce.c Version 0.1 + * $Id: wmforce.c,v 1.6 2000/05/29 09:01:52 vojtech Exp $ * * Copyright (c) 2000 Vojtech Pavlik * @@ -44,6 +44,7 @@ signed char data[8]; struct input_dev dev; struct urb irq; + int open; }; static struct { @@ -51,6 +52,8 @@ __s32 y; } wmforce_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; +static char *wmforce_name = "Logitech WingMan Force"; + static void wmforce_irq(struct urb *urb) { struct wmforce *wmforce = urb->context; @@ -71,15 +74,36 @@ input_report_abs(dev, ABS_HAT0X, wmforce_hat_to_axis[data[7] >> 4].x); input_report_abs(dev, ABS_HAT0Y, wmforce_hat_to_axis[data[7] >> 4].y); - input_report_key(dev, BTN_TRIGGER, !!(data[6] & 0x01)); - input_report_key(dev, BTN_TOP, !!(data[6] & 0x02)); - input_report_key(dev, BTN_THUMB, !!(data[6] & 0x04)); - input_report_key(dev, BTN_TOP2, !!(data[6] & 0x08)); - input_report_key(dev, BTN_BASE, !!(data[6] & 0x10)); - input_report_key(dev, BTN_BASE2, !!(data[6] & 0x20)); - input_report_key(dev, BTN_BASE3, !!(data[6] & 0x40)); - input_report_key(dev, BTN_BASE4, !!(data[6] & 0x80)); - input_report_key(dev, BTN_BASE5, !!(data[7] & 0x01)); + input_report_key(dev, BTN_TRIGGER, data[6] & 0x01); + input_report_key(dev, BTN_TOP, data[6] & 0x02); + input_report_key(dev, BTN_THUMB, data[6] & 0x04); + input_report_key(dev, BTN_TOP2, data[6] & 0x08); + input_report_key(dev, BTN_BASE, data[6] & 0x10); + input_report_key(dev, BTN_BASE2, data[6] & 0x20); + input_report_key(dev, BTN_BASE3, data[6] & 0x40); + input_report_key(dev, BTN_BASE4, data[6] & 0x80); + input_report_key(dev, BTN_BASE5, data[7] & 0x01); +} + +static int wmforce_open(struct input_dev *dev) +{ + struct wmforce *wmforce = dev->private; + + if (wmforce->open++) + return 0; + + if (usb_submit_urb(&wmforce->irq)) + return -EIO; + + return 0; +} + +static void wmforce_close(struct input_dev *dev) +{ + struct wmforce *wmforce = dev->private; + + if (!--wmforce->open) + usb_unlink_urb(&wmforce->irq); } static void *wmforce_probe(struct usb_device *dev, unsigned int ifnum) @@ -105,33 +129,34 @@ for (i = ABS_X; i <= ABS_Y; i++) { wmforce->dev.absmax[i] = 1920; wmforce->dev.absmin[i] = -1920; - wmforce->dev.absfuzz[i] = 0; wmforce->dev.absflat[i] = 128; } - wmforce->dev.absmax[ABS_THROTTLE] = 0; - wmforce->dev.absmin[ABS_THROTTLE] = 255; - wmforce->dev.absfuzz[ABS_THROTTLE] = 0; - wmforce->dev.absflat[ABS_THROTTLE] = 0; + wmforce->dev.absmax[ABS_THROTTLE] = 255; + wmforce->dev.absmin[ABS_THROTTLE] = 0; for (i = ABS_HAT0X; i <= ABS_HAT0Y; i++) { wmforce->dev.absmax[i] = 1; wmforce->dev.absmin[i] = -1; - wmforce->dev.absfuzz[i] = 0; - wmforce->dev.absflat[i] = 0; } + wmforce->dev.private = wmforce; + wmforce->dev.open = wmforce_open; + wmforce->dev.close = wmforce_close; + + wmforce->dev.name = wmforce_name; + wmforce->dev.idbus = BUS_USB; + wmforce->dev.idvendor = dev->descriptor.idVendor; + wmforce->dev.idproduct = dev->descriptor.idProduct; + wmforce->dev.idversion = dev->descriptor.bcdDevice; + FILL_INT_URB(&wmforce->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), wmforce->data, 8, wmforce_irq, wmforce, endpoint->bInterval); - if (usb_submit_urb(&wmforce->irq)) { - kfree(wmforce); - return NULL; - } - input_register_device(&wmforce->dev); - printk(KERN_INFO "input%d: Logitech WingMan Force USB\n", wmforce->dev.number); + printk(KERN_INFO "input%d: %s on usb%d:%d.%d\n", + wmforce->dev.number, wmforce_name, dev->bus->busnum, dev->devnum, ifnum); return wmforce; } 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 Tue May 30 15:25:27 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; @@ -2539,12 +2541,12 @@ #else - if (pdev->resource[0].flags & IORESOURCE_IO) { - *display = pdev->resource[1].start; - *registers = pdev->resource[0].start; + if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { + *display = pci_resource_start(pdev, 1); + *registers = pci_resource_start(pdev, 0); } else { - *display = pdev->resource[0].start; - *registers = pdev->resource[1].start; + *display = pci_resource_start(pdev, 0); + *registers = pci_resource_start(pdev, 1); } #endif /* kernel older than 2.3.13 */ @@ -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/matrox/matroxfb_base.c linux.ac/drivers/video/matrox/matroxfb_base.c --- linux.vanilla/drivers/video/matrox/matroxfb_base.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/video/matrox/matroxfb_base.c Tue May 30 15:25:46 2000 @@ -1595,11 +1595,11 @@ if (ACCESS_FBINFO(capable.cross4MB) < 0) ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB; if (b->flags & DEVF_SWAPS) { - ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[1].start; - video_base_phys = ACCESS_FBINFO(pcidev)->resource[0].start; + ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); + video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); } else { - ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[0].start; - video_base_phys = ACCESS_FBINFO(pcidev)->resource[1].start; + ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); + video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); } err = -EINVAL; if (!ctrlptr_phys) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/video/pm2fb.c linux.ac/drivers/video/pm2fb.c --- linux.vanilla/drivers/video/pm2fb.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/video/pm2fb.c Tue May 30 15:26:08 2000 @@ -1107,12 +1107,12 @@ } #else if (pm2fb_options.flags & OPTF_VIRTUAL) { - p->regions.rg_base= __pa(pci->dev->resource[0].start); - p->regions.fb_base= __pa(pci->dev->resource[1].start); + p->regions.rg_base = __pa(pci_resource_start(pci->dev, 0)); + p->regions.fb_base = __pa(pci_resource_start(pci->dev, 1)); } else { - p->regions.rg_base= (pci->dev->resource[0].start); - p->regions.fb_base= (pci->dev->resource[0].start); + p->regions.rg_base = pci_resource_start(pci->dev, 0); + p->regions.fb_base = pci_resource_start(pci->dev, 0); } #endif #ifdef PM2FB_BE_APERTURE @@ -2049,10 +2049,13 @@ int __init pm2fb_init(void){ + MOD_INC_USE_COUNT; memset(&fb_info, 0, sizeof(fb_info)); memcpy(&fb_info.current_par, &pm2fb_options.user_mode, sizeof(fb_info.current_par)); - if (!pm2fb_conf(&fb_info)) + if (!pm2fb_conf(&fb_info)) { + MOD_DEC_USE_COUNT; return -ENXIO; + } pm2fb_reset(&fb_info); fb_info.disp.scrollmode=SCROLL_YNOMOVE; fb_info.gen.parsize=sizeof(struct pm2fb_par); @@ -2071,6 +2074,7 @@ fbgen_install_cmap(0, &fb_info.gen); if (register_framebuffer(&fb_info.gen.info)<0) { printk(KERN_ERR "pm2fb: unable to register.\n"); + MOD_DEC_USE_COUNT; return -EINVAL; } printk(KERN_INFO "fb%d: %s (%s), using %uK of video memory.\n", @@ -2078,7 +2082,6 @@ board_table[fb_info.board].name, permedia2_name, (u32 )(fb_info.regions.fb_size>>10)); - MOD_INC_USE_COUNT; return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/video/riva/fbdev.c linux.ac/drivers/video/riva/fbdev.c --- linux.vanilla/drivers/video/riva/fbdev.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/video/riva/fbdev.c Tue May 30 15:26:22 2000 @@ -526,8 +526,8 @@ assert (rinfo->base0_region_size >= 0x00800000); /* from GGI */ assert (rinfo->base1_region_size >= 0x01000000); /* from GGI */ - rinfo->ctrl_base_phys = rinfo->pd->resource[0].start; - rinfo->fb_base_phys = rinfo->pd->resource[1].start; + rinfo->ctrl_base_phys = pci_resource_start (rinfo->pd, 0); + rinfo->fb_base_phys = pci_resource_start (rinfo->pd, 1); if (!request_mem_region (rinfo->ctrl_base_phys, rinfo->base0_region_size, "rivafb")) { 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/buffer.c linux.ac/fs/buffer.c --- linux.vanilla/fs/buffer.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/buffer.c Tue May 30 17:07:33 2000 @@ -1281,6 +1281,56 @@ } } +/** + * discard_buffer - discard that buffer without doing any IO + * @bh: buffer to discard + * + * This function removes a buffer from all the queues, without doing + * any IO, we are not interested in the contents of the buffer. This + * function can block if the buffer is locked. + */ +static struct buffer_head *discard_buffer(struct buffer_head * bh) +{ + int index = BUFSIZE_INDEX(bh->b_size); + struct buffer_head *next; + + /* grab the lru lock here to block bdflush. */ + atomic_inc(&bh->b_count); + lock_buffer(bh); + next = bh->b_this_page; + clear_bit(BH_Uptodate, &bh->b_state); + clear_bit(BH_Mapped, &bh->b_state); + clear_bit(BH_Req, &bh->b_state); + clear_bit(BH_New, &bh->b_state); + + spin_lock(&lru_list_lock); + write_lock(&hash_table_lock); + spin_lock(&free_list[index].lock); + spin_lock(&unused_list_lock); + + if (!atomic_dec_and_test(&bh->b_count)) + BUG(); + + __hash_unlink(bh); + /* The bunffer can be either on the regular + * queues or on the free list.. + */ + if (bh->b_dev != B_FREE) + __remove_from_queues(bh); + else + __remove_from_free_list(bh, index); + __put_unused_buffer_head(bh); + spin_unlock(&unused_list_lock); + write_unlock(&hash_table_lock); + spin_unlock(&free_list[index].lock); + spin_unlock(&lru_list_lock); + /* We can unlock the buffer, we have just returned it. + * Ditto for the counter + */ + return next; +} + + /* * We don't have to release all buffers here, but * we have to be sure that no dirty buffer is left @@ -1313,24 +1363,43 @@ bh = next; } while (bh != head); - /* - * subtle. We release buffer-heads only if this is - * the 'final' flushpage. We have invalidated the get_block - * cached value unconditionally, so real IO is not - * possible anymore. - * - * If the free doesn't work out, the buffers can be - * left around - they just turn into anonymous buffers - * instead. - */ - if (!offset) { - if (!try_to_free_buffers(page, 0)) { - atomic_inc(&buffermem_pages); - return 0; - } - } - return 1; +} + +/** + * block_destroy_buffers - Will destroy the contents of all the + * buffers in this page + * @page: page to examine the buffers + * + * This function destroy all the buffers in one page without making + * any IO. The function can block due to the fact that discad_bufferr + * can block. + */ +void block_destroy_buffers(struct page *page) +{ + struct buffer_head *bh, *head; + + if (!PageLocked(page)) + BUG(); + if (!page->buffers) + return; + + head = page->buffers; + bh = head; + do { + /* We need to get the next buffer from discard buffer + * because discard buffer can block and anybody else + * can change the buffer list under our feet. + */ + bh = discard_buffer(bh); + }while (bh != head); + + /* Wake up anyone waiting for buffer heads */ + wake_up(&buffer_wait); + + /* And free the page */ + page->buffers = NULL; + page_cache_release(page); } static void create_empty_buffers(struct page *page, struct inode *inode, unsigned long blocksize) 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/ext2/balloc.c linux.ac/fs/ext2/balloc.c --- linux.vanilla/fs/ext2/balloc.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/ext2/balloc.c Tue May 30 14:38:13 2000 @@ -473,11 +473,8 @@ if (i >= sb->u.ext2_sb.s_groups_count) i = 0; gdp = ext2_get_group_desc (sb, i, &bh2); - if (!gdp) { - *err = -EIO; - unlock_super (sb); - return 0; - } + if (!gdp) + goto io_error; if (le16_to_cpu(gdp->bg_free_blocks_count) > 0) break; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ext2/ialloc.c linux.ac/fs/ext2/ialloc.c --- linux.vanilla/fs/ext2/ialloc.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/ext2/ialloc.c Tue May 30 14:38:13 2000 @@ -305,7 +305,6 @@ repeat: gdp = NULL; i=0; - *err = -ENOSPC; if (S_ISDIR(mode)) { avefreei = le32_to_cpu(es->s_free_inodes_count) / sb->u.ext2_sb.s_groups_count; @@ -387,6 +386,7 @@ if (!gdp) { unlock_super (sb); iput(inode); + *err = -ENOSPC; return NULL; } bitmap_nr = load_inode_bitmap (sb, i); @@ -416,9 +416,8 @@ ext2_error (sb, "ext2_new_inode", "Free inodes count corrupted in group %d", i); - unlock_super (sb); - iput (inode); - return NULL; + /* If we continue recover from this case */ + gdp->bg_free_inodes_count = 0; } goto repeat; } @@ -429,6 +428,7 @@ "block_group = %d,inode=%d", i, j); unlock_super (sb); iput (inode); + *err = EIO; /* Should never happen */ return NULL; } gdp->bg_free_inodes_count = diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ext2/inode.c linux.ac/fs/ext2/inode.c --- linux.vanilla/fs/ext2/inode.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/ext2/inode.c Tue May 30 14:38:13 2000 @@ -117,7 +117,7 @@ inode->u.ext2_i.i_prealloc_count--; ext2_debug ("preallocation hit (%lu/%lu).\n", ++alloc_hits, ++alloc_attempts); - + *err = 0; } else { ext2_discard_prealloc (inode); ext2_debug ("preallocation miss (%lu/%lu).\n", @@ -200,6 +200,7 @@ return ret; } +/* returns NULL and sets *err on error */ static struct buffer_head * inode_getblk (struct inode * inode, int nr, int new_block, int * err, int metadata, long *phys, int *new) { @@ -223,7 +224,6 @@ return NULL; } } - *err = -EFBIG; /* Check file limits.. */ { @@ -311,7 +311,7 @@ * can fail due to: - not present * - out of space * - * NULL return in the data case is mandatory. + * NULL return in the data case, or an error, is mandatory. */ static struct buffer_head * block_getblk (struct inode * inode, struct buffer_head * bh, int nr, @@ -341,6 +341,7 @@ if (tmp == le32_to_cpu(*p)) goto out; brelse (result); + result = NULL; goto repeat; } else { *phys = tmp; @@ -487,9 +488,9 @@ #define GET_INODE_PTR(x) \ inode_getblk(inode, x, iblock, &err, 1, NULL, NULL) #define GET_INDIRECT_DATABLOCK(x) \ - block_getblk (inode, bh, x, iblock, &err, 0, &phys, &new); + block_getblk (inode, bh, x, iblock, &err, 0, &phys, &new) #define GET_INDIRECT_PTR(x) \ - block_getblk (inode, bh, x, iblock, &err, 1, NULL, NULL); + block_getblk (inode, bh, x, iblock, &err, 1, NULL, NULL) if (ptr < direct_blocks) { bh = GET_INODE_DATABLOCK(ptr); @@ -547,13 +548,11 @@ struct buffer_head * ext2_getblk(struct inode * inode, long block, int create, int * err) { struct buffer_head dummy; - int error; dummy.b_state = 0; dummy.b_blocknr = -1000; - error = ext2_get_block(inode, block, &dummy, create); - *err = error; - if (!error && buffer_mapped(&dummy)) { + *err = ext2_get_block(inode, block, &dummy, create); + if (!*err && buffer_mapped(&dummy)) { struct buffer_head *bh; bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize); if (buffer_new(&dummy)) { @@ -881,8 +880,23 @@ raw_inode->i_file_acl = cpu_to_le32(inode->u.ext2_i.i_file_acl); if (S_ISDIR(inode->i_mode)) raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext2_i.i_dir_acl); - else + else { raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32); + if (inode->i_size >> 31) { + struct super_block *sb = inode->i_sb; + struct ext2_super_block *es = sb->u.ext2_sb.s_es; + if (!(es->s_feature_ro_compat & cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE))) { + /* If this is the first large file + * created, add a flag to the superblock + * SMP Note: we're currently protected by the + * big kernel lock here, so this will need + * to be changed if that's no longer true. + */ + es->s_feature_ro_compat |= cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE); + ext2_write_super(sb); + } + } + } raw_inode->i_generation = cpu_to_le32(inode->i_generation); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ext2/namei.c linux.ac/fs/ext2/namei.c --- linux.vanilla/fs/ext2/namei.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/ext2/namei.c Tue May 30 14:38:13 2000 @@ -366,12 +366,9 @@ struct inode * inode; int err; - /* - * N.B. Several error exits in ext2_new_inode don't set err. - */ inode = ext2_new_inode (dir, mode, &err); if (!inode) - return -EIO; + return err; inode->i_op = &ext2_file_inode_operations; inode->i_fop = &ext2_file_operations; @@ -397,7 +394,7 @@ inode = ext2_new_inode (dir, mode, &err); if (!inode) - return -EIO; + return err; inode->i_uid = current->fsuid; init_special_inode(inode, mode, rdev); @@ -428,7 +425,7 @@ inode = ext2_new_inode (dir, S_IFDIR, &err); if (!inode) - return -EIO; + return err; inode->i_op = &ext2_dir_inode_operations; inode->i_fop = &ext2_dir_operations; @@ -634,7 +631,7 @@ return -ENAMETOOLONG; if (!(inode = ext2_new_inode (dir, S_IFLNK, &err))) - return -EIO; + return err; inode->i_mode = S_IFLNK | S_IRWXUGO; 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/inode.c linux.ac/fs/inode.c --- linux.vanilla/fs/inode.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/inode.c Tue May 30 17:07:33 2000 @@ -322,7 +322,7 @@ inode = list_entry(inode_entry, struct inode, i_list); if (inode->i_data.nrpages) - truncate_inode_pages(&inode->i_data, 0); + truncate_all_inode_pages(&inode->i_data); clear_inode(inode); destroy_inode(inode); } @@ -768,7 +768,7 @@ spin_unlock(&inode_lock); if (inode->i_data.nrpages) - truncate_inode_pages(&inode->i_data, 0); + truncate_all_inode_pages(&inode->i_data); destroy = 1; if (op && op->delete_inode) { 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/bugs.h linux.ac/include/asm-i386/bugs.h --- linux.vanilla/include/asm-i386/bugs.h Thu May 25 17:37:34 2000 +++ linux.ac/include/asm-i386/bugs.h Tue May 30 17:15:35 2000 @@ -8,6 +8,9 @@ * * - Channing Corn (tests & fixes), * - Andrew D. Balsa (code cleanup). + * + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 */ /* @@ -46,7 +49,7 @@ __setup("no387", no_387); -static char __initdata fpu_error = 0; +static char fpu_error __initdata = 0; static void __init copro_timeout(void) { @@ -59,8 +62,13 @@ outb_p(0,0xf0); } -static double __initdata x = 4195835.0; -static double __initdata y = 3145727.0; +static double x __initdata = 4195835.0; +static double y __initdata = 3145727.0; + +#ifdef CONFIG_X86_XMM +static float zero[4] __initdata = { 0.0, 0.0, 0.0, 0.0 }; +static float one[4] __initdata = { 1.0, 1.0, 1.0, 1.0 }; +#endif static void __init check_fpu(void) { @@ -139,6 +147,37 @@ printk("OK, FPU using exception 16 error reporting.\n"); else printk("Hmm, FPU using exception 16 error reporting with FDIV bug.\n"); + +#ifdef CONFIG_X86_FXSR + /* + * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned. + */ + if (offsetof(struct task_struct, thread.i387.hard) & 15) + panic("Kernel compiled for PII/PIII+ with FXSR, data not 16-byte aligned!"); + + if (cpu_has_fxsr) { + printk(KERN_INFO "Enabling fast FPU save and restore... "); + set_in_cr4(X86_CR4_OSFXSR); + printk("done.\n"); + } +#endif +#ifdef CONFIG_X86_XMM + if (cpu_has_xmm) { + printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... "); + set_in_cr4(X86_CR4_OSXMMEXCPT); + printk("done.\n"); + + /* Check if exception 19 works okay. */ + set_fpu_mxcsr(XMM_UNMASKED_MXCSR); + printk(KERN_INFO "Checking SIMD FPU exceptions... "); + __asm__("movups %0,%%xmm0\n\t" + "movups %1,%%xmm1\n\t" + "divps %%xmm0,%%xmm1\n\t" + : : "m" (*&zero), "m" (*&one)); + printk("OK, SIMD FPU using exception 19 error reporting.\n"); + set_fpu_mxcsr(XMM_DEFAULT_MXCSR); + } +#endif } static void __init check_hlt(void) @@ -423,6 +462,14 @@ && boot_cpu_data.x86_model == 2 && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11)) panic("Kernel compiled for PPro+, assumes a local APIC without the read-before-write bug!"); +#endif + +/* + * If we configured ourselves for FXSR, we'd better have it. + */ +#ifdef CONFIG_X86_FXSR + if (!cpu_has_fxsr) + panic("Kernel compiled for PII/PIII+, requires FXSR feature!"); #endif } 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 Tue May 30 17:16:40 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/processor.h linux.ac/include/asm-i386/processor.h --- linux.vanilla/include/asm-i386/processor.h Thu May 25 17:46:16 2000 +++ linux.ac/include/asm-i386/processor.h Tue May 30 17:15:35 2000 @@ -2,6 +2,9 @@ * include/asm-i386/processor.h * * Copyright (C) 1994 Linus Torvalds + * + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 */ #ifndef __ASM_I386_PROCESSOR_H @@ -90,17 +93,15 @@ #define X86_FEATURE_20 0x00100000 #define X86_FEATURE_21 0x00200000 #define X86_FEATURE_22 0x00400000 -#define X86_FEATURE_MMX 0x00800000 /* multimedia extensions */ +#define X86_FEATURE_MMX 0x00800000 /* Multimedia Extensions */ #define X86_FEATURE_FXSR 0x01000000 /* FXSAVE and FXRSTOR instructions (fast save and restore of FPU context), and CR4.OSFXSR (OS uses these instructions) available */ -#define X86_FEATURE_XMM 0x02000000 /* Intel MMX2 instruction set */ +#define X86_FEATURE_XMM 0x02000000 /* Streaming SIMD Extensions */ #define X86_FEATURE_26 0x04000000 #define X86_FEATURE_27 0x08000000 #define X86_FEATURE_28 0x10000000 #define X86_FEATURE_29 0x20000000 #define X86_FEATURE_30 0x40000000 #define X86_FEATURE_AMD3D 0x80000000 -#define X86_CR4_OSFXSR 0x0200 /* fast FPU save/restore */ -#define X86_CR4_OSXMMEXCPT 0x0400 /* KNI (MMX2) unmasked exception 16 */ extern struct cpuinfo_x86 boot_cpu_data; extern struct tss_struct init_tss[NR_CPUS]; @@ -125,6 +126,10 @@ (boot_cpu_data.x86_capability & X86_FEATURE_DE) #define cpu_has_vme \ (boot_cpu_data.x86_capability & X86_FEATURE_VME) +#define cpu_has_fxsr \ + (boot_cpu_data.x86_capability & X86_FEATURE_FXSR) +#define cpu_has_xmm \ + (boot_cpu_data.x86_capability & X86_FEATURE_XMM) extern char ignore_irq13; @@ -150,15 +155,17 @@ /* * Intel CPU features in CR4 */ -#define X86_CR4_VME 0x0001 /* enable vm86 extensions */ -#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ -#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ -#define X86_CR4_DE 0x0008 /* enable debugging extensions */ -#define X86_CR4_PSE 0x0010 /* enable page size extensions */ -#define X86_CR4_PAE 0x0020 /* enable physical address extensions */ -#define X86_CR4_MCE 0x0040 /* Machine check enable */ -#define X86_CR4_PGE 0x0080 /* enable global pages */ -#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ +#define X86_CR4_VME 0x0001 /* enable vm86 extensions */ +#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ +#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ +#define X86_CR4_DE 0x0008 /* enable debugging extensions */ +#define X86_CR4_PSE 0x0010 /* enable page size extensions */ +#define X86_CR4_PAE 0x0020 /* enable physical address extensions */ +#define X86_CR4_MCE 0x0040 /* Machine check enable */ +#define X86_CR4_PGE 0x0080 /* enable global pages */ +#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ +#define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */ +#define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */ /* * Save the cr4 feature set we're using (ie @@ -244,21 +251,7 @@ #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) #define INVALID_IO_BITMAP_OFFSET 0x8000 -#ifndef CONFIG_X86_FX - -#define i387_save_hard(x) \ - __asm__("fnsave %0\n\tfwait": :"m" (x)) -#define i387_restore_hard(x) \ - __asm__("frstor %0": :"m" (x)) - -#define i387_hard_to_user(uaddr, x) \ - __copy_to_user((uaddr), (x), sizeof(struct i387_hard_struct)) -#define i387_user_to_hard(x, uaddr) \ - __copy_from_user((x), (uaddr), sizeof(struct i387_hard_struct)) - -#define i387_set_cwd(x,v) do { (x).cwd = 0xffff0000 | (v); } while (0) -#define i387_set_swd(x,v) do { (x).swd = 0xffff0000 | (v); } while (0) -#define i387_set_twd(x,v) do { (x).twd = 0xffff0000 | (v); } while (0) +#ifndef CONFIG_X86_FXSR struct i387_hard_struct { long cwd; @@ -274,65 +267,24 @@ #else -/* - * has to be 128-bit aligned - */ struct i387_hard_struct { unsigned short cwd; unsigned short swd; unsigned short twd; - unsigned short fopcode; - unsigned int fip; - unsigned short fcs; - unsigned short __reserved_01; - unsigned int fdp; - unsigned short fds; - unsigned short __reserved_02; - unsigned int mxcsr; - unsigned int __reserved_03; - unsigned int st_space[32]; /* 8*16 bytes for each FP/MMX-reg = 128 bytes */ - unsigned int xmm_space[22*4]; /* 22 cachelines for MMX2 registers */ - unsigned long status; + unsigned short fop; + long fip; + long fcs; + long foo; + long fos; + long mxcsr; + long reserved; + long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ + long padding[56]; + long status; /* software status information */ } __attribute__ ((aligned (16))); -/* - * tag word conversion (thanks to Gabriel Paubert for noticing the - * subtle format difference and implementing these functions) - * - * there are several erratas wrt. the tag word in the i387, thus - * any software relying on it's value is questionable, but we - * definitely want to be as close as possible. - */ -static inline unsigned short fputag_KNIto387(unsigned char tb) { - unsigned short tw = tb; - tw = ((tw<<4) | tw) &0x0f0f; /* zzzz7654zzzz3210 */ - tw = ((tw<<2) | tw) &0x3333; /* zz76zz54zz32zz10 */ - tw = ((tw<<1) | tw) &0x5555; /* z7z6z5z4z3z2z1z0 */ - return ~(tw*3); -} - -static inline unsigned char fputag_387toKNI(unsigned short tw) { - tw = ~tw; - tw = (tw | (tw>>1)) & 0x5555; /* z7z6z5z4z3z2z1z0 */ - tw = (tw | (tw>>1)) & 0x3333; /* zz76zz54zz32zz10 */ - tw = (tw | (tw>>3)) & 0x0f0f; /* zzzz7654zzzz3210 */ - return (tw|(tw>>4)) & 0x00ff; /* zzzzzzzz76543210 */ -} - -#define i387_set_cwd(x,v) do { (x).cwd = (short)(v); } while (0) -#define i387_set_swd(x,v) do { (x).swd = (short)(v); } while (0) -#define i387_set_twd(x,v) do { (x).twd = fputag_387toKNI(v); } while (0) - -#define i387_save_hard(x) \ - { __asm__ __volatile__(".byte 0x0f, 0xae, 0x06": :"S" (&(x))); } while (0) - -#define i387_restore_hard(x) \ -do { __asm__ __volatile__(".byte 0x0f, 0xae, 0x4f, 0x00": :"D" (&(x))); } while(0) - -extern int i387_hard_to_user ( struct _fpstate * user, - struct i387_hard_struct * hard); -extern int i387_user_to_hard (struct i387_hard_struct * hard, - struct _fpstate * user); +#define X86_FXSR_MAGIC 0xbebafeca #endif struct i387_soft_struct { @@ -469,12 +421,45 @@ /* * FPU lazy state save handling.. */ +#ifndef CONFIG_X86_FXSR + #define save_fpu(tsk) do { \ - i387_save_hard(tsk->thread.i387); \ + asm volatile("fnsave %0 ; fwait" \ + : "=m" (tsk->thread.i387.hard)); \ tsk->flags &= ~PF_USEDFPU; \ stts(); \ } while (0) +#define save_init_fpu(tsk) save_fpu(tsk) + +#define restore_fpu(tsk) do { \ + asm volatile("frstor %0" \ + : : "m" (tsk->thread.i387.hard)); \ +} while (0) + +#else /* CONFIG_X86_FXSR */ + +#define save_fpu(tsk) do { \ + asm volatile("fxsave %0 ; fwait" \ + : "=m" (tsk->thread.i387.hard)); \ + tsk->flags &= ~PF_USEDFPU; \ + stts(); \ +} while (0) + +#define save_init_fpu(tsk) do { \ + asm volatile("fxsave %0 ; fnclex" \ + : "=m" (tsk->thread.i387.hard)); \ + tsk->flags &= ~PF_USEDFPU; \ + stts(); \ +} while (0) + +#define restore_fpu(tsk) do { \ + asm volatile("fxrstor %0" \ + : : "m" (tsk->thread.i387.hard)); \ +} while (0) + +#endif /* CONFIG_X86_FXSR */ + #define unlazy_fpu(tsk) do { \ if (tsk->flags & PF_USEDFPU) \ save_fpu(tsk); \ @@ -486,6 +471,51 @@ stts(); \ } \ } while (0) + +/* + * FPU state initialization.. + */ +#ifdef CONFIG_X86_FXSR + +#define set_fpu_cwd(tsk, val) do { \ + tsk->thread.i387.hard.cwd = (unsigned short)(val); \ +} while (0) + +#define set_fpu_swd(tsk, val) do { \ + tsk->thread.i387.hard.swd = (unsigned short)(val); \ +} while (0) + +#define set_fpu_twd(tsk, val) do { \ + tsk->thread.i387.hard.twd = (unsigned short)(val); \ +} while (0) + +#else /* CONFIG_X86_FXSR */ + +#define set_fpu_cwd(tsk, val) do { \ + tsk->thread.i387.hard.cwd = ((long)(val) | 0xffff0000); \ +} while (0) + +#define set_fpu_swd(tsk, val) do { \ + tsk->thread.i387.hard.swd = ((long)(val) | 0xffff0000); \ +} while (0) + +#define set_fpu_twd(tsk, val) do { \ + tsk->thread.i387.hard.twd = ((long)(val) | 0xffff0000); \ +} while (0) + +#endif /* CONFIG_X86_FXSR */ + +#ifdef CONFIG_X86_XMM +#define XMM_DEFAULT_MXCSR 0x1f80 +#define XMM_UNMASKED_MXCSR 0x0000 + +#define set_fpu_mxcsr(val) do { \ + if (cpu_has_xmm) { \ + unsigned long __mxcsr = ((unsigned long)(val) & 0xffff); \ + asm volatile("ldmxcsr %0" : : "m" (__mxcsr)); \ + } \ +} while (0) +#endif /* * Return saved PC of a blocked thread. 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 Tue May 30 17:15:35 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/sigcontext.h linux.ac/include/asm-i386/sigcontext.h --- linux.vanilla/include/asm-i386/sigcontext.h Thu May 25 17:46:16 2000 +++ linux.ac/include/asm-i386/sigcontext.h Tue May 30 16:47:56 2000 @@ -1,34 +1,70 @@ #ifndef _ASMi386_SIGCONTEXT_H #define _ASMi386_SIGCONTEXT_H -#include /* * As documented in the iBCS2 standard.. * - * The first part of "struct _fpstate" is just the - * normal i387 hardware setup, the extra "status" - * word is used to save the coprocessor status word - * before entering the handler. + * The first part of "struct _fpstate" is just the normal i387 + * hardware setup, the extra "status" word is used to save the + * coprocessor status word before entering the handler. + * + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 + * + * The FPU state data structures have had to grow to accomodate the + * extended FPU state required by the Streaming SIMD Extensions. + * There is no documented standard to accomplish this at the moment. */ struct _fpreg { unsigned short significand[4]; unsigned short exponent; }; -struct _fpstate { - unsigned long cw, - sw, - tag, - ipoff, - cssel, - dataoff, - datasel; +struct _fpxreg { + unsigned short significand[4]; + unsigned short exponent; + unsigned short padding[3]; +}; + +struct _xmmreg { + unsigned long element[4]; +}; + +struct _fpstate_fsave { + unsigned long cw; + unsigned long sw; + unsigned long tag; + unsigned long ipoff; + unsigned long cssel; + unsigned long dataoff; + unsigned long datasel; struct _fpreg _st[8]; unsigned long status; -#ifdef CONFIG_X86_FX +}; + +struct _fpstate_fxsave { + unsigned short cw; + unsigned short sw; + unsigned short tag; + unsigned short opcode; + unsigned long ipoff; + unsigned long cssel; + unsigned long dataoff; + unsigned long datasel; unsigned long mxcsr; - unsigned long _xmm[4*22]; -#endif + unsigned long reserved; + struct _fpxreg _st[8]; + struct _xmmreg _xmm[8]; + unsigned long padding[56]; + unsigned long status; +}; + +struct _fpstate { + union { + struct _fpstate_fsave fsave; + struct _fpstate_fxsave fxsave; + } fpregs; + unsigned long magic; /* FPU save format: 0 = FSAVE, else FXSAVE */ }; struct sigcontext { 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-i386/user.h linux.ac/include/asm-i386/user.h --- linux.vanilla/include/asm-i386/user.h Thu May 25 17:46:16 2000 +++ linux.ac/include/asm-i386/user.h Tue May 30 16:47:56 2000 @@ -30,15 +30,53 @@ The minimum core file size is 3 pages, or 12288 bytes. */ -struct user_i387_struct { +/* + * Pentium III FXSR, SSE support + * Gareth Hughes , May 2000 + * + * To enable an ELF-compatible FPU context dump that includes the SIMD FPU + * state, we must have room for the regular i387 FPU state as well as the + * new extended SIMD FPU state format. The magic field can be used to + * determine in what format the FPU was dumped, and thus SIMD FPU core + * dumps can be correctly interpreted by non-PIII+ processors. We use the + * following convention: a non-zero magic field implies an extended FXSAVE + * FPU state format, while a zero magic field implies a regular FSAVE + * format. + */ + +struct user_i387_fsave { long cwd; long swd; long twd; long fip; long fcs; - long fdp; - long fds; + long foo; + long fos; long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ +}; + +struct user_i387_fxsave { + unsigned short cwd; + unsigned short swd; + unsigned short twd; + unsigned short fop; + long fip; + long fcs; + long foo; + long fos; + long mxcsr; + long reserved; + long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ + long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ + long padding[56]; +}; + +struct user_i387_struct { + union { + struct user_i387_fsave fsave; + struct user_i387_fxsave fxsave; + } fpregs; + unsigned long magic; /* FPU save format: 0 = FSAVE, else FXSAVE */ }; /* 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<i_size ? size : inode->i_size, - abs(inode->i_size - size) - ); + size < inode->i_size ? inode->i_size - size + : size - inode->i_size); return 0; } @@ -865,7 +875,6 @@ #define putname(name) free_page((unsigned long)(name)) enum {BDEV_FILE, BDEV_SWAP, BDEV_FS, BDEV_RAW}; -extern void kill_fasync(struct fasync_struct *, int, int); extern int register_blkdev(unsigned int, const char *, struct block_device_operations *); extern int unregister_blkdev(unsigned int, const char *); extern struct block_device *bdget(dev_t); @@ -1104,6 +1113,7 @@ /* Generic buffer handling for block filesystems.. */ extern int block_flushpage(struct page *, unsigned long); +extern void block_destroy_buffers(struct page *); extern int block_symlink(struct inode *, const char *, int); extern int block_write_full_page(struct page*, get_block_t*); extern int block_read_full_page(struct page*, get_block_t*); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/input.h linux.ac/include/linux/input.h --- linux.vanilla/include/linux/input.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/input.h Tue May 30 21:28:10 2000 @@ -2,9 +2,9 @@ #define _INPUT_H /* - * input.h Version 0.1 + * $Id: input.h,v 1.13 2000/05/29 10:54:53 vojtech Exp $ * - * Copyright (c) 1999 Vojtech Pavlik + * Copyright (c) 1999-2000 Vojtech Pavlik * * Sponsored by SuSE */ @@ -33,6 +33,7 @@ #include #else #include +#include #endif /* @@ -47,16 +48,6 @@ }; /* - * The device ID structure; - */ - -struct input_id { - __u16 bus; - __u16 vendor; - __u16 product; -}; - -/* * Protocol version. */ @@ -66,14 +57,17 @@ * IOCTLs (0x00 - 0x7f) */ -#define EVIOCGVERSION _IOR('E', 0x01, __u32) /* get driver version */ -#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */ +#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ +#define EVIOCGID _IOR('E', 0x02, short[4]) /* get device ID */ #define EVIOCGREP _IOR('E', 0x03, int[2]) /* get repeat settings */ #define EVIOCSREP _IOW('E', 0x03, int[2]) /* get repeat settings */ -#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x03, len) /* get device name */ +#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ +#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ +#define EVIOCGKEY _IOR('E', 0x05, int[2]) /* get key value */ +#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ + #define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */ -#define EVIOCGABSLIM(num) _IOR('E', 0x40 + num, int[4]) /* get abs event limits */ -#define EVIOCGABS(num) _IOR('E', 0x80 + num, int) /* get abs value */ +#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, int[5]) /* get abs value/limits */ /* * Event types @@ -308,6 +302,7 @@ #define BTN_BASE3 0x128 #define BTN_BASE4 0x129 #define BTN_BASE5 0x12a +#define BTN_BASE6 0x12b #define BTN_GAMEPAD 0x130 #define BTN_A 0x130 @@ -364,6 +359,8 @@ #define ABS_RZ 0x05 #define ABS_THROTTLE 0x06 #define ABS_RUDDER 0x07 +#define ABS_TL 0x08 +#define ABS_TR 0x09 #define ABS_HAT0X 0x10 #define ABS_HAT0Y 0x11 #define ABS_HAT1X 0x12 @@ -406,6 +403,27 @@ #define SND_BELL 0x01 #define SND_MAX 0x07 +/* + * IDs. + */ + +#define ID_BUS 0 +#define ID_VENDOR 1 +#define ID_PRODUCT 2 +#define ID_VERSION 3 + +#define BUS_PCI 0x01 +#define BUS_ISAPNP 0x02 +#define BUS_USB 0x03 + +#define BUS_ISA 0x10 +#define BUS_I8042 0x11 +#define BUS_XTKBD 0x12 +#define BUS_RS232 0x13 +#define BUS_GAMEPORT 0x14 +#define BUS_PARPORT 0x15 +#define BUS_AMIGA 0x16 + #ifdef __KERNEL__ /* @@ -425,7 +443,10 @@ int number; char *name; - struct input_id id; + unsigned short idbus; + unsigned short idvendor; + unsigned short idproduct; + unsigned short idversion; unsigned long evbit[NBITS(EV_MAX)]; unsigned long keybit[NBITS(KEY_MAX)]; @@ -434,7 +455,10 @@ unsigned long ledbit[NBITS(LED_MAX)]; unsigned long sndbit[NBITS(SND_MAX)]; - unsigned char *keycode; + unsigned int keycodemax; + unsigned int keycodesize; + void *keycode; + unsigned int repeat_key; struct timer_list timer; @@ -500,8 +524,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); -#define input_report_key(a,b,c) input_event(a, EV_KEY, b, c) -#define input_report_btn(a,b,c) input_event(a, EV_KEY, b, !!(c)) +#define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c)) #define input_report_rel(a,b,c) input_event(a, EV_REL, b, c) #define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/mc146818rtc.h linux.ac/include/linux/mc146818rtc.h --- linux.vanilla/include/linux/mc146818rtc.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/mc146818rtc.h Tue May 30 17:16:40 2000 @@ -10,22 +10,10 @@ #ifndef _MC146818RTC_H #define _MC146818RTC_H -#include -#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 Tue May 30 17:15:35 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) @@ -457,6 +462,7 @@ extern unsigned long page_unuse(struct page *); extern int shrink_mmap(int, int); extern void truncate_inode_pages(struct address_space *, loff_t); +extern void truncate_all_inode_pages(struct address_space *); /* generic vm_area_ops exported for stackable file systems */ extern int filemap_swapout(struct page * page, struct file *file); 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 Tue May 30 17:15:35 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 Tue May 30 14:53:15 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 @@ -1073,6 +1077,9 @@ #define PCI_VENDOR_ID_AFAVLAB 0x14db #define PCI_DEVICE_ID_AFAVLAB_TK9902 0x2120 + +#define PCI_VENDOR_ID_MORETON 0x15aa +#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000 #define PCI_VENDOR_ID_SYMPHONY 0x1c1c #define PCI_DEVICE_ID_SYMPHONY_101 0x0001 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 Tue May 30 17:15:35 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/serial.h linux.ac/include/linux/serial.h --- linux.vanilla/include/linux/serial.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/serial.h Tue May 30 14:53:12 2000 @@ -10,6 +10,7 @@ #ifndef _LINUX_SERIAL_H #define _LINUX_SERIAL_H +#ifdef __KERNEL__ #include /* @@ -27,10 +28,12 @@ */ #define SERIAL_XMIT_SIZE PAGE_SIZE +#endif + struct serial_struct { int type; int line; - unsigned long port; + unsigned int port; int irq; int flags; int xmit_fifo_size; @@ -44,7 +47,8 @@ unsigned short closing_wait2; /* no longer used... */ unsigned char *iomem_base; unsigned short iomem_reg_shift; - int reserved[2]; + unsigned int port_high; + int reserved[1]; }; /* @@ -70,7 +74,8 @@ #define PORT_16C950 10 /* Oxford Semiconductor */ #define PORT_16654 11 #define PORT_16850 12 -#define PORT_MAX 12 +#define PORT_RSA 13 /* RSA-DV II/S card */ +#define PORT_MAX 13 #define SERIAL_IO_PORT 0 #define SERIAL_IO_HUB6 1 @@ -115,7 +120,10 @@ #define ASYNC_LOW_LATENCY 0x2000 /* Request low latency behaviour */ -#define ASYNC_FLAGS 0x3FFF /* Possible legal async flags */ +#define ASYNC_BUGGY_UART 0x4000 /* This is a buggy UART, skip some safety + * checks. Note: can be dangerous! */ + +#define ASYNC_FLAGS 0x7FFF /* Possible legal async flags */ #define ASYNC_USR_MASK 0x3430 /* Legal flags that non-privileged * users can set or reset */ @@ -127,7 +135,9 @@ #define ASYNC_CLOSING 0x08000000 /* Serial port is closing */ #define ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */ #define ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */ -#define ASYNC_SHARE_IRQ 0x01000000 /* for multifunction cards */ +#define ASYNC_SHARE_IRQ 0x01000000 /* for multifunction cards + --- no longer used */ +#define ASYNC_AUTOPROBE 0x00800000 /* Port was autoprobed */ #define ASYNC_INTERNAL_FLAGS 0xFF000000 /* Internal flags */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/serialP.h linux.ac/include/linux/serialP.h --- linux.vanilla/include/linux/serialP.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/serialP.h Tue May 30 17:16:27 2000 @@ -24,6 +24,11 @@ #include #include #include +#if (LINUX_VERSION_CODE < 0x020300) +/* Unfortunate, but Linux 2.2 needs async_icount defined here and + * it got moved in 2.3 */ +#include +#endif struct serial_state { int magic; @@ -190,6 +195,9 @@ /* Do not use irq sharing for this device */ #define SPCI_FL_NO_SHIRQ 0x1000 -#define SPCI_FL_PNPDEFAULT (SPCI_FL_IRQRESOURCE) +/* This is a PNP device */ +#define SPCI_FL_ISPNP 0x2000 + +#define SPCI_FL_PNPDEFAULT (SPCI_FL_IRQRESOURCE|SPCI_FL_ISPNP) #endif /* _LINUX_SERIAL_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/serial_reg.h linux.ac/include/linux/serial_reg.h --- linux.vanilla/include/linux/serial_reg.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/serial_reg.h Tue May 30 14:53:12 2000 @@ -229,5 +229,54 @@ #define UART_TRG_120 0x78 #define UART_TRG_128 0x80 +/* + * These definitions are for the RSA-DV II/S card, from + * + * Kiyokazu SUTO + */ + +#define UART_RSA_BASE (-8) + +#define UART_RSA_MSR ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */ + +#define UART_RSA_MSR_SWAP (1 << 0) /* Swap low/high 8 bytes in I/O port addr */ +#define UART_RSA_MSR_FIFO (1 << 2) /* Enable the external FIFO */ +#define UART_RSA_MSR_FLOW (1 << 3) /* Enable the auto RTS/CTS flow control */ +#define UART_RSA_MSR_ITYP (1 << 4) /* Level (1) / Edge triger (0) */ + +#define UART_RSA_IER ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */ + +#define UART_RSA_IER_Rx_FIFO_H (1 << 0) /* Enable Rx FIFO half full int. */ +#define UART_RSA_IER_Tx_FIFO_H (1 << 1) /* Enable Tx FIFO half full int. */ +#define UART_RSA_IER_Tx_FIFO_E (1 << 2) /* Enable Tx FIFO empty int. */ +#define UART_RSA_IER_Rx_TOUT (1 << 3) /* Enable char receive timeout int */ +#define UART_RSA_IER_TIMER (1 << 4) /* Enable timer interrupt */ + +#define UART_RSA_SRR ((UART_RSA_BASE) + 2) /* IN: Status Read Register */ + +#define UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0) /* Tx FIFO is not empty (1) */ +#define UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1) /* Tx FIFO is not half full (1) */ +#define UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2) /* Tx FIFO is not full (1) */ +#define UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3) /* Rx FIFO is not empty (1) */ +#define UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4) /* Rx FIFO is not half full (1) */ +#define UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5) /* Rx FIFO is not full (1) */ +#define UART_RSA_SRR_Rx_TOUT (1 << 6) /* Character reception timeout occured (1) */ +#define UART_RSA_SRR_TIMER (1 << 7) /* Timer interrupt occured */ + +#define UART_RSA_FRR ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */ + +#define UART_RSA_TIVSR ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */ + +#define UART_RSA_TCR ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */ + +#define UART_RSA_TCR_SWITCH (1 << 0) /* Timer on */ + +/* + * The RSA DSV/II board has two fixed clock frequencies. One is the + * standard rate, and the other is 8 times faster. + */ +#define SERIAL_RSA_BAUD_BASE (921600) +#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8) + #endif /* _LINUX_SERIAL_REG_H */ 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 Tue May 30 21:25:55 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 Tue May 30 17:35:23 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 Tue May 30 17:07:33 2000 @@ -90,10 +90,16 @@ /* * Remove a page from the page cache and free it. Caller has to make * sure the page is locked and that nobody else uses it - or that usage - * is safe. + * is safe. We need that the page don't have any buffers. */ static inline void __remove_inode_page(struct page *page) { + if (!PageLocked(page)) + PAGE_BUG(page); + + if (page->buffers) + BUG(); + remove_page_from_inode_queue(page); remove_page_from_hash_queue(page); page->mapping = NULL; @@ -101,9 +107,6 @@ void remove_inode_page(struct page *page) { - if (!PageLocked(page)) - PAGE_BUG(page); - spin_lock(&pagecache_lock); __remove_inode_page(page); spin_unlock(&pagecache_lock); @@ -116,14 +119,13 @@ * This function only removes the unlocked pages, if you want to * remove all the pages of one inode, you must call truncate_inode_pages. */ - void invalidate_inode_pages(struct inode * inode) { struct list_head *head, *curr; struct page * page; head = &inode->i_mapping->pages; - +repeat: spin_lock(&pagecache_lock); spin_lock(&pagemap_lru_lock); curr = head->next; @@ -135,20 +137,61 @@ /* We cannot invalidate a locked page */ if (TryLockPage(page)) continue; - - __lru_cache_del(page); + if (page->buffers) { + page_cache_get(page); + spin_unlock(&pagemap_lru_lock); + spin_unlock(&pagecache_lock); + block_destroy_buffers(page); + remove_inode_page(page); + lru_cache_del(page); + page_cache_release(page); + UnlockPage(page); + page_cache_release(page); + goto repeat; + } __remove_inode_page(page); + __lru_cache_del(page); UnlockPage(page); page_cache_release(page); } - spin_unlock(&pagemap_lru_lock); spin_unlock(&pagecache_lock); } -/* +static inline void truncate_partial_page(struct page *page, unsigned partial) +{ + memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial); + + if (page->buffers) + block_flushpage(page, partial); + +} + +static inline void truncate_complete_page(struct page *page) +{ + if (page->buffers) + block_destroy_buffers(page); + lru_cache_del(page); + + /* + * We remove the page from the page cache _after_ we have + * destroyed all buffer-cache references to it. Otherwise some + * other process might think this inode page is not in the + * page cache and creates a buffer-cache alias to it causing + * all sorts of fun problems ... + */ + remove_inode_page(page); + page_cache_release(page); +} + +/** + * truncate_inode_pages - truncate *all* the pages from an offset + * @mapping: mapping to truncate + * @lstart: offset from with to truncate + * * Truncate the page cache at a set offset, removing the pages * that are beyond that offset (and zeroing out partial pages). + * If any page is locked we wait for it to become unlocked. */ void truncate_inode_pages(struct address_space * mapping, loff_t lstart) { @@ -168,11 +211,10 @@ page = list_entry(curr, struct page, list); curr = curr->next; - offset = page->index; - /* page wholly truncated - free it */ - if (offset >= start) { + /* Is one of the pages to truncate? */ + if ((offset >= start) || (partial && (offset + 1) == start)) { if (TryLockPage(page)) { page_cache_get(page); spin_unlock(&pagecache_lock); @@ -183,22 +225,14 @@ page_cache_get(page); spin_unlock(&pagecache_lock); - if (!page->buffers || block_flushpage(page, 0)) - lru_cache_del(page); - - /* - * We remove the page from the page cache - * _after_ we have destroyed all buffer-cache - * references to it. Otherwise some other process - * might think this inode page is not in the - * page cache and creates a buffer-cache alias - * to it causing all sorts of fun problems ... - */ - remove_inode_page(page); + if (partial && (offset + 1) == start) { + truncate_partial_page(page, partial); + partial = 0; + } else + truncate_complete_page(page); UnlockPage(page); page_cache_release(page); - page_cache_release(page); /* * We have done things without the pagecache lock, @@ -209,38 +243,59 @@ */ goto repeat; } - /* - * there is only one partial page possible. - */ - if (!partial) - continue; + } + spin_unlock(&pagecache_lock); +} - /* and it's the one preceeding the first wholly truncated page */ - if ((offset + 1) != start) - continue; +/** + * truncate_all_inode_pages - truncate *all* the pages + * @mapping: mapping to truncate + * + * Truncate all the inode pages. If any page is locked we wait for it + * to become unlocked. This function can block. + */ +void truncate_all_inode_pages(struct address_space * mapping) +{ + struct list_head *head, *curr; + struct page * page; + + head = &mapping->pages; +repeat: + spin_lock(&pagecache_lock); + spin_lock(&pagemap_lru_lock); + curr = head->next; + + while (curr != head) { + page = list_entry(curr, struct page, list); + curr = curr->next; - /* partial truncate, clear end of page */ if (TryLockPage(page)) { + page_cache_get(page); + spin_unlock(&pagemap_lru_lock); spin_unlock(&pagecache_lock); + wait_on_page(page); + page_cache_release(page); goto repeat; } - page_cache_get(page); - spin_unlock(&pagecache_lock); - - memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial); - if (page->buffers) - block_flushpage(page, partial); - - partial = 0; - - /* - * we have dropped the spinlock so we have to - * restart. - */ + if (page->buffers) { + page_cache_get(page); + spin_unlock(&pagemap_lru_lock); + spin_unlock(&pagecache_lock); + block_destroy_buffers(page); + remove_inode_page(page); + lru_cache_del(page); + page_cache_release(page); + UnlockPage(page); + page_cache_release(page); + goto repeat; + } + __lru_cache_del(page); + __remove_inode_page(page); UnlockPage(page); page_cache_release(page); - goto repeat; } + + spin_unlock(&pagemap_lru_lock); spin_unlock(&pagecache_lock); } @@ -264,7 +319,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,22 +381,28 @@ 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) { @@ -351,6 +421,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 Tue May 30 17:07:33 2000 @@ -73,6 +73,7 @@ PAGE_BUG(page); PageClearSwapCache(page); + ClearPageDirty(page); remove_inode_page(page); } @@ -102,9 +103,10 @@ if (!PageLocked(page)) BUG(); - if (block_flushpage(page, 0)) - lru_cache_del(page); + if (page->buffers) + block_destroy_buffers(page); + lru_cache_del(page); __delete_from_swap_cache(page); page_cache_release(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/ipx/af_ipx.c linux.ac/net/ipx/af_ipx.c --- linux.vanilla/net/ipx/af_ipx.c Thu May 25 17:37:38 2000 +++ linux.ac/net/ipx/af_ipx.c Tue May 30 14:48:47 2000 @@ -600,8 +600,7 @@ memcpy(skb2->h.raw, skb->h.raw, skb->len); } kfree_skb(skb); - - return (NULL); + return (skb2); } static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) 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/header.tk linux.ac/scripts/header.tk --- linux.vanilla/scripts/header.tk Thu May 25 17:38:37 2000 +++ linux.ac/scripts/header.tk Tue May 30 21:02:01 2000 @@ -402,6 +402,7 @@ proc menusplit {w m n} { if { $n > 2 } then { + update idletasks set menuoptsize [expr [$m yposition 2] - [$m yposition 1]] set maxsize [winfo screenheight $w] set splitpoint [expr $maxsize * 4 / 5 / $menuoptsize - 1] @@ -409,6 +410,10 @@ $m entryconfigure $i -columnbreak 1 } } +} + +proc menutitle {text menu w} { + wm title $w "$text" } proc submenu { w mnum line text subnum } { 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/tkgen.c linux.ac/scripts/tkgen.c --- linux.vanilla/scripts/tkgen.c Thu May 25 17:38:37 2000 +++ linux.ac/scripts/tkgen.c Tue May 30 21:02:01 2000 @@ -1248,7 +1248,7 @@ printf( "\tminimenu $w.config.f %d %d \"%s\" tmpvar_%d %s\n", cfg->menu_number, cfg->menu_line, cfg->label, -(cfg->nameindex), vartable[cfg->next->nameindex].name ); - printf( "\tmenu $w.config.f.x%d.x.menu -title \"%s\"\n", + printf( "\tmenu $w.config.f.x%d.x.menu -tearoffcommand \"menutitle \\\"%s\\\"\"\n", cfg->menu_line, cfg->label ); cfg1 = cfg; opt_count = 0; 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: