From 0b48ceffbf52b9842c7840f48b84ea92c3b674e9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:29:24 -0500 Subject: [PATCH] Import 2.3.34pre3 --- CREDITS | 20 +- Documentation/Configure.help | 88 ++- Documentation/filesystems/vfat.txt | 5 - Documentation/proc_usb_info.txt | 49 +- Documentation/serial-console.txt | 1 + MAINTAINERS | 18 +- MAINTAINERS.orig | 1027 ---------------------------- Makefile | 18 +- arch/alpha/boot/Makefile | 4 +- arch/alpha/kernel/entry.S | 3 +- arch/alpha/lib/Makefile | 8 +- arch/arm/boot/compressed/Makefile | 6 +- arch/arm/kernel/Makefile | 2 +- arch/i386/boot/Makefile | 8 +- arch/i386/boot/compressed/Makefile | 2 +- arch/i386/config.in | 2 + arch/i386/kernel/apm.c | 143 ++-- arch/i386/kernel/entry.S | 10 +- arch/i386/kernel/head.S | 22 +- arch/i386/kernel/process.c | 84 ++- arch/i386/kernel/vm86.c | 2 +- arch/i386/math-emu/Makefile | 2 +- arch/m68k/fpsp040/Makefile | 2 +- arch/m68k/ifpsp060/Makefile | 2 +- arch/m68k/kernel/Makefile | 2 +- arch/m68k/lib/Makefile | 2 +- arch/m68k/math-emu/Makefile | 2 +- arch/m68k/sun3/Makefile | 2 +- arch/m68k/sun3/prom/Makefile | 2 +- arch/mips/arc/Makefile | 2 +- arch/mips/dec/prom/Makefile | 2 +- arch/mips/sgi/kernel/Makefile | 2 +- arch/ppc/Makefile | 4 +- arch/ppc/boot/Makefile | 8 +- arch/ppc/chrpboot/Makefile | 8 +- arch/ppc/coffboot/Makefile | 2 +- arch/ppc/kernel/gemini_setup.c | 9 +- arch/ppc/kernel/open_pic.c | 45 +- arch/ppc/kernel/open_pic.h | 1 + arch/ppc/kernel/pmac_pic.c | 2 +- arch/ppc/kernel/ppc_ksyms.c | 2 + arch/ppc/kernel/process.c | 9 - arch/ppc/kernel/smp.c | 174 ++--- arch/ppc/lib/Makefile | 2 +- arch/ppc/mbxboot/Makefile | 8 +- arch/ppc/mm/init.c | 51 +- arch/sparc/ap1000/Makefile | 4 +- arch/sparc/kernel/Makefile | 10 +- arch/sparc/lib/Makefile | 42 +- arch/sparc/math-emu/Makefile | 4 +- arch/sparc/prom/Makefile | 2 +- arch/sparc64/Makefile | 8 +- arch/sparc64/kernel/Makefile | 14 +- arch/sparc64/prom/Makefile | 2 +- drivers/block/Config.in | 10 +- drivers/char/console.c | 18 +- drivers/char/lp.c | 2 +- drivers/net/aironet4500.h | 104 ++- drivers/net/aironet4500_card.c | 4 +- drivers/net/aironet4500_core.c | 199 +++--- drivers/net/aironet4500_proc.c | 4 +- drivers/net/arlan-proc.c | 32 +- drivers/net/arlan.c | 106 ++- drivers/net/arlan.h | 61 +- drivers/net/pcmcia/Config.in | 9 +- drivers/net/pcmcia/netwave_cs.c | 4 +- drivers/net/pcmcia/ray_cs.c | 27 +- drivers/net/pcmcia/wavelan_cs.h | 4 +- drivers/net/tlan.c | 15 +- drivers/net/tlan.h | 5 - drivers/net/wan/cosa.c | 19 +- drivers/net/wan/hostess_sv11.c | 16 +- drivers/net/wan/sealevel.c | 28 +- drivers/net/wan/syncppp.c | 19 +- drivers/net/wan/syncppp.h | 6 +- drivers/pcmcia/bulkmem.c | 17 +- drivers/pcmcia/cs.c | 32 +- drivers/scsi/Makefile | 6 +- drivers/scsi/ips.c | 130 +++- drivers/scsi/ips.h | 201 +++--- drivers/scsi/scsi.c | 130 +++- drivers/scsi/scsi.h | 15 +- drivers/scsi/scsi_error.c | 8 +- drivers/scsi/scsi_ioctl.c | 16 +- drivers/scsi/scsi_lib.c | 129 ++-- drivers/scsi/scsi_merge.c | 129 +++- drivers/scsi/scsi_queue.c | 2 - drivers/scsi/sd.c | 3 +- drivers/scsi/sg.c | 17 +- drivers/scsi/sr.c | 7 +- drivers/scsi/sr_ioctl.c | 3 +- drivers/scsi/st.c | 2 +- drivers/usb/ohci-hcd.c | 18 +- drivers/usb/proc_usb.c | 15 +- drivers/usb/usb_scsi.c | 190 +++-- drivers/usb/usb_scsi.h | 3 +- drivers/usb/uss720.c | 8 +- fs/buffer.c | 5 +- fs/exec.c | 8 - fs/fat/dir.c | 181 +++-- fs/fat/inode.c | 9 +- fs/isofs/inode.c | 35 +- fs/minix/inode.c | 13 +- fs/read_write.c | 23 +- fs/vfat/namei.c | 320 +++++---- include/asm-alpha/unistd.h | 1 + include/asm-i386/hw_irq.h | 4 +- include/asm-ppc/cache.h | 32 - include/asm-ppc/smp.h | 3 +- include/asm-ppc/stat.h | 36 + include/linux/apm_bios.h | 3 - include/linux/fs.h | 2 +- include/linux/openpic.h | 8 +- include/pcmcia/bulkmem.h | 4 +- include/pcmcia/cs.h | 2 +- ipc/shm.c | 4 +- kernel/Makefile | 2 +- net/core/dev.c | 22 +- net/ipv4/af_inet.c | 10 +- net/netsyms.c | 1 + 120 files changed, 2088 insertions(+), 2368 deletions(-) delete mode 100644 MAINTAINERS.orig diff --git a/CREDITS b/CREDITS index c6ff4bebd762..28b905403de2 100644 --- a/CREDITS +++ b/CREDITS @@ -621,7 +621,7 @@ S: 1131 Budapest S: Hungary N: Jürgen Fischer -E: fischer@et-inf.fho-emden.de (=?iso-8859-1?q?J=FCrgen?= Fischer) +E: fischer@norbit.de (=?iso-8859-1?q?J=FCrgen?= Fischer) D: Author of Adaptec AHA-152x SCSI driver S: Schulstraße 18 S: 26506 Norden @@ -1082,12 +1082,13 @@ S: 1403 ND BUSSUM S: The Netherlands N: Karl Keyte -E: kkeyte@koft.rhein-main.de -E: kkeyte@esoc.esa.de +E: karl@koft.com D: Disk usage statistics and modifications to line printer driver -S: Erbacher Strasse 6 -S: D-64283 Darmstadt -S: Germany +S: 26a Sheen Road +S: Richmond +S: Surrey +S: TW9 1AE +S: United Kingdom N: Russell King E: rmk@arm.uk.linux.org @@ -2385,6 +2386,13 @@ S: 542 West 112th Street, 5N S: New York, New York 10025 S: USA +N: Victor Yodaiken +E: yodaiken@fsmlabs.com +D: RTLinux (RealTime Linux) +S: POB 1822 +S: Socorro NM, 87801 +S: USA + N: Eric Youngdale E: eric@aib.com D: General kernel hacker diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 458a5667e4d3..7df50c7549f6 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -5551,6 +5551,9 @@ CONFIG_AIRONET4500 channel=1..? meaningful in adhoc mode all other parameters can be set via proc interface These parameters belong to .._card module, but alas, they are here + if you have problems with screwin up card, both_bap_lock=1 is conservative + value (performance hit 15%) + for any other configuration options look at ..._proc module Aironet 4500/4800 ISA/PCI/PNP/365 support CONFIG_AIRONET4500_NONCS @@ -5606,7 +5609,8 @@ CONFIG_AIRONET4500_PROC NOTE: it takes lot of memory. Compile it as module and remove after configuration module: aironet4500_proc - + additional info: look into drivers/net/aironet4500_rids.c + this is quite human-readable(no need to know C) @@ -10174,11 +10178,6 @@ CONFIG_APM 11) exchange RAM chips 12) exchange the motherboard. - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - If you want to compile it as a module, say M here and read - Documentation/modules.txt. The module will be called apm.o. - Ignore USER SUSPEND CONFIG_APM_IGNORE_USER_SUSPEND This option will ignore USER SUSPEND requests. On machines with a @@ -10223,17 +10222,6 @@ CONFIG_APM_DISPLAY_BLANK backlight at all, or it might print a lot of errors to the console, especially if you are using gpm. -Power off on shutdown -CONFIG_APM_POWER_OFF - Enable the ability to power off the computer after the Linux kernel - is halted. You will need software (e.g., a suitable version of the - halt(8) command ("man 8 halt")) to cause the computer to power down. - Recent versions of the sysvinit package available from - ftp://metalab.unc.edu/pub/Linux/system/daemons/init/ contain support - for this ("halt -p" shuts down Linux and powers off the computer, if - executed from runlevel 0). As with the other APM options, this - option may not work reliably with some APM BIOS implementations. - Ignore multiple suspend/standby events CONFIG_APM_IGNORE_MULTIPLE_SUSPEND This option is necessary on the IBM Thinkpad 560, but should work on @@ -10271,6 +10259,20 @@ CONFIG_APM_ALLOW_INTS many of the newer IBM Thinkpads. If you experience hangs when you suspend, try setting this to Y. Otherwise, say N. +Entry point offset fix (some Acer laptops) +CONFIG_APM_BAD_ENTRY_OFFSET + Some implementations of the APM BIOS provide the driver with a bad + entry point offset. If you set this option to Y, then the upper + sixteen bits of the offset will be set to zero. This is usually + unnecessary but harmless. This is required for the Acer Travelmate + 510DX, Travelmate 510T and Extensa 503T. For others, say N. + +Use real mode APM BIOS call to power off +CONFIG_APM_REAL_MODE_POWER_OFF + Use real mode APM BIOS calls to switch off the computer. This is + a work-around for a number of buggy BIOSes. Switch this option on if + your computer crashes instead of powering off properly. + Watchdog Timer Support CONFIG_WATCHDOG If you say Y here (and to one of the following options) and create a @@ -13145,6 +13147,58 @@ CONFIG_KHTTPD The kHTTPd is experimental. Be careful when using it on a production machine. Also note that kHTTPd doesn't support virtual servers yet. +I2C support +CONFIG_I2C + I2C (pronounce: I-square-C) is a slow bus protocol developed by + Philips. SMBus, or System Management Bus is a sub-protocol of I2C. + + Both I2C and SMBus are supported here. You will need this for + hardware sensors support, and in the future for Video for Linux + support. + + Beside this option, you will also need to select specific drivers + for your bus adapter(s). + +I2C bit-banging interfaces +CONFIG_I2C_ALGOBIT + This allows you to use a range of I2C adapters called bit-banging + adapters. Why they are called so is rather technical and uninteresting; + but you need to select this if you own one of the adapters listed + under it. + +Philips style parallel port adapter +CONFIG_I2C_PHILIPSPAR + This supports parallel-port I2C adapters made by Philips. Unless you + own such an adapter, you do not need to select this. + +ELV adapter +CONFIG_I2C_ELV + This supports parallel-port I2C adapters called ELV. Unless you + own such an adapter, you do not need to select this. + +Velleman K9000 adapter +CONFIG_I2C_VELLEMAN + This supports the Velleman K9000 parallel-port I2C adapter. Unless + you own such an adapter, you do not need to select this. + +I2C PCF 8584 interfaces +CONFIG_I2C_ALGOPCF + This allows you to use a range of I2C adapters called PCF + adapters. Why they are called so is rather technical and uninteresting; + but you need to select this if you own one of the adapters listed + under it. + +Elektor ISA card +CONFIG_I2C_ELEKTOR + This supports the PCF8584 ISA bus I2C adapter. Unless you own such + an adapter, you do not need to select this. + +I2C device interface +CONFIG_I2C_CHARDEV + Here you find the drivers which allow you to use the i2c-* device + files, usually found in the /dev directory on your system. They + make it possible to have user-space programs use the I2C bus. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt index 8ee0ea9cc46d..b4b7a28bb990 100644 --- a/Documentation/filesystems/vfat.txt +++ b/Documentation/filesystems/vfat.txt @@ -52,11 +52,6 @@ check=s|r|n -- Case sensitivity checking setting. TODO ---------------------------------------------------------------------- -* When only shortnames exist, translate them from the codepage character - set to the iocharset. Currently, translations only occur when longnames - exist. To translate, first convert from codepage to Unicode and then - to the output character set. - * Need to get rid of the raw scanning stuff. Instead, always use a get next directory entry approach. The only thing left that uses raw scanning is the directory renaming code. diff --git a/Documentation/proc_usb_info.txt b/Documentation/proc_usb_info.txt index e3c7055811dd..38861818e625 100644 --- a/Documentation/proc_usb_info.txt +++ b/Documentation/proc_usb_info.txt @@ -1,6 +1,6 @@ /proc/bus/usb filesystem output =============================== -(version 19990722) +(version 19991218) The /proc filesystem for USB devices generates @@ -22,9 +22,11 @@ different topo/connections and it looked possible.) Each line is tagged with a one-character ID for that line: T = Topology (etc.) +B = Bandwidth D = Device descriptor info. P = Product ID info. (from Device descriptor, but they won't fit together on one line) +S = String info C = Configuration descriptor info. (* = active configuration) I = Interface descriptor info. E = Endpoint descriptor info. @@ -41,19 +43,26 @@ Legend: Topology info: -T: Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd If#=ddd MxCh=dd Driver=%s -| | | | | | | | | |__DriverName -| | | | | | | | |__MaxChildren -| | | | | | | |__Configured InterfaceNumber -| | | | | | |__Device Speed in Mbps -| | | | | |__DeviceNumber -| | | | |__Count of devices at this level -| | | |__Connector/Port on Parent for this device -| | |__Parent DeviceNumber -| |__Level in topology +T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd +| | | | | | | | |__MaxChildren +| | | | | | | |__Device Speed in Mbps +| | | | | | |__DeviceNumber +| | | | | |__Count of devices at this level +| | | | |__Connector/Port on Parent for this device +| | | |__Parent DeviceNumber +| | |__Level in topology for this bus +| |__Bus number |__Topology info tag +Bandwidth info: +B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd +| | | |__Number if isochronous requests +| | |__Number of interrupt requests +| |__Total Bandwidth allocated to this bus +|__Bandwidth info tag + + Device descriptor info & Product ID info: D: Ver=x.xx Cls=xx(s) Sub=xx Prot=xx MxPS=dd #Cfgs=dd @@ -77,6 +86,17 @@ P: Vendor=xxxx ProdID=xxxx Rev=xx.xx |__Device info tag #2 +String descriptor info: + +S: Manufacturer=ssss +| |__Manufacturer of this device as read from the device. +|__String info tag + +S: Product=ssss +| |__Product description of this device as read from the device. +|__String info tag + + Configuration descriptor info: C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA @@ -89,7 +109,8 @@ C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA Interface descriptor info (can be multiple per Config): -I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx +I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss +| | | | | | | |__Driver name | | | | | | |__InterfaceProtocol | | | | | |__InterfaceSubClass | | | | |__InterfaceClass @@ -103,8 +124,8 @@ Endpoint descriptor info (can be multiple per Interface): E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms -| | | | |__Interval -| | | |__EndpointMaxPacketSize +| | | | |__Interval +| | | |__EndpointMaxPacketSize | | |__Attributes(EndpointType) | |__EndpointAddress(I=In,O=Out) |__Endpoint info tag diff --git a/Documentation/serial-console.txt b/Documentation/serial-console.txt index 5b4168833a9e..80fd38300a5a 100644 --- a/Documentation/serial-console.txt +++ b/Documentation/serial-console.txt @@ -11,6 +11,7 @@ The format of this option is: device: tty0 for the foreground virtual console ttyX for any other virtual console ttySx for a serial port + lp0 for the first parallel port options: depend on the driver. For the serial port this defines the baudrate/parity/bits of the port, diff --git a/MAINTAINERS b/MAINTAINERS index 950ed588f907..42d30a0bb863 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -122,13 +122,13 @@ S: Maintained AHA152X SCSI DRIVER P: Juergen E. Fischer -M: Juergen Fischer +M: Juergen Fischer L: linux-scsi@vger.rutgers.edu S: Maintained APM DRIVER P: Stephen Rothwell -M: sfr@linuxcare.com +M: apm@linuxcare.com.au L: linux-laptop@vger.rutgers.edu W: http://linuxcare.com.au/apm/ S: Supported @@ -958,6 +958,13 @@ L: linux-usb@suse.com S: Maintained (not yet usable) W: http://suitenine.com/usb/ +USB SERIAL DRIVER +P: Greg Kroah-Hartman +M: greg@kroah.com +L: linux-usb@suse.com +S: Maintained +W: http://www.kroah.com/linux-usb/ + USB UHCI DRIVER P: Georg Acher M: usb@in.tum.de @@ -1008,6 +1015,13 @@ M: eis@baty.hanse.de L: linux-x25@vger.rutgers.edu S: Maintained +RTLINUX REALTIME LINUX +P: Victor Yodaiken +M: yodaiken@fsmlabs.com +L: rtl@rtlinux.org +W: www.rtlinux.org +S: Maintained + Z85230 SYNCHRONOUS DRIVER P: Alan Cox M: alan@redhat.com diff --git a/MAINTAINERS.orig b/MAINTAINERS.orig deleted file mode 100644 index f55bdcd42afe..000000000000 --- a/MAINTAINERS.orig +++ /dev/null @@ -1,1027 +0,0 @@ - List of maintainers and how to submit kernel changes - -Please try to follow the guidelines below. This will make things -easier on the maintainers. Not all of these guidelines matter for every -trivial patch so apply some common sense. - -1. Always _test_ your changes, however small, on at least 4 or - 5 people, preferably many more. - -2. Try to release a few ALPHA test versions to the net. Announce - them onto the kernel channel and await results. This is especially - important for device drivers, because often that's the only way - you will find things like the fact version 3 firmware needs - a magic fix you didn't know about, or some clown changed the - chips on a board and not its name. (Don't laugh! Look at the - SMC etherpower for that.) - -3. Make sure your changes compile correctly in multiple - configurations. In particular check that changes work both as a - module and built into the kernel. - -4. When you are happy with a change make it generally available for - testing and await feedback. - -5. Make a patch available to the relevant maintainer in the list. Use - 'diff -u' to make the patch easy to merge. Be prepared to get your - changes sent back with seemingly silly requests about formatting - and variable names. These aren't as silly as they seem. One - job the maintainers (and especially Linus) do is to keep things - looking the same. Sometimes this means that the clever hack in - your driver to get around a problem actually needs to become a - generalized kernel feature ready for next time. See - Documentation/CodingStyle for guidance here. - - PLEASE try to include any credit lines you want added with the - patch. It avoids people being missed off by mistake and makes - it easier to know who wants adding and who doesn't. - - PLEASE document known bugs. If it doesn't work for everything - or does something very odd once a month document it. - -6. Make sure you have the right to send any changes you make. If you - do changes at work you may find your employer owns the patch - not you. - -7. Happy hacking. - - ----------------------------------- - -Maintainers List (try to look for most precise areas first) - -Note: For the hard of thinking, this list is meant to remain in alphabetical -order. If you could add yourselves to it in alphabetical order that would -so much easier [Ed] - -P: Person -M: Mail patches to -L: Mailing list that is relevant to this area -W: Web-page with status/info -S: Status, one of the following: - - Supported: Someone is actually paid to look after this. - Maintained: Someone actually looks after it. - Odd Fixes: It has a maintainer but they don't have time to do - much other than throw the odd patch in. See below.. - Orphan: No current maintainer [but maybe you could take the - role as you write your new code]. - Obsolete: Old code. Something tagged obsolete generally means - it has been replaced by a better system and you - should be using that. - -3C501 NETWORK DRIVER -P: Alan Cox -M: alan@the.3c501.cabal.tm -L: linux-net@vger.rutgers.edu -S: Maintained - -3C505 NETWORK DRIVER -P: Philip Blundell -M: Philip.Blundell@pobox.com -L: linux-net@vger.rutgers.edu -S: Maintained - -6PACK NETWORK DRIVER FOR AX.25 -P: Andreas Koensgen -M: ajk@iehk.rwth-aachen.de -L: linux-hams@vger.rutgers.edu -S: Maintained - -8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.] -P: Paul Gortmaker -M: p_gortmaker@yahoo.com -L: linux-net@vger.rutgers.edu -S: Maintained - -ACPI -P: Andrew Henroid -M: andy_henroid@yahoo.com -L: acpi@phobos.fs.tum.de -W: http://phobos.fs.tum.de/acpi/index.html -S: Maintained - -AD1816 SOUND DRIVER -P: Thorsten Knabe -M: Thorsten Knabe -M: Thorsten Knabe -W: http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html -W: http://www.tu-darmstadt.de/~tek01/projects/linux.html -S: Maintained - -ADVANSYS SCSI DRIVER -P: Bob Frey -M: linux@advansys.com -W: http://www.advansys.com/linux.html -L: linux-scsi@vger.rutgers.edu -S: Maintained - -AEDSP16 DRIVER -P: Riccardo Facchetti -M: fizban@tin.it -S: Maintained - -AHA152X SCSI DRIVER -P: Juergen E. Fischer -M: Juergen Fischer -L: linux-scsi@vger.rutgers.edu -S: Maintained - -APM DRIVER -P: Stephen Rothwell -M: sfr@linuxcare.com -L: linux-laptop@vger.rutgers.edu -W: http://linuxcare.com.au/apm/ -S: Supported - -APPLETALK NETWORK LAYER -P: Jay Schulist -M: Jay.Schulist@spacs.k12.wi.us -L: linux-atalk@netspace.org -S: Maintained - -ARM MFM AND FLOPPY DRIVERS -P: Dave Gilbert -M: linux@treblig.org -S: Maintained - -ARM PORT -P: Russell King -M: linux@arm.linux.org.uk -L: linux-arm@vger.rutgers.edu -W: http://www.arm.linux.org.uk/~rmk/armlinux.html -S: Maintained - -ARPD SUPPORT -P: Jonathan Layes -M: layes@loran.com -L: linux-net@vger.rutgers.edu -S: Maintained - -AX.25 NETWORK LAYER -P: Matthias Welwarsky -M: dg2fef@afthd.tu-darmstadt.de -L: linux-hams@vger.rutgers.edu -S: Maintained - -BAYCOM/HDLCDRV/SOUNDMODEM DRIVERS FOR AX.25 -P: Thomas Sailer -M: sailer@ife.ee.ethz.ch -L: linux-hams@vger.rutgers.edu -W: http://www.ife.ee.ethz.ch/~sailer/ham/ham.html -S: Maintained - -BERKSHIRE PRODUCTS PC WATCHDOG DRIVER -P: Kenji Hollis -M: kenji@bitgate.com -W: http://ftp.bitgate.com/pcwd/ -S: Maintained - -BFS FILE SYSTEM -P: Tigran A. Aivazian -M: tigran@ocston.org -L: linux-kernel@vger.rutgers.edu -W: http://www.ocston.org/~tigran/patches/bfs -S: Maintained - -BUSLOGIC SCSI DRIVER -P: Leonard N. Zubkoff -M: Leonard N. Zubkoff -L: linux-scsi@vger.rutgers.edu -W: http://www.dandelion.com/Linux/ -S: Maintained - -CIRRUS LOGIC GENERIC FBDEV DRIVER -P: Jeff Garzik -M: jgarzik@pobox.com -L: linux-fbdev@vuser.vu.union.edu -S: Maintained - -COMPAQ SMART2 RAID DRIVER -P: Charles White -M: Charles White -L: compaqandlinux@yps.org -S: Maintained - -COMPUTONE INTELLIPORT MULTIPORT CARD -P: Doug McNash -P: Michael H. Warfield -M: Doug McNash -M: Michael H. Warfield -W: http://www.computone.com/ -W: http://www.wittsend.com/computone.html -L: linux-computone@lazuli.wittsend.com -S: Supported - -CONFIGURE, MENUCONFIG, XCONFIG -P: Michael Elizabeth Chastain -M: mec@shout.net -L: linux-kbuild@torque.net -S: Maintained - -CONFIGURE.HELP -P: Axel Boldt -M: boldt@math.ucsb.edu -S: Maintained - -COSA/SRP SYNC SERIAL DRIVER -P: Jan "Yenya" Kasprzak -M: kas@fi.muni.cz -W: http://www.fi.muni.cz/~kas/cosa/ -S: Maintained - -CREDITS FILE -P: John A. Martin -M: jam@acm.org -S: Maintained - -CYCLADES 2X SYNC CARD DRIVER -P: Arnaldo Carvalho de Melo -M: acme@conectiva.com.br -W: http://www.conectiva.com.br/~acme -L: cycsyn-devel@bazar.conectiva.com.br -S: Maintained - -CYCLADES ASYNC MUX DRIVER -P: Ivan Passos -M: Ivan Passos -W: http://www.cyclades.com/ -S: Supported - -DAMA SLAVE for AX.25 -P: Joerg Reuter -M: jreuter@poboxes.com -W: http://poboxes.com/jreuter/ -W: http://qsl.net/dl1bke/ -L: linux-hams@vger.rutgers.edu -S: Maintained - -DC390/AM53C974 SCSI driver -P: Kurt Garloff -M: kurt@garloff.de -W: http://www.garloff.de/kurt/linux/dc390/ -S: Maintained - -DECnet NETWORK LAYER -P: Steven Whitehouse -M: SteveW@ACM.org -W: http://www.sucs.swan.ac.uk/~rohan/ -W: http://www-sigproc.eng.cam.ac.uk/~sjw44/ -L: netdev@oss.sgi.com -S: Maintained - -DEVICE NUMBER REGISTRY -P: H. Peter Anvin -M: hpa@zytor.com -L: linux-kernel@vger.rutgers.edu -S: Maintained - -DIGI INTL. EPCA DRIVER -P: Chad Schwartz -M: support@dgii.com -M: chads@dgii.com -L: digilnux@dgii.com -S: Maintained - -DIGI RIGHTSWITCH NETWORK DRIVER -P: Rick Richardson -M: rick@dgii.com -L: linux-net@vger.rutgers.edu -W: http://www.dgii.com/linux/ -S: Maintained - -DISKQUOTA: -P: Marco van Wieringen -M: mvw@planets.elm.net -L: linux-kernel@vger.rutgers.edu -S: Maintained - -DOUBLETALK DRIVER -P: James R. Van Zandt -M: jrv@vanzandt.mv.com -L: blinux-list@redhat.com -S: Maintained - -EATA-DMA SCSI DRIVER -P: Michael Neuffer -M: mike@i-Connect.Net -L: linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu -S: Maintained - -EATA ISA/EISA/PCI SCSI DRIVER -P: Dario Ballabio -M: dario@milano.europe.dg.com -L: linux-scsi@vger.rutgers.edu -S: Maintained - -EATA-PIO SCSI DRIVER -P: Michael Neuffer -M: mike@i-Connect.Net -L: linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu -S: Maintained - -ETHEREXPRESS-16 NETWORK DRIVER -P: Philip Blundell -M: Philip.Blundell@pobox.com -L: linux-net@vger.rutgers.edu -S: Maintained - -ETHERTEAM 16I DRIVER -P: Mika Kuoppala -M: miku@iki.fi -S: Maintained - -EXT2 FILE SYSTEM -P: Remy Card -M: Remy.Card@linux.org -L: linux-kernel@vger.rutgers.edu -S: Maintained - -FILE LOCKING (flock() and fcntl()/lockf()) -P: Andy Walker -M: andy@lysaker.kvaerner.no -L: linux-kernel@vger.rutgers.edu -S: Maintained - -FPU EMULATOR -P: Bill Metzenthen -M: billm@suburbia.net -W: http://suburbia.net/~billm/floating-point/emulator/ -S: Maintained - -FRAME RELAY DLCI/FRAD (Sangoma drivers too) -P: Mike McLagan -M: mike.mclagan@linux.org -L: linux-net@vger.rutgers.edu -S: Maintained - -FTAPE/QIC-117 -P: Claus-Justus Heine -M: claus@momo.math.rwth-aachen.de -L: linux-tape@vger.rutgers.edu -W: http://www-math.math.rwth-aachen.de/~LBFM/claus/ftape/ -S: Maintained - -FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit) -P: Rik Faith -M: faith@cs.unc.edu -L: linux-scsi@vger.rutgers.edu -S: Odd fixes (e.g., new signatures) - -GDT SCSI DISK ARRAY CONTROLLER DRIVER -P: Achim Leubner -M: achim@vortex.de -L: linux-scsi@vger.rutgers.edu -W: http://www.icp-vortex.com/ -S: Supported - -HAYES ESP SERIAL DRIVER -P: Andrew J. Robinson -M: arobinso@nyx.net -L: linux-kernel@vger.rutgers.edu -W: http://www.nyx.net/~arobinso -S: Maintained - -HFS FILESYSTEM -P: Adrian Sun -M: asun@cobaltnet.com -L: linux-kernel@vger.rutgers.edu -S: Maintained - -HIGH-SPEED SCC DRIVER FOR AX.25 -P: Klaus Kudielka -M: oe1kib@oe1kib.ampr.org -L: linux-hams@vger.rutgers.edu -S: Maintained - -HIPPI -P: Jes Sorensen -M: Jes.Sorensen@cern.ch -L: linux-hippi@sunsite.auc.dk -S: Maintained - -HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series -P: Jaroslav Kysela -M: perex@suse.cz -S: Maintained - -HPFS FILESYSTEM -P: Mikulas Patocka -M: mikulas@artax.karlin.mff.cuni.cz -W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi -S: Maintained - -i386 BOOT CODE -P: Riley H. Williams -M: rhw@memalpha.cx -L: Linux-Kernel@vger.rutgers.edu -S: Maintained - -IBM MCA SCSI SUBSYSTEM DRIVER -P: Michael Lang -M: langa2@kph.uni-mainz.de -W: http://www.uni-mainz.de/~langm000/linux.html -S: Maintained - -IBM ServeRAID RAID DRIVER -P: Keith Mitchell -M: ipslinux@us.ibm.com -W: http://www.developer.ibm.com/welcome/netfinity/serveraid_beta.html -S: Supported - -IDE DRIVER [GENERAL] -P: Andre Hedrick -M: andre@suse.com -L: linux-kernel@vger.rutgers.edu -W: http://linux.kernel.org/pub/linux/kernel/people/hedrick/ -S: Supported - -IDE/ATAPI CDROM DRIVER -P: Jens Axboe -M: axboe@image.dk -L: linux-kernel@vger.rutgers.edu -W: http://www.kernel.dk -S: Maintained - -IDE/ATAPI TAPE/FLOPPY DRIVERS -P: Gadi Oxman -M: Gadi Oxman -L: linux-kernel@vger.rutgers.edu -S: Maintained - -INTEL APIC/IOAPIC, LOWLEVEL X86 SMP SUPPORT -P: Ingo Molnar -M: mingo@redhat.com -S: Maintained - -IP MASQUERADING: -P: Juanjo Ciarlante -M: jjciarla@raiz.uncu.edu.ar -S: Maintained - -IPX/SPX NETWORK LAYER -P: Jay Schulist -M: Jay Schulist -L: linux-net@vger.rutgers.edu -S: Maintained - -IRDA SUBSYSTEM -P: Dag Brattli -M: Dag Brattli -L: linux-irda@pasta.cs.uit.no -W: http://www.cs.uit.no/linux-irda/ -S: Maintained - -ISAPNP -P: Jaroslav Kysela -M: perex@suse.cz -S: Maintained - -ISDN SUBSYSTEM (general) -P: Fritz Elfert -M: fritz@isdn4linux.de -L: isdn4linux@listserv.isdn4linux.de -W: http://www.isdn4linux.de -S: Maintained - -ISDN SUBSYSTEM (card drivers) -P: Karsten Keil -M: kkeil@suse.de -L: isdn4linux@listserv.isdn4linux.de -W: http://www.isdn4linux.de -S: Maintained - -JOYSTICK DRIVER -P: Vojtech Pavlik -M: vojtech@suse.cz -L: linux-joystick@atrey.karlin.mff.cuni.cz -W: http://www.suse.cz/development/joystick/ -S: Maintained - -KERNEL AUTOMOUNTER (AUTOFS) -P: H. Peter Anvin -M: hpa@zytor.com -L: autofs@linux.kernel.org -S: Maintained - -KERNEL NFSD -P: G. Allen Morris III -M: gam3@acm.org -L: nfs-devel@linux.kernel.org (Linux NFS) -W: http://csua.berkeley.edu/~gam3/knfsd -S: Maintained - -LAPB module -P: Henner Eisen -M: eis@baty.hanse.de -L: linux-x25@vger.rutgers.edu -S: Maintained - -LINUX FOR POWERPC -P: Cort Dougan -M: cort@ppc.kernel.org -W: http://www.ppc.kernel.org/ -S: Maintained - -LINUX FOR POWER MACINTOSH -P: Paul Mackerras -M: paulus@linuxcare.com -W: http://www.linuxppc.org/ -L: linuxppc-dev@lists.linuxppc.org -S: Maintained - -M68K -P: Jes Sorensen -M: Jes.Sorensen@cern.ch -W: http://www.clark.net/pub/lawrencc/linux/index.html -L: linux-m68k@lists.linux-m68k.org -S: Maintained - -M68K ON APPLE MACINTOSH -P: Alan Cox -M: Alan.Cox@linux.org -W: http://www.mac.linux-m68k.org/home.html -L: linux-mac68k@wave.lm.com -S: As time permits [Michael confess, you are the mac68k maintainer 8)] - -M68K ON HP9000/300 -P: Philip Blundell -M: philb@gnu.org -W: http://www.tazenda.demon.co.uk/phil/linux-hp -S: Maintained - -MIPS -P: Ralf Baechle -M: ralf@gnu.ai.mit.edu -W: http://lena.fnet.fr/ -L: linux-mips@fnet.fr -S: Maintained - -MISCELLANEOUS MCA-SUPPORT -P: David Weinehall -M: tao@acc.umu.se (personal) -W: http://www.acc.umu.se/~tao/ -W: http://www.acc.umu.se/~mcalinux/ -L: linux-kernel@vger.rutgers.edu -S: Maintained - -MODULE SUPPORT [GENERAL], KERNELD -P: Richard Henderson -M: richard@gnu.ai.mit.edu -L: linux-kernel@vger.rutgers.edu -S: Maintained - -MOUSE AND MISC DEVICES [GENERAL] -P: Alessandro Rubini -M: rubini@ipvvis.unipv.it -L: linux-kernel@vger.rutgers.edu -S: Maintained - -MTRR AND SIMILAR SUPPORT [i386] -P: Richard Gooch -M: rgooch@atnf.csiro.au -L: linux-kernel@vger.rutgers.edu -W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html -S: Maintained - -MULTISOUND SOUND DRIVER -P: Andrew Veliath -M: andrewtv@usa.net -S: Maintained - -NCP FILESYSTEM -P: Petr Vandrovec -M: vandrove@vc.cvut.cz -P: Volker Lendecke -M: vl@kki.org -L: linware@sh.cvut.cz -S: Maintained - -NETFILTER -P: Rusty Russell -M: Rusty.Russell@rustcorp.com.au -W: http://www.samba.org/netfilter/ -W: http://netfilter.kernelnotes.org -W: http://antarctica.penguincomputing.com/~netfilter/ -L: netfilter@lists.samba.org -S: Supported - -NETROM NETWORK LAYER -P: Tomi Manninen -M: Tomi.Manninen@hut.fi -L: linux-hams@vger.rutgers.edu -S: Maintained - -NETWORK BLOCK DEVICE -P: Pavel Machek -M: pavel@atrey.karlin.mff.cuni.cz -S: Maintained - -NETWORKING [GENERAL] -P: Networking Teak -M: netdev@oss.sgi.com -L: linux-net@vger.rutgers.edu -W: http://www.uk.linux.org/NetNews.html (2.0 only) -S: Maintained - -NETWORKING [IPv4/IPv6] -P: David S. Miller -M: davem@redhat.com -P: Andi Kleen -M: ak@muc.de -P: Alexey Kuznetsov -M: kuznet@ms2.inr.ac.ru -L: netdev@oss.sgi.com -S: Maintained - -NFS CLIENT -P: Trond Myklebust -M: trond.myklebust@fys.uio.no -L: linux-kernel@vger.rutgers.edu -S: Maintained - -NI5010 NETWORK DRIVER -P: Jan-Pascal van Best and Andreas Mohr -M: jvbest@qv3pluto.leidenuniv.nl (Best) -M: 100.30936@germany.net (Mohr) -L: linux-net@vger.rutgers.edu -S: Maintained - -NON-IDE/NON-SCSI CDROM DRIVERS [GENERAL] (come on, crew - mark your responsibility) -P: Eberhard Moenkeberg -M: emoenke@gwdg.de -L: linux-kernel@vger.rutgers.edu -S: Maintained - -OLYMPIC NETWORK DRIVER -P: Peter De Shrijver -M: p2@ace.ulyssis.sutdent.kuleuven.ac.be -P: Mike Phillips -M: phillim@amtrak.com -L: linux-net@vger.rutgers.edu -L: linux-tr@emissary.aus-etc.com -W: http://www.linuxtr.net -S: Maintained - -OPL3-SA2, SA3, and SAx DRIVER -P: Scott Murray -M: scottm@interlog.com -L: linux-sound@vger.rutgers.edu -S: Maintained - -PARALLEL PORT SUPPORT -P: Phil Blundell -M: Philip.Blundell@pobox.com -P: Tim Waugh -M: tim@cyberelk.demon.co.uk -P: David Campbell -M: campbell@torque.net -P: Andrea Arcangeli -M: andrea@e-mind.com -L: linux-parport@torque.net -W: http://www.cyberelk.demon.co.uk/parport.html -S: Maintained - -PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES -P: Grant Guenther -M: grant@torque.net -L: linux-parport@torque.net -W: http://www.torque.net/linux-pp.html -S: Maintained - -PCI ID DATABASE -P: Jens Maurer -M: jmaurer@cck.uni-kl.de -S: Maintained - -PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES) -P: Thomas Sailer -M: sailer@ife.ee.ethz.ch -L: linux-sound@vger.rutgers.edu -W: http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html -S: Maintained - -PCI SUBSYSTEM -P: Martin Mares -M: mj@suse.cz -L: linux-kernel@vger.rutgers.edu -S: Maintained - -PCMCIA SUBSYSTEM -P: David Hinds -M: dhinds@zen.stanford.edu -L: linux-kernel@vger.rutgers.edu -W: http://pcmcia.sourceforge.org -S: Maintained - -PCNET32 NETWORK DRIVER -P: Thomas Bogendörfer -M: tsbogend@alpha.franken.de -L: linux-net@vger.rutgers.edu -S: Maintained - -PNP SUPPORT -P: Tom Lees -M: tom@lpsg.demon.co.uk -L: pnp-users@ferret.lmh.ox.ac.uk -L: pnp-devel@ferret.lmh.ox.ac.uk -W: http://www-jcr.lmh.ox.ac.uk/~pnp/ -S: Maintained - -PPP PROTOCOL DRIVERS AND COMPRESSORS -P: Al Longyear -M: longyear@pobox.com -L: linux-ppp@vger.rutgers.edu -S: Maintained - -PROMISE DC4030 CACHING DISK CONTROLLER DRIVER -P: Peter Denison -M: promise@pnd-pc.demon.co.uk -W: http://www.pnd-pc.demon.co.uk/promise/ -S: Maintained - -RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER -P: Corey Thomas -M: corey@world.std.com -L: linux-kernel@vger.rutgers.edu -S: Maintained - -REAL TIME CLOCK DRIVER -P: Paul Gortmaker -M: p_gortmaker@yahoo.com -L: linux-kernel@vger.rutgers.edu -S: Maintained - -ROSE NETWORK LAYER -P: Frederic Rible -M: frible@teaser.fr -L: linux-hams@vger.rutgers.edu -S: Maintained - -RISCOM8 DRIVER -P: Dmitry Gorodchanin -M: pgmdsg@ibi.com -L: linux-kernel@vger.rutgers.edu -S: Maintained - -SBPCD CDROM DRIVER -P: Eberhard Moenkeberg -M: emoenke@gwdg.de -L: linux-kernel@vger.rutgers.edu -S: Maintained - -SCSI CDROM DRIVER -P: Jens Axboe -M: axboe@image.dk -L: linux-scsi@vger.rutgers.edu -W: http://www.kernel.dk -S: Maintained - -SCSI SG DRIVER -P: Doug Gilbert -M: dgilbert@interlog.com -L: linux-scsi@vger.rutgers.edu -W: http://www.torque.net/sg -S: Maintained - -SCSI SUBSYSTEM -L: linux-scsi@vger.rutgers.edu -S: Unmaintained - -SCSI TAPE DRIVER -P: Kai Mdkisara -M: Kai.Makisara@metla.fi -L: linux-scsi@vger.rutgers.edu -S: Maintained - -SGI VISUAL WORKSTATION 320 AND 540 -P: Bent Hagemark -M: bh@sgi.com -P: Ingo Molnar -M: mingo@redhat.com -S: Maintained - -SIS 900/7016 FAST ETHERNET DRIVER -P: Ollie Lho -M: ollie@sis.com.tw -L: linux-net@vger.rutgers.edu -S: Supported - -SMB FILESYSTEM -P: Andrew Tridgell -M: tridge@samba.org -W: http://samba.org/ -L: samba@samba.org -S: Maintained - -SMP: (except SPARC) -P: Linus Torvalds -M: torvalds@transmeta.com -L: linux-smp@vger.rutgers.edu -S: Maintained - -SONIC NETWORK DRIVER -P: Thomas Bogendoerfer -M: tsbogend@alpha.franken.de -L: linux-net@vger.rutgers.edu -S: Maintained - -SOUND -P: Alan Cox -M: alan@redhat.com -S: Supported - -SPARC: -P: David S. Miller -M: davem@redhat.com -P: Eddie C. Dost -M: ecd@skynet.be -P: Jakub Jelinek -M: jj@sunsite.ms.mff.cuni.cz -P: Anton Blanchard -M: anton@progsoc.uts.edu.au -L: sparclinux@vger.rutgers.edu -L: ultralinux@vger.rutgers.edu -W: http://ultra.linux.cz -W: http://www.geog.ubc.ca/s_linux.html -S: Maintained - -SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER -P: Roger Wolff -M: R.E.Wolff@BitWizard.nl -M: io8-linux@specialix.co.uk -L: linux-kernel@vger.rutgers.edu ? -S: Supported - -SPX NETWORK LAYER -P: Jay Schulist -M: Jay.Schulist@spacs.k12.wi.us -L: linux-net@vger.rutgers.edu -S: Supported - -STALLION TECHNOLOGIES MULTIPORT SERIAL BOARDS -M: support@stallion.oz.au -W: http://www.stallion.com -S: Supported - -STARMODE RADIO IP (STRIP) PROTOCOL DRIVER -W: http://mosquitonet.Stanford.EDU/strip.html -S: Unsupported ? - -SUPERH -P: Niibe Yutaka -M: gniibe@chroot.org -P: Kazumoto Kojima -M: kkojima@rr.iij4u.or.jp -L: linux-sh@m17n.org -W: http://www.m17n.org/linux-sh/ -W: http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html -S: Maintained - -SVGA HANDLING -P: Martin Mares -M: mj@atrey.karlin.mff.cuni.cz -L: linux-video@atrey.karlin.mff.cuni.cz -S: Maintained - -SYSV FILESYSTEM -P: Krzysztof G. Baranowski -M: kgb@manjak.knm.org.pl -S: Maintained - -TLAN NETWORK DRIVER -P: Torben Mathiasen -M: torben.mathiasen@compaq.com -L: tlan@vuser.vu.union.edu -S: Maintained - -TOKEN-RING NETWORK DRIVER -P: Paul Norton -M: pnorton@ieee.org -L: linux-net@vger.rutgers.edu -L: linux-tr@linuxtr.net -S: Maintained - -TMS380 TOKEN-RING NETWORK DRIVER -P: Adam Fritzler -M: mid@auk.cx -L: linux-tr@linuxtr.net -W: http://www.auk.cx/tms380tr/ -S: Maintained - -U14-34F SCSI DRIVER -P: Dario Ballabio -M: dario@milano.europe.dg.com -L: linux-scsi@vger.rutgers.edu -S: Maintained - -UDF FILESYSTEM -P: Ben Fennema -M: bfennema@falcon.csc.calpoly.edu -P: Dave Boynton -M: dave@trylinux.com -L: linux_udf@hootie.lvld.hp.com -W: http://www.trylinux.com/projects/udf/index.html -S: Maintained - -UMSDOS FILESYSTEM -P: Matija Nalis -M: Matija Nalis -L: linux-kernel@vger.rutgers.edu -W: http://www.voyager.hr/~mnalis/umsdos/ -S: Maintained - -UNIFORM CDROM DRIVER -P: Jens Axboe -M: axboe@image.dk -L: linux-kernel@vger.rutgers.edu -W: http://www.kernel.dk -S: Maintained - -USB SUBSYSTEM -P: Randy Dunlap -M: randy.dunlap@intel.com -L: linux-usb@suse.com -W: http://www.linux-usb.org -S: Supported - -USB HUB AND UHCI DRIVERS -P: Johannes Erdfelt -M: jerdfelt@sventech.com -L: linux-usb@suse.com -S: Maintained - -USB OHCI DRIVER -P: Gregory P. Smith -M: greg@electricrain.com -M: greg@suitenine.com -L: linux-usb@suse.com -S: Maintained (not yet usable) -W: http://suitenine.com/usb/ - -VFAT FILESYSTEM: -P: Gordon Chaffee -M: chaffee@cs.berkeley.edu -L: linux-kernel@vger.rutgers.edu -W: http://bmrc.berkeley.edu/people/chaffee -S: Maintained - -VIA 82Cxxx AUDIO DRIVER -P: Jeff Garzik -M: jgarzik@pobox.com -S: Maintained - -VIDEO FOR LINUX -P: Alan Cox -M: Alan.Cox@linux.org -W: http://roadrunner.swansea.linux.org.uk/v4l.shtml -S: Maintained - -WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC) -P: Jaspreet Singh -M: jaspreet@sangoma.com -M: dm@sangoma.com -W: http://www.sangoma.com -S: Supported - -WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS -P: Jean Tourrilhes -M: jt@hpl.hp.com -W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/ -S: Maintained - -WD7000 SCSI DRIVER -P: Miroslav Zagorac -M: zaga@fly.cc.fer.hr -L: linux-scsi@vger.rutgers.edu -S: Maintained - -X.25 NETWORK LAYER -P: Henner Eisen -M: eis@baty.hanse.de -L: linux-x25@vger.rutgers.edu -S: Maintained - -Z85230 SYNCHRONOUS DRIVER -P: Alan Cox -M: alan@redhat.com -W: http://roadrunner.swansea.linux.org.uk/synchronous.shtml -S: Maintained - -Z8530 DRIVER FOR AX.25 -P: Joerg Reuter -M: jreuter@poboxes.com -W: http://poboxes.com/jreuter/ -W: http://qsl.net/dl1bke/ -L: linux-hams@vger.rutgers.edu -S: Maintained - -ZR36120 VIDEO FOR LINUX DRIVER -P: Pauline Middelink -M: middelin@polyware.nl -W: http://www.polyware.nl/~middelin/En/hobbies.html -W: http://www.polyware.nl/~middelin/hobbies.html -S: Maintained - -THE REST -P: Linus Torvalds -S: Buried alive in reporters diff --git a/Makefile b/Makefile index 5dabdf297a41..f2089a69ccb2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 33 +SUBLEVEL = 34 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) @@ -22,7 +22,7 @@ CROSS_COMPILE = AS =$(CROSS_COMPILE)as LD =$(CROSS_COMPILE)ld -CC =$(CROSS_COMPILE)gcc -D__KERNEL__ -I$(HPATH) +CC =$(CROSS_COMPILE)gcc CPP =$(CC) -E AR =$(CROSS_COMPILE)ar NM =$(CROSS_COMPILE)nm @@ -86,16 +86,18 @@ SVGA_MODE= -DSVGA_MODE=NORMAL_VGA # standard CFLAGS # -CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer - -# use '-fno-strict-aliasing', but only if the compiler can take it -CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi) +CPPFLAGS := -D__KERNEL__ -I$(HPATH) ifdef CONFIG_SMP -CFLAGS += -D__SMP__ -AFLAGS += -D__SMP__ +CPPFLAGS += -D__SMP__ endif +CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer +AFLAGS := $(CPPFLAGS) + +# use '-fno-strict-aliasing', but only if the compiler can take it +CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi) + # # if you want the RAM disk device, define this to be the # size in blocks. diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile index ee3460463efd..ee2ac0ac0d22 100644 --- a/arch/alpha/boot/Makefile +++ b/arch/alpha/boot/Makefile @@ -11,9 +11,9 @@ LINKFLAGS = -static -T bootloader.lds #-N -relax .S.s: - $(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< OBJECTS = head.o main.o BPOBJECTS = head.o bootp.o diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index ce47e1979374..927d4aa81906 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -8,7 +8,7 @@ #define SIGCHLD 20 -#define NR_SYSCALLS 373 +#define NR_SYSCALLS 374 /* * These offsets must match with alpha_mv in . @@ -1149,3 +1149,4 @@ sys_call_table: .quad sys_sendfile /* 370 */ .quad sys_setresgid .quad sys_getresgid + .quad sys_ni_syscall /* sys_dipc */ diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index a224f84bb040..52571557b508 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile @@ -14,16 +14,16 @@ lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) __divqu.o: divide.S - $(CC) -DDIV -c -o __divqu.o divide.S + $(CC) $(AFLAGS) -DDIV -c -o __divqu.o divide.S __remqu.o: divide.S - $(CC) -DREM -c -o __remqu.o divide.S + $(CC) $(AFLAGS) -DREM -c -o __remqu.o divide.S __divlu.o: divide.S - $(CC) -DDIV -DINTSIZE -c -o __divlu.o divide.S + $(CC) $(AFLAGS) -DDIV -DINTSIZE -c -o __divlu.o divide.S __remlu.o: divide.S - $(CC) -DREM -DINTSIZE -c -o __remlu.o divide.S + $(CC) $(AFLAGS) -DREM -DINTSIZE -c -o __remlu.o divide.S dep: diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index a9d71cb7b81d..8a100eb77997 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -6,7 +6,7 @@ HEAD = head.o OBJS = misc.o SYSTEM = $(TOPDIR)/vmlinux -CFLAGS = -O2 -DSTDC_HEADERS $(CFLAGS_PROC) +CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_PROC) FONTC = $(TOPDIR)/drivers/video/font_acorn_8x8.c ZLDFLAGS = -p -X -T vmlinux.lds @@ -77,7 +77,7 @@ vmlinux: $(HEAD) $(OBJS) piggy.o vmlinux.lds $(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o $(GCCLIB) -o vmlinux $(HEAD): $(HEAD:.o=.S) - $(CC) -traditional -c $(HEAD:.o=.S) + $(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S) piggy.o: $(SYSTEM) $(OBJCOPY) $(SYSTEM) piggy @@ -86,7 +86,7 @@ piggy.o: $(SYSTEM) rm -f piggy piggy.gz font.o: $(FONTC) - $(CC) -Dstatic= -c -o $@ $(FONTC) + $(CC) $(CFLAGS) -Dstatic= -c -o $@ $(FONTC) vmlinux.lds: vmlinux.lds.in @sed "$(SEDFLAGS)" < vmlinux.lds.in > $@ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 31ca81ddcdda..3b79f080b7ae 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -75,7 +75,7 @@ else endif $(HEAD_OBJ): $(HEAD_OBJ:.o=.S) - $(CC) -D__ASSEMBLY__ -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@ + $(CC) -D__ASSEMBLY__ $(AFLAGS) -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@ include $(TOPDIR)/Rules.make diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index 56a941a624da..e75eb2fdff4d 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile @@ -49,7 +49,7 @@ bootsect.o: bootsect.s $(AS) -o $@ $< bootsect.s: bootsect.S Makefile $(BOOT_INCL) - $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ + $(CPP) $(CPPFLAGS) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ bbootsect: bbootsect.o $(LD) -Ttext 0x0 -s -oformat binary $< -o $@ @@ -58,7 +58,7 @@ bbootsect.o: bbootsect.s $(AS) -o $@ $< bbootsect.s: bootsect.S Makefile $(BOOT_INCL) - $(CPP) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ + $(CPP) $(CPPFLAGS) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ setup: setup.o $(LD) -Ttext 0x0 -s -oformat binary -e begtext -o $@ $< @@ -67,7 +67,7 @@ setup.o: setup.s $(AS) -o $@ $< setup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h - $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ + $(CPP) $(CPPFLAGS) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ bsetup: bsetup.o $(LD) -Ttext 0x0 -s -oformat binary -e begtext -o $@ $< @@ -76,7 +76,7 @@ bsetup.o: bsetup.s $(AS) -o $@ $< bsetup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h - $(CPP) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ + $(CPP) $(CPPFLAGS) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ dep: diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile index 83a245add919..6e4b4998df57 100644 --- a/arch/i386/boot/compressed/Makefile +++ b/arch/i386/boot/compressed/Makefile @@ -9,7 +9,7 @@ SYSTEM = $(TOPDIR)/vmlinux OBJECTS = $(HEAD) misc.o -CFLAGS = -O2 -DSTDC_HEADERS +CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS ZLDFLAGS = -e startup_32 # diff --git a/arch/i386/config.in b/arch/i386/config.in index 4a09997b2c74..c08924f73f5c 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -129,6 +129,8 @@ if [ "$CONFIG_APM" != "n" ]; then bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT bool ' Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS + bool ' Entry point offset fix (some Acer laptops)' CONFIG_APM_BAD_ENTRY_OFFSET + bool ' Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF fi endmenu diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 564e6b42b2ca..c6c51ccffa04 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -34,6 +34,7 @@ * Jan 1999, Version 1.8 * Jan 1999, Version 1.9 * Oct 1999, Version 1.10 + * Nov 1999, Version 1.11 * * History: * 0.6b: first version in official kernel, Linux 1.3.46 @@ -101,6 +102,14 @@ * configurable (default on). * Make debug only a boot time parameter (remove APM_DEBUG). * Try to blank all devices on any error. + * 1.11: Remove APM dependencies in drivers/char/console.c + * Check nr_running to detect if we are idle (from + * Borislav Deianov ) + * Fix for bioses that don't zero the top part of the + * entrypoint offset (Mario Sitta ) + * (reported by Panos Katsaloulis ). + * Real mode power off patch (Walter Hofmann + * ). * * APM 1.1 Reference: * @@ -135,6 +144,7 @@ #include #include #include +#include #include #include @@ -149,8 +159,14 @@ EXPORT_SYMBOL(apm_register_callback); EXPORT_SYMBOL(apm_unregister_callback); extern unsigned long get_cmos_time(void); +extern void machine_real_restart(unsigned char *, int); +#ifdef CONFIG_MAGIC_SYSRQ extern void (*sysrq_power_off)(void); +#endif +#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) +extern int (*console_blank_hook)(int); +#endif /* * The apm_bios device is one of the misc char devices. @@ -269,7 +285,7 @@ static int power_off_enabled = 1; static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static struct apm_bios_struct * user_list = NULL; -static char driver_version[] = "1.10"; /* no spaces */ +static char driver_version[] = "1.11"; /* no spaces */ static char * apm_event_name[] = { "system standby", @@ -380,7 +396,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" - "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "; cld\n\t" + "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" "setc %%al\n\t" "popl %%ebp\n\t" "popl %%edi\n\t" @@ -413,7 +429,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax) __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" - "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry)"; cld\n\t" + "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry)"\n\t" "setc %%bl\n\t" "popl %%ebp\n\t" "popl %%edi\n\t" @@ -551,24 +567,24 @@ static void apm_power_off(void) * they are doing because they booted with the smp-power-off * kernel option. */ - if (apm_enabled || (smp_hack == 2)) + if (apm_enabled || (smp_hack == 2)) { +#ifdef CONFIG_APM_REAL_MODE_POWER_OFF + unsigned char po_bios_call[] = { + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */ + 0x8e, 0xd0, /* movw ax,ss */ + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */ + 0xb8, 0x07, 0x53, /* movw $0x5307,ax */ + 0xbb, 0x01, 0x00, /* movw $0x0001,bx */ + 0xb9, 0x03, 0x00, /* movw $0x0003,cx */ + 0xcd, 0x15 /* int $0x15 */ + }; + + machine_real_restart(po_bios_call, sizeof(po_bios_call)); +#else (void) apm_set_power_state(APM_STATE_OFF); -} - -#ifdef CONFIG_APM_DISPLAY_BLANK -/* Called by apm_display_blank and apm_display_unblank when apm_enabled. */ -static int apm_set_display_power_state(u_short state) -{ - int error; - - /* Blank the first display device */ - error = set_power_state(0x0100, state); - if (error != APM_SUCCESS) - /* try to blank them all instead */ - error = set_power_state(0x01ff, state); - return error; -} #endif + } +} #ifdef CONFIG_APM_DO_ENABLE static int __init apm_enable_power_management(void) @@ -651,33 +667,25 @@ static void apm_error(char *str, int err) str, err); } +#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) /* Called from console driver -- must make sure apm_enabled. */ -int apm_display_blank(void) +static int apm_console_blank(int blank) { -#ifdef CONFIG_APM_DISPLAY_BLANK - if (apm_enabled) { - int error = apm_set_display_power_state(APM_STATE_STANDBY); - if ((error == APM_SUCCESS) || (error == APM_NO_ERROR)) - return 1; - apm_error("set display standby", error); - } -#endif - return 0; -} + int error; + u_short state; -/* Called from console driver -- must make sure apm_enabled. */ -int apm_display_unblank(void) -{ -#ifdef CONFIG_APM_DISPLAY_BLANK - if (apm_enabled) { - int error = apm_set_display_power_state(APM_STATE_READY); - if ((error == APM_SUCCESS) || (error == APM_NO_ERROR)) - return 1; - apm_error("set display ready", error); - } -#endif + state = blank ? APM_STATE_STANDBY : APM_STATE_READY; + /* Blank the first display device */ + error = set_power_state(0x100, state); + if (error != APM_SUCCESS) + /* try to blank them all instead */ + error = set_power_state(0x1ff, state); + if ((error == APM_SUCCESS) || (error == APM_NO_ERROR)) + return 1; + apm_error("set display", error); return 0; } +#endif int apm_register_callback(int (*callback)(apm_event_t)) { @@ -884,12 +892,15 @@ static void check_events(void) case APM_USER_STANDBY: #ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND if (waiting_for_resume) - return; - waiting_for_resume = 1; + break; #endif - if (send_event(event, APM_STANDBY_RESUME, NULL) - && (standbys_pending <= 0)) - standby(); + if (send_event(event, APM_STANDBY_RESUME, NULL)) { +#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + waiting_for_resume = 1; +#endif + if (standbys_pending <= 0) + standby(); + } break; case APM_USER_SUSPEND: @@ -905,12 +916,15 @@ static void check_events(void) #endif #ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND if (waiting_for_resume) - return; - waiting_for_resume = 1; + break; +#endif + if (send_event(event, APM_NORMAL_RESUME, NULL)) { +#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + waiting_for_resume = 1; #endif - if (send_event(event, APM_NORMAL_RESUME, NULL) - && (suspends_pending <= 0)) - suspend(); + if (suspends_pending <= 0) + suspend(); + } break; case APM_NORMAL_RESUME: @@ -947,21 +961,18 @@ static void check_events(void) static void apm_event_handler(void) { static int pending_count = 0; + int err; - if (((standbys_pending > 0) || (suspends_pending > 0)) - && (apm_bios_info.version > 0x100)) { - if (pending_count-- <= 0) { - int err; - + if ((standbys_pending > 0) || (suspends_pending > 0)) { + if ((apm_bios_info.version > 0x100) && (pending_count-- <= 0)) { pending_count = 4; err = apm_set_power_state(APM_STATE_BUSY); if (err) apm_error("busy", err); } - } else { + } else pending_count = 0; - check_events(); - } + check_events(); } /* @@ -970,12 +981,8 @@ static void apm_event_handler(void) * Check whether we're the only running process to * decide if we should just power down. * - * Do this by checking the runqueue: if we're the - * only one, then the current process run_list will - * have both prev and next pointing to the same - * entry (the true idle process) */ -#define system_idle() (current->run_list.next == current->run_list.prev) +#define system_idle() (nr_running == 1) static void apm_mainloop(void) { @@ -1367,10 +1374,13 @@ static int apm(void *unused) /* Install our power off handler.. */ if (power_off_enabled) acpi_power_off = apm_power_off; - #ifdef CONFIG_MAGIC_SYSRQ sysrq_power_off = apm_power_off; #endif +#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) + console_blank_hook = apm_console_blank; +#endif + apm_mainloop(); return 0; } @@ -1492,6 +1502,9 @@ static int __init apm_init(void) _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4)); apm_bios_entry.offset = apm_bios_info.offset; +#ifdef CONFIG_APM_BAD_ENTRY_OFFSET + apm_bios_entry.offset &= 0xffff; +#endif apm_bios_entry.segment = APM_CS; set_base(gdt[APM_CS >> 3], __va((unsigned long)apm_bios_info.cseg << 4)); diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 1cc0d8d2f8d2..ecfe0697d45c 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -92,8 +92,8 @@ ENOSYS = 38 pushl %ecx; \ pushl %ebx; \ movl $(__KERNEL_DS),%edx; \ - movl %dx,%ds; \ - movl %dx,%es; + movl %edx,%ds; \ + movl %edx,%es; #define RESTORE_ALL \ popl %ebx; \ @@ -288,15 +288,15 @@ error_code: pushl %ecx pushl %ebx cld - movl %es,%cx + movl %es,%ecx xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. ) movl %esp,%edx xchgl %ecx, ES(%esp) # get the address and save es. pushl %eax # push the error code pushl %edx movl $(__KERNEL_DS),%edx - movl %dx,%ds - movl %dx,%es + movl %edx,%ds + movl %edx,%es GET_CURRENT(%ebx) call *%ecx addl $8,%esp diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index b3f1335d0913..2a0699e5887e 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -47,10 +47,10 @@ startup_32: */ cld movl $(__KERNEL_DS),%eax - movl %ax,%ds - movl %ax,%es - movl %ax,%fs - movl %ax,%gs + movl %eax,%ds + movl %eax,%es + movl %eax,%fs + movl %eax,%gs #ifdef __SMP__ orw %bx,%bx jz 1f @@ -231,13 +231,13 @@ is386: pushl %ecx # restore original EFLAGS lidt idt_descr ljmp $(__KERNEL_CS),$1f 1: movl $(__KERNEL_DS),%eax # reload all the segment registers - movl %ax,%ds # after changing gdt. - movl %ax,%es - movl %ax,%fs - movl %ax,%gs + movl %eax,%ds # after changing gdt. + movl %eax,%es + movl %eax,%fs + movl %eax,%gs #ifdef __SMP__ movl $(__KERNEL_DS), %eax - mov %ax,%ss # Reload the stack pointer (segment only) + movl %eax,%ss # Reload the stack pointer (segment only) #else lss stack_start,%esp # Load processor stack #endif @@ -323,8 +323,8 @@ ignore_int: pushl %es pushl %ds movl $(__KERNEL_DS),%eax - movl %ax,%ds - movl %ax,%es + movl %eax,%ds + movl %eax,%es pushl $int_msg call SYMBOL_NAME(printk) popl %eax diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 43cb7ef5f7b5..703482425cdf 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -187,7 +187,10 @@ static unsigned char real_mode_switch [] = 0x74, 0x02, /* jz f */ 0x0f, 0x08, /* invd */ 0x24, 0x10, /* f: andb $0x10,al */ - 0x66, 0x0f, 0x22, 0xc0, /* movl %eax,%cr0 */ + 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */ +}; +static unsigned char jump_to_bios [] = +{ 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */ }; @@ -200,34 +203,13 @@ static inline void kb_wait(void) break; } -void machine_restart(char * __unused) +/* + * Switch to real mode and then execute the code + * specified by the code and length parameters. + * We assume that length will aways be less that 100! + */ +void machine_real_restart(unsigned char *code, int length) { -#if __SMP__ - /* - * Stop all CPUs and turn off local APICs and the IO-APIC, so - * other OSs see a clean IRQ state. - */ - smp_send_stop(); - disable_IO_APIC(); -#endif - - if(!reboot_thru_bios) { - /* rebooting needs to touch the page at absolute addr 0 */ - *((unsigned short *)__va(0x472)) = reboot_mode; - for (;;) { - int i; - for (i=0; i<100; i++) { - kb_wait(); - udelay(50); - outb(0xfe,0x64); /* pulse reset low */ - udelay(50); - } - /* That didn't work - force a triple fault.. */ - __asm__ __volatile__("lidt %0": :"m" (no_idt)); - __asm__ __volatile__("int3"); - } - } - cli(); /* Write zero to CMOS register number 0x0f, which the BIOS POST @@ -273,8 +255,9 @@ void machine_restart(char * __unused) off paging. Copy it near the end of the first page, out of the way of BIOS variables. */ - memcpy ((void *) (0x1000 - sizeof (real_mode_switch)), + memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch)); + memcpy ((void *) (0x1000 - 100), code, length); /* Set up the IDT for real mode. */ @@ -293,11 +276,11 @@ void machine_restart(char * __unused) the values are consistent for real mode operation already. */ __asm__ __volatile__ ("movl $0x0010,%%eax\n" - "\tmovl %%ax,%%ds\n" - "\tmovl %%ax,%%es\n" - "\tmovl %%ax,%%fs\n" - "\tmovl %%ax,%%gs\n" - "\tmovl %%ax,%%ss" : : : "eax"); + "\tmovl %%eax,%%ds\n" + "\tmovl %%eax,%%es\n" + "\tmovl %%eax,%%fs\n" + "\tmovl %%eax,%%gs\n" + "\tmovl %%eax,%%ss" : : : "eax"); /* Jump to the 16-bit code that we copied earlier. It disables paging and the cache, switches to real mode, and jumps to the BIOS reset @@ -305,7 +288,38 @@ void machine_restart(char * __unused) __asm__ __volatile__ ("ljmp $0x0008,%0" : - : "i" ((void *) (0x1000 - sizeof (real_mode_switch)))); + : "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100))); +} + +void machine_restart(char * __unused) +{ +#if __SMP__ + /* + * Stop all CPUs and turn off local APICs and the IO-APIC, so + * other OSs see a clean IRQ state. + */ + smp_send_stop(); + disable_IO_APIC(); +#endif + + if(!reboot_thru_bios) { + /* rebooting needs to touch the page at absolute addr 0 */ + *((unsigned short *)__va(0x472)) = reboot_mode; + for (;;) { + int i; + for (i=0; i<100; i++) { + kb_wait(); + udelay(50); + outb(0xfe,0x64); /* pulse reset low */ + udelay(50); + } + /* That didn't work - force a triple fault.. */ + __asm__ __volatile__("lidt %0": :"m" (no_idt)); + __asm__ __volatile__("int3"); + } + } + + machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); } void machine_halt(void) diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index 5719ecaf17db..4974d5c32840 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c @@ -260,7 +260,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk mark_screen_rdonly(tsk); unlock_kernel(); __asm__ __volatile__( - "xorl %%eax,%%eax; movl %%ax,%%fs; movl %%ax,%%gs\n\t" + "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t" "movl %0,%%esp\n\t" "jmp ret_from_sys_call" : /* no outputs */ diff --git a/arch/i386/math-emu/Makefile b/arch/i386/math-emu/Makefile index 588f7ada2759..68b327a2acd5 100644 --- a/arch/i386/math-emu/Makefile +++ b/arch/i386/math-emu/Makefile @@ -10,7 +10,7 @@ PARANOID = -DPARANOID CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION) .S.o: - $(CC) -D__ASSEMBLY__ $(PARANOID) -c $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) $(PARANOID) -c $< # From 'C' language sources: C_OBJS =fpu_entry.o errors.o \ diff --git a/arch/m68k/fpsp040/Makefile b/arch/m68k/fpsp040/Makefile index d3ec21217b44..bbfc0b174181 100644 --- a/arch/m68k/fpsp040/Makefile +++ b/arch/m68k/fpsp040/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< OS_TARGET := fpsp.o diff --git a/arch/m68k/ifpsp060/Makefile b/arch/m68k/ifpsp060/Makefile index 94eea44a4bce..7836197a6546 100644 --- a/arch/m68k/ifpsp060/Makefile +++ b/arch/m68k/ifpsp060/Makefile @@ -5,7 +5,7 @@ # for more details. .S.o: - $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< OS_TARGET := ifpsp.o diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 146fcb69b738..3d20007240e8 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o ifndef CONFIG_SUN3 all: head.o kernel.o diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index f152e28e4714..d1d6b1d7d901 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -3,7 +3,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ -traditional -c $< -o $@ + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $@ L_TARGET = lib.a L_OBJS = ashrdi3.o checksum.o memcpy.o memcmp.o memset.o semaphore.o diff --git a/arch/m68k/math-emu/Makefile b/arch/m68k/math-emu/Makefile index fe379cb2c9dd..0e22edc961b0 100644 --- a/arch/m68k/math-emu/Makefile +++ b/arch/m68k/math-emu/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) $(EXTRA_CFLAGS) -D__ASSEMBLY__ -traditional -c $< -o $*.o + $(CC) $(EXTRA_CFLAGS) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o #EXTRA_CFLAGS=-DFPU_EMU_DEBUG diff --git a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile index bf987e3d2310..998a4eee16b7 100644 --- a/arch/m68k/sun3/Makefile +++ b/arch/m68k/sun3/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) -D__ASSEMBLY__ -traditional -Wa,-m68020 -c $< -o $*.o + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -Wa,-m68020 -c $< -o $*.o O_TARGET := sun3.o O_OBJS := config.o idprom.o mmu_emu.o sun3ints.o leds.o dvma.o sbus.o diff --git a/arch/m68k/sun3/prom/Makefile b/arch/m68k/sun3/prom/Makefile index d1aeb0602077..aea488ed2604 100644 --- a/arch/m68k/sun3/prom/Makefile +++ b/arch/m68k/sun3/prom/Makefile @@ -17,6 +17,6 @@ promlib.a: $(OBJS) sync dep: - $(CPP) -M *.c > .depend + $(CPP) $(CPPFLAGS) -M *.c > .depend include $(TOPDIR)/Rules.make diff --git a/arch/mips/arc/Makefile b/arch/mips/arc/Makefile index 08ea3a4eab25..51f0a5242dcf 100644 --- a/arch/mips/arc/Makefile +++ b/arch/mips/arc/Makefile @@ -18,6 +18,6 @@ arclib.a: $(OBJS) sync dep: - $(CPP) -M *.c > .depend + $(CPP) $(CPPFLAGS) -M *.c > .depend include $(TOPDIR)/Rules.make diff --git a/arch/mips/dec/prom/Makefile b/arch/mips/dec/prom/Makefile index 33f906ece0b1..959f0f847804 100644 --- a/arch/mips/dec/prom/Makefile +++ b/arch/mips/dec/prom/Makefile @@ -24,6 +24,6 @@ rexlib.a: $(OBJS) locore.o: locore.S dep: - $(CPP) -M *.c > .depend + $(CPP) $(CPPFLAGS) -M *.c > .depend include $(TOPDIR)/Rules.make diff --git a/arch/mips/sgi/kernel/Makefile b/arch/mips/sgi/kernel/Makefile index 8a57e13405ee..760e9fe51b05 100644 --- a/arch/mips/sgi/kernel/Makefile +++ b/arch/mips/sgi/kernel/Makefile @@ -28,6 +28,6 @@ sgikern.a: $(OBJS) indyIRQ.o: indyIRQ.S dep: - $(CPP) -M *.c > .depend + $(CPP) $(CPPFLAGS) -M *.c > .depend include $(TOPDIR)/Rules.make diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 8a6db08e252b..6552a7140f67 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -20,8 +20,8 @@ endif ASFLAGS = LINKFLAGS = -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic -CFLAGSINC = -D__KERNEL__ -I$(TOPDIR)/include -D__powerpc__ -CFLAGS := $(CFLAGS) -I$(HPATH) -D__powerpc__ -fsigned-char \ +CPPFLAGS := $(CPPFLAGS) -D__powerpc__ +CFLAGS := $(CFLAGS) -D__powerpc__ -fsigned-char \ -msoft-float -pipe -fno-builtin -ffixed-r2 -Wno-uninitialized \ -mmultiple -mstring CPP = $(CC) -E $(CFLAGS) diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 96b6ba306ecc..eb48313f4eb1 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -16,9 +16,9 @@ .c.o: $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -c -o $*.o $< .S.s: - $(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< ZOFF = 0 ZSZ = 0 @@ -52,7 +52,7 @@ ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00800000 GZIP_FLAGS = -v9 OBJECTS := head.o misc.o ../coffboot/zlib.o -CFLAGS = -O2 -DSTDC_HEADERS -fno-builtin -I$(TOPDIR)/include +CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin OBJCOPY = $(CROSS_COMPILE)objcopy OBJCOPY_ARGS = -O elf32-powerpc @@ -140,7 +140,7 @@ fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend dep: - $(CPP) -M *.S *.c > .depend + $(CPP) $(CPPFLAGS) -M *.S *.c > .depend # just here to match coffboot/Makefile vmlinux.coff: diff --git a/arch/ppc/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile index 15f9a8e538a4..70ae95eb8e7d 100644 --- a/arch/ppc/chrpboot/Makefile +++ b/arch/ppc/chrpboot/Makefile @@ -12,11 +12,11 @@ .c.o: $(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $< .S.s: - $(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< -CFLAGS = -O -fno-builtin -DSTDC_HEADERS -I$(TOPDIR)/include +CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS LD_ARGS = -Ttext 0x00400000 OBJCOPY = $(CROSS_COMPILE)objcopy @@ -102,5 +102,5 @@ fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend dep: - $(CPP) -M *.S *.c > .depend + $(CPP) $(CPPFLAGS) -M *.S *.c > .depend diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile index a7ed94074b35..b9868e6ac216 100644 --- a/arch/ppc/coffboot/Makefile +++ b/arch/ppc/coffboot/Makefile @@ -7,7 +7,7 @@ HOSTCFLAGS = -O -I$(TOPDIR)/include CC = $(CROSS_COMPILE)gcc LD = $(CROSS_COMPILE)ld -CFLAGS = -O -fno-builtin -I$(TOPDIR)/include +CFLAGS = $(CPPFLAGS) -O -fno-builtin OBJCOPY = $(CROSS_COMPILE)objcopy OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c index 57ea34687cdb..f0b57a8b6622 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/kernel/gemini_setup.c @@ -335,7 +335,14 @@ void __init gemini_init_IRQ(void) irq_desc[i].ctl = &open_pic; openpic_init(1); #ifdef __SMP__ - request_irq(OPENPIC_VEC_IPI, openpic_ipi_action, 0, "IPI0", 0); + request_irq(OPENPIC_VEC_IPI, openpic_ipi_action, + 0, "IPI0", 0); + request_irq(OPENPIC_VEC_IPI+1, openpic_ipi_action, + 0, "IPI1 (invalidate TLB)", 0); + request_irq(OPENPIC_VEC_IPI+2, openpic_ipi_action, + 0, "IPI2 (stop CPU)", 0); + request_irq(OPENPIC_VEC_IPI+3, openpic_ipi_action, + 0, "IPI3 (reschedule)", 0); #endif /* __SMP__ */ } diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index 4b0375433f0b..c278585d9960 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -64,14 +64,13 @@ struct hw_interrupt_type open_pic = { if (pri < 0 || pri >= OPENPIC_NUM_PRI) \ printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri); /* - * Turned this check off since the IPI's are treated as irqs - * but they're above NumSources -- Cort - */ -#define check_arg_irq(irq) -#if 0 - if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \ - printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq); -#endif + * I changed this to return to keep us from from trying to use irq #'s + * that we're using for IPI's. + * -- Cort + */ +#define check_arg_irq(irq) \ + /*if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \ + printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);*/ #define check_arg_cpu(cpu) \ if (cpu < 0 || cpu >= NumProcessors) \ printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu); @@ -91,8 +90,7 @@ static void no_action(int ir1, void *dev, struct pt_regs *regs) #ifdef __SMP__ void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) { -printk("openpic_ipi_action\n"); - smp_message_recv(); + smp_message_recv(cpl-OPENPIC_VEC_IPI); } #endif /* __SMP__ */ @@ -213,6 +211,9 @@ void __init openpic_init(int main_pic) /* Initialize external interrupts */ if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc); + /* SIOint (8259 cascade) is special */ + openpic_initirq(0, 8, open_pic.irq_offset, 1, 1); + openpic_mapirq(0, 1<<0); for (i = 1; i < NumSources; i++) { /* Enabled, Priority 8 */ openpic_initirq(i, 8, open_pic.irq_offset+i, 0, @@ -226,9 +227,6 @@ void __init openpic_init(int main_pic) openpic_set_spurious(OPENPIC_VEC_SPURIOUS); if ( _machine != _MACH_gemini ) { - /* SIOint (8259 cascade) is special */ - openpic_initirq(0, 8, open_pic.irq_offset, 1, 1); - openpic_mapirq(0, 1<<0); if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT, "82c59 cascade", NULL)) printk("Unable to get OpenPIC IRQ 0 for cascade\n"); @@ -365,6 +363,27 @@ void openpic_enable_IPI(u_int ipi) OPENPIC_MASK); } +/* + * Do per-cpu setup for SMP systems. + * + * Get IPI's working and start taking interrupts. + * -- Cort + */ +void do_openpic_setup_cpu(void) +{ + int i; + + for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) + openpic_enable_IPI(i); +#if 0 + /* let the openpic know we want intrs */ + for ( i = 0; i < NumSources ; i++ ) + openpic_mapirq(i, openpic_read(&OpenPIC->Source[i].Destination) + | (1< #include #include +#include #include #include @@ -269,3 +270,4 @@ void ppc_irq_dispatch_handler(struct pt_regs *, int); EXPORT_SYMBOL(ppc_irq_dispatch_handler); EXPORT_SYMBOL(decrementer_count); EXPORT_SYMBOL(get_wchan); +EXPORT_SYMBOL(console_drivers); diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 403213883eba..64b17104243b 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -204,15 +204,6 @@ _switch_to(struct task_struct *prev, struct task_struct *new, if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) && prev->thread.vrsave ) giveup_altivec(prev); - /* - * The 750 doesn't broadcast invalidates with tlbie's - * so flush every processor switch. - * -- Cort - */ - if ( ((_get_PVR()>>16) == 8) && - (new->last_processor != NO_PROC_ID) && - (new->last_processor != new->processor) && new->mm ) - flush_tlb_mm(new->mm); prev->last_processor = prev->processor; current_set[smp_processor_id()] = new; #endif /* __SMP__ */ diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index fad7c7c1d07c..c2891e21f525 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -108,34 +108,8 @@ void smp_local_timer_interrupt(struct pt_regs * regs) } } -/* - * Dirty hack to get smp message passing working. - * - * As it is now, if we're sending two message at the same time - * we have race conditions. The PowerSurge doesn't easily - * allow us to send IPI messages so we put the messages in - * smp_message[]. - * - * This is because don't have several IPI's on the PowerSurge even though - * we do on the chrp. It would be nice to use the actual IPI's on the chrp - * rather than this but having two methods of doing IPI isn't a good idea - * right now. - * -- Cort - */ -int smp_message[NR_CPUS]; -void smp_message_recv(void) +void smp_message_recv(int msg) { - int msg = smp_message[smp_processor_id()]; - - if ( _machine == _MACH_Pmac ) - { - /* clear interrupt */ - out_be32(PSURGE_INTR, ~0); - } - - /* make sure msg is for us */ - if ( msg == -1 ) return; - ipi_count++; switch( msg ) @@ -147,15 +121,54 @@ void smp_message_recv(void) case MSG_RESCHEDULE: current->need_resched = 1; break; - case 0xf0f0: /* syncing time bases - just return */ + case MSG_INVALIDATE_TLB: + _tlbia(); + case 0xf0f0: /* pmac syncing time bases - just return */ break; default: printk("SMP %d: smp_message_recv(): unknown msg %d\n", smp_processor_id(), msg); break; } - /* reset message */ - smp_message[smp_processor_id()] = -1; +} + +/* + * As it is now, if we're sending two message at the same time + * we have race conditions on Pmac. The PowerSurge doesn't easily + * allow us to send IPI messages so we put the messages in + * smp_message[]. + * + * This is because don't have several IPI's on the PowerSurge even though + * we do on the chrp. It would be nice to use actual IPI's such as with openpic + * rather than this. + * -- Cort + */ +int pmac_smp_message[NR_CPUS]; +void pmac_smp_message_recv(void) +{ + int msg = pmac_smp_message[smp_processor_id()]; + + /* clear interrupt */ + out_be32(PSURGE_INTR, ~0); + + /* make sure msg is for us */ + if ( msg == -1 ) return; + + smp_message_recv(msg); + + /* reset message */ + pmac_smp_message[smp_processor_id()] = -1; +} + +/* + * 750's don't broadcast tlb invalidates so + * we have to emulate that behavior. + * -- Cort + */ +void smp_send_tlb_invalidate(int cpu) +{ + if ( (_get_PVR()>>16) == 8 ) + smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0, 0); } void smp_send_reschedule(int cpu) @@ -169,6 +182,8 @@ void smp_send_reschedule(int cpu) * as the timer). * -- Cort */ + /* This is only used if `cpu' is running an idle task, + so it will reschedule itself anyway... */ smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0); } @@ -177,38 +192,39 @@ void smp_send_stop(void) smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0); } -spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED; void smp_message_pass(int target, int msg, unsigned long data, int wait) { int i; - if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_gemini)) ) + + if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) ) return; - spin_lock(&mesg_pass_lock); - - /* - * We assume here that the msg is not -1. If it is, - * the recipient won't know the message was destined - * for it. -- Cort - */ - - switch( target ) - { - case MSG_ALL: - smp_message[smp_processor_id()] = msg; - /* fall through */ - case MSG_ALL_BUT_SELF: - for ( i = 0 ; i < smp_num_cpus ; i++ ) - if ( i != smp_processor_id () ) - smp_message[i] = msg; - break; - default: - smp_message[target] = msg; - break; - } - - if ( _machine == _MACH_Pmac ) - { + switch (_machine) { + case _MACH_Pmac: + /* + * IPI's on the Pmac are a hack but without reasonable + * IPI hardware SMP on Pmac is a hack. + * + * We assume here that the msg is not -1. If it is, + * the recipient won't know the message was destined + * for it. -- Cort + */ + for ( i = 0; i <= smp_num_cpus ; i++ ) + pmac_smp_message[i] = -1; + switch( target ) + { + case MSG_ALL: + pmac_smp_message[smp_processor_id()] = msg; + /* fall through */ + case MSG_ALL_BUT_SELF: + for ( i = 0 ; i < smp_num_cpus ; i++ ) + if ( i != smp_processor_id () ) + pmac_smp_message[i] = msg; + break; + default: + pmac_smp_message[target] = msg; + break; + } /* interrupt secondary processor */ out_be32(PSURGE_INTR, ~0); out_be32(PSURGE_INTR, 0); @@ -218,40 +234,28 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) */ /* interrupt primary */ /**(volatile unsigned long *)(0xf3019000);*/ - } - - if ( _machine == _MACH_chrp ) - { - /* - * There has to be some way of doing this better - - * perhaps a send-to-all or send-to-all-but-self - * in the openpic. This gets us going for now, though. - * -- Cort - */ + break; + case _MACH_chrp: + case _MACH_prep: + case _MACH_gemini: + /* make sure we're sending something that translates to an IPI */ + if ( msg > 0x3 ) + break; switch ( target ) { case MSG_ALL: - openpic_cause_IPI(smp_processor_id(), 0, 0x0 ); - openpic_cause_IPI(smp_processor_id(), 0, 0xffffffff ); + openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff); break; case MSG_ALL_BUT_SELF: - for ( i = 0 ; i < smp_num_cpus ; i++ ) - if ( i != smp_processor_id () ) - { - openpic_cause_IPI(smp_processor_id(), 0, - 0x0 ); - openpic_cause_IPI(smp_processor_id(), 0, + openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff & ~(1 << smp_processor_id())); - } break; default: - openpic_cause_IPI(smp_processor_id(), 0, 0x0 ); - openpic_cause_IPI(target, 0, 1U << target ); + openpic_cause_IPI(smp_processor_id(), msg, 1<mm->mmap->vm_end = init_mm.mmap->vm_end; #endif cpu_callin_map[current->processor] = 1; + /* + * Each processor has to do this and this is the best + * place to stick it for now. + * -- Cort + */ + if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) ) + do_openpic_setup_cpu(); while(!smp_commenced) barrier(); __sti(); diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index 8ca9a3cd5466..e454e952dc0b 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -3,7 +3,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ -c $< -o $*.o + $(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $*.o O_TARGET = lib.o O_OBJS = checksum.o string.o strcase.o diff --git a/arch/ppc/mbxboot/Makefile b/arch/ppc/mbxboot/Makefile index ce86ebbe8af4..0a70462a7a6d 100644 --- a/arch/ppc/mbxboot/Makefile +++ b/arch/ppc/mbxboot/Makefile @@ -16,9 +16,9 @@ .c.o: $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -c -o $*.o $< .S.s: - $(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $< + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< ZOFF = 0 ZSZ = 0 @@ -30,7 +30,7 @@ ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00100000 GZIP_FLAGS = -v9 OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o -CFLAGS = -O2 -DSTDC_HEADERS -fno-builtin -I$(TOPDIR)/include -DCONFIG_8xx +CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8xx OBJCOPY = $(CROSS_COMPILE)objcopy OBJCOPY_ARGS = -O elf32-powerpc @@ -109,7 +109,7 @@ fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend dep: - $(CPP) -M *.S *.c > .depend + $(CPP) $(CPPFLAGS) -M *.S *.c > .depend # just here to match coffboot/Makefile vmlinux.coff: diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 397083aca118..34117098e402 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -324,23 +324,24 @@ void show_mem(void) void si_meminfo(struct sysinfo *val) { - int i, c; + int i; i = max_mapnr; - val->totalram = totalram_pages; + val->totalram = 0; + val->sharedram = 0; val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); - val->sharedram = 0; while (i-- > 0) { if (PageReserved(mem_map+i)) continue; - c = atomic_read(&mem_map[i].count); - if (c > 1) - val->sharedram += c - 1; + val->totalram++; + if (!atomic_read(&mem_map[i].count)) + continue; + val->sharedram += atomic_read(&mem_map[i].count) - 1; } - val->totalhigh = 0; - val->freehigh = 0; - val->mem_unit = PAGE_SIZE; + val->totalram <<= PAGE_SHIFT; + val->sharedram <<= PAGE_SHIFT; + return; } void * @@ -498,6 +499,9 @@ local_flush_tlb_all(void) { __clear_user(Hash, Hash_size); _tlbia(); +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif } /* @@ -511,6 +515,9 @@ local_flush_tlb_mm(struct mm_struct *mm) mm->context = NO_CONTEXT; if (mm == current->mm) activate_mm(mm, mm); +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif } void @@ -520,6 +527,9 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) flush_hash_page(vma->vm_mm->context, vmaddr); else flush_hash_page(0, vmaddr); +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif } @@ -545,6 +555,9 @@ local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long e { flush_hash_page(mm->context, start); } +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif } /* @@ -566,6 +579,9 @@ mmu_context_overflow(void) } read_unlock(&tasklist_lock); flush_hash_segments(0x10, 0xffffff); +#ifdef __SMP__ + smp_send_tlb_invalidate(0); +#endif atomic_set(&next_mmu_context, 0); /* make sure current always has a context */ current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context)); @@ -715,7 +731,7 @@ static void __init mapin_ram(void) f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; #ifndef CONFIG_8xx else - /* On the powerpc, denying user access + /* On the powerpc (not 8xx), no user access forces R/W kernel access */ f |= _PAGE_USER; #endif /* CONFIG_8xx */ @@ -874,7 +890,7 @@ void __init MMU_init(void) setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); break; case _MACH_Pmac: -#if 1 +#if 0 { unsigned long base = 0xf3000000; struct device_node *macio = find_devices("mac-io"); @@ -967,7 +983,6 @@ void __init do_init_bootmem(void) /* remove the bootmem bitmap from the available memory */ mem_pieces_remove(&phys_avail, start, boot_mapsize, 1); - /* add everything in phys_avail into the bootmem map */ for (i = 0; i < phys_avail.n_regions; ++i) free_bootmem(phys_avail.regions[i].address, @@ -1053,9 +1068,9 @@ void __init mem_init(void) int codepages = 0; int datapages = 0; int initpages = 0; -#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) +#if defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) extern unsigned int rtas_data, rtas_size; -#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */ +#endif /* defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) */ max_mapnr = max_low_pfn; high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); num_physpages = max_mapnr; /* RAM is assumed contiguous */ @@ -1071,13 +1086,13 @@ void __init mem_init(void) } #endif /* CONFIG_BLK_DEV_INITRD */ -#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) +#if defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) /* mark the RTAS pages as reserved */ if ( rtas_data ) for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ; addr += PAGE_SIZE) SetPageReserved(mem_map + MAP_NR(addr)); -#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */ +#endif /* defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC) */ for (addr = PAGE_OFFSET; addr < (unsigned long)end_of_DRAM; addr += PAGE_SIZE) { @@ -1088,12 +1103,12 @@ void __init mem_init(void) else if (addr >= (unsigned long)&__init_begin && addr < (unsigned long)&__init_end) initpages++; - else + else if (addr < (ulong) klimit) datapages++; } printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n", - (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), + (unsigned long) nr_free_pages << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10), datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10), diff --git a/arch/sparc/ap1000/Makefile b/arch/sparc/ap1000/Makefile index 83df0ef8ea44..f070f7675f5a 100644 --- a/arch/sparc/ap1000/Makefile +++ b/arch/sparc/ap1000/Makefile @@ -6,9 +6,9 @@ # .S.s: - $(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s + $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o all: ap1000lib.o diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 2e2fdef2c6b0..323608dcd2a0 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -55,11 +55,13 @@ check_asm: dummy @echo "#ifndef CONFIG_SMP" >> asm_offsets.h @echo "" >> asm_offsets.h @echo "#include " > tmp.c + @echo "#undef __SMP__" >> tmp.c @echo "#undef CONFIG_SMP" >> tmp.c @echo "#include " >> tmp.c - $(CC) -E tmp.c -o tmp.i + $(CC) $(CPPFLAGS) -E tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c + @echo "#undef __SMP__" >> check_asm.c @echo "#undef CONFIG_SMP" >> check_asm.c @echo "#include " >> check_asm.c @echo 'struct task_struct _task;' >> check_asm.c @@ -71,7 +73,7 @@ check_asm: dummy $(SH) ./check_asm.sh thread tmp.i check_asm.c @echo 'return 0; }' >> check_asm.c @rm -f tmp.[ci] - $(CC) -o check_asm check_asm.c + $(CC) $(CFLAGS) -o check_asm check_asm.c ./check_asm >> asm_offsets.h @rm -f check_asm check_asm.c @echo "" >> asm_offsets.h @@ -81,7 +83,7 @@ check_asm: dummy @echo "#undef CONFIG_SMP" >> tmp.c @echo "#define CONFIG_SMP 1" >> tmp.c @echo "#include " >> tmp.c - $(CC) -D__SMP__ -E tmp.c -o tmp.i + $(CC) $(CPPFLAGS) -D__SMP__ -E tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c @echo "#undef CONFIG_SMP" >> check_asm.c @@ -96,7 +98,7 @@ check_asm: dummy $(SH) ./check_asm.sh thread tmp.i check_asm.c @echo 'return 0; }' >> check_asm.c @rm -f tmp.[ci] - $(CC) -D__SMP__ -o check_asm check_asm.c + $(CC) $(CFLAGS) -D__SMP__ -o check_asm check_asm.c ./check_asm >> asm_offsets.h @rm -f check_asm check_asm.c @echo "" >> asm_offsets.h diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index d5b4754802d6..af0f8906e50e 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -16,34 +16,34 @@ lib.a: $(OBJS) sync checksum.o: checksum.S - $(CC) -D__ASSEMBLY__ -ansi -c -o checksum.o checksum.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o checksum.o checksum.S memcpy.o: memcpy.S - $(CC) -D__ASSEMBLY__ -ansi -c -o memcpy.o memcpy.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o memcpy.o memcpy.S memcmp.o: memcmp.S - $(CC) -D__ASSEMBLY__ -ansi -c -o memcmp.o memcmp.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o memcmp.o memcmp.S memscan.o: memscan.S - $(CC) -D__ASSEMBLY__ -ansi -c -o memscan.o memscan.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o memscan.o memscan.S strncmp.o: strncmp.S - $(CC) -D__ASSEMBLY__ -ansi -c -o strncmp.o strncmp.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o strncmp.o strncmp.S strncpy_from_user.o: strncpy_from_user.S - $(CC) -D__ASSEMBLY__ -ansi -c -o strncpy_from_user.o strncpy_from_user.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o strncpy_from_user.o strncpy_from_user.S strlen_user.o: strlen_user.S - $(CC) -D__ASSEMBLY__ -ansi -c -o strlen_user.o strlen_user.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o strlen_user.o strlen_user.S copy_user.o: copy_user.S - $(CC) -D__ASSEMBLY__ -ansi -c -o copy_user.o copy_user.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o copy_user.o copy_user.S blockops.o: blockops.S - $(CC) -D__ASSEMBLY__ -ansi -c -o blockops.o blockops.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o blockops.o blockops.S memset.o: memset.S - $(CC) -D__ASSEMBLY__ -ansi -c -o memset.o memset.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o memset.o memset.S locks.o: locks.S $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o locks.o locks.S @@ -60,37 +60,37 @@ irqlock.o: irqlock.S endif strlen.o: strlen.S - $(CC) -D__ASSEMBLY__ -ansi -c -o strlen.o strlen.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o strlen.o strlen.S divdi3.o: divdi3.S - $(CC) -D__ASSEMBLY__ -ansi -c -o divdi3.o divdi3.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o divdi3.o divdi3.S udivdi3.o: udivdi3.S - $(CC) -D__ASSEMBLY__ -ansi -c -o udivdi3.o udivdi3.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o udivdi3.o udivdi3.S mul.o: mul.S - $(CC) -D__ASSEMBLY__ -c -o mul.o mul.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o mul.o mul.S rem.o: rem.S - $(CC) -D__ASSEMBLY__ -DST_DIV0=0x2 -c -o rem.o rem.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -DST_DIV0=0x2 -c -o rem.o rem.S sdiv.o: sdiv.S - $(CC) -D__ASSEMBLY__ -DST_DIV0=0x2 -c -o sdiv.o sdiv.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -DST_DIV0=0x2 -c -o sdiv.o sdiv.S udiv.o: udiv.S - $(CC) -D__ASSEMBLY__ -DST_DIV0=0x2 -c -o udiv.o udiv.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -DST_DIV0=0x2 -c -o udiv.o udiv.S umul.o: umul.S - $(CC) -D__ASSEMBLY__ -c -o umul.o umul.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o umul.o umul.S urem.o: urem.S - $(CC) -D__ASSEMBLY__ -DST_DIV0=0x2 -c -o urem.o urem.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -DST_DIV0=0x2 -c -o urem.o urem.S ashrdi3.o: ashrdi3.S - $(CC) -D__ASSEMBLY__ -c -o ashrdi3.o ashrdi3.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o ashrdi3.o ashrdi3.S lshrdi3.o: lshrdi3.S - $(CC) -D__ASSEMBLY__ -c -o lshrdi3.o lshrdi3.S + $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o lshrdi3.o lshrdi3.S dep: diff --git a/arch/sparc/math-emu/Makefile b/arch/sparc/math-emu/Makefile index 6e4862a8361f..e8880cd078b1 100644 --- a/arch/sparc/math-emu/Makefile +++ b/arch/sparc/math-emu/Makefile @@ -11,10 +11,10 @@ O_TARGET := math-emu.o O_OBJS := math.o ashldi3.o .S.s: - $(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s + $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o + $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 917aa9ad72cf..1f4047f64229 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile @@ -22,6 +22,6 @@ promlib.a: $(OBJS) sync dep: - $(CPP) -M *.c > .depend + $(CPP) $(CPPFLAGS) -M *.c > .depend include $(TOPDIR)/Rules.make diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile index 1216a3a4f44f..df4aac61af6a 100644 --- a/arch/sparc64/Makefile +++ b/arch/sparc64/Makefile @@ -12,17 +12,11 @@ # line... SHELL =/bin/bash -CC := sparc64-linux-gcc -D__KERNEL__ -I$(TOPDIR)/include +CC := sparc64-linux-gcc -CC_HAS_ARGS := $(shell if echo "$(CC)" | grep '\(__KERNEL__\| \)' > /dev/null; then echo y; else echo n; fi) IS_EGCS := $(shell if $(CC) -m64 -mcmodel=medlow -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo y; else echo n; fi; ) NEW_GAS := $(shell if $(LD) --version 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi) -ifneq ($(CC_HAS_ARGS),y) -MAKEOVERRIDES := $(shell echo "$(MAKEOVERRIDES)" | sed 's CC=$(CC) CC=$(CC)\\\ -D__KERNEL__\\\ -I$(TOPDIR)/include ') -override CC := $(CC) -D__KERNEL__ -I$(TOPDIR)/include -endif - ifneq ($(NEW_GAS),y) AS = sparc64-linux-as LD = sparc64-linux-ld diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 34f52698e7ad..607a8a2615c9 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -74,11 +74,13 @@ check_asm: dummy @echo -e "# error Please issue 'make check_asm' in linux top-level directory first\n# endif\n#endif\n" >> asm_offsets.h @echo -e "#ifndef CONFIG_SMP\n" >> asm_offsets.h @echo "#include " > tmp.c + @echo "#undef __SMP__" >> tmp.c @echo "#undef CONFIG_SMP" >> tmp.c @echo "#include " >> tmp.c - $(CC) -E tmp.c -o tmp.i + $(CC) $(CPPFLAGS) -E tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c + @echo "#undef __SMP__" >> check_asm.c @echo "#undef CONFIG_SMP" >> check_asm.c @echo "#include " >> check_asm.c @echo 'struct task_struct _task;' >> check_asm.c @@ -92,7 +94,7 @@ check_asm: dummy @rm -f tmp.[ci] #$(CC) -o check_asm check_asm.c # Until we can do this natively, a hack has to take place - $(CC) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c + $(CC) $(CPPFLAGS) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c $(HOSTCC) -Wa,-Av9a -o check_asm check_asm.s @rm -f check_asm.s # @@ -104,7 +106,7 @@ check_asm: dummy @echo "#undef CONFIG_SMP" >> tmp.c @echo "#define CONFIG_SMP 1" >> tmp.c @echo "#include " >> tmp.c - $(CC) -D__SMP__ -E tmp.c -o tmp.i + $(CC) $(CPPFLAGS) -D__SMP__ -E tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c @echo "#undef CONFIG_SMP" >> check_asm.c @@ -121,7 +123,7 @@ check_asm: dummy @rm -f tmp.[ci] #$(CC) -D__SMP__ -o check_asm check_asm.c # Until we can do this natively, a hack has to take place - $(CC) -D__SMP__ $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c + $(CC) $(CPPFLAGS) -D__SMP__ $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c $(HOSTCC) -Wa,-Av9a -o check_asm check_asm.s @rm -f check_asm.s # @@ -129,7 +131,7 @@ check_asm: dummy @rm -f check_asm check_asm.c @echo -e "\n#else /* SPIN_LOCK_DEBUG */\n" >> asm_offsets.h @echo "#include " > tmp.c - $(CC) -D__SMP__ -DSPIN_LOCK_DEBUG -E tmp.c -o tmp.i + $(CC) $(CPPFLAGS) -D__SMP__ -DSPIN_LOCK_DEBUG -E tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c @echo "#undef CONFIG_SMP" >> check_asm.c @@ -146,7 +148,7 @@ check_asm: dummy @rm -f tmp.[ci] #$(CC) -D__SMP__ -DSPIN_LOCK_DEBUG -o check_asm check_asm.c # Until we can do this natively, a hack has to take place - $(CC) -D__SMP__ -DSPIN_LOCK_DEBUG $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c + $(CC) $(CPPFLAGS) -D__SMP__ -DSPIN_LOCK_DEBUG $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c $(HOSTCC) -Wa,-Av9a -o check_asm check_asm.s @rm -f check_asm.s # diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile index 1cec2111e18d..9e6b185fb6b0 100644 --- a/arch/sparc64/prom/Makefile +++ b/arch/sparc64/prom/Makefile @@ -18,6 +18,6 @@ promlib.a: $(OBJS) sync dep: - $(CPP) -M *.c > .depend + $(CPP) $(CPPFLAGS) -M *.c > .depend include $(TOPDIR)/Rules.make diff --git a/drivers/block/Config.in b/drivers/block/Config.in index 5b7ef403d6f6..0c0c1048186b 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -70,11 +70,11 @@ else if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_HPT366" = "y" ]; then bool ' HPT366 Fast Interrupt support (EXPERIMENTAL)' HPT366_FAST_IRQ_PREDICTION fi - fi - if [ "$CONFIG_X86" = "y" ]; then - bool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX - if [ "$CONFIG_BLK_DEV_PIIX" = "y" -a "$CONFIG_IDEDMA_PCI_AUTO" = "y" ]; then - bool ' PIIXn Tuning support' CONFIG_BLK_DEV_PIIX_TUNING + if [ "$CONFIG_X86" = "y" ]; then + bool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX + if [ "$CONFIG_BLK_DEV_PIIX" = "y" -a "$CONFIG_IDEDMA_PCI_AUTO" = "y" ]; then + bool ' PIIXn Tuning support' CONFIG_BLK_DEV_PIIX_TUNING + fi fi fi if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then diff --git a/drivers/char/console.c b/drivers/char/console.c index 2a58a72ec638..090f1066cdc9 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -91,9 +91,6 @@ #include #include #include -#ifdef CONFIG_APM -#include -#endif #include #include @@ -189,6 +186,12 @@ DECLARE_TASK_QUEUE(con_task_queue); */ static int scrollback_delta = 0; +/* + * Hook so that the power management routines can (un)blank + * the console on our behalf. + */ +int (*console_blank_hook)(int) = NULL; + /* * Low-Level Functions */ @@ -2551,10 +2554,8 @@ void do_blank_screen(int entering_gfx) if (i) set_origin(currcons); -#ifdef CONFIG_APM - if (apm_display_blank()) + if (console_blank_hook && console_blank_hook(1)) return; -#endif if (vesa_blank_mode) sw->con_blank(vc_cons[currcons].d, vesa_blank_mode + 1); } @@ -2578,9 +2579,8 @@ void unblank_screen(void) currcons = fg_console; console_blanked = 0; -#ifdef CONFIG_APM - apm_display_unblank(); -#endif + if (console_blank_hook) + console_blank_hook(0); if (sw->con_blank(vc_cons[currcons].d, 0)) /* Low-level driver cannot restore -> do it ourselves */ update_screen(fg_console); diff --git a/drivers/char/lp.c b/drivers/char/lp.c index d42b0f39b3bb..eb56250ae132 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -679,7 +679,7 @@ static kdev_t lp_console_device (struct console *c) } static struct console lpcons = { - "lp", + "lp0", lp_console_write, NULL, lp_console_device, diff --git a/drivers/net/aironet4500.h b/drivers/net/aironet4500.h index 933ce485e234..95f0d23af11b 100644 --- a/drivers/net/aironet4500.h +++ b/drivers/net/aironet4500.h @@ -2,7 +2,7 @@ * Aironet 4500 Pcmcia driver * * Elmer Joandi, Januar 1999 - * Copyright Elmer Joandi, all rights restricted + * Copyright: GPL * * * Revision 0.1 ,started 30.12.1998 @@ -15,12 +15,14 @@ #define AIRONET4500_H // redefined to avoid PCMCIA includes -#include -#include -#include - -#if (LINUX_VERSION_CODE < 0x2030e) + #include +/*#include + #include +*/ +#if LINUX_VERSION_CODE < 0x2030E #define NET_DEVICE device +#error bad kernel version code + #else #define NET_DEVICE net_device #endif @@ -28,12 +30,13 @@ #if LINUX_VERSION_CODE < 0x20300 #define init_MUTEX(a) *(a) = MUTEX; #endif - +/* #include #include #include #include #include +*/ #include //damn idiot PCMCIA stuff @@ -53,41 +56,12 @@ typedef struct pcmcia_junkdev_node_t dev_node_t; -#if LINUX_VERSION_CODE <= 0x20100 - -typedef struct { volatile int lock ;} my_spinlock_t; - -#define my_spin_lock_irqsave(a,b) {\ - save_flags(b);\ - cli();\ - (a)->lock++;while(0);\ - if ((a)->lock != 1 )\ - printk("awc_spinlock high at locking \n");\ -} - -#define my_spin_unlock_irqrestore(a,b) {\ - cli(); (a)->lock--;while(0);\ - if ((a)->lock != 0 )\ - printk("awc_spinlock !=0 at unlocking \n");\ - restore_flags(b);\ -} - - -#else -#if LINUX_VERSION_CODE < 0x20300 -#include -#else #include -#endif -#ifndef __SMP__ -// #warning non-SMP 2.2 kernel -#endif typedef spinlock_t my_spinlock_t ; +#define my_spin_lock_init(a) spin_lock_init(a) #define my_spin_lock_irqsave(a,b) spin_lock_irqsave(a,b) #define my_spin_unlock_irqrestore(a,b) spin_unlock_irqrestore(a,b) -#endif //kernel version - #if LINUX_VERSION_CODE <= 0x20100 #define in_interrupt() intr_count @@ -193,11 +167,17 @@ struct awc_command { /* if (!in_interrupt())\ printk("bap lock under cli but not in int\n");\ */ + +#define AWC_LOCK_COMMAND_ISSUING(a) my_spin_lock_irqsave(&a->command_issuing_spinlock,a->command_issuing_spinlock_flags); +#define AWC_UNLOCK_COMMAND_ISSUING(a) my_spin_unlock_irqrestore(&a->command_issuing_spinlock,a->command_issuing_spinlock_flags); + #define AWC_BAP_LOCK_UNDER_CLI_REAL(cmd) \ if (!cmd.priv) {\ printk(KERN_CRIT "awc4500: no priv present in command !");\ }\ cmd.bap = &(cmd.priv->bap1);\ + if (both_bap_lock)\ + my_spin_lock_irqsave(&cmd.priv->both_bap_spinlock,cmd.priv->both_bap_spinlock_flags);\ if (cmd.bap){\ my_spin_lock_irqsave(&(cmd.bap->spinlock),cmd.bap->flags);\ cmd.bap->lock++;\ @@ -213,6 +193,8 @@ struct awc_command { printk(KERN_CRIT "awc4500: no priv present in command,lockup follows !");\ }\ cmd.bap = &(cmd.priv->bap0);\ + if (both_bap_lock)\ + my_spin_lock_irqsave(&cmd.priv->both_bap_spinlock,cmd.priv->both_bap_spinlock_flags);\ my_spin_lock_irqsave(&(cmd.bap->spinlock),cmd.bap->flags);\ DOWN(&(cmd.priv->bap0.sem));\ cmd.bap->lock++;\ @@ -223,6 +205,8 @@ struct awc_command { #define AWC_BAP_LOCK_NOT_CLI_CLI_REAL(cmd) {\ cmd.bap = &(cmd.priv->bap0);\ + if (both_bap_lock)\ + my_spin_lock_irqsave(&cmd.priv->both_bap_spinlock,cmd.priv->both_bap_spinlock_flags);\ my_spin_lock_irqsave(&(cmd.bap->spinlock),cmd.bap->flags);\ cmd.bap->lock++;\ if (cmd.bap->lock > 1)\ @@ -292,6 +276,8 @@ struct awc_command { my_spin_unlock_irqrestore(&(cmd.bap->spinlock),cmd.bap->flags);\ }\ }\ + if (both_bap_lock)\ + my_spin_unlock_irqrestore(&cmd.priv->both_bap_spinlock,cmd.priv->both_bap_spinlock_flags);\ } #define AWC_RELEASE_COMMAND(com) {\ @@ -475,7 +461,7 @@ struct awc_fid_queue { struct awc_fid * head; struct awc_fid * tail; int size; - my_spinlock_t lock; + my_spinlock_t spinlock; }; @@ -483,16 +469,13 @@ extern inline void awc_fid_queue_init(struct awc_fid_queue * queue){ unsigned long flags; -#ifdef __SMP__ - queue->lock.lock = 0; -#endif memset(queue,0, sizeof(struct awc_fid_queue)); - - my_spin_lock_irqsave(&queue->lock,flags); + my_spin_lock_init(&queue->spinlock); + my_spin_lock_irqsave(&queue->spinlock,flags); queue->head = NULL; queue->tail = NULL; queue->size = 0; - my_spin_unlock_irqrestore(&queue->lock,flags); + my_spin_unlock_irqrestore(&queue->spinlock,flags); }; extern inline void @@ -501,7 +484,7 @@ awc_fid_queue_push_tail( struct awc_fid_queue * queue, unsigned long flags; - my_spin_lock_irqsave(&queue->lock,flags); + my_spin_lock_irqsave(&queue->spinlock,flags); fid->prev = queue->tail; fid->next = NULL; @@ -515,7 +498,7 @@ awc_fid_queue_push_tail( struct awc_fid_queue * queue, queue->head = fid; queue->size++; - my_spin_unlock_irqrestore(&queue->lock,flags); + my_spin_unlock_irqrestore(&queue->spinlock,flags); }; @@ -526,7 +509,7 @@ awc_fid_queue_push_head( struct awc_fid_queue * queue, unsigned long flags; - my_spin_lock_irqsave(&queue->lock,flags); + my_spin_lock_irqsave(&queue->spinlock,flags); fid->prev = NULL; fid->next = queue->head; @@ -541,7 +524,7 @@ awc_fid_queue_push_head( struct awc_fid_queue * queue, queue->size++; - my_spin_unlock_irqrestore(&queue->lock,flags); + my_spin_unlock_irqrestore(&queue->spinlock,flags); }; @@ -579,11 +562,11 @@ extern inline void awc_fid_queue_remove( struct awc_fid_queue * queue, struct awc_fid * fid){ unsigned long flags; - my_spin_lock_irqsave(&queue->lock,flags); + my_spin_lock_irqsave(&queue->spinlock,flags); awc_fid_queue_rm(queue,fid); - my_spin_unlock_irqrestore(&queue->lock,flags); + my_spin_unlock_irqrestore(&queue->spinlock,flags); }; @@ -595,14 +578,14 @@ awc_fid_queue_pop_head( struct awc_fid_queue * queue){ unsigned long flags; struct awc_fid * fid; - my_spin_lock_irqsave(&queue->lock,flags); + my_spin_lock_irqsave(&queue->spinlock,flags); fid = queue->head; if (fid) awc_fid_queue_rm(queue,fid); - my_spin_unlock_irqrestore(&queue->lock,flags); + my_spin_unlock_irqrestore(&queue->spinlock,flags); return fid; }; @@ -616,13 +599,13 @@ awc_fid_queue_pop_tail( struct awc_fid_queue * queue){ unsigned long flags; struct awc_fid * fid; - my_spin_lock_irqsave(&queue->lock,flags); + my_spin_lock_irqsave(&queue->spinlock,flags); fid = queue->tail; if (fid) awc_fid_queue_rm(queue,fid); - my_spin_unlock_irqrestore(&queue->lock,flags); + my_spin_unlock_irqrestore(&queue->spinlock,flags); return fid; }; @@ -630,7 +613,7 @@ awc_fid_queue_pop_tail( struct awc_fid_queue * queue){ #define AWC_TX_HEAD_SIZE 0x44 -#define AWC_TX_ALLOC_SMALL_SIZE 150 +#define AWC_TX_ALLOC_SMALL_SIZE 200 #define AWC_RX_BUFFS 50 @@ -1522,7 +1505,13 @@ struct awc_private { volatile int interrupt_count; // Command serialize stuff - struct semaphore command_semaphore; +//changed to spinlock struct semaphore command_semaphore; + my_spinlock_t both_bap_spinlock; + unsigned long both_bap_spinlock_flags; + my_spinlock_t bap_setup_spinlock; + unsigned long bap_setup_spinlock_flags; + my_spinlock_t command_issuing_spinlock; + unsigned long command_issuing_spinlock_flags; volatile int unlock_command_postponed; struct awc_command cmd; long long async_command_start; @@ -1607,6 +1596,8 @@ extern int bap_sleep_after_setup ; extern int sleep_before_command ; extern int bap_sleep_before_write; extern int sleep_in_command ; +extern int both_bap_lock; +extern int bap_setup_spinlock; extern int tx_queue_len ; extern int tx_rate; extern int awc_full_stats; @@ -1614,6 +1605,7 @@ extern int awc_full_stats; #define MAX_AWCS 4 extern struct NET_DEVICE * aironet4500_devices[MAX_AWCS]; +#define AWC_DEBUG 1 #ifdef AWC_DEBUG #define DEBUG(a,args...) if (awc_debug & a) printk( args) diff --git a/drivers/net/aironet4500_card.c b/drivers/net/aironet4500_card.c index 1725f4aec54b..b6a00e87549c 100644 --- a/drivers/net/aironet4500_card.c +++ b/drivers/net/aironet4500_card.c @@ -2,7 +2,7 @@ * Aironet 4500 PCI-ISA-i365 driver * * Elmer Joandi, Januar 1999 - * Copyright Elmer Joandi, all rights restricted + * Copyright GPL * * * Revision 0.1 ,started 30.12.1998 @@ -35,7 +35,7 @@ static const char *awc_version = #include #include #include - +#include #if LINUX_VERSION_CODE < 0x20100 #include #endif diff --git a/drivers/net/aironet4500_core.c b/drivers/net/aironet4500_core.c index 4461ad2fba23..6b293dad1bed 100644 --- a/drivers/net/aironet4500_core.c +++ b/drivers/net/aironet4500_core.c @@ -1,14 +1,21 @@ /* - * Aironet 4500 Pcmcia driver + * Aironet 4500/4800 driver core * * Elmer Joandi, Januar 1999 - * Copyright Elmer Joandi, all rights restricted + * Copyright: GPL * * * Revision 0.1 ,started 30.12.1998 * * */ + /* CHANGELOG: + march 99, stable version 2.0 + august 99, stable version 2.2 + november 99, integration with 2.3 + 17.12.99: finally, got SMP near-correct. + timing issues remain- on SMP box its 15% slower on tcp + */ #include #include @@ -34,12 +41,16 @@ int bap_sleep_after_setup = 1; int sleep_before_command = 1; int bap_sleep_before_write= 1; int sleep_in_command = 1; +int both_bap_lock =0; /* activated at awc_init in this */ +int bap_setup_spinlock =0; /* file if numcpu >1 */ EXPORT_SYMBOL(bap_sleep); EXPORT_SYMBOL(bap_sleep_after_setup); EXPORT_SYMBOL(sleep_before_command); EXPORT_SYMBOL(bap_sleep_before_write); EXPORT_SYMBOL(sleep_in_command); +EXPORT_SYMBOL(both_bap_lock); +EXPORT_SYMBOL(bap_setup_spinlock); struct awc_strings awc_status_error_codes[]=awc_reply_error_strings; struct awc_strings awc_command_names[]=awc_command_name_strings; @@ -160,10 +171,7 @@ awc_issue_command_and_block(struct awc_command * cmd){ AWC_ENTRY_EXIT_DEBUG(" entry awc_issue_command_and_block "); - DOWN(&cmd->priv->command_semaphore); - -// save_flags(flags); -// cli(); + AWC_LOCK_COMMAND_ISSUING(cmd->priv); if (awc_command_busy_clear_wait(cmd->dev)) goto final; @@ -232,14 +240,12 @@ awc_issue_command_and_block(struct awc_command * cmd){ goto final; } - // restore_flags(flags); - UP(&cmd->priv->command_semaphore); + AWC_UNLOCK_COMMAND_ISSUING(cmd->priv); AWC_ENTRY_EXIT_DEBUG(" exit \n"); udelay(1); return 0; final: -// restore_flags(flags); - UP(&cmd->priv->command_semaphore); + AWC_UNLOCK_COMMAND_ISSUING(cmd->priv); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ; }; @@ -268,7 +274,7 @@ awc_issue_command(struct awc_command * cmd){ } - DOWN(&cmd->priv->command_semaphore); + AWC_LOCK_COMMAND_ISSUING(cmd->priv); if(awc_command_busy_clear_wait(cmd->dev)) goto final; @@ -304,7 +310,7 @@ awc_issue_command(struct awc_command * cmd){ AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: - UP(&cmd->priv->command_semaphore); + AWC_UNLOCK_COMMAND_ISSUING(cmd->priv); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ; @@ -323,7 +329,7 @@ awc_issue_command_no_ack(struct NET_DEVICE * dev, AWC_ENTRY_EXIT_DEBUG(" entry awc_issue_command_no_ack "); - DOWN(&priv->command_semaphore); + AWC_LOCK_COMMAND_ISSUING(priv); if (awc_command_busy_clear_wait(dev)) { printk("aironet4x00 no_ack command (reset) with stuck card \n"); @@ -351,11 +357,11 @@ awc_issue_command_no_ack(struct NET_DEVICE * dev, if (awc_command_busy(dev->base_addr)) awc_event_ack_ClrStckCmdBsy(dev->base_addr); - UP(&priv->command_semaphore); + AWC_UNLOCK_COMMAND_ISSUING(priv); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: - UP(&priv->command_semaphore); + AWC_UNLOCK_COMMAND_ISSUING(priv); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ; }; @@ -383,7 +389,8 @@ int awc_bap_setup(struct awc_command * cmd) { if (!cmd->bap || !(cmd->lock_state & (AWC_BAP_SEMALOCKED |AWC_BAP_LOCKED))) DEBUG(1,"no bap or bap not locked cmd %d !!", cmd->command); - + if (bap_setup_spinlock) + my_spin_lock_irqsave(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags); status = AWC_IN(cmd->bap->offset); if (status & ~0x2000 ){ @@ -412,14 +419,14 @@ int awc_bap_setup(struct awc_command * cmd) { // AWC_OUT(cmd->bap->offset, 0x800); } -// save_flags(flags); -// cli(); + save_flags(flags); + cli(); AWC_OUT(cmd->bap->select, cmd->rid); WAIT61x3; AWC_OUT(cmd->bap->offset, cmd->offset); -// restore_flags(flags); + restore_flags(flags); WAIT61x3; @@ -431,11 +438,11 @@ int awc_bap_setup(struct awc_command * cmd) { if ( cmd->priv->sleeping_bap) udelay(bap_sleep); if (cmd->priv->ejected) - return -1; + goto ejected_unlock; udelay(1); if (cycles > 10000) { printk(KERN_CRIT "deadlock in bap\n"); - return AWC_ERROR; + goto return_AWC_ERROR; }; status = AWC_IN(cmd->bap->offset); if (status & AWC_BAP_BUSY) { @@ -464,7 +471,7 @@ int awc_bap_setup(struct awc_command * cmd) { if (jiffies - jiff > 1 ) { AWC_ENTRY_EXIT_DEBUG(" BAD BUSY exit \n"); awc_dump_registers(cmd->dev); - return AWC_ERROR; + goto return_AWC_ERROR; } continue; } @@ -478,7 +485,7 @@ int awc_bap_setup(struct awc_command * cmd) { udelay(bap_sleep_after_setup); // success - return AWC_SUCCESS; + goto return_AWC_SUCCESS; } if (status & AWC_BAP_ERR) { @@ -486,7 +493,7 @@ int awc_bap_setup(struct awc_command * cmd) { // invalid rid or offset printk(KERN_ERR "bap setup error bit set for rid %x offset %x \n",cmd->rid,cmd->offset); awc_dump_registers(cmd->dev); - return AWC_ERROR; + goto return_AWC_ERROR; } if ( cmd->priv->sleeping_bap) udelay(bap_sleep); @@ -505,13 +512,31 @@ int awc_bap_setup(struct awc_command * cmd) { if (! (status &(AWC_BAP_ERR |AWC_BAP_DONE |AWC_BAP_BUSY))){ printk("aironet4500: bap setup lock without any status bits set"); awc_dump_registers(cmd->dev); - return AWC_ERROR; + goto return_AWC_ERROR; }; } - + AWC_ENTRY_EXIT_DEBUG(" WE MUST NOT BE HERE exit \n"); + +ejected_unlock: + if (bap_setup_spinlock) + my_spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags); + AWC_ENTRY_EXIT_DEBUG(" ejected_unlock_exit \n"); + return -1; + +return_AWC_ERROR: + if (bap_setup_spinlock) + my_spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags); + AWC_ENTRY_EXIT_DEBUG(" AWC_ERROR_exit \n"); + return AWC_ERROR; + +return_AWC_SUCCESS: + if (bap_setup_spinlock) + my_spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags); + AWC_ENTRY_EXIT_DEBUG(" exit \n"); + return AWC_SUCCESS; } @@ -683,15 +708,13 @@ awc_readrid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf ){ sleep_state = cmd.priv->sleeping_bap ; cmd.priv->sleeping_bap = 1; udelay(500); - if (awc_issue_command_and_block(&cmd)) goto final; AWC_BAP_LOCK_NOT_CLI(cmd); + if (awc_issue_command_and_block(&cmd)) goto final; udelay(1); if (awc_bap_setup(&cmd)) goto final; udelay(1); if (awc_bap_read(&cmd)) goto final; cmd.priv->sleeping_bap = sleep_state; - AWC_BAP_UNLOCK(cmd); - AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); @@ -728,8 +751,8 @@ awc_writerid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf){ udelay(10); cmd.command=0x121; if (awc_issue_command_and_block(&cmd)) goto final; - AWC_BAP_UNLOCK(cmd); cmd.priv->sleeping_bap = sleep_state; + AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; @@ -755,15 +778,13 @@ awc_readrid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid ){ cmd.priv->sleeping_bap = 1; udelay(500); - if (awc_issue_command_and_block(&cmd)) goto final; AWC_BAP_LOCK_NOT_CLI(cmd); + if (awc_issue_command_and_block(&cmd)) goto final; if (awc_bap_setup(&cmd)) goto final; if (awc_bap_read(&cmd)) goto final; cmd.priv->sleeping_bap = sleep_state; - AWC_BAP_UNLOCK(cmd); - AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); @@ -793,13 +814,13 @@ awc_writerid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid){ cmd.priv->sleeping_bap = 1; udelay(500); - if (awc_issue_command_and_block(&cmd)) goto final; AWC_BAP_LOCK_NOT_CLI(cmd); + + if (awc_issue_command_and_block(&cmd)) goto final; if (awc_bap_setup(&cmd)) goto final; if (awc_bap_write(&cmd)) goto final; cmd.priv->sleeping_bap = sleep_state; - AWC_BAP_UNLOCK(cmd); cmd.command=0x121; udelay(500); @@ -833,7 +854,9 @@ awc_issue_blocking_command(struct NET_DEVICE * dev,u16 comm){ AWC_ENTRY_EXIT_DEBUG(" entry awc_issue_blocking_command "); AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,comm,0, 0, 0, 0 ,0 ); - + + AWC_BAP_LOCK_NOT_CLI(cmd); + if (awc_issue_command_and_block(&cmd)) goto final; @@ -1005,6 +1028,8 @@ int awc_tx_alloc(struct NET_DEVICE * dev) { DEBUG(32,"in %x large buffers ",cmd.priv->large_buff_mem / (dev->mtu + AWC_TX_HEAD_SIZE + 8) ); k=0;tot=0; + AWC_BAP_LOCK_NOT_CLI(cmd); + while (k < cmd.priv->large_buff_mem / (dev->mtu + AWC_TX_HEAD_SIZE + 8) ) { fid = kmalloc(sizeof(struct awc_fid),GFP_KERNEL ); @@ -1097,6 +1122,8 @@ awc_tx_dealloc_fid(struct NET_DEVICE * dev,struct awc_fid * fid){ AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x0C,0, 0,0,0,NULL); + AWC_BAP_LOCK_NOT_CLI(cmd); + if (fid->u.tx.fid){ fid_handle = cmd.par0 = fid->u.tx.fid; fid->u.tx.fid = 0; @@ -1959,7 +1986,7 @@ awc_receive_packet(struct NET_DEVICE * dev){ DEBUG(128, "rx payload read %x \n",rx_buff->u.rx.ieee_802_3.payload_length); }; - AWC_BAP_UNLOCK(cmd); + AWC_RELEASE_COMMAND(cmd); DEBUG(128,"\n payload hdr %x ",rx_buff->u.rx.ieee_802_3.status ); if (awc_debug && rx_buff->u.rx.payload) @@ -1968,8 +1995,6 @@ awc_receive_packet(struct NET_DEVICE * dev){ awc_802_11_router_rx(dev,rx_buff); - AWC_RELEASE_COMMAND(cmd); -// awc_event_ack_Rx(dev->base_addr); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: @@ -1977,7 +2002,6 @@ awc_receive_packet(struct NET_DEVICE * dev){ awc_802_11_failed_rx_copy(dev,rx_buff); // if (skb) dev_kfree_skb(skb, FREE_WRITE); AWC_RELEASE_COMMAND(cmd); -// awc_event_ack_Rx(dev->base_addr); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ; @@ -2089,27 +2113,31 @@ awc_transmit_packet(struct NET_DEVICE * dev, struct awc_fid * tx_buff) { cmd.len = tx_buff->pkt_len; if (awc_bap_write(&cmd)) goto final; + AWC_RELEASE_COMMAND(cmd); +// locking probs, these two lines below and above, swithc order + if (awc_issue_command_and_block(&cmd)) goto final_unlocked; - - AWC_BAP_UNLOCK(cmd); - if (awc_issue_command_and_block(&cmd)) goto final; -// if (awc_issue_command(&cmd)) goto final; tx_buff->transmit_start_time = jiffies; awc_802_11_after_tx_packet_to_card_write(dev,tx_buff); // issue the transmit command - AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: - awc_802_11_after_failed_tx_packet_to_card_write(dev,tx_buff); - + awc_802_11_after_failed_tx_packet_to_card_write(dev,tx_buff); printk(KERN_CRIT "%s awc tx command failed \n",dev->name); AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ; + + final_unlocked: + awc_802_11_after_failed_tx_packet_to_card_write(dev,tx_buff); + printk(KERN_CRIT "%s awc tx command failed \n",dev->name); + AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); + return -1; ; + } @@ -2141,12 +2169,11 @@ awc_tx_complete_check(struct NET_DEVICE * dev){ AWC_BAP_LOCK_NOT_CLI(cmd); if (awc_bap_setup(&cmd)) goto final; if (awc_bap_read(&cmd)) goto final; - AWC_BAP_UNLOCK(cmd); + AWC_RELEASE_COMMAND(cmd); awc_802_11_after_tx_complete(dev,fid); - AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; @@ -2202,7 +2229,7 @@ start: dev->start = 0; if (priv->command_semaphore_on){ priv->command_semaphore_on--; - UP(&priv->command_semaphore); + AWC_UNLOCK_COMMAND_ISSUING(priv); } priv->tx_chain_active =0; goto bad_end; @@ -2219,7 +2246,7 @@ start: if (priv->command_semaphore_on){ priv->command_semaphore_on--; - UP(&priv->command_semaphore); + AWC_UNLOCK_COMMAND_ISSUING(priv); } } }; @@ -2269,10 +2296,10 @@ awc_interrupt_process(struct NET_DEVICE * dev){ // u16 ints_to_ack =0; struct awc_fid * fid = NULL; // int interrupt_reenter = 0; - unsigned long flags; +// unsigned long flags; - save_flags(flags); - cli(); +// save_flags(flags); +// cli(); // disable_irq(dev->irq); DEBUG(2," entering interrupt handler %s ",dev->name); @@ -2420,6 +2447,7 @@ start: printk(KERN_ERR "No tx fid when tx int active\n"); fid = awc_tx_fid_lookup_and_remove(dev, tx_fid); + if (fid) { if (priv->process_tx_results) { awc_fid_queue_push_tail(&priv->tx_post_process,fid); @@ -2491,21 +2519,21 @@ start: //end_here: // enable_irq(dev->irq); - restore_flags(flags); +// restore_flags(flags); return 0; reenter_end_here: AWC_ENTRY_EXIT_DEBUG(" reenter-bad end exit \n"); // enable_irq(dev->irq); - restore_flags(flags); +// restore_flags(flags); return 0; bad_end: dev->interrupt = 0; AWC_ENTRY_EXIT_DEBUG(" bad_end exit \n"); // enable_irq(dev->irq); - restore_flags(flags); +// restore_flags(flags); return -1; @@ -2516,7 +2544,7 @@ static const char *aironet4500_core_version = struct NET_DEVICE * aironet4500_devices[MAX_AWCS] = {NULL,NULL,NULL,NULL}; -static int awc_debug = 0; // 0xffffff; +static int awc_debug = 0; // 0xffffff; static int p802_11_send = 0; // 1 static int awc_process_tx_results = 0; @@ -2632,8 +2660,15 @@ char name[] = "ElmerLinux"; DEBUG(2, "%s: awc_init \n", dev->name); - - + /* both_bap_lock decreases performance about 15% + * but without it card gets screwed up + */ +#ifdef CONFIG_SMP + if(smp_num_cpus > 1){ + both_bap_lock = 1; + bap_setup_spinlock = 1; + } +#endif //awc_dump_registers(dev); if (adhoc & !max_mtu) @@ -2749,7 +2784,7 @@ char name[] = "ElmerLinux"; // here we go, bad aironet memset(&priv->SSIDs,0,sizeof(priv->SSIDs)); - memset(&priv->queues_lock,0,sizeof(priv->queues_lock)); + my_spin_lock_init(&priv->queues_lock); priv->SSIDs.ridLen =0; if (!SSID) { @@ -2807,21 +2842,29 @@ int awc_private_init(struct NET_DEVICE * dev){ memset(priv, 0, sizeof(struct awc_private)); + my_spin_lock_init(&priv->queues_lock); + priv->bap0.select = dev->base_addr + awc_Select0_register; priv->bap0.offset = dev->base_addr + awc_Offset0_register; priv->bap0.data = dev->base_addr + awc_Data0_register; priv->bap0.lock = 0; priv->bap0.status = 0; + my_spin_lock_init(&priv->bap0.spinlock); init_MUTEX(&priv->bap0.sem); priv->bap1.select = dev->base_addr + awc_Select1_register; priv->bap1.offset = dev->base_addr + awc_Offset1_register; priv->bap1.data = dev->base_addr + awc_Data1_register; priv->bap1.lock = 0; priv->bap1.status = 0; + my_spin_lock_init(&priv->bap1.spinlock); init_MUTEX(&priv->bap1.sem); priv->sleeping_bap = 1; - init_MUTEX(&priv->command_semaphore); +//spinlock now init_MUTEX(&priv->command_semaphore); + my_spin_lock_init(&priv->command_issuing_spinlock); + my_spin_lock_init(&priv->both_bap_spinlock); + my_spin_lock_init(&priv->bap_setup_spinlock); + priv->command_semaphore_on = 0; priv->unlock_command_postponed = 0; priv->immediate_bh.next = NULL; @@ -2927,11 +2970,11 @@ int awc_private_init(struct NET_DEVICE * dev){ udelay(10000); - DOWN(&priv->command_semaphore); + AWC_LOCK_COMMAND_ISSUING(priv); MOD_DEC_USE_COUNT; - UP(&priv->command_semaphore); + AWC_UNLOCK_COMMAND_ISSUING(priv); return 0; } @@ -2965,7 +3008,7 @@ int direction = 1; struct awc_private *priv = (struct awc_private *)dev->priv; int retval = 0; - unsigned long flags; +// unsigned long flags; struct awc_fid * fid = NULL; int cnt=0; @@ -2980,8 +3023,8 @@ int direction = 1; /* Transmitter timeout, serious problems. */ if (test_and_set_bit( 0, (void *) &dev->tbusy) ) { if (jiffies - dev->trans_start > 3* HZ ){ - save_flags(flags); - cli(); + // save_flags(flags); + // cli(); fid = priv->tx_in_transmit.head; cnt = 0; while (fid){ @@ -2998,12 +3041,12 @@ int direction = 1; fid = fid->next; if (cnt++ > 200) { printk("bbb in awc_fid_queue\n"); - restore_flags(flags); + // restore_flags(flags); return -1; }; } - restore_flags(flags); + //restore_flags(flags); //debug =0x8; }; if (jiffies - dev->trans_start >= (5* HZ) ) { @@ -3092,7 +3135,7 @@ int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { struct enet_statistics *awc_get_stats(struct NET_DEVICE *dev) { struct awc_private *priv = (struct awc_private *)dev->priv; - unsigned long flags; +// unsigned long flags; // int cnt = 0; // int unlocked_stats_in_interrupt=0; @@ -3101,11 +3144,11 @@ int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { if (!dev->start) { return 0; } - save_flags(flags); - cli(); +// save_flags(flags); +// cli(); if (awc_full_stats) awc_readrid_dir(dev, &priv->rid_dir[9]); - restore_flags(flags); +// restore_flags(flags); // the very following is the very wrong very probably if (awc_full_stats){ @@ -3134,7 +3177,7 @@ int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { int awc_change_mtu(struct NET_DEVICE *dev, int new_mtu){ // struct awc_private *priv = (struct awc_private *)dev->priv; - unsigned long flags; +// unsigned long flags; if ((new_mtu < 256 ) || (new_mtu > 2312) || (max_mtu && new_mtu > max_mtu) ) return -EINVAL; @@ -3144,14 +3187,14 @@ int awc_change_mtu(struct NET_DEVICE *dev, int new_mtu){ }; if (dev->mtu != new_mtu) { - save_flags(flags); - cli(); +// save_flags(flags); +// cli(); awc_disable_MAC(dev); awc_tx_dealloc(dev); dev->mtu = new_mtu; awc_tx_alloc(dev); awc_enable_MAC(dev); - restore_flags(flags); +// restore_flags(flags); printk("%s mtu has been changed to %d \n ",dev->name,dev->mtu); @@ -3208,7 +3251,7 @@ int init_module(void) { // unsigned long flags; -// debug = awc_debug; + printk(KERN_INFO"%s", aironet4500_core_version); return 0; diff --git a/drivers/net/aironet4500_proc.c b/drivers/net/aironet4500_proc.c index 756f7266f6f2..2b28f1a63adf 100644 --- a/drivers/net/aironet4500_proc.c +++ b/drivers/net/aironet4500_proc.c @@ -2,7 +2,7 @@ * Aironet 4500 Pcmcia driver * * Elmer Joandi, Januar 1999 - * Copyright Elmer Joandi, all rights restricted + * Copyright GPL * * * Revision 0.1 ,started 30.12.1998 @@ -379,6 +379,8 @@ ctl_table awc_driver_proc_table[] = { {4, "sleep_before_command" , &sleep_before_command, sizeof(sleep_before_command), 0600,NULL, proc_dointvec}, {5, "bap_sleep_before_write" , &bap_sleep_before_write, sizeof(bap_sleep_before_write), 0600,NULL, proc_dointvec}, {6, "sleep_in_command" , &sleep_in_command , sizeof(sleep_in_command), 0600,NULL, proc_dointvec}, + {7, "both_bap_lock" , &both_bap_lock , sizeof(both_bap_lock), 0600,NULL, proc_dointvec}, + {8, "bap_setup_spinlock" , &bap_setup_spinlock , sizeof(bap_setup_spinlock), 0600,NULL, proc_dointvec}, {0} }; diff --git a/drivers/net/arlan-proc.c b/drivers/net/arlan-proc.c index 83ac209e8946..2832171929e3 100644 --- a/drivers/net/arlan-proc.c +++ b/drivers/net/arlan-proc.c @@ -11,7 +11,6 @@ /* void enableReceive(struct net_device* dev); */ -static int arlan_command(struct net_device * dev, int command); #define ARLAN_STR_SIZE 0x2ff0 @@ -186,7 +185,7 @@ static const char *arlan_hardware_type_string(struct net_device *dev) return "type A672T"; } } - +#ifdef ARLAN_DEBUGING static void arlan_print_diagnostic_info(struct net_device *dev) { int i; @@ -320,7 +319,6 @@ static int arlan_hw_test_memory(struct net_device *dev) return 0; } - static int arlan_setup_card_by_book(struct net_device *dev) { u_char irqLevel, configuredStatusFlag; @@ -396,7 +394,7 @@ static int arlan_setup_card_by_book(struct net_device *dev) return 0; /* no errors */ } - +#endif #ifdef ARLAN_PROC_INTERFACE #ifdef ARLAN_PROC_SHM_DUMP @@ -820,7 +818,15 @@ int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp, #define CTBLN(num,card,nam) \ {num , #nam, &(arlan_conf[card].nam), \ sizeof(int), 0600, NULL, &proc_dointvec} +#ifdef ARLAN_DEBUGING +#define ARLAN_PROC_DEBUG_ENTRIES {48, "entry_exit_debug", &arlan_entry_and_exit_debug, \ + sizeof(int), 0600, NULL, &proc_dointvec},\ + {49, "debug", &arlan_debug, \ + sizeof(int), 0600, NULL, &proc_dointvec}, +#else +#define ARLAN_PROC_DEBUG_ENTRIES +#endif #define ARLAN_SYSCTL_TABLE_TOTAL(cardNo)\ CTBLN(1,cardNo,spreadingCode),\ @@ -871,10 +877,7 @@ int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp, CTBLN(45,cardNo,radioType),\ CTBLN(46,cardNo,writeEEPROM),\ CTBLN(47,cardNo,writeRadioType),\ - {48, "entry_exit_debug", &arlan_entry_and_exit_debug, \ - sizeof(int), 0600, NULL, &proc_dointvec},\ - {49, "debug", &arlan_debug, \ - sizeof(int), 0600, NULL, &proc_dointvec},\ + ARLAN_PROC_DEBUG_ENTRIES\ CTBLN(50,cardNo,in_speed),\ CTBLN(51,cardNo,out_speed),\ CTBLN(52,cardNo,in_speed10),\ @@ -1010,7 +1013,8 @@ static ctl_table arlan_table[MAX_ARLANS + 1] = }; #endif -static int mmtu = 1234; + +// static int mmtu = 1234; static ctl_table arlan_root_table[] = { @@ -1019,11 +1023,11 @@ static ctl_table arlan_root_table[] = }; /* Make sure that /proc/sys/dev is there */ -static ctl_table arlan_device_root_table[] = -{ - {CTL_DEV, "dev", NULL, 0, 0555, arlan_root_table}, - {0} -}; +//static ctl_table arlan_device_root_table[] = +//{ +// {CTL_DEV, "dev", NULL, 0, 0555, arlan_root_table}, +// {0} +//}; diff --git a/drivers/net/arlan.c b/drivers/net/arlan.c index 5ccad60a999e..d2a02efcb8dc 100644 --- a/drivers/net/arlan.c +++ b/drivers/net/arlan.c @@ -17,28 +17,32 @@ static int SID = SIDUNKNOWN; static int radioNodeId = radioNodeIdUNKNOWN; static char encryptionKey[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; static char *siteName = siteNameUNKNOWN; -static int irq = irqUNKNOWN; static int mem = memUNKNOWN; -static int arlan_debug = debugUNKNOWN; +int arlan_debug = debugUNKNOWN; static int probe = probeUNKNOWN; static int numDevices = numDevicesUNKNOWN; -static int testMemory = testMemoryUNKNOWN; static int spreadingCode = spreadingCodeUNKNOWN; static int channelNumber = channelNumberUNKNOWN; static int channelSet = channelSetUNKNOWN; static int systemId = systemIdUNKNOWN; static int registrationMode = registrationModeUNKNOWN; -static int txScrambled = 1; static int keyStart = 0; -static int mdebug = 0; static int tx_delay_ms = 0; static int retries = 5; static int async = 1; static int tx_queue_len = 1; +static int arlan_EEPROM_bad = 0; +int arlan_entry_and_exit_debug = 0; + +#ifdef ARLAN_DEBUGING + static int arlan_entry_debug = 0; static int arlan_exit_debug = 0; -static int arlan_entry_and_exit_debug = 0; -static int arlan_EEPROM_bad = 0; +static int testMemory = testMemoryUNKNOWN; +static int irq = irqUNKNOWN; +static int txScrambled = 1; +static int mdebug = 0; +#endif #if LINUX_VERSION_CODE > 0x20100 MODULE_PARM(irq, "i"); @@ -336,11 +340,15 @@ int arlan_command(struct net_device *dev, int command_p) } else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) { + priv->under_reset=1; + dev->tbusy = 1; + arlan_drop_tx(dev); if (priv->tx_command_given || priv->rx_command_given) { printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); }; + dev->tbusy = 1; if (arlan_debug & ARLAN_DEBUG_RESET) printk(KERN_ERR "%s: Doing chip reset\n", dev->name); priv->lastReset = jiffies; @@ -398,15 +406,10 @@ int arlan_command(struct net_device *dev, int command_p) { priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF_WAIT; priv->waiting_command_mask |= ARLAN_COMMAND_RX; + priv->waiting_command_mask |= ARLAN_COMMAND_TBUSY_CLEAR; priv->card_polling_interval = HZ / 10; priv->tx_command_given = 0; priv->under_config = 0; - if (dev->tbusy || !dev->start) - { - dev->tbusy = 0; - dev->start = 1; - mark_bh(NET_BH); - }; } else { @@ -424,7 +427,7 @@ int arlan_command(struct net_device *dev, int command_p) WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_RX_ENABLE); WRITESHMB(arlan->commandParameter[0], conf->rxParameter); arlan_interrupt_lancpu(dev); - priv->rx_command_given; + priv->rx_command_given = 0; // mnjah, bad priv->last_rx_time = arlan_time(); priv->waiting_command_mask &= ~ARLAN_COMMAND_RX; priv->card_polling_interval = 1; @@ -432,6 +435,17 @@ int arlan_command(struct net_device *dev, int command_p) else priv->card_polling_interval = 2; } + else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR) + { + if ( !registrationBad(dev) && (dev->tbusy || !dev->start) ) + { + priv->waiting_command_mask &= ~ARLAN_COMMAND_TBUSY_CLEAR; + + dev->tbusy = 0; + dev->start = 1; + mark_bh(NET_BH); + }; + } else if (priv->waiting_command_mask & ARLAN_COMMAND_TX) { if (!test_and_set_bit(0, (void *) &priv->tx_command_given)) @@ -692,7 +706,7 @@ static void arlan_registration_timer(unsigned long data) } - +#ifdef ARLAN_DEBUGING static void arlan_print_registers(struct net_device *dev, int line) { @@ -718,6 +732,7 @@ static void arlan_print_registers(struct net_device *dev, int line) ARLAN_DEBUG_EXIT("arlan_print_registers"); } +#endif static int arlan_hw_tx(struct net_device *dev, char *buf, int length) @@ -1039,12 +1054,18 @@ static int __init arlan_check_fingerprint(int memaddr) volatile struct arlan_shmem *arlan = (struct arlan_shmem *) memaddr; ARLAN_DEBUG_ENTRY("arlan_check_fingerprint"); + if (check_mem_region(virt_to_phys((void *)memaddr),0x2000 )){ + // printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",virt_to_phys((void*)memaddr)); + return -ENODEV; + }; memcpy_fromio(tempBuf, arlan->textRegion, 29); tempBuf[30] = 0; /* check for card at this address */ - if (0 != strncmp(tempBuf, probeText, 29)) + if (0 != strncmp(tempBuf, probeText, 29)){ +// not release_mem_region(virt_to_phys((void*)memaddr),0x2000); return -ENODEV; + } // printk(KERN_INFO "arlan found at 0x%x \n",memaddr); ARLAN_DEBUG_EXIT("arlan_check_fingerprint"); @@ -1063,17 +1084,17 @@ int __init arlan_probe_everywhere(struct net_device *dev) ARLAN_DEBUG_ENTRY("arlan_probe_everywhere"); if (mem != 0 && numDevices == 1) /* Check a single specified location. */ { - if (arlan_probe_here(dev, mem) == 0) + if (arlan_probe_here(dev, (int) phys_to_virt( mem) ) == 0) return 0; else return -ENODEV; } - for (m = lastFoundAt + 0x2000; m <= 0xDE000; m += 0x2000) + for (m = (int)phys_to_virt(lastFoundAt) + 0x2000; m <= (int)phys_to_virt(0xDE000); m += 0x2000) { if (arlan_probe_here(dev, m) == 0) { found++; - lastFoundAt = m; + lastFoundAt = (int)virt_to_phys((void*)m); break; } probed++; @@ -1100,7 +1121,7 @@ int __init arlan_find_devices(void) ARLAN_DEBUG_ENTRY("arlan_find_devices"); if (mem != 0 && numDevices == 1) /* Check a single specified location. */ return 1; - for (m = 0xc000; m <= 0xDE000; m += 0x2000) + for (m =(int) phys_to_virt(0xc0000); m <=(int) phys_to_virt(0xDE000); m += 0x2000) { if (arlan_check_fingerprint(m) == 0) found++; @@ -1172,6 +1193,9 @@ static int __init printk(KERN_CRIT "init_etherdev failed "); return 0; } + + memset(dev->priv,0,sizeof(struct arlan_private)); + ((struct arlan_private *) dev->priv)->conf = kmalloc(sizeof(struct arlan_shmem), GFP_KERNEL); @@ -1199,6 +1223,9 @@ static int __init dev->set_multicast_list = arlan_set_multicast; dev->change_mtu = arlan_change_mtu; dev->set_mac_address = arlan_mac_addr; + dev->tbusy = 1; + dev->start = 0; + ((struct arlan_private *) dev->priv)->irq_test_done = 0; arlan_device[num] = dev; ((struct arlan_private *) arlan_device[num]->priv)->Conf = &(arlan_conf[num]); @@ -1221,7 +1248,7 @@ int __init arlan_probe_here(struct net_device *dev, int memaddr) if (arlan_check_fingerprint(memaddr)) return -ENODEV; - printk(KERN_NOTICE "%s: Arlan found at %#5x, \n ", dev->name, memaddr); + printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name, (int) virt_to_phys((void*)memaddr)); if (!arlan_allocate_device(arlans_found, dev)) return -1; @@ -1261,14 +1288,13 @@ static int arlan_open(struct net_device *dev) return ret; arlan = ((struct arlan_private *) dev->priv)->card; - if (request_irq(dev->irq, &arlan_interrupt, 0, dev->name, dev)) { printk(KERN_ERR "%s: unable to get IRQ %d .\n", dev->name, dev->irq); return -EAGAIN; } - arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW); + priv->bad = 0; priv->lastReset = 0; @@ -1279,15 +1305,10 @@ static int arlan_open(struct net_device *dev) dev->tbusy = 1; priv->txOffset = 0; dev->interrupt = 0; - dev->start = 1; + dev->start = 0; dev->tx_queue_len = tx_queue_len; - init_timer(&priv->timer); - priv->timer.expires = jiffies + HZ / 10; - priv->timer.data = (unsigned long) dev; - priv->timer.function = &arlan_registration_timer; /* timer handler */ priv->interrupt_processing_active = 0; priv->command_lock = 0; - add_timer(&priv->timer); init_MUTEX(&priv->card_lock); myATOMIC_INIT(priv->card_users, 1); /* damn 2.0.33 */ @@ -1295,7 +1316,8 @@ static int arlan_open(struct net_device *dev) priv->registrationLastSeen = jiffies; priv->txLast = 0; priv->tx_command_given = 0; - + priv->rx_command_given = 0; + priv->reRegisterExp = 1; priv->nof_tx = 0; priv->nof_tx_ack = 0; @@ -1306,6 +1328,16 @@ static int arlan_open(struct net_device *dev) priv->Conf->registrationInterrupts = 1; dev->tbusy = 0; + init_timer(&priv->timer); + priv->timer.expires = jiffies + HZ / 10; + priv->timer.data = (unsigned long) dev; + priv->timer.function = &arlan_registration_timer; /* timer handler */ + + arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW); + udelay(200000); + dev->tbusy = 0; + dev->start = 1; + add_timer(&priv->timer); MOD_INC_USE_COUNT; #ifdef CONFIG_PROC_FS @@ -1898,29 +1930,31 @@ static int arlan_close(struct net_device *dev) } ARLAN_DEBUG_ENTRY("arlan_close"); + del_timer(&priv->timer); + + arlan_command(dev, ARLAN_COMMAND_POWERDOWN); + IFDEBUG(ARLAN_DEBUG_STARTUP) printk(KERN_NOTICE "%s: Closing device\n", dev->name); priv->open_time = 0; dev->tbusy = 1; dev->start = 0; - del_timer(&priv->timer); free_irq(dev->irq, dev); - MOD_DEC_USE_COUNT; ARLAN_DEBUG_EXIT("arlan_close"); return 0; } - +#ifdef ARLAN_DEBUGING static long alignLong(volatile u_char * ptr) { long ret; memcpy_fromio(&ret, (void *) ptr, 4); return ret; } - +#endif /* * Get the current statistics. @@ -2041,6 +2075,7 @@ int init_module(void) } if (probe) arlan_probe_everywhere(arlan_device[i]); +// arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN ); } printk(KERN_INFO "Arlan driver %s\n", arlan_version); ARLAN_DEBUG_EXIT("init_module"); @@ -2060,6 +2095,9 @@ void cleanup_module(void) { if (arlan_device[i]) { + arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN ); + +// release_mem_region(virt_to_phys(arlan_device[i]->mem_start), 0x2000 ); unregister_netdev(arlan_device[i]); if (arlan_device[i]->priv) { diff --git a/drivers/net/arlan.h b/drivers/net/arlan.h index 869c8bebd4b2..83208e4e347d 100644 --- a/drivers/net/arlan.h +++ b/drivers/net/arlan.h @@ -29,7 +29,7 @@ #include -#define DEBUG 1 +//#define ARLAN_DEBUGING 1 #define ARLAN_PROC_INTERFACE #define MAX_ARLANS 4 /* not more than 4 ! */ @@ -46,13 +46,14 @@ extern int init_arlan_proc(void); #endif extern struct net_device *arlan_device[MAX_ARLANS]; -static int arlan_debug; -static char * siteName; -static int arlan_entry_debug; -static int arlan_exit_debug; -static int arlan_entry_and_exit_debug; -static int testMemory; -static const char* arlan_version; +extern int arlan_debug; +extern char * siteName; +extern int arlan_entry_debug; +extern int arlan_exit_debug; +extern int arlan_entry_and_exit_debug; +extern int testMemory; +extern const char* arlan_version; +extern int arlan_command(struct net_device * dev, int command); #define SIDUNKNOWN -1 #define radioNodeIdUNKNOWN -1 @@ -75,7 +76,8 @@ static const char* arlan_version; #define IFDEBUG( L ) if ( (L) & arlan_debug ) #define ARLAN_FAKE_HDR_LEN 12 -#ifdef DEBUG +#ifdef ARLAN_DEBUGING + #define DEBUG 1 #define ARLAN_ENTRY_EXIT_DEBUGING 1 #define ARLAN_DEBUG(a,b) printk(KERN_DEBUG a, b) #else @@ -532,26 +534,27 @@ struct arlan_private { -#define ARLAN_COMMAND_RX 0x00001 -#define ARLAN_COMMAND_NOOP 0x00002 -#define ARLAN_COMMAND_NOOPINT 0x00004 -#define ARLAN_COMMAND_TX 0x00008 -#define ARLAN_COMMAND_CONF 0x00010 -#define ARLAN_COMMAND_RESET 0x00020 -#define ARLAN_COMMAND_TX_ABORT 0x00040 -#define ARLAN_COMMAND_RX_ABORT 0x00080 -#define ARLAN_COMMAND_POWERDOWN 0x00100 -#define ARLAN_COMMAND_POWERUP 0x00200 -#define ARLAN_COMMAND_SLOW_POLL 0x00400 -#define ARLAN_COMMAND_ACTIVATE 0x00800 -#define ARLAN_COMMAND_INT_ACK 0x01000 -#define ARLAN_COMMAND_INT_ENABLE 0x02000 -#define ARLAN_COMMAND_WAIT_NOW 0x04000 -#define ARLAN_COMMAND_LONG_WAIT_NOW 0x08000 -#define ARLAN_COMMAND_STANDBY 0x10000 -#define ARLAN_COMMAND_INT_RACK 0x20000 -#define ARLAN_COMMAND_INT_RENABLE 0x40000 -#define ARLAN_COMMAND_CONF_WAIT 0x80000 +#define ARLAN_COMMAND_RX 0x000001 +#define ARLAN_COMMAND_NOOP 0x000002 +#define ARLAN_COMMAND_NOOPINT 0x000004 +#define ARLAN_COMMAND_TX 0x000008 +#define ARLAN_COMMAND_CONF 0x000010 +#define ARLAN_COMMAND_RESET 0x000020 +#define ARLAN_COMMAND_TX_ABORT 0x000040 +#define ARLAN_COMMAND_RX_ABORT 0x000080 +#define ARLAN_COMMAND_POWERDOWN 0x000100 +#define ARLAN_COMMAND_POWERUP 0x000200 +#define ARLAN_COMMAND_SLOW_POLL 0x000400 +#define ARLAN_COMMAND_ACTIVATE 0x000800 +#define ARLAN_COMMAND_INT_ACK 0x001000 +#define ARLAN_COMMAND_INT_ENABLE 0x002000 +#define ARLAN_COMMAND_WAIT_NOW 0x004000 +#define ARLAN_COMMAND_LONG_WAIT_NOW 0x008000 +#define ARLAN_COMMAND_STANDBY 0x010000 +#define ARLAN_COMMAND_INT_RACK 0x020000 +#define ARLAN_COMMAND_INT_RENABLE 0x040000 +#define ARLAN_COMMAND_CONF_WAIT 0x080000 +#define ARLAN_COMMAND_TBUSY_CLEAR 0x100000 #define ARLAN_COMMAND_CLEAN_AND_CONF (ARLAN_COMMAND_TX_ABORT\ | ARLAN_COMMAND_RX_ABORT\ | ARLAN_COMMAND_CONF) diff --git a/drivers/net/pcmcia/Config.in b/drivers/net/pcmcia/Config.in index 2ccfd28b89d9..dddb451096a4 100644 --- a/drivers/net/pcmcia/Config.in +++ b/drivers/net/pcmcia/Config.in @@ -22,9 +22,12 @@ if [ "$CONFIG_NET_PCMCIA" = "y" ]; then dep_tristate ' SMC EPIC CardBus support' CONFIG_PCMCIA_EPIC100 m fi - 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 + 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 + fi fi if [ "$CONFIG_PCMCIA_3C589" = "y" -o "$CONFIG_PCMCIA_3C574" = "y" -o \ diff --git a/drivers/net/pcmcia/netwave_cs.c b/drivers/net/pcmcia/netwave_cs.c index 8e837ffc76a3..6ca0ce297d7e 100644 --- a/drivers/net/pcmcia/netwave_cs.c +++ b/drivers/net/pcmcia/netwave_cs.c @@ -61,9 +61,9 @@ #include #include -#ifdef CONFIG_NET_RADIO +#ifdef CONFIG_NET_PCMCIA_RADIO #include -#endif +#endif /* CONFIG_NET_PCMCIA_RADIO */ #include #include diff --git a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c index 20d44ecc2b62..c282db8d95ef 100644 --- a/drivers/net/pcmcia/ray_cs.c +++ b/drivers/net/pcmcia/ray_cs.c @@ -51,18 +51,16 @@ #include #include -#ifdef HAS_WIRELESS_EXTENSIONS +#ifdef CONFIG_NET_PCMCIA_RADIO #include -#if WIRELESS_EXT < 8 -#warning "Wireless extension v8 or newer required" -#endif /* WIRELESS_EXT < 8 */ + /* Warning : these stuff will slow down the driver... */ #define WIRELESS_SPY /* Enable spying addresses */ /* Definitions we need for spy */ typedef struct iw_statistics iw_stats; typedef struct iw_quality iw_qual; typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ -#endif /* HAS_WIRELESS_EXTENSIONS */ +#endif /* CONFIG_NET_PCMCIA_RADIO */ #include "rayctl.h" #include "ray_cs.h" @@ -109,7 +107,7 @@ static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_typ unsigned char *data); static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); #if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ -static iw_stats * ray_get_wireless_stats(struct device * dev); +static iw_stats * ray_get_wireless_stats(struct net_device * dev); #endif /* WIRELESS_EXT > 7 */ /***** Prototypes for raylink functions **************************************/ @@ -213,7 +211,7 @@ static dev_link_t *dev_list = NULL; 'priv' pointer in a dev_link_t structure can be used to point to a device-specific private data structure, like this. */ -static unsigned int ray_mem_speed = 0x2A; +static unsigned int ray_mem_speed = 500; MODULE_AUTHOR("Corey Thomas "); MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver"); @@ -543,8 +541,7 @@ static void ray_config(dev_link_t *link) req.Base = 0; req.Size = 0x8000; req.AccessSpeed = ray_mem_speed; - link->win = (window_handle_t)link->handle; - CS_CHECK(pcmcia_request_window, &link->win, &req); + CS_CHECK(pcmcia_request_window, &link->handle, &req, &link->win); mem.CardOffset = 0x0000; mem.Page = 0; CS_CHECK(pcmcia_map_mem_page, link->win, &mem); local->sram = (UCHAR *)(ioremap(req.Base,req.Size)); @@ -554,8 +551,7 @@ static void ray_config(dev_link_t *link) req.Base = 0; req.Size = 0x4000; req.AccessSpeed = ray_mem_speed; - local->rmem_handle = (window_handle_t)link->handle; - CS_CHECK(pcmcia_request_window, &local->rmem_handle, &req); + CS_CHECK(pcmcia_request_window, &link->handle, &req, &local->rmem_handle); mem.CardOffset = 0x8000; mem.Page = 0; CS_CHECK(pcmcia_map_mem_page, local->rmem_handle, &mem); local->rmem = (UCHAR *)(ioremap(req.Base,req.Size)); @@ -565,8 +561,7 @@ static void ray_config(dev_link_t *link) req.Base = 0; req.Size = 0x1000; req.AccessSpeed = ray_mem_speed; - local->amem_handle = (window_handle_t)link->handle; - CS_CHECK(pcmcia_request_window, &local->amem_handle, &req); + CS_CHECK(pcmcia_request_window, &link->handle, &req, &local->amem_handle); mem.CardOffset = 0x0000; mem.Page = 0; CS_CHECK(pcmcia_map_mem_page, local->amem_handle, &mem); local->amem = (UCHAR *)(ioremap(req.Base,req.Size)); @@ -1471,7 +1466,7 @@ static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } /* end ray_dev_ioctl */ /*===========================================================================*/ #if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ -static iw_stats * ray_get_wireless_stats(struct device * dev) +static iw_stats * ray_get_wireless_stats(struct net_device * dev) { ray_dev_t * local = (ray_dev_t *) dev->priv; dev_link_t *link = local->finder; @@ -1848,7 +1843,7 @@ static void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) UCHAR cmd; UCHAR status; - if ((dev == NULL) || !dev->start) + if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */ return; DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev); @@ -2094,7 +2089,7 @@ static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_a int total_len; int tmp; #ifdef WIRELESS_SPY - int siglev = prcs->var.rx_packet.rx_sig_lev; + int siglev = local->last_rsl; u_char linksrcaddr[ETH_ALEN]; /* Other end of the wireless link */ #endif diff --git a/drivers/net/pcmcia/wavelan_cs.h b/drivers/net/pcmcia/wavelan_cs.h index 314b5f3832c8..0f5be4f37423 100644 --- a/drivers/net/pcmcia/wavelan_cs.h +++ b/drivers/net/pcmcia/wavelan_cs.h @@ -382,9 +382,9 @@ #include #include -#ifdef CONFIG_NET_RADIO +#ifdef CONFIG_NET_PCMCIA_RADIO #include /* Wireless extensions */ -#endif +#endif /* CONFIG_NET_PCMCIA_RADIO */ /* Pcmcia headers that we need */ #include diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 00ae312fa9b1..7e260fb2c2db 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -34,6 +34,11 @@ * * Torben Mathiasen New Maintainer! * + * v1.1 Dec 20 -- Removed linux version checking(patch from + * Tigran Aivazian). v1.1 includes Alan's SMP + * opdates. We still have problems on SMP though, + * but I'm looking into that. + * ********************************************************************/ @@ -76,7 +81,7 @@ static int bbuf = 0; static u8 *TLanPadBuffer; static char TLanSignature[] = "TLAN"; static int TLanVersionMajor = 1; -static int TLanVersionMinor = 0; +static int TLanVersionMinor = 1; static TLanAdapterEntry TLanAdapterList[] = { @@ -1136,9 +1141,7 @@ u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) printk( "TLAN: Received interrupt for uncompleted TX frame.\n" ); } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) priv->stats.tx_bytes += head_list->frameSize; -#endif head_list->cStat = TLAN_CSTAT_UNUSED; dev->tbusy = 0; @@ -1256,9 +1259,7 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) skb_reserve( skb, 2 ); t = (void *) skb_put( skb, head_list->frameSize ); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) priv->stats.rx_bytes += head_list->frameSize; -#endif memcpy( t, head_buffer, head_list->frameSize ); skb->protocol = eth_type_trans( skb, dev ); @@ -1280,9 +1281,8 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) skb = (struct sk_buff *) head_list->buffer[9].address; head_list->buffer[9].address = 0; skb_trim( skb, head_list->frameSize ); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) + priv->stats.rx_bytes += head_list->frameSize; -#endif skb->protocol = eth_type_trans( skb, dev ); netif_rx( skb ); @@ -2447,7 +2447,6 @@ int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val ) int err; int minten; TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv; - int irq; unsigned long flags; err = FALSE; diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h index 4ae1cf278974..978c208d5393 100644 --- a/drivers/net/tlan.h +++ b/drivers/net/tlan.h @@ -25,11 +25,6 @@ #include #include -#if LINUX_VERSION_CODE <= 0x20100 -#define net_device_stats enet_statistics -#endif - - /***************************************************************** diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index a48c5d31ce49..81f77856b05e 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -118,6 +118,7 @@ typedef struct wait_queue *wait_queue_head_t; /* Per-channel data structure */ struct channel_data { + void *if_ptr; /* General purpose pointer (used by SPPP) */ int usage; /* Usage count; >0 for chrdev, -1 for netdev */ int num; /* Number of the channel */ struct cosa_data *cosa; /* Pointer to the per-card structure */ @@ -577,8 +578,10 @@ bad1: release_region(cosa->datareg,is_8bit(cosa)?2:4); static void sppp_channel_init(struct channel_data *chan) { struct net_device *d; + chan->if_ptr = &chan->pppdev; + chan->pppdev.dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); sppp_attach(&chan->pppdev); - d=&chan->pppdev.dev; + d=chan->pppdev.dev; d->name = chan->name; d->base_addr = chan->cosa->datareg; d->irq = chan->cosa->irq; @@ -593,15 +596,15 @@ static void sppp_channel_init(struct channel_data *chan) dev_init_buffers(d); if (register_netdev(d) == -1) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); - sppp_detach(&chan->pppdev.dev); + sppp_detach(chan->pppdev.dev); return; } } static void sppp_channel_delete(struct channel_data *chan) { - sppp_detach(&chan->pppdev.dev); - unregister_netdev(&chan->pppdev.dev); + sppp_detach(chan->pppdev.dev); + unregister_netdev(chan->pppdev.dev); } @@ -717,7 +720,7 @@ static char *sppp_setup_rx(struct channel_data *chan, int size) chan->stats.rx_dropped++; return NULL; } - chan->pppdev.dev.trans_start = jiffies; + chan->pppdev.dev->trans_start = jiffies; return skb_put(chan->rx_skb, size); } @@ -731,13 +734,13 @@ static int sppp_rx_done(struct channel_data *chan) return 0; } chan->rx_skb->protocol = htons(ETH_P_WAN_PPP); - chan->rx_skb->dev = &chan->pppdev.dev; + chan->rx_skb->dev = chan->pppdev.dev; chan->rx_skb->mac.raw = chan->rx_skb->data; chan->stats.rx_packets++; chan->stats.rx_bytes += chan->cosa->rxsize; netif_rx(chan->rx_skb); chan->rx_skb = 0; - chan->pppdev.dev.trans_start = jiffies; + chan->pppdev.dev->trans_start = jiffies; return 0; } @@ -755,7 +758,7 @@ static int sppp_tx_done(struct channel_data *chan, int size) chan->tx_skb = 0; chan->stats.tx_packets++; chan->stats.tx_bytes += size; - chan->pppdev.dev.tbusy = 0; + chan->pppdev.dev->tbusy = 0; mark_bh(NET_BH); return 1; } diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index ba4e49c83a50..d5c7ebd5e690 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -41,6 +41,7 @@ static int dma; struct sv11_device { + void *if_ptr; /* General purpose pointer (used by SPPP) */ struct z8530_dev sync; struct ppp_device netdev; char name[16]; @@ -240,7 +241,12 @@ static struct sv11_device *sv11_init(int iobase, int irq) goto fail3; memset(sv, 0, sizeof(*sv)); + sv->if_ptr=&sv->netdev; + sv->netdev.dev=(struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL); + if(!sv->netdev.dev) + goto fail2; + dev=&sv->sync; /* @@ -264,12 +270,12 @@ static struct sv11_device *sv11_init(int iobase, int irq) if(request_irq(irq, &z8530_interrupt, SA_INTERRUPT, "Hostess SV/11", dev)<0) { printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq); - goto fail2; + goto fail1; } dev->irq=irq; dev->chanA.private=sv; - dev->chanA.netdevice=&sv->netdev.dev; + dev->chanA.netdevice=sv->netdev.dev; dev->chanA.dev=dev; dev->chanB.dev=dev; dev->name=sv->name; @@ -374,6 +380,8 @@ dmafail: free_dma(dev->chanA.txdma); fail: free_irq(irq, dev); +fail1: + kfree(sv->netdev.dev); fail2: kfree(sv); fail3: @@ -383,9 +391,9 @@ fail3: static void sv11_shutdown(struct sv11_device *dev) { - sppp_detach(&dev->netdev.dev); + sppp_detach(dev->netdev.dev); z8530_shutdown(&dev->sync); - unregister_netdev(&dev->netdev.dev); + unregister_netdev(dev->netdev.dev); free_irq(dev->sync.irq, dev); if(dma) { diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 5cbbff8c9522..90cccf81ddca 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -32,6 +32,7 @@ struct slvl_device { + void *if_ptr; /* General purpose pointer (used by SPPP) */ struct z8530_channel *chan; struct ppp_device netdev; char name[16]; @@ -243,8 +244,19 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i memset(b, 0, sizeof(*sv)); b->dev[0].chan = &b->board.chanA; + b->dev[0].if_ptr = &b->dev[0].netdev; + b->dev[0].netdev.dev=(struct net_device *) + kmalloc(sizeof(struct net_device), GFP_KERNEL); + if(!b->dev[0].netdev.dev) + goto fail2; + b->dev[1].chan = &b->board.chanB; - + b->dev[1].if_ptr = &b->dev[1].netdev; + b->dev[1].netdev.dev=(struct net_device *) + kmalloc(sizeof(struct net_device), GFP_KERNEL); + if(!b->dev[1].netdev.dev) + goto fail1_0; + dev=&b->board; /* @@ -283,14 +295,14 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i if(request_irq(irq, &z8530_interrupt, SA_INTERRUPT, "SeaLevel", dev)<0) { printk(KERN_WARNING "sealevel: IRQ %d already in use.\n", irq); - goto fail2; + goto fail1_1; } dev->irq=irq; dev->chanA.private=&b->dev[0]; dev->chanB.private=&b->dev[1]; - dev->chanA.netdevice=&b->dev[0].netdev.dev; - dev->chanB.netdevice=&b->dev[1].netdev.dev; + dev->chanA.netdevice=b->dev[0].netdev.dev; + dev->chanB.netdevice=b->dev[1].netdev.dev; dev->chanA.dev=dev; dev->chanB.dev=dev; dev->name=b->dev[0].name; @@ -399,6 +411,10 @@ dmafail: free_dma(dev->chanA.txdma); fail: free_irq(irq, dev); +fail1_1: + kfree(b->dev[1].netdev.dev); +fail1_0: + kfree(b->dev[0].netdev.dev); fail2: kfree(b); fail3: @@ -414,8 +430,8 @@ static void slvl_shutdown(struct slvl_board *b) for(u=0; u<2; u++) { - sppp_detach(&b->dev[u].netdev.dev); - unregister_netdev(&b->dev[u].netdev.dev); + sppp_detach(b->dev[u].netdev.dev); + unregister_netdev(b->dev[u].netdev.dev); } free_irq(b->board.irq, &b->board); diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c index eee3fceb86c5..bfa2bf89ffbc 100644 --- a/drivers/net/wan/syncppp.c +++ b/drivers/net/wan/syncppp.c @@ -187,7 +187,7 @@ static void sppp_clear_timeout(struct sppp *p) void sppp_input (struct net_device *dev, struct sk_buff *skb) { struct ppp_header *h; - struct sppp *sp = &((struct ppp_device *)dev)->sppp; + struct sppp *sp = (struct sppp *)sppp_of(dev); skb->dev=dev; skb->mac.raw=skb->data; @@ -316,7 +316,7 @@ EXPORT_SYMBOL(sppp_input); static int sppp_hard_header(struct sk_buff *skb, struct net_device *dev, __u16 type, void *daddr, void *saddr, unsigned int len) { - struct sppp *sp = &((struct ppp_device *)dev)->sppp; + struct sppp *sp = (struct sppp *)sppp_of(dev); struct ppp_header *h; skb_push(skb,sizeof(struct ppp_header)); h=(struct ppp_header *)skb->data; @@ -826,7 +826,7 @@ static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2) int sppp_close (struct net_device *dev) { - struct sppp *sp = &((struct ppp_device *)dev)->sppp; + struct sppp *sp = (struct sppp *)sppp_of(dev); dev->flags &= ~IFF_RUNNING; sp->lcp.state = LCP_STATE_CLOSED; sp->ipcp.state = IPCP_STATE_CLOSED; @@ -839,7 +839,7 @@ EXPORT_SYMBOL(sppp_close); int sppp_open (struct net_device *dev) { - struct sppp *sp = &((struct ppp_device *)dev)->sppp; + struct sppp *sp = (struct sppp *)sppp_of(dev); sppp_close(dev); dev->flags |= IFF_RUNNING; if (!(sp->pp_flags & PP_CISCO)) @@ -851,7 +851,7 @@ EXPORT_SYMBOL(sppp_open); int sppp_reopen (struct net_device *dev) { - struct sppp *sp = &((struct ppp_device *)dev)->sppp; + struct sppp *sp = (struct sppp *)sppp_of(dev); sppp_close(dev); dev->flags |= IFF_RUNNING; if (!(sp->pp_flags & PP_CISCO)) @@ -880,7 +880,7 @@ EXPORT_SYMBOL(sppp_change_mtu); int sppp_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct sppp *sp = &((struct ppp_device *)dev)->sppp; + struct sppp *sp = (struct sppp *)sppp_of(dev); if(dev->flags&IFF_UP) return -EBUSY; @@ -913,7 +913,7 @@ EXPORT_SYMBOL(sppp_do_ioctl); void sppp_attach(struct ppp_device *pd) { - struct net_device *dev=&pd->dev; + struct net_device *dev = pd->dev; struct sppp *sp = &pd->sppp; /* Initialize keepalive handler. */ @@ -970,8 +970,7 @@ EXPORT_SYMBOL(sppp_attach); void sppp_detach (struct net_device *dev) { - struct sppp **q, *p, *sp = &((struct ppp_device *)dev)->sppp; - + struct sppp **q, *p, *sp = (struct sppp *)sppp_of(dev); /* Remove the entry from the keepalive list. */ for (q = &spppq; (p = *q); q = &p->pp_next) @@ -1297,6 +1296,8 @@ void sync_ppp_init(void) dev_add_pack(&sppp_packet_type); } +EXPORT_SYMBOL(sync_ppp_init); + #ifdef MODULE int init_module(void) diff --git a/drivers/net/wan/syncppp.h b/drivers/net/wan/syncppp.h index c03c720cacdd..1e2056869cfd 100644 --- a/drivers/net/wan/syncppp.h +++ b/drivers/net/wan/syncppp.h @@ -51,10 +51,13 @@ struct sppp struct ppp_device { - struct net_device dev; /* Network device */ + struct net_device *dev; /* Network device pointer */ struct sppp sppp; /* Synchronous PPP */ }; +#define sppp_of(dev) \ + (&((struct ppp_device *)(*(unsigned long *)((dev)->priv)))->sppp) + #define PP_KEEPALIVE 0x01 /* use keepalive protocol */ #define PP_CISCO 0x02 /* use Cisco protocol instead of PPP */ #define PP_TIMO 0x04 /* cp_timeout routine active */ @@ -82,6 +85,7 @@ void sppp_flush (struct net_device *dev); int sppp_open (struct net_device *dev); int sppp_reopen (struct net_device *dev); int sppp_close (struct net_device *dev); +void sync_ppp_init (void); #endif #define SPPPIOCCISCO (SIOCDEVPRIVATE) diff --git a/drivers/pcmcia/bulkmem.c b/drivers/pcmcia/bulkmem.c index e3c602cd4c6d..cc46e352d041 100644 --- a/drivers/pcmcia/bulkmem.c +++ b/drivers/pcmcia/bulkmem.c @@ -294,7 +294,13 @@ int MTDHelperEntry(int func, void *a1, void *a2) { switch (func) { case MTDRequestWindow: - return pcmcia_request_window(a1, a2); + { + window_handle_t w; + int ret = pcmcia_request_window(a1, a2, &w); + (window_handle_t *)a1 = w; + return ret; + } + break; case MTDReleaseWindow: return pcmcia_release_window(a1); case MTDModifyWindow: @@ -470,7 +476,8 @@ int pcmcia_register_mtd(client_handle_t handle, mtd_reg_t *reg) ======================================================================*/ -int pcmcia_register_erase_queue(client_handle_t *handle, eraseq_hdr_t *header) +int pcmcia_register_erase_queue(client_handle_t *handle, eraseq_hdr_t *header, + eraseq_handle_t *e) { eraseq_t *queue; @@ -481,7 +488,7 @@ int pcmcia_register_erase_queue(client_handle_t *handle, eraseq_hdr_t *header) queue->handle = *handle; queue->count = header->QueueEntryCnt; queue->entry = header->QueueEntryArray; - *handle = (client_handle_t)queue; + *e = queue; return CS_SUCCESS; } /* register_erase_queue */ @@ -517,7 +524,7 @@ int pcmcia_check_erase_queue(eraseq_handle_t eraseq) ======================================================================*/ -int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open) +int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open, memory_handle_t *mh) { socket_info_t *s; memory_handle_t region; @@ -534,7 +541,7 @@ int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open) region = region->info.next; } if (region && region->mtd) { - *handle = (client_handle_t)region; + *mh = region; DEBUG(1, "cs: open_memory(0x%p, 0x%x) = 0x%p\n", handle, open->Offset, region); return CS_SUCCESS; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 3b74627a26c9..da43623c43d6 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -1814,7 +1814,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) ======================================================================*/ -int pcmcia_request_window(client_handle_t *handle, win_req_t *req) +int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh) { socket_info_t *s; window_t *win; @@ -1876,7 +1876,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req) s->state |= SOCKET_WIN_REQ(w); /* Return window handle */ - *handle = (client_handle_t)win; + *wh = win; return CS_SUCCESS; } /* request_window */ @@ -2141,7 +2141,14 @@ int CardServices(int func, void *a1, void *a2, void *a3) case ModifyWindow: return pcmcia_modify_window(a1, a2); break; case OpenMemory: - return pcmcia_open_memory(a1, a2); +/* return pcmcia_open_memory(a1, a2); */ + { + memory_handle_t m; + int ret = pcmcia_open_memory(a1, a2, &m); + (memory_handle_t *)a1 = m; + return ret; + } + break; case ParseTuple: return pcmcia_parse_tuple(a1, a2, a3); break; case ReadMemory: @@ -2149,8 +2156,15 @@ int CardServices(int func, void *a1, void *a2, void *a3) case RegisterClient: return pcmcia_register_client(a1, a2); break; case RegisterEraseQueue: - return pcmcia_register_erase_queue(a1, a2); break; - case RegisterMTD: + { + eraseq_handle_t w; + int ret = pcmcia_register_erase_queue(a1, a2, &w); + (eraseq_handle_t *)a1 = w; + return ret; + } + break; +/* return pcmcia_register_erase_queue(a1, a2); break; */ + return pcmcia_register_mtd(a1, a2); break; case ReleaseConfiguration: return pcmcia_release_configuration(a1); break; @@ -2167,7 +2181,13 @@ int CardServices(int func, void *a1, void *a2, void *a3) case RequestIRQ: return pcmcia_request_irq(a1, a2); break; case RequestWindow: - return pcmcia_request_window(a1, a2); break; + { + window_handle_t w; + int ret = pcmcia_request_window(a1, a2, &w); + (window_handle_t *)a1 = w; + return ret; + } + break; case ResetCard: return pcmcia_reset_card(a1, a2); break; case SetEventMask: diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index e6d51509ba73..7cf7803f3191 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -679,7 +679,7 @@ include $(TOPDIR)/Rules.make 53c8xx_d.h: 53c7,8xx.scr script_asm.pl ln -sf 53c7,8xx.scr fake8.c - $(CPP) -traditional -DCHIP=810 fake8.c | grep -v '^#' | perl script_asm.pl + $(CPP) $(CPPFLAGS) -traditional -DCHIP=810 fake8.c | grep -v '^#' | perl script_asm.pl mv script.h 53c8xx_d.h mv scriptu.h 53c8xx_u.h rm fake8.c @@ -688,7 +688,7 @@ include $(TOPDIR)/Rules.make 53c7xx_d.h: 53c7xx.scr script_asm.pl ln -sf 53c7xx.scr fake7.c - $(CPP) -traditional -DCHIP=710 fake7.c | grep -v '^#' | perl -s script_asm.pl -ncr7x0_family + $(CPP) $(CPPFLAGS) -traditional -DCHIP=710 fake7.c | grep -v '^#' | perl -s script_asm.pl -ncr7x0_family mv script.h 53c7xx_d.h mv scriptu.h 53c7xx_u.h rm fake7.c @@ -699,7 +699,7 @@ include $(TOPDIR)/Rules.make sim710_d.h: sim710.scr script_asm.pl ln -sf sim710.scr fake7.c - $(CPP) -traditional -DCHIP=710 fake7.c | grep -v '^#' | perl -s script_asm.pl -ncr7x0_family + $(CPP) $(CPPFLAGS) -traditional -DCHIP=710 fake7.c | grep -v '^#' | perl -s script_asm.pl -ncr7x0_family mv script.h sim710_d.h mv scriptu.h sim710_u.h rm fake7.c diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index f9fa60742452..a5dd9d29b81e 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -60,6 +60,12 @@ /* 0.99.05 - Fix an oops when we get certain passthru commands */ /* 1.00.00 - Initial Public Release */ /* Functionally equivalent to 0.99.05 */ +/* 3.60.00 - Bump max commands to 128 for use with ServeRAID firmware 3.60 */ +/* - Change version to 3.60 to coincide with ServeRAID release */ +/* numbering. */ +/* 3.60.01 - Remove bogus error check in passthru routine */ +/* 3.60.02 - Make DCDB direction based on lookup table */ +/* - Only allow one DCDB command to a SCSI ID at a time */ /* */ /*****************************************************************************/ @@ -110,8 +116,8 @@ /* * DRIVER_VER */ -#define IPS_VERSION_HIGH "1.00" /* MUST be 4 chars */ -#define IPS_VERSION_LOW ".00 " /* MUST be 4 chars */ +#define IPS_VERSION_HIGH "3.60" /* MUST be 4 chars */ +#define IPS_VERSION_LOW ".02 " /* MUST be 4 chars */ #if !defined(__i386__) #error "This driver has only been tested on the x86 platform" @@ -154,6 +160,63 @@ static char ips_adapter_name[][30] = { "ServeRAID 3L" }; +/* + * Direction table + */ +static char ips_command_direction[] = { +IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, +IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, +IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, +IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT, +IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT, +IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN, +IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK, +IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, +IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, +IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, +IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, +IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE, +IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, +IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE, +IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT, +IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE, +IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, +IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK +}; + /* * Function prototypes */ @@ -1333,7 +1396,7 @@ ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { (scb->cmd.basic_io.op_code == DIRECT_CDB_SCATTER_GATHER)) return (0); - if (pt->CmdBSize && pt->CmdBuffer) { + if (pt->CmdBSize) { scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + sizeof(ips_passthru_t)); } else { scb->data_busaddr = 0L; @@ -1657,8 +1720,10 @@ ips_hainit(ips_ha_t *ha) { /* set controller IDs */ ha->ha_id[0] = IPS_ADAPTER_ID; - for (i = 1; i < ha->nbus; i++) + for (i = 1; i < ha->nbus; i++) { ha->ha_id[i] = ha->conf->init_id[i-1] & 0x1f; + ha->dcdb_active[i-1] = 0; + } return (1); } @@ -1678,6 +1743,7 @@ static void ips_next(ips_ha_t *ha) { ips_scb_t *scb; Scsi_Cmnd *SC; + Scsi_Cmnd *p; int ret; DBG("ips_next"); @@ -1750,9 +1816,15 @@ ips_next(ips_ha_t *ha) { /* * Send "Normal" I/O commands */ - while ((ha->scb_waitlist.head) && - (scb = ips_getscb(ha))) { - SC = ips_removeq_wait_head(&ha->scb_waitlist); + p = ha->scb_waitlist.head; + while ((p) && (scb = ips_getscb(ha))) { + if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) { + ips_freescb(ha, scb); + p = (Scsi_Cmnd *) p->host_scribble; + continue; + } + + SC = ips_removeq_wait(&ha->scb_waitlist, p); SC->result = DID_OK; SC->host_scribble = NULL; @@ -1767,7 +1839,7 @@ ips_next(ips_ha_t *ha) { scb->data_len = 0; scb->callback = ipsintr_done; scb->timeout = ips_cmd_timeout; - memset(&scb->cmd, 0, 4); + memset(&scb->cmd, 0, 16); /* copy in the CDB */ memcpy(scb->cdb, SC->cmnd, SC->cmd_len); @@ -1825,11 +1897,11 @@ ips_next(ips_ha_t *ha) { } - if ((scb->scsi_cmd->request.cmd == READ) && (SC->request_bufflen)) - scb->dcdb.cmd_attribute |= IPS_DATA_IN; + scb->dcdb.cmd_attribute |= + ips_command_direction[scb->scsi_cmd->cmnd[0]]; - if ((scb->scsi_cmd->request.cmd == WRITE) && (SC->request_bufflen)) - scb->dcdb.cmd_attribute |= IPS_DATA_OUT; + if (!scb->dcdb.cmd_attribute & 0x3) + scb->dcdb.transfer_length = 0; if (scb->data_len >= IPS_MAX_XFER) { scb->dcdb.cmd_attribute |= TRANSFER_64K; @@ -1848,16 +1920,25 @@ ips_next(ips_ha_t *ha) { scb->scsi_cmd->scsi_done(scb->scsi_cmd); } + if (scb->bus) + ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); + ips_freescb(ha, scb); break; case IPS_SUCCESS_IMM: if (scb->scsi_cmd) scb->scsi_cmd->scsi_done(scb->scsi_cmd); + + if (scb->bus) + ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); + ips_freescb(ha, scb); break; default: break; } /* end case */ + + p = (Scsi_Cmnd *) p->host_scribble; } /* end while */ } @@ -2259,12 +2340,11 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { scb->sg_len = 0; } - if ((scb->scsi_cmd->request.cmd == READ) && (scb->data_len)) - scb->dcdb.cmd_attribute |= IPS_DATA_IN; - - if ((scb->scsi_cmd->request.cmd == WRITE) && (scb->data_len)) - scb->dcdb.cmd_attribute |= IPS_DATA_OUT; - + scb->dcdb.cmd_attribute |= + ips_command_direction[scb->scsi_cmd->cmnd[0]]; + + if (!scb->dcdb.cmd_attribute & 0x3) + scb->dcdb.transfer_length = 0; if (scb->data_len >= IPS_MAX_XFER) { scb->dcdb.cmd_attribute |= TRANSFER_64K; scb->dcdb.transfer_length = 0; @@ -2299,6 +2379,9 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) { } /* end if passthru */ #endif + if (scb->bus) + ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id); + /* call back to SCSI layer */ scb->scsi_cmd->scsi_done(scb->scsi_cmd); ips_freescb(ha, scb); @@ -2323,6 +2406,16 @@ ips_map_status(ips_scb_t *scb, ips_stat_t *sp) { DBG("ips_map_status"); if (scb->bus) { +#if IPS_DEBUG >= 10 + printk(KERN_NOTICE "(%s) Physical device error: %x %x, Sense Key: %x, ASC: %x, ASCQ: %x\n", + ips_name, + scb->basic_status, + scb->extended_status, + scb->dcdb.sense_info[2] & 0xf, + scb->dcdb.sense_info[12], + scb->dcdb.sense_info[13]); +#endif + /* copy SCSI status and sense data for DCDB commands */ memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info, sizeof(scb->scsi_cmd->sense_buffer)); @@ -2669,6 +2762,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { else scb->cmd.dcdb.op_code = DIRECT_CDB_SCATTER_GATHER; + ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id); scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb); scb->cmd.dcdb.reserved = 0; diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 967b69522bfb..d760ae3a6ac2 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -77,102 +77,102 @@ #define UDELAY udelay #define MDELAY mdelay - #define verify_area_20(t,a,sz) (0) /* success */ - #define PUT_USER put_user - #define __PUT_USER __put_user - #define PUT_USER_RET put_user_ret - #define GET_USER get_user - #define __GET_USER __get_user - #define GET_USER_RET get_user_ret + #define verify_area_20(t,a,sz) (0) /* success */ + #define PUT_USER put_user + #define __PUT_USER __put_user + #define PUT_USER_RET put_user_ret + #define GET_USER get_user + #define __GET_USER __get_user + #define GET_USER_RET get_user_ret /* * Adapter address map equates */ - #define HISR 0x08 /* Host Interrupt Status Reg */ - #define CCSAR 0x10 /* Cmd Channel System Addr Reg */ - #define CCCR 0x14 /* Cmd Channel Control Reg */ - #define SQHR 0x20 /* Status Q Head Reg */ - #define SQTR 0x24 /* Status Q Tail Reg */ - #define SQER 0x28 /* Status Q End Reg */ - #define SQSR 0x2C /* Status Q Start Reg */ - #define SCPR 0x05 /* Subsystem control port reg */ - #define ISPR 0x06 /* interrupt status port reg */ - #define CBSP 0x07 /* CBSP register */ + #define HISR 0x08 /* Host Interrupt Status Reg */ + #define CCSAR 0x10 /* Cmd Channel System Addr Reg */ + #define CCCR 0x14 /* Cmd Channel Control Reg */ + #define SQHR 0x20 /* Status Q Head Reg */ + #define SQTR 0x24 /* Status Q Tail Reg */ + #define SQER 0x28 /* Status Q End Reg */ + #define SQSR 0x2C /* Status Q Start Reg */ + #define SCPR 0x05 /* Subsystem control port reg */ + #define ISPR 0x06 /* interrupt status port reg */ + #define CBSP 0x07 /* CBSP register */ /* * Adapter register bit equates */ - #define GHI 0x04 /* HISR General Host Interrupt */ - #define SQO 0x02 /* HISR Status Q Overflow */ - #define SCE 0x01 /* HISR Status Channel Enqueue */ - #define SEMAPHORE 0x08 /* CCCR Semaphore Bit */ - #define ILE 0x10 /* CCCR ILE Bit */ - #define START_COMMAND 0x101A /* CCCR Start Command Channel */ - #define START_STOP_BIT 0x0002 /* CCCR Start/Stop Bit */ - #define RST 0x80 /* SCPR Reset Bit */ - #define EBM 0x02 /* SCPR Enable Bus Master */ - #define EI 0x80 /* HISR Enable Interrupts */ - #define OP 0x01 /* OP bit in CBSP */ + #define GHI 0x04 /* HISR General Host Interrupt */ + #define SQO 0x02 /* HISR Status Q Overflow */ + #define SCE 0x01 /* HISR Status Channel Enqueue */ + #define SEMAPHORE 0x08 /* CCCR Semaphore Bit */ + #define ILE 0x10 /* CCCR ILE Bit */ + #define START_COMMAND 0x101A /* CCCR Start Command Channel */ + #define START_STOP_BIT 0x0002 /* CCCR Start/Stop Bit */ + #define RST 0x80 /* SCPR Reset Bit */ + #define EBM 0x02 /* SCPR Enable Bus Master */ + #define EI 0x80 /* HISR Enable Interrupts */ + #define OP 0x01 /* OP bit in CBSP */ /* * Adapter Command ID Equates */ - #define GET_LOGICAL_DRIVE_INFO 0x19 - #define GET_SUBSYS_PARAM 0x40 - #define READ_NVRAM_CONFIGURATION 0x38 - #define RW_NVRAM_PAGE 0xBC - #define IPS_READ 0x02 - #define IPS_WRITE 0x03 - #define ENQUIRY 0x05 - #define FLUSH_CACHE 0x0A - #define NORM_STATE 0x00 - #define READ_SCATTER_GATHER 0x82 - #define WRITE_SCATTER_GATHER 0x83 - #define DIRECT_CDB 0x04 - #define DIRECT_CDB_SCATTER_GATHER 0x84 - #define CONFIG_SYNC 0x58 - #define POCL 0x30 - #define GET_ERASE_ERROR_TABLE 0x17 - #define RESET_CHANNEL 0x1A - #define CSL 0xFF - #define ADAPT_RESET 0xFF + #define GET_LOGICAL_DRIVE_INFO 0x19 + #define GET_SUBSYS_PARAM 0x40 + #define READ_NVRAM_CONFIGURATION 0x38 + #define RW_NVRAM_PAGE 0xBC + #define IPS_READ 0x02 + #define IPS_WRITE 0x03 + #define ENQUIRY 0x05 + #define FLUSH_CACHE 0x0A + #define NORM_STATE 0x00 + #define READ_SCATTER_GATHER 0x82 + #define WRITE_SCATTER_GATHER 0x83 + #define DIRECT_CDB 0x04 + #define DIRECT_CDB_SCATTER_GATHER 0x84 + #define CONFIG_SYNC 0x58 + #define POCL 0x30 + #define GET_ERASE_ERROR_TABLE 0x17 + #define RESET_CHANNEL 0x1A + #define CSL 0xFF + #define ADAPT_RESET 0xFF /* * Adapter Equates */ - #define IPS_MAX_ADAPTERS 16 - #define IPS_MAX_IOCTL 1 - #define IPS_MAX_IOCTL_QUEUE 8 - #define IPS_MAX_QUEUE 128 - #define IPS_BLKSIZE 512 - #define MAX_SG_ELEMENTS 17 - #define MAX_LOGICAL_DRIVES 8 - #define MAX_CHANNELS 3 - #define MAX_TARGETS 15 - #define MAX_CHUNKS 16 - #define MAX_CMDS 64 - #define IPS_MAX_XFER 0x10000 - #define COMP_MODE_HEADS 128 - #define COMP_MODE_SECTORS 32 - #define NORM_MODE_HEADS 254 - #define NORM_MODE_SECTORS 63 - #define NVRAM_PAGE5_SIGNATURE 0xFFDDBB99 - #define MAX_POST_BYTES 0x02 - #define MAX_CONFIG_BYTES 0x02 - #define GOOD_POST_BASIC_STATUS 0x80 - #define SEMAPHORE_TIMEOUT 2000 - #define IPS_INTR_OFF 0 - #define IPS_INTR_ON 1 - #define IPS_ADAPTER_ID 0xF - #define IPS_VENDORID 0x1014 - #define IPS_DEVICEID 0x002E - #define TIMEOUT_10 0x10 - #define TIMEOUT_60 0x20 - #define TIMEOUT_20M 0x30 - #define STATUS_SIZE 4 - #define STATUS_Q_SIZE (MAX_CMDS+1) * STATUS_SIZE - #define ONE_MSEC 1 - #define ONE_SEC 1000 + #define IPS_MAX_ADAPTERS 16 + #define IPS_MAX_IOCTL 1 + #define IPS_MAX_IOCTL_QUEUE 8 + #define IPS_MAX_QUEUE 128 + #define IPS_BLKSIZE 512 + #define MAX_SG_ELEMENTS 17 + #define MAX_LOGICAL_DRIVES 8 + #define MAX_CHANNELS 3 + #define MAX_TARGETS 15 + #define MAX_CHUNKS 16 + #define MAX_CMDS 128 + #define IPS_MAX_XFER 0x10000 + #define COMP_MODE_HEADS 128 + #define COMP_MODE_SECTORS 32 + #define NORM_MODE_HEADS 254 + #define NORM_MODE_SECTORS 63 + #define NVRAM_PAGE5_SIGNATURE 0xFFDDBB99 + #define MAX_POST_BYTES 0x02 + #define MAX_CONFIG_BYTES 0x02 + #define GOOD_POST_BASIC_STATUS 0x80 + #define SEMAPHORE_TIMEOUT 2000 + #define IPS_INTR_OFF 0 + #define IPS_INTR_ON 1 + #define IPS_ADAPTER_ID 0xF + #define IPS_VENDORID 0x1014 + #define IPS_DEVICEID 0x002E + #define TIMEOUT_10 0x10 + #define TIMEOUT_60 0x20 + #define TIMEOUT_20M 0x30 + #define STATUS_SIZE 4 + #define STATUS_Q_SIZE (MAX_CMDS+1) * STATUS_SIZE + #define ONE_MSEC 1 + #define ONE_SEC 1000 /* * Adapter Basic Status Codes @@ -196,24 +196,24 @@ /* * Adapter Extended Status Equates */ - #define SELECTION_TIMEOUT 0xF0 - #define DATA_OVER_UNDER_RUN 0xF2 - #define EXT_HOST_RESET 0xF7 - #define EXT_DEVICE_RESET 0xF8 - #define EXT_RECOVERY 0xFC - #define EXT_CHECK_CONDITION 0xFF + #define SELECTION_TIMEOUT 0xF0 + #define DATA_OVER_UNDER_RUN 0xF2 + #define EXT_HOST_RESET 0xF7 + #define EXT_DEVICE_RESET 0xF8 + #define EXT_RECOVERY 0xFC + #define EXT_CHECK_CONDITION 0xFF /* * Operating System Defines */ - #define OS_WINDOWS_NT 0x01 - #define OS_NETWARE 0x02 - #define OS_OPENSERVER 0x03 - #define OS_UNIXWARE 0x04 - #define OS_SOLARIS 0x05 - #define OS_OS2 0x06 - #define OS_LINUX 0x07 - #define OS_FREEBSD 0x08 + #define OS_WINDOWS_NT 0x01 + #define OS_NETWARE 0x02 + #define OS_OPENSERVER 0x03 + #define OS_UNIXWARE 0x04 + #define OS_SOLARIS 0x05 + #define OS_OS2 0x06 + #define OS_LINUX 0x07 + #define OS_FREEBSD 0x08 /* * Adapter Command/Status Packet Definitions @@ -225,11 +225,11 @@ /* * Logical Drive Equates */ - #define OFF_LINE 0x02 - #define OKAY 0x03 - #define FREE 0x00 - #define SYS 0x06 - #define CRS 0x24 + #define OFF_LINE 0x02 + #define OKAY 0x03 + #define FREE 0x00 + #define SYS 0x06 + #define CRS 0x24 /* * DCDB Table Equates @@ -237,6 +237,8 @@ #define NO_DISCONNECT 0x00 #define DISCONNECT_ALLOWED 0x80 #define NO_AUTO_REQUEST_SENSE 0x40 + #define IPS_DATA_NONE 0x00 + #define IPS_DATA_UNK 0x00 #define IPS_DATA_IN 0x01 #define IPS_DATA_OUT 0x02 #define TRANSFER_64K 0x08 @@ -734,6 +736,7 @@ typedef struct ips_wait_queue { typedef struct ips_ha { u8 ha_id[MAX_CHANNELS+1]; + u32 dcdb_active[MAX_CHANNELS]; u32 io_addr; /* Base I/O address */ u8 irq; /* IRQ for adapter */ u8 ntargets; /* Number of targets */ diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 072c7d82c2f4..2981d3105997 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -470,7 +470,10 @@ static void scan_scsis(struct Scsi_Host *shpnt, initialize_merge_fn(SDpnt); - init_waitqueue_head(&SDpnt->device_wait); + /* + * Initialize the object that we will use to wait for command blocks. + */ + init_waitqueue_head(&SDpnt->scpnt_wait); /* * Next, hook the device to the host in question. @@ -901,7 +904,10 @@ int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun, SDpnt->device_queue = SCpnt; SDpnt->online = TRUE; - init_waitqueue_head(&SDpnt->device_wait); + /* + * Initialize the object that we will use to wait for command blocks. + */ + init_waitqueue_head(&SDpnt->scpnt_wait); /* * Since we just found one device, there had damn well better be one in the list @@ -984,24 +990,6 @@ int scan_scsis_single(int channel, int dev, int lun, int *max_dev_lun, #define IN_RESET3 8 -/* This function takes a quick look at a request, and decides if it - * can be queued now, or if there would be a stall while waiting for - * something else to finish. This routine assumes that interrupts are - * turned off when entering the routine. It is the responsibility - * of the calling code to ensure that this is the case. - */ - - -/* This function returns a structure pointer that will be valid for - * the device. The wait parameter tells us whether we should wait for - * the unit to become free or not. We are also able to tell this routine - * not to return a descriptor if the host is unable to accept any more - * commands for the time being. We need to keep in mind that there is no - * guarantee that the host remain not busy. Keep in mind the - * scsi_request_queueable function also knows the internal allocation scheme - * of the packets for each device - */ - /* * This lock protects the freelist for all devices on the system. * We could make this finer grained by having a single lock per @@ -1029,15 +1017,24 @@ static spinlock_t scsi_bhqueue_lock = SPIN_LOCK_UNLOCKED; * Arguments: device - device for which we want a command descriptor * wait - 1 if we should wait in the event that none * are available. + * interruptible - 1 if we should unblock and return NULL + * in the event that we must wait, and a signal + * arrives. * * Lock status: No locks assumed to be held. This function is SMP-safe. * * Returns: Pointer to command descriptor. * * Notes: Prior to the new queue code, this function was not SMP-safe. + * + * If the wait flag is true, and we are waiting for a free + * command block, this function will interrupt and return + * NULL in the event that a signal arrives that needs to + * be handled. */ -Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait) +Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait, + int interruptable) { struct Scsi_Host *host; Scsi_Cmnd *SCpnt = NULL; @@ -1121,15 +1118,53 @@ Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait) * If we have been asked to wait for a free block, then * wait here. */ - spin_unlock_irqrestore(&device_request_lock, flags); if (wait) { + DECLARE_WAITQUEUE(wait, current); + + /* + * We need to wait for a free commandblock. We need to + * insert ourselves into the list before we release the + * lock. This way if a block were released the same + * microsecond that we released the lock, the call + * to schedule() wouldn't block (well, it might switch, + * but the current task will still be schedulable. + */ + add_wait_queue(&device->scpnt_wait, &wait); + if( interruptable ) { + set_current_state(TASK_INTERRUPTIBLE); + } else { + set_current_state(TASK_UNINTERRUPTIBLE); + } + + spin_unlock_irqrestore(&device_request_lock, flags); + /* * This should block until a device command block * becomes available. */ - sleep_on(&device->device_wait); + schedule(); + spin_lock_irqsave(&device_request_lock, flags); + + remove_wait_queue(&device->scpnt_wait, &wait); + /* + * FIXME - Isn't this redundant?? Someone + * else will have forced the state back to running. + */ + set_current_state(TASK_RUNNING); + /* + * In the event that a signal has arrived that we need + * to consider, then simply return NULL. Everyone + * that calls us should be prepared for this + * possibility, and pass the appropriate code back + * to the user. + */ + if( interruptable ) { + if (signal_pending(current)) + return NULL; + } } else { + spin_unlock_irqrestore(&device_request_lock, flags); return NULL; } } @@ -1172,11 +1207,22 @@ Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait) * * Notes: The command block can no longer be used by the caller once * this funciton is called. This is in effect the inverse - * of scsi_allocate_device/scsi_request_queueable. + * of scsi_allocate_device. Note that we also must perform + * a couple of additional tasks. We must first wake up any + * processes that might have blocked waiting for a command + * block, and secondly we must hit the queue handler function + * to make sure that the device is busy. + * + * The idea is that a lot of the mid-level internals gunk + * gets hidden in this function. Upper level drivers don't + * have any chickens to wave in the air to get things to + * work reliably. */ void scsi_release_command(Scsi_Cmnd * SCpnt) { unsigned long flags; + Scsi_Device * SDpnt; + spin_lock_irqsave(&device_request_lock, flags); SCpnt->request.rq_status = RQ_INACTIVE; @@ -1204,13 +1250,41 @@ void scsi_release_command(Scsi_Cmnd * SCpnt) atomic_read(&SCpnt->host->eh_wait->count))); up(SCpnt->host->eh_wait); } + + SDpnt = SCpnt->device; + spin_unlock_irqrestore(&device_request_lock, flags); + + /* + * Wake up anyone waiting for this device. Do this after we + * have released the lock, as they will need it as soon as + * they wake up. + */ + wake_up(&SDpnt->scpnt_wait); + + /* + * Finally, hit the queue request function to make sure that + * the device is actually busy if there are requests present. + * This won't block - if the device cannot take any more, life + * will go on. + */ + { + request_queue_t *q; + + q = &SDpnt->request_queue; + scsi_queue_next_request(q, NULL); + } } /* - * This is inline because we have stack problemes if we recurse to deeply. + * Function: scsi_dispatch_command + * + * Purpose: Dispatch a command to the low-level driver. + * + * Arguments: SCpnt - command block we are dispatching. + * + * Notes: */ - int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt) { #ifdef DEBUG_DELAY @@ -1921,8 +1995,6 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt) SCpnt->lun = SDpnt->lun; SCpnt->channel = SDpnt->channel; SCpnt->request.rq_status = RQ_INACTIVE; - SCpnt->host_wait = FALSE; - SCpnt->device_wait = FALSE; SCpnt->use_sg = 0; SCpnt->old_use_sg = 0; SCpnt->old_cmd_len = 0; @@ -2885,7 +2957,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) DECLARE_MUTEX_LOCKED(sem); shpnt->eh_notify = &sem; - send_sig(SIGKILL, shpnt->ehandler, 1); + send_sig(SIGHUP, shpnt->ehandler, 1); down(&sem); shpnt->eh_notify = NULL; } diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h index d0ad7b6f38ed..7e6e851e2e7d 100644 --- a/drivers/scsi/scsi.h +++ b/drivers/scsi/scsi.h @@ -407,6 +407,7 @@ extern void recount_segments(Scsi_Cmnd * SCpnt); */ extern void initialize_merge_fn(Scsi_Device * SDpnt); extern void scsi_request_fn(request_queue_t * q); +extern void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt); extern int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int); extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt); @@ -427,7 +428,7 @@ extern void scsi_wait_cmd(Scsi_Cmnd *, const void *cmnd, void (*done) (struct scsi_cmnd *), int timeout, int retries); -extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int); +extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int, int); extern Scsi_Cmnd *scsi_request_queueable(struct request *, Scsi_Device *); @@ -456,7 +457,7 @@ struct scsi_device { */ struct scsi_device *next; /* Used for linked list */ struct scsi_device *prev; /* Used for linked list */ - wait_queue_head_t device_wait; /* Used to wait if + wait_queue_head_t scpnt_wait; /* Used to wait if device is busy */ struct Scsi_Host *host; request_queue_t request_queue; @@ -637,16 +638,6 @@ struct scsi_cmnd { */ unsigned done_late:1; - /* - * These two flags are used to track commands that are in the - * mid-level queue. The idea is that a command can be there for - * one of two reasons - either the host is busy or the device is - * busy. Thus when a command on the host finishes, we only try - * and requeue commands that we might expect to be queueable. - */ - unsigned host_wait:1; - unsigned device_wait:1; - /* Low-level done function - can be used by low-level driver to point * to completion function. Not used by mid/upper level code. */ void (*scsi_done) (struct scsi_cmnd *); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 8de7cf8c6711..8ef70d4ac24f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -40,8 +40,14 @@ * the host drivers that we are using may be loaded as modules, and * when we unload these, we need to ensure that the error handler thread * can be shut down. + * + * Note - when we unload a module, we send a SIGHUP. We mustn't + * enable SIGTERM, as this is how the init shuts things down when you + * go to single-user mode. For that matter, init also sends SIGKILL, + * so we mustn't enable that one either. We use SIGHUP instead. Other + * options would be SIGPWR, I suppose. */ -#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM)) +#define SHUTDOWN_SIGS (sigmask(SIGHUP)) #ifdef DEBUG #define SENSE_TIMEOUT SCSI_TIMEOUT diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 3b471d52a6a3..9c725d71a42b 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -111,7 +111,12 @@ static int ioctl_internal_command(Scsi_Device * dev, char *cmd, SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0])); - SCpnt = scsi_allocate_device(dev, 1); + SCpnt = scsi_allocate_device(dev, TRUE, TRUE); + if( SCpnt == NULL ) + { + return -EINTR; + } + { DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; @@ -163,8 +168,6 @@ static int ioctl_internal_command(Scsi_Device * dev, char *cmd, scsi_release_command(SCpnt); SCpnt = NULL; - - wake_up(&SDpnt->device_wait); return result; } @@ -297,7 +300,11 @@ int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic) #ifndef DEBUG_NO_CMD - SCpnt = scsi_allocate_device(dev, 1); + SCpnt = scsi_allocate_device(dev, TRUE, TRUE); + if( SCpnt == NULL ) + { + return -EINTR; + } { DECLARE_MUTEX_LOCKED(sem); @@ -328,7 +335,6 @@ int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic) result = SCpnt->result; - wake_up(&SCpnt->device->device_wait); SDpnt = SCpnt->device; scsi_release_command(SCpnt); SCpnt = NULL; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index e015cc0da73a..4ca20b687103 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -87,8 +87,10 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head) SCpnt->request.special = (void *) SCpnt; /* - * For the moment, we insert at the head of the queue. This may turn - * out to be a bad idea, but we will see about that when we get there. + * We have the option of inserting the head or the tail of the queue. + * Typically we use the tail for new ioctls and so forth. We use the + * head of the queue for things like a QUEUE_FULL message from a + * device, or a host that is unable to accept a particular command. */ spin_lock_irqsave(&io_request_lock, flags); @@ -97,8 +99,12 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head) q->current_request = &SCpnt->request; } else { /* - * FIXME(eric) - we always insert at the tail of the list. Otherwise - * ioctl commands would always take precedence over normal I/O. + * FIXME(eric) - we always insert at the tail of the + * list. Otherwise ioctl commands would always take + * precedence over normal I/O. An ioctl on a busy + * disk might be delayed indefinitely because the + * request might not float high enough in the queue + * to be scheduled. */ SCpnt->request.next = NULL; if (q->current_request == NULL) { @@ -116,9 +122,9 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head) } /* - * Now hit the requeue function for the queue. If the host is already - * busy, so be it - we have nothing special to do. If the host can queue - * it, then send it off. + * Now hit the requeue function for the queue. If the host is + * already busy, so be it - we have nothing special to do. If + * the host can queue it, then send it off. */ q->request_fn(q); spin_unlock_irqrestore(&io_request_lock, flags); @@ -219,13 +225,41 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) q->current_request = &SCpnt->request; SCpnt->request.special = (void *) SCpnt; } + /* * Just hit the requeue function for the queue. - * FIXME - if this queue is empty, check to see if we might need to - * start requests for other devices attached to the same host. */ q->request_fn(q); + SDpnt = (Scsi_Device *) q->queuedata; + SHpnt = SDpnt->host; + + /* + * If this is a single-lun device, and we are currently finished + * with this device, then see if we need to get another device + * started. FIXME(eric) - if this function gets too cluttered + * with special case code, then spin off separate versions and + * use function pointers to pick the right one. + */ + if (SDpnt->single_lun + && q->current_request == NULL + && SDpnt->device_busy == 0) { + request_queue_t *q; + + for (SDpnt = SHpnt->host_queue; + SDpnt; + SDpnt = SDpnt->next) { + if (((SHpnt->can_queue > 0) + && (SHpnt->host_busy >= SHpnt->can_queue)) + || (SHpnt->host_blocked) + || (SDpnt->device_blocked)) { + break; + } + q = &SDpnt->request_queue; + q->request_fn(q); + } + } + /* * Now see whether there are other devices on the bus which * might be starved. If so, hit the request function. If we @@ -234,8 +268,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) * flag as the queue function releases the lock and thus some * other device might have become starved along the way. */ - SDpnt = (Scsi_Device *) q->queuedata; - SHpnt = SDpnt->host; all_clear = 1; if (SHpnt->some_device_starved) { for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { @@ -274,6 +306,9 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) * * Notes: This is called for block device requests in order to * mark some number of sectors as complete. + * + * We are guaranteeing that the request queue will be goosed + * at some point during this call. */ Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors) { @@ -311,7 +346,16 @@ Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors) * to queue the remainder of them. */ if (req->bh) { + request_queue_t *q; + + q = &SCpnt->device->request_queue; + req->buffer = bh->b_data; + /* + * Bleah. Leftovers again. Stick the leftovers in + * the front of the queue, and goose the queue again. + */ + scsi_queue_next_request(q, SCpnt); return SCpnt; } /* @@ -323,6 +367,11 @@ Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors) up(req->sem); } add_blkdev_randomness(MAJOR(req->rq_dev)); + + /* + * This will goose the queue request function at the end, so we don't + * need to worry about launching another command. + */ scsi_release_command(SCpnt); return NULL; } @@ -351,6 +400,19 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, int this_count = SCpnt->bufflen >> 9; request_queue_t *q = &SCpnt->device->request_queue; + /* + * We must do one of several things here: + * + * Call scsi_end_request. This will finish off the specified + * number of sectors. If we are done, the command block will + * be released, and the queue function will be goosed. If we + * are not done, then scsi_end_request will directly goose + * the the queue. + * + * We can just use scsi_queue_next_request() here. This + * would be used if we just wanted to retry, for example. + * + */ ASSERT_LOCK(&io_request_lock, 0); /* @@ -417,7 +479,6 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, * rest of the command, or start a new one. */ if (result == 0) { - scsi_queue_next_request(q, SCpnt); return; } } @@ -446,13 +507,13 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, */ SCpnt->device->changed = 1; SCpnt = scsi_end_request(SCpnt, 0, this_count); - scsi_queue_next_request(q, SCpnt); return; } else { /* - * Must have been a power glitch, or a bus reset. - * Could not have been a media change, so we just retry - * the request and see what happens. + * Must have been a power glitch, or a + * bus reset. Could not have been a + * media change, so we just retry the + * request and see what happens. */ scsi_queue_next_request(q, SCpnt); return; @@ -469,11 +530,14 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, case ILLEGAL_REQUEST: if (SCpnt->device->ten) { SCpnt->device->ten = 0; + /* + * This will cause a retry with a 6-byte + * command. + */ scsi_queue_next_request(q, SCpnt); result = 0; } else { SCpnt = scsi_end_request(SCpnt, 0, this_count); - scsi_queue_next_request(q, SCpnt); return; } break; @@ -481,7 +545,6 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, printk(KERN_INFO "Device %x not ready.\n", SCpnt->request.rq_dev); SCpnt = scsi_end_request(SCpnt, 0, this_count); - scsi_queue_next_request(q, SCpnt); return; break; case MEDIUM_ERROR: @@ -492,7 +555,6 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, print_command(SCpnt->cmnd); print_sense("sd", SCpnt); SCpnt = scsi_end_request(SCpnt, 0, block_sectors); - scsi_queue_next_request(q, SCpnt); return; default: break; @@ -508,7 +570,6 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, if (driver_byte(result) & DRIVER_SENSE) print_sense("sd", SCpnt); SCpnt = scsi_end_request(SCpnt, 0, SCpnt->request.current_nr_sectors); - scsi_queue_next_request(q, SCpnt); return; } } @@ -603,7 +664,7 @@ void scsi_request_fn(request_queue_t * q) */ while (1 == 1) { /* - * If the host cannot accept another request, then quit. + * If the device cannot accept another request, then quit. */ if (SDpnt->device_blocked) { break; @@ -671,7 +732,7 @@ void scsi_request_fn(request_queue_t * q) */ recount_segments(SCpnt); } else { - SCpnt = scsi_allocate_device(SDpnt, FALSE); + SCpnt = scsi_allocate_device(SDpnt, FALSE, FALSE); } /* * If so, we are ready to do something. Bump the count @@ -786,28 +847,4 @@ void scsi_request_fn(request_queue_t * q) */ spin_lock_irq(&io_request_lock); } - - /* - * If this is a single-lun device, and we are currently finished - * with this device, then see if we need to get another device - * started. - */ - if (SDpnt->single_lun - && q->current_request == NULL - && SDpnt->device_busy == 0) { - request_queue_t *q; - - for (SDpnt = SHpnt->host_queue; - SDpnt; - SDpnt = SDpnt->next) { - if (((SHpnt->can_queue > 0) - && (SHpnt->host_busy >= SHpnt->can_queue)) - || (SHpnt->host_blocked) - || (SDpnt->device_blocked)) { - break; - } - q = &SDpnt->request_queue; - q->request_fn(q); - } - } } diff --git a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c index d19ba3d185b6..1cb59caa76b8 100644 --- a/drivers/scsi/scsi_merge.c +++ b/drivers/scsi/scsi_merge.c @@ -66,7 +66,6 @@ * Enable a bunch of additional consistency checking. Turn this off * if you are benchmarking. */ - static int dump_stats(struct request *req, int use_clustering, int dma_host, @@ -109,6 +108,40 @@ here: \ #define SANITY_CHECK(req, _CLUSTER, _DMA) #endif +static void dma_exhausted(Scsi_Cmnd * SCpnt, int i) +{ + int jj; + struct scatterlist *sgpnt; + int consumed = 0; + + sgpnt = (struct scatterlist *) SCpnt->request_buffer; + + /* + * Now print out a bunch of stats. First, start with the request + * size. + */ + printk("dma_free_sectors:%d\n", scsi_dma_free_sectors); + printk("use_sg:%d\ti:%d\n", SCpnt->use_sg, i); + printk("request_bufflen:%d\n", SCpnt->request_bufflen); + /* + * Now dump the scatter-gather table, up to the point of failure. + */ + for(jj=0; jj < SCpnt->use_sg; jj++) + { + printk("[%d]\tlen:%d\taddr:%p\talt:%p\n", + jj, + sgpnt[jj].length, + sgpnt[jj].address, + sgpnt[jj].alt_address); + if( sgpnt[jj].alt_address != NULL ) + { + consumed = (sgpnt[jj].length >> 9); + } + } + printk("Total %d sectors consumed\n", consumed); + panic("DMA pool exhausted"); +} + /* * FIXME(eric) - the original disk code disabled clustering for MOD * devices. I have no idea why we thought this was a good idea - my @@ -516,14 +549,15 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt, int use_clustering, int dma_host) { - struct buffer_head *bh; - struct buffer_head *bhprev; - char *buff; - int count; - int i; - struct request *req; - struct scatterlist *sgpnt; - int this_count; + struct buffer_head * bh; + struct buffer_head * bhprev; + char * buff; + int count; + int i; + struct request * req; + int sectors; + struct scatterlist * sgpnt; + int this_count; /* * FIXME(eric) - don't inline this - it doesn't depend on the @@ -647,21 +681,23 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt, */ SCpnt->request_bufflen = 0; for (i = 0; i < count; i++) { + sectors = (sgpnt[i].length >> 9); SCpnt->request_bufflen += sgpnt[i].length; if (virt_to_phys(sgpnt[i].address) + sgpnt[i].length - 1 > ISA_DMA_THRESHOLD) { - if( scsi_dma_free_sectors <= 10 ) { + if( scsi_dma_free_sectors - sectors <= 10 ) { /* - * If the DMA pool is nearly empty, then - * let's stop here. Don't make this request - * any larger. This is kind of a safety valve - * that we use - we could get screwed later on - * if we run out completely. + * If this would nearly drain the DMA + * pool, mpty, then let's stop here. + * Don't make this request any larger. + * This is kind of a safety valve that + * we use - we could get screwed later + * on if we run out completely. */ SCpnt->request_bufflen -= sgpnt[i].length; SCpnt->use_sg = i; if (i == 0) { - panic("DMA pool exhausted"); + goto big_trouble; } break; } @@ -678,7 +714,7 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt, SCpnt->request_bufflen -= sgpnt[i].length; SCpnt->use_sg = i; if (i == 0) { - panic("DMA pool exhausted"); + goto big_trouble; } break; } @@ -690,6 +726,63 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt, } return 1; + big_trouble: + /* + * We come here in the event that we get one humongous + * request, where we need a bounce buffer, and the buffer is + * more than we can allocate in a single call to + * scsi_malloc(). In addition, we only come here when it is + * the 0th element of the scatter-gather table that gets us + * into this trouble. As a fallback, we fall back to + * non-scatter-gather, and ask for a single segment. We make + * a half-hearted attempt to pick a reasonably large request + * size mainly so that we don't thrash the thing with + * iddy-biddy requests. + */ + + /* + * The original number of sectors in the 0th element of the + * scatter-gather table. + */ + sectors = sgpnt[0].length >> 9; + + /* + * Free up the original scatter-gather table. Note that since + * it was the 0th element that got us here, we don't have to + * go in and free up memory from the other slots. + */ + SCpnt->request_bufflen = 0; + SCpnt->use_sg = 0; + scsi_free(SCpnt->request_buffer, SCpnt->sglist_len); + + /* + * Make an attempt to pick up as much as we reasonably can. + * Just keep adding sectors until the pool starts running kind of + * low. The limit of 30 is somewhat arbitrary - the point is that + * it would kind of suck if we dropped down and limited ourselves to + * single-block requests if we had hundreds of free sectors. + */ + if( scsi_dma_free_sectors > 30 ) { + for (this_count = 0, bh = SCpnt->request.bh; + bh; bh = bh->b_reqnext) { + if( scsi_dma_free_sectors < 30 || this_count == sectors ) + { + break; + } + this_count += bh->b_size >> 9; + } + + } else { + /* + * Yow! Take the absolute minimum here. + */ + this_count = SCpnt->request.current_nr_sectors; + } + + /* + * Now drop through into the single-segment case. + */ + single_segment: /* * Come here if for any reason we choose to do this as a single @@ -713,7 +806,7 @@ __inline static int __init_io(Scsi_Cmnd * SCpnt, this_count = SCpnt->request.current_nr_sectors; buff = (char *) scsi_malloc(this_count << 9); if (!buff) { - panic("Unable to allocate DMA buffer\n"); + dma_exhausted(SCpnt, 0); } } if (SCpnt->request.cmd == WRITE) diff --git a/drivers/scsi/scsi_queue.c b/drivers/scsi/scsi_queue.c index 1c64977e9da7..22fef7c1e419 100644 --- a/drivers/scsi/scsi_queue.c +++ b/drivers/scsi/scsi_queue.c @@ -108,7 +108,6 @@ int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason) } } host->host_blocked = TRUE; - cmd->host_wait = TRUE; } else { /* * Protect against race conditions. If the device isn't busy, @@ -124,7 +123,6 @@ int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason) } } cmd->device->device_blocked = TRUE; - cmd->device_wait = TRUE; } /* diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8e72fd092e55..c82391a01d5b 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -705,7 +705,7 @@ static int sd_init_onedisk(int i) * just after a scsi bus reset. */ - SCpnt = scsi_allocate_device(rscsi_disks[i].device, 1); + SCpnt = scsi_allocate_device(rscsi_disks[i].device, 1, FALSE); buffer = (unsigned char *) scsi_malloc(512); @@ -950,7 +950,6 @@ static int sd_init_onedisk(int i) SCpnt->device->remap = 1; SCpnt->device->sector_size = sector_size; /* Wake up a process waiting for device */ - wake_up(&SCpnt->device->device_wait); scsi_release_command(SCpnt); SCpnt = NULL; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 8d467ceba33b..edcaa5fa5113 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -65,6 +65,7 @@ #include #include +static spinlock_t sg_request_lock = SPIN_LOCK_UNLOCKED; int sg_big_buff = SG_DEF_RESERVED_SIZE; /* sg_big_buff is ro through sysctl */ /* N.B. This global is here to keep existing software happy. It now holds @@ -432,9 +433,13 @@ static ssize_t sg_write(struct file * filp, const char * buf, } /* SCSI_LOG_TIMEOUT(7, printk("sg_write: allocating device\n")); */ if (! (SCpnt = scsi_allocate_device(sdp->device, - !(filp->f_flags & O_NONBLOCK)))) - { + !(filp->f_flags & O_NONBLOCK), + TRUE))) { sg_finish_rem_req(srp, NULL, 0); + if( signal_pending(current) ) + { + return -EINTR; + } return -EAGAIN; /* No available command blocks at the moment */ } /* SCSI_LOG_TIMEOUT(7, printk("sg_write: device allocated\n")); */ @@ -1043,7 +1048,7 @@ static void sg_detach(Scsi_Device * scsidp) continue; /* dirty but lowers nesting */ if (sdp->headfp) { /* Need to stop sg_command_done() playing with this list during this loop */ - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&sg_request_lock, flags); sfp = sdp->headfp; while (sfp) { srp = sfp->headrp; @@ -1054,7 +1059,7 @@ static void sg_detach(Scsi_Device * scsidp) } sfp = sfp->nextfp; } - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&sg_request_lock, flags); SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty, sleep(3)\n", k)); scsi_sleep(3); /* sleep 3 jiffies, hoping for timeout to go off */ } @@ -1114,9 +1119,9 @@ static void sg_shorten_timeout(Scsi_Cmnd * scpnt) scsi_add_timer(scpnt, scpnt->timeout_per_command, scsi_old_times_out); #else - spin_unlock_irq(&io_request_lock); + spin_unlock_irq(&sg_request_lock); scsi_sleep(HZ); /* just sleep 1 second and hope ... */ - spin_lock_irq(&io_request_lock); + spin_lock_irq(&sg_request_lock); #endif } diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index f196732bbae8..e34f5688af0a 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -486,7 +486,7 @@ void get_sectorsize(int i) buffer = (unsigned char *) scsi_malloc(512); - SCpnt = scsi_allocate_device(scsi_CDs[i].device, 1); + SCpnt = scsi_allocate_device(scsi_CDs[i].device, 1, FALSE); retries = 3; do { @@ -509,7 +509,6 @@ void get_sectorsize(int i) } while (the_result && retries); - wake_up(&SCpnt->device->device_wait); scsi_release_command(SCpnt); SCpnt = NULL; @@ -659,7 +658,7 @@ static int sr_packet(struct cdrom_device_info *cdi, struct cdrom_generic_command int buflen; /* get the device */ - SCpnt = scsi_allocate_device(device, 1); + SCpnt = scsi_allocate_device(device, 1, FALSE); if (SCpnt == NULL) return -ENODEV; /* this just doesn't seem right /axboe */ @@ -864,7 +863,7 @@ void cleanup_module(void) sr_hardsizes = NULL; } blksize_size[MAJOR_NR] = NULL; - hardsect_size[MAJOR_NR] = sr_hardsizes; + hardsect_size[MAJOR_NR] = NULL; blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blk_size[MAJOR_NR] = NULL; read_ahead[MAJOR_NR] = 0; diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index d3a649f4df36..5032d7f8662b 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -59,7 +59,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen char *bounce_buffer; SDev = scsi_CDs[target].device; - SCpnt = scsi_allocate_device(scsi_CDs[target].device, 1); + SCpnt = scsi_allocate_device(scsi_CDs[target].device, 1, FALSE); /* use ISA DMA buffer if necessary */ SCpnt->request.buffer = buffer; @@ -142,7 +142,6 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen } result = SCpnt->result; /* Wake up a process waiting for device */ - wake_up(&SCpnt->device->device_wait); scsi_release_command(SCpnt); SCpnt = NULL; return err; diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index dde365229aa7..7acf23741389 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -289,7 +289,7 @@ static Scsi_Cmnd * unsigned char *bp; if (SCpnt == NULL) - SCpnt = scsi_allocate_device(STp->device, 1); + SCpnt = scsi_allocate_device(STp->device, 1, FALSE); if (SCpnt == NULL) { printk(KERN_ERR "st%d: Can't get SCSI request.\n", TAPE_NR(STp->devt)); diff --git a/drivers/usb/ohci-hcd.c b/drivers/usb/ohci-hcd.c index bd034b4f83fd..6072e060e1d6 100644 --- a/drivers/usb/ohci-hcd.c +++ b/drivers/usb/ohci-hcd.c @@ -47,19 +47,16 @@ #include #include -#define DEBUG +// #define DEBUG #include "usb.h" #include "ohci-hcd.h" #ifdef DEBUG - #define dbg printk + #define dbg(format, arg...) printk(format, ## arg) #else - #define dbg __xxx -static void __xxx (const char *format, ...) -{ -} + #define dbg(format, arg...) #endif #ifdef CONFIG_APM @@ -589,6 +586,7 @@ static int ep_link (ohci_t * ohci, ed_t * edi) case ISO: ed->hwNextED = 0; + ed->int_interval = 1; if (ohci->ed_isotail != NULL) { ohci->ed_isotail->hwNextED = cpu_to_le32 (virt_to_bus (ed)); ed->ed_prev = ohci->ed_isotail; @@ -803,7 +801,7 @@ static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int t urb_priv_t * urb_priv = urb->hcpriv; if (index >= urb_priv->length) { - printk(KERN_ERR MODSTR "internal OHCI error: TD index > length\n"); + printk (KERN_ERR MODSTR "internal OHCI error: TD index > length\n"); return; } @@ -930,7 +928,7 @@ static td_t * dl_reverse_done_list (ohci_t * ohci) td_list->ed->hwHeadP = (urb_priv->td[urb_priv->length - 1]->hwNextTD & cpu_to_le32 (0xfffffff0)) | (td_list->ed->hwHeadP & cpu_to_le32 (0x2)); - urb_priv->td_cnt = urb_priv->length - 1; + urb_priv->td_cnt += urb_priv->length - td_list->index - 1; } else td_list->ed->hwHeadP &= cpu_to_le32 (0xfffffff2); } @@ -1072,7 +1070,7 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list) if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN)) cc = TD_CC_NOERROR; if (++(urb_priv->td_cnt) == urb_priv->length) { - if (urb_priv->state != URB_DEL) { + if (urb_priv->state != URB_DEL && !(ed->state & ED_DEL) && ed->state != ED_NEW) { urb->status = cc_to_error[cc]; sohci_return_urb (urb); } else { @@ -1136,7 +1134,7 @@ static __u8 root_hub_config_des[] = 0x01, /* __u8 bConfigurationValue; */ 0x00, /* __u8 iConfiguration; */ 0x40, /* __u8 bmAttributes; - Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ + Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ 0x00, /* __u8 MaxPower; */ /* interface */ diff --git a/drivers/usb/proc_usb.c b/drivers/usb/proc_usb.c index 4bf0b999a1da..c0f11bfc9258 100644 --- a/drivers/usb/proc_usb.c +++ b/drivers/usb/proc_usb.c @@ -72,8 +72,8 @@ #define ALLOW_SERIAL_NUMBER static char *format_topo = -/* T: Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ - "T: Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; +/* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ + "T: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; static char *format_string_manufacturer = /* S: Manufacturer=xxxx */ @@ -396,7 +396,7 @@ static char *usb_dump_string(char *start, char *end, const struct usb_device *de /*****************************************************************/ static char *usb_device_dump(char *start, char *end, const struct usb_device *usbdev, - int level, int index, int count) + int bus, int level, int index, int count) { int chix; int cnt = 0; @@ -410,7 +410,7 @@ static char *usb_device_dump(char *start, char *end, const struct usb_device *us * So the root hub's parent is 0 and any device that is * plugged into the root hub has a parent of 0. */ - start += sprintf(start, format_topo, level, parent_devnum, index, count, + start += sprintf(start, format_topo, bus, level, parent_devnum, index, count, usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild); /* * level = topology-tier level; @@ -428,7 +428,7 @@ static char *usb_device_dump(char *start, char *end, const struct usb_device *us if (start > end) return start; if (usbdev->children[chix]) - start = usb_device_dump(start, end, usbdev->children[chix], level + 1, chix, ++cnt); + start = usb_device_dump(start, end, usbdev->children[chix], bus, level + 1, chix, ++cnt); } return start; } @@ -440,6 +440,7 @@ static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff char *page, *end; ssize_t ret = 0; unsigned int pos, len; + int busnum = 0; if (*ppos < 0) return -EINVAL; @@ -452,13 +453,13 @@ static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff pos = *ppos; usb_bus_list = usb_bus_get_list(); /* enumerate busses */ - for (buslist = usb_bus_list->next; buslist != usb_bus_list; buslist = buslist->next) { + for (buslist = usb_bus_list->next; buslist != usb_bus_list; buslist = buslist->next, ++busnum) { /* print bandwidth allocation */ bus = list_entry(buslist, struct usb_bus, bus_list); len = sprintf(page, format_bandwidth, bus->bandwidth_allocated, FRAME_TIME_MAX_USECS_ALLOC, (100 * bus->bandwidth_allocated + FRAME_TIME_MAX_USECS_ALLOC / 2) / FRAME_TIME_MAX_USECS_ALLOC, bus->bandwidth_int_reqs, bus->bandwidth_isoc_reqs); - end = usb_device_dump(page + len, page + (PAGE_SIZE - 100), bus->root_hub, 0, 0, 0); + end = usb_device_dump(page + len, page + (PAGE_SIZE - 100), bus->root_hub, busnum, 0, 0, 0); len = end - page; if (len > pos) { len -= pos; diff --git a/drivers/usb/usb_scsi.c b/drivers/usb/usb_scsi.c index dd0597df8e70..bd33fa812965 100644 --- a/drivers/usb/usb_scsi.c +++ b/drivers/usb/usb_scsi.c @@ -242,10 +242,13 @@ static int pop_CBI_irq(int state, void *buffer, int len, void *dev_id) { struct us_data *us = (struct us_data *)dev_id; + US_DEBUGP("pop_CBI_irq() called!!\n"); + if (state != USB_ST_REMOVED) { us->ip_data = le16_to_cpup((__u16 *)buffer); - /* US_DEBUGP("Interrupt Status %x\n", us->ip_data); */ + US_DEBUGP("Interrupt Status %x\n", us->ip_data); } + if (us->ip_wanted) { us->ip_wanted = 0; wake_up(&us->ip_waitq); @@ -289,13 +292,13 @@ static int pop_CB_command(Scsi_Cmnd *srb) int retry = 5; int done_start = 0; + /* we'll try this up to 5 times? */ while (retry--) { - if (us->flags & US_FL_FIXED_COMMAND) { memset(cmd, 0, us->fixedlength); - + /* fix some commands */ - + switch (srb->cmnd[0]) { case WRITE_6: case READ_6: @@ -321,37 +324,52 @@ static int pop_CB_command(Scsi_Cmnd *srb) us->mode_xlate = 0; memcpy(cmd, srb->cmnd, srb->cmd_len); break; - } + } /* switch */ + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE, 0, us->ifnum, cmd, us->fixedlength, HZ*5); - if (!done_start && (us->subclass == US_SC_UFI /*|| us->subclass == US_SC_8070*/) - && cmd[0] == TEST_UNIT_READY && result) { + US_DEBUGP("First usb_control_msg returns %d\n", result); + + /* For UFI, if this is the first time we've sent this TEST_UNIT_READY + * command, we can try again + */ + if (!done_start && (us->subclass == US_SC_UFI) + && (cmd[0] == TEST_UNIT_READY) && (result < 0)) { + /* as per spec try a start command, wait and retry */ + wait_ms(100); done_start++; memset(cmd, 0, sizeof(cmd)); cmd[0] = START_STOP; cmd[4] = 1; /* start */ + result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), - US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE, + US_CBI_ADSC, + USB_TYPE_CLASS | USB_RT_INTERFACE, 0, us->ifnum, cmd, us->fixedlength, HZ*5); - wait_ms(100); + US_DEBUGP("Next usb_control_msg returns %d\n", result); + + /* allow another retry */ retry++; continue; } - } else { + } else { /* !US_FL_FIXED_COMMAND */ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0), US_CBI_ADSC, USB_TYPE_CLASS | USB_RT_INTERFACE, 0, us->ifnum, srb->cmnd, srb->cmd_len, HZ*5); } + + /* return an answer if we've got one */ if (/*result != USB_ST_STALL &&*/ result != USB_ST_TIMEOUT) return result; } + /* all done -- return our status */ return result; } @@ -396,20 +414,14 @@ static int pop_CB_status(Scsi_Cmnd *srb) /* add interrupt transfer, marked for removal */ us->ip_wanted = 1; - us->irqpipe = usb_rcvintpipe(us->pusb_dev, us->ep_int); - result = usb_request_irq(us->pusb_dev, us->irqpipe, pop_CBI_irq, - IRQ_PERIOD, (void *)us, &us->irq_handle); - if (result) { - US_DEBUGP("usb_request_irq failed (0x%x), No interrupt for CBI\n", - result); - return DID_ABORT << 16; - } + /* go to sleep until we get this interrup */ sleep_on(&us->ip_waitq); -#ifdef REWRITE_PROJECT - usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe); - us->irq_handle = NULL; -#endif + + /* NO! We don't release this IRQ. We just re-use the handler + usb_release_irq(us->pusb_dev, us->irq_handle, us->irqpipe); + us->irq_handle = NULL; + */ if (us->ip_wanted) { US_DEBUGP("Did not get interrupt on CBI\n"); @@ -445,10 +457,12 @@ static int pop_CBI(Scsi_Cmnd *srb) { int result; - /* run the command */ + US_DEBUGP("CBI gets a command:\n"); + us_show_command(srb); - if ((result = pop_CB_command(srb))) { - US_DEBUGP("CBI command %x\n", result); + /* run the command */ + if ((result = pop_CB_command(srb)) < 0) { + US_DEBUGP("Call to pop_CB_command returned %d\n", result); if (result == USB_ST_STALL || result == USB_ST_TIMEOUT) { return (DID_OK << 16) | 2; } @@ -456,11 +470,12 @@ static int pop_CBI(Scsi_Cmnd *srb) } /* transfer the data */ - if (us_transfer_length(srb)) { result = us_transfer(srb, US_DIRECTION(srb->cmnd[0])); - if (result && result != USB_ST_DATAUNDERRUN && result != USB_ST_STALL) { - US_DEBUGP("CBI transfer %x\n", result); + if ((result < 0) && + (result != USB_ST_DATAUNDERRUN) && + (result != USB_ST_STALL)) { + US_DEBUGP("CBI attempted to transfer data, result is %x\n", result); return DID_ERROR << 16; } #if 0 @@ -625,7 +640,8 @@ static int us_detect(struct SHT *sht) /* odd... didn't register properly. Abort and free pointers */ kfree(sht->proc_name); - sht->proc_name = sht->name = NULL; + sht->proc_name = NULL; + sht->name = NULL; return 0; } @@ -702,55 +718,80 @@ static int us_host_reset( Scsi_Cmnd *srb ) return 0; } +/*********************************************************************** + * /proc/scsi/ functions + ***********************************************************************/ + +/* we use this macro to help us write into the buffer */ #undef SPRINTF -#define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } +#define SPRINTF(args...) do { if (pos < (buffer + length)) pos += sprintf (pos, ## args); } while (0) -int usb_scsi_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout) +int usb_scsi_proc_info (char *buffer, char **start, off_t offset, + int length, int hostno, int inout) { struct us_data *us = us_list; char *pos = buffer; - char *vendor; - char *product; - char *style = ""; + char *tmp_ptr; /* find our data from hostno */ - while (us) { if (us->host_no == hostno) break; us = us->next; } + /* if we couldn't find it, we return an error */ if (!us) return -ESRCH; - /* null on outward */ - + /* if someone is sending us data, just throw it away */ if (inout) return length; - if (!us->pusb_dev || !(vendor = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer))) - vendor = "?"; - if (!us->pusb_dev || !(product = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct))) - product = "?"; + /* print the controler name */ + SPRINTF ("Host scsi%d: usb-scsi\n", hostno); + + /* print product and vendor strings */ + if (!us->pusb_dev) { + SPRINTF("Vendor: Unknown Vendor\n"); + SPRINTF("Product: Unknown Product\n"); + } else { + SPRINTF("Vendor: "); + tmp_ptr = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iManufacturer); + if (!tmp_ptr) + SPRINTF("Unknown Vendor\n"); + else + SPRINTF("%s\n", tmp_ptr); + + SPRINTF("Product: "); + tmp_ptr = usb_string(us->pusb_dev, us->pusb_dev->descriptor.iProduct); + if (!tmp_ptr) + SPRINTF("Unknown Vendor\n"); + else + SPRINTF("%s\n", tmp_ptr); + } + SPRINTF("Protocol: "); switch (us->protocol) { case US_PR_CB: - style = "Control/Bulk"; + SPRINTF("Control/Bulk\n"); break; - + case US_PR_CBI: - style = "Control/Bulk/Interrupt"; + SPRINTF("Control/Bulk/Interrupt\n"); break; - - case US_PR_ZIP: - style = "Bulk only"; + + case US_PR_BULK: + SPRINTF("Bulk only\n"); + break; + + default: + SPRINTF("Unknown Protocol\n"); break; - } - SPRINTF ("Host scsi%d: usb-scsi\n", hostno); - SPRINTF ("Device: %s %s - GUID " GUID_FORMAT "\n", vendor, product, GUID_ARGS(us->guid) ); - SPRINTF ("Style: %s\n", style); + + /* show the GUID of the device */ + SPRINTF("GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid)); /* * Calculate start of next buffer, and return value. @@ -824,7 +865,6 @@ static int usbscsi_control_thread(void * __us) { struct us_data *us = (struct us_data *)__us; int action; - int i; lock_kernel(); @@ -1038,6 +1078,10 @@ static int usbscsi_control_thread(void * __us) us->srb->request_bufflen = savelen; switch (us->srb->cmnd[0]) { case INQUIRY: + if ((((unsigned char*)us->srb->request_buffer)[2] & 0x7) == 0) { + US_DEBUGP("Fixing INQUIRY data, setting SCSI rev to 2\n"); + ((unsigned char*)us->srb->request_buffer)[2] |= 2; + } /* FALL THROUGH */ case REQUEST_SENSE: case MODE_SENSE: @@ -1126,7 +1170,7 @@ static int usbscsi_control_thread(void * __us) } } - MOD_DEC_USE_COUNT; + // MOD_DEC_USE_COUNT; printk("usbscsi_control_thread exiting\n"); @@ -1257,7 +1301,7 @@ static void * scsi_probe(struct usb_device *dev, unsigned int ifnum) } /* set the handler pointers based on the protocol */ - US_DEBUGP("Protocol "); + US_DEBUGP("Protocol: "); switch (ss->protocol) { case US_PR_CB: US_DEBUGPX("Control/Bulk\n"); @@ -1271,14 +1315,14 @@ static void * scsi_probe(struct usb_device *dev, unsigned int ifnum) ss->pop_reset = pop_CB_reset; break; - case US_PR_ZIP: + case US_PR_BULK: US_DEBUGPX("Bulk\n"); ss->pop = pop_Bulk; ss->pop_reset = pop_Bulk_reset; break; default: - US_DEBUGPX("Oh Crap! I don't understand this protocol!"); + US_DEBUGPX("Unknown\n"); kfree(ss); return NULL; break; @@ -1327,15 +1371,6 @@ static void * scsi_probe(struct usb_device *dev, unsigned int ifnum) return NULL; } - /* If there are configuration or interface strings, let's show them */ - if (dev->actconfig->iConfiguration && - usb_string(dev, dev->actconfig->iConfiguration)) - US_DEBUGP("Configuration %s\n", - usb_string(dev, dev->actconfig->iConfiguration)); - if (interface->iInterface && usb_string(dev, interface->iInterface)) - US_DEBUGP("Interface %s\n", - usb_string(dev, interface->iInterface)); - /* If this is a new device (i.e. we haven't seen it before), we need to * generate a scsi host definition, and register with scsi above us */ @@ -1345,7 +1380,7 @@ static void * scsi_probe(struct usb_device *dev, unsigned int ifnum) memcpy(ss->guid, guid, sizeof(guid)); /* set class specific stuff */ - US_DEBUGP("SubClass "); + US_DEBUGP("SubClass: "); switch (ss->subclass) { case US_SC_RBC: US_DEBUGPX("Reduced Block Commands\n"); @@ -1370,13 +1405,13 @@ static void * scsi_probe(struct usb_device *dev, unsigned int ifnum) break; case US_SC_UFI: - US_DEBUGPX(" UFF\n"); + US_DEBUGPX("UFI\n"); ss->flags |= US_FL_FIXED_COMMAND; ss->fixedlength = 12; break; default: - US_DEBUGPX(" Unknown\n"); + US_DEBUGPX("Unknown\n"); break; } @@ -1430,8 +1465,23 @@ static void * scsi_probe(struct usb_device *dev, unsigned int ifnum) #endif } else if (ss->protocol == US_PR_CBI) + { + int result; + init_waitqueue_head(&ss->ip_waitq); + /* set up the IRQ pipe and handler */ + /* FIXME: This needs to get the period from the device */ + ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int); + result = usb_request_irq(ss->pusb_dev, ss->irqpipe, pop_CBI_irq, + 255, (void *)ss, &ss->irq_handle); + if (result) { + US_DEBUGP("usb_request_irq failed (0x%x), No interrupt for CBI\n", + result); + } + } + + /* start up our thread */ { DECLARE_MUTEX_LOCKED(sem); @@ -1482,7 +1532,7 @@ static void scsi_disconnect(struct usb_device *dev, void *ptr) if (ss->filter) ss->filter->release(ss->fdata); ss->pusb_dev = NULL; - MOD_DEC_USE_COUNT; + // MOD_DEC_USE_COUNT; } @@ -1492,7 +1542,7 @@ static void scsi_disconnect(struct usb_device *dev, void *ptr) int usb_scsi_init(void) { - MOD_INC_USE_COUNT; + // MOD_INC_USE_COUNT; if (usb_register(&scsi_driver) < 0) return -1; diff --git a/drivers/usb/usb_scsi.h b/drivers/usb/usb_scsi.h index f777378a6052..7f4b5a4dad1f 100644 --- a/drivers/usb/usb_scsi.h +++ b/drivers/usb/usb_scsi.h @@ -47,8 +47,7 @@ extern unsigned char us_direction[256/8]; #define US_PR_CB 1 /* Control/Bulk w/o interrupt */ #define US_PR_CBI 0 /* Control/Bulk/Interrupt */ -#define US_PR_ZIP 0x50 /* bulk only */ -/* #define US_PR_BULK ?? */ +#define US_PR_BULK 0x50 /* bulk only */ /* * Bulk only data structures (Zip 100, for example) diff --git a/drivers/usb/uss720.c b/drivers/usb/uss720.c index 3e7870acfc2f..f594b079563e 100644 --- a/drivers/usb/uss720.c +++ b/drivers/usb/uss720.c @@ -363,7 +363,7 @@ static size_t parport_uss720_epp_write_data(struct parport *pp, const void *buf, return 0; if (change_mode(pp, ECR_EPP)) return 0; - i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buf, length, &rlen, HZ*20); + i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buf, length, &rlen, HZ*20); if (i) printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buf, length, rlen); change_mode(pp, ECR_PS2); @@ -424,7 +424,7 @@ static size_t parport_uss720_ecp_write_data(struct parport *pp, const void *buff return 0; if (change_mode(pp, ECR_ECP)) return 0; - i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buffer, len, &rlen, HZ*20); + i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buffer, len, &rlen, HZ*20); if (i) printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buffer, len, rlen); change_mode(pp, ECR_PS2); @@ -442,7 +442,7 @@ static size_t parport_uss720_ecp_read_data(struct parport *pp, void *buffer, siz return 0; if (change_mode(pp, ECR_ECP)) return 0; - i = usbdev->bus->op->bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, HZ*20); + i = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, HZ*20); if (i) printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %u rlen %lu\n", buffer, len, rlen); change_mode(pp, ECR_PS2); @@ -475,7 +475,7 @@ static size_t parport_uss720_write_compat(struct parport *pp, const void *buffer return 0; if (change_mode(pp, ECR_PPF)) return 0; - i = usbdev->bus->op->bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buffer, len, &rlen, HZ*20); + i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), buffer, len, &rlen, HZ*20); if (i) printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %u rlen %lu\n", buffer, len, rlen); change_mode(pp, ECR_PS2); diff --git a/fs/buffer.c b/fs/buffer.c index 6bf84ca27fb5..48dfff066128 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -727,8 +727,7 @@ static void end_buffer_io_async(struct buffer_head * bh, int uptodate) atomic_dec(&bh->b_count); tmp = bh->b_this_page; while (tmp != bh) { - if (atomic_read(&tmp->b_count) && - (tmp->b_end_io == end_buffer_io_async)) + if (tmp->b_end_io == end_buffer_io_async && buffer_locked(tmp)) goto still_busy; tmp = tmp->b_this_page; } @@ -1089,7 +1088,7 @@ static struct buffer_head * get_unused_buffer_head(int async) return NULL; } -void set_bh_page (struct buffer_head *bh, struct page *page, unsigned int offset) +void set_bh_page (struct buffer_head *bh, struct page *page, unsigned long offset) { bh->b_page = page; if (offset >= PAGE_SIZE) diff --git a/fs/exec.c b/fs/exec.c index e329252d19dc..40b4ae2afd9f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -42,14 +42,6 @@ #include #endif -/* - * Here are the actual binaries that will be accepted: - * add more with "register_binfmt()" if using modules... - * - * These are defined again for the 'real' modules if you are using a - * module definition for these routines. - */ - static struct linux_binfmt *formats = (struct linux_binfmt *) NULL; int register_binfmt(struct linux_binfmt * fmt) diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 628c0bb9c0ef..c31d02024cb3 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -10,6 +10,7 @@ * VFAT extensions by Gordon Chaffee * Merged with msdos fs by Henrik Storner * Rewritten for constant inumbers. Plugged buffer overrun in readdir(). AV + * Short name translation 1999 by Wolfram Pienkoss */ #define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S)) @@ -55,22 +56,21 @@ struct file_operations fat_dir_operations = { /* * Convert Unicode 16 to UTF8, translated Unicode, or ASCII. - * If uni_xlate is enabled and we - * can't get a 1:1 conversion, use a colon as an escape character since - * it is normally invalid on the vfat filesystem. The following three - * characters are a sort of uuencoded 16 bit Unicode value. This lets - * us do a full dump and restore of Unicode filenames. We could get - * into some trouble with long Unicode names, but ignore that right now. + * If uni_xlate is enabled and we can't get a 1:1 conversion, use a + * colon as an escape character since it is normally invalid on the vfat + * filesystem. The following four characters are the hexadecimal digits + * of Unicode value. This lets us do a full dump and restore of Unicode + * filenames. We could get into some trouble with long Unicode names, + * but ignore that right now. * Ahem... Stack smashing in ring 0 isn't fun. Fixed. */ static int uni16_to_x8(unsigned char *ascii, unsigned char *uni, int uni_xlate, struct nls_table *nls) { - unsigned char *ip, *op; - unsigned char ch, cl; - unsigned char *uni_page; - unsigned short val; + unsigned char *ip, *op, *uni_page, ch, cl, nc; + unsigned int ec; + int k; ip = uni; op = ascii; @@ -84,14 +84,15 @@ uni16_to_x8(unsigned char *ascii, unsigned char *uni, int uni_xlate, *op++ = uni_page[cl]; } else { if (uni_xlate == 1) { - *op++ = ':'; - val = (cl << 8) + ch; - op[2] = fat_uni2esc[val & 0x3f]; - val >>= 6; - op[1] = fat_uni2esc[val & 0x3f]; - val >>= 6; - *op = fat_uni2esc[val & 0x3f]; - op += 3; + *op = ':'; + ec = (ch << 8) + cl; + for (k = 4; k > 0; k--) { + nc = ec & 0xF; + op[k] = nc > 9 ? nc + ('a' - 10) + : nc + '0'; + ec >>= 4; + } + op += 5; } else { *op++ = '?'; } @@ -119,8 +120,31 @@ static void dump_de(struct msdos_dir_entry *de) printk("]\n"); } #endif -static int memicmp(const char *s1, const char *s2, int len) { - while(len--) if (tolower(*s1++)!=tolower(*s2++)) return 1; + +static inline unsigned char +fat_tolower(struct nls_table *t, unsigned char c) +{ + unsigned char nc = t->charset2lower[c]; + + return nc ? nc : c; +} + +static inline struct nls_unicode +fat_short2lower_uni(struct nls_table *t, unsigned char c) +{ + unsigned char nc = t->charset2lower[c]; + + return nc ? t->charset2uni[nc] : t->charset2uni[c]; +} + +static int +fat_strnicmp(struct nls_table *t, const unsigned char *s1, + const unsigned char *s2, int len) +{ + while(len--) + if (fat_tolower(t, *s1++) != fat_tolower(t, *s2++)) + return 1; + return 0; } @@ -128,23 +152,21 @@ static int memicmp(const char *s1, const char *s2, int len) { * Return values: negative -> error, 0 -> not found, positive -> found, * value is the total amount of slots, including the shortname entry. */ -int fat_search_long( - struct inode *inode, const char *name, int name_len, int anycase, - loff_t *spos, loff_t *lpos) +int fat_search_long(struct inode *inode, const char *name, int name_len, + int anycase, loff_t *spos, loff_t *lpos) { struct super_block *sb = inode->i_sb; - int ino,i,i2,last; - char c; struct buffer_head *bh = NULL; struct msdos_dir_entry *de; - loff_t cpos = 0; - char bufname[14]; - unsigned char long_slots; + struct nls_table *nls_io = MSDOS_SB(sb)->nls_io; + struct nls_table *nls_disk = MSDOS_SB(sb)->nls_disk; + struct nls_unicode bufuname[14]; + unsigned char xlate_len, long_slots, *unicode = NULL; + char c, bufname[260]; /* 256 + 4 */ int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate; int utf8 = MSDOS_SB(sb)->options.utf8; - unsigned char *unicode = NULL; - struct nls_table *nls = MSDOS_SB(sb)->nls_io; - int res = 0; + int ino, i, i2, last, res = 0; + loff_t cpos = 0; while(1) { if (fat_get_entry(inode,&cpos,&bh,&de,&ino) == -1) @@ -157,7 +179,7 @@ parse_record: continue; if (de->attr != ATTR_EXT && IS_FREE(de->name)) continue; - if (de->attr == ATTR_EXT) { + if (de->attr == ATTR_EXT) { struct msdos_dir_slot *ds; int offset; unsigned char id; @@ -226,36 +248,42 @@ parse_long: for (i = 0, last = 0; i < 8;) { if (!(c = de->name[i])) break; - if (c >= 'A' && c <= 'Z') c += 32; if (c == 0x05) c = 0xE5; - if ((bufname[i++] = c) != ' ') + bufuname[i++] = fat_short2lower_uni(nls_disk, c); + if (c != ' ') last = i; } i = last; - bufname[i++] = '.'; + bufuname[i++] = fat_short2lower_uni(nls_disk, '.'); for (i2 = 0; i2 < 3; i2++) { if (!(c = de->ext[i2])) break; - if (c >= 'A' && c <= 'Z') c += 32; - if ((bufname[i++] = c) != ' ') + bufuname[i++] = fat_short2lower_uni(nls_disk, c); + if (c != ' ') last = i; } if (!last) continue; - if (last==name_len) - if ((!anycase && !memcmp(name, bufname, last)) || - (anycase && !memicmp(name, bufname, last))) - goto Found; + memset(&bufuname[last], 0, sizeof(struct nls_unicode)); + xlate_len = utf8 + ?utf8_wcstombs(bufname, (__u16 *) &bufuname, 260) + :uni16_to_x8(bufname, (unsigned char *) &bufuname, + uni_xlate, nls_io); + if (xlate_len == name_len) + if ((!anycase && !memcmp(name, bufname, xlate_len)) || + (anycase && !fat_strnicmp(nls_io, name, bufname, + xlate_len))) + goto Found; + if (long_slots) { - char longname[260]; /* 256 + 4 */ - unsigned char long_len; - long_len = utf8 - ?utf8_wcstombs(longname, (__u16 *) unicode, 260) - :uni16_to_x8(longname, unicode, uni_xlate, nls); - if (long_len != name_len) + xlate_len = utf8 + ?utf8_wcstombs(bufname, (__u16 *) unicode, 260) + :uni16_to_x8(bufname, unicode, uni_xlate, nls_io); + if (xlate_len != name_len) continue; - if ((!anycase && !memcmp(name, longname, long_len)) || - (anycase && !memicmp(name, longname, long_len))) + if ((!anycase && !memcmp(name, bufname, xlate_len)) || + (anycase && !fat_strnicmp(nls_io, name, bufname, + xlate_len))) goto Found; } } @@ -272,31 +300,23 @@ EODir: return res; } -static int fat_readdirx( - struct inode *inode, - struct file *filp, - void *dirent, - filldir_t filldir, - int shortnames, - int both) +static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent, + filldir_t filldir, int shortnames, int both) { struct super_block *sb = inode->i_sb; - int ino,inum,i,i2,last; - char c; struct buffer_head *bh; struct msdos_dir_entry *de; - unsigned long lpos; - loff_t cpos; - unsigned char long_slots; + struct nls_table *nls_io = MSDOS_SB(sb)->nls_io; + struct nls_table *nls_disk = MSDOS_SB(sb)->nls_disk; + struct nls_unicode bufuname[14], *ptuname = &bufuname[0]; + unsigned char long_slots, *unicode = NULL; + char c, bufname[56], *ptname = bufname; + unsigned long lpos, dummy, *furrfu = &lpos; int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate; + int isvfat = MSDOS_SB(sb)->options.isvfat; int utf8 = MSDOS_SB(sb)->options.utf8; - unsigned char *unicode = NULL; - struct nls_table *nls = MSDOS_SB(sb)->nls_io; - char bufname[14]; - char *ptname = bufname; - int dotoffset = 0; - unsigned long *furrfu = &lpos; - unsigned long dummy; + int ino,inum,i,i2,last, dotoffset = 0; + loff_t cpos; cpos = filp->f_pos; /* Fake . and .. for the root directory. */ @@ -322,7 +342,7 @@ GetNew: if (fat_get_entry(inode,&cpos,&bh,&de,&ino) == -1) goto EODir; /* Check for long filename entry */ - if (MSDOS_SB(sb)->options.isvfat) { + if (isvfat) { if (de->name[0] == (__s8) DELETED_FLAG) goto RecEnd; if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME)) @@ -334,7 +354,7 @@ GetNew: goto RecEnd; } - if (MSDOS_SB(sb)->options.isvfat && de->attr == ATTR_EXT) { + if (isvfat && de->attr == ATTR_EXT) { struct msdos_dir_slot *ds; int offset; unsigned char id; @@ -403,23 +423,27 @@ ParseLong: } if ((de->attr & ATTR_HIDDEN) && MSDOS_SB(sb)->options.dotsOK) { + *ptuname = fat_short2lower_uni(nls_disk, '.'); *ptname++ = '.'; dotoffset = 1; } for (i = 0, last = 0; i < 8;) { if (!(c = de->name[i])) break; - if (c >= 'A' && c <= 'Z') c += 32; /* see namei.c, msdos_format_name */ if (c == 0x05) c = 0xE5; - if ((ptname[i++] = c) != ' ') + ptuname[i] = fat_short2lower_uni(nls_disk, c); + ptname[i++] = (c>='A' && c<='Z') ? c+32 : c; + if (c != ' ') last = i; } i = last; + ptuname[i] = fat_short2lower_uni(nls_disk, '.'); ptname[i++] = '.'; for (i2 = 0; i2 < 3; i2++) { if (!(c = de->ext[i2])) break; - if (c >= 'A' && c <= 'Z') c += 32; - if ((ptname[i++] = c) != ' ') + ptuname[i] = fat_short2lower_uni(nls_disk, c); + ptname[i++] = (c>='A' && c<='Z') ? c+32 : c; + if (c != ' ') last = i; } if (!last) @@ -442,6 +466,13 @@ ParseLong: inum = iunique(sb, MSDOS_ROOT_INO); } + if (isvfat) { + memset(&bufuname[i], 0, sizeof(struct nls_unicode)); + i = utf8 ? utf8_wcstombs(bufname, (__u16 *) &bufuname, 56) + : uni16_to_x8(bufname, (unsigned char *) &bufuname, + uni_xlate, nls_io); + } + if (!long_slots||shortnames) { if (both) bufname[i] = '\0'; @@ -451,7 +482,7 @@ ParseLong: char longname[275]; unsigned char long_len = utf8 ? utf8_wcstombs(longname, (__u16 *) unicode, 275) - : uni16_to_x8(longname, unicode, uni_xlate, nls); + : uni16_to_x8(longname, unicode, uni_xlate, nls_io); if (both) { memcpy(&longname[long_len+1], bufname, i); long_len += i; diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 033c40c2b273..3919f651766d 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -653,13 +653,13 @@ fat_read_super(struct super_block *sb, void *data, int silent, if (sbi->options.isvfat && !opts.utf8) { p = opts.iocharset ? opts.iocharset : "iso8859-1"; sbi->nls_io = load_nls(p); - if (! sbi->nls_io) { + if (! sbi->nls_io) /* Fail only if explicit charset specified */ if (opts.iocharset) goto out_unload_nls; - sbi->nls_io = load_nls_default(); - } } + if (! sbi->nls_io) + sbi->nls_io = load_nls_default(); root_inode=get_empty_inode(); if (!root_inode) @@ -681,8 +681,7 @@ fat_read_super(struct super_block *sb, void *data, int silent, out_no_root: printk("get root inode failed\n"); iput(root_inode); - if (sbi->nls_io) - unload_nls(sbi->nls_io); + unload_nls(sbi->nls_io); out_unload_nls: unload_nls(sbi->nls_disk); goto out_fail; diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 84aa2ec3069b..d6649bdecdb3 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -927,7 +927,8 @@ static int isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz) int isofs_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create) { - off_t b_off, offset, sect_size; + unsigned long b_off; + unsigned offset, sect_size; unsigned int firstext; unsigned long nextino; int i, err; @@ -942,30 +943,21 @@ int isofs_get_block(struct inode *inode, long iblock, if (iblock < 0) goto abort_negative; - b_off = iblock << ISOFS_BUFFER_BITS(inode); + b_off = iblock; - /* If we are beyond the end of this file, don't give out any - * blocks. + /* If we are *way* beyond the end of the file, print a message. + * Access beyond the end of the file up to the next page boundary + * is normal, however because of the way the page cache works. + * In this case, we just return 0 so that we can properly fill + * the page with useless information without generating any + * I/O errors. */ - if (b_off > inode->i_size) { - off_t max_legal_read_offset; - - /* If we are *way* beyond the end of the file, print a message. - * Access beyond the end of the file up to the next page boundary - * is normal, however because of the way the page cache works. - * In this case, we just return 0 so that we can properly fill - * the page with useless information without generating any - * I/O errors. - */ - max_legal_read_offset = (inode->i_size + PAGE_SIZE - 1) - & ~(PAGE_SIZE - 1); - if (b_off >= max_legal_read_offset) - goto abort_beyond_end; - } + if (b_off > ((inode->i_size + PAGE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode))) + goto abort_beyond_end; offset = 0; firstext = inode->u.isofs_i.i_first_extent; - sect_size = inode->u.isofs_i.i_section_size; + sect_size = inode->u.isofs_i.i_section_size >> ISOFS_BUFFER_BITS(inode); nextino = inode->u.isofs_i.i_next_section_ino; i = 0; @@ -990,8 +982,7 @@ int isofs_get_block(struct inode *inode, long iblock, } bh_result->b_dev = inode->i_dev; - bh_result->b_blocknr = firstext + - ((b_off - offset) >> ISOFS_BUFFER_BITS(inode)); + bh_result->b_blocknr = firstext + b_off - offset; bh_result->b_state |= (1UL << BH_Mapped); err = 0; diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 6cc9522fafac..66582c216504 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -177,6 +177,7 @@ static struct super_block *minix_read_super(struct super_block *s, void *data, kdev_t dev = s->s_dev; const char * errmsg; struct inode *root_inode; + unsigned int hblock; /* N.B. These should be compile-time tests. Unfortunately that is impossible. */ @@ -186,6 +187,11 @@ static struct super_block *minix_read_super(struct super_block *s, void *data, panic("bad V2 i-node size"); MOD_INC_USE_COUNT; + + hblock = get_hardblocksize(dev); + if (hblock && hblock > BLOCK_SIZE) + goto out_bad_hblock; + lock_super(s); set_blocksize(dev, BLOCK_SIZE); if (!(bh = bread(dev,1,BLOCK_SIZE))) @@ -322,11 +328,16 @@ out_no_fs: brelse(bh); goto out_unlock; +out_bad_hblock: + printk("MINIX-fs: blocksize too small for device.\n"); + goto out; + out_bad_sb: printk("MINIX-fs: unable to read superblock\n"); out_unlock: - s->s_dev = 0; unlock_super(s); + out: + s->s_dev = 0; MOD_DEC_USE_COUNT; return NULL; } diff --git a/fs/read_write.c b/fs/read_write.c index eb729a4fdcbd..c15ce4c73836 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -39,11 +39,15 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin) static inline loff_t llseek(struct file *file, loff_t offset, int origin) { loff_t (*fn)(struct file *, loff_t, int); + loff_t retval; fn = default_llseek; if (file->f_op && file->f_op->llseek) fn = file->f_op->llseek; - return fn(file, offset, origin); + lock_kernel(); + retval = fn(file, offset, origin); + unlock_kernel(); + return retval; } asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) @@ -53,7 +57,6 @@ asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) struct dentry * dentry; struct inode * inode; - lock_kernel(); retval = -EBADF; file = fget(fd); if (!file) @@ -72,7 +75,6 @@ asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) out_putf: fput(file); bad: - unlock_kernel(); return retval; } @@ -87,7 +89,6 @@ asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, struct inode * inode; loff_t offset; - lock_kernel(); retval = -EBADF; file = fget(fd); if (!file) @@ -112,7 +113,6 @@ asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, out_putf: fput(file); bad: - unlock_kernel(); return retval; } #endif @@ -264,7 +264,6 @@ asmlinkage ssize_t sys_readv(unsigned long fd, const struct iovec * vector, struct file * file; ssize_t ret; - lock_kernel(); ret = -EBADF; file = fget(fd); @@ -275,7 +274,6 @@ asmlinkage ssize_t sys_readv(unsigned long fd, const struct iovec * vector, fput(file); bad_file: - unlock_kernel(); return ret; } @@ -285,19 +283,16 @@ asmlinkage ssize_t sys_writev(unsigned long fd, const struct iovec * vector, struct file * file; ssize_t ret; - lock_kernel(); ret = -EBADF; file = fget(fd); if (!file) goto bad_file; - if (file->f_op && file->f_op->write && (file->f_mode & FMODE_WRITE)) { + if (file->f_op && file->f_op->write && (file->f_mode & FMODE_WRITE)) ret = do_readv_writev(VERIFY_READ, file, vector, count); - } fput(file); bad_file: - unlock_kernel(); return ret; } @@ -312,8 +307,6 @@ asmlinkage ssize_t sys_pread(unsigned int fd, char * buf, struct file * file; ssize_t (*read)(struct file *, char *, size_t, loff_t *); - lock_kernel(); - ret = -EBADF; file = fget(fd); if (!file) @@ -333,7 +326,6 @@ asmlinkage ssize_t sys_pread(unsigned int fd, char * buf, out: fput(file); bad_file: - unlock_kernel(); return ret; } @@ -344,8 +336,6 @@ asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf, struct file * file; ssize_t (*write)(struct file *, const char *, size_t, loff_t *); - lock_kernel(); - ret = -EBADF; file = fget(fd); if (!file) @@ -366,6 +356,5 @@ asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf, out: fput(file); bad_file: - unlock_kernel(); return ret; } diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 2ee7aaf0a6dd..0dea64e75f5f 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -8,6 +8,8 @@ * VFAT filesystem to . Specify * what file operation caused you trouble and if you can duplicate * the problem, send a script that demonstrates it. + * + * Short name translation 1999 by Wolfram Pienkoss */ #define __NO_VERSION__ @@ -161,6 +163,69 @@ static int parse_options(char *options, struct fat_mount_options *opts) return 1; } +static inline unsigned char +vfat_getlower(struct nls_table *t, unsigned char c) +{ + return t->charset2lower[c]; +} + +static inline unsigned char +vfat_tolower(struct nls_table *t, unsigned char c) +{ + unsigned char nc = t->charset2lower[c]; + + return nc ? nc : c; +} + +static inline unsigned char +vfat_getupper(struct nls_table *t, unsigned char c) +{ + return t->charset2upper[c]; +} + +static inline unsigned char +vfat_toupper(struct nls_table *t, unsigned char c) +{ + unsigned char nc = t->charset2upper[c]; + + return nc ? nc : c; +} + +static int +vfat_strnicmp(struct nls_table *t, const unsigned char *s1, + const unsigned char *s2, int len) +{ + while(len--) + if (vfat_tolower(t, *s1++) != vfat_tolower(t, *s2++)) + return 1; + + return 0; +} + +static inline unsigned char +vfat_uni2short(struct nls_table *t, struct nls_unicode uc) +{ + unsigned char *up; + + up = t->page_uni2charset[uc.uni2]; + if (up) + return up[uc.uni1]; + + return 0; +} + +static inline unsigned char +vfat_uni2upper_short(struct nls_table *t, struct nls_unicode uc) +{ + unsigned char *up; + + up = t->page_uni2charset[uc.uni2]; + if (up) + return vfat_toupper(t, up[uc.uni1]); + + return 0; +} + /* * Compute the hash for the vfat name corresponding to the dentry. * Note: if the name is invalid, we leave the hash code unchanged so @@ -190,9 +255,9 @@ static int vfat_hash(struct dentry *dentry, struct qstr *qstr) */ static int vfat_hashi(struct dentry *dentry, struct qstr *qstr) { + struct nls_table *t = MSDOS_SB(dentry->d_inode->i_sb)->nls_io; const char *name; int len; - char c; unsigned long hash; len = qstr->len; @@ -201,10 +266,8 @@ static int vfat_hashi(struct dentry *dentry, struct qstr *qstr) len--; hash = init_name_hash(); - while (len--) { - c = tolower(*name++); - hash = partial_name_hash(tolower(c), hash); - } + while (len--) + hash = partial_name_hash(vfat_tolower(t, *name++), hash); qstr->hash = end_name_hash(hash); return 0; @@ -215,6 +278,7 @@ static int vfat_hashi(struct dentry *dentry, struct qstr *qstr) */ static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b) { + struct nls_table *t = MSDOS_SB(dentry->d_inode->i_sb)->nls_io; int alen, blen; /* A filename cannot end in '.' or we treat it like it has none */ @@ -225,7 +289,7 @@ static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b) while (blen && b->name[blen-1] == '.') blen--; if (alen == blen) { - if (strnicmp(a->name, b->name, alen) == 0) + if (vfat_strnicmp(t, a->name, b->name, alen) == 0) return 0; } return 1; @@ -339,8 +403,6 @@ static int vfat_valid_longname(const char *name, int len, int xlate) unsigned char c; int i, baselen; - if (IS_FREE(name)) return -EINVAL; - if (len && name[len-1] == ' ') return -EINVAL; if (len >= 256) return -EINVAL; for (i = 0; i < len; i++) { @@ -369,44 +431,47 @@ static int vfat_valid_longname(const char *name, int len, int xlate) return 0; } -static int vfat_valid_shortname(const char *name,int len,int utf8) +static int vfat_valid_shortname(struct nls_table *nls, struct nls_unicode *name, + int len) { - const char *walk; - unsigned char c; + struct nls_unicode *walk; + unsigned char c, l; int space; - int baselen; + + c = vfat_uni2upper_short(nls, *name); + if (IS_FREE(&c)) + return -EINVAL; space = 1; /* disallow names starting with a dot */ - c = 0; for (walk = name; len && walk-name < 8;) { - c = *walk++; len--; - if (utf8 && (c & 0x80)) return -EINVAL; + l = vfat_uni2short(nls, *walk++); + c = vfat_getupper(nls, l); + if (!c) return -EINVAL; + if (l != vfat_tolower(nls, c)) return -EINVAL; if (strchr(replace_chars,c)) return -EINVAL; - if (c >= 'A' && c <= 'Z') return -EINVAL; if (c < ' '|| c==':') return -EINVAL; if (c == '.') break; space = c == ' '; } if (space) return -EINVAL; if (len && c != '.') { - c = *walk++; len--; + c = vfat_uni2upper_short(nls, *walk++); if (c != '.') return -EINVAL; } - baselen = walk - name; if (c == '.') { - baselen--; if (len >= 4) return -EINVAL; while (len > 0) { - c = *walk++; len--; - if (utf8 && (c & 0x80)) return -EINVAL; + l = vfat_uni2short(nls, *walk++); + c = vfat_getupper(nls, l); + if (!c) return -EINVAL; + if (l != vfat_tolower(nls, c)) return -EINVAL; if (strchr(replace_chars,c)) return -EINVAL; if (c < ' ' || c == '.'|| c==':') return -EINVAL; - if (c >= 'A' && c <= 'Z') return -EINVAL; space = c == ' '; } if (space) return -EINVAL; @@ -428,36 +493,41 @@ static int vfat_find_form(struct inode *dir,char *name) return 0; } -static int vfat_format_name(const char *name,int len,char *res,int utf8) +static int vfat_format_name(struct nls_table *nls, struct nls_unicode *name, + int len, char *res) { char *walk; unsigned char c; int space; + c = vfat_uni2upper_short(nls, *name); + if (IS_FREE(&c)) + return -EINVAL; + space = 1; /* disallow names starting with a dot */ - for (walk = res; len-- && (c=*name++)!='.' ; walk++) { + for (walk = res; len--; walk++) { + c = vfat_uni2upper_short(nls, *name++); + if (c == '.') break; + if (!c) return -EINVAL; if (walk-res == 8) return -EINVAL; - if (utf8 && (c & 0x80)) return -EINVAL; if (strchr(replace_chars,c)) return -EINVAL; - if (c >= 'A' && c <= 'Z') return -EINVAL; if (c < ' '|| c==':') return -EINVAL; space = c == ' '; - *walk = c >= 'a' && c <= 'z' ? c-32 : c; + *walk = c; } if (space) return -EINVAL; if (len >= 0) { while (walk-res < 8) *walk++ = ' '; while (len > 0 && walk-res < MSDOS_NAME) { - c = *name++; + c = vfat_uni2upper_short(nls, *name++); len--; - if (utf8 && (c & 0x80)) return -EINVAL; + if (!c) return -EINVAL; if (strchr(replace_chars,c)) return -EINVAL; if (c < ' ' || c == '.'|| c==':') return -EINVAL; - if (c >= 'A' && c <= 'Z') return -EINVAL; space = c == ' '; - *walk++ = c >= 'a' && c <= 'z' ? c-32 : c; + *walk++ = c; } if (space) return -EINVAL; if (len) return -EINVAL; @@ -472,44 +542,35 @@ static char skip_chars[] = ".:\"?<>| "; /* Given a valid longname, create a unique shortname. Make sure the * shortname does not exist */ -static int vfat_create_shortname(struct inode *dir, const char *name, - int len, char *name_res, int utf8) +static int vfat_create_shortname(struct inode *dir, struct nls_table *nls, + struct nls_unicode *name, int len, + char *name_res) { - const char *ip, *ext_start, *end; - char *p; - int sz, extlen, baselen; - char msdos_name[13]; - char base[9], ext[4]; - int i; - char buf[8]; - const char *name_start; + struct nls_unicode *ip, *op, *ext_start, *end, *name_start; + struct nls_unicode msdos_name[13]; + char base[9], ext[4], buf[8], *p; + int sz, extlen, baselen, i; - PRINTK2(("Entering vfat_create_shortname: name=%s, len=%d\n", name, len)); + PRINTK2(("Entering vfat_create_shortname\n")); sz = 0; /* Make compiler happy */ - if (len && name[len-1]==' ') return -EINVAL; if (len <= 12) { /* Do a case insensitive search if the name would be a valid * shortname if is were all capitalized. However, do not * allow spaces in short names because Win95 scandisk does * not like that */ - for (i = 0, p = msdos_name, ip = name; ; i++, p++, ip++) { + for (i = 0, op = &msdos_name[0], ip = name; ; i++, ip++, op++) { if (i == len) { - if (vfat_format_name(msdos_name, - len, name_res, utf8) < 0) + if (vfat_format_name(nls, &msdos_name[0], len, + name_res) < 0) break; PRINTK3(("vfat_create_shortname 1\n")); if (vfat_find_form(dir, name_res) < 0) return 0; return -EEXIST; } - - if (*ip == ' ') + if (vfat_uni2upper_short(nls, *ip) == ' ') break; - if (*ip >= 'A' && *ip <= 'Z') { - *p = *ip + 32; - } else { - *p = *ip; - } + *op = *ip; } } @@ -517,7 +578,7 @@ static int vfat_create_shortname(struct inode *dir, const char *name, /* Now, we need to create a shortname from the long name */ ext_start = end = &name[len]; while (--ext_start >= name) { - if (*ext_start == '.') { + if (vfat_uni2upper_short(nls, *ext_start) == '.') { if (ext_start == end - 1) { sz = len; ext_start = NULL; @@ -537,7 +598,11 @@ static int vfat_create_shortname(struct inode *dir, const char *name, name_start = &name[0]; while (name_start < ext_start) { - if (!strchr(skip_chars,*name_start)) break; + unsigned char c = vfat_uni2upper_short(nls, *name_start); + if (!c) + break; + if (!strchr(skip_chars, c)) + break; name_start++; } if (name_start != ext_start) { @@ -551,16 +616,15 @@ static int vfat_create_shortname(struct inode *dir, const char *name, for (baselen = i = 0, p = base, ip = name; i < sz && baselen < 8; i++) { - if (utf8 && (*ip & 0x80)) { - *p++ = '_'; + unsigned char c = vfat_uni2upper_short(nls, *ip); + if (!c) { + *p++ = c = '_'; baselen++; - } else if (!strchr(skip_chars, *ip)) { - if (*ip >= 'a' && *ip <= 'z') { - *p = *ip - 32; - } else { - *p = *ip; - } - if (strchr(replace_chars, *p)) *p='_'; + } else if (!strchr(skip_chars, c)) { + if (strchr(replace_chars, c)) + *p = '_'; + else + *p = c; p++; baselen++; } ip++; @@ -572,18 +636,16 @@ static int vfat_create_shortname(struct inode *dir, const char *name, extlen = 0; if (ext_start) { for (p = ext, ip = ext_start; extlen < 3 && ip < end; ip++) { - if (utf8 && (*ip & 0x80)) { - *p++ = '_'; + unsigned char c = vfat_uni2upper_short(nls, *ip); + if (!c) { + *p++ = c = '_'; extlen++; - } else if (!strchr(skip_chars, *ip)) { - if (*ip >= 'a' && *ip <= 'z') { - *p = *ip - 32; - } else { - *p = *ip; - } - if (strchr(replace_chars, *p)) *p='_'; - extlen++; - p++; + } else if (!strchr(skip_chars, c)) { + if (strchr(replace_chars, c)) + *p = '_'; + else + *p = c; + p++; extlen++; } } } @@ -641,14 +703,14 @@ static int vfat_create_shortname(struct inode *dir, const char *name, /* Translate a string, including coded sequences into Unicode */ static int -xlate_to_uni(const char *name, int len, char *outname, int *outlen, +xlate_to_uni(const char *name, int len, char *outname, int *longlen, int *outlen, int escape, int utf8, struct nls_table *nls) { - int i; const unsigned char *ip; + unsigned char nc; char *op; - int fill; - unsigned char c1, c2, c3; + unsigned int ec; + int i, k, fill; if (utf8) { *outlen = utf8_mbstowcs((__u16 *) outname, name, PAGE_SIZE); @@ -658,25 +720,40 @@ xlate_to_uni(const char *name, int len, char *outname, int *outlen, } else { if (name[len-1] == '.') len--; - op = outname; if (nls) { for (i = 0, ip = name, op = outname, *outlen = 0; - i < len && *outlen <= 260; i++, *outlen += 1) + i < len && *outlen <= 260; *outlen += 1) { if (escape && (*ip == ':')) { - if (i > len - 4) return -EINVAL; - c1 = fat_esc2uni[ip[1]]; - c2 = fat_esc2uni[ip[2]]; - c3 = fat_esc2uni[ip[3]]; - if (c1 == 255 || c2 == 255 || c3 == 255) + if (i > len - 5) return -EINVAL; - *op++ = (c1 << 4) + (c2 >> 2); - *op++ = ((c2 & 0x3) << 6) + c3; - ip += 4; + ec = 0; + for (k = 1; k < 5; k++) { + nc = ip[k]; + ec <<= 4; + if (nc >= '0' && nc <= '9') { + ec |= nc - '0'; + continue; + } + if (nc >= 'a' && nc <= 'f') { + ec |= nc - ('a' - 10); + continue; + } + if (nc >= 'A' && nc <= 'F') { + ec |= nc - ('A' - 10); + continue; + } + return -EINVAL; + } + *op++ = ec & 0xFF; + *op++ = ec >> 8; + ip += 5; + i += 5; } else { *op++ = nls->charset2uni[*ip].uni1; *op++ = nls->charset2uni[*ip].uni2; ip++; + i++; } } } else { @@ -691,6 +768,7 @@ xlate_to_uni(const char *name, int len, char *outname, int *outlen, if (*outlen > 260) return -ENAMETOOLONG; + *longlen = *outlen; if (*outlen % 13) { *op++ = 0; *op++ = 0; @@ -709,37 +787,49 @@ xlate_to_uni(const char *name, int len, char *outname, int *outlen, } static int -vfat_fill_long_slots(struct msdos_dir_slot *ds, const char *name, int len, - char *msdos_name, int *slots, - int uni_xlate, int utf8, struct nls_table *nls) +vfat_fill_slots(struct inode *dir, struct msdos_dir_slot *ds, const char *name, + int len, int *slots, int uni_xlate) { + struct nls_table *nls_io, *nls_disk; + struct nls_unicode *uname; struct msdos_dir_slot *ps; struct msdos_dir_entry *de; - int res; - int slot; + unsigned long page; unsigned char cksum; - char *uniname; const char *ip; - unsigned long page; - int unilen; - int i; + char *uniname, msdos_name[MSDOS_NAME]; + int res, utf8, slot, ulen, unilen, i; loff_t offset; + de = (struct msdos_dir_entry *) ds; + utf8 = MSDOS_SB(dir->i_sb)->options.utf8; + nls_io = MSDOS_SB(dir->i_sb)->nls_io; + nls_disk = MSDOS_SB(dir->i_sb)->nls_disk; + if (name[len-1] == '.') len--; if(!(page = __get_free_page(GFP_KERNEL))) return -ENOMEM; uniname = (char *) page; - res = xlate_to_uni(name, len, uniname, &unilen, uni_xlate, utf8, nls); - if (res < 0) { - free_page(page); - return res; + res = xlate_to_uni(name, len, uniname, &ulen, &unilen, uni_xlate, + utf8, nls_io); + if (res < 0) + goto out_free; + + uname = (struct nls_unicode *) page; + if (vfat_valid_shortname(nls_disk, uname, ulen) >= 0) { + res = vfat_format_name(nls_disk, uname, ulen, de->name); + if (!res) + goto out_free; } + res = vfat_create_shortname(dir, nls_disk, uname, ulen, msdos_name); + if (res) + goto out_free; *slots = unilen / 13; for (cksum = i = 0; i < 11; i++) { cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i]; } - PRINTK3(("vfat_fill_long_slots 3: slots=%d\n",*slots)); + PRINTK3(("vfat_fill_slots 3: slots=%d\n",*slots)); for (ps = ds, slot = *slots; slot > 0; slot--, ps++) { ps->id = slot; @@ -756,12 +846,13 @@ vfat_fill_long_slots(struct msdos_dir_slot *ds, const char *name, int len, ds[0].id |= 0x40; de = (struct msdos_dir_entry *) ps; - PRINTK3(("vfat_fill_long_slots 9\n")); + PRINTK3(("vfat_fill_slots 9\n")); strncpy(de->name, msdos_name, MSDOS_NAME); (*slots)++; +out_free: free_page(page); - return 0; + return res; } /* We can't get "." or ".." here - VFS takes care of those cases */ @@ -769,29 +860,14 @@ vfat_fill_long_slots(struct msdos_dir_slot *ds, const char *name, int len, static int vfat_build_slots(struct inode *dir,const char *name,int len, struct msdos_dir_slot *ds, int *slots) { - struct msdos_dir_entry *de; - char msdos_name[MSDOS_NAME]; - int res, xlate, utf8; - struct nls_table *nls; + int res, xlate; - de = (struct msdos_dir_entry *) ds; xlate = MSDOS_SB(dir->i_sb)->options.unicode_xlate; - utf8 = MSDOS_SB(dir->i_sb)->options.utf8; - nls = MSDOS_SB(dir->i_sb)->nls_io; - *slots = 1; res = vfat_valid_longname(name, len, xlate); if (res < 0) return res; - if (vfat_valid_shortname(name, len, utf8) >= 0) { - vfat_format_name(name, len, de->name, utf8); - return 0; - } - res = vfat_create_shortname(dir, name, len, msdos_name, utf8); - if (res < 0) - return res; - return vfat_fill_long_slots(ds, name, len, msdos_name, slots, xlate, - utf8, nls); + return vfat_fill_slots(dir, ds, name, len, slots, xlate); } static int vfat_add_entry(struct inode *dir,struct qstr* qname, diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index c2fe527c1700..e80f0ae3b599 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -310,6 +310,7 @@ #define __NR_sendfile 370 #define __NR_setresgid 371 #define __NR_getresgid 372 +#define __NR_dipc 373 #if defined(__LIBRARY__) && defined(__GNUC__) diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h index 0a2e01c3617e..84d73ee1364f 100644 --- a/include/asm-i386/hw_irq.h +++ b/include/asm-i386/hw_irq.h @@ -124,8 +124,8 @@ extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; "pushl %ecx\n\t" \ "pushl %ebx\n\t" \ "movl $" STR(__KERNEL_DS) ",%edx\n\t" \ - "movl %dx,%ds\n\t" \ - "movl %dx,%es\n\t" + "movl %edx,%ds\n\t" \ + "movl %edx,%es\n\t" #define IRQ_NAME2(nr) nr##_interrupt(void) #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h index bc8e8c805e50..0a7f79689512 100644 --- a/include/asm-ppc/cache.h +++ b/include/asm-ppc/cache.h @@ -6,7 +6,6 @@ #include #include -/*#include */ /* bytes per L1 cache line */ #define L1_CACHE_BYTES 32 @@ -26,37 +25,6 @@ #if defined(__KERNEL__) && !defined(__ASSEMBLY__) extern void flush_dcache_range(unsigned long start, unsigned long stop); -static inline unsigned long unlock_dcache(void) -{ -#ifndef CONFIG_8xx - ulong hid0 = 0; - /* 601 doesn't do this */ - if ( (ulong) _get_PVR() == 1 ) - return 0; - asm("mfspr %0,1008 \n\t" : "=r" (hid0) ); - if ( !(hid0 & HID0_DLOCK) ) - return 0; - asm("mtspr 1008,%0 \n\t" :: "r" (hid0 & ~(HID0_DLOCK))); - return (hid0 & HID0_DLOCK) ? 1 : 0; -#else /* ndef CONFIG_8xx */ - return 0; -#endif -} - -static inline void lock_dcache(unsigned long lockit) -{ -#ifndef CONFIG_8xx - /* 601 doesn't do this */ - if ( !lockit || ((ulong) _get_PVR() == 1) ) - return; - asm("mfspr %0,1008 \n\t" - "ori %0,%0,%2 \n\t" - "mtspr 1008,%0 \n\t" - "sync \n\t isync \n\t" - : "=r" (lockit) : "0" (lockit), "i" (HID0_DLOCK)); -#endif /* ndef CONFIG_8xx */ -} - #endif /* __ASSEMBLY__ */ /* prep registers for L2 */ diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index d2df19224926..ac1442861337 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -25,7 +25,8 @@ extern unsigned long smp_proc_in_lock[NR_CPUS]; extern void smp_message_pass(int target, int msg, unsigned long data, int wait); extern void smp_store_cpu_info(int id); -extern void smp_message_recv(void); +extern void smp_message_recv(int); +void smp_send_tlb_invalidate(int); #define NO_PROC_ID 0xFF /* No processor magic marker */ #define PROC_CHANGE_PENALTY 20 diff --git a/include/asm-ppc/stat.h b/include/asm-ppc/stat.h index d6d868312805..7cc8654e0b06 100644 --- a/include/asm-ppc/stat.h +++ b/include/asm-ppc/stat.h @@ -16,6 +16,7 @@ struct __old_kernel_stat { unsigned long st_mtime; unsigned long st_ctime; }; + struct stat { dev_t st_dev; ino_t st_ino; @@ -37,4 +38,39 @@ struct stat { unsigned long __unused5; }; +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned short st_dev; + unsigned char __pad0[10]; + + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned short st_rdev; + unsigned char __pad3[10]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* future possible st_blocks high bits */ + + unsigned long st_atime; + unsigned long __pad5; + + unsigned long st_mtime; + unsigned long __pad6; + + unsigned long st_ctime; + unsigned long __pad7; /* will be high 32 bits of ctime someday */ + + unsigned long __unused1; + unsigned long __unused2; +}; #endif diff --git a/include/linux/apm_bios.h b/include/linux/apm_bios.h index 14de8251d117..074cad84f463 100644 --- a/include/linux/apm_bios.h +++ b/include/linux/apm_bios.h @@ -124,9 +124,6 @@ extern struct apm_bios_info apm_bios_info; extern int apm_register_callback(int (*callback)(apm_event_t)); extern void apm_unregister_callback(int (*callback)(apm_event_t)); -extern int apm_display_blank(void); -extern int apm_display_unblank(void); - #endif /* __KERNEL__ */ /* diff --git a/include/linux/fs.h b/include/linux/fs.h index 57ba941ddcd6..ff257b469f4a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -250,7 +250,7 @@ void init_buffer(struct buffer_head *, bh_end_io_t *, void *); #define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK) -extern void set_bh_page(struct buffer_head *bh, struct page *page, unsigned int offset); +extern void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset); #define touch_buffer(bh) set_bit(PG_referenced, &bh->b_page->flags) diff --git a/include/linux/openpic.h b/include/linux/openpic.h index 9cf18c5da172..ce7ffdf899e8 100644 --- a/include/linux/openpic.h +++ b/include/linux/openpic.h @@ -50,10 +50,10 @@ * Vector numbers */ -#define OPENPIC_VEC_SOURCE 0x10 /* and up */ -#define OPENPIC_VEC_TIMER 0x40 /* and up */ -#define OPENPIC_VEC_IPI 0x50 /* and up */ -#define OPENPIC_VEC_SPURIOUS 99 +#define OPENPIC_VEC_SOURCE 16 /* and up */ +#define OPENPIC_VEC_TIMER 64 /* and up */ +#define OPENPIC_VEC_IPI 72 /* and up */ +#define OPENPIC_VEC_SPURIOUS 127 /* diff --git a/include/pcmcia/bulkmem.h b/include/pcmcia/bulkmem.h index dcc84bf04b94..c920e3d41620 100644 --- a/include/pcmcia/bulkmem.h +++ b/include/pcmcia/bulkmem.h @@ -195,10 +195,10 @@ extern int MTDHelperEntry(int func, ...); int pcmcia_get_first_region(client_handle_t handle, region_info_t *rgn); int pcmcia_get_next_region(client_handle_t handle, region_info_t *rgn); int pcmcia_register_mtd(client_handle_t handle, mtd_reg_t *reg); -int pcmcia_register_erase_queue(client_handle_t *handle, eraseq_hdr_t *header); +int pcmcia_register_erase_queue(client_handle_t *handle, eraseq_hdr_t *header, eraseq_handle_t *e); int pcmcia_deregister_erase_queue(eraseq_handle_t eraseq); int pcmcia_check_erase_queue(eraseq_handle_t eraseq); -int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open); +int pcmcia_open_memory(client_handle_t *handle, open_mem_t *open, memory_handle_t *m); int pcmcia_close_memory(memory_handle_t handle); int pcmcia_read_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf); int pcmcia_write_memory(memory_handle_t handle, mem_op_t *req, caddr_t buf); diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index 8a67a6f98eb5..c2e971d528b6 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -464,7 +464,7 @@ int pcmcia_release_window(window_handle_t win); int pcmcia_request_configuration(client_handle_t handle, config_req_t *req); int pcmcia_request_io(client_handle_t handle, io_req_t *req); int pcmcia_request_irq(client_handle_t handle, irq_req_t *req); -int pcmcia_request_window(client_handle_t *handle, win_req_t *req); +int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh); int pcmcia_reset_card(client_handle_t handle, client_req_t *req); int pcmcia_suspend_card(client_handle_t handle, client_req_t *req); int pcmcia_resume_card(client_handle_t handle, client_req_t *req); diff --git a/ipc/shm.c b/ipc/shm.c index 5e1517d4ec93..8d5ae6189550 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -549,8 +549,8 @@ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) down(¤t->mm->mmap_sem); err = -EINVAL; shp = shm_lock(shmid); - if(shp == NULL) - goto out_unlock_up; + if (!shp) + goto out_up; err = -EACCES; if (ipcperms(&shp->u.shm_perm, flg)) diff --git a/kernel/Makefile b/kernel/Makefile index 00d0dfa6939b..2c6f4d971988 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.s: - $(CPP) -traditional $< -o $*.s + $(CPP) $(CPPFLAGS) -traditional $< -o $*.s O_TARGET := kernel.o O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \ diff --git a/net/core/dev.c b/net/core/dev.c index 64c13ed05e8c..6362554b8e85 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -87,9 +87,9 @@ #include #include #include -#ifdef CONFIG_NET_RADIO -#include -#endif /* CONFIG_NET_RADIO */ +#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) +#include /* Note : will define WIRELESS_EXT */ +#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ #ifdef CONFIG_PLIP extern int plip_init(void); #endif @@ -1307,7 +1307,7 @@ static int dev_proc_stats(char *buffer, char **start, off_t offset, #endif /* CONFIG_PROC_FS */ -#ifdef CONFIG_NET_RADIO +#ifdef WIRELESS_EXT #ifdef CONFIG_PROC_FS /* @@ -1392,7 +1392,7 @@ static int dev_get_wireless_info(char * buffer, char **start, off_t offset, return len; } #endif /* CONFIG_PROC_FS */ -#endif /* CONFIG_NET_RADIO */ +#endif /* WIRELESS_EXT */ void dev_set_promiscuity(struct net_device *dev, int inc) { @@ -1624,13 +1624,13 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) return -EOPNOTSUPP; } -#ifdef CONFIG_NET_RADIO +#ifdef WIRELESS_EXT if(cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { if (dev->do_ioctl) return dev->do_ioctl(dev, ifr, cmd); return -EOPNOTSUPP; } -#endif /* CONFIG_NET_RADIO */ +#endif /* WIRELESS_EXT */ } return -EINVAL; @@ -1754,7 +1754,7 @@ int dev_ioctl(unsigned int cmd, void *arg) return -EFAULT; return ret; } -#ifdef CONFIG_NET_RADIO +#ifdef WIRELESS_EXT if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { dev_load(ifr.ifr_name); if (IW_IS_SET(cmd)) { @@ -1769,7 +1769,7 @@ int dev_ioctl(unsigned int cmd, void *arg) return -EFAULT; return ret; } -#endif /* CONFIG_NET_RADIO */ +#endif /* WIRELESS_EXT */ return -EINVAL; } } @@ -2083,9 +2083,9 @@ int __init net_dev_init(void) #ifdef CONFIG_PROC_FS proc_net_create("dev", 0, dev_get_info); create_proc_read_entry("net/dev_stat", 0, 0, dev_proc_stats, NULL); -#ifdef CONFIG_NET_RADIO +#ifdef WIRELESS_EXT proc_net_create("wireless", 0, dev_get_wireless_info); -#endif /* CONFIG_NET_RADIO */ +#endif /* WIRELESS_EXT */ #endif /* CONFIG_PROC_FS */ init_bh(NET_BH, net_bh); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 5c370cc7ceb2..95ee577e9935 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -109,9 +109,9 @@ #ifdef CONFIG_KMOD #include #endif -#ifdef CONFIG_NET_RADIO -#include -#endif /* CONFIG_NET_RADIO */ +#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) +#include /* Note : will define WIRELESS_EXT */ +#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ #define min(a,b) ((a)<(b)?(a):(b)) @@ -887,10 +887,10 @@ static int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) (cmd <= (SIOCDEVPRIVATE + 15))) return(dev_ioctl(cmd,(void *) arg)); -#ifdef CONFIG_NET_RADIO +#ifdef WIRELESS_EXT if((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) return(dev_ioctl(cmd,(void *) arg)); -#endif +#endif /* WIRELESS_EXT */ if (sk->prot->ioctl==NULL || (err=sk->prot->ioctl(sk, cmd, arg))==-ENOIOCTLCMD) return(dev_ioctl(cmd,(void *) arg)); diff --git a/net/netsyms.c b/net/netsyms.c index e5129c3c4d4b..5b4d57305670 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -543,6 +543,7 @@ EXPORT_SYMBOL(qdisc_head); EXPORT_SYMBOL(qdisc_create_dflt); EXPORT_SYMBOL(noop_qdisc); EXPORT_SYMBOL(qdisc_tree_lock); +EXPORT_SYMBOL(qdisc_runqueue_lock); #ifdef CONFIG_NET_SCHED PSCHED_EXPORTLIST; EXPORT_SYMBOL(pfifo_qdisc_ops); -- 2.39.5