Merge HEAD from ../scsi-misc-2.6-tmp
authorJames Bottomley <jejb@titanic.(none)>
Sun, 28 Aug 2005 16:18:35 +0000 (11:18 -0500)
committerJames Bottomley <jejb@titanic.(none)>
Sun, 28 Aug 2005 16:18:35 +0000 (11:18 -0500)
1  2 
MAINTAINERS
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/linit.c
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/sg.c
drivers/scsi/st.c

diff --combined MAINTAINERS
index 564a03e61a0c4b2322136ab9d96b3f121391ee83,562441d67b82656284ba612e5493311db89a36b5..fb0da63621cd0f087bad4ed4cdf27f775291204f
@@@ -784,7 -784,7 +784,7 @@@ DVB SUBSYSTEM AND DRIVER
  P:    LinuxTV.org Project
  M:    linux-dvb-maintainer@linuxtv.org
  L:    linux-dvb@linuxtv.org (subscription required)
 -W:    http://linuxtv.org/developer/dvb.xml
 +W:    http://linuxtv.org/
  S:    Supported
  
  EATA-DMA SCSI DRIVER
@@@ -824,6 -824,13 +824,13 @@@ L:       emu10k1-devel@lists.sourceforge.ne
  W:    http://sourceforge.net/projects/emu10k1/
  S:    Maintained
  
+ EMULEX LPFC FC SCSI DRIVER
+ P:      James Smart
+ M:      james.smart@emulex.com
+ L:      linux-scsi@vger.kernel.org
+ W:      http://sourceforge.net/projects/lpfcxxxx
+ S:      Supported
  EPSON 1355 FRAMEBUFFER DRIVER
  P:    Christopher Hoover
  M:    ch@murgatroid.com, ch@hpl.hp.com
@@@ -1521,12 -1528,6 +1528,12 @@@ P:    Zach Brow
  M:    zab@zabbo.net
  S:    Odd Fixes
  
 +MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
 +P: Michael Kerrisk
 +M: mtk-manpages@gmx.net
 +W: ftp://ftp.kernel.org/pub/linux/docs/manpages
 +S: Maintained
 +
  MARVELL MV64340 ETHERNET DRIVER
  P:    Manish Lachwani
  M:    Manish_Lachwani@pmc-sierra.com
@@@ -1658,7 -1659,7 +1665,7 @@@ M:      kuznet@ms2.inr.ac.r
  P:    Pekka Savola (ipv6)
  M:    pekkas@netcore.fi
  P:    James Morris
 -M:    jmorris@redhat.com
 +M:    jmorris@namei.org
  P:    Hideaki YOSHIFUJI
  M:    yoshfuji@linux-ipv6.org
  P:    Patrick McHardy
@@@ -1739,7 -1740,7 +1746,7 @@@ S:      Maintaine
  
  OPL3-SA2, SA3, and SAx DRIVER
  P:    Zwane Mwaikambo
 -M:    zwane@commfireservices.com
 +M:    zwane@arm.linux.org.uk
  L:    linux-sound@vger.kernel.org
  S:    Maintained
  
@@@ -1825,12 -1826,6 +1832,12 @@@ P:    Greg Kroah-Hartma
  M:    greg@kroah.com
  S:    Maintained
  
 +PCIE HOTPLUG DRIVER
 +P:    Kristen Carlson Accardi
 +M:    kristen.c.accardi@intel.com
 +L:    pcihpd-discuss@lists.sourceforge.net
 +S:    Maintained
 +
  PCMCIA SUBSYSTEM
  P:    Linux PCMCIA Team
  L:    http://lists.infradead.org/mailman/listinfo/linux-pcmcia
@@@ -1995,7 -1990,7 +2002,7 @@@ S:      Maintaine
  
  SC1200 WDT DRIVER
  P:    Zwane Mwaikambo
 -M:    zwane@commfireservices.com
 +M:    zwane@arm.linux.org.uk
  S:    Maintained
  
  SCHEDULER
@@@ -2053,7 -2048,7 +2060,7 @@@ SELINUX SECURITY MODUL
  P:    Stephen Smalley
  M:    sds@epoch.ncsc.mil
  P:    James Morris
 -M:    jmorris@redhat.com
 +M:    jmorris@namei.org
  L:    linux-kernel@vger.kernel.org (kernel issues)
  L:    selinux@tycho.nsa.gov (general discussion)
  W:    http://www.nsa.gov/selinux
@@@ -2207,12 -2202,6 +2214,12 @@@ W:    http://projects.buici.com/ar
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  S:    Maintained
  
 +SHPC HOTPLUG DRIVER
 +P:    Kristen Carlson Accardi
 +M:    kristen.c.accardi@intel.com
 +L:    pcihpd-discuss@lists.sourceforge.net
 +S:    Maintained
 +
  SPARC (sparc32):
  P:    William L. Irwin
  M:    wli@holomorphy.com
index 4ab07861b457fd80c1af736cb17dd633119228e6,bc91e7ce5e595f8d42e9908c774daea3c01a123e..e40528185d48fab70a6d5011ed1a4f6773073cef
  #define AAC_MAX_LUN           (8)
  
  #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
 -/*
 - *  max_sectors is an unsigned short, otherwise limit is 0x100000000 / 512
 - * Linux has starvation problems if we permit larger than 4MB I/O ...
 - */
 -#define AAC_MAX_32BIT_SGBCOUNT        ((unsigned short)8192)
 +#define AAC_MAX_32BIT_SGBCOUNT        ((unsigned short)512)
  
  /*
   * These macros convert from physical channels to virtual channels
@@@ -110,6 -114,22 +110,22 @@@ struct user_sgentry64 
        u32     count;  /* Length. */
  };
  
+ struct sgentryraw {
+       __le32          next;   /* reserved for F/W use */
+       __le32          prev;   /* reserved for F/W use */
+       __le32          addr[2];
+       __le32          count;
+       __le32          flags;  /* reserved for F/W use */
+ };
+ struct user_sgentryraw {
+       u32             next;   /* reserved for F/W use */
+       u32             prev;   /* reserved for F/W use */
+       u32             addr[2];
+       u32             count;
+       u32             flags;  /* reserved for F/W use */
+ };
  /*
   *    SGMAP
   *
@@@ -137,6 -157,16 +153,16 @@@ struct user_sgmap64 
        struct user_sgentry64 sg[1];
  };
  
+ struct sgmapraw {
+       __le32            count;
+       struct sgentryraw sg[1];
+ };
+ struct user_sgmapraw {
+       u32               count;
+       struct user_sgentryraw sg[1];
+ };
  struct creation_info
  {
        u8              buildnum;               /* e.g., 588 */
@@@ -351,6 -381,7 +377,7 @@@ struct hw_fib 
   */
  #define               ContainerCommand                500
  #define               ContainerCommand64              501
+ #define               ContainerRawIo                  502
  /*
   *    Cluster Commands
   */
@@@ -456,6 -487,7 +483,7 @@@ struct adapter_op
  {
        void (*adapter_interrupt)(struct aac_dev *dev);
        void (*adapter_notify)(struct aac_dev *dev, u32 event);
+       void (*adapter_disable_int)(struct aac_dev *dev);
        int  (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
        int  (*adapter_check_health)(struct aac_dev *dev);
  };
@@@ -981,6 -1013,9 +1009,9 @@@ struct aac_de
        u8                      nondasd_support; 
        u8                      dac_support;
        u8                      raid_scsi_mode;
+       /* macro side-effects BEWARE */
+ #     define                  raw_io_interface \
+         init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
        u8                      printf_enabled;
  };
  
  #define aac_adapter_notify(dev, event) \
        (dev)->a_ops.adapter_notify(dev, event)
  
