D: Originator of design for new combined interrupt handlers
S: William Gates Department
S: Stanford University
-S: Stanford, California 94305, USA
+S: Stanford, California 94305
+S: USA
N: Juan Jose Ciarlante
E: jjciarla@raiz.uncu.edu.ar
N: Mike McLagan
E: mike.mclagan@linux.org
W: http://www.invlogic.com/~mmclagan
+D: DLCI/FRAD drivers for Sangoma SDLAs
S: Innovative Logic Corp
S: P.O. Box 1068
S: Laurel, MD 20732
S: USA
-D: DLCI/FRAD drivers for Sangoma SDLAs
N: Bradley McLean
E: brad@bradpc.gaylord.com
S: c/o Ingenia Communications Corporation
S: Suite 4200, CTTC Building
S: 1125 Colonel By Drive
-S: Ottawa, Ontario, Canada
-S: K1S 5R1
+S: Ottawa, Ontario
+S: Canada K1S 5R1
N: John Shifflett
E: john@geolog.com
S: IRISA
S: Universit=E9 de Rennes I
S: F-35042 Rennes Cedex
-S: FRANCE
+S: France
N: Jon Tombs
E: jon@gtex02.us.es
S: Roger Maris Cancer Center
S: 820 4th St. N.
S: Fargo, ND 58122
+S: USA
N: Hans-Joachim Widmaier
E: jbhr@sofal.tynet.sub.org
S: San Jose, California 95148
S: USA
-# Don't add your name here, unless you really _are_ after Leonard
-# alphabetically. Leonard is very proud of being the last entry,
-# and this file really _is_ supposed to be in alphabetic order.
+N: Marc Zyngier
+E: maz@gloups.fdn.fr
+D: MD driver
+S: 11 rue Victor HUGO
+S: 95560 Montsoult
+S: France
+
+# Don't add your name here, unless you really _are_ after Marc
+# alphabetically. Leonard used to be very proud of being the
+# last entry, and he'll get positively pissed if he can't even
+# be second-to-last. (and this file really _is_ supposed to be
+# in alphabetic order)
This driver is enabled at runtime using the "ide0=dtc2278" kernel
boot parameter. It enables support for the secondary IDE interface
of the DTC-2278 card, and permits faster I/O speeds to be set as
- well. See the README.ide and dtc2278.c files for more info.
+ well. See the Documentation/ide.txt and dtc2278.c files for more
+ info.
Holtek HT6560B support
CONFIG_BLK_DEV_HT6560B
This driver is enabled at runtime using the "ide0=ht6560b" kernel
boot parameter. It enables support for the secondary IDE interface
of the Holtek card, and permits faster I/O speeds to be set as well.
- See the README.ide and ht6560b.c files for more info.
+ See the Documentation/ide.txt and ht6560b.c files for more info.
QDI QD6580 support
CONFIG_BLK_DEV_QD6580
This driver is enabled at runtime using the "ide0=qd6580" kernel
- boot parameter. It permits faster I/O speeds to be set.
- See the README.ide and qd6580.c files for more info.
+ boot parameter. It permits faster I/O speeds to be set. See the
+ Documentation/ide.txt and qd6580.c files for more info.
UMC 8672 support
CONFIG_BLK_DEV_UMC8672
This driver is enabled at runtime using the "ide0=umc8672" kernel
boot parameter. It enables support for the secondary IDE interface
of the UMC-8672, and permits faster I/O speeds to be set as well.
- See the README.ide and umc8672.c files for more info.
+ See the Documentation/ide.txt and umc8672.c files for more info.
ALI M1439/M1445 support
CONFIG_BLK_DEV_ALI14XX
This driver is enabled at runtime using the "ide0=ali14xx" kernel
boot parameter. It enables support for the secondary IDE interface
of the chipset, and permits faster I/O speeds to be set as well.
- See the README.ide and ali14xx.c files for more info.
+ See the Documentation/ide.txt and ali14xx.c files for more info.
PROMISE DC4030 support (EXPERIMENTAL)
CONFIG_BLK_DEV_PROMISE
boot parameter. It enables support for the secondary IDE interface
of the chipset, and takes advantage of the caching features of the
card. This driver is known to incur timeouts/retries during heavy
- I/O to drives attached to the secondary interface. CDROM and
- TAPE devices are not supported yet.
- See the README.ide and promise.c files for more info.
+ I/O to drives attached to the secondary interface. CDROM and TAPE
+ devices are not supported yet. See the Documentation/ide.txt and
+ promise.c files for more info.
XT harddisk support
CONFIG_BLK_DEV_XD
about 2kB. You may need to read the FIREWALL-HOWTO, available via
ftp (user: anonymous) in
sunsite.unc.edu:/pub/Linux/docs/HOWTO. Also, you will need the
- ipfwadm tool to allow selective blocking of internet traffic based
+ ipfwadm tool (available via ftp (user: anonymous) from ftp.xos.nl)
+ to allow selective blocking of internet traffic based
on type, origin and destination. You need to enable IP firewalling
in order to be able to use IP masquerading (i.e. local computers can
chat with an outside host, but that outside host is made to think
that it is talking to the firewall box. Makes the local network
completely invisible and avoids the need to allocate valid IP host
- addresses for the machines on the local net) or to use the ip packet
+ addresses for the machines on the local net) or to use the IP packet
accounting to see what is using all your network bandwidth.
This option is also needed when you want to enable the transparent
- proxying support (via which non-local connections can be redirected
- to local proxy servers).
+ proxying support (makes the computers on the local network think
+ they're talking to a remote computer, while in reality the traffic
+ is redirected by your Linux firewall to a local proxy server).
IP: accounting
CONFIG_IP_ACCT
encapsulating protocol. This particular tunneling driver implements
encapsulation of IP within IP, which sounds kind of pointless, but
can be useful if you want to make your (or some other) machine
- appear on a different network than it physically is, or to use the
- mobile IP facilities (which effectively are doing that). Enabling this
- option will produce two modules ( = code which can be inserted in
- and removed from the running kernel whenever you want), one
+ appear on a different network than it physically is, or to use
+ mobile-IP facilities (allowing laptops to seamlessly move between
+ networks without changing their IP addresses; check out
+ http://anchor.cs.binghamton.edu/~mobileip/LJ/index.html). Enabling
+ this option will produce two modules ( = code which can be inserted
+ in and removed from the running kernel whenever you want), one
encapsulator and one decapsulator. You can read details in
drivers/net/README.tunnel. Most people can say N.
IP: transparent proxying (EXPERIMENTAL)
CONFIG_IP_TRANSPARENT_PROXY
- This enables you to redirect any network traffic to a local server,
- acting as a "transparent proxy server". Redirection is activated
- by defining special input firewall rules (using the ipfwadm utility)
- and/or by doing an appropriate bind() system call.
+ This enables your Linux firewall to transparently redirect any
+ network traffic originating from the local network and destined
+ for a remote host to a local server, called a "transparent proxy
+ server". This makes the local computers think they are talking to
+ the remote end, while in fact they are connected to the local
+ proxy. Redirection is activated by defining special input firewall
+ rules (using the ipfwadm utility) and/or by doing an appropriate
+ bind() system call.
IP: masquerading (EXPERIMENTAL)
CONFIG_IP_MASQUERADE
last problem can also be solved by connecting the Linux box to the
Internet using SLiRP [SLiRP is a SLIP/PPP emulator that works if you
have a regular dial up shell account on some UNIX computer; get it
- from ftp://sunsite.unc.edu/pub/Linux/system/Network/serial/
+ from ftp://sunsite.unc.edu/pub/Linux/system/Network/serial/].)
Details on how to set things up are contained in the
IP Masquerading FAQ, available at http://www.indyramp.com/masq/
This is EXPERIMENTAL code, which means that it need not be completely
stable. If you want this, say Y.
-IP: always defragment
-CONFIG_IP_ALWAYS_DEFRAG
- This option means that all incoming fragments will be reassembled
- (defragmented) before being processed, even if those packets
- should be forwarded. This option is highly recommended if you
- have enabled CONFIG_IP_MASQUERADE, because these facilities requires
- that second and further fragments can be related to TCP or UDP port
- numbers, which are only stored in the first fragment. When using
- CONFIG_IP_FIREWALL, you might also want to enable this option, to
- have a more reliable firewall (otherwise second and further fragments
- will always be accepted by the firewall). When using transparent
- proxying (CONFIG_IP_TRANSPARENT_PROXY), this option is implicit,
- although it is safe to say Y here. Do not say Y to this option except
- when running either a firewall that is the sole link to your network or
- a transparent proxy. Never ever say Y to this for a normal router or
- host.
+IP: always defragment
+CONFIG_IP_ALWAYS_DEFRAG
+ This option means that all incoming fragments (= parts of IP packets
+ that arose when some host between origin and destination decided
+ that the IP packets were too large and cut them in pieces) will be
+ reassembled (defragmented) before being processed, even if they are
+ about to be forwarded. This option is highly recommended if you
+ have enabled the masquerading support (CONFIG_IP_MASQUERADE),
+ because this facility requires that second and further fragments can
+ be related to TCP or UDP port numbers, which are only stored in the
+ first fragment. When using IP firewall support
+ (CONFIG_IP_FIREWALL), you might also want to enable this option, to
+ have a more reliable firewall (otherwise second and further
+ fragments will always be accepted by the firewall). When using
+ transparent proxying (CONFIG_IP_TRANSPARENT_PROXY), this option is
+ implicit, although it is safe to say Y here. Do not say Y to this
+ option except when running either a firewall that is the sole link
+ to your network or a transparent proxy. Never ever say Y to this for
+ a normal router or host.
IP: aliasing support
CONFIG_IP_ALIAS
Adaptec AHA152X/2825 support
CONFIG_SCSI_AHA152X
- This is support for a SCSI host adaptor. It is explained in section
- 3.3 of the SCSI-HOWTO, available via ftp (user: anonymous) at
- sunsite.unc.edu:/pub/Linux/docs/HOWTO. If it doesn't work out of the
- box, you may have to change some settings in drivers/scsi/aha152x.h.
- 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
+ This is support for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
+ SCSI host adaptors. It is explained in section 3.3 of the
+ SCSI-HOWTO, available via ftp (user: anonymous) at
+ sunsite.unc.edu:/pub/Linux/docs/HOWTO. You might also want to read
+ the comments at the top of drivers/scsi/aha152x.c. 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.
Adaptec AHA1542 support
EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support
CONFIG_SCSI_EATA_DMA
- This is support for the EATA-DMA protocol compliant SCSI Host Adaptors
- like the SmartCache III/IV, SmartRAID controller families and the DPT
- PM2011B and PM2012B controllers.
- Please read the SCSI-HOWTO, available via ftp (user: anonymous) at
- sunsite.unc.edu:/pub/Linux/docs/HOWTO.
- 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.
+ This is support for the EATA-DMA protocol compliant SCSI Host
+ Adaptors like the SmartCache III/IV, SmartRAID controller families
+ and the DPT PM2011B and PM2012B controllers. Please read the
+ SCSI-HOWTO, available via ftp (user: anonymous) at
+ sunsite.unc.edu:/pub/Linux/docs/HOWTO. 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.
EATA-PIO (old DPT PM2001, PM2012A) support
CONFIG_SCSI_EATA_PIO
- This driver supports all EATA-PIO protocol compliant SCSI Host Adaptors
- like the DPT PM2001 and the PM2012A. EATA-DMA compliant HBAs can also use
- this driver but are discouraged from doing so, since this driver only
- supports harddisks and lacks numerous features.
- You might want to have a look at the SCSI-HOWTO, available via ftp
- (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO.
- If you want to compile this as a module ( = code which can be inserted
- in and removed from the running kernel whenever you want), say M here
- and read Documentation/modules.txt.
+ This driver supports all EATA-PIO protocol compliant SCSI Host
+ Adaptors like the DPT PM2001 and the PM2012A. EATA-DMA compliant
+ HBAs can also use this driver but are discouraged from doing so,
+ since this driver only supports harddisks and lacks numerous
+ features. You might want to have a look at the SCSI-HOWTO,
+ available via ftp (user: anonymous) at
+ sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you want to compile this
+ as a module ( = code which can be inserted in and removed from the
+ running kernel whenever you want), say M here and read
+ Documentation/modules.txt.
UltraStor 14F/34F support
CONFIG_SCSI_U14_34F
allow DISCONNECT
CONFIG_SCSI_NCR53C7xx_DISCONNECT
- This enables the disconnect/reconnect feature of the NCR SCSI controller.
- When this is enabled, a slow SCSI device will not lock the SCSI bus
- while processing a request, allowing simultaneous use of e.g. a SCSI
- hard disk and SCSI tape or CD-ROM drive, and providing much better
- performance when using slow and fast SCSI devices at the same time. Some
- devices, however, do not operate properly with this option enabled, and
- will cause your SCSI system to hang, which might cause a system crash.
- The safe answer therefore is to say N.
+ This enables the disconnect/reconnect feature of the NCR SCSI
+ controller. When this is enabled, a slow SCSI device will not lock
+ the SCSI bus while processing a request, allowing simultaneous use
+ of e.g. a SCSI hard disk and SCSI tape or CD-ROM drive, and
+ providing much better performance when using slow and fast SCSI
+ devices at the same time. Some devices, however, do not operate
+ properly with this option enabled, and will cause your SCSI system
+ to hang, which might cause a system crash. The safe answer
+ therefore is to say N.
NCR53C8XX SCSI support
CONFIG_SCSI_NCR53C8XX
- This is the BSD ncr driver adapted to linux for NCR53C8XX family of PCI-SCSI
- controllers. This driver supports parity checking, tagged command queueing,
- fast scsi II transfer up to 10 MB/s with narrow scsi devices and 20 MB/s
- with wide scsi devices.
- This driver has been tested ok with linux/i386 and is currently untested
- under linux/Alpha. If you intend to use this driver under linux/Alpha, just
- try it first with read-only or mounted read-only devices.
- Memory mapped io are currently not supported under linux/Alpha.
+ This is the BSD ncr driver adapted to linux for the NCR53C8XX family
+ of PCI-SCSI controllers. This driver supports parity checking,
+ tagged command queuing, fast scsi II transfer up to 10 MB/s with
+ narrow scsi devices and 20 MB/s with wide scsi devices.
+ This driver has been tested OK with linux/i386 and is currently
+ untested under linux/Alpha. If you intend to use this driver under
+ linux/Alpha, just try it first with read-only or mounted read-only
+ devices. Memory mapped io is currently not supported under
+ linux/Alpha. Please read drivers/scsi/README.ncr53c8xx for more
+ information.
force normal IO
CONFIG_SCSI_NCR53C8XX_IOMAPPED
- Under linux/Alpha only normal io are currently supported.
- Under linux/i386, this option allow to force the driver to use normal IO.
- Memory mapped IO have less latency than normal IO.
- During initialisation phase, the driver first tries to use memory mapped io.
- If nothing seems wrong, it will use memory mapped io.
- If a flaw is detected, it will use normal io.
- However, it's possible that memory mapped does not work properly for you and
- the driver has not detected the problem.
- The normal answer therefore is N.
+ Under linux/Alpha only normal io is currently supported.
+ Under linux/i386, this option allows you to force the driver to use
+ normal IO. Memory mapped IO has less latency than normal IO.
+ During the initialization phase, the driver first tries to use
+ memory mapped io. If nothing seems wrong, it will use memory mapped
+ io. If a flaw is detected, it will use normal io. However, it's
+ possible that memory mapped does not work properly for you and the
+ driver has not detected the problem; then you would want to say Y
+ here. The normal answer therefore is N.
not allow targets to disconnect
CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
- This option is only provided for safe if you suspect some scsi device
- of yours to not support properly this feature.
- To not allow targets to disconnect is not reasonnable if there is more
- than 1 device on a scsi bus.
- The normal answer therefore is N.
+ This option is only provided for safety if you suspect some scsi
+ device of yours to not support properly this feature. In that case,
+ you would say Y here. In general however, to not allow targets to
+ disconnect is not reasonable if there is more than 1 device on a
+ scsi bus. The normal answer therefore is N.
-enable tagged command queueing
+enable tagged command queuing
CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
- This option allow to enable tagged command queuing support at linux start-up.
- Some scsi devices do not support properly this feature.
- The suggested method may be to not validate this option in the configuration
- but to use the "settags" control command after boot-up to enable this feature.
+ This option allows you to enable tagged command queuing support at
+ linux start-up. Some scsi devices do not properly support this
+ feature. The suggested method is to say N here and to use the
+ "settags" control command after boot-up to enable this feature:
echo "settags 2 4" >/proc/scsi/ncr53c8xx/0
- Ask the driver to use up to 4 concurrent tagged commands for target 2 of
- controller 0.
- See the README.ncr53c8xx file for more information.
- WARNING! tagged queue support requires to allow targets to disconnect.
+ asks the driver to use up to 4 concurrent tagged commands for target
+ 2 of controller 0.
+ See the file drivers/scsi/README.ncr53c8xx for more information.
+ WARNING! tagged queue support requires to allow targets to
+ disconnect (see above).
The safe answer therefore is N.
The normal answer therefore is Y.
force asynchronous transfer mode
CONFIG_SCSI_NCR53C8XX_FORCE_ASYNCHRONOUS
- This option allow to force asynchronous transfer mode for all devices at
- linux startup. You can enable synchronous negotiation with the "setsync"
- control command after boot-up, for example:
+ This option allows you to force asynchronous transfer mode for all
+ devices at linux startup. You can enable synchronous negotiation
+ with the "setsync" control command after boot-up, for example:
echo "setsync 2 25" >/proc/scsi/ncr53c8xx/0
- Ask the driver to set the period to 25 ns (10MB/sec) for target 2 of
- controller 0.
- The safe answer therefore is Y.
- The normal answer therefore is N.
+ asks the driver to set the period to 25 ns (10MB/sec) for target 2
+ of controller 0 (please read drivers/scsi/README.ncr53c8xx for more
+ information). The safe answer therefore is Y. The normal answer
+ therefore is N.
force synchronous negotiation
CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
- Some scsi-2 devices support synchronous negotiations but do not report
- this feature in byte 7 of inquiry data.
+ Some scsi-2 devices support synchronous negotiations but do not
+ report this feature in byte 7 of inquiry data.
Answer Y only if you suspect some device to be so humble.
The normal answer therefore is N.
disable master parity checking
CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
- Some hardware may have problems with parity during master cycles on PCI bus.
- Only seen once. Answer Y if you suspect such problem.
- The normal answer therefore is N.
+ Some hardware may have problems with parity during master cycles on
+ PCI bus. Only seen once. Answer Y if you suspect such problem. The
+ normal answer therefore is N.
disable scsi parity checking
CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
- Parity on scsi bus is a system option. If one device checks parity, then
- all devices on the scsi bus must generate parity.
- However, the parity can be ignored by the scsi devices.
- Answer Y only if you know what you are doing.
- The normal answer therefore is N.
+ Parity on scsi bus is a system option. If one device checks parity,
+ then all devices on the scsi bus must generate parity. However, the
+ parity can be ignored by the scsi devices. Answer Y only if you
+ know what you are doing. The normal answer therefore is N.
Always IN2000 SCSI support
CONFIG_SCSI_IN2000
FX-001 or FX-001D CDROM drive. In addition, this driver uses much less
kernel memory than the old one, if that is a concern. This driver is
able to support more than one drive, but each drive needs a separate
- interface card.
+ interface card. Check out Documentation/cdrom/mcdx.
Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support
CONFIG_SBPCD
Optics Storage DOLPHIN 8000AT CDROM support
CONFIG_OPTCD
- If this is your CDROM drive, say Y here.
+ This is the driver for the 'DOLPHIN' drive with a 34-pin Sony
+ compatible interface. It also works with the Lasermate CR328A. If
+ you have one of those, say Y. This driver does not work for the
+ Optics Storage 8001 drive; use the IDE-ATAPI CDROM driver for this
+ one.
Sanyo CDR-H94A CDROM support
CONFIG_SJCD
serial ports. People who might say N here are those that are
setting up dedicated ethernet WWW/ftp servers, or users that have
one of the various bus mice instead of a serial mouse. (Note that
- the Cyclades and Stallion drivers do not need this driver built in
- for them to work. They are completely independent of each other.)
- If you want to compile this driver as a module, say M here and read
- Documentation/modules.txt. [WARNING: Do not compile this driver as
- a module if you are using non-standard serial ports, since the
- configuration information will be lost when kerneld automatically
- unloads the driver. This limitation may be lifted in the future.]
- Most people will say Y or M here, so that they can use serial mice,
- modems and similar devices connecting to the standard serial ports.
-
-Digiboard PC/X Support
+ the Cyclades and Stallion multi serial port drivers do not need this
+ driver built in for them to work. They are completely independent of
+ each other.) If you want to compile this driver as a module, say M
+ here and read Documentation/modules.txt. [WARNING: Do not compile
+ this driver as a module if you are using non-standard serial ports,
+ since the configuration information will be lost when kerneld
+ automatically unloads the driver. This limitation may be lifted in
+ the future.] Most people will say Y or M here, so that they can use
+ serial mice, modems and similar devices connecting to the standard
+ serial ports.
+
+Digiboard PC/Xx Support
CONFIG_DIGI
This is a driver for the Digiboard PC/Xe, PC/Xi, and PC/Xeve cards
that give you many serial ports. You would need something like this
tells you how to specify the port and IRQ to be used by PLIP at
module load time.
+
+Mouse Support (not serial mice)
+CONFIG_MOUSE
+ This is for machines with a bus mouse or a PS/2 mouse as opposed to
+ a serial mouse. Most people have a regular serial MouseSystem or
+ Microsoft mouse (made by Logitech) that plugs into a COM port
+ (rectangular with 9 or 25 pins). These people say N here. If you
+ have something else, read the Busmouse-HOWTO, available via ftp
+ (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO and say Y
+ here. If you have a laptop, you either have to check the
+ documentation or experiment a bit to find out whether the trackball
+ is a serial mouse or not; it's best to say Y here for you. Note that
+ the answer to this question won't directly affect the kernel: saying
+ N will just cause this configure script to skip all the questions
+ about non-serial mice. If unsure, say Y.
+
Logitech busmouse support
CONFIG_BUSMOUSE
Logitech mouse connected to a proprietary interface card. It's
as a module ( = code which can be inserted in and removed from the
running kernel whenever you want), say M here and read
Documentation/modules.txt. If you are unsure, say N and read the
- HOWTO nevertheless: it will tell you what you have. Chances are that
- you have a regular serial MouseSystem or Microsoft mouse (made by
- Logitech) plugging in a COM port (rectangular with 9 or 25 pins)
- which is supported automatically.
+ HOWTO nevertheless: it will tell you what you have.
PS/2 mouse (aka "auxiliary device") support
CONFIG_PSMOUSE
the mouse does not use any serial ports. This port can also be used
for other input devices like light pens, tablets, keypads. Compaq,
AST and IBM all use this as their mouse port on currently shipping
- machines. The trackballs of some laptops are PS/2 mice
- also. Although this is not a busmouse, it is explained in detail in
- the Busmouse-HOWTO, available via ftp (user: anonymous) in
- sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you want to compile this
- as a module ( = code which can be inserted in and removed from the
- running kernel whenever you want), say M here and read
- Documentation/modules.txt. If you are unsure, say N and read the
- HOWTO nevertheless: it will tell you what you have. Chances are that
- you have a regular serial MouseSystem or Microsoft mouse plugging in
- a COM port (9 or 25 pins) which is supported automatically.
+ machines. The trackballs of some laptops are PS/2 mice also. In
+ particular, the C&T 82C710 mouse on TI Travelmates is a PS/2
+ mouse. Although PS/2 mice are not technically bus mice, they are
+ explained in detail in the Busmouse-HOWTO, available via ftp (user:
+ anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you want to
+ compile this as a module ( = code which can be inserted in and
+ removed from the running kernel whenever you want), say M here and
+ read Documentation/modules.txt. If you are unsure, say N and read
+ the HOWTO nevertheless: it will tell you what you have.
C&T 82C710 mouse port support (as on TI Travelmate)
CONFIG_82C710_MOUSE
want to compile this as a module ( = code which can be inserted in
and removed from the running kernel whenever you want), say M here
and read Documentation/modules.txt. If you are unsure, say N and
- read the HOWTO nevertheless: it will tell you what you have. Chances
- are that you have a regular serial MouseSystem or Microsoft mouse
- plugging in a COM port which is supported automatically. Also be aware
- several vendors talk about 'Microsoft busmouse' and actually mean PS/2
- busmouse - so count the pins on the connector.
+ read the HOWTO nevertheless: it will tell you what you have. Also be
+ aware that several vendors talk about 'Microsoft busmouse' and
+ actually mean PS/2 busmouse - so count the pins on the connector.
ATIXL busmouse support
CONFIG_ATIXL_BUSMOUSE
compile this as a module ( = code which can be inserted in and
removed from the running kernel whenever you want), say M here and
read Documentation/modules.txt. If you are unsure, say N and read
- the HOWTO nevertheless: it will tell you what you have. Chances are
- that you have a regular serial MouseSystem or Microsoft mouse
- plugging in a COM port (9 or 25 pins) which is supported
- automatically.
+ the HOWTO nevertheless: it will tell you what you have.
Support for user miscellaneous modules
CONFIG_UMISC
with the ISDN utility package for example), you will be able
to use your Linux box as an ISDN-answering machine. Of course, this
must be supported by the lowlevel driver also. Currently, the Teles
- driver is the only voice-supporting one.
+ driver is the only voice-supporting one. See
+ Documentation/isdn/README.audio for more information.
ICN 2B and 4B support
CONFIG_ISDN_DRV_ICN
# LocalWords: rtc SMP lp Digi Intl RightSwitch DGRS dgrs AFFS Amiga UFS SDL AP
# LocalWords: Solaris RISCom riscom syncPPP PCBIT pcbit sparc anu au artoo ufs
# LocalWords: hitchcock Crynwr cnam pktdrvr NCSA's CyDROM CyCDROM FreeBSD NeXT
-# LocalWords: NeXTstep disklabel disklabels SMD FFS tm AmigaOS diskfiles Un
+# LocalWords: NeXTstep disklabel disklabels SMD FFS tm AmigaOS diskfiles Un IQ
# LocalWords: Bernd informatik rwth aachen uae affs multihosting bytecode java
# LocalWords: applets applet JDK ncsa cabi SNI Alphatronix readme LANs scarab
-# LocalWords: winsock RNIS caltech OSPF honour Honouring Mbit Localtalk
+# LocalWords: winsock RNIS caltech OSPF honour Honouring Mbit Localtalk DEFRAG
# LocalWords: localtalk download Packetwin Baycom baycom interwork ascii JNT
-# LocalWords: Camtec
+# LocalWords: Camtec proxying indyramp defragment defragmented UDP FAS FASXX
+# LocalWords: FastSCSI SIO FDC qlogicfas QLogic qlogicisp setbaycom ife ee LJ
+# LocalWords: ethz ch Travelmates ProAudioSpectrum ProAudio SoundMan SB SBPro
+# LocalWords: Thunderboard SM OPL FM ADLIB TSR Gravis MPU PSS ADI SW DSP codec
+# LocalWords: ADSP ESC ASIC daughtercard GUSMAX MSS NX AdLib Excell Ensoniq YM
+# LocalWords: SoundScape Spea MediaTriX AudioTriX WSS OTI ThunderBoard VoxWare
+# LocalWords: Soundscape SSCAPE TRIX MediaTrix PnP Maui dsp midixx EIA getty
+# LocalWords: mgetty sendfax gert greenie muc lowlevel Lasermate LanManager io
+# LocalWords: OOPSes trackball binghamton mobileip ncr IOMAPPED settags ns ser
+# LocalWords: setsync NEGO MPARITY
VERSION = 2
PATCHLEVEL = 0
-SUBLEVEL = 7
+SUBLEVEL = 8
ARCH = i386
*/
static inline unsigned long csum_partial_copy_aligned(
unsigned long *src, unsigned long *dst,
- long len, unsigned long checksum,
- unsigned long word)
+ long len, unsigned long checksum)
{
unsigned long carry = 0;
while (len >= 0) {
+ unsigned long word = *src;
checksum += carry;
src++;
checksum += word;
len -= 8;
carry = checksum < word;
*dst = word;
- word = *src;
dst++;
}
len += 8;
checksum += carry;
if (len) {
- unsigned long tmp = *dst;
+ unsigned long word, tmp;
+ word = *src;
+ tmp = *dst;
mskql(word, len, word);
checksum += word;
mskqh(tmp, len, tmp);
static inline unsigned long csum_partial_copy_dest_aligned(
unsigned long *src, unsigned long *dst,
unsigned long soff,
- long len, unsigned long checksum,
- unsigned long first)
+ long len, unsigned long checksum)
{
- unsigned long word, carry = 0;
+ unsigned long first;
+ unsigned long word, carry;
+ unsigned long lastsrc = 7+len+(unsigned long)src;
+ ldq_u(first,src);
+ carry = 0;
while (len >= 0) {
unsigned long second;
if (len) {
unsigned long tmp;
unsigned long second;
- ldq_u(second, src+1);
+ ldq_u(second, lastsrc);
tmp = *dst;
extql(first, soff, word);
extqh(second, soff, first);
unsigned long *src, unsigned long *dst,
unsigned long doff,
long len, unsigned long checksum,
- unsigned long word,
unsigned long partial_dest)
{
unsigned long carry = 0;
+ unsigned long word;
mskql(partial_dest, doff, partial_dest);
while (len >= 0) {
unsigned long second_dest;
-
+ word = *src;
len -= 8;
insql(word, doff, second_dest);
checksum += carry;
checksum += word;
insqh(word, doff, partial_dest);
carry = checksum < word;
- word = *src;
dst++;
}
len += doff;
checksum += carry;
if (len >= 0) {
unsigned long second_dest;
-
+ word = *src;
mskql(word, len-doff, word);
- src++;
checksum += word;
insql(word, doff, second_dest);
stq_u(partial_dest | second_dest, dst);
checksum += carry;
} else if (len & 7) {
unsigned long second_dest;
+ word = *src;
ldq_u(second_dest, dst);
mskql(word, len-doff, word);
checksum += word;
unsigned long * src, unsigned long * dst,
unsigned long soff, unsigned long doff,
long len, unsigned long checksum,
- unsigned long first, unsigned long partial_dest)
+ unsigned long partial_dest)
{
unsigned long carry = 0;
+ unsigned long first;
+ unsigned long lastsrc;
+ ldq_u(first, src);
+ lastsrc = 7+len+(unsigned long)src;
mskql(partial_dest, doff, partial_dest);
while (len >= 0) {
unsigned long second, word;
unsigned long second, word;
unsigned long second_dest;
- ldq_u(second, src+1);
+ ldq_u(second, lastsrc);
extql(first, soff, word);
extqh(second, soff, first);
word |= first;
- src++;
first = second;
mskql(word, len-doff, word);
checksum += word;
unsigned long second, word;
unsigned long second_dest;
- ldq_u(second, src+1);
+ ldq_u(second, lastsrc);
extql(first, soff, word);
extqh(second, soff, first);
word |= first;
unsigned long doff = 7 & (unsigned long) dst;
if (len) {
- unsigned long first;
- ldq_u(first, src);
if (!doff) {
if (!soff)
checksum = csum_partial_copy_aligned(
(unsigned long *) src,
(unsigned long *) dst,
- len-8, checksum, first);
+ len-8, checksum);
else
checksum = csum_partial_copy_dest_aligned(
(unsigned long *) src,
(unsigned long *) dst,
- soff, len-8, checksum, first);
+ soff, len-8, checksum);
} else {
unsigned long partial_dest;
ldq_u(partial_dest, dst);
(unsigned long *) src,
(unsigned long *) dst,
doff, len-8, checksum,
- first, partial_dest);
+ partial_dest);
else
checksum = csum_partial_copy_unaligned(
(unsigned long *) src,
(unsigned long *) dst,
soff, doff, len-8, checksum,
- first, partial_dest);
+ partial_dest);
}
/* 64 -> 33 bits */
checksum = (checksum & 0xffffffff) + (checksum >> 32);
LD=$(CROSS_COMPILE)ld -m elf_i386
CPP=$(CC) -E -D__ELF__
-OBJDUMP =$(CROSS_COMPILE)objdump
-ENCAPS=$(CROSS_COMPILE)encaps
+OBJDUMP=$(CROSS_COMPILE)objdump
OBJDUMP_FLAGS=-k -q
+ENCAPS=$(CROSS_COMPILE)encaps
+OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment
ZLDFLAGS=-e startup_32
LDFLAGS=-e stext
ZIMAGE_OFFSET=0x1000
zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
ifdef CONFIG_KERNEL_ELF
- $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(ZIMAGE_OFFSET) compressed/vmlinux > compressed/vmlinux.out
+ if hash $(ENCAPS) 2> /dev/null; then \
+ $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(ZIMAGE_OFFSET) compressed/vmlinux > compressed/vmlinux.out; \
+ else \
+ $(OBJCOPY) compressed/vmlinux compressed/vmlinux.out; \
+ fi
tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
else
tools/build bootsect setup compressed/vmlinux $(ROOT_DEV) > zImage
bzImage: $(CONFIGURE) bbootsect setup compressed/bvmlinux tools/bbuild
ifdef CONFIG_KERNEL_ELF
- $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out
+ if hash $(ENCAPS) 2> /dev/null; then \
+ $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out; \
+ else \
+ $(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out; \
+ fi
tools/bbuild bbootsect setup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
else
tools/bbuild bbootsect setup compressed/bvmlinux $(ROOT_DEV) > bzImage
# You cannot compress a file and have the kernel uncompress it, it must
# be stdin
piggy.o: $(SYSTEM)
- tmppiggy=/tmp/$$$$.piggy; \
- rm -f $$tmppiggy $$tmppiggy.gz; \
- $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) $(SYSTEM) > $$tmppiggy; \
+ tmppiggy=/tmp/$$$$piggy; \
+ rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
+ if hash $(ENCAPS) 2> /dev/null; then \
+ $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) $(SYSTEM) > $$tmppiggy; \
+ else \
+ $(OBJCOPY) $(SYSTEM) $$tmppiggy; \
+ fi; \
gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
- $(ENCAPS) $(TARGET) piggy.o $$tmppiggy.gz $(INPUT_DATA) $(INPUT_LEN); \
- rm -f $$tmppiggy $$tmppiggy.gz
+ if hash $(ENCAPS) 2> /dev/null; then \
+ $(ENCAPS) $(TARGET) piggy.o $$tmppiggy.gz $(INPUT_DATA) $(INPUT_LEN); \
+ else \
+ echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
+ ld -m elf_i386 -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
+ fi; \
+ rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
else
piggy.o: $(SYSTEM) xtract piggyback
push %es
push %ds
pushl %eax
+ xorl %eax,%eax
pushl %ebp
pushl %edi
pushl %esi
pushl %edx
+ decl %eax # eax = -1
pushl %ecx
pushl %ebx
- movl $0,%eax
- movl %eax,%db7 # disable hardware debugging...
cld
- movl $-1, %eax
- xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
xorl %ebx,%ebx # zero ebx
+ xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
mov %gs,%bx # get the lower order bits of gs
+ movl %esp,%edx
xchgl %ebx, GS(%esp) # get the address and save gs.
pushl %eax # push the error code
- lea 4(%esp),%edx
pushl %edx
movl $(KERNEL_DS),%edx
mov %dx,%ds
mov %dx,%fs
#ifdef __SMP__
ENTER_KERNEL
-#endif
- pushl %eax
-#ifdef __SMP__
GET_PROCESSOR_OFFSET(%eax)
movl SYMBOL_NAME(current_set)(,%eax), %eax
#else
#endif
movl %db6,%edx
movl %edx,dbgreg6(%eax) # save current hardware debugging status
- popl %eax
call *%ebx
addl $8,%esp
jmp ret_from_sys_call
#include <linux/delay.h>
#include <linux/mc146818rtc.h> /* CMOS defines */
#include <linux/ioport.h>
+#include <linux/interrupt.h>
#include <asm/dma.h>
#include <asm/irq.h>
INT_OFF;
fd_disable_dma();
fd_clear_dma_ff();
+ fd_cacheflush(raw_cmd->kernel_data, raw_cmd->length);
fd_set_dma_mode((raw_cmd->flags & FD_RAW_READ)?
DMA_MODE_READ : DMA_MODE_WRITE);
fd_set_dma_addr(virt_to_bus(raw_cmd->kernel_data));
} while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
}
if (handler) {
- /* expected interrupt */
- floppy_tq.routine = (void *)(void *) handler;
- queue_task_irq(&floppy_tq, &tq_timer);
+ if(intr_count >= 2)
+ {
+ /* expected interrupt */
+ floppy_tq.routine = (void *)(void *) handler;
+ queue_task_irq(&floppy_tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+ }
+ else
+ handler();
} else
FDCS->reset = 1;
is_alive("normal interrupt end");
unsigned long flags;
floppy_tq.routine = (void *)(void *) handler;
- queue_task(&floppy_tq, &tq_timer);
-
+ queue_task(&floppy_tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
INT_OFF;
while(command_status < 2 && NO_SIGNAL){
is_alive("wait_til_done");
if (((unsigned long)buffer) % 512)
DPRINT("%p buffer not aligned\n", buffer);
#endif
- if (CT(COMMAND) == FD_READ) {
- fd_cacheflush(dma_buffer, size);
+ if (CT(COMMAND) == FD_READ)
memcpy(buffer, dma_buffer, size);
- } else {
+ else
memcpy(dma_buffer, buffer, size);
- fd_cacheflush(dma_buffer, size);
- }
remaining -= size;
if (!remaining)
break;
raw_cmd = & default_raw_cmd;
raw_cmd->flags = 0;
if (start_motor(redo_fd_request)) return;
+ disk_change(current_drive);
if (test_bit(current_drive, &fake_change) ||
TESTF(FD_DISK_CHANGED)){
DPRINT("disk absent or changed during operation\n");
if (TESTF(FD_NEED_TWADDLE))
twaddle();
floppy_tq.routine = (void *)(void *) floppy_start;
- queue_task(&floppy_tq, &tq_timer);
+ queue_task(&floppy_tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
#ifdef DEBUGT
debugt("queue fd request");
#endif
static void process_fd_request(void)
{
cont = &rw_cont;
- queue_task(&request_tq, &tq_timer);
+ queue_task(&request_tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
}
static void do_fd_request(void)
{
+ sti();
if (fdc_busy){
/* fdc busy, this new request will be treated when the
current one is done */
int ret;
ECALL(verify_area(VERIFY_WRITE,param,size));
- fd_cacheflush(address, size); /* is this necessary ??? */
- /* Ralf: Yes; only the l2 cache is completely chipset
- controlled */
memcpy_tofs(param,(void *) address, size);
return 0;
}
int i;
if (!flag) {
- raw_cmd->flags = FD_RAW_FAILURE;
+ raw_cmd->flags |= FD_RAW_FAILURE;
raw_cmd->flags |= FD_RAW_HARDFAILURE;
} else {
raw_cmd->reply_count = inr;
return drive;
} else if (major == IDE0_MAJOR && unit < 4) {
printk("ide: probable bad entry for /dev/hd%c\n", 'a'+unit);
- printk("ide: to fix it, run: /usr/src/linux/drivers/block/MAKEDEV.ide\n");
+ printk("ide: to fix it, run: /usr/src/linux/scripts/MAKEDEV.ide\n");
}
break;
}
* Rearranged SIGIO support to use code from tty_io. 9Sept95 ctm@ardi.com
*
* Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
+ *
+ * Fixed keyboard lockups at open time (intervening kbd interrupts), handle
+ * RESEND replies, better error checking
+ * 3-Jul-96 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
*/
/* Uncomment the following line if your mouse needs initialization. */
#define AUX_STATUS 0x64 /* Aux device status reg */
/* aux controller status bits */
+#define AUX_KOBUF_FULL 0x01 /* output buffer (from controller) full */
#define AUX_OBUF_FULL 0x21 /* output buffer (from device) full */
#define AUX_IBUF_FULL 0x02 /* input buffer (to device) full */
+#define AUX_TIMEOUT 0x40 /* controller reports timeout */
/* aux controller commands */
#define AUX_CMD_WRITE 0x60 /* value to write to controller */
#define AUX_DISABLE_DEV 0xf5 /* disable aux device */
#define AUX_RESET 0xff /* reset aux device */
+/* kbd controller commands */
+#define KBD_DISABLE 0xad
+#define KBD_ENABLE 0xae
+
+/* replies */
+#define AUX_ACK 0xfa
+#define AUX_RESEND 0xfe
+
#define MAX_RETRIES 60 /* some aux operations take long time*/
#if defined(__alpha__) && !defined(CONFIG_PCI)
# define AUX_IRQ 9 /* Jensen is odd indeed */
static int aux_count = 0;
static int aux_present = 0;
static int poll_aux_status(void);
-static int poll_aux_status_nosleep(void);
static int fasync_aux(struct inode *inode, struct file *filp, int on);
#ifdef CONFIG_82C710_MOUSE
/*
- * Write to aux device
+ * Write a byte to the kbd controller and wait for it being processed
*/
-static void aux_write_dev(int val)
+static int aux_write_byte(int val,int port)
{
- poll_aux_status();
- outb_p(AUX_MAGIC_WRITE,AUX_COMMAND); /* write magic cookie */
- poll_aux_status();
- outb_p(val,AUX_OUTPUT_PORT); /* write data */
+ outb_p(val, port);
+ return poll_aux_status();
}
/*
- * Write to device & handle returned ack
+ * Write to device, handle returned resend requests and wait for ack
*/
-#if defined INITIALIZE_DEVICE
static int aux_write_ack(int val)
{
- int retries = 0;
-
- poll_aux_status_nosleep();
- outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
- poll_aux_status_nosleep();
- outb_p(val,AUX_OUTPUT_PORT);
- poll_aux_status_nosleep();
-
- if ((inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
- {
- return (inb(AUX_INPUT_PORT));
+ int rv, retries = 0, stat;
+
+ repeat:
+ if (poll_aux_status() < 0)
+ return -1;
+ outb_p(AUX_MAGIC_WRITE, AUX_COMMAND);
+ if (poll_aux_status() < 0)
+ return -1;
+ outb_p(val, AUX_OUTPUT_PORT);
+
+ if ((rv = poll_aux_status()) < 0)
+ /* timeout */
+ return -1;
+ else if (rv == AUX_RESEND)
+ /* controller needs last byte again... */
+ goto repeat;
+ else if (rv == AUX_ACK)
+ /* already got ACK */
+ return 0;
+ else {
+ /* wait for ACK from controller */
+ while (retries < MAX_RETRIES) {
+ stat = inb_p(AUX_STATUS);
+ if ((stat & AUX_OBUF_FULL) == AUX_OBUF_FULL &&
+ inb_p(AUX_INPUT_PORT) == AUX_ACK)
+ return 0;
+ current->state = TASK_INTERRUPTIBLE;
+ current->timeout = jiffies + (5*HZ + 99) / 100;
+ schedule();
+ retries++;
+ }
+ return -1;
}
- return 0;
}
-#endif /* INITIALIZE_DEVICE */
/*
* Write aux device command
*/
-static void aux_write_cmd(int val)
+static int aux_write_cmd(int val)
{
- poll_aux_status();
- outb_p(AUX_CMD_WRITE,AUX_COMMAND);
- poll_aux_status();
- outb_p(val,AUX_OUTPUT_PORT);
+ if (poll_aux_status() < 0)
+ return -1;
+ outb_p(AUX_CMD_WRITE, AUX_COMMAND);
+ if (poll_aux_status() < 0)
+ return -1;
+ outb_p(val, AUX_OUTPUT_PORT);
+ if (poll_aux_status() < 0)
+ return -1;
+ return 0;
}
fasync_aux(inode, file, 0);
if (--aux_count)
return;
- aux_write_cmd(AUX_INTS_OFF); /* disable controller ints */
- poll_aux_status();
- outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */
+ /* disable keyboard to avoid clashes with multi-byte command sequences */
poll_aux_status();
+ if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
+ printk(KERN_ERR "psaux: controller timeout\n");
+ /* disable controller ints */
+ if (aux_write_cmd(AUX_INTS_OFF) < 0)
+ printk(KERN_ERR "psaux: controller timeout\n");
+ /* Disable Aux device */
+ if (aux_write_byte(AUX_DISABLE, AUX_COMMAND) < 0)
+ printk(KERN_ERR "psaux: controller timeout\n");
+ /* re-enable keyboard */
+ if (aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
+ printk(KERN_ERR "psaux: controller timeout\n");
free_irq(AUX_IRQ, NULL);
MOD_DEC_USE_COUNT;
}
return -ENODEV;
if (aux_count++)
return 0;
- if (!poll_aux_status()) {
+ if (poll_aux_status() < 0) {
aux_count--;
return -EBUSY;
}
}
MOD_INC_USE_COUNT;
poll_aux_status();
- outb_p(AUX_ENABLE,AUX_COMMAND); /* Enable Aux */
- aux_write_dev(AUX_ENABLE_DEV); /* enable aux device */
- aux_write_cmd(AUX_INTS_ON); /* enable controller ints */
- poll_aux_status();
+ /* disable keyboard to avoid clashes with multi-byte command sequences */
+ if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
+ goto open_error;
+ /* Enable Aux in kbd controller */
+ if (aux_write_byte(AUX_ENABLE, AUX_COMMAND) < 0)
+ goto open_error;
+ /* enable aux device */
+ if (aux_write_ack(AUX_ENABLE_DEV) < 0)
+ goto open_error;
+ /* enable controller ints */
+ if (aux_write_cmd(AUX_INTS_ON) < 0)
+ goto open_error;
+ /* re-enable keyboard */
+ if (aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
+ goto open_error;
+
aux_ready = 0;
return 0;
+ open_error:
+ printk( KERN_ERR "psaux: controller timeout\n" );
+ return -EIO;
}
#ifdef CONFIG_82C710_MOUSE
static int write_aux(struct inode * inode, struct file * file, const char * buffer, int count)
{
int i = count;
+ int rv = 0;
+
+ /* temporary disable keyboard to avoid clashes with multi-byte command
+ * sequence */
+ if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
+ return -EIO;
while (i--) {
- if (!poll_aux_status())
- return -EIO;
+ if (poll_aux_status() < 0) {
+ rv = -EIO;
+ break;
+ }
outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
- if (!poll_aux_status())
- return -EIO;
+ if (poll_aux_status() < 0) {
+ rv = -EIO;
+ break;
+ }
outb_p(get_user(buffer++),AUX_OUTPUT_PORT);
}
+ /* reenable keyboard */
+ if (poll_aux_status() < 0 || aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
+ rv = -EIO;
+
inode->i_mtime = CURRENT_TIME;
- return count;
+ return rv ? rv : count;
}
aux_write_ack(AUX_SET_RES);
aux_write_ack(3); /* 8 counts per mm */
aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
- poll_aux_status_nosleep();
#endif /* INITIALIZE_DEVICE */
- outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */
- poll_aux_status_nosleep();
- outb_p(AUX_CMD_WRITE,AUX_COMMAND);
- poll_aux_status_nosleep(); /* Disable interrupts */
- outb_p(AUX_INTS_OFF, AUX_OUTPUT_PORT); /* on the controller */
+ /* Disable Aux device and its interrupts on the controller */
+ if (aux_write_byte(AUX_DISABLE, AUX_COMMAND) < 0 ||
+ aux_write_cmd(AUX_INTS_OFF) < 0)
+ printk(KERN_ERR "psaux: controller timeout\n");
}
return 0;
}
#ifdef MODULE
int init_module(void)
{
- return psaux_init(); /*?? Bjorn */
+ return psaux_init();
}
void cleanup_module(void)
static int poll_aux_status(void)
{
int retries=0;
+ int reply=0;
- while ((inb(AUX_STATUS)&0x03) && retries < MAX_RETRIES) {
+ while ((inb(AUX_STATUS) & (AUX_KOBUF_FULL|AUX_IBUF_FULL)) &&
+ retries < MAX_RETRIES) {
if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
- inb_p(AUX_INPUT_PORT);
+ reply = inb_p(AUX_INPUT_PORT);
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies + (5*HZ + 99) / 100;
schedule();
retries++;
}
- return !(retries==MAX_RETRIES);
-}
-
-static int poll_aux_status_nosleep(void)
-{
- int retries = 0;
-
- while ((inb(AUX_STATUS)&0x03) && retries < 1000000) {
- if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
- inb_p(AUX_INPUT_PORT);
- retries++;
- }
- return !(retries == 1000000);
+ return (retries==MAX_RETRIES) ? -1 : reply;
}
#ifdef CONFIG_82C710_MOUSE
-/* $Id: isdn_net.c,v 1.17 1996/06/25 18:37:37 fritz Exp $
+/* $Id: isdn_net.c,v 1.18 1996/07/03 13:48:51 hipp Exp $
*
* Linux ISDN subsystem, network interfaces and related functions (linklevel).
*
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn_net.c,v $
+ * Revision 1.18 1996/07/03 13:48:51 hipp
+ * bugfix: Call dev_purge_queues() only for master device
+ *
* Revision 1.17 1996/06/25 18:37:37 fritz
* Fixed return count for empty return string in isdn_net_getphones().
*
extern void dev_purge_queues(struct device *dev); /* move this to net/core/dev.c */
-char *isdn_net_revision = "$Revision: 1.17 $";
+char *isdn_net_revision = "$Revision: 1.18 $";
/*
* Code for raw-networking over ISDN
dev_kfree_skb(lp->sav_skb,FREE_WRITE);
lp->sav_skb = NULL;
}
- dev_purge_queues(&lp->netdev->dev);
+ if(!lp->master) /* purge only for master device */
+ dev_purge_queues(&lp->netdev->dev);
lp->dialstate = 0;
dev->rx_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
dev->st_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
-/* $Id: isdn_ppp.c,v 1.12 1996/06/24 17:42:03 fritz Exp $
+/* $Id: isdn_ppp.c,v 1.13 1996/07/01 19:47:24 hipp Exp $
*
* Linux ISDN subsystem, functions for synchronous PPP (linklevel).
*
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn_ppp.c,v $
+ * Revision 1.13 1996/07/01 19:47:24 hipp
+ * Fixed memory leak in VJ handling and more VJ changes
+ *
* Revision 1.12 1996/06/24 17:42:03 fritz
* Minor bugfixes.
*
int BEbyte, int *sqno, int min_sqno);
#endif
-char *isdn_ppp_revision = "$Revision: 1.12 $";
+char *isdn_ppp_revision = "$Revision: 1.13 $";
struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
extern int isdn_net_force_dial_lp(isdn_net_local *);
ippp_table[lp->ppp_minor]->lp = NULL; /* link is down .. set lp to NULL */
lp->ppp_minor = -1; /* is this OK ?? */
restore_flags(flags);
+
return 0;
}
/*
* VJ header compression init
*/
- ippp_table[minor]->cbuf = kmalloc(ippp_table[minor]->mru + PPP_HARD_HDR_LEN + 2, GFP_KERNEL);
-
- if (ippp_table[minor]->cbuf == NULL) {
- printk(KERN_DEBUG "ippp: Can't allocate memory buffer for VJ compression.\n");
- return -ENOMEM;
- }
ippp_table[minor]->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
#endif
#ifdef CONFIG_ISDN_PPP_VJ
slhc_free(ippp_table[minor]->slcomp);
ippp_table[minor]->slcomp = NULL;
- kfree(ippp_table[minor]->cbuf);
#endif
ippp_table[minor]->state = 0;
if(skb->data[0] == 0xff && skb->data[1] == 0x03)
skb_pull(skb,2);
else if (ippp_table[lp->ppp_minor]->pppcfg & SC_REJ_COMP_AC) {
- dev_kfree_skb(skb,FREE_WRITE);
+ skb->free = 1;
+ dev_kfree_skb(skb,0 /* FREE_READ */ );
return; /* discard it silently */
}
if (!q) {
net_dev->ib.modify = 0;
printk(KERN_WARNING "ippp/MPPP: Bad! Can't alloc sq node!\n");
- dev_kfree_skb(skb,FREE_WRITE);
+ skb->free = 1;
+ dev_kfree_skb(skb, 0 /* FREE_READ */ );
return; /* discard */
}
q->skb = skb;
switch (proto) {
case PPP_IPX: /* untested */
+ if(ippp_table[lp->ppp_minor]->debug & 0x20)
+ printk(KERN_DEBUG "isdn_ppp: _IPX\n");
skb->dev = dev;
skb->mac.raw = skb->data;
skb->protocol = htons(ETH_P_IPX);
break;
#ifdef CONFIG_ISDN_PPP_VJ
case PPP_VJC_UNCOMP:
- slhc_remember(ippp_table[net_dev->local.ppp_minor]->slcomp, skb->data, skb->len);
+ if(ippp_table[lp->ppp_minor]->debug & 0x20)
+ printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
+ if(slhc_remember(ippp_table[net_dev->local.ppp_minor]->slcomp, skb->data, skb->len) <= 0) {
+ printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
+ net_dev->local.stats.rx_dropped++;
+ skb->free = 1;
+ dev_kfree_skb(skb,0 /* FREE_READ */ );
+ return;
+ }
#endif
case PPP_IP:
+ if(ippp_table[lp->ppp_minor]->debug & 0x20)
+ printk(KERN_DEBUG "isdn_ppp: IP\n");
skb->dev = dev;
skb->mac.raw = skb->data;
skb->protocol = htons(ETH_P_IP);
break;
case PPP_VJC_COMP:
+ if(ippp_table[lp->ppp_minor]->debug & 0x20)
+ printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
#ifdef CONFIG_ISDN_PPP_VJ
{
struct sk_buff *skb_old = skb;
int pkt_len;
skb = dev_alloc_skb(skb_old->len + 40);
+ skb_old->free = 1;
+
if (!skb) {
printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
net_dev->local.stats.rx_dropped++;
- dev_kfree_skb(skb_old,FREE_WRITE);
+ dev_kfree_skb(skb_old,0 /* FREE_READ */ );
return;
}
skb->dev = dev;
skb->mac.raw = skb->data;
pkt_len = slhc_uncompress(ippp_table[net_dev->local.ppp_minor]->slcomp,
skb->data, skb_old->len);
- dev_kfree_skb(skb_old,FREE_WRITE);
+ dev_kfree_skb(skb_old,0 /* FREE_READ */ );
if(pkt_len < 0) {
- dev_kfree_skb(skb,FREE_WRITE);
+ skb->free = 1;
+ dev_kfree_skb(skb, 0 /* FREE_READ */ );
lp->stats.rx_dropped++;
return;
}
#else
printk(KERN_INFO "isdn: Ooopsa .. VJ-Compression support not compiled into isdn driver.\n");
lp->stats.rx_dropped++;
- dev_kfree_skb(skb,FREE_WRITE);
+ skb->free = 1;
+ dev_kfree_skb(skb,0 /* FREE_READ */ );
return;
#endif
break;
default:
isdn_ppp_fill_rq(skb->data, skb->len,proto, lp->ppp_minor); /* push data to pppd device */
- dev_kfree_skb(skb,FREE_WRITE);
+ skb->free = 1;
+ dev_kfree_skb(skb,0 /* FREE_READ */ );
return;
}
/*
* send ppp frame .. we expect a PIDCOMPressable proto --
* (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
+ *
+ * VJ compression may change skb pointer!!! .. requeue with old
+ * skb isn't allowed!!
*/
int isdn_ppp_xmit(struct sk_buff *skb, struct device *dev)
#ifdef CONFIG_ISDN_PPP_VJ
if (ipts->pppcfg & SC_COMP_TCP) { /* ipts here? probably yes .. but check again */
- u_char *buf = skb->data;
- int pktlen;
+ struct sk_buff *new_skb;
int len = 4;
#ifdef CONFIG_ISDN_MPP
if (ipt->mpppcfg & SC_MP_PROT) /* sigh */ /* ipt or ipts ?? */
else
len += 5;
#endif
- buf += len;
- pktlen = slhc_compress(ipts->slcomp, buf, skb->len-len, ipts->cbuf,
- &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
- skb_trim(skb,pktlen+len);
- if(buf != skb->data+len) { /* copied to new buffer ??? (btw: WHY must slhc copy it?? *sigh*) */
- memcpy(skb->data+len,buf,pktlen);
- }
- if (skb->data[len] & SL_TYPE_COMPRESSED_TCP) { /* cslip? style -> PPP */
- proto = PPP_VJC_COMP;
- skb->data[len] ^= SL_TYPE_COMPRESSED_TCP;
- } else {
- if (skb->data[len] >= SL_TYPE_UNCOMPRESSED_TCP)
- proto = PPP_VJC_UNCOMP;
- skb->data[len] = (skb->data[len] & 0x0f) | 0x40;
+ new_skb = dev_alloc_skb(skb->len);
+ if(new_skb) {
+ u_char *buf;
+ int pktlen;
+
+ new_skb->dev = skb->dev;
+ new_skb->free = 1;
+ skb_put(new_skb,skb->len);
+ skb_pull(skb,len); /* pull PPP header */
+ skb_pull(new_skb,len); /* pull PPP header */
+ buf = skb->data;
+
+ pktlen = slhc_compress(ipts->slcomp, skb->data, skb->len, new_skb->data,
+ &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
+
+ if(buf != skb->data) { /* copied to new buffer ??? (btw: WHY must slhc copy it?? *sigh*) */
+ if(new_skb->data != buf)
+ printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n");
+ dev_kfree_skb(skb,FREE_WRITE);
+ skb = new_skb;
+ }
+ else {
+ dev_kfree_skb(new_skb,0 /* FREE_WRITE */ );
+ }
+
+ skb_trim(skb,pktlen);
+ if (skb->data[0] & SL_TYPE_COMPRESSED_TCP) { /* cslip? style -> PPP */
+ proto = PPP_VJC_COMP;
+ skb->data[0] ^= SL_TYPE_COMPRESSED_TCP;
+ } else {
+ if (skb->data[0] >= SL_TYPE_UNCOMPRESSED_TCP)
+ proto = PPP_VJC_UNCOMP;
+ skb->data[0] = (skb->data[0] & 0x0f) | 0x40;
+ }
+ skb_push(skb,len);
}
}
#endif
/* tx-stats are now updated via BSENT-callback */
if(isdn_net_send_skb(dev , lp , skb)) {
if(lp->sav_skb) { /* whole sav_skb processing with disabled IRQs ?? */
- printk(KERN_ERR "%s: whoops .. there is another stored skb!\n!",dev->name);
+ printk(KERN_ERR "%s: whoops .. there is another stored skb!\n",dev->name);
dev_kfree_skb(skb,FREE_WRITE);
}
else
p->ib.sq = NULL;
while(q) {
struct sqqueue *qn = q->next;
- if(q->skb)
- dev_kfree_skb(q->skb,FREE_WRITE);
+ if(q->skb) {
+ q->skb->free = 1;
+ dev_kfree_skb(q->skb,0 /* FREE_READ */ );
+ }
kfree(q);
q = qn;
}
struct mpqueue *ql, *q = p->mp_last;
while (q) {
ql = q->next;
- dev_kfree_skb(q->skb,FREE_WRITE);
+ q->skb->free = 1;
+ dev_kfree_skb(q->skb,0 /* FREE_READ */ );
kfree(q);
q = ql;
}
if (!(*skb)) {
while (q) {
struct mpqueue *ql = q->next;
- dev_kfree_skb(q->skb,FREE_WRITE);
+ q->skb->free = 1;
+ dev_kfree_skb(q->skb,0 /* FREE_READ */ );
kfree(q);
q = ql;
}
struct mpqueue *ql = q->next;
memcpy((*skb)->data + cnt, q->skb->data, q->skb->len);
cnt += q->skb->len;
- dev_kfree_skb(q->skb,FREE_WRITE);
+ q->skb->free = 1;
+ dev_kfree_skb(q->skb,0 /* FREE_READ */ );
kfree(q);
q = ql;
}
q->next->last = NULL;
while (q) {
ql = q->last;
- dev_kfree_skb(q->skb,FREE_WRITE);
+ q->skb->free = 1;
+ dev_kfree_skb(q->skb,0 /* FREE_READ */ );
kfree(q);
#ifdef CONFIG_ISDN_PPP_VJ
toss = 1;
int len;
isdn_net_local *lp = (isdn_net_local *) dev->priv;
-#if 1
+#if 0
printk(KERN_DEBUG "ippp, dev_ioctl: cmd %#08x , %d \n",cmd,lp->ppp_minor);
#endif
we actually have room for this packet.
*/
+#if 0
+ /* unstable optimization */
if (inw(ioaddr + TxFree) > skb->len) /* We actually have free room. */
dev->tbusy = 0; /* Fake out the check below. */
- else if (dev->tbusy) {
+ else
+#endif
+ if (dev->tbusy) {
/* Transmitter timeout, serious problems. */
int tickssofar = jiffies - dev->trans_start;
int i;
#include <linux/module.h>
-#include <endian.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/segment.h>
+#include <asm/byteorder.h>
#include <linux/if.h>
union { /* hash value */
unsigned long fcode;
struct {
-#ifndef BIG_ENDIAN_BITFIELD /* Little endian order */
+#if defined(__LITTLE_ENDIAN) /* Little endian order */
unsigned short prefix; /* preceding code */
unsigned char suffix; /* last character of new code */
unsigned char pad;
-#else /* Big endian order */
+#elif defined(__BIG_ENDIAN) /* Big endian order */
unsigned char pad;
unsigned char suffix; /* last character of new code */
unsigned short prefix; /* preceding code */
printk("Room left at tail: %d\n", skb_tailroom(skb));
printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
#endif
- if (skb_headroom(skb) >= max_headroom) {
+ if (skb_headroom(skb) >= max_headroom && skb->free) {
skb->h.iph = (struct iphdr *) skb_push(skb, tunnel_hlen);
+ skb_device_unlock(skb);
} else {
struct sk_buff *new_skb;
iph->tot_len = htons(skb->len);
iph->id = htons(ip_id_count++); /* Race condition here? */
ip_send_check(iph);
- skb->ip_hdr = skb->h.iph;
+ skb->ip_hdr = skb->h.iph;
skb->protocol = htons(ETH_P_IP);
#ifdef TUNNEL_DEBUG
printk("New IP Header....\n");
*/
#ifdef CONFIG_IP_FORWARD
- if (ip_forward(skb, dev, 0, target))
+ if (ip_forward(skb, dev, IPFWD_NOTTLDEC, target))
#endif
kfree_skb(skb, FREE_WRITE);
*/
#include <linux/module.h>
-#include <endian.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
case MODE_SELECT:
case WRITE_6:
case WRITE_10:
+ case START_STOP: /* also SCAN, which may do DATA OUT */
#if 0
printk("scsi%d : command is ", host->host_no);
print_command(cmd->cmnd);
* These commands do no data transfer, we should force an
* interrupt if a data phase is attempted on them.
*/
- case START_STOP:
case TEST_UNIT_READY:
datain = dataout = 0;
break;
*/
-#define BusLogic_DriverVersion "2.0.5"
-#define BusLogic_DriverDate "7 July 1996"
+#define BusLogic_DriverVersion "2.0.6"
+#define BusLogic_DriverDate "17 July 1996"
#include <linux/module.h>
/*
- BusLogic_DriverInfo returns the Board Name to identify this SCSI Driver
+ BusLogic_DriverInfo returns the Controller Name to identify this SCSI Driver
and Host Adapter.
*/
{
BusLogic_HostAdapter_T *HostAdapter =
(BusLogic_HostAdapter_T *) Host->hostdata;
- return HostAdapter->BoardName;
+ return HostAdapter->ControllerName;
}
the Host Adapter (including any discarded data); on failure, it returns
-1 if the command was invalid, or -2 if a timeout occurred.
- This function is only called during board detection and initialization, so
- performance and latency are not critical, and exclusive access to the Host
- Adapter hardware is assumed. Once the board and driver are initialized, the
- only Host Adapter command that is issued is the single byte Execute Mailbox
- Command operation code , which does not require waiting for the Host Adapter
- Ready bit to be set in the Status Register.
+ This function is only called during controller detection and initialization,
+ so performance and latency are not critical, and exclusive access to the Host
+ Adapter hardware is assumed. Once the controller and driver are initialized,
+ the only Host Adapter command that is issued is the single byte Execute
+ Mailbox Command operation code, which does not require waiting for the Host
+ Adapter Ready bit to be set in the Status Register.
*/
static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
{
case BusLogic_InquireInstalledDevicesID0to7:
case BusLogic_InquireInstalledDevicesID8to15:
- case BusLogic_InquireDevices:
+ case BusLogic_InquireTargetDevices:
/* Approximately 60 seconds. */
TimeoutCounter = loops_per_sec << 2;
break;
rejected later when the Inquire Extended Setup Information command is
issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
BusLogic clone that implements the same interface as earlier BusLogic
- boards, including the undocumented commands, and is therefore supported by
- this driver. However, the AMI FastDisk always returns 0x00 upon reading
- the Geometry Register, so the extended translation option should always be
- left disabled on the AMI FastDisk.
+ controllers, including the undocumented commands, and is therefore
+ supported by this driver. However, the AMI FastDisk always returns 0x00
+ upon reading the Geometry Register, so the extended translation option
+ should always be left disabled on the AMI FastDisk.
*/
GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
if (TraceProbe)
BusLogic_Configuration_T Configuration;
BusLogic_SetupInformation_T SetupInformation;
BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
- BusLogic_BoardModelNumber_T BoardModelNumber;
+ BusLogic_ControllerModelNumber_T ControllerModelNumber;
BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
BusLogic_GenericIOPortInformation_T GenericIOPortInformation;
!= sizeof(ExtendedSetupInformation))
return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
/*
- Issue the Inquire Board Model Number command.
+ Issue the Inquire Controller Model Number command.
*/
if (ExtendedSetupInformation.BusType == 'A' &&
BoardID.FirmwareVersion1stDigit == '2')
/* BusLogic BT-542B ISA 2.xx */
- strcpy(BoardModelNumber, "542B");
+ strcpy(ControllerModelNumber, "542B");
else if (ExtendedSetupInformation.BusType == 'E' &&
BoardID.FirmwareVersion1stDigit == '0')
/* AMI FastDisk EISA Series 441 0.x */
- strcpy(BoardModelNumber, "747A");
+ strcpy(ControllerModelNumber, "747A");
else
{
- RequestedReplyLength = sizeof(BoardModelNumber);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelNumber,
+ RequestedReplyLength = sizeof(ControllerModelNumber);
+ if (BusLogic_Command(HostAdapter, BusLogic_InquireControllerModelNumber,
&RequestedReplyLength, sizeof(RequestedReplyLength),
- &BoardModelNumber, sizeof(BoardModelNumber))
- != sizeof(BoardModelNumber))
- return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL NUMBER");
+ &ControllerModelNumber,
+ sizeof(ControllerModelNumber))
+ != sizeof(ControllerModelNumber))
+ return BusLogic_Failure(HostAdapter, "INQUIRE CONTROLLER MODEL NUMBER");
}
/*
Issue the Inquire Firmware Version 3rd Digit command.
0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
*/
/*
- Save the Model Name and Board Name in the Host Adapter structure.
+ Save the Model Name and Controller Name in the Host Adapter structure.
*/
TargetPointer = HostAdapter->ModelName;
*TargetPointer++ = 'B';
*TargetPointer++ = 'T';
*TargetPointer++ = '-';
- for (i = 0; i < sizeof(BoardModelNumber); i++)
+ for (i = 0; i < sizeof(ControllerModelNumber); i++)
{
- Character = BoardModelNumber[i];
+ Character = ControllerModelNumber[i];
if (Character == ' ' || Character == '\0') break;
*TargetPointer++ = Character;
}
*TargetPointer++ = '\0';
- strcpy(HostAdapter->BoardName, "BusLogic ");
- strcat(HostAdapter->BoardName, HostAdapter->ModelName);
- strcpy(HostAdapter->InterruptLabel, HostAdapter->BoardName);
+ strcpy(HostAdapter->ControllerName, "BusLogic ");
+ strcat(HostAdapter->ControllerName, HostAdapter->ModelName);
+ strcpy(HostAdapter->InterruptLabel, HostAdapter->ControllerName);
/*
Save the Firmware Version in the Host Adapter structure.
*/
/*
Save the Disconnect/Reconnect Permitted flag bits in the Host Adapter
structure. The Disconnect Permitted information is only valid on "W" and
- "C" Series boards, but Disconnect/Reconnect is always permitted on "S" and
- "A" Series boards.
+ "C" Series controllers, but Disconnect/Reconnect is always permitted on "S"
+ and "A" Series controllers.
*/
if (HostAdapter->FirmwareVersion[0] >= '4')
HostAdapter->DisconnectPermitted =
HostAdapter->HostAutomaticConfiguration =
ExtendedSetupInformation.HostAutomaticConfiguration;
HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
+ /*
+ Determine whether 64 LUN Format CCBs are supported and save the information
+ in the Host Adapter structure.
+ */
+ if (HostAdapter->FirmwareVersion[0] == '5' ||
+ (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
+ HostAdapter->Host64LUNSupport = true;
/*
Determine the Host Adapter BIOS Address if the BIOS is enabled and
save it in the Host Adapter structure. The BIOS is disabled if the
if (HostAdapter->BusType == BusLogic_ISA_Bus && high_memory > MAX_DMA_ADDRESS)
HostAdapter->BounceBuffersRequired = true;
/*
- BusLogic BT-445S Host Adapters prior to board revision E have a hardware
- bug whereby when the BIOS is enabled, transfers to/from the same address
- range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
- functioning BT-445S boards have firmware version 3.37, so we require that
- ISA Bounce Buffers be used for the buggy BT-445S models if there is more
- than 16MB memory.
+ BusLogic BT-445S Host Adapters prior to controller revision E have a
+ hardware bug whereby when the BIOS is enabled, transfers to/from the same
+ address range the BIOS occupies modulo 16MB are handled incorrectly. Only
+ properly functioning BT-445S controllers have firmware version 3.37, so we
+ require that ISA Bounce Buffers be used for the buggy BT-445S models if
+ there is more than 16MB memory.
*/
if (HostAdapter->BIOS_Address > 0 &&
strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
Determine the maximum number of Target IDs and Logical Units supported by
this driver for Wide and Narrow Host Adapters.
*/
- if (HostAdapter->HostWideSCSI)
- {
- HostAdapter->MaxTargetDevices = 16;
- HostAdapter->MaxLogicalUnits = 64;
- }
- else
- {
- HostAdapter->MaxTargetDevices = 8;
- HostAdapter->MaxLogicalUnits = 8;
- }
+ HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
+ HostAdapter->MaxLogicalUnits = (HostAdapter->Host64LUNSupport ? 64 : 8);
/*
Select appropriate values for the Mailbox Count, Initial CCBs, and
Incremental CCBs variables based on whether or not Strict Round Robin Mode
*/
if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
{
- HostAdapter->StrictRoundRobinModeSupported = true;
+ HostAdapter->StrictRoundRobinModeSupport = true;
HostAdapter->MailboxCount = 255;
HostAdapter->InitialCCBs = 64;
HostAdapter->IncrementalCCBs = 32;
}
else
{
- HostAdapter->StrictRoundRobinModeSupported = false;
+ HostAdapter->StrictRoundRobinModeSupport = false;
HostAdapter->MailboxCount = 32;
HostAdapter->InitialCCBs = 32;
HostAdapter->IncrementalCCBs = 4;
sizeof(HostAdapter->ErrorRecoveryStrategy));
/*
Tagged Queuing support is available and operates properly on all "W" Series
- boards, on "C" Series boards with firmware version 4.22 and above, and on
- "S" Series boards with firmware version 3.35 and above. Tagged Queuing is
- disabled by default when the Tagged Queue Depth is 1 since queuing multiple
- commands is not possible.
+ controllers, on "C" Series controllers with firmware version 4.22 and
+ above, and on "S" Series controllers with firmware version 3.35 and above.
+ Tagged Queuing is disabled by default when the Tagged Queue Depth is 1
+ since queuing multiple commands is not possible.
*/
TaggedQueuingPermittedDefault = 0;
if (HostAdapter->TaggedQueueDepth != 1)
*/
if (HostAdapter->DMA_Channel > 0)
{
- if (request_dma(HostAdapter->DMA_Channel, HostAdapter->BoardName) < 0)
+ if (request_dma(HostAdapter->DMA_Channel,
+ HostAdapter->ControllerName) < 0)
{
printk("scsi%d: UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
HostAdapter->HostNumber, HostAdapter->DMA_Channel);
{
BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
- BusLogic_WideModeCCBRequest_T WideModeCCBRequest;
+ BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
int TargetID;
/*
Outgoing Mailboxes to find any that have new commands in them. Strict
Round Robin Mode is significantly more efficient.
*/
- if (HostAdapter->StrictRoundRobinModeSupported)
+ if (HostAdapter->StrictRoundRobinModeSupport)
{
RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
}
/*
- For Wide SCSI Host Adapters, issue the Enable Wide Mode CCB command to
- allow more than 8 Logical Units per Target Device to be supported.
+ For Host Adapters that support 64 LUN Format CCBs, issue the Set CCB Format
+ command to allow 64 Logical Units per Target Device.
*/
- if (HostAdapter->HostWideSCSI)
+ if (HostAdapter->Host64LUNSupport)
{
- WideModeCCBRequest = BusLogic_WideModeCCB;
- if (BusLogic_Command(HostAdapter, BusLogic_EnableWideModeCCB,
- &WideModeCCBRequest,
- sizeof(WideModeCCBRequest), NULL, 0) < 0)
- return BusLogic_Failure(HostAdapter, "ENABLE WIDE MODE CCB");
+ SetCCBFormatRequest = BusLogic_64LUNFormatCCB;
+ if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
+ &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
+ NULL, 0) < 0)
+ return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
}
/*
For PCI Host Adapters being accessed through the PCI compliant I/O
Announce Successful Initialization.
*/
printk("scsi%d: *** %s Initialized Successfully ***\n",
- HostAdapter->HostNumber, HostAdapter->BoardName);
+ HostAdapter->HostNumber, HostAdapter->ControllerName);
/*
Indicate the Host Adapter Initialization completed successfully.
*/
/*
- BusLogic_InquireTargetDevices inquires about the Target Devices accessible
+ BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
through Host Adapter and reports on the results.
*/
-static boolean BusLogic_InquireTargetDevices(BusLogic_HostAdapter_T
- *HostAdapter)
+static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
+ *HostAdapter)
{
BusLogic_InstalledDevices_T InstalledDevices;
BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
return true;
}
/*
- Issue the Inquire Devices command for boards with firmware version 4.25 or
- later, or the Inquire Installed Devices ID 0 to 7 command for older boards.
- This is necessary to force Synchronous Transfer Negotiation so that the
- Inquire Setup Information and Inquire Synchronous Period commands will
- return valid data. The Inquire Devices command is preferable to Inquire
- Installed Devices ID 0 to 7 since it only probes Logical Unit 0 of each
- Target Device.
+ Issue the Inquire Target Devices command for controllers with firmware
+ version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
+ for older controllers. This is necessary to force Synchronous Transfer
+ Negotiation so that the Inquire Setup Information and Inquire Synchronous
+ Period commands will return valid data. The Inquire Target Devices command
+ is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
+ Logical Unit 0 of each Target Device.
*/
if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
{
- if (BusLogic_Command(HostAdapter, BusLogic_InquireDevices, NULL, 0,
+ if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
&InstalledDevices, sizeof(InstalledDevices))
!= sizeof(InstalledDevices))
- return BusLogic_Failure(HostAdapter, "INQUIRE DEVICES");
+ return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
}
else
{
Read the Host Adapter Configuration, Acquire the System Resources
necessary to use Host Adapter and initialize the fields in the SCSI
Host structure, then Test Interrupts, Create the Mailboxes and CCBs,
- Initialize the Host Adapter, and finally Inquire about the Target
- Devices.
+ Initialize the Host Adapter, and finally perform Target Device Inquiry.
*/
if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
BusLogic_AcquireResources(HostAdapter) &&
BusLogic_CreateMailboxes(HostAdapter) &&
BusLogic_CreateCCBs(HostAdapter) &&
BusLogic_InitializeHostAdapter(HostAdapter) &&
- BusLogic_InquireTargetDevices(HostAdapter))
+ BusLogic_TargetDeviceInquiry(HostAdapter))
{
/*
Initialization has been completed successfully. Release and
*/
release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
- HostAdapter->BoardName);
+ HostAdapter->ControllerName);
BusLogic_InitializeHostStructure(HostAdapter, Host);
BusLogicHostAdapterCount++;
}
HostStatus = DID_RESET;
break;
default:
- printk("BusLogic: unknown Host Adapter Status 0x%02X\n",
+ printk("BusLogic: Unknown Host Adapter Status 0x%02X\n",
HostAdapterStatus);
HostStatus = DID_ERROR;
break;
CCB->TargetID = TargetID;
CCB->LogicalUnit = LogicalUnit;
/*
- For Wide SCSI Host Adapters, Wide Mode CCBs are used to support more than
- 8 Logical Units per Target, and this requires setting the overloaded
+ For Host Adapters that support it, 64 LUN Format CCBs are used to allow
+ 64 Logical Units per Target, and this requires setting the overloaded
TagEnable field to Logical Unit bit 5.
*/
- if (HostAdapter->HostWideSCSI)
+ if (HostAdapter->Host64LUNSupport)
{
CCB->TagEnable = LogicalUnit >> 5;
- CCB->WideModeTagEnable = false;
+ CCB->TagEnable64LUN = false;
}
else CCB->TagEnable = false;
/*
are sent to a Target Device be sent in a non Tagged Queue fashion so that
the Host Adapter and Target Device can establish Synchronous and Wide
Transfer before Queue Tag messages can interfere with the Synchronous and
- Wide Negotiation message. By waiting to enable Tagged Queuing until after
- the first 2*BusLogic_PreferredQueueDepth commands have been sent, it is
- assured that after a Reset any pending commands are resent before Tagged
+ Wide Negotiation messages. By waiting to enable Tagged Queuing until after
+ the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
+ assured that after a Reset any pending commands are requeued before Tagged
Queuing is enabled and that the Tagged Queuing message will not occur while
- the partition table is being printed.
- */
- if (HostAdapter->TotalCommandCount[TargetID]++ ==
- 2*BusLogic_PreferredTaggedQueueDepth &&
+ the partition table is being printed. In addition, some devices do not
+ properly handle the transition from non-tagged to tagged commands, so it is
+ necessary to wait until there are no pending commands for a target device
+ before queuing tagged commands.
+ */
+ if (HostAdapter->TotalCommandCount[TargetID]++ >=
+ BusLogic_MaxTaggedQueueDepth &&
+ !HostAdapter->TaggedQueuingActive[TargetID] &&
+ HostAdapter->ActiveCommandCount[TargetID] == 0 &&
(HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
Command->device->tagged_supported)
{
write nearer the head position continue to arrive without interruption.
Therefore, for each Target Device this driver keeps track of the last
time either the queue was empty or an Ordered Queue Tag was issued. If
- more than 5 seconds (half the 10 second disk timeout) have elapsed
- since this last sequence point, this command will be issued with an
- Ordered Queue Tag rather than a Simple Queue Tag, which forces the
- Target Device to complete all previously queued commands before this
- command may be executed.
+ more than 5 seconds (one third of the 15 second disk timeout) have
+ elapsed since this last sequence point, this command will be issued
+ with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
+ the Target Device to complete all previously queued commands before
+ this command may be executed.
*/
if (HostAdapter->ActiveCommandCount[TargetID] == 0)
HostAdapter->LastSequencePoint[TargetID] = jiffies;
HostAdapter->LastSequencePoint[TargetID] = jiffies;
QueueTag = BusLogic_OrderedQueueTag;
}
- if (HostAdapter->HostWideSCSI)
+ if (HostAdapter->Host64LUNSupport)
{
- CCB->WideModeTagEnable = true;
- CCB->WideModeQueueTag = QueueTag;
+ CCB->TagEnable64LUN = true;
+ CCB->QueueTag64LUN = QueueTag;
}
else
{
}
if (Command == NULL)
printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
- HostAdapter->HostNumber, HostAdapter->BoardName);
+ HostAdapter->HostNumber, HostAdapter->ControllerName);
else printk("scsi%d: Resetting %s due to Target %d\n",
- HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
+ HostAdapter->HostNumber, HostAdapter->ControllerName,
+ Command->target);
/*
Attempt to Reset and Reinitialize the Host Adapter.
*/
BusLogic_InitializeHostAdapter(HostAdapter)))
{
printk("scsi%d: Resetting %s Failed\n",
- HostAdapter->HostNumber, HostAdapter->BoardName);
+ HostAdapter->HostNumber, HostAdapter->ControllerName);
Result = SCSI_RESET_ERROR;
goto Done;
}
/*
BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
- Parameters for Disk. The default disk geometry is 64 heads, 32 sectors,
- and the appropriate number of cylinders so as not to exceed drive capacity.
- In order for disks equal to or larger than 1 GB to be addressable by the
- BIOS without exceeding the BIOS limitation of 1024 cylinders, Extended
- Translation may be enabled in AutoSCSI on "W" and "C" Series boards or by a
- dip switch setting on older boards. With Extended Translation enabled,
- drives between 1 GB inclusive and 2 GB exclusive are given a disk geometry
- of 128 heads and 32 sectors, and drives above 2 GB inclusive are given a
- disk geometry of 255 heads and 63 sectors. However, if the BIOS detects
- that the Extended Translation setting does not match the geometry in the
- partition table, then the translation inferred from the partition table
- will be used by the BIOS, and a warning may be displayed.
+ Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
+ the appropriate number of cylinders so as not to exceed drive capacity. In
+ order for disks equal to or larger than 1 GB to be addressable by the BIOS
+ without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
+ may be enabled in AutoSCSI on "W" and "C" Series controllers or by a dip
+ switch setting on older controllers. With Extended Translation enabled,
+ drives between 1 GB inclusive and 2 GB exclusive are given a disk geometry of
+ 128 heads and 32 sectors, and drives above 2 GB inclusive are given a disk
+ geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
+ Extended Translation setting does not match the geometry in the partition
+ table, then the translation inferred from the partition table will be used by
+ the BIOS, and a warning may be displayed.
*/
int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
/*
- Define the possible Local Options.
+ Define the possible Probe Options.
*/
-#define BusLogic_InhibitTargetInquiry 1
+#define BusLogic_NoProbe 1
+#define BusLogic_NoProbeISA 2
+#define BusLogic_NoSortPCI 4
/*
- Define the possible Probe Options.
+ Define the possible Local Options.
*/
-#define BusLogic_NoProbe 1
-#define BusLogic_NoProbeISA 2
-#define BusLogic_NoSortPCI 4
+#define BusLogic_InhibitTargetInquiry 1
/*
#define BusLogic_CommandParameterRegister 1 /* WO register */
#define BusLogic_DataInRegister 1 /* RO register */
#define BusLogic_InterruptRegister 2 /* RO register */
-#define BusLogic_GeometryRegister 3 /* RO, undocumented */
+#define BusLogic_GeometryRegister 3 /* RO register */
/*
/*
- Define the bits in the undocumented read-only Geometry Register.
+ Define the bits in the read-only Geometry Register.
*/
#define BusLogic_Drive0Geometry 0x03
typedef enum
{
- BusLogic_TestCommandCompleteInterrupt = 0x00, /* documented */
- BusLogic_InitializeMailbox = 0x01, /* documented */
- BusLogic_ExecuteMailboxCommand = 0x02, /* documented */
- BusLogic_ExecuteBIOSCommand = 0x03, /* documented */
- BusLogic_InquireBoardID = 0x04, /* documented */
- BusLogic_EnableOutgoingMailboxAvailableInt = 0x05, /* documented */
- BusLogic_SetSCSISelectionTimeout = 0x06, /* documented */
- BusLogic_SetPreemptTimeOnBus = 0x07, /* documented */
- BusLogic_SetTimeOffBus = 0x08, /* ISA Bus only */
- BusLogic_SetBusTransferRate = 0x09, /* ISA Bus only */
- BusLogic_InquireInstalledDevicesID0to7 = 0x0A, /* documented */
- BusLogic_InquireConfiguration = 0x0B, /* documented */
- BusLogic_SetTargetMode = 0x0C, /* now undocumented */
- BusLogic_InquireSetupInformation = 0x0D, /* documented */
- BusLogic_WriteAdapterLocalRAM = 0x1A, /* documented */
- BusLogic_ReadAdapterLocalRAM = 0x1B, /* documented */
- BusLogic_WriteBusMasterChipFIFO = 0x1C, /* documented */
- BusLogic_ReadBusMasterChipFIFO = 0x1D, /* documented */
- BusLogic_EchoCommandData = 0x1F, /* documented */
- BusLogic_HostAdapterDiagnostic = 0x20, /* documented */
- BusLogic_SetAdapterOptions = 0x21, /* documented */
- BusLogic_InquireInstalledDevicesID8to15 = 0x23, /* Wide only */
- BusLogic_InquireDevices = 0x24, /* "W" and "C" only */
- BusLogic_InitializeExtendedMailbox = 0x81, /* documented */
- BusLogic_InquireFirmwareVersion3rdDigit = 0x84, /* undocumented */
- BusLogic_InquireFirmwareVersionLetter = 0x85, /* undocumented */
- BusLogic_InquireGenericIOPortInformation = 0x86, /* PCI only */
- BusLogic_InquireBoardModelNumber = 0x8B, /* undocumented */
- BusLogic_InquireSynchronousPeriod = 0x8C, /* undocumented */
- BusLogic_InquireExtendedSetupInformation = 0x8D, /* documented */
- BusLogic_EnableStrictRoundRobinMode = 0x8F, /* documented */
- BusLogic_FetchHostAdapterLocalRAM = 0x91, /* undocumented */
- BusLogic_ModifyIOAddress = 0x95, /* PCI only */
- BusLogic_EnableWideModeCCB = 0x96 /* Wide only */
+ BusLogic_TestCommandCompleteInterrupt = 0x00,
+ BusLogic_InitializeMailbox = 0x01,
+ BusLogic_ExecuteMailboxCommand = 0x02,
+ BusLogic_ExecuteBIOSCommand = 0x03,
+ BusLogic_InquireBoardID = 0x04,
+ BusLogic_EnableOutgoingMailboxAvailableInt = 0x05,
+ BusLogic_SetSCSISelectionTimeout = 0x06,
+ BusLogic_SetPreemptTimeOnBus = 0x07,
+ BusLogic_SetTimeOffBus = 0x08,
+ BusLogic_SetBusTransferRate = 0x09,
+ BusLogic_InquireInstalledDevicesID0to7 = 0x0A,
+ BusLogic_InquireConfiguration = 0x0B,
+ BusLogic_EnableTargetMode = 0x0C,
+ BusLogic_InquireSetupInformation = 0x0D,
+ BusLogic_WriteAdapterLocalRAM = 0x1A,
+ BusLogic_ReadAdapterLocalRAM = 0x1B,
+ BusLogic_WriteBusMasterChipFIFO = 0x1C,
+ BusLogic_ReadBusMasterChipFIFO = 0x1D,
+ BusLogic_EchoCommandData = 0x1F,
+ BusLogic_HostAdapterDiagnostic = 0x20,
+ BusLogic_SetAdapterOptions = 0x21,
+ BusLogic_InquireInstalledDevicesID8to15 = 0x23,
+ BusLogic_InquireTargetDevices = 0x24,
+ BusLogic_DisableHostAdapterInterrupt = 0x25,
+ BusLogic_InitializeExtendedMailbox = 0x81,
+ BusLogic_ExecuteSCSICommand = 0x83,
+ BusLogic_InquireFirmwareVersion3rdDigit = 0x84,
+ BusLogic_InquireFirmwareVersionLetter = 0x85,
+ BusLogic_InquireGenericIOPortInformation = 0x86,
+ BusLogic_InquireControllerModelNumber = 0x8B,
+ BusLogic_InquireSynchronousPeriod = 0x8C,
+ BusLogic_InquireExtendedSetupInformation = 0x8D,
+ BusLogic_EnableStrictRoundRobinMode = 0x8F,
+ BusLogic_StoreHostAdapterLocalRAM = 0x90,
+ BusLogic_FetchHostAdapterLocalRAM = 0x91,
+ BusLogic_StoreLocalDataInEEPROM = 0x92,
+ BusLogic_UploadAutoSCSICode = 0x94,
+ BusLogic_ModifyIOAddress = 0x95,
+ BusLogic_SetCCBFormat = 0x96,
+ BusLogic_WriteInquiryBuffer = 0x9A,
+ BusLogic_ReadInquiryBuffer = 0x9B,
+ BusLogic_FlashROMUploadDownload = 0xA7,
+ BusLogic_ReadSCAMData = 0xA8,
+ BusLogic_WriteSCAMData = 0xA9
}
BusLogic_OperationCode_T;
/*
- Define the Inquire Devices reply type. Inquire Devices only tests Logical
- Unit 0 of each Target Device unlike Inquire Installed Devices which tests
- Logical Units 0 - 7. Two bytes are returned, where bit 0 set indicates
- that Target Device 0 exists, and so on.
+ Define the Inquire Target Devices reply type. Inquire Target Devices only
+ tests Logical Unit 0 of each Target Device unlike the Inquire Installed
+ Devices commands which test Logical Units 0 - 7. Two bytes are returned,
+ where bit 0 set indicates that Target Device 0 exists, and so on.
*/
typedef unsigned short BusLogic_InstalledDevices_T;
unsigned char DisconnectPermittedID0to7; /* Byte 16 */
unsigned char Signature; /* Byte 17 */
unsigned char CharacterD; /* Byte 18 */
- unsigned char BusLetter; /* Byte 19 */
+ unsigned char HostBusType; /* Byte 19 */
unsigned char :8; /* Byte 20 */
unsigned char :8; /* Byte 21 */
BusLogic_SynchronousValues8_T SynchronousValuesID8to15; /* Bytes 22-29 */
/*
- Define the Inquire Board Model Number reply type.
+ Define the Inquire Controller Model Number reply type.
*/
-typedef unsigned char BusLogic_BoardModelNumber_T[5];
+typedef unsigned char BusLogic_ControllerModelNumber_T[5];
/*
boolean HostDifferentialSCSI:1; /* Byte 13 Bit 1 */
boolean HostAutomaticConfiguration:1; /* Byte 13 Bit 2 */
boolean HostUltraSCSI:1; /* Byte 13 Bit 3 */
- unsigned char :4; /* Byte 13 Bits 4-7 */
+ boolean HostSmartTermination:1; /* Byte 13 Bit 4 */
+ unsigned char :3; /* Byte 13 Bits 5-7 */
}
BusLogic_ExtendedSetupInformation_T;
/*
- Define the Enable Wide Mode SCSI CCB request type. Wide Mode CCBs are
- necessary to support more than 8 Logical Units per Target Device.
+ Define the Set CCB Format request type. 64 LUN Format CCBs are necessary to
+ support 64 Logical Units per Target Device. 8 LUN Format CCBs only support 8
+ Logical Units per Target Device.
*/
-#define BusLogic_NormalModeCCB 0x00
-#define BusLogic_WideModeCCB 0x01
+#define BusLogic_8LUNFormatCCB 0x00
+#define BusLogic_64LUNFormatCCB 0x01
-typedef unsigned char BusLogic_WideModeCCBRequest_T;
+typedef unsigned char BusLogic_SetCCBFormatRequest_T;
/*
Define the Requested Reply Length type used by the Inquire Setup Information,
- Inquire Board Model Number, Inquire Synchronous Period, and Inquire Extended
- Setup Information commands.
+ Inquire Controller Model Number, Inquire Synchronous Period, and Inquire
+ Extended Setup Information commands.
*/
typedef unsigned char BusLogic_RequestedReplyLength_T;
/*
Define the 32 Bit Mode Command Control Block (CCB) structure. The first 40
bytes are defined by the Host Adapter Firmware Interface. The remaining
- components are defined by the Linux BusLogic Driver. Wide Mode CCBs differ
- from standard 32 Bit Mode CCBs only in having the TagEnable and QueueTag
- fields moved from byte 17 to byte 1, and the Logical Unit field in byte 17
- expanded to 6 bits; unfortunately, using a union of structs containing
- enumeration type bitfields to provide both definitions leads to packing
- problems, so the following definition is used which requires setting
- TagEnable to Logical Unit bit 5 in Wide Mode CCBs.
+ components are defined by the Linux BusLogic Driver. 64 LUN Format CCBs
+ differ from standard 8 LUN Format 32 Bit Mode CCBs only in having the
+ TagEnable and QueueTag fields moved from byte 17 to byte 1, and the Logical
+ Unit field in byte 17 expanded to 6 bits; unfortunately, using a union of
+ structs containing enumeration type bitfields to provide both definitions
+ leads to packing problems, so the following definition is used which requires
+ setting TagEnable to Logical Unit bit 5 in 64 LUN Format CCBs.
*/
typedef struct BusLogic_CCB
BusLogic_CCB_Opcode_T Opcode:8; /* Byte 0 */
unsigned char :3; /* Byte 1 Bits 0-2 */
BusLogic_DataDirection_T DataDirection:2; /* Byte 1 Bits 3-4 */
- boolean WideModeTagEnable:1; /* Byte 1 Bit 5 */
- BusLogic_QueueTag_T WideModeQueueTag:2; /* Byte 1 Bits 6-7 */
+ boolean TagEnable64LUN:1; /* Byte 1 Bit 5 */
+ BusLogic_QueueTag_T QueueTag64LUN:2; /* Byte 1 Bits 6-7 */
unsigned char CDB_Length; /* Byte 2 */
unsigned char SenseDataLength; /* Byte 3 */
unsigned int DataLength; /* Bytes 4-7 */
unsigned char HostNumber;
unsigned char ModelName[9];
unsigned char FirmwareVersion[6];
- unsigned char BoardName[18];
+ unsigned char ControllerName[18];
unsigned char InterruptLabel[62];
unsigned char IRQ_Channel;
unsigned char DMA_Channel;
boolean LowByteTerminated:1;
boolean HighByteTerminated:1;
boolean BounceBuffersRequired:1;
- boolean StrictRoundRobinModeSupported:1;
+ boolean StrictRoundRobinModeSupport:1;
+ boolean Host64LUNSupport:1;
boolean HostAdapterResetRequested:1;
volatile boolean HostAdapterCommandCompleted:1;
unsigned short HostAdapterScatterGatherLimit;
unsigned long ProcessorFlags;
save_flags(ProcessorFlags);
sti();
- while (jiffies < TimeoutJiffies) ;
+ while (jiffies < TimeoutJiffies) barrier();
restore_flags(ProcessorFlags);
}
BusLogic MultiMaster SCSI Driver for Linux
- Version 1.2.5 for Linux 1.2.13
- Version 2.0.5 for Linux 2.0.4
+ Version 1.2.6 for Linux 1.2.13
+ Version 2.0.6 for Linux 2.0.4
- 7 July 1996
+ 17 July 1996
Leonard N. Zubkoff
Dandelion Digital
during installation on a system with a flaky SCSI configuration. In cases
of a marginal SCSI configuration it may also be beneficial to disable fast
transfers and/or synchronous negotiation using AutoSCSI on "W" and "C"
- series boards. Disconnect/reconnect may also be disabled for fast devices
- such as disk drives, but should not be disabled for tape drives or other
- devices where a single command may take over a second to execute.
+ series controllers. Disconnect/reconnect may also be disabled for fast
+ devices such as disk drives, but should not be disabled for tape drives or
+ other devices where a single command may take over a second to execute.
"BusLogic=0,0,30"
INSTALLATION
This distribution was prepared for Linux kernel version 1.2.13
-(BusLogic-1.2.5.tar.gz) or Linux kernel version 2.0.4 (BusLogic-2.0.5.tar.gz).
+(BusLogic-1.2.6.tar.gz) or Linux kernel version 2.0.4 (BusLogic-2.0.6.tar.gz).
Installation in later versions will probably be successful as well, though
BusLogic.patch may not be required. Installation in earlier versions is not
recommended.
(substitute "1.2" or "2.0" for "x.y" in the tar command as appropriate):
cd /usr/src
- tar -xvzf BusLogic-x.y.5.tar.gz
+ tar -xvzf BusLogic-x.y.6.tar.gz
mv README.* BusLogic.[ch] linux/drivers/scsi
patch -p < BusLogic.patch (on Linux 1.2.13 only)
patch -p < BusLogic.elf_patch (on Linux 1.2.13 ELF systems only)
((unsigned int) SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
#endif
SCpnt->use_sg = count; /* Number of chains */
- count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes */
- while( count < (SCpnt->use_sg * sizeof(struct scatterlist)))
- count = count << 1;
+ /* scsi_malloc can only allocate in chunks of 512 bytes */
+ count = (SCpnt->use_sg * sizeof(struct scatterlist) + 511) & ~511;
+
SCpnt->sglist_len = count;
max_sg = count / sizeof(struct scatterlist);
if(SCpnt->host->sg_tablesize < max_sg)
};
};
SCpnt->use_sg = count; /* Number of chains */
- count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
- while( count < (SCpnt->use_sg * sizeof(struct scatterlist)))
- count = count << 1;
+ /* scsi_malloc can only allocate in chunks of 512 bytes */
+ count = (SCpnt->use_sg * sizeof(struct scatterlist) + 511) & ~511;
+
SCpnt->sglist_len = count;
sgpnt = (struct scatterlist * ) scsi_malloc(count);
if (!sgpnt) {
#define AD1848_DEVS (B(OPT_GUS16)|B(OPT_MSS)|B(OPT_PSS)|B(OPT_GUSMAX)|\
B(OPT_SSCAPE)|B(OPT_TRIX)|B(OPT_MAD16)|B(OPT_CS4232)|\
B(OPT_SPNP))
-#define SBDSP_DEVS (B(OPT_SB)|B(OPT_SPNP)|B(OPT_MAD16))
+#define SBDSP_DEVS (B(OPT_SB)|B(OPT_SPNP)|B(OPT_MAD16)|B(OPT_TRIX))
#define SEQUENCER_DEVS (OPT_MIDI|OPT_YM3812|OPT_ADLIB|OPT_GUS|OPT_MAUI|MIDI_CARDS)
/*
* Options that have been disabled for some reason (incompletely implemented
void
unload_trix_sb (struct address_info *hw_config)
{
+#ifdef CONFIG_SBDSP
unload_sb (hw_config);
+#endif
}
}
}
+static inline int
+ncp_namespace(struct inode *i)
+{
+ struct ncp_server *server = NCP_SERVER(i);
+ struct nw_info_struct *info = NCP_ISTRUCT(i);
+ return server->name_space[info->volNumber];
+}
+
+static inline int
+ncp_preserve_case(struct inode *i)
+{
+ return (ncp_namespace(i) == NW_NS_OS2);
+}
+
static struct file_operations ncp_dir_operations = {
NULL, /* lseek - default */
ncp_dir_read, /* read - bad */
/* Here we encapsulate the inode number handling that depends upon the
* mount mode: When we mount a complete server, the memory address of
* the ncp_inode_info is used as the inode number. When only a single
- * volume is mounted, then the DosDirNum is used as the inode
+ * volume is mounted, then the dirEntNum is used as the inode
* number. As this is unique for the complete volume, this should
* enable the NFS exportability of a ncpfs-mounted volume.
*/
ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info)
{
return ncp_single_volume(server)
- ? info->finfo.i.DosDirNum : (ino_t)info;
+ ? info->finfo.i.dirEntNum : (ino_t)info;
}
static inline int
return NULL;
}
-
-
static int
ncp_dir_read(struct inode *inode, struct file *filp, char *buf, int count)
{
c_last_returned_index = 0;
index = 0;
- for (i = 0; i < c_size; i++)
+ if (!ncp_preserve_case(inode))
{
- str_lower(c_entry[i].i.entryName);
+ for (i = 0; i < c_size; i++)
+ {
+ str_lower(c_entry[i].i.entryName);
+ }
}
}
}
if (ncp_single_volume(server))
{
- ino = (ino_t)(entry->i.DosDirNum);
+ ino = (ino_t)(entry->i.dirEntNum);
}
else
{
root->finfo.opened = 0;
i->attributes = aDIR;
i->dataStreamSize = 1024;
- i->DosDirNum = 0;
+ i->dirEntNum = i->DosDirNum = 0;
i->volNumber = NCP_NUMBER_OF_VOLUMES+1; /* illegal volnum */
ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));
ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate));
do
{
- if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum)
+ if ( (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum)
&& (result->dir->finfo.i.volNumber == dir_info->volNumber)
&& (strcmp(result->finfo.i.entryName, name) == 0)
/* The root dir is never looked up using this
struct ncp_server *server;
struct ncp_inode_info *result_info;
int found_in_cache;
+ int down_case = 0;
char name[len+1];
*result = NULL;
if (found_in_cache == 0)
{
int res;
- str_upper(name);
DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
NCP_ISTRUCT(dir)->entryName, name);
if (ncp_is_server_root(dir))
{
+ str_upper(name);
+ down_case = 1;
res = ncp_lookup_volume(server, name, &(finfo.i));
}
else
{
+ if (!ncp_preserve_case(dir))
+ {
+ str_upper(name);
+ down_case = 1;
+ }
res = ncp_obtain_info(server,
NCP_ISTRUCT(dir)->volNumber,
- NCP_ISTRUCT(dir)->DosDirNum,
+ NCP_ISTRUCT(dir)->dirEntNum,
name, &(finfo.i));
}
if (res != 0)
}
finfo.opened = 0;
- str_lower(finfo.i.entryName);
+
+ if (down_case != 0)
+ {
+ str_lower(finfo.i.entryName);
+ }
if (!(*result = ncp_iget(dir, &finfo)))
{
strncpy(_name, name, len);
_name[len] = '\0';
- str_upper(_name);
+
+ if (!ncp_preserve_case(dir))
+ {
+ str_upper(_name);
+ }
lock_super(dir->i_sb);
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
ncp_invalid_dir_cache(dir);
- str_lower(finfo.i.entryName);
+ if (!ncp_preserve_case(dir))
+ {
+ str_lower(finfo.i.entryName);
+ }
+
finfo.access = O_RDWR;
if (!(*result = ncp_iget(dir, &finfo)) < 0)
strncpy(_name, name, len);
_name[len] = '\0';
- str_upper(_name);
+
+ if (!ncp_preserve_case(dir))
+ {
+ str_upper(_name);
+ }
if (!dir || !S_ISDIR(dir->i_mode))
{
strncpy(_name, name, len);
_name[len] = '\0';
- str_upper(_name);
+
+ if (!ncp_preserve_case(dir))
+ {
+ str_upper(_name);
+ }
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir),
{
strncpy(_name, name, len);
_name[len] = '\0';
- str_upper(_name);
+
+ if (!ncp_preserve_case(dir))
+ {
+ str_upper(_name);
+ }
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir),
strncpy(_old_name, old_name, old_len);
_old_name[old_len] = '\0';
- str_upper(_old_name);
+
+ if (!ncp_preserve_case(old_dir))
+ {
+ str_upper(_old_name);
+ }
strncpy(_new_name, new_name, new_len);
_new_name[new_len] = '\0';
- str_upper(_new_name);
+
+ if (!ncp_preserve_case(new_dir))
+ {
+ str_upper(_new_name);
+ }
res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
NCP_ISTRUCT(old_dir), _old_name,
return 0;
}
-int
-ncp_get_volume_number(struct ncp_server *server, const char *name, int *target)
-{
- int result;
-
- ncp_init_request_s(server, 5);
- ncp_add_pstring(server, name);
-
- if ((result = ncp_request(server, 22)) != 0)
- {
- ncp_unlock_server(server);
- return result;
- }
-
- *target = ncp_reply_byte(server, 0);
- ncp_unlock_server(server);
- return 0;
-}
-
int
ncp_close_file(struct ncp_server *server, const char *file_id)
{
ncp_init_request(server);
ncp_add_byte(server, 6); /* subfunction */
- ncp_add_byte(server, 0); /* dos name space */
- ncp_add_byte(server, 0); /* dos name space as dest */
+ ncp_add_byte(server, server->name_space[vol_num]);
+ ncp_add_byte(server, server->name_space[vol_num]);
ncp_add_word(server, 0xff); /* get all */
ncp_add_dword(server, RIM_ALL);
ncp_add_handle_path(server, vol_num, dir_base, 1, path);
return 0;
}
+static inline int
+ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
+{
+ int result;
+ __u8 *namespace;
+ __u16 no_namespaces;
+
+ ncp_init_request(server);
+ ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */
+ ncp_add_word(server, 0);
+ ncp_add_byte(server, volume);
+
+ if ((result = ncp_request(server, 87)) != 0)
+ {
+ ncp_unlock_server(server);
+ return 0;
+ }
+
+ no_namespaces = ncp_reply_word(server, 0);
+ namespace = ncp_reply_data(server, 2);
+
+ while (no_namespaces > 0)
+ {
+ DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
+
+ if (*namespace == 4)
+ {
+ DPRINTK("get_namespaces: found OS2\n");
+ ncp_unlock_server(server);
+ return 1;
+ }
+ namespace += 1;
+ no_namespaces -= 1;
+ }
+ ncp_unlock_server(server);
+ return 0;
+}
+
int
ncp_lookup_volume(struct ncp_server *server,
char *volname,
struct nw_info_struct *target)
{
int result;
- __u8 vol_num;
- __u32 dir_base;
+ int volnum;
DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
ncp_init_request(server);
ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
- ncp_add_byte(server, 0); /* DOS name space */
+ ncp_add_byte(server, 0); /* DOS namespace */
ncp_add_byte(server, 0); /* reserved */
ncp_add_byte(server, 0); /* reserved */
ncp_add_byte(server, 0); /* reserved */
return result;
}
- dir_base = ncp_reply_dword(server, 4);
- vol_num = ncp_reply_byte(server, 8);
+ memset(target, 0, sizeof(*target));
+ target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
+ target->volNumber = volnum = ncp_reply_byte(server, 8);
ncp_unlock_server(server);
- if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL,
- target)) != 0)
- {
- return result;
- }
+ server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0;
- DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes);
+ DPRINTK("lookup_vol: namespace[%d] = %d\n",
+ volnum, server->name_space[volnum]);
target->nameLen = strlen(volname);
strcpy(target->entryName, volname);
+ target->attributes = aDIR;
return 0;
}
ncp_init_request(server);
ncp_add_byte(server, 7); /* subfunction */
- ncp_add_byte(server, 0); /* dos name space */
+ ncp_add_byte(server, server->name_space[file->volNumber]);
ncp_add_byte(server, 0); /* reserved */
ncp_add_word(server, 0x8006); /* search attribs: all */
ncp_add_dword(server, info_mask);
ncp_add_mem(server, info, sizeof(*info));
ncp_add_handle_path(server, file->volNumber,
- file->DosDirNum, 1, NULL);
+ file->dirEntNum, 1, NULL);
result = ncp_request(server, 87);
ncp_unlock_server(server);
ncp_init_request(server);
ncp_add_byte(server, 8); /* subfunction */
- ncp_add_byte(server, 0); /* dos name space */
+ ncp_add_byte(server, server->name_space[dir->volNumber]);
ncp_add_byte(server, 0); /* reserved */
ncp_add_word(server, 0x8006); /* search attribs: all */
ncp_add_handle_path(server, dir->volNumber,
- dir->DosDirNum, 1, name);
+ dir->dirEntNum, 1, name);
result = ncp_request(server, 87);
ncp_unlock_server(server);
{
int result;
__u16 search_attribs = 0x0006;
+ __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
if ((create_attributes & aDIR) != 0)
{
- search_attribs |= 0x8000;
- }
+ search_attribs |= 0x8000;
+}
ncp_init_request(server);
ncp_add_byte(server, 1); /* subfunction */
- ncp_add_byte(server, 0); /* dos name space */
+ ncp_add_byte(server, server->name_space[volume]);
ncp_add_byte(server, open_create_mode);
ncp_add_word(server, search_attribs);
ncp_add_dword(server, RIM_ALL);
if (dir != NULL)
{
- ncp_add_handle_path(server, dir->volNumber,
- dir->DosDirNum, 1, name);
+ ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
}
else
{
- ncp_add_handle_path(server,
- target->i.volNumber, target->i.DosDirNum,
+ ncp_add_handle_path(server, volume, target->i.dirEntNum,
1, NULL);
}
ncp_init_request(server);
ncp_add_byte(server, 2); /* subfunction */
- ncp_add_byte(server, 0); /* dos name space */
+ ncp_add_byte(server, server->name_space[dir->volNumber]);
ncp_add_byte(server, 0); /* reserved */
- ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
+ ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
if ((result = ncp_request(server, 87)) != 0)
{
ncp_init_request(server);
ncp_add_byte(server, 3); /* subfunction */
- ncp_add_byte(server, 0); /* dos name space */
+ ncp_add_byte(server, server->name_space[seq->volNumber]);
ncp_add_byte(server, 0); /* data stream (???) */
ncp_add_word(server, 0xffff); /* Search attribs */
ncp_add_dword(server, RIM_ALL); /* return info mask */
ncp_init_request(server);
ncp_add_byte(server, 4); /* subfunction */
- ncp_add_byte(server, 0); /* dos name space */
+ ncp_add_byte(server, server->name_space[old_dir->volNumber]);
ncp_add_byte(server, 1); /* rename flag */
ncp_add_word(server, 0x8006); /* search attributes */
/* source Handle Path */
ncp_add_byte(server, old_dir->volNumber);
- ncp_add_dword(server, old_dir->DosDirNum);
+ ncp_add_dword(server, old_dir->dirEntNum);
ncp_add_byte(server, 1);
ncp_add_byte(server, 1); /* 1 source component */
/* dest Handle Path */
ncp_add_byte(server, new_dir->volNumber);
- ncp_add_dword(server, new_dir->DosDirNum);
+ ncp_add_dword(server, new_dir->dirEntNum);
ncp_add_byte(server, 1);
ncp_add_byte(server, 1); /* 1 destination component */
{
struct nfs_fattr fattr;
- if (jiffies - NFS_READTIME(dir) < server->acdirmax)
+ if (jiffies - NFS_READTIME(dir) < NFS_ATTRTIMEO(dir))
return;
NFS_READTIME(dir) = jiffies;
if (nfs_proc_getattr(server, NFS_FH(dir), &fattr) == 0) {
nfs_refresh_inode(dir, &fattr);
- if (fattr.mtime.seconds == NFS_OLDMTIME(dir))
+ if (fattr.mtime.seconds == NFS_OLDMTIME(dir)) {
+ if ((NFS_ATTRTIMEO(dir) <<= 1) > server->acdirmax)
+ NFS_ATTRTIMEO(dir) = server->acdirmax;
return;
+ }
NFS_OLDMTIME(dir) = fattr.mtime.seconds;
}
/* invalidate directory cache here when we _really_ start caching */
/* Size changed from outside: invalidate caches on next read */
if (inode->i_size != fattr->size)
NFS_CACHEINV(inode);
+ if (NFS_OLDMTIME(inode) != fattr->mtime.seconds)
+ NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
inode->i_size = fattr->size;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
inode->i_rdev = to_kdev_t(fattr->rdev);
{
struct nfs_fattr fattr;
- if (jiffies - NFS_READTIME(inode) < server->acregmax)
+ if (jiffies - NFS_READTIME(inode) < NFS_ATTRTIMEO(inode))
return;
NFS_READTIME(inode) = jiffies;
if (nfs_proc_getattr(server, NFS_FH(inode), &fattr) == 0) {
nfs_refresh_inode(inode, &fattr);
- if (fattr.mtime.seconds == NFS_OLDMTIME(inode))
+ if (fattr.mtime.seconds == NFS_OLDMTIME(inode)) {
+ if ((NFS_ATTRTIMEO(inode) <<= 1) > server->acregmax)
+ NFS_ATTRTIMEO(inode) = server->acregmax;
return;
+ }
NFS_OLDMTIME(inode) = fattr.mtime.seconds;
}
invalidate_inode_pages(inode);
__asm__ __volatile__("movl %0,%%cr3": :"r" (pgdir)); \
} while (0)
-extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
-extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
-extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
+#define pte_none(x) (!pte_val(x))
+#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(xp) do { pte_val(*(xp)) = 0; } while (0)
-extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
-extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; }
-extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; }
-extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
+#define pmd_none(x) (!pmd_val(x))
+#define pmd_bad(x) ((pmd_val(x) & ~PAGE_MASK) != _PAGE_TABLE)
+#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
+#define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0)
/*
* The "pgd_xxx()" functions here are trivial for a folded two-level
extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
{
- address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
- if (pmd_none(*pmd)) {
- pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
- if (pmd_none(*pmd)) {
- if (page) {
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
- return page + address;
- }
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
- return NULL;
- }
- free_page((unsigned long) page);
- }
- if (pmd_bad(*pmd)) {
- printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
- pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + address;
+ address = (address >> (PAGE_SHIFT-2)) & 4*(PTRS_PER_PTE - 1);
+
+repeat:
+ if (pmd_none(*pmd))
+ goto getnew;
+ if (pmd_bad(*pmd))
+ goto fix;
+ return (pte_t *) (pmd_page(*pmd) + address);
+
+getnew:
+{
+ unsigned long page = __get_free_page(GFP_KERNEL);
+ if (!pmd_none(*pmd))
+ goto freenew;
+ if (!page)
+ goto oom;
+ memset((void *) page, 0, PAGE_SIZE);
+ pmd_val(*pmd) = _PAGE_TABLE | page;
+ return (pte_t *) (page + address);
+freenew:
+ free_page(page);
+ goto repeat;
+}
+
+fix:
+ printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+oom:
+ pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+ return NULL;
}
/*
* here (16 bytes or greater). This ordering should be particularly
* beneficial on 32-bit processors.
*
- * The first line is data used in linear searches (eg. clock algorithm
- * scans). The second line is data used in page searches through the
- * page-cache. -- sct
+ * The first line is data used in page cache lookup, the second line
+ * is used for linear searches (eg. clock algorithm scans).
*/
typedef struct page {
+ struct inode *inode;
+ unsigned long offset;
+ struct page *next_hash;
atomic_t count;
+ unsigned flags; /* atomic flags, some possibly updated asynchronously */
unsigned dirty:16,
age:8;
- unsigned flags; /* atomic flags, some possibly updated asynchronously */
struct wait_queue *wait;
struct page *next;
- struct page *next_hash;
- unsigned long offset;
- struct inode *inode;
struct page *prev;
struct page *prev_hash;
struct buffer_head * buffers;
__u16 update_time;
};
+/* Defines for Name Spaces */
+#define NW_NS_DOS 0
+#define NW_NS_MAC 1
+#define NW_NS_NFS 2
+#define NW_NS_FTAM 3
+#define NW_NS_OS2 4
/* Defines for ReturnInformationMask */
#define RIM_NAME (0x0001L)
interest for us later, so we store
it completely. */
+ __u8 name_space[NCP_NUMBER_OF_VOLUMES];
+
struct file *ncp_filp; /* File pointer to ncp socket */
struct file *wdog_filp; /* File pointer to wdog socket */
struct file *msg_filp; /* File pointer to message socket */
#define NFS_RENAMED_DIR(inode) ((inode)->u.nfs_i.silly_rename_dir)
#define NFS_READTIME(inode) ((inode)->u.nfs_i.read_cache_jiffies)
#define NFS_OLDMTIME(inode) ((inode)->u.nfs_i.read_cache_mtime)
+#define NFS_ATTRTIMEO(inode) ((inode)->u.nfs_i.attrtimeo)
+#define NFS_MINATTRTIMEO(inode) (S_ISREG((inode)->i_mode)? \
+ NFS_SERVER(inode)->acregmin : \
+ NFS_SERVER(inode)->acdirmin)
#define NFS_CACHEINV(inode) \
do { \
NFS_READTIME(inode) = jiffies - 1000000; \
* NFS FH, but that requires a kmalloc.
*/
struct inode *silly_rename_dir;
+ /*
+ * attrtimeo defines for how long the cached attributes are valid
+ */
+ unsigned long attrtimeo;
};
#endif
return PAGE_OFFSET + PAGE_SIZE * page->map_nr;
}
-#define PAGE_HASH_BITS 10
+#define PAGE_HASH_BITS 11
#define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS)
#define PAGE_AGE_VALUE 16
{
struct page *page;
- for (page = page_hash(inode, offset); page ; page = page->next_hash) {
+ page = page_hash(inode, offset);
+ goto inside;
+ for (;;) {
+ page = page->next_hash;
+inside:
+ if (!page)
+ goto not_found;
if (page->inode != inode)
continue;
- if (page->offset != offset)
- continue;
- /* Found the page. */
- atomic_inc(&page->count);
- set_bit(PG_referenced, &page->flags);
- break;
+ if (page->offset == offset)
+ break;
}
+ /* Found the page. */
+ atomic_inc(&page->count);
+ set_bit(PG_referenced, &page->flags);
+not_found:
return page;
}
#define IPFWD_LASTFRAG 2
#define IPFWD_MASQUERADED 4
#define IPFWD_MULTICASTING 8
-#define IPFWD_MULTITUNNEL 16
+#define IPFWD_MULTITUNNEL 0x10
+#define IPFWD_NOTTLDEC 0x20
#endif
#define __NET_NETLINK_H
#define NET_MAJOR 36 /* Major 18 is reserved for networking */
-#define MAX_LINKS 10 /* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved */
+#define MAX_LINKS 11 /* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved */
/* 4-7 are psi0-psi3 8 is arpd 9 is ppp */
+ /* 10 is for IPSEC <John Ioannidis> */
#define MAX_QBYTES 32768 /* Maximum bytes in the queue */
#include <linux/config.h>
#define NETLINK_PSI 4 /* PSI devices - 4 to 7 */
#define NETLINK_ARPD 8
#define NETLINK_NET_PPP 9 /* Non tty PPP devices */
+#define NETLINK_IPSEC 10 /* IPSEC */
#ifdef CONFIG_RTNETLINK
extern void ip_netlink_msg(unsigned long, __u32, __u32, __u32, short, short, char *);
#include <linux/skbuff.h>
#include <linux/genhd.h>
#include <linux/swap.h>
+#include <linux/ctype.h>
extern unsigned char aux_device_present, kbd_read_mask;
X(system_utsname),
X(sys_call_table),
X(hard_reset_now),
+ X(_ctype),
/* Signal interfaces */
X(send_sig),
if (increase)
increment = -increment;
newprio = current->priority - increment;
- if (newprio < 1)
+ if ((signed) newprio < 1)
newprio = 1;
if (newprio > DEF_PRIORITY*2)
newprio = DEF_PRIORITY*2;
{
struct task_struct * p;
- if (current->leader)
- return -EPERM;
-
for_each_task(p) {
- if (p != current && p->pgrp == current->pid)
+ if (p->pgrp == current->pid)
return -EPERM;
}
* Ok, found a page in the page cache, now we need to check
* that it's up-to-date
*/
- wait_on_page(page);
+ if (PageLocked(page))
+ goto page_locked_wait;
if (!PageUptodate(page))
goto page_read_error;
new_page = try_to_read_ahead(inode, offset + PAGE_SIZE, 0);
goto found_page;
+page_locked_wait:
+ __wait_on_page(page);
+ if (PageUptodate(page))
+ goto success;
+
page_read_error:
/*
* Umm, take care of errors if the page isn't up-to-date.
} while ((mpnt = mpnt->vm_next_share) != inode->i_mmap);
}
-/*
- * fill in an empty page-table if none exists.
- */
-static inline pte_t * get_empty_pgtable(struct task_struct * tsk,unsigned long address)
-{
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
-
- pgd = pgd_offset(tsk->mm, address);
- pmd = pmd_alloc(pgd, address);
- if (!pmd) {
- oom(tsk);
- return NULL;
- }
- pte = pte_alloc(pmd, address);
- if (!pte) {
- oom(tsk);
- return NULL;
- }
- return pte;
-}
static inline void do_swap_page(struct task_struct * tsk,
struct vm_area_struct * vma, unsigned long address,
void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma,
unsigned long address, int write_access)
{
+ pgd_t * pgd;
+ pmd_t * pmd;
pte_t * page_table;
pte_t entry;
unsigned long page;
- page_table = get_empty_pgtable(tsk, address);
+ pgd = pgd_offset(tsk->mm, address);
+ pmd = pmd_alloc(pgd, address);
+ if (!pmd)
+ goto no_memory;
+ page_table = pte_alloc(pmd, address);
if (!page_table)
- return;
+ goto no_memory;
entry = *page_table;
if (pte_present(entry))
- return;
- if (!pte_none(entry)) {
- do_swap_page(tsk, vma, address, page_table, entry, write_access);
- return;
- }
+ goto is_present;
+ if (!pte_none(entry))
+ goto swap_page;
address &= PAGE_MASK;
- if (!vma->vm_ops || !vma->vm_ops->nopage) {
- flush_cache_page(vma, address);
- get_empty_page(tsk, vma, page_table, write_access);
- return;
- }
- ++tsk->maj_flt;
- ++vma->vm_mm->rss;
+ if (!vma->vm_ops || !vma->vm_ops->nopage)
+ goto anonymous_page;
/*
* The third argument is "no_share", which tells the low-level code
* to copy, not share the page even if sharing is possible. It's
* essentially an early COW detection
*/
- page = vma->vm_ops->nopage(vma, address, write_access && !(vma->vm_flags & VM_SHARED));
- if (!page) {
- force_sig(SIGBUS, current);
- flush_cache_page(vma, address);
- put_page(page_table, BAD_PAGE);
- /* no need to invalidate, wasn't present */
- return;
- }
+ page = vma->vm_ops->nopage(vma, address,
+ (vma->vm_flags & VM_SHARED)?0:write_access);
+ if (!page)
+ goto sigbus;
+ ++tsk->maj_flt;
+ ++vma->vm_mm->rss;
/*
* This silly early PAGE_DIRTY setting removes a race
* due to the bad i386 page protection. But it's valid
flush_cache_page(vma, address);
put_page(page_table, entry);
/* no need to invalidate: a not-present page shouldn't be cached */
+ return;
+
+sigbus:
+ force_sig(SIGBUS, current);
+ flush_cache_page(vma, address);
+ put_page(page_table, BAD_PAGE);
+ /* no need to invalidate, wasn't present */
+ return;
+
+anonymous_page:
+ flush_cache_page(vma, address);
+ get_empty_page(tsk, vma, page_table, write_access);
+ return;
+
+swap_page:
+ do_swap_page(tsk, vma, address, page_table, entry, write_access);
+ return;
+
+no_memory:
+ oom(tsk);
+is_present:
+ return;
}
/*
/*
* Sending
*/
- if (port_info[f->port].state == Forwarding) {
+ if (f->port!=port && port_info[f->port].state == Forwarding) {
/* has entry expired? */
if (f->timer + fdb_aging_time < CURRENT_TIME) {
/* timer expired, invalidate entry */
bool 'IP: firewalling' CONFIG_IP_FIREWALL
if [ "$CONFIG_IP_FIREWALL" = "y" ]; then
bool 'IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_IP_FORWARD" = "y" ]; then
bool 'IP: masquerading (EXPERIMENTAL)' CONFIG_IP_MASQUERADE
if [ "$CONFIG_IP_MASQUERADE" != "n" ]; then
comment 'Protocol-specific masquerading support will be built as modules.'
#include <net/checksum.h>
#include <linux/route.h>
#include <net/route.h>
-
+
#ifdef CONFIG_IP_FORWARD
#ifdef CONFIG_IP_MROUTE
* Firstly push down and install the IPIP header.
*/
struct iphdr *iph=(struct iphdr *)skb_push(skb,sizeof(struct iphdr));
+
if(len>65515)
len=65515;
+
+
iph->version = 4;
iph->tos = skb->ip_hdr->tos;
iph->ttl = skb->ip_hdr->ttl;
iph->saddr = out->pa_addr;
iph->protocol = IPPROTO_IPIP;
iph->ihl = 5;
- iph->tot_len = htons(skb->len);
+ iph->tot_len = htons(skb->len + len); /* Anand, ernet */
iph->id = htons(ip_id_count++);
ip_send_check(iph);
skb->dev = out;
skb->arp = 1;
- skb->raddr=daddr;
+ skb->raddr=daddr; /* Router address is not destination address. The
+ * correct value is given eventually. I have not
+ * removed this statement. But could have.
+ * Anand, ernet.
+ */
/*
* Now add the physical header (driver will push it down).
*/
- if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL, len)<0)
+
+ /* The last parameter of out->hard_header() needed skb->len + len.
+ * Anand, ernet.
+ */
+ if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL,
+ skb->len + len)<0)
skb->arp=0;
/*
* Read to queue for transmission.
*/
iph = skb->h.iph;
- iph->ttl--;
+ if (!(is_frag&IPFWD_NOTTLDEC))
+ {
+ unsigned long checksum = iph->check;
+ iph->ttl--;
/*
* Re-compute the IP header checksum.
- * This is inefficient. We know what has happened to the header
- * and could thus adjust the checksum as Phil Karn does in KA9Q
+ * This is efficient. We know what has happened to the header
+ * and can thus adjust the checksum as Phil Karn does in KA9Q
+ * except we do this in "network byte order".
*/
-
- iph->check = ntohs(iph->check) + 0x0100;
- if ((iph->check & 0xFF00) == 0)
- iph->check++; /* carry overflow */
- iph->check = htons(iph->check);
+ checksum += htons(0x0100);
+ /* carry overflow? */
+ checksum += checksum >> 16;
+ iph->check = checksum;
+ }
if (iph->ttl <= 0)
{
return -1;
}
+ /* If IPFWD_MULTITUNNEL flag is set, then we have to perform routing
+ * decision so as to reach the other end of the tunnel. This condition
+ * also means that we are dealing with a unicast IP packet "in a way".
+ * Anand, ernet.
+ */
+
#ifdef CONFIG_IP_MROUTE
- if(!(is_frag&IPFWD_MULTICASTING))
+ if(!(is_frag&IPFWD_MULTICASTING) || (is_frag&IPFWD_MULTITUNNEL))
{
#endif
/*
icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
#endif
#ifdef CONFIG_IP_MROUTE
+
+ /* This is for ip encap. Anand, ernet.*/
+
+ if (is_frag&IPFWD_MULTITUNNEL) {
+ encap=20;
+ }
}
else
{
if(is_frag&IPFWD_MULTITUNNEL)
{
skb_reserve(skb2,(encap+dev2->hard_header_len+15)&~15); /* 16 byte aligned IP headers are good */
- ip_encap(skb2,skb->len, dev2, raddr);
+
+/* We need to pass on IP information of the incoming packet to ip_encap()
+ * to fillin ttl, and tos fields.The destination should be target_addr.
+ * Anand, ernet.
+ */
+
+ skb2->ip_hdr = skb->ip_hdr;
+
+ ip_encap(skb2,skb->len, dev2, target_addr);
+
+/* The router address is got earlier that to take us to the remote tunnel
+ * Anand, ernet.
+ */
+ skb2->raddr = rt->rt_gateway;
}
else
#endif
ptr = skb_put(skb2,skb->len);
skb2->free = 1;
skb2->h.raw = ptr;
-
/*
* Copy the packet data into the new buffer.
*/
#endif
+
+
+
struct sk_buff *skb2;
int left, mtu, hlen, len;
int offset;
+
+ unsigned short true_hard_header_len;
/*
* Point into the IP datagram header.
iph = skb->ip_hdr;
#endif
+ /*
+ * Calculate the length of the link-layer header appended to
+ * the IP-packet.
+ */
+ true_hard_header_len = ((unsigned char *)iph) - raw;
+
/*
* Setup starting values.
*/
hlen = iph->ihl * 4;
left = ntohs(iph->tot_len) - hlen; /* Space per frame */
- hlen += dev->hard_header_len; /* Total header size */
+ hlen += true_hard_header_len;
mtu = (dev->mtu - hlen); /* Size of data space */
ptr = (raw + hlen); /* Where to start from */
*/
skb2->arp = skb->arp;
+ skb2->protocol = htons(ETH_P_IP); /* Atleast PPP needs this */
+#if 0
if(skb->free==0)
printk(KERN_ERR "IP fragmenter: BUG free!=1 in fragmenter\n");
+#endif
skb2->free = 1;
skb_put(skb2,len + hlen);
skb2->h.raw=(char *) skb2->data;
memcpy(skb2->h.raw + hlen, ptr, len);
left -= len;
- skb2->h.raw+=dev->hard_header_len;
+ skb2->h.raw+=true_hard_header_len;
/*
* Fill in the new header fields.
/*
- * IP multicast routing support for mrouted 3.6
+ * IP multicast routing support for mrouted 3.6/3.8
*
* (c) 1995 Alan Cox, <alan@cymru.net>
* Linux Consultancy and Custom Driver Development
*
* Fixes:
* Michael Chastain : Incorrect size of copying.
- * Alan Cox : Added the cache manager code
+ * Alan Cox : Added the cache manager code.
* Alan Cox : Fixed the clone/copy bug and device race.
+ * Malcolm Beattie : Buffer handling fixes.
+ * Alexey Kuznetsov : Double buffer free and other fixes.
+ * SVR Anand : Fixed several multicast bugs and problems.
*
* Status:
* Cache manager under test. Forwarding in vague test mode
kfree_skb(skb, FREE_WRITE);
return;
}
+
+ /*
+ * Without the following addition, skb->h.iph points to something
+ * different that is not the ip header.
+ */
+ skb->h.iph = skb->ip_hdr; /* Anand, ernet. */
+
vif_table[vif].pkt_in++;
vif_table[vif].bytes_in+=skb->len;
void ip_mr_init(void)
{
- printk(KERN_INFO "Linux IP multicast router 0.05.\n");
+ printk(KERN_INFO "Linux IP multicast router 0.06.\n");
register_netdevice_notifier(&ip_mr_notifier);
#ifdef CONFIG_PROC_FS
proc_net_register(&(struct proc_dir_entry) {
* Route an outgoing frame from a socket.
*/
-static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len)
+static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len, int noblock)
{
struct sk_buff *skb;
ipx_interface *intrfc;
size=sizeof(ipx_packet)+len;
size += ipx_offset;
- skb=sock_alloc_send_skb(sk, size, 0, 0, &err);
+ skb=sock_alloc_send_skb(sk, size, 0, noblock, &err);
if(skb==NULL)
return err;
memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN);
}
- retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len);
+ retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, noblock);
if (retval < 0)
return retval;
X(skb_clone),
X(dev_alloc_skb),
X(dev_kfree_skb),
+ X(skb_device_unlock),
X(netif_rx),
X(dev_tint),
X(irq2dev_map),