linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/16]  qla2xxx: update qla2xxx driver to 8.01.00.
@ 2005-08-27  2:07 Andrew Vasquez
  2005-08-27  2:08 ` [PATCH 1/16] qla2xxx: Use dma_get_required_mask() in determining the 'ideal' DMA mask Andrew Vasquez
                   ` (15 more replies)
  0 siblings, 16 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:07 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

James,

Here's a set of patches which fix a handful of outstanding issues with
the qla2xxx driver.  Please apply.

Summary of patches:

  Use dma_get_required_mask() in determining the 'ideal' DMA mask.
  Export class-of-service (COS) information.
  Correct ISP24xx soft-reset handling.
  Add FDMI support.
  Correct domain/area exclusion logic.
  Simplify redundant target/device reset logic.
  Correct LED scheme definition.
  Remove RISC pause/release barriers during flash manipulation.
  Remove redundant call to pci_unmap_sg().
  Add change_queue_depth/type() API support.
  Add host attributes.
  Generalize WWN to u64 interger conversions.
  Remove bad call to fc_remove_host() during probe failure.
  Stop firmware execution at unintialization time.
  Update version number to 8.01.00-k.
  Replace schedule_timeout().

All patches can be found at the following URL:

        ftp://ftp.qlogic.com/outgoing/linux/patches/8.x/8.01.00k/

Regards,
Andrew Vasquez
QLogic Corporation

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 1/16]  qla2xxx: Use dma_get_required_mask() in determining the 'ideal' DMA mask.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
@ 2005-08-27  2:08 ` Andrew Vasquez
  2005-08-27  2:08 ` [PATCH 2/16] qla2xxx: Export class-of-service (COS) information Andrew Vasquez
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:08 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Use dma_get_required_mask() in determining the 'ideal' DMA mask.

In order to efficiently utilise the ISP's IOCB
request-queue, use the dma_get_required_mask() function to
determine the use of command-type 2 or 3 IOCBs when queueing
SCSI commands.  This applies to ISP2[123]xx chips only, as
the ISP24xx uses command-type 7 IOCBs which use 64bit DSDs.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_os.c |   33 ++++++++++-----------------------
 1 files changed, 10 insertions(+), 23 deletions(-)

2978995966996a021e5ac86dbccf917846553754
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1113,36 +1113,23 @@ qla2xxx_slave_destroy(struct scsi_device
 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

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 2/16]  qla2xxx: Export class-of-service (COS) information.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
  2005-08-27  2:08 ` [PATCH 1/16] qla2xxx: Use dma_get_required_mask() in determining the 'ideal' DMA mask Andrew Vasquez
@ 2005-08-27  2:08 ` Andrew Vasquez
  2005-08-27  2:08 ` [PATCH 3/16] qla2xxx: Correct ISP24xx soft-reset handling Andrew Vasquez
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:08 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Export class-of-service (COS) information.

Export COS information for the fc_host and fc_remote_port
objects added by the driver.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_attr.c |    4 ++++
 drivers/scsi/qla2xxx/qla_def.h  |    1 +
 drivers/scsi/qla2xxx/qla_init.c |    7 +++++++
 drivers/scsi/qla2xxx/qla_mbx.c  |   14 ++++++++++++++
 4 files changed, 26 insertions(+), 0 deletions(-)

eae4fae7fed2123a1557f6e1b0a1e4e363388cea
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -304,10 +304,13 @@ struct fc_function_template qla2xxx_tran
 
 	.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 +332,5 @@ qla2x00_init_host_attr(scsi_qla_host_t *
 	    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;
 }
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1673,6 +1673,7 @@ typedef struct fc_port {
     	uint8_t cur_path;		/* current path id */
 
 	struct fc_rport *rport;
+	u32 supported_classes;
 } fc_port_t;
 
 /*
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1697,6 +1697,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha
 	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);
 }
@@ -2075,6 +2076,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t 
 		return;
 	}
 	rport->dd_data = fcport;
+	rport->supported_classes = fcport->supported_classes;
 
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
 	if (fcport->port_type == FCT_INITIATOR)
@@ -2794,6 +2796,11 @@ qla2x00_fabric_login(scsi_qla_host_t *ha
 				}
 			}
 
+			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) {
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/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)
@@ -1326,6 +1327,10 @@ qla2x00_get_port_database(scsi_qla_host_
 			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 +1666,13 @@ qla24xx_login_fabric(scsi_qla_host_t *ha
 				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 +1735,8 @@ qla2x00_login_fabric(scsi_qla_host_t *ha
 		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) {

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 3/16]  qla2xxx: Correct ISP24xx soft-reset handling.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
  2005-08-27  2:08 ` [PATCH 1/16] qla2xxx: Use dma_get_required_mask() in determining the 'ideal' DMA mask Andrew Vasquez
  2005-08-27  2:08 ` [PATCH 2/16] qla2xxx: Export class-of-service (COS) information Andrew Vasquez
@ 2005-08-27  2:08 ` Andrew Vasquez
  2005-08-27  2:26   ` James Bottomley
  2005-08-27  2:08 ` [PATCH 4/16] qla2xxx: Add FDMI support Andrew Vasquez
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:08 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Correct ISP24xx soft-reset handling.

A driver must wait 100us before attempting an MMIO operation
to the RISC after a soft-reset has been initiated.  A
similar delay was needed with earlier ISPs.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_dbg.c  |   10 +++++++---
 drivers/scsi/qla2xxx/qla_init.c |   10 +++++++---
 2 files changed, 14 insertions(+), 6 deletions(-)