+ #define aac_adapter_disable_int(dev) \
+       (dev)->a_ops.adapter_disable_int(dev)
  #define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
        (dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)
  
@@@ -1156,6 -1194,17 +1190,17 @@@ struct aac_write_repl
        __le32          committed;
  };
  
+ struct aac_raw_io
+ {
+       __le32          block[2];
+       __le32          count;
+       __le16          cid;
+       __le16          flags;          /* 00 W, 01 R */
+       __le16          bpTotal;        /* reserved for F/W use */
+       __le16          bpComplete;     /* reserved for F/W use */
+       struct sgmapraw sg;
+ };
  #define CT_FLUSH_CACHE 129
  struct aac_synchronize {
        __le32          command;        /* VM_ContainerConfig */
@@@ -1196,7 -1245,7 +1241,7 @@@ struct aac_sr
  };
  
  /*
-  * This and assocated data structs are used by the 
+  * This and associated data structs are used by the
   * ioctl caller and are in cpu order.
   */
  struct user_aac_srb
@@@ -1508,11 -1557,12 +1553,12 @@@ struct fib_ioct
  
  struct revision
  {
-       u32 compat;
-       u32 version;
-       u32 build;
+       __le32 compat;
+       __le32 version;
+       __le32 build;
  };
        
  /*
   *    Ugly - non Linux like ioctl coding for back compat.
   */
@@@ -1733,3 -1783,4 +1779,4 @@@ int aac_get_adapter_info(struct aac_dev
  int aac_send_shutdown(struct aac_dev *dev);
  extern int numacb;
  extern int acbsize;
+ extern char aac_driver_version[];
index 562da90480a1426346ceba19efe54108e4043826,2bd5942678814b276f8331aad0fb077412edab0f..4ff29d7f58252cb6b5fabb309aa84ad25eea64be
   * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
   */
  
- #define AAC_DRIVER_VERSION            "1.1.2-lk2"
- #define AAC_DRIVER_BUILD_DATE         __DATE__
+ #define AAC_DRIVER_VERSION            "1.1-4"
+ #ifndef AAC_DRIVER_BRANCH
+ #define AAC_DRIVER_BRANCH             ""
+ #endif
+ #define AAC_DRIVER_BUILD_DATE         __DATE__ " " __TIME__
  #define AAC_DRIVERNAME                        "aacraid"
  
  #include <linux/compat.h>
  
  #include "aacraid.h"
  
+ #ifdef AAC_DRIVER_BUILD
+ #define _str(x) #x
+ #define str(x) _str(x)
+ #define AAC_DRIVER_FULL_VERSION       AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
+ #else
+ #define AAC_DRIVER_FULL_VERSION       AAC_DRIVER_VERSION AAC_DRIVER_BRANCH " " AAC_DRIVER_BUILD_DATE
+ #endif
  
  MODULE_AUTHOR("Red Hat Inc and Adaptec");
  MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, "
                   "Adaptec Advanced Raid Products, "
                   "and HP NetRAID-4M SCSI driver");
  MODULE_LICENSE("GPL");
- MODULE_VERSION(AAC_DRIVER_VERSION);
+ MODULE_VERSION(AAC_DRIVER_FULL_VERSION);
  
  static LIST_HEAD(aac_devices);
  static int aac_cfg_major = -1;
