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 Sun Jun 4 21:19:20 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 @@ -2155,6 +2173,14 @@ 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 D: the gpm mouse server and kernel support for it @@ -2168,7 +2194,7 @@ N: Paul `Rusty' Russell E: rusty@linuxcare.com -W: http://www.rustcorp.com +W: http://www.samba.org/netfilter D: Ruggedly handsome. D: netfilter, ipchains with Michael Neuling. S: 301/222 City Walk @@ -2779,15 +2805,15 @@ S: The Netherlands N: David Woodhouse -E: David.Woodhouse@mvhi.com -E: Dave@imladris.demon.co.uk -D: Extensive ARCnet rewrite -D: ARCnet COM20020, COM90xx IO-MAP drivers -D: SO_BINDTODEVICE in 2.1.x (from Elliot Poger's code in 2.0.31) -D: Contributed to NCPFS rewrite for 2.1.x dcache -D: Alpha platforms: SX164, LX164 and Ruffian ported to 2.1.x -S: 29, David Bull Way -S: Milton, Cambridge. CB4 6DP +E: dwmw2@infradead.org +E: dwmw2@redhat.com +D: ARCnet stuff, Applicom board driver, SO_BINDTODEVICE, +D: some Alpha platform porting from 2.0, Memory Technology Devices, +D: Acquire watchdog timer, PC speaker driver maintenance, +D: various other stuff that annoyed me by not working. +S: c/o Red Hat UK Limited +S: 35-36 Cambridge Place +S: Cambridge. CB2 1NS S: England N: Frank Xia 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 Sun Jun 4 22:06:32 2000 @@ -72,12 +72,17 @@ 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: + System V shared memory is now implemented via a filesystem. You do +not have to mount it to use it as long as you can live with the +default maxima for shared memory and segments. If you wish to change +these variables, you have to mount it with the options nr_blocks +and/or nr_inodes. If you want to use POSIX shm, then it needs to be +mounted somewhere. The recommended place is /dev/shm and this can be +done by adding the following line to /etc/fstab: -none /var/shm shm defaults 0 0 +none /dev/shm shm defaults 0 0 -Remember to create the mountpoint directory; it does not have to be /var/shm. +Remember to create the directory that you intend to mount shm on. now performs a cold reboot instead of a warm reboot for increased hardware compatibility. If you want a warm reboot and @@ -246,7 +251,7 @@ The IP firewalling and NAT code has been replaced again. The userspace tool `iptables' is distributed at: - http://antarctica.penguincomputing.com/~netfilter/ + http://netfilter.filewatcher.org http://www.samba.org/netfilter/ http://netfilter.kernelnotes.org @@ -740,7 +745,7 @@ ========= The 1.1.0 release: -http://antarctica.penguincomputing.com/~netfilter/iptables-1.1.0.tar.bz2 +http://netfilter.filewatcher.org/iptables-1.1.0.tar.bz2 http://www.samba.org/netfilter/iptables-1.1.0.tar.bz2 http://netfilter.kernelnotes.org/iptables-1.1.0.tar.bz2 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 Sun Jun 4 22:06:32 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 @@ -699,6 +699,15 @@ It is normally safe to answer Y to this question unless your motherboard uses a VIA VP2 chipset, in which case you should say N. +IGNORE word93 Validation BITS +CONFIG_IDEDMA_IVB + Since various rules were applied and created ... et al. as it relates + the detection of vaild cable signals. This is a result of unclear terms + in ATA-4 and ATA-5 standards. + + It is normally safe to answer Y; however, the default is N. + + Various ATA, Work(s) In Progress (EXPERIMENTAL) CONFIG_IDEDMA_PCI_WIP If you enable this you will be able to use and test highly @@ -733,7 +742,7 @@ If you say Y here, then say Y to "Use DMA by default when available" as well. -AEC62XX Tuning support (WIP) +AEC62XX Tuning support CONFIG_AEC62XX_TUNING Please read the comments at the top of drivers/ide/aec62xx.c If unsure, say N. @@ -1781,7 +1790,8 @@ Various modules exist for netfilter which replace the previous masquerading (ipmasqadm), packet filtering (ipchains), transparent proxying, and portforwarding mechanisms. Please see - Documentation/Changes for the location of these packages. + Documentation/Changes under "iptables" for the location of these + packages. Make sure to say N to "Fast switching" below if you intend to say Y here, as Fast switching currently bypasses netfilter. @@ -2571,11 +2581,10 @@ http://www.linuxdoc.org/docs.html#guide . Shared memory is now implemented using a new (minimal) virtual file - system, which you need to mount before programs can use shared - memory. To do this automatically at system startup just add the + system. To mount it automatically at system startup just add the following line to your /etc/fstab: - none /var/shm shm defaults 0 0 + none /dev/shm shm defaults 0 0 Saying Y here enlarges your kernel by about 18 KB. Just say Y. @@ -2729,24 +2738,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 +8535,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 +9593,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 +9625,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 +9645,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 +9666,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 +9704,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 @@ -13525,16 +13538,19 @@ differs slightly from OSS/Free, so PLEASE READ Documentation/sound/sonicvibes. -Trident 4DWave DX/NX or SiS 7018 PCI Audio Core +Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core CONFIG_SOUND_TRIDENT Say Y or M if you have a PCI sound card utilizing the Trident 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 - built-in. The SiS 7018 PCI Audio Core is embedded in SiS960 - Super South Bridge and SiS540/630 Single Chipset. + or ALi 5451 built-in. The SiS 7018 PCI Audio Core is embedded + in SiS960 Super South Bridge and SiS540/630 Single Chipset. + The ALi 5451 PCI Audio Core is embedded in ALi M1535, M1535D, + M1535+ or M1535D+ South Bridge. Use lspci -n to find out if your sound card or chipset uses Trident 4DWave or SiS 7018. PCI ID 1023:2000 or 1023:2001 stands - for Trident 4Dwave. PCI ID 1039:7018 stands for SiS7018. + for Trident 4Dwave. PCI ID 1039:7018 stands for SiS7018. PCI ID + 10B9:5451 stands for ALi5451. This driver differs slightly from OSS/Free, so PLEASE READ the comments at the top of driver/sound/trident.c 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/DocBook/kernel-locking.tmpl linux.ac/Documentation/DocBook/kernel-locking.tmpl --- linux.vanilla/Documentation/DocBook/kernel-locking.tmpl Thu May 25 17:38:41 2000 +++ linux.ac/Documentation/DocBook/kernel-locking.tmpl Sun Jun 4 21:26:29 2000 @@ -208,7 +208,12 @@ your task will put itself on the queue, and be woken up when the semaphore is released. This means the CPU will do something else while you are waiting, but there are many cases when you - simply can't sleep, and so have to use a spinlock instead. + simply can't sleep (see ), and so + have to use a spinlock instead. + + + Neither type of lock is recursive: see + . @@ -430,7 +435,7 @@ Hardware interrupts usually communicate with a bottom half, - tasklet or softirq. Frequently this involved putting work in a + tasklet or softirq. Frequently this involves putting work in a queue, which the BH/softirq will take out. @@ -522,8 +527,8 @@ There is a coding bug where a piece of code tries to grab a spinlock twice: it will spin forever, waiting for the lock to - be released (spinlocks and writelocks are not re-entrant in - Linux). This is trivial to diagnose: not a + be released (spinlocks, rwlocks and semaphores are not + recursive in Linux). This is trivial to diagnose: not a stay-up-five-nights-talk-to-fluffy-code-bunnies kind of problem. @@ -754,37 +759,15 @@ - Dropping or gaining a spinlock, and any atomic operation are - all defined to act as memory barriers (ie. as per the - mb() macro). - - - - There is a similar, but unrelated, problem with code like the - following: - - - - if (!(ctrack->status & IPS_CONFIRMED)) { - spin_lock_bh(&ip_conntrack_lock); - if (!(ctrack->status & IPS_CONFIRMED)) { - clean_from_lists(h->ctrack); - h->ctrack->status |= IPS_CONFIRMED; - } - spin_unlock_bh(&ip_conntrack_lock); - } - - - - In this case, the author has tried to be tricky: knowing that - the CONFIRMED bit is set and never reset in the status word, - you can test it outside the lock, and frequently avoid - grabbing the lock at all. However, the compiler could cache - the value in a register, rather than rereading it once the - lock is obtained, creating a subtle race. The way to get - around this is to declare the status field `volatile', or use - a temporary volatile pointer to achieve the same effect in - this one place. + Any atomic operation is defined to act as a memory barrier + (ie. as per the mb() macro). Also, + spinlock operations act as partial barriers: operations after + gaining a spinlock will never be moved to precede the + spin_lock() call, and operations before + releasing a spinlock will never be moved after the + spin_unlock() call. + @@ -911,7 +894,8 @@ You can never call the following routines while holding a - spinlock, as they may sleep: + spinlock, as they may sleep. This also means you need to be in + user context. @@ -952,11 +936,19 @@ - printk(), which can be called from - user context, interestingly enough. + down_interruptible() and + down() + + + There is a down_trylock() which can be + used inside interrupt context, as it will not sleep. + up() will also never sleep. + + printk() can be called in + any context, interestingly enough. @@ -1047,9 +1039,11 @@ Another common problem is deleting timers which restart themselves (by calling add_timer() at the end of their timer function). Because this is a fairly common case - which is prone to races, the function del_timer_sync() - (include/linux/timer.h) is - provided to handle this case. It returns the number of times the timer + which is prone to races, you can put a call to + timer_exit() at the very end of your timer function, + and user del_timer_sync() + (include/linux/timer.h) + to handle this case. It returns the number of times the timer had to be deleted before we finally stopped it from adding itself back in. @@ -1093,8 +1087,8 @@ Thanks to Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul - Mackerras, Ruedi Aschwanden, Alan Cox for proofreading, - correcting, flaming, commenting. + Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul and Tim + Waugh for proofreading, correcting, flaming, commenting. 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/kernel-doc-nano-HOWTO.txt linux.ac/Documentation/kernel-doc-nano-HOWTO.txt --- linux.vanilla/Documentation/kernel-doc-nano-HOWTO.txt Thu May 25 17:38:41 2000 +++ linux.ac/Documentation/kernel-doc-nano-HOWTO.txt Sun Jun 4 22:21:48 2000 @@ -123,6 +123,25 @@ Take a look around the source tree for examples. + +How to make new SGML template files +----------------------------------- + +SGML template files (*.tmpl) are like normal SGML files, except that +they can contain escape sequences where extracted documentation should +be inserted. + +!E is replaced by the documentation, in , for +functions that are exported using EXPORT_SYMBOL: the function list is +collected from files listed in Documentation/DocBook/Makefile. + +!I is replaced by the documentation for functions that are +_not_ exported using EXPORT_SYMBOL. + +!F is replaced by the +documentation, in , for the functions listed. + + Tim. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/networking/8139too.txt linux.ac/Documentation/networking/8139too.txt --- linux.vanilla/Documentation/networking/8139too.txt Thu May 25 17:38:38 2000 +++ linux.ac/Documentation/networking/8139too.txt Wed May 31 11:25:23 2000 @@ -181,11 +181,20 @@ 11) RTL8139C support untested. +12) 10base-T support flaky + Change History -------------- +Version 0.9.6 - May 30, 2000 + +* Fix 4-extra-bytes bug + (thanks to Markus Westergren, via Santiago Garcia Mantinan) +* Yet more improved chip recognition + + Version 0.9.5 - May 17, 2000 * Improved chip version recognition 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/README.ymfsb linux.ac/Documentation/sound/README.ymfsb --- linux.vanilla/Documentation/sound/README.ymfsb Thu Jan 1 01:00:00 1970 +++ linux.ac/Documentation/sound/README.ymfsb Sun Jun 4 21:42:08 2000 @@ -0,0 +1,107 @@ +Legacy audio driver for YMF7xx PCI cards. + + +FIRST OF ALL +============ + + This code references YAMAHA's sample codes and data sheets. + I respect and thank for all people they made open the informations + about YMF7xx cards. + + And this codes heavily based on Jeff Garzik 's + old VIA 82Cxxx driver (via82cxxx.c). I also respect him. + + +DISCLIMER +========= + + This driver is currently at early ALPHA stage. It may cause serious + damage to your computer when used. + PLEASE USE IT AT YOUR OWN RISK. + + +ABOUT THIS DRIVER +================= + + This code enables you to use your YMF724[A-F], YMF740[A-C], YMF744, YMF754 + cards. When enabled, your card acts as "SoundBlaster Pro" compatible card. + It can only play 22.05kHz / 8bit / Stereo samples, control external MIDI + port. + If you want to use your card as recent "16-bit" card, you should use + Alsa or OSS/Linux driver. Ofcource you can write native PCI driver for + your cards :) + + +USAGE +===== + + # modprobe ymfsb (options) + + +OPTIONS FOR MODULE +================== + + io : SB base address (0x220, 0x240, 0x260, 0x280) + synth_io : OPL3 base address (0x388, 0x398, 0x3a0, 0x3a8) + dma : DMA number (0,1,3) + master_volume: AC'97 PCM out Vol (0-100) + spdif_out : SPDIF-out flag (0:disable 1:enable) + + These options will change in future... + + +FREQUENCY +========= + + When playing sounds via this driver, you will hear its pitch is slightly + lower than original sounds. Since this driver recognizes your card acts + with 21.739kHz sample rates rather than 22.050kHz (I think it must be + hardware restriction). So many players become tone deafness. + To prevent this, you should express some options to your sound player + that specify correct sample frequency. For example, to play your MP3 file + correctly with mpg123, specify the frequency like following: + + % mpg123 -r 21739 foo.mp3 + + +SPDIF OUT +========= + + With installing modules with option 'spdif_out=1', you can enjoy your + sounds from SPDIF-out of your card (if it had). + Its Fs is fixed to 48kHz (It never means the sample frequency become + up to 48kHz. All sounds via SPDIF-out also 22kHz samples). So your + digital-in capable components has to be able to handle 48kHz Fs. + + +COPYING +======= + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +TODO +==== + * support for multiple cards + (set the different SB_IO,MPU_IO,OPL_IO for each cards) + + * support for OPL (dmfm) : There will be no requirements... :-< + + +AUTHOR +====== + + Daisuke Nagano + 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 Sun Jun 4 22:05:16 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 registered + 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/Documentation/video4linux/bttv/CARDLIST linux.ac/Documentation/video4linux/bttv/CARDLIST --- linux.vanilla/Documentation/video4linux/bttv/CARDLIST Thu May 25 17:38:41 2000 +++ linux.ac/Documentation/video4linux/bttv/CARDLIST Sun Jun 4 21:51:41 2000 @@ -42,6 +42,8 @@ card=40 - STB2 card=41 - AVerMedia TVPhone 98 card=42 - ProVideo PV951 + card=43 - Little OnAir TV + card=44 - Sigma TVII-FM tuner.o type=0 - Temic PAL diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/video4linux/bttv/Insmod-options linux.ac/Documentation/video4linux/bttv/Insmod-options --- linux.vanilla/Documentation/video4linux/bttv/Insmod-options Thu May 25 17:38:41 2000 +++ linux.ac/Documentation/video4linux/bttv/Insmod-options Sun Jun 4 21:51:41 2000 @@ -3,7 +3,7 @@ the bt848 (grabber chip) driver insmod args: - card=n card type, see cardlist for a list. + card=n card type, see CARDLIST for a list. radio=0/1 card supports radio pll=0/1/2 pll settings 0: don't use PLL @@ -31,6 +31,29 @@ remap, card, radio and pll accept up to four comma-separated arguments (for multiple boards). +tuner.o + The tuner driver. You need this unless you want to use only + with a camera or external tuner ... + + insmod args: + debug=1 print some debug info to the syslog + type=n type of the tuner chip. n as follows: + see CARDLIST for a complete list. + +tvmixer.o + registers a mixer device for the TV card's volume/bass/treble + controls (requires a i2c audio control chip like the msp3400). + + insmod args: + debug=1 print some debug info to the syslog. + devnr=n allocate device #n (0 == /dev/mixer, + 1 = /dev/mixer1, ...), default is to + use the first free one. + +tvaudio.o + new, experimental module which is supported to provide a single + driver for all simple i2c audio control chips (tda/tea*). + msp3400.o The driver for the msp34xx sound processor chips. If you have a stereo card, you probably want to insmod this one. @@ -47,8 +70,6 @@ amsound=1 Audio carrier is AM/NICAM at 6.5 Mhz. This should improve things for french people, the carrier autoscan seems to work with FM only... - mixer=n allocate mixer device #n. Default is the - first free slot. tea6300.o The driver for the tea6300 fader chip. If you have a stereo @@ -73,20 +94,3 @@ insmod args: debug=1 print some debug info to the syslog. chip=9850/9855 set the chip type. - -tuner.o - The tuner driver. You need this unless you want to use only - with a camera or external tuner ... - - insmod args: - debug=1 print some debug info to the syslog - type=n type of the tuner chip. n as follows: - 0: Temic PAL tuner - 1: Philips PAL_I tuner - 2: Philips NTSC tuner - 3: Philips SECAM tuner - 4: no tuner - 5: Philips PAL tuner - 6: Temic NTSC tuner - 7: Temic PAL tuner - 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 Sun Jun 4 22:23:29 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: @@ -659,7 +664,8 @@ MISCELLANEOUS MCA-SUPPORT P: David Weinehall -M: tao@acc.umu.se (personal) +M: Project MCA Team +M: David Weinehall W: http://www.acc.umu.se/~tao/ W: http://www.acc.umu.se/~mcalinux/ L: linux-kernel@vger.rutgers.edu @@ -699,12 +705,12 @@ NETFILTER P: Rusty Russell -M: Rusty.Russell@rustcorp.com.au +M: rusty@linuxcare.com P: Marc Boucher M: marc@mbsi.ca W: http://www.samba.org/netfilter/ W: http://netfilter.kernelnotes.org -W: http://antarctica.penguincomputing.com/~netfilter/ +W: http://netfilter.filewatcher.org L: netfilter@lists.samba.org S: Supported @@ -744,8 +750,8 @@ NI5010 NETWORK DRIVER P: Jan-Pascal van Best and Andreas Mohr -M: jvbest@qv3pluto.leidenuniv.nl (Best) -M: 100.30936@germany.net (Mohr) +M: Jan-Pascal van Best +M: Andreas Mohr <100.30936@germany.net> L: linux-net@vger.rutgers.edu S: Maintained @@ -793,12 +799,12 @@ 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 -P: Grant Guenther -M: grant@torque.net +P: Tim Waugh +M: tim@cyberelk.demon.co.uk L: linux-parport@torque.net W: http://www.torque.net/linux-pp.html S: Maintained @@ -1051,6 +1057,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 Sun Jun 4 23:40:44 2000 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -test1 +EXTRAVERSION = -test1-ac8 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/Makefile linux.ac/arch/arm/Makefile --- linux.vanilla/arch/arm/Makefile Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/Makefile Sun Jun 4 21:14:16 2000 @@ -19,7 +19,7 @@ AFLAGS += -mno-fpu CFLAGS_PIPE := -pipe -CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) +CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) -msoft-float ifdef CONFIG_FRAME_POINTER CFLAGS := $(CFLAGS:-fomit-frame-pointer=) @@ -29,11 +29,13 @@ CFLAGS += -g endif +GZFLAGS = -9 + # Ensure this is ld "2.9.4" or later NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi) ifneq ($(NEW_LINKER),y) -dummy:; @echo '*** 2.3 kernels no longer build correctly with old versions of binutils.' +dummy:; @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.' @echo '*** Please upgrade your binutils to 2.9.5.' @false endif @@ -45,7 +47,7 @@ # select flags depending on the compiler # ifeq ($(NEW_GCC),y) -CFLAGS += -mshort-load-bytes -msoft-float +CFLAGS += -mshort-load-bytes CFLAGS_PROC_CPU_26 := -mcpu=arm3 -Os CFLAGS_PROC_CPU_32v3 := -march=armv3 CFLAGS_PROC_CPU_32v4 := -march=armv4 @@ -110,7 +112,7 @@ LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) -export LIBGCC MACHINE PROCESSOR TEXTADDR +export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS ifeq ($(CONFIG_ARCH_A5K),y) MACHINE = a5k diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/Makefile linux.ac/arch/arm/boot/compressed/Makefile --- linux.vanilla/arch/arm/boot/compressed/Makefile Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/boot/compressed/Makefile Sun Jun 4 21:14:16 2000 @@ -89,7 +89,7 @@ piggy.o: $(SYSTEM) $(OBJCOPY) $(SYSTEM) piggy - gzip -9 < piggy > piggy.gz + gzip $(GZFLAGS) < piggy > piggy.gz $(LD) -r -o $@ -b binary piggy.gz rm -f piggy piggy.gz diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/head-sa1100.S linux.ac/arch/arm/boot/compressed/head-sa1100.S --- linux.vanilla/arch/arm/boot/compressed/head-sa1100.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/boot/compressed/head-sa1100.S Sun Jun 4 21:14:16 2000 @@ -133,6 +133,5 @@ #endif @ Restore initial r0/r1 - @ (r8 preserved) mov r0, r8 mov r1, r9 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/head.S linux.ac/arch/arm/boot/compressed/head.S --- linux.vanilla/arch/arm/boot/compressed/head.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/boot/compressed/head.S Sun Jun 4 21:14:16 2000 @@ -178,9 +178,13 @@ .align 5 cache_on: ldr r1, proc_sa110_type eor r1, r1, r6 - movs r1, r1, lsr #5 + movs r1, r1, lsr #5 @ catch SA110 and SA1100 + beq 1f + ldr r1, proc_sa1110_type + eor r1, r1, r6 + movs r1, r1, lsr #4 movne pc, lr - +1: sub r3, r4, #16384 @ Page directory size bic r3, r3, #0xff @ Align the pointer bic r3, r3, #0x3f @@ -259,6 +263,11 @@ .word 0x4401a100 .size proc_sa110_type, . - proc_sa110_type + .type proc_sa1110_type,#object +proc_sa1110_type: + .word 0x6901b110 + .size proc_sa1110_type, . - proc_sa1110_type + /* * Turn off StrongARM cache and MMU. It is safe to * leave the I-cache on. @@ -273,8 +282,13 @@ .align 5 cache_off: ldr r1, proc_sa110_type eor r1, r1, r6 - movs r1, r1, lsr #5 + movs r1, r1, lsr #5 @ catch SA110 and SA1100 + beq 1f + ldr r1, proc_sa1110_type + eor r1, r1, r6 + movs r1, r1, lsr #4 movne pc, lr +1: mrc p15, 0, r0, c1, c0 bic r0, r0, #0x000d mcr p15, 0, r0, c1, c0 @@ -292,11 +306,15 @@ */ .align 5 cache_clean_flush: - ldr r1, proc_sa110_type @ SA-110 or SA-1100? + ldr r1, proc_sa110_type + eor r1, r1, r6 + movs r1, r1, lsr #5 @ catch SA110 and SA1100 + beq 1f + ldr r1, proc_sa1110_type eor r1, r1, r6 - movs r1, r1, lsr #5 + movs r1, r1, lsr #4 movne pc, lr - +1: bic r1, pc, #31 add r2, r1, #32768 1: ldr r12, [r1], #32 @ s/w flush D cache 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 Sun Jun 4 21:14:16 2000 @@ -19,39 +19,43 @@ choice 'ARM system type' \ "Archimedes CONFIG_ARCH_ARC \ A5000 CONFIG_ARCH_A5K \ - RiscPC CONFIG_ARCH_RPC \ EBSA-110 CONFIG_ARCH_EBSA110 \ - FootBridge-based CONFIG_FOOTBRIDGE" RiscPC + FootBridge-based CONFIG_FOOTBRIDGE \ + RiscPC CONFIG_ARCH_RPC \ + SA1100-based CONFIG_ARCH_SA1100" RiscPC # the following are placeholders for when they are fully integrated +# Cirrus CL-PS7500FE CONFIG_ARCH_CLPS7500 \ # LinkUp-L7200 CONFIG_ARCH_L7200 -# SA1100-based CONFIG_ARCH_SA1100 if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then - bool 'FootBridge in HOST mode' CONFIG_HOST_FOOTBRIDGE - if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then - define_bool CONFIG_ADDIN_FOOTBRIDGE n + comment 'Footbridge Implementations' + + bool ' CATS support' CONFIG_ARCH_CATS + bool ' Compaq Personal Server support' CONFIG_ARCH_PERSONAL_SERVER + bool ' EBSA285 (host mode) support' CONFIG_ARCH_EBSA285 + bool ' NetWinder support' CONFIG_ARCH_NETWINDER + + if [ "$CONFIG_ARCH_EBSA285" = "y" -o \ + "$CONFIG_ARCH_CATS" = "y" -o \ + "$CONFIG_ARCH_NETWINDER" = "y" -o \ + "$CONFIG_ARCH_PERSONAL_SERVER" = "y" ]; then + define_bool CONFIG_FOOTBRIDGE_HOST y + define_bool CONFIG_FOOTBRIDGE_ADDIN n else - define_bool CONFIG_ADDIN_FOOTBRIDGE y + define_bool CONFIG_FOOTBRIDGE_HOST n + define_bool CONFIG_FOOTBRIDGE_ADDIN y fi -fi - -if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then - comment 'Footbridge Implementations' - bool ' Include support for EBSA285' CONFIG_ARCH_EBSA285 - bool ' Include support for CATS' CONFIG_ARCH_CATS - bool ' Include support for NetWinder' CONFIG_ARCH_NETWINDER - bool ' Include support for Compaq Personal Server' CONFIG_ARCH_PERSONAL_SERVER -fi -if [ "$CONFIG_ADDIN_FOOTBRIDGE" = "y" ]; then - # If we get any other footbridge-based plug-in boards, then - # add your architecture options here - define_bool CONFIG_ARCH_CO285 y + if [ "$CONFIG_FOOTBRIDGE_ADDIN" = "y" ]; then + # If we get any other footbridge-based plug-in boards, then + # add your architecture options here + define_bool CONFIG_ARCH_CO285 y + fi fi if [ "$CONFIG_ARCH_SA1100" = "y" ]; then comment 'SA11x0 Implementations' - bool ' Include support for Assabet' CONFIG_SA110_ASSABET + bool ' Include support for Assabet' CONFIG_SA1100_ASSABET bool ' Include support for Bitsy' CONFIG_SA1100_BITSY bool ' Include support for Brutus' CONFIG_SA1100_BRUTUS # bool ' Include support for Empeg' CONFIG_SA1100_EMPEG @@ -113,6 +117,10 @@ define_bool CONFIG_CPU_32v4 y define_bool CONFIG_CPU_SA110 y fi +if [ "$CONFIG_ARCH_CLPS7500" = "y" ]; then + define_bool CONFIG_CPU_32v4 y + define_bool CONFIG_CPU_ARM7 y +fi if [ "$CONFIG_ARCH_L7200" = "y" ]; then define_bool CONFIG_CPU_32v4 y define_bool CONFIG_CPU_ARM720 y @@ -126,7 +134,7 @@ # These machines always have PCI # if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \ - "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then + "$CONFIG_FOOTBRIDGE_HOST" = "y" ]; then define_bool CONFIG_PCI y source drivers/pci/Config.in else @@ -189,20 +197,25 @@ "$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 \ "$CONFIG_ARCH_EBSA285" = "y" -o \ - "$CONFIG_ARCH_CO285" = "y" ]; then + "$CONFIG_ARCH_CO285" = "y" -o \ + "$CONFIG_ARCH_SA1100" = "y" ]; then bool 'Timer and CPU usage LEDs' CONFIG_LEDS if [ "$CONFIG_LEDS" = "y" ]; then if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \ "$CONFIG_ARCH_EBSA285" = "y" -o \ - "$CONFIG_ARCH_CO285" = "y" ]; then + "$CONFIG_ARCH_CO285" = "y" -o \ + "$CONFIG_ARCH_SA1100" = "y" ]; then bool ' Timer LED' CONFIG_LEDS_TIMER bool ' CPU usage LED' CONFIG_LEDS_CPU fi + fi + if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then + define_bool CONFIG_LEDS_TIMER y fi fi endmenu 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 Sun Jun 4 21:14:16 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 @@ -216,10 +212,12 @@ # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y # CONFIG_DEVFS_FS is not set @@ -227,11 +225,16 @@ # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_NCPFS_NLS is not set # # Partition Types 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 Sun Jun 4 21:14:16 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 @@ -336,10 +332,12 @@ # CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y # CONFIG_DEVFS_FS is not set @@ -347,23 +345,39 @@ # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # # CONFIG_CODA_FS is not set CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set # # Partition Types 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/arm/kernel/Makefile linux.ac/arch/arm/kernel/Makefile --- linux.vanilla/arch/arm/kernel/Makefile Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/Makefile Sun Jun 4 21:14:16 2000 @@ -17,6 +17,7 @@ O_OBJS_rpc = dma-rpc.o O_OBJS_ebsa110 = dma-dummy.o O_OBJS_footbridge = dma.o dma-footbridge.o $(ISA_DMA_OBJS) hw-footbridge.o isa.o +O_OBJS_clps7500 = dma-dummy.o O_OBJS_nexuspci = dma-dummy.o O_OBJS_sa1100 = dma-dummy.o fiq.o O_OBJS_l7200 = dma-dummy.o fiq.o @@ -25,9 +26,9 @@ # Object file lists. -obj-y := arch.o $(ENTRY_OBJ) ioport.o irq.o process.o ptrace.o \ - semaphore.o setup.o signal.o sys_arm.o time.o traps.o \ - $(O_OBJS_$(MACHINE)) +obj-y := arch.o $(ENTRY_OBJ) irq.o process.o ptrace.o \ + semaphore.o setup.o signal.o sys_arm.o time.o \ + traps.o $(O_OBJS_$(MACHINE)) obj-m := obj-n := obj- := diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/arch.c linux.ac/arch/arm/kernel/arch.c --- linux.vanilla/arch/arm/kernel/arch.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/arch.c Sun Jun 4 21:14:16 2000 @@ -55,6 +55,7 @@ for (i = 0; i < 4; i++) { mi->bank[i].start = PHYS_OFFSET + (i << 26); + mi->bank[i].node = 0; mi->bank[i].size = params->u1.s.pages_in_bank[i] * params->u1.s.page_size; @@ -181,6 +182,7 @@ mi->nr_banks = 1; mi->bank[0].start = PHYS_OFFSET; mi->bank[0].size = boot_memory_end; + mi->bank[0].node = 0; *cmdline = boot_command_line; } @@ -197,7 +199,8 @@ extern void select_sa1100_io_desc(void); #define SET_BANK(__nr,__start,__size) \ mi->bank[__nr].start = (__start), \ - mi->bank[__nr].size = (__size) + mi->bank[__nr].size = (__size), \ + mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27) static void __init fixup_sa1100(struct machine_desc *desc, struct param_struct *params, char **cmdline, struct meminfo *mi) @@ -252,7 +255,7 @@ setup_initrd(0xc0400000, 4*1024*1024); } - else if (machine_is_thinclient()) { + else if (machine_is_thinclient() || machine_is_graphicsclient()) { SET_BANK( 0, 0xc0000000, 16*1024*1024 ); mi->nr_banks = 1; @@ -312,6 +315,12 @@ FIXUP(fixup_sa1100) MACHINE_END #endif +#ifdef CONFIG_SA1100_GRAPHICSCLIENT +MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END +#endif #ifdef CONFIG_SA1100_ITSY MACHINE_START(ITSY, "Compaq Itsy") BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) @@ -349,6 +358,29 @@ FIXUP(fixup_sa1100) MACHINE_END #endif +#endif + +#ifdef CONFIG_ARCH_L7200 + +static void __init +fixup_l7200(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + mi->nr_banks = 1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].size = (32*1024*1024); + mi->bank[0].node = 0; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( __phys_to_virt(0xf1000000), 0x00162b0d); +} + +MACHINE_START(L7200, "LinkUp Systems L7200SDB") + MAINTAINER("Steve Hill") + BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000) + FIXUP(fixup_l7200) +MACHINE_END #endif #ifdef CONFIG_ARCH_EBSA110 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/bios32.c linux.ac/arch/arm/kernel/bios32.c --- linux.vanilla/arch/arm/kernel/bios32.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/bios32.c Sun Jun 4 21:14:16 2000 @@ -21,65 +21,94 @@ extern void hw_init(void); -void pcibios_report_device_errors(int warn) +void pcibios_report_status(u_int status_mask, int warn) { struct pci_dev *dev; pci_for_each_dev(dev) { u16 status; + /* + * ignore host bridge - we handle + * that separately + */ + if (dev->bus->number == 0 && dev->devfn == 0) + continue; + pci_read_config_word(dev, PCI_STATUS, &status); - if ((status & 0xf900) == 0) + status &= status_mask; + if (status == 0) continue; - pci_write_config_word(dev, PCI_STATUS, status & 0xf900); + /* clear the status errors */ + pci_write_config_word(dev, PCI_STATUS, status); if (warn) - printk(KERN_DEBUG "PCI: %02X:%02X: status %04X " - "on %s\n", dev->bus->number, dev->devfn, - status, dev->name); + printk("(%02x:%02x.%d: %04X) ", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + status); } } /* * We don't use this to fix the device, but initialisation of it. - * It's not the correct use for this, but it works. The actions we - * take are: - * - enable only IO - * - set memory region to start at zero - * - (0x48) enable all memory requests from ISA to be channeled to PCI - * - (0x42) disable ping-pong (as per errata) - * - (0x40) enable PCI packet retry + * It's not the correct use for this, but it works. + * Note that the arbiter/ISA bridge appears to be buggy, specifically in + * the following area: + * 1. park on CPU + * 2. ISA bridge ping-pong + * 3. ISA bridge master handling of target RETRY + * + * Bug 3 is responsible for the sound DMA grinding to a halt. We now + * live with bug 2. */ static void __init pci_fixup_83c553(struct pci_dev *dev) { + /* + * Set memory region to start at address 0, and enable IO + */ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE_MEMORY); pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO); dev->resource[0].end -= dev->resource[0].start; dev->resource[0].start = 0; + /* + * All memory requests from ISA to be channelled to PCI + */ pci_write_config_byte(dev, 0x48, 0xff); - pci_write_config_byte(dev, 0x42, 0x00); + + /* + * Enable ping-pong on bus master to ISA bridge transactions. + * This improves the sound DMA substantially. The fixed + * priority arbiter also helps (see below). + */ + pci_write_config_byte(dev, 0x42, 0x01); + + /* + * Enable PCI retry + */ pci_write_config_byte(dev, 0x40, 0x22); /* - * We used to set the arbiter to "park on last master" - * (bit 1 set), but unfortunately the CyberPro does not - * park the bus. We must therefore park on CPU. + * We used to set the arbiter to "park on last master" (bit + * 1 set), but unfortunately the CyberPro does not park the + * bus. We must therefore park on CPU. Unfortunately, this + * may trigger yet another bug in the 553. */ - pci_write_config_byte(dev, 0x83, 0x00); + pci_write_config_byte(dev, 0x83, 0x02); /* - * Rotate priorities of each PCI request + * Make the ISA DMA request lowest priority, and disable + * rotating priorities completely. */ - pci_write_config_byte(dev, 0x80, 0xe0); - pci_write_config_byte(dev, 0x81, 0x01); + pci_write_config_byte(dev, 0x80, 0x11); + pci_write_config_byte(dev, 0x81, 0x00); /* - * Route INTA input to IRQ 11, and set - * IRQ11 to be level sensitive. + * Route INTA input to IRQ 11, and set IRQ11 to be level + * sensitive. */ pci_write_config_word(dev, 0x44, 0xb000); outb(0x08, 0x4d1); @@ -193,8 +222,8 @@ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -/* - * Called after each bus is probed, but before its children +/** + * pcibios_fixup_bus - Called after each bus is probed, but before its children * are examined. */ void __init pcibios_fixup_bus(struct pci_bus *bus) @@ -209,6 +238,8 @@ else BUG(); + busdata->max_lat = 255; + /* * Walk the devices on this bus, working out what we can * and can't support. @@ -216,6 +247,7 @@ for (walk = walk->next; walk != &bus->devices; walk = walk->next) { struct pci_dev *dev = pci_dev_b(walk); u16 status; + u8 max_lat, min_gnt; pci_read_config_word(dev, PCI_STATUS, &status); @@ -227,6 +259,17 @@ busdata->features &= ~PCI_COMMAND_FAST_BACK; /* + * If we encounter a CyberPro 2000, then we disable + * SERR and PERR reporting - this chip doesn't drive the + * parity line correctly. + */ +#if 1 /* !testing */ + if (dev->vendor == PCI_VENDOR_ID_INTERG && + dev->device == PCI_DEVICE_ID_INTERG_2000) + busdata->features &= ~(PCI_COMMAND_SERR | + PCI_COMMAND_PARITY); +#endif + /* * Calculate the maximum devsel latency. */ if (busdata->maxdevsel < (status & PCI_STATUS_DEVSEL_MASK)) @@ -240,6 +283,16 @@ if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA || dev->class >> 8 == PCI_CLASS_BRIDGE_EISA) have_isa_bridge = !0; + + /* + * Calculate the maximum latency on this bus. Note + * that we ignore any device which reports its max + * latency is the same as its use. + */ + pci_read_config_byte(dev, PCI_MAX_LAT, &max_lat); + pci_read_config_byte(dev, PCI_MIN_GNT, &min_gnt); + if (max_lat && max_lat != min_gnt && max_lat < busdata->max_lat) + busdata->max_lat = max_lat; } /* @@ -249,6 +302,7 @@ for (walk = walk->next; walk != &bus->devices; walk = walk->next) { struct pci_dev *dev = pci_dev_b(walk); u16 cmd; + u8 min_gnt, latency; /* * architecture specific hacks. I don't really want @@ -263,11 +317,27 @@ pci_write_config_dword(dev, 0x40, 0x80000000); /* - * Set latency timer to 32, and a cache line size to 32 bytes. + * Calculate this masters latency timer value. + * This is rather primitive - it does not take + * account of the number of masters in a system + * wanting to use the bus. + */ + pci_read_config_byte(dev, PCI_MIN_GNT, &min_gnt); + if (min_gnt) { + if (min_gnt > busdata->max_lat) + min_gnt = busdata->max_lat; + + latency = (int)min_gnt * 25 / 3; + } else + latency = 32; /* 1us */ + + pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency); + + /* + * Set the cache line size to 32 bytes. * Also, set system error enable, parity error enable. * Disable ROM. */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32); pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8); pci_read_config_word(dev, PCI_COMMAND, &cmd); @@ -520,15 +590,6 @@ pci_assign_unassigned_resources(); pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq); pci_set_bus_ranges(); - -#ifdef CONFIG_FOOTBRIDGE - /* - * Initialise any other hardware after we've got the PCI bus - * initialised. We may need the PCI bus to talk to this other - * hardware. - */ - hw_init(); -#endif } char * __init pcibios_setup(char *str) @@ -544,10 +605,18 @@ { } +/** + * pcibios_set_master - Setup device for bus mastering. + * @dev: PCI device to be setup + */ void pcibios_set_master(struct pci_dev *dev) { } +/** + * pcibios_enable_device - Enable I/O and memory. + * @dev: PCI device to be enabled + */ int pcibios_enable_device(struct pci_dev *dev) { u16 cmd, old_cmd; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/bios32.h linux.ac/arch/arm/kernel/bios32.h --- linux.vanilla/arch/arm/kernel/bios32.h Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/bios32.h Sun Jun 4 21:14:16 2000 @@ -10,6 +10,11 @@ * Maximum devsel for this bus. */ u16 maxdevsel; + /* + * The maximum latency that devices on this + * bus can withstand. + */ + u8 max_lat; }; struct arm_pci_sysdata { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/calls.S linux.ac/arch/arm/kernel/calls.S --- linux.vanilla/arch/arm/kernel/calls.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/calls.S Sun Jun 4 21:14:16 2000 @@ -119,7 +119,7 @@ .long SYMBOL_NAME(sys_newlstat) .long SYMBOL_NAME(sys_newfstat) .long SYMBOL_NAME(sys_ni_syscall) /* was sys_uname */ -/* 110 */ .long SYMBOL_NAME(sys_iopl) +/* 110 */ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_iopl */ .long SYMBOL_NAME(sys_vhangup) .long SYMBOL_NAME(sys_ni_syscall) .long SYMBOL_NAME(sys_syscall) /* call a syscall */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/debug-armv.S linux.ac/arch/arm/kernel/debug-armv.S --- linux.vanilla/arch/arm/kernel/debug-armv.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/debug-armv.S Sun Jun 4 21:14:16 2000 @@ -64,7 +64,7 @@ beq 1001b .endm -#elif defined(CONFIG_HOST_FOOTBRIDGE) || defined(CONFIG_ADDIN_FOOTBRIDGE) +#elif defined(CONFIG_FOOTBRIDGE) #ifndef CONFIG_DEBUG_DC21285_PORT /* For NetWinder debugging */ .macro addruart,rx diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/dec21285.c linux.ac/arch/arm/kernel/dec21285.c --- linux.vanilla/arch/arm/kernel/dec21285.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/dec21285.c Sun Jun 4 21:14:16 2000 @@ -1,7 +1,7 @@ /* * arch/arm/kernel/dec21285.c: PCI functions for DC21285 * - * Copyright (C) 1998-1999 Russell King, Phil Blundell + * Copyright (C) 1998-2000 Russell King, Phil Blundell */ #include #include @@ -23,7 +23,7 @@ #define MAX_SLOTS 21 extern int setup_arm_irq(int, struct irqaction *); -extern void pcibios_report_device_errors(int warn); +extern void pcibios_report_status(u_int status_mask, int warn); static unsigned long dc21285_base_address(struct pci_dev *dev) @@ -145,76 +145,112 @@ dc21285_write_config_dword, }; +static struct timer_list serr_timer; +static struct timer_list perr_timer; + +static void dc21285_enable_error(unsigned long __data) +{ + switch (__data) { + case IRQ_PCI_SERR: + del_timer(&serr_timer); + break; + + case IRQ_PCI_PERR: + del_timer(&perr_timer); + break; + } + + enable_irq(__data); +} + /* * Warn on PCI errors. */ -static void -dc21285_error(int irq, void *dev_id, struct pt_regs *regs) +static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs) { - static unsigned long next_warn; - unsigned long cmd = *CSR_PCICMD & 0x0000ffff; - unsigned long ctrl = (*CSR_SA110_CNTL) & 0xffffde07; - unsigned long irqstatus = *CSR_IRQ_RAWSTATUS; - int warn = time_after_eq(jiffies, next_warn); - - if (machine_is_netwinder()) - warn = 0; - - ctrl |= SA110_CNTL_DISCARDTIMER; - - if (warn) { - next_warn = jiffies + HZ; - printk(KERN_DEBUG "PCI: "); - } + unsigned int cmd; + unsigned int status; - if (irqstatus & (1 << 31)) { - if (warn) - printk("parity error "); - cmd |= 1 << 31; - } + cmd = *CSR_PCICMD; + status = cmd >> 16; + cmd = cmd & 0xffff; + + if (status & PCI_STATUS_REC_MASTER_ABORT) { + printk(KERN_DEBUG "PCI: master abort: "); + pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT, 1); + printk("\n"); - if (irqstatus & (1 << 30)) { - if (warn) - printk("target abort "); - cmd |= 1 << 28; + cmd |= PCI_STATUS_REC_MASTER_ABORT << 16; } - if (irqstatus & (1 << 29)) { - if (warn) - printk("master abort "); - cmd |= 1 << 29; - } + if (status & PCI_STATUS_REC_TARGET_ABORT) { + printk(KERN_DEBUG "PCI: target abort: "); + pcibios_report_status(PCI_STATUS_SIG_TARGET_ABORT, 1); + printk("\n"); - if (irqstatus & (1 << 28)) { - if (warn) - printk("data parity error "); - cmd |= 1 << 24; + cmd |= PCI_STATUS_REC_TARGET_ABORT << 16; } - if (irqstatus & (1 << 27)) { - if (warn) - printk("discard timer expired "); - ctrl &= ~SA110_CNTL_DISCARDTIMER; - } + *CSR_PCICMD = cmd; +} - if (irqstatus & (1 << 23)) { - if (warn) - printk("system error "); - ctrl |= SA110_CNTL_RXSERR; - } +static void dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct timer_list *timer = dev_id; + unsigned int cntl; - if (warn) - printk("pc=[<%08lX>]\n", instruction_pointer(regs)); + printk(KERN_DEBUG "PCI: system error received: "); + pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1); + printk("\n"); - pcibios_report_device_errors(warn); + cntl = *CSR_SA110_CNTL & 0xffffdf07; + *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR; - *CSR_PCICMD = cmd; - *CSR_SA110_CNTL = ctrl; + /* + * back off this interrupt + */ + disable_irq(irq); + timer->expires = jiffies + HZ; + add_timer(timer); } -static struct irqaction dc21285_error_action = { - dc21285_error, SA_INTERRUPT, 0, "PCI error", NULL, NULL -}; +static void dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + printk(KERN_DEBUG "PCI: discard timer expired\n"); + *CSR_SA110_CNTL &= 0xffffde07; +} + +static void dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int cmd; + + printk(KERN_DEBUG "PCI: data parity error detected: "); + pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1); + printk("\n"); + + cmd = *CSR_PCICMD & 0xffff; + *CSR_PCICMD = cmd | 1 << 24; +} + +static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct timer_list *timer = dev_id; + unsigned int cmd; + + printk(KERN_DEBUG "PCI: parity error detected: "); + pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1); + printk("\n"); + + cmd = *CSR_PCICMD & 0xffff; + *CSR_PCICMD = cmd | 1 << 31; + + /* + * back off this interrupt + */ + disable_irq(irq); + timer->expires = jiffies + HZ; + add_timer(timer); +} void __init dc21285_init(void) { @@ -233,32 +269,31 @@ *CSR_CSRBASEOFFSET = 0; *CSR_PCIADDR_EXTN = 0; -#ifdef CONFIG_HOST_FOOTBRIDGE - - csrio.flags = IORESOURCE_IO; - csrio.name = "DC21285"; - csrmem.flags = IORESOURCE_MEM; - csrmem.name = "DC21285"; - - allocate_resource(&ioport_resource, &csrio, 128, - 0xff00, 0xffff, 128, NULL, NULL); - allocate_resource(&iomem_resource, &csrmem, 128, - 0xf4000000, 0xf8000000, 128, NULL, NULL); - - /* - * Map our SDRAM at a known address in PCI space, just in case - * the firmware had other ideas. Using a nonzero base is - * necessary, since some VGA cards forcefully use PCI addresses - * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards). - */ - *CSR_PCICACHELINESIZE = 0x00002008; - *CSR_PCICSRBASE = csrmem.start; - *CSR_PCICSRIOBASE = csrio.start; - *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET); - *CSR_PCIROMBASE = 0; - *CSR_PCICMD = pci_cmd | + if (footbridge_cfn_mode()) { + csrio.flags = IORESOURCE_IO; + csrio.name = "DC21285"; + csrmem.flags = IORESOURCE_MEM; + csrmem.name = "DC21285"; + + allocate_resource(&ioport_resource, &csrio, 128, + 0xff00, 0xffff, 128, NULL, NULL); + allocate_resource(&iomem_resource, &csrmem, 128, + 0xf4000000, 0xf8000000, 128, NULL, NULL); + + /* + * Map our SDRAM at a known address in PCI space, just in case + * the firmware had other ideas. Using a nonzero base is + * necessary, since some VGA cards forcefully use PCI addresses + * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards). + */ + *CSR_PCICACHELINESIZE = 0x00002008; + *CSR_PCICSRBASE = csrmem.start; + *CSR_PCICSRIOBASE = csrio.start; + *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET); + *CSR_PCIROMBASE = 0; + *CSR_PCICMD = pci_cmd | (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24); -#endif + } printk(KERN_DEBUG "PCI: DC21285 footbridge, revision %02lX\n", *CSR_CLASSREV & 0xff); @@ -288,5 +323,20 @@ /* * Initialise PCI error IRQ after we've finished probing */ - setup_arm_irq(IRQ_PCI_ERR, &dc21285_error_action); + request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, SA_INTERRUPT, "PCI abort", NULL); + request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT, "Discard timer", NULL); + request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, SA_INTERRUPT, "PCI data parity", NULL); + + init_timer(&serr_timer); + init_timer(&perr_timer); + + serr_timer.data = IRQ_PCI_SERR; + serr_timer.function = dc21285_enable_error; + perr_timer.data = IRQ_PCI_PERR; + perr_timer.function = dc21285_enable_error; + + request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT, + "PCI system error", &serr_timer); + request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT, + "PCI parity error", &perr_timer); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/dma-a5k.c linux.ac/arch/arm/kernel/dma-a5k.c --- linux.vanilla/arch/arm/kernel/dma-a5k.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/dma-a5k.c Sun Jun 4 21:14:16 2000 @@ -15,7 +15,9 @@ #include "dma.h" -static struct fiq_handler fh = { NULL, "floppydma", NULL, NULL }; +static struct fiq_handler fh = { + name: "floppydma" +}; int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_id) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/dma-rpc.c linux.ac/arch/arm/kernel/dma-rpc.c --- linux.vanilla/arch/arm/kernel/dma-rpc.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/dma-rpc.c Sun Jun 4 21:14:16 2000 @@ -20,7 +20,9 @@ #include "dma.h" -static struct fiq_handler fh = { NULL, "floppydma", NULL, NULL }; +static struct fiq_handler fh = { + name: "floppydma" +}; #if 0 typedef enum { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/ecard.c linux.ac/arch/arm/kernel/ecard.c --- linux.vanilla/arch/arm/kernel/ecard.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/ecard.c Sun Jun 4 21:14:16 2000 @@ -52,6 +52,10 @@ #define oldlatch_init() #endif +#ifndef CONFIG_ARCH_RPC +#define HAVE_EXPMASK +#endif + enum req { req_readbytes, req_reset diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/entry-armv.S linux.ac/arch/arm/kernel/entry-armv.S --- linux.vanilla/arch/arm/kernel/entry-armv.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/entry-armv.S Sun Jun 4 21:14:16 2000 @@ -233,14 +233,12 @@ .macro irq_prio_table .endm -#elif defined(CONFIG_HOST_FOOTBRIDGE) || defined(CONFIG_ADDIN_FOOTBRIDGE) +#elif defined(CONFIG_FOOTBRIDGE) #include .macro disable_fiq .endm - .equ irq_mask_pci_err_high, IRQ_MASK_PCI_ERR & 0xff000000 - .equ irq_mask_pci_err_low, IRQ_MASK_PCI_ERR & 0x00ffffff .equ dc21285_high, ARMCSR_BASE & 0xff000000 .equ dc21285_low, ARMCSR_BASE & 0x00ffffff @@ -311,10 +309,24 @@ movne \irqnr, #IRQ_CONTX bne 1001f - tst \irqstat, #irq_mask_pci_err_high - tsteq \irqstat, #irq_mask_pci_err_low - movne \irqnr, #IRQ_PCI_ERR + tst \irqstat, #IRQ_MASK_PCI_ABORT + movne \irqnr, #IRQ_PCI_ABORT bne 1001f + + tst \irqstat, #IRQ_MASK_PCI_SERR + movne \irqnr, #IRQ_PCI_SERR + bne 1001f + + tst \irqstat, #IRQ_MASK_DISCARD_TIMER + movne \irqnr, #IRQ_DISCARD_TIMER + bne 1001f + + tst \irqstat, #IRQ_MASK_PCI_DPERR + movne \irqnr, #IRQ_PCI_DPERR + bne 1001f + + tst \irqstat, #IRQ_MASK_PCI_PERR + movne \irqnr, #IRQ_PCI_PERR 1001: .endm @@ -441,7 +453,8 @@ .macro restore_user_regs ldr r0, [sp, #S_PSR] @ Get calling cpsr - msr cpsr_c, #I_BIT | MODE_SVC @ disable IRQs + mov ip, #I_BIT | MODE_SVC + msr cpsr_c, ip @ disable IRQs msr spsr, r0 @ save in spsr_svc ldmia sp, {r0 - lr}^ @ Get calling r0 - lr mov r0, r0 @@ -592,9 +605,10 @@ bl cpu_data_abort #endif msr cpsr_c, r9 - mov r3, sp + mov r2, sp bl SYMBOL_NAME(do_DataAbort) - msr cpsr_c, #I_BIT | MODE_SVC + mov r0, #I_BIT | MODE_SVC + msr cpsr_c, r0 ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr @@ -636,7 +650,8 @@ mov r1, sp @ struct pt_regs *regs bl SYMBOL_NAME(do_undefinstr) -1: msr cpsr_c, #I_BIT | MODE_SVC +1: mov r0, #I_BIT | MODE_SVC + msr cpsr_c, r0 ldr lr, [sp, #S_PSR] @ Get SVC cpsr msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore SVC registers @@ -675,8 +690,9 @@ #else bl cpu_data_abort #endif - msr cpsr_c, #MODE_SVC @ Enable interrupts - mov r3, sp + mov r2, #MODE_SVC + msr cpsr_c, r2 @ Enable interrupts + mov r2, sp adrsvc al, lr, ret_from_sys_call b SYMBOL_NAME(do_DataAbort) @@ -720,9 +736,10 @@ add r10, r10, #TSS_FPESAVE @ r10 = workspace ldr pc, [r4] @ Call FP module USR entry point -fpundefinstr: mov r0, lr +fpundefinstr: mov r0, #MODE_SVC + msr cpsr_c, r0 @ Enable interrupts + mov r0, lr mov r1, sp - msr cpsr_c, #MODE_SVC @ Enable interrupts adrsvc al, lr, ret_from_sys_call b SYMBOL_NAME(do_undefinstr) @@ -736,7 +753,8 @@ stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr alignment_trap r4, r7, __temp_abt zero_fp - msr cpsr_c, #MODE_SVC @ Enable interrupts + mov r0, #MODE_SVC + msr cpsr_c, r0 @ Enable interrupts mov r0, r5 @ address (pc) mov r1, sp @ regs bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler @@ -816,7 +834,8 @@ @ @ now branch to the relevent MODE handling routine @ - msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode + mov r13, #I_BIT | MODE_SVC + msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 ldr lr, [pc, lr, lsl #2] @@ -856,7 +875,8 @@ @ @ now branch to the relevent MODE handling routine @ - msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode + mov r13, #I_BIT | MODE_SVC + msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 ldr lr, [pc, lr, lsl #2] @@ -897,7 +917,8 @@ @ @ now branch to the relevent MODE handling routine @ - msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode + mov r13, #I_BIT | MODE_SVC + msr spsr_c, r13 @ switch to SVC_32 mode ands lr, lr, #15 ldreq lr, .LCtab_pabt @@ -924,7 +945,8 @@ @ @ now branch to the relevent MODE handling routine @ - msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode + mov r13, #I_BIT | MODE_SVC + msr spsr_c, r13 @ switch to SVC_32 mode and lr, lr, #15 ldr lr, [pc, lr, lsl #2] diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/hw-footbridge.c linux.ac/arch/arm/kernel/hw-footbridge.c --- linux.vanilla/arch/arm/kernel/hw-footbridge.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/hw-footbridge.c Sun Jun 4 21:14:16 2000 @@ -662,7 +662,12 @@ #endif -void __init hw_init(void) +/* + * Initialise any other hardware after we've got the PCI bus + * initialised. We may need the PCI bus to talk to this other + * hardware. + */ +static int __init hw_init(void) { extern void register_isa_ports(unsigned int, unsigned int, unsigned int); @@ -702,6 +707,7 @@ if (machine_is_cats()) cats_hw_init(); #endif - - leds_event(led_start); + return 0; } + +__initcall(hw_init); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/ioport.c linux.ac/arch/arm/kernel/ioport.c --- linux.vanilla/arch/arm/kernel/ioport.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/ioport.c Thu Jan 1 01:00:00 1970 @@ -1,36 +0,0 @@ -/* - * linux/arch/arm/kernel/ioport.c - * - * IO permission support for ARM. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef CONFIG_CPU_32 -asmlinkage int sys_iopl(unsigned long turn_on) -{ - if (turn_on && !capable(CAP_SYS_RAWIO)) - return -EPERM; - - /* - * We only support an on_off approach - */ - modify_domain(DOMAIN_IO, turn_on ? DOMAIN_MANAGER : DOMAIN_CLIENT); - - return 0; -} -#else -asmlinkage int sys_iopl(unsigned long turn_on) -{ - return -ENOSYS; -} -#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/irq.c linux.ac/arch/arm/kernel/irq.c --- linux.vanilla/arch/arm/kernel/irq.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/irq.c Sun Jun 4 21:14:16 2000 @@ -15,7 +15,7 @@ * IRQ's are in fact implemented a bit like signal handlers for the kernel. * Naturally it's not a 1:1 relation, but there are similarities. */ -#include /* for CONFIG_DEBUG_ERRORS */ +#include #include #include #include @@ -33,13 +33,6 @@ #include #include -#ifndef SMP -#define irq_enter(cpu, irq) (++local_irq_count[cpu]) -#define irq_exit(cpu, irq) (--local_irq_count[cpu]) -#else -#error SMP not supported -#endif - #ifndef cliIF #define cliIF() #endif @@ -85,6 +78,7 @@ }; static struct irqdesc irq_desc[NR_IRQS]; +static volatile unsigned long irq_err_count; /* * Get architecture specific interrupt handlers @@ -133,8 +127,8 @@ action = irq_desc[i].action; if (!action) continue; - p += sprintf(p, "%3d: %10u %s", - i, kstat_irqs(i), action->name); + p += sprintf(p, "%3d: %10u ", i, kstat_irqs(i)); + p += sprintf(p, " %s", action->name); for (action = action->next; action; action = action->next) { p += sprintf(p, ", %s", action->name); } @@ -144,6 +138,7 @@ #ifdef CONFIG_ARCH_ACORN p += get_fiq_list(p); #endif + p += sprintf(p, "Err: %10lu\n", irq_err_count); return p - buf; } @@ -181,10 +176,17 @@ { struct irqdesc * desc; struct irqaction * action; - int status, cpu; + int cpu; irq = fixup_irq(irq); + /* + * Some hardware gives randomly wrong interrupts. Rather + * than crashing, do something sensible. + */ + if (irq >= NR_IRQS) + goto bad_irq; + desc = irq_desc + irq; spin_lock(&irq_controller_lock); @@ -197,10 +199,11 @@ desc->triggered = 1; /* Return with this interrupt masked if no action */ - status = 0; action = desc->action; if (action) { + int status = 0; + if (desc->nomask) { spin_lock(&irq_controller_lock); desc->unmask(irq); @@ -237,9 +240,15 @@ if (softirq_state[cpu].active & softirq_state[cpu].mask) do_softirq(); + return; + +bad_irq: + irq_err_count += 1; + printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); + return; } -#if defined(CONFIG_ARCH_ACORN) +#ifdef CONFIG_ARCH_ACORN void do_ecard_IRQ(int irq, struct pt_regs *regs) { struct irqdesc * desc; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/leds-footbridge.c linux.ac/arch/arm/kernel/leds-footbridge.c --- linux.vanilla/arch/arm/kernel/leds-footbridge.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/leds-footbridge.c Sun Jun 4 21:14:16 2000 @@ -46,7 +46,7 @@ switch (evt) { case led_start: hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN; -#ifndef CONFIG_LEDS_IDLE +#ifndef CONFIG_LEDS_CPU hw_led_state |= XBUS_LED_AMBER; #endif led_state |= LED_STATE_ENABLED; @@ -223,11 +223,12 @@ { } -static void __init -init_leds_event(led_event_t evt) -{ - leds_event = dummy_leds_event; +void (*leds_event)(led_event_t) = dummy_leds_event; + +EXPORT_SYMBOL(leds_event); +static int __init leds_init(void) +{ #ifdef CONFIG_FOOTBRIDGE if (machine_is_ebsa285() || machine_is_co285()) leds_event = ebsa285_leds_event; @@ -237,9 +238,9 @@ leds_event = netwinder_leds_event; #endif - leds_event(evt); -} + leds_event(led_start); -void (*leds_event)(led_event_t) = init_leds_event; + return 0; +} -EXPORT_SYMBOL(leds_event); +__initcall(leds_init); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/leds-sa1100.c linux.ac/arch/arm/kernel/leds-sa1100.c --- linux.vanilla/arch/arm/kernel/leds-sa1100.c Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/arm/kernel/leds-sa1100.c Sun Jun 4 21:14:16 2000 @@ -0,0 +1,333 @@ +/* + * linux/arch/arm/kernel/leds-sa1100.c + * + * Copyright (C) 2000 John Dorsey + * + * Original (leds-footbridge.c) by Russell King + * + * Added Brutus LEDs support + * Nicolas Pitre, Mar 19, 2000 + * + * Added LART LED support + * Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000 + * + * + * Assabet uses the LEDs as follows: + * - Green - toggles state every 50 timer interrupts + * - Red - on if system is not idle + * + * Brutus uses the LEDs as follows: + * - D3 (Green, GPIO9) - toggles state every 50 timer interrupts + * - D17 (Red, GPIO20) - on if system is not idle + * - D4 (Green, GPIO8) - misc function + * + * LART uses the LED as follows: + * - GPIO23 is the LED, on if system is not idle + * You can use both CONFIG_LEDS_CPU and CONFIG_LEDS_TIMER at the same + * time, but in that case the timer events will still dictate the + * pace of the LED. + * + */ +#include +#include +#include +#include +#include + +#include +#include +#include + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + + +#ifdef CONFIG_SA1100_ASSABET + +#define BCR_LED_MASK (BCR_LED_GREEN | BCR_LED_RED) + +static void assabet_leds_event(led_event_t evt) +{ + unsigned long flags; + + save_flags_cli(flags); + + switch (evt) { + case led_start: + hw_led_state = BCR_LED_RED | BCR_LED_GREEN; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = BCR_LED_RED | BCR_LED_GREEN; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = BCR_LED_RED | BCR_LED_GREEN; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= BCR_LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= BCR_LED_RED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~BCR_LED_RED; + break; +#endif + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~BCR_LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= BCR_LED_GREEN; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~BCR_LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= BCR_LED_RED; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + BCR = BCR_value = (BCR_value & ~BCR_LED_MASK) | hw_led_state; + + restore_flags(flags); +} + +#endif /* CONFIG_SA1100_ASSABET */ + +#ifdef CONFIG_SA1100_BRUTUS + +#define LED_D3 GPIO_GPIO(9) +#define LED_D4 GPIO_GPIO(8) +#define LED_D17 GPIO_GPIO(20) +#define LED_MASK (LED_D3|LED_D4|LED_D17) + +static void brutus_leds_event(led_event_t evt) +{ + unsigned long flags; + + save_flags_cli(flags); + + switch (evt) { + case led_start: + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_D3; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_D17; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_D17; + break; +#endif + + case led_green_on: + hw_led_state &= ~LED_D4; + break; + + case led_green_off: + hw_led_state |= LED_D4; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_D17; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_D17; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + restore_flags(flags); +} + +#endif /* CONFIG_SA1100_BRUTUS */ + +#ifdef CONFIG_SA1100_LART + +#define LED_23 GPIO_GPIO23 +#define LED_MASK (LED_23) + + +static void lart_leds_event(led_event_t evt) +{ + unsigned long flags; + + save_flags_cli(flags); + + switch(evt) { + case led_start: + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_23; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + /* The LART people like the LED to be off when the + system is idle... */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_23; + break; + + case led_idle_end: + /* ... and on if the system is not idle */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_23; + break; +#endif + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_23; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_23; + break; + + default: + break; + } + + /* Now set the GPIO state, or nothing will happen at all */ + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + restore_flags(flags); +} + +#endif /* CONFIG_SA1100_LART */ + +static void dummy_leds_event(led_event_t evt) +{ +} + +void (*leds_event)(led_event_t) = dummy_leds_event; + +EXPORT_SYMBOL(leds_event); + +static int __init +sa1100_leds_init(void) +{ +#ifdef CONFIG_SA1100_ASSABET + if (machine_is_assabet()) + leds_event = assabet_leds_event; +#endif +#ifdef CONFIG_SA1100_BRUTUS + if (machine_is_brutus()) + leds_event = brutus_leds_event; +#endif +#ifdef CONFIG_SA1100_LART + if (machine_is_lart()) + leds_event = lart_leds_event; +#endif + + leds_event(led_start); + return 0; +} + +__initcall(sa1100_leds_init); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/process.c linux.ac/arch/arm/kernel/process.c --- linux.vanilla/arch/arm/kernel/process.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/process.c Sun Jun 4 21:14:16 2000 @@ -353,10 +353,12 @@ pid_t __ret; __asm__ __volatile__( - "mov r0, %1 @ kernel_thread sys_clone\n" -" mov r1, #0\n" - __syscall(clone)"\n" -" mov %0, r0" + "mov r0, %1 @ kernel_thread sys_clone + mov r1, #0 + "__syscall(clone)" + teq r0, #0 @ if we are the child + moveq fp, #0 @ ensure that fp is zero + mov %0, r0" : "=r" (__ret) : "Ir" (flags | CLONE_VM) : "r0", "r1"); if (__ret == 0) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/semaphore.c linux.ac/arch/arm/kernel/semaphore.c --- linux.vanilla/arch/arm/kernel/semaphore.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/semaphore.c Sun Jun 4 21:14:16 2000 @@ -290,68 +290,95 @@ * need to convert that sequence back into the C sequence when * there is contention on the semaphore. * - * r0 contains the semaphore pointer on entry. Save the C-clobbered - * registers (r0 to r3, ip and lr) except r0 in the cases where it - * is used as a return value.. + * ip contains the semaphore pointer on entry. Save the C-clobbered + * registers (r0 to r3 and lr), but not ip, as we use it as a return + * value in some cases.. */ asm(" .section .text.lock, \"ax\" .align 5 .globl __down_failed __down_failed: - stmfd sp!, {r0 - r3, ip, lr} + stmfd sp!, {r0 - r3, lr} + mov r0, ip bl __down - ldmfd sp!, {r0 - r3, ip, pc} + ldmfd sp!, {r0 - r3, pc} .align 5 .globl __down_interruptible_failed __down_interruptible_failed: - stmfd sp!, {r1 - r3, ip, lr} + stmfd sp!, {r0 - r3, lr} + mov r0, ip bl __down_interruptible - ldmfd sp!, {r1 - r3, ip, pc} + mov ip, r0 + ldmfd sp!, {r0 - r3, pc} .align 5 .globl __down_trylock_failed __down_trylock_failed: - stmfd sp!, {r1 - r3, ip, lr} + stmfd sp!, {r0 - r3, lr} + mov r0, ip bl __down_trylock - ldmfd sp!, {r1 - r3, ip, pc} + mov ip, r0 + ldmfd sp!, {r0 - r3, pc} .align 5 .globl __up_wakeup __up_wakeup: - stmfd sp!, {r0 - r3, ip, lr} + stmfd sp!, {r0 - r3, lr} + mov r0, ip bl __up - ldmfd sp!, {r0 - r3, ip, pc} + ldmfd sp!, {r0 - r3, pc} .align 5 .globl __down_read_failed __down_read_failed: - stmfd sp!, {r0 - r3, ip, lr} + stmfd sp!, {r0 - r3, lr} + mov r0, ip bcc 1f - bl down_read_failed_biased - ldmfd sp!, {r0 - r3, ip, pc} -1: bl down_read_failed - /***/ +1: bl down_read_failed_biased + ldmfd sp!, {r0 - r3, pc} +2: bl down_read_failed + mrs r1, cpsr + orr r2, r1, #128 + msr cpsr_c, r2 + ldr r3, [r0] + subs r3, r3, #1 + str r3, [r0] + msr cpsr_c, r1 + ldmplfd sp!, {r0 - r3, pc} + bcc 2b + b 1b .align 5 .globl __down_write_failed __down_write_failed: - stmfd sp!, {r0 - r3, ip, lr} + stmfd sp!, {r0 - r3, lr} + mov r0, ip bcc 1f - bl down_write_failed_biased - ldmfd sp!, {r0 - r3, ip, pc} -1: bl down_write_failed - /***/ +1: bl down_write_failed_biased + ldmfd sp!, {r0 - r3, pc} +2: bl down_write_failed + mrs r1, cpsr + orr r2, r1, #128 + msr cpsr_c, r2 + ldr r3, [r0] + subs r3, r3, #"RW_LOCK_BIAS_STR" + str r3, [r0] + msr cpsr_c, r1 + ldmeqfd sp!, {r0 - r3, pc} + bcc 2b + b 1b .align 5 .globl __rwsem_wake __rwsem_wake: - stmfd sp!, {r0 - r3, ip, lr} + stmfd sp!, {r0 - r3, lr} + mov r0, ip beq 1f bl rwsem_wake_readers - ldmfd sp!, {r0 - r3, ip, pc} + ldmfd sp!, {r0 - r3, pc} 1: bl rwsem_wake_writer - ldmfd sp!, {r0 - r3, ip, pc} + ldmfd sp!, {r0 - r3, pc} .previous "); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/setup.c linux.ac/arch/arm/kernel/setup.c --- linux.vanilla/arch/arm/kernel/setup.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/setup.c Sun Jun 4 21:14:16 2000 @@ -217,6 +217,7 @@ mi->bank[mi->nr_banks].start = start; mi->bank[mi->nr_banks].size = size; + mi->bank[mi->nr_banks].node = 0; mi->nr_banks += 1; } c = *from++; @@ -378,6 +379,7 @@ if (meminfo.nr_banks == 0) { meminfo.nr_banks = 1; meminfo.bank[0].start = PHYS_OFFSET; + meminfo.bank[0].node = 0; if (params) meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT; else @@ -393,8 +395,8 @@ saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; parse_cmdline(&meminfo, cmdline_p, from); bootmem_init(&meminfo); - request_standard_resources(&meminfo, mdesc); paging_init(&meminfo); + request_standard_resources(&meminfo, mdesc); #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/time.c linux.ac/arch/arm/kernel/time.c --- linux.vanilla/arch/arm/kernel/time.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/kernel/time.c Sun Jun 4 21:14:16 2000 @@ -154,21 +154,29 @@ static void do_leds(void) { - static unsigned int count = 50; - static int last_pid; +#ifdef CONFIG_LEDS_CPU + { + static int last_pid; - if (current->pid != last_pid) { - last_pid = current->pid; - if (last_pid) - leds_event(led_idle_end); - else - leds_event(led_idle_start); + if (current->pid != last_pid) { + last_pid = current->pid; + if (last_pid) + leds_event(led_idle_end); + else + leds_event(led_idle_start); + } } - - if (--count == 0) { - count = 50; - leds_event(led_timer); +#endif +#ifdef CONFIG_LEDS_TIMER + { + static unsigned int count = 50; + + if (--count == 0) { + count = 50; + leds_event(led_timer); + } } +#endif } #else #define do_leds() diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/changebit.S linux.ac/arch/arm/lib/changebit.S --- linux.vanilla/arch/arm/lib/changebit.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/lib/changebit.S Sun Jun 4 21:14:16 2000 @@ -9,18 +9,15 @@ .text /* Purpose : Function to change a bit - * Prototype: int change_bit(int bit,int *addr) + * Prototype: int change_bit(int bit, void *addr) */ ENTRY(change_bit) - and r2, r0, #7 - mov r3, #1 - mov r3, r3, lsl r2 - SAVEIRQS(ip) - DISABLEIRQS(ip) + and r2, r0, #7 + mov r3, #1 + mov r3, r3, lsl r2 + save_and_disable_irqs ip, r2 ldrb r2, [r1, r0, lsr #3] eor r2, r2, r3 strb r2, [r1, r0, lsr #3] - RESTOREIRQS(ip) + restore_irqs ip RETINSTR(mov,pc,lr) - - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/clearbit.S linux.ac/arch/arm/lib/clearbit.S --- linux.vanilla/arch/arm/lib/clearbit.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/lib/clearbit.S Sun Jun 4 21:14:16 2000 @@ -8,19 +8,20 @@ #include .text -@ Purpose : Function to clear a bit -@ Prototype: int clear_bit(int bit,int *addr) +/* + * Purpose : Function to clear a bit + * Prototype: int clear_bit(int bit, void *addr) + */ ENTRY(clear_bit) and r2, r0, #7 mov r3, #1 mov r3, r3, lsl r2 - SAVEIRQS(ip) - DISABLEIRQS(ip) + save_and_disable_irqs ip, r2 ldrb r2, [r1, r0, lsr #3] bic r2, r2, r3 strb r2, [r1, r0, lsr #3] - RESTOREIRQS(ip) + restore_irqs ip RETINSTR(mov,pc,lr) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/findbit.S linux.ac/arch/arm/lib/findbit.S --- linux.vanilla/arch/arm/lib/findbit.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/lib/findbit.S Sun Jun 4 21:14:16 2000 @@ -1,65 +1,53 @@ /* - * linux/arch/arm/lib/bitops.S + * linux/arch/arm/lib/findbit.S * - * Copyright (C) 1995-1996 Russell King + * Copyright (C) 1995-2000 Russell King */ #include #include .text -@ Purpose : Find a 'zero' bit -@ Prototype: int find_first_zero_bit(char *addr,int maxbit); - +/* + * Purpose : Find a 'zero' bit + * Prototype: int find_first_zero_bit(void *addr, int maxbit); + */ ENTRY(find_first_zero_bit) - mov r2, #0 @ Initialise bit position -Lfindzbit1lp: ldrb r3, [r0, r2, lsr #3] @ Check byte, if 0xFF, then all bits set - teq r3, #0xFF - bne Lfoundzbit - add r2, r2, #8 - cmp r2, r1 @ Check to see if we have come to the end - bcc Lfindzbit1lp - add r0, r1, #1 @ Make sure that we flag an error - RETINSTR(mov,pc,lr) -Lfoundzbit: tst r3, #1 @ Check individual bits - moveq r0, r2 - RETINSTR(moveq,pc,lr) - tst r3, #2 - addeq r0, r2, #1 - RETINSTR(moveq,pc,lr) - tst r3, #4 - addeq r0, r2, #2 - RETINSTR(moveq,pc,lr) - tst r3, #8 - addeq r0, r2, #3 - RETINSTR(moveq,pc,lr) - tst r3, #16 - addeq r0, r2, #4 - RETINSTR(moveq,pc,lr) - tst r3, #32 - addeq r0, r2, #5 - RETINSTR(moveq,pc,lr) - tst r3, #64 - addeq r0, r2, #6 - RETINSTR(moveq,pc,lr) - add r0, r2, #7 + mov r2, #0 +.bytelp: ldrb r3, [r0, r2, lsr #3] + eors r3, r3, #0xff @ invert bits + bne .found @ any now set - found zero bit + add r2, r2, #8 @ next bit pointer + cmp r2, r1 @ any more? + bcc .bytelp + add r0, r1, #1 @ no free bits RETINSTR(mov,pc,lr) -@ Purpose : Find next 'zero' bit -@ Prototype: int find_next_zero_bit(char *addr,int maxbit,int offset) - +/* + * Purpose : Find next 'zero' bit + * Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset) + */ ENTRY(find_next_zero_bit) - tst r2, #7 - beq Lfindzbit1lp @ If new byte, goto old routine + ands ip, r2, #7 + beq .bytelp @ If new byte, goto old routine ldrb r3, [r0, r2, lsr#3] - orr r3, r3, #0xFF00 @ Set top bits so we wont get confused - str r4, [sp, #-4]! - and r4, r2, #7 - mov r3, r3, lsr r4 @ Shift right by no. of bits - ldr r4, [sp], #4 - and r3, r3, #0xFF - teq r3, #0xFF - orreq r2, r2, #7 + eor r3, r3, #0xff @ now looking for a 1 bit + movs r3, r3, lsr ip @ shift off unused bits + orreq r2, r2, #7 @ if zero, then no bits here + addeq r2, r2, #1 @ align bit pointer + beq .bytelp @ loop for next bit + +/* + * One or more bits in the LSB of r3 are assumed to be set. + */ +.found: tst r3, #0x0f + addeq r2, r2, #4 + movne r3, r3, lsl #4 + tst r3, #0x30 + addeq r2, r2, #2 + movne r3, r3, lsl #2 + tst r3, #0x40 addeq r2, r2, #1 - beq Lfindzbit1lp @ If all bits are set, goto old routine - b Lfoundzbit + mov r0, r2 + RETINSTR(mov,pc,lr) + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/setbit.S linux.ac/arch/arm/lib/setbit.S --- linux.vanilla/arch/arm/lib/setbit.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/lib/setbit.S Sun Jun 4 21:14:16 2000 @@ -8,19 +8,20 @@ #include .text -@ Purpose : Function to set a bit -@ Prototype: int set_bit(int bit,int *addr) +/* + * Purpose : Function to set a bit + * Prototype: int set_bit(int bit, void *addr) + */ ENTRY(set_bit) and r2, r0, #7 mov r3, #1 mov r3, r3, lsl r2 - SAVEIRQS(ip) - DISABLEIRQS(ip) + save_and_disable_irqs ip, r2 ldrb r2, [r1, r0, lsr #3] orr r2, r2, r3 strb r2, [r1, r0, lsr #3] - RESTOREIRQS(ip) + restore_irqs ip RETINSTR(mov,pc,lr) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/testchangebit.S linux.ac/arch/arm/lib/testchangebit.S --- linux.vanilla/arch/arm/lib/testchangebit.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/lib/testchangebit.S Sun Jun 4 21:14:16 2000 @@ -12,14 +12,13 @@ add r1, r1, r0, lsr #3 and r3, r0, #7 mov r0, #1 - SAVEIRQS(ip) - DISABLEIRQS(ip) + save_and_disable_irqs ip, r2 ldrb r2, [r1] tst r2, r0, lsl r3 eor r2, r2, r0, lsl r3 - moveq r0, #0 strb r2, [r1] - RESTOREIRQS(ip) + restore_irqs ip + moveq r0, #0 RETINSTR(mov,pc,lr) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/testclearbit.S linux.ac/arch/arm/lib/testclearbit.S --- linux.vanilla/arch/arm/lib/testclearbit.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/lib/testclearbit.S Sun Jun 4 21:14:16 2000 @@ -10,16 +10,15 @@ ENTRY(test_and_clear_bit) add r1, r1, r0, lsr #3 @ Get byte offset - and r3, r0, #7 @ Get bit offset + and r3, r0, #7 @ Get bit offset mov r0, #1 - SAVEIRQS(ip) - DISABLEIRQS(ip) + save_and_disable_irqs ip, r2 ldrb r2, [r1] tst r2, r0, lsl r3 bic r2, r2, r0, lsl r3 - moveq r0, #0 strb r2, [r1] - RESTOREIRQS(ip) + restore_irqs ip + moveq r0, #0 RETINSTR(mov,pc,lr) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/testsetbit.S linux.ac/arch/arm/lib/testsetbit.S --- linux.vanilla/arch/arm/lib/testsetbit.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/lib/testsetbit.S Sun Jun 4 21:14:16 2000 @@ -12,14 +12,13 @@ add r1, r1, r0, lsr #3 @ Get byte offset and r3, r0, #7 @ Get bit offset mov r0, #1 - SAVEIRQS(ip) - DISABLEIRQS(ip) + save_and_disable_irqs ip, r2 ldrb r2, [r1] tst r2, r0, lsl r3 orr r2, r2, r0, lsl r3 - moveq r0, #0 strb r2, [r1] - RESTOREIRQS(ip) + restore_irqs ip + moveq r0, #0 RETINSTR(mov,pc,lr) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/uaccess.S linux.ac/arch/arm/lib/uaccess.S --- linux.vanilla/arch/arm/lib/uaccess.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/lib/uaccess.S Sun Jun 4 21:14:16 2000 @@ -538,13 +538,18 @@ .section .fixup,"ax" .align 0 - /* We took an exception. Zero out the buffer and pretend no - data was copied. */ -9001: ldr r0, [sp], #4 - ldr r1, [sp] - teq r1, #0 + /* + * We took an exception. r0 contains a pointer to + * the byte not copied. + */ +9001: ldr r2, [sp], #4 @ void *to + sub r2, r0, r2 @ bytes copied + ldr r1, [sp], #4 @ unsigned long count + subs r4, r1, r2 @ bytes left to copy + movne r1, r4 blne SYMBOL_NAME(__memzero) - LOADREGS(fd,sp!, {r0, r4 - r7, pc}) + mov r0, r4 + LOADREGS(fd,sp!, {r4 - r7, pc}) .previous /* Prototype: int __arch_clear_user(void *addr, size_t sz) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/Makefile linux.ac/arch/arm/mm/Makefile --- linux.vanilla/arch/arm/mm/Makefile Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/Makefile Sun Jun 4 21:14:16 2000 @@ -22,6 +22,9 @@ ifeq ($(CONFIG_CPU_ARM7),y) P_OBJS += proc-arm6,7.o endif + ifeq ($(CONFIG_CPU_ARM720),y) + P_OBJS += proc-arm720.o + endif ifeq ($(CONFIG_CPU_SA110),y) P_OBJS += proc-sa110.o endif @@ -41,5 +44,6 @@ fault-armo.o: fault-common.c proc-arm2,3.o: ../lib/constants.h proc-arm6,7.o: ../lib/constants.h +proc-arm720.o: ../lib/constants.h proc-sa110.o: ../lib/constants.h diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/consistent.c linux.ac/arch/arm/mm/consistent.c --- linux.vanilla/arch/arm/mm/consistent.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/consistent.c Sun Jun 4 21:14:16 2000 @@ -9,8 +9,10 @@ #include #include #include +#include #include +#include #include /* @@ -19,6 +21,8 @@ * whether this could be called from an interrupt context or not. For * now, we expressly forbid it, especially as some of the stuff we do * here is not interrupt context safe. + * + * Note that this does *not* zero the allocated area! */ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) { @@ -36,15 +40,21 @@ if (!page) goto no_page; - memset((void *)page, 0, size); - clean_cache_area(page, size); - - *dma_handle = virt_to_bus((void *)page); - ret = __ioremap(virt_to_phys((void *)page), size, 0); if (ret) { /* free wasted pages */ unsigned long end = page + (PAGE_SIZE << order); + + /* + * we need to ensure that there are no + * cachelines in use, or worse dirty in + * this area. + */ + dma_cache_inv(page, size); + dma_cache_inv(ret, size); + + *dma_handle = virt_to_bus((void *)page); + page += size; while (page < end) { free_page(page); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/fault-armv.c linux.ac/arch/arm/mm/fault-armv.c --- linux.vanilla/arch/arm/mm/fault-armv.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/fault-armv.c Sun Jun 4 21:14:16 2000 @@ -250,6 +250,8 @@ } } +if (addr != eaddr) +printk("PC = %08lx, instr = %08x, addr = %08lx, eaddr = %08lx\n", instruction_pointer(regs), instr, addr, eaddr); if (LDST_L_BIT(instr)) { regs->uregs[rd] = get_unaligned((unsigned long *)eaddr); if (rd == 15) @@ -383,29 +385,38 @@ "more information\n" asmlinkage void -do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs) +do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr) { - const struct fsr_info *inf; + const struct fsr_info *inf = fsr_info + (fsr & 15); - if (user_mode(regs) && addr == regs->ARM_pc) { + if (addr == regs->ARM_pc) + goto weirdness; + + if (!inf->fn) + goto bad; + + if (!inf->fn(addr, error_code, regs)) + return; +bad: + force_sig(inf->sig, current); + die_if_kernel(inf->name, regs, fsr); + return; + +weirdness: + if (user_mode(regs)) { static int first = 1; - if (first) { + if (first) /* * I want statistical information on this problem, * but we don't want to hastle the users too much. */ printk(BUG_PROC_MSG, fsr); - first = 0; - } + first = 0; return; } - inf = fsr_info + (fsr & 15); - - if (!inf->fn || inf->fn(addr, error_code, regs)) { - force_sig(inf->sig, current); - die_if_kernel(inf->name, regs, fsr); - } + if (!inf->fn || inf->fn(addr, error_code, regs)) + goto bad; } asmlinkage int diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/fault-common.c linux.ac/arch/arm/mm/fault-common.c --- linux.vanilla/arch/arm/mm/fault-common.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/fault-common.c Sun Jun 4 21:14:16 2000 @@ -16,6 +16,10 @@ { pgd_t *pgd; + if (!mm) + mm = &init_mm; + + printk(KERN_ALERT "pgd = %p\n", mm->pgd); pgd = pgd_offset(mm, addr); printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd)); @@ -52,39 +56,78 @@ printk("\n"); } -/* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. - */ -static void -kernel_page_fault(unsigned long addr, int write_access, struct pt_regs *regs, - struct task_struct *tsk, struct mm_struct *mm) +static int __do_page_fault(struct mm_struct *mm, unsigned long addr, int mode, struct task_struct *tsk) { - char *reason; + struct vm_area_struct *vma; + int fault, mask; + + vma = find_vma(mm, addr); + fault = -2; /* bad map area */ + if (!vma) + goto out; + if (vma->vm_start > addr) + goto check_stack; - if (addr < PAGE_SIZE) - reason = "NULL pointer dereference"; + /* + * Ok, we have a good vm_area for this + * memory access, so we can handle it. + */ +good_area: + if (READ_FAULT(mode)) /* read? */ + mask = VM_READ|VM_EXEC; else - reason = "paging request"; + mask = VM_WRITE; - printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n", - reason, addr); - if (!mm) - mm = &init_mm; + fault = -1; /* bad access type */ + if (!(vma->vm_flags & mask)) + goto out; - printk(KERN_ALERT "pgd = %p\n", mm->pgd); - show_pte(mm, addr); - die("Oops", regs, write_access); + /* + * If for any reason at all we couldn't handle + * the fault, make sure we exit gracefully rather + * than endlessly redo the fault. + */ +survive: + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(mode)); - do_exit(SIGKILL); + /* + * Handle the "normal" cases first - successful and sigbus + */ + switch (fault) { + case 2: + tsk->maj_flt++; + return fault; + case 1: + tsk->min_flt++; + case 0: + return fault; + } + + fault = -3; /* out of memory */ + if (tsk->pid != 1) + goto out; + + /* + * If we are out of memory for pid1, + * sleep for a while and retry + */ + tsk->policy |= SCHED_YIELD; + schedule(); + goto survive; + +check_stack: + if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr)) + goto good_area; +out: + return fault; } static int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs) { struct task_struct *tsk; struct mm_struct *mm; - struct vm_area_struct *vma; unsigned long fixup; + int fault; tsk = current; mm = tsk->mm; @@ -97,57 +140,77 @@ goto no_context; down(&mm->mmap_sem); - vma = find_vma(mm, addr); - if (!vma) - goto bad_area; - if (vma->vm_start <= addr) - goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack(vma, addr)) - goto bad_area; + fault = __do_page_fault(mm, addr, mode, tsk); + up(&mm->mmap_sem); /* - * Ok, we have a good vm_area for this memory access, so - * we can handle it.. + * Handle the "normal" case first */ -good_area: - if (READ_FAULT(mode)) { /* read? */ - if (!(vma->vm_flags & (VM_READ|VM_EXEC))) - goto bad_area; - } else { - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - } + if (fault > 0) + return 0; /* - * If for any reason at all we couldn't handle the fault, - * make sure we exit gracefully rather than endlessly redo - * the fault. + * We had some memory, but were unable to + * successfully fix up this page fault. */ - if (!handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(mode))) + if (fault == 0) goto do_sigbus; - up(&mm->mmap_sem); - return 0; - /* - * Something tried to access memory that isn't in our memory map.. - * Fix it, but check if it's kernel or user first.. + * If we are in kernel mode at this point, we + * have no context to handle this fault with. */ -bad_area: - up(&mm->mmap_sem); + if (!user_mode(regs)) + goto no_context; + + if (fault == -3) { + /* + * We ran out of memory, or some other thing happened to + * us that made us unable to handle the page fault gracefully. + */ + printk("VM: killing process %s\n", tsk->comm); + do_exit(SIGKILL); + } else { + /* + * Something tried to access memory that isn't in our memory map.. + * User mode accesses just cause a SIGSEGV + */ + struct siginfo si; + +#ifdef CONFIG_DEBUG_USER + printk(KERN_DEBUG "%s: unhandled page fault at pc=0x%08lx, " + "lr=0x%08lx (bad address=0x%08lx, code %d)\n", + tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode); +#endif - /* User mode accesses just cause a SIGSEGV */ - if (user_mode(regs)) { tsk->thread.address = addr; tsk->thread.error_code = mode; tsk->thread.trap_no = 14; -#ifdef CONFIG_DEBUG_USER - printk("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n", - tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode); -#endif - force_sig(SIGSEGV, tsk); - return 0; + si.si_signo = SIGSEGV; + si.si_code = fault == -1 ? SEGV_ACCERR : SEGV_MAPERR; + si.si_addr = (void *)addr; + force_sig_info(SIGSEGV, &si, tsk); } + return 0; + + +/* + * We ran out of memory, or some other thing happened to us that made + * us unable to handle the page fault gracefully. + */ +do_sigbus: + /* + * Send a sigbus, regardless of whether we were in kernel + * or user mode. + */ + tsk->thread.address = addr; + tsk->thread.error_code = mode; + tsk->thread.trap_no = 14; + force_sig(SIGBUS, tsk); + + /* Kernel mode? Handle exceptions or die */ + if (user_mode(regs)) + return 0; no_context: /* Are we prepared to handle this kernel fault? */ @@ -160,29 +223,16 @@ return 0; } - kernel_page_fault(addr, mode, regs, tsk, mm); - return 0; - -do_sigbus: /* - * We ran out of memory, or some other thing happened to us that made - * us unable to handle the page fault gracefully. + * Oops. The kernel tried to access some bad page. We'll have to + * terminate things with extreme prejudice. */ - up(&mm->mmap_sem); + printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n", + (addr < PAGE_SIZE) ? "NULL pointer dereference" : "paging request", addr); - /* - * Send a sigbus, regardless of whether we were in kernel - * or user mode. - */ - tsk->thread.address = addr; - tsk->thread.error_code = mode; - tsk->thread.trap_no = 14; - force_sig(SIGBUS, tsk); + show_pte(mm, addr); + die("Oops", regs, mode); + do_exit(SIGKILL); - /* Kernel mode? Handle exceptions or die */ - if (!user_mode(regs)) - goto no_context; return 0; } - - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/init.c linux.ac/arch/arm/mm/init.c --- linux.vanilla/arch/arm/mm/init.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/init.c Sun Jun 4 21:14:16 2000 @@ -31,16 +31,23 @@ #include "map.h" +#ifndef CONFIG_DISCONTIGMEM +#define NR_NODES 1 +#else +#define NR_NODES 4 +#endif + #ifdef CONFIG_CPU_32 #define TABLE_OFFSET (PTRS_PER_PTE) #else #define TABLE_OFFSET 0 #endif + #define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *)) static unsigned long totalram_pages; pgd_t swapper_pg_dir[PTRS_PER_PGD]; -extern int _stext, _text, _etext, _edata, _end; +extern char _stext, _text, _etext, _end, __init_begin, __init_end; /* * The sole use of this is to pass memory configuration @@ -173,6 +180,12 @@ show_buffers(); } +struct node_info { + unsigned int start; + unsigned int end; + int bootmap_pages; +}; + #define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT) #define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x)) @@ -183,34 +196,24 @@ #define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \ (((unsigned long)(s)) & PAGE_MASK)) +/* + * FIXME: We really want to avoid allocating the bootmap bitmap + * over the top of the initrd. Hopefully, this is located towards + * the start of a bank, so if we allocate the bootmap bitmap at + * the end, we won't clash. + */ static unsigned int __init -find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages) +find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages) { unsigned int start_pfn, bank, bootmap_pfn; start_pfn = V_PFN_UP(&_end); bootmap_pfn = 0; - /* - * FIXME: We really want to avoid allocating the bootmap - * over the top of the initrd. - */ -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) { - if (__pa(initrd_end) > mi->end) { - printk ("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx) - disabling initrd\n", - __pa(initrd_end), mi->end); - initrd_start = 0; - initrd_end = 0; - } - } -#endif - for (bank = 0; bank < mi->nr_banks; bank ++) { unsigned int start, end; - if (mi->bank[bank].size == 0) + if (mi->bank[bank].node != node) continue; start = O_PFN_UP(mi->bank[bank].start); @@ -239,99 +242,224 @@ } /* - * Initialise one node of the bootmem allocator. For now, we - * only initialise node 0. Notice that we have a bootmem - * bitmap per node. + * Scan the memory info structure and pull out: + * - the end of memory + * - the number of nodes + * - the pfn range of each node + * - the number of bootmem bitmap pages */ -static void __init setup_bootmem_node(int node, struct meminfo *mi) +static unsigned int __init +find_memend_and_nodes(struct meminfo *mi, struct node_info *np) { - unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn; - unsigned int i; + unsigned int i, bootmem_pages = 0, memend_pfn = 0; + + for (i = 0; i < NR_NODES; i++) { + np[i].start = -1U; + np[i].end = 0; + np[i].bootmap_pages = 0; + } + + for (i = 0; i < mi->nr_banks; i++) { + unsigned long start, end; + int node; + + if (mi->bank[i].size == 0) { + /* + * Mark this bank with an invalid node number + */ + mi->bank[i].node = -1; + continue; + } + + node = mi->bank[i].node; + + if (node >= numnodes) { + numnodes = node + 1; - if (node != 0) /* only initialise node 0 for now */ - return; + /* + * Make sure we haven't exceeded the maximum number + * of nodes that we have in this configuration. If + * we have, we're in trouble. (maybe we ought to + * limit, instead of bugging?) + */ + if (numnodes > NR_NODES) + BUG(); + } + + /* + * Get the start and end pfns for this bank + */ + start = O_PFN_UP(mi->bank[i].start); + end = O_PFN_DOWN(mi->bank[i].start + mi->bank[i].size); - start_pfn = O_PFN_UP(PHYS_OFFSET); - end_pfn = O_PFN_DOWN(mi->end); - bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); - bootmap_pfn = find_bootmap_pfn(mi, bootmap_pages); + if (np[node].start > start) + np[node].start = start; + + if (np[node].end < end) + np[node].end = end; + + if (memend_pfn < end) + memend_pfn = end; + } /* - * Initialise the boot-time allocator + * Calculate the number of pages we require to + * store the bootmem bitmaps. */ - init_bootmem_node(node, bootmap_pfn, start_pfn, end_pfn); + for (i = 0; i < numnodes; i++) { + if (np[i].end == 0) + continue; + + np[i].bootmap_pages = bootmem_bootmap_pages(np[i].end - + np[i].start); + bootmem_pages += np[i].bootmap_pages; + } /* - * Register all available RAM with the bootmem allocator. + * This doesn't seem to be used by the Linux memory + * manager any more. If we can get rid of it, we + * also get rid of some of the stuff above as well. */ - for (i = 0; i < mi->nr_banks; i++) - if (mi->bank[i].size) - free_bootmem_node(node, mi->bank[i].start, - PFN_SIZE(mi->bank[i].size) << PAGE_SHIFT); + max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET); + mi->end = memend_pfn << PAGE_SHIFT; - reserve_bootmem_node(node, bootmap_pfn << PAGE_SHIFT, - bootmap_pages << PAGE_SHIFT); + return bootmem_pages; } -/* - * Initialise the bootmem allocator. - */ -void __init bootmem_init(struct meminfo *mi) +static int __init check_initrd(struct meminfo *mi) { - unsigned int i, node; + int initrd_node = -2; +#ifdef CONFIG_BLK_DEV_INITRD /* - * Calculate the physical address of the top of memory. - * Note that there are no guarantees assumed about the - * ordering of the bank information. + * Make sure that the initrd is within a valid area of + * memory. */ - mi->end = 0; - for (i = 0; i < mi->nr_banks; i++) { - unsigned long end; + if (initrd_start) { + unsigned long phys_initrd_start, phys_initrd_end; + unsigned int i; + + phys_initrd_start = __pa(initrd_start); + phys_initrd_end = __pa(initrd_end); + + for (i = 0; i < mi->nr_banks; i++) { + unsigned long bank_end; - if (mi->bank[i].size != 0) { - end = mi->bank[i].start + mi->bank[i].size; - if (mi->end < end) - mi->end = end; + bank_end = mi->bank[i].start + mi->bank[i].size; + + if (mi->bank[i].start <= phys_initrd_start && + phys_initrd_end <= bank_end) + initrd_node = mi->bank[i].node; } } - max_low_pfn = O_PFN_DOWN(mi->end - PHYS_OFFSET); + if (initrd_node == -1) { + printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond " + "physical memory - disabling initrd\n", + initrd_start, initrd_end); + initrd_start = initrd_end = 0; + } +#endif - /* - * Setup each node - */ - for (node = 0; node < numnodes; node++) - setup_bootmem_node(node, mi); + return initrd_node; +} +/* + * Reserve the various regions of node 0 + */ +static inline void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages) +{ /* * Register the kernel text and data with bootmem. * Note that this can only be in node 0. */ - reserve_bootmem_node(0, V_PFN_DOWN(&_stext) << PAGE_SHIFT, - PFN_RANGE(&_stext, &_end) << PAGE_SHIFT); + reserve_bootmem_node(0, __pa(&_stext), &_end - &_stext); #ifdef CONFIG_CPU_32 /* * Reserve the page tables. These are already in use, * and can only be in node 0. */ - reserve_bootmem_node(0, V_PFN_DOWN(swapper_pg_dir) << PAGE_SHIFT, - PFN_SIZE(PTRS_PER_PGD * sizeof(void *)) << PAGE_SHIFT); + reserve_bootmem_node(0, __pa(swapper_pg_dir), + PTRS_PER_PGD * sizeof(void *)); #endif -#ifdef CONFIG_BLK_DEV_INITRD /* - * This may be in any bank. Currently, we assume that - * it is in bank 0. + * And don't forget to reserve the allocator bitmap, + * which will be freed later. */ - if (initrd_start) - reserve_bootmem_node(0, V_PFN_DOWN(initrd_start) << PAGE_SHIFT, - PFN_RANGE(initrd_start, initrd_end) << PAGE_SHIFT); + reserve_bootmem_node(0, bootmap_pfn << PAGE_SHIFT, + bootmap_pages << PAGE_SHIFT); +} + +/* + * Register all available RAM in this node with the bootmem allocator. + */ +static inline void free_bootmem_node_bank(int node, struct meminfo *mi) +{ + int bank; + + for (bank = 0; bank < mi->nr_banks; bank++) + if (mi->bank[bank].node == node) + free_bootmem_node(node, mi->bank[bank].start, + mi->bank[bank].size); +} + +/* + * Initialise the bootmem allocator for all nodes. This is called + * early during the architecture specific initialisation. + */ +void __init bootmem_init(struct meminfo *mi) +{ + struct node_info node_info[NR_NODES], *np = node_info; + unsigned int bootmap_pages, bootmap_pfn, map_pg; + int node, initrd_node; + + bootmap_pages = find_memend_and_nodes(mi, np); + bootmap_pfn = find_bootmap_pfn(0, mi, bootmap_pages); + initrd_node = check_initrd(mi); + + map_pg = bootmap_pfn; + + for (node = 0; node < numnodes; node++, np++) { + /* + * If there are no pages in this node, ignore it. + * Note that node 0 must always have some pages. + */ + if (np->end == 0) { + if (node == 0) + BUG(); + continue; + } + + /* + * Initialise the bootmem allocator. + */ + init_bootmem_node(node, map_pg, np->start, np->end); + free_bootmem_node_bank(node, mi); + map_pg += np->bootmap_pages; + + /* + * If this is node 0, we need to reserve some areas ASAP - + * we may use bootmem on node 0 to setup the other nodes. + */ + if (node == 0) + reserve_node_zero(bootmap_pfn, bootmap_pages); + } + + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_node >= 0) + reserve_bootmem_node(initrd_node, __pa(initrd_start), + initrd_end - initrd_start); #endif + + if (map_pg != bootmap_pfn + bootmap_pages) + BUG(); } /* - * paging_init() sets up the page tables... + * paging_init() sets up the page tables, initialises the zone memory + * maps, and sets up the zero page, bad page and bad page tables. */ void __init paging_init(struct meminfo *mi) { @@ -378,11 +506,23 @@ * The size of this node has already been determined. * If we need to do anything fancy with the allocation * of this memory to the zones, now is the time to do - * it. For now, we don't touch zhole_size. + * it. */ zone_size[0] = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT); + /* + * For each bank in this node, calculate the size of the + * holes. holes = node_size - sum(bank_sizes_in_node) + */ + zhole_size[0] = zone_size[0]; + for (i = 0; i < mi->nr_banks; i++) { + if (mi->bank[i].node != node) + continue; + + zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT; + } + free_area_init_node(node, pgdat, zone_size, bdata->node_boot_start, zhole_size); } @@ -399,31 +539,6 @@ empty_bad_pte_table = ((pte_t *)bad_table) + TABLE_OFFSET; } -static inline void free_unused_mem_map(void) -{ - struct page *page, *end; - - end = mem_map + max_mapnr; - - for (page = mem_map; page < end; page++) { - unsigned long low, high; - - if (!PageSkip(page)) - continue; - - low = PAGE_ALIGN((unsigned long)(page + 1)); - if (page->next_hash < page) - high = ((unsigned long)end) & PAGE_MASK; - else - high = ((unsigned long)page->next_hash) & PAGE_MASK; - - while (low < high) { - ClearPageReserved(mem_map + MAP_NR(low)); - low += PAGE_SIZE; - } - } -} - /* * mem_init() marks the free areas in the mem_map and tells us how much * memory is free. This is done after various parts of the system have @@ -431,7 +546,6 @@ */ void __init mem_init(void) { - extern char __init_begin, __init_end; unsigned int codepages, datapages, initpages; int i, node; @@ -443,8 +557,7 @@ max_mapnr = MAP_NR(high_memory); /* - * We may have non-contiguous memory. Setup the PageSkip stuff, - * and mark the areas of mem_map which can be freed + * We may have non-contiguous memory. */ if (meminfo.nr_banks != 1) create_memmap_holes(&meminfo); @@ -500,8 +613,6 @@ void free_initmem(void) { - extern char __init_begin, __init_end; - printk("Freeing unused kernel memory:"); free_area((unsigned long)(&__init_begin), diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/mm-armv.c linux.ac/arch/arm/mm/mm-armv.c --- linux.vanilla/arch/arm/mm/mm-armv.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/mm-armv.c Sun Jun 4 21:14:16 2000 @@ -411,50 +411,41 @@ } /* - * The mem_map array can get very big. Mark the end of the valid mem_map - * banks with PG_skip, and setup the address validity bitmap. + * The mem_map array can get very big. Free the unused area of the memory map. */ -void __init create_memmap_holes(struct meminfo *mi) +static inline void free_unused_memmap_node(int node, struct meminfo *mi) { - unsigned int start_pfn, end_pfn = -1; - struct page *pg = NULL; + unsigned long bank_start, prev_bank_end = 0; unsigned int i; -#define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT) -#define free_bootmem(s,sz) free_bootmem(((s)<nr_banks; i++) { - if (mi->bank[i].size == 0) + if (mi->bank[i].size == 0 || mi->bank[i].node != node) continue; - start_pfn = PFN(mi->bank[i].start); + bank_start = mi->bank[i].start & PAGE_MASK; /* - * subtle here - if we have a full bank, then - * start_pfn == end_pfn, and we don't want to - * set PG_skip, or next_hash + * If we had a previous bank, and there is a space + * between the current bank and the previous, free it. */ - if (pg && start_pfn != end_pfn) { - set_bit(PG_skip, &pg->flags); - pg->next_hash = mem_map + start_pfn; - - start_pfn = PFN(PAGE_ALIGN(__pa(pg + 1))); - end_pfn = PFN(__pa(pg->next_hash) & PAGE_MASK); - - if (end_pfn != start_pfn) - free_bootmem(start_pfn, end_pfn - start_pfn); - - pg = NULL; - } + if (prev_bank_end && prev_bank_end != bank_start) + free_bootmem_node(node, prev_bank_end, + bank_start - prev_bank_end); - end_pfn = PFN(mi->bank[i].start + mi->bank[i].size); - - if (end_pfn != PFN(mi->end)) - pg = mem_map + end_pfn; + prev_bank_end = PAGE_ALIGN(mi->bank[i].start + + mi->bank[i].size); } +} - if (pg) { - set_bit(PG_skip, &pg->flags); - pg->next_hash = NULL; - } +void __init create_memmap_holes(struct meminfo *mi) +{ + int node; + + for (node = 0; node < numnodes; node++) + free_unused_memmap_node(node, mi); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/mm-footbridge.c linux.ac/arch/arm/mm/mm-footbridge.c --- linux.vanilla/arch/arm/mm/mm-footbridge.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/mm-footbridge.c Sun Jun 4 21:14:16 2000 @@ -29,7 +29,7 @@ * You can then access the PCI bus at 0xe0000000 and 0xffe00000. */ -#ifdef CONFIG_HOST_FOOTBRIDGE +#ifdef CONFIG_FOOTBRIDGE_HOST /* * The mapping when the footbridge is in host mode. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/mm-l7200.c linux.ac/arch/arm/mm/mm-l7200.c --- linux.vanilla/arch/arm/mm/mm-l7200.c Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/arm/mm/mm-l7200.c Sun Jun 4 21:14:16 2000 @@ -0,0 +1,25 @@ +/* + * arch/arm/mm/mm-lusl7200.c + * + * Extra MM routines for LUSL7200 architecture + * + * Copyright (C) 2000 Steven J. Hill + */ + +#include + +#include +#include +#include +#include + +#include "map.h" + +#define SIZE(x) (sizeof(x) / sizeof(x[0])) + +struct map_desc io_desc[] __initdata = { + { IO_BASE, IO_START, IO_SIZE, DOMAIN_IO, 0, 1 ,0 ,0}, + { IO_BASE_2, IO_START_2, IO_SIZE_2, DOMAIN_IO, 0, 1 ,0 ,0}, +}; + +unsigned int __initdata io_desc_size = SIZE(io_desc); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/mm-sa1100.c linux.ac/arch/arm/mm/mm-sa1100.c --- linux.vanilla/arch/arm/mm/mm-sa1100.c Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/mm-sa1100.c Sun Jun 4 21:14:16 2000 @@ -11,13 +11,14 @@ * Memory is listed physically now. * * 2000/04/07 Nicolas Pitre - * Reworked for real-time selection of memory definitions + * Reworked for run-time selection of memory definitions * */ #include #include #include +#include #include #include @@ -140,4 +141,21 @@ io_desc_size = SIZE(default_io_desc); } } + +#ifdef CONFIG_DISCONTIGMEM + +/* + * Our node_data structure for discontigous memory. + * There is 4 possible nodes i.e. the 4 SA1100 RAM banks. + */ + +static bootmem_data_t node_bootmem_data[4]; + +pg_data_t sa1100_node_data[4] = +{ { bdata: &node_bootmem_data[0] }, + { bdata: &node_bootmem_data[1] }, + { bdata: &node_bootmem_data[2] }, + { bdata: &node_bootmem_data[3] } }; + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/proc-arm6,7.S linux.ac/arch/arm/mm/proc-arm6,7.S --- linux.vanilla/arch/arm/mm/proc-arm6,7.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/proc-arm6,7.S Sun Jun 4 21:14:16 2000 @@ -93,37 +93,30 @@ * Purpose : obtain information about current aborted instruction * * Returns : r0 = address of abort - * : r1 = FSR - * : r2 != 0 if writing + * : r1 != 0 if writing + * : r3 = FSR * : sp = pointer to registers */ -Lukabttxt: .ascii "Unknown data abort code %d [pc=%p, *pc=%p] LR=%p\0" - .align - -msg: .ascii "DA*%p=%p\n\0" - .align - ENTRY(cpu_arm6_data_abort) ldr r4, [r0] @ read instruction causing problem - mov r2, r4, lsr #19 @ r2 b1 = L - and r1, r4, #14 << 24 - and r2, r2, #2 @ check read/write bit - teq r1, #4 << 23 + mov r1, r4, lsr #19 @ r1 b1 = L + and r2, r4, #14 << 24 + and r1, r1, #2 @ check read/write bit + teq r2, #8 << 24 @ was it ldm/stm bne Ldata_simple - Ldata_ldmstm: tst r4, #1 << 21 @ check writeback bit beq Ldata_simple mov r7, #0x11 orr r7, r7, r7, lsl #8 and r0, r4, r7 - and r1, r4, r7, lsl #1 - add r0, r0, r1, lsr #1 - and r1, r4, r7, lsl #2 - add r0, r0, r1, lsr #2 - and r1, r4, r7, lsl #3 - add r0, r0, r1, lsr #3 + and r2, r4, r7, lsl #1 + add r0, r0, r2, lsr #1 + and r2, r4, r7, lsl #2 + add r0, r0, r2, lsr #2 + and r2, r4, r7, lsl #3 + add r0, r0, r2, lsr #3 add r0, r0, r0, lsr #8 add r0, r0, r0, lsr #4 and r7, r0, #15 @ r7 = no. of registers to transfer. @@ -134,16 +127,16 @@ addeq r7, r0, r7, lsl #2 @ Do correction (signed) Ldata_saver7: str r7, [sp, r5, lsr #14] @ Put register Ldata_simple: mrc p15, 0, r0, c6, c0, 0 @ get FAR - mrc p15, 0, r1, c5, c0, 0 @ get FSR - and r1, r1, #255 + mrc p15, 0, r3, c5, c0, 0 @ get FSR + and r3, r3, #255 mov pc, lr ENTRY(cpu_arm7_data_abort) ldr r4, [r0] @ read instruction causing problem - mov r2, r4, lsr #19 @ r2 b1 = L - and r1, r4, #15 << 24 - and r2, r2, #2 @ check read/write bit - add pc, pc, r1, lsr #22 @ Now branch to the relevent processing routine + mov r1, r4, lsr #19 @ r1 b1 = L + and r2, r4, #15 << 24 + and r1, r1, #2 @ check read/write bit + add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine movs pc, lr b Ldata_unknown @@ -162,7 +155,7 @@ b Ldata_simple @ ldc rd, [rn, #m] b Ldata_unknown Ldata_unknown: @ Part of jumptable - mov r0, r1 + mov r0, r2 mov r1, r4 mov r2, r3 b baddataabort @@ -172,13 +165,13 @@ tst r4, #1 << 21 @ check writeback bit beq Ldata_simple Ldata_lateldrpostconst: - movs r1, r4, lsl #20 @ Get offset + movs r2, r4, lsl #20 @ Get offset beq Ldata_simple and r5, r4, #15 << 16 @ Get Rn ldr r0, [sp, r5, lsr #14] tst r4, #1 << 23 @ U bit - subne r7, r0, r1, lsr #20 - addeq r7, r0, r1, lsr #20 + subne r7, r0, r2, lsr #20 + addeq r7, r0, r2, lsr #20 b Ldata_saver7 Ldata_lateldrprereg: @@ -186,7 +179,7 @@ beq Ldata_simple Ldata_lateldrpostreg: and r5, r4, #15 - ldr r1, [sp, r5, lsl #2] @ Get Rm + ldr r2, [sp, r5, lsl #2] @ Get Rm mov r3, r4, lsr #7 ands r3, r3, #31 and r6, r4, #0x70 @@ -194,7 +187,7 @@ add pc, pc, r6 mov r0, r0 - mov r1, r1, lsl r3 @ 0: LSL #!0 + mov r2, r2, lsl r3 @ 0: LSL #!0 b 1f b 1f @ 1: LSL #0 mov r0, r0 @@ -202,25 +195,25 @@ mov r0, r0 b 1f @ 3: MUL? mov r0, r0 - mov r1, r1, lsr r3 @ 4: LSR #!0 + mov r2, r2, lsr r3 @ 4: LSR #!0 b 1f - mov r1, r1, lsr #32 @ 5: LSR #32 + mov r2, r2, lsr #32 @ 5: LSR #32 b 1f b 1f @ 6: MUL? mov r0, r0 b 1f @ 7: MUL? mov r0, r0 - mov r1, r1, asr r3 @ 8: ASR #!0 + mov r2, r2, asr r3 @ 8: ASR #!0 b 1f - mov r1, r1, asr #32 @ 9: ASR #32 + mov r2, r2, asr #32 @ 9: ASR #32 b 1f b 1f @ A: MUL? mov r0, r0 b 1f @ B: MUL? mov r0, r0 - mov r1, r1, ror r3 @ C: ROR #!0 + mov r2, r2, ror r3 @ C: ROR #!0 b 1f - mov r1, r1, rrx @ D: RRX + mov r2, r2, rrx @ D: RRX b 1f mov r0, r0 @ E: MUL? mov r0, r0 @@ -230,8 +223,8 @@ 1: and r5, r4, #15 << 16 @ Get Rn ldr r0, [sp, r5, lsr #14] tst r4, #1 << 23 @ U bit - subne r7, r0, r1 - addeq r7, r0, r1 + subne r7, r0, r2 + addeq r7, r0, r2 b Ldata_saver7 /* @@ -254,7 +247,8 @@ ENTRY(cpu_arm6_proc_fin) ENTRY(cpu_arm7_proc_fin) - msr cpsr_c, #F_BIT | I_BIT | SVC_MODE + mov r0, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, r0 mov r0, #0x31 @ ....S..DP...M mcr p15, 0, r0, c1, c0, 0 @ disable caches mov pc, lr @@ -364,7 +358,8 @@ .section ".text.init", #alloc, #execinstr -__arm6_setup: msr cpsr_c, #F_BIT | I_BIT | SVC_MODE +__arm6_setup: mov r0, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, r0 mov r0, #0 mcr p15, 0, r0, c7, c0 @ flush caches on v3 mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 @@ -375,7 +370,8 @@ orr r0, r0, #0x100 mov pc, lr -__arm7_setup: msr cpsr_c, #F_BIT | I_BIT | SVC_MODE +__arm7_setup: mov r0, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, r0 mov r0, #0 mcr p15, 0, r0, c7, c0 @ flush caches on v3 mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/proc-sa110.S linux.ac/arch/arm/mm/proc-sa110.S --- linux.vanilla/arch/arm/mm/proc-sa110.S Thu May 25 17:38:34 2000 +++ linux.ac/arch/arm/mm/proc-sa110.S Sun Jun 4 21:14:16 2000 @@ -300,19 +300,18 @@ * Params : r0 = address of aborted instruction * Purpose : obtain information about current aborted instruction * Returns : r0 = address of abort - * : r1 = FSR - * : r2 != 0 if writing + * : r1 != 0 if writing + * : r3 = FSR */ .align 5 ENTRY(cpu_sa110_data_abort) ENTRY(cpu_sa1100_data_abort) - ldr r2, [r0] @ read instruction causing problem + ldr r1, [r0] @ read instruction causing problem mrc p15, 0, r0, c6, c0, 0 @ get FAR - mov r2, r2, lsr #19 @ b1 = L - and r3, r2, #0x69 << 2 - and r2, r2, #2 - mrc p15, 0, r1, c5, c0, 0 @ get FSR - and r1, r1, #255 + mov r1, r1, lsr #19 @ b1 = L + and r1, r1, #2 + mrc p15, 0, r3, c5, c0, 0 @ get FSR + and r3, r3, #255 mov pc, lr .align 5 @@ -423,7 +422,8 @@ ENTRY(cpu_sa110_proc_fin) stmfd sp!, {r1, lr} - msr cpsr_c, #F_BIT | I_BIT | SVC_MODE + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip bl cpu_sa110_flush_cache_all @ clean caches 1: mov r0, #0 mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching @@ -435,7 +435,8 @@ ENTRY(cpu_sa1100_proc_fin) stmfd sp!, {r1, lr} - msr cpsr_c, #F_BIT | I_BIT | SVC_MODE + mov ip, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, ip bl cpu_sa1100_flush_cache_all @ clean caches b 1b @@ -501,7 +502,8 @@ .section ".text.init", #alloc, #execinstr -__sa110_setup: msr cpsr_c, #F_BIT | I_BIT | SVC_MODE +__sa110_setup: mov r0, #F_BIT | I_BIT | SVC_MODE + msr cpsr_c, r0 mov r0, #0 mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/Makefile linux.ac/arch/i386/Makefile --- linux.vanilla/arch/i386/Makefile Thu May 25 17:46:15 2000 +++ linux.ac/arch/i386/Makefile Sun Jun 4 21:47:46 2000 @@ -49,7 +49,7 @@ CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) endif -ifdef CONFIG_M686FX +ifdef CONFIG_M686FXSR CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) endif 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 Sun Jun 4 21:47:46 2000 @@ -19,7 +19,7 @@ # CONFIG_M586 is not set # CONFIG_M586TSC is not set CONFIG_M686=y -# CONFIG_M686FX is not set +# CONFIG_M686FXSR is not set # CONFIG_MK6 is not set # CONFIG_MK7 is not set # CONFIG_MCRUSOE is not set @@ -33,6 +33,7 @@ CONFIG_X86_GOOD_APIC=y CONFIG_X86_PGE=y CONFIG_X86_USE_PPRO_CHECKSUM=y +# CONFIG_X86_FXSR is not set # CONFIG_MICROCODE is not set # CONFIG_X86_MSR is not set # CONFIG_X86_CPUID is not set @@ -105,10 +106,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 @@ -179,6 +176,8 @@ # CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set # CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set # CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set # CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set @@ -228,6 +227,7 @@ # CONFIG_VIA82CXXX_TUNING is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set CONFIG_BLK_DEV_IDE_MODES=y # 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 Sun Jun 4 22:17:47 2000 @@ -700,7 +700,7 @@ if (!(pmregmisc & ACPI_PIIX4_PMIOSE)) return -ENODEV; - base = dev->resource[PCI_BRIDGE_RESOURCES].start & PCI_BASE_ADDRESS_IO_MASK; + base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES); if (!base) return -ENODEV; @@ -759,7 +759,6 @@ if (!base) return -ENODEV; } - base &= PCI_BASE_ADDRESS_IO_MASK; pci_read_config_byte(dev, 0x42, &irq); @@ -824,7 +823,7 @@ {acpi_init_via}, }; -const static struct pci_device_id acpi_pci_tbl[] = +static struct pci_device_id acpi_pci_tbl[] __initdata = { {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4}, {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586}, @@ -1169,6 +1168,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 +1192,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 Wed May 31 11:35:48 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/pci-i386.c linux.ac/arch/i386/kernel/pci-i386.c --- linux.vanilla/arch/i386/kernel/pci-i386.c Thu May 25 17:38:24 2000 +++ linux.ac/arch/i386/kernel/pci-i386.c Sun Jun 4 21:40:00 2000 @@ -106,6 +106,7 @@ reg = PCI_BASE_ADDRESS_0 + 4*resource; } else if (resource == PCI_ROM_RESOURCE) { res->flags |= PCI_ROM_ADDRESS_ENABLE; + new |= PCI_ROM_ADDRESS_ENABLE; reg = dev->rom_base_reg; } else { /* Somebody might have asked allocation of a non-standard resource */ 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/8xx_io/Config.in linux.ac/arch/ppc/8xx_io/Config.in --- linux.vanilla/arch/ppc/8xx_io/Config.in Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/8xx_io/Config.in Sun Jun 4 21:10:56 2000 @@ -12,5 +12,7 @@ fi fi bool '860T FEC Ethernet' CONFIG_FEC_ENET + bool 'Use SMC2 for UART' CONFIG_8xxSMC2 + bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC endmenu fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/8xx_io/commproc.c linux.ac/arch/ppc/8xx_io/commproc.c --- linux.vanilla/arch/ppc/8xx_io/commproc.c Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/8xx_io/commproc.c Sun Jun 4 21:10:56 2000 @@ -94,9 +94,9 @@ */ host_buffer = host_page_addr; /* Host virtual page address */ host_end = host_page_addr + PAGE_SIZE; - pte = find_pte(&init_mm, host_page_addr); + pte = va_to_pte(&init_mm, host_page_addr); pte_val(*pte) |= _PAGE_NO_CACHE; - flush_tlb_page(current->mm->mmap, host_buffer); + flush_tlb_page(init_mm.mmap, host_buffer); /* Tell everyone where the comm processor resides. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/8xx_io/enet.c linux.ac/arch/ppc/8xx_io/enet.c --- linux.vanilla/arch/ppc/8xx_io/enet.c Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/8xx_io/enet.c Sun Jun 4 21:10:56 2000 @@ -402,6 +402,7 @@ * full. */ if (cep->tx_full) { + cep->tx_full = 0; if (netif_queue_stopped(dev)) netif_wake_queue(dev); } @@ -835,7 +836,7 @@ /* Make it uncached. */ - pte = find_pte(&init_mm, mem_addr); + pte = va_to_pte(&init_mm, mem_addr); pte_val(*pte) |= _PAGE_NO_CACHE; flush_tlb_page(init_mm.mmap, mem_addr); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/8xx_io/fec.c linux.ac/arch/ppc/8xx_io/fec.c --- linux.vanilla/arch/ppc/8xx_io/fec.c Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/8xx_io/fec.c Sun Jun 4 21:10:56 2000 @@ -1,5 +1,5 @@ /* - * Fast Ethernet Controller (FECC) driver for Motorola MPC8xx. + * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) * * This version of the driver is specific to the FADS implementation, @@ -15,8 +15,17 @@ * will be much more memory efficient and will easily handle lots of * small packets. * + * Much better multiple PHY support by Magnus Damm. + * Copyright (c) 2000 Ericsson Radio Systems AB. + * */ -#include + +/* List of PHYs we wish to support. +*/ +#define CONFIG_FEC_LXT970 +#define CONFIG_FEC_LXT971 +#define CONFIG_FEC_QS6612 + #include #include #include @@ -31,6 +40,10 @@ #include #include #include +#include +#ifdef CONFIG_FEC_PACKETHOOK +#include +#endif #include #include @@ -40,6 +53,24 @@ #include #include "commproc.h" +/* Forward declarations of some structures to support different PHYs +*/ + +typedef struct { + uint mii_data; + void (*funct)(uint mii_reg, struct net_device *dev); +} phy_cmd_t; + +typedef struct { + uint id; + char *name; + + const phy_cmd_t *config; + const phy_cmd_t *startup; + const phy_cmd_t *ack_int; + const phy_cmd_t *shutdown; +} phy_info_t; + /* The number of Tx and Rx buffers. These are allocated from the page * pool. The code may assume these are power of two, so it it best * to keep them that size. @@ -103,20 +134,51 @@ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ scc_t *sccp; struct net_device_stats stats; - char tx_full; - unsigned long lock; + uint tx_full; + spinlock_t lock; + + uint phy_id; + uint phy_id_done; + uint phy_status; + uint phy_speed; + phy_info_t *phy; + struct tq_struct phy_task; + + uint sequence_done; + + uint phy_addr; + + int link; + int old_link; + int full_duplex; + +#ifdef CONFIG_FEC_PACKETHOOK + unsigned long ph_lock; + fec_ph_func *ph_rxhandler; + fec_ph_func *ph_txhandler; + __u16 ph_proto; + volatile __u32 *ph_regaddr; + void *ph_priv; +#endif }; static int fec_enet_open(struct net_device *dev); static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); -static int fec_enet_rx(struct net_device *dev); static void fec_enet_mii(struct net_device *dev); -static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); +static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); +#ifdef CONFIG_FEC_PACKETHOOK +static void fec_enet_tx(struct net_device *dev, __u32 regval); +static void fec_enet_rx(struct net_device *dev, __u32 regval); +#else +static void fec_enet_tx(struct net_device *dev); +static void fec_enet_rx(struct net_device *dev); +#endif static int fec_enet_close(struct net_device *dev); static struct net_device_stats *fec_enet_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); - -static ushort my_enet_addr[] = { 0x0800, 0x3e26, 0x1559 }; +static void fec_restart(struct net_device *dev, int duplex); +static void fec_stop(struct net_device *dev); +static ushort my_enet_addr[3]; /* MII processing. We keep this as simple as possible. Requests are * placed on the list (if there is room). When the request is finished @@ -124,91 +186,133 @@ */ typedef struct mii_list { uint mii_regval; - void (*mii_func)(int val); + void (*mii_func)(uint val, struct net_device *dev); struct mii_list *mii_next; } mii_list_t; -#define NMII 10 +#define NMII 20 mii_list_t mii_cmds[NMII]; mii_list_t *mii_free; mii_list_t *mii_head; mii_list_t *mii_tail; -static int mii_queue(int request, void (*func)(int)); +static int mii_queue(struct net_device *dev, int request, + void (*func)(uint, struct net_device *)); /* Make MII read/write commands for the FEC. */ #define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \ (VAL & 0xffff)) +#define mk_mii_end 0 -static int -fec_enet_open(struct net_device *dev) +/* Transmitter timeout. +*/ +#define TX_TIMEOUT (2*HZ) + +/* Register definitions for the PHY. +*/ + +#define MII_REG_CR 0 /* Control Register */ +#define MII_REG_SR 1 /* Status Register */ +#define MII_REG_PHYIR1 2 /* PHY Identification Register 1 */ +#define MII_REG_PHYIR2 3 /* PHY Identification Register 2 */ +#define MII_REG_ANAR 4 /* A-N Advertisement Register */ +#define MII_REG_ANLPAR 5 /* A-N Link Partner Ability Register */ +#define MII_REG_ANER 6 /* A-N Expansion Register */ +#define MII_REG_ANNPTR 7 /* A-N Next Page Transmit Register */ +#define MII_REG_ANLPRNPR 8 /* A-N Link Partner Received Next Page Reg. */ + +/* values for phy_status */ + +#define PHY_CONF_ANE 0x0001 /* 1 auto-negotiation enabled */ +#define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ +#define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ +#define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ +#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ +#define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ +#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ + +#define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ +#define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ +#define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ +#define PHY_STAT_SPMASK 0xf000 /* mask for speed */ +#define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ +#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ +#define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ +#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ + +#ifdef CONFIG_FEC_PACKETHOOK +int +fec_register_ph(struct net_device *dev, fec_ph_func *rxfun, fec_ph_func *txfun, + __u16 proto, volatile __u32 *regaddr, void *priv) { + struct fec_enet_private *fep; + int retval = 0; - /* I should reset the ring buffers here, but I don't yet know - * a simple way to do that. - */ + fep = dev->priv; + + if (test_and_set_bit(0, (void*)&fep->ph_lock) != 0) { + /* Someone is messing with the packet hook */ + return -EAGAIN; + } + if (fep->ph_rxhandler != NULL || fep->ph_txhandler != NULL) { + retval = -EBUSY; + goto out; + } + fep->ph_rxhandler = rxfun; + fep->ph_txhandler = txfun; + fep->ph_proto = proto; + fep->ph_regaddr = regaddr; + fep->ph_priv = priv; - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; + out: + fep->ph_lock = 0; - return 0; /* Always succeed */ + return retval; } -static int -fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv; - volatile cbd_t *bdp; - unsigned long flags; - /* Transmitter timeout, serious problems. */ - if (dev->tbusy) { - int tickssofar = jiffies - dev->trans_start; - if (tickssofar < 20) - return 1; - printk("%s: transmit timed out.\n", dev->name); - fep->stats.tx_errors++; -#ifndef final_version - { - int i; - cbd_t *bdp; - printk(" Ring data dump: cur_tx %x%s cur_rx %x.\n", - fep->cur_tx, fep->tx_full ? " (full)" : "", - fep->cur_rx); - bdp = fep->tx_bd_base; - for (i = 0 ; i < TX_RING_SIZE; i++) - printk("%04x %04x %08x\n", - bdp->cbd_sc, - bdp->cbd_datlen, - bdp->cbd_bufaddr); - bdp = fep->rx_bd_base; - for (i = 0 ; i < RX_RING_SIZE; i++) - printk("%04x %04x %08x\n", - bdp->cbd_sc, - bdp->cbd_datlen, - bdp->cbd_bufaddr); - } -#endif +int +fec_unregister_ph(struct net_device *dev) +{ + struct fec_enet_private *fep; + int retval = 0; - dev->tbusy=0; - dev->trans_start = jiffies; + fep = dev->priv; - return 0; + if (test_and_set_bit(0, (void*)&fep->ph_lock) != 0) { + /* Someone is messing with the packet hook */ + return -EAGAIN; } - /* Block a timer-based transmit from overlapping. This could better be - done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ - if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { - printk("%s: Transmitter access conflict.\n", dev->name); - return 1; - } + fep->ph_rxhandler = fep->ph_txhandler = NULL; + fep->ph_proto = 0; + fep->ph_regaddr = NULL; + fep->ph_priv = NULL; + + fep->ph_lock = 0; + + return retval; +} + +EXPORT_SYMBOL(fec_register_ph); +EXPORT_SYMBOL(fec_unregister_ph); + +#endif /* CONFIG_FEC_PACKETHOOK */ + +static int +fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct fec_enet_private *fep; + volatile fec_t *fecp; + volatile cbd_t *bdp; - if (test_and_set_bit(0, (void*)&fep->lock) != 0) { - printk("%s: tx queue lock!.\n", dev->name); - /* don't clear dev->tbusy flag. */ + fep = dev->priv; + fecp = (volatile fec_t*)dev->base_addr; + + if (!fep->link) { + /* Link is down or autonegotiation is in progress. */ return 1; } @@ -221,7 +325,6 @@ * This should not happen, since dev->tbusy should be set. */ printk("%s: tx queue full!.\n", dev->name); - fep->lock = 0; return 1; } #endif @@ -245,38 +348,85 @@ /* Push the data cache so the CPM does not get stale memory * data. */ - flush_dcache_range(skb->data, skb->data + skb->len); + flush_dcache_range((unsigned long)skb->data, + (unsigned long)skb->data + skb->len); + + spin_lock_irq(&fep->lock); - /* Send it on its way. Tell CPM its ready, interrupt when done, + /* Send it on its way. Tell FEC its ready, interrupt when done, * its the last BD of the frame, and to put the CRC on the end. */ - save_flags(flags); - cli(); - bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); + bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR + | BD_ENET_TX_LAST | BD_ENET_TX_TC); dev->trans_start = jiffies; - (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_x_des_active = 0x01000000; + + /* Trigger transmission start */ + fecp->fec_x_des_active = 0x01000000; /* If this was the last BD in the ring, start at the beginning again. */ - if (bdp->cbd_sc & BD_ENET_TX_WRAP) + if (bdp->cbd_sc & BD_ENET_TX_WRAP) { bdp = fep->tx_bd_base; - else + } else { bdp++; + } - fep->lock = 0; if (bdp->cbd_sc & BD_ENET_TX_READY) - fep->tx_full = 1; - else - dev->tbusy=0; - restore_flags(flags); + netif_stop_queue(dev); fep->cur_tx = (cbd_t *)bdp; + spin_unlock_irq(&fep->lock); + return 0; } +static void +fec_timeout(struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + + printk("%s: transmit timed out.\n", dev->name); + fep->stats.tx_errors++; +#ifndef final_version + { + int i; + cbd_t *bdp; + + printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n", + (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "", + (unsigned long)fep->dirty_tx, + (unsigned long)fep->cur_rx); + + bdp = fep->tx_bd_base; + printk(" tx: %u buffers\n", TX_RING_SIZE); + for (i = 0 ; i < TX_RING_SIZE; i++) { + printk(" %08x: %04x %04x %08x\n", + (uint) bdp, + bdp->cbd_sc, + bdp->cbd_datlen, + bdp->cbd_bufaddr); + bdp++; + } + + bdp = fep->rx_bd_base; + printk(" rx: %lu buffers\n", RX_RING_SIZE); + for (i = 0 ; i < RX_RING_SIZE; i++) { + printk(" %08x: %04x %04x %08x\n", + (uint) bdp, + bdp->cbd_sc, + bdp->cbd_datlen, + bdp->cbd_bufaddr); + bdp++; + } + } +#endif + if (!fep->tx_full) + netif_wake_queue(dev); +} + /* The interrupt handler. * This is called from the MPC core interrupt. */ @@ -284,136 +434,177 @@ fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) { struct net_device *dev = dev_id; - struct fec_enet_private *fep; - volatile cbd_t *bdp; - volatile fec_t *ep; + volatile fec_t *fecp; uint int_events; - int c=0; +#ifdef CONFIG_FEC_PACKETHOOK + struct fec_enet_private *fep = dev->priv; + __u32 regval; - fep = (struct fec_enet_private *)dev->priv; - ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); - if (dev->interrupt) - printk("%s: Re-entering the interrupt handler.\n", dev->name); - dev->interrupt = 1; + if (fep->ph_regaddr) regval = *fep->ph_regaddr; +#endif + + fecp = (volatile fec_t*)dev->base_addr; /* Get the interrupt events that caused us to be here. */ - while ((int_events = ep->fec_ievent) != 0) { - ep->fec_ievent = int_events; - if ((int_events & - (FEC_ENET_HBERR | FEC_ENET_BABR | - FEC_ENET_BABT | FEC_ENET_EBERR)) != 0) - printk("FEC ERROR %x\n", int_events); - - /* Handle receive event in its own function. - */ - if (int_events & (FEC_ENET_RXF | FEC_ENET_RXB)) - fec_enet_rx(dev_id); - - /* Transmit OK, or non-fatal error. Update the buffer descriptors. - * FEC handles all errors, we just discover them as part of the - * transmit process. - */ - if (int_events & (FEC_ENET_TXF | FEC_ENET_TXB)) { - bdp = fep->dirty_tx; - while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) { -#if 1 - if (bdp==fep->cur_tx) - break; + while ((int_events = fecp->fec_ievent) != 0) { + fecp->fec_ievent = int_events; + if ((int_events & (FEC_ENET_HBERR | FEC_ENET_BABR | + FEC_ENET_BABT | FEC_ENET_EBERR)) != 0) { + printk("FEC ERROR %x\n", int_events); + } + + /* Handle receive event in its own function. + */ + if (int_events & FEC_ENET_RXF) { +#ifdef CONFIG_FEC_PACKETHOOK + fec_enet_rx(dev, regval); +#else + fec_enet_rx(dev); +#endif + } + + /* Transmit OK, or non-fatal error. Update the buffer + descriptors. FEC handles all errors, we just discover + them as part of the transmit process. + */ + if (int_events & FEC_ENET_TXF) { +#ifdef CONFIG_FEC_PACKETHOOK + fec_enet_tx(dev, regval); +#else + fec_enet_tx(dev); #endif - if (++c>1) {/*we go here when an it has been lost*/}; + } + if (int_events & FEC_ENET_MII) { + fec_enet_mii(dev); + } + + } +} - if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ - fep->stats.tx_heartbeat_errors++; - if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ - fep->stats.tx_window_errors++; - if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ - fep->stats.tx_aborted_errors++; - if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ - fep->stats.tx_fifo_errors++; - if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ - fep->stats.tx_carrier_errors++; - fep->stats.tx_errors++; - - fep->stats.tx_packets++; - +static void +#ifdef CONFIG_FEC_PACKETHOOK +fec_enet_tx(struct net_device *dev, __u32 regval) +#else +fec_enet_tx(struct net_device *dev) +#endif +{ + struct fec_enet_private *fep; + volatile cbd_t *bdp; + struct sk_buff *skb; + + fep = dev->priv; + spin_lock(&fep->lock); + bdp = fep->dirty_tx; + + while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) { + if (bdp == fep->cur_tx && fep->tx_full == 0) break; + + skb = fep->tx_skbuff[fep->skb_dirty]; + /* Check for errors. */ + if (bdp->cbd_sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | + BD_ENET_TX_RL | BD_ENET_TX_UN | + BD_ENET_TX_CSL)) { + fep->stats.tx_errors++; + if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ + fep->stats.tx_heartbeat_errors++; + if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ + fep->stats.tx_window_errors++; + if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ + fep->stats.tx_aborted_errors++; + if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ + fep->stats.tx_fifo_errors++; + if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ + fep->stats.tx_carrier_errors++; + } else { +#ifdef CONFIG_FEC_PACKETHOOK + /* Packet hook ... */ + if (fep->ph_txhandler && + ((struct ethhdr *)skb->data)->h_proto + == fep->ph_proto) { + fep->ph_txhandler((__u8*)skb->data, skb->len, + regval, fep->ph_priv); + } +#endif + fep->stats.tx_packets++; + } + #ifndef final_version if (bdp->cbd_sc & BD_ENET_TX_READY) - printk("HEY! Enet xmit interrupt and TX_READY.\n"); + printk("HEY! Enet xmit interrupt and TX_READY.\n"); #endif /* Deferred means some collisions occurred during transmit, * but we eventually sent the packet OK. */ if (bdp->cbd_sc & BD_ENET_TX_DEF) - fep->stats.collisions++; + fep->stats.collisions++; /* Free the sk buffer associated with this last transmit. */ - dev_kfree_skb(fep->tx_skbuff[fep->skb_dirty]/*, FREE_WRITE*/); +#if 0 +printk("TXI: %x %x %x\n", bdp, skb, fep->skb_dirty); +#endif + dev_kfree_skb(skb/*, FREE_WRITE*/); + fep->tx_skbuff[fep->skb_dirty] = NULL; fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; /* Update pointer to next buffer descriptor to be transmitted. */ if (bdp->cbd_sc & BD_ENET_TX_WRAP) - bdp = fep->tx_bd_base; + bdp = fep->tx_bd_base; else - bdp++; + bdp++; /* Since we have freed up a buffer, the ring is no longer * full. */ - if (fep->tx_full && dev->tbusy) { - fep->tx_full = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + if (fep->tx_full) { + fep->tx_full = 0; + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); } - - fep->dirty_tx = (cbd_t *)bdp; -#if 0 - if (bdp==fep->cur_tx) - break; +#ifdef CONFIG_FEC_PACKETHOOK + /* Re-read register. Not exactly guaranteed to be correct, + but... */ + if (fep->ph_regaddr) regval = *fep->ph_regaddr; #endif - }/*while (bdp->cbd_sc&BD_ENET_TX_READY)==0*/ - } /* if tx events */ - - if (int_events & FEC_ENET_MII) - fec_enet_mii(dev_id); - - } /* while any events */ - - dev->interrupt = 0; - - return; + } + fep->dirty_tx = (cbd_t *)bdp; + spin_unlock(&fep->lock); } + /* During a receive, the cur_rx points to the current incoming buffer. * When we update through the ring, if the next incoming buffer has * not been given to the system, we just set the empty indicator, * effectively tossing the packet. */ -static int +static void +#ifdef CONFIG_FEC_PACKETHOOK +fec_enet_rx(struct net_device *dev, __u32 regval) +#else fec_enet_rx(struct net_device *dev) +#endif { struct fec_enet_private *fep; + volatile fec_t *fecp; volatile cbd_t *bdp; struct sk_buff *skb; ushort pkt_len; - volatile fec_t *ep; + __u8 *data; - fep = (struct fec_enet_private *)dev->priv; - ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); + fep = dev->priv; + fecp = (volatile fec_t*)dev->base_addr; /* First, grab all of the stats for the incoming packet. * These get messed up if we get called due to a busy condition. */ bdp = fep->cur_rx; -for (;;) { - if (bdp->cbd_sc & BD_ENET_RX_EMPTY) - break; - +while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { + #ifndef final_version /* Since we have allocated space to hold a complete frame, * the last indicator should be set. @@ -422,50 +613,77 @@ printk("FEC ENET: rcv is not +last\n"); #endif - /* Frame too long or too short. - */ - if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) - fep->stats.rx_length_errors++; - if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ - fep->stats.rx_frame_errors++; - if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ - fep->stats.rx_crc_errors++; - if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ - fep->stats.rx_crc_errors++; + /* Check for errors. */ + if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | + BD_ENET_RX_CR | BD_ENET_RX_OV)) { + fep->stats.rx_errors++; + if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { + /* Frame too long or too short. */ + fep->stats.rx_length_errors++; + } + if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ + fep->stats.rx_frame_errors++; + if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ + fep->stats.rx_crc_errors++; + if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ + fep->stats.rx_crc_errors++; + } /* Report late collisions as a frame error. * On this error, the BD is closed, but we don't know what we * have in the buffer. So, just drop this frame on the floor. */ if (bdp->cbd_sc & BD_ENET_RX_CL) { + fep->stats.rx_errors++; fep->stats.rx_frame_errors++; + goto rx_processing_done; } - else { - /* Process the incoming frame. - */ - fep->stats.rx_packets++; - pkt_len = bdp->cbd_datlen; - fep->stats.rx_bytes += pkt_len; + /* Process the incoming frame. + */ + fep->stats.rx_packets++; + pkt_len = bdp->cbd_datlen; + fep->stats.rx_bytes += pkt_len; + data = (__u8*)__va(bdp->cbd_bufaddr); + +#ifdef CONFIG_FEC_PACKETHOOK + /* Packet hook ... */ + if (fep->ph_rxhandler) { + if (((struct ethhdr *)data)->h_proto == fep->ph_proto) { + switch (fep->ph_rxhandler(data, pkt_len, regval, + fep->ph_priv)) { + case 1: + goto rx_processing_done; + break; + case 0: + break; + default: + fep->stats.rx_errors++; + goto rx_processing_done; + } + } + } - /* This does 16 byte alignment, exactly what we need. - */ - skb = dev_alloc_skb(pkt_len); + /* If it wasn't filtered - copy it to an sk buffer. */ +#endif - if (skb == NULL) { - printk("%s: Memory squeeze, dropping packet.\n", dev->name); - fep->stats.rx_dropped++; - } - else { - skb->dev = dev; - skb_put(skb,pkt_len); /* Make room */ - eth_copy_and_sum(skb, - (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len, 0); - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); - } + /* This does 16 byte alignment, exactly what we need. + */ + skb = dev_alloc_skb(pkt_len); + + if (skb == NULL) { + printk("%s: Memory squeeze, dropping packet.\n", dev->name); + fep->stats.rx_dropped++; + } else { + skb->dev = dev; + skb_put(skb,pkt_len); /* Make room */ + eth_copy_and_sum(skb, + (unsigned char *)__va(bdp->cbd_bufaddr), + pkt_len, 0); + skb->protocol=eth_type_trans(skb,dev); + netif_rx(skb); } + rx_processing_done: /* Clear the status flags for this buffer. */ @@ -487,9 +705,14 @@ * incoming frames. On a heavily loaded network, we should be * able to keep up at the expense of system resources. */ - ep->fec_r_des_active = 0x01000000; + fecp->fec_r_des_active = 0x01000000; #endif - } +#ifdef CONFIG_FEC_PACKETHOOK + /* Re-read register. Not exactly guaranteed to be correct, + but... */ + if (fep->ph_regaddr) regval = *fep->ph_regaddr; +#endif + } /* while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) */ fep->cur_rx = (cbd_t *)bdp; #if 0 @@ -500,12 +723,11 @@ * our way back to the interrupt return only to come right back * here. */ - ep->fec_r_des_active = 0x01000000; + fecp->fec_r_des_active = 0x01000000; #endif - - return 0; } + static void fec_enet_mii(struct net_device *dev) { @@ -524,7 +746,7 @@ } if (mip->mii_func != NULL) - (*(mip->mii_func))(mii_reg); + (*(mip->mii_func))(mii_reg, dev); mii_head = mip->mii_next; mip->mii_next = mii_free; @@ -535,12 +757,18 @@ } static int -mii_queue(int regval, void (*func)(int)) +mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *)) { + struct fec_enet_private *fep; unsigned long flags; mii_list_t *mip; int retval; + /* Add PHY address to register command. + */ + fep = dev->priv; + regval |= fep->phy_addr << 23; + retval = 0; save_flags(flags); @@ -569,199 +797,580 @@ return(retval); } -static void -mii_status(uint mii_reg) +static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) { - if (((mii_reg >> 18) & 0x1f) == 1) { - /* status register. - */ - printk("fec: "); - if (mii_reg & 0x0004) - printk("link up"); - else - printk("link down"); + int k; - if (mii_reg & 0x0010) - printk(",remote fault"); - if (mii_reg & 0x0020) - printk(",auto complete"); - printk("\n"); - } - if (((mii_reg >> 18) & 0x1f) == 0x14) { - /* Extended chip status register. - */ - printk("fec: "); - if (mii_reg & 0x0800) - printk("100 Mbps"); - else - printk("10 Mbps"); + if(!c) + return; - if (mii_reg & 0x1000) - printk(", Full-Duplex\n"); - else - printk(", Half-Duplex\n"); - } - if (((mii_reg >> 18) & 0x1f) == 0x1f) { - printk("fec: %x\n", mii_reg); - } + for(k = 0; (c+k)->mii_data != mk_mii_end; k++) + mii_queue(dev, (c+k)->mii_data, (c+k)->funct); } -static void -mii_startup_cmds(void) +static void mii_parse_sr(uint mii_reg, struct net_device *dev) { + struct fec_enet_private *fep = dev->priv; + volatile uint *s = &(fep->phy_status); - /* Read status registers to clear any pending interrupt. - */ - mii_queue(mk_mii_read(1), mii_status); -#ifndef CONFIG_RPXCLASSIC - mii_queue(mk_mii_read(18), mii_status); + *s &= ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC); - /* Read extended chip status register. - */ - mii_queue(mk_mii_read(0x14), mii_status); + if (mii_reg & 0x0004) + *s |= PHY_STAT_LINK; + if (mii_reg & 0x0010) + *s |= PHY_STAT_FAULT; + if (mii_reg & 0x0020) + *s |= PHY_STAT_ANC; +} - /* Enable Link status change interrupts. - */ - mii_queue(mk_mii_write(0x11, 0x0002), NULL); +static void mii_parse_cr(uint mii_reg, struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + volatile uint *s = &(fep->phy_status); -#ifdef CONFIG_FADS - /* FADS uses the TRSTE in the BCSR, which is kind of weird. - * This really controls the startup default configuration. - * Changing the state of TRSTE once powered up doesn't do - * anything, you have to whack the control register. - * This of course screws up any autoconfig that was done....... - */ - mii_queue(mk_mii_write(0, 0x1000), NULL); -#endif -#else - /* Experimenting with the QS6612 PHY....not done yet. - */ - mii_queue(mk_mii_read(31), mii_status); -#endif + *s &= ~(PHY_CONF_ANE | PHY_CONF_LOOP); + + if (mii_reg & 0x1000) + *s |= PHY_CONF_ANE; + if (mii_reg & 0x4000) + *s |= PHY_CONF_LOOP; } -/* This supports the mii_link interrupt below. - * We should get called three times. Once for register 1, once for - * register 18, and once for register 20. - */ -static uint mii_saved_reg1; +static void mii_parse_anar(uint mii_reg, struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + volatile uint *s = &(fep->phy_status); -static void -mii_relink(uint mii_reg) + *s &= ~(PHY_CONF_SPMASK); + + if (mii_reg & 0x0020) + *s |= PHY_CONF_10HDX; + if (mii_reg & 0x0040) + *s |= PHY_CONF_10FDX; + if (mii_reg & 0x0080) + *s |= PHY_CONF_100HDX; + if (mii_reg & 0x00100) + *s |= PHY_CONF_100FDX; +} +#if 0 +static void mii_disp_reg(uint mii_reg, struct net_device *dev) { - if (((mii_reg >> 18) & 0x1f) == 1) { - /* Just save the status register and get out. - */ - mii_saved_reg1 = mii_reg; - return; - } - if (((mii_reg >> 18) & 0x1f) == 18) { - /* Not much here, but has to be read to clear the - * interrupt condition. - */ - if ((mii_reg & 0x8000) == 0) - printk("fec: re-link and no IRQ?\n"); - if ((mii_reg & 0x4000) == 0) - printk("fec: no PHY power?\n"); - } - if (((mii_reg >> 18) & 0x1f) == 20) { - /* Extended chip status register. - * OK, now we have it all, so figure out what is going on. - */ - printk("fec: "); - if (mii_saved_reg1 & 0x0004) - printk("link up"); - else - printk("link down"); + printk("reg %u = 0x%04x\n", (mii_reg >> 18) & 0x1f, mii_reg & 0xffff); +} +#endif - if (mii_saved_reg1 & 0x0010) - printk(", remote fault"); - if (mii_saved_reg1 & 0x0020) - printk(", auto complete"); +/* ------------------------------------------------------------------------- */ +/* The Level one LXT970 is used by many boards */ - if (mii_reg & 0x0800) - printk(", 100 Mbps"); - else - printk(", 10 Mbps"); +#ifdef CONFIG_FEC_LXT970 + +#define MII_LXT970_MIRROR 16 /* Mirror register */ +#define MII_LXT970_IER 17 /* Interrupt Enable Register */ +#define MII_LXT970_ISR 18 /* Interrupt Status Register */ +#define MII_LXT970_CONFIG 19 /* Configuration Register */ +#define MII_LXT970_CSR 20 /* Chip Status Register */ + +static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + volatile uint *s = &(fep->phy_status); + *s &= ~(PHY_STAT_SPMASK); + + if (mii_reg & 0x0800) { + if (mii_reg & 0x1000) + *s |= PHY_STAT_100FDX; + else + *s |= PHY_STAT_100HDX; + } + else { if (mii_reg & 0x1000) - printk(", Full-Duplex\n"); + *s |= PHY_STAT_10FDX; else - printk(", Half-Duplex\n"); + *s |= PHY_STAT_10HDX; } } -/* This interrupt occurs when the LTX970 detects a link change. -*/ -static void -mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) -{ - struct net_device *dev = dev_id; - struct fec_enet_private *fep; - volatile fec_t *ep; - - fep = (struct fec_enet_private *)dev->priv; - ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); +static phy_info_t phy_info_lxt970 = { + 0x07810000, + "LXT970", - /* We need to sequentially read registers 1 and 18 to clear - * the interrupt. We don't need to do that here because this - * is an edge triggered interrupt that has already been acknowledged - * by the top level handler. We also read the extended status - * register 20. We just queue the commands and let them happen - * as part of the "normal" processing. - */ - mii_queue(mk_mii_read(1), mii_relink); -#ifndef CONFIG_RPXCLASSIC - - /* Unique to LevelOne PHY. - */ - mii_queue(mk_mii_read(18), mii_relink); - mii_queue(mk_mii_read(20), mii_relink); -#else + (const phy_cmd_t []) { /* config */ +#if 0 +// { mk_mii_write(MII_REG_ANAR, 0x0021), NULL }, - /* Unique to QS6612 PHY. - */ - mii_queue(mk_mii_read(6), mii_relink); - mii_queue(mk_mii_read(31), mii_relink); + /* Set default operation of 100-TX....for some reason + * some of these bits are set on power up, which is wrong. + */ + { mk_mii_write(MII_LXT970_CONFIG, 0), NULL }, #endif -} + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup - enable interrupts */ + { mk_mii_write(MII_LXT970_IER, 0x0002), NULL }, + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* ack_int */ + /* read SR and ISR to acknowledge */ + + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_LXT970_ISR), NULL }, -static int -fec_enet_close(struct net_device *dev) -{ - /* Don't know what to do yet. - */ + /* find out the current status */ + + { mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown - disable interrupts */ + { mk_mii_write(MII_LXT970_IER, 0x0000), NULL }, + { mk_mii_end, } + }, +}; + +#endif /* CONFIG_FEC_LXT970 */ - return 0; -} +/* ------------------------------------------------------------------------- */ +/* The Level one LXT971 is used on some of my custom boards */ -static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) -{ - struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv; +#ifdef CONFIG_FEC_LXT971 - return &fep->stats; -} +/* register definitions for the 971 */ -/* Set or clear the multicast filter for this adaptor. - * Skeleton taken from sunlance driver. - * The CPM Ethernet implementation allows Multicast as well as individual - * MAC address filtering. Some of the drivers check to make sure it is - * a group multicast address, and discard those that are not. I guess I - * will do the same for now, but just remove the test if you want - * individual filtering as well (do the upper net layers want or support - * this kind of feature?). +#define MII_LXT971_PCR 16 /* Port Control Register */ +#define MII_LXT971_SR2 17 /* Status Register 2 */ +#define MII_LXT971_IER 18 /* Interrupt Enable Register */ +#define MII_LXT971_ISR 19 /* Interrupt Status Register */ +#define MII_LXT971_LCR 20 /* LED Control Register */ +#define MII_LXT971_TCR 30 /* Transmit Control Register */ + +/* + * I had some nice ideas of running the MDIO faster... + * The 971 should support 8MHz and I tried it, but things acted really + * wierd, so 2.5 MHz ought to be enough for anyone... */ -static void set_multicast_list(struct net_device *dev) +static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev) { - struct fec_enet_private *fep; - struct dev_mc_list *dmi; - u_char *mcptr, *tdptr; - volatile fec_t *ep; - int i, j; + struct fec_enet_private *fep = dev->priv; + volatile uint *s = &(fep->phy_status); - fep = (struct fec_enet_private *)dev->priv; - ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); + *s &= ~(PHY_STAT_SPMASK); + + if (mii_reg & 0x4000) { + if (mii_reg & 0x0200) + *s |= PHY_STAT_100FDX; + else + *s |= PHY_STAT_100HDX; + } + else { + if (mii_reg & 0x0200) + *s |= PHY_STAT_10FDX; + else + *s |= PHY_STAT_10HDX; + } + if (mii_reg & 0x0008) + *s |= PHY_STAT_FAULT; +} + +static phy_info_t phy_info_lxt971 = { + 0x0001378e, + "LXT971", + + (const phy_cmd_t []) { /* config */ + /* limit to 10MBit because my protorype board + * doesn't work with 100. */ + + { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 MBit */ + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup - enable interrupts */ + { mk_mii_write(MII_LXT971_IER, 0x00f2), NULL }, + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ + + /* Somehow does the 971 tell me that the link is down + * the first read after power-up. + * read here to get a valid value in ack_int */ + + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* ack_int */ + /* find out the current status */ + + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 }, + + /* we only need to read ISR to acknowledge */ + + { mk_mii_read(MII_LXT971_ISR), NULL }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown - disable interrupts */ + { mk_mii_write(MII_LXT971_IER, 0x0000), NULL }, + { mk_mii_end, } + }, +}; + +#endif /* CONFIG_FEC_LXT970 */ + + +/* ------------------------------------------------------------------------- */ +/* The Quality Semiconductor QS6612 is used on the RPX CLLF */ + +#ifdef CONFIG_FEC_QS6612 + +/* register definitions */ + +#define MII_QS6612_MCR 17 /* Mode Control Register */ +#define MII_QS6612_FTR 27 /* Factory Test Register */ +#define MII_QS6612_MCO 28 /* Misc. Control Register */ +#define MII_QS6612_ISR 29 /* Interrupt Source Register */ +#define MII_QS6612_IMR 30 /* Interrupt Mask Register */ +#define MII_QS6612_PCR 31 /* 100BaseTx PHY Control Reg. */ + +static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + volatile uint *s = &(fep->phy_status); + + *s &= ~(PHY_STAT_SPMASK); + + switch((mii_reg >> 2) & 7) { + case 1: *s |= PHY_STAT_10HDX; break; + case 2: *s |= PHY_STAT_100HDX; break; + case 5: *s |= PHY_STAT_10FDX; break; + case 6: *s |= PHY_STAT_100FDX; break; + } +} + +static phy_info_t phy_info_qs6612 = { + 0x00181440, + "QS6612", + + (const phy_cmd_t []) { /* config */ +// { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 MBit */ + + /* The PHY powers up isolated on the RPX, + * so send a command to allow operation. + */ + + { mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL }, + + /* parse cr and anar to get some info */ + + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup - enable interrupts */ + { mk_mii_write(MII_QS6612_IMR, 0x003a), NULL }, + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* ack_int */ + + /* we need to read ISR, SR and ANER to acknowledge */ + + { mk_mii_read(MII_QS6612_ISR), NULL }, + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_REG_ANER), NULL }, + + /* read pcr to get info */ + + { mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown - disable interrupts */ + { mk_mii_write(MII_QS6612_IMR, 0x0000), NULL }, + { mk_mii_end, } + }, +}; + + +#endif /* CONFIG_FEC_QS6612 */ + + +static phy_info_t *phy_info[] = { + +#ifdef CONFIG_FEC_LXT970 + &phy_info_lxt970, +#endif /* CONFIG_FEC_LXT970 */ + +#ifdef CONFIG_FEC_LXT971 + &phy_info_lxt971, +#endif /* CONFIG_FEC_LXT971 */ + +#ifdef CONFIG_FEC_QS6612 + &phy_info_qs6612, +#endif /* CONFIG_FEC_LXT971 */ + + NULL +}; + +static void mii_display_status(struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + volatile uint *s = &(fep->phy_status); + + if (!fep->link && !fep->old_link) { + /* Link is still down - don't print anything */ + return; + } + + printk("%s: status: ", dev->name); + + if (!fep->link) { + printk("link down"); + } else { + printk("link up"); + + switch(*s & PHY_STAT_SPMASK) { + case PHY_STAT_100FDX: printk(", 100MBit Full Duplex"); break; + case PHY_STAT_100HDX: printk(", 100MBit Half Duplex"); break; + case PHY_STAT_10FDX: printk(", 10MBit Full Duplex"); break; + case PHY_STAT_10HDX: printk(", 10MBit Half Duplex"); break; + default: + printk(", Unknown speed/duplex"); + } + + if (*s & PHY_STAT_ANC) + printk(", auto-negotiation complete"); + } + + if (*s & PHY_STAT_FAULT) + printk(", remote fault"); + + printk(".\n"); +} + +static void mii_display_config(struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + volatile uint *s = &(fep->phy_status); + + printk("%s: config: auto-negotiation ", dev->name); + + if (*s & PHY_CONF_ANE) + printk("on"); + else + printk("off"); + + if (*s & PHY_CONF_100FDX) + printk(", 100FDX"); + if (*s & PHY_CONF_100HDX) + printk(", 100HDX"); + if (*s & PHY_CONF_10FDX) + printk(", 10FDX"); + if (*s & PHY_CONF_10HDX) + printk(", 10HDX"); + if (!(*s & PHY_CONF_SPMASK)) + printk(", No speed/duplex selected?"); + + if (*s & PHY_CONF_LOOP) + printk(", loopback enabled"); + + printk(".\n"); + + fep->sequence_done = 1; +} + +static void mii_relink(struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + int duplex; + + fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; + mii_display_status(dev); + fep->old_link = fep->link; + + if (fep->link) { + duplex = 0; + if (fep->phy_status + & (PHY_STAT_100FDX | PHY_STAT_10FDX)) + duplex = 1; + fec_restart(dev, duplex); + } + else + fec_stop(dev); + +#if 0 + enable_irq(fep->mii_irq); +#endif + +} + +static void mii_queue_relink(uint mii_reg, struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + + fep->phy_task.routine = (void *)mii_relink; + fep->phy_task.data = dev; + queue_task(&fep->phy_task, &tq_scheduler); +} + +static void mii_queue_config(uint mii_reg, struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + + fep->phy_task.routine = (void *)mii_display_config; + fep->phy_task.data = dev; + queue_task(&fep->phy_task, &tq_scheduler); +} + + + +phy_cmd_t phy_cmd_relink[] = { { mk_mii_read(MII_REG_CR), mii_queue_relink }, + { mk_mii_end, } }; +phy_cmd_t phy_cmd_config[] = { { mk_mii_read(MII_REG_CR), mii_queue_config }, + { mk_mii_end, } }; + + + +/* Read remainder of PHY ID. +*/ +static void +mii_discover_phy3(uint mii_reg, struct net_device *dev) +{ + struct fec_enet_private *fep; + int i; + + fep = dev->priv; + fep->phy_id |= (mii_reg & 0xffff); + printk("fec: Phy @ 0x%x, type 0x%08x\n", fep->phy_addr, fep->phy_id); + + for(i = 0; phy_info[i]; i++) + if(phy_info[i]->id == (fep->phy_id >> 4)) + break; + + if(!phy_info[i]) + panic("%s: PHY id 0x%08x is not supported!\n", + dev->name, fep->phy_id); + + fep->phy = phy_info[i]; + fep->phy_id_done = 1; +} + +/* Scan all of the MII PHY addresses looking for someone to respond + * with a valid ID. This usually happens quickly. + */ +static void +mii_discover_phy(uint mii_reg, struct net_device *dev) +{ + struct fec_enet_private *fep; + uint phytype; + + fep = dev->priv; + + if (fep->phy_addr < 32) { + if ((phytype = (mii_reg & 0xffff)) != 0xffff) { + + /* Got first part of ID, now get remainder. + */ + fep->phy_id = phytype << 16; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), + mii_discover_phy3); + } + else { + fep->phy_addr++; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), + mii_discover_phy); + } + } + else { + printk("FEC: No PHY device found.\n"); + } +} + +/* This interrupt occurs when the PHY detects a link change. +*/ +static void +#ifdef CONFIG_RPXCLASSIC +mii_link_interrupt(void *dev_id) +#else +mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) +#endif +{ + struct net_device *dev = dev_id; + struct fec_enet_private *fep = dev->priv; + +#if 0 + disable_irq(fep->mii_irq); /* disable now, enable later */ +#endif + + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ + +} + +static int +fec_enet_open(struct net_device *dev) +{ + struct fec_enet_private *fep = dev->priv; + + /* I should reset the ring buffers here, but I don't yet know + * a simple way to do that. + */ + + fep->sequence_done = 0; + fep->link = 0; + + if (fep->phy) { + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, fep->phy->config); + mii_do_cmd(dev, phy_cmd_config); /* display configuration */ + + while(!fep->sequence_done) + schedule(); + + mii_do_cmd(dev, fep->phy->startup); + netif_start_queue(dev); + return 0; /* Success */ + } + + return -ENODEV; /* No PHY we understand */ + +} + +static int +fec_enet_close(struct net_device *dev) +{ + /* Don't know what to do yet. + */ + netif_stop_queue(dev); + fec_stop(dev); + + return 0; +} + +static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) +{ + struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv; + + return &fep->stats; +} + +/* Set or clear the multicast filter for this adaptor. + * Skeleton taken from sunlance driver. + * The CPM Ethernet implementation allows Multicast as well as individual + * MAC address filtering. Some of the drivers check to make sure it is + * a group multicast address, and discard those that are not. I guess I + * will do the same for now, but just remove the test if you want + * individual filtering as well (do the upper net layers want or support + * this kind of feature?). + */ + +static void set_multicast_list(struct net_device *dev) +{ + struct fec_enet_private *fep; + volatile fec_t *ep; + + fep = (struct fec_enet_private *)dev->priv; + ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); if (dev->flags&IFF_PROMISC) { @@ -826,20 +1435,23 @@ struct net_device *dev; struct fec_enet_private *fep; int i, j; - unsigned char *eap; + unsigned char *eap, *iap; unsigned long mem_addr; pte_t *pte; volatile cbd_t *bdp; cbd_t *cbd_base; volatile immap_t *immap; volatile fec_t *fecp; - unsigned char *iap; bd_t *bd; - - bd = (bd_t *)__res; + extern uint _get_IMMR(void); +#ifdef CONFIG_RPXCLASSIC + unsigned char tmpaddr[6]; +#endif immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */ + bd = (bd_t *)__res; + /* Allocate some private information. */ fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL); @@ -856,47 +1468,27 @@ fecp->fec_ecntrl = 1; udelay(10); - /* Enable interrupts we wish to service. - */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); - - /* Clear any outstanding interrupt. - */ - fecp->fec_ievent = 0xffc0; - - fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; - - /* Right now, all of the boards supply the ethernet address in - * the board descriptor. If someone doesn't we can just use - * the hard coded address in this driver for testing (this is - * a Motorola address for a board I have, so it is unlikely to - * be used elsewhere). + /* Set the Ethernet address. If using multiple Enets on the 8xx, + * this needs some work to get unique addresses. */ - eap = (unsigned char *)&my_enet_addr[0]; -#if 1 + eap = (unsigned char *)my_enet_addr; iap = bd->bi_enetaddr; + +#ifdef CONFIG_RPXCLASSIC + /* The Embedded Planet boards have only one MAC address in + * the EEPROM, but can have two Ethernet ports. For the + * FEC port, we create another address by setting one of + * the address bits above something that would have (up to + * now) been allocated. + */ for (i=0; i<6; i++) - dev->dev_addr[i] = *eap++ = *iap++; -#else - for (i=0; i<6; i++) - dev->dev_addr[i] = *eap++; + tmpaddr[i] = *iap++; + tmpaddr[3] |= 0x80; + iap = tmpaddr; #endif - /* Set station address. - */ - fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1]; - fecp->fec_addr_high = my_enet_addr[2]; - - /* Reset all multicast. - */ - fecp->fec_hash_table_high = 0; - fecp->fec_hash_table_low = 0; - - /* Set maximum receive buffer size. - */ - fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; - fecp->fec_r_hash = PKT_MAXBUF_SIZE; + for (i=0; i<6; i++) + dev->dev_addr[i] = *eap++ = *iap++; /* Allocate memory for buffer descriptors. */ @@ -910,15 +1502,13 @@ /* Make it uncached. */ - pte = find_pte(&init_mm, (int)mem_addr); + pte = va_to_pte(&init_mm, mem_addr); pte_val(*pte) |= _PAGE_NO_CACHE; - flush_tlb_page(current->mm->mmap, mem_addr); + flush_tlb_page(init_mm.mmap, mem_addr); /* Set receive and transmit descriptor base. */ - fecp->fec_r_des_start = __pa(mem_addr); fep->rx_bd_base = cbd_base; - fecp->fec_x_des_start = __pa((unsigned long)(cbd_base + RX_RING_SIZE)); fep->tx_bd_base = cbd_base + RX_RING_SIZE; fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; @@ -937,9 +1527,9 @@ /* Make it uncached. */ - pte = find_pte(&init_mm, mem_addr); + pte = va_to_pte(&init_mm, mem_addr); pte_val(*pte) |= _PAGE_NO_CACHE; - flush_tlb_page(current->mm->mmap, mem_addr); + flush_tlb_page(init_mm.mmap, mem_addr); /* Initialize the BD for every fragment in the page. */ @@ -956,6 +1546,172 @@ bdp--; bdp->cbd_sc |= BD_SC_WRAP; +#ifdef CONFIG_FEC_PACKETHOOK + fep->ph_lock = 0; + fep->ph_rxhandler = fep->ph_txhandler = NULL; + fep->ph_proto = 0; + fep->ph_regaddr = NULL; + fep->ph_priv = NULL; +#endif + + /* Install our interrupt handler. + */ + if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0) + panic("Could not allocate FEC IRQ!"); +#ifdef CONFIG_RPXCLASSIC + /* Make Port C, bit 15 an input that causes interrupts. + */ + immap->im_ioport.iop_pcpar &= ~0x0001; + immap->im_ioport.iop_pcdir &= ~0x0001; + immap->im_ioport.iop_pcso &= ~0x0001; + immap->im_ioport.iop_pcint |= 0x0001; + cpm_install_handler(CPMVEC_PIO_PC15, mii_link_interrupt, dev); + + /* Make LEDS reflect Link status. + */ + *((uint *) RPX_CSR_ADDR) &= ~BCSR2_FETHLEDMODE; +#endif +#ifdef CONFIG_FADS + if (request_8xxirq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0) + panic("Could not allocate MII IRQ!"); +#endif + + dev->base_addr = (unsigned long)fecp; + dev->priv = fep; + + /* The FEC Ethernet specific entries in the device structure. */ + dev->open = fec_enet_open; + dev->hard_start_xmit = fec_enet_start_xmit; + dev->tx_timeout = fec_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + dev->stop = fec_enet_close; + dev->get_stats = fec_enet_get_stats; + dev->set_multicast_list = set_multicast_list; + + for (i=0; iim_ioport.iop_pdpar = 0x1fff; + + /* Bits moved from Rev. D onward. + */ + if ((_get_IMMR() & 0xffff) < 0x0501) + immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */ + else + immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */ + + /* Set MII speed to 2.5 MHz + */ + fecp->fec_mii_speed = fep->phy_speed = + ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e; + + printk("%s: FEC ENET Version 0.2, ", dev->name); + for (i=0; i<5; i++) + printk("%02x:", dev->dev_addr[i]); + printk("%02x\n", dev->dev_addr[5]); + + /* Queue up command to detect the PHY and initialize the + * remainder of the interface. + */ + fep->phy_id_done = 0; + fep->phy_addr = 0; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); + + return 0; +} + +/* This function is called to start or restart the FEC during a link + * change. This only happens when switching between half and full + * duplex. + */ +static void +fec_restart(struct net_device *dev, int duplex) +{ + struct fec_enet_private *fep; + int i; + unsigned char *eap; + volatile cbd_t *bdp; + volatile immap_t *immap; + volatile fec_t *fecp; + + immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */ + + fecp = &(immap->im_cpm.cp_fec); + + fep = dev->priv; + + /* Whack a reset. We should wait for this. + */ + fecp->fec_ecntrl = 1; + udelay(10); + + /* Enable interrupts we wish to service. + */ + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); + + /* Clear any outstanding interrupt. + */ + fecp->fec_ievent = 0xffc0; + + fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; + + /* Set station address. + */ + fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1]; + fecp->fec_addr_high = my_enet_addr[2]; + + eap = (unsigned char *)&my_enet_addr[0]; + for (i=0; i<6; i++) + dev->dev_addr[i] = *eap++; + + /* Reset all multicast. + */ + fecp->fec_hash_table_high = 0; + fecp->fec_hash_table_low = 0; + + /* Set maximum receive buffer size. + */ + fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; + fecp->fec_r_hash = PKT_MAXBUF_SIZE; + + /* Set receive and transmit descriptor base. + */ + fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base)); + fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base)); + + fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; + fep->cur_rx = fep->rx_bd_base; + + /* Reset SKB transmit buffers. + */ + fep->skb_cur = fep->skb_dirty = 0; + for (i=0; i<=TX_RING_MOD_MASK; i++) { + if (fep->tx_skbuff[i] != NULL) { + dev_kfree_skb(fep->tx_skbuff[i]); + fep->tx_skbuff[i] = NULL; + } + } + + /* Initialize the receive buffer descriptors. + */ + bdp = fep->rx_bd_base; + for (i=0; icbd_sc = BD_ENET_RX_EMPTY; + bdp++; + } + + /* Set the last buffer to wrap. + */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + /* ...and the same for transmmit. */ bdp = fep->tx_bd_base; @@ -973,59 +1729,65 @@ bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* Enable MII mode, half-duplex until we know better.. + /* Enable MII mode. */ - fecp->fec_r_cntrl = 0x0c; - fecp->fec_x_cntrl = 0x00; + if (duplex) { + fecp->fec_r_cntrl = 0x04; /* MII enable */ + fecp->fec_x_cntrl = 0x04; /* FD enable */ + } + else { + fecp->fec_r_cntrl = 0x06; /* MII enable|No Rcv on Xmit */ + fecp->fec_x_cntrl = 0x00; + } + fep->full_duplex = duplex; /* Enable big endian and don't care about SDMA FC. */ fecp->fec_fun_code = 0x78000000; - /* Set MII speed (50 MHz core). + /* Set MII speed. */ - fecp->fec_mii_speed = 0x14; + fecp->fec_mii_speed = fep->phy_speed; - /* Configure all of port D for MII. + /* And last, enable the transmit and receive processing. */ - immap->im_ioport.iop_pdpar = 0x1fff; - immap->im_ioport.iop_pddir = 0x1c58; + fecp->fec_ecntrl = 6; + fecp->fec_r_des_active = 0x01000000; +} - /* Install our interrupt handlers. The 860T FADS board uses - * IRQ2 for the MII interrupt. - */ - if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0) - panic("Could not allocate FEC IRQ!"); - if (request_8xxirq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0) - panic("Could not allocate MII IRQ!"); +static void +fec_stop(struct net_device *dev) +{ + volatile immap_t *immap; + volatile fec_t *fecp; + struct fec_enet_private *fep; - dev->base_addr = (unsigned long)fecp; - dev->priv = fep; - dev->name = "fec"; + immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */ + + fecp = &(immap->im_cpm.cp_fec); + + fep = dev->priv; - /* The FEC Ethernet specific entries in the device structure. */ - dev->open = fec_enet_open; - dev->hard_start_xmit = fec_enet_start_xmit; - dev->stop = fec_enet_close; - dev->get_stats = fec_enet_get_stats; - dev->set_multicast_list = set_multicast_list; - /* And last, enable the transmit and receive processing. - */ - fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0x01000000; + fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ - printk("FEC ENET Version 0.1, "); - for (i=0; i<5; i++) - printk("%02x:", dev->dev_addr[i]); - printk("%02x\n", dev->dev_addr[5]); + while(!(fecp->fec_ievent & 0x10000000)); - for (i=0; ifec_ecntrl = 1; + udelay(10); + + /* Clear outstanding MII command interrupts. + */ + fecp->fec_ievent = FEC_ENET_MII; - mii_startup_cmds(); + /* Enable MII command finihed interrupt + */ + fecp->fec_ivec = (FEC_INTERRUPT/2) << 29; + fecp->fec_imask = FEC_ENET_MII; - return 0; + /* Set MII speed. + */ + fecp->fec_mii_speed = fep->phy_speed; } - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/8xx_io/uart.c linux.ac/arch/ppc/8xx_io/uart.c --- linux.vanilla/arch/ppc/8xx_io/uart.c Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/8xx_io/uart.c Sun Jun 4 21:10:56 2000 @@ -101,11 +101,15 @@ */ #define smc_scc_num hub6 +#ifdef CONFIG_8xxSMC2 /* SMC2 is sometimes used for low performance TDM interfaces. Define * this as 1 if you want SMC2 as a serial port UART managed by this driver. * Define this as 0 if you wish to use SMC2 for something else. */ #define USE_SMC2 1 +#else +#define USE_SMC2 0 +#endif /* Define SCC to ttySx mapping. */ @@ -130,7 +134,7 @@ #if USE_SMC2 { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */ #endif -#if defined(CONFIG_MPC860) || defined(CONFIG_MPC860T) +#ifdef CONFIG_8xxSCC { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, SCC_NUM_BASE}, /* SCC2 ttyS2 */ { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, SCC_NUM_BASE + 1}, /* SCC3 ttyS3 */ #endif 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 Sun Jun 4 21:10:56 2000 @@ -35,14 +35,6 @@ if [ "$CONFIG_8xx" = "y" ]; then define_bool CONFIG_SERIAL_CONSOLE y - choice 'Processor Model' \ - "821 CONFIG_MPC821 \ - 823 CONFIG_MPC823 \ - 850 CONFIG_MPC850 \ - 855 CONFIG_MPC855 \ - 860 CONFIG_MPC860 \ - 860T CONFIG_MPC860T" 860 - choice 'Machine Type' \ "RPX-Lite CONFIG_RPXLITE \ RPX-Classic CONFIG_RPXCLASSIC \ @@ -161,7 +153,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/ppc/kernel/entry.S linux.ac/arch/ppc/kernel/entry.S --- linux.vanilla/arch/ppc/kernel/entry.S Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/kernel/entry.S Sun Jun 4 21:10:56 2000 @@ -233,6 +233,8 @@ lwz r9,PGDIR(r4) /* cache the page table root */ tophys(r9,r9) /* convert to phys addr */ mtspr M_TWB,r9 /* Update MMU base address */ + tlbia + SYNC #endif /* CONFIG_8xx */ lwz r1,KSP(r4) /* Load new stack pointer */ /* save the old current 'last' for return value */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/head.S linux.ac/arch/ppc/kernel/head.S --- linux.vanilla/arch/ppc/kernel/head.S Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/kernel/head.S Sun Jun 4 21:10:56 2000 @@ -1,7 +1,7 @@ /* * arch/ppc/kernel/head.S * - * $Id: head.S,v 1.154 1999/10/12 00:33:31 cort Exp $ + * $Id: head.S,v 1.4 2000/05/15 21:30:54 diekema Exp $ * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -221,6 +221,7 @@ mtspr DBAT0U,r11 /* bit in upper BAT register */ mtspr IBAT0L,r8 mtspr IBAT0U,r11 + #if 0 /* Useful debug code, please leave in for now so I don't have to * look at docs when I need to setup a BAT ... */ @@ -1453,6 +1454,7 @@ ori r3,r3,start_kernel@l mtspr SRR0,r3 mtspr SRR1,r4 + SYNC rfi /* enable MMU and jump to start_kernel */ @@ -1568,7 +1570,7 @@ mtlr r4 blr #endif - + /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the data segment, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/m8260_setup.c linux.ac/arch/ppc/kernel/m8260_setup.c --- linux.vanilla/arch/ppc/kernel/m8260_setup.c Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/kernel/m8260_setup.c Sun Jun 4 21:10:56 2000 @@ -167,9 +167,11 @@ bp = (bd_t *)__res; - len += sprintf(len+buffer,"clock\t\t: %dMHz\n" - "bus clock\t: %dMHz\n", + len += sprintf(len+buffer,"core clock\t: %d MHz\n" + "CPM clock\t: %d MHz\n" + "bus clock\t: %d MHz\n", bp->bi_intfreq /*/ 1000000*/, + bp->bi_cpmfreq /*/ 1000000*/, bp->bi_busfreq /*/ 1000000*/); return len; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/misc.S linux.ac/arch/ppc/kernel/misc.S --- linux.vanilla/arch/ppc/kernel/misc.S Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/kernel/misc.S Sun Jun 4 21:10:56 2000 @@ -650,6 +650,12 @@ _GLOBAL(_get_PVR) mfspr r3,PVR blr + +#ifdef CONFIG_8xx +_GLOBAL(_get_IMMR) + mfspr r3, 638 + blr +#endif _GLOBAL(_get_HID0) mfspr r3,HID0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/pmac_time.c linux.ac/arch/ppc/kernel/pmac_time.c --- linux.vanilla/arch/ppc/kernel/pmac_time.c Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/kernel/pmac_time.c Sun Jun 4 21:10:56 2000 @@ -28,6 +28,8 @@ #include "time.h" +extern rwlock_t xtime_lock; + /* Apparently the RTC stores seconds since 1 Jan 1904 */ #define RTC_OFFSET 2082844800 @@ -151,16 +153,21 @@ static int time_sleep_notify(struct pmu_sleep_notifier *self, int when) { static unsigned long time_diff; + unsigned long flags; switch (when) { case PBOOK_SLEEP_NOW: + read_lock_irqsave(&xtime_lock, flags); time_diff = xtime.tv_sec - pmac_get_rtc_time(); + read_unlock_irqrestore(&xtime_lock, flags); break; case PBOOK_WAKE: + write_lock_irqsave(&xtime_lock, flags); xtime.tv_sec = pmac_get_rtc_time() + time_diff; xtime.tv_usec = 0; set_dec(decrementer_count); last_rtc_update = xtime.tv_sec; + write_unlock_irqrestore(&xtime_lock, flags); break; } return PBOOK_SLEEP_OK; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/ppc_asm.h linux.ac/arch/ppc/kernel/ppc_asm.h --- linux.vanilla/arch/ppc/kernel/ppc_asm.h Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/kernel/ppc_asm.h Sun Jun 4 21:10:56 2000 @@ -73,9 +73,11 @@ /* * This instruction is not implemented on the PPC 603 or 601; however, on * the 403GCX and 405GP tlbia IS defined and tlbie is not. + * All of these instructions exist in the 8xx, they have magical powers, + * and they must be used. */ -#if !defined(CONFIG_4xx) +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) #define tlbia \ li r4,128; \ mtctr r4; \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/ppc_ksyms.c linux.ac/arch/ppc/kernel/ppc_ksyms.c --- linux.vanilla/arch/ppc/kernel/ppc_ksyms.c Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/kernel/ppc_ksyms.c Sun Jun 4 21:10:56 2000 @@ -267,6 +267,7 @@ EXPORT_SYMBOL(decrementer_count); EXPORT_SYMBOL(get_wchan); EXPORT_SYMBOL(console_drivers); +EXPORT_SYMBOL(console_lock); #ifdef CONFIG_XMON EXPORT_SYMBOL(xmon); #endif @@ -287,3 +288,4 @@ EXPORT_SYMBOL(debugger_fault_handler); EXPORT_SYMBOL(ret_to_user_hook); +EXPORT_SYMBOL(do_softirq); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/time.c linux.ac/arch/ppc/kernel/time.c --- linux.vanilla/arch/ppc/kernel/time.c Thu May 25 17:38:30 2000 +++ linux.ac/arch/ppc/kernel/time.c Sun Jun 4 21:10:56 2000 @@ -50,6 +50,7 @@ /* keep track of when we need to update the rtc */ time_t last_rtc_update = 0; +extern rwlock_t xtime_lock; /* The decrementer counts down by 128 every 128ns on a 601. */ #define DECREMENTER_COUNT_601 (1000000000 / HZ) @@ -69,6 +70,7 @@ int timer_interrupt(struct pt_regs * regs) { int dval, d; + unsigned long flags; unsigned long cpu = smp_processor_id(); hardirq_enter(cpu); @@ -102,7 +104,6 @@ while ((d = get_dec()) == dval) ; asm volatile("mftb %0" : "=r" (last_tb) ); - /* * Don't play catchup between the call to time_init() * and sti() in init/main.c. @@ -122,6 +123,7 @@ /* * update the rtc when needed */ + read_lock_irqsave(&xtime_lock, flags); if ( (time_status & STA_UNSYNC) && ((xtime.tv_sec > last_rtc_update + 60) || (xtime.tv_sec < last_rtc_update)) ) @@ -132,6 +134,7 @@ /* do it again in 60 s */ last_rtc_update = xtime.tv_sec; } + read_unlock_irqrestore(&xtime_lock, flags); } #ifdef CONFIG_SMP smp_local_timer_interrupt(regs); @@ -153,17 +156,18 @@ save_flags(flags); cli(); + read_lock_irqsave(&xtime_lock, flags); *tv = xtime; + read_unlock_irqrestore(&xtime_lock, flags); /* XXX we don't seem to have the decrementers synced properly yet */ #ifndef CONFIG_SMP asm volatile("mftb %0" : "=r" (diff) ); diff -= last_tb; - tv->tv_usec += diff * count_period_num / count_period_den; tv->tv_sec += tv->tv_usec / 1000000; tv->tv_usec = tv->tv_usec % 1000000; #endif - + restore_flags(flags); } @@ -177,8 +181,10 @@ frac_tick = tv->tv_usec % (1000000 / HZ); save_flags(flags); cli(); + write_lock_irqsave(&xtime_lock, flags); xtime.tv_sec = tv->tv_sec; xtime.tv_usec = tv->tv_usec - frac_tick; + write_unlock_irqrestore(&xtime_lock, flags); set_dec(frac_tick * count_period_den / count_period_num); time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; @@ -191,6 +197,7 @@ void __init time_init(void) { + unsigned long flags; if (ppc_md.time_init != NULL) { ppc_md.time_init(); @@ -205,8 +212,10 @@ ppc_md.calibrate_decr(); } - xtime.tv_sec = ppc_md.get_rtc_time(); - xtime.tv_usec = 0; + write_lock_irqsave(&xtime_lock, flags); + xtime.tv_sec = ppc_md.get_rtc_time(); + xtime.tv_usec = 0; + write_unlock_irqrestore(&xtime_lock, flags); set_dec(decrementer_count); /* allow setting the time right away */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/mbxboot/Makefile linux.ac/arch/ppc/mbxboot/Makefile --- linux.vanilla/arch/ppc/mbxboot/Makefile Thu May 25 17:38:31 2000 +++ linux.ac/arch/ppc/mbxboot/Makefile Sun Jun 4 21:10:57 2000 @@ -28,14 +28,14 @@ TFTPIMAGE=/tftpboot/zImage.embedded ifdef CONFIG_8xx -ZLINKFLAGS = -T vmlinux.lds -Ttext 0x00180000 -OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o gzimage.o rdimage.o +ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00180000 +OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8xx endif ifdef CONFIG_8260 -ZLINKFLAGS = -T vmlinux.lds -Ttext 0x00400000 -OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o gzimage.o rdimage.o +ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00400000 +OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8260 endif @@ -61,32 +61,21 @@ all: zImage zvmlinux.initrd: zvmlinux -# -# Build the boot loader images -# - $(OBJCOPY) $(OBJCOPY_ARGS) -R .gzimage gzimage.o - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=.gzimage=../coffboot/vmlinux.gz \ - --set-section-flags=.gzimage=alloc,load,readonly,data \ - gzimage.o - $(OBJCOPY) $(OBJCOPY_ARGS) -R .rdimage rdimage.o + $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp1 $(OBJECTS) $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=.rdimage=ramdisk.image.gz \ - --set-section-flags=.rdimage=alloc,load,readonly,data \ - rdimage.o - $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS) -# -# Compute the sizes/offsets for the final image, and rebuild with these values. -# - $(CC) $(CFLAGS) \ - -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd .rdimage` \ - -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd .rdimage` \ - -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd .gzimage` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd .gzimage` \ + --add-section=initrd=ramdisk.image.gz \ + --add-section=image=../coffboot/vmlinux.gz \ + zvmlinux.initrd.tmp1 zvmlinux.initrd1 + $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 initrd` \ + -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 initrd` \ + -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 image` \ + -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 image` \ -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment $@ - $(OBJDUMP) -h $@ + $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=ramdisk.image.gz \ + --add-section=image=../coffboot/vmlinux.gz \ + zvmlinux.initrd.tmp $@ zImage: zvmlinux ln -sf zvmlinux zImage @@ -96,27 +85,23 @@ zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz # -# Build the boot loader images -# -# - $(OBJCOPY) $(OBJCOPY_ARGS) -R .gzimage gzimage.o - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=.gzimage=../coffboot/vmlinux.gz \ - --set-section-flags=.gzimage=alloc,load,readonly,data \ - gzimage.o - $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS) -# -# Compute the sizes/offsets for the final image, and rebuild with these values. +# build the boot loader image and then compute the offset into it +# for the kernel image # - $(CC) $(CFLAGS) \ - -DINITRD_OFFSET=0 \ - -DINITRD_SIZE=0 \ - -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux .gzimage` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux .gzimage` \ + $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ + zvmlinux.tmp $@ +# +# then with the offset rebuild the bootloader so we know where the kernel is +# + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux image` \ + -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \ -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o $@ $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment $@ - $(OBJDUMP) -h $@ + $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ + zvmlinux.tmp $@ + rm zvmlinux.tmp znetboot : zImage cp zImage $(TFTPIMAGE) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/mbxboot/embed_config.c linux.ac/arch/ppc/mbxboot/embed_config.c --- linux.vanilla/arch/ppc/mbxboot/embed_config.c Thu May 25 17:38:32 2000 +++ linux.ac/arch/ppc/mbxboot/embed_config.c Sun Jun 4 21:10:57 2000 @@ -3,7 +3,7 @@ * not have boot monitor support for board information. */ #include -#include +#include #ifdef CONFIG_8xx #include #endif @@ -231,17 +231,17 @@ u_char *cp; int i; -#if 1 +#if 0 /* This is actually provided by my boot rom. I have it * here for those people that may load the kernel with * a JTAG/COP tool and not the rom monitor. */ - bd->bi_baudrate = 19200; - bd->bi_intfreq = 165; - bd->bi_busfreq = 33; - bd->bi_cpmfreq = 132; - bd->bi_brgfreq = bd->bi_cpmfreq / 2; /* BRGCLK = (CPM*2/4) */ - bd->bi_memsize = 16 * 1024 * 1024; + bd->bi_baudrate = 115200; + bd->bi_intfreq = 200; + bd->bi_busfreq = 66; + bd->bi_cpmfreq = 66; + bd->bi_brgfreq = 33; + bd->bi_memsize = 16 * 1024 * 1024; #endif cp = (u_char *)def_enet_addr; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/mbxboot/head_8260.S linux.ac/arch/ppc/mbxboot/head_8260.S --- linux.vanilla/arch/ppc/mbxboot/head_8260.S Thu May 25 17:38:32 2000 +++ linux.ac/arch/ppc/mbxboot/head_8260.S Sun Jun 4 21:10:57 2000 @@ -101,6 +101,11 @@ subi r1,r1,256 li r2,0x000F /* Mask pointer to 16-byte boundary */ andc r1,r1,r2 + + /* Speed us up a little. + */ + bl flush_instruction_cache + /* Run loader */ mr r3,r8 /* Load point */ mr r4,r7 /* Program length */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/mbxboot/m8260_tty.c linux.ac/arch/ppc/mbxboot/m8260_tty.c --- linux.vanilla/arch/ppc/mbxboot/m8260_tty.c Thu May 25 17:38:32 2000 +++ linux.ac/arch/ppc/mbxboot/m8260_tty.c Sun Jun 4 21:10:57 2000 @@ -72,8 +72,8 @@ */ up->smc_rbase = dpaddr; up->smc_tbase = dpaddr+sizeof(cbd_t); - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; + up->smc_rfcr = CPMFCR_EB; + up->smc_tfcr = CPMFCR_EB; up->smc_brklen = 0; up->smc_brkec = 0; up->smc_brkcr = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/mbxboot/mbxtty.c linux.ac/arch/ppc/mbxboot/mbxtty.c --- linux.vanilla/arch/ppc/mbxboot/mbxtty.c Thu May 25 17:38:32 2000 +++ linux.ac/arch/ppc/mbxboot/mbxtty.c Thu Jan 1 01:00:00 1970 @@ -1,201 +0,0 @@ - - -/* Minimal serial functions needed to send messages out the serial - * port on the MBX console. - * - * The MBX uxes SMC1 for the serial port. We reset the port and use - * only the first BD that EPPC-Bug set up as a character FIFO. - * - * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug - * use COM1 instead of SMC1 as the console port. This kinda sucks - * for the rest of the kernel, so here we force the use of SMC1 again. - * I f**ked around for a day trying to figure out how to make EPPC-Bug - * use SMC1, but gave up and decided to fix it here. - */ -#include -#include -#ifdef CONFIG_MBX -#include -#endif -#ifdef CONFIG_FADS -#include -#endif -#include "../8xx_io/commproc.h" - -#ifdef CONFIG_MBX -#define MBX_CSR1 ((volatile u_char *)0xfa100000) -#define CSR1_COMEN (u_char)0x02 -#endif - -static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); - -void -serial_init(bd_t *bd) -{ - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile cbd_t *tbdf, *rbdf; - volatile cpm8xx_t *cp; - uint dpaddr, memaddr; - - cp = cpmp; - sp = (smc_t*)&(cp->cp_smc[0]); - up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1]; - - /* Disable transmitter/receiver. - */ - sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - -#ifdef CONFIG_MBX - if (*MBX_CSR1 & CSR1_COMEN) { - /* COM1 is enabled. Initialize SMC1 and use it for - * the console port. - */ - - /* Enable SDMA. - */ - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; - - /* Use Port B for SMCs instead of other functions. - */ - cp->cp_pbpar |= 0x00000cc0; - cp->cp_pbdir &= ~0x00000cc0; - cp->cp_pbodr &= ~0x00000cc0; - - /* Allocate space for two buffer descriptors in the DP ram. - * For now, this address seems OK, but it may have to - * change with newer versions of the firmware. - */ - dpaddr = 0x0800; - - /* Grab a few bytes from the top of memory. EPPC-Bug isn't - * running any more, so we can do this. - */ - memaddr = (bd->bi_memsize - 32) & ~15; - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; - rbdf->cbd_bufaddr = memaddr; - rbdf->cbd_sc = 0; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = memaddr+4; - tbdf->cbd_sc = 0; - - /* Set up the uart parameters in the parameter ram. - */ - up->smc_rbase = dpaddr; - up->smc_tbase = dpaddr+sizeof(cbd_t); - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Mask all interrupts and remove anything pending. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* Set up the baud rate generator. - * See 8xx_io/commproc.c for details. - */ - cp->cp_simode = 0x10000000; - cp->cp_brgc1 = - ((((bd->bi_intfreq * 1000000)/16) / 9600) << 1) | CPM_BRG_EN; - - /* Enable SMC1 for console output. - */ - *MBX_CSR1 &= ~CSR1_COMEN; - } - else { -#endif - /* SMC1 is used as console port. - */ - tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; - rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; - - /* Issue a stop transmit, and wait for it. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, - CPM_CR_STOP_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); -#ifdef CONFIG_MBX - } -#endif - - /* Make the first buffer the only buffer. - */ - tbdf->cbd_sc |= BD_SC_WRAP; - rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; - - /* Single character receive. - */ - up->smc_mrblr = 1; - up->smc_maxidl = 0; - - /* Initialize Tx/Rx parameters. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Enable transmitter/receiver. - */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -} - -void -serial_putchar(const char c) -{ - volatile cbd_t *tbdf; - volatile char *buf; - volatile smc_uart_t *up; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; - tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; - - /* Wait for last character to go. - */ - buf = (char *)tbdf->cbd_bufaddr; - while (tbdf->cbd_sc & BD_SC_READY); - - *buf = c; - tbdf->cbd_datlen = 1; - tbdf->cbd_sc |= BD_SC_READY; -} - -char -serial_getc() -{ - volatile cbd_t *rbdf; - volatile char *buf; - volatile smc_uart_t *up; - char c; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; - rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; - - /* Wait for character to show up. - */ - buf = (char *)rbdf->cbd_bufaddr; - while (rbdf->cbd_sc & BD_SC_EMPTY); - c = *buf; - rbdf->cbd_sc |= BD_SC_EMPTY; - - return(c); -} - -int -serial_tstc() -{ - volatile cbd_t *rbdf; - volatile smc_uart_t *up; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; - rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; - - return(!(rbdf->cbd_sc & BD_SC_EMPTY)); -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/mm/fault.c linux.ac/arch/ppc/mm/fault.c --- linux.vanilla/arch/ppc/mm/fault.c Thu May 25 17:38:29 2000 +++ linux.ac/arch/ppc/mm/fault.c Sun Jun 4 21:10:57 2000 @@ -238,7 +238,7 @@ /* The pgtable.h claims some functions generically exist, but I * can't find them...... */ -pte_t *find_pte(struct mm_struct *mm, unsigned long address) +pte_t *va_to_pte(struct mm_struct *mm, unsigned long address) { pgd_t *dir; pmd_t *pmd; @@ -267,7 +267,7 @@ { pte_t *pte; - pte = find_pte(current->mm, address); + pte = va_to_pte(current->mm, address); if (pte) return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK-1))); return (0); 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/acorn/char/Makefile linux.ac/drivers/acorn/char/Makefile --- linux.vanilla/drivers/acorn/char/Makefile Thu May 25 17:38:12 2000 +++ linux.ac/drivers/acorn/char/Makefile Sun Jun 4 21:15:50 2000 @@ -18,7 +18,7 @@ # Object file lists. -obj-y := i2c.o pcf8583.o +obj-y := obj-m := obj-n := obj- := @@ -34,7 +34,8 @@ obj-$(CONFIG_ATOMWIDE_SERIAL) += serial-atomwide.o obj-$(CONFIG_DUALSP_SERIAL) += serial-dualsp.o -obj-y += $(obj-$(MACHINE)) +# Do the i2c and rtc last +obj-y += $(obj-$(MACHINE)) i2c.o pcf8583.o O_OBJS := $(filter-out $(export-objs), $(obj-y)) OX_OBJS := $(filter $(export-objs), $(obj-y)) 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/ll_rw_blk.c linux.ac/drivers/block/ll_rw_blk.c --- linux.vanilla/drivers/block/ll_rw_blk.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/block/ll_rw_blk.c Wed May 31 11:45:14 2000 @@ -411,6 +411,7 @@ drive_stat_acct(req->rq_dev, req->cmd, req->nr_sectors, 1); + elevator_account_request(&q->elevator, req); if (list_empty(head)) { req->elevator_sequence = elevator_sequence(&q->elevator, latency); list_add(&req->queue, &q->queue_head); @@ -748,7 +749,6 @@ req->bhtail = bh; req->q = q; add_request(q, req, head, orig_latency); - elevator_account_request(elevator, req); spin_unlock_irqrestore(&io_request_lock, flags); return; 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/Config.in linux.ac/drivers/char/Config.in --- linux.vanilla/drivers/char/Config.in Thu May 25 17:46:15 2000 +++ linux.ac/drivers/char/Config.in Sun Jun 4 21:51:40 2000 @@ -206,7 +206,7 @@ fi comment 'Video Adapters' if [ "$CONFIG_I2C_ALGOBIT" = "y" -o "$CONFIG_I2C_ALGOBIT" = "m" ]; then - dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C_ALGOBIT $CONFIG_SOUND + dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C_ALGOBIT fi dep_tristate ' Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV if [ "$CONFIG_ALL_PPC" = "y" ]; then 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 Sun Jun 4 21:51:40 2000 @@ -134,40 +134,22 @@ 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 - -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 +# 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 + ifeq ($(CONFIG_RIO),y) - L_OBJS += rio/rio.o generic_serial.o SUB_DIRS += rio - MOD_SUB_DIRS += rio - GS = y -endif - -ifeq ($(CONFIG_SX),y) - L_OBJS += sx.o - GS = y +else + ifeq ($(CONFIG_RIO),m) + MOD_SUB_DIRS += rio + endif endif -obj-$(GS) += generic_serial.o - obj-$(CONFIG_ATIXL_BUSMOUSE) += atixlmouse.o obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o obj-$(CONFIG_PRINTER) += lp.o @@ -238,6 +220,7 @@ L_TUNERS=m endif endif +obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o obj-$(CONFIG_VIDEO_ZR36120) += zoran.o ifeq ($(CONFIG_VIDEO_ZR36120),y) 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/amikeyb.c linux.ac/drivers/char/amikeyb.c --- linux.vanilla/drivers/char/amikeyb.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/amikeyb.c Sun Jun 4 22:01:47 2000 @@ -186,8 +186,8 @@ kbd_pt_regs = NULL; + init_timer(&amikeyb_rep_timer); amikeyb_rep_timer.expires = jiffies + key_repeat_rate; - amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL; add_timer(&amikeyb_rep_timer); handle_scancode(rep_scancode, 1); @@ -254,8 +254,8 @@ } else { del_timer(&amikeyb_rep_timer); rep_scancode = keycode; + init_timer(&amikeyb_rep_timer); amikeyb_rep_timer.expires = jiffies + key_repeat_delay; - amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL; add_timer(&amikeyb_rep_timer); } handle_scancode(keycode, !break_flag); 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/bttv.c linux.ac/drivers/char/bttv.c --- linux.vanilla/drivers/char/bttv.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/char/bttv.c Sun Jun 4 21:51:40 2000 @@ -64,7 +64,6 @@ /* insmod args */ MODULE_PARM(triton1,"i"); -MODULE_PARM(remap,"1-4i"); MODULE_PARM(radio,"1-4i"); MODULE_PARM(card,"1-4i"); MODULE_PARM(pll,"1-4i"); @@ -76,6 +75,7 @@ MODULE_PARM(gbuffers,"i"); MODULE_PARM(gbufsize,"i"); +EXPORT_SYMBOL(bttv_get_cardinfo); EXPORT_SYMBOL(bttv_get_id); EXPORT_SYMBOL(bttv_gpio_enable); EXPORT_SYMBOL(bttv_read_gpio); @@ -91,7 +91,6 @@ static unsigned int bigendian=0; #endif static int triton1=0; -static unsigned long remap[BTTV_MAX]; static unsigned int radio[BTTV_MAX]; static unsigned int card[BTTV_MAX] = { 0, 0, 0, 0 }; static unsigned int pll[BTTV_MAX] = { -1, -1, -1, -1}; @@ -123,8 +122,19 @@ /* gpio ports (IR for example) */ /* see bttv.h for comments */ +int bttv_get_cardinfo(unsigned int card, int *type, int *cardid) +{ + if (card >= bttv_num) { + return -1; + } + *type = bttvs[card].type; + *cardid = bttvs[card].cardid; + return 0; +} + int bttv_get_id(unsigned int card) { + printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n"); if (card >= bttv_num) { return -1; } @@ -180,7 +190,7 @@ return 0; } -WAIT_QUEUE* bttv_get_gpio_queue(unsigned int card) +wait_queue_head_t* bttv_get_gpio_queue(unsigned int card) { struct bttv *btv; @@ -276,7 +286,7 @@ void * mem; unsigned long adr, page; - mem=vmalloc_32(size); + mem=vmalloc(size); if (mem) { memset(mem, 0, size); /* Clear the ram out, no junk to the user */ @@ -467,7 +477,7 @@ NULL }; -static int __init init_bttv_i2c(struct bttv *btv) +static int __devinit init_bttv_i2c(struct bttv *btv) { /* i2c bit_adapter */ memcpy(&btv->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter)); @@ -489,7 +499,7 @@ } /* read I2C */ -static int __init I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) +static int I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) { unsigned char buffer = 0; @@ -514,7 +524,7 @@ } /* write I2C */ -static int __init I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, +static int I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, unsigned char b2, int both) { unsigned char buffer[2]; @@ -531,7 +541,7 @@ } /* read EEPROM */ -static void __init readee(struct bttv *btv, unsigned char *eedata, int addr) +static void __devinit readee(struct bttv *btv, unsigned char *eedata, int addr) { int i; @@ -558,7 +568,7 @@ int id; char *name; } -hauppauge_tuner[] __initdata = +hauppauge_tuner[] __devinitdata = { { TUNER_ABSENT, "" }, { TUNER_ABSENT, "External" }, @@ -606,7 +616,7 @@ { TUNER_ABSENT, "Temic 4046FM5" }, }; -static void __init hauppauge_eeprom(struct bttv *btv) +static void __devinit hauppauge_eeprom(struct bttv *btv) { if (eeprom_data[9] < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { @@ -615,11 +625,9 @@ printk("bttv%d: Hauppauge eeprom: tuner=%s (%d)\n",btv->nr, hauppauge_tuner[eeprom_data[9]].name,btv->tuner_type); } - - return; } -static void __init hauppauge_boot_msp34xx(struct bttv *btv) +static void __devinit hauppauge_boot_msp34xx(struct bttv *btv) { int i; @@ -655,7 +663,7 @@ /* This is basically the same procedure as * used by Alessandro Rubini in his pxc200 * driver, but using BTTV functions */ -static void __init init_PXC200(struct bttv *btv) +static void __devinit init_PXC200(struct bttv *btv) { static const int vals[] = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, @@ -705,7 +713,7 @@ unsigned id; int cardnr; char *name; -} cards[] __initdata = { +} cards[] __devinitdata = { { 0x00011002, BTTV_HAUPPAUGE878, "ATI TV Wonder" }, { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, @@ -813,7 +821,7 @@ /* 0x10 */ { "Pixelview PlayTV (bt878)", - 3, 1, 0, 2, 0x01fe00, { 2, 0, 1, 1}, + 3, 1, 0, 2, 0x01fe00, { 2, 3, 1, 1}, { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },0, 1,1,1,1,0,0,0,1, PLL_28, -1 }, { "Leadtek WinView 601", @@ -910,10 +918,18 @@ { "ProVideo PV951", /* pic16c54 */ 3, 1, 0, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0},0, 0,0,0,0,0,0,0,0, PLL_28, 1 }, + { "Little OnAir TV", + 3, 1, 0, 2, 0xe00b, {2, 3, 1, 1}, + {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},0, + 0,0,0,0,0,0,0,0, PLL_NONE, -1 }, + + { "Sigma TVII-FM", + 2, 1, 0, -1, 3, {2, 3, 1, 1}, {1, 1, 0, 2, 3},0, + 0,0,0,0,0,0,0,0, PLL_NONE, -1 }, }; #define TVCARDS (sizeof(tvcards)/sizeof(struct tvcard)) -static void __init dump_eeprom(struct bttv *btv,int addr) +static void __devinit dump_eeprom(struct bttv *btv,int addr) { int i; @@ -930,7 +946,7 @@ } } -static int __init idcard_eeprom(struct bttv *btv) +static int __devinit idcard_eeprom(struct bttv *btv) { unsigned id; int i,n; @@ -943,6 +959,7 @@ return -1; /* look for the card */ + btv->cardid = id; for (n = -1, i = 0; cards[i].id != 0; i++) if (cards[i].id == id) n = i; @@ -1203,7 +1220,7 @@ unsigned int *po=(unsigned int *) btv->vbi_odd; unsigned int *pe=(unsigned int *) btv->vbi_even; - if (debug) + if (debug > 1) printk("bttv%d: vbi1: po=%08lx pe=%08lx\n", btv->nr,virt_to_bus(po), virt_to_bus(pe)); @@ -1225,7 +1242,7 @@ *(pe++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16)); *(pe++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+10)); - if (debug) + if (debug > 1) printk("bttv%d: vbi2: po=%08lx pe=%08lx\n", btv->nr,virt_to_bus(po), virt_to_bus(pe)); } @@ -1302,7 +1319,7 @@ unsigned long vadr=(unsigned long) vbuf; int shift, csize; - if (debug) + if (debug > 1) printk("bttv%d: prisc1: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); @@ -1399,7 +1416,7 @@ *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16)); *(re++)=cpu_to_le32(btv->bus_vbi_odd); - if (debug) + if (debug > 1) printk("bttv%d: prisc2: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); @@ -1424,7 +1441,7 @@ if (palette>=VIDEO_PALETTE_PLANAR) return make_prisctab(btv, ro, re, vbuf, width, height, palette); - if (debug) + if (debug > 1) printk("bttv%d: vrisc1: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); @@ -1476,7 +1493,7 @@ *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16)); *(re++)=cpu_to_le32(btv->bus_vbi_odd); - if (debug) + if (debug > 1) printk("bttv%d: vrisc2: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); @@ -1494,7 +1511,7 @@ int W, l, r; int i; - if (debug) + if (debug > 1) printk("bttv clip: %dx%d+%d+%d\n",w,h,x,y); /* bitmap is fixed width, 128 bytes (1024 pixels represented) */ @@ -1559,7 +1576,7 @@ inter=(btv->win.interlace&1)^1; width=btv->win.width; height=btv->win.height; - if (debug) + if (debug > 1) printk("bttv%d: clip1: pal=%d size=%dx%d, bpl=%d bpp=%d\n", btv->nr,btv->picture.palette,width,height,bpl,bpp); if(width > 1023) @@ -1668,7 +1685,7 @@ *(re++)=cpu_to_le32(BT848_RISC_JUMP); *(re++)=cpu_to_le32(btv->bus_vbi_odd); - if (debug) + if (debug > 1) printk("bttv%d: clip2: pal=%d size=%dx%d, bpl=%d bpp=%d\n", btv->nr,btv->picture.palette,width,height,bpl,bpp); } @@ -1734,9 +1751,6 @@ u16 ewidth, eheight, owidth, oheight; u16 format, bswap; struct tvnorm *tvn; - unsigned long flags; - - spin_lock_irqsave(&btv->s_lock, flags); tvn=&tvnorms[btv->win.norm]; @@ -1789,8 +1803,6 @@ btwrite(format, BT848_COLOR_FMT); btwrite(bswap | BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); - - spin_unlock_irqrestore(&btv->s_lock, flags); } @@ -1847,7 +1859,6 @@ /* * Grab into virtual memory. - * Currently only does double buffering. Do we need more? */ static int vgrab(struct bttv *btv, struct video_mmap *mp) @@ -1904,16 +1915,16 @@ btv->gbuf[mp->frame].ro = 0; #endif - if (btv->gq_in == btv->gq_out) { + if (-1 == btv->gq_grab && btv->gq_in == btv->gq_out) { btv->gq_start = 1; btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ); } btv->gqueue[btv->gq_in++] = mp->frame; btv->gq_in = btv->gq_in % MAX_GBUFFERS; - spin_unlock_irqrestore(&btv->s_lock, flags); btor(3, BT848_CAP_CTL); btor(3, BT848_GPIO_DMA_CTL); + spin_unlock_irqrestore(&btv->s_lock, flags); return 0; } @@ -1927,39 +1938,43 @@ { struct bttv *btv= (struct bttv *)v; int q,todo; + DECLARE_WAITQUEUE(wait, current); /* BROKEN: RETURNS VBI WHEN IT SHOULD RETURN GRABBED VIDEO FRAME */ todo=count; while (todo && todo>(q=VBIBUF_SIZE-btv->vbip)) { - unsigned long flags; - if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q)) return -EFAULT; todo-=q; buf+=q; - spin_lock_irqsave(&btv->s_lock, flags); + add_wait_queue(&btv->vbiq, &wait); + current->state = TASK_INTERRUPTIBLE; if (todo && q==VBIBUF_SIZE-btv->vbip) { if(nonblock) { - spin_unlock_irqrestore(&btv->s_lock, flags); + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; if(count==todo) return -EWOULDBLOCK; return count-todo; } - spin_unlock_irqrestore(&btv->s_lock, flags); - interruptible_sleep_on(&btv->vbiq); + schedule(); if(signal_pending(current)) { + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; + if(todo==count) return -EINTR; else return count-todo; } - } else - spin_unlock_irqrestore(&btv->s_lock, flags); + } + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; } if (todo) { @@ -1980,9 +1995,11 @@ static void bt848_restart(struct bttv *btv) { + unsigned long irq_flags; + if (verbose) printk("bttv%d: resetting chip\n",btv->nr); - btwrite(~0x0UL, BT848_INT_STAT); + btwrite(0xfffffUL, BT848_INT_STAT); btand(~15, BT848_GPIO_DMA_CTL); btwrite(0, BT848_SRESET); btwrite(virt_to_bus(btv->risc_jmp+2), @@ -1994,8 +2011,10 @@ btv->errors = 0; btv->needs_restart = 0; + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_geo(btv,0); bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); } /* @@ -2042,13 +2061,16 @@ static void bttv_close(struct video_device *dev) { struct bttv *btv=(struct bttv *)dev; + unsigned long irq_flags; down(&btv->lock); btv->user--; + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->scr_on = 0; btv->risc_cap_odd = 0; btv->risc_cap_even = 0; bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); /* * A word of warning. At this point the chip @@ -2133,9 +2155,11 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { struct bttv *btv=(struct bttv *)dev; + unsigned long irq_flags; int i,ret = 0; - if (debug) printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd); + if (debug > 1) + printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd); switch (cmd) { case VIDIOCGCAP: @@ -2206,7 +2230,9 @@ if (btv->win.norm != v.norm) { btv->win.norm = v.norm; make_vbitab(btv); + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_winsize(btv); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); } up(&btv->lock); return 0; @@ -2248,7 +2274,9 @@ down(&btv->lock); set_pll(btv); make_vbitab(btv); + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_winsize(btv); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); up(&btv->lock); } return 0; @@ -2289,12 +2317,13 @@ if(copy_from_user(&vw,arg,sizeof(vw))) return -EFAULT; + down(&btv->lock); if(vw.flags || vw.width < 16 || vw.height < 16) { - down(&btv->lock); + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->scr_on = 0; bt848_set_risc_jmps(btv,-1); - up(&btv->lock); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); return -EINVAL; } if (btv->win.bpp < 4) @@ -2302,18 +2331,17 @@ vw.x = (vw.x + 3) & ~3; vw.width &= ~3; } - down(&btv->lock); if (btv->needs_restart) bt848_restart(btv); btv->win.x=vw.x; btv->win.y=vw.y; btv->win.width=vw.width; btv->win.height=vw.height; - + + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_risc_jmps(btv,0); - bt848_set_winsize(btv); - up(&btv->lock); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); /* * Do any clips. @@ -2337,11 +2365,12 @@ return -EFAULT; } } - down(&btv->lock); make_clip_tab(btv, vcp, vw.clipcount); if (vw.clipcount != 0) vfree(vcp); + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); up(&btv->lock); return 0; } @@ -2370,13 +2399,13 @@ return -EINVAL; if (btv->win.width==0 || btv->win.height==0) return -EINVAL; - down(&btv->lock); + spin_lock_irqsave(&btv->s_lock, irq_flags); if (v == 1 && btv->win.vidadr != 0) btv->scr_on = 1; if (v == 0) btv->scr_on = 0; bt848_set_risc_jmps(btv,-1); - up(&btv->lock); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); return 0; } case VIDIOCGFBUF: @@ -2500,9 +2529,7 @@ if(!(v.flags&VIDEO_AUDIO_MUTE)) audio(btv, AUDIO_UNMUTE, 1); - up(&btv->lock); call_i2c_clients(btv,cmd,&v); - down(&btv->lock); if (btv->type == BTTV_TERRATV) { unsigned int con = 0; @@ -2554,6 +2581,9 @@ } case VIDIOCSYNC: + { + DECLARE_WAITQUEUE(wait, current); + if(copy_from_user((void *)&i,arg,sizeof(int))) return -EFAULT; if (i < 0 || i >= gbuffers) @@ -2563,13 +2593,20 @@ ret = -EINVAL; break; case GBUFFER_GRABBING: + add_wait_queue(&btv->capq, &wait); + current->state = TASK_INTERRUPTIBLE; while(btv->gbuf[i].stat==GBUFFER_GRABBING) { if (debug) printk("bttv%d: cap sync: sleep on %d\n",btv->nr,i); - interruptible_sleep_on(&btv->capq); - if(signal_pending(current)) + schedule(); + if(signal_pending(current)) { + remove_wait_queue(&btv->capq, &wait); + current->state = TASK_RUNNING; return -EINTR; + } } + remove_wait_queue(&btv->capq, &wait); + current->state = TASK_RUNNING; /* fall throuth */ case GBUFFER_DONE: case GBUFFER_ERROR: @@ -2584,6 +2621,7 @@ up(&btv->lock); } return ret; + } case BTTV_FIELDNR: if(copy_to_user((void *) arg, (void *) &btv->last_field, @@ -2602,7 +2640,6 @@ btv->pll.pll_ofreq = p.pll_ofreq; btv->pll.pll_crystal = p.pll_crystal; up(&btv->lock); - break; } @@ -2749,12 +2786,11 @@ { struct bttv *btv=(struct bttv *)(v-2); int q,todo; + DECLARE_WAITQUEUE(wait, current); todo=count; while (todo && todo>(q=VBIBUF_SIZE-btv->vbip)) { - unsigned long flags; - if (btv->needs_restart) { down(&btv->lock); bt848_restart(btv); @@ -2765,27 +2801,31 @@ todo-=q; buf+=q; - spin_lock_irqsave(&btv->s_lock, flags); + add_wait_queue(&btv->vbiq, &wait); + current->state = TASK_INTERRUPTIBLE; if (todo && q==VBIBUF_SIZE-btv->vbip) { if(nonblock) { - spin_unlock_irqrestore(&btv->s_lock, flags); + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; if(count==todo) return -EWOULDBLOCK; return count-todo; } - spin_unlock_irqrestore(&btv->s_lock, flags); - interruptible_sleep_on(&btv->vbiq); + schedule(); if(signal_pending(current)) { + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; if(todo==count) return -EINTR; else return count-todo; } - } else - spin_unlock_irqrestore(&btv->s_lock, flags); + } + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; } if (todo) { @@ -2813,15 +2853,18 @@ static int vbi_open(struct video_device *dev, int flags) { struct bttv *btv=(struct bttv *)(dev-2); + unsigned long irq_flags; MOD_INC_USE_COUNT; - down(&btv->lock); if (btv->needs_restart) bt848_restart(btv); + set_pll(btv); btv->vbip=VBIBUF_SIZE; + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->vbi_on = 1; bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); up(&btv->lock); return 0; @@ -2830,12 +2873,12 @@ static void vbi_close(struct video_device *dev) { struct bttv *btv=(struct bttv *)(dev-2); + unsigned long irq_flags; - down(&btv->lock); + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->vbi_on = 0; bt848_set_risc_jmps(btv,-1); - up(&btv->lock); - + spin_unlock_irqrestore(&btv->s_lock, irq_flags); MOD_DEC_USE_COUNT; } @@ -3018,7 +3061,7 @@ #define TRITON_PEER_CONCURRENCY (1<<3) -static void __init handle_chipset(void) +static void __devinit handle_chipset(void) { struct pci_dev *dev = NULL; @@ -3050,7 +3093,7 @@ /* can tda9855.c handle this too maybe? */ -static void __init init_tda9840(struct bttv *btv) +static void __devinit init_tda9840(struct bttv *btv) { /* Horrible Hack */ I2CWrite(btv, I2C_TDA9840, TDA9840_SW, 0x2a, 1); /* sound mode switching */ @@ -3066,12 +3109,11 @@ /* Figure out card and tuner type */ -static void __init idcard(struct bttv *btv) +static void __devinit idcard(struct bttv *btv) { int type,eeprom = 0; btwrite(0, BT848_GPIO_OUT_EN); - DEBUG(printk(KERN_DEBUG "bttv%d: GPIO: 0x%08x\n", btv->nr, btread(BT848_GPIO_DATA))); /* Default the card to the user-selected one. */ if (card[btv->nr] >= 0 && card[btv->nr] < TVCARDS) @@ -3114,7 +3156,6 @@ (btv->id==848 && btv->revision==0x12) ? "A" : "", tvcards[btv->type].name); printk(KERN_INFO "bttv%d: model: %s\n",btv->nr,btv->video_dev.name); - /* board specific initialisations */ if (btv->type == BTTV_MIRO || btv->type == BTTV_MIROPRO) { @@ -3228,10 +3269,6 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags) { - unsigned long irq_flags; - - spin_lock_irqsave(&btv->s_lock, irq_flags); - if (-1 == flags) { /* defaults */ flags = 0; @@ -3241,8 +3278,9 @@ flags |= 0x0c; } - if (debug) printk("bttv%d: set_risc_jmp %08lx:", - btv->nr,virt_to_bus(btv->risc_jmp)); + if (debug > 1) + printk("bttv%d: set_risc_jmp %08lx:", + btv->nr,virt_to_bus(btv->risc_jmp)); /* Sync to start of odd field */ btv->risc_jmp[0]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC @@ -3252,24 +3290,29 @@ /* Jump to odd vbi sub */ btv->risc_jmp[2]=cpu_to_le32(BT848_RISC_JUMP|(0xd<<20)); if (flags&8) { - if (debug) printk(" ev=%08lx",virt_to_bus(btv->vbi_odd)); + if (debug > 1) + printk(" ev=%08lx",virt_to_bus(btv->vbi_odd)); btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->vbi_odd)); } else { - if (debug) printk(" -----------"); + if (debug > 1) + printk(" -----------"); btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->risc_jmp+4)); } /* Jump to odd sub */ btv->risc_jmp[4]=cpu_to_le32(BT848_RISC_JUMP|(0xe<<20)); if (0 != btv->risc_cap_odd) { - if (debug) printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd); + if (debug > 1) + printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd); flags |= 3; btv->risc_jmp[5]=cpu_to_le32(btv->risc_cap_odd); } else if (flags&2) { - if (debug) printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd)); + if (debug > 1) + printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd)); btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_scr_odd)); } else { - if (debug) printk(" -----------"); + if (debug > 1) + printk(" -----------"); btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_jmp+6)); } @@ -3282,24 +3325,29 @@ /* Jump to even vbi sub */ btv->risc_jmp[8]=cpu_to_le32(BT848_RISC_JUMP); if (flags&4) { - if (debug) printk(" ov=%08lx",virt_to_bus(btv->vbi_even)); + if (debug > 1) + printk(" ov=%08lx",virt_to_bus(btv->vbi_even)); btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->vbi_even)); } else { - if (debug) printk(" -----------"); + if (debug > 1) + printk(" -----------"); btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->risc_jmp+10)); } /* Jump to even sub */ btv->risc_jmp[10]=cpu_to_le32(BT848_RISC_JUMP|(8<<20)); if (0 != btv->risc_cap_even) { - if (debug) printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even); + if (debug > 1) + printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even); flags |= 3; btv->risc_jmp[11]=cpu_to_le32(btv->risc_cap_even); } else if (flags&1) { - if (debug) printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even)); + if (debug > 1) + printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even)); btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_scr_even)); } else { - if (debug) printk(" -----------"); + if (debug > 1) + printk(" -----------"); btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_jmp+12)); } @@ -3311,18 +3359,17 @@ btv->risc_jmp[13]=cpu_to_le32(virt_to_bus(btv->risc_jmp)); /* enable cpaturing and DMA */ - if (debug) printk(" flags=0x%x dma=%s\n", - flags,(flags&0x0f) ? "on" : "off"); + if (debug > 1) + printk(" flags=0x%x dma=%s\n", + flags,(flags&0x0f) ? "on" : "off"); btaor(flags, ~0x0f, BT848_CAP_CTL); if (flags&0x0f) bt848_dma(btv, 3); else bt848_dma(btv, 0); - - spin_unlock_irqrestore(&btv->s_lock, irq_flags); } -static int __init init_video_dev(struct bttv *btv) +static int __devinit init_video_dev(struct bttv *btv) { memcpy(&btv->video_dev,&bttv_template, sizeof(bttv_template)); memcpy(&btv->vbi_dev,&vbi_template, sizeof(vbi_template)); @@ -3349,9 +3396,10 @@ return 1; } -static int __init init_bt848(struct bttv *btv) +static int __devinit init_bt848(struct bttv *btv) { int j; + unsigned long irq_flags; btv->user=0; init_MUTEX(&btv->lock); @@ -3412,7 +3460,6 @@ return -1; if (!(btv->risc_jmp =(unsigned int *) kmalloc(2048, GFP_KERNEL))) return -1; - DEBUG(printk(KERN_DEBUG "risc_jmp: %p\n",btv->risc_jmp)); btv->vbi_odd=btv->risc_jmp+16; btv->vbi_even=btv->vbi_odd+256; btv->bus_vbi_odd=virt_to_bus(btv->risc_jmp+12); @@ -3475,7 +3522,7 @@ btwrite(0x00, BT848_O_SCLOOP); /* clear interrupt status */ - btwrite(~0x0UL, BT848_INT_STAT); + btwrite(0xfffffUL, BT848_INT_STAT); /* set interrupt mask */ btwrite(btv->triton1| @@ -3489,8 +3536,10 @@ BT848_INT_MASK); make_vbitab(btv); + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_risc_jmps(btv,-1); - + spin_unlock_irqrestore(&btv->s_lock, irq_flags); + /* * Now add the template and register the device unit. */ @@ -3505,7 +3554,8 @@ u32 dstat; int count,i; struct bttv *btv; - + unsigned long irq_flags; + btv=(struct bttv *)dev_id; count=0; while (1) @@ -3515,6 +3565,7 @@ astat=stat&btread(BT848_INT_MASK); if (!astat) return; + btwrite(astat,BT848_INT_STAT); IDEBUG(printk ("bttv%d: astat=%08x\n", btv->nr, astat)); IDEBUG(printk ("bttv%d: stat=%08x\n", btv->nr, stat)); @@ -3550,15 +3601,18 @@ btread(BT848_RISC_COUNT)); btv->errors++; if (btv->errors < BTTV_ERRORS) { + spin_lock_irqsave(&btv->s_lock, irq_flags); btand(~15, BT848_GPIO_DMA_CTL); btwrite(virt_to_bus(btv->risc_jmp+2), BT848_RISC_STRT_ADD); bt848_set_geo(btv,0); bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); } else { if (verbose) printk("bttv%d: aiee: error loops\n",btv->nr); /* cancel all outstanding grab requests */ + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->gq_in = 0; btv->gq_out = 0; btv->gq_grab = -1; @@ -3569,8 +3623,9 @@ btv->risc_cap_odd = 0; btv->risc_cap_even = 0; bt848_set_risc_jmps(btv,0); - btv->needs_restart = 1; + spin_unlock_irqrestore(&btv->s_lock, irq_flags); + wake_up_interruptible(&btv->vbiq); wake_up_interruptible(&btv->capq); } @@ -3596,6 +3651,7 @@ if (debug) printk("bttv%d: cap irq: done %d\n",btv->nr,btv->gq_grab); do_gettimeofday(&btv->gbuf[btv->gq_grab].tv); + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->gbuf[btv->gq_grab].stat = GBUFFER_DONE; btv->gq_grab = -1; if (btv->gq_in != btv->gq_out) @@ -3618,22 +3674,25 @@ btwrite(btv->fb_color_ctl | BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); } + spin_unlock_irqrestore(&btv->s_lock, irq_flags); wake_up_interruptible(&btv->capq); break; } if (stat&(8<<28)) { + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->gq_start = 0; btv->gq_grab = btv->gqueue[btv->gq_out++]; btv->gq_out = btv->gq_out % MAX_GBUFFERS; if (debug) - printk("bttv%d: cap irq: capture %d\n",btv->nr,btv->gq_grab); + printk("bttv%d: cap irq: capture %d [start]\n",btv->nr,btv->gq_grab); btv->risc_cap_odd = btv->gbuf[btv->gq_grab].ro; btv->risc_cap_even = btv->gbuf[btv->gq_grab].re; bt848_set_risc_jmps(btv,-1); bt848_set_geo(btv,0); btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); } } if (astat&BT848_INT_OCERR) @@ -3676,9 +3735,6 @@ { IDEBUG(printk ("bttv%d: IRQ_I2CDONE\n", btv->nr)); } - - btwrite(astat,BT848_INT_STAT); - count++; if (count > 10) printk (KERN_WARNING "bttv%d: irq loop %d\n", @@ -3698,11 +3754,11 @@ * Scan for a Bt848 card, request the irq and map the io memory */ -static void __init bttv_remove(struct pci_dev *pci_dev) +static void __devinit bttv_remove(struct pci_dev *pci_dev) { u8 command; int j; - struct bttv *btv = pci_dev->driver_data; + struct bttv *btv = PCI_GET_DRIVER_DATA(pci_dev); /* unregister i2c_bus */ i2c_bit_del_bus(&btv->i2c_adap); @@ -3767,7 +3823,7 @@ } -static int __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) +static int __devinit bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { int result; unsigned char command; @@ -3788,20 +3844,17 @@ btv->vbi_even=NULL; init_waitqueue_head(&btv->vbiq); init_waitqueue_head(&btv->capq); - init_waitqueue_head(&btv->capqo); - init_waitqueue_head(&btv->capqe); btv->vbip=VBIBUF_SIZE; - - init_waitqueue_head(&btv->gpioq); btv->s_lock = SPIN_LOCK_UNLOCKED; + init_waitqueue_head(&btv->gpioq); btv->shutdown=0; btv->id=dev->device; btv->irq=dev->irq; - btv->bt848_adr=pci_resource_start(dev, 0); + btv->bt848_adr=pci_resource_start(dev,0); if (pci_enable_device(dev)) return -EIO; - if (!request_mem_region(btv->bt848_adr, + if (!request_mem_region(pci_resource_start(dev,0), pci_resource_len(dev,0), "bttv")) { return -EBUSY; @@ -3871,24 +3924,23 @@ } } - dev->driver_data = btv; + PCI_SET_DRIVER_DATA(dev,btv); if(init_bt848(btv) < 0) { bttv_remove(dev); return -EIO; } - bttv_num++; return 0; fail: - release_mem_region(btv->bt848_adr, + release_mem_region(pci_resource_start(btv->dev,0), pci_resource_len(btv->dev,0)); return result; } -static struct pci_device_id bttv_pci_tbl[] __initdata = { +static struct pci_device_id bttv_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, @@ -3903,13 +3955,13 @@ MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); static struct pci_driver bttv_pci_driver = { - name:"bttv", - id_table:bttv_pci_tbl, - probe:bttv_probe, - remove:bttv_remove, + name: "bttv", + id_table: bttv_pci_tbl, + probe: bttv_probe, + remove: bttv_remove, }; -static int __init bttv_init_module(void) +int bttv_init_module(void) { bttv_num = 0; @@ -3930,10 +3982,10 @@ return pci_module_init(&bttv_pci_driver); } -static void __exit bttv_cleanup_module(void) +void bttv_cleanup_module(void) { pci_unregister_driver(&bttv_pci_driver); - return; + return; } module_init(bttv_init_module); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/bttv.h linux.ac/drivers/char/bttv.h --- linux.vanilla/drivers/char/bttv.h Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/bttv.h Sun Jun 4 22:37:30 2000 @@ -21,7 +21,12 @@ #ifndef _BTTV_H_ #define _BTTV_H_ -#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,28) +#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,31) + +#ifndef PCI_GET_DRIVER_DATA +# define PCI_GET_DRIVER_DATA(pdev) ((pdev)->driver_data) +# define PCI_SET_DRIVER_DATA(pdev,data) (((pdev)->driver_data) = (data)) +#endif /* PCI_GET_DRIVER_DATA */ #include #include @@ -32,12 +37,13 @@ #include "audiochip.h" #include "bt848.h" -#define WAIT_QUEUE wait_queue_head_t - -/* returns card type, +/* returns card type + card ID (for bt878-based ones) for possible values see lines below beginning with #define BTTV_UNKNOWN returns negative value if error ocurred */ +extern int bttv_get_cardinfo(unsigned int card, int *type, int *cardid); + +/* obsolete, use bttv_get_cardinfo instead */ extern int bttv_get_id(unsigned int card); /* sets GPOE register (BT848_GPIO_OUT_EN) to new value: @@ -68,7 +74,7 @@ WARNING: because there is no buffer for GPIO data, one MUST process data ASAP */ -extern WAIT_QUEUE* bttv_get_gpio_queue(unsigned int card); +extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card); #ifndef O_NONCAP @@ -130,6 +136,7 @@ struct video_picture picture; /* Current picture params */ struct video_audio audio_dev; /* Current audio params */ + spinlock_t s_lock; struct semaphore lock; int user; int capuser; @@ -143,8 +150,6 @@ int tuner_type; int channel; - - spinlock_t s_lock; unsigned int nr; unsigned short id; @@ -160,6 +165,7 @@ struct bttv_window win; int fb_color_ctl; int type; /* card type */ + int cardid; int audio; /* audio mode */ int audio_chip; /* set to one of the chips supported by bttv.c */ int radio; @@ -169,10 +175,8 @@ u32 *vbi_even; u32 bus_vbi_even; u32 bus_vbi_odd; - WAIT_QUEUE vbiq; - WAIT_QUEUE capq; - WAIT_QUEUE capqo; - WAIT_QUEUE capqe; + wait_queue_head_t vbiq; + wait_queue_head_t capq; int vbip; u32 *risc_scr_odd; @@ -198,7 +202,7 @@ int errors; int needs_restart; - WAIT_QUEUE gpioq; + wait_queue_head_t gpioq; int shutdown; }; #endif @@ -277,6 +281,8 @@ #define BTTV_STB2 0x28 #define BTTV_AVPHONE98 0x29 #define BTTV_PV951 0x2a +#define BTTV_ONAIR_TV 0x2b +#define BTTV_SIGMA_TVII_FM 0x2c #define PLL_NONE 0 #define PLL_28 1 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 Sun Jun 4 21:23:03 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); } } @@ -193,6 +192,8 @@ if (mousedev >= NR_MICE) return -EINVAL; + MOD_INC_USE_COUNT; + down(&mouse_sem); mse = busmouse_data[mousedev]; if (!mse) @@ -211,8 +212,6 @@ if (mse->active++) goto end; - MOD_INC_USE_COUNT; - spin_lock_irq(&mse->lock); mse->ready = 0; @@ -226,6 +225,9 @@ spin_unlock_irq(&mse->lock); end: up(&mouse_sem); + + if (ret) + MOD_DEC_USE_COUNT; return ret; } 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/console.c linux.ac/drivers/char/console.c --- linux.vanilla/drivers/char/console.c Thu May 25 17:37:59 2000 +++ linux.ac/drivers/char/console.c Sun Jun 4 21:34:21 2000 @@ -2290,10 +2290,13 @@ static void con_flush_chars(struct tty_struct *tty) { + unsigned long flags; struct vt_struct *vt = (struct vt_struct *)tty->driver_data; pm_access(pm_con); + spin_lock_irqsave(&console_lock, flags); set_cursor(vt->vc_num); + spin_unlock_irqrestore(&console_lock, flags); } /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/cyclades.c linux.ac/drivers/char/cyclades.c --- linux.vanilla/drivers/char/cyclades.c Thu May 25 17:38:00 2000 +++ linux.ac/drivers/char/cyclades.c Sun Jun 4 22:15:37 2000 @@ -1,7 +1,8 @@ #undef BLOCKMOVE #define Z_WAKE +#undef Z_EXT_CHARS_IN_BUFFER static char rcsid[] = -"$Revision: 2.3.2.6 $$Date: 2000/05/05 13:56:05 $"; +"$Revision: 2.3.2.7 $$Date: 2000/06/01 18:26:34 $"; /* * linux/drivers/char/cyclades.c @@ -24,6 +25,12 @@ * This version supports shared IRQ's (only for PCI boards). * * $Log: cyclades.c,v $ + * Revision 2.3.2.7 2000/06/01 18:26:34 ivan + * Request PLX I/O region, although driver doesn't use it, to avoid + * problems with other drivers accessing it. + * Removed count for on-board buffer characters in cy_chars_in_buffer + * (Cyclades-Z only). + * * Revision 2.3.2.6 2000/05/05 13:56:05 ivan * Driver now reports physical instead of virtual memory addresses. * Masks were added to some Cyclades-Z read accesses. @@ -636,6 +643,7 @@ #include #include #include +#include #include #include #include @@ -882,9 +890,8 @@ static long cyz_polling_cycle = CZ_DEF_POLL; static int cyz_timeron = 0; -static struct timer_list -cyz_timerlist = { - NULL, NULL, 0, 0, cyz_poll +static struct timer_list cyz_timerlist = { + function: cyz_poll }; #else /* CONFIG_CYZ_INTR */ static void cyz_rx_restart(unsigned long); @@ -3122,12 +3129,15 @@ card = info->card; channel = (info->line) - (cy_card[card].first_line); +#ifdef Z_EXT_CHARS_IN_BUFFER if (!IS_CYC_Z(cy_card[card])) { +#endif /* Z_EXT_CHARS_IN_BUFFER */ #ifdef CY_DEBUG_IO printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */ #endif return info->xmit_cnt; +#ifdef Z_EXT_CHARS_IN_BUFFER } else { static volatile struct FIRM_ID *firm_id; static volatile struct ZFW_CTRL *zfw_ctrl; @@ -3156,6 +3166,7 @@ #endif return (info->xmit_cnt + char_count); } +#endif /* Z_EXT_CHARS_IN_BUFFER */ } /* cy_chars_in_buffer */ @@ -4856,7 +4867,7 @@ struct pci_dev *pdev = NULL; unsigned char cyy_rev_id; unsigned char cy_pci_irq = 0; - uclong cy_pci_phys0, cy_pci_phys2; + uclong cy_pci_phys0, cy_pci_phys1, cy_pci_phys2; uclong cy_pci_addr0, cy_pci_addr2; unsigned short i,j,cy_pci_nchan, plx_ver; unsigned short device_id,dev_index = 0; @@ -4885,6 +4896,7 @@ /* read PCI configuration area */ cy_pci_irq = pdev->irq; cy_pci_phys0 = pci_resource_start(pdev, 0); + cy_pci_phys1 = pci_resource_start(pdev, 1); cy_pci_phys2 = pci_resource_start(pdev, 2); pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id); @@ -4907,6 +4919,11 @@ pdev->resource[2].flags &= ~IORESOURCE_IO; } + /* Although we don't use this I/O region, we should + request it from the kernel anyway, to avoid problems + with other drivers accessing it. */ + request_region(cy_pci_phys1, CyPCI_Yctl, "Cyclom-Y"); + #if defined(__alpha__) if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", @@ -5054,6 +5071,12 @@ "Ignoring it...\n"); pdev->resource[2].flags &= ~IORESOURCE_IO; } + + /* Although we don't use this I/O region, we should + request it from the kernel anyway, to avoid problems + with other drivers accessing it. */ + request_region(cy_pci_phys1, CyPCI_Zctl, "Cyclades-Z"); + if (mailbox == ZE_V1) { #if !defined(__alpha__) cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win); 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/msp3400.c linux.ac/drivers/char/msp3400.c --- linux.vanilla/drivers/char/msp3400.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/msp3400.c Sun Jun 4 21:51:40 2000 @@ -1,7 +1,7 @@ /* * programming the msp34* sound processor family * - * (c) 1997,1998 Gerd Knorr + * (c) 1997-2000 Gerd Knorr * * what works and what doesn't: * @@ -46,6 +46,7 @@ #include #include #include +#include #ifdef CONFIG_SMP #include @@ -57,16 +58,14 @@ #include "audiochip.h" -#define WAIT_QUEUE wait_queue_head_t - /* sound mixer stuff */ -#if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE) +#if 0 /* defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE) */ # define REGISTER_MIXER 1 #endif /* Addresses to scan */ static unsigned short normal_i2c[] = {I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {0x40,0x44,I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {0x40,0x40,I2C_CLIENT_END}; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; @@ -102,7 +101,7 @@ /* thread */ struct task_struct *thread; - WAIT_QUEUE wq; + wait_queue_head_t wq; struct semaphore *notify; int active,restart,rmmod; @@ -1370,7 +1369,7 @@ if (simple == -1) { /* default mode */ - msp->simple = 0; + msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; } else { /* use insmod option */ msp->simple = simple; @@ -1632,22 +1631,19 @@ /* ----------------------------------------------------------------------- */ -#ifdef MODULE -int init_module(void) -#else -int msp3400c_init(void) -#endif +int msp3400_init_module(void) { i2c_add_driver(&driver); return 0; } -#ifdef MODULE -void cleanup_module(void) +void msp3400_cleanup_module(void) { i2c_del_driver(&driver); } -#endif + +module_init(msp3400_init_module); +module_exit(msp3400_cleanup_module); /* * Overrides for Emacs so that we follow Linus's tabbing style. 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 Wed May 31 11:18:46 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 -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/stallion.c linux.ac/drivers/char/stallion.c --- linux.vanilla/drivers/char/stallion.c Thu May 25 17:38:00 2000 +++ linux.ac/drivers/char/stallion.c Sun Jun 4 22:02:49 2000 @@ -2795,8 +2795,8 @@ */ #if DEBUG printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__, - devp->resource[0].start, devp->resource[1].start, - devp->resource[2].start, devp->resource[3].start, devp->irq); + pci_resource_start(devp, 0), pci_resource_start(devp, 1), + pci_resource_start(devp, 2), pci_resource_start(devp, 3), devp->irq); #endif /* @@ -2805,22 +2805,16 @@ */ switch (brdtype) { case BRD_ECHPCI: - brdp->ioaddr2 = (devp->resource[0].start & - PCI_BASE_ADDRESS_IO_MASK); - brdp->ioaddr1 = (devp->resource[1].start & - PCI_BASE_ADDRESS_IO_MASK); + brdp->ioaddr2 = pci_resource_start(devp, 0); + brdp->ioaddr1 = pci_resource_start(devp, 1); break; case BRD_ECH64PCI: - brdp->ioaddr2 = (devp->resource[2].start & - PCI_BASE_ADDRESS_IO_MASK); - brdp->ioaddr1 = (devp->resource[1].start & - PCI_BASE_ADDRESS_IO_MASK); + brdp->ioaddr2 = pci_resource_start(devp, 2); + brdp->ioaddr1 = pci_resource_start(devp, 1); break; case BRD_EASYIOPCI: - brdp->ioaddr1 = (devp->resource[2].start & - PCI_BASE_ADDRESS_IO_MASK); - brdp->ioaddr2 = (devp->resource[1].start & - PCI_BASE_ADDRESS_IO_MASK); + brdp->ioaddr1 = pci_resource_start(devp, 2); + brdp->ioaddr2 = pci_resource_start(devp, 1); break; default: printk("STALLION: unknown PCI board type=%d\n", brdtype); 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 Sun Jun 4 21:54:58 2000 @@ -2055,10 +2055,13 @@ 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); + if (!saa->saa7146_mem) + return -EIO; + 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/tuner.c linux.ac/drivers/char/tuner.c --- linux.vanilla/drivers/char/tuner.c Thu May 25 17:38:02 2000 +++ linux.ac/drivers/char/tuner.c Sun Jun 4 21:51:40 2000 @@ -428,22 +428,19 @@ EXPORT_NO_SYMBOLS; -#ifdef MODULE -int init_module(void) -#else -int i2c_tuner_init(void) -#endif +int tuner_init_module(void) { i2c_add_driver(&driver); return 0; } -#ifdef MODULE -void cleanup_module(void) +void tuner_cleanup_module(void) { i2c_del_driver(&driver); } -#endif + +module_init(tuner_init_module); +module_exit(tuner_cleanup_module); /* * Overrides for Emacs so that we follow Linus's tabbing style. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/tvmixer.c linux.ac/drivers/char/tvmixer.c --- linux.vanilla/drivers/char/tvmixer.c Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/char/tvmixer.c Sun Jun 4 21:51:40 2000 @@ -0,0 +1,353 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "audiochip.h" + +#define DEV_MAX 4 + +static int debug = 0; +static int devnr = -1; + +MODULE_PARM(debug,"i"); +MODULE_PARM(devnr,"i"); + +/* ----------------------------------------------------------------------- */ + +struct TVMIXER { + struct i2c_client *dev; + int minor; + int count; +}; + +static struct TVMIXER devices[DEV_MAX]; + +static int tvmixer_adapters(struct i2c_adapter *adap); +static int tvmixer_clients(struct i2c_client *client); + +static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int tvmixer_open(struct inode *inode, struct file *file); +static int tvmixer_release(struct inode *inode, struct file *file); +static loff_t tvmixer_llseek(struct file *file, loff_t offset, int origin); + + +static struct i2c_driver driver = { + "tv card mixer driver", + 42 /* I2C_DRIVERID_FIXME */, + I2C_DF_DUMMY, + tvmixer_adapters, + tvmixer_clients, +}; + +static struct file_operations tvmixer_fops = { + llseek: tvmixer_llseek, + ioctl: tvmixer_ioctl, + open: tvmixer_open, + release: tvmixer_release, +}; + +/* ----------------------------------------------------------------------- */ + +static int mix_to_v4l(int i) +{ + int r; + + r = ((i & 0xff) * 65536 + 50) / 100; + if (r > 65535) r = 65535; + if (r < 0) r = 0; + return r; +} + +static int v4l_to_mix(int i) +{ + int r; + + r = (i * 100 + 32768) / 65536; + if (r > 100) r = 100; + if (r < 0) r = 0; + return r | (r << 8); +} + +static int v4l_to_mix2(int l, int r) +{ + r = (r * 100 + 32768) / 65536; + if (r > 100) r = 100; + if (r < 0) r = 0; + l = (l * 100 + 32768) / 65536; + if (l > 100) l = 100; + if (l < 0) l = 0; + return (r << 8) | l; +} + +static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct video_audio va; + int left,right,ret,val = 0; + struct TVMIXER *mix = file->private_data; + struct i2c_client *client = mix->dev; + + if (NULL == client) + return -ENODEV; + + if (cmd == SOUND_MIXER_INFO) { + mixer_info info; + strncpy(info.id, "tv card", sizeof(info.id)); + strncpy(info.name, client->name, sizeof(info.name)); + info.modify_counter = 42 /* FIXME */; + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == SOUND_OLD_MIXER_INFO) { + _old_mixer_info info; + strncpy(info.id, "tv card", sizeof(info.id)); + strncpy(info.name, client->name, sizeof(info.name)); + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == OSS_GETVERSION) + return put_user(SOUND_VERSION, (int *)arg); + + if (_SIOC_DIR(cmd) & _SIOC_WRITE) + if (get_user(val, (int *)arg)) + return -EFAULT; + + /* read state */ + memset(&va,0,sizeof(va)); + client->driver->command(client,VIDIOCGAUDIO,&va); + + switch (cmd) { + case MIXER_READ(SOUND_MIXER_RECMASK): + case MIXER_READ(SOUND_MIXER_CAPS): + case MIXER_READ(SOUND_MIXER_RECSRC): + case MIXER_WRITE(SOUND_MIXER_RECSRC): + ret = 0; + break; + + case MIXER_READ(SOUND_MIXER_STEREODEVS): + ret = SOUND_MASK_VOLUME; + break; + case MIXER_READ(SOUND_MIXER_DEVMASK): + ret = SOUND_MASK_VOLUME; + if (va.flags & VIDEO_AUDIO_BASS) + ret |= SOUND_MASK_BASS; + if (va.flags & VIDEO_AUDIO_TREBLE) + ret |= SOUND_MASK_TREBLE; + break; + + case MIXER_WRITE(SOUND_MIXER_VOLUME): + left = mix_to_v4l(val); + right = mix_to_v4l(val >> 8); + va.volume = MAX(left,right); + va.balance = (32768*MIN(left,right)) / (va.volume ? va.volume : 1); + va.balance = (leftdriver->command(client,VIDIOCSAUDIO,&va); + client->driver->command(client,VIDIOCGAUDIO,&va); + /* fall throuth */ + case MIXER_READ(SOUND_MIXER_VOLUME): + left = (MIN(65536 - va.balance,32768) * + va.volume) / 32768; + right = (MIN(va.balance,32768) * + va.volume) / 32768; + ret = v4l_to_mix2(left,right); + break; + + case MIXER_WRITE(SOUND_MIXER_BASS): + va.bass = mix_to_v4l(val); + client->driver->command(client,VIDIOCSAUDIO,&va); + client->driver->command(client,VIDIOCGAUDIO,&va); + /* fall throuth */ + case MIXER_READ(SOUND_MIXER_BASS): + ret = v4l_to_mix(va.bass); + break; + + case MIXER_WRITE(SOUND_MIXER_TREBLE): + va.treble = mix_to_v4l(val); + client->driver->command(client,VIDIOCSAUDIO,&va); + client->driver->command(client,VIDIOCGAUDIO,&va); + /* fall throuth */ + case MIXER_READ(SOUND_MIXER_TREBLE): + ret = v4l_to_mix(va.treble); + break; + + default: + return -EINVAL; + } + if (put_user(ret, (int *)arg)) + return -EFAULT; + return 0; +} + +static int tvmixer_open(struct inode *inode, struct file *file) +{ + int i, minor = MINOR(inode->i_rdev); + struct TVMIXER *mix = NULL; + struct i2c_client *client = NULL; + + for (i = 0; i < DEV_MAX; i++) { + if (devices[i].minor == minor) { + mix = devices+i; + client = mix->dev; + break; + } + } + + if (NULL == client) + return -ENODEV; + + /* lock bttv in memory while the mixer is in use */ + file->private_data = mix; + if (client->adapter->inc_use) + client->adapter->inc_use(client->adapter); + MOD_INC_USE_COUNT; + return 0; +} + +static int tvmixer_release(struct inode *inode, struct file *file) +{ + struct TVMIXER *mix = file->private_data; + struct i2c_client *client = mix->dev; + + if (NULL == client) + return -ENODEV; + + if (client->adapter->dec_use) + client->adapter->dec_use(client->adapter); + MOD_DEC_USE_COUNT; + return 0; +} + +static loff_t tvmixer_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + +/* ----------------------------------------------------------------------- */ + +static int tvmixer_adapters(struct i2c_adapter *adap) +{ + return 0; +} + +static int tvmixer_clients(struct i2c_client *client) +{ + struct video_audio va; + int i,minor; + + /* TV card ??? */ + if (client->adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848)) { + if (debug) + printk("tvmixer: %s is not a tv card\n", + client->adapter->name); + return -1; + } + printk("tvmixer: debug: %s\n",client->name); + + /* unregister ?? */ + for (i = 0; i < DEV_MAX; i++) { + if (devices[i].dev == client) { + /* unregister */ + unregister_sound_mixer(devices[i].minor); + devices[i].dev = NULL; + devices[i].minor = -1; + printk("tvmixer: %s unregistered (#1)\n",client->name); + return 0; + } + } + + /* look for a free slot */ + for (i = 0; i < DEV_MAX; i++) + if (NULL == devices[i].dev) + break; + if (i == DEV_MAX) { + printk(KERN_WARNING "tvmixer: DEV_MAX too small\n"); + return -1; + } + + /* audio chip with mixer ??? */ + if (NULL == client->driver->command) { + if (debug) + printk("tvmixer: %s: driver->command is NULL\n", + client->driver->name); + return -1; + } + memset(&va,0,sizeof(va)); + if (0 != client->driver->command(client,VIDIOCGAUDIO,&va)) { + if (debug) + printk("tvmixer: %s: VIDIOCGAUDIO failed\n", + client->name); + return -1; + } + if (0 == (va.flags & VIDEO_AUDIO_VOLUME)) { + if (debug) + printk("tvmixer: %s: has no volume control\n", + client->name); + return -1; + } + + /* everything is fine, register */ + if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) { + printk(KERN_ERR "tvmixer: cannot allocate mixer device\n"); + return -1; + } + + devices[i].minor = minor; + devices[i].count = 0; + devices[i].dev = client; + printk("tvmixer: %s (%s) registered with minor %d\n", + client->name,client->adapter->name,minor); + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +int tvmixer_init_module(void) +{ + int i; + + for (i = 0; i < DEV_MAX; i++) + devices[i].minor = -1; + i2c_add_driver(&driver); + return 0; +} + +void tvmixer_cleanup_module(void) +{ + int i; + + i2c_del_driver(&driver); + for (i = 0; i < DEV_MAX; i++) { + if (devices[i].minor != -1) { + unregister_sound_mixer(devices[i].minor); + printk("tvmixer: %s unregistered (#2)\n", + devices[i].dev->name); + } + } +} + +module_init(tvmixer_init_module); +module_exit(tvmixer_cleanup_module); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ 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 Sun Jun 4 22:47:13 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/Config.in linux.ac/drivers/ide/Config.in --- linux.vanilla/drivers/ide/Config.in Thu May 25 17:46:15 2000 +++ linux.ac/drivers/ide/Config.in Sun Jun 4 21:54:13 2000 @@ -21,6 +21,9 @@ dep_mbool ' Seagate Vendor Specific' CONFIG_BLK_DEV_IDEDISK_SEAGATE $CONFIG_BLK_DEV_IDEDISK_VENDOR dep_mbool ' Western Digital Vendor Specific' CONFIG_BLK_DEV_IDEDISK_WD $CONFIG_BLK_DEV_IDEDISK_VENDOR + define_bool CONFIG_BLK_DEV_COMMERIAL n + dep_mbool ' TiVo Commerial Application Specific' CONFIG_BLK_DEV_TIVO $CONFIG_BLK_DEV_COMMERIAL + dep_tristate ' PCMCIA IDE support' CONFIG_BLK_DEV_IDECS $CONFIG_BLK_DEV_IDE $CONFIG_PCMCIA dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE @@ -44,7 +47,7 @@ dep_bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL dep_bool ' Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP dep_bool ' AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI - dep_mbool ' AEC62XX Tuning support (WIP)' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX $CONFIG_IDEDMA_PCI_WIP + dep_mbool ' AEC62XX Tuning support' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX dep_bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3 dep_bool ' AMD Viper support' CONFIG_BLK_DEV_AMD7409 $CONFIG_BLK_DEV_IDEDMA_PCI @@ -81,14 +84,12 @@ dep_bool ' PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC $CONFIG_BLK_DEV_IDE_PMAC dep_bool ' Use DMA by default' CONFIG_IDEDMA_PMAC_AUTO $CONFIG_BLK_DEV_IDEDMA_PMAC define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PMAC - define_bool CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_BLK_DEV_IDEDMA_PMAC fi if [ "$CONFIG_ARCH_ACORN" = "y" ]; then dep_bool ' ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN dep_bool ' ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS $CONFIG_BLK_DEV_IDE_ICSIDE dep_bool ' Use ICS DMA by default' CONFIG_IDEDMA_ICS_AUTO $CONFIG_BLK_DEV_IDEDMA_ICS define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_ICS - define_bool CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_BLK_DEV_IDEDMA_ICS dep_bool ' RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE $CONFIG_ARCH_ACORN fi if [ "$CONFIG_AMIGA" = "y" ]; then @@ -132,6 +133,17 @@ define_bool CONFIG_IDEDMA_AUTO n fi +if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" -o \ + "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" -o \ + "$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then + bool ' IGNORE word93 Validation BITS' CONFIG_IDEDMA_IVB +fi + +if [ "$CONFIG_BLK_DEV_TIVO" = "y" ]; then + define_bool CONFIG_DMA_NONPCI y +else + define_bool CONFIG_DMA_NONPCI n +fi if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ "$CONFIG_BLK_DEV_AEC62XX" = "y" -o \ "$CONFIG_BLK_DEV_ALI15X3" = "y" -o \ 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 Wed May 31 11:20:20 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) @@ -97,7 +97,8 @@ IDE_OBJS += icside.o endif -ifeq ($(CONFIG_BLK_DEV_IDEDMA_PCI),y) +## ifeq ($(CONFIG_DMA_NONPCI),n) +ifeq ($(CONFIG_BLK_DEV_IDEDMA),y) IDE_OBJS += ide-dma.o endif @@ -178,8 +179,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 +191,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 +199,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 +207,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 +215,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 +223,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 Wed May 31 11:20:20 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; @@ -358,7 +358,7 @@ byte unit = (drive->select.b.unit & 0x01); unsigned long dma_base = hwif->dma_base; byte speed = -1; - byte ultra66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte ultra66 = eighty_ninty_three(drive); if (drive->media != ide_disk) return ((int) ide_dma_off_quietly); 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 Wed May 31 11:20:20 2000 @@ -372,7 +372,7 @@ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); byte speed = 0x00; - byte ultra66 = ((hwif->udma_four) && (id->hw_config & 0x2000)) ? 1 : 0; + byte ultra66 = eighty_ninty_three(drive); int rval; if ((id->dma_ultra & 0x0010) && (ultra66) && (ultra33)) { @@ -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) { /* * */ 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 Wed May 31 11:20:20 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; /* @@ -268,8 +268,7 @@ static int config_chipset_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - byte udma_66 = ((id->hw_config & 0x2000) && - (HWIF(drive)->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); byte speed = 0x00; int rval; @@ -372,9 +371,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) { /* * */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/cmd64x.c linux.ac/drivers/ide/cmd64x.c --- linux.vanilla/drivers/ide/cmd64x.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/cmd64x.c Wed May 31 11:20:20 2000 @@ -420,7 +420,7 @@ byte speed = 0x00; byte set_pio = 0x00; byte udma_33 = ((rev >= 0x05) || (ultra_66)) ? 1 : 0; - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); int rval; switch(dev->device) { 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 Wed May 31 11:20:20 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; /* @@ -342,17 +342,18 @@ struct hd_driveid *id = drive->id; byte speed = 0x00; byte reg51h = 0; + byte ultra66 = eighty_ninty_three(drive); int rval; if ((id->dma_ultra & 0x0010) && (!check_in_drive_lists(drive, bad_ata66_4)) && (HPT366_ALLOW_ATA66_4) && - (HWIF(drive)->udma_four)) { + (ultra66)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (!check_in_drive_lists(drive, bad_ata66_3)) && (HPT366_ALLOW_ATA66_3) && - (HWIF(drive)->udma_four)) { + (ultra66)) { speed = XFER_UDMA_3; } else if (id->dma_ultra && (!check_in_drive_lists(drive, bad_ata33))) { if (id->dma_ultra & 0x0004) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/ide-cd.c linux.ac/drivers/ide/ide-cd.c --- linux.vanilla/drivers/ide/ide-cd.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/ide-cd.c Sat May 27 15:37:02 2000 @@ -1524,7 +1524,7 @@ memset(&pc, 0, sizeof(pc)); pc.sense = sense; pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; - pc.c[4] = lockflag ? 3 : 0; + pc.c[4] = lockflag ? 1 : 0; stat = cdrom_queue_packet_command (drive, &pc); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/ide-disk.c linux.ac/drivers/ide/ide-disk.c --- linux.vanilla/drivers/ide/ide-disk.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/ide-disk.c Wed May 31 11:20:21 2000 @@ -686,12 +686,24 @@ static int set_nowerr(ide_drive_t *drive, int arg) { +#if SPIN_FLAGS_SET + unsigned long flags; + + if (ide_spin_wait_hwgroup(drive, &flags)) +#else if (ide_spin_wait_hwgroup(drive)) +#endif /* SPIN_FLAGS_SET */ return -EBUSY; drive->nowerr = arg; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; + +#if SPIN_FLAGS_SET + spin_unlock_irqrestore(&io_request_lock, flags); +#else spin_unlock_irq(&io_request_lock); +#endif /* SPIN_FLAGS_SET */ + return 0; } 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 Wed May 31 11:20:21 2000 @@ -358,8 +358,7 @@ { struct hd_driveid *id = drive->id; - if ((id->field_valid & 4) && (id->hw_config & 0x2000) && - (HWIF(drive)->udma_four) && + if ((id->field_valid & 4) && (eighty_ninty_three(drive)) && (id->dma_ultra & (id->dma_ultra >> 11) & 3)) { if ((id->dma_ultra >> 12) & 1) { printk(", UDMA(66)"); /* UDMA BIOS-enabled! */ @@ -394,7 +393,7 @@ return hwif->dmaproc(ide_dma_off, drive); /* Enable DMA on any drive that has UltraDMA (mode 3/4) enabled */ - if ((id->field_valid & 4) && (hwif->udma_four) && (id->hw_config & 0x2000)) + if ((id->field_valid & 4) && (eighty_ninty_three(drive))) if ((id->dma_ultra & (id->dma_ultra >> 11) & 3)) return hwif->dmaproc(ide_dma_on, drive); /* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */ @@ -413,6 +412,22 @@ } /* + * 1 dmaing, 2 error, 4 intr + */ +static int dma_timer_expiry (ide_drive_t *drive) +{ + byte dma_stat = inb(HWIF(drive)->dma_base+2); + + if (dma_stat & 1) /* DMAing */ + return WAIT_CMD; + if (dma_stat & 4) /* INTRing */ + return WAIT_CMD; +// HWIF(drive)->dmaproc(ide_dma_test_irq, drive); +// HWIF(drive)->dmaproc(ide_dma_end, drive); + return 0; +} + +/* * ide_dmaproc() initiates/aborts DMA read/write operations on a drive. * * The caller is assumed to have selected the drive and programmed the drive's @@ -459,7 +474,7 @@ drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ + ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); case ide_dma_begin: /* Note that this is done *after* the cmd has @@ -570,8 +585,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) { 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/ide-features.c linux.ac/drivers/ide/ide-features.c --- linux.vanilla/drivers/ide/ide-features.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/ide/ide-features.c Wed May 31 11:20:21 2000 @@ -244,6 +244,18 @@ } /* + * All hosts that use the 80c ribbon mus use! + */ +byte eighty_ninty_three (ide_drive_t *drive) +{ + return ((byte) ((HWIF(drive)->udma_four) && +#ifndef CONFIG_IDEDMA_IVB + (drive->id->hw_config & 0x4000) && +#endif /* CONFIG_IDEDMA_IVB */ + (drive->id->hw_config & 0x2000)) ? 1 : 0); +} + +/* * Similar to ide_wait_stat(), except it never calls ide_error internally. * This is a kludge to handle the new ide_config_drive_speed() function, * and should not otherwise be used anywhere. Eventually, the tuneproc's @@ -260,10 +272,11 @@ int i, error = 1; byte stat; -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#ifndef CONFIG_DMA_NONPCI byte unit = (drive->select.b.unit & 0x01); outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* CONFIG_DMA_NONPCI */ + /* * Don't use ide_wait_cmd here - it will * attempt to set_geometry and recalibrate, @@ -273,7 +286,11 @@ /* * Select the drive, and issue the SETFEATURES command */ +#if DISABLE_IRQ_NOSYNC + disable_irq_nosync(hwif->irq); +#else disable_irq(hwif->irq); /* disable_irq_nosync ?? */ +#endif /* DISABLE_IRQ_NOSYNC */ udelay(1); SELECT_DRIVE(HWIF(drive), drive); udelay(1); @@ -326,13 +343,13 @@ drive->id->dma_mword &= ~0x0F00; drive->id->dma_1word &= ~0x0F00; -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#ifndef CONFIG_DMA_NONPCI if (speed > XFER_PIO_4) { outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); } else { outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); } -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* CONFIG_DMA_NONPCI */ switch(speed) { case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break; @@ -358,5 +375,6 @@ EXPORT_SYMBOL(ide_driveid_update); EXPORT_SYMBOL(ide_ata66_check); EXPORT_SYMBOL(set_transfer); +EXPORT_SYMBOL(eighty_ninty_three); EXPORT_SYMBOL(ide_config_drive_speed); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/ide-geometry.c linux.ac/drivers/ide/ide-geometry.c --- linux.vanilla/drivers/ide/ide-geometry.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/ide/ide-geometry.c Wed May 31 11:20:21 2000 @@ -3,7 +3,7 @@ */ #include -#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD) +#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD_ONLY) #include #include @@ -211,4 +211,4 @@ drive->bios_cyl, drive->bios_head, drive->bios_sect); return ret; } -#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD) */ +#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD_ONLY) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/ide.c linux.ac/drivers/ide/ide.c --- linux.vanilla/drivers/ide/ide.c Thu May 25 17:46:15 2000 +++ linux.ac/drivers/ide/ide.c Sun Jun 4 21:38:47 2000 @@ -1404,7 +1404,11 @@ */ spin_unlock(&io_request_lock); hwif = HWIF(drive); +#if DISABLE_IRQ_NOSYNC + disable_irq_nosync(hwif->irq); +#else disable_irq(hwif->irq); /* disable_irq_nosync ?? */ +#endif /* DISABLE_IRQ_NOSYNC */ __cli(); /* local CPU only, as if we were handling an interrupt */ if (hwgroup->poll_timeout != 0) { startstop = handler(drive); @@ -2008,12 +2012,12 @@ else hwgroup->hwif = HWIF(hwgroup->drive); -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) if (hwif->dma_base) { (void) ide_release_dma(hwif); hwif->dma_base = 0; } -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ /* * Remove us from the kernel's knowledge @@ -2269,24 +2273,41 @@ return val; } +#if SPIN_FLAGS_SET +int ide_spin_wait_hwgroup (ide_drive_t *drive, unsigned long *flags) +#else int ide_spin_wait_hwgroup (ide_drive_t *drive) +#endif /* SPIN_FLAGS_SET */ { ide_hwgroup_t *hwgroup = HWGROUP(drive); unsigned long timeout = jiffies + (3 * HZ); +#if SPIN_FLAGS_SET + spin_lock_irqsave(&io_request_lock, *flags); +#else spin_lock_irq(&io_request_lock); +#endif /* SPIN_FLAGS_SET */ + while (hwgroup->busy) { - unsigned long flags; + unsigned long lflags; +#if SPIN_FLAGS_SET + spin_unlock_irqrestore(&io_request_lock, *flags); +#else spin_unlock_irq(&io_request_lock); - __save_flags(flags); /* local CPU only */ +#endif /* SPIN_FLAGS_SET */ + __save_flags(lflags); /* local CPU only */ __sti(); /* local CPU only; needed for jiffies */ if (0 < (signed long)(jiffies - timeout)) { - __restore_flags(flags); + __restore_flags(lflags); /* local CPU only */ printk("%s: channel busy\n", drive->name); return -EBUSY; } - __restore_flags(flags); /* local CPU only */ + __restore_flags(lflags); /* local CPU only */ +#if SPIN_FLAGS_SET + spin_lock_irqsave(&io_request_lock, *flags); +#else spin_lock_irq(&io_request_lock); +#endif /* SPIN_FLAGS_SET */ } return 0; } @@ -2298,6 +2319,9 @@ */ int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val) { +#if SPIN_FLAGS_SET + unsigned long flags; +#endif /* SPIN_FLAGS_SET */ int i; u32 *p; @@ -2309,7 +2333,11 @@ return -EINVAL; if (setting->set) return setting->set(drive, val); +#if SPIN_FLAGS_SET + if (ide_spin_wait_hwgroup(drive, &flags)) +#else if (ide_spin_wait_hwgroup(drive)) +#endif /* SPIN_FLAGS_SET */ return -EBUSY; switch (setting->data_type) { case TYPE_BYTE: @@ -2327,7 +2355,13 @@ *p = val; break; } + +#if SPIN_FLAGS_SET + spin_unlock_irqrestore(&io_request_lock, flags); +#else spin_unlock_irq(&io_request_lock); +#endif /* SPIN_FLAGS_SET */ + return 0; } @@ -2422,13 +2456,13 @@ */ void ide_delay_50ms (void) { -#if 0 +#ifndef CONFIG_BLK_DEV_IDECS unsigned long timeout = jiffies + ((HZ + 19)/20) + 1; while (0 < (signed long)(timeout - jiffies)); #else __set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/20); -#endif +#endif /* CONFIG_BLK_DEV_IDECS */ } int system_bus_clock (void) @@ -3266,6 +3300,7 @@ if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) { ide_get_lock(&ide_lock, NULL, NULL); /* for atari only */ disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */ +// disable_irq_nosync(ide_hwifs[0].irq); } #endif /* __mc68000__ || CONFIG_APUS */ @@ -3619,10 +3654,10 @@ for (index = 0; index < MAX_HWIFS; ++index) { ide_unregister(index); -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) if (ide_hwifs[index].dma_base) (void) ide_release_dma(&ide_hwifs[index]); -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ } #ifdef CONFIG_PROC_FS 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 Wed May 31 11:20:21 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); @@ -418,7 +418,7 @@ byte AP; unsigned short EP; byte CLKSPD = IN_BYTE(high_16 + 0x11); - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); byte udma_33 = ultra ? (inb(high_16 + 0x001f) & 1) : 0; /* @@ -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 Wed May 31 11:20:21 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; @@ -341,7 +341,7 @@ struct pci_dev *dev = hwif->pci_dev; byte speed; - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); int ultra66 = ((dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0; int ultra = ((ultra66) || diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ide/sis5513.c linux.ac/drivers/ide/sis5513.c --- linux.vanilla/drivers/ide/sis5513.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/ide/sis5513.c Sun Jun 4 21:46:06 2000 @@ -111,12 +111,12 @@ extern int (*sis_display_info)(char *, char **, off_t, int); /* ide-proc.c */ static struct pci_dev *bmide_dev; -static char *cable_type[] __initdata = { +static char *cable_type[] = { "80 pins", "40 pins" }; -static char *recovery_time [] __initdata ={ +static char *recovery_time [] ={ "12 PCICLK", "1 PCICLK", "2 PCICLK", "3 PCICLK", "4 PCICLK", "5 PCICLCK", @@ -127,14 +127,14 @@ "15 PCICLK", "15 PCICLK" }; -static char * cycle_time [] __initdata = { +static char * cycle_time [] = { "Undefined", "2 CLCK", "3 CLK", "4 CLK", "5 CLK", "6 CLK", "7 CLK", "8 CLK" }; -static char * active_time [] __initdata = { +static char * active_time [] = { "8 PCICLK", "1 PCICLCK", "2 PCICLK", "2 PCICLK", "4 PCICLK", "5 PCICLK", @@ -185,7 +185,7 @@ p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]); p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n", - active_time[(reg & 0x07)], active_time[(reg &0x07)] ); + active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); rc = pci_read_config_byte(bmide_dev, 0x40, ®); rc = pci_read_config_byte(bmide_dev, 0x44, ®1); @@ -209,7 +209,7 @@ p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]); p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n", - active_time[(reg & 0x07)], active_time[(reg &0x07)] ); + active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); rc = pci_read_config_byte(bmide_dev, 0x42, ®); rc = pci_read_config_byte(bmide_dev, 0x46, ®1); @@ -335,7 +335,7 @@ #ifdef CONFIG_BLK_DEV_IDEDMA /* - * ((id->hw_config & 0x2000) && (HWIF(drive)->udma_four)) + * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four)) */ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) { @@ -349,7 +349,7 @@ unsigned long dma_base = hwif->dma_base; byte unit = (drive->select.b.unit & 0x01); byte speed = 0x00, unmask = 0xE0, four_two = 0x00; - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); if (host_dev) { switch(host_dev->device) { @@ -536,7 +536,7 @@ pci_read_config_byte(dev, 0x52, ®52h); if (!(reg52h & 0x04)) { - /* set IDE controller to operate in Compabitility mode obly */ + /* set IDE controller to operate in Compabitility mode only */ pci_write_config_byte(dev, 0x52, reg52h|0x04); } #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) 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 Wed May 31 11:20:21 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; @@ -760,11 +760,12 @@ { struct hd_driveid *id = drive->id; byte speed = 0x00; + byte ultra66 = eighty_ninty_three(drive); int rval; - if ((id->dma_ultra & 0x0010) && (HWIF(drive)->udma_four)) { + if ((id->dma_ultra & 0x0010) && (ultra66)) { speed = XFER_UDMA_4; - } else if ((id->dma_ultra & 0x0008) && (HWIF(drive)->udma_four)) { + } else if ((id->dma_ultra & 0x0008) && (ultra66)) { speed = XFER_UDMA_3; } else if (id->dma_ultra & 0x0004) { speed = XFER_UDMA_2; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/Makefile linux.ac/drivers/ieee1394/Makefile --- linux.vanilla/drivers/ieee1394/Makefile Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/Makefile Sun Jun 4 21:50:42 2000 @@ -25,15 +25,13 @@ OX_OBJS := ifeq ($(CONFIG_IEEE1394),y) -L_OBJS += ieee1394.o hosts.o highlevel.o csr.o -O_TARGET = ieee1394.o -O_OBJS += ieee1394_core.o ieee1394_transactions.o -OX_OBJS += ieee1394_syms.o +L_OBJS += ieee1394_core.o ieee1394_transactions.o hosts.o highlevel.o csr.o guid.o +LX_OBJS += ieee1394_syms.o else ifeq ($(CONFIG_IEEE1394),m) M_OBJS += ieee1394.o O_TARGET = ieee1394.o - O_OBJS += ieee1394_core.o ieee1394_transactions.o hosts.o highlevel.o csr.o + O_OBJS += ieee1394_core.o ieee1394_transactions.o hosts.o highlevel.o csr.o guid.o OX_OBJS += ieee1394_syms.o endif endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/guid.c linux.ac/drivers/ieee1394/guid.c --- linux.vanilla/drivers/ieee1394/guid.c Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/ieee1394/guid.c Sun Jun 4 21:50:42 2000 @@ -0,0 +1,226 @@ +/* + * IEEE 1394 for Linux + * + * GUID collection and management + * + * Copyright (C) 2000 Andreas E. Bombe + */ + +#include +#include +#include +#include +#include + +#include "ieee1394_types.h" +#include "ieee1394.h" +#include "hosts.h" +#include "ieee1394_transactions.h" +#include "highlevel.h" +#include "csr.h" + + +static atomic_t outstanding_requests; + +static LIST_HEAD(guid_list); +rwlock_t guid_lock = RW_LOCK_UNLOCKED; + +struct guid_entry { + struct list_head list; + atomic_t refcount; + + u64 guid; + + struct hpsb_host *host; + nodeid_t node_id; + + atomic_t generation; +}; + +struct guid_req { + struct hpsb_packet *pkt; + struct tq_struct tq; +}; + + +static struct guid_entry *create_guid_entry(void) +{ + struct guid_entry *ge; + unsigned long flags; + + ge = kmalloc(sizeof(struct guid_entry), SLAB_ATOMIC); + if (!ge) return NULL; + + INIT_LIST_HEAD(&ge->list); + atomic_set(&ge->refcount, 0); + ge->guid = (u64) -1; + ge->host = NULL; + ge->node_id = 0; + atomic_set(&ge->generation, -1); + + write_lock_irqsave(&guid_lock, flags); + list_add_tail(&ge->list, &guid_list); + write_unlock_irqrestore(&guid_lock, flags); + + return ge; +} + +static struct guid_entry *find_entry(u64 guid) +{ + struct list_head *lh; + struct guid_entry *ge; + + lh = guid_list.next; + while (lh != &guid_list) { + ge = list_entry(lh, struct guid_entry, list); + if (ge->guid == guid) return ge; + lh = lh->next; + } + + return NULL; +} + +static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid) +{ + struct guid_entry *ge; + unsigned long flags; + + HPSB_DEBUG("node %d on host 0x%p has GUID 0x%08x%08x", + nodeid & NODE_MASK, host, (unsigned int)(guid >> 32), + (unsigned int)(guid & 0xffffffff)); + + read_lock_irqsave(&guid_lock, flags); + ge = find_entry(guid); + read_unlock_irqrestore(&guid_lock, flags); + + if (!ge) ge = create_guid_entry(); + if (!ge) return; + + ge->host = host; + ge->node_id = nodeid; + ge->guid = guid; + + atomic_set(&ge->generation, get_hpsb_generation()); +} + +static void pkt_complete(struct guid_req *req) +{ + struct hpsb_packet *pkt = req->pkt; + int rcode = (pkt->header[1] >> 12) & 0xf; + + if (pkt->ack_code == ACK_PENDING && rcode == RCODE_COMPLETE) { + if (*(char *)pkt->data > 1) { + associate_guid(pkt->host, pkt->node_id, + ((u64)be32_to_cpu(pkt->data[3]) << 32) + | be32_to_cpu(pkt->data[4])); + } else { + HPSB_DEBUG("minimal ROM on node %d", + pkt->node_id & NODE_MASK); + } + } else { + HPSB_DEBUG("guid transaction error: ack %d, rcode %d", + pkt->ack_code, rcode); + } + + free_tlabel(pkt->host, pkt->node_id, pkt->tlabel); + free_hpsb_packet(pkt); + kfree(req); + + if (atomic_dec_and_test(&outstanding_requests)) { + /* FIXME: free unreferenced and inactive GUID entries. */ + } +} + + +static void host_reset(struct hpsb_host *host) +{ + struct guid_req *greq; + struct hpsb_packet *pkt; + struct selfid *sid = (struct selfid *)host->topology_map; + int nodecount = host->node_count; + nodeid_t nodeid = LOCAL_BUS; + + for (; nodecount; nodecount--, nodeid++, sid++) { + while (sid->extended) sid++; + if (!sid->link_active) continue; + if (nodeid == host->node_id) continue; + + greq = kmalloc(sizeof(struct guid_req), SLAB_ATOMIC); + if (!greq) { + HPSB_ERR("out of memory in GUID processing"); + return; + } + + pkt = hpsb_make_readbpacket(host, nodeid, + CSR_REGISTER_BASE + CSR_CONFIG_ROM, + 20); + if (!pkt) { + kfree(greq); + HPSB_ERR("out of memory in GUID processing"); + return; + } + + greq->tq.next = NULL; + greq->tq.sync = 0; + greq->tq.routine = (void (*)(void*))pkt_complete; + greq->tq.data = greq; + greq->pkt = pkt; + + queue_task(&greq->tq, &pkt->complete_tq); + + if (!hpsb_send_packet(pkt)) { + free_tlabel(pkt->host, pkt->node_id, pkt->tlabel); + free_hpsb_packet(pkt); + kfree(greq); + HPSB_NOTICE("failed to send packet in GUID processing"); + } + + HPSB_INFO("GUID request sent to node %d", nodeid & NODE_MASK); + atomic_inc(&outstanding_requests); + } +} + + +struct guid_entry *hpsb_guid_get_handle(u64 guid) +{ + unsigned long flags; + struct guid_entry *ge; + + read_lock_irqsave(&guid_lock, flags); + ge = find_entry(guid); + if (ge) atomic_inc(&ge->refcount); + read_unlock_irqrestore(&guid_lock, flags); + + return ge; +} + +struct hpsb_host *hpsb_guid_localhost(struct guid_entry *ge) +{ + if (atomic_read(&ge->generation) != get_hpsb_generation()) return NULL; + if (ge->node_id == ge->host->node_id) return ge->host; + return NULL; +} + +int hpsb_guid_fill_packet(struct guid_entry *ge, struct hpsb_packet *pkt) +{ + if (atomic_read(&ge->generation) != get_hpsb_generation()) return 0; + + pkt->host = ge->host; + pkt->node_id = ge->node_id; + pkt->generation = atomic_read(&ge->generation); + return 1; +} + + +static struct hpsb_highlevel_ops guid_ops = { + host_reset: host_reset, +}; + +void init_ieee1394_guid(void) +{ + atomic_set(&outstanding_requests, 0); + + if (!hpsb_register_highlevel("GUID manager", &guid_ops)) { + HPSB_ERR("out of memory during ieee1394 initialization"); + } +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/guid.h linux.ac/drivers/ieee1394/guid.h --- linux.vanilla/drivers/ieee1394/guid.h Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/ieee1394/guid.h Sun Jun 4 21:50:42 2000 @@ -0,0 +1,54 @@ + +#ifndef _IEEE1394_GUID_H +#define _IEEE1394_GUID_H + + +/* + * General information: Finding out which GUID belongs to which node is done by + * sending packets and therefore waiting for the answers. Wherever it is + * mentioned that a node is inaccessible this could just as well mean that we + * just don't know yet (usually, bus reset handlers can't rely on GUIDs being + * associated with current nodes). + */ + +struct guid_entry; +typedef struct guid_entry *hpsb_guid_t; + + +/* + * Returns a guid handle (which has its reference count incremented) or NULL if + * there is the GUID in question is not known of. Getting a valid handle does + * not mean that the node with this GUID is currently accessible (might not be + * plugged in or powered down). + */ +hpsb_guid_t hpsb_guid_get_handle(u64 guid); + +/* + * If the handle refers to a local host, this function will return the pointer + * to the hpsb_host structure. It will return NULL otherwise. Once you have + * established it is a local host, you can use that knowledge from then on (the + * GUID won't wander to an external node). + * + * Note that the local GUID currently isn't collected, so this will always + * return NULL. + */ +struct hpsb_host *hpsb_guid_localhost(hpsb_guid_t handle); + +/* + * This will fill in the given, pre-initialised hpsb_packet with the current + * information from the GUID handle (host, node ID, generation number). It will + * return false if the node owning the GUID is not accessible (and not modify the + * hpsb_packet) and return true otherwise. + * + * Note that packet sending may still fail in hpsb_send_packet if a bus reset + * happens while you are trying to set up the packet (due to obsolete generation + * number). It will at least reliably fail so that you don't accidentally and + * unknowingly send your packet to the wrong node. + */ +int hpsb_guid_fill_packet(hpsb_guid_t handle, struct hpsb_packet *pkt); + + +void init_ieee1394_guid(void); + + +#endif /* _IEEE1394_GUID_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/ieee1394_core.c linux.ac/drivers/ieee1394/ieee1394_core.c --- linux.vanilla/drivers/ieee1394/ieee1394_core.c Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/ieee1394_core.c Sun Jun 4 21:50:42 2000 @@ -25,6 +25,7 @@ #include "highlevel.h" #include "ieee1394_transactions.h" #include "csr.h" +#include "guid.h" atomic_t hpsb_generation = ATOMIC_INIT(0); @@ -45,6 +46,26 @@ } +/** + * alloc_hpsb_packet - allocate new packet structure + * @data_size: size of the data block to be allocated + * + * This function allocates, initializes and returns a new &struct hpsb_packet. + * It can be used in interrupt context. A header block is always included, its + * size is big enough to contain all possible 1394 headers. The data block is + * only allocated when @data_size is not zero. + * + * For packets for which responses will be received the @data_size has to be big + * enough to contain the response's data block since no further allocation + * occurs at response matching time. + * + * The packet's generation value will be set to the current generation number + * for ease of use. Remember to overwrite it with your own recorded generation + * number if you can not be sure that your code will not race with a bus reset. + * + * Return value: A pointer to a &struct hpsb_packet or NULL on allocation + * failure. + */ struct hpsb_packet *alloc_hpsb_packet(size_t data_size) { struct hpsb_packet *packet = NULL; @@ -83,6 +104,14 @@ return packet; } + +/** + * free_hpsb_packet - free packet and data associated with it + * @packet: packet to free (is NULL safe) + * + * This function will free packet->data, packet->header and finally the packet + * itself. + */ void free_hpsb_packet(struct hpsb_packet *packet) { if (packet == NULL) { @@ -336,6 +365,20 @@ queue_task(&host->timeout_tq, &tq_timer); } +/** + * hpsb_send_packet - transmit a packet on the bus + * @packet: packet to send + * + * The packet is sent through the host specified in the packet->host field. + * Before sending, the packet's transmit speed is automatically determined using + * the local speed map. + * + * Possibilities for failure are that host is either not initialized, in bus + * reset, the packet's generation number doesn't match the current generation + * number or the host reports a transmit error. + * + * Return value: False (0) on failure, true (1) otherwise. + */ int hpsb_send_packet(struct hpsb_packet *packet) { struct hpsb_host *host = packet->host; @@ -721,47 +764,6 @@ } -#if 0 -int hpsb_host_thread(void *hostPointer) -{ - struct hpsb_host *host = (struct hpsb_host *)hostPointer; - - /* I don't understand why, but I just want to be on the safe side. */ - lock_kernel(); - - HPSB_INFO(__FUNCTION__ " starting for one %s adapter", - host->template->name); - - exit_mm(current); - exit_files(current); - exit_fs(current); - - strcpy(current->comm, "ieee1394 thread"); - - /* ... but then again, I think the following is safe. */ - unlock_kernel(); - - for (;;) { - siginfo_t info; - unsigned long signr; - - if (signal_pending(current)) { - spin_lock_irq(¤t->sigmask_lock); - signr = dequeue_signal(¤t->blocked, &info); - spin_unlock_irq(¤t->sigmask_lock); - - break; - } - - abort_timedouts(host); - } - - HPSB_INFO(__FUNCTION__ " exiting"); - return 0; -} -#endif - - #ifndef MODULE void __init ieee1394_init(void) @@ -769,6 +771,7 @@ register_builtin_lowlevels(); init_hpsb_highlevel(); init_csr(); + init_ieee1394_guid(); } #else @@ -777,6 +780,8 @@ { init_hpsb_highlevel(); init_csr(); + init_ieee1394_guid(); + return 0; } 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 Sun Jun 4 21:50:42 2000 @@ -8,6 +8,7 @@ #include #include +#include #include "ieee1394_types.h" #include "hosts.h" @@ -15,6 +16,7 @@ #include "ieee1394_transactions.h" /* #include "events.h" */ #include "highlevel.h" +#include "guid.h" EXPORT_SYMBOL(hpsb_register_lowlevel); EXPORT_SYMBOL(hpsb_unregister_lowlevel); @@ -52,3 +54,7 @@ EXPORT_SYMBOL(highlevel_write); EXPORT_SYMBOL(highlevel_lock); EXPORT_SYMBOL(highlevel_lock64); + +EXPORT_SYMBOL(hpsb_guid_get_handle); +EXPORT_SYMBOL(hpsb_guid_localhost); +EXPORT_SYMBOL(hpsb_guid_fill_packet); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/ieee1394_transactions.c linux.ac/drivers/ieee1394/ieee1394_transactions.c --- linux.vanilla/drivers/ieee1394/ieee1394_transactions.c Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/ieee1394_transactions.c Sun Jun 4 21:50:42 2000 @@ -132,6 +132,26 @@ } +/** + * get_tlabel - allocate a transaction label + * @host: host to be used for transmission + * @nodeid: the node ID of the transmission target + * @wait: whether to sleep if no tlabel is available + * + * Every asynchronous transaction on the 1394 bus needs a transaction label to + * match the response to the request. This label has to be different from any + * other transaction label in an outstanding request to the same node to make + * matching possible without ambiguity. + * + * There are 64 different tlabels, so an allocated tlabel has to be freed with + * free_tlabel() after the transaction is complete (unless it's reused again for + * the same target node). + * + * @wait must not be set to true if you are calling from interrupt context. + * + * Return value: The allocated transaction label or -1 if there was no free + * tlabel and @wait is false. + */ int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait) { unsigned long flags; @@ -166,6 +186,18 @@ } } +/** + * free_tlabel - free an allocated transaction label + * @host: host to be used for transmission + * @nodeid: the node ID of the transmission target + * @tlabel: the transaction label to free + * + * Frees the transaction label allocated with get_tlabel(). The tlabel has to + * be freed after the transaction is complete (i.e. response was received for a + * split transaction or packet was sent for a unified transaction). + * + * A tlabel must not be freed twice. + */ void free_tlabel(struct hpsb_host *host, nodeid_t nodeid, int tlabel) { unsigned long flags; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/ieee1394_types.h linux.ac/drivers/ieee1394/ieee1394_types.h --- linux.vanilla/drivers/ieee1394/ieee1394_types.h Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/ieee1394_types.h Sun Jun 4 22:49:43 2000 @@ -27,7 +27,19 @@ #define __constant_cpu_to_be32(x) __constant_htonl((x)) -#endif +#define set_current_state(state_value) \ + do { current->state = (state_value); } while (0) + +#include +inline static int pci_enable_device(struct pci_dev *dev) +{ + u16 cmd; + pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY); + return 0; +} + +#endif /* Linux version < 2.3 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) #include @@ -39,6 +51,9 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif typedef __u32 quadlet_t; typedef __u64 octlet_t; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/ohci1394.c linux.ac/drivers/ieee1394/ohci1394.c --- linux.vanilla/drivers/ieee1394/ohci1394.c Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/ohci1394.c Sun Jun 4 21:50:42 2000 @@ -38,15 +38,25 @@ * . Self-id are sometimes not received properly * if card is initialized with no other nodes * on the bus + * . SONY CXD3222 chip is not working properly + * . Apple PowerBook detected but not working yet */ /* * Acknowledgments: * * Emilie Chung - * .Tip on Async Request Filter + * . Tip on Async Request Filter * Pascal Drolet - * .Various tips for optimization and functionnalities + * . Various tips for optimization and functionnalities + * Robert Ficklin + * . Loop in irq_handler + * James Goodwin + * . Various tips on initialization, self-id reception, etc. + * Albrecht Dress + * . Apple PowerBook detection + * Daniel Kobras + * . Reset the board properly before leaving */ #include @@ -65,6 +75,7 @@ #include #include #include +#include #include #include @@ -118,6 +129,7 @@ { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_UPD72862 }, { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_UPD72870 }, { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_UPD72871 }, + { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW }, { -1, -1 } }; @@ -128,7 +140,618 @@ static void remove_card(struct ti_ohci *ohci); static int init_driver(void); static void dma_trm_bh(void *data); +static void dma_rcv_bh(void *data); static void dma_trm_reset(struct dma_trm_ctx *d); +static void stop_context(struct ti_ohci *ohci, int reg, char *msg); + +#ifdef _VIDEO_1394_H + +/* Taken from bttv.c */ +/*******************************/ +/* Memory management functions */ +/*******************************/ + +#define MDEBUG(x) do { } while(0) /* Debug memory management */ + +/* [DaveM] I've recoded most of this so that: + * 1) It's easier to tell what is happening + * 2) It's more portable, especially for translating things + * out of vmalloc mapped areas in the kernel. + * 3) Less unnecessary translations happen. + * + * The code used to assume that the kernel vmalloc mappings + * existed in the page tables of every process, this is simply + * not guarenteed. We now use pgd_offset_k which is the + * defined way to get at the kernel page tables. + */ + +/* Given PGD from the address space's page table, return the kernel + * virtual mapping of the physical memory mapped at ADR. + */ +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) +{ + unsigned long ret = 0UL; + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, adr); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, adr); + pte = *ptep; + if(pte_present(pte)) + ret = (pte_page(pte)|(adr&(PAGE_SIZE-1))); + } + } + MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret)); + return ret; +} + +static inline unsigned long uvirt_to_bus(unsigned long adr) +{ + unsigned long kva, ret; + + kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr); + ret = virt_to_bus((void *)kva); + MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret)); + return ret; +} + +static inline unsigned long kvirt_to_bus(unsigned long adr) +{ + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = virt_to_bus((void *)kva); + MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret)); + return ret; +} + +/* Here we want the physical address of the memory. + * This is used when initializing the contents of the + * area and marking the pages as reserved. + */ +static inline unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = __pa(kva); + MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret)); + return ret; +} + +static void * rvmalloc(unsigned long size) +{ + void * mem; + unsigned long adr, page; + + mem=vmalloc(size); + if (mem) + { + memset(mem, 0, size); /* Clear the ram out, no junk to the user */ + adr=(unsigned long) mem; + while (size > 0) + { + page = kvirt_to_pa(adr); + mem_map_reserve(MAP_NR(__va(page))); + adr+=PAGE_SIZE; + size-=PAGE_SIZE; + } + } + return mem; +} + +static void rvfree(void * mem, unsigned long size) +{ + unsigned long adr, page; + + if (mem) + { + adr=(unsigned long) mem; + while (size > 0) + { + page = kvirt_to_pa(adr); + mem_map_unreserve(MAP_NR(__va(page))); + adr+=PAGE_SIZE; + size-=PAGE_SIZE; + } + vfree(mem); + } +} + +static int free_dma_fbuf_ctx(struct dma_fbuf_ctx **d) +{ + int i; + struct ti_ohci *ohci; + + if ((*d)==NULL) return -1; + + ohci = (struct ti_ohci *)(*d)->ohci; + + DBGMSG(ohci->id, "Freeing dma_fbuf_ctx %d", (*d)->ctx); + + stop_context(ohci, (*d)->ctrlClear, NULL); + + if ((*d)->buf) rvfree((void *)(*d)->buf, + (*d)->num_desc * (*d)->buf_size); + + if ((*d)->prg) { + for (i=0;i<(*d)->num_desc;i++) + if ((*d)->prg[i]) kfree((*d)->prg[i]); + kfree((*d)->prg); + } + + if ((*d)->buffer_status) + kfree((*d)->buffer_status); + + kfree(*d); + *d = NULL; + + return 0; +} + +static struct dma_fbuf_ctx * +alloc_dma_fbuf_ctx(struct ti_ohci *ohci, int ctx, int num_desc, + int buf_size, int channel) +{ + struct dma_fbuf_ctx *d=NULL; + int i; + + d = (struct dma_fbuf_ctx *)kmalloc(sizeof(struct dma_fbuf_ctx), + GFP_KERNEL); + + if (d==NULL) { + PRINT(KERN_ERR, ohci->id, "failed to allocate dma_fbuf_ctx"); + return NULL; + } + + d->ohci = (void *)ohci; + d->ctx = ctx; + d->channel = channel; + d->num_desc = num_desc; + d->frame_size = buf_size; + if (buf_size%PAGE_SIZE) + d->buf_size = buf_size + PAGE_SIZE - (buf_size%PAGE_SIZE); + else + d->buf_size = buf_size; + d->ctrlSet = OHCI1394_IrRcvContextControlSet+32*d->ctx; + d->ctrlClear = OHCI1394_IrRcvContextControlClear+32*d->ctx; + d->cmdPtr = OHCI1394_IrRcvCommandPtr+32*d->ctx; + d->ctxMatch = OHCI1394_IrRcvContextMatch+32*d->ctx; + d->nb_cmd = d->buf_size / PAGE_SIZE + 1; + d->last_buffer = 0; + d->buf = NULL; + d->prg = NULL; + init_waitqueue_head(&d->waitq); + + d->buf = rvmalloc(d->num_desc * d->buf_size); + + if (d->buf == NULL) { + PRINT(KERN_ERR, ohci->id, "failed to allocate dma fbuffer"); + free_dma_fbuf_ctx(&d); + return NULL; + } + memset(d->buf, 0, d->num_desc * d->buf_size); + + d->prg = kmalloc(d->num_desc * sizeof(struct dma_cmd *), + GFP_KERNEL); + + if (d->prg == NULL) { + PRINT(KERN_ERR, ohci->id, "failed to allocate dma fbuf prg"); + free_dma_fbuf_ctx(&d); + return NULL; + } + memset(d->prg, 0, d->num_desc * sizeof(struct dma_cmd *)); + + for (i=0;inum_desc;i++) { + d->prg[i] = kmalloc(d->nb_cmd * sizeof(struct dma_cmd), + GFP_KERNEL); + if (d->prg[i] == NULL) { + PRINT(KERN_ERR, ohci->id, + "failed to allocate dma fbuf prg"); + free_dma_fbuf_ctx(&d); + return NULL; + } + } + + d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int), + GFP_KERNEL); + + if (d->buffer_status == NULL) { + PRINT(KERN_ERR, ohci->id, "failed to allocate dma fbuf prg"); + free_dma_fbuf_ctx(&d); + return NULL; + } + memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int)); + + PRINT(KERN_INFO, ohci->id, "Iso DMA to User's Space: %d buffers " + "of size %d allocated for a frame size %d, each with %d prgs", + d->num_desc, d->buf_size, d->frame_size, d->nb_cmd); + + return d; +} + +static void initialize_dma_fbuf_prg(struct dma_cmd *prg, int n, + int frame_size, unsigned long buf) +{ + int i; + int leftsize = (frame_size%PAGE_SIZE) ? + frame_size%PAGE_SIZE : PAGE_SIZE; + + /* the first descriptor will sync and read only 4 bytes */ + prg[0].control = (0x280F << 16) | 4; + prg[0].address = kvirt_to_bus(buf); + prg[0].branchAddress = (virt_to_bus(&(prg[1].control)) + & 0xfffffff0) | 0x1; + prg[0].status = 0; + + /* the second descriptor will read PAGE_SIZE-4 bytes */ + prg[1].control = (0x280C << 16) | (PAGE_SIZE-4); + prg[1].address = kvirt_to_bus(buf+4); + prg[1].branchAddress = (virt_to_bus(&(prg[2].control)) + & 0xfffffff0) | 0x1; + prg[1].status = 0; + + for (i=2;iohci; + int i; + + stop_context(ohci, d->ctrlClear, NULL); + + for (i=0;inum_desc;i++) { + initialize_dma_fbuf_prg(d->prg[i], d->nb_cmd, d->frame_size, + (unsigned long)d->buf+i*d->buf_size); + } + + /* Set bufferFill, no header */ + reg_write(ohci, d->ctrlSet, 0x80000000); + + /* Set the context match register to match on all tags, + sync for sync tag, and listen to d->channel */ + reg_write(ohci, d->ctxMatch, 0xf0000000|((tag&0xf)<<8)|d->channel); + + /* Set up isoRecvIntMask to generate interrupts */ + reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1<ctx); +} + +/* find which context is listening to this channel */ +int fbuf_ctx_listening(struct ti_ohci *ohci, int channel) +{ + int i; + for (i=0;inb_iso_ctx-1;i++) + if (ohci->fbuf_context[i]) { + if (ohci->fbuf_context[i]->channel==channel) + return i; + } + + PRINT(KERN_ERR, ohci->id, + "no iso context is listening to channel %d", + channel); + return -1; +} + +static int ohci_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct ti_ohci *ohci=&cards[MINOR(inode->i_rdev)]; + + switch(cmd) + { + case VIDEO1394_LISTEN_CHANNEL: + { + struct video1394_mmap v; + int i; + + if(copy_from_user(&v, (void *)arg, sizeof(v))) + return -EFAULT; + if (v.channel<0 || v.channel>(ISO_CHANNELS-1)) { + PRINT(KERN_ERR, ohci->id, + "iso channel %d out of bound", v.channel); + return -EFAULT; + } + if (test_and_set_bit(v.channel, &ohci->IR_channel_usage)) { + PRINT(KERN_ERR, ohci->id, + "channel %d is already taken", v.channel); + return -EFAULT; + } + + /* find a free iso context */ + for (i=0;inb_iso_ctx-1;i++) + if (ohci->fbuf_context[i]==NULL) break; + + if (i==(ohci->nb_iso_ctx-1)) { + PRINT(KERN_ERR, ohci->id, "no iso context available"); + return -EFAULT; + } + + if (v.nb_buffers * v.buf_size > VIDEO1394_MAX_SIZE) { + PRINT(KERN_ERR, ohci->id, + "%d buffers of size %d bytes is too big", + v.nb_buffers, v.buf_size); + return -EFAULT; + } + + ohci->fbuf_context[i] = + alloc_dma_fbuf_ctx(ohci, i+1, v.nb_buffers, + v.buf_size, v.channel); + + if (ohci->fbuf_context[i] == NULL) { + PRINT(KERN_ERR, ohci->id, + "Couldn't allocate fbuf context"); + return -EFAULT; + } + initialize_dma_fbuf_ctx(ohci->fbuf_context[i], v.sync_tag); + + ohci->current_fbuf_ctx = ohci->fbuf_context[i]; + + v.buf_size = ohci->fbuf_context[i]->buf_size; + + PRINT(KERN_INFO, ohci->id, + "iso context %d listen on channel %d", i+1, + v.channel); + + if(copy_to_user((void *)arg, &v, sizeof(v))) + return -EFAULT; + + return 0; + } + case VIDEO1394_UNLISTEN_CHANNEL: + { + int channel; + int i; + + if(copy_from_user(&channel, (void *)arg, sizeof(int))) + return -EFAULT; + + if (!test_and_clear_bit(channel, &ohci->IR_channel_usage)) { + PRINT(KERN_ERR, ohci->id, + "channel %d is not being used", channel); + return -EFAULT; + } + + i = fbuf_ctx_listening(ohci, channel); + if (i<0) return -EFAULT; + + free_dma_fbuf_ctx(&ohci->fbuf_context[i]); + + PRINT(KERN_INFO, ohci->id, + "iso context %d stop listening on channel %d", + i+1, channel); + + return 0; + } + case VIDEO1394_QUEUE_BUFFER: + { + struct video1394_wait v; + struct dma_fbuf_ctx *d; + int i; + + if(copy_from_user(&v, (void *)arg, sizeof(v))) + return -EFAULT; + + i = fbuf_ctx_listening(ohci, v.channel); + if (i<0) return -EFAULT; + d = ohci->fbuf_context[i]; + + if ((v.buffer<0) || (v.buffer>d->num_desc)) { + PRINT(KERN_ERR, ohci->id, + "buffer %d out of range",v.buffer); + return -EFAULT; + } + + if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) { + PRINT(KERN_ERR, ohci->id, + "buffer %d is already used",v.buffer); + return -EFAULT; + } + + d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; + + d->prg[d->last_buffer][d->nb_cmd-1].branchAddress = + (virt_to_bus(&(d->prg[v.buffer][0].control)) + & 0xfffffff0) | 0x1; + + d->last_buffer = v.buffer; + + if (!(reg_read(ohci, d->ctrlSet) & 0x8000)) + { + DBGMSG(ohci->id, "Starting iso DMA ctx=%d",d->ctx); + + /* Tell the controller where the first program is */ + reg_write(ohci, d->cmdPtr, + virt_to_bus(&(d->prg[v.buffer][0])) | 0x1 ); + + /* Run IR context */ + reg_write(ohci, d->ctrlSet, 0x8000); + } + else { + /* Wake up dma context if necessary */ + if (!(reg_read(ohci, d->ctrlSet) & 0x400)) { + PRINT(KERN_INFO, ohci->id, + "Waking up iso dma ctx=%d", d->ctx); + reg_write(ohci, d->ctrlSet, 0x1000); + } + } + return 0; + + } + case VIDEO1394_WAIT_BUFFER: + { + struct video1394_wait v; + struct dma_fbuf_ctx *d; + int i; + + if(copy_from_user(&v, (void *)arg, sizeof(v))) + return -EFAULT; + + i = fbuf_ctx_listening(ohci, v.channel); + if (i<0) return -EFAULT; + d = ohci->fbuf_context[i]; + + if ((v.buffer<0) || (v.buffer>d->num_desc)) { + PRINT(KERN_ERR, ohci->id, + "buffer %d out of range",v.buffer); + return -EFAULT; + } + + switch(d->buffer_status[v.buffer]) { + case VIDEO1394_BUFFER_READY: + d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE; + return 0; + case VIDEO1394_BUFFER_QUEUED: + while(d->buffer_status[v.buffer]!= + VIDEO1394_BUFFER_READY) { + interruptible_sleep_on(&d->waitq); + if(signal_pending(current)) return -EINTR; + } + d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE; + return 0; + default: + PRINT(KERN_ERR, ohci->id, + "buffer %d is not queued",v.buffer); + return -EFAULT; + } + } + default: + return -EINVAL; + } +} + +/* + * This maps the vmalloced and reserved fbuffer to user space. + * + * FIXME: + * - PAGE_READONLY should suffice!? + * - remap_page_range is kind of inefficient for page by page remapping. + * But e.g. pte_alloc() does not work in modules ... :-( + */ + +static int do_fbuf_mmap(struct ti_ohci *ohci, struct dma_fbuf_ctx *d, + const char *adr, unsigned long size) +{ + unsigned long start=(unsigned long) adr; + unsigned long page,pos; + + if (size>d->num_desc * d->buf_size) { + PRINT(KERN_ERR, ohci->id, + "fbuf context %d buf size is different from mmap size", + d->ctx); + return -EINVAL; + } + if (!d->buf) { + PRINT(KERN_ERR, ohci->id, + "fbuf context %d is not allocated", d->ctx); + return -EINVAL; + } + + pos=(unsigned long) d->buf; + while (size > 0) { + page = kvirt_to_pa(pos); + if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; + start+=PAGE_SIZE; + pos+=PAGE_SIZE; + size-=PAGE_SIZE; + } + return 0; +} + +int ohci_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct ti_ohci *ohci=&cards[MINOR(file->f_dentry->d_inode->i_rdev)]; + PRINT(KERN_INFO, ohci->id, "mmap"); + if (ohci->current_fbuf_ctx == NULL) { + PRINT(KERN_ERR, ohci->id, "current fbuf context not set"); + return -EINVAL; + } + + return do_fbuf_mmap(ohci, ohci->current_fbuf_ctx, + (char *)vma->vm_start, + (unsigned long)(vma->vm_end-vma->vm_start)); + return 0; +} + +static int ohci_open(struct inode *inode, struct file *file) +{ + struct ti_ohci *ohci=&cards[MINOR(inode->i_rdev)]; + PRINT(KERN_INFO, ohci->id, "open"); + return 0; +} + +static int ohci_release(struct inode *inode, struct file *file) +{ + struct ti_ohci *ohci=&cards[MINOR(inode->i_rdev)]; + int i; + + PRINT(KERN_INFO, ohci->id, "release"); + for (i=0;inb_iso_ctx-1;i++) + if (ohci->fbuf_context[i]) { + if (!test_and_clear_bit(ohci->fbuf_context[i]->channel, + &ohci->IR_channel_usage)) { + PRINT(KERN_ERR, ohci->id, + "channel %d is not being used", + ohci->fbuf_context[i]->channel); + } + PRINT(KERN_INFO, ohci->id, + "iso context %d stop listening on channel %d", + i+1, ohci->fbuf_context[i]->channel); + free_dma_fbuf_ctx(&ohci->fbuf_context[i]); + } + return 0; +} + +static struct file_operations ohci_fops= +{ + ioctl: ohci_ioctl, + mmap: ohci_mmap, + open: ohci_open, + release: ohci_release +}; + +int wakeup_dma_fbuf_ctx(struct ti_ohci *ohci, struct dma_fbuf_ctx *d) +{ + int i; + + if (d==NULL) { + PRINT(KERN_ERR, ohci->id, "Iso receive event received but " + "context not allocated"); + return -EFAULT; + } + + for (i=0;inum_desc;i++) { + if (d->prg[i][d->nb_cmd-1].status) { + d->prg[i][d->nb_cmd-1].status=0; + d->buffer_status[i] = VIDEO1394_BUFFER_READY; + } + } + if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq); + return 0; +} + +#endif + + /*********************************** * IEEE-1394 functionality section * @@ -220,6 +843,22 @@ "Error in reception of self-id packets" "Self-id count: %08x q[0]: %08x", self_id_count, q[0]); + + /* + * Tip by James Goodwin : + * We had an error, generate another bus reset in response. + * TODO. Actually read the current value in the phy before + * generating a bus reset (read modify write). This way + * we don't stomp any current gap count settings, etc. + */ + if (ohci->self_id_errorsself_id_errors++; + } + else { + PRINT(KERN_ERR, ohci->id, + "Timeout on self-id error reception"); + } return -1; } @@ -411,15 +1050,34 @@ spin_lock_init(&ohci->phy_reg_lock); + /* + * Tip by James Goodwin : + * We need to add delays after the soft reset, setting LPS, and + * enabling our link. This might fixes the self-id reception + * problem at initialization. + */ + /* Soft reset */ if ((retval=ohci_soft_reset(ohci))<0) return retval; - - /* Set the bus number */ - reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0); + /* + *Delay aftger soft reset to make sure everything has settled + * down (sanity) + */ + mdelay(100); + /* Set Link Power Status (LPS) */ reg_write(ohci, OHCI1394_HCControlSet, 0x00080000); + /* + * Delay after setting LPS in order to make sure link/phy + * communication is established + */ + mdelay(100); + + /* Set the bus number */ + reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0); + /* Enable posted writes */ reg_write(ohci, OHCI1394_HCControlSet, 0x00040000); @@ -464,9 +1122,6 @@ /* Don't accept phy packets into AR request context */ reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400); - /* Enable link */ - reg_write(ohci, OHCI1394_HCControlSet, 0x00020000); - /* Initialize IR dma */ ohci->nb_iso_ctx = get_nb_iso_ctx(ohci); PRINT(KERN_INFO, ohci->id, "%d iso contexts available", @@ -477,7 +1132,18 @@ reg_write(ohci, OHCI1394_IrRcvContextMatch+32*i, 0); reg_write(ohci, OHCI1394_IrRcvCommandPtr+32*i, 0); } - +#ifdef _VIDEO_1394_H + ohci->fbuf_context = (struct dma_fbuf_ctx **) + kmalloc((ohci->nb_iso_ctx-1)*sizeof(struct dma_fbuf_ctx *), + GFP_KERNEL); + if (ohci->fbuf_context) + memset(ohci->fbuf_context, 0, + (ohci->nb_iso_ctx-1)*sizeof(struct dma_fbuf_ctx *)); + else { + PRINT(KERN_ERR, ohci->id, "Cannot allocate fbuf_context"); + return -1; + } +#endif /* Set bufferFill, isochHeader, multichannel for IR context */ reg_write(ohci, OHCI1394_IrRcvContextControlSet, 0xd0000000); @@ -495,16 +1161,6 @@ (thanks to Michael Greger for seeing that I forgot this) */ reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 0x00000001); - initialize_dma_rcv_ctx(ohci->ir_context); - - /* Initialize AR dma */ - initialize_dma_rcv_ctx(ohci->ar_req_context); - initialize_dma_rcv_ctx(ohci->ar_resp_context); - - /* Initialize AT dma */ - initialize_dma_trm_ctx(ohci->at_req_context); - initialize_dma_trm_ctx(ohci->at_resp_context); - /* * Accept AT requests from all nodes. This probably * will have to be controlled from the subsystem @@ -539,6 +1195,20 @@ OHCI1394_isochRx ); + /* Enable link */ + reg_write(ohci, OHCI1394_HCControlSet, 0x00020000); + + /* Initialize AR dma */ + initialize_dma_rcv_ctx(ohci->ar_req_context); + initialize_dma_rcv_ctx(ohci->ar_resp_context); + + /* Initialize AT dma */ + initialize_dma_trm_ctx(ohci->at_req_context); + initialize_dma_trm_ctx(ohci->at_resp_context); + + /* Initialize IR dma */ + initialize_dma_rcv_ctx(ohci->ir_context); + return 1; } @@ -619,7 +1289,7 @@ struct ti_ohci *ohci = host->hostdata; struct dma_trm_ctx *d; unsigned char tcode; - int i=50; + int timeout=50; if (packet->data_size >= ohci->max_packet_size) { PRINT(KERN_ERR, ohci->id, @@ -642,8 +1312,9 @@ } while (d->free_prgs<1) { spin_unlock(&d->lock); - schedule(); - if (i-- <0) { + interruptible_sleep_on(&d->waitq); + if(signal_pending(current)) return -EINTR; + if (timeout--<0) { stop_context(ohci, d->ctrlClear, "AT DMA runaway loop... bailing out"); return 0; @@ -687,7 +1358,7 @@ switch (cmd) { case RESET_BUS: - host->attempt_root=1; + host->attempt_root=1; PRINT(KERN_INFO, ohci->id, "resetting bus on request%s", (host->attempt_root ? " and attempting to become root" : "")); @@ -743,6 +1414,11 @@ spin_lock_irqsave(&ohci->IR_channel_lock, flags); +#if 0 + PRINT(KERN_INFO, ohci->id, "!!! try listen on channel %d !!!", + arg); +#endif + if (!test_and_set_bit(arg, &ohci->IR_channel_usage)) { PRINT(KERN_INFO, ohci->id, "listening enabled on channel %d", arg); @@ -845,137 +1521,179 @@ struct ti_ohci *ohci = (struct ti_ohci *)dev_id; struct hpsb_host *host = ohci->host; int phyid = -1, isroot = 0; + int timeout = 255; - /* read the interrupt event register */ - event=reg_read(ohci, OHCI1394_IntEventSet); - -#if 0 - /* - * clear the interrupt event register, except for the - * bus reset event interrupt (if any). This is an - * attempt to comply with ohci spec 7.2.3.2 - */ - reg_write(ohci, OHCI1394_IntEventClear, event & (~OHCI1394_busReset)); + do { + /* read the interrupt event register */ + event=reg_read(ohci, OHCI1394_IntEventClear); + + DBGMSG(ohci->id, "IntEvent: %08x",event); + + if (!event) return; + + /* clear the interrupt event register */ + reg_write(ohci, OHCI1394_IntEventClear, event); + + if (event & OHCI1394_busReset) { + if (!host->in_bus_reset) { + PRINT(KERN_INFO, ohci->id, "Bus reset"); + + /* Wait for the AT fifo to be flushed */ + dma_trm_reset(ohci->at_req_context); + dma_trm_reset(ohci->at_resp_context); + + /* Subsystem call */ + hpsb_bus_reset(ohci->host); + + ohci->NumBusResets++; + } + } + /* + * Problem: How can I ensure that the AT bottom half will be + * executed before the AR bottom half (both events may have + * occured within a single irq event) + * Quick hack: just launch it within the IRQ handler + */ + if (event & OHCI1394_reqTxComplete) { + struct dma_trm_ctx *d = ohci->at_req_context; + DBGMSG(ohci->id, "Got reqTxComplete interrupt " + "status=0x%08X", reg_read(ohci, d->ctrlSet)); + if (reg_read(ohci, d->ctrlSet) & 0x800) + stop_context(ohci, d->ctrlClear, + "reqTxComplete"); + else + dma_trm_bh((void *)d); + } + if (event & OHCI1394_respTxComplete) { + struct dma_trm_ctx *d = ohci->at_resp_context; + DBGMSG(ohci->id, "Got respTxComplete interrupt " + "status=0x%08X", reg_read(ohci, d->ctrlSet)); + if (reg_read(ohci, d->ctrlSet) & 0x800) + stop_context(ohci, d->ctrlClear, + "respTxComplete"); + else + dma_trm_bh((void *)d); + } + if (event & OHCI1394_RQPkt) { + struct dma_rcv_ctx *d = ohci->ar_req_context; + DBGMSG(ohci->id, "Got RQPkt interrupt status=0x%08X", + reg_read(ohci, d->ctrlSet)); + if (reg_read(ohci, d->ctrlSet) & 0x800) + stop_context(ohci, d->ctrlClear, "RQPkt"); + else { +#if 1 + queue_task(&d->task, &tq_immediate); + mark_bh(IMMEDIATE_BH); #else - /* The above attempt doesn't work */ - reg_write(ohci, OHCI1394_IntEventClear, event); + dma_rcv_bh((void *)d); #endif - if (event & OHCI1394_busReset) { - if (!host->in_bus_reset) { - PRINT(KERN_INFO, ohci->id, "Bus reset"); - - /* Wait for the AT fifo to be flushed */ - dma_trm_reset(ohci->at_req_context); - dma_trm_reset(ohci->at_resp_context); - -#if 0 - /* clear the bus reset event */ - reg_write(ohci, OHCI1394_IntEventClear, - OHCI1394_busReset); -#endif - /* Subsystem call */ - hpsb_bus_reset(ohci->host); - - ohci->NumBusResets++; + } } - } - /* - * Problem: How can I ensure that the AT bottom half will be - * executed before the AR bottom half (both events may have - * occured within a single irq event) - * Quick hack: just launch it within the IRQ handler - */ - if (event & OHCI1394_reqTxComplete) { - struct dma_trm_ctx *d = ohci->at_req_context; - DBGMSG(ohci->id, "Got reqTxComplete interrupt status=0x%08X", - reg_read(ohci, d->ctrlSet)); - if (reg_read(ohci, d->ctrlSet) & 0x800) - stop_context(ohci, d->ctrlClear, "reqTxComplete"); - else - dma_trm_bh((void *)d); - } - if (event & OHCI1394_respTxComplete) { - struct dma_trm_ctx *d = ohci->at_resp_context; - DBGMSG(ohci->id, "Got respTxComplete interrupt status=0x%08X", - reg_read(ohci, d->ctrlSet)); - if (reg_read(ohci, d->ctrlSet) & 0x800) - stop_context(ohci, d->ctrlClear, "respTxComplete"); - else - dma_trm_bh((void *)d); - } - if (event & OHCI1394_RQPkt) { - struct dma_rcv_ctx *d = ohci->ar_req_context; - DBGMSG(ohci->id, "Got RQPkt interrupt status=0x%08X", - reg_read(ohci, d->ctrlSet)); - if (reg_read(ohci, d->ctrlSet) & 0x800) - stop_context(ohci, d->ctrlClear, "RQPkt"); - else { - queue_task(&d->task, &tq_immediate); - mark_bh(IMMEDIATE_BH); + if (event & OHCI1394_RSPkt) { + struct dma_rcv_ctx *d = ohci->ar_resp_context; + DBGMSG(ohci->id, "Got RSPkt interrupt status=0x%08X", + reg_read(ohci, d->ctrlSet)); + if (reg_read(ohci, d->ctrlSet) & 0x800) + stop_context(ohci, d->ctrlClear, "RSPkt"); + else { +#if 1 + queue_task(&d->task, &tq_immediate); + mark_bh(IMMEDIATE_BH); +#else + dma_rcv_bh((void *)d); +#endif + } } - } - if (event & OHCI1394_RSPkt) { - struct dma_rcv_ctx *d = ohci->ar_resp_context; - DBGMSG(ohci->id, "Got RSPkt interrupt status=0x%08X", - reg_read(ohci, d->ctrlSet)); - if (reg_read(ohci, d->ctrlSet) & 0x800) - stop_context(ohci, d->ctrlClear, "RSPkt"); - else { - queue_task(&d->task, &tq_immediate); - mark_bh(IMMEDIATE_BH); + if (event & OHCI1394_isochRx) { + quadlet_t isoRecvIntEvent; + struct dma_rcv_ctx *d = ohci->ir_context; +#ifdef _VIDEO_1394_H + int i; +#endif + isoRecvIntEvent = + reg_read(ohci, OHCI1394_IsoRecvIntEventSet); + reg_write(ohci, OHCI1394_IsoRecvIntEventClear, + isoRecvIntEvent); + DBGMSG(ohci->id, "Got isochRx interrupt " + "status=0x%08X isoRecvIntEvent=%08x", + reg_read(ohci, d->ctrlSet), isoRecvIntEvent); + if (isoRecvIntEvent & 0x1) { + if (reg_read(ohci, d->ctrlSet) & 0x800) + stop_context(ohci, d->ctrlClear, + "isochRx"); + else { +#if 1 + queue_task(&d->task, &tq_immediate); + mark_bh(IMMEDIATE_BH); +#else + dma_rcv_bh((void *)d); +#endif + } + } +#ifdef _VIDEO_1394_H + for (i=0;inb_iso_ctx-1;i++) + if (isoRecvIntEvent & (1<<(i+1))) + wakeup_dma_fbuf_ctx( + ohci,ohci->fbuf_context[i]); +#endif } - } - if (event & OHCI1394_isochRx) { - quadlet_t isoRecvIntEvent; - struct dma_rcv_ctx *d = ohci->ir_context; - isoRecvIntEvent = reg_read(ohci, OHCI1394_IsoRecvIntEventSet); - reg_write(ohci, OHCI1394_IsoRecvIntEventClear, - isoRecvIntEvent); - DBGMSG(ohci->id, "Got reqTxComplete interrupt status=0x%08X", - reg_read(ohci, d->ctrlSet)); - if (reg_read(ohci, d->ctrlSet) & 0x800) - stop_context(ohci, d->ctrlClear, "isochRx"); - else { - queue_task(&d->task, &tq_immediate); - mark_bh(IMMEDIATE_BH); + if (event & OHCI1394_selfIDComplete) { + if (host->in_bus_reset) { + node_id = reg_read(ohci, OHCI1394_NodeID); + if (node_id & 0x80000000) { /* NodeID valid */ + phyid = node_id & 0x0000003f; + isroot = (node_id & 0x40000000) != 0; + + PRINT(KERN_INFO, ohci->id, + "SelfID process finished " + "(phyid %d, %s)", phyid, + (isroot ? "root" : "not root")); + + handle_selfid(ohci, host, + phyid, isroot); + } + else + PRINT(KERN_ERR, ohci->id, + "SelfID process finished but " + "NodeID not valid: %08X", + node_id); + + /* Accept Physical requests from all nodes. */ + reg_write(ohci,OHCI1394_AsReqFilterHiSet, + 0xffffffff); + reg_write(ohci,OHCI1394_AsReqFilterLoSet, + 0xffffffff); + /* + * Tip by James Goodwin + * Turn on phys dma reception. We should + * probably manage the filtering somehow, + * instead of blindly turning it on. + */ + reg_write(ohci,OHCI1394_PhyReqFilterHiSet, + 0xffffffff); + reg_write(ohci,OHCI1394_PhyReqFilterLoSet, + 0xffffffff); + reg_write(ohci,OHCI1394_PhyUpperBound, + 0xffff0000); + } + else PRINT(KERN_ERR, ohci->id, + "self-id received outside of bus reset" + "sequence"); } - } - if (event & OHCI1394_selfIDComplete) { - if (host->in_bus_reset) { - node_id = reg_read(ohci, OHCI1394_NodeID); - if (node_id & 0x80000000) { /* NodeID valid */ - phyid = node_id & 0x0000003f; - isroot = (node_id & 0x40000000) != 0; - - PRINT(KERN_INFO, ohci->id, - "SelfID process finished (phyid %d, %s)", - phyid, (isroot ? "root" : "not root")); - - handle_selfid(ohci, host, phyid, isroot); + if (event & OHCI1394_phyRegRcvd) { +#if 1 + if (host->in_bus_reset) { + PRINT(KERN_INFO, ohci->id, "PhyControl: %08X", + reg_read(ohci, OHCI1394_PhyControl)); } - else - PRINT(KERN_ERR, ohci->id, - "SelfID process finished but NodeID" - " not valid: %08X",node_id); - - /* Accept Physical requests from all nodes. */ - reg_write(ohci,OHCI1394_AsReqFilterHiSet, 0xffffffff); - reg_write(ohci,OHCI1394_AsReqFilterLoSet, 0xffffffff); - } - else PRINT(KERN_INFO, ohci->id, - "phy reg received without reset\n"); - } - if (event & OHCI1394_phyRegRcvd) { -#if 0 - if (host->in_bus_reset) { - PRINT(KERN_INFO, ohci->id, "PhyControl: %08X", - reg_read(ohci, OHCI1394_PhyControl)); - } else - PRINT(KERN_ERR, ohci->id, - "phy reg received without reset"); + else PRINT(KERN_ERR, ohci->id, + "phy reg received outside of bus reset" + "sequence"); #endif - } + } + } while (--timeout); + PRINT(KERN_ERR, ohci->id, "irq_handler timeout event=0x%08x", event); } /* Put the buffer back into the dma context */ @@ -1119,6 +1837,17 @@ buf_ptr += offset/4; } + /* + * Tip by James Goodwin + * We need to handle write requests that are received + * to our middle address space (posted writes). + * In this case, the hardware generates an + * ack_complete... but, if we pass the packet up to + * the subsystem, it will try and send a response + * (which it shouldn't), because it assumes we + * returned ack_pending. + */ + /* * We get one phy packet for each bus reset. * we know that from now on the bus topology may @@ -1132,6 +1861,20 @@ (d->spb[length/4-1]>>16)&0x1f, (d->spb[length/4-1]>>21)&0x3, tcode, length, d->spb[3], d->ctx); + + /* + * Tip by James Goodwin + * Handle case of posted writes. If we receive + * an ack_complete, we should not send a + * response. Fake out upper layers by turning + * the packet into a broadcast packet... we + * should really modify the core stack to + * accept an ack received argument and figure + * out whether to reply. + */ + if (((d->spb[length/4-1]>>16)&0x1f) == 0x11) { + d->spb[0] |= (ALL_NODES<<16); + } hpsb_packet_received(ohci->host, d->spb, length); } @@ -1154,6 +1897,20 @@ (buf_ptr[length/4-1]>>16)&0x1f, (buf_ptr[length/4-1]>>21)&0x3, tcode, length, buf_ptr[3], d->ctx); + + /* + * Tip by James Goodwin + * Handle case of posted writes. If we receive + * an ack_complete, we should not send a + * response. Fake out upper layers by turning + * the packet into a broadcast packet... we + * should really modify the core stack to + * accept an ack received argument and figure + * out whether to reply. + */ + if (((d->spb[length/4-1]>>16)&0x1f) == 0x11) { + buf_ptr[0] |= (ALL_NODES<<16); + } hpsb_packet_received(ohci->host, buf_ptr, length); } @@ -1207,32 +1964,42 @@ d->sent_ind = (d->sent_ind+1)%d->num_desc; d->free_prgs++; spin_unlock(&d->lock); - + + if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq); + DBGMSG(ohci->id, "Packet sent to node %d ack=0x%X spd=%d ctx=%d", (packet->header[0]>>16)&0x3f, ack&0x1f, (ack>>5)&0x3, d->ctx); hpsb_packet_sent(ohci->host, packet, ack&0xf); } -static int free_dma_rcv_ctx(struct dma_rcv_ctx *d) +static int free_dma_rcv_ctx(struct dma_rcv_ctx **d) { int i; + struct ti_ohci *ohci; - if (d==NULL) return -1; + if (*d==NULL) return -1; - if (d->buf) { - for (i=0; inum_desc; i++) - if (d->buf[i]) kfree(d->buf[i]); - kfree(d->buf); - } - if (d->prg) { - for (i=0; inum_desc; i++) - if (d->prg[i]) kfree(d->prg[i]); - kfree(d->prg); - } - if (d->spb) kfree(d->spb); + ohci = (struct ti_ohci *)(*d)->ohci; + + DBGMSG(ohci->id, "Freeing dma_rcv_ctx %d",(*d)->ctx); - kfree(d); + stop_context(ohci, (*d)->ctrlClear, NULL); + + if ((*d)->buf) { + for (i=0; i<(*d)->num_desc; i++) + if ((*d)->buf[i]) kfree((*d)->buf[i]); + kfree((*d)->buf); + } + if ((*d)->prg) { + for (i=0; i<(*d)->num_desc; i++) + if ((*d)->prg[i]) kfree((*d)->prg[i]); + kfree((*d)->prg); + } + if ((*d)->spb) kfree((*d)->spb); + kfree(*d); + *d = NULL; + return 0; } @@ -1270,7 +2037,7 @@ if (d->buf == NULL) { PRINT(KERN_ERR, ohci->id, "failed to allocate dma buffer"); - free_dma_rcv_ctx(d); + free_dma_rcv_ctx(&d); return NULL; } memset(d->buf, 0, d->num_desc * sizeof(quadlet_t*)); @@ -1279,7 +2046,7 @@ if (d->prg == NULL) { PRINT(KERN_ERR, ohci->id, "failed to allocate dma prg"); - free_dma_rcv_ctx(d); + free_dma_rcv_ctx(&d); return NULL; } memset(d->prg, 0, d->num_desc * sizeof(struct dma_cmd*)); @@ -1288,7 +2055,7 @@ if (d->spb == NULL) { PRINT(KERN_ERR, ohci->id, "failed to allocate split buffer"); - free_dma_rcv_ctx(d); + free_dma_rcv_ctx(&d); return NULL; } @@ -1300,7 +2067,7 @@ } else { PRINT(KERN_ERR, ohci->id, "failed to allocate dma buffer"); - free_dma_rcv_ctx(d); + free_dma_rcv_ctx(&d); return NULL; } @@ -1311,7 +2078,7 @@ } else { PRINT(KERN_ERR, ohci->id, "failed to allocate dma prg"); - free_dma_rcv_ctx(d); + free_dma_rcv_ctx(&d); return NULL; } } @@ -1319,17 +2086,29 @@ spin_lock_init(&d->lock); /* initialize bottom handler */ + d->task.sync = 0; + d->task.next = NULL; d->task.routine = dma_rcv_bh; d->task.data = (void*)d; return d; } -static int free_dma_trm_ctx(struct dma_trm_ctx *d) +static int free_dma_trm_ctx(struct dma_trm_ctx **d) { - if (d==NULL) return -1; - if (d->prg) kfree(d->prg); - kfree(d); + struct ti_ohci *ohci; + + if (*d==NULL) return -1; + + ohci = (struct ti_ohci *)(*d)->ohci; + + DBGMSG(ohci->id, "Freeing dma_trm_ctx %d",(*d)->ctx); + + stop_context(ohci, (*d)->ctrlClear, NULL); + + if ((*d)->prg) kfree((*d)->prg); + kfree(*d); + *d = NULL; return 0; } @@ -1359,7 +2138,7 @@ if (d->prg == NULL) { PRINT(KERN_ERR, ohci->id, "failed to allocate at dma prg"); - free_dma_trm_ctx(d); + free_dma_trm_ctx(&d); return NULL; } memset(d->prg, 0, d->num_desc * sizeof(struct at_dma_prg)); @@ -1370,6 +2149,8 @@ d->task.routine = dma_trm_bh; d->task.data = (void*)d; + init_waitqueue_head(&d->waitq); + return d; } @@ -1385,10 +2166,12 @@ return 1; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) - /* XXX check return value */ - pci_enable_device(dev); -#endif + if (pci_enable_device(dev)) { + PRINT_G(KERN_NOTICE, "failed to enable OHCI hardware %d", + num_of_cards); + return 1; + } + pci_set_master(dev); ohci = &cards[num_of_cards++]; @@ -1397,13 +2180,6 @@ ohci->state = 0; - if (!request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ, - OHCI1394_DRIVER_NAME, ohci)) { - PRINT(KERN_INFO, ohci->id, "allocated interrupt %d", dev->irq); - } else { - FAIL("failed to allocate shared interrupt %d", dev->irq); - } - /* csr_config rom allocation */ ohci->csr_config_rom = kmalloc(1024, GFP_KERNEL); if (ohci->csr_config_rom == NULL) { @@ -1437,7 +2213,9 @@ OHCI1394_AsRspRcvContextControlClear, OHCI1394_AsRspRcvCommandPtr); - if (ohci->ar_resp_context == NULL) return 1; + if (ohci->ar_resp_context == NULL) { + FAIL("failed to allocate AR Resp context"); + } ohci->at_req_context = alloc_dma_trm_ctx(ohci, 0, AT_REQ_NUM_DESC, @@ -1445,7 +2223,9 @@ OHCI1394_AsReqTrContextControlClear, OHCI1394_AsReqTrCommandPtr); - if (ohci->at_req_context == NULL) return 1; + if (ohci->at_req_context == NULL) { + FAIL("failed to allocate AT Req context"); + } ohci->at_resp_context = alloc_dma_trm_ctx(ohci, 1, AT_RESP_NUM_DESC, @@ -1453,7 +2233,9 @@ OHCI1394_AsRspTrContextControlClear, OHCI1394_AsRspTrCommandPtr); - if (ohci->at_resp_context == NULL) return 1; + if (ohci->at_resp_context == NULL) { + FAIL("failed to allocate AT Resp context"); + } ohci->ir_context = alloc_dma_rcv_ctx(ohci, 2, IR_NUM_DESC, @@ -1462,7 +2244,9 @@ OHCI1394_IrRcvContextControlClear, OHCI1394_IrRcvCommandPtr); - if (ohci->ir_context == NULL) return 1; + if (ohci->ir_context == NULL) { + FAIL("failed to allocate IR context"); + } ohci->IR_channel_usage= 0x0000000000000000; spin_lock_init(&ohci->IR_channel_lock); @@ -1482,6 +2266,13 @@ PRINT(KERN_INFO, ohci->id, "remapped memory spaces reg 0x%p", ohci->registers); + if (!request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ, + OHCI1394_DRIVER_NAME, ohci)) { + PRINT(KERN_INFO, ohci->id, "allocated interrupt %d", dev->irq); + } else { + FAIL("failed to allocate shared interrupt %d", dev->irq); + } + return 0; #undef FAIL } @@ -1507,6 +2298,10 @@ int i; struct dma_rcv_ctx *d=NULL; struct dma_trm_ctx *dt=NULL; +#ifdef _VIDEO_1394_H + int j; + struct dma_fbuf_ctx *f=ohci->fbuf_context[0]; +#endif p += sprintf(p,"IEEE-1394 OHCI Driver status report:\n"); p += sprintf(p," bus number: 0x%x Node ID: 0x%x\n", @@ -1535,6 +2330,27 @@ host->is_busmgr ? "bus_mgr" : ""); p += sprintf(p,"\n---Iso Receive DMA---\n"); + +#ifdef _VIDEO_1394_H + +#if 0 + if (f!=NULL) { + for (i=0; inum_desc; i++) { + for (j=0;jnb_cmd;j++) { + p += sprintf(p, + "prg[%d][%d]: %p %08x %08x %08x %08x\n", + i,j,virt_to_bus(&(f->prg[i][j])), + f->prg[i][j].control, + f->prg[i][j].address, + f->prg[i][j].branchAddress, + f->prg[i][j].status); + } + } + } +#endif + +#else + d = ohci->ir_context; #if 0 for (i=0; inum_desc; i++) { @@ -1621,7 +2437,8 @@ dt->branchAddrPtr); p += sprintf(p, "AT resp queue: first: %p last: %p\n", dt->first, dt->last); - +#endif + /* ----- Register Dump ----- */ p += sprintf(p,"\n### HC Register dump ###\n"); SR("Version : %08x GUID_ROM : %08x ATRetries : %08x\n", @@ -1736,19 +2553,34 @@ static void remove_card(struct ti_ohci *ohci) { - if (ohci->registers) - iounmap(ohci->registers); +#ifdef _VIDEO_1394_H + int i; +#endif /* Free AR dma */ - free_dma_rcv_ctx(ohci->ar_req_context); - free_dma_rcv_ctx(ohci->ar_resp_context); + free_dma_rcv_ctx(&ohci->ar_req_context); + free_dma_rcv_ctx(&ohci->ar_resp_context); /* Free AT dma */ - free_dma_trm_ctx(ohci->at_req_context); - free_dma_trm_ctx(ohci->at_resp_context); + free_dma_trm_ctx(&ohci->at_req_context); + free_dma_trm_ctx(&ohci->at_resp_context); /* Free IR dma */ - free_dma_rcv_ctx(ohci->ir_context); + free_dma_rcv_ctx(&ohci->ir_context); + +#ifdef _VIDEO_1394_H + /* Free the frame buffer context */ + if (ohci->fbuf_context) + for (i=0;inb_iso_ctx-1;i++) { + free_dma_fbuf_ctx(&ohci->fbuf_context[i]); + } +#endif + + /* + * Reset the board properly before leaving + * Daniel Kobras + */ + ohci_soft_reset(ohci); /* Free self-id buffer */ if (ohci->self_id_buffer) @@ -1761,6 +2593,9 @@ /* Free the IRQ */ free_irq(ohci->dev->irq, ohci); + if (ohci->registers) + iounmap(ohci->registers); + ohci->state = 0; } @@ -1858,16 +2693,30 @@ proc_unregister(&proc_root, ohci_proc_entry.low_ino); #endif #endif + +#ifdef _VIDEO_1394_H + unregister_chrdev(OHCI1394_MAJOR, "ohci1394"); +#endif + PRINT_G(KERN_INFO, "removed " OHCI1394_DRIVER_NAME " module\n"); } int init_module(void) { - + memset(cards, 0, MAX_OHCI1394_CARDS * sizeof (struct ti_ohci)); + if (hpsb_register_lowlevel(get_ohci_template())) { PRINT_G(KERN_ERR, "registering failed\n"); return -ENXIO; } else { +#ifdef _VIDEO_1394_H + if (register_chrdev(OHCI1394_MAJOR, "ohci1394", &ohci_fops)) + { + printk("ohci1394: unable to get major %d\n", + OHCI1394_MAJOR); + return -EIO; + } +#endif return 0; } } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/ohci1394.h linux.ac/drivers/ieee1394/ohci1394.h --- linux.vanilla/drivers/ieee1394/ohci1394.h Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/ohci1394.h Sun Jun 4 22:51:02 2000 @@ -1,8 +1,29 @@ +/* + * ohci1394.h - driver for OHCI 1394 boards + * Copyright (C)1999,2000 Sebastien Rougeaux + * Gord Peters + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #ifndef _OHCI1394_H #define _OHCI1394_H #include "ieee1394_types.h" +/* include this for the video frame grabber */ +/* #include "video1394.h" */ #define OHCI1394_DRIVER_NAME "ohci1394" @@ -46,11 +67,16 @@ #define PCI_DEVICE_ID_NEC_UPD72871 0x00ce #endif +#ifndef PCI_DEVICE_ID_APPLE_UNI_N_FW +#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018 +#endif + #define MAX_OHCI1394_CARDS 4 #define OHCI1394_MAX_AT_REQ_RETRIES 0x2 #define OHCI1394_MAX_AT_RESP_RETRIES 0x2 #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 +#define OHCI1394_MAX_SELF_ID_ERRORS 16 #define AR_REQ_NUM_DESC 4 /* number of AR req descriptors */ #define AR_REQ_BUF_SIZE 4096 /* size of AR req buffers */ @@ -116,8 +142,34 @@ int ctrlClear; int ctrlSet; int cmdPtr; + wait_queue_head_t waitq; }; +#ifdef _VIDEO_1394_H + +#define OHCI1394_MAJOR 172 +#define ISO_CHANNELS 64 + +struct dma_fbuf_ctx { + void *ohci; + int ctx; + int channel; + int last_buffer; + unsigned int num_desc; + unsigned int buf_size; + unsigned int frame_size; + unsigned int nb_cmd; + unsigned char *buf; + struct dma_cmd **prg; + unsigned int *buffer_status; + int ctrlClear; + int ctrlSet; + int cmdPtr; + int ctxMatch; + wait_queue_head_t waitq; +}; +#endif + struct ti_ohci { int id; /* sequential card number */ @@ -147,6 +199,12 @@ spinlock_t IR_channel_lock; int nb_iso_ctx; +#ifdef _VIDEO_1394_H + /* frame buffer context */ + struct dma_fbuf_ctx **fbuf_context; + struct dma_fbuf_ctx *current_fbuf_ctx; +#endif + /* IEEE-1394 part follows */ struct hpsb_host *host; @@ -154,6 +212,7 @@ spinlock_t phy_reg_lock; + int self_id_errors; int NumBusResets; }; @@ -328,8 +387,8 @@ #define OHCI1394_RSPkt 0x00000020 #define OHCI1394_isochTx 0x00000040 #define OHCI1394_isochRx 0x00000080 -#define OHCI1394_postedWriteErr 0x00001000 -#define OHCI1394_lockRespErr 0x00002000 +#define OHCI1394_postedWriteErr 0x00000100 +#define OHCI1394_lockRespErr 0x00000200 #define OHCI1394_selfIDComplete 0x00010000 #define OHCI1394_busReset 0x00020000 #define OHCI1394_phy 0x00080000 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 Sun Jun 4 22:50:42 2000 @@ -99,6 +99,8 @@ return -1; } + +#if 0 static void free_pcl(struct ti_lynx *lynx, pcl_t pclid) { int off, bit; @@ -145,6 +147,7 @@ get_pcl(lynx, pclid, &pcl); pretty_print_pcl(&pcl); } +#endif static int add_card(struct pci_dev *dev); @@ -486,7 +489,8 @@ put_pcl(lynx, lynx->iso_rcv.pcl_start, &pcl); /* 85 bytes for each FIFO - FIXME - optimize or make configurable */ - reg_write(lynx, FIFO_SIZES, 0x00555555); + /* reg_write(lynx, FIFO_SIZES, 0x00555555); */ + reg_write(lynx, FIFO_SIZES, 0x002020c0); /* 20 byte threshold before triggering PCI transfer */ reg_write(lynx, DMA_GLOBAL_REGISTER, 0x2<<24); /* 69 byte threshold on both send FIFOs before transmitting */ @@ -597,15 +601,16 @@ } else { arg = 1 << 6; } - + + retval = get_phy_reg(lynx, 1); + arg |= (retval == -1 ? 63 : retval); + retval = 0; + PRINT(KERN_INFO, lynx->id, "resetting bus on request%s", (host->attempt_root ? " and attempting to become root" : "")); - spin_lock_irqsave(&lynx->phy_reg_lock, flags); - reg_write(lynx, LINK_PHY, LINK_PHY_WRITE | LINK_PHY_ADDR(1) - | LINK_PHY_WDATA(arg)); - spin_unlock_irqrestore(&lynx->phy_reg_lock, flags); + set_phy_reg(lynx, 1, arg); break; case GET_CYCLE_COUNTER: @@ -717,61 +722,10 @@ static void aux_setup_pcls(struct ti_lynx *lynx) { struct ti_pcl pcl; - unsigned long membufbus = virt_to_bus(lynx->mem_dma_buffer); - int i; - /* This pcl is used to start any aux transfers, the pointer to next - points to itself to avoid a dummy pcl (the PCL engine only executes - the next pcl on startup. The real chain is done by branch */ - pcl.next = pcl_bus(lynx, lynx->mem_pcl.start); - pcl.buffer[0].control = PCL_CMD_BRANCH | PCL_COND_DMARDY_SET; - pcl.buffer[0].pointer = pcl_bus(lynx, lynx->mem_pcl.max); - pcl.buffer[1].control = PCL_CMD_BRANCH | PCL_COND_DMARDY_CLEAR; - pcl.buffer[1].pointer = pcl_bus(lynx, lynx->mem_pcl.cmd); - put_pcl(lynx, lynx->mem_pcl.start, &pcl); - - /* let maxpcl transfer exactly 32kB */ - pcl.next = PCL_NEXT_INVALID; - for (i=0; i<8; i++) { - pcl.buffer[i].control = 4000; - pcl.buffer[i].pointer = membufbus + i * 4000; - } - pcl.buffer[0].control |= PCL_CMD_LBUS_TO_PCI /*| PCL_GEN_INTR*/; - pcl.buffer[8].control = 768 | PCL_LAST_BUFF; - pcl.buffer[8].pointer = membufbus + 8 * 4000; - put_pcl(lynx, lynx->mem_pcl.max, &pcl); - - - /* magic stuff - self and modpcl modifying pcl */ - pcl.next = pcl_bus(lynx, lynx->mem_pcl.mod); - pcl.user_data = 4000; - pcl.buffer[0].control = PCL_CMD_LOAD; - pcl.buffer[0].pointer = pcl_bus(lynx, lynx->mem_pcl.cmd) - + pcloffs(user_data); - pcl.buffer[1].control = PCL_CMD_STOREQ; - pcl.buffer[1].pointer = pcl_bus(lynx, lynx->mem_pcl.mod) - + pcloffs(buffer[1].control); - pcl.buffer[2].control = PCL_CMD_LOAD; - pcl.buffer[2].pointer = membufbus; - pcl.buffer[3].control = PCL_CMD_STOREQ; - pcl.buffer[3].pointer = pcl_bus(lynx, lynx->mem_pcl.cmd) - + pcloffs(buffer[1].pointer); - pcl.buffer[4].control = PCL_CMD_STOREQ; - pcl.buffer[4].pointer = pcl_bus(lynx, lynx->mem_pcl.cmd) - + pcloffs(buffer[6].pointer); - pcl.buffer[5].control = PCL_CMD_LOAD; - pcl.buffer[5].pointer = membufbus + 4; - pcl.buffer[6].control = PCL_CMD_STOREQ | PCL_LAST_CMD; - put_pcl(lynx, lynx->mem_pcl.cmd, &pcl); - - /* modified by cmdpcl when actual transfer occurs */ pcl.next = PCL_NEXT_INVALID; - pcl.buffer[0].control = PCL_CMD_LBUS_TO_PCI; /* null transfer */ - for (i=1; i<13; i++) { - pcl.buffer[i].control = 4000; - pcl.buffer[i].pointer = membufbus + (i-1) * 4000; - } - put_pcl(lynx, lynx->mem_pcl.mod, &pcl); + pcl.user_data = pcl_bus(lynx, lynx->dmem_pcl); + put_pcl(lynx, lynx->dmem_pcl, &pcl); } static int mem_open(struct inode *inode, struct file *file) @@ -828,7 +782,8 @@ md->type = ram; break; case aux: - md->aux_intr_last_seen = atomic_read(&cards[cid].aux_intr_seen); + atomic_set(&md->aux_intr_last_seen, + atomic_read(&cards[cid].aux_intr_seen)); md->type = aux; break; } @@ -862,11 +817,9 @@ poll_wait(file, &cards[cid].aux_intr_wait, pt); intr_seen = atomic_read(&cards[cid].aux_intr_seen); - if (md->aux_intr_last_seen != intr_seen) { + if (atomic_read(&md->aux_intr_last_seen) != intr_seen) { mask |= POLLPRI; - /* md->aux_intr_last_seen = intr_seen; */ - md->aux_intr_last_seen++; /* don't miss interrupts */ - /* FIXME - make ioctl for configuring this */ + atomic_inc(&md->aux_intr_last_seen); } } @@ -882,38 +835,104 @@ short mem_mindma = 2400; MODULE_PARM(mem_mindma, "h"); +static ssize_t mem_dmaread(struct memdata *md, u32 physbuf, ssize_t count, + int offset) +{ + pcltmp_t pcltmp; + struct ti_pcl *pcl; + size_t retval; + int i; + DECLARE_WAITQUEUE(wait, current); + + //printk("buf 0x%08x %x count %d offset %d\n", physbuf, physbuf % 3, count, offset); + + count &= ~3; + count = MIN(count, 53196); + retval = count; + + if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) + & DMA_CHAN_CTRL_BUSY) { + PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!"); + } + + switch (md->type) { + case rom: + reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_ROM | offset); + break; + case ram: + reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_RAM | offset); + break; + case aux: + reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_AUX | offset); + break; + } + + pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); + pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | MIN(count, 4092); + pcl->buffer[0].pointer = physbuf; + count -= 4092; + + i = 0; + while (count > 0) { + i++; + pcl->buffer[i].control = MIN(count, 4092); + pcl->buffer[i].pointer = physbuf + i * 4092; + count -= 4092; + } + pcl->buffer[i].control |= PCL_LAST_BUFF; + commit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); + run_sub_pcl(md->lynx, md->lynx->dmem_pcl, 2, CHANNEL_LOCALBUS); + + schedule(); + while (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) + & DMA_CHAN_CTRL_BUSY) { + if (signal_pending(current)) { + retval = -EINTR; + break; + } + schedule(); + } + + reg_write(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS), 0); + remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); + + if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) + & DMA_CHAN_CTRL_BUSY) { + PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!"); + } + + return retval; +} + static ssize_t mem_read(struct file *file, char *buffer, size_t count, loff_t *offset) { struct memdata *md = (struct memdata *)file->private_data; - size_t bcount; + ssize_t bcount; size_t alignfix; int off = (int)*offset; /* avoid useless 64bit-arithmetic */ + ssize_t retval; void *membase; - DECLARE_WAITQUEUE(wait, current); - - if ((off + count) > PCILYNX_MAX_MEMORY+1) { - count = PCILYNX_MAX_MEMORY+1 - off; + if ((off + count) > PCILYNX_MAX_MEMORY + 1) { + count = PCILYNX_MAX_MEMORY + 1 - off; } if (count <= 0) { return 0; } - down(&md->lynx->mem_dma_mutex); - switch (md->type) { case rom: - reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_ROM | off); membase = md->lynx->local_rom; break; case ram: - reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_RAM | off); membase = md->lynx->local_ram; break; case aux: - reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_AUX | off); membase = md->lynx->aux_port; break; default: @@ -921,89 +940,49 @@ md->lynx->id, md->type); } + down(&md->lynx->mem_dma_mutex); + if (count < mem_mindma) { memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count); - copy_to_user(buffer, md->lynx->mem_dma_buffer, count); - bcount = 0; - goto done; + goto out; } - + bcount = count; alignfix = 4 - (off % 4); if (alignfix != 4) { if (bcount < alignfix) { alignfix = bcount; } - memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, alignfix); - copy_to_user(buffer, md->lynx->mem_dma_buffer, alignfix); + memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, + alignfix); if (bcount == alignfix) { - goto done; + goto out; } bcount -= alignfix; - buffer += alignfix; off += alignfix; } - if (reg_read(md->lynx, DMA0_CHAN_CTRL) & DMA_CHAN_CTRL_BUSY) { - PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!"); - } - - add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); - - if (bcount > 32768) { - current->state = TASK_INTERRUPTIBLE; - - reg_write(md->lynx, DMA0_READY, 1); /* select maxpcl */ - run_pcl(md->lynx, md->lynx->mem_pcl.start, 0); - - while (reg_read(md->lynx, DMA0_CHAN_CTRL) - & DMA_CHAN_CTRL_BUSY) { - if (signal_pending(current)) { - reg_write(md->lynx, DMA0_CHAN_CTRL, 0); - goto rmwait_done; - } - schedule(); - } - - copy_to_user(buffer, md->lynx->mem_dma_buffer, 32768); - buffer += 32768; - bcount -= 32768; - } - - *(u32 *)(md->lynx->mem_dma_buffer) = - pcl_bus(md->lynx, md->lynx->mem_pcl.mod) - + pcloffs(buffer[bcount/4000+1].control); - *(u32 *)(md->lynx->mem_dma_buffer+4) = PCL_LAST_BUFF | (bcount % 4000); - - current->state = TASK_INTERRUPTIBLE; + while (bcount >= 4) { + retval = mem_dmaread(md, virt_to_phys(md->lynx->mem_dma_buffer) + + count - bcount, bcount, off); + if (retval < 0) return retval; - reg_write(md->lynx, DMA0_READY, 0); - run_pcl(md->lynx, md->lynx->mem_pcl.start, 0); - - while (reg_read(md->lynx, DMA0_CHAN_CTRL) & DMA_CHAN_CTRL_BUSY) { - if (signal_pending(current)) { - reg_write(md->lynx, DMA0_CHAN_CTRL, 0); - goto rmwait_done; - } - schedule(); + bcount -= retval; + off += retval; } - copy_to_user(buffer, md->lynx->mem_dma_buffer, bcount); - bcount = 0; - - if (reg_read(md->lynx, DMA0_CHAN_CTRL) & DMA_CHAN_CTRL_BUSY) { - PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!"); + if (bcount) { + memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount, + membase+off, bcount); } - rmwait_done: - reg_write(md->lynx, DMA0_CHAN_CTRL, 0); - remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); - done: + out: + retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count); up(&md->lynx->mem_dma_mutex); - count -= bcount; + if (retval < 0) return retval; *offset += count; - return (count ? count : -EINTR); + return count; } @@ -1200,6 +1179,12 @@ data = lynx->iso_rcv.page[idx / ISORCV_PER_PAGE] + (idx % ISORCV_PER_PAGE) * MAX_ISORCV_SIZE; + if ((*data >> 16) + 4 != (lynx->iso_rcv.stat[idx] & 0x1fff)) { + PRINT(KERN_ERR, lynx->id, + "iso length mismatch 0x%08x/0x%08x", *data, + lynx->iso_rcv.stat[idx]); + } + if (lynx->iso_rcv.stat[idx] & (DMA_CHAN_STAT_PCIERR | DMA_CHAN_STAT_PKTERR)) { PRINT(KERN_INFO, lynx->id, @@ -1224,11 +1209,12 @@ static int add_card(struct pci_dev *dev) { -#define FAIL(fmt, args...) \ +#define FAIL(fmt, args...) do { \ PRINT_G(KERN_ERR, fmt , ## args); \ num_of_cards--; \ remove_card(lynx); \ - return 1 + return 1; \ + } while (0) struct ti_lynx *lynx; /* shortcut to currently handled device */ unsigned long page; @@ -1246,6 +1232,9 @@ lynx->id = num_of_cards-1; lynx->dev = dev; + if (pci_enable_device(dev)) { + FAIL("failed to enable PCILynx hardware %d", lynx->id); + } pci_set_master(dev); if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ, @@ -1271,7 +1260,7 @@ } #endif - lynx->mem_dma_buffer = kmalloc(32768, GFP_KERNEL); + lynx->mem_dma_buffer = kmalloc(65536, GFP_KERNEL); if (lynx->mem_dma_buffer != NULL) { lynx->state = have_aux_buf; } else { @@ -1301,15 +1290,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; @@ -1328,12 +1317,8 @@ /* alloc_pcl return values are not checked, it is expected that the * provided PCL space is sufficient for the initial allocations */ if (lynx->aux_port != NULL) { - lynx->mem_pcl.start = alloc_pcl(lynx); - lynx->mem_pcl.cmd = alloc_pcl(lynx); - lynx->mem_pcl.mod = alloc_pcl(lynx); - lynx->mem_pcl.max = alloc_pcl(lynx); + lynx->dmem_pcl = alloc_pcl(lynx); aux_setup_pcls(lynx); - sema_init(&lynx->mem_dma_mutex, 1); } lynx->rcv_pcl = alloc_pcl(lynx); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/pcilynx.h linux.ac/drivers/ieee1394/pcilynx.h --- linux.vanilla/drivers/ieee1394/pcilynx.h Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/pcilynx.h Sun Jun 4 21:50:42 2000 @@ -19,7 +19,7 @@ #define ISORCV_PER_PAGE (PAGE_SIZE / MAX_ISORCV_SIZE) #define ISORCV_PAGES (NUM_ISORCV_PCL / ISORCV_PER_PAGE) -/* only iso rcv uses these definitions so far */ +/* only iso rcv and localbus use these definitions so far */ #define CHANNEL_LOCALBUS 0 #define CHANNEL_ASYNC_RCV 1 #define CHANNEL_ISO_RCV 2 @@ -70,9 +70,7 @@ #endif /* PCLs for local mem / aux transfers */ - struct { - pcl_t start, cmd, mod, max; - } mem_pcl; + pcl_t dmem_pcl; /* IEEE-1394 part follows */ struct hpsb_host *host; @@ -105,7 +103,7 @@ struct memdata { struct ti_lynx *lynx; int cid; - int aux_intr_last_seen; + atomic_t aux_intr_last_seen; enum { rom, aux, ram } type; }; @@ -415,6 +413,38 @@ #endif /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */ +#if defined (CONFIG_IEEE1394_PCILYNX_LOCALRAM) || defined (__BIG_ENDIAN) +typedef struct ti_pcl pcltmp_t; + +inline static struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid, + pcltmp_t *tmp) +{ + get_pcl(lynx, pclid, tmp); + return tmp; +} + +inline static void commit_pcl(const struct ti_lynx *lynx, pcl_t pclid, + pcltmp_t *tmp) +{ + put_pcl(lynx, pclid, tmp); +} + +#else +typedef int pcltmp_t; /* just a dummy */ + +inline static struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid, + pcltmp_t *tmp) +{ + return lynx->pcl_mem + pclid * sizeof(struct ti_pcl); +} + +inline static void commit_pcl(const struct ti_lynx *lynx, pcl_t pclid, + pcltmp_t *tmp) +{ +} +#endif + + inline static void run_sub_pcl(const struct ti_lynx *lynx, pcl_t pclid, int idx, int dmachan) { @@ -464,73 +494,73 @@ #define _(x) (__constant_cpu_to_be32(x)) -quadlet_t lynx_csr_rom[] = { - /* bus info block */ - _(0x04040000), /* info/CRC length, CRC */ - _(0x31333934), /* 1394 magic number */ - _(0xf064a000), /* misc. settings */ - _(0x08002850), /* vendor ID, chip ID high */ - _(0x0000ffff), /* chip ID low */ - /* root directory */ - _(0x00090000), /* CRC length, CRC */ - _(0x03080028), /* vendor ID (Texas Instr.) */ - _(0x81000009), /* offset to textual ID */ - _(0x0c000200), /* node capabilities */ - _(0x8d00000e), /* offset to unique ID */ - _(0xc7000010), /* offset to module independent info */ - _(0x04000000), /* module hardware version */ - _(0x81000026), /* offset to textual ID */ - _(0x09000000), /* node hardware version */ - _(0x81000026), /* offset to textual ID */ - /* module vendor ID textual */ - _(0x00080000), /* CRC length, CRC */ - _(0x00000000), - _(0x00000000), - _(0x54455841), /* "Texas Instruments" */ - _(0x5320494e), - _(0x53545255), - _(0x4d454e54), - _(0x53000000), - /* node unique ID leaf */ - _(0x00020000), /* CRC length, CRC */ - _(0x08002850), /* vendor ID, chip ID high */ - _(0x0000ffff), /* chip ID low */ - /* module dependent info */ - _(0x00060000), /* CRC length, CRC */ - _(0xb8000006), /* offset to module textual ID */ - _(0x81000004), /* ??? textual descriptor */ - _(0x39010000), /* SRAM size */ - _(0x3a010000), /* AUXRAM size */ - _(0x3b000000), /* AUX device */ - /* module textual ID */ - _(0x00050000), /* CRC length, CRC */ - _(0x00000000), - _(0x00000000), - _(0x54534231), /* "TSB12LV21" */ - _(0x324c5632), - _(0x31000000), - /* part number */ - _(0x00060000), /* CRC length, CRC */ - _(0x00000000), - _(0x00000000), - _(0x39383036), /* "9806000-0001" */ - _(0x3030342d), - _(0x30303431), - _(0x20000001), - /* module hardware version textual */ - _(0x00050000), /* CRC length, CRC */ - _(0x00000000), - _(0x00000000), - _(0x5453424b), /* "TSBKPCITST" */ - _(0x50434954), - _(0x53540000), - /* node hardware version textual */ - _(0x00050000), /* CRC length, CRC */ - _(0x00000000), - _(0x00000000), - _(0x54534232), /* "TSB21LV03" */ - _(0x313c5630), - _(0x33000000) +static quadlet_t lynx_csr_rom[] = { +/* bus info block offset (hex) */ + _(0x04040000), /* info/CRC length, CRC 400 */ + _(0x31333934), /* 1394 magic number 404 */ + _(0xf064a000), /* misc. settings 408 */ + _(0x08002850), /* vendor ID, chip ID high 40c */ + _(0x0000ffff), /* chip ID low 410 */ +/* root directory */ + _(0x00090000), /* directory length, CRC 414 */ + _(0x03080028), /* vendor ID (Texas Instr.) 418 */ + _(0x81000008), /* offset to textual ID 41c */ + _(0x0c000200), /* node capabilities 420 */ + _(0x8d00000e), /* offset to unique ID 424 */ + _(0xc7000010), /* offset to module independent info 428 */ + _(0x04000000), /* module hardware version 42c */ + _(0x81000014), /* offset to textual ID 430 */ + _(0x09000000), /* node hardware version 434 */ + _(0x81000018), /* offset to textual ID 438 */ + /* module vendor ID textual */ + _(0x00070000), /* CRC length, CRC 43c */ + _(0x00000000), /* 440 */ + _(0x00000000), /* 444 */ + _(0x54455841), /* "Texas Instruments" 448 */ + _(0x5320494e), /* 44c */ + _(0x53545255), /* 450 */ + _(0x4d454e54), /* 454 */ + _(0x53000000), /* 458 */ +/* node unique ID leaf */ + _(0x00020000), /* CRC length, CRC 45c */ + _(0x08002850), /* vendor ID, chip ID high 460 */ + _(0x0000ffff), /* chip ID low 464 */ +/* module dependent info */ + _(0x00050000), /* CRC length, CRC 468 */ + _(0x81000012), /* offset to module textual ID 46c */ + _(0x81000017), /* textual descriptor 470 */ + _(0x39010000), /* SRAM size 474 */ + _(0x3a010000), /* AUXRAM size 478 */ + _(0x3b000000), /* AUX device 47c */ +/* module textual ID */ + _(0x00050000), /* CRC length, CRC 480 */ + _(0x00000000), /* 484 */ + _(0x00000000), /* 488 */ + _(0x54534231), /* "TSB12LV21" 48c */ + _(0x324c5632), /* 490 */ + _(0x31000000), /* 494 */ +/* part number */ + _(0x00060000), /* CRC length, CRC 498 */ + _(0x00000000), /* 49c */ + _(0x00000000), /* 4a0 */ + _(0x39383036), /* "9806000-0001" 4a4 */ + _(0x3030302d), /* 4a8 */ + _(0x30303031), /* 4ac */ + _(0x20000001), /* 4b0 */ +/* module hardware version textual */ + _(0x00050000), /* CRC length, CRC 4b4 */ + _(0x00000000), /* 4b8 */ + _(0x00000000), /* 4bc */ + _(0x5453424b), /* "TSBKPCITST" 4c0 */ + _(0x50434954), /* 4c4 */ + _(0x53540000), /* 4c8 */ +/* node hardware version textual */ + _(0x00050000), /* CRC length, CRC 4d0 */ + _(0x00000000), /* 4d4 */ + _(0x00000000), /* 4d8 */ + _(0x54534232), /* "TSB21LV03" 4dc */ + _(0x314c5630), /* 4e0 */ + _(0x33000000) /* 4e4 */ }; #undef _ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/raw1394.c linux.ac/drivers/ieee1394/raw1394.c --- linux.vanilla/drivers/ieee1394/raw1394.c Thu May 25 17:38:23 2000 +++ linux.ac/drivers/ieee1394/raw1394.c Sun Jun 4 21:50:42 2000 @@ -575,8 +575,8 @@ break; case RAW1394_REQ_LOCK: - if ((req->req.misc != EXTCODE_FETCH_ADD) - && (req->req.misc != EXTCODE_LITTLE_ADD)) { + if ((req->req.misc == EXTCODE_FETCH_ADD) + || (req->req.misc == EXTCODE_LITTLE_ADD)) { if (req->req.length != 4) { req->req.error = RAW1394_ERROR_INVALID_ARG; break; @@ -667,8 +667,8 @@ break; case RAW1394_REQ_LOCK: - if ((req->req.misc != EXTCODE_FETCH_ADD) - && (req->req.misc != EXTCODE_LITTLE_ADD)) { + if ((req->req.misc == EXTCODE_FETCH_ADD) + || (req->req.misc == EXTCODE_LITTLE_ADD)) { if (req->req.length != 4) { req->req.error = RAW1394_ERROR_INVALID_ARG; break; @@ -690,6 +690,7 @@ break; } + req->data = packet->data; req->req.length = 4; break; @@ -716,6 +717,7 @@ if (!hpsb_send_packet(packet)) { req->req.error = RAW1394_ERROR_SEND_ERROR; req->req.length = 0; + free_tlabel(packet->host, packet->node_id, packet->tlabel); queue_complete_req(req); } return sizeof(struct raw1394_request); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/ieee1394/video1394.h linux.ac/drivers/ieee1394/video1394.h --- linux.vanilla/drivers/ieee1394/video1394.h Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/ieee1394/video1394.h Sun Jun 4 21:50:42 2000 @@ -0,0 +1,50 @@ +/* + * video1394.h - driver for OHCI 1394 boards + * Copyright (C)1999,2000 Sebastien Rougeaux + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _VIDEO_1394_H +#define _VIDEO_1394_H + +#define VIDEO1394_MAX_SIZE 0x400000 + +enum { + VIDEO1394_BUFFER_FREE = 0, + VIDEO1394_BUFFER_QUEUED, + VIDEO1394_BUFFER_READY +}; + +enum { + VIDEO1394_LISTEN_CHANNEL = 0, + VIDEO1394_UNLISTEN_CHANNEL, + VIDEO1394_QUEUE_BUFFER, + VIDEO1394_WAIT_BUFFER +}; + +struct video1394_mmap { + int channel; + int sync_tag; + int nb_buffers; + int buf_size; +}; + +struct video1394_wait { + int channel; + int buffer; +}; + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/isdn/avmb1/c4.c linux.ac/drivers/isdn/avmb1/c4.c --- linux.vanilla/drivers/isdn/avmb1/c4.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/isdn/avmb1/c4.c Sun Jun 4 21:58:22 2000 @@ -1333,9 +1333,12 @@ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, dev))) { struct capicardparams param; - param.port = dev->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK; + if (pci_enable_device(dev)) + continue; + + param.port = pci_resource_start (dev, 1); param.irq = dev->irq; - param.membase = dev->resource[ 0].start & PCI_BASE_ADDRESS_MEM_MASK; + param.membase = pci_resource_start (dev, 0); printk(KERN_INFO "%s: PCI BIOS reports AVM-C4 at i/o %#x, irq %d, mem %#x\n", 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/avmb1/t1pci.c linux.ac/drivers/isdn/avmb1/t1pci.c --- linux.vanilla/drivers/isdn/avmb1/t1pci.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/isdn/avmb1/t1pci.c Sun Jun 4 21:59:02 2000 @@ -305,11 +305,12 @@ while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, dev))) { struct capicardparams param; + if (pci_enable_device(dev)) + continue; + param.port = pci_resource_start (dev, 1); param.irq = dev->irq; param.membase = pci_resource_start (dev, 0); - - pci_enable_device (dev); /* XXX check return */ printk(KERN_INFO "%s: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n", diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/isdn/hisax/telespci.c linux.ac/drivers/isdn/hisax/telespci.c --- linux.vanilla/drivers/isdn/hisax/telespci.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/isdn/hisax/telespci.c Sun Jun 4 21:59:41 2000 @@ -325,6 +325,8 @@ return(0); } if ((dev_tel = pci_find_device (0x11DE, 0x6120, dev_tel))) { + if (pci_enable_device(dev_tel)) + return (0); cs->irq = dev_tel->irq; if (!cs->irq) { printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/isdn/hisax/w6692.c linux.ac/drivers/isdn/hisax/w6692.c --- linux.vanilla/drivers/isdn/hisax/w6692.c Thu May 25 17:38:09 2000 +++ linux.ac/drivers/isdn/hisax/w6692.c Sun Jun 4 22:00:27 2000 @@ -1009,8 +1009,11 @@ dev_w6692 = pci_find_device(id_list[id_idx].vendor_id, id_list[id_idx].device_id, dev_w6692); - if (dev_w6692) + if (dev_w6692) { + if (pci_enable_device(dev_w6692)) + continue; break; + } id_idx++; } if (dev_w6692) { @@ -1018,7 +1021,7 @@ pci_irq = dev_w6692->irq; /* I think address 0 is allways the configuration area */ /* and address 1 is the real IO space KKe 03.09.99 */ - pci_ioaddr = dev_w6692->resource[ 1].start; + pci_ioaddr = pci_resource_start(dev_w6692, 1); } if (!found) { printk(KERN_WARNING "W6692: No PCI card found\n"); @@ -1029,7 +1032,6 @@ printk(KERN_WARNING "W6692: No IRQ for PCI card found\n"); return (0); } - pci_ioaddr &= PCI_BASE_ADDRESS_IO_MASK; if (!pci_ioaddr) { printk(KERN_WARNING "W6692: NO I/O Base Address found\n"); return (0); 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/3c507.c linux.ac/drivers/net/3c507.c --- linux.vanilla/drivers/net/3c507.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/3c507.c Sun Jun 4 21:52:47 2000 @@ -315,7 +315,7 @@ if (base_addr > 0x1ff) /* Check a single specified location. */ return el16_probe1(dev, base_addr); else if (base_addr != 0) - return ENXIO; /* Don't probe at all. */ + return -ENXIO; /* Don't probe at all. */ for (i = 0; netcard_portlist[i]; i++) { int ioaddr = netcard_portlist[i]; @@ -325,7 +325,7 @@ return 0; } - return ENODEV; + return -ENODEV; } static int __init el16_probe1(struct net_device *dev, int ioaddr) @@ -351,7 +351,7 @@ && inb(ioaddr+2) == 'C' && inb(ioaddr+3) == 'O') ; else - return ENODEV; + return -ENODEV; /* Allocate a new 'dev' if needed. */ if (dev == NULL) @@ -370,7 +370,7 @@ irqval = request_irq(irq, &el16_interrupt, 0, "3c507", dev); if (irqval) { printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval); - return EAGAIN; + return -EAGAIN; } /* We've committed to using the board, and can start filling in *dev. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/3c523.c linux.ac/drivers/net/3c523.c --- linux.vanilla/drivers/net/3c523.c Thu May 25 17:37:52 2000 +++ linux.ac/drivers/net/3c523.c Sun Jun 4 21:53:30 2000 @@ -417,7 +417,7 @@ unsigned int size = 0; if (MCA_bus == 0) { - return ENODEV; + return -ENODEV; } /* search through the slots for the 3c523. */ slot = mca_find_adapter(ELMC_MCA_ID, 0); @@ -519,7 +519,7 @@ printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name, dev->mem_start); release_region(dev->base_addr, ELMC_IO_EXTENT); - return ENODEV; + return -ENODEV; } dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/8139too.c linux.ac/drivers/net/8139too.c --- linux.vanilla/drivers/net/8139too.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/8139too.c Wed May 31 11:25:23 2000 @@ -97,7 +97,7 @@ #include -#define RTL8139_VERSION "0.9.5" +#define RTL8139_VERSION "0.9.6" #define RTL8139_MODULE_NAME "8139too" #define RTL8139_DRIVER_NAME RTL8139_MODULE_NAME " Fast Ethernet driver " RTL8139_VERSION #define PFX RTL8139_MODULE_NAME ": " @@ -232,6 +232,7 @@ IntrMask = 0x3C, IntrStatus = 0x3E, TxConfig = 0x40, + ChipVersion = 0x43, RxConfig = 0x44, Timer = 0x48, /* A general-purpose counter. */ RxMissed = 0x4C, /* 24 bits valid, write clears. */ @@ -392,8 +393,8 @@ typedef enum { CH_8139 = 0, + CH_8139_K, CH_8139A, - CH_8139A_G, CH_8139B, CH_8130, CH_8139C, @@ -403,36 +404,36 @@ /* directly indexed by chip_t, above */ const static struct { const char *name; - u32 version; /* from RTL8139C docs */ + u8 version; /* from RTL8139C docs */ u32 RxConfigMask; /* should clear the bits supported by this chip */ } rtl_chip_info[] = { { "RTL-8139", - 0x60000000, + 0x40, 0xf0fe0040, /* XXX copied from RTL8139A, verify */ }, - { "RTL-8139A", - 0x70000000, - 0xf0fe0040, + { "RTL-8139 rev K", + 0x60, + 0xf0fe0040, /* XXX copied from RTL8139A, verify */ }, - { "RTL-8139A rev. G", - 0x70800000, + { "RTL-8139A", + 0x70, 0xf0fe0040, }, { "RTL-8139B", - 0x78000000, + 0x78, 0xf0fc0040 }, { "RTL-8130", - 0x7C000000, + 0x7C, 0xf0fe0040, /* XXX copied from RTL8139A, verify */ }, { "RTL-8139C", - 0x74000000, + 0x74, 0xf0fc0040, /* XXX copied from RTL8139B, verify */ }, @@ -672,7 +673,7 @@ } /* identify chip attached to board */ - tmp = RTL_R32 (TxConfig) & TxVersionMask; + tmp = RTL_R8 (ChipVersion); for (i = arraysize (rtl_chip_info) - 1; i >= 0; i--) if (tmp == rtl_chip_info[i].version) { tp->chipset = i; @@ -686,10 +687,8 @@ tp->chipset = 0; match: - DPRINTK ("chipset id (%d/%d/%d) == %d, '%s'\n", - CH_8139, - CH_8139A, - CH_8139B, + DPRINTK ("chipset id (%d) == index %d, '%s'\n", + tmp, tp->chipset, rtl_chip_info[tp->chipset].name); @@ -1703,8 +1702,8 @@ } else { eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], - rx_size, 0); - skb_put (skb, rx_size); + rx_size - 4, 0); + skb_put (skb, rx_size - 4); } skb->protocol = eth_type_trans (skb, dev); netif_rx (skb); 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/am79c961a.c linux.ac/drivers/net/am79c961a.c --- linux.vanilla/drivers/net/am79c961a.c Thu May 25 17:37:55 2000 +++ linux.ac/drivers/net/am79c961a.c Sun Jun 4 21:17:02 2000 @@ -466,8 +466,15 @@ dev->trans_start = jiffies; restore_flags (flags); - if (!(am_readword (dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN)) + /* + * If the next packet is owned by the ethernet device, + * then the tx ring is full and we can't add another + * packet. + */ + if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN) { + printk(KERN_DEBUG"tx ring full, stopping queue\n"); netif_stop_queue(dev); + } dev_kfree_skb(skb); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/apne.c linux.ac/drivers/net/apne.c --- linux.vanilla/drivers/net/apne.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/apne.c Sun Jun 4 21:55:37 2000 @@ -271,7 +271,7 @@ stop_page = (wordlength == 2) ? 0x40 : 0x20; } else { printk(" not found.\n"); - return ENXIO; + return -ENXIO; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/arlan.c linux.ac/drivers/net/arlan.c --- linux.vanilla/drivers/net/arlan.c Thu May 25 17:37:54 2000 +++ linux.ac/drivers/net/arlan.c Sun Jun 4 21:56:12 2000 @@ -1091,14 +1091,14 @@ { if (lastFoundAt == 0xbe000) printk(KERN_ERR "arlan: No Arlan devices found \n"); - return ENODEV; + return -ENODEV; } else return 0; ARLAN_DEBUG_EXIT("arlan_probe_everywhere"); - return ENODEV; + return -ENODEV; } int __init arlan_find_devices(void) @@ -1975,7 +1975,7 @@ printk("Arlan driver %s\n", arlan_version); if (arlan_probe_everywhere(dev)) - return ENODEV; + return -ENODEV; arlans_found++; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/daynaport.c linux.ac/drivers/net/daynaport.c --- linux.vanilla/drivers/net/daynaport.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/daynaport.c Sun Jun 4 21:57:44 2000 @@ -633,6 +633,7 @@ static int ns8390_open(struct net_device *dev) { + MOD_INC_USE_COUNT; ei_open(dev); /* At least on my card (a Focus Enhancements PDS card) I start */ @@ -644,10 +645,9 @@ if (request_irq(dev->irq, ei_interrupt, 0, "8390 Ethernet", dev)) { printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq); - return EAGAIN; + MOD_DEC_USE_COUNT; + return -EAGAIN; } - - MOD_INC_USE_COUNT; return 0; } 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 Wed May 31 11:18:46 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. */ @@ -218,9 +207,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 +331,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 +371,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 +410,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 +654,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 +674,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 +710,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 +727,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 +741,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 +763,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 +842,7 @@ pdev->driver_data = dev; dev->base_addr = ioaddr; - dev->irq = irq; + dev->irq = pdev->irq; sp = dev->priv; sp->pdev = pdev; @@ -887,30 +890,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 +1109,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 +1145,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 +1180,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 +1260,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 +1309,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 +1320,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 +1343,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 +1403,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 +1931,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 +1953,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: @@ -2205,6 +2241,10 @@ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557, 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,} }; 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/hp100.c linux.ac/drivers/net/hp100.c --- linux.vanilla/drivers/net/hp100.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/hp100.c Sun Jun 4 22:14:21 2000 @@ -8,7 +8,7 @@ ** Extended for new busmaster capable chipsets by ** Siegfried "Frieder" Loeffler (dg1sek) ** -** Maintained by: Jaroslav Kysela +** Maintained by: Jaroslav Kysela ** ** This driver has only been tested with ** -- HP J2585B 10/100 Mbit/s PCI Busmaster @@ -109,16 +109,9 @@ #include #include -#if LINUX_VERSION_CODE >= 0x020100 #define LINUX_2_1 typedef struct net_device_stats hp100_stats_t; EXPORT_NO_SYMBOLS; -#else -#include -#define ioremap vremap -#define iounmap vfree -typedef struct enet_statistics hp100_stats_t; -#endif #include "hp100.h" @@ -187,12 +180,7 @@ u_short priority_tx; /* != 0 - priority tx */ u_short mode; /* PIO, Shared Mem or Busmaster */ u_char bus; -#ifndef LINUX_2_1 - u_char pci_bus; - u_char pci_device_fn; -#else struct pci_dev *pci_dev; -#endif short mem_mapped; /* memory mapped access */ void *mem_ptr_virt; /* virtual memory mapped area, maybe NULL */ unsigned long mem_ptr_phys; /* physical memory mapped area */ @@ -287,21 +275,15 @@ static int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX; static int hp100_mode = 1; -#ifdef LINUX_2_1 MODULE_PARM( hp100_rx_ratio, "1i" ); MODULE_PARM( hp100_priority_tx, "1i" ); MODULE_PARM( hp100_mode, "1i" ); -#endif /* * prototypes */ -#ifdef LINUX_2_1 static int hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ); -#else -static int hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ); -#endif static int hp100_open( struct net_device *dev ); static int hp100_close( struct net_device *dev ); static int hp100_start_xmit( struct sk_buff *skb, struct net_device *dev ); @@ -361,25 +343,12 @@ { if ( check_region( base_addr, HP100_REGION_SIZE ) ) return -EINVAL; if ( base_addr < 0x400 ) -#ifdef LINUX_2_1 return hp100_probe1( dev, base_addr, HP100_BUS_ISA, NULL ); -#else - return hp100_probe1( dev, base_addr, HP100_BUS_ISA, 0, 0 ); -#endif if ( EISA_bus && base_addr >= 0x1c38 && ( (base_addr - 0x1c38) & 0x3ff ) == 0 ) -#ifdef LINUX_2_1 return hp100_probe1( dev, base_addr, HP100_BUS_EISA, NULL ); -#else - return hp100_probe1( dev, base_addr, HP100_BUS_EISA, 0, 0 ); -#endif #ifdef CONFIG_PCI -#ifdef LINUX_2_1 printk( "hp100: %s: You must specify card # in i/o address parameter for PCI bus...", dev->name ); #else - printk( "hp100: %s: You may specify card # in i/o address parameter for PCI bus...", dev->name ); - return hp100_probe1( dev, base_addr, HP100_BUS_PCI, 0, 0 ); -#endif -#else return -ENODEV; #endif } @@ -397,16 +366,13 @@ if ( pcibios_present() ) { int pci_index; -#ifdef LINUX_2_1 struct pci_dev *pci_dev = NULL; int pci_id_index; u_short pci_command; -#endif #ifdef HP100_DEBUG_PCI printk( "hp100: %s: PCI BIOS is present, checking for devices..\n", dev->name ); #endif -#ifdef LINUX_2_1 pci_index = 0; for ( pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE; pci_id_index++ ) { while ( (pci_dev = pci_find_device( hp100_pci_ids[ pci_id_index ].vendor, @@ -416,8 +382,10 @@ pci_index++; continue; } + if (pci_enable_device(pci_dev)) + continue; /* found... */ - ioaddr = pci_dev ->resource[ 0 ].start; + ioaddr = pci_resource_start (pci_dev, 0); if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue; pci_read_config_word( pci_dev, PCI_COMMAND, &pci_command ); if ( !( pci_command & PCI_COMMAND_IO ) ) { @@ -441,55 +409,6 @@ return 0; } } -#else /* old PCI interface */ - for ( pci_index = pci_start_index & 7; pci_index < 8; pci_index++ ) - { - u_char pci_bus, pci_device_fn; - u_short pci_command; - int pci_id_index; - - for ( pci_id_index = 0; pci_id_index < HP100_PCI_IDS_SIZE; pci_id_index++ ) - if ( pcibios_find_device( hp100_pci_ids[ pci_id_index ].vendor, - hp100_pci_ids[ pci_id_index ].device, - pci_index, &pci_bus, - &pci_device_fn ) == 0 ) goto __pci_found; - break; - - __pci_found: - pcibios_read_config_dword( pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &ioaddr ); - - ioaddr &= ~3; /* remove I/O space marker in bit 0. */ - - if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue; - - pcibios_read_config_word( pci_bus, pci_device_fn, - PCI_COMMAND, &pci_command ); - if ( !( pci_command & PCI_COMMAND_IO ) ) - { -#ifdef HP100_DEBUG - printk( "hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name ); -#endif - pci_command |= PCI_COMMAND_IO; - pcibios_write_config_word( pci_bus, pci_device_fn, - PCI_COMMAND, pci_command ); - } - if ( !( pci_command & PCI_COMMAND_MASTER ) ) - { -#ifdef HP100_DEBUG - printk( "hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name ); -#endif - pci_command |= PCI_COMMAND_MASTER; - pcibios_write_config_word( pci_bus, pci_device_fn, - PCI_COMMAND, pci_command ); - } -#ifdef HP100_DEBUG - printk( "hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr ); -#endif - if ( hp100_probe1( dev, ioaddr, HP100_BUS_PCI, pci_bus, pci_device_fn ) == 0 ) - return 0; - } -#endif } if ( pci_start_index > 0 ) return -ENODEV; #endif /* CONFIG_PCI */ @@ -498,33 +417,21 @@ for ( ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400 ) { if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue; -#ifdef LINUX_2_1 if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA, NULL ) == 0 ) return 0; -#else - if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA, 0, 0 ) == 0 ) return 0; -#endif } /* Third Probe all ISA possible port regions */ for ( ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20 ) { if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue; -#ifdef LINUX_2_1 if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA, NULL ) == 0 ) return 0; -#else - if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA, 0, 0 ) == 0 ) return 0; -#endif } return -ENODEV; } -#ifdef LINUX_2_1 static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ) -#else -static int __init hp100_probe1( struct net_device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ) -#endif { int i; @@ -549,7 +456,7 @@ #ifdef HP100_DEBUG printk( "hp100_probe1: %s: dev == NULL ?\n", dev->name ); #endif - return EIO; + return -EIO; } if ( hp100_inw( HW_ID ) != HP100_HW_ID_CASCADE ) @@ -799,12 +706,7 @@ lp->chip = chip; lp->mode = local_mode; lp->bus = bus; -#ifdef LINUX_2_1 lp->pci_dev = pci_dev; -#else - lp->pci_bus = pci_bus; - lp->pci_device_fn = pci_device_fn; -#endif lp->priority_tx = hp100_priority_tx; lp->rx_ratio = hp100_rx_ratio; lp->mem_ptr_phys = mem_ptr_phys; @@ -836,18 +738,14 @@ dev->set_multicast_list = &hp100_set_multicast_list; /* Ask the card for which IRQ line it is configured */ -#ifdef LINUX_2_1 if ( bus == HP100_BUS_PCI ) { dev->irq = pci_dev->irq; } else { -#endif hp100_page( HW_MAP ); dev->irq = hp100_inb( IRQ_CHANNEL ) & HP100_IRQMASK; if ( dev->irq == 2 ) dev->irq = 9; -#ifdef LINUX_2_1 } -#endif if(lp->mode==1) /* busmaster */ dev->dma=4; @@ -1648,9 +1546,6 @@ if ( skb==NULL ) { -#ifndef LINUX_2_1 - dev_tint( dev ); -#endif return 0; } @@ -1754,9 +1649,7 @@ /* Update statistics */ lp->stats.tx_packets++; -#ifdef LINUX_2_1 lp->stats.tx_bytes += skb->len; -#endif dev->trans_start = jiffies; return 0; @@ -1799,11 +1692,7 @@ hp100_inb(TX_PDL), donecount); #endif -#ifdef LINUX_2_1 dev_kfree_skb_any( lp->txrhead->skb ); -#else - dev_kfree_skb_any( lp->txrhead->skb, FREE_WRITE ); -#endif lp->txrhead->skb=(void *)NULL; lp->txrhead=lp->txrhead->next; lp->txrcommit--; @@ -1826,9 +1715,6 @@ if ( skb==NULL ) { -#ifndef LINUX_2_1 - dev_tint( dev ); -#endif return 0; } @@ -1953,17 +1839,11 @@ hp100_outb( HP100_TX_CMD | HP100_SET_LB, OPTION_MSW ); /* send packet */ lp->stats.tx_packets++; -#ifdef LINUX_2_1 lp->stats.tx_bytes += skb->len; -#endif dev->trans_start=jiffies; hp100_ints_on(); -#ifdef LINUX_2_1 dev_kfree_skb_any( skb ); -#else - dev_kfree_skb_any( skb, FREE_WRITE ); -#endif #ifdef HP100_DEBUG_TX printk( "hp100: %s: start_xmit: end\n", dev->name ); @@ -2071,9 +1951,7 @@ netif_rx( skb ); lp->stats.rx_packets++; -#ifdef LINUX_2_1 lp->stats.rx_bytes += skb->len; -#endif #ifdef HP100_DEBUG_RX printk( "hp100: %s: rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", @@ -2180,9 +2058,7 @@ netif_rx( ptr->skb ); /* Up and away... */ lp->stats.rx_packets++; -#ifdef LINUX_2_1 lp->stats.rx_bytes += ptr->skb->len; -#endif } switch ( header & 0x00070000 ) { @@ -2197,11 +2073,7 @@ printk("hp100: %s: rx_bm: Received bad packet (length=%d)\n",dev->name,pkt_len); #endif if(ptr->skb!=NULL) -#ifdef LINUX_2_1 dev_kfree_skb_any( ptr->skb ); -#else - dev_kfree_skb_any( ptr->skb, FREE_READ ); -#endif lp->stats.rx_errors++; } @@ -3119,16 +2991,12 @@ /* Parameters set by insmod */ int hp100_port[5] = { 0, -1, -1, -1, -1 }; -#ifdef LINUX_2_1 MODULE_PARM(hp100_port, "1-5i"); -#endif /* Allocate 5 string of length IFNAMSIZ, one string for each device */ char hp100_name[5][IFNAMSIZ] = { "", "", "", "", "" }; -#ifdef LINUX_2_1 /* Allow insmod to write those 5 strings individually */ MODULE_PARM(hp100_name, "1-5c" __MODULE_STRING(IFNAMSIZ)); -#endif /* List of devices */ static struct net_device *hp100_devlist[5] = { NULL, NULL, NULL, NULL, NULL }; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/ioc3-eth.c linux.ac/drivers/net/ioc3-eth.c --- linux.vanilla/drivers/net/ioc3-eth.c Thu May 25 17:37:58 2000 +++ linux.ac/drivers/net/ioc3-eth.c Mon May 29 19:29:10 2000 @@ -38,7 +38,6 @@ * - Free rings and buffers when closing or before re-initializing rings. * - Handle allocation failures in ioc3_alloc_skb() more gracefully. * - Handle allocation failures in ioc3_init_rings(). - * - Maybe implement private_ioctl(). * - Use prefetching for large packets. What is a good lower limit for * prefetching? * - We're probably allocating a bit too much memory. @@ -75,6 +74,17 @@ /* 32 RX buffers. This is tunable in the range of 16 <= x < 512. */ #define RX_BUFFS 32 +/* Private ioctls that de facto are well known and used for examply + by mii-tool. */ +#define SIOCGMIIPHY (SIOCDEVPRIVATE) /* Read from current PHY */ +#define SIOCGMIIREG (SIOCDEVPRIVATE+1) /* Read any PHY register */ +#define SIOCSMIIREG (SIOCDEVPRIVATE+2) /* Write any PHY register */ + +/* These exist in other drivers; we don't use them at this time. */ +#define SIOCGPARAMS (SIOCDEVPRIVATE+3) /* Read operational parameters */ +#define SIOCSPARAMS (SIOCDEVPRIVATE+4) /* Set operational parameters */ + +static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void ioc3_set_multicast_list(struct net_device *dev); static int ioc3_open(struct net_device *dev); static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev); @@ -97,6 +107,7 @@ int rx_pi; /* RX producer index */ int tx_ci; /* TX consumer index */ int tx_pi; /* TX producer index */ + int txqlen; spinlock_t ioc3_lock; }; @@ -124,17 +135,6 @@ #define BARRIER() \ __asm__("sync" ::: "memory") -/* This El Cheapo implementatin of TX_BUFFS_AVAIL may leave on entry unused. - Since the TX ring has 128 entries which is fairly large we don't care and - use this, more efficient implementation. */ -#define TX_BUFFS_AVAIL(ip) \ -({ \ - struct ioc3_private *_ip = (ip); \ - ((512 + _ip->tx_ci + 1) - _ip->tx_pi) & 511; \ -}) -//#undef TX_BUFFS_AVAIL -//#define TX_BUFFS_AVAIL(ip) (1) - #define IOC3_SIZE 0x100000 @@ -276,6 +276,8 @@ printk(".\n"); } +/* Caller must hold the ioc3_lock ever for MII readers. This is also + used to protect the transmitter side but it's low contention. */ static u16 mii_read(struct ioc3 *ioc3, int phy, int reg) { while (ioc3->micr & MICR_BUSY); @@ -385,8 +387,9 @@ } static inline void -ioc3_tx(struct ioc3_private *ip, struct ioc3 *ioc3) +ioc3_tx(struct net_device *dev, struct ioc3_private *ip, struct ioc3 *ioc3) { + unsigned long packets, bytes; int tx_entry, o_entry; struct sk_buff *skb; u32 etcir; @@ -395,14 +398,16 @@ etcir = ioc3->etcir; tx_entry = (etcir >> 7) & 127; o_entry = ip->tx_ci; + packets = 0; + bytes = 0; while (o_entry != tx_entry) { ioc3->eisr = EISR_TXEXPLICIT; /* Ack */ ioc3->eisr; /* Flush */ + packets++; + bytes += skb->len; skb = ip->tx_skbs[o_entry]; - ip->stats.tx_packets++; - ip->stats.tx_bytes += skb->len; dev_kfree_skb_irq(skb); ip->tx_skbs[o_entry] = NULL; @@ -411,6 +416,14 @@ etcir = ioc3->etcir; /* More pkts sent? */ tx_entry = (etcir >> 7) & 127; } + + ip->stats.tx_packets += packets; + ip->stats.tx_bytes += bytes; + ip->txqlen -= packets; + + if (ip->txqlen < 128) + netif_wake_queue(dev); + ip->tx_ci = o_entry; spin_unlock(&ip->ioc3_lock); } @@ -454,24 +467,20 @@ ioc3_rx(dev, ip, ioc3); } if (eisr & EISR_TXEXPLICIT) { - ioc3_tx(ip, ioc3); + ioc3_tx(dev, ip, ioc3); } if (eisr & (EISR_RXMEMERR | EISR_TXMEMERR)) { ioc3_error(dev, ip, ioc3, eisr); } - if ((TX_BUFFS_AVAIL(ip) >= 0) && netif_queue_stopped(dev)) { - netif_wake_queue(dev); - } - __cli(); ioc3->eier = eier; return; } -int -ioc3_eth_init(struct net_device *dev, struct ioc3_private *p, struct ioc3 *ioc3) +int ioc3_eth_init(struct net_device *dev, struct ioc3_private *ip, + struct ioc3 *ioc3) { u16 word, mii0, mii_status, mii2, mii3, mii4; u32 vendor, model, rev; @@ -482,6 +491,7 @@ udelay(4); /* Give it time ... */ ioc3->emcr = 0; + spin_lock_irq(&ip->ioc3_lock); phy = -1; for (i = 0; i < 32; i++) { word = mii_read(ioc3, i, 2); @@ -491,10 +501,11 @@ } } if (phy == -1) { + spin_unlock_irq(&ip->ioc3_lock); printk("Didn't find a PHY, goodbye.\n"); return -ENODEV; } - p->phy = phy; + ip->phy = phy; mii0 = mii_read(ioc3, phy, 0); mii_status = mii_read(ioc3, phy, 1); @@ -512,8 +523,13 @@ /* Autonegotiate 100mbit and fullduplex. */ mii_write(ioc3, phy, 0, mii0 | 0x3100); - mdelay(1000); + + spin_unlock_irq(&ip->ioc3_lock); + mdelay(1000); /* XXX Yikes XXX */ + spin_lock_irq(&ip->ioc3_lock); + mii_status = mii_read(ioc3, phy, 1); + spin_unlock_irq(&ip->ioc3_lock); return 0; /* XXX */ } @@ -629,6 +645,7 @@ ioc3_init_rings(dev, ip, ioc3); spin_lock_init(&ip->ioc3_lock); + ip->txqlen = 0; /* Misc registers */ ioc3->erbar = 0; @@ -644,13 +661,14 @@ //ioc3->erpir = ERPIR_ARM; /* The IOC3-specific entries in the device structure. */ - dev->open = &ioc3_open; - dev->hard_start_xmit = &ioc3_start_xmit; + dev->open = ioc3_open; + dev->hard_start_xmit = ioc3_start_xmit; dev->tx_timeout = ioc3_timeout; dev->watchdog_timeo = (400 * HZ) / 1000; - dev->stop = &ioc3_close; - dev->get_stats = &ioc3_get_stats; - dev->set_multicast_list = &ioc3_set_multicast_list; + dev->stop = ioc3_close; + dev->get_stats = ioc3_get_stats; + dev->do_ioctl = ioc3_ioctl; + dev->set_multicast_list = ioc3_set_multicast_list; } int @@ -664,7 +682,11 @@ return 0; initialized++; - nid = get_nasid(); +#if 0 + nid = get_nasid(); /* Never assume we are on master cpu */ +#else + nid = 0; +#endif ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base; ioc3_probe1(dev, ioc3); @@ -693,7 +715,7 @@ ioc3->eier = EISR_RXTIMERINT | EISR_TXEXPLICIT | /* Interrupts ... */ EISR_RXMEMERR | EISR_TXMEMERR; - netif_wake_queue(dev); + netif_start_queue(dev); restore_flags(flags); MOD_INC_USE_COUNT; @@ -711,11 +733,8 @@ struct ioc3_etxd *desc; int produce; - if (!TX_BUFFS_AVAIL(ip)) { - return 1; - } - spin_lock_irq(&ip->ioc3_lock); + data = (unsigned long) skb->data; len = skb->len; @@ -759,8 +778,11 @@ ip->tx_pi = produce; ioc3->etpir = produce << 7; /* Fire ... */ - if (TX_BUFFS_AVAIL(ip)) - netif_wake_queue(dev); + ip->txqlen++; + + if (ip->txqlen > 127) + netif_stop_queue(dev); + spin_unlock_irq(&ip->ioc3_lock); return 0; @@ -853,6 +875,40 @@ return temp; } +/* Provide ioctl() calls to examine the MII xcvr state. */ +static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct ioc3_private *ip = (struct ioc3_private *) dev->priv; + u16 *data = (u16 *)&rq->ifr_data; + struct ioc3 *ioc3 = ip->regs; + int phy = ip->phy; + + switch (cmd) { + case SIOCGMIIPHY: /* Get the address of the PHY in use. */ + if (phy == -1) + return -ENODEV; + data[0] = phy; + return 0; + + case SIOCGMIIREG: /* Read any PHY register. */ + spin_lock_irq(&ip->ioc3_lock); + data[3] = mii_read(ioc3, data[0], data[1]); + spin_unlock_irq(&ip->ioc3_lock); + return 0; + + case SIOCSMIIREG: /* Write any PHY register. */ + spin_lock_irq(&ip->ioc3_lock); + mii_write(ioc3, data[0], data[1], data[2]); + spin_unlock_irq(&ip->ioc3_lock); + return 0; + + default: + return -EOPNOTSUPP; + } + + return -EOPNOTSUPP; +} + static void ioc3_set_multicast_list(struct net_device *dev) { struct dev_mc_list *dmi = dev->mc_list; @@ -905,6 +961,8 @@ struct pci_dev *dev = NULL; while ((dev = pci_find_device(PCI_VENDOR_ID_SGI, 0x0003, dev))) { + if (pci_enable_device(dev)) + continue; ioc3_init(&p, dev); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/irda/Makefile linux.ac/drivers/net/irda/Makefile --- linux.vanilla/drivers/net/irda/Makefile Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/irda/Makefile Sat May 27 15:29:39 2000 @@ -52,22 +52,6 @@ endif endif -ifeq ($(CONFIG_TOSHIBA_FIR),y) -L_OBJS += toshoboe.o -else - ifeq ($(CONFIG_TOSHIBA_FIR),m) - M_OBJS += toshoboe.o - endif -endif - -ifeq ($(CONFIG_TOSHIBA_FIR),y) -L_OBJS += toshoboe.o -else - ifeq ($(CONFIG_TOSHIBA_FIR),m) - M_OBJS += toshoboe.o - endif -endif - ifeq ($(CONFIG_SMC_IRCC_FIR),y) L_OBJS += smc-ircc.o LX_OBJS += irport.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/irda/toshoboe.c linux.ac/drivers/net/irda/toshoboe.c --- linux.vanilla/drivers/net/irda/toshoboe.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/irda/toshoboe.c Fri May 26 14:36:51 2000 @@ -717,7 +717,7 @@ self->open = 0; self->stopped = 0; self->pdev = pci_dev; - self->base = pci_dev->resource[0].start; + self->base = pci_resource_start (pci_dev, 0); self->io.sir_base = self->base; self->io.irq = pci_dev->irq; @@ -900,7 +900,6 @@ static void toshoboe_wakeup (struct toshoboe_cb *self) { - struct net_device *dev = self->netdev; unsigned long flags; if (!self->stopped) @@ -952,36 +951,26 @@ struct pci_dev *pci_dev = NULL; int found = 0; - do - { - pci_dev = pci_find_device (PCI_VENDOR_ID_TOSHIBA, - PCI_DEVICE_ID_FIR701, pci_dev); - if (pci_dev) - { + while ((pci_dev = pci_find_device (PCI_VENDOR_ID_TOSHIBA, + PCI_DEVICE_ID_FIR701, pci_dev)) != NULL) { + if (pci_enable_device(pci_dev)) + continue; printk (KERN_WARNING "ToshOboe: Found 701 chip at 0x%0lx irq %d\n", - pci_dev->resource[0].start, + pci_resource_start (pci_dev, 0), pci_dev->irq); if (!toshoboe_open (pci_dev)) found++; - } - - } - while (pci_dev); - + } if (found) - { return 0; - } return -ENODEV; } -#ifdef MODULE -static void -toshoboe_cleanup (void) +static void __exit toshoboe_cleanup (void) { int i; @@ -997,19 +986,8 @@ } - -int -init_module (void) -{ - return toshoboe_init (); -} - - -void -cleanup_module (void) -{ - toshoboe_cleanup (); -} - - +#ifdef MODULE +module_init(toshoboe_init); #endif +module_exit(toshoboe_cleanup); + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/lance.c linux.ac/drivers/net/lance.c --- linux.vanilla/drivers/net/lance.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/lance.c Fri May 26 14:36:51 2000 @@ -361,7 +361,6 @@ lance_need_isa_bounce_buffers = 0; #if defined(CONFIG_PCI) - if (pci_present()) { struct pci_dev *pdev = NULL; if (lance_debug > 1) @@ -369,20 +368,12 @@ while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, pdev))) { unsigned int pci_ioaddr; - unsigned short pci_command; + if (pci_enable_device(pdev)) + continue; + pci_set_master(pdev); pci_irq_line = pdev->irq; - pci_ioaddr = pdev->resource[0].start; - /* PCI Spec 2.1 states that it is either the driver or PCI card's - * responsibility to set the PCI Master Enable Bit if needed. - * (From Mark Stockton ) - */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_command); - if ( ! (pci_command & PCI_COMMAND_MASTER)) { - printk("PCI Master Bit has not been set. Setting...\n"); - pci_command |= PCI_COMMAND_MASTER; - pci_write_config_word(pdev, PCI_COMMAND, pci_command); - } + pci_ioaddr = pci_resource_start (pdev, 0); printk("Found PCnet/PCI at %#x, irq %d.\n", pci_ioaddr, pci_irq_line); result = lance_probe1(dev, pci_ioaddr, pci_irq_line, 0); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/ne.c linux.ac/drivers/net/ne.c --- linux.vanilla/drivers/net/ne.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/ne.c Fri May 26 14:36:51 2000 @@ -195,7 +195,7 @@ if (base_addr > 0x1ff) /* Check a single specified location. */ return ne_probe1(dev, base_addr); else if (base_addr != 0) /* Don't probe at all. */ - return ENXIO; + return -ENXIO; #ifdef CONFIG_PCI /* Then look for any installed PCI clones */ @@ -218,7 +218,7 @@ } #endif - return ENODEV; + return -ENODEV; } #endif @@ -232,7 +232,9 @@ unsigned int pci_ioaddr; while ((pdev = pci_find_device(pci_clone_list[i].vendor, pci_clone_list[i].dev_id, pdev))) { - pci_ioaddr = pdev->resource[0].start; + if (pci_enable_device(pdev)) + continue; + pci_ioaddr = pci_resource_start (pdev, 0); /* Avoid already found cards from previous calls */ if (check_region(pci_ioaddr, NE_IO_EXTENT)) continue; @@ -309,7 +311,7 @@ static unsigned version_printed = 0; if (reg0 == 0xFF) - return ENODEV; + return -ENODEV; /* Do a preliminary verification that we have a 8390. */ { @@ -322,7 +324,7 @@ if (inb_p(ioaddr + EN0_COUNTER0) != 0) { outb_p(reg0, ioaddr); outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */ - return ENODEV; + return -ENODEV; } } @@ -364,7 +366,7 @@ break; } else { printk(" not found (no reset ack).\n"); - return ENODEV; + return -ENODEV; } } @@ -466,11 +468,11 @@ { printk(" not found (invalid signature %2.2x %2.2x).\n", SA_prom[14], SA_prom[15]); - return ENXIO; + return -ENXIO; } #else printk(" not found.\n"); - return ENXIO; + return -ENXIO; #endif } @@ -496,7 +498,7 @@ if (! dev->irq) { printk(" failed to detect IRQ line.\n"); - return EAGAIN; + return -EAGAIN; } /* Allocate dev->priv and fill in 8390 specific dev fields. */ @@ -516,7 +518,7 @@ printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); kfree(dev->priv); dev->priv = NULL; - return EAGAIN; + return -EAGAIN; } } dev->base_addr = ioaddr; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/net_init.c linux.ac/drivers/net/net_init.c --- linux.vanilla/drivers/net/net_init.c Thu May 25 17:37:50 2000 +++ linux.ac/drivers/net/net_init.c Thu May 25 20:28:46 2000 @@ -115,14 +115,17 @@ * Allocate a name */ - if (dev->name[0] == '\0' || dev->name[0] == ' ') - { - if(dev_alloc_name(dev, mask)<0) - { - if(new_device) - kfree(dev); - return NULL; + if (dev->name[0] == '\0' || dev->name[0] == ' ') { + strcpy(dev->name, mask); + if (!netdev_boot_setup_check(dev)) { + if (dev_alloc_name(dev, mask)<0) { + if (new_device) + kfree(dev); + return NULL; + } } + } else { + netdev_boot_setup_check(dev); } /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/pcmcia/Config.in linux.ac/drivers/net/pcmcia/Config.in --- linux.vanilla/drivers/net/pcmcia/Config.in Thu May 25 17:37:58 2000 +++ linux.ac/drivers/net/pcmcia/Config.in Sat May 27 22:03:39 2000 @@ -21,12 +21,12 @@ tristate ' Xircom Tulip-like CardBus support' CONFIG_PCMCIA_XIRTULIP fi - bool 'Pcmcia Wireless LAN' CONFIG_NET_PCMCIA_RADIO + bool ' Pcmcia Wireless LAN' CONFIG_NET_PCMCIA_RADIO if [ "$CONFIG_NET_PCMCIA_RADIO" = "y" ]; then - dep_tristate ' Aviator/Raytheon 2.4MHz wireless support' CONFIG_PCMCIA_RAYCS $CONFIG_PCMCIA - dep_tristate ' Xircom Netwave AirSurfer wireless support' CONFIG_PCMCIA_NETWAVE $CONFIG_PCMCIA - dep_tristate ' AT&T/Lucent Wavelan wireless support' CONFIG_PCMCIA_WAVELAN $CONFIG_PCMCIA - dep_tristate ' Aironet 4500/4800 PCMCIA support' CONFIG_AIRONET4500_CS $CONFIG_AIRONET4500 $CONFIG_PCMCIA + dep_tristate ' Aviator/Raytheon 2.4MHz wireless support' CONFIG_PCMCIA_RAYCS $CONFIG_PCMCIA + dep_tristate ' Xircom Netwave AirSurfer wireless support' CONFIG_PCMCIA_NETWAVE $CONFIG_PCMCIA + dep_tristate ' AT&T/Lucent Wavelan wireless support' CONFIG_PCMCIA_WAVELAN $CONFIG_PCMCIA + dep_tristate ' Aironet 4500/4800 PCMCIA support' CONFIG_AIRONET4500_CS $CONFIG_AIRONET4500 $CONFIG_PCMCIA fi fi diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/pcnet32.c linux.ac/drivers/net/pcnet32.c --- linux.vanilla/drivers/net/pcnet32.c Thu May 25 17:37:54 2000 +++ linux.ac/drivers/net/pcnet32.c Fri May 26 14:36:51 2000 @@ -311,21 +311,6 @@ int (*probe1) (unsigned long, unsigned char, int, int, struct pci_dev *); }; -static struct pcnet32_pci_id_info pcnet32_tbl[] = { - { "AMD PCnetPCI series", - PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0, 0, - PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, - pcnet32_probe1}, - { "AMD PCnetPCI series (IBM)", - PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, 0x1014, 0x2000, - PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, - pcnet32_probe1}, - { "AMD PCnetHome series", - PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_PCNETHOME, 0, 0, - PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE, - pcnet32_probe1}, - {0,} -}; /* * PCI device identifiers for "new style" Linux PCI Device Drivers @@ -751,7 +736,7 @@ } if (pcnet32_debug > 0) - printk(KERN_INFO, version); + printk(KERN_INFO "%s", version); /* The PCNET32-specific entries in the device structure. */ dev->open = &pcnet32_open; @@ -1257,8 +1242,7 @@ lp->stats.rx_errors++; } else { int rx_in_place = 0; - dma_addr_t rx_dma_addr = lp->rx_dma_addr[entry]; - + if (pkt_len > rx_copybreak) { struct sk_buff *newskb; @@ -1524,7 +1508,7 @@ /* find the PCI devices */ #define USE_PCI_REGISTER_DRIVER #ifdef USE_PCI_REGISTER_DRIVER - if (err = pci_module_init(&pcnet32_driver) < 0 ) + if ((err = pci_module_init(&pcnet32_driver)) < 0 ) return err; #else { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/rcpci45.c linux.ac/drivers/net/rcpci45.c --- linux.vanilla/drivers/net/rcpci45.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/rcpci45.c Fri May 26 14:36:51 2000 @@ -205,7 +205,7 @@ !((pdev = pci_find_slot(pci_bus, pci_device_fn)))) break; pci_irq_line = pdev->irq; - pci_ioaddr = pdev->resource[0].start; + pci_ioaddr = pci_resource_start (pdev, 0); #ifdef RCDEBUG printk("rc: Found RedCreek PCI adapter\n"); @@ -214,6 +214,8 @@ printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr); #endif + if (pci_enable_device(pdev)) + break; pci_set_master(pdev); if (!RCfound_device(pci_ioaddr, pci_irq_line, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/rrunner.c linux.ac/drivers/net/rrunner.c --- linux.vanilla/drivers/net/rrunner.c Thu May 25 17:37:56 2000 +++ linux.ac/drivers/net/rrunner.c Fri May 26 14:36:51 2000 @@ -146,6 +146,9 @@ PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER, pdev))) { + if (pci_enable_device(pdev)) + continue; + if (pdev == opdev) return 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/rtl8129.c linux.ac/drivers/net/rtl8129.c --- linux.vanilla/drivers/net/rtl8129.c Thu May 25 17:37:58 2000 +++ linux.ac/drivers/net/rtl8129.c 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/sunhme.c linux.ac/drivers/net/sunhme.c --- linux.vanilla/drivers/net/sunhme.c Thu May 25 17:37:53 2000 +++ linux.ac/drivers/net/sunhme.c Wed May 31 00:23:28 2000 @@ -2519,12 +2519,12 @@ if (is_qfe) { qp = quattro_sbus_find(sdev); if (qp == NULL) - return ENODEV; + return -ENODEV; for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) if (qp->happy_meals[qfe_slot] == NULL) break; if (qfe_slot == 4) - return ENODEV; + return -ENODEV; } if (dev == NULL) { dev = init_etherdev(0, sizeof(struct happy_meal)); @@ -2564,7 +2564,7 @@ printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", sdev->num_registers); printk(KERN_ERR "happymeal: Would you like that for here or to go?\n"); - return ENODEV; + return -ENODEV; } if (qp != NULL) { @@ -2578,35 +2578,35 @@ GREG_REG_SIZE, "HME Global Regs"); if (!hp->gregs) { printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); - return ENODEV; + return -ENODEV; } hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, ETX_REG_SIZE, "HME TX Regs"); if (!hp->etxregs) { printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); - return ENODEV; + return -ENODEV; } hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, ERX_REG_SIZE, "HME RX Regs"); if (!hp->erxregs) { printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); - return ENODEV; + return -ENODEV; } hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, BMAC_REG_SIZE, "HME BIGMAC Regs"); if (!hp->bigmacregs) { printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); - return ENODEV; + return -ENODEV; } hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, TCVR_REG_SIZE, "HME Tranceiver Regs"); if (!hp->tcvregs) { printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); - return ENODEV; + return -ENODEV; } hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); @@ -2695,7 +2695,7 @@ pcp = pdev->sysdata; if (pcp == NULL || pcp->prom_node == -1) { printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); - return ENODEV; + return -ENODEV; } node = pcp->prom_node; @@ -2703,12 +2703,12 @@ if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) { qp = quattro_pci_find(pdev); if (qp == NULL) - return ENODEV; + return -ENODEV; for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) if (qp->happy_meals[qfe_slot] == NULL) break; if (qfe_slot == 4) - return ENODEV; + return -ENODEV; } if (dev == NULL) { dev = init_etherdev(0, sizeof(struct happy_meal)); @@ -2758,12 +2758,11 @@ qp->happy_meals[qfe_slot] = dev; } - hpreg_base = pdev->resource[0].start; + hpreg_base = pci_resource_start(pdev, 0); if ((pdev->resource[0].flags & IORESOURCE_IO) != 0) { printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n"); - return ENODEV; + return -ENODEV; } - hpreg_base &= PCI_BASE_ADDRESS_MEM_MASK; hpreg_base = (unsigned long) ioremap(hpreg_base, 0x8000); if (qfe_slot != -1 && prom_getproplen(node, "local-mac-address") == 6) @@ -2806,7 +2805,7 @@ if (!hp->happy_block) { printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n"); - return ENODEV; + return -ENODEV; } hp->linkcheck = 0; @@ -2920,7 +2919,7 @@ #endif if (called) - return ENODEV; + return -ENODEV; called++; cards = 0; @@ -2933,7 +2932,7 @@ cards += happy_meal_pci_probe(dev); #endif if (!cards) - return ENODEV; + return -ENODEV; return 0; } 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 Sun Jun 4 22:41:54 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 Sun Jun 4 22:42:02 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 Sun Jun 4 22:19:54 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 @@ -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 Sun Jun 4 22:21:48 2000 @@ -1,3 +1,23 @@ +2000-05-28 Gunther Mayer + + * Fix PCI ID printk for non-superio PCI cards. + +2000-05-28 Tim Waugh + + * share.c (call_driver_chain): Get the driverlist_lock. + (parport_register_device): Make sure that port->devices always + looks consistent. + (parport_register_driver): Ensure that parport drivers are given + parameters that are valid for the duration of the callback by + locking the portlist against changes. + (parport_unregister_driver): Likewise. + (parport_claim): Don't overwrite flags. + +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 Wed May 31 11:21:50 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; @@ -181,6 +181,26 @@ } /* + * PIIX3 USB: We have to disable USB interrupts that are + * hardwired to PIRQD# and may be shared with an + * external device. + * + * Legacy Support Register (LEGSUP): + * bit13: USB PIRQ Enable (USBPIRQDEN), + * bit4: Trap/SMI ON IRQ Enable (USBSMIEN). + * + * We mask out all r/wc bits, too. + */ +static void __init quirk_piix3usb(struct pci_dev *dev) +{ + u16 legsup; + + pci_read_config_word(dev, 0xc0, &legsup); + legsup &= 0x50ef; + pci_write_config_word(dev, 0xc0, legsup); +} + +/* * The main table of quirks. */ @@ -209,10 +229,11 @@ { 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 }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_2, quirk_piix3usb }, { 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/hosts.c linux.ac/drivers/scsi/hosts.c --- linux.vanilla/drivers/scsi/hosts.c Thu May 25 17:38:03 2000 +++ linux.ac/drivers/scsi/hosts.c Sun Jun 4 21:16:31 2000 @@ -345,6 +345,10 @@ #include "../acorn/scsi/powertec.h" #endif +#ifdef CONFIG_SCSI_ARXESCSI +#include "../acorn/scsi/arxescsi.h" +#endif + #ifdef CONFIG_JAZZ_ESP #include "jazz_esp.h" #endif @@ -635,6 +639,9 @@ #endif #ifdef CONFIG_SCSI_CUMANA_2 CUMANA_FAS216, +#endif +#ifdef CONFIG_SCSI_ARXESCSI + ARXEScsi, #endif #ifdef CONFIG_SCSI_ECOSCSI ECOSCSI_NCR5380, 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 Sun Jun 4 22:47:31 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 Sun Jun 4 22:47:31 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/724hwmcode.h linux.ac/drivers/sound/724hwmcode.h --- linux.vanilla/drivers/sound/724hwmcode.h Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/sound/724hwmcode.h Wed May 31 11:15:34 2000 @@ -0,0 +1,1575 @@ +//============================================================================= +// Copyright (c) 1997-1999 Yamaha Corporation. All Rights Reserved. +// +// Title: +// hwmcode.c +// Desc: +// micro-code for CTRL & DSP +//============================================================================= +#ifndef _HWMCODE_ +#define _HWMCODE_ + +static unsigned long int DspInst[] = { + 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, + 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, + 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, + 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static unsigned long int CntrlInst[] = { + 0x000007, 0x240007, 0x0C0007, 0x1C0007, + 0x060007, 0x700002, 0x000020, 0x030040, + 0x007104, 0x004286, 0x030040, 0x000F0D, + 0x000810, 0x20043A, 0x000282, 0x00020D, + 0x000810, 0x20043A, 0x001282, 0x200E82, + 0x001A82, 0x032D0D, 0x000810, 0x10043A, + 0x02D38D, 0x000810, 0x18043A, 0x00010D, + 0x020015, 0x0000FD, 0x000020, 0x038860, + 0x039060, 0x038060, 0x038040, 0x038040, + 0x038040, 0x018040, 0x000A7D, 0x038040, + 0x038040, 0x018040, 0x200402, 0x000882, + 0x08001A, 0x000904, 0x015986, 0x000007, + 0x260007, 0x000007, 0x000007, 0x018A06, + 0x000007, 0x030C8D, 0x000810, 0x18043A, + 0x260007, 0x00087D, 0x018042, 0x00160A, + 0x04A206, 0x000007, 0x00218D, 0x000810, + 0x08043A, 0x21C206, 0x000007, 0x0007FD, + 0x018042, 0x08000A, 0x000904, 0x029386, + 0x000195, 0x090D04, 0x000007, 0x000820, + 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD, + 0x032206, 0x018040, 0x000A7D, 0x038042, + 0x13804A, 0x18000A, 0x001820, 0x059060, + 0x058860, 0x018040, 0x0000FD, 0x018042, + 0x70000A, 0x000115, 0x071144, 0x032386, + 0x030000, 0x007020, 0x034A06, 0x018040, + 0x00348D, 0x000810, 0x08043A, 0x21EA06, + 0x000007, 0x02D38D, 0x000810, 0x18043A, + 0x018206, 0x000007, 0x240007, 0x000F8D, + 0x000810, 0x00163A, 0x002402, 0x005C02, + 0x0028FD, 0x000020, 0x018040, 0x08000D, + 0x000815, 0x510984, 0x000007, 0x00004D, + 0x000E5D, 0x000E02, 0x00418D, 0x000810, + 0x08043A, 0x2C8A06, 0x000007, 0x00008D, + 0x000924, 0x000F02, 0x00458D, 0x000810, + 0x08043A, 0x2C8A06, 0x000007, 0x00387D, + 0x018042, 0x08000A, 0x001015, 0x010984, + 0x018386, 0x000007, 0x01AA06, 0x000007, + 0x0008FD, 0x018042, 0x18000A, 0x001904, + 0x218086, 0x280007, 0x001810, 0x28043A, + 0x280C02, 0x00000D, 0x000810, 0x28143A, + 0x08808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00020D, 0x189904, 0x000007, + 0x00402D, 0x0000BD, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x055A86, 0x000007, + 0x000100, 0x000A20, 0x00047D, 0x018040, + 0x018042, 0x20000A, 0x003015, 0x012144, + 0x034986, 0x000007, 0x002104, 0x034986, + 0x000007, 0x000F8D, 0x000810, 0x280C3A, + 0x023944, 0x06C986, 0x000007, 0x001810, + 0x28043A, 0x08810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x002810, 0x78003A, + 0x00688D, 0x000810, 0x08043A, 0x288A06, + 0x000007, 0x00400D, 0x001015, 0x189904, + 0x292904, 0x393904, 0x000007, 0x060206, + 0x000007, 0x0004F5, 0x00007D, 0x000020, + 0x00008D, 0x010860, 0x018040, 0x00047D, + 0x038042, 0x21804A, 0x18000A, 0x021944, + 0x215886, 0x000007, 0x004075, 0x71F104, + 0x000007, 0x010042, 0x28000A, 0x002904, + 0x212086, 0x000007, 0x003C0D, 0x30A904, + 0x000007, 0x00077D, 0x018042, 0x08000A, + 0x000904, 0x07DA86, 0x00057D, 0x002820, + 0x03B060, 0x07F206, 0x018040, 0x003020, + 0x03A860, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x07FA86, 0x000007, + 0x00057D, 0x018042, 0x28040A, 0x000E8D, + 0x000810, 0x280C3A, 0x00000D, 0x000810, + 0x28143A, 0x09000D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x003DFD, 0x000020, + 0x018040, 0x00107D, 0x008D8D, 0x000810, + 0x08043A, 0x288A06, 0x000007, 0x000815, + 0x08001A, 0x010984, 0x095186, 0x00137D, + 0x200500, 0x280F20, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x038A60, 0x018040, 0x007FBD, 0x383DC4, + 0x000007, 0x001A7D, 0x001375, 0x018042, + 0x09004A, 0x10000A, 0x0B8D04, 0x139504, + 0x000007, 0x000820, 0x019060, 0x001104, + 0x212086, 0x010040, 0x0017FD, 0x018042, + 0x08000A, 0x000904, 0x212286, 0x000007, + 0x00197D, 0x038042, 0x09804A, 0x10000A, + 0x000924, 0x001664, 0x0011FD, 0x038042, + 0x2B804A, 0x19804A, 0x00008D, 0x218944, + 0x000007, 0x002244, 0x0AE186, 0x000007, + 0x001A64, 0x002A24, 0x00197D, 0x080102, + 0x100122, 0x000820, 0x039060, 0x018040, + 0x003DFD, 0x00008D, 0x000820, 0x018040, + 0x001375, 0x001A7D, 0x010042, 0x09804A, + 0x10000A, 0x00021D, 0x0189E4, 0x2992E4, + 0x309144, 0x000007, 0x00060D, 0x000A15, + 0x000C1D, 0x001025, 0x00A9E4, 0x012BE4, + 0x000464, 0x01B3E4, 0x0232E4, 0x000464, + 0x000464, 0x000464, 0x000464, 0x00040D, + 0x08B1C4, 0x000007, 0x000820, 0x000BF5, + 0x030040, 0x00197D, 0x038042, 0x09804A, + 0x000A24, 0x08000A, 0x080E64, 0x000007, + 0x100122, 0x000820, 0x031060, 0x010040, + 0x0064AC, 0x00027D, 0x000020, 0x018040, + 0x00107D, 0x018042, 0x0011FD, 0x3B804A, + 0x09804A, 0x20000A, 0x000095, 0x1A1144, + 0x00A144, 0x0D2086, 0x00040D, 0x00B984, + 0x0D2186, 0x0018FD, 0x018042, 0x0010FD, + 0x09804A, 0x28000A, 0x000095, 0x010924, + 0x002A64, 0x0D1186, 0x000007, 0x002904, + 0x0D2286, 0x000007, 0x0D2A06, 0x080002, + 0x00008D, 0x00387D, 0x000820, 0x018040, + 0x00127D, 0x018042, 0x10000A, 0x003904, + 0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984, + 0x0DA186, 0x000025, 0x0E7A06, 0x00002D, + 0x000015, 0x00082D, 0x02C78D, 0x000820, + 0x0EC206, 0x00000D, 0x7F8035, 0x00B984, + 0x0E7186, 0x400025, 0x00008D, 0x110944, + 0x000007, 0x00018D, 0x109504, 0x000007, + 0x009164, 0x000424, 0x000424, 0x000424, + 0x100102, 0x280002, 0x02C68D, 0x000820, + 0x0EC206, 0x00018D, 0x00042D, 0x00008D, + 0x109504, 0x000007, 0x00020D, 0x109184, + 0x000007, 0x02C70D, 0x000820, 0x00008D, + 0x0038FD, 0x018040, 0x003BFD, 0x001020, + 0x03A860, 0x000815, 0x313184, 0x212184, + 0x000007, 0x03B060, 0x03A060, 0x018040, + 0x0022FD, 0x000095, 0x010924, 0x000424, + 0x000424, 0x001264, 0x100102, 0x000820, + 0x039060, 0x018040, 0x001924, 0x00FB8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x000424, + 0x000424, 0x00117D, 0x018042, 0x08000A, + 0x000A24, 0x280502, 0x280C02, 0x09800D, + 0x000820, 0x0002FD, 0x018040, 0x200007, + 0x0022FD, 0x018042, 0x08000A, 0x000095, + 0x280DC4, 0x011924, 0x00197D, 0x018042, + 0x0011FD, 0x09804A, 0x10000A, 0x0000B5, + 0x113144, 0x0A8D04, 0x000007, 0x080A44, + 0x129504, 0x000007, 0x0023FD, 0x001020, + 0x038040, 0x101244, 0x000007, 0x000820, + 0x039060, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x10FA86, 0x000007, + 0x003BFD, 0x000100, 0x000A10, 0x0B807A, + 0x13804A, 0x090984, 0x000007, 0x000095, + 0x013D04, 0x118086, 0x10000A, 0x100002, + 0x090984, 0x000007, 0x038042, 0x11804A, + 0x090D04, 0x000007, 0x10000A, 0x090D84, + 0x000007, 0x00257D, 0x000820, 0x018040, + 0x00010D, 0x000810, 0x28143A, 0x00127D, + 0x018042, 0x20000A, 0x00197D, 0x018042, + 0x00117D, 0x31804A, 0x10000A, 0x003124, + 0x01280D, 0x00397D, 0x000820, 0x058040, + 0x038042, 0x09844A, 0x000606, 0x08040A, + 0x300102, 0x003124, 0x000424, 0x000424, + 0x001224, 0x280502, 0x001A4C, 0x130186, + 0x700002, 0x00002D, 0x030000, 0x00387D, + 0x018042, 0x10000A, 0x132A06, 0x002124, + 0x0000AD, 0x100002, 0x00010D, 0x000924, + 0x006B24, 0x01368D, 0x00397D, 0x000820, + 0x058040, 0x038042, 0x09844A, 0x000606, + 0x08040A, 0x003264, 0x00008D, 0x000A24, + 0x001020, 0x00227D, 0x018040, 0x013C0D, + 0x000810, 0x08043A, 0x29D206, 0x000007, + 0x002820, 0x00207D, 0x018040, 0x00117D, + 0x038042, 0x13804A, 0x33800A, 0x00387D, + 0x018042, 0x08000A, 0x000904, 0x163A86, + 0x000007, 0x00008D, 0x030964, 0x01478D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x380102, + 0x000424, 0x000424, 0x001224, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x14A286, + 0x000007, 0x280502, 0x001A4C, 0x163986, + 0x000007, 0x032164, 0x00632C, 0x003DFD, + 0x018042, 0x08000A, 0x000095, 0x090904, + 0x000007, 0x000820, 0x001A4C, 0x156186, + 0x018040, 0x030000, 0x157A06, 0x002124, + 0x00010D, 0x000924, 0x006B24, 0x015B8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x003A64, + 0x000095, 0x001224, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x15DA86, 0x000007, + 0x01628D, 0x000810, 0x08043A, 0x29D206, + 0x000007, 0x14D206, 0x000007, 0x007020, + 0x08010A, 0x10012A, 0x0020FD, 0x038860, + 0x039060, 0x018040, 0x00227D, 0x018042, + 0x003DFD, 0x08000A, 0x31844A, 0x000904, + 0x16D886, 0x18008B, 0x00008D, 0x189904, + 0x00312C, 0x17AA06, 0x000007, 0x00324C, + 0x173386, 0x000007, 0x001904, 0x173086, + 0x000007, 0x000095, 0x199144, 0x00222C, + 0x003124, 0x00636C, 0x000E3D, 0x001375, + 0x000BFD, 0x010042, 0x09804A, 0x10000A, + 0x038AEC, 0x0393EC, 0x00224C, 0x17A986, + 0x000007, 0x00008D, 0x189904, 0x00226C, + 0x00322C, 0x30050A, 0x301DAB, 0x002083, + 0x0018FD, 0x018042, 0x08000A, 0x018924, + 0x300502, 0x001083, 0x001875, 0x010042, + 0x10000A, 0x00008D, 0x010924, 0x001375, + 0x330542, 0x330CCB, 0x332CCB, 0x3334CB, + 0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB, + 0x305C8B, 0x006083, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x187A86, 0x000007, + 0x001E2D, 0x0005FD, 0x018042, 0x08000A, + 0x028924, 0x280502, 0x00060D, 0x000810, + 0x280C3A, 0x00008D, 0x000810, 0x28143A, + 0x0A808D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x001275, 0x030042, 0x21004A, + 0x00008D, 0x1A0944, 0x000007, 0x01980D, + 0x000810, 0x08043A, 0x2B2206, 0x000007, + 0x0001F5, 0x030042, 0x0D004A, 0x10000A, + 0x089144, 0x000007, 0x000820, 0x010040, + 0x0025F5, 0x0A3144, 0x000007, 0x000820, + 0x032860, 0x030040, 0x00217D, 0x038042, + 0x0B804A, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x00008D, 0x000124, 0x00012C, + 0x000E64, 0x001A64, 0x00636C, 0x08010A, + 0x10012A, 0x000820, 0x031060, 0x030040, + 0x0020FD, 0x018042, 0x08000A, 0x00227D, + 0x018042, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x00197D, 0x018042, 0x08000A, + 0x0022FD, 0x038042, 0x10000A, 0x000820, + 0x031060, 0x030040, 0x090D04, 0x000007, + 0x000820, 0x030040, 0x038042, 0x0B804A, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x038042, 0x13804A, 0x19804A, 0x110D04, + 0x198D04, 0x000007, 0x08000A, 0x001020, + 0x031860, 0x030860, 0x030040, 0x00008D, + 0x0B0944, 0x000007, 0x000820, 0x010040, + 0x0005F5, 0x030042, 0x08000A, 0x000820, + 0x010040, 0x0000F5, 0x010042, 0x08000A, + 0x000904, 0x1C6086, 0x001E75, 0x030042, + 0x01044A, 0x000C0A, 0x1C7206, 0x000007, + 0x000402, 0x000C02, 0x00177D, 0x001AF5, + 0x018042, 0x03144A, 0x031C4A, 0x03244A, + 0x032C4A, 0x03344A, 0x033C4A, 0x03444A, + 0x004C0A, 0x00043D, 0x0013F5, 0x001AFD, + 0x030042, 0x0B004A, 0x1B804A, 0x13804A, + 0x20000A, 0x089144, 0x19A144, 0x0389E4, + 0x0399EC, 0x005502, 0x005D0A, 0x030042, + 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, + 0x089144, 0x19A144, 0x0389E4, 0x0399EC, + 0x006502, 0x006D0A, 0x030042, 0x0B004A, + 0x19004A, 0x2B804A, 0x13804A, 0x21804A, + 0x30000A, 0x089144, 0x19A144, 0x2AB144, + 0x0389E4, 0x0399EC, 0x007502, 0x007D0A, + 0x03A9E4, 0x000702, 0x00107D, 0x000415, + 0x018042, 0x08000A, 0x0109E4, 0x000F02, + 0x002AF5, 0x0019FD, 0x010042, 0x09804A, + 0x10000A, 0x000934, 0x001674, 0x0029F5, + 0x010042, 0x10000A, 0x00917C, 0x002075, + 0x010042, 0x08000A, 0x000904, 0x1ED286, + 0x0026F5, 0x0027F5, 0x030042, 0x09004A, + 0x10000A, 0x000A3C, 0x00167C, 0x001A75, + 0x000BFD, 0x010042, 0x51804A, 0x48000A, + 0x160007, 0x001075, 0x010042, 0x282C0A, + 0x281D12, 0x282512, 0x001F32, 0x1E0007, + 0x0E0007, 0x001975, 0x010042, 0x002DF5, + 0x0D004A, 0x10000A, 0x009144, 0x1FB286, + 0x010042, 0x28340A, 0x000E5D, 0x00008D, + 0x000375, 0x000820, 0x010040, 0x05D2F4, + 0x54D104, 0x00735C, 0x205386, 0x000007, + 0x0C0007, 0x080007, 0x0A0007, 0x02040D, + 0x000810, 0x08043A, 0x332206, 0x000007, + 0x205A06, 0x000007, 0x080007, 0x002275, + 0x010042, 0x20000A, 0x002104, 0x212086, + 0x001E2D, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x209286, 0x000007, 0x002010, + 0x30043A, 0x00057D, 0x0180C3, 0x08000A, + 0x028924, 0x280502, 0x280C02, 0x0A810D, + 0x000820, 0x0002F5, 0x010040, 0x220007, + 0x0004FD, 0x018042, 0x70000A, 0x030000, + 0x007020, 0x06FA06, 0x018040, 0x02180D, + 0x000810, 0x08043A, 0x2B2206, 0x000007, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x218A86, 0x000007, 0x01F206, 0x000007, + 0x000875, 0x0009FD, 0x00010D, 0x220A06, + 0x000295, 0x000B75, 0x00097D, 0x00000D, + 0x000515, 0x010042, 0x18000A, 0x001904, + 0x287886, 0x0006F5, 0x001020, 0x010040, + 0x0004F5, 0x000820, 0x010040, 0x000775, + 0x010042, 0x09804A, 0x10000A, 0x001124, + 0x000904, 0x22BA86, 0x000815, 0x080102, + 0x101204, 0x22DA06, 0x000575, 0x081204, + 0x000007, 0x100102, 0x000575, 0x000425, + 0x021124, 0x100102, 0x000820, 0x031060, + 0x010040, 0x001924, 0x287886, 0x00008D, + 0x000464, 0x009D04, 0x278886, 0x180102, + 0x000575, 0x010042, 0x28040A, 0x00018D, + 0x000924, 0x280D02, 0x00000D, 0x000924, + 0x281502, 0x10000D, 0x000820, 0x0002F5, + 0x010040, 0x200007, 0x001175, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x23C286, + 0x000007, 0x000100, 0x080B20, 0x130B60, + 0x1B0B60, 0x030A60, 0x010040, 0x050042, + 0x3D004A, 0x35004A, 0x2D004A, 0x20000A, + 0x0006F5, 0x010042, 0x28140A, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x24CA86, 0x004015, 0x000095, 0x010D04, + 0x24B886, 0x100022, 0x10002A, 0x24E206, + 0x000007, 0x333104, 0x2AA904, 0x000007, + 0x032124, 0x280502, 0x001124, 0x000424, + 0x000424, 0x003224, 0x00292C, 0x00636C, + 0x25F386, 0x000007, 0x02B164, 0x000464, + 0x000464, 0x00008D, 0x000A64, 0x280D02, + 0x10008D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x00008D, 0x38B904, 0x000007, + 0x03296C, 0x30010A, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x25BA86, 0x000007, + 0x02312C, 0x28050A, 0x00008D, 0x01096C, + 0x280D0A, 0x10010D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x001124, 0x000424, + 0x000424, 0x003224, 0x300102, 0x032944, + 0x267A86, 0x000007, 0x300002, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x26C086, 0x003124, 0x000464, 0x300102, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x26CA86, 0x000007, 0x003124, 0x300502, + 0x003924, 0x300583, 0x000883, 0x0005F5, + 0x010042, 0x28040A, 0x00008D, 0x008124, + 0x280D02, 0x00008D, 0x008124, 0x281502, + 0x10018D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x001025, 0x000575, 0x030042, + 0x09004A, 0x10000A, 0x0A0904, 0x121104, + 0x000007, 0x001020, 0x050860, 0x050040, + 0x0006FD, 0x018042, 0x09004A, 0x10000A, + 0x0000A5, 0x0A0904, 0x121104, 0x000007, + 0x000820, 0x019060, 0x010040, 0x0002F5, + 0x010042, 0x08000A, 0x000904, 0x284286, + 0x000007, 0x230A06, 0x000007, 0x000606, + 0x000007, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x289286, 0x000007, 0x000100, + 0x080B20, 0x138B60, 0x1B8B60, 0x238B60, + 0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60, + 0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60, + 0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60, + 0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60, + 0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60, + 0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60, + 0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60, + 0x000606, 0x018040, 0x00008D, 0x000A64, + 0x280D02, 0x000A24, 0x00027D, 0x018042, + 0x10000A, 0x001224, 0x0003FD, 0x018042, + 0x08000A, 0x000904, 0x2A8286, 0x000007, + 0x00018D, 0x000A24, 0x000464, 0x000464, + 0x080102, 0x000924, 0x000424, 0x000424, + 0x100102, 0x02000D, 0x009144, 0x2AD986, + 0x000007, 0x0001FD, 0x018042, 0x08000A, + 0x000A44, 0x2ABB86, 0x018042, 0x0A000D, + 0x000820, 0x0002FD, 0x018040, 0x200007, + 0x00027D, 0x001020, 0x000606, 0x018040, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x2B2A86, 0x000007, 0x00037D, 0x018042, + 0x08000A, 0x000904, 0x2B5A86, 0x000007, + 0x000075, 0x002E7D, 0x010042, 0x0B804A, + 0x000020, 0x000904, 0x000686, 0x010040, + 0x31844A, 0x30048B, 0x000883, 0x00008D, + 0x000810, 0x28143A, 0x00008D, 0x000810, + 0x280C3A, 0x000675, 0x010042, 0x08000A, + 0x003815, 0x010924, 0x280502, 0x0B000D, + 0x000820, 0x0002F5, 0x010040, 0x000606, + 0x220007, 0x000464, 0x000464, 0x000606, + 0x000007, 0x000134, 0x007F8D, 0x00093C, + 0x281D12, 0x282512, 0x001F32, 0x0E0007, + 0x00010D, 0x00037D, 0x000820, 0x018040, + 0x05D2F4, 0x000007, 0x080007, 0x00037D, + 0x018042, 0x08000A, 0x000904, 0x2D0286, + 0x000007, 0x000606, 0x000007, 0x000007, + 0x000012, 0x100007, 0x320007, 0x600007, + 0x100080, 0x48001A, 0x004904, 0x2D6186, + 0x000007, 0x001210, 0x58003A, 0x000145, + 0x5C5D04, 0x000007, 0x000080, 0x48001A, + 0x004904, 0x2DB186, 0x000007, 0x001210, + 0x50003A, 0x005904, 0x2E0886, 0x000045, + 0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524, + 0x004224, 0x500102, 0x200502, 0x000082, + 0x40001A, 0x004104, 0x2E3986, 0x000007, + 0x003865, 0x40001A, 0x004020, 0x00104D, + 0x04C184, 0x301B86, 0x000040, 0x040007, + 0x000165, 0x000145, 0x004020, 0x000040, + 0x000765, 0x080080, 0x40001A, 0x004104, + 0x2EC986, 0x000007, 0x001210, 0x40003A, + 0x004104, 0x2F2286, 0x00004D, 0x0000CD, + 0x004810, 0x20043A, 0x000882, 0x40001A, + 0x004104, 0x2F3186, 0x000007, 0x004820, + 0x005904, 0x300886, 0x000040, 0x0007E5, + 0x200480, 0x2816A0, 0x3216E0, 0x3A16E0, + 0x4216E0, 0x021260, 0x000040, 0x000032, + 0x400075, 0x00007D, 0x07D574, 0x200512, + 0x000082, 0x40001A, 0x004104, 0x2FE186, + 0x000007, 0x037206, 0x640007, 0x060007, + 0x0000E5, 0x000020, 0x000040, 0x000A65, + 0x000020, 0x020040, 0x020040, 0x000040, + 0x000165, 0x000042, 0x70000A, 0x007104, + 0x30A286, 0x000007, 0x018206, 0x640007, + 0x050000, 0x007020, 0x000040, 0x037206, + 0x640007, 0x000007, 0x00306D, 0x028860, + 0x029060, 0x08000A, 0x028860, 0x008040, + 0x100012, 0x00100D, 0x009184, 0x314186, + 0x000E0D, 0x009184, 0x325186, 0x000007, + 0x300007, 0x001020, 0x003B6D, 0x008040, + 0x000080, 0x08001A, 0x000904, 0x316186, + 0x000007, 0x001220, 0x000DED, 0x008040, + 0x008042, 0x10000A, 0x40000D, 0x109544, + 0x000007, 0x001020, 0x000DED, 0x008040, + 0x008042, 0x20040A, 0x000082, 0x08001A, + 0x000904, 0x31F186, 0x000007, 0x003B6D, + 0x008042, 0x08000A, 0x000E15, 0x010984, + 0x329B86, 0x600007, 0x08001A, 0x000C15, + 0x010984, 0x328386, 0x000020, 0x1A0007, + 0x0002ED, 0x008040, 0x620007, 0x00306D, + 0x028042, 0x0A804A, 0x000820, 0x0A804A, + 0x000606, 0x10804A, 0x000007, 0x282512, + 0x001F32, 0x05D2F4, 0x54D104, 0x00735C, + 0x000786, 0x000007, 0x0C0007, 0x0A0007, + 0x1C0007, 0x003465, 0x020040, 0x004820, + 0x025060, 0x40000A, 0x024060, 0x000040, + 0x454944, 0x000007, 0x004020, 0x003AE5, + 0x000040, 0x0028E5, 0x000042, 0x48000A, + 0x004904, 0x386886, 0x002C65, 0x000042, + 0x40000A, 0x0000D5, 0x454104, 0x000007, + 0x000655, 0x054504, 0x34F286, 0x0001D5, + 0x054504, 0x34F086, 0x002B65, 0x000042, + 0x003AE5, 0x50004A, 0x40000A, 0x45C3D4, + 0x000007, 0x454504, 0x000007, 0x0000CD, + 0x444944, 0x000007, 0x454504, 0x000007, + 0x00014D, 0x554944, 0x000007, 0x045144, + 0x34E986, 0x002C65, 0x000042, 0x48000A, + 0x4CD104, 0x000007, 0x04C144, 0x34F386, + 0x000007, 0x160007, 0x002CE5, 0x040042, + 0x40000A, 0x004020, 0x000040, 0x002965, + 0x000042, 0x40000A, 0x004104, 0x356086, + 0x000007, 0x002402, 0x36A206, 0x005C02, + 0x0025E5, 0x000042, 0x40000A, 0x004274, + 0x002AE5, 0x000042, 0x40000A, 0x004274, + 0x500112, 0x0029E5, 0x000042, 0x40000A, + 0x004234, 0x454104, 0x000007, 0x004020, + 0x000040, 0x003EE5, 0x000020, 0x000040, + 0x002DE5, 0x400152, 0x50000A, 0x045144, + 0x364A86, 0x0000C5, 0x003EE5, 0x004020, + 0x000040, 0x002BE5, 0x000042, 0x40000A, + 0x404254, 0x000007, 0x002AE5, 0x004020, + 0x000040, 0x500132, 0x040134, 0x005674, + 0x0029E5, 0x020042, 0x42000A, 0x000042, + 0x50000A, 0x05417C, 0x0028E5, 0x000042, + 0x48000A, 0x0000C5, 0x4CC144, 0x371086, + 0x0026E5, 0x0027E5, 0x020042, 0x40004A, + 0x50000A, 0x00423C, 0x00567C, 0x0028E5, + 0x004820, 0x000040, 0x281D12, 0x282512, + 0x001F72, 0x002965, 0x000042, 0x40000A, + 0x004104, 0x37AA86, 0x0E0007, 0x160007, + 0x1E0007, 0x003EE5, 0x000042, 0x40000A, + 0x004104, 0x37E886, 0x002D65, 0x000042, + 0x28340A, 0x003465, 0x020042, 0x42004A, + 0x004020, 0x4A004A, 0x50004A, 0x05D2F4, + 0x54D104, 0x00735C, 0x385186, 0x000007, + 0x000606, 0x080007, 0x0C0007, 0x080007, + 0x0A0007, 0x0001E5, 0x020045, 0x004020, + 0x000060, 0x000365, 0x000040, 0x002E65, + 0x001A20, 0x0A1A60, 0x000040, 0x003465, + 0x020042, 0x42004A, 0x004020, 0x4A004A, + 0x000606, 0x50004A, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000 +}; + +// -------------------------------------------- +// DS-1E Controller InstructionRAM Code +// 1999/06/21 +// Buf441 slot is Enabled. +// -------------------------------------------- +// 04/09?@creat +// 04/12 stop nise fix +// 06/21?@WorkingOff timming +static unsigned long int CntrlInst1E[] = { + 0x000007, 0x240007, 0x0C0007, 0x1C0007, + 0x060007, 0x700002, 0x000020, 0x030040, + 0x007104, 0x004286, 0x030040, 0x000F0D, + 0x000810, 0x20043A, 0x000282, 0x00020D, + 0x000810, 0x20043A, 0x001282, 0x200E82, + 0x00800D, 0x000810, 0x20043A, 0x001A82, + 0x03460D, 0x000810, 0x10043A, 0x02EC0D, + 0x000810, 0x18043A, 0x00010D, 0x020015, + 0x0000FD, 0x000020, 0x038860, 0x039060, + 0x038060, 0x038040, 0x038040, 0x038040, + 0x018040, 0x000A7D, 0x038040, 0x038040, + 0x018040, 0x200402, 0x000882, 0x08001A, + 0x000904, 0x017186, 0x000007, 0x260007, + 0x400007, 0x000007, 0x03258D, 0x000810, + 0x18043A, 0x260007, 0x284402, 0x00087D, + 0x018042, 0x00160A, 0x05A206, 0x000007, + 0x440007, 0x00230D, 0x000810, 0x08043A, + 0x22FA06, 0x000007, 0x0007FD, 0x018042, + 0x08000A, 0x000904, 0x02AB86, 0x000195, + 0x090D04, 0x000007, 0x000820, 0x0000F5, + 0x000B7D, 0x01F060, 0x0000FD, 0x033A06, + 0x018040, 0x000A7D, 0x038042, 0x13804A, + 0x18000A, 0x001820, 0x059060, 0x058860, + 0x018040, 0x0000FD, 0x018042, 0x70000A, + 0x000115, 0x071144, 0x033B86, 0x030000, + 0x007020, 0x036206, 0x018040, 0x00360D, + 0x000810, 0x08043A, 0x232206, 0x000007, + 0x02EC0D, 0x000810, 0x18043A, 0x019A06, + 0x000007, 0x240007, 0x000F8D, 0x000810, + 0x00163A, 0x002402, 0x005C02, 0x0028FD, + 0x000020, 0x018040, 0x08000D, 0x000815, + 0x510984, 0x000007, 0x00004D, 0x000E5D, + 0x000E02, 0x00430D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x00008D, 0x000924, + 0x000F02, 0x00470D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x480480, 0x001210, + 0x28043A, 0x00778D, 0x000810, 0x280C3A, + 0x00068D, 0x000810, 0x28143A, 0x284402, + 0x03258D, 0x000810, 0x18043A, 0x07FF8D, + 0x000820, 0x0002FD, 0x018040, 0x260007, + 0x200007, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x051286, 0x000007, 0x240007, + 0x02EC0D, 0x000810, 0x18043A, 0x00387D, + 0x018042, 0x08000A, 0x001015, 0x010984, + 0x019B86, 0x000007, 0x01B206, 0x000007, + 0x0008FD, 0x018042, 0x18000A, 0x001904, + 0x22B886, 0x280007, 0x001810, 0x28043A, + 0x280C02, 0x00000D, 0x000810, 0x28143A, + 0x08808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00020D, 0x189904, 0x000007, + 0x00402D, 0x0000BD, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x065A86, 0x000007, + 0x000100, 0x000A20, 0x00047D, 0x018040, + 0x018042, 0x20000A, 0x003015, 0x012144, + 0x036186, 0x000007, 0x002104, 0x036186, + 0x000007, 0x000F8D, 0x000810, 0x280C3A, + 0x023944, 0x07C986, 0x000007, 0x001810, + 0x28043A, 0x08810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x002810, 0x78003A, + 0x00788D, 0x000810, 0x08043A, 0x2A1206, + 0x000007, 0x00400D, 0x001015, 0x189904, + 0x292904, 0x393904, 0x000007, 0x070206, + 0x000007, 0x0004F5, 0x00007D, 0x000020, + 0x00008D, 0x010860, 0x018040, 0x00047D, + 0x038042, 0x21804A, 0x18000A, 0x021944, + 0x229086, 0x000007, 0x004075, 0x71F104, + 0x000007, 0x010042, 0x28000A, 0x002904, + 0x225886, 0x000007, 0x003C0D, 0x30A904, + 0x000007, 0x00077D, 0x018042, 0x08000A, + 0x000904, 0x08DA86, 0x00057D, 0x002820, + 0x03B060, 0x08F206, 0x018040, 0x003020, + 0x03A860, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x08FA86, 0x000007, + 0x00057D, 0x018042, 0x28040A, 0x000E8D, + 0x000810, 0x280C3A, 0x00000D, 0x000810, + 0x28143A, 0x09000D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x003DFD, 0x000020, + 0x018040, 0x00107D, 0x009D8D, 0x000810, + 0x08043A, 0x2A1206, 0x000007, 0x000815, + 0x08001A, 0x010984, 0x0A5186, 0x00137D, + 0x200500, 0x280F20, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x038A60, 0x018040, 0x00107D, 0x018042, + 0x08000A, 0x000215, 0x010984, 0x3A8186, + 0x000007, 0x007FBD, 0x383DC4, 0x000007, + 0x001A7D, 0x001375, 0x018042, 0x09004A, + 0x10000A, 0x0B8D04, 0x139504, 0x000007, + 0x000820, 0x019060, 0x001104, 0x225886, + 0x010040, 0x0017FD, 0x018042, 0x08000A, + 0x000904, 0x225A86, 0x000007, 0x00197D, + 0x038042, 0x09804A, 0x10000A, 0x000924, + 0x001664, 0x0011FD, 0x038042, 0x2B804A, + 0x19804A, 0x00008D, 0x218944, 0x000007, + 0x002244, 0x0C1986, 0x000007, 0x001A64, + 0x002A24, 0x00197D, 0x080102, 0x100122, + 0x000820, 0x039060, 0x018040, 0x003DFD, + 0x00008D, 0x000820, 0x018040, 0x001375, + 0x001A7D, 0x010042, 0x09804A, 0x10000A, + 0x00021D, 0x0189E4, 0x2992E4, 0x309144, + 0x000007, 0x00060D, 0x000A15, 0x000C1D, + 0x001025, 0x00A9E4, 0x012BE4, 0x000464, + 0x01B3E4, 0x0232E4, 0x000464, 0x000464, + 0x000464, 0x000464, 0x00040D, 0x08B1C4, + 0x000007, 0x000820, 0x000BF5, 0x030040, + 0x00197D, 0x038042, 0x09804A, 0x000A24, + 0x08000A, 0x080E64, 0x000007, 0x100122, + 0x000820, 0x031060, 0x010040, 0x0064AC, + 0x00027D, 0x000020, 0x018040, 0x00107D, + 0x018042, 0x0011FD, 0x3B804A, 0x09804A, + 0x20000A, 0x000095, 0x1A1144, 0x00A144, + 0x0E5886, 0x00040D, 0x00B984, 0x0E5986, + 0x0018FD, 0x018042, 0x0010FD, 0x09804A, + 0x28000A, 0x000095, 0x010924, 0x002A64, + 0x0E4986, 0x000007, 0x002904, 0x0E5A86, + 0x000007, 0x0E6206, 0x080002, 0x00008D, + 0x00387D, 0x000820, 0x018040, 0x00127D, + 0x018042, 0x10000A, 0x003904, 0x0F0986, + 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986, + 0x000025, 0x0FB206, 0x00002D, 0x000015, + 0x00082D, 0x02E00D, 0x000820, 0x0FFA06, + 0x00000D, 0x7F8035, 0x00B984, 0x0FA986, + 0x400025, 0x00008D, 0x110944, 0x000007, + 0x00018D, 0x109504, 0x000007, 0x009164, + 0x000424, 0x000424, 0x000424, 0x100102, + 0x280002, 0x02DF0D, 0x000820, 0x0FFA06, + 0x00018D, 0x00042D, 0x00008D, 0x109504, + 0x000007, 0x00020D, 0x109184, 0x000007, + 0x02DF8D, 0x000820, 0x00008D, 0x0038FD, + 0x018040, 0x003BFD, 0x001020, 0x03A860, + 0x000815, 0x313184, 0x212184, 0x000007, + 0x03B060, 0x03A060, 0x018040, 0x0022FD, + 0x000095, 0x010924, 0x000424, 0x000424, + 0x001264, 0x100102, 0x000820, 0x039060, + 0x018040, 0x001924, 0x010F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x000424, 0x000424, + 0x00117D, 0x018042, 0x08000A, 0x000A24, + 0x280502, 0x280C02, 0x09800D, 0x000820, + 0x0002FD, 0x018040, 0x200007, 0x0022FD, + 0x018042, 0x08000A, 0x000095, 0x280DC4, + 0x011924, 0x00197D, 0x018042, 0x0011FD, + 0x09804A, 0x10000A, 0x0000B5, 0x113144, + 0x0A8D04, 0x000007, 0x080A44, 0x129504, + 0x000007, 0x0023FD, 0x001020, 0x038040, + 0x101244, 0x000007, 0x000820, 0x039060, + 0x018040, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x123286, 0x000007, 0x003BFD, + 0x000100, 0x000A10, 0x0B807A, 0x13804A, + 0x090984, 0x000007, 0x000095, 0x013D04, + 0x12B886, 0x10000A, 0x100002, 0x090984, + 0x000007, 0x038042, 0x11804A, 0x090D04, + 0x000007, 0x10000A, 0x090D84, 0x000007, + 0x00257D, 0x000820, 0x018040, 0x00010D, + 0x000810, 0x28143A, 0x00127D, 0x018042, + 0x20000A, 0x00197D, 0x018042, 0x00117D, + 0x31804A, 0x10000A, 0x003124, 0x013B8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x300102, + 0x003124, 0x000424, 0x000424, 0x001224, + 0x280502, 0x001A4C, 0x143986, 0x700002, + 0x00002D, 0x030000, 0x00387D, 0x018042, + 0x10000A, 0x146206, 0x002124, 0x0000AD, + 0x100002, 0x00010D, 0x000924, 0x006B24, + 0x014A0D, 0x00397D, 0x000820, 0x058040, + 0x038042, 0x09844A, 0x000606, 0x08040A, + 0x003264, 0x00008D, 0x000A24, 0x001020, + 0x00227D, 0x018040, 0x014F8D, 0x000810, + 0x08043A, 0x2B5A06, 0x000007, 0x002820, + 0x00207D, 0x018040, 0x00117D, 0x038042, + 0x13804A, 0x33800A, 0x00387D, 0x018042, + 0x08000A, 0x000904, 0x177286, 0x000007, + 0x00008D, 0x030964, 0x015B0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x380102, 0x000424, + 0x000424, 0x001224, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x15DA86, 0x000007, + 0x280502, 0x001A4C, 0x177186, 0x000007, + 0x032164, 0x00632C, 0x003DFD, 0x018042, + 0x08000A, 0x000095, 0x090904, 0x000007, + 0x000820, 0x001A4C, 0x169986, 0x018040, + 0x030000, 0x16B206, 0x002124, 0x00010D, + 0x000924, 0x006B24, 0x016F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x003A64, 0x000095, + 0x001224, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x171286, 0x000007, 0x01760D, + 0x000810, 0x08043A, 0x2B5A06, 0x000007, + 0x160A06, 0x000007, 0x007020, 0x08010A, + 0x10012A, 0x0020FD, 0x038860, 0x039060, + 0x018040, 0x00227D, 0x018042, 0x003DFD, + 0x08000A, 0x31844A, 0x000904, 0x181086, + 0x18008B, 0x00008D, 0x189904, 0x00312C, + 0x18E206, 0x000007, 0x00324C, 0x186B86, + 0x000007, 0x001904, 0x186886, 0x000007, + 0x000095, 0x199144, 0x00222C, 0x003124, + 0x00636C, 0x000E3D, 0x001375, 0x000BFD, + 0x010042, 0x09804A, 0x10000A, 0x038AEC, + 0x0393EC, 0x00224C, 0x18E186, 0x000007, + 0x00008D, 0x189904, 0x00226C, 0x00322C, + 0x30050A, 0x301DAB, 0x002083, 0x0018FD, + 0x018042, 0x08000A, 0x018924, 0x300502, + 0x001083, 0x001875, 0x010042, 0x10000A, + 0x00008D, 0x010924, 0x001375, 0x330542, + 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB, + 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B, + 0x006083, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x19B286, 0x000007, 0x001E2D, + 0x0005FD, 0x018042, 0x08000A, 0x028924, + 0x280502, 0x00060D, 0x000810, 0x280C3A, + 0x00008D, 0x000810, 0x28143A, 0x0A808D, + 0x000820, 0x0002F5, 0x010040, 0x220007, + 0x001275, 0x030042, 0x21004A, 0x00008D, + 0x1A0944, 0x000007, 0x01AB8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0001F5, + 0x030042, 0x0D004A, 0x10000A, 0x089144, + 0x000007, 0x000820, 0x010040, 0x0025F5, + 0x0A3144, 0x000007, 0x000820, 0x032860, + 0x030040, 0x00217D, 0x038042, 0x0B804A, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00008D, 0x000124, 0x00012C, 0x000E64, + 0x001A64, 0x00636C, 0x08010A, 0x10012A, + 0x000820, 0x031060, 0x030040, 0x0020FD, + 0x018042, 0x08000A, 0x00227D, 0x018042, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00197D, 0x018042, 0x08000A, 0x0022FD, + 0x038042, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x090D04, 0x000007, 0x000820, + 0x030040, 0x038042, 0x0B804A, 0x10000A, + 0x000820, 0x031060, 0x030040, 0x038042, + 0x13804A, 0x19804A, 0x110D04, 0x198D04, + 0x000007, 0x08000A, 0x001020, 0x031860, + 0x030860, 0x030040, 0x00008D, 0x0B0944, + 0x000007, 0x000820, 0x010040, 0x0005F5, + 0x030042, 0x08000A, 0x000820, 0x010040, + 0x0000F5, 0x010042, 0x08000A, 0x000904, + 0x1D9886, 0x001E75, 0x030042, 0x01044A, + 0x000C0A, 0x1DAA06, 0x000007, 0x000402, + 0x000C02, 0x00177D, 0x001AF5, 0x018042, + 0x03144A, 0x031C4A, 0x03244A, 0x032C4A, + 0x03344A, 0x033C4A, 0x03444A, 0x004C0A, + 0x00043D, 0x0013F5, 0x001AFD, 0x030042, + 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, + 0x089144, 0x19A144, 0x0389E4, 0x0399EC, + 0x005502, 0x005D0A, 0x030042, 0x0B004A, + 0x1B804A, 0x13804A, 0x20000A, 0x089144, + 0x19A144, 0x0389E4, 0x0399EC, 0x006502, + 0x006D0A, 0x030042, 0x0B004A, 0x19004A, + 0x2B804A, 0x13804A, 0x21804A, 0x30000A, + 0x089144, 0x19A144, 0x2AB144, 0x0389E4, + 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4, + 0x000702, 0x00107D, 0x000415, 0x018042, + 0x08000A, 0x0109E4, 0x000F02, 0x002AF5, + 0x0019FD, 0x010042, 0x09804A, 0x10000A, + 0x000934, 0x001674, 0x0029F5, 0x010042, + 0x10000A, 0x00917C, 0x002075, 0x010042, + 0x08000A, 0x000904, 0x200A86, 0x0026F5, + 0x0027F5, 0x030042, 0x09004A, 0x10000A, + 0x000A3C, 0x00167C, 0x001A75, 0x000BFD, + 0x010042, 0x51804A, 0x48000A, 0x160007, + 0x001075, 0x010042, 0x282C0A, 0x281D12, + 0x282512, 0x001F32, 0x1E0007, 0x0E0007, + 0x001975, 0x010042, 0x002DF5, 0x0D004A, + 0x10000A, 0x009144, 0x20EA86, 0x010042, + 0x28340A, 0x000E5D, 0x00008D, 0x000375, + 0x000820, 0x010040, 0x05D2F4, 0x54D104, + 0x00735C, 0x218B86, 0x000007, 0x0C0007, + 0x080007, 0x0A0007, 0x02178D, 0x000810, + 0x08043A, 0x34B206, 0x000007, 0x219206, + 0x000007, 0x080007, 0x002275, 0x010042, + 0x20000A, 0x002104, 0x225886, 0x001E2D, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x21CA86, 0x000007, 0x002010, 0x30043A, + 0x00057D, 0x0180C3, 0x08000A, 0x028924, + 0x280502, 0x280C02, 0x0A810D, 0x000820, + 0x0002F5, 0x010040, 0x220007, 0x0004FD, + 0x018042, 0x70000A, 0x030000, 0x007020, + 0x07FA06, 0x018040, 0x022B8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x22C286, + 0x000007, 0x020206, 0x000007, 0x000875, + 0x0009FD, 0x00010D, 0x234206, 0x000295, + 0x000B75, 0x00097D, 0x00000D, 0x000515, + 0x010042, 0x18000A, 0x001904, 0x2A0086, + 0x0006F5, 0x001020, 0x010040, 0x0004F5, + 0x000820, 0x010040, 0x000775, 0x010042, + 0x09804A, 0x10000A, 0x001124, 0x000904, + 0x23F286, 0x000815, 0x080102, 0x101204, + 0x241206, 0x000575, 0x081204, 0x000007, + 0x100102, 0x000575, 0x000425, 0x021124, + 0x100102, 0x000820, 0x031060, 0x010040, + 0x001924, 0x2A0086, 0x00008D, 0x000464, + 0x009D04, 0x291086, 0x180102, 0x000575, + 0x010042, 0x28040A, 0x00018D, 0x000924, + 0x280D02, 0x00000D, 0x000924, 0x281502, + 0x10000D, 0x000820, 0x0002F5, 0x010040, + 0x200007, 0x001175, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x24FA86, 0x000007, + 0x000100, 0x080B20, 0x130B60, 0x1B0B60, + 0x030A60, 0x010040, 0x050042, 0x3D004A, + 0x35004A, 0x2D004A, 0x20000A, 0x0006F5, + 0x010042, 0x28140A, 0x0004F5, 0x010042, + 0x08000A, 0x000315, 0x010D04, 0x260286, + 0x004015, 0x000095, 0x010D04, 0x25F086, + 0x100022, 0x10002A, 0x261A06, 0x000007, + 0x333104, 0x2AA904, 0x000007, 0x032124, + 0x280502, 0x284402, 0x001124, 0x400102, + 0x000424, 0x000424, 0x003224, 0x00292C, + 0x00636C, 0x277386, 0x000007, 0x02B164, + 0x000464, 0x000464, 0x00008D, 0x000A64, + 0x280D02, 0x10008D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x00008D, 0x38B904, + 0x000007, 0x03296C, 0x30010A, 0x0002F5, + 0x010042, 0x08000A, 0x000904, 0x270286, + 0x000007, 0x00212C, 0x28050A, 0x00316C, + 0x00046C, 0x00046C, 0x28450A, 0x001124, + 0x006B64, 0x100102, 0x00008D, 0x01096C, + 0x280D0A, 0x10010D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x004124, 0x000424, + 0x000424, 0x003224, 0x300102, 0x032944, + 0x27FA86, 0x000007, 0x300002, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x284086, 0x003124, 0x000464, 0x300102, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x284A86, 0x000007, 0x284402, 0x003124, + 0x300502, 0x003924, 0x300583, 0x000883, + 0x0005F5, 0x010042, 0x28040A, 0x00008D, + 0x008124, 0x280D02, 0x00008D, 0x008124, + 0x281502, 0x10018D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x001025, 0x000575, + 0x030042, 0x09004A, 0x10000A, 0x0A0904, + 0x121104, 0x000007, 0x001020, 0x050860, + 0x050040, 0x0006FD, 0x018042, 0x09004A, + 0x10000A, 0x0000A5, 0x0A0904, 0x121104, + 0x000007, 0x000820, 0x019060, 0x010040, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x29CA86, 0x000007, 0x244206, 0x000007, + 0x000606, 0x000007, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x2A1A86, 0x000007, + 0x000100, 0x080B20, 0x138B60, 0x1B8B60, + 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60, + 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60, + 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60, + 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60, + 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60, + 0x038A60, 0x000606, 0x018040, 0x00008D, + 0x000A64, 0x280D02, 0x000A24, 0x00027D, + 0x018042, 0x10000A, 0x001224, 0x0003FD, + 0x018042, 0x08000A, 0x000904, 0x2C0A86, + 0x000007, 0x00018D, 0x000A24, 0x000464, + 0x000464, 0x080102, 0x000924, 0x000424, + 0x000424, 0x100102, 0x02000D, 0x009144, + 0x2C6186, 0x000007, 0x0001FD, 0x018042, + 0x08000A, 0x000A44, 0x2C4386, 0x018042, + 0x0A000D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00027D, 0x001020, 0x000606, + 0x018040, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x2CB286, 0x000007, 0x00037D, + 0x018042, 0x08000A, 0x000904, 0x2CE286, + 0x000007, 0x000075, 0x002E7D, 0x010042, + 0x0B804A, 0x000020, 0x000904, 0x000686, + 0x010040, 0x31844A, 0x30048B, 0x000883, + 0x00008D, 0x000810, 0x28143A, 0x00008D, + 0x000810, 0x280C3A, 0x000675, 0x010042, + 0x08000A, 0x003815, 0x010924, 0x280502, + 0x0B000D, 0x000820, 0x0002F5, 0x010040, + 0x000606, 0x220007, 0x000464, 0x000464, + 0x000606, 0x000007, 0x000134, 0x007F8D, + 0x00093C, 0x281D12, 0x282512, 0x001F32, + 0x0E0007, 0x00010D, 0x00037D, 0x000820, + 0x018040, 0x05D2F4, 0x000007, 0x080007, + 0x00037D, 0x018042, 0x08000A, 0x000904, + 0x2E8A86, 0x000007, 0x000606, 0x000007, + 0x000007, 0x000012, 0x100007, 0x320007, + 0x600007, 0x460007, 0x100080, 0x48001A, + 0x004904, 0x2EF186, 0x000007, 0x001210, + 0x58003A, 0x000145, 0x5C5D04, 0x000007, + 0x000080, 0x48001A, 0x004904, 0x2F4186, + 0x000007, 0x001210, 0x50003A, 0x005904, + 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5, + 0x7FFF7D, 0x07D524, 0x004224, 0x500102, + 0x200502, 0x000082, 0x40001A, 0x004104, + 0x2FC986, 0x000007, 0x003865, 0x40001A, + 0x004020, 0x00104D, 0x04C184, 0x31AB86, + 0x000040, 0x040007, 0x000165, 0x000145, + 0x004020, 0x000040, 0x000765, 0x080080, + 0x40001A, 0x004104, 0x305986, 0x000007, + 0x001210, 0x40003A, 0x004104, 0x30B286, + 0x00004D, 0x0000CD, 0x004810, 0x20043A, + 0x000882, 0x40001A, 0x004104, 0x30C186, + 0x000007, 0x004820, 0x005904, 0x319886, + 0x000040, 0x0007E5, 0x200480, 0x2816A0, + 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260, + 0x000040, 0x000032, 0x400075, 0x00007D, + 0x07D574, 0x200512, 0x000082, 0x40001A, + 0x004104, 0x317186, 0x000007, 0x038A06, + 0x640007, 0x0000E5, 0x000020, 0x000040, + 0x000A65, 0x000020, 0x020040, 0x020040, + 0x000040, 0x000165, 0x000042, 0x70000A, + 0x007104, 0x323286, 0x000007, 0x060007, + 0x019A06, 0x640007, 0x050000, 0x007020, + 0x000040, 0x038A06, 0x640007, 0x000007, + 0x00306D, 0x028860, 0x029060, 0x08000A, + 0x028860, 0x008040, 0x100012, 0x00100D, + 0x009184, 0x32D186, 0x000E0D, 0x009184, + 0x33E186, 0x000007, 0x300007, 0x001020, + 0x003B6D, 0x008040, 0x000080, 0x08001A, + 0x000904, 0x32F186, 0x000007, 0x001220, + 0x000DED, 0x008040, 0x008042, 0x10000A, + 0x40000D, 0x109544, 0x000007, 0x001020, + 0x000DED, 0x008040, 0x008042, 0x20040A, + 0x000082, 0x08001A, 0x000904, 0x338186, + 0x000007, 0x003B6D, 0x008042, 0x08000A, + 0x000E15, 0x010984, 0x342B86, 0x600007, + 0x08001A, 0x000C15, 0x010984, 0x341386, + 0x000020, 0x1A0007, 0x0002ED, 0x008040, + 0x620007, 0x00306D, 0x028042, 0x0A804A, + 0x000820, 0x0A804A, 0x000606, 0x10804A, + 0x000007, 0x282512, 0x001F32, 0x05D2F4, + 0x54D104, 0x00735C, 0x000786, 0x000007, + 0x0C0007, 0x0A0007, 0x1C0007, 0x003465, + 0x020040, 0x004820, 0x025060, 0x40000A, + 0x024060, 0x000040, 0x454944, 0x000007, + 0x004020, 0x003AE5, 0x000040, 0x0028E5, + 0x000042, 0x48000A, 0x004904, 0x39F886, + 0x002C65, 0x000042, 0x40000A, 0x0000D5, + 0x454104, 0x000007, 0x000655, 0x054504, + 0x368286, 0x0001D5, 0x054504, 0x368086, + 0x002B65, 0x000042, 0x003AE5, 0x50004A, + 0x40000A, 0x45C3D4, 0x000007, 0x454504, + 0x000007, 0x0000CD, 0x444944, 0x000007, + 0x454504, 0x000007, 0x00014D, 0x554944, + 0x000007, 0x045144, 0x367986, 0x002C65, + 0x000042, 0x48000A, 0x4CD104, 0x000007, + 0x04C144, 0x368386, 0x000007, 0x160007, + 0x002CE5, 0x040042, 0x40000A, 0x004020, + 0x000040, 0x002965, 0x000042, 0x40000A, + 0x004104, 0x36F086, 0x000007, 0x002402, + 0x383206, 0x005C02, 0x0025E5, 0x000042, + 0x40000A, 0x004274, 0x002AE5, 0x000042, + 0x40000A, 0x004274, 0x500112, 0x0029E5, + 0x000042, 0x40000A, 0x004234, 0x454104, + 0x000007, 0x004020, 0x000040, 0x003EE5, + 0x000020, 0x000040, 0x002DE5, 0x400152, + 0x50000A, 0x045144, 0x37DA86, 0x0000C5, + 0x003EE5, 0x004020, 0x000040, 0x002BE5, + 0x000042, 0x40000A, 0x404254, 0x000007, + 0x002AE5, 0x004020, 0x000040, 0x500132, + 0x040134, 0x005674, 0x0029E5, 0x020042, + 0x42000A, 0x000042, 0x50000A, 0x05417C, + 0x0028E5, 0x000042, 0x48000A, 0x0000C5, + 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5, + 0x020042, 0x40004A, 0x50000A, 0x00423C, + 0x00567C, 0x0028E5, 0x004820, 0x000040, + 0x281D12, 0x282512, 0x001F72, 0x002965, + 0x000042, 0x40000A, 0x004104, 0x393A86, + 0x0E0007, 0x160007, 0x1E0007, 0x003EE5, + 0x000042, 0x40000A, 0x004104, 0x397886, + 0x002D65, 0x000042, 0x28340A, 0x003465, + 0x020042, 0x42004A, 0x004020, 0x4A004A, + 0x50004A, 0x05D2F4, 0x54D104, 0x00735C, + 0x39E186, 0x000007, 0x000606, 0x080007, + 0x0C0007, 0x080007, 0x0A0007, 0x0001E5, + 0x020045, 0x004020, 0x000060, 0x000365, + 0x000040, 0x002E65, 0x001A20, 0x0A1A60, + 0x000040, 0x003465, 0x020042, 0x42004A, + 0x004020, 0x4A004A, 0x000606, 0x50004A, + 0x0017FD, 0x018042, 0x08000A, 0x000904, + 0x225A86, 0x000007, 0x00107D, 0x018042, + 0x0011FD, 0x33804A, 0x19804A, 0x20000A, + 0x000095, 0x2A1144, 0x01A144, 0x3B9086, + 0x00040D, 0x00B184, 0x3B9186, 0x0018FD, + 0x018042, 0x0010FD, 0x09804A, 0x38000A, + 0x000095, 0x010924, 0x003A64, 0x3B8186, + 0x000007, 0x003904, 0x3B9286, 0x000007, + 0x3B9A06, 0x00000D, 0x00008D, 0x000820, + 0x00387D, 0x018040, 0x700002, 0x00117D, + 0x018042, 0x00197D, 0x29804A, 0x30000A, + 0x380002, 0x003124, 0x000424, 0x000424, + 0x002A24, 0x280502, 0x00068D, 0x000810, + 0x28143A, 0x00750D, 0x00B124, 0x002264, + 0x3D0386, 0x284402, 0x000810, 0x280C3A, + 0x0B800D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00758D, 0x00B124, 0x100102, + 0x012144, 0x3E4986, 0x001810, 0x10003A, + 0x00387D, 0x018042, 0x08000A, 0x000904, + 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD, + 0x00008D, 0x023164, 0x000A64, 0x280D02, + 0x0B808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00387D, 0x018042, 0x08000A, + 0x000904, 0x3E3286, 0x030000, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x3D8286, + 0x000007, 0x002810, 0x28043A, 0x00750D, + 0x030924, 0x002264, 0x280D02, 0x02316C, + 0x28450A, 0x0B810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x00008D, 0x000A24, + 0x3E4A06, 0x100102, 0x001810, 0x10003A, + 0x0000BD, 0x003810, 0x30043A, 0x00187D, + 0x018042, 0x0018FD, 0x09804A, 0x20000A, + 0x0000AD, 0x028924, 0x07212C, 0x001010, + 0x300583, 0x300D8B, 0x3014BB, 0x301C83, + 0x002083, 0x00137D, 0x038042, 0x33844A, + 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB, + 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083, + 0x001E0D, 0x0005FD, 0x018042, 0x20000A, + 0x020924, 0x00068D, 0x00A96C, 0x00009D, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x3F6A86, 0x000007, 0x280502, 0x280D0A, + 0x284402, 0x001810, 0x28143A, 0x0C008D, + 0x000820, 0x0002FD, 0x018040, 0x220007, + 0x003904, 0x225886, 0x001E0D, 0x00057D, + 0x018042, 0x20000A, 0x020924, 0x0000A5, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x402A86, 0x000007, 0x280502, 0x280C02, + 0x002010, 0x28143A, 0x0C010D, 0x000820, + 0x0002FD, 0x018040, 0x225A06, 0x220007, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000 +}; + +#endif //_HWMCODE_ + + 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 Sun Jun 4 21:51:41 2000 @@ -27,7 +27,7 @@ dep_tristate ' SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND fi -dep_tristate ' Trident 4DWave DX/NX or SiS 7018 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND +dep_tristate ' Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND dep_tristate ' Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND if [ "$CONFIG_SOUND_MSNDCLAS" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "m" ]; then @@ -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 @@ -149,6 +149,7 @@ dep_tristate ' Yamaha FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS dep_tristate ' Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS dep_tristate ' Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS + dep_tristate ' Yamaha PCI legacy mode support' CONFIG_SOUND_YMPCI $CONFIG_SOUND_OSS $CONFIG_PCI dep_tristate ' 6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS dep_tristate ' Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_SOUND_AEDSP16 $CONFIG_SOUND_OSS @@ -181,3 +182,4 @@ fi +dep_tristate ' TV card (bt848) mixer support' CONFIG_SOUND_TVMIXER $CONFIG_SOUND CONFIG_I2C diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/Hwmcode.h linux.ac/drivers/sound/Hwmcode.h --- linux.vanilla/drivers/sound/Hwmcode.h Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/sound/Hwmcode.h Wed May 31 11:15:34 2000 @@ -0,0 +1,804 @@ +//============================================================================= +// Copyright (c) 1997 Yamaha Corporation. All Rights Reserved. +// +// Title: +// hwmcode.c +// Desc: +// micro-code for CTRL & DSP +// HISTORY: +// April 03, 1997: 1st try by M. Mukojima +//============================================================================= +#define YDSXG_DSPLENGTH 0x0080 +#define YDSXG_CTRLLENGTH 0x3000 + + +static unsigned long int gdwDSPCode[YDSXG_DSPLENGTH >> 2] = { + 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, + 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, + 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, + 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + + +// -------------------------------------------- +// DS-1E Controller InstructionRAM Code +// 1999/06/21 +// Buf441 slot is Enabled. +// -------------------------------------------- +// 04/09?@creat +// 04/12 stop nise fix +// 06/21?@WorkingOff timming +static unsigned long gdwCtrl1eCode[YDSXG_CTRLLENGTH >> 2] = { + 0x000007, 0x240007, 0x0C0007, 0x1C0007, + 0x060007, 0x700002, 0x000020, 0x030040, + 0x007104, 0x004286, 0x030040, 0x000F0D, + 0x000810, 0x20043A, 0x000282, 0x00020D, + 0x000810, 0x20043A, 0x001282, 0x200E82, + 0x00800D, 0x000810, 0x20043A, 0x001A82, + 0x03460D, 0x000810, 0x10043A, 0x02EC0D, + 0x000810, 0x18043A, 0x00010D, 0x020015, + 0x0000FD, 0x000020, 0x038860, 0x039060, + 0x038060, 0x038040, 0x038040, 0x038040, + 0x018040, 0x000A7D, 0x038040, 0x038040, + 0x018040, 0x200402, 0x000882, 0x08001A, + 0x000904, 0x017186, 0x000007, 0x260007, + 0x400007, 0x000007, 0x03258D, 0x000810, + 0x18043A, 0x260007, 0x284402, 0x00087D, + 0x018042, 0x00160A, 0x05A206, 0x000007, + 0x440007, 0x00230D, 0x000810, 0x08043A, + 0x22FA06, 0x000007, 0x0007FD, 0x018042, + 0x08000A, 0x000904, 0x02AB86, 0x000195, + 0x090D04, 0x000007, 0x000820, 0x0000F5, + 0x000B7D, 0x01F060, 0x0000FD, 0x033A06, + 0x018040, 0x000A7D, 0x038042, 0x13804A, + 0x18000A, 0x001820, 0x059060, 0x058860, + 0x018040, 0x0000FD, 0x018042, 0x70000A, + 0x000115, 0x071144, 0x033B86, 0x030000, + 0x007020, 0x036206, 0x018040, 0x00360D, + 0x000810, 0x08043A, 0x232206, 0x000007, + 0x02EC0D, 0x000810, 0x18043A, 0x019A06, + 0x000007, 0x240007, 0x000F8D, 0x000810, + 0x00163A, 0x002402, 0x005C02, 0x0028FD, + 0x000020, 0x018040, 0x08000D, 0x000815, + 0x510984, 0x000007, 0x00004D, 0x000E5D, + 0x000E02, 0x00430D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x00008D, 0x000924, + 0x000F02, 0x00470D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x480480, 0x001210, + 0x28043A, 0x00778D, 0x000810, 0x280C3A, + 0x00068D, 0x000810, 0x28143A, 0x284402, + 0x03258D, 0x000810, 0x18043A, 0x07FF8D, + 0x000820, 0x0002FD, 0x018040, 0x260007, + 0x200007, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x051286, 0x000007, 0x240007, + 0x02EC0D, 0x000810, 0x18043A, 0x00387D, + 0x018042, 0x08000A, 0x001015, 0x010984, + 0x019B86, 0x000007, 0x01B206, 0x000007, + 0x0008FD, 0x018042, 0x18000A, 0x001904, + 0x22B886, 0x280007, 0x001810, 0x28043A, + 0x280C02, 0x00000D, 0x000810, 0x28143A, + 0x08808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00020D, 0x189904, 0x000007, + 0x00402D, 0x0000BD, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x065A86, 0x000007, + 0x000100, 0x000A20, 0x00047D, 0x018040, + 0x018042, 0x20000A, 0x003015, 0x012144, + 0x036186, 0x000007, 0x002104, 0x036186, + 0x000007, 0x000F8D, 0x000810, 0x280C3A, + 0x023944, 0x07C986, 0x000007, 0x001810, + 0x28043A, 0x08810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x002810, 0x78003A, + 0x00788D, 0x000810, 0x08043A, 0x2A1206, + 0x000007, 0x00400D, 0x001015, 0x189904, + 0x292904, 0x393904, 0x000007, 0x070206, + 0x000007, 0x0004F5, 0x00007D, 0x000020, + 0x00008D, 0x010860, 0x018040, 0x00047D, + 0x038042, 0x21804A, 0x18000A, 0x021944, + 0x229086, 0x000007, 0x004075, 0x71F104, + 0x000007, 0x010042, 0x28000A, 0x002904, + 0x225886, 0x000007, 0x003C0D, 0x30A904, + 0x000007, 0x00077D, 0x018042, 0x08000A, + 0x000904, 0x08DA86, 0x00057D, 0x002820, + 0x03B060, 0x08F206, 0x018040, 0x003020, + 0x03A860, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x08FA86, 0x000007, + 0x00057D, 0x018042, 0x28040A, 0x000E8D, + 0x000810, 0x280C3A, 0x00000D, 0x000810, + 0x28143A, 0x09000D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x003DFD, 0x000020, + 0x018040, 0x00107D, 0x009D8D, 0x000810, + 0x08043A, 0x2A1206, 0x000007, 0x000815, + 0x08001A, 0x010984, 0x0A5186, 0x00137D, + 0x200500, 0x280F20, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x038A60, 0x018040, 0x00107D, 0x018042, + 0x08000A, 0x000215, 0x010984, 0x3A8186, + 0x000007, 0x007FBD, 0x383DC4, 0x000007, + 0x001A7D, 0x001375, 0x018042, 0x09004A, + 0x10000A, 0x0B8D04, 0x139504, 0x000007, + 0x000820, 0x019060, 0x001104, 0x225886, + 0x010040, 0x0017FD, 0x018042, 0x08000A, + 0x000904, 0x225A86, 0x000007, 0x00197D, + 0x038042, 0x09804A, 0x10000A, 0x000924, + 0x001664, 0x0011FD, 0x038042, 0x2B804A, + 0x19804A, 0x00008D, 0x218944, 0x000007, + 0x002244, 0x0C1986, 0x000007, 0x001A64, + 0x002A24, 0x00197D, 0x080102, 0x100122, + 0x000820, 0x039060, 0x018040, 0x003DFD, + 0x00008D, 0x000820, 0x018040, 0x001375, + 0x001A7D, 0x010042, 0x09804A, 0x10000A, + 0x00021D, 0x0189E4, 0x2992E4, 0x309144, + 0x000007, 0x00060D, 0x000A15, 0x000C1D, + 0x001025, 0x00A9E4, 0x012BE4, 0x000464, + 0x01B3E4, 0x0232E4, 0x000464, 0x000464, + 0x000464, 0x000464, 0x00040D, 0x08B1C4, + 0x000007, 0x000820, 0x000BF5, 0x030040, + 0x00197D, 0x038042, 0x09804A, 0x000A24, + 0x08000A, 0x080E64, 0x000007, 0x100122, + 0x000820, 0x031060, 0x010040, 0x0064AC, + 0x00027D, 0x000020, 0x018040, 0x00107D, + 0x018042, 0x0011FD, 0x3B804A, 0x09804A, + 0x20000A, 0x000095, 0x1A1144, 0x00A144, + 0x0E5886, 0x00040D, 0x00B984, 0x0E5986, + 0x0018FD, 0x018042, 0x0010FD, 0x09804A, + 0x28000A, 0x000095, 0x010924, 0x002A64, + 0x0E4986, 0x000007, 0x002904, 0x0E5A86, + 0x000007, 0x0E6206, 0x080002, 0x00008D, + 0x00387D, 0x000820, 0x018040, 0x00127D, + 0x018042, 0x10000A, 0x003904, 0x0F0986, + 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986, + 0x000025, 0x0FB206, 0x00002D, 0x000015, + 0x00082D, 0x02E00D, 0x000820, 0x0FFA06, + 0x00000D, 0x7F8035, 0x00B984, 0x0FA986, + 0x400025, 0x00008D, 0x110944, 0x000007, + 0x00018D, 0x109504, 0x000007, 0x009164, + 0x000424, 0x000424, 0x000424, 0x100102, + 0x280002, 0x02DF0D, 0x000820, 0x0FFA06, + 0x00018D, 0x00042D, 0x00008D, 0x109504, + 0x000007, 0x00020D, 0x109184, 0x000007, + 0x02DF8D, 0x000820, 0x00008D, 0x0038FD, + 0x018040, 0x003BFD, 0x001020, 0x03A860, + 0x000815, 0x313184, 0x212184, 0x000007, + 0x03B060, 0x03A060, 0x018040, 0x0022FD, + 0x000095, 0x010924, 0x000424, 0x000424, + 0x001264, 0x100102, 0x000820, 0x039060, + 0x018040, 0x001924, 0x010F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x000424, 0x000424, + 0x00117D, 0x018042, 0x08000A, 0x000A24, + 0x280502, 0x280C02, 0x09800D, 0x000820, + 0x0002FD, 0x018040, 0x200007, 0x0022FD, + 0x018042, 0x08000A, 0x000095, 0x280DC4, + 0x011924, 0x00197D, 0x018042, 0x0011FD, + 0x09804A, 0x10000A, 0x0000B5, 0x113144, + 0x0A8D04, 0x000007, 0x080A44, 0x129504, + 0x000007, 0x0023FD, 0x001020, 0x038040, + 0x101244, 0x000007, 0x000820, 0x039060, + 0x018040, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x123286, 0x000007, 0x003BFD, + 0x000100, 0x000A10, 0x0B807A, 0x13804A, + 0x090984, 0x000007, 0x000095, 0x013D04, + 0x12B886, 0x10000A, 0x100002, 0x090984, + 0x000007, 0x038042, 0x11804A, 0x090D04, + 0x000007, 0x10000A, 0x090D84, 0x000007, + 0x00257D, 0x000820, 0x018040, 0x00010D, + 0x000810, 0x28143A, 0x00127D, 0x018042, + 0x20000A, 0x00197D, 0x018042, 0x00117D, + 0x31804A, 0x10000A, 0x003124, 0x013B8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x300102, + 0x003124, 0x000424, 0x000424, 0x001224, + 0x280502, 0x001A4C, 0x143986, 0x700002, + 0x00002D, 0x030000, 0x00387D, 0x018042, + 0x10000A, 0x146206, 0x002124, 0x0000AD, + 0x100002, 0x00010D, 0x000924, 0x006B24, + 0x014A0D, 0x00397D, 0x000820, 0x058040, + 0x038042, 0x09844A, 0x000606, 0x08040A, + 0x003264, 0x00008D, 0x000A24, 0x001020, + 0x00227D, 0x018040, 0x014F8D, 0x000810, + 0x08043A, 0x2B5A06, 0x000007, 0x002820, + 0x00207D, 0x018040, 0x00117D, 0x038042, + 0x13804A, 0x33800A, 0x00387D, 0x018042, + 0x08000A, 0x000904, 0x177286, 0x000007, + 0x00008D, 0x030964, 0x015B0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x380102, 0x000424, + 0x000424, 0x001224, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x15DA86, 0x000007, + 0x280502, 0x001A4C, 0x177186, 0x000007, + 0x032164, 0x00632C, 0x003DFD, 0x018042, + 0x08000A, 0x000095, 0x090904, 0x000007, + 0x000820, 0x001A4C, 0x169986, 0x018040, + 0x030000, 0x16B206, 0x002124, 0x00010D, + 0x000924, 0x006B24, 0x016F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x003A64, 0x000095, + 0x001224, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x171286, 0x000007, 0x01760D, + 0x000810, 0x08043A, 0x2B5A06, 0x000007, + 0x160A06, 0x000007, 0x007020, 0x08010A, + 0x10012A, 0x0020FD, 0x038860, 0x039060, + 0x018040, 0x00227D, 0x018042, 0x003DFD, + 0x08000A, 0x31844A, 0x000904, 0x181086, + 0x18008B, 0x00008D, 0x189904, 0x00312C, + 0x18E206, 0x000007, 0x00324C, 0x186B86, + 0x000007, 0x001904, 0x186886, 0x000007, + 0x000095, 0x199144, 0x00222C, 0x003124, + 0x00636C, 0x000E3D, 0x001375, 0x000BFD, + 0x010042, 0x09804A, 0x10000A, 0x038AEC, + 0x0393EC, 0x00224C, 0x18E186, 0x000007, + 0x00008D, 0x189904, 0x00226C, 0x00322C, + 0x30050A, 0x301DAB, 0x002083, 0x0018FD, + 0x018042, 0x08000A, 0x018924, 0x300502, + 0x001083, 0x001875, 0x010042, 0x10000A, + 0x00008D, 0x010924, 0x001375, 0x330542, + 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB, + 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B, + 0x006083, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x19B286, 0x000007, 0x001E2D, + 0x0005FD, 0x018042, 0x08000A, 0x028924, + 0x280502, 0x00060D, 0x000810, 0x280C3A, + 0x00008D, 0x000810, 0x28143A, 0x0A808D, + 0x000820, 0x0002F5, 0x010040, 0x220007, + 0x001275, 0x030042, 0x21004A, 0x00008D, + 0x1A0944, 0x000007, 0x01AB8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0001F5, + 0x030042, 0x0D004A, 0x10000A, 0x089144, + 0x000007, 0x000820, 0x010040, 0x0025F5, + 0x0A3144, 0x000007, 0x000820, 0x032860, + 0x030040, 0x00217D, 0x038042, 0x0B804A, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00008D, 0x000124, 0x00012C, 0x000E64, + 0x001A64, 0x00636C, 0x08010A, 0x10012A, + 0x000820, 0x031060, 0x030040, 0x0020FD, + 0x018042, 0x08000A, 0x00227D, 0x018042, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00197D, 0x018042, 0x08000A, 0x0022FD, + 0x038042, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x090D04, 0x000007, 0x000820, + 0x030040, 0x038042, 0x0B804A, 0x10000A, + 0x000820, 0x031060, 0x030040, 0x038042, + 0x13804A, 0x19804A, 0x110D04, 0x198D04, + 0x000007, 0x08000A, 0x001020, 0x031860, + 0x030860, 0x030040, 0x00008D, 0x0B0944, + 0x000007, 0x000820, 0x010040, 0x0005F5, + 0x030042, 0x08000A, 0x000820, 0x010040, + 0x0000F5, 0x010042, 0x08000A, 0x000904, + 0x1D9886, 0x001E75, 0x030042, 0x01044A, + 0x000C0A, 0x1DAA06, 0x000007, 0x000402, + 0x000C02, 0x00177D, 0x001AF5, 0x018042, + 0x03144A, 0x031C4A, 0x03244A, 0x032C4A, + 0x03344A, 0x033C4A, 0x03444A, 0x004C0A, + 0x00043D, 0x0013F5, 0x001AFD, 0x030042, + 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, + 0x089144, 0x19A144, 0x0389E4, 0x0399EC, + 0x005502, 0x005D0A, 0x030042, 0x0B004A, + 0x1B804A, 0x13804A, 0x20000A, 0x089144, + 0x19A144, 0x0389E4, 0x0399EC, 0x006502, + 0x006D0A, 0x030042, 0x0B004A, 0x19004A, + 0x2B804A, 0x13804A, 0x21804A, 0x30000A, + 0x089144, 0x19A144, 0x2AB144, 0x0389E4, + 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4, + 0x000702, 0x00107D, 0x000415, 0x018042, + 0x08000A, 0x0109E4, 0x000F02, 0x002AF5, + 0x0019FD, 0x010042, 0x09804A, 0x10000A, + 0x000934, 0x001674, 0x0029F5, 0x010042, + 0x10000A, 0x00917C, 0x002075, 0x010042, + 0x08000A, 0x000904, 0x200A86, 0x0026F5, + 0x0027F5, 0x030042, 0x09004A, 0x10000A, + 0x000A3C, 0x00167C, 0x001A75, 0x000BFD, + 0x010042, 0x51804A, 0x48000A, 0x160007, + 0x001075, 0x010042, 0x282C0A, 0x281D12, + 0x282512, 0x001F32, 0x1E0007, 0x0E0007, + 0x001975, 0x010042, 0x002DF5, 0x0D004A, + 0x10000A, 0x009144, 0x20EA86, 0x010042, + 0x28340A, 0x000E5D, 0x00008D, 0x000375, + 0x000820, 0x010040, 0x05D2F4, 0x54D104, + 0x00735C, 0x218B86, 0x000007, 0x0C0007, + 0x080007, 0x0A0007, 0x02178D, 0x000810, + 0x08043A, 0x34B206, 0x000007, 0x219206, + 0x000007, 0x080007, 0x002275, 0x010042, + 0x20000A, 0x002104, 0x225886, 0x001E2D, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x21CA86, 0x000007, 0x002010, 0x30043A, + 0x00057D, 0x0180C3, 0x08000A, 0x028924, + 0x280502, 0x280C02, 0x0A810D, 0x000820, + 0x0002F5, 0x010040, 0x220007, 0x0004FD, + 0x018042, 0x70000A, 0x030000, 0x007020, + 0x07FA06, 0x018040, 0x022B8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x22C286, + 0x000007, 0x020206, 0x000007, 0x000875, + 0x0009FD, 0x00010D, 0x234206, 0x000295, + 0x000B75, 0x00097D, 0x00000D, 0x000515, + 0x010042, 0x18000A, 0x001904, 0x2A0086, + 0x0006F5, 0x001020, 0x010040, 0x0004F5, + 0x000820, 0x010040, 0x000775, 0x010042, + 0x09804A, 0x10000A, 0x001124, 0x000904, + 0x23F286, 0x000815, 0x080102, 0x101204, + 0x241206, 0x000575, 0x081204, 0x000007, + 0x100102, 0x000575, 0x000425, 0x021124, + 0x100102, 0x000820, 0x031060, 0x010040, + 0x001924, 0x2A0086, 0x00008D, 0x000464, + 0x009D04, 0x291086, 0x180102, 0x000575, + 0x010042, 0x28040A, 0x00018D, 0x000924, + 0x280D02, 0x00000D, 0x000924, 0x281502, + 0x10000D, 0x000820, 0x0002F5, 0x010040, + 0x200007, 0x001175, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x24FA86, 0x000007, + 0x000100, 0x080B20, 0x130B60, 0x1B0B60, + 0x030A60, 0x010040, 0x050042, 0x3D004A, + 0x35004A, 0x2D004A, 0x20000A, 0x0006F5, + 0x010042, 0x28140A, 0x0004F5, 0x010042, + 0x08000A, 0x000315, 0x010D04, 0x260286, + 0x004015, 0x000095, 0x010D04, 0x25F086, + 0x100022, 0x10002A, 0x261A06, 0x000007, + 0x333104, 0x2AA904, 0x000007, 0x032124, + 0x280502, 0x284402, 0x001124, 0x400102, + 0x000424, 0x000424, 0x003224, 0x00292C, + 0x00636C, 0x277386, 0x000007, 0x02B164, + 0x000464, 0x000464, 0x00008D, 0x000A64, + 0x280D02, 0x10008D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x00008D, 0x38B904, + 0x000007, 0x03296C, 0x30010A, 0x0002F5, + 0x010042, 0x08000A, 0x000904, 0x270286, + 0x000007, 0x00212C, 0x28050A, 0x00316C, + 0x00046C, 0x00046C, 0x28450A, 0x001124, + 0x006B64, 0x100102, 0x00008D, 0x01096C, + 0x280D0A, 0x10010D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x004124, 0x000424, + 0x000424, 0x003224, 0x300102, 0x032944, + 0x27FA86, 0x000007, 0x300002, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x284086, 0x003124, 0x000464, 0x300102, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x284A86, 0x000007, 0x284402, 0x003124, + 0x300502, 0x003924, 0x300583, 0x000883, + 0x0005F5, 0x010042, 0x28040A, 0x00008D, + 0x008124, 0x280D02, 0x00008D, 0x008124, + 0x281502, 0x10018D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x001025, 0x000575, + 0x030042, 0x09004A, 0x10000A, 0x0A0904, + 0x121104, 0x000007, 0x001020, 0x050860, + 0x050040, 0x0006FD, 0x018042, 0x09004A, + 0x10000A, 0x0000A5, 0x0A0904, 0x121104, + 0x000007, 0x000820, 0x019060, 0x010040, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x29CA86, 0x000007, 0x244206, 0x000007, + 0x000606, 0x000007, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x2A1A86, 0x000007, + 0x000100, 0x080B20, 0x138B60, 0x1B8B60, + 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60, + 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60, + 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60, + 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60, + 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60, + 0x038A60, 0x000606, 0x018040, 0x00008D, + 0x000A64, 0x280D02, 0x000A24, 0x00027D, + 0x018042, 0x10000A, 0x001224, 0x0003FD, + 0x018042, 0x08000A, 0x000904, 0x2C0A86, + 0x000007, 0x00018D, 0x000A24, 0x000464, + 0x000464, 0x080102, 0x000924, 0x000424, + 0x000424, 0x100102, 0x02000D, 0x009144, + 0x2C6186, 0x000007, 0x0001FD, 0x018042, + 0x08000A, 0x000A44, 0x2C4386, 0x018042, + 0x0A000D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00027D, 0x001020, 0x000606, + 0x018040, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x2CB286, 0x000007, 0x00037D, + 0x018042, 0x08000A, 0x000904, 0x2CE286, + 0x000007, 0x000075, 0x002E7D, 0x010042, + 0x0B804A, 0x000020, 0x000904, 0x000686, + 0x010040, 0x31844A, 0x30048B, 0x000883, + 0x00008D, 0x000810, 0x28143A, 0x00008D, + 0x000810, 0x280C3A, 0x000675, 0x010042, + 0x08000A, 0x003815, 0x010924, 0x280502, + 0x0B000D, 0x000820, 0x0002F5, 0x010040, + 0x000606, 0x220007, 0x000464, 0x000464, + 0x000606, 0x000007, 0x000134, 0x007F8D, + 0x00093C, 0x281D12, 0x282512, 0x001F32, + 0x0E0007, 0x00010D, 0x00037D, 0x000820, + 0x018040, 0x05D2F4, 0x000007, 0x080007, + 0x00037D, 0x018042, 0x08000A, 0x000904, + 0x2E8A86, 0x000007, 0x000606, 0x000007, + 0x000007, 0x000012, 0x100007, 0x320007, + 0x600007, 0x460007, 0x100080, 0x48001A, + 0x004904, 0x2EF186, 0x000007, 0x001210, + 0x58003A, 0x000145, 0x5C5D04, 0x000007, + 0x000080, 0x48001A, 0x004904, 0x2F4186, + 0x000007, 0x001210, 0x50003A, 0x005904, + 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5, + 0x7FFF7D, 0x07D524, 0x004224, 0x500102, + 0x200502, 0x000082, 0x40001A, 0x004104, + 0x2FC986, 0x000007, 0x003865, 0x40001A, + 0x004020, 0x00104D, 0x04C184, 0x31AB86, + 0x000040, 0x040007, 0x000165, 0x000145, + 0x004020, 0x000040, 0x000765, 0x080080, + 0x40001A, 0x004104, 0x305986, 0x000007, + 0x001210, 0x40003A, 0x004104, 0x30B286, + 0x00004D, 0x0000CD, 0x004810, 0x20043A, + 0x000882, 0x40001A, 0x004104, 0x30C186, + 0x000007, 0x004820, 0x005904, 0x319886, + 0x000040, 0x0007E5, 0x200480, 0x2816A0, + 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260, + 0x000040, 0x000032, 0x400075, 0x00007D, + 0x07D574, 0x200512, 0x000082, 0x40001A, + 0x004104, 0x317186, 0x000007, 0x038A06, + 0x640007, 0x0000E5, 0x000020, 0x000040, + 0x000A65, 0x000020, 0x020040, 0x020040, + 0x000040, 0x000165, 0x000042, 0x70000A, + 0x007104, 0x323286, 0x000007, 0x060007, + 0x019A06, 0x640007, 0x050000, 0x007020, + 0x000040, 0x038A06, 0x640007, 0x000007, + 0x00306D, 0x028860, 0x029060, 0x08000A, + 0x028860, 0x008040, 0x100012, 0x00100D, + 0x009184, 0x32D186, 0x000E0D, 0x009184, + 0x33E186, 0x000007, 0x300007, 0x001020, + 0x003B6D, 0x008040, 0x000080, 0x08001A, + 0x000904, 0x32F186, 0x000007, 0x001220, + 0x000DED, 0x008040, 0x008042, 0x10000A, + 0x40000D, 0x109544, 0x000007, 0x001020, + 0x000DED, 0x008040, 0x008042, 0x20040A, + 0x000082, 0x08001A, 0x000904, 0x338186, + 0x000007, 0x003B6D, 0x008042, 0x08000A, + 0x000E15, 0x010984, 0x342B86, 0x600007, + 0x08001A, 0x000C15, 0x010984, 0x341386, + 0x000020, 0x1A0007, 0x0002ED, 0x008040, + 0x620007, 0x00306D, 0x028042, 0x0A804A, + 0x000820, 0x0A804A, 0x000606, 0x10804A, + 0x000007, 0x282512, 0x001F32, 0x05D2F4, + 0x54D104, 0x00735C, 0x000786, 0x000007, + 0x0C0007, 0x0A0007, 0x1C0007, 0x003465, + 0x020040, 0x004820, 0x025060, 0x40000A, + 0x024060, 0x000040, 0x454944, 0x000007, + 0x004020, 0x003AE5, 0x000040, 0x0028E5, + 0x000042, 0x48000A, 0x004904, 0x39F886, + 0x002C65, 0x000042, 0x40000A, 0x0000D5, + 0x454104, 0x000007, 0x000655, 0x054504, + 0x368286, 0x0001D5, 0x054504, 0x368086, + 0x002B65, 0x000042, 0x003AE5, 0x50004A, + 0x40000A, 0x45C3D4, 0x000007, 0x454504, + 0x000007, 0x0000CD, 0x444944, 0x000007, + 0x454504, 0x000007, 0x00014D, 0x554944, + 0x000007, 0x045144, 0x367986, 0x002C65, + 0x000042, 0x48000A, 0x4CD104, 0x000007, + 0x04C144, 0x368386, 0x000007, 0x160007, + 0x002CE5, 0x040042, 0x40000A, 0x004020, + 0x000040, 0x002965, 0x000042, 0x40000A, + 0x004104, 0x36F086, 0x000007, 0x002402, + 0x383206, 0x005C02, 0x0025E5, 0x000042, + 0x40000A, 0x004274, 0x002AE5, 0x000042, + 0x40000A, 0x004274, 0x500112, 0x0029E5, + 0x000042, 0x40000A, 0x004234, 0x454104, + 0x000007, 0x004020, 0x000040, 0x003EE5, + 0x000020, 0x000040, 0x002DE5, 0x400152, + 0x50000A, 0x045144, 0x37DA86, 0x0000C5, + 0x003EE5, 0x004020, 0x000040, 0x002BE5, + 0x000042, 0x40000A, 0x404254, 0x000007, + 0x002AE5, 0x004020, 0x000040, 0x500132, + 0x040134, 0x005674, 0x0029E5, 0x020042, + 0x42000A, 0x000042, 0x50000A, 0x05417C, + 0x0028E5, 0x000042, 0x48000A, 0x0000C5, + 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5, + 0x020042, 0x40004A, 0x50000A, 0x00423C, + 0x00567C, 0x0028E5, 0x004820, 0x000040, + 0x281D12, 0x282512, 0x001F72, 0x002965, + 0x000042, 0x40000A, 0x004104, 0x393A86, + 0x0E0007, 0x160007, 0x1E0007, 0x003EE5, + 0x000042, 0x40000A, 0x004104, 0x397886, + 0x002D65, 0x000042, 0x28340A, 0x003465, + 0x020042, 0x42004A, 0x004020, 0x4A004A, + 0x50004A, 0x05D2F4, 0x54D104, 0x00735C, + 0x39E186, 0x000007, 0x000606, 0x080007, + 0x0C0007, 0x080007, 0x0A0007, 0x0001E5, + 0x020045, 0x004020, 0x000060, 0x000365, + 0x000040, 0x002E65, 0x001A20, 0x0A1A60, + 0x000040, 0x003465, 0x020042, 0x42004A, + 0x004020, 0x4A004A, 0x000606, 0x50004A, + 0x0017FD, 0x018042, 0x08000A, 0x000904, + 0x225A86, 0x000007, 0x00107D, 0x018042, + 0x0011FD, 0x33804A, 0x19804A, 0x20000A, + 0x000095, 0x2A1144, 0x01A144, 0x3B9086, + 0x00040D, 0x00B184, 0x3B9186, 0x0018FD, + 0x018042, 0x0010FD, 0x09804A, 0x38000A, + 0x000095, 0x010924, 0x003A64, 0x3B8186, + 0x000007, 0x003904, 0x3B9286, 0x000007, + 0x3B9A06, 0x00000D, 0x00008D, 0x000820, + 0x00387D, 0x018040, 0x700002, 0x00117D, + 0x018042, 0x00197D, 0x29804A, 0x30000A, + 0x380002, 0x003124, 0x000424, 0x000424, + 0x002A24, 0x280502, 0x00068D, 0x000810, + 0x28143A, 0x00750D, 0x00B124, 0x002264, + 0x3D0386, 0x284402, 0x000810, 0x280C3A, + 0x0B800D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00758D, 0x00B124, 0x100102, + 0x012144, 0x3E4986, 0x001810, 0x10003A, + 0x00387D, 0x018042, 0x08000A, 0x000904, + 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD, + 0x00008D, 0x023164, 0x000A64, 0x280D02, + 0x0B808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00387D, 0x018042, 0x08000A, + 0x000904, 0x3E3286, 0x030000, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x3D8286, + 0x000007, 0x002810, 0x28043A, 0x00750D, + 0x030924, 0x002264, 0x280D02, 0x02316C, + 0x28450A, 0x0B810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x00008D, 0x000A24, + 0x3E4A06, 0x100102, 0x001810, 0x10003A, + 0x0000BD, 0x003810, 0x30043A, 0x00187D, + 0x018042, 0x0018FD, 0x09804A, 0x20000A, + 0x0000AD, 0x028924, 0x07212C, 0x001010, + 0x300583, 0x300D8B, 0x3014BB, 0x301C83, + 0x002083, 0x00137D, 0x038042, 0x33844A, + 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB, + 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083, + 0x001E0D, 0x0005FD, 0x018042, 0x20000A, + 0x020924, 0x00068D, 0x00A96C, 0x00009D, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x3F6A86, 0x000007, 0x280502, 0x280D0A, + 0x284402, 0x001810, 0x28143A, 0x0C008D, + 0x000820, 0x0002FD, 0x018040, 0x220007, + 0x003904, 0x225886, 0x001E0D, 0x00057D, + 0x018042, 0x20000A, 0x020924, 0x0000A5, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x402A86, 0x000007, 0x280502, 0x280C02, + 0x002010, 0x28143A, 0x0C010D, 0x000820, + 0x0002FD, 0x018040, 0x225A06, 0x220007, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000 +}; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/sound/Makefile linux.ac/drivers/sound/Makefile --- linux.vanilla/drivers/sound/Makefile Thu May 25 17:38:07 2000 +++ linux.ac/drivers/sound/Makefile Wed May 31 11:16:22 2000 @@ -67,6 +67,7 @@ obj-$(CONFIG_SOUND_AWE32_SYNTH) += awe_wave.o obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx_audio.o ac97_codec.o +obj-$(CONFIG_SOUND_YMPCI) += ymf_sb.o sb_lib.o uart401.o obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o obj-$(CONFIG_SOUND_VWSND) += vwsnd.o 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/awe_wave.c linux.ac/drivers/sound/awe_wave.c --- linux.vanilla/drivers/sound/awe_wave.c Thu May 25 17:38:08 2000 +++ linux.ac/drivers/sound/awe_wave.c Sun Jun 4 22:25:51 2000 @@ -3252,7 +3252,7 @@ int removed = 0; prev = NULL; - for (p = sf->infos; p; prev = p, p = next) { + for (p = sf->infos; p; p = next) { next = p->next; if (p->type == V_ST_NORMAL && p->bank == bank && p->instr == instr) { @@ -3266,8 +3266,11 @@ sf->num_info--; removed++; kfree(p); - } + } else + prev = p; } + if (removed) + rebuild_preset_list(); return removed; } @@ -3318,7 +3321,7 @@ } break; case AWE_WR_REPLACE: - /* replace mode - remoe the instrument if it already exists */ + /* replace mode - remove the instrument if it already exists */ remove_info(sf, hdr.bank, hdr.instr); break; } 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/sound/ymf_sb.c linux.ac/drivers/sound/ymf_sb.c --- linux.vanilla/drivers/sound/ymf_sb.c Thu Jan 1 01:00:00 1970 +++ linux.ac/drivers/sound/ymf_sb.c Sun Jun 4 21:41:18 2000 @@ -0,0 +1,867 @@ +/* + Legacy audio driver for YMF724, 740, 744, 754 series. + Copyright 2000 Daisuke Nagano + + Based on the VIA 82Cxxx driver by Jeff Garzik + And ported to 2.3.x by Jeff Garzik too :) My it is a small world. + + Distribued under the GNU PUBLIC LICENSE (GPL) Version 2. + See the "COPYING" file distributed with kernel source tree for more info. + + ------------------------------------------------------------------------- + + It only supports SBPro compatible function of YMF7xx series s.t. + * 22.05kHz, 8-bit and stereo sample + * OPL3-compatible FM synthesizer + * MPU-401 compatible "external" MIDI interface + + ------------------------------------------------------------------------- + + Revision history + + Tue May 14 19:00:00 2000 0.0.1 + * initial release + + Tue May 16 19:29:29 2000 0.0.2 + + * add a little delays for reset devices. + * fixed addressing bug. + + Sun May 21 15:14:37 2000 0.0.3 + + * Add 'master_vol' module parameter to change 'PCM out Vol' of AC'97. + * remove native UART401 support. External MIDI port should be supported + by sb_midi driver. + * add support for SPDIF OUT. Module parameter 'spdif_out' is now available. + + Wed May 31 00:13:57 2000 0.0.4 + + * remove entries in Hwmcode.h. Now YMF744 / YMF754 sets instructions + in 724hwmcode.h. + * fixed wrong legacy_io setting on YMF744/YMF754 . + + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "sound_config.h" +#include "soundmodule.h" +#include "sb.h" + +#include "724hwmcode.h" + +#undef YMF_DEBUG +#define SUPPORT_UART401_MIDI 1 + +/* ---------------------------------------------------------------------- */ + +#ifndef SOUND_LOCK +#define SOUND_LOCK do {} while (0) +#define SOUND_LOCK_END do {} while (0) +#endif + +#ifndef PCI_VENDOR_ID_YAMAHA +#define PCI_VENDOR_ID_YAMAHA 0x1073 +#endif +#ifndef PCI_DEVICE_ID_YMF724 +#define PCI_DEVICE_ID_YMF724 0x0004 +#endif +#ifndef PCI_DEVICE_ID_YMF740 +#define PCI_DEVICE_ID_YMF740 0x000A +#endif +#ifndef PCI_DEVICE_ID_YMF740C +#define PCI_DEVICE_ID_YMF740C 0x000C +#endif +#ifndef PCI_DEVICE_ID_YMF724F +#define PCI_DEVICE_ID_YMF724F 0x000D +#endif +#ifndef PCI_DEVICE_ID_YMF744 +#define PCI_DEVICE_ID_YMF744 0x0010 +#endif +#ifndef PCI_DEVICE_ID_YMF754 +#define PCI_DEVICE_ID_YMF754 0x0012 +#endif + +/* ---------------------------------------------------------------------- */ + +#define YMFSB_RESET_DELAY 5 + +#define YMFSB_REGSIZE 0x8000 + +#define YMFSB_AC97TIMEOUT 2000 + +#define YMFSB_WORKBITTIMEOUT 250000 + +#define YMFSB_DSPLENGTH 0x0080 +#define YMFSB_CTRLLENGTH 0x3000 + +#define YMFSB_PCIR_VENDORID 0x00 +#define YMFSB_PCIR_DEVICEID 0x02 +#define YMFSB_PCIR_CMD 0x04 +#define YMFSB_PCIR_REVISIONID 0x08 +#define YMFSB_PCIR_BASEADDR 0x10 +#define YMFSB_PCIR_IRQ 0x3c + +#define YMFSB_PCIR_LEGCTRL 0x40 +#define YMFSB_PCIR_ELEGCTRL 0x42 +#define YMFSB_PCIR_DSXGCTRL 0x48 +#define YMFSB_PCIR_OPLADR 0x60 +#define YMFSB_PCIR_SBADR 0x62 +#define YMFSB_PCIR_MPUADR 0x64 + +#define YMFSB_INTFLAG 0x0004 +#define YMFSB_ACTIVITY 0x0006 +#define YMFSB_GLOBALCTRL 0x0008 +#define YMFSB_ZVCTRL 0x000A +#define YMFSB_TIMERCTRL 0x0010 +#define YMFSB_TIMERCOUNT 0x0012 +#define YMFSB_SPDIFOUTCTRL 0x0018 +#define YMFSB_SPDIFOUTSTATUS 0x001C +#define YMFSB_EEPROMCTRL 0x0020 +#define YMFSB_SPDIFINCTRL 0x0034 +#define YMFSB_SPDIFINSTATUS 0x0038 +#define YMFSB_DSPPROGRAMDL 0x0048 +#define YMFSB_DLCNTRL 0x004C +#define YMFSB_GPIOININTFLAG 0x0050 +#define YMFSB_GPIOININTENABLE 0x0052 +#define YMFSB_GPIOINSTATUS 0x0054 +#define YMFSB_GPIOOUTCTRL 0x0056 +#define YMFSB_GPIOFUNCENABLE 0x0058 +#define YMFSB_GPIOTYPECONFIG 0x005A +#define YMFSB_AC97CMDDATA 0x0060 +#define YMFSB_AC97CMDADR 0x0062 +#define YMFSB_PRISTATUSDATA 0x0064 +#define YMFSB_PRISTATUSADR 0x0066 +#define YMFSB_SECSTATUSDATA 0x0068 +#define YMFSB_SECSTATUSADR 0x006A +#define YMFSB_SECCONFIG 0x0070 +#define YMFSB_LEGACYOUTVOL 0x0080 +#define YMFSB_LEGACYOUTVOLL 0x0080 +#define YMFSB_LEGACYOUTVOLR 0x0082 +#define YMFSB_NATIVEDACOUTVOL 0x0084 +#define YMFSB_NATIVEDACOUTVOLL 0x0084 +#define YMFSB_NATIVEDACOUTVOLR 0x0086 +#define YMFSB_SPDIFOUTVOL 0x0088 +#define YMFSB_SPDIFOUTVOLL 0x0088 +#define YMFSB_SPDIFOUTVOLR 0x008A +#define YMFSB_AC3OUTVOL 0x008C +#define YMFSB_AC3OUTVOLL 0x008C +#define YMFSB_AC3OUTVOLR 0x008E +#define YMFSB_PRIADCOUTVOL 0x0090 +#define YMFSB_PRIADCOUTVOLL 0x0090 +#define YMFSB_PRIADCOUTVOLR 0x0092 +#define YMFSB_LEGACYLOOPVOL 0x0094 +#define YMFSB_LEGACYLOOPVOLL 0x0094 +#define YMFSB_LEGACYLOOPVOLR 0x0096 +#define YMFSB_NATIVEDACLOOPVOL 0x0098 +#define YMFSB_NATIVEDACLOOPVOLL 0x0098 +#define YMFSB_NATIVEDACLOOPVOLR 0x009A +#define YMFSB_SPDIFLOOPVOL 0x009C +#define YMFSB_SPDIFLOOPVOLL 0x009E +#define YMFSB_SPDIFLOOPVOLR 0x009E +#define YMFSB_AC3LOOPVOL 0x00A0 +#define YMFSB_AC3LOOPVOLL 0x00A0 +#define YMFSB_AC3LOOPVOLR 0x00A2 +#define YMFSB_PRIADCLOOPVOL 0x00A4 +#define YMFSB_PRIADCLOOPVOLL 0x00A4 +#define YMFSB_PRIADCLOOPVOLR 0x00A6 +#define YMFSB_NATIVEADCINVOL 0x00A8 +#define YMFSB_NATIVEADCINVOLL 0x00A8 +#define YMFSB_NATIVEADCINVOLR 0x00AA +#define YMFSB_NATIVEDACINVOL 0x00AC +#define YMFSB_NATIVEDACINVOLL 0x00AC +#define YMFSB_NATIVEDACINVOLR 0x00AE +#define YMFSB_BUF441OUTVOL 0x00B0 +#define YMFSB_BUF441OUTVOLL 0x00B0 +#define YMFSB_BUF441OUTVOLR 0x00B2 +#define YMFSB_BUF441LOOPVOL 0x00B4 +#define YMFSB_BUF441LOOPVOLL 0x00B4 +#define YMFSB_BUF441LOOPVOLR 0x00B6 +#define YMFSB_SPDIFOUTVOL2 0x00B8 +#define YMFSB_SPDIFOUTVOL2L 0x00B8 +#define YMFSB_SPDIFOUTVOL2R 0x00BA +#define YMFSB_SPDIFLOOPVOL2 0x00BC +#define YMFSB_SPDIFLOOPVOL2L 0x00BC +#define YMFSB_SPDIFLOOPVOL2R 0x00BE +#define YMFSB_ADCSLOTSR 0x00C0 +#define YMFSB_RECSLOTSR 0x00C4 +#define YMFSB_ADCFORMAT 0x00C8 +#define YMFSB_RECFORMAT 0x00CC +#define YMFSB_P44SLOTSR 0x00D0 +#define YMFSB_STATUS 0x0100 +#define YMFSB_CTRLSELECT 0x0104 +#define YMFSB_MODE 0x0108 +#define YMFSB_SAMPLECOUNT 0x010C +#define YMFSB_NUMOFSAMPLES 0x0110 +#define YMFSB_CONFIG 0x0114 +#define YMFSB_PLAYCTRLSIZE 0x0140 +#define YMFSB_RECCTRLSIZE 0x0144 +#define YMFSB_EFFCTRLSIZE 0x0148 +#define YMFSB_WORKSIZE 0x014C +#define YMFSB_MAPOFREC 0x0150 +#define YMFSB_MAPOFEFFECT 0x0154 +#define YMFSB_PLAYCTRLBASE 0x0158 +#define YMFSB_RECCTRLBASE 0x015C +#define YMFSB_EFFCTRLBASE 0x0160 +#define YMFSB_WORKBASE 0x0164 +#define YMFSB_DSPINSTRAM 0x1000 +#define YMFSB_CTRLINSTRAM 0x4000 + + +/* ---------------------------------------------------------------------- */ + +#define MAX_CARDS 4 + +#define PFX "ymf_sb: " + +#define YMFSB_VERSION "0.0.4" +#define YMFSB_CARD_NAME "YMF7xx Legacy Audio driver " YMFSB_VERSION + +#ifdef SUPPORT_UART401_MIDI +#if 0 +# define ymf7xxsb_probe_midi probe_uart401 +# define ymf7xxsb_attach_midi attach_uart401 +# define ymf7xxsb_unload_midi unload_uart401 +#else +# define ymf7xxsb_probe_midi probe_sbmpu +# define ymf7xxsb_attach_midi attach_sbmpu +# define ymf7xxsb_unload_midi unload_sbmpu +#endif +#endif + +/* ---------------------------------------------------------------------- */ + +static struct address_info sb_data[MAX_CARDS]; +static struct address_info opl3_data[MAX_CARDS]; +#ifdef SUPPORT_UART401_MIDI +static struct address_info mpu_data[MAX_CARDS]; +#endif +static unsigned cards = 0; +static unsigned short *ymfbase[MAX_CARDS]; + +/* ---------------------------------------------------------------------- */ + +#ifdef MODULE +#ifdef SUPPORT_UART401_MIDI +static int mpu_io = 0; +#endif +static int synth_io = 0; +static int io = 0; +static int dma = 0; +static int master_vol = -1; +static int spdif_out = 0; +#ifdef SUPPORT_UART401_MIDI +MODULE_PARM(mpu_io, "i"); +#endif +MODULE_PARM(synth_io, "i"); +MODULE_PARM(io,"i"); +MODULE_PARM(dma,"i"); +MODULE_PARM(master_vol,"i"); +MODULE_PARM(spdif_out,"i"); +#else +#ifdef SUPPORT_UART401_MIDI +static int mpu_io = 0x330; +#endif +static int synth_io = 0x388; +static int io = 0x220; +static int dma = 1; +static int master_vol = 80; +static int spdif_out = 0; +#endif + +/* ---------------------------------------------------------------------- */ + +static int readRegWord( int adr ) { + + if (ymfbase[cards]==NULL) return 0; + + return readw(ymfbase[cards]+adr/2); +} + +static void writeRegWord( int adr, int val ) { + + if (ymfbase[cards]==NULL) return; + + writew((unsigned short)(val&0xffff), ymfbase[cards] + adr/2); + + return; +} + +static int readRegDWord( int adr ) { + + if (ymfbase[cards]==NULL) return 0; + + return (readl(ymfbase[cards]+adr/2)); +} + +static void writeRegDWord( int adr, int val ) { + + if (ymfbase[cards]==NULL) return; + + writel((unsigned int)(val&0xffffffff), ymfbase[cards]+adr/2); + + return; +} + +/* ---------------------------------------------------------------------- */ + +static int checkPrimaryBusy( void ) +{ + int timeout=0; + + while ( timeout++ < YMFSB_AC97TIMEOUT ) + { + if ( (readRegWord(YMFSB_PRISTATUSADR) & 0x8000) == 0x0000 ) + return 0; + } + return -1; +} + +static int writeAc97( int adr, unsigned short val ) +{ + + if ( adr > 0x7f || adr < 0x00 ) return -1; + + if ( checkPrimaryBusy() ) return -1; + +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "AC97 0x%0x = 0x%0x\n",adr,val); +#endif + + writeRegWord( YMFSB_AC97CMDADR, 0x0000 | adr ); + writeRegWord( YMFSB_AC97CMDDATA, val ); + + return 0; +} + +static int checkCodec( struct pci_dev *pcidev ) +{ + u8 tmp8; + + pci_read_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, &tmp8); + if ( tmp8 & 0x03 ) { + pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc); + mdelay(YMFSB_RESET_DELAY); + pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8|0x03); + mdelay(YMFSB_RESET_DELAY); + pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc); + mdelay(YMFSB_RESET_DELAY); + } + + if ( checkPrimaryBusy() ) return -1; + + return 0; +} + +static int setupLegacyIO( struct pci_dev *pcidev ) +{ + int v; + int sbio=0,mpuio=0,oplio=0,dma=0; + + switch(sb_data[cards].io_base) { + case 0x220: + sbio = 0; + break; + case 0x240: + sbio = 1; + break; + case 0x260: + sbio = 2; + break; + case 0x280: + sbio = 3; + break; + default: + return -1; + break; + } +#ifdef YMF_DEBUG + printk(PFX "set SBPro I/O at 0x%x\n",sb_data[cards].io_base); +#endif + +#ifdef SUPPORT_UART401_MIDI + switch(mpu_data[cards].io_base) { + case 0x330: + mpuio = 0; + break; + case 0x300: + mpuio = 1; + break; + case 0x332: + mpuio = 2; + break; + case 0x334: + mpuio = 3; + break; + default: + mpuio = 0; + break; + } +# ifdef YMF_DEBUG + printk(PFX "set MPU401 I/O at 0x%x\n",mpu_data[cards].io_base); +# endif +#endif + + switch(opl3_data[cards].io_base) { + case 0x388: + oplio = 0; + break; + case 0x398: + oplio = 1; + break; + case 0x3a0: + oplio = 2; + break; + case 0x3a8: + oplio = 3; + break; + default: + return -1; + break; + } +#ifdef YMF_DEBUG + printk(PFX "set OPL3 I/O at 0x%x\n",opl3_data[cards].io_base); +#endif + + dma = sb_data[cards].dma; +#ifdef YMF_DEBUG + printk(PFX "set DMA address at 0x%x\n",sb_data[cards].dma); +#endif + + v = 0x0000 | ((dma<<6)&0x03) | 0x003f; + pci_write_config_word(pcidev, YMFSB_PCIR_LEGCTRL, v); +#ifdef YMF_DEBUG + printk(PFX "LEGCTRL: 0x%x\n",v); +#endif + switch( pcidev->device ) { + case PCI_DEVICE_ID_YMF724: + case PCI_DEVICE_ID_YMF740: + case PCI_DEVICE_ID_YMF724F: + case PCI_DEVICE_ID_YMF740C: + v = 0x8800 | ((mpuio<<4)&0x03) | ((sbio<<2)&0x03) | (oplio&0x03); + pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v); +#ifdef YMF_DEBUG + printk(PFX "ELEGCTRL: 0x%x\n",v); +#endif + break; + + case PCI_DEVICE_ID_YMF744: + case PCI_DEVICE_ID_YMF754: + v = 0x8800; + pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v); +#ifdef YMF_DEBUG + printk(PFX "ELEGCTRL: 0x%x\n",v); +#endif + pci_write_config_word(pcidev, YMFSB_PCIR_OPLADR, opl3_data[cards].io_base); + pci_write_config_word(pcidev, YMFSB_PCIR_SBADR, sb_data[cards]. +io_base); +#ifdef SUPPORT_UART401_MIDI + pci_write_config_word(pcidev, YMFSB_PCIR_MPUADR, mpu_data[cards].io_base); +#endif + break; + + default: + printk(KERN_ERR PFX "Invalid device ID: %d\n",pcidev->device); + return -1; + break; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static void enableDSP( void ) +{ + writeRegDWord( YMFSB_CONFIG, 0x00000001 ); + return; +} + +static void disableDSP( void ) +{ + int val; + int i; + + val = readRegDWord( YMFSB_CONFIG ); + if ( val ) { + writeRegDWord( YMFSB_CONFIG, 0 ); + } + + i=0; + while( ++i < YMFSB_WORKBITTIMEOUT ) { + val = readRegDWord(YMFSB_STATUS); + if ( (val & 0x00000002) == 0x00000000 ) break; + } + + return; +} + +static int setupInstruction( struct pci_dev *pcidev ) +{ + int i; + int val; + + writeRegDWord( YMFSB_NATIVEDACOUTVOL, 0 ); /* mute dac */ + disableDSP(); + + writeRegDWord( YMFSB_MODE, 0x00010000 ); + + /* DS-XG Software Reset */ + writeRegDWord( YMFSB_MODE, 0x00000000 ); + writeRegDWord( YMFSB_MAPOFREC, 0x00000000 ); + writeRegDWord( YMFSB_MAPOFEFFECT, 0x00000000 ); + writeRegDWord( YMFSB_PLAYCTRLBASE, 0x00000000 ); + writeRegDWord( YMFSB_RECCTRLBASE, 0x00000000 ); + writeRegDWord( YMFSB_EFFCTRLBASE, 0x00000000 ); + + val = readRegWord( YMFSB_GLOBALCTRL ); + writeRegWord( YMFSB_GLOBALCTRL, (val&~0x0007) ); + + /* setup DSP instruction code */ + for ( i=0 ; i>2] ); + } + + switch( pcidev->device ) { + case PCI_DEVICE_ID_YMF724: + case PCI_DEVICE_ID_YMF740: + /* setup Control instruction code */ + for ( i=0 ; i>2] ); + } + break; + + case PCI_DEVICE_ID_YMF724F: + case PCI_DEVICE_ID_YMF740C: + case PCI_DEVICE_ID_YMF744: + case PCI_DEVICE_ID_YMF754: + /* setup Control instruction code */ + for ( i=0 ; i>2] ); + } + break; + + default: + return -1; + } + + enableDSP(); + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static int __init ymf7xx_init(struct pci_dev *pcidev) +{ + unsigned short v; + + /* Read hardware information */ +#ifdef YMF_DEBUG + unsigned int dv; + pci_read_config_word(pcidev, YMFSB_PCIR_VENDORID, &v); + printk(KERN_INFO PFX "Vendor ID = 0x%x\n",v); + pci_read_config_word(pcidev, YMFSB_PCIR_DEVICEID, &v); + printk(KERN_INFO PFX "Device ID = 0x%x\n",v); + pci_read_config_word(pcidev, YMFSB_PCIR_REVISIONID, &v); + printk(KERN_INFO PFX "Revision ID = 0x%x\n",v&0xff); + pci_read_config_dword(pcidev, YMFSB_PCIR_BASEADDR, &dv); + printk(KERN_INFO PFX "Base address = 0x%x\n",dv); + pci_read_config_word(pcidev, YMFSB_PCIR_IRQ, &v); + printk(KERN_INFO PFX "IRQ line = 0x%x\n",v&0xff); +#endif + + /* enables memory space access / bus mastering */ + pci_read_config_word(pcidev, YMFSB_PCIR_CMD, &v); + pci_write_config_word(pcidev, YMFSB_PCIR_CMD, v|0x06); + + /* check codec */ +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "check codec...\n"); +#endif + if (checkCodec(pcidev)) return -1; + + /* setup legacy I/O */ +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup legacy I/O...\n"); +#endif + if (setupLegacyIO(pcidev)) return -1; + + /* setup instruction code */ +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup instructions...\n"); +#endif + if (setupInstruction(pcidev)) return -1; + + /* AC'97 setup */ +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup AC'97...\n"); +#endif + if ( writeAc97(AC97_RESET ,0x0000) ) /* Reset */ + return -1; + if ( writeAc97(AC97_MASTER_VOL_STEREO,0x0000) ) /* Master Volume */ + return -1; + + v = 31*(100-master_vol)/100; + v = (v<<8 | v)&0x7fff; + if ( writeAc97(AC97_PCMOUT_VOL ,v ) ) /* PCM out Volume */ + return -1; + +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup Legacy Volume...\n"); +#endif + /* Legacy Audio Output Volume L & R ch */ + writeRegDWord( YMFSB_LEGACYOUTVOL, 0x3fff3fff ); + +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup SPDIF output control...\n"); +#endif + /* SPDIF Output control */ + v = spdif_out != 0 ? 0x0001 : 0x0000; + writeRegWord( YMFSB_SPDIFOUTCTRL, v ); + /* no copyright protection, + sample-rate converted, + re-recorded software comercially available (the 1st generation), + original */ + writeRegWord( YMFSB_SPDIFOUTSTATUS, 0x9a04 ); + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static void __init ymf7xxsb_attach_sb(struct address_info *hw_config) +{ + if(!sb_dsp_init(hw_config)) + hw_config->slots[0] = -1; +} + +static int __init ymf7xxsb_probe_sb(struct address_info *hw_config) +{ + if (check_region(hw_config->io_base, 16)) + { + printk(KERN_DEBUG PFX "SBPro port 0x%x is already in use\n", + hw_config->io_base); + return 0; + } + return sb_dsp_detect(hw_config, SB_PCI_YAMAHA, 0, NULL); +} + + +static void ymf7xxsb_unload_sb(struct address_info *hw_config, int unload_mpu) +{ + if(hw_config->slots[0]!=-1) + sb_dsp_unload(hw_config, unload_mpu); +} + +/* ---------------------------------------------------------------------- */ + +enum chip_types { + CH_YMF724 = 0, + CH_YMF724F, + CH_YMF740, + CH_YMF740C, + CH_YMF744, + CH_YMF754, +}; + +/* directly indexed by chip_types enum above */ +/* note we keep this a struct to ease adding + * other per-board or per-chip info here */ +struct { + const char *devicename; +} devicetable[] __initdata = +{ + { "YMF724A-E" }, + { "YMF724F" }, + { "YMF740A-B" }, + { "YMF740C" }, + { "YMF744" }, + { "YMF754" }, +}; + +static struct pci_device_id ymf7xxsb_pci_tbl[] __initdata = { + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724 }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724F }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740 }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740C }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF744 }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF754 }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, ymf7xxsb_pci_tbl); + +static int __init ymf7xxsb_init_one (struct pci_dev *pcidev, const struct pci_device_id *ent) +{ + + const char *devicename; + unsigned long iobase; + + if (cards == MAX_CARDS) { + printk (KERN_DEBUG PFX "maximum number of cards reached\n"); + return -ENODEV; + } + + if ( pcidev->irq == 0 ) return -ENODEV; + iobase = pci_resource_start (pcidev, 0); + if ( iobase == 0x00000000 ) return -ENODEV; + + devicename = devicetable[ent->driver_data].devicename; + + /* remap memory mapped I/O onto kernel virtual memory */ + if ( (ymfbase[cards] = ioremap_nocache(iobase, YMFSB_REGSIZE)) == 0 ) + { + printk(KERN_ERR PFX "ioremap (0x%lx) returns zero\n", iobase); + return -ENODEV; + } + printk(KERN_INFO PFX "found %s at 0x%lx\n", devicename, iobase); +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "remappling to 0x%p\n", ymfbase[cards]); +#endif + + memset (&sb_data[cards], 0, sizeof (struct address_info)); + memset (&opl3_data[cards], 0, sizeof (struct address_info)); +#ifdef SUPPORT_UART401_MIDI + memset (&mpu_data[cards], 0, sizeof (struct address_info)); +#endif + + sb_data[cards].name = YMFSB_CARD_NAME; + opl3_data[cards].name = YMFSB_CARD_NAME; +#ifdef SUPPORT_UART401_MIDI + mpu_data[cards].name = YMFSB_CARD_NAME; +#endif + + sb_data[cards].card_subtype = MDL_YMPCI; + + if ( io == 0 ) io = 0x220; + sb_data[cards].io_base = io; + sb_data[cards].irq = pcidev->irq; + sb_data[cards].dma = dma; + + if ( synth_io == 0 ) synth_io = 0x388; + opl3_data[cards].io_base = synth_io; + opl3_data[cards].irq = -1; + +#ifdef SUPPORT_UART401_MIDI + if ( mpu_io == 0 ) mpu_io = 0x330; + mpu_data[cards].io_base = mpu_io; + mpu_data[cards].irq = -1; +#endif + + if ( ymf7xx_init(pcidev) ) { + printk (KERN_ERR PFX + "Cannot initialize %s, aborting\n", + devicename); + return -ENODEV; + } + + /* register legacy SoundBlaster Pro */ + if (!ymf7xxsb_probe_sb(&sb_data[cards])) { + printk (KERN_ERR PFX + "SB probe at 0x%X failed, aborting\n", + io); + return -ENODEV; + } + ymf7xxsb_attach_sb (&sb_data[cards]); + +#ifdef SUPPORT_UART401_MIDI + /* register legacy MIDI */ + if ( mpu_io > 0 && 0) + { + if (!ymf7xxsb_probe_midi (&mpu_data[cards])) { + printk (KERN_ERR PFX + "MIDI probe @ 0x%X failed, aborting\n", + mpu_io); + ymf7xxsb_unload_sb (&sb_data[cards], 0); + return -ENODEV; + } + ymf7xxsb_attach_midi (&mpu_data[cards]); + } +#endif + + /* register legacy OPL3 */ + + cards++; + return 0; +} + +static struct pci_driver ymf7xxsb_driver = { + name: "ymf7xxsb", + id_table: ymf7xxsb_pci_tbl, + probe: ymf7xxsb_init_one, +}; + +static int __init init_ymf7xxsb_module(void) +{ + int i; + + /* + * Binds us to the sound subsystem + */ + SOUND_LOCK; + + if ( master_vol < 0 ) master_vol = 50; + if ( master_vol > 100 ) master_vol = 100; + + for (i=0 ; im_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 Sun Jun 4 22:47:07 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/dabusb.c linux.ac/drivers/usb/dabusb.c --- linux.vanilla/drivers/usb/dabusb.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/dabusb.c Sun Jun 4 22:13:29 2000 @@ -573,7 +573,7 @@ int devnum = MINOR (inode->i_rdev); pdabusb_t s; - if (devnum < DABUSB_MINOR || devnum > (DABUSB_MINOR + NRDABUSB)) + if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB)) return -EIO; MOD_INC_USE_COUNT; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/dabusb.h linux.ac/drivers/usb/dabusb.h --- linux.vanilla/drivers/usb/dabusb.h Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/dabusb.h Sun Jun 4 22:13:28 2000 @@ -49,7 +49,7 @@ #define _DABUSB_IF 2 -#define _DABUSB_ISOPIPE 0x89 +#define _DABUSB_ISOPIPE 0x09 #define _ISOPIPESIZE 16384 #define _BULK_DATA_LEN 64 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 Sun Jun 4 22:46:27 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/hub.c linux.ac/drivers/usb/hub.c --- linux.vanilla/drivers/usb/hub.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/hub.c Sun Jun 4 21:36:16 2000 @@ -120,18 +120,25 @@ struct usb_hub_descriptor *descriptor; struct usb_descriptor_header *header; struct usb_hub_status *hubsts; - int i; + int i, ret; /* Get the length first */ - if (usb_get_hub_descriptor(dev, buffer, 4) < 0) + ret = usb_get_hub_descriptor(dev, buffer, sizeof(*header)); + if (ret < 0) { + err("Unable to get partial hub descriptor (err = %d)", ret); return -1; + } header = (struct usb_descriptor_header *)buffer; bitmap = kmalloc(header->bLength, GFP_KERNEL); - if (!bitmap) + if (!bitmap) { + err("Unable to kmalloc %d bytes for bitmap", header->bLength); return -1; + } - if (usb_get_hub_descriptor(dev, bitmap, header->bLength) < 0) { + ret = usb_get_hub_descriptor(dev, bitmap, header->bLength); + if (ret < 0) { + err("Unable to get hub descriptor (err = %d)", ret); kfree(bitmap); return -1; } @@ -182,8 +189,11 @@ kfree(bitmap); - if (usb_get_hub_status(dev, buffer) < 0) + ret = usb_get_hub_status(dev, buffer); + if (ret < 0) { + err("Unable to get hub status (err = %d)", ret); return -1; + } hubsts = (struct usb_hub_status *)buffer; dbg("local power source is %s", @@ -225,12 +235,16 @@ endpoint = &interface->endpoint[0]; /* Output endpoint? Curiousier and curiousier.. */ - if (!(endpoint->bEndpointAddress & USB_DIR_IN)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) { + err("Device is hub class, but has output endpoint?"); return NULL; + } /* If it's not an interrupt endpoint, we'd better punt! */ - if ((endpoint->bmAttributes & 3) != 3) + if ((endpoint->bmAttributes & 3) != 3) { + err("Device is hub class, but has endpoint other than interrupt?"); return NULL; + } /* We found a hub */ info("USB hub found"); @@ -326,12 +340,13 @@ struct usb_device *usb; struct usb_port_status portsts; unsigned short portstatus, portchange; - int tries; + int ret, tries; wait_ms(100); - /* Check status */ - if (usb_get_port_status(hub, port + 1, &portsts)<0) { - err("get_port_status failed"); + + ret = usb_get_port_status(hub, port + 1, &portsts); + if (ret < 0) { + err("get_port_status(%d) failed (err = %d)", port + 1, ret); return; } @@ -353,19 +368,19 @@ } wait_ms(400); - /* Reset the port */ - #define MAX_TRIES 5 - - for(tries=0;tries= MAX_TRIES) { err("Cannot enable port %i after %i retries, disabling port.", port+1, MAX_TRIES); err("Maybe the USB cable is bad?"); return; @@ -390,7 +405,6 @@ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_RESET); /* Allocate a new device struct for it */ - usb = usb_alloc_dev(hub, hub->bus); if (!usb) { err("couldn't allocate usb_device"); @@ -556,10 +570,9 @@ } static struct usb_driver hub_driver = { - "hub", - hub_probe, - hub_disconnect, - { NULL, NULL } + name: "hub", + probe: hub_probe, + disconnect: hub_disconnect }; /* @@ -569,8 +582,10 @@ { int pid; - if (usb_register(&hub_driver) < 0) + if (usb_register(&hub_driver) < 0) { + err("Unable to register USB hub driver"); return -1; + } pid = kernel_thread(usb_hub_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); 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/scanner.c linux.ac/drivers/usb/scanner.c --- linux.vanilla/drivers/usb/scanner.c Thu May 25 17:38:13 2000 +++ linux.ac/drivers/usb/scanner.c Sun Jun 4 22:20:40 2000 @@ -1,7 +1,7 @@ /* -*- linux-c -*- */ /* - * Driver for USB Scanners (linux-2.3.99-pre6-3) + * Driver for USB Scanners (linux-2.4.0test1-ac7) * * Copyright (C) 1999, 2000 David E. Nelson * @@ -192,6 +192,12 @@ * scanner lookup/ident table. Thanks Randy. * - Documentation updates. * - Added wait queues to read_scanner(). + * + * + * 0.4.3.1 + * + * - Fixed HP S20 ID's...again..sigh. Thanks to Ruud + * Linders . * * * TODO diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/usb/scanner.h linux.ac/drivers/usb/scanner.h --- linux.vanilla/drivers/usb/scanner.h Thu May 25 17:38:14 2000 +++ linux.ac/drivers/usb/scanner.h Sun Jun 4 22:46:40 2000 @@ -1,5 +1,5 @@ /* - * Driver for USB Scanners (linux-2.3.99-pre6-3) + * Driver for USB Scanners (linux-2.4.0test1-ac7) * * Copyright (C) 1999, 2000 David E. Nelson * @@ -118,7 +118,7 @@ { 0x03f0, 0x0205 }, /* 3300C */ { 0x03f0, 0x0101 }, /* 4100C */ { 0x03f0, 0x0105 }, /* 4200C */ - { 0x03f0, 0x0202 }, /* PhotoSmart S20 */ + { 0x03f0, 0x0102 }, /* PhotoSmart S20 */ { 0x03f0, 0x0401 }, /* 5200C */ { 0x03f0, 0x0201 }, /* 6200C */ { 0x03f0, 0x0601 }, /* 6300C */ 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/uss720.c linux.ac/drivers/usb/uss720.c --- linux.vanilla/drivers/usb/uss720.c Thu May 25 17:38:12 2000 +++ linux.ac/drivers/usb/uss720.c Sun Jun 4 21:33:26 2000 @@ -546,13 +546,13 @@ struct parport *pp; int i; - printk(KERN_DEBUG "uss720: probe: vendor id 0x%x, device id 0x%x\n", - usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); - if ((usbdev->descriptor.idVendor != 0x047e || usbdev->descriptor.idProduct != 0x1001) && (usbdev->descriptor.idVendor != 0x0557 || usbdev->descriptor.idProduct != 0x2001) && (usbdev->descriptor.idVendor != 0x0729 || usbdev->descriptor.idProduct != 0x1284)) return NULL; + + printk(KERN_DEBUG "uss720: probe: vendor id 0x%x, device id 0x%x\n", + usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); /* our known interfaces have 3 alternate settings */ if (usbdev->actconfig->interface[ifnum].num_altsetting != 3) 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/Config.in linux.ac/drivers/video/Config.in --- linux.vanilla/drivers/video/Config.in Thu May 25 17:46:15 2000 +++ linux.ac/drivers/video/Config.in Sun Jun 4 21:17:38 2000 @@ -251,8 +251,8 @@ "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \ - "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \ - "$CONFIG_FB_SIS" = "y" ]; then + "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \ + "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" ]; then define_tristate CONFIG_FBCON_CFB16 y else if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ @@ -264,7 +264,8 @@ "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ "$CONFIG_FB_PM2" = "m" -o "$CONFIG_FB_SGIVW" = "m" -o \ - "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" ]; then + "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" \ + "$CONFIG_FB_SA1100" = "m"]; then define_tristate CONFIG_FBCON_CFB16 m fi fi 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 Sun Jun 4 21:37:47 2000 @@ -31,7 +31,7 @@ * */ -#define CLGEN_VERSION "1.9.6" +#define CLGEN_VERSION "1.9.7" #include #include @@ -628,12 +628,6 @@ long *nom, long *den, long *div, long maxfreq); -#ifdef CONFIG_PCI -static struct pci_dev *clgen_pci_dev_get (clgen_board_t *btype); -static unsigned int clgen_get_memsize (caddr_t regbase); -static int clgen_pci_setup (struct clgenfb_info *fb_info, clgen_board_t *btype); -#endif /* CONFIG_PCI */ - #ifdef CLGEN_DEBUG static void clgen_dump (void); static void clgen_dbg_reg_dump (caddr_t regbase); @@ -2502,8 +2496,11 @@ pdev = pci_find_device (PCI_VENDOR_ID_CIRRUS, clgen_pci_probe_list[i].device, NULL); - if (pdev) + 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 +2536,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 +2552,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/cyber2000fb.c linux.ac/drivers/video/cyber2000fb.c --- linux.vanilla/drivers/video/cyber2000fb.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/video/cyber2000fb.c Sun Jun 4 21:18:26 2000 @@ -12,8 +12,13 @@ * especially for the colourmap stuff. Once fbcon has been fully migrated, * we can kill the last 5 references to cfb->currcon. * - * We also use the new hotplug PCI subsystem. This doesn't work fully in - * the case of multiple CyberPro cards yet however. + * We also use the new hotplug PCI subsystem. I'm not sure if there are any + * such cards, but I'm erring on the side of caution. We don't want to go + * pop just because someone does have one. + * + * Note that this doesn't work fully in the case of multiple CyberPro cards + * with grabbers. We currently can only attach to the first CyberPro card + * found. */ #include #include @@ -47,7 +52,7 @@ /* * This is the offset of the PCI space in physical memory */ -#ifdef CONFIG_ARCH_FOOTBRIDGE +#ifdef CONFIG_FOOTBRIDGE #define PCI_PHYS_OFFSET 0x80000000 #else #define PCI_PHYS_OFFSET 0x00000000 @@ -62,6 +67,8 @@ struct display_switch *dispsw; struct pci_dev *dev; signed int currcon; + int func_use_count; + u_long ref_ps; /* * Clock divisors @@ -72,7 +79,10 @@ u8 red, green, blue; } palette[NR_PALETTE]; + u_char mem_ctl1; u_char mem_ctl2; + u_char mclk_mult; + u_char mclk_div; }; /* -------------------- Hardware specific routines ------------------------- */ @@ -363,7 +373,7 @@ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 }; -static void cyber2000fb_set_timing(struct par_info *hw) +static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw) { u_int i; @@ -416,11 +426,10 @@ cyber2000_attrw(0x14, 0x00); /* PLL registers */ - cyber2000_grphw(0xb0, hw->clock_mult); - cyber2000_grphw(0xb1, hw->clock_div); - - cyber2000_grphw(0xb2, 0xdb); - cyber2000_grphw(0xb3, 0x54); /* MCLK: 75MHz */ + cyber2000_grphw(DCLK_MULT, hw->clock_mult); + cyber2000_grphw(DCLK_DIV, hw->clock_div); + cyber2000_grphw(MCLK_MULT, cfb->mclk_mult); + cyber2000_grphw(MCLK_DIV, cfb->mclk_div); cyber2000_grphw(0x90, 0x01); cyber2000_grphw(0xb9, 0x80); cyber2000_grphw(0xb9, 0x00); @@ -438,7 +447,9 @@ cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) | ((hw->pitch >> 4) & 0x30)); cyber2000_grphw(0x77, hw->visualid); - cyber2000_grphw(0x33, 0x0c); + + /* make sure we stay in linear mode */ + cyber2000_grphw(0x33, 0x0d); /* * Set up accelerator registers @@ -535,6 +546,7 @@ Htotal = var->xres + var->right_margin + var->hsync_len + var->left_margin; + if (Htotal > 2080) return -EINVAL; @@ -619,7 +631,7 @@ struct fb_var_screeninfo *var) { u_long pll_ps = var->pixclock; - const u_long ref_ps = 69842; + const u_long ref_ps = cfb->ref_ps; u_int div2, t_div1, best_div1, best_mult; int best_diff; @@ -641,7 +653,6 @@ if (div2 == 4) return -EINVAL; -#if 1 /* * Step 2: * Given pll_ps and ref_ps, find: @@ -689,94 +700,7 @@ if (diff == 0) break; } -#else - /* Note! This table will be killed shortly. --rmk */ - /* - * 1600x1200 1280x1024 1152x864 1024x768 800x600 640x480 - * 5051 5051 yes 76* - * 5814 5814 no 66 - * 6411 6411 no 60 - * 7408 7408 yes 75* - * 74* - * 7937 7937 yes 70* - * 9091 4545 yes 80* - * 75* 100* - * 9260 4630 yes 60* - * 10000 5000 no 70 90 - * 12500 6250 yes 47-lace* 60* - * 43-lace* - * 12699 6349 yes 75* - * 13334 6667 no 72 - * 70 - * 14815 7407 yes 100* - * 15385 7692 yes 47-lace* 60* - * 43-lace* - * 17656 4414 no 90 - * 20000 5000 no 72 - * 20203 5050 yes 75* - * 22272 5568 yes 43-lace* 70* 100* - * 25000 6250 yes 60* - * 25057 6264 no 90 - * 27778 6944 yes 56* - * 48-lace* - * 31747 7936 yes 75* - * 32052 8013 no 72 - * 39722 /6 6620 no - * 39722 /8 4965 yes 60* - */ - /* /1 /2 /4 /6 /8 */ - /* (2010) (2000) */ - if (pll_ps >= 4543 && pll_ps <= 4549) { - best_mult = 169; /*u220.0 110.0 54.99 36.663 27.497 */ - best_div1 = 11; /* 4546 9092 18184 27276 36367 */ - } else if (pll_ps >= 4596 && pll_ps <= 4602) { - best_mult = 243; /* 217.5 108.7 54.36 36.243 27.181 */ - best_div1 = 16; /* 4599 9197 18395 27592 36789 */ - } else if (pll_ps >= 4627 && pll_ps <= 4633) { - best_mult = 181; /*u216.0, 108.0, 54.00, 36.000 27.000 */ - best_div1 = 12; /* 4630 9260 18520 27780 37040 */ - } else if (pll_ps >= 4962 && pll_ps <= 4968) { - best_mult = 211; /*u201.0, 100.5, 50.25, 33.500 25.125 */ - best_div1 = 15; /* 4965 9930 19860 29790 39720 */ - } else if (pll_ps >= 5005 && pll_ps <= 5011) { - best_mult = 251; /* 200.0 99.8 49.92 33.280 24.960 */ - best_div1 = 18; /* 5008 10016 20032 30048 40064 */ - } else if (pll_ps >= 5047 && pll_ps <= 5053) { - best_mult = 83; /*u198.0, 99.0, 49.50, 33.000 24.750 */ - best_div1 = 6; /* 5050 10100 20200 30300 40400 */ - } else if (pll_ps >= 5490 && pll_ps <= 5496) { - best_mult = 89; /* 182.0 91.0 45.51 30.342 22.756 */ - best_div1 = 7; /* 5493 10986 21972 32958 43944 */ - } else if (pll_ps >= 5567 && pll_ps <= 5573) { - best_mult = 163; /*u179.5 89.8 44.88 29.921 22.441 */ - best_div1 = 13; /* 5570 11140 22281 33421 44562 */ - } else if (pll_ps >= 6246 && pll_ps <= 6252) { - best_mult = 190; /*u160.0, 80.0, 40.00, 26.671 20.003 */ - best_div1 = 17; /* 6249 12498 24996 37494 49992 */ - } else if (pll_ps >= 6346 && pll_ps <= 6352) { - best_mult = 209; /*u158.0, 79.0, 39.50, 26.333 19.750 */ - best_div1 = 19; /* 6349 12698 25396 38094 50792 */ - } else if (pll_ps >= 6648 && pll_ps <= 6655) { - best_mult = 210; /*u150.3 75.2 37.58 25.057 18.792 */ - best_div1 = 20; /* 6652 13303 26606 39909 53213 */ - } else if (pll_ps >= 6943 && pll_ps <= 6949) { - best_mult = 181; /*u144.0 72.0 36.00 23.996 17.997 */ - best_div1 = 18; /* 6946 13891 27782 41674 55565 */ - } else if (pll_ps >= 7404 && pll_ps <= 7410) { - best_mult = 198; /*u134.0 67.5 33.75 22.500 16.875 */ - best_div1 = 21; /* 7407 14815 29630 44445 59260 */ - } else if (pll_ps >= 7689 && pll_ps <= 7695) { - best_mult = 227; /*u130.0 65.0 32.50 21.667 16.251 */ - best_div1 = 25; /* 7692 15384 30768 46152 61536 */ - } else if (pll_ps >= 7808 && pll_ps <= 7814) { - best_mult = 152; /* 128.0 64.0 32.00 21.337 16.003 */ - best_div1 = 17; /* 7811 15623 31245 46868 62490 */ - } else if (pll_ps >= 7934 && pll_ps <= 7940) { - best_mult = 44; /*u126.0 63.0 31.498 20.999 15.749 */ - best_div1 = 5; /* 7937 15874 31748 47622 63494 */ - } else - return -EINVAL; -#endif + /* * Step 3: * combine values @@ -1018,7 +942,7 @@ cfb->fb.changevar(con); cyber2000fb_update_start(cfb, var); - cyber2000fb_set_timing(&hw); + cyber2000fb_set_timing(cfb, &hw); fb_set_cmap(&cfb->fb.cmap, 1, cyber2000_setcolreg, &cfb->fb); return 0; @@ -1195,26 +1119,32 @@ /* * Enable access to the extended registers - * Bug: this should track the usage of these registers */ -static void cyber2000fb_enable_extregs(void) +static void cyber2000fb_enable_extregs(struct cfb_info *cfb) { - int old; + cfb->func_use_count += 1; - old = cyber2000_grphr(FUNC_CTL); - cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL); + if (cfb->func_use_count == 1) { + int old; + + old = cyber2000_grphr(FUNC_CTL); + cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL); + } } /* * Disable access to the extended registers - * Bug: this should track the usage of these registers */ -static void cyber2000fb_disable_extregs(void) +static void cyber2000fb_disable_extregs(struct cfb_info *cfb) { - int old; + if (cfb->func_use_count == 1) { + int old; - old = cyber2000_grphr(FUNC_CTL); - cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL); + old = cyber2000_grphr(FUNC_CTL); + cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL); + } + + cfb->func_use_count -= 1; } /* @@ -1227,7 +1157,7 @@ /* * Attach a capture/tv driver to the core CyberX0X0 driver. */ -int cyber2000fb_attach(struct cyberpro_info *info) +int cyber2000fb_attach(struct cyberpro_info *info, int idx) { if (int_cfb_info != NULL) { info->dev = int_cfb_info->dev; @@ -1236,6 +1166,7 @@ info->fb_size = int_cfb_info->fb.fix.smem_len; info->enable_extregs = cyber2000fb_enable_extregs; info->disable_extregs = cyber2000fb_disable_extregs; + info->info = int_cfb_info; strncpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name)); @@ -1248,7 +1179,7 @@ /* * Detach a capture/tv driver from the core CyberX0X0 driver. */ -void cyber2000fb_detach(void) +void cyber2000fb_detach(int idx) { MOD_DEC_USE_COUNT; } @@ -1281,8 +1212,8 @@ } static char igs_regs[] __devinitdata = { - 0x10, 0x10, 0x12, 0x00, 0x13, 0x00, - 0x31, 0x00, 0x32, 0x00, 0x33, 0x01, + 0x12, 0x00, 0x13, 0x00, + 0x31, 0x00, 0x32, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x01, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, @@ -1290,22 +1221,129 @@ 0x74, 0x0b, 0x75, 0x17, 0x76, 0x00, 0x7a, 0xc8 }; -static inline void cyberpro_init_hw(struct cfb_info *cfb) +/* + * We need to wake up the CyberPro, and make sure its in linear memory + * mode. Unfortunately, this is specific to the platform and card that + * we are running on. + * + * On x86 and ARM, should we be initialising the CyberPro first via the + * IO registers, and then the MMIO registers to catch all cases? Can we + * end up in the situation where the chip is in MMIO mode, but not awake + * on an x86 system? + * + * Note that on the NetWinder, the firmware automatically detects the + * type, width and size, and leaves this in extended registers 0x71 and + * 0x72 for us. + */ +static inline void cyberpro_init_hw(struct cfb_info *cfb, int at_boot) { int i; /* - * Wake up the CyberPro + * Wake up the CyberPro. */ +#ifdef __sparc__ +#ifdef __sparc_v9__ +#error "You loose, consult DaveM." +#else + /* + * SPARC does not have an "outb" instruction, so we generate + * I/O cycles storing into a reserved memory space at + * physical address 0x3000000 + */ + { + unsigned char *iop; + + iop = ioremap(0x3000000, 0x5000); + if (iop == NULL) { + prom_printf("iga5000: cannot map I/O\n"); + return -ENOMEM; + } + + writeb(0x18, iop + 0x46e8); + writeb(0x01, iop + 0x102); + writeb(0x08, iop + 0x46e8); + writeb(0x33, iop + 0x3ce); + writeb(0x01, iop + 0x3cf); + + iounmap((void *)iop); + } +#endif + + if (at_boot) { + /* + * Use mclk from BIOS. Only read this if we're + * initialising this card for the first time. + * FIXME: what about hotplug? + */ + cfb->mclk_mult = cyber2000_grphr(MCLK_MULT); + cfb->mclk_div = cyber2000_grphr(MCLK_DIV); + } +#endif +#ifdef __i386__ + /* + * x86 is simple, we just do regular outb's instead of + * cyber2000_outb. + */ + outb(0x18, 0x46e8); + outb(0x01, 0x102); + outb(0x08, 0x46e8); + outb(0x33, 0x3ce); + outb(0x01, 0x3cf); + + if (at_boot) { + /* + * Use mclk from BIOS. Only read this if we're + * initialising this card for the first time. + * FIXME: what about hotplug? + */ + cfb->mclk_mult = cyber2000_grphr(MCLK_MULT); + cfb->mclk_div = cyber2000_grphr(MCLK_DIV); + } +#endif +#ifdef __arm__ cyber2000_outb(0x18, 0x46e8); cyber2000_outb(0x01, 0x102); cyber2000_outb(0x08, 0x46e8); + cyber2000_outb(0x33, 0x3ce); + cyber2000_outb(0x01, 0x3cf); + + /* + * MCLK on the NetWinder is fixed at 75MHz + */ + cfb->mclk_mult = 0xdb; + cfb->mclk_div = 0x54; +#endif /* * Initialise the CyberPro */ for (i = 0; i < sizeof(igs_regs); i += 2) cyber2000_grphw(igs_regs[i], igs_regs[i+1]); + + if (at_boot) { + /* + * get the video RAM size and width from the VGA register. + * This should have been already initialised by the BIOS, + * but if it's garbage, claim default 1MB VRAM (woody) + */ + cfb->mem_ctl1 = cyber2000_grphr(MEM_CTL1); + cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2); + } else { + /* + * Reprogram the MEM_CTL1 and MEM_CTL2 registers + */ + cyber2000_grphw(MEM_CTL1, cfb->mem_ctl1); + cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2); + } + + /* + * Ensure thatwe are using the correct PLL. + * (CyberPro 5000's may be programmed to use + * an additional set of PLLs. + */ + cyber2000_outb(0xba, 0x3ce); + cyber2000_outb(cyber2000_inb(0x3cf) & 0x80, 0x3cf); } static struct cfb_info * __devinit @@ -1323,6 +1361,7 @@ cfb->currcon = -1; cfb->dev = dev; + cfb->ref_ps = 69842; cfb->divisors[0] = 1; cfb->divisors[1] = 2; cfb->divisors[2] = 4; @@ -1466,13 +1505,6 @@ u_long smem_size; int err; - /* - * We can only accept one CyberPro device at the moment. We can - * kill this once int_cfb_info and CyberRegs have been killed. - */ - if (int_cfb_info) - return -EBUSY; - err = pci_enable_device(dev); if (err) return err; @@ -1486,14 +1518,7 @@ if (err) goto failed; - cyberpro_init_hw(cfb); - - /* - * get the video RAM size and width from the VGA register. - * This should have been already initialised by the BIOS, - * but if it's garbage, claim default 1MB VRAM (woody) - */ - cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2); + cyberpro_init_hw(cfb, 1); switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) { case MEM_CTL2_SIZE_4MB: smem_size = 0x00400000; break; @@ -1519,6 +1544,12 @@ cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb); + /* + * Calculate the hsync and vsync frequencies. Note that + * we split the 1e12 constant up so that we can preserve + * the precision and fit the results into 32-bit registers. + * (1953125000 * 512 = 1e12) + */ h_sync = 1953125000 / cfb->fb.var.pixclock; h_sync = h_sync * 512 / (cfb->fb.var.xres + cfb->fb.var.left_margin + cfb->fb.var.right_margin + cfb->fb.var.hsync_len); @@ -1538,7 +1569,8 @@ * Our driver data */ dev->driver_data = cfb; - int_cfb_info = cfb; + if (int_cfb_info == NULL) + int_cfb_info = cfb; return 0; @@ -1555,7 +1587,15 @@ struct cfb_info *cfb = (struct cfb_info *)dev->driver_data; if (cfb) { - unregister_framebuffer(&cfb->fb); + /* + * If unregister_framebuffer fails, then + * we will be leaving hooks that could cause + * oopsen laying around. + */ + if (unregister_framebuffer(&cfb->fb)) + printk(KERN_WARNING "%s: danger Will Robinson, " + "danger danger! Oopsen imminent!\n", + cfb->fb.fix.id); cyberpro_unmap_smem(cfb); cyberpro_unmap_mmio(cfb); cyberpro_free_fb_info(cfb); @@ -1565,7 +1605,8 @@ * valid. */ dev->driver_data = NULL; - int_cfb_info = NULL; + if (cfb == int_cfb_info) + int_cfb_info = NULL; } } @@ -1581,12 +1622,7 @@ struct cfb_info *cfb = (struct cfb_info *)dev->driver_data; if (cfb) { - cyberpro_init_hw(cfb); - - /* - * Reprogram the MEM_CTL2 register - */ - cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2); + cyberpro_init_hw(cfb, 0); /* * Restore the old video mode and the palette. @@ -1620,7 +1656,8 @@ /* * I don't think we can use the "module_init" stuff here because - * the fbcon stuff may not be initialised yet. + * the fbcon stuff may not be initialised yet. Hence the #ifdef + * around module_init. */ int __init cyber2000fb_init(void) { @@ -1636,5 +1673,3 @@ module_init(cyber2000fb_init); #endif module_exit(cyberpro_exit); - -MODULE_DEVICE_TABLE(pci, cyberpro_pci_table); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/video/cyber2000fb.h linux.ac/drivers/video/cyber2000fb.h --- linux.vanilla/drivers/video/cyber2000fb.h Thu May 25 17:38:11 2000 +++ linux.ac/drivers/video/cyber2000fb.h Sun Jun 4 21:18:26 2000 @@ -127,6 +127,8 @@ #define CAP_DDA_Y_INIT 0x6c #define CAP_DDA_Y_INC 0x6e +#define MEM_CTL1 0x71 + #define MEM_CTL2 0x72 #define MEM_CTL2_SIZE_2MB 0x01 #define MEM_CTL2_SIZE_4MB 0x02 @@ -156,6 +158,11 @@ #define CAP_MODE1_MIRRORY 0x40 /* mirror vertically */ #define CAP_MODE1_MIRRORX 0x80 /* mirror horizontally */ +#define DCLK_MULT 0xb0 +#define DCLK_DIV 0xb1 +#define MCLK_MULT 0xb2 +#define MCLK_DIV 0xb3 + #define CAP_MODE2 0xa5 #define Y_TV_CTL 0xae @@ -281,6 +288,11 @@ #define CO_REG_DEST_PTR 0xbf178 #define CO_REG_DEST_WIDTH 0xbf218 +/* + * Private structure + */ +struct cfb_info; + struct cyberpro_info { struct pci_dev *dev; unsigned char *regs; @@ -289,16 +301,27 @@ unsigned int fb_size; /* - * Use these to enable the BM or TV registers. + * The following is a pointer to be passed into the + * functions below. The modules outside the main + * cyber2000fb.c driver have no knowledge as to what + * is within this structure. + */ + struct cfb_info *info; + + /* + * Use these to enable the BM or TV registers. In an SMP + * environment, these two function pointers should only be + * called from the module_init() or module_exit() + * functions. */ - void (*enable_extregs)(void); - void (*disable_extregs)(void); + void (*enable_extregs)(struct cfb_info *); + void (*disable_extregs)(struct cfb_info *); }; /* * Note! Writing to the Cyber20x0 registers from an interrupt * routine is definitely a bad idea atm. */ -int cyber2000fb_attach(struct cyberpro_info *info); -void cyber2000fb_detach(void); +int cyber2000fb_attach(struct cyberpro_info *info, int idx); +void cyber2000fb_detach(int idx); 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/sa1100fb.c linux.ac/drivers/video/sa1100fb.c --- linux.vanilla/drivers/video/sa1100fb.c Thu May 25 17:38:11 2000 +++ linux.ac/drivers/video/sa1100fb.c Sun Jun 4 21:17:38 2000 @@ -53,74 +53,23 @@ /* * Debug macros */ -// #define DEBUG +//#define DEBUG #ifdef DEBUG -# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) +# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) #else # define DPRINTK(fmt, args...) #endif -/* - * The MAX_x defines are used to specify the maximum ranges for - * parameters that affect the size of the frame buffer memory - * region. Since the frame buffer memory is not dynamically - * alocated, the maximum size that will be used is allocated. - */ -#if defined (CONFIG_SA1100_PENNY) - -#define MAX_BITS_PER_PIXEL 8 -#define MAX_SCREEN_SIZE_H 640 -#define MAX_SCREEN_SIZE_V 480 - -#elif defined(CONFIG_SA1100_BRUTUS) - -#define MAX_BITS_PER_PIXEL 8 -#define MAX_SCREEN_SIZE_H 320 -#define MAX_SCREEN_SIZE_V 240 - -#elif defined (CONFIG_SA1100_THINCLIENT) - -#define MAX_BITS_PER_PIXEL 8 -/*#define MAX_BITS_PER_PIXEL 16*/ - -#define MAX_SCREEN_SIZE_H 640 -#define MAX_SCREEN_SIZE_V 480 - -#elif defined(CONFIG_SA1100_TIFON) - -#define MAX_BITS_PER_PIXEL 4 -#define MAX_SCREEN_SIZE_H 640 -#define MAX_SCREEN_SIZE_V 200 - -#define REVERSE_VIDEO_4BIT - -#elif defined(CONFIG_SA1100_LART) - -#define MAX_BITS_PER_PIXEL 4 -#define MAX_SCREEN_SIZE_H 320 -#define MAX_SCREEN_SIZE_V 240 - -#endif - -/* Default resolutions */ -#if defined(CONFIG_SA1100_PENNY) -#define DEFAULT_XRES 640 -#define DEFAULT_YRES 480 -#define DEFAULT_BPP 8 -#else -#define DEFAULT_XRES MAX_SCREEN_SIZE_H -#define DEFAULT_YRES MAX_SCREEN_SIZE_V -#define DEFAULT_BPP MAX_BITS_PER_PIXEL -#endif - /* Memory size macros for determining required FrameBuffer size */ -#define MAX_PALETTE_NUM_ENTRIES 256 -#define ADJUSTED_MAX_BITS_PER_PIXEL (MAX_BITS_PER_PIXEL > 8 ? 16 : MAX_BITS_PER_PIXEL) -#define MAX_PALETTE_MEM_SIZE (MAX_PALETTE_NUM_ENTRIES * 2) -#define MAX_PIXEL_MEM_SIZE ((MAX_SCREEN_SIZE_H * MAX_SCREEN_SIZE_V * ADJUSTED_MAX_BITS_PER_PIXEL ) / 8) -#define MAX_FRAMEBUFFER_MEM_SIZE (MAX_PIXEL_MEM_SIZE + MAX_PALETTE_MEM_SIZE + 32) -#define ALLOCATED_FB_MEM_SIZE (PAGE_ALIGN (MAX_FRAMEBUFFER_MEM_SIZE + PAGE_SIZE * 2)) +#define MAX_PALETTE_NUM_ENTRIES 256 +#define MAX_PALETTE_MEM_SIZE (MAX_PALETTE_NUM_ENTRIES * 2) +#define MAX_PIXEL_MEM_SIZE \ + ((current_par.max_xres * current_par.max_yres * current_par.max_bpp)/8) +#define MAX_FRAMEBUFFER_MEM_SIZE \ + (MAX_PIXEL_MEM_SIZE + MAX_PALETTE_MEM_SIZE + 32) +#define ALLOCATED_FB_MEM_SIZE \ + (PAGE_ALIGN(MAX_FRAMEBUFFER_MEM_SIZE + PAGE_SIZE * 2)) #define SA1100_PALETTE_MEM_SIZE(bpp) (((bpp)==8?256:16)*2) #define SA1100_PALETTE_MODE_VAL(bpp) (((bpp) & 0x018) << 9) @@ -137,30 +86,34 @@ #define SA1100_NAME "SA1100" #define NR_MONTYPES 1 -static u_char *VideoMemRegion = NULL; -static u_char *VideoMemRegion_phys = NULL; +static u_char *VideoMemRegion; +static u_char *VideoMemRegion_phys; /* Local LCD controller parameters */ /* These can be reduced by making better use of fb_var_screeninfo parameters. */ /* Several duplicates exist in the two structures. */ struct sa1100fb_par { - u_char *p_screen_base; - u_char *v_screen_base; - u_short *p_palette_base; - u_short *v_palette_base; - unsigned long screen_size; - unsigned int palette_size; - unsigned int xres; - unsigned int yres; - unsigned int xres_virtual; - unsigned int yres_virtual; - unsigned int bits_per_pixel; - signed int montype; - unsigned int currcon; - unsigned int visual; - unsigned int allow_modeset : 1; - unsigned int active_lcd : 1; - volatile u_char controller_state; + u_char *p_screen_base; + u_char *v_screen_base; + u_short *p_palette_base; + u_short *v_palette_base; + unsigned long screen_size; + unsigned int palette_size; + unsigned int max_xres; + unsigned int max_yres; + unsigned int xres; + unsigned int yres; + unsigned int xres_virtual; + unsigned int yres_virtual; + unsigned int max_bpp; + unsigned int bits_per_pixel; + signed int montype; + unsigned int currcon; + unsigned int visual; + unsigned int allow_modeset : 1; + unsigned int active_lcd : 1; + unsigned int inv_4bpp : 1; + volatile u_char controller_state; }; /* Shadows for LCD controller registers */ @@ -177,7 +130,7 @@ 30000, 70000, 50, 65, 0 /* Generic */ }; -static struct display global_disp; /* Initial (default) Display Settings */ +static struct display global_disp; /* Initial (default) Display Settings */ static struct fb_info fb_info; static struct sa1100fb_par current_par; static struct fb_var_screeninfo __initdata init_var = {}; @@ -231,18 +184,16 @@ static inline u_short sa1100fb_palette_encode(u_int regno, u_int red, u_int green, u_int blue, u_int trans) { - u_short pal; - + u_int pal; if(current_par.bits_per_pixel == 4){ /* * RGB -> luminance is defined to be * Y = 0.299 * R + 0.587 * G + 0.114 * B */ - pal = ((19595 * red + 38470 * green + 7471 * blue) >> 28) & 0x00f; -#ifdef REVERSE_VIDEO_4BIT - pal = 15 - pal; -#endif + pal = (19595 * red + 38470 * green + 7471 * blue) >> 28; + if( current_par.inv_4bpp ) + pal = 15 - pal; } else{ pal = ((red >> 4) & 0xf00); @@ -268,9 +219,8 @@ pal = sa1100fb_palette_read(regno); if( current_par.bits_per_pixel == 4){ -#ifdef REVERSE_VIDEO_4BIT - pal = 15 - pal; -#endif + if( current_par.inv_4bpp ) + pal = 15 - pal; pal &= 0x000f; pal |= pal << 4; pal |= pal << 8; @@ -317,6 +267,7 @@ { int err = 0; + DPRINTK("current_par.visual=%d\n", current_par.visual); if (con == current_par.currcon) err = fb_get_cmap(cmap, kspc, sa1100fb_getcolreg, info); else if (fb_display[con].cmap.len) @@ -329,13 +280,13 @@ static int sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, - struct fb_info *info) + struct fb_info *info) { int err = 0; + DPRINTK("current_par.visual=%d\n", current_par.visual); if (!fb_display[con].cmap.len) err = fb_alloc_cmap(&fb_display[con].cmap, - current_par.palette_size, 0); if (!err) { if (con == current_par.currcon) @@ -372,6 +323,7 @@ var->bits_per_pixel = par->bits_per_pixel; + DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); switch(var->bits_per_pixel) { case 2: case 4: @@ -418,16 +370,17 @@ par->xres = MIN_XRES; if ((par->yres = var->yres) < MIN_YRES) par->yres = MIN_YRES; - if (par->xres > MAX_SCREEN_SIZE_H) - par->xres = MAX_SCREEN_SIZE_H; - if (par->yres > MAX_SCREEN_SIZE_V) - par->yres = MAX_SCREEN_SIZE_V; - par->xres_virtual = + if (par->xres > current_par.max_xres) + par->xres = current_par.max_xres; + if (par->yres > current_par.max_yres) + par->yres = current_par.max_yres; + par->xres_virtual = var->xres_virtual < par->xres ? par->xres : var->xres_virtual; par->yres_virtual = var->yres_virtual < par->yres ? par->yres : var->yres_virtual; par->bits_per_pixel = var->bits_per_pixel; + DPRINTK("par->bits_per_pixel=%d\n", par->bits_per_pixel); switch (par->bits_per_pixel) { #ifdef FBCON_HAS_CFB4 case 4: @@ -444,38 +397,38 @@ #ifdef FBCON_HAS_CFB16 case 16: /* RGB 555 */ par->visual = FB_VISUAL_TRUECOLOR; - par->palette_size = -1; + par->palette_size = 0; break; #endif default: return -EINVAL; } - palette_mem_size = SA1100_PALETTE_MEM_SIZE(par->bits_per_pixel); - palette_mem_phys = (u_long)VideoMemRegion_phys + PAGE_SIZE - - palette_mem_size; - par->p_palette_base = (u_short *)palette_mem_phys; - par->v_palette_base = (u_short *)((u_long)VideoMemRegion + PAGE_SIZE - palette_mem_size); - par->p_screen_base = (u_char *)((u_long)VideoMemRegion_phys + PAGE_SIZE); - par->v_screen_base = (u_char *)((u_long)VideoMemRegion + PAGE_SIZE); - - DPRINTK("p_palette_base = 0x%08lx\n",(u_long)par->p_palette_base); - DPRINTK("v_palette_base = 0x%08lx\n",(u_long)par->v_palette_base); - DPRINTK("p_screen_base = 0x%08lx\n",(u_long)par->p_screen_base); - DPRINTK("v_screen_base = 0x%08lx\n",(u_long)par->v_screen_base); - DPRINTK("VideoMemRegion = 0x%08lx\n",(u_long)VideoMemRegion); - DPRINTK("VideoMemRegion_phys = 0x%08lx\n",(u_long)VideoMemRegion_phys); + palette_mem_size = SA1100_PALETTE_MEM_SIZE(par->bits_per_pixel); + palette_mem_phys = (u_long)VideoMemRegion_phys + PAGE_SIZE - palette_mem_size; + par->p_palette_base = (u_short *)palette_mem_phys; + par->v_palette_base = (u_short *)((u_long)VideoMemRegion + PAGE_SIZE - palette_mem_size); + par->p_screen_base = (u_char *)((u_long)VideoMemRegion_phys + PAGE_SIZE); + par->v_screen_base = (u_char *)((u_long)VideoMemRegion + PAGE_SIZE); + + DPRINTK("p_palette_base = 0x%08lx\n",(u_long)par->p_palette_base); + DPRINTK("v_palette_base = 0x%08lx\n",(u_long)par->v_palette_base); + DPRINTK("p_screen_base = 0x%08lx\n",(u_long)par->p_screen_base); + DPRINTK("v_screen_base = 0x%08lx\n",(u_long)par->v_screen_base); + DPRINTK("VideoMemRegion = 0x%08lx\n",(u_long)VideoMemRegion); + DPRINTK("VideoMemRegion_phys = 0x%08lx\n",(u_long)VideoMemRegion_phys); return 0; } static int sa1100fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) { - struct sa1100fb_par par; + struct sa1100fb_par par; + DPRINTK("con=%d\n", con); if (con == -1) { - sa1100fb_get_par(&par); - sa1100fb_encode_var(var, &par); + sa1100fb_get_par(&par); + sa1100fb_encode_var(var, &par); } else *var = fb_display[con].var; @@ -491,7 +444,7 @@ { struct display *display; int err, chgvar = 0; - struct sa1100fb_par par; + struct sa1100fb_par par; if (con >= 0) display = &fb_display[con]; /* Display settings for console */ @@ -500,18 +453,18 @@ DPRINTK("xres = %d, yres = %d\n",var->xres, var->yres); - // Decode var contents into a par structure, adjusting any - // out of range values. + /* Decode var contents into a par structure, adjusting any */ + /* out of range values. */ if ((err = sa1100fb_decode_var(var, &par))) return err; - // Store adjusted par values into var structure - sa1100fb_encode_var(var, &par); + // Store adjusted par values into var structure + sa1100fb_encode_var(var, &par); - if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST) + if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST) return 0; - else if (((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) && - ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NXTOPEN)) - return -EINVAL; + else if (((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) && + ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NXTOPEN)) + return -EINVAL; if (con >= 0) { if ((display->var.xres != var->xres) || @@ -525,6 +478,7 @@ (memcmp(&display->var.blue, &var->blue, sizeof(var->blue)))) chgvar = 1; } + DPRINTK("chgvar=%d\n", chgvar); display->var = *var; display->screen_base = par.v_screen_base; @@ -539,6 +493,8 @@ display->can_soft_blank = 1; display->inverse = 0; + DPRINTK("display->var.bits_per_pixel=%d xres=%d yres=%d display->dispsw=%p\n", + display->var.bits_per_pixel, var->xres, var->yres, display->dispsw); switch (display->var.bits_per_pixel) { #ifdef FBCON_HAS_CFB4 case 4: @@ -560,13 +516,13 @@ break; } - // If the console has changed and the console has defined - // a changevar function, call that function. + /* If the console has changed and the console has defined */ + /* a changevar function, call that function. */ if (chgvar && info && info->changevar) info->changevar(con); - // If the current console is selected, update the palette - if (con == current_par.currcon) + // If the current console is selected and it's not truecolor, update the palette + if ((con == current_par.currcon) && (current_par.visual != FB_VISUAL_TRUECOLOR)) { struct fb_cmap *cmap; @@ -575,10 +531,11 @@ cmap = &display->cmap; else cmap = fb_default_cmap(current_par.palette_size); + DPRINTK("visual=%d palette_size=%d cmap=%p\n", current_par.visual, current_par.palette_size, cmap); fb_set_cmap(cmap, 1, sa1100fb_setcolreg, info); - sa1100fb_activate_var(var); + sa1100fb_activate_var(var); } return 0; } @@ -606,7 +563,7 @@ else display = &global_disp; /* Default display settings */ - fix->smem_start = current_par.p_screen_base; + fix->smem_start = (unsigned long)current_par.p_screen_base; fix->smem_len = current_par.screen_size; fix->type = display->type; fix->type_aux = display->type_aux; @@ -627,78 +584,118 @@ strcpy(fb_info.modename, SA1100_NAME); strcpy(fb_info.fontname, "Acorn8x8"); - fb_info.node = -1; - fb_info.flags = FBINFO_FLAG_DEFAULT; - fb_info.fbops = &sa1100fb_ops; - fb_info.monspecs = monspecs; - fb_info.disp = &global_disp; - fb_info.changevar = NULL; - fb_info.switch_con = sa1100fb_switch; - fb_info.updatevar = sa1100fb_updatevar; - fb_info.blank = sa1100fb_blank; + fb_info.node = -1; + fb_info.flags = FBINFO_FLAG_DEFAULT; + fb_info.fbops = &sa1100fb_ops; + fb_info.monspecs = monspecs; + fb_info.disp = &global_disp; + fb_info.changevar = NULL; + fb_info.switch_con = sa1100fb_switch; + fb_info.updatevar = sa1100fb_updatevar; + fb_info.blank = sa1100fb_blank; /* * setup initial parameters */ memset(&init_var, 0, sizeof(init_var)); - init_var.xres = DEFAULT_XRES; - init_var.yres = DEFAULT_YRES; - init_var.xres_virtual = init_var.xres; - init_var.yres_virtual = init_var.yres; - init_var.xoffset = 0; - init_var.yoffset = 0; - init_var.bits_per_pixel = DEFAULT_BPP; - - init_var.transp.length = 0; - init_var.nonstd = 0; - init_var.activate = FB_ACTIVATE_NOW; - init_var.height = -1; - init_var.width = -1; - init_var.vmode = FB_VMODE_NONINTERLACED; - -#if defined(CONFIG_SA1100_PENNY) - init_var.red.length = 4; - init_var.green = init_var.red; - init_var.blue = init_var.red; - init_var.sync = 0; -#elif defined(CONFIG_SA1100_BRUTUS) - init_var.red.length = 4; - init_var.green = init_var.red; - init_var.blue = init_var.red; - init_var.sync = 0; -#elif defined(CONFIG_SA1100_THINCLIENT) - init_var.red.length = 4; - init_var.green = init_var.red; - init_var.blue = init_var.red; - init_var.sync = 0; -#elif defined(CONFIG_SA1100_TIFON) - init_var.red.length = 4; - init_var.green = init_var.red; - init_var.blue = init_var.red; - init_var.grayscale = 1; - init_var.pixclock = 150000; - init_var.left_margin = 20; - init_var.right_margin = 255; - init_var.upper_margin = 20; - init_var.lower_margin = 0; - init_var.hsync_len = 2; - init_var.vsync_len = 1; - init_var.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT; - init_var.vmode = 0; -#elif defined(CONFIG_SA1100_LART) - init_var.red.length = 4; - init_var.green = init_var.red; - init_var.blue = init_var.red; - init_var.grayscale = 1; - init_var.pixclock = 150000; - init_var.sync = 0; -#endif + init_var.transp.length = 0; + init_var.nonstd = 0; + init_var.activate = FB_ACTIVATE_NOW; + init_var.xoffset = 0; + init_var.yoffset = 0; + init_var.height = -1; + init_var.width = -1; + init_var.vmode = FB_VMODE_NONINTERLACED; + + if (machine_is_assabet()) { + current_par.max_xres = 320; + current_par.max_yres = 240; + current_par.max_bpp = 16; + init_var.red.length = 5; + init_var.green.length = 6; + init_var.blue.length = 5; + init_var.grayscale = 0; + init_var.sync = 0; + } else if (machine_is_bitsy()) { + current_par.max_xres = 320; + current_par.max_yres = 240; + current_par.max_bpp = 16; + init_var.red.length = 5; + init_var.green.length = 6; + init_var.blue.length = 5; + init_var.grayscale = 0; + } else if (machine_is_brutus()) { + current_par.max_xres = 320; + current_par.max_yres = 240; + current_par.max_bpp = 8; + init_var.red.length = 4; + init_var.green = init_var.red; + init_var.blue = init_var.red; + init_var.sync = 0; + } else if (machine_is_lart()) { + current_par.max_xres = 320; + current_par.max_yres = 240; + current_par.max_bpp = 4; + init_var.red.length = 4; + init_var.green = init_var.red; + init_var.blue = init_var.red; + init_var.grayscale = 1; + init_var.pixclock = 150000; + init_var.sync = 0; + } else if (machine_is_penny()) { + current_par.max_xres = 640; + current_par.max_yres = 480; + current_par.max_bpp = 8; + init_var.red.length = 4; + init_var.green = init_var.red; + init_var.blue = init_var.red; + init_var.sync = 0; + } else if (machine_is_thinclient() || machine_is_graphicsclient()) { + current_par.max_xres = 640; + current_par.max_yres = 480; + current_par.max_bpp = 8; + init_var.red.length = 4; + init_var.green = init_var.red; + init_var.blue = init_var.red; + init_var.sync = 0; + } else if (machine_is_tifon()) { + current_par.max_xres = 640; + current_par.max_yres = 200; + current_par.max_bpp = 4; + current_par.inv_4bpp = 1; + init_var.red.length = 4; + init_var.green = init_var.red; + init_var.blue = init_var.red; + init_var.grayscale = 1; + init_var.pixclock = 150000; + init_var.left_margin = 20; + init_var.right_margin = 255; + init_var.upper_margin = 20; + init_var.lower_margin = 0; + init_var.hsync_len = 2; + init_var.vsync_len = 1; + init_var.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT; + init_var.vmode = 0; + } - current_par.montype = -1; - current_par.currcon = -1; - current_par.allow_modeset = 1; - current_par.controller_state = LCD_MODE_DISABLED; + current_par.p_palette_base = NULL; + current_par.v_palette_base = NULL; + current_par.p_screen_base = NULL; + current_par.v_screen_base = NULL; + current_par.palette_size = MAX_PALETTE_NUM_ENTRIES; + current_par.screen_size = MAX_PIXEL_MEM_SIZE; + current_par.montype = -1; + current_par.currcon = -1; + current_par.allow_modeset = 1; + current_par.controller_state = LCD_MODE_DISABLED; + + init_var.xres = current_par.max_xres; + init_var.yres = current_par.max_yres; + init_var.xres_virtual = init_var.xres; + init_var.yres_virtual = init_var.yres; + init_var.bits_per_pixel = current_par.max_bpp; + } @@ -723,6 +720,8 @@ if (VideoMemRegion != NULL) return -EINVAL; + DPRINTK("-1-"); + /* Find order required to allocate enough memory for framebuffer */ required_pages = ALLOCATED_FB_MEM_SIZE >> PAGE_SHIFT; for (order = 0 ; required_pages >> order ; order++) {;} @@ -741,7 +740,7 @@ free_page((u_int)allocated_region + ((extra_pages-1) << PAGE_SHIFT)); /* Set reserved flag for fb memory to allow it to be remapped into */ - /* user space by the common fbmem driver using remap_page_range(). */ + /* user space by the common fbmem driver using remap_page_range(). */ for(i = MAP_NR(VideoMemRegion); i < MAP_NR(VideoMemRegion + ALLOCATED_FB_MEM_SIZE); i++) set_bit(PG_reserved, &mem_map[i].flags); @@ -753,6 +752,7 @@ L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE); + memset(VideoMemRegion, 0xAA, ALLOCATED_FB_MEM_SIZE); return (VideoMemRegion == NULL ? -EINVAL : 0); } @@ -776,16 +776,21 @@ }; -static int get_pcd(unsigned int pixclock) +static inline int get_pcd(unsigned int pixclock) { - unsigned int pcd; - pcd = frequency[PPCR &0xf] / 1000; - pcd *= pixclock/1000; - return pcd / 10000000 * 12; - /* the last multiplication by 1.2 is to handle */ - /* sync problems */ + unsigned int pcd = 0; + + if (machine_is_tifon()) { + pcd = frequency[PPCR &0xf] / 1000; + pcd *= pixclock/1000; + pcd = pcd / 10000000 * 12; + /* the last multiplication by 1.2 is to handle */ + /* sync problems */ + } + return pcd; } + /* * sa1100fb_activate_var(): * Configures LCD Controller based on entries in var parameter. Settings are @@ -797,105 +802,138 @@ u_long flags; int pcd = get_pcd(var->pixclock); + DPRINTK("Configuring SA1100 LCD\n"); + if (current_par.p_palette_base == NULL) return -EINVAL; + DPRINTK("activating\n"); + /* Disable interrupts and save status */ save_flags_cli(flags); // disable the interrupts and save flags /* Reset the LCD Controller's DMA address if it has changed */ lcd_shadow.dbar1 = (Address)current_par.p_palette_base; -#if defined(CONFIG_SA1100_PENNY) - DPRINTK("Configuring SA1100 LCD\n"); - - DPRINTK("Configuring xres = %d, yres = %d\n",var->xres, var->yres); - - lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act + - LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + - LCCR0_DMADel(0); - lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth (65) + - LCCR1_EndLnDel (43) + LCCR1_BegLnDel(43) ; - lcd_shadow.lccr2 = LCCR2_DisHght (var->yres) + LCCR2_VrtSnchWdth (35) + - LCCR2_EndFrmDel (0) + LCCR2_BegFrmDel (0) ; - lcd_shadow.lccr3 = LCCR3_PixClkDiv(16) + - LCCR3_ACBsDiv (2) + LCCR3_ACBsCntOff + - ((var->sync & FB_SYNC_HOR_HIGH_ACT) ?LCCR3_HorSnchH:LCCR3_HorSnchL) + - ((var->sync & FB_SYNC_VERT_HIGH_ACT)?LCCR3_VrtSnchH:LCCR3_VrtSnchL); - -#elif defined(CONFIG_SA1100_BRUTUS) - DPRINTK("Configuring BRUTUS LCD\n"); - lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Pas + - LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + - LCCR0_DMADel(0); - lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(4) + - LCCR1_BegLnDel(41) + LCCR1_EndLnDel(101); - lcd_shadow.lccr2 = LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) + - LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0); - lcd_shadow.lccr3 = LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH + LCCR3_HorSnchH + - LCCR3_ACBsCntOff + LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(44); -#elif defined(CONFIG_SA1100_THINCLIENT) - DPRINTK("Configuring ThinClient LCD\n"); DPRINTK("Configuring xres = %d, yres = %d\n",var->xres, var->yres); - lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + - LCCR0_Act; - lcd_shadow.lccr1 = LCCR1_DisWdth(var->xres) +LCCR1_HorSnchWdth(10)+ - LCCR1_EndLnDel (81) + LCCR1_BegLnDel(81) ; - lcd_shadow.lccr2 = LCCR2_DisHght (var->yres) +LCCR2_VrtSnchWdth(9) + - LCCR2_EndFrmDel (20) + LCCR2_BegFrmDel (20) ; - lcd_shadow.lccr3 = LCCR3_PixClkDiv(6) + - LCCR3_ACBsDiv (2) + LCCR3_ACBsCntOff + - LCCR3_HorSnchL + LCCR3_VrtSnchL; - -#elif defined(CONFIG_SA1100_TIFON) - DPRINTK("Configuring TIFON LCD\n"); - - lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas + - LCCR0_BigEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + - LCCR0_8PixMono + LCCR0_DMADel(0); - lcd_shadow.lccr1 = LCCR1_DisWdth( var->xres ) + - LCCR1_HorSnchWdth( var->hsync_len) + - LCCR1_BegLnDel( var->left_margin) + - LCCR1_EndLnDel( var->right_margin); - lcd_shadow.lccr2 = LCCR2_DisHght( var->yres ) + - LCCR2_VrtSnchWdth( var->vsync_len )+ - LCCR2_BegFrmDel( var->upper_margin ) + - LCCR2_EndFrmDel( var->lower_margin ); - lcd_shadow.lccr3 = LCCR3_PixClkDiv( pcd ) + - LCCR3_ACBsDiv( 512 ) + - LCCR3_ACBsCnt(0) + - LCCR3_HorSnchH + LCCR3_VrtSnchH; - /* - ((current_var.sync & FB_SYNC_HOR_HIGH_ACT) ? - LCCR3_HorSnchH : LCCR3_HorSnchL) + - ((current_var.sync & FB_SYNC_VERT_HIGH_ACT) ? - LCCR3_VrtSnchH : LCCR3_VrtSnchL); - */ -#elif defined(CONFIG_SA1100_LART) - DPRINTK("Configuring LART LCD\n"); - - lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas + - LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + - LCCR0_DMADel(0); - lcd_shadow.lccr1 = LCCR1_DisWdth( var->xres ) + - LCCR1_HorSnchWdth( 2 ) + - LCCR1_BegLnDel( 4 ) + - LCCR1_EndLnDel( 2 ); - lcd_shadow.lccr2 = LCCR2_DisHght( var->yres ) + - LCCR2_VrtSnchWdth( 1 )+ - LCCR2_BegFrmDel( 0 ) + - LCCR2_EndFrmDel( 0 ); - lcd_shadow.lccr3 = LCCR3_PixClkDiv( 34 ) + - LCCR3_ACBsDiv( 512 ) + - LCCR3_ACBsCntOff + - LCCR3_HorSnchH + - LCCR3_VrtSnchH; -#endif - - /* Restore status of interrupts */ - restore_flags(flags); + if (machine_is_assabet()) { + DPRINTK("Configuring Assabet LCD\n"); + lcd_shadow.lccr0 = + LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_Act + + LCCR0_LtlEnd + LCCR0_DMADel(0); + lcd_shadow.lccr1 = + LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(4) + + LCCR1_BegLnDel(30) + LCCR1_EndLnDel(30); + lcd_shadow.lccr2 = + LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) + + LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0); + lcd_shadow.lccr3 = + LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH + + LCCR3_HorSnchH + LCCR3_ACBsCntOff + + LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(28); + } else if (machine_is_bitsy()) { + DPRINTK("Configuring Bitsy LCD\n"); + lcd_shadow.lccr0 = LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act + + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + + LCCR0_DMADel(0); + lcd_shadow.lccr1 = LCCR1_DisWdth( var->xres ) + + LCCR1_HorSnchWdth( 4 ) + + LCCR1_BegLnDel( 0x1f ) + + LCCR1_EndLnDel( 0x1f ); + lcd_shadow.lccr2 = LCCR2_DisHght( var->yres ) + + LCCR2_VrtSnchWdth( 1 )+ + LCCR2_BegFrmDel( 0 ) + + LCCR2_EndFrmDel( 0 ); + lcd_shadow.lccr3 = 15; + } else if (machine_is_brutus()) { + DPRINTK("Configuring Brutus LCD\n"); + lcd_shadow.lccr0 = + LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Pas + + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + + LCCR0_DMADel(0); + lcd_shadow.lccr1 = + LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(4) + + LCCR1_BegLnDel(41) + LCCR1_EndLnDel(101); + lcd_shadow.lccr2 = + LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) + + LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0); + lcd_shadow.lccr3 = + LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH + + LCCR3_HorSnchH + LCCR3_ACBsCntOff + + LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(44); + } else if (machine_is_lart()) { + DPRINTK("Configuring LART LCD\n"); + lcd_shadow.lccr0 = + LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas + + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + + LCCR0_DMADel(0); + lcd_shadow.lccr1 = + LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(2) + + LCCR1_BegLnDel(4) + LCCR1_EndLnDel(2); + lcd_shadow.lccr2 = + LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) + + LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0); + lcd_shadow.lccr3 = + LCCR3_PixClkDiv(34) + LCCR3_ACBsDiv(512) + + LCCR3_ACBsCntOff + LCCR3_HorSnchH + LCCR3_VrtSnchH; + } else if (machine_is_penny()) { + DPRINTK("Configuring Penny LCD\n"); + lcd_shadow.lccr0 = + LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act + + LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + + LCCR0_DMADel(0); + lcd_shadow.lccr1 = + LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(65) + + LCCR1_EndLnDel(43) + LCCR1_BegLnDel(43); + lcd_shadow.lccr2 = + LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(35) + + LCCR2_EndFrmDel(0) + LCCR2_BegFrmDel(0); + lcd_shadow.lccr3 = + LCCR3_PixClkDiv(16) + LCCR3_ACBsDiv (2) + LCCR3_ACBsCntOff + + ((var->sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HorSnchH : LCCR3_HorSnchL) + + ((var->sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); + } else if (machine_is_thinclient() || machine_is_graphicsclient()) { + DPRINTK("Configuring ThinClient LCD\n"); + lcd_shadow.lccr0 = + LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act; + lcd_shadow.lccr1 = + LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(10) + + LCCR1_EndLnDel(81) + LCCR1_BegLnDel(81); + lcd_shadow.lccr2 = + LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(9) + + LCCR2_EndFrmDel (20) + LCCR2_BegFrmDel(20); + lcd_shadow.lccr3 = + LCCR3_PixClkDiv(6) + LCCR3_ACBsDiv(2) + + LCCR3_ACBsCntOff + LCCR3_HorSnchL + LCCR3_VrtSnchL; + } else if (machine_is_tifon()) { + DPRINTK("Configuring TIFON LCD\n"); + lcd_shadow.lccr0 = + LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas + + LCCR0_BigEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + + LCCR0_8PixMono + LCCR0_DMADel(0); + lcd_shadow.lccr1 = + LCCR1_DisWdth(var->xres) + + LCCR1_HorSnchWdth(var->hsync_len) + + LCCR1_BegLnDel(var->left_margin) + + LCCR1_EndLnDel(var->right_margin); + lcd_shadow.lccr2 = + LCCR2_DisHght(var->yres) + + LCCR2_VrtSnchWdth(var->vsync_len) + + LCCR2_BegFrmDel(var->upper_margin) + + LCCR2_EndFrmDel(var->lower_margin); + lcd_shadow.lccr3 = + LCCR3_PixClkDiv(pcd) + LCCR3_ACBsDiv(512) + + LCCR3_ACBsCnt(0) + LCCR3_HorSnchH + LCCR3_VrtSnchH; + /* + ((current_var.sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HorSnchH : LCCR3_HorSnchL) + + ((current_var.sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VrtSnchH : LCCR3_VrtSnchL); + */ + } + /* Restore interrupt status */ + restore_flags(flags); if (( LCCR0 != lcd_shadow.lccr0 ) || ( LCCR1 != lcd_shadow.lccr1 ) || @@ -937,26 +975,36 @@ */ static void sa1100fb_disable_lcd_controller(void) { - DPRINTK("sa1100fb: Disabling LCD controller\n"); + DPRINTK("Disabling LCD controller\n"); /* Exit if already LCD disabled, or LDD IRQ unmasked */ if ((current_par.controller_state == LCD_MODE_DISABLED) || (!(LCCR0 & LCCR0_LDM))) { - DPRINTK("sa1100fb: LCD already disabled\n"); + DPRINTK("LCD already disabled\n"); return; } -#if defined(CONFIG_SA1100_PENNY) - FpgaLcdCS1 = 0x000; /* LCD Backlight to 0% */ - FpgaPortI &= ~LCD_ON; /* Turn off LCD Backlight */ -#elif defined(CONFIG_SA1100_TIFON) - GPCR = GPIO_GPIO(24); /* turn off display */ + if (machine_is_assabet()) { +#ifdef CONFIG_SA1100_ASSABET + BCR_clear(BCR_LCD_ON); +#endif + } else if (machine_is_bitsy()) { +#ifdef CONFIG_SA1100_BITSY + clr_bitsy_egpio(EGPIO_BITSY_LCD_ON | EGPIO_BITSY_LCD_PCI | EGPIO_BITSY_LCD_5V_ON | EGPIO_BITSY_LVDD_ON); #endif + } else if (machine_is_penny()) { +#ifdef CONFIG_SA1100_PENNY + FpgaLcdCS1 = 0x000; /* LCD Backlight to 0% */ + FpgaPortI &= ~LCD_ON; /* Turn off LCD Backlight */ +#endif + } else if (machine_is_tifon()) { + GPCR = GPIO_GPIO(24); /* turn off display */ + } - LCSR = 0; /* Clear LCD Status Register */ - LCCR0 &= ~(LCCR0_LDM); /* Enable LCD Disable Done Interrupt */ + LCSR = 0; /* Clear LCD Status Register */ + LCCR0 &= ~(LCCR0_LDM); /* Enable LCD Disable Done Interrupt */ enable_irq(IRQ_LCD); /* Enable LCD IRQ */ - LCCR0 &= ~(LCCR0_LEN); /* Disable LCD Controller */ + LCCR0 &= ~(LCCR0_LEN); /* Disable LCD Controller */ } @@ -977,7 +1025,7 @@ current_par.controller_state = LCD_MODE_DISABLE_BEFORE_ENABLE; sa1100fb_disable_lcd_controller(); } else { - DPRINTK("sa1100fb: Enabling LCD controller\n"); + DPRINTK("Enabling LCD controller\n"); /* Make sure the mode bits are present in the first palette entry */ current_par.v_palette_base[0] &= 0x0FFF; @@ -992,21 +1040,35 @@ LCCR1 = lcd_shadow.lccr1; LCCR0 = lcd_shadow.lccr0; -#if defined(CONFIG_SA1100_PENNY) - FpgaLcdCS1 = 0x0FF; /* LCD Backlight to 100% */ - FpgaPortI |= LCD_ON; /* Turn on LCD Backlight */ -#elif defined(CONFIG_SA1100_TIFON) - GPCR = GPIO_GPIO(24); /* cycle on/off-switch */ - udelay(150); - GPSR = GPIO_GPIO(24); /* turn on display */ - udelay(150); - GPSR = GPIO_GPIO(24); /* turn on display */ + if (machine_is_assabet()) { +#ifdef CONFIG_SA1100_ASSABET + BCR_set(BCR_LCD_ON); +#endif + } else if (machine_is_bitsy()) { +#ifdef CONFIG_SA1100_BITSY + set_bitsy_egpio(EGPIO_BITSY_LCD_ON | EGPIO_BITSY_LCD_PCI | EGPIO_BITSY_LCD_5V_ON | EGPIO_BITSY_LVDD_ON) + DPRINTK("DBAR1=%p\n", DBAR1); + DPRINTK("LCCR0=%x\n", LCCR0); + DPRINTK("LCCR1=%x\n", LCCR1); + DPRINTK("LCCR2=%x\n", LCCR2); + DPRINTK("LCCR3=%x\n", LCCR3); #endif + } else if (machine_is_penny()) { +#ifdef CONFIG_SA1100_PENNY + FpgaLcdCS1 = 0x0FF; /* LCD Backlight to 100% */ + FpgaPortI |= LCD_ON; /* Turn on LCD Backlight */ +#endif + } else if (machine_is_tifon()) { + GPCR = GPIO_GPIO(24); /* cycle on/off-switch */ + udelay(150); + GPSR = GPIO_GPIO(24); /* turn on display */ + } + current_par.controller_state = LCD_MODE_ENABLED; - /* Restore status of interrupts */ - } - restore_flags(flags); + } + /* Restore interrupt status */ + restore_flags(flags); } @@ -1046,12 +1108,14 @@ { int i; + DPRINTK("blank=%d info->modename=%s\n", blank, info->modename); if (blank) { for (i = 0; i < current_par.palette_size; i++) sa1100fb_palette_write(i, sa1100fb_palette_encode(i, 0, 0, 0, 0)); sa1100fb_disable_lcd_controller(); } else { + if (current_par.visual != FB_VISUAL_TRUECOLOR) sa1100fb_set_cmap(&fb_display[current_par.currcon].cmap, 1, current_par.currcon, info); sa1100fb_enable_lcd_controller(); @@ -1067,8 +1131,10 @@ static int sa1100fb_switch(int con, struct fb_info *info) { - struct fb_cmap *cmap; + DPRINTK("con=%d info->modename=%s\n", con, info->modename); + if (current_par.visual != FB_VISUAL_TRUECOLOR) { + struct fb_cmap *cmap; if (current_par.currcon >= 0) { // Get the colormap for the selected console cmap = &fb_display[current_par.currcon].cmap; @@ -1076,9 +1142,11 @@ if (cmap->len) fb_get_cmap(cmap, 1, sa1100fb_getcolreg, info); } + } current_par.currcon = con; fb_display[con].var.activate = FB_ACTIVATE_NOW; + DPRINTK("fb_display[%d].var.activate=%x\n", con, fb_display[con].var.activate); sa1100fb_set_var(&fb_display[con].var, con, info); return 0; } @@ -1086,44 +1154,47 @@ void __init sa1100fb_init(void) { - current_par.p_palette_base = NULL; - current_par.v_palette_base = NULL; - current_par.p_screen_base = NULL; - current_par.v_screen_base = NULL; - current_par.palette_size = MAX_PALETTE_NUM_ENTRIES; - current_par.screen_size = MAX_PIXEL_MEM_SIZE; - -#if defined(CONFIG_SA1100_PENNY) - GPDR |= GPIO_GPDR_GFX; /* GPIO Data Direction register for LCD data bits 8-11 */ - GAFR |= GPIO_GAFR_GFX; /* GPIO Alternate Function register for LCD data bits 8-11 */ -#elif defined(CONFIG_SA1100_TIFON) - - GPDR = GPDR | GPIO_GPIO(24); /* set GPIO24 to output */ -#endif + sa1100fb_init_fbinfo(); /* Initialize video memory */ if (sa1100fb_map_video_memory()) - return; + return; - sa1100fb_init_fbinfo(); if (current_par.montype < 0 || current_par.montype > NR_MONTYPES) current_par.montype = 1; - /* Request the interrupt in the init routine only because */ - /* this driver will not be used as a module. */ - if (request_irq(IRQ_LCD, sa1100fb_inter_handler, SA_INTERRUPT, "SA1100 LCD", NULL)!= 0) { - DPRINTK("sa1100fb: failed in request_irq\n"); + if (request_irq(IRQ_LCD, sa1100fb_inter_handler, SA_INTERRUPT, "SA1100 LCD", NULL) != 0) { + printk("sa1100fb: failed in request_irq\n"); + return; } DPRINTK("sa1100fb: request_irq succeeded\n"); disable_irq(IRQ_LCD); + if (machine_is_assabet()) { +#ifdef CONFIG_SA1100_ASSABET + GPDR |= 0x3fc; + GAFR |= 0x3fc; + BCR_clear(BCR_LCD_12RGB); +#endif + } else if (machine_is_bitsy()) { + GPDR = (GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8); + GAFR |= (GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8); + } else if (machine_is_penny()) { +#ifdef CONFIG_SA1100_PENNY + GPDR |= GPIO_GPDR_GFX; /* GPIO Data Direction register for LCD data bits 8-11 */ + GAFR |= GPIO_GAFR_GFX; /* GPIO Alternate Function register for LCD data bits 8-11 */ +#endif + } else if (machine_is_tifon()) { + GPDR |= GPIO_GPIO(24); /* set GPIO24 to output */ + } + if (sa1100fb_set_var(&init_var, -1, &fb_info)) current_par.allow_modeset = 0; sa1100fb_decode_var(&init_var, ¤t_par); register_framebuffer(&fb_info); - /* This driver cannot be unloaded */ + /* This driver cannot be unloaded at the moment */ MOD_INC_USE_COUNT; } 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/block_dev.c linux.ac/fs/block_dev.c --- linux.vanilla/fs/block_dev.c Thu May 25 17:46:15 2000 +++ linux.ac/fs/block_dev.c Sun Jun 4 22:17:00 2000 @@ -597,6 +597,8 @@ ret = bdev->bd_op->open(fake_inode, &fake_file); if (!ret) atomic_inc(&bdev->bd_openers); + else if (!atomic_read(&bdev->bd_openers)) + bdev->bd_op = NULL; iput(fake_inode); } } @@ -617,6 +619,8 @@ ret = bdev->bd_op->open(inode,filp); if (!ret) atomic_inc(&bdev->bd_openers); + else if (!atomic_read(&bdev->bd_openers)) + bdev->bd_op = NULL; } up(&bdev->bd_sem); return ret; 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 Sun Jun 4 22:19:09 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,26 +1363,45 @@ 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) { struct buffer_head *bh, *head, *tail; @@ -1799,6 +1868,7 @@ } spin_unlock(&unused_list_lock); + wake_up(&buffer_wait); return iosize; } @@ -1935,6 +2005,8 @@ __put_unused_buffer_head(bh[bhind]); } spin_unlock(&unused_list_lock); + wake_up(&buffer_wait); + goto finished; } @@ -2112,6 +2184,12 @@ } /* + * Can the buffer be thrown out? + */ +#define BUFFER_BUSY_BITS ((1<b_count) | ((bh)->b_state & BUFFER_BUSY_BITS)) + +/* * Sync all the buffers on one page.. * * If we have old buffers that are locked, we'll @@ -2121,7 +2199,7 @@ * This all is required so that we can free up memory * later. */ -static void sync_page_buffers(struct buffer_head *bh, int wait) +static int sync_page_buffers(struct buffer_head *bh, int wait) { struct buffer_head * tmp = bh; @@ -2134,13 +2212,17 @@ } else if (buffer_dirty(p)) ll_rw_block(WRITE, 1, &p); } while (tmp != bh); -} -/* - * Can the buffer be thrown out? - */ -#define BUFFER_BUSY_BITS ((1<b_count) | ((bh)->b_state & BUFFER_BUSY_BITS)) + do { + struct buffer_head *p = tmp; + tmp = tmp->b_this_page; + if (buffer_busy(p)) + return 0; + } while (tmp != bh); + + /* Success. Now try_to_free_buffers can free the page. */ + return 1; +} /* * try_to_free_buffers() checks if all the buffers on this particular page @@ -2158,6 +2240,7 @@ struct buffer_head * tmp, * bh = page->buffers; int index = BUFSIZE_INDEX(bh->b_size); +again: spin_lock(&lru_list_lock); write_lock(&hash_table_lock); spin_lock(&free_list[index].lock); @@ -2203,7 +2286,8 @@ spin_unlock(&free_list[index].lock); write_unlock(&hash_table_lock); spin_unlock(&lru_list_lock); - sync_page_buffers(bh, wait); + if (sync_page_buffers(bh, wait)) + goto again; return 0; } @@ -2499,7 +2583,7 @@ * the syscall above, but now we launch it ourselves internally with * kernel_thread(...) directly after the first thread in init/main.c */ -int bdflush(void * unused) +int bdflush(void *sem) { struct task_struct *tsk = current; int flushed; @@ -2521,6 +2605,8 @@ recalc_sigpending(tsk); spin_unlock_irq(&tsk->sigmask_lock); + up((struct semaphore *)sem); + for (;;) { CHECK_EMERGENCY_SYNC @@ -2555,7 +2641,7 @@ * You don't need to change your userspace configuration since * the userspace `update` will do_exit(0) at the first sys_bdflush(). */ -int kupdate(void * unused) +int kupdate(void *sem) { struct task_struct * tsk = current; int interval; @@ -2571,6 +2657,8 @@ recalc_sigpending(tsk); spin_unlock_irq(&tsk->sigmask_lock); + up((struct semaphore *)sem); + for (;;) { /* update interval */ interval = bdf_prm.b_un.interval; @@ -2604,8 +2692,11 @@ static int __init bdflush_init(void) { - kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); - kernel_thread(kupdate, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + DECLARE_MUTEX_LOCKED(sem); + kernel_thread(bdflush, &sem, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + down(&sem); + kernel_thread(kupdate, &sem, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + down(&sem); return 0; } 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 Wed May 31 11:17:01 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; @@ -585,21 +587,18 @@ cap_clear(bprm->cap_effective); /* To support inheritance of root-permissions and suid-root - * executables under compatibility mode, we raise the - * effective and inherited bitmasks of the executable file - * (translation: we set the executable "capability dumb" and - * set the allowed set to maximum). We don't set any forced - * bits. + * executables under compatibility mode, we raise all three + * capability sets for the file. * * If only the real uid is 0, we only raise the inheritable - * bitmask of the executable file (translation: we set the - * allowed set to maximum and the application to "capability - * smart"). + * and permitted sets of the executable file. */ if (!issecure(SECURE_NOROOT)) { - if (bprm->e_uid == 0 || current->uid == 0) + if (bprm->e_uid == 0 || current->uid == 0) { cap_set_full(bprm->cap_inheritable); + cap_set_full(bprm->cap_permitted); + } if (bprm->e_uid == 0) cap_set_full(bprm->cap_effective); } @@ -610,10 +609,12 @@ * privilege does not go against other system constraints. * The new Permitted set is defined below -- see (***). */ { - kernel_cap_t working = - cap_combine(bprm->cap_permitted, - cap_intersect(bprm->cap_inheritable, - current->cap_inheritable)); + kernel_cap_t permitted, working; + + permitted = cap_intersect(bprm->cap_permitted, cap_bset); + working = cap_intersect(bprm->cap_inheritable, + current->cap_inheritable); + working = cap_combine(permitted, working); if (!cap_issubset(working, current->cap_permitted)) { cap_raised = 1; } @@ -646,26 +647,29 @@ * The formula used for evolving capabilities is: * * pI' = pI - * (***) pP' = fP | (fI & pI) + * (***) pP' = (fP & X) | (fI & pI) * pE' = pP' & fE [NB. fE is 0 or ~0] * * I=Inheritable, P=Permitted, E=Effective // p=process, f=file - * ' indicates post-exec(). + * ' indicates post-exec(), and X is the global 'cap_bset'. */ void compute_creds(struct linux_binprm *bprm) { - int new_permitted = cap_t(bprm->cap_permitted) | - (cap_t(bprm->cap_inheritable) & - cap_t(current->cap_inheritable)); + kernel_cap_t new_permitted, working; + + new_permitted = cap_intersect(bprm->cap_permitted, cap_bset); + working = cap_intersect(bprm->cap_inheritable, + current->cap_inheritable); + new_permitted = cap_combine(new_permitted, working); /* For init, we want to retain the capabilities set * in the init_task struct. Thus we skip the usual * capability rules */ if (current->pid != 1) { - cap_t(current->cap_permitted) = new_permitted; - cap_t(current->cap_effective) = new_permitted & - cap_t(bprm->cap_effective); + current->cap_permitted = new_permitted; + current->cap_effective = + cap_intersect(new_permitted, bprm->cap_effective); } /* AUD: Audit candidate if current->cap_effective is set */ 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/ioctl.c linux.ac/fs/ioctl.c --- linux.vanilla/fs/ioctl.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/ioctl.c Wed May 31 11:19:15 2000 @@ -88,8 +88,12 @@ /* Did FASYNC state change ? */ if ((flag ^ filp->f_flags) & FASYNC) { if (filp->f_op && filp->f_op->fasync) - filp->f_op->fasync(fd, filp, on); + error = filp->f_op->fasync(fd, filp, on); + else error = -ENOTTY; } + if (error != 0) + break; + if (on) filp->f_flags |= FASYNC; else 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/namei.c linux.ac/fs/namei.c --- linux.vanilla/fs/namei.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/namei.c Sun Jun 4 22:17:00 2000 @@ -771,8 +771,6 @@ int error; if (!victim->d_inode || victim->d_parent->d_inode != dir) return -ENOENT; - if (IS_DEADDIR(dir)) - return -ENOENT; error = permission(dir,MAY_WRITE | MAY_EXEC); if (error) return error; @@ -786,8 +784,6 @@ return -ENOTDIR; if (IS_ROOT(victim)) return -EBUSY; - if (d_mountpoint(victim)) - return -EBUSY; } else if (S_ISDIR(victim->d_inode->i_mode)) return -EISDIR; return 0; @@ -917,6 +913,13 @@ error = -EEXIST; if (flag & O_EXCL) goto exit_dput; + /* Check mountpoints - it may be a binding on file. */ + while (d_mountpoint(dentry) && + __follow_down(&nd->mnt, &dentry)) + ; + error = -ENOENT; + if (!dentry->d_inode) + goto exit_dput; if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) { /* @@ -962,6 +965,10 @@ if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) goto exit; + error = -EOPNOTSUPP; + if (S_ISSOCK(inode->i_mode)) + goto exit; + error = permission(inode,acc_mode); if (error) goto exit; @@ -1213,9 +1220,15 @@ double_down(&dir->i_zombie, &dentry->d_inode->i_zombie); d_unhash(dentry); - error = dir->i_op->rmdir(dir, dentry); - if (!error) - dentry->d_inode->i_flags |= S_DEAD; + if (IS_DEADDIR(dir)) + error = -ENOENT; + else if (d_mountpoint(dentry)) + error = -EBUSY; + else { + error = dir->i_op->rmdir(dir, dentry); + if (!error) + dentry->d_inode->i_flags |= S_DEAD; + } double_up(&dir->i_zombie, &dentry->d_inode->i_zombie); if (!error) d_delete(dentry); @@ -1275,9 +1288,13 @@ error = -EPERM; if (dir->i_op && dir->i_op->unlink) { DQUOT_INIT(dir); - error = dir->i_op->unlink(dir, dentry); - if (!error) - d_delete(dentry); + if (d_mountpoint(dentry)) + error = -EBUSY; + else { + error = dir->i_op->unlink(dir, dentry); + if (!error) + d_delete(dentry); + } } } up(&dir->i_zombie); @@ -1555,7 +1572,12 @@ } else double_down(&old_dir->i_zombie, &new_dir->i_zombie); - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); + if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir)) + error = -ENOENT; + else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) + error = -EBUSY; + else + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); if (target) { if (!error) target->i_flags |= S_DEAD; @@ -1603,7 +1625,10 @@ DQUOT_INIT(old_dir); DQUOT_INIT(new_dir); double_down(&old_dir->i_zombie, &new_dir->i_zombie); - error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); + if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) + error = -EBUSY; + else + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); double_up(&old_dir->i_zombie, &new_dir->i_zombie); if (error) return error; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ncpfs/dir.c linux.ac/fs/ncpfs/dir.c --- linux.vanilla/fs/ncpfs/dir.c Thu May 25 17:37:32 2000 +++ linux.ac/fs/ncpfs/dir.c Sun Jun 4 21:48:39 2000 @@ -973,7 +973,7 @@ /* * Check whether to close the file ... */ - if (inode && NCP_FINFO(inode)->opened) { + if (inode) { PPRINTK("ncp_unlink: closing file\n"); ncp_make_closed(inode); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ncpfs/file.c linux.ac/fs/ncpfs/file.c --- linux.vanilla/fs/ncpfs/file.c Thu May 25 17:46:16 2000 +++ linux.ac/fs/ncpfs/file.c Sun Jun 4 21:48:39 2000 @@ -46,12 +46,12 @@ } DPRINTK("ncp_make_open: opened=%d, volume # %u, dir entry # %u\n", - NCP_FINFO(inode)->opened, + atomic_read(&NCP_FINFO(inode)->opened), NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum); error = -EACCES; - lock_super(inode->i_sb); - if (!NCP_FINFO(inode)->opened) { + down(&NCP_FINFO(inode)->open_sem); + if (!atomic_read(&NCP_FINFO(inode)->opened)) { struct ncp_entry_info finfo; int result; @@ -88,15 +88,18 @@ */ update: ncp_update_inode(inode, &finfo); + atomic_set(&NCP_FINFO(inode)->opened, 1); } access = NCP_FINFO(inode)->access; PPRINTK("ncp_make_open: file open, access=%x\n", access); - if (access == right || access == O_RDWR) + if (access == right || access == O_RDWR) { + atomic_inc(&NCP_FINFO(inode)->opened); error = 0; + } out_unlock: - unlock_super(inode->i_sb); + up(&NCP_FINFO(inode)->open_sem); out: return error; } @@ -153,7 +156,7 @@ freelen = ncp_read_bounce_size(bufsize); freepage = kmalloc(freelen, GFP_NFS); if (!freepage) - goto out; + goto outrel; error = 0; /* First read in as much as possible for each bufsize. */ while (already_read < count) { @@ -166,9 +169,8 @@ pos, to_read, buf, &read_this_time, freepage, freelen); if (error) { - kfree(freepage); - error = -EIO; /* This is not exact, i know.. */ - goto out; + error = -EIO; /* NW errno -> Linux errno */ + break; } pos += read_this_time; buf += read_this_time; @@ -188,6 +190,8 @@ DPRINTK("ncp_file_read: exit %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); +outrel: + ncp_inode_close(inode); out: return already_read ? already_read : error; } @@ -236,8 +240,10 @@ already_written = 0; bouncebuffer = kmalloc(bufsize, GFP_NFS); - if (!bouncebuffer) - return -EIO; /* -ENOMEM */ + if (!bouncebuffer) { + errno = -EIO; /* -ENOMEM */ + goto outrel; + } while (already_written < count) { int written_this_time; size_t to_write = min(bufsize - (pos % bufsize), @@ -271,15 +277,15 @@ } DPRINTK("ncp_file_write: exit %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); +outrel: + ncp_inode_close(inode); out: return already_written ? already_written : errno; } static int ncp_release(struct inode *inode, struct file *file) { - if (NCP_FINFO(inode)->opened) { - if (ncp_make_closed(inode)) { - DPRINTK("ncp_release: failed to close\n"); - } + if (ncp_make_closed(inode)) { + DPRINTK("ncp_release: failed to close\n"); } return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ncpfs/inode.c linux.ac/fs/ncpfs/inode.c --- linux.vanilla/fs/ncpfs/inode.c Thu May 25 17:37:32 2000 +++ linux.ac/fs/ncpfs/inode.c Sun Jun 4 21:48:39 2000 @@ -62,7 +62,6 @@ #ifdef CONFIG_NCPFS_STRONG NCP_FINFO(inode)->nwattr = nwinfo->i.attributes; #endif - NCP_FINFO(inode)->opened = nwinfo->opened; NCP_FINFO(inode)->access = nwinfo->access; NCP_FINFO(inode)->server_file_handle = nwinfo->server_file_handle; memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle, @@ -77,7 +76,7 @@ struct nw_info_struct *nwi = &nwinfo->i; struct ncp_server *server = NCP_SERVER(inode); - if (!NCP_FINFO(inode)->opened) { + if (!atomic_read(&NCP_FINFO(inode)->opened)) { #ifdef CONFIG_NCPFS_STRONG NCP_FINFO(inode)->nwattr = nwi->attributes; #endif @@ -217,6 +216,9 @@ inode = get_empty_inode(); if (inode) { + init_MUTEX(&NCP_FINFO(inode)->open_sem); + atomic_set(&NCP_FINFO(inode)->opened, info->opened); + inode->i_sb = sb; inode->i_dev = sb->s_dev; inode->i_ino = info->ino; @@ -252,7 +254,7 @@ DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino); } - if (NCP_FINFO(inode)->opened && ncp_make_closed(inode) != 0) { + if (ncp_make_closed(inode) != 0) { /* We can't do anything but complain. */ printk(KERN_ERR "ncp_delete_inode: could not close\n"); } @@ -683,6 +685,7 @@ /* According to ndir, the changes only take effect after closing the file */ + ncp_inode_close(inode); result = ncp_make_closed(inode); if (!result) vmtruncate(inode, attr->ia_size); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ncpfs/ioctl.c linux.ac/fs/ncpfs/ioctl.c --- linux.vanilla/fs/ncpfs/ioctl.c Thu May 25 17:46:16 2000 +++ linux.ac/fs/ncpfs/ioctl.c Sun Jun 4 21:48:39 2000 @@ -335,18 +335,12 @@ { return result; } + result = -EIO; if (!ncp_conn_valid(server)) - { - return -EIO; - } + goto outrel; + result = -EISDIR; if (!S_ISREG(inode->i_mode)) - { - return -EISDIR; - } - if (!NCP_FINFO(inode)->opened) - { - return -EBADFD; - } + goto outrel; if (rqdata.cmd == NCP_LOCK_CLEAR) { result = ncp_ClearPhysicalRecord(NCP_SERVER(inode), @@ -373,6 +367,8 @@ rqdata.timeout); if (result > 0) result = -EAGAIN; } +outrel: + ncp_inode_close(inode); return result; } #endif /* CONFIG_NCPFS_IOCTL_LOCKING */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ncpfs/mmap.c linux.ac/fs/ncpfs/mmap.c --- linux.vanilla/fs/ncpfs/mmap.c Thu May 25 17:37:32 2000 +++ linux.ac/fs/ncpfs/mmap.c Sun Jun 4 21:48:39 2000 @@ -82,6 +82,7 @@ break; } } + ncp_inode_close(inode); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ncpfs/ncplib_kernel.c linux.ac/fs/ncpfs/ncplib_kernel.c --- linux.vanilla/fs/ncpfs/ncplib_kernel.c Thu May 25 17:37:32 2000 +++ linux.ac/fs/ncpfs/ncplib_kernel.c Sun Jun 4 21:48:39 2000 @@ -221,20 +221,23 @@ return result; } -/* - * Called with the superblock locked. - */ int ncp_make_closed(struct inode *inode) { int err; - NCP_FINFO(inode)->opened = 0; - err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle); - if (!err) - PPRINTK("ncp_make_closed: volnum=%d, dirent=%u, error=%d\n", - NCP_FINFO(inode)->volNumber, - NCP_FINFO(inode)->dirEntNum, err); + err = 0; + down(&NCP_FINFO(inode)->open_sem); + if (atomic_read(&NCP_FINFO(inode)->opened) == 1) { + atomic_set(&NCP_FINFO(inode)->opened, 0); + err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle); + + if (!err) + PPRINTK("ncp_make_closed: volnum=%d, dirent=%u, error=%d\n", + NCP_FINFO(inode)->volNumber, + NCP_FINFO(inode)->dirEntNum, err); + } + up(&NCP_FINFO(inode)->open_sem); return err; } @@ -613,7 +616,8 @@ if ((result = ncp_request(server, 87)) != 0) goto out; - target->opened = 1; + if (!(create_attributes & aDIR)) + target->opened = 1; target->server_file_handle = ncp_reply_dword(server, 0); target->open_create_action = ncp_reply_byte(server, 4); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ncpfs/ncplib_kernel.h linux.ac/fs/ncpfs/ncplib_kernel.h --- linux.vanilla/fs/ncpfs/ncplib_kernel.h Thu May 25 17:37:32 2000 +++ linux.ac/fs/ncpfs/ncplib_kernel.h Sun Jun 4 22:55:54 2000 @@ -57,6 +57,10 @@ int ncp_write_kernel(struct ncp_server *, const char *, __u32, __u16, const char *, int *); +static inline void ncp_inode_close(struct inode *inode) { + atomic_dec(&NCP_FINFO(inode)->opened); +} + int ncp_obtain_info(struct ncp_server *server, struct inode *, char *, struct nw_info_struct *target); int ncp_lookup_volume(struct ncp_server *, char *, struct nw_info_struct *); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/ncpfs/symlink.c linux.ac/fs/ncpfs/symlink.c --- linux.vanilla/fs/ncpfs/symlink.c Thu May 25 17:37:32 2000 +++ linux.ac/fs/ncpfs/symlink.c Sun Jun 4 21:48:39 2000 @@ -29,6 +29,7 @@ #include #include #include +#include #include "ncplib_kernel.h" @@ -50,10 +51,6 @@ char *link; char *buf = (char*)kmap(page); - error = -EIO; - if (ncp_make_open(inode,O_RDONLY)) - goto fail; - error = -ENOMEM; for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_NFS))==NULL; cnt++) { if (cnt > 10) @@ -61,20 +58,22 @@ schedule(); } + if (ncp_make_open(inode,O_RDONLY)) + goto failEIO; + error=ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle, 0,NCP_MAX_SYMLINK_SIZE,link,&length); - if (error) { - kfree(link); - goto fail; - } + ncp_inode_close(inode); + /* Close file handle if no other users... */ + ncp_make_closed(inode); + if (error) + goto failEIO; + if (lengthd_inode; + if (ncp_make_open(inode, O_WRONLY)) + goto failfree; + ((__u32 *)link)[0]=NCP_SYMLINK_MAGIC0; ((__u32 *)link)[1]=NCP_SYMLINK_MAGIC1; @@ -134,19 +138,26 @@ symlink can point out of ncp filesystem */ length += 1; err = ncp_io2vol(NCP_SERVER(inode),link+8,&length,symname,length-1,0); - if (err) { - kfree(link); - return err; - } + if (err) + goto fail; if(ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, 0, length+8, link, &i) || i!=length+8) { - kfree(link); - return -EIO; + err = -EIO; + goto fail; } + ncp_inode_close(inode); + ncp_make_closed(inode); kfree(link); return 0; + +fail: + ncp_inode_close(inode); + ncp_make_closed(inode); +failfree: + kfree(link); + return err; } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/proc/generic.c linux.ac/fs/proc/generic.c --- linux.vanilla/fs/proc/generic.c Thu May 25 17:37:31 2000 +++ linux.ac/fs/proc/generic.c Sun Jun 4 22:10:14 2000 @@ -535,7 +535,7 @@ { int ino = de->low_ino; - if (ino < PROC_DYNAMIC_FIRST && + if (ino < PROC_DYNAMIC_FIRST || ino >= PROC_DYNAMIC_FIRST+PROC_NDYNAMIC) return; if (S_ISLNK(de->mode) && de->data) 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/fs/super.c linux.ac/fs/super.c --- linux.vanilla/fs/super.c Thu May 25 17:46:16 2000 +++ linux.ac/fs/super.c Sun Jun 4 22:17:00 2000 @@ -738,10 +738,6 @@ /* Done with lookups, semaphore down */ down(&mount_sem); dev = to_kdev_t(bdev->bd_dev); - check_disk_change(dev); - error = -EACCES; - if (!(flags & MS_RDONLY) && is_read_only(dev)) - goto out; sb = get_super(dev); if (sb) { if (fs_type == sb->s_type) { @@ -755,6 +751,10 @@ error = blkdev_get(bdev, mode, 0, BDEV_FS); if (error) goto out; + check_disk_change(dev); + error = -EACCES; + if (!(flags & MS_RDONLY) && is_read_only(dev)) + goto out1; error = -EINVAL; sb = read_super(dev, bdev, fs_type, flags, data, 0); if (sb) { @@ -762,6 +762,7 @@ path_release(&nd); return sb; } +out1: blkdev_put(bdev, BDEV_FS); } out: @@ -1067,6 +1068,8 @@ { if (capable(CAP_SYS_ADMIN)) return 0; + return -EPERM; +#ifdef notyet if (S_ISLNK(nd->dentry->d_inode->i_mode)) return -EPERM; if (nd->dentry->d_inode->i_mode & S_ISVTX) { @@ -1076,6 +1079,7 @@ if (permission(nd->dentry->d_inode, MAY_WRITE)) return -EPERM; return 0; +#endif } /* 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/arch-arc/hardware.h linux.ac/include/asm-arm/arch-arc/hardware.h --- linux.vanilla/include/asm-arm/arch-arc/hardware.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/arch-arc/hardware.h Sun Jun 4 21:13:31 2000 @@ -25,11 +25,6 @@ #include #define HAS_VIDC -/* - * Optional hardware - */ -#define HAS_EXPMASK - /* Hardware addresses of major areas. * *_START is the physical address * *_SIZE is the size of the region @@ -100,7 +95,6 @@ #endif -#ifdef HAS_EXPMASK #ifndef __ASSEMBLY__ #define __EXPMASK(offset) (((volatile unsigned char *)EXPMASK_BASE)[offset]) #else @@ -109,7 +103,5 @@ #define EXPMASK_STATUS __EXPMASK(0x00) #define EXPMASK_ENABLE __EXPMASK(0x04) - -#endif #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/arch-ebsa285/hardware.h linux.ac/include/asm-arm/arch-ebsa285/hardware.h --- linux.vanilla/include/asm-arm/arch-ebsa285/hardware.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/arch-ebsa285/hardware.h Sun Jun 4 21:13:31 2000 @@ -11,7 +11,7 @@ #include #include -#ifdef CONFIG_HOST_FOOTBRIDGE +#ifdef CONFIG_FOOTBRIDGE_HOST /* Virtual Physical Size * 0xff800000 0x40000000 1MB X-Bus * 0xff000000 0x7c000000 1MB PCI I/O space diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/arch-ebsa285/irq.h linux.ac/include/asm-arm/arch-ebsa285/irq.h --- linux.vanilla/include/asm-arm/arch-ebsa285/irq.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/arch-ebsa285/irq.h Sun Jun 4 21:13:31 2000 @@ -10,7 +10,6 @@ * 26-Jan-1999 PJB Don't use IACK on CATS * 16-Mar-1999 RMK Added autodetect of ISA PICs */ -/* no need for config.h - arch/arm/kernel/irq.c does this for us */ #include #include #include @@ -36,29 +35,31 @@ IRQ_MASK_PCI, /* 12 */ IRQ_MASK_SDRAMPARITY, /* 13 */ IRQ_MASK_I2OINPOST, /* 14 */ - IRQ_MASK_PCI_ERR /* 15 */ + IRQ_MASK_PCI_ABORT, /* 15 */ + IRQ_MASK_PCI_SERR, /* 16 */ + IRQ_MASK_DISCARD_TIMER, /* 17 */ + IRQ_MASK_PCI_DPERR, /* 18 */ + IRQ_MASK_PCI_PERR, /* 19 */ }; static int isa_irq = -1; static inline int fixup_irq(unsigned int irq) { -#ifdef CONFIG_HOST_FOOTBRIDGE if (irq == isa_irq) irq = *(unsigned char *)PCIIACK_BASE; -#endif return irq; } static void dc21285_mask_irq(unsigned int irq) { - *CSR_IRQ_DISABLE = dc21285_irq_mask[irq & 15]; + *CSR_IRQ_DISABLE = dc21285_irq_mask[_DC21285_INR(irq)]; } static void dc21285_unmask_irq(unsigned int irq) { - *CSR_IRQ_ENABLE = dc21285_irq_mask[irq & 15]; + *CSR_IRQ_ENABLE = dc21285_irq_mask[_DC21285_INR(irq)]; } static void isa_mask_pic_lo_irq(unsigned int irq) @@ -124,7 +125,7 @@ *CSR_IRQ_DISABLE = -1; *CSR_FIQ_DISABLE = -1; - for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(16); irq++) { + for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) { irq_desc[irq].valid = 1; irq_desc[irq].probe_ok = 1; irq_desc[irq].mask_ack = dc21285_mask_irq; @@ -138,19 +139,21 @@ */ isa_irq = -1; - if (machine_is_ebsa285()) - /* The following is dependent on which slot - * you plug the Southbridge card into. We - * currently assume that you plug it into - * the right-hand most slot. - */ - isa_irq = IRQ_PCI; + if (footbridge_cfn_mode()) { + if (machine_is_ebsa285()) + /* The following is dependent on which slot + * you plug the Southbridge card into. We + * currently assume that you plug it into + * the right-hand most slot. + */ + isa_irq = IRQ_PCI; - if (machine_is_cats()) - isa_irq = IRQ_IN2; + if (machine_is_cats()) + isa_irq = IRQ_IN2; - if (machine_is_netwinder()) - isa_irq = IRQ_IN3; + if (machine_is_netwinder()) + isa_irq = IRQ_IN3; + } if (isa_irq != -1) { /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/arch-ebsa285/irqs.h linux.ac/include/asm-arm/arch-ebsa285/irqs.h --- linux.vanilla/include/asm-arm/arch-ebsa285/irqs.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/arch-ebsa285/irqs.h Sun Jun 4 21:13:31 2000 @@ -9,11 +9,13 @@ * 01-Feb-1999 PJB ISA IRQs start at 0 not 16 */ -#define NR_IRQS 32 +#define NR_IRQS 36 #define NR_DC21285_IRQS 16 #define _ISA_IRQ(x) (0 + (x)) +#define _ISA_INR(x) ((x) - 0) #define _DC21285_IRQ(x) (16 + (x)) +#define _DC21285_INR(x) ((x) - 16) /* * This is a list of all interrupts that the 21285 @@ -34,7 +36,11 @@ #define IRQ_PCI _DC21285_IRQ(12) #define IRQ_SDRAMPARITY _DC21285_IRQ(13) #define IRQ_I2OINPOST _DC21285_IRQ(14) -#define IRQ_PCI_ERR _DC21285_IRQ(15) +#define IRQ_PCI_ABORT _DC21285_IRQ(15) +#define IRQ_PCI_SERR _DC21285_IRQ(16) +#define IRQ_DISCARD_TIMER _DC21285_IRQ(17) +#define IRQ_PCI_DPERR _DC21285_IRQ(18) +#define IRQ_PCI_PERR _DC21285_IRQ(19) #define IRQ_ISA_TIMER _ISA_IRQ(0) #define IRQ_ISA_KEYBOARD _ISA_IRQ(1) @@ -64,7 +70,11 @@ #define IRQ_MASK_PCI (1 << 18) #define IRQ_MASK_SDRAMPARITY (1 << 24) #define IRQ_MASK_I2OINPOST (1 << 25) -#define IRQ_MASK_PCI_ERR ((1 <<23) | (1 << 27) | (1 << 28) | (1 << 29) | (1 << 30) | (1 << 31)) +#define IRQ_MASK_PCI_ABORT ((1 << 29) | (1 << 30)) +#define IRQ_MASK_PCI_SERR (1 << 23) +#define IRQ_MASK_DISCARD_TIMER (1 << 27) +#define IRQ_MASK_PCI_DPERR (1 << 28) +#define IRQ_MASK_PCI_PERR (1 << 31) /* * Netwinder interrupt allocations diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/arch-ebsa285/memory.h linux.ac/include/asm-arm/arch-ebsa285/memory.h --- linux.vanilla/include/asm-arm/arch-ebsa285/memory.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/arch-ebsa285/memory.h Sun Jun 4 21:13:31 2000 @@ -17,7 +17,7 @@ #include -#if defined(CONFIG_HOST_FOOTBRIDGE) +#if defined(CONFIG_FOOTBRIDGE_HOST) /* * Task size: 3GB @@ -36,7 +36,7 @@ #define __bus_to_virt__is_a_macro #define __bus_to_virt(x) ((x) + 0xe0000000) -#elif defined(CONFIG_ADDIN_FOOTBRIDGE) +#elif defined(CONFIG_FOOTBRIDGE_ADDIN) #if defined(CONFIG_ARCH_CO285) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/arch-rpc/hardware.h linux.ac/include/asm-arm/arch-rpc/hardware.h --- linux.vanilla/include/asm-arm/arch-rpc/hardware.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/arch-rpc/hardware.h Sun Jun 4 21:13:31 2000 @@ -93,7 +93,6 @@ #endif -#ifdef HAS_EXPMASK #ifndef __ASSEMBLY__ #define __EXPMASK(offset) (((volatile unsigned char *)EXPMASK_BASE)[offset]) #else @@ -102,7 +101,5 @@ #define EXPMASK_STATUS __EXPMASK(0x00) #define EXPMASK_ENABLE __EXPMASK(0x04) - -#endif #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/arch-sa1100/mmzone.h linux.ac/include/asm-arm/arch-sa1100/mmzone.h --- linux.vanilla/include/asm-arm/arch-sa1100/mmzone.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-arm/arch-sa1100/mmzone.h Sun Jun 4 21:13:31 2000 @@ -0,0 +1,81 @@ +/* + * linux/include/asm-arm/arch-sa1100/mmzone.h + * + * (C) 1999-2000, Nicolas Pitre + * (inspired by Kanoj Sarcar's code) + * + * Because of the wide memory address space between physical RAM banks on the + * SA1100, it's much convenient to use Linux's NUMA support to implement our + * memory map representation. Assuming all memory nodes have equal access + * characteristics, we then have generic discontigous memory support. + * + * Of course, all this isn't mandatory for SA1100 implementations with only + * one used memory bank. For those, simply undefine CONFIG_DISCONTIGMEM. + */ + + +/* + * Currently defined in arch/arm/mm/init.c + */ +extern pg_data_t sa1100_node_data[]; + +/* + * 32MB max in each bank, must fit with __virt_to_phys() & __phys_to_virt() + */ +#define NODE_MAX_MEM_SHIFT 25 +#define NODE_MAX_MEM_SIZE (1<> NODE_MAX_MEM_SHIFT) + +/* + * Return a pointer to the node data for node n. + */ +#define NODE_DATA(nid) (&sa1100_node_data[nid]) + +/* + * NODE_MEM_MAP gives the kaddr for the mem_map of the node. + */ +#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map) + +/* + * Given a mem_map_t, LOCAL_MAP_BASE finds the owning node for the + * physical page and returns the kaddr for the mem_map of that node. + */ +#define LOCAL_MAP_BASE(page) \ + NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(page))) + +/* + * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory + * and returns the the mem_map of that node. + */ +#define ADDR_TO_MAPBASE(kaddr) \ + NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr))) + +/* + * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory + * and returns the kaddr corresponding to first physical page in the + * node's mem_map. + */ +#define LOCAL_BASE_ADDR(kaddr) ((unsigned long)(kaddr) & ~(NODE_MAX_MEM_SIZE-1)) + +/* + * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory + * and returns the index corresponding to the appropriate page in the + * node's mem_map. + */ +#define LOCAL_MAP_NR(kvaddr) \ + (((unsigned long)(kvaddr)-LOCAL_BASE_ADDR((kvaddr))) >> PAGE_SHIFT) + +/* + * With discontigmem, the conceptual mem_map array starts from PAGE_OFFSET. + * Given a kaddr, MAP_NR returns the appropriate global mem_map index so + * it matches the corresponding node's local mem_map. + */ +#define MAP_NR(kaddr) (LOCAL_MAP_NR((kaddr)) + \ + (((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \ + sizeof(mem_map_t))) + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/arch-sa1100/time.h linux.ac/include/asm-arm/arch-sa1100/time.h --- linux.vanilla/include/asm-arm/arch-sa1100/time.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/arch-sa1100/time.h Sun Jun 4 21:13:31 2000 @@ -33,16 +33,22 @@ static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + long flags; int next_match; /* Loop until we get ahead of the free running timer. * This ensures an exact clock tick count and time acuracy. - * Should be IRQ race free. + * IRQs are disabled inside the loop to ensure coherence between + * lost_ticks (updated in do_timer()) and the match reg value, so we + * can use do_gettimeofday() from interrupt handlers. */ do { + do_leds(); + save_flags_cli( flags ); do_timer(regs); OSSR = OSSR_M0; /* Clear match on timer 0 */ next_match = (OSMR0 += LATCH); + restore_flags( flags ); } while( (signed long)(next_match - OSCR) <= 0 ); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/arch-shark/time.h linux.ac/include/asm-arm/arch-shark/time.h --- linux.vanilla/include/asm-arm/arch-shark/time.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/arch-shark/time.h Sun Jun 4 21:13:31 2000 @@ -28,15 +28,7 @@ CMOS_READ(RTC_INTR_FLAGS); -#ifdef CONFIG_LEDS - { - static int count = 50; - if (--count == 0) { - count = 50; - leds_event(led_timer); - } - } -#endif + do_leds(); { #ifdef DIVISOR diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/dec21285.h linux.ac/include/asm-arm/dec21285.h --- linux.vanilla/include/asm-arm/dec21285.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/dec21285.h Sun Jun 4 21:13:31 2000 @@ -80,6 +80,18 @@ #define SA110_CNTL_XCSDIR(x) ((x)<<28) #define SA110_CNTL_PCICFN (1 << 31) +/* + * footbridge_cfn_mode() is used when we want + * to check whether we are the central function + */ +#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN) +#define footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN) +#elif defined(CONFIG_FOOTBRIDGE_HOST) +#define footbridge_cfn_mode() (1) +#else +#define footbridge_cfn_mode() (0) +#endif + #define CSR_PCIADDR_EXTN DC21285_IO(0x0140) #define CSR_PREFETCHMEMRANGE DC21285_IO(0x0144) #define CSR_XBUS_CYCLE DC21285_IO(0x0148) 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/mmzone.h linux.ac/include/asm-arm/mmzone.h --- linux.vanilla/include/asm-arm/mmzone.h Thu Jan 1 01:00:00 1970 +++ linux.ac/include/asm-arm/mmzone.h Sun Jun 4 21:13:31 2000 @@ -0,0 +1,12 @@ +/* + * linux/include/asm-arm/mmzone.h + * + * 1999-12-29 Nicolas Pitre Created + */ + +#ifndef __ASM_MMZONE_H +#define __ASM_MMZONE_H + +#include + +#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/page.h linux.ac/include/asm-arm/page.h --- linux.vanilla/include/asm-arm/page.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/page.h Sun Jun 4 21:13:31 2000 @@ -84,11 +84,15 @@ #endif /* !__ASSEMBLY__ */ +#include #include #define __pa(x) __virt_to_phys((unsigned long)(x)) #define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) + +#ifndef CONFIG_DISCONTIGMEM #define MAP_NR(addr) ((__pa(addr) - PHYS_OFFSET) >> PAGE_SHIFT) +#endif #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/pgtable.h linux.ac/include/asm-arm/pgtable.h --- linux.vanilla/include/asm-arm/pgtable.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/pgtable.h Sun Jun 4 21:13:31 2000 @@ -77,7 +77,18 @@ #define pte_none(pte) (!pte_val(pte)) #define pte_clear(ptep) set_pte((ptep), __pte(0)) + +#ifndef CONFIG_DISCONTIGMEM #define pte_pagenr(pte) ((unsigned long)(((pte_val(pte) - PHYS_OFFSET) >> PAGE_SHIFT))) +#else +/* + * I'm not happy with this - we needlessly convert a physical address + * to a virtual one, and then immediately back to a physical address, + * which, if __va and __pa are expensive causes twice the expense for + * zero gain. --rmk + */ +#define pte_pagenr(pte) MAP_NR(__va(pte_val(pte))) +#endif #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0)) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/proc-armv/assembler.h linux.ac/include/asm-arm/proc-armv/assembler.h --- linux.vanilla/include/asm-arm/proc-armv/assembler.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/proc-armv/assembler.h Sun Jun 4 21:13:31 2000 @@ -1,10 +1,10 @@ /* * linux/asm-arm/proc-armv/assembler.h * - * Copyright (C) 1996 Russell King + * Copyright (C) 1996-2000 Russell King * - * This file contains arm architecture specific defines - * for the different processors + * This file contains ARM processor specifics for + * the ARM6 and better processors. */ #ifndef __ASSEMBLY__ #error "Only include this from assembly code" @@ -19,68 +19,36 @@ /* * LOADREGS - ldm with PC in register list (eg, ldmfd sp!, {pc}) - * RETINSTR - return instruction (eg, mov pc, lr) */ #ifdef __STDC__ #define LOADREGS(cond, base, reglist...)\ ldm##cond base,reglist - -#define RETINSTR(instr, regs...)\ - instr regs #else #define LOADREGS(cond, base, reglist...)\ ldm/**/cond base,reglist - -#define RETINSTR(instr, regs...)\ - instr regs #endif /* - * No nop required after mode change - */ -#define MODENOP - -/* - * Change to `mode' - */ -#define MODE(savereg,tmpreg,mode) \ - mrs savereg, cpsr; \ - bic tmpreg, savereg, $0x1f; \ - orr tmpreg, tmpreg, $mode; \ - msr cpsr, tmpreg - -/* - * Restore mode + * Build a return instruction for this processor type. */ -#define RESTOREMODE(savereg) \ - msr cpsr, savereg - -/* - * save interrupt state (uses stack) - */ -#define SAVEIRQS(tmpreg)\ - mrs tmpreg, cpsr; \ - str tmpreg, [sp, $-4]! - -/* - * restore interrupt state (uses stack) - */ -#define RESTOREIRQS(tmpreg)\ - ldr tmpreg, [sp], $4; \ - msr cpsr, tmpreg - -/* - * disable IRQs - */ -#define DISABLEIRQS(tmpreg)\ - mrs tmpreg , cpsr; \ - orr tmpreg , tmpreg , $I_BIT; \ - msr cpsr, tmpreg +#define RETINSTR(instr, regs...)\ + instr regs /* - * enable IRQs - */ -#define ENABLEIRQS(tmpreg)\ - mrs tmpreg , cpsr; \ - bic tmpreg , tmpreg , $I_BIT; \ - msr cpsr, tmpreg + * Save the current IRQ state and disable IRQs + * Note that this macro assumes FIQs are enabled, and + * that the processor is in SVC mode. + */ + .macro save_and_disable_irqs, oldcpsr, temp + mrs \oldcpsr, cpsr + mov \temp, #I_BIT | MODE_SVC + msr cpsr_c, \temp + .endm + +/* + * Restore interrupt state previously stored in + * a register + */ + .macro restore_irqs, oldcpsr + msr cpsr_c, \oldcpsr + .endm diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/proc-armv/locks.h linux.ac/include/asm-arm/proc-armv/locks.h --- linux.vanilla/include/asm-arm/proc-armv/locks.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/proc-armv/locks.h Sun Jun 4 21:13:31 2000 @@ -72,7 +72,8 @@ * BIAS once per CPU will result in the long remaining * negative. */ -#define RW_LOCK_BIAS 0x01000000 +#define RW_LOCK_BIAS 0x01000000 +#define RW_LOCK_BIAS_STR "0x01000000" #define __down_op_write(ptr,fail) \ ({ \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/setup.h linux.ac/include/asm-arm/setup.h --- linux.vanilla/include/asm-arm/setup.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/setup.h Sun Jun 4 21:13:31 2000 @@ -74,6 +74,7 @@ struct { unsigned long start; unsigned long size; + int node; } bank[NR_BANKS]; }; 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-arm/system.h linux.ac/include/asm-arm/system.h --- linux.vanilla/include/asm-arm/system.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/system.h Sun Jun 4 21:13:31 2000 @@ -280,6 +280,20 @@ # define machine_is_lart() (0) #endif +#ifdef CONFIG_SA1100_GRAPHICSCLIENT +# ifdef machine_arch_type +# undef machine_arch_type +# define machine_arch_type __machine_arch_type +# else +# define machine_arch_type MACH_TYPE_GRAPHICSCLIENT +# endif +# define machine_is_grpahicsclient() \ + (machine_arch_type == MACH_TYPE_GRAPHICSCLIENT) +#else +# define machine_is_graphicsclient() \ + (0) +#endif + /* * The following are currently unregistered */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-arm/unistd.h linux.ac/include/asm-arm/unistd.h --- linux.vanilla/include/asm-arm/unistd.h Thu May 25 17:37:36 2000 +++ linux.ac/include/asm-arm/unistd.h Sun Jun 4 21:13:31 2000 @@ -116,7 +116,7 @@ #define __NR_lstat (__NR_SYSCALL_BASE+107) #define __NR_fstat (__NR_SYSCALL_BASE+108) -#define __NR_iopl (__NR_SYSCALL_BASE+110) + #define __NR_vhangup (__NR_SYSCALL_BASE+111) #define __NR_idle (__NR_SYSCALL_BASE+112) #define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */ 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 Sun Jun 4 22:32:07 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/est8260.h linux.ac/include/asm-ppc/est8260.h --- linux.vanilla/include/asm-ppc/est8260.h Thu May 25 17:37:35 2000 +++ linux.ac/include/asm-ppc/est8260.h Sun Jun 4 21:10:57 2000 @@ -1,4 +1,10 @@ +/* Board information for the EST8260, which should be generic for + * all 8260 boards. The IMMR is now given to us so the hard define + * will soon be removed. All of the clock values are computed from + * the configuration SCMR and the Power-On-Reset word. + */ + #define IMAP_ADDR ((uint)0xf0000000) @@ -12,8 +18,10 @@ unsigned int bi_busfreq; /* Bus Freq, in MHz */ unsigned int bi_cpmfreq; /* CPM Freq, in MHz */ unsigned int bi_brgfreq; /* BRG Freq, in MHz */ + unsigned int bi_vco; /* VCO Out from PLL */ + unsigned int bi_baudrate; /* Default console baud rate */ + unsigned int bi_immr; /* IMMR when called from boot rom */ unsigned char bi_enetaddr[6]; - unsigned int bi_baudrate; } bd_t; extern bd_t m8xx_board_info; 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/pgtable.h linux.ac/include/asm-ppc/pgtable.h --- linux.vanilla/include/asm-ppc/pgtable.h Thu May 25 17:37:35 2000 +++ linux.ac/include/asm-ppc/pgtable.h Sun Jun 4 21:10:57 2000 @@ -72,7 +72,7 @@ #define flush_page_to_ram(page) __flush_page_to_ram(page_address(page)) extern unsigned long va_to_phys(unsigned long address); -extern pte_t *va_to_pte(struct task_struct *tsk, unsigned long address); +extern pte_t *va_to_pte(struct mm_struct *mm, unsigned long address); extern unsigned long ioremap_bot, ioremap_base; #endif /* __ASSEMBLY__ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/asm-ppc/rpxclassic.h linux.ac/include/asm-ppc/rpxclassic.h --- linux.vanilla/include/asm-ppc/rpxclassic.h Thu May 25 17:37:35 2000 +++ linux.ac/include/asm-ppc/rpxclassic.h Sun Jun 4 21:10:57 2000 @@ -26,8 +26,6 @@ * We just map a few things we need. The CSR is actually 4 byte-wide * registers that can be accessed as 8-, 16-, or 32-bit values. */ -#define PCMCIA_MEM_ADDR ((uint)0x04000000) -#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) #define PCI_ISA_IO_ADDR ((unsigned)0x80000000) #define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024)) #define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000) @@ -38,6 +36,12 @@ #define IMAP_SIZE ((uint)(64 * 1024)) #define PCI_CSR_ADDR ((uint)0x80000000) #define PCI_CSR_SIZE ((uint)(64 * 1024)) +#define PCMCIA_MEM_ADDR ((uint)0xe0000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) +#define PCMCIA_IO_ADDR ((uint)0xe4000000) +#define PCMCIA_IO_SIZE ((uint)(4 * 1024)) +#define PCMCIA_ATTRB_ADDR ((uint)0xe8000000) +#define PCMCIA_ATTRB_SIZE ((uint)(4 * 1024)) /* Things of interest in the CSR. */ @@ -49,8 +53,19 @@ #define BCSR0_FLASH_SEL ((uint)0x02000000) #define BCSR0_ENMONXCVR ((uint)0x01000000) +#define BCSR0_PCMCIAVOLT ((uint)0x000f0000) /* CLLF */ +#define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) /* CLLF */ +#define BCSR0_PCMCIA5VOLT ((uint)0x00060000) /* CLLF */ + #define BCSR2_EN232XCVR ((uint)0x00008000) #define BCSR2_QSPACESEL ((uint)0x00004000) +#define BCSR2_FETHLEDMODE ((uint)0x00000800) /* CLLF */ + +#if defined(CONFIG_RPXLCD) || defined(CONFIG_HTDMSOUND) +/* HIOX Expansion card. +*/ +#include +#endif /* Interrupt level assignments. */ 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/pgtable.h linux.ac/include/asm-s390/pgtable.h --- linux.vanilla/include/asm-s390/pgtable.h Thu May 25 17:37:37 2000 +++ linux.ac/include/asm-s390/pgtable.h Sun Jun 4 22:06:32 2000 @@ -270,6 +270,7 @@ extern inline int pte_none(pte_t pte) { return ((pte_val(pte) & (_PAGE_INVALID | _PAGE_RO)) == _PAGE_INVALID); } extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = _PAGE_INVALID; } +#define PTE_INIT(x) pte_clear(x) extern inline int pte_pagenr(pte_t pte) { return ((unsigned long)((pte_val(pte) >> PAGE_SHIFT))); } extern inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; } 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< * Alexander Kjeldaas * with help from Aleph1, Roland Buresund and Andrew Main. + * + * See here for the libcap library ("POSIX draft" compliance): + * + * ftp://linux.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.2/ */ #ifndef _LINUX_CAPABILITY_H @@ -170,8 +174,8 @@ #define CAP_IPC_OWNER 15 -/* Insert and remove kernel modules */ - +/* Insert and remove kernel modules - modify kernel without limit */ +/* Modify cap_bset */ #define CAP_SYS_MODULE 16 /* Allow ioperm/iopl access */ @@ -294,12 +298,12 @@ #define CAP_EMPTY_SET to_cap_t(0) #define CAP_FULL_SET to_cap_t(~0) #define CAP_INIT_EFF_SET to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP)) -#define CAP_INIT_INH_SET to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP)) +#define CAP_INIT_INH_SET to_cap_t(0) #define CAP_TO_MASK(x) (1 << (x)) #define cap_raise(c, flag) (cap_t(c) |= CAP_TO_MASK(flag)) #define cap_lower(c, flag) (cap_t(c) &= ~CAP_TO_MASK(flag)) -#define cap_raised(c, flag) (cap_t(c) & CAP_TO_MASK(flag) & cap_bset) +#define cap_raised(c, flag) (cap_t(c) & CAP_TO_MASK(flag)) static inline kernel_cap_t cap_combine(kernel_cap_t a, kernel_cap_t b) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/cdrom.h linux.ac/include/linux/cdrom.h --- linux.vanilla/include/linux/cdrom.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/cdrom.h Sun Jun 4 22:31:05 2000 @@ -477,16 +477,11 @@ /* This seems to be a SCSI specific CD-ROM opcode * to play data at track/index */ #define GPCMD_PLAYAUDIO_TI 0x48 - -/* Is this really used by anything? I couldn't find these...*/ -#if 0 -/* MMC2/MTFuji Opcodes */ -#define ERASE 0x2c -#define READ_BUFFER 0x3c -#endif - - - +/* + * From MS Media Status Notification Support Specification. For + * older drives only. + */ +#define GPCMD_GET_MEDIA_STATUS 0xda /* Mode page codes for mode sense/set */ #define GPMODE_R_W_ERROR_PAGE 0x01 @@ -997,6 +992,22 @@ __u8 subhdr2; __u8 subhdr3; } __attribute__((packed)) write_param_page; + +struct modesel_head +{ + __u8 reserved1; + __u8 medium; + __u8 reserved2; + __u8 block_desc_length; + __u8 density; + __u8 number_of_blocks_hi; + __u8 number_of_blocks_med; + __u8 number_of_blocks_lo; + __u8 reserved3; + __u8 block_length_hi; + __u8 block_length_med; + __u8 block_length_lo; +}; #endif /* End of kernel only stuff */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/fs.h linux.ac/include/linux/fs.h --- linux.vanilla/include/linux/fs.h Thu May 25 17:46:16 2000 +++ linux.ac/include/linux/fs.h Sun Jun 4 22:31:01 2000 @@ -47,7 +47,12 @@ #define BLOCK_SIZE (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/ide.h linux.ac/include/linux/ide.h --- linux.vanilla/include/linux/ide.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/ide.h Sun Jun 4 22:32:26 2000 @@ -58,6 +58,14 @@ #endif #endif /* CONFIG_BLK_DEV_CMD640 */ +#ifndef SPIN_FLAGS_SET +#define SPIN_FLAGS_SET 0 +#endif + +#ifndef DISABLE_IRQ_NOSYNC +#define DISABLE_IRQ_NOSYNC 0 +#endif + /* * IDE_DRIVE_CMD is used to implement many features of the hdparm utility */ @@ -614,12 +622,14 @@ /* * This is used for (nearly) all data transfers from/to the IDE interface + * FIXME for 2.5, to a pointer pass verses memcpy........ */ void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); /* * This is used for (nearly) all ATAPI data transfers from/to the IDE interface + * FIXME for 2.5, to a pointer pass verses memcpy........ */ void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); @@ -750,6 +760,7 @@ int ide_driveid_update (ide_drive_t *drive); int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature); int ide_config_drive_speed (ide_drive_t *drive, byte speed); +byte eighty_ninty_three (ide_drive_t *drive); int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature); /* @@ -784,7 +795,12 @@ */ int drive_is_flashcard (ide_drive_t *drive); +#if SPIN_FLAGS_SET +int ide_spin_wait_hwgroup (ide_drive_t *drive, unsigned long *flags); +#else int ide_spin_wait_hwgroup (ide_drive_t *drive); +#endif /* SPIN_FLAGS_SET */ + void ide_timer_expiry (unsigned long data); void ide_intr (int irq, void *dev_id, struct pt_regs *regs); void do_ide_request (request_queue_t * q); 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 Sun Jun 4 22:46:18 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 Sun Jun 4 22:32:07 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 Sun Jun 4 22:31:01 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/ncp_fs_i.h linux.ac/include/linux/ncp_fs_i.h --- linux.vanilla/include/linux/ncp_fs_i.h Thu May 25 17:37:33 2000 +++ linux.ac/include/linux/ncp_fs_i.h Sun Jun 4 21:48:39 2000 @@ -19,7 +19,8 @@ __u32 DosDirNum __attribute__((packed)); __u32 volNumber __attribute__((packed)); __u32 nwattr; - int opened; + struct semaphore open_sem; + atomic_t opened; int access; __u32 server_file_handle __attribute__((packed)); __u8 open_create_action __attribute__((packed)); 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 Sun Jun 4 22:31:01 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/netfilter_ipv4/ip_conntrack_tuple.h linux.ac/include/linux/netfilter_ipv4/ip_conntrack_tuple.h --- linux.vanilla/include/linux/netfilter_ipv4/ip_conntrack_tuple.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/netfilter_ipv4/ip_conntrack_tuple.h Wed May 31 11:18:09 2000 @@ -31,7 +31,6 @@ { u_int32_t ip; union ip_conntrack_manip_proto u; - u_int16_t pad; /* Must be set to 0 for memcmp. */ }; /* This contains the information to distinguish a connection. */ 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 Sun Jun 4 22:31:01 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/reboot.h linux.ac/include/linux/reboot.h --- linux.vanilla/include/linux/reboot.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/reboot.h Wed May 31 11:36:24 2000 @@ -34,7 +34,6 @@ #include -extern struct notifier_block *reboot_notifier_list; extern int register_reboot_notifier(struct notifier_block *); extern int unregister_reboot_notifier(struct notifier_block *); 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/sunrpc/debug.h linux.ac/include/linux/sunrpc/debug.h --- linux.vanilla/include/linux/sunrpc/debug.h Thu May 25 17:37:34 2000 +++ linux.ac/include/linux/sunrpc/debug.h Sun Jun 4 22:31:17 2000 @@ -9,13 +9,17 @@ #ifndef _LINUX_SUNRPC_DEBUG_H_ #define _LINUX_SUNRPC_DEBUG_H_ +#include + #include #include /* * Enable RPC debugging/profiling. */ +#ifdef CONFIG_SYSCTL #define RPC_DEBUG +#endif /* #define RPC_PROFILE */ /* 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 Sun Jun 4 22:19:09 2000 @@ -161,6 +161,16 @@ extern spinlock_t pagemap_lru_lock; /* + * Magic constants for page aging. If the system is programmed + * right, tweaking these should have almost no effect... + * The 2.4 code, however, is mostly simple and stable ;) + */ +#define PG_AGE_MAX 64 +#define PG_AGE_START 2 +#define PG_AGE_ADV 3 +#define PG_AGE_DECL 1 + +/* * Helper macros for lru_pages handling. */ #define lru_cache_add(page) \ @@ -168,12 +178,15 @@ spin_lock(&pagemap_lru_lock); \ list_add(&(page)->lru, &lru_cache); \ nr_lru_pages++; \ + page->age = PG_AGE_START; \ + 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 Sun Jun 4 22:04:00 2000 @@ -1,6 +1,8 @@ #ifndef _LINUX_TIMER_H #define _LINUX_TIMER_H +#ifdef __KERNEL__ + #include #include @@ -91,9 +93,11 @@ #define timer_set_running(t) (void)(t) #define timer_is_running(t) (0) #define timer_synchronize(t) do { (void)(t); barrier(); } while(0) -#define del_timer_sync(t) del_timer(t) +#define del_timer_sync del_timer #endif +#define del_timer_async del_timer + /* * These inlines deal with timer wrapping correctly. You are * strongly encouraged to use them @@ -111,4 +115,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 Sun Jun 4 22:37:49 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/ipc/shm.c linux.ac/ipc/shm.c --- linux.vanilla/ipc/shm.c Thu May 25 17:37:50 2000 +++ linux.ac/ipc/shm.c Sun Jun 4 22:06:32 2000 @@ -16,11 +16,9 @@ * * The filesystem has the following restrictions/bugs: * 1) It only can handle one directory. - * 2) Because the directory is represented by the SYSV shm array it - * can only be mounted one time. - * 3) Private writeable mappings are not supported - * 4) Read and write are not implemented (should they?) - * 5) No special nodes are supported + * 2) Private writeable mappings are not supported + * 3) Read and write are not implemented (should they?) + * 4) No special nodes are supported * * There are the following mount options: * - nr_blocks (^= shmall) is the number of blocks of size PAGE_SIZE @@ -335,7 +333,7 @@ return (struct shmid_kernel *)ipc_rmid(&shm_ids,id); } -static __inline__ int shm_addid(struct shmid_kernel *shp) +static inline int shm_addid(struct shmid_kernel *shp) { return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni+1); } @@ -544,13 +542,37 @@ return 0; } -#define SHM_ENTRY(shp, index) (shp)->shm_dir[(index)/PTRS_PER_PTE][(index)%PTRS_PER_PTE] +/* + * We cannot use kmalloc for shm_alloc since this restricts the + * maximum size of the segments. + * + * We also cannot use vmalloc, since this uses too much of the vmalloc + * space and we run out of this on highend machines. + * + * So we have to use this complicated indirect scheme to alloc the shm + * page tables. + * + */ + +#ifdef PTE_INIT +static inline void init_ptes (pte_t *pte, int number) { + while (number--) + PTE_INIT (pte++); +} +#else +static inline void init_ptes (pte_t *pte, int number) { + memset (pte, 0, number*sizeof(*pte)); +} +#endif + +#define PTES_PER_PAGE (PAGE_SIZE/sizeof(pte_t)) +#define SHM_ENTRY(shp, index) (shp)->shm_dir[(index)/PTES_PER_PAGE][(index)%PTES_PER_PAGE] static pte_t **shm_alloc(unsigned long pages, int doacc) { - unsigned short dir = pages / PTRS_PER_PTE; - unsigned short last = pages % PTRS_PER_PTE; - pte_t **ret, **ptr, *pte; + unsigned short dir = pages / PTES_PER_PAGE; + unsigned short last = pages % PTES_PER_PAGE; + pte_t **ret, **ptr; if (pages == 0) return NULL; @@ -564,8 +586,7 @@ *ptr = (pte_t *)__get_free_page (GFP_KERNEL); if (!*ptr) goto free; - for (pte = *ptr; pte < *ptr + PTRS_PER_PTE; pte++) - pte_clear (pte); + init_ptes (*ptr, PTES_PER_PAGE); } /* The last one is probably not of PAGE_SIZE: we use kmalloc */ @@ -573,8 +594,7 @@ *ptr = kmalloc (last*sizeof(pte_t), GFP_KERNEL); if (!*ptr) goto free; - for (pte = *ptr; pte < *ptr + last; pte++) - pte_clear (pte); + init_ptes (*ptr, last); } if (doacc) { shm_lockall(); @@ -597,14 +617,14 @@ static void shm_free(pte_t** dir, unsigned long pages, int doacc) { int i, rss, swp; - pte_t **ptr = dir+pages/PTRS_PER_PTE; + pte_t **ptr = dir+pages/PTES_PER_PAGE; if (!dir) return; for (i = 0, rss = 0, swp = 0; i < pages ; i++) { pte_t pte; - pte = dir[i/PTRS_PER_PTE][i%PTRS_PER_PTE]; + pte = dir[i/PTES_PER_PAGE][i%PTES_PER_PAGE]; if (pte_none(pte)) continue; if (pte_present(pte)) { @@ -617,7 +637,7 @@ } /* first the last page */ - if (pages%PTRS_PER_PTE) + if (pages%PTES_PER_PAGE) kfree (*ptr); /* now the whole pages */ while (--ptr >= dir) @@ -663,10 +683,10 @@ BUG(); error = -ENOSPC; if (shm_tot - shp->shm_npages >= shm_ctlall) - goto out; + goto size_out; error = 0; if (shp->shm_segsz == attr->ia_size) - goto out; + goto size_out; /* Now we set them to the real values */ old_dir = shp->shm_dir; old_pages = shp->shm_npages; @@ -674,8 +694,8 @@ pte_t *swap; int i,j; i = old_pages < new_pages ? old_pages : new_pages; - j = i % PTRS_PER_PTE; - i /= PTRS_PER_PTE; + j = i % PTES_PER_PAGE; + i /= PTES_PER_PAGE; if (j) memcpy (new_dir[i], old_dir[i], j * sizeof (pte_t)); while (i--) { @@ -687,10 +707,21 @@ shp->shm_dir = new_dir; shp->shm_npages = new_pages; shp->shm_segsz = attr->ia_size; -out: +size_out: shm_unlock(inode->i_ino); shm_free (old_dir, old_pages, 1); + set_attr: + if (!(shp = shm_lock(inode->i_ino))) + BUG(); + if (attr->ia_valid & ATTR_MODE) + shp->shm_perm.mode = attr->ia_mode; + if (attr->ia_valid & ATTR_UID) + shp->shm_perm.uid = attr->ia_uid; + if (attr->ia_valid & ATTR_GID) + shp->shm_perm.gid = attr->ia_gid; + shm_unlock (inode->i_ino); + inode_setattr(inode, attr); return error; } @@ -1073,6 +1104,9 @@ case IPC_SET: { + struct dentry * dentry; + char name[SHM_FMT_LEN+1]; + if ((shmid % SEQ_MULTIPLIER)== zero_id) return -EINVAL; @@ -1098,7 +1132,29 @@ shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO) | (setbuf.mode & S_IRWXUGO); shp->shm_ctim = CURRENT_TIME; - break; + shm_unlock(shmid); + up(&shm_ids.sem); + + sprintf (name, SHM_FMT, shmid); + lock_kernel(); + dentry = lookup_one(name, lock_parent(shm_sb->s_root)); + unlock_dir(shm_sb->s_root); + err = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto bad_dentry; + err = -ENOENT; + if (dentry->d_inode) { + struct inode *ino = dentry->d_inode; + ino->i_uid = setbuf.uid; + ino->i_gid = setbuf.gid; + ino->i_mode = (setbuf.mode & S_IRWXUGO) | (ino->i_mode & ~S_IALLUGO);; + ino->i_atime = ino->i_mtime = ino->i_ctime = CURRENT_TIME; + err = 0; + } + dput (dentry); + bad_dentry: + unlock_kernel(); + return err; } default: @@ -1492,7 +1548,7 @@ shm_lockall(); check_id: shp = shm_get(swap_id); - if(shp==NULL || shp->shm_flags & SHM_LOCKED) { + if(shp==NULL || shp->shm_flags & PRV_LOCKED) { next_id: swap_idx = 0; if (++swap_id > shm_ids.max_id) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/ipc/util.c linux.ac/ipc/util.c --- linux.vanilla/ipc/util.c Thu May 25 17:37:50 2000 +++ linux.ac/ipc/util.c Sun Jun 4 22:06:32 2000 @@ -310,7 +310,7 @@ int map_zero_setup(struct vm_area_struct *vma) { - return -EINVAL; + return -ENOSYS; } #endif /* CONFIG_SYSVIPC */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/acct.c linux.ac/kernel/acct.c --- linux.vanilla/kernel/acct.c Thu May 25 17:46:17 2000 +++ linux.ac/kernel/acct.c Sun Jun 4 22:17:00 2000 @@ -37,6 +37,10 @@ * one race (and leak) in BSD implementation. * OK, that's better. ANOTHER race and leak in BSD variant. There always * is one more bug... 10/11/98, AV. + * + * Oh, fsck... Oopsable SMP race in do_process_acct() - we must hold + * ->mmap_sem to walk the vma list of current->mm. Nasty, since it leaks + * a struct file opened for write. Fixed. 2/6/2000, AV. */ #include @@ -66,7 +70,6 @@ /* * External references and all of the globals. */ -void acct_timeout(unsigned long); static volatile int acct_active; static volatile int acct_needcheck; @@ -77,7 +80,7 @@ /* * Called whenever the timer says to check the free space. */ -void acct_timeout(unsigned long unused) +static void acct_timeout(unsigned long unused) { acct_needcheck = 1; } @@ -303,11 +306,14 @@ vsize = 0; if (current->mm) { - struct vm_area_struct *vma = current->mm->mmap; + struct vm_area_struct *vma; + down(¤t->mm->mmap_sem); + vma = current->mm->mmap; while (vma) { vsize += vma->vm_end - vma->vm_start; vma = vma->vm_next; } + up(¤t->mm->mmap_sem); } vsize = vsize / 1024; ac.ac_mem = encode_comp_t(vsize); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/capability.c linux.ac/kernel/capability.c --- linux.vanilla/kernel/capability.c Thu May 25 17:37:33 2000 +++ linux.ac/kernel/capability.c Wed May 31 11:17:01 2000 @@ -8,6 +8,8 @@ #include #include +kernel_cap_t cap_bset = CAP_INIT_EFF_SET; + /* Note: never hold tasklist_lock while spinning for this one */ spinlock_t task_capability_lock = SPIN_LOCK_UNLOCKED; @@ -16,8 +18,6 @@ * capability set pointers may be NULL -- indicating that that set is * uninteresting and/or not to be changed. */ - -kernel_cap_t cap_bset = CAP_FULL_SET; asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/dma.c linux.ac/kernel/dma.c --- linux.vanilla/kernel/dma.c Thu May 25 17:37:33 2000 +++ linux.ac/kernel/dma.c Wed May 31 11:36:24 2000 @@ -115,9 +115,8 @@ return -EINVAL; } -int free_dma(unsigned int dmanr) +void free_dma(unsigned int dmanr) { - return -EINVAL; } int get_dma_list(char *buf) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/kmod.c linux.ac/kernel/kmod.c --- linux.vanilla/kernel/kmod.c Thu May 25 17:37:33 2000 +++ linux.ac/kernel/kmod.c Sun Jun 4 22:06:05 2000 @@ -95,9 +95,8 @@ /* Drop the "current user" thing */ free_uid(current); - /* Give kmod all privileges.. */ + /* Give kmod all effective privileges.. */ current->uid = current->euid = current->fsuid = 0; - cap_set_full(current->cap_inheritable); cap_set_full(current->cap_effective); /* Allow execve args to be in kernel space. */ 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/panic.c linux.ac/kernel/panic.c --- linux.vanilla/kernel/panic.c Thu May 25 17:37:33 2000 +++ linux.ac/kernel/panic.c Wed May 31 11:36:24 2000 @@ -19,7 +19,6 @@ asmlinkage void sys_sync(void); /* it's really int */ extern void unblank_console(void); -extern int C_A_D; int panic_timeout; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/signal.c linux.ac/kernel/signal.c --- linux.vanilla/kernel/signal.c Thu May 25 17:46:17 2000 +++ linux.ac/kernel/signal.c Wed May 31 11:36:24 2000 @@ -1109,7 +1109,7 @@ } #endif /* !defined(__alpha__) */ -#if !defined(__alpha__) && !defined(__mips__) +#if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips__) /* * For backwards compatibility. Functionality superseded by sigaction. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/sys.c linux.ac/kernel/sys.c --- linux.vanilla/kernel/sys.c Thu May 25 17:37:33 2000 +++ linux.ac/kernel/sys.c Wed May 31 11:36:24 2000 @@ -46,7 +46,7 @@ * and the like. */ -struct notifier_block *reboot_notifier_list = NULL; +static struct notifier_block *reboot_notifier_list = NULL; int register_reboot_notifier(struct notifier_block * nb) { 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 Wed May 31 11:17:01 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}, @@ -803,8 +803,11 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp) { + if (!capable(CAP_SYS_MODULE)) { + return -EPERM; + } return do_proc_dointvec(table,write,filp,buffer,lenp,1, - (current->pid == 1) ? OP_SET : OP_AND); + (current->pid == 1) ? OP_SET : OP_AND); } int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/kernel/timer.c linux.ac/kernel/timer.c --- linux.vanilla/kernel/timer.c Thu May 25 17:37:33 2000 +++ linux.ac/kernel/timer.c Sun Jun 4 22:04:00 2000 @@ -238,7 +238,17 @@ if (!running) return ret; - timer_synchronize(timer); + + { + int count = 50*1000*1000; + while (timer_is_running(timer) && --count) + ; + if (count == 0) { + printk( "del_timer_sync(%p): deadlock! Called from %p\n", + timer, __builtin_return_address(0)); + printk("See http://www.uow.edu.au/~andrewm/linux/deadlock.html\n"); + } + } } return ret; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/lib/vsprintf.c linux.ac/lib/vsprintf.c --- linux.vanilla/lib/vsprintf.c Thu May 25 17:37:33 2000 +++ linux.ac/lib/vsprintf.c Wed May 31 11:36:24 2000 @@ -31,8 +31,8 @@ } } } - while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) - ? toupper(*cp) : *cp)-'A'+10) < base) { + while (isxdigit(*cp) && + (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { result = result*base + value; cp++; } @@ -48,14 +48,11 @@ return simple_strtoul(cp,endp,base); } -/* we use this so that we can do without the ctype library */ -#define is_digit(c) ((c) >= '0' && (c) <= '9') - static int skip_atoi(const char **s) { int i=0; - while (is_digit(**s)) + while (isdigit(**s)) i = i*10 + *((*s)++) - '0'; return i; } @@ -175,7 +172,7 @@ /* get field width */ field_width = -1; - if (is_digit(*fmt)) + if (isdigit(*fmt)) field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; @@ -191,7 +188,7 @@ precision = -1; if (*fmt == '.') { ++fmt; - if (is_digit(*fmt)) + if (isdigit(*fmt)) precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; 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 Sun Jun 4 22:19:09 2000 @@ -56,6 +56,8 @@ #define CLUSTER_PAGES (1 << page_cluster) #define CLUSTER_OFFSET(x) (((x) >> page_cluster) << page_cluster) +#define min(a,b) ((a < b) ? a : b) + void __add_page_to_hash_queue(struct page * page, struct page **p) { atomic_inc(&page_cache_size); @@ -90,10 +92,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 +109,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); @@ -114,16 +119,16 @@ * @inode: the inode which pages we want to invalidate * * This function only removes the unlocked pages, if you want to - * remove all the pages of one inode, you must call truncate_inode_pages. + * remove all the pages of one inode, you must call + * truncate_inode_pages. This function is not supposed to be called + * by block based filesystems. */ - void invalidate_inode_pages(struct inode * inode) { struct list_head *head, *curr; struct page * page; head = &inode->i_mapping->pages; - spin_lock(&pagecache_lock); spin_lock(&pagemap_lru_lock); curr = head->next; @@ -135,20 +140,53 @@ /* We cannot invalidate a locked page */ if (TryLockPage(page)) continue; + /* We _should not be called_ by block based filesystems */ + if (page->buffers) + BUG(); - __lru_cache_del(page); __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 +206,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 +220,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 +238,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 +314,15 @@ page = list_entry(page_lru, struct page, lru); list_del(page_lru); - if (PageTestandClearReferenced(page)) + if (PageTestandClearReferenced(page)) { + page->age += PG_AGE_ADV; + if (page->age > PG_AGE_MAX) + page->age = PG_AGE_MAX; + goto dispose_continue; + } + page->age -= min(PG_AGE_DECL, page->age); + + if (page->age) goto dispose_continue; count--; @@ -303,6 +361,13 @@ } } + /* + * 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 unlock_continue; + /* Take the pagecache_lock spinlock held to avoid other tasks to notice the page while we are looking at its page count. If it's a pagecache-page we'll free it @@ -322,17 +387,23 @@ * 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) { + spin_unlock(&pagecache_lock); + /* Do NOT unlock the page ... brw_page does. */ + ClearPageDirty(page); + rw_swap_page(WRITE, page, 0); + spin_lock(&pagemap_lru_lock); + page_cache_release(page); + goto dispose_continue; + } goto cache_unlock_continue; + } /* is it a page-cache page? */ if (page->mapping) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/mm/memory.c linux.ac/mm/memory.c --- linux.vanilla/mm/memory.c Thu May 25 17:37:33 2000 +++ linux.ac/mm/memory.c Wed May 31 11:24:24 2000 @@ -847,7 +847,7 @@ UnlockPage(old_page); break; } - delete_from_swap_cache_nolock(old_page); + SetPageDirty(old_page); UnlockPage(old_page); /* FallThrough */ case 1: @@ -1058,7 +1058,7 @@ */ lock_page(page); swap_free(entry); - if (write_access && !is_page_shared(page)) { + if (write_access && !is_page_shared(page) && nr_free_highpages()) { delete_from_swap_cache_nolock(page); UnlockPage(page); page = replace_with_highmem(page); 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 Sun Jun 4 22:19:09 2000 @@ -29,7 +29,7 @@ pg_data_t *pgdat_list; static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; -static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 128, }; +static int zone_balance_ratio[MAX_NR_ZONES] = { 128, 128, 512, }; static int zone_balance_min[MAX_NR_ZONES] = { 10 , 10, 10, }; static int zone_balance_max[MAX_NR_ZONES] = { 255 , 255, 255, }; @@ -93,6 +93,8 @@ BUG(); if (PageDecrAfter(page)) BUG(); + if (PageDirty(page)) + BUG(); zone = page->zone; @@ -139,10 +141,13 @@ spin_unlock_irqrestore(&zone->lock, flags); - if (zone->free_pages > zone->pages_high) { - zone->zone_wake_kswapd = 0; + if (zone->free_pages >= zone->pages_low) { zone->low_on_memory = 0; } + + if (zone->free_pages >= zone->pages_high) { + zone->zone_wake_kswapd = 0; + } } #define MARK_USED(index, order, area) \ @@ -217,6 +222,9 @@ { zone_t **zone = zonelist->zones; extern wait_queue_head_t kswapd_wait; + static int last_woke_kswapd; + static int kswapd_pause = HZ; + int gfp_mask = zonelist->gfp_mask; /* * (If anyone calls gfp from interrupts nonatomically then it @@ -237,8 +245,6 @@ struct page *page = rmqueue(z, order); if (z->free_pages < z->pages_low) { z->zone_wake_kswapd = 1; - if (waitqueue_active(&kswapd_wait)) - wake_up_interruptible(&kswapd_wait); } if (page) return page; @@ -246,9 +252,27 @@ } /* + * Kswapd should be freeing enough memory to satisfy all allocations + * immediately. Calling try_to_free_pages from processes will slow + * down the system a lot. On the other hand, waking up kswapd too + * often means wasted memory and cpu time. + * + * We tune the kswapd pause interval in such a way that kswapd is + * always just agressive enough to free the amount of memory we + * want freed. + */ + if (waitqueue_active(&kswapd_wait) && + time_after(jiffies, last_woke_kswapd + kswapd_pause)) { + kswapd_pause++; + last_woke_kswapd = jiffies; + wake_up_interruptible(&kswapd_wait); + } + + /* * Ok, we don't have any zones that don't need some * balancing.. See if we have any that aren't critical.. */ +again: zone = zonelist->zones; for (;;) { zone_t *z = *(zone++); @@ -256,20 +280,33 @@ break; if (!z->low_on_memory) { struct page *page = rmqueue(z, order); - if (z->free_pages < z->pages_min) + if (z->free_pages < (z->pages_min + z->pages_low) / 2) z->low_on_memory = 1; if (page) return page; + } else { + if (kswapd_pause > 0) + kswapd_pause--; } } + /* We didn't kick kswapd often enough... */ + kswapd_pause /= 2; + if (waitqueue_active(&kswapd_wait)) + wake_up_interruptible(&kswapd_wait); + /* If we're low priority, we just wait a bit and try again later. */ + if ((gfp_mask & __GFP_WAIT) && current->need_resched && + current->state == TASK_RUNNING) { + schedule(); + goto again; + } + /* * Uhhuh. All the zones have been critical, which means that * we'd better do some synchronous swap-out. kswapd has not * been able to cope.. */ if (!(current->flags & PF_MEMALLOC)) { - int gfp_mask = zonelist->gfp_mask; if (!try_to_free_pages(gfp_mask)) { if (!(gfp_mask & __GFP_HIGH)) goto fail; @@ -277,7 +314,7 @@ } /* - * Final phase: allocate anything we can! + * We freed something, so we're allowed to allocate anything we can! */ zone = zonelist->zones; for (;;) { @@ -292,6 +329,18 @@ } fail: + /* Last try, zone->low_on_memory isn't reset until we hit pages_low */ + zone = zonelist->zones; + for (;;) { + zone_t *z = *(zone++); + if (!z) + break; + if (z->free_pages > z->pages_min) { + struct page *page = rmqueue(z, order); + if (page) + return page; + } + } /* No luck.. */ return NULL; } 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 Sun Jun 4 22:19:09 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); @@ -430,12 +439,12 @@ * latency. */ #define FREE_COUNT 8 -#define SWAP_COUNT 16 static int do_try_to_free_pages(unsigned int gfp_mask) { int priority; int count = FREE_COUNT; - int swap_count; + int swap_count = 0; + int ret = 0; /* Always trim SLAB caches when memory gets low. */ kmem_cache_reap(gfp_mask); @@ -443,6 +452,7 @@ priority = 64; do { while (shrink_mmap(priority, gfp_mask)) { + ret = 1; if (!--count) goto done; } @@ -457,9 +467,12 @@ */ count -= shrink_dcache_memory(priority, gfp_mask); count -= shrink_icache_memory(priority, gfp_mask); - if (count <= 0) + if (count <= 0) { + ret = 1; goto done; + } while (shm_swap(priority, gfp_mask)) { + ret = 1; if (!--count) goto done; } @@ -471,24 +484,30 @@ * This will not actually free any pages (they get * put in the swap cache), so we must not count this * as a "count" success. + * + * The amount we page out is the amount of pages we're + * short freeing, amplified by the number of times we + * failed above. This generates a negative feedback loop: + * the more difficult it was to free pages, the easier we + * will make it. */ - swap_count = SWAP_COUNT; - while (swap_out(priority, gfp_mask)) + swap_count += count; + while (swap_out(priority, gfp_mask)) { if (--swap_count < 0) break; + } } while (--priority >= 0); /* Always end on a shrink_mmap.. */ while (shrink_mmap(0, gfp_mask)) { + ret = 1; if (!--count) goto done; } - /* We return 1 if we are freed some page */ - return (count != FREE_COUNT); done: - return 1; + return ret; } DECLARE_WAIT_QUEUE_HEAD(kswapd_wait); 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/ip_conntrack_core.c linux.ac/net/ipv4/netfilter/ip_conntrack_core.c --- linux.vanilla/net/ipv4/netfilter/ip_conntrack_core.c Thu May 25 17:37:38 2000 +++ linux.ac/net/ipv4/netfilter/ip_conntrack_core.c Wed May 31 11:18:09 2000 @@ -99,10 +99,6 @@ #if 0 dump_tuple(tuple); #endif -#ifdef CONFIG_NETFILTER_DEBUG - if (tuple->src.pad) - DEBUGP("Tuple %p has non-zero padding.\n", tuple); -#endif /* ntohl because more differences in low bits. */ /* To ensure that halves of the same connection don't hash clash, we add the source per-proto again. */ @@ -132,8 +128,8 @@ else if (iph->ihl * 4 + 8 > len) return 0; + memset(tuple, 0, sizeof(*tuple)); tuple->src.ip = iph->saddr; - tuple->src.pad = 0; tuple->dst.ip = iph->daddr; tuple->dst.protonum = iph->protocol; @@ -148,8 +144,8 @@ const struct ip_conntrack_tuple *orig, const struct ip_conntrack_protocol *protocol) { + memset(inverse, 0, sizeof(*inverse)); inverse->src.ip = orig->dst.ip; - inverse->src.pad = 0; inverse->dst.ip = orig->src.ip; inverse->dst.protonum = orig->dst.protonum; @@ -867,10 +863,14 @@ getorigdst(struct sock *sk, int optval, void *user, int *len) { struct ip_conntrack_tuple_hash *h; - struct ip_conntrack_tuple tuple = { { sk->rcv_saddr, { sk->sport }, - 0 }, - { sk->daddr, { sk->dport }, - IPPROTO_TCP } }; + struct ip_conntrack_tuple tuple; + + memset(&tuple, 0, sizeof(tuple)); + tuple.src.ip = sk->rcv_saddr; + tuple.src.u.tcp.port = sk->sport; + tuple.dst.ip = sk->daddr; + tuple.dst.u.tcp.port = sk->dport; + tuple.dst.protonum = IPPROTO_TCP; /* We only do TCP at the moment: is there a better way? */ if (strcmp(sk->prot->name, "TCP") != 0) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/ipv4/netfilter/ip_conntrack_ftp.c linux.ac/net/ipv4/netfilter/ip_conntrack_ftp.c --- linux.vanilla/net/ipv4/netfilter/ip_conntrack_ftp.c Thu May 25 17:37:38 2000 +++ linux.ac/net/ipv4/netfilter/ip_conntrack_ftp.c Wed May 31 11:18:09 2000 @@ -206,13 +206,13 @@ info->ftptype = dir; info->port = array[4] << 8 | array[5]; - t = ((struct ip_conntrack_tuple) - { { ct->tuplehash[!dir].tuple.src.ip, - { 0 }, 0 }, - { htonl((array[0] << 24) | (array[1] << 16) - | (array[2] << 8) | array[3]), - { htons(array[4] << 8 | array[5]) }, - IPPROTO_TCP }}); + memset(&t, 0, sizeof(t)); + t.src.ip = ct->tuplehash[!dir].tuple.src.ip; + t.dst.ip = htonl((array[0] << 24) | (array[1] << 16) + | (array[2] << 8) | array[3]); + t.dst.u.tcp.port = htons(array[4] << 8 | array[5]); + t.dst.protonum = IPPROTO_TCP; + ip_conntrack_expect_related(ct, &t); UNLOCK_BH(&ip_ftp_lock); 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/cramfs/mkcramfs.c linux.ac/scripts/cramfs/mkcramfs.c --- linux.vanilla/scripts/cramfs/mkcramfs.c Thu May 25 17:38:37 2000 +++ linux.ac/scripts/cramfs/mkcramfs.c Sun Jun 4 22:14:58 2000 @@ -93,7 +93,7 @@ if(!orig) return 0; if(orig->size==newfile->size && orig->uncompressed && !memcmp(orig->uncompressed,newfile->uncompressed,orig->size)) { newfile->same=orig; - return 0; + return 1; } return find_identical_file(orig->child,newfile) || find_identical_file(orig->next,newfile); 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 Wed May 31 11:30:18 2000 @@ -110,6 +110,8 @@ wm geometry $w +$winx+$winy } +bind all {maybe_exit .maybe} + proc maybe_exit { w } { catch {destroy $w} toplevel $w -class Dialog @@ -128,6 +130,8 @@ -width 20 -command "destroy $w; focus $oldFocus" pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 pack $w.f -pady 10 -side bottom -padx 10 -anchor w + bind $w "exit" + bind $w "destroy $w; focus $oldFocus" focus $w global winx; global winy set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] @@ -402,6 +406,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] @@ -411,6 +416,10 @@ } } +proc menutitle {text menu w} { + wm title $w "$text" +} + proc submenu { w mnum line text subnum } { frame $w.x$line button $w.x$line.l -text "" -width 15 -relief groove @@ -531,6 +540,9 @@ wm maxsize $w [winfo width $w] $sizy } +bind all { catch {exec cp -f .config .config.old}; \ + writeconfig .config include/linux/autoconf.h; wrapup .wrap } + proc wrapup {w } { catch {destroy $w} toplevel $w -class Dialog @@ -554,6 +566,7 @@ pack $w.f.back -side bottom -pady 10 -anchor s pack $w.f -pady 10 -side top -padx 10 -anchor s focus $w + bind $w "exit" global winx; global winy set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] wm geometry $w +$winx+$winy 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/tail.tk linux.ac/scripts/tail.tk --- linux.vanilla/scripts/tail.tk Thu May 25 17:38:37 2000 +++ linux.ac/scripts/tail.tk Wed May 31 11:30:18 2000 @@ -32,11 +32,11 @@ update_define 1 $total_menus 0 update_mainmenu -button .f0.right.save -anchor w -text "Save and Exit" \ +button .f0.right.save -anchor w -text "Save and Exit" -underline 0\ -command { catch {exec cp -f .config .config.old}; \ writeconfig .config include/linux/autoconf.h; wrapup .wrap } -button .f0.right.quit -anchor w -text "Quit Without Saving" \ +button .f0.right.quit -anchor w -text "Quit Without Saving" -underline 0\ -command { maybe_exit .maybe } button .f0.right.load -anchor w -text "Load Configuration from File" \ 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 Sun Jun 4 21:22:09 2000 @@ -149,18 +149,10 @@ printf( "\tpack $w.m -pady 10 -side top -padx 10\n" ); printf( "\twm title $w \"%s\" \n\n", label ); - /* - * Attach the "Prev", "Next" and "OK" buttons at the end of the window. - */ - printf( "\tframe $w.f\n" ); - if ( toplevel ) - printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" ); - else - printf( "\tbutton $w.f.back -text \"OK\" \\\n" ); - printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d\"\n", - menu_num ); - printf( "\tbutton $w.f.next -text \"Next\" \\\n" ); - printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; " ); + printf( "\tbind $w \"catch {focus $oldFocus}; destroy $w; unregister_active %d; break\"\n", menu_num); + + printf("\tset nextscript "); + printf("\"catch {focus $oldFocus}; " ); /* * We are checking which windows should be destroyed and which are * common parrents with the next one. Remember that menu_num field @@ -182,13 +174,48 @@ } printf( "menu%d .menu%d \\\"$title\\\"\"\n", menu_num+1, menu_num+1 ); - if ( menu_num == tot_menu_num ) - printf( "\t$w.f.next configure -state disabled\n" ); - printf( "\tbutton $w.f.prev -text \"Prev\" \\\n" ); + + /* + * Attach the "Prev", "Next" and "OK" buttons at the end of the window. + */ + printf( "\tframe $w.f\n" ); + if ( toplevel ) + printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" ); + else + printf( "\tbutton $w.f.back -text \"OK\" \\\n" ); + printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d\"\n", + menu_num ); + printf( "\tbutton $w.f.next -text \"Next\" -underline 0\\\n" ); + printf( "\t\t-width 15 -command $nextscript\n"); + + if ( menu_num == tot_menu_num ) { + printf( "\t$w.f.next configure -state disabled\n" ); + /* + * this is a bit hackish but Alt-n must be rebound + * otherwise if the user press Alt-n on the last menu + * it will give him/her the next menu of one of the + * previous options + */ + printf( "\tbind all \"puts \\\"no more menus\\\" \"\n"); + } + else + { + /* + * I should be binding to $w not all - but if I do nehat I get the error "unknown path" + */ + printf( "\tbind all $nextscript\n"); + } + printf( "\tbutton $w.f.prev -text \"Prev\" -underline 0\\\n" ); printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\"\"\n", menu_num, menu_num-1, menu_num-1 ); - if ( menu_num == 1 ) + if ( menu_num == 1 ) { printf( "\t$w.f.prev configure -state disabled\n" ); + } + else + { + printf( "\tbind $w \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\";break\"\n", + menu_num, menu_num-1, menu_num-1 ); + } printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" ); printf( "\tpack $w.f -pady 10 -side bottom -anchor w -fill x\n" ); @@ -215,6 +242,12 @@ printf( "\t\t-relief flat -borderwidth 0 -yscrollcommand \"$w.config.vscroll set\" \\\n" ); printf( "\t\t-width [expr [winfo screenwidth .] * 1 / 2] \n" ); printf( "\tframe $w.config.f\n" ); + printf( "\tbind $w \"$w.config.canvas yview scroll 1 unit;break;\"\n"); + printf( "\tbind $w \"$w.config.canvas yview scroll -1 unit;break;\"\n"); + printf( "\tbind $w \"$w.config.canvas yview scroll 1 page;break;\"\n"); + printf( "\tbind $w \"$w.config.canvas yview scroll -1 page;break;\"\n"); + printf( "\tbind $w \"$w.config.canvas yview moveto 0;break;\"\n"); + printf( "\tbind $w \"$w.config.canvas yview moveto 1 ;break;\"\n"); printf( "\tpack $w.config.canvas -side right -fill y\n" ); printf("\n\n"); } @@ -1248,7 +1281,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: