瀏覽代碼

Merge by hand (conflicts in sd.c)

James Bottomley 20 年之前
父節點
當前提交
17fa53da12
共有 49 個文件被更改,包括 2482 次插入755 次删除
  1. 0 41
      Documentation/scsi/scsi_mid_low_api.txt
  2. 45 22
      drivers/base/attribute_container.c
  3. 17 2
      drivers/message/fusion/lsi/mpi.h
  4. 68 17
      drivers/message/fusion/lsi/mpi_cnfg.h
  5. 46 21
      drivers/message/fusion/lsi/mpi_history.txt
  6. 202 1
      drivers/message/fusion/lsi/mpi_init.h
  7. 9 2
      drivers/message/fusion/lsi/mpi_ioc.h
  8. 73 1
      drivers/message/fusion/lsi/mpi_targ.h
  9. 184 137
      drivers/message/fusion/mptbase.c
  10. 4 1
      drivers/message/fusion/mptbase.h
  11. 7 7
      drivers/message/fusion/mptctl.c
  12. 73 67
      drivers/message/fusion/mptscsih.c
  13. 3 3
      drivers/message/fusion/mptspi.c
  14. 6 0
      drivers/scsi/Kconfig
  15. 2 0
      drivers/scsi/Makefile
  16. 1 1
      drivers/scsi/aacraid/aachba.c
  17. 84 12
      drivers/scsi/aic7xxx/aic79xx_osm.c
  18. 44 1
      drivers/scsi/aic7xxx/aic79xx_proc.c
  19. 81 8
      drivers/scsi/aic7xxx/aic7xxx_osm.c
  20. 44 1
      drivers/scsi/aic7xxx/aic7xxx_proc.c
  21. 0 121
      drivers/scsi/aic7xxx/aiclib.c
  22. 0 22
      drivers/scsi/aic7xxx/aiclib.h
  23. 8 15
      drivers/scsi/hosts.c
  24. 114 42
      drivers/scsi/ibmvscsi/ibmvscsi.c
  25. 2 0
      drivers/scsi/ibmvscsi/ibmvscsi.h
  26. 136 0
      drivers/scsi/qla2xxx/qla_attr.c
  27. 7 0
      drivers/scsi/qla2xxx/qla_dbg.h
  28. 151 6
      drivers/scsi/qla2xxx/qla_def.h
  29. 9 3
      drivers/scsi/qla2xxx/qla_gbl.h
  30. 564 0
      drivers/scsi/qla2xxx/qla_gs.c
  31. 22 2
      drivers/scsi/qla2xxx/qla_init.c
  32. 1 5
      drivers/scsi/qla2xxx/qla_iocb.c
  33. 2 0
      drivers/scsi/qla2xxx/qla_isr.c
  34. 44 53
      drivers/scsi/qla2xxx/qla_mbx.c
  35. 71 46
      drivers/scsi/qla2xxx/qla_os.c
  36. 0 34
      drivers/scsi/qla2xxx/qla_sup.c
  37. 2 2
      drivers/scsi/qla2xxx/qla_version.h
  38. 250 0
      drivers/scsi/raid_class.c
  39. 1 0
      drivers/scsi/scsi_devinfo.c
  40. 5 30
      drivers/scsi/scsi_error.c
  41. 9 9
      drivers/scsi/scsi_ioctl.c
  42. 3 0
      drivers/scsi/scsi_priv.h
  43. 19 5
      drivers/scsi/sd.c
  44. 4 4
      drivers/scsi/sg.c
  45. 4 4
      drivers/scsi/st.c
  46. 2 2
      include/linux/attribute_container.h
  47. 59 0
      include/linux/raid_class.h
  48. 0 3
      include/scsi/scsi_eh.h
  49. 0 2
      include/scsi/scsi_host.h

+ 0 - 41
Documentation/scsi/scsi_mid_low_api.txt

@@ -373,13 +373,11 @@ Summary:
    scsi_activate_tcq - turn on tag command queueing
    scsi_add_device - creates new scsi device (lu) instance
    scsi_add_host - perform sysfs registration and SCSI bus scan.
-   scsi_add_timer - (re-)start timer on a SCSI command.
    scsi_adjust_queue_depth - change the queue depth on a SCSI device
    scsi_assign_lock - replace default host_lock with given lock
    scsi_bios_ptable - return copy of block device's partition table
    scsi_block_requests - prevent further commands being queued to given host
    scsi_deactivate_tcq - turn off tag command queueing
-   scsi_delete_timer - cancel timer on a SCSI command.
    scsi_host_alloc - return a new scsi_host instance whose refcount==1
    scsi_host_get - increments Scsi_Host instance's refcount
    scsi_host_put - decrements Scsi_Host instance's refcount (free if 0)
@@ -457,27 +455,6 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
 int scsi_add_host(struct Scsi_Host *shost, struct device * dev)
 
 
-/**
- * scsi_add_timer - (re-)start timer on a SCSI command.
- * @scmd:    pointer to scsi command instance
- * @timeout: duration of timeout in "jiffies"
- * @complete: pointer to function to call if timeout expires
- *
- *      Returns nothing
- *
- *      Might block: no
- *
- *      Notes: Each scsi command has its own timer, and as it is added
- *      to the queue, we set up the timer. When the command completes, 
- *      we cancel the timer. An LLD can use this function to change
- *      the existing timeout value.
- *
- *      Defined in: drivers/scsi/scsi_error.c
- **/
-void scsi_add_timer(struct scsi_cmnd *scmd, int timeout, 
-                    void (*complete)(struct scsi_cmnd *))
-
-
 /**
  * scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device
  * @sdev:       pointer to SCSI device to change queue depth on
@@ -565,24 +542,6 @@ void scsi_block_requests(struct Scsi_Host * shost)
 void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
 
 
-/**
- * scsi_delete_timer - cancel timer on a SCSI command.
- * @scmd:    pointer to scsi command instance
- *
- *      Returns 1 if able to cancel timer else 0 (i.e. too late or already
- *      cancelled).
- *
- *      Might block: no [may in the future if it invokes del_timer_sync()]
- *
- *      Notes: All commands issued by upper levels already have a timeout
- *      associated with them. An LLD can use this function to cancel the
- *      timer.
- *
- *      Defined in: drivers/scsi/scsi_error.c
- **/
-int scsi_delete_timer(struct scsi_cmnd *scmd)
-
-
 /**
  * scsi_host_alloc - create a scsi host adapter instance and perform basic
  *                   initialization.

+ 45 - 22
drivers/base/attribute_container.c

@@ -22,11 +22,26 @@
 /* This is a private structure used to tie the classdev and the
  * container .. it should never be visible outside this file */
 struct internal_container {
-	struct list_head node;
+	struct klist_node node;
 	struct attribute_container *cont;
 	struct class_device classdev;
 };
 
+static void internal_container_klist_get(struct klist_node *n)
+{
+	struct internal_container *ic =
+		container_of(n, struct internal_container, node);
+	class_device_get(&ic->classdev);
+}
+
+static void internal_container_klist_put(struct klist_node *n)
+{
+	struct internal_container *ic =
+		container_of(n, struct internal_container, node);
+	class_device_put(&ic->classdev);
+}
+
+
 /**
  * attribute_container_classdev_to_container - given a classdev, return the container
  *
@@ -57,8 +72,8 @@ int
 attribute_container_register(struct attribute_container *cont)
 {
 	INIT_LIST_HEAD(&cont->node);
-	INIT_LIST_HEAD(&cont->containers);
-	spin_lock_init(&cont->containers_lock);
+	klist_init(&cont->containers,internal_container_klist_get,
+		   internal_container_klist_put);
 		
 	down(&attribute_container_mutex);
 	list_add_tail(&cont->node, &attribute_container_list);
@@ -78,13 +93,13 @@ attribute_container_unregister(struct attribute_container *cont)
 {
 	int retval = -EBUSY;
 	down(&attribute_container_mutex);
-	spin_lock(&cont->containers_lock);
-	if (!list_empty(&cont->containers))
+	spin_lock(&cont->containers.k_lock);
+	if (!list_empty(&cont->containers.k_list))
 		goto out;
 	retval = 0;
 	list_del(&cont->node);
  out:
-	spin_unlock(&cont->containers_lock);
+	spin_unlock(&cont->containers.k_lock);
 	up(&attribute_container_mutex);
 	return retval;
 		
@@ -143,7 +158,6 @@ attribute_container_add_device(struct device *dev,
 			continue;
 		}
 		memset(ic, 0, sizeof(struct internal_container));
-		INIT_LIST_HEAD(&ic->node);
 		ic->cont = cont;
 		class_device_initialize(&ic->classdev);
 		ic->classdev.dev = get_device(dev);
@@ -154,13 +168,22 @@ attribute_container_add_device(struct device *dev,
 			fn(cont, dev, &ic->classdev);
 		else
 			attribute_container_add_class_device(&ic->classdev);
-		spin_lock(&cont->containers_lock);
-		list_add_tail(&ic->node, &cont->containers);
-		spin_unlock(&cont->containers_lock);
+		klist_add_tail(&ic->node, &cont->containers);
 	}
 	up(&attribute_container_mutex);
 }
 
+/* FIXME: can't break out of this unless klist_iter_exit is also
+ * called before doing the break
+ */
+#define klist_for_each_entry(pos, head, member, iter) \
+	for (klist_iter_init(head, iter); (pos = ({ \
+		struct klist_node *n = klist_next(iter); \
+		n ? container_of(n, typeof(*pos), member) : \
+			({ klist_iter_exit(iter) ; NULL; }); \
+	}) ) != NULL; )
+			
+
 /**
  * attribute_container_remove_device - make device eligible for removal.
  *
@@ -187,18 +210,19 @@ attribute_container_remove_device(struct device *dev,
 
 	down(&attribute_container_mutex);
 	list_for_each_entry(cont, &attribute_container_list, node) {
-		struct internal_container *ic, *tmp;
+		struct internal_container *ic;
+		struct klist_iter iter;
 
 		if (attribute_container_no_classdevs(cont))
 			continue;
 
 		if (!cont->match(cont, dev))
 			continue;
-		spin_lock(&cont->containers_lock);
-		list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
+
+		klist_for_each_entry(ic, &cont->containers, node, &iter) {
 			if (dev != ic->classdev.dev)
 				continue;
-			list_del(&ic->node);
+			klist_del(&ic->node);
 			if (fn)
 				fn(cont, dev, &ic->classdev);
 			else {
@@ -206,7 +230,6 @@ attribute_container_remove_device(struct device *dev,
 				class_device_unregister(&ic->classdev);
 			}
 		}
-		spin_unlock(&cont->containers_lock);
 	}
 	up(&attribute_container_mutex);
 }
@@ -232,7 +255,8 @@ attribute_container_device_trigger(struct device *dev,
 
 	down(&attribute_container_mutex);
 	list_for_each_entry(cont, &attribute_container_list, node) {
-		struct internal_container *ic, *tmp;
+		struct internal_container *ic;
+		struct klist_iter iter;
 
 		if (!cont->match(cont, dev))
 			continue;
@@ -242,12 +266,10 @@ attribute_container_device_trigger(struct device *dev,
 			continue;
 		}
 
-		spin_lock(&cont->containers_lock);
-		list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
+		klist_for_each_entry(ic, &cont->containers, node, &iter) {
 			if (dev == ic->classdev.dev)
 				fn(cont, dev, &ic->classdev);
 		}
-		spin_unlock(&cont->containers_lock);
 	}
 	up(&attribute_container_mutex);
 }
@@ -397,15 +419,16 @@ attribute_container_find_class_device(struct attribute_container *cont,
 {
 	struct class_device *cdev = NULL;
 	struct internal_container *ic;
+	struct klist_iter iter;
 
-	spin_lock(&cont->containers_lock);
-	list_for_each_entry(ic, &cont->containers, node) {
+	klist_for_each_entry(ic, &cont->containers, node, &iter) {
 		if (ic->classdev.dev == dev) {
 			cdev = &ic->classdev;
+			/* FIXME: must exit iterator then break */
+			klist_iter_exit(&iter);
 			break;
 		}
 	}
-	spin_unlock(&cont->containers_lock);
 
 	return cdev;
 }

+ 17 - 2
drivers/message/fusion/lsi/mpi.h

@@ -6,7 +6,7 @@
  *          Title:  MPI Message independent structures and definitions
  *  Creation Date:  July 27, 2000
  *
- *    mpi.h Version:  01.05.07
+ *    mpi.h Version:  01.05.08
  *
  *  Version History
  *  ---------------
@@ -71,6 +71,9 @@
  *  03-11-05  01.05.07  Removed function codes for SCSI IO 32 and
  *                      TargetAssistExtended requests.
  *                      Removed EEDP IOCStatus codes.
+ *  06-24-05  01.05.08  Added function codes for SCSI IO 32 and
+ *                      TargetAssistExtended requests.
+ *                      Added EEDP IOCStatus codes.
  *  --------------------------------------------------------------------------
  */
 
@@ -101,7 +104,7 @@
 /* Note: The major versions of 0xe0 through 0xff are reserved */
 
 /* versioning for this MPI header set */
-#define MPI_HEADER_VERSION_UNIT             (0x09)
+#define MPI_HEADER_VERSION_UNIT             (0x0A)
 #define MPI_HEADER_VERSION_DEV              (0x00)
 #define MPI_HEADER_VERSION_UNIT_MASK        (0xFF00)
 #define MPI_HEADER_VERSION_UNIT_SHIFT       (8)
@@ -292,10 +295,13 @@
 #define MPI_FUNCTION_DIAG_BUFFER_POST               (0x1D)
 #define MPI_FUNCTION_DIAG_RELEASE                   (0x1E)
 
+#define MPI_FUNCTION_SCSI_IO_32                     (0x1F)
+
 #define MPI_FUNCTION_LAN_SEND                       (0x20)
 #define MPI_FUNCTION_LAN_RECEIVE                    (0x21)
 #define MPI_FUNCTION_LAN_RESET                      (0x22)
 
+#define MPI_FUNCTION_TARGET_ASSIST_EXTENDED         (0x23)
 #define MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST       (0x24)
 #define MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST       (0x25)
 
@@ -680,6 +686,15 @@ typedef struct _MSG_DEFAULT_REPLY
 #define MPI_IOCSTATUS_SCSI_IOC_TERMINATED       (0x004B)
 #define MPI_IOCSTATUS_SCSI_EXT_TERMINATED       (0x004C)
 
+/****************************************************************************/
+/*  For use by SCSI Initiator and SCSI Target end-to-end data protection    */
+/****************************************************************************/
+
+#define MPI_IOCSTATUS_EEDP_GUARD_ERROR          (0x004D)
+#define MPI_IOCSTATUS_EEDP_REF_TAG_ERROR        (0x004E)
+#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR        (0x004F)
+
+
 /****************************************************************************/
 /*  SCSI Target values                                                      */
 /****************************************************************************/

+ 68 - 17
drivers/message/fusion/lsi/mpi_cnfg.h

@@ -6,7 +6,7 @@
  *          Title:  MPI Config message, structures, and Pages
  *  Creation Date:  July 27, 2000
  *
- *    mpi_cnfg.h Version:  01.05.08
+ *    mpi_cnfg.h Version:  01.05.09
  *
  *  Version History
  *  ---------------
@@ -232,6 +232,23 @@
  *                      New physical mapping mode in SAS IO Unit Page 2.
  *                      Added CONFIG_PAGE_SAS_ENCLOSURE_0.
  *                      Added Slot and Enclosure fields to SAS Device Page 0.
+ *  06-24-05  01.05.09  Added EEDP defines to IOC Page 1.
+ *                      Added more RAID type defines to IOC Page 2.
+ *                      Added Port Enable Delay settings to BIOS Page 1.
+ *                      Added Bad Block Table Full define to RAID Volume Page 0.
+ *                      Added Previous State defines to RAID Physical Disk
+ *                      Page 0.
+ *                      Added Max Sata Targets define for DiscoveryStatus field
+ *                      of SAS IO Unit Page 0.
+ *                      Added Device Self Test to Control Flags of SAS IO Unit
+ *                      Page 1.
+ *                      Added Direct Attach Starting Slot Number define for SAS
+ *                      IO Unit Page 2.
+ *                      Added new fields in SAS Device Page 2 for enclosure
+ *                      mapping.
+ *                      Added OwnerDevHandle and Flags field to SAS PHY Page 0.
+ *                      Added IOC GPIO Flags define to SAS Enclosure Page 0.
+ *                      Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
  *  --------------------------------------------------------------------------
  */
 
@@ -477,6 +494,7 @@ typedef struct _MSG_CONFIG_REPLY
 #define MPI_MANUFACTPAGE_DEVICEID_FC929X            (0x0626)
 #define MPI_MANUFACTPAGE_DEVICEID_FC939X            (0x0642)
 #define MPI_MANUFACTPAGE_DEVICEID_FC949X            (0x0640)
+#define MPI_MANUFACTPAGE_DEVICEID_FC949ES           (0x0646)
 /* SCSI */
 #define MPI_MANUFACTPAGE_DEVID_53C1030              (0x0030)
 #define MPI_MANUFACTPAGE_DEVID_53C1030ZC            (0x0031)
@@ -769,9 +787,13 @@ typedef struct _CONFIG_PAGE_IOC_1
 } CONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
   IOCPage1_t, MPI_POINTER pIOCPage1_t;
 
-#define MPI_IOCPAGE1_PAGEVERSION                        (0x02)
+#define MPI_IOCPAGE1_PAGEVERSION                        (0x03)
 
 /* defines for the Flags field */
+#define MPI_IOCPAGE1_EEDP_MODE_MASK                     (0x07000000)
+#define MPI_IOCPAGE1_EEDP_MODE_OFF                      (0x00000000)
+#define MPI_IOCPAGE1_EEDP_MODE_T10                      (0x01000000)
+#define MPI_IOCPAGE1_EEDP_MODE_LSI_1                    (0x02000000)
 #define MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE    (0x00000010)
 #define MPI_IOCPAGE1_REPLY_COALESCING                   (0x00000001)
 
@@ -795,6 +817,11 @@ typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
 #define MPI_RAID_VOL_TYPE_IS                        (0x00)
 #define MPI_RAID_VOL_TYPE_IME                       (0x01)
 #define MPI_RAID_VOL_TYPE_IM                        (0x02)
+#define MPI_RAID_VOL_TYPE_RAID_5                    (0x03)
+#define MPI_RAID_VOL_TYPE_RAID_6                    (0x04)
+#define MPI_RAID_VOL_TYPE_RAID_10                   (0x05)
+#define MPI_RAID_VOL_TYPE_RAID_50                   (0x06)
+#define MPI_RAID_VOL_TYPE_UNKNOWN                   (0xFF)
 
 /* IOC Page 2 Volume Flags values */
 
@@ -820,13 +847,17 @@ typedef struct _CONFIG_PAGE_IOC_2
 } CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
   IOCPage2_t, MPI_POINTER pIOCPage2_t;
 
-#define MPI_IOCPAGE2_PAGEVERSION                        (0x02)
+#define MPI_IOCPAGE2_PAGEVERSION                        (0x03)
 
 /* IOC Page 2 Capabilities flags */
 
 #define MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT               (0x00000001)
 #define MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT              (0x00000002)
 #define MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT               (0x00000004)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT           (0x00000008)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT           (0x00000010)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT          (0x00000020)
+#define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT          (0x00000040)
 #define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT              (0x20000000)
 #define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT            (0x40000000)
 #define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT    (0x80000000)
@@ -945,7 +976,7 @@ typedef struct _CONFIG_PAGE_BIOS_1
 } CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
   BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
 
-#define MPI_BIOSPAGE1_PAGEVERSION                       (0x01)
+#define MPI_BIOSPAGE1_PAGEVERSION                       (0x02)
 
 /* values for the BiosOptions field */
 #define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE                (0x00000400)
@@ -954,6 +985,8 @@ typedef struct _CONFIG_PAGE_BIOS_1
 #define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS              (0x00000001)
 
 /* values for the IOCSettings field */
+#define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY     (0x00F00000)
+#define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY    (20)
 #define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE       (0x00030000)
 #define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT        (0x00000000)
 #define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT           (0x00010000)
@@ -1167,6 +1200,7 @@ typedef struct _CONFIG_PAGE_BIOS_2
 #define MPI_BIOSPAGE2_FORM_PCI_SLOT_NUMBER              (0x03)
 #define MPI_BIOSPAGE2_FORM_FC_WWN                       (0x04)
 #define MPI_BIOSPAGE2_FORM_SAS_WWN                      (0x05)
+#define MPI_BIOSPAGE2_FORM_ENCLOSURE_SLOT               (0x06)
 
 
 /****************************************************************************
@@ -1957,11 +1991,11 @@ typedef struct _RAID_VOL0_STATUS
   RaidVol0Status_t, MPI_POINTER pRaidVol0Status_t;
 
 /* RAID Volume Page 0 VolumeStatus defines */
-
 #define MPI_RAIDVOL0_STATUS_FLAG_ENABLED                (0x01)
 #define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED               (0x02)
 #define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS     (0x04)
 #define MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE        (0x08)
+#define MPI_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL   (0x10)
 
 #define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL               (0x00)
 #define MPI_RAIDVOL0_STATUS_STATE_DEGRADED              (0x01)
@@ -2025,7 +2059,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
 } CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
   RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
 
-#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x04)
+#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x05)
 
 /* values for RAID Volume Page 0 InactiveStatus field */
 #define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE               (0x00)
@@ -2104,6 +2138,8 @@ typedef struct _RAID_PHYS_DISK0_STATUS
 #define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC           (0x01)
 #define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED              (0x02)
 #define MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME       (0x04)
+#define MPI_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS      (0x00)
+#define MPI_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS  (0x08)
 
 #define MPI_PHYSDISK0_STATUS_ONLINE                     (0x00)
 #define MPI_PHYSDISK0_STATUS_MISSING                    (0x01)
@@ -2132,7 +2168,7 @@ typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_0
 } CONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0,
   RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t;
 
-#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION           (0x01)
+#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION           (0x02)
 
 
 typedef struct _RAID_PHYS_DISK1_PATH
@@ -2263,7 +2299,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
 } CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
   SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
 
-#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x02)
+#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x03)
 
 /* values for SAS IO Unit Page 0 PortFlags */
 #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS    (0x08)
@@ -2299,6 +2335,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
 #define MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK                 (0x00000200)
 #define MPI_SAS_IOUNIT0_DS_TABLE_LINK                       (0x00000400)
 #define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE               (0x00000800)
+#define MPI_SAS_IOUNIT0_DS_MAX_SATA_TARGETS                 (0x00001000)
 
 
 typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
@@ -2336,6 +2373,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
 #define MPI_SASIOUNITPAGE1_PAGEVERSION      (0x04)
 
 /* values for SAS IO Unit Page 1 ControlFlags */
+#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST        (0x8000)
 #define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX            (0x4000)
 #define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX            (0x2000)
 #define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE        (0x1000)
@@ -2345,9 +2383,8 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
 #define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT       (9)
 #define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH        (0x00)
 #define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT         (0x01)
-#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT        (0x10)
+#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT        (0x02)
 
-#define MPI_SAS_IOUNIT1_CONTROL_AUTO_PORT_SAME_SAS_ADDR (0x0100)
 #define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
 #define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED     (0x0040)
 #define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED       (0x0020)
@@ -2390,7 +2427,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
 } CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
   SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
 
-#define MPI_SASIOUNITPAGE2_PAGEVERSION      (0x03)
+#define MPI_SASIOUNITPAGE2_PAGEVERSION      (0x04)
 
 /* values for SAS IO Unit Page 2 Status field */
 #define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
@@ -2406,6 +2443,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
 #define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP       (0x02)
 
 #define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT         (0x10)
+#define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT              (0x20)
 
 
 typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3
@@ -2584,11 +2622,19 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2
 {
     CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
     U64                                 PhysicalIdentifier;     /* 08h */
-    U32                                 Reserved1;              /* 10h */
+    U32                                 EnclosureMapping;       /* 10h */
 } CONFIG_PAGE_SAS_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_2,
   SasDevicePage2_t, MPI_POINTER pSasDevicePage2_t;
 
-#define MPI_SASDEVICE2_PAGEVERSION          (0x00)
+#define MPI_SASDEVICE2_PAGEVERSION          (0x01)
+
+/* defines for SAS Device Page 2 EnclosureMapping field */
+#define MPI_SASDEVICE2_ENC_MAP_MASK_MISSING_COUNT       (0x0000000F)
+#define MPI_SASDEVICE2_ENC_MAP_SHIFT_MISSING_COUNT      (0)
+#define MPI_SASDEVICE2_ENC_MAP_MASK_NUM_SLOTS           (0x000007F0)
+#define MPI_SASDEVICE2_ENC_MAP_SHIFT_NUM_SLOTS          (4)
+#define MPI_SASDEVICE2_ENC_MAP_MASK_START_INDEX         (0x001FF800)
+#define MPI_SASDEVICE2_ENC_MAP_SHIFT_START_INDEX        (11)
 
 
 /****************************************************************************
@@ -2598,7 +2644,8 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2
 typedef struct _CONFIG_PAGE_SAS_PHY_0
 {
     CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
-    U32                                 Reserved1;              /* 08h */
+    U16                                 OwnerDevHandle;         /* 08h */
+    U16                                 Reserved1;              /* 0Ah */
     U64                                 SASAddress;             /* 0Ch */
     U16                                 AttachedDevHandle;      /* 14h */
     U8                                  AttachedPhyIdentifier;  /* 16h */
@@ -2607,12 +2654,12 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
     U8                                  ProgrammedLinkRate;     /* 20h */
     U8                                  HwLinkRate;             /* 21h */
     U8                                  ChangeCount;            /* 22h */