de11680e687bc8e8a0d34e42b872a60dd9ab7db2
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -1526,10 +1526,14 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int
 
 		WRT_REG_DWORD(&reg->ctrl_status,
 		    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
-		RD_REG_DWORD(&reg->ctrl_status);
+		/*
+		 * It is necessary to delay here since the card doesn't respond
+		 * to PCI reads during a reset. On some architectures this will
+		 * result in an MCA.
+		*/
+		udelay(100);
 
 		/* Wait for firmware to complete NVRAM accesses. */
-		udelay(5);
 		mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
 		for (cnt = 10000 ; cnt && mb[0]; cnt--) {
 			udelay(5);
@@ -1537,7 +1541,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int
 			barrier();
 		}
 
-		udelay(20);
+		/* Wait for soft-reset to complete. */
 		for (cnt = 0; cnt < 30000; cnt++) {
 			if ((RD_REG_DWORD(&reg->ctrl_status) &
 			    CSRX_ISP_SOFT_RESET) == 0)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -589,10 +589,14 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
 
 	WRT_REG_DWORD(&reg->ctrl_status,
 	    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
-	RD_REG_DWORD(&reg->ctrl_status);
+	/*
+	 * It is necessary to delay here since the card doesn't respond to PCI
+	 * reads during a reset. On some architectures this will result in an
+	 * MCA.
+	 */
+	udelay(100);
 
 	/* Wait for firmware to complete NVRAM accesses. */
-	udelay(5);
 	d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
 	for (cnt = 10000 ; cnt && d2; cnt--) {
 		udelay(5);
@@ -600,7 +604,7 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
 		barrier();
 	}
 
-	udelay(20);
+	/* Wait for soft-reset to complete. */
 	d2 = RD_REG_DWORD(&reg->ctrl_status);
 	for (cnt = 6000000 ; cnt && (d2 & CSRX_ISP_SOFT_RESET); cnt--) {
 		udelay(5);

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 4/16]  qla2xxx: Add FDMI support.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (2 preceding siblings ...)
  2005-08-27  2:08 ` [PATCH 3/16] qla2xxx: Correct ISP24xx soft-reset handling Andrew Vasquez
@ 2005-08-27  2:08 ` Andrew Vasquez
  2005-08-27  2:08 ` [PATCH 5/16] qla2xxx: Correct domain/area exclusion logic Andrew Vasquez
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:08 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Add FDMI support.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_dbg.h  |    7 
 drivers/scsi/qla2xxx/qla_def.h  |  151 ++++++++++
 drivers/scsi/qla2xxx/qla_gbl.h  |    4 
 drivers/scsi/qla2xxx/qla_gs.c   |  564 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_init.c |    6 
 drivers/scsi/qla2xxx/qla_isr.c  |    2 
 drivers/scsi/qla2xxx/qla_mbx.c  |    2 
 drivers/scsi/qla2xxx/qla_os.c   |   10 +
 8 files changed, 741 insertions(+), 5 deletions(-)

65d5302a171f3f42542962aa597500334f41bdf4
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/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)
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/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 */
@@ -1131,10 +1132,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;
@@ -1728,6 +1726,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
@@ -1769,6 +1769,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;
@@ -1826,6 +1920,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;
 };
 
@@ -1883,6 +2014,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;
 };
 
@@ -2033,6 +2170,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);
@@ -2112,6 +2251,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
@@ -2205,6 +2345,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;
 
@@ -2319,6 +2460,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;
@@ -2378,6 +2520,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
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/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 *);
 
@@ -269,6 +270,9 @@ extern int qla2x00_rft_id(scsi_qla_host_
 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.
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/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;
+}
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -88,6 +88,7 @@ qla2x00_initialize_adapter(scsi_qla_host
 	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);
@@ -2136,6 +2137,11 @@ qla2x00_configure_fabric(scsi_qla_host_t
 		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;
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -451,6 +451,8 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 
 		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);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -252,7 +252,7 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 			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",
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -88,6 +88,12 @@ static void qla2x00_free_device(scsi_qla
 
 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
  */
@@ -1303,6 +1309,7 @@ int qla2x00_probe_one(struct pci_dev *pd
 	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;
@@ -1325,6 +1332,7 @@ int qla2x00_probe_one(struct pci_dev *pd
 	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;
@@ -1362,6 +1370,7 @@ int qla2x00_probe_one(struct pci_dev *pd
 		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;
@@ -1382,6 +1391,7 @@ int qla2x00_probe_one(struct pci_dev *pd
 		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;

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 5/16]  qla2xxx: Correct domain/area exclusion logic.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (3 preceding siblings ...)
  2005-08-27  2:08 ` [PATCH 4/16] qla2xxx: Add FDMI support Andrew Vasquez
@ 2005-08-27  2:08 ` Andrew Vasquez
  2005-08-27  2:08 ` [PATCH 6/16] qla2xxx: Simplify redundant target/device reset logic Andrew Vasquez
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:08 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Correct domain/area exclusion logic.

In an FL topology, limit port recognition to those devices
not within the same area and domain of the ISP.  The
firmware will recogonize such devices during local-loop
discovery.

Some devices may respond to a PLOGI before they have
completed their fabric login or they may not be a public
device. In this case they will report:

        domain == 00
        area == 00
        alpa == <XX>

which is valid. Exclude such devices from local loop
discovery.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_init.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

051e6f0a69a8a9b3012dfe568eb11d74362df53c
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1904,7 +1904,8 @@ qla2x00_configure_local_loop(scsi_qla_ho
 			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. */
@@ -2404,6 +2405,12 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
 		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;

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 6/16]  qla2xxx: Simplify redundant target/device reset logic.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (4 preceding siblings ...)
  2005-08-27  2:08 ` [PATCH 5/16] qla2xxx: Correct domain/area exclusion logic Andrew Vasquez
@ 2005-08-27  2:08 ` Andrew Vasquez
  2005-08-27  2:09 ` [PATCH 7/16] qla2xxx: Correct LED scheme definition Andrew Vasquez
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:08 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Simplify redundant target/device reset logic.

Remove redundant qla2x00_target_reset() function in favour of
the equivalent qla2x00_device_reset().  Update callers of
old function.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_gbl.h |    3 --
 drivers/scsi/qla2xxx/qla_mbx.c |   52 ----------------------------------------
 drivers/scsi/qla2xxx/qla_os.c  |    2 +-
 3 files changed, 1 insertions(+), 56 deletions(-)

3afc7a5ea763a249b0da88944967d4e52868c41c
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -148,9 +148,6 @@ 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 *);
 
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -984,58 +984,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.
  *
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1022,7 +1022,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;
 		}

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 7/16]  qla2xxx: Correct LED scheme definition.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (5 preceding siblings ...)
  2005-08-27  2:08 ` [PATCH 6/16] qla2xxx: Simplify redundant target/device reset logic Andrew Vasquez
@ 2005-08-27  2:09 ` Andrew Vasquez
  2005-08-27  2:09 ` [PATCH 8/16] qla2xxx: Remove RISC pause/release barriers during flash manipulation Andrew Vasquez
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:09 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Correct LED scheme definition.

Original implementation used an overloaded bit in the EFI
parameters.  The correct bit is BIT_4 of the special_options
section of NVRAM.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_def.h  |    4 ++--
 drivers/scsi/qla2xxx/qla_init.c |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

54e2e1934181c71de6b758123c74f397b8e8fb00
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -914,7 +914,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)
@@ -1036,7 +1036,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)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1568,7 +1568,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;

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 8/16]  qla2xxx: Remove RISC pause/release barriers during flash manipulation.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (6 preceding siblings ...)
  2005-08-27  2:09 ` [PATCH 7/16] qla2xxx: Correct LED scheme definition Andrew Vasquez
@ 2005-08-27  2:09 ` Andrew Vasquez
  2005-08-27  2:09 ` [PATCH 9/16] qla2xxx: Remove redundant call to pci_unmap_sg() Andrew Vasquez
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:09 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Remove RISC pause/release barriers during flash manipulation.

Remove unnecessary RISC pause/release barriers during
ISP24xx flash manipulation.  The ISP24xx can arbitrate flash
access requests during RISC executions.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_sup.c |   34 ----------------------------------
 1 files changed, 0 insertions(+), 34 deletions(-)

2fa684b695e1ff9420557a5488cc00e7ddc42499
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -468,21 +468,12 @@ qla24xx_read_flash_data(scsi_qla_host_t 
     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
 
 	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
 	    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 
 {
 	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 
 		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
 
 	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
 	    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;
 }

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 9/16]  qla2xxx: Remove redundant call to pci_unmap_sg().
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (7 preceding siblings ...)
  2005-08-27  2:09 ` [PATCH 8/16] qla2xxx: Remove RISC pause/release barriers during flash manipulation Andrew Vasquez
