]> git.neil.brown.name Git - history.git/commitdiff
Import 2.4.0-test6pre1 2.4.0-test6pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:37:16 +0000 (15:37 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:37:16 +0000 (15:37 -0500)
240 files changed:
CREDITS
Documentation/DMA-mapping.txt
Documentation/IO-mapping.txt
Documentation/arm/SA1100/ThinClient
Documentation/arm/empeg/ir.txt
Documentation/arm/nwfpe/README
Documentation/cdrom/cdrom-standard.tex
Documentation/cdrom/ide-cd
Documentation/computone.txt
Documentation/cpqarray.txt
Documentation/fb/aty128fb.txt
Documentation/fb/matroxfb.txt
Documentation/fb/vesafb.txt
Documentation/filesystems/Locking
Documentation/filesystems/affs.txt
Documentation/filesystems/coda.txt
Documentation/filesystems/fat_cvf.txt
Documentation/filesystems/hpfs.txt
Documentation/filesystems/proc.txt
Documentation/filesystems/ufs.txt
Documentation/filesystems/vfs.txt
Documentation/floppy.txt
Documentation/highuid.txt
Documentation/i2c/dev-interface
Documentation/i2c/i2c-protocol
Documentation/i2c/writing-clients
Documentation/ia64/README
Documentation/ia64/efirtc.txt
Documentation/isdn/00-INDEX
Documentation/isdn/INTERFACE.fax
Documentation/isdn/README
Documentation/isdn/README.HiSax
Documentation/isdn/README.act2000
Documentation/isdn/README.avmb1
Documentation/isdn/README.concap
Documentation/isdn/README.diversion
Documentation/isdn/README.hysdn
Documentation/isdn/README.icn
Documentation/isdn/README.sc
Documentation/joystick-api.txt
Documentation/joystick-parport.txt
Documentation/joystick.txt
Documentation/kbuild/commands.txt
Documentation/kbuild/config-language.txt
Documentation/m68k/README.buddha
Documentation/m68k/kernel-options.txt
Documentation/md.txt
Documentation/moxa-smartio
Documentation/mtrr.txt
Documentation/networking/README.sb1000
Documentation/networking/comx.txt
Documentation/networking/cs89x0.txt
Documentation/networking/decnet.txt
Documentation/networking/dmfe.txt
Documentation/networking/ethertap.txt
Documentation/networking/ip-sysctl.txt
Documentation/networking/ipddp.txt
Documentation/networking/iphase.txt
Documentation/networking/olympic.txt
Documentation/networking/shaper.txt
Documentation/networking/sis900.txt
Documentation/networking/sk98lin.txt
Documentation/networking/smctr.txt
Documentation/networking/tlan.txt
Documentation/networking/tms380tr.txt
Documentation/networking/tulip.txt
Documentation/networking/vortex.txt
Documentation/networking/wan-router.txt
Documentation/networking/wanpipe.txt
Documentation/networking/wavelan.txt
Documentation/nmi_watchdog.txt
Documentation/powerpc/SBC8260_memory_mapping.txt
Documentation/s390/DASD
Documentation/s390/cds.txt
Documentation/sound/CMI8338
Documentation/sound/ESS
Documentation/sound/Introduction
Documentation/sound/Maestro
Documentation/sound/PSS
Documentation/sound/README.OSS
Documentation/sound/README.modules
Documentation/sound/README.ymfsb
Documentation/stallion.txt
Documentation/sysctl/vm.txt
Documentation/sysrq.txt
Documentation/usb/CREDITS
Documentation/usb/URB.txt
Documentation/usb/input.txt
Documentation/usb/ohci.txt
Documentation/usb/ov511.txt
Documentation/usb/proc_usb_info.txt
Documentation/usb/scanner.txt
Documentation/usb/uhci.txt
Documentation/usb/usb-serial.txt
Documentation/video4linux/CQcam.txt
Documentation/video4linux/README.cpia
Documentation/video4linux/radiotrack.txt
Documentation/video4linux/zr36120.txt
Documentation/vm/numa
MAINTAINERS
Makefile
arch/alpha/kernel/entry.S
arch/i386/Makefile
arch/i386/boot/compressed/misc.c
arch/i386/config.in
arch/i386/defconfig
arch/i386/kernel/microcode.c
arch/mips/Makefile
arch/mips/config.in
arch/mips/defconfig
arch/mips/defconfig-cobalt
arch/mips/defconfig-decstation
arch/mips/defconfig-ip22
arch/mips/defconfig-orion
arch/mips/defconfig-rm200
arch/mips/kernel/scall_o32.S
arch/mips/mm/andes.c
arch/mips/mm/r2300.c
arch/mips/mm/r4xx0.c
arch/mips/orion/misc.c
arch/mips/orion/setup.c
arch/mips/sgi/kernel/setup.c
arch/mips/tools/offset.c
arch/mips64/Makefile
arch/mips64/config.in
arch/mips64/defconfig
arch/mips64/defconfig-ip22
arch/mips64/defconfig-ip27
arch/mips64/kernel/binfmt_elf32.c
arch/mips64/kernel/linux32.c
arch/mips64/kernel/mips64_ksyms.c
arch/mips64/kernel/scall_64.S
arch/mips64/kernel/scall_o32.S
arch/mips64/kernel/smp.c
arch/mips64/kernel/syscall.c
arch/mips64/mm/andes.c
arch/mips64/mm/init.c
arch/mips64/mm/loadmmu.c
arch/mips64/mm/r4xx0.c
arch/mips64/sgi-ip27/ip27-init.c
arch/mips64/sgi-ip27/ip27-memory.c
arch/mips64/tools/offset.c
drivers/char/Makefile
drivers/char/drm/agpsupport.c
drivers/char/drm/auth.c
drivers/char/drm/drm_syms.c
drivers/char/drm/memory.c
drivers/char/drm/r128_bufs.c
drivers/char/drm/r128_drv.c
drivers/char/drm/tdfx_drv.c
drivers/char/n_tty.c
drivers/i2c/Config.in
drivers/ide/pdc202xx.c
drivers/net/acenic.c
drivers/net/gmac.c
drivers/net/ioc3-eth.c
drivers/pci/quirks.c
drivers/scsi/README.ibmmca
drivers/scsi/ibmmca.c
drivers/scsi/ibmmca.h
drivers/scsi/scsi.c
drivers/scsi/sg.c
drivers/sound/Makefile
drivers/usb/acm.c
drivers/usb/audio.c
drivers/usb/dabusb.c
drivers/usb/dsbr100.c
drivers/usb/evdev.c
drivers/usb/hid.c
drivers/usb/ibmcam.c
drivers/usb/iforce.c
drivers/usb/input.c
drivers/usb/joydev.c
drivers/usb/keybdev.c
drivers/usb/microtek.c
drivers/usb/mousedev.c
drivers/usb/ov511.c
drivers/usb/pegasus.c
drivers/usb/printer.c
drivers/usb/rio500.c
drivers/usb/serial/Makefile
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/storage/Makefile
drivers/usb/storage/scm.c [deleted file]
drivers/usb/storage/scm.h [deleted file]
drivers/usb/storage/scsiglue.c
drivers/usb/storage/scsiglue.h
drivers/usb/storage/sddr09.c [new file with mode: 0644]
drivers/usb/storage/sddr09.h [new file with mode: 0644]
drivers/usb/storage/shuttle_usbat.c [new file with mode: 0644]
drivers/usb/storage/shuttle_usbat.h [new file with mode: 0644]
drivers/usb/storage/transport.c
drivers/usb/storage/transport.h
drivers/usb/storage/usb.c
drivers/usb/uhci.c
drivers/usb/usb-ohci.c
drivers/usb/usb-uhci.c
drivers/usb/usbkbd.c
drivers/usb/usbmouse.c
drivers/usb/wacom.c
drivers/video/riva/fbdev.c
fs/binfmt_elf.c
fs/binfmt_misc.c
fs/binfmt_script.c
fs/buffer.c
fs/dcache.c
fs/devices.c
fs/exec.c
fs/ext2/balloc.c
fs/ext2/file.c
fs/ext2/inode.c
fs/ext2/super.c
fs/fat/dir.c
fs/vfat/namei.c
include/asm-alpha/cache.h
include/asm-mips/elf.h
include/asm-mips/mc146818rtc.h
include/asm-mips64/elf.h
include/asm-mips64/mc146818rtc.h
include/asm-mips64/pgtable.h
include/asm-mips64/system.h
include/linux/arcdevice.h
include/linux/binfmts.h
include/linux/module.h
include/linux/sched.h
include/linux/spinlock.h
include/scsi/sg.h
kernel/Makefile
kernel/exit.c
kernel/fork.c
kernel/sys.c
kernel/user.c [new file with mode: 0644]
mm/numa.c
net/ipv6/netfilter/ip6table_filter.c
net/socket.c

diff --git a/CREDITS b/CREDITS
index 6aae42df56fd9c62bfc5dadbcaece2df041cd8d9..8784a9810070280260d653ea9edbfde916ecf27e 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1071,15 +1071,11 @@ D: Berkshire PC Watchdog Driver
 D: Small/Industrial Driver Project
 
 N: Nick Holloway
-E: Nick.Holloway@alfie.demon.co.uk
-E: Nick.Holloway@parallax.co.uk
-W: http://www.alfie.demon.co.uk/
-P: 1024/75C49395 3A F0 E3 4E B7 9F E0 7E  47 A3 B0 D5 68 6A C2 FB
+E: Nick.Holloway@pyrites.org.uk
+W: http://www.pyrites.org.uk/
+P: 1024/36115A04 F4E1 3384 FCFD C055 15D6  BA4C AB03 FBF8 3611 5A04
 D: Occasional Linux hacker...
-S: 15 Duke Street
-S: Chapelfields
-S: Coventry
-S: CV5 8BZ
+S: (ask for current address)
 S: United Kingdom
 
 N: Ron Holt
@@ -1556,6 +1552,12 @@ S: 8786 Niwot Road
 S: Niwot, Colorado 80503
 S: USA
 
+N: Robert M. Love
+E: rml@tech9.net
+E: rml@ufl.edu
+D: misc. kernel hacking and debugging
+S: FL, USA
+
 N: Martin von Löwis
 E: loewis@informatik.hu-berlin.de
 D: script binary format
index 443d07be80fb3ca1e50d4ff1ffe5e0e4eb589edd..5dd11a173dca5b58f5b14c5b69a7959df06fe948 100644 (file)
@@ -111,7 +111,7 @@ There are two types of DMA mappings:
 
 - Consistent DMA mappings which are usually mapped at driver
   initialization, unmapped at the end and for which the hardware should
-  guarentee that the device and the cpu can access the data
+  guarantee that the device and the cpu can access the data
   in parallel and will see updates made by each other without any
   explicit software flushing.
 
@@ -126,7 +126,7 @@ There are two types of DMA mappings:
 
   The invariant these examples all require is that any cpu store
   to memory is immediately visible to the device, and vice
-  versa.  Consistent mappings guarentee this.
+  versa.  Consistent mappings guarantee this.
 
 - Streaming DMA mappings which are usually mapped for one DMA transfer,
   unmapped right after it (unless you use pci_dma_sync below) and for which
@@ -171,9 +171,9 @@ it from the CPU and dma_handle which you pass to the card.
 The cpu return address and the DMA bus master address are both
 guaranteed to be aligned to the smallest PAGE_SIZE order which
 is greater than or equal to the requested size.  This invariant
-exists (for example) to guarentee that if you allocate a chunk
+exists (for example) to guarantee that if you allocate a chunk
 which is smaller than or equal to 64 kilobytes, the extent of the
-buffer you receive will not cross a 64K boundry.
+buffer you receive will not cross a 64K boundary.
 
 To unmap and free such a DMA region, you call:
 
@@ -203,7 +203,7 @@ as you possibly can.
 
 If you absolutely cannot know the direction of the DMA transfer,
 specify PCI_DMA_BIDIRECTIONAL.  It means that the DMA can go in
-either direction.  The platform guarentees that you may legally
+either direction.  The platform guarantees that you may legally
 specify this, and that it will work, but this may be at the
 cost of performance for example.
 
index b18355ba77b305e3574f0a36489a0fd5f7f0dc96..78253e5b1d4f3e807a9624a47f17246bd05434d1 100644 (file)
@@ -176,7 +176,7 @@ ioremap() function "vremap()".  ioremap() is the proper name, but I
 didn't think straight when I wrote it originally.  People who have to
 support both can do something like:
  
-       /* support old naming sillyness */
+       /* support old naming silliness */
        #if LINUX_VERSION_CODE < 0x020100                                     
        #define ioremap vremap
        #define iounmap vfree                                                     
index e3c8d5094bda342aad492080f1c9290d3e66d318..d5d7625fd6fda9526646f2f876a356ece877f40c 100644 (file)
@@ -10,7 +10,7 @@ Current Linux support for this product has been provided by Nicolas Pitre
 <nico@cam.org>.
 
 It's currently possible to mount a root filesystem via NFS providing a
-complete Linux environment.  Otherwyse a ramdisk image may be used.  Use
+complete Linux environment.  Otherwise a ramdisk image may be used.  Use
 'make thinclient_config' before any 'make config'.  This will set up
 defaults for ThinClient support.
 
index c82e9c513252d52de7cf3d1ed326233b11210452..10a29745016442cc22131fe67ebdc540e12e4bde 100644 (file)
@@ -17,7 +17,7 @@ For each of the 32 bits
   Go low for less than 2T (Around 750us)
 
 Rather than repeat a signal when the button is held down certain buttons
-generate the following code to indicate repitition.
+generate the following code to indicate repetition.
 
 Go low for approx 16T
 Go high for approx 4T
index 253cea48cfa3e703c19aea1636240ed40d5db962..771871de0c8bb943ca8c5ad28b1932ff6da78beb 100644 (file)
@@ -15,7 +15,7 @@ have attempted to use the C_SYMBOL_NAME macro wherever this may be
 important.
 
 Another choice I made was in the file structure.  I have attempted to
-contain all operating system specfic code in one module (fpmodule.*).
+contain all operating system specific code in one module (fpmodule.*).
 All the other files contain emulator specific code.  This should allow
 others to port the emulator to NetBSD for instance relatively easily.
 
index 1bf6434cbff622a0217a2d377d4d461f42a89fd8..61becaf07f4662cbdba5a6da9d8fd07d41869374 100644 (file)
@@ -919,7 +919,7 @@ the current flags.
   than fixing this interface by changing the assumptions it was made
   under, thereby breaking all user applications that use this
   function, the \UCD\ implements this $ioctl$ as follows: If the CD in
-  question has audio tracks on it, and it has absolutly no CD-I, XA,
+  question has audio tracks on it, and it has absolutely no CD-I, XA,
   or data tracks on it, it will be reported as $CDS_AUDIO$.  If it has
   both audio and data tracks, it will return $CDS_MIXED$.  If there
   are no audio tracks on the disc, and if the CD in question has any
index b5967f50689337e2e358b92e99f36e17b38d70db..8146e9987ea2d418b4b499e044c17a871d99ed2f 100644 (file)
@@ -286,7 +286,7 @@ b. Timeout/IRQ errors.
     Unfortunately, these drives seem to become very confused when we perform
     the standard Linux ATA disk drive probe. If you own one of these drives,
     you can bypass the ATA probing which confuses these CDROM drives, by 
-    adding `append="hdX=noprobe hdX=cdrom"' to your lilo.conf file and runing 
+    adding `append="hdX=noprobe hdX=cdrom"' to your lilo.conf file and running 
     lilo (again where X is the drive letter corresponding to where your drive 
     is installed.)
     
index 444d0c4f427650de85bfd8123e5b48a39324cb25..de281aa84464faf1f418cbb123f27e92d3ba040a 100644 (file)
@@ -93,7 +93,7 @@ Previously, the driver sources were packaged with a set of patch files
 to update the character drivers' makefile and configuration file, and other 
 kernel source files. A build script (ip2build) was included which applies 
 the patches if needed, and build any utilities needed.
-What you recieve may be a single patch file in conventional kernel
+What you receive may be a single patch file in conventional kernel
 patch format build script. That form can also be applied by
 running patch -p1 < ThePatchFile.  Otherwise run ip2build.
  
@@ -191,7 +191,7 @@ Higher speeds can be obtained using the setserial utility which remaps
 Intelliport II installations using the PowerPort expansion module can
 use the custom speed setting to select the highest speeds: 153,600 bps,
 230,400 bps, 307,200 bps, 460,800bps and 921,600 bps. The base for
-custom baud rate configuration is fixed at 921,600 for cards/expantion
+custom baud rate configuration is fixed at 921,600 for cards/expansion
 modules with ST654's and 115200 for those with Cirrus CD1400's.  This
 corresponds to the maximum bit rates those chips are capable.  
 For example if the baud base is 921600 and the baud divisor is 18 then
@@ -220,13 +220,13 @@ DEVFS is the DEVice File System available as an add on package for the
 2.2.x kernels and available as a configuration option in 2.3.46 and higher.
 Devfs allows for the automatic creation and management of device names
 under control of the device drivers themselves.  The Devfs namespace is
-hierarchial and reduces the clutter present in the normal flat /dev
+hierarchical and reduces the clutter present in the normal flat /dev
 namespace.  Devfs names and conventional device names may be intermixed.
 A userspace daemon, devfsd, exists to allow for automatic creation and
 management of symbolic links from the devfs name space to the conventional
 names.  More details on devfs can be found on the DEVFS home site at
 <http://www.atnf.csiro.au/~rgooch/linux/> or in the file kernel
-documenation files, .../linux/Documenation/filesystems/devfs/REAME.
+documentation files, .../linux/Documentation/filesystems/devfs/REAME.
 
 If you are using devfs, existing devices are automatically created within
 the devfs name space.  Normal devices will be ttf/0 - ttf/255 and callout
index 67db480cb4ee17f56ab5acb7637b5d79908e98c4..a2c9a0862edcf2d3b88d93d70174f728cb9c9038 100644 (file)
@@ -1,4 +1,4 @@
-This driver is for Compaq's SMART2 Intellegent Disk Array Controllers.
+This driver is for Compaq's SMART2 Intelligent Disk Array Controllers.
 
 Supported Cards:
 ----------------
index c1c574b424c077574180980407a4da22ce9a462c..3382565909141535d7f7fe80f67fcc82b75ba142 100644 (file)
@@ -66,7 +66,7 @@ Limitations
 There are known and unknown bugs, features and misfeatures.
 Currently there are following known bugs:
  + This driver is still experimental and is not finished.  Too many
-   bugs/eratta to list here.
+   bugs/errata to list here.
 
 --
 Brad Douglas <brad@neruo.com>
index 2575ecf1735f83e7b0cb3dc4f23898fd8e6787a1..13a641b9836460c5e4e5becf136c97515593aa28 100644 (file)
@@ -193,7 +193,7 @@ nocross4MB - pixel line must not cross 4MB boundary. It is default for
             XF86_FBDev.
 dfp      - enables digital flat panel interface. This option is incompatible with
            secondary (TV) output - if DFP is active, TV output must be
-          inactive and vice versa. DFP always uses same timming as primary
+          inactive and vice versa. DFP always uses same timing as primary
           (monitor) output.
 vesa:X   - selects startup videomode. X is number from 0 to 0x1FF, see table
            above for detailed explanation. Default is 640x480x8bpp if driver
index 19d810a4498c0f4191f7a9d868bc5e463f815be8..d7e7bd78ce1c6c045ba6e755cd90126e1c954303 100644 (file)
@@ -62,7 +62,7 @@ So the table for the Kernel mode numbers are:
 16M |  0x312    0x315    0x318    0x31B   
 
 To enable one of those modes you have to specify "vga=ask" in the
-lilo.conf file and rerun LILO. Then you can type in the descired
+lilo.conf file and rerun LILO. Then you can type in the desired
 mode at the "vga=ask" prompt. For example if you like to use 
 1024x768x256 colors you have to say "305" at this prompt.
 
index 421b1731809d71989ac3a22baaa3b2e68b2e4636..6213242da14077e447649048db9c714422233d74 100644 (file)
@@ -137,7 +137,7 @@ bmap:               yes
 may be called from the request handler (/dev/loop).
        ->sync_page() locking rules are not well-defined - usually it is called
 with lock on page, but that is not guaranteed. Considering the currently
-existsing instances of this method ->sync_page() itself doesn't look
+existing instances of this method ->sync_page() itself doesn't look
 well-defined...
        ->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some
 filesystems and by the swapper. The latter will eventually go away. All
index 543b02a7c1fd65f3d8f220b7f124cd1bfa5d8ea8..30c9738590f42b162e3402cf718315a9aaaa2d40 100644 (file)
@@ -158,7 +158,7 @@ If you boot Windows 95 (don't know about 3.x, 98 and NT) while you
 have an Amiga harddisk connected to your PC, it will overwrite
 the bytes 0x00dc..0x00df of block 0 with garbage, thus invalidating
 the Rigid Disk Block. Sheer luck has it that this is an unused
-area of the RDB, so only the checksum doesn's match anymore.
+area of the RDB, so only the checksum doesn't match anymore.
 Linux will ignore this garbage and recognize the RDB anyway, but
 before you connect that drive to your Amiga again, you must
 restore or repair your RDB. So please do make a backup copy of it
index 4ab793a71b18fe724e05c6030c989395276ad8c2..61311356025da58d09c0c518d513c3501faf466c 100644 (file)
@@ -1531,7 +1531,7 @@ kernel support.
 
 
   D\bDe\bes\bsc\bcr\bri\bip\bpt\bti\bio\bon\bn Remove all entries in the cache lying in a directory
-  CodaFid, and all children of this directory. This call is issed when
+  CodaFid, and all children of this directory. This call is issued when
   Venus receives a callback on the directory.
 
 
@@ -1630,7 +1630,7 @@ kernel support.
 
   The following requirements should be accommodated:
 
-  1. The message queueus should have open and close routines.  On Unix
+  1. The message queues should have open and close routines.  On Unix
      the opening of the character devices are such routines.
 
   +\bo  Before opening, no messages can be placed.
index c1cf27bd74c045cc85bfb7d9d112c15d8a2e83ad..9082cbe4e9da20de0ce1ffd569705d5566bae6ac 100644 (file)
@@ -140,7 +140,7 @@ It contains...
       THE KIND OF CVF I SUPPORT". The function must maintain the module
       usage counters for safety, i.e. do MOD_INC_USE_COUNT at the beginning
       and MOD_DEC_USE_COUNT at the end. The function *must not* assume that
-      successful recongition would lead to a call of the mount_cvf function
+      successful recognition would lead to a call of the mount_cvf function
       later. 
   - mount_cvf:
       A function that sets up some values or initializes something additional
index 756fcb2c034ba8c8223ca5016d03a15bc2e06eeb..ac2b1c6ae5f3380048861c6bf93c59c32a1fc5af 100644 (file)
@@ -25,14 +25,14 @@ conv=binary,text,auto (default binary)
        - there is a list of text extensions (I thing it's better to not convert
        text file than to damage binary file). If you want to change that list,
        change it in the source. Original readonly HPFS contained some strange
-       heuristic alghoritm that I removed. I thing it's danger to let the
+       heuristic algorithm that I removed. I thing it's danger to let the
        computer decide whether file is text or binary. For example, DJGPP
        binaries contain small text message at the beginning and they could be
        misidentified and damaged under some circumstances.
 check=none,normal,strict (default normal)
        Check level. Selecting none will cause only little speedup and big
        danger. I tried to write it so that it won't crash if check=normal on
-       corrupted filesystems. check=strict means many superflous checks -
+       corrupted filesystems. check=strict means many superfluous checks -
        used for debugging (for example it checks if file is allocated in
        bitmaps when accessing it).
 errors=continue,remount-ro,panic (default remount-ro)
@@ -65,12 +65,12 @@ access it under names 'a.', 'a..', 'a .  . . ' etc.
 
 Extended attributes
 
-On HPFS partion, OS/2 can associate to each file a special information called
+On HPFS partitions, OS/2 can associate to each file a special information called
 extended attributes. Extended attributes are pairs of (key,value) where key is
 an ascii string identifying that attribute and value is any string of bytes of
 variable length. OS/2 stores window and icon positions and file types there. So
 why not use it for unix-specific info like file owner or access rights? This
-driver can do it. If you chown/chgrp/chmod on a hpfs partion, extended
+driver can do it. If you chown/chgrp/chmod on a hpfs partition, extended
 attributes with keys "UID", "GID" or "MODE" and 2-byte values are created. Only
 that extended attributes those value differs from defaults specified in mount
 options are created. Once created, the extended attributes are never deleted,
@@ -89,7 +89,7 @@ values doesn't work.
 
 Symlinks
 
-You can do symlinks on HPFS partion, symlinks are achieved by setting extended
+You can do symlinks on HPFS partition, symlinks are achieved by setting extended
 attribute named "SYMLINK" with symlink value. Like on ext2, you can chown and
 chgrp symlinks but I don't know what is it good for. chmoding symlink results
 in chmoding file where symlink points. These symlinks are just for Linux use and
@@ -107,12 +107,12 @@ file has a pointer to codepage it's name is in. However OS/2 was created in
 America where people don't care much about codepages and so multiple codepages
 support is quite buggy. I have Czech OS/2 working in codepage 852 on my disk.
 Once I booted English OS/2 working in cp 850 and I created a file on my 852
-partion. It marked file name codepage as 850 - good. But when I again booted
+partition. It marked file name codepage as 850 - good. But when I again booted
 Czech OS/2, the file was completely inaccessible under any name. It seems that
 OS/2 uppercases the search pattern with it's system code page (852) and file
 name it's comparing to with its code page (850). These could never match. Is it
-really what IBM developers wanted? But problems countinue. When I created in
-Czech OS/2 another file in that direcotry, that file was inaccesible too. OS/2
+really what IBM developers wanted? But problems continued. When I created in
+Czech OS/2 another file in that directory, that file was inaccessible too. OS/2
 probably uses different uppercasing method when searching where to place a file
 (note, that files in HPFS directory must be sorted) and when searching for
 a file. Finally when I opened this directory in PmShell, PmShell crashed (the
@@ -199,7 +199,7 @@ File names like "a .b" are marked as 'long' by OS/2 but chkdsk "corrects" it and
 marks them as short (and writes "minor fs error corrected"). This bug is not in
 HPFS386.
 
-Codepage bugs decsribed above.
+Codepage bugs described above.
 
 If you don't install fixpacks, there are many, many more...
 
@@ -266,7 +266,7 @@ History
 1.99 Corrected a possible problem when there's not enough space while deleting
        file
      Now it tries to truncate the file if there's not enough space when deleting
-     Removed a lot of redundat code
+     Removed a lot of redundant code
 2.00 Fixed a bug in rename (it was there since 1.96)
      Better anti-fragmentation strategy
 
index fef3bb7430b127c67bc6f43db42658f08ae5cab4..c2314e0f1b4de32989a5e1cd3704ed83fa828488 100644 (file)
@@ -1047,7 +1047,7 @@ low and the high value.
 
 On a  low-memory,  single  CPU system, you can safely set these values to 0 so
 you don't  waste  memory.  It  is  used  on SMP systems so that the system can
-perform fast  pagetable allocations without having to aquire the kernel memory
+perform fast  pagetable allocations without having to acquire the kernel memory
 lock.
 
 For large  systems,  the  settings  are probably fine. For normal systems they
index dafae246da9f0642ef046db2a6d08300bdba1c6b..0e2b243ff4451ffb7fc0f6b140038709b0e054c2 100644 (file)
@@ -9,7 +9,7 @@ UFS OPTIONS
 
 ufstype=type_of_ufs
        UFS is a file system widely used in different operating systems.
-       The problem are differencies among implementations. Features of
+       The problem are differences among implementations. Features of
        some implementations are undocumented, so its hard to recognize
        type of ufs automatically. That's why user must specify type of 
        ufs manually by mount option ufstype. Possible values are:
index 7d1f5ca72fa3c617ea4977f6901ba711489afd63..9d91d121068e78abc634c2599efb9c931bce5fa9 100644 (file)
@@ -24,7 +24,7 @@ What is it?                                                           <section>
 
 The Virtual File System (otherwise known as the Virtual Filesystem
 Switch) is the software layer in the kernel that provides the
-filesystem interface to userspace programmes. It also provides an
+filesystem interface to userspace programs. It also provides an
 abstraction within the kernel which allows different filesystem
 implementations to co-exist.
 
@@ -34,7 +34,7 @@ A Quick Look At How It Works                                          <section>
 
 In this section I'll briefly describe how things work, before
 launching into the details. I'll start with describing what happens
-when user programmes open and manipulate files, and then look from the
+when user programs open and manipulate files, and then look from the
 other view which is how a filesystem is supported and subsequently
 mounted.
 
index 463937232e0bcc9c5e0a3a99521d3f0b694948b2..99d3ad3b3aa1a6c318bfcfcb40d5cc4710f8390d 100644 (file)
@@ -88,7 +88,7 @@ insmod), first check whether there is a more recent version.
 
        If you have a FIFO-able FDC, the floppy driver automatically
        falls back on non DMA mode if no DMA-able memory can be found.
-       If you want to avoid this, explicitely ask for 'yesdma'.
+       If you want to avoid this, explicitly ask for 'yesdma'.
 
  floppy=yesdma
        Tells the floppy driver that a workable DMA channel is available.
index ce7c17b7b3800a15581c1bd8b6a9dd12b1ee5fbb..2c33926b909923bc440fe7d01c2a67e38cde45a1 100644 (file)
@@ -20,7 +20,7 @@ What's left to be done for 32-bit UIDs on all Linux architectures:
 - Decide whether or not to keep backwards compatibility with the system
   accounting file, or if we should break it as the comments suggest
   (currently, the old 16-bit UID and GID are still written to disk, and
-  part of the former pad sparce is used to store separate 32-bit UID and
+  part of the former pad space is used to store separate 32-bit UID and
   GID)
 
 - Need to validate that OS emulation calls the 16-bit UID
index 3a0f73bf63548a241a31e850be663d539cbbe6f4..03b5836f49ff29a8142b5a3bd538055a9c29f470 100644 (file)
@@ -126,7 +126,7 @@ for details) through the following functions:
   __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
   __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, 
                                    __u8 *values);
-All these tranactions return -1 on failure; you can read errno to see
+All these transactions return -1 on failure; you can read errno to see
 what happened. The 'write' transactions return 0 on success; the
 'read' transactions return the read value, except for read_block, which
 returns the number of values read. The block buffers need not be longer
index d8cfdc77b39690e4e419c11fe4b85f82b11b682f..40c686d6585d86a2694b13829a70c8466dfaf011 100644 (file)
@@ -18,7 +18,7 @@ Count (8 bits): A data byte containing the length of a block operation.
 [..]: Data sent by I2C device, as opposed to data sent by the host adapter.
 
 
-Simple send tranaction
+Simple send transaction
 ======================
 
 This corresponds to i2c_master_send.
@@ -34,7 +34,7 @@ This corresponds to i2c_master_recv
   S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
 
 
-Combined tranactions
+Combined transactions
 ====================
 
 This corresponds to i2c_transfer
@@ -54,7 +54,7 @@ We have found some I2C devices that needs the following modifications:
   Flag I2C_M_NOSTART: 
     In a combined transaction, no 'S Addr' is generated at some point.
     For example, setting I2C_M_NOSTART on the second partial message
-    generateds something like:
+    generates something like:
       S Addr Rd [A] [Data] NA Wr [A] Data [A] P
     If you set the I2C_M_NOSTART variable for the first partial message,
     we do not generate Addr, but we do generate the startbit S. This will
index a9328d869bc328be2168566f401858246789ece6..a66debc0ff24e634bc53869418c81b753de5831d 100644 (file)
@@ -36,7 +36,7 @@ address.
     /* dec_use        */  &foo_dev_use    /* May be NULL */
   }
  
-The name can be choosen freely, and may be upto 40 characters long. Please
+The name can be chosen freely, and may be upto 40 characters long. Please
 use something descriptive here.
 
 The id should be a unique ID. The range 0xf000 to 0xffff is reserved for
@@ -659,7 +659,7 @@ kernel booting is completed.
 Command function
 ================
 
-A generic ioctl-like function call back is supported. You will seldomly
+A generic ioctl-like function call back is supported. You will seldom
 need this. You may even set it to NULL.
 
   /* No commands defined */
@@ -733,7 +733,7 @@ SMBus communication
                                         u8 command, u8 length,
                                         u8 *values);
 
-All these tranactions return -1 on failure. The 'write' transactions 
+All these transactions return -1 on failure. The 'write' transactions 
 return 0 on success; the 'read' transactions return the read value, except 
 for read_block, which returns the number of values read. The block buffers 
 need not be longer than 32 bytes.
@@ -749,7 +749,7 @@ Below all general purpose routines are listed, that were not mentioned
 before.
 
   /* This call returns a unique low identifier for each registered adapter,
-   * or -1 if the adapter was not regisitered.
+   * or -1 if the adapter was not registered.
    */
   extern int i2c_adapter_id(struct i2c_adapter *adap);
 
@@ -791,7 +791,7 @@ The third, sixth and ninth parameters should always be NULL, and the
 fourth should always be 0. The fifth is the mode of the /proc file;
 0644 is safe, as the file will be owned by root:root. 
 
-The seventh and eigth parameters should be &sensors_proc_real and
+The seventh and eighth parameters should be &sensors_proc_real and
 &sensors_sysctl_real if you want to export lists of reals (scaled
 integers). You can also use your own function for them, as usual.
 Finally, the last parameter is the call-back to gather the data
index 5bb41f96fc7aa1c94de1232657d791759cae4bda..54b591caa8611d84b9147f846d9be119c68570cb 100644 (file)
@@ -57,8 +57,8 @@ IA-64 SPECIFICS
       table and only if that fails fall back on walking the page table
       tree.
          
-    o Discontigous large memory support; memory above 4GB will be
-      discontigous since the 4GB-64MB is reserved for firmware and I/O
+    o Discontinuous large memory support; memory above 4GB will be
+      discontinuous since the 4GB-64MB is reserved for firmware and I/O
       space.
  
     o Correct mapping for PAL runtime code; PAL code needs to be
index b0c62765c7c75e54433a63df432cd21efcc44b13..87f66bbafdab67cb953a3430f621c92698c29b3b 100644 (file)
@@ -36,7 +36,7 @@ The Epoch is January 1st 1998. For backward compatibility reasons we don't
 expose this new way of representing time. Instead we use something very 
 similar to the struct tm, i.e. struct rtc_time, as used by hwclock.
 One of the reasons for doing it this way is to allow for EFI to still evolve
-without necessarily impatcing any of the user applications. The decoupling
+without necessarily impacting any of the user applications. The decoupling
 enables flexibility and permits writing wrapper code is ncase things change.
 
 The driver exposes two interfaces, one via the device file and a set of ioctl()s.
index b2e73cbc1d17ff1f32d6c4a16c9362b7d2d18a00..0f2b8e0f6f5edc15289052c85b84af2260779653 100644 (file)
@@ -31,7 +31,7 @@ README.act2000
 README.eicon
        - info on driver for Eicon active cards.
 README.concap
-       - info on "CONCAP" ecapsulation protocol interface used for X.25.
+       - info on "CONCAP" encapsulation protocol interface used for X.25.
 README.diversion
        - info on module for isdn diversion services.
 README.sc
index 2c9659f0df01f520a2e1ecf7af29fd2c3726d490..4c164b8054ab74c4b231e444e15fdcf3d9277f9e 100644 (file)
@@ -4,7 +4,7 @@ $Id: INTERFACE.fax,v 1.1 1999/08/11 20:30:28 armin Exp $
 Description of the fax-subinterface between linklevel and hardwarelevel of 
   isdn4linux. 
 
-  The communication between linklevel (LL) and harwarelevel (HL) for fax
+  The communication between linklevel (LL) and hardwarelevel (HL) for fax
   is based on the struct T30_s (defined in isdnif.h).
   This struct is allocated in the LL.  
   In order to use fax, the LL provides the pointer to this struct with the 
@@ -60,7 +60,7 @@ Structure T30_s:
   depending on progress and type of connection.
   If the phase changes because of an AT command, the LL driver
   changes this value. Otherwise the HL-driver takes care of it, but
-  only neccessary on call establishment (from IDLE to PHASE_A).
+  only necessary on call establishment (from IDLE to PHASE_A).
   (one of the constants ISDN_FAX_PHASE_[IDLE,A,B,C,D,E])
 
   -  direction
index afd9f45af04d4b16cc9f5a712162a880fb3c8832..0d3b0b02331bfd9b208180d59a0574386d2fc0f0 100644 (file)
@@ -146,7 +146,7 @@ README for the ISDN-subsystem
                             x = 38400: 198
                           Note on value in Reg 19:
                             There is _NO_ common convention for 38400 baud.
-                            The value 198 is choosen arbitrarily. Users
+                            The value 198 is chosen arbitrarily. Users
                             _MUST_ negotiate this value before establishing
                             a connection.
                AT&Sx    Set window-size (x = 1..8) (not yet implemented)
index 0416782255fc7461be30f3e4e691e096a015ea93..fb64b1ecd2fceac6145c91ecd493cf04d32fe24f 100644 (file)
@@ -77,7 +77,7 @@ Note: PCF, PCF-Pro: up to now, only the ISDN part is supported
 
 If you know other passive cards with the Siemens chipset, please let me know.
 To use the PNP cards you need the isapnptools.
-You can combine any card, if there is no conflict between the ressources
+You can combine any card, if there is no conflict between the resources
 (io, mem, irq).
 
 
@@ -532,7 +532,7 @@ to e.g. the Internet:
       /sbin/isdnctrl huptimeout isdn0 0
       /sbin/isdnctrl l2_prot isdn0 hdlc
       # Attention you must not set an outgoing number !!! This won't work !!!
-      # The incomming number is LEASED0 for the first card, LEASED1 for the
+      # The incoming number is LEASED0 for the first card, LEASED1 for the
       # second and so on.
       /sbin/isdnctrl addphone isdn0 in LEASED0
       # Here is no need to bind the channel.
@@ -551,7 +551,7 @@ a) Use state of the art isdn4k-utils
 
 Here an example script:
 #!/bin/sh
-# Start/Stop ISDN lesaed line connection
+# Start/Stop ISDN leased line connection
 
 I4L_AS_MODULE=yes
 I4L_REMOTE_IS_CISCO=no
index 7248ead804ab276cd7b079beebf3a78c32ddee14..0846d96b3e1445f8d8ee4e34e02ec475bf1fa0e4 100644 (file)
@@ -7,7 +7,7 @@ There are 3 Types of this card available. A ISA-, MCA-, and PCMCIA-Bus
 Version. Currently, only the ISA-Bus version of the card is supported.
 However MCA and PCMCIA will follow soon.
 
-The ISA-Bus Version uses 8 IO-ports. The base port adress has to be set
+The ISA-Bus Version uses 8 IO-ports. The base port address has to be set
 manually using the DIP switches.
 
 Setting up the DIP switches for the IBM Active 2000 ISDN card:
index 6fa9406dfece99ef3bf1b79809e94932797ae524..9e075484ef1e03e22385465c02ee9dbab61d2480 100644 (file)
@@ -175,7 +175,7 @@ a mail to majordomo@calle.in-berlin.de with
 subscribe linux-avmb1
 in the body.
 
-German documentaion and several scripts can be found at
+German documentation and several scripts can be found at
 ftp://ftp.avm.de/cardware/b1/linux/
 
 Bugs 
index a934fe346e2accf63d3c9d65221ff676c43163cc..2f114babe4b6a22538274deff8f384eece7a801f 100644 (file)
@@ -68,7 +68,7 @@ increased.
 Likewise, a similar encapsulation protocol will frequently be needed by
 several different interfaces of even different hardware type, e.g. the
 synchronous ppp implementation used by the isdn driver and the
-asyncronous ppp implementation used by the ppp driver have a lot of
+asynchronous ppp implementation used by the ppp driver have a lot of
 similar code in them. By cleanly separating the encapsulation protocol
 from the hardware specific interface stuff such code could be shared
 better in future.
index 8e1d7a01b1612a9b6309d0d40dc77babf0274c94..98909b1bf7e4977c758f5eeb459371141816d644 100644 (file)
@@ -57,7 +57,7 @@ Table of contents
    compared to the mechanism of ipfwadm or ipchains. If a given rule matches
    the checking process is finished and the rule matching will be applied
    to the call.
-   The rules include primary and secondary service indentifiers, called 
+   The rules include primary and secondary service identifiers, called 
    number and subaddress, callers number and subaddress and whether the rule
    matches to all filtered calls or only those when all B-channel resources
    are exhausted.
@@ -82,7 +82,7 @@ Table of contents
    available in some countries (for example germany). Countries requiring the 
    keypad protocol for activating static diversions (like the netherlands) are
    not supported but may use the tty devices for this purpose.
-   The dynamic diversion servives may be used in all countries if the provider
+   The dynamic diversion services may be used in all countries if the provider
    enables the feature CF (call forwarding). This should work on both MSN- and
    point-to-point lines.
    To add and delete rules the additional divertctrl program is needed. This
index c9dbd0de875063542cbb04f29104bc87eaab146d..9cfac4626df328f1a86116f0f8a4cdab8292ee98 100644 (file)
@@ -92,7 +92,7 @@ Table of contents
    3 -> card is booted and active
 
    And the last field (device) shows the name of the ethernet device assigned
-   to this card. Up to the first successfull boot this field only shows a -
+   to this card. Up to the first successful boot this field only shows a -
    to tell that no net device has been allocated up to now. Once a net device
    has been allocated it remains assigned to this card, even if a card is
    rebooted and an boot error occurs. 
@@ -128,12 +128,12 @@ Table of contents
    get the cards and drivers log data. Card messages always start with the
    keyword LOG. All other lines are output from the driver. 
    The driver log data may be redirected to the syslog by selecting the 
-   approriate bitmask. The cards log messages will always be send to this
+   appropriate bitmask. The cards log messages will always be send to this
    interface but never to the syslog.
 
    A root user may write a decimal or hex (with 0x) value t this file to select
    desired output options. As mentioned above the cards log dat is always 
-   written to the cardlog file independant of the following options only used
+   written to the cardlog file independent of the following options only used
    to check and debug the driver itself:
 
    For example: 
index 9c72e602509adf3da1daff2d122e9547425c8a43..37aa7f3d0e6b5c7b97c0768fe74e1dc7c8324065 100644 (file)
@@ -139,7 +139,7 @@ Loading the firmware into the card:
   To load a 4B-card, the same command is used, except a second firmware
   file is appended to the commandline of icnctrl.
 
-  -> After dowloading firmware, the two LEDs at the back cover of the card
+  -> After downloading firmware, the two LEDs at the back cover of the card
      (ICN-4B: 4 LEDs) must be blinking intermittently now. If a connection
      is up, the corresponding led is lit continuously.
 
index b70db7a630b1bcca92ca7205ecd298e6c61a106f..1153cd9260590e91e8c9552f1845a1045e785da2 100644 (file)
@@ -93,7 +93,7 @@ include:
     this driver release?
 
 Before you can compile, install and use the SpellCaster ISA ISDN driver, you
-must ensure that the following software is installed, configuraed and running:
+must ensure that the following software is installed, configured and running:
 
        - Linux kernel 2.0.20 or later with the required init and ps
          versions. Please see your distribution vendor for the correct
@@ -189,7 +189,7 @@ A) 10 steps to the establishment of a basic HDLC connection
        basic HDLC connection between its two channels.  Two network 
        interfaces are created and two routes added between the channels.
 
-       i)   using the isdnctrl utitity, add an interface with "addif" and 
+       i)   using the isdnctrl utility, add an interface with "addif" and 
             name it "isdn0"
        ii)  add the outgoing and inbound telephone numbers
        iii) set the Layer 2 protocol to hdlc
@@ -213,7 +213,7 @@ B) Establishment of a PPP connection
        This file is a script used to configure a BRI ISDN TA to establish a 
        PPP connection  between the two channels.  The file is almost 
        identical to the HDLC connection example except that the packet 
-       ecapsulation type has to be set.
+       encapsulation type has to be set.
        
        use the same procedure as in the HDLC connection from steps i) to 
        iii) then, after the Layer 2 protocol is set, set the encapsulation 
@@ -238,7 +238,7 @@ C) Establishment of a MLPPP connection
        This file is a script used to configure a BRI ISDN TA to accept a 
        Multi Link PPP connection. 
        
-       i)   using the isdnctrl utitity, add an interface with "addif" and 
+       i)   using the isdnctrl utility, add an interface with "addif" and 
             name it "ippp0"
        ii)  add the inbound telephone number
        iii) set the Layer 2 protocol to hdlc and the Layer 3 protocol to 
index b3a0c20c7398cf746ae8968e8b27a8f90c895418..763a5c4ff62451ef6bfd839df9f31cdbded9d05a 100644 (file)
@@ -29,13 +29,13 @@ By default, the device is opened in blocking mode.
 where js_event is defined as
 
        struct js_event {
-               __u32 time;     /* event timestamp in miliseconds */
+               __u32 time;     /* event timestamp in milliseconds */
                __s16 value;    /* value */
                __u8 type;      /* event type */
                __u8 number;    /* axis/button number */
        };
 
-If the read is successfull, it will return sizeof(struct js_event), unless
+If the read is successful, it will return sizeof(struct js_event), unless
 you wanted to read more than one event per read as described in section 3.1.
 
 
@@ -225,7 +225,7 @@ JS_VERSION symbol
 ~~~~~~~~~~~~~~
 
 JSIOCGNAME(len) allows you to get the name string of the joystick - the same
-as is being printed at boot time. The 'len' argument is the lenght of the
+as is being printed at boot time. The 'len' argument is the length of the
 buffer provided by the application asking for the name. It is used to avoid
 possible overrun should the name be too long.
 
index 0576fc07ebb7ba8a96d33576d412e13b10c0e462..fabfb1f01588a7fda5e8d3da3daf22ad2c4cd7d6 100644 (file)
@@ -22,7 +22,7 @@ connecting such devices.
 
 2. Devices supported
 ~~~~~~~~~~~~~~~~~~~~
-  Many console and 8-bit coputer gamepads and joysticks are supported. The
+  Many console and 8-bit computer gamepads and joysticks are supported. The
 following subsections discuss usage of each.
 
 2.1 NES and SNES
@@ -328,7 +328,7 @@ controllers:
 ~~~~~~~~
   All the Sega controllers are more or less based on the standard 2-button
 Multisystem joystick. However, since they don't use switches and use TTL
-logic, the only driver useable with them is the db9.c driver.
+logic, the only driver usable with them is the db9.c driver.
 
 2.4.1 Sega Master System
 ~~~~~~~~~~~~~~~~~~~~~~~~
index 18fc52232d32b9b4a9c1fc891c570307fafd4390..e66fb0d85c263c9132ef9ad4334dfdfbfb3dc4fc 100644 (file)
@@ -166,7 +166,7 @@ other system.
 
   It also supports extensions like additional hats and buttons compatible
 with CH Flightstick Pro, ThrustMaster FCS or 6 and 8 button gamepads. Saitek
-Cyborg 'digital' joysticks are also supportted by this driver, because
+Cyborg 'digital' joysticks are also supported by this driver, because
 they're basically souped up CHF sticks.
 
   However the only types that can be autodetected are:
@@ -475,7 +475,7 @@ models, the additional buttons on the 'Plus' versions are not supported yet.
        inputattach --magellan /dev/tts/x &
 
 command. After that the Magellan will be detected, initialized, will beep,
-and the /dev/input/jsX device should become useable.
+and the /dev/input/jsX device should become usable.
 
 3.17 I-Force devices 
 ~~~~~~~~~~~~~~~~~~~~
@@ -491,7 +491,7 @@ but is not limited to:
        inputattach --iforce /dev/tts/x &
 
 command. After that the I-Force device will be detected, and the
-/dev/input/jsX device should become useable.
+/dev/input/jsX device should become usable.
 
   In case you're using the device via the USB port, the inputattach command
 isn't needed.
index a732118484a5066cc64754de66ac8bbfecf97c69..d61e1a16e75cb33442855adc8a82b1d3e7b494ff 100644 (file)
@@ -84,7 +84,7 @@ Here are the targets available at the top level:
        occasionally.  If you are adding configuration options, it's
        nice if you do it before you publish your patch!
 
-       You can run 'make checkhelp' withoug configuring the kernel.
+       You can run 'make checkhelp' without configuring the kernel.
        Also, 'make checkhelp' does not modify any files.
 
     make dep, make depend
index b37dafb7e5e181d9f252a79fe611f2e4cf2b4d0c..dc175601332a16401b363a9aee5248b476240373 100644 (file)
@@ -80,7 +80,7 @@ Here are the basic grammar elements.
 
     A /word/ is a single unquoted word, a single-quoted string, or a
     double-quoted string.  If the word is unquoted or double quoted,
-    then $-substition will be performed on the word.
+    then $-substitution will be performed on the word.
 
     A /symbol/ is a single unquoted word.  A symbol must have a name of
     the form CONFIG_*.  scripts/mkdep.c relies on this convention in order
@@ -231,7 +231,7 @@ Note that the bool verb does not have a default value.  People keep
 trying to write Config Language scripts with a default value for bool,
 but *all* of the existing language interpreters discard additional values.
 Feel free to submit a multi-interpreter patch to linux-kbuild if you
-want to implement this as an enhancment.
+want to implement this as an enhancement.
 
 Configure:  implemented
 Menuconfig: implemented
index d3b7bc73fec53933990af092cb3fe1e16b503111..bf802ffc98ad1c134ea32a69a01fcb48259554aa 100644 (file)
@@ -21,7 +21,7 @@ Rom-vector: $1000
 
 The  card  should be a Z-II board, size 64K, not for freemem
 list, Rom-Vektor is valid, no second Autoconfig-board on the
-same card, no space preferrence, supports "Shutup_forever".
+same card, no space preference, supports "Shutup_forever".
 
 Setting  the  base address should be done in two steps, just
 as  the Amiga Kickstart does:  The lower nibble of the 8-Bit
@@ -29,7 +29,7 @@ address is written to $4a, then the whole Byte is written to
 $48, while it doesn't matter how often you're writing to $4a
 as  long as $48 is not touched.  After $48 has been written,
 the  whole card disappears from $e8 and is mapped to the new
-addrress just written.  Make shure $4a is written befor $48,
+address just written.  Make shure $4a is written before $48,
 otherwise your chance is only 1:16 to find the board :-).
 
 The local memory-map is even active when mapped to $e8:
@@ -100,7 +100,7 @@ IRQ-lines  of  the  IDE-ports by reading from the three (two
 for  Buddha-only)  registers  $f00, $f40 and $f80.  This way
 more  than one I/O request can be handled and you can easily
 determine  what  driver  has  to serve the INT2.  Buddha and
-Catweasel  expansion  boards  can issue an INT6.  A seperate
+Catweasel  expansion  boards  can issue an INT6.  A separate
 memory  map  is available for the I/O module and the sysop's
 I/O module.
 
index 5938cb8cf90f024756c65bdff83952f6098b524c..e191baad83082595eaa81e6076b234e49de23787 100644 (file)
@@ -482,7 +482,7 @@ the physical linelength differs from the visible length. With ProMST,
 xres_virtual must be set to 2048. For ET4000, xres_virtual depends on the
 initialisation of the video-card.
 If you're missing a corresponding yres_virtual: the external part is legacy,
-therefore we don't support hardware-dependend functions like hardware-scroll,
+therefore we don't support hardware-dependent functions like hardware-scroll,
 panning or blanking.
 
 4.1.7) eclock:
index 7e894fd977cfd7e03d3993edebafb124e84b1ced..0df89447bb0e4f29603be329ab60e7db55ea256c 100644 (file)
@@ -6,7 +6,7 @@ Tools that manage md devices can be found at
 You can boot (if you selected boot support in the configuration) with your md 
 device with the following kernel command lines:
 
-for old raid arrays without persistant superblocks:
+for old raid arrays without persistent superblocks:
   md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn
 
 for raid arrays with persistant superblocks
index 4357e6772d11841fabb7a885152278b6c296ac52..75efa68409d79e886dacbed6594de54c625e3ce0 100644 (file)
@@ -23,7 +23,7 @@ Content
     -C168P/H/HS, C168H/PCI 8 port multiport board.
 
    This driver has been modified a little and cleaned up from the Moxa
-   contributed driver code and merged into Linux 2.2.14pre. In paticular
+   contributed driver code and merged into Linux 2.2.14pre. In particular
    official major/minor numbers have been assigned which are different to
    those the original Moxa supplied driver used.
 
@@ -83,7 +83,7 @@ Content
 
        PCI board
        ---------
-       You may need to adjust IRQ useage in BIOS to avoid from IRQ conflict
+       You may need to adjust IRQ usage in BIOS to avoid from IRQ conflict
        with other ISA devices. Please refer to hardware installation
        procedure in User's Manual in advance.
 
@@ -150,7 +150,7 @@ Content
 
          # insmod mxser
 
-         to activate the moduler driver. You may run "lsmod" to check
+         to activate the modular driver. You may run "lsmod" to check
          if "mxser.o" is activated.
 
        2. Create special files by executing "msmknod".
@@ -158,7 +158,7 @@ Content
          # ./msmknod
 
          Default major numbers for dial-in device and callout device are
-         174, 175. Msmknod will delete any special files occuping the same
+         174, 175. Msmknod will delete any special files occupying the same
          device naming.
 
        3. Up to now, you may manually execute "insmod mxser" to activate
@@ -209,7 +209,7 @@ Content
          below.
          a. # cd /moxa/mxser/driver
             # vi mxser.c
-         b. Find the array mxserBoardCAP[] as belows.
+         b. Find the array mxserBoardCAP[] as below.
 
             static int mxserBoardCAP[]
             = {0x00, 0x00, 0x00, 0x00};
@@ -260,7 +260,7 @@ Content
           f. cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz
           g. Please make sure the boot kernel (vmlinuz) is in the
              correct position. If you use 'lilo' utility, you should
-             check /etc/lilo.conf 'image' item specifiedd the path
+             check /etc/lilo.conf 'image' item specified the path
              which is the 'vmlinuz' path, or you will load wrong
              (or old) boot kernel image (vmlinuz).
           h. chmod 400 /vmlinuz
@@ -372,7 +372,7 @@ Content
 -----------------------------------------------------------------------------
 6. Troubleshooting
 
-   The boot time error mesages and solutions are stated as clearly as
+   The boot time error messages and solutions are stated as clearly as
    possible. If all the possible solutions fail, please contact our technical
    support team to get more help.
 
@@ -388,7 +388,7 @@ Content
    which device causes the situation,please check /proc/interrupts to find
    free IRQ and simply change another free IRQ for Moxa board.
 
-   Error msg: Board #: C1xx Series(CAP=xxx) interupt number invalid.
+   Error msg: Board #: C1xx Series(CAP=xxx) interrupt number invalid.
    Solution:
    Each port within the same multiport board shares the same IRQ. Please set
    one IRQ (IRQ doesn't equal to zero) for one Moxa board.
index 941da7e91421ee1f8a3353b19b663c9473455ce8..01332836346a51778e38a9416460136bf1582123 100644 (file)
@@ -31,7 +31,7 @@ Richard Gooch
 There are two interfaces to /proc/mtrr: one is an ASCII interface
 which allows you to read and write. The other is an ioctl()
 interface. The ASCII interface is meant for administration. The
-ioctl() interface is meant for C programmes (i.e. the X server). The
+ioctl() interface is meant for C programs (i.e. the X server). The
 interfaces are described below, with sample commands and C code.
 
 ===============================================================================
@@ -96,11 +96,11 @@ Removing MTRRs from the C-shell:
 or using bash:
 % echo "disable=2" >| /proc/mtrr
 ===============================================================================
-Reading MTRRs from a C programme using ioctl()'s:
+Reading MTRRs from a C program using ioctl()'s:
 
 /*  mtrr-show.c
 
-    Source file for mtrr-show (example programme to show MTRRs using ioctl()'s)
+    Source file for mtrr-show (example program to show MTRRs using ioctl()'s)
 
     Copyright (C) 1997-1998  Richard Gooch
 
@@ -124,7 +124,7 @@ Reading MTRRs from a C programme using ioctl()'s:
 */
 
 /*
-    This programme will use an ioctl() on /proc/mtrr to show the current MTRR
+    This program will use an ioctl() on /proc/mtrr to show the current MTRR
     settings. This is an alternative to reading /proc/mtrr.
 
 
index 37c39a0c86f80d505152195c292410fee5a859d2..f82d42584e985474ed43d170e4d1eccea5d0c042 100644 (file)
@@ -30,7 +30,7 @@ cable modem easy.
       http://home.adelphia.net/~siglercm/sb1000.html
       http://linuxpower.cx/~cable/
 
-   along with these utilties.
+   along with these utilities.
 
 3.) The standard isapnp tools.  These are necessary to configure your SB1000
 card at boot time (or afterwards by hand) since it's a PnP card.
index a58e78d905f9a1dcb9dc9478e6b431b91322f042..38ad51622c042c22d85f312039f87c805986615d 100644 (file)
@@ -63,7 +63,7 @@ values upon creation, so you don't necessarily have to change all of them.
 
 When you're ready with filling in the files in the comx[n] directory, you can
 configure the corresponding network interface with the standard network 
-configuration utilites. If you're unble to bring the interfaces up, look up
+configuration utilities. If you're unable to bring the interfaces up, look up
 the various kernel log files on your system, and consult the messages for
 a probable reason.
 
index 24f15cb7114647778acc314146a4c35f1f717462..aaccf6bc0bb9804ebb8eeb9b9d04138cdb2c3fe7 100644 (file)
@@ -214,7 +214,7 @@ Example:
 \r
     insmod cs89x0.o io=0x200 irq=0xA media=aui\r
 \r
-This exmaple loads the module and configures the adapter to use an IO port base\r
+This example loads the module and configures the adapter to use an IO port base\r
 address of 200h, interrupt 10, and use the AUI media connection.  The following\r
 configuration options are available on the command line:\r
 \r
@@ -259,7 +259,7 @@ e) The minimum command-line configuration required if an EEPROM is
    irq \r
    media type (no autodetect)\r
 \r
-f) The following addtional parameters are CS89XX defaults (values\r
+f) The following additional parameters are CS89XX defaults (values\r
    used with no EEPROM or command-line argument).\r
 \r
    * DMA Burst = enabled\r
index 3a4116310351659180b391800e3a2af8b793239b..a2b050be911df86f8f9b716dfbbac5d7c035e1f9 100644 (file)
@@ -44,7 +44,7 @@ The kernel command line takes options looking like the following:
 the two numbers are the node address 1,2 = 1.2 For 2.2.xx kernels
 and early 2.3.xx kernels, you must use a comma when specifying the
 DECnet address like this. For more recent 2.3.xx kernels, you may
-use almost charecter except space, although a `.` would be the most
+use almost any character except space, although a `.` would be the most
 obvious choice :-)
 
 There used to be a third number specifying the node type. This option
index c8e5615967989d602da8347af8eaab3154f2cac4..c0e8398674eff5c5d026ed774a8fb01b23ad6c2b 100644 (file)
@@ -25,7 +25,7 @@
             -Wall -Wstrict-prototypes -O6 -c dmfe.c"
 
 
-  B. The following steps teach you how to active DM9102 board:
+  B. The following steps teach you how to activate a DM9102 board:
 
         1. Used the upper compiler command to compile dmfe.c
 
            "ifconfig eth0 172.22.3.18"
                           ^^^^^^^^^^^ Your IP address
 
-        4. Active the IP routing table. For some distributions, it is not
+        4. Activate the IP routing table. For some distributions, it is not
            necessary. You can type "route" to check.
 
            "route add default eth0"
 
 
-        5. Well done. Your DM9102 adapter actived now.
+        5. Well done. Your DM9102 adapter is now activated.
 
 
    C. Object files description:
index 7af37a00484bc92c063d5b541858a9b86a566d82..653f043a733ad8192483d4f2d1f6c7a8dbd3be74 100644 (file)
@@ -1,7 +1,7 @@
 Documentation on setup and use of EtherTap.
 
 Contact Jay Schulist <jschlst@turbolinux.com> if you
-have questions or need futher assistance.
+have questions or need further assistance.
 
 Introduction
 ============
index 482fbecb0ec64b2d8368a52bfec8d77059a71e58..e1436a7bb7714ee48b4bbebb6ed4ef4db5bd7911 100644 (file)
@@ -88,7 +88,7 @@ tcp_keepalive_interval - INTEGER
        will be aborted after ~11 minutes of retries.
 
 tcp_retries1 - INTEGER
-       How many times to retry before deciding that somethig is wrong
+       How many times to retry before deciding that something is wrong
        and it is necessary to report this suspection to network layer.
        Minimal RFC value is 3, it is default, which corresponds
        to ~3sec-8min depending on RTO.
@@ -139,13 +139,13 @@ tcp_max_orphans - INTEGER
        (probably, after increasing installed memory),
        if network conditions require more than default value,
        and tune network services to linger and kill such states
-       more aggressivley. Let me to remind again: each orphan eats
+       more aggressively. Let me to remind again: each orphan eats
        up to ~64K of unswappable memory.
 
 tcp_abort_on_overflow - BOOLEAN
        If listening service is too slow to accept new connections,
        reset them. Default state is FALSE. It means that if overflow
-       occured due to a burst, connection will recover. Enable this
+       occurred due to a burst, connection will recover. Enable this
        option _only_ if you are really sure that listening daemon
        cannot be tuned to accept connections faster. Enabling this
        option can harm clients of your server.
@@ -179,7 +179,7 @@ tcp_stdurg - BOOLEAN
        
 tcp_max_syn_backlog - INTEGER
        Maximal number of remembered connection requests, which are
-       still did not receive an acknowldgement from connecting client.
+       still did not receive an acknowledgement from connecting client.
        Default value is 1024 for systems with more than 128Mb of memory,
        and 128 for low memory machines. If server suffers of overload,
        try to increase this number. Warning! If you make it greater
index 8df88a7df809ffd62d8e663896c0569614334960..5fb6c3c744e8d3e2439c0f583916a7b4b730f3cc 100644 (file)
@@ -1,7 +1,7 @@
 Text file for ipddp.c:
        AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation
 
-This text file writen by Jay Schulist <jschlst@turbolinux.com>
+This text file is written by Jay Schulist <jschlst@turbolinux.com>
 
 Introduction
 ------------
index 94356d67de0ccb60e8d39f98bf7dcdf16b59a72c..39ccb8595bf15c8aec5639ae082717d533b066c4 100644 (file)
@@ -137,7 +137,7 @@ Installation
          -Pcbr:max_pcr=<xxx>
          where:
              xxx = the maximum peak cell rate, from 170 - 353207.
-         This option may only be set on the trasmit machine.
+         This option may only be set on the transmit machine.
 
 
 OUTSTANDING ISSUES
index 04198aec574839a7150e59e19c745597d13509bb..63806258a9ed916ac254fe75eb56ef2a3b26d700 100644 (file)
@@ -38,14 +38,14 @@ the driver now re-sizes buffers based on MTU settings as well.
 message_level: Controls level of messages created by the driver. Defaults to 0:
 which only displays start-up and critical messages.  Presently any non-zero 
 value will display all soft messages as well.  NB This does not turn 
-debuging messages on, that must be done by modified the source code.
+debugging messages on, that must be done by modified the source code.
 
 Multi-card:
 
 The driver will detect multiple cards and will work with shared interrupts,
 each card is assigned the next token ring device, i.e. tr0 , tr1, tr2.  The 
 driver should also happily reside in the system with other drivers.  It has 
-been tested with ibmtr.c running, and I personnally have had one Olicom PCI 
+been tested with ibmtr.c running, and I personally have had one Olicom PCI 
 card and two IBM olympic cards (all on the same interrupt), all running
 together. 
 
@@ -68,7 +68,7 @@ mode.  All unexpected MAC frames (beaconing etc.) will be received
 by the driver and the source and destination addresses printed. 
 Also an entry will be added in  /proc/net called olympic_tr. This 
 displays low level information about the configuration of the ring and
-the adapter. This feature has been designed for network adiministrators
+the adapter. This feature has been designed for network administrators
 to assist in the diagnosis of network / ring problems.
 
 6/8/99 Peter De Schrijver and Mike Phillips
index 1be0db8c0bc4362f16391b7a32dd5f0c9fa607ef..6c4ebb66a906558e6702c66228b0a5b2978130c9 100644 (file)
@@ -42,7 +42,7 @@ multiple route tables to get the flexibility.
 
        There is no "borrowing" or "sharing" scheme. This is a simple
 traffic limiter. We implement Van Jacobson and Sally Floyd's CBQ
-architecture into Linux 2.2. THis is the preferred solution. Shaper is
+architecture into Linux 2.2. This is the preferred solution. Shaper is
 for simple or back compatible setups.
 
 Alan
index b353eaa3be791df5414383216559e13584c3184b..6c26c9927728eeeae113af8fb20fde13cacdbb91 100644 (file)
 
   Silicon Integrated System Corp. is cooperating closely with core Linux
   Kernel developers. The revisions of SiS 900 driver are distributed by
-  the usuall channels for kernel tar files and patches. Those kernel tar
+  the usual channels for kernel tar files and patches. Those kernel tar
   files for official kernel and patches for kernel pre-release can be
   download at official kernel ftp site
   <http://ftp.kernel.org/pub/linux/kernel/> and its mirrors.  The 1.06
index 510d2c4ef82f1c7eb39efa29b67000da27843d71..2af3964ef378aa1938426ccb2c190fa9a36e0f06 100644 (file)
@@ -138,7 +138,7 @@ Insert a line of the form:
 options sk98lin ...
 
 For "...", use the same syntax as described below for the command
-line paramaters of insmod.
+line parameters of insmod.
 You either have to reboot your computer or unload and reload
 the driver to activate the new parameters.
 The syntax of the driver parameters is:
@@ -187,7 +187,7 @@ which you set the parameter (A or B).
   this port is not "Sense". If autonegotiation is "On", all
   three values are possible. If it is "Off", only "Full" and
   "Half" are allowed.
-  It is usefull if your link partner does not support all
+  It is useful if your link partner does not support all
   possible combinations.
 
 - Flow Control
@@ -269,7 +269,7 @@ which you set the parameter (A or B).
 
 Large frames (also called jumbo frames) are now supported by the
 driver. This can result in a greatly improved throughput if
-transfering large amounts of data.
+transferring large amounts of data.
 To enable large frames, set the MTU (maximum transfer unit)
 of the interface to the value you wish (up to 9000). The command
 for this is:
@@ -285,7 +285,7 @@ it will simply drop them.
 You can switch back to the standard ethernet frame size with:
   ifconfig eth0 mtu 1500
 
-To make this setting persitent, add a script with the 'ifconfig'
+To make this setting persistent, add a script with the 'ifconfig'
 line to the system startup sequence (named something like "S99sk98lin"
 in /etc/rc.d/rc2.d).
 ***
index 57dbe7a653d23ce793b976823bd705760b913239..a393133a403a6a27de0e6ee489ce4ba08b79a630 100644 (file)
@@ -62,5 +62,5 @@ Errata:
 
 This driver is under the GNU General Public License. Its Firmware image is
 included as an initialized C-array and is licensed by SMC to the Linux
-users of this driver. However no waranty about its fitness is expressed or
+users of this driver. However no warranty about its fitness is expressed or
 implied by SMC.
index 901eb44bc58cde588cae1fad5692093479528c4c..d513191cd9697862bd0df7ad7ecc915f9ea31f23 100644 (file)
@@ -51,7 +51,7 @@ II.   Driver Options
           0x01         Turn on general debugging messages.
           0x02         Turn on receive debugging messages.
           0x04         Turn on transmit debugging messages.
-          0x08         Turn on list debugging messsages.
+          0x08         Turn on list debugging messages.
 
        2. You can append aui=1 to the end of the insmod line to cause
            the adapter to use the AUI interface instead of the 10 Base T
index f73895f4fee8afaf040451305eb02849241eff4a..7ae835331fb5c2bc455b4e8fd954486566fe90a1 100644 (file)
@@ -10,8 +10,8 @@ Please point your browser to:
 http://www.linux-sna.org
 
 Many thanks to Christoph Goos for his excellent work on this driver and
-SysKonnect for donating the adapters to Linux-SNA for the testing and maintaince
-of this device driver.
+SysKonnect for donating the adapters to Linux-SNA for the testing and 
+maintenance of this device driver.
 
 Important information to be noted:
 1. Adapters can be slow to open (~20 secs) and close (~5 secs), please be 
@@ -52,7 +52,7 @@ to http://www.syskonnect.com
 
 This driver is under the GNU General Public License. Its Firmware image is 
 included as an initialized C-array and is licensed by SysKonnect to the Linux 
-users of this driver. However no waranty about its fitness is expressed or 
+users of this driver. However no warranty about its fitness is expressed or 
 implied by SysKonnect.
 
 Below find attached the setting for the SK NET TR 4/16 ISA adapters
index 35d5dea652c0e2668065e138e8d6fb08fd86eb70..b5a6254228fd0953d2ed2669cdd6cf5f52edab38 100644 (file)
@@ -170,7 +170,7 @@ Version history
 
 0.9.4.3 (April 14, 2000):
 * mod_timer fix (Hal Murray)
-* PNIC2 resusitation (Chris Smith)
+* PNIC2 resuscitation (Chris Smith)
 
 0.9.4.2 (March 21, 2000):
 * Fix 21041 CSR7, CSR13/14/15 handling
index 19d30079d4caa3c607b5ae9189307df6743d8391..9a8039234c815f4653556d43ab32ea35322a22f7 100644 (file)
@@ -8,7 +8,7 @@ driver for Linux, 3c59x.c.
 
 The driver was written by Donald Becker <becker@cesdis.gsfc.nasa.gov>
 
-Don is no longer the prime maintener of this version of the driver. 
+Don is no longer the prime maintainer of this version of the driver. 
 Please report problems to one or more of:
 
   Andrew Morton <andrewm@uow.edu.au>
@@ -64,7 +64,7 @@ its module is loaded.  These are usually placed in /etc/modules.conf
 
 options 3c59x debug=3 rx_copybreak=300
 
-If you are using the PCMCIA tools (cardmgr) then theoptions may be
+If you are using the PCMCIA tools (cardmgr) then the options may be
 placed in /etc/pcmcia/config.opts:
 
 module "3c59x" opts "debug=3 extra_reset=1"
@@ -135,7 +135,7 @@ rx_copybreak=M
 max_interrupt_work=N
 
   The driver's interrupt service routine can handle many receive and
-  transmit packets in a single invokation.  It does this in a loop. 
+  transmit packets in a single invocation.  It does this in a loop. 
   The value of max_interrupt_work governs how mnay times the interrupt
   service routine will loop.  The default value is 32 loops.  If this
   is exceeded the interrupt service routine gives up and generates a
index f82ceb548f63691833811c589e3ce9c0d424334c..5cb1b3e428be209bb93e19ac88f03e7e70aded41 100644 (file)
@@ -142,11 +142,11 @@ REVISION HISTORY
 
 2.0.8   Nov 02, 1999            - Fixed up the X25API code.
                                 - Clear call bug fixed.i
-                                - Eanbled driver for multi-card
+                                - Enabled driver for multi-card
                                   operation.                                
 
 2.0.7   Aug 26, 1999           - Merged X25API code into WANPIPE.
-                               - Fixed a memeory leak for X25API
+                               - Fixed a memory leak for X25API
                                - Updated the X25API code for 2.2.X kernels.
                                - Improved NEM handling.
 
index 7cb28178e908d76259fc07b6c95f31ab4ab38fee..1fd1642d8def9af3c427dc2cc998b2f140642c93 100644 (file)
@@ -228,7 +228,7 @@ REVISION HISTORY
                                creating applications using BiSync
                                streaming.        
 
-2.0.5   Aug 04, 1999           CHDLC initializatin bug fix.
+2.0.5   Aug 04, 1999           CHDLC initialization bug fix.
                                PPP interrupt driven driver: 
                                Fix to the PPP line hangup problem.
                                New PPP firmware
@@ -241,13 +241,13 @@ REVISION HISTORY
                                Streaming HDLC API has been taken out.  
                                 Available as a patch.                 
 
-2.0.6   Aug 17, 1999           Increased debugging in statup scripts
-                               Fixed insallation bugs from 2.0.5
+2.0.6   Aug 17, 1999           Increased debugging in startup scripts
+                               Fixed installation bugs from 2.0.5
                                Kernel patch works for both 2.2.10 and 2.2.11 kernels.
                                There is no functional difference between the two packages         
 
 2.0.7   Aug 26, 1999           o  Merged X25API code into WANPIPE.
-                               o  Fixed a memeory leak for X25API
+                               o  Fixed a memory leak for X25API
                                o  Updated the X25API code for 2.2.X kernels.
                                o  Improved NEM handling.   
 
index 82006e55d08b13a7feb5c6cb5ade68cc9cbd3fa2..c1acf5eb3712a4b03d0be47e2bf31f2cd6793a33 100644 (file)
@@ -19,7 +19,7 @@ and many Linux driver to support it.
 
        This is the driver for the ISA version of the first generation
 of the Wavelan, now discontinued. The device is 2 Mb/s, composed of a
-Intel 82586 controler and a Lucent Modem, and is NOT 802.11 compliant.
+Intel 82586 controller and a Lucent Modem, and is NOT 802.11 compliant.
        The driver has been tested with the following hardware :
        o Wavelan ISA 915 MHz (full length ISA card) 
        o Wavelan ISA 915 MHz 2.0 (half length ISA card) 
@@ -38,7 +38,7 @@ Intel 82586 controler and a Lucent Modem, and is NOT 802.11 compliant.
 
        This is the driver for the PCMCIA version of the first
 generation of the Wavelan, now discontinued. The device is 2 Mb/s,
-composed of a Intel 82593 controler (totally different from the 82586)
+composed of a Intel 82593 controller (totally different from the 82586)
 and a Lucent Modem, and NOT 802.11 compatible.
        The driver has been tested with the following hardware :
        o Wavelan Pcmcia 915 MHz 2.0 (Pcmcia card + separate
index feb78559effafaae3f95a7af7fb6df2c7120f549..7f517608a3690d11a776392b99b673fd97e70d4d 100644 (file)
@@ -7,7 +7,7 @@ on Intel SMP hardware there is a feature that enables us to generate
 'watchdog NMI interrupts'. (NMI: Non Maskable Interrupt - these get
 executed even if the system is otherwise locked up hard) This can be
 used to debug hard kernel lockups. By executing periodic NMI interrupts,
-the kernel can monitor wether any CPU has locked up, and print out
+the kernel can monitor whether any CPU has locked up, and print out
 debugging messages if so.  You can enable/disable the NMI watchdog at boot
 time with the 'nmi_watchdog=1' boot parameter. Eg. the relevant
 lilo.conf entry:
index c61827c07b823c59aa1382cb08846495b7d37fff..e6e9ee0506c3ee522cd63fc96179a1fcf4d68254 100644 (file)
@@ -125,7 +125,7 @@ if you have questions, comments or corrections.
 
          Although platform dependent, and certainly the case for embedded
          8xx, traditionally memory is mapped at physical address zero,
-         and I/O devices above phsical address 0x80000000.  The lowest
+         and I/O devices above physical address 0x80000000.  The lowest
          and highest (above 0xf0000000) I/O addresses are traditionally 
          used for devices or registers we need to map during kernel 
          initialization and prior to KVM operation.  For this reason, 
index 6f8f9b527a9332cc31aaf11b835ceee3b28a6614..9963f1e9c98a5f46a67d213624066028dc9ed3f0 100644 (file)
@@ -30,7 +30,7 @@ an Enterprise Storage Server (Seascape) should work fine as well.
 We currently implement one partition per volume, which is the whole
 volume, skipping the first blocks up to the volume label. These are
 reserved for IPL records and IBM's volume label to assure
-accessability of the DASD from other OSs. In a later stage we will
+accessibility of the DASD from other OSs. In a later stage we will
 provide support of partitions, maybe VTOC oriented or using a kind of
 partition table in the label record.
 
@@ -38,7 +38,7 @@ USAGE
 
 -Low-level format (?CKD only)
 For using an ECKD-DASD as a Linux harddisk you have to low-level
-format the tracks by issueing the BLKDASDFORMAT-ioctl on that
+format the tracks by issuing the BLKDASDFORMAT-ioctl on that
 device. This will erase any data on that volume including IBM volume
 labels, VTOCs etc. The ioctl may take a 'struct format_data *' or
 'NULL' as an argument.  
index d126fe4d6a56bbee799f59ba5bf09ca197d1e63c..99d514d4c3bbec5b316b6a78f7ab97c812b2dda5 100644 (file)
@@ -778,7 +778,7 @@ flag    : 0 (zero) or DOIO_WAIT_FOR_INTERRUPT
 The halt_IO() function returns :
 
       0 - successful completion or request successfuly initiated
--EBUSY  - the device is currently performing a sysnchonous I/O
+-EBUSY  - the device is currently performing a synchronous I/O
           operation : do_IO() with flag DOIO_WAIT_FOR_INTERRUPT
           or an error was encountered and the device is currently
           be sensed
index 70423953c9f297a47dddde291340155513780880..ba3ca358b339cb0b8cf4c9dac4267882aea9e940 100644 (file)
@@ -14,7 +14,7 @@ WHAT'S NEW
   1. Support modem interface for 8738. (select in kernel configuration)
   2. Enable S/PDIF-in to S/PDIF-out (S/PDIF loop).
   3. Enable 4 channels analog duplicate mode on 3 jack or 4 jack
-     configurateion.
+     configuration.
 
 
    Be aware: C-Media Electronics Inc. is basically an IC design house,
index ac551fa4dd982aa9930edba53bf1a0e24310a5eb..38d97ba972e605fc074d69355a5c80fedd436ead 100644 (file)
@@ -12,7 +12,7 @@ Every chip that's detected as a later-than-es1688 chip has a 6 bits logarithmic
 master volume control.
 
 Every chip that's detected as a ES1887 now has Full Duplex support. Made a 
-little testprogram that showes that is works, haven't seen a real program that
+little testprogram that shows that is works, haven't seen a real program that
 needs this however.
 
 For ESS chips an additional parameter "esstype" can be specified. This controls
index f2ce25d6745082e59895d91b961c1ec270a078b3..86aa069c18c95953068159e7664c36b3d6017549 100644 (file)
@@ -320,7 +320,7 @@ in the Sound-HOWTO).
 
 7)  Turn on debug in drivers/sound/sound_config.h (DEB, DDB, MDB).
 
-8)  If the system reports insuffcient DMA memory then you may want to
+8)  If the system reports insufficient DMA memory then you may want to
     load sound with the "dmabufs=1" option. Or in /etc/conf.modules add
        
        preinstall sound dmabufs=1
@@ -354,7 +354,7 @@ Module Loading:
 
 When a sound card is first referenced and sound is modular the sound system
 will ask for the sound devices to be loaded. Initially it requests that
-the driver for the sound system is loaded. It then wwill ask for 
+the driver for the sound system is loaded. It then will ask for 
 sound-slot-0, where 0 is the first sound card. (sound-slot-1 the second and
 so on). Thus you can do
 
index f572112ffc4983025264583c6a8e3221a26aefac..4a80eb3f8e00ef3a4d289c3e4c6e65c214b1dcb8 100644 (file)
@@ -70,7 +70,7 @@ maestro chip.
 
 As this is a PCI device, the module does not need to be informed of
 any IO or IRQ resources it should use, it devines these from the
-system.  Somtimes, on sucky PCs, the BIOS fails to allocated resources
+system.  Sometimes, on sucky PCs, the BIOS fails to allocated resources
 for the maestro.  This will result in a message like:
        maestro: PCI subsystem reports IRQ 0, this might not be correct.
 from the kernel.  Should this happen the sound chip most likely will
index ee81f73503cb213de19a2f03a8a3f38674e5c5e9..187b9525e1f6df0f9483ad027d0e52ece43ae459 100644 (file)
@@ -3,7 +3,7 @@ downloadable programs and also has an AD1848 "Microsoft Sound System"
 device. The PSS driver enables MSS and MPU401 modes of the card. SB 
 is not enabled since it doesn't work concurrently with MSS. 
 
-If you build this driver as a module then the driver takes the folowing
+If you build this driver as a module then the driver takes the following
 parameters
 
 pss_io.        The I/O base the PSS card is configured at (normally 0x220
index f594802e5c42da4dacf48349cdade56276891628..22c7979268daa7406ae3d2b71bb2b0c226680445 100644 (file)
@@ -81,7 +81,7 @@ contributors. (I could have forgotten some names.)
        Gregor Hoffleit Mozart support (initial version)
        Riccardo Facchetti Audio Excel DSP 16 (aedsp16) support
        James Hightower Spotting a tiny but important bug in CS423x support.
-       Denis Sablic    OPTi 82C924 spesific enhancements (non PnP mode)
+       Denis Sablic    OPTi 82C924 specific enhancements (non PnP mode)
        Tim MacKenzie   Full duplex support for OPTi 82C930.
        
        Please look at lowlevel/README for more contributors.
@@ -512,7 +512,7 @@ Yamaha OPL3-SA1
 
        There are also chips called OPL3-SA2, OPL3-SA3, ..., OPL3SA-N. They
        are PnP chips and will not work with the OPL3-SA1 driver. You should 
-       use the standard MSS, MPU401 and OPL3 options with thses chips and to
+       use the standard MSS, MPU401 and OPL3 options with these chips and to
        activate the card using isapnptools.
 
 4Front Technologies SoftOSS
@@ -1275,7 +1275,7 @@ with ES688).
 NOTE! ESS cards are not compatible with MSS/WSS so don't worry if MSS support
 of OSS doesn't work with it.
 
-There are some ES1688/688 based sound cards and (particularily) motherboards
+There are some ES1688/688 based sound cards and (particularly) motherboards
 which use software configurable I/O port relocation feature of the chip.
 This ESS proprietary feature is supported only by OSS/Linux.
 
@@ -1285,7 +1285,7 @@ At least a card called (Pearl?) Hypersound 16 supports IRQ 15 but it doesn't
 work.
 
 ES1868 is a PnP chip which is (supposed to be) compatible with ESS1688
-brobably works with OSS/Free after initialization using isapnptools.
+probably works with OSS/Free after initialization using isapnptools.
 
 Reveal cards
 ------------
index 39f7d954a8a9dfd49a2129337b5df6db12744547..98f525cab6c49156403cb2b3f98a8c79ac28269b 100644 (file)
@@ -77,7 +77,7 @@ Persistent DMA Buffers:
 The sound modules normally allocate DMA buffers during open() and
 deallocate them during close(). Linux can often have problems allocating
 DMA buffers for ISA cards on machines with more than 16MB RAM. This is
-because ISA DMA buffers must exist below the 16MB boundry and it is quite
+because ISA DMA buffers must exist below the 16MB boundary and it is quite
 possible that we can't find a large enough free block in this region after
 the machine has been running for any amount of time. The way to avoid this
 problem is to allocate the DMA buffers during module load and deallocate
index feda77915b18695742bf9c851bcf2f0240f2e4fe..af8a7d3a4e8e99c21182b65c006ec2b3f7c9341d 100644 (file)
@@ -28,7 +28,7 @@ ABOUT THIS DRIVER
  It can only play 22.05kHz / 8bit / Stereo samples, control external MIDI
  port.
  If you want to use your card as recent "16-bit" card, you should use
- Alsa or OSS/Linux driver. Ofcource you can write native PCI driver for
+ Alsa or OSS/Linux driver. Of course you can write native PCI driver for
  your cards :)
 
 
index 65f4bcb8a52fd6e589d86d089d0fd128e86d5c6f..084d485b1581ad10a91d98a12edbe259187043b5 100644 (file)
@@ -62,7 +62,7 @@ configuration structure. Note that kernel PCI support is required to use PCI
 boards.
 
 There are two methods of configuring ISA, EISA and MCA boards into the drivers.
-If using the driver as a loadable module then the simplist method is to pass
+If using the driver as a loadable module then the simplest method is to pass
 the driver configuration as module arguments. The other method is to modify
 the driver source to add configuration lines for each board in use.
 
@@ -108,7 +108,7 @@ when loading the driver. The general form of the configuration argument is
 
 where:
 
-    board?  -- specifies the arbitary board number of this board,
+    board?  -- specifies the arbitrary board number of this board,
                can be in the range 0 to 3.
 
     name    -- textual name of this board. The board name is the comman
index 5fe4af170183d3ab21f89e8e5f5bed83dc7f53b6..cc447c1b565b1e9f36683d1453a0dfe48aadfcec 100644 (file)
@@ -118,11 +118,11 @@ freepages.min     When the number of free pages in the system
                reaches this number, only the kernel can
                allocate more memory.
 freepages.low  If the number of free pages gets below this
-               point, the kernel starts swapping agressively.
+               point, the kernel starts swapping aggressively.
 freepages.high The kernel tries to keep up to this amount of
                memory free; if memory comes below this point,
                the kernel gently starts swapping in the hopes
-               that it never has to do real agressive swapping.
+               that it never has to do real aggressive swapping.
 
 ==============================================================
 
@@ -198,7 +198,7 @@ In 2.2, the page cache is used for 3 main purposes:
 - swap cache
 
 When your system is both deep in swap and high on cache,
-it probably means that a lot of the swaped data is being
+it probably means that a lot of the swapped data is being
 cached, making for more efficient swapping than possible
 with the 2.0 kernel.
 
@@ -213,7 +213,7 @@ each processor will be between the low and the high value.
 On a low-memory, single CPU system you can safely set these
 values to 0 so you don't waste the memory. On SMP systems it
 is used so that the system can do fast pagetable allocations
-without having to aquire the kernel memory lock.
+without having to acquire the kernel memory lock.
 
 For large systems, the settings are probably OK. For normal
 systems they won't hurt a bit. For small systems (<16MB ram)
index 7643922320f815acbe7fac7bd9ccc8e42b2501d2..4bb08aacafba936bd36d60d15b02b38e897ece0a 100644 (file)
@@ -74,14 +74,14 @@ On other - If you know of the key combos for other architectures, please
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Well, un'R'aw is very handy when your X server or a svgalib program crashes.
 
-sa'K' (Secure Access Key) is usefull when you want to be sure there are no
+sa'K' (Secure Access Key) is useful when you want to be sure there are no
 trojan program is running at console and which could grab your password
 when you would try to login. It will kill all programs on given console
 and thus letting you make sure that the login prompt you see is actually
 the one from init, not some trojan program.
 IMPORTANT:In its true form it is not a true SAK like the one in   :IMPORTANT
 IMPORTATN:c2 compliant systems, and it should be mistook as such. :IMPORTANT
-       It seems other find it usefull as (System Attention Key) which is
+       It seems other find it useful as (System Attention Key) which is
 useful when you want to exit a program that will not let you switch consoles.
 (For example, X or a svgalib program.)
 
index 38bdbaee0d95173a0a7dacad1748d2084b26e3b2..e05f4d43f20cce00c75d3c67a2a6d330a7622c48 100644 (file)
@@ -45,7 +45,7 @@ THANKS file in Inaky's driver):
 
         - USAR Systems provided us with one of their excellent USB
           Evaluation Kits. It allows us to test the Linux-USB driver
-          for compilance with the latest USB specification. USAR
+          for compliance with the latest USB specification. USAR
           Systems recognized the importance of an up-to-date open
           Operating System and supports this project with
           Hardware. Thanks!.
@@ -64,9 +64,9 @@ THANKS file in Inaky's driver):
           Linux users.
 
         - Many thanks to ing büro h doran [http://www.ibhdoran.com]!
-          It was almost imposible to get a PC backplate USB connector
+          It was almost impossible to get a PC backplate USB connector
           for the motherboard here at Europe (mine, home-made, was
-          quite lowsy :). Now I know where to adquire nice USB stuff!
+          quite lousy :). Now I know where to acquire nice USB stuff!
 
         - Genius Germany donated a USB mouse to test the mouse boot
           protocol. They've also donated a F-23 digital joystick and a
@@ -128,7 +128,7 @@ THANKS file in Inaky's driver):
           documentation for the UUSBD. Go for it!
 
         - Ric Klaren <ia_ric@cs.utwente.nl> for doing nice
-          introductory documents (compiting with Alberto's :).
+          introductory documents (competing with Alberto's :).
 
         - Christian Groessler <cpg@aladdin.de>, for it's help on those
           itchy bits ... :)
@@ -143,7 +143,7 @@ THANKS file in Inaky's driver):
         - Rasca Gmelch <thron@gmx.de> has revived the raw driver and
           pointed bugs, as well as started the uusbd-utils package.
 
-        - Peter Dettori <dettori@ozy.dec.com> is unconvering bugs like
+        - Peter Dettori <dettori@ozy.dec.com> is uncovering bugs like
           crazy, as well as making cool suggestions, great :)
 
         - All the Free Software and Linux community, the FSF & the GNU
@@ -153,7 +153,7 @@ THANKS file in Inaky's driver):
         - Big thanks to Richard Stallman for creating Emacs!
 
         - The people at the linux-usb mailing list, for reading so
-          many messages :) Ok, no more kidding; for all your advices!
+          many messages :) Ok, no more kidding; for all your advises!
 
         - All the people at the USB Implementors Forum for their
           help and assistance.
index 67cb9e31f62f8736cd5568188e97139754199b56..6cfd89ef34f08b317e24075360c6404b6cc7e2e4 100644 (file)
@@ -23,7 +23,7 @@ usage and information passing to the completion handler.
 - URBs can be linked. After completing one URB, the next one can be
 automatically submitted. This is especially useful for ISO transfers:
 You only have read/write the data from/to the buffers in the completion 
-handler, the continous streaming itself is transparently done by the 
+handler, the continuous streaming itself is transparently done by the 
 URB-machinery.
 
 1.2. The URB structure
@@ -104,7 +104,7 @@ transfer_flags.
 
 Usually, (to reduce restart time) the completion handler is called
 AFTER the URB re-submission. You can get the other way by setting
-USB_URB_EARLY_COMPLETE in transfer_flags. This is implicite for
+USB_URB_EARLY_COMPLETE in transfer_flags. This is implicit for
 INT transfers.
 
 1.5. How to submit an URB?
@@ -131,7 +131,7 @@ For isochronous endpoints, subsequent submitting of URBs to the same endpoint
 with the ASAP flag result in a seamless ISO streaming. Exception: The 
 execution cannot be scheduled later than 900 frames from the 'now'-time. 
 The same applies to INT transfers, but here the seamless continuation is 
-independent of the transfer flags (implicitely ASAP).
+independent of the transfer flags (implicitly ASAP).
 
 1.6. How to cancel an already running URB?
 
@@ -174,14 +174,14 @@ It is allowed to specify a varying length from frame to frame (e.g. for
 audio synchronisation/adaptive transfer rates). You can also use the length 
 0 to omit one or more frames (striping).
 
-As can be concluded from above, the UHCI-driver does not care for continous
+As can be concluded from above, the UHCI-driver does not care for continuous
 data in case of short packet ISO reads! There's no fixup_isoc() like in the 
 old driver. There may be a common routine to do this in the future, but this 
 has nothing to do with the UHCI-driver!
 
 For scheduling you can choose your own start frame or ASAP. As written above,
 queuing more than one ISO frame with ASAP to the same device&endpoint result 
-in seamless ISO streaming. For continous streaming you have to use URB
+in seamless ISO streaming. For continuous streaming you have to use URB
 linking. 
 
 1.9. How to start interrupt (INT) transfers?
index c60bd900bad08cbb067513d6078d06eeabec430e..079566472d11a428afeaf335c2e681d90b1c944d 100644 (file)
@@ -134,7 +134,7 @@ instead.
 
 3.1.3 usbkbd.c
 ~~~~~~~~~~~~~~
-  Much like usbmouse.c, this module talks to keyboards with a simpplified
+  Much like usbmouse.c, this module talks to keyboards with a simplified
 HIDBP protocol. It's smaller, but doesn't support any extra special keys.
 Use hid.c instead if there isn't any special reason to use this.
 
@@ -158,7 +158,7 @@ matter of a couple days to add it.
 
 3.2 Event handlers
 ~~~~~~~~~~~~~~~~~~
-  Event handlers distrubite the events from the devices to userland and
+  Event handlers distribute the events from the devices to userland and
 kernel, as needed.
 
 3.2.1 keybdev.c
@@ -230,7 +230,7 @@ And so on up to js31.
 ~~~~~~~~~~~~~
   Evdev is the generic input event interface. It passes the events generated
 in the kernel straight to the program, with timestamps. The API is still
-evolving, but should be useable now. It's described in section 5.
+evolving, but should be usable now. It's described in section 5.
 
   This should be the way for GPM and X to get keyboard and mouse mouse
 events. It allows for multihead in X without any specific multihead kernel
@@ -273,7 +273,7 @@ emulated, characters should appear if you move it.
   You can test the joystick emulation with the 'jstest' utility, available
 in the joystick package (see Documentation/joystick.txt).
 
-  You can test the event devics with the 'evtest' utitily available on the
+  You can test the event devics with the 'evtest' utility available on the
 input driver homepage (see the URL above).
 
 5. Event interface
@@ -295,7 +295,7 @@ struct input_event {
 };
 
   'time' is the timestamp, it returns the time at which the event happened.
-Type is for example EV_REL for relative momement, REL_KEY for a keypress or
+Type is for example EV_REL for relative movement, REL_KEY for a keypress or
 release. More types are defined in include/linux/input.h.
 
   'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete
index 39a5ce4827ef8d4633652284e38bef5c7eaeb3da..ad2dbc6b80a334fac6a68a24dde1813ab2a76774 100644 (file)
@@ -1,7 +1,7 @@
 
 The OHCI HCD layer is a simple but nearly complete implementation of what the
 USB people would call a HCD  for the OHCI. 
- (ISO comming soon, Bulk, INT u. CTRL transfers enabled)
+ (ISO coming soon, Bulk, INT u. CTRL transfers enabled)
 It is based on Linus Torvalds UHCI code and Gregory Smith OHCI fragments (0.03 source tree).
 The layer (functions) on top of it, is for interfacing to the alternate-usb device-drivers. 
 
@@ -35,11 +35,11 @@ Features:
 
 - Endpoint Descriptor (ED) handling more static approach 
  (EDs should be allocated in parallel to the SET CONFIGURATION command and they live
- as long as the function (device) is alive or another configuration is choosen.
+ as long as the function (device) is alive or another configuration is chosen.
  In the HCD layer the EDs has to be allocated manually either by calling a subroutine
  or by sending a USB root hub vendor specific command to the virtual root hub.
  At the alternate linux usb stack EDs will be added (allocated) at their first use.
- ED will be unlinked from the HC chains if they are not bussy.
+ ED will be unlinked from the HC chains if they are not busy.
  
  files: ohci-hcd.c ohci-hcd.h
  routines:   (do not use for drivers, use the top layer alternate usb commands instead)
index bd519ec0769e39cbf938e4ff03696ff27fe5e51a..b15e6817652e1ea19e7591c26afe41d4ae4c6f7e 100644 (file)
@@ -158,7 +158,7 @@ MODULE PARAMETERS:
   DEFAULT: 5
   DESC: This is the number of times the driver will try to sync and detect the
         internal i2c bus (which connects the OV511 and sensor). If you are
-        getting intermittant detection failures ("Failed to read sensor ID...")
+        getting intermittent detection failures ("Failed to read sensor ID...")
         you should increase this by a modest amount. If setting it to 20 or so
         doesn't fix things, look elsewhere for the cause of the problem.
 
index 84510b9505d2429ed88a35dd92b54e6f532f0c7d..f3e629cbecabc19eff6a28af6a2d8e83e819b7ec 100644 (file)
@@ -103,7 +103,7 @@ S:  Product=ssss
 S:  SerialNumber=ssss
 |   |__Serial Number of this device as read from the device,
 |      except that it is a generated string for USB host controllers
-|      (virtual root hubs), and represent's the host controller's
+|      (virtual root hubs), and represents the host controller's
 |      unique identification in the system (currently I/O or
 |      memory-mapped base address).
 |__String info tag
index e800b37e5f7dbbe12c895fa0588391c5969e303b..1dce956deed417f8f4370676f963a45cce7eaf74 100644 (file)
@@ -121,11 +121,11 @@ data in the file is raw data so it's not very useful for imaging.
 
 MESSAGES
 
-On occassion the message 'usb_control/bulk_msg: timeout' or something
+On occasions the message 'usb_control/bulk_msg: timeout' or something
 similar will appear in '/var/adm/messages' or on the console or both,
 depending on how your system is configured.  This is a side effect
 that scanners are sometimes very slow at warming up and/or
-initialiazing.  In most cases, however, only several of these messages
+initializing.  In most cases, however, only several of these messages
 should appear and is generally considered to be normal.  If you see
 a message of the type 'excessive NAK's received' then this should
 be considered abnormal and generally indicates that the USB system is
index 53aaa11d8fb700c9c1557f36f60055891edea68c..13ed3a96c155c7b0d53f18045473dd92e1fcb04a 100644 (file)
@@ -32,7 +32,7 @@ The invention of the basic concept, and major coding were completed in two
 days (and nights) on the 16th and 17th of October 1999, now known as the
 great USB-October-Revolution started by GA, DF, and TS ;-)
 
-Since the concept is in no way UHCI dependant, we hope that it will also be 
+Since the concept is in no way UHCI dependent, we hope that it will also be 
 transfered to the OHCI-driver, so both drivers share a common API.
 
 1.2. Advantages and disadvantages
@@ -58,7 +58,7 @@ and its semantics were unnecessary complicated in our opinion.
 
 1.4. What's really working?
 
-As said above, CTRL und BULK already work fine even with the wrappers,
+As said above, CTRL and BULK already work fine even with the wrappers,
 so legacy code wouldn't notice the change.
 Regarding to Thomas, ISO transfers now run stable with USB audio.
 INT transfers (e.g. mouse driver) work fine, too.
@@ -113,7 +113,7 @@ before the End Chain QH (for BULK). Since only the QH->next pointers are
 affected, no atomic memory operation is required. The three QHs in the
 common chain are never equipped with TDs!
 
-For ISO or INT, the TD for each frame is simply inserted into the apropriate
+For ISO or INT, the TD for each frame is simply inserted into the appropriate
 ISO/INT-TD-chain for the desired frame. The 7 skeleton INT-TDs are scattered
 among the 1024 frames similar to the old UHCI driver.
 
index b5b30911b5c9fb22fcb6894cfcdf5f68f5dd63a0..da7d1909075620a3a08565533df48cf2d96ff589 100644 (file)
@@ -46,7 +46,7 @@ ConnectTech WhiteHEAT 4 port converter
 
 Current status:
   The device's firmware is downloaded on connection, the new firmware 
-  runs properly and all four ports are successfuly recognized and connected.
+  runs properly and all four ports are successfully recognized and connected.
   Data can be sent and received through the device on all ports.
   Hardware flow control needs to be implemented.
 
index 6d54c07c0443630a901cab9741b223f07cd311bc..8bbe611039057f22f871af8090ced5ed730ddd89 100644 (file)
@@ -127,7 +127,7 @@ everything is working.
 
   The c-qcam is IEEE1284 compatible, so if you are using the proc file
 system (CONFIG_PROC_FS), the parallel printer support
-(CONFIG_PRINTER), the IEEE 1284 sytem,(CONFIG_PRINTER_READBACK), you
+(CONFIG_PRINTER), the IEEE 1284 system,(CONFIG_PRINTER_READBACK), you
 should be able to read some identification from your quickcam with
 
          modprobe -v parport
index 7ac342ff696a745d792f966f47d55a3c24784e45..521ef795a6474425edc68dba5c72eef7b7fa5a96 100644 (file)
@@ -107,7 +107,7 @@ FEATURES:
   device opens
 - complete control over camera via proc-interface (_all_ camera settings are
   supported), there is also a python-gtk application available for this [3]
-- works under SMP (but the driver is completly serialized and synchronous)
+- works under SMP (but the driver is completely serialized and synchronous)
   so you get no benefit from SMP, but at least it does not crash your box
 - might work for non-Intel architecture, let us know about this
 
@@ -159,7 +159,7 @@ IMPLEMENTATION NOTES:
 
 The camera can act in two modes, streaming or grabbing. Right now a
 polling grab-scheme is used. Maybe interrupt driven streaming will be
-used for a ansychronous mmap interface in the next major release of the
+used for a asynchronous mmap interface in the next major release of the
 driver. This might give a better frame rate.
 
 ---------------------------------------------------------------------------
index a3f2347f0b33542472c3e38fca95132b3ef68b70..2b75345f13e3a428a862b18348e5a724a7b4c3fc 100644 (file)
@@ -35,7 +35,7 @@ PHYSICAL DESCRIPTION
 --------------------
 The RadioTrack card is an ISA 8-bit FM radio card.  The radio frequency (RF)
 input is simply an antenna lead, and the output is a power audio signal
-available through a miniature phono plug.  Its RF frequencies of operation are
+available through a miniature phone plug.  Its RF frequencies of operation are
 more or less limited from 87.0 to 109.0 MHz (the commercial FM broadcast
 band).  Although the registers can be programmed to request frequencies beyond
 these limits, experiments did not give promising results.  The variable
index 54e46326a1e0e230e7168fb5fe3be32e556ed3ee..96ecaa8978bae85aa289b8777f8825affb09e39f 100644 (file)
@@ -45,7 +45,7 @@ fps we ought to get... Here is the scenario: capturing frames
 to memory is done in the so-called snapshot mode. In this mode
 the Zoran stops after capturing a frame worth of data and wait
 till the application set GRAB bit to indicate readiness for the
-next frame. After detecting a set bit, the chip neetly waits
+next frame. After detecting a set bit, the chip neatly waits
 till the start of a frame, captures it and it goes back to off.
 Smart ppl will notice the problem here. Its the waiting on the
 _next_ frame each time we set the GRAB bit... Oh well, 12,5 fps
index 21a3442b77b918a385a04b4dd42ce2930aae2766..b28fb352ba286ddade997d04b6e18babdddf927f 100644 (file)
@@ -14,7 +14,7 @@ across nodes, and trying to house all the data structures that
 key components of the kernel need on memory on that node.
 
 Currently, all the numa support is to provide efficient handling
-of widely discontiguous physical memory, so architectures which 
+of widely discontinuous physical memory, so architectures which 
 are not NUMA but can have huge holes in the physical address space
 can use the same code. All this code is bracketed by CONFIG_DISCONTIGMEM.
 
index a43577dedd65f41e773adadbe7aacdf32a5b5c09..f521bc0d52d7bacc4e2dc41c21bdcf14f8df74bd 100644 (file)
@@ -393,8 +393,8 @@ L:  linux-kernel@vger.rutgers.edu
 S:     Maintained
 
 FILE LOCKING (flock() and fcntl()/lockf())
-P:     Andy Walker
-M:     andy@lysaker.kvaerner.no
+P:     Matthew Wilcox
+M:     willy@thepuffingroup.com
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
index 4b89522d199b98b25ae087c29441267a2b794f15..8d2689a29018f17cd04cc96388085ca66026adb6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -test5
+EXTRAVERSION = -test6
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -128,8 +128,8 @@ DRIVERS-y :=
 DRIVERS-m :=
 DRIVERS-  :=
 
-DRIVERS-$(CONFIG_DRM) += drivers/char/drm/drm.o
 DRIVERS-$(CONFIG_AGP) += drivers/char/agp/agp.o
+DRIVERS-$(CONFIG_DRM) += drivers/char/drm/drm.o
 DRIVERS-$(CONFIG_NUBUS) += drivers/nubus/nubus.a
 DRIVERS-$(CONFIG_ISDN) += drivers/isdn/isdn.a
 DRIVERS-$(CONFIG_NET_FC) += drivers/net/fc/fc.a
@@ -177,6 +177,8 @@ include arch/$(ARCH)/Makefile
 
 # use '-fno-strict-aliasing', but only if the compiler can take it
 CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi)
+# likewise for -fno-delete-null-pointer-checks
+CFLAGS += $(shell if $(CC) -fno-delete-null-pointer-checks -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-delete-null-pointer-checks"; fi)
 
 export CPPFLAGS CFLAGS AFLAGS
 
@@ -308,7 +310,7 @@ modules_install:
        MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE); \
        mkdir -p $$MODLIB; \
        rm -f $$MODLIB/build; \
-       ln -s $TOPDIR $$MODLIB/build; \
+       ln -s $$TOPDIR $$MODLIB/build; \
        cd modules; \
        MODULES=""; \
        inst_mod() { These="`cat $$1`"; MODULES="$$MODULES $$These"; \
index d77c2efc6f88511b9b6ff2e4ddce6571cf23cbb4..253b8d6c191a08c2c28e97253d7ada56fd330b99 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/config.h>
 #include <asm/system.h>
+#include <asm/cache.h>
 
 #define SIGCHLD 20
 
@@ -577,7 +578,7 @@ ret_from_sys_call:
        cmovne  $26,0,$19               /* $19 = 0 => non-restartable */
        ldl     $3,TASK_PROCESSOR($8)
        lda     $4,softirq_state
-       sll     $3,5,$3
+       sll     $3,L1_CACHE_SHIFT,$3
        addq    $3,$4,$4
        ldq     $4,0($4)
        sll     $4,32,$3
index b63dcb89e7d7112b6d635ea9a825aff62af2adc7..4087e089bc733471b5c8d258d6c77e5861938db9 100644 (file)
@@ -58,7 +58,7 @@ CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>
 endif
 
 ifdef CONFIG_MK7
-CFLAGS += $(shell if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686"; fi) -malign-functions=4 -fschedule-insns2 -mwide-multiply -fexpensive-optimizations
+CFLAGS += $(shell if $(CC) -march=athlon -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=athlon"; else  if $(CC) -march=i686 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=i686 -malign-functions=4";  fi fi) 
 endif
 
 ifdef CONFIG_MCRUSOE
index 15d6e4f6a724d4637c13f59a1d203af173a1b961..abb382d8ff6a2f747ab5e80fa640dec651fc13a6 100644 (file)
@@ -298,6 +298,7 @@ void setup_normal_output_buffer(void)
        if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n");
 #endif
        output_data = (char *)0x100000; /* Points to 1M */
+       free_mem_end_ptr = (long)real_mode;
 }
 
 struct moveparams {
index d9fcd91db9a757a912a941fa7ae957b662daeceb..5f6ae670db8baf1b396197686048403e7fc81457 100644 (file)
@@ -344,5 +344,5 @@ mainmenu_option next_comment
 comment 'Kernel hacking'
 
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
-bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_VT
 endmenu
index 1055ed5e33b496f1d195af70aa909577e36c24b4..4ead92e81cb94e4df05004ff990eb83ee463ea05 100644 (file)
@@ -478,13 +478,13 @@ CONFIG_PSMOUSE=y
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
 CONFIG_DRM=y
 CONFIG_DRM_TDFX=y
 # CONFIG_DRM_GAMMA is not set
 # CONFIG_DRM_R128 is not set
 # CONFIG_DRM_I810 is not set
 # CONFIG_DRM_MGA is not set
-# CONFIG_AGP is not set
 CONFIG_PCMCIA_SERIAL=y
 
 #
index 0519aee0caaa3ea0360bc5c1c2e9327a89c2c7f0..c02385e793f46b3a5561207de7298db407df6472 100644 (file)
@@ -145,11 +145,10 @@ static int microcode_open(struct inode *inode, struct file *file)
        return 0;
 }
 
+/* our specific f_op->release() method needs no locking */
 static int microcode_release(struct inode *inode, struct file *file)
 {
-       lock_kernel();
        clear_bit(MICROCODE_IS_OPEN, &microcode_status);
-       unlock_kernel();
        return 0;
 }
 
index 1ea5c62e9aba1fe3a2a1b94f6919f91af945da7d..23cd0c30c4aee2e2cc3c374fc4f1aa0bb8445710 100644 (file)
@@ -50,25 +50,25 @@ ifdef CONFIG_CPU_R3000
 CFLAGS         := $(CFLAGS) -mcpu=r3000 -mips1
 endif
 ifdef CONFIG_CPU_R6000
-CFLAGS         := $(CFLAGS) -mcpu=r6000 -mips2
+CFLAGS         := $(CFLAGS) -mcpu=r6000 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_R4300
-CFLAGS         := $(CFLAGS) -mcpu=r4300 -mips2
+CFLAGS         := $(CFLAGS) -mcpu=r4300 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_R4X00
-CFLAGS         := $(CFLAGS) -mcpu=r4600 -mips2
+CFLAGS         := $(CFLAGS) -mcpu=r4600 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_R5000
-CFLAGS         := $(CFLAGS) -mcpu=r8000 -mips2
+CFLAGS         := $(CFLAGS) -mcpu=r8000 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_NEVADA
-CFLAGS         := $(CFLAGS) -mcpu=r8000 -mips2 -mmad
+CFLAGS         := $(CFLAGS) -mcpu=r8000 -mips2 -Wa,--trap -mmad
 endif
 ifdef CONFIG_CPU_R8000
-CFLAGS         := $(CFLAGS) -mcpu=r8000 -mips2
+CFLAGS         := $(CFLAGS) -mcpu=r8000 -mips2 -Wa,--trap
 endif
 ifdef CONFIG_CPU_R10000
-CFLAGS         := $(CFLAGS) -mcpu=r8000 -mips2
+CFLAGS         := $(CFLAGS) -mcpu=r8000 -mips2 -Wa,--trap
 endif
 
 #
index b064607cae619914cc9f5bb520665c7230f1ded4..41b93931bf29a949391e8e942f5c8f714a5e3a60 100644 (file)
@@ -9,15 +9,6 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
 mainmenu_option next_comment
 comment 'Machine selection'
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -100,80 +91,88 @@ fi
 endmenu
 
 mainmenu_option next_comment
-       comment 'CPU selection'
-
-       choice 'CPU type' \
-               "R3000 CONFIG_CPU_R3000 \
-                R6000 CONFIG_CPU_R6000 \
-                R4300 CONFIG_CPU_R4300 \
-                R4x00 CONFIG_CPU_R4X00 \
-                R5000 CONFIG_CPU_R5000 \
-                R56x0 CONFIG_CPU_NEVADA \
-                R8000 CONFIG_CPU_R8000 \
-                R10000 CONFIG_CPU_R10000" R4x00
-
-       bool 'Override CPU Options' CONFIG_CPU_ADVANCED
-
-       if [ "$CONFIG_CPU_ADVANCED" = "y" ]; then
-               bool '  ll/sc Instructions available' CONFIG_CPU_HAS_LLSC
-               bool '  Writeback Buffer available' CONFIG_CPU_HAS_WB
-       else
-               if [ "$CONFIG_CPU_R3000" = "y" ]; then
-                       if [ "$CONFIG_DECSTATION" = "y" ]; then
-                               define_bool CONFIG_CPU_HAS_LLSC n
-                               define_bool CONFIG_CPU_HAS_WB y
-                       else
-                               define_bool CONFIG_CPU_HAS_LLSC n
-                               define_bool CONFIG_CPU_HAS_WB n
-                       fi
-               else
-                       define_bool CONFIG_CPU_HAS_LLSC y
-                       define_bool CONFIG_CPU_HAS_WB n
-               fi
-       fi
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
 endmenu
 
 mainmenu_option next_comment
-comment 'General setup'
+comment 'CPU selection'
+
+choice 'CPU type' \
+       "R3000 CONFIG_CPU_R3000 \
+        R6000 CONFIG_CPU_R6000 \
+        R4300 CONFIG_CPU_R4300 \
+        R4x00 CONFIG_CPU_R4X00 \
+        R5000 CONFIG_CPU_R5000 \
+        R56x0 CONFIG_CPU_NEVADA \
+        R8000 CONFIG_CPU_R8000 \
+        R10000 CONFIG_CPU_R10000" R4x00
+
+bool 'Override CPU Options' CONFIG_CPU_ADVANCED
+
+if [ "$CONFIG_CPU_ADVANCED" = "y" ]; then
+   bool '  ll/sc Instructions available' CONFIG_CPU_HAS_LLSC
+   bool '  Writeback Buffer available' CONFIG_CPU_HAS_WB
+else
+   if [ "$CONFIG_CPU_R3000" = "y" ]; then
+      if [ "$CONFIG_DECSTATION" = "y" ]; then
+        define_bool CONFIG_CPU_HAS_LLSC n
+        define_bool CONFIG_CPU_HAS_WB y
+      else
+        define_bool CONFIG_CPU_HAS_LLSC n
+        define_bool CONFIG_CPU_HAS_WB n
+      fi
+   else
+      define_bool CONFIG_CPU_HAS_LLSC y
+      define_bool CONFIG_CPU_HAS_WB n
+   fi
+fi
+endmenu
 
-       if [ "$CONFIG_DECSTATION" = "y" -o "$CONFIG_DDB5074" = "y" ]; then
-          define_bool CONFIG_CPU_LITTLE_ENDIAN y
-       else
-          bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
-       fi
+mainmenu_option next_comment
+comment 'General setup'
+if [ "$CONFIG_DECSTATION" = "y" -o "$CONFIG_DDB5074" = "y" ]; then
+   define_bool CONFIG_CPU_LITTLE_ENDIAN y
+else
+   bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
+fi
 
-       if [ "$CONFIG_PROC_FS" = "y" ]; then
-          define_bool CONFIG_KCORE_ELF y
-       fi
-       define_bool CONFIG_ELF_KERNEL y
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   define_bool CONFIG_KCORE_ELF y
+fi
+define_bool CONFIG_ELF_KERNEL y
 
-       if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
-          bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX 
-          bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD 
-       fi
+if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
+   bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX 
+   bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD 
+fi
 
-       define_bool CONFIG_BINFMT_AOUT n
-       define_bool CONFIG_BINFMT_ELF y
-       tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+define_bool CONFIG_BINFMT_AOUT n
+define_bool CONFIG_BINFMT_ELF y
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
-       bool 'Networking support' CONFIG_NET
+bool 'Networking support' CONFIG_NET
 
-       if [ "$CONFIG_PCI" = "y" ]; then
-           source drivers/pci/Config.in
-       fi
+if [ "$CONFIG_PCI" = "y" ]; then
+    source drivers/pci/Config.in
+fi
 
-       bool 'System V IPC' CONFIG_SYSVIPC
-       bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
-       bool 'Sysctl support' CONFIG_SYSCTL
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'Sysctl support' CONFIG_SYSCTL
 
-        source drivers/parport/Config.in
+source drivers/parport/Config.in
 
-       if [ "$CONFIG_DECSTATION" = "y" ]; then
-            bool 'TURBOchannel support' CONFIG_TC
-#           if [ "$CONFIG_TC" = "y" ]; then
-#              bool ' Access.Bus support' CONFIG_ACCESSBUS
-#           fi
-       fi
+if [ "$CONFIG_DECSTATION" = "y" ]; then
+    bool 'TURBOchannel support' CONFIG_TC
+#    if [ "$CONFIG_TC" = "y" ]; then
+#      bool ' Access.Bus support' CONFIG_ACCESSBUS
+#    fi
+fi
 endmenu
 
 if [ "$CONFIG_ISA" = "y" ]; then
@@ -196,24 +195,24 @@ fi
 
 if [ "$CONFIG_DECSTATION" != "y" -a \
      "$CONFIG_SGI_IP22" != "y" ]; then
-    source drivers/telephony/Config.in
+   source drivers/telephony/Config.in
 fi
 
 if [ "$CONFIG_SGI_IP22" != "y" -a \
      "$CONFIG_DECSTATION" != "y" ]; then
 
-    mainmenu_option next_comment
-    comment 'ATA/IDE/MFM/RLL support'
+   mainmenu_option next_comment
+   comment 'ATA/IDE/MFM/RLL support'
     
-    tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+   tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
     
-    if [ "$CONFIG_IDE" != "n" ]; then
+   if [ "$CONFIG_IDE" != "n" ]; then
       source drivers/ide/Config.in
-    else
+   else
       define_bool CONFIG_BLK_DEV_IDE_MODES n
       define_bool CONFIG_BLK_DEV_HD n
-    fi
-    endmenu
+   fi
+   endmenu
 fi
 
 mainmenu_option next_comment
@@ -228,7 +227,7 @@ endmenu
 
 if [ "$CONFIG_DECSTATION" != "y" -a \
      "$CONFIG_SGI_IP22" != "y" ]; then
-    source drivers/i2o/Config.in
+   source drivers/i2o/Config.in
 fi
 
 if [ "$CONFIG_NET" = "y" ]; then
@@ -336,7 +335,7 @@ if [ "$CONFIG_SGI_IP22" = "y" ]; then
       if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then
         define_bool CONFIG_DUMMY_CONSOLE y
       else
-         define_bool CONFIG_FONT_8x16 y
+        define_bool CONFIG_FONT_8x16 y
       fi
       bool 'SGI PROM Console Support' CONFIG_SGI_PROM_CONSOLE
    fi
index c186035e5c2d0dfecc938086977a71c04b8583b3..61436603db42e1a39a0482a4cdcd3c11fc69142d 100644 (file)
@@ -28,6 +28,13 @@ CONFIG_SGI=y
 # CONFIG_ISA is not set
 # CONFIG_PCI is not set
 
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
 #
 # CPU selection
 #
@@ -63,9 +70,6 @@ CONFIG_SYSCTL=y
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
 # CONFIG_PCMCIA is not set
 
 #
index 9f632f279ab90551f483e09538fbbe751b20e8bf..bfef9e3a019d0fd6ec0478bbbf954a3494d9db99 100644 (file)
@@ -30,6 +30,13 @@ CONFIG_COBALT_SERIAL=y
 CONFIG_PCI=y
 # CONFIG_ISA is not set
 
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
 #
 # CPU selection
 #
@@ -64,9 +71,6 @@ CONFIG_SYSCTL=y
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
 # CONFIG_PCMCIA is not set
 
 #
@@ -444,7 +448,6 @@ CONFIG_RTC=y
 #
 # CONFIG_FTAPE is not set
 # CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
 # CONFIG_AGP is not set
 
 #
@@ -522,6 +525,7 @@ CONFIG_NLS=y
 #
 # Native Language Support
 #
+CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
 CONFIG_NLS_CODEPAGE_737=m
 CONFIG_NLS_CODEPAGE_775=m
@@ -538,6 +542,10 @@ CONFIG_NLS_CODEPAGE_865=m
 CONFIG_NLS_CODEPAGE_866=m
 CONFIG_NLS_CODEPAGE_869=m
 CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_950=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_ISO8859_2=m
 CONFIG_NLS_ISO8859_3=m
@@ -550,6 +558,7 @@ CONFIG_NLS_ISO8859_9=m
 # CONFIG_NLS_ISO8859_14 is not set
 # CONFIG_NLS_ISO8859_15 is not set
 CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_UTF8=m
 
 #
 # Sound
index 32a880b610619fde275a048d20bfaef9d57f54f2..d7bba78d17187508865f0bcd6c15120730d4e733 100644 (file)
@@ -25,6 +25,13 @@ CONFIG_DECSTATION=y
 # CONFIG_ISA is not set
 # CONFIG_PCI is not set
 
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
 #
 # CPU selection
 #
@@ -58,9 +65,6 @@ CONFIG_SYSCTL=y
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
 CONFIG_TC=y
 # CONFIG_PCMCIA is not set
 
index c186035e5c2d0dfecc938086977a71c04b8583b3..61436603db42e1a39a0482a4cdcd3c11fc69142d 100644 (file)
@@ -28,6 +28,13 @@ CONFIG_SGI=y
 # CONFIG_ISA is not set
 # CONFIG_PCI is not set
 
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
 #
 # CPU selection
 #
@@ -63,9 +70,6 @@ CONFIG_SYSCTL=y
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
 # CONFIG_PCMCIA is not set
 
 #
index 2ae1b11c38de051c1401b84b7917d82c0d059b47..e45b978b4af69b79bf7750da1f8916fcc3c5c282 100644 (file)
@@ -25,6 +25,11 @@ CONFIG_ORION=y
 # CONFIG_ISA is not set
 # CONFIG_PCI is not set
 
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
 #
 # CPU selection
 #
@@ -60,7 +65,6 @@ CONFIG_NET=y
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-# CONFIG_MODULES is not set
 # CONFIG_PCMCIA is not set
 
 #
@@ -199,7 +203,6 @@ CONFIG_BLK_DEV_INITRD=y
 #
 # CONFIG_FTAPE is not set
 # CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
 # CONFIG_AGP is not set
 
 #
index 4166d9a1f27cd38fa6d999cf2450e0412937738a..f67154e911d708965939470812aa6d6ee992c2db 100644 (file)
@@ -27,6 +27,13 @@ CONFIG_PCI=y
 CONFIG_ISA=y
 CONFIG_PC_KEYB=y
 
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
 #
 # CPU selection
 #
@@ -61,9 +68,6 @@ CONFIG_SYSCTL=y
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
 
 #
 # Plug and Play configuration
@@ -215,7 +219,7 @@ CONFIG_VT_CONSOLE=y
 # CONFIG_WATCHDOG is not set
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
+CONFIG_RTC=y
 
 #
 # Video For Linux
@@ -230,7 +234,6 @@ CONFIG_VT_CONSOLE=y
 #
 # CONFIG_FTAPE is not set
 # CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
 # CONFIG_AGP is not set
 
 #
index 0135a6c62a122539ddb39369a07fd2eda22514a8..ddf69a964c508a162c1ea6fdf3bf63ca5de6fdc5 100644 (file)
@@ -1,10 +1,9 @@
-/* $Id: scall_o32.S,v 1.10 2000/02/23 00:41:00 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1997, 1998 by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle
  */
 #include <asm/asm.h>
 #include <linux/errno.h>
@@ -16,7 +15,7 @@
 #include <asm/unistd.h>
 
 /* This duplicates the definition from <linux/sched.h> */
-#define PF_TRACESYS    0x00000020      /* tracing system calls */
+#define PT_TRACESYS    0x00000002      /* tracing system calls */
 
 /* This duplicates the definition from <asm/signal.h> */
 #define SIGILL         4               /* Illegal instruction (ANSI).  */
@@ -50,8 +49,8 @@ NESTED(handle_sys, PT_SIZE, sp)
 
 stack_done:
         sw      a3, PT_R26(sp)          # save for syscall restart
-       lw      t0, TASK_FLAGS($28)     # syscall tracing enabled?
-       andi    t0, PF_TRACESYS
+       lw      t0, TASK_PTRACE($28)    # syscall tracing enabled?
+       andi    t0, PT_TRACESYS
        bnez    t0, trace_a_syscall
 
        jalr    t2                      # Do The Real Thing (TM)
index d76b5f14196ca51e19596a28edc9a39df47eea16..631d6f002520068086f15cf0b2323e905be50c0e 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: andes.c,v 1.10 2000/02/13 20:52:05 harald Exp $
- *
+/*
  * andes.c: MMU and cache operations for the R10000 (ANDES).
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
index dcf1e8a2d21de02adce3395775c17da9949fb17e..690e3698f694f7d6ab17dd6a029e1eecce049632 100644 (file)
@@ -6,8 +6,6 @@
  * with a lot of changes to make this thing work for R3000s
  * Copyright (C) 1998, 2000 Harald Koerfgen
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- *
- * $Id: r2300.c,v 1.16 2000/03/13 10:33:05 raiko Exp $
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -294,7 +292,7 @@ static inline void r3k_flush_cache_all(void)
  
 static void r3k_flush_cache_mm(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
@@ -309,7 +307,7 @@ static void r3k_flush_cache_range(struct mm_struct *mm,
 {
        struct vm_area_struct *vma;
 
-       if(mm->context == 0) 
+       if (mm->context == 0) 
                return;
 
        start &= PAGE_MASK;
@@ -317,15 +315,15 @@ static void r3k_flush_cache_range(struct mm_struct *mm,
        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
        vma = find_vma(mm, start);
-       if(vma) {
-               if(mm->context != current->mm->context) {
+       if (vma) {
+               if (mm->context != current->active_mm->context) {
                        flush_cache_all();
                } else {
                        unsigned long flags, physpage;
 
                        save_and_cli(flags);
-                       while(start < end) {
-                               if((physpage = get_phys_page(start, mm)))
+                       while (start < end) {
+                               if ((physpage = get_phys_page(start, mm)))
                                        r3k_flush_icache_range(physpage, PAGE_SIZE);
                
                                start += PAGE_SIZE;
@@ -340,7 +338,7 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma,
 {
        struct mm_struct *mm = vma->vm_mm;
 
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -349,7 +347,7 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma,
        if (vma->vm_flags & VM_EXEC) {
                unsigned long physpage;
 
-               if((physpage = get_phys_page(page, vma->vm_mm)))
+               if ((physpage = get_phys_page(page, vma->vm_mm)))
                        r3k_flush_icache_range(physpage, PAGE_SIZE);
 
        }
@@ -416,7 +414,7 @@ void flush_tlb_all(void)
 
 void flush_tlb_mm(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
                unsigned long flags;
 
 #ifdef DEBUG_TLB
@@ -542,7 +540,13 @@ void update_mmu_cache(struct vm_area_struct * vma,
        pte_t *ptep;
        int idx, pid;
 
-       pid = (get_entryhi() & 0xfc0);
+       /*
+        * Handle debugger faulting in for debugee.
+        */
+       if (current->active_mm != vma->vm_mm)
+               return;
+
+       pid = get_entryhi() & 0xfc0;
 
 #ifdef DEBUG_TLB
        if((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) {
index 8fc356d9ee521a387961a407ccc8c1f6e7e1401e..2796766161e87f0ba72ec61de347265d83bead36 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: r4xx0.c,v 1.29 2000/02/24 00:12:40 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -7,7 +6,7 @@
  * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
  *
  * To do:
  *
@@ -996,7 +995,7 @@ r4k_flush_cache_range_s16d16i16(struct mm_struct *mm,
        struct vm_area_struct *vma;
        unsigned long flags;
 
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
        start &= PAGE_MASK;
@@ -1004,8 +1003,8 @@ r4k_flush_cache_range_s16d16i16(struct mm_struct *mm,
        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
        vma = find_vma(mm, start);
-       if(vma) {
-               if(mm->context != current->mm->context) {
+       if (vma) {
+               if (mm->context != current->active_mm->context) {
                        r4k_flush_cache_all_s16d16i16();
                } else {
                        pgd_t *pgd;
@@ -1037,7 +1036,7 @@ r4k_flush_cache_range_s32d16i16(struct mm_struct *mm,
        struct vm_area_struct *vma;
        unsigned long flags;
 
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
        start &= PAGE_MASK;
@@ -1045,8 +1044,8 @@ r4k_flush_cache_range_s32d16i16(struct mm_struct *mm,
        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
        vma = find_vma(mm, start);
-       if(vma) {
-               if(mm->context != current->mm->context) {
+       if (vma) {
+               if (mm->context != current->active_mm->context) {
                        r4k_flush_cache_all_s32d16i16();
                } else {
                        pgd_t *pgd;
@@ -1077,7 +1076,7 @@ static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm,
        struct vm_area_struct *vma;
        unsigned long flags;
 
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
        start &= PAGE_MASK;
@@ -1086,7 +1085,7 @@ static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm,
 #endif
        vma = find_vma(mm, start);
        if(vma) {
-               if(mm->context != current->mm->context) {
+               if (mm->context != current->active_mm->context) {
                        r4k_flush_cache_all_s64d16i16();
                } else {
                        pgd_t *pgd;
@@ -1117,7 +1116,7 @@ static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm,
        struct vm_area_struct *vma;
        unsigned long flags;
 
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
        start &= PAGE_MASK;
@@ -1125,8 +1124,8 @@ static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm,
        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
        vma = find_vma(mm, start);
-       if(vma) {
-               if(mm->context != current->mm->context) {
+       if (vma) {
+               if (mm->context != current->active_mm->context) {
                        r4k_flush_cache_all_s128d16i16();
                } else {
                        pgd_t *pgd;
@@ -1157,7 +1156,7 @@ static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm,
        struct vm_area_struct *vma;
        unsigned long flags;
 
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
        start &= PAGE_MASK;
@@ -1165,8 +1164,8 @@ static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm,
        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
        vma = find_vma(mm, start);
-       if(vma) {
-               if(mm->context != current->mm->context) {
+       if (vma) {
+               if (mm->context != current->active_mm->context) {
                        r4k_flush_cache_all_s32d32i32();
                } else {
                        pgd_t *pgd;
@@ -1197,7 +1196,7 @@ static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm,
        struct vm_area_struct *vma;
        unsigned long flags;
 
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
        start &= PAGE_MASK;
@@ -1205,8 +1204,8 @@ static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm,
        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
        vma = find_vma(mm, start);
-       if(vma) {
-               if(mm->context != current->mm->context) {
+       if (vma) {
+               if (mm->context != current->active_mm->context) {
                        r4k_flush_cache_all_s64d32i32();
                } else {
                        pgd_t *pgd;
@@ -1237,7 +1236,7 @@ static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm,
        struct vm_area_struct *vma;
        unsigned long flags;
 
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
        start &= PAGE_MASK;
@@ -1245,8 +1244,8 @@ static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm,
        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
 #endif
        vma = find_vma(mm, start);
-       if(vma) {
-               if(mm->context != current->mm->context) {
+       if (vma) {
+               if (mm->context != current->active_mm->context) {
                        r4k_flush_cache_all_s128d32i32();
                } else {
                        pgd_t *pgd;
@@ -1274,7 +1273,7 @@ static void r4k_flush_cache_range_d16i16(struct mm_struct *mm,
                                         unsigned long start,
                                         unsigned long end)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
                unsigned long flags;
 
 #ifdef DEBUG_CACHE
@@ -1290,7 +1289,7 @@ static void r4k_flush_cache_range_d32i32(struct mm_struct *mm,
                                         unsigned long start,
                                         unsigned long end)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
                unsigned long flags;
 
 #ifdef DEBUG_CACHE
@@ -1309,7 +1308,7 @@ static void r4k_flush_cache_range_d32i32(struct mm_struct *mm,
  */
 static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1319,7 +1318,7 @@ static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm)
 
 static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1329,7 +1328,7 @@ static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm)
 
 static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1339,7 +1338,7 @@ static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm)
 
 static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1349,7 +1348,7 @@ static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm)
 
 static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1359,7 +1358,7 @@ static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm)
 
 static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1369,7 +1368,7 @@ static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm)
 
 static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1379,7 +1378,7 @@ static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm)
 
 static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1389,7 +1388,7 @@ static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm)
 
 static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
 #ifdef DEBUG_CACHE
                printk("cmm[%d]", (int)mm->context);
 #endif
@@ -1411,7 +1410,7 @@ static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1427,7 +1426,7 @@ static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma,
         * If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_VALID))
+       if (!(pte_val(*ptep) & _PAGE_VALID))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1436,7 +1435,7 @@ static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if(mm->context != current->mm->context) {
+       if (mm->context != current->active_mm->context) {
                /* Do indexed flush, too much work to get the (possible)
                 * tlb refills to work correctly.
                 */
@@ -1465,7 +1464,7 @@ static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1480,7 +1479,7 @@ static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
        /* If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_VALID))
+       if (!(pte_val(*ptep) & _PAGE_VALID))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1489,7 +1488,7 @@ static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if(mm->context != current->mm->context) {
+       if (mm->context != current->active_mm->context) {
                /* Do indexed flush, too much work to get the (possible)
                 * tlb refills to work correctly.
                 */
@@ -1518,7 +1517,7 @@ static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1533,7 +1532,7 @@ static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
        /* If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_VALID))
+       if (!(pte_val(*ptep) & _PAGE_VALID))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1543,7 +1542,7 @@ static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if(mm->context != current->mm->context) {
+       if (mm->context != current->active_mm->context) {
                /* Do indexed flush, too much work to get the (possible)
                 * tlb refills to work correctly.
                 */
@@ -1572,7 +1571,7 @@ static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1588,7 +1587,7 @@ static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
         * If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_VALID))
+       if (!(pte_val(*ptep) & _PAGE_VALID))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1597,7 +1596,7 @@ static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if(mm->context != current->mm->context) {
+       if (mm->context != current->active_mm->context) {
                /*
                 * Do indexed flush, too much work to get the (possible)
                 * tlb refills to work correctly.
@@ -1627,7 +1626,7 @@ static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1643,7 +1642,7 @@ static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
         * If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_VALID))
+       if (!(pte_val(*ptep) & _PAGE_VALID))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1653,7 +1652,7 @@ static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if(mm->context != current->mm->context) {
+       if (mm->context != current->active_mm->context) {
                /*
                 * Do indexed flush, too much work to get the (possible)
                 * tlb refills to work correctly.
@@ -1683,7 +1682,7 @@ static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1699,7 +1698,7 @@ static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
         * If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_VALID))
+       if (!(pte_val(*ptep) & _PAGE_VALID))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1709,7 +1708,7 @@ static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if(mm->context != current->mm->context) {
+       if (mm->context != current->active_mm->context) {
                /*
                 * Do indexed flush, too much work to get the (possible)
                 * tlb refills to work correctly.
@@ -1754,7 +1753,7 @@ static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
        /* If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_VALID))
+       if (!(pte_val(*ptep) & _PAGE_VALID))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1764,7 +1763,7 @@ static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if(mm->context != current->mm->context) {
+       if (mm->context != current->active_mm->context) {
                /* Do indexed flush, too much work to get the (possible)
                 * tlb refills to work correctly.
                 */
@@ -1793,7 +1792,7 @@ static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1808,7 +1807,7 @@ static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
        /* If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_VALID))
+       if (!(pte_val(*ptep) & _PAGE_VALID))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1818,7 +1817,7 @@ static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if(mm == current->mm) {
+       if (mm == current->active_mm) {
                blast_dcache16_page(page);
                if(text)
                        blast_icache16_page(page);
@@ -1849,7 +1848,7 @@ static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1865,7 +1864,7 @@ static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
         * If the page isn't marked valid, the page cannot possibly be
         * in the cache.
         */
-       if(!(pte_val(*ptep) & _PAGE_PRESENT))
+       if (!(pte_val(*ptep) & _PAGE_PRESENT))
                goto out;
 
        text = (vma->vm_flags & VM_EXEC);
@@ -1875,7 +1874,7 @@ static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+       if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
                blast_dcache32_page(page);
                if(text)
                        blast_icache32_page(page);
@@ -1907,7 +1906,7 @@ static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
         * If ownes no valid ASID yet, cannot possibly have gotten
         * this page into the cache.
         */
-       if(mm->context == 0)
+       if (mm->context == 0)
                return;
 
 #ifdef DEBUG_CACHE
@@ -1933,7 +1932,7 @@ static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
         * for every cache flush operation.  So we do indexed flushes
         * in that case, which doesn't overly flush the cache too much.
         */
-       if((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+       if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
                blast_dcache32_page(page);
                if(text)
                        blast_icache32_page(page);
@@ -2263,7 +2262,7 @@ void flush_tlb_all(void)
 
 void flush_tlb_mm(struct mm_struct *mm)
 {
-       if(mm->context != 0) {
+       if (mm->context != 0) {
                unsigned long flags;
 
 #ifdef DEBUG_TLB
@@ -2271,7 +2270,7 @@ void flush_tlb_mm(struct mm_struct *mm)
 #endif
                save_and_cli(flags);
                get_new_mmu_context(mm, asid_cache);
-               if(mm == current->mm)
+               if (mm == current->active_mm)
                        set_entryhi(mm->context & 0xff);
                restore_flags(flags);
        }
@@ -2319,7 +2318,7 @@ void flush_tlb_range(struct mm_struct *mm, unsigned long start,
                        set_entryhi(oldpid);
                } else {
                        get_new_mmu_context(mm, asid_cache);
-                       if(mm == current->mm)
+                       if (mm == current->active_mm)
                                set_entryhi(mm->context & 0xff);
                }
                restore_flags(flags);
@@ -2328,7 +2327,7 @@ void flush_tlb_range(struct mm_struct *mm, unsigned long start,
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
-       if(vma->vm_mm->context != 0) {
+       if (vma->vm_mm->context != 0) {
                unsigned long flags;
                int oldpid, newpid, idx;
 
@@ -2400,6 +2399,12 @@ void update_mmu_cache(struct vm_area_struct * vma,
        pte_t *ptep;
        int idx, pid;
 
+       /*
+        * Handle debugger faulting in for debugee.
+        */
+       if (current->active_mm != vma->vm_mm)
+               return;
+
        pid = get_entryhi() & 0xff;
 
 #ifdef DEBUG_TLB
index 0d88810581bf74b315bc4e8ab2d5ab0643e23337..1c6d9e2fa5d43ef0a4a9448e7e914875c709a2d4 100644 (file)
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #include <asm/cpu.h>
+#include <linux/sched.h>
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
+#include <asm/bootinfo.h>
 #include <asm/mc146818rtc.h>
 
 char arcs_cmdline[CL_SIZE] = {0, };
index c247d6b528aea756d64c011b553af1bc455e453e..8d4cc54f0ff6555ebd5fb2816790ad834d10ea15 100644 (file)
 #include <asm/stackframe.h>
 #include <asm/system.h>
 #include <asm/cpu.h>
+#include <linux/sched.h>
 #include <linux/bootmem.h>
 #include <asm/addrspace.h>
+#include <asm/bootinfo.h>
 #include <asm/mc146818rtc.h>
 #include <asm/orion.h>
 
index afd52c3439ea629029ddcd46177e9205dcfb2673..f511e98de95d5e87516308e2ac29e44d34d459cd 100644 (file)
@@ -180,7 +180,7 @@ void sgi_time_init (struct irqaction *irq) {
         */
         struct sgi_ioc_timers *p;
         volatile unsigned char *tcwp, *tc2p;
-       unsigned long r4k_ticks[3];
+       unsigned long r4k_ticks[3] = { 0, 0, 0 };
        unsigned long r4k_next;
 
         /* Figure out the r4k offset, the algorithm is very simple
@@ -198,15 +198,16 @@ void sgi_time_init (struct irqaction *irq) {
         tc2p = &p->tcnt2;
 
         printk("Calibrating system timer... ");
-        dosample(tcwp, tc2p);                   /* First sample. */
-        dosample(tcwp, tc2p);                   /* Eat one.     */
-        r4k_ticks[0] = dosample(tcwp, tc2p);      /* Second sample. */
-       dosample(tcwp, tc2p);                   /* Eat another. */
-       r4k_ticks[1] += dosample (tcwp, tc2p);  /* Third sample. */
+        dosample(tcwp, tc2p);                   /* Prime cache. */
+        dosample(tcwp, tc2p);                   /* Prime cache. */
+       /* Zero is NOT an option. */
+       while (!r4k_ticks[0])
+               r4k_ticks[0] = dosample (tcwp, tc2p);
+       while (!r4k_ticks[1])
+               r4k_ticks[1] = dosample (tcwp, tc2p);
 
        if (r4k_ticks[0] != r4k_ticks[1]) {
                printk ("warning: timer counts differ, retrying...");
-               dosample (tcwp, tc2p);
                r4k_ticks[2] = dosample (tcwp, tc2p);
                if (r4k_ticks[2] == r4k_ticks[0] 
                    || r4k_ticks[2] == r4k_ticks[1])
index 2e2af434e093f9d469ac896ed3a3f4dc53557686..e691b6d71adb608ad2e0fe196eb2149db23816af 100644 (file)
@@ -80,6 +80,7 @@ void output_task_defines(void)
        offset("#define TASK_FLAGS         ", struct task_struct, flags);
        offset("#define TASK_SIGPENDING    ", struct task_struct, sigpending);
        offset("#define TASK_NEED_RESCHED  ", struct task_struct, need_resched);
+       offset("#define TASK_PTRACE        ", struct task_struct, ptrace);
        offset("#define TASK_COUNTER       ", struct task_struct, counter);
        offset("#define TASK_NICE          ", struct task_struct, nice);
        offset("#define TASK_MM            ", struct task_struct, mm);
index b37fabe6980f750f19340f5c4908323db50047e6..77609a84aa339bb5260a153144f4c8673b0599db 100644 (file)
@@ -1,4 +1,3 @@
-# $Id: Makefile,v 1.5 2000/01/21 22:34:03 ralf Exp $
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
@@ -33,7 +32,7 @@ endif
 # machines may also.  Since BFD is incredibly buggy with respect to
 # crossformat linking we rely on the elf2ecoff tool for format conversion.
 #
-CFLAGS         += -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe
+CFLAGS         += -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe
 LINKFLAGS      += -G 0 -static # -N
 MODFLAGS       += -mlong-calls
 
index 162fa671ec2259f62c27f890688c597f8ca78083..70e375fed2e3707669e04293eec33d4dee5c67ae 100644 (file)
@@ -10,15 +10,6 @@ comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
 endmenu
 
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
-   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
-   bool '  Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
 mainmenu_option next_comment
 comment 'Machine selection'
 bool 'Support for SGI IP22' CONFIG_SGI_IP22
@@ -118,6 +109,14 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
 endmenu
 
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+   bool 'Kernel module loader' CONFIG_KMOD
+fi
+
 source drivers/pci/Config.in
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
index 3af288cffa0dc45fb69f2c8995883098fa9f2807..aa9fdef16c72bbe9b2e7a756b403c4c979d16464 100644 (file)
@@ -327,7 +327,7 @@ CONFIG_SERIAL_CONSOLE=y
 #
 # CONFIG_FTAPE is not set
 # CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
 
 #
 # File systems
index a40dc4eb0cc8413a6aa18f9416f7b4ddb5b6341b..6c2835d21898af10f9fdd09c365452ce9c29278b 100644 (file)
@@ -246,7 +246,7 @@ CONFIG_VT_CONSOLE=y
 #
 # CONFIG_FTAPE is not set
 # CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
 
 #
 # File systems
index 3af288cffa0dc45fb69f2c8995883098fa9f2807..aa9fdef16c72bbe9b2e7a756b403c4c979d16464 100644 (file)
@@ -327,7 +327,7 @@ CONFIG_SERIAL_CONSOLE=y
 #
 # CONFIG_FTAPE is not set
 # CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
 
 #
 # File systems
index 6d59c35d2eb643bd74b269a5ef1f2033ef5ee65a..fd68241f4a0e07d0f2d9e819e565ec729407c7e9 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: binfmt_elf32.c,v 1.1 1999/11/24 06:56:13 ralf Exp $
- *
+/*
  * Support for 32-bit Linux/MIPS ELF binaries.
  *
  * Copyright (C) 1999 Ralf Baechle
@@ -28,7 +27,8 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 typedef double elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
-#define elf_check_arch(x)      ((x)->e_machine == EM_MIPS || (x)->e_machine == EM_MIPS_RS4_BE)
+#define elf_check_arch(x)      \
+       ((x)->e_machine == EM_MIPS || (x)->e_machine == EM_MIPS_RS4_BE)
 
 #define TASK32_SIZE            0x80000000UL
 #undef ELF_ET_DYN_BASE
index 70746da227b4917ffdb5b4583f1393172235e25e..8d6bc8c45e9bdd449349b59813b5bfb2556dcce3 100644 (file)
 #include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/filter.h>
+#include <linux/shm.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
 
 #include <asm/uaccess.h>
 #include <asm/mman.h>
+#include <asm/ipc.h>
 
 
 #define A(__x) ((unsigned long)(__x))
@@ -359,16 +363,18 @@ static int
 nargs(unsigned int arg, char **ap)
 {
        char *ptr;
-       int n;
+       int n, ret;
 
        n = 0;
        do {
                /* egcs is stupid */
                if (!access_ok(VERIFY_READ, arg, sizeof (unsigned int)))
                        return -EFAULT;
-               __get_user((long)ptr,(int *)A(arg));
-               if (ap)
-                       *ap++ = ptr;
+               if (IS_ERR(ret = __get_user((long)ptr,(int *)A(arg))))
+                       return ret;
+               if (ap)         /* no access_ok needed, we allocated */
+                       if (IS_ERR(ret = __put_user(ptr, ap++)))
+                               return ret;
                arg += sizeof(unsigned int);
                n++;
        } while (ptr);
@@ -387,7 +393,11 @@ sys32_execve(abi64_no_regargs, struct pt_regs regs)
        char * filename;
 
        na = nargs(argv, NULL);
+       if (IS_ERR(na))
+               return(na);
        ne = nargs(envp, NULL);
+       if (IS_ERR(ne))
+               return(ne);
        len = (na + ne + 2) * sizeof(*av);
        /*
         *  kmalloc won't work because the `sys_exec' code will attempt
@@ -403,20 +413,25 @@ sys32_execve(abi64_no_regargs, struct pt_regs regs)
        up(&current->mm->mmap_sem);
 
        if (IS_ERR(av))
-               return((long) av);
+               return (long) av;
        ae = av + na + 1;
-       av[na] = (char *)0;
-       ae[ne] = (char *)0;
-       (void)nargs(argv, av);
-       (void)nargs(envp, ae);
+       if (IS_ERR(r = __put_user(0, (av + na))))
+               goto out;
+       if (IS_ERR(r = __put_user(0, (ae + ne))))
+               goto out;
+       if (IS_ERR(r = nargs(argv, av)))
+               goto out;
+       if (IS_ERR(r = nargs(envp, ae)))
+               goto out;
        filename = getname((char *) (long)regs.regs[4]);
        r = PTR_ERR(filename);
        if (IS_ERR(filename))
-               return(r);
+               goto out;
 
        r = do_execve(filename, av, ae, &regs);
        putname(filename);
        if (IS_ERR(r))
+out:
                sys_munmap((unsigned long)av, len);
        return(r);
 }
@@ -1337,3 +1352,413 @@ asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg
                return sys_fcntl(fd, cmd, (unsigned long)arg);
        }
 }
+
+struct msgbuf32 { s32 mtype; char mtext[1]; };
+
+struct ipc_perm32
+{
+       key_t             key;
+        __kernel_uid_t32  uid;
+        __kernel_gid_t32  gid;
+        __kernel_uid_t32  cuid;
+        __kernel_gid_t32  cgid;
+        __kernel_mode_t32 mode;
+        unsigned short  seq;
+};
+
+struct semid_ds32 {
+        struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
+        __kernel_time_t32 sem_otime;              /* last semop time */
+        __kernel_time_t32 sem_ctime;              /* last change time */
+        u32 sem_base;              /* ptr to first semaphore in array */
+        u32 sem_pending;          /* pending operations to be processed */
+        u32 sem_pending_last;    /* last pending operation */
+        u32 undo;                  /* undo requests on this array */
+        unsigned short  sem_nsems;              /* no. of semaphores in array */
+};
+
+struct msqid_ds32
+{
+        struct ipc_perm32 msg_perm;
+        u32 msg_first;
+        u32 msg_last;
+        __kernel_time_t32 msg_stime;
+        __kernel_time_t32 msg_rtime;
+        __kernel_time_t32 msg_ctime;
+        u32 wwait;
+        u32 rwait;
+        unsigned short msg_cbytes;
+        unsigned short msg_qnum;  
+        unsigned short msg_qbytes;
+        __kernel_ipc_pid_t32 msg_lspid;
+        __kernel_ipc_pid_t32 msg_lrpid;
+};
+
+struct shmid_ds32 {
+        struct ipc_perm32       shm_perm;
+        int                     shm_segsz;
+        __kernel_time_t32       shm_atime;
+        __kernel_time_t32       shm_dtime;
+        __kernel_time_t32       shm_ctime;
+        __kernel_ipc_pid_t32    shm_cpid; 
+        __kernel_ipc_pid_t32    shm_lpid; 
+        unsigned short          shm_nattch;
+};
+
+#define IPCOP_MASK(__x)        (1UL << (__x))
+
+static int
+do_sys32_semctl(int first, int second, int third, void *uptr)
+{
+       union semun fourth;
+       u32 pad;
+       int err, err2;
+       struct semid64_ds s;
+       struct semid_ds32 *usp;
+       mm_segment_t old_fs;
+
+       if (!uptr)
+               return -EINVAL;
+       err = -EFAULT;
+       if (get_user (pad, (u32 *)uptr))
+               return err;
+       if(third == SETVAL)
+               fourth.val = (int)pad;
+       else
+               fourth.__pad = (void *)A(pad);
+       switch (third) {
+
+       case IPC_INFO:
+       case IPC_RMID:
+       case IPC_SET:
+       case SEM_INFO:
+       case GETVAL:
+       case GETPID:
+       case GETNCNT:
+       case GETZCNT:
+       case GETALL:
+       case SETVAL:
+       case SETALL:
+               err = sys_semctl (first, second, third, fourth);
+               break;
+
+       case IPC_STAT:
+       case SEM_STAT:
+               usp = (struct semid_ds32 *)A(pad);
+               fourth.__pad = &s;
+               old_fs = get_fs ();
+               set_fs (KERNEL_DS);
+               err = sys_semctl (first, second, third, fourth);
+               set_fs (old_fs);
+               err2 = put_user(s.sem_perm.key, &usp->sem_perm.key);
+               err2 |= __put_user(s.sem_perm.uid, &usp->sem_perm.uid);
+               err2 |= __put_user(s.sem_perm.gid, &usp->sem_perm.gid);
+               err2 |= __put_user(s.sem_perm.cuid,
+                                  &usp->sem_perm.cuid);
+               err2 |= __put_user (s.sem_perm.cgid,
+                                   &usp->sem_perm.cgid);
+               err2 |= __put_user (s.sem_perm.mode,
+                                   &usp->sem_perm.mode);
+               err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
+               err2 |= __put_user (s.sem_otime, &usp->sem_otime);
+               err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
+               err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
+               if (err2)
+                       err = -EFAULT;
+               break;
+
+       }
+
+       return err;
+}
+
+static int
+do_sys32_msgsnd (int first, int second, int third, void *uptr)
+{
+       struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
+                                   + 4, GFP_USER);
+       struct msgbuf32 *up = (struct msgbuf32 *)uptr;
+       mm_segment_t old_fs;
+       int err;
+
+       if (!p)
+               return -ENOMEM;
+       err = get_user (p->mtype, &up->mtype);
+       err |= __copy_from_user (p->mtext, &up->mtext, second);
+       if (err)
+               goto out;
+       old_fs = get_fs ();
+       set_fs (KERNEL_DS);
+       err = sys_msgsnd (first, p, second, third);
+       set_fs (old_fs);
+out:
+       kfree (p);
+       return err;
+}
+
+static int
+do_sys32_msgrcv (int first, int second, int msgtyp, int third,
+                int version, void *uptr)
+{
+       struct msgbuf32 *up;
+       struct msgbuf *p;
+       mm_segment_t old_fs;
+       int err;
+
+       if (!version) {
+               struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
+               struct ipc_kludge ipck;
+
+               err = -EINVAL;
+               if (!uptr)
+                       goto out;
+               err = -EFAULT;
+               if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
+                       goto out;
+               uptr = (void *)A(ipck.msgp);
+               msgtyp = ipck.msgtyp;
+       }
+       err = -ENOMEM;
+       p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
+       if (!p)
+               goto out;
+       old_fs = get_fs ();
+       set_fs (KERNEL_DS);
+       err = sys_msgrcv (first, p, second + 4, msgtyp, third);
+       set_fs (old_fs);
+       if (err < 0)
+               goto free_then_out;
+       up = (struct msgbuf32 *)uptr;
+       if (put_user (p->mtype, &up->mtype) ||
+           __copy_to_user (&up->mtext, p->mtext, err))
+               err = -EFAULT;
+free_then_out:
+       kfree (p);
+out:
+       return err;
+}
+
+static int
+do_sys32_msgctl (int first, int second, void *uptr)
+{
+       int err = -EINVAL, err2;
+       struct msqid_ds m;
+       struct msqid64_ds m64;
+       struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
+       mm_segment_t old_fs;
+
+       switch (second) {
+
+       case IPC_INFO:
+       case IPC_RMID:
+       case MSG_INFO:
+               err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
+               break;
+
+       case IPC_SET:
+               err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
+               err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
+               err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
+               err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
+               if (err)
+                       break;
+               old_fs = get_fs ();
+               set_fs (KERNEL_DS);
+               err = sys_msgctl (first, second, &m);
+               set_fs (old_fs);
+               break;
+
+       case IPC_STAT:
+       case MSG_STAT:
+               old_fs = get_fs ();
+               set_fs (KERNEL_DS);
+               err = sys_msgctl (first, second, (void *) &m64);
+               set_fs (old_fs);
+               err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
+               err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
+               err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid);
+               err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid);
+               err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid);
+               err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode);
+               err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq);
+               err2 |= __put_user(m64.msg_stime, &up->msg_stime);
+               err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);
+               err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);
+               err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);
+               err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);
+               err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);
+               err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);
+               err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);
+               if (err2)
+                       err = -EFAULT;
+               break;
+
+       }
+
+       return err;
+}
+
+static int
+do_sys32_shmat (int first, int second, int third, int version, void *uptr)
+{
+       unsigned long raddr;
+       u32 *uaddr = (u32 *)A((u32)third);
+       int err = -EINVAL;
+
+       if (version == 1)
+               return err;
+       if (version == 1)
+               return err;
+       err = sys_shmat (first, uptr, second, &raddr);
+       if (err)
+               return err;
+       err = put_user (raddr, uaddr);
+       return err;
+}
+
+static int
+do_sys32_shmctl (int first, int second, void *uptr)
+{
+       int err = -EFAULT, err2;
+       struct shmid_ds s;
+       struct shmid64_ds s64;
+       struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
+       mm_segment_t old_fs;
+       struct shm_info32 {
+               int used_ids;
+               u32 shm_tot, shm_rss, shm_swp;
+               u32 swap_attempts, swap_successes;
+       } *uip = (struct shm_info32 *)uptr;
+       struct shm_info si;
+
+       switch (second) {
+
+       case IPC_INFO:
+       case IPC_RMID:
+       case SHM_LOCK:
+       case SHM_UNLOCK:
+               err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
+               break;
+       case IPC_SET:
+               err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
+               err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
+               err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
+               if (err)
+                       break;
+               old_fs = get_fs ();
+               set_fs (KERNEL_DS);
+               err = sys_shmctl (first, second, &s);
+               set_fs (old_fs);
+               break;
+
+       case IPC_STAT:
+       case SHM_STAT:
+               old_fs = get_fs ();
+               set_fs (KERNEL_DS);
+               err = sys_shmctl (first, second, (void *) &s64);
+               set_fs (old_fs);
+               if (err < 0)
+                       break;
+               err2 = put_user (s64.shm_perm.key, &up->shm_perm.key);
+               err2 |= __put_user (s64.shm_perm.uid, &up->shm_perm.uid);
+               err2 |= __put_user (s64.shm_perm.gid, &up->shm_perm.gid);
+               err2 |= __put_user (s64.shm_perm.cuid,
+                                   &up->shm_perm.cuid);
+               err2 |= __put_user (s64.shm_perm.cgid,
+                                   &up->shm_perm.cgid);
+               err2 |= __put_user (s64.shm_perm.mode,
+                                   &up->shm_perm.mode);
+               err2 |= __put_user (s64.shm_perm.seq, &up->shm_perm.seq);
+               err2 |= __put_user (s64.shm_atime, &up->shm_atime);
+               err2 |= __put_user (s64.shm_dtime, &up->shm_dtime);
+               err2 |= __put_user (s64.shm_ctime, &up->shm_ctime);
+               err2 |= __put_user (s64.shm_segsz, &up->shm_segsz);
+               err2 |= __put_user (s64.shm_nattch, &up->shm_nattch);
+               err2 |= __put_user (s64.shm_cpid, &up->shm_cpid);
+               err2 |= __put_user (s64.shm_lpid, &up->shm_lpid);
+               if (err2)
+                       err = -EFAULT;
+               break;
+
+       case SHM_INFO:
+               old_fs = get_fs ();
+               set_fs (KERNEL_DS);
+               err = sys_shmctl (first, second, (void *)&si);
+               set_fs (old_fs);
+               if (err < 0)
+                       break;
+               err2 = put_user (si.used_ids, &uip->used_ids);
+               err2 |= __put_user (si.shm_tot, &uip->shm_tot);
+               err2 |= __put_user (si.shm_rss, &uip->shm_rss);
+               err2 |= __put_user (si.shm_swp, &uip->shm_swp);
+               err2 |= __put_user (si.swap_attempts,
+                                   &uip->swap_attempts);
+               err2 |= __put_user (si.swap_successes,
+                                   &uip->swap_successes);
+               if (err2)
+                       err = -EFAULT;
+               break;
+
+       }
+       return err;
+}
+
+asmlinkage long
+sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
+{
+       int version, err;
+
+       version = call >> 16; /* hack for backward compatibility */
+       call &= 0xffff;
+
+       switch (call) {
+
+       case SEMOP:
+               /* struct sembuf is the same on 32 and 64bit :)) */
+               err = sys_semop (first, (struct sembuf *)A(ptr),
+                                second);
+               break;
+       case SEMGET:
+               err = sys_semget (first, second, third);
+               break;
+       case SEMCTL:
+               err = do_sys32_semctl (first, second, third,
+                                      (void *)A(ptr));
+               break;
+
+       case MSGSND:
+               err = do_sys32_msgsnd (first, second, third,
+                                      (void *)A(ptr));
+               break;
+       case MSGRCV:
+               err = do_sys32_msgrcv (first, second, fifth, third,
+                                      version, (void *)A(ptr));
+               break;
+       case MSGGET:
+               err = sys_msgget ((key_t) first, second);
+               break;
+       case MSGCTL:
+               err = do_sys32_msgctl (first, second, (void *)A(ptr));
+               break;
+
+       case SHMAT:
+               err = do_sys32_shmat (first, second, third,
+                                     version, (void *)A(ptr));
+               break;
+       case SHMDT: 
+               err = sys_shmdt ((char *)A(ptr));
+               break;
+       case SHMGET:
+               err = sys_shmget (first, second, third);
+               break;
+       case SHMCTL:
+               err = do_sys32_shmctl (first, second, (void *)A(ptr));
+               break;
+       default:
+               err = -EINVAL;
+               break;
+       }
+
+       return err;
+}
+
index 284e831b46144d4cdb75e279d7222b3d9ba6e5ec..b384db2af63a1c597f2e9e0129be04322d7d35f2 100644 (file)
@@ -81,7 +81,7 @@ EXPORT_SYMBOL(csum_partial_copy);
  * Functions to control caches.
  */
 EXPORT_SYMBOL(_flush_page_to_ram);
-EXPORT_SYMBOL(_flush_cache_all);
+EXPORT_SYMBOL(_flush_cache_l1);
 #ifndef CONFIG_COHERENT_IO
 EXPORT_SYMBOL(_dma_cache_wback_inv);
 EXPORT_SYMBOL(_dma_cache_inv);
index 6a7a595512e8239881dbac481aaa98e7503654e4..a6ac27f68667ee00faf2da6556cdc4ef26d6e08a 100644 (file)
@@ -1,11 +1,10 @@
-/* $Id: scall_64.S,v 1.7 2000/02/23 00:41:00 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/config.h>
 #include <asm/asm.h>
@@ -17,7 +16,7 @@
 #include <asm/unistd.h>
 
 /* This duplicates the definition from <linux/sched.h> */
-#define PF_TRACESYS    0x00000020      /* tracing system calls */
+#define PT_TRACESYS    0x00000002      /* tracing system calls */
 
 /* This duplicates the definition from <asm/signal.h> */
 #define SIGILL         4               /* Illegal instruction (ANSI).  */
@@ -48,8 +47,8 @@ NESTED(handle_sys64, PT_SIZE, sp)
 
        sd      a3, PT_R26(sp)          # save a3 for syscall restarting
 
-       ld      t0, TASK_FLAGS($28)     # syscall tracing enabled?
-       andi    t0, PF_TRACESYS
+       ld      t0, TASK_PTRACE($28)    # syscall tracing enabled?
+       andi    t0, PT_TRACESYS
        bnez    t0, trace_a_syscall
 
        jalr    t2                      # Do The Real Thing (TM)
index a6f7266eb801813095be03f47a6b4ed01ecadf45..2047c7303de41be513aedc82e17a2793d7e1b1b4 100644 (file)
@@ -20,7 +20,7 @@
 #include <asm/unistd.h>
 
 /* This duplicates the definition from <linux/sched.h> */
-#define PF_TRACESYS    0x00000020      /* tracing system calls */
+#define PT_TRACESYS    0x00000002      /* tracing system calls */
 
 /* This duplicates the definition from <asm/signal.h> */
 #define SIGILL         4               /* Illegal instruction (ANSI).  */
@@ -60,8 +60,8 @@ NESTED(handle_sys, PT_SIZE, sp)
        bgez    t0, stackargs
 
 stack_done:
-       ld      t0, TASK_FLAGS($28)     # syscall tracing enabled?
-       andi    t0, PF_TRACESYS
+       ld      t0, TASK_PTRACE($28)    # syscall tracing enabled?
+       andi    t0, PT_TRACESYS
        bnez    t0, trace_a_syscall
 
        jalr    t2                      # Do The Real Thing (TM)
@@ -318,7 +318,7 @@ illegal_syscall:
        sys     sys32_wait4     4
        sys     sys_swapoff     1                       /* 4115 */
        sys     sys_sysinfo     1
-       sys     sys_ipc         6
+       sys     sys32_ipc               6
        sys     sys_fsync       1
        sys     sys32_sigreturn 0
        sys     sys_clone       0                       /* 4120 */
index e1aedbb10ccb244309c2b9673af8158c340eefb7..c36337564df0679a3c78f34631b4b477e03b788a 100644 (file)
@@ -71,7 +71,6 @@ void __init smp_boot_cpus(void)
        extern void allowboot(void);
 
        init_new_context(current, &init_mm);
-       global_irq_holder = 0;
        current->processor = 0;
        init_idle();
        smp_tune_scheduling();
index 55685248abe150a84ad608d6b1ba797bd1e66b68..1588b95a7623ad5d54ba784848d1c425eef68f7f 100644 (file)
@@ -217,7 +217,7 @@ sys_sysmips(int cmd, long arg1, int arg2, int arg3)
                return 0;
 
        case FLUSH_CACHE:
-               flush_cache_all();
+               flush_cache_l1();
                return 0;
 
        case MIPS_RDNVRAM:
index 885443032915c73088a9f839757f43cd0db32d88..bcbb077606a907cc1e0a735981b46f706ca03b1e 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id: andes.c,v 1.7 2000/03/13 22:43:25 kanoj Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <asm/sgialib.h>
 #include <asm/mmu_context.h>
 
+static int scache_lsz64;
+
 /* CP0 hazard avoidance.  I think we can drop this for the R10000.  */
 #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
                                     "nop; nop; nop; nop; nop; nop;\n\t" \
                                     ".set reorder\n\t")
 
-/* R10000 has no Create_Dirty type cacheops.  */
+/*
+ * This version has been tuned on an Origin.  For other machines the arguments
+ * of the pref instructin may have to be tuned differently.
+ */
 static void andes_clear_page(void * page)
 {
        __asm__ __volatile__(
                ".set\tnoreorder\n\t"
                ".set\tnoat\n\t"
                "daddiu\t$1,%0,%2\n"
-               "1:\tsd\t$0,(%0)\n\t"
+               "1:\tpref 7,512(%0)\n\t"
+               "sd\t$0,(%0)\n\t"
                "sd\t$0,8(%0)\n\t"
                "sd\t$0,16(%0)\n\t"
                "sd\t$0,24(%0)\n\t"
@@ -47,147 +53,78 @@ static void andes_clear_page(void * page)
                :"$1", "memory");
 }
 
+/* R10000 has no Create_Dirty type cacheops.  */
 static void andes_copy_page(void * to, void * from)
 {
-       unsigned long dummy1, dummy2, reg1, reg2;
+       unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4;
 
        __asm__ __volatile__(
                ".set\tnoreorder\n\t"
                ".set\tnoat\n\t"
-               "daddiu\t$1,%0,%6\n"
-               "1:\tld\t%2,(%1)\n\t"
+               "daddiu\t$1,%0,%8\n"
+               "1:\tpref\t0,2*128(%1)\n\t"
+               "pref\t1,2*128(%0)\n\t"
+               "ld\t%2,(%1)\n\t"
                "ld\t%3,8(%1)\n\t"
+               "ld\t%4,16(%1)\n\t"
+               "ld\t%5,24(%1)\n\t"
                "sd\t%2,(%0)\n\t"
                "sd\t%3,8(%0)\n\t"
-               "ld\t%2,16(%1)\n\t"
-               "ld\t%3,24(%1)\n\t"
-               "sd\t%2,16(%0)\n\t"
-               "sd\t%3,24(%0)\n\t"
+               "sd\t%4,16(%0)\n\t"
+               "sd\t%5,24(%0)\n\t"
                "daddiu\t%0,64\n\t"
                "daddiu\t%1,64\n\t"
                "ld\t%2,-32(%1)\n\t"
                "ld\t%3,-24(%1)\n\t"
+               "ld\t%4,-16(%1)\n\t"
+               "ld\t%5,-8(%1)\n\t"
                "sd\t%2,-32(%0)\n\t"
                "sd\t%3,-24(%0)\n\t"
-               "ld\t%2,-16(%1)\n\t"
-               "ld\t%3,-8(%1)\n\t"
-               "sd\t%2,-16(%0)\n\t"
+               "sd\t%4,-16(%0)\n\t"
                "bne\t$1,%0,1b\n\t"
-               " sd\t%3,-8(%0)\n\t"
+               " sd\t%5,-8(%0)\n\t"
                ".set\tat\n\t"
                ".set\treorder"
-               :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+               :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2),
+                "=&r" (reg3), "=&r" (reg4)
                :"0" (to), "1" (from), "I" (PAGE_SIZE));
 }
 
 /* Cache operations.  These are only used with the virtual memory system,
    not for non-coherent I/O so it's ok to ignore the secondary caches.  */
 static void
-andes_flush_cache_all(void)
+andes_flush_cache_l1(void)
 {
        blast_dcache32(); blast_icache64();
 }
 
+/*
+ * This is only used during initialization time. vmalloc() also calls
+ * this, but that will be changed pretty soon.
+ */
 static void
-andes_flush_cache_mm(struct mm_struct *mm)
+andes_flush_cache_l2(void)
 {
-       if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
-#ifdef DEBUG_CACHE
-               printk("cmm[%d]", (int)mm->context);
-#endif
-               andes_flush_cache_all();
+       switch (sc_lsize()) {
+               case 64:
+                       blast_scache64();
+                       break;
+               case 128:
+                       blast_scache128();
+                       break;
+               default:
+                       printk("Unknown L2 line size\n");
+                       while(1);
        }
 }
 
-static void
-andes_flush_cache_range(struct mm_struct *mm, unsigned long start,
-                        unsigned long end)
+void
+andes_flush_icache_page(unsigned long page)
 {
-       if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
-               unsigned long flags;
-
-#ifdef DEBUG_CACHE
-               printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
-#endif
-               save_and_cli(flags);
-               blast_dcache32(); blast_icache64();
-               restore_flags(flags);
-       }
-}
-
-static void
-andes_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
-{
-       struct mm_struct *mm = vma->vm_mm;
-       unsigned long flags;
-       pgd_t *pgdp;
-       pmd_t *pmdp;
-       pte_t *ptep;
-       int text;
-
-       /*
-        * If ownes no valid ASID yet, cannot possibly have gotten
-        * this page into the cache.
-        */
-       if (CPU_CONTEXT(smp_processor_id(), mm) == 0)
-               return;
-
-#ifdef DEBUG_CACHE
-       printk("cpage[%d,%08lx]", (int)mm->context, page);
-#endif
-       save_and_cli(flags);
-       page &= PAGE_MASK;
-       pgdp = pgd_offset(mm, page);
-       pmdp = pmd_offset(pgdp, page);
-       ptep = pte_offset(pmdp, page);
-
-       /*
-        * If the page isn't marked valid, the page cannot possibly be
-        * in the cache.
-        */
-       if(!(pte_val(*ptep) & _PAGE_PRESENT))
-               goto out;
-
-       text = (vma->vm_flags & VM_EXEC);
-       /*
-        * Doing flushes for another ASID than the current one is
-        * too difficult since stupid R4k caches do a TLB translation
-        * for every cache flush operation.  So we do indexed flushes
-        * in that case, which doesn't overly flush the cache too much.
-        */
-       if ((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
-               blast_dcache32_page(page);
-               if(text)
-                       blast_icache64_page(page);
-       } else {
-               /*
-                * Do indexed flush, too much work to get the (possible)
-                * tlb refills to work correctly.
-                */
-               page = (CKSEG0 + (page & (dcache_size - 1)));
-               blast_dcache32_page_indexed(page);
-               if(text)
-                       blast_icache64_page_indexed(page);
-       }
-out:
-       restore_flags(flags);
-}
-
-/* Hoo hum...  will this ever be called for an address that is not in CKSEG0
-   and not cacheable?  */
-static void
-andes_flush_page_to_ram(struct page * page)
-{
-       unsigned long addr = page_address(page) & PAGE_MASK;
-
-       if ((addr >= K0BASE_NONCOH && addr < (0xb0UL << 56))
-           || (addr >= KSEG0 && addr < KSEG1)
-           || (addr >= KSEG2)) {
-#ifdef DEBUG_CACHE
-               printk("cram[%08lx]", addr);
-#endif
-               blast_dcache32_page(addr);
-       }
+       if (scache_lsz64)
+               blast_scache64_page(page);
+       else
+               blast_scache128_page(page);
 }
 
 static void
@@ -355,6 +292,12 @@ static void andes_update_mmu_cache(struct vm_area_struct * vma,
        pte_t *ptep;
        int idx, pid;
 
+       /*
+        * Handle debugger faulting in for debugee.
+        */
+       if (current->active_mm != vma->vm_mm)
+               return;
+
        __save_and_cli(flags);
        pid = get_entryhi() & 0xff;
 
@@ -440,24 +383,33 @@ void __init ld_mmu_andes(void)
        _clear_page = andes_clear_page;
        _copy_page = andes_copy_page;
 
-       _flush_cache_all = andes_flush_cache_all;
-       _flush_cache_mm = andes_flush_cache_mm;
-       _flush_cache_range = andes_flush_cache_range;
-       _flush_cache_page = andes_flush_cache_page;
+       _flush_cache_l1 = andes_flush_cache_l1;
+       _flush_cache_l2 = andes_flush_cache_l2;
        _flush_cache_sigtramp = andes_flush_cache_sigtramp;
-       _flush_page_to_ram = andes_flush_page_to_ram;
 
        _flush_tlb_all = andes_flush_tlb_all;
        _flush_tlb_mm = andes_flush_tlb_mm;
        _flush_tlb_range = andes_flush_tlb_range;
        _flush_tlb_page = andes_flush_tlb_page;
+
+       switch (sc_lsize()) {
+               case 64:
+                       scache_lsz64 = 1;
+                       break;
+               case 128:
+                       scache_lsz64 = 0;
+                       break;
+               default:
+                       printk("Unknown L2 line size\n");
+                       while(1);
+       }
     
        update_mmu_cache = andes_update_mmu_cache;
 
        _show_regs = andes_show_regs;
        _user_mode = andes_user_mode;
 
-        flush_cache_all();
+        flush_cache_l1();
 
        /*
         * You should never change this register:
index c518f96b4f589592cec46b0687aa8c053f772fd9..223ca3e5e625e7a933384b181672c9d817e50793 100644 (file)
@@ -200,7 +200,7 @@ int do_check_pgt_cache(int low, int high)
 asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
 {
        /* XXX Just get it working for now... */
-       flush_cache_all();
+       flush_cache_l1();
        return 0;
 }
 
index 69f661c0baed5ded3fa2ef3829ad7b4fe66f3f1a..ce7525545537d4c192fa54749270d29997c5f9fc 100644 (file)
@@ -25,14 +25,18 @@ void (*_clear_page)(void * page);
 void (*_copy_page)(void * to, void * from);
 
 /* Cache operations. */
-void (*_flush_cache_all)(void);
 void (*_flush_cache_mm)(struct mm_struct *mm);
 void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
                            unsigned long end);
 void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
-void (*_flush_cache_sigtramp)(unsigned long addr);
 void (*_flush_page_to_ram)(struct page * page);
 
+/* MIPS specific cache operations */
+void (*_flush_cache_sigtramp)(unsigned long addr);
+void (*_flush_cache_l2)(void);
+void (*_flush_cache_l1)(void);
+
+
 /* DMA cache operations. */
 void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
 void (*_dma_cache_wback)(unsigned long start, unsigned long size);
index 2b3ca03a44f481cb5fce6b4db21cfae744e9e237..1b2fb35bfb4bfad4ae5ec92218ccacfb2e9814fb 100644 (file)
@@ -1882,7 +1882,7 @@ r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
        unsigned int flags;
 
        if (size >= dcache_size) {
-               flush_cache_all();
+               flush_cache_l1();
        } else {
                /* Workaround for R4600 bug.  See comment above. */
                __save_and_cli(flags);
@@ -1906,7 +1906,7 @@ r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size)
        unsigned long end, a;
 
        if (size >= scache_size) {
-               flush_cache_all();
+               flush_cache_l1();
                return;
        }
 
@@ -1926,7 +1926,7 @@ r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
        unsigned int flags;
 
        if (size >= dcache_size) {
-               flush_cache_all();
+               flush_cache_l1();
        } else {
                /* Workaround for R4600 bug.  See comment above. */
                __save_and_cli(flags);
@@ -1951,7 +1951,7 @@ r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
        unsigned long end, a;
 
        if (size >= scache_size) {
-               flush_cache_all();
+               flush_cache_l1();
                return;
        }
 
@@ -2146,6 +2146,11 @@ static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
        }
 }
 
+static void
+r4k_flush_cache_l2(void)
+{
+}
+
 #ifdef DEBUG_TLBUPDATE
 static unsigned long ehi_debug[NTLB_ENTRIES];
 static unsigned long el0_debug[NTLB_ENTRIES];
@@ -2165,6 +2170,12 @@ static void r4k_update_mmu_cache(struct vm_area_struct * vma,
        pte_t *ptep;
        int idx, pid;
 
+       /*
+        * Handle debugger faulting in for debugee.
+        */
+       if (current->active_mm != vma->vm_mm)
+               return;
+
        __save_and_cli(flags);
        pid = (get_entryhi() & 0xff);
 
@@ -2371,7 +2382,7 @@ static void __init setup_noscache_funcs(void)
        case 16:
                _clear_page = r4k_clear_page_d16;
                _copy_page = r4k_copy_page_d16;
-               _flush_cache_all = r4k_flush_cache_all_d16i16;
+               _flush_cache_l1 = r4k_flush_cache_all_d16i16;
                _flush_cache_mm = r4k_flush_cache_mm_d16i16;
                _flush_cache_range = r4k_flush_cache_range_d16i16;
                _flush_cache_page = r4k_flush_cache_page_d16i16;
@@ -2389,7 +2400,7 @@ static void __init setup_noscache_funcs(void)
                        _clear_page = r4k_clear_page_d32;
                        _copy_page = r4k_copy_page_d32;
                }
-               _flush_cache_all = r4k_flush_cache_all_d32i32;
+               _flush_cache_l1 = r4k_flush_cache_all_d32i32;
                _flush_cache_mm = r4k_flush_cache_mm_d32i32;
                _flush_cache_range = r4k_flush_cache_range_d32i32;
                _flush_cache_page = r4k_flush_cache_page_d32i32;
@@ -2407,7 +2418,7 @@ static void __init setup_scache_funcs(void)
        case 16:
                switch(dc_lsize) {
                case 16:
-                       _flush_cache_all = r4k_flush_cache_all_s16d16i16;
+                       _flush_cache_l1 = r4k_flush_cache_all_s16d16i16;
                        _flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
                        _flush_cache_range = r4k_flush_cache_range_s16d16i16;
                        _flush_cache_page = r4k_flush_cache_page_s16d16i16;
@@ -2422,14 +2433,14 @@ static void __init setup_scache_funcs(void)
        case 32:
                switch(dc_lsize) {
                case 16:
-                       _flush_cache_all = r4k_flush_cache_all_s32d16i16;
+                       _flush_cache_l1 = r4k_flush_cache_all_s32d16i16;
                        _flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
                        _flush_cache_range = r4k_flush_cache_range_s32d16i16;
                        _flush_cache_page = r4k_flush_cache_page_s32d16i16;
                        _flush_page_to_ram = r4k_flush_page_to_ram_s32d16i16;
                        break;
                case 32:
-                       _flush_cache_all = r4k_flush_cache_all_s32d32i32;
+                       _flush_cache_l1 = r4k_flush_cache_all_s32d32i32;
                        _flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
                        _flush_cache_range = r4k_flush_cache_range_s32d32i32;
                        _flush_cache_page = r4k_flush_cache_page_s32d32i32;
@@ -2442,14 +2453,14 @@ static void __init setup_scache_funcs(void)
        case 64:
                switch(dc_lsize) {
                case 16:
-                       _flush_cache_all = r4k_flush_cache_all_s64d16i16;
+                       _flush_cache_l1 = r4k_flush_cache_all_s64d16i16;
                        _flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
                        _flush_cache_range = r4k_flush_cache_range_s64d16i16;
                        _flush_cache_page = r4k_flush_cache_page_s64d16i16;
                        _flush_page_to_ram = r4k_flush_page_to_ram_s64d16i16;
                        break;
                case 32:
-                       _flush_cache_all = r4k_flush_cache_all_s64d32i32;
+                       _flush_cache_l1 = r4k_flush_cache_all_s64d32i32;
                        _flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
                        _flush_cache_range = r4k_flush_cache_range_s64d32i32;
                        _flush_cache_page = r4k_flush_cache_page_s64d32i32;
@@ -2462,14 +2473,14 @@ static void __init setup_scache_funcs(void)
        case 128:
                switch(dc_lsize) {
                case 16:
-                       _flush_cache_all = r4k_flush_cache_all_s128d16i16;
+                       _flush_cache_l1 = r4k_flush_cache_all_s128d16i16;
                        _flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
                        _flush_cache_range = r4k_flush_cache_range_s128d16i16;
                        _flush_cache_page = r4k_flush_cache_page_s128d16i16;
                        _flush_page_to_ram = r4k_flush_page_to_ram_s128d16i16;
                        break;
                case 32:
-                       _flush_cache_all = r4k_flush_cache_all_s128d32i32;
+                       _flush_cache_l1 = r4k_flush_cache_all_s128d32i32;
                        _flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
                        _flush_cache_range = r4k_flush_cache_range_s128d32i32;
                        _flush_cache_page = r4k_flush_cache_page_s128d32i32;
@@ -2538,13 +2549,14 @@ void __init ld_mmu_r4xx0(void)
        _flush_tlb_mm = r4k_flush_tlb_mm;
        _flush_tlb_range = r4k_flush_tlb_range;
        _flush_tlb_page = r4k_flush_tlb_page;
+       _flush_cache_l2 = r4k_flush_cache_l2;
 
        update_mmu_cache = r4k_update_mmu_cache;
 
        _show_regs = r4k_show_regs;
        _user_mode = r4k_user_mode;
 
-       flush_cache_all();
+       flush_cache_l1();
 
        /*
         * You should never change this register:
index 91bd7c9f52348075642e13ed142094c64a919ffe..f6b94445b2204dee96606a924cbbf6a9e1645778 100644 (file)
@@ -301,7 +301,8 @@ void per_hub_init(cnodeid_t cnode)
                        memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
                        memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic,
                                                                0x100);
-                       flush_cache_all();
+                       flush_cache_l1();
+                       flush_cache_l2();
                }
 #endif
        }
@@ -418,7 +419,8 @@ void cboot(void)
        init_mfhi_war();
 #endif
        _flush_tlb_all();
-       flush_cache_all();
+       flush_cache_l1();
+       flush_cache_l2();
        start_secondary();
 }
 
index 4900ff77720bc4ccfa8fa01fefeb108fe1d81af6..c31e006679b7aa3a551aa07046d40fe1212a6d40 100644 (file)
@@ -169,24 +169,6 @@ pfn_t szmem(pfn_t fpage, pfn_t maxpmem)
                return num_pages;
 }
 
-/*
- * HACK ALERT - Things do not work if this is not here. Maybe this is
- * acting as a pseudocacheflush operation. The write pattern seems to
- * be important, writing a 0 does not help.
- */
-void setup_test(cnodeid_t node, pfn_t start, pfn_t end)
-{
-       unsigned long *ptr = __va(start << PAGE_SHIFT);
-       unsigned long size = 4 * 1024 * 1024;   /* 4M L2 caches */
-
-       while (size) {
-               size -= sizeof(unsigned long);
-               *ptr = (0xdeadbeefbabeb000UL|node);
-               /* *ptr = 0; */
-               ptr++;
-       }
-}
-
 /*
  * Currently, the intranode memory hole support assumes that each slot
  * contains at least 32 MBytes of memory. We assume all bootmem data
@@ -210,8 +192,7 @@ void __init prom_meminit(void)
                /* Foll line hack for non discontigmem; remove once discontigmem
                 * becomes the default. */
                max_low_pfn = (slot_lastpfn - slot_firstpfn);
-               if (node != 0) 
-                       setup_test(node, slot_freepfn, slot_lastpfn);
+
                /*
                 * Allocate the node data structure on the node first.
                 */
index 6fec8d31398d5af26a97829b82659b7d95571ada..37324533c9356830defa8327db79a5ea8c5f065b 100644 (file)
@@ -78,6 +78,7 @@ void output_task_defines(void)
        offset("#define TASK_FLAGS         ", struct task_struct, flags);
        offset("#define TASK_SIGPENDING    ", struct task_struct, sigpending);
        offset("#define TASK_NEED_RESCHED  ", struct task_struct, need_resched);
+       offset("#define TASK_PTRACE        ", struct task_struct, ptrace);
        offset("#define TASK_COUNTER       ", struct task_struct, counter);
        offset("#define TASK_NICE          ", struct task_struct, nice);
        offset("#define TASK_MM            ", struct task_struct, mm);
index 085c48c8fa3013fd796b69ae8502524c71cdd2df..a83719fb7123f217d7d0bf9cfede2ad476bc7d30 100644 (file)
@@ -23,7 +23,7 @@ obj-          :=
 
 SUB_DIRS     := 
 MOD_SUB_DIRS := $(SUB_DIRS)
-ALL_SUB_DIRS := $(SUB_DIRS) ftape joystick pcmcia rio
+ALL_SUB_DIRS := $(SUB_DIRS) ftape joystick pcmcia rio drm agp
 
 #
 # This file contains the font map for the default (hardware) font
@@ -109,16 +109,7 @@ else
 endif
 
 obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
-
 obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
-ifeq ($(CONFIG_ATARI_DSP56K),y)
-S = y
-else
-  ifeq ($(CONFIG_ATARI_DSP56K),m)
-  SM = y
-  endif
-endif
-
 obj-$(CONFIG_ROCKETPORT) += rocket.o
 obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
 obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
@@ -135,10 +126,6 @@ obj-$(CONFIG_SYNCLINK) += synclink.o
 obj-$(CONFIG_N_HDLC) += n_hdlc.o
 obj-$(CONFIG_SPECIALIX) += specialix.o
 obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
-
-# After much ado, we found that an object can safely be declared as
-# both a module and into the kernel. Below that is filtered out.
-# So this should simply provide the wanted functionality!
 obj-$(CONFIG_SX) += sx.o generic_serial.o
 obj-$(CONFIG_RIO) += rio/rio.o generic_serial.o
 obj-$(CONFIG_SH_SCI) += sh-sci.o generic_serial.o
@@ -166,14 +153,6 @@ else
 endif
 
 obj-$(CONFIG_BUSMOUSE) += busmouse.o
-ifeq ($(CONFIG_BUSMOUSE),y)
-M = y
-else
-  ifeq ($(CONFIG_BUSMOUSE),m)
-  MM = m
-  endif
-endif
-
 obj-$(CONFIG_DTLK) += dtlk.o
 obj-$(CONFIG_R3964) += n_r3964.o
 obj-$(CONFIG_APPLICOM) += applicom.o
@@ -203,72 +182,17 @@ obj-$(CONFIG_977_WATCHDOG) += wdt977.o
 obj-$(CONFIG_DS1620) += ds1620.o
 obj-$(CONFIG_INTEL_RNG) += i810_rng.o
 
-#
-# for external dependencies in arm/config.in and video/config.in
-#
-ifeq ($(CONFIG_BUS_I2C),y)
-       L_I2C=y
-else
-  ifeq ($(CONFIG_BUS_I2C),m)
-       L_I2C=m
-  endif
-endif
-
+obj-$(CONFIG_BUS_I2C) += i2c-old.o
 obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o \
-       tda7432.o tda8425.o tda985x.o tda9875.o tea6300.o tea6420.o
-ifeq ($(CONFIG_VIDEO_BT848),y)
-L_TUNERS=y
-else
-  ifeq ($(CONFIG_VIDEO_BT848),m)
-    L_TUNERS=m
-  endif
-endif
+       tda7432.o tda8425.o tda985x.o tda9875.o tea6300.o tea6420.o tuner.o
 obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
 
-obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
-ifeq ($(CONFIG_VIDEO_ZR36120),y)
-L_I2C=y
-L_TUNERS=y
-L_DECODERS=y
-else
-  ifeq ($(CONFIG_VIDEO_ZR36120),m)
-    L_I2C=m
-    L_TUNERS=m
-    L_DECODERS=m
-  endif
-endif
-
-obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
-ifeq ($(CONFIG_I2C_PARPORT),y)
-L_I2C = y
-else
-  ifeq ($(CONFIG_I2C_PARPORT),m)
-    L_I2C = m
-  endif
-endif
-
-obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
-ifeq ($(CONFIG_VIDEO_SAA5249),y)
-L_I2C=y
-else
-  ifeq ($(CONFIG_VIDEO_SAA5249),m)
-    L_I2C=m
-  endif
-endif
-
+obj-$(CONFIG_VIDEO_ZR36120) += zoran.o i2c-old.o tuner.o saa7110.o saa7111.o saa7185.o 
+obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o i2c-old.o
+obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o i2c-old.o
 obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
 obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
-obj-$(CONFIG_VIDEO_ZORAN) += buz.o
-ifeq ($(CONFIG_VIDEO_ZORAN),y)
-L_I2C=y
-L_DECODERS=y
-else
-  ifeq ($(CONFIG_VIDEO_ZORAN),m)
-    L_I2C=m
-    L_DECODERS=m
-  endif
-endif
-
+obj-$(CONFIG_VIDEO_ZORAN) += buz.o i2c-old.o saa7110.o saa7111.o saa7185.o 
 obj-$(CONFIG_VIDEO_LML33) += bt856.o bt819.o
 obj-$(CONFIG_VIDEO_PMS) += pms.o
 obj-$(CONFIG_VIDEO_PLANB) += planb.o
@@ -305,24 +229,17 @@ endif
 
 obj-$(CONFIG_H8) += h8.o
 obj-$(CONFIG_PPDEV) += ppdev.o
-
-# set when a framegrabber supports external tuners
-obj-$(L_TUNERS) += tuner.o
-
-# set when a framegrabber supports external decoders
-obj-$(L_DECODERS) += saa7110.o saa7111.o saa7185.o
-
-# set when a framegrabber implements i2c support
-obj-$(L_I2C) += i2c-old.o
-
 obj-$(CONFIG_DZ) += dz.o
 obj-$(CONFIG_NWBUTTON) += nwbutton.o
 obj-$(CONFIG_NWFLASH) += nwflash.o
 
 ifeq ($(CONFIG_DRM),y)
   SUB_DIRS += drm
-  ALL_SUB_DIRS += drm
   MOD_SUB_DIRS += drm
+else
+  ifeq ($(CONFIG_DRM),m)
+  MOD_SUB_DIRS += drm
+  endif
 endif
 
 ifeq ($(CONFIG_PCMCIA),y)
@@ -336,11 +253,9 @@ endif
 
 ifeq ($(CONFIG_AGP), y)
   SUB_DIRS += agp
-  ALL_SUB_DIRS += agp
   MOD_SUB_DIRS += agp
 else
   ifeq ($(CONFIG_AGP), m)
-    ALL_SUB_DIRS += agp
     MOD_SUB_DIRS += agp
   endif
 endif
index 628e8cad5287468854ba75f1e4f4c0337b7034cd..48a6aa5f97f064824363d5c1ccdf4d74fbace1bc 100644 (file)
@@ -30,6 +30,7 @@
 
 #define __NO_VERSION__
 #include "drmP.h"
+#include <linux/module.h>
 
 drm_agp_func_t drm_agp = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 
index 3ee85388ecebb42674e75c34777375df38c8e409..9f81c5391dde9182c66004629fe5ee7936c4b3e1 100644 (file)
@@ -45,8 +45,6 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
 
        down(&dev->struct_sem);
        for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
-               if (pt->priv->authenticated)
-                       continue;
                if (pt->magic == magic) {
                        retval = pt->priv;
                        break;
index be199ee0696fb17c20bb924f2c9f78e19b2767fe..e7aaf569d307a544da014cb5c0d4ce192698ddd0 100644 (file)
@@ -1,4 +1,4 @@
-
+#include <linux/config.h>
 #include "drmP.h"
 
 /* Misc. support (init.c) */
index e1f462bdd8fed698f7e35bcf799ebad0f14ab8fc..5023de808920eb6f72adfe56949a0b52bd10990a 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #define __NO_VERSION__
+#include <linux/config.h>
 #include "drmP.h"
 
 typedef struct drm_mem_stats {
index d02fc5e00044293c9e5d52967e175eaf1cff6b31..bd81dcdc04c71c3fae8fccb0cf28919702674ab5 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #define __NO_VERSION__
+#include <linux/config.h>
 #include "drmP.h"
 #include "r128_drv.h"
 #include "linux/un.h"
index 27b16614c9dc3afb85413db202a62c7328438b1c..b382a13c5a652a737eb7842ab6db3bf2835712ab 100644 (file)
@@ -466,8 +466,6 @@ int r128_open(struct inode *inode, struct file *filp)
                spin_unlock(&dev->count_lock);
        }
        
-       unlock_kernel();
-
        return retcode;
 }
 
index 85f88044d1918d5fd5dddcd327886acf530cad4c..896705e9711f16fd3e3342b6c43e4359647c5ae4 100644 (file)
@@ -446,9 +446,11 @@ int tdfx_release(struct inode *inode, struct file *filp)
                                          atomic_read(&dev->ioctl_count),
                                          dev->blocked);
                                spin_unlock(&dev->count_lock);
+                               unlock_kernel();
                                return -EBUSY;
                        }
                        spin_unlock(&dev->count_lock);
+                       unlock_kernel();
                        return tdfx_takedown(dev);
                }
                spin_unlock(&dev->count_lock);
index 0e9d7b57f9038dcc3cd5702c1e3665ea2a13b70d..6f4ebe44c13d47d54e3bbd3333d412c1f7cedd21 100644 (file)
@@ -1154,9 +1154,7 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file,
                                nr -= num;
                                if (nr == 0)
                                        break;
-                               current->state = TASK_RUNNING;
                                get_user(c, b);
-                               current->state = TASK_INTERRUPTIBLE;
                                if (opost(c, tty) < 0)
                                        break;
                                b++; nr--;
@@ -1164,9 +1162,7 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file,
                        if (tty->driver.flush_chars)
                                tty->driver.flush_chars(tty);
                } else {
-                       current->state = TASK_RUNNING;
                        c = tty->driver.write(tty, 1, b, nr);
-                       current->state = TASK_INTERRUPTIBLE;
                        if (c < 0) {
                                retval = c;
                                goto break_out;
index 9050f3528707404bb37350537c03cc497b013dd6..405121edc70a5ead68072f6e313a91263bfa1b0a 100644 (file)
@@ -10,7 +10,7 @@ if [ "$CONFIG_I2C" != "n" ]; then
 
    dep_tristate 'I2C bit-banging interfaces'  CONFIG_I2C_ALGOBIT $CONFIG_I2C
    if [ "$CONFIG_I2C_ALGOBIT" != "n" ]; then
-      dep_tristate '  Philips style parallel port adapter' CONFIG_I2C_PHILIPSPAR $CONFIG_I2C_ALGOBIT
+      dep_tristate '  Philips style parallel port adapter' CONFIG_I2C_PHILIPSPAR $CONFIG_I2C_ALGOBIT $CONFIG_PARPORT
       dep_tristate '  ELV adapter' CONFIG_I2C_ELV $CONFIG_I2C_ALGOBIT
       dep_tristate '  Velleman K9000 adapter' CONFIG_I2C_VELLEMAN $CONFIG_I2C_ALGOBIT
    fi
index 6385cd81b4968296fefeaa2d09f00987fd07eb4b..72dd5013414696335867315133cd921e1ad40730 100644 (file)
@@ -862,7 +862,6 @@ void __init ide_init_pdc202xx (ide_hwif_t *hwif)
            (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
            (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) {
                hwif->resetproc = &pdc202xx_reset;
-               hwif->tri_proc  = &pdc202xx_tristate;
        }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
index 29d5d76387950659ac59e066bb5939a6eaf571b3..ae023616a18f2f64569b819e96043d2a1b49fca2 100644 (file)
@@ -607,6 +607,7 @@ MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i");
 
+#endif
 
 void __exit ace_module_cleanup(void)
 {
@@ -695,7 +696,6 @@ void __exit ace_module_cleanup(void)
                root_dev = next;
        }
 }
-#endif
 
 
 int __init ace_module_init(void)
index 4717a652c63575f67e95c77df39792e91692b60d..17d32829489e6227ef947d980e92e5e1064e13bc 100644 (file)
@@ -9,8 +9,6 @@
  */
 
 #include <linux/module.h>
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
index 7342b98b58b7e171557bd85382e7c89e0c61dd0e..04c84c99d98fff98f02407a5fe60482640788896 100644 (file)
@@ -105,8 +105,6 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void ioc3_timeout(struct net_device *dev);
 static inline unsigned int ioc3_hash(const unsigned char *addr);
 static void ioc3_stop(struct net_device *dev);
-static void ioc3_clean_tx_ring(struct ioc3_private *ip);
-static void ioc3_clean_rx_ring(struct ioc3_private *ip);
 static void ioc3_init(struct net_device *dev);
 
 static const char ioc3_str[] = "IOC3 Ethernet";
@@ -446,7 +444,6 @@ ioc3_rx(struct net_device *dev, struct ioc3_private *ip, struct ioc3 *ioc3)
 
                        ip->stats.rx_packets++;         /* Statistics */
                        ip->stats.rx_bytes += len;
-
                } else {
                        /* The frame is invalid and the skb never
                            reached the network layer so we can just
@@ -464,7 +461,6 @@ next:
                                ((unsigned long) rxb & TO_PHYS_MASK);
                rxb->w0 = 0;                            /* Clear valid flag */
                n_entry = (n_entry + 1) & 511;          /* Update erpir */
-               ioc3->erpir = (n_entry << 3) | ERPIR_ARM;
 
                /* Now go on to the next ring entry.  */
                rx_entry = (rx_entry + 1) & 511;
@@ -472,6 +468,7 @@ next:
                rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
                w0 = rxb->w0;
        }
+       ioc3->erpir = (n_entry << 3) | ERPIR_ARM;
        ip->rx_pi = n_entry;
        ip->rx_ci = rx_entry;
 }
@@ -527,17 +524,26 @@ static void
 ioc3_error(struct net_device *dev, struct ioc3_private *ip,
            struct ioc3 *ioc3, u32 eisr)
 {
-       if (eisr & (EISR_RXMEMERR | EISR_TXMEMERR)) {
-               if (eisr & EISR_RXMEMERR) {
-                       printk(KERN_ERR "%s: RX PCI error.\n", dev->name);
-               }
-               if (eisr & EISR_TXMEMERR) {
-                       printk(KERN_ERR "%s: TX PCI error.\n", dev->name);
-               }
+       if (eisr & EISR_RXOFLO) {
+               printk(KERN_ERR "%s: RX overflow.\n", dev->name);
+       }
+       if (eisr & EISR_RXBUFOFLO) {
+               printk(KERN_ERR "%s: RX buffer overflow.\n", dev->name);
+       }
+       if (eisr & EISR_RXMEMERR) {
+               printk(KERN_ERR "%s: RX PCI error.\n", dev->name);
+       }
+       if (eisr & EISR_RXPARERR) {
+               printk(KERN_ERR "%s: RX SSRAM parity error.\n", dev->name);
+       }
+       if (eisr & EISR_TXBUFUFLO) {
+               printk(KERN_ERR "%s: TX buffer underflow.\n", dev->name);
+       }
+       if (eisr & EISR_TXMEMERR) {
+               printk(KERN_ERR "%s: TX PCI error.\n", dev->name);
        }
 
        ioc3_stop(dev);
-       ioc3_clean_tx_ring(dev->priv);
        ioc3_init(dev);
 
        dev->trans_start = jiffies;
@@ -551,8 +557,9 @@ static void ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs)
        struct net_device *dev = (struct net_device *)_dev;
        struct ioc3_private *ip = dev->priv;
        struct ioc3 *ioc3 = ip->regs;
-       const u32 enabled = EISR_RXTIMERINT | EISR_TXEXPLICIT |
-                           EISR_RXMEMERR | EISR_TXMEMERR;
+       const u32 enabled = EISR_RXTIMERINT | EISR_RXOFLO | EISR_RXBUFOFLO |
+                           EISR_RXMEMERR | EISR_RXPARERR | EISR_TXBUFUFLO |
+                           EISR_TXEXPLICIT | EISR_TXMEMERR;
        u32 eisr;
 
        eisr = ioc3->eisr & enabled;
@@ -560,12 +567,14 @@ static void ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs)
                ioc3->eisr = eisr;
                ioc3->eisr;                             /* Flush */
 
+               if (eisr & (EISR_RXOFLO | EISR_RXBUFOFLO | EISR_RXMEMERR |
+                           EISR_RXPARERR | EISR_TXBUFUFLO | EISR_TXMEMERR))
+                       ioc3_error(dev, ip, ioc3, eisr);
                if (eisr & EISR_RXTIMERINT)
                        ioc3_rx(dev, ip, ioc3);
                if (eisr & EISR_TXEXPLICIT)
                        ioc3_tx(dev, ip, ioc3);
-               if (eisr & (EISR_RXMEMERR | EISR_TXMEMERR))
-                       ioc3_error(dev, ip, ioc3, eisr);
+
                eisr = ioc3->eisr & enabled;
        }
 }
@@ -611,16 +620,74 @@ int ioc3_mii_init(struct net_device *dev, struct ioc3_private *ip,
        /* Autonegotiate 100mbit and fullduplex. */
        mii_write(ioc3, phy, 0, mii0 | 0x3100);
 
-       spin_unlock_irq(&ip->ioc3_lock);
-       mdelay(1000);                           /* XXX Yikes XXX */
-       spin_lock_irq(&ip->ioc3_lock);
-
-       mii_status = mii_read(ioc3, phy, 1);
        spin_unlock_irq(&ip->ioc3_lock);
 
        return 0;
 }
 
+static inline void
+ioc3_clean_rx_ring(struct ioc3_private *ip)
+{
+       struct sk_buff *skb;
+       int i;
+
+       for (i = ip->rx_ci; i & 15; i++) {
+               ip->rx_skbs[ip->rx_pi] = ip->rx_skbs[ip->rx_ci];
+               ip->rxr[ip->rx_pi++] = ip->rxr[ip->rx_ci++];
+       }
+       ip->rx_pi &= 511;
+       ip->rx_ci &= 511;
+
+       for (i = ip->rx_ci; i != ip->rx_pi; i = (i+1) & 511) {
+               struct ioc3_erxbuf *rxb;
+               skb = ip->rx_skbs[i];
+               rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
+               rxb->w0 = 0;
+       }
+}
+
+static inline void
+ioc3_clean_tx_ring(struct ioc3_private *ip)
+{
+       struct sk_buff *skb;
+       int i;
+
+       for (i=0; i < 128; i++) {
+               skb = ip->tx_skbs[i];
+               if (skb) {
+                       ip->tx_skbs[i] = NULL;
+                       dev_kfree_skb_any(skb);
+               }
+               ip->txr[i].cmd = 0;
+       }
+       ip->tx_pi = 0;
+       ip->tx_ci = 0;
+}
+
+static void
+ioc3_free_rings(struct ioc3_private *ip)
+{
+       struct sk_buff *skb;
+       int rx_entry, n_entry;
+
+       ioc3_clean_tx_ring(ip);
+       ip->txr = NULL;
+       free_pages((unsigned long)ip->txr, 2);
+
+       n_entry = ip->rx_ci;
+       rx_entry = ip->rx_pi;
+
+       while (n_entry != rx_entry) {
+               skb = ip->rx_skbs[n_entry];
+               if (skb)
+                       dev_kfree_skb_any(skb);
+
+               n_entry = (n_entry + 1) & 511;
+       }
+       free_page((unsigned long)ip->rxr);
+       ip->rxr = NULL;
+}
+
 static void
 ioc3_alloc_rings(struct net_device *dev, struct ioc3_private *ip,
                 struct ioc3 *ioc3)
@@ -676,8 +743,8 @@ ioc3_init_rings(struct net_device *dev, struct ioc3_private *ip,
 
        ioc3_alloc_rings(dev, ip, ioc3);
 
-       ioc3_clean_tx_ring(ip);
        ioc3_clean_rx_ring(ip);
+       ioc3_clean_tx_ring(ip);
 
        /* Now the rx ring base, consume & produce registers.  */
        ring = (0xa5UL << 56) | ((unsigned long)ip->rxr & TO_PHYS_MASK);
@@ -698,61 +765,6 @@ ioc3_init_rings(struct net_device *dev, struct ioc3_private *ip,
        ioc3->etcir;                                    /* Flush */
 }
 
-static void
-ioc3_clean_tx_ring(struct ioc3_private *ip)
-{
-       struct sk_buff *skb;
-       int i;
-
-       for (i=0; i < 128; i++) {
-               skb = ip->tx_skbs[i];
-               if (skb) {
-                       ip->tx_skbs[i] = NULL;
-                       dev_kfree_skb_any(skb);
-               }
-               ip->txr[i].cmd = 0;
-       }
-}
-
-static void
-ioc3_clean_rx_ring(struct ioc3_private *ip)
-{
-       struct sk_buff *skb;
-       int i;
-       
-       for (i = 0; i < RX_BUFFS; i++) {
-               struct ioc3_erxbuf *rxb;
-               skb = ip->rx_skbs[i];
-               rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
-
-               rxb->w0 = 0;
-       }
-}
-
-static void
-ioc3_free_rings(struct ioc3_private *ip)
-{
-       struct sk_buff *skb;
-       int rx_entry, n_entry;
-
-       ioc3_clean_tx_ring(ip);
-       free_pages((unsigned long)ip->txr, 2);
-       ip->txr = NULL;
-
-       n_entry = ip->rx_ci;
-       rx_entry = ip->rx_pi;
-
-       while (n_entry != rx_entry) {
-               skb = ip->rx_skbs[n_entry];
-               if (skb)
-                       dev_kfree_skb_any(skb);
-
-               n_entry = (n_entry + 1) & 511;
-       }
-       free_page((unsigned long)ip->rxr);
-       ip->rxr = NULL;
-}
-
 static inline void
 ioc3_ssram_disc(struct ioc3_private *ip)
 {
@@ -797,17 +809,18 @@ static void ioc3_init(struct net_device *dev)
        ioc3->emar_h = (dev->dev_addr[5] << 8) | dev->dev_addr[4];
        ioc3->emar_l = (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) |
                       (dev->dev_addr[1] <<  8) | dev->dev_addr[0];
-       ioc3->ehar_h = ioc3->ehar_l = 0;
+       ioc3->ehar_h = ip->ehar_h;
+       ioc3->ehar_l = ip->ehar_l;
        ioc3->ersr = 42;                        /* XXX should be random */
-       //ioc3->erpir = ERPIR_ARM;
 
        ioc3_init_rings(dev, ip, ioc3);
 
        ip->emcr |= ((RX_OFFSET / 2) << EMCR_RXOFF_SHIFT) | EMCR_TXDMAEN |
-                     EMCR_TXEN | EMCR_RXDMAEN | EMCR_RXEN;
+                    EMCR_TXEN | EMCR_RXDMAEN | EMCR_RXEN;
        ioc3->emcr = ip->emcr;
-       ioc3->eier = EISR_RXTIMERINT | EISR_TXEXPLICIT | /* Interrupts ...  */
-                    EISR_RXMEMERR | EISR_TXMEMERR;
+       ioc3->eier = EISR_RXTIMERINT | EISR_RXOFLO | EISR_RXBUFOFLO |
+                    EISR_RXMEMERR | EISR_RXPARERR | EISR_TXBUFUFLO |
+                    EISR_TXEXPLICIT | EISR_TXMEMERR;
        ioc3->eier;
 }
 
@@ -817,7 +830,6 @@ static void ioc3_stop(struct net_device *dev)
        struct ioc3 *ioc3 = ip->regs;
 
        ioc3->emcr = 0;                         /* Shutup */
-       ip->emcr = 0;
        ioc3->eier = 0;                         /* Disable interrupts */
        ioc3->eier;                             /* Flush */
 }
@@ -825,14 +837,18 @@ static void ioc3_stop(struct net_device *dev)
 static int
 ioc3_open(struct net_device *dev)
 {
+       struct ioc3_private *ip;
+
        if (request_irq(dev->irq, ioc3_interrupt, 0, ioc3_str, dev)) {
                printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq);
 
                return -EAGAIN;
        }
 
-       ((struct ioc3_private *)dev->priv)->ehar_h = 0;
-       ((struct ioc3_private *)dev->priv)->ehar_l = 0;
+       ip = (struct ioc3_private *) dev->priv;
+
+       ip->ehar_h = 0;
+       ip->ehar_l = 0;
        ioc3_init(dev);
 
        netif_start_queue(dev);
@@ -1005,7 +1021,6 @@ static void ioc3_timeout(struct net_device *dev)
        printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
 
        ioc3_stop(dev);
-       ioc3_clean_tx_ring(dev->priv);
        ioc3_init(dev);
 
        dev->trans_start = jiffies;
@@ -1117,7 +1132,7 @@ static void ioc3_set_multicast_list(struct net_device *dev)
                                if (!(*addr & 1))
                                        continue;
 
-                               ehar |= (1 << ioc3_hash(addr));
+                               ehar |= (1UL << ioc3_hash(addr));
                        }
                        ip->ehar_h = ehar >> 32;
                        ip->ehar_l = ehar & 0xffffffff;
index 1d5efdfc4e40e885967cb6e0527d042c2ddbaf93..8d0d245b3f9db99fcfbed50196e75ed416fd4abb 100644 (file)
@@ -222,6 +222,18 @@ static void __init quirk_piix3usb(struct pci_dev *dev)
        pci_write_config_word(dev, 0xc0, legsup);
 }
 
+/*
+ * VIA VT82C598 has its device ID settable and many BIOSes
+ * set it to the ID of VT82C597 for backward compatibility.
+ * We need to switch it off to be able to recognize the real
+ * type of the chip.
+ */
+static void __init quirk_vt82c598_id(struct pci_dev *dev)
+{
+       pci_write_config_byte(dev, 0xfc, 0);
+       pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
+}
+
 /*
  *  The main table of quirks.
  */
@@ -232,7 +244,6 @@ static struct pci_fixup pci_fixups[] __initdata = {
        /*
         * Its not totally clear which chipsets are the problematic ones
         * We know 82C586 and 82C596 variants are affected.
-        *
         */
        { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C586_0,     quirk_isa_dma_hangs },
        { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C596,       quirk_isa_dma_hangs },
@@ -251,6 +262,7 @@ static struct pci_fixup pci_fixups[] __initdata = {
        { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82443BX_2,  quirk_natoma },
        { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_5597,          quirk_nopcipci },
        { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_496,           quirk_nopcipci },
+       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C597_0,     quirk_vt82c598_id },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C586_3,     quirk_vt82c586_acpi },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_VIA,      PCI_DEVICE_ID_VIA_82C686_4,     quirk_vt82c686_acpi },
        { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82371AB_3,  quirk_piix4_acpi },
index 61fd18e51f30a93a58d24b911be2970cb8f7cf50..313690c26bee5095c2597bf3db1f9c1634770f8f 100644 (file)
   General Public License. Originally written by Martin Kolinek, December 1995.
          Officially maintained by Michael Lang since January 1999.
           
-                              Version 3.1e
+                              Version 3.2
        
        
-   Last update: 20 February 1999
+   Last update: 29 July 2000
 
 
    Authors of this Driver
@@ -23,7 +23,8 @@
     - Klaus Kudielka (multiple SCSI-host management/detection, adaption to
                       Linux Kernel 2.1.x, module support)
     - Michael Lang (assigning original pun,lun mapping, dynamical ldn 
-                    assignment, this file, patch, official driver maintenance)
+                    assignment, this file, patch, official driver maintenance
+                   and subsequent pains related with the driver :-))
 
    Table of Contents
    -----------------
      5.3 Bugreports
      5.4 Support WWW-page
    6 References
-   7 Trademarks
+   7 Credits to
+     7.1 People
+     7.2 Sponsors & Supporters
+   8 Trademarks
+   9 Disclaimer
 
                               * * *
 
@@ -64,7 +69,7 @@
    quite outdated. The history of the driver development is also kept inside 
    here. Multiple historical developments have been summarized to shorten the 
    textsize a bit. At the end of this file you can find a small manual for 
-   this driver and hints to get it running even on your machine (hopefully).
+   this driver and hints to get it running on your machine.
 
    2 Driver Description
    --------------------
    Microchannel-bus support is enabled, as the IBM SCSI-subsystem needs the
    Microchannel. In a next step, a free interrupt is chosen and the main
    interrupt handler is connected to it to handle answers of the SCSI-
-   subsystem(s). In a further step, it is checked, wether there was a forced
-   detection of the adapter via the kernel commandline, where the I/O port
-   and the SCSI-subsystem id can be specified. The next step checks if there
-   is an integrated SCSI-subsystem installed. This register area is fixed 
-   through all IBM PS/2 MCA-machines and appears as something like a virtual 
-   slot 10 of the MCA-bus. If POS-register 2 is not 0xff, there must be a SCSI-
+   subsystem(s). If the F/W SCSI-adapter is forced by the BIOS to use IRQ11
+   instead of IRQ14, IRQ11 is used for the IBM SCSI-2 F/W adapter. In a 
+   further step it is checked, if the adapter gets detected by force from
+   the kernel commandline, where the I/O port and the SCSI-subsystem id can 
+   be specified. The next step checks if there is an integrated SCSI-subsystem
+   installed. This register area is fixed through all IBM PS/2 MCA-machines 
+   and appears as something like a virtual slot 10 of the MCA-bus. On most
+   PS/2 machines, the POS registers of slot 10 are set to 0xff or 0x00 if not
+   integrated SCSI-controller is available. But on certain PS/2s, like model 
+   9595, this slot 10 is used to store other information which at earlier
+   stage confused the driver and resulted in the detection of some ghost-SCSI. 
+   If POS-register 2 and 3 are not 0x00 and not 0xff, but all other POS
+   registers are either 0xff or 0x00, there must be an integrated SCSI-
    subsystem present and it will be registered as IBM Integrated SCSI-
    Subsystem. The next step checks, if there is a slot-adapter installed on 
    the MCA-bus. To get this, the first two POS-registers, that represent the 
    adapter ID are checked. If they fit to one of the ids, stored in the 
-   adapter list, a SCSI-subsystem is assumed to be found and will be 
+   adapter list, a SCSI-subsystem is assumed to be found in a slot and will be 
    registered. This check is done through all possible MCA-bus slots to allow 
    more than one SCSI-adapter to be present in the PS/2-system and this is 
    already the first point of problems. Looking into the technical reference 
    manual for the IBM PS/2 common interfaces, the POS2 register must have 
-   different interpretation of its single bits. While one can assume, that the
-   integrated subsystem has a fix I/O-address at 0x3540 - 0x3547, further
-   installed IBM SCSI-adapters must use a different I/O-address. This is
-   expressed by bit 1 to 3 of POS2 (multiplied by 8 + 0x3540). Bits 2 and 3 
-   are reserved for the integrated subsystem, but not for the adapters! The
-   following list shows, how the bits of POS2 and POS3 should be interpreted.
+   different interpretation of its single bits to avoid overlapping I/O
+   regions. While one can assume, that the integrated subsystem has a fix 
+   I/O-address at 0x3540 - 0x3547, further installed IBM SCSI-adapters must 
+   use a different I/O-address. This is expressed by bit 1 to 3 of POS2 
+   (multiplied by 8 + 0x3540). Bits 2 and 3 are reserved for the integrated 
+   subsystem, but not for the adapters! The following list shows, how the 
+   bits of POS2 and POS3 should be interpreted.
    
    The POS2-register of all PS/2 models' integrated SCSI-subsystems has the 
    following interpretation of bits:
                            Bit 3 - 2 : Reserved
                            Bit 1     : 8k NVRAM Disabled
                            Bit 0     : Chip Enable (EN-Signal)
-   The POS3-register is interpreted as follows (for ALL IBM SCSI-subsys.):
+   The POS3-register is interpreted as follows (for most IBM SCSI-subsys.):
                            Bit 7 - 5 : SCSI ID
                            Bit 4 - 0 : Reserved = 0
-   (taken from "IBM, PS/2 Hardware Interface Technical Reference, Common
-   Interfaces (1991)"). 
-   In short words, this means, that IBM PS/2 machines only support 1 single 
-   subsystem by default. But (additional) slot-adapters must have another 
-   configuration on pos2 in order to be enabled to use more than one IBM SCSI-
-   subsystem, e.g. for a network server. From tests with the IBM SCSI Adapter 
-   w/cache, the POS2-register for slot adapters should be interpreted in the 
-   following way:
-                           Bit 7 - 4 : Chip Revision ID (Release)
-                           Bit 3 - 1 : port offset factor ( * 8 + 0x3540 )
-                           Bit 0     : Chip Enable (EN-Signal)
+   The slot-adapters have different interpretation of these bits. The IBM SCSI
+   adapter (w/Cache) and the IBM SCSI-2 F/W adapter use the following
+   interpretation of the POS2 register:
+                           Bit 7 - 4 : ROM Segment Address Select
+                          Bit 3 - 1 : Adapter I/O Address Select (*8+0x3540)
+                          Bit 0     : Adapter Enable (EN-Signal)
+   and for the POS3 register:
+                           Bit 7 - 5 : SCSI ID 
+                          Bit 4     : Fairness Enable (SCSI ID3 f. F/W)
+                          Bit 3 - 0 : Arbitration Level
+   The most modern product of the series is the IBM SCSI-2 F/W adapter, it 
+   allows dual-bus SCSI and SCSI-wide addressing, which means, PUNs may be
+   between 0 and 15. Here, Bit 4 is the high-order bit of the 4-bit wide
+   adapter PUN expression. In short words, this means, that IBM PS/2 machines 
+   can only support 1 single integrated subsystem by default. Additional
+   slot-adapters get ports assigned by the automatic configuration tool.
 
    One day I found a patch in ibmmca_detect(), forcing the I/O-address to be 
    0x3540 for integrated SCSI-subsystems, there was a remark placed, that on 
    number or pun, also called the scsi id, this is the number you select
    with hardware jumpers), and each physical unit can have up to 8 
    "logical units" (each identified by logical unit number, or lun, 
-   between 0 and 7). 
+   between 0 and 7). The IBM SCSI-2 F/W adapter offers this on up to two
+   busses and provides support for 30 logical devices at the same time, where
+   in wide-addressing mode you can have 16 puns with 32 luns on each device.
+   This section dexribes you the handling of devices on non-F/W adapters.
+   Just imagine, that you can have 16 * 32 = 512 devices on a F/W adapter
+   which means a lot of possible devices for such a small machine.
 
    Typically the adapter has pun=7, so puns of other physical units
-   are between 0 and 6. Almost all physical units have only one   
-   logical unit, with lun=0. A CD-ROM jukebox would be an example of 
-   a physical unit with more than one logical unit.
+   are between 0 and 6(15). On a wide-adapter a pun higher than 7 is
+   possible, but is normally not used. Almost all physical units have only 
+   one logical unit, with lun=0. A CD-ROM jukebox would be an example of a 
+   physical unit with more than one logical unit.
 
    The embedded microprocessor of the IBM SCSI-subsystem hides the complex
    two-dimensional (pun,lun) organization from the operating system.
    checks, on its own, all 56 possible (pun,lun) combinations, and the first 
    15 devices found are assigned into a one-dimensional array of so-called 
    "logical devices", identified by "logical device numbers" or ldn. The last 
-   ldn=15 is reserved for the subsystem itself.
+   ldn=15 is reserved for the subsystem itself. Wide adapters may have 
+   to check up to 15 * 8 = 120 pun/lun combinations.
    
    2.3 SCSI-Device Recognition and dynamical ldn Assignment
    --------------------------------------------------------
    numbers are also hidden. The two possibilities to get around this problem
    is to offer fake pun/lun combinations to the operating system or to 
    delete the whole mapping of the adapter and to reassign the ldns, using
-   the immediate assign command of the SCSI-subsystem. At the beginning of the
-   development of this driver, the following approach was used:
+   the immediate assign command of the SCSI-subsystem for probing through
+   all possible pun/lun combinations. a ldn is a "logical device number"
+   which is used by IBM SCSI-subsystems to access some valid SCSI-device.
+   At the beginning of the development of this driver, the following approach 
+   was used:
+   
    First, the driver checked the ldn's (0 to 6) to find out which ldn's
    have devices assigned. This was done by the functions check_devices() and
    device_exists(). The interrupt handler has a special paragraph of code
    and later, realizes the device recognition in the following way:
    The physical SCSI-devices on the SCSI-bus are probed via immediate_assign- 
    and device_inquiry-commands, that is all implemented in a completely new
-   made check_devices() subroutine. This delivers a exact map of the physical
+   made check_devices() subroutine. This delivers an exact map of the physical
    SCSI-world that is now stored in the get_scsi[][]-array. This means,
    that the once hidden pun,lun assignment is now known to this driver.
    It no longer believes in default-settings of the subsystem and maps all
    can be different from the old, faked puns. Therefore, Linux will eventually
    change /dev/sdXXX assignments and prompt you for corrupted superblock
    repair on boottime. In this case DO NOT PANIC, YOUR DISKS ARE STILL OK!!!
-   You have to reboot (CTRL-D) with a old kernel and set the /etc/fstab-file
+   You have to reboot (CTRL-D) with an old kernel and set the /etc/fstab-file
    entries right. After that, the system should come up as errorfree as before.
    If your boot-partition is not coming up, also edit the /etc/lilo.conf-file
    in a Linux session booted on old kernel and run lilo before reboot. Check
    ----------------------------------
    The following IBM SCSI-subsystems are supported by this driver:
    
-     - IBM Fast SCSI-2 Adapter
+     - IBM Fast/Wide SCSI-2 Adapter
      - IBM 7568 Industrial Computer SCSI Adapter w/cache
      - IBM Expansion Unit SCSI Controller
      - IBM SCSI Adapter w/Cache
      - IBM SCSI Adapter
      - IBM Integrated SCSI Controller
+     - All clones, 100% compatible with the chipset and subsystem command
+       system of IBM SCSI-adapters (forced detection)
      
    2.14 Linux Kernel Versions
    --------------------------
    The IBM SCSI-subsystem low level driver is prepared to be used with
-   all versions of Linux between 2.0.x and 2.2.x. The compatibility checks
+   all versions of Linux between 2.0.x and 2.4.x. The compatibility checks
    are fully implemented up from version 3.1e of the driver. This means, that
    you just need the latest ibmmca.h and ibmmca.c file and copy it in the
    linux/drivers/scsi directory. The code is automatically adapted during 
       addition more flexibility.
    - Michael Lang
 
+   Apr 23, 2000 (v3.2pre1)
+   1) During a very long time, I collected a huge amount of bugreports from
+      various people, trying really quite different things on their SCSI-
+      PS/2s. Today, all these bugreports are taken into account and should be
+      mostly solved. The major topics were:
+      - Driver crashes during boottime by no obvious reason.
+      - Driver panics while the midlevel-SCSI-driver is trying to inquire
+        the SCSI-device properties, even though hardware is in perfect state.
+      - Displayed info for the various slot-cards is interpreted wrong.
+      The main reasons for the crashes were two:
+      1) The commands to check for device information like INQUIRY, 
+         TEST_UNIT_READY, REQUEST_SENSE and MODE_SENSE cause the devices
+        to deliver information of up to 255 bytes. Midlevel drivers offer
+        1024 bytes of space for the answer, but the IBM-SCSI-adapters do
+        not accept this, as they stick quite near to ANSI-SCSI and report
+        a COMMAND_ERROR message which causes the driver to panic. The main
+        problem was located around the INQUIRY command. Now, for all the
+        mentioned commands, the buffersize, sent to the adapter is at 
+        maximum 255 which seems to be a quite reasonable solution. 
+        TEST_UNIT_READY gets a buffersize of 0 to make sure, that no 
+        data is transferred in order to avoid any possible command failure.
+      2) On unsuccessful TEST_UNIT_READY, the midlevel-driver has to send
+         a REQUEST_SENSE in order to see, where the problem is located. This
+        REQUEST_SENSE may have various length in its answer-buffer. IBM
+        SCSI-subsystems report a command failure, if the returned buffersize
+        is different from the sent buffersize, but this can be supressed by
+        a special bit, which is now done and problems seem to be solved.
+   2) Code adaption to all kernel-releases. Now, the 3.2 code compiles on 
+      2.0.x, 2.1.x, 2.2.x and 2.3.x kernel releases without any code-changes.
+   3) Commandline-parameters are recognized again, even under Kernel 2.3.x or
+      higher.
+   - Michael Lang   
+
+   April 27, 2000 (v3.2pre2)
+   1) Bypassed commands get read by the adapter by one cycle instead of two.
+      This increases SCSI-performance.
+   2) Synchronous datatransfer is provided for sure to be 5 MHz on older
+      SCSI and 10 MHz on internal F/W SCSI-adapter.
+   3) New commandline parameters allow to force the adapter to slow down while
+      in synchronous transfer. Could be helpful for very old devices.
+   - Michael Lang
+   
+   June 2, 2000 (v3.2pre5)
+   1) Added Jim Shorney's contribution to make the activity indicator
+      flashing in addition to the LED-alphanumeric display-panel on
+      models 95A. To be enabled to choose this feature freely, a new
+      commandline parameter is added, called 'activity'.
+   2) Added the READ_CONTROL bit for test_unit_ready SCSI-command.
+   3) Added some suppress_exception bits to read_device_capacity and
+      all device_inquiry occurences in the driver code.
+   4) Complaints about the various KERNEL_VERSION implementations are
+      taken into account. Every local_LinuxKernelVersion occurence is
+      now replaced by KERNEL_VERSION, defined in linux/version.h. 
+      Corresponding changes were applied to ibmmca.h, too. This was a
+      contribution to all kernel-parts by Philipp Hahn.
+   - Michael Lang
+   
+   July 17, 2000 (v3.2pre8)
+   A long period of collecting bugreports from all corners of the world
+   now lead to the following corrections to the code:
+   1) SCSI-2 F/W support crashed with a COMMAND ERROR. The reason for this 
+      was, that it is possible to disbale Fast-SCSI for the external bus.
+      The feature-control command, where this crash appeared regularly tried
+      to set the maximum speed of 10MHz synchronous transfer speed and that
+      reports a COMMAND ERROR, if external bus Fast-SCSI is disabled. Now,
+      the feature-command probes down from maximum speed until the adapter 
+      stops to complain, which is at the same time the maximum possible
+      speed selected in the reference program. So, F/W external can run at
+      5 MHz (slow-) or 10 MHz (fast-SCSI). During feature probing, the 
+      COMMAND ERROR message is used to detect if the adapter does not complain.
+   2) Up to now, only combined busmode is supported, if you use external
+      SCSI-devices, attached to the F/W-controller. If dual bus is selected,
+      only the internal SCSI-devices get accessed by Linux. For most 
+      applications, this should do fine. 
+   3) Wide-SCSI-addressing (16-Bit) is now possible for the internal F/W
+      bus on the F/W adapter. If F/W adapter is detected, the driver
+      automatically uses the extended PUN/LUN <-> LDN mapping tables, which
+      are now new from 3.2pre8. This allows PUNs between 0 and 15 and should
+      provide more fun with the F/W adapter.
+   4) Several machines use the SCSI: POS registers for internal/undocumented
+      storage of system relevant info. This confused the driver, mainly on
+      models 9595, as it expected no onboard SCSI only, if all POS in
+      the integrated SCSI-area are set to 0x00 or 0xff. Now, the mechanism
+      to check for integrated SCSI is much more restrictive and these problems
+      should be history.
+   - Michael Lang          
+
+   July 18, 2000 (v3.2pre9)
+   This develop rather quickly at the moment. Two major things were still
+   missing in 3.2pre8:
+   1) The adapter PUN for F/W adapters has 4-bits, while all other adapters
+      have 3-bits. This is now taken into account for F/W.
+   2) When you select CONFIG_IBMMCA_SCSI_ORDER_STANDARD, you should 
+      normally get the inverse probing order of your devices on the SCSI-bus.
+      The ANSI device order gets scrambled in version 3.2pre8!! Now, a new
+      and tested algorithm inverts the device-order on the SCSI-bus and
+      automatically avoids accidental access to whatever SCSI PUN the adapter 
+      is set and works with SCSI- and Wide-SCSI-addressing.
+   - Michael Lang
+
+   July 23, 2000 (v3.2pre10 unpublished) 
+   1) LED panel display supports wide-addressing in ibmmca=display mode.
+   2) Adapter-information and autoadaption to address-space is done.
+   3) Auto-probing for maximum synchronous SCSI transfer rate is working.
+   4) Optimization to some embedded function calls is applied.
+   5) Added some comment for the user to wait for SCSI-devices beeing probed.
+   6) Finished version 3.2 for Kernel 2.4.0. It least, I thought it is but...
+   - Michael Lang
+   
+   July 26, 2000 (v3.2pre11)
+   1) I passed a horrible weekend getting mad with NMIs on kernel 2.2.14 and
+      a model 9595. Asking around in the community, nobody except of me has
+      seen such errors. Weired, but I am trying to recompile everything on
+      the model 9595. Maybe, as I use a specially modified gcc, that could
+      cause problems. But, it was not the reason. The true background was,
+      that the kernel was compiled for i386 and the 9595 has a 486DX-2. 
+      Normally, no troubles should appear, but for this special machine,
+      only the right processor support is working fine!
+   2) Previous problems with synchronous speed, slowing down from one adapter 
+      to the next during probing are corrected. Now, local variables store
+      the synchronous bitmask for every single adapter found on the MCA bus.
+   3) LED alphanumeric panel support for XX95 systems is now showing some
+      alive rotator during boottime. This makes sense, when no monitor is 
+      connected to the system. You can get rid of all display activity, if
+      you do not use any parameter or just ibmmcascsi=activity, for the 
+      harddrive activity LED, existant on all PS/2, except models 8595-XXX.
+      If no monitor is available, please use ibmmcascsi=display, which works
+      fine together with the linuxinfo utility for the LED-panel.
+   - Michael Lang
+   
+   July 29, 2000 (v3.2)
+   1) Submission of this driver for kernel 2.4test-XX and 2.2.17.
+   - Michael Lang
+   
    4 To do
    -------
+        - IBM SCSI-2 F/W external SCSI bus support in seperate mode.
        - It seems that the handling of bad disks is really bad -
          non-existent, in fact.
         - More testing of the full driver-controlled dynamical ldn 
-          (re)mapping for up to 56 SCSI-devices.
-        - Support more of the SCSI-command set.
-       - Support some of the caching abilities, particularly Read Prefetch.
-         This fetches data into the cache, which later gets hit by the
-         regular Read Data. (<--- This is coming soon!!!!)
-        - Abort and Reset functions still slightly buggy or better say,
-         it is the new episode, called SCREAM III.
+          (re)mapping for up to 56 SCSI-devices. I guess, it won't work
+         at the moment, but nobody ever really tried it.
+        - Abort and Reset functions still slightly buggy.
 
    5 Users' Manual
    ---------------
                                
                    where '-' stays dark, 'D' shows the SCSI-device id
                    and 'A' shows the SCSI hostindex, beeing currently 
-                   accessed.
+                   accessed. During boottime, this will give the message
+                   
+                               SCSIini*
+                               
+                    on the LED-panel, where the * represents a rotator, 
+                   showing the activity during the probing phase of the
+                   driver which can take up to two minutes per SCSI-adapter.
         adisplay   This works like display, but gives more optical overview 
                    of the activities on the SCSI-bus. The display will have
                    the following output:
                    hostindex. If display nor adisplay is set, the internal
                    PS/2 harddisk LED is used for media-activities. So, if
                    you really do not have a system with a LED-display, you
-                   should not set display or adisplay.
+                   should not set display or adisplay. Keep in mind, that
+                   display and adisplay can only be used alternatively. It
+                   is not recommended to use this option, if you have some
+                   wide-addressed devices e.g. at the SCSI-2 F/W adapter in
+                   your system. In addition, the usage of the display for
+                   other tasks in parallel, like the linuxinfo-utility makes 
+                   no sense with this option.
+        activity   This enables the PS/2 harddisk LED activity indicator.
+                   Most PS/2 have no alphanumeric LED display, but some
+                   indicator. So you should use this parameter to activate it.
+                   If you own model 9595 (Server95), you can have both, the 
+                   LED panel and the activity indicator in parallel. However,
+                   some PS/2s, like the 8595 do not have any harddisk LED 
+                   activity indicator, which means, that you must use the
+                   alphanumeric LED display if you want to monitor SCSI-
+                   activity.
         bypass     This commandline parameter forces the driver never to use
                    SCSI-subsystems' integrated SCSI-command set. Except of
                    the immediate assign, which is of vital importance for
                    this flag will slow-down SCSI-accesses slightly, as the 
                    software generated commands are always slower than the 
                    hardware. Non-harddisk devices always get read/write-
-                   commands in bypass mode.
+                   commands in bypass mode. On the most recent releases of 
+                   the Linux IBM-SCSI-driver, the bypass command should be
+                   no longer a necessary thing, if you are sure about your
+                   SCSI-hardware!
         normal     This is the parameter, introduced on the 2.0.x development
                    rail by ZP Gu. This parameter defines the SCSI-device
                    scan order in the new industry standard. This means, that
                    pun=6 gets sda and a harddisk at pun=0 gets sdb. If you
                    like to have the same SCSI-device order, as in DOS, OS-9
                    or OS/2, just use this parameter.
+         fast       SCSI-I/O in synchronous mode is done at 5 MHz for IBM-
+                    SCSI-devices. SCSI-2 Fast/Wide Adapter/A external bus
+                    should then run at 10 MHz if Fast-SCSI is enabled,
+                    and at 5 MHz if Fast-SCSI is disabled on the external
+                    bus. This is the default setting when nothing is 
+                    specified here.
+         medium     Synchronous rate is at 50% approximately, which means
+                    2.5 MHz for IBM SCSI-adapters and 5.0 MHz for F/W ext.
+                    SCSI-bus (when Fast-SCSI speed enabled on external bus).
+         slow       The slowest possible synchronous transfer rate is set. 
+                    This means 1.82 MHz for IBM SCSI-adapters and 2.0 MHz
+                    for F/W external bus at Fast-SCSI speed on the external
+                   bus.
                    
    A further option is that you can force the SCSI-driver to accept a SCSI-
    subsystem at a certain I/O-address with a predefined adapter PUN. This
         ibmmcascsi=adisplay,bypass
        
    This will use the advanced display mode for the model 95 LED display and
-   every SCSI-command passed to a attached device will get bypassed in order
+   every SCSI-command passed to an attached device will get bypassed in order
    not to use any of the subsystem built-in commands.
    
         ibmmcascsi=display,0x3558,7
        with OS/2 and DOS, you have to activate this flag in the kernel
        configuration or you should set 'ansi' as parameter for the kernel.
        The parameter 'normal' sets the new industry standard, starting
-       from pun 0, scaning up to pun 6. This allows you to change your 
+       from pun 0, scanning up to pun 6. This allows you to change your 
        opinion still after having already compiled the kernel.
-     Q: Why can I not find the IBM MCA SCSI support in the config menue?
+     Q: Why I cannot find the IBM MCA SCSI support in the config menue?
      A: You have to activate MCA bus support, first.
      Q: Where can I find the latest info about this driver?
      A: See the file MAINTAINERS for the current WWW-address, which offers
      A: Just force it to be recognized by kernel parameters. See section 5.1.
      Q: The driver screws up, if it starts to probe SCSI-devices, is there
         some way out of it?
-     A: This is based on some problems with the driver. In such cases, send
-        e-mail to the maintainer. If you are owner of a model with the serial
-       number 95XX, just send as subject NOTIFY 95XX PROBLEM and the 
-       maintainer immediately knows about your problem. But please:
-       Check your hardware and only if it works fine with other operating
-       systems, send E-Mail to me to notify the troubles. See the homepage
-       for how to send bug-reports or please read the next Q/A, here:
+     A: Yes, that was some recognition problem of the correct SCSI-adapter
+        and its I/O base addresses. Upgrade your driver to the latest release
+       and it should be fine again.
      Q: I get a message: panic IBM MCA SCSI: command error .... , what can
         I do against this?
      A: Previously, I followed the way by ignoring command errors by using
         ibmmcascsi=forgiveall. Are there other possibilities to prevent
        such panics?
      A: No, get just the latest release of the driver and it should work 
-        better and better with increasing version number. Forget this
-       ibmmcascsi=forgiveall, as also ignorecmd are obsolete.
+        better and better with increasing version number. Forget about this
+       ibmmcascsi=forgiveall, as also ignorecmd are obsolete.!
      Q: Linux panics or stops without any comment, but it is probable, that my
         harddisk(s) have bad blocks.
      A: Sorry, the bad-block handling is still a feeble point of this driver,
        Astonishingly, reset works in most cases quite ok, but the harddisks
        won't run in synchonous mode anymore after a reset, until you reboot.
      Q: Why does my XXX w/Cache adapter not use read-prefetch?
-     A: w/Cache technical manuals are incoming here, so if I understood the
-        command of read-prefetch, it should be an easy thing to get harddisks
-       read in read-prefetch with w/Cache controllers. Some weeks or months,
-       still ahead and a lot of work still to do, sigh ...
+     A: Ok, that is not completely possible. If a cache is present, the 
+        adapter tries to use it internally. Explicitly, one can use the cache
+       with a read prefetch command, maybe in future, but this requires
+       some major overhead of SCSI-commands that risks the performance to
+       go down more than it gets improved. Tests with that are running.
+     Q: I have a IBM SCSI-2 Fast/Wide adapter, it boots in some way and hangs.
+     A: Yes, that is understood, as for sure, your SCSI-2 Fast/Wide adapter
+        was in such a case recognized as integrated SCSI-adapter or something 
+       else, but not as the correct adapter. As the I/O-ports get assigned 
+       wrongly by that reason, the system should crash in most cases. You 
+       should upgrade to the latest release of the SCSI-driver. The 
+       recommended version is 3.2 or later. Here, the F/W support is in
+       a stable and reliable condition. Wide-addressing is in addition 
+       supported.
+     Q: I get a Ooops message and something like "killing interrupt".
+     A: The reason for this is that the IBM SCSI-subsystem only sends a 
+        termination status back, if some error appeared. In former releases
+       of the driver, it was not checked, if the termination status block
+       is NULL. From version 3.2, it is taken care of this.
+     Q: I have a F/W adapter and the driver sees my internal SCSI-devices,
+        but ignores the external ones.
+     A: Select combined busmode in the config-program and check for that
+        no SCSI-id on the external devices appears on internal devices.
+        Reboot afterwards. Dual busmode is supported, but works only for the
+       internal bus, yet. External bus is still ignored. Take care for your
+       SCSI-ids. If combined bus-mode is activated, on some adapters, 
+       the wide-addressing is not possible, so devices with ids between 8 
+       and 15 get ignored by the driver & adapter!
+     Q: I have a 9595 and I get a NMI during heavy SCSI I/O e.g. during fsck.
+        A COMMAND ERROR is reported and characters on the screen are missing.
+       Warm reboot is not possible. Things look like quite weired.
+     A: Check the processor type of your 9595. If you have an 80486 or 486DX-2
+        processor complex on your mainboard and you compiled a kernel that
+       supports 80386 processors, it is possible, that the kernel cannot
+       keep track of the PS/2 interrupt handling and stops on an NMI. Just
+       compile a kernel for the correct processor type of your PS/2 and
+       everything should be fine. This is necessary even if one assumes,
+       that some 80486 system should be downward compatible to 80386
+       software.
        
    5.3 Bugreports
    --------------
    Zubkoff, as Linus is burried in E-Mail and Leonard is supervising all
    SCSI-drivers and won't have the time left to look inside every single
    driver to fix a bug and especially DO NOT send modified code to Linus
-   Torvalds, which has not been checked here!!! Recently, I got a lot of 
+   Torvalds or Alan J. Cox which has not been checked here!!! They are both
+   quite burried in E-mail (as me, sometimes, too) and one should first check
+   for problems on my local teststand. Recently, I got a lot of 
    bugreports for errors in the ibmmca.c code, which I could not imagine, but
    a look inside some Linux-distribution showed me quite often some modified
    code, which did no longer work on most other machines than the one of the
         http://www.uni-mainz.de/~langm000/linux.html
        
    Here you can find info about the background of this driver, patches,
-   news and a bugreport form.
+   troubleshooting support, news and a bugreport form. Please check that
+   WWW-page regularly for latest hints.
+   
+   For the bugreport, please fill out the formular on the corresponding
+   WWW-page. Read the dedicated instructions and write as much as you
+   know about your problem. If you do not like such formulars, please send
+   some e-mail directly, but at least with the same information as required by
+   the formular.
+   
+   If you have extensive bugreports, including Ooops messages and 
+   screen-shots, please feel free to send it directly to the address
+   of the maintainer, too. The current address of the maintainer is:
+   
+            Michael Lang <langa2@kph.uni-mainz.de>
    
    6 References
    ------------
-   The source of information is "Update for the PS/2 Hardware 
-   Interface Technical Reference, Common Interfaces", September 1991, 
-   part number 04G3281, available in the U.S. for $21.75 at 
-   1-800-IBM-PCTB, elsewhere call your local friendly IBM 
-   representative. E.g. in Germany, "Hallo IBM" works really great.
-   In addition to SCSI subsystem, this update contains fairly detailed 
-   (at hardware register level) sections on diskette  controller,
-   keyboard controller, serial port controller, VGA, and XGA.
+   IBM Corp., "Update for the PS/2 Hardware Interface Technical Reference, 
+   Common Interfaces", Armonk, September 1991, PN 04G3281, 
+   (available in the U.S. for $21.75 at 1-800-IBM-PCTB or in Germany for
+   around 40,-DM at "Hallo IBM").
   
-   Additional information from "Personal System/2 Micro Channel SCSI
-   Adapter with Cache Technical Reference", March 1990, PN 68X2365,
-   probably available from the same source (or possibly found buried
-   in officemates desk).
+   IBM Corp., "Personal System/2 Micro Channel SCSI
+   Adapter with Cache Technical Reference", Armonk, March 1990, PN 68X2365.
+
+   IBM Corp., "Personal System/2 Micro Channel SCSI
+   Adapter Technical Reference", Armonk, March 1990, PN 68X2397.
+
+   IBM Corp., "SCSI-2 Fast/Wide Adapter/A Technical Reference - Dual Bus",
+   Armonk, March 1994, PN 83G7545.
  
    Friedhelm Schmidt, "SCSI-Bus und IDE-Schnittstelle - Moderne Peripherie-
    Schnittstellen: Hardware, Protokollbeschreibung und Anwendung", 2. Aufl.
    Helmut Rompel, "IBM Computerwelt GUIDE", What is what bei IBM., Systeme *
    Programme * Begriffe, IWT-Verlag GmbH - Muenchen, 1988
    
-   7 Trademarks
+   7 Credits to
+   ------------
+   7.1 People
+   ----------
+   Klaus Grimm
+                who already a long time ago gave me the old code from the
+               SCSI-driver in order to get it running for some old machine
+               in our institute.
+   Martin Kolinek
+                who wrote the first release of the IBM SCSI-subsystem driver.
+   Chris Beauregard
+                who for a long time maintained MCA-Linux and the SCSI-driver
+               in the beginning. Chris, wherever you are: Cheers to you!
+   Klaus Kudielka
+                with whom in the 2.1.x times, I had a quite fruitful
+                cooperation to get the driver running as a module and to get
+               it running with multiple SCSI-adapters.
+   David Weinehall
+                for his excellent maintenance of the MCA-stuff and the quite 
+               detailed bug reports and ideas for this driver (and his 
+               patience ;-)).
+   Alan J. Cox  
+                for his bugreports and his bold activities in cross-checking
+               the driver-code with his teststand.
+               
+   7.2 Sponsors & Supporters
+   -------------------------
+   "Hallo IBM",
+   IBM-Deutschland GmbH
+                the service of IBM-Deutschland for customers. Their E-Mail
+               service is unbeatable. Whatever old stuff I asked for, I 
+               always got some helpful answers.
+   Karl-Otto Reimers,
+   IBM Klub - Sparte IBM Geschichte, Sindelfingen
+                for sending me a copy of the w/Cache manual from the 
+               IBM-Deutschland archives.
+   Harald Staiger
+                for his extensive hardware donations which allows me today
+               still to test the driver in various constellations.
+   Erich Fritscher
+                for his very kind sponsoring.
+   Louis Ohland,
+   Charles Lasitter
+                for support by shipping me an IBM SCSI-2 Fast/Wide manual.
+                In addition, the contribution of various hardware is quite 
+                decessive and will make it possible to add FWSR (RAID)
+                adapter support to the driver in the near future! So,
+                complaints about no RAID support won't remain forever.
+                Yes, folks, that is no joke, RAID support is going to rise!
+   Erik Weber
+                for the great deal we made about a model 9595 and the nice
+                surrounding equipment and the cool trip to Mannheim
+                second-hand computer market.
+   Anthony Hogbin
+                for his direct shipment of a SCSI F/W adapter, which allowed
+                me immediately on the first stage to try it on model 8557
+                together with onboard SCSI adapter and some SCSI w/Cache.
+   Andreas Hotz
+                for his support by memory and an IBM SCSI-adapter. Collecting
+                all this together now allows me to try really things with
+                the driver at maximum load and variety on various models in
+                a very quick and efficient way.
+   Peter Jennewein
+                for his model 30, which serves me as part of my teststand
+               and his cool remark about how you make an ordinary diskette
+               drive working and how to connect it to an IBM-diskette port.
+   Johannes Gutenberg-University, Mainz &
+   Institut fuer Kernphysik, MAMI
+                for the offered space, the link, placed on the central
+                homepage and the space to store and offer the driver and 
+               related material and the free working times, which allow
+                me to answer all your e-mail.
+                   
+   8 Trademarks
    ------------
    IBM, PS/2, OS/2, Microchannel are registered trademarks of International 
-   Business Machines Corp.
+   Business Machines Corporation
    
    MS-DOS is a registered trademark of Microsoft Corporation
    
-   OS-9 is a registered trademark of Microware Systems
+   Microware, OS-9 are registered trademarks of Microware Systems
+   
+   9 Disclaimer
+   ------------
+   Beside the GNU public license and the dependant disclaimers and disclaimers
+   concerning the Linux-kernel in special, this SCSI-driver comes without any
+   warranty. Its functionality is tested as good as possible on certain 
+   machines and combinations of computer hardware, which does not exclude,
+   that dataloss or severe damage of hardware is possible while using this
+   part of software on some arbitrary computer hardware or in combination 
+   with other software packages. It is highly recommended to make backup
+   copies of your data before using this software.
+   
+   This driver supports hardware, produced by International Business Machines
+   Corporation (IBM).
    
 ------
 Michael Lang 
index 393cf909e4099ba90d8f7456ce4803d4a96ad08a..aa4cca39018e5f58cfb0e59812d81390f9b257f7 100644 (file)
@@ -7,7 +7,7 @@
  * See the file README.ibmmca for a detailed description of this driver,
  * the commandline arguments and the history of its development.
  * See the WWW-page: http://www.uni-mainz.de/~langm000/linux.html for latest
- * updates and info.
+ * updates, info and ADF-files for adapters supported by this driver.
  */
 
 /******************* HEADER FILE INCLUDES ************************************/
 #endif
 
 /* choose adaption for Kernellevel */
-#define local_LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,65)
+#define OLDKERN
+#else
+#undef OLDKERN
+#endif
 
-#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/ctype.h>
 #include <linux/stat.h>
 #include <linux/mca.h>
 #include <asm/system.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17)
 #include <linux/spinlock.h>
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
+#include <asm/spinlock.h>
+#endif
 #include <asm/io.h>
+#include <linux/init.h>
 #include "sd.h"
 #include "scsi.h"
 #include "hosts.h"
@@ -42,6 +50,7 @@
 
 /******************* LOCAL DEFINES *******************************************/
 
+/* milliseconds of delay for timing out reset. */
 #ifndef mdelay
 #define mdelay(a)    udelay((a) * 1000)
 #endif
@@ -49,7 +58,7 @@
 /*--------------------------------------------------------------------*/
 
 /* current version of this driver-source: */
-#define IBMMCA_SCSI_DRIVER_VERSION "3.1e"
+#define IBMMCA_SCSI_DRIVER_VERSION "3.2"
 
 /*--------------------------------------------------------------------*/
 
 /* driver debugging - #undef all for normal operation */
 
 /* if defined: count interrupts and ignore this special one: */
-#undef  IM_DEBUG_TIMEOUT  50
+#undef  IM_DEBUG_TIMEOUT  50            
 #define TIMEOUT_PUN   0
 #define TIMEOUT_LUN   0
 /* verbose interrupt: */
-#undef  IM_DEBUG_INT
+#undef  IM_DEBUG_INT                   
 /* verbose queuecommand: */
-#undef  IM_DEBUG_CMD
+#undef  IM_DEBUG_CMD    
 /* verbose queucommand for specific SCSI-device type: */
-#undef  IM_DEBUG_CMD_SPEC_DEV
+#undef  IM_DEBUG_CMD_SPEC_DEV          
 /* verbose device probing */
-#undef  IM_DEBUG_PROBE
+#define  IM_DEBUG_PROBE
 
 /* device type that shall be displayed on syslog (only during debugging): */
 #define IM_DEBUG_CMD_DEVICE   TYPE_TAPE
 /*note: the lower nibble specifies the device(0-14), or subsystem(15) */
 #define IM_SCB_CMD_COMPLETED               0x10
 #define IM_SCB_CMD_COMPLETED_WITH_RETRIES  0x50
+#define IM_LOOP_SCATTER_BUFFER_FULL        0x60
 #define IM_ADAPTER_HW_FAILURE              0x70
 #define IM_IMMEDIATE_CMD_COMPLETED         0xa0
 #define IM_CMD_COMPLETED_WITH_FAILURE      0xc0
@@ -146,7 +156,7 @@ struct im_scb
            unsigned short length;      /*block length, on SCSI device */
          }
        blk;
-       unsigned char scsi_command[12];         /*other scsi command */
+       unsigned char scsi_command[12];    /*other scsi command */
       }
     u2;
   };
@@ -158,6 +168,31 @@ struct im_sge
     unsigned long byte_length;
   };
 
+/*structure returned by a get_pos_info command: */
+struct im_pos_info
+  {
+     unsigned short pos_id;         /* adapter id */
+     unsigned char pos_3a;          /* pos 3 (if pos 6 = 0) */
+     unsigned char pos_2;           /* pos 2 */
+     unsigned char int_level;       /* interrupt level IRQ 11 or 14 */
+     unsigned char pos_4a;          /* pos 4 (if pos 6 = 0) */
+     unsigned short connector_size; /* MCA connector size: 16 or 32 Bit */
+     unsigned char num_luns;        /* number of supported luns per device */
+     unsigned char num_puns;        /* number of supported puns */
+     unsigned char pacing_factor;   /* pacing factor */
+     unsigned char num_ldns;        /* number of ldns available */
+     unsigned char eoi_off;         /* time EOI and interrupt inactive */
+     unsigned char max_busy;        /* time between reset and busy on */
+     unsigned short cache_stat;     /* ldn cachestat. Bit=1 = not cached */
+     unsigned short retry_stat;     /* retry status of ldns. Bit=1=disabled */
+     unsigned char pos_4b;          /* pos 4 (if pos 6 = 1) */
+     unsigned char pos_3b;          /* pos 3 (if pos 6 = 1) */
+     unsigned char pos_6;           /* pos 6 */
+     unsigned char pos_5;           /* pos 5 */ 
+     unsigned short max_overlap;    /* maximum overlapping requests */
+     unsigned short num_bus;        /* number of SCSI-busses */
+  };
+
 /*values for SCB command word */
 #define IM_NO_SYNCHRONOUS      0x0040  /*flag for any command */
 #define IM_NO_DISCONNECT       0x0080  /*flag for any command */
@@ -168,6 +203,7 @@ struct im_sge
 #define IM_REQUEST_SENSE_CMD   0x1c08
 #define IM_READ_CAPACITY_CMD   0x1c09
 #define IM_DEVICE_INQUIRY_CMD  0x1c0b
+#define IM_READ_LOGICAL_CMD    0x1c2a
 #define IM_OTHER_SCSI_CMD_CMD  0x241f
 
 /* unused, but supported, SCB commands */
@@ -183,6 +219,7 @@ struct im_sge
 #define IM_RETRY_ENABLE              0x2000
 #define IM_POINTER_TO_LIST           0x1000
 #define IM_SUPRESS_EXCEPTION_SHORT   0x0400
+#define IM_BYPASS_BUFFER             0x0200
 #define IM_CHAIN_ON_NO_ERROR         0x0001
 
 /*TSB (Termination Status Block) structure */
@@ -204,15 +241,17 @@ struct im_tsb
   };
 
 /*subsystem uses interrupt request level 14 */
-#define IM_IRQ  14
+#define IM_IRQ     14
+/*SCSI-2 F/W may evade to interrupt 11 */
+#define IM_IRQ_FW  11
 
 /*--------------------------------------------------------------------*/
 /*
        The model 95 doesn't have a standard activity light.  Instead it
-       has a row of LEDs on the front.  We use the last one as the activity
-       indicator if we think we're on a model 95.  I suspect the model id
-       check will be either too narrow or too general, and some machines
-       won't have an activity indicator.  Oh well...
+       has a row of alphanumerial LEDs on the front.  We use the last one 
+        as the activity indicator if we think we're on a model 95.  I suspect
+        the model id check will be either too narrow or too general, and some 
+        machines won't have an activity indicator.  Oh well...
 
        The regular PS/2 disk led is turned on/off by bits 6,7 of system
        control port.
@@ -222,6 +261,12 @@ struct im_tsb
 #define MOD95_LED_PORT    0x108
 /* system-control-register of PS/2s with diskindicator */
 #define PS2_SYS_CTR        0x92
+/* activity displaying methods */
+#define LED_DISP           1
+#define LED_ADISP          2
+#define LED_ACTIVITY       4
+
+#define CMD_FAIL           255
 
 /* The SCSI-ID(!) of the accessed SCSI-device is shown on PS/2-95 machines' LED
    displays. ldn is no longer displayed here, because the ldn mapping is now 
@@ -230,30 +275,39 @@ struct im_tsb
    interest, debugging or just for having fun. The left number gives the
    host-adapter number and the right shows the accessed SCSI-ID. */
 
-/* use_display is set by the ibmmcascsi=display command line arg */
-static int use_display = 0;
-/* use_adisplay is set by ibmmcascsi=adisplay, which offers a higher
- * level of displayed luxus on PS/2 95 (really fancy! :-))) */
-static int use_adisplay = 0;
-
+/* display_mode is set by the ibmmcascsi= command line arg */
+static int display_mode = 0;
+/* set default adapter timeout */
+static unsigned int adapter_timeout = 45;
+/* for probing on feature-command: */
+static unsigned int global_command_error_excuse = 0;
+/* global setting by command line for adapter_speed */
+static int global_adapter_speed = 0; /* full speed by default */
+
+/* Panel / LED on, do it right for F/W addressin, too. adisplay will
+ * just ignore ids>7, as the panel has only 7 digits available */
 #define PS2_DISK_LED_ON(ad,id) {\
-       if( use_display ) { outb((char)(id+48), MOD95_LED_PORT ); \
-        outb((char)(ad+48), MOD95_LED_PORT+1); } \
-        else if( use_adisplay ) { if (id<7) outb((char)(id+48), \
-       MOD95_LED_PORT+1+id); outb((char)(ad+48), MOD95_LED_PORT); } \
-       else outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR); \
+        if (display_mode & LED_DISP) { \
+           if (id>9) \
+            outw((ad+48)|((id+55)<<8), MOD95_LED_PORT ); \
+           else \
+             outw((ad+48)|((id+48)<<8), MOD95_LED_PORT ); } \
+        else if (display_mode & LED_ADISP) { \
+           if (id<7) outb((char)(id+48),MOD95_LED_PORT+1+id); \
+           outb((char)(ad+48), MOD95_LED_PORT); } \
+        if ((display_mode & LED_ACTIVITY)||(!display_mode)) \
+           outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR); \
 }
-
+/* Panel / LED off */
 /* bug fixed, Dec 15, 1997, where | was replaced by & here */
 #define PS2_DISK_LED_OFF() {\
-       if( use_display ) { outb( ' ', MOD95_LED_PORT ); \
-        outb(' ', MOD95_LED_PORT+1); } \
-        if ( use_adisplay ) { outb(' ',MOD95_LED_PORT ); \
-       outb(' ',MOD95_LED_PORT+1); outb(' ',MOD95_LED_PORT+2); \
-        outb(' ',MOD95_LED_PORT+3); outb(' ',MOD95_LED_PORT+4); \
-        outb(' ',MOD95_LED_PORT+5); outb(' ',MOD95_LED_PORT+6); \
-       outb(' ',MOD95_LED_PORT+7); } \
-       else outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); \
+       if (display_mode & LED_DISP) \
+           outw(0x2020, MOD95_LED_PORT ); \
+        else if (display_mode & LED_ADISP) { \
+           outl(0x20202020,MOD95_LED_PORT); \
+           outl(0x20202020,MOD95_LED_PORT+4); } \
+       if ((display_mode & LED_ACTIVITY)||(!display_mode)) \
+           outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); \
 }
 
 /*--------------------------------------------------------------------*/
@@ -265,15 +319,37 @@ struct subsys_list_struct
     char *description;
   };
 
+/* types of different supported hardware that goes to hostdata special */
+#define IBM_SCSI2_FW     0
+#define IBM_7568_WCACHE  1
+#define IBM_EXP_UNIT     2
+#define IBM_SCSI_WCACHE  3
+#define IBM_SCSI         4
+
+/* other special flags for hostdata structure */
+#define FORCED_DETECTION         100
+#define INTEGRATED_SCSI          101
+
 /* List of possible IBM-SCSI-adapters */
 struct subsys_list_struct subsys_list[] =
 {
-  {0x8efc, "IBM Fast SCSI-2 Adapter"}, /* special = 0 */
-  {0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/cache"}, /* special = 1 */
+  {0x8efc, "IBM SCSI-2 F/W Adapter"}, /* special = 0 */
+  {0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/Cache"}, /* special = 1 */
   {0x8ef8, "IBM Expansion Unit SCSI Controller"},/* special = 2 */
   {0x8eff, "IBM SCSI Adapter w/Cache"}, /* special = 3 */
   {0x8efe, "IBM SCSI Adapter"}, /* special = 4 */
+};                   
+
+/*for /proc filesystem, only valid in older kernel releases */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,27)
+struct proc_dir_entry proc_scsi_ibmmca =
+{
+  PROC_SCSI_IBMMCA, 6, "ibmmca",
+  S_IFDIR | S_IRUGO | S_IXUGO, 2,
+  0, 0, 0, NULL, NULL, NULL, NULL,
+  NULL, NULL, NULL 
 };
+#endif
 
 /* Max number of logical devices (can be up from 0 to 14).  15 is the address
 of the adapter itself. */
@@ -286,11 +362,12 @@ struct logical_device
     struct im_tsb tsb; /* SCSI command complete status block structure */
     struct im_sge sge[16]; /* scatter gather list structure */
     unsigned char buf[256]; /* SCSI command return data buffer */
-    Scsi_Cmnd *cmd;  /* SCSI-command that is currently in progress */
-
+    Scsi_Cmnd *cmd;  /* SCSI-command that is currently in progress */     
     int device_type; /* type of the SCSI-device. See include/scsi/scsi.h
                        for interpretation of the possible values */
     int block_length;/* blocksize of a particular logical SCSI-device */
+    int cache_flag; /* 1 if this is uncached, 0 if cache is present for ldn */
+    int retry_flag; /* 1 if adapter retry is disabled, 0 if enabled */
   };
 
 /* statistics of the driver during operations (for proc_info) */
@@ -302,6 +379,8 @@ struct Driver_Statistics
       int ldn_write_access[MAX_LOG_DEV+1];   /* total write-access on a ldn */
       int ldn_inquiry_access[MAX_LOG_DEV+1]; /* total inquiries on a ldn */
       int ldn_modeselect_access[MAX_LOG_DEV+1]; /* total mode selects on ldn */
+      int scbs;                              /* short SCBs queued */
+      int long_scbs;                         /* long SCBs queued */
       int total_accesses;                    /* total accesses on all ldns */
       int total_interrupts;                  /* total interrupts (should be
                                                same as total_accesses) */
@@ -318,12 +397,12 @@ struct Driver_Statistics
 struct ibmmca_hostdata
 {
    /* array of logical devices: */
-   struct logical_device _ld[MAX_LOG_DEV+1];
+   struct logical_device _ld[MAX_LOG_DEV+1];   
    /* array to convert (pun, lun) into logical device number: */
-   unsigned char _get_ldn[8][8];
+   unsigned char _get_ldn[16][8];
    /*array that contains the information about the physical SCSI-devices
     attached to this host adapter: */
-   unsigned char _get_scsi[8][8];
+   unsigned char _get_scsi[16][8];
    /* used only when checking logical devices: */
    int _local_checking_phase_flag;
    /* report received interrupt: */
@@ -336,21 +415,30 @@ struct ibmmca_hostdata
    int _last_scsi_command[MAX_LOG_DEV+1];
    /* identifier of the last SCSI-command type */
    int _last_scsi_type[MAX_LOG_DEV+1];
-   /* Counter that points on the next reassignable ldn for dynamical
-    remapping. The default value is 7, that is the first reassignable
+   /* last blockcount */
+   int _last_scsi_blockcount[MAX_LOG_DEV+1];
+   /* last locgical block address */
+   unsigned long _last_scsi_logical_block[MAX_LOG_DEV+1];
+   /* Counter that points on the next reassignable ldn for dynamical 
+    remapping. The default value is 7, that is the first reassignable 
     number in the list at boottime: */
    int _next_ldn;
    /* Statistics-structure for this IBM-SCSI-host: */
    struct Driver_Statistics _IBM_DS;
-   /* This hostadapters pos-registers pos2 and pos3 */
-   unsigned _pos2, _pos3;
+   /* This hostadapters pos-registers pos2 until pos6 */
+   unsigned _pos2, _pos3, _pos4, _pos5, _pos6;
    /* assign a special variable, that contains dedicated info about the
     adaptertype */
    int _special;
+   /* connector size on the MCA bus */
+   int _connector_size;
+   /* synchronous SCSI transfer rate bitpattern */
+   int _adapter_speed;
 };
 
 /* macros to access host data structure */
 #define subsystem_pun(hi) (hosts[(hi)]->this_id)
+#define subsystem_maxid(hi) (hosts[(hi)]->max_id)
 #define ld(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_ld)
 #define get_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_ldn)
 #define get_scsi(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_scsi)
@@ -360,13 +448,21 @@ struct ibmmca_hostdata
 #define reset_status(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_reset_status)
 #define last_scsi_command(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_command)
 #define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
+#define last_scsi_blockcount(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_blockcount)
+#define last_scsi_logical_block(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_logical_block)
+#define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
 #define next_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_next_ldn)
 #define IBM_DS(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_IBM_DS)
 #define special(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_special)
+#define subsystem_connector_size(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_connector_size)
+#define adapter_speed(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_adapter_speed)
 #define pos2(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos2)
 #define pos3(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos3)
+#define pos4(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos4)
+#define pos5(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos5)
+#define pos6(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos6)
 
-/* Define a arbitrary number as subsystem-marker-type. This number is, as
+/* Define a arbitrary number as subsystem-marker-type. This number is, as 
    described in the ANSI-SCSI-standard, not occupied by other device-types. */
 #define TYPE_IBM_SCSI_ADAPTER   0x2F
 
@@ -396,10 +492,6 @@ struct ibmmca_hostdata
 #define IM_RESET_NOT_IN_PROGRESS_NO_INT  4
 #define IM_RESET_FINISHED_OK_NO_INT      5
 
-/* special flags for hostdata structure */
-#define FORCED_DETECTION         100
-#define INTEGRATED_SCSI          101
-
 /* define undefined SCSI-command */
 #define NO_SCSI                  0xffff
 
@@ -409,22 +501,40 @@ struct ibmmca_hostdata
 static int io_port[IM_MAX_HOSTS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 static int scsi_id[IM_MAX_HOSTS] = { 7, 7, 7, 7, 7, 7, 7, 7 };
 
+/* fill module-parameters only, when this define is present.
+   (that is kernel version 2.1.x) */
+#if defined(MODULE)
+static char *boot_options = NULL;
+#include <linux/module.h>
+MODULE_PARM(boot_options, "s");
+MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
+MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i"); 
+MODULE_PARM(display, "1i");
+MODULE_PARM(adisplay, "1i");
+MODULE_PARM(bypass, "1i");
+MODULE_PARM(normal, "1i");
+MODULE_PARM(ansi, "1i");
+#endif
 
 /*counter of concurrent disk read/writes, to turn on/off disk led */
 static int disk_rw_in_progress = 0;
 
 /* spinlock handling to avoid command clash while in operation */
+#ifndef OLDKERN
 spinlock_t info_lock  = SPIN_LOCK_UNLOCKED;
 spinlock_t proc_lock  = SPIN_LOCK_UNLOCKED;
 spinlock_t abort_lock = SPIN_LOCK_UNLOCKED;
 spinlock_t reset_lock = SPIN_LOCK_UNLOCKED;
 spinlock_t issue_lock = SPIN_LOCK_UNLOCKED;
 spinlock_t intr_lock  = SPIN_LOCK_UNLOCKED;
+#endif
 
 /* host information */
 static int found = 0;
-static struct Scsi_Host *hosts[IM_MAX_HOSTS+1] = { NULL };
-static unsigned int pos[8]; /* whole pos register-line */
+static struct Scsi_Host *hosts[IM_MAX_HOSTS+1] = { NULL, NULL, NULL, NULL, 
+                                                   NULL, NULL, NULL, NULL,
+                                                   NULL };
+static unsigned int pos[8]; /* whole pos register-line for diagnosis */
 /* Taking into account the additions, made by ZP Gu.
  * This selects now the preset value from the configfile and
  * offers the 'normal' commandline option to be accepted */
@@ -439,32 +549,40 @@ static char ibm_ansi_order = 0;
 /******************* FUNCTIONS IN FORWARD DECLARATION ************************/
 
 static void interrupt_handler (int, void *, struct pt_regs *);
+#ifndef OLDKERN
 static void do_interrupt_handler (int, void *, struct pt_regs *);
+#endif
 static void issue_cmd (int, unsigned long, unsigned char);
 static void internal_done (Scsi_Cmnd * cmd);
-static void check_devices (int);
-static int immediate_assign(int, unsigned int, unsigned int, unsigned int,
+static void check_devices (int, int);
+static int immediate_assign(int, unsigned int, unsigned int, unsigned int, 
                             unsigned int);
+static int immediate_feature(int, unsigned int, unsigned int);
 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
 static int immediate_reset(int, unsigned int);
 #endif
 static int device_inquiry(int, int);
 static int read_capacity(int, int);
+static int get_pos_info(int);
 static char *ti_p(int);
 static char *ti_l(int);
+static char *ibmrate(unsigned int, int);
+static int probe_display(int);
+static int probe_bus_mode(int);
 static int device_exists (int, int, int *, int *);
 static struct Scsi_Host *ibmmca_register(Scsi_Host_Template *,
-                                        int, int, char *);
-
+                                        int, int, int, char *);
 /* local functions needed for proc_info */
 static int ldn_access_load(int, int);
 static int ldn_access_total_read_write(int);
 
 static int bypass_controller = 0;   /* bypass integrated SCSI-cmd set flag */
+
 /*--------------------------------------------------------------------*/
 
 /******************* LOCAL FUNCTIONS IMPLEMENTATION *************************/
 
+#ifndef OLDKERN
 /* newer Kernels need the spinlock interrupt handler */
 static void do_interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -473,8 +591,9 @@ static void do_interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
   spin_lock_irqsave(&io_request_lock, flags);
   interrupt_handler(irq, dev_id, regs);
   spin_unlock_irqrestore(&io_request_lock, flags);
-  return;
+  return; 
 }
+#endif
 
 static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -482,20 +601,17 @@ static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
    unsigned int intr_reg;
    unsigned int cmd_result;
    unsigned int ldn;
-   static unsigned long flags;
+   unsigned long flags;
    Scsi_Cmnd *cmd;
-   int errorflag;
-   int interror;
-
-   host_index=0; /* make sure, host_index is 0, else this won't work and
-                   never dare to ask, what happens, if an interrupt-handler
-                   does not work :-((( .... */
+   int lastSCSI;
+   
+   host_index = 0; /* make sure, host_index is 0 */
 
    /* search for one adapter-response on shared interrupt */
    while (hosts[host_index]
          && !(inb(IM_STAT_REG(host_index)) & IM_INTR_REQUEST))
      host_index++;
-
+      
    /* return if some other device on this IRQ caused the interrupt */
    if (!hosts[host_index]) return;
 
@@ -507,88 +623,126 @@ static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
        reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS;
        return;
      }
-
-   /*get command result and logical device */
-   intr_reg = inb (IM_INTR_REG(host_index));
-   cmd_result = intr_reg & 0xf0;
-   ldn = intr_reg & 0x0f;
-
+   
    /*must wait for attention reg not busy, then send EOI to subsystem */
-   while (1)
+   while (1) 
      {
+#ifdef OLDKERN
+       save_flags(flags);
+       cli();
+#else
        spin_lock_irqsave(&intr_lock, flags);
-       if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
+#endif 
+       /* if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY)) */
+       if ((inb(IM_STAT_REG(host_index)) & 0xf) == (IM_CMD_REG_EMPTY | IM_INTR_REQUEST))
          break;
+#ifdef OLDKERN 
+       restore_flags(flags);
+#else
        spin_unlock_irqrestore(&intr_lock, flags);
+#endif
      }
-   outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
+   /*get command result and logical device */
+   intr_reg = (unsigned char)(inb (IM_INTR_REG(host_index)));
+   cmd_result = intr_reg & 0xf0;
+   ldn = intr_reg & 0x0f;
+
    /* get the last_scsi_command here */
-   interror = last_scsi_command(host_index)[ldn];
-   spin_unlock_irqrestore(&intr_lock, flags);
-   errorflag = 0; /* no errors by default */
+   lastSCSI = last_scsi_command(host_index)[ldn];
+   
    /*these should never happen (hw fails, or a local programming bug) */
-   if (cmd_result == IM_ADAPTER_HW_FAILURE)
-     {
-       printk("\n");
-       printk("IBM MCA SCSI: ERROR - subsystem hardware failure!\n");
-       printk("              Last SCSI-command=0x%X, ldn=%d, host=%d.\n",
-              last_scsi_command(host_index)[ldn],ldn,host_index);
-       errorflag = 1;
-     }
-   if (cmd_result == IM_SOFTWARE_SEQUENCING_ERROR)
-     {
-       printk("\n");
-       printk("IBM MCA SCSI: ERROR - software sequencing error!\n");
-       printk("              Last SCSI-command=0x%X, ldn=%d, host=%d.\n",
-              last_scsi_command(host_index)[ldn],ldn,host_index);
-       errorflag = 1;
-     }
-   if (cmd_result == IM_CMD_ERROR)
-     {
-       printk("\n");
-       printk("IBM MCA SCSI: ERROR - command error!\n");
-       printk("              Last SCSI-command=0x%X, ldn=%d, host=%d.\n",
-              last_scsi_command(host_index)[ldn],ldn,host_index);
-       errorflag = 1;
+   if (!global_command_error_excuse)
+     { 
+       switch (cmd_result)
+         { /* Prevent from Ooopsing on error to show the real reason */      
+          case IM_ADAPTER_HW_FAILURE:
+          case IM_SOFTWARE_SEQUENCING_ERROR:
+          case IM_CMD_ERROR:
+            printk("\nIBM MCA SCSI: Fatal Subsystem ERROR!\n");
+            printk("              Last cmd=0x%x, ena=%x, len=",lastSCSI,
+                   ld(host_index)[ldn].scb.enable);
+            if (ld(host_index)[ldn].cmd)
+              printk("%ld/%ld",(long)(ld(host_index)[ldn].cmd->request_bufflen),
+                     (long)(ld(host_index)[ldn].scb.sys_buf_length));
+            else
+              printk("none");
+            printk(", ");
+            if (ld(host_index)[ldn].cmd)
+              printk("Blocksize=%d",ld(host_index)[ldn].scb.u2.blk.length);
+            else
+              printk("Blocksize=none");
+            printk(", host=0x%x, ldn=0x%x\n",host_index, ldn);
+            if (ld(host_index)[ldn].cmd)
+              {                  
+                 printk("Blockcount=%d/%d\n",last_scsi_blockcount(host_index)[ldn],
+                        ld(host_index)[ldn].scb.u2.blk.count);
+                 printk("Logical block=%lx/%lx\n",last_scsi_logical_block(host_index)[ldn],
+                        ld(host_index)[ldn].scb.u1.log_blk_adr);
+              }                                 
+            printk("Reason given: %s\n",
+                   (cmd_result==IM_ADAPTER_HW_FAILURE) ? "HARDWARE FAILURE" :
+                   (cmd_result==IM_SOFTWARE_SEQUENCING_ERROR) ? "SOFTWARE SEQUENCING ERROR" :
+                   (cmd_result==IM_CMD_ERROR) ? "COMMAND ERROR" : "UNKNOWN");  
+            /* if errors appear, enter this section to give detailed info */
+            printk("IBM MCA SCSI: Subsystem Error-Status follows:\n");
+            printk("              Command Type................: %x\n",
+                   last_scsi_type(host_index)[ldn]);
+            printk("              Attention Register..........: %x\n",
+                   inb (IM_ATTN_REG(host_index)));
+            printk("              Basic Control Register......: %x\n",
+                   inb (IM_CTR_REG(host_index)));
+            printk("              Interrupt Status Register...: %x\n",
+                   intr_reg);
+            printk("              Basic Status Register.......: %x\n",
+                   inb (IM_STAT_REG(host_index)));
+            if ((last_scsi_type(host_index)[ldn]==IM_SCB)||
+                (last_scsi_type(host_index)[ldn]==IM_LONG_SCB))
+              {
+                 printk("              SCB-Command.................: %x\n",
+                        ld(host_index)[ldn].scb.command);
+                 printk("              SCB-Enable..................: %x\n",
+                        ld(host_index)[ldn].scb.enable);
+                 printk("              SCB-logical block address...: %lx\n",
+                        ld(host_index)[ldn].scb.u1.log_blk_adr);
+                 printk("              SCB-system buffer address...: %lx\n",
+                        ld(host_index)[ldn].scb.sys_buf_adr);
+                 printk("              SCB-system buffer length....: %lx\n",
+                        ld(host_index)[ldn].scb.sys_buf_length);
+                 printk("              SCB-tsb address.............: %lx\n",
+                        ld(host_index)[ldn].scb.tsb_adr);
+                 printk("              SCB-Chain address...........: %lx\n",
+                        ld(host_index)[ldn].scb.scb_chain_adr);
+                 printk("              SCB-block count.............: %x\n",
+                        ld(host_index)[ldn].scb.u2.blk.count);
+                 printk("              SCB-block length............: %x\n",
+                        ld(host_index)[ldn].scb.u2.blk.length);
+              }
+            printk("              Send this report to the maintainer.\n");
+            panic("IBM MCA SCSI: Fatal errormessage from the subsystem (0x%X,0x%X)!\n",
+                  lastSCSI,cmd_result);
+            break;
+         }  
      }
-   if (errorflag)
-     { /* if errors appear, enter this section to give detailed info */
-       printk("IBM MCA SCSI: Subsystem Error-Status follows:\n");
-       printk("              Command Type................: %x\n",
-              last_scsi_type(host_index)[ldn]);
-       printk("              Attention Register..........: %x\n",
-              inb (IM_ATTN_REG(host_index)));
-        printk("              Basic Control Register......: %x\n",
-              inb (IM_CTR_REG(host_index)));
-       printk("              Interrupt Status Register...: %x\n",
-              intr_reg);
-       printk("              Basic Status Register.......: %x\n",
-              inb (IM_STAT_REG(host_index)));
-       if ((last_scsi_type(host_index)[ldn]==IM_SCB)||
-           (last_scsi_type(host_index)[ldn]==IM_LONG_SCB))
+   else 
+     { /* The command error handling is made silent, but we tell the
+       * calling function, that there is a reported error from the
+       * adapter. */
+       switch (cmd_result)
          {
-            printk("              SCB End Status Word.........: %x\n",
-                   ld(host_index)[ldn].tsb.end_status);
-            printk("              Command Status..............: %x\n",
-                   ld(host_index)[ldn].tsb.cmd_status);
-            printk("              Device Status...............: %x\n",
-                   ld(host_index)[ldn].tsb.dev_status);
-            printk("              Command Error...............: %x\n",
-                   ld(host_index)[ldn].tsb.cmd_error);
-            printk("              Device Error................: %x\n",
-                   ld(host_index)[ldn].tsb.dev_error);
-            printk("              Last SCB Address (LSW)......: %x\n",
-                   ld(host_index)[ldn].tsb.low_of_last_scb_adr);
-            printk("              Last SCB Address (MSW)......: %x\n",
-                   ld(host_index)[ldn].tsb.high_of_last_scb_adr);
+          case IM_ADAPTER_HW_FAILURE:
+          case IM_SOFTWARE_SEQUENCING_ERROR:
+          case IM_CMD_ERROR:
+            global_command_error_excuse = CMD_FAIL;
+            break;
+          default:
+            global_command_error_excuse = 0;
+            break;
          }
-       printk("              Send report to the maintainer.\n");
-       panic("IBM MCA SCSI: Fatal errormessage from the subsystem!\n");
-     }
-
+     }   
+   
    /* if no panic appeared, increase the interrupt-counter */
    IBM_DS(host_index).total_interrupts++;
-
+   
    /*only for local checking phase */
    if (local_checking_phase_flag(host_index))
      {
@@ -596,8 +750,15 @@ static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
        got_interrupt(host_index) = 1;
        reset_status(host_index) = IM_RESET_FINISHED_OK;
        last_scsi_command(host_index)[ldn] = NO_SCSI;
+       
+       outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
+#ifdef OLDKERN
+       restore_flags(flags);
+#else
+       spin_unlock_irqrestore(&intr_lock, flags);
+#endif      
        return;
-     }
+     }   
    /*handling of commands coming from upper level of scsi driver */
    else
      {
@@ -622,24 +783,39 @@ static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
                    }
                  stat_result(host_index) = cmd_result;
                  last_scsi_command(host_index)[ldn] = NO_SCSI;
+                 last_scsi_type(host_index)[ldn] = 0;
+                 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
+#ifdef OLDKERN
+                 restore_flags(flags);
+#else
+                 spin_unlock_irqrestore(&intr_lock, flags);
+#endif      
                  return;
               }
             else if (last_scsi_command(host_index)[ldn] == IM_ABORT_IMM_CMD)
               { /* react on SCSI abort command */
 #ifdef IM_DEBUG_PROBE
                  printk("IBM MCA SCSI: Interrupt from SCSI-abort.\n");
-#endif
+#endif 
                  disk_rw_in_progress = 0;
                  PS2_DISK_LED_OFF();
                  cmd = ld(host_index)[ldn].cmd;
+                 ld(host_index)[ldn].cmd = NULL;
                  if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
                    cmd->result = DID_NO_CONNECT << 16;
                  else
                    cmd->result = DID_ABORT << 16;
                  stat_result(host_index) = cmd_result;
                  last_scsi_command(host_index)[ldn] = NO_SCSI;
+                 last_scsi_type(host_index)[ldn] = 0;            
+                 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
+#ifdef OLDKERN
+                 restore_flags(flags);
+#else
+                 spin_unlock_irqrestore(&intr_lock, flags);
+#endif                   
                  if (cmd->scsi_done)
-                   (cmd->scsi_done) (cmd); /* should be the internal_done */
+                   (cmd->scsi_done)(cmd); /* should be the internal_done */
                  return;
               }
             else
@@ -649,36 +825,59 @@ static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
                  reset_status(host_index) = IM_RESET_FINISHED_OK;
                  stat_result(host_index) = cmd_result;
                  last_scsi_command(host_index)[ldn] = NO_SCSI;
+                 
+                 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
+#ifdef OLDKERN
+                 restore_flags(flags);
+#else
+                 spin_unlock_irqrestore(&intr_lock, flags);
+#endif                   
                  return;
-              }
+              }             
          }
        last_scsi_command(host_index)[ldn] = NO_SCSI;
+       last_scsi_type(host_index)[ldn] = 0;
        cmd = ld(host_index)[ldn].cmd;
+       ld(host_index)[ldn].cmd = NULL;
 #ifdef IM_DEBUG_TIMEOUT
        if (cmd)
          {
-            if ((cmd->target == TIMEOUT_PUN)&&(cmd->lun == TIMEOUT_LUN))
+            if ((cmd->target == TIMEOUT_PUN)&&
+                (cmd->lun == TIMEOUT_LUN))
               {
                  printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n",
                         cmd->target, cmd->lun);
+                 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
+#ifdef OLDKERN
+                 restore_flags(flags);
+#else
+                 spin_unlock_irqrestore(&intr_lock, flags);
+#endif                                   
                  return;
               }
          }
 #endif
        /*if no command structure, just return, else clear cmd */
        if (!cmd)
-         return;
-       ld(host_index)[ldn].cmd = NULL;
-
+         {
+            outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
+#ifdef OLDKERN
+            restore_flags(flags);
+#else
+            spin_unlock_irqrestore(&intr_lock, flags);
+#endif                   
+            return;
+         }             
+       
 #ifdef IM_DEBUG_INT
-       printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n",
-              cmd->cmnd[0], intr_reg,
-              ld(host_index)[ldn].tsb.dev_status,
+       printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", 
+              cmd->cmnd[0], intr_reg, 
+              ld(host_index)[ldn].tsb.dev_status, 
               ld(host_index)[ldn].tsb.cmd_status,
-              ld(host_index)[ldn].tsb.dev_error,
+              ld(host_index)[ldn].tsb.dev_error, 
               ld(host_index)[ldn].tsb.cmd_error);
 #endif
-
+       
        /*if this is end of media read/write, may turn off PS/2 disk led */
        if ((ld(host_index)[ldn].device_type!=TYPE_NO_LUN)&&
            (ld(host_index)[ldn].device_type!=TYPE_NO_DEVICE))
@@ -697,41 +896,73 @@ static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
          }
 
        /* IBM describes the status-mask to be 0x1e, but this is not conform
-        * with SCSI-defintion, I suppose, it is a printing error in the
-        * technical reference and assume as mask 0x3e. (ML) */
-       cmd->result = (ld(host_index)[ldn].tsb.dev_status & 0x3e);
-       /* write device status into cmd->result, and call done function */
+        * with SCSI-defintion, I suppose, the reason for it is that IBM 
+        * adapters do not support CMD_TERMINATED, TASK_SET_FULL and 
+        * ACA_ACTIVE as returning statusbyte information. (ML) */
        if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
-         IBM_DS(host_index).total_errors++;
-       if (interror == NO_SCSI) /* unexpected interrupt :-( */
-         cmd->result |= DID_BAD_INTR << 16;
+         {
+            cmd->result = (unsigned char)(ld(host_index)[ldn].tsb.dev_status & 0x1e);
+            IBM_DS(host_index).total_errors++;
+         }
        else
+         cmd->result = 0;
+       /* write device status into cmd->result, and call done function */
+       if (lastSCSI == NO_SCSI) /* unexpected interrupt :-( */
+         cmd->result |= DID_BAD_INTR << 16;
+       else /* things went right :-) */
          cmd->result |= DID_OK << 16;
-       (cmd->scsi_done) (cmd);
-     }
-   if (interror == NO_SCSI)
+       outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
+#ifdef OLDKERN
+       restore_flags(flags);
+#else
+       spin_unlock_irqrestore(&intr_lock, flags);
+#endif
+       /* This is for Kernel 2.2.x. Something weired happens here. 
+        * Between the command got queued and the interrupt is released,
+        * the flags sometimes contain different values, which must
+        * be a strange thing. E.g. it appears when cold-booting with a
+        * tape drive at id0. */
+       cmd->flags &= 0x3f;
+       if (cmd->scsi_done)
+         (cmd->scsi_done)(cmd);
+     }   
+   if (lastSCSI == NO_SCSI)
      printk("IBM MCA SCSI: WARNING - Interrupt from non-pending SCSI-command!\n");
    return;
 }
 
 /*--------------------------------------------------------------------*/
 
-static void issue_cmd (int host_index, unsigned long cmd_reg,
+static void issue_cmd (int host_index, unsigned long cmd_reg, 
                       unsigned char attn_reg)
 {
    static unsigned long flags;
-   /* must wait for attention reg not busy */
+   /* must wait for attention reg not busy */   
    while (1)
      {
+#ifdef OLDKERN 
+       save_flags(flags);
+       cli();
+#else
        spin_lock_irqsave(&issue_lock, flags);
-       if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
+#endif 
+       if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
          break;
+#ifdef OLDKERN 
+       restore_flags(flags);
+#else
        spin_unlock_irqrestore(&issue_lock, flags);
+#endif 
      }
    /*write registers and enable system interrupts */
    outl (cmd_reg, IM_CMD_REG(host_index));
    outb (attn_reg, IM_ATTN_REG(host_index));
+#ifdef OLDKERN   
+   restore_flags(flags);
+#else
    spin_unlock_irqrestore(&issue_lock, flags);
+#endif
+   return;
 }
 
 /*--------------------------------------------------------------------*/
@@ -739,75 +970,70 @@ static void issue_cmd (int host_index, unsigned long cmd_reg,
 static void internal_done (Scsi_Cmnd * cmd)
 {
    cmd->SCp.Status++;
+   return;
 }
 
 /*--------------------------------------------------------------------*/
 
 /* SCSI-SCB-command for device_inquiry */
 static int device_inquiry(int host_index, int ldn)
-{
+{   
    int retries;
-   Scsi_Cmnd *cmd;
+   Scsi_Cmnd cmd;
    struct im_scb *scb;
    struct im_tsb *tsb;
    unsigned char *buf;
-
+   
    scb = &(ld(host_index)[ldn].scb);
    tsb = &(ld(host_index)[ldn].tsb);
    buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
    ld(host_index)[ldn].tsb.dev_status = 0; /* prepare stusblock */
 
-   cmd = kmalloc(sizeof(*cmd), GFP_KERNEL|GFP_DMA);
-   if(cmd==NULL)
-   {
-       printk(KERN_ERR "ibmmca: out of memory for inquiry.\n");
-       return 0;
-   }
    if (bypass_controller)
      { /* fill the commonly known field for device-inquiry SCSI cmnd */
-       cmd->cmd_len = 6;
-        memset (&(cmd->cmnd), 0x0, sizeof(char) * cmd->cmd_len);
-       cmd->cmnd[0] = INQUIRY; /* device inquiry */
-       cmd->cmnd[4] = 0xff; /* return buffer size = 255 */
-     }
+       cmd.cmd_len = 6;
+        memset (&(cmd.cmnd), 0x0, sizeof(char) * cmd.cmd_len);
+       cmd.cmnd[0] = INQUIRY; /* device inquiry */
+       cmd.cmnd[4] = 0xff; /* return buffer size = 255 */
+     }   
    for (retries = 0; retries < 3; retries++)
      {
        if (bypass_controller)
          { /* bypass the hardware integrated command set */
-            scb->command = IM_OTHER_SCSI_CMD_CMD;
-            scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
-            scb->u1.scsi_cmd_length = cmd->cmd_len;
-            memcpy (scb->u2.scsi_command, &(cmd->cmnd), cmd->cmd_len);
+            scb->command = IM_OTHER_SCSI_CMD_CMD | IM_NO_DISCONNECT;      
+            scb->enable  = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
+            scb->u1.scsi_cmd_length = cmd.cmd_len;
+            memcpy (scb->u2.scsi_command, &(cmd.cmnd), cmd.cmd_len);
             last_scsi_command(host_index)[ldn] = INQUIRY;
-            last_scsi_type(host_index)[ldn] = IM_SCB;
+            last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
          }
        else
          {
             /*fill scb with inquiry command */
-            scb->command = IM_DEVICE_INQUIRY_CMD;
-            scb->enable = IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
+            scb->command = IM_DEVICE_INQUIRY_CMD | IM_NO_DISCONNECT;
+            scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
             last_scsi_command(host_index)[ldn] = IM_DEVICE_INQUIRY_CMD;
-            last_scsi_type(host_index)[ldn] = IM_SCB;
+            last_scsi_type(host_index)[ldn] = IM_SCB;       
          }
        scb->sys_buf_adr = virt_to_bus(buf);
        scb->sys_buf_length = 0xff; /* maximum bufferlength gives max info */
        scb->tsb_adr = virt_to_bus(tsb);
-
+       
        /*issue scb to passed ldn, and busy wait for interrupt */
        got_interrupt(host_index) = 0;
-       issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
+       if ((scb->command & IM_OTHER_SCSI_CMD_CMD) == IM_OTHER_SCSI_CMD_CMD)
+         issue_cmd (host_index, virt_to_bus(scb), IM_LONG_SCB | ldn);
+       else
+         issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
        while (!got_interrupt(host_index))
          barrier ();
-
+       
        /*if command succesful, break */
        if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED)||
            (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
-         {
-            return 1;
-         }
+         return 1;
      }
-   kfree(cmd);
-
+   
    /*if all three retries failed, return "no device at this ldn" */
    if (retries >= 3)
      return 0;
@@ -822,25 +1048,25 @@ static int read_capacity(int host_index, int ldn)
    struct im_scb *scb;
    struct im_tsb *tsb;
    unsigned char *buf;
-
+   
    scb = &(ld(host_index)[ldn].scb);
    tsb = &(ld(host_index)[ldn].tsb);
    buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
    ld(host_index)[ldn].tsb.dev_status = 0;
-
+   
    if (bypass_controller)
      { /* read capacity in commonly known default SCSI-format */
        cmd.cmd_len = 10;
         memset (&(cmd.cmnd), 0x0, sizeof(char) * cmd.cmd_len);
        cmd.cmnd[0] = READ_CAPACITY; /* read capacity */
-     }
+     } 
    for (retries = 0; retries < 3; retries++)
      {
        /*fill scb with read capacity command */
        if (bypass_controller)
          { /* bypass the SCSI-command */
-            scb->command = IM_OTHER_SCSI_CMD_CMD;
-            scb->enable |= IM_READ_CONTROL;
+            scb->command = IM_OTHER_SCSI_CMD_CMD;      
+            scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
             scb->u1.scsi_cmd_length = cmd.cmd_len;
             memcpy (scb->u2.scsi_command, &(cmd.cmnd), cmd.cmd_len);
             last_scsi_command(host_index)[ldn] = READ_CAPACITY;
@@ -849,26 +1075,27 @@ static int read_capacity(int host_index, int ldn)
        else
          {
             scb->command = IM_READ_CAPACITY_CMD;
-            scb->enable = IM_READ_CONTROL;
+            scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
             last_scsi_command(host_index)[ldn] = IM_READ_CAPACITY_CMD;
-            last_scsi_type(host_index)[ldn] = IM_SCB;
+            last_scsi_type(host_index)[ldn] = IM_SCB;       
          }
        scb->sys_buf_adr = virt_to_bus(buf);
        scb->sys_buf_length = 8;
        scb->tsb_adr = virt_to_bus(tsb);
-
+       
        /*issue scb to passed ldn, and busy wait for interrupt */
        got_interrupt(host_index) = 0;
-       issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
+       if ((scb->command & IM_OTHER_SCSI_CMD_CMD) == IM_OTHER_SCSI_CMD_CMD)
+         issue_cmd (host_index, virt_to_bus(scb), IM_LONG_SCB | ldn);
+       else
+         issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
        while (!got_interrupt(host_index))
          barrier ();
-
-            /*if got capacity, get block length and return one device found */
+            
+       /*if got capacity, get block length and return one device found */
        if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED)||
            (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
-         {
-            return 1;
-         }
+         return 1;
      }
    /*if all three retries failed, return "no device at this ldn" */
    if (retries >= 3)
@@ -877,41 +1104,141 @@ static int read_capacity(int host_index, int ldn)
      return 1;
 }
 
+static int get_pos_info(int host_index)
+{
+   int retries;
+   struct im_scb *scb;
+   struct im_tsb *tsb;
+   unsigned char *buf;
+   
+   scb = &(ld(host_index)[MAX_LOG_DEV].scb);
+   tsb = &(ld(host_index)[MAX_LOG_DEV].tsb);
+   buf = (unsigned char *)(&(ld(host_index)[MAX_LOG_DEV].buf));
+   ld(host_index)[MAX_LOG_DEV].tsb.dev_status = 0;
+
+   for (retries = 0; retries < 3; retries++)
+     {
+       /*fill scb with get_pos_info command */
+       scb->command = IM_GET_POS_INFO_CMD;
+       scb->enable = IM_READ_CONTROL | IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE | IM_BYPASS_BUFFER | IM_SUPRESS_EXCEPTION_SHORT;
+       last_scsi_command(host_index)[MAX_LOG_DEV] = IM_GET_POS_INFO_CMD;
+       last_scsi_type(host_index)[MAX_LOG_DEV] = IM_SCB;            
+
+       scb->sys_buf_adr = virt_to_bus(buf);
+       if (special(host_index)==IBM_SCSI2_FW)
+         scb->sys_buf_length = 256; /* get all info from F/W adapter */
+       else
+         scb->sys_buf_length = 18; /* get exactly 18 bytes for other SCSI */
+       
+       scb->tsb_adr = virt_to_bus(tsb);
+       
+       /*issue scb to ldn=15, and busy wait for interrupt */
+       got_interrupt(host_index) = 0;
+       issue_cmd (host_index, virt_to_bus(scb), IM_SCB | MAX_LOG_DEV); 
+       while (!got_interrupt(host_index))
+         barrier ();
+            
+       /*if got POS-stuff, get block length and return one device found */
+       if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED)||
+           (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
+         return 1;
+     }
+   /* if all three retries failed, return "no device at this ldn" */
+   if (retries >= 3)
+     return 0;
+   else
+     return 1;
+}
+
 /* SCSI-immediate-command for assign. This functions maps/unmaps specific
  ldn-numbers on SCSI (PUN,LUN). It is needed for presetting of the
  subsystem and for dynamical remapping od ldns. */
-static int immediate_assign(int host_index, unsigned int pun,
-                            unsigned int lun, unsigned int ldn,
+static int immediate_assign(int host_index, unsigned int pun, 
+                            unsigned int lun, unsigned int ldn, 
                             unsigned int operation)
 {
    int retries;
    unsigned long imm_command;
-
+   
    for (retries=0; retries<3; retries ++)
      {
-        imm_command = inl(IM_CMD_REG(host_index));
-        imm_command &= (unsigned long)(0xF8000000); /* keep reserved bits */
-        imm_command |= (unsigned long)(IM_ASSIGN_IMM_CMD);
-        imm_command |= (unsigned long)((lun & 7) << 24);
-        imm_command |= (unsigned long)((operation & 1) << 23);
-        imm_command |= (unsigned long)((pun & 7) << 20);
-        imm_command |= (unsigned long)((ldn & 15) << 16);
-
-       last_scsi_command(host_index)[0xf] = IM_ASSIGN_IMM_CMD;
-       last_scsi_type(host_index)[0xf] = IM_IMM_CMD;
+       /* select mutation level of the SCSI-adapter */
+       switch (special(host_index))
+         {
+          case IBM_SCSI2_FW:
+            imm_command = (unsigned long)(IM_ASSIGN_IMM_CMD);
+            imm_command |= (unsigned long)((lun & 7) << 24);
+            imm_command |= (unsigned long)((operation & 1) << 23);
+            imm_command |= (unsigned long)((pun & 7)<< 20)|((pun & 8)<< 24);
+            imm_command |= (unsigned long)((ldn & 15) << 16);
+            break;
+          default:
+            imm_command = inl(IM_CMD_REG(host_index));
+            imm_command &= (unsigned long)(0xF8000000); /* keep reserved bits */
+            imm_command |= (unsigned long)(IM_ASSIGN_IMM_CMD);
+            imm_command |= (unsigned long)((lun & 7) << 24);
+            imm_command |= (unsigned long)((operation & 1) << 23);
+            imm_command |= (unsigned long)((pun & 7) << 20);
+            imm_command |= (unsigned long)((ldn & 15) << 16);
+            break;
+         }             
+       last_scsi_command(host_index)[MAX_LOG_DEV] = IM_ASSIGN_IMM_CMD;
+       last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD;
         got_interrupt(host_index) = 0;
-        issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | 0xf);
+        issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | MAX_LOG_DEV);
         while (!got_interrupt(host_index))
          barrier ();
-
+       
         /*if command succesful, break */
        if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
+         return 1;
+     }
+   if (retries >= 3) 
+     return 0;
+   else
+     return 1;
+}
+
+static int immediate_feature(int host_index, unsigned int speed, 
+                            unsigned int timeout)
+{
+   int retries;
+   unsigned long imm_command;
+   
+   for (retries=0; retries<3; retries ++)
+     {
+       /* select mutation level of the SCSI-adapter */
+       switch (special(host_index))
          {
-            return 1;
+          default:
+            imm_command  = IM_FEATURE_CTR_IMM_CMD;
+            imm_command |= (unsigned long)((speed & 0x7) << 29);
+            imm_command |= (unsigned long)((timeout & 0x1fff) << 16);
+            break;
+         }             
+       last_scsi_command(host_index)[MAX_LOG_DEV] = IM_FEATURE_CTR_IMM_CMD;
+       last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD;
+        got_interrupt(host_index) = 0;
+       /* we need to run into command errors in order to probe for the
+        * right speed! */
+       global_command_error_excuse = 1;
+        issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | MAX_LOG_DEV);
+        while (!got_interrupt(host_index))
+         barrier ();
+       if (global_command_error_excuse == CMD_FAIL)
+         {
+            global_command_error_excuse = 0;    
+            return 2;
          }
+       else
+         global_command_error_excuse = 0;
+       
+        /*if command succesful, break */
+       if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
+         return 1;
      }
-
-   if (retries >= 3)
+   
+   if (retries >= 3) 
      return 0;
    else
      return 1;
@@ -923,7 +1250,7 @@ static int immediate_reset(int host_index, unsigned int ldn)
    int retries;
    int ticks;
    unsigned long imm_command;
-
+   
    for (retries=0; retries<3; retries ++)
      {
         imm_command = inl(IM_CMD_REG(host_index));
@@ -933,31 +1260,29 @@ static int immediate_reset(int host_index, unsigned int ldn)
        last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
 
        got_interrupt(host_index) = 0;
-       reset_status(host_index) = IM_RESET_IN_PROGRESS;
+       reset_status(host_index) = IM_RESET_IN_PROGRESS;        
        issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | ldn);
-       ticks = IM_RESET_DELAY*HZ;
-       while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks)
+       ticks = IM_RESET_DELAY*HZ;      
+       while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks) 
          {
             mdelay(1+999/HZ);
             barrier();
          }
        /* if reset did not complete, just claim */
-       if (!ticks)
+       if (!ticks) 
          {
             printk("IBM MCA SCSI: reset did not complete within %d seconds.\n",
                    IM_RESET_DELAY);
-            reset_status(host_index) = IM_RESET_FINISHED_OK;
+            reset_status(host_index) = IM_RESET_FINISHED_OK; 
             /* did not work, finish */
             return 1;
          }
         /*if command succesful, break */
        if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
-         {
-            return 1;
-         }
+         return 1;
      }
-
-   if (retries >= 3)
+   
+   if (retries >= 3) 
      return 0;
    else
      return 1;
@@ -990,17 +1315,108 @@ static char *ti_l(int value)
 {
    const char hex[16] = "0123456789abcdef";
    static char answer[2];
-
+   
    answer[1] = (char)(0x0);
    if (value<=MAX_LOG_DEV)
      answer[0] = hex[value];
    else
      answer[0] = '-';
-
+   
    return (char *)&answer;
 }
 
-/*
+/* transfers bitpattern of the feature command to values in MHz */
+static char *ibmrate(unsigned int speed, int adaptertype)
+{
+   int i;
+   i=adaptertype;
+   switch (speed)
+     {
+      case 0: if (i) return "5.00"; else return "10.00"; break;
+      case 1: if (i) return "4.00"; else return "8.00"; break;
+      case 2: if (i) return "3.33"; else return "6.66"; break;
+      case 3: if (i) return "2.86"; else return "5.00"; break;
+      case 4: if (i) return "2.50"; else return "4.00"; break;
+      case 5: if (i) return "2.22"; else return "3.10"; break;
+      case 6: if (i) return "2.00"; else return "2.50"; break;
+      case 7: if (i) return "1.82"; else return "2.00"; break;
+     }
+   return "---";
+}
+
+static int probe_display(int what)
+{
+   static int rotator = 0;
+   const char rotor[] = "|/-\\";
+   
+   if (!(display_mode & LED_DISP))
+     return 0;
+   if (!what)
+     {
+       outl(0x20202020,MOD95_LED_PORT);
+       outl(0x20202020,MOD95_LED_PORT+4);
+     }
+   else
+     {
+       outb('S',MOD95_LED_PORT+7);
+       outb('C',MOD95_LED_PORT+6);
+       outb('S',MOD95_LED_PORT+5);
+       outb('I',MOD95_LED_PORT+4);
+       outb('i',MOD95_LED_PORT+3);
+       outb('n',MOD95_LED_PORT+2);
+       outb('i',MOD95_LED_PORT+1);
+       outb((char)(rotor[rotator]),MOD95_LED_PORT);
+       rotator++;
+       if (rotator>3) 
+         rotator=0;
+     }
+   return 0;  
+}
+
+static int probe_bus_mode(int host_index)
+{
+   struct im_pos_info *info;
+   int num_bus = 0;
+   int ldn;
+   
+   info = (struct im_pos_info *)(&(ld(host_index)[MAX_LOG_DEV].buf));
+   
+   if (get_pos_info(host_index))
+     {
+       if (info->connector_size & 0xf000)
+         subsystem_connector_size(host_index)=16;
+       else
+         subsystem_connector_size(host_index)=32;      
+       num_bus |= (info->pos_4b & 8) >> 3;
+       for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
+         {
+            if ((special(host_index)==IBM_SCSI_WCACHE)||
+                (special(host_index)==IBM_7568_WCACHE))
+              {                  
+                 if (!((info->cache_stat >> ldn) & 1))
+                   ld(host_index)[ldn].cache_flag = 0;
+              }
+            if (!((info->retry_stat >> ldn) & 1))
+              ld(host_index)[ldn].retry_flag = 0;
+         }
+#ifdef IM_DEBUG_PROBE  
+       printk("IBM MCA SCSI: SCSI-Cache bits: ");
+       for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
+         {
+            printk("%d",ld(host_index)[ldn].cache_flag);
+         }     
+       printk("\nIBM MCA SCSI: SCSI-Retry bits: ");
+       for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
+         {
+            printk("%d",ld(host_index)[ldn].retry_flag);
+         }
+       printk("\n");   
+#endif         
+     }
+   return num_bus;
+}
+
+/* 
  The following routine probes the SCSI-devices in four steps:
  1. The current ldn -> pun,lun mapping is removed on the SCSI-adapter.
  2. ldn 0 is used to go through all possible combinations of pun,lun and
@@ -1020,32 +1436,36 @@ static char *ti_l(int value)
  The assignment of ALL ldns avoids dynamical remapping by the adapter
  itself.
  */
-static void check_devices (int host_index)
+static void check_devices (int host_index, int adaptertype)
 {
    int id, lun, ldn, ticks;
    int count_devices; /* local counter for connected device */
-
+   int max_pun;
+   int num_bus;
+   int speedrun; /* local adapter_speed check variable */
+      
    /* assign default values to certain variables */
-
    ticks = 0;
    count_devices = 0;
    IBM_DS(host_index).dyn_flag = 0; /* normally no need for dynamical ldn management */
    IBM_DS(host_index).total_errors = 0; /* set errorcounter to 0 */
    next_ldn(host_index) = 7; /* next ldn to be assigned is 7, because 0-6 is 'hardwired'*/
+
+   /* initialize the very important driver-informational arrays/structs */
+   memset (ld(host_index), 0, 
+          sizeof(ld(host_index)));   
    for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
      {
        last_scsi_command(host_index)[ldn] = NO_SCSI; /* emptify last SCSI-command storage */
        last_scsi_type(host_index)[ldn] = 0;
+       ld(host_index)[ldn].cache_flag = 1;
+       ld(host_index)[ldn].retry_flag = 1;
      }
-
-   /* initialize the very important driver-informational arrays/structs */
-   memset (ld(host_index), 0,
-          sizeof(ld(host_index)));
-   memset (get_ldn(host_index), TYPE_NO_DEVICE,
+   memset (get_ldn(host_index), TYPE_NO_DEVICE, 
           sizeof(get_ldn(host_index))); /* this is essential ! */
    memset (get_scsi(host_index), TYPE_NO_DEVICE,
           sizeof(get_scsi(host_index))); /* this is essential ! */
-
+   
    for (lun=0; lun<8; lun++) /* mark the adapter at its pun on all luns*/
      {
        get_scsi(host_index)[subsystem_pun(host_index)][lun] = TYPE_IBM_SCSI_ADAPTER;
@@ -1054,13 +1474,58 @@ static void check_devices (int host_index)
                                                                luns. */
      }
 
+   probe_display(0); /* Supercool display usage during SCSI-probing. */
+                     /* This makes sense, when booting without any */
+                     /* monitor connected on model XX95. */
+   
    /* STEP 1: */
+   adapter_speed(host_index) = global_adapter_speed;
+   speedrun = adapter_speed(host_index);
+   while (immediate_feature(host_index,speedrun,adapter_timeout)==2)
+     {
+       probe_display(1);
+       if (speedrun==7)
+         panic("IBM MCA SCSI: Cannot set Synchronous-Transfer-Rate!\n");
+       speedrun++;
+       if (speedrun>7) 
+         speedrun=7;
+     }
+   adapter_speed(host_index) = speedrun;
+   /* Get detailed information about the current adapter, necessary for
+    * device operations: */
+   num_bus=probe_bus_mode(host_index);
+   
+   /* num_bus contains only valid data for the F/W adapter! */
+   if (adaptertype==IBM_SCSI2_FW) /* F/W SCSI adapter: */
+     {
+       /* F/W adapter PUN-space extension evaluation: */
+       if (num_bus)      
+         {          
+            printk("IBM MCA SCSI: Seperate bus mode (wide-addressing enabled)\n");
+            subsystem_maxid(host_index) = 16;
+         }     
+       else
+         {          
+            printk("IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n");
+            subsystem_maxid(host_index) = 8;
+         }     
+       printk("IBM MCA SCSI: Sync.-Rate (F/W: 20, Int.: 10, Ext.: %s) MBytes/s\n",
+              ibmrate(speedrun,adaptertype));
+     }
+   else /* all other IBM SCSI adapters: */
+     printk("IBM MCA SCSI: Synchronous-SCSI-Transfer-Rate: %s MBytes/s\n",
+           ibmrate(speedrun,adaptertype));
+   
+   /* assign correct PUN device space */
+   max_pun = subsystem_maxid(host_index);
+     
 #ifdef IM_DEBUG_PROBE
    printk("IBM MCA SCSI: Current SCSI-host index: %d\n",host_index);
 #endif
    printk("IBM MCA SCSI: Removing default logical SCSI-device mapping.");
    for (ldn=0; ldn<MAX_LOG_DEV; ldn++)
      {
+       probe_display(1);
 #ifdef IM_DEBUG_PROBE
        printk(".");
 #endif
@@ -1068,14 +1533,20 @@ static void check_devices (int host_index)
      }
 
    lun = 0; /* default lun is 0 */
-
+   
    /* STEP 2: */
-   printk("\nIBM MCA SCSI: Probing SCSI-devices.");
-   for (id=0; id<8; id++)
+   printk("\nIBM MCA SCSI: Probing SCSI-devices");
+#ifndef IM_DEBUG_PROBE
+   printk(" (this can take up to 2 minutes)");
+#endif
+   printk(".");
+   
+   for (id=0; id<max_pun ; id++)
 #ifdef CONFIG_SCSI_MULTI_LUN
      for (lun=0; lun<8; lun++)
 #endif
      {
+       probe_display(1);
 #ifdef IM_DEBUG_PROBE
        printk(".");
 #endif
@@ -1095,31 +1566,32 @@ static void check_devices (int host_index)
             immediate_assign(host_index,id,lun,PROBE_LDN,REMOVE_LDN);
          }
      }
-
-   /* STEP 3: */
+   
+   /* STEP 3: */   
    printk("\nIBM MCA SCSI: Mapping SCSI-devices.");
-
+   
    ldn = 0;
    lun = 0;
-
-#ifdef CONFIG_SCSI_MULTI_LUN
+   
+#ifdef CONFIG_SCSI_MULTI_LUN   
    for (lun=0; lun<8 && ldn<MAX_LOG_DEV; lun++)
 #endif
-     for (id=0; id<8 && ldn<MAX_LOG_DEV; id++)
+     for (id=0; id<max_pun && ldn<MAX_LOG_DEV; id++)
      {
+       probe_display(1);
 #ifdef IM_DEBUG_PROBE
        printk(".");
 #endif
        if (id != subsystem_pun(host_index))
          {
-            if (get_scsi(host_index)[id][lun] != TYPE_NO_LUN &&
+            if (get_scsi(host_index)[id][lun] != TYPE_NO_LUN && 
                 get_scsi(host_index)[id][lun] != TYPE_NO_DEVICE)
               {
-                 /* Only map if accepted type. Always enter for
+                 /* Only map if accepted type. Always enter for 
                   lun == 0 to get no gaps into ldn-mapping for ldn<7. */
                  immediate_assign(host_index,id,lun,ldn,SET_LDN);
                  get_ldn(host_index)[id][lun]=ldn; /* map ldn */
-                 if (device_exists (host_index, ldn,
+                 if (device_exists (host_index, ldn, 
                                     &ld(host_index)[ldn].block_length,
                                     &ld(host_index)[ldn].device_type))
                    {
@@ -1149,18 +1621,19 @@ static void check_devices (int host_index)
                  get_ldn(host_index)[id][lun]=ldn; /* map ldn */
                  ldn++;
               }
-         }
+         }      
      }
-
+   
    /* STEP 4: */
-
+   
    /* map remaining ldns to non-existing devices */
    for (lun=1; lun<8 && ldn<MAX_LOG_DEV; lun++)
-     for (id=0; id<8 && ldn<MAX_LOG_DEV; id++)
+     for (id=0; id<max_pun && ldn<MAX_LOG_DEV; id++)
      {
        if (get_scsi(host_index)[id][lun] == TYPE_NO_LUN ||
            get_scsi(host_index)[id][lun] == TYPE_NO_DEVICE)
          {
+            probe_display(1);       
             /* Map remaining ldns only to NON-existing pun,lun
              combinations to make sure an inquiry will fail. 
              For MULTI_LUN, it is needed to avoid adapter autonome
@@ -1169,20 +1642,20 @@ static void check_devices (int host_index)
             get_ldn(host_index)[id][lun]=ldn;
             ldn++;
          }
-     }
-
+     } 
+   
    printk("\n");
    if (ibm_ansi_order)
      printk("IBM MCA SCSI: Device order: IBM/ANSI (pun=7 is first).\n");
    else
      printk("IBM MCA SCSI: Device order: New Industry Standard (pun=0 is first).\n");
-
+   
 #ifdef IM_DEBUG_PROBE
    /* Show the physical and logical mapping during boot. */
    printk("IBM MCA SCSI: Determined SCSI-device-mapping:\n");
    printk("    Physical SCSI-Device Map               Logical SCSI-Device Map\n");
    printk("ID\\LUN  0  1  2  3  4  5  6  7       ID\\LUN  0  1  2  3  4  5  6  7\n");
-   for (id=0; id<8; id++)
+   for (id=0; id<max_pun; id++)
      {
         printk("%2d     ",id);
        for (lun=0; lun<8; lun++)
@@ -1193,52 +1666,54 @@ static void check_devices (int host_index)
        printk("\n");
      }
 #endif
-
+   
    /* assign total number of found SCSI-devices to the statistics struct */
    IBM_DS(host_index).total_scsi_devices = count_devices;
-
+   
    /* decide for output in /proc-filesystem, if the configuration of
     SCSI-devices makes dynamical reassignment of devices necessary */
-   if (count_devices>=MAX_LOG_DEV)
+   if (count_devices>=MAX_LOG_DEV) 
      IBM_DS(host_index).dyn_flag = 1; /* dynamical assignment is necessary */
-   else
+   else 
      IBM_DS(host_index).dyn_flag = 0; /* dynamical assignment is not necessary */
-
+   
    /* If no SCSI-devices are assigned, return 1 in order to cause message. */
    if (ldn == 0)
      printk("IBM MCA SCSI: Warning: No SCSI-devices found/assigned!\n");
-
+   
    /* reset the counters for statistics on the current adapter */
+   IBM_DS(host_index).scbs = 0;
+   IBM_DS(host_index).long_scbs = 0;
    IBM_DS(host_index).total_accesses = 0;
    IBM_DS(host_index).total_interrupts = 0;
    IBM_DS(host_index).dynamical_assignments = 0;
-   memset (IBM_DS(host_index).ldn_access, 0x0,
+   memset (IBM_DS(host_index).ldn_access, 0x0, 
           sizeof (IBM_DS(host_index).ldn_access));
-   memset (IBM_DS(host_index).ldn_read_access, 0x0,
+   memset (IBM_DS(host_index).ldn_read_access, 0x0, 
           sizeof (IBM_DS(host_index).ldn_read_access));
-   memset (IBM_DS(host_index).ldn_write_access, 0x0,
+   memset (IBM_DS(host_index).ldn_write_access, 0x0, 
           sizeof (IBM_DS(host_index).ldn_write_access));
-   memset (IBM_DS(host_index).ldn_inquiry_access, 0x0,
+   memset (IBM_DS(host_index).ldn_inquiry_access, 0x0, 
           sizeof (IBM_DS(host_index).ldn_inquiry_access));
-   memset (IBM_DS(host_index).ldn_modeselect_access, 0x0,
+   memset (IBM_DS(host_index).ldn_modeselect_access, 0x0, 
           sizeof (IBM_DS(host_index).ldn_modeselect_access));
-   memset (IBM_DS(host_index).ldn_assignments, 0x0,
+   memset (IBM_DS(host_index).ldn_assignments, 0x0, 
           sizeof (IBM_DS(host_index).ldn_assignments));
-
+   probe_display(0);
    return;
 }
 
 /*--------------------------------------------------------------------*/
 
-static int device_exists (int host_index, int ldn, int *block_length,
+static int device_exists (int host_index, int ldn, int *block_length, 
                          int *device_type)
 {
    unsigned char *buf;
-
+   
    /* if no valid device found, return immediately with 0 */
    if (!(device_inquiry(host_index, ldn)))
      return 0;
-
+   
    buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
 
    /*if device is CD_ROM, assume block size 2048 and return */
@@ -1248,64 +1723,64 @@ static int device_exists (int host_index, int ldn, int *block_length,
        *block_length = 2048; /* (standard blocksize for yellow-/red-book) */
        return 1;
      }
-
-   if (*buf == TYPE_WORM) /* CD-burner, WORM, Linux handles this as CD-ROM
+   
+   if (*buf == TYPE_WORM) /* CD-burner, WORM, Linux handles this as CD-ROM 
                             therefore, the block_length is also 2048. */
      {
        *device_type = TYPE_WORM;
        *block_length = 2048;
        return 1;
      }
-
+   
    /* if device is disk, use "read capacity" to find its block size */
    if (*buf == TYPE_DISK)
      {
        *device_type = TYPE_DISK;
         if (read_capacity( host_index, ldn))
          {
-            *block_length = *(buf+7) + (*(buf+6) << 8) +
+            *block_length = *(buf+7) + (*(buf+6) << 8) + 
                            (*(buf+5) << 16) + (*(buf+4) << 24);
             return 1;
          }
        else
          return 0;
      }
-
+   
    /* if this is a magneto-optical drive, treat it like a harddisk */
    if (*buf == TYPE_MOD)
      {
        *device_type = TYPE_MOD;
         if (read_capacity( host_index, ldn))
          {
-            *block_length = *(buf+7) + (*(buf+6) << 8) +
+            *block_length = *(buf+7) + (*(buf+6) << 8) + 
                            (*(buf+5) << 16) + (*(buf+4) << 24);
             return 1;
          }
        else
          return 0;
-     }
-
+     }   
+   
    if (*buf == TYPE_TAPE) /* TAPE-device found */
      {
        *device_type = TYPE_TAPE;
        *block_length = 0; /* not in use (setting by mt and mtst in op.) */
-       return 1;
+       return 1;   
      }
-
+   
    if (*buf == TYPE_PROCESSOR) /* HP-Scanners, diverse SCSI-processing units*/
      {
        *device_type = TYPE_PROCESSOR;
        *block_length = 0; /* they set their stuff on drivers */
        return 1;
      }
-
+   
    if (*buf == TYPE_SCANNER) /* other SCSI-scanners */
      {
        *device_type = TYPE_SCANNER;
        *block_length = 0; /* they set their stuff on drivers */
        return 1;
      }
-
+   
    if (*buf == TYPE_MEDIUM_CHANGER) /* Medium-Changer */
      {
        *device_type = TYPE_MEDIUM_CHANGER;
@@ -1313,60 +1788,54 @@ static int device_exists (int host_index, int ldn, int *block_length,
                            changer device. */
        return 1;
      }
-
+   
    /* Up to now, no SCSI-devices that are known up to kernel 2.1.31 are
-      ignored! MO-drives are now supported and treated as harddisk. */
+      ignored! MO-drives are now supported and treated as harddisk. */   
    return 0;
 }
 
 /*--------------------------------------------------------------------*/
-
+   
 #ifdef CONFIG_SCSI_IBMMCA
 
-void ibmmca_scsi_setup (char *str, int *ints)
+void internal_ibmmca_scsi_setup (char *str, int *ints)
 {
    int i, j, io_base, id_base;
    char *token;
-
+   
    io_base = 0;
    id_base = 0;
-
+   
    if (str)
      {
        token = strtok(str,",");
        j = 0;
        while (token)
          {
+            if (!strcmp(token,"activity"))
+              display_mode |= LED_ACTIVITY;
             if (!strcmp(token,"display"))
-              {
-                 use_display = 1;
-              }
+              display_mode |= LED_DISP;
             if (!strcmp(token,"adisplay"))
-              {
-                 use_adisplay = 1;
-              }
+              display_mode |= LED_ADISP;
             if (!strcmp(token,"bypass"))
-              {
-                 bypass_controller = 1;
-              }
+              bypass_controller = 1;
             if (!strcmp(token,"normal"))
-              {
-                 ibm_ansi_order = 0;
-              }
+              ibm_ansi_order = 0;
             if (!strcmp(token,"ansi"))
-              {
-                 ibm_ansi_order = 1;
-              }
+              ibm_ansi_order = 1;
+            if (!strcmp(token,"fast"))
+              global_adapter_speed = 0;
+            if (!strcmp(token,"medium"))
+              global_adapter_speed = 4;
+            if (!strcmp(token,"slow"))
+              global_adapter_speed = 7;             
             if ( (*token == '-') || (isdigit(*token)) )
               {
                  if (!(j%2) && (io_base < IM_MAX_HOSTS))
-                   {
-                      io_port[io_base++] = simple_strtoul(token,NULL,0);
-                   }
+                   io_port[io_base++] = simple_strtoul(token,NULL,0);
                  if ((j%2) && (id_base < IM_MAX_HOSTS))
-                   {
-                      scsi_id[id_base++] = simple_strtoul(token,NULL,0);
-                   }
+                   scsi_id[id_base++] = simple_strtoul(token,NULL,0);
                  j++;
               }
             token = strtok(NULL,",");
@@ -1374,7 +1843,7 @@ void ibmmca_scsi_setup (char *str, int *ints)
      }
    else if (ints)
      {
-       for (i = 0; i < IM_MAX_HOSTS && 2*i+2 < ints[0]; i++)
+       for (i = 0; i < IM_MAX_HOSTS && 2*i+2 < ints[0]; i++) 
          {
             io_port[i] = ints[2*i+2];
             scsi_id[i] = ints[2*i+2];
@@ -1390,28 +1859,34 @@ void ibmmca_scsi_setup (char *str, int *ints)
 static int ibmmca_getinfo (char *buf, int slot, void *dev)
 {
    struct Scsi_Host *shpnt;
-   int len, special;
+   int len, speciale,connectore;
    unsigned int pos2, pos3;
    static unsigned long flags;
-
+     
+#ifdef OLDKERN   
+   save_flags(flags);
+   cli();   
+#else
    spin_lock_irqsave(&info_lock, flags);
-
+#endif   
+   
    shpnt = dev; /* assign host-structure to local pointer */
    len = 0; /* set filled text-buffer index to 0 */
    /* get the _special contents of the hostdata structure */
-   special = ((struct ibmmca_hostdata *)shpnt->hostdata)->_special;
+   speciale = ((struct ibmmca_hostdata *)shpnt->hostdata)->_special;
+   connectore = ((struct ibmmca_hostdata *)shpnt->hostdata)->_connector_size;
    pos2 = ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2;
    pos3 = ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3;
-
-   if (special == FORCED_DETECTION) /* forced detection */
+   
+   if (speciale == FORCED_DETECTION) /* forced detection */
      {
-       len += sprintf (buf + len, "Adapter cathegory: forced detected\n");
+       len += sprintf (buf + len, "Adapter category: forced detected\n");
        len += sprintf(buf + len, "***************************************\n");
        len += sprintf(buf + len, "***  Forced detected SCSI Adapter   ***\n");
        len += sprintf(buf + len, "***  No chip-information available  ***\n");
        len += sprintf(buf + len, "***************************************\n");
      }
-   else if (special == INTEGRATED_SCSI)
+   else if (speciale == INTEGRATED_SCSI)
      { /* if the integrated subsystem has been found automatically: */
        len += sprintf (buf + len, "Adapter category: integrated\n");
        len += sprintf (buf + len, "Chip revision level: %d\n",
@@ -1421,15 +1896,19 @@ static int ibmmca_getinfo (char *buf, int slot, void *dev)
        len += sprintf (buf + len, "8 kByte NVRAM status: %s\n",
                        (pos2 & 2) ? "locked" : "accessible");
      }
-   else if ((special>=0)&&
-          (special<(sizeof(subsys_list)/sizeof(struct subsys_list_struct))))
-     { /* if the subsystem is a slot adapter */
+   else if ((speciale>=0)&&
+          (speciale<(sizeof(subsys_list)/sizeof(struct subsys_list_struct))))
+     { /* if the subsystem is a slot adapter */        
        len += sprintf (buf + len, "Adapter category: slot-card\n");
-       len += sprintf (buf + len, "Chip revision level: %d\n",
-                       ((pos2 & 0xf0) >> 4));
+       len += sprintf (buf + len, "ROM Segment Address: ");
+       if ((pos2 & 0xf0) == 0xf0)
+         len += sprintf (buf + len, "off\n");
+       else
+         len += sprintf (buf + len, "0x%x\n",
+                       ((pos2 & 0xf0) << 13) + 0xc0000);
        len += sprintf (buf + len, "Chip status: %s\n",
                        (pos2 & 1) ? "enabled" : "disabled");
-       len += sprintf (buf + len, "Port offset: 0x%x\n",
+       len += sprintf (buf + len, "Adapter I/O Offset: 0x%x\n",
                        ((pos2 & 0x0e) << 2));
      }
    else
@@ -1438,10 +1917,11 @@ static int ibmmca_getinfo (char *buf, int slot, void *dev)
      }
    /* common subsystem information to write to the slotn file */
    len += sprintf (buf + len, "Subsystem PUN: %d\n", shpnt->this_id);
-   len += sprintf (buf + len, "I/O base address range: 0x%x-0x%x",
+   len += sprintf (buf + len, "I/O base address range: 0x%x-0x%x\n",
                   (unsigned int)(shpnt->io_port), 
                   (unsigned int)(shpnt->io_port+7));
-   /* Now make sure, the bufferlength is divisible by 4 to avoid
+   len += sprintf (buf + len, "MCA-slot size: %d bits",connectore);
+   /* Now make sure, the bufferlength is devidable by 4 to avoid
     * paging problems of the buffer. */
    while ( len % sizeof( int ) != ( sizeof ( int ) - 1 ) )
      {
@@ -1449,34 +1929,59 @@ static int ibmmca_getinfo (char *buf, int slot, void *dev)
      }
    len += sprintf (buf + len, "\n");
 
+#ifdef OLDKERN   
+   restore_flags(flags);
+#else
    spin_unlock_irqrestore(&info_lock, flags);
+#endif   
    return len;
 }
-
+   
 int ibmmca_detect (Scsi_Host_Template * scsi_template)
 {
    struct Scsi_Host *shpnt;
    int port, id, i, j, list_size, slot;
-
+   int devices_on_irq_11 = 0;
+   int devices_on_irq_14 = 0;
+   int IRQ14_registered = 0;
+   int IRQ11_registered = 0;
+   
    found = 0; /* make absolutely sure, that found is set to 0 */
 
+   /* First of all, print the version number of the driver. This is 
+    * important to allow better user bugreports in case of already
+    * having problems with the MCA_bus probing. */
+   printk("IBM MCA SCSI: Version %s\n",IBMMCA_SCSI_DRIVER_VERSION);
    /* if this is not MCA machine, return "nothing found" */
    if (!MCA_bus)
      {
-       printk("IBM MCA SCSI: No Microchannel-bus support present -> Aborting.\n");
+       printk("IBM MCA SCSI: No Microchannel-bus present --> Aborting.\n");
+       printk("              This machine does not have any IBM MCA-bus\n");
+       printk("              or the MCA-Kernel-support is not enabled!\n");
        return 0;
      }
-   else
-     printk("IBM MCA SCSI: Version %s\n",IBMMCA_SCSI_DRIVER_VERSION);
 
+#ifdef MODULE
+   /* If the driver is run as module, read from conf.modules or cmd-line */
+   if (boot_options) 
+     option_setup(boot_options);
+#endif   
+   
    /* get interrupt request level */
+#ifdef OLDKERN
+   if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmcascsi",
+                   hosts))
+#else
    if (request_irq (IM_IRQ, do_interrupt_handler, SA_SHIRQ, "ibmmcascsi",
                    hosts))
+#endif
      {
        printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ);
        return 0;
      }
-
+   else
+     IRQ14_registered++;
+         
    /* if ibmmcascsi setup option was passed to kernel, return "found" */
    for (i = 0; i < IM_MAX_HOSTS; i++)
      if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8)
@@ -1484,20 +1989,25 @@ int ibmmca_detect (Scsi_Host_Template * scsi_template)
        printk("IBM MCA SCSI: forced detected SCSI Adapter, io=0x%x, scsi id=%d.\n",
               io_port[i], scsi_id[i]);
        if ((shpnt = ibmmca_register(scsi_template, io_port[i], scsi_id[i],
+                    FORCED_DETECTION,
                     "forced detected SCSI Adapter")))
          {
             ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = 0;
             ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = 0;
-            ((struct ibmmca_hostdata *)shpnt->hostdata)->_special =
+            ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos4 = 0;
+            ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos5 = 0;
+            ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos6 = 0;         
+            ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = 
               FORCED_DETECTION;
-            mca_set_adapter_name(MCA_INTEGSCSI, "forcibly detected SCSI Adapter");
+            mca_set_adapter_name(MCA_INTEGSCSI, "forced detected SCSI Adapter");
             mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
                                    shpnt);
             mca_mark_as_used(MCA_INTEGSCSI);
-         }
+            devices_on_irq_14++;
+         }     
      }
    if (found) return found;
-
+   
    /* The POS2-register of all PS/2 model SCSI-subsystems has the following
     * interpretation of bits:
     *                             Bit 7 - 4 : Chip Revision ID (Release)
@@ -1509,16 +2019,16 @@ int ibmmca_detect (Scsi_Host_Template * scsi_template)
     *                             Bit 4     : Reserved = 0
     *                             Bit 3 - 0 : Reserved = 0
     * (taken from "IBM, PS/2 Hardware Interface Technical Reference, Common
-    * Interfaces (1991)").
-    * In short words, this means, that IBM PS/2 machines only support
-    * 1 single subsystem by default. The slot-adapters must have another
+    * Interfaces (1991)"). 
+    * In short words, this means, that IBM PS/2 machines only support 
+    * 1 single subsystem by default. The slot-adapters must have another 
     * configuration on pos2. Here, one has to assume the following
     * things for POS2-register:
     *                             Bit 7 - 4 : Chip Revision ID (Release)
     *                             Bit 3 - 1 : port offset factor
     *                             Bit 0     : Chip Enable (EN-Signal)
     * As I found a patch here, setting the IO-registers to 0x3540 forced,
-    * as there was a 0x05 in POS2 on a model 56, I assume, that the
+    * as there was a 0x05 in POS2 on a model 56, I assume, that the 
     * port 0x3540 must be fix for integrated SCSI-controllers.
     * Ok, this discovery leads to the following implementation: (M.Lang) */
 
@@ -1526,13 +2036,15 @@ int ibmmca_detect (Scsi_Host_Template * scsi_template)
    for (j=0;j<8;j++) /* read the pos-information */
      pos[j] = mca_read_stored_pos(MCA_INTEGSCSI,j);
    /* pos2 = pos3 = 0xff if there is no integrated SCSI-subsystem present  */
-   if (( pos[2] != 0xff) || (pos[3] != 0xff ))
+   /* if (( pos[2] != 0xff) || (pos[3] != 0xff )) */
+   /* Previous if-arguments do fail! Therefore, we use now the following to
+    * make sure, we see a real integrated onboard SCSI-interface: */
+   if ((!pos[0] && !pos[1] && pos[2]>0 && pos[3]>0 && !pos[4] && !pos[5] && !pos[6] && !pos[7]) ||
+       (pos[0]==0xff && pos[1]==0xff && pos[2]<0xff && pos[3]<0xff && pos[4]==0xff && pos[5]==0xff && pos[6]==0xff && pos[7]==0xff))
      {
        if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
-         {
-            port = IM_IO_PORT;
-         }
-       else
+         port = IM_IO_PORT;
+       else 
          { /* if disabled, no IRQs will be generated, as the chip won't
             * listen to the incomming commands and will do really nothing,
             * except for listening to the pos-register settings. If this
@@ -1543,10 +2055,10 @@ int ibmmca_detect (Scsi_Host_Template * scsi_template)
             port = IM_IO_PORT; /* anyway, set the portnumber and warn */
             printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
             printk("              SCSI-operations may not work.\n");
-         }
+         }      
        id = (pos[3] & 0xe0) >> 5; /* this is correct and represents the PUN */
-
-       /* give detailed information on the subsystem. This helps me
+       
+       /* give detailed information on the subsystem. This helps me 
         * additionally during debugging and analyzing bug-reports. */
        printk("IBM MCA SCSI: IBM Integrated SCSI Controller found, io=0x%x, scsi id=%d,\n",
               port, id);
@@ -1556,20 +2068,25 @@ int ibmmca_detect (Scsi_Host_Template * scsi_template)
 
        /* register the found integrated SCSI-subsystem */
        if ((shpnt = ibmmca_register(scsi_template, port, id,
+                    INTEGRATED_SCSI,
                     "IBM Integrated SCSI Controller")))
          {
             ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = pos[2];
             ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = pos[3];
-            ((struct ibmmca_hostdata *)shpnt->hostdata)->_special =
+            ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos4 = pos[4];
+            ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos5 = pos[5];
+            ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos6 = pos[6];
+            ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = 
               INTEGRATED_SCSI;
             mca_set_adapter_name(MCA_INTEGSCSI, "IBM Integrated SCSI Controller");
             mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
                                    shpnt);
             mca_mark_as_used(MCA_INTEGSCSI);
+            devices_on_irq_14++;
          }
      }
-
-   /* now look for other adapters in MCA slots, */
+   
+   /* now look for other adapters in MCA slots, */   
    /* determine the number of known IBM-SCSI-subsystem types */
    /* see the pos[2] dependence to get the adapter port-offset. */
    list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
@@ -1584,54 +2101,189 @@ int ibmmca_detect (Scsi_Host_Template * scsi_template)
             if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
               { /* (explanations see above) */
                  port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
-              }
-            else
+              } 
+            else 
               { /* anyway, set the portnumber and warn */
-                 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
+                 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2); 
                  printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
                  printk("              SCSI-operations may not work.\n");
+              }             
+            if ((i==IBM_SCSI2_FW)&&(pos[6]!=0))               
+              {
+                 printk("IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
+                 printk("              Impossible to determine adapter PUN!\n");
+                 printk("              Guessing adapter PUN = 7.\n");
+                 id = 7;
+              }
+            else
+              {                  
+                 id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */
+                 if (i==IBM_SCSI2_FW)
+                   {                  
+                      id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit
+                                                   * for F/W adapters */
+                   }             
+              }             
+            if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0))
+              {  /* IRQ11 is used by SCSI-2 F/W Adapter/A */
+                 printk("IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
+                 /* get interrupt request level */
+#ifdef OLDKERN
+                 if (request_irq (IM_IRQ_FW, interrupt_handler, SA_SHIRQ, 
+                                  "ibmmcascsi", hosts))
+#else
+                 if (request_irq (IM_IRQ_FW, do_interrupt_handler, SA_SHIRQ,
+                                  "ibmmcascsi", hosts))
+#endif
+                   {
+                      printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n",
+                             IM_IRQ_FW);
+                   }
+                 else
+                   IRQ11_registered++;           
               }
-            id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */
             printk("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n",
                     subsys_list[i].description, slot + 1, port, id);
-            printk("              chip rev.=%d, port-offset=0x%x, subsystem=%s\n",
-                   ((pos[2] & 0xf0) >> 4),
+            if ((pos[2] & 0xf0) == 0xf0)
+              printk("              ROM Addr.=off,");
+            else
+              printk("              ROM Addr.=0x%x,",
+                     ((pos[2] & 0xf0) << 13) + 0xc0000);
+            printk(" port-offset=0x%x, subsystem=%s\n",
                    ((pos[2] & 0x0e) << 2),
                    (pos[2] & 1) ? "enabled." : "disabled.");
-
+            
             /* register the hostadapter */
-            if ((shpnt = ibmmca_register(scsi_template, port, id,
+            if ((shpnt = ibmmca_register(scsi_template, port, id, i,
                          subsys_list[i].description)))
               {
                  ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = pos[2];
                  ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = pos[3];
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos4 = pos[4];
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos5 = pos[5];
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos6 = pos[6];
                  ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = i;
 
                  mca_set_adapter_name (slot, subsys_list[i].description);
                  mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
                                          shpnt);
                  mca_mark_as_used(slot);
+                 if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0))
+                   devices_on_irq_11++;
+                 else
+                   devices_on_irq_14++;
               }
             slot++; /* advance to next slot */
          } /* advance to next adapter id in the list of IBM-SCSI-subsystems*/
      }
 
-   if (!found)
-     { /* maybe ESDI, or other producers' SCSI-hosts */
-       free_irq (IM_IRQ, hosts);
-       printk("IBM MCA SCSI: No IBM SCSI-subsystem adapter attached.\n");
+   
+   /* now look for SCSI-adapters, by bugs mapped to the integrated SCSI
+    * area. E.g. a W/Cache in MCA-slot 9 ???? Arrrrgh!! */
+   list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
+   for (i = 0; i < list_size; i++)
+     { /* scan each slot for a fitting adapter id */
+       slot = mca_find_adapter(subsys_list[i].mca_id, MCA_INTEGSCSI);
+       if (slot != MCA_NOTFOUND)
+         { /* scan through all slots */
+            for (j=0;j<8;j++) /* read the pos-information */
+              pos[j] = mca_read_stored_pos(slot, j);
+            if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
+              { /* (explanations see above) */
+                 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
+              } 
+            else 
+              { /* anyway, set the portnumber and warn */
+                 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2); 
+                 printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
+                 printk("              SCSI-operations may not work.\n");
+              }
+            if ((i==IBM_SCSI2_FW)&&(pos[6]!=0))               
+              {
+                 printk("IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
+                 printk("              Impossible to determine adapter PUN!\n");
+                 printk("              Guessing adapter PUN = 7.\n");
+                 id = 7;
+              }
+            else
+              {                  
+                 id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */
+                 if (i==IBM_SCSI2_FW)
+                   {                  
+                      id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit
+                                                   * for F/W adapters */
+                   }             
+              }             
+            if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0))
+              {  /* IRQ11 is used by SCSI-2 F/W Adapter/A */
+                 printk("IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
+                 /* get interrupt request level */
+#ifdef OLDKERN
+                 if (request_irq (IM_IRQ_FW, interrupt_handler, SA_SHIRQ, 
+                                  "ibmmcascsi", hosts))
+#else
+                 if (request_irq (IM_IRQ_FW, do_interrupt_handler, SA_SHIRQ,
+                                  "ibmmcascsi", hosts))
+#endif
+                   {
+                      printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n",
+                             IM_IRQ_FW);
+                   }
+                 else
+                   IRQ11_registered++;           
+              }
+            printk("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n",
+                    subsys_list[i].description, slot + 1, port, id);
+            if ((pos[2] & 0xf0) == 0xf0)
+              printk("              ROM Addr.=off,");
+            else
+              printk("              ROM Addr.=0x%x,",
+                     ((pos[2] & 0xf0) << 13) + 0xc0000);
+            printk(" port-offset=0x%x, subsystem=%s\n",
+                   ((pos[2] & 0x0e) << 2),
+                   (pos[2] & 1) ? "enabled." : "disabled.");
+            
+            /* register the hostadapter */
+            if ((shpnt = ibmmca_register(scsi_template, port, id, i,
+                         subsys_list[i].description)))
+              {
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = pos[2];
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = pos[3];
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos4 = pos[4];
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos5 = pos[5];
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos6 = pos[6];
+                 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = i;
+
+                 mca_set_adapter_name (slot, subsys_list[i].description);
+                 mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
+                                         shpnt);
+                 mca_mark_as_used(slot);
+                 if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0))
+                   devices_on_irq_11++;
+                 else
+                   devices_on_irq_14++;
+              }
+            slot++; /* advance to next slot */
+         } /* advance to next adapter id in the list of IBM-SCSI-subsystems*/
      }
+   
+   if ( IRQ11_registered && !devices_on_irq_11 )
+     free_irq(IM_IRQ_FW, hosts); /* no devices on IRQ 11 */
+   if ( IRQ14_registered && !devices_on_irq_14 )
+     free_irq(IM_IRQ, hosts); /* no devices on IRQ 14 */
+   if ( !devices_on_irq_11 && !devices_on_irq_14 )
+     printk("IBM MCA SCSI: No IBM SCSI-subsystem adapter attached.\n");
    return found; /* return the number of found SCSI hosts. Should be 1 or 0. */
 }
 
 static struct Scsi_Host *
-ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id,
-               char *hostname)
+ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id, 
+               int adaptertype, char *hostname)
 {
    struct Scsi_Host *shpnt;
    int i, j;
    unsigned int ctrl;
-
+   
    /* check I/O region */
    if (check_region(port, IM_N_IO_PORT))
      {
@@ -1639,7 +2291,7 @@ ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id,
               port, port + IM_N_IO_PORT - 1, IM_N_IO_PORT);
        return NULL;
      }
-
+   
    /* register host */
    shpnt = scsi_register(scsi_template, sizeof(struct ibmmca_hostdata));
    if (!shpnt)
@@ -1647,18 +2299,21 @@ ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id,
        printk("IBM MCA SCSI: Unable to register host.\n");
        return NULL;
      }
-
+   
    /* request I/O region */
    request_region(port, IM_N_IO_PORT, hostname);
-
+      
    hosts[found] = shpnt; /* add new found hostadapter to the list */
+   special(found) = adaptertype; /* important assignment or else crash! */
+   subsystem_connector_size(found) = 0; /* preset slot-size */
    shpnt->irq = IM_IRQ; /* assign necessary stuff for the adapter */
    shpnt->io_port = port;
    shpnt->n_io_port = IM_N_IO_PORT;
    shpnt->this_id = id;
+   shpnt->max_id = 8; /* 8 PUNs are default */
    /* now, the SCSI-subsystem is connected to Linux */
-
-   ctrl = (unsigned int)(inb(IM_CTR_REG(found))); /* get control-register status */
+   
+   ctrl = (unsigned int)(inb(IM_CTR_REG(found))); /* get control-register status */   
 #ifdef IM_DEBUG_PROBE
    printk("IBM MCA SCSI: Control Register contents: %x, status: %x\n",
          ctrl,inb(IM_STAT_REG(found)));
@@ -1669,18 +2324,19 @@ ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id,
    if (bypass_controller)
      printk("IBM MCA SCSI: Subsystem SCSI-commands get bypassed.\n");
 #endif
-
+   
    reset_status(found) = IM_RESET_NOT_IN_PROGRESS;
 
-   for (i = 0; i < 8; i++) /* reset the tables */
+   for (i = 0; i < 16; i++) /* reset the tables */
      for (j = 0; j < 8; j++)
      get_ldn(found)[i][j] = MAX_LOG_DEV;
 
    /* check which logical devices exist */
-   local_checking_phase_flag(found) = 1;
-   check_devices(found); /* call by value, using the global variable hosts*/
+   /* after this line, local interrupting is possible: */
+   local_checking_phase_flag(found) = 1;   
+   check_devices(found,adaptertype); /* call by value, using the global variable hosts*/
    local_checking_phase_flag(found) = 0;
-
+   
    found++; /* now increase index to be prepared for next found subsystem */
    /* an ibm mca subsystem has been detected */
    return shpnt;
@@ -1710,21 +2366,21 @@ int ibmmca_release(struct Scsi_Host *shpnt)
 /*--------------------------------------------------------------------*/
 
 /* The following routine is the SCSI command queue. The old edition is
-   now improved by dynamical reassignment of ldn numbers that are
+   now improved by dynamical reassignment of ldn numbers that are 
    currently not assigned. The mechanism works in a way, that first
    the physical structure is checked. If at a certain pun,lun a device
    should be present, the routine proceeds to the ldn check from
    get_ldn. An answer of 0xff would show-up, that the aimed device is
-   currently not assigned any ldn. At this point, the dynamical
+   currently not assigned any ldn. At this point, the dynamical 
    remapping algorithm is called. It works in a way, that it goes in
    cyclic order through the ldns from 7 to 14. If a ldn is assigned,
    it takes 8 dynamical reassignment calls, until a device looses its
-   ldn again. With this method it is assured, that while doing
+   ldn again. With this method it is assured, that while doing 
    intense I/O between up to eight devices, no dynamical remapping is
    done there. ldns 0 through 6(!) are left untouched, which means, that
    puns 0 through 7(!) on lun=0 are always accessible without remapping.
-   These ldns are statically assigned by this driver. The subsystem always
-   occupies at least one pun, therefore 7 ldns (at lun=0) for other devices
+   These ldns are statically assigned by this driver. The subsystem always 
+   occupies at least one pun, therefore 7 ldns (at lun=0) for other devices 
    are sufficient. (The adapter uses always ldn=15, at whatever pun it is.) */
 int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
@@ -1736,33 +2392,46 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
    int id,lun;
    int target;
    int host_index;
-
-   if (ibm_ansi_order)
-     target = 6 - cmd->target;
-   else
-     target = cmd->target;
-
+   int max_pun;
+   int i;
+   struct scatterlist *sl;
+   
    shpnt = cmd->host;
 
    /* search for the right hostadapter */
    for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
-
+   
    if (!hosts[host_index])
      { /* invalid hostadapter descriptor address */
        cmd->result = DID_NO_CONNECT << 16;
-       done (cmd);
+       if (done)
+         done (cmd);
        return 0;
      }
-
+   
+   max_pun = subsystem_maxid(host_index);
+   
+   if (ibm_ansi_order)
+     { 
+       target = max_pun - 1 - cmd->target;
+       if ((target <= subsystem_pun(host_index))&&(cmd->target <= subsystem_pun(host_index)))
+         target--;
+       else if ((target >= subsystem_pun(host_index))&&(cmd->target >= subsystem_pun(host_index)))
+         target++;
+     }         
+   else
+     target = cmd->target;
+   
    /*if (target,lun) is NO LUN or not existing at all, return error */
    if ((get_scsi(host_index)[target][cmd->lun] == TYPE_NO_LUN)||
        (get_scsi(host_index)[target][cmd->lun] == TYPE_NO_DEVICE))
      {
        cmd->result = DID_NO_CONNECT << 16;
-       done (cmd);
+       if (done)
+         done (cmd);
        return 0;
      }
-
+   
    /*if (target,lun) unassigned, do further checks... */
    ldn = get_ldn(host_index)[target][cmd->lun];
    if (ldn >= MAX_LOG_DEV) /* on invalid ldn do special stuff */
@@ -1773,7 +2442,7 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
             while (ld(host_index)[next_ldn(host_index)].cmd) /* search for a occupied, but not in */
               {                      /* command-processing ldn. */
                  next_ldn(host_index)++;
-                 if (next_ldn(host_index)>=MAX_LOG_DEV)
+                 if (next_ldn(host_index)>=MAX_LOG_DEV) 
                    next_ldn(host_index) = 7;
                  if (current_ldn == next_ldn(host_index)) /* One circle done ? */
                    {         /* no non-processing ldn found */
@@ -1782,18 +2451,19 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                       printk("              Reporting DID_NO_CONNECT for device (%d,%d).\n",
                              target, cmd->lun);
                       cmd->result = DID_NO_CONNECT << 16;/* return no connect*/
-                      done (cmd);
+                      if (done)
+                        done (cmd);
                       return 0;
                    }
               }
-
+            
             /* unmap non-processing ldn */
-            for (id=0; id<8; id ++)
+            for (id=0; id<max_pun; id ++)
               for (lun=0; lun<8; lun++)
               {
                  if (get_ldn(host_index)[id][lun] == next_ldn(host_index))
                    {
-                      get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE;
+                      get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE; 
                       /* unmap entry */
                    }
               }
@@ -1808,66 +2478,69 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
             /* change ldn to the right value, that is now next_ldn */
             ldn = next_ldn(host_index);
             /* get device information for ld[ldn] */
-            if (device_exists (host_index, ldn,
+            if (device_exists (host_index, ldn, 
                                &ld(host_index)[ldn].block_length,
                                &ld(host_index)[ldn].device_type))
               {
                  ld(host_index)[ldn].cmd = 0; /* To prevent panic set 0, because
                                                devices that were not assigned,
                                                should have nothing in progress. */
-
+                 
                  /* increase assignment counters for statistics in /proc */
                  IBM_DS(host_index).dynamical_assignments++;
                  IBM_DS(host_index).ldn_assignments[ldn]++;
               }
             else
-              /* panic here, because a device, found at boottime has
+              /* panic here, because a device, found at boottime has 
                vanished */
               panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n",
                     ldn, target, cmd->lun);
-
+            
             /* set back to normal interrupt_handling */
             local_checking_phase_flag(host_index) = 0;
-
+            
             /* Information on syslog terminal */
             printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n",
                    ldn, target, cmd->lun);
-
-            /* increase next_ldn for next dynamical assignment */
+            
+            /* increase next_ldn for next dynamical assignment */ 
             next_ldn(host_index)++;
-            if (next_ldn(host_index)>=MAX_LOG_DEV)
+            if (next_ldn(host_index)>=MAX_LOG_DEV) 
               next_ldn(host_index) = 7;
-         }
+         }       
        else
-         {  /* wall against Linux accesses to the subsystem adapter */
+         {  /* wall against Linux accesses to the subsystem adapter */  
             cmd->result = DID_BAD_TARGET << 16;
-            done (cmd);
+            if (done)
+              done (cmd);
             return 0;
          }
      }
-
+   
    /*verify there is no command already in progress for this log dev */
    if (ld(host_index)[ldn].cmd)
      panic ("IBM MCA SCSI: cmd already in progress for this ldn.\n");
-
+   
    /*save done in cmd, and save cmd for the interrupt handler */
    cmd->scsi_done = done;
    ld(host_index)[ldn].cmd = cmd;
-
+   
    /*fill scb information independent of the scsi command */
    scb = &(ld(host_index)[ldn].scb);
    ld(host_index)[ldn].tsb.dev_status = 0;
-   scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR;
+   scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE;
    scb->tsb_adr = virt_to_bus(&(ld(host_index)[ldn].tsb));
+   scsi_cmd = cmd->cmnd[0];
+   
    if (cmd->use_sg)
      {
-       int i = cmd->use_sg;
-       struct scatterlist *sl = (struct scatterlist *) cmd->request_buffer;
+       i = cmd->use_sg;
+       sl = (struct scatterlist *)(cmd->request_buffer);
        if (i > 16)
          panic ("IBM MCA SCSI: scatter-gather list too long.\n");
        while (--i >= 0)
          {
-            ld(host_index)[ldn].sge[i].address = (void *) virt_to_bus(sl[i].address);
+            ld(host_index)[ldn].sge[i].address = (void *)(virt_to_bus(sl[i].address));
             ld(host_index)[ldn].sge[i].byte_length = sl[i].length;
          }
        scb->enable |= IM_POINTER_TO_LIST;
@@ -1877,31 +2550,45 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
    else
      {
        scb->sys_buf_adr = virt_to_bus(cmd->request_buffer);
-       scb->sys_buf_length = cmd->request_bufflen;
+       /* recent Linux midlevel SCSI places 1024 byte for inquiry
+        * command. Far too much for old PS/2 hardware. */      
+       switch (scsi_cmd)
+         { /* avoid command errors by setting bufferlengths to
+            * ANSI-standard. */
+          case INQUIRY:
+          case REQUEST_SENSE:
+          case MODE_SENSE:
+          case MODE_SELECT:
+            scb->sys_buf_length = 255;
+            break;
+          case TEST_UNIT_READY:
+            scb->sys_buf_length = 0;
+            break;
+          default:
+            scb->sys_buf_length = cmd->request_bufflen;
+            break;
+         }
      }
-
    /*fill scb information dependent on scsi command */
-   scsi_cmd = cmd->cmnd[0];
-
+   
 #ifdef IM_DEBUG_CMD
    printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn);
 #endif
-
+   
    /* for specific device-type debugging: */
 #ifdef IM_DEBUG_CMD_SPEC_DEV
    if (ld(host_index)[ldn].device_type==IM_DEBUG_CMD_DEVICE)
-     printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n",
+     printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n", 
            ld(host_index)[ldn].device_type, scsi_cmd, ldn);
 #endif
-
+   
    /* for possible panics store current command */
-   last_scsi_command(host_index)[ldn] = scsi_cmd;
-   last_scsi_type(host_index)[ldn] = IM_SCB;
-
+   last_scsi_command(host_index)[ldn] = scsi_cmd; 
+   last_scsi_type(host_index)[ldn] = IM_SCB;   
    /* update statistical info */
    IBM_DS(host_index).total_accesses++;
    IBM_DS(host_index).ldn_access[ldn]++;
-
+   
    switch (scsi_cmd)
      {
       case READ_6:
@@ -1909,54 +2596,48 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
       case READ_10:
       case WRITE_10:
       case READ_12:
-      case WRITE_12:
-       /* statistics for proc_info */
-       if ((scsi_cmd == READ_6)||(scsi_cmd == READ_10)||(scsi_cmd == READ_12))
-         IBM_DS(host_index).ldn_read_access[ldn]++; /* increase READ-access on ldn stat. */
-       else if ((scsi_cmd == WRITE_6)||(scsi_cmd == WRITE_10)||
-                (scsi_cmd == WRITE_12))
-         IBM_DS(host_index).ldn_write_access[ldn]++; /* increase write-count on ldn stat.*/
-
+      case WRITE_12:       
        /* Distinguish between disk and other devices. Only disks (that are the
-          most frequently accessed devices) should be supported by the
-         IBM-SCSI-Subsystem commands. */
+          most frequently accessed devices) should be supported by the 
+           IBM-SCSI-Subsystem commands. */
        switch (ld(host_index)[ldn].device_type)
          {
           case TYPE_DISK: /* for harddisks enter here ... */
           case TYPE_MOD:  /* ... try it also for MO-drives (send flames as */
                           /*     you like, if this won't work.) */
-            if (scsi_cmd == READ_6 || scsi_cmd == READ_10 ||
+            if (scsi_cmd == READ_6 || scsi_cmd == READ_10 || 
                 scsi_cmd == READ_12)
               { /* read command preparations */
+                 scb->enable |= IM_READ_CONTROL;
+                 IBM_DS(host_index).ldn_read_access[ldn]++; /* increase READ-access on ldn stat. */
                  if (bypass_controller)
                    {
                       scb->command = IM_OTHER_SCSI_CMD_CMD;
-                      scb->enable |= IM_READ_CONTROL;
+                      scb->enable |= IM_BYPASS_BUFFER;
                       scb->u1.scsi_cmd_length = cmd->cmd_len;
                       memcpy(scb->u2.scsi_command,cmd->cmnd,cmd->cmd_len);
+                      last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
                    }
                  else
-                   {
-                      scb->command = IM_READ_DATA_CMD;
-                      scb->enable |= IM_READ_CONTROL;
-                   }
+                   scb->command = IM_READ_DATA_CMD | IM_NO_DISCONNECT;
               }
             else
               { /* write command preparations */
+                 IBM_DS(host_index).ldn_write_access[ldn]++; /* increase write-count on ldn stat.*/
                  if (bypass_controller)
                    {
                       scb->command = IM_OTHER_SCSI_CMD_CMD;
+                      scb->enable |= IM_BYPASS_BUFFER;
                       scb->u1.scsi_cmd_length = cmd->cmd_len;
                       memcpy(scb->u2.scsi_command,cmd->cmnd,cmd->cmd_len);
+                      last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
                    }
                  else
-                   {
-                      scb->command = IM_WRITE_DATA_CMD;
-                   }
+                   scb->command = IM_WRITE_DATA_CMD | IM_NO_DISCONNECT;
               }
-
+            
             if (!bypass_controller)
-              {
+              {                 
                  if (scsi_cmd == READ_6 || scsi_cmd == WRITE_6)
                    {
                       scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[3]) << 0) |
@@ -1973,12 +2654,14 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                       scb->u2.blk.count = (((unsigned) cmd->cmnd[8]) << 0) |
                         (((unsigned) cmd->cmnd[7]) << 8);
                    }
+                 last_scsi_logical_block(host_index)[ldn] = scb->u1.log_blk_adr;
+                 last_scsi_blockcount(host_index)[ldn] = scb->u2.blk.count;
                  scb->u2.blk.length = ld(host_index)[ldn].block_length;
-              }
+              }            
             if (++disk_rw_in_progress == 1)
               PS2_DISK_LED_ON (shpnt->host_no, target);
             break;
-
+            
             /* for other devices, enter here. Other types are not known by
              Linux! TYPE_NO_LUN is forbidden as valid device. */
           case TYPE_ROM:
@@ -1986,31 +2669,29 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
           case TYPE_PROCESSOR:
           case TYPE_WORM:
           case TYPE_SCANNER:
-          case TYPE_MEDIUM_CHANGER:
-
+          case TYPE_MEDIUM_CHANGER:         
             /* If there is a sequential-device, IBM recommends to use
-             IM_OTHER_SCSI_CMD_CMD instead of subsystem READ/WRITE.
+             IM_OTHER_SCSI_CMD_CMD instead of subsystem READ/WRITE. 
              Good/modern CD-ROM-drives are capable of
              reading sequential AND random-access. This leads to the problem,
-             that random-accesses are covered by the subsystem, but
+             that random-accesses are covered by the subsystem, but 
              sequentials are not, as like for tape-drives. Therefore, it is
              the easiest way to use IM_OTHER_SCSI_CMD_CMD for all read-ops
              on CD-ROM-drives in order not to run into timing problems and
              to have a stable state. In addition, data-access on CD-ROMs
              works faster like that. Strange, but obvious. */
-
+           
             scb->command = IM_OTHER_SCSI_CMD_CMD;
-            if (scsi_cmd == READ_6 || scsi_cmd == READ_10 ||
+            if (scsi_cmd == READ_6 || scsi_cmd == READ_10 || 
                 scsi_cmd == READ_12) /* enable READ */
-              {
-                 scb->enable |= IM_READ_CONTROL;
-              }
-
+              scb->enable |= IM_READ_CONTROL;
+            scb->enable |= IM_BYPASS_BUFFER;
             scb->u1.scsi_cmd_length = cmd->cmd_len;
             memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
-
-            /* Read/write on this non-disk devices is also displayworthy,
-             so flash-up the LED/display. */
+            last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
+            
+            /* Read/write on this non-disk devices is also displayworthy, 
+               so flash-up the LED/display. */
             if (++disk_rw_in_progress == 1)
               PS2_DISK_LED_ON (shpnt->host_no, target);
             break;
@@ -2021,17 +2702,27 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        if (bypass_controller)
          {
             scb->command = IM_OTHER_SCSI_CMD_CMD;
-            scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
+            scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
+            scb->u1.log_blk_adr = 0;
             scb->u1.scsi_cmd_length = cmd->cmd_len;
             memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
+            last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
          }
        else
          {
             scb->command = IM_DEVICE_INQUIRY_CMD;
             scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
+            scb->u1.log_blk_adr = 0;
          }
        break;
-
+      case TEST_UNIT_READY:
+       scb->command = IM_OTHER_SCSI_CMD_CMD;
+       scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
+       scb->u1.log_blk_adr = 0;
+       scb->u1.scsi_cmd_length = 6;
+       memcpy (scb->u2.scsi_command, cmd->cmnd, 6);
+       last_scsi_type(host_index)[ldn] = IM_LONG_SCB;  
+       break;
       case READ_CAPACITY:
        /* the length of system memory buffer must be exactly 8 bytes */
        if (scb->sys_buf_length > 8)
@@ -2039,55 +2730,67 @@ int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        if (bypass_controller)
          {
             scb->command = IM_OTHER_SCSI_CMD_CMD;
-            scb->enable |= IM_READ_CONTROL;
+            scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
             scb->u1.scsi_cmd_length = cmd->cmd_len;
             memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
+            last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
          }
        else
          {
             scb->command = IM_READ_CAPACITY_CMD;
-            scb->enable |= IM_READ_CONTROL;
+            scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
          }
        break;
-
-       /* Commands that need read-only-mode (system <- device): */
+       
+      /* Commands that need read-only-mode (system <- device): */
       case REQUEST_SENSE:
-       if (bypass_controller)
+        if (bypass_controller)
          {
             scb->command = IM_OTHER_SCSI_CMD_CMD;
-            scb->enable |= IM_READ_CONTROL;
+            scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
             scb->u1.scsi_cmd_length = cmd->cmd_len;
             memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
+            last_scsi_type(host_index)[ldn] = IM_LONG_SCB;          
          }
        else
          {
             scb->command = IM_REQUEST_SENSE_CMD;
-            scb->enable |= IM_READ_CONTROL;
+            scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
          }
        break;
-
-       /* Commands that need write-only-mode (system -> device): */
+       
+      /* Commands that need write-only-mode (system -> device): */
       case MODE_SELECT:
       case MODE_SELECT_10:
        IBM_DS(host_index).ldn_modeselect_access[ldn]++;
-       scb->command = IM_OTHER_SCSI_CMD_CMD;
-       scb->enable |= IM_SUPRESS_EXCEPTION_SHORT; /*Select needs WRITE-enabled*/
+       scb->command = IM_OTHER_SCSI_CMD_CMD;      
+       scb->enable |= IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; /*Select needs WRITE-enabled*/
        scb->u1.scsi_cmd_length = cmd->cmd_len;
        memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
+       last_scsi_type(host_index)[ldn] = IM_LONG_SCB;  
        break;
-
-       /* For other commands, read-only is useful. Most other commands are
+       
+       /* For other commands, read-only is useful. Most other commands are 
         running without an input-data-block. */
       default:
        scb->command = IM_OTHER_SCSI_CMD_CMD;
-       scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
+       scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
        scb->u1.scsi_cmd_length = cmd->cmd_len;
        memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
+       last_scsi_type(host_index)[ldn] = IM_LONG_SCB;  
        break;
      }
-
    /*issue scb command, and return */
-   issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
+   if (last_scsi_type(host_index)[ldn] == IM_LONG_SCB)
+     { 
+       issue_cmd (host_index, virt_to_bus(scb), IM_LONG_SCB | ldn);
+       IBM_DS(host_index).long_scbs++;
+     }   
+   else
+     {
+       issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
+       IBM_DS(host_index).scbs++;
+     }
    return 0;
 }
 
@@ -2098,36 +2801,50 @@ int ibmmca_abort (Scsi_Cmnd * cmd)
    /* Abort does not work, as the adapter never generates an interrupt on
     * whatever situation is simulated, even when really pending commands
     * are running on the adapters' hardware ! */
-
+   
    struct Scsi_Host *shpnt;
    unsigned int ldn;
    void (*saved_done) (Scsi_Cmnd *);
    int target;
    int host_index;
+   int max_pun;
    static unsigned long flags;
    unsigned long imm_command;
 
    /* return SCSI_ABORT_SNOOZE ; */
 
+#ifdef OLDKERN   
+   save_flags(flags);
+   cli();   
+#else
    spin_lock_irqsave(&abort_lock, flags);
-   if (ibm_ansi_order)
-     target = 6 - cmd->target;
-   else
-     target = cmd->target;
-
+#endif            
    shpnt = cmd->host;
 
    /* search for the right hostadapter */
-   for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
-
+   for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);   
+   
    if (!hosts[host_index])
      { /* invalid hostadapter descriptor address */
        cmd->result = DID_NO_CONNECT << 16;
        if (cmd->scsi_done)
-         (cmd->done) (cmd);
+         (cmd->scsi_done) (cmd);
        return SCSI_ABORT_SNOOZE;
      }
-
+   
+   max_pun = subsystem_maxid(host_index);
+       
+   if (ibm_ansi_order)
+     {
+       target = max_pun - 1 - cmd->target;
+       if ((target <= subsystem_pun(host_index))&&(cmd->target <= subsystem_pun(host_index)))
+         target--;
+       else if ((target >= subsystem_pun(host_index))&&(cmd->target >= subsystem_pun(host_index)))
+         target++;             
+     }   
+   else
+     target = cmd->target;
    /*get logical device number, and disable system interrupts */
    printk ("IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n",
           target, cmd->lun);
@@ -2136,13 +2853,17 @@ int ibmmca_abort (Scsi_Cmnd * cmd)
    /*if cmd for this ldn has already finished, no need to abort */
    if (!ld(host_index)[ldn].cmd)
      {
+#ifdef OLDKERN   
+       restore_flags(flags);
+#else
        spin_unlock_irqrestore(&abort_lock, flags);
+#endif         
        return SCSI_ABORT_NOT_RUNNING;
      }
 
-   /* Clear ld.cmd, save done function, install internal done,
-    * send abort immediate command (this enables sys. interrupts),
-    * and wait until the interrupt arrives.
+   /* Clear ld.cmd, save done function, install internal done, 
+    * send abort immediate command (this enables sys. interrupts), 
+    * and wait until the interrupt arrives. 
     */
    saved_done = cmd->scsi_done;
    cmd->scsi_done = internal_done;
@@ -2157,22 +2878,34 @@ int ibmmca_abort (Scsi_Cmnd * cmd)
      {
        if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
          break;
+#ifdef OLDKERN 
+       restore_flags (flags);
+#else
        spin_unlock_irqrestore(&abort_lock, flags);
-
+#endif 
+#ifdef OLDKERN   
+       save_flags(flags);
+       cli();   
+#else
        spin_lock_irqsave(&abort_lock, flags);
+#endif   
      }
    /*write registers and enable system interrupts */
    outl (imm_command, IM_CMD_REG(host_index));
    outb (IM_IMM_CMD | ldn, IM_ATTN_REG(host_index));
+#ifdef OLDKERN   
+   restore_flags (flags);
+#else
    spin_unlock_irqrestore(&abort_lock, flags);
-
+#endif
+   
 #ifdef IM_DEBUG_PROBE
        printk("IBM MCA SCSI: Abort submitted, waiting for adapter response...\n");
-#endif
+#endif 
    while (!cmd->SCp.Status)
-     barrier ();
-   cmd->scsi_done = saved_done;
-   /*if abort went well, call saved done, then return success or error */
+     barrier ();   
+   cmd->scsi_done = saved_done;   
+   /*if abort went well, call saved done, then return success or error */   
    if (cmd->result == (DID_ABORT << 16))
      {
        cmd->result |= DID_ABORT << 16;
@@ -2181,7 +2914,7 @@ int ibmmca_abort (Scsi_Cmnd * cmd)
        ld(host_index)[ldn].cmd = NULL;
 #ifdef IM_DEBUG_PROBE
        printk("IBM MCA SCSI: Abort finished with success.\n");
-#endif
+#endif 
        return SCSI_ABORT_SUCCESS;
      }
    else
@@ -2192,7 +2925,7 @@ int ibmmca_abort (Scsi_Cmnd * cmd)
        ld(host_index)[ldn].cmd = NULL;
 #ifdef IM_DEBUG_PROBE
        printk("IBM MCA SCSI: Abort failed.\n");
-#endif
+#endif         
        return SCSI_ABORT_ERROR;
      }
 }
@@ -2208,7 +2941,17 @@ int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
    static unsigned long flags;
    unsigned long imm_command;
 
+   if (cmd == NULL)
+     {
+       printk("IBM MCA SCSI: Reset called with NULL-command!\n");
+       return(SCSI_RESET_SNOOZE);
+     }      
+#ifdef OLDKERN   
+   save_flags(flags);
+   cli();   
+#else
    spin_lock_irqsave(&reset_lock, flags);
+#endif   
    ticks = IM_RESET_DELAY*HZ;
    shpnt = cmd->host;
    /* search for the right hostadapter */
@@ -2218,9 +2961,19 @@ int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
      { /* invalid hostadapter descriptor address */
        if (!local_checking_phase_flag(host_index))
          {
-            cmd->result = DID_NO_CONNECT << 16;
-            if (cmd->scsi_done)
-              (cmd->done) (cmd);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,132)
+            if (flags & SCSI_RESET_SYNCHRONOUS)
+              {
+#ifdef OLDKERN 
+                 restore_flags(flags);
+#else
+                 spin_unlock_irqrestore(&reset_lock, flags);
+#endif                           
+                 cmd->result = DID_NO_CONNECT << 16;        
+                 if (cmd->scsi_done)
+                   (cmd->scsi_done) (cmd);
+              }             
+#endif      
          }
        return SCSI_ABORT_SNOOZE;
      }
@@ -2228,7 +2981,11 @@ int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
    if (local_checking_phase_flag(host_index))
      {
        printk("IBM MCA SCSI: unable to reset while checking devices.\n");
+#ifdef OLDKERN 
+       restore_flags(flags);
+#else
        spin_unlock_irqrestore(&reset_lock, flags);
+#endif         
        return SCSI_RESET_SNOOZE;
      }
 
@@ -2245,8 +3002,17 @@ int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
      {
        if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
          break;
+#ifdef OLDKERN 
+       restore_flags(flags);
+#else
        spin_unlock_irqrestore(&reset_lock, flags);
+#endif 
+#ifdef OLDKERN   
+       save_flags(flags);
+       cli();   
+#else
        spin_lock_irqsave(&reset_lock, flags);
+#endif   
      }
    /*write registers and enable system interrupts */
    outl (imm_command, IM_CMD_REG(host_index));
@@ -2263,10 +3029,14 @@ int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
       printk("IBM MCA SCSI: reset did not complete within %d seconds.\n",
             IM_RESET_DELAY);
       reset_status(host_index) = IM_RESET_FINISHED_FAIL;
+#ifdef OLDKERN   
+      restore_flags(flags);
+#else
       spin_unlock_irqrestore(&reset_lock, flags);
+#endif   
       return SCSI_RESET_ERROR;
    }
-
+   
    if ((inb(IM_INTR_REG(host_index)) & 0x8f)==0x8f)
      { /* analysis done by this routine and not by the intr-routine */
        if (inb(IM_INTR_REG(host_index))==0xaf)
@@ -2276,18 +3046,26 @@ int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
        else /* failed, 4get it */
          reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS_NO_INT;
        outb (IM_EOI | 0xf, IM_ATTN_REG(host_index));
-     }
-
+     } 
+   
    /* if reset failed, just return an error */
    if (reset_status(host_index) == IM_RESET_FINISHED_FAIL) {
       printk("IBM MCA SCSI: reset failed.\n");
+#ifdef OLDKERN   
+      restore_flags(flags);
+#else
       spin_unlock_irqrestore(&reset_lock, flags);
+#endif         
       return SCSI_RESET_ERROR;
    }
-
+   
    /* so reset finished ok - call outstanding done's, and return success */
-   printk ("IBM MCA SCSI: Reset completed without known error.\n");
+   printk ("IBM MCA SCSI: Reset successfully completed.\n");
+#ifdef OLDKERN   
+   restore_flags(flags);
+#else
    spin_unlock_irqrestore(&reset_lock, flags);
+#endif      
    for (i = 0; i < MAX_LOG_DEV; i++)
      {
        cmd_aid = ld(host_index)[i].cmd;
@@ -2295,10 +3073,22 @@ int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
          {
             ld(host_index)[i].cmd = NULL;
             cmd_aid->result = DID_RESET << 16;
-            (cmd_aid->scsi_done) (cmd_aid);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,132)
+            if (flags & SCSI_RESET_SYNCHRONOUS)
+              {
+                 cmd_aid->result = DID_BUS_BUSY << 16;
+                 if (cmd_aid->scsi_done)
+                   (cmd_aid->scsi_done) (cmd_aid);
+              }             
+#endif      
          }
      }
-   return SCSI_RESET_SUCCESS;
+   if (flags & SCSI_RESET_SUGGEST_HOST_RESET)
+     return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
+   else if (flags & SCSI_RESET_SUGGEST_BUS_RESET)
+     return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);
+   else
+     return SCSI_RESET_SUCCESS;
 }
 
 /*--------------------------------------------------------------------*/
@@ -2338,7 +3128,7 @@ static int ldn_access_total_read_write(int host_index)
 {
    int a;
    int i;
-
+   
    a = 0;
    for (i=0; i<=MAX_LOG_DEV; i++)
      a+=IBM_DS(host_index).ldn_read_access[i]+IBM_DS(host_index).ldn_write_access[i];
@@ -2349,7 +3139,7 @@ static int ldn_access_total_inquiry(int host_index)
 {
    int a;
    int i;
-
+   
    a = 0;
    for (i=0; i<=MAX_LOG_DEV; i++)
      a+=IBM_DS(host_index).ldn_inquiry_access[i];
@@ -2360,7 +3150,7 @@ static int ldn_access_total_modeselect(int host_index)
 {
    int a;
    int i;
-
+   
    a = 0;
    for (i=0; i<=MAX_LOG_DEV; i++)
      a+=IBM_DS(host_index).ldn_modeselect_access[i];
@@ -2375,17 +3165,24 @@ int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
    int i,id,lun,host_index;
    struct Scsi_Host *shpnt;
    unsigned long flags;
-
+   int max_pun;
+   
+#ifdef OLDKERN   
+   save_flags(flags);
+   cli();
+#else
    spin_lock_irqsave(&proc_lock, flags);
+#endif   
 
    for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
    shpnt = hosts[i];
    host_index = i;
    if (!shpnt) {
-       len += sprintf(buffer+len, "\nCan't find adapter for host number %d\n", hostno);
+       len += sprintf(buffer+len, "\nIBM MCA SCSI: Can't find adapter for host number %d\n", hostno);
        return len;
    }
-
+   max_pun = subsystem_maxid(host_index);
+   
    len += sprintf(buffer+len, "\n             IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n",
                  IBMMCA_SCSI_DRIVER_VERSION);
    len += sprintf(buffer+len, " SCSI Access-Statistics:\n");
@@ -2406,8 +3203,12 @@ int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
                  (bypass_controller) ? "software" : "hardware integrated");
    len += sprintf(buffer+len, "               Total Interrupts.........: %d\n",
                  IBM_DS(host_index).total_interrupts);
-   len += sprintf(buffer+len, "               Total SCSI Accesses......: %d\n",
+   len += sprintf(buffer+len, "               Total SCSI Accesses......: %d\n",                  
                  IBM_DS(host_index).total_accesses);
+   len += sprintf(buffer+len, "               Total short SCBs.........: %d\n",
+                 IBM_DS(host_index).scbs);
+   len += sprintf(buffer+len, "               Total long SCBs..........: %d\n",
+                 IBM_DS(host_index).long_scbs);   
    len += sprintf(buffer+len, "                 Total SCSI READ/WRITE..: %d\n",
                  ldn_access_total_read_write(host_index));
    len += sprintf(buffer+len, "                 Total SCSI Inquiries...: %d\n",
@@ -2428,11 +3229,11 @@ int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
                     i, ldn_access_load(host_index, i), IBM_DS(host_index).ldn_read_access[i],
                     IBM_DS(host_index).ldn_write_access[i], IBM_DS(host_index).ldn_assignments[i]);
    len += sprintf(buffer+len, "        -----------------------------------------------------------\n\n");
-
+   
    len += sprintf(buffer+len, " Dynamical-LDN-Assignment-Statistics:\n");
    len += sprintf(buffer+len, "               Number of physical SCSI-devices..: %d (+ Adapter)\n",
                  IBM_DS(host_index).total_scsi_devices);
-   len += sprintf(buffer+len, "               Dynamical Assignment necessaray..: %s\n", 
+   len += sprintf(buffer+len, "               Dynamical Assignment necessary...: %s\n", 
                  IBM_DS(host_index).dyn_flag ? "Yes" : "No ");
    len += sprintf(buffer+len, "               Next LDN to be assigned..........: 0x%x\n",
                  next_ldn(host_index));
@@ -2442,47 +3243,63 @@ int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
    len += sprintf(buffer+len, "\n Current SCSI-Device-Mapping:\n");
    len += sprintf(buffer+len, "        Physical SCSI-Device Map               Logical SCSI-Device Map\n");
    len += sprintf(buffer+len, "    ID\\LUN  0  1  2  3  4  5  6  7       ID\\LUN  0  1  2  3  4  5  6  7\n");
-   for (id=0; id<=7; id++)
+   for (id=0; id<max_pun; id++)
      {
        len += sprintf(buffer+len, "    %2d     ",id);
        for (lun=0; lun<8; lun++)
-         len += sprintf(buffer+len,"%2s ",ti_p(get_scsi(host_index)[id][lun]));
-
+         len += sprintf(buffer+len,"%2s ",ti_p(get_scsi(host_index)[id][lun]));        
        len += sprintf(buffer+len, "      %2d     ",id);
        for (lun=0; lun<8; lun++)
          len += sprintf(buffer+len,"%2s ",ti_l(get_ldn(host_index)[id][lun]));
        len += sprintf(buffer+len,"\n");
      }
-
+   
    len += sprintf(buffer+len, "(A = IBM-Subsystem, D = Harddisk, T = Tapedrive, P = Processor, W = WORM,\n");
    len += sprintf(buffer+len, " R = CD-ROM, S = Scanner, M = MO-Drive, C = Medium-Changer, + = unprovided LUN,\n");
    len += sprintf(buffer+len, " - = nothing found, nothing assigned or unprobed LUN)\n\n");
-
+   
    *start = buffer + offset;
    len -= offset;
-   if (len > length)
+   if (len > length) 
      len = length;
+#ifdef OLDKERN   
+   restore_flags(flags);
+#else
    spin_unlock_irqrestore(&proc_lock, flags);
+#endif   
    return len;
 }
 
+void ibmmca_scsi_setup (char *str, int *ints)
+{
+   internal_ibmmca_scsi_setup (str, ints);
+}
+
+static int option_setup(char *str)
+{
+   int ints[IM_MAX_HOSTS];
+   char *cur = str;
+   int i = 1;
+   
+   while (cur && isdigit(*cur) && i <= IM_MAX_HOSTS) {
+      ints[i++] = simple_strtoul(cur, NULL, 0);
+      if ((cur = strchr(cur,',')) != NULL) cur++;
+   }   
+   ints[0] = i - 1;
+   internal_ibmmca_scsi_setup(cur, ints);
+   return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
+__setup("ibmmcascsi=", option_setup);
+#endif
+
 #ifdef MODULE
 /* Eventually this will go into an include file, but this will be later */
 Scsi_Host_Template driver_template = IBMMCA;
 
 #include "scsi_module.c"
-
-/*
- *     Module parameters
- */
-
-MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
-MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
-MODULE_PARM(display, "1i");
-MODULE_PARM(adisplay, "1i");
-MODULE_PARM(bypass, "1i");
-MODULE_PARM(normal, "1i");
-MODULE_PARM(ansi, "1i");
 #endif
 
 /*--------------------------------------------------------------------*/
+
index 99d0fe90f2e41c665b9380c276cbc6cc6af84f74..52cd7386b2011d83fbb9c02f815310fe473d76d4 100644 (file)
@@ -1,3 +1,9 @@
+/* 
+ * Low Level Driver for the IBM Microchannel SCSI Subsystem
+ * (Headerfile, see README.ibmmca for description of the IBM MCA SCSI-driver
+ * For use under the GNU public license within the Linux-kernel project.
+ */
+
 #ifndef _IBMMCA_H
 #define _IBMMCA_H
 
 #include <linux/version.h>
 #endif
 
-#ifndef ibmmca_header_linux_version
-#define ibmmca_header_linux_version(v,p,s) (((v)<<16)+((p)<<8)+(s))
-#endif
-
-/* 
- * Low Level Driver for the IBM Microchannel SCSI Subsystem
- * (Headerfile, see README.ibmmca for description of the IBM MCA SCSI-driver)
- */
+/* Note to the Linux-toplevel-maintainers: 
+ * This file contains the unified header for all available Linux-distributions.
+ * For reasons of maintenance, it is recommended to keep this unmodified to
+ * be downward compatible until I no longer get any requests from people 
+ * using older kernel releases on their PS/2 machines. (23 Apr 2000, M.Lang) */
 
 /* Common forward declarations for all Linux-versions: */
 
-/*services provided to the higher level of Linux SCSI driver */
+/* Interfaces to the midlevel Linux SCSI driver */
 extern int ibmmca_proc_info (char *, char **, off_t, int, int, int);
 extern int ibmmca_detect (Scsi_Host_Template *);
 extern int ibmmca_release (struct Scsi_Host *);
@@ -27,14 +30,39 @@ extern int ibmmca_reset (Scsi_Cmnd *, unsigned int);
 extern int ibmmca_biosparam (Disk *, kdev_t, int *);
 
 /*structure for /proc filesystem */
+extern struct proc_dir_entry proc_scsi_ibmmca;
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,75)
+/* Stuff for Linux >= 2.1.75: */
 /*
  * 2/8/98
  * Note to maintainer of IBMMCA.  Do not change this initializer back to
  * the old format.  Please ask eric@andante.jic.com if you have any questions
  * about this, but it will break things in the future.
  */
-#define IBMMCA {                                                     \
+/*initialization for Scsi_host_template type (Linux >= 2.1.75 && < 2.3.27) */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,27)
+#define IBMMCA {                                                      \
+          proc_dir:       &proc_scsi_ibmmca,    /*proc_dir*/          \
+         proc_info:      ibmmca_proc_info,     /*proc info fn*/      \
+          name:           "IBM SCSI-Subsystem", /*name*/              \
+          detect:         ibmmca_detect,        /*detect fn*/         \
+          release:        ibmmca_release,       /*release fn*/        \
+          command:        ibmmca_command,       /*command fn*/        \
+          queuecommand:   ibmmca_queuecommand,  /*queuecommand fn*/   \
+          abort:          ibmmca_abort,         /*abort fn*/          \
+          reset:          ibmmca_reset,         /*reset fn*/          \
+          bios_param:     ibmmca_biosparam,     /*bios fn*/           \
+          can_queue:      16,                   /*can_queue*/         \
+          this_id:        7,                    /*set by detect*/     \
+          sg_tablesize:   16,                   /*sg_tablesize*/      \
+          cmd_per_lun:    1,                    /*cmd_per_lun*/       \
+          unchecked_isa_dma: 0,                 /*32-Bit Busmaster */ \
+          use_clustering: ENABLE_CLUSTERING     /*use_clustering*/    \
+          }
+#else
+#define IBMMCA {                                                      \
           proc_name:      "ibmmca",             /*proc_name*/         \
          proc_info:      ibmmca_proc_info,     /*proc info fn*/      \
           name:           "IBM SCSI-Subsystem", /*name*/              \
@@ -52,5 +80,34 @@ extern int ibmmca_biosparam (Disk *, kdev_t, int *);
           unchecked_isa_dma: 0,                 /*32-Bit Busmaster */ \
           use_clustering: ENABLE_CLUSTERING     /*use_clustering*/    \
           }
+#endif
+#else
+/* Stuff for Linux < 2.1.75: */
+
+/*initialization for Scsi_host_template type (Linux < 2.1.75) */
+#define IBMMCA {                                      \
+          NULL,                 /*next*/              \
+          NULL,                 /*usage_count*/       \
+          &proc_scsi_ibmmca,    /*proc_dir*/          \
+          ibmmca_proc_info,     /*proc info fn*/      \
+          "IBM SCSI-Subsystem", /*name*/              \
+          ibmmca_detect,        /*detect fn*/         \
+          ibmmca_release,       /*release fn*/        \
+          NULL,                 /*info fn*/           \
+          ibmmca_command,       /*command fn*/        \
+          ibmmca_queuecommand,  /*queuecommand fn*/   \
+          ibmmca_abort,         /*abort fn*/          \
+          ibmmca_reset,         /*reset fn*/          \
+          NULL,                 /*slave_attach fn*/   \
+          ibmmca_biosparam,     /*bios fn*/           \
+          16,                   /*can_queue*/         \
+          7,                    /*set by detect*/     \
+          16,                   /*sg_tablesize*/      \
+          1,                    /*cmd_per_lun*/       \
+          0,                    /*present*/           \
+          0,                    /*unchecked_isa_dma*/ \
+          ENABLE_CLUSTERING     /*use_clustering*/    \
+        }
+#endif /* kernelversion selection */
 
 #endif /* _IBMMCA_H */
index 3494e793e137079fccbe0b6530ef78fdb19317e7..10b65fa2d4494269fddfd98292d0a88a5311acf3 100644 (file)
@@ -1912,7 +1912,7 @@ out:
  * their hosts through the modules entrypoints, and don't use the big
  * list in hosts.c.
  */
-#if defined(CONFIG_MODULES) || defined(CONFIG_BLK_DEV_IDESCSI) || defined(CONFIG_USB_STORAGE)  /* a big #ifdef block... */
+#if defined(CONFIG_MODULES) || defined(CONFIG_BLK_DEV_IDESCSI) || defined(CONFIG_USB_STORAGE) || defined(CONFIG_USB_MICROTEK)  /* a big #ifdef block... */
 
 /*
  * This entry point should be called by a loadable module if it is trying
index 4ac3dbcfb473134bc74a5259bd8b88132fbb9689..cc5bb1c4876ccddbacbdc11fcd376aa0c0dfbd76 100644 (file)
@@ -17,8 +17,8 @@
  * any later version.
  *
  */
- static char * sg_version_str = "Version: 3.1.15 (20000528)";
- static int sg_version_num = 30115; /* 2 digits for each component */
+ static char * sg_version_str = "Version: 3.1.16 (20000716)";
+ static int sg_version_num = 30116; /* 2 digits for each component */
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
  *      - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -1890,9 +1890,9 @@ static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
     Sg_scatter_hold * req_schp = &srp->data;
     Sg_scatter_hold * rsv_schp = &sfp->reserve;
 
+    srp->res_used = 1;
     SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
-    /* round request up to next highest SG_SECTOR_SZ byte boundary */
-    size = (size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK);
+    size = (size + 1) & (~1);    /* round to even for aha1542 */
     if (rsv_schp->k_use_sg > 0) {
         int k, num;
         int rem = size;
@@ -1901,22 +1901,26 @@ static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
        for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
             num = (int)sclp->length;
             if (rem <= num) {
-                sfp->save_scat_len = num;
-                sclp->length = (unsigned)rem;
-                break;
+               if (0 == k) {
+                   req_schp->k_use_sg = 0;
+                   req_schp->buffer = sclp->address;
+               }
+               else {
+                   sfp->save_scat_len = num;
+                   sclp->length = (unsigned)rem;
+                   req_schp->k_use_sg = k + 1;
+                   req_schp->sglist_len = rsv_schp->sglist_len;
+                   req_schp->buffer = rsv_schp->buffer;
+               }
+               req_schp->bufflen = size;
+               req_schp->buffer_mem_src = rsv_schp->buffer_mem_src;
+               req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+               break;
             }
             else
                 rem -= num;
         }
-       if (k < rsv_schp->k_use_sg) {
-           req_schp->k_use_sg = k + 1;   /* adjust scatter list length */
-            req_schp->bufflen = size;
-            req_schp->sglist_len = rsv_schp->sglist_len;
-            req_schp->buffer = rsv_schp->buffer;
-           req_schp->buffer_mem_src = rsv_schp->buffer_mem_src;
-            req_schp->b_malloc_len = rsv_schp->b_malloc_len;
-        }
-        else
+       if (k >= rsv_schp->k_use_sg)
            SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
     }
     else {
@@ -1924,10 +1928,8 @@ static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
         req_schp->bufflen = size;
         req_schp->buffer = rsv_schp->buffer;
        req_schp->buffer_mem_src = rsv_schp->buffer_mem_src;
-       req_schp->k_use_sg = rsv_schp->k_use_sg;
         req_schp->b_malloc_len = rsv_schp->b_malloc_len;
     }
-    srp->res_used = 1;
 }
 
 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
@@ -1937,7 +1939,7 @@ static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
 
     SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->k_use_sg=%d\n",
                               (int)req_schp->k_use_sg));
-    if (rsv_schp->k_use_sg > 0) {
+    if ((rsv_schp->k_use_sg > 0) && (req_schp->k_use_sg > 0)) {
         struct scatterlist * sclp = (struct scatterlist *)rsv_schp->buffer;
 
        if (sfp->save_scat_len > 0)
@@ -2118,13 +2120,12 @@ static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev)
 }
 
 static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
-{      /* if this is to be locked remember that it is called from _bh */
+{
     Sg_request * srp;
     Sg_request * tsrp;
     int dirty = 0;
     int res = 0;
 
-    /* no lock since not expecting any parallel action on this fd */
     srp = sfp->headrp;
     if (srp) {
        while (srp) {
index 399148c74129efd08ce87f9bf2b8d15bbcfd0e38..2c7dbb018de4b29793da7bddaf99f13fbc4ff952 100644 (file)
@@ -62,7 +62,7 @@ obj-$(CONFIG_SOUND_VMIDI)     += v_midi.o
 obj-$(CONFIG_SOUND_VIDC)       += vidc_mod.o
 obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
 obj-$(CONFIG_SOUND_SGALAXY)    += sgalaxy.o ad1848.o
-obj-$(CONFIG_SOUND_AD1816)     += ad1816.o
+obj-$(CONFIG_SOUND_AD1816)     += ad1816.o sound.o
 obj-$(CONFIG_SOUND_ACI_MIXER)  += aci.o
 obj-$(CONFIG_SOUND_AWE32_SYNTH)        += awe_wave.o
 
index b60733b4adb68d22fea0b79bb964f9ee0b88ceb8..49f881a8ce7d665da16243cedfbf838371fa0002 100644 (file)
@@ -689,3 +689,6 @@ static void __exit acm_exit(void)
 
 module_init(acm_init);
 module_exit(acm_exit);
+
+MODULE_AUTHOR("Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik");
+MODULE_DESCRIPTION("USB Abstract Control Model driver for USB modems and ISDN adapters");
index 4560ad60210a9f498ce1df0b774bb72c41963d36..5d6def5627fe3a457f27e1c0d831b036b3ba890f 100644 (file)
@@ -3732,4 +3732,6 @@ void cleanup_module(void)
        usb_deregister(&usb_audio_driver);
 }
 
+MODULE_AUTHOR("Alan Cox <alan@lxorguk.ukuu.org.uk>, Thomas Sailer (sailer@ife.ee.ethz.ch)");
+MODULE_DESCRIPTION("USB Audio Class driver");
 #endif
index 7b19729a9ecdc09c5858db61edec48ad415262d5..d04d3eaaa642ebdf1a7cae87111ad47dd163c8c7 100644 (file)
@@ -841,6 +841,7 @@ void __exit dabusb_cleanup (void)
 MODULE_AUTHOR ("Deti Fliegl, deti@fliegl.de");
 MODULE_DESCRIPTION ("DAB-USB Interface Driver for Linux (c)1999");
 MODULE_PARM (buffers, "i");
+MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");
 
 int __init init_module (void)
 {
index e2056a2e332052599aa35adccbfe197c7738db4f..6ffffdc6fc397a2128c28de52a957578261805c7 100644 (file)
@@ -347,6 +347,9 @@ void cleanup_module(void)
        usb_deregister(&usb_dsbr100_driver);
 }
 
+MODULE_AUTHOR("Markus Demleitner <msdemlei@tucana.harvard.edu>");
+MODULE_DESCRIPTION("D-Link DSB-R100 USB radio driver");
+
 /*
 vi: ts=8
 Sigh.  Of course, I am one of the ts=2 heretics, but Linus' wish is
index e11327cefdd2ee10afb2292ad931b3796f4738a3..65109e9ca37754290d5242f901a1c73848c3cb9f 100644 (file)
@@ -351,3 +351,6 @@ static void __exit evdev_exit(void)
 
 module_init(evdev_init);
 module_exit(evdev_exit);
+
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("Event character device driver");
index ae529b7464a6483754a7e807cb3b1f78eb7103a9..68a981e2765040089a947e08a2aa094becb4c1b7 100644 (file)
@@ -1524,3 +1524,6 @@ static void __exit hid_exit(void)
 
 module_init(hid_init);
 module_exit(hid_exit);
+
+MODULE_AUTHOR("Andreas Gal, Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("USB HID support drivers");
index d70c99ddffb0e08719f27c53852f454566612652..6b85a15f09c5cee80d457397ec02d209c0468df4 100644 (file)
@@ -127,21 +127,36 @@ static int init_model2_sat = -1;
 static int init_model2_yb = -1;
 
 MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
 MODULE_PARM(flags, "i");
+MODULE_PARM_DESC(flags, "Bitfield: 0=VIDIOCSYNC, 1=B/W, 2=show hints, 3=show stats, 4=test pattern, 5=seperate frames, 6=clean frames");
 MODULE_PARM(framerate, "i");
+MODULE_PARM_DESC(framerate, "Framerate setting: 0=slowest, 6=fastest (default=2)");
 MODULE_PARM(lighting, "i");
+MODULE_PARM_DESC(lighting, "Photosensitivity: 0=bright, 1=medium (default), 2=low light");
 MODULE_PARM(sharpness, "i");
+MODULE_PARM_DESC(sharpness, "Model1 noise reduction: 0=smooth, 6=sharp (default=4)");
 MODULE_PARM(videosize, "i");
+MODULE_PARM_DESC(videosize, "Image size: 0=128x96, 1=176x144, 2=352x288, 3=320x240, 4=352x240 (default=1)");
 MODULE_PARM(init_brightness, "i");
+MODULE_PARM_DESC(init_brightness, "Brightness preconfiguration: 0-255 (default=128)");
 MODULE_PARM(init_contrast, "i");
+MODULE_PARM_DESC(init_contrast, "Contrast preconfiguration: 0-255 (default=192)");
 MODULE_PARM(init_color, "i");
+MODULE_PARM_DESC(init_color, "Dolor preconfiguration: 0-255 (default=128)");
 MODULE_PARM(init_hue, "i");
+MODULE_PARM_DESC(init_hue, "Hue preconfiguration: 0-255 (default=128)");
 MODULE_PARM(hue_correction, "i");
+MODULE_PARM_DESC(hue_correction, "YUV colorspace regulation: 0-255 (default=128)");
 
 MODULE_PARM(init_model2_rg, "i");
+MODULE_PARM_DESC(init_model2_rg, "Model2 preconfiguration: 0-255 (default=112)");
 MODULE_PARM(init_model2_rg2, "i");
+MODULE_PARM_DESC(init_model2_rg2, "Model2 preconfiguration: 0-255 (default=47)");
 MODULE_PARM(init_model2_sat, "i");
+MODULE_PARM_DESC(init_model2_sat, "Model2 preconfiguration: 0-255 (default=52)");
 MODULE_PARM(init_model2_yb, "i");
+MODULE_PARM_DESC(init_model2_yb, "Model2 preconfiguration: 0-255 (default=160)");
 
 MODULE_AUTHOR ("module author");
 MODULE_DESCRIPTION ("IBM/Xirlink C-it USB Camera Driver for Linux (c) 2000");
index a61b7801f3651b51fe0fb6a9336a2df4e0104490..d70bfd90ecc927f7e50e6009757e46c79202d137 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/config.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver");
 
 #define USB_VENDOR_ID_LOGITECH         0x046d
 #define USB_DEVICE_ID_LOGITECH_WMFORCE 0xc281
index 98f1a1109dd8f87846b3f6dad7860cb729f95715..f3701965eac3ad5be9889c6cc555676662e4b003 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/random.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("Input layer module");
 
 EXPORT_SYMBOL(input_register_device);
 EXPORT_SYMBOL(input_unregister_device);
index 2210ad0d1923351c49363bfe8770b90f498201f7..99b17a3cda85d26c567f53e887f33804e58becb8 100644 (file)
@@ -83,6 +83,7 @@ struct joydev_list {
 static struct joydev *joydev_table[JOYDEV_MINORS];
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("Joystick device driver");
 MODULE_SUPPORTED_DEVICE("input/js");
 
 static int joydev_correct(int value, struct js_corr *corr)
index 76496349b6213685e3d480f80e1d1f1d4245f0b9..95fce5e80f5f769cf70b0bc0cd8ddc1a7b9ed6f6 100644 (file)
@@ -195,3 +195,6 @@ static void __exit keybdev_exit(void)
 
 module_init(keybdev_init);
 module_exit(keybdev_exit);
+
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("Input driver to keyboard driver binding");
index a3de2b7320edc7ae8d963996409966cd6e09f40b..b8eb74c771447c1467e6fdf520fd2a996848b995 100644 (file)
@@ -1050,3 +1050,6 @@ void __exit microtek_drv_exit(void)
 
 module_init(microtek_drv_init);
 module_exit(microtek_drv_exit);
+
+MODULE_AUTHOR("John Fremlin <vii@penguinpowered.com>, Oliver Neukum <Oliver.Neukum@lrz.uni-muenchen.de>");
+MODULE_DESCRIPTION("Microtek Scanmaker X6 USB scanner driver");
index ea5ad301bbae1f6b7259efdc170de853436fb3a5..ccb118520777551d07a90ece0e978c3de0be7654 100644 (file)
@@ -481,3 +481,6 @@ static void __exit mousedev_exit(void)
 
 module_init(mousedev_init);
 module_exit(mousedev_exit);
+
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("Input driver to PS/2 or ImPS/2 device driver");
index 462a49957fcd6bddcabbf25dab61497f678b4dde..73e3a5be17ea4d9115804d18105ac1ba57ec452c 100644 (file)
@@ -108,16 +108,27 @@ static int cams = 1;
 static int retry_sync = 0;
 
 MODULE_PARM(autoadjust, "i");
+MODULE_PARM_DESC(autoadjust, "CCD dynamically changes exposure");
 MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug level: 0=none, 1=init/detection, 2=warning, 3=config/control, 4=function call, 5=max");
 MODULE_PARM(fix_rgb_offset, "i");
+MODULE_PARM_DESC(fix_rgb_offset, "Fix vertical misalignment of red and blue at 640x480");
 MODULE_PARM(snapshot, "i");
+MODULE_PARM_DESC(snapshot, "Enable snapshot mode");
 MODULE_PARM(sensor, "i");
+MODULE_PARM_DESC(sensor, "Override sensor detection");
 MODULE_PARM(i2c_detect_tries, "i");
+MODULE_PARM_DESC(i2c_detect_tries, "Number of tries to detect sensor");
 MODULE_PARM(aperture, "i");
+MODULE_PARM_DESC(aperture, "Read the OV7610/7620 specs");
 MODULE_PARM(force_rgb, "i");
+MODULE_PARM_DESC(force_rgb, "Read RBG instead of BGR");
 MODULE_PARM(buf_timeout, "i");
+MODULE_PARM_DESC(buf_timeout, "Number of seconds before buffer deallocation");
 MODULE_PARM(cams, "i");
+MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
 MODULE_PARM(retry_sync, "i");
+MODULE_PARM_DESC(retry_sync, "Prevent apps from timing out");
 
 MODULE_AUTHOR("Mark McClelland <mmcclelland@delphi.com> & Bret Wallach & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>");
 MODULE_DESCRIPTION("OV511 USB Camera Driver");
index 8c588f79ef7ad90a25773c1f92c88a84aef86367..0a264faafa7a7a8ac35ba628f480b134fb40df29 100644 (file)
@@ -103,7 +103,7 @@ static int multicast_filter_limit = 32;
 MODULE_AUTHOR("Petko Manolov <petkan@spct.net>");
 MODULE_DESCRIPTION("ADMtek AN986 Pegasus USB Ethernet driver");
 MODULE_PARM(loopback, "i");
-
+MODULE_PARM_DESC(loopback, "Enable loopback mode (Bit 0) and ??? (Bit 1)");
 
 static struct usb_eth_dev usb_dev_id[] = {
        {"Billionton USB-100", 0x08dd, 0x0986, NULL},
index 987f1a8b5011b5238afdbbed8cb0e4319042b0cd..96fa971d85f07fa5f2be1b0d9e770f6a8e65b316 100644 (file)
@@ -527,3 +527,6 @@ static void __exit usblp_exit(void)
 
 module_init(usblp_init);
 module_exit(usblp_exit);
+
+MODULE_AUTHOR("Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap");
+MODULE_DESCRIPTION("USB Printer Device Class driver");
index 011f853f6715f58c3c67e72757a6bcaea588e06d..c84a01fa65a153682efd1a9ff24553870a55fed9 100644 (file)
@@ -445,3 +445,5 @@ void usb_rio_cleanup(void)
 module_init(usb_rio_init);
 module_exit(usb_rio_cleanup);
 
+MODULE_AUTHOR("Cesar Miquel <miquel@df.uba.ar>");
+MODULE_DESCRIPTION("USB Rio 500 driver");
index 146090ab2ba7d15a06c7e1deee556bf64ef88e01..31f913ff9f63c6e45bbccf05e6d0bdbe35d20c93 100644 (file)
@@ -14,13 +14,7 @@ obj-m        :=
 obj-n  :=
 obj-   :=
 
-ifeq ($(CONFIG_USB_SERIAL),y)
-       obj-y += usbserial.o
-endif
-ifeq ($(CONFIG_USB_SERIAL),m)
-       obj-m += usbserial.o
-endif
-
+obj-$(CONFIG_USB_SERIAL)                        += usbserial.o
 obj-$(CONFIG_USB_SERIAL_VISOR)                 += visor.o
 obj-$(CONFIG_USB_SERIAL_WHITEHEAT)             += whiteheat.o
 obj-$(CONFIG_USB_SERIAL_FTDI_SIO)              += ftdi_sio.o
index 9ecd1370b2230be82089368581deef7c0d6d4a22..c5c403b2b3515638fd6b8303aa8174ab7bb1b7d6 100644 (file)
@@ -1768,4 +1768,6 @@ void digi_exit (void)
 module_init(digi_init);
 module_exit(digi_exit);
 
+MODULE_AUTHOR("Peter Berger <pberger@brimson.com>, Al Borchers <borchers@steinerpoint.com>");
+MODULE_DESCRIPTION("Digi AccelePort USB-4 Serial Converter driver");
 
index f78ff752b9a06ac3c98f9e3539efa51ccf3fe30a..aa156ba8d3fc2ae25d650873feff3265ef907fc5 100644 (file)
@@ -741,3 +741,5 @@ void ftdi_sio_exit (void)
 module_init(ftdi_sio_init);
 module_exit(ftdi_sio_exit);
 
+MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>");
+MODULE_DESCRIPTION("USB FTDI SIO driver");
index 2fecdca12591c8015dd73f8b848eb981fb95dabf..64a1f709e7f221f3a303b480331c03f8749478b8 100644 (file)
@@ -721,3 +721,5 @@ void keyspan_exit (void)
 module_init(keyspan_init);
 module_exit(keyspan_exit);
 
+MODULE_AUTHOR("Hugh Blemings <hugh@linuxcare.com>");
+MODULE_DESCRIPTION("Keyspan USB to Serial Converter driver");
index aca2a38c533cb1c61a8d67376f806467fae6d682..675764ad4f3ae6e1866a869cac2a4f849a1e9688 100644 (file)
@@ -720,3 +720,5 @@ void keyspan_pda_exit (void)
 module_init(keyspan_pda_init);
 module_exit(keyspan_pda_exit);
 
+MODULE_AUTHOR("Brian Warner <warner@lothar.com>");
+MODULE_DESCRIPTION("USB Keyspan PDA Converter driver");
index f8145c37fa08fd51dad67e26cfd5e952ad2a06aa..568f2b5cd73b8932562fcf4b9bc47cbcf300bfea 100644 (file)
@@ -434,3 +434,5 @@ void visor_exit (void)
 module_init(visor_init);
 module_exit(visor_exit);
 
+MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");
+MODULE_DESCRIPTION("USB HandSpring Visor driver");
index a6ca6ebcbf2715009fc43d7a112ad6994a1d0f64..7ec405501c966e01fdd4e10b8fb869bda2700458 100644 (file)
@@ -549,3 +549,5 @@ void whiteheat_exit (void)
 module_init(whiteheat_init);
 module_exit(whiteheat_exit);
 
+MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");
+MODULE_DESCRIPTION("USB ConnectTech WhiteHEAT driver");
index aaf1072dba3bb267c525f871bebb6e68852a242c..1b204ab28bc33c0ed15c37fd6d865bf600da3292 100644 (file)
@@ -12,18 +12,19 @@ CFLAGS_protocol.o:= -I../../scsi/
 CFLAGS_transport.o:= -I../../scsi/
 CFLAGS_debug.o:= -I../../scsi/
 CFLAGS_usb.o:= -I../../scsi/
-CFLAGS_scm.o:= -I../../scsi/
+CFLAGS_shuttle_usbat.o:= -I../../scsi/
+CFLAGS_sddr09.o:= -I../../scsi/
 
 ifeq ($(CONFIG_USB_STORAGE_DEBUG),y)
        O_OBJS += debug.o
 endif
 
 ifeq ($(CONFIG_USB_STORAGE_HP8200e),y)
-       O_OBJS += scm.o
+       O_OBJS += shuttle_usbat.o
 endif
 
 ifeq ($(CONFIG_USB_STORAGE_SDDR09),y)
-       O_OBJS += scm.o
+       O_OBJS += sddr09.o
 endif
 
 ifeq ($(CONFIG_USB_STORAGE_FREECOM),y)
diff --git a/drivers/usb/storage/scm.c b/drivers/usb/storage/scm.c
deleted file mode 100644 (file)
index 7bae5e6..0000000
+++ /dev/null
@@ -1,1156 +0,0 @@
-/* Driver for SCM Microsystems USB-ATAPI cable
- *
- * $Id: scm.c,v 1.4 2000/07/24 19:19:52 mdharm Exp $
- *
- * SCM driver v0.2:
- *
- * Removed any reference to maxlen for bulk transfers.
- * Changed scm_bulk_transport to allow for transfers without commands.
- * Changed hp8200e transport to use the request_bufflen field in the
- *   SCSI command for the length of the transfer, rather than calculating
- *   it ourselves based on the command.
- *
- * SCM driver v0.1:
- *
- * First release - hp8200e.
- *
- * Current development and maintainance by:
- *   (c) 2000 Robert Baruch (autophile@dol.net)
- *
- * Many originally ATAPI devices were slightly modified to meet the USB
- * market by using some kind of translation from ATAPI to USB on the host,
- * and the peripheral would translate from USB back to ATAPI.
- *
- * SCM Microsystems (www.scmmicro.com) makes a device, sold to OEM's only, 
- * which does the USB-to-ATAPI conversion.  By obtaining the data sheet on
- * their device under nondisclosure agreement, I have been able to write
- * this driver for Linux.
- *
- * The chip used in the device can also be used for EPP and ISA translation
- * as well. This driver is only guaranteed to work with the ATAPI
- * translation.
- *
- * The only peripherals that I know of (as of 14 Jul 2000) that uses this
- * device is the Hewlett-Packard 8200e CD-Writer Plus.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "transport.h"
-#include "protocol.h"
-#include "usb.h"
-#include "debug.h"
-#include "scm.h"
-
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-
-extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
-       u8 request, u8 requesttype, u16 value, u16 index,
-       void *data, u16 size);
-extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
-       unsigned int len, unsigned int *act_len);
-
-/*
- * Send a control message and wait for the response.
- *
- * us - the pointer to the us_data structure for the device to use
- *
- * request - the URB Setup Packet's first 6 bytes. The first byte always
- *  corresponds to the request type, and the second byte always corresponds
- *  to the request.  The other 4 bytes do not correspond to value and index,
- *  since they are used in a custom way by the SCM protocol.
- *
- * xfer_data - a buffer from which to get, or to which to store, any data
- *  that gets send or received, respectively, with the URB. Even though
- *  it looks like we allocate a buffer in this code for the data, xfer_data
- *  must contain enough allocated space.
- *
- * xfer_len - the number of bytes to send or receive with the URB.
- *
- */
-
-static int scm_send_control(struct us_data *us,
-                    unsigned char command[8],
-                    unsigned char *xfer_data,
-                    unsigned int xfer_len) {
-
-       int result;
-       int pipe;
-       void *buffer = NULL;
-
-       command[6] = xfer_len&0xFF;
-       command[7] = (xfer_len>>8)&0xFF;
-
-       // Get the receive or send control pipe number, based on
-       // the direction indicated by the request type.
-
-       if (command[0] & USB_DIR_IN)
-               pipe = usb_rcvctrlpipe(us->pusb_dev,0);
-       else
-               pipe = usb_sndctrlpipe(us->pusb_dev,0);
-
-
-       // If data is going to be sent or received with the URB,
-       // then allocate a buffer for it. If data is to be sent,
-       // copy the data into the buffer.
-
-       if (xfer_len > 0) {
-               buffer = kmalloc(xfer_len, GFP_KERNEL);
-               if (!(command[0] & USB_DIR_IN))
-                       memcpy(buffer, xfer_data, xfer_len);
-       }
-
-       // Send the URB to the device and wait for a response.
-
-       /* Why are request and request type reversed in this call? */
-
-       result = usb_stor_control_msg(us, pipe,
-                     command[1], command[0],
-                     (((unsigned short)command[3])<<8) | command[2],
-                     (((unsigned short)command[5])<<8) | command[3],
-                     buffer,
-                     xfer_len);
-
-
-       // If data was sent or received with the URB, free the buffer we
-       // allocated earlier, but not before reading the data out of the
-       // buffer if we wanted to receive data.
-
-       if (xfer_len > 0) {
-               if (command[0] & USB_DIR_IN)
-                       memcpy(xfer_data, buffer, xfer_len);
-               kfree(buffer);
-       }
-
-       // Check the return code for the command.
-
-       if (result < 0) {
-               /* a stall is a fatal condition from the device */
-               if (result == -EPIPE) {
-                       US_DEBUGP("-- Stall on control pipe. Clearing\n");
-                       result = usb_clear_halt(us->pusb_dev, pipe);
-                       US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
-                       return USB_STOR_TRANSPORT_FAILED;
-               }
-
-               /* Uh oh... serious problem here */
-               return USB_STOR_TRANSPORT_ERROR;
-       }
-
-       return USB_STOR_TRANSPORT_GOOD;
-}
-
-static int scm_raw_bulk(struct us_data *us, 
-               int direction,
-               unsigned char *data,
-               unsigned short len) {
-
-       int result;
-       int act_len;
-       int pipe;
-
-       if (direction == SCSI_DATA_READ)
-               pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
-       else
-               pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
-
-       result = usb_stor_bulk_msg(us, data, pipe, len, &act_len);
-
-        /* if we stall, we need to clear it before we go on */
-        if (result == -EPIPE) {
-                       US_DEBUGP("EPIPE: clearing endpoint halt for"
-                       " pipe 0x%x, stalled at %d bytes\n",
-                       pipe, act_len);
-                       usb_clear_halt(us->pusb_dev, pipe);
-        }
-
-       if (result) {
-
-                /* NAK - that means we've retried a few times already */
-                       if (result == -ETIMEDOUT) {
-                        US_DEBUGP("scm_raw_bulk():"
-                               " device NAKed\n");
-                        return US_BULK_TRANSFER_FAILED;
-                }
-
-                /* -ENOENT -- we canceled this transfer */
-                if (result == -ENOENT) {
-                        US_DEBUGP("scm_raw_bulk():"
-                               " transfer aborted\n");
-                        return US_BULK_TRANSFER_ABORTED;
-                }
-
-               if (result == -EPIPE) {
-                       US_DEBUGP("scm_raw_bulk():"
-                               " output pipe stalled\n");
-                       return USB_STOR_TRANSPORT_FAILED;
-               }
-
-                /* the catch-all case */
-                US_DEBUGP("us_transfer_partial(): unknown error\n");
-                return US_BULK_TRANSFER_FAILED;
-        }
-       
-       if (act_len != len) {
-               US_DEBUGP("Warning: Transferred only %d bytes\n",
-                       act_len);
-               return US_BULK_TRANSFER_SHORT;
-       }
-
-       US_DEBUGP("Transfered %d of %d bytes\n", act_len, len);
-
-       return US_BULK_TRANSFER_GOOD;
-}
-
-/*
- * Note: direction must be set if command_len == 0.
- */
-
-static int scm_bulk_transport(struct us_data *us,
-                         unsigned char *command,
-                         unsigned short command_len,
-                         int direction,
-                         unsigned char *data,
-                         unsigned short len,
-                         int use_sg) {
-
-       int result = USB_STOR_TRANSPORT_GOOD;
-       int transferred = 0;
-       unsigned char execute[8] = {
-               0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-       };
-       int i;
-       struct scatterlist *sg;
-       char string[64];
-
-       if (command_len != 0) {
-
-               /* Fix up the command's data length */
-
-               command[6] = len&0xFF;
-               command[7] = (len>>8)&0xFF;
-
-               result = scm_send_control(us, 
-                                         execute,
-                                         command,
-                                         command_len);
-
-               if (result != USB_STOR_TRANSPORT_GOOD)
-                       return result;
-       }
-
-       if (len==0)
-               return USB_STOR_TRANSPORT_GOOD;
-
-
-       /* transfer the data payload for the command, if there is any */
-
-
-       if (command_len != 0)
-               direction = (command[0]&0x80) ? SCSI_DATA_READ :
-                       SCSI_DATA_WRITE;
-
-       if (direction == SCSI_DATA_WRITE) {
-
-               /* Debug-print the first 48 bytes of the write transfer */
-
-               if (!use_sg) {
-                       string[0] = 0;
-                       for (i=0; i<len && i<48; i++) {
-                               sprintf(string+strlen(string), "%02X ",
-                                 data[i]);
-                               if ((i%16)==15) {
-                                       US_DEBUGP("%s\n", string);
-                                       string[0] = 0;
-                               }
-                       }
-                       if (string[0]!=0)
-                               US_DEBUGP("%s\n", string);
-               }
-       }
-
-
-       US_DEBUGP("SCM data %s transfer %d sg buffers %d\n",
-                 ( direction==SCSI_DATA_READ ? "in" : "out"),
-                 len, use_sg);
-
-       if (!use_sg)
-               result = scm_raw_bulk(us, direction, data, len);
-       else {
-               sg = (struct scatterlist *)data;
-               for (i=0; i<use_sg && transferred<len; i++) {
-                       result = scm_raw_bulk(us, direction,
-                               sg[i].address, 
-                               len-transferred > sg[i].length ?
-                                       sg[i].length : len-transferred);
-                       if (result!=US_BULK_TRANSFER_GOOD)
-                               break;
-                       transferred += sg[i].length;
-               }
-       }
-
-       return result;
-}
-
-int scm_read(struct us_data *us,
-            unsigned char access,
-            unsigned char reg, 
-            unsigned char *content) {
-
-       int result;
-       unsigned char command[8] = {
-               0xC0, access, reg, 0x00, 0x00, 0x00, 0x00, 0x00
-       };
-
-       result =  scm_send_control(us, command, content, 1);
-
-       if (result != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // US_DEBUGP("SCM: Reg %d -> %02X\n", reg, *content);
-
-       return result;
-}
-
-int scm_write(struct us_data *us,
-            unsigned char access,
-            unsigned char reg, 
-            unsigned char content) {
-
-       int result;
-       unsigned char command[8] = {
-               0x40, access|0x01, reg, content, 0x00, 0x00, 0x00, 0x00
-       };
-
-       result =  scm_send_control(us, command, NULL, 0);
-
-       if (result != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // US_DEBUGP("SCM: Reg %d <- %02X\n", reg, content);
-
-       return result;
-}
-
-int scm_set_shuttle_features(struct us_data *us,
-            unsigned char external_trigger,
-            unsigned char epp_control, 
-            unsigned char mask_byte, 
-            unsigned char test_pattern, 
-            unsigned char subcountH, 
-            unsigned char subcountL) {
-
-       int result;
-       unsigned char command[8] = {
-               0x40, 0x81, epp_control, external_trigger,
-               test_pattern, mask_byte, subcountL, subcountH
-       };
-
-       result =  scm_bulk_transport(us, command, 8, 0, NULL, 0, 0);
-
-       if (result != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       return result;
-}
-
-int scm_read_block(struct us_data *us,
-            unsigned char access,
-            unsigned char reg, 
-            unsigned char *content,
-            unsigned short len,
-            int use_sg) {
-
-       int result;
-       unsigned char command[8] = {
-               0xC0, access|0x02, reg, 0x00, 0x00, 0x00, 0x00, 0x00
-       };
-
-       result =  scm_bulk_transport(us,
-               command, 8, 0, content, len, use_sg);
-
-       if (result != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // US_DEBUGP("SCM: Read data, result %d\n", result);
-
-       return result;
-}
-
-/*
- * Block, waiting for an ATA device to become not busy or to report
- * an error condition.
- */
-
-int scm_wait_not_busy(struct us_data *us) {
-
-       int i;
-       int result;
-       unsigned char status;
-
-       /* Synchronizing cache on a CDR could take a heck of a long time,
-          but probably not more than 15 minutes or so */
-
-       for (i=0; i<500; i++) {
-               result = scm_read(us, SCM_ATA, 0x17, &status);
-               US_DEBUGP("SCM: Write ATA data status is %02X\n", status);
-               if (result!=USB_STOR_TRANSPORT_GOOD)
-                       return result;
-               if (status&0x01) // check condition
-                       return USB_STOR_TRANSPORT_FAILED;
-               if (status&0x20) // device fault
-                       return USB_STOR_TRANSPORT_FAILED;
-               if ((status&0x80)!=0x80) // not busy
-                       break;
-               if (i<5)
-                       wait_ms(100);
-               else if (i<20)
-                       wait_ms(500);
-               else if (i<49)
-                       wait_ms(1000);
-               else if (i<499)
-                       wait_ms(2000);
-       }
-
-       if (i==500)
-               return USB_STOR_TRANSPORT_FAILED;
-
-       return USB_STOR_TRANSPORT_GOOD;
-}
-
-int scm_write_block(struct us_data *us,
-            unsigned char access,
-            unsigned char reg, 
-            unsigned char *content,
-            unsigned short len,
-            int use_sg) {
-
-       int result;
-       unsigned char command[8] = {
-               0x40, access|0x03, reg, 0x00, 0x00, 0x00, 0x00, 0x00
-       };
-
-       result =  scm_bulk_transport(us,
-               command, 8, 0, content, len, use_sg);
-
-       if (result!=USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       return scm_wait_not_busy(us);
-}
-
-int scm_write_block_test(struct us_data *us,
-            unsigned char access,
-            unsigned char *registers,
-            unsigned char *data_out,
-            unsigned short num_registers,
-            unsigned char data_reg, 
-            unsigned char status_reg, 
-            unsigned char qualifier, 
-            unsigned char timeout, 
-            unsigned char *content,
-            unsigned short len,
-            int use_sg) {
-
-       int result;
-       unsigned char command[16] = {
-               0x40, access|0x07, 0x07, 0x17, 0xfc, 0xe7, 0x00, 0x00,
-               0x40, access|0x05, data_reg, status_reg,
-               qualifier, timeout, 0x00, 0x00
-       };
-       int i;
-       unsigned char data[num_registers*2];
-       int transferred;
-       struct scatterlist *sg;
-       char string[64];
-
-       command[14] = len&0xFF;
-       command[15] = (len>>8)&0xFF;
-
-       for (i=0; i<num_registers; i++) {
-               data[i<<1] = registers[i];
-               data[1+(i<<1)] = data_out[i];
-       }
-
-       result =  scm_bulk_transport(us,
-               command, 16, 0, data, num_registers*2, 0);
-
-       if (result!=USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       transferred = 0;
-
-       US_DEBUGP("Transfer out %d bytes, sg buffers %d\n",
-               len, use_sg);
-
-       if (!use_sg) {
-
-               /* Debug-print the first 48 bytes of the transfer */
-
-               string[0] = 0;
-               for (i=0; i<len && i<48; i++) {
-                       sprintf(string+strlen(string), "%02X ",
-                               content[i]);
-                       if ((i%16)==15) {
-                               US_DEBUGP("%s\n", string);
-                               string[0] = 0;
-                       }
-               }
-               if (string[0]!=0)
-                       US_DEBUGP("%s\n", string);
-
-               result = scm_raw_bulk(us, SCSI_DATA_WRITE, content, len);
-
-       } else {
-
-               sg = (struct scatterlist *)content;
-               for (i=0; i<use_sg && transferred<len; i++) {
-                       result = scm_raw_bulk(us, SCSI_DATA_WRITE,
-                               sg[i].address, 
-                               len-transferred > sg[i].length ?
-                                       sg[i].length : len-transferred);
-                       if (result!=US_BULK_TRANSFER_GOOD)
-                               break;
-                       transferred += sg[i].length;
-               }
-       }
-
-       if (result!=USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       return scm_wait_not_busy(us);
-}
-
-int scm_multiple_write(struct us_data *us, 
-                       unsigned char access,
-                       unsigned char *registers,
-                       unsigned char *data_out,
-                       unsigned short num_registers) {
-
-       int result;
-       unsigned char data[num_registers*2];
-       int i;
-       unsigned char cmd[8] = {
-               0x40, access|0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-       };
-
-       for (i=0; i<num_registers; i++) {
-               data[i<<1] = registers[i];
-               data[1+(i<<1)] = data_out[i];
-       }
-
-       result = scm_bulk_transport(us, cmd, 8, 0, data, num_registers*2, 0);
-
-       if (result!=USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       return scm_wait_not_busy(us);
-}
-
-static int hp_8200e_select_and_test_registers(struct us_data *us) {
-
-       int result;
-       int selector;
-       unsigned char status;
-
-       // try device = master, then device = slave.
-
-       for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {
-
-               if ( (result = scm_write(us, SCM_ATA, 0x16, selector)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-
-               if ( (result = scm_read(us, SCM_ATA, 0x17, &status)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-
-               if ( (result = scm_read(us, SCM_ATA, 0x16, &status)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-
-               if ( (result = scm_read(us, SCM_ATA, 0x14, &status)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-
-               if ( (result = scm_read(us, SCM_ATA, 0x15, &status)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-
-               if ( (result = scm_write(us, SCM_ATA, 0x14, 0x55)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-
-               if ( (result = scm_write(us, SCM_ATA, 0x15, 0xAA)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-
-               if ( (result = scm_read(us, SCM_ATA, 0x14, &status)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-
-               if ( (result = scm_read(us, SCM_ATA, 0x15, &status)) != 
-                               USB_STOR_TRANSPORT_GOOD)
-                       return result;
-       }
-
-       return result;
-}
-
-int scm_read_user_io(struct us_data *us,
-               unsigned char *data_flags) {
-
-       unsigned char command[8] = {
-               0xC0, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-       };
-       int result;
-
-       result = scm_send_control(us, command, data_flags, 1);
-
-       if (result != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // US_DEBUGP("SCM: User I/O flags -> %02X\n", *data_flags);
-
-       return result;
-}
-
-int scm_write_user_io(struct us_data *us,
-               unsigned char enable_flags,
-               unsigned char data_flags) {
-
-       unsigned char command[8] = {
-               0x40, 0x82, enable_flags, data_flags, 0x00, 0x00, 0x00, 0x00
-       };
-       int result;
-
-       result = scm_send_control(us, command, NULL, 0);
-
-       if (result != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // US_DEBUGP("SCM: User I/O flags <- %02X\n", data_flags);
-
-       return result;
-}
-
-static int init_sddr09(struct us_data *us) {
-
-       int result;
-       unsigned char data[14];
-       unsigned char command[8] = {
-               0xc1, 0x01, 0, 0, 0, 0, 0, 0
-       };
-       unsigned char command2[8] = {
-               0x41, 0, 0, 0, 0, 0, 0, 0
-       };
-       unsigned char tur[12] = {
-               0x03, 0x20, 0, 0, 0x0e, 0, 0, 0, 0, 0, 0, 0
-       };
-
-       if ( (result = scm_send_control(us, command, data, 2)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       US_DEBUGP("SDDR09: %02X %02X\n", data[0], data[1]);
-
-       command[1] = 0x08;
-
-       if ( (result = scm_send_control(us, command, data, 2)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       US_DEBUGP("SDDR09: %02X %02X\n", data[0], data[1]);
-/*
-       if ( (result = scm_send_control(us, command2, tur, 12)) !=
-                       USB_STOR_TRANSPORT_GOOD) {
-               US_DEBUGP("SDDR09: request sense failed\n");
-               return result;
-       }
-
-       if ( (result = scm_raw_bulk(
-               us, SCSI_DATA_READ, data, 14)) !=
-                       USB_STOR_TRANSPORT_GOOD) {
-               US_DEBUGP("SDDR09: request sense bulk in failed\n");
-               return result;
-       }
-
-       US_DEBUGP("SDDR09: request sense worked\n");
-*/
-       return result;
-}
-
-static int init_8200e(struct us_data *us) {
-
-       int result;
-       unsigned char status;
-
-       // Enable peripheral control signals
-
-       if ( (result = scm_write_user_io(us,
-         SCM_UIO_OE1 | SCM_UIO_OE0,
-         SCM_UIO_EPAD | SCM_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       wait_ms(2000);
-
-       if ( (result = scm_read_user_io(us, &status)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       if ( (result = scm_read_user_io(us, &status)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // Reset peripheral, enable periph control signals
-       // (bring reset signal up)
-
-       if ( (result = scm_write_user_io(us,
-         SCM_UIO_DRVRST | SCM_UIO_OE1 | SCM_UIO_OE0,
-         SCM_UIO_EPAD | SCM_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // Enable periph control signals
-       // (bring reset signal down)
-
-       if ( (result = scm_write_user_io(us,
-         SCM_UIO_OE1 | SCM_UIO_OE0,
-         SCM_UIO_EPAD | SCM_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       wait_ms(250);
-
-       // Write 0x80 to ISA port 0x3F
-
-       if ( (result = scm_write(us, SCM_ISA, 0x3F, 0x80)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // Read ISA port 0x27
-
-       if ( (result = scm_read(us, SCM_ISA, 0x27, &status)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       if ( (result = scm_read_user_io(us, &status)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       if ( (result = hp_8200e_select_and_test_registers(us)) !=
-                        USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       if ( (result = scm_read_user_io(us, &status)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       // Enable periph control signals and card detect
-
-       if ( (result = scm_write_user_io(us,
-         SCM_UIO_ACKD |SCM_UIO_OE1 | SCM_UIO_OE0,
-         SCM_UIO_EPAD | SCM_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       if ( (result = scm_read_user_io(us, &status)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       wait_ms(1400);
-
-       if ( (result = scm_read_user_io(us, &status)) !=
-                       USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       if ( (result = hp_8200e_select_and_test_registers(us)) !=
-                        USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       if ( (result = scm_set_shuttle_features(us, 
-                       0x83, 0x00, 0x88, 0x08, 0x15, 0x14)) !=
-                        USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       return result;
-}
-
-/*
- * Transport for the HP 8200e
- */
-int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
-{
-       int result;
-       unsigned char status;
-       unsigned char registers[32];
-       unsigned char data[32];
-       unsigned int len;
-       int i;
-       char string[64];
-
-       /* This table tells us:
-          X = command not supported
-          L = return length in cmnd[4] (8 bits).
-          H = return length in cmnd[7] and cmnd[8] (16 bits).
-          D = return length in cmnd[6] to cmnd[9] (32 bits).
-          B = return length/blocksize in cmnd[6] to cmnd[8].
-          T = return length in cmnd[6] to cmnd[8] (24 bits).
-          0-9 = fixed return length
-          W = 24 bytes
-          h = return length/2048 in cmnd[7-8].
-       */
-
-       static char *lengths =
-
-       /* 0123456789ABCDEF   0123456789ABCDEF */
-
-         "0XXL0XXXXXXXXXXX" "XXLXXXXXXXX0XX0X"  /* 00-1F */
-         "XXXXX8XXhXH0XXX0" "XXXXX0XXXXXXXXXX"  /* 20-3F */
-         "XXHHL0X0XXH0XX0X" "XHH00HXX0TH0H0XX"  /* 40-5F */
-         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* 60-7F */
-         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* 80-9F */
-         "X0XXX0XXDXDXXXXX" "XXXXXXXXX000XHBX"  /* A0-BF */
-         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* C0-DF */
-         "XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */
-
-       if (us->flags & US_FL_NEED_INIT) {
-               US_DEBUGP("8200e: initializing\n");
-               init_8200e(us);
-               us->flags &= ~US_FL_NEED_INIT;
-       }
-
-       len = srb->request_bufflen;
-
-/*     if (srb->sc_data_direction == SCSI_DATA_WRITE)
-               len = srb->request_bufflen;
-       else {
-
-               switch (lengths[srb->cmnd[0]]) {
-
-               case 'L':
-                       len = srb->cmnd[4];
-                       break;
-               case '0':
-               case '1':
-               case '2':
-               case '3':
-               case '4':
-               case '5':
-               case '6':
-               case '7':
-               case '8':
-               case '9':
-                       len = lengths[srb->cmnd[0]]-'0';
-                       break;
-               case 'H':
-                       len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
-                       break;
-               case 'h':
-                       len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
-                       len <<= 11; // *2048
-                       break;
-               case 'T':
-                       len = (((unsigned int)srb->cmnd[6])<<16) |
-                             (((unsigned int)srb->cmnd[7])<<8) |
-                             srb->cmnd[8];
-                       break;
-               case 'D':
-                       len = (((unsigned int)srb->cmnd[6])<<24) |
-                             (((unsigned int)srb->cmnd[7])<<16) |
-                             (((unsigned int)srb->cmnd[8])<<8) |
-                             srb->cmnd[9];
-                       break;
-               case 'W':
-                       len = 24;
-                       break;
-               case 'B':
-                       // Let's try using the command structure's
-                       //   request_bufflen here 
-                       len = srb->request_bufflen;
-                       break;
-               default:
-                       US_DEBUGP("Error: UNSUPPORTED COMMAND %02X\n",
-                               srb->cmnd[0]);
-                       return USB_STOR_TRANSPORT_ERROR;
-               }
-       } */
-
-       if (len > 0xFFFF) {
-               US_DEBUGP("Error: len = %08X... what do I do now?\n",
-                       len);
-               return USB_STOR_TRANSPORT_ERROR;
-       }
-
-       // US_DEBUGP("XXXXXXXXXXXXXXXX req_bufflen %d, len %d, bufflen %d\n", 
-       //      srb->request_bufflen, len, srb->bufflen);
-
-       /* Send A0 (ATA PACKET COMMAND).
-          Note: I guess we're never going to get any of the ATA
-          commands... just ATA Packet Commands.
-        */
-
-       registers[0] = 0x11;
-       registers[1] = 0x12;
-       registers[2] = 0x13;
-       registers[3] = 0x14;
-       registers[4] = 0x15;
-       registers[5] = 0x16;
-       registers[6] = 0x17;
-       data[0] = 0x00;
-       data[1] = 0x00;
-       data[2] = 0x00;
-       data[3] = len&0xFF;             // (cylL) = expected length (L)
-       data[4] = (len>>8)&0xFF;        // (cylH) = expected length (H)
-       data[5] = 0xB0;                 // (device sel) = slave
-       data[6] = 0xA0;                 // (command) = ATA PACKET COMMAND
-
-       if (srb->sc_data_direction == SCSI_DATA_WRITE) {
-
-               for (i=7; i<19; i++) {
-                       registers[i] = 0x10;
-                       data[i] = (i-7 >= srb->cmd_len) ? 0 : srb->cmnd[i-7];
-               }
-
-               result = scm_write_block_test(us, SCM_ATA, 
-                       registers, data, 19,
-                       0x10, 0x17, 0xFD, 0x30,
-                       srb->request_buffer, 
-                       len, srb->use_sg);
-
-               return result;
-       }
-
-       if ( (result = scm_multiple_write(us, 
-                       SCM_ATA,
-                       registers, data, 7)) != USB_STOR_TRANSPORT_GOOD) {
-               return result;
-       }
-
-       // Write the 12-byte command header.
-
-       if ( (result = scm_write_block(us, 
-                       SCM_ATA, 0x10, srb->cmnd, 12, 0)) !=
-                               USB_STOR_TRANSPORT_GOOD) {
-               return result;
-       }
-
-       // If there is response data to be read in 
-       // then do it here.
-
-       if (len != 0 && (srb->sc_data_direction == SCSI_DATA_READ)) {
-
-               // How many bytes to read in? Check cylL register
-
-               if ( (result = scm_read(us, SCM_ATA, 0x14, &status)) != 
-                   USB_STOR_TRANSPORT_GOOD) {
-                       return result;
-               }
-
-               if (len>0xFF) { // need to read cylH also
-                       len = status;
-                       if ( (result = scm_read(us, SCM_ATA, 0x15, &status)) !=
-                                   USB_STOR_TRANSPORT_GOOD) {
-                               return result;
-                       }
-                       len += ((unsigned int)status)<<8;
-               }
-               else
-                       len = status;
-                       
-
-               result = scm_read_block(us, SCM_ATA, 0x10, 
-                       srb->request_buffer, len, srb->use_sg);
-
-               /* Debug-print the first 32 bytes of the transfer */
-
-               if (!srb->use_sg) {
-                       string[0] = 0;
-                       for (i=0; i<len && i<32; i++) {
-                               sprintf(string+strlen(string), "%02X ",
-                                 ((unsigned char *)srb->request_buffer)[i]);
-                               if ((i%16)==15) {
-                                       US_DEBUGP("%s\n", string);
-                                       string[0] = 0;
-                               }
-                       }
-                       if (string[0]!=0)
-                               US_DEBUGP("%s\n", string);
-               }
-       }
-
-       // US_DEBUGP("Command result %d\n", result);
-
-       return result;
-}
-
-
-/*
- * Transport for the Sandisk SDDR-09
- */
-int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us)
-{
-       int result;
-       unsigned int len;
-       unsigned char send_scsi_command[8] = {
-               0x41, 0, 0, 0, 0, 0, 0, 0
-       };
-       int i;
-       char string[64];
-       unsigned char *ptr;
-       unsigned char inquiry_response[36] = {
-               0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00,
-               'S', 'a', 'n', 'D', 'i', 's', 'k', ' ',
-               'I', 'm', 'a', 'g', 'e', 'M', 'a', 't',
-               'e', ' ', 'S', 'D', 'D', 'R', '0', '9',
-               ' ', ' ', ' ', ' '
-       };
-
-       /* This table tells us:
-          X = command not supported
-          L = return length in cmnd[4] (8 bits).
-          H = return length in cmnd[7] and cmnd[8] (16 bits).
-          D = return length in cmnd[6] to cmnd[9] (32 bits).
-          B = return length/blocksize in cmnd[6] to cmnd[8].
-          T = return length in cmnd[6] to cmnd[8] (24 bits).
-          0-9 = fixed return length
-          W = 24 bytes
-          h = return length/2048 in cmnd[7-8].
-       */
-
-       static char *lengths =
-
-       /* 0123456789ABCDEF   0123456789ABCDEF */
-
-         "0XXL0XXXXXXXXXXX" "XXLXXXXXXXX0XX0X"  /* 00-1F */
-         "XXXXX8XXhXH0XXX0" "XXXXX0XXXXXXXXXX"  /* 20-3F */
-         "XXHHL0X0XXH0XX0X" "XHH00HXX0TH0H0XX"  /* 40-5F */
-         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* 60-7F */
-         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* 80-9F */
-         "X0XXX0XXDXDXXXXX" "XXXXXXXXX000XHBX"  /* A0-BF */
-         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* C0-DF */
-         "XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */
-
-       if (us->flags & US_FL_NEED_INIT) {
-               US_DEBUGP("SDDR-09: initializing\n");
-               init_sddr09(us);
-               us->flags &= ~US_FL_NEED_INIT;
-       }
-
-       /* if (srb->sc_data_direction == SCSI_DATA_WRITE) */
-               len = srb->request_bufflen;
-       /* else {
-
-               switch (lengths[srb->cmnd[0]]) {
-
-               case 'L':
-                       len = srb->cmnd[4];
-                       break;
-               case '0':
-               case '1':
-               case '2':
-               case '3':
-               case '4':
-               case '5':
-               case '6':
-               case '7':
-               case '8':
-               case '9':
-                       len = lengths[srb->cmnd[0]]-'0';
-                       break;
-               case 'H':
-                       len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
-                       break;
-               case 'h':
-                       len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
-                       len <<= 11; // *2048
-                       break;
-               case 'T':
-                       len = (((unsigned int)srb->cmnd[6])<<16) |
-                             (((unsigned int)srb->cmnd[7])<<8) |
-                             srb->cmnd[8];
-                       break;
-               case 'D':
-                       len = (((unsigned int)srb->cmnd[6])<<24) |
-                             (((unsigned int)srb->cmnd[7])<<16) |
-                             (((unsigned int)srb->cmnd[8])<<8) |
-                             srb->cmnd[9];
-                       break;
-               case 'W':
-                       len = 24;
-                       break;
-               case 'B':
-                       // Let's try using the command structure's
-                       //    request_bufflen here
-                       len = srb->request_bufflen;
-                       break;
-               default:
-                       US_DEBUGP("Error: UNSUPPORTED COMMAND %02X\n",
-                               srb->cmnd[0]);
-                       return USB_STOR_TRANSPORT_ERROR;
-               }
-       } */
-
-       if (srb->request_bufflen > 0xFFFF) {
-               US_DEBUGP("Error: len = %08X... what do I do now?\n",
-                       len);
-               return USB_STOR_TRANSPORT_ERROR;
-       }
-
-       /* Dummy up a response for INQUIRY since SDDR09 doesn't
-          respond to INQUIRY commands */
-
-       if (srb->cmnd[0] == INQUIRY) {
-               memcpy(srb->request_buffer, inquiry_response, 36);
-               return USB_STOR_TRANSPORT_GOOD;
-       }
-
-       for (; srb->cmd_len<12; srb->cmd_len++)
-               srb->cmnd[srb->cmd_len] = 0;
-
-       srb->cmnd[1] = 0x20;
-
-       string[0] = 0;
-       for (i=0; i<12; i++)
-         sprintf(string+strlen(string), "%02X ", srb->cmnd[i]);
-
-       US_DEBUGP("SDDR09: Send control for command %s\n",
-               string);
-
-       if ( (result = scm_send_control(us, send_scsi_command, 
-                       srb->cmnd, 12)) != USB_STOR_TRANSPORT_GOOD)
-               return result;
-
-       US_DEBUGP("SDDR09: Control for command OK\n");
-       
-       if (srb->sc_data_direction == SCSI_DATA_WRITE ||
-           srb->sc_data_direction == SCSI_DATA_READ) {
-
-               US_DEBUGP("SDDR09: %s %d bytes\n",
-                       srb->sc_data_direction==SCSI_DATA_WRITE ?
-                         "sending" : "receiving",
-                       len);
-
-               result = scm_bulk_transport(us,
-                       NULL, 0, srb->sc_data_direction,
-                       srb->request_buffer, 
-                       len, srb->use_sg);
-
-               return result;
-
-       } 
-
-       return result;
-}
-
diff --git a/drivers/usb/storage/scm.h b/drivers/usb/storage/scm.h
deleted file mode 100644 (file)
index f57463a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Driver for SCM Microsystems USB-ATAPI cable
- * Header File
- *
- * $Id: scm.h,v 1.3 2000/07/24 19:19:52 mdharm Exp $
- *
- * Current development and maintainance by:
- *   (c) 2000 Robert Baruch (autophile@dol.net)
- *
- * See scm.c for more explanation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _USB_SCM_H
-#define _USB_SCM_H
-
-#define SCM_EPP_PORT           0x10
-#define SCM_EPP_REGISTER       0x30
-#define SCM_ATA                        0x40
-#define SCM_ISA                        0x50
-
-/* SCM User I/O Data registers */
-
-#define SCM_UIO_EPAD           0x80 // Enable Peripheral Control Signals
-#define SCM_UIO_CDT            0x40 // Card Detect (Read Only)
-                                    // CDT = ACKD & !UI1 & !UI0
-#define SCM_UIO_1              0x20 // I/O 1
-#define SCM_UIO_0              0x10 // I/O 0
-#define SCM_UIO_EPP_ATA                0x08 // 1=EPP mode, 0=ATA mode
-#define SCM_UIO_UI1            0x04 // Input 1
-#define SCM_UIO_UI0            0x02 // Input 0
-#define SCM_UIO_INTR_ACK       0x01 // Interrupt (ATA & ISA)/Acknowledge (EPP)
-
-/* SCM User I/O Enable registers */
-
-#define SCM_UIO_DRVRST         0x80 // Reset Peripheral
-#define SCM_UIO_ACKD           0x40 // Enable Card Detect
-#define SCM_UIO_OE1            0x20 // I/O 1 set=output/clr=input
-                                    // If ACKD=1, set OE1 to 1 also.
-#define SCM_UIO_OE0            0x10 // I/O 0 set=output/clr=input
-#define SCM_UIO_ADPRST         0x01 // Reset SCM chip
-
-/* SCM-specific commands */
-
-extern int scm_read(struct us_data *us, unsigned char access,
-       unsigned char reg, unsigned char *content);
-extern int scm_write(struct us_data *us, unsigned char access,
-       unsigned char reg, unsigned char content);
-extern int scm_read_block(struct us_data *us, unsigned char access,
-       unsigned char reg, unsigned char *content, unsigned short len,
-       int use_sg);
-extern int scm_write_block(struct us_data *us, unsigned char access,
-       unsigned char reg, unsigned char *content, unsigned short len,
-       int use_sg);
-extern int scm_multiple_write(struct us_data *us, unsigned char access,
-       unsigned char *registers, unsigned char *data_out,
-       unsigned short num_registers);
-extern int scm_read_user_io(struct us_data *us, unsigned char *data_flags);
-extern int scm_write_user_io(struct us_data *us,
-       unsigned char enable_flags, unsigned char data_flags);
-
-/* HP 8200e stuff */
-
-extern int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us);
-
-/* Sandisk SDDR-09 stuff */
-
-extern int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us);
-
-#endif
index 21fe3ec972811cc688de026f7e914e094f1e16f6..25328669b793b2693646a18d00e41d20b209ba39 100644 (file)
@@ -1,7 +1,7 @@
 /* Driver for USB Mass Storage compliant devices
  * SCSI layer glue code
  *
- * $Id: scsiglue.c,v 1.5 2000/07/24 18:55:39 mdharm Exp $
+ * $Id: scsiglue.c,v 1.6 2000/07/25 23:04:47 mdharm Exp $
  *
  * Current development and maintainance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
 
 #include <linux/malloc.h>
 
-/* direction table -- this indicates the direction of the data
- * transfer for each command code -- a 1 indicates input
- */
-/* FIXME: we need to use the new direction indicators in the Scsi_Cmnd
- * structure, not this table.  First we need to evaluate if it's being set
- * correctly for us, though
- */
-unsigned char us_direction[256/8] = {
-       0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77, 
-       0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-
 /*
  * kernel thread actions
  */
index e9da1bcc01c644cc8921a2da731b4ca8a342ef8f..f81787678f82c6e7955b9bc8312e3db05ec36ecf 100644 (file)
@@ -1,7 +1,7 @@
 /* Driver for USB Mass Storage compliant devices
  * SCSI Connecting Glue Header File
  *
- * $Id: scsiglue.h,v 1.2 2000/07/19 22:12:07 mdharm Exp $
+ * $Id: scsiglue.h,v 1.3 2000/07/25 23:04:47 mdharm Exp $
  *
  * Current development and maintainance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -46,7 +46,6 @@
 #include "hosts.h"
 
 extern unsigned char usb_stor_sense_notready[18];
-extern unsigned char us_direction[256/8];
 extern Scsi_Host_Template usb_stor_host_template;
 extern int usb_stor_scsiSense10to6(Scsi_Cmnd*);
 extern int usb_stor_scsiSense6to10(Scsi_Cmnd*);
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
new file mode 100644 (file)
index 0000000..2757129
--- /dev/null
@@ -0,0 +1,635 @@
+/* Driver for SanDisk SDDR-09 SmartMedia reader
+ *
+ * SDDR09 driver v0.1:
+ *
+ * First release
+ *
+ * Current development and maintainance by:
+ *   (c) 2000 Robert Baruch (autophile@dol.net)
+ *
+ * The SanDisk SDDR-09 SmartMedia reader uses the Shuttle EUSB-01 chip.
+ * This chip is a programmable USB controller. In the SDDR-09, it has
+ * been programmed to obey a certain limited set of SCSI commands. This
+ * driver translates the "real" SCSI commands to the SDDR-09 SCSI
+ * commands.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "transport.h"
+#include "protocol.h"
+#include "usb.h"
+#include "debug.h"
+#include "sddr09.h"
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/malloc.h>
+
+extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
+       u8 request, u8 requesttype, u16 value, u16 index,
+       void *data, u16 size);
+extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
+       unsigned int len, unsigned int *act_len);
+
+#define short_pack(b1,b2) ( ((u16)(b1)) | ( ((u16)(b2))<<8 ) )
+#define LSB_of(s) ((s)&0xFF)
+#define MSB_of(s) ((s)>>8)
+
+/*
+ * Send a control message and wait for the response.
+ *
+ * us - the pointer to the us_data structure for the device to use
+ *
+ * request - the URB Setup Packet's first 6 bytes. The first byte always
+ *  corresponds to the request type, and the second byte always corresponds
+ *  to the request.  The other 4 bytes do not correspond to value and index,
+ *  since they are used in a custom way by the SCM protocol.
+ *
+ * xfer_data - a buffer from which to get, or to which to store, any data
+ *  that gets send or received, respectively, with the URB. Even though
+ *  it looks like we allocate a buffer in this code for the data, xfer_data
+ *  must contain enough allocated space.
+ *
+ * xfer_len - the number of bytes to send or receive with the URB.
+ *
+ */
+
+static int sddr09_send_control(struct us_data *us,
+               int pipe,
+               unsigned char request,
+               unsigned char requesttype,
+               unsigned short value,
+               unsigned short index,
+               unsigned char *xfer_data,
+               unsigned int xfer_len) {
+
+       int result;
+
+       // If data is going to be sent or received with the URB,
+       // then allocate a buffer for it. If data is to be sent,
+       // copy the data into the buffer.
+/*
+       if (xfer_len > 0) {
+               buffer = kmalloc(xfer_len, GFP_KERNEL);
+               if (!(command[0] & USB_DIR_IN))
+                       memcpy(buffer, xfer_data, xfer_len);
+       }
+*/
+       // Send the URB to the device and wait for a response.
+
+       /* Why are request and request type reversed in this call? */
+
+       result = usb_stor_control_msg(us, pipe,
+                       request, requesttype, value, index,
+                       xfer_data, xfer_len);
+
+
+       // If data was sent or received with the URB, free the buffer we
+       // allocated earlier, but not before reading the data out of the
+       // buffer if we wanted to receive data.
+/*
+       if (xfer_len > 0) {
+               if (command[0] & USB_DIR_IN)
+                       memcpy(xfer_data, buffer, xfer_len);
+               kfree(buffer);
+       }
+*/
+       // Check the return code for the command.
+
+       if (result < 0) {
+               /* if the command was aborted, indicate that */
+               if (result == -ENOENT)
+                       return USB_STOR_TRANSPORT_ABORTED;
+
+               /* a stall is a fatal condition from the device */
+               if (result == -EPIPE) {
+                       US_DEBUGP("-- Stall on control pipe. Clearing\n");
+                       result = usb_clear_halt(us->pusb_dev, pipe);
+                       US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
+                       return USB_STOR_TRANSPORT_FAILED;
+               }
+
+               /* Uh oh... serious problem here */
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
+static int sddr09_raw_bulk(struct us_data *us, 
+               int direction,
+               unsigned char *data,
+               unsigned short len) {
+
+       int result;
+       int act_len;
+       int pipe;
+
+       if (direction == SCSI_DATA_READ)
+               pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
+       else
+               pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
+
+       result = usb_stor_bulk_msg(us, data, pipe, len, &act_len);
+
+        /* if we stall, we need to clear it before we go on */
+        if (result == -EPIPE) {
+                       US_DEBUGP("EPIPE: clearing endpoint halt for"
+                       " pipe 0x%x, stalled at %d bytes\n",
+                       pipe, act_len);
+                       usb_clear_halt(us->pusb_dev, pipe);
+        }
+
+       if (result) {
+
+                /* NAK - that means we've retried a few times already */
+                       if (result == -ETIMEDOUT) {
+                        US_DEBUGP("usbat_raw_bulk():"
+                               " device NAKed\n");
+                        return US_BULK_TRANSFER_FAILED;
+                }
+
+                /* -ENOENT -- we canceled this transfer */
+                if (result == -ENOENT) {
+                        US_DEBUGP("usbat_raw_bulk():"
+                               " transfer aborted\n");
+                        return US_BULK_TRANSFER_ABORTED;
+                }
+
+               if (result == -EPIPE) {
+                       US_DEBUGP("usbat_raw_bulk():"
+                               " output pipe stalled\n");
+                       return USB_STOR_TRANSPORT_FAILED;
+               }
+
+                /* the catch-all case */
+                US_DEBUGP("us_transfer_partial(): unknown error\n");
+                return US_BULK_TRANSFER_FAILED;
+        }
+       
+       if (act_len != len) {
+               US_DEBUGP("Warning: Transferred only %d bytes\n",
+                       act_len);
+               return US_BULK_TRANSFER_SHORT;
+       }
+
+       US_DEBUGP("Transfered %d of %d bytes\n", act_len, len);
+
+       return US_BULK_TRANSFER_GOOD;
+}
+
+/*
+ * Note: direction must be set if command_len == 0.
+ */
+
+static int sddr09_bulk_transport(struct us_data *us,
+                         unsigned char *command,
+                         unsigned short command_len,
+                         int direction,
+                         unsigned char *data,
+                         unsigned short len,
+                         int use_sg) {
+
+       int result = USB_STOR_TRANSPORT_GOOD;
+       int transferred = 0;
+       unsigned char execute[8] = {
+               0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       int i;
+       struct scatterlist *sg;
+       char string[64];
+/*
+       if (command_len != 0) {
+
+               // Fix up the command's data length
+
+               command[6] = len&0xFF;
+               command[7] = (len>>8)&0xFF;
+
+               result = sddr09_send_control(us, 
+                                         execute,
+                                         command,
+                                         command_len);
+
+               if (result != USB_STOR_TRANSPORT_GOOD)
+                       return result;
+       }
+*/
+       if (len==0)
+               return USB_STOR_TRANSPORT_GOOD;
+
+
+       /* transfer the data payload for the command, if there is any */
+
+
+       if (command_len != 0)
+               direction = (command[0]&0x80) ? SCSI_DATA_READ :
+                       SCSI_DATA_WRITE;
+
+       if (direction == SCSI_DATA_WRITE) {
+
+               /* Debug-print the first 48 bytes of the write transfer */
+
+               if (!use_sg) {
+                       string[0] = 0;
+                       for (i=0; i<len && i<48; i++) {
+                               sprintf(string+strlen(string), "%02X ",
+                                 data[i]);
+                               if ((i%16)==15) {
+                                       US_DEBUGP("%s\n", string);
+                                       string[0] = 0;
+                               }
+                       }
+                       if (string[0]!=0)
+                               US_DEBUGP("%s\n", string);
+               }
+       }
+
+
+       US_DEBUGP("SCM data %s transfer %d sg buffers %d\n",
+                 ( direction==SCSI_DATA_READ ? "in" : "out"),
+                 len, use_sg);
+
+       if (!use_sg)
+               result = sddr09_raw_bulk(us, direction, data, len);
+       else {
+               sg = (struct scatterlist *)data;
+               for (i=0; i<use_sg && transferred<len; i++) {
+                       result = sddr09_raw_bulk(us, direction,
+                               sg[i].address, 
+                               len-transferred > sg[i].length ?
+                                       sg[i].length : len-transferred);
+                       if (result!=US_BULK_TRANSFER_GOOD)
+                               break;
+                       transferred += sg[i].length;
+               }
+       }
+
+       return result;
+}
+
+int sddr09_read_data(struct us_data *us,
+               unsigned long address,
+               unsigned short sectors,
+               unsigned char *content,
+               int use_sg) {
+
+       int result;
+       unsigned char command[12] = {
+               0xe8, 0x20, MSB_of(address>>16),
+               LSB_of(address>>16), MSB_of(address&0xFFFF),
+               LSB_of(address&0xFFFF), 0, 0, 0, 0,
+               MSB_of(sectors), LSB_of(sectors)
+       };
+
+       result = sddr09_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0,
+               0x41,
+               0,
+               0,
+               command,
+               12);
+               
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       result = sddr09_bulk_transport(us,
+               NULL, 0, SCSI_DATA_READ, content,
+               sectors*512, use_sg);
+
+       return result;
+}
+
+int sddr09_read_control(struct us_data *us,
+               unsigned long address,
+               unsigned short sectors,
+               unsigned char *content,
+               int use_sg) {
+
+       int result;
+       unsigned char command[12] = {
+               0xe8, 0x21, MSB_of(address>>16),
+               LSB_of(address>>16), MSB_of(address&0xFFFF),
+               LSB_of(address&0xFFFF), 0, 0, 0, 0,
+               MSB_of(sectors), LSB_of(sectors)
+       };
+
+       result = sddr09_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0,
+               0x41,
+               0,
+               0,
+               command,
+               12);
+               
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       result = sddr09_bulk_transport(us,
+               NULL, 0, SCSI_DATA_READ, content,
+               sectors*64, use_sg);
+
+       return result;
+}
+
+int sddr09_read_deviceID(struct us_data *us,
+               unsigned char *manufacturerID,
+               unsigned char *deviceID) {
+
+       int result;
+       unsigned char command[12] = {
+               0xed, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+       };
+       unsigned char content[64];
+
+       result = sddr09_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0,
+               0x41,
+               0,
+               0,
+               command,
+               12);
+
+       US_DEBUGP("Result of send_control for device ID is %d\n",
+               result);
+               
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       result = sddr09_bulk_transport(us,
+               NULL, 0, SCSI_DATA_READ, content,
+               64, 0);
+
+       *manufacturerID = content[0];
+       *deviceID = content[1];
+
+       return result;
+}
+
+int sddr09_read_status(struct us_data *us,
+               unsigned char *status) {
+
+       int result;
+       unsigned char command[12] = {
+               0xec, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+       };
+       unsigned char content[2];
+
+       result = sddr09_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0,
+               0x41,
+               0,
+               0,
+               command,
+               12);
+               
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       result = sddr09_bulk_transport(us,
+               NULL, 0, SCSI_DATA_READ, status,
+               1, 0);
+
+       return result;
+}
+
+int sddr09_reset(struct us_data *us) {
+
+       int result;
+       unsigned char command[12] = {
+               0xeb, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+       };
+
+       result = sddr09_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0,
+               0x41,
+               0,
+               0,
+               command,
+               12);
+               
+       return result;
+}
+
+/*
+static int init_sddr09(struct us_data *us) {
+
+       int result;
+       unsigned char data[14];
+       unsigned char command[8] = {
+               0xc1, 0x01, 0, 0, 0, 0, 0, 0
+       };
+       unsigned char command2[8] = {
+               0x41, 0, 0, 0, 0, 0, 0, 0
+       };
+       unsigned char tur[12] = {
+               0x03, 0x20, 0, 0, 0x0e, 0, 0, 0, 0, 0, 0, 0
+       };
+
+       if ( (result = sddr09_send_control(us, command, data, 2)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("SDDR09: %02X %02X\n", data[0], data[1]);
+
+       command[1] = 0x08;
+
+       if ( (result = sddr09_send_control(us, command, data, 2)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("SDDR09: %02X %02X\n", data[0], data[1]);
+
+       if ( (result = sddr09_send_control(us, command2, tur, 12)) !=
+                       USB_STOR_TRANSPORT_GOOD) {
+               US_DEBUGP("SDDR09: request sense failed\n");
+               return result;
+       }
+
+       if ( (result = sddr09_raw_bulk(
+               us, SCSI_DATA_READ, data, 14)) !=
+                       USB_STOR_TRANSPORT_GOOD) {
+               US_DEBUGP("SDDR09: request sense bulk in failed\n");
+               return result;
+       }
+
+       US_DEBUGP("SDDR09: request sense worked\n");
+
+       return result;
+}
+*/
+
+/*
+ * Transport for the Sandisk SDDR-09
+ */
+int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us)
+{
+       int result;
+       unsigned char send_scsi_command[8] = {
+               0x41, 0, 0, 0, 0, 0, 0, 0
+       };
+       int i;
+       char string[64];
+       unsigned char inquiry_response[36] = {
+               0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00,
+               'S', 'a', 'n', 'D', 'i', 's', 'k', ' ',
+               'I', 'm', 'a', 'g', 'e', 'M', 'a', 't',
+               'e', ' ', 'S', 'D', 'D', 'R', '0', '9',
+               ' ', ' ', ' ', ' '
+       };
+       unsigned char deviceID;
+       unsigned char manufacturerID;
+       unsigned char *ptr;
+
+/*
+       if (us->flags & US_FL_NEED_INIT) {
+               US_DEBUGP("SDDR-09: initializing\n");
+               init_sddr09(us);
+               us->flags &= ~US_FL_NEED_INIT;
+       }
+*/
+
+       ptr = (unsigned char *)srb->request_buffer;
+
+       /* Dummy up a response for INQUIRY since SDDR09 doesn't
+          respond to INQUIRY commands */
+
+       if (srb->cmnd[0] == INQUIRY) {
+               memcpy(srb->request_buffer, inquiry_response, 36);
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       if (srb->cmnd[0] == READ_CAPACITY) {
+
+               US_DEBUGP("Reading capacity...\n");
+
+               result = sddr09_read_deviceID(us,
+                       &manufacturerID,
+                       &deviceID);
+
+               US_DEBUGP("Result of read_deviceID is %d\n",
+                       result);
+
+               if (result != USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               US_DEBUGP("Device ID = %02X\n", deviceID);
+               US_DEBUGP("Manuf  ID = %02X\n", manufacturerID);
+
+               ptr[0] = 0;
+               ptr[1] = 0;
+               ptr[2] = 0;
+               ptr[3] = 0;
+
+               switch (deviceID) {
+
+               case 0x6e: // 1MB
+               case 0xe8:
+               case 0xec:
+                       ptr[4] = 0;
+                       ptr[5] = 0x10;
+                       break;
+
+               case 0xea: // 2MB
+               case 0x64:
+               case 0x5d:
+                       ptr[4] = 0;
+                       ptr[5] = 0x20;
+                       break;
+
+               case 0xe3: // 4MB
+               case 0xe5:
+               case 0x6b:
+               case 0xd5:
+                       ptr[4] = 0;
+                       ptr[5] = 0x40;
+                       break;
+
+               case 0xe6: // 8MB
+               case 0xd6:
+                       ptr[4] = 0;
+                       ptr[5] = 0x80;
+                       break;
+
+               case 0x75: // 32MB
+                       ptr[4] = 0x02;
+                       ptr[5] = 0;
+                       break;
+
+               default: // unknown
+                       ptr[4] = 0;
+                       ptr[5] = 0;
+
+               }
+
+               ptr[6] = 0;
+               ptr[7] = 0;
+               
+               return USB_STOR_TRANSPORT_GOOD;
+       }
+
+       for (; srb->cmd_len<12; srb->cmd_len++)
+               srb->cmnd[srb->cmd_len] = 0;
+
+       srb->cmnd[1] = 0x20;
+
+       string[0] = 0;
+       for (i=0; i<12; i++)
+         sprintf(string+strlen(string), "%02X ", srb->cmnd[i]);
+
+       US_DEBUGP("SDDR09: Send control for command %s\n",
+               string);
+
+       if ( (result = sddr09_send_control(us,
+                       usb_sndctrlpipe(us->pusb_dev,0),
+                       0,
+                       0x41,
+                       0,
+                       0,
+                       srb->cmnd,
+                       12)) != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("SDDR09: Control for command OK\n");
+
+       if (srb->request_bufflen == 0)
+               return USB_STOR_TRANSPORT_GOOD;
+       
+       if (srb->sc_data_direction == SCSI_DATA_WRITE ||
+           srb->sc_data_direction == SCSI_DATA_READ) {
+
+               US_DEBUGP("SDDR09: %s %d bytes\n",
+                       srb->sc_data_direction==SCSI_DATA_WRITE ?
+                         "sending" : "receiving",
+                       srb->request_bufflen);
+
+               result = sddr09_bulk_transport(us,
+                       NULL, 0, srb->sc_data_direction,
+                       srb->request_buffer, 
+                       srb->request_bufflen, srb->use_sg);
+
+               return result;
+
+       } 
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h
new file mode 100644 (file)
index 0000000..76a7495
--- /dev/null
@@ -0,0 +1,31 @@
+/* Driver for SanDisk SDDR-09 SmartMedia reader
+ * Header File
+ *
+ * Current development and maintainance by:
+ *   (c) 2000 Robert Baruch (autophile@dol.net)
+ *
+ * See sddr09.c for more explanation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _USB_SHUTTLE_EUSB_SDDR09_H
+#define _USB_SHUTTLE_EUSB_SDDR09_H
+
+/* Sandisk SDDR-09 stuff */
+
+extern int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us);
+
+#endif
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
new file mode 100644 (file)
index 0000000..f68595c
--- /dev/null
@@ -0,0 +1,1067 @@
+/* Driver for SCM Microsystems USB-ATAPI cable
+ *
+ * SCM driver v0.2:
+ *
+ * Removed any reference to maxlen for bulk transfers.
+ * Changed scm_bulk_transport to allow for transfers without commands.
+ * Changed hp8200e transport to use the request_bufflen field in the
+ *   SCSI command for the length of the transfer, rather than calculating
+ *   it ourselves based on the command.
+ *
+ * SCM driver v0.1:
+ *
+ * First release - hp8200e.
+ *
+ * Current development and maintainance by:
+ *   (c) 2000 Robert Baruch (autophile@dol.net)
+ *
+ * Many originally ATAPI devices were slightly modified to meet the USB
+ * market by using some kind of translation from ATAPI to USB on the host,
+ * and the peripheral would translate from USB back to ATAPI.
+ *
+ * SCM Microsystems (www.scmmicro.com) makes a device, sold to OEM's only, 
+ * which does the USB-to-ATAPI conversion.  By obtaining the data sheet on
+ * their device under nondisclosure agreement, I have been able to write
+ * this driver for Linux.
+ *
+ * The chip used in the device can also be used for EPP and ISA translation
+ * as well. This driver is only guaranteed to work with the ATAPI
+ * translation.
+ *
+ * The only peripherals that I know of (as of 14 Jul 2000) that uses this
+ * device is the Hewlett-Packard 8200e CD-Writer Plus.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "transport.h"
+#include "protocol.h"
+#include "usb.h"
+#include "debug.h"
+#include "shuttle_usbat.h"
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/malloc.h>
+
+extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
+       u8 request, u8 requesttype, u16 value, u16 index,
+       void *data, u16 size);
+extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
+       unsigned int len, unsigned int *act_len);
+
+#define short_pack(b1,b2) ( ((u16)(b1)) | ( ((u16)(b2))<<8 ) )
+#define LSB_of(s) ((s)&0xFF)
+#define MSB_of(s) ((s)>>8)
+
+/*
+ * Send a control message and wait for the response.
+ *
+ * us - the pointer to the us_data structure for the device to use
+ *
+ * request - the URB Setup Packet's first 6 bytes. The first byte always
+ *  corresponds to the request type, and the second byte always corresponds
+ *  to the request.  The other 4 bytes do not correspond to value and index,
+ *  since they are used in a custom way by the SCM protocol.
+ *
+ * xfer_data - a buffer from which to get, or to which to store, any data
+ *  that gets send or received, respectively, with the URB. Even though
+ *  it looks like we allocate a buffer in this code for the data, xfer_data
+ *  must contain enough allocated space.
+ *
+ * xfer_len - the number of bytes to send or receive with the URB.
+ *
+ */
+
+static int usbat_send_control(struct us_data *us,
+               int pipe,
+               unsigned char request,
+               unsigned char requesttype,
+               unsigned short value,
+               unsigned short index,
+               unsigned char *xfer_data,
+               unsigned int xfer_len) {
+
+       int result;
+
+       // If data is going to be sent or received with the URB,
+       // then allocate a buffer for it. If data is to be sent,
+       // copy the data into the buffer.
+/*
+       if (xfer_len > 0) {
+               buffer = kmalloc(xfer_len, GFP_KERNEL);
+               if (!(command[0] & USB_DIR_IN))
+                       memcpy(buffer, xfer_data, xfer_len);
+       }
+*/
+       // Send the URB to the device and wait for a response.
+
+       /* Why are request and request type reversed in this call? */
+
+       result = usb_stor_control_msg(us, pipe,
+                       request, requesttype, value, index,
+                       xfer_data, xfer_len);
+
+
+       // If data was sent or received with the URB, free the buffer we
+       // allocated earlier, but not before reading the data out of the
+       // buffer if we wanted to receive data.
+/*
+       if (xfer_len > 0) {
+               if (command[0] & USB_DIR_IN)
+                       memcpy(xfer_data, buffer, xfer_len);
+               kfree(buffer);
+       }
+*/
+       // Check the return code for the command.
+
+       if (result < 0) {
+               /* if the command was aborted, indicate that */
+               if (result == -ENOENT)
+                       return USB_STOR_TRANSPORT_ABORTED;
+
+               /* a stall is a fatal condition from the device */
+               if (result == -EPIPE) {
+                       US_DEBUGP("-- Stall on control pipe. Clearing\n");
+                       result = usb_clear_halt(us->pusb_dev, pipe);
+                       US_DEBUGP("-- usb_clear_halt() returns %d\n", result);
+                       return USB_STOR_TRANSPORT_FAILED;
+               }
+
+               /* Uh oh... serious problem here */
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
+static int usbat_raw_bulk(struct us_data *us, 
+               int direction,
+               unsigned char *data,
+               unsigned short len) {
+
+       int result;
+       int act_len;
+       int pipe;
+
+       if (direction == SCSI_DATA_READ)
+               pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
+       else
+               pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
+
+       result = usb_stor_bulk_msg(us, data, pipe, len, &act_len);
+
+        /* if we stall, we need to clear it before we go on */
+        if (result == -EPIPE) {
+                       US_DEBUGP("EPIPE: clearing endpoint halt for"
+                       " pipe 0x%x, stalled at %d bytes\n",
+                       pipe, act_len);
+                       usb_clear_halt(us->pusb_dev, pipe);
+        }
+
+       if (result) {
+
+                /* NAK - that means we've retried a few times already */
+                       if (result == -ETIMEDOUT) {
+                        US_DEBUGP("usbat_raw_bulk():"
+                               " device NAKed\n");
+                        return US_BULK_TRANSFER_FAILED;
+                }
+
+                /* -ENOENT -- we canceled this transfer */
+                if (result == -ENOENT) {
+                        US_DEBUGP("usbat_raw_bulk():"
+                               " transfer aborted\n");
+                        return US_BULK_TRANSFER_ABORTED;
+                }
+
+               if (result == -EPIPE) {
+                       US_DEBUGP("usbat_raw_bulk():"
+                               " output pipe stalled\n");
+                       return USB_STOR_TRANSPORT_FAILED;
+               }
+
+                /* the catch-all case */
+                US_DEBUGP("us_transfer_partial(): unknown error\n");
+                return US_BULK_TRANSFER_FAILED;
+        }
+       
+       if (act_len != len) {
+               US_DEBUGP("Warning: Transferred only %d bytes\n",
+                       act_len);
+               return US_BULK_TRANSFER_SHORT;
+       }
+
+       US_DEBUGP("Transfered %d of %d bytes\n", act_len, len);
+
+       return US_BULK_TRANSFER_GOOD;
+}
+
+/*
+ * Note: direction must be set if command_len == 0.
+ */
+
+static int usbat_bulk_transport(struct us_data *us,
+                         unsigned char *command,
+                         unsigned short command_len,
+                         int direction,
+                         unsigned char *data,
+                         unsigned short len,
+                         int use_sg) {
+
+       int result = USB_STOR_TRANSPORT_GOOD;
+       int transferred = 0;
+       unsigned char execute[8] = {
+               0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       int i;
+       struct scatterlist *sg;
+       char string[64];
+       int pipe;
+
+/*
+       if (command_len != 0) {
+
+               // Fix up the command's data length
+
+               command[6] = len&0xFF;
+               command[7] = (len>>8)&0xFF;
+
+               
+
+               result = usbat_send_control(us, 
+                                         execute,
+                                         command,
+                                         command_len);
+
+               if (result != USB_STOR_TRANSPORT_GOOD)
+                       return result;
+       }
+*/
+       if (len==0)
+               return USB_STOR_TRANSPORT_GOOD;
+
+
+       /* transfer the data payload for the command, if there is any */
+
+
+       if (command_len != 0)
+               direction = (command[0]&0x80) ? SCSI_DATA_READ :
+                       SCSI_DATA_WRITE;
+
+       if (direction == SCSI_DATA_WRITE) {
+
+               /* Debug-print the first 48 bytes of the write transfer */
+
+               if (!use_sg) {
+                       string[0] = 0;
+                       for (i=0; i<len && i<48; i++) {
+                               sprintf(string+strlen(string), "%02X ",
+                                 data[i]);
+                               if ((i%16)==15) {
+                                       US_DEBUGP("%s\n", string);
+                                       string[0] = 0;
+                               }
+                       }
+                       if (string[0]!=0)
+                               US_DEBUGP("%s\n", string);
+               }
+       }
+
+
+       US_DEBUGP("SCM data %s transfer %d sg buffers %d\n",
+                 ( direction==SCSI_DATA_READ ? "in" : "out"),
+                 len, use_sg);
+
+       if (!use_sg)
+               result = usbat_raw_bulk(us, direction, data, len);
+       else {
+               sg = (struct scatterlist *)data;
+               for (i=0; i<use_sg && transferred<len; i++) {
+                       result = usbat_raw_bulk(us, direction,
+                               sg[i].address, 
+                               len-transferred > sg[i].length ?
+                                       sg[i].length : len-transferred);
+                       if (result!=US_BULK_TRANSFER_GOOD)
+                               break;
+                       transferred += sg[i].length;
+               }
+       }
+
+       return result;
+}
+
+int usbat_read(struct us_data *us,
+            unsigned char access,
+            unsigned char reg, 
+            unsigned char *content) {
+
+       int result;
+       unsigned char command[8] = {
+               0xC0, access, reg, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+
+       result = usbat_send_control(us,
+               usb_rcvctrlpipe(us->pusb_dev,0),
+               access,
+               0xC0,
+               (u16)reg,
+               0,
+               content,
+               1);
+               
+       // result =  usbat_send_control(us, command, content, 1);
+
+       return result;
+}
+
+int usbat_write(struct us_data *us,
+            unsigned char access,
+            unsigned char reg, 
+            unsigned char content) {
+
+       int result;
+       unsigned char command[8] = {
+               0x40, access|0x01, reg, content, 0x00, 0x00, 0x00, 0x00
+       };
+
+       result = usbat_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               access|0x01,
+               0x40,
+               short_pack(reg, content),
+               0,
+               NULL,
+               0);
+               
+       // result =  usbat_send_control(us, command, NULL, 0);
+
+       return result;
+}
+
+int usbat_set_shuttle_features(struct us_data *us,
+            unsigned char external_trigger,
+            unsigned char epp_control, 
+            unsigned char mask_byte, 
+            unsigned char test_pattern, 
+            unsigned char subcountH, 
+            unsigned char subcountL) {
+
+       int result;
+       unsigned char command[8] = {
+               0x40, 0x81, epp_control, external_trigger,
+               test_pattern, mask_byte, subcountL, subcountH
+       };
+
+       result = usbat_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0x80,
+               0x40,
+               0,
+               0,
+               command,
+               8);
+               
+       // result =  usbat_bulk_transport(us, command, 8, 0, NULL, 0, 0);
+
+       return result;
+}
+
+int usbat_read_block(struct us_data *us,
+            unsigned char access,
+            unsigned char reg, 
+            unsigned char *content,
+            unsigned short len,
+            int use_sg) {
+
+       int result;
+       unsigned char command[8] = {
+               0xC0, access|0x02, reg, 0x00, 0x00, 0x00, 
+               LSB_of(len), MSB_of(len)
+       };
+
+       result = usbat_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0x80,
+               0x40,
+               0,
+               0,
+               command,
+               8);
+
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       result = usbat_bulk_transport(us,
+               NULL, 0, SCSI_DATA_READ, content, len, use_sg);
+               
+       // result =  usbat_bulk_transport(us,
+       //      command, 8, 0, content, len, use_sg);
+
+       return result;
+}
+
+/*
+ * Block, waiting for an ATA device to become not busy or to report
+ * an error condition.
+ */
+
+int usbat_wait_not_busy(struct us_data *us) {
+
+       int i;
+       int result;
+       unsigned char status;
+
+       /* Synchronizing cache on a CDR could take a heck of a long time,
+          but probably not more than 15 minutes or so */
+
+       for (i=0; i<500; i++) {
+               result = usbat_read(us, USBAT_ATA, 0x17, &status);
+               US_DEBUGP("SCM: Write ATA data status is %02X\n", status);
+               if (result!=USB_STOR_TRANSPORT_GOOD)
+                       return result;
+               if (status&0x01) // check condition
+                       return USB_STOR_TRANSPORT_FAILED;
+               if (status&0x20) // device fault
+                       return USB_STOR_TRANSPORT_FAILED;
+               if ((status&0x80)!=0x80) // not busy
+                       break;
+               if (i<5)
+                       wait_ms(100);
+               else if (i<20)
+                       wait_ms(500);
+               else if (i<49)
+                       wait_ms(1000);
+               else if (i<499)
+                       wait_ms(2000);
+       }
+
+       if (i==500)
+               return USB_STOR_TRANSPORT_FAILED;
+
+       return USB_STOR_TRANSPORT_GOOD;
+}
+
+int usbat_write_block(struct us_data *us,
+            unsigned char access,
+            unsigned char reg, 
+            unsigned char *content,
+            unsigned short len,
+            int use_sg) {
+
+       int result;
+       unsigned char command[8] = {
+               0x40, access|0x03, reg, 0x00, 0x00, 0x00, 
+               LSB_of(len), MSB_of(len)
+       };
+
+       result = usbat_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0x80,
+               0x40,
+               0,
+               0,
+               command,
+               8);
+
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       result = usbat_bulk_transport(us,
+               NULL, 0, SCSI_DATA_WRITE, content, len, use_sg);
+
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       // result =  usbat_bulk_transport(us,
+       //      command, 8, 0, content, len, use_sg);
+
+       return usbat_wait_not_busy(us);
+}
+
+int usbat_write_block_test(struct us_data *us,
+            unsigned char access,
+            unsigned char *registers,
+            unsigned char *data_out,
+            unsigned short num_registers,
+            unsigned char data_reg, 
+            unsigned char status_reg, 
+            unsigned char qualifier, 
+            unsigned char timeout, 
+            unsigned char *content,
+            unsigned short len,
+            int use_sg) {
+
+       int result;
+
+       // Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here,
+       // but that's what came out of the trace.
+
+       unsigned char command[16] = {
+               0x40, access|0x07, 0x07, 0x17, 0xfc, 0xe7,
+               LSB_of(num_registers*2), MSB_of(num_registers*2),
+               0x40, access|0x05, data_reg, status_reg,
+               qualifier, timeout, LSB_of(len), MSB_of(len)
+       };
+       int i;
+       unsigned char data[num_registers*2];
+       int transferred;
+       struct scatterlist *sg;
+       char string[64];
+
+       for (i=0; i<num_registers; i++) {
+               data[i<<1] = registers[i];
+               data[1+(i<<1)] = data_out[i];
+       }
+
+       result = usbat_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0x80,
+               0x40,
+               0,
+               0,
+               command,
+               16);
+
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       result = usbat_bulk_transport(us,
+               NULL, 0, SCSI_DATA_WRITE, data, num_registers*2, 0);
+
+       // result =  usbat_bulk_transport(us,
+       //      command, 16, 0, data, num_registers*2, 0);
+
+       if (result!=USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       // transferred = 0;
+
+       US_DEBUGP("Transfer out %d bytes, sg buffers %d\n",
+               len, use_sg);
+
+       result = usbat_bulk_transport(us,
+               NULL, 0, SCSI_DATA_WRITE, content, len, use_sg);
+
+/*
+       if (!use_sg) {
+
+               // Debug-print the first 48 bytes of the transfer
+
+               string[0] = 0;
+               for (i=0; i<len && i<48; i++) {
+                       sprintf(string+strlen(string), "%02X ",
+                               content[i]);
+                       if ((i%16)==15) {
+                               US_DEBUGP("%s\n", string);
+                               string[0] = 0;
+                       }
+               }
+               if (string[0]!=0)
+                       US_DEBUGP("%s\n", string);
+
+               result = usbat_raw_bulk(us, SCSI_DATA_WRITE, content, len);
+
+       } else {
+
+               sg = (struct scatterlist *)content;
+               for (i=0; i<use_sg && transferred<len; i++) {
+                       result = usbat_raw_bulk(us, SCSI_DATA_WRITE,
+                               sg[i].address, 
+                               len-transferred > sg[i].length ?
+                                       sg[i].length : len-transferred);
+                       if (result!=US_BULK_TRANSFER_GOOD)
+                               break;
+                       transferred += sg[i].length;
+               }
+       }
+*/
+       if (result!=USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       return usbat_wait_not_busy(us);
+}
+
+int usbat_multiple_write(struct us_data *us, 
+                       unsigned char access,
+                       unsigned char *registers,
+                       unsigned char *data_out,
+                       unsigned short num_registers) {
+
+       int result;
+       unsigned char data[num_registers*2];
+       int i;
+       unsigned char command[8] = {
+               0x40, access|0x07, 0x00, 0x00, 0x00, 0x00,
+               LSB_of(num_registers*2), MSB_of(num_registers*2)
+       };
+
+       for (i=0; i<num_registers; i++) {
+               data[i<<1] = registers[i];
+               data[1+(i<<1)] = data_out[i];
+       }
+
+       result = usbat_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0x80,
+               0x40,
+               0,
+               0,
+               command,
+               8);
+
+       if (result != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       result = usbat_bulk_transport(us,
+               NULL, 0, SCSI_DATA_WRITE, data, num_registers*2, 0);
+
+       // result = usbat_bulk_transport(us, cmd, 8, 0, 
+       //      data, num_registers*2, 0);
+
+       if (result!=USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       return usbat_wait_not_busy(us);
+}
+
+int usbat_read_user_io(struct us_data *us,
+               unsigned char *data_flags) {
+
+       unsigned char command[8] = {
+               0xC0, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       };
+       int result;
+
+       result = usbat_send_control(us,
+               usb_rcvctrlpipe(us->pusb_dev,0),
+               0x82,
+               0xC0,
+               0,
+               0,
+               data_flags,
+               1);
+               
+       // result = usbat_send_control(us, command, data_flags, 1);
+
+       return result;
+}
+
+int usbat_write_user_io(struct us_data *us,
+               unsigned char enable_flags,
+               unsigned char data_flags) {
+
+       unsigned char command[8] = {
+               0x40, 0x82, enable_flags, data_flags, 0x00, 0x00, 0x00, 0x00
+       };
+       int result;
+
+       result = usbat_send_control(us,
+               usb_sndctrlpipe(us->pusb_dev,0),
+               0x82,
+               0x40,
+               short_pack(enable_flags, data_flags),
+               0,
+               NULL,
+               0);
+               
+       // result = usbat_send_control(us, command, NULL, 0);
+
+       return result;
+}
+
+static int hp_8200e_select_and_test_registers(struct us_data *us) {
+
+       int result;
+       int selector;
+       unsigned char status;
+
+       // try device = master, then device = slave.
+
+       for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {
+
+               if ( (result = usbat_write(us, USBAT_ATA, 0x16, selector)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               if ( (result = usbat_read(us, USBAT_ATA, 0x17, &status)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               if ( (result = usbat_read(us, USBAT_ATA, 0x16, &status)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               if ( (result = usbat_read(us, USBAT_ATA, 0x14, &status)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               if ( (result = usbat_read(us, USBAT_ATA, 0x15, &status)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               if ( (result = usbat_write(us, USBAT_ATA, 0x14, 0x55)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               if ( (result = usbat_write(us, USBAT_ATA, 0x15, 0xAA)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               if ( (result = usbat_read(us, USBAT_ATA, 0x14, &status)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+
+               if ( (result = usbat_read(us, USBAT_ATA, 0x15, &status)) != 
+                               USB_STOR_TRANSPORT_GOOD)
+                       return result;
+       }
+
+       return result;
+}
+
+static int init_8200e(struct us_data *us) {
+
+       int result;
+       unsigned char status;
+
+       // Enable peripheral control signals
+
+       if ( (result = usbat_write_user_io(us,
+         USBAT_UIO_OE1 | USBAT_UIO_OE0,
+         USBAT_UIO_EPAD | USBAT_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 1\n");
+
+       wait_ms(2000);
+
+       if ( (result = usbat_read_user_io(us, &status)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 2\n");
+
+       if ( (result = usbat_read_user_io(us, &status)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 3\n");
+
+       // Reset peripheral, enable periph control signals
+       // (bring reset signal up)
+
+       if ( (result = usbat_write_user_io(us,
+         USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0,
+         USBAT_UIO_EPAD | USBAT_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 4\n");
+
+       // Enable periph control signals
+       // (bring reset signal down)
+
+       if ( (result = usbat_write_user_io(us,
+         USBAT_UIO_OE1 | USBAT_UIO_OE0,
+         USBAT_UIO_EPAD | USBAT_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 5\n");
+
+       wait_ms(250);
+
+       // Write 0x80 to ISA port 0x3F
+
+       if ( (result = usbat_write(us, USBAT_ISA, 0x3F, 0x80)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 6\n");
+
+       // Read ISA port 0x27
+
+       if ( (result = usbat_read(us, USBAT_ISA, 0x27, &status)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 7\n");
+
+       if ( (result = usbat_read_user_io(us, &status)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 8\n");
+
+       if ( (result = hp_8200e_select_and_test_registers(us)) !=
+                        USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 9\n");
+
+       if ( (result = usbat_read_user_io(us, &status)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 10\n");
+
+       // Enable periph control signals and card detect
+
+       if ( (result = usbat_write_user_io(us,
+         USBAT_UIO_ACKD |USBAT_UIO_OE1 | USBAT_UIO_OE0,
+         USBAT_UIO_EPAD | USBAT_UIO_1)) != USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 11\n");
+
+       if ( (result = usbat_read_user_io(us, &status)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 12\n");
+
+       wait_ms(1400);
+
+       if ( (result = usbat_read_user_io(us, &status)) !=
+                       USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 13\n");
+
+       if ( (result = hp_8200e_select_and_test_registers(us)) !=
+                        USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 14\n");
+
+       if ( (result = usbat_set_shuttle_features(us, 
+                       0x83, 0x00, 0x88, 0x08, 0x15, 0x14)) !=
+                        USB_STOR_TRANSPORT_GOOD)
+               return result;
+
+       US_DEBUGP("INIT 15\n");
+
+       return result;
+}
+
+/*
+ * Transport for the HP 8200e
+ */
+int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
+{
+       int result;
+       unsigned char status;
+       unsigned char registers[32];
+       unsigned char data[32];
+       unsigned int len;
+       int i;
+       char string[64];
+
+       /* This table tells us:
+          X = command not supported
+          L = return length in cmnd[4] (8 bits).
+          H = return length in cmnd[7] and cmnd[8] (16 bits).
+          D = return length in cmnd[6] to cmnd[9] (32 bits).
+          B = return length/blocksize in cmnd[6] to cmnd[8].
+          T = return length in cmnd[6] to cmnd[8] (24 bits).
+          0-9 = fixed return length
+          W = 24 bytes
+          h = return length/2048 in cmnd[7-8].
+       */
+
+       static char *lengths =
+
+       /* 0123456789ABCDEF   0123456789ABCDEF */
+
+         "0XXL0XXXXXXXXXXX" "XXLXXXXXXXX0XX0X"  /* 00-1F */
+         "XXXXX8XXhXH0XXX0" "XXXXX0XXXXXXXXXX"  /* 20-3F */
+         "XXHHL0X0XXH0XX0X" "XHH00HXX0TH0H0XX"  /* 40-5F */
+         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* 60-7F */
+         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* 80-9F */
+         "X0XXX0XXDXDXXXXX" "XXXXXXXXX000XHBX"  /* A0-BF */
+         "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX"  /* C0-DF */
+         "XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */
+
+       if (us->flags & US_FL_NEED_INIT) {
+               US_DEBUGP("8200e: initializing\n");
+               init_8200e(us);
+               us->flags &= ~US_FL_NEED_INIT;
+       }
+
+       len = srb->request_bufflen;
+
+/*     if (srb->sc_data_direction == SCSI_DATA_WRITE)
+               len = srb->request_bufflen;
+       else {
+
+               switch (lengths[srb->cmnd[0]]) {
+
+               case 'L':
+                       len = srb->cmnd[4];
+                       break;
+               case '0':
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+                       len = lengths[srb->cmnd[0]]-'0';
+                       break;
+               case 'H':
+                       len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
+                       break;
+               case 'h':
+                       len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
+                       len <<= 11; // *2048
+                       break;
+               case 'T':
+                       len = (((unsigned int)srb->cmnd[6])<<16) |
+                             (((unsigned int)srb->cmnd[7])<<8) |
+                             srb->cmnd[8];
+                       break;
+               case 'D':
+                       len = (((unsigned int)srb->cmnd[6])<<24) |
+                             (((unsigned int)srb->cmnd[7])<<16) |
+                             (((unsigned int)srb->cmnd[8])<<8) |
+                             srb->cmnd[9];
+                       break;
+               case 'W':
+                       len = 24;
+                       break;
+               case 'B':
+                       // Let's try using the command structure's
+                       //   request_bufflen here 
+                       len = srb->request_bufflen;
+                       break;
+               default:
+                       US_DEBUGP("Error: UNSUPPORTED COMMAND %02X\n",
+                               srb->cmnd[0]);
+                       return USB_STOR_TRANSPORT_ERROR;
+               }
+       } */
+
+       if (len > 0xFFFF) {
+               US_DEBUGP("Error: len = %08X... what do I do now?\n",
+                       len);
+               return USB_STOR_TRANSPORT_ERROR;
+       }
+
+       // US_DEBUGP("XXXXXXXXXXXXXXXX req_bufflen %d, len %d, bufflen %d\n", 
+       //      srb->request_bufflen, len, srb->bufflen);
+
+       /* Send A0 (ATA PACKET COMMAND).
+          Note: I guess we're never going to get any of the ATA
+          commands... just ATA Packet Commands.
+        */
+
+       registers[0] = 0x11;
+       registers[1] = 0x12;
+       registers[2] = 0x13;
+       registers[3] = 0x14;
+       registers[4] = 0x15;
+       registers[5] = 0x16;
+       registers[6] = 0x17;
+       data[0] = 0x00;
+       data[1] = 0x00;
+       data[2] = 0x00;
+       data[3] = len&0xFF;             // (cylL) = expected length (L)
+       data[4] = (len>>8)&0xFF;        // (cylH) = expected length (H)
+       data[5] = 0xB0;                 // (device sel) = slave
+       data[6] = 0xA0;                 // (command) = ATA PACKET COMMAND
+
+       if (srb->sc_data_direction == SCSI_DATA_WRITE) {
+
+               for (i=7; i<19; i++) {
+                       registers[i] = 0x10;
+                       data[i] = (i-7 >= srb->cmd_len) ? 0 : srb->cmnd[i-7];
+               }
+
+               result = usbat_write_block_test(us, USBAT_ATA, 
+                       registers, data, 19,
+                       0x10, 0x17, 0xFD, 0x30,
+                       srb->request_buffer, 
+                       len, srb->use_sg);
+
+               return result;
+       }
+
+       if ( (result = usbat_multiple_write(us, 
+                       USBAT_ATA,
+                       registers, data, 7)) != USB_STOR_TRANSPORT_GOOD) {
+               return result;
+       }
+
+       // Write the 12-byte command header.
+
+       if ( (result = usbat_write_block(us, 
+                       USBAT_ATA, 0x10, srb->cmnd, 12, 0)) !=
+                               USB_STOR_TRANSPORT_GOOD) {
+               return result;
+       }
+
+       // If there is response data to be read in 
+       // then do it here.
+
+       if (len != 0 && (srb->sc_data_direction == SCSI_DATA_READ)) {
+
+               // How many bytes to read in? Check cylL register
+
+               if ( (result = usbat_read(us, USBAT_ATA, 0x14, &status)) != 
+                   USB_STOR_TRANSPORT_GOOD) {
+                       return result;
+               }
+
+               if (len>0xFF) { // need to read cylH also
+                       len = status;
+                       if ( (result = usbat_read(us, USBAT_ATA, 0x15,
+                               &status)) !=
+                                   USB_STOR_TRANSPORT_GOOD) {
+                               return result;
+                       }
+                       len += ((unsigned int)status)<<8;
+               }
+               else
+                       len = status;
+                       
+
+               result = usbat_read_block(us, USBAT_ATA, 0x10, 
+                       srb->request_buffer, len, srb->use_sg);
+
+               /* Debug-print the first 32 bytes of the transfer */
+
+               if (!srb->use_sg) {
+                       string[0] = 0;
+                       for (i=0; i<len && i<32; i++) {
+                               sprintf(string+strlen(string), "%02X ",
+                                 ((unsigned char *)srb->request_buffer)[i]);
+                               if ((i%16)==15) {
+                                       US_DEBUGP("%s\n", string);
+                                       string[0] = 0;
+                               }
+                       }
+                       if (string[0]!=0)
+                               US_DEBUGP("%s\n", string);
+               }
+       }
+
+       // US_DEBUGP("Command result %d\n", result);
+
+       return result;
+}
+
+
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h
new file mode 100644 (file)
index 0000000..eede265
--- /dev/null
@@ -0,0 +1,76 @@
+/* Driver for SCM Microsystems USB-ATAPI cable
+ * Header File
+ *
+ * Current development and maintainance by:
+ *   (c) 2000 Robert Baruch (autophile@dol.net)
+ *
+ * See scm.c for more explanation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _USB_SHUTTLE_USBAT_H
+#define _USB_SHUTTLE_USBAT_H
+
+#define USBAT_EPP_PORT         0x10
+#define USBAT_EPP_REGISTER     0x30
+#define USBAT_ATA              0x40
+#define USBAT_ISA              0x50
+
+/* SCM User I/O Data registers */
+
+#define USBAT_UIO_EPAD         0x80 // Enable Peripheral Control Signals
+#define USBAT_UIO_CDT          0x40 // Card Detect (Read Only)
+                                    // CDT = ACKD & !UI1 & !UI0
+#define USBAT_UIO_1            0x20 // I/O 1
+#define USBAT_UIO_0            0x10 // I/O 0
+#define USBAT_UIO_EPP_ATA      0x08 // 1=EPP mode, 0=ATA mode
+#define USBAT_UIO_UI1          0x04 // Input 1
+#define USBAT_UIO_UI0          0x02 // Input 0
+#define USBAT_UIO_INTR_ACK     0x01 // Interrupt (ATA & ISA)/Acknowledge (EPP)
+
+/* SCM User I/O Enable registers */
+
+#define USBAT_UIO_DRVRST       0x80 // Reset Peripheral
+#define USBAT_UIO_ACKD         0x40 // Enable Card Detect
+#define USBAT_UIO_OE1          0x20 // I/O 1 set=output/clr=input
+                                    // If ACKD=1, set OE1 to 1 also.
+#define USBAT_UIO_OE0          0x10 // I/O 0 set=output/clr=input
+#define USBAT_UIO_ADPRST       0x01 // Reset SCM chip
+
+/* USBAT-specific commands */
+
+extern int usbat_read(struct us_data *us, unsigned char access,
+       unsigned char reg, unsigned char *content);
+extern int usbat_write(struct us_data *us, unsigned char access,
+       unsigned char reg, unsigned char content);
+extern int usbat_read_block(struct us_data *us, unsigned char access,
+       unsigned char reg, unsigned char *content, unsigned short len,
+       int use_sg);
+extern int usbat_write_block(struct us_data *us, unsigned char access,
+       unsigned char reg, unsigned char *content, unsigned short len,
+       int use_sg);
+extern int usbat_multiple_write(struct us_data *us, unsigned char access,
+       unsigned char *registers, unsigned char *data_out,
+       unsigned short num_registers);
+extern int usbat_read_user_io(struct us_data *us, unsigned char *data_flags);
+extern int usbat_write_user_io(struct us_data *us,
+       unsigned char enable_flags, unsigned char data_flags);
+
+/* HP 8200e stuff */
+
+extern int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us);
+
+#endif
index 88c8476419894836566089283e47b595cf9594b3..69dfcfde88f8ceabe2e37a0f9eba106f816618ac 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  *
- * $Id: transport.c,v 1.3 2000/07/20 01:06:40 mdharm Exp $
+ * $Id: transport.c,v 1.4 2000/07/25 23:04:47 mdharm Exp $
  *
  * Current development and maintainance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -203,7 +203,7 @@ static int us_transfer_partial(struct us_data *us, char *buf, int length)
        int pipe;
 
        /* calculate the appropriate pipe information */
-       if (US_DIRECTION(us->srb->cmnd[0]))
+       if (us->srb->sc_data_direction == SCSI_DATA_READ)
                pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
        else
                pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
@@ -258,7 +258,7 @@ static int us_transfer_partial(struct us_data *us, char *buf, int length)
  * function simply determines if we're going to use scatter-gather or not,
  * and acts appropriately.  For now, it also re-interprets the error codes.
  */
-static void us_transfer(Scsi_Cmnd *srb, struct us_data* us, int dir_in)
+static void us_transfer(Scsi_Cmnd *srb, struct us_data* us)
 {
        int i;
        int result = -1;
@@ -414,8 +414,9 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
        if (need_auto_sense) {
                int temp_result;
                void* old_request_buffer;
-               int old_sg;
-               int old_request_bufflen;
+               unsigned short old_sg;
+               unsigned old_request_bufflen;
+               unsigned char old_sc_data_direction;
                unsigned char old_cmnd[MAX_COMMAND_SIZE];
 
                US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
@@ -431,13 +432,21 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
                srb->cmnd[4] = 18;
                srb->cmnd[5] = 0;
 
-               /* set the buffer length for transfer */
+               /* set the transfer direction */
+               old_sc_data_direction = srb->sc_data_direction;
+               srb->sc_data_direction = SCSI_DATA_READ;
+
+               /* use the new buffer we have */
                old_request_buffer = srb->request_buffer;
+               srb->request_buffer = srb->sense_buffer;
+
+               /* set the buffer length for transfer */
                old_request_bufflen = srb->request_bufflen;
+               srb->request_bufflen = 18;
+
+               /* set up for no scatter-gather use */
                old_sg = srb->use_sg;
                srb->use_sg = 0;
-               srb->request_bufflen = 18;
-               srb->request_buffer = srb->sense_buffer;
 
                /* issue the auto-sense command */
                temp_result = us->transport(us->srb, us);
@@ -462,6 +471,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
                srb->request_buffer = old_request_buffer;
                srb->request_bufflen = old_request_bufflen;
                srb->use_sg = old_sg;
+               srb->sc_data_direction = old_sc_data_direction;
                memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
 
                /* If things are really okay, then let's show that */
@@ -555,7 +565,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
        /* DATA STAGE */
        /* transfer the data payload for this command, if one exists*/
        if (us_transfer_length(srb, us)) {
-               us_transfer(srb, us, US_DIRECTION(srb->cmnd[0]));
+               us_transfer(srb, us);
                US_DEBUGP("CBI data stage result is 0x%x\n", srb->result);
 
                /* if it was aborted, we need to indicate that */
@@ -656,7 +666,7 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
        /* DATA STAGE */
        /* transfer the data payload for this command, if one exists*/
        if (us_transfer_length(srb, us)) {
-               us_transfer(srb, us, US_DIRECTION(srb->cmnd[0]));
+               us_transfer(srb, us);
                US_DEBUGP("CB data stage result is 0x%x\n", srb->result);
 
                /* if it was aborted, we need to indicate that */
@@ -718,7 +728,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
        /* set up the command wrapper */
        bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
        bcb.DataTransferLength = cpu_to_le32(us_transfer_length(srb, us));
-       bcb.Flags = US_DIRECTION(srb->cmnd[0]) << 7;
+       bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
        bcb.Tag = srb->serial_number;
        bcb.Lun = srb->cmnd[1] >> 5;
        bcb.Length = srb->cmd_len;
@@ -755,7 +765,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
        if (result == 0) {
                /* send/receive data payload, if there is any */
                if (bcb.DataTransferLength) {
-                       us_transfer(srb, us, bcb.Flags);
+                       us_transfer(srb, us);
                        US_DEBUGP("Bulk data transfer result 0x%x\n", 
                                  srb->result);
 
index 55e12f79f41faba0129ed92d36f775e5fa6a6d48..9d0993c1eaed9d9596113dedfab328aa30db4a80 100644 (file)
@@ -1,7 +1,7 @@
 /* Driver for USB Mass Storage compliant devices
  * Transport Functions Header File
  *
- * $Id: transport.h,v 1.4 2000/07/23 18:40:38 groovyjava Exp $
+ * $Id: transport.h,v 1.6 2000/07/27 14:42:43 groovyjava Exp $
  *
  * Current development and maintainance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
 #include "usb.h"
 #include "scsi.h"
 
-/* bit set if input */
-extern unsigned char us_direction[256/8];
-#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
-
 /* Protocols */
 
 #define US_PR_CBI      0x00            /* Control/Bulk/Interrupt */
@@ -59,7 +55,8 @@ extern unsigned char us_direction[256/8];
 #define US_PR_SCM_ATAPI        0x80            /* SCM-ATAPI bridge */
 #endif
 #ifdef CONFIG_USB_STORAGE_SDDR09
-#define US_PR_SCM_SCSI 0x81            /* SCM-SCSI bridge */
+#define US_PR_EUSB_SDDR09      0x81    /* SCM-SCSI bridge for
+                                               SDDR-09 */
 #endif
 
 /*
index 99986371fbbeb26945e574ac2ef941af94d3d31a..c82d7e914d32f0738533255d374cfb36a2dc00da 100644 (file)
@@ -1,6 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  *
- * $Id: usb.c,v 1.11 2000/07/24 20:37:24 mdharm Exp $
+ * $Id: usb.c,v 1.14 2000/07/27 14:42:43 groovyjava Exp $
  *
  * Current development and maintainance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
 #include "transport.h"
 #include "protocol.h"
 #include "debug.h"
-#if defined(CONFIG_USB_STORAGE_HP8200e) || defined(CONFIG_USB_STORAGE_SDDR09)
-#include "scm.h"
+#ifdef CONFIG_USB_STORAGE_HP8200e
+#include "shuttle_usbat.h"
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR09
+#include "sddr09.h"
 #endif
 
 #include <linux/module.h>
@@ -117,9 +120,9 @@ static int usb_stor_control_thread(void * __us)
 
        /* signal that we've started the thread */
        up(&(us->notify));
+       set_current_state(TASK_INTERRUPTIBLE);
 
        for(;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
                US_DEBUGP("*** thread sleeping.\n");
                schedule();
                US_DEBUGP("*** thread awakened.\n");
@@ -137,15 +140,27 @@ static int usb_stor_control_thread(void * __us)
 
                switch (action) {
                case US_ACT_COMMAND:
+                       /* reject the command if the direction indicator 
+                        * is UNKNOWN
+                        */
+                       if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) {
+                               US_DEBUGP("UNKNOWN data direction\n");
+                               us->srb->result = DID_ERROR;
+                               set_current_state(TASK_INTERRUPTIBLE);
+                               us->srb->scsi_done(us->srb);
+                               us->srb = NULL;
+                               break;
+                       }
+                       
                        /* reject if target != 0 or if LUN is higher than
                         * the maximum known LUN
                         */
                        if (us->srb->target || (us->srb->lun > us->max_lun)) {
                                US_DEBUGP("Bad device number (%d/%d)\n",
                                          us->srb->target, us->srb->lun);
-
                                us->srb->result = DID_BAD_TARGET << 16;
 
+                               set_current_state(TASK_INTERRUPTIBLE);
                                us->srb->scsi_done(us->srb);
                                us->srb = NULL;
                                break;
@@ -155,6 +170,8 @@ static int usb_stor_control_thread(void * __us)
                        if ((us->srb->cmnd[0] == START_STOP) &&
                            (us->flags & US_FL_START_STOP)) {
                                us->srb->result = GOOD;
+
+                               set_current_state(TASK_INTERRUPTIBLE);
                                us->srb->scsi_done(us->srb);
                                us->srb = NULL;
                                break;
@@ -194,9 +211,11 @@ static int usb_stor_control_thread(void * __us)
                        if (us->srb->result != DID_ABORT << 16) {
                                US_DEBUGP("scsi cmd done, result=0x%x\n", 
                                           us->srb->result);
+                               set_current_state(TASK_INTERRUPTIBLE);
                                us->srb->scsi_done(us->srb);
                        } else {
                                US_DEBUGP("scsi command aborted\n");
+                               set_current_state(TASK_INTERRUPTIBLE);
                                up(&(us->notify));
                        }
                        us->srb = NULL;
@@ -253,12 +272,12 @@ static struct us_unusual_dev us_unusual_dev_list[] = {
                US_SC_UFI,  US_PR_CBI, US_FL_SINGLE_LUN},
        { 0x0693, 0x0002, 0x0100, 0x0100, "Hagiwara FlashGate SmartMedia",
                US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
-       { 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk ImageMate (SDDR-01)",
+       { 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk ImageMate (SDDR-05a)",
                US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN | US_FL_START_STOP},
 #ifdef CONFIG_USB_STORAGE_SDDR09
        { 0x0781, 0x0200, 0x0100, 0x0100, "Sandisk ImageMate (SDDR-09)",
-               US_SC_SCSI, US_PR_SCM_SCSI,
-               US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_NEED_INIT},
+               US_SC_SCSI, US_PR_EUSB_SDDR09,
+               US_FL_SINGLE_LUN | US_FL_START_STOP},
 #endif
        { 0x0781, 0x0002, 0x0009, 0x0009, "Sandisk Imagemate (SDDR-31)",
                US_SC_SCSI, US_PR_BULK, US_FL_IGNORE_SER},
@@ -447,7 +466,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
 
        /* set the interface -- STALL is an acceptable response here */
 #ifdef CONFIG_USB_STORAGE_SDDR09
-       if (protocol != US_PR_SCM_SCSI)
+       if (protocol != US_PR_EUSB_SDDR09)
                result = usb_set_interface(dev, 
                        altsetting->bInterfaceNumber, 0);
        else
@@ -631,8 +650,8 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
 #endif
 
 #ifdef CONFIG_USB_STORAGE_SDDR09
-               case US_PR_SCM_SCSI:
-                       ss->transport_name = "SCM/SCSI";
+               case US_PR_EUSB_SDDR09:
+                       ss->transport_name = "EUSB/SDDR09";
                        ss->transport = sddr09_transport;
                        ss->transport_reset = usb_stor_CB_reset;
                        ss->max_lun = 1;
@@ -855,3 +874,6 @@ void __exit usb_stor_exit(void)
 
 module_init(usb_stor_init) ;
 module_exit(usb_stor_exit) ;
+
+MODULE_AUTHOR("Michael Gee <michael@linuxspecific.com>, David L. Brown, Jr. <usb-storage@davidb.org>, Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
+MODULE_DESCRIPTION("USB Mass Storage driver");
index 31be1c0e25f45c23c8017f827fad2f2af3737a6e..8423b448ab3386e3d4f239d847b93607002cfd3c 100644 (file)
@@ -49,6 +49,7 @@ static int handle_pm_event(struct pm_dev *dev, pm_request_t rqst, void *data);
 
 static int debug = 1;
 MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug level");
 
 static kmem_cache_t *uhci_td_cachep;
 static kmem_cache_t *uhci_qh_cachep;
@@ -2541,5 +2542,8 @@ void cleanup_module(void)
        pm_unregister_all(handle_pm_event);
        uhci_cleanup();
 }
+
+MODULE_AUTHOR("Linus Torvalds, Johannes Erdfelt, Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber");
+MODULE_DESCRIPTION("USB Universal Host Controller Interface driver");
 #endif //MODULE
 
index 48a5df48eb43f0a5df32a202eccc918855e16b5a..cfa8715030730c9d927a5f5d769539c04793b16f 100644 (file)
@@ -65,6 +65,9 @@
  */
 #include <linux/adb.h>
 #include <linux/pmu.h>
+#ifndef CONFIG_PM
+#define CONFIG_PM
+#endif
 #endif
 
 
@@ -415,9 +418,11 @@ static int sohci_submit_urb (urb_t * urb)
        int i, size = 0;
        unsigned long flags;
        
-       if (!urb->dev || !urb->dev->bus) return -EINVAL;
+       if (!urb->dev || !urb->dev->bus)
+               return -EINVAL;
        
-       if (urb->hcpriv) return -EINVAL; /* urb already in use */
+       if (urb->hcpriv)                        /* urb already in use */
+               return -EINVAL;
 
 //     if(usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe))) 
 //             return -EPIPE;
@@ -435,8 +440,10 @@ static int sohci_submit_urb (urb_t * urb)
        
        /* when controller's hung, permit only roothub cleanup attempts
         * such as powering down ports */
-       if (ohci->disabled)
+       if (ohci->disabled) {
+               usb_dec_dev_use (urb->dev);     
                return -ESHUTDOWN;
+       }
 
        /* every endpoint has a ed, locate and fill it */
        if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1))) {
@@ -1730,7 +1737,9 @@ static int rh_submit_urb (urb_t * urb)
        urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe));
 #endif
 
-       if (urb->complete) urb->complete (urb);
+       if (urb->complete)
+               urb->complete (urb);
+       usb_dec_dev_use (urb->dev);
        return 0;
 }
 
@@ -1880,7 +1889,9 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
                        ohci->ohci_dev->slot_name);
                // e.g. due to PCI Master/Target Abort
 
-#ifndef        DEBUG
+#ifdef DEBUG
+               ohci_dump (ohci, 1);
+#else
                // FIXME: be optimistic, hope that bug won't repeat often.
                // Make some non-interrupt context restart the controller.
                // Count and limit the retries though; either hardware or
@@ -1910,6 +1921,8 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
        }
        writel (ints, &regs->intrstatus);
        writel (OHCI_INTR_MIE, &regs->intrenable);      
+
+       /* FIXME:  check URB timeouts */
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1921,7 +1934,7 @@ static ohci_t * __devinit hc_alloc_ohci (void * mem_base)
        ohci_t * ohci;
        struct usb_bus * bus;
 
-       ohci = (ohci_t *) __get_free_pages (GFP_KERNEL, 1);
+       ohci = (ohci_t *) kmalloc (sizeof *ohci, GFP_KERNEL);
        if (!ohci)
                return NULL;
                
@@ -1932,7 +1945,7 @@ static ohci_t * __devinit hc_alloc_ohci (void * mem_base)
 
        bus = usb_alloc_bus (&sohci_device_operations);
        if (!bus) {
-               free_pages ((unsigned long) ohci, 1);
+               kfree (ohci);
                return NULL;
        }
 
@@ -1974,7 +1987,7 @@ static void hc_release_ohci (ohci_t * ohci)
        /* unmap the IO address space */
        iounmap (ohci->regs);
        
-       free_pages ((unsigned long) ohci, 1);   
+       kfree (ohci);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2085,13 +2098,27 @@ static void hc_restart (ohci_t *ohci)
 static int __devinit
 ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
 {
-       unsigned long mem_resource;
+       unsigned long mem_resource, mem_len;
        u8 latency, limit;
        void *mem_base;
 
        if (pci_enable_device(dev) < 0)
                return -ENODEV;
        
+       /* we read its hardware registers as memory */
+       mem_resource = pci_resource_start(dev, 0);
+       mem_len = pci_resource_len(dev, 0);
+       if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
+               dbg ("controller already in use");
+               return -EBUSY;
+       }
+
+       mem_base = ioremap_nocache (mem_resource, mem_len);
+       if (!mem_base) {
+               err("Error mapping OHCI memory");
+               return -EFAULT;
+       }
+
        /* controller writes into our memory */
        pci_set_master (dev);
        pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
@@ -2103,15 +2130,6 @@ ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
                }
        }
 
-       /* we read its hardware registers as memory */
-       mem_resource = pci_resource_start(dev, 0);
-       /* request_mem_region ... */
-       mem_base = ioremap_nocache (mem_resource, 4096);
-       if (!mem_base) {
-               err("Error mapping OHCI memory");
-               return -EFAULT;
-       }
-
        return hc_found_ohci (dev, dev->irq, mem_base);
 } 
 
@@ -2145,6 +2163,8 @@ ohci_pci_remove (struct pci_dev *dev)
                        &ohci->regs->control);
 
        hc_release_ohci (ohci);
+
+       release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
 }
 
 
@@ -2233,7 +2253,7 @@ ohci_pci_resume (struct pci_dev *dev)
 
 /*-------------------------------------------------------------------------*/
 
-static const struct __devinitdata pci_device_id        ohci_pci_ids [] = { {
+static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
 
        /* handle any USB OHCI controller */
        class:          ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
@@ -2328,4 +2348,5 @@ module_exit (ohci_hcd_cleanup);
 #endif /* MODULE */
 
 
+MODULE_AUTHOR ("Roman Weissgaerber <weissg@vienna.at>");
 MODULE_DESCRIPTION ("USB OHCI Host Controller Driver");
index 626bfc93cd7ee0d283892985489605fcfdc21129..e82fa78a08aaac8f8e623324938b37b955b3bf5e 100644 (file)
@@ -2885,4 +2885,6 @@ void cleanup_module (void)
        uhci_cleanup ();
 }
 
+MODULE_AUTHOR("Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber");
+MODULE_DESCRIPTION("USB Universal Host Controller Interface driver");
 #endif //MODULE
index 42f82604e78d2039d8d84dbc690efb6c76fa1632..89cc765371b10757fd3154f1680e8cabd1b5f2b2 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/usb.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("USB HID Boot Protocol keyboard driver");
 
 static unsigned char usb_kbd_keycode[256] = {
          0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
index 55bd14fdbba8338326211e97bdeca9caf06a9414..39df8e5e05b7ee5c011108009e6ea252d628f166 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/usb.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("USB HID Boot Protocol mouse driver");
 
 struct usb_mouse {
        signed char data[8];
index de2821e4709756664056b8e10f435e0bd66ec3c0..b74a003e8f1f6c7f95bec6a68225bdf92c8d502d 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/usb.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
+MODULE_DESCRIPTION("USB Wacom Graphire and Wacom Intuos tablet driver");
 
 /*
  * Wacom Graphire packet:
index 4b388f60b45d09ed98493636a7c3025594f15083..f206bef562b9927c39d66044ffbf9bb8eb75b401 100644 (file)
@@ -857,7 +857,7 @@ static int rivafb_set_var (struct fb_var_screeninfo *var, int con,
                v.blue.offset = 0;
 #endif
                v.red.length = 5;
-               v.green.length = 5;
+               v.green.length = 6;
                v.blue.length = 5;
                break;
 #endif
@@ -1390,8 +1390,8 @@ static int riva_setcolreg (unsigned regno, unsigned red, unsigned green,
                    ((green & 0xf800) << 2) | ((blue & 0xf800) >> 3);
 #else
                rivainfo->con_cmap.cfb16[regno] =
-                   ((red & 0xf800) >> 1) |
-                   ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
+                   ((red & 0xf800) >> 0) |
+                   ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
 #endif
                break;
 #endif                         /* FBCON_HAS_CFB16 */
index 4fb5b1685abf3ac0499f9435a8371752e73f8cb0..4225311580b92a55dfd99bf8f48a7dc68de970ee 100644 (file)
@@ -512,7 +512,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                        retval = PTR_ERR(interpreter);
                        if (IS_ERR(interpreter))
                                goto out_free_interp;
-                       retval = kernel_read(interpreter, 0, bprm->buf, 128);
+                       retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE);
                        if (retval < 0)
                                goto out_free_dentry;
 
index f9c30df1bc156223e9f03bd4063cb8358996ab94..c1653647946aff0116ada39469b193bb7982916e 100644 (file)
@@ -182,7 +182,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 {
        struct binfmt_entry *fmt;
        struct file * file;
-       char iname[128];
+       char iname[BINPRM_BUF_SIZE];
        char *iname_addr = iname;
        int retval;
 
@@ -194,8 +194,8 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        read_lock(&entries_lock);
        fmt = check_file(bprm);
        if (fmt) {
-               strncpy(iname, fmt->interpreter, 127);
-               iname[127] = '\0';
+               strncpy(iname, fmt->interpreter, BINPRM_BUF_SIZE - 1);
+               iname[BINPRM_BUF_SIZE - 1] = '\0';
        }
        read_unlock(&entries_lock);
        if (!fmt)
@@ -324,7 +324,7 @@ static int proc_write_register(struct file *file, const char *buffer,
 
        /* more sanity checks */
        if (err || !(!cnt || (!(--cnt) && (*sp == '\n'))) ||
-           (e->size < 1) || ((e->size + e->offset) > 127) ||
+           (e->size < 1) || ((e->size + e->offset) > (BINPRM_BUF_SIZE - 1)) ||
            !(e->proc_name) || !(e->interpreter) || entry_proc_setup(e))
                goto free_err;
 
index 3d5023e2d6347784816ca75c223a48ffee6cc9b0..ae7de4c24663acf570cd9870d144deba77fc6d22 100644 (file)
@@ -18,7 +18,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
        char *cp, *i_name, *i_arg;
        struct file *file;
-       char interp[128];
+       char interp[BINPRM_BUF_SIZE];
        int retval;
 
        if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
@@ -33,9 +33,9 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
        fput(bprm->file);
        bprm->file = NULL;
 
-       bprm->buf[127] = '\0';
+       bprm->buf[BINPRM_BUF_SIZE - 1] = '\0';
        if ((cp = strchr(bprm->buf, '\n')) == NULL)
-               cp = bprm->buf+127;
+               cp = bprm->buf+BINPRM_BUF_SIZE-1;
        *cp = '\0';
        while (cp > bprm->buf) {
                cp--;
index dad4fbcfb7760fb0b1c1fed5c90ac0a95cb382e4..341dfe5917fcd915068f73f96ca2099ca037730f 100644 (file)
@@ -1341,13 +1341,27 @@ static void create_empty_buffers(struct page *page, struct inode *inode, unsigne
        page_cache_get(page);
 }
 
+/*
+ * We are taking a block for data and we don't want any output from any
+ * buffer-cache aliases starting from return from that function and
+ * until the moment when something will explicitly mark the buffer
+ * dirty (hopefully that will not happen until we will free that block ;-)
+ * We don't even need to mark it not-uptodate - nobody can expect
+ * anything from a newly allocated buffer anyway. We used to used
+ * unmap_buffer() for such invalidation, but that was wrong. We definitely
+ * don't want to mark the alias unmapped, for example - it would confuse
+ * anyone who might pick it with bread() afterwards...
+ */
+
 static void unmap_underlying_metadata(struct buffer_head * bh)
 {
        struct buffer_head *old_bh;
 
        old_bh = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size);
        if (old_bh) {
-               unmap_buffer(old_bh);
+               mark_buffer_clean(old_bh);
+               wait_on_buffer(old_bh);
+               clear_bit(BH_Req, &old_bh->b_state);
                /* Here we could run brelse or bforget. We use
                   bforget because it will try to put the buffer
                   in the freelist. */
index 729b48855c54b8c2b350e6f0f03a7e5a19ef705d..9be3e8cdc934fdcfeaa9faaa6838d3be8de6b217 100644 (file)
@@ -14,6 +14,7 @@
  * the dcache entry is deleted or garbage collected.
  */
 
+#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
index dd7db77306dec194a3324d8ef4a124cdd97a1cab..85fb7e519fc09003244213abd4393e1b5719fb17 100644 (file)
@@ -88,11 +88,11 @@ static struct file_operations * get_chrfops(unsigned int major, unsigned int min
                char name[20];
                sprintf(name, "char-major-%d", major);
                request_module(name);
-       }
-       read_lock(&chrdevs_lock);
-       ret = fops_get(chrdevs[major].fops);
-       read_unlock(&chrdevs_lock);
 
+               read_lock(&chrdevs_lock);
+               ret = fops_get(chrdevs[major].fops);
+               read_unlock(&chrdevs_lock);
+       }
 #endif
        return ret;
 }
index d28aaec822abf4273e0ca5fa081a4b89b062bd56..f7745f9de2ab116ed3bb390e81bab810932d0f25 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -555,7 +555,7 @@ static inline int must_not_trace_exec(struct task_struct * p)
 
 /* 
  * Fill the binprm structure from the inode. 
- * Check permissions, then read the first 512 bytes
+ * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
  */
 int prepare_binprm(struct linux_binprm *bprm)
 {
@@ -646,8 +646,8 @@ int prepare_binprm(struct linux_binprm *bprm)
                }
        }
 
-       memset(bprm->buf,0,sizeof(bprm->buf));
-       return kernel_read(bprm->file,0,bprm->buf,128);
+       memset(bprm->buf,0,BINPRM_BUF_SIZE);
+       return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
 }
 
 /*
@@ -819,15 +819,15 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
        int retval;
        int i;
 
-       bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
-       memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
-
        file = open_exec(filename);
 
        retval = PTR_ERR(file);
        if (IS_ERR(file))
                return retval;
 
+       bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
+       memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
+
        bprm.file = file;
        bprm.filename = filename;
        bprm.sh_bang = 0;
index a3f8ae4cedeb1d81c8f58bf9b763c27fc1527850..8ca28e0a094e06e712f25177d392a79b9d3fb677 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/locks.h>
 #include <linux/quotaops.h>
 
-
 /*
  * balloc.c contains the blocks allocation and deallocation routines
  */
@@ -379,10 +378,8 @@ int ext2_new_block (const struct inode * inode, unsigned long goal,
            ((sb->u.ext2_sb.s_resuid != current->fsuid) &&
             (sb->u.ext2_sb.s_resgid == 0 ||
              !in_group_p (sb->u.ext2_sb.s_resgid)) && 
-            !capable(CAP_SYS_RESOURCE))) {
-               unlock_super (sb);
-               return 0;
-       }
+            !capable(CAP_SYS_RESOURCE)))
+               goto out;
 
        ext2_debug ("goal=%lu.\n", goal);
 
@@ -475,16 +472,13 @@ repeat:
                gdp = ext2_get_group_desc (sb, i, &bh2);
                if (!gdp) {
                        *err = -EIO;
-                       unlock_super (sb);
-                       return 0;
+                       goto out;
                }
                if (le16_to_cpu(gdp->bg_free_blocks_count) > 0)
                        break;
        }
-       if (k >= sb->u.ext2_sb.s_groups_count) {
-               unlock_super (sb);
-               return 0;
-       }
+       if (k >= sb->u.ext2_sb.s_groups_count)
+               goto out;
        bitmap_nr = load_block_bitmap (sb, i);
        if (bitmap_nr < 0)
                goto io_error;
@@ -500,8 +494,7 @@ repeat:
        if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
                ext2_error (sb, "ext2_new_block",
                            "Free blocks count corrupted for block group %d", i);
-               unlock_super (sb);
-               return 0;
+               goto out;
        }
 
 search_back:
@@ -520,9 +513,8 @@ got_block:
         * Check quota for allocation of this block.
         */
        if(DQUOT_ALLOC_BLOCK(sb, inode, 1)) {
-               unlock_super(sb);
                *err = -EDQUOT;
-               return 0;
+               goto out;
        }
 
        tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + le32_to_cpu(es->s_first_data_block);
@@ -550,31 +542,50 @@ got_block:
 #ifdef EXT2_PREALLOCATE
        if (prealloc_block) {
                int     prealloc_goal;
+               unsigned long next_block = tmp + 1;
 
                prealloc_goal = es->s_prealloc_blocks ?
                        es->s_prealloc_blocks : EXT2_DEFAULT_PREALLOC_BLOCKS;
 
+               /* Writer: ->i_prealloc* */
+               /*
+                * Can't happen right now, will need handling if we go for
+                * per-group spinlocks. Handling == skipping preallocation if
+                * condition below will be true. For now there is no legitimate
+                * way it could happen, thus the BUG().
+                */
+               if (*prealloc_count)
+                       BUG();
                *prealloc_count = 0;
-               *prealloc_block = tmp + 1;
+               *prealloc_block = next_block;
+               /* Writer: end */
                for (k = 1;
                     k < prealloc_goal && (j + k) < EXT2_BLOCKS_PER_GROUP(sb);
-                    k++) {
+                    k++, next_block++) {
                        if (DQUOT_PREALLOC_BLOCK(sb, inode, 1))
                                break;
-                       if (ext2_set_bit (j + k, bh->b_data)) {
+                       /* Writer: ->i_prealloc* */
+                       if (*prealloc_block + *prealloc_count != next_block ||
+                           ext2_set_bit (j + k, bh->b_data)) {
+                               /* Writer: end */
                                DQUOT_FREE_BLOCK(sb, inode, 1);
                                break;
                        }
                        (*prealloc_count)++;
+                       /* Writer: end */
                }       
+               /*
+                * As soon as we go for per-group spinlocks we'll need these
+                * done inside the loop above.
+                */
                gdp->bg_free_blocks_count =
                        cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) -
-                              *prealloc_count);
+                              (k - 1));
                es->s_free_blocks_count =
                        cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) -
-                              *prealloc_count);
+                              (k - 1));
                ext2_debug ("Preallocated a further %lu bits.\n",
-                           *prealloc_count);
+                              (k - 1));
        }
 #endif
 
@@ -591,8 +602,7 @@ got_block:
                            "block(%d) >= blocks count(%d) - "
                            "block_group = %d, es == %p ",j,
                        le32_to_cpu(es->s_blocks_count), i, es);
-               unlock_super (sb);
-               return 0;
+               goto out;
        }
 
        ext2_debug ("allocating block %d. "
@@ -609,6 +619,7 @@ got_block:
        
 io_error:
        *err = -EIO;
+out:
        unlock_super (sb);
        return 0;
        
index 1b9983e24d7777a2828bca341075c6562a5ca769..27b1fcbcbb6d8498a121ead5409e8b15256e4a15 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <linux/fs.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 
 static loff_t ext2_file_lseek(struct file *, loff_t, int);
 static int ext2_open_file (struct inode *, struct file *);
@@ -74,11 +73,8 @@ static loff_t ext2_file_lseek(
  */
 static int ext2_release_file (struct inode * inode, struct file * filp)
 {
-       if (filp->f_mode & FMODE_WRITE) {
-               lock_kernel();
+       if (filp->f_mode & FMODE_WRITE)
                ext2_discard_prealloc (inode);
-               unlock_kernel();
-       }
        return 0;
 }
 
index 4580c87e0a303b85f2e210c40ba38cc1bfef3ea1..c7234e7b5e25090759c1d7d5b5c85debd3ba2fcb 100644 (file)
@@ -35,9 +35,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync);
  */
 void ext2_put_inode (struct inode * inode)
 {
-       lock_kernel();
        ext2_discard_prealloc (inode);
-       unlock_kernel();
 }
 
 /*
@@ -66,19 +64,6 @@ no_delete:
        clear_inode(inode);     /* We must guarantee clearing of inode... */
 }
 
-#define inode_bmap(inode, nr) (le32_to_cpu((inode)->u.ext2_i.i_data[(nr)]))
-
-static inline int block_bmap (struct buffer_head * bh, int nr)
-{
-       int tmp;
-
-       if (!bh)
-               return 0;
-       tmp = le32_to_cpu(((u32 *) bh->b_data)[nr]);
-       brelse (bh);
-       return tmp;
-}
-
 /* 
  * ext2_discard_prealloc and ext2_alloc_block are atomic wrt. the
  * superblock in the same manner as are ext2_free_blocks and
@@ -91,11 +76,13 @@ void ext2_discard_prealloc (struct inode * inode)
 #ifdef EXT2_PREALLOCATE
        unsigned short total;
 
+       lock_kernel();
        if (inode->u.ext2_i.i_prealloc_count) {
                total = inode->u.ext2_i.i_prealloc_count;
                inode->u.ext2_i.i_prealloc_count = 0;
                ext2_free_blocks (inode, inode->u.ext2_i.i_prealloc_block, total);
        }
+       unlock_kernel();
 #endif
 }
 
@@ -135,69 +122,181 @@ static int ext2_alloc_block (struct inode * inode, unsigned long goal, int *err)
        return result;
 }
 
-static inline long ext2_block_map (struct inode * inode, long block)
+typedef struct {
+       u32     *p;
+       u32     key;
+       struct buffer_head *bh;
+} Indirect;
+
+static inline void add_chain(Indirect *p, struct buffer_head *bh, u32 *v)
+{
+       p->key = *(p->p = v);
+       p->bh = bh;
+}
+
+static inline int verify_chain(Indirect *from, Indirect *to)
+{
+       while (from <= to && from->key == *from->p)
+               from++;
+       return (from > to);
+}
+
+/**
+ *     ext2_block_to_path - parse the block number into array of offsets
+ *     @inode: inode in question (we are only interested in its superblock)
+ *     @i_block: block number to be parsed
+ *     @offsets: array to store the offsets in
+ *
+ *     To store the locations of file's data ext2 uses a data structure common
+ *     for UNIX filesystems - tree of pointers anchored in the inode, with
+ *     data blocks at leaves and indirect blocks in intermediate nodes.
+ *     This function translates the block number into path in that tree -
+ *     return value is the path length and @offsets[n] is the offset of
+ *     pointer to (n+1)th node in the nth one. If @block is out of range
+ *     (negative or too large) warning is printed and zero returned.
+ *
+ *     Note: function doesn't find node addresses, so no IO is needed. All
+ *     we need to know is the capacity of indirect blocks (taken from the
+ *     inode->i_sb).
+ */
+
+/*
+ * Portability note: the last comparison (check that we fit into triple
+ * indirect block) is spelled differently, because otherwise on an
+ * architecture with 32-bit longs and 8Kb pages we might get into trouble
+ * if our filesystem had 8Kb blocks. We might use long long, but that would
+ * kill us on x86. Oh, well, at least the sign propagation does not matter -
+ * i_block would have to be negative in the very beginning, so we would not
+ * get there at all.
+ */
+
+static int ext2_block_to_path(struct inode *inode, long i_block, int offsets[4])
 {
-       int i, ret;
        int ptrs = EXT2_ADDR_PER_BLOCK(inode->i_sb);
        int ptrs_bits = EXT2_ADDR_PER_BLOCK_BITS(inode->i_sb);
-
-       ret = 0;
-       lock_kernel();
-       if (block < 0) {
-               ext2_warning (inode->i_sb, "ext2_block_map", "block < 0");
-               goto out;
-       }
-       if (block >= EXT2_NDIR_BLOCKS + ptrs +
-               (1 << (ptrs_bits * 2)) +
-               ((1 << (ptrs_bits * 2)) << ptrs_bits)) {
-               ext2_warning (inode->i_sb, "ext2_block_map", "block > big");
-               goto out;
-       }
-       if (block < EXT2_NDIR_BLOCKS) {
-               ret = inode_bmap (inode, block);
-               goto out;
-       }
-       block -= EXT2_NDIR_BLOCKS;
-       if (block < ptrs) {
-               i = inode_bmap (inode, EXT2_IND_BLOCK);
-               if (!i)
-                       goto out;
-               ret = block_bmap (bread (inode->i_dev, i,
-                                         inode->i_sb->s_blocksize), block);
-               goto out;
+       const long direct_blocks = EXT2_NDIR_BLOCKS,
+               indirect_blocks = ptrs,
+               double_blocks = (1 << (ptrs_bits * 2));
+       int n = 0;
+
+       if (i_block < 0) {
+               ext2_warning (inode->i_sb, "ext2_block_to_path", "block < 0");
+       } else if (i_block < direct_blocks) {
+               offsets[n++] = i_block;
+       } else if ( (i_block -= direct_blocks) < indirect_blocks) {
+               offsets[n++] = EXT2_IND_BLOCK;
+               offsets[n++] = i_block;
+       } else if ((i_block -= indirect_blocks) < double_blocks) {
+               offsets[n++] = EXT2_DIND_BLOCK;
+               offsets[n++] = i_block >> ptrs_bits;
+               offsets[n++] = i_block & (ptrs - 1);
+       } else if (((i_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) {
+               offsets[n++] = EXT2_TIND_BLOCK;
+               offsets[n++] = i_block >> (ptrs_bits * 2);
+               offsets[n++] = (i_block >> ptrs_bits) & (ptrs - 1);
+               offsets[n++] = i_block & (ptrs - 1);
+       } else {
+               ext2_warning (inode->i_sb, "ext2_block_to_path", "block > big");
        }
-       block -= ptrs;
-       if (block < (1 << (ptrs_bits * 2))) {
-               i = inode_bmap (inode, EXT2_DIND_BLOCK);
-               if (!i)
-                       goto out;
-               i = block_bmap (bread (inode->i_dev, i,
-                                      inode->i_sb->s_blocksize),
-                               block >> ptrs_bits);
-               if (!i)
-                       goto out;
-               ret = block_bmap (bread (inode->i_dev, i,
-                                         inode->i_sb->s_blocksize),
-                               block & (ptrs - 1));
-               goto out;
+       return n;
+}
+
+/**
+ *     ext2_get_branch - read the chain of indirect blocks leading to data
+ *     @inode: inode in question
+ *     @depth: depth of the chain (1 - direct pointer, etc.)
+ *     @offsets: offsets of pointers in inode/indirect blocks
+ *     @chain: place to store the result
+ *     @err: here we store the error value
+ *
+ *     Function fills the array of triples <key, p, bh> and returns %NULL
+ *     if everything went OK or the pointer to the last filled triple
+ *     (incomplete one) otherwise. Upon the return chain[i].key contains
+ *     the number of (i+1)-th block in the chain (as it is stored in memory,
+ *     i.e. little-endian 32-bit), chain[i].p contains the address of that
+ *     number (it points into struct inode for i==0 and into the bh->b_data
+ *     for i>0) and chain[i].bh points to the buffer_head of i-th indirect
+ *     block for i>0 and NULL for i==0. In other words, it holds the block
+ *     numbers of the chain, addresses they were taken from (and where we can
+ *     verify that chain did not change) and buffer_heads hosting these
+ *     numbers.
+ *
+ *     Function stops when it stumbles upon zero pointer (absent block)
+ *             (pointer to last triple returned, *@err == 0)
+ *     or when it gets an IO error reading an indirect block
+ *             (ditto, *@err == -EIO)
+ *     or when it notices that chain had been changed while it was reading
+ *             (ditto, *@err == -EAGAIN)
+ *     or when it reads all @depth-1 indirect blocks successfully and finds
+ *     the whole chain, all way to the data (returns %NULL, *err == 0).
+ */
+static inline Indirect *ext2_get_branch(struct inode *inode,
+                                       int depth,
+                                       int *offsets,
+                                       Indirect chain[4],
+                                       int *err)
+{
+       kdev_t dev = inode->i_dev;
+       int size = inode->i_sb->s_blocksize;
+       Indirect *p = chain;
+       struct buffer_head *bh;
+
+       *err = 0;
+       /* i_data is not going away, no lock needed */
+       add_chain (chain, NULL, inode->u.ext2_i.i_data + *offsets);
+       if (!p->key)
+               goto no_block;
+       /*
+        * switch below is merely an unrolled loop - body should be
+        * repeated depth-1 times. Maybe loop would be actually better,
+        * but that way we get straight execution path in normal cases.
+        * Easy to change, anyway - all cases in switch are literally
+        * identical.
+        */
+       switch (depth) {
+               case 4:
+                       bh = bread(dev, le32_to_cpu(p->key), size);
+                       if (!bh)
+                               goto failure;
+                       /* Reader: pointers */
+                       if (!verify_chain(chain, p))
+                               goto changed;
+                       add_chain(++p, bh, (u32*)bh->b_data + *++offsets);
+                       /* Reader: end */
+                       if (!p->key)
+                               goto no_block;
+               case 3:
+                       bh = bread(dev, le32_to_cpu(p->key), size);
+                       if (!bh)
+                               goto failure;
+                       /* Reader: pointers */
+                       if (!verify_chain(chain, p))
+                               goto changed;
+                       add_chain(++p, bh, (u32*)bh->b_data + *++offsets);
+                       /* Reader: end */
+                       if (!p->key)
+                               goto no_block;
+               case 2:
+                       bh = bread(dev, le32_to_cpu(p->key), size);
+                       if (!bh)
+                               goto failure;
+                       /* Reader: pointers */
+                       if (!verify_chain(chain, p))
+                               goto changed;
+                       add_chain(++p, bh, (u32*)bh->b_data + *++offsets);
+                       /* Reader: end */
+                       if (!p->key)
+                               goto no_block;
        }
-       block -= (1 << (ptrs_bits * 2));
-       i = inode_bmap (inode, EXT2_TIND_BLOCK);
-       if (!i)
-               goto out;
-       i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
-                       block >> (ptrs_bits * 2));
-       if (!i)
-               goto out;
-       i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
-                       (block >> ptrs_bits) & (ptrs - 1));
-       if (!i)
-               goto out;
-       ret = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
-                          block & (ptrs - 1));
-out:
-       unlock_kernel();
-       return ret;
+       return NULL;
+
+changed:
+       *err = -EAGAIN;
+       goto no_block;
+failure:
+       *err = -EIO;
+no_block:
+       return p;
 }
 
 static struct buffer_head * inode_getblk (struct inode * inode, int nr,
@@ -396,28 +495,37 @@ static int ext2_get_block(struct inode *inode, long iblock, struct buffer_head *
 {
        int ret, err, new;
        struct buffer_head *bh;
-       unsigned long ptr, phys;
-       /*
-        * block pointers per block
-        */
-       unsigned long ptrs = EXT2_ADDR_PER_BLOCK(inode->i_sb);
-       int ptrs_bits = EXT2_ADDR_PER_BLOCK_BITS(inode->i_sb);
-       const int direct_blocks = EXT2_NDIR_BLOCKS,
-               indirect_blocks = ptrs,
-               double_blocks = (1 << (ptrs_bits * 2)),
-               triple_blocks = (1 << (ptrs_bits * 3));
+       unsigned long phys;
+       int offsets[4];
+       int *p;
+       Indirect chain[4];
+       Indirect *partial;
+       int depth;
+
+       depth = ext2_block_to_path(inode, iblock, offsets);
+       if (depth == 0)
+               goto abort;
+
+       lock_kernel();
+       partial = ext2_get_branch(inode, depth, offsets, chain, &err);
+
+       if (!partial) {
+               unlock_kernel();
+               for (partial = chain + depth - 1; partial > chain; partial--)
+                       brelse(partial->bh);
+               bh_result->b_dev = inode->i_dev;
+               bh_result->b_blocknr = le32_to_cpu(chain[depth-1].key);
+               bh_result->b_state |= (1UL << BH_Mapped);
+               return 0;
+       }
+
+       while (partial > chain) {
+               brelse(partial->bh);
+               partial--;
+       }
 
        if (!create) {
-               /*
-                * Will clean this up further, ext2_block_map() should use the
-                * bh instead of an integer block-number interface.
-                */
-               phys = ext2_block_map(inode, iblock);
-               if (phys) {
-                       bh_result->b_dev = inode->i_dev;
-                       bh_result->b_blocknr = phys;
-                       bh_result->b_state |= (1UL << BH_Mapped);
-               }
+               unlock_kernel();
                return 0;
        }
 
@@ -426,14 +534,6 @@ static int ext2_get_block(struct inode *inode, long iblock, struct buffer_head *
        ret = 0;
        bh = NULL;
 
-       lock_kernel();
-
-       if (iblock < 0)
-               goto abort_negative;
-       if (iblock > direct_blocks + indirect_blocks +
-                                        double_blocks + triple_blocks)
-               goto abort_too_big;
-
        /*
         * If this is a sequential block allocation, set the next_alloc_block
         * to this block now so that all the indblock and data block
@@ -450,7 +550,6 @@ static int ext2_get_block(struct inode *inode, long iblock, struct buffer_head *
        }
 
        err = 0;
-       ptr = iblock;
 
        /*
         * ok, these macros clean the logic up a bit and make
@@ -465,27 +564,20 @@ static int ext2_get_block(struct inode *inode, long iblock, struct buffer_head *
 #define GET_INDIRECT_PTR(x) \
                block_getblk (inode, bh, x, iblock, &err, 1, NULL, NULL);
 
-       if (ptr < direct_blocks) {
-               bh = GET_INODE_DATABLOCK(ptr);
+       p = offsets;
+       if (depth == 1) {
+               bh = GET_INODE_DATABLOCK(*p);
                goto out;
        }
-       ptr -= direct_blocks;
-       if (ptr < indirect_blocks) {
-               bh = GET_INODE_PTR(EXT2_IND_BLOCK);
-               goto get_indirect;
+       bh = GET_INODE_PTR(*p);
+       switch (depth) {
+               default: /* case 4: */
+                       bh = GET_INDIRECT_PTR(*++p);
+               case 3:
+                       bh = GET_INDIRECT_PTR(*++p);
+               case 2:
+                       bh = GET_INDIRECT_DATABLOCK(*++p);
        }
-       ptr -= indirect_blocks;
-       if (ptr < double_blocks) {
-               bh = GET_INODE_PTR(EXT2_DIND_BLOCK);
-               goto get_double;
-       }
-       ptr -= double_blocks;
-       bh = GET_INODE_PTR(EXT2_TIND_BLOCK);
-       bh = GET_INDIRECT_PTR(ptr >> (ptrs_bits * 2));
-get_double:
-       bh = GET_INDIRECT_PTR((ptr >> ptrs_bits) & (ptrs - 1));
-get_indirect:
-       bh = GET_INDIRECT_DATABLOCK(ptr & (ptrs - 1));
 
 #undef GET_INODE_DATABLOCK
 #undef GET_INODE_PTR
@@ -505,17 +597,9 @@ out:
        bh_result->b_state |= (1UL << BH_Mapped); /* safe */
        if (new)
                bh_result->b_state |= (1UL << BH_New);
-abort:
        unlock_kernel();
+abort:
        return err;
-
-abort_negative:
-       ext2_warning (inode->i_sb, "ext2_get_block", "block < 0");
-       goto abort;
-
-abort_too_big:
-       ext2_warning (inode->i_sb, "ext2_get_block", "block > big");
-       goto abort;
 }
 
 struct buffer_head * ext2_getblk(struct inode * inode, long block, int create, int * err)
index e395c75a1d5a5a35b776bc55fbfd970ca357e4aa..bca514ee52e5c911ffe94bc31ae52b198a6ce9d6 100644 (file)
@@ -254,53 +254,56 @@ static int parse_options (char * options, unsigned long * sb_block,
        return 1;
 }
 
-static void ext2_setup_super (struct super_block * sb,
-                             struct ext2_super_block * es)
+static int ext2_setup_super (struct super_block * sb,
+                             struct ext2_super_block * es,
+                             int read_only)
 {
+       int res = 0;
        if (le32_to_cpu(es->s_rev_level) > EXT2_MAX_SUPP_REV) {
                        printk ("EXT2-fs warning: revision level too high, "
                                "forcing read/only mode\n");
-                       sb->s_flags |= MS_RDONLY;
+                       res = MS_RDONLY;
        }
-       if (!(sb->s_flags & MS_RDONLY)) {
-               if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
-                       printk ("EXT2-fs warning: mounting unchecked fs, "
-                               "running e2fsck is recommended\n");
-               else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS))
-                       printk ("EXT2-fs warning: mounting fs with errors, "
-                               "running e2fsck is recommended\n");
-               else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
-                        le16_to_cpu(es->s_mnt_count) >=
-                        (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
-                       printk ("EXT2-fs warning: maximal mount count reached, "
-                               "running e2fsck is recommended\n");
-               else if (le32_to_cpu(es->s_checkinterval) &&
-                       (le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= CURRENT_TIME))
-                       printk ("EXT2-fs warning: checktime reached, "
-                               "running e2fsck is recommended\n");
-               es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT2_VALID_FS);
-               if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
-                       es->s_max_mnt_count = (__s16) cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);
-               es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1);
-               es->s_mtime = cpu_to_le32(CURRENT_TIME);
-               mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
-               sb->s_dirt = 1;
-               if (test_opt (sb, DEBUG))
-                       printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
-                               "bpg=%lu, ipg=%lu, mo=%04lx]\n",
-                               EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
-                               sb->u.ext2_sb.s_frag_size,
-                               sb->u.ext2_sb.s_groups_count,
-                               EXT2_BLOCKS_PER_GROUP(sb),
-                               EXT2_INODES_PER_GROUP(sb),
-                               sb->u.ext2_sb.s_mount_opt);
+       if (read_only)
+               return res;
+       if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS))
+               printk ("EXT2-fs warning: mounting unchecked fs, "
+                       "running e2fsck is recommended\n");
+       else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS))
+               printk ("EXT2-fs warning: mounting fs with errors, "
+                       "running e2fsck is recommended\n");
+       else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
+                le16_to_cpu(es->s_mnt_count) >=
+                (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
+               printk ("EXT2-fs warning: maximal mount count reached, "
+                       "running e2fsck is recommended\n");
+       else if (le32_to_cpu(es->s_checkinterval) &&
+               (le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= CURRENT_TIME))
+               printk ("EXT2-fs warning: checktime reached, "
+                       "running e2fsck is recommended\n");
+       es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT2_VALID_FS);
+       if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
+               es->s_max_mnt_count = (__s16) cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);
+       es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1);
+       es->s_mtime = cpu_to_le32(CURRENT_TIME);
+       mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
+       sb->s_dirt = 1;
+       if (test_opt (sb, DEBUG))
+               printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
+                       "bpg=%lu, ipg=%lu, mo=%04lx]\n",
+                       EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
+                       sb->u.ext2_sb.s_frag_size,
+                       sb->u.ext2_sb.s_groups_count,
+                       EXT2_BLOCKS_PER_GROUP(sb),
+                       EXT2_INODES_PER_GROUP(sb),
+                       sb->u.ext2_sb.s_mount_opt);
 #ifdef CONFIG_EXT2_CHECK
-               if (test_opt (sb, CHECK)) {
-                       ext2_check_blocks_bitmap (sb);
-                       ext2_check_inodes_bitmap (sb);
-               }
-#endif
+       if (test_opt (sb, CHECK)) {
+               ext2_check_blocks_bitmap (sb);
+               ext2_check_inodes_bitmap (sb);
        }
+#endif
+       return res;
 }
 
 static int ext2_check_descriptors (struct super_block * sb)
@@ -601,7 +604,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
                printk ("EXT2-fs: get root inode failed\n");
                return NULL;
        }
-       ext2_setup_super (sb, es);
+       ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
        return sb;
 }
 
@@ -685,8 +688,8 @@ int ext2_remount (struct super_block * sb, int * flags, char * data)
                 * by e2fsck since we originally mounted the partition.)
                 */
                sb->u.ext2_sb.s_mount_state = le16_to_cpu(es->s_state);
-               sb->s_flags &= ~MS_RDONLY;
-               ext2_setup_super (sb, es);
+               if (!ext2_setup_super (sb, es, 0))
+                       sb->s_flags &= ~MS_RDONLY;
        }
        return 0;
 }
index c7ea5cfe571fa5ce7936013ae2e906496d91a6b9..bbb895285eae2f89bbbb3660c08ab968333ad990 100644 (file)
@@ -10,7 +10,7 @@
  *  VFAT extensions by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
  *  Merged with msdos fs by Henrik Storner <storner@osiris.ping.dk>
  *  Rewritten for constant inumbers. Plugged buffer overrun in readdir(). AV
- *  Short name translation 1999 by Wolfram Pienkoss <wp@bsz.shk.th.schule.de>
+ *  Short name translation 1999 by Wolfram Pienkoss <wp@bszh.de>
  */
 
 #define ASC_LINUX_VERSION(V, P, S)     (((V) * 65536) + ((P) * 256) + (S))
index 3895b0774778ec49a9537ff3eb1538989d583b4e..b3fcf2088479e946b6f4f19a4bf821793e4fc980 100644 (file)
@@ -9,7 +9,7 @@
  *    what file operation caused you trouble and if you can duplicate
  *    the problem, send a script that demonstrates it.
  *
- *  Short name translation 1999 by Wolfram Pienkoss <wp@bsz.shk.th.schule.de>
+ *  Short name translation 1999 by Wolfram Pienkoss <wp@bszh.de>
  */
 
 #define __NO_VERSION__
index d9483efb1f55e897be1b149f91a0b0abfeb8406c..e6d4d1695e256cdccce5a74d1b87edc8e99b8542 100644 (file)
@@ -8,12 +8,14 @@
 
 /* Bytes per L1 (data) cache line. */
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
-# define L1_CACHE_BYTES     32 /* should be 64, but networking dies */
+# define L1_CACHE_BYTES     64
+# define L1_CACHE_SHIFT     6
 #else
 /* Both EV4 and EV5 are write-through, read-allocate,
    direct-mapped, physical.
 */
 # define L1_CACHE_BYTES     32
+# define L1_CACHE_SHIFT     5
 #endif
 
 #define L1_CACHE_ALIGN(x)  (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
index 732ea22eab466df1faebbd82b671945272544a9b..adaba397ae2ea09bb91477c160d1c7b5f762c2f0 100644 (file)
@@ -1,8 +1,10 @@
 /*
- * $Id: elf.h,v 1.6 1999/02/15 02:22:10 ralf Exp $
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  */
-#ifndef __ASM_MIPS_ELF_H
-#define __ASM_MIPS_ELF_H
+#ifndef __ASM_ELF_H
+#define __ASM_ELF_H
 
 /* ELF register definitions */
 #define ELF_NGREG      45
@@ -20,13 +22,14 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
  */
 #define elf_check_arch(hdr)                                            \
 ({                                                                     \
-       int __res = 0;                                                  \
+       int __res = 1;                                                  \
        struct elfhdr *__h = (hdr);                                     \
                                                                        \
-       if ((__h->e_machine != EM_MIPS) && (__h->e_machine != EM_MIPS)) \
-               __res = -ENOEXEC;                                       \
+       if ((__h->e_machine != EM_MIPS) &&                              \
+           (__h->e_machine != EM_MIPS_RS4_BE))                         \
+               __res = 0;                                              \
        if (__h->e_flags & EF_MIPS_ARCH)                                \
-               __res = -ENOEXEC;                                       \
+               __res = 0;                                              \
                                                                        \
        __res;                                                          \
 })
@@ -34,11 +37,12 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 /* This one accepts IRIX binaries.  */
 #define irix_elf_check_arch(hdr)                                       \
 ({                                                                     \
-       int __res = 0;                                                  \
+       int __res = 1;                                                  \
        struct elfhdr *__h = (hdr);                                     \
                                                                        \
-       if ((__h->e_machine != EM_MIPS) && (__h->e_machine != EM_MIPS)) \
-               __res = -ENOEXEC;                                       \
+       if ((__h->e_machine != EM_MIPS) &&                              \
+           (__h->e_machine != EM_MIPS_RS4_BE))                         \
+               __res = 0;                                              \
                                                                        \
        __res;                                                          \
 })
@@ -102,4 +106,4 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
 #endif
 
-#endif /* __ASM_MIPS_ELF_H */
+#endif /* __ASM_ELF_H */
index 4ed782fc6fd0b16d456339d74dea0e5d15a64d98..bae7fcd1acdcb3982342fe88127f11ec3a516edb 100644 (file)
@@ -1,12 +1,11 @@
-/* $Id: mc146818rtc.h,v 1.2 1998/06/30 00:23:10 ralf Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
  * Machine dependent access functions for RTC registers.
  *
- * Copyright (C) 1996, 1997, 1998 Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 2000 Ralf Baechle
  */
 #ifndef _ASM_MC146818RTC_H
 #define _ASM_MC146818RTC_H
@@ -43,4 +42,10 @@ struct rtc_ops {
 
 extern struct rtc_ops *rtc_ops;
 
+#ifdef CONFIG_DECSTATION
+#define RTC_IRQ 0
+#else
+#define RTC_IRQ        8
+#endif
+
 #endif /* _ASM_MC146818RTC_H */
index 429c805610d46b34207cdb2a49cc34b682f49c83..3ab76a80bc4dc154aae9210c25adb5b76c77bef9 100644 (file)
@@ -26,14 +26,15 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
  */
 #define elf_check_arch(hdr)                                            \
 ({                                                                     \
-       int __res = 0;                                                  \
+       int __res = 1;                                                  \
        struct elfhdr *__h = (hdr);                                     \
                                                                        \
-       if ((__h->e_machine != EM_MIPS) && (__h->e_machine != EM_MIPS)) \
-               __res = -ENOEXEC;                                       \
+       if ((__h->e_machine != EM_MIPS) &&                              \
+           (__h->e_machine != EM_MIPS_RS4_BE))                         \
+               __res = 0;                                              \
        if (sizeof(elf_caddr_t) == 8 &&                                 \
            __h->e_ident[EI_CLASS] == ELFCLASS32)                       \
-               __res = -ENOEXEC;                                       \
+               __res = 0;                                              \
                                                                        \
        __res;                                                          \
 })
index f9e51fa61902096f05eab8442d70d71dc21909fa..cdea504a2bf24ae4a2801d8a91adcc98ddc1fdb1 100644 (file)
@@ -43,4 +43,6 @@ struct rtc_ops {
 
 extern struct rtc_ops *rtc_ops;
 
+#define RTC_IRQ 8
+
 #endif /* _ASM_MC146818RTC_H */
index b0c97ced10c552784c8c675034dcc3ea0d74c703..c40380569ae6fc5aa93b45b2494d8066dcb3a74b 100644 (file)
  *  - flush_cache_range(mm, start, end) flushes a range of pages
  *  - flush_page_to_ram(page) write back kernel page to ram
  */
-extern void (*_flush_cache_all)(void);
 extern void (*_flush_cache_mm)(struct mm_struct *mm);
 extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
                                  unsigned long end);
 extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
-extern void (*_flush_cache_sigtramp)(unsigned long addr);
 extern void (*_flush_page_to_ram)(struct page * page);
 
-#define flush_cache_all()              _flush_cache_all()
+#define flush_cache_all()              do { } while(0)
+
+#ifndef CONFIG_CPU_R10000
 #define flush_cache_mm(mm)             _flush_cache_mm(mm)
 #define flush_cache_range(mm,start,end)        _flush_cache_range(mm,start,end)
 #define flush_cache_page(vma,page)     _flush_cache_page(vma, page)
-#define flush_cache_sigtramp(addr)     _flush_cache_sigtramp(addr)
 #define flush_page_to_ram(page)                _flush_page_to_ram(page)
 
-#define flush_icache_range(start, end) flush_cache_all()
+#define flush_icache_range(start, end) _flush_cache_l1()
 
 #define flush_icache_page(vma, page)                                   \
 do {                                                                   \
@@ -50,6 +49,40 @@ do {                                                                 \
        addr = page_address(page);                                      \
        _flush_cache_page(vma, addr);                                   \
 } while (0)                                                              
+#else /* !CONFIG_CPU_R10000 */
+/*
+ * Since the r10k handles VCEs in hardware, most of the flush cache
+ * routines are not needed. Only the icache on a processor is not
+ * coherent with the dcache of the _same_ processor, so we must flush
+ * the icache so that it does not contain stale contents of physical
+ * memory. No flushes are needed for dma coherency, since the o200s 
+ * are io coherent. The only place where we might be overoptimizing 
+ * out icache flushes are from mprotect (when PROT_EXEC is added).
+ */
+extern void andes_flush_icache_page(unsigned long);
+#define flush_cache_mm(mm)             do { } while(0)
+#define flush_cache_range(mm,start,end)        do { } while(0)
+#define flush_cache_page(vma,page)     do { } while(0)
+#define flush_page_to_ram(page)                do { } while(0)
+#define flush_icache_range(start, end) _flush_cache_l1()
+#define flush_icache_page(vma, page)                                   \
+do {                                                                   \
+       if ((vma)->vm_flags & VM_EXEC)                                  \
+               andes_flush_icache_page(page_address(page));            \
+} while (0)
+#endif /* !CONFIG_CPU_R10000 */
+
+/*
+ * The foll cache flushing routines are MIPS specific.
+ * flush_cache_l2 is needed only during initialization.
+ */
+extern void (*_flush_cache_sigtramp)(unsigned long addr);
+extern void (*_flush_cache_l2)(void);
+extern void (*_flush_cache_l1)(void);
+
+#define flush_cache_sigtramp(addr)     _flush_cache_sigtramp(addr)
+#define flush_cache_l2()               _flush_cache_l2()
+#define flush_cache_l1()               _flush_cache_l1()
 
 /*
  * Each address space has 2 4K pages as its page directory, giving 1024
index 3592b3821add1a366b0004a30963df322b55c181..47e90aec4619bc6fd44747b38e5b91ee44721b08 100644 (file)
@@ -117,7 +117,7 @@ extern void __global_restore_flags(unsigned long);
 #define sti() __global_sti()
 #define save_flags(x) ((x)=__global_save_flags())
 #define restore_flags(x) __global_restore_flags(x)
-#define save_and_cli(x) do { save_flags(flags); cli(); } while(0)
+#define save_and_cli(x) do { save_flags(x); cli(); } while(0)
 
 #else
 
index 63edac9d6b8f76cbb5d4607a060c22fd5997abbf..dd88e8a80178f3e37411c7476f246a9be703d495 100644 (file)
@@ -76,7 +76,7 @@
 #define D_TIMING       4096    /* show time needed to copy buffers to card */
 
 #ifndef ARCNET_DEBUG_MAX
-#define ARCNET_DEBUG_MAX (~0)  /* enable ALL debug messages       */
+#define ARCNET_DEBUG_MAX (127) /* change to ~0 if you want detailed debugging */
 #endif
 
 #ifndef ARCNET_DEBUG
index 0644ae74cc06f73ee0c5d7b2b927527f1b7cebcd..062e310ee87260138d76ae17b54748447cab9a7d 100644 (file)
  */
 #define MAX_ARG_PAGES 32
 
+/* sizeof(linux_binprm->buf) */
+#define BINPRM_BUF_SIZE 128
+
 #ifdef __KERNEL__
 
 /*
  * This structure is used to hold the arguments that are used when loading binaries.
  */
 struct linux_binprm{
-       char buf[128];
+       char buf[BINPRM_BUF_SIZE];
        struct page *page[MAX_ARG_PAGES];
        unsigned long p; /* current top of mem */
        int sh_bang;
index a561f805fdded9b91c487a09189deb909c5cd7e4..fef8d2b2010240c30bb702e6806caa48905370a5 100644 (file)
@@ -143,8 +143,13 @@ struct module_info
 #define __MODULE_STRING(x)     __MODULE_STRING_1(x)
 
 /* Find a symbol exported by the kernel or another module */
+#ifdef CONFIG_MODULES
 extern unsigned long get_module_symbol(char *, char *);
 extern void put_module_symbol(unsigned long);
+#else
+static inline unsigned long get_module_symbol(char *unused1, char *unused2) { return 0; };
+static inline void put_module_symbol(unsigned long unused) { };
+#endif
 
 extern int try_inc_mod_count(struct module *mod);
 
index 673a78d167fbdd6d9b022d7fa8006165b2103e71..e8450e8a4939f5642f032a2ddd00b7e2869de4ef 100644 (file)
@@ -243,10 +243,24 @@ struct signal_struct {
 
 /*
  * Some day this will be a full-fledged user tracking system..
- * Right now it is only used to track how many processes a
- * user has, but it has the potential to track memory usage etc.
  */
-struct user_struct;
+struct user_struct {
+       atomic_t __count;       /* reference count */
+       atomic_t processes;     /* How many processes does this user have? */
+       atomic_t files;         /* How many open files does this user have? */
+
+       /* Hash table maintenance information */
+       struct user_struct *next, **pprev;
+       unsigned int uid;
+};
+
+#define get_current_user() ({                          \
+       struct user_struct *__user = current->user;     \
+       atomic_inc(&__user->__count);                   \
+       __user; })
+
+extern struct user_struct root_user;
+#define INIT_USER (&root_user)
 
 struct task_struct {
        /*
@@ -427,6 +441,7 @@ struct task_struct {
     cap_permitted:     CAP_FULL_SET,                                   \
     keep_capabilities: 0,                                              \
     rlim:              INIT_RLIMITS,                                   \
+    user:              INIT_USER,                                      \
     comm:              "swapper",                                      \
     thread:            INIT_THREAD,                                    \
     fs:                        &init_fs,                                       \
@@ -489,8 +504,8 @@ static inline struct task_struct *find_task_by_pid(int pid)
 }
 
 /* per-UID process charging. */
-extern int alloc_uid(struct task_struct *);
-void free_uid(struct task_struct *);
+extern struct user_struct * alloc_uid(uid_t);
+extern void free_uid(struct user_struct *);
 
 #include <asm/current.h>
 
index 86fce1e7d8886023dfee1222e76de1ce2939ec19..8ba581f5ba38050955fc043f977916b0f19fd291 100644 (file)
@@ -118,6 +118,7 @@ typedef struct {
   #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 #endif
 
+#define rwlock_init(lock)      do { } while(0)
 #define read_lock(lock)                (void)(lock) /* Not "unused variable". */
 #define read_unlock(lock)      do { } while(0)
 #define write_lock(lock)       (void)(lock) /* Not "unused variable". */
index 680069a4472df75291da3fb07a5ff0a36270e2ff..060d5de240f992c4c17fdce388174ca0751b7059 100644 (file)
@@ -11,9 +11,11 @@ Original driver (sg.h):
 Version 2 and 3 extensions to driver:
 *       Copyright (C) 1998 - 2000 Douglas Gilbert
 
-    Version: 3.1.15 (20000528)
+    Version: 3.1.16 (20000716)
     This version is for 2.3/2.4 series kernels.
 
+    Changes since 3.1.15 (20000528)
+       - further (scatter gather) buffer length changes
     Changes since 3.1.14 (20000503)
         - fix aha1542 odd length buffer problem
         - make multiple readers on same fd safe
index 53606a35937dd8c54cc096c6c5d5455f20ddaa00..a13812119e4839578e12c925c1f0ac6b2784ee87 100644 (file)
@@ -10,7 +10,7 @@
 O_TARGET := kernel.o
 O_OBJS    = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
            module.o exit.o itimer.o info.o time.o softirq.o resource.o \
-           sysctl.o acct.o capability.o ptrace.o timer.o
+           sysctl.o acct.o capability.o ptrace.o timer.o user.o
 
 OX_OBJS  += signal.o sys.o
 
index ae1b28177b0b5cac941014e6c56e9880c4915581..45eb97748163ddd5165d41aecd064fdf06b15c27 100644 (file)
@@ -38,7 +38,8 @@ static void release(struct task_struct * p)
                        spin_unlock_irq(&runqueue_lock);
                } while (has_cpu);
 #endif
-               free_uid(p);
+               atomic_dec(&p->user->processes);
+               free_uid(p->user);
                unhash_process(p);
 
                release_thread(p);
index 683f047ad33aaf92f7fa9d7f071cc6ea2bb625a9..594ee79f317689d002dc3caceae83b6685b24572 100644 (file)
@@ -37,125 +37,6 @@ kmem_cache_t *mm_cachep;
 
 struct task_struct *pidhash[PIDHASH_SZ];
 
-/* UID task count cache, to prevent walking entire process list every
- * single fork() operation.
- */
-#define UIDHASH_SZ     (PIDHASH_SZ >> 2)
-
-static struct user_struct {
-       atomic_t count;
-       struct user_struct *next, **pprev;
-       unsigned int uid;
-} *uidhash[UIDHASH_SZ];
-
-spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
-
-kmem_cache_t *uid_cachep;
-
-#define uidhashfn(uid) (((uid >> 8) ^ uid) & (UIDHASH_SZ - 1))
-
-/*
- * These routines must be called with the uidhash spinlock held!
- */
-static inline void uid_hash_insert(struct user_struct *up, unsigned int hashent)
-{
-       if((up->next = uidhash[hashent]) != NULL)
-               uidhash[hashent]->pprev = &up->next;
-       up->pprev = &uidhash[hashent];
-       uidhash[hashent] = up;
-}
-
-static inline void uid_hash_remove(struct user_struct *up)
-{
-       if(up->next)
-               up->next->pprev = up->pprev;
-       *up->pprev = up->next;
-}
-
-static inline struct user_struct *uid_hash_find(unsigned short uid, unsigned int hashent)
-{
-       struct user_struct *up, *next;
-
-       next = uidhash[hashent];
-       for (;;) {
-               up = next;
-               if (next) {
-                       next = up->next;
-                       if (up->uid != uid)
-                               continue;
-                       atomic_inc(&up->count);
-               }
-               break;
-       }
-       return up;
-}
-
-/*
- * For SMP, we need to re-test the user struct counter
- * after having aquired the spinlock. This allows us to do
- * the common case (not freeing anything) without having
- * any locking.
- */
-#ifdef CONFIG_SMP
-  #define uid_hash_free(up)    (!atomic_read(&(up)->count))
-#else
-  #define uid_hash_free(up)    (1)
-#endif
-
-void free_uid(struct task_struct *p)
-{
-       struct user_struct *up = p->user;
-
-       if (up) {
-               p->user = NULL;
-               if (atomic_dec_and_test(&up->count)) {
-                       spin_lock(&uidhash_lock);
-                       if (uid_hash_free(up)) {
-                               uid_hash_remove(up);
-                               kmem_cache_free(uid_cachep, up);
-                       }
-                       spin_unlock(&uidhash_lock);
-               }
-       }
-}
-
-int alloc_uid(struct task_struct *p)
-{
-       unsigned int hashent = uidhashfn(p->uid);
-       struct user_struct *up;
-
-       spin_lock(&uidhash_lock);
-       up = uid_hash_find(p->uid, hashent);
-       spin_unlock(&uidhash_lock);
-
-       if (!up) {
-               struct user_struct *new;
-
-               new = kmem_cache_alloc(uid_cachep, SLAB_KERNEL);
-               if (!new)
-                       return -EAGAIN;
-               new->uid = p->uid;
-               atomic_set(&new->count, 1);
-
-               /*
-                * Before adding this, check whether we raced
-                * on adding the same user already..
-                */
-               spin_lock(&uidhash_lock);
-               up = uid_hash_find(p->uid, hashent);
-               if (up) {
-                       kmem_cache_free(uid_cachep, new);
-               } else {
-                       uid_hash_insert(new, hashent);
-                       up = new;
-               }
-               spin_unlock(&uidhash_lock);
-
-       }
-       p->user = up;
-       return 0;
-}
-
 void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
 {
        unsigned long flags;
@@ -185,17 +66,6 @@ void remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
 
 void __init fork_init(unsigned long mempages)
 {
-       int i;
-
-       uid_cachep = kmem_cache_create("uid_cache", sizeof(struct user_struct),
-                                      0,
-                                      SLAB_HWCACHE_ALIGN, NULL, NULL);
-       if(!uid_cachep)
-               panic("Cannot create uid taskcount SLAB cache\n");
-
-       for(i = 0; i < UIDHASH_SZ; i++)
-               uidhash[i] = 0;
-
        /*
         * The default maximum number of threads is set to a safe
         * value: the thread structures can take up at most half
@@ -664,11 +534,10 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
        lock_kernel();
 
        retval = -EAGAIN;
-       if (p->user) {
-               if (atomic_read(&p->user->count) >= p->rlim[RLIMIT_NPROC].rlim_cur)
-                       goto bad_fork_free;
-               atomic_inc(&p->user->count);
-       }
+       if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur)
+               goto bad_fork_free;
+       atomic_inc(&p->user->__count);
+       atomic_inc(&p->user->processes);
 
        /*
         * Counter increases are protected by
@@ -801,8 +670,8 @@ bad_fork_cleanup:
        if (p->binfmt && p->binfmt->module)
                __MOD_DEC_USE_COUNT(p->binfmt->module);
 bad_fork_cleanup_count:
-       if (p->user)
-               free_uid(p);
+       atomic_dec(&p->user->processes);
+       free_uid(p->user);
 bad_fork_free:
        free_task_struct(p);
        goto bad_fork;
index 581021d858e028fb11b8ce5ab7217c838837ed43..2a918b632e6a4d9376792db3a29ef2c11e8538af 100644 (file)
@@ -466,6 +466,28 @@ extern inline void cap_emulate_setxuid(int old_ruid, int old_euid,
        }
 }
 
+static int set_user(uid_t new_ruid)
+{
+       struct user_struct *new_user, *old_user;
+
+       /* What if a process setreuid()'s and this brings the
+        * new uid over his NPROC rlimit?  We can check this now
+        * cheaply with the new uid cache, so if it matters
+        * we should be checking for it.  -DaveM
+        */
+       new_user = alloc_uid(new_ruid);
+       if (!new_user)
+               return -EAGAIN;
+       old_user = current->user;
+       atomic_dec(&old_user->processes);
+       atomic_inc(&new_user->processes);
+
+       current->uid = new_ruid;
+       current->user = new_user;
+       free_uid(old_user);
+       return 0;
+}
+
 /*
  * Unprivileged users may change the real uid to the effective uid
  * or vice versa.  (BSD-style)
@@ -483,28 +505,33 @@ extern inline void cap_emulate_setxuid(int old_ruid, int old_euid,
  */
 asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
 {
-       int old_ruid, old_euid, old_suid, new_ruid;
+       int old_ruid, old_euid, old_suid, new_ruid, new_euid;
 
        new_ruid = old_ruid = current->uid;
-       old_euid = current->euid;
+       new_euid = old_euid = current->euid;
        old_suid = current->suid;
+
        if (ruid != (uid_t) -1) {
-               if ((old_ruid == ruid) || 
-                   (current->euid==ruid) ||
-                   capable(CAP_SETUID))
-                       new_ruid = ruid;
-               else
+               new_ruid = ruid;
+               if ((old_ruid != ruid) &&
+                   (current->euid != ruid) &&
+                   !capable(CAP_SETUID))
                        return -EPERM;
        }
+
        if (euid != (uid_t) -1) {
-               if ((old_ruid == euid) ||
-                   (current->euid == euid) ||
-                   (current->suid == euid) ||
-                   capable(CAP_SETUID))
-                       current->fsuid = current->euid = euid;
-               else
+               new_euid = euid;
+               if ((old_ruid != euid) &&
+                   (current->euid != euid) &&
+                   (current->suid != euid) &&
+                   !capable(CAP_SETUID))
                        return -EPERM;
        }
+
+       if (new_ruid != old_ruid && set_user(new_ruid) < 0)
+               return -EAGAIN;
+
+       current->fsuid = current->euid = new_euid;
        if (ruid != (uid_t) -1 ||
            (euid != (uid_t) -1 && euid != old_ruid))
                current->suid = current->euid;
@@ -512,17 +539,6 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
        if (current->euid != old_euid)
                current->dumpable = 0;
 
-       if(new_ruid != old_ruid) {
-               /* What if a process setreuid()'s and this brings the
-                * new uid over his NPROC rlimit?  We can check this now
-                * cheaply with the new uid cache, so if it matters
-                * we should be checking for it.  -DaveM
-                */
-               free_uid(current);
-               current->uid = new_ruid;
-               alloc_uid(current);
-       }
-       
        if (!issecure(SECURE_NO_SETUID_FIXUP)) {
                cap_emulate_setxuid(old_ruid, old_euid, old_suid);
        }
@@ -550,22 +566,22 @@ asmlinkage long sys_setuid(uid_t uid)
 
        old_ruid = new_ruid = current->uid;
        old_suid = current->suid;
-       if (capable(CAP_SETUID))
-               new_ruid = current->euid = current->suid = current->fsuid = uid;
-       else if ((uid == current->uid) || (uid == current->suid))
-               current->fsuid = current->euid = uid;
-       else
+       if (capable(CAP_SETUID)) {
+               if (uid != old_ruid && set_user(uid) < 0)
+                       return -EAGAIN;
+               current->suid = uid;
+       } else if (uid == current->uid) {
+               /* Nothing - just set fsuid/euid */
+       }  else if (uid == current->suid) {
+               if (set_user(uid) < 0)
+                       return -EAGAIN;
+       } else
                return -EPERM;
 
-       if (current->euid != old_euid)
-               current->dumpable = 0;
+       current->fsuid = current->euid = uid;
 
-       if (new_ruid != old_ruid) {
-               /* See comment above about NPROC rlimit issues... */
-               free_uid(current);
-               current->uid = new_ruid;
-               alloc_uid(current);
-       }
+       if (old_euid != uid)
+               current->dumpable = 0;
 
        if (!issecure(SECURE_NO_SETUID_FIXUP)) {
                cap_emulate_setxuid(old_ruid, old_euid, old_suid);
@@ -597,10 +613,8 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
                        return -EPERM;
        }
        if (ruid != (uid_t) -1) {
-               /* See above commentary about NPROC rlimit issues here. */
-               free_uid(current);
-               current->uid = ruid;
-               alloc_uid(current);
+               if (ruid != current->uid && set_user(ruid) < 0)
+                       return -EAGAIN;
        }
        if (euid != (uid_t) -1) {
                if (euid != current->euid)
diff --git a/kernel/user.c b/kernel/user.c
new file mode 100644 (file)
index 0000000..d9f96da
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * The "user cache".
+ *
+ * (C) Copyright 1991-2000 Linus Torvalds
+ *
+ * We have a per-user structure to keep track of how many
+ * processes, files etc the user has claimed, in order to be
+ * able to have per-user limits for system resources. 
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+/*
+ * UID task count cache, to get fast user lookup in "alloc_uid"
+ * when changing user ID's (ie setuid() and friends).
+ */
+#define UIDHASH_SZ     (256)
+
+static struct user_struct *uidhash[UIDHASH_SZ];
+
+spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED;
+
+struct user_struct root_user = {
+       __count:        ATOMIC_INIT(1),
+       processes:      ATOMIC_INIT(1),
+       files:          ATOMIC_INIT(0)
+};
+
+static kmem_cache_t *uid_cachep;
+
+#define uidhashfn(uid) (((uid >> 8) ^ uid) & (UIDHASH_SZ - 1))
+
+/*
+ * These routines must be called with the uidhash spinlock held!
+ */
+static inline void uid_hash_insert(struct user_struct *up, unsigned int hashent)
+{
+       if((up->next = uidhash[hashent]) != NULL)
+               uidhash[hashent]->pprev = &up->next;
+       up->pprev = &uidhash[hashent];
+       uidhash[hashent] = up;
+}
+
+static inline void uid_hash_remove(struct user_struct *up)
+{
+       if(up->next)
+               up->next->pprev = up->pprev;
+       *up->pprev = up->next;
+}
+
+static inline struct user_struct *uid_hash_find(unsigned short uid, unsigned int hashent)
+{
+       struct user_struct *up, *next;
+
+       next = uidhash[hashent];
+       for (;;) {
+               up = next;
+               if (next) {
+                       next = up->next;
+                       if (up->uid != uid)
+                               continue;
+                       atomic_inc(&up->__count);
+               }
+               break;
+       }
+       return up;
+}
+
+/*
+ * For SMP, we need to re-test the user struct counter
+ * after having aquired the spinlock. This allows us to do
+ * the common case (not freeing anything) without having
+ * any locking.
+ */
+#ifdef CONFIG_SMP
+  #define uid_hash_free(up)    (!atomic_read(&(up)->__count))
+#else
+  #define uid_hash_free(up)    (1)
+#endif
+
+void free_uid(struct user_struct *up)
+{
+       if (up) {
+               if (atomic_dec_and_test(&up->__count)) {
+                       spin_lock(&uidhash_lock);
+                       if (uid_hash_free(up)) {
+                               uid_hash_remove(up);
+                               kmem_cache_free(uid_cachep, up);
+                       }
+                       spin_unlock(&uidhash_lock);
+               }
+       }
+}
+
+struct user_struct * alloc_uid(uid_t uid)
+{
+       unsigned int hashent = uidhashfn(uid);
+       struct user_struct *up;
+
+       spin_lock(&uidhash_lock);
+       up = uid_hash_find(uid, hashent);
+       spin_unlock(&uidhash_lock);
+
+       if (!up) {
+               struct user_struct *new;
+
+               new = kmem_cache_alloc(uid_cachep, SLAB_KERNEL);
+               if (!new)
+                       return NULL;
+               new->uid = uid;
+               atomic_set(&new->__count, 1);
+               atomic_set(&new->processes, 0);
+               atomic_set(&new->files, 0);
+
+               /*
+                * Before adding this, check whether we raced
+                * on adding the same user already..
+                */
+               spin_lock(&uidhash_lock);
+               up = uid_hash_find(uid, hashent);
+               if (up) {
+                       kmem_cache_free(uid_cachep, new);
+               } else {
+                       uid_hash_insert(new, hashent);
+                       up = new;
+               }
+               spin_unlock(&uidhash_lock);
+
+       }
+       return up;
+}
+
+
+static int __init uid_cache_init(void)
+{
+       int i;
+
+       uid_cachep = kmem_cache_create("uid_cache", sizeof(struct user_struct),
+                                      0,
+                                      SLAB_HWCACHE_ALIGN, NULL, NULL);
+       if(!uid_cachep)
+               panic("Cannot create uid taskcount SLAB cache\n");
+
+       for(i = 0; i < UIDHASH_SZ; i++)
+               uidhash[i] = 0;
+
+       /* Insert the root user immediately - init already runs with this */
+       uid_hash_insert(&root_user, uidhashfn(0));
+       return 0;
+}
+
+module_init(uid_cache_init);
index 3826d636e58306ea52e8868db5ba9c189011695f..bbe9ec6fb14974d481aeb93c33e445106315d553 100644 (file)
--- a/mm/numa.c
+++ b/mm/numa.c
@@ -86,18 +86,24 @@ void __init free_area_init_node(int nid, pg_data_t *pgdat,
 struct page * alloc_pages(int gfp_mask, unsigned long order)
 {
        struct page *ret = 0;
-       unsigned long flags;
        int startnode, tnode;
+#ifndef CONFIG_NUMA
+       unsigned long flags;
        static int nextnid = 0;
+#endif
 
        if (order >= MAX_ORDER)
                return NULL;
+#ifdef CONFIG_NUMA
+       tnode = numa_node_id();
+#else
        spin_lock_irqsave(&node_lock, flags);
        tnode = nextnid;
        nextnid++;
        if (nextnid == numnodes)
                nextnid = 0;
        spin_unlock_irqrestore(&node_lock, flags);
+#endif
        startnode = tnode;
        while (tnode < numnodes) {
                if ((ret = alloc_pages_node(tnode++, gfp_mask, order)))
index cc40383858fc7f0e2f25ee9b0f146eb5b61ee7e4..33de64cc9847a8c50bc762e57c253c05a2fd4106 100644 (file)
@@ -44,7 +44,7 @@ static struct
       0, NULL, { } },
     {
            /* LOCAL_IN */
-           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
+           { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
                0,
                sizeof(struct ip6t_entry),
                sizeof(struct ip6t_standard),
@@ -52,7 +52,7 @@ static struct
              { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
                -NF_ACCEPT - 1 } },
            /* FORWARD */
-           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
+           { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
                0,
                sizeof(struct ip6t_entry),
                sizeof(struct ip6t_standard),
@@ -60,7 +60,7 @@ static struct
              { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
                -NF_ACCEPT - 1 } },
            /* LOCAL_OUT */
-           { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
+           { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
                0,
                sizeof(struct ip6t_entry),
                sizeof(struct ip6t_standard),
@@ -69,7 +69,7 @@ static struct
                -NF_ACCEPT - 1 } }
     },
     /* ERROR */
-    { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
+    { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
        0,
        sizeof(struct ip6t_entry),
        sizeof(struct ip6t_error),
index 1870a867c6ac0d5ce215877441eddb3bec7c457c..2993991dd4802647fb8c4eab3cbcce5faa7349de 100644 (file)
@@ -1667,7 +1667,7 @@ void __init sock_init(void)
 {
        int i;
 
-       printk(KERN_INFO "Linux NET4.0 for Linux 2.3\n");
+       printk(KERN_INFO "Linux NET4.0 for Linux 2.4\n");
        printk(KERN_INFO "Based upon Swansea University Computer Society NET3.039\n");
 
        /*