-    U8                                  Reserved3;              /* 23h */
+    U8                                  Flags;                  /* 23h */
     U32                                 PhyInfo;                /* 24h */
 } CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
   SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
 
-#define MPI_SASPHY0_PAGEVERSION             (0x00)
+#define MPI_SASPHY0_PAGEVERSION             (0x01)
 
 /* values for SAS PHY Page 0 ProgrammedLinkRate field */
 #define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK                        (0xF0)
@@ -2632,6 +2679,9 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
 #define MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5                        (0x08)
 #define MPI_SAS_PHY0_HWRATE_MIN_RATE_3_0                        (0x09)
 
+/* values for SAS PHY Page 0 Flags field */
+#define MPI_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC              (0x01)
+
 /* values for SAS PHY Page 0 PhyInfo field */
 #define MPI_SAS_PHY0_PHYINFO_SATA_PORT_ACTIVE                   (0x00004000)
 #define MPI_SAS_PHY0_PHYINFO_SATA_PORT_SELECTOR                 (0x00002000)
@@ -2690,7 +2740,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
 } CONFIG_PAGE_SAS_ENCLOSURE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_ENCLOSURE_0,
   SasEnclosurePage0_t, MPI_POINTER pSasEnclosurePage0_t;
 
-#define MPI_SASENCLOSURE0_PAGEVERSION       (0x00)
+#define MPI_SASENCLOSURE0_PAGEVERSION       (0x01)
 
 /* values for SAS Enclosure Page 0 Flags field */
 #define MPI_SAS_ENCLS0_FLAGS_SEP_BUS_ID_VALID       (0x0020)
@@ -2702,6 +2752,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
 #define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO          (0x0002)
 #define MPI_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO          (0x0003)
 #define MPI_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE      (0x0004)
+#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO           (0x0005)
 
 
 /****************************************************************************

+ 46 - 21
drivers/message/fusion/lsi/mpi_history.txt

@@ -6,17 +6,17 @@
  Copyright (c) 2000-2005 LSI Logic Corporation.
 
  ---------------------------------------
- Header Set Release Version:    01.05.09
+ Header Set Release Version:    01.05.10
  Header Set Release Date:       03-11-05
  ---------------------------------------
 
  Filename               Current version     Prior version
  ----------             ---------------     -------------
- mpi.h                  01.05.07            01.05.06
- mpi_ioc.h              01.05.08            01.05.07
- mpi_cnfg.h             01.05.08            01.05.07
- mpi_init.h             01.05.04            01.05.03
- mpi_targ.h             01.05.04            01.05.03
+ mpi.h                  01.05.08            01.05.07
+ mpi_ioc.h              01.05.09            01.05.08
+ mpi_cnfg.h             01.05.09            01.05.08
+ mpi_init.h             01.05.05            01.05.04
+ mpi_targ.h             01.05.05            01.05.04
  mpi_fc.h               01.05.01            01.05.01
  mpi_lan.h              01.05.01            01.05.01
  mpi_raid.h             01.05.02            01.05.02
@@ -24,7 +24,7 @@
  mpi_inb.h              01.05.01            01.05.01
  mpi_sas.h              01.05.01            01.05.01
  mpi_type.h             01.05.01            01.05.01
- mpi_history.txt        01.05.09            01.05.08
+ mpi_history.txt        01.05.09            01.05.09
 
 
  *  Date      Version   Description
@@ -88,6 +88,9 @@ mpi.h
  *  03-11-05  01.05.07  Removed function codes for SCSI IO 32 and
  *                      TargetAssistExtended requests.
  *                      Removed EEDP IOCStatus codes.
+ *  06-24-05  01.05.08  Added function codes for SCSI IO 32 and
+ *                      TargetAssistExtended requests.
+ *                      Added EEDP IOCStatus codes.
  *  --------------------------------------------------------------------------
 
 mpi_ioc.h
@@ -159,6 +162,8 @@ mpi_ioc.h
  *                      Reply and IOC Init Request.
  *  03-11-05  01.05.08  Added family code for 1068E family.
  *                      Removed IOCFacts Reply EEDP Capability bit.
+ *  06-24-05  01.05.09  Added 5 new IOCFacts Reply IOCCapabilities bits.
+ *                      Added Max SATA Targets to SAS Discovery Error event.
  *  --------------------------------------------------------------------------
 
 mpi_cnfg.h
@@ -380,6 +385,23 @@ mpi_cnfg.h
  *                      New physical mapping mode in SAS IO Unit Page 2.
  *                      Added CONFIG_PAGE_SAS_ENCLOSURE_0.
  *                      Added Slot and Enclosure fields to SAS Device Page 0.
+ *  06-24-05  01.05.09  Added EEDP defines to IOC Page 1.
+ *                      Added more RAID type defines to IOC Page 2.
+ *                      Added Port Enable Delay settings to BIOS Page 1.
+ *                      Added Bad Block Table Full define to RAID Volume Page 0.
+ *                      Added Previous State defines to RAID Physical Disk
+ *                      Page 0.
+ *                      Added Max Sata Targets define for DiscoveryStatus field
+ *                      of SAS IO Unit Page 0.
+ *                      Added Device Self Test to Control Flags of SAS IO Unit
+ *                      Page 1.
+ *                      Added Direct Attach Starting Slot Number define for SAS
+ *                      IO Unit Page 2.
+ *                      Added new fields in SAS Device Page 2 for enclosure
+ *                      mapping.
+ *                      Added OwnerDevHandle and Flags field to SAS PHY Page 0.
+ *                      Added IOC GPIO Flags define to SAS Enclosure Page 0.
+ *                      Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
  *  --------------------------------------------------------------------------
 
 mpi_init.h
@@ -418,6 +440,8 @@ mpi_init.h
  *                      Modified SCSI Enclosure Processor Request and Reply to
  *                      support Enclosure/Slot addressing rather than WWID
  *                      addressing.
+ *  06-24-05  01.05.05  Added SCSI IO 32 structures and defines.
+ *                      Added four new defines for SEP SlotStatus.
  *  --------------------------------------------------------------------------
 
 mpi_targ.h
@@ -461,6 +485,7 @@ mpi_targ.h
  *  10-05-04  01.05.02  MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
  *  02-22-05  01.05.03  Changed a comment.
  *  03-11-05  01.05.04  Removed TargetAssistExtended Request.
+ *  06-24-05  01.05.05  Added TargetAssistExtended structures and defines.
  *  --------------------------------------------------------------------------
 
 mpi_fc.h
@@ -571,20 +596,20 @@ mpi_type.h
 
 mpi_history.txt         Parts list history
 
-Filename    01.05.09
-----------  --------
-mpi.h       01.05.07
-mpi_ioc.h   01.05.08
-mpi_cnfg.h  01.05.08
-mpi_init.h  01.05.04
-mpi_targ.h  01.05.04
-mpi_fc.h    01.05.01
-mpi_lan.h   01.05.01
-mpi_raid.h  01.05.02
-mpi_tool.h  01.05.03
-mpi_inb.h   01.05.01
-mpi_sas.h   01.05.01
-mpi_type.h  01.05.01
+Filename    01.05.10  01.05.09
+----------  --------  --------
+mpi.h       01.05.08  01.05.07
+mpi_ioc.h   01.05.09  01.05.08
+mpi_cnfg.h  01.05.09  01.05.08
+mpi_init.h  01.05.05  01.05.04
+mpi_targ.h  01.05.05  01.05.04
+mpi_fc.h    01.05.01  01.05.01
+mpi_lan.h   01.05.01  01.05.01
+mpi_raid.h  01.05.02  01.05.02
+mpi_tool.h  01.05.03  01.05.03
+mpi_inb.h   01.05.01  01.05.01
+mpi_sas.h   01.05.01  01.05.01
+mpi_type.h  01.05.01  01.05.01
 
 Filename    01.05.08   01.05.07   01.05.06   01.05.05   01.05.04   01.05.03
 ----------  --------   --------   --------   --------   --------   --------

+ 202 - 1
drivers/message/fusion/lsi/mpi_init.h

@@ -6,7 +6,7 @@
  *          Title:  MPI initiator mode messages and structures
  *  Creation Date:  June 8, 2000
  *
- *    mpi_init.h Version:  01.05.04
+ *    mpi_init.h Version:  01.05.05
  *
  *  Version History
  *  ---------------
@@ -48,6 +48,8 @@
  *                      Modified SCSI Enclosure Processor Request and Reply to
  *                      support Enclosure/Slot addressing rather than WWID
  *                      addressing.
+ *  06-24-05  01.05.05  Added SCSI IO 32 structures and defines.
+ *                      Added four new defines for SEP SlotStatus.
  *  --------------------------------------------------------------------------
  */
 
@@ -202,6 +204,197 @@ typedef struct _MSG_SCSI_IO_REPLY
 #define MPI_SCSI_TASKTAG_UNKNOWN                (0xFFFF)
 
 
+/****************************************************************************/
+/*  SCSI IO 32 messages and associated structures                           */
+/****************************************************************************/
+
+typedef struct
+{
+    U8                      CDB[20];                    /* 00h */
+    U32                     PrimaryReferenceTag;        /* 14h */
+    U16                     PrimaryApplicationTag;      /* 18h */
+    U16                     PrimaryApplicationTagMask;  /* 1Ah */
+    U32                     TransferLength;             /* 1Ch */
+} MPI_SCSI_IO32_CDB_EEDP32, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP32,
+  MpiScsiIo32CdbEedp32_t, MPI_POINTER pMpiScsiIo32CdbEedp32_t;
+
+typedef struct
+{
+    U8                      CDB[16];                    /* 00h */
+    U32                     DataLength;                 /* 10h */
+    U32                     PrimaryReferenceTag;        /* 14h */
+    U16                     PrimaryApplicationTag;      /* 18h */
+    U16                     PrimaryApplicationTagMask;  /* 1Ah */
+    U32                     TransferLength;             /* 1Ch */
+} MPI_SCSI_IO32_CDB_EEDP16, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP16,
+  MpiScsiIo32CdbEedp16_t, MPI_POINTER pMpiScsiIo32CdbEedp16_t;
+
+typedef union
+{
+    U8                       CDB32[32];
+    MPI_SCSI_IO32_CDB_EEDP32 EEDP32;
+    MPI_SCSI_IO32_CDB_EEDP16 EEDP16;
+    SGE_SIMPLE_UNION         SGE;
+} MPI_SCSI_IO32_CDB_UNION, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_UNION,
+  MpiScsiIo32Cdb_t, MPI_POINTER pMpiScsiIo32Cdb_t;
+
+typedef struct
+{
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U16                     Reserved1;          /* 02h */
+    U32                     Reserved2;          /* 04h */
+} MPI_SCSI_IO32_BUS_TARGET_ID_FORM, MPI_POINTER PTR_MPI_SCSI_IO32_BUS_TARGET_ID_FORM,
+  MpiScsiIo32BusTargetIdForm_t, MPI_POINTER pMpiScsiIo32BusTargetIdForm_t;
+
+typedef union
+{
+    MPI_SCSI_IO32_BUS_TARGET_ID_FORM    SCSIID;
+    U64                                 WWID;
+} MPI_SCSI_IO32_ADDRESS, MPI_POINTER PTR_MPI_SCSI_IO32_ADDRESS,
+  MpiScsiIo32Address_t, MPI_POINTER pMpiScsiIo32Address_t;
+
+typedef struct _MSG_SCSI_IO32_REQUEST
+{
+    U8                          Port;                           /* 00h */
+    U8                          Reserved1;                      /* 01h */
+    U8                          ChainOffset;                    /* 02h */
+    U8                          Function;                       /* 03h */
+    U8                          CDBLength;                      /* 04h */
+    U8                          SenseBufferLength;              /* 05h */
+    U8                          Flags;                          /* 06h */
+    U8                          MsgFlags;                       /* 07h */
+    U32                         MsgContext;                     /* 08h */
+    U8                          LUN[8];                         /* 0Ch */
+    U32                         Control;                        /* 14h */
+    MPI_SCSI_IO32_CDB_UNION     CDB;                            /* 18h */
+    U32                         DataLength;                     /* 38h */
+    U32                         BidirectionalDataLength;        /* 3Ch */
+    U32                         SecondaryReferenceTag;          /* 40h */
+    U16                         SecondaryApplicationTag;        /* 44h */
+    U16                         Reserved2;                      /* 46h */
+    U16                         EEDPFlags;                      /* 48h */
+    U16                         ApplicationTagTranslationMask;  /* 4Ah */
+    U32                         EEDPBlockSize;                  /* 4Ch */
+    MPI_SCSI_IO32_ADDRESS       DeviceAddress;                  /* 50h */
+    U8                          SGLOffset0;                     /* 58h */
+    U8                          SGLOffset1;                     /* 59h */
+    U8                          SGLOffset2;                     /* 5Ah */
+    U8                          SGLOffset3;                     /* 5Bh */
+    U32                         Reserved3;                      /* 5Ch */
+    U32                         Reserved4;                      /* 60h */
+    U32                         SenseBufferLowAddr;             /* 64h */
+    SGE_IO_UNION                SGL;                            /* 68h */
+} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST,
+  SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t;
+
+/* SCSI IO 32 MsgFlags bits */
+#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH                (0x01)
+#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32             (0x00)
+#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64             (0x01)
+
+#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION             (0x02)
+#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST             (0x00)
+#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_IOC              (0x02)
+
+#define MPI_SCSIIO32_MSGFLGS_CMD_DETERMINES_DATA_DIR    (0x04)
+#define MPI_SCSIIO32_MSGFLGS_SGL_OFFSETS_CHAINS         (0x08)
+#define MPI_SCSIIO32_MSGFLGS_MULTICAST                  (0x10)
+#define MPI_SCSIIO32_MSGFLGS_BIDIRECTIONAL              (0x20)
+#define MPI_SCSIIO32_MSGFLGS_LARGE_CDB                  (0x40)
+
+/* SCSI IO 32 Flags bits */
+#define MPI_SCSIIO32_FLAGS_FORM_MASK                    (0x03)
+#define MPI_SCSIIO32_FLAGS_FORM_SCSIID                  (0x00)
+#define MPI_SCSIIO32_FLAGS_FORM_WWID                    (0x01)
+
+/* SCSI IO 32 LUN fields */
+#define MPI_SCSIIO32_LUN_FIRST_LEVEL_ADDRESSING     (0x0000FFFF)
+#define MPI_SCSIIO32_LUN_SECOND_LEVEL_ADDRESSING    (0xFFFF0000)
+#define MPI_SCSIIO32_LUN_THIRD_LEVEL_ADDRESSING     (0x0000FFFF)
+#define MPI_SCSIIO32_LUN_FOURTH_LEVEL_ADDRESSING    (0xFFFF0000)
+#define MPI_SCSIIO32_LUN_LEVEL_1_WORD               (0xFF00)
+#define MPI_SCSIIO32_LUN_LEVEL_1_DWORD              (0x0000FF00)
+
+/* SCSI IO 32 Control bits */
+#define MPI_SCSIIO32_CONTROL_DATADIRECTION_MASK     (0x03000000)
+#define MPI_SCSIIO32_CONTROL_NODATATRANSFER         (0x00000000)
+#define MPI_SCSIIO32_CONTROL_WRITE                  (0x01000000)
+#define MPI_SCSIIO32_CONTROL_READ                   (0x02000000)
+#define MPI_SCSIIO32_CONTROL_BIDIRECTIONAL          (0x03000000)
+
+#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_MASK         (0xFC000000)
+#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_SHIFT        (26)
+
+#define MPI_SCSIIO32_CONTROL_TASKATTRIBUTE_MASK     (0x00000700)
+#define MPI_SCSIIO32_CONTROL_SIMPLEQ                (0x00000000)
+#define MPI_SCSIIO32_CONTROL_HEADOFQ                (0x00000100)
+#define MPI_SCSIIO32_CONTROL_ORDEREDQ               (0x00000200)
+#define MPI_SCSIIO32_CONTROL_ACAQ                   (0x00000400)
+#define MPI_SCSIIO32_CONTROL_UNTAGGED               (0x00000500)
+#define MPI_SCSIIO32_CONTROL_NO_DISCONNECT          (0x00000700)
+
+#define MPI_SCSIIO32_CONTROL_TASKMANAGE_MASK        (0x00FF0000)
+#define MPI_SCSIIO32_CONTROL_OBSOLETE               (0x00800000)
+#define MPI_SCSIIO32_CONTROL_CLEAR_ACA_RSV          (0x00400000)
+#define MPI_SCSIIO32_CONTROL_TARGET_RESET           (0x00200000)
+#define MPI_SCSIIO32_CONTROL_LUN_RESET_RSV          (0x00100000)
+#define MPI_SCSIIO32_CONTROL_RESERVED               (0x00080000)
+#define MPI_SCSIIO32_CONTROL_CLR_TASK_SET_RSV       (0x00040000)
+#define MPI_SCSIIO32_CONTROL_ABORT_TASK_SET         (0x00020000)
+#define MPI_SCSIIO32_CONTROL_RESERVED2              (0x00010000)
+
+/* SCSI IO 32 EEDPFlags */
+#define MPI_SCSIIO32_EEDPFLAGS_MASK_OP              (0x0007)
+#define MPI_SCSIIO32_EEDPFLAGS_NOOP_OP              (0x0000)
+#define MPI_SCSIIO32_EEDPFLAGS_CHK_OP               (0x0001)
+#define MPI_SCSIIO32_EEDPFLAGS_STRIP_OP             (0x0002)
+#define MPI_SCSIIO32_EEDPFLAGS_CHKRM_OP             (0x0003)
+#define MPI_SCSIIO32_EEDPFLAGS_INSERT_OP            (0x0004)
+#define MPI_SCSIIO32_EEDPFLAGS_REPLACE_OP           (0x0006)
+#define MPI_SCSIIO32_EEDPFLAGS_CHKREGEN_OP          (0x0007)
+
+#define MPI_SCSIIO32_EEDPFLAGS_PASS_REF_TAG         (0x0008)
+#define MPI_SCSIIO32_EEDPFLAGS_8_9THS_MODE          (0x0010)
+
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_MASK         (0x0700)
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_GUARD        (0x0100)
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_REFTAG       (0x0200)
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_LBATAG       (0x0400)
+#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_SHIFT        (8)
+
+#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_APPTAG       (0x1000)
+#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_APPTAG       (0x2000)
+#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_REFTAG       (0x4000)
+#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_REFTAG       (0x8000)
+
+
+/* SCSIIO32 IO reply structure */
+typedef struct _MSG_SCSIIO32_IO_REPLY
+{
+    U8                      Port;                       /* 00h */
+    U8                      Reserved1;                  /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      CDBLength;                  /* 04h */
+    U8                      SenseBufferLength;          /* 05h */
+    U8                      Flags;                      /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      SCSIStatus;                 /* 0Ch */
+    U8                      SCSIState;                  /* 0Dh */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     TransferCount;              /* 14h */
+    U32                     SenseCount;                 /* 18h */
+    U32                     ResponseInfo;               /* 1Ch */
+    U16                     TaskTag;                    /* 20h */
+    U16                     Reserved2;                  /* 22h */
+    U32                     BidirectionalTransferCount; /* 24h */
+} MSG_SCSIIO32_IO_REPLY, MPI_POINTER PTR_MSG_SCSIIO32_IO_REPLY,
+  SCSIIO32Reply_t, MPI_POINTER pSCSIIO32Reply_t;
+
+
 /****************************************************************************/
 /*  SCSI Task Management messages                                           */
 /****************************************************************************/
@@ -310,10 +503,14 @@ typedef struct _MSG_SEP_REQUEST
 #define MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED             (0x00000080)
 #define MPI_SEP_REQ_SLOTSTATUS_HOT_SPARE                (0x00000100)
 #define MPI_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED          (0x00000200)
+#define MPI_SEP_REQ_SLOTSTATUS_REQ_CONSISTENCY_CHECK    (0x00001000)
+#define MPI_SEP_REQ_SLOTSTATUS_DISABLE                  (0x00002000)
+#define MPI_SEP_REQ_SLOTSTATUS_REQ_RESERVED_DEVICE      (0x00004000)
 #define MPI_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST         (0x00020000)
 #define MPI_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE           (0x00040000)
 #define MPI_SEP_REQ_SLOTSTATUS_REQUEST_INSERT           (0x00080000)
 #define MPI_SEP_REQ_SLOTSTATUS_DO_NOT_MOVE              (0x00400000)
+#define MPI_SEP_REQ_SLOTSTATUS_ACTIVE                   (0x00800000)
 #define MPI_SEP_REQ_SLOTSTATUS_B_ENABLE_BYPASS          (0x04000000)
 #define MPI_SEP_REQ_SLOTSTATUS_A_ENABLE_BYPASS          (0x08000000)
 #define MPI_SEP_REQ_SLOTSTATUS_DEV_OFF                  (0x10000000)
@@ -352,11 +549,15 @@ typedef struct _MSG_SEP_REPLY
 #define MPI_SEP_REPLY_SLOTSTATUS_UNCONFIGURED           (0x00000080)
 #define MPI_SEP_REPLY_SLOTSTATUS_HOT_SPARE              (0x00000100)
 #define MPI_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED        (0x00000200)
+#define MPI_SEP_REPLY_SLOTSTATUS_CONSISTENCY_CHECK      (0x00001000)
+#define MPI_SEP_REPLY_SLOTSTATUS_DISABLE                (0x00002000)
+#define MPI_SEP_REPLY_SLOTSTATUS_RESERVED_DEVICE        (0x00004000)
 #define MPI_SEP_REPLY_SLOTSTATUS_REPORT                 (0x00010000)
 #define MPI_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST       (0x00020000)
 #define MPI_SEP_REPLY_SLOTSTATUS_REMOVE_READY           (0x00040000)
 #define MPI_SEP_REPLY_SLOTSTATUS_INSERT_READY           (0x00080000)
 #define MPI_SEP_REPLY_SLOTSTATUS_DO_NOT_REMOVE          (0x00400000)
+#define MPI_SEP_REPLY_SLOTSTATUS_ACTIVE                 (0x00800000)
 #define MPI_SEP_REPLY_SLOTSTATUS_B_BYPASS_ENABLED       (0x01000000)
 #define MPI_SEP_REPLY_SLOTSTATUS_A_BYPASS_ENABLED       (0x02000000)
 #define MPI_SEP_REPLY_SLOTSTATUS_B_ENABLE_BYPASS        (0x04000000)

+ 9 - 2
drivers/message/fusion/lsi/mpi_ioc.h

@@ -6,7 +6,7 @@
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  August 11, 2000
  *
- *    mpi_ioc.h Version:  01.05.08
+ *    mpi_ioc.h Version:  01.05.09
  *
  *  Version History
  *  ---------------
@@ -81,6 +81,8 @@
  *                      Reply and IOC Init Request.
  *  03-11-05  01.05.08  Added family code for 1068E family.
  *                      Removed IOCFacts Reply EEDP Capability bit.
+ *  06-24-05  01.05.09  Added 5 new IOCFacts Reply IOCCapabilities bits.
+ *                      Added Max SATA Targets to SAS Discovery Error event.
  *  --------------------------------------------------------------------------
  */
 
@@ -261,7 +263,11 @@ typedef struct _MSG_IOC_FACTS_REPLY
 #define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER       (0x00000008)
 #define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER         (0x00000010)
 #define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER         (0x00000020)
-
+#define MPI_IOCFACTS_CAPABILITY_EEDP                    (0x00000040)
+#define MPI_IOCFACTS_CAPABILITY_BIDIRECTIONAL           (0x00000080)
+#define MPI_IOCFACTS_CAPABILITY_MULTICAST               (0x00000100)
+#define MPI_IOCFACTS_CAPABILITY_SCSIIO32                (0x00000200)
+#define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16             (0x00000400)
 
 
 /*****************************************************************************
@@ -677,6 +683,7 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR
 #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE          (0x00000200)
 #define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE              (0x00000400)
 #define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS                (0x00000800)
+#define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS            (0x00001000)
 
 
 /*****************************************************************************

+ 73 - 1
drivers/message/fusion/lsi/mpi_targ.h

@@ -6,7 +6,7 @@
  *          Title:  MPI Target mode messages and structures
  *  Creation Date:  June 22, 2000
  *
- *    mpi_targ.h Version:  01.05.04
+ *    mpi_targ.h Version:  01.05.05
  *
  *  Version History
  *  ---------------
@@ -53,6 +53,7 @@
  *  10-05-04  01.05.02  MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
  *  02-22-05  01.05.03  Changed a comment.
  *  03-11-05  01.05.04  Removed TargetAssistExtended Request.
+ *  06-24-05  01.05.05  Added TargetAssistExtended structures and defines.
  *  --------------------------------------------------------------------------
  */
 
@@ -370,6 +371,77 @@ typedef struct _MSG_TARGET_ERROR_REPLY
   TargetErrorReply_t, MPI_POINTER pTargetErrorReply_t;
 
 