@ 2005-08-27  2:09 ` Andrew Vasquez
  2005-08-27  2:09 ` [PATCH 10/16] qla2xxx: Add change_queue_depth/type() API support Andrew Vasquez
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:09 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Remove redundant call to pci_unmap_sg().

In a corner-case failure where the request-q does not
contain enough entries for a given request, pci_unmap_sg()
would be called twice.  Remove direct call and let the
failure-path logic handle the unmapping.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_iocb.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

a1f5bbf1b3a49977421a852127630a37ec5b90b1
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/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;

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 10/16] qla2xxx: Add change_queue_depth/type() API support.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (8 preceding siblings ...)
  2005-08-27  2:09 ` [PATCH 9/16] qla2xxx: Remove redundant call to pci_unmap_sg() Andrew Vasquez
@ 2005-08-27  2:09 ` Andrew Vasquez
  2005-08-27  2:09 ` [PATCH 11/16] qla2xxx: Add host attributes Andrew Vasquez
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:09 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Add change_queue_depth/type() API support.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_os.c |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)

c61d82773aa6675dd6e8553f5aee97a743948689
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -111,6 +111,9 @@ static int qla2xxx_eh_host_reset(struct 
 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",
@@ -125,6 +128,8 @@ static struct scsi_host_template qla2x00
 
 	.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,
@@ -151,6 +156,8 @@ static struct scsi_host_template qla24xx
 
 	.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,
@@ -1109,6 +1116,28 @@ qla2xxx_slave_destroy(struct scsi_device
 	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

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 11/16] qla2xxx: Add host attributes.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (9 preceding siblings ...)
  2005-08-27  2:09 ` [PATCH 10/16] qla2xxx: Add change_queue_depth/type() API support Andrew Vasquez
@ 2005-08-27  2:09 ` Andrew Vasquez
  2005-08-27  2:09 ` [PATCH 12/16] qla2xxx: Generalize WWN to u64 interger conversions Andrew Vasquez
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:09 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Add host attributes.

Export additional host information vi the shost_attrs member in
the scsi_host template.  Attributes include: driver version,
firmware version, ISP serial number, ISP type, ISP product ID,
HBA model name, HBA model description, PCI interconnect
information, and HBA port state.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_attr.c |  132 +++++++++++++++++++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_gbl.h  |    2 +
 drivers/scsi/qla2xxx/qla_os.c   |    2 +
 3 files changed, 136 insertions(+), 0 deletions(-)

b274c510177f2013b5e00604e226878656b4dc77
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -211,6 +211,138 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t 
 	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
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -290,6 +290,8 @@ extern void qla2x00_cancel_io_descriptor
 /*
  * 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 *);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -140,6 +140,7 @@ static struct scsi_host_template qla2x00
 	 * which equates to 0x800000 sectors.
 	 */
 	.max_sectors		= 0xFFFF,