+ char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
  
  /*
   * Because of the way Linux names scsi devices, the order in this table has
@@@ -109,36 -120,39 +120,39 @@@ static struct pci_device_id aac_pci_tbl
        { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */
        { 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */
        { 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */
-       { 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 32 }, /* Themisto Jupiter Platform */
-       { 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 32 }, /* Themisto Jupiter Platform */
-       { 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 33 }, /* Callisto Jupiter Platform */
-       { 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 34 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
-       { 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 35 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
-       { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 36 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
-       { 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 37 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
-       { 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 38 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
-       { 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 39 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
-       { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 40 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
-       { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 41 }, /* AAR-2610SA PCI SATA 6ch */
-       { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 42 }, /* ASR-2240S (SabreExpress) */
-       { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 43 }, /* ASR-4005SAS */
-       { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 44 }, /* IBM 8i (AvonPark) */
-       { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 44 }, /* IBM 8i (AvonPark Lite) */
-       { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 45 }, /* ASR-4000SAS (BlackBird) */
-       { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 46 }, /* ASR-4800SAS (Marauder-X) */
-       { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 47 }, /* ASR-4805SAS (Marauder-E) */
-       { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 48 }, /* ASR-4810SAS (Hurricane */
-       { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 49 }, /* Perc 320/DC*/
-       { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 50 }, /* Adaptec 5400S (Mustang)*/
-       { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 51 }, /* Adaptec 5400S (Mustang)*/
-       { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 52 }, /* Dell PERC2/QC */
-       { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 53 }, /* HP NetRAID-4M */
-       { 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 54 }, /* Dell Catchall */
-       { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 55 }, /* Legend Catchall */
-       { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 56 }, /* Adaptec Catch All */
-       { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 57 }, /* Adaptec Rocket Catch All */
+       { 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 }, /* ICP9067MA (Intruder-6) */
+       { 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 33 }, /* Themisto Jupiter Platform */
+       { 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 33 }, /* Themisto Jupiter Platform */
+       { 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 34 }, /* Callisto Jupiter Platform */
+       { 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 35 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
+       { 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 36 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
+       { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 37 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
+       { 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 38 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
+       { 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 39 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
+       { 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 40 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
+       { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 41 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
+       { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 42 }, /* AAR-2610SA PCI SATA 6ch */
+       { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 43 }, /* ASR-2240S (SabreExpress) */
+       { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005SAS */
+       { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 45 }, /* IBM 8i (AvonPark) */
+       { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 45 }, /* IBM 8i (AvonPark Lite) */
+       { 0x9005, 0x0286, 0x1014, 0x9580, 0, 0, 46 }, /* IBM 8k/8k-l8 (Aurora) */
+       { 0x9005, 0x0286, 0x1014, 0x9540, 0, 0, 47 }, /* IBM 8k/8k-l4 (Aurora Lite) */
+       { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */
+       { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */
+       { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */
+       { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-4810SAS (Hurricane */
+       { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/
+       { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/
+       { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 54 }, /* Adaptec 5400S (Mustang)*/
+       { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 55 }, /* Dell PERC2/QC */
+       { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 56 }, /* HP NetRAID-4M */
+       { 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 57 }, /* Dell Catchall */
+       { 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */
+       { 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */
+       { 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */
        { 0,}
  };
  MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
@@@ -180,8 -194,9 +194,9 @@@ static struct aac_driver_ident aac_driv
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP9047MA       ", 1 }, /* ICP9047MA (Lancer) */
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP9087MA       ", 1 }, /* ICP9087MA (Lancer) */
        { aac_rkt_init, "aacraid",  "ICP     ", "ICP5085AU       ", 1 }, /* ICP5085AU (Hurricane) */
-       { aac_rkt_init, "aacraid",  "ICP     ", "ICP9085LI       ", 1 }, /* ICP9085LI (Marauder-X) */
-       { aac_rkt_init, "aacraid",  "ICP     ", "ICP5085BR       ", 1 }, /* ICP5085BR (Marauder-E) */
+       { aac_rx_init, "aacraid",  "ICP     ", "ICP9085LI       ", 1 }, /* ICP9085LI (Marauder-X) */
+       { aac_rx_init, "aacraid",  "ICP     ", "ICP5085BR       ", 1 }, /* ICP5085BR (Marauder-E) */
+       { aac_rkt_init, "aacraid",  "ICP     ", "ICP9067MA       ", 1 }, /* ICP9067MA (Intruder-6) */
        { NULL        , "aacraid",  "ADAPTEC ", "Themisto        ", 0, AAC_QUIRK_SLAVE }, /* Jupiter Platform */
        { aac_rkt_init, "aacraid",  "ADAPTEC ", "Callisto        ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2020SA       ", 1 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2240S       ", 1 }, /* ASR-2240S (SabreExpress) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4005SAS     ", 1 }, /* ASR-4005SAS */
        { aac_rx_init, "ServeRAID","IBM     ", "ServeRAID 8i    ", 1 }, /* IBM 8i (AvonPark) */
+       { aac_rkt_init, "ServeRAID","IBM     ", "ServeRAID 8k-l8 ", 1 }, /* IBM 8k/8k-l8 (Aurora) */
+       { aac_rkt_init, "ServeRAID","IBM     ", "ServeRAID 8k-l4 ", 1 }, /* IBM 8k/8k-l4 (Aurora Lite) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4000SAS     ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4800SAS     ", 1 }, /* ASR-4800SAS (Marauder-X) */
        { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4805SAS     ", 1 }, /* ASR-4805SAS (Marauder-E) */
-       { aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4810SAS     ", 1 }, /* ASR-4810SAS (Hurricane) */
+       { aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-4810SAS     ", 1 }, /* ASR-4810SAS (Hurricane) */
  
        { aac_rx_init, "percraid", "DELL    ", "PERC 320/DC     ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
        { aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
@@@ -374,8 -391,7 +391,8 @@@ static int aac_slave_configure(struct s
        else
                scsi_adjust_queue_depth(sdev, 0, 1);
  
 -      if (host->max_sectors < AAC_MAX_32BIT_SGBCOUNT)
 +      if (!(((struct aac_dev *)host->hostdata)->adapter_info.options
 +        & AAC_OPT_NEW_COMM))
                blk_queue_max_segment_size(sdev->request_queue, 65536);
  
        return 0;
@@@ -839,11 -855,12 +856,12 @@@ static int __devinit aac_probe_one(stru
  
        return 0;
  
- out_deinit:
 out_deinit:
        kill_proc(aac->thread_pid, SIGKILL, 0);
        wait_for_completion(&aac->aif_completion);
  
        aac_send_shutdown(aac);
+       aac_adapter_disable_int(aac);
        fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
        kfree(aac->queues);
        return error;
  }
  
+ static void aac_shutdown(struct pci_dev *dev)
+ {
+       struct Scsi_Host *shost = pci_get_drvdata(dev);
+       struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
+       aac_send_shutdown(aac);
+ }
  static void __devexit aac_remove_one(struct pci_dev *pdev)
  {
        struct Scsi_Host *shost = pci_get_drvdata(pdev);
        wait_for_completion(&aac->aif_completion);
  
        aac_send_shutdown(aac);
+       aac_adapter_disable_int(aac);
        fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,
                        aac->comm_phys);
@@@ -891,14 -916,15 +917,15 @@@ static struct pci_driver aac_pci_drive
        .id_table       = aac_pci_tbl,
        .probe          = aac_probe_one,
        .remove         = __devexit_p(aac_remove_one),
+       .shutdown       = aac_shutdown,
  };
  
  static int __init aac_init(void)
  {
        int error;
        
-       printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n",
-                       AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE);
+       printk(KERN_INFO "Adaptec %s driver (%s)\n",
+         AAC_DRIVERNAME, aac_driver_version);
  
        error = pci_module_init(&aac_pci_driver);
        if (error)
                printk(KERN_WARNING
                       "aacraid: unable to register \"aac\" device.\n");
        }
        return 0;
  }
  
index 687f19e9cf03a179d6671163509176c3350fdc1f,22434849de4812469180f6e0699bfa7e517b1665..54173887e1605af55efa56fe7da334e85291bb89
@@@ -635,6 -635,8 +635,8 @@@ ahc_linux_slave_alloc(struct scsi_devic
        
        targ->sdev[sdev->lun] = sdev;
  
+       spi_period(starget) = 0;
        return 0;
  }
  
@@@ -1264,12 -1266,14 +1266,12 @@@ ahc_platform_set_tags(struct ahc_softc 
        }
        switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
        case AHC_DEV_Q_BASIC:
 -              scsi_adjust_queue_depth(sdev,
 -                                      MSG_SIMPLE_TASK,
 -                                      dev->openings + dev->active);
 +              scsi_set_tag_type(sdev, MSG_SIMPLE_TAG);
 +              scsi_activate_tcq(sdev, dev->openings + dev->active);
                break;
        case AHC_DEV_Q_TAGGED:
 -              scsi_adjust_queue_depth(sdev,
 -                                      MSG_ORDERED_TASK,
 -                                      dev->openings + dev->active);
 +              scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
 +              scsi_activate_tcq(sdev, dev->openings + dev->active);
                break;
        default:
                /*
                 * serially on the controller/device.  This should
                 * remove some latency.
                 */
 -              scsi_adjust_queue_depth(sdev,
 -                                      /*NON-TAGGED*/0,
 -                                      /*queue depth*/2);
 +              scsi_deactivate_tcq(sdev, 2);
                break;
        }
  }
@@@ -1612,9 -1618,9 +1614,9 @@@ ahc_send_async(struct ahc_softc *ahc, c
                if (channel == 'B')
                        target_offset += 8;
                starget = ahc->platform_data->starget[target_offset];
-               targ = scsi_transport_target_data(starget);
-               if (targ == NULL)
+               if (starget == NULL)
                        break;
+               targ = scsi_transport_target_data(starget);
  
                target_ppr_options =
                        (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
                spi_period(starget) = tinfo->curr.period;
                spi_width(starget) = tinfo->curr.width;
                spi_offset(starget) = tinfo->curr.offset;
 -              spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
 -              spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ;
 -              spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ;
 +              spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
 +              spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
 +              spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
                spi_display_xfer_agreement(starget);
                break;
        }
@@@ -2329,8 -2335,6 +2331,6 @@@ ahc_platform_dump_card_state(struct ahc
  {
  }
  
- static void ahc_linux_exit(void);
  static void ahc_linux_set_width(struct scsi_target *starget, int width)
  {
        struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@@ -2425,14 -2429,12 +2425,14 @@@ static void ahc_linux_set_dt(struct scs
        unsigned int ppr_options = tinfo->goal.ppr_options
                & ~MSG_EXT_PPR_DT_REQ;
        unsigned int period = tinfo->goal.period;
 +      unsigned int width = tinfo->goal.width;
        unsigned long flags;
        struct ahc_syncrate *syncrate;
  
        if (dt) {
 -              period = 9;     /* 12.5ns is the only period valid for DT */
                ppr_options |= MSG_EXT_PPR_DT_REQ;
 +              if (!width)
 +                      ahc_linux_set_width(starget, 1);
        } else if (period == 9)
                period = 10;    /* if resetting DT, period must be >= 25ns */
  
diff --combined drivers/scsi/scsi_lib.c
index b8212c563fed96ed07594283ff1f45fad14e4784,060010bccabc387d0047da8f64be6a9d79d70498..278e0c99b2aecf287430df8f0c1ca7da13f32c1f
@@@ -232,6 -232,23 +232,6 @@@ void scsi_do_req(struct scsi_request *s
  }
  EXPORT_SYMBOL(scsi_do_req);
  
 -static void scsi_wait_done(struct scsi_cmnd *cmd)
 -{
 -      struct request *req = cmd->request;
 -      struct request_queue *q = cmd->device->request_queue;
 -      unsigned long flags;
 -
 -      req->rq_status = RQ_SCSI_DONE;  /* Busy, but indicate request done */
 -
 -      spin_lock_irqsave(q->queue_lock, flags);
 -      if (blk_rq_tagged(req))
 -              blk_queue_end_tag(q, req);
 -      spin_unlock_irqrestore(q->queue_lock, flags);
 -
 -      if (req->waiting)
 -              complete(req->waiting);
 -}
 -
  /* This is the end routine we get to if a command was never attached
   * to the request.  Simply complete the request without changing
   * rq_status; this will cause a DRIVER_ERROR. */
@@@ -246,90 -263,21 +246,90 @@@ void scsi_wait_req(struct scsi_request 
                   unsigned bufflen, int timeout, int retries)
  {
        DECLARE_COMPLETION(wait);
 -      
 -      sreq->sr_request->waiting = &wait;
 -      sreq->sr_request->rq_status = RQ_SCSI_BUSY;
 -      sreq->sr_request->end_io = scsi_wait_req_end_io;
 -      scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done,
 -                      timeout, retries);
 +      int write = (sreq->sr_data_direction == DMA_TO_DEVICE);
 +      struct request *req;
 +
 +      req = blk_get_request(sreq->sr_device->request_queue, write,
 +                            __GFP_WAIT);
 +      if (bufflen && blk_rq_map_kern(sreq->sr_device->request_queue, req,
 +                                     buffer, bufflen, __GFP_WAIT)) {
 +              sreq->sr_result = DRIVER_ERROR << 24;
 +              blk_put_request(req);
 +              return;
 +      }
 +
 +      req->flags |= REQ_NOMERGE;
 +      req->waiting = &wait;
 +      req->end_io = scsi_wait_req_end_io;
 +      req->cmd_len = COMMAND_SIZE(((u8 *)cmnd)[0]);
 +      req->sense = sreq->sr_sense_buffer;
 +      req->sense_len = 0;
 +      memcpy(req->cmd, cmnd, req->cmd_len);
 +      req->timeout = timeout;
 +      req->flags |= REQ_BLOCK_PC;
 +      req->rq_disk = NULL;
 +      blk_insert_request(sreq->sr_device->request_queue, req,
 +                         sreq->sr_data_direction == DMA_TO_DEVICE, NULL);
        wait_for_completion(&wait);
        sreq->sr_request->waiting = NULL;
 -      if (sreq->sr_request->rq_status != RQ_SCSI_DONE)
 +      sreq->sr_result = req->errors;
 +      if (req->errors)
                sreq->sr_result |= (DRIVER_ERROR << 24);
  
 -      __scsi_release_request(sreq);
 +      blk_put_request(req);
  }
 +
  EXPORT_SYMBOL(scsi_wait_req);
  
 +/**
 + * scsi_execute_req - insert request and wait for the result
 + * @sdev:     scsi device
 + * @cmd:      scsi command
 + * @data_direction: data direction
 + * @buffer:   data buffer
 + * @bufflen:  len of buffer
 + * @sense:    optional sense buffer
 + * @timeout:  request timeout in seconds
 + * @retries:  number of times to retry request
 + *
 + * scsi_execute_req returns the req->errors value which is the
 + * the scsi_cmnd result field.
 + **/
 +int scsi_execute_req(struct scsi_device *sdev, unsigned char *cmd,
 +                   int data_direction, void *buffer, unsigned bufflen,
 +                   unsigned char *sense, int timeout, int retries)
 +{
 +      struct request *req;
 +      int write = (data_direction == DMA_TO_DEVICE);
 +      int ret = DRIVER_ERROR << 24;
 +
 +      req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
 +
 +      if (bufflen &&  blk_rq_map_kern(sdev->request_queue, req,
 +                                      buffer, bufflen, __GFP_WAIT))
 +              goto out;
 +
 +      req->cmd_len = COMMAND_SIZE(cmd[0]);
 +      memcpy(req->cmd, cmd, req->cmd_len);
 +      req->sense = sense;
 +      req->sense_len = 0;
 +      req->timeout = timeout;
 +      req->flags |= REQ_BLOCK_PC | REQ_SPECIAL;
 +
 +      /*
 +       * head injection *required* here otherwise quiesce won't work
 +       */
 +      blk_execute_rq(req->q, NULL, req, 1);
 +
 +      ret = req->errors;
 + out:
 +      blk_put_request(req);
 +
 +      return ret;
 +}
 +
 +EXPORT_SYMBOL(scsi_execute_req);
 +
  /*
   * Function:    scsi_init_cmd_errh()
   *
@@@ -400,7 -348,7 +400,7 @@@ void scsi_device_unbusy(struct scsi_dev
  
        spin_lock_irqsave(shost->host_lock, flags);
        shost->host_busy--;
-       if (unlikely(test_bit(SHOST_RECOVERY, &shost->shost_state) &&
+       if (unlikely((shost->shost_state == SHOST_RECOVERY) &&
                     shost->host_failed))
                scsi_eh_wakeup(shost);
        spin_unlock(shost->host_lock);
@@@ -930,12 -878,11 +930,12 @@@ void scsi_io_completion(struct scsi_cmn
                return;
        }
        if (result) {
 -              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);
 +              if (!(req->flags & REQ_SPECIAL))
 +                      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);
  
                if (driver_byte(result) & DRIVER_SENSE)
                        scsi_print_sense("", cmd);
@@@ -1073,12 -1020,6 +1073,12 @@@ static int scsi_issue_flush_fn(request_
        return -EOPNOTSUPP;
  }
  
 +static void scsi_generic_done(struct scsi_cmnd *cmd)
 +{
 +      BUG_ON(!blk_pc_request(cmd->request));
 +      scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0);
 +}
 +
  static int scsi_prep_fn(struct request_queue *q, struct request *req)
  {
        struct scsi_device *sdev = q->queuedata;
         * these two cases differently.  We differentiate by looking
         * at request->cmd, as this tells us the real story.
         */
 -      if (req->flags & REQ_SPECIAL) {
 +      if (req->flags & REQ_SPECIAL && req->special) {
                struct scsi_request *sreq = req->special;
  
                if (sreq->sr_magic == SCSI_REQ_MAGIC) {
                        cmd = req->special;
        } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
  
 -              if(unlikely(specials_only)) {
 +              if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) {
                        if(specials_only == SDEV_QUIESCE ||
                                        specials_only == SDEV_BLOCK)
                                return BLKPREP_DEFER;
                /*
                 * Initialize the actual SCSI command for this request.
                 */
 -              drv = *(struct scsi_driver **)req->rq_disk->private_data;
 -              if (unlikely(!drv->init_command(cmd))) {
 -                      scsi_release_buffers(cmd);
 -                      scsi_put_command(cmd);
 -                      return BLKPREP_KILL;
 +              if (req->rq_disk) {
 +                      drv = *(struct scsi_driver **)req->rq_disk->private_data;
 +                      if (unlikely(!drv->init_command(cmd))) {
 +                              scsi_release_buffers(cmd);
 +                              scsi_put_command(cmd);
 +                              return BLKPREP_KILL;
 +                      }
 +              } else {
 +                      memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
 +                      if (rq_data_dir(req) == WRITE)
 +                              cmd->sc_data_direction = DMA_TO_DEVICE;
 +                      else if (req->data_len)
 +                              cmd->sc_data_direction = DMA_FROM_DEVICE;
 +                      else
 +                              cmd->sc_data_direction = DMA_NONE;
 +                      
 +                      cmd->transfersize = req->data_len;
 +                      cmd->allowed = 3;
 +                      cmd->timeout_per_command = req->timeout;
 +                      cmd->done = scsi_generic_done;
                }
        }
  
@@@ -1281,7 -1207,7 +1281,7 @@@ static inline int scsi_host_queue_ready
                                   struct Scsi_Host *shost,
                                   struct scsi_device *sdev)
  {
-       if (test_bit(SHOST_RECOVERY, &shost->shost_state))
+       if (shost->shost_state == SHOST_RECOVERY)
                return 0;
        if (shost->host_busy == 0 && shost->host_blocked) {
                /*
diff --combined drivers/scsi/scsi_scan.c
index d2ca4b8fbc13fef37ca55d9ede16fe3af902361f,076cbe3b5a05c994d3e196163b6e39a1a0091bba..0048beaffc9f097c5adfaec1c18801bf4ecea23f
@@@ -111,14 -111,15 +111,14 @@@ MODULE_PARM_DESC(inq_timeout
  
  /**
   * scsi_unlock_floptical - unlock device via a special MODE SENSE command
 - * @sreq:     used to send the command
 + * @sdev:     scsi device to send command to
   * @result:   area to store the result of the MODE SENSE
   *
   * Description:
 - *     Send a vendor specific MODE SENSE (not a MODE SELECT) command using
 - *     @sreq to unlock a device, storing the (unused) results into result.
 + *     Send a vendor specific MODE SENSE (not a MODE SELECT) command.
   *     Called for BLIST_KEY devices.
   **/
 -static void scsi_unlock_floptical(struct scsi_request *sreq,
 +static void scsi_unlock_floptical(struct scsi_device *sdev,
                                  unsigned char *result)
  {
        unsigned char scsi_cmd[MAX_COMMAND_SIZE];
        scsi_cmd[1] = 0;
        scsi_cmd[2] = 0x2e;
        scsi_cmd[3] = 0;
 -      scsi_cmd[4] = 0x2a;     /* size */
 +      scsi_cmd[4] = 0x2a;     /* size */
        scsi_cmd[5] = 0;
 -      sreq->sr_cmd_len = 0;
 -      sreq->sr_data_direction = DMA_FROM_DEVICE;
 -      scsi_wait_req(sreq, scsi_cmd, result, 0x2a /* size */, SCSI_TIMEOUT, 3);
 +      scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result, 0x2a, NULL,
 +                       SCSI_TIMEOUT, 3);
  }
  
  /**
@@@ -334,23 -336,9 +334,23 @@@ static struct scsi_target *scsi_alloc_t
        unsigned long flags;
        const int size = sizeof(struct scsi_target)
                + shost->transportt->target_size;
 -      struct scsi_target *starget = kmalloc(size, GFP_ATOMIC);
 +      struct scsi_target *starget;
        struct scsi_target *found_target;
  
 +      /*
 +       * Obtain the real parent from the transport. The transport
 +       * is allowed to fail (no error) if there is nothing at that
 +       * target id.
 +       */
 +      if (shost->transportt->target_parent) {
 +              spin_lock_irqsave(shost->host_lock, flags);
 +              parent = shost->transportt->target_parent(shost, channel, id);
 +              spin_unlock_irqrestore(shost->host_lock, flags);
 +              if (!parent)
 +                      return NULL;
 +      }
 +
 +      starget = kmalloc(size, GFP_KERNEL);
        if (!starget) {
                printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
                return NULL;
@@@ -431,26 -419,26 +431,26 @@@ void scsi_target_reap(struct scsi_targe
  
  /**
   * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
 - * @sreq:     used to send the INQUIRY
 + * @sdev:     scsi_device to probe
   * @inq_result:       area to store the INQUIRY result
 + * @result_len: len of inq_result
   * @bflags:   store any bflags found here
   *
   * Description:
 - *     Probe the lun associated with @sreq using a standard SCSI INQUIRY;
 + *     Probe the lun associated with @req using a standard SCSI INQUIRY;
   *
 - *     If the INQUIRY is successful, sreq->sr_result is zero and: the
 + *     If the INQUIRY is successful, zero is returned and the
   *     INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
 - *     are copied to the Scsi_Device at @sreq->sr_device (sdev);
 - *     any flags value is stored in *@bflags.
 + *     are copied to the Scsi_Device any flags value is stored in *@bflags.
   **/
 -static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
 -                         int *bflags)
 +static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
 +                        int result_len, int *bflags)
  {
 -      struct scsi_device *sdev = sreq->sr_device;     /* a bit ugly */
 +      char sense[SCSI_SENSE_BUFFERSIZE];
        unsigned char scsi_cmd[MAX_COMMAND_SIZE];
        int first_inquiry_len, try_inquiry_len, next_inquiry_len;
        int response_len = 0;
 -      int pass, count;
 +      int pass, count, result;
        struct scsi_sense_hdr sshdr;
  
        *bflags = 0;
                memset(scsi_cmd, 0, 6);
                scsi_cmd[0] = INQUIRY;
                scsi_cmd[4] = (unsigned char) try_inquiry_len;
 -              sreq->sr_cmd_len = 0;
 -              sreq->sr_data_direction = DMA_FROM_DEVICE;
  
 +              memset(sense, 0, sizeof(sense));
                memset(inq_result, 0, try_inquiry_len);
 -              scsi_wait_req(sreq, (void *) scsi_cmd, (void *) inq_result,
 -                              try_inquiry_len,
 -                              HZ/2 + HZ*scsi_inq_timeout, 3);
 +
 +              result = scsi_execute_req(sdev,  scsi_cmd, DMA_FROM_DEVICE,
 +                                        inq_result, try_inquiry_len, sense,
 +                                        HZ / 2 + HZ * scsi_inq_timeout, 3);
  
                SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s "
                                "with code 0x%x\n",
 -                              sreq->sr_result ? "failed" : "successful",
 -                              sreq->sr_result));
 +                              result ? "failed" : "successful", result));
  
 -              if (sreq->sr_result) {
 +              if (result) {
                        /*
                         * 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) &&
 -                          scsi_request_normalize_sense(sreq, &sshdr)) {
 +                      if ((driver_byte(result) & DRIVER_SENSE) &&
 +                          scsi_normalize_sense(sense, sizeof(sense),
 +                                               &sshdr)) {
                                if ((sshdr.sense_key == UNIT_ATTENTION) &&
                                    ((sshdr.asc == 0x28) ||
                                     (sshdr.asc == 0x29)) &&
                break;
        }
  
 -      if (sreq->sr_result == 0) {
 +      if (result == 0) {
                response_len = (unsigned char) inq_result[4] + 5;
                if (response_len > 255)
                        response_len = first_inquiry_len;       /* sanity */
  
        /* If the last transfer attempt got an error, assume the
         * peripheral doesn't exist or is dead. */
 -      if (sreq->sr_result)
 -              return;
 +      if (result)
 +              return -EIO;
  
        /* Don't report any more data than the device says is valid */
        sdev->inquiry_len = min(try_inquiry_len, response_len);
            (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
                sdev->scsi_level++;
  
 -      return;
 +      return 0;
  }
  
  /**
@@@ -798,8 -786,9 +798,8 @@@ static int scsi_probe_and_add_lun(struc
                                  void *hostdata)
  {
        struct scsi_device *sdev;
 -      struct scsi_request *sreq;
        unsigned char *result;
 -      int bflags, res = SCSI_SCAN_NO_RESPONSE;
 +      int bflags, res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
        struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  
        /*
        sdev = scsi_alloc_sdev(starget, lun, hostdata);
        if (!sdev)
                goto out;
 -      sreq = scsi_allocate_request(sdev, GFP_ATOMIC);
 -      if (!sreq)
 -              goto out_free_sdev;
 -      result = kmalloc(256, GFP_ATOMIC |
 +
 +      result = kmalloc(result_len, GFP_ATOMIC |
                        ((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
        if (!result)
 -              goto out_free_sreq;
 +              goto out_free_sdev;
  
 -      scsi_probe_lun(sreq, result, &bflags);
 -      if (sreq->sr_result)
 +      if (scsi_probe_lun(sdev, result, result_len, &bflags))
                goto out_free_result;
  
        /*
        if (res == SCSI_SCAN_LUN_PRESENT) {
                if (bflags & BLIST_KEY) {
                        sdev->lockable = 0;
 -                      scsi_unlock_floptical(sreq, result);
 +                      scsi_unlock_floptical(sdev, result);
                }
                if (bflagsp)
                        *bflagsp = bflags;
  
   out_free_result:
        kfree(result);
 - out_free_sreq:
 -      scsi_release_request(sreq);
   out_free_sdev:
        if (res == SCSI_SCAN_LUN_PRESENT) {
                if (sdevp) {
@@@ -1057,14 -1051,13 +1057,14 @@@ static int scsi_report_lun_scan(struct 
                                int rescan)
  {
        char devname[64];
 +      char sense[SCSI_SENSE_BUFFERSIZE];
        unsigned char scsi_cmd[MAX_COMMAND_SIZE];
        unsigned int length;
        unsigned int lun;
        unsigned int num_luns;
        unsigned int retries;
 +      int result;
        struct scsi_lun *lunp, *lun_data;
 -      struct scsi_request *sreq;
        u8 *data;
        struct scsi_sense_hdr sshdr;
        struct scsi_target *starget = scsi_target(sdev);
        if (bflags & BLIST_NOLUN)
                return 0;
  
 -      sreq = scsi_allocate_request(sdev, GFP_ATOMIC);
 -      if (!sreq)
 -              goto out;
 -
        sprintf(devname, "host %d channel %d id %d",
                sdev->host->host_no, sdev->channel, sdev->id);
  
        lun_data = kmalloc(length, GFP_ATOMIC |
                           (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
        if (!lun_data)
 -              goto out_release_request;
 +              goto out;
  
        scsi_cmd[0] = REPORT_LUNS;
  
  
        scsi_cmd[10] = 0;       /* reserved */
        scsi_cmd[11] = 0;       /* control */
 -      sreq->sr_cmd_len = 0;
 -      sreq->sr_data_direction = DMA_FROM_DEVICE;
  
        /*
         * We can get a UNIT ATTENTION, for example a power on/reset, so
                SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending"
                                " REPORT LUNS to %s (try %d)\n", devname,
                                retries));
 -              scsi_wait_req(sreq, scsi_cmd, lun_data, length,
 -                              SCSI_TIMEOUT + 4*HZ, 3);
 +
 +              memset(sense, 0, sizeof(sense));
 +              result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
 +                                        lun_data, length, sense,
 +                                        SCSI_TIMEOUT + 4 * HZ, 3);
 +
                SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
 -                              " %s (try %d) result 0x%x\n", sreq->sr_result
 -                              ?  "failed" : "successful", retries,
 -                              sreq->sr_result));
 -              if (sreq->sr_result == 0)
 +                              " %s (try %d) result 0x%x\n", result
 +                              ?  "failed" : "successful", retries, result));
 +              if (result == 0)
                        break;
 -              else if (scsi_request_normalize_sense(sreq, &sshdr)) {
 +              else if (scsi_normalize_sense(sense, sizeof(sense), &sshdr)) {
                        if (sshdr.sense_key != UNIT_ATTENTION)
                                break;
                }
        }
  
 -      if (sreq->sr_result) {
 +      if (result) {
                /*
                 * The device probably does not support a REPORT LUN command
                 */
                kfree(lun_data);
 -              scsi_release_request(sreq);
                return 1;
        }
 -      scsi_release_request(sreq);
  
        /*
         * Get the length from the first four bytes of lun_data.
        kfree(lun_data);
        return 0;
  
 - out_release_request:
 -      scsi_release_request(sreq);
   out:
        /*
         * We are out of memory, don't try scanning any further.
@@@ -1251,9 -1251,12 +1251,12 @@@ struct scsi_device *__scsi_add_device(s
  
        get_device(&starget->dev);
        down(&shost->scan_mutex);
-       res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
-       if (res != SCSI_SCAN_LUN_PRESENT)
-               sdev = ERR_PTR(-ENODEV);
+       if (scsi_host_scan_allowed(shost)) {
+               res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1,
+                                            hostdata);
+               if (res != SCSI_SCAN_LUN_PRESENT)
+                       sdev = ERR_PTR(-ENODEV);
+       }
        up(&shost->scan_mutex);
        scsi_target_reap(starget);
        put_device(&starget->dev);
@@@ -1403,11 -1406,15 +1406,15 @@@ int scsi_scan_host_selected(struct Scsi
                return -EINVAL;
  
        down(&shost->scan_mutex);
-       if (channel == SCAN_WILD_CARD) 
-               for (channel = 0; channel <= shost->max_channel; channel++)
+       if (scsi_host_scan_allowed(shost)) {
+               if (channel == SCAN_WILD_CARD)
+                       for (channel = 0; channel <= shost->max_channel;
+                            channel++)
+                               scsi_scan_channel(shost, channel, id, lun,
+                                                 rescan);
+               else
                        scsi_scan_channel(shost, channel, id, lun, rescan);
-       else
-               scsi_scan_channel(shost, channel, id, lun, rescan);
+       }
        up(&shost->scan_mutex);
  
        return 0;
index e6412fce423ce8fa5b2ebfd432f79c46f29c8d64,96243c7fe110691b05f5ed906fb53b664d07a676..2cab556b6e82afa886203254b16024783e47f8c5
@@@ -252,7 -252,8 +252,8 @@@ struct fc_internal 
  
  #define to_fc_internal(tmpl)  container_of(tmpl, struct fc_internal, t)
  
- static int fc_target_setup(struct device *dev)
+ static int fc_target_setup(struct transport_container *tc, struct device *dev,
+                          struct class_device *cdev)
  {
        struct scsi_target *starget = to_scsi_target(dev);
        struct fc_rport *rport = starget_to_rport(starget);
@@@ -281,7 -282,8 +282,8 @@@ static DECLARE_TRANSPORT_CLASS(fc_trans
                               NULL,
                               NULL);
  
- static int fc_host_setup(struct device *dev)
+ static int fc_host_setup(struct transport_container *tc, struct device *dev,
+                        struct class_device *cdev)
  {
        struct Scsi_Host *shost = dev_to_shost(dev);
  
@@@ -1022,23 -1024,6 +1024,23 @@@ static int fc_rport_match(struct attrib
        return &i->rport_attr_cont.ac == cont;
  }
  
 +
 +/*
 + * Must be called with shost->host_lock held
 + */
 +static struct device *fc_target_parent(struct Scsi_Host *shost,
 +                                      int channel, uint id)
 +{
 +      struct fc_rport *rport;
 +
 +      list_for_each_entry(rport, &fc_host_rports(shost), peers)
 +              if ((rport->channel == channel) &&
 +                  (rport->scsi_target_id == id))
 +                      return &rport->dev;
 +
 +      return NULL;
 +}
 +
  struct scsi_transport_template *
  fc_attach_transport(struct fc_function_template *ft)
  {
  
        /* Transport uses the shost workq for scsi scanning */
        i->t.create_work_queue = 1;
 +
 +      i->t.target_parent = fc_target_parent;
        
        /*
         * Setup SCSI Target Attributes.
diff --combined drivers/scsi/sg.c
index e822ca0e97cf441ca7ea407266dec3a8aee132f9,14fb179b3842193dceacd206b1b22d23d54a324f..052d55c167d41d04a03dac56b3e5d75bfc064db2
@@@ -1027,8 -1027,7 +1027,7 @@@ sg_ioctl(struct inode *inode, struct fi
                if (sdp->detached)
                        return -ENODEV;
                if (filp->f_flags & O_NONBLOCK) {
-                       if (test_bit(SHOST_RECOVERY,
-                                    &sdp->device->host->shost_state))
+                       if (sdp->device->host->shost_state == SHOST_RECOVERY)
                                return -EBUSY;
                } else if (!scsi_block_when_processing_errors(sdp->device))
                        return -EBUSY;
@@@ -2971,22 -2970,23 +2970,22 @@@ static void * dev_seq_start(struct seq_
  {
        struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL);
  
 +      s->private = it;
        if (! it)
                return NULL;
 +
        if (NULL == sg_dev_arr)
 -              goto err1;
 +              return NULL;
        it->index = *pos;
        it->max = sg_last_dev();
        if (it->index >= it->max)
 -              goto err1;
 +              return NULL;
        return it;
 -err1:
 -      kfree(it);
 -      return NULL;
  }
  
  static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos)
  {
 -      struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
 +      struct sg_proc_deviter * it = s->private;
  
        *pos = ++it->index;
        return (it->index < it->max) ? it : NULL;
  
  static void dev_seq_stop(struct seq_file *s, void *v)
  {
 -      kfree (v);
 +      kfree(s->private);
  }
  
  static int sg_proc_open_dev(struct inode *inode, struct file *file)
diff --combined drivers/scsi/st.c
index 0a7839db57529c700e71dd1699eb45f273d44ccb,47a5698a712a7461459dadbf91ac5e06d2c2780f..9aadf2fcad6a271fb2fecfea1d2a28ed36bb3afc
@@@ -17,7 -17,7 +17,7 @@@
     Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
   */
  
- static char *verstr = "20050501";
+ static char *verstr = "20050802";
  
  #include <linux/module.h>
  
@@@ -219,6 -219,12 +219,12 @@@ static int switch_partition(struct scsi
  
  static int st_int_ioctl(struct scsi_tape *, unsigned int, unsigned long);
  
+ static void scsi_tape_release(struct kref *);
+ #define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
+ static DECLARE_MUTEX(st_ref_sem);
  \f
  #include "osst_detect.h"
  #ifndef SIGS_FROM_OSST
        {"OnStream", "FW-", "", "osst"}
  #endif
  
+ static struct scsi_tape *scsi_tape_get(int dev)
+ {
+       struct scsi_tape *STp = NULL;
+       down(&st_ref_sem);
+       write_lock(&st_dev_arr_lock);
+       if (dev < st_dev_max && scsi_tapes != NULL)
+               STp = scsi_tapes[dev];
+       if (!STp) goto out;
+       kref_get(&STp->kref);
+       if (!STp->device)
+               goto out_put;
+       if (scsi_device_get(STp->device))
+               goto out_put;
+       goto out;
+ out_put:
+       kref_put(&STp->kref, scsi_tape_release);
+       STp = NULL;
+ out:
+       write_unlock(&st_dev_arr_lock);
+       up(&st_ref_sem);
+       return STp;
+ }
+ static void scsi_tape_put(struct scsi_tape *STp)
+ {
+       struct scsi_device *sdev = STp->device;
+       down(&st_ref_sem);
+       kref_put(&STp->kref, scsi_tape_release);
+       scsi_device_put(sdev);
+       up(&st_ref_sem);
+ }
  struct st_reject_data {
        char *vendor;
        char *model;
@@@ -311,7 -357,7 +357,7 @@@ static int st_chk_result(struct scsi_ta
                return 0;
  
        cmdstatp = &STp->buffer->cmdstat;
-       st_analyze_sense(STp->buffer->last_SRpnt, cmdstatp);
+       st_analyze_sense(SRpnt, cmdstatp);
  
        if (cmdstatp->have_sense)
                scode = STp->buffer->cmdstat.sense_hdr.sense_key;
@@@ -399,10 -445,10 +445,10 @@@ static void st_sleep_done(struct scsi_c
  
        (STp->buffer)->cmdstat.midlevel_result = SCpnt->result;
        SCpnt->request->rq_status = RQ_SCSI_DONE;
-       (STp->buffer)->last_SRpnt = SCpnt->sc_request;
        DEB( STp->write_pending = 0; )
  
-       complete(SCpnt->request->waiting);
+       if (SCpnt->request->waiting)
+               complete(SCpnt->request->waiting);
  }
  
  /* Do the scsi command. Waits until command performed if do_wait is true.
@@@ -412,8 -458,20 +458,20 @@@ static struct scsi_request 
  st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
           int bytes, int direction, int timeout, int retries, int do_wait)
  {
+       struct completion *waiting;
        unsigned char *bp;
  
+       /* if async, make sure there's no command outstanding */
+       if (!do_wait && ((STp->buffer)->last_SRpnt)) {
+               printk(KERN_ERR "%s: Async command already active.\n",
+                      tape_name(STp));
+               if (signal_pending(current))
+                       (STp->buffer)->syscall_result = (-EINTR);
+               else
+                       (STp->buffer)->syscall_result = (-EBUSY);
+               return NULL;
+       }
        if (SRpnt == NULL) {
                SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC);
                if (SRpnt == NULL) {
                }
        }
  
-       init_completion(&STp->wait);
+       /* If async IO, set last_SRpnt. This ptr tells write_behind_check
+          which IO is outstanding. It's nulled out when the IO completes. */
+       if (!do_wait)
+               (STp->buffer)->last_SRpnt = SRpnt;
+       waiting = &STp->wait;
+       init_completion(waiting);
        SRpnt->sr_use_sg = STp->buffer->do_dio || (bytes > (STp->buffer)->frp[0].length);
        if (SRpnt->sr_use_sg) {
                if (!STp->buffer->do_dio)
                bp = (STp->buffer)->b_data;
        SRpnt->sr_data_direction = direction;
        SRpnt->sr_cmd_len = 0;
-       SRpnt->sr_request->waiting = &(STp->wait);
+       SRpnt->sr_request->waiting = waiting;
        SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
        SRpnt->sr_request->rq_disk = STp->disk;
+       SRpnt->sr_request->end_io = blk_end_sync_rq;
        STp->buffer->cmdstat.have_sense = 0;
  
        scsi_do_req(SRpnt, (void *) cmd, bp, bytes,
                    st_sleep_done, timeout, retries);
  
        if (do_wait) {
-               wait_for_completion(SRpnt->sr_request->waiting);
+               wait_for_completion(waiting);
                SRpnt->sr_request->waiting = NULL;
+               if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE)
+                       SRpnt->sr_result |= (DRIVER_ERROR << 24);
                (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
        }
        return SRpnt;
@@@ -465,6 -532,7 +532,7 @@@ static int write_behind_check(struct sc
        struct st_buffer *STbuffer;
        struct st_partstat *STps;
        struct st_cmdstatus *cmdstatp;
+       struct scsi_request *SRpnt;
  
        STbuffer = STp->buffer;
        if (!STbuffer->writing)
          ) /* end DEB */
  
        wait_for_completion(&(STp->wait));
-       (STp->buffer)->last_SRpnt->sr_request->waiting = NULL;
+       SRpnt = STbuffer->last_SRpnt;
+       STbuffer->last_SRpnt = NULL;
+       SRpnt->sr_request->waiting = NULL;
+       if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE)
+               SRpnt->sr_result |= (DRIVER_ERROR << 24);
  
-       (STp->buffer)->syscall_result = st_chk_result(STp, (STp->buffer)->last_SRpnt);
-       scsi_release_request((STp->buffer)->last_SRpnt);
+       (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
+       scsi_release_request(SRpnt);
  
        STbuffer->buffer_bytes -= STbuffer->writing;
        STps = &(STp->ps[STp->partition]);
@@@ -1055,25 -1127,20 +1127,20 @@@ static int st_open(struct inode *inode
         */
        filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
  
+       if (!(STp = scsi_tape_get(dev)))
+               return -ENXIO;
        write_lock(&st_dev_arr_lock);
-       if (dev >= st_dev_max || scsi_tapes == NULL ||
-           ((STp = scsi_tapes[dev]) == NULL)) {
-               write_unlock(&st_dev_arr_lock);
-               return (-ENXIO);
-       }
        filp->private_data = STp;
        name = tape_name(STp);
  
        if (STp->in_use) {
                write_unlock(&st_dev_arr_lock);
+               scsi_tape_put(STp);
                DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
                return (-EBUSY);
        }
  
-       if(scsi_device_get(STp->device)) {
-               write_unlock(&st_dev_arr_lock);
-               return (-ENXIO);
-       }
        STp->in_use = 1;
        write_unlock(&st_dev_arr_lock);
        STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
   err_out:
        normalize_buffer(STp->buffer);
        STp->in_use = 0;
-       scsi_device_put(STp->device);
+       scsi_tape_put(STp);
        return retval;
  
  }
@@@ -1250,7 -1317,7 +1317,7 @@@ static int st_release(struct inode *ino
        write_lock(&st_dev_arr_lock);
        STp->in_use = 0;
        write_unlock(&st_dev_arr_lock);
-       scsi_device_put(STp->device);
+       scsi_tape_put(STp);
  
        return result;
  }
@@@ -3887,6 -3954,7 +3954,7 @@@ static int st_probe(struct device *dev
                goto out_put_disk;
        }
        memset(tpnt, 0, sizeof(struct scsi_tape));
+       kref_init(&tpnt->kref);
        tpnt->disk = disk;
        sprintf(disk->disk_name, "st%d", i);
        disk->private_data = &tpnt->driver;
                tpnt->tape_type = MT_ISSCSI2;
  
        tpnt->buffer = buffer;
+       tpnt->buffer->last_SRpnt = NULL;
  
        tpnt->inited = 0;
        tpnt->dirty = 0;
@@@ -4076,15 -4145,10 +4145,10 @@@ static int st_remove(struct device *dev
                                        tpnt->modes[mode].cdevs[j] = NULL;
                                }
                        }
-                       tpnt->device = NULL;
  
-                       if (tpnt->buffer) {
-                               tpnt->buffer->orig_frp_segs = 0;
-                               normalize_buffer(tpnt->buffer);
-                               kfree(tpnt->buffer);
-                       }
-                       put_disk(tpnt->disk);
-                       kfree(tpnt);
+                       down(&st_ref_sem);
+                       kref_put(&tpnt->kref, scsi_tape_release);
+                       up(&st_ref_sem);
                        return 0;
                }
        }
        return 0;
  }
  
+ /**
+  *      scsi_tape_release - Called to free the Scsi_Tape structure
+  *      @kref: pointer to embedded kref
+  *
+  *      st_ref_sem must be held entering this routine.  Because it is
+  *      called on last put, you should always use the scsi_tape_get()
+  *      scsi_tape_put() helpers which manipulate the semaphore directly
+  *      and never do a direct kref_put().
+  **/
+ static void scsi_tape_release(struct kref *kref)
+ {
+       struct scsi_tape *tpnt = to_scsi_tape(kref);
+       struct gendisk *disk = tpnt->disk;
+       tpnt->device = NULL;
+       if (tpnt->buffer) {
+               tpnt->buffer->orig_frp_segs = 0;
+               normalize_buffer(tpnt->buffer);
+               kfree(tpnt->buffer);
+       }
+       disk->private_data = NULL;
+       put_disk(disk);
+       kfree(tpnt);
+       return;
+ }
  static void st_intr(struct scsi_cmnd *SCpnt)
  {
        scsi_io_completion(SCpnt, (SCpnt->result ? 0: SCpnt->bufflen), 1);
@@@ -4149,10 -4241,12 +4241,10 @@@ static int __init init_st(void
                        do_create_driverfs_files();
                        return 0;
                }
 -              if (st_sysfs_class)
 -                      class_destroy(st_sysfs_class);
                unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
 -
                                         ST_MAX_TAPE_ENTRIES);
        }
 +      class_destroy(st_sysfs_class);
  
        printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
        return 1;
  
  static void __exit exit_st(void)
  {
 -      if (st_sysfs_class)
 -              class_destroy(st_sysfs_class);
 -      st_sysfs_class = NULL;
        do_remove_driverfs_files();
        scsi_unregister_driver(&st_template.gendrv);
        unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
                                 ST_MAX_TAPE_ENTRIES);
 +      class_destroy(st_sysfs_class);
        kfree(scsi_tapes);
        printk(KERN_INFO "st: Unloaded.\n");
  }