+/****************************************************************************/
+/* Target Assist Extended Request                                           */
+/****************************************************************************/
+
+typedef struct _MSG_TARGET_ASSIST_EXT_REQUEST
+{
+    U8                      StatusCode;                     /* 00h */
+    U8                      TargetAssistFlags;              /* 01h */
+    U8                      ChainOffset;                    /* 02h */
+    U8                      Function;                       /* 03h */
+    U16                     QueueTag;                       /* 04h */
+    U8                      Reserved1;                      /* 06h */
+    U8                      MsgFlags;                       /* 07h */
+    U32                     MsgContext;                     /* 08h */
+    U32                     ReplyWord;                      /* 0Ch */
+    U8                      LUN[8];                         /* 10h */
+    U32                     RelativeOffset;                 /* 18h */
+    U32                     Reserved2;                      /* 1Ch */
+    U32                     Reserved3;                      /* 20h */
+    U32                     PrimaryReferenceTag;            /* 24h */
+    U16                     PrimaryApplicationTag;          /* 28h */
+    U16                     PrimaryApplicationTagMask;      /* 2Ah */
+    U32                     Reserved4;                      /* 2Ch */
+    U32                     DataLength;                     /* 30h */
+    U32                     BidirectionalDataLength;        /* 34h */
+    U32                     SecondaryReferenceTag;          /* 38h */
+    U16                     SecondaryApplicationTag;        /* 3Ch */
+    U16                     Reserved5;                      /* 3Eh */
+    U16                     EEDPFlags;                      /* 40h */
+    U16                     ApplicationTagTranslationMask;  /* 42h */
+    U32                     EEDPBlockSize;                  /* 44h */
+    U8                      SGLOffset0;                     /* 48h */
+    U8                      SGLOffset1;                     /* 49h */
+    U8                      SGLOffset2;                     /* 4Ah */
+    U8                      SGLOffset3;                     /* 4Bh */
+    U32                     Reserved6;                      /* 4Ch */
+    SGE_IO_UNION            SGL[1];                         /* 50h */
+} MSG_TARGET_ASSIST_EXT_REQUEST, MPI_POINTER PTR_MSG_TARGET_ASSIST_EXT_REQUEST,
+  TargetAssistExtRequest_t, MPI_POINTER pTargetAssistExtRequest_t;
+
+/* see the defines after MSG_TARGET_ASSIST_REQUEST for TargetAssistFlags */
+
+/* defines for the MsgFlags field */
+#define TARGET_ASSIST_EXT_MSGFLAGS_BIDIRECTIONAL        (0x20)
+#define TARGET_ASSIST_EXT_MSGFLAGS_MULTICAST            (0x10)
+#define TARGET_ASSIST_EXT_MSGFLAGS_SGL_OFFSET_CHAINS    (0x08)
+
+/* defines for the EEDPFlags field */
+#define TARGET_ASSIST_EXT_EEDP_MASK_OP          (0x0007)
+#define TARGET_ASSIST_EXT_EEDP_NOOP_OP          (0x0000)
+#define TARGET_ASSIST_EXT_EEDP_CHK_OP           (0x0001)
+#define TARGET_ASSIST_EXT_EEDP_STRIP_OP         (0x0002)
+#define TARGET_ASSIST_EXT_EEDP_CHKRM_OP         (0x0003)
+#define TARGET_ASSIST_EXT_EEDP_INSERT_OP        (0x0004)
+#define TARGET_ASSIST_EXT_EEDP_REPLACE_OP       (0x0006)
+#define TARGET_ASSIST_EXT_EEDP_CHKREGEN_OP      (0x0007)
+
+#define TARGET_ASSIST_EXT_EEDP_PASS_REF_TAG     (0x0008)
+
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_MASK     (0x0700)
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_GUARD    (0x0100)
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_APPTAG   (0x0200)
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_REFTAG   (0x0400)
+#define TARGET_ASSIST_EXT_EEDP_T10_CHK_SHIFT    (8)
+
+#define TARGET_ASSIST_EXT_EEDP_INC_SEC_APPTAG   (0x1000)
+#define TARGET_ASSIST_EXT_EEDP_INC_PRI_APPTAG   (0x2000)
+#define TARGET_ASSIST_EXT_EEDP_INC_SEC_REFTAG   (0x4000)
+#define TARGET_ASSIST_EXT_EEDP_INC_PRI_REFTAG   (0x8000)
+
+
 /****************************************************************************/
 /* Target Status Send Request                                               */
 /****************************************************************************/

+ 184 - 137
drivers/message/fusion/mptbase.c

@@ -218,8 +218,7 @@ pci_enable_io_access(struct pci_dev *pdev)
  *	(also referred to as a IO Controller or IOC).
  *	This routine must clear the interrupt from the adapter and does
  *	so by reading the reply FIFO.  Multiple replies may be processed
- *	per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
- *	which is currently set to 32 in mptbase.h.
+ *	per single call to this routine.
  *
  *	This routine handles register-level access of the adapter but
  *	dispatches (calls) a protocol-specific callback routine to handle
@@ -279,11 +278,11 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
 			cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
 			mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
 
-			dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n",
-					ioc->name, mr, req_idx));
+			dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
+					ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
 			DBG_DUMP_REPLY_FRAME(mr)
 
-			/*  Check/log IOC log info
+			 /*  Check/log IOC log info
 			 */
 			ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
 			if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
@@ -345,7 +344,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
 			if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
 				|| (mf < ioc->req_frames)) ) {
 				printk(MYIOC_s_WARN_FMT
-					"mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
+					"mpt_interrupt: Invalid mf (%p)!\n", ioc->name, (void *)mf);
 				cb_idx = 0;
 				pa = 0;
 				freeme = 0;
@@ -399,7 +398,7 @@ mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
  *	@mf: Pointer to original MPT request frame
  *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
  *
-	*	Returns 1 indicating original alloc'd request frame ptr
+ *	Returns 1 indicating original alloc'd request frame ptr
  *	should be freed, or 0 if it shouldn't.
  */
 static int
@@ -408,28 +407,17 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
 	int freereq = 1;
 	u8 func;
 
-	dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
-
-	if ((mf == NULL) ||
-	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
-		printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
-				ioc->name, (void *)mf);
-		return 1;
-	}
-
-	if (reply == NULL) {
-		dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
-				ioc->name));
-		return 1;
-	}
+	dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
 
+#if defined(MPT_DEBUG_MSG_FRAME)
 	if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
 		dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
 		DBG_DUMP_REQUEST_FRAME_HDR(mf)
 	}
+#endif
 
 	func = reply->u.hdr.Function;
-	dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
+	dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
 			ioc->name, func));
 
 	if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
@@ -448,8 +436,14 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
 		 *	Hmmm...  It seems that EventNotificationReply is an exception
 		 *	to the rule of one reply per request.
 		 */
-		if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
+		if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
 			freereq = 0;
+			devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
+				ioc->name, pEvReply));
+		} else {
+			devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
+				ioc->name, pEvReply));
+		}
 
 #ifdef CONFIG_PROC_FS
 //		LogEvent(ioc, pEvReply);
@@ -491,10 +485,21 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
 
 				pCfg->status = status;
 				if (status == MPI_IOCSTATUS_SUCCESS) {
-					pCfg->hdr->PageVersion = pReply->Header.PageVersion;
-					pCfg->hdr->PageLength = pReply->Header.PageLength;
-					pCfg->hdr->PageNumber = pReply->Header.PageNumber;
-					pCfg->hdr->PageType = pReply->Header.PageType;
+					if ((pReply->Header.PageType &
+					    MPI_CONFIG_PAGETYPE_MASK) ==
+					    MPI_CONFIG_PAGETYPE_EXTENDED) {
+						pCfg->cfghdr.ehdr->ExtPageLength =
+						    le16_to_cpu(pReply->ExtPageLength);
+						pCfg->cfghdr.ehdr->ExtPageType =
+						    pReply->ExtPageType;
+					}
+					pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
+
+					/* If this is a regular header, save PageLength. */
+					/* LMP Do this better so not using a reserved field! */
+					pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
+					pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
+					pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
 				}
 			}
 
@@ -705,7 +710,7 @@ mpt_device_driver_deregister(int cb_idx)
 		if (dd_cbfunc->remove)
 			dd_cbfunc->remove(ioc->pcidev);
 	}
-	
+
 	MptDeviceDriverHandlers[cb_idx] = NULL;
 }
 
@@ -818,7 +823,7 @@ mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
 	}
 #endif
 
-	mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];  
+	mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
 	dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
 	CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
 }
@@ -920,7 +925,7 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
 
 	/* Make sure there are no doorbells */
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-	
+
 	CHIPREG_WRITE32(&ioc->chip->Doorbell,
 			((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
 			 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
@@ -935,14 +940,14 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
 		return -5;
 
 	dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
-			ioc->name, ii));
+		ioc->name, ii));
 
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
 		return -2;
 	}
-		
+
 	/* Send request via doorbell handshake */
 	req_as_bytes = (u8 *) req;
 	for (ii = 0; ii < reqBytes/4; ii++) {
@@ -988,9 +993,9 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
 		if (ioc->id == iocid) {
 			*iocpp =ioc;
 			return iocid;
-		} 
+		}
 	}
-	
+
 	*iocpp = NULL;
 	return -1;
 }
@@ -1032,9 +1037,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	if (pci_enable_device(pdev))
 		return r;
-	
+
 	dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
-	
+
 	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		dprintk((KERN_INFO MYNAM
 			": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
@@ -1059,7 +1064,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 	ioc->alloc_total = sizeof(MPT_ADAPTER);
 	ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;		/* avoid div by zero! */
 	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
-	
+
 	ioc->pcidev = pdev;
 	ioc->diagPending = 0;
 	spin_lock_init(&ioc->diagLock);
@@ -1088,7 +1093,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 	/* Find lookup slot. */
 	INIT_LIST_HEAD(&ioc->list);
 	ioc->id = mpt_ids++;
-	
+
 	mem_phys = msize = 0;
 	port = psize = 0;
 	for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
@@ -1143,7 +1148,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 		ioc->prod_name = "LSIFC909";
 		ioc->bus_type = FC;
 	}
-	if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
+	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
 		ioc->prod_name = "LSIFC929";
 		ioc->bus_type = FC;
 	}
@@ -1322,7 +1327,7 @@ mpt_detach(struct pci_dev *pdev)
 	remove_proc_entry(pname, NULL);
 	sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
 	remove_proc_entry(pname, NULL);
-	
+
 	/* call per device driver remove entry point */
 	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
 		if(MptDeviceDriverHandlers[ii] &&
@@ -1330,7 +1335,7 @@ mpt_detach(struct pci_dev *pdev)
 			MptDeviceDriverHandlers[ii]->remove(pdev);
 		}
 	}
-	
+
 	/* Disable interrupts! */
 	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
 
@@ -1403,7 +1408,7 @@ mpt_resume(struct pci_dev *pdev)
 	u32 device_state = pdev->current_state;
 	int recovery_state;
 	int ii;
-	
+
 	printk(MYIOC_s_INFO_FMT
 	"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
 		ioc->name, pdev, pci_name(pdev), device_state);
@@ -1534,7 +1539,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 		if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
 			break;
 	}
-	
+
 
 	if (ii == 5) {
 		dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
@@ -1542,7 +1547,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 	} else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
 		MptDisplayIocCapabilities(ioc);
 	}
-	
+
 	if (alt_ioc_ready) {
 		if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
 			dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
@@ -1613,7 +1618,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 
 	if (reset_alt_ioc_active && ioc->alt_ioc) {
 		/* (re)Enable alt-IOC! (reply interrupt) */
-		dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
+		dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
 				ioc->alt_ioc->name));
 		CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
 		ioc->alt_ioc->active = 1;
@@ -1670,7 +1675,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 
 			/* Find IM volumes
 			 */
-			if (ioc->facts.MsgVersion >= 0x0102)
+			if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
 				mpt_findImVolumes(ioc);
 
 			/* Check, and possibly reset, the coalescing value
@@ -1700,7 +1705,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 			}
 
 			if (alt_ioc_ready && MptResetHandlers[ii]) {
-				dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
+				drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
 						ioc->name, ioc->alt_ioc->name, ii));
 				rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
 				handlers++;
@@ -1733,8 +1738,8 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
 
 	dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
 	    " searching for devfn match on %x or %x\n",
-		ioc->name, pci_name(pdev), pdev->devfn,
-		func-1, func+1));
+		ioc->name, pci_name(pdev), pdev->bus->number,
+		pdev->devfn, func-1, func+1));
 
 	peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
 	if (!peer) {
@@ -1861,36 +1866,39 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
 static void
 mpt_adapter_dispose(MPT_ADAPTER *ioc)
 {
-	if (ioc != NULL) {
-		int sz_first, sz_last;
+	int sz_first, sz_last;
 
-		sz_first = ioc->alloc_total;
+	if (ioc == NULL)
+		return;
 
-		mpt_adapter_disable(ioc);
+	sz_first = ioc->alloc_total;
 
-		if (ioc->pci_irq != -1) {
-			free_irq(ioc->pci_irq, ioc);
-			ioc->pci_irq = -1;
-		}
+	mpt_adapter_disable(ioc);
 
-		if (ioc->memmap != NULL)
-			iounmap(ioc->memmap);
+	if (ioc->pci_irq != -1) {
+		free_irq(ioc->pci_irq, ioc);
+		ioc->pci_irq = -1;
+	}
+
+	if (ioc->memmap != NULL) {
+		iounmap(ioc->memmap);
+		ioc->memmap = NULL;
+	}
 
 #if defined(CONFIG_MTRR) && 0
-		if (ioc->mtrr_reg > 0) {
-			mtrr_del(ioc->mtrr_reg, 0, 0);
-			dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
-		}
+	if (ioc->mtrr_reg > 0) {
+		mtrr_del(ioc->mtrr_reg, 0, 0);
+		dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
+	}
 #endif
 
-		/*  Zap the adapter lookup ptr!  */
-		list_del(&ioc->list);
+	/*  Zap the adapter lookup ptr!  */
+	list_del(&ioc->list);
 
-		sz_last = ioc->alloc_total;
-		dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
-				ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
-		kfree(ioc);
-	}
+	sz_last = ioc->alloc_total;
+	dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
+			ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
+	kfree(ioc);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1977,7 +1985,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
 	}
 
 	/* Is it already READY? */
-	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) 
+	if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
 		return 0;
 
 	/*
@@ -1995,7 +2003,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
 	 *	Hmmm...  Did it get left operational?
 	 */
 	if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
-		dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
+		dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
 				ioc->name));
 
 		/* Check WhoInit.
@@ -2004,8 +2012,8 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
 		 * Else, fall through to KickStart case
 		 */
 		whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
-		dprintk((KERN_WARNING MYNAM
-			": whoinit 0x%x\n statefault %d force %d\n",
+		dinitprintk((KERN_INFO MYNAM
+			": whoinit 0x%x statefault %d force %d\n",
 			whoinit, statefault, force));
 		if (whoinit == MPI_WHOINIT_PCI_PEER)
 			return -4;
@@ -2140,8 +2148,8 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
 	get_facts.Function = MPI_FUNCTION_IOC_FACTS;
 	/* Assert: All other get_facts fields are zero! */
 
-	dinitprintk((MYIOC_s_INFO_FMT 
-	    "Sending get IocFacts request req_sz=%d reply_sz=%d\n", 
+	dinitprintk((MYIOC_s_INFO_FMT
+	    "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
 	    ioc->name, req_sz, reply_sz));
 
 	/* No non-zero fields in the get_facts request are greater than
@@ -2174,7 +2182,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
 		facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
 		facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
 		facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
-		status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
+		status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
 		/* CHECKME! IOCStatus, IOCLogInfo */
 
 		facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
@@ -2221,7 +2229,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
 		if ( sz & 0x02 )
 			sz += 2;
 		facts->FWImageSize = sz;
-		
+
 		if (!facts->RequestFrameSize) {
 			/*  Something is wrong!  */
 			printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
@@ -2240,7 +2248,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
 		ioc->NBShiftFactor  = shiftFactor;
 		dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
 					ioc->name, vv, shiftFactor, r));
-    
+
 		if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
 			/*
 			 * Set values for this IOC's request & reply frame sizes,
@@ -2261,7 +2269,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
 				return r;
 		}
 	} else {
-		printk(MYIOC_s_ERR_FMT 
+		printk(MYIOC_s_ERR_FMT
 		     "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
 		     ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
 		     RequestFrameSize)/sizeof(u32)));
@@ -2413,9 +2421,11 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
 
 	dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
 			ioc->name, &ioc_init));
-	
-	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
+
+	if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
+		printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
 		return r;
+	}
 
 	/* YIKES!  SUPER IMPORTANT!!!
 	 *  Poll IocState until _OPERATIONAL while IOC is doing
@@ -2440,7 +2450,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
 		state = mpt_GetIocState(ioc, 1);
 		count++;
 	}
-	dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
+	dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
 			ioc->name, count));
 
 	return r;
@@ -2529,7 +2539,7 @@ mpt_free_fw_memory(MPT_ADAPTER *ioc)
 	int sz;
 
 	sz = ioc->facts.FWImageSize;
-	dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
+	dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
 	pci_free_consistent(ioc->pcidev, sz,
 			ioc->cached_fw, ioc->cached_fw_dma);
@@ -2573,9 +2583,9 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
 
 	mpt_alloc_fw_memory(ioc, sz);
 
-	dinitprintk((KERN_WARNING MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
+	dinitprintk((KERN_INFO MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
 		 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
-	
+
 	if (ioc->cached_fw == NULL) {
 		/* Major Failure.
 		 */
@@ -2605,14 +2615,14 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
 	mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
 
 	sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
-	dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
+	dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
 			prequest, sgeoffset));
 	DBG_DUMP_FW_REQUEST_FRAME(prequest)
 
 	ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
 				reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
 
-	dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
+	dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
 
 	cmdStatus = -EFAULT;
 	if (ii == 0) {
@@ -2627,10 +2637,10 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
 				cmdStatus = 0;
 		}
 	}
-	dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
+	dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
 			ioc->name, cmdStatus));
 
-	
+
 	if (cmdStatus) {
 
 		ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
@@ -2761,8 +2771,8 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
 		fwSize = (pExtImage->ImageSize + 3) >> 2;
 		ptrFw = (u32 *)pExtImage;
 
-		ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
-						ioc->name, fwSize*4, ptrFw, load_addr));
+		ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
+						ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
 		CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
 
 		while (fwSize--) {
@@ -2845,9 +2855,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
  *			  0 else
  *
  *	Returns:
- *		 1 - hard reset, READY	
- *		 0 - no reset due to History bit, READY	
- *		-1 - no reset due to History bit but not READY	
+ *		 1 - hard reset, READY
+ *		 0 - no reset due to History bit, READY
+ *		-1 - no reset due to History bit but not READY
  *		     OR reset but failed to come READY
  *		-2 - no reset, could not enter DIAG mode
  *		-3 - reset but bad FW bit
@@ -2990,7 +3000,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
 		 *
 		 */
 		CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
-		mdelay (1);
+		mdelay(1);
 
 		/*
 		 * Now hit the reset bit in the Diagnostic register
@@ -3170,7 +3180,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
 	u32 state;
 	int cntdn, count;
 
-	drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
+	drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
 			ioc->name, reset_type));
 	CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
 	if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
@@ -3374,6 +3384,9 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
 		ioc->reply_frames = (MPT_FRAME_HDR *) mem;
 		ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
 
+		dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
+	 		ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
+
 		alloc_dma += reply_sz;
 		mem += reply_sz;
 
@@ -3382,7 +3395,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
 		ioc->req_frames = (MPT_FRAME_HDR *) mem;
 		ioc->req_frames_dma = alloc_dma;
 
-		dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
+		dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
 			 	ioc->name, mem, (void *)(ulong)alloc_dma));
 
 		ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
@@ -3408,7 +3421,7 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
 		ioc->ChainBuffer = mem;
 		ioc->ChainBufferDMA = alloc_dma;
 
-		dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
+		dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
 			ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
 
 		/* Initialize the free chain Q.
@@ -3513,7 +3526,7 @@ out_fail:
  */
 static int
 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
-				int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
+		int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
 {
 	MPIDefaultReply_t *mptReply;
 	int failcnt = 0;
@@ -3588,7 +3601,7 @@ mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
 		 */
 		if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
 			failcnt++;
-		
+
 		dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
 				ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
 
@@ -3747,7 +3760,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
 	}
 
 	dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
-			ioc->name, t, le32_to_cpu(*(u32 *)hs_reply), 
+			ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
 			failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
 
 	/*
@@ -3819,7 +3832,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
 	hdr.PageLength = 0;
 	hdr.PageNumber = 0;
 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
-	cfg.hdr = &hdr;
+	cfg.cfghdr.hdr = &hdr;
 	cfg.physAddr = -1;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;
@@ -3863,7 +3876,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
 	hdr.PageLength = 0;
 	hdr.PageNumber = 1;
 	hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
-	cfg.hdr = &hdr;
+	cfg.cfghdr.hdr = &hdr;
 	cfg.physAddr = -1;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;
@@ -3930,7 +3943,7 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
 	hdr.PageLength = 0;
 	hdr.PageNumber = 0;
 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
-	cfg.hdr = &hdr;
+	cfg.cfghdr.hdr = &hdr;
 	cfg.physAddr = -1;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;
@@ -4012,7 +4025,7 @@ GetIoUnitPage2(MPT_ADAPTER *ioc)
 	hdr.PageLength = 0;
 	hdr.PageNumber = 2;
 	hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
-	cfg.hdr = &hdr;
+	cfg.cfghdr.hdr = &hdr;
 	cfg.physAddr = -1;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;
@@ -4102,7 +4115,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
 	header.PageLength = 0;
 	header.PageNumber = 0;
 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
-	cfg.hdr = &header;
+	cfg.cfghdr.hdr = &header;
 	cfg.physAddr = -1;
 	cfg.pageAddr = portnum;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4122,6 +4135,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
 				ioc->spi_data.minSyncFactor = MPT_ASYNC;
 				ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
 				rc = 1;
+				ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
+					ioc->name, ioc->spi_data.minSyncFactor));
 			} else {
 				/* Save the Port Page 0 data
 				 */
@@ -4131,7 +4146,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
 
 				if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
 					ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
-					dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
+					ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
 						ioc->name, pPP0->Capabilities));
 				}
 				ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
@@ -4140,6 +4155,8 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
 					ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
 					data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
 					ioc->spi_data.minSyncFactor = (u8) (data >> 8);
+					ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
+						ioc->name, ioc->spi_data.minSyncFactor));
 				} else {
 					ioc->spi_data.maxSyncOffset = 0;
 					ioc->spi_data.minSyncFactor = MPT_ASYNC;
@@ -4152,8 +4169,11 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
 				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
 					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
 
-				if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
+					if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
 						ioc->spi_data.minSyncFactor = MPT_ULTRA;
+						ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
+							ioc->name, ioc->spi_data.minSyncFactor));
+					}
 				}
 			}
 			if (pbuf) {
@@ -4168,7 +4188,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
 	header.PageLength = 0;
 	header.PageNumber = 2;
 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
-	cfg.hdr = &header;
+	cfg.cfghdr.hdr = &header;
 	cfg.physAddr = -1;
 	cfg.pageAddr = portnum;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4236,7 +4256,7 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
 	header.PageLength = 0;
 	header.PageNumber = 1;
 	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-	cfg.hdr = &header;
+	cfg.cfghdr.hdr = &header;
 	cfg.physAddr = -1;
 	cfg.pageAddr = portnum;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4245,8 +4265,8 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
 	if (mpt_config(ioc, &cfg) != 0)
 		 return -EFAULT;
 
-	ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
-	ioc->spi_data.sdp1length = cfg.hdr->PageLength;
+	ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
+	ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
 
 	header.PageVersion = 0;
 	header.PageLength = 0;
@@ -4255,8 +4275,8 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
 	if (mpt_config(ioc, &cfg) != 0)
 		 return -EFAULT;
 
-	ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
-	ioc->spi_data.sdp0length = cfg.hdr->PageLength;
+	ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
+	ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
 
 	dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
 			ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
@@ -4298,7 +4318,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
 	header.PageLength = 0;
 	header.PageNumber = 2;
 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
-	cfg.hdr = &header;
+	cfg.cfghdr.hdr = &header;
 	cfg.physAddr = -1;
 	cfg.pageAddr = 0;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4394,7 +4414,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
 	header.PageLength = 0;
 	header.PageNumber = 3;
 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
-	cfg.hdr = &header;
+	cfg.cfghdr.hdr = &header;
 	cfg.physAddr = -1;
 	cfg.pageAddr = 0;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4446,7 +4466,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
 	header.PageLength = 0;
 	header.PageNumber = 4;
 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
-	cfg.hdr = &header;
+	cfg.cfghdr.hdr = &header;
 	cfg.physAddr = -1;
 	cfg.pageAddr = 0;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4498,7 +4518,7 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
 	header.PageLength = 0;
 	header.PageNumber = 1;
 	header.PageType = MPI_CONFIG_PAGETYPE_IOC;
-	cfg.hdr = &header;
+	cfg.cfghdr.hdr = &header;
 	cfg.physAddr = -1;
 	cfg.pageAddr = 0;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -4580,13 +4600,13 @@ SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
 
 	evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
 	if (evnp == NULL) {
-		dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
+		devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
 				ioc->name));
 		return 0;
 	}
 	memset(evnp, 0, sizeof(*evnp));
 
-	dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
+	devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
 
 	evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
 	evnp->ChainOffset = 0;
@@ -4610,8 +4630,10 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
 	EventAck_t	*pAck;
 
 	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
-		printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
-				ioc->name);
+		printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
+			"request frame for Event=%x EventContext=%x EventData=%x!\n",
+			ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
+			le32_to_cpu(evnp->Data[0]));
 		return -1;
 	}
 	memset(pAck, 0, sizeof(*pAck));