+	.shost_attrs		= qla2x00_host_attrs,
 };
 
 static struct scsi_host_template qla24xx_driver_template = {
@@ -164,6 +165,7 @@ static struct scsi_host_template qla24xx
 	.sg_tablesize		= SG_ALL,
 
 	.max_sectors		= 0xFFFF,
+	.shost_attrs		= qla2x00_host_attrs,
 };
 
 static struct scsi_transport_template *qla2xxx_transport_template = NULL;

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 12/16] qla2xxx: Generalize WWN to u64 interger conversions.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (10 preceding siblings ...)
  2005-08-27  2:09 ` [PATCH 11/16] qla2xxx: Add host attributes Andrew Vasquez
@ 2005-08-27  2:09 ` Andrew Vasquez
  2005-08-27 10:40   ` Christoph Hellwig
  2005-08-27  2:10 ` [PATCH 13/16] qla2xxx: Remove bad call to fc_remove_host() during probe failure Andrew Vasquez
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:09 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Generalize WWN to u64 interger conversions.

On some platforms the hard-casting of the 8 byte node_name
and port_name arrays to an u64 would cause unaligned-access
warnings.  Generalize the conversions with consistent
shifting of WWN bytes.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_attr.c |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

c7a5df1dc950e8a1cc04aa9a184619dfc78e5ed6
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -345,6 +345,15 @@ struct class_device_attribute *qla2x00_h
 
 /* Host attributes. */
 
+static u64
+wwn_to_u64(uint8_t *wwn)
+{
+	return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 |
+	    (u64)wwn[2] << 40 | (u64)wwn[3] << 32 |
+	    (u64)wwn[4] << 24 | (u64)wwn[5] << 16 |
+	    (u64)wwn[6] <<  8 | (u64)wwn[7];
+}
+
 static void
 qla2x00_get_host_port_id(struct Scsi_Host *shost)
 {
@@ -360,16 +369,16 @@ qla2x00_get_starget_node_name(struct scs
 	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
 	scsi_qla_host_t *ha = to_qla_host(host);
 	fc_port_t *fcport;
-	uint64_t node_name = 0;
+	u64 node_name = 0;
 
 	list_for_each_entry(fcport, &ha->fcports, list) {
 		if (starget->id == fcport->os_target_id) {
-			node_name = *(uint64_t *)fcport->node_name;
+			node_name = wwn_to_u64(fcport->node_name);
 			break;
 		}
 	}
 
-	fc_starget_node_name(starget) = be64_to_cpu(node_name);
+	fc_starget_node_name(starget) = node_name;
 }
 
 static void
@@ -378,16 +387,16 @@ qla2x00_get_starget_port_name(struct scs
 	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
 	scsi_qla_host_t *ha = to_qla_host(host);
 	fc_port_t *fcport;
-	uint64_t port_name = 0;
+	u64 port_name = 0;
 
 	list_for_each_entry(fcport, &ha->fcports, list) {
 		if (starget->id == fcport->os_target_id) {
-			port_name = *(uint64_t *)fcport->port_name;
+			port_name = wwn_to_u64(fcport->port_name);
 			break;
 		}
 	}
 
-	fc_starget_port_name(starget) = be64_to_cpu(port_name);
+	fc_starget_port_name(starget) = port_name;
 }
 
 static void
@@ -460,9 +469,7 @@ struct fc_function_template qla2xxx_tran
 void
 qla2x00_init_host_attr(scsi_qla_host_t *ha)
 {
-	fc_host_node_name(ha->host) =
-	    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_node_name(ha->host) = wwn_to_u64(ha->init_cb->node_name);
+	fc_host_port_name(ha->host) = wwn_to_u64(ha->init_cb->port_name);
 	fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
 }

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 13/16] qla2xxx: Remove bad call to fc_remove_host() during probe failure.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (11 preceding siblings ...)
  2005-08-27  2:09 ` [PATCH 12/16] qla2xxx: Generalize WWN to u64 interger conversions Andrew Vasquez
@ 2005-08-27  2:10 ` Andrew Vasquez
  2005-08-27  2:10 ` [PATCH 14/16] qla2xxx: Replace schedule_timeout() Andrew Vasquez
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:10 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Remove bad call to fc_remove_host() during probe failure.

fc_remove_host() should only be called after a scsi_host has
been successfully added via scsi_add_host() -- any failures
while qla2xxx probing would result in an incorrect call to
fc_remove_host() during cleanup.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_os.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

a4fe148ca8c724f44cab281c162043d3ca81c60c
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1586,8 +1586,6 @@ int qla2x00_probe_one(struct pci_dev *pd
 	return 0;
 
 probe_failed:
-	fc_remove_host(ha->host);
-
 	qla2x00_free_device(ha);
 
 	scsi_host_put(host);

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 14/16] qla2xxx: Replace schedule_timeout().
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (12 preceding siblings ...)
  2005-08-27  2:10 ` [PATCH 13/16] qla2xxx: Remove bad call to fc_remove_host() during probe failure Andrew Vasquez
@ 2005-08-27  2:10 ` Andrew Vasquez
  2005-08-27  2:10 ` [PATCH 15/16] qla2xxx: Stop firmware execution at unintialization time Andrew Vasquez
  2005-08-27  2:10 ` [PATCH 16/16] qla2xxx: Update version number to 8.01.00-k Andrew Vasquez
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:10 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Replace schedule_timeout().
From: Nishanth Aravamudan <nacc@us.ibm.com>
Date: 1125377408 -0700

Replace schedule_timeout() with
msleep()/msleep_interruptible() as appropriate, to guarantee the task
delays as expected.

Patch is compile-tested.

Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Signed-off-by: Domen Puncer <domen@coderock.org>
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_os.c |   25 +++++++++++--------------
 1 files changed, 11 insertions(+), 14 deletions(-)

e7a48fd7d795d483405f7b30990e3745a2668288
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -502,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;
@@ -1960,7 +1959,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 */
@@ -1969,11 +1968,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);
@@ -2504,15 +2501,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;
 }

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 15/16] qla2xxx: Stop firmware execution at unintialization time.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (13 preceding siblings ...)
  2005-08-27  2:10 ` [PATCH 14/16] qla2xxx: Replace schedule_timeout() Andrew Vasquez
