bk://linux-scsi.bkbits.net/scsi-misc-2.6
jejb@mulgrave.(none)|ChangeSet|20041206173801|38692 jejb

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/12/10 13:38:42-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/scsi_lib.c
#   2004/12/10 13:38:38-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/Kconfig
#   2004/12/10 13:38:38-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/12/06 11:38:01-06:00 jejb@mulgrave.(none) 
#   Rename SCSI ChangeLog to reflect its venarability
#   
#   The last time it was modified was 1997, so add the 
#   date range of applicability to its name.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# Documentation/scsi/ChangeLog.1992-1997
#   2004/12/06 11:36:04-06:00 jejb@mulgrave.(none) +0 -0
#   Rename: Documentation/scsi/ChangeLog -> Documentation/scsi/ChangeLog.1992-1997
# 
# ChangeSet
#   2004/12/01 01:00:27-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-scsi
# 
# include/linux/pci_ids.h
#   2004/12/01 01:00:22-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/11/27 13:45:31-08:00 akpm@bix.(none) 
#   Merge bk://linux-scsi.bkbits.net/scsi-misc-2.6
#   into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/hosts.c
#   2004/11/27 13:45:26-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/11/26 11:50:43-06:00 bunk@stusta.de 
#   [PATCH] remove bouncing email address of Deanna Bonds
#   
#   The patch below (applies against both 2.4 and 2.6) removes the bouncing
#   email address of Deanna Bonds (I didn't find a nmore recent address).
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/dpti.h
#   2004/11/24 12:23:56-06:00 bunk@stusta.de +0 -1
#   remove bouncing email address of Deanna Bonds
# 
# drivers/scsi/dpt_i2o.c
#   2004/11/24 12:24:37-06:00 bunk@stusta.de +0 -1
#   remove bouncing email address of Deanna Bonds
# 
# drivers/scsi/dpt/dpti_ioctl.h
#   2004/11/24 12:24:27-06:00 bunk@stusta.de +0 -1
#   remove bouncing email address of Deanna Bonds
# 
# drivers/scsi/aacraid/README
#   2004/11/24 12:24:16-06:00 bunk@stusta.de +1 -1
#   remove bouncing email address of Deanna Bonds
# 
# ChangeSet
#   2004/11/26 11:47:06-06:00 bunk@stusta.de 
#   [PATCH] SCSI aic7xxx_old.c: make a function static
#   
#   The patch below makes the needlessly global function aic7xxx_info 
#   static.
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/aic7xxx_old/aic7xxx_proc.c
#   2004/11/13 10:16:45-06:00 bunk@stusta.de +1 -1
#   SCSI aic7xxx_old.c: make a function static
# 
# drivers/scsi/aic7xxx_old.c
#   2004/11/13 10:16:12-06:00 bunk@stusta.de +1 -1
#   SCSI aic7xxx_old.c: make a function static
# 
# ChangeSet
#   2004/11/26 11:45:27-06:00 jejb@mulgrave.(none) 
#   LSI Logic - SAS and FC PCI ID's
#   
#   From: 	Moore, Eric Dean <Eric.Moore@lsil.com>
#   
#   Here are new PCI ID's for SAS and Fibre Channel
#   LSI Logic controllers.
#   
#   Signed-off-by: Eric Moore <Eric.Moore@lsil.com>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/linux/pci_ids.h
#   2004/11/26 11:44:15-06:00 jejb@mulgrave.(none) +10 -0
#   LSI Logic - SAS and FC PCI ID's
# 
# ChangeSet
#   2004/11/26 11:33:06-06:00 jejb@mulgrave.(none) 
#   fixup dynamic scan aids EXPORT_SYMBOL mismerge
#   
#   OK, so I exported the wrong symbols ...
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/scsi_scan.c
#   2004/11/26 11:31:38-06:00 jejb@mulgrave.(none) +2 -1
#   fixup dynamic scan aids EXPORT_SYMBOL mismerge
# 
# ChangeSet
#   2004/11/26 10:16:03-06:00 jejb@mulgrave.(none) 
#   scsi: 	LLDD dynamic scan aids
#   
#   From: 	James.Smart@Emulex.Com
#   
#   With rejection fixes around the removal of scsi_syms.c
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/scsi/scsi_host.h
#   2004/11/26 10:15:26-06:00 jejb@mulgrave.(none) +3 -0
#   scsi: 	LLDD dynamic scan aids
# 
# drivers/scsi/scsi_scan.c
#   2004/11/26 10:15:26-06:00 jejb@mulgrave.(none) +13 -0
#   scsi: 	LLDD dynamic scan aids
# 
# ChangeSet
#   2004/11/26 10:10:46-06:00 axboe@suse.de 
#   [PATCH] kill locking around scsi_done()
#   
#   Lets show the mid layer as a good example and remove the host lock
#   around the scsi_done() call.
#   
#   Signed-off-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
#   
#   ===== drivers/scsi/scsi.c 1.148 vs edited =====
# 
# drivers/scsi/scsi.c
#   2004/11/20 16:25:38-06:00 axboe@suse.de +0 -2
#   kill locking around scsi_done()
# 
# ChangeSet
#   2004/11/26 10:07:03-06:00 bunk@stusta.de 
#   [PATCH] kill scsi_syms.c
#   
#   The patch below removes scsi_syms.c and moves the EXPORT_SYMBOL's to the
#   files where the actual functions are.
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/scsicam.c
#   2004/11/20 14:31:54-06:00 bunk@stusta.de +3 -0
#   kill scsi_syms.c
# 
# drivers/scsi/scsi_sysfs.c
#   2004/11/20 14:44:12-06:00 bunk@stusta.de +3 -0
#   kill scsi_syms.c
# 
# drivers/scsi/scsi_scan.c
#   2004/11/20 14:43:37-06:00 bunk@stusta.de +5 -0
#   kill scsi_syms.c
# 
# drivers/scsi/scsi_lib.c
#   2004/11/20 14:46:26-06:00 bunk@stusta.de +9 -1
#   kill scsi_syms.c
# 
# drivers/scsi/scsi_ioctl.c
#   2004/11/20 14:36:32-06:00 bunk@stusta.de +3 -0
#   kill scsi_syms.c
# 
# drivers/scsi/scsi_error.c
#   2004/11/20 14:46:48-06:00 bunk@stusta.de +6 -0
#   kill scsi_syms.c
# 
# drivers/scsi/scsi.c
#   2004/11/20 14:46:12-06:00 bunk@stusta.de +11 -0
#   kill scsi_syms.c
# 
# drivers/scsi/hosts.c
#   2004/11/20 14:30:51-06:00 bunk@stusta.de +8 -0
#   kill scsi_syms.c
# 
# drivers/scsi/constants.c
#   2004/11/20 14:35:16-06:00 bunk@stusta.de +9 -0
#   kill scsi_syms.c
# 
# drivers/scsi/Makefile
#   2004/11/20 14:26:17-06:00 bunk@stusta.de +1 -1
#   kill scsi_syms.c
# 
# Documentation/scsi/scsi_mid_low_api.txt
#   2004/11/20 14:25:56-06:00 bunk@stusta.de +2 -2
#   kill scsi_syms.c
# 
# BitKeeper/deleted/.del-scsi_syms.c~8c75b2d48ed73d87
#   2004/11/26 10:06:12-06:00 bunk@stusta.de +0 -0
#   Delete: drivers/scsi/scsi_syms.c
# 
# ChangeSet
#   2004/11/26 00:46:18-08:00 akpm@bix.(none) 
#   Merge bk://linux-scsi.bkbits.net/scsi-misc-2.6
#   into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/hosts.c
#   2004/11/26 00:46:13-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/Kconfig
#   2004/11/26 00:46:13-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/11/25 12:07:52-06:00 jejb@mulgrave.(none) 
#   convert eata to pass pointers around
#   
#   From: 	Christoph Hellwig <hch@lst.de>
#   
#   pass pointers to Scsi_Host and the private data around instead of using
#   indices into global arrays all over the place.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/eata.c
#   2004/11/25 12:05:43-06:00 jejb@mulgrave.(none) +291 -298
#   convert eata to pass pointers around
# 
# ChangeSet
#   2004/11/25 11:54:54-06:00 hch@lst.de 
#   [PATCH] feed eata.c through Lindent
#   
#   the driver oopses on load for me currently, but to debug it I need to
#   actually be able to read the source..
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/eata.c
#   2004/11/02 07:28:36-06:00 hch@lst.de +1770 -1568
#   feed eata.c through Lindent
# 
# ChangeSet
#   2004/11/25 11:08:32-06:00 jejb@mulgrave.(none) 
#   Merge ssh://linux-scsi@linux-scsi.bkbits.net/scsi-misc-2.6
#   into mulgrave.(none):/home/jejb/BK/scsi-misc-2.6
# 
# drivers/scsi/hosts.c
#   2004/11/25 11:08:25-06:00 jejb@mulgrave.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/Kconfig
#   2004/11/25 11:08:25-06:00 jejb@mulgrave.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/11/19 20:11:31-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/megaraid/megaraid_mbox.h
#   2004/11/19 20:11:27-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/megaraid/megaraid_mbox.c
#   2004/11/19 20:11:27-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/hosts.c
#   2004/11/19 20:11:26-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/Kconfig
#   2004/11/19 20:11:26-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/scsi/ChangeLog.megaraid
#   2004/11/19 20:11:26-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/11/17 10:34:09-06:00 akpm@osdl.org 
#   [PATCH] iscsi_transport build fix
#   
#   drivers/scsi/scsi_transport_iscsi.c:176: structure has no member named `sin6_addr'
#   
#   Older gcc's dont support anonymous unions.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/scsi/scsi_transport_iscsi.h
#   2004/11/17 03:55:50-06:00 akpm@osdl.org +3 -3
#   iscsi_transport build fix
# 
# ChangeSet
#   2004/11/16 16:05:58-06:00 jejb@mulgrave.(none) 
#   SCSI: Add missing state transition BLOCK->OFFLINE
#   
#   From: 	James.Smart@Emulex.Com
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/scsi_lib.c
#   2004/11/16 16:05:38-06:00 jejb@mulgrave.(none) +1 -0
#   SCSI: Add missing state transition BLOCK->OFFLINE
# 
# ChangeSet
#   2004/11/16 16:01:31-06:00 dougg@torque.net 
#   SCSI: descriptor sense format, mid-level
#   
#      - generalize sense data logic to cope with both fixed and
#        descriptor format
#      - use KERN_INFO on most printk()s to limit console noise
#      - retire mid-level usage of sense_class(), sense_error() and
#        sense_valid() macros which are SCSI-1 remnants. Now only
#        cpqfcTSinit.c seems to use them
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/scsi_scan.c
#   2004/11/08 02:33:25-06:00 dougg@torque.net +21 -12
#   descriptor sense format, mid-level
# 
# drivers/scsi/scsi_lib.c
#   2004/11/08 01:14:41-06:00 dougg@torque.net +16 -12
#   descriptor sense format, mid-level
# 
# drivers/scsi/scsi_ioctl.c
#   2004/11/08 04:56:44-06:00 dougg@torque.net +18 -12
#   descriptor sense format, mid-level
# 
# drivers/scsi/scsi_error.c
#   2004/11/08 00:43:52-06:00 dougg@torque.net +35 -12
#   descriptor sense format, mid-level
# 
# ChangeSet
#   2004/11/16 15:23:21-06:00 michaelc@cs.wisc.edu 
#   [PATCH] iSCSI transport class
#   
#   The attached patch adds an iSCSI transport class. It was
#   built against scsi-misc-2.6. It allows the software/virtual
#   iSCSI driver to remove at least one of its ioctl commands.
#   The patch also assumes the no multipath/failover rule in
#   llds applies to iSCSI drivers, so when we remove our
#   portal/portal_group failover support it will allow us to
#   kill all our ioctl commands execpt the session creation one
#   (that will take more thought).
#   
#   We would like to build some functions like the
#   unblock/block capabilites into the iscsi transport class
#   like James Smart has done with FC class. but initially we
#   would like to begin with this smaller patch that only provides
#   an iscsi sysfs interface.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/scsi/scsi_transport_iscsi.h
#   2004/10/29 05:55:13-05:00 michaelc@cs.wisc.edu +178 -0
#   iSCSI transport class
# 
# include/scsi/scsi_transport_iscsi.h
#   2004/10/29 05:55:13-05:00 michaelc@cs.wisc.edu +0 -0
#   BitKeeper file /home/jejb/BK/scsi-misc-2.6/include/scsi/scsi_transport_iscsi.h
# 
# drivers/scsi/scsi_transport_iscsi.c
#   2004/10/29 06:30:20-05:00 michaelc@cs.wisc.edu +355 -0
#   iSCSI transport class
# 
# drivers/scsi/Makefile
#   2004/10/28 22:57:11-05:00 michaelc@cs.wisc.edu +1 -1
#   iSCSI transport class
# 
# drivers/scsi/Kconfig
#   2004/10/28 22:57:11-05:00 michaelc@cs.wisc.edu +8 -0
#   iSCSI transport class
# 
# drivers/scsi/scsi_transport_iscsi.c
#   2004/10/29 06:30:20-05:00 michaelc@cs.wisc.edu +0 -0
#   BitKeeper file /home/jejb/BK/scsi-misc-2.6/drivers/scsi/scsi_transport_iscsi.c
# 
# ChangeSet
#   2004/11/16 13:49:34-06:00 jejb@mulgrave.(none) 
#   SCSI: Add transport destructors
#   
#   From: 	James.Smart@Emulex.Com
#   
#   This patch adds host/target/sdev destructor functions to the transport
#   template. The FC transport is updated to utilize them to cancel any
#   outstanding timer. It slightly rearranges the slave_xxx functions so
#   the transport is always involved prior to the LLDD.
#   
#   Minor rejection fixes and
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/scsi/scsi_transport.h
#   2004/11/16 13:48:01-06:00 jejb@mulgrave.(none) +5 -0
#   SCSI: Add transport destructors
# 
# drivers/scsi/scsi_transport_fc.c
#   2004/11/16 13:48:01-06:00 jejb@mulgrave.(none) +16 -0
#   SCSI: Add transport destructors
# 
# drivers/scsi/scsi_sysfs.c
#   2004/11/16 13:48:01-06:00 jejb@mulgrave.(none) +5 -0
#   SCSI: Add transport destructors
# 
# drivers/scsi/scsi_scan.c
#   2004/11/16 13:48:01-06:00 jejb@mulgrave.(none) +13 -6
#   SCSI: Add transport destructors
# 
# drivers/scsi/hosts.c
#   2004/11/16 13:48:01-06:00 jejb@mulgrave.(none) +6 -1
#   SCSI: Add transport destructors
# 
# ChangeSet
#   2004/11/16 13:42:53-06:00 jejb@mulgrave.(none) 
#   SCSI: updates to constants.c
#   
#   From: 	Douglas Gilbert <dougg@torque.net>
#   
#     - bring opcode names, asc/ascq strings and sense format
#       into line with SPC-3 rev 21 (22 September 2004)
#     - drop SCSI-1 sense buffer decoding [still output it in hex]
#     - opcode names include those that depend on service actions
#       including variable length commands **
#     - decodes both fixed and descriptor sense data formats
#     - use KERN_INFO on printk()s that start on new lines
#     - flag vendor specific asc and acsq codes
#     - print all bytes of a cdb after the name (previously skipped
#       the first byte)
#     - cleanup file, tab to 8 spaces
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/constants.c
#   2004/11/16 13:41:26-06:00 jejb@mulgrave.(none) +578 -339
#   SCSI: updates to constants.c
# 
# ChangeSet
#   2004/11/16 13:29:04-06:00 jejb@mulgrave.(none) 
#   update the fc_transport_class to use a workqueue instead of a timeout
#   
#   The amount of work that has to be done in the timeout routines is really
#   a bit much if there's a large number of LUNS.  Plus the
#   device_for_each_child needs user context to get the bus semaphore, so
#   the solution is to migrate them from a timer to delayed work.
#   
#   There's still a race here in that the timer may still be ticking when
#   the device is destroyed ... To fix this, I think we may need to
#   introduce a destroy callback to the transport class.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/scsi/scsi_transport_fc.h
#   2004/11/16 13:26:54-06:00 jejb@mulgrave.(none) +6 -6
#   update the fc_transport_class to use a workqueue instead of a timeout
# 
# drivers/scsi/scsi_transport_fc.c
#   2004/11/16 13:26:54-06:00 jejb@mulgrave.(none) +17 -17
#   update the fc_transport_class to use a workqueue instead of a timeout
# 
# ChangeSet
#   2004/11/14 21:35:57-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/qla1280.c
#   2004/11/14 21:35:54-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/11/11 15:07:32-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/qla1280.c
#   2004/11/11 15:07:28-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/10/24 22:09:45-07:00 akpm@bix.(none) 
#   Merge bk://linux-scsi.bkbits.net/scsi-misc-2.6
#   into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/megaraid/megaraid_mbox.c
#   2004/10/24 22:09:40-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/10/24 16:48:01-05:00 jejb@mulgrave.(none) 
#   scsi_debug v 1.75
#   
#   From: 	Douglas Gilbert <dougg@torque.net>
#   
#       - fix highmem data transfers
#            - fix kunmap_atomic() argument
#            - disable clustering
#       - allow every_nth < 0 for error continuously once
#         count is reached
#       - minor sense buffer handling cleanup
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/scsi_debug.c
#   2004/10/24 16:47:49-05:00 jejb@mulgrave.(none) +265 -214
#   scsi_debug v 1.75
# 
# ChangeSet
#   2004/10/21 00:22:42-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/megaraid/megaraid_mbox.h
#   2004/10/21 00:22:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/megaraid/megaraid_mbox.c
#   2004/10/21 00:22:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/10/19 22:12:26-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/megaraid/megaraid_mbox.c
#   2004/10/19 22:12:23-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/10/15 22:40:42-07:00 akpm@bix.(none) 
#   Merge bk://linux-scsi.bkbits.net/scsi-misc-2.6
#   into bix.(none):/usr/src/bk-scsi
# 
# drivers/scsi/megaraid/megaraid_mbox.h
#   2004/10/15 22:40:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/megaraid/megaraid_mbox.c
#   2004/10/15 22:40:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# Documentation/scsi/ChangeLog.megaraid
#   2004/10/15 22:40:38-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/10/13 13:38:51-07:00 akpm@bix.(none) 
#   foo
# 
# Documentation/scsi/ChangeLog.megaraid
#   2004/10/13 13:38:44-07:00 akpm@bix.(none) +0 -8
#   foo
# 
# drivers/scsi/megaraid/megaraid_mbox.h
#   2004/10/13 13:32:32-07:00 akpm@bix.(none) +0 -2
#   Auto merged
# 
# drivers/scsi/megaraid/megaraid_mbox.c
#   2004/10/13 13:32:32-07:00 akpm@bix.(none) +0 -3
#   Auto merged
# 
diff -Nru a/Documentation/scsi/ChangeLog b/Documentation/scsi/ChangeLog
--- a/Documentation/scsi/ChangeLog	2004-12-12 18:04:46 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,2023 +0,0 @@
-Sat Jan 18 15:51:45 1997  Richard Henderson  <rth@tamu.edu>
-
-	* Don't play with usage_count directly, instead hand around
-	the module header and use the module macros.
-
-Fri May 17 00:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 2.0.3 Released.
-
-Tue Apr 16 21:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 1.3.2 Released.
-
-Sun Dec 31 23:26:00 1995  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* BusLogic Driver Version 1.3.1 Released.
-
-Fri Nov 10 15:29:49 1995  Leonard N. Zubkoff <lnz@dandelion.com>
-
-	* Released new BusLogic driver.
-
-Wed Aug  9 22:37:04 1995  Andries Brouwer  <aeb@cwi.nl>
-
-	As a preparation for new device code, separated the various
-	functions the request->dev field had into the device proper,
-	request->rq_dev and a status field request->rq_status.
-
-	The 2nd argument of bios_param is now a kdev_t.
-
-Wed Jul 19 10:43:15 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-        * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all
-	attached devices.
-
-	* scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and
-	eata_dma_proc.c to produce some device info for /proc/scsi.
-
-	* eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done):
-	Changed handling of internal SCSI commands send to the HBA.
-
-
-Wed Jul 19 10:09:17 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.11 released.
-
-	* eata_dma.c (eata_queue)(eata_int_handler): Added code to do
-	command latency measurements if requested by root through
-	/proc/scsi interface.
-	Throughout Use HZ constant for time references.
-
-	* eata_pio.c: Use HZ constant for time references.
-
-	* aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD
-	to GNU style.
-
-	* scsi.h: Added READ_12 command opcode constant
-
-Wed Jul 19 09:25:30 1995  Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.10 released.
-
-	* scsi_proc.c (dispatch_scsi_info): Removed unused variable.
-
-Wed Jul 19 09:25:30 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.9 released.
-
-	* scsi.c Blacklist concept expanded to 'support' more device
-	deficiencies. blacklist[] renamed to device_list[]
-	(scan_scsis): Code cleanup.
-
-	* scsi_debug.c (scsi_debug_proc_info): Added support to control
-	device lockup simulation via /proc/scsi interface.
-
-
-Wed Jul 19 09:22:34 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.7 released.
-
-	* scsi_proc.c: Fixed a number of bugs in directory handling
-
-Wed Jul 19 09:18:28 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.5 released.
-
-	* Native wide, multichannel and /proc/scsi support now in official
-	kernel distribution.
-
-        * scsi.c/h, hosts.c/h et al reindented to increase readability
-	(especially on 80 column wide terminals).
-
-	* scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added
-	/proc/scsi/scsi which allows root to scan for hotplugged devices.
-
-	* scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi.
-	(scan_scsis): Added some 'spaghetti' code to allow scanning for
-	single devices.
-	
-
-Thu Jun 20 15:20:27 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-        * proc.c: Renamed to scsi_proc.c
-
-Mon Jun 12 20:32:45 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* Linux 1.3.0 released.
-
-Mon May 15 19:33:14 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* scsi.c: Added native multichannel and wide scsi support.
-
-	* proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries):
-	Updated /proc/scsi interface.
-
-Thu May  4 17:58:48 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
-
-	* sd.c (requeue_sd_request): Zero out the scatterlist only if
-	scsi_malloc returned memory for it.
-
-	* eata_dma.c (register_HBA) (eata_queue): Add support for
-	large scatter/gather tables and set use_clustering accordingly
-
-	* hosts.c: Make use_clustering changeable in the Scsi_Host structure.
-
-Wed Apr 12 15:25:52 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.5 released.
-
-	* buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff).
-	Fixed interrupt routine to avoid races when handling multiple
-	complete commands per interrupt.  Seems to come up with faster
-	cards.
-
-	* eata_dma.c: Update to 2.3.5r. Modularize. Improved error handling
-        throughout and fixed bug interrupt routine which resulted in shifted
-        status bytes. Added blink LED state checks for ISA and EISA HBAs.
-        Memory management bug seems to have disappeared ==> increasing
-        C_P_L_CURRENT_MAX to 16 for now. Decreasing C_P_L_DIV to 3 for
-        performance reasons.
-
-	* scsi.c: If we get a FMK, EOM, or ILI when attempting to scan
-	the bus, assume that it was just noise on the bus, and ignore
-	the device.
-
-	* scsi.h: Update and add a bunch of missing commands which we
-	were never using.
-
-	* sd.c: Use restore_flags in do_sd_request - this may result in
-	latency conditions, but it gets rid of races and crashes.
-	Do not save flags again when searching for a second command to
-	queue.
-
-	* st.c: Use bytes, not STP->buffer->buffer_size when reading
-	from tape.
-
-
-Tue Apr  4 09:42:08 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.4 released.
-
-	* st.c: Fix typo - restoring wrong flags.
-
-Wed Mar 29 06:55:12 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.3 released.
-
-	* st.c: Perform some waiting operations with interrupts off.
-	Is this correct???
-
-Wed Mar 22 10:34:26 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.2 released.
-
-	* aha152x.c: Modularize.  Add support for PCMCIA.
-
-	* eata.c: Update to version 2.0.  Fixed bug preventing media
-	detection.  If scsi_register_host returns NULL, fail gracefully.
-
-	* scsi.c: Detect as NEC (for photo-cd purposes) for the 84
-	and 25 models as "NEC_OLDCDR".
-
-	* scsi.h: Add define for NEC_OLDCDR
-
-	* sr.c: Add handling for NEC_OLDCDR.  Treat as unknown.
-
-	* u14-34f.c: Update to version 2.0.  Fixed same bug as in
-	eata.c.
-
-
-Mon Mar  6 11:11:20 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.2.0 released.  Yeah!!!
-
-	* Minor spelling/punctuation changes throughout.  Nothing
-	substantive.
-
-Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.95 released.
-
-	* qlogic.c: Update to version 0.41.
-
-	* seagate.c: Change some message to be more descriptive about what
-	we detected.
-
-	* sr.c: spelling/whitespace changes.
-
-Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.94 released.
-
-Mon Feb 20 08:57:17 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.93 released.
-
-	* hosts.h: Change io_port to long int from short.
-
- 	* 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP,
- 	  NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output
- 	  fixed, should initialize correctly if left running, now loadable,
-  	  new memory allocation, extraneous diagnostic output suppressed,
- 	  splx() replaced with save/restore flags. [ Drew ]
-
-	* hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c,
-	sr_ioctl.c: Add special junk at end that Emacs will use for
-	formatting the file.
-
-	* qlogic.c: Update to v0.40a.  Improve parity handling.
-
-	* scsi.c: Add Hitachi DK312C to blacklist.  Change "};" to "}" in
-	many places.  Use scsi_init_malloc to get command block - may
-	need this to be dma compatible for some host adapters.
-	Restore interrupts after unregistering a host.
-
-	* sd.c: Use sti instead of restore flags - causes latency problems.
-
-	* seagate.c: Use controller_type to determine string used when
-	registering irq.
-
-	* sr.c: More photo-cd hacks to make sure we get the xa stuff right.
-	* sr.h, sr.c: Change is_xa to xa_flags field.
-
-	* st.c: Disable retries for write operations.
-
-Wed Feb 15 10:52:56 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.92 released.
-
-	* eata.c: Update to 1.17.
-
-	* eata_dma.c: Update to 2.31a. Add more support for /proc/scsi.
-        Continuing modularization. Less crashes because of the bug in the
-        memory management ==> increase C_P_L_CURRENT_MAX to 10
-        and decrease C_P_L_DIV to 4.
-
-	* hosts.c: If we remove last host registered, reuse host number.
-	When freeing memory from host being deregistered, free extra_bytes
-	too.
-
-	* scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt.
-	Change memory allocation to work around bugs in __get_dma_pages.
-	Do not free host if usage count is not zero (for modules).
-
-	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000.
-
-	* st.c: Allow for ST_EXTRA_DEVS in st data structures.
-
-	* u14-34f.c: Update to 1.17.
-
-Thu Feb  9 10:11:16 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.91 released.
-
-	* eata.c: Update to 1.16.  Use wish_block instead of host->block.
-
-	* hosts.c: Initialize wish_block to 0.
-
-	* hosts.h: Add wish_block.
-
-	* scsi.c: Use wish_block as indicator that the host should be added
-	to block list.
-
-	* sg.c: Add SG_EXTRA_DEVS to number of slots.
-
-	* u14-34f.c: Use wish_block.
-
-Tue Feb  7 11:46:04 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.90 released.
-
-	* eata.c: Change naming from eata_* to eata2x_*.  Now at vers 1.15.
-	Update interrupt handler to take pt_regs as arg.  Allow blocking
-	even if loaded as module.  Initialize target_time_out array.
-	Do not put sti(); in timing loop.
-
-	* hosts.c: Do not reuse host numbers.
-	Use scsi_make_blocked_list to generate blocking list.
-
-	* script_asm.pl:  Beats me.  Don't know perl.  Something to do with
-	phase index.
-
-	* scsi.c (scsi_make_blocked_list): New function - code copied from
-	hosts.c.
-
-	* scsi.c: Update code to disable photo CD for Toshiba cdroms.
-	Use just manufacturer name, not model number.
-
-	* sr.c: Fix setting density for Toshiba drives.
-
-	* u14-34f.c: Clear target_time_out array during reset.
-
-Wed Feb  1 09:20:45 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.89 released.
-
-	* Makefile, u14-34f.c: Modularize.
-
-	* Makefile, eata.c: Modularize.  Now version 1.14
-
-	* NCR5380.c: Update interrupt handler with new arglist.  Minor
-	cleanups.
-
-	* eata_dma.c: Begin to modularize.  Add hooks for /proc/scsi.
-	New version 2.3.0a. Add code in interrupt handler to allow
-        certain CDROM drivers to be detected which return a
-        CHECK_CONDITION during SCSI bus scan. Add opcode check to get
-        all DATA IN and DATA OUT phases right. Utilize HBA_interpret flag.
-	Improvements in HBA identification. Various other minor stuff.
-
-	* hosts.c: Initialize ->dma_channel and ->io_port when registering
-	a new host.
-
-	* qlogic.c: Modularize and add PCMCIA support.
-
-	* scsi.c: Add Hitachi to blacklist.
-
-	* scsi.c: Change default to no lun scan (too many problem devices).
-
-	* scsi.h: Define QUEUE_FULL condition.
-
-	* sd.c: Do not check for non-existent partition until after
-	new media check.
-
-	* sg.c: Undo previous change which was wrong.
-
-	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000.
-
-	* st.c: Patches from Kai - improve filemark handling.
-
-Tue Jan 31 17:32:12 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.88 released.
-
-	* Throughout - spelling/grammar fixups.
-
-	* scsi.c: Make sure that all buffers are 16 byte aligned - some
-	drivers (buslogic) need this.
-
-	* scsi.c (scan_scsis): Remove message printed.
-
-	* scsi.c (scsi_init): Move message here.
-
-Mon Jan 30 06:40:25 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.87 released.
-
-	* sr.c: Photo-cd related changes. (Gerd Knorr??).
-
-	* st.c: Changes from Kai related to EOM detection.
-
-Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.86 released.
-
-	* 53c7,8xx.h: Change SG size to 127.
-
-	* eata_dma: Update to version 2.10i. Remove bug in the registration
-        of multiple HBAs and channels. Minor other improvements and stylistic
-        changes.
-
-	* scsi.c: Test for Toshiba XM-3401TA and exclude from detection
-	as toshiba drive - photo cd does not work with this drive.
-
-	* sr.c:  Update photocd code.
-
-Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.85 released.
-
-	* st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c:
-	include linux/mm.h
-
-	* qlogic.c, buslogic.c, aha1542.c: Include linux/module.h.
-
-Sun Jan 22 22:08:46 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.84 released.
-
-	* Makefile: Support for loadable QLOGIC boards.
-
-	* aha152x.c: Update to version 1.8 from Juergen.
-
-	* eata_dma.c: Update from Michael Neuffer.
-        Remove hard limit of 2 commands per lun and make it better
-        configurable. Improvements in HBA identification.
-
-	* in2000.c: Fix biosparam to support large disks.
-
-	* qlogic.c: Minor changes (change sti -> restore_flags).
-
-Wed Jan 18 23:33:09 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.83 released.
-
-	* aha1542.c(aha1542_intr_handle): Use arguments handed down to find
-	which irq.
-
-	* buslogic.c: Likewise.
-
-	* eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards.
-
-	* scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK.
-
-	* sd.c: Fail if we are opening a non-existent partition.
-
-	* sr.c: Bump SR_TIMEOUT to 15000.
-	Do not probe for media size at boot time(hard on changers).
-	Flag device as needing sector size instead.
-
-	* sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl.
-
-	* ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args).
-
-Mon Jan 16 07:18:23 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.82 released.
-
-	Throughout.
-	- Change all interrupt handlers to accept new calling convention.
-	In particular, we now receive the irq number as one of the arguments.
-
-	* More minor spelling corrections in some of the new files.
-
-	* aha1542.c, buslogic.c: Clean up interrupt handler a little now
-	that we receive the irq as an arg.
-
-	* aha274x.c: s/snarf_region/request_region/
-
-	* eata.c: Update to version 1.12.   Fix some comments and display a
-	message if we cannot reserve the port addresses.
-
-	* u14-34f.c: Update to version 1.13.   Fix some comments and display a
-	message if we cannot reserve the port addresses.
-
-	* eata_dma.c: Define get_board_data function (send INQUIRY command).
-	Use to improve detection of variants of different DPT boards.  Change
-	version subnumber to "0g".
-
-	* fdomain.c:  Update to version 5.26.  Improve detection of some boards
-	repackaged by IBM.
-
-	* scsi.c (scsi_register_host): Change "name" to const char *.
-
-	* sr.c: Fix problem in set mode command for Toshiba drives.
-
-	* sr.c: Fix typo from patch 81.
-
-Fri Jan 13 12:54:46 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.81 released.  Codefreeze for 1.2 release announced.
-
-	Big changes here.
-
-	* eata_dma.*: New files from Michael Neuffer.
-	(neuffer@goofy.zdv.uni-mainz.de).  Should support
-	all eata/dpt cards.
-
-	* hosts.c, Makefile: Add eata_dma.
-
-	* README.st: Document MTEOM.
-
-	Patches from me (ERY) to finish support for low-level loadable scsi.
-	It now works, and is actually useful.
-
-	* Throughout - add new argument to scsi_init_malloc that takes an
-	additional parameter.  This is used as a priority to kmalloc,
-	and you can specify the GFP_DMA flag if you need DMA-able memory.
-
-	* Makefile: For source files that are loadable, always add name
-	to SCSI_SRCS.  Fill in modules: target.
-
-	* hosts.c:  Change next_host to next_scsi_host, and make global.
-	Print hosts after we have identified all of them.  Use info()
-	function if present, otherwise use name field.
-
-	* hosts.h: Change attach function to return int, not void.
-	Define number of device slots to allow for loadable devices.
-	Define tags to tell scsi module code what type of module we
-	are loading.
-
-	* scsi.c: Fix scan_scsis so that it can be run by a user process.
-	Do not use waiting loops - use up and down mechanism as long
-	as current != task[0].
-
-	* scsi.c(scan_scsis): Do not use stack variables for I/O - this
-	could be > 16Mb if we are loading a module at runtime (i.e. use
-	scsi_init_malloc to get some memory we know will be safe).
-
-	* scsi.c: Change dma freelist to be a set of pages.  This allows
-	us to dynamically adjust the size of the list by adding more pages
-	to the pagelist.  Fix scsi_malloc and scsi_free accordingly.
-
-	* scsi_module.c: Fix include.
-
-	* sd.c: Declare detach function.  Increment/decrement module usage
-	count as required.  Fix init functions to allow loaded devices.
-	Revalidate all new disks so we get the partition tables.  Define
-	detach function.
-
-	* sr.c: Likewise.
-
-	* sg.c: Declare detach function.  Allow attachment of devices on
-	loaded drivers.
-
-	* st.c: Declare detach function.  Increment/decrement module usage
-	count as required.
-
-Tue Jan 10 10:09:58 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.79 released.
-
-	Patch from some undetermined individual who needs to get a life :-).
-
-	* sr.c: Attacked by spelling bee...
-
-	Patches from Gerd Knorr:
-
-	* sr.c: make printk messages for photoCD a little more informative.
-
-	* sr_ioctl.c: Fix CDROMMULTISESSION_SYS ioctl.
-
-Mon Jan  9 10:01:37 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.78 released.
-
-	* Makefile: Add empty modules: target.
-
-	* Wheee.  Now change register_iomem to request_region.
-
-	* in2000.c: Bugfix - apparently this is the fix that we have
-	all been waiting for.  It fixes a problem whereby the driver
-	is not stable under heavy load.  Race condition and all that.
-	Patch from Peter Lu.
-
-Wed Jan  4 21:17:40 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.77 released.
-
-	* 53c7,8xx.c: Fix from Linus - emulate splx.
-
-	Throughout:
-
-		Change "snarf_region" with "register_iomem".
-
-	* scsi_module.c: New file.  Contains support for low-level loadable
-	  scsi drivers. [ERY].
-
-	* sd.c: More s/int/long/ changes.
-
-	* seagate.c: Explicitly include linux/config.h
-
-	* sg.c: Increment/decrement module usage count on open/close.
-
-	* sg.c: Be a bit more careful about the user not supplying enough
-	  information for a valid command.  Pass correct size down to
-	  scsi_do_cmd.
-
-	* sr.c:  More changes for Photo-CD.  This apparently breaks NEC drives.
-
-	* sr_ioctl.c:  Support CDROMMULTISESSION ioctl.
-
-
-Sun Jan  1 19:55:21 1995  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.76 released.
-
-	* constants.c: Add type cast in switch statement.
-
-	* scsi.c (scsi_free): Change datatype of "offset" to long.
-	  (scsi_malloc): Change a few more variables to long.  Who
-	  did this and why was it important?  64 bit machines?
-
-
-	Lots of changes to use save_state/restore_state instead of cli/sti.
-	Files changed include:
-
-	* aha1542.c:
-	* aha1740.c:
-	* buslogic.c:
-	* in2000.c:
-	* scsi.c:
-	* scsi_debug.c:
-	* sd.c:
-	* sr.c:
-	* st.c:
-
-Wed Dec 28 16:38:29 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.75 released.
-
-	* buslogic.c: Spelling fix.
-
-	* scsi.c: Add HP C1790A and C2500A scanjet to blacklist.
-
-	* scsi.c: Spelling fixup.
-
-	* sd.c: Add support for sd_hardsizes (hard sector sizes).
-
-	* ultrastor.c: Use save_flags/restore_flags instead of cli/sti.
-
-Fri Dec 23 13:36:25 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.74 released.
-
-	* README.st: Update from Kai Makisara.
-
-	* eata.c: New version from Dario - version 1.11.
-	  use scsicam bios_param routine.  Add support for 2011
-	  and 2021 boards.
-
-	* hosts.c: Add support for blocking.  Linked list automatically
-	  generated when shpnt->block is set.
-
-	* scsi.c: Add sankyo & HP scanjet to blacklist.  Add support for
-	  kicking things loose when we deadlock.
-
-	* scsi.c: Recognize scanners and processors in scan_scsis.
-
-	* scsi_ioctl.h: Increase timeout to 9 seconds.
-
-	* st.c: New version from Kai - add better support for backspace.
-
-	* u14-34f.c: New version from Dario.  Supports blocking.
-
-Wed Dec 14 14:46:30 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.73 released.
-
-	* buslogic.c: Update from Dave Gentzel.  Version 1.14.
-	  Add module related stuff.   More fault tolerant if out of
-	  DMA memory.
-
-	* fdomain.c: New version from Rik Faith - version 5.22.  Add support
-	  for ISA-200S SCSI adapter.
-
-	* hosts.c: Spelling.
-
-	* qlogic.c: Update to version 0.38a.  Add more support for PCMCIA.
-
-	* scsi.c: Mask device type with 0x1f during scan_scsis.
-	  Add support for deadlocking, err, make that getting out of
-	  deadlock situations that are created when we allow the user
-	  to limit requests to one host adapter at a time.
-
-	* scsi.c: Bugfix - pass pid, not SCpnt as second arg to
-	  scsi_times_out.
-
-	* scsi.c: Restore interrupt state to previous value instead of using
-	  cli/sti pairs.
-
-	* scsi.c: Add a bunch of module stuff (all commented out for now).
-
-	* scsi.c: Clean up scsi_dump_status.
-
-Tue Dec  6 12:34:20 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.72 released.
-
-	* sg.c: Bugfix - always use sg_free, since we might have big buff.
-
-Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.71 released.
-
-	* sg.c: Clear buff field when not in use.  Only call scsi_free if
-	non-null.
-
-	* scsi.h: Call wake_up(&wait_for_request) when done with a
-	command.
-
-	* scsi.c (scsi_times_out): Pass pid down so that we can protect
-	against race conditions.
-
-	* scsi.c (scsi_abort): Zero timeout field if we get the
-	NOT_RUNNING message back from low-level driver.
-
-
-	* scsi.c (scsi_done): Restore cmd_len, use_sg here.
-
-	* scsi.c (request_sense): Not here.
-
-	* hosts.h: Add new forbidden_addr, forbidden_size fields.  Who
-	added these and why????
-
-	* hosts.c (scsi_mem_init): Mark pages as reserved if they fall in
-	the forbidden regions.  I am not sure - I think this is so that
-	we can deal with boards that do incomplete decoding of their
-	address lines for the bios chips, but I am not entirely sure.
-
-	* buslogic.c: Set forbidden_addr stuff if using a buggy board.
-
-	* aha1740.c: Test for NULL pointer in SCtmp.  This should not
-	occur, but a nice message is better than a kernel segfault.
-
-	* 53c7,8xx.c: Add new PCI chip ID for 815.
-
-Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.70 released.
-
-	* ChangeLog, st.c: Spelling.
-
-Tue Nov 29 18:48:42 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.69 released.
-
-	* u14-34f.h: Non-functional change.  [Dario].
-
-	* u14-34f.c: Use block field in Scsi_Host to prevent commands from
-	being queued to more than one host at the same time (used when
-	motherboard does not deal with multiple bus-masters very well).
-	Only when SINGLE_HOST_OPERATIONS is defined.
-	Use new cmd_per_lun field.  [Dario]
-
-	* eata.c: Likewise.
-
-	* st.c: More changes from Kai.  Add ready flag to indicate drive
-	status.
-
-	* README.st: Document this.
-
-	* sr.c: Bugfix (do not subtract CD_BLOCK_OFFSET) for photo-cd
-	code.
-
-	* sg.c: Bugfix - fix problem where opcode is not correctly set up.
-
-	* seagate.[c,h]: Use #defines to set driver name.
-
-	* scsi_ioctl.c: Zero buffer before executing command.
-
-	* scsi.c: Use new cmd_per_lun field in Scsi_Hosts as appropriate.
-	Add Sony CDU55S to blacklist.
-
-	* hosts.h: Add new cmd_per_lun field to Scsi_Hosts.
-
-	* hosts.c: Initialize cmd_per_lun in Scsi_Hosts from template.
-
-	* buslogic.c: Use cmd_per_lun field - initialize to different
-	values depending upon bus type (i.e. use 1 if ISA, so we do not
-	hog memory).  Use other patches which got lost from 1.1.68.
-
-	* aha1542.c: Spelling.
-
-Tue Nov 29 15:43:50 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.68 released.
-
-	Add support for 12 byte vendor specific commands in scsi-generics,
-	more (i.e. the last mandatory) low-level changes to support
-	loadable modules, plus a few other changes people have requested
-	lately.  Changes by me (ERY) unless otherwise noted.  Spelling
-	changes appear from some unknown corner of the universe.
-
-	* Throughout: Change COMMAND_SIZE() to use SCpnt->cmd_len.
-
-	* Throughout: Change info() low level function to take a Scsi_Host
-	pointer.  This way the info function can return specific
-	information about the host in question, if desired.
-
-	* All low-level drivers: Add NULL in initializer for the
-	usage_count field added to Scsi_Host_Template.
-
-	* aha152x.[c,h]: Remove redundant info() function.
-
-	* aha1542.[c,h]: Likewise.
-
-	* aha1740.[c,h]: Likewise.
-
-	* aha274x.[c,h]: Likewise.
-
-	* eata.[c,h]: Likewise.
-
-	* pas16.[c,h]: Likewise.
-
-	* scsi_debug.[c,h]: Likewise.
-
-	* t128.[c,h]: Likewise.
-
-	* u14-34f.[c,h]: Likewise.
-
-	* ultrastor.[c,h]: Likewise.
-
-	* wd7000.[c,h]: Likewise.
-
-	* aha1542.c: Add support for command line options with lilo to set
-	DMA parameters, I/O port.  From Matt Aarnio.
-
-	* buslogic.[c,h]: New version (1.13) from Dave Gentzel.
-
-	* hosts.h: Add new field to Scsi_Hosts "block" to allow blocking
-	all I/O to certain other cards.  Helps prevent problems with some
-	ISA motherboards.
-
-	* hosts.h: Add usage_count to Scsi_Host_Template.
-
-	* hosts.h: Add n_io_port to Scsi_Host (used when releasing module).
-
-	* hosts.c: Initialize block field.
-
-	* in2000.c: Remove "static" declarations from exported functions.
-
-	* in2000.h: Likewise.
-
-	* scsi.c: Correctly set cmd_len field as required.  Save and
-	change setting when doing a request_sense, restore when done.
-	Move abort timeout message.  Fix panic in request_queueable to
-	print correct function name.
-
-	* scsi.c: When incrementing usage count, walk block linked list
-	for host, and or in SCSI_HOST_BLOCK bit.  When decrementing usage
-	count to 0, clear this bit to allow usage to continue, wake up
-	processes waiting.
-
-
-	* scsi_ioctl.c: If we have an info() function, call it, otherwise
-	if we have a "name" field, use it, else do nothing.
-
-	* sd.c, sr.c: Clear cmd_len field prior to each command we
-	generate.
-
-	* sd.h: Add "has_part_table" bit to rscsi_disks.
-
-	* sg.[c,h]: Add support for vendor specific 12 byte commands (i.e.
-	override command length in COMMAND_SIZE).
-
-	* sr.c: Bugfix from Gerd in photocd code.
-
-	* sr.c: Bugfix in get_sectorsize - always use scsi_malloc buffer -
-	we cannot guarantee that the stack is < 16Mb.
-
-Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.67 released.
-
-	* sr.c: Change spelling of manufactor to manufacturer.
-
-	* scsi.h: Likewise.
-
-	* scsi.c: Likewise.
-
-	* qlogic.c: Spelling corrections.
-
-	* in2000.h: Spelling corrections.
-
-	* in2000.c: Update from Bill Earnest, change from
-	jshiffle@netcom.com.  Support new bios versions.
-
-	* README.qlogic: Spelling correction.
-
-Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.66 released.
-
-	* u14-34f.c: Spelling corrections.
-
-	* sr.[h,c]: Add support for multi-session CDs from Gerd Knorr.
-
-	* scsi.h: Add manufactor field for keeping track of device
-	manufacturer.
-
-	* scsi.c: More spelling corrections.
-
-	* qlogic.h, qlogic.c, README.qlogic: New driver from Tom Zerucha.
-
-	* in2000.c, in2000.h: New driver from Brad McLean/Bill Earnest.
-
-	* fdomain.c: Spelling correction.
-
-	* eata.c: Spelling correction.
-
-Fri Nov 18 15:22:44 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.65 released.
-
-	* eata.h: Update version string to 1.08.00.
-
-	* eata.c: Set sg_tablesize correctly for DPT PM2012 boards.
-
-	* aha274x.seq: Spell checking.
-
-	* README.st: Likewise.
-
-	* README.aha274x: Likewise.
-
-	* ChangeLog: Likewise.
-
-Tue Nov 15 15:35:08 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.64 released.
-
-	* u14-34f.h: Update version number to 1.10.01.
-
-	* u14-34f.c: Use Scsi_Host can_queue variable instead of one from template.
-
-	* eata.[c,h]: New driver for DPT boards from Dario Ballabio.
-
-	* buslogic.c: Use can_queue field.
-
-Wed Nov 30 12:09:09 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.63 released.
-
-	* sd.c: Give I/O error if we attempt 512 byte I/O to a disk with
-	1024 byte sectors.
-
-	* scsicam.c: Make sure we do read from whole disk (mask off
-	partition).
-
-	* scsi.c: Use can_queue in Scsi_Host structure.
-	Fix panic message about invalid host.
-
-	* hosts.c: Initialize can_queue from template.
-
-	* hosts.h: Add can_queue to Scsi_Host structure.
-
-	* aha1740.c: Print out warning about NULL ecbptr.
-
-Fri Nov  4 12:40:30 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.62 released.
-
-	* fdomain.c: Update to version 5.20. (From Rik Faith).  Support
-	BIOS version 3.5.
-
-	* st.h: Add ST_EOD symbol.
-
-	* st.c: Patches from Kai Makisara - support additional densities,
-	add support for MTFSS, MTBSS, MTWSM commands.
-
-	* README.st: Update to document new commands.
-
-	* scsi.c: Add Mediavision CDR-H93MV to blacklist.
-
-Sat Oct 29 20:57:36 1994  Eric Youngdale  (eric@andante.aib.com)
-
-	* Linux 1.1.60 released.
-
-	* u14-34f.[c,h]: New driver from Dario Ballabio.
-
-	* aic7770.c, aha274x_seq.h, aha274x.seq, aha274x.h, aha274x.c,
-	README.aha274x: New files, new driver from John Aycock.
-
-
-Tue Oct 11 08:47:39 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.54 released.
-
-	* Add third PCI chip id.  [Drew]
-
-	* buslogic.c: Set BUSLOGIC_CMDLUN back to 1 [Eric].
-
-	* ultrastor.c: Fix asm directives for new GCC.
-
-	* sr.c, sd.c: Use new end_scsi_request function.
-
-	* scsi.h(end_scsi_request): Return pointer to block if still
-	active, else return NULL if inactive.  Fixes race condition.
-
-Sun Oct  9 20:23:14 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.53 released.
-
-	* scsi.c: Do not allocate dma bounce buffers if we have exactly
-	16Mb.
-
-Fri Sep  9 05:35:30 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.51 released.
-
-	* aha152x.c: Add support for disabling the parity check.  Update
-	to version 1.4. [Juergen].
-
-	* seagate.c: Tweak debugging message.
-
-Wed Aug 31 10:15:55 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.50 released.
-
-	* aha152x.c: Add eb800 for Vtech Platinum SMP boards. [Juergen].
-
-	* scsi.c: Add Quantum PD1225S to blacklist.
-
-Fri Aug 26 09:38:45 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.49 released.
-
-	* sd.c: Fix bug when we were deleting the wrong entry if we
-	get an unsupported sector size device.
-
-	* sr.c: Another spelling patch.
-
-Thu Aug 25 09:15:27 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.48 released.
-
-	* Throughout: Use new semantics for request_dma, as appropriate.
-
-	* sr.c: Print correct device number.
-
-Sun Aug 21 17:49:23 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.47 released.
-
-	* NCR5380.c: Add support for LIMIT_TRANSFERSIZE.
-
-	* constants.h: Add prototype for print_Scsi_Cmnd.
-
-	* pas16.c: Some more minor tweaks.  Test for Mediavision board.
-	Allow for disks > 1Gb.  [Drew??]
-
-	* sr.c: Set SCpnt->transfersize.
-
-Tue Aug 16 17:29:35 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.46 released.
-
-	* Throughout: More spelling fixups.
-
-	* buslogic.c: Add a few more fixups from Dave.  Disk translation
-	mainly.
-
-	* pas16.c: Add a few patches (Drew?).
-
-
-Thu Aug 11 20:45:15 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.44 released.
-
-	* hosts.c: Add type casts for scsi_init_malloc.
-
-	* scsicam.c: Add type cast.
-
-Wed Aug 10 19:23:01 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.43 released.
-
-	* Throughout: Spelling cleanups. [??]
-
-	* aha152x.c, NCR53*.c, fdomain.c, g_NCR5380.c, pas16.c, seagate.c,
-	 t128.c: Use request_irq, not irqaction. [??]
-
-	* aha1542.c: Move test for shost before we start to use shost.
-
-	* aha1542.c, aha1740.c, ultrastor.c, wd7000.c: Use new
-	calling sequence for request_irq.
-
-	* buslogic.c: Update from Dave Gentzel.
-
-Tue Aug  9 09:32:59 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.42 released.
-
-	* NCR5380.c: Change NCR5380_print_status to static.
-
-	* seagate.c: A few more bugfixes.  Only Drew knows what they are
-	for.
-
-	* ultrastor.c: Tweak some __asm__ directives so that it works
-	with newer compilers. [??]
-
-Sat Aug  6 21:29:36 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.40 released.
-
-	* NCR5380.c: Return SCSI_RESET_WAKEUP from reset function.
-
-	* aha1542.c: Reset mailbox status after a bus device reset.
-
-	* constants.c: Fix typo (;;).
-
-	* g_NCR5380.c:
-	* pas16.c:  Correct usage of NCR5380_init.
-
-	* scsi.c: Remove redundant (and unused variables).
-
-	* sd.c: Use memset to clear all of rscsi_disks before we use it.
-
-	* sg.c: Ditto, except for scsi_generics.
-
-	* sr.c: Ditto, except for scsi_CDs.
-
-	* st.c: Initialize STp->device.
-
-	* seagate.c: Fix bug. [Drew]
-
-Thu Aug  4 08:47:27 1994  Eric Youngdale  (eric@andante)
-
-	* Linux 1.1.39 released.
-
-	* Makefile: Fix typo in NCR53C7xx.
-
-	* st.c: Print correct number for device.
-
-Tue Aug  2 11:29:14 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.38 released.
-
-	Lots of changes in 1.1.38.  All from Drew unless otherwise noted.
-
-	* 53c7,8xx.c: New file from Drew.  PCI driver.
-
-	* 53c7,8xx.h: Likewise.
-
-	* 53c7,8xx.scr: Likewise.
-
-	* 53c8xx_d.h, 53c8xx_u.h, script_asm.pl: Likewise.
-
-	* scsicam.c: New file from Drew.  Read block 0 on the disk and
-	read the partition table.  Attempt to deduce the geometry from
-	the partition table if possible.  Only used by 53c[7,8]xx right
-	now, but could be used by any device for which we have no way
-	of identifying the geometry.
-
-	* sd.c: Use device letters instead of sd%d in a lot of messages.
-
-	* seagate.c: Fix bug that resulted in lockups with some devices.
-
-	* sr.c (sr_open): Return -EROFS, not -EACCES if we attempt to open
-	device for write.
-
-	* hosts.c, Makefile: Update for new driver.
-
-	* NCR5380.c, NCR5380.h, g_NCR5380.h: Update from Drew to support
-	53C400 chip.
-
-	* constants.c: Define CONST_CMND and CONST_MSG.  Other minor
-	cleanups along the way.  Improve handling of CONST_MSG.
-
-	* fdomain.c, fdomain.h: New version from Rik Faith.  Update to
-	5.18.  Should now support TMC-3260 PCI card with 18C30 chip.
-
-	* pas16.c: Update with new irq initialization.
-
-	* t128.c: Update with minor cleanups.
-
-	* scsi.c (scsi_pid): New variable - gives each command a unique
-	id. Add Quantum LPS5235S to blacklist.  Change in_scan to
-	in_scan_scsis and make global.
-
-	* scsi.h: Add some defines for extended message handling,
-	INITIATE/RELEASE_RECOVERY.  Add a few new fields to support sync
-	transfers.
-
-	* scsi_ioctl.h: Add ioctl to request synchronous transfers.
-
-
-Tue Jul 26 21:36:58 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.37 released.
-
-	* aha1542.c: Always call aha1542_mbenable, use new udelay
-	mechanism so we do not wait a long time if the board does not
-	implement this command.
-
-	* g_NCR5380.c: Remove #include <linux/config.h> and #if
-	defined(CONFIG_SCSI_*).
-
-	* seagate.c: Likewise.
-
-	Next round of changes to support loadable modules.  Getting closer
-	now, still not possible to do anything remotely usable.
-
-	hosts.c: Create a linked list of detected high level devices.
-	(scsi_register_device): New function to insert into this list.
-	(scsi_init): Call scsi_register_device for each of the known high
-	level drivers.
-
-	hosts.h: Add prototype for linked list header.  Add structure
-	definition for device template structure which defines the linked
-	list.
-
-	scsi.c: (scan_scsis): Use linked list instead of knowledge about
-	existing high level device drivers.
-	(scsi_dev_init): Use init functions for drivers on linked list
-	instead of explicit list to initialize and attach devices to high
-	level drivers.
-
-	scsi.h: Add new field "attached" to scsi_device - count of number
-	of high level devices attached.
-
-	sd.c, sr.c, sg.c, st.c: Adjust init/attach functions to use new
-	scheme.
-
-Sat Jul 23 13:03:17 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.35 released.
-
-	* ultrastor.c: Change constraint on asm() operand so that it works
-	with gcc 2.6.0.
-
-Thu Jul 21 10:37:39 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.33 released.
-
-	* sr.c(sr_open): Do not allow opens with write access.
-
-Mon Jul 18 09:51:22 1994 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.31 released.
-
-	* sd.c: Increase SD_TIMEOUT from 300 to 600.
-
-	* sr.c: Remove stray task_struct* variable that was no longer
-	used.
-
-	* sr_ioctl.c: Fix typo in up() call.
-
-Sun Jul 17 16:25:29 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.30 released.
-
-	* scsi.c (scan_scsis): Fix detection of some Toshiba CDROM drives
-	that report themselves as disk drives.
-
-	* (Throughout): Use request.sem instead of request.waiting.
-	Should fix swap problem with fdomain.
-
-Thu Jul 14 10:51:42 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.29 released.
-
-	* scsi.c (scan_scsis): Add new devices to end of linked list, not
-	to the beginning.
-
-	* scsi.h (SCSI_SLEEP): Remove brain dead hack to try to save
-	the task state before sleeping.
-
-Sat Jul  9 15:01:03 1994  Eric Youngdale  (eric@esp22)
-
-	More changes to eventually support loadable modules.  Mainly
-	we want to use linked lists instead of arrays because it is easier
-	to dynamically add and remove things this way.
-
-	Quite a bit more work is needed before loadable modules are
-	possible (and usable) with scsi, but this is most of the grunge
-	work.
-
-	* Linux 1.1.28 released.
-
-	* scsi.c, scsi.h (allocate_device, request_queueable): Change
-	argument from index into scsi_devices to a pointer to the
-	Scsi_Device struct.
-
-	* Throughout: Change all calls to allocate_device,
-	request_queueable to use new calling sequence.
-
-	* Throughout: Use SCpnt->device instead of
-	scsi_devices[SCpnt->index].  Ugh - the pointer was there all along
-	- much cleaner this way.
-
-	* scsi.c (scsi_init_malloc, scsi_free_malloc): New functions -
-	allow us to pretend that we have a working malloc when we
-	initialize.  Use this instead of passing memory_start, memory_end
-	around all over the place.
-
-	* scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use
-	scsi_init_malloc, remove all arguments, no return value.
-
-	* scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd
-	structs.
-
-	* scsi.c (scsi_dev_init): Set up for scsi_init_malloc.
-	(scan_scsis): Get SDpnt from scsi_init_malloc, and refresh
-	when we discover a device.  Free pointer before returning.
-	Change scsi_devices into a linked list.
-
-	* scsi.c (scan_scsis): Change to only scan one host.
-	(scsi_dev_init): Loop over all detected hosts, and scan them.
-
-	* hosts.c  (scsi_init_free): Change so that  number of extra bytes
-	is stored in struct, and we do not have to pass it each time.
-
-	* hosts.h: Change Scsi_Host_Template struct to include "next" and
-	"release" functions.  Initialize to NULL in all low level
-	adapters.
-
-	* hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked
-	list scsi_hosts, linked together with the new "next" field.
-
-Wed Jul  6 05:45:02 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.25 released.
-
-	* aha152x.c: Changes from Juergen - cleanups and updates.
-
-	* sd.c, sr.c: Use new check_media_change and revalidate
-	file_operations fields.
-
-	* st.c, st.h: Add changes from Kai Makisara, dated Jun 22.
-
-	* hosts.h: Change SG_ALL back to 0xff.  Apparently soft error
-	in /dev/brain resulted in having this bumped up.
-	Change first parameter in bios_param function to be Disk * instead
-	of index into rscsi_disks.
-
-	* sd_ioctl.c: Pass pointer to rscsi_disks element instead of index
-	to array.
-
-	* sd.h: Add struct name "scsi_disk" to typedef for Scsi_Disk.
-
-	* scsi.c: Remove redundant Maxtor XT8760S from blacklist.
-	In scsi_reset, add printk when DEBUG defined.
-
-	* All low level drivers: Modify definitions of bios_param in
-	appropriate way.
-
-Thu Jun 16 10:31:59 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.20 released.
-
-	* scsi_ioctl.c: Only pass down the actual number of characters
-	required to scsi_do_cmd, not the one rounded up to a even number
-	of sectors.
-
-	* ultrastor.c: Changes from Caleb Epstein for 24f cards.  Support
-	larger SG lists.
-
-	* ultrastor.c: Changes from me - use scsi_register to register
-	host.  Add some consistency checking,
-
-Wed Jun  1 21:12:13 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.19 released.
-
-	* scsi.h: Add new return code for reset() function:
-	SCSI_RESET_PUNT.
-
-	* scsi.c: Make SCSI_RESET_PUNT the same as SCSI_RESET_WAKEUP for
-	now.
-
-	* aha1542.c: If the command responsible for the reset is not
-	pending, return SCSI_RESET_PUNT.
-
-	* aha1740.c, buslogic.c, wd7000.c, ultrastor.c: Return
-	SCSI_RESET_PUNT instead of SCSI_RESET_SNOOZE.
-
-Tue May 31 19:36:01 1994  Eric Youngdale  (eric@esp22)
-
-	* buslogic.c: Do not print out message about "must be Adaptec"
-	if we have detected a buslogic card.  Print out a warning message
-	if we are configuring for >16Mb, since the 445S at board level
-	D or earlier does not work right.  The "D" level board can be made
-	to work by flipping an undocumented switch, but this is too subtle.
-
-    Changes based upon patches in Yggdrasil distribution.
-
-	* sg.c, sg.h: Return sense data to user.
-
-	* aha1542.c, aha1740.c, buslogic.c: Do not panic if
-	sense buffer is wrong size.
-
-	* hosts.c: Test for ultrastor card before any of the others.
-
-	* scsi.c: Allow boot-time option for max_scsi_luns=? so that
-	buggy firmware has an easy work-around.
-
-Sun May 15 20:24:34 1994  Eric Youngdale  (eric@esp22)
-
-	* Linux 1.1.15 released.
-
-	Post-codefreeze thaw...
-
-	* buslogic.[c,h]: New driver from David Gentzel.
-
-	* hosts.h: Add use_clustering field to explicitly say whether
-	clustering should be used for devices attached to this host
-	adapter.  The buslogic board apparently supports large SG lists,
-	but it is apparently faster if sd.c condenses this into a smaller
-	list.
-
-	* sd.c: Use this field instead of heuristic.
-
-	* All host adapter include files: Add appropriate initializer for
-	use_clustering field.
-
-	* scsi.h: Add #defines for return codes for the abort and reset
-	functions.  There are now a specific set of return codes to fully
-	specify all of the possible things that the low-level adapter
-	could do.
-
-	* scsi.c: Act based upon return codes from abort/reset functions.
-
-	* All host adapter abort/reset functions: Return new return code.
-
-	* Add code in scsi.c to help debug timeouts.  Use #define
-	DEBUG_TIMEOUT to enable this.
-
-	* scsi.c: If the host->irq field is set, use
-	disable_irq/enable_irq before calling queuecommand if we
-	are not already in an interrupt.  Reduce races, and we
-	can be sloppier about cli/sti in the interrupt routines now
-	(reduce interrupt latency).
-
-	* constants.c: Fix some things to eliminate warnings.  Add some
-	sense descriptions that were omitted before.
-
-	* aha1542.c: Watch for SCRD from host adapter - if we see it, set
-	a flag.  Currently we only print out the number of pending
-	commands that might need to be restarted.
-
-	* aha1542.c (aha1542_abort): Look for lost interrupts, OGMB still
-	full, and attempt to recover.  Otherwise give up.
-
-	* aha1542.c (aha1542_reset): Try BUS DEVICE RESET, and then pass
-	DID_RESET back up to the upper level code for all commands running
-	on this target (even on different LUNs).
-
-Sat May  7 14:54:01 1994
-
-	* Linux 1.1.12 released.
-
-	* st.c, st.h: New version from Kai.  Supports boot time
-	specification of number of buffers.
-
-	* wd7000.[c,h]: Updated driver from John Boyd.  Now supports
-	more than one wd7000 board in machine at one time, among other things.
-
-Wed Apr 20 22:20:35 1994
-
-	* Linux 1.1.8 released.
-
-	* sd.c: Add a few type casts where scsi_malloc is called.
-
-Wed Apr 13 12:53:29 1994
-
-	* Linux 1.1.4 released.
-
-	* scsi.c: Clean up a few printks (use %p to print pointers).
-
-Wed Apr 13 11:33:02 1994
-
-	* Linux 1.1.3 released.
-
-	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
-	better).
-
-Fri Apr  8 08:57:19 1994
-
-	* Linux 1.1.2 released.
-
-	* Throughout: SCSI portion of cluster diffs added.
-
-Tue Apr  5 07:41:50 1994
-
-	* Linux 1.1 development tree initiated.
-
-	* The linux 1.0 development tree is now effectively frozen except
-	for obvious bugfixes.
-
-******************************************************************
-******************************************************************
-******************************************************************
-******************************************************************
-
-Sun Apr 17 00:17:39 1994
-
-	* Linux 1.0, patchlevel 9 released.
-
-	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
-	better).
-
-Thu Apr  7 08:36:20 1994
-
-	* Linux 1.0, patchlevel8 released.
-
-	* fdomain.c: Update to version 5.15 from 5.9.  Handles 3.4 bios.
-
-Sun Apr  3 14:43:03 1994
-
-	* Linux 1.0, patchlevel6 released.
-
-	* wd7000.c: Make stab at fixing race condition.
-
-Sat Mar 26 14:14:50 1994
-
-	* Linux 1.0, patchlevel5 released.
-
-	* aha152x.c, Makefile: Fix a few bugs (too much data message).
-	Add a few more bios signatures. (Patches from Juergen).
-
-	* aha1542.c: Fix race condition in aha1542_out.
-
-Mon Mar 21 16:36:20 1994
-
-	* Linux 1.0, patchlevel3 released.
-
-	* sd.c, st.c, sr.c, sg.c: Return -ENXIO, not -ENODEV if we attempt
-	to open a non-existent device.
-
-	* scsi.c: Add Chinon cdrom to blacklist.
-
-	* sr_ioctl.c: Check return status of verify_area.
-
-Sat Mar  6 16:06:19 1994
-
-	* Linux 1.0 released (technically a pre-release).
-
-	* scsi.c: Add IMS CDD521, Maxtor XT-8760S to blacklist.
-
-Tue Feb 15 10:58:20 1994
-
-        * pl15e released.
-
-        * aha1542.c: For 1542C, allow dynamic device scan with >1Gb turned
-	off.
-
-	* constants.c: Fix typo in definition of CONSTANTS.
-
-        * pl15d released.
-
-Fri Feb 11 10:10:16 1994
-
-        * pl15c released.
-
-	* scsi.c: Add Maxtor XT-3280 and Rodime RO3000S to blacklist.
-
-	* scsi.c: Allow tagged queueing for scsi 3 devices as well.
-	Some really old devices report a version number of 0.  Disallow
-	LUN != 0 for these.
-
-Thu Feb 10 09:48:57 1994
-
-        * pl15b released.
-
-Sun Feb  6 12:19:46 1994
-
-        * pl15a released.
-
-Fri Feb  4 09:02:17 1994
-
-        * scsi.c: Add Teac cdrom to blacklist.
-
-Thu Feb  3 14:16:43 1994
-
-	* pl15 released.
-
-Tue Feb  1 15:47:43 1994
-
-	* pl14w released.
-
-	* wd7000.c (wd_bases): Fix typo in last change.
-
-Mon Jan 24 17:37:23 1994
-
-	* pl14u released.
-
-	* aha1542.c: Support 1542CF/extended bios.  Different from 1542C
-
-	* wd7000.c: Allow bios at 0xd8000 as well.
-
-	* ultrastor.c: Do not truncate cylinders to 1024.
-
-	* fdomain.c: Update to version 5.9 (add new bios signature).
-
-	* NCR5380.c: Update from Drew - should work a lot better now.
-
-Sat Jan  8 15:13:10 1994
-
-	* pl14o released.
-
-	* sr_ioctl.c: Zero reserved field before trying to set audio volume.
-
-Wed Jan  5 13:21:10 1994
-
-	* pl14m released.
-
-	* fdomain.c: Update to version 5.8.  No functional difference???
-
-Tue Jan  4 14:26:13 1994
-
-	* pl14l released.
-
-	* ultrastor.c: Remove outl, inl functions (now provided elsewhere).
-
-Mon Jan  3 12:27:25 1994
-
-	* pl14k released.
-
-	* aha152x.c: Remove insw and outsw functions.
-
-	* fdomain.c: Ditto.
-
-Wed Dec 29 09:47:20 1993
-
-	* pl14i released.
-
-	* scsi.c: Support RECOVERED_ERROR for tape drives.
-
-	* st.c: Update of tape driver from Kai.
-
-Tue Dec 21 09:18:30 1993
-
-	* pl14g released.
-
-	* aha1542.[c,h]: Support extended BIOS stuff.
-
-	* scsi.c: Clean up messages about disks, so they are displayed as
-	sda, sdb, etc instead of sd0, sd1, etc.
-
-	* sr.c:  Force reread of capacity if disk was changed.
-	Clear buffer before asking for capacity/sectorsize (some drives
-	do not report this properly).  Set needs_sector_size flag if
-	drive did not return sensible sector size.
-
-Mon Dec 13 12:13:47 1993
-
-	* aha152x.c: Update to version .101 from Juergen.
-
-Mon Nov 29 03:03:00 1993
-
-        * linux 0.99.14 released.
-
-	* All scsi stuff moved from kernel/blk_drv/scsi to drivers/scsi.
-
-	* Throughout: Grammatical corrections to various comments.
-
-	* Makefile: fix so that we do not need to compile things we are
-	not going to use.
-
-	* NCR5380.c, NCR5380.h, g_NCR5380.c, g_NCR5380.h, pas16.c,
-	pas16.h, t128.c, t128.h:  New files from Drew.
-
-	* aha152x.c, aha152x.h: New files from Juergen Fischer.
-
-	* aha1542.c: Support for more than one 1542 in the machine
-	at the same time.  Make functions static that do not need
-	visibility.
-
-	* aha1740.c: Set NEEDS_JUMPSTART flag in reset function, so we
-	know to restart the command.  Change prototype of aha1740_reset
-	to take a command pointer.
-
-	* constants.c: Clean up a few things.
-
-	* fdomain.c: Update to version 5.6.  Move snarf_region.  Allow
-	board to be set at different SCSI ids.  Remove support for
-	reselection (did not work well).  Set JUMPSTART flag in reset
-	code.
-
-	* hosts.c: Support new low-level adapters.  Allow for more than
-	one adapter of a given type.
-
-	* hosts.h: Allow for more than one adapter of a given type.
-
-	* scsi.c:  Add scsi_device_types array, if NEEDS_JUMPSTART is set
-	after a low-level reset, start the command again.  Sort blacklist,
-	and add Maxtor MXT-1240S, XT-4170S, NEC CDROM 84, Seagate ST157N.
-
-	* scsi.h: Add constants for tagged queueing.
-
-	* Throughout: Use constants from major.h instead of hardcoded
-	numbers for major numbers.
-
-	* scsi_ioctl.c: Fix bug in buffer length in ioctl_command.  Use
-	verify_area in GET_IDLUN ioctl.  Add new ioctls for
-	TAGGED_QUEUE_ENABLE, DISABLE.  Only allow IOCTL_SEND_COMMAND by
-	superuser.
-
-	* sd.c: Only pay attention to UNIT_ATTENTION for removable disks.
-	Fix bug where sometimes portions of blocks would get lost
-	resulting in processes hanging.  Add messages when we spin up a
-	disk, and fix a bug in the timing.  Increase read-ahead for disks
-	that are on a scatter-gather capable host adapter.
-
-	* seagate.c: Fix so that some parameters can be set from the lilo
-	prompt.  Supply jumpstart flag if we are resetting and need the
-	command restarted.   Fix so that we return 1 if we detect a card
-	so that multiple card detection works correctly.  Add yet another
-	signature for FD cards (950).  Add another signature for ST0x.
-
-	* sg.c, sg.h: New files from Lawrence Foard for generic scsi
-	access.
-
-	* sr.c:  Add type casts for (void*) so that we can do pointer
-	arithmetic.  Works with GCC without this, but it is not strictly
-	correct.  Same bugfix as was in sd.c.  Increase read-ahead a la
-	disk driver.
-
-	* sr_ioctl.c: Use scsi_malloc buffer instead of buffer from stack
-	since we cannot guarantee that the stack is < 16Mb.
-
-	ultrastor.c: Update to support 24f properly (JFC's driver).
-
-	wd7000.c: Supply jumpstart flag for reset.  Do not round up
-	number of cylinders in biosparam function.
-
-Sat Sep  4 20:49:56 1993
-
-    * 0.99pl13 released.
-
-    * Throughout:  Use check_region/snarf_region for all low-level
-    drivers.
-
-    * aha1542.c: Do hard reset instead of soft (some ethercard probes
-    screw us up).
-
-    * scsi.c: Add new flag ASKED_FOR_SENSE so that we can tell if we are
-    in a loop whereby the device returns null sense data.
-
-    * sd.c: Add code to spin up a drive if it is not already spinning.
-    Do this one at a time to make it easier on power supplies.
-
-    * sd_ioctl.c: Use sync_dev instead of fsync_dev in BLKFLSBUF ioctl.
-
-    * seagate.c: Switch around DATA/CONTROL lines.
-
-    * st.c: Change sense to unsigned.
-
-Thu Aug  5 11:59:18 1993
-
-    * 0.99pl12 released.
-
-    * constants.c, constants.h: New files with ascii descriptions of
-    various conditions.
-
-    * Makefile: Do not try to count the number of low-level drivers,
-    just generate the list of .o files.
-
-    * aha1542.c: Replace 16 with sizeof(SCpnt->sense_buffer).  Add tests
-    for addresses > 16Mb, panic if we find one.
-
-    * aha1740.c: Ditto with sizeof().
-
-    * fdomain.c: Update to version 3.18.  Add new signature, register IRQ
-    with irqaction.  Use ID 7 for new board.  Be more intelligent about
-    obtaining the h/s/c numbers for biosparam.
-
-    * hosts.c: Do not depend upon Makefile generated count of the number
-    of low-level host adapters.
-
-    * scsi.c: Use array for scsi_command_size instead of a function.  Add
-    Texel cdrom and Maxtor XT-4380S to blacklist.  Allow compile time
-    option for no-multi lun scan.  Add semaphore for possible problems
-    with handshaking, assume device is faulty until we know it not to be
-    the case.  Add DEBUG_INIT symbol to dump info as we scan for devices.
-    Zero sense buffer so we can tell if we need to request it.  When
-    examining sense information, request sense if buffer is all zero.
-    If RESET, request sense information to see what to do next.
-
-    * scsi_debug.c: Change some constants to use symbols like INT_MAX.
-
-    * scsi_ioctl.c (kernel_scsi_ioctl): New function -for making ioctl
-    calls from kernel space.
-
-    * sd.c: Increase timeout to 300.  Use functions in constants.h to
-    display info.  Use scsi_malloc buffer for READ_CAPACITY, since
-    we cannot guarantee that a stack based buffer is < 16Mb.
-
-    * sd_ioctl.c: Add BLKFLSBUF ioctl.
-
-    * seagate.c: Add new compile time options for ARBITRATE,
-    SLOW_HANDSHAKE, and SLOW_RATE.  Update assembly loops for transferring
-    data.  Use kernel_scsi_ioctl to request mode page with geometry.
-
-    * sr.c: Use functions in constants.c to display messages.
-
-    * st.c: Support for variable block size.
-
-    * ultrastor.c: Do not use cache for tape drives.  Set
-    unchecked_isa_dma flag, even though this may not be needed (gets set
-    later).
-
-Sat Jul 17 18:32:44 1993
-
-    * 0.99pl11 released.  C++ compilable.
-
-    * Throughout: Add type casts all over the place, and use "ip" instead
-    of "info" in the various biosparam functions.
-
-    * Makefile: Compile seagate.c with C++ compiler.
-
-    * aha1542.c: Always set ccb pointer as this gets trashed somehow on
-    some systems.  Add a few type casts.  Update biosparam function a little.
-
-    * aha1740.c: Add a few type casts.
-
-    * fdomain.c: Update to version 3.17 from 3.6.  Now works with
-    TMC-18C50.
-
-    * scsi.c: Minor changes here and there with datatypes.  Save use_sg
-    when requesting sense information so that this can properly be
-    restored if we retry the command.  Set aside dma buffers assuming each
-    block is 1 page, not 1Kb minix block.
-
-    * scsi_ioctl.c: Add a few type casts.  Other minor changes.
-
-    * sd.c:  Correctly  free all scsi_malloc'd memory if we run out of
-    dma_pool. Store blocksize information for each partition.
-
-    * seagate.c: Minor cleanups here and there.
-
-    * sr.c: Set up blocksize array for all discs.  Fix bug in freeing
-    buffers if we run out of dma pool.
-
-Thu Jun  2 17:58:11 1993
-
-    * 0.99pl10 released.
-
-    * aha1542.c: Support for BT 445S (VL-bus board with no dma channel).
-
-    * fdomain.c: Upgrade to version 3.6. Preliminary support for TNC-18C50.
-
-    * scsi.c: First attempt to fix problem with old_use_sg.  Change
-    NOT_READY to a SUGGEST_ABORT.  Fix timeout race where time might
-    get decremented past zero.
-
-    * sd.c: Add block_fsync function to dispatch table.
-
-    * sr.c: Increase timeout to 500 from 250.  Add entry for sync in
-    dispatch table (supply NULL).  If we do not have a sectorsize,
-    try to get it in the sd_open function.  Add new function just to
-    obtain sectorsize.
-
-    * sr.h: Add needs_sector_size semaphore.
-
-    * st.c: Add NULL for fsync in dispatch table.
-
-    * wd7000.c: Allow another condition for power on that are normal
-    and do not require a panic.
-
-Thu Apr 22 23:10:11 1993
-
-    * 0.99pl9 released.
-
-    * aha1542.c: Use (void) instead of () in setup_mailboxes.
-
-    * scsi.c: Initialize transfersize and underflow fields in SCmd to 0.
-    Do not panic for unsupported message bytes.
-
-    * scsi.h: Allocate 12 bytes instead of 10 for commands.  Add
-    transfersize and underflow fields.
-
-    * scsi_ioctl.c: Further bugfix to ioctl_probe.
-
-    * sd.c: Use long instead of int for last parameter in sd_ioctl.
-    Initialize transfersize and underflow fields.
-
-    * sd_ioctl.c: Ditto for sd_ioctl(,,,,);
-
-    * seagate.c: New version from Drew.  Includes new signatures for FD
-    cards.  Support for 0ws jumper. Correctly initialize
-    scsi_hosts[hostnum].this_id.  Improved handing of
-    disconnect/reconnect, and support command linking.  Use
-    transfersize and underflow fields.  Support scatter-gather.
-
-    * sr.c, sr_ioctl.c: Use long instead of int for last parameter in sr_ioctl.
-    Use buffer and buflength in do_ioctl.  Patches from Chris Newbold for
-    scsi-2 audio commands.
-
-    * ultrastor.c: Comment out in_byte (compiler warning).
-
-    * wd7000.c: Change () to (void) in wd7000_enable_dma.
-
-Wed Mar 31 16:36:25 1993
-
-    * 0.99pl8 released.
-
-    * aha1542.c: Handle mailboxes better for 1542C.
-        Do not truncate number of cylinders at 1024 for biosparam call.
-
-    * aha1740.c: Fix a few minor bugs for multiple devices.
-        Same as above for biosparam.
-
-    * scsi.c: Add lockable semaphore for removable devices that can have
-    media removal prevented.  Add another signature for flopticals.
-    (allocate_device): Fix race condition.  Allow more space in dma pool
-    for blocksizes of up to 4Kb.
-
-    * scsi.h: Define COMMAND_SIZE.  Define a SCSI specific version of
-    INIT_REQUEST that can run with interrupts off.
-
-    * scsi_ioctl.c: Make ioctl_probe function more idiot-proof.  If
-    a removable device says ILLEGAL REQUEST to a door-locking command,
-    clear lockable flag.  Add SCSI_IOCTL_GET_IDLUN ioctl.  Do not attempt
-    to lock door for devices that do not have lockable semaphore set.
-
-    * sd.c: Fix race condition for multiple disks.  Use INIT_SCSI_REQUEST
-    instead of INIT_REQUEST.  Allow sector sizes of 1024 and 256.  For
-    removable disks that are not ready, mark them as having a media change
-    (some drives do not report this later).
-
-    * seagate.c: Use volatile keyword for memory-mapped register pointers.
-
-    * sr.c: Fix race condition, a la sd.c.  Increase the number of retries
-    to 1.  Use INIT_SCSI_REQUEST.  Allow 512 byte sector sizes.  Do a
-    read_capacity when we init the device so we know the size and
-    sectorsize.
-
-    * st.c: If ioctl not found in st.c, try scsi_ioctl for others.
-
-    * ultrastor.c: Do not truncate number of cylinders at 1024 for
-    biosparam call.
-
-    * wd7000.c: Ditto.
-    Throughout: Use COMMAND_SIZE macro to determine length of scsi
-    command.
-
-
-
-Sat Mar 13 17:31:29 1993
-
-    * 0.99pl7 released.
-
-    Throughout: Improve punctuation in some messages, and use new
-    verify_area syntax.
-
-    * aha1542.c: Handle unexpected interrupts better.
-
-    * scsi.c: Ditto.  Handle reset conditions a bit better, asking for
-    sense information and retrying if required.
-
-    * scsi_ioctl.c: Allow for 12 byte scsi commands.
-
-    * ultrastor.c: Update to use scatter-gather.
-
-Sat Feb 20 17:57:15 1993
-
-    * 0.99pl6 released.
-
-    * fdomain.c: Update to version 3.5.  Handle spurious interrupts
-    better.
-
-    * sd.c: Use register_blkdev function.
-
-    * sr.c: Ditto.
-
-    * st.c: Use register_chrdev function.
-
-    * wd7000.c: Undo previous change.
-
-Sat Feb  6 11:20:43 1993
-
-    * 0.99pl5 released.
-
-    * scsi.c: Fix bug in testing for UNIT_ATTENTION.
-
-    * wd7000.c: Check at more addresses for bios.  Fix bug in biosparam
-    (heads & sectors turned around).
-
-Wed Jan 20 18:13:59 1993
-
-    * 0.99pl4 released.
-
-    * scsi.c: Ignore leading spaces when looking for blacklisted devices.
-
-    * seagate.c: Add a few new signatures for FD cards.  Another patch
-    with SCint to fix race condition.  Use recursion_depth to keep track
-    of how many times we have been recursively called, and do not start
-    another command unless we are on the outer level.  Fixes bug
-    with Syquest cartridge drives (used to crash kernel), because
-    they do not disconnect with large data transfers.
-
-Tue Jan 12 14:33:36 1993
-
-    * 0.99pl3 released.
-
-    * fdomain.c: Update to version 3.3 (a few new signatures).
-
-    * scsi.c: Add CDU-541, Denon DRD-25X to blacklist.
-    (allocate_request, request_queueable): Init request.waiting to NULL if
-    non-buffer type of request.
-
-    * seagate.c:  Allow controller to be overridden with CONTROLLER symbol.
-    Set SCint=NULL when we are done, to remove race condition.
-
-    * st.c: Changes from Kai.
-
-Wed Dec 30 20:03:47 1992
-
-    * 0.99pl2 released.
-
-    * scsi.c: Blacklist back in.  Remove Newbury drive as other bugfix
-    eliminates need for it here.
-
-    * sd.c: Return ENODEV instead of EACCES if no such device available.
-    (sd_init) Init blkdev_fops earlier so that sd_open is available sooner.
-
-    * sr.c: Same as above for sd.c.
-
-    * st.c: Return ENODEV instead of ENXIO if no device.  Init chrdev_fops
-    sooner, so that it is always there even if no tapes.
-
-    * seagate.c (controller_type): New variable to keep track of ST0x or
-    FD.  Modify signatures list to indicate controller type, and init
-    controller_type once we find a match.
-
-    * wd7000.c (wd7000_set_sync): Remove redundant function.
-
-Sun Dec 20 16:26:24 1992
-
-    * 0.99pl1 released.
-
-    * scsi_ioctl.c: Bugfix - check dev->index, not dev->id against
-    NR_SCSI_DEVICES.
-
-    * sr_ioctl.c: Verify that device exists before allowing an ioctl.
-
-    * st.c: Patches from Kai - change timeout values, improve end of tape
-    handling.
-
-Sun Dec 13 18:15:23 1992
-
-    * 0.99 kernel released.  Baseline for this ChangeLog.
diff -Nru a/Documentation/scsi/ChangeLog.1992-1997 b/Documentation/scsi/ChangeLog.1992-1997
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/scsi/ChangeLog.1992-1997	2004-12-12 18:04:46 -08:00
@@ -0,0 +1,2023 @@
+Sat Jan 18 15:51:45 1997  Richard Henderson  <rth@tamu.edu>
+
+	* Don't play with usage_count directly, instead hand around
+	the module header and use the module macros.
+
+Fri May 17 00:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
+
+	* BusLogic Driver Version 2.0.3 Released.
+
+Tue Apr 16 21:00:00 1996  Leonard N. Zubkoff <lnz@dandelion.com>
+
+	* BusLogic Driver Version 1.3.2 Released.
+
+Sun Dec 31 23:26:00 1995  Leonard N. Zubkoff <lnz@dandelion.com>
+
+	* BusLogic Driver Version 1.3.1 Released.
+
+Fri Nov 10 15:29:49 1995  Leonard N. Zubkoff <lnz@dandelion.com>
+
+	* Released new BusLogic driver.
+
+Wed Aug  9 22:37:04 1995  Andries Brouwer  <aeb@cwi.nl>
+
+	As a preparation for new device code, separated the various
+	functions the request->dev field had into the device proper,
+	request->rq_dev and a status field request->rq_status.
+
+	The 2nd argument of bios_param is now a kdev_t.
+
+Wed Jul 19 10:43:15 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+        * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all
+	attached devices.
+
+	* scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and
+	eata_dma_proc.c to produce some device info for /proc/scsi.
+
+	* eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done):
+	Changed handling of internal SCSI commands send to the HBA.
+
+
+Wed Jul 19 10:09:17 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.11 released.
+
+	* eata_dma.c (eata_queue)(eata_int_handler): Added code to do
+	command latency measurements if requested by root through
+	/proc/scsi interface.
+	Throughout Use HZ constant for time references.
+
+	* eata_pio.c: Use HZ constant for time references.
+
+	* aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD
+	to GNU style.
+
+	* scsi.h: Added READ_12 command opcode constant
+
+Wed Jul 19 09:25:30 1995  Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.10 released.
+
+	* scsi_proc.c (dispatch_scsi_info): Removed unused variable.
+
+Wed Jul 19 09:25:30 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.9 released.
+
+	* scsi.c Blacklist concept expanded to 'support' more device
+	deficiencies. blacklist[] renamed to device_list[]
+	(scan_scsis): Code cleanup.
+
+	* scsi_debug.c (scsi_debug_proc_info): Added support to control
+	device lockup simulation via /proc/scsi interface.
+
+
+Wed Jul 19 09:22:34 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.7 released.
+
+	* scsi_proc.c: Fixed a number of bugs in directory handling
+
+Wed Jul 19 09:18:28 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.5 released.
+
+	* Native wide, multichannel and /proc/scsi support now in official
+	kernel distribution.
+
+        * scsi.c/h, hosts.c/h et al reindented to increase readability
+	(especially on 80 column wide terminals).
+
+	* scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added
+	/proc/scsi/scsi which allows root to scan for hotplugged devices.
+
+	* scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi.
+	(scan_scsis): Added some 'spaghetti' code to allow scanning for
+	single devices.
+	
+
+Thu Jun 20 15:20:27 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+        * proc.c: Renamed to scsi_proc.c
+
+Mon Jun 12 20:32:45 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* Linux 1.3.0 released.
+
+Mon May 15 19:33:14 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* scsi.c: Added native multichannel and wide scsi support.
+
+	* proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries):
+	Updated /proc/scsi interface.
+
+Thu May  4 17:58:48 1995  Michael Neuffer  <neuffer@goofy.zdv.uni-mainz.de>
+
+	* sd.c (requeue_sd_request): Zero out the scatterlist only if
+	scsi_malloc returned memory for it.
+
+	* eata_dma.c (register_HBA) (eata_queue): Add support for
+	large scatter/gather tables and set use_clustering accordingly
+
+	* hosts.c: Make use_clustering changeable in the Scsi_Host structure.
+
+Wed Apr 12 15:25:52 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.5 released.
+
+	* buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff).
+	Fixed interrupt routine to avoid races when handling multiple
+	complete commands per interrupt.  Seems to come up with faster
+	cards.
+
+	* eata_dma.c: Update to 2.3.5r. Modularize. Improved error handling
+        throughout and fixed bug interrupt routine which resulted in shifted
+        status bytes. Added blink LED state checks for ISA and EISA HBAs.
+        Memory management bug seems to have disappeared ==> increasing
+        C_P_L_CURRENT_MAX to 16 for now. Decreasing C_P_L_DIV to 3 for
+        performance reasons.
+
+	* scsi.c: If we get a FMK, EOM, or ILI when attempting to scan
+	the bus, assume that it was just noise on the bus, and ignore
+	the device.
+
+	* scsi.h: Update and add a bunch of missing commands which we
+	were never using.
+
+	* sd.c: Use restore_flags in do_sd_request - this may result in
+	latency conditions, but it gets rid of races and crashes.
+	Do not save flags again when searching for a second command to
+	queue.
+
+	* st.c: Use bytes, not STP->buffer->buffer_size when reading
+	from tape.
+
+
+Tue Apr  4 09:42:08 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.4 released.
+
+	* st.c: Fix typo - restoring wrong flags.
+
+Wed Mar 29 06:55:12 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.3 released.
+
+	* st.c: Perform some waiting operations with interrupts off.
+	Is this correct???
+
+Wed Mar 22 10:34:26 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.2 released.
+
+	* aha152x.c: Modularize.  Add support for PCMCIA.
+
+	* eata.c: Update to version 2.0.  Fixed bug preventing media
+	detection.  If scsi_register_host returns NULL, fail gracefully.
+
+	* scsi.c: Detect as NEC (for photo-cd purposes) for the 84
+	and 25 models as "NEC_OLDCDR".
+
+	* scsi.h: Add define for NEC_OLDCDR
+
+	* sr.c: Add handling for NEC_OLDCDR.  Treat as unknown.
+
+	* u14-34f.c: Update to version 2.0.  Fixed same bug as in
+	eata.c.
+
+
+Mon Mar  6 11:11:20 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.2.0 released.  Yeah!!!
+
+	* Minor spelling/punctuation changes throughout.  Nothing
+	substantive.
+
+Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.95 released.
+
+	* qlogic.c: Update to version 0.41.
+
+	* seagate.c: Change some message to be more descriptive about what
+	we detected.
+
+	* sr.c: spelling/whitespace changes.
+
+Mon Feb 20 21:33:03 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.94 released.
+
+Mon Feb 20 08:57:17 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.93 released.
+
+	* hosts.h: Change io_port to long int from short.
+
+ 	* 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP,
+ 	  NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output
+ 	  fixed, should initialize correctly if left running, now loadable,
+  	  new memory allocation, extraneous diagnostic output suppressed,
+ 	  splx() replaced with save/restore flags. [ Drew ]
+
+	* hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c,
+	sr_ioctl.c: Add special junk at end that Emacs will use for
+	formatting the file.
+
+	* qlogic.c: Update to v0.40a.  Improve parity handling.
+
+	* scsi.c: Add Hitachi DK312C to blacklist.  Change "};" to "}" in
+	many places.  Use scsi_init_malloc to get command block - may
+	need this to be dma compatible for some host adapters.
+	Restore interrupts after unregistering a host.
+
+	* sd.c: Use sti instead of restore flags - causes latency problems.
+
+	* seagate.c: Use controller_type to determine string used when
+	registering irq.
+
+	* sr.c: More photo-cd hacks to make sure we get the xa stuff right.
+	* sr.h, sr.c: Change is_xa to xa_flags field.
+
+	* st.c: Disable retries for write operations.
+
+Wed Feb 15 10:52:56 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.92 released.
+
+	* eata.c: Update to 1.17.
+
+	* eata_dma.c: Update to 2.31a. Add more support for /proc/scsi.
+        Continuing modularization. Less crashes because of the bug in the
+        memory management ==> increase C_P_L_CURRENT_MAX to 10
+        and decrease C_P_L_DIV to 4.
+
+	* hosts.c: If we remove last host registered, reuse host number.
+	When freeing memory from host being deregistered, free extra_bytes
+	too.
+
+	* scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt.
+	Change memory allocation to work around bugs in __get_dma_pages.
+	Do not free host if usage count is not zero (for modules).
+
+	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000.
+
+	* st.c: Allow for ST_EXTRA_DEVS in st data structures.
+
+	* u14-34f.c: Update to 1.17.
+
+Thu Feb  9 10:11:16 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.91 released.
+
+	* eata.c: Update to 1.16.  Use wish_block instead of host->block.
+
+	* hosts.c: Initialize wish_block to 0.
+
+	* hosts.h: Add wish_block.
+
+	* scsi.c: Use wish_block as indicator that the host should be added
+	to block list.
+
+	* sg.c: Add SG_EXTRA_DEVS to number of slots.
+
+	* u14-34f.c: Use wish_block.
+
+Tue Feb  7 11:46:04 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.90 released.
+
+	* eata.c: Change naming from eata_* to eata2x_*.  Now at vers 1.15.
+	Update interrupt handler to take pt_regs as arg.  Allow blocking
+	even if loaded as module.  Initialize target_time_out array.
+	Do not put sti(); in timing loop.
+
+	* hosts.c: Do not reuse host numbers.
+	Use scsi_make_blocked_list to generate blocking list.
+
+	* script_asm.pl:  Beats me.  Don't know perl.  Something to do with
+	phase index.
+
+	* scsi.c (scsi_make_blocked_list): New function - code copied from
+	hosts.c.
+
+	* scsi.c: Update code to disable photo CD for Toshiba cdroms.
+	Use just manufacturer name, not model number.
+
+	* sr.c: Fix setting density for Toshiba drives.
+
+	* u14-34f.c: Clear target_time_out array during reset.
+
+Wed Feb  1 09:20:45 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.89 released.
+
+	* Makefile, u14-34f.c: Modularize.
+
+	* Makefile, eata.c: Modularize.  Now version 1.14
+
+	* NCR5380.c: Update interrupt handler with new arglist.  Minor
+	cleanups.
+
+	* eata_dma.c: Begin to modularize.  Add hooks for /proc/scsi.
+	New version 2.3.0a. Add code in interrupt handler to allow
+        certain CDROM drivers to be detected which return a
+        CHECK_CONDITION during SCSI bus scan. Add opcode check to get
+        all DATA IN and DATA OUT phases right. Utilize HBA_interpret flag.
+	Improvements in HBA identification. Various other minor stuff.
+
+	* hosts.c: Initialize ->dma_channel and ->io_port when registering
+	a new host.
+
+	* qlogic.c: Modularize and add PCMCIA support.
+
+	* scsi.c: Add Hitachi to blacklist.
+
+	* scsi.c: Change default to no lun scan (too many problem devices).
+
+	* scsi.h: Define QUEUE_FULL condition.
+
+	* sd.c: Do not check for non-existent partition until after
+	new media check.
+
+	* sg.c: Undo previous change which was wrong.
+
+	* sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000.
+
+	* st.c: Patches from Kai - improve filemark handling.
+
+Tue Jan 31 17:32:12 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.88 released.
+
+	* Throughout - spelling/grammar fixups.
+
+	* scsi.c: Make sure that all buffers are 16 byte aligned - some
+	drivers (buslogic) need this.
+
+	* scsi.c (scan_scsis): Remove message printed.
+
+	* scsi.c (scsi_init): Move message here.
+
+Mon Jan 30 06:40:25 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.87 released.
+
+	* sr.c: Photo-cd related changes. (Gerd Knorr??).
+
+	* st.c: Changes from Kai related to EOM detection.
+
+Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.86 released.
+
+	* 53c7,8xx.h: Change SG size to 127.
+
+	* eata_dma: Update to version 2.10i. Remove bug in the registration
+        of multiple HBAs and channels. Minor other improvements and stylistic
+        changes.
+
+	* scsi.c: Test for Toshiba XM-3401TA and exclude from detection
+	as toshiba drive - photo cd does not work with this drive.
+
+	* sr.c:  Update photocd code.
+
+Mon Jan 23 23:53:10 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.85 released.
+
+	* st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c:
+	include linux/mm.h
+
+	* qlogic.c, buslogic.c, aha1542.c: Include linux/module.h.
+
+Sun Jan 22 22:08:46 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.84 released.
+
+	* Makefile: Support for loadable QLOGIC boards.
+
+	* aha152x.c: Update to version 1.8 from Juergen.
+
+	* eata_dma.c: Update from Michael Neuffer.
+        Remove hard limit of 2 commands per lun and make it better
+        configurable. Improvements in HBA identification.
+
+	* in2000.c: Fix biosparam to support large disks.
+
+	* qlogic.c: Minor changes (change sti -> restore_flags).
+
+Wed Jan 18 23:33:09 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.83 released.
+
+	* aha1542.c(aha1542_intr_handle): Use arguments handed down to find
+	which irq.
+
+	* buslogic.c: Likewise.
+
+	* eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards.
+
+	* scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK.
+
+	* sd.c: Fail if we are opening a non-existent partition.
+
+	* sr.c: Bump SR_TIMEOUT to 15000.
+	Do not probe for media size at boot time(hard on changers).
+	Flag device as needing sector size instead.
+
+	* sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl.
+
+	* ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args).
+
+Mon Jan 16 07:18:23 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.82 released.
+
+	Throughout.
+	- Change all interrupt handlers to accept new calling convention.
+	In particular, we now receive the irq number as one of the arguments.
+
+	* More minor spelling corrections in some of the new files.
+
+	* aha1542.c, buslogic.c: Clean up interrupt handler a little now
+	that we receive the irq as an arg.
+
+	* aha274x.c: s/snarf_region/request_region/
+
+	* eata.c: Update to version 1.12.   Fix some comments and display a
+	message if we cannot reserve the port addresses.
+
+	* u14-34f.c: Update to version 1.13.   Fix some comments and display a
+	message if we cannot reserve the port addresses.
+
+	* eata_dma.c: Define get_board_data function (send INQUIRY command).
+	Use to improve detection of variants of different DPT boards.  Change
+	version subnumber to "0g".
+
+	* fdomain.c:  Update to version 5.26.  Improve detection of some boards
+	repackaged by IBM.
+
+	* scsi.c (scsi_register_host): Change "name" to const char *.
+
+	* sr.c: Fix problem in set mode command for Toshiba drives.
+
+	* sr.c: Fix typo from patch 81.
+
+Fri Jan 13 12:54:46 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.81 released.  Codefreeze for 1.2 release announced.
+
+	Big changes here.
+
+	* eata_dma.*: New files from Michael Neuffer.
+	(neuffer@goofy.zdv.uni-mainz.de).  Should support
+	all eata/dpt cards.
+
+	* hosts.c, Makefile: Add eata_dma.
+
+	* README.st: Document MTEOM.
+
+	Patches from me (ERY) to finish support for low-level loadable scsi.
+	It now works, and is actually useful.
+
+	* Throughout - add new argument to scsi_init_malloc that takes an
+	additional parameter.  This is used as a priority to kmalloc,
+	and you can specify the GFP_DMA flag if you need DMA-able memory.
+
+	* Makefile: For source files that are loadable, always add name
+	to SCSI_SRCS.  Fill in modules: target.
+
+	* hosts.c:  Change next_host to next_scsi_host, and make global.
+	Print hosts after we have identified all of them.  Use info()
+	function if present, otherwise use name field.
+
+	* hosts.h: Change attach function to return int, not void.
+	Define number of device slots to allow for loadable devices.
+	Define tags to tell scsi module code what type of module we
+	are loading.
+
+	* scsi.c: Fix scan_scsis so that it can be run by a user process.
+	Do not use waiting loops - use up and down mechanism as long
+	as current != task[0].
+
+	* scsi.c(scan_scsis): Do not use stack variables for I/O - this
+	could be > 16Mb if we are loading a module at runtime (i.e. use
+	scsi_init_malloc to get some memory we know will be safe).
+
+	* scsi.c: Change dma freelist to be a set of pages.  This allows
+	us to dynamically adjust the size of the list by adding more pages
+	to the pagelist.  Fix scsi_malloc and scsi_free accordingly.
+
+	* scsi_module.c: Fix include.
+
+	* sd.c: Declare detach function.  Increment/decrement module usage
+	count as required.  Fix init functions to allow loaded devices.
+	Revalidate all new disks so we get the partition tables.  Define
+	detach function.
+
+	* sr.c: Likewise.
+
+	* sg.c: Declare detach function.  Allow attachment of devices on
+	loaded drivers.
+
+	* st.c: Declare detach function.  Increment/decrement module usage
+	count as required.
+
+Tue Jan 10 10:09:58 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.79 released.
+
+	Patch from some undetermined individual who needs to get a life :-).
+
+	* sr.c: Attacked by spelling bee...
+
+	Patches from Gerd Knorr:
+
+	* sr.c: make printk messages for photoCD a little more informative.
+
+	* sr_ioctl.c: Fix CDROMMULTISESSION_SYS ioctl.
+
+Mon Jan  9 10:01:37 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.78 released.
+
+	* Makefile: Add empty modules: target.
+
+	* Wheee.  Now change register_iomem to request_region.
+
+	* in2000.c: Bugfix - apparently this is the fix that we have
+	all been waiting for.  It fixes a problem whereby the driver
+	is not stable under heavy load.  Race condition and all that.
+	Patch from Peter Lu.
+
+Wed Jan  4 21:17:40 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.77 released.
+
+	* 53c7,8xx.c: Fix from Linus - emulate splx.
+
+	Throughout:
+
+		Change "snarf_region" with "register_iomem".
+
+	* scsi_module.c: New file.  Contains support for low-level loadable
+	  scsi drivers. [ERY].
+
+	* sd.c: More s/int/long/ changes.
+
+	* seagate.c: Explicitly include linux/config.h
+
+	* sg.c: Increment/decrement module usage count on open/close.
+
+	* sg.c: Be a bit more careful about the user not supplying enough
+	  information for a valid command.  Pass correct size down to
+	  scsi_do_cmd.
+
+	* sr.c:  More changes for Photo-CD.  This apparently breaks NEC drives.
+
+	* sr_ioctl.c:  Support CDROMMULTISESSION ioctl.
+
+
+Sun Jan  1 19:55:21 1995  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.76 released.
+
+	* constants.c: Add type cast in switch statement.
+
+	* scsi.c (scsi_free): Change datatype of "offset" to long.
+	  (scsi_malloc): Change a few more variables to long.  Who
+	  did this and why was it important?  64 bit machines?
+
+
+	Lots of changes to use save_state/restore_state instead of cli/sti.
+	Files changed include:
+
+	* aha1542.c:
+	* aha1740.c:
+	* buslogic.c:
+	* in2000.c:
+	* scsi.c:
+	* scsi_debug.c:
+	* sd.c:
+	* sr.c:
+	* st.c:
+
+Wed Dec 28 16:38:29 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.75 released.
+
+	* buslogic.c: Spelling fix.
+
+	* scsi.c: Add HP C1790A and C2500A scanjet to blacklist.
+
+	* scsi.c: Spelling fixup.
+
+	* sd.c: Add support for sd_hardsizes (hard sector sizes).
+
+	* ultrastor.c: Use save_flags/restore_flags instead of cli/sti.
+
+Fri Dec 23 13:36:25 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.74 released.
+
+	* README.st: Update from Kai Makisara.
+
+	* eata.c: New version from Dario - version 1.11.
+	  use scsicam bios_param routine.  Add support for 2011
+	  and 2021 boards.
+
+	* hosts.c: Add support for blocking.  Linked list automatically
+	  generated when shpnt->block is set.
+
+	* scsi.c: Add sankyo & HP scanjet to blacklist.  Add support for
+	  kicking things loose when we deadlock.
+
+	* scsi.c: Recognize scanners and processors in scan_scsis.
+
+	* scsi_ioctl.h: Increase timeout to 9 seconds.
+
+	* st.c: New version from Kai - add better support for backspace.
+
+	* u14-34f.c: New version from Dario.  Supports blocking.
+
+Wed Dec 14 14:46:30 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.73 released.
+
+	* buslogic.c: Update from Dave Gentzel.  Version 1.14.
+	  Add module related stuff.   More fault tolerant if out of
+	  DMA memory.
+
+	* fdomain.c: New version from Rik Faith - version 5.22.  Add support
+	  for ISA-200S SCSI adapter.
+
+	* hosts.c: Spelling.
+
+	* qlogic.c: Update to version 0.38a.  Add more support for PCMCIA.
+
+	* scsi.c: Mask device type with 0x1f during scan_scsis.
+	  Add support for deadlocking, err, make that getting out of
+	  deadlock situations that are created when we allow the user
+	  to limit requests to one host adapter at a time.
+
+	* scsi.c: Bugfix - pass pid, not SCpnt as second arg to
+	  scsi_times_out.
+
+	* scsi.c: Restore interrupt state to previous value instead of using
+	  cli/sti pairs.
+
+	* scsi.c: Add a bunch of module stuff (all commented out for now).
+
+	* scsi.c: Clean up scsi_dump_status.
+
+Tue Dec  6 12:34:20 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.72 released.
+
+	* sg.c: Bugfix - always use sg_free, since we might have big buff.
+
+Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.71 released.
+
+	* sg.c: Clear buff field when not in use.  Only call scsi_free if
+	non-null.
+
+	* scsi.h: Call wake_up(&wait_for_request) when done with a
+	command.
+
+	* scsi.c (scsi_times_out): Pass pid down so that we can protect
+	against race conditions.
+
+	* scsi.c (scsi_abort): Zero timeout field if we get the
+	NOT_RUNNING message back from low-level driver.
+
+
+	* scsi.c (scsi_done): Restore cmd_len, use_sg here.
+
+	* scsi.c (request_sense): Not here.
+
+	* hosts.h: Add new forbidden_addr, forbidden_size fields.  Who
+	added these and why????
+
+	* hosts.c (scsi_mem_init): Mark pages as reserved if they fall in
+	the forbidden regions.  I am not sure - I think this is so that
+	we can deal with boards that do incomplete decoding of their
+	address lines for the bios chips, but I am not entirely sure.
+
+	* buslogic.c: Set forbidden_addr stuff if using a buggy board.
+
+	* aha1740.c: Test for NULL pointer in SCtmp.  This should not
+	occur, but a nice message is better than a kernel segfault.
+
+	* 53c7,8xx.c: Add new PCI chip ID for 815.
+
+Fri Dec  2 11:24:53 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.70 released.
+
+	* ChangeLog, st.c: Spelling.
+
+Tue Nov 29 18:48:42 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.69 released.
+
+	* u14-34f.h: Non-functional change.  [Dario].
+
+	* u14-34f.c: Use block field in Scsi_Host to prevent commands from
+	being queued to more than one host at the same time (used when
+	motherboard does not deal with multiple bus-masters very well).
+	Only when SINGLE_HOST_OPERATIONS is defined.
+	Use new cmd_per_lun field.  [Dario]
+
+	* eata.c: Likewise.
+
+	* st.c: More changes from Kai.  Add ready flag to indicate drive
+	status.
+
+	* README.st: Document this.
+
+	* sr.c: Bugfix (do not subtract CD_BLOCK_OFFSET) for photo-cd
+	code.
+
+	* sg.c: Bugfix - fix problem where opcode is not correctly set up.
+
+	* seagate.[c,h]: Use #defines to set driver name.
+
+	* scsi_ioctl.c: Zero buffer before executing command.
+
+	* scsi.c: Use new cmd_per_lun field in Scsi_Hosts as appropriate.
+	Add Sony CDU55S to blacklist.
+
+	* hosts.h: Add new cmd_per_lun field to Scsi_Hosts.
+
+	* hosts.c: Initialize cmd_per_lun in Scsi_Hosts from template.
+
+	* buslogic.c: Use cmd_per_lun field - initialize to different
+	values depending upon bus type (i.e. use 1 if ISA, so we do not
+	hog memory).  Use other patches which got lost from 1.1.68.
+
+	* aha1542.c: Spelling.
+
+Tue Nov 29 15:43:50 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.68 released.
+
+	Add support for 12 byte vendor specific commands in scsi-generics,
+	more (i.e. the last mandatory) low-level changes to support
+	loadable modules, plus a few other changes people have requested
+	lately.  Changes by me (ERY) unless otherwise noted.  Spelling
+	changes appear from some unknown corner of the universe.
+
+	* Throughout: Change COMMAND_SIZE() to use SCpnt->cmd_len.
+
+	* Throughout: Change info() low level function to take a Scsi_Host
+	pointer.  This way the info function can return specific
+	information about the host in question, if desired.
+
+	* All low-level drivers: Add NULL in initializer for the
+	usage_count field added to Scsi_Host_Template.
+
+	* aha152x.[c,h]: Remove redundant info() function.
+
+	* aha1542.[c,h]: Likewise.
+
+	* aha1740.[c,h]: Likewise.
+
+	* aha274x.[c,h]: Likewise.
+
+	* eata.[c,h]: Likewise.
+
+	* pas16.[c,h]: Likewise.
+
+	* scsi_debug.[c,h]: Likewise.
+
+	* t128.[c,h]: Likewise.
+
+	* u14-34f.[c,h]: Likewise.
+
+	* ultrastor.[c,h]: Likewise.
+
+	* wd7000.[c,h]: Likewise.
+
+	* aha1542.c: Add support for command line options with lilo to set
+	DMA parameters, I/O port.  From Matt Aarnio.
+
+	* buslogic.[c,h]: New version (1.13) from Dave Gentzel.
+
+	* hosts.h: Add new field to Scsi_Hosts "block" to allow blocking
+	all I/O to certain other cards.  Helps prevent problems with some
+	ISA motherboards.
+
+	* hosts.h: Add usage_count to Scsi_Host_Template.
+
+	* hosts.h: Add n_io_port to Scsi_Host (used when releasing module).
+
+	* hosts.c: Initialize block field.
+
+	* in2000.c: Remove "static" declarations from exported functions.
+
+	* in2000.h: Likewise.
+
+	* scsi.c: Correctly set cmd_len field as required.  Save and
+	change setting when doing a request_sense, restore when done.
+	Move abort timeout message.  Fix panic in request_queueable to
+	print correct function name.
+
+	* scsi.c: When incrementing usage count, walk block linked list
+	for host, and or in SCSI_HOST_BLOCK bit.  When decrementing usage
+	count to 0, clear this bit to allow usage to continue, wake up
+	processes waiting.
+
+
+	* scsi_ioctl.c: If we have an info() function, call it, otherwise
+	if we have a "name" field, use it, else do nothing.
+
+	* sd.c, sr.c: Clear cmd_len field prior to each command we
+	generate.
+
+	* sd.h: Add "has_part_table" bit to rscsi_disks.
+
+	* sg.[c,h]: Add support for vendor specific 12 byte commands (i.e.
+	override command length in COMMAND_SIZE).
+
+	* sr.c: Bugfix from Gerd in photocd code.
+
+	* sr.c: Bugfix in get_sectorsize - always use scsi_malloc buffer -
+	we cannot guarantee that the stack is < 16Mb.
+
+Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.67 released.
+
+	* sr.c: Change spelling of manufactor to manufacturer.
+
+	* scsi.h: Likewise.
+
+	* scsi.c: Likewise.
+
+	* qlogic.c: Spelling corrections.
+
+	* in2000.h: Spelling corrections.
+
+	* in2000.c: Update from Bill Earnest, change from
+	jshiffle@netcom.com.  Support new bios versions.
+
+	* README.qlogic: Spelling correction.
+
+Tue Nov 22 15:40:46 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.66 released.
+
+	* u14-34f.c: Spelling corrections.
+
+	* sr.[h,c]: Add support for multi-session CDs from Gerd Knorr.
+
+	* scsi.h: Add manufactor field for keeping track of device
+	manufacturer.
+
+	* scsi.c: More spelling corrections.
+
+	* qlogic.h, qlogic.c, README.qlogic: New driver from Tom Zerucha.
+
+	* in2000.c, in2000.h: New driver from Brad McLean/Bill Earnest.
+
+	* fdomain.c: Spelling correction.
+
+	* eata.c: Spelling correction.
+
+Fri Nov 18 15:22:44 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.65 released.
+
+	* eata.h: Update version string to 1.08.00.
+
+	* eata.c: Set sg_tablesize correctly for DPT PM2012 boards.
+
+	* aha274x.seq: Spell checking.
+
+	* README.st: Likewise.
+
+	* README.aha274x: Likewise.
+
+	* ChangeLog: Likewise.
+
+Tue Nov 15 15:35:08 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.64 released.
+
+	* u14-34f.h: Update version number to 1.10.01.
+
+	* u14-34f.c: Use Scsi_Host can_queue variable instead of one from template.
+
+	* eata.[c,h]: New driver for DPT boards from Dario Ballabio.
+
+	* buslogic.c: Use can_queue field.
+
+Wed Nov 30 12:09:09 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.63 released.
+
+	* sd.c: Give I/O error if we attempt 512 byte I/O to a disk with
+	1024 byte sectors.
+
+	* scsicam.c: Make sure we do read from whole disk (mask off
+	partition).
+
+	* scsi.c: Use can_queue in Scsi_Host structure.
+	Fix panic message about invalid host.
+
+	* hosts.c: Initialize can_queue from template.
+
+	* hosts.h: Add can_queue to Scsi_Host structure.
+
+	* aha1740.c: Print out warning about NULL ecbptr.
+
+Fri Nov  4 12:40:30 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.62 released.
+
+	* fdomain.c: Update to version 5.20. (From Rik Faith).  Support
+	BIOS version 3.5.
+
+	* st.h: Add ST_EOD symbol.
+
+	* st.c: Patches from Kai Makisara - support additional densities,
+	add support for MTFSS, MTBSS, MTWSM commands.
+
+	* README.st: Update to document new commands.
+
+	* scsi.c: Add Mediavision CDR-H93MV to blacklist.
+
+Sat Oct 29 20:57:36 1994  Eric Youngdale  (eric@andante.aib.com)
+
+	* Linux 1.1.60 released.
+
+	* u14-34f.[c,h]: New driver from Dario Ballabio.
+
+	* aic7770.c, aha274x_seq.h, aha274x.seq, aha274x.h, aha274x.c,
+	README.aha274x: New files, new driver from John Aycock.
+
+
+Tue Oct 11 08:47:39 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.54 released.
+
+	* Add third PCI chip id.  [Drew]
+
+	* buslogic.c: Set BUSLOGIC_CMDLUN back to 1 [Eric].
+
+	* ultrastor.c: Fix asm directives for new GCC.
+
+	* sr.c, sd.c: Use new end_scsi_request function.
+
+	* scsi.h(end_scsi_request): Return pointer to block if still
+	active, else return NULL if inactive.  Fixes race condition.
+
+Sun Oct  9 20:23:14 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.53 released.
+
+	* scsi.c: Do not allocate dma bounce buffers if we have exactly
+	16Mb.
+
+Fri Sep  9 05:35:30 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.51 released.
+
+	* aha152x.c: Add support for disabling the parity check.  Update
+	to version 1.4. [Juergen].
+
+	* seagate.c: Tweak debugging message.
+
+Wed Aug 31 10:15:55 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.50 released.
+
+	* aha152x.c: Add eb800 for Vtech Platinum SMP boards. [Juergen].
+
+	* scsi.c: Add Quantum PD1225S to blacklist.
+
+Fri Aug 26 09:38:45 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.49 released.
+
+	* sd.c: Fix bug when we were deleting the wrong entry if we
+	get an unsupported sector size device.
+
+	* sr.c: Another spelling patch.
+
+Thu Aug 25 09:15:27 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.48 released.
+
+	* Throughout: Use new semantics for request_dma, as appropriate.
+
+	* sr.c: Print correct device number.
+
+Sun Aug 21 17:49:23 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.47 released.
+
+	* NCR5380.c: Add support for LIMIT_TRANSFERSIZE.
+
+	* constants.h: Add prototype for print_Scsi_Cmnd.
+
+	* pas16.c: Some more minor tweaks.  Test for Mediavision board.
+	Allow for disks > 1Gb.  [Drew??]
+
+	* sr.c: Set SCpnt->transfersize.
+
+Tue Aug 16 17:29:35 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.46 released.
+
+	* Throughout: More spelling fixups.
+
+	* buslogic.c: Add a few more fixups from Dave.  Disk translation
+	mainly.
+
+	* pas16.c: Add a few patches (Drew?).
+
+
+Thu Aug 11 20:45:15 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.44 released.
+
+	* hosts.c: Add type casts for scsi_init_malloc.
+
+	* scsicam.c: Add type cast.
+
+Wed Aug 10 19:23:01 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.43 released.
+
+	* Throughout: Spelling cleanups. [??]
+
+	* aha152x.c, NCR53*.c, fdomain.c, g_NCR5380.c, pas16.c, seagate.c,
+	 t128.c: Use request_irq, not irqaction. [??]
+
+	* aha1542.c: Move test for shost before we start to use shost.
+
+	* aha1542.c, aha1740.c, ultrastor.c, wd7000.c: Use new
+	calling sequence for request_irq.
+
+	* buslogic.c: Update from Dave Gentzel.
+
+Tue Aug  9 09:32:59 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.42 released.
+
+	* NCR5380.c: Change NCR5380_print_status to static.
+
+	* seagate.c: A few more bugfixes.  Only Drew knows what they are
+	for.
+
+	* ultrastor.c: Tweak some __asm__ directives so that it works
+	with newer compilers. [??]
+
+Sat Aug  6 21:29:36 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.40 released.
+
+	* NCR5380.c: Return SCSI_RESET_WAKEUP from reset function.
+
+	* aha1542.c: Reset mailbox status after a bus device reset.
+
+	* constants.c: Fix typo (;;).
+
+	* g_NCR5380.c:
+	* pas16.c:  Correct usage of NCR5380_init.
+
+	* scsi.c: Remove redundant (and unused variables).
+
+	* sd.c: Use memset to clear all of rscsi_disks before we use it.
+
+	* sg.c: Ditto, except for scsi_generics.
+
+	* sr.c: Ditto, except for scsi_CDs.
+
+	* st.c: Initialize STp->device.
+
+	* seagate.c: Fix bug. [Drew]
+
+Thu Aug  4 08:47:27 1994  Eric Youngdale  (eric@andante)
+
+	* Linux 1.1.39 released.
+
+	* Makefile: Fix typo in NCR53C7xx.
+
+	* st.c: Print correct number for device.
+
+Tue Aug  2 11:29:14 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.38 released.
+
+	Lots of changes in 1.1.38.  All from Drew unless otherwise noted.
+
+	* 53c7,8xx.c: New file from Drew.  PCI driver.
+
+	* 53c7,8xx.h: Likewise.
+
+	* 53c7,8xx.scr: Likewise.
+
+	* 53c8xx_d.h, 53c8xx_u.h, script_asm.pl: Likewise.
+
+	* scsicam.c: New file from Drew.  Read block 0 on the disk and
+	read the partition table.  Attempt to deduce the geometry from
+	the partition table if possible.  Only used by 53c[7,8]xx right
+	now, but could be used by any device for which we have no way
+	of identifying the geometry.
+
+	* sd.c: Use device letters instead of sd%d in a lot of messages.
+
+	* seagate.c: Fix bug that resulted in lockups with some devices.
+
+	* sr.c (sr_open): Return -EROFS, not -EACCES if we attempt to open
+	device for write.
+
+	* hosts.c, Makefile: Update for new driver.
+
+	* NCR5380.c, NCR5380.h, g_NCR5380.h: Update from Drew to support
+	53C400 chip.
+
+	* constants.c: Define CONST_CMND and CONST_MSG.  Other minor
+	cleanups along the way.  Improve handling of CONST_MSG.
+
+	* fdomain.c, fdomain.h: New version from Rik Faith.  Update to
+	5.18.  Should now support TMC-3260 PCI card with 18C30 chip.
+
+	* pas16.c: Update with new irq initialization.
+
+	* t128.c: Update with minor cleanups.
+
+	* scsi.c (scsi_pid): New variable - gives each command a unique
+	id. Add Quantum LPS5235S to blacklist.  Change in_scan to
+	in_scan_scsis and make global.
+
+	* scsi.h: Add some defines for extended message handling,
+	INITIATE/RELEASE_RECOVERY.  Add a few new fields to support sync
+	transfers.
+
+	* scsi_ioctl.h: Add ioctl to request synchronous transfers.
+
+
+Tue Jul 26 21:36:58 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.37 released.
+
+	* aha1542.c: Always call aha1542_mbenable, use new udelay
+	mechanism so we do not wait a long time if the board does not
+	implement this command.
+
+	* g_NCR5380.c: Remove #include <linux/config.h> and #if
+	defined(CONFIG_SCSI_*).
+
+	* seagate.c: Likewise.
+
+	Next round of changes to support loadable modules.  Getting closer
+	now, still not possible to do anything remotely usable.
+
+	hosts.c: Create a linked list of detected high level devices.
+	(scsi_register_device): New function to insert into this list.
+	(scsi_init): Call scsi_register_device for each of the known high
+	level drivers.
+
+	hosts.h: Add prototype for linked list header.  Add structure
+	definition for device template structure which defines the linked
+	list.
+
+	scsi.c: (scan_scsis): Use linked list instead of knowledge about
+	existing high level device drivers.
+	(scsi_dev_init): Use init functions for drivers on linked list
+	instead of explicit list to initialize and attach devices to high
+	level drivers.
+
+	scsi.h: Add new field "attached" to scsi_device - count of number
+	of high level devices attached.
+
+	sd.c, sr.c, sg.c, st.c: Adjust init/attach functions to use new
+	scheme.
+
+Sat Jul 23 13:03:17 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.35 released.
+
+	* ultrastor.c: Change constraint on asm() operand so that it works
+	with gcc 2.6.0.
+
+Thu Jul 21 10:37:39 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.33 released.
+
+	* sr.c(sr_open): Do not allow opens with write access.
+
+Mon Jul 18 09:51:22 1994 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.31 released.
+
+	* sd.c: Increase SD_TIMEOUT from 300 to 600.
+
+	* sr.c: Remove stray task_struct* variable that was no longer
+	used.
+
+	* sr_ioctl.c: Fix typo in up() call.
+
+Sun Jul 17 16:25:29 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.30 released.
+
+	* scsi.c (scan_scsis): Fix detection of some Toshiba CDROM drives
+	that report themselves as disk drives.
+
+	* (Throughout): Use request.sem instead of request.waiting.
+	Should fix swap problem with fdomain.
+
+Thu Jul 14 10:51:42 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.29 released.
+
+	* scsi.c (scan_scsis): Add new devices to end of linked list, not
+	to the beginning.
+
+	* scsi.h (SCSI_SLEEP): Remove brain dead hack to try to save
+	the task state before sleeping.
+
+Sat Jul  9 15:01:03 1994  Eric Youngdale  (eric@esp22)
+
+	More changes to eventually support loadable modules.  Mainly
+	we want to use linked lists instead of arrays because it is easier
+	to dynamically add and remove things this way.
+
+	Quite a bit more work is needed before loadable modules are
+	possible (and usable) with scsi, but this is most of the grunge
+	work.
+
+	* Linux 1.1.28 released.
+
+	* scsi.c, scsi.h (allocate_device, request_queueable): Change
+	argument from index into scsi_devices to a pointer to the
+	Scsi_Device struct.
+
+	* Throughout: Change all calls to allocate_device,
+	request_queueable to use new calling sequence.
+
+	* Throughout: Use SCpnt->device instead of
+	scsi_devices[SCpnt->index].  Ugh - the pointer was there all along
+	- much cleaner this way.
+
+	* scsi.c (scsi_init_malloc, scsi_free_malloc): New functions -
+	allow us to pretend that we have a working malloc when we
+	initialize.  Use this instead of passing memory_start, memory_end
+	around all over the place.
+
+	* scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use
+	scsi_init_malloc, remove all arguments, no return value.
+
+	* scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd
+	structs.
+
+	* scsi.c (scsi_dev_init): Set up for scsi_init_malloc.
+	(scan_scsis): Get SDpnt from scsi_init_malloc, and refresh
+	when we discover a device.  Free pointer before returning.
+	Change scsi_devices into a linked list.
+
+	* scsi.c (scan_scsis): Change to only scan one host.
+	(scsi_dev_init): Loop over all detected hosts, and scan them.
+
+	* hosts.c  (scsi_init_free): Change so that  number of extra bytes
+	is stored in struct, and we do not have to pass it each time.
+
+	* hosts.h: Change Scsi_Host_Template struct to include "next" and
+	"release" functions.  Initialize to NULL in all low level
+	adapters.
+
+	* hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked
+	list scsi_hosts, linked together with the new "next" field.
+
+Wed Jul  6 05:45:02 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.25 released.
+
+	* aha152x.c: Changes from Juergen - cleanups and updates.
+
+	* sd.c, sr.c: Use new check_media_change and revalidate
+	file_operations fields.
+
+	* st.c, st.h: Add changes from Kai Makisara, dated Jun 22.
+
+	* hosts.h: Change SG_ALL back to 0xff.  Apparently soft error
+	in /dev/brain resulted in having this bumped up.
+	Change first parameter in bios_param function to be Disk * instead
+	of index into rscsi_disks.
+
+	* sd_ioctl.c: Pass pointer to rscsi_disks element instead of index
+	to array.
+
+	* sd.h: Add struct name "scsi_disk" to typedef for Scsi_Disk.
+
+	* scsi.c: Remove redundant Maxtor XT8760S from blacklist.
+	In scsi_reset, add printk when DEBUG defined.
+
+	* All low level drivers: Modify definitions of bios_param in
+	appropriate way.
+
+Thu Jun 16 10:31:59 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.20 released.
+
+	* scsi_ioctl.c: Only pass down the actual number of characters
+	required to scsi_do_cmd, not the one rounded up to a even number
+	of sectors.
+
+	* ultrastor.c: Changes from Caleb Epstein for 24f cards.  Support
+	larger SG lists.
+
+	* ultrastor.c: Changes from me - use scsi_register to register
+	host.  Add some consistency checking,
+
+Wed Jun  1 21:12:13 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.19 released.
+
+	* scsi.h: Add new return code for reset() function:
+	SCSI_RESET_PUNT.
+
+	* scsi.c: Make SCSI_RESET_PUNT the same as SCSI_RESET_WAKEUP for
+	now.
+
+	* aha1542.c: If the command responsible for the reset is not
+	pending, return SCSI_RESET_PUNT.
+
+	* aha1740.c, buslogic.c, wd7000.c, ultrastor.c: Return
+	SCSI_RESET_PUNT instead of SCSI_RESET_SNOOZE.
+
+Tue May 31 19:36:01 1994  Eric Youngdale  (eric@esp22)
+
+	* buslogic.c: Do not print out message about "must be Adaptec"
+	if we have detected a buslogic card.  Print out a warning message
+	if we are configuring for >16Mb, since the 445S at board level
+	D or earlier does not work right.  The "D" level board can be made
+	to work by flipping an undocumented switch, but this is too subtle.
+
+    Changes based upon patches in Yggdrasil distribution.
+
+	* sg.c, sg.h: Return sense data to user.
+
+	* aha1542.c, aha1740.c, buslogic.c: Do not panic if
+	sense buffer is wrong size.
+
+	* hosts.c: Test for ultrastor card before any of the others.
+
+	* scsi.c: Allow boot-time option for max_scsi_luns=? so that
+	buggy firmware has an easy work-around.
+
+Sun May 15 20:24:34 1994  Eric Youngdale  (eric@esp22)
+
+	* Linux 1.1.15 released.
+
+	Post-codefreeze thaw...
+
+	* buslogic.[c,h]: New driver from David Gentzel.
+
+	* hosts.h: Add use_clustering field to explicitly say whether
+	clustering should be used for devices attached to this host
+	adapter.  The buslogic board apparently supports large SG lists,
+	but it is apparently faster if sd.c condenses this into a smaller
+	list.
+
+	* sd.c: Use this field instead of heuristic.
+
+	* All host adapter include files: Add appropriate initializer for
+	use_clustering field.
+
+	* scsi.h: Add #defines for return codes for the abort and reset
+	functions.  There are now a specific set of return codes to fully
+	specify all of the possible things that the low-level adapter
+	could do.
+
+	* scsi.c: Act based upon return codes from abort/reset functions.
+
+	* All host adapter abort/reset functions: Return new return code.
+
+	* Add code in scsi.c to help debug timeouts.  Use #define
+	DEBUG_TIMEOUT to enable this.
+
+	* scsi.c: If the host->irq field is set, use
+	disable_irq/enable_irq before calling queuecommand if we
+	are not already in an interrupt.  Reduce races, and we
+	can be sloppier about cli/sti in the interrupt routines now
+	(reduce interrupt latency).
+
+	* constants.c: Fix some things to eliminate warnings.  Add some
+	sense descriptions that were omitted before.
+
+	* aha1542.c: Watch for SCRD from host adapter - if we see it, set
+	a flag.  Currently we only print out the number of pending
+	commands that might need to be restarted.
+
+	* aha1542.c (aha1542_abort): Look for lost interrupts, OGMB still
+	full, and attempt to recover.  Otherwise give up.
+
+	* aha1542.c (aha1542_reset): Try BUS DEVICE RESET, and then pass
+	DID_RESET back up to the upper level code for all commands running
+	on this target (even on different LUNs).
+
+Sat May  7 14:54:01 1994
+
+	* Linux 1.1.12 released.
+
+	* st.c, st.h: New version from Kai.  Supports boot time
+	specification of number of buffers.
+
+	* wd7000.[c,h]: Updated driver from John Boyd.  Now supports
+	more than one wd7000 board in machine at one time, among other things.
+
+Wed Apr 20 22:20:35 1994
+
+	* Linux 1.1.8 released.
+
+	* sd.c: Add a few type casts where scsi_malloc is called.
+
+Wed Apr 13 12:53:29 1994
+
+	* Linux 1.1.4 released.
+
+	* scsi.c: Clean up a few printks (use %p to print pointers).
+
+Wed Apr 13 11:33:02 1994
+
+	* Linux 1.1.3 released.
+
+	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
+	better).
+
+Fri Apr  8 08:57:19 1994
+
+	* Linux 1.1.2 released.
+
+	* Throughout: SCSI portion of cluster diffs added.
+
+Tue Apr  5 07:41:50 1994
+
+	* Linux 1.1 development tree initiated.
+
+	* The linux 1.0 development tree is now effectively frozen except
+	for obvious bugfixes.
+
+******************************************************************
+******************************************************************
+******************************************************************
+******************************************************************
+
+Sun Apr 17 00:17:39 1994
+
+	* Linux 1.0, patchlevel 9 released.
+
+	* fdomain.c: Update to version 5.16 (Handle different FIFO sizes
+	better).
+
+Thu Apr  7 08:36:20 1994
+
+	* Linux 1.0, patchlevel8 released.
+
+	* fdomain.c: Update to version 5.15 from 5.9.  Handles 3.4 bios.
+
+Sun Apr  3 14:43:03 1994
+
+	* Linux 1.0, patchlevel6 released.
+
+	* wd7000.c: Make stab at fixing race condition.
+
+Sat Mar 26 14:14:50 1994
+
+	* Linux 1.0, patchlevel5 released.
+
+	* aha152x.c, Makefile: Fix a few bugs (too much data message).
+	Add a few more bios signatures. (Patches from Juergen).
+
+	* aha1542.c: Fix race condition in aha1542_out.
+
+Mon Mar 21 16:36:20 1994
+
+	* Linux 1.0, patchlevel3 released.
+
+	* sd.c, st.c, sr.c, sg.c: Return -ENXIO, not -ENODEV if we attempt
+	to open a non-existent device.
+
+	* scsi.c: Add Chinon cdrom to blacklist.
+
+	* sr_ioctl.c: Check return status of verify_area.
+
+Sat Mar  6 16:06:19 1994
+
+	* Linux 1.0 released (technically a pre-release).
+
+	* scsi.c: Add IMS CDD521, Maxtor XT-8760S to blacklist.
+
+Tue Feb 15 10:58:20 1994
+
+        * pl15e released.
+
+        * aha1542.c: For 1542C, allow dynamic device scan with >1Gb turned
+	off.
+
+	* constants.c: Fix typo in definition of CONSTANTS.
+
+        * pl15d released.
+
+Fri Feb 11 10:10:16 1994
+
+        * pl15c released.
+
+	* scsi.c: Add Maxtor XT-3280 and Rodime RO3000S to blacklist.
+
+	* scsi.c: Allow tagged queueing for scsi 3 devices as well.
+	Some really old devices report a version number of 0.  Disallow
+	LUN != 0 for these.
+
+Thu Feb 10 09:48:57 1994
+
+        * pl15b released.
+
+Sun Feb  6 12:19:46 1994
+
+        * pl15a released.
+
+Fri Feb  4 09:02:17 1994
+
+        * scsi.c: Add Teac cdrom to blacklist.
+
+Thu Feb  3 14:16:43 1994
+
+	* pl15 released.
+
+Tue Feb  1 15:47:43 1994
+
+	* pl14w released.
+
+	* wd7000.c (wd_bases): Fix typo in last change.
+
+Mon Jan 24 17:37:23 1994
+
+	* pl14u released.
+
+	* aha1542.c: Support 1542CF/extended bios.  Different from 1542C
+
+	* wd7000.c: Allow bios at 0xd8000 as well.
+
+	* ultrastor.c: Do not truncate cylinders to 1024.
+
+	* fdomain.c: Update to version 5.9 (add new bios signature).
+
+	* NCR5380.c: Update from Drew - should work a lot better now.
+
+Sat Jan  8 15:13:10 1994
+
+	* pl14o released.
+
+	* sr_ioctl.c: Zero reserved field before trying to set audio volume.
+
+Wed Jan  5 13:21:10 1994
+
+	* pl14m released.
+
+	* fdomain.c: Update to version 5.8.  No functional difference???
+
+Tue Jan  4 14:26:13 1994
+
+	* pl14l released.
+
+	* ultrastor.c: Remove outl, inl functions (now provided elsewhere).
+
+Mon Jan  3 12:27:25 1994
+
+	* pl14k released.
+
+	* aha152x.c: Remove insw and outsw functions.
+
+	* fdomain.c: Ditto.
+
+Wed Dec 29 09:47:20 1993
+
+	* pl14i released.
+
+	* scsi.c: Support RECOVERED_ERROR for tape drives.
+
+	* st.c: Update of tape driver from Kai.
+
+Tue Dec 21 09:18:30 1993
+
+	* pl14g released.
+
+	* aha1542.[c,h]: Support extended BIOS stuff.
+
+	* scsi.c: Clean up messages about disks, so they are displayed as
+	sda, sdb, etc instead of sd0, sd1, etc.
+
+	* sr.c:  Force reread of capacity if disk was changed.
+	Clear buffer before asking for capacity/sectorsize (some drives
+	do not report this properly).  Set needs_sector_size flag if
+	drive did not return sensible sector size.
+
+Mon Dec 13 12:13:47 1993
+
+	* aha152x.c: Update to version .101 from Juergen.
+
+Mon Nov 29 03:03:00 1993
+
+        * linux 0.99.14 released.
+
+	* All scsi stuff moved from kernel/blk_drv/scsi to drivers/scsi.
+
+	* Throughout: Grammatical corrections to various comments.
+
+	* Makefile: fix so that we do not need to compile things we are
+	not going to use.
+
+	* NCR5380.c, NCR5380.h, g_NCR5380.c, g_NCR5380.h, pas16.c,
+	pas16.h, t128.c, t128.h:  New files from Drew.
+
+	* aha152x.c, aha152x.h: New files from Juergen Fischer.
+
+	* aha1542.c: Support for more than one 1542 in the machine
+	at the same time.  Make functions static that do not need
+	visibility.
+
+	* aha1740.c: Set NEEDS_JUMPSTART flag in reset function, so we
+	know to restart the command.  Change prototype of aha1740_reset
+	to take a command pointer.
+
+	* constants.c: Clean up a few things.
+
+	* fdomain.c: Update to version 5.6.  Move snarf_region.  Allow
+	board to be set at different SCSI ids.  Remove support for
+	reselection (did not work well).  Set JUMPSTART flag in reset
+	code.
+
+	* hosts.c: Support new low-level adapters.  Allow for more than
+	one adapter of a given type.
+
+	* hosts.h: Allow for more than one adapter of a given type.
+
+	* scsi.c:  Add scsi_device_types array, if NEEDS_JUMPSTART is set
+	after a low-level reset, start the command again.  Sort blacklist,
+	and add Maxtor MXT-1240S, XT-4170S, NEC CDROM 84, Seagate ST157N.
+
+	* scsi.h: Add constants for tagged queueing.
+
+	* Throughout: Use constants from major.h instead of hardcoded
+	numbers for major numbers.
+
+	* scsi_ioctl.c: Fix bug in buffer length in ioctl_command.  Use
+	verify_area in GET_IDLUN ioctl.  Add new ioctls for
+	TAGGED_QUEUE_ENABLE, DISABLE.  Only allow IOCTL_SEND_COMMAND by
+	superuser.
+
+	* sd.c: Only pay attention to UNIT_ATTENTION for removable disks.
+	Fix bug where sometimes portions of blocks would get lost
+	resulting in processes hanging.  Add messages when we spin up a
+	disk, and fix a bug in the timing.  Increase read-ahead for disks
+	that are on a scatter-gather capable host adapter.
+
+	* seagate.c: Fix so that some parameters can be set from the lilo
+	prompt.  Supply jumpstart flag if we are resetting and need the
+	command restarted.   Fix so that we return 1 if we detect a card
+	so that multiple card detection works correctly.  Add yet another
+	signature for FD cards (950).  Add another signature for ST0x.
+
+	* sg.c, sg.h: New files from Lawrence Foard for generic scsi
+	access.
+
+	* sr.c:  Add type casts for (void*) so that we can do pointer
+	arithmetic.  Works with GCC without this, but it is not strictly
+	correct.  Same bugfix as was in sd.c.  Increase read-ahead a la
+	disk driver.
+
+	* sr_ioctl.c: Use scsi_malloc buffer instead of buffer from stack
+	since we cannot guarantee that the stack is < 16Mb.
+
+	ultrastor.c: Update to support 24f properly (JFC's driver).
+
+	wd7000.c: Supply jumpstart flag for reset.  Do not round up
+	number of cylinders in biosparam function.
+
+Sat Sep  4 20:49:56 1993
+
+    * 0.99pl13 released.
+
+    * Throughout:  Use check_region/snarf_region for all low-level
+    drivers.
+
+    * aha1542.c: Do hard reset instead of soft (some ethercard probes
+    screw us up).
+
+    * scsi.c: Add new flag ASKED_FOR_SENSE so that we can tell if we are
+    in a loop whereby the device returns null sense data.
+
+    * sd.c: Add code to spin up a drive if it is not already spinning.
+    Do this one at a time to make it easier on power supplies.
+
+    * sd_ioctl.c: Use sync_dev instead of fsync_dev in BLKFLSBUF ioctl.
+
+    * seagate.c: Switch around DATA/CONTROL lines.
+
+    * st.c: Change sense to unsigned.
+
+Thu Aug  5 11:59:18 1993
+
+    * 0.99pl12 released.
+
+    * constants.c, constants.h: New files with ascii descriptions of
+    various conditions.
+
+    * Makefile: Do not try to count the number of low-level drivers,
+    just generate the list of .o files.
+
+    * aha1542.c: Replace 16 with sizeof(SCpnt->sense_buffer).  Add tests
+    for addresses > 16Mb, panic if we find one.
+
+    * aha1740.c: Ditto with sizeof().
+
+    * fdomain.c: Update to version 3.18.  Add new signature, register IRQ
+    with irqaction.  Use ID 7 for new board.  Be more intelligent about
+    obtaining the h/s/c numbers for biosparam.
+
+    * hosts.c: Do not depend upon Makefile generated count of the number
+    of low-level host adapters.
+
+    * scsi.c: Use array for scsi_command_size instead of a function.  Add
+    Texel cdrom and Maxtor XT-4380S to blacklist.  Allow compile time
+    option for no-multi lun scan.  Add semaphore for possible problems
+    with handshaking, assume device is faulty until we know it not to be
+    the case.  Add DEBUG_INIT symbol to dump info as we scan for devices.
+    Zero sense buffer so we can tell if we need to request it.  When
+    examining sense information, request sense if buffer is all zero.
+    If RESET, request sense information to see what to do next.
+
+    * scsi_debug.c: Change some constants to use symbols like INT_MAX.
+
+    * scsi_ioctl.c (kernel_scsi_ioctl): New function -for making ioctl
+    calls from kernel space.
+
+    * sd.c: Increase timeout to 300.  Use functions in constants.h to
+    display info.  Use scsi_malloc buffer for READ_CAPACITY, since
+    we cannot guarantee that a stack based buffer is < 16Mb.
+
+    * sd_ioctl.c: Add BLKFLSBUF ioctl.
+
+    * seagate.c: Add new compile time options for ARBITRATE,
+    SLOW_HANDSHAKE, and SLOW_RATE.  Update assembly loops for transferring
+    data.  Use kernel_scsi_ioctl to request mode page with geometry.
+
+    * sr.c: Use functions in constants.c to display messages.
+
+    * st.c: Support for variable block size.
+
+    * ultrastor.c: Do not use cache for tape drives.  Set
+    unchecked_isa_dma flag, even though this may not be needed (gets set
+    later).
+
+Sat Jul 17 18:32:44 1993
+
+    * 0.99pl11 released.  C++ compilable.
+
+    * Throughout: Add type casts all over the place, and use "ip" instead
+    of "info" in the various biosparam functions.
+
+    * Makefile: Compile seagate.c with C++ compiler.
+
+    * aha1542.c: Always set ccb pointer as this gets trashed somehow on
+    some systems.  Add a few type casts.  Update biosparam function a little.
+
+    * aha1740.c: Add a few type casts.
+
+    * fdomain.c: Update to version 3.17 from 3.6.  Now works with
+    TMC-18C50.
+
+    * scsi.c: Minor changes here and there with datatypes.  Save use_sg
+    when requesting sense information so that this can properly be
+    restored if we retry the command.  Set aside dma buffers assuming each
+    block is 1 page, not 1Kb minix block.
+
+    * scsi_ioctl.c: Add a few type casts.  Other minor changes.
+
+    * sd.c:  Correctly  free all scsi_malloc'd memory if we run out of
+    dma_pool. Store blocksize information for each partition.
+
+    * seagate.c: Minor cleanups here and there.
+
+    * sr.c: Set up blocksize array for all discs.  Fix bug in freeing
+    buffers if we run out of dma pool.
+
+Thu Jun  2 17:58:11 1993
+
+    * 0.99pl10 released.
+
+    * aha1542.c: Support for BT 445S (VL-bus board with no dma channel).
+
+    * fdomain.c: Upgrade to version 3.6. Preliminary support for TNC-18C50.
+
+    * scsi.c: First attempt to fix problem with old_use_sg.  Change
+    NOT_READY to a SUGGEST_ABORT.  Fix timeout race where time might
+    get decremented past zero.
+
+    * sd.c: Add block_fsync function to dispatch table.
+
+    * sr.c: Increase timeout to 500 from 250.  Add entry for sync in
+    dispatch table (supply NULL).  If we do not have a sectorsize,
+    try to get it in the sd_open function.  Add new function just to
+    obtain sectorsize.
+
+    * sr.h: Add needs_sector_size semaphore.
+
+    * st.c: Add NULL for fsync in dispatch table.
+
+    * wd7000.c: Allow another condition for power on that are normal
+    and do not require a panic.
+
+Thu Apr 22 23:10:11 1993
+
+    * 0.99pl9 released.
+
+    * aha1542.c: Use (void) instead of () in setup_mailboxes.
+
+    * scsi.c: Initialize transfersize and underflow fields in SCmd to 0.
+    Do not panic for unsupported message bytes.
+
+    * scsi.h: Allocate 12 bytes instead of 10 for commands.  Add
+    transfersize and underflow fields.
+
+    * scsi_ioctl.c: Further bugfix to ioctl_probe.
+
+    * sd.c: Use long instead of int for last parameter in sd_ioctl.
+    Initialize transfersize and underflow fields.
+
+    * sd_ioctl.c: Ditto for sd_ioctl(,,,,);
+
+    * seagate.c: New version from Drew.  Includes new signatures for FD
+    cards.  Support for 0ws jumper. Correctly initialize
+    scsi_hosts[hostnum].this_id.  Improved handing of
+    disconnect/reconnect, and support command linking.  Use
+    transfersize and underflow fields.  Support scatter-gather.
+
+    * sr.c, sr_ioctl.c: Use long instead of int for last parameter in sr_ioctl.
+    Use buffer and buflength in do_ioctl.  Patches from Chris Newbold for
+    scsi-2 audio commands.
+
+    * ultrastor.c: Comment out in_byte (compiler warning).
+
+    * wd7000.c: Change () to (void) in wd7000_enable_dma.
+
+Wed Mar 31 16:36:25 1993
+
+    * 0.99pl8 released.
+
+    * aha1542.c: Handle mailboxes better for 1542C.
+        Do not truncate number of cylinders at 1024 for biosparam call.
+
+    * aha1740.c: Fix a few minor bugs for multiple devices.
+        Same as above for biosparam.
+
+    * scsi.c: Add lockable semaphore for removable devices that can have
+    media removal prevented.  Add another signature for flopticals.
+    (allocate_device): Fix race condition.  Allow more space in dma pool
+    for blocksizes of up to 4Kb.
+
+    * scsi.h: Define COMMAND_SIZE.  Define a SCSI specific version of
+    INIT_REQUEST that can run with interrupts off.
+
+    * scsi_ioctl.c: Make ioctl_probe function more idiot-proof.  If
+    a removable device says ILLEGAL REQUEST to a door-locking command,
+    clear lockable flag.  Add SCSI_IOCTL_GET_IDLUN ioctl.  Do not attempt
+    to lock door for devices that do not have lockable semaphore set.
+
+    * sd.c: Fix race condition for multiple disks.  Use INIT_SCSI_REQUEST
+    instead of INIT_REQUEST.  Allow sector sizes of 1024 and 256.  For
+    removable disks that are not ready, mark them as having a media change
+    (some drives do not report this later).
+
+    * seagate.c: Use volatile keyword for memory-mapped register pointers.
+
+    * sr.c: Fix race condition, a la sd.c.  Increase the number of retries
+    to 1.  Use INIT_SCSI_REQUEST.  Allow 512 byte sector sizes.  Do a
+    read_capacity when we init the device so we know the size and
+    sectorsize.
+
+    * st.c: If ioctl not found in st.c, try scsi_ioctl for others.
+
+    * ultrastor.c: Do not truncate number of cylinders at 1024 for
+    biosparam call.
+
+    * wd7000.c: Ditto.
+    Throughout: Use COMMAND_SIZE macro to determine length of scsi
+    command.
+
+
+
+Sat Mar 13 17:31:29 1993
+
+    * 0.99pl7 released.
+
+    Throughout: Improve punctuation in some messages, and use new
+    verify_area syntax.
+
+    * aha1542.c: Handle unexpected interrupts better.
+
+    * scsi.c: Ditto.  Handle reset conditions a bit better, asking for
+    sense information and retrying if required.
+
+    * scsi_ioctl.c: Allow for 12 byte scsi commands.
+
+    * ultrastor.c: Update to use scatter-gather.
+
+Sat Feb 20 17:57:15 1993
+
+    * 0.99pl6 released.
+
+    * fdomain.c: Update to version 3.5.  Handle spurious interrupts
+    better.
+
+    * sd.c: Use register_blkdev function.
+
+    * sr.c: Ditto.
+
+    * st.c: Use register_chrdev function.
+
+    * wd7000.c: Undo previous change.
+
+Sat Feb  6 11:20:43 1993
+
+    * 0.99pl5 released.
+
+    * scsi.c: Fix bug in testing for UNIT_ATTENTION.
+
+    * wd7000.c: Check at more addresses for bios.  Fix bug in biosparam
+    (heads & sectors turned around).
+
+Wed Jan 20 18:13:59 1993
+
+    * 0.99pl4 released.
+
+    * scsi.c: Ignore leading spaces when looking for blacklisted devices.
+
+    * seagate.c: Add a few new signatures for FD cards.  Another patch
+    with SCint to fix race condition.  Use recursion_depth to keep track
+    of how many times we have been recursively called, and do not start
+    another command unless we are on the outer level.  Fixes bug
+    with Syquest cartridge drives (used to crash kernel), because
+    they do not disconnect with large data transfers.
+
+Tue Jan 12 14:33:36 1993
+
+    * 0.99pl3 released.
+
+    * fdomain.c: Update to version 3.3 (a few new signatures).
+
+    * scsi.c: Add CDU-541, Denon DRD-25X to blacklist.
+    (allocate_request, request_queueable): Init request.waiting to NULL if
+    non-buffer type of request.
+
+    * seagate.c:  Allow controller to be overridden with CONTROLLER symbol.
+    Set SCint=NULL when we are done, to remove race condition.
+
+    * st.c: Changes from Kai.
+
+Wed Dec 30 20:03:47 1992
+
+    * 0.99pl2 released.
+
+    * scsi.c: Blacklist back in.  Remove Newbury drive as other bugfix
+    eliminates need for it here.
+
+    * sd.c: Return ENODEV instead of EACCES if no such device available.
+    (sd_init) Init blkdev_fops earlier so that sd_open is available sooner.
+
+    * sr.c: Same as above for sd.c.
+
+    * st.c: Return ENODEV instead of ENXIO if no device.  Init chrdev_fops
+    sooner, so that it is always there even if no tapes.
+
+    * seagate.c (controller_type): New variable to keep track of ST0x or
+    FD.  Modify signatures list to indicate controller type, and init
+    controller_type once we find a match.
+
+    * wd7000.c (wd7000_set_sync): Remove redundant function.
+
+Sun Dec 20 16:26:24 1992
+
+    * 0.99pl1 released.
+
+    * scsi_ioctl.c: Bugfix - check dev->index, not dev->id against
+    NR_SCSI_DEVICES.
+
+    * sr_ioctl.c: Verify that device exists before allowing an ioctl.
+
+    * st.c: Patches from Kai - change timeout values, improve end of tape
+    handling.
+
+Sun Dec 13 18:15:23 1992
+
+    * 0.99 kernel released.  Baseline for this ChangeLog.
diff -Nru a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
--- a/Documentation/scsi/scsi_mid_low_api.txt	2004-12-12 18:04:46 -08:00
+++ b/Documentation/scsi/scsi_mid_low_api.txt	2004-12-12 18:04:46 -08:00
@@ -363,8 +363,8 @@
 Mid level supplied functions
 ============================
 These functions are supplied by the SCSI mid level for use by LLDs.
-The names (i.e. entry points) of these functions are exported (mainly in 
-scsi_syms.c) so an LLD that is a module can access them. The kernel will
+The names (i.e. entry points) of these functions are exported 
+so an LLD that is a module can access them. The kernel will
 arrange for the SCSI mid level to be loaded and initialized before any LLD
 is initialized. The functions below are listed alphabetically and their
 names all start with "scsi_".
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/Kconfig	2004-12-12 18:04:46 -08:00
@@ -203,6 +203,14 @@
 	  each attached FiberChannel device to sysfs, say Y.
 	  Otherwise, say N.
 
+config SCSI_ISCSI_ATTRS
+	tristate "iSCSI Transport Attributes"
+	depends on SCSI
+	help
+	  If you wish to export transport-specific information about
+	  each attached iSCSI device to sysfs, say Y.
+	  Otherwise, say N.
+
 endmenu
 
 menu "SCSI low-level drivers"
diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/Makefile	2004-12-12 18:04:46 -08:00
@@ -28,7 +28,7 @@
 # --------------------------
 obj-$(CONFIG_SCSI_SPI_ATTRS)	+= scsi_transport_spi.o
 obj-$(CONFIG_SCSI_FC_ATTRS) 	+= scsi_transport_fc.o
-
+obj-$(CONFIG_SCSI_ISCSI_ATTRS)	+= scsi_transport_iscsi.o
 
 obj-$(CONFIG_SCSI_AMIGA7XX)	+= amiga7xx.o	53c7xx.o
 obj-$(CONFIG_A3000_SCSI)	+= a3000.o	wd33c93.o
@@ -143,7 +143,7 @@
 
 scsi_mod-y			+= scsi.o hosts.o scsi_ioctl.o constants.o \
 				   scsicam.o scsi_error.o scsi_lib.o \
-				   scsi_scan.o scsi_syms.o scsi_sysfs.o \
+				   scsi_scan.o scsi_sysfs.o \
 				   scsi_devinfo.o
 scsi_mod-$(CONFIG_SYSCTL)	+= scsi_sysctl.o
 scsi_mod-$(CONFIG_SCSI_PROC_FS)	+= scsi_proc.o
diff -Nru a/drivers/scsi/aacraid/README b/drivers/scsi/aacraid/README
--- a/drivers/scsi/aacraid/README	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/aacraid/README	2004-12-12 18:04:46 -08:00
@@ -42,7 +42,7 @@
 Christoph Hellwig <hch@infradead.org>	(updates for new-style PCI probing and SCSI host registration,
 					 small cleanups/fixes)
 Matt Domsch <matt_domsch@dell.com>	(revision ioctl, adapter messages)
-Deanna Bonds <deanna_bonds@adaptec.com> (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
+Deanna Bonds                            (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
 					 added new ioctls, changed scsi interface to use new error handler,
 					 increased the number of fibs and outstanding commands to a container)
 
diff -Nru a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c
--- a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c	2004-12-12 18:04:46 -08:00
@@ -64,7 +64,7 @@
  * Description:
  *   Set parameters for the driver from the /proc filesystem.
  *-F*************************************************************************/
-int
+static int
 aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
 {
   proc_debug("aic7xxx_set_info(): %s\n", buffer);
diff -Nru a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
--- a/drivers/scsi/aic7xxx_old.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/aic7xxx_old.c	2004-12-12 18:04:46 -08:00
@@ -1838,7 +1838,7 @@
  * Description:
  *   Return a string describing the driver.
  *-F*************************************************************************/
-const char *
+static const char *
 aic7xxx_info(struct Scsi_Host *dooh)
 {
   static char buffer[256];
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/constants.c	2004-12-12 18:04:46 -08:00
@@ -4,6 +4,7 @@
  * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422)
  * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
  *   by D. Gilbert and aeb (20020609)
+ * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025
  */
 
 #include <linux/config.h>
@@ -15,96 +16,78 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_request.h>
+#include <scsi/scsi_eh.h>
 
 
-#define CONST_COMMAND   0x01
-#define CONST_STATUS    0x02
-#define CONST_SENSE     0x04
-#define CONST_XSENSE    0x08
-#define CONST_CMND      0x10
-#define CONST_MSG       0x20
-#define CONST_HOST	0x40
-#define CONST_DRIVER	0x80
 
-static const char unknown[] = "UNKNOWN";
+/* Commands with service actions that change the command name */
+#define MAINTENANCE_IN 0xa3
+#define MAINTENANCE_OUT 0xa4
+#define SERVICE_ACTION_IN_12 0xab
+#define SERVICE_ACTION_OUT_12 0xa9
+#define SERVICE_ACTION_IN_16 0x9e
+#define SERVICE_ACTION_OUT_16 0x9f
+#define VARIABLE_LENGTH_CMD 0x7f
 
-#ifdef CONFIG_SCSI_CONSTANTS
-#ifdef CONSTANTS
-#undef CONSTANTS
-#endif
-#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE \
-		   | CONST_CMND | CONST_MSG | CONST_HOST | CONST_DRIVER)
-#else
-#define CONSTANTS 0
-#endif
-
-#if (CONSTANTS & CONST_COMMAND)
-static const char * group_0_commands[] = {
-/* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense",
-/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks",
-/* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown,
-/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
-/* 13-16 */ "Verify", "Recover Buffered Data", "Mode Select", "Reserve",
-/* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit",
-/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic", 
-/* 1e-1f */ "Prevent/Allow Medium Removal", unknown,
-};
 
 
-static const char *group_1_commands[] = {
-/* 20-22 */  unknown, unknown, unknown,
-/* 23-28 */ unknown, "Define window parameters", "Read Capacity", 
-            unknown, unknown, "Read (10)", 
-/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase", 
+#ifdef CONFIG_SCSI_CONSTANTS
+static const char * cdb_byte0_names[] = {
+/* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense",
+/* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL,
+	    "Reasssign Blocks",
+/* 08-0d */ "Read (6)", NULL, "Write (6)", "Seek (6)", NULL, NULL,
+/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
+/* 13-16 */ "Verify (6)", "Recover Buffered Data", "Mode Select (6)",
+	    "Reserve (6)",
+/* 17-1a */ "Release (6)", "Copy", "Erase", "Mode Sense (6)", 
+/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", 
+/* 1e-1f */ "Prevent/Allow Medium Removal", NULL,
+/* 20-22 */  NULL, NULL, NULL,
+/* 23-28 */ "Read Format Capacities", "Set Window",
+	    "Read Capacity (10)", NULL, NULL, "Read (10)", 
+/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase (10)", 
             "Read updated block", 
-/* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal", 
-/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position", 
-/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data", 
+/* 2e-31 */ "Write Verify (10)", "Verify (10)", "Search High", "Search Equal", 
+/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", 
+/* 35-37 */ "Synchronize Cache (10)", "Lock/Unlock Cache (10)",
+	    "Read Defect Data(10)", 
 /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", 
             "Read Buffer", 
-/* 3d-3f */ "Update Block", "Read Long",  "Write Long",
-};
-
-
-static const char *group_2_commands[] = {
-/* 40-41 */ "Change Definition", "Write Same",
-/* 42-48 */ "Read sub-channel", "Read TOC", "Read header",
+/* 3d-3f */ "Update Block", "Read Long (10)",  "Write Long (10)",
+/* 40-41 */ "Change Definition", "Write Same (10)",
+/* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support",
             "Play audio (10)", "Get configuration", "Play audio msf",
             "Play audio track/index",
 /* 49-4f */ "Play track relative (10)", "Get event status notification",
             "Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
-            unknown,
+            NULL,
 /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info",
-            "Reserve track", "Send OPC onfo", "Mode Select (10)",
+            "Reserve track", "Send OPC info", "Mode Select (10)",
 /* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue",
             "Mode Sense (10)", "Close track/session",
 /* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in",
             "Persistent reserve out",
-};
-
-
-/* The following are 16 byte commands in group 4 */
-static const char *group_4_commands[] = {
+/* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+/* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+/* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+/* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length",
 /* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy",
             "Receive copy results",
 /* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out",
             "Read (16)", "Memory Export Out (16)",
-/* 8a-8f */ "Write (16)", unknown, "Read attributes", "Write attributes",
+/* 8a-8f */ "Write (16)", NULL, "Read attributes", "Write attributes",
             "Write and verify (16)", "Verify (16)",
 /* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)",
-            "Lock/unlock cache (16)", "Write same (16)", unknown,
-/* 95-99 */ unknown, unknown, unknown, unknown, unknown,
-/* 9a-9f */ unknown, unknown, unknown, unknown, "Service action in",
-            "Service action out",
-};
-
-/* The following are 12 byte commands in group 5 */
-static const char *group_5_commands[] = {
-/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance (in)",
-            "Maintenance (out)", "Move medium/play audio(12)",
+            "Lock/unlock cache (16)", "Write same (16)", NULL,
+/* 95-99 */ NULL, NULL, NULL, NULL, NULL,
+/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in (16)",
+            "Service action out (16)",
+/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance in",
+            "Maintenance out", "Move medium/play audio(12)",
 /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)",
             "Play track relative(12)",
-/* aa-ae */ "Write(12)", unknown, "Erase(12), Get Performance",
+/* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance",
             "Read DVD structure", "Write and verify(12)",
 /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)",
 /* b2-b4 */ "Search data low(12)", "Set limits(12)",
@@ -112,57 +95,279 @@
 /* b5-b6 */ "Request volume element address", "Send volume tag, set streaming",
 /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf",
 /* ba-bc */ "Redundancy group (in), Scan",
-            "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd",
-/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd",
-            "Volume set (out), Send DVD structure",
+            "Redundancy group (out), Set cd-rom speed", "Spare in, Play cd",
+/* bd-bf */ "Spare out, Mechanism status", "Volume set in, Read cd",
+            "Volume set out, Send DVD structure",
+};
+
+struct value_name_pair {
+	int value;
+	const char * name;
+};
+
+static const struct value_name_pair maint_in_arr[] = {
+	{0x5, "Report device identifier"},
+	{0xa, "Report target port groups"},
+	{0xb, "Report aliases"},
+	{0xc, "Report supported operation codes"},
+	{0xd, "Report supported task management functions"},
+	{0xe, "Report priority"},
+};
+#define MAINT_IN_SZ \
+        (int)(sizeof(maint_in_arr) / sizeof(maint_in_arr[0]))
+
+static const struct value_name_pair maint_out_arr[] = {
+	{0x6, "Set device identifier"},
+	{0xa, "Set target port groups"},
+	{0xb, "Change aliases"},
+	{0xe, "Set priority"},
 };
+#define MAINT_OUT_SZ \
+        (int)(sizeof(maint_out_arr) / sizeof(maint_out_arr[0]))
 
+static const struct value_name_pair serv_in12_arr[] = {
+	{0x1, "Read media serial number"},
+};
+#define SERV_IN12_SZ  \
+        (int)(sizeof(serv_in12_arr) / sizeof(serv_in12_arr[0]))
 
+static const struct value_name_pair serv_out12_arr[] = {
+	{-1, "dummy entry"},
+};
+#define SERV_OUT12_SZ \
+        (int)(sizeof(serv_out12_arr) / sizeof(serv_in12_arr[0]))
 
-#define group(opcode) (((opcode) >> 5) & 7)
+static const struct value_name_pair serv_in16_arr[] = {
+	{0x10, "Read capacity(16)"},
+	{0x11, "Read long(16)"},
+};
+#define SERV_IN16_SZ  \
+        (int)(sizeof(serv_in16_arr) / sizeof(serv_in16_arr[0]))
 
-#define RESERVED_GROUP  0
-#define VENDOR_GROUP    1
+static const struct value_name_pair serv_out16_arr[] = {
+	{0x11, "Write long(16)"},
+	{0x1f, "Notify data transfer device(16)"},
+};
+#define SERV_OUT16_SZ \
+        (int)(sizeof(serv_out16_arr) / sizeof(serv_in16_arr[0]))
 
-static const char **commands[] = {
-    group_0_commands, group_1_commands, group_2_commands, 
-    (const char **) RESERVED_GROUP, group_4_commands, 
-    group_5_commands, (const char **) VENDOR_GROUP, 
-    (const char **) VENDOR_GROUP
+static const struct value_name_pair variable_length_arr[] = {
+	{0x1, "Rebuild(32)"},
+	{0x2, "Regenerate(32)"},
+	{0x3, "Xdread(32)"},
+	{0x4, "Xdwrite(32)"},
+	{0x5, "Xdwrite extended(32)"},
+	{0x6, "Xpwrite(32)"},
+	{0x7, "Xdwriteread(32)"},
+	{0x8, "Xdwrite extended(64)"},
+	{0x9, "Read(32)"},
+	{0xa, "Verify(32)"},
+	{0xb, "Write(32)"},
+	{0xc, "Write an verify(32)"},
+	{0xd, "Write same(32)"},
+	{0x8801, "Format OSD"},
+	{0x8802, "Create (osd)"},
+	{0x8803, "List (osd)"},
+	{0x8805, "Read (osd)"},
+	{0x8806, "Write (osd)"},
+	{0x8807, "Append (osd)"},
+	{0x8808, "Flush (osd)"},
+	{0x880a, "Remove (osd)"},
+	{0x880b, "Create partition (osd)"},
+	{0x880c, "Remove partition (osd)"},
+	{0x880e, "Get attributes (osd)"},
+	{0x880f, "Set attributes (osd)"},
+	{0x8812, "Create and write (osd)"},
+	{0x8815, "Create collection (osd)"},
+	{0x8816, "Remove collection (osd)"},
+	{0x8817, "List collection (osd)"},
+	{0x8818, "Set key (osd)"},
+	{0x8819, "Set master key (osd)"},
+	{0x881a, "Flush collection (osd)"},
+	{0x881b, "Flush partition (osd)"},
+	{0x881c, "Flush OSD"},
+	{0x8f7e, "Perform SCSI command (osd)"},
+	{0x8f7f, "Perform task management function (osd)"},
 };
+#define VARIABLE_LENGTH_SZ \
+        (int)(sizeof(variable_length_arr) / sizeof(variable_length_arr[0]))
 
-static const char reserved[] = "RESERVED";
-static const char vendor[] = "VENDOR SPECIFIC";
+static const char * get_sa_name(const struct value_name_pair * arr,
+			        int arr_sz, int service_action)
+{
+	int k;
 
-static void print_opcode(int opcode) {
-    const char **table = commands[ group(opcode) ];
-    switch ((unsigned long) table) {
-    case RESERVED_GROUP:
-	printk("%s(0x%02x) ", reserved, opcode); 
-	break;
-    case VENDOR_GROUP:
-	printk("%s(0x%02x) ", vendor, opcode); 
-	break;
-    default:
-	if (table[opcode & 0x1f] != unknown)
-	    printk("%s ",table[opcode & 0x1f]);
-	else
-	    printk("%s(0x%02x) ", unknown, opcode);
-	break;
-    }
+	for (k = 0; k < arr_sz; ++k, ++arr) {
+		if (service_action == arr->value)
+			break;
+	}
+	return (k < arr_sz) ? arr->name : NULL;
 }
-#else /* CONST & CONST_COMMAND */
-static void print_opcode(int opcode) {
-    printk("0x%02x ", opcode);
+
+/* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */
+static void print_opcode_name(unsigned char * cdbp, int cdb_len,
+			      int start_of_line)
+{
+	int sa, len, cdb0;
+	const char * name;
+	const char * leadin = start_of_line ? KERN_INFO : "";
+
+	cdb0 = cdbp[0];
+	switch(cdb0) {
+	case VARIABLE_LENGTH_CMD:
+		len = cdbp[7] + 8;
+		if (len < 10) {
+			printk("%sshort variable length command, "
+			       "len=%d ext_len=%d", leadin, len, cdb_len);
+			break;
+		}
+		sa = (cdbp[8] << 8) + cdbp[9];
+		name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
+		if (name) {
+			printk("%s%s", leadin, name);
+			if ((cdb_len > 0) && (len != cdb_len))
+				printk(", in_cdb_len=%d, ext_len=%d",
+				       len, cdb_len);
+		} else {
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			if ((cdb_len > 0) && (len != cdb_len))
+				printk(", in_cdb_len=%d, ext_len=%d",
+				       len, cdb_len);
+		}
+		break;
+	case MAINTENANCE_IN:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case MAINTENANCE_OUT:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case SERVICE_ACTION_IN_12:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case SERVICE_ACTION_OUT_12:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case SERVICE_ACTION_IN_16:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	case SERVICE_ACTION_OUT_16:
+		sa = cdbp[1] & 0x1f;
+		name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa);
+		if (name)
+			printk("%s%s", leadin, name);
+		else
+			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	default:
+		if (cdb0 < 0xc0) {
+			name = cdb_byte0_names[cdb0];
+			if (name)
+				printk("%s%s", leadin, name);
+			else
+				printk("%scdb[0]=0x%x (reserved)",
+				       leadin, cdb0);
+		} else
+			printk("%scdb[0]=0x%x (vendor)", leadin, cdb0);
+		break;
+	}
+}
+
+#else /* ifndef CONFIG_SCSI_CONSTANTS */
+
+static void print_opcode_name(unsigned char * cdbp, int cdb_len,
+			      int start_of_line)
+{
+	int sa, len, cdb0;
+	const char * leadin = start_of_line ? KERN_INFO : "";
+
+	cdb0 = cdbp[0];
+	switch(cdb0) {
+	case VARIABLE_LENGTH_CMD:
+		len = cdbp[7] + 8;
+		if (len < 10) {
+			printk("%sshort opcode=0x%x command, len=%d "
+			       "ext_len=%d", leadin, cdb0, len, cdb_len);
+			break;
+		}
+		sa = (cdbp[8] << 8) + cdbp[9];
+		printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		if (len != cdb_len)
+			printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len);
+		break;
+	case MAINTENANCE_IN:
+	case MAINTENANCE_OUT:
+	case SERVICE_ACTION_IN_12:
+	case SERVICE_ACTION_OUT_12:
+	case SERVICE_ACTION_IN_16:
+	case SERVICE_ACTION_OUT_16:
+		sa = cdbp[1] & 0x1f;
+		printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		break;
+	default:
+		if (cdb0 < 0xc0)
+			printk("%scdb[0]=0x%x", leadin, cdb0);
+		else
+			printk("%scdb[0]=0x%x (vendor)", leadin, cdb0);
+		break;
+	}
 }
 #endif  
 
-void __scsi_print_command (unsigned char *command) {
-    int i,s;
-    print_opcode(command[0]);
-    for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) 
-	printk("%02x ", command[i]);
-    printk("\n");
+void __scsi_print_command(unsigned char *command)
+{
+	int k, len;
+
+	print_opcode_name(command, 0, 1);
+	if (VARIABLE_LENGTH_CMD == command[0])
+		len = command[7] + 8;
+	else
+		len = COMMAND_SIZE(command[0]);
+	/* print out all bytes in cdb */
+	for (k = 0; k < len; ++k) 
+		printk(" %02x", command[k]);
+	printk("\n");
+}
+EXPORT_SYMBOL(__scsi_print_command);
+
+/* This function (perhaps with the addition of peripheral device type)
+ * is more approriate than __scsi_print_command(). Perhaps that static
+ * can be dropped later if it replaces the __scsi_print_command version.
+ */
+static void scsi_print_cdb(unsigned char *cdb, int cdb_len, int start_of_line)
+{
+	int k;
+
+	print_opcode_name(cdb, cdb_len, start_of_line);
+	/* print out all bytes in cdb */
+	printk(":");
+	for (k = 0; k < cdb_len; ++k) 
+		printk(" %02x", cdb[k]);
+	printk("\n");
 }
 
 /**
@@ -177,7 +382,7 @@
  **/
 void
 scsi_print_status(unsigned char scsi_status) {
-#if (CONSTANTS & CONST_STATUS)
+#ifdef CONFIG_SCSI_CONSTANTS
 	const char * ccp;
 
 	switch (scsi_status) {
@@ -194,13 +399,14 @@
 	case 0x40: ccp = "Task Aborted"; break;
 	default:   ccp = "Unknown status";
 	}
-	printk("%s", ccp);
+	printk(KERN_INFO "%s", ccp);
 #else
-	printk("0x%0x", scsi_status);
+	printk(KERN_INFO "0x%0x", scsi_status);
 #endif
 }
+EXPORT_SYMBOL(scsi_print_status);
 
-#if (CONSTANTS & CONST_XSENSE)
+#ifdef CONFIG_SCSI_CONSTANTS
 
 struct error_info {
 	unsigned short code12;	/* 0x0302 looks better than 0x03,0x02 */
@@ -253,6 +459,8 @@
 	{0x040C, "Logical unit not accessible, target port in unavailable "
 	 "state"},
 	{0x0410, "Logical unit not ready, auxiliary memory not accessible"},
+	{0x0411, "Logical unit not ready, notify (enable spinup) required"},
+	{0x0412, "Logical unit not ready, offline"},
 
 	{0x0500, "Logical unit does not respond to selection"},
 
@@ -300,7 +508,14 @@
 	{0x0D04, "Copy target device data underrun"},
 	{0x0D05, "Copy target device data overrun"},
 
+	{0x0E00, "Invalid information unit"},
+	{0x0E01, "Information unit too short"},
+	{0x0E02, "Information unit too long"},
+
 	{0x1000, "Id CRC or ECC error"},
+	{0x1001, "Data block guard check failed"},
+	{0x1002, "Data block application tag check failed"},
+	{0x1003, "Data block reference tag check failed"},
 
 	{0x1100, "Unrecovered read error"},
 	{0x1101, "Read retries exhausted"},
@@ -407,8 +622,10 @@
 
 	{0x2400, "Invalid field in cdb"},
 	{0x2401, "CDB decryption error"},
-	{0x2402, "Obsolete"},
-	{0x2403, "Obsolete"},
+	{0x2404, "Security audit value frozen"},
+	{0x2405, "Security working key frozen"},
+	{0x2406, "Nonce not unique"},
+	{0x2407, "Nonce timestamp out of range"},
 
 	{0x2500, "Logical unit not supported"},
 
@@ -426,6 +643,8 @@
 	{0x260B, "Inline data length exceeded"},
 	{0x260C, "Invalid operation for copy source or destination"},
 	{0x260D, "Copy segment granularity violation"},
+	{0x260E, "Invalid parameter while port is enabled"},
+	{0x260F, "Invalid data-out buffer integrity"},
 
 	{0x2700, "Write protected"},
 	{0x2701, "Hardware write protected"},
@@ -455,6 +674,8 @@
 	{0x2A05, "Registrations preempted"},
 	{0x2A06, "Asymmetric access state changed"},
 	{0x2A07, "Implicit asymmetric access state transition failed"},
+	{0x2A08, "Priority changed"},
+	{0x2A09, "Capacity data has changed"},
 
 	{0x2B00, "Copy cannot execute since host cannot disconnect"},
 
@@ -468,6 +689,8 @@
 	{0x2C07, "Previous busy status"},
 	{0x2C08, "Previous task set full status"},
 	{0x2C09, "Previous reservation conflict status"},
+	{0x2C0A, "Partition or collection contains user objects"},
+	{0x2C0B, "Not reserved"},
 
 	{0x2D00, "Overwrite error on update in place"},
 
@@ -485,6 +708,8 @@
 	{0x3007, "Cleaning failure"},
 	{0x3008, "Cannot write - application code mismatch"},
 	{0x3009, "Current session not fixated for append"},
+	{0x300A, "Cleaning request rejected"},
+	{0x300C, "WORM medium, overwrite attempted"},
 	{0x3010, "Medium not formatted"},
 
 	{0x3100, "Medium format corrupted"},
@@ -503,6 +728,7 @@
 	{0x3502, "Enclosure services unavailable"},
 	{0x3503, "Enclosure services transfer failure"},
 	{0x3504, "Enclosure services transfer refused"},
+	{0x3505, "Enclosure services checksum error"},
 
 	{0x3600, "Ribbon, ink, or toner failure"},
 
@@ -543,6 +769,7 @@
 	{0x3B14, "Medium magazine locked"},
 	{0x3B15, "Medium magazine unlocked"},
 	{0x3B16, "Mechanical positioning or changer error"},
+	{0x3B17, "Read past end of user object"},
 
 	{0x3D00, "Invalid bits in identify message"},
 
@@ -570,14 +797,12 @@
 	{0x3F0F, "Echo buffer overwritten"},
 	{0x3F10, "Medium loadable"},
 	{0x3F11, "Medium auxiliary memory accessible"},
-
-#if 0
-	{0x40NN, "Ram failure"},
-	{0x40NN, "Diagnostic failure on component nn"},
-	{0x41NN, "Data path failure"},
-	{0x42NN, "Power-on or self-test failure"},
-#endif
-
+/*
+ *	{0x40NN, "Ram failure"},
+ *	{0x40NN, "Diagnostic failure on component nn"},
+ *	{0x41NN, "Data path failure"},
+ *	{0x42NN, "Power-on or self-test failure"},
+ */
 	{0x4300, "Message error"},
 
 	{0x4400, "Internal target failure"},
@@ -592,6 +817,7 @@
 	{0x4703, "Information unit CRC error detected"},
 	{0x4704, "Asynchronous information protection error detected"},
 	{0x4705, "Protocol service CRC error"},
+	{0x477f, "Some commands cleared by iSCSI Protocol event"},
 
 	{0x4800, "Initiator detected error message received"},
 
@@ -600,13 +826,17 @@
 	{0x4A00, "Command phase error"},
 
 	{0x4B00, "Data phase error"},
+	{0x4B01, "Invalid target port transfer tag received"},
+	{0x4B02, "Too much write data"},
+	{0x4B03, "Ack/nak timeout"},
+	{0x4B04, "Nak received"},
+	{0x4B05, "Data offset error"},
+	{0x4B06, "Initiator response timeout"},
 
 	{0x4C00, "Logical unit failed self-configuration"},
-
-#if 0
-	{0x4DNN, "Tagged overlapped commands (nn = queue tag)"},
-#endif
-
+/*
+ *	{0x4DNN, "Tagged overlapped commands (nn = queue tag)"},
+ */
 	{0x4E00, "Overlapped commands attempted"},
 
 	{0x5000, "Write append error"},
@@ -631,6 +861,7 @@
 	{0x5504, "Insufficient registration resources"},
 	{0x5505, "Insufficient access control resources"},
 	{0x5506, "Auxiliary memory out of space"},
+	{0x5507, "Quota error"},
 
 	{0x5700, "Unable to recover table-of-contents"},
 
@@ -806,11 +1037,9 @@
 	{0x6F03, "Read of scrambled sector without authentication"},
 	{0x6F04, "Media region code is mismatched to logical unit region"},
 	{0x6F05, "Drive region must be permanent/region reset count error"},
-
-#if 0
-	{0x70NN, "Decompression exception short algorithm id of nn"},
-#endif
-
+/*
+ *	{0x70NN, "Decompression exception short algorithm id of nn"},
+ */
 	{0x7100, "Decompression exception long algorithm id"},
 
 	{0x7200, "Session fixation error"},
@@ -845,9 +1074,7 @@
 	{0x70,0x00,0xff,"Decompression exception short algorithm id of %x"},
 	{0, 0, 0, NULL}
 };
-#endif
 
-#if (CONSTANTS & CONST_SENSE)
 /* description of the sense key values */
 static const char *snstext[] = {
 	"No Sense",	    /* 0: There is no sense information */
@@ -858,11 +1085,11 @@
 	"Hardware Error",   /* 4: Controller or device failure */
 	"Illegal Request",  /* 5: Error in request */
 	"Unit Attention",   /* 6: Removable medium was changed, or
-				  the target has been reset */
+				  the target has been reset, or ... */
 	"Data Protect",	    /* 7: Access to the data is blocked */
 	"Blank Check",	    /* 8: Reached unexpected written or unwritten
 				  region of the medium */
-	"Vendor Specific",  /* 9: Vendor specific */
+	"Vendor Specific(9)",
 	"Copy Aborted",	    /* A: COPY or COMPARE was aborted */
 	"Aborted Command",  /* B: The target aborted the command */
 	"Equal",	    /* C: A SEARCH DATA command found data equal */
@@ -875,20 +1102,21 @@
 /* Get sense key string or NULL if not available */
 const char *
 scsi_sense_key_string(unsigned char key) {
-#if (CONSTANTS & CONST_SENSE)
+#ifdef CONFIG_SCSI_CONSTANTS
 	if (key <= 0xE)
 		return snstext[key];
 #endif
 	return NULL;
 }
+EXPORT_SYMBOL(scsi_sense_key_string);
 
 /*
- * Get extended sense key string or NULL if not available.
- * This string may contain a %x and must be printed with ascq as arg.
+ * Get additional sense code string or NULL if not available.
+ * This string may contain a "%x" and should be printed with ascq as arg.
  */
 const char *
 scsi_extd_sense_format(unsigned char asc, unsigned char ascq) {
-#if (CONSTANTS & CONST_XSENSE)
+#ifdef CONFIG_SCSI_CONSTANTS
 	int i;
 	unsigned short code = ((asc << 8) | ascq);
 
@@ -903,18 +1131,27 @@
 #endif
 	return NULL;
 }
+EXPORT_SYMBOL(scsi_extd_sense_format);
 
-/* Print extended sense information */
+/* Print extended sense information; no leadin, no linefeed */
 static void
-scsi_show_extd_sense(unsigned char asc, unsigned char ascq) {
+scsi_show_extd_sense(unsigned char asc, unsigned char ascq)
+{
 	const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq);
 
 	if (extd_sense_fmt) {
-		printk("Additional sense: ");
-		printk(extd_sense_fmt, ascq);
-		printk("\n");
+		if (strstr(extd_sense_fmt, "%x")) {
+			printk("Additional sense: ");
+			printk(extd_sense_fmt, ascq);
+		} else
+			printk("Additional sense: %s", extd_sense_fmt);
 	} else {
-		printk("ASC=%2x ASCQ=%2x\n", asc, ascq);
+		if (asc >= 0x80)
+			printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc, ascq);
+		if (ascq >= 0x80)
+			printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc, ascq);
+		else
+			printk("ASC=0x%x ASCQ=0x%x", asc, ascq);
 	}
 }
 
@@ -922,112 +1159,117 @@
 static void
 print_sense_internal(const char *devclass, 
 		     const unsigned char *sense_buffer,
+		     int sense_len,
 		     struct request *req)
 {
-	int s, sense_class, valid, code, info;
-	const char *error = NULL;
-	unsigned char asc, ascq;
+	int k, num, res;
+	unsigned int info;
+	const char *error;
 	const char *sense_txt;
 	const char *name = req->rq_disk ? req->rq_disk->disk_name : devclass;
+	struct scsi_sense_hdr ssh;
     
-	sense_class = (sense_buffer[0] >> 4) & 0x07;
-	code = sense_buffer[0] & 0xf;
-	valid = sense_buffer[0] & 0x80;
-    
-	if (sense_class == 7) {	/* extended sense data */
-		s = sense_buffer[7] + 8;
-		if (s > SCSI_SENSE_BUFFERSIZE)
-			s = SCSI_SENSE_BUFFERSIZE;
-	
-		info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
-			(sense_buffer[5] << 8) | sense_buffer[6]);
-		if (info || valid) {
-			printk("Info fld=0x%x", info);
-			if (!valid)	/* info data not according to standard */
-				printk(" (nonstd)");
-			printk(", ");
-		}
-		if (sense_buffer[2] & 0x80)
-			printk( "FMK ");	/* current command has read a filemark */
-		if (sense_buffer[2] & 0x40)
-			printk( "EOM ");	/* end-of-medium condition exists */
-		if (sense_buffer[2] & 0x20)
-			printk( "ILI ");	/* incorrect block length requested */
-	
-		switch (code) {
-		case 0x0:
-			error = "Current";	/* error concerns current command */
-			break;
-		case 0x1:
-			error = "Deferred";	/* error concerns some earlier command */
-			/* e.g., an earlier write to disk cache succeeded, but
-			   now the disk discovers that it cannot write the data */
-			break;
-		default:
-			error = "Invalid";
+	res = scsi_normalize_sense(sense_buffer, sense_len, &ssh);
+	if (0 == res) {
+		/* this may be SCSI-1 sense data */
+		num = (sense_len < 32) ? sense_len : 32;
+		printk(KERN_INFO "Unrecognized sense data (in hex):");
+		for (k = 0; k < num; ++k) {
+			if (0 == (k % 16)) {
+				printk("\n");
+				printk(KERN_INFO "        ");
+			}
+			printk("%02x ", sense_buffer[k]);
 		}
+		printk("\n");
+		return;
+	}
 
-		printk("%s ", error);
+	/* An example of deferred is when an earlier write to disk cache
+	 * succeeded, but now the disk discovers that it cannot write the
+	 * data to the magnetic media.
+	 */
+	error = scsi_sense_is_deferred(&ssh) ? 
+			"<<DEFERRED>>" : "Current";
+	printk(KERN_INFO "%s: %s", name, error);
+	if (ssh.response_code >= 0x72)
+		printk(" [descriptor]");
+
+	sense_txt = scsi_sense_key_string(ssh.sense_key);
+	if (sense_txt)
+		printk(": sense key: %s\n", sense_txt);
+	else
+		printk(": sense key=0x%x\n", ssh.sense_key);
+	printk(KERN_INFO "    ");
+	scsi_show_extd_sense(ssh.asc, ssh.ascq);
+	printk("\n");
 
-		sense_txt = scsi_sense_key_string(sense_buffer[2]);
-		if (sense_txt)
-			printk("%s: sense key %s\n", name, sense_txt);
-		else
-			printk("%s: sense = %2x %2x\n", name,
-			       sense_buffer[0], sense_buffer[2]);
+	if (ssh.response_code < 0x72) {
+		/* only decode extras for "fixed" format now */
+		char buff[80];
+		int blen, fixed_valid;
 
-		asc = ascq = 0;
-		if (sense_buffer[7] + 7 >= 13) {
-			asc = sense_buffer[12];
-			ascq = sense_buffer[13];
+		fixed_valid = sense_buffer[0] & 0x80;
+		info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
+			(sense_buffer[5] << 8) | sense_buffer[6]);
+		res = 0;
+		memset(buff, 0, sizeof(buff));
+		blen = sizeof(buff) - 1;
+		if (fixed_valid)
+			res += snprintf(buff + res, blen - res,
+					"Info fld=0x%x", info);
+		if (sense_buffer[2] & 0x80) {
+			/* current command has read a filemark */
+			if (res > 0)
+				res += snprintf(buff + res, blen - res, ", ");
+			res += snprintf(buff + res, blen - res, "FMK");
 		}
-		if (asc || ascq)
-			scsi_show_extd_sense(asc, ascq);
-
-	} else {	/* non-extended sense data */
-
-		/*
-		 * Standard says:
-		 *    sense_buffer[0] & 0200 : address valid
-		 *    sense_buffer[0] & 0177 : vendor-specific error code
-		 *    sense_buffer[1] & 0340 : vendor-specific
-		 *    sense_buffer[1..3] : 21-bit logical block address
-		 */
-
-		sense_txt = scsi_sense_key_string(sense_buffer[0]);
-		if (sense_txt)
-			printk("%s: old sense key %s\n", name, sense_txt);
-		else
-			printk("%s: sense = %2x %2x\n", name,
-			       sense_buffer[0], sense_buffer[2]);
-
-		printk("Non-extended sense class %d code 0x%0x\n",
-		       sense_class, code);
-		s = 4;
-	}
-    
-#if !(CONSTANTS & CONST_SENSE)
-	{
-		int i;
-	printk("Raw sense data:");
-	for (i = 0; i < s; ++i) 
-		printk("0x%02x ", sense_buffer[i]);
-	printk("\n");
+		if (sense_buffer[2] & 0x40) {
+			/* end-of-medium condition exists */
+			if (res > 0)
+				res += snprintf(buff + res, blen - res, ", ");
+			res += snprintf(buff + res, blen - res, "EOM");
+		}
+		if (sense_buffer[2] & 0x20) {
+			/* incorrect block length requested */
+			if (res > 0)
+				res += snprintf(buff + res, blen - res, ", ");
+			res += snprintf(buff + res, blen - res, "ILI");
+		}
+		if (res > 0)
+			printk(KERN_INFO "%s\n", buff);
+	} else if (ssh.additional_length > 0) {
+		/* descriptor format with sense descriptors */
+		num = 8 + ssh.additional_length;
+		num = (sense_len < num) ? sense_len : num;
+		printk(KERN_INFO "Descriptor sense data with sense "
+		       "descriptors (in hex):");
+		for (k = 0; k < num; ++k) {
+			if (0 == (k % 16)) {
+				printk("\n");
+				printk(KERN_INFO "        ");
+			}
+			printk("%02x ", sense_buffer[k]);
+		}
+		printk("\n");
 	}
-#endif
 }
 
 void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd)
 {
-	print_sense_internal(devclass, cmd->sense_buffer, cmd->request);
+	print_sense_internal(devclass, cmd->sense_buffer,
+			     SCSI_SENSE_BUFFERSIZE, cmd->request);
 }
+EXPORT_SYMBOL(scsi_print_sense);
 
 void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq)
 {
-	print_sense_internal(devclass, sreq->sr_sense_buffer, sreq->sr_request);
+	print_sense_internal(devclass, sreq->sr_sense_buffer,
+			     SCSI_SENSE_BUFFERSIZE, sreq->sr_request);
 }
+EXPORT_SYMBOL(scsi_print_req_sense);
 
-#if (CONSTANTS & CONST_MSG) 
+#ifdef CONFIG_SCSI_CONSTANTS
 static const char *one_byte_msgs[] = {
 /* 0x00 */ "Command Complete", NULL, "Save Pointers",
 /* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
@@ -1036,161 +1278,167 @@
 /* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
 /* 0x0f */ "Initiate Recovery", "Release Recovery"
 };
-
 #define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs)  / sizeof (const char *))
 
 static const char *two_byte_msgs[] = {
 /* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag"
 /* 0x23 */ "Ignore Wide Residue"
 };
-
 #define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
 
 static const char *extended_msgs[] = {
 /* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
 /* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request"
 };
-
 #define NO_EXTENDED_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
-#endif /* (CONSTANTS & CONST_MSG) */
 
-int scsi_print_msg (const unsigned char *msg) {
-    int len = 0, i;
-    if (msg[0] == EXTENDED_MESSAGE) {
-	len = 3 + msg[1];
-#if (CONSTANTS & CONST_MSG)
-	if (msg[2] < NO_EXTENDED_MSGS)
-	    printk ("%s ", extended_msgs[msg[2]]); 
-	else 
-	    printk ("Extended Message, reserved code (0x%02x) ", (int) msg[2]);
-	switch (msg[2]) {
-	case EXTENDED_MODIFY_DATA_POINTER:
-	    printk("pointer = %d", (int) (msg[3] << 24) | (msg[4] << 16) | 
-		   (msg[5] << 8) | msg[6]);
-	    break;
-	case EXTENDED_SDTR:
-	    printk("period = %d ns, offset = %d", (int) msg[3] * 4, (int) 
-		   msg[4]);
-	    break;
-	case EXTENDED_WDTR:
-	    printk("width = 2^%d bytes", msg[3]);
-	    break;
-	default:
-	    for (i = 2; i < len; ++i) 
-		printk("%02x ", msg[i]);
-	}
-#else
-	for (i = 0; i < len; ++i)
-	    printk("%02x ", msg[i]);
-#endif
+
+int scsi_print_msg (const unsigned char *msg)
+{
+	int len = 0, i;
+	if (msg[0] == EXTENDED_MESSAGE) {
+		len = 3 + msg[1];
+		if (msg[2] < NO_EXTENDED_MSGS)
+			printk ("%s ", extended_msgs[msg[2]]); 
+		else 
+			printk ("Extended Message, reserved code (0x%02x) ",
+				(int) msg[2]);
+		switch (msg[2]) {
+		case EXTENDED_MODIFY_DATA_POINTER:
+			printk("pointer = %d", (int) (msg[3] << 24) |
+				(msg[4] << 16) | (msg[5] << 8) | msg[6]);
+			break;
+		case EXTENDED_SDTR:
+			printk("period = %d ns, offset = %d",
+				(int) msg[3] * 4, (int) msg[4]);
+			break;
+		case EXTENDED_WDTR:
+			printk("width = 2^%d bytes", msg[3]);
+			break;
+		default:
+		for (i = 2; i < len; ++i) 
+			printk("%02x ", msg[i]);
+		}
 	/* Identify */
-    } else if (msg[0] & 0x80) {
-#if (CONSTANTS & CONST_MSG)
-	printk("Identify disconnect %sallowed %s %d ",
-	       (msg[0] & 0x40) ? "" : "not ",
-	       (msg[0] & 0x20) ? "target routine" : "lun",
-	       msg[0] & 0x7);
-#else
-	printk("%02x ", msg[0]);
-#endif
-	len = 1;
+	} else if (msg[0] & 0x80) {
+		printk("Identify disconnect %sallowed %s %d ",
+			(msg[0] & 0x40) ? "" : "not ",
+			(msg[0] & 0x20) ? "target routine" : "lun",
+			msg[0] & 0x7);
+		len = 1;
 	/* Normal One byte */
-    } else if (msg[0] < 0x1f) {
-#if (CONSTANTS & CONST_MSG)
-	if (msg[0] < NO_ONE_BYTE_MSGS)
-	    printk(one_byte_msgs[msg[0]]);
-	else
-	    printk("reserved (%02x) ", msg[0]);
-#else
-	printk("%02x ", msg[0]);
-#endif
-	len = 1;
+	} else if (msg[0] < 0x1f) {
+		if (msg[0] < NO_ONE_BYTE_MSGS)
+			printk(one_byte_msgs[msg[0]]);
+		else
+			printk("reserved (%02x) ", msg[0]);
+		len = 1;
 	/* Two byte */
-    } else if (msg[0] <= 0x2f) {
-#if (CONSTANTS & CONST_MSG)
-	if ((msg[0] - 0x20) < NO_TWO_BYTE_MSGS)
-	    printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
-		   msg[1]);
-	else 
-	    printk("reserved two byte (%02x %02x) ", 
-		   msg[0], msg[1]);
-#else
-	printk("%02x %02x", msg[0], msg[1]);
-#endif
-	len = 2;
-    } else 
-#if (CONSTANTS & CONST_MSG)
-	printk(reserved);
-#else
-    printk("%02x ", msg[0]);
-#endif
-    return len;
+	} else if (msg[0] <= 0x2f) {
+		if ((msg[0] - 0x20) < NO_TWO_BYTE_MSGS)
+			printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
+				msg[1]);
+		else 
+			printk("reserved two byte (%02x %02x) ", 
+				msg[0], msg[1]);
+		len = 2;
+	} else 
+		printk("reserved");
+	return len;
 }
+EXPORT_SYMBOL(scsi_print_msg);
 
-void scsi_print_command(struct scsi_cmnd *cmd) {
-    printk("scsi%d : destination target %d, lun %d\n", 
-	   cmd->device->host->host_no, 
-	   cmd->device->id, 
-	   cmd->device->lun);
-    printk("        command = ");
-    __scsi_print_command(cmd->cmnd);
+#else  /* ifndef CONFIG_SCSI_CONSTANTS */
+
+int scsi_print_msg (const unsigned char *msg)
+{
+	int len = 0, i;
+
+	if (msg[0] == EXTENDED_MESSAGE) {
+		len = 3 + msg[1];
+		for (i = 0; i < len; ++i)
+			printk("%02x ", msg[i]);
+	/* Identify */
+	} else if (msg[0] & 0x80) {
+		printk("%02x ", msg[0]);
+		len = 1;
+	/* Normal One byte */
+	} else if (msg[0] < 0x1f) {
+		printk("%02x ", msg[0]);
+		len = 1;
+	/* Two byte */
+	} else if (msg[0] <= 0x2f) {
+		printk("%02x %02x", msg[0], msg[1]);
+		len = 2;
+	} else 
+		printk("%02x ", msg[0]);
+	return len;
+}
+EXPORT_SYMBOL(scsi_print_msg);
+#endif /* ! CONFIG_SCSI_CONSTANTS */
+
+void scsi_print_command(struct scsi_cmnd *cmd)
+{
+	/* Assume appended output (i.e. not at start of line) */
+	printk("scsi%d : destination target %d, lun %d\n", 
+		cmd->device->host->host_no, 
+		cmd->device->id, 
+		cmd->device->lun);
+	printk(KERN_INFO "        command: ");
+	scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0);
 }
+EXPORT_SYMBOL(scsi_print_command);
+
+#ifdef CONFIG_SCSI_CONSTANTS
 
-#if (CONSTANTS & CONST_HOST)
 static const char * hostbyte_table[]={
 "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", 
 "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
-"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", NULL};
+"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"};
+#define NUM_HOSTBYTE_STRS (sizeof(hostbyte_table) / sizeof(const char *))
 
 void scsi_print_hostbyte(int scsiresult)
-{   static int maxcode=0;
-    int i;
-   
-    if(!maxcode) {
-	for(i=0;hostbyte_table[i];i++) ;
-	maxcode=i-1;
-    }
-    printk("Hostbyte=0x%02x",host_byte(scsiresult));
-    if(host_byte(scsiresult)>maxcode) {
-	printk("is invalid "); 
-	return;
-    }
-    printk("(%s) ",hostbyte_table[host_byte(scsiresult)]);
+{
+	int hb = host_byte(scsiresult);
+
+	printk("Hostbyte=0x%02x", hb);
+	if (hb < NUM_HOSTBYTE_STRS)
+		printk("(%s) ", hostbyte_table[hb]);
+	else
+		printk("is invalid "); 
 }
 #else
 void scsi_print_hostbyte(int scsiresult)
-{   printk("Hostbyte=0x%02x ",host_byte(scsiresult));
+{
+	printk("Hostbyte=0x%02x ", host_byte(scsiresult));
 }
 #endif
 
-#if (CONSTANTS & CONST_DRIVER)
+#ifdef CONFIG_SCSI_CONSTANTS
+
 static const char * driverbyte_table[]={
 "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT",  "DRIVER_MEDIA", "DRIVER_ERROR", 
-"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD",NULL };
+"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
+#define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *))
 
 static const char * driversuggest_table[]={"SUGGEST_OK",
 "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
-unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
-
+"SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
+#define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *))
 
 void scsi_print_driverbyte(int scsiresult)
-{   static int driver_max=0,suggest_max=0;
-    int i,dr=driver_byte(scsiresult)&DRIVER_MASK, 
-	su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4;
-
-    if(!driver_max) {
-        for(i=0;driverbyte_table[i];i++) ;
-        driver_max=i;
-	for(i=0;driversuggest_table[i];i++) ;
-	suggest_max=i;
-    }
-    printk("Driverbyte=0x%02x",driver_byte(scsiresult));
-    printk("(%s,%s) ",
-	dr<driver_max  ? driverbyte_table[dr]:"invalid",
-	su<suggest_max ? driversuggest_table[su]:"invalid");
+{
+	int dr = (driver_byte(scsiresult) & DRIVER_MASK);
+	int su = ((driver_byte(scsiresult) & SUGGEST_MASK) >> 4);
+
+	printk("Driverbyte=0x%02x ", driver_byte(scsiresult));
+	printk("(%s,%s) ",
+	       (dr < NUM_DRIVERBYTE_STRS ? driverbyte_table[dr] : "invalid"),
+	       (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid"));
 }
 #else
 void scsi_print_driverbyte(int scsiresult)
-{   printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
+{
+	printk("Driverbyte=0x%02x ", driver_byte(scsiresult));
 }
 #endif
diff -Nru a/drivers/scsi/dpt/dpti_ioctl.h b/drivers/scsi/dpt/dpti_ioctl.h
--- a/drivers/scsi/dpt/dpti_ioctl.h	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/dpt/dpti_ioctl.h	2004-12-12 18:04:46 -08:00
@@ -3,7 +3,6 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2001 by Adaptec
-    email                : deanna_bonds@adaptec.com
 
     See Documentation/scsi/dpti.txt for history, notes, license info
     and credits
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/dpt_i2o.c	2004-12-12 18:04:46 -08:00
@@ -3,7 +3,6 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2000 by Adaptec
-    email                : deanna_bonds@adaptec.com
 
 			   July 30, 2001 First version being submitted
 			   for inclusion in the kernel.  V2.4
diff -Nru a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
--- a/drivers/scsi/dpti.h	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/dpti.h	2004-12-12 18:04:46 -08:00
@@ -3,7 +3,6 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2001 by Adaptec
-    email                : deanna_bonds@adaptec.com
 
     See Documentation/scsi/dpti.txt for history, notes, license info
     and credits
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/eata.c	2004-12-12 18:04:46 -08:00
@@ -505,28 +505,29 @@
 static int eata2x_detect(struct scsi_host_template *);
 static int eata2x_release(struct Scsi_Host *);
 static int eata2x_queuecommand(struct scsi_cmnd *,
-		void (*done)(struct scsi_cmnd *));
+			       void (*done) (struct scsi_cmnd *));
 static int eata2x_eh_abort(struct scsi_cmnd *);
 static int eata2x_eh_host_reset(struct scsi_cmnd *);
 static int eata2x_bios_param(struct scsi_device *, struct block_device *,
-                             sector_t, int *);
+			     sector_t, int *);
 static int eata2x_slave_configure(struct scsi_device *);
 
 static struct scsi_host_template driver_template = {
-                .name                    = "EATA/DMA 2.0x rev. 8.10.00 ",
-                .detect                  = eata2x_detect,
-                .release                 = eata2x_release,
-                .queuecommand            = eata2x_queuecommand,
-                .eh_abort_handler        = eata2x_eh_abort,
-                .eh_device_reset_handler = NULL,
-                .eh_bus_reset_handler    = NULL,
-                .eh_host_reset_handler   = eata2x_eh_host_reset,
-                .bios_param              = eata2x_bios_param,
-                .slave_configure         = eata2x_slave_configure,
-                .this_id                 = 7,
-                .unchecked_isa_dma       = 1,
-                .use_clustering          = ENABLE_CLUSTERING
-                };
+	.name = "EATA/DMA 2.0x rev. 8.10.00 ",
+	.detect = eata2x_detect,
+	.release = eata2x_release,
+	.queuecommand = eata2x_queuecommand,
+	.eh_abort_handler = eata2x_eh_abort,
+	.eh_device_reset_handler = NULL,
+	.eh_bus_reset_handler = NULL,
+	.eh_host_reset_handler = eata2x_eh_host_reset,
+	.bios_param = eata2x_bios_param,
+	.slave_configure = eata2x_slave_configure,
+	.this_id = 7,
+	.unchecked_isa_dma = 1,
+	.use_clustering = ENABLE_CLUSTERING
+};
+
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 #error "Adjust your <asm/byteorder.h> defines"
 #endif
@@ -618,188 +619,224 @@
 
 /* Board info structure */
 struct eata_info {
-   u_int32_t data_len;  /* Number of valid bytes after this field */
-   u_int32_t sign;      /* ASCII "EATA" signature */
+	u_int32_t data_len;	/* Number of valid bytes after this field */
+	u_int32_t sign;		/* ASCII "EATA" signature */
 
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar version:4, :4;
-   unchar  haaval:1, ata:1, drqvld:1, dmasup:1, morsup:1, trnxfr:1, tarsup:1,
-           ocsena:1;
+	unchar version	: 4,
+	       		: 4;
+	unchar haaval	: 1,
+	       ata	: 1,
+	       drqvld	: 1,
+	       dmasup	: 1,
+	       morsup	: 1,
+	       trnxfr	: 1,
+	       tarsup	: 1,
+	       ocsena	: 1;
 #else
-   unchar        :4,    /* unused low nibble */
-          version:4;    /* EATA version, should be 0x1 */
-   unchar  ocsena:1,    /* Overlap Command Support Enabled */
-           tarsup:1,    /* Target Mode Supported */
-           trnxfr:1,    /* Truncate Transfer Cmd NOT Necessary */
-           morsup:1,    /* More Supported */
-           dmasup:1,    /* DMA Supported */
-           drqvld:1,    /* DRQ Index (DRQX) is valid */
-              ata:1,    /* This is an ATA device */
-           haaval:1;    /* Host Adapter Address Valid */
-#endif
-
-   ushort cp_pad_len;   /* Number of pad bytes after cp_len */
-   unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
-   u_int32_t cp_len;    /* Number of valid bytes in cp */
-   u_int32_t sp_len;    /* Number of valid bytes in sp */
-   ushort queue_size;   /* Max number of cp that can be queued */
-   ushort unused;
-   ushort scatt_size;   /* Max number of entries in scatter/gather table */
+	unchar		: 4,	/* unused low nibble */
+	 	version	: 4;	/* EATA version, should be 0x1 */
+	unchar ocsena	: 1,	/* Overlap Command Support Enabled */
+	       tarsup	: 1,	/* Target Mode Supported */
+	       trnxfr	: 1,	/* Truncate Transfer Cmd NOT Necessary */
+	       morsup	: 1,	/* More Supported */
+	       dmasup	: 1,	/* DMA Supported */
+	       drqvld	: 1,	/* DRQ Index (DRQX) is valid */
+	       ata	: 1,	/* This is an ATA device */
+	       haaval	: 1;	/* Host Adapter Address Valid */
+#endif
+
+	ushort cp_pad_len;	/* Number of pad bytes after cp_len */
+	unchar host_addr[4];	/* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
+	u_int32_t cp_len;	/* Number of valid bytes in cp */
+	u_int32_t sp_len;	/* Number of valid bytes in sp */
+	ushort queue_size;	/* Max number of cp that can be queued */
+	ushort unused;
+	ushort scatt_size;	/* Max number of entries in scatter/gather table */
 
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar    drqx:2, second:1, irq_tr:1, irq:4;
-   unchar  sync;
-   unchar         :4, res1:1, large_sg:1, forcaddr:1, isaena:1;
-   unchar max_chan:3, max_id:5;
-   unchar   max_lun;
-   unchar     eisa:1, pci:1, idquest:1, m1:1, :4;
+	unchar drqx	: 2,
+	       second	: 1,
+	       irq_tr	: 1,
+	       irq	: 4;
+	unchar sync;
+	unchar		: 4,
+	       res1	: 1,
+	       large_sg	: 1,
+	       forcaddr	: 1,
+	       isaena	: 1;
+	unchar max_chan	: 3,
+	       max_id	: 5;
+	unchar max_lun;
+	unchar eisa	: 1,
+	       pci	: 1,
+	       idquest	: 1,
+	       m1	: 1,
+	       		: 4;
 #else
-   unchar     irq:4,    /* Interrupt Request assigned to this controller */
-           irq_tr:1,    /* 0 for edge triggered, 1 for level triggered */
-           second:1,    /* 1 if this is a secondary (not primary) controller */
-             drqx:2;    /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
-   unchar  sync;        /* 1 if scsi target id 7...0 is running sync scsi */
-
-   /* Structure extension defined in EATA 2.0B */
-   unchar  isaena:1,    /* ISA i/o addressing is disabled/enabled */
-         forcaddr:1,    /* Port address has been forced */
-         large_sg:1,    /* 1 if large SG lists are supported */
-             res1:1,
-                 :4;
-   unchar  max_id:5,    /* Max SCSI target ID number */
-         max_chan:3;    /* Max SCSI channel number on this board */
-
-   /* Structure extension defined in EATA 2.0C */
-   unchar   max_lun;    /* Max SCSI LUN number */
-   unchar        :4,
-               m1:1,    /* This is a PCI with an M1 chip installed */
-          idquest:1,    /* RAIDNUM returned is questionable */
-              pci:1,    /* This board is PCI */
-             eisa:1;    /* This board is EISA */
+	unchar irq	: 4,	/* Interrupt Request assigned to this controller */
+	       irq_tr	: 1,	/* 0 for edge triggered, 1 for level triggered */
+	       second	: 1,	/* 1 if this is a secondary (not primary) controller */
+	       drqx	: 2;	/* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
+	unchar sync;		/* 1 if scsi target id 7...0 is running sync scsi */
+
+	/* Structure extension defined in EATA 2.0B */
+	unchar isaena	: 1,	/* ISA i/o addressing is disabled/enabled */
+	       forcaddr	: 1,	/* Port address has been forced */
+	       large_sg	: 1,	/* 1 if large SG lists are supported */
+	       res1	: 1,
+	       		: 4;
+	unchar max_id	: 5,	/* Max SCSI target ID number */
+	       max_chan	: 3;	/* Max SCSI channel number on this board */
+
+	/* Structure extension defined in EATA 2.0C */
+	unchar max_lun;		/* Max SCSI LUN number */
+	unchar
+			: 4,
+	       m1	: 1,	/* This is a PCI with an M1 chip installed */
+	       idquest	: 1,	/* RAIDNUM returned is questionable */
+	       pci	: 1,	/* This board is PCI */
+	       eisa	: 1;	/* This board is EISA */
 #endif
 
-   unchar   raidnum;    /* Uniquely identifies this HBA in a system */
-   unchar   notused;
+	unchar raidnum;		/* Uniquely identifies this HBA in a system */
+	unchar notused;
 
-   ushort ipad[247];
-   };
+	ushort ipad[247];
+};
 
 /* Board config structure */
 struct eata_config {
-   ushort len;          /* Number of bytes following this field */
+	ushort len;		/* Number of bytes following this field */
 
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar     :4, tarena:1, mdpena:1, ocena:1, edis:1;
+	unchar		: 4,
+	       tarena	: 1,
+	       mdpena	: 1,
+	       ocena	: 1,
+	       edis	: 1;
 #else
-   unchar edis:1,       /* Disable EATA interface after config command */
-         ocena:1,       /* Overlapped Commands Enabled */
-        mdpena:1,       /* Transfer all Modified Data Pointer Messages */
-        tarena:1,       /* Target Mode Enabled for this controller */
-              :4;
+	unchar edis	: 1,	/* Disable EATA interface after config command */
+	       ocena	: 1,	/* Overlapped Commands Enabled */
+	       mdpena	: 1,	/* Transfer all Modified Data Pointer Messages */
+	       tarena	: 1,	/* Target Mode Enabled for this controller */
+	       		: 4;
 #endif
-
-   unchar cpad[511];
-   };
+	unchar cpad[511];
+};
 
 /* Returned status packet structure */
 struct mssp {
-
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar            eoc:1, adapter_status:7;
+	unchar eoc	: 1,
+	       adapter_status : 7;
 #else
-   unchar adapter_status:7,    /* State related to current command */
-                     eoc:1;    /* End Of Command (1 = command completed) */
+	unchar adapter_status : 7,	/* State related to current command */
+	       eoc	: 1;		/* End Of Command (1 = command completed) */
 #endif
-
-   unchar target_status;       /* SCSI status received after data transfer */
-   unchar unused[2];
-   u_int32_t inv_res_len;      /* Number of bytes not transferred */
-   u_int32_t cpp_index;        /* Index of address set in cp */
-   char mess[12];
-   };
+	unchar target_status;	/* SCSI status received after data transfer */
+	unchar unused[2];
+	u_int32_t inv_res_len;	/* Number of bytes not transferred */
+	u_int32_t cpp_index;	/* Index of address set in cp */
+	char mess[12];
+};
 
 struct sg_list {
-   unsigned int address;                /* Segment Address */
-   unsigned int num_bytes;              /* Segment Length */
-   };
+	unsigned int address;	/* Segment Address */
+	unsigned int num_bytes;	/* Segment Length */
+};
 
 /* MailBox SCSI Command Packet */
 struct mscp {
-
 #if defined(__BIG_ENDIAN_BITFIELD)
-   unchar     din:1, dout:1, interp:1, :1, sg:1, reqsen:1, init:1, sreset:1;
-   unchar sense_len;
-   unchar unused[3];
-   unchar        :7, fwnest:1;
-   unchar        :5, hbaci:1, iat:1, phsunit:1;
-   unchar channel:3, target:5;
-   unchar     one:1, dispri:1, luntar:1, lun:5;
+	unchar din	: 1,
+	       dout	: 1,
+	       interp	: 1,
+	       		: 1,
+		sg	: 1,
+		reqsen	:1,
+		init	: 1,
+		sreset	: 1;
+	unchar sense_len;
+	unchar unused[3];
+	unchar		: 7,
+	       fwnest	: 1;
+	unchar		: 5,
+	       hbaci	: 1,
+	       iat	: 1,
+	       phsunit	: 1;
+	unchar channel	: 3,
+	       target	: 5;
+	unchar one	: 1,
+	       dispri	: 1,
+	       luntar	: 1,
+	       lun	: 5;
 #else
-   unchar  sreset:1,     /* SCSI Bus Reset Signal should be asserted */
-             init:1,     /* Re-initialize controller and self test */
-           reqsen:1,     /* Transfer Request Sense Data to addr using DMA */
-               sg:1,     /* Use Scatter/Gather */
-                 :1,
-           interp:1,     /* The controller interprets cp, not the target */
-             dout:1,     /* Direction of Transfer is Out (Host to Target) */
-              din:1;     /* Direction of Transfer is In (Target to Host) */
-   unchar sense_len;     /* Request Sense Length */
-   unchar unused[3];
-   unchar  fwnest:1,     /* Send command to a component of an Array Group */
-                 :7;
-   unchar phsunit:1,     /* Send to Target Physical Unit (bypass RAID) */
-              iat:1,     /* Inhibit Address Translation */
-            hbaci:1,     /* Inhibit HBA Caching for this command */
-                 :5;
-   unchar  target:5,     /* SCSI target ID */
-          channel:3;     /* SCSI channel number */
-   unchar     lun:5,     /* SCSI logical unit number */
-           luntar:1,     /* This cp is for Target (not LUN) */
-           dispri:1,     /* Disconnect Privilege granted */
-              one:1;     /* 1 */
-#endif
-
-   unchar mess[3];       /* Massage to/from Target */
-   unchar cdb[12];       /* Command Descriptor Block */
-   u_int32_t data_len;   /* If sg=0 Data Length, if sg=1 sglist length */
-   u_int32_t cpp_index;  /* Index of address to be returned in sp */
-   u_int32_t data_address; /* If sg=0 Data Address, if sg=1 sglist address */
-   u_int32_t sp_dma_addr;  /* Address where sp is DMA'ed when cp completes */
-   u_int32_t sense_addr; /* Address where Sense Data is DMA'ed on error */
-
-   /* Additional fields begin here. */
-   struct scsi_cmnd *SCpnt;
-
-   /* All the cp structure is zero filled by queuecommand except the
-      following CP_TAIL_SIZE bytes, initialized by detect */
-   dma_addr_t cp_dma_addr; /* dma handle for this cp structure */
-   struct sg_list *sglist; /* pointer to the allocated SG list */
-   };
+	unchar sreset	:1,	/* SCSI Bus Reset Signal should be asserted */
+	       init	:1,	/* Re-initialize controller and self test */
+	       reqsen	:1,	/* Transfer Request Sense Data to addr using DMA */
+	       sg	:1,	/* Use Scatter/Gather */
+	       		:1,
+	       interp	:1,	/* The controller interprets cp, not the target */
+	       dout	:1,	/* Direction of Transfer is Out (Host to Target) */
+	       din	:1;	/* Direction of Transfer is In (Target to Host) */
+	unchar sense_len;	/* Request Sense Length */
+	unchar unused[3];
+	unchar fwnest	: 1,	/* Send command to a component of an Array Group */
+			: 7;
+	unchar phsunit	: 1,	/* Send to Target Physical Unit (bypass RAID) */
+	       iat	: 1,	/* Inhibit Address Translation */
+	       hbaci	: 1,	/* Inhibit HBA Caching for this command */
+	       		: 5;
+	unchar target	: 5,	/* SCSI target ID */
+	       channel	: 3;	/* SCSI channel number */
+	unchar lun	: 5,	/* SCSI logical unit number */
+	       luntar	: 1,	/* This cp is for Target (not LUN) */
+	       dispri	: 1,	/* Disconnect Privilege granted */
+	       one	: 1;	/* 1 */
+#endif
+
+	unchar mess[3];		/* Massage to/from Target */
+	unchar cdb[12];		/* Command Descriptor Block */
+	u_int32_t data_len;	/* If sg=0 Data Length, if sg=1 sglist length */
+	u_int32_t cpp_index;	/* Index of address to be returned in sp */
+	u_int32_t data_address;	/* If sg=0 Data Address, if sg=1 sglist address */
+	u_int32_t sp_dma_addr;	/* Address where sp is DMA'ed when cp completes */
+	u_int32_t sense_addr;	/* Address where Sense Data is DMA'ed on error */
+
+	/* Additional fields begin here. */
+	struct scsi_cmnd *SCpnt;
+
+	/* All the cp structure is zero filled by queuecommand except the
+	   following CP_TAIL_SIZE bytes, initialized by detect */
+	dma_addr_t cp_dma_addr;	/* dma handle for this cp structure */
+	struct sg_list *sglist;	/* pointer to the allocated SG list */
+};
 
 #define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t))
 
 struct hostdata {
-   struct mscp cp[MAX_MAILBOXES];       /* Mailboxes for this board */
-   unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */
-   unsigned int last_cp_used;           /* Index of last mailbox used */
-   unsigned int iocount;                /* Total i/o done for this board */
-   int board_number;                    /* Number of this board */
-   char board_name[16];                 /* Name of this board */
-   int in_reset;                        /* True if board is doing a reset */
-   int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
-   int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If 1 redo i/o on target */
-   unsigned int retries;                /* Number of internal retries */
-   unsigned long last_retried_pid;      /* Pid of last retried command */
-   unsigned char subversion;            /* Bus type, either ISA or EISA/PCI */
-   unsigned char protocol_rev;          /* EATA 2.0 rev., 'A' or 'B' or 'C' */
-   unsigned char is_pci;                /* 1 is bus type is PCI */
-   struct pci_dev *pdev;                /* pdev for PCI bus, NULL otherwise */
-   struct mssp *sp_cpu_addr;            /* cpu addr for DMA buffer sp */
-   dma_addr_t sp_dma_addr;              /* dma handle for DMA buffer sp */
-   struct mssp sp;                      /* Local copy of sp buffer */
-   };
+	struct mscp cp[MAX_MAILBOXES];	/* Mailboxes for this board */
+	unsigned int cp_stat[MAX_MAILBOXES];	/* FREE, IN_USE, LOCKED, IN_RESET */
+	unsigned int last_cp_used;	/* Index of last mailbox used */
+	unsigned int iocount;	/* Total i/o done for this board */
+	int board_number;	/* Number of this board */
+	char board_name[16];	/* Name of this board */
+	int in_reset;		/* True if board is doing a reset */
+	int target_to[MAX_TARGET][MAX_CHANNEL];	/* N. of timeout errors on target */
+	int target_redo[MAX_TARGET][MAX_CHANNEL];	/* If 1 redo i/o on target */
+	unsigned int retries;	/* Number of internal retries */
+	unsigned long last_retried_pid;	/* Pid of last retried command */
+	unsigned char subversion;	/* Bus type, either ISA or EISA/PCI */
+	unsigned char protocol_rev;	/* EATA 2.0 rev., 'A' or 'B' or 'C' */
+	unsigned char is_pci;	/* 1 is bus type is PCI */
+	struct pci_dev *pdev;	/* pdev for PCI bus, NULL otherwise */
+	struct mssp *sp_cpu_addr;	/* cpu addr for DMA buffer sp */
+	dma_addr_t sp_dma_addr;	/* dma handle for DMA buffer sp */
+	struct mssp sp;		/* Local copy of sp buffer */
+};
 
-static struct Scsi_Host *sh[MAX_BOARDS + 1];
+static struct Scsi_Host *sh[MAX_BOARDS];
 static const char *driver_name = "EATA";
 static char sha[MAX_BOARDS];
 static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
@@ -809,30 +846,27 @@
 
 static unsigned long io_port[] = {
 
-   /* Space for MAX_INT_PARAM ports usable while loading as a module */
-   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,
-   SKIP,    SKIP,
-
-   /* First ISA */
-   0x1f0,
-
-   /* Space for MAX_PCI ports possibly reported by PCI_BIOS */
-   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,
-   SKIP,    SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,
-
-   /* MAX_EISA ports */
-   0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
-   0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,
-
-   /* Other (MAX_ISA - 1) ports */
-   0x170,  0x230,  0x330,
-
-   /* End of list */
-   0x0
-   };
-
-#define HD(board) ((struct hostdata *) &sh[board]->hostdata)
-#define BN(board) (HD(board)->board_name)
+	/* Space for MAX_INT_PARAM ports usable while loading as a module */
+	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
+	SKIP, SKIP,
+
+	/* First ISA */
+	0x1f0,
+
+	/* Space for MAX_PCI ports possibly reported by PCI_BIOS */
+	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
+	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
+
+	/* MAX_EISA ports */
+	0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
+	0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,
+
+	/* Other (MAX_ISA - 1) ports */
+	0x170, 0x230, 0x330,
+
+	/* End of list */
+	0x0
+};
 
 /* Device is Big Endian */
 #define H2DEV(x)   cpu_to_be32(x)
@@ -844,7 +878,8 @@
 #define REG2H(x)   le16_to_cpu(x)
 
 static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *);
-static void flush_dev(struct scsi_device *, unsigned long, unsigned int, unsigned int);
+static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *,
+		      unsigned int);
 static int do_trace = 0;
 static int setup_done = 0;
 static int link_statistics;
@@ -896,1531 +931,1691 @@
 #include <linux/moduleparam.h>
 
 module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0);
-MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." \
-"            Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\"");
+MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option."
+		 "            Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\"");
 MODULE_AUTHOR("Dario Ballabio");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("EATA/DMA SCSI Driver");
 
 #endif
 
-static int eata2x_slave_configure(struct scsi_device *dev) {
-   int j, tqd, utqd;
-   char *tag_suffix, *link_suffix;
-   struct Scsi_Host *host = dev->host;
-
-   j = ((struct hostdata *) host->hostdata)->board_number;
-
-   utqd = MAX_CMD_PER_LUN;
-   tqd = max_queue_depth;
-
-   if (TLDEV(dev->type) && dev->tagged_supported)
-
-      if (tag_mode == TAG_SIMPLE) {
-         scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd);
-         tag_suffix = ", simple tags";
-         }
-      else if (tag_mode == TAG_ORDERED) {
-         scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd);
-         tag_suffix = ", ordered tags";
-         }
-      else {
-         scsi_adjust_queue_depth(dev, 0, tqd);
-         tag_suffix = ", no tags";
-         }
-
-   else if (TLDEV(dev->type) && linked_comm) {
-      scsi_adjust_queue_depth(dev, 0, tqd);
-      tag_suffix = ", untagged";
-      }
-
-   else {
-      scsi_adjust_queue_depth(dev, 0, utqd);
-      tag_suffix = "";
-      }
-
-   if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2)
-      link_suffix = ", sorted";
-   else if (TLDEV(dev->type))
-      link_suffix = ", unsorted";
-   else
-      link_suffix = "";
-
-   printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
-          BN(j), host->host_no, dev->channel, dev->id, dev->lun,
-          dev->queue_depth, link_suffix, tag_suffix);
-
-   return 0;
-}
-
-static int wait_on_busy(unsigned long iobase, unsigned int loop) {
-
-   while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) {
-      udelay(1L);
-      if (--loop == 0) return 1;
-      }
-
-   return 0;
-}
-
-static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) {
-   unsigned char *byaddr;
-   unsigned long devaddr;
+static int eata2x_slave_configure(struct scsi_device *dev)
+{
+	int tqd, utqd;
+	char *tag_suffix, *link_suffix;
+	struct Scsi_Host *shost = dev->host;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+
+	utqd = MAX_CMD_PER_LUN;
+	tqd = max_queue_depth;
+
+	if (TLDEV(dev->type) && dev->tagged_supported) {
+		if (tag_mode == TAG_SIMPLE) {
+			scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd);
+			tag_suffix = ", simple tags";
+		} else if (tag_mode == TAG_ORDERED) {
+			scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd);
+			tag_suffix = ", ordered tags";
+		} else {
+			scsi_adjust_queue_depth(dev, 0, tqd);
+			tag_suffix = ", no tags";
+		}
+	} else if (TLDEV(dev->type) && linked_comm) {
+		scsi_adjust_queue_depth(dev, 0, tqd);
+		tag_suffix = ", untagged";
+	} else {
+		scsi_adjust_queue_depth(dev, 0, utqd);
+		tag_suffix = "";
+	}
+
+	if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2)
+		link_suffix = ", sorted";
+	else if (TLDEV(dev->type))
+		link_suffix = ", unsorted";
+	else
+		link_suffix = "";
+
+	printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
+	       ha->board_name, shost->host_no, dev->channel, dev->id, dev->lun,
+	       dev->queue_depth, link_suffix, tag_suffix);
+
+	return 0;
+}
+
+static int wait_on_busy(unsigned long iobase, unsigned int loop)
+{
+	while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) {
+		udelay(1L);
+		if (--loop == 0)
+			return 1;
+	}
+	return 0;
+}
+
+static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd)
+{
+	unsigned char *byaddr;
+	unsigned long devaddr;
+
+	if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP)))
+		return 1;
+
+	if (addr) {
+		devaddr = H2DEV(addr);
+		byaddr = (unsigned char *)&devaddr;
+		outb(byaddr[3], iobase + REG_LOW);
+		outb(byaddr[2], iobase + REG_LM);
+		outb(byaddr[1], iobase + REG_MID);
+		outb(byaddr[0], iobase + REG_MSB);
+	}
+
+	outb(cmd, iobase + REG_CMD);
+	return 0;
+}
+
+static int read_pio(unsigned long iobase, ushort * start, ushort * end)
+{
+	unsigned int loop = MAXLOOP;
+	ushort *p;
+
+	for (p = start; p <= end; p++) {
+		while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) {
+			udelay(1L);
+			if (--loop == 0)
+				return 1;
+		}
+		loop = MAXLOOP;
+		*p = REG2H(inw(iobase));
+	}
 
-   if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) return 1;
-
-   if (addr) {
-      devaddr = H2DEV(addr);
-      byaddr = (unsigned char *) &devaddr;
-      outb(byaddr[3], iobase + REG_LOW);
-      outb(byaddr[2], iobase + REG_LM);
-      outb(byaddr[1], iobase + REG_MID);
-      outb(byaddr[0], iobase + REG_MSB);
-      }
-
-   outb(cmd, iobase + REG_CMD);
-   return 0;
+	return 0;
 }
 
-static int read_pio(unsigned long iobase, ushort *start, ushort *end) {
-   unsigned int loop = MAXLOOP;
-   ushort *p;
-
-   for (p = start; p <= end; p++) {
-
-      while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) {
-         udelay(1L);
-         if (--loop == 0) return 1;
-         }
-
-      loop = MAXLOOP;
-      *p = REG2H(inw(iobase));
-      }
-
-   return 0;
-}
-
-static struct pci_dev *get_pci_dev(unsigned long port_base) {
-
+static struct pci_dev *get_pci_dev(unsigned long port_base)
+{
 #if defined(CONFIG_PCI)
+	unsigned int addr;
+	struct pci_dev *dev = NULL;
 
-   unsigned int addr;
-   struct pci_dev *dev = NULL;
-
-   while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
-      addr = pci_resource_start (dev, 0);
+	while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
+		addr = pci_resource_start(dev, 0);
 
 #if defined(DEBUG_PCI_DETECT)
-      printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n",
-             driver_name, dev->bus->number, dev->devfn, addr);
+		printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n",
+		       driver_name, dev->bus->number, dev->devfn, addr);
 #endif
 
-      /* we are in so much trouble for a pci hotplug system with this driver
-       * anyway, so doing this at least lets people unload the driver and not
-       * cause memory problems, but in general this is a bad thing to do (this
-       * driver needs to be converted to the proper PCI api someday... */
-      pci_dev_put(dev);
-      if (addr + PCI_BASE_ADDRESS_0 == port_base) return dev;
-      }
-
-#endif /* end CONFIG_PCI */
-
-   return NULL;
+		/* we are in so much trouble for a pci hotplug system with this driver
+		 * anyway, so doing this at least lets people unload the driver and not
+		 * cause memory problems, but in general this is a bad thing to do (this
+		 * driver needs to be converted to the proper PCI api someday... */
+		pci_dev_put(dev);
+		if (addr + PCI_BASE_ADDRESS_0 == port_base)
+			return dev;
+	}
+#endif				/* end CONFIG_PCI */
+	return NULL;
 }
 
-static void enable_pci_ports(void) {
-
+static void enable_pci_ports(void)
+{
 #if defined(CONFIG_PCI)
+	struct pci_dev *dev = NULL;
 
-   struct pci_dev *dev = NULL;
-
-   while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
-
+	while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
 #if defined(DEBUG_PCI_DETECT)
-      printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n",
-             driver_name, dev->bus->number, dev->devfn);
+		printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n",
+		       driver_name, dev->bus->number, dev->devfn);
 #endif
 
-      if (pci_enable_device (dev))
-         printk("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n",
-                driver_name, dev->bus->number, dev->devfn);
-      }
-
-#endif /* end CONFIG_PCI */
-}
-
-static int port_detect \
-      (unsigned long port_base, unsigned int j, struct scsi_host_template *tpnt) {
-   unsigned char irq, dma_channel, subversion, i, is_pci = 0;
-   unsigned char protocol_rev;
-   struct eata_info info;
-   char *bus_type, dma_name[16];
-   struct pci_dev *pdev;
-
-   /* Allowed DMA channels for ISA (0 indicates reserved) */
-   unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
+		if (pci_enable_device(dev))
+			printk
+			    ("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n",
+			     driver_name, dev->bus->number, dev->devfn);
+	}
+
+#endif				/* end CONFIG_PCI */
+}
+
+static int port_detect(unsigned long port_base, unsigned int j,
+		struct scsi_host_template *tpnt)
+{
+	unsigned char irq, dma_channel, subversion, i, is_pci = 0;
+	unsigned char protocol_rev;
+	struct eata_info info;
+	char *bus_type, dma_name[16];
+	struct pci_dev *pdev;
+	/* Allowed DMA channels for ISA (0 indicates reserved) */
+	unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
+	struct Scsi_Host *shost;
+	struct hostdata *ha;
+	char name[16];
 
-   char name[16];
+	sprintf(name, "%s%d", driver_name, j);
 
-   sprintf(name, "%s%d", driver_name, j);
-
-   if (!request_region(port_base, REGION_SIZE, driver_name)) {
+	if (!request_region(port_base, REGION_SIZE, driver_name)) {
 #if defined(DEBUG_DETECT)
-      printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
+		printk("%s: address 0x%03lx in use, skipping probe.\n", name,
+		       port_base);
 #endif
-      goto fail;
-      }
+		goto fail;
+	}
 
-   spin_lock_irq(&driver_lock);
+	spin_lock_irq(&driver_lock);
 
-   if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
+	if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
 #if defined(DEBUG_DETECT)
-      printk("%s: detect, do_dma failed at 0x%03lx.\n", name, port_base);
+		printk("%s: detect, do_dma failed at 0x%03lx.\n", name,
+		       port_base);
 #endif
-      goto freelock;
-      }
+		goto freelock;
+	}
 
-   /* Read the info structure */
-   if (read_pio(port_base, (ushort *)&info, (ushort *)&info.ipad[0])) {
+	/* Read the info structure */
+	if (read_pio(port_base, (ushort *) & info, (ushort *) & info.ipad[0])) {
 #if defined(DEBUG_DETECT)
-      printk("%s: detect, read_pio failed at 0x%03lx.\n", name, port_base);
+		printk("%s: detect, read_pio failed at 0x%03lx.\n", name,
+		       port_base);
 #endif
-      goto freelock;
-      }
+		goto freelock;
+	}
 
-   info.data_len = DEV2H(info.data_len);
-   info.sign = DEV2H(info.sign);
-   info.cp_pad_len = DEV2H16(info.cp_pad_len);
-   info.cp_len = DEV2H(info.cp_len);
-   info.sp_len = DEV2H(info.sp_len);
-   info.scatt_size = DEV2H16(info.scatt_size);
-   info.queue_size = DEV2H16(info.queue_size);
+	info.data_len = DEV2H(info.data_len);
+	info.sign = DEV2H(info.sign);
+	info.cp_pad_len = DEV2H16(info.cp_pad_len);
+	info.cp_len = DEV2H(info.cp_len);
+	info.sp_len = DEV2H(info.sp_len);
+	info.scatt_size = DEV2H16(info.scatt_size);
+	info.queue_size = DEV2H16(info.queue_size);
 
-   /* Check the controller "EATA" signature */
-   if (info.sign != EATA_SIG_BE) {
+	/* Check the controller "EATA" signature */
+	if (info.sign != EATA_SIG_BE) {
 #if defined(DEBUG_DETECT)
-      printk("%s: signature 0x%04x discarded.\n", name, info.sign);
+		printk("%s: signature 0x%04x discarded.\n", name, info.sign);
 #endif
-      goto freelock;
-      }
-
-   if (info.data_len < EATA_2_0A_SIZE) {
-      printk("%s: config structure size (%d bytes) too short, detaching.\n",
-             name, info.data_len);
-      goto freelock;
-      }
-   else if (info.data_len == EATA_2_0A_SIZE)
-      protocol_rev = 'A';
-   else if (info.data_len == EATA_2_0B_SIZE)
-      protocol_rev = 'B';
-   else
-      protocol_rev = 'C';
-
-   if (protocol_rev != 'A' && info.forcaddr) {
-      printk("%s: warning, port address has been forced.\n", name);
-      bus_type = "PCI";
-      is_pci = 1;
-      subversion = ESA;
-      }
-   else if (port_base > MAX_EISA_ADDR || (protocol_rev == 'C' && info.pci)) {
-      bus_type = "PCI";
-      is_pci = 1;
-      subversion = ESA;
-      }
-   else if (port_base >= MIN_EISA_ADDR || (protocol_rev == 'C' && info.eisa)) {
-      bus_type = "EISA";
-      subversion = ESA;
-      }
-   else if (protocol_rev == 'C' && !info.eisa && !info.pci) {
-      bus_type = "ISA";
-      subversion = ISA;
-      }
-   else if (port_base > MAX_ISA_ADDR) {
-      bus_type = "PCI";
-      is_pci = 1;
-      subversion = ESA;
-      }
-   else {
-      bus_type = "ISA";
-      subversion = ISA;
-      }
-
-   if (!info.haaval || info.ata) {
-      printk("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
-             name, port_base, bus_type, info.haaval, info.ata);
-      goto freelock;
-      }
-
-   if (info.drqvld) {
-
-      if (subversion ==  ESA)
-         printk("%s: warning, weird %s board using DMA.\n", name, bus_type);
-
-      subversion = ISA;
-      dma_channel = dma_channel_table[3 - info.drqx];
-      }
-   else {
-
-      if (subversion ==  ISA)
-         printk("%s: warning, weird %s board not using DMA.\n", name, bus_type);
-
-      subversion = ESA;
-      dma_channel = NO_DMA;
-      }
-
-   if (!info.dmasup)
-      printk("%s: warning, DMA protocol support not asserted.\n", name);
-
-   irq = info.irq;
-
-   if (subversion == ESA && !info.irq_tr)
-      printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
-             name, irq);
-
-   if (is_pci) {
-      pdev = get_pci_dev(port_base);
-      if (!pdev)
-         printk("%s: warning, failed to get pci_dev structure.\n", name);
-      }
-   else
-      pdev = NULL;
-
-   if (pdev && (irq != pdev->irq)) {
-      printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, pdev->irq);
-      irq = pdev->irq;
-      }
-
-   /* Board detected, allocate its IRQ */
-   if (request_irq(irq, do_interrupt_handler,
-             SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
-             driver_name, (void *) &sha[j])) {
-      printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
-      goto freelock;
-      }
-
-   if (subversion == ISA && request_dma(dma_channel, driver_name)) {
-      printk("%s: unable to allocate DMA channel %u, detaching.\n",
-             name, dma_channel);
-      goto freeirq;
-      }
+		goto freelock;
+	}
 
+	if (info.data_len < EATA_2_0A_SIZE) {
+		printk
+		    ("%s: config structure size (%d bytes) too short, detaching.\n",
+		     name, info.data_len);
+		goto freelock;
+	} else if (info.data_len == EATA_2_0A_SIZE)
+		protocol_rev = 'A';
+	else if (info.data_len == EATA_2_0B_SIZE)
+		protocol_rev = 'B';
+	else
+		protocol_rev = 'C';
+
+	if (protocol_rev != 'A' && info.forcaddr) {
+		printk("%s: warning, port address has been forced.\n", name);
+		bus_type = "PCI";
+		is_pci = 1;
+		subversion = ESA;
+	} else if (port_base > MAX_EISA_ADDR
+		   || (protocol_rev == 'C' && info.pci)) {
+		bus_type = "PCI";
+		is_pci = 1;
+		subversion = ESA;
+	} else if (port_base >= MIN_EISA_ADDR
+		   || (protocol_rev == 'C' && info.eisa)) {
+		bus_type = "EISA";
+		subversion = ESA;
+	} else if (protocol_rev == 'C' && !info.eisa && !info.pci) {
+		bus_type = "ISA";
+		subversion = ISA;
+	} else if (port_base > MAX_ISA_ADDR) {
+		bus_type = "PCI";
+		is_pci = 1;
+		subversion = ESA;
+	} else {
+		bus_type = "ISA";
+		subversion = ISA;
+	}
+
+	if (!info.haaval || info.ata) {
+		printk
+		    ("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
+		     name, port_base, bus_type, info.haaval, info.ata);
+		goto freelock;
+	}
+
+	if (info.drqvld) {
+		if (subversion == ESA)
+			printk("%s: warning, weird %s board using DMA.\n", name,
+			       bus_type);
+
+		subversion = ISA;
+		dma_channel = dma_channel_table[3 - info.drqx];
+	} else {
+		if (subversion == ISA)
+			printk("%s: warning, weird %s board not using DMA.\n",
+			       name, bus_type);
+
+		subversion = ESA;
+		dma_channel = NO_DMA;
+	}
+
+	if (!info.dmasup)
+		printk("%s: warning, DMA protocol support not asserted.\n",
+		       name);
+
+	irq = info.irq;
+
+	if (subversion == ESA && !info.irq_tr)
+		printk
+		    ("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
+		     name, irq);
+
+	if (is_pci) {
+		pdev = get_pci_dev(port_base);
+		if (!pdev)
+			printk
+			    ("%s: warning, failed to get pci_dev structure.\n",
+			     name);
+	} else
+		pdev = NULL;
+
+	if (pdev && (irq != pdev->irq)) {
+		printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq,
+		       pdev->irq);
+		irq = pdev->irq;
+	}
+
+	/* Board detected, allocate its IRQ */
+	if (request_irq(irq, do_interrupt_handler,
+			SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
+			driver_name, (void *)&sha[j])) {
+		printk("%s: unable to allocate IRQ %u, detaching.\n", name,
+		       irq);
+		goto freelock;
+	}
+
+	if (subversion == ISA && request_dma(dma_channel, driver_name)) {
+		printk("%s: unable to allocate DMA channel %u, detaching.\n",
+		       name, dma_channel);
+		goto freeirq;
+	}
 #if defined(FORCE_CONFIG)
-   {
-   struct eata_config *cf;
-   dma_addr_t cf_dma_addr;
-
-   cf = pci_alloc_consistent(pdev, sizeof(struct eata_config), &cf_dma_addr);
-
-   if (!cf) {
-      printk("%s: config, pci_alloc_consistent failed, detaching.\n", name);
-      goto freedma;
-      }
-
-   /* Set board configuration */
-   memset((char *)cf, 0, sizeof(struct eata_config));
-   cf->len = (ushort) H2DEV16((ushort)510);
-   cf->ocena = 1;
-
-   if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
-      printk("%s: busy timeout sending configuration, detaching.\n", name);
-      pci_free_consistent(pdev, sizeof(struct eata_config), cf, cf_dma_addr);
-      goto freedma;
-      }
-
-   }
-#endif
-
-   spin_unlock_irq(&driver_lock);
-   sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
-   spin_lock_irq(&driver_lock);
-
-   if (sh[j] == NULL) {
-      printk("%s: unable to register host, detaching.\n", name);
-      goto freedma;
-      }
-
-   sh[j]->io_port = port_base;
-   sh[j]->unique_id = port_base;
-   sh[j]->n_io_port = REGION_SIZE;
-   sh[j]->dma_channel = dma_channel;
-   sh[j]->irq = irq;
-   sh[j]->sg_tablesize = (ushort) info.scatt_size;
-   sh[j]->this_id = (ushort) info.host_addr[3];
-   sh[j]->can_queue = (ushort) info.queue_size;
-   sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
-   memset(HD(j), 0, sizeof(struct hostdata));
-   HD(j)->subversion = subversion;
-   HD(j)->protocol_rev = protocol_rev;
-   HD(j)->is_pci = is_pci;
-   HD(j)->pdev = pdev;
-   HD(j)->board_number = j;
-
-   if (HD(j)->subversion == ESA)
-      sh[j]->unchecked_isa_dma = 0;
-   else {
-      unsigned long flags;
-      sh[j]->unchecked_isa_dma = 1;
-
-      flags=claim_dma_lock();
-      disable_dma(dma_channel);
-      clear_dma_ff(dma_channel);
-      set_dma_mode(dma_channel, DMA_MODE_CASCADE);
-      enable_dma(dma_channel);
-      release_dma_lock(flags);
-
-      }
-
-   strcpy(BN(j), name);
-
-   /* DPT PM2012 does not allow to detect sg_tablesize correctly */
-   if (sh[j]->sg_tablesize > MAX_SGLIST || sh[j]->sg_tablesize < 2) {
-      printk("%s: detect, wrong n. of SG lists %d, fixed.\n",
-             BN(j), sh[j]->sg_tablesize);
-      sh[j]->sg_tablesize = MAX_SGLIST;
-      }
-
-   /* DPT PM2012 does not allow to detect can_queue correctly */
-   if (sh[j]->can_queue > MAX_MAILBOXES || sh[j]->can_queue  < 2) {
-      printk("%s: detect, wrong n. of mbox %d, fixed.\n",
-             BN(j), sh[j]->can_queue);
-      sh[j]->can_queue = MAX_MAILBOXES;
-      }
-
-   if (protocol_rev != 'A') {
-
-      if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
-         sh[j]->max_channel = info.max_chan;
-
-      if (info.max_id > 7 && info.max_id < MAX_TARGET)
-         sh[j]->max_id = info.max_id + 1;
-
-      if (info.large_sg && sh[j]->sg_tablesize == MAX_SGLIST)
-         sh[j]->sg_tablesize = MAX_LARGE_SGLIST;
-      }
-
-   if (protocol_rev == 'C') {
-
-      if (info.max_lun > 7 && info.max_lun < MAX_LUN)
-         sh[j]->max_lun = info.max_lun + 1;
-      }
-
-   if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST");
-   else                       sprintf(dma_name, "DMA %u", dma_channel);
-
-   spin_unlock_irq(&driver_lock);
-
-   for (i = 0; i < sh[j]->can_queue; i++)
-      HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
-            &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
-
-   for (i = 0; i < sh[j]->can_queue; i++)
-      if (! ((&HD(j)->cp[i])->sglist = kmalloc(
-            sh[j]->sg_tablesize * sizeof(struct sg_list),
-            (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
-         printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);
-         goto release;
-         }
-
-   if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev,
-         sizeof(struct mssp), &HD(j)->sp_dma_addr))) {
-      printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j));
-      goto release;
-      }
-
-   if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
-       max_queue_depth = MAX_TAGGED_CMD_PER_LUN;
-
-   if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;
-
-   if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
-      tag_mode = TAG_ORDERED;
-
-   if (j == 0) {
-      printk("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");
-      printk("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "\
-             "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
-             YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
-             YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe),
-             YESNO(pci_probe));
-      }
-
-   printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n",
-          BN(j), HD(j)->protocol_rev, bus_type, (unsigned long)sh[j]->io_port,
-          sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue);
-
-   if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
-      printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
-             BN(j), sh[j]->max_id, sh[j]->max_lun);
-
-   for (i = 0; i <= sh[j]->max_channel; i++)
-      printk("%s: SCSI channel %u enabled, host target ID %d.\n",
-             BN(j), i, info.host_addr[3 - i]);
+	{
+		struct eata_config *cf;
+		dma_addr_t cf_dma_addr;
+
+		cf = pci_alloc_consistent(pdev, sizeof(struct eata_config),
+					  &cf_dma_addr);
+
+		if (!cf) {
+			printk
+			    ("%s: config, pci_alloc_consistent failed, detaching.\n",
+			     name);
+			goto freedma;
+		}
+
+		/* Set board configuration */
+		memset((char *)cf, 0, sizeof(struct eata_config));
+		cf->len = (ushort) H2DEV16((ushort) 510);
+		cf->ocena = 1;
+
+		if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
+			printk
+			    ("%s: busy timeout sending configuration, detaching.\n",
+			     name);
+			pci_free_consistent(pdev, sizeof(struct eata_config),
+					    cf, cf_dma_addr);
+			goto freedma;
+		}
+
+	}
+#endif
+
+	spin_unlock_irq(&driver_lock);
+	sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata));
+	spin_lock_irq(&driver_lock);
+
+	if (shost == NULL) {
+		printk("%s: unable to register host, detaching.\n", name);
+		goto freedma;
+	}
+
+	shost->io_port = port_base;
+	shost->unique_id = port_base;
+	shost->n_io_port = REGION_SIZE;
+	shost->dma_channel = dma_channel;
+	shost->irq = irq;
+	shost->sg_tablesize = (ushort) info.scatt_size;
+	shost->this_id = (ushort) info.host_addr[3];
+	shost->can_queue = (ushort) info.queue_size;
+	shost->cmd_per_lun = MAX_CMD_PER_LUN;
+
+	ha = (struct hostdata *)shost->hostdata;
+	
+	memset(ha, 0, sizeof(struct hostdata));
+	ha->subversion = subversion;
+	ha->protocol_rev = protocol_rev;
+	ha->is_pci = is_pci;
+	ha->pdev = pdev;
+	ha->board_number = j;
+
+	if (ha->subversion == ESA)
+		shost->unchecked_isa_dma = 0;
+	else {
+		unsigned long flags;
+		shost->unchecked_isa_dma = 1;
+
+		flags = claim_dma_lock();
+		disable_dma(dma_channel);
+		clear_dma_ff(dma_channel);
+		set_dma_mode(dma_channel, DMA_MODE_CASCADE);
+		enable_dma(dma_channel);
+		release_dma_lock(flags);
+
+	}
+
+	strcpy(ha->board_name, name);
+
+	/* DPT PM2012 does not allow to detect sg_tablesize correctly */
+	if (shost->sg_tablesize > MAX_SGLIST || shost->sg_tablesize < 2) {
+		printk("%s: detect, wrong n. of SG lists %d, fixed.\n",
+		       ha->board_name, shost->sg_tablesize);
+		shost->sg_tablesize = MAX_SGLIST;
+	}
+
+	/* DPT PM2012 does not allow to detect can_queue correctly */
+	if (shost->can_queue > MAX_MAILBOXES || shost->can_queue < 2) {
+		printk("%s: detect, wrong n. of mbox %d, fixed.\n",
+		       ha->board_name, shost->can_queue);
+		shost->can_queue = MAX_MAILBOXES;
+	}
+
+	if (protocol_rev != 'A') {
+		if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
+			shost->max_channel = info.max_chan;
+
+		if (info.max_id > 7 && info.max_id < MAX_TARGET)
+			shost->max_id = info.max_id + 1;
+
+		if (info.large_sg && shost->sg_tablesize == MAX_SGLIST)
+			shost->sg_tablesize = MAX_LARGE_SGLIST;
+	}
+
+	if (protocol_rev == 'C') {
+		if (info.max_lun > 7 && info.max_lun < MAX_LUN)
+			shost->max_lun = info.max_lun + 1;
+	}
+
+	if (dma_channel == NO_DMA)
+		sprintf(dma_name, "%s", "BMST");
+	else
+		sprintf(dma_name, "DMA %u", dma_channel);
+
+	spin_unlock_irq(&driver_lock);
+
+	for (i = 0; i < shost->can_queue; i++)
+		ha->cp[i].cp_dma_addr = pci_map_single(ha->pdev,
+							  &ha->cp[i],
+							  sizeof(struct mscp),
+							  PCI_DMA_BIDIRECTIONAL);
+
+	for (i = 0; i < shost->can_queue; i++) {
+		size_t sz = shost->sg_tablesize *sizeof(struct sg_list);
+		unsigned int gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC;
+		ha->cp[i].sglist = kmalloc(sz, gfp_mask);
+		if (!ha->cp[i].sglist) {
+			printk
+			    ("%s: kmalloc SGlist failed, mbox %d, detaching.\n",
+			     ha->board_name, i);
+			goto release;
+		}
+	}
+
+	if (!(ha->sp_cpu_addr = pci_alloc_consistent(ha->pdev,
+							sizeof(struct mssp),
+							&ha->sp_dma_addr))) {
+		printk("%s: pci_alloc_consistent failed, detaching.\n", ha->board_name);
+		goto release;
+	}
+
+	if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
+		max_queue_depth = MAX_TAGGED_CMD_PER_LUN;
+
+	if (max_queue_depth < MAX_CMD_PER_LUN)
+		max_queue_depth = MAX_CMD_PER_LUN;
+
+	if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
+		tag_mode = TAG_ORDERED;
+
+	if (j == 0) {
+		printk
+		    ("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");
+		printk
+		    ("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "
+		     "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
+		     YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
+		     YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe),
+		     YESNO(pci_probe));
+	}
+
+	printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n",
+	       ha->board_name, ha->protocol_rev, bus_type,
+	       (unsigned long)shost->io_port, shost->irq, dma_name,
+	       shost->sg_tablesize, shost->can_queue);
+
+	if (shost->max_id > 8 || shost->max_lun > 8)
+		printk
+		    ("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+		     ha->board_name, shost->max_id, shost->max_lun);
+
+	for (i = 0; i <= shost->max_channel; i++)
+		printk("%s: SCSI channel %u enabled, host target ID %d.\n",
+		       ha->board_name, i, info.host_addr[3 - i]);
 
 #if defined(DEBUG_DETECT)
-   printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "\
-          "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,
-          info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,
-          info.second, info.data_len, info.cp_len,
-          info.sp_len);
-
-   if (protocol_rev == 'B' || protocol_rev == 'C')
-      printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "\
-             "large_sg %u, res1 %u.\n", name, info.isaena, info.forcaddr,
-             info.max_id, info.max_chan, info.large_sg, info.res1);
-
-   if (protocol_rev == 'C')
-      printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, "\
-             "raidnum %u.\n", name, info.max_lun, info.m1, info.idquest,
-             info.pci, info.eisa, info.raidnum);
-#endif
-
-   if (HD(j)->pdev) {
-      pci_set_master(HD(j)->pdev);
-      if (pci_set_dma_mask(HD(j)->pdev, 0xffffffff))
-         printk("%s: warning, pci_set_dma_mask failed.\n", BN(j));
-      }
-
-   return 1;
-
-freedma:
-   if (subversion == ISA) free_dma(dma_channel);
-freeirq:
-   free_irq(irq, &sha[j]);
-freelock:
-   spin_unlock_irq(&driver_lock);
-   release_region(port_base, REGION_SIZE);
-fail:
-   return 0;
-
-release:
-   eata2x_release(sh[j]);
-   return 0;
-}
-
-static void internal_setup(char *str, int *ints) {
-   int i, argc = ints[0];
-   char *cur = str, *pc;
-
-   if (argc > 0) {
-
-      if (argc > MAX_INT_PARAM) argc = MAX_INT_PARAM;
-
-      for (i = 0; i < argc; i++) io_port[i] = ints[i + 1];
-
-      io_port[i] = 0;
-      setup_done = 1;
-      }
-
-   while (cur && (pc = strchr(cur, ':'))) {
-      int val = 0, c = *++pc;
-
-      if (c == 'n' || c == 'N') val = 0;
-      else if (c == 'y' || c == 'Y') val = 1;
-      else val = (int) simple_strtoul(pc, NULL, 0);
-
-      if (!strncmp(cur, "lc:", 3)) linked_comm = val;
-      else if (!strncmp(cur, "tm:", 3)) tag_mode = val;
-      else if (!strncmp(cur, "tc:", 3)) tag_mode = val;
-      else if (!strncmp(cur, "mq:", 3))  max_queue_depth = val;
-      else if (!strncmp(cur, "ls:", 3))  link_statistics = val;
-      else if (!strncmp(cur, "et:", 3))  ext_tran = val;
-      else if (!strncmp(cur, "rs:", 3))  rev_scan = val;
-      else if (!strncmp(cur, "ip:", 3))  isa_probe = val;
-      else if (!strncmp(cur, "ep:", 3))  eisa_probe = val;
-      else if (!strncmp(cur, "pp:", 3))  pci_probe = val;
-
-      if ((cur = strchr(cur, ','))) ++cur;
-      }
-
-   return;
-}
-
-static int option_setup(char *str) {
-   int ints[MAX_INT_PARAM];
-   char *cur = str;
-   int i = 1;
-
-   while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {
-      ints[i++] = simple_strtoul(cur, NULL, 0);
-
-      if ((cur = strchr(cur, ',')) != NULL) cur++;
-   }
-
-   ints[0] = i - 1;
-   internal_setup(cur, ints);
-   return 1;
+	printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, "
+	       "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version,
+	       info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync,
+	       info.second, info.data_len, info.cp_len, info.sp_len);
+
+	if (protocol_rev == 'B' || protocol_rev == 'C')
+		printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, "
+		       "large_sg %u, res1 %u.\n", name, info.isaena,
+		       info.forcaddr, info.max_id, info.max_chan, info.large_sg,
+		       info.res1);
+
+	if (protocol_rev == 'C')
+		printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, "
+		       "raidnum %u.\n", name, info.max_lun, info.m1,
+		       info.idquest, info.pci, info.eisa, info.raidnum);
+#endif
+
+	if (ha->pdev) {
+		pci_set_master(ha->pdev);
+		if (pci_set_dma_mask(ha->pdev, 0xffffffff))
+			printk("%s: warning, pci_set_dma_mask failed.\n",
+			       ha->board_name);
+	}
+
+	return 1;
+
+      freedma:
+	if (subversion == ISA)
+		free_dma(dma_channel);
+      freeirq:
+	free_irq(irq, &sha[j]);
+      freelock:
+	spin_unlock_irq(&driver_lock);
+	release_region(port_base, REGION_SIZE);
+      fail:
+	return 0;
+
+      release:
+	eata2x_release(shost);
+	return 0;
+}
+
+static void internal_setup(char *str, int *ints)
+{
+	int i, argc = ints[0];
+	char *cur = str, *pc;
+
+	if (argc > 0) {
+		if (argc > MAX_INT_PARAM)
+			argc = MAX_INT_PARAM;
+
+		for (i = 0; i < argc; i++)
+			io_port[i] = ints[i + 1];
+
+		io_port[i] = 0;
+		setup_done = 1;
+	}
+
+	while (cur && (pc = strchr(cur, ':'))) {
+		int val = 0, c = *++pc;
+
+		if (c == 'n' || c == 'N')
+			val = 0;
+		else if (c == 'y' || c == 'Y')
+			val = 1;
+		else
+			val = (int)simple_strtoul(pc, NULL, 0);
+
+		if (!strncmp(cur, "lc:", 3))
+			linked_comm = val;
+		else if (!strncmp(cur, "tm:", 3))
+			tag_mode = val;
+		else if (!strncmp(cur, "tc:", 3))
+			tag_mode = val;
+		else if (!strncmp(cur, "mq:", 3))
+			max_queue_depth = val;
+		else if (!strncmp(cur, "ls:", 3))
+			link_statistics = val;
+		else if (!strncmp(cur, "et:", 3))
+			ext_tran = val;
+		else if (!strncmp(cur, "rs:", 3))
+			rev_scan = val;
+		else if (!strncmp(cur, "ip:", 3))
+			isa_probe = val;
+		else if (!strncmp(cur, "ep:", 3))
+			eisa_probe = val;
+		else if (!strncmp(cur, "pp:", 3))
+			pci_probe = val;
+
+		if ((cur = strchr(cur, ',')))
+			++cur;
+	}
+
+	return;
+}
+
+static int option_setup(char *str)
+{
+	int ints[MAX_INT_PARAM];
+	char *cur = str;
+	int i = 1;
+
+	while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) {
+		ints[i++] = simple_strtoul(cur, NULL, 0);
+
+		if ((cur = strchr(cur, ',')) != NULL)
+			cur++;
+	}
+
+	ints[0] = i - 1;
+	internal_setup(cur, ints);
+	return 1;
 }
 
-static void add_pci_ports(void) {
-
+static void add_pci_ports(void)
+{
 #if defined(CONFIG_PCI)
+	unsigned int addr, k;
+	struct pci_dev *dev = NULL;
 
-   unsigned int addr, k;
-
-   struct pci_dev *dev = NULL;
-
-   for (k = 0; k < MAX_PCI; k++) {
-
-      if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
+	for (k = 0; k < MAX_PCI; k++) {
 
-      if (pci_enable_device (dev)) {
+		if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev)))
+			break;
 
+		if (pci_enable_device(dev)) {
 #if defined(DEBUG_PCI_DETECT)
-         printk("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n",
-                driver_name, dev->bus->number, dev->devfn);
+			printk
+			    ("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n",
+			     driver_name, dev->bus->number, dev->devfn);
 #endif
 
-         continue;
-         }
+			continue;
+		}
 
-      addr = pci_resource_start (dev, 0);
+		addr = pci_resource_start(dev, 0);
 
 #if defined(DEBUG_PCI_DETECT)
-      printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
-             driver_name, k, dev->bus->number, dev->devfn, addr);
+		printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",
+		       driver_name, k, dev->bus->number, dev->devfn, addr);
 #endif
 
-      /* Order addresses according to rev_scan value */
-      io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] =
-             addr + PCI_BASE_ADDRESS_0;
-      }
+		/* Order addresses according to rev_scan value */
+		io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] =
+		    addr + PCI_BASE_ADDRESS_0;
+	}
 
-   pci_dev_put(dev);
-#endif /* end CONFIG_PCI */
-
-   return;
+	pci_dev_put(dev);
+#endif				/* end CONFIG_PCI */
 }
 
-static int eata2x_detect(struct scsi_host_template *tpnt) {
-   unsigned int j = 0, k;
+static int eata2x_detect(struct scsi_host_template *tpnt)
+{
+	unsigned int j = 0, k;
 
-   tpnt->proc_name = "eata2x";
+	tpnt->proc_name = "eata2x";
 
-   if(strlen(boot_options)) option_setup(boot_options);
+	if (strlen(boot_options))
+		option_setup(boot_options);
 
 #if defined(MODULE)
-   /* io_port could have been modified when loading as a module */
-   if(io_port[0] != SKIP) {
-      setup_done = 1;
-      io_port[MAX_INT_PARAM] = 0;
-      }
-#endif
-
-   for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL;
-
-   for (k = MAX_INT_PARAM; io_port[k]; k++)
-      if (io_port[k] == SKIP) continue;
-      else if (io_port[k] <= MAX_ISA_ADDR) {
-         if (!isa_probe) io_port[k] = SKIP;
-         }
-      else if (io_port[k] >= MIN_EISA_ADDR && io_port[k] <= MAX_EISA_ADDR) {
-         if (!eisa_probe) io_port[k] = SKIP;
-         }
-
-   if (pci_probe) {
-      if (!setup_done) add_pci_ports();
-      else          enable_pci_ports();
-      }
-
-   for (k = 0; io_port[k]; k++) {
-
-      if (io_port[k] == SKIP) continue;
-
-      if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) j++;
-      }
-
-   num_boards = j;
-   return j;
-}
-
-static void map_dma(unsigned int i, unsigned int j) {
-   unsigned int k, count, pci_dir;
-   struct scatterlist *sgpnt;
-   struct mscp *cpp;
-   struct scsi_cmnd *SCpnt;
-
-   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
-   pci_dir = SCpnt->sc_data_direction;
-
-   if (SCpnt->sense_buffer)
-      cpp->sense_addr = H2DEV(pci_map_single(HD(j)->pdev, SCpnt->sense_buffer,
-                           sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE));
-
-   cpp->sense_len = sizeof SCpnt->sense_buffer;
-
-   if (!SCpnt->use_sg) {
+	/* io_port could have been modified when loading as a module */
+	if (io_port[0] != SKIP) {
+		setup_done = 1;
+		io_port[MAX_INT_PARAM] = 0;
+	}
+#endif
+
+	for (k = MAX_INT_PARAM; io_port[k]; k++)
+		if (io_port[k] == SKIP)
+			continue;
+		else if (io_port[k] <= MAX_ISA_ADDR) {
+			if (!isa_probe)
+				io_port[k] = SKIP;
+		} else if (io_port[k] >= MIN_EISA_ADDR
+			   && io_port[k] <= MAX_EISA_ADDR) {
+			if (!eisa_probe)
+				io_port[k] = SKIP;
+		}
+
+	if (pci_probe) {
+		if (!setup_done)
+			add_pci_ports();
+		else
+			enable_pci_ports();
+	}
+
+	for (k = 0; io_port[k]; k++) {
+
+		if (io_port[k] == SKIP)
+			continue;
+
+		if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt))
+			j++;
+	}
+
+	num_boards = j;
+	return j;
+}
+
+static void map_dma(unsigned int i, struct hostdata *ha)
+{
+	unsigned int k, count, pci_dir;
+	struct scatterlist *sgpnt;
+	struct mscp *cpp;
+	struct scsi_cmnd *SCpnt;
+
+	cpp = &ha->cp[i];
+	SCpnt = cpp->SCpnt;
+	pci_dir = SCpnt->sc_data_direction;
+
+	if (SCpnt->sense_buffer)
+		cpp->sense_addr =
+		    H2DEV(pci_map_single(ha->pdev, SCpnt->sense_buffer,
+			   sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE));
+
+	cpp->sense_len = sizeof SCpnt->sense_buffer;
+
+	if (!SCpnt->use_sg) {
+
+		/* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
+		if (!SCpnt->request_bufflen)
+			pci_dir = PCI_DMA_BIDIRECTIONAL;
+
+		if (SCpnt->request_buffer)
+			cpp->data_address = H2DEV(pci_map_single(ha->pdev,
+								 SCpnt->
+								 request_buffer,
+								 SCpnt->
+								 request_bufflen,
+								 pci_dir));
+
+		cpp->data_len = H2DEV(SCpnt->request_bufflen);
+		return;
+	}
+
+	sgpnt = (struct scatterlist *)SCpnt->request_buffer;
+	count = pci_map_sg(ha->pdev, sgpnt, SCpnt->use_sg, pci_dir);
+
+	for (k = 0; k < count; k++) {
+		cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
+		cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
+	}
+
+	cpp->sg = 1;
+	cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist,
+						 SCpnt->use_sg *
+						 sizeof(struct sg_list),
+						 pci_dir));
+	cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
+}
+
+static void unmap_dma(unsigned int i, struct hostdata *ha)
+{
+	unsigned int pci_dir;
+	struct mscp *cpp;
+	struct scsi_cmnd *SCpnt;
+
+	cpp = &ha->cp[i];
+	SCpnt = cpp->SCpnt;
+	pci_dir = SCpnt->sc_data_direction;
+
+	if (DEV2H(cpp->sense_addr))
+		pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr),
+				 DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
+
+	if (SCpnt->use_sg)
+		pci_unmap_sg(ha->pdev, SCpnt->request_buffer, SCpnt->use_sg,
+			     pci_dir);
+
+	if (!DEV2H(cpp->data_len))
+		pci_dir = PCI_DMA_BIDIRECTIONAL;
+
+	if (DEV2H(cpp->data_address))
+		pci_unmap_single(ha->pdev, DEV2H(cpp->data_address),
+				 DEV2H(cpp->data_len), pci_dir);
+}
+
+static void sync_dma(unsigned int i, struct hostdata *ha)
+{
+	unsigned int pci_dir;
+	struct mscp *cpp;
+	struct scsi_cmnd *SCpnt;
+
+	cpp = &ha->cp[i];
+	SCpnt = cpp->SCpnt;
+	pci_dir = SCpnt->sc_data_direction;
+
+	if (DEV2H(cpp->sense_addr))
+		pci_dma_sync_single_for_cpu(ha->pdev, DEV2H(cpp->sense_addr),
+					    DEV2H(cpp->sense_len),
+					    PCI_DMA_FROMDEVICE);
+
+	if (SCpnt->use_sg)
+		pci_dma_sync_sg_for_cpu(ha->pdev, SCpnt->request_buffer,
+					SCpnt->use_sg, pci_dir);
+
+	if (!DEV2H(cpp->data_len))
+		pci_dir = PCI_DMA_BIDIRECTIONAL;
+
+	if (DEV2H(cpp->data_address))
+		pci_dma_sync_single_for_cpu(ha->pdev,
+					    DEV2H(cpp->data_address),
+					    DEV2H(cpp->data_len), pci_dir);
+}
+
+static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha)
+{
+	unsigned int k;
+
+	static const unsigned char data_out_cmds[] = {
+		0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e,
+		0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40,
+		0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d
+	};
+
+	static const unsigned char data_none_cmds[] = {
+		0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e,
+		0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47,
+		0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00
+	};
+
+	struct mscp *cpp;
+	struct scsi_cmnd *SCpnt;
+
+	cpp = &ha->cp[i];
+	SCpnt = cpp->SCpnt;
+
+	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
+		cpp->din = 1;
+		cpp->dout = 0;
+		return;
+	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
+		cpp->din = 0;
+		cpp->dout = 1;
+		return;
+	} else if (SCpnt->sc_data_direction == DMA_NONE) {
+		cpp->din = 0;
+		cpp->dout = 0;
+		return;
+	}
+
+	if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL)
+		panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n",
+				ha->board_name);
+
+	for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
+		if (SCpnt->cmnd[0] == data_out_cmds[k]) {
+			cpp->dout = 1;
+			break;
+		}
+
+	if ((cpp->din = !cpp->dout))
+		for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
+			if (SCpnt->cmnd[0] == data_none_cmds[k]) {
+				cpp->din = 0;
+				break;
+			}
+
+}
+
+static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
+			       void (*done) (struct scsi_cmnd *))
+{
+	struct Scsi_Host *shost = SCpnt->device->host;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	unsigned int i, k;
+	struct mscp *cpp;
+
+	if (SCpnt->host_scribble)
+		panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
+		      ha->board_name, SCpnt->pid, SCpnt);
+
+	/* i is the mailbox number, look for the first free mailbox
+	   starting from last_cp_used */
+	i = ha->last_cp_used + 1;
+
+	for (k = 0; k < shost->can_queue; k++, i++) {
+		if (i >= shost->can_queue)
+			i = 0;
+		if (ha->cp_stat[i] == FREE) {
+			ha->last_cp_used = i;
+			break;
+		}
+	}
+
+	if (k == shost->can_queue) {
+		printk("%s: qcomm, no free mailbox.\n", ha->board_name);
+		return 1;
+	}
+
+	/* Set pointer to control packet structure */
+	cpp = &ha->cp[i];
+
+	memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE);
+
+	/* Set pointer to status packet structure, Big Endian format */
+	cpp->sp_dma_addr = H2DEV(ha->sp_dma_addr);
+
+	SCpnt->scsi_done = done;
+	cpp->cpp_index = i;
+	SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index;
+
+	if (do_trace)
+		printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+		       ha->board_name, i, SCpnt->device->channel, SCpnt->device->id,
+		       SCpnt->device->lun, SCpnt->pid);
 
-      /* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */
-      if (!SCpnt->request_bufflen) pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-      if (SCpnt->request_buffer)
-         cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev,
-                  SCpnt->request_buffer, SCpnt->request_bufflen, pci_dir));
-
-      cpp->data_len = H2DEV(SCpnt->request_bufflen);
-      return;
-      }
-
-   sgpnt = (struct scatterlist *) SCpnt->request_buffer;
-   count = pci_map_sg(HD(j)->pdev, sgpnt, SCpnt->use_sg, pci_dir);
-
-   for (k = 0; k < count; k++) {
-      cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
-      cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
-      }
-
-   cpp->sg = 1;
-   cpp->data_address = H2DEV(pci_map_single(HD(j)->pdev, cpp->sglist,
-                             SCpnt->use_sg * sizeof(struct sg_list), pci_dir));
-   cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
-}
-
-static void unmap_dma(unsigned int i, unsigned int j) {
-   unsigned int pci_dir;
-   struct mscp *cpp;
-   struct scsi_cmnd *SCpnt;
-
-   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
-   pci_dir = SCpnt->sc_data_direction;
-
-   if (DEV2H(cpp->sense_addr))
-      pci_unmap_single(HD(j)->pdev, DEV2H(cpp->sense_addr),
-                       DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
-
-   if (SCpnt->use_sg)
-      pci_unmap_sg(HD(j)->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir);
-
-   if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-   if (DEV2H(cpp->data_address))
-      pci_unmap_single(HD(j)->pdev, DEV2H(cpp->data_address),
-                       DEV2H(cpp->data_len), pci_dir);
-}
-
-static void sync_dma(unsigned int i, unsigned int j) {
-   unsigned int pci_dir;
-   struct mscp *cpp;
-   struct scsi_cmnd *SCpnt;
-
-   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
-   pci_dir = SCpnt->sc_data_direction;
-
-   if (DEV2H(cpp->sense_addr))
-      pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->sense_addr),
-                          DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE);
-
-   if (SCpnt->use_sg)
-      pci_dma_sync_sg_for_cpu(HD(j)->pdev, SCpnt->request_buffer,
-                         SCpnt->use_sg, pci_dir);
-
-   if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL;
-
-   if (DEV2H(cpp->data_address))
-      pci_dma_sync_single_for_cpu(HD(j)->pdev, DEV2H(cpp->data_address),
-                       DEV2H(cpp->data_len), pci_dir);
-}
-
-static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
-   unsigned int k;
-
-   static const unsigned char data_out_cmds[] = {
-      0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e,
-      0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40,
-      0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d
-      };
-
-   static const unsigned char data_none_cmds[] = {
-      0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e,
-      0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47,
-      0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00
-      };
-
-   struct mscp *cpp;
-   struct scsi_cmnd *SCpnt;
-
-   cpp = &HD(j)->cp[i]; SCpnt = cpp->SCpnt;
-
-   if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
-      cpp->din  = 1;
-      cpp->dout = 0;
-      return;
-      }
-   else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
-      cpp->din  = 0;
-      cpp->dout = 1;
-      return;
-      }
-   else if (SCpnt->sc_data_direction == DMA_NONE) {
-      cpp->din  = 0;
-      cpp->dout = 0;
-      return;
-      }
-
-   if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL)
-      panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", BN(j));
-
-   for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
-      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
-         cpp->dout = 1;
-         break;
-         }
-
-   if ((cpp->din = !cpp->dout))
-      for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)
-         if (SCpnt->cmnd[0] == data_none_cmds[k]) {
-            cpp->din = 0;
-            break;
-            }
-
-}
-
-static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
-   unsigned int i, j, k;
-   struct mscp *cpp;
-
-   /* j is the board number */
-   j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number;
-
-   if (SCpnt->host_scribble)
-      panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
-            BN(j), SCpnt->pid, SCpnt);
-
-   /* i is the mailbox number, look for the first free mailbox
-      starting from last_cp_used */
-   i = HD(j)->last_cp_used + 1;
-
-   for (k = 0; k < sh[j]->can_queue; k++, i++) {
-
-      if (i >= sh[j]->can_queue) i = 0;
-
-      if (HD(j)->cp_stat[i] == FREE) {
-         HD(j)->last_cp_used = i;
-         break;
-         }
-      }
-
-   if (k == sh[j]->can_queue) {
-      printk("%s: qcomm, no free mailbox.\n", BN(j));
-      return 1;
-      }
-
-   /* Set pointer to control packet structure */
-   cpp = &HD(j)->cp[i];
-
-   memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE);
-
-   /* Set pointer to status packet structure, Big Endian format */
-   cpp->sp_dma_addr = H2DEV(HD(j)->sp_dma_addr);
-
-   SCpnt->scsi_done = done;
-   cpp->cpp_index = i;
-   SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
-
-   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
-                        BN(j), i, SCpnt->device->channel, SCpnt->device->id,
-                        SCpnt->device->lun, SCpnt->pid);
-
-   cpp->reqsen = 1;
-   cpp->dispri = 1;
+	cpp->reqsen = 1;
+	cpp->dispri = 1;
 #if 0
-   if (SCpnt->device->type == TYPE_TAPE) cpp->hbaci = 1;
+	if (SCpnt->device->type == TYPE_TAPE)
+		cpp->hbaci = 1;
 #endif
-   cpp->one = 1;
-   cpp->channel = SCpnt->device->channel;
-   cpp->target = SCpnt->device->id;
-   cpp->lun = SCpnt->device->lun;
-   cpp->SCpnt = SCpnt;
-   memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
-
-   /* Use data transfer direction SCpnt->sc_data_direction */
-   scsi_to_dev_dir(i, j);
-
-   /* Map DMA buffers and SG list */
-   map_dma(i, j);
-
-   if (linked_comm && SCpnt->device->queue_depth > 2
-                                     && TLDEV(SCpnt->device->type)) {
-      HD(j)->cp_stat[i] = READY;
-      flush_dev(SCpnt->device, SCpnt->request->sector, j, 0);
-      return 0;
-      }
-
-   /* Send control packet to the board */
-   if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
-      unmap_dma(i, j);
-      SCpnt->host_scribble = NULL;
-      printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
-             BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid);
-      return 1;
-      }
-
-   HD(j)->cp_stat[i] = IN_USE;
-   return 0;
-}
-
-static int eata2x_eh_abort(struct scsi_cmnd *SCarg) {
-   unsigned int i, j;
-
-   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
-
-   if (SCarg->host_scribble == NULL) {
-      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
-             BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
-      return SUCCESS;
-      }
-
-   i = *(unsigned int *)SCarg->host_scribble;
-   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
-          BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
-
-   if (i >= sh[j]->can_queue)
-      panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: abort, timeout error.\n", BN(j));
-      return FAILED;
-      }
-
-   if (HD(j)->cp_stat[i] == FREE) {
-      printk("%s: abort, mbox %d is free.\n", BN(j), i);
-      return SUCCESS;
-      }
-
-   if (HD(j)->cp_stat[i] == IN_USE) {
-      printk("%s: abort, mbox %d is in use.\n", BN(j), i);
-
-      if (SCarg != HD(j)->cp[i].SCpnt)
-         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
-               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
-
-      if (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)
-         printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i);
-
-      if (SCarg->eh_state == SCSI_STATE_TIMEOUT) {
-         unmap_dma(i, j);
-         SCarg->host_scribble = NULL;
-         HD(j)->cp_stat[i] = FREE;
-         printk("%s, abort, mbox %d, eh_state timeout, pid %ld.\n",
-                BN(j), i, SCarg->pid);
-         return SUCCESS;
-         }
-
-      return FAILED;
-      }
-
-   if (HD(j)->cp_stat[i] == IN_RESET) {
-      printk("%s: abort, mbox %d is in reset.\n", BN(j), i);
-      return FAILED;
-      }
-
-   if (HD(j)->cp_stat[i] == LOCKED) {
-      printk("%s: abort, mbox %d is locked.\n", BN(j), i);
-      return SUCCESS;
-      }
-
-   if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
-      unmap_dma(i, j);
-      SCarg->result = DID_ABORT << 16;
-      SCarg->host_scribble = NULL;
-      HD(j)->cp_stat[i] = FREE;
-      printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
-             BN(j), i, SCarg->pid);
-      SCarg->scsi_done(SCarg);
-      return SUCCESS;
-      }
-
-   panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
-}
-
-static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) {
-   unsigned int i, j, time, k, c, limit = 0;
-   int arg_done = 0;
-   struct scsi_cmnd *SCpnt;
-
-   j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
-   printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
-          BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
-
-   if (SCarg->host_scribble == NULL)
-      printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
-
-   if (HD(j)->in_reset) {
-      printk("%s: reset, exit, already in reset.\n", BN(j));
-      return FAILED;
-      }
-
-   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
-      printk("%s: reset, exit, timeout error.\n", BN(j));
-      return FAILED;
-      }
-
-   HD(j)->retries = 0;
-
-   for (c = 0; c <= sh[j]->max_channel; c++)
-      for (k = 0; k < sh[j]->max_id; k++) {
-         HD(j)->target_redo[k][c] = 1;
-         HD(j)->target_to[k][c] = 0;
-         }
-
-   for (i = 0; i < sh[j]->can_queue; i++) {
-
-      if (HD(j)->cp_stat[i] == FREE) continue;
-
-      if (HD(j)->cp_stat[i] == LOCKED) {
-         HD(j)->cp_stat[i] = FREE;
-         printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
-         continue;
-         }
-
-      if (!(SCpnt = HD(j)->cp[i].SCpnt))
-         panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
-      if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
-         HD(j)->cp_stat[i] = ABORTING;
-         printk("%s: reset, mbox %d aborting, pid %ld.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      else {
-         HD(j)->cp_stat[i] = IN_RESET;
-         printk("%s: reset, mbox %d in reset, pid %ld.\n",
-                BN(j), i, SCpnt->pid);
-         }
-
-      if (SCpnt->host_scribble == NULL)
-         panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
-
-      if (*(unsigned int *)SCpnt->host_scribble != i)
-         panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
-
-      if (SCpnt->scsi_done == NULL)
-         panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
-
-      if (SCpnt == SCarg) arg_done = 1;
-      }
-
-   if (do_dma(sh[j]->io_port, 0, RESET_PIO)) {
-      printk("%s: reset, cannot reset, timeout error.\n", BN(j));
-      return FAILED;
-      }
+	cpp->one = 1;
+	cpp->channel = SCpnt->device->channel;
+	cpp->target = SCpnt->device->id;
+	cpp->lun = SCpnt->device->lun;
+	cpp->SCpnt = SCpnt;
+	memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+
+	/* Use data transfer direction SCpnt->sc_data_direction */
+	scsi_to_dev_dir(i, ha);
+
+	/* Map DMA buffers and SG list */
+	map_dma(i, ha);
+
+	if (linked_comm && SCpnt->device->queue_depth > 2
+	    && TLDEV(SCpnt->device->type)) {
+		ha->cp_stat[i] = READY;
+		flush_dev(SCpnt->device, SCpnt->request->sector, ha, 0);
+		return 0;
+	}
+
+	/* Send control packet to the board */
+	if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
+		unmap_dma(i, ha);
+		SCpnt->host_scribble = NULL;
+		printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",
+		       ha->board_name, SCpnt->device->channel, SCpnt->device->id,
+		       SCpnt->device->lun, SCpnt->pid);
+		return 1;
+	}
+
+	ha->cp_stat[i] = IN_USE;
+	return 0;
+}
+
+static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
+{
+	struct Scsi_Host *shost = SCarg->device->host;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	unsigned int i;
+
+	if (SCarg->host_scribble == NULL) {
+		printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
+		       ha->board_name, SCarg->device->channel, SCarg->device->id,
+		       SCarg->device->lun, SCarg->pid);
+		return SUCCESS;
+	}
+
+	i = *(unsigned int *)SCarg->host_scribble;
+	printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
+	       ha->board_name, i, SCarg->device->channel, SCarg->device->id,
+	       SCarg->device->lun, SCarg->pid);
+
+	if (i >= shost->can_queue)
+		panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name);
+
+	if (wait_on_busy(shost->io_port, MAXLOOP)) {
+		printk("%s: abort, timeout error.\n", ha->board_name);
+		return FAILED;
+	}
+
+	if (ha->cp_stat[i] == FREE) {
+		printk("%s: abort, mbox %d is free.\n", ha->board_name, i);
+		return SUCCESS;
+	}
+
+	if (ha->cp_stat[i] == IN_USE) {
+		printk("%s: abort, mbox %d is in use.\n", ha->board_name, i);
+
+		if (SCarg != ha->cp[i].SCpnt)
+			panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
+			      ha->board_name, i, SCarg, ha->cp[i].SCpnt);
+
+		if (inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)
+			printk("%s: abort, mbox %d, interrupt pending.\n",
+			       ha->board_name, i);
+
+		if (SCarg->eh_state == SCSI_STATE_TIMEOUT) {
+			unmap_dma(i, ha);
+			SCarg->host_scribble = NULL;
+			ha->cp_stat[i] = FREE;
+			printk
+			    ("%s, abort, mbox %d, eh_state timeout, pid %ld.\n",
+			     ha->board_name, i, SCarg->pid);
+			return SUCCESS;
+		}
+
+		return FAILED;
+	}
+
+	if (ha->cp_stat[i] == IN_RESET) {
+		printk("%s: abort, mbox %d is in reset.\n", ha->board_name, i);
+		return FAILED;
+	}
+
+	if (ha->cp_stat[i] == LOCKED) {
+		printk("%s: abort, mbox %d is locked.\n", ha->board_name, i);
+		return SUCCESS;
+	}
+
+	if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) {
+		unmap_dma(i, ha);
+		SCarg->result = DID_ABORT << 16;
+		SCarg->host_scribble = NULL;
+		ha->cp_stat[i] = FREE;
+		printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
+		       ha->board_name, i, SCarg->pid);
+		SCarg->scsi_done(SCarg);
+		return SUCCESS;
+	}
+
+	panic("%s: abort, mbox %d, invalid cp_stat.\n", ha->board_name, i);
+}
+
+static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
+{
+	unsigned int i, time, k, c, limit = 0;
+	int arg_done = 0;
+	struct scsi_cmnd *SCpnt;
+	struct Scsi_Host *shost = SCarg->device->host;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+
+	printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
+	       ha->board_name, SCarg->device->channel, SCarg->device->id,
+	       SCarg->device->lun, SCarg->pid);
+
+	if (SCarg->host_scribble == NULL)
+		printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid);
+
+	if (ha->in_reset) {
+		printk("%s: reset, exit, already in reset.\n", ha->board_name);
+		return FAILED;
+	}
+
+	if (wait_on_busy(shost->io_port, MAXLOOP)) {
+		printk("%s: reset, exit, timeout error.\n", ha->board_name);
+		return FAILED;
+	}
+
+	ha->retries = 0;
+
+	for (c = 0; c <= shost->max_channel; c++)
+		for (k = 0; k < shost->max_id; k++) {
+			ha->target_redo[k][c] = 1;
+			ha->target_to[k][c] = 0;
+		}
+
+	for (i = 0; i < shost->can_queue; i++) {
+
+		if (ha->cp_stat[i] == FREE)
+			continue;
+
+		if (ha->cp_stat[i] == LOCKED) {
+			ha->cp_stat[i] = FREE;
+			printk("%s: reset, locked mbox %d forced free.\n",
+			       ha->board_name, i);
+			continue;
+		}
+
+		if (!(SCpnt = ha->cp[i].SCpnt))
+			panic("%s: reset, mbox %d, SCpnt == NULL.\n", ha->board_name, i);
+
+		if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) {
+			ha->cp_stat[i] = ABORTING;
+			printk("%s: reset, mbox %d aborting, pid %ld.\n",
+			       ha->board_name, i, SCpnt->pid);
+		}
+
+		else {
+			ha->cp_stat[i] = IN_RESET;
+			printk("%s: reset, mbox %d in reset, pid %ld.\n",
+			       ha->board_name, i, SCpnt->pid);
+		}
+
+		if (SCpnt->host_scribble == NULL)
+			panic("%s: reset, mbox %d, garbled SCpnt.\n", ha->board_name, i);
+
+		if (*(unsigned int *)SCpnt->host_scribble != i)
+			panic("%s: reset, mbox %d, index mismatch.\n", ha->board_name, i);
+
+		if (SCpnt->scsi_done == NULL)
+			panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n",
+			      ha->board_name, i);
+
+		if (SCpnt == SCarg)
+			arg_done = 1;
+	}
+
+	if (do_dma(shost->io_port, 0, RESET_PIO)) {
+		printk("%s: reset, cannot reset, timeout error.\n", ha->board_name);
+		return FAILED;
+	}
 
-   printk("%s: reset, board reset done, enabling interrupts.\n", BN(j));
+	printk("%s: reset, board reset done, enabling interrupts.\n", ha->board_name);
 
 #if defined(DEBUG_RESET)
-   do_trace = 1;
+	do_trace = 1;
 #endif
 
-   HD(j)->in_reset = 1;
+	ha->in_reset = 1;
 
-   spin_unlock_irq(sh[j]->host_lock);
-   time = jiffies;
-   while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);
-   spin_lock_irq(sh[j]->host_lock);
+	spin_unlock_irq(shost->host_lock);
+	time = jiffies;
+	while ((jiffies - time) < (10 * HZ) && limit++ < 200000)
+		udelay(100L);
+	spin_lock_irq(shost->host_lock);
 
-   printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
+	printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit);
 
-   for (i = 0; i < sh[j]->can_queue; i++) {
+	for (i = 0; i < shost->can_queue; i++) {
 
-      if (HD(j)->cp_stat[i] == IN_RESET) {
-         SCpnt = HD(j)->cp[i].SCpnt;
-         unmap_dma(i, j);
-         SCpnt->result = DID_RESET << 16;
-         SCpnt->host_scribble = NULL;
+		if (ha->cp_stat[i] == IN_RESET) {
+			SCpnt = ha->cp[i].SCpnt;
+			unmap_dma(i, ha);
+			SCpnt->result = DID_RESET << 16;
+			SCpnt->host_scribble = NULL;
 
-         /* This mailbox is still waiting for its interrupt */
-         HD(j)->cp_stat[i] = LOCKED;
+			/* This mailbox is still waiting for its interrupt */
+			ha->cp_stat[i] = LOCKED;
 
-         printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->pid);
-         }
+			printk
+			    ("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
+			     ha->board_name, i, SCpnt->pid);
+		}
 
-      else if (HD(j)->cp_stat[i] == ABORTING) {
-         SCpnt = HD(j)->cp[i].SCpnt;
-         unmap_dma(i, j);
-         SCpnt->result = DID_RESET << 16;
-         SCpnt->host_scribble = NULL;
+		else if (ha->cp_stat[i] == ABORTING) {
+			SCpnt = ha->cp[i].SCpnt;
+			unmap_dma(i, ha);
+			SCpnt->result = DID_RESET << 16;
+			SCpnt->host_scribble = NULL;
 
-         /* This mailbox was never queued to the adapter */
-         HD(j)->cp_stat[i] = FREE;
+			/* This mailbox was never queued to the adapter */
+			ha->cp_stat[i] = FREE;
 
-         printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->pid);
-         }
+			printk
+			    ("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
+			     ha->board_name, i, SCpnt->pid);
+		}
 
-      else
+		else
+			/* Any other mailbox has already been set free by interrupt */
+			continue;
 
-         /* Any other mailbox has already been set free by interrupt */
-         continue;
+		SCpnt->scsi_done(SCpnt);
+	}
 
-      SCpnt->scsi_done(SCpnt);
-      }
+	ha->in_reset = 0;
+	do_trace = 0;
 
-   HD(j)->in_reset = 0;
-   do_trace = 0;
+	if (arg_done)
+		printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->pid);
+	else
+		printk("%s: reset, exit.\n", ha->board_name);
 
-   if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid);
-   else          printk("%s: reset, exit.\n", BN(j));
-
-   return SUCCESS;
+	return SUCCESS;
 }
 
 int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev,
-                      sector_t capacity, int *dkinfo) {
-   unsigned int size = capacity;
-
-   if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
-      dkinfo[0] = 255;
-      dkinfo[1] = 63;
-      dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
-      }
-
+		      sector_t capacity, int *dkinfo)
+{
+	unsigned int size = capacity;
+
+	if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
+		dkinfo[0] = 255;
+		dkinfo[1] = 63;
+		dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
+	}
 #if defined (DEBUG_GEOMETRY)
-   printk ("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
-           dkinfo[0], dkinfo[1], dkinfo[2]);
+	printk("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
+	       dkinfo[0], dkinfo[1], dkinfo[2]);
 #endif
 
-   return 0;
+	return 0;
 }
 
 static void sort(unsigned long sk[], unsigned int da[], unsigned int n,
-                 unsigned int rev) {
-   unsigned int i, j, k, y;
-   unsigned long x;
-
-   for (i = 0; i < n - 1; i++) {
-      k = i;
-
-      for (j = k + 1; j < n; j++)
-         if (rev) {
-            if (sk[j] > sk[k]) k = j;
-            }
-         else {
-            if (sk[j] < sk[k]) k = j;
-            }
-
-      if (k != i) {
-         x = sk[k]; sk[k] = sk[i]; sk[i] = x;
-         y = da[k]; da[k] = da[i]; da[i] = y;
-         }
-      }
-
-   return;
-   }
-
-static int reorder(unsigned int j, unsigned long cursec,
-                 unsigned int ihdlr, unsigned int il[], unsigned int n_ready) {
-   struct scsi_cmnd *SCpnt;
-   struct mscp *cpp;
-   unsigned int k, n;
-   unsigned int rev = 0, s = 1, r = 1;
-   unsigned int input_only = 1, overlap = 0;
-   unsigned long sl[n_ready], pl[n_ready], ll[n_ready];
-   unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0;
-   unsigned long ioseek = 0;
-
-   static unsigned int flushcount = 0, batchcount = 0, sortcount = 0;
-   static unsigned int readycount = 0, ovlcount = 0, inputcount = 0;
-   static unsigned int readysorted = 0, revcount = 0;
-   static unsigned long seeksorted = 0, seeknosort = 0;
-
-   if (link_statistics && !(++flushcount % link_statistics))
-      printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"\
-             " av %ldK as %ldK.\n", flushcount, batchcount, inputcount,
-             ovlcount, readycount, readysorted, sortcount, revcount,
-             seeknosort / (readycount + 1),
-             seeksorted / (readycount + 1));
-
-   if (n_ready <= 1) return 0;
-
-   for (n = 0; n < n_ready; n++) {
-      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-
-      if (!cpp->din) input_only = 0;
-
-      if (SCpnt->request->sector < minsec) minsec = SCpnt->request->sector;
-      if (SCpnt->request->sector > maxsec) maxsec = SCpnt->request->sector;
-
-      sl[n] = SCpnt->request->sector;
-      ioseek += SCpnt->request->nr_sectors;
-
-      if (!n) continue;
-
-      if (sl[n] < sl[n - 1]) s = 0;
-      if (sl[n] > sl[n - 1]) r = 0;
-
-      if (link_statistics) {
-         if (sl[n] > sl[n - 1])
-            seek += sl[n] - sl[n - 1];
-         else
-            seek += sl[n - 1] - sl[n];
-         }
-
-      }
-
-   if (link_statistics) {
-      if (cursec > sl[0]) seek += cursec - sl[0]; else seek += sl[0] - cursec;
-      }
-
-   if (cursec > ((maxsec + minsec) / 2)) rev = 1;
-
-   if (ioseek > ((maxsec - minsec) / 2)) rev = 0;
-
-   if (!((rev && r) || (!rev && s))) sort(sl, il, n_ready, rev);
-
-   if (!input_only) for (n = 0; n < n_ready; n++) {
-      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-      ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->pid;
-
-      if (!n) continue;
-
-      if ((sl[n] == sl[n - 1]) || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n]))
-          || (rev && ((sl[n] + ll[n]) > sl[n - 1]))) overlap = 1;
-      }
-
-   if (overlap) sort(pl, il, n_ready, 0);
-
-   if (link_statistics) {
-      if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec;
-      batchcount++; readycount += n_ready; seeknosort += seek / 1024;
-      if (input_only) inputcount++;
-      if (overlap) { ovlcount++; seeksorted += iseek / 1024; }
-      else seeksorted += (iseek + maxsec - minsec) / 1024;
-      if (rev && !r)     {  revcount++; readysorted += n_ready; }
-      if (!rev && !s)    { sortcount++; readysorted += n_ready; }
-      }
-
+		 unsigned int rev)
+{
+	unsigned int i, j, k, y;
+	unsigned long x;
+
+	for (i = 0; i < n - 1; i++) {
+		k = i;
+
+		for (j = k + 1; j < n; j++)
+			if (rev) {
+				if (sk[j] > sk[k])
+					k = j;
+			} else {
+				if (sk[j] < sk[k])
+					k = j;
+			}
+
+		if (k != i) {
+			x = sk[k];
+			sk[k] = sk[i];
+			sk[i] = x;
+			y = da[k];
+			da[k] = da[i];
+			da[i] = y;
+		}
+	}
+
+	return;
+}
+
+static int reorder(struct hostdata *ha, unsigned long cursec,
+		   unsigned int ihdlr, unsigned int il[], unsigned int n_ready)
+{
+	struct scsi_cmnd *SCpnt;
+	struct mscp *cpp;
+	unsigned int k, n;
+	unsigned int rev = 0, s = 1, r = 1;
+	unsigned int input_only = 1, overlap = 0;
+	unsigned long sl[n_ready], pl[n_ready], ll[n_ready];
+	unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0;
+	unsigned long ioseek = 0;
+
+	static unsigned int flushcount = 0, batchcount = 0, sortcount = 0;
+	static unsigned int readycount = 0, ovlcount = 0, inputcount = 0;
+	static unsigned int readysorted = 0, revcount = 0;
+	static unsigned long seeksorted = 0, seeknosort = 0;
+
+	if (link_statistics && !(++flushcount % link_statistics))
+		printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d"
+		       " av %ldK as %ldK.\n", flushcount, batchcount,
+		       inputcount, ovlcount, readycount, readysorted, sortcount,
+		       revcount, seeknosort / (readycount + 1),
+		       seeksorted / (readycount + 1));
+
+	if (n_ready <= 1)
+		return 0;
+
+	for (n = 0; n < n_ready; n++) {
+		k = il[n];
+		cpp = &ha->cp[k];
+		SCpnt = cpp->SCpnt;
+
+		if (!cpp->din)
+			input_only = 0;
+
+		if (SCpnt->request->sector < minsec)
+			minsec = SCpnt->request->sector;
+		if (SCpnt->request->sector > maxsec)
+			maxsec = SCpnt->request->sector;
+
+		sl[n] = SCpnt->request->sector;
+		ioseek += SCpnt->request->nr_sectors;
+
+		if (!n)
+			continue;
+
+		if (sl[n] < sl[n - 1])
+			s = 0;
+		if (sl[n] > sl[n - 1])
+			r = 0;
+
+		if (link_statistics) {
+			if (sl[n] > sl[n - 1])
+				seek += sl[n] - sl[n - 1];
+			else
+				seek += sl[n - 1] - sl[n];
+		}
+
+	}
+
+	if (link_statistics) {
+		if (cursec > sl[0])
+			seek += cursec - sl[0];
+		else
+			seek += sl[0] - cursec;
+	}
+
+	if (cursec > ((maxsec + minsec) / 2))
+		rev = 1;
+
+	if (ioseek > ((maxsec - minsec) / 2))
+		rev = 0;
+
+	if (!((rev && r) || (!rev && s)))
+		sort(sl, il, n_ready, rev);
+
+	if (!input_only)
+		for (n = 0; n < n_ready; n++) {
+			k = il[n];
+			cpp = &ha->cp[k];
+			SCpnt = cpp->SCpnt;
+			ll[n] = SCpnt->request->nr_sectors;
+			pl[n] = SCpnt->pid;
+
+			if (!n)
+				continue;
+
+			if ((sl[n] == sl[n - 1])
+			    || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n]))
+			    || (rev && ((sl[n] + ll[n]) > sl[n - 1])))
+				overlap = 1;
+		}
+
+	if (overlap)
+		sort(pl, il, n_ready, 0);
+
+	if (link_statistics) {
+		if (cursec > sl[0])
+			iseek = cursec - sl[0];
+		else
+			iseek = sl[0] - cursec;
+		batchcount++;
+		readycount += n_ready;
+		seeknosort += seek / 1024;
+		if (input_only)
+			inputcount++;
+		if (overlap) {
+			ovlcount++;
+			seeksorted += iseek / 1024;
+		} else
+			seeksorted += (iseek + maxsec - minsec) / 1024;
+		if (rev && !r) {
+			revcount++;
+			readysorted += n_ready;
+		}
+		if (!rev && !s) {
+			sortcount++;
+			readysorted += n_ready;
+		}
+	}
 #if defined(DEBUG_LINKED_COMMANDS)
-   if (link_statistics && (overlap || !(flushcount % link_statistics)))
-      for (n = 0; n < n_ready; n++) {
-         k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-         printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\
-                " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
-                (ihdlr ? "ihdlr" : "qcomm"), SCpnt->device->channel, SCpnt->device->id,
-                SCpnt->device->lun, SCpnt->pid, k, flushcount, n_ready,
-                SCpnt->request->sector, SCpnt->request->nr_sectors, cursec,
-                YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
-                YESNO(overlap), cpp->din);
-         }
-#endif
-   return overlap;
-}
-
-static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned int j,
-                      unsigned int ihdlr) {
-   struct scsi_cmnd *SCpnt;
-   struct mscp *cpp;
-   unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES];
-
-   for (k = 0; k < sh[j]->can_queue; k++) {
+	if (link_statistics && (overlap || !(flushcount % link_statistics)))
+		for (n = 0; n < n_ready; n++) {
+			k = il[n];
+			cpp = &ha->cp[k];
+			SCpnt = cpp->SCpnt;
+			printk
+			    ("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"
+			     " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
+			     (ihdlr ? "ihdlr" : "qcomm"),
+			     SCpnt->device->channel, SCpnt->device->id,
+			     SCpnt->device->lun, SCpnt->pid, k, flushcount,
+			     n_ready, SCpnt->request->sector,
+			     SCpnt->request->nr_sectors, cursec, YESNO(s),
+			     YESNO(r), YESNO(rev), YESNO(input_only),
+			     YESNO(overlap), cpp->din);
+		}
+#endif
+	return overlap;
+}
+
+static void flush_dev(struct scsi_device *dev, unsigned long cursec,
+		      struct hostdata *ha, unsigned int ihdlr)
+{
+	struct scsi_cmnd *SCpnt;
+	struct mscp *cpp;
+	unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES];
+
+	for (k = 0; k < dev->host->can_queue; k++) {
+
+		if (ha->cp_stat[k] != READY && ha->cp_stat[k] != IN_USE)
+			continue;
+
+		cpp = &ha->cp[k];
+		SCpnt = cpp->SCpnt;
+
+		if (SCpnt->device != dev)
+			continue;
+
+		if (ha->cp_stat[k] == IN_USE)
+			return;
+
+		il[n_ready++] = k;
+	}
+
+	if (reorder(ha, cursec, ihdlr, il, n_ready))
+		n_ready = 1;
+
+	for (n = 0; n < n_ready; n++) {
+		k = il[n];
+		cpp = &ha->cp[k];
+		SCpnt = cpp->SCpnt;
+
+		if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
+			printk
+			    ("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"
+			     " busy, will abort.\n", ha->board_name,
+			     (ihdlr ? "ihdlr" : "qcomm"),
+			     SCpnt->device->channel, SCpnt->device->id,
+			     SCpnt->device->lun, SCpnt->pid, k);
+			ha->cp_stat[k] = ABORTING;
+			continue;
+		}
+
+		ha->cp_stat[k] = IN_USE;
+	}
+}
+
+static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost)
+{
+	struct scsi_cmnd *SCpnt;
+	unsigned int i, k, c, status, tstatus, reg;
+	struct mssp *spp;
+	struct mscp *cpp;
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+
+	if (shost->irq != irq)
+		panic("%s: ihdlr, irq %d, shost->irq %d.\n", ha->board_name, irq,
+		      shost->irq);
+
+	/* Check if this board need to be serviced */
+	if (!(inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED))
+		goto none;
+
+	ha->iocount++;
+
+	if (do_trace)
+		printk("%s: ihdlr, enter, irq %d, count %d.\n", ha->board_name, irq,
+		       ha->iocount);
+
+	/* Check if this board is still busy */
+	if (wait_on_busy(shost->io_port, 20 * MAXLOOP)) {
+		reg = inb(shost->io_port + REG_STATUS);
+		printk
+		    ("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
+		     ha->board_name, irq, reg, ha->iocount);
+		goto none;
+	}
+
+	spp = &ha->sp;
 
-      if (HD(j)->cp_stat[k] != READY && HD(j)->cp_stat[k] != IN_USE) continue;
-
-      cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-
-      if (SCpnt->device != dev) continue;
-
-      if (HD(j)->cp_stat[k] == IN_USE) return;
-
-      il[n_ready++] = k;
-      }
-
-   if (reorder(j, cursec, ihdlr, il, n_ready)) n_ready = 1;
-
-   for (n = 0; n < n_ready; n++) {
-      k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-
-      if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
-         printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\
-                " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"),
-                SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k);
-         HD(j)->cp_stat[k] = ABORTING;
-         continue;
-         }
-
-      HD(j)->cp_stat[k] = IN_USE;
-      }
-
-}
+	/* Make a local copy just before clearing the interrupt indication */
+	memcpy(spp, ha->sp_cpu_addr, sizeof(struct mssp));
 
-static irqreturn_t ihdlr(int irq, unsigned int j) {
-   struct scsi_cmnd *SCpnt;
-   unsigned int i, k, c, status, tstatus, reg;
-   struct mssp *spp;
-   struct mscp *cpp;
+	/* Clear the completion flag and cp pointer on the dynamic copy of sp */
+	memset(ha->sp_cpu_addr, 0, sizeof(struct mssp));
 
-   if (sh[j]->irq != irq)
-       panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq);
-
-   /* Check if this board need to be serviced */
-   if (!(inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) goto none;
-
-   HD(j)->iocount++;
-
-   if (do_trace) printk("%s: ihdlr, enter, irq %d, count %d.\n", BN(j), irq,
-                        HD(j)->iocount);
-
-   /* Check if this board is still busy */
-   if (wait_on_busy(sh[j]->io_port, 20 * MAXLOOP)) {
-      reg = inb(sh[j]->io_port + REG_STATUS);
-      printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
-             BN(j), irq, reg, HD(j)->iocount);
-      goto none;
-      }
-
-   spp  = &HD(j)->sp;
-
-   /* Make a local copy just before clearing the interrupt indication */
-   memcpy(spp, HD(j)->sp_cpu_addr, sizeof(struct mssp));
-
-   /* Clear the completion flag and cp pointer on the dynamic copy of sp */
-   memset(HD(j)->sp_cpu_addr, 0, sizeof(struct mssp));
-
-   /* Read the status register to clear the interrupt indication */
-   reg = inb(sh[j]->io_port + REG_STATUS);
+	/* Read the status register to clear the interrupt indication */
+	reg = inb(shost->io_port + REG_STATUS);
 
 #if defined (DEBUG_INTERRUPT)
-   {
-   unsigned char *bytesp;
-   int cnt;
-   bytesp= (unsigned char *) spp;
-   if (HD(j)->iocount < 200) {
-      printk("sp[] =");
-      for (cnt=0; cnt < 15; cnt++) printk(" 0x%x", bytesp[cnt]);
-      printk("\n");
-      }
-   }
-#endif
-
-   /* Reject any sp with supspect data */
-   if (spp->eoc == 0 && HD(j)->iocount > 1)
-      printk("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n",
-             BN(j), irq, reg, HD(j)->iocount);
-   if (spp->cpp_index < 0 || spp->cpp_index >= sh[j]->can_queue)
-      printk("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
-             BN(j), spp->cpp_index, irq, reg, HD(j)->iocount);
-   if (spp->eoc == 0 || spp->cpp_index < 0
-                         || spp->cpp_index >= sh[j]->can_queue) goto handled;
+	{
+		unsigned char *bytesp;
+		int cnt;
+		bytesp = (unsigned char *)spp;
+		if (ha->iocount < 200) {
+			printk("sp[] =");
+			for (cnt = 0; cnt < 15; cnt++)
+				printk(" 0x%x", bytesp[cnt]);
+			printk("\n");
+		}
+	}
+#endif
+
+	/* Reject any sp with supspect data */
+	if (spp->eoc == 0 && ha->iocount > 1)
+		printk
+		    ("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n",
+		     ha->board_name, irq, reg, ha->iocount);
+	if (spp->cpp_index < 0 || spp->cpp_index >= shost->can_queue)
+		printk
+		    ("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
+		     ha->board_name, spp->cpp_index, irq, reg, ha->iocount);
+	if (spp->eoc == 0 || spp->cpp_index < 0
+	    || spp->cpp_index >= shost->can_queue)
+		goto handled;
 
-   /* Find the mailbox to be serviced on this board */
-   i = spp->cpp_index;
+	/* Find the mailbox to be serviced on this board */
+	i = spp->cpp_index;
 
-   cpp = &(HD(j)->cp[i]);
+	cpp = &(ha->cp[i]);
 
 #if defined(DEBUG_GENERATE_ABORTS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) goto handled;
+	if ((ha->iocount > 500) && ((ha->iocount % 500) < 3))
+		goto handled;
 #endif
 
-   if (HD(j)->cp_stat[i] == IGNORE) {
-      HD(j)->cp_stat[i] = FREE;
-      goto handled;
-      }
-   else if (HD(j)->cp_stat[i] == LOCKED) {
-      HD(j)->cp_stat[i] = FREE;
-      printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i,
-             HD(j)->iocount);
-      goto handled;
-      }
-   else if (HD(j)->cp_stat[i] == FREE) {
-      printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i,
-             HD(j)->iocount);
-      goto handled;
-      }
-   else if (HD(j)->cp_stat[i] == IN_RESET)
-      printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
-   else if (HD(j)->cp_stat[i] != IN_USE)
-      panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n",
-            BN(j), i, HD(j)->cp_stat[i]);
-
-   HD(j)->cp_stat[i] = FREE;
-   SCpnt = cpp->SCpnt;
-
-   if (SCpnt == NULL) panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
-   if (SCpnt->host_scribble == NULL)
-      panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i,
-            SCpnt->pid, SCpnt);
-
-   if (*(unsigned int *)SCpnt->host_scribble != i)
-      panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
-            BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble);
-
-   sync_dma(i, j);
-
-   if (linked_comm && SCpnt->device->queue_depth > 2
-                                     && TLDEV(SCpnt->device->type))
-      flush_dev(SCpnt->device, SCpnt->request->sector, j, 1);
+	if (ha->cp_stat[i] == IGNORE) {
+		ha->cp_stat[i] = FREE;
+		goto handled;
+	} else if (ha->cp_stat[i] == LOCKED) {
+		ha->cp_stat[i] = FREE;
+		printk("%s: ihdlr, mbox %d unlocked, count %d.\n", ha->board_name, i,
+		       ha->iocount);
+		goto handled;
+	} else if (ha->cp_stat[i] == FREE) {
+		printk("%s: ihdlr, mbox %d is free, count %d.\n", ha->board_name, i,
+		       ha->iocount);
+		goto handled;
+	} else if (ha->cp_stat[i] == IN_RESET)
+		printk("%s: ihdlr, mbox %d is in reset.\n", ha->board_name, i);
+	else if (ha->cp_stat[i] != IN_USE)
+		panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n",
+		      ha->board_name, i, ha->cp_stat[i]);
+
+	ha->cp_stat[i] = FREE;
+	SCpnt = cpp->SCpnt;
+
+	if (SCpnt == NULL)
+		panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", ha->board_name, i);
+
+	if (SCpnt->host_scribble == NULL)
+		panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name,
+		      i, SCpnt->pid, SCpnt);
+
+	if (*(unsigned int *)SCpnt->host_scribble != i)
+		panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
+		      ha->board_name, i, SCpnt->pid,
+		      *(unsigned int *)SCpnt->host_scribble);
+
+	sync_dma(i, ha);
+
+	if (linked_comm && SCpnt->device->queue_depth > 2
+	    && TLDEV(SCpnt->device->type))
+		flush_dev(SCpnt->device, SCpnt->request->sector, ha, 1);
 
-   tstatus = status_byte(spp->target_status);
+	tstatus = status_byte(spp->target_status);
 
 #if defined(DEBUG_GENERATE_ERRORS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 200) < 2))
-                                           spp->adapter_status = 0x01;
+	if ((ha->iocount > 500) && ((ha->iocount % 200) < 2))
+		spp->adapter_status = 0x01;
 #endif
 
-   switch (spp->adapter_status) {
-      case ASOK:     /* status OK */
+	switch (spp->adapter_status) {
+	case ASOK:		/* status OK */
 
-         /* Forces a reset if a disk drive keeps returning BUSY */
-         if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE)
-            status = DID_ERROR << 16;
-
-         /* If there was a bus reset, redo operation on each target */
-         else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
-                  && HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel])
-            status = DID_BUS_BUSY << 16;
-
-         /* Works around a flaw in scsi.c */
-         else if (tstatus == CHECK_CONDITION
-                  && SCpnt->device->type == TYPE_DISK
-                  && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
-            status = DID_BUS_BUSY << 16;
-
-         else
-            status = DID_OK << 16;
-
-         if (tstatus == GOOD)
-            HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = 0;
-
-         if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
-             (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
-               (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
-            printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
-                   "target_status 0x%x, sense key 0x%x.\n", BN(j),
-                   SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
-                   SCpnt->pid, spp->target_status,
-                   SCpnt->sense_buffer[2]);
-
-         HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
-
-         if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
-
-         break;
-      case ASST:     /* Selection Time Out */
-      case 0x02:     /* Command Time Out   */
-
-         if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
-            status = DID_ERROR << 16;
-         else {
-            status = DID_TIME_OUT << 16;
-            HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++;
-            }
-
-         break;
-
-      /* Perform a limited number of internal retries */
-      case 0x03:     /* SCSI Bus Reset Received */
-      case 0x04:     /* Initial Controller Power-up */
-
-         for (c = 0; c <= sh[j]->max_channel; c++)
-            for (k = 0; k < sh[j]->max_id; k++)
-               HD(j)->target_redo[k][c] = 1;
+		/* Forces a reset if a disk drive keeps returning BUSY */
+		if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE)
+			status = DID_ERROR << 16;
+
+		/* If there was a bus reset, redo operation on each target */
+		else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
+			 && ha->target_redo[SCpnt->device->id][SCpnt->
+								  device->
+								  channel])
+			status = DID_BUS_BUSY << 16;
+
+		/* Works around a flaw in scsi.c */
+		else if (tstatus == CHECK_CONDITION
+			 && SCpnt->device->type == TYPE_DISK
+			 && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
+			status = DID_BUS_BUSY << 16;
+
+		else
+			status = DID_OK << 16;
+
+		if (tstatus == GOOD)
+			ha->target_redo[SCpnt->device->id][SCpnt->device->
+							      channel] = 0;
+
+		if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
+		    (!(tstatus == CHECK_CONDITION && ha->iocount <= 1000 &&
+		       (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
+			printk("%s: ihdlr, target %d.%d:%d, pid %ld, "
+			       "target_status 0x%x, sense key 0x%x.\n",
+			       ha->board_name,
+			       SCpnt->device->channel, SCpnt->device->id,
+			       SCpnt->device->lun, SCpnt->pid,
+			       spp->target_status, SCpnt->sense_buffer[2]);
+
+		ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
+
+		if (ha->last_retried_pid == SCpnt->pid)
+			ha->retries = 0;
+
+		break;
+	case ASST:		/* Selection Time Out */
+	case 0x02:		/* Command Time Out   */
+
+		if (ha->target_to[SCpnt->device->id][SCpnt->device->channel] > 1)
+			status = DID_ERROR << 16;
+		else {
+			status = DID_TIME_OUT << 16;
+			ha->target_to[SCpnt->device->id][SCpnt->device->
+							    channel]++;
+		}
+
+		break;
+
+		/* Perform a limited number of internal retries */
+	case 0x03:		/* SCSI Bus Reset Received */
+	case 0x04:		/* Initial Controller Power-up */
+
+		for (c = 0; c <= shost->max_channel; c++)
+			for (k = 0; k < shost->max_id; k++)
+				ha->target_redo[k][c] = 1;
 
-         if (SCpnt->device->type != TYPE_TAPE
-             && HD(j)->retries < MAX_INTERNAL_RETRIES) {
+		if (SCpnt->device->type != TYPE_TAPE
+		    && ha->retries < MAX_INTERNAL_RETRIES) {
 
 #if defined(DID_SOFT_ERROR)
-            status = DID_SOFT_ERROR << 16;
+			status = DID_SOFT_ERROR << 16;
 #else
-            status = DID_BUS_BUSY << 16;
+			status = DID_BUS_BUSY << 16;
 #endif
 
-            HD(j)->retries++;
-            HD(j)->last_retried_pid = SCpnt->pid;
-            }
-         else
-            status = DID_ERROR << 16;
-
-         break;
-      case 0x05:     /* Unexpected Bus Phase */
-      case 0x06:     /* Unexpected Bus Free */
-      case 0x07:     /* Bus Parity Error */
-      case 0x08:     /* SCSI Hung */
-      case 0x09:     /* Unexpected Message Reject */
-      case 0x0a:     /* SCSI Bus Reset Stuck */
-      case 0x0b:     /* Auto Request-Sense Failed */
-      case 0x0c:     /* Controller Ram Parity Error */
-      default:
-         status = DID_ERROR << 16;
-         break;
-      }
+			ha->retries++;
+			ha->last_retried_pid = SCpnt->pid;
+		} else
+			status = DID_ERROR << 16;
+
+		break;
+	case 0x05:		/* Unexpected Bus Phase */
+	case 0x06:		/* Unexpected Bus Free */
+	case 0x07:		/* Bus Parity Error */
+	case 0x08:		/* SCSI Hung */
+	case 0x09:		/* Unexpected Message Reject */
+	case 0x0a:		/* SCSI Bus Reset Stuck */
+	case 0x0b:		/* Auto Request-Sense Failed */
+	case 0x0c:		/* Controller Ram Parity Error */
+	default:
+		status = DID_ERROR << 16;
+		break;
+	}
 
-   SCpnt->result = status | spp->target_status;
+	SCpnt->result = status | spp->target_status;
 
 #if defined(DEBUG_INTERRUPT)
-   if (SCpnt->result || do_trace)
+	if (SCpnt->result || do_trace)
 #else
-   if ((spp->adapter_status != ASOK && HD(j)->iocount >  1000) ||
-       (spp->adapter_status != ASOK &&
-        spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
-        do_trace || msg_byte(spp->target_status))
-#endif
-      printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
-             " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
-             BN(j), i, spp->adapter_status, spp->target_status,
-             SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid,
-             reg, HD(j)->iocount);
-
-   unmap_dma(i, j);
-
-   /* Set the command state to inactive */
-   SCpnt->host_scribble = NULL;
-
-   SCpnt->scsi_done(SCpnt);
-
-   if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq,
-                        HD(j)->iocount);
-
-handled:
-   return IRQ_HANDLED;
-none:
-   return IRQ_NONE;
+	if ((spp->adapter_status != ASOK && ha->iocount > 1000) ||
+	    (spp->adapter_status != ASOK &&
+	     spp->adapter_status != ASST && ha->iocount <= 1000) ||
+	    do_trace || msg_byte(spp->target_status))
+#endif
+		printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"
+		       " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n",
+		       ha->board_name, i, spp->adapter_status, spp->target_status,
+		       SCpnt->device->channel, SCpnt->device->id,
+		       SCpnt->device->lun, SCpnt->pid, reg, ha->iocount);
+
+	unmap_dma(i, ha);
+
+	/* Set the command state to inactive */
+	SCpnt->host_scribble = NULL;
+
+	SCpnt->scsi_done(SCpnt);
+
+	if (do_trace)
+		printk("%s: ihdlr, exit, irq %d, count %d.\n", ha->board_name,
+				irq, ha->iocount);
+
+      handled:
+	return IRQ_HANDLED;
+      none:
+	return IRQ_NONE;
 }
 
 static irqreturn_t do_interrupt_handler(int irq, void *shap,
-                                        struct pt_regs *regs) {
-   unsigned int j;
-   unsigned long spin_flags;
-   irqreturn_t ret;
-
-   /* Check if the interrupt must be processed by this handler */
-   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return IRQ_NONE;
-
-   spin_lock_irqsave(sh[j]->host_lock, spin_flags);
-   ret = ihdlr(irq, j);
-   spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
-   return ret;
-}
-
-static int eata2x_release(struct Scsi_Host *shpnt) {
-   unsigned int i, j;
-
-   for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
-
-   if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n",
-                            driver_name);
-
-   for (i = 0; i < sh[j]->can_queue; i++)
-      if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
-
-   for (i = 0; i < sh[j]->can_queue; i++)
-      pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
-                     sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
-
-   if (HD(j)->sp_cpu_addr)
-      pci_free_consistent(HD(j)->pdev, sizeof(struct mssp),
-                          HD(j)->sp_cpu_addr, HD(j)->sp_dma_addr);
-
-   free_irq(sh[j]->irq, &sha[j]);
-
-   if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel);
-
-   release_region(sh[j]->io_port, sh[j]->n_io_port);
-   scsi_unregister(sh[j]);
-   return 0;
+					struct pt_regs *regs)
+{
+	struct Scsi_Host *shost;
+	unsigned int j;
+	unsigned long spin_flags;
+	irqreturn_t ret;
+
+	/* Check if the interrupt must be processed by this handler */
+	if ((j = (unsigned int)((char *)shap - sha)) >= num_boards)
+		return IRQ_NONE;
+	shost = sh[j];
+
+	spin_lock_irqsave(shost->host_lock, spin_flags);
+	ret = ihdlr(irq, shost);
+	spin_unlock_irqrestore(shost->host_lock, spin_flags);
+	return ret;
+}
+
+static int eata2x_release(struct Scsi_Host *shost)
+{
+	struct hostdata *ha = (struct hostdata *)shost->hostdata;
+	unsigned int i;
+
+	for (i = 0; i < shost->can_queue; i++)
+		if ((&ha->cp[i])->sglist)
+			kfree((&ha->cp[i])->sglist);
+
+	for (i = 0; i < shost->can_queue; i++)
+		pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr,
+				 sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
+
+	if (ha->sp_cpu_addr)
+		pci_free_consistent(ha->pdev, sizeof(struct mssp),
+				    ha->sp_cpu_addr, ha->sp_dma_addr);
+
+	free_irq(shost->irq, &sha[ha->board_number]);
+
+	if (shost->dma_channel != NO_DMA)
+		free_dma(shost->dma_channel);
+
+	release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
 }
 
 #include "scsi_module.c"
 
 #ifndef MODULE
 __setup("eata=", option_setup);
-#endif /* end MODULE */
+#endif				/* end MODULE */
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/hosts.c	2004-12-12 18:04:46 -08:00
@@ -79,11 +79,14 @@
 
 	set_bit(SHOST_DEL, &shost->shost_state);
 
+	if (shost->transportt->host_destroy)
+		shost->transportt->host_destroy(shost);
 	class_device_unregister(&shost->shost_classdev);
 	if (shost->transport_classdev.class)
 		class_device_unregister(&shost->transport_classdev);
 	device_del(&shost->shost_gendev);
 }
+EXPORT_SYMBOL(scsi_remove_host);
 
 /**
  * scsi_add_host - add a scsi host
@@ -133,11 +136,14 @@
 
 	error = scsi_sysfs_add_host(shost);
 	if (error)
-		goto out_del_classdev;
+		goto out_destroy_host;
 
 	scsi_proc_host_add(shost);
 	return error;
 
+ out_destroy_host:
+	if (shost->transportt->host_destroy)
+		shost->transportt->host_destroy(shost);
  out_del_classdev:
 	class_device_del(&shost->shost_classdev);
  out_del_gendev:
@@ -145,6 +151,7 @@
  out:
 	return error;
 }
+EXPORT_SYMBOL(scsi_add_host);
 
 static void scsi_host_dev_release(struct device *dev)
 {
@@ -301,6 +308,7 @@
 	kfree(shost);
 	return NULL;
 }
+EXPORT_SYMBOL(scsi_host_alloc);
 
 struct Scsi_Host *scsi_register(struct scsi_host_template *sht, int privsize)
 {
@@ -316,12 +324,14 @@
 		list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts);
 	return shost;
 }
+EXPORT_SYMBOL(scsi_register);
 
 void scsi_unregister(struct Scsi_Host *shost)
 {
 	list_del(&shost->sht_legacy_list);
 	scsi_host_put(shost);
 }
+EXPORT_SYMBOL(scsi_unregister);
 
 /**
  * scsi_host_lookup - get a reference to a Scsi_Host by host no
@@ -349,6 +359,7 @@
 
 	return shost;
 }
+EXPORT_SYMBOL(scsi_host_lookup);
 
 /**
  * scsi_host_get - inc a Scsi_Host ref count
@@ -361,6 +372,7 @@
 		return NULL;
 	return shost;
 }
+EXPORT_SYMBOL(scsi_host_get);
 
 /**
  * scsi_host_put - dec a Scsi_Host ref count
@@ -370,6 +382,7 @@
 {
 	put_device(&shost->shost_gendev);
 }
+EXPORT_SYMBOL(scsi_host_put);
 
 int scsi_init_hosts(void)
 {
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsi.c	2004-12-12 18:04:46 -08:00
@@ -98,6 +98,9 @@
  * After the system is up, you may enable logging via the /proc interface.
  */
 unsigned int scsi_logging_level;
+#if defined(CONFIG_SCSI_LOGGING)
+EXPORT_SYMBOL(scsi_logging_level);
+#endif
 
 const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = {
 	"Direct-Access    ",
@@ -115,6 +118,7 @@
 	"RAID             ",
 	"Enclosure        ",
 };
+EXPORT_SYMBOL(scsi_device_types);
 
 /*
  * Function:    scsi_allocate_request
@@ -147,6 +151,7 @@
 
 	return sreq;
 }
+EXPORT_SYMBOL(scsi_allocate_request);
 
 void __scsi_release_request(struct scsi_request *sreq)
 {
@@ -187,6 +192,7 @@
 	__scsi_release_request(sreq);
 	kfree(sreq);
 }
+EXPORT_SYMBOL(scsi_release_request);
 
 struct scsi_host_cmd_pool {
 	kmem_cache_t	*slab;
@@ -269,6 +275,7 @@
 
 	return cmd;
 }				
+EXPORT_SYMBOL(scsi_get_command);
 
 /*
  * Function:	scsi_put_command()
@@ -305,6 +312,7 @@
 
 	put_device(&sdev->sdev_gendev);
 }
+EXPORT_SYMBOL(scsi_put_command);
 
 /*
  * Function:	scsi_setup_command_freelist()
@@ -606,9 +614,7 @@
 				printk("queuecommand : command too long.\n"));
 		cmd->result = (DID_ABORT << 16);
 
-		spin_lock_irqsave(host->host_lock, flags);
 		scsi_done(cmd);
-		spin_unlock_irqrestore(host->host_lock, flags);
 		goto out;
 	}
 
@@ -961,6 +967,7 @@
 	spin_unlock(sdev->request_queue->queue_lock);
 	spin_unlock_irqrestore(&device_request_lock, flags);
 }
+EXPORT_SYMBOL(scsi_adjust_queue_depth);
 
 /*
  * Function:	scsi_track_queue_full()
@@ -1011,6 +1018,7 @@
 		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
 	return depth;
 }
+EXPORT_SYMBOL(scsi_track_queue_full);
 
 /**
  * scsi_device_get  -  get an addition reference to a scsi_device
@@ -1177,6 +1185,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(scsi_device_cancel);
 
 #ifdef CONFIG_HOTPLUG_CPU
 static int scsi_cpu_notify(struct notifier_block *self,
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsi_debug.c	2004-12-12 18:04:46 -08:00
@@ -55,8 +55,8 @@
 #include "scsi_logging.h"
 #include "scsi_debug.h"
 
-#define SCSI_DEBUG_VERSION "1.74"
-static const char * scsi_debug_version_date = "20040829";
+#define SCSI_DEBUG_VERSION "1.75"
+static const char * scsi_debug_version_date = "20041023";
 
 /* Additional Sense Code (ASC) used */
 #define NO_ADDED_SENSE 0x0
@@ -82,7 +82,7 @@
 #define DEF_EVERY_NTH   0
 #define DEF_NUM_PARTS   0
 #define DEF_OPTS   0
-#define DEF_SCSI_LEVEL   4    /* SPC-2 */
+#define DEF_SCSI_LEVEL   5    /* INQUIRY, byte2 [5->SPC-3] */
 #define DEF_PTYPE   0
 #define DEF_D_SENSE   0
 
@@ -95,6 +95,13 @@
  *   - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
  *   - a RECOVERED_ERROR is simulated on successful read and write
  *     commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
+ *
+ * When "every_nth" < 0 then after "- every_nth" commands:
+ *   - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
+ *   - a RECOVERED_ERROR is simulated on successful read and write
+ *     commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
+ * This will continue until some other action occurs (e.g. the user
+ * writing a new value (other than -1 or 1) to every_nth via sysfs).
  */
 
 /* when 1==SCSI_DEBUG_OPT_MEDIUM_ERR, a medium error is simulated at this
@@ -195,14 +202,12 @@
 	.cmd_per_lun =		3,
 	.max_sectors =		4096,
 	.unchecked_isa_dma = 	0,
-	.use_clustering = 	ENABLE_CLUSTERING,
+	.use_clustering = 	DISABLE_CLUSTERING,
 	.module =		THIS_MODULE,
 };
 
 static unsigned char * fake_storep;	/* ramdisk storage */
 
-static unsigned char spare_buff[SDEBUG_SENSE_LEN];
-
 static int num_aborts = 0;
 static int num_dev_resets = 0;
 static int num_bus_resets = 0;
@@ -228,21 +233,28 @@
 		(DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
 /* function declarations */
-static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
-			int bufflen, struct sdebug_dev_info * devip);
-static int resp_mode_sense(unsigned char * cmd, int target,
-			   unsigned char * buff, int bufflen,
+static int resp_inquiry(struct scsi_cmnd * SCpnt, int target,
+			struct sdebug_dev_info * devip);
+static int resp_requests(struct scsi_cmnd * SCpnt,
+			 struct sdebug_dev_info * devip);
+static int resp_readcap(struct scsi_cmnd * SCpnt,
+			struct sdebug_dev_info * devip);
+static int resp_mode_sense(struct scsi_cmnd * SCpnt, int target,
 			   struct sdebug_dev_info * devip);
 static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 		     int num, struct sdebug_dev_info * devip);
 static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 		      int num, struct sdebug_dev_info * devip);
-static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
-			    int bufflen, struct sdebug_dev_info * devip);
+static int resp_report_luns(struct scsi_cmnd * SCpnt,
+			    struct sdebug_dev_info * devip);
+static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
+                                int arr_len);
+static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
+                               int max_arr_len);
 static void timer_intr_handler(unsigned long);
 static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
 static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
-			    int asc, int asq, int inbandLen);
+			    int asc, int asq);
 static int check_reset(struct scsi_cmnd * SCpnt,
 		       struct sdebug_dev_info * devip);
 static int schedule_resp(struct scsi_cmnd * cmnd,
@@ -264,49 +276,20 @@
 static struct device pseudo_primary;
 static struct bus_type pseudo_lld_bus;
 
-static unsigned char * scatg2virt(const struct scatterlist * sclp)
-{
-	if (NULL == sclp)
-		return NULL;
-	else if (sclp->page)
-		return (unsigned char *)page_address(sclp->page) +
-		       sclp->offset;
-	else
-		return NULL;
-}
 
 static
 int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
 {
 	unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
 	int block, upper_blk, num, k;
-	unsigned char *buff;
 	int errsts = 0;
 	int target = SCpnt->device->id;
-	int bufflen = SCpnt->request_bufflen;
-	unsigned long capac;
 	struct sdebug_dev_info * devip = NULL;
-	unsigned char * sbuff;
 	int inj_recovered = 0;
 
 	if (done == NULL)
 		return 0;	/* assume mid level reprocessing command */
 
-	if (SCpnt->use_sg) { /* just use first element */
-		struct scatterlist *sgpnt = (struct scatterlist *)
-						SCpnt->request_buffer;
-
-		buff = scatg2virt(&sgpnt[0]);
-		bufflen = sgpnt[0].length;
-		/* READ and WRITE process scatterlist themselves */
-	}
-	else
-		buff = (unsigned char *) SCpnt->request_buffer;
-	if (NULL == buff) {
-		buff = spare_buff;	/* assume cmd moves no data */
-		bufflen = SDEBUG_SENSE_LEN;
-	}
-
 	if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
 		printk(KERN_INFO "scsi_debug: cmd ");
 		for (k = 0, num = SCpnt->cmd_len; k < num; ++k)
@@ -328,9 +311,11 @@
 		return schedule_resp(SCpnt, NULL, done,
 				     DID_NO_CONNECT << 16, 0);
 
-        if ((scsi_debug_every_nth > 0) &&
-            (++scsi_debug_cmnd_count >= scsi_debug_every_nth)) {
-                scsi_debug_cmnd_count =0;
+        if ((scsi_debug_every_nth != 0) &&
+            (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) {
+                scsi_debug_cmnd_count = 0;
+		if (scsi_debug_every_nth < -1)
+			scsi_debug_every_nth = -1;
 		if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
 			return 0; /* ignore command causing timeout */
 		else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
@@ -339,23 +324,14 @@
 
 	switch (*cmd) {
 	case INQUIRY:     /* mandatory, ignore unit attention */
-		errsts = resp_inquiry(cmd, target, buff, bufflen, devip);
+		errsts = resp_inquiry(SCpnt, target, devip);
 		break;
 	case REQUEST_SENSE:	/* mandatory, ignore unit attention */
-		if (devip) {
-			sbuff = devip->sense_buff;
-			memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ?
-					     bufflen : SDEBUG_SENSE_LEN);
-			mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0, 7);
-		} else {
-			memset(buff, 0, bufflen);
-			buff[0] = 0x70;
-		}
+		errsts = resp_requests(SCpnt, devip);
 		break;
 	case REZERO_UNIT:	/* actually this is REWIND for SSC */
 	case START_STOP:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
 		break;
 	case ALLOW_MEDIUM_REMOVAL:
 		if ((errsts = check_reset(SCpnt, devip)))
@@ -366,40 +342,24 @@
 		break;
 	case SEND_DIAGNOSTIC:     /* mandatory */
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
 		break;
 	case TEST_UNIT_READY:     /* mandatory */
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
 		break;
         case RESERVE:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
                 break;
         case RESERVE_10:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
                 break;
         case RELEASE:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
                 break;
         case RELEASE_10:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
                 break;
 	case READ_CAPACITY:
-		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
-		if (bufflen > 7) {
-			capac = (unsigned long)sdebug_capacity - 1;
-			buff[0] = (capac >> 24);
-			buff[1] = (capac >> 16) & 0xff;
-			buff[2] = (capac >> 8) & 0xff;
-			buff[3] = capac & 0xff;
-			buff[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
-			buff[7] = SECT_SIZE_PER(target) & 0xff;
-		}
+		errsts = resp_readcap(SCpnt, devip);
 		break;
 	case READ_16:
 	case READ_12:
@@ -432,12 +392,15 @@
 		errsts = resp_read(SCpnt, upper_blk, block, num, devip);
 		if (inj_recovered && (0 == errsts)) {
 			mk_sense_buffer(devip, RECOVERED_ERROR,
-					THRESHHOLD_EXCEEDED, 0, 18);
+					THRESHHOLD_EXCEEDED, 0);
 			errsts = check_condition_result;
 		}
 		break;
 	case REPORT_LUNS:	/* mandatory, ignore unit attention */
-		errsts = resp_report_luns(cmd, buff, bufflen, devip);
+		errsts = resp_report_luns(SCpnt, devip);
+		break;
+	case VERIFY:		/* 10 byte SBC-2 command */
+		errsts = check_reset(SCpnt, devip);
 		break;
 	case WRITE_16:
 	case WRITE_12:
@@ -470,19 +433,16 @@
 		errsts = resp_write(SCpnt, upper_blk, block, num, devip);
 		if (inj_recovered && (0 == errsts)) {
 			mk_sense_buffer(devip, RECOVERED_ERROR,
-					THRESHHOLD_EXCEEDED, 0, 18);
+					THRESHHOLD_EXCEEDED, 0);
 			errsts = check_condition_result;
 		}
 		break;
 	case MODE_SENSE:
 	case MODE_SENSE_10:
-		if ((errsts = check_reset(SCpnt, devip)))
-			break;
-		errsts = resp_mode_sense(cmd, target, buff, bufflen, devip);
+		errsts = resp_mode_sense(SCpnt, target, devip);
 		break;
 	case SYNCHRONIZE_CACHE:
 		errsts = check_reset(SCpnt, devip);
-		memset(buff, 0, bufflen);
 		break;
 	default:
 		if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
@@ -490,7 +450,7 @@
 			       "supported\n", *cmd);
 		if ((errsts = check_reset(SCpnt, devip)))
 			break;	/* Unit attention takes precedence */
-		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0, 18);
+		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
 		errsts = check_condition_result;
 		break;
 	}
@@ -513,18 +473,105 @@
 			printk(KERN_INFO "scsi_debug: Reporting Unit "
 			       "attention: power on reset\n");
 		devip->reset = 0;
-		mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0, 18);
+		mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0);
 		return check_condition_result;
 	}
 	return 0;
 }
 
-#define SDEBUG_LONG_INQ_SZ 96
-#define SDEBUG_MAX_INQ_ARR_SZ 128
+/* Returns 0 if ok else (DID_ERROR << 16). Sets scp->resid . */
+static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
+				int arr_len)
+{
+	int k, req_len, act_len, len, active;
+	void * kaddr;
+	void * kaddr_off;
+	struct scatterlist * sgpnt;
+
+	if (0 == scp->request_bufflen)
+		return 0;
+	if (NULL == scp->request_buffer)
+		return (DID_ERROR << 16);
+	if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
+	      (scp->sc_data_direction == DMA_FROM_DEVICE)))
+		return (DID_ERROR << 16);
+	if (0 == scp->use_sg) {
+		req_len = scp->request_bufflen;
+		act_len = (req_len < arr_len) ? req_len : arr_len;
+		memcpy(scp->request_buffer, arr, act_len);
+		scp->resid = req_len - act_len;
+		return 0;
+	}
+	sgpnt = (struct scatterlist *)scp->request_buffer;
+	active = 1;
+	for (k = 0, req_len = 0, act_len = 0; k < scp->use_sg; ++k, ++sgpnt) {
+		if (active) {
+			kaddr = (unsigned char *)
+				kmap_atomic(sgpnt->page, KM_USER0);
+			if (NULL == kaddr)
+				return (DID_ERROR << 16);
+			kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
+			len = sgpnt->length;
+			if ((req_len + len) > arr_len) {
+				active = 0;
+				len = arr_len - req_len;
+			}
+			memcpy(kaddr_off, arr + req_len, len);
+			kunmap_atomic(kaddr, KM_USER0);
+			act_len += len;
+		}
+		req_len += sgpnt->length;
+	}
+	scp->resid = req_len - act_len;
+	return 0;
+}
 
-static const char * vendor_id = "Linux   ";
-static const char * product_id = "scsi_debug      ";
-static const char * product_rev = "0004";
+/* Returns number of bytes fetched into 'arr' or -1 if error. */
+static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
+			       int max_arr_len)
+{
+	int k, req_len, len, fin;
+	void * kaddr;
+	void * kaddr_off;
+	struct scatterlist * sgpnt;
+
+	if (0 == scp->request_bufflen)
+		return 0;
+	if (NULL == scp->request_buffer)
+		return -1;
+	if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) ||
+	      (scp->sc_data_direction == DMA_TO_DEVICE)))
+		return -1;
+	if (0 == scp->use_sg) {
+		req_len = scp->request_bufflen;
+		len = (req_len < max_arr_len) ? req_len : max_arr_len;
+		memcpy(arr, scp->request_buffer, len);
+		return len;
+	}
+	sgpnt = (struct scatterlist *)scp->request_buffer;
+	for (k = 0, req_len = 0, fin = 0; k < scp->use_sg; ++k, ++sgpnt) {
+		kaddr = (unsigned char *)kmap_atomic(sgpnt->page, KM_USER0);
+		if (NULL == kaddr)
+			return -1;
+		kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
+		len = sgpnt->length;
+		if ((req_len + len) > max_arr_len) {
+			len = max_arr_len - req_len;
+			fin = 1;
+		}
+		memcpy(arr + req_len, kaddr_off, len);
+		kunmap_atomic(kaddr, KM_USER0);
+		if (fin)
+			return req_len + len;
+		req_len += sgpnt->length;
+	}
+	return req_len;
+}
+
+
+static const char * inq_vendor_id = "Linux   ";
+static const char * inq_product_id = "scsi_debug      ";
+static const char * inq_product_rev = "0004";
 
 static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
 			   const char * dev_id_str, int dev_id_str_len)
@@ -536,8 +583,8 @@
 	arr[0] = 0x2;	/* ASCII */
 	arr[1] = 0x1;
 	arr[2] = 0x0;
-	memcpy(&arr[4], vendor_id, 8);
-	memcpy(&arr[12], product_id, 16);
+	memcpy(&arr[4], inq_vendor_id, 8);
+	memcpy(&arr[12], inq_product_id, 16);
 	memcpy(&arr[28], dev_id_str, dev_id_str_len);
 	num = 8 + 16 + dev_id_str_len;
 	arr[3] = num;
@@ -558,24 +605,25 @@
 	return num + 12;
 }
 
-static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
-			int bufflen, struct sdebug_dev_info * devip)
+
+#define SDEBUG_LONG_INQ_SZ 96
+#define SDEBUG_MAX_INQ_ARR_SZ 128
+
+static int resp_inquiry(struct scsi_cmnd * scp, int target,
+			struct sdebug_dev_info * devip)
 {
 	unsigned char pq_pdt;
 	unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ];
-	int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ?
-			SDEBUG_MAX_INQ_ARR_SZ : bufflen;
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
+	int alloc_len;
 
-	if (bufflen < cmd[4])
-		printk(KERN_INFO "scsi_debug: inquiry: bufflen=%d "
-		       "< alloc_length=%d\n", bufflen, (int)cmd[4]);
-	memset(buff, 0, bufflen);
+	alloc_len = (cmd[3] << 8) + cmd[4];
 	memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ);
 	pq_pdt = (scsi_debug_ptype & 0x1f);
 	arr[0] = pq_pdt;
 	if (0x2 & cmd[1]) {  /* CMDDT bit set */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	} else if (0x1 & cmd[1]) {  /* EVPD bit set */
 		int dev_id_num, len;
@@ -600,11 +648,11 @@
 		} else {
 			/* Illegal request, invalid field in cdb */
 			mk_sense_buffer(devip, ILLEGAL_REQUEST,
-					INVALID_FIELD_IN_CDB, 0, 18);
+					INVALID_FIELD_IN_CDB, 0);
 			return check_condition_result;
 		}
-		memcpy(buff, arr, min_len);
-		return 0;
+		return fill_from_dev_buffer(scp, arr,
+			    min(alloc_len, SDEBUG_MAX_INQ_ARR_SZ));
 	}
 	/* drops through here for a standard inquiry */
 	arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0;	/* Removable disk */
@@ -612,20 +660,67 @@
 	arr[3] = 2;    /* response_data_format==2 */
 	arr[4] = SDEBUG_LONG_INQ_SZ - 5;
 	arr[6] = 0x1; /* claim: ADDR16 */
+	/* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */
 	arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */
-	memcpy(&arr[8], vendor_id, 8);
-	memcpy(&arr[16], product_id, 16);
-	memcpy(&arr[32], product_rev, 4);
+	memcpy(&arr[8], inq_vendor_id, 8);
+	memcpy(&arr[16], inq_product_id, 16);
+	memcpy(&arr[32], inq_product_rev, 4);
 	/* version descriptors (2 bytes each) follow */
 	arr[58] = 0x0; arr[59] = 0x40; /* SAM-2 */
-	arr[60] = 0x2; arr[61] = 0x60; /* SPC-2 */
+	arr[60] = 0x3; arr[61] = 0x0;  /* SPC-3 */
 	if (scsi_debug_ptype == 0) {
-	    arr[62] = 0x1; arr[63] = 0x80; /* SBC */
+		arr[62] = 0x1; arr[63] = 0x80; /* SBC */
 	} else if (scsi_debug_ptype == 1) {
-	    arr[62] = 0x2; arr[63] = 0x00; /* SSC */
+		arr[62] = 0x2; arr[63] = 0x00; /* SSC */
 	}
-	memcpy(buff, arr, min_len);
-	return 0;
+	return fill_from_dev_buffer(scp, arr,
+			    min(alloc_len, SDEBUG_LONG_INQ_SZ));
+}
+
+static int resp_requests(struct scsi_cmnd * scp,
+			 struct sdebug_dev_info * devip)
+{
+	unsigned char * sbuff;
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
+	unsigned char arr[SDEBUG_SENSE_LEN];
+	int len = 18;
+
+	memset(arr, 0, SDEBUG_SENSE_LEN);
+	if (devip->reset == 1)
+		mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0);
+	sbuff = devip->sense_buff;
+	if ((cmd[1] & 1) && (! scsi_debug_dsense)) {
+		/* DESC bit set and sense_buff in fixed format */
+		arr[0] = 0x72;
+		arr[1] = sbuff[2];     /* sense key */
+		arr[2] = sbuff[12];    /* asc */
+		arr[3] = sbuff[13];    /* ascq */
+		len = 8;
+	} else
+		memcpy(arr, sbuff, SDEBUG_SENSE_LEN);
+	mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0);
+	return fill_from_dev_buffer(scp, arr, len);
+}
+
+#define SDEBUG_READCAP_ARR_SZ 8
+static int resp_readcap(struct scsi_cmnd * scp,
+			struct sdebug_dev_info * devip)
+{
+	unsigned char arr[SDEBUG_READCAP_ARR_SZ];
+	unsigned long capac;
+	int errsts;
+
+	if ((errsts = check_reset(scp, devip)))
+		return errsts;
+	memset(arr, 0, SDEBUG_READCAP_ARR_SZ);
+	capac = (unsigned long)sdebug_capacity - 1;
+	arr[0] = (capac >> 24);
+	arr[1] = (capac >> 16) & 0xff;
+	arr[2] = (capac >> 8) & 0xff;
+	arr[3] = capac & 0xff;
+	arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff;
+	arr[7] = SECT_SIZE_PER(target) & 0xff;
+	return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ);
 }
 
 /* <<Following mode page info copied from ST318451LW>> */
@@ -706,34 +801,29 @@
 
 #define SDEBUG_MAX_MSENSE_SZ 256
 
-static int resp_mode_sense(unsigned char * cmd, int target,
-			   unsigned char * buff, int bufflen,
+static int resp_mode_sense(struct scsi_cmnd * scp, int target,
 			   struct sdebug_dev_info * devip)
 {
 	unsigned char dbd;
 	int pcontrol, pcode, subpcode;
 	unsigned char dev_spec;
-	int alloc_len, msense_6, offset, len;
+	int alloc_len, msense_6, offset, len, errsts;
 	unsigned char * ap;
 	unsigned char arr[SDEBUG_MAX_MSENSE_SZ];
-	int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ?
-			SDEBUG_MAX_MSENSE_SZ : bufflen;
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
 
-	SCSI_LOG_LLQUEUE(3, printk("Mode sense ...(%p %d)\n", buff, bufflen));
+	if ((errsts = check_reset(scp, devip)))
+		return errsts;
 	dbd = cmd[1] & 0x8;
 	pcontrol = (cmd[2] & 0xc0) >> 6;
 	pcode = cmd[2] & 0x3f;
 	subpcode = cmd[3];
 	msense_6 = (MODE_SENSE == cmd[0]);
 	alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]);
-	if (bufflen < alloc_len)
-		printk(KERN_INFO "scsi_debug: mode_sense: bufflen=%d "
-		       "< alloc_length=%d\n", bufflen, alloc_len);
-	memset(buff, 0, bufflen);
 	memset(arr, 0, SDEBUG_MAX_MSENSE_SZ);
 	if (0x3 == pcontrol) {  /* Saving values not supported */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, SAVING_PARAMS_UNSUP,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
 	dev_spec = DEV_READONLY(target) ? 0x80 : 0x0;
@@ -748,7 +838,7 @@
 
 	if (0 != subpcode) { /* TODO: Control Extension page */
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
 	switch (pcode) {
@@ -787,146 +877,104 @@
 		break;
 	default:
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
 	if (msense_6)
 		arr[0] = offset - 1;
 	else {
-		offset -= 2;
-		arr[0] = (offset >> 8) & 0xff;
-		arr[1] = offset & 0xff;
+		arr[0] = ((offset - 2) >> 8) & 0xff;
+		arr[1] = (offset - 2) & 0xff;
 	}
-	memcpy(buff, arr, min_len);
-	return 0;
+	return fill_from_dev_buffer(scp, arr, min(alloc_len, offset));
 }
 
 static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 		     int num, struct sdebug_dev_info * devip)
 {
-        unsigned char *buff = (unsigned char *) SCpnt->request_buffer;
-        int nbytes, sgcount;
-        struct scatterlist *sgpnt = NULL;
-        int bufflen = SCpnt->request_bufflen;
 	unsigned long iflags;
+	int ret;
 
 	if (upper_blk || (block + num > sdebug_capacity)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
-				0, 18);
+				0);
 		return check_condition_result;
 	}
 	if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) &&
 	    (block <= OPT_MEDIUM_ERR_ADDR) &&
 	    ((block + num) > OPT_MEDIUM_ERR_ADDR)) {
 		mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR,
-				0, 18);
+				0);
 		/* claim unrecoverable read error */
 		return check_condition_result;
 	}
 	read_lock_irqsave(&atomic_rw, iflags);
-        sgcount = 0;
-	nbytes = bufflen;
-	/* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n",
-	       block, bufflen); */
-	if (SCpnt->use_sg) {
-		sgcount = 0;
-		sgpnt = (struct scatterlist *) buff;
-		buff = scatg2virt(&sgpnt[sgcount]);
-		bufflen = sgpnt[sgcount].length;
-	}
-	do {
-		memcpy(buff, fake_storep + (block * SECT_SIZE), bufflen);
-		nbytes -= bufflen;
-		if (SCpnt->use_sg) {
-			block += bufflen >> POW2_SECT_SIZE;
-			sgcount++;
-			if (nbytes) {
-				buff = scatg2virt(&sgpnt[sgcount]);
-				bufflen = sgpnt[sgcount].length;
-			}
-		} else if (nbytes > 0)
-			printk(KERN_WARNING "scsi_debug:resp_read: unexpected "
-			       "nbytes=%d\n", nbytes);
-	} while (nbytes);
+	ret = fill_from_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE),
+			   	   num * SECT_SIZE);
 	read_unlock_irqrestore(&atomic_rw, iflags);
-	return 0;
+	return ret;
 }
 
 static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
 		      int num, struct sdebug_dev_info * devip)
 {
-        unsigned char *buff = (unsigned char *) SCpnt->request_buffer;
-        int nbytes, sgcount;
-        struct scatterlist *sgpnt = NULL;
-        int bufflen = SCpnt->request_bufflen;
 	unsigned long iflags;
+	int res;
 
 	if (upper_blk || (block + num > sdebug_capacity)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
 
 	write_lock_irqsave(&atomic_rw, iflags);
-        sgcount = 0;
-	nbytes = bufflen;
-	if (SCpnt->use_sg) {
-		sgcount = 0;
-		sgpnt = (struct scatterlist *) buff;
-		buff = scatg2virt(&sgpnt[sgcount]);
-		bufflen = sgpnt[sgcount].length;
-	}
-	do {
-		memcpy(fake_storep + (block * SECT_SIZE), buff, bufflen);
-
-		nbytes -= bufflen;
-		if (SCpnt->use_sg) {
-			block += bufflen >> POW2_SECT_SIZE;
-			sgcount++;
-			if (nbytes) {
-				buff = scatg2virt(&sgpnt[sgcount]);
-				bufflen = sgpnt[sgcount].length;
-			}
-		} else if (nbytes > 0)
-			printk(KERN_WARNING "scsi_debug:resp_write: "
-			       "unexpected nbytes=%d\n", nbytes);
-	} while (nbytes);
+	res = fetch_to_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE),
+			   	  num * SECT_SIZE);
 	write_unlock_irqrestore(&atomic_rw, iflags);
+	if (-1 == res)
+		return (DID_ERROR << 16);
+	else if ((res < (num * SECT_SIZE)) &&
+		 (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts))
+		printk(KERN_INFO "scsi_debug: write: cdb indicated=%d, "
+		       " IO sent=%d bytes\n", num * SECT_SIZE, res);
 	return 0;
 }
 
-static int resp_report_luns(unsigned char * cmd, unsigned char * buff,
-			    int bufflen, struct sdebug_dev_info * devip)
+#define SDEBUG_RLUN_ARR_SZ 128
+
+static int resp_report_luns(struct scsi_cmnd * scp,
+			    struct sdebug_dev_info * devip)
 {
 	unsigned int alloc_len;
 	int lun_cnt, i, upper;
+	unsigned char *cmd = (unsigned char *)scp->cmnd;
 	int select_report = (int)cmd[2];
 	struct scsi_lun *one_lun;
+	unsigned char arr[SDEBUG_RLUN_ARR_SZ];
 
 	alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
 	if ((alloc_len < 16) || (select_report > 2)) {
 		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
-			       	0, 18);
+			       	0);
 		return check_condition_result;
 	}
-	if (bufflen > 8) { /* can produce response with up to 16k luns
-			      (lun 0 to lun 16383) */
-		memset(buff, 0, bufflen);
-		lun_cnt = scsi_debug_max_luns;
-		buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
-		buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
-		lun_cnt = min((int)((bufflen - 8) / sizeof(struct scsi_lun)),
-			      lun_cnt);
-		one_lun = (struct scsi_lun *) &buff[8];
-		for (i = 0; i < lun_cnt; i++) {
-			upper = (i >> 8) & 0x3f;
-			if (upper)
-				one_lun[i].scsi_lun[0] =
-				    (upper | (SAM2_LUN_ADDRESS_METHOD << 6));
-			one_lun[i].scsi_lun[1] = i & 0xff;
-		}
+	/* can produce response with up to 16k luns (lun 0 to lun 16383) */
+	memset(arr, 0, SDEBUG_RLUN_ARR_SZ);
+	lun_cnt = scsi_debug_max_luns;
+	arr[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
+	arr[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
+	lun_cnt = min((int)((SDEBUG_RLUN_ARR_SZ - 8) /
+			    sizeof(struct scsi_lun)), lun_cnt);
+	one_lun = (struct scsi_lun *) &arr[8];
+	for (i = 0; i < lun_cnt; i++) {
+		upper = (i >> 8) & 0x3f;
+		if (upper)
+			one_lun[i].scsi_lun[0] =
+			    (upper | (SAM2_LUN_ADDRESS_METHOD << 6));
+		one_lun[i].scsi_lun[1] = i & 0xff;
 	}
-	return 0;
+	return fill_from_dev_buffer(scp, arr,
+				    min((int)alloc_len, SDEBUG_RLUN_ARR_SZ));
 }
 
 /* When timer goes off this function is called. */
@@ -1041,14 +1089,19 @@
 		open_devip->reset = 1;
 		open_devip->used = 1;
 		memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN);
-		open_devip->sense_buff[0] = 0x70;
+		if (scsi_debug_dsense)
+			open_devip->sense_buff[0] = 0x72;
+		else {
+			open_devip->sense_buff[0] = 0x70;
+			open_devip->sense_buff[7] = 0xa;
+		}
 		return open_devip;
         }
         return NULL;
 }
 
 static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
-			    int asc, int asq, int inbandLen)
+			    int asc, int asq)
 {
 	unsigned char * sbuff;
 
@@ -1060,11 +1113,9 @@
 		sbuff[2] = asc;
 		sbuff[3] = asq;
 	} else {
-		if (inbandLen > SDEBUG_SENSE_LEN)
-			inbandLen = SDEBUG_SENSE_LEN;
 		sbuff[0] = 0x70;  /* fixed, current */
 		sbuff[2] = key;
-		sbuff[7] = (inbandLen > 7) ? (inbandLen - 8) : 0;
+		sbuff[7] = 0xa;	  /* implies 18 byte sense buffer */
 		sbuff[12] = asc;
 		sbuff[13] = asq;
 	}
@@ -1355,7 +1406,7 @@
 MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate");
 MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->...");
 MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
-MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=4[SPC-2])");
+MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
 
 
 static char sdebug_info[256];
@@ -1391,7 +1442,7 @@
 		if (1 != sscanf(arr, "%d", &pos))
 			return -EINVAL;
 		scsi_debug_opts = pos;
-		if (scsi_debug_every_nth > 0)
+		if (scsi_debug_every_nth != 0)
                         scsi_debug_cmnd_count = 0;
 		return length;
 	}
@@ -1547,7 +1598,7 @@
 {
         int nth;
 
-	if ((count > 0) && (1 == sscanf(buf, "%d", &nth)) && (nth >= 0)) {
+	if ((count > 0) && (1 == sscanf(buf, "%d", &nth))) {
 		scsi_debug_every_nth = nth;
 		scsi_debug_cmnd_count = 0;
 		return count;
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsi_error.c	2004-12-12 18:04:46 -08:00
@@ -125,6 +125,7 @@
 
 	add_timer(&scmd->eh_timeout);
 }
+EXPORT_SYMBOL(scsi_add_timer);
 
 /**
  * scsi_delete_timer - Delete/cancel timer for a given function.
@@ -152,6 +153,7 @@
 
 	return rtn;
 }
+EXPORT_SYMBOL(scsi_delete_timer);
 
 /**
  * scsi_times_out - Timeout function for normal scsi commands.
@@ -214,6 +216,7 @@
 
 	return online;
 }
+EXPORT_SYMBOL(scsi_block_when_processing_errors);
 
 #ifdef CONFIG_SCSI_LOGGING
 /**
@@ -268,16 +271,42 @@
  *
  * Return value:
  * 	SUCCESS or FAILED or NEEDS_RETRY
+ *
+ * Notes:
+ *	When a deferred error is detected the current command has
+ *	not been executed and needs retrying.
  **/
 static int scsi_check_sense(struct scsi_cmnd *scmd)
 {
-	if (!SCSI_SENSE_VALID(scmd))
-		return FAILED;
+	struct scsi_sense_hdr sshdr;
 
-	if (scmd->sense_buffer[2] & 0xe0)
-		return SUCCESS;
+	if (! scsi_command_normalize_sense(scmd, &sshdr))
+		return FAILED;	/* no valid sense data */
 
-	switch (scmd->sense_buffer[2] & 0xf) {
+	if (scsi_sense_is_deferred(&sshdr))
+		return NEEDS_RETRY;
+
+	/*
+	 * Previous logic looked for FILEMARK, EOM or ILI which are
+	 * mainly associated with tapes and returned SUCCESS.
+	 */
+	if (sshdr.response_code == 0x70) {
+		/* fixed format */
+		if (scmd->sense_buffer[2] & 0xe0)
+			return SUCCESS;
+	} else {
+		/*
+		 * descriptor format: look for "stream commands sense data
+		 * descriptor" (see SSC-3). Assume single sense data
+		 * descriptor. Ignore ILI from SBC-2 READ LONG and WRITE LONG.
+		 */
+		if ((sshdr.additional_length > 3) &&
+		    (scmd->sense_buffer[8] == 0x4) &&
+		    (scmd->sense_buffer[11] & 0xe0))
+			return SUCCESS;
+	}
+
+	switch (sshdr.sense_key) {
 	case NO_SENSE:
 		return SUCCESS;
 	case RECOVERED_ERROR:
@@ -301,19 +330,15 @@
 		 * if the device is in the process of becoming ready, we 
 		 * should retry.
 		 */
-		if ((scmd->sense_buffer[12] == 0x04) &&
-			(scmd->sense_buffer[13] == 0x01)) {
+		if ((sshdr.asc == 0x04) && (sshdr.ascq == 0x01))
 			return NEEDS_RETRY;
-		}
 		/*
 		 * if the device is not started, we need to wake
 		 * the error handler to start the motor
 		 */
 		if (scmd->device->allow_restart &&
-		    (scmd->sense_buffer[12] == 0x04) &&
-		    (scmd->sense_buffer[13] == 0x02)) {
+		    (sshdr.asc == 0x04) && (sshdr.ascq == 0x02))
 			return FAILED;
-		}
 		return SUCCESS;
 
 		/* these three are not supported */
@@ -1358,7 +1383,8 @@
 		return SUCCESS;
 
 	case RESERVATION_CONFLICT:
-		printk("scsi%d (%d,%d,%d) : reservation conflict\n",
+		printk(KERN_INFO "scsi: reservation conflict: host"
+                                " %d channel %d id %d lun %d\n",
 		       scmd->device->host->host_no, scmd->device->channel,
 		       scmd->device->id, scmd->device->lun);
 		return SUCCESS; /* causes immediate i/o error */
@@ -1729,6 +1755,7 @@
 		}
 	}
 }
+EXPORT_SYMBOL(scsi_report_bus_reset);
 
 /*
  * Function:    scsi_report_device_reset()
@@ -1764,6 +1791,7 @@
 		}
 	}
 }
+EXPORT_SYMBOL(scsi_report_device_reset);
 
 static void
 scsi_reset_provider_done_command(struct scsi_cmnd *scmd)
@@ -1843,6 +1871,7 @@
 	scsi_next_command(scmd);
 	return rtn;
 }
+EXPORT_SYMBOL(scsi_reset_provider);
 
 /**
  * scsi_normalize_sense - normalize main elements from either fixed or
diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
--- a/drivers/scsi/scsi_ioctl.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsi_ioctl.c	2004-12-12 18:04:46 -08:00
@@ -21,6 +21,7 @@
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi_request.h>
 #include <scsi/sg.h>
+#include <scsi/scsi_dbg.h>
 
 #include "scsi_logging.h"
 
@@ -94,12 +95,13 @@
 {
 	struct scsi_request *sreq;
 	int result;
+	struct scsi_sense_hdr sshdr;
 
 	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
 
 	sreq = scsi_allocate_request(sdev, GFP_KERNEL);
 	if (!sreq) {
-		printk("SCSI internal ioctl failed, no memory\n");
+		printk(KERN_WARNING "SCSI internal ioctl failed, no memory\n");
 		return -ENOMEM;
 	}
 
@@ -108,17 +110,21 @@
 
 	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", sreq->sr_result));
 
-	if (driver_byte(sreq->sr_result)) {
-		switch (sreq->sr_sense_buffer[2] & 0xf) {
+	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
+	    (scsi_request_normalize_sense(sreq, &sshdr))) {
+		switch (sshdr.sense_key) {
 		case ILLEGAL_REQUEST:
 			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
 				sdev->lockable = 0;
 			else
-				printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
+				printk(KERN_INFO "ioctl_internal_command: "
+				       "ILLEGAL REQUEST asc=0x%x ascq=0x%x\n",
+				       sshdr.asc, sshdr.ascq);
 			break;
 		case NOT_READY:	/* This happens if there is no disc in drive */
 			if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
-				printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
+				printk(KERN_INFO "Device not ready. Make sure"
+				       " there is a disc in the drive.\n");
 				break;
 			}
 		case UNIT_ATTENTION:
@@ -128,16 +134,15 @@
 				break;
 			}
 		default:	/* Fall through for non-removable media */
-			printk("SCSI error: host %d id %d lun %d return code = %x\n",
+			printk(KERN_INFO "ioctl_internal_command: <%d %d %d "
+			       "%d> return code = %x\n",
 			       sdev->host->host_no,
+			       sdev->channel,
 			       sdev->id,
 			       sdev->lun,
 			       sreq->sr_result);
-			printk("\tSense class %x, sense error %x, extended sense %x\n",
-			       sense_class(sreq->sr_sense_buffer[0]),
-			       sense_error(sreq->sr_sense_buffer[0]),
-			       sreq->sr_sense_buffer[2] & 0xf);
-
+			scsi_print_req_sense("   ", sreq);
+			break;
 		}
 	}
 
@@ -168,6 +173,7 @@
 		sdev->locked = (state == SCSI_REMOVAL_PREVENT);
 	return ret;
 }
+EXPORT_SYMBOL(scsi_set_medium_removal);
 
 /*
  * This interface is deprecated - users should use the scsi generic (sg)
@@ -349,6 +355,7 @@
 	kfree(buf);
 	return result;
 }
+EXPORT_SYMBOL(scsi_ioctl_send_command);
 
 /*
  * The scsi_ioctl_get_pci() function places into arg the value
@@ -401,7 +408,8 @@
 	case SCSI_IOCTL_SYNC:
 	case SCSI_IOCTL_START_UNIT:
 	case SCSI_IOCTL_STOP_UNIT:
-		printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO\n", current->comm);
+		printk(KERN_WARNING "program %s is using a deprecated SCSI "
+		       "ioctl, please convert it to SG_IO\n", current->comm);
 		break;
 	default:
 		break;
@@ -457,6 +465,7 @@
 	}
 	return -EINVAL;
 }
+EXPORT_SYMBOL(scsi_ioctl);
 
 /*
  * the scsi_nonblock_ioctl() function is designed for ioctls which may
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsi_lib.c	2004-12-12 18:04:46 -08:00
@@ -233,7 +233,8 @@
 	 */
 	scsi_insert_special_req(sreq, 1);
 }
- 
+EXPORT_SYMBOL(scsi_do_req);
+
 static void scsi_wait_done(struct scsi_cmnd *cmd)
 {
 	struct request *req = cmd->request;
@@ -267,6 +268,7 @@
 
 	__scsi_release_request(sreq);
 }
+EXPORT_SYMBOL(scsi_wait_req);
 
 /*
  * Function:    scsi_init_cmd_errh()
@@ -718,7 +720,7 @@
 			clear_errors = 0;
 			if (scsi_command_normalize_sense(cmd, &sshdr)) {
 				/*
-				 * SG_IO wants to know about deferred errors
+				 * SG_IO wants current and deferred errors
 				 */
 				int len = 8 + cmd->sense_buffer[7];
 
@@ -844,9 +846,10 @@
 			cmd = scsi_end_request(cmd, 0, this_count, 1);
 			return;
 		case VOLUME_OVERFLOW:
-			printk("scsi%d: ERROR on channel %d, id %d, lun %d, CDB: ",
-			       cmd->device->host->host_no, (int) cmd->device->channel,
-			       (int) cmd->device->id, (int) cmd->device->lun);
+			printk(KERN_INFO "Volume overflow <%d %d %d %d> CDB: ",
+			       cmd->device->host->host_no,
+			       (int)cmd->device->channel,
+			       (int)cmd->device->id, (int)cmd->device->lun);
 			__scsi_print_command(cmd->data_cmnd);
 			scsi_print_sense("", cmd);
 			cmd = scsi_end_request(cmd, 0, block_bytes, 1);
@@ -865,8 +868,8 @@
 		return;
 	}
 	if (result) {
-		printk("SCSI error : <%d %d %d %d> return code = 0x%x\n",
-		       cmd->device->host->host_no,
+		printk(KERN_INFO "SCSI error : <%d %d %d %d> return code "
+		       "= 0x%x\n", cmd->device->host->host_no,
 		       cmd->device->channel,
 		       cmd->device->id,
 		       cmd->device->lun, result);
@@ -884,6 +887,7 @@
 		cmd = scsi_end_request(cmd, 0, block_bytes, 1);
 	}
 }
+EXPORT_SYMBOL(scsi_io_completion);
 
 /*
  * Function:    scsi_init_io()
@@ -1344,6 +1348,7 @@
 
 	return bounce_limit;
 }
+EXPORT_SYMBOL(scsi_calculate_bounce_limit);
 
 struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
 {
@@ -1393,6 +1398,7 @@
 {
 	shost->host_self_blocked = 1;
 }
+EXPORT_SYMBOL(scsi_block_requests);
 
 /*
  * Function:    scsi_unblock_requests()
@@ -1419,6 +1425,7 @@
 	shost->host_self_blocked = 0;
 	scsi_run_host_queues(shost);
 }
+EXPORT_SYMBOL(scsi_unblock_requests);
 
 int __init scsi_init_queue(void)
 {
@@ -1553,6 +1560,7 @@
 
 	return sreq->sr_result;
 }
+EXPORT_SYMBOL(__scsi_mode_sense);
 
 /**
  *	scsi_mode_sense - issue a mode sense, falling back from 10 to 
@@ -1587,6 +1595,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL(scsi_mode_sense);
 
 int
 scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries)
@@ -1604,12 +1613,15 @@
 	sreq->sr_data_direction = DMA_NONE;
 	scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
 
-	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
-	    ((sreq->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION ||
-	     (sreq->sr_sense_buffer[2] & 0x0f) == NOT_READY) &&
-	    sdev->removable) {
-		sdev->changed = 1;
-		sreq->sr_result = 0;
+	if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && sdev->removable) {
+		struct scsi_sense_hdr sshdr;
+
+		if ((scsi_request_normalize_sense(sreq, &sshdr)) &&
+		    ((sshdr.sense_key == UNIT_ATTENTION) ||
+		     (sshdr.sense_key == NOT_READY))) {
+			sdev->changed = 1;
+			sreq->sr_result = 0;
+		}
 	}
 	result = sreq->sr_result;
 	scsi_release_request(sreq);
@@ -1668,6 +1680,7 @@
 		case SDEV_CREATED:
 		case SDEV_RUNNING:
 		case SDEV_QUIESCE:
+		case SDEV_BLOCK:
 			break;
 		default:
 			goto illegal;
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsi_scan.c	2004-12-12 18:04:46 -08:00
@@ -39,6 +39,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_request.h>
 #include <scsi/scsi_transport.h>
+#include <scsi/scsi_eh.h>
 
 #include "scsi_priv.h"
 #include "scsi_logging.h"
@@ -253,6 +254,11 @@
 	sdev->request_queue->queuedata = sdev;
 	scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
 
+	if (shost->transportt->device_setup) {
+		if (shost->transportt->device_setup(sdev))
+			goto out_free_queue;
+	}
+
 	if (shost->hostt->slave_alloc) {
 		ret = shost->hostt->slave_alloc(sdev);
 		if (ret) {
@@ -262,15 +268,10 @@
 			 */
 			if (ret == -ENXIO)
 				display_failure_msg = 0;
-			goto out_free_queue;
+			goto out_device_destroy;
 		}
 	}
 
-	if (shost->transportt->device_setup) {
-		if (shost->transportt->device_setup(sdev))
-			goto out_cleanup_slave;
-	}
-
 	if (scsi_sysfs_device_initialize(sdev) != 0)
 		goto out_cleanup_slave;
 
@@ -290,6 +291,9 @@
 out_cleanup_slave:
 	if (shost->hostt->slave_destroy)
 		shost->hostt->slave_destroy(sdev);
+out_device_destroy:
+	if (shost->transportt->device_destroy)
+		shost->transportt->device_destroy(sdev);
 out_free_queue:
 	scsi_free_queue(sdev->request_queue);
 out_free_dev:
@@ -322,6 +326,7 @@
 	int first_inquiry_len, try_inquiry_len, next_inquiry_len;
 	int response_len = 0;
 	int pass, count;
+	struct scsi_sense_hdr sshdr;
 
 	*bflags = 0;
 
@@ -357,17 +362,20 @@
 				sreq->sr_result));
 
 		if (sreq->sr_result) {
-
-			/* not-ready to ready transition or power-on - good */
-			/* dpg: bogus? INQUIRY never returns UNIT_ATTENTION */
-			/* Supposedly, but many buggy devices do so anyway. */
+			/*
+			 * not-ready to ready transition [asc/ascq=0x28/0x0]
+			 * or power-on, reset [asc/ascq=0x29/0x0], continue.
+			 * INQUIRY should not yield UNIT_ATTENTION
+			 * but many buggy devices do so anyway. 
+			 */
 			if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
-					(sreq->sr_sense_buffer[2] & 0xf) ==
-						UNIT_ATTENTION &&
-					(sreq->sr_sense_buffer[12] == 0x28 ||
-					 sreq->sr_sense_buffer[12] == 0x29) &&
-					sreq->sr_sense_buffer[13] == 0)
-				continue;
+			    scsi_request_normalize_sense(sreq, &sshdr)) {
+				if ((sshdr.sense_key == UNIT_ATTENTION) &&
+				    ((sshdr.asc == 0x28) ||
+				     (sshdr.asc == 0x29)) &&
+				    (sshdr.ascq == 0))
+					continue;
+			}
 		}
 		break;
 	}
@@ -741,6 +749,8 @@
 	} else {
 		if (sdev->host->hostt->slave_destroy)
 			sdev->host->hostt->slave_destroy(sdev);
+		if (sdev->host->transportt->device_destroy)
+			sdev->host->transportt->device_destroy(sdev);
 		put_device(&sdev->sdev_gendev);
 	}
  out:
@@ -893,6 +903,7 @@
 	struct scsi_lun *lunp, *lun_data;
 	struct scsi_request *sreq;
 	u8 *data;
+	struct scsi_sense_hdr sshdr;
 
 	/*
 	 * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
@@ -970,9 +981,12 @@
 				" %s (try %d) result 0x%x\n", sreq->sr_result
 				?  "failed" : "successful", retries,
 				sreq->sr_result));
-		if (sreq->sr_result == 0 ||
-		    sreq->sr_sense_buffer[2] != UNIT_ATTENTION)
+		if (sreq->sr_result == 0)
 			break;
+		else if (scsi_request_normalize_sense(sreq, &sshdr)) {
+			if (sshdr.sense_key != UNIT_ATTENTION)
+				break;
+		}
 	}
 
 	if (sreq->sr_result) {
@@ -1082,6 +1096,7 @@
 
 	return sdev;
 }
+EXPORT_SYMBOL(__scsi_add_device);
 
 void scsi_rescan_device(struct device *dev)
 {
@@ -1097,6 +1112,7 @@
 		module_put(drv->owner);
 	}
 }
+EXPORT_SYMBOL(scsi_rescan_device);
 
 /**
  * scsi_scan_target - scan a target id, possibly including all LUNs on the
@@ -1225,6 +1241,20 @@
 	scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
 				SCAN_WILD_CARD, 0);
 }
+EXPORT_SYMBOL(scsi_scan_host);
+
+/**
+ * scsi_scan_single_target - scan the given SCSI target
+ * @shost:         adapter to scan
+ * @chan:          channel to scan
+ * @id:            target id to scan
+ **/
+void scsi_scan_single_target(struct Scsi_Host *shost, 
+	unsigned int chan, unsigned int id)
+{
+	scsi_scan_host_selected(shost, chan, id, SCAN_WILD_CARD, 1);
+}
+EXPORT_SYMBOL(scsi_scan_single_target);
 
 void scsi_forget_host(struct Scsi_Host *shost)
 {
@@ -1279,6 +1309,7 @@
 	}
 	return sdev;
 }
+EXPORT_SYMBOL(scsi_get_host_dev);
 
 /*
  * Function:    scsi_free_host_dev()
@@ -1299,5 +1330,9 @@
 
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
+	if (sdev->host->transportt->device_destroy)
+		sdev->host->transportt->device_destroy(sdev);
 	put_device(&sdev->sdev_gendev);
 }
+EXPORT_SYMBOL(scsi_free_host_dev);
+
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	2004-12-12 18:04:46 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,97 +0,0 @@
-/*
- * We should not even be trying to compile this if we are not doing
- * a module.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_dbg.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_driver.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_ioctl.h>
-#include <scsi/scsi_request.h>
-#include <scsi/scsicam.h>
-
-#include "scsi_logging.h"
-
-
-/*
- * This source file contains the symbol table used by scsi loadable
- * modules.
- */
-EXPORT_SYMBOL(scsi_register_driver);
-EXPORT_SYMBOL(scsi_register_interface);
-EXPORT_SYMBOL(scsi_host_alloc);
-EXPORT_SYMBOL(scsi_add_host);
-EXPORT_SYMBOL(scsi_scan_host);
-EXPORT_SYMBOL(scsi_remove_host);
-EXPORT_SYMBOL(scsi_host_get);
-EXPORT_SYMBOL(scsi_host_put);
-EXPORT_SYMBOL(scsi_host_lookup);
-EXPORT_SYMBOL(scsi_register);
-EXPORT_SYMBOL(scsi_unregister);
-EXPORT_SYMBOL(scsicam_bios_param);
-EXPORT_SYMBOL(scsi_partsize);
-EXPORT_SYMBOL(scsi_bios_ptable);
-EXPORT_SYMBOL(scsi_ioctl);
-EXPORT_SYMBOL(scsi_print_command);
-EXPORT_SYMBOL(__scsi_print_command);
-EXPORT_SYMBOL(scsi_print_sense);
-EXPORT_SYMBOL(scsi_print_req_sense);
-EXPORT_SYMBOL(scsi_print_msg);
-EXPORT_SYMBOL(scsi_print_status);
-EXPORT_SYMBOL(scsi_sense_key_string);
-EXPORT_SYMBOL(scsi_extd_sense_format);
-EXPORT_SYMBOL(scsi_block_when_processing_errors);
-EXPORT_SYMBOL(scsi_ioctl_send_command);
-EXPORT_SYMBOL(scsi_set_medium_removal);
-#if defined(CONFIG_SCSI_LOGGING)	/* { */
-EXPORT_SYMBOL(scsi_logging_level);
-#endif
-
-EXPORT_SYMBOL(scsi_allocate_request);
-EXPORT_SYMBOL(scsi_release_request);
-EXPORT_SYMBOL(scsi_wait_req);
-EXPORT_SYMBOL(scsi_do_req);
-EXPORT_SYMBOL(scsi_get_command);
-EXPORT_SYMBOL(scsi_put_command);
-
-EXPORT_SYMBOL(scsi_report_bus_reset);
-EXPORT_SYMBOL(scsi_report_device_reset);
-EXPORT_SYMBOL(scsi_block_requests);
-EXPORT_SYMBOL(scsi_unblock_requests);
-EXPORT_SYMBOL(scsi_adjust_queue_depth);
-EXPORT_SYMBOL(scsi_track_queue_full);
-
-EXPORT_SYMBOL(scsi_get_host_dev);
-EXPORT_SYMBOL(scsi_free_host_dev);
-
-EXPORT_SYMBOL(scsi_io_completion);
-
-EXPORT_SYMBOL(__scsi_add_device);
-EXPORT_SYMBOL(scsi_remove_device);
-EXPORT_SYMBOL(scsi_device_cancel);
-
-EXPORT_SYMBOL(__scsi_mode_sense);
-EXPORT_SYMBOL(scsi_mode_sense);
-
-/*
- * This symbol is for the highlevel drivers (e.g. sg) only.
- */
-EXPORT_SYMBOL(scsi_reset_provider);
-
-EXPORT_SYMBOL(scsi_device_types);
-
-/*
- * This is for st to find the bounce limit
- */
-EXPORT_SYMBOL(scsi_calculate_bounce_limit);
-
-/*
- * Externalize timers so that HBAs can safely start/restart commands.
- */
-EXPORT_SYMBOL(scsi_add_timer);
-EXPORT_SYMBOL(scsi_delete_timer);
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsi_sysfs.c	2004-12-12 18:04:46 -08:00
@@ -169,7 +169,10 @@
 
 	if (delete) {
 		struct scsi_target *starget = to_scsi_target(parent);
+		struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
 		if (!starget->create) {
+			if (shost->transportt->target_destroy)
+				shost->transportt->target_destroy(starget);
 			device_del(parent);
 			if (starget->transport_classdev.class)
 				class_device_unregister(&starget->transport_classdev);
@@ -601,11 +604,14 @@
 	scsi_device_set_state(sdev, SDEV_DEL);
 	if (sdev->host->hostt->slave_destroy)
 		sdev->host->hostt->slave_destroy(sdev);
+	if (sdev->host->transportt->device_destroy)
+		sdev->host->transportt->device_destroy(sdev);
 	put_device(&sdev->sdev_gendev);
 
 out:
 	up(&shost->scan_mutex);
 }
+EXPORT_SYMBOL(scsi_remove_device);
 
 int scsi_register_driver(struct device_driver *drv)
 {
@@ -613,6 +619,7 @@
 
 	return driver_register(drv);
 }
+EXPORT_SYMBOL(scsi_register_driver);
 
 int scsi_register_interface(struct class_interface *intf)
 {
@@ -620,6 +627,7 @@
 
 	return class_interface_register(intf);
 }
+EXPORT_SYMBOL(scsi_register_interface);
 
 
 static struct class_device_attribute *class_attr_overridden(
diff -Nru a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
--- a/drivers/scsi/scsi_transport_fc.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsi_transport_fc.c	2004-12-12 18:04:46 -08:00
@@ -29,6 +29,8 @@
 
 static void transport_class_release(struct class_device *class_dev);
 static void host_class_release(struct class_device *class_dev);
+static void fc_timeout_blocked_host(void *data);
+static void fc_timeout_blocked_tgt(void *data);
 
 #define FC_STARGET_NUM_ATTRS 	4	/* increase this if you add attributes */
 #define FC_STARGET_OTHER_ATTRS 	0	/* increase this if you add "always on"
@@ -87,10 +89,18 @@
 	fc_starget_port_name(starget) = -1;
 	fc_starget_port_id(starget) = -1;
 	fc_starget_dev_loss_tmo(starget) = -1;
-	init_timer(&fc_starget_dev_loss_timer(starget));
+	INIT_WORK(&fc_starget_dev_loss_work(starget),
+		  fc_timeout_blocked_tgt, starget);
 	return 0;
 }
 
+static void fc_destroy_starget(struct scsi_target *starget)
+{
+	/* Stop the target timer */
+	if (cancel_delayed_work(&fc_starget_dev_loss_work(starget)))
+		flush_scheduled_work();
+}
+
 static int fc_setup_host_transport_attrs(struct Scsi_Host *shost)
 {
 	/* 
@@ -99,10 +109,18 @@
 	 * all transport attributes to valid values per host.
 	 */
 	fc_host_link_down_tmo(shost) = -1;
-	init_timer(&fc_host_link_down_timer(shost));
+	INIT_WORK(&fc_host_link_down_work(shost),
+		  fc_timeout_blocked_host, shost);
 	return 0;
 }
 
+static void fc_destroy_host(struct Scsi_Host *shost)
+{
+	/* Stop the host timer */
+	if (cancel_delayed_work(&fc_host_link_down_work(shost)))
+		flush_scheduled_work();
+}
+
 static void transport_class_release(struct class_device *class_dev)
 {
 	struct scsi_target *starget = transport_class_to_starget(class_dev);
@@ -277,11 +295,13 @@
 	i->t.target_attrs = &i->starget_attrs[0];
 	i->t.target_class = &fc_transport_class;
 	i->t.target_setup = &fc_setup_starget_transport_attrs;
+	i->t.target_destroy = &fc_destroy_starget;
 	i->t.target_size = sizeof(struct fc_starget_attrs);
 
 	i->t.host_attrs = &i->host_attrs[0];
 	i->t.host_class = &fc_host_class;
 	i->t.host_setup = &fc_setup_host_transport_attrs;
+	i->t.host_destroy = &fc_destroy_host;
 	i->t.host_size = sizeof(struct fc_host_attrs);
 	i->f = ft;
 
@@ -353,7 +373,7 @@
  *			 that fail to recover in the alloted time.
  * @data:	scsi target that failed to reappear in the alloted time.
  **/
-static void fc_timeout_blocked_tgt(unsigned long data)
+static void fc_timeout_blocked_tgt(void  *data)
 {
 	struct scsi_target *starget = (struct scsi_target *)data;
 
@@ -388,7 +408,7 @@
 fc_target_block(struct scsi_target *starget)
 {
 	int timeout = fc_starget_dev_loss_tmo(starget);
-	struct timer_list *timer = &fc_starget_dev_loss_timer(starget);
+	struct work_struct *work = &fc_starget_dev_loss_work(starget);
 
 	if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
 		return -EINVAL;
@@ -396,10 +416,7 @@
 	device_for_each_child(&starget->dev, NULL, fc_device_block);
 
 	/* The scsi lld blocks this target for the timeout period only. */
-	timer->data = (unsigned long)starget;
-	timer->expires = jiffies + timeout * HZ;
-	timer->function = fc_timeout_blocked_tgt;
-	add_timer(timer);
+	schedule_delayed_work(work, timeout * HZ);
 
 	return 0;
 }
@@ -424,7 +441,8 @@
 	 * failure as the state machine state change will validate the
 	 * transaction. 
 	 */
-	del_timer_sync(&fc_starget_dev_loss_timer(starget));
+	if (cancel_delayed_work(&fc_starget_dev_loss_work(starget)))
+		flush_scheduled_work();
 
 	device_for_each_child(&starget->dev, NULL, fc_device_unblock);
 }
@@ -436,7 +454,7 @@
  * @data:	scsi host that failed to recover its devices in the alloted
  *		time.
  **/
-static void fc_timeout_blocked_host(unsigned long data)
+static void fc_timeout_blocked_host(void  *data)
 {
 	struct Scsi_Host *shost = (struct Scsi_Host *)data;
 	struct scsi_device *sdev;
@@ -475,7 +493,7 @@
 {
 	struct scsi_device *sdev;
 	int timeout = fc_host_link_down_tmo(shost);
-	struct timer_list *timer = &fc_host_link_down_timer(shost);
+	struct work_struct *work = &fc_host_link_down_work(shost);
 
 	if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
 		return -EINVAL;
@@ -484,11 +502,7 @@
 		scsi_internal_device_block(sdev);
 	}
 
-	/* The scsi lld blocks this host for the timeout period only. */
-	timer->data = (unsigned long)shost;
-	timer->expires = jiffies + timeout * HZ;
-	timer->function = fc_timeout_blocked_host;
-	add_timer(timer);
+	schedule_delayed_work(work, timeout * HZ);
 
 	return 0;
 }
@@ -516,7 +530,9 @@
 	 * failure as the state machine state change will validate the
 	 * transaction.
 	 */
-	del_timer_sync(&fc_host_link_down_timer(shost));
+	if (cancel_delayed_work(&fc_host_link_down_work(shost)))
+		flush_scheduled_work();
+
 	shost_for_each_device(sdev, shost) {
 		scsi_internal_device_unblock(sdev);
 	}
diff -Nru a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/scsi/scsi_transport_iscsi.c	2004-12-12 18:04:46 -08:00
@@ -0,0 +1,355 @@
+/* 
+ * iSCSI transport class definitions
+ *
+ * Copyright (C) IBM Corporation, 2004
+ * Copyright (C) Mike Christie, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/module.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_iscsi.h>
+
+#define ISCSI_SESSION_ATTRS 20
+#define ISCSI_HOST_ATTRS 2
+
+struct iscsi_internal {
+	struct scsi_transport_template t;
+	struct iscsi_function_template *fnt;
+	/*
+	 * We do not have any private or other attrs.
+	 */
+	struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
+	struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
+};
+
+#define to_iscsi_internal(tmpl) container_of(tmpl, struct iscsi_internal, t)
+
+static void iscsi_transport_class_release(struct class_device *class_dev)
+{
+	struct scsi_target *starget = transport_class_to_starget(class_dev);
+	put_device(&starget->dev);
+}
+
+struct class iscsi_transport_class = {
+	.name = "iscsi_transport_class",
+	.release = iscsi_transport_class_release,
+};
+
+static void iscsi_host_class_release(struct class_device *class_dev)
+{
+	struct Scsi_Host *shost = transport_class_to_shost(class_dev);
+	put_device(&shost->shost_gendev);
+}
+
+struct class iscsi_host_class = {
+	.name = "iscsi_host",
+	.release = iscsi_host_class_release,
+};
+
+/*
+ * iSCSI target and session attrs
+ */
+#define iscsi_session_show_fn(field, format)				\
+									\
+static ssize_t								\
+show_session_##field(struct class_device *cdev, char *buf)		\
+{									\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		i->fnt->get_##field(starget);				\
+	return snprintf(buf, 20, format"\n", iscsi_##field(starget));	\
+}
+
+#define iscsi_session_rd_attr(field, format)				\
+	iscsi_session_show_fn(field, format)				\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_##field, NULL);
+
+iscsi_session_rd_attr(tpgt, "%hu");
+iscsi_session_rd_attr(tsih, "%2x");
+iscsi_session_rd_attr(max_recv_data_segment_len, "%u");
+iscsi_session_rd_attr(max_burst_len, "%u");
+iscsi_session_rd_attr(first_burst_len, "%u");
+iscsi_session_rd_attr(def_time2wait, "%hu");
+iscsi_session_rd_attr(def_time2retain, "%hu");
+iscsi_session_rd_attr(max_outstanding_r2t, "%hu");
+iscsi_session_rd_attr(erl, "%d");
+
+
+#define iscsi_session_show_bool_fn(field)				\
+									\
+static ssize_t								\
+show_session_bool_##field(struct class_device *cdev, char *buf)		\
+{									\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		i->fnt->get_##field(starget);				\
+									\
+	if (iscsi_##field(starget))					\
+		return sprintf(buf, "Yes\n");				\
+	return sprintf(buf, "No\n");					\
+}
+
+#define iscsi_session_rd_bool_attr(field)				\
+	iscsi_session_show_bool_fn(field)				\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_bool_##field, NULL);
+
+iscsi_session_rd_bool_attr(initial_r2t);
+iscsi_session_rd_bool_attr(immediate_data);
+iscsi_session_rd_bool_attr(data_pdu_in_order);
+iscsi_session_rd_bool_attr(data_sequence_in_order);
+
+#define iscsi_session_show_digest_fn(field)				\
+									\
+static ssize_t								\
+show_##field(struct class_device *cdev, char *buf)			\
+{									\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		i->fnt->get_##field(starget);				\
+									\
+	if (iscsi_##field(starget))					\
+		return sprintf(buf, "CRC32C\n");			\
+	return sprintf(buf, "None\n");					\
+}
+
+#define iscsi_session_rd_digest_attr(field)				\
+	iscsi_session_show_digest_fn(field)				\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+
+iscsi_session_rd_digest_attr(header_digest);
+iscsi_session_rd_digest_attr(data_digest);
+
+static ssize_t
+show_port(struct class_device *cdev, char *buf)
+{
+	struct scsi_target *starget = transport_class_to_starget(cdev);
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+
+	if (i->fnt->get_port)
+		i->fnt->get_port(starget);
+
+	return snprintf(buf, 20, "%hu\n", ntohs(iscsi_port(starget)));
+}
+static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
+
+static ssize_t
+show_ip_address(struct class_device *cdev, char *buf)
+{
+	struct scsi_target *starget = transport_class_to_starget(cdev);
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+
+	if (i->fnt->get_ip_address)
+		i->fnt->get_ip_address(starget);
+
+	if (iscsi_addr_type(starget) == AF_INET)
+		return sprintf(buf, "%u.%u.%u.%u\n",
+			       NIPQUAD(iscsi_sin_addr(starget)));
+	else if(iscsi_addr_type(starget) == AF_INET6)
+		return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+			       NIP6(iscsi_sin6_addr(starget)));
+	return -EINVAL;
+}
+static CLASS_DEVICE_ATTR(ip_address, S_IRUGO, show_ip_address, NULL);
+
+static ssize_t
+show_isid(struct class_device *cdev, char *buf)
+{
+	struct scsi_target *starget = transport_class_to_starget(cdev);
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt);
+
+	if (i->fnt->get_isid)
+		i->fnt->get_isid(starget);
+
+	return sprintf(buf, "%02x%02x%02x%02x%02x%02x\n",
+		       iscsi_isid(starget)[0], iscsi_isid(starget)[1],
+		       iscsi_isid(starget)[2], iscsi_isid(starget)[3],
+		       iscsi_isid(starget)[4], iscsi_isid(starget)[5]);
+}
+static CLASS_DEVICE_ATTR(isid, S_IRUGO, show_isid, NULL);
+
+/*
+ * This is used for iSCSI names. Normally, we follow
+ * the transport class convention of having the lld
+ * set the field, but in these cases the value is
+ * too large.
+ */
+#define iscsi_session_show_str_fn(field)				\
+									\
+static ssize_t								\
+show_session_str_##field(struct class_device *cdev, char *buf)		\
+{									\
+	ssize_t ret = 0;						\
+	struct scsi_target *starget = transport_class_to_starget(cdev);	\
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		ret = i->fnt->get_##field(starget, buf, PAGE_SIZE);	\
+	return ret;							\
+}
+
+#define iscsi_session_rd_str_attr(field)				\
+	iscsi_session_show_str_fn(field)				\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_str_##field, NULL);
+
+iscsi_session_rd_str_attr(target_name);
+iscsi_session_rd_str_attr(target_alias);
+
+/*
+ * iSCSI host attrs
+ */
+
+/*
+ * Again, this is used for iSCSI names. Normally, we follow
+ * the transport class convention of having the lld set
+ * the field, but in these cases the value is too large.
+ */
+#define iscsi_host_show_str_fn(field)					\
+									\
+static ssize_t								\
+show_host_str_##field(struct class_device *cdev, char *buf)		\
+{									\
+	int ret = 0;							\
+	struct Scsi_Host *shost = transport_class_to_shost(cdev);	\
+	struct iscsi_internal *i = to_iscsi_internal(shost->transportt); \
+									\
+	if (i->fnt->get_##field)					\
+		ret = i->fnt->get_##field(shost, buf, PAGE_SIZE);	\
+	return ret;							\
+}
+
+#define iscsi_host_rd_str_attr(field)					\
+	iscsi_host_show_str_fn(field)					\
+static CLASS_DEVICE_ATTR(field, S_IRUGO, show_host_str_##field, NULL);
+
+iscsi_host_rd_str_attr(initiator_name);
+iscsi_host_rd_str_attr(initiator_alias);
+
+#define SETUP_SESSION_RD_ATTR(field)					\
+	if (i->fnt->show_##field) {					\
+		i->session_attrs[count] = &class_device_attr_##field;	\
+		count++;						\
+	}
+
+#define SETUP_HOST_RD_ATTR(field)					\
+	if (i->fnt->show_##field) {					\
+		i->host_attrs[count] = &class_device_attr_##field;	\
+		count++;						\
+	}
+
+struct scsi_transport_template *
+iscsi_attach_transport(struct iscsi_function_template *fnt)
+{
+	struct iscsi_internal *i = kmalloc(sizeof(struct iscsi_internal),
+					   GFP_KERNEL);
+	int count = 0;
+
+	if (unlikely(!i))
+		return NULL;
+
+	memset(i, 0, sizeof(struct iscsi_internal));
+	i->fnt = fnt;
+
+	i->t.target_attrs = &i->session_attrs[0];
+	i->t.target_class = &iscsi_transport_class;
+	i->t.target_setup = NULL;
+	i->t.target_size = sizeof(struct iscsi_class_session);
+
+	SETUP_SESSION_RD_ATTR(tsih);
+	SETUP_SESSION_RD_ATTR(isid);
+	SETUP_SESSION_RD_ATTR(header_digest);
+	SETUP_SESSION_RD_ATTR(data_digest);
+	SETUP_SESSION_RD_ATTR(target_name);
+	SETUP_SESSION_RD_ATTR(target_alias);
+	SETUP_SESSION_RD_ATTR(port);
+	SETUP_SESSION_RD_ATTR(tpgt);
+	SETUP_SESSION_RD_ATTR(ip_address);
+	SETUP_SESSION_RD_ATTR(initial_r2t);
+	SETUP_SESSION_RD_ATTR(immediate_data);
+	SETUP_SESSION_RD_ATTR(max_recv_data_segment_len);
+	SETUP_SESSION_RD_ATTR(max_burst_len);
+	SETUP_SESSION_RD_ATTR(first_burst_len);
+	SETUP_SESSION_RD_ATTR(def_time2wait);
+	SETUP_SESSION_RD_ATTR(def_time2retain);
+	SETUP_SESSION_RD_ATTR(max_outstanding_r2t);
+	SETUP_SESSION_RD_ATTR(data_pdu_in_order);
+	SETUP_SESSION_RD_ATTR(data_sequence_in_order);
+	SETUP_SESSION_RD_ATTR(erl);
+
+	BUG_ON(count > ISCSI_SESSION_ATTRS);
+	i->session_attrs[count] = NULL;
+
+	i->t.host_attrs = &i->host_attrs[0];
+	i->t.host_class = &iscsi_host_class;
+	i->t.host_setup = NULL;
+	i->t.host_size = 0;
+
+	count = 0;
+	SETUP_HOST_RD_ATTR(initiator_name);
+	SETUP_HOST_RD_ATTR(initiator_alias);
+
+	BUG_ON(count > ISCSI_HOST_ATTRS);
+	i->host_attrs[count] = NULL;
+
+	return &i->t;
+}
+
+EXPORT_SYMBOL(iscsi_attach_transport);
+
+void iscsi_release_transport(struct scsi_transport_template *t)
+{
+	struct iscsi_internal *i = to_iscsi_internal(t);
+	kfree(i);
+}
+
+EXPORT_SYMBOL(iscsi_release_transport);
+
+static __init int iscsi_transport_init(void)
+{
+	int err = class_register(&iscsi_transport_class);
+
+	if (err)
+		return err;
+	return class_register(&iscsi_host_class);
+}
+
+static void __exit iscsi_transport_exit(void)
+{
+	class_unregister(&iscsi_host_class);
+	class_unregister(&iscsi_transport_class);
+}
+
+module_init(iscsi_transport_init);
+module_exit(iscsi_transport_exit);
+
+MODULE_AUTHOR("Mike Christie");
+MODULE_DESCRIPTION("iSCSI Transport Attributes");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c
--- a/drivers/scsi/scsicam.c	2004-12-12 18:04:46 -08:00
+++ b/drivers/scsi/scsicam.c	2004-12-12 18:04:46 -08:00
@@ -41,6 +41,7 @@
 	}
 	return res;
 }
+EXPORT_SYMBOL(scsi_bios_ptable);
 
 /*
  * Function : int scsicam_bios_param (struct block_device *bdev, ector_t capacity, int *ip)
@@ -94,6 +95,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(scsicam_bios_param);
 
 /*
  * Function : static int scsi_partsize(unsigned char *buf, unsigned long 
@@ -175,6 +177,7 @@
 	}
 	return -1;
 }
+EXPORT_SYMBOL(scsi_partsize);
 
 /*
  * Function : static int setsize(unsigned long capacity,unsigned int *cyls,
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	2004-12-12 18:04:46 -08:00
+++ b/include/linux/pci_ids.h	2004-12-12 18:04:46 -08:00
@@ -176,10 +176,20 @@
 #define PCI_DEVICE_ID_LSI_FC919		0x0624
 #define PCI_DEVICE_ID_LSI_FC919_LAN	0x0625
 #define PCI_DEVICE_ID_LSI_FC929X	0x0626
+#define PCI_DEVICE_ID_LSI_FC939X	0x0642
+#define PCI_DEVICE_ID_LSI_FC949X	0x0640
 #define PCI_DEVICE_ID_LSI_FC919X	0x0628
 #define PCI_DEVICE_ID_NCR_YELLOWFIN	0x0701
 #define PCI_DEVICE_ID_LSI_61C102	0x0901
 #define PCI_DEVICE_ID_LSI_63C815	0x1000
+#define PCI_DEVICE_ID_LSI_SAS1064	0x0050
+#define PCI_DEVICE_ID_LSI_SAS1066	0x005E
+#define PCI_DEVICE_ID_LSI_SAS1068	0x0054
+#define PCI_DEVICE_ID_LSI_SAS1064A	0x005C
+#define PCI_DEVICE_ID_LSI_SAS1064E	0x0056
+#define PCI_DEVICE_ID_LSI_SAS1066E	0x005A
+#define PCI_DEVICE_ID_LSI_SAS1068E	0x0058
+#define PCI_DEVICE_ID_LSI_SAS1078	0x0060
 
 #define PCI_VENDOR_ID_ATI		0x1002
 /* Mach64 */
diff -Nru a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
--- a/include/scsi/scsi_host.h	2004-12-12 18:04:46 -08:00
+++ b/include/scsi/scsi_host.h	2004-12-12 18:04:46 -08:00
@@ -527,6 +527,9 @@
 extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
 extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
 extern void scsi_scan_host(struct Scsi_Host *);
+extern void scsi_scan_single_target(struct Scsi_Host *, unsigned int,
+	unsigned int);
+extern void scsi_rescan_device(struct device *);
 extern void scsi_remove_host(struct Scsi_Host *);
 extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *);
 extern void scsi_host_put(struct Scsi_Host *t);
diff -Nru a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
--- a/include/scsi/scsi_transport.h	2004-12-12 18:04:46 -08:00
+++ b/include/scsi/scsi_transport.h	2004-12-12 18:04:46 -08:00
@@ -40,6 +40,11 @@
 	int (*target_setup)(struct scsi_target *);
 	int (*host_setup)(struct Scsi_Host *);
 
+	/* Destructor functions */
+	void (*device_destroy)(struct scsi_device *);
+	void (*target_destroy)(struct scsi_target *);
+	void (*host_destroy)(struct Scsi_Host *);
+
 	/* The size of the specific transport attribute structure (a
 	 * space of this size will be left at the end of the
 	 * scsi_* structure */
diff -Nru a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
--- a/include/scsi/scsi_transport_fc.h	2004-12-12 18:04:46 -08:00
+++ b/include/scsi/scsi_transport_fc.h	2004-12-12 18:04:46 -08:00
@@ -29,7 +29,7 @@
 	uint64_t node_name;
 	uint64_t port_name;
 	uint32_t dev_loss_tmo;	/* Remote Port loss timeout in seconds. */
-	struct timer_list dev_loss_timer;
+	struct work_struct dev_loss_work;
 };
 
 #define fc_starget_port_id(x) \
@@ -40,18 +40,18 @@
 	(((struct fc_starget_attrs *)&(x)->starget_data)->port_name)
 #define fc_starget_dev_loss_tmo(x) \
 	(((struct fc_starget_attrs *)&(x)->starget_data)->dev_loss_tmo)
-#define fc_starget_dev_loss_timer(x) \
-	(((struct fc_starget_attrs *)&(x)->starget_data)->dev_loss_timer)
+#define fc_starget_dev_loss_work(x) \
+	(((struct fc_starget_attrs *)&(x)->starget_data)->dev_loss_work)
 
 struct fc_host_attrs {
 	uint32_t link_down_tmo;	/* Link Down timeout in seconds. */
-	struct timer_list link_down_timer;
+	struct work_struct link_down_work;
 };
 
 #define fc_host_link_down_tmo(x) \
 	(((struct fc_host_attrs *)(x)->shost_data)->link_down_tmo)
-#define fc_host_link_down_timer(x) \
-	(((struct fc_host_attrs *)(x)->shost_data)->link_down_timer)
+#define fc_host_link_down_work(x) \
+	(((struct fc_host_attrs *)(x)->shost_data)->link_down_work)
 
 
 /* The functions by which the transport class and the driver communicate */
diff -Nru a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/scsi/scsi_transport_iscsi.h	2004-12-12 18:04:46 -08:00
@@ -0,0 +1,178 @@
+/* 
+ * iSCSI transport class definitions
+ *
+ * Copyright (C) IBM Corporation, 2004
+ * Copyright (C) Mike Christie, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef SCSI_TRANSPORT_ISCSI_H
+#define SCSI_TRANSPORT_ISCSI_H
+
+#include <linux/config.h>
+#include <linux/in6.h>
+#include <linux/in.h>
+
+struct scsi_transport_template;
+
+struct iscsi_class_session {
+	uint8_t isid[6];
+	uint16_t tsih;
+	int header_digest;		/* 1 CRC32, 0 None */
+	int data_digest;		/* 1 CRC32, 0 None */
+	uint16_t tpgt;
+	union {
+		struct in6_addr sin6_addr;
+		struct in_addr sin_addr;
+	} u;
+	sa_family_t addr_type;		/* must be AF_INET or AF_INET6 */
+	uint16_t port;			/* must be in network byte order */
+	int initial_r2t;		/* 1 Yes, 0 No */
+	int immediate_data;		/* 1 Yes, 0 No */
+	uint32_t max_recv_data_segment_len;
+	uint32_t max_burst_len;
+	uint32_t first_burst_len;
+	uint16_t def_time2wait;
+	uint16_t def_time2retain;
+	uint16_t max_outstanding_r2t;
+	int data_pdu_in_order;		/* 1 Yes, 0 No */
+	int data_sequence_in_order;	/* 1 Yes, 0 No */
+	int erl;
+};
+
+/*
+ * accessor macros
+ */
+#define iscsi_isid(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->isid)
+#define iscsi_tsih(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->tsih)
+#define iscsi_header_digest(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->header_digest)
+#define iscsi_data_digest(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->data_digest)
+#define iscsi_port(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->port)
+#define iscsi_addr_type(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->addr_type)
+#define iscsi_sin_addr(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->u.sin_addr)
+#define iscsi_sin6_addr(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->u.sin6_addr)
+#define iscsi_tpgt(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->tpgt)
+#define iscsi_initial_r2t(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->initial_r2t)
+#define iscsi_immediate_data(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->immediate_data)
+#define iscsi_max_recv_data_segment_len(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->max_recv_data_segment_len)
+#define iscsi_max_burst_len(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->max_burst_len)
+#define iscsi_first_burst_len(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->first_burst_len)
+#define iscsi_def_time2wait(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->def_time2wait)
+#define iscsi_def_time2retain(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->def_time2retain)
+#define iscsi_max_outstanding_r2t(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->max_outstanding_r2t)
+#define iscsi_data_pdu_in_order(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->data_pdu_in_order)
+#define iscsi_data_sequence_in_order(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->data_sequence_in_order)
+#define iscsi_erl(x) \
+	(((struct iscsi_class_session *)&(x)->starget_data)->erl)
+
+/*
+ * The functions by which the transport class and the driver communicate
+ */
+struct iscsi_function_template {
+	/*
+	 * target attrs
+	 */
+	void (*get_isid)(struct scsi_target *);
+	void (*get_tsih)(struct scsi_target *);
+	void (*get_header_digest)(struct scsi_target *);
+	void (*get_data_digest)(struct scsi_target *);
+	void (*get_port)(struct scsi_target *);
+	void (*get_tpgt)(struct scsi_target *);
+	/*
+	 * In get_ip_address the lld must set the address and
+	 * the address type
+	 */
+	void (*get_ip_address)(struct scsi_target *);
+	/*
+	 * The lld should snprintf the name or alias to the buffer
+	 */
+	ssize_t (*get_target_name)(struct scsi_target *, char *, ssize_t);
+	ssize_t (*get_target_alias)(struct scsi_target *, char *, ssize_t);
+	void (*get_initial_r2t)(struct scsi_target *);
+	void (*get_immediate_data)(struct scsi_target *);
+	void (*get_max_recv_data_segment_len)(struct scsi_target *);
+	void (*get_max_burst_len)(struct scsi_target *);
+	void (*get_first_burst_len)(struct scsi_target *);
+	void (*get_def_time2wait)(struct scsi_target *);
+	void (*get_def_time2retain)(struct scsi_target *);
+	void (*get_max_outstanding_r2t)(struct scsi_target *);
+	void (*get_data_pdu_in_order)(struct scsi_target *);
+	void (*get_data_sequence_in_order)(struct scsi_target *);
+	void (*get_erl)(struct scsi_target *);
+
+	/*
+	 * host atts
+	 */
+
+	/*
+	 * The lld should snprintf the name or alias to the buffer
+	 */
+	ssize_t (*get_initiator_alias)(struct Scsi_Host *, char *, ssize_t);
+	ssize_t (*get_initiator_name)(struct Scsi_Host *, char *, ssize_t);
+	/*
+	 * The driver sets these to tell the transport class it
+	 * wants the attributes displayed in sysfs.  If the show_ flag
+	 * is not set, the attribute will be private to the transport
+	 * class. We could probably just test if a get_ fn was set
+	 * since we only use the values for sysfs but this is how
+	 * fc does it too.
+	 */
+	unsigned long show_isid:1;
+	unsigned long show_tsih:1;
+	unsigned long show_header_digest:1;
+	unsigned long show_data_digest:1;
+	unsigned long show_port:1;
+	unsigned long show_tpgt:1;
+	unsigned long show_ip_address:1;
+	unsigned long show_target_name:1;
+	unsigned long show_target_alias:1;
+	unsigned long show_initial_r2t:1;
+	unsigned long show_immediate_data:1;
+	unsigned long show_max_recv_data_segment_len:1;
+	unsigned long show_max_burst_len:1;
+	unsigned long show_first_burst_len:1;
+	unsigned long show_def_time2wait:1;
+	unsigned long show_def_time2retain:1;
+	unsigned long show_max_outstanding_r2t:1;
+	unsigned long show_data_pdu_in_order:1;
+	unsigned long show_data_sequence_in_order:1;
+	unsigned long show_erl:1;
+	unsigned long show_initiator_name:1;
+	unsigned long show_initiator_alias:1;
+};
+
+struct scsi_transport_template *iscsi_attach_transport(struct iscsi_function_template *);
+void iscsi_release_transport(struct scsi_transport_template *);
+
+#endif