@@ -4647,10 +4669,11 @@ int
 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
 {
 	Config_t	*pReq;
+	ConfigExtendedPageHeader_t  *pExtHdr = NULL;
 	MPT_FRAME_HDR	*mf;
 	unsigned long	 flags;
 	int		 ii, rc;
-	u32		 flagsLength;
+	int		 flagsLength;
 	int		 in_isr;
 
 	/*	Prevent calling wait_event() (below), if caller happens
@@ -4675,16 +4698,30 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
 	pReq->Reserved = 0;
 	pReq->ChainOffset = 0;
 	pReq->Function = MPI_FUNCTION_CONFIG;
+
+	/* Assume page type is not extended and clear "reserved" fields. */
 	pReq->ExtPageLength = 0;
 	pReq->ExtPageType = 0;
 	pReq->MsgFlags = 0;
+
 	for (ii=0; ii < 8; ii++)
 		pReq->Reserved2[ii] = 0;
 
-	pReq->Header.PageVersion = pCfg->hdr->PageVersion;
-	pReq->Header.PageLength = pCfg->hdr->PageLength;
-	pReq->Header.PageNumber = pCfg->hdr->PageNumber;
-	pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
+	pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
+	pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
+	pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
+	pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
+
+	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
+		pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
+		pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
+		pReq->ExtPageType = pExtHdr->ExtPageType;
+		pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+
+		/* Page Length must be treated as a reserved field for the extended header. */
+		pReq->Header.PageLength = 0;
+	}
+
 	pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
 
 	/* Add a SGE to the config request.
@@ -4694,12 +4731,20 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
 	else
 		flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
 
-	flagsLength |= pCfg->hdr->PageLength * 4;
+	if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
+		flagsLength |= pExtHdr->ExtPageLength * 4;
 
-	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
+		dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
+			ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
+	}
+	else {
+		flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
+
+		dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
+			ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
+	}
 
-	dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
-		ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
+	mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
 
 	/* Append pCfg pointer to end of mf
 	 */
@@ -4789,8 +4834,8 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
 	pReq->Reserved3 = 0;
 	pReq->NumAddressBytes = 0x01;
 	pReq->Reserved4 = 0;
-	pReq->DataLength = 0x04;
-	pdev = (struct pci_dev *) ioc->pcidev;
+	pReq->DataLength = cpu_to_le16(0x04);
+	pdev = ioc->pcidev;
 	if (pdev->devfn & 1)
 		pReq->DeviceAddr = 0xB2;
 	else
@@ -5504,6 +5549,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
 	 *  If needed, send (a single) EventAck.
 	 */
 	if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
+		devtprintk((MYIOC_s_WARN_FMT
+			"EventAck required\n",ioc->name));
 		if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
 			devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
 					ioc->name, ii));
@@ -5584,7 +5631,7 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
 	case 0x00080000:
 		desc = "Outbound DMA Overrun";
 		break;
-	
+
 	case 0x00090000:
 		desc = "Task Management";
 		break;
@@ -5600,7 +5647,7 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
 	case 0x000C0000:
 		desc = "Untagged Table Size";
 		break;
-	
+
 	}
 
 	printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
@@ -5692,7 +5739,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
 		break;
 
 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
-		/* This error is checked in scsi_io_done(). Skip. 
+		/* This error is checked in scsi_io_done(). Skip.
 		desc = "SCSI Data Underrun";
 		*/
 		break;

+ 4 - 1
drivers/message/fusion/mptbase.h

@@ -915,7 +915,10 @@ struct scsi_cmnd;
 typedef struct _x_config_parms {
 	struct list_head	 linkage;	/* linked list */
 	struct timer_list	 timer;		/* timer function for this request  */
-	ConfigPageHeader_t	*hdr;
+	union {
+		ConfigExtendedPageHeader_t	*ehdr;
+		ConfigPageHeader_t	*hdr;
+	} cfghdr;
 	dma_addr_t		 physAddr;
 	int			 wait_done;	/* wait for this request */
 	u32			 pageAddr;	/* properly formatted */

+ 7 - 7
drivers/message/fusion/mptctl.c

@@ -242,7 +242,7 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
 		/* Set the command status to GOOD if IOC Status is GOOD
 		 * OR if SCSI I/O cmd and data underrun or recovered error.
 		 */
-		iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
+		iocStatus = le16_to_cpu(reply->u.reply.IOCStatus) & MPI_IOCSTATUS_MASK;
 		if (iocStatus  == MPI_IOCSTATUS_SUCCESS)
 			ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
 
@@ -2324,7 +2324,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 	hdr.PageLength = 0;
 	hdr.PageNumber = 0;
 	hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
-	cfg.hdr = &hdr;
+	cfg.cfghdr.hdr = &hdr;
 	cfg.physAddr = -1;
 	cfg.pageAddr = 0;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
@@ -2333,7 +2333,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
 
 	strncpy(karg.serial_number, " ", 24);
 	if (mpt_config(ioc, &cfg) == 0) {
-		if (cfg.hdr->PageLength > 0) {
+		if (cfg.cfghdr.hdr->PageLength > 0) {
 			/* Issue the second config page request */
 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
 
@@ -2479,7 +2479,7 @@ mptctl_hp_targetinfo(unsigned long arg)
 		hdr.PageNumber = 0;
 		hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
 
-		cfg.hdr = &hdr;
+		cfg.cfghdr.hdr = &hdr;
 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
 		cfg.dir = 0;
 		cfg.timeout = 0;
@@ -2527,15 +2527,15 @@ mptctl_hp_targetinfo(unsigned long arg)
 	hdr.PageNumber = 3;
 	hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
 
-	cfg.hdr = &hdr;
+	cfg.cfghdr.hdr = &hdr;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;
 	cfg.timeout = 0;
 	cfg.physAddr = -1;
-	if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) {
+	if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
 		/* Issue the second config page request */
 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-		data_sz = (int) cfg.hdr->PageLength * 4;
+		data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
 		pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
 							ioc->pcidev, data_sz, &page_dma);
 		if (pg3_alloc) {

+ 73 - 67
drivers/message/fusion/mptscsih.c

@@ -281,12 +281,12 @@ mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
 		offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
 		chain_idx = offset / ioc->req_sz;
 		rc = SUCCESS;
-		dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
-			ioc->name, *retIndex, chainBuf));
+		dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
+			ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
 	} else {
 		rc = FAILED;
 		chain_idx = MPT_HOST_NO_CHAIN;
-		dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
+		dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
 			ioc->name));
 	}
 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
@@ -432,7 +432,7 @@ nextSGEset:
 			 */
 			pReq->ChainOffset = 0;
 			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
-			dsgprintk((MYIOC_s_ERR_FMT 
+			dsgprintk((MYIOC_s_INFO_FMT
 			    "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
 			ioc->RequestNB[req_idx] = RequestNB;
 		}
@@ -491,11 +491,12 @@ nextSGEset:
 		/* NOTE: psge points to the beginning of the chain element
 		 * in current buffer. Get a chain buffer.
 		 */
-		dsgprintk((MYIOC_s_INFO_FMT 
-		    "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
-		    ioc->name, pReq->CDB[0], SCpnt));
-		if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
+		if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
+			dfailprintk((MYIOC_s_INFO_FMT
+			    "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
+ 			    ioc->name, pReq->CDB[0], SCpnt));
 			return FAILED;
+		}
 
 		/* Update the tracking arrays.
 		 * If chainSge == NULL, update ReqToChain, else ChainToChain
@@ -577,14 +578,20 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 		return 1;
 	}
 
-	dmfprintk((MYIOC_s_INFO_FMT
-		"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
-		ioc->name, mf, mr, sc, req_idx));
-
 	sc->result = DID_OK << 16;		/* Set default reply as OK */
 	pScsiReq = (SCSIIORequest_t *) mf;
 	pScsiReply = (SCSIIOReply_t *) mr;
 
+	if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
+		dmfprintk((MYIOC_s_INFO_FMT
+			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
+			ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
+	}else{
+		dmfprintk((MYIOC_s_INFO_FMT
+			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
+			ioc->name, mf, mr, sc, req_idx));
+	}
+
 	if (pScsiReply == NULL) {
 		/* special context reply handling */
 		;
@@ -658,8 +665,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 				/* Sufficient data transfer occurred */
 				sc->result = (DID_OK << 16) | scsi_status;
 			} else if ( xfer_cnt == 0 ) {
-				/* A CRC Error causes this condition; retry */ 
-				sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | 
+				/* A CRC Error causes this condition; retry */
+				sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
 					(CHECK_CONDITION << 1);
 				sc->sense_buffer[0] = 0x70;
 				sc->sense_buffer[2] = NO_SENSE;
@@ -668,7 +675,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 			} else {
 				sc->result = DID_SOFT_ERROR << 16;
 			}
-			dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
+			dreplyprintk((KERN_NOTICE
+			    "RESIDUAL_MISMATCH: result=%x on id=%d\n",
+			    sc->result, sc->device->id));
 			break;
 
 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
@@ -796,7 +805,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 	return 1;
 }
 
-
 /*
  *	mptscsih_flush_running_cmds - For each command found, search
  *		Scsi_Host instance taskQ and reply to OS.
@@ -1017,7 +1025,7 @@ mptscsih_remove(struct pci_dev *pdev)
 	scsi_host_put(host);
 
 	mpt_detach(pdev);
-	
+
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1072,7 +1080,7 @@ mptscsih_resume(struct pci_dev *pdev)
 	MPT_SCSI_HOST		*hd;
 
 	mpt_resume(pdev);
-	
+
 	if(!host)
 		return 0;
 
@@ -1214,8 +1222,8 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off
 	int size = 0;
 
 	if (func) {
-		/* 
-		 * write is not supported 
+		/*
+		 * write is not supported
 		 */
 	} else {
 		if (start)
@@ -1535,17 +1543,17 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
 	 */
 	if (mptscsih_tm_pending_wait(hd) == FAILED) {
 		if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
-			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
+			dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
 			   "Timed out waiting for last TM (%d) to complete! \n",
 			   hd->ioc->name, hd->tmPending));
 			return FAILED;
 		} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
-			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
+			dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
 			   "Timed out waiting for last TM (%d) to complete! \n",
 			   hd->ioc->name, hd->tmPending));
 			return FAILED;
 		} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
-			dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
+			dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
 			   "Timed out waiting for last TM (%d) to complete! \n",
 			   hd->ioc->name, hd->tmPending));
 			if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
@@ -1631,8 +1639,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
 	if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
 		dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
 				hd->ioc->name));
-		//return FAILED;
-		return -999;
+		return FAILED;
 	}
 	dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
 			hd->ioc->name, mf));
@@ -1661,9 +1668,8 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
 
 	pScsiTm->TaskMsgContext = ctx2abort;
 
-	dtmprintk((MYIOC_s_INFO_FMT
-		"IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
-		hd->ioc->name, ctx2abort, type));
+	dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
+			hd->ioc->name, ctx2abort, type));
 
 	DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
 
@@ -1902,13 +1908,13 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
 
 	/*  If we can't locate the host to reset, then we failed. */
 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
-		dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
+		dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
 			     "Can't locate host! (sc=%p)\n",
 			     SCpnt ) );
 		return FAILED;
 	}
 
-	printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
+	printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
 	       hd->ioc->name, SCpnt);
 
 	/*  If our attempts to reset the host failed, then return a failed
@@ -1924,7 +1930,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
 		hd->tmState = TM_STATE_NONE;
 	}
 
-	dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
+	dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
 		     "Status = %s\n",
 		     (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
 
@@ -1951,8 +1957,8 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
 		if (hd->tmState == TM_STATE_NONE) {
 			hd->tmState = TM_STATE_IN_PROGRESS;
 			hd->tmPending = 1;
-			status = SUCCESS;
 			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+			status = SUCCESS;
 			break;
 		}
 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
@@ -1980,7 +1986,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
 		spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
 		if(hd->tmPending == 0) {
 			status = SUCCESS;
-			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
+ 			spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
 			break;
 		}
 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
@@ -2318,10 +2324,10 @@ mptscsih_slave_configure(struct scsi_device *device)
 	if (pTarget == NULL) {
 		/* Driver doesn't know about this device.
 		 * Kernel may generate a "Dummy Lun 0" which
-		 * may become a real Lun if a 
+		 * may become a real Lun if a
 		 * "scsi add-single-device" command is executed
-		 * while the driver is active (hot-plug a 
-		 * device).  LSI Raid controllers need 
+		 * while the driver is active (hot-plug a
+		 * device).  LSI Raid controllers need
 		 * queue_depth set to DEV_HIGH for this reason.
 		 */
 		scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
@@ -2691,7 +2697,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
 	 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
 	 * (i.e. The targer is capable of supporting the specified peripheral device type
 	 * on this logical unit; however, the physical device is not currently connected
-	 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not 
+	 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
 	 * capable of supporting a physical device on this logical unit). This is to work
 	 * around a bug in th emid-layer in some distributions in which the mid-layer will
 	 * continue to try to communicate to the LUN and evntually create a dummy LUN.
@@ -3194,8 +3200,8 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
 		/* Get a MF for this command.
 		 */
 		if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
-			dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
-						ioc->name));
+			dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
+				ioc->name));
 			return -EAGAIN;
 		}
 
@@ -3289,7 +3295,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
 	/* Get a MF for this command.
 	 */
 	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
-		dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
+		dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
 					ioc->name));
 		return -EAGAIN;
 	}
@@ -3447,7 +3453,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 				 * some type of error occurred.
 				 */
 				MpiRaidActionReply_t	*pr = (MpiRaidActionReply_t *)mr;
-				if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
+				if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
 					completionCode = MPT_SCANDV_GOOD;
 				else
 					completionCode = MPT_SCANDV_SOME_ERROR;
@@ -3955,7 +3961,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
 				header1.PageLength = ioc->spi_data.sdp1length;
 				header1.PageNumber = 1;
 				header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-				cfg.hdr = &header1;
+				cfg.cfghdr.hdr = &header1;
 				cfg.physAddr = cfg1_dma_addr;
 				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
 				cfg.dir = 1;
@@ -3996,9 +4002,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
 			dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
 				"offset=0 negoFlags=%x request=%x config=%x\n",
 				id, flags, requested, configuration));
-			pcfg1Data->RequestedParameters = le32_to_cpu(requested);
+			pcfg1Data->RequestedParameters = cpu_to_le32(requested);
 			pcfg1Data->Reserved = 0;
-			pcfg1Data->Configuration = le32_to_cpu(configuration);
+			pcfg1Data->Configuration = cpu_to_le32(configuration);
 			cfg.pageAddr = (bus<<8) | id;
 			mpt_config(hd->ioc, &cfg);
 		}
@@ -4353,7 +4359,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 	/* Prep cfg structure
 	 */
 	cfg.pageAddr = (bus<<8) | id;
-	cfg.hdr = NULL;
+	cfg.cfghdr.hdr = NULL;
 
 	/* Prep SDP0 header
 	 */
@@ -4399,7 +4405,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 	pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
 	cfg1_dma_addr = dvbuf_dma + sz;
 
-	/* Skip this ID? Set cfg.hdr to force config page write
+	/* Skip this ID? Set cfg.cfghdr.hdr to force config page write
 	 */
 	{
 		ScsiCfgData *pspi_data = &hd->ioc->spi_data;
@@ -4417,7 +4423,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 
 				dv.cmd = MPT_SET_MAX;
 				mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
-				cfg.hdr = &header1;
+				cfg.cfghdr.hdr = &header1;
 
 				/* Save the final negotiated settings to
 				 * SCSI device page 1.
@@ -4483,7 +4489,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 		dv.cmd = MPT_SET_MIN;
 		mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
 
-		cfg.hdr = &header1;
+		cfg.cfghdr.hdr = &header1;
 		cfg.physAddr = cfg1_dma_addr;
 		cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
 		cfg.dir = 1;
@@ -4596,8 +4602,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 				if ((pbuf1[56] & 0x02) == 0) {
 					pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
 					hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
-					ddvprintk((MYIOC_s_NOTE_FMT 
-					    "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", 
+					ddvprintk((MYIOC_s_NOTE_FMT
+					    "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
 					    ioc->name, id, pbuf1[56]));
 				}
 			}
@@ -4637,7 +4643,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 					u32 sdp0_info;
 					u32 sdp0_nego;
 
-					cfg.hdr = &header0;
+					cfg.cfghdr.hdr = &header0;
 					cfg.physAddr = cfg0_dma_addr;
 					cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
 					cfg.dir = 0;
@@ -4673,7 +4679,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 						if (!firstPass)
 							doFallback = 1;
 					} else {
-						ddvprintk((MYIOC_s_NOTE_FMT 
+						ddvprintk((MYIOC_s_NOTE_FMT
 						    "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
 						hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
 						mptscsih_initTarget(hd,
@@ -4689,8 +4695,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 
 			} else if (rc == MPT_SCANDV_ISSUE_SENSE)
 				doFallback = 1;	/* set fallback flag */
-			else if ((rc == MPT_SCANDV_DID_RESET) || 
-				 (rc == MPT_SCANDV_SENSE) || 
+			else if ((rc == MPT_SCANDV_DID_RESET) ||
+				 (rc == MPT_SCANDV_SENSE) ||
 				 (rc == MPT_SCANDV_FALLBACK))
 				doFallback = 1;	/* set fallback flag */
 			else
@@ -4722,7 +4728,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 	 * 4) release
 	 * 5) update nego parms to target struct
 	 */
-	cfg.hdr = &header1;
+	cfg.cfghdr.hdr = &header1;
 	cfg.physAddr = cfg1_dma_addr;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
 	cfg.dir = 1;
@@ -5121,12 +5127,12 @@ target_done:
 
 	/* Set if cfg1_dma_addr contents is valid
 	 */
-	if ((cfg.hdr != NULL) && (retcode == 0)){
+	if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
 		/* If disk, not U320, disable QAS
 		 */
 		if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
 			hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
-			ddvprintk((MYIOC_s_NOTE_FMT 
+			ddvprintk((MYIOC_s_NOTE_FMT
 			    "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
 		}
 
@@ -5137,7 +5143,7 @@ target_done:
 		 * skip save of the final negotiated settings to
 		 * SCSI device page 1.
 		 *
-		cfg.hdr = &header1;
+		cfg.cfghdr.hdr = &header1;
 		cfg.physAddr = cfg1_dma_addr;
 		cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
 		cfg.dir = 1;
@@ -5248,7 +5254,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
 		/* Update tmax values with those from Device Page 0.*/
 		pPage0 = (SCSIDevicePage0_t *) pPage;
 		if (pPage0) {
-			val = cpu_to_le32(pPage0->NegotiatedParameters);
+			val = le32_to_cpu(pPage0->NegotiatedParameters);
 			dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
 			dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
 			dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
@@ -5276,12 +5282,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
 				dv->now.offset, &val, &configuration, dv->now.flags);
 			dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
 				id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
-			pPage1->RequestedParameters = le32_to_cpu(val);
+			pPage1->RequestedParameters = cpu_to_le32(val);
 			pPage1->Reserved = 0;
-			pPage1->Configuration = le32_to_cpu(configuration);
+			pPage1->Configuration = cpu_to_le32(configuration);
 		}
 
-		ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
+		ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
 				id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
 		break;
 
@@ -5301,9 +5307,9 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
 				offset, &val, &configuration, negoFlags);
 			dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
 				id, width, factor, offset, negoFlags, val, configuration));
-			pPage1->RequestedParameters = le32_to_cpu(val);
+			pPage1->RequestedParameters = cpu_to_le32(val);
 			pPage1->Reserved = 0;
-			pPage1->Configuration = le32_to_cpu(configuration);
+			pPage1->Configuration = cpu_to_le32(configuration);
 		}
 		ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
 				id, width, factor, offset, val, configuration, negoFlags));
@@ -5377,12 +5383,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
 		if (pPage1) {
 			mptscsih_setDevicePage1Flags (width, factor, offset, &val,
 						&configuration, dv->now.flags);
-			dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
+			dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
 			     id, width, offset, factor, dv->now.flags, val, configuration));
 
-			pPage1->RequestedParameters = le32_to_cpu(val);
+			pPage1->RequestedParameters = cpu_to_le32(val);
 			pPage1->Reserved = 0;
-			pPage1->Configuration = le32_to_cpu(configuration);
+			pPage1->Configuration = cpu_to_le32(configuration);
 		}
 
 		ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",

+ 3 - 3
drivers/message/fusion/mptspi.c

@@ -162,15 +162,15 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	u8			*mem;
 	int			error=0;
 	int			r;
-	
+
 	if ((r = mpt_attach(pdev,id)) != 0)
 		return r;
-	
+
 	ioc = pci_get_drvdata(pdev);
 	ioc->DoneCtx = mptspiDoneCtx;
 	ioc->TaskCtx = mptspiTaskCtx;
 	ioc->InternalCtx = mptspiInternalCtx;
-	
+
 	/*  Added sanity check on readiness of the MPT adapter.
 	 */
 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {

+ 6 - 0
drivers/scsi/Kconfig

@@ -1,5 +1,11 @@
 menu "SCSI device support"
 
+config RAID_ATTRS
+	tristate "RAID Transport Class"
+	default n
+	---help---
+	  Provides RAID
+
 config SCSI
 	tristate "SCSI device support"
 	---help---

+ 2 - 0
drivers/scsi/Makefile

@@ -22,6 +22,8 @@ subdir-$(CONFIG_PCMCIA)		+= pcmcia
 
 obj-$(CONFIG_SCSI)		+= scsi_mod.o
 
+obj-$(CONFIG_RAID_ATTRS)	+= raid_class.o
+
 # --- NOTE ORDERING HERE ---
 # For kernel non-modular link, transport attributes need to
 # be initialised before drivers

+ 1 - 1
drivers/scsi/aacraid/aachba.c

@@ -972,7 +972,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
 		fibsize = sizeof(struct aac_read64) + 
 			((le32_to_cpu(readcmd->sg.count) - 1) * 
 			 sizeof (struct sgentry64));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size - 
 					sizeof(struct aac_fibhdr)));
 		/*
 		 *	Now send the Fib to the adapter

+ 84 - 12
drivers/scsi/aic7xxx/aic79xx_osm.c

@@ -48,12 +48,6 @@
 
 static struct scsi_transport_template *ahd_linux_transport_template = NULL;
 
-/*
- * Include aiclib.c as part of our
- * "module dependencies are hard" work around.
- */
-#include "aiclib.c"
-
 #include <linux/init.h>		/* __setup */
 #include <linux/mm.h>		/* For fetching system memory size */
 #include <linux/blkdev.h>		/* For block_size() */
@@ -372,8 +366,6 @@ static int ahd_linux_run_command(struct ahd_softc*,
 				 struct ahd_linux_device *,
 				 struct scsi_cmnd *);
 static void ahd_linux_setup_tag_info_global(char *p);
-static aic_option_callback_t ahd_linux_setup_tag_info;
-static aic_option_callback_t ahd_linux_setup_iocell_info;
 static int  aic79xx_setup(char *c);
 
 static int ahd_linux_unit;
@@ -907,6 +899,86 @@ ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
 	}
 }
 
+static char *
+ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
+		       void (*callback)(u_long, int, int, int32_t),
+		       u_long callback_arg)
+{
+	char	*tok_end;
+	char	*tok_end2;
+	int      i;
+	int      instance;
+	int	 targ;
+	int	 done;
+	char	 tok_list[] = {'.', ',', '{', '}', '\0'};
+
+	/* All options use a ':' name/arg separator */
+	if (*opt_arg != ':')
+		return (opt_arg);
+	opt_arg++;
+	instance = -1;
+	targ = -1;
+	done = FALSE;
+	/*
+	 * Restore separator that may be in
+	 * the middle of our option argument.
+	 */
+	tok_end = strchr(opt_arg, '\0');
+	if (tok_end < end)
+		*tok_end = ',';
+	while (!done) {
+		switch (*opt_arg) {
+		case '{':
+			if (instance == -1) {
+				instance = 0;
+			} else {
+				if (depth > 1) {
+					if (targ == -1)
+						targ = 0;
+				} else {
+					printf("Malformed Option %s\n",
+					       opt_name);
+					done = TRUE;
+				}
+			}
+			opt_arg++;
+			break;
+		case '}':
+			if (targ != -1)
+				targ = -1;
+			else if (instance != -1)
+				instance = -1;
+			opt_arg++;
+			break;
+		case ',':
+		case '.':
+			if (instance == -1)
+				done = TRUE;
+			else if (targ >= 0)
+				targ++;
+			else if (instance >= 0)
+				instance++;
+			opt_arg++;
+			break;
+		case '\0':
+			done = TRUE;
+			break;
+		default:
+			tok_end = end;
+			for (i = 0; tok_list[i]; i++) {
+				tok_end2 = strchr(opt_arg, tok_list[i]);
+				if ((tok_end2) && (tok_end2 < tok_end))
+					tok_end = tok_end2;
+			}
+			callback(callback_arg, instance, targ,
+				 simple_strtol(opt_arg, NULL, 0));
+			opt_arg = tok_end;
+			break;
+		}
+	}
+	return (opt_arg);
+}
+
 /*
  * Handle Linux boot parameters. This routine allows for assigning a value
  * to a parameter with a ':' between the parameter and the value.
@@ -964,18 +1036,18 @@ aic79xx_setup(char *s)
 		if (strncmp(p, "global_tag_depth", n) == 0) {
 			ahd_linux_setup_tag_info_global(p + n);
 		} else if (strncmp(p, "tag_info", n) == 0) {
-			s = aic_parse_brace_option("tag_info", p + n, end,
+			s = ahd_parse_brace_option("tag_info", p + n, end,
 			    2, ahd_linux_setup_tag_info, 0);
 		} else if (strncmp(p, "slewrate", n) == 0) {
-			s = aic_parse_brace_option("slewrate",
+			s = ahd_parse_brace_option("slewrate",
 			    p + n, end, 1, ahd_linux_setup_iocell_info,
 			    AIC79XX_SLEWRATE_INDEX);
 		} else if (strncmp(p, "precomp", n) == 0) {
-			s = aic_parse_brace_option("precomp",
+			s = ahd_parse_brace_option("precomp",
 			    p + n, end, 1, ahd_linux_setup_iocell_info,
 			    AIC79XX_PRECOMP_INDEX);
 		} else if (strncmp(p, "amplitude", n) == 0) {
-			s = aic_parse_brace_option("amplitude",
+			s = ahd_parse_brace_option("amplitude",
 			    p + n, end, 1, ahd_linux_setup_iocell_info,
 			    AIC79XX_AMPLITUDE_INDEX);
 		} else if (p[n] == ':') {

+ 44 - 1
drivers/scsi/aic7xxx/aic79xx_proc.c

@@ -53,6 +53,49 @@ static void	ahd_dump_device_state(struct info_str *info,
 static int	ahd_proc_write_seeprom(struct ahd_softc *ahd,
 				       char *buffer, int length);
 
+/*
+ * Table of syncrates that don't follow the "divisible by 4"
+ * rule. This table will be expanded in future SCSI specs.
+ */
+static struct {
+	u_int period_factor;
+	u_int period;	/* in 100ths of ns */
+} scsi_syncrates[] = {
+	{ 0x08, 625 },	/* FAST-160 */
+	{ 0x09, 1250 },	/* FAST-80 */
+	{ 0x0a, 2500 },	/* FAST-40 40MHz */
+	{ 0x0b, 3030 },	/* FAST-40 33MHz */
+	{ 0x0c, 5000 }	/* FAST-20 */
+};
+
+/*
+ * Return the frequency in kHz corresponding to the given
+ * sync period factor.
+ */
+static u_int
+ahd_calc_syncsrate(u_int period_factor)
+{
+	int i;
+	int num_syncrates;
+
+	num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
+	/* See if the period is in the "exception" table */
+	for (i = 0; i < num_syncrates; i++) {
+
+		if (period_factor == scsi_syncrates[i].period_factor) {
+			/* Period in kHz */
+			return (100000000 / scsi_syncrates[i].period);
+		}
+	}
+
+	/*
+	 * Wasn't in the table, so use the standard
+	 * 4 times conversion.
+	 */
+	return (10000000 / (period_factor * 4 * 10));
+}
+
+
 static void
 copy_mem_info(struct info_str *info, char *data, int len)
 {
@@ -109,7 +152,7 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo)
         speed = 3300;
         freq = 0;
 	if (tinfo->offset != 0) {
-		freq = aic_calc_syncsrate(tinfo->period);
+		freq = ahd_calc_syncsrate(tinfo->period);
 		speed = freq;
 	}
 	speed *= (0x01 << tinfo->width);