@ 2005-08-27  2:10 ` Andrew Vasquez
  2005-08-27  2:10 ` [PATCH 16/16] qla2xxx: Update version number to 8.01.00-k Andrew Vasquez
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:10 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Stop firmware execution at unintialization time.

On ISP24xx parts, stop execution of firmware during ISP
tear-down.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_def.h |    1 +
 drivers/scsi/qla2xxx/qla_gbl.h |    3 +++
 drivers/scsi/qla2xxx/qla_mbx.c |   30 ++++++++++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_os.c  |   14 ++++++++------
 4 files changed, 42 insertions(+), 6 deletions(-)

928d73db7de14683cc79e1672027ab0e75ccb9cc
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -631,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). */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -213,6 +213,9 @@ qla2x00_get_serdes_params(scsi_qla_host_
 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.
  */
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2427,3 +2427,32 @@ qla2x00_set_serdes_params(scsi_qla_host_
 
 	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;
+}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -79,7 +79,7 @@ module_param(ql2xloginretrycount, int, S
 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.");
@@ -1626,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);
@@ -1649,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;
 

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 16/16] qla2xxx: Update version number to 8.01.00-k.
  2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
                   ` (14 preceding siblings ...)
  2005-08-27  2:10 ` [PATCH 15/16] qla2xxx: Stop firmware execution at unintialization time Andrew Vasquez
@ 2005-08-27  2:10 ` Andrew Vasquez
  15 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-27  2:10 UTC (permalink / raw)
  To: James Bottomley, Linux-SCSI Mailing List; +Cc: Andrew Vasquez

Update version number to 8.01.00-k.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

 drivers/scsi/qla2xxx/qla_version.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

9fdabc46aa84637af6518661786d624da60830c5
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/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

-- 
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/16]  qla2xxx: Correct ISP24xx soft-reset handling.
  2005-08-27  2:08 ` [PATCH 3/16] qla2xxx: Correct ISP24xx soft-reset handling Andrew Vasquez
@ 2005-08-27  2:26   ` James Bottomley
  2005-08-29 16:04     ` Andrew Vasquez
  0 siblings, 1 reply; 24+ messages in thread
From: James Bottomley @ 2005-08-27  2:26 UTC (permalink / raw)
  To: Andrew Vasquez; +Cc: Linux-SCSI Mailing List

On Fri, 2005-08-26 at 19:08 -0700, Andrew Vasquez wrote:
>  		WRT_REG_DWORD(&reg->ctrl_status,
>  		    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
> -		RD_REG_DWORD(&reg->ctrl_status);
> +		/*
> +		 * It is necessary to delay here since the card doesn't respond
> +		 * to PCI reads during a reset. On some architectures this will
> +		 * result in an MCA.
> +		*/
> +		udelay(100);

Removing the read introduces a potential write posting bug, doesn't?
And again:


> @@ -589,10 +589,14 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
>  
>         WRT_REG_DWORD(&reg->ctrl_status,
>             CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
> -       RD_REG_DWORD(&reg->ctrl_status);

James



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 12/16] qla2xxx: Generalize WWN to u64 interger conversions.
  2005-08-27  2:09 ` [PATCH 12/16] qla2xxx: Generalize WWN to u64 interger conversions Andrew Vasquez
@ 2005-08-27 10:40   ` Christoph Hellwig
  2005-08-31 22:18     ` [PATCH 1/3] " Andrew Vasquez
  0 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2005-08-27 10:40 UTC (permalink / raw)
  To: Andrew Vasquez; +Cc: James Bottomley, Linux-SCSI Mailing List

On Fri, Aug 26, 2005 at 07:09:50PM -0700, Andrew Vasquez wrote:
> Generalize WWN to u64 interger conversions.
> 
> On some platforms the hard-casting of the 8 byte node_name
> and port_name arrays to an u64 would cause unaligned-access
> warnings.  Generalize the conversions with consistent
> shifting of WWN bytes.
> 
> Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
> ---
> 
>  drivers/scsi/qla2xxx/qla_attr.c |   27 +++++++++++++++++----------
>  1 files changed, 17 insertions(+), 10 deletions(-)
> 
> c7a5df1dc950e8a1cc04aa9a184619dfc78e5ed6
> diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
> --- a/drivers/scsi/qla2xxx/qla_attr.c
> +++ b/drivers/scsi/qla2xxx/qla_attr.c
> @@ -345,6 +345,15 @@ struct class_device_attribute *qla2x00_h
>  
>  /* Host attributes. */
>  
> +static u64
> +wwn_to_u64(uint8_t *wwn)
> +{
> +	return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 |
> +	    (u64)wwn[2] << 40 | (u64)wwn[3] << 32 |
> +	    (u64)wwn[4] << 24 | (u64)wwn[5] << 16 |
> +	    (u64)wwn[6] <<  8 | (u64)wwn[7];
> +}

Shouldn't this go into the transport class?  Could probably be an inline
aswell.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/16]  qla2xxx: Correct ISP24xx soft-reset handling.
  2005-08-27  2:26   ` James Bottomley
@ 2005-08-29 16:04     ` Andrew Vasquez
  0 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-29 16:04 UTC (permalink / raw)
  To: James Bottomley; +Cc: Linux-SCSI Mailing List

On Fri, 26 Aug 2005, James Bottomley wrote:

> On Fri, 2005-08-26 at 19:08 -0700, Andrew Vasquez wrote:
> >  		WRT_REG_DWORD(&reg->ctrl_status,
> >  		    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
> > -		RD_REG_DWORD(&reg->ctrl_status);
> > +		/*
> > +		 * It is necessary to delay here since the card doesn't respond
> > +		 * to PCI reads during a reset. On some architectures this will
> > +		 * result in an MCA.
> > +		*/
> > +		udelay(100);
> 
> Removing the read introduces a potential write posting bug, doesn't?

Possibly, but that has been the case all software drivers have had to
contend with after an ISP soft-reset:

	...
	/* Reset ISP chip. */
	WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);

	/* Wait for RISC to recover from reset. */
	if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
		/*
		 * It is necessary to for a delay here since the
		 * card doesn't respond to PCI reads during a
		 * reset. On some architectures this will
		 * result in an MCA.
		 */
		udelay(20);
		...

During the soft-reset, the ISP cannot respond to the MMIO read until
completion.  On several platforms, the subsequent readl() without the
delay would cause machine checks.

Unfortunately, this has been a risk we've come to accept. We're still
evaluating the possibility of using a config-space read as a means of
flushing any posted writes -- since the RISC state-machines can handle
the request while resetting.  I'll ping the hardware folks again, but
in the interim, the udelay() will need to be present.

--
Andrew Vasquez

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 1/3] Generalize WWN to u64 interger conversions.
  2005-08-27 10:40   ` Christoph Hellwig
@ 2005-08-31 22:18     ` Andrew Vasquez
  2005-08-31 22:21       ` [PATCH 2/3] qla2xxx: use wwn_to_u64() transport helper Andrew Vasquez
                         ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-31 22:18 UTC (permalink / raw)
  To: James Bottomley; +Cc: Christoph Hellwig, Linux-SCSI Mailing List, Smart, James

> > --- a/drivers/scsi/qla2xxx/qla_attr.c
> > +++ b/drivers/scsi/qla2xxx/qla_attr.c
> > @@ -345,6 +345,15 @@ struct class_device_attribute *qla2x00_h
> >  
> >  /* Host attributes. */
> >  
> > +static u64
> > +wwn_to_u64(uint8_t *wwn)
> > +{
> > +	return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 |
> > +	    (u64)wwn[2] << 40 | (u64)wwn[3] << 32 |
> > +	    (u64)wwn[4] << 24 | (u64)wwn[5] << 16 |
> > +	    (u64)wwn[6] <<  8 | (u64)wwn[7];
> > +}
> 
> Shouldn't this go into the transport class?  Could probably be an inline
> aswell.

Ok, how about this generic patchset:

1) add helper function to transport class
2) add support to qla2xxx
3) add support to lpfc -- I'll let James S. decide on
   whether the union {} changes to lpfc_name are acceptable

