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
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
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
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
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)
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
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
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
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,
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.
/proc/bus/usb filesystem output
===============================
-(version 19990722)
+(version 19991218)
The /proc filesystem for USB devices generates
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.
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
|__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
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
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
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,
AHA152X SCSI DRIVER
P: Juergen E. Fischer
-M: Juergen Fischer <fischer@et-inf.fho-emden.de>
+M: Juergen Fischer <fischer@norbit.de>
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
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
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
+++ /dev/null
- 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 <tek@rbg.informatik.tu-darmstadt.de>
-M: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de>
-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 <fischer@et-inf.fho-emden.de>
-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 <lnz@dandelion.com>
-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 <arrays@compaq.com>
-L: compaqandlinux@yps.org
-S: Maintained
-
-COMPUTONE INTELLIPORT MULTIPORT CARD
-P: Doug McNash
-P: Michael H. Warfield
-M: Doug McNash <dmcnash@computone.com>
-M: Michael H. Warfield <mhw@wittsend.com>
-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 <ivan@cyclades.com>
-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 <gadio@netvision.net.il>
-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 <Jay.Schulist@spacs.k12.wi.us>
-L: linux-net@vger.rutgers.edu
-S: Maintained
-
-IRDA SUBSYSTEM
-P: Dag Brattli
-M: Dag Brattli <dagb@cs.uit.no>
-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 <mnalis-umsdos@voyager.hr>
-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
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/)
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
# 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.
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
#define SIGCHLD 20
-#define NR_SYSCALLS 373
+#define NR_SYSCALLS 374
/*
* These offsets must match with alpha_mv in <asm/machvec.h>.
.quad sys_sendfile /* 370 */
.quad sys_setresgid
.quad sys_getresgid
+ .quad sys_ni_syscall /* sys_dipc */
$(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:
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
$(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
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 > $@
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
$(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 $@
$(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 $@ $<
$(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 $@ $<
$(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:
OBJECTS = $(HEAD) misc.o
-CFLAGS = -O2 -DSTDC_HEADERS
+CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS
ZLDFLAGS = -e startup_32
#
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
* 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
* 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 <borislav@lix.polytechnique.fr>)
+ * Fix for bioses that don't zero the top part of the
+ * entrypoint offset (Mario Sitta <sitta@al.unipmn.it>)
+ * (reported by Panos Katsaloulis <teras@writeme.com>).
+ * Real mode power off patch (Walter Hofmann
+ * <Walter.Hofmann@physik.stud.uni-erlangen.de>).
*
* APM 1.1 Reference:
*
#include <linux/miscdevice.h>
#include <linux/apm_bios.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include <asm/system.h>
#include <asm/uaccess.h>
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.
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",
__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"
__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"
* 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)
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))
{
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:
#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:
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();
}
/*
* 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)
{
/* 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;
}
_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));
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; \
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
*/
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
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
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
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 */
};
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
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. */
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
__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)
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 */
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 \
# 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
# for more details.
.S.o:
- $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $<
+ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $<
OS_TARGET := ifpsp.o
# 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
#
.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
# 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
# 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
sync
dep:
- $(CPP) -M *.c > .depend
+ $(CPP) $(CPPFLAGS) -M *.c > .depend
include $(TOPDIR)/Rules.make
sync
dep:
- $(CPP) -M *.c > .depend
+ $(CPP) $(CPPFLAGS) -M *.c > .depend
include $(TOPDIR)/Rules.make
locore.o: locore.S
dep:
- $(CPP) -M *.c > .depend
+ $(CPP) $(CPPFLAGS) -M *.c > .depend
include $(TOPDIR)/Rules.make
indyIRQ.o: indyIRQ.S
dep:
- $(CPP) -M *.c > .depend
+ $(CPP) $(CPPFLAGS) -M *.c > .depend
include $(TOPDIR)/Rules.make
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)
.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
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
$(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:
.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
$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
dep:
- $(CPP) -M *.S *.c > .depend
+ $(CPP) $(CPPFLAGS) -M *.S *.c > .depend
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
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__ */
}
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);
#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__ */
/* 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,
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");
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<<smp_processor_id()) );
+#endif
+ openpic_set_priority(smp_processor_id(), 0);
+}
+
/*
* Initialize a timer interrupt (and disable it)
*
void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
void openpic_enable_IPI(u_int ipi);
+void do_openpic_setup_cpu(void);
#endif /* _PPC_KERNEL_OPEN_PIC_H */
if (xmon_2nd)
xmon(regs);
#endif
- smp_message_recv();
+ pmac_smp_message_recv();
return -1;
}
#include <linux/vt_kern.h>
#include <linux/nvram.h>
#include <linux/spinlock.h>
+#include <linux/console.h>
#include <asm/page.h>
#include <asm/semaphore.h>
EXPORT_SYMBOL(ppc_irq_dispatch_handler);
EXPORT_SYMBOL(decrementer_count);
EXPORT_SYMBOL(get_wchan);
+EXPORT_SYMBOL(console_drivers);
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__ */
}
}
-/*
- * 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 )
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)
* 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);
}
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);
*/
/* 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<<target);
break;
}
+ break;
}
-
- spin_unlock(&mesg_pass_lock);
}
void __init smp_boot_cpus(void)
}
}
+ if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
+ do_openpic_setup_cpu();
+
if ( _machine == _MACH_Pmac )
{
/* reset the entry point so if we get another intr we won't
current->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();
#
.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
.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
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
$(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:
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 *
{
__clear_user(Hash, Hash_size);
_tlbia();
+#ifdef __SMP__
+ smp_send_tlb_invalidate(0);
+#endif
}
/*
mm->context = NO_CONTEXT;
if (mm == current->mm)
activate_mm(mm, mm);
+#ifdef __SMP__
+ smp_send_tlb_invalidate(0);
+#endif
}
void
flush_hash_page(vma->vm_mm->context, vmaddr);
else
flush_hash_page(0, vmaddr);
+#ifdef __SMP__
+ smp_send_tlb_invalidate(0);
+#endif
}
{
flush_hash_page(mm->context, start);
}
+#ifdef __SMP__
+ smp_send_tlb_invalidate(0);
+#endif
}
/*
}
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));
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 */
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");
/* 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,
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 */
}
#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) {
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),
#
.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
@echo "#ifndef CONFIG_SMP" >> asm_offsets.h
@echo "" >> asm_offsets.h
@echo "#include <linux/config.h>" > tmp.c
+ @echo "#undef __SMP__" >> tmp.c
@echo "#undef CONFIG_SMP" >> tmp.c
@echo "#include <linux/sched.h>" >> 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 <linux/config.h>" >> check_asm.c
+ @echo "#undef __SMP__" >> check_asm.c
@echo "#undef CONFIG_SMP" >> check_asm.c
@echo "#include <linux/sched.h>" >> check_asm.c
@echo 'struct task_struct _task;' >> check_asm.c
$(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
@echo "#undef CONFIG_SMP" >> tmp.c
@echo "#define CONFIG_SMP 1" >> tmp.c
@echo "#include <linux/sched.h>" >> 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 <linux/config.h>" >> check_asm.c
@echo "#undef CONFIG_SMP" >> check_asm.c
$(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
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
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:
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
sync
dep:
- $(CPP) -M *.c > .depend
+ $(CPP) $(CPPFLAGS) -M *.c > .depend
include $(TOPDIR)/Rules.make
# 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
@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 <linux/config.h>" > tmp.c
+ @echo "#undef __SMP__" >> tmp.c
@echo "#undef CONFIG_SMP" >> tmp.c
@echo "#include <linux/sched.h>" >> 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 <linux/config.h>" >> check_asm.c
+ @echo "#undef __SMP__" >> check_asm.c
@echo "#undef CONFIG_SMP" >> check_asm.c
@echo "#include <linux/sched.h>" >> check_asm.c
@echo 'struct task_struct _task;' >> check_asm.c
@rm -f tmp.[ci]
#$(CC) -o check_asm check_asm.c
# <hack> 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
# </hack>
@echo "#undef CONFIG_SMP" >> tmp.c
@echo "#define CONFIG_SMP 1" >> tmp.c
@echo "#include <linux/sched.h>" >> 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 <linux/config.h>" >> check_asm.c
@echo "#undef CONFIG_SMP" >> check_asm.c
@rm -f tmp.[ci]
#$(CC) -D__SMP__ -o check_asm check_asm.c
# <hack> 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
# </hack>
@rm -f check_asm check_asm.c
@echo -e "\n#else /* SPIN_LOCK_DEBUG */\n" >> asm_offsets.h
@echo "#include <linux/sched.h>" > 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 <linux/config.h>" >> check_asm.c
@echo "#undef CONFIG_SMP" >> check_asm.c
@rm -f tmp.[ci]
#$(CC) -D__SMP__ -DSPIN_LOCK_DEBUG -o check_asm check_asm.c
# <hack> 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
# </hack>
sync
dep:
- $(CPP) -M *.c > .depend
+ $(CPP) $(CPPFLAGS) -M *.c > .depend
include $(TOPDIR)/Rules.make
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
#include <linux/config.h>
#include <linux/version.h>
#include <linux/tqueue.h>
-#ifdef CONFIG_APM
-#include <linux/apm_bios.h>
-#endif
#include <linux/bootmem.h>
#include <linux/acpi.h>
*/
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
*/
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);
}
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);
}
static struct console lpcons = {
- "lp",
+ "lp0",
lp_console_write,
NULL,
lp_console_device,
* Aironet 4500 Pcmcia driver
*
* Elmer Joandi, Januar 1999
- * Copyright Elmer Joandi, all rights restricted
+ * Copyright: GPL
*
*
* Revision 0.1 ,started 30.12.1998
#define AIRONET4500_H
// redefined to avoid PCMCIA includes
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#if (LINUX_VERSION_CODE < 0x2030e)
+ #include <linux/version.h>
+/*#include <linux/module.h>
+ #include <linux/kernel.h>
+*/
+#if LINUX_VERSION_CODE < 0x2030E
#define NET_DEVICE device
+#error bad kernel version code
+
#else
#define NET_DEVICE net_device
#endif
#if LINUX_VERSION_CODE < 0x20300
#define init_MUTEX(a) *(a) = MUTEX;
#endif
-
+/*
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/time.h>
+*/
#include <linux/802_11.h>
//damn idiot PCMCIA stuff
-#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 <asm/spinlock.h>
-#else
#include <linux/spinlock.h>
-#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
/* 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++;\
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++;\
#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)\
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) {\
struct awc_fid * head;
struct awc_fid * tail;
int size;
- my_spinlock_t lock;
+ my_spinlock_t spinlock;
};
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
unsigned long flags;
- my_spin_lock_irqsave(&queue->lock,flags);
+ my_spin_lock_irqsave(&queue->spinlock,flags);
fid->prev = queue->tail;
fid->next = NULL;
queue->head = fid;
queue->size++;
- my_spin_unlock_irqrestore(&queue->lock,flags);
+ my_spin_unlock_irqrestore(&queue->spinlock,flags);
};
unsigned long flags;
- my_spin_lock_irqsave(&queue->lock,flags);
+ my_spin_lock_irqsave(&queue->spinlock,flags);
fid->prev = NULL;
fid->next = queue->head;
queue->size++;
- my_spin_unlock_irqrestore(&queue->lock,flags);
+ my_spin_unlock_irqrestore(&queue->spinlock,flags);
};
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);
};
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;
};
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;
};
#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
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;
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;
#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)
* 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
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/ioport.h>
-
+#include <linux/delay.h>
#if LINUX_VERSION_CODE < 0x20100
#include <linux/bios32.h>
#endif
/*
- * 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 <linux/module.h>
#include <linux/kernel.h>
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;
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;
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; ;
};
}
- DOWN(&cmd->priv->command_semaphore);
+ AWC_LOCK_COMMAND_ISSUING(cmd->priv);
if(awc_command_busy_clear_wait(cmd->dev)) goto final;
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; ;
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");
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; ;
};
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 ){
// 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;
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) {
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;
}
udelay(bap_sleep_after_setup);
// success
- return AWC_SUCCESS;
+ goto return_AWC_SUCCESS;
}
if (status & AWC_BAP_ERR) {
// 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);
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;
}
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");
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;
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");
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);
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;
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 );
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;
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)
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:
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; ;
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; ;
+
}
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;
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;
if (priv->command_semaphore_on){
priv->command_semaphore_on--;
- UP(&priv->command_semaphore);
+ AWC_UNLOCK_COMMAND_ISSUING(priv);
}
}
};
// 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);
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);
//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;
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;
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)
// 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) {
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;
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;
}
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;
/* 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){
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) ) {
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;
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){
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;
};
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);
{
// unsigned long flags;
-// debug = awc_debug;
+
printk(KERN_INFO"%s", aironet4500_core_version);
return 0;
* Aironet 4500 Pcmcia driver
*
* Elmer Joandi, Januar 1999
- * Copyright Elmer Joandi, all rights restricted
+ * Copyright GPL
*
*
* Revision 0.1 ,started 30.12.1998
{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}
};
/* void enableReceive(struct net_device* dev);
*/
-static int arlan_command(struct net_device * dev, int command);
#define ARLAN_STR_SIZE 0x2ff0
return "type A672T";
}
}
-
+#ifdef ARLAN_DEBUGING
static void arlan_print_diagnostic_info(struct net_device *dev)
{
int i;
return 0;
}
-
static int arlan_setup_card_by_book(struct net_device *dev)
{
u_char irqLevel, configuredStatusFlag;
return 0; /* no errors */
}
-
+#endif
#ifdef ARLAN_PROC_INTERFACE
#ifdef ARLAN_PROC_SHM_DUMP
#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),\
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),\
};
#endif
-static int mmtu = 1234;
+
+// static int mmtu = 1234;
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}
+//};
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");
}
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;
{
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
{
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;
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))
}
-
+#ifdef ARLAN_DEBUGING
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)
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");
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++;
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++;
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);
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]);
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;
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;
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 */
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;
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
}
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.
}
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");
{
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)
{
#include <linux/etherdevice.h>
-#define DEBUG 1
+//#define ARLAN_DEBUGING 1
#define ARLAN_PROC_INTERFACE
#define MAX_ARLANS 4 /* not more than 4 ! */
#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
#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
-#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)
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 \
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#ifdef CONFIG_NET_RADIO
+#ifdef CONFIG_NET_PCMCIA_RADIO
#include <linux/wireless.h>
-#endif
+#endif /* CONFIG_NET_PCMCIA_RADIO */
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ds.h>
#include <pcmcia/mem_op.h>
-#ifdef HAS_WIRELESS_EXTENSIONS
+#ifdef CONFIG_NET_PCMCIA_RADIO
#include <linux/wireless.h>
-#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"
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 **************************************/
'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 <corey@world.std.com>");
MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
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));
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));
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));
} /* 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;
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);
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
#include <linux/ioport.h>
#include <linux/fcntl.h>
-#ifdef CONFIG_NET_RADIO
+#ifdef CONFIG_NET_PCMCIA_RADIO
#include <linux/wireless.h> /* Wireless extensions */
-#endif
+#endif /* CONFIG_NET_PCMCIA_RADIO */
/* Pcmcia headers that we need */
#include <pcmcia/cs_types.h>
*
* Torben Mathiasen <torben.mathiasen@compaq.com> 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.
+ *
********************************************************************/
static u8 *TLanPadBuffer;
static char TLanSignature[] = "TLAN";
static int TLanVersionMajor = 1;
-static int TLanVersionMinor = 0;
+static int TLanVersionMinor = 1;
static TLanAdapterEntry TLanAdapterList[] = {
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;
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 );
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 );
int err;
int minten;
TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
- int irq;
unsigned long flags;
err = FALSE;
#include <asm/types.h>
#include <linux/netdevice.h>
-#if LINUX_VERSION_CODE <= 0x20100
-#define net_device_stats enet_statistics
-#endif
-
-
/*****************************************************************
/* 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 */
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;
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);
}
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);
}
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;
}
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;
}
struct sv11_device
{
+ void *if_ptr; /* General purpose pointer (used by SPPP) */
struct z8530_dev sync;
struct ppp_device netdev;
char name[16];
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;
/*
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;
free_dma(dev->chanA.txdma);
fail:
free_irq(irq, dev);
+fail1:
+ kfree(sv->netdev.dev);
fail2:
kfree(sv);
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)
{
struct slvl_device
{
+ void *if_ptr; /* General purpose pointer (used by SPPP) */
struct z8530_channel *chan;
struct ppp_device netdev;
char name[16];
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;
/*
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;
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:
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);
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;
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;
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;
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))
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))
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;
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. */
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)
dev_add_pack(&sppp_packet_type);
}
+EXPORT_SYMBOL(sync_ppp_init);
+
#ifdef MODULE
int init_module(void)
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 */
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)
{
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:
======================================================================*/
-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;
queue->handle = *handle;
queue->count = header->QueueEntryCnt;
queue->entry = header->QueueEntryArray;
- *handle = (client_handle_t)queue;
+ *e = queue;
return CS_SUCCESS;
} /* register_erase_queue */
======================================================================*/
-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;
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;
======================================================================*/
-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;
s->state |= SOCKET_WIN_REQ(w);
/* Return window handle */
- *handle = (client_handle_t)win;
+ *wh = win;
return CS_SUCCESS;
} /* request_window */
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:
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;
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:
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
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
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
/* 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 */
/* */
/*****************************************************************************/
/*
* 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"
"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
*/
(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;
/* 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);
}
ips_next(ips_ha_t *ha) {
ips_scb_t *scb;
Scsi_Cmnd *SC;
+ Scsi_Cmnd *p;
int ret;
DBG("ips_next");
/*
* 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;
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);
}
- 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;
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 */
}
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;
} /* 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);
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));
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;
#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
/*
* 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
/*
* 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
#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
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 */
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.
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
#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
* 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;
* 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;
}
}
*
* 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;
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
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;
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;
}
*/
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);
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 *);
*/
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;
*/
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 *);
* 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
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;
scsi_release_command(SCpnt);
SCpnt = NULL;
-
- wake_up(&SDpnt->device_wait);
return result;
}
#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);
result = SCpnt->result;
- wake_up(&SCpnt->device->device_wait);
SDpnt = SCpnt->device;
scsi_release_command(SCpnt);
SCpnt = NULL;
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);
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) {
}
/*
- * 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);
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
* 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) {
*
* 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)
{
* 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;
}
/*
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;
}
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);
/*
* rest of the command, or start a new one.
*/
if (result == 0) {
- scsi_queue_next_request(q, SCpnt);
return;
}
}
*/
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;
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;
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:
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;
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;
}
}
*/
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;
*/
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
*/
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);
- }
- }
}
* 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,
#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
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
*/
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;
}
SCpnt->request_bufflen -= sgpnt[i].length;
SCpnt->use_sg = i;
if (i == 0) {
- panic("DMA pool exhausted");
+ goto big_trouble;
}
break;
}
}
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
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)
}
}
host->host_blocked = TRUE;
- cmd->host_wait = TRUE;
} else {
/*
* Protect against race conditions. If the device isn't busy,
}
}
cmd->device->device_blocked = TRUE;
- cmd->device_wait = TRUE;
}
/*
* 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);
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;
#include <scsi/scsi_ioctl.h>
#include <scsi/sg.h>
+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
}
/* 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")); */
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;
}
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 */
}
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
}
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 {
} while (the_result && retries);
- wake_up(&SCpnt->device->device_wait);
scsi_release_command(SCpnt);
SCpnt = NULL;
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 */
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;
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;
}
result = SCpnt->result;
/* Wake up a process waiting for device */
- wake_up(&SCpnt->device->device_wait);
scsi_release_command(SCpnt);
SCpnt = NULL;
return err;
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));
#include <asm/irq.h>
#include <asm/system.h>
-#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
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;
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;
}
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);
}
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 {
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 */
#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 */
/*****************************************************************/
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;
* 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;
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;
}
char *page, *end;
ssize_t ret = 0;
unsigned int pos, len;
+ int busnum = 0;
if (*ppos < 0)
return -EINVAL;
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;
{
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);
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:
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;
}
/* 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");
{
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;
}
}
/* 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
/* 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;
}
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.
{
struct us_data *us = (struct us_data *)__us;
int action;
- int i;
lock_kernel();
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:
}
}
- MOD_DEC_USE_COUNT;
+ // MOD_DEC_USE_COUNT;
printk("usbscsi_control_thread exiting\n");
}
/* 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");
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;
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
*/
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");
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;
}
#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);
if (ss->filter)
ss->filter->release(ss->fdata);
ss->pusb_dev = NULL;
- MOD_DEC_USE_COUNT;
+ // MOD_DEC_USE_COUNT;
}
int usb_scsi_init(void)
{
- MOD_INC_USE_COUNT;
+ // MOD_INC_USE_COUNT;
if (usb_register(&scsi_driver) < 0)
return -1;
#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)
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);
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);
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);
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);
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;
}
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)
#include <linux/kmod.h>
#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)
* VFAT extensions by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
* Merged with msdos fs by Henrik Storner <storner@osiris.ping.dk>
* Rewritten for constant inumbers. Plugged buffer overrun in readdir(). AV
+ * Short name translation 1999 by Wolfram Pienkoss <wp@bsz.shk.th.schule.de>
*/
#define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))
/*
* 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;
*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++ = '?';
}
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;
}
* 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)
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;
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;
}
}
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. */
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))
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;
}
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)
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';
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;
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)
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;
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;
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;
}
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;
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. */
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)))
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;
}
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)
struct dentry * dentry;
struct inode * inode;
- lock_kernel();
retval = -EBADF;
file = fget(fd);
if (!file)
out_putf:
fput(file);
bad:
- unlock_kernel();
return retval;
}
struct inode * inode;
loff_t offset;
- lock_kernel();
retval = -EBADF;
file = fget(fd);
if (!file)
out_putf:
fput(file);
bad:
- unlock_kernel();
return retval;
}
#endif
struct file * file;
ssize_t ret;
- lock_kernel();
ret = -EBADF;
file = fget(fd);
fput(file);
bad_file:
- unlock_kernel();
return ret;
}
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;
}
struct file * file;
ssize_t (*read)(struct file *, char *, size_t, loff_t *);
- lock_kernel();
-
ret = -EBADF;
file = fget(fd);
if (!file)
out:
fput(file);
bad_file:
- unlock_kernel();
return ret;
}
struct file * file;
ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
- lock_kernel();
-
ret = -EBADF;
file = fget(fd);
if (!file)
out:
fput(file);
bad_file:
- unlock_kernel();
return ret;
}
* VFAT filesystem to <chaffee@cs.berkeley.edu>. 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 <wp@bsz.shk.th.schule.de>
*/
#define __NO_VERSION__
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
*/
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;
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;
*/
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 */
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;
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++) {
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;
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;
/* 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;
}
}
/* 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;
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) {
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++;
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++;
}
}
}
/* 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);
} 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 {
if (*outlen > 260)
return -ENAMETOOLONG;
+ *longlen = *outlen;
if (*outlen % 13) {
*op++ = 0;
*op++ = 0;
}
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;
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 */
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,
#define __NR_sendfile 370
#define __NR_setresgid 371
#define __NR_getresgid 372
+#define __NR_dipc 373
#if defined(__LIBRARY__) && defined(__GNUC__)
"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)
#include <linux/config.h>
#include <asm/processor.h>
-/*#include <asm/system.h>*/
/* bytes per L1 cache line */
#define L1_CACHE_BYTES 32
#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 */
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
unsigned long st_mtime;
unsigned long st_ctime;
};
+
struct stat {
dev_t st_dev;
ino_t st_ino;
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
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__ */
/*
#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)
* 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
/*
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);
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);
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))
# 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 \
#include <net/profile.h>
#include <linux/init.h>
#include <linux/kmod.h>
-#ifdef CONFIG_NET_RADIO
-#include <linux/wireless.h>
-#endif /* CONFIG_NET_RADIO */
+#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
+#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
+#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
#ifdef CONFIG_PLIP
extern int plip_init(void);
#endif
#endif /* CONFIG_PROC_FS */
-#ifdef CONFIG_NET_RADIO
+#ifdef WIRELESS_EXT
#ifdef CONFIG_PROC_FS
/*
return len;
}
#endif /* CONFIG_PROC_FS */
-#endif /* CONFIG_NET_RADIO */
+#endif /* WIRELESS_EXT */
void dev_set_promiscuity(struct net_device *dev, int inc)
{
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;
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)) {
return -EFAULT;
return ret;
}
-#endif /* CONFIG_NET_RADIO */
+#endif /* WIRELESS_EXT */
return -EINVAL;
}
}
#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);
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
-#ifdef CONFIG_NET_RADIO
-#include <linux/wireless.h>
-#endif /* CONFIG_NET_RADIO */
+#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
+#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
+#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
#define min(a,b) ((a)<(b)?(a):(b))
(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));
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);