+ 81 - 8
drivers/scsi/aic7xxx/aic7xxx_osm.c

@@ -125,12 +125,6 @@
 
 static struct scsi_transport_template *ahc_linux_transport_template = NULL;
 
-/*
- * Include aiclib.c as part of our
- * "module dependencies are hard" work around.
- */
-#include "aiclib.c"
-
 #include <linux/init.h>		/* __setup */
 #include <linux/mm.h>		/* For fetching system memory size */
 #include <linux/blkdev.h>		/* For block_size() */
@@ -391,7 +385,6 @@ static int ahc_linux_run_command(struct ahc_softc*,
 				 struct ahc_linux_device *,
 				 struct scsi_cmnd *);
 static void ahc_linux_setup_tag_info_global(char *p);
-static aic_option_callback_t ahc_linux_setup_tag_info;
 static int  aic7xxx_setup(char *s);
 
 static int ahc_linux_unit;
@@ -920,6 +913,86 @@ ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
 	}
 }
 
+static char *
+ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
+		       void (*callback)(u_long, int, int, int32_t),
+		       u_long callback_arg)
+{
+	char	*tok_end;
+	char	*tok_end2;
+	int      i;
+	int      instance;
+	int	 targ;
+	int	 done;
+	char	 tok_list[] = {'.', ',', '{', '}', '\0'};
+
+	/* All options use a ':' name/arg separator */
+	if (*opt_arg != ':')
+		return (opt_arg);
+	opt_arg++;
+	instance = -1;
+	targ = -1;
+	done = FALSE;
+	/*
+	 * Restore separator that may be in
+	 * the middle of our option argument.
+	 */
+	tok_end = strchr(opt_arg, '\0');
+	if (tok_end < end)
+		*tok_end = ',';
+	while (!done) {
+		switch (*opt_arg) {
+		case '{':
+			if (instance == -1) {
+				instance = 0;
+			} else {
+				if (depth > 1) {
+					if (targ == -1)
+						targ = 0;
+				} else {
+					printf("Malformed Option %s\n",
+					       opt_name);
+					done = TRUE;
+				}
+			}
+			opt_arg++;
+			break;
+		case '}':
+			if (targ != -1)
+				targ = -1;
+			else if (instance != -1)
+				instance = -1;
+			opt_arg++;
+			break;
+		case ',':
+		case '.':
+			if (instance == -1)
+				done = TRUE;
+			else if (targ >= 0)
+				targ++;
+			else if (instance >= 0)
+				instance++;
+			opt_arg++;
+			break;
+		case '\0':
+			done = TRUE;
+			break;
+		default:
+			tok_end = end;
+			for (i = 0; tok_list[i]; i++) {
+				tok_end2 = strchr(opt_arg, tok_list[i]);
+				if ((tok_end2) && (tok_end2 < tok_end))
+					tok_end = tok_end2;
+			}
+			callback(callback_arg, instance, targ,
+				 simple_strtol(opt_arg, NULL, 0));
+			opt_arg = tok_end;
+			break;
+		}
+	}
+	return (opt_arg);
+}
+
 /*
  * Handle Linux boot parameters. This routine allows for assigning a value
  * to a parameter with a ':' between the parameter and the value.
@@ -974,7 +1047,7 @@ aic7xxx_setup(char *s)
 		if (strncmp(p, "global_tag_depth", n) == 0) {
 			ahc_linux_setup_tag_info_global(p + n);
 		} else if (strncmp(p, "tag_info", n) == 0) {
-			s = aic_parse_brace_option("tag_info", p + n, end,
+			s = ahc_parse_brace_option("tag_info", p + n, end,
 			    2, ahc_linux_setup_tag_info, 0);
 		} else if (p[n] == ':') {
 			*(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);

+ 44 - 1
drivers/scsi/aic7xxx/aic7xxx_proc.c

@@ -54,6 +54,49 @@ static void	ahc_dump_device_state(struct info_str *info,
 static int	ahc_proc_write_seeprom(struct ahc_softc *ahc,
 				       char *buffer, int length);
 
+/*
+ * Table of syncrates that don't follow the "divisible by 4"
+ * rule. This table will be expanded in future SCSI specs.
+ */
+static struct {
+	u_int period_factor;
+	u_int period;	/* in 100ths of ns */
+} scsi_syncrates[] = {
+	{ 0x08, 625 },	/* FAST-160 */
+	{ 0x09, 1250 },	/* FAST-80 */
+	{ 0x0a, 2500 },	/* FAST-40 40MHz */
+	{ 0x0b, 3030 },	/* FAST-40 33MHz */
+	{ 0x0c, 5000 }	/* FAST-20 */
+};
+
+/*
+ * Return the frequency in kHz corresponding to the given
+ * sync period factor.
+ */
+static u_int
+ahc_calc_syncsrate(u_int period_factor)
+{
+	int i;
+	int num_syncrates;
+
+	num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
+	/* See if the period is in the "exception" table */
+	for (i = 0; i < num_syncrates; i++) {
+
+		if (period_factor == scsi_syncrates[i].period_factor) {
+			/* Period in kHz */
+			return (100000000 / scsi_syncrates[i].period);
+		}
+	}
+
+	/*
+	 * Wasn't in the table, so use the standard
+	 * 4 times conversion.
+	 */
+	return (10000000 / (period_factor * 4 * 10));
+}
+
+
 static void
 copy_mem_info(struct info_str *info, char *data, int len)
 {
@@ -106,7 +149,7 @@ ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo)
         speed = 3300;
         freq = 0;
 	if (tinfo->offset != 0) {
-		freq = aic_calc_syncsrate(tinfo->period);
+		freq = ahc_calc_syncsrate(tinfo->period);
 		speed = freq;
 	}
 	speed *= (0x01 << tinfo->width);

+ 0 - 121
drivers/scsi/aic7xxx/aiclib.c

@@ -32,124 +32,3 @@
 
 #include "aiclib.h"
 
-
-/*
- * Table of syncrates that don't follow the "divisible by 4"
- * rule. This table will be expanded in future SCSI specs.
- */
-static struct {
-	u_int period_factor;
-	u_int period;	/* in 100ths of ns */
-} scsi_syncrates[] = {
-	{ 0x08, 625 },	/* FAST-160 */
-	{ 0x09, 1250 },	/* FAST-80 */
-	{ 0x0a, 2500 },	/* FAST-40 40MHz */
-	{ 0x0b, 3030 },	/* FAST-40 33MHz */
-	{ 0x0c, 5000 }	/* FAST-20 */
-};
-
-/*
- * Return the frequency in kHz corresponding to the given
- * sync period factor.
- */
-u_int
-aic_calc_syncsrate(u_int period_factor)
-{
-	int i;
-	int num_syncrates;
-
-	num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
-	/* See if the period is in the "exception" table */
-	for (i = 0; i < num_syncrates; i++) {
-
-		if (period_factor == scsi_syncrates[i].period_factor) {
-			/* Period in kHz */
-			return (100000000 / scsi_syncrates[i].period);
-		}
-	}
-
-	/*
-	 * Wasn't in the table, so use the standard
-	 * 4 times conversion.
-	 */
-	return (10000000 / (period_factor * 4 * 10));
-}
-
-char *
-aic_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
-		       aic_option_callback_t *callback, u_long callback_arg)
-{
-	char	*tok_end;
-	char	*tok_end2;
-	int      i;
-	int      instance;
-	int	 targ;
-	int	 done;
-	char	 tok_list[] = {'.', ',', '{', '}', '\0'};
-
-	/* All options use a ':' name/arg separator */
-	if (*opt_arg != ':')
-		return (opt_arg);
-	opt_arg++;
-	instance = -1;
-	targ = -1;
-	done = FALSE;
-	/*
-	 * Restore separator that may be in
-	 * the middle of our option argument.
-	 */
-	tok_end = strchr(opt_arg, '\0');
-	if (tok_end < end)
-		*tok_end = ',';
-	while (!done) {
-		switch (*opt_arg) {
-		case '{':
-			if (instance == -1) {
-				instance = 0;
-			} else {
-				if (depth > 1) {
-					if (targ == -1)
-						targ = 0;
-				} else {
-					printf("Malformed Option %s\n",
-					       opt_name);
-					done = TRUE;
-				}
-			}
-			opt_arg++;
-			break;
-		case '}':
-			if (targ != -1)
-				targ = -1;
-			else if (instance != -1)
-				instance = -1;
-			opt_arg++;
-			break;
-		case ',':
-		case '.':
-			if (instance == -1)
-				done = TRUE;
-			else if (targ >= 0)
-				targ++;
-			else if (instance >= 0)
-				instance++;
-			opt_arg++;
-			break;
-		case '\0':
-			done = TRUE;
-			break;
-		default:
-			tok_end = end;
-			for (i = 0; tok_list[i]; i++) {
-				tok_end2 = strchr(opt_arg, tok_list[i]);
-				if ((tok_end2) && (tok_end2 < tok_end))
-					tok_end = tok_end2;
-			}
-			callback(callback_arg, instance, targ,
-				 simple_strtol(opt_arg, NULL, 0));
-			opt_arg = tok_end;
-			break;
-		}
-	}
-	return (opt_arg);
-}

+ 0 - 22
drivers/scsi/aic7xxx/aiclib.h

@@ -141,28 +141,6 @@ aic_sector_div(sector_t capacity, int heads, int sectors)
 	return (int)capacity;
 }
 
-/**************************** Module Library Hack *****************************/
-/*
- * What we'd like to do is have a single "scsi library" module that both the
- * aic7xxx and aic79xx drivers could load and depend on.  A cursory examination
- * of implementing module dependencies in Linux (handling the install and
- * initrd cases) does not look promissing.  For now, we just duplicate this
- * code in both drivers using a simple symbol renaming scheme that hides this
- * hack from the drivers.
- */
-#define AIC_LIB_ENTRY_CONCAT(x, prefix)	prefix ## x
-#define	AIC_LIB_ENTRY_EXPAND(x, prefix) AIC_LIB_ENTRY_CONCAT(x, prefix)
-#define AIC_LIB_ENTRY(x)		AIC_LIB_ENTRY_EXPAND(x, AIC_LIB_PREFIX)
-
-#define aic_calc_syncsrate		AIC_LIB_ENTRY(_calc_syncrate)
-
-u_int		aic_calc_syncsrate(u_int /*period_factor*/);
-
-typedef void aic_option_callback_t(u_long, int, int, int32_t);
-char *		aic_parse_brace_option(char *opt_name, char *opt_arg,
-				       char *end, int depth,
-				       aic_option_callback_t *, u_long);
-
 static __inline uint32_t
 scsi_4btoul(uint8_t *bytes)
 {

+ 8 - 15
drivers/scsi/hosts.c

@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/blkdev.h>
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/init.h>
@@ -225,15 +226,8 @@ static void scsi_host_dev_release(struct device *dev)
 	struct Scsi_Host *shost = dev_to_shost(dev);
 	struct device *parent = dev->parent;
 
-	if (shost->ehandler) {
-		DECLARE_COMPLETION(sem);
-		shost->eh_notify = &sem;
-		shost->eh_kill = 1;
-		up(shost->eh_wait);
-		wait_for_completion(&sem);
-		shost->eh_notify = NULL;
-	}
-
+	if (shost->ehandler)
+		kthread_stop(shost->ehandler);
 	if (shost->work_q)
 		destroy_workqueue(shost->work_q);
 
@@ -263,7 +257,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 {
 	struct Scsi_Host *shost;
 	int gfp_mask = GFP_KERNEL, rval;
-	DECLARE_COMPLETION(complete);
 
 	if (sht->unchecked_isa_dma && privsize)
 		gfp_mask |= __GFP_DMA;
@@ -369,12 +362,12 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 	snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d",
 		  shost->host_no);
 
-	shost->eh_notify = &complete;
-	rval = kernel_thread(scsi_error_handler, shost, 0);
-	if (rval < 0)
+	shost->ehandler = kthread_run(scsi_error_handler, shost,
+			"scsi_eh_%d", shost->host_no);
+	if (IS_ERR(shost->ehandler)) {
+		rval = PTR_ERR(shost->ehandler);
 		goto fail_destroy_freelist;
-	wait_for_completion(&complete);
-	shost->eh_notify = NULL;
+	}
 
 	scsi_proc_hostdir_add(shost->hostt);
 	return shost;

+ 114 - 42
drivers/scsi/ibmvscsi/ibmvscsi.c

@@ -87,7 +87,7 @@ static int max_channel = 3;
 static int init_timeout = 5;
 static int max_requests = 50;
 
-#define IBMVSCSI_VERSION "1.5.6"
+#define IBMVSCSI_VERSION "1.5.7"
 
 MODULE_DESCRIPTION("IBM Virtual SCSI");
 MODULE_AUTHOR("Dave Boutcher");
@@ -145,6 +145,8 @@ static int initialize_event_pool(struct event_pool *pool,
 			sizeof(*evt->xfer_iu) * i;
 		evt->xfer_iu = pool->iu_storage + i;
 		evt->hostdata = hostdata;
+		evt->ext_list = NULL;
+		evt->ext_list_token = 0;
 	}
 
 	return 0;
@@ -161,9 +163,16 @@ static void release_event_pool(struct event_pool *pool,
 			       struct ibmvscsi_host_data *hostdata)
 {
 	int i, in_use = 0;
-	for (i = 0; i < pool->size; ++i)
+	for (i = 0; i < pool->size; ++i) {
 		if (atomic_read(&pool->events[i].free) != 1)
 			++in_use;
+		if (pool->events[i].ext_list) {
+			dma_free_coherent(hostdata->dev,
+				  SG_ALL * sizeof(struct memory_descriptor),
+				  pool->events[i].ext_list,
+				  pool->events[i].ext_list_token);
+		}
+	}
 	if (in_use)
 		printk(KERN_WARNING
 		       "ibmvscsi: releasing event pool with %d "
@@ -286,24 +295,41 @@ static void set_srp_direction(struct scsi_cmnd *cmd,
 	} else {
 		if (cmd->sc_data_direction == DMA_TO_DEVICE) {
 			srp_cmd->data_out_format = SRP_INDIRECT_BUFFER;
-			srp_cmd->data_out_count = numbuf;
+			srp_cmd->data_out_count =
+				numbuf < MAX_INDIRECT_BUFS ?
+					numbuf: MAX_INDIRECT_BUFS;
 		} else {
 			srp_cmd->data_in_format = SRP_INDIRECT_BUFFER;
-			srp_cmd->data_in_count = numbuf;
+			srp_cmd->data_in_count =
+				numbuf < MAX_INDIRECT_BUFS ?
+					numbuf: MAX_INDIRECT_BUFS;
 		}
 	}
 }
 
+static void unmap_sg_list(int num_entries, 
+		struct device *dev,
+		struct memory_descriptor *md)
+{ 
+	int i;
+
+	for (i = 0; i < num_entries; ++i) {
+		dma_unmap_single(dev,
+			md[i].virtual_address,
+			md[i].length, DMA_BIDIRECTIONAL);
+	}
+}
+
 /**
  * unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format
  * @cmd:	srp_cmd whose additional_data member will be unmapped
  * @dev:	device for which the memory is mapped
  *
 */
-static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev)
+static void unmap_cmd_data(struct srp_cmd *cmd,
+			   struct srp_event_struct *evt_struct,
+			   struct device *dev)
 {
-	int i;
-
 	if ((cmd->data_out_format == SRP_NO_BUFFER) &&
 	    (cmd->data_in_format == SRP_NO_BUFFER))
 		return;
@@ -318,15 +344,34 @@ static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev)
 			(struct indirect_descriptor *)cmd->additional_data;
 		int num_mapped = indirect->head.length / 
 			sizeof(indirect->list[0]);
-		for (i = 0; i < num_mapped; ++i) {
-			struct memory_descriptor *data = &indirect->list[i];
-			dma_unmap_single(dev,
-					 data->virtual_address,
-					 data->length, DMA_BIDIRECTIONAL);
+
+		if (num_mapped <= MAX_INDIRECT_BUFS) {
+			unmap_sg_list(num_mapped, dev, &indirect->list[0]);
+			return;
 		}
+
+		unmap_sg_list(num_mapped, dev, evt_struct->ext_list);
 	}
 }
 
+static int map_sg_list(int num_entries, 
+		       struct scatterlist *sg,
+		       struct memory_descriptor *md)
+{
+	int i;
+	u64 total_length = 0;
+
+	for (i = 0; i < num_entries; ++i) {
+		struct memory_descriptor *descr = md + i;
+		struct scatterlist *sg_entry = &sg[i];
+		descr->virtual_address = sg_dma_address(sg_entry);
+		descr->length = sg_dma_len(sg_entry);
+		descr->memory_handle = 0;
+		total_length += sg_dma_len(sg_entry);
+ 	}
+	return total_length;
+}
+
 /**
  * map_sg_data: - Maps dma for a scatterlist and initializes decriptor fields
  * @cmd:	Scsi_Cmnd with the scatterlist
@@ -337,10 +382,11 @@ static void unmap_cmd_data(struct srp_cmd *cmd, struct device *dev)
  * Returns 1 on success.
 */
 static int map_sg_data(struct scsi_cmnd *cmd,
+		       struct srp_event_struct *evt_struct,
 		       struct srp_cmd *srp_cmd, struct device *dev)
 {
 
-	int i, sg_mapped;
+	int sg_mapped;
 	u64 total_length = 0;
 	struct scatterlist *sg = cmd->request_buffer;
 	struct memory_descriptor *data =
@@ -363,27 +409,46 @@ static int map_sg_data(struct scsi_cmnd *cmd,
 		return 1;
 	}
 
-	if (sg_mapped > MAX_INDIRECT_BUFS) {
+	if (sg_mapped > SG_ALL) {
 		printk(KERN_ERR
 		       "ibmvscsi: More than %d mapped sg entries, got %d\n",
-		       MAX_INDIRECT_BUFS, sg_mapped);
+		       SG_ALL, sg_mapped);
 		return 0;
 	}
 
 	indirect->head.virtual_address = 0;
 	indirect->head.length = sg_mapped * sizeof(indirect->list[0]);
 	indirect->head.memory_handle = 0;
-	for (i = 0; i < sg_mapped; ++i) {
-		struct memory_descriptor *descr = &indirect->list[i];
-		struct scatterlist *sg_entry = &sg[i];
-		descr->virtual_address = sg_dma_address(sg_entry);
-		descr->length = sg_dma_len(sg_entry);
-		descr->memory_handle = 0;
-		total_length += sg_dma_len(sg_entry);
+
+	if (sg_mapped <= MAX_INDIRECT_BUFS) {
+		total_length = map_sg_list(sg_mapped, sg, &indirect->list[0]);
+		indirect->total_length = total_length;
+		return 1;
 	}
-	indirect->total_length = total_length;
 
-	return 1;
+	/* get indirect table */
+	if (!evt_struct->ext_list) {
+		evt_struct->ext_list =(struct memory_descriptor*)
+			dma_alloc_coherent(dev, 
+				SG_ALL * sizeof(struct memory_descriptor),
+				&evt_struct->ext_list_token, 0);
+		if (!evt_struct->ext_list) {
+		    printk(KERN_ERR
+		   	"ibmvscsi: Can't allocate memory for indirect table\n");
+			return 0;
+			
+		}
+	}
+
+	total_length = map_sg_list(sg_mapped, sg, evt_struct->ext_list);	
+
+	indirect->total_length = total_length;
+	indirect->head.virtual_address = evt_struct->ext_list_token;
+	indirect->head.length = sg_mapped * sizeof(indirect->list[0]);
+	memcpy(indirect->list, evt_struct->ext_list,
+		MAX_INDIRECT_BUFS * sizeof(struct memory_descriptor));
+	
+ 	return 1;
 }
 
 /**
@@ -428,6 +493,7 @@ static int map_single_data(struct scsi_cmnd *cmd,
  * Returns 1 on success.
 */
 static int map_data_for_srp_cmd(struct scsi_cmnd *cmd,
+				struct srp_event_struct *evt_struct,
 				struct srp_cmd *srp_cmd, struct device *dev)
 {
 	switch (cmd->sc_data_direction) {
@@ -450,7 +516,7 @@ static int map_data_for_srp_cmd(struct scsi_cmnd *cmd,
 	if (!cmd->request_buffer)
 		return 1;
 	if (cmd->use_sg)
-		return map_sg_data(cmd, srp_cmd, dev);
+		return map_sg_data(cmd, evt_struct, srp_cmd, dev);
 	return map_single_data(cmd, srp_cmd, dev);
 }
 
@@ -486,6 +552,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
 		printk(KERN_WARNING 
 		       "ibmvscsi: Warning, request_limit exceeded\n");
 		unmap_cmd_data(&evt_struct->iu.srp.cmd,
+			       evt_struct,
 			       hostdata->dev);
 		free_event_struct(&hostdata->pool, evt_struct);
 		return SCSI_MLQUEUE_HOST_BUSY;
@@ -513,7 +580,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
 	return 0;
 
  send_error:
-	unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev);
+	unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
 
 	if ((cmnd = evt_struct->cmnd) != NULL) {
 		cmnd->result = DID_ERROR << 16;
@@ -551,6 +618,7 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct)
 			       rsp->sense_and_response_data,
 			       rsp->sense_data_list_length);
 		unmap_cmd_data(&evt_struct->iu.srp.cmd, 
+			       evt_struct, 
 			       evt_struct->hostdata->dev);
 
 		if (rsp->doover)
@@ -583,6 +651,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
 {
 	struct srp_cmd *srp_cmd;
 	struct srp_event_struct *evt_struct;
+	struct indirect_descriptor *indirect;
 	struct ibmvscsi_host_data *hostdata =
 		(struct ibmvscsi_host_data *)&cmnd->device->host->hostdata;
 	u16 lun = lun_from_dev(cmnd->device);
@@ -591,14 +660,6 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
 	if (!evt_struct)
 		return SCSI_MLQUEUE_HOST_BUSY;
 
-	init_event_struct(evt_struct,
-			  handle_cmd_rsp,
-			  VIOSRP_SRP_FORMAT,
-			  cmnd->timeout_per_command/HZ);
-
-	evt_struct->cmnd = cmnd;
-	evt_struct->cmnd_done = done;
-
 	/* Set up the actual SRP IU */
 	srp_cmd = &evt_struct->iu.srp.cmd;
 	memset(srp_cmd, 0x00, sizeof(*srp_cmd));
@@ -606,17 +667,25 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
 	memcpy(srp_cmd->cdb, cmnd->cmnd, sizeof(cmnd->cmnd));
 	srp_cmd->lun = ((u64) lun) << 48;
 
-	if (!map_data_for_srp_cmd(cmnd, srp_cmd, hostdata->dev)) {
+	if (!map_data_for_srp_cmd(cmnd, evt_struct, srp_cmd, hostdata->dev)) {
 		printk(KERN_ERR "ibmvscsi: couldn't convert cmd to srp_cmd\n");
 		free_event_struct(&hostdata->pool, evt_struct);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
+	init_event_struct(evt_struct,
+			  handle_cmd_rsp,
+			  VIOSRP_SRP_FORMAT,
+			  cmnd->timeout_per_command/HZ);
+
+	evt_struct->cmnd = cmnd;
+	evt_struct->cmnd_done = done;
+
 	/* Fix up dma address of the buffer itself */
-	if ((srp_cmd->data_out_format == SRP_INDIRECT_BUFFER) ||
-	    (srp_cmd->data_in_format == SRP_INDIRECT_BUFFER)) {
-		struct indirect_descriptor *indirect =
-		    (struct indirect_descriptor *)srp_cmd->additional_data;
+	indirect = (struct indirect_descriptor *)srp_cmd->additional_data;
+	if (((srp_cmd->data_out_format == SRP_INDIRECT_BUFFER) ||
+	    (srp_cmd->data_in_format == SRP_INDIRECT_BUFFER)) &&
+	    (indirect->head.virtual_address == 0)) {
 		indirect->head.virtual_address = evt_struct->crq.IU_data_ptr +
 		    offsetof(struct srp_cmd, additional_data) +
 		    offsetof(struct indirect_descriptor, list);
@@ -931,7 +1000,8 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
 
 	cmd->result = (DID_ABORT << 16);
 	list_del(&found_evt->list);
-	unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt->hostdata->dev);
+	unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt,
+		       found_evt->hostdata->dev);
 	free_event_struct(&found_evt->hostdata->pool, found_evt);
 	spin_unlock_irqrestore(hostdata->host->host_lock, flags);
 	atomic_inc(&hostdata->request_limit);
@@ -1023,7 +1093,8 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
 			if (tmp_evt->cmnd)
 				tmp_evt->cmnd->result = (DID_RESET << 16);
 			list_del(&tmp_evt->list);
-			unmap_cmd_data(&tmp_evt->iu.srp.cmd, tmp_evt->hostdata->dev);
+			unmap_cmd_data(&tmp_evt->iu.srp.cmd, tmp_evt,
+				       tmp_evt->hostdata->dev);
 			free_event_struct(&tmp_evt->hostdata->pool,
 						   tmp_evt);
 			atomic_inc(&hostdata->request_limit);
@@ -1052,6 +1123,7 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata)
 		if (tmp_evt->cmnd) {
 			tmp_evt->cmnd->result = (DID_ERROR << 16);
 			unmap_cmd_data(&tmp_evt->iu.srp.cmd, 
+				       tmp_evt,	
 				       tmp_evt->hostdata->dev);
 			if (tmp_evt->cmnd_done)
 				tmp_evt->cmnd_done(tmp_evt->cmnd);
@@ -1356,7 +1428,7 @@ static struct scsi_host_template driver_template = {
 	.cmd_per_lun = 16,
 	.can_queue = 1,		/* Updated after SRP_LOGIN */
 	.this_id = -1,
-	.sg_tablesize = MAX_INDIRECT_BUFS,
+	.sg_tablesize = SG_ALL,
 	.use_clustering = ENABLE_CLUSTERING,
 	.shost_attrs = ibmvscsi_attrs,
 };

+ 2 - 0
drivers/scsi/ibmvscsi/ibmvscsi.h

@@ -68,6 +68,8 @@ struct srp_event_struct {
 	void (*cmnd_done) (struct scsi_cmnd *);
 	struct completion comp;
 	union viosrp_iu *sync_srp;
+	struct memory_descriptor *ext_list;
+	dma_addr_t ext_list_token;
 };
 
 /* a pool of event structs for use */

+ 136 - 0
drivers/scsi/qla2xxx/qla_attr.c

@@ -211,6 +211,138 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
 	sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
 }
 
+/* Scsi_Host attributes. */
+
+static ssize_t
+qla2x00_drvr_version_show(struct class_device *cdev, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
+}
+
+static ssize_t
+qla2x00_fw_version_show(struct class_device *cdev, char *buf)
+{
+	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+	char fw_str[30];
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+	    ha->isp_ops.fw_version_str(ha, fw_str));
+}
+
+static ssize_t
+qla2x00_serial_num_show(struct class_device *cdev, char *buf)
+{
+	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+	uint32_t sn;
+
+	sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
+	return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,
+	    sn % 100000);
+}
+
+static ssize_t
+qla2x00_isp_name_show(struct class_device *cdev, char *buf)
+{
+	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+	return snprintf(buf, PAGE_SIZE, "%s\n", ha->brd_info->isp_name);
+}
+
+static ssize_t
+qla2x00_isp_id_show(struct class_device *cdev, char *buf)
+{
+	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+	return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
+	    ha->product_id[0], ha->product_id[1], ha->product_id[2],
+	    ha->product_id[3]);
+}
+
+static ssize_t
+qla2x00_model_name_show(struct class_device *cdev, char *buf)
+{
+	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+	return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number);
+}
+
+static ssize_t
+qla2x00_model_desc_show(struct class_device *cdev, char *buf)
+{
+	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+	    ha->model_desc ? ha->model_desc: "");
+}
+
+static ssize_t
+qla2x00_pci_info_show(struct class_device *cdev, char *buf)
+{
+	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+	char pci_info[30];
+
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+	    ha->isp_ops.pci_info_str(ha, pci_info));
+}
+
+static ssize_t
+qla2x00_state_show(struct class_device *cdev, char *buf)
+{
+	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+	int len = 0;
+
+	if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
+	    atomic_read(&ha->loop_state) == LOOP_DEAD)
+		len = snprintf(buf, PAGE_SIZE, "Link Down\n");
+	else if (atomic_read(&ha->loop_state) != LOOP_READY ||
+	    test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||
+	    test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags))
+		len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
+	else {
+		len = snprintf(buf, PAGE_SIZE, "Link Up - ");
+
+		switch (ha->current_topology) {
+		case ISP_CFG_NL:
+			len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
+			break;
+		case ISP_CFG_FL:
+			len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n");
+			break;
+		case ISP_CFG_N:
+			len += snprintf(buf + len, PAGE_SIZE-len,
+			    "N_Port to N_Port\n");
+			break;
+		case ISP_CFG_F:
+			len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n");
+			break;
+		default:
+			len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n");
+			break;
+		}
+	}
+	return len;
+}
+
+static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,
+	NULL);
+static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
+static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
+static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL);
+static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL);
+static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL);
+static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL);
+static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL);
+static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL);
+
+struct class_device_attribute *qla2x00_host_attrs[] = {
+	&class_device_attr_driver_version,
+	&class_device_attr_fw_version,
+	&class_device_attr_serial_num,
+	&class_device_attr_isp_name,
+	&class_device_attr_isp_id,
+	&class_device_attr_model_name,
+	&class_device_attr_model_desc,
+	&class_device_attr_pci_info,
+	&class_device_attr_state,
+	NULL,
+};
+
 /* Host attributes. */
 
 static void