---

Generalize WWN to u64 interger conversions.

On some platforms the hard-casting of 8 byte node_name and
port_name arrays to an u64 would cause unaligned-access
warnings.  Generalize the conversions with a transport
helper function which performs consistent shifting of WWN
bytes.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -439,4 +439,12 @@ int fc_remote_port_block(struct fc_rport
 void fc_remote_port_unblock(struct fc_rport *rport);
 int scsi_is_fc_rport(const struct device *);
 
+static inline u64 wwn_to_u64(u8 *wwn)
+{
+	return (u64)wwn[0] << 56 | (u64)wwn[1] << 48 |
+	    (u64)wwn[2] << 40 | (u64)wwn[3] << 32 |
+	    (u64)wwn[4] << 24 | (u64)wwn[5] << 16 |
+	    (u64)wwn[6] <<  8 | (u64)wwn[7];
+}
+
 #endif /* SCSI_TRANSPORT_FC_H */

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 2/3] qla2xxx: use wwn_to_u64() transport helper
  2005-08-31 22:18     ` [PATCH 1/3] " Andrew Vasquez
@ 2005-08-31 22:21       ` Andrew Vasquez
  2005-08-31 22:23       ` [PATCH 3/3] lpfc: " Andrew Vasquez
  2005-09-05 12:26       ` [PATCH 1/3] Generalize WWN to u64 interger conversions Christoph Hellwig
  2 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-31 22:21 UTC (permalink / raw)
  To: James Bottomley; +Cc: Christoph Hellwig, Linux-SCSI Mailing List, Smart, James

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> 
---

diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -360,16 +360,16 @@ qla2x00_get_starget_node_name(struct scs
 	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
 	scsi_qla_host_t *ha = to_qla_host(host);
 	fc_port_t *fcport;
-	uint64_t node_name = 0;
+	u64 node_name = 0;
 
 	list_for_each_entry(fcport, &ha->fcports, list) {
 		if (starget->id == fcport->os_target_id) {
-			node_name = *(uint64_t *)fcport->node_name;
+			node_name = wwn_to_u64(fcport->node_name);
 			break;
 		}
 	}
 
-	fc_starget_node_name(starget) = be64_to_cpu(node_name);
+	fc_starget_node_name(starget) = node_name;
 }
 
 static void
@@ -378,16 +378,16 @@ qla2x00_get_starget_port_name(struct scs
 	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
 	scsi_qla_host_t *ha = to_qla_host(host);
 	fc_port_t *fcport;
-	uint64_t port_name = 0;
+	u64 port_name = 0;
 
 	list_for_each_entry(fcport, &ha->fcports, list) {
 		if (starget->id == fcport->os_target_id) {
-			port_name = *(uint64_t *)fcport->port_name;
+			port_name = wwn_to_u64(fcport->port_name);
 			break;
 		}
 	}
 
-	fc_starget_port_name(starget) = be64_to_cpu(port_name);
+	fc_starget_port_name(starget) = port_name;
 }
 
 static void