@@ -304,10 +436,13 @@ struct fc_function_template qla2xxx_transport_functions = {
 
 	.show_host_node_name = 1,
 	.show_host_port_name = 1,
+	.show_host_supported_classes = 1,
+
 	.get_host_port_id = qla2x00_get_host_port_id,
 	.show_host_port_id = 1,
 
 	.dd_fcrport_size = sizeof(struct fc_port *),
+	.show_rport_supported_classes = 1,
 
 	.get_starget_node_name = qla2x00_get_starget_node_name,
 	.show_starget_node_name = 1,
@@ -329,4 +464,5 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha)
 	    be64_to_cpu(*(uint64_t *)ha->init_cb->node_name);
 	fc_host_port_name(ha->host) =
 	    be64_to_cpu(*(uint64_t *)ha->init_cb->port_name);
+	fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
 }

+ 7 - 0
drivers/scsi/qla2xxx/qla_dbg.h

@@ -81,6 +81,7 @@
 #define DEBUG2_3_11(x)  do {x;} while (0);
 #define DEBUG2_9_10(x)    do {x;} while (0);
 #define DEBUG2_11(x)    do {x;} while (0);
+#define DEBUG2_13(x)    do {x;} while (0);
 #else
 #define DEBUG2(x)	do {} while (0);
 #endif
@@ -169,8 +170,14 @@
 
 #if defined(QL_DEBUG_LEVEL_13)
 #define DEBUG13(x)      do {x;} while (0)
+#if !defined(DEBUG2_13)
+#define DEBUG2_13(x)    do {x;} while(0)
+#endif
 #else
 #define DEBUG13(x)	do {} while (0)
+#if !defined(QL_DEBUG_LEVEL_2)
+#define DEBUG2_13(x)	do {} while(0)
+#endif
 #endif
 
 #if defined(QL_DEBUG_LEVEL_14)

+ 151 - 6
drivers/scsi/qla2xxx/qla_def.h

@@ -214,6 +214,7 @@
  * valid range of an N-PORT id is 0 through 0x7ef.
  */
 #define NPH_LAST_HANDLE		0x7ef
+#define NPH_MGMT_SERVER		0x7fa		/*  FFFFFA */
 #define NPH_SNS			0x7fc		/*  FFFFFC */
 #define NPH_FABRIC_CONTROLLER	0x7fd		/*  FFFFFD */
 #define NPH_F_PORT		0x7fe		/*  FFFFFE */
@@ -630,6 +631,7 @@ typedef struct {
 #define MBC_WRITE_RAM_WORD_EXTENDED	0xd	/* Write RAM word extended */
 #define MBC_READ_RAM_EXTENDED		0xf	/* Read RAM extended. */
 #define MBC_IOCB_COMMAND		0x12	/* Execute IOCB command. */
+#define MBC_STOP_FIRMWARE		0x14	/* Stop firmware. */
 #define MBC_ABORT_COMMAND		0x15	/* Abort IOCB command. */
 #define MBC_ABORT_DEVICE		0x16	/* Abort device (ID/LUN). */
 #define MBC_ABORT_TARGET		0x17	/* Abort target (ID). */
@@ -913,7 +915,7 @@ typedef struct {
 	 * MSB BIT 1 =
 	 * MSB BIT 2 =
 	 * MSB BIT 3 =
-	 * MSB BIT 4 =
+	 * MSB BIT 4 = LED mode
 	 * MSB BIT 5 = enable 50 ohm termination
 	 * MSB BIT 6 = Data Rate (2300 only)
 	 * MSB BIT 7 = Data Rate (2300 only)
@@ -1035,7 +1037,7 @@ typedef struct {
 	 * MSB BIT 1 =
 	 * MSB BIT 2 =
 	 * MSB BIT 3 =
-	 * MSB BIT 4 =
+	 * MSB BIT 4 = LED mode
 	 * MSB BIT 5 = enable 50 ohm termination
 	 * MSB BIT 6 = Data Rate (2300 only)
 	 * MSB BIT 7 = Data Rate (2300 only)
@@ -1131,10 +1133,7 @@ typedef struct {
 
 	uint8_t link_down_timeout;
 
-	uint8_t adapter_id_0[4];
-	uint8_t adapter_id_1[4];
-	uint8_t adapter_id_2[4];
-	uint8_t adapter_id_3[4];
+	uint8_t adapter_id[16];
 
 	uint8_t alt1_boot_node_name[WWN_SIZE];
 	uint16_t alt1_boot_lun_number;
@@ -1673,6 +1672,7 @@ typedef struct fc_port {
     	uint8_t cur_path;		/* current path id */
 
 	struct fc_rport *rport;
+	u32 supported_classes;
 } fc_port_t;
 
 /*
@@ -1727,6 +1727,8 @@ typedef struct fc_port {
 
 #define CT_REJECT_RESPONSE	0x8001
 #define CT_ACCEPT_RESPONSE	0x8002
+#define CT_REASON_CANNOT_PERFORM	0x09
+#define CT_EXPL_ALREADY_REGISTERED	0x10
 
 #define NS_N_PORT_TYPE	0x01
 #define NS_NL_PORT_TYPE	0x02
@@ -1768,6 +1770,100 @@ typedef struct fc_port {
 #define	RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255)
 #define	RSNN_NN_RSP_SIZE 16
 
+/*
+ * HBA attribute types.
+ */
+#define FDMI_HBA_ATTR_COUNT			9
+#define FDMI_HBA_NODE_NAME			1
+#define FDMI_HBA_MANUFACTURER			2
+#define FDMI_HBA_SERIAL_NUMBER			3
+#define FDMI_HBA_MODEL				4
+#define FDMI_HBA_MODEL_DESCRIPTION		5
+#define FDMI_HBA_HARDWARE_VERSION		6
+#define FDMI_HBA_DRIVER_VERSION			7
+#define FDMI_HBA_OPTION_ROM_VERSION		8
+#define FDMI_HBA_FIRMWARE_VERSION		9
+#define FDMI_HBA_OS_NAME_AND_VERSION		0xa
+#define FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH	0xb
+
+struct ct_fdmi_hba_attr {
+	uint16_t type;
+	uint16_t len;
+	union {
+		uint8_t node_name[WWN_SIZE];
+		uint8_t manufacturer[32];
+		uint8_t serial_num[8];
+		uint8_t model[16];
+		uint8_t model_desc[80];
+		uint8_t hw_version[16];
+		uint8_t driver_version[32];
+		uint8_t orom_version[16];
+		uint8_t fw_version[16];
+		uint8_t os_version[128];
+		uint8_t max_ct_len[4];
+	} a;
+};
+
+struct ct_fdmi_hba_attributes {
+	uint32_t count;
+	struct ct_fdmi_hba_attr entry[FDMI_HBA_ATTR_COUNT];
+};
+
+/*
+ * Port attribute types.
+ */
+#define FDMI_PORT_ATTR_COUNT		5
+#define FDMI_PORT_FC4_TYPES		1
+#define FDMI_PORT_SUPPORT_SPEED		2
+#define FDMI_PORT_CURRENT_SPEED		3
+#define FDMI_PORT_MAX_FRAME_SIZE	4
+#define FDMI_PORT_OS_DEVICE_NAME	5
+#define FDMI_PORT_HOST_NAME		6
+
+struct ct_fdmi_port_attr {
+	uint16_t type;
+	uint16_t len;
+	union {
+		uint8_t fc4_types[32];
+		uint32_t sup_speed;
+		uint32_t cur_speed;
+		uint32_t max_frame_size;
+		uint8_t os_dev_name[32];
+		uint8_t host_name[32];
+	} a;
+};
+
+/*
+ * Port Attribute Block.
+ */
+struct ct_fdmi_port_attributes {
+	uint32_t count;
+	struct ct_fdmi_port_attr entry[FDMI_PORT_ATTR_COUNT];
+};
+
+/* FDMI definitions. */
+#define GRHL_CMD	0x100
+#define GHAT_CMD	0x101
+#define GRPL_CMD	0x102
+#define GPAT_CMD	0x110
+
+#define RHBA_CMD	0x200
+#define RHBA_RSP_SIZE	16
+
+#define RHAT_CMD	0x201
+#define RPRT_CMD	0x210
+
+#define RPA_CMD		0x211
+#define RPA_RSP_SIZE	16
+
+#define DHBA_CMD	0x300
+#define DHBA_REQ_SIZE	(16 + 8)
+#define DHBA_RSP_SIZE	16
+
+#define DHAT_CMD	0x301
+#define DPRT_CMD	0x310
+#define DPA_CMD		0x311
+
 /* CT command header -- request/response common fields */
 struct ct_cmd_hdr {
 	uint8_t revision;
@@ -1825,6 +1921,43 @@ struct ct_sns_req {
 			uint8_t name_len;
 			uint8_t sym_node_name[255];
 		} rsnn_nn;
+
+		struct {
+			uint8_t hba_indentifier[8];
+		} ghat;
+
+		struct {
+			uint8_t hba_identifier[8];
+			uint32_t entry_count;
+			uint8_t port_name[8];
+			struct ct_fdmi_hba_attributes attrs;
+		} rhba;
+
+		struct {
+			uint8_t hba_identifier[8];
+			struct ct_fdmi_hba_attributes attrs;
+		} rhat;
+
+		struct {
+			uint8_t port_name[8];
+			struct ct_fdmi_port_attributes attrs;
+		} rpa;
+
+		struct {
+			uint8_t port_name[8];
+		} dhba;
+
+		struct {
+			uint8_t port_name[8];
+		} dhat;
+
+		struct {
+			uint8_t port_name[8];
+		} dprt;
+
+		struct {
+			uint8_t port_name[8];
+		} dpa;
 	} req;
 };
 
@@ -1882,6 +2015,12 @@ struct ct_sns_rsp {
 		struct {
 			uint8_t fc4_types[32];
 		} gft_id;
+
+		struct {
+			uint32_t entry_count;
+			uint8_t port_name[8];
+			struct ct_fdmi_hba_attributes attrs;
+		} ghat;
 	} rsp;
 };
 
@@ -2032,6 +2171,8 @@ struct isp_operations {
 	uint16_t (*calc_req_entries) (uint16_t);
 	void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t);
 	void * (*prep_ms_iocb) (struct scsi_qla_host *, uint32_t, uint32_t);
+	void * (*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t,
+	    uint32_t);
 
 	uint8_t * (*read_nvram) (struct scsi_qla_host *, uint8_t *,
 		uint32_t, uint32_t);
@@ -2111,6 +2252,7 @@ typedef struct scsi_qla_host {
 #define IOCTL_ERROR_RECOVERY	23
 #define LOOP_RESET_NEEDED	24
 #define BEACON_BLINK_NEEDED	25
+#define REGISTER_FDMI_NEEDED	26
 
 	uint32_t	device_flags;
 #define DFLG_LOCAL_DEVICES		BIT_0
@@ -2204,6 +2346,7 @@ typedef struct scsi_qla_host {
 	int		port_down_retry_count;
 	uint8_t		mbx_count;
 	uint16_t	last_loop_id;
+	uint16_t	mgmt_svr_loop_id;
 
         uint32_t	login_retry_count;
 
@@ -2318,6 +2461,7 @@ typedef struct scsi_qla_host {
 	uint8_t		model_number[16+1];
 #define BINZERO		"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 	char		*model_desc;
+	uint8_t		adapter_id[16+1];
 
 	uint8_t		*node_name;
 	uint8_t		*port_name;
@@ -2377,6 +2521,7 @@ typedef struct scsi_qla_host {
 #define QLA_SUSPENDED			0x106
 #define QLA_BUSY			0x107
 #define QLA_RSCNS_HANDLED		0x108
+#define QLA_ALREADY_REGISTERED		0x109
 
 /*
 * Stat info for all adpaters

+ 9 - 3
drivers/scsi/qla2xxx/qla_gbl.h

@@ -79,6 +79,7 @@ extern int ql2xplogiabsentdevice;
 extern int ql2xenablezio;
 extern int ql2xintrdelaytimer;
 extern int ql2xloginretrycount;
+extern int ql2xfdmienable;
 
 extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
 
@@ -146,9 +147,6 @@ extern int
 qla2x00_abort_target(fc_port_t *);
 #endif
 
-extern int
-qla2x00_target_reset(scsi_qla_host_t *, struct fc_port *);
-
 extern int
 qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
     uint8_t *, uint16_t *);
@@ -215,6 +213,9 @@ qla2x00_get_serdes_params(scsi_qla_host_t *, uint16_t *, uint16_t *,
 extern int
 qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
 
+extern int
+qla2x00_stop_firmware(scsi_qla_host_t *);
+
 /*
  * Global Function Prototypes in qla_isr.c source file.
  */
@@ -269,6 +270,9 @@ extern int qla2x00_rft_id(scsi_qla_host_t *);
 extern int qla2x00_rff_id(scsi_qla_host_t *);
 extern int qla2x00_rnn_id(scsi_qla_host_t *);
 extern int qla2x00_rsnn_nn(scsi_qla_host_t *);
+extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
+extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
+extern int qla2x00_fdmi_register(scsi_qla_host_t *);
 
 /*
  * Global Function Prototypes in qla_rscn.c source file.
@@ -289,6 +293,8 @@ extern void qla2x00_cancel_io_descriptors(scsi_qla_host_t *);
 /*
  * Global Function Prototypes in qla_attr.c source file.
  */
+struct class_device_attribute;
+extern struct class_device_attribute *qla2x00_host_attrs[];
 struct fc_function_template;
 extern struct fc_function_template qla2xxx_transport_functions;
 extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);

+ 564 - 0
drivers/scsi/qla2xxx/qla_gs.c

@@ -1099,3 +1099,567 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *ha)
 
 	return (rval);
 }
+
+/**
+ * qla2x00_mgmt_svr_login() - Login to fabric Managment Service.
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+static int
+qla2x00_mgmt_svr_login(scsi_qla_host_t *ha)
+{
+	int ret;
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+
+	ret = QLA_SUCCESS;
+	if (ha->flags.management_server_logged_in)
+		return ret;
+
+	ha->isp_ops.fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa,
+	    mb, BIT_1);
+	if (mb[0] != MBS_COMMAND_COMPLETE) {
+		DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: "
+		    "loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x\n",
+		    __func__, ha->host_no, ha->mgmt_svr_loop_id, mb[0], mb[1],
+		    mb[2], mb[6], mb[7]));
+		ret = QLA_FUNCTION_FAILED;
+	} else
+		ha->flags.management_server_logged_in = 1;
+
+	return ret;
+}
+
+/**
+ * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
+ * @ha: HA context
+ * @req_size: request size in bytes
+ * @rsp_size: response size in bytes
+ *
+ * Returns a pointer to the @ha's ms_iocb.
+ */
+void *
+qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
+    uint32_t rsp_size)
+{
+	ms_iocb_entry_t *ms_pkt;
+
+	ms_pkt = ha->ms_iocb;
+	memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
+
+	ms_pkt->entry_type = MS_IOCB_TYPE;
+	ms_pkt->entry_count = 1;
+	SET_TARGET_ID(ha, ms_pkt->loop_id, ha->mgmt_svr_loop_id);
+	ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
+	ms_pkt->timeout = __constant_cpu_to_le16(59);
+	ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
+	ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
+	ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
+	ms_pkt->req_bytecount = cpu_to_le32(req_size);
+
+	ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+	ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+	ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
+
+	ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+	ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+	ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
+
+	return ms_pkt;
+}
+
+/**
+ * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
+ * @ha: HA context
+ * @req_size: request size in bytes
+ * @rsp_size: response size in bytes
+ *
+ * Returns a pointer to the @ha's ms_iocb.
+ */
+void *
+qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size,
+    uint32_t rsp_size)
+{
+	struct ct_entry_24xx *ct_pkt;
+
+	ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
+	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
+
+	ct_pkt->entry_type = CT_IOCB_TYPE;
+	ct_pkt->entry_count = 1;
+	ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
+	ct_pkt->timeout = __constant_cpu_to_le16(59);
+	ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
+	ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
+	ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
+	ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
+
+	ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+	ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+	ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
+
+	ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+	ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+	ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
+
+	return ct_pkt;
+}
+
+static inline ms_iocb_entry_t *
+qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size)
+{
+	ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
+	struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
+
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
+		ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
+	} else {
+		ms_pkt->req_bytecount = cpu_to_le32(req_size);
+		ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
+	}
+
+	return ms_pkt;
+}
+
+/**
+ * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
+ * @ct_req: CT request buffer
+ * @cmd: GS command
+ * @rsp_size: response size in bytes
+ *
+ * Returns a pointer to the intitialized @ct_req.
+ */
+static inline struct ct_sns_req *
+qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd,
+    uint16_t rsp_size)
+{
+	memset(ct_req, 0, sizeof(struct ct_sns_pkt));
+
+	ct_req->header.revision = 0x01;
+	ct_req->header.gs_type = 0xFA;
+	ct_req->header.gs_subtype = 0x10;
+	ct_req->command = cpu_to_be16(cmd);
+	ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
+
+	return ct_req;
+}
+
+/**
+ * qla2x00_fdmi_rhba() -
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+static int
+qla2x00_fdmi_rhba(scsi_qla_host_t *ha)
+{
+	int rval, alen;
+	uint32_t size, sn;
+
+	ms_iocb_entry_t *ms_pkt;
+	struct ct_sns_req *ct_req;
+	struct ct_sns_rsp *ct_rsp;
+	uint8_t *entries;
+	struct ct_fdmi_hba_attr *eiter;
+
+	/* Issue RHBA */
+	/* Prepare common MS IOCB */
+	/*   Request size adjusted after CT preparation */
+	ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE);
+
+	/* Prepare CT request */
+	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD,
+	    RHBA_RSP_SIZE);
+	ct_rsp = &ha->ct_sns->p.rsp;
+
+	/* Prepare FDMI command arguments -- attribute block, attributes. */
+	memcpy(ct_req->req.rhba.hba_identifier, ha->port_name, WWN_SIZE);
+	ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1);
+	memcpy(ct_req->req.rhba.port_name, ha->port_name, WWN_SIZE);
+	size = 2 * WWN_SIZE + 4 + 4;
+
+	/* Attributes */
+	ct_req->req.rhba.attrs.count =
+	    __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT);
+	entries = ct_req->req.rhba.hba_identifier;
+
+	/* Nodename. */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME);
+	eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE);
+	memcpy(eiter->a.node_name, ha->node_name, WWN_SIZE);
+	size += 4 + WWN_SIZE;
+
+	DEBUG13(printk("%s(%ld): NODENAME=%02x%02x%02x%02x%02x%02x%02x%02x.\n",
+	    __func__, ha->host_no,
+	    eiter->a.node_name[0], eiter->a.node_name[1], eiter->a.node_name[2],
+	    eiter->a.node_name[3], eiter->a.node_name[4], eiter->a.node_name[5],
+	    eiter->a.node_name[6], eiter->a.node_name[7]));
+
+	/* Manufacturer. */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER);
+	strcpy(eiter->a.manufacturer, "QLogic Corporation");
+	alen = strlen(eiter->a.manufacturer);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): MANUFACTURER=%s.\n", __func__, ha->host_no,
+	    eiter->a.manufacturer));
+
+	/* Serial number. */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
+	sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
+	sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000);
+	alen = strlen(eiter->a.serial_num);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): SERIALNO=%s.\n", __func__, ha->host_no,
+	    eiter->a.serial_num));
+
+	/* Model name. */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL);
+	strcpy(eiter->a.model, ha->model_number);
+	alen = strlen(eiter->a.model);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): MODEL_NAME=%s.\n", __func__, ha->host_no,
+	    eiter->a.model));
+
+	/* Model description. */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
+	if (ha->model_desc)
+		strncpy(eiter->a.model_desc, ha->model_desc, 80);
+	alen = strlen(eiter->a.model_desc);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): MODEL_DESC=%s.\n", __func__, ha->host_no,
+	    eiter->a.model_desc));
+
+	/* Hardware version. */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
+	strcpy(eiter->a.hw_version, ha->adapter_id);
+	alen = strlen(eiter->a.hw_version);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): HARDWAREVER=%s.\n", __func__, ha->host_no,
+	    eiter->a.hw_version));
+
+	/* Driver version. */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
+	strcpy(eiter->a.driver_version, qla2x00_version_str);
+	alen = strlen(eiter->a.driver_version);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): DRIVERVER=%s.\n", __func__, ha->host_no,
+	    eiter->a.driver_version));
+
+	/* Option ROM version. */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
+	strcpy(eiter->a.orom_version, "0.00");
+	alen = strlen(eiter->a.orom_version);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): OPTROMVER=%s.\n", __func__, ha->host_no,
+	    eiter->a.orom_version));
+
+	/* Firmware version */
+	eiter = (struct ct_fdmi_hba_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
+	ha->isp_ops.fw_version_str(ha, eiter->a.fw_version);
+	alen = strlen(eiter->a.fw_version);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): FIRMWAREVER=%s.\n", __func__, ha->host_no,
+	    eiter->a.fw_version));
+
+	/* Update MS request size. */
+	qla2x00_update_ms_fdmi_iocb(ha, size + 16);
+
+	DEBUG13(printk("%s(%ld): RHBA identifier="
+	    "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__,
+	    ha->host_no, ct_req->req.rhba.hba_identifier[0],
+	    ct_req->req.rhba.hba_identifier[1],
+	    ct_req->req.rhba.hba_identifier[2],
+	    ct_req->req.rhba.hba_identifier[3],
+	    ct_req->req.rhba.hba_identifier[4],
+	    ct_req->req.rhba.hba_identifier[5],
+	    ct_req->req.rhba.hba_identifier[6],
+	    ct_req->req.rhba.hba_identifier[7], size));
+	DEBUG13(qla2x00_dump_buffer(entries, size));
+
+	/* Execute MS IOCB */
+	rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
+	    sizeof(ms_iocb_entry_t));
+	if (rval != QLA_SUCCESS) {
+		/*EMPTY*/
+		DEBUG2_3(printk("scsi(%ld): RHBA issue IOCB failed (%d).\n",
+		    ha->host_no, rval));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RHBA") !=
+	    QLA_SUCCESS) {
+		rval = QLA_FUNCTION_FAILED;
+		if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
+		    ct_rsp->header.explanation_code ==
+		    CT_EXPL_ALREADY_REGISTERED) {
+			DEBUG2_13(printk("%s(%ld): HBA already registered.\n",
+			    __func__, ha->host_no));
+			rval = QLA_ALREADY_REGISTERED;
+		}
+	} else {
+		DEBUG2(printk("scsi(%ld): RHBA exiting normally.\n",
+		    ha->host_no));
+	}
+
+	return rval;
+}
+
+/**
+ * qla2x00_fdmi_dhba() -
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+static int
+qla2x00_fdmi_dhba(scsi_qla_host_t *ha)
+{
+	int rval;
+
+	ms_iocb_entry_t *ms_pkt;
+	struct ct_sns_req *ct_req;
+	struct ct_sns_rsp *ct_rsp;
+
+	/* Issue RPA */
+	/* Prepare common MS IOCB */
+	ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE,
+	    DHBA_RSP_SIZE);
+
+	/* Prepare CT request */
+	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD,
+	    DHBA_RSP_SIZE);
+	ct_rsp = &ha->ct_sns->p.rsp;
+
+	/* Prepare FDMI command arguments -- portname. */
+	memcpy(ct_req->req.dhba.port_name, ha->port_name, WWN_SIZE);
+
+	DEBUG13(printk("%s(%ld): DHBA portname="
+	    "%02x%02x%02x%02x%02x%02x%02x%02x.\n", __func__, ha->host_no,
+	    ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1],
+	    ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3],
+	    ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5],
+	    ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7]));
+
+	/* Execute MS IOCB */
+	rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
+	    sizeof(ms_iocb_entry_t));
+	if (rval != QLA_SUCCESS) {
+		/*EMPTY*/
+		DEBUG2_3(printk("scsi(%ld): DHBA issue IOCB failed (%d).\n",
+		    ha->host_no, rval));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "DHBA") !=
+	    QLA_SUCCESS) {
+		rval = QLA_FUNCTION_FAILED;
+	} else {
+		DEBUG2(printk("scsi(%ld): DHBA exiting normally.\n",
+		    ha->host_no));
+	}
+
+	return rval;
+}
+
+/**
+ * qla2x00_fdmi_rpa() -
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+static int
+qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
+{
+	int rval, alen;
+	uint32_t size, max_frame_size;
+
+	ms_iocb_entry_t *ms_pkt;
+	struct ct_sns_req *ct_req;
+	struct ct_sns_rsp *ct_rsp;
+	uint8_t *entries;
+	struct ct_fdmi_port_attr *eiter;
+	struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb;
+
+	/* Issue RPA */
+	/* Prepare common MS IOCB */
+	/*   Request size adjusted after CT preparation */
+	ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE);
+
+	/* Prepare CT request */
+	ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD,
+	    RPA_RSP_SIZE);
+	ct_rsp = &ha->ct_sns->p.rsp;
+
+	/* Prepare FDMI command arguments -- attribute block, attributes. */
+	memcpy(ct_req->req.rpa.port_name, ha->port_name, WWN_SIZE);
+	size = WWN_SIZE + 4;
+
+	/* Attributes */
+	ct_req->req.rpa.attrs.count =
+	    __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT);
+	entries = ct_req->req.rpa.port_name;
+
+	/* FC4 types. */
+	eiter = (struct ct_fdmi_port_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES);
+	eiter->len = __constant_cpu_to_be16(4 + 32);
+	eiter->a.fc4_types[2] = 0x01;
+	size += 4 + 32;
+
+	DEBUG13(printk("%s(%ld): FC4_TYPES=%02x %02x.\n", __func__, ha->host_no,
+	    eiter->a.fc4_types[2], eiter->a.fc4_types[1]));
+
+	/* Supported speed. */
+	eiter = (struct ct_fdmi_port_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
+	eiter->len = __constant_cpu_to_be16(4 + 4);
+	if (IS_QLA25XX(ha))
+		eiter->a.sup_speed = __constant_cpu_to_be32(4);
+	else if (IS_QLA24XX(ha))
+		eiter->a.sup_speed = __constant_cpu_to_be32(8);
+	else if (IS_QLA23XX(ha))
+		eiter->a.sup_speed = __constant_cpu_to_be32(2);
+	else
+		eiter->a.sup_speed = __constant_cpu_to_be32(1);
+	size += 4 + 4;
+
+	DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no,
+	    eiter->a.sup_speed));
+
+	/* Current speed. */
+	eiter = (struct ct_fdmi_port_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
+	eiter->len = __constant_cpu_to_be16(4 + 4);
+	switch (ha->link_data_rate) {
+	case 0:
+		eiter->a.cur_speed = __constant_cpu_to_be32(1);
+		break;
+	case 1:
+		eiter->a.cur_speed = __constant_cpu_to_be32(2);
+		break;
+	case 3:
+		eiter->a.cur_speed = __constant_cpu_to_be32(8);
+		break;
+	case 4:
+		eiter->a.cur_speed = __constant_cpu_to_be32(4);
+		break;
+	}
+	size += 4 + 4;
+
+	DEBUG13(printk("%s(%ld): CURRENT_SPEED=%x.\n", __func__, ha->host_no,
+	    eiter->a.cur_speed));
+
+	/* Max frame size. */
+	eiter = (struct ct_fdmi_port_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
+	eiter->len = __constant_cpu_to_be16(4 + 4);
+	max_frame_size = IS_QLA24XX(ha) || IS_QLA25XX(ha) ?
+		(uint32_t) icb24->frame_payload_size:
+		(uint32_t) ha->init_cb->frame_payload_size;
+	eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
+	size += 4 + 4;
+
+	DEBUG13(printk("%s(%ld): MAX_FRAME_SIZE=%x.\n", __func__, ha->host_no,
+	    eiter->a.max_frame_size));
+
+	/* OS device name. */
+	eiter = (struct ct_fdmi_port_attr *) (entries + size);
+	eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
+	sprintf(eiter->a.os_dev_name, "/proc/scsi/qla2xxx/%ld", ha->host_no);
+	alen = strlen(eiter->a.os_dev_name);
+	alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+	eiter->len = cpu_to_be16(4 + alen);
+	size += 4 + alen;
+
+	DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no,
+	    eiter->a.os_dev_name));
+
+	/* Update MS request size. */
+	qla2x00_update_ms_fdmi_iocb(ha, size + 16);
+
+	DEBUG13(printk("%s(%ld): RPA portname="
+	    "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__,
+	    ha->host_no, ct_req->req.rpa.port_name[0],
+	    ct_req->req.rpa.port_name[1], ct_req->req.rpa.port_name[2],
+	    ct_req->req.rpa.port_name[3], ct_req->req.rpa.port_name[4],
+	    ct_req->req.rpa.port_name[5], ct_req->req.rpa.port_name[6],
+	    ct_req->req.rpa.port_name[7], size));
+	DEBUG13(qla2x00_dump_buffer(entries, size));
+
+	/* Execute MS IOCB */
+	rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
+	    sizeof(ms_iocb_entry_t));
+	if (rval != QLA_SUCCESS) {
+		/*EMPTY*/
+		DEBUG2_3(printk("scsi(%ld): RPA issue IOCB failed (%d).\n",
+		    ha->host_no, rval));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RPA") !=
+	    QLA_SUCCESS) {
+		rval = QLA_FUNCTION_FAILED;
+	} else {
+		DEBUG2(printk("scsi(%ld): RPA exiting normally.\n",
+		    ha->host_no));
+	}
+
+	return rval;
+}
+
+/**
+ * qla2x00_fdmi_register() -
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+int
+qla2x00_fdmi_register(scsi_qla_host_t *ha)
+{
+	int rval;
+
+	rval = qla2x00_mgmt_svr_login(ha);
+	if (rval)
+		return rval;
+
+	rval = qla2x00_fdmi_rhba(ha);
+	if (rval) {
+		if (rval != QLA_ALREADY_REGISTERED)
+			return rval;
+
+		rval = qla2x00_fdmi_dhba(ha);
+		if (rval)
+			return rval;
+
+		rval = qla2x00_fdmi_rhba(ha);
+		if (rval)
+			return rval;
+	}
+	rval = qla2x00_fdmi_rpa(ha);
+
+	return rval;
+}

+ 22 - 2
drivers/scsi/qla2xxx/qla_init.c

@@ -88,6 +88,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
 	ha->mbx_flags = 0;
 	ha->isp_abort_cnt = 0;
 	ha->beacon_blink_led = 0;
+	set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
 
 	qla_printk(KERN_INFO, ha, "Configuring PCI space...\n");
 	rval = ha->isp_ops.pci_config(ha);
@@ -1563,7 +1564,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
 	ha->flags.enable_lip_reset = ((nv->host_p[1] & BIT_1) ? 1 : 0);
 	ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0);
 	ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0);
-	ha->flags.enable_led_scheme = ((nv->efi_parameters & BIT_3) ? 1 : 0);
+	ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0;
 
 	ha->operating_mode =
 	    (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4;
@@ -1697,6 +1698,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, int flags)
 	fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
 	atomic_set(&fcport->state, FCS_UNCONFIGURED);
 	fcport->flags = FCF_RLC_SUPPORT;
+	fcport->supported_classes = FC_COS_UNSPECIFIED;
 
 	return (fcport);
 }
@@ -1898,7 +1900,8 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
 			continue;
 
 		/* Bypass if not same domain and area of adapter. */