@@ -460,9 +460,7 @@ struct fc_function_template qla2xxx_tran
 void
 qla2x00_init_host_attr(scsi_qla_host_t *ha)
 {
-	fc_host_node_name(ha->host) =
-	    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_node_name(ha->host) = wwn_to_u64(ha->init_cb->node_name);
+	fc_host_port_name(ha->host) = wwn_to_u64(ha->init_cb->port_name);
 	fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
 }
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2070,8 +2070,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t 
 		return;
 	}
 
-	rport_ids.node_name = be64_to_cpu(*(uint64_t *)fcport->node_name);
-	rport_ids.port_name = be64_to_cpu(*(uint64_t *)fcport->port_name);
+	rport_ids.node_name = wwn_to_u64(fcport->node_name);
+	rport_ids.port_name = wwn_to_u64(fcport->port_name);
 	rport_ids.port_id = fcport->d_id.b.domain << 16 |
 	    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 3/3] lpfc: use wwn_to_u64() transport helper
  2005-08-31 22:18     ` [PATCH 1/3] " Andrew Vasquez
  2005-08-31 22:21       ` [PATCH 2/3] qla2xxx: use wwn_to_u64() transport helper Andrew Vasquez
@ 2005-08-31 22:23       ` Andrew Vasquez
  2005-09-05 12:26       ` [PATCH 1/3] Generalize WWN to u64 interger conversions Christoph Hellwig
  2 siblings, 0 replies; 24+ messages in thread
From: Andrew Vasquez @ 2005-08-31 22:23 UTC (permalink / raw)
  To: James Bottomley; +Cc: Christoph Hellwig, Linux-SCSI Mailing List, Smart, James

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
---

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -965,21 +965,21 @@ static void
 lpfc_get_host_fabric_name (struct Scsi_Host *shost)
 {
 	struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
-	u64 nodename;
+	u64 node_name;
 
 	spin_lock_irq(shost->host_lock);
 
 	if ((phba->fc_flag & FC_FABRIC) ||
 	    ((phba->fc_topology == TOPOLOGY_LOOP) &&
 	     (phba->fc_flag & FC_PUBLIC_LOOP)))
-		memcpy(&nodename, &phba->fc_fabparam.nodeName, sizeof(u64));
+		node_name = wwn_to_u64(phba->fc_fabparam.nodeName.wwn);
 	else
 		/* fabric is local port if there is no F/FL_Port */
-		memcpy(&nodename, &phba->fc_nodename, sizeof(u64));
+		node_name = wwn_to_u64(phba->fc_nodename.wwn);
 
 	spin_unlock_irq(shost->host_lock);
 
-	fc_host_fabric_name(shost) = be64_to_cpu(nodename);
+	fc_host_fabric_name(shost) = node_name;
 }
 
 
@@ -1101,21 +1101,20 @@ lpfc_get_starget_node_name(struct scsi_t
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
 	struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
-	uint64_t node_name = 0;
+	u64 node_name = 0;
 	struct lpfc_nodelist *ndlp = NULL;
 
 	spin_lock_irq(shost->host_lock);
 	/* Search the mapped list for this target ID */
 	list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
 		if (starget->id == ndlp->nlp_sid) {
-			memcpy(&node_name, &ndlp->nlp_nodename,
-						sizeof(struct lpfc_name));
+			node_name = wwn_to_u64(ndlp->nlp_nodename.wwn);
 			break;
 		}
 	}
 	spin_unlock_irq(shost->host_lock);
 
-	fc_starget_node_name(starget) = be64_to_cpu(node_name);
+	fc_starget_node_name(starget) = node_name;
 }
 
 static void
@@ -1123,21 +1122,20 @@ lpfc_get_starget_port_name(struct scsi_t
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
 	struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
-	uint64_t port_name = 0;
+	u64 port_name = 0;
 	struct lpfc_nodelist *ndlp = NULL;
 
 	spin_lock_irq(shost->host_lock);
 	/* Search the mapped list for this target ID */
 	list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
 		if (starget->id == ndlp->nlp_sid) {
-			memcpy(&port_name, &ndlp->nlp_portname,
-						sizeof(struct lpfc_name));
+			port_name = wwn_to_u64(ndlp->nlp_portname.wwn);
 			break;
 		}
 	}
 	spin_unlock_irq(shost->host_lock);
 
-	fc_starget_port_name(starget) = be64_to_cpu(port_name);
+	fc_starget_port_name(starget) = port_name;
 }
 
 static void
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1016,13 +1016,10 @@ lpfc_register_remote_port(struct lpfc_hb
 	struct fc_rport *rport;
 	struct lpfc_rport_data *rdata;
 	struct fc_rport_identifiers rport_ids;
-	uint64_t wwn;
 
 	/* Remote port has reappeared. Re-register w/ FC transport */
-	memcpy(&wwn, &ndlp->nlp_nodename, sizeof(uint64_t));
-	rport_ids.node_name = be64_to_cpu(wwn);
-	memcpy(&wwn, &ndlp->nlp_portname, sizeof(uint64_t));
-	rport_ids.port_name = be64_to_cpu(wwn);
+	rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.wwn);
+	rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.wwn);
 	rport_ids.port_id = ndlp->nlp_DID;
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
 	if (ndlp->nlp_type & NLP_FCP_TARGET)
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -262,12 +262,14 @@ struct lpfc_sli_ct_request {
 #define FF_FRAME_SIZE     2048
 
 struct lpfc_name {
+	union {
+		struct {
 #ifdef __BIG_ENDIAN_BITFIELD
-	uint8_t nameType:4;	/* FC Word 0, bit 28:31 */
-	uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+			uint8_t nameType:4;	/* FC Word 0, bit 28:31 */
+			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
 #else	/*  __LITTLE_ENDIAN_BITFIELD */
-	uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
-	uint8_t nameType:4;	/* FC Word 0, bit 28:31 */
+			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+			uint8_t nameType:4;	/* FC Word 0, bit 28:31 */
 #endif
 
 #define NAME_IEEE           0x1	/* IEEE name - nameType */
@@ -276,8 +278,11 @@ struct lpfc_name {
 #define NAME_IP_TYPE        0x4	/* IP address */
 #define NAME_CCITT_TYPE     0xC
 #define NAME_CCITT_GR_TYPE  0xE
-	uint8_t IEEEextLsb;	/* FC Word 0, bit 16:23, IEEE extended Lsb */
-	uint8_t IEEE[6];	/* FC IEEE address */
+			uint8_t IEEEextLsb;	/* FC Word 0, bit 16:23, IEEE extended Lsb */
+			uint8_t IEEE[6];	/* FC IEEE address */
+		};
+		uint8_t wwn[8];
+	};
 };
 
 struct csp {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1332,7 +1332,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev,
 	unsigned long bar0map_len, bar2map_len;
 	int error = -ENODEV, retval;
 	int i;
-	u64 wwname;
 
 	if (pci_enable_device(pdev))
 		goto out;
@@ -1525,10 +1524,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev,
 	 * Must done after lpfc_sli_hba_setup()
 	 */
 
-	memcpy(&wwname, &phba->fc_nodename, sizeof(u64));
-	fc_host_node_name(host) = be64_to_cpu(wwname);
-	memcpy(&wwname, &phba->fc_portname, sizeof(u64));
-	fc_host_port_name(host) = be64_to_cpu(wwname);
+	fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.wwn);
+	fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.wwn);
 	fc_host_supported_classes(host) = FC_COS_CLASS3;
 
 	memset(fc_host_supported_fc4s(host), 0,

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/3] Generalize WWN to u64 interger conversions.
  2005-08-31 22:18     ` [PATCH 1/3] " Andrew Vasquez
  2005-08-31 22:21       ` [PATCH 2/3] qla2xxx: use wwn_to_u64() transport helper Andrew Vasquez
  2005-08-31 22:23       ` [PATCH 3/3] lpfc: " Andrew Vasquez
@ 2005-09-05 12:26       ` Christoph Hellwig
  2 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2005-09-05 12:26 UTC (permalink / raw)
  To: Andrew Vasquez
  Cc: James Bottomley, Christoph Hellwig, Linux-SCSI Mailing List,
	Smart, James

On Wed, Aug 31, 2005 at 03:18:35PM -0700, Andrew Vasquez wrote:
> Ok, how about this generic patchset:
> 
> 1) add helper function to transport class
> 2) add support to qla2xxx
> 3) add support to lpfc -- I'll let James S. decide on
>    whether the union {} changes to lpfc_name are acceptable

looks very nice.


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2005-09-05 12:26 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-27  2:07 [PATCH 0/16] qla2xxx: update qla2xxx driver to 8.01.00 Andrew Vasquez
2005-08-27  2:08 ` [PATCH 1/16] qla2xxx: Use dma_get_required_mask() in determining the 'ideal' DMA mask Andrew Vasquez
2005-08-27  2:08 ` [PATCH 2/16] qla2xxx: Export class-of-service (COS) information Andrew Vasquez
2005-08-27  2:08 ` [PATCH 3/16] qla2xxx: Correct ISP24xx soft-reset handling Andrew Vasquez
2005-08-27  2:26   ` James Bottomley
2005-08-29 16:04     ` Andrew Vasquez
2005-08-27  2:08 ` [PATCH 4/16] qla2xxx: Add FDMI support Andrew Vasquez
2005-08-27  2:08 ` [PATCH 5/16] qla2xxx: Correct domain/area exclusion logic Andrew Vasquez
2005-08-27  2:08 ` [PATCH 6/16] qla2xxx: Simplify redundant target/device reset logic Andrew Vasquez
2005-08-27  2:09 ` [PATCH 7/16] qla2xxx: Correct LED scheme definition Andrew Vasquez
2005-08-27  2:09 ` [PATCH 8/16] qla2xxx: Remove RISC pause/release barriers during flash manipulation Andrew Vasquez
2005-08-27  2:09 ` [PATCH 9/16] qla2xxx: Remove redundant call to pci_unmap_sg() Andrew Vasquez
2005-08-27  2:09 ` [PATCH 10/16] qla2xxx: Add change_queue_depth/type() API support Andrew Vasquez
2005-08-27  2:09 ` [PATCH 11/16] qla2xxx: Add host attributes Andrew Vasquez
2005-08-27  2:09 ` [PATCH 12/16] qla2xxx: Generalize WWN to u64 interger conversions Andrew Vasquez
2005-08-27 10:40   ` Christoph Hellwig
2005-08-31 22:18     ` [PATCH 1/3] " Andrew Vasquez
2005-08-31 22:21       ` [PATCH 2/3] qla2xxx: use wwn_to_u64() transport helper Andrew Vasquez
2005-08-31 22:23       ` [PATCH 3/3] lpfc: " Andrew Vasquez
2005-09-05 12:26       ` [PATCH 1/3] Generalize WWN to u64 interger conversions Christoph Hellwig
2005-08-27  2:10 ` [PATCH 13/16] qla2xxx: Remove bad call to fc_remove_host() during probe failure Andrew Vasquez
2005-08-27  2:10 ` [PATCH 14/16] qla2xxx: Replace schedule_timeout() Andrew Vasquez
2005-08-27  2:10 ` [PATCH 15/16] qla2xxx: Stop firmware execution at unintialization time Andrew Vasquez
2005-08-27  2:10 ` [PATCH 16/16] qla2xxx: Update version number to 8.01.00-k Andrew Vasquez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).