-		if (area != ha->d_id.b.area || domain != ha->d_id.b.domain)
+		if (area && domain &&
+		    (area != ha->d_id.b.area || domain != ha->d_id.b.domain))
 			continue;
 
 		/* Bypass invalid local loop ID. */
@@ -2075,6 +2078,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
 		return;
 	}
 	rport->dd_data = fcport;
+	rport->supported_classes = fcport->supported_classes;
 
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
 	if (fcport->port_type == FCT_INITIATOR)
@@ -2130,6 +2134,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
 		return (QLA_SUCCESS);
 	}
 	do {
+		/* FDMI support. */
+		if (ql2xfdmienable &&
+		    test_and_clear_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags))
+			qla2x00_fdmi_register(ha);
+
 		/* Ensure we are logged into the SNS. */
 		if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
 			loop_id = NPH_SNS;
@@ -2392,6 +2401,12 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
 		if (new_fcport->d_id.b24 == ha->d_id.b24)
 			continue;
 
+		/* Bypass if same domain and area of adapter. */
+		if (((new_fcport->d_id.b24 & 0xffff00) ==
+		    (ha->d_id.b24 & 0xffff00)) && ha->current_topology ==
+			ISP_CFG_FL)
+			    continue;
+
 		/* Bypass reserved domain fields. */
 		if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0)
 			continue;
@@ -2794,6 +2809,11 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
 				}
 			}
 
+			if (mb[10] & BIT_0)
+				fcport->supported_classes |= FC_COS_CLASS2;
+			if (mb[10] & BIT_1)
+				fcport->supported_classes |= FC_COS_CLASS3;
+
 			rval = QLA_SUCCESS;
 			break;
 		} else if (mb[0] == MBS_LOOP_ID_USED) {

+ 1 - 5
drivers/scsi/qla2xxx/qla_iocb.c

@@ -810,12 +810,8 @@ qla24xx_start_scsi(srb_t *sp)
 			ha->req_q_cnt = ha->request_q_length -
 				(ha->req_ring_index - cnt);
 	}
-	if (ha->req_q_cnt < (req_cnt + 2)) {
-		if  (cmd->use_sg)
-			pci_unmap_sg(ha->pdev, sg, cmd->use_sg,
-					cmd->sc_data_direction);
+	if (ha->req_q_cnt < (req_cnt + 2))
 		goto queuing_error;
-	}
 
 	/* Build command packet. */
 	ha->current_outstanding_cmd = handle;

+ 2 - 0
drivers/scsi/qla2xxx/qla_isr.c

@@ -451,6 +451,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 
 		ha->flags.management_server_logged_in = 0;
 		ha->link_data_rate = 0;
+		if (ql2xfdmienable)
+			set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
 
 		/* Update AEN queue. */
 		qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL);

+ 44 - 53
drivers/scsi/qla2xxx/qla_mbx.c

@@ -19,6 +19,7 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
+#include <scsi/scsi_transport_fc.h>
 
 static void
 qla2x00_mbx_sem_timeout(unsigned long data)
@@ -251,7 +252,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
 			mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
 			ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
 		} else {
-			mb0 = RD_MAILBOX_REG(ha, reg->isp, 0);
+			mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
 			ictrl = RD_REG_WORD(&reg->isp.ictrl);
 		}
 		printk("%s(%ld): **** MB Command Timeout for cmd %x ****\n",
@@ -982,58 +983,6 @@ qla2x00_abort_target(fc_port_t *fcport)
 }
 #endif
 
-/*
- * qla2x00_target_reset
- *	Issue target reset mailbox command.
- *
- * Input:
- *	ha = adapter block pointer.
- *	TARGET_QUEUE_LOCK must be released.
- *	ADAPTER_STATE_LOCK must be released.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
-int
-qla2x00_target_reset(scsi_qla_host_t *ha, struct fc_port *fcport)
-{
-	int rval;
-	mbx_cmd_t mc;
-	mbx_cmd_t *mcp = &mc;
-
-	DEBUG11(printk("qla2x00_target_reset(%ld): entered.\n", ha->host_no);)
-
-	if (atomic_read(&fcport->state) != FCS_ONLINE)
-		return 0;
-
-	mcp->mb[0] = MBC_TARGET_RESET;
-	if (HAS_EXTENDED_IDS(ha))
-		mcp->mb[1] = fcport->loop_id;
-	else
-		mcp->mb[1] = fcport->loop_id << 8;
-	mcp->mb[2] = ha->loop_reset_delay;
-	mcp->out_mb = MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
-	mcp->flags = 0;
-	rval = qla2x00_mailbox_command(ha, mcp);
-
-	if (rval != QLA_SUCCESS) {
-		/*EMPTY*/
-		DEBUG2_3_11(printk("qla2x00_target_reset(%ld): failed=%x.\n",
-		    ha->host_no, rval);)
-	} else {
-		/*EMPTY*/
-		DEBUG11(printk("qla2x00_target_reset(%ld): done.\n",
-		    ha->host_no);)
-	}
-
-	return rval;
-}
-
 /*
  * qla2x00_get_adapter_id
  *	Get adapter ID and topology.
@@ -1326,6 +1275,10 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
 			fcport->port_type = FCT_INITIATOR;
 		else
 			fcport->port_type = FCT_TARGET;
+
+		/* Passback COS information. */
+		fcport->supported_classes = (pd->options & BIT_4) ?
+		    FC_COS_CLASS2: FC_COS_CLASS3;
 	}
 
 gpd_error_out:
@@ -1661,6 +1614,13 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
 				mb[1] |= BIT_1;
 		} else
 			mb[1] = BIT_0;
+
+		/* Passback COS information. */
+		mb[10] = 0;
+		if (lg->io_parameter[7] || lg->io_parameter[8])
+			mb[10] |= BIT_0;	/* Class 2. */
+		if (lg->io_parameter[9] || lg->io_parameter[10])
+			mb[10] |= BIT_1;	/* Class 3. */
 	}
 
 	dma_pool_free(ha->s_dma_pool, lg, lg_dma);
@@ -1723,6 +1683,8 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
 		mb[2] = mcp->mb[2];
 		mb[6] = mcp->mb[6];
 		mb[7] = mcp->mb[7];
+		/* COS retrieved from Get-Port-Database mailbox command. */
+		mb[10] = 0;
 	}
 
 	if (rval != QLA_SUCCESS) {
@@ -2465,3 +2427,32 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g,
 
 	return rval;
 }
+
+int
+qla2x00_stop_firmware(scsi_qla_host_t *ha)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha))
+		return QLA_FUNCTION_FAILED;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+	mcp->mb[0] = MBC_STOP_FIRMWARE;
+	mcp->out_mb = MBX_0;
+	mcp->in_mb = MBX_0;
+	mcp->tov = 5;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(ha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+		    ha->host_no, rval));
+	} else {
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+	}
+
+	return rval;
+}

+ 71 - 46
drivers/scsi/qla2xxx/qla_os.c

@@ -79,7 +79,7 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
 MODULE_PARM_DESC(ql2xloginretrycount,
 		"Specify an alternate value for the NVRAM login retry count.");
 
-int ql2xfwloadbin;
+int ql2xfwloadbin=1;
 module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
 MODULE_PARM_DESC(ql2xfwloadbin,
 		"Load ISP2xxx firmware image via hotplug.");
@@ -88,6 +88,12 @@ static void qla2x00_free_device(scsi_qla_host_t *);
 
 static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);
 
+int ql2xfdmienable;
+module_param(ql2xfdmienable, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xfdmienable,
+		"Enables FDMI registratons "
+		"Default is 0 - no FDMI. 1 - perfom FDMI.");
+
 /*
  * SCSI host template entry points
  */
@@ -105,6 +111,9 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
 static int qla2x00_loop_reset(scsi_qla_host_t *ha);
 static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *);
 
+static int qla2x00_change_queue_depth(struct scsi_device *, int);
+static int qla2x00_change_queue_type(struct scsi_device *, int);
+
 static struct scsi_host_template qla2x00_driver_template = {
 	.module			= THIS_MODULE,
 	.name			= "qla2xxx",
@@ -119,6 +128,8 @@ static struct scsi_host_template qla2x00_driver_template = {
 
 	.slave_alloc		= qla2xxx_slave_alloc,
 	.slave_destroy		= qla2xxx_slave_destroy,
+	.change_queue_depth	= qla2x00_change_queue_depth,
+	.change_queue_type	= qla2x00_change_queue_type,
 	.this_id		= -1,
 	.cmd_per_lun		= 3,
 	.use_clustering		= ENABLE_CLUSTERING,
@@ -129,6 +140,7 @@ static struct scsi_host_template qla2x00_driver_template = {
 	 * which equates to 0x800000 sectors.
 	 */
 	.max_sectors		= 0xFFFF,
+	.shost_attrs		= qla2x00_host_attrs,
 };
 
 static struct scsi_host_template qla24xx_driver_template = {
@@ -145,12 +157,15 @@ static struct scsi_host_template qla24xx_driver_template = {
 
 	.slave_alloc		= qla2xxx_slave_alloc,
 	.slave_destroy		= qla2xxx_slave_destroy,
+	.change_queue_depth	= qla2x00_change_queue_depth,
+	.change_queue_type	= qla2x00_change_queue_type,
 	.this_id		= -1,
 	.cmd_per_lun		= 3,
 	.use_clustering		= ENABLE_CLUSTERING,
 	.sg_tablesize		= SG_ALL,
 
 	.max_sectors		= 0xFFFF,
+	.shost_attrs		= qla2x00_host_attrs,
 };
 
 static struct scsi_transport_template *qla2xxx_transport_template = NULL;
@@ -487,14 +502,13 @@ qc24_fail_command:
 static int
 qla2x00_eh_wait_on_command(scsi_qla_host_t *ha, struct scsi_cmnd *cmd)
 {
-#define ABORT_POLLING_PERIOD	HZ
-#define ABORT_WAIT_ITER		((10 * HZ) / (ABORT_POLLING_PERIOD))
+#define ABORT_POLLING_PERIOD	1000
+#define ABORT_WAIT_ITER		((10 * 1000) / (ABORT_POLLING_PERIOD))
 	unsigned long wait_iter = ABORT_WAIT_ITER;
 	int ret = QLA_SUCCESS;
 
 	while (CMD_SP(cmd)) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(ABORT_POLLING_PERIOD);
+		msleep(ABORT_POLLING_PERIOD);
 
 		if (--wait_iter)
 			break;
@@ -1016,7 +1030,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
 			if (fcport->port_type != FCT_TARGET)
 				continue;
 
-			status = qla2x00_target_reset(ha, fcport);
+			status = qla2x00_device_reset(ha, fcport);
 			if (status != QLA_SUCCESS)
 				break;
 		}
@@ -1103,6 +1117,28 @@ qla2xxx_slave_destroy(struct scsi_device *sdev)
 	sdev->hostdata = NULL;
 }
 
+static int
+qla2x00_change_queue_depth(struct scsi_device *sdev, int qdepth)
+{
+	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
+	return sdev->queue_depth;
+}
+
+static int
+qla2x00_change_queue_type(struct scsi_device *sdev, int tag_type)
+{
+	if (sdev->tagged_supported) {
+		scsi_set_tag_type(sdev, tag_type);
+		if (tag_type)
+			scsi_activate_tcq(sdev, sdev->queue_depth);
+		else
+			scsi_deactivate_tcq(sdev, sdev->queue_depth);
+	} else
+		tag_type = 0;
+
+	return tag_type;
+}
+
 /**
  * qla2x00_config_dma_addressing() - Configure OS DMA addressing method.
  * @ha: HA context
@@ -1113,36 +1149,23 @@ qla2xxx_slave_destroy(struct scsi_device *sdev)
 static void
 qla2x00_config_dma_addressing(scsi_qla_host_t *ha)
 {
-	/* Assume 32bit DMA address */
+	/* Assume a 32bit DMA mask. */
 	ha->flags.enable_64bit_addressing = 0;
 
-	/*
-	 * Given the two variants pci_set_dma_mask(), allow the compiler to
-	 * assist in setting the proper dma mask.
-	 */
-	if (sizeof(dma_addr_t) > 4) {
-		if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) {
+	if (!dma_set_mask(&ha->pdev->dev, DMA_64BIT_MASK)) {
+		/* Any upper-dword bits set? */
+		if (MSD(dma_get_required_mask(&ha->pdev->dev)) &&
+		    !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
+			/* Ok, a 64bit DMA mask is applicable. */
 			ha->flags.enable_64bit_addressing = 1;
 			ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64;
 			ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64;
-
-			if (pci_set_consistent_dma_mask(ha->pdev,
-			    DMA_64BIT_MASK)) {
-				qla_printk(KERN_DEBUG, ha,
-				    "Failed to set 64 bit PCI consistent mask; "
-				    "using 32 bit.\n");
-				pci_set_consistent_dma_mask(ha->pdev,
-				    DMA_32BIT_MASK);
-			}
-		} else {
-			qla_printk(KERN_DEBUG, ha,
-			    "Failed to set 64 bit PCI DMA mask, falling back "
-			    "to 32 bit MASK.\n");
-			pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK);
+			return;
 		}
-	} else {
-		pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK);
 	}
+
+	dma_set_mask(&ha->pdev->dev, DMA_32BIT_MASK);
+	pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
 }
 
 static int
@@ -1316,6 +1339,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
 	ha->prev_topology = 0;
 	ha->ports = MAX_BUSES;
 	ha->init_cb_size = sizeof(init_cb_t);
+	ha->mgmt_svr_loop_id = MANAGEMENT_SERVER;
 
 	/* Assign ISP specific operations. */
 	ha->isp_ops.pci_config		= qla2100_pci_config;
@@ -1338,6 +1362,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
 	ha->isp_ops.calc_req_entries	= qla2x00_calc_iocbs_32;
 	ha->isp_ops.build_iocbs		= qla2x00_build_scsi_iocbs_32;
 	ha->isp_ops.prep_ms_iocb	= qla2x00_prep_ms_iocb;
+	ha->isp_ops.prep_ms_fdmi_iocb	= qla2x00_prep_ms_fdmi_iocb;
 	ha->isp_ops.read_nvram		= qla2x00_read_nvram_data;
 	ha->isp_ops.write_nvram		= qla2x00_write_nvram_data;
 	ha->isp_ops.fw_dump		= qla2100_fw_dump;
@@ -1375,6 +1400,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
 		ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
 		ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
 		ha->init_cb_size = sizeof(struct init_cb_24xx);
+		ha->mgmt_svr_loop_id = 10;
 		ha->isp_ops.pci_config = qla24xx_pci_config;
 		ha->isp_ops.reset_chip = qla24xx_reset_chip;
 		ha->isp_ops.chip_diag = qla24xx_chip_diag;
@@ -1395,6 +1421,7 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
 		ha->isp_ops.fabric_login = qla24xx_login_fabric;
 		ha->isp_ops.fabric_logout = qla24xx_fabric_logout;
 		ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb;
+		ha->isp_ops.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb;
 		ha->isp_ops.read_nvram = qla24xx_read_nvram_data;
 		ha->isp_ops.write_nvram = qla24xx_write_nvram_data;
 		ha->isp_ops.fw_dump = qla24xx_fw_dump;
@@ -1558,8 +1585,6 @@ int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
 	return 0;
 
 probe_failed:
-	fc_remove_host(ha->host);
-
 	qla2x00_free_device(ha);
 
 	scsi_host_put(host);
@@ -1601,10 +1626,6 @@ qla2x00_free_device(scsi_qla_host_t *ha)
 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
 		qla2x00_cancel_io_descriptors(ha);
 
-	/* turn-off interrupts on the card */
-	if (ha->interrupts_on)
-		ha->isp_ops.disable_intrs(ha);
-
 	/* Disable timer */
 	if (ha->timer_active)
 		qla2x00_stop_timer(ha);
@@ -1624,8 +1645,14 @@ qla2x00_free_device(scsi_qla_host_t *ha)
 		}
 	}
 
-	qla2x00_mem_free(ha);
+	/* Stop currently executing firmware. */
+	qla2x00_stop_firmware(ha);
+
+	/* turn-off interrupts on the card */
+	if (ha->interrupts_on)
+		ha->isp_ops.disable_intrs(ha);
 
+	qla2x00_mem_free(ha);
 
 	ha->flags.online = 0;
 
@@ -1934,7 +1961,7 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
 {
 	struct list_head	*fcpl, *fcptemp;
 	fc_port_t	*fcport;
-	unsigned long	wtime;/* max wait time if mbx cmd is busy. */
+	unsigned int	wtime;/* max wait time if mbx cmd is busy. */
 
 	if (ha == NULL) {
 		/* error */
@@ -1943,11 +1970,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
 	}
 
 	/* Make sure all other threads are stopped. */
-	wtime = 60 * HZ;
-	while (ha->dpc_wait && wtime) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		wtime = schedule_timeout(wtime);
-	}
+	wtime = 60 * 1000;
+	while (ha->dpc_wait && wtime)
+		wtime = msleep_interruptible(wtime);
 
 	/* free ioctl memory */
 	qla2x00_free_ioctl_mem(ha);
@@ -2478,15 +2503,15 @@ qla2x00_timer(scsi_qla_host_t *ha)
 int
 qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
 {
-	const unsigned int step = HZ/10;
+	const unsigned int step = 100; /* msecs */
+	unsigned int iterations = jiffies_to_msecs(timeout)/100;
 
 	do {
 		if (!down_trylock(sema))
 			return 0;
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (schedule_timeout(step))
+		if (msleep_interruptible(step))
 			break;
-	} while ((timeout -= step) > 0);
+	} while (--iterations >= 0);
 
 	return -ETIMEDOUT;
 }

+ 0 - 34
drivers/scsi/qla2xxx/qla_sup.c

@@ -468,21 +468,12 @@ qla24xx_read_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
     uint32_t dwords)
 {
 	uint32_t i;
-	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-
-	/* Pause RISC. */
-	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
-	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
 
 	/* Dword reads to flash. */
 	for (i = 0; i < dwords; i++, faddr++)
 		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
 		    flash_data_to_access_addr(faddr)));
 
-	/* Release RISC pause. */
-	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
-	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
-
 	return dwptr;
 }
 
@@ -532,10 +523,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
 
 	ret = QLA_SUCCESS;
 
-	/* Pause RISC. */
-	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
-	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
-
 	qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id);
 	DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__,
 	    ha->host_no, man_id, flash_id));
@@ -599,10 +586,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
 	    RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
 	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
 
-	/* Release RISC pause. */
-	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
-	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
-
 	return ret;
 }
 
@@ -630,11 +613,6 @@ qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
 {
 	uint32_t i;
 	uint32_t *dwptr;
-	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-
-	/* Pause RISC. */
-	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
-	RD_REG_DWORD(&reg->hccr);	/* PCI Posting. */
 
 	/* Dword reads to flash. */
 	dwptr = (uint32_t *)buf;
@@ -642,10 +620,6 @@ qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
 		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
 		    nvram_data_to_access_addr(naddr)));
 
-	/* Release RISC pause. */
-	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
-	RD_REG_DWORD(&reg->hccr);	/* PCI Posting. */
-
 	return buf;
 }
 
@@ -690,10 +664,6 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
 
 	ret = QLA_SUCCESS;
 
-	/* Pause RISC. */
-	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
-	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
-
 	/* Enable flash write. */
 	WRT_REG_DWORD(&reg->ctrl_status,
 	    RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
@@ -728,9 +698,5 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
 	    RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
 	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
 
-	/* Release RISC pause. */
-	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
-	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
-
 	return ret;
 }

+ 2 - 2
drivers/scsi/qla2xxx/qla_version.h

@@ -19,9 +19,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.01.00b5-k"
+#define QLA2XXX_VERSION      "8.01.00-k"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	1
 #define QLA_DRIVER_PATCH_VER	0
-#define QLA_DRIVER_BETA_VER	5
+#define QLA_DRIVER_BETA_VER	0

+ 250 - 0
drivers/scsi/raid_class.c

@@ -0,0 +1,250 @@
+/*
+ * RAID Attributes
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/raid_class.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
+#define RAID_NUM_ATTRS	3
+
+struct raid_internal {
+	struct raid_template r;
+	struct raid_function_template *f;
+	/* The actual attributes */
+	struct class_device_attribute private_attrs[RAID_NUM_ATTRS];
+	/* The array of null terminated pointers to attributes 
+	 * needed by scsi_sysfs.c */
+	struct class_device_attribute *attrs[RAID_NUM_ATTRS + 1];
+};
+
+struct raid_component {
+	struct list_head node;
+	struct device *dev;
+	int num;
+};
+
+#define to_raid_internal(tmpl)	container_of(tmpl, struct raid_internal, r)
+
+#define tc_to_raid_internal(tcont) ({					\
+	struct raid_template *r =					\
+		container_of(tcont, struct raid_template, raid_attrs);	\
+	to_raid_internal(r);						\
+})
+
+#define ac_to_raid_internal(acont) ({					\
+	struct transport_container *tc =				\
+		container_of(acont, struct transport_container, ac);	\
+	tc_to_raid_internal(tc);					\
+})
+
+#define class_device_to_raid_internal(cdev) ({				\
+	struct attribute_container *ac =				\
+		attribute_container_classdev_to_container(cdev);	\
+	ac_to_raid_internal(ac);					\
+})
+	
+
+static int raid_match(struct attribute_container *cont, struct device *dev)
+{
+	/* We have to look for every subsystem that could house
+	 * emulated RAID devices, so start with SCSI */
+	struct raid_internal *i = ac_to_raid_internal(cont);
+
+	if (scsi_is_sdev_device(dev)) {
+		struct scsi_device *sdev = to_scsi_device(dev);
+
+		if (i->f->cookie != sdev->host->hostt)
+			return 0;
+
+		return i->f->is_raid(dev);
+	}
+	/* FIXME: look at other subsystems too */
+	return 0;
+}
+
+static int raid_setup(struct transport_container *tc, struct device *dev,
+		       struct class_device *cdev)
+{
+	struct raid_data *rd;
+
+	BUG_ON(class_get_devdata(cdev));
+
+	rd = kmalloc(sizeof(*rd), GFP_KERNEL);
+	if (!rd)
+		return -ENOMEM;
+
+	memset(rd, 0, sizeof(*rd));
+	INIT_LIST_HEAD(&rd->component_list);
+	class_set_devdata(cdev, rd);
+		
+	return 0;
+}
+
+static int raid_remove(struct transport_container *tc, struct device *dev,
+		       struct class_device *cdev)
+{
+	struct raid_data *rd = class_get_devdata(cdev);
+	struct raid_component *rc, *next;
+	class_set_devdata(cdev, NULL);
+	list_for_each_entry_safe(rc, next, &rd->component_list, node) {
+		char buf[40];
+		snprintf(buf, sizeof(buf), "component-%d", rc->num);
+		list_del(&rc->node);
+		sysfs_remove_link(&cdev->kobj, buf);
+		kfree(rc);
+	}
+	kfree(class_get_devdata(cdev));
+	return 0;
+}
+
+static DECLARE_TRANSPORT_CLASS(raid_class,
+			       "raid_devices",
+			       raid_setup,
+			       raid_remove,
+			       NULL);
+
+static struct {
+	enum raid_state	value;
+	char		*name;
+} raid_states[] = {
+	{ RAID_ACTIVE, "active" },
+	{ RAID_DEGRADED, "degraded" },
+	{ RAID_RESYNCING, "resyncing" },
+	{ RAID_OFFLINE, "offline" },
+};
+
+static const char *raid_state_name(enum raid_state state)
+{
+	int i;
+	char *name = NULL;
+
+	for (i = 0; i < sizeof(raid_states)/sizeof(raid_states[0]); i++) {
+		if (raid_states[i].value == state) {
+			name = raid_states[i].name;
+			break;
+		}
+	}
+	return name;
+}
+
+
+#define raid_attr_show_internal(attr, fmt, var, code)			\
+static ssize_t raid_show_##attr(struct class_device *cdev, char *buf)	\
+{									\
+	struct raid_data *rd = class_get_devdata(cdev);			\
+	code								\
+	return snprintf(buf, 20, #fmt "\n", var);			\
+}
+
+#define raid_attr_ro_states(attr, states, code)				\
+raid_attr_show_internal(attr, %s, name,					\
+	const char *name;						\
+	code								\
+	name = raid_##states##_name(rd->attr);				\
+)									\
+static CLASS_DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL)
+
+
+#define raid_attr_ro_internal(attr, code)				\
+raid_attr_show_internal(attr, %d, rd->attr, code)			\
+static CLASS_DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL)
+
+#define ATTR_CODE(attr)							\
+	struct raid_internal *i = class_device_to_raid_internal(cdev);	\
+	if (i->f->get_##attr)						\
+		i->f->get_##attr(cdev->dev);
+
+#define raid_attr_ro(attr)	raid_attr_ro_internal(attr, )
+#define raid_attr_ro_fn(attr)	raid_attr_ro_internal(attr, ATTR_CODE(attr))
+#define raid_attr_ro_state(attr)	raid_attr_ro_states(attr, attr, ATTR_CODE(attr))
+
+raid_attr_ro(level);
+raid_attr_ro_fn(resync);
+raid_attr_ro_state(state);
+
+void raid_component_add(struct raid_template *r,struct device *raid_dev,
+			struct device *component_dev)
+{
+	struct class_device *cdev =
+		attribute_container_find_class_device(&r->raid_attrs.ac,
+						      raid_dev);
+	struct raid_component *rc;
+	struct raid_data *rd = class_get_devdata(cdev);
+	char buf[40];
+
+	rc = kmalloc(sizeof(*rc), GFP_KERNEL);
+	if (!rc)
+		return;
+
+	INIT_LIST_HEAD(&rc->node);
+	rc->dev = component_dev;
+	rc->num = rd->component_count++;
+
+	snprintf(buf, sizeof(buf), "component-%d", rc->num);
+	list_add_tail(&rc->node, &rd->component_list);
+	sysfs_create_link(&cdev->kobj, &component_dev->kobj, buf);
+}
+EXPORT_SYMBOL(raid_component_add);
+
+struct raid_template *
+raid_class_attach(struct raid_function_template *ft)
+{
+	struct raid_internal *i = kmalloc(sizeof(struct raid_internal),
+					  GFP_KERNEL);
+	int count = 0;
+
+	if (unlikely(!i))
+		return NULL;
+
+	memset(i, 0, sizeof(*i));
+
+	i->f = ft;
+
+	i->r.raid_attrs.ac.class = &raid_class.class;
+	i->r.raid_attrs.ac.match = raid_match;
+	i->r.raid_attrs.ac.attrs = &i->attrs[0];
+
+	attribute_container_register(&i->r.raid_attrs.ac);
+
+	i->attrs[count++] = &class_device_attr_level;
+	i->attrs[count++] = &class_device_attr_resync;
+	i->attrs[count++] = &class_device_attr_state;
+
+	i->attrs[count] = NULL;
+	BUG_ON(count > RAID_NUM_ATTRS);
+
+	return &i->r;
+}
+EXPORT_SYMBOL(raid_class_attach);
+
+void
+raid_class_release(struct raid_template *r)
+{
+	struct raid_internal *i = to_raid_internal(r);
+
+	attribute_container_unregister(&i->r.raid_attrs.ac);
+
+	kfree(i);
+}
+EXPORT_SYMBOL(raid_class_release);
+
+static __init int raid_init(void)
+{
+	return transport_class_register(&raid_class);
+}
+
+static __exit void raid_exit(void)
+{
+	transport_class_unregister(&raid_class);
+}
+
+MODULE_AUTHOR("James Bottomley");
+MODULE_DESCRIPTION("RAID device class");
+MODULE_LICENSE("GPL");
+
+module_init(raid_init);
+module_exit(raid_exit);
+

+ 1 - 0
drivers/scsi/scsi_devinfo.c

@@ -192,6 +192,7 @@ static struct {
 	{"SGI", "RAID5", "*", BLIST_SPARSELUN},
 	{"SGI", "TP9100", "*", BLIST_REPORTLUN2},
 	{"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
+	{"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
 	{"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36},
 	{"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN},
 	{"SONY", "TSL", NULL, BLIST_FORCELUN},		/* DDS3 & DDS4 autoloaders */

+ 5 - 30
drivers/scsi/scsi_error.c

@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/interrupt.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
@@ -115,7 +116,6 @@ void scsi_add_timer(struct scsi_cmnd *scmd, int timeout,
 
 	add_timer(&scmd->eh_timeout);
 }
-EXPORT_SYMBOL(scsi_add_timer);
 
 /**
  * scsi_delete_timer - Delete/cancel timer for a given function.
@@ -143,7 +143,6 @@ int scsi_delete_timer(struct scsi_cmnd *scmd)
 
 	return rtn;
 }
-EXPORT_SYMBOL(scsi_delete_timer);
 
 /**
  * scsi_times_out - Timeout function for normal scsi commands.
@@ -776,9 +775,11 @@ retry_tur:
 		__FUNCTION__, scmd, rtn));
 	if (rtn == SUCCESS)
 		return 0;
-	else if (rtn == NEEDS_RETRY)
+	else if (rtn == NEEDS_RETRY) {
 		if (retry_cnt--)
 			goto retry_tur;
+		return 0;
+	}
 	return 1;
 }
 
@@ -1583,16 +1584,8 @@ int scsi_error_handler(void *data)
 	int rtn;
 	DECLARE_MUTEX_LOCKED(sem);
 
-	/*
-	 *    Flush resources
-	 */
-
-	daemonize("scsi_eh_%d", shost->host_no);
-
 	current->flags |= PF_NOFREEZE;
-
 	shost->eh_wait = &sem;
-	shost->ehandler = current;
 
 	/*
 	 * Wake up the thread that created us.
@@ -1600,8 +1593,6 @@ int scsi_error_handler(void *data)
 	SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
 					  " scsi_eh_%d\n",shost->host_no));
 
-	complete(shost->eh_notify);
-
 	while (1) {
 		/*
 		 * If we get a signal, it means we are supposed to go
@@ -1622,7 +1613,7 @@ int scsi_error_handler(void *data)
 		 * semaphores isn't unreasonable.
 		 */
 		down_interruptible(&sem);
-		if (shost->eh_kill)
+		if (kthread_should_stop())
 			break;
 
 		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
@@ -1661,22 +1652,6 @@ int scsi_error_handler(void *data)
 	 * Make sure that nobody tries to wake us up again.
 	 */
 	shost->eh_wait = NULL;
-
-	/*
-	 * Knock this down too.  From this point on, the host is flying
-	 * without a pilot.  If this is because the module is being unloaded,
-	 * that's fine.  If the user sent a signal to this thing, we are
-	 * potentially in real danger.
-	 */
-	shost->eh_active = 0;
-	shost->ehandler = NULL;
-
-	/*
-	 * If anyone is waiting for us to exit (i.e. someone trying to unload
-	 * a driver), then wake up that process to let them know we are on
-	 * the way out the door.
-	 */
-	complete_and_exit(shost->eh_notify, 0);
 	return 0;
 }
 

+ 9 - 9
drivers/scsi/scsi_ioctl.c

@@ -30,20 +30,20 @@
 
 #define MAX_BUF PAGE_SIZE
 
-/*
- * If we are told to probe a host, we will return 0 if  the host is not
- * present, 1 if the host is present, and will return an identifying
- * string at *arg, if arg is non null, filling to the length stored at
- * (int *) arg
+/**
+ * ioctl_probe  --  return host identification
+ * @host:	host to identify
+ * @buffer:	userspace buffer for identification
+ *
+ * Return an identifying string at @buffer, if @buffer is non-NULL, filling
+ * to the length stored at * (int *) @buffer.
  */
-
 static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
 {
 	unsigned int len, slen;
 	const char *string;
-	int temp = host->hostt->present;
 
-	if (temp && buffer) {
+	if (buffer) {
 		if (get_user(len, (unsigned int __user *) buffer))
 			return -EFAULT;
 
@@ -59,7 +59,7 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer)
 				return -EFAULT;
 		}
 	}
-	return temp;
+	return 1;
 }
 
 /*

+ 3 - 0
drivers/scsi/scsi_priv.h

@@ -63,6 +63,9 @@ extern int __init scsi_init_devinfo(void);
 extern void scsi_exit_devinfo(void);
 
 /* scsi_error.c */
+extern void scsi_add_timer(struct scsi_cmnd *, int,
+		void (*)(struct scsi_cmnd *));
+extern int scsi_delete_timer(struct scsi_cmnd *);
 extern void scsi_times_out(struct scsi_cmnd *cmd);
 extern int scsi_error_handler(void *host);
 extern int scsi_decide_disposition(struct scsi_cmnd *cmd);

+ 19 - 5
drivers/scsi/sd.c

@@ -972,7 +972,7 @@ static void
 sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
 {
 	unsigned char cmd[10];
-	unsigned long spintime_value = 0;
+	unsigned long spintime_expire = 0;
 	int retries, spintime;
 	unsigned int the_result;
 	struct scsi_sense_hdr sshdr;
@@ -1049,12 +1049,27 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
 				scsi_execute_req(sdkp->device, cmd, DMA_NONE,
 						 NULL, 0, &sshdr,
 						 SD_TIMEOUT, SD_MAX_RETRIES);
-				spintime_value = jiffies;
+				spintime_expire = jiffies + 100 * HZ;
+				spintime = 1;
 			}
-			spintime = 1;
 			/* Wait 1 second for next try */
 			msleep(1000);
 			printk(".");
+
+		/*
+		 * Wait for USB flash devices with slow firmware.
+		 * Yes, this sense key/ASC combination shouldn't
+		 * occur here.  It's characteristic of these devices.
+		 */
+		} else if (sense_valid &&
+				sshdr.sense_key == UNIT_ATTENTION &&
+				sshdr.asc == 0x28) {
+			if (!spintime) {
+				spintime_expire = jiffies + 5 * HZ;
+				spintime = 1;
+			}
+			/* Wait 1 second for next try */
+			msleep(1000);
 		} else {
 			/* we don't understand the sense code, so it's
 			 * probably pointless to loop */
@@ -1066,8 +1081,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
 			break;
 		}
 				
-	} while (spintime &&
-		 time_after(spintime_value + 100 * HZ, jiffies));
+	} while (spintime && time_before_eq(jiffies, spintime_expire));
 
 	if (spintime) {
 		if (scsi_status_is_good(the_result))

+ 4 - 4
drivers/scsi/sg.c

@@ -61,7 +61,7 @@ static int sg_version_num = 30533;	/* 2 digits for each component */
 
 #ifdef CONFIG_SCSI_PROC_FS
 #include <linux/proc_fs.h>
-static char *sg_version_date = "20050328";
+static char *sg_version_date = "20050901";
 
 static int sg_proc_init(void);
 static void sg_proc_cleanup(void);
@@ -1794,12 +1794,12 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
 	          unsigned long uaddr, size_t count, int rw,
 	          unsigned long max_pfn)
 {
+	unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	unsigned long start = uaddr >> PAGE_SHIFT;
+	const int nr_pages = end - start;
 	int res, i, j;
-	unsigned int nr_pages;
 	struct page **pages;
 
-	nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
-
 	/* User attempted Overflow! */
 	if ((uaddr + count) < uaddr)
 		return -EINVAL;

+ 4 - 4
drivers/scsi/st.c

@@ -17,7 +17,7 @@
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static char *verstr = "20050802";
+static char *verstr = "20050830";
 
 #include <linux/module.h>
 
@@ -4440,12 +4440,12 @@ static int st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pag
 static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
 			      unsigned long uaddr, size_t count, int rw)
 {
+	unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	unsigned long start = uaddr >> PAGE_SHIFT;
+	const int nr_pages = end - start;
 	int res, i, j;
-	unsigned int nr_pages;
 	struct page **pages;
 
-	nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
-
 	/* User attempted Overflow! */
 	if ((uaddr + count) < uaddr)
 		return -EINVAL;

+ 2 - 2
include/linux/attribute_container.h

@@ -11,12 +11,12 @@
 
 #include <linux/device.h>
 #include <linux/list.h>
+#include <linux/klist.h>
 #include <linux/spinlock.h>
 
 struct attribute_container {
 	struct list_head	node;
-	struct list_head	containers;
-	spinlock_t		containers_lock;
+	struct klist		containers;
 	struct class		*class;
 	struct class_device_attribute **attrs;
 	int (*match)(struct attribute_container *, struct device *);

+ 59 - 0
include/linux/raid_class.h

@@ -0,0 +1,59 @@
+/*
+ */
+#include <linux/transport_class.h>
+
+struct raid_template {
+	struct transport_container raid_attrs;
+};
+
+struct raid_function_template {
+	void *cookie;
+	int (*is_raid)(struct device *);
+	void (*get_resync)(struct device *);
+	void (*get_state)(struct device *);
+};
+
+enum raid_state {
+	RAID_ACTIVE = 1,
+	RAID_DEGRADED,
+	RAID_RESYNCING,
+	RAID_OFFLINE,
+};
+
+struct raid_data {
+	struct list_head component_list;
+	int component_count;
+	int level;
+	enum raid_state state;
+	int resync;
+};
+
+#define DEFINE_RAID_ATTRIBUTE(type, attr)				      \
+static inline void							      \
+raid_set_##attr(struct raid_template *r, struct device *dev, type value) {    \
+	struct class_device *cdev =					      \
+		attribute_container_find_class_device(&r->raid_attrs.ac, dev);\
+	struct raid_data *rd;						      \
+	BUG_ON(!cdev);							      \
+	rd = class_get_devdata(cdev);					      \
+	rd->attr = value;						      \
+}									      \
+static inline type							      \
+raid_get_##attr(struct raid_template *r, struct device *dev) {		      \
+	struct class_device *cdev =					      \
+		attribute_container_find_class_device(&r->raid_attrs.ac, dev);\
+	struct raid_data *rd;						      \
+	BUG_ON(!cdev);							      \
+	rd = class_get_devdata(cdev);					      \
+	return rd->attr;						      \
+}
+
+DEFINE_RAID_ATTRIBUTE(int, level)
+DEFINE_RAID_ATTRIBUTE(int, resync)
+DEFINE_RAID_ATTRIBUTE(enum raid_state, state)
+	
+struct raid_template *raid_class_attach(struct raid_function_template *);
+void raid_class_release(struct raid_template *);
+
+void raid_component_add(struct raid_template *, struct device *,
+			struct device *);

+ 0 - 3
include/scsi/scsi_eh.h

@@ -35,9 +35,6 @@ static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr)
 }
 
 
-extern void scsi_add_timer(struct scsi_cmnd *, int,
-		void (*)(struct scsi_cmnd *));
-extern int scsi_delete_timer(struct scsi_cmnd *);
 extern void scsi_report_bus_reset(struct Scsi_Host *, int);
 extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
 extern int scsi_block_when_processing_errors(struct scsi_device *);

+ 0 - 2
include/scsi/scsi_host.h

@@ -467,12 +467,10 @@ struct Scsi_Host {
 	struct task_struct    * ehandler;  /* Error recovery thread. */
 	struct semaphore      * eh_wait;   /* The error recovery thread waits
 					      on this. */
-	struct completion     * eh_notify; /* wait for eh to begin or end */
 	struct semaphore      * eh_action; /* Wait for specific actions on the
                                           host. */
 	unsigned int            eh_active:1; /* Indicates the eh thread is awake and active if
                                           this is true. */
-	unsigned int            eh_kill:1; /* set when killing the eh thread */
 	wait_queue_head_t       host_wait;
 	struct scsi_host_template *hostt;
 	struct scsi_transport_template *transportt;