--- /dev/null
+From: David Somayajulu <david.somayajulu@qlogic.com>
+Subject: Update qla4xxx to 5.01.00-k8_sles11-03
+References: bnc#444884
+
+This patch updates the qla4xxx driver to 5.01.00-k8_sles11-03.
+
+
+Signed-off-by: David Somayajulu <david.somayajulu@qlogic.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+---
+ drivers/scsi/qla4xxx/ql4_dbg.c | 36 --
+ drivers/scsi/qla4xxx/ql4_dbg.h | 59 ++--
+ drivers/scsi/qla4xxx/ql4_def.h | 11
+ drivers/scsi/qla4xxx/ql4_glbl.h | 10
+ drivers/scsi/qla4xxx/ql4_init.c | 172 +++++++-----
+ drivers/scsi/qla4xxx/ql4_inline.h | 143 ++++++++++
+ drivers/scsi/qla4xxx/ql4_iocb.c | 161 +----------
+ drivers/scsi/qla4xxx/ql4_isr.c | 36 +-
+ drivers/scsi/qla4xxx/ql4_mbx.c | 11
+ drivers/scsi/qla4xxx/ql4_os.c | 499 ++++++++++++++++++++-----------------
+ drivers/scsi/qla4xxx/ql4_os.h | 125 +++++++++
+ drivers/scsi/qla4xxx/ql4_version.h | 3
+ 12 files changed, 736 insertions(+), 530 deletions(-)
+
+--- a/drivers/scsi/qla4xxx/ql4_dbg.c
++++ b/drivers/scsi/qla4xxx/ql4_dbg.c
+@@ -13,28 +13,6 @@
+
+ #include <scsi/scsi_dbg.h>
+
+-static void qla4xxx_print_srb_info(struct srb * srb)
+-{
+- printk("%s: srb = 0x%p, flags=0x%02x\n", __func__, srb, srb->flags);
+- printk("%s: cmd = 0x%p, saved_dma_handle = 0x%lx\n",
+- __func__, srb->cmd, (unsigned long) srb->dma_handle);
+- printk("%s: fw_ddb_index = %d, lun = %d\n",
+- __func__, srb->fw_ddb_index, srb->cmd->device->lun);
+- printk("%s: iocb_tov = %d\n",
+- __func__, srb->iocb_tov);
+- printk("%s: cc_stat = 0x%x\n", __func__, srb->cc_stat);
+-}
+-
+-void qla4xxx_print_scsi_cmd(struct scsi_cmnd *cmd)
+-{
+- printk("SCSI Command = 0x%p, Handle=0x%p\n", cmd, cmd->host_scribble);
+- printk(" b=%d, t=%02xh, l=%02xh, cmd_len = %02xh\n",
+- cmd->device->channel, cmd->device->id, cmd->device->lun,
+- cmd->cmd_len);
+- scsi_print_command(cmd);
+- qla4xxx_print_srb_info((struct srb *) cmd->SCp.ptr);
+-}
+-
+ void __dump_registers(struct scsi_qla_host *ha)
+ {
+ uint8_t i;
+@@ -143,17 +121,6 @@ void __dump_registers(struct scsi_qla_ho
+ }
+ }
+
+-void qla4xxx_dump_mbox_registers(struct scsi_qla_host *ha)
+-{
+- unsigned long flags = 0;
+- int i = 0;
+- spin_lock_irqsave(&ha->hardware_lock, flags);
+- for (i = 1; i < MBOX_REG_COUNT; i++)
+- printk(KERN_INFO " Mailbox[%d] = %08x\n", i,
+- readw(&ha->reg->mailbox[i]));
+- spin_unlock_irqrestore(&ha->hardware_lock, flags);
+-}
+-
+ void qla4xxx_dump_registers(struct scsi_qla_host *ha)
+ {
+ unsigned long flags = 0;
+@@ -179,6 +146,5 @@ void qla4xxx_dump_buffer(void *b, uint32
+ else
+ printk(KERN_DEBUG " ");
+ }
+- if (cnt % 16)
+- printk(KERN_DEBUG "\n");
++ printk(KERN_DEBUG "\n");
+ }
+--- a/drivers/scsi/qla4xxx/ql4_dbg.h
++++ b/drivers/scsi/qla4xxx/ql4_dbg.h
+@@ -14,49 +14,44 @@
+ /* #define QL_DEBUG_LEVEL_5 */
+ /* #define QL_DEBUG_LEVEL_6 */
+ /* #define QL_DEBUG_LEVEL_9 */
++#ifndef _QL4_DBG_
++#define _QL4_DBG_
+
+ #define QL_DEBUG_LEVEL_2 /* ALways enable error messagess */
+ #if defined(QL_DEBUG)
+-#define DEBUG(x) do {x;} while (0);
++#define DEBUG(x) do {if(extended_error_logging & 0x01) x;} while (0);
+ #else
+-#define DEBUG(x) do {} while (0);
++#define DEBUG(x)
+ #endif
+
+ #if defined(QL_DEBUG_LEVEL_2)
+-#define DEBUG2(x) do {if(extended_error_logging == 2) x;} while (0);
+-#define DEBUG2_3(x) do {x;} while (0);
+-#else /* */
+-#define DEBUG2(x) do {} while (0);
+-#endif /* */
++#define DEBUG2(x) do {if(extended_error_logging & 0x02) x;} while (0);
++#else
++#define DEBUG2(x)
++#endif
+
+ #if defined(QL_DEBUG_LEVEL_3)
+-#define DEBUG3(x) do {if(extended_error_logging == 3) x;} while (0);
+-#else /* */
+-#define DEBUG3(x) do {} while (0);
+-#if !defined(QL_DEBUG_LEVEL_2)
+-#define DEBUG2_3(x) do {} while (0);
+-#endif /* */
+-#endif /* */
++#define DEBUG3(x) do {if(extended_error_logging & 0x04) x;} while (0);
++#else
++#define DEBUG3(x)
++#endif
++
+ #if defined(QL_DEBUG_LEVEL_4)
+-#define DEBUG4(x) do {x;} while (0);
+-#else /* */
+-#define DEBUG4(x) do {} while (0);
+-#endif /* */
++#define DEBUG4(x) do {if(extended_error_logging & 0x08) x;} while (0);
++#else
++#define DEBUG4(x)
++#endif
+
+ #if defined(QL_DEBUG_LEVEL_5)
+-#define DEBUG5(x) do {x;} while (0);
+-#else /* */
+-#define DEBUG5(x) do {} while (0);
+-#endif /* */
++#define DEBUG5(x) do {if(extended_error_logging & 0x10) x;} while (0);
++#else
++#define DEBUG5(x)
++#endif
+
+ #if defined(QL_DEBUG_LEVEL_6)
+-#define DEBUG6(x) do {x;} while (0);
+-#else /* */
+-#define DEBUG6(x) do {} while (0);
+-#endif /* */
+-
+-#if defined(QL_DEBUG_LEVEL_9)
+-#define DEBUG9(x) do {x;} while (0);
+-#else /* */
+-#define DEBUG9(x) do {} while (0);
+-#endif /* */
++#define DEBUG6(x) do {if(extended_error_logging & 0x20) x;} while (0);
++#else
++#define DEBUG6(x)
++#endif
++
++#endif /*_QL4_DBG_*/
+--- a/drivers/scsi/qla4xxx/ql4_def.h
++++ b/drivers/scsi/qla4xxx/ql4_def.h
+@@ -144,7 +144,6 @@
+ #define RESET_FIRMWARE_TOV 30
+ #define LOGOUT_TOV 10
+ #define IOCB_TOV_MARGIN 10
+-#define RELOGIN_TOV 18
+ #define ISNS_DEREG_TOV 5
+
+ #define MAX_RESET_HA_RETRIES 2
+@@ -252,6 +251,8 @@ struct ddb_entry {
+ #define DF_NO_RELOGIN 1 /* Do not relogin if IOCTL
+ * logged it out */
+ #define DF_SCAN_ISSUED 2
++#define DF_OFFLINE 3 /* Offline Device */
++#define DF_DELETED 4 /* Device has been removed */
+
+ /*
+ * Asynchronous Event Queue structure
+@@ -286,7 +287,6 @@ struct scsi_qla_host {
+ uint32_t tot_ddbs;
+ unsigned long flags;
+
+-#define AF_ISNS_CMD_DONE 13 /* 0x00002000 */
+ #define AF_ONLINE 0 /* 0x00000001 */
+ #define AF_INIT_DONE 1 /* 0x00000002 */
+ #define AF_MBOX_COMMAND 2 /* 0x00000004 */
+@@ -294,9 +294,9 @@ struct scsi_qla_host {
+ #define AF_INTERRUPTS_ON 6 /* 0x00000040 Not Used */
+ #define AF_GET_CRASH_RECORD 7 /* 0x00000080 */
+ #define AF_LINK_UP 8 /* 0x00000100 */
+-#define AF_TOPCAT_CHIP_PRESENT 9 /* 0x00000200 */
+ #define AF_IRQ_ATTACHED 10 /* 0x00000400 */
+ #define AF_DISABLE_ACB_COMPLETE 11 /* 0x00000800 */
++#define AF_OS_INDEX_VALID 12 /* 0x00001000 */
+
+ unsigned long dpc_flags;
+
+@@ -308,6 +308,8 @@ struct scsi_qla_host {
+ #define DPC_ISNS_RESTART 7 /* 0x00000080 */
+ #define DPC_AEN 9 /* 0x00000200 */
+ #define DPC_GET_DHCP_IP_ADDR 15 /* 0x00008000 */
++#define DPC_OFFLINE_DEVICE 16 /* 0x00010000 */
++#define DPC_DELETE_DEVICE 17 /* 0x00020000 */
+
+ uint16_t iocb_cnt;
+ uint16_t iocb_hiwat;
+@@ -460,7 +462,7 @@ struct scsi_qla_host {
+ void (*ql4getaenlog)(struct scsi_qla_host *ha, struct ql4_aen_log *aenl);
+ #define QL_INDICES_PER_ENTRY 32
+ #define QL_OSINDEX_ENTRIES (MAX_DDB_ENTRIES/QL_INDICES_PER_ENTRY)
+- volatile uint32_t os_map[QL_OSINDEX_ENTRIES];
++ volatile unsigned long os_map[QL_OSINDEX_ENTRIES];
+ };
+
+ static inline int is_qla4010(struct scsi_qla_host *ha)
+@@ -468,6 +470,7 @@ static inline int is_qla4010(struct scsi
+ return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4010;
+ }
+
++
+ static inline int is_qla4022(struct scsi_qla_host *ha)
+ {
+ return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022;
+--- a/drivers/scsi/qla4xxx/ql4_glbl.h
++++ b/drivers/scsi/qla4xxx/ql4_glbl.h
+@@ -10,7 +10,7 @@
+
+ struct iscsi_cls_conn;
+
+-void qla4xxx_hw_reset(struct scsi_qla_host *ha);
++void qla4xxx_hw_reset(struct scsi_qla_host *ha, int hw_lock);
+ int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a);
+ int qla4xxx_conn_start(struct iscsi_cls_conn *conn);
+ int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port);
+@@ -18,9 +18,9 @@ int qla4xxx_send_command_to_isp(struct s
+ int qla4xxx_initialize_adapter(struct scsi_qla_host * ha,
+ uint8_t renew_ddb_list);
+ int qla4xxx_soft_reset(struct scsi_qla_host *ha);
+-irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id);
+
+ void qla4xxx_free_ddb_list(struct scsi_qla_host * ha);
++void qla4xxx_free_ddb(struct scsi_qla_host *, struct ddb_entry *);
+ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen);
+
+ int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha);
+@@ -47,6 +47,8 @@ int qla4xxx_get_fwddb_entry(struct scsi_
+ uint16_t *tcp_source_port_num,
+ uint16_t *connection_id);
+
++struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host * ha,
++ uint32_t fw_ddb_index);
+ int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
+ dma_addr_t fw_ddb_entry_dma);
+
+@@ -77,10 +79,6 @@ int qla4xxx_process_ddb_changed(struct s
+
+ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
+ uint8_t outCount, uint32_t *mbx_cmd, uint32_t *mbx_sts);
+-int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
+- struct ddb_entry *ddb_entry, int lun);
+-
+-
+
+ extern int extended_error_logging;
+ extern int ql4xdiscoverywait;
+--- a/drivers/scsi/qla4xxx/ql4_init.c
++++ b/drivers/scsi/qla4xxx/ql4_init.c
+@@ -10,6 +10,7 @@
+ #include "ql4_glbl.h"
+ #include "ql4_dbg.h"
+ #include "ql4_inline.h"
++#include "ql4_os.h"
+
+ /* link auto negotiation normally takes roughly 2s. */
+ /* If we don't have link in 3 times that period quit. */
+@@ -19,9 +20,6 @@
+ * QLogic ISP4xxx Hardware Support Function Prototypes.
+ */
+
+-static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
+- uint32_t fw_ddb_index);
+-
+ static void ql4xxx_set_mac_number(struct scsi_qla_host *ha)
+ {
+ uint32_t value;
+@@ -52,15 +50,14 @@ static void ql4xxx_set_mac_number(struct
+ }
+
+ /**
+- * qla4xxx_free_ddb - deallocate ddb
++ * qla4xxx_free_ddb - deallocate ddb
+ * @ha: pointer to host adapter structure.
+ * @ddb_entry: pointer to device database entry
+ *
+ * This routine deallocates and unlinks the specified ddb_entry from the
+ * adapter's
+ **/
+-static void qla4xxx_free_ddb(struct scsi_qla_host *ha,
+- struct ddb_entry *ddb_entry)
++void qla4xxx_free_ddb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry)
+ {
+ /* Remove device entry from list */
+ list_del_init(&ddb_entry->list);
+@@ -359,8 +356,8 @@ static void qla4xxx_fill_ddb(struct ddb_
+ * This routine allocates a ddb_entry, ititializes some values, and
+ * inserts it into the ddb list.
+ **/
+-static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
+- uint32_t fw_ddb_index)
++struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
++ uint32_t fw_ddb_index)
+ {
+ struct ddb_entry *ddb_entry;
+
+@@ -478,7 +475,7 @@ static int qla4xxx_build_ddb_list(struct
+ (strlen(fw_ddb_entry->iscsi_name) != 0)){
+ ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
+ if (ddb_entry == NULL) {
+- DEBUG2(dev_info(&ha->pdev->dev,"%s alloc_ddb %d "
++ DEBUG2(dev_info(&ha->pdev->dev,"%s alloc_ddb %d"
+ "failed\n", __func__, fw_ddb_index));
+ goto exit_ddb_list;
+ }
+@@ -488,7 +485,7 @@ static int qla4xxx_build_ddb_list(struct
+ ddb_entry->connection_id = conn_id;
+ qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry);
+ ddb_entry->fw_ddb_device_state = ddb_state;
+-
++
+ if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) {
+ atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
+ dev_info(&ha->pdev->dev,
+@@ -695,6 +692,8 @@ static int qla4xxx_initialize_ddb_list(s
+
+ qla4xxx_flush_AENS(ha);
+
++ /* Wait for an AEN */
++ qla4xxx_devices_ready(ha);
+
+ /*
+ * First perform device discovery for active
+@@ -704,9 +703,6 @@ static int qla4xxx_initialize_ddb_list(s
+ if ((status = qla4xxx_build_ddb_list(ha)) == QLA_ERROR)
+ return status;
+
+- /* Wait for an AEN */
+- qla4xxx_devices_ready(ha);
+-
+ /*
+ * Targets can come online after the inital discovery, so processing
+ * the aens here will catch them.
+@@ -747,13 +743,15 @@ int qla4xxx_reinitialize_ddb_list(struct
+
+ qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry);
+
+- if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) {
++ if (ddb_entry->fw_ddb_device_state ==
++ DDB_DS_SESSION_ACTIVE) {
+ atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
+ dev_info(&ha->pdev->dev,
+- "scsi%ld: %s: ddb[%d] os[%d] marked ONLINE\n",
+- ha->host_no, __func__, ddb_entry->fw_ddb_index,
++ "%s: ddb[%d] os[%d] marked ONLINE\n",
++ __func__, ddb_entry->fw_ddb_index,
+ ddb_entry->os_target_id);
+- } else if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
++ } else if (atomic_read(&ddb_entry->state) ==
++ DDB_STATE_ONLINE)
+ qla4xxx_mark_device_missing(ha, ddb_entry);
+ }
+ }
+@@ -884,8 +882,8 @@ static int qla4xxx_start_firmware_from_f
+ writel(set_rmask(NVR_WRITE_ENABLE),
+ &ha->reg->u1.isp4022.nvram);
+
+- writel(2, &ha->reg->mailbox[6]);
+- readl(&ha->reg->mailbox[6]);
++ writel(2, &ha->reg->mailbox[6]);
++ readl(&ha->reg->mailbox[6]);
+
+ writel(set_rmask(CSR_BOOT_ENABLE), &ha->reg->ctrl_status);
+ readl(&ha->reg->ctrl_status);
+@@ -1054,7 +1052,7 @@ static int qla4xxx_start_firmware(struct
+ }
+ config_chip = 1;
+
+- /* Reset clears the semaphore, so acquire again */
++ /* Reset clears the semaphore, so aquire again */
+ if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS)
+ return QLA_ERROR;
+ }
+@@ -1083,7 +1081,7 @@ static int qla4xxx_start_firmware(struct
+ * @renew_ddb_list: Indicates what to do with the adapter's ddb list
+ * after adapter recovery has completed.
+ * 0=preserve ddb list, 1=destroy and rebuild ddb list
+- *
++ *
+ * This routine parforms all of the steps necessary to initialize the adapter.
+ *
+ **/
+@@ -1119,12 +1117,12 @@ int qla4xxx_initialize_adapter(struct sc
+ * followed by 0x8014 aen" to trigger the tgt discovery process.
+ */
+ if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS)
+- goto exit_init_online;
++ goto exit_init_hba0;
+
+ /* Skip device discovery if ip and subnet is zero */
+ if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 ||
+ memcmp(ha->subnet_mask, ip_address, IP_ADDR_LEN) == 0)
+- goto exit_init_online;
++ goto exit_init_hba0;
+
+ if (renew_ddb_list == PRESERVE_DDB_LIST) {
+ /*
+@@ -1153,8 +1151,10 @@ int qla4xxx_initialize_adapter(struct sc
+ ha->host_no));
+ }
+
+-exit_init_online:
++exit_init_hba0:
+ set_bit(AF_ONLINE, &ha->flags);
++ dev_info(&ha->pdev->dev, "%s: adapter ONLINE\n", __func__);
++
+ exit_init_hba:
+ return status;
+ }
+@@ -1204,40 +1204,63 @@ static void qla4xxx_add_device_dynamical
+ }
+ }
+
+- if (!found)
+- ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
+- else if (ddb_entry->fw_ddb_index != fw_ddb_index) {
+- /* Target has been bound to a new fw_ddb_index */
+- qla4xxx_free_ddb(ha, ddb_entry);
++ if (!found) {
+ ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
+- }
+
+- if (ddb_entry == NULL) {
+- DEBUG2(dev_info(&ha->pdev->dev, "%s NULL DDB %d\n",
+- __func__, fw_ddb_index));
+- goto exit_dyn_add;
+- }
++ if (ddb_entry == NULL) {
++ DEBUG2(dev_info(&ha->pdev->dev, "%s NULL DDB %d\n",
++ __func__, fw_ddb_index));
++ goto exit_dyn_add;
++ }
+
+- ddb_entry->fw_ddb_index = fw_ddb_index;
+- ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
+- ddb_entry->tcp_source_port_num = src_port;
+- ddb_entry->connection_id = conn_id;
+- qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry);
+- ddb_entry->fw_ddb_device_state = ddb_state;
++ ddb_entry->fw_ddb_index = fw_ddb_index;
++ ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
++ ddb_entry->tcp_source_port_num = src_port;
++ ddb_entry->connection_id = conn_id;
++ qla4xxx_fill_ddb(ddb_entry, fw_ddb_entry);
++ ddb_entry->fw_ddb_device_state = ddb_state;
++
++ if (probe)
++ goto exit_dyn_add;
+
+- if (!probe) {
+ if (qla4xxx_add_sess(ddb_entry, 1)) {
+- DEBUG2(printk(KERN_WARNING
+- "scsi%ld: failed to add new device at index "
+- "[%d]\n Unable to add connection and session\n",
+- ha->host_no, fw_ddb_index));
++ DEBUG2(dev_info(&ha->pdev->dev,
++ "%s: failed to add new ddb %d\n",
++ __func__, fw_ddb_index));
+ qla4xxx_free_ddb(ha, ddb_entry);
++ } else {
++ DEBUG6(dev_info(&ha->pdev->dev,
++ "%s added ddb 0x%p sess 0x%p"
++ " conn 0x%p state 0x%x\n",
++ __func__, ddb_entry,
++ ddb_entry->sess, ddb_entry->conn,
++ ddb_entry->state));
+ }
+- }
++ } else if (ddb_entry->fw_ddb_index != fw_ddb_index) {
++ /* Target has been bound to a new fw_ddb_index */
++ ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = NULL;
++ ddb_entry->fw_ddb_index = fw_ddb_index;
++ ddb_entry->fw_ddb_device_state = ddb_state;
++ ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
++ atomic_set(&ddb_entry->port_down_timer,
++ ha->port_down_retry_count);
++ atomic_set(&ddb_entry->relogin_retry_count, 0);
++ atomic_set(&ddb_entry->relogin_timer, 0);
++ clear_bit(DF_RELOGIN, &ddb_entry->flags);
++ clear_bit(DF_NO_RELOGIN, &ddb_entry->flags);
++ atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
+
+- DEBUG6(dev_info(&ha->pdev->dev, "%s added ddb 0x%p sess 0x%p conn 0x%p"
+- " state 0x%x\n", __func__, ddb_entry, ddb_entry->sess,
+- ddb_entry->conn, ddb_entry->state));
++ dev_info(&ha->pdev->dev,
++ "scsi%ld: %s: ddb[%d] os[%d] marked ONLINE sess:%p conn:%p\n",
++ ha->host_no, __func__, ddb_entry->fw_ddb_index,
++ ddb_entry->os_target_id, ddb_entry->sess, ddb_entry->conn);
++
++ if (!probe)
++ qla4xxx_conn_start(ddb_entry->conn);
++ DEBUG6(dev_info(&ha->pdev->dev, "%s calling conn_start ddb 0x%p sess 0x%p"
++ " conn 0x%p state 0x%x\n", __func__, ddb_entry, ddb_entry->sess,
++ ddb_entry->conn, ddb_entry->state));
++ }
+ exit_dyn_add:
+ dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry,
+ fw_ddb_entry_dma);
+@@ -1272,15 +1295,15 @@ int qla4xxx_process_ddb_changed(struct s
+ qla4xxx_add_device_dynamically(ha, fw_ddb_index, probe);
+ return QLA_SUCCESS;
+ }
+- DEBUG6(dev_info(&ha->pdev->dev, "%s ddb_entry 0x%p ostate 0x%x"
+- " sess 0x%p conn 0x%p\n", __func__, ddb_entry,
+- ddb_entry->state, ddb_entry->sess, ddb_entry->conn));
++ DEBUG6(dev_info(&ha->pdev->dev, "%s ddb[%d] os[%d] ostate 0x%x"
++ " sess 0x%p conn 0x%p o_fwstate 0x%x n_fwstate ox%x \n",
++ __func__, ddb_entry->fw_ddb_index, ddb_entry->os_target_id,
++ ddb_entry->state, ddb_entry->sess, ddb_entry->conn,
++ ddb_entry->fw_ddb_device_state, state));
+
+ /* Device already exists in our database. */
+ old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state;
+- DEBUG2(printk("scsi%ld: %s DDB - old state= 0x%x, new state=0x%x for "
+- "index [%d]\n", ha->host_no, __func__,
+- ddb_entry->fw_ddb_device_state, state, fw_ddb_index));
++
+ if (old_fw_ddb_device_state == state &&
+ state == DDB_DS_SESSION_ACTIVE) {
+ /* Do nothing, state not changed. */
+@@ -1297,26 +1320,33 @@ int qla4xxx_process_ddb_changed(struct s
+ atomic_set(&ddb_entry->port_down_timer,
+ ha->port_down_retry_count);
+ atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
++ dev_info(&ha->pdev->dev,
++ "%s: ddb[%d] os[%d] marked ONLINE\n",
++ __func__, ddb_entry->fw_ddb_index,
++ ddb_entry->os_target_id);
++
+ atomic_set(&ddb_entry->relogin_retry_count, 0);
+ atomic_set(&ddb_entry->relogin_timer, 0);
+ clear_bit(DF_RELOGIN, &ddb_entry->flags);
+ clear_bit(DF_NO_RELOGIN, &ddb_entry->flags);
+
+- DEBUG6(dev_info(&ha->pdev->dev, "%s conn startddb_entry 0x%p"
+- " sess 0x%p conn 0x%p\n",
+- __func__, ddb_entry, ddb_entry->sess, ddb_entry->conn));
+-
+- qla4xxx_conn_start(ddb_entry->conn);
+-
+- DEBUG6(dev_info(&ha->pdev->dev, "%s conn start done "
+- "ddb_entry 0x%p sess 0x%p conn 0x%p\n",
+- __func__, ddb_entry, ddb_entry->sess, ddb_entry->conn));
+-
+- if (!test_bit(DF_SCAN_ISSUED, &ddb_entry->flags)) {
+- scsi_scan_target(&ddb_entry->sess->dev, 0,
+- ddb_entry->sess->target_id,
+- SCAN_WILD_CARD, 0);
+- set_bit(DF_SCAN_ISSUED, &ddb_entry->flags);
++ if (ddb_entry->conn) {
++ DEBUG6(dev_info(&ha->pdev->dev,
++ "%s conn startddb_entry 0x%p"
++ " sess 0x%p conn 0x%p\n",
++ __func__,
++ ddb_entry, ddb_entry->sess, ddb_entry->conn));
++
++ qla4xxx_conn_start(ddb_entry->conn);
++
++ DEBUG6(dev_info(&ha->pdev->dev, "%s conn start done "
++ "ddb_entry 0x%p sess 0x%p conn 0x%p\n",
++ __func__, ddb_entry, ddb_entry->sess, ddb_entry->conn));
++
++ if (!test_bit(DF_SCAN_ISSUED, &ddb_entry->flags)) {
++ qla4xxx_scan_target(ddb_entry);
++ set_bit(DF_SCAN_ISSUED, &ddb_entry->flags);
++ }
+ }
+ } else {
+ /* Device went away, try to relogin. */
+--- a/drivers/scsi/qla4xxx/ql4_inline.h
++++ b/drivers/scsi/qla4xxx/ql4_inline.h
+@@ -34,6 +34,34 @@ qla4xxx_lookup_ddb_by_fw_index(struct sc
+ return ddb_entry;
+ }
+
++/*
++ * The MBOX_CMD_CLEAR_DATABASE_ENTRY (0x31) mailbox command does not
++ * result in an AEN, so we need to process it seperately.
++ */
++static inline void qla4xxx_check_for_clear_ddb(struct scsi_qla_host *ha,
++ uint32_t *mbox_cmd)
++{
++ uint32_t fw_ddb_index;
++ struct ddb_entry *ddb_entry = NULL;
++
++ if (mbox_cmd[0] == MBOX_CMD_CLEAR_DATABASE_ENTRY) {
++
++ fw_ddb_index = mbox_cmd[1];
++
++ if (fw_ddb_index < MAX_DDB_ENTRIES)
++ ddb_entry = ha->fw_ddb_index_map[fw_ddb_index];
++
++ if (ddb_entry) {
++ dev_info(&ha->pdev->dev, "%s: ddb[%d] os[%d] freed\n",
++ __func__, ddb_entry->fw_ddb_index,
++ ddb_entry->os_target_id);
++ set_bit(DF_DELETED, &ddb_entry->flags);
++ set_bit(DPC_DELETE_DEVICE, &ha->dpc_flags);
++ queue_work(ha->dpc_thread, &ha->dpc_work);
++ }
++ }
++}
++
+ static inline void
+ __qla4xxx_enable_intrs(struct scsi_qla_host *ha)
+ {
+@@ -81,3 +109,118 @@ qla4xxx_disable_intrs(struct scsi_qla_ho
+ __qla4xxx_disable_intrs(ha);
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
++
++static inline int qla4xxx_get_req_pkt(struct scsi_qla_host *ha,
++ struct queue_entry **queue_entry)
++{
++ uint16_t request_in;
++ uint8_t status = QLA_SUCCESS;
++
++ *queue_entry = ha->request_ptr;
++
++ /* get the latest request_in and request_out index */
++ request_in = ha->request_in;
++ ha->request_out = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out);
++
++ /* Advance request queue pointer and check for queue full */
++ if (request_in == (REQUEST_QUEUE_DEPTH - 1)) {
++ request_in = 0;
++ ha->request_ptr = ha->request_ring;
++ } else {
++ request_in++;
++ ha->request_ptr++;
++ }
++
++ /* request queue is full, try again later */
++ if ((ha->iocb_cnt + 1) >= ha->iocb_hiwat) {
++ /* restore request pointer */
++ ha->request_ptr = *queue_entry;
++ status = QLA_ERROR;
++ } else {
++ ha->request_in = request_in;
++ memset(*queue_entry, 0, sizeof(**queue_entry));
++ }
++
++ return status;
++}
++
++/**
++ * qla4xxx_send_marker_iocb - issues marker iocb to HBA
++ * @ha: Pointer to host adapter structure.
++ * @ddb_entry: Pointer to device database entry
++ * @lun: SCSI LUN
++ * @marker_type: marker identifier
++ *
++ * This routine issues a marker IOCB.
++ **/
++static inline int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
++ struct ddb_entry *ddb_entry, int lun)
++{
++ struct marker_entry *marker_entry;
++ unsigned long flags = 0;
++ uint8_t status = QLA_SUCCESS;
++
++ /* Acquire hardware specific lock */
++ spin_lock_irqsave(&ha->hardware_lock, flags);
++
++ /* Get pointer to the queue entry for the marker */
++ if (qla4xxx_get_req_pkt(ha, (struct queue_entry **) &marker_entry) !=
++ QLA_SUCCESS) {
++ status = QLA_ERROR;
++ goto exit_send_marker;
++ }
++
++ /* Put the marker in the request queue */
++ marker_entry->hdr.entryType = ET_MARKER;
++ marker_entry->hdr.entryCount = 1;
++ marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index);
++ marker_entry->modifier = cpu_to_le16(MM_LUN_RESET);
++ int_to_scsilun(lun, &marker_entry->lun);
++ wmb();
++
++ /* Tell ISP it's got a new I/O request */
++ writel(ha->request_in, &ha->reg->req_q_in);
++ readl(&ha->reg->req_q_in);
++
++exit_send_marker:
++ spin_unlock_irqrestore(&ha->hardware_lock, flags);
++ return status;
++}
++
++static inline struct continuation_t1_entry* qla4xxx_alloc_cont_entry(
++ struct scsi_qla_host *ha)
++{
++ struct continuation_t1_entry *cont_entry;
++
++ cont_entry = (struct continuation_t1_entry *)ha->request_ptr;
++
++ /* Advance request queue pointer */
++ if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) {
++ ha->request_in = 0;
++ ha->request_ptr = ha->request_ring;
++ } else {
++ ha->request_in++;
++ ha->request_ptr++;
++ }
++
++ /* Load packet defaults */
++ cont_entry->hdr.entryType = ET_CONTINUE;
++ cont_entry->hdr.entryCount = 1;
++ cont_entry->hdr.systemDefined = (uint8_t) cpu_to_le16(ha->request_in);
++
++ return cont_entry;
++}
++
++static inline uint16_t qla4xxx_calc_request_entries(uint16_t dsds)
++{
++ uint16_t iocbs;
++
++ iocbs = 1;
++ if (dsds > COMMAND_SEG) {
++ iocbs += (dsds - COMMAND_SEG) / CONTINUE_SEG;
++ if ((dsds - COMMAND_SEG) % CONTINUE_SEG)
++ iocbs++;
++ }
++ return iocbs;
++}
++
+--- a/drivers/scsi/qla4xxx/ql4_iocb.c
++++ b/drivers/scsi/qla4xxx/ql4_iocb.c
+@@ -11,133 +11,8 @@
+ #include "ql4_dbg.h"
+ #include "ql4_inline.h"
+
+-#define VMWARE_CMD_TIMEOUT 30
+ #include <scsi/scsi_tcq.h>
+
+-/**
+- * qla4xxx_get_req_pkt - returns a valid entry in request queue.
+- * @ha: Pointer to host adapter structure.
+- * @queue_entry: Pointer to pointer to queue entry structure
+- *
+- * This routine performs the following tasks:
+- * - returns the current request_in pointer (if queue not full)
+- * - advances the request_in pointer
+- * - checks for queue full
+- **/
+-static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha,
+- struct queue_entry **queue_entry)
+-{
+- uint16_t request_in;
+- uint8_t status = QLA_SUCCESS;
+-
+- *queue_entry = ha->request_ptr;
+-
+- /* get the latest request_in and request_out index */
+- request_in = ha->request_in;
+- ha->request_out = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out);
+-
+- /* Advance request queue pointer and check for queue full */
+- if (request_in == (REQUEST_QUEUE_DEPTH - 1)) {
+- request_in = 0;
+- ha->request_ptr = ha->request_ring;
+- } else {
+- request_in++;
+- ha->request_ptr++;
+- }
+-
+- /* request queue is full, try again later */
+- if ((ha->iocb_cnt + 1) >= ha->iocb_hiwat) {
+- /* restore request pointer */
+- ha->request_ptr = *queue_entry;
+- status = QLA_ERROR;
+- } else {
+- ha->request_in = request_in;
+- memset(*queue_entry, 0, sizeof(**queue_entry));
+- }
+-
+- return status;
+-}
+-
+-/**
+- * qla4xxx_send_marker_iocb - issues marker iocb to HBA
+- * @ha: Pointer to host adapter structure.
+- * @ddb_entry: Pointer to device database entry
+- * @lun: SCSI LUN
+- * @marker_type: marker identifier
+- *
+- * This routine issues a marker IOCB.
+- **/
+-int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
+- struct ddb_entry *ddb_entry, int lun)
+-{
+- struct marker_entry *marker_entry;
+- unsigned long flags = 0;
+- uint8_t status = QLA_SUCCESS;
+-
+- /* Acquire hardware specific lock */
+- spin_lock_irqsave(&ha->hardware_lock, flags);
+-
+- /* Get pointer to the queue entry for the marker */
+- if (qla4xxx_get_req_pkt(ha, (struct queue_entry **) &marker_entry) !=
+- QLA_SUCCESS) {
+- status = QLA_ERROR;
+- goto exit_send_marker;
+- }
+-
+- /* Put the marker in the request queue */
+- marker_entry->hdr.entryType = ET_MARKER;
+- marker_entry->hdr.entryCount = 1;
+- marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index);
+- marker_entry->modifier = cpu_to_le16(MM_LUN_RESET);
+- int_to_scsilun(lun, &marker_entry->lun);
+- wmb();
+-
+- /* Tell ISP it's got a new I/O request */
+- writel(ha->request_in, &ha->reg->req_q_in);
+- readl(&ha->reg->req_q_in);
+-
+-exit_send_marker:
+- spin_unlock_irqrestore(&ha->hardware_lock, flags);
+- return status;
+-}
+-
+-static struct continuation_t1_entry* qla4xxx_alloc_cont_entry(
+- struct scsi_qla_host *ha)
+-{
+- struct continuation_t1_entry *cont_entry;
+-
+- cont_entry = (struct continuation_t1_entry *)ha->request_ptr;
+-
+- /* Advance request queue pointer */
+- if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) {
+- ha->request_in = 0;
+- ha->request_ptr = ha->request_ring;
+- } else {
+- ha->request_in++;
+- ha->request_ptr++;
+- }
+-
+- /* Load packet defaults */
+- cont_entry->hdr.entryType = ET_CONTINUE;
+- cont_entry->hdr.entryCount = 1;
+- cont_entry->hdr.systemDefined = (uint8_t) cpu_to_le16(ha->request_in);
+-
+- return cont_entry;
+-}
+-
+-static uint16_t qla4xxx_calc_request_entries(uint16_t dsds)
+-{
+- uint16_t iocbs;
+-
+- iocbs = 1;
+- if (dsds > COMMAND_SEG) {
+- iocbs += (dsds - COMMAND_SEG) / CONTINUE_SEG;
+- if ((dsds - COMMAND_SEG) % CONTINUE_SEG)
+- iocbs++;
+- }
+- return iocbs;
+-}
+-
+ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
+ struct command_t3_entry *cmd_entry,
+ uint16_t tot_dsds)
+@@ -224,6 +99,7 @@ int qla4xxx_send_command_to_isp(struct s
+ /* Acquire hardware specific lock */
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+
++ //index = (uint32_t)cmd->request->tag;
+ index = ha->current_active_index;
+ for (i = 0; i < MAX_SRBS; i++) {
+ index++;
+@@ -242,10 +118,14 @@ int qla4xxx_send_command_to_isp(struct s
+ }
+
+ /* Calculate the number of request entries needed. */
+- nseg = scsi_dma_map(cmd);
+- if (nseg < 0)
+- goto queuing_error;
+- tot_dsds = nseg;
++ if (srb->flags & SRB_SCSI_PASSTHRU)
++ tot_dsds = 1;
++ else {
++ nseg = scsi_dma_map(cmd);
++ if (nseg < 0)
++ goto queuing_error;
++ tot_dsds = nseg;
++ }
+
+ req_cnt = qla4xxx_calc_request_entries(tot_dsds);
+
+@@ -281,9 +161,9 @@ int qla4xxx_send_command_to_isp(struct s
+ cmd_entry->hdr.entryCount = req_cnt;
+
+ /* Set data transfer direction control flags
+- * NOTE: Look at data_direction bits iff there is data to be
+- * transferred, as the data direction bit is sometimed filled
+- * in when there is no data to be transferred */
++ * NOTE: Look at data_direction bits iff there is data to be
++ * transferred, as the data direction bit is sometimed filled
++ * in when there is no data to be transferred */
+ cmd_entry->control_flags = CF_NO_DATA;
+ if (scsi_bufflen(cmd)) {
+ if (cmd->sc_data_direction == DMA_TO_DEVICE)
+@@ -324,10 +204,10 @@ int qla4xxx_send_command_to_isp(struct s
+
+ /*
+ * Check to see if adapter is online before placing request on
+- * request queue. If a reset occurs and a request is in the queue,
+- * the firmware will still attempt to process the request, retrieving
+- * garbage for pointers.
+- */
++ * request queue. If a reset occurs and a request is in the queue,
++ * the firmware will still attempt to process the request, retrieving
++ * garbage for pointers.
++ */
+ if (!test_bit(AF_ONLINE, &ha->flags)) {
+ DEBUG2(printk("scsi%ld: %s: Adapter OFFLINE! "
+ "Do not issue command.\n",
+@@ -355,13 +235,12 @@ int qla4xxx_send_command_to_isp(struct s
+ return QLA_SUCCESS;
+
+ queuing_error:
+- if (srb->flags & SRB_SCSI_PASSTHRU)
+- return QLA_ERROR;
+-
+- if (tot_dsds)
+- scsi_dma_unmap(cmd);
++ if (!(srb->flags & SRB_SCSI_PASSTHRU))
++ if (tot_dsds)
++ scsi_dma_unmap(cmd);
+
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+ return QLA_ERROR;
+ }
++
+--- a/drivers/scsi/qla4xxx/ql4_isr.c
++++ b/drivers/scsi/qla4xxx/ql4_isr.c
+@@ -10,6 +10,7 @@
+ #include "ql4_glbl.h"
+ #include "ql4_dbg.h"
+ #include "ql4_inline.h"
++#include "ql4_os.h"
+
+ /**
+ * qla4xxx_status_entry - processes status IOCBs
+@@ -59,8 +60,8 @@ static void qla4xxx_status_entry(struct
+ break;
+ }
+ if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_UNDER) {
+- scsi_set_resid(cmd, residual);
+- if (!scsi_status && ((scsi_bufflen(cmd) - residual) <
++ QL_SET_SCSI_RESID(cmd, residual);
++ if (!scsi_status && ((QL_SCSI_BUFFLEN(cmd) - residual) <
+ cmd->underflow)) {
+ cmd->result = DID_ERROR << 16;
+ break;
+@@ -144,7 +145,7 @@ static void qla4xxx_status_entry(struct
+ break;
+ }
+
+- scsi_set_resid(cmd, residual);
++ QL_SET_SCSI_RESID(cmd, residual);
+
+ /*
+ * If there is scsi_status, it takes precedense over
+@@ -184,7 +185,7 @@ static void qla4xxx_status_entry(struct
+ if ((sts_entry->iscsiFlags &
+ ISCSI_FLAG_RESIDUAL_UNDER) == 0) {
+ cmd->result = DID_BUS_BUSY << 16;
+- } else if ((scsi_bufflen(cmd) - residual) <
++ } else if ((QL_SCSI_BUFFLEN(cmd) - residual) <
+ cmd->underflow) {
+ /*
+ * Handle mid-layer underflow???
+@@ -203,7 +204,7 @@ static void qla4xxx_status_entry(struct
+ "resid = 0x%x, compstat = 0x%x\n",
+ ha->host_no, cmd->device->channel,
+ cmd->device->id, cmd->device->lun,
+- __func__, scsi_bufflen(cmd),
++ __func__, QL_SCSI_BUFFLEN(cmd),
+ residual,
+ sts_entry->completionStatus));
+
+@@ -396,13 +397,13 @@ static void qla4xxx_isr_decode_mailbox(s
+ /* Immediately process the AENs that don't require much work.
+ * Only queue the database_changed AENs */
+
+- dev_info(&ha->pdev->dev, "%s mbx0 0x%08x mbx1 0x%08x"
++ DEBUG6(dev_info(&ha->pdev->dev, "%s mbx0 0x%08x mbx1 0x%08x"
+ " mbx2 0x%08x mbx3 0x%08x mbx4 0x%08x mbx5 0x%08x "
+ "mbx6 0x%08x mbx7 0x%08x\n", __func__,
+ readl(&ha->reg->mailbox[0]), readl(&ha->reg->mailbox[1]),
+ readl(&ha->reg->mailbox[2]), readl(&ha->reg->mailbox[3]),
+ readl(&ha->reg->mailbox[4]), readl(&ha->reg->mailbox[5]),
+- readl(&ha->reg->mailbox[6]), readl(&ha->reg->mailbox[7]));
++ readl(&ha->reg->mailbox[6]), readl(&ha->reg->mailbox[7])));
+
+ if (ha->aen_log.count < MAX_AEN_ENTRIES) {
+ for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
+@@ -412,11 +413,13 @@ static void qla4xxx_isr_decode_mailbox(s
+ }
+ switch (mbox_status) {
+ case MBOX_ASTS_SYSTEM_ERROR:
++ dev_info(&ha->pdev->dev, "%s: System Err\n", __func__);
+ /* Log Mailbox registers */
+ if (ql4xdontresethba) {
+ DEBUG2(printk("%s:Dont Reset HBA\n",
+ __func__));
+ } else {
++ qla4xxx_hw_reset(ha, 0);
+ set_bit(AF_GET_CRASH_RECORD, &ha->flags);
+ set_bit(DPC_RESET_HA, &ha->dpc_flags);
+ }
+@@ -433,15 +436,13 @@ static void qla4xxx_isr_decode_mailbox(s
+ break;
+
+ case MBOX_ASTS_LINK_UP:
+- DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK UP\n",
+- ha->host_no, mbox_status));
+ set_bit(AF_LINK_UP, &ha->flags);
++ dev_info(&ha->pdev->dev, "%s: LINK UP\n", __func__);
+ break;
+
+ case MBOX_ASTS_LINK_DOWN:
+- DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK DOWN\n",
+- ha->host_no, mbox_status));
+ clear_bit(AF_LINK_UP, &ha->flags);
++ dev_info(&ha->pdev->dev, "%s: LINK DOWN\n", __func__);
+ break;
+
+ case MBOX_ASTS_HEARTBEAT:
+@@ -470,9 +471,9 @@ static void qla4xxx_isr_decode_mailbox(s
+ mbox_stat2 = readl(&ha->reg->mailbox[2]);
+ mbox_stat3 = readl(&ha->reg->mailbox[3]);
+
+- if ((mbox_stat3 == 5) && (mbox_stat2 == 3))
++ if ((mbox_stat3 == 5) && (mbox_stat2 == 3))
+ set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
+- else if ((mbox_stat3 == 2) && (mbox_stat2 == 5))
++ else if ((mbox_stat3 == 2) && (mbox_stat2 == 5))
+ set_bit(DPC_RESET_HA, &ha->dpc_flags);
+ break;
+
+@@ -591,10 +592,10 @@ void qla4xxx_interrupt_service_routine(s
+ * qla4xxx_intr_handler - hardware interrupt handler.
+ * @irq: Unused
+ * @dev_id: Pointer to host adapter structure
++ * @regs: Unused
+ **/
+-irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
++QL_DECLARE_INTR_HANDLER(qla4xxx_intr_handler, irq, dev_id, regs)
+ {
+-
+ struct scsi_qla_host *ha;
+ uint32_t intr_status;
+ unsigned long flags = 0;
+@@ -625,8 +626,7 @@ irqreturn_t qla4xxx_intr_handler(int irq
+ intr_status = readl(&ha->reg->ctrl_status);
+
+ if ((intr_status &
+- (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) ==
+- 0) {
++ (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) == 0) {
+ if (reqs_count == 0)
+ ha->spurious_int_count++;
+ break;
+@@ -662,6 +662,8 @@ irqreturn_t qla4xxx_intr_handler(int irq
+ break;
+ } else if (intr_status & CSR_SCSI_RESET_INTR) {
+ clear_bit(AF_ONLINE, &ha->flags);
++ dev_info(&ha->pdev->dev,"%s: adapter OFFLINE\n",
++ __func__);
+ __qla4xxx_disable_intrs(ha);
+
+ writel(set_rmask(CSR_SCSI_RESET_INTR),
+--- a/drivers/scsi/qla4xxx/ql4_mbx.c
++++ b/drivers/scsi/qla4xxx/ql4_mbx.c
+@@ -10,6 +10,7 @@
+ #include "ql4_glbl.h"
+ #include "ql4_dbg.h"
+ #include "ql4_inline.h"
++#include "ql4_os.h"
+
+
+ /**
+@@ -43,6 +44,7 @@ int qla4xxx_mailbox_command(struct scsi_
+
+ /* Mailbox code active */
+ wait_count = MBOX_TOV * 100;
++
+ while (wait_count--) {
+ mutex_lock(&ha->mbox_sem);
+ if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
+@@ -166,6 +168,8 @@ int qla4xxx_mailbox_command(struct scsi_
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+ mbox_exit:
++ if (status == QLA_SUCCESS)
++ qla4xxx_check_for_clear_ddb(ha, mbx_cmd);
+ mutex_lock(&ha->mbox_sem);
+ clear_bit(AF_MBOX_COMMAND, &ha->flags);
+ mutex_unlock(&ha->mbox_sem);
+@@ -851,8 +855,8 @@ int qla4xxx_get_flash(struct scsi_qla_ho
+ * qla4xxx_get_fw_version - gets firmware version
+ * @ha: Pointer to host adapter structure.
+ *
+- * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
+- * hold an address for data. Make sure that we write 0 to those mailboxes,
++ * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
++ * hold an address for data. Make sure that we write 0 to those mailboxes,
+ * if unused.
+ **/
+ int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
+@@ -882,8 +886,7 @@ int qla4xxx_get_fw_version(struct scsi_q
+ return QLA_SUCCESS;
+ }
+
+-static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha,
+- dma_addr_t dma_addr)
++int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, dma_addr_t dma_addr)
+ {
+ uint32_t mbox_cmd[MBOX_REG_COUNT];
+ uint32_t mbox_sts[MBOX_REG_COUNT];
+--- a/drivers/scsi/qla4xxx/ql4_os.c
++++ b/drivers/scsi/qla4xxx/ql4_os.c
+@@ -15,6 +15,8 @@
+ #include "ql4_glbl.h"
+ #include "ql4_dbg.h"
+ #include "ql4_inline.h"
++#include "ql4_os.h"
++
+
+ /*
+ * Driver version
+@@ -56,24 +58,32 @@ MODULE_PARM_DESC(extended_error_logging,
+ "Option to enable extended error logging, "
+ "Default is 0 - no logging, 1 - debug logging");
+
++/* Command Timeout before ddb state goes to MISSING */
++int cmd_timeout = IOCB_CMD_TIMEOUT;
++module_param(cmd_timeout, int, S_IRUGO | S_IRUSR);
++MODULE_PARM_DESC(cmd_timeout, "Command Timeout");
++
++/* Timeout before ddb state MISSING goes DEAD */
++int recovery_tmo = RECOVERY_TIMEOUT;
++module_param(recovery_tmo, int, S_IRUGO | S_IRUSR);
++MODULE_PARM_DESC(recovery_tmo, "Recovery Timeout");
++
+ int ql4_mod_unload = 0;
+ /*
+ * SCSI host template entry points
+ */
+-static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha);
++
++void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha);
+
+ /*
+ * iSCSI template entry points
+ */
+-static int qla4xxx_tgt_dscvr(struct Scsi_Host *shost,
+- enum iscsi_tgt_dscvr type, uint32_t enable,
+- struct sockaddr *dst_addr);
++static int qla4xxx_host_get_param(struct Scsi_Host *,
++ enum iscsi_host_param, char *);
+ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn,
+ enum iscsi_param param, char *buf);
+ static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess,
+ enum iscsi_param param, char *buf);
+-static int qla4xxx_host_get_param(struct Scsi_Host *shost,
+- enum iscsi_host_param param, char *buf);
+ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session);
+
+ /*
+@@ -85,11 +95,13 @@ static int qla4xxx_eh_device_reset(struc
+ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd);
+ static int qla4xxx_slave_alloc(struct scsi_device *device);
+ static int qla4xxx_slave_configure(struct scsi_device *device);
++static void qla4xxx_slave_destroy(struct scsi_device *device);
+
+ static struct scsi_host_template qla4xxx_driver_template = {
+ .module = THIS_MODULE,
+ .name = DRIVER_NAME,
+ .proc_name = DRIVER_NAME,
++ .proc_info = qla4xxx_proc_info,
+ .queuecommand = qla4xxx_queuecommand,
+
+ .eh_device_reset_handler = qla4xxx_eh_device_reset,
+@@ -97,6 +109,7 @@ static struct scsi_host_template qla4xxx
+
+ .slave_configure = qla4xxx_slave_configure,
+ .slave_alloc = qla4xxx_slave_alloc,
++ .slave_destroy = qla4xxx_slave_destroy,
+
+ .this_id = -1,
+ .cmd_per_lun = 3,
+@@ -113,10 +126,13 @@ static struct iscsi_transport qla4xxx_is
+ ISCSI_CONN_ADDRESS |
+ ISCSI_TARGET_NAME |
+ ISCSI_TPGT,
+- .tgt_dscvr = qla4xxx_tgt_dscvr,
++
++ QL_INIT_SESSION_DATASIZE(sessiondata_size)
++ QL_INIT_HOST_TEMPLATE(host_template)
++
++ .get_host_param = qla4xxx_host_get_param,
+ .get_conn_param = qla4xxx_conn_get_param,
+ .get_session_param = qla4xxx_sess_get_param,
+- .get_host_param = qla4xxx_host_get_param,
+ .session_recovery_timedout = qla4xxx_recovery_timedout,
+ };
+
+@@ -134,31 +150,9 @@ static void qla4xxx_recovery_timedout(st
+ ddb_entry->fw_ddb_index, ddb_entry->os_target_id,
+ ha->port_down_retry_count);
+
+- DEBUG2(printk("scsi%ld: %s: scheduling dpc routine - dpc flags = "
+- "0x%lx\n", ha->host_no, __func__, ha->dpc_flags));
+- queue_work(ha->dpc_thread, &ha->dpc_work);
+-}
+-
+-static int qla4xxx_host_get_param(struct Scsi_Host *shost,
+- enum iscsi_host_param param, char *buf)
+-{
+- struct scsi_qla_host *ha = to_qla_host(shost);
+- int len;
+-
+- switch (param) {
+- case ISCSI_HOST_PARAM_IPADDRESS:
+- len = sprintf(buf, "%d.%d.%d.%d", ha->ip_address[0],
+- ha->ip_address[1], ha->ip_address[2],
+- ha->ip_address[3]);
+- break;
+- case ISCSI_HOST_PARAM_INITIATOR_NAME:
+- len = sprintf(buf, "%s", ha->name_string);
+- break;
+- default:
+- return -ENOSYS;
+- }
++ QL_SET_DDB_OFFLINE(ha, ddb_entry);
+
+- return len;
++ queue_work(ha->dpc_thread, &ha->dpc_work);
+ }
+
+ int qla4xxx_conn_start(struct iscsi_cls_conn *conn)
+@@ -166,7 +160,8 @@ int qla4xxx_conn_start(struct iscsi_cls_
+ struct iscsi_cls_session *session;
+ struct ddb_entry *ddb_entry;
+
+- session = iscsi_dev_to_session(conn->dev.parent);
++ session = QL_ISCSI_CONN_TO_SESS(conn);
++
+ ddb_entry = session->dd_data;
+
+ DEBUG2(printk("scsi%ld: %s: index [%d] starting conn\n",
+@@ -181,7 +176,8 @@ static void qla4xxx_conn_stop(struct isc
+ struct iscsi_cls_session *session;
+ struct ddb_entry *ddb_entry;
+
+- session = iscsi_dev_to_session(conn->dev.parent);
++ session = QL_ISCSI_CONN_TO_SESS(conn);
++
+ ddb_entry = session->dd_data;
+
+ DEBUG2(printk("scsi%ld: %s: index [%d] stopping conn\n",
+@@ -207,6 +203,12 @@ static int qla4xxx_sess_get_param(struct
+ case ISCSI_PARAM_TPGT:
+ len = sprintf(buf, "%u", ddb_entry->tpgt);
+ break;
++
++#ifdef ISCSI_ISID
++ case ISCSI_PARAM_ISID:
++ len = sprintf(buf, "%u", QL_ISCSI_SESSION_ID(ddb_entry));
++ break;
++#endif
+ default:
+ return -ENOSYS;
+ }
+@@ -221,7 +223,8 @@ static int qla4xxx_conn_get_param(struct
+ struct ddb_entry *ddb_entry;
+ int len;
+
+- session = iscsi_dev_to_session(conn->dev.parent);
++ session = QL_ISCSI_CONN_TO_SESS(conn);
++
+ ddb_entry = session->dd_data;
+
+ switch (param) {
+@@ -240,47 +243,53 @@ static int qla4xxx_conn_get_param(struct
+ return len;
+ }
+
+-static int qla4xxx_tgt_dscvr(struct Scsi_Host *shost,
+- enum iscsi_tgt_dscvr type, uint32_t enable,
+- struct sockaddr *dst_addr)
++static int qla4xxx_host_get_param(struct Scsi_Host *shost,
++ enum iscsi_host_param param, char *buf)
+ {
+- struct scsi_qla_host *ha;
+- struct sockaddr_in *addr;
+- struct sockaddr_in6 *addr6;
+- int ret = 0;
+-
+- ha = (struct scsi_qla_host *) shost->hostdata;
+-
+- switch (type) {
+- case ISCSI_TGT_DSCVR_SEND_TARGETS:
+- if (dst_addr->sa_family == AF_INET) {
+- addr = (struct sockaddr_in *)dst_addr;
+- if (qla4xxx_send_tgts(ha, (char *)&addr->sin_addr,
+- addr->sin_port) != QLA_SUCCESS)
+- ret = -EIO;
+- } else if (dst_addr->sa_family == AF_INET6) {
+- /*
+- * TODO: fix qla4xxx_send_tgts
+- */
+- addr6 = (struct sockaddr_in6 *)dst_addr;
+- if (qla4xxx_send_tgts(ha, (char *)&addr6->sin6_addr,
+- addr6->sin6_port) != QLA_SUCCESS)
+- ret = -EIO;
+- } else
+- ret = -ENOSYS;
++ struct scsi_qla_host *ha = to_qla_host(shost);
++ int len;
++
++ switch (param) {
++ case ISCSI_HOST_PARAM_IPADDRESS:
++ len = sprintf(buf, "%d.%d.%d.%d", ha->ip_address[0],
++ ha->ip_address[1], ha->ip_address[2],
++ ha->ip_address[3]);
++ break;
++ case ISCSI_HOST_PARAM_INITIATOR_NAME:
++ len = sprintf(buf, "%s", ha->name_string);
+ break;
+ default:
+- ret = -ENOSYS;
++ return -ENOSYS;
+ }
+- return ret;
++
++ return len;
++}
++
++static int ql_alloc_osindex(struct scsi_qla_host *ha)
++{
++ unsigned int idx;
++
++ for (idx = 0; idx < MAX_DDB_ENTRIES; idx++)
++ if (test_and_set_bit((idx & 0x1F), &ha->os_map[(idx >> 5)]) == 0)
++ return idx;
++ return -1;
++}
++
++static void free_osindex(struct scsi_qla_host *ha, uint32_t idx)
++{
++ clear_bit((idx & 0x1F), &ha->os_map[idx >> 5]);
+ }
+
++
+ void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry)
+ {
+ if (!ddb_entry->sess)
+ return;
++ free_osindex(ddb_entry->ha, ddb_entry->os_target_id);
+
+ if (ddb_entry->conn) {
++ QL_ISCSI_IF_DESTROY_SESSION_DONE(ddb_entry);
++ QL_ISCSI_DESTROY_CONN(ddb_entry);
+ iscsi_remove_session(ddb_entry->sess);
+ }
+ iscsi_free_session(ddb_entry->sess);
+@@ -290,25 +299,27 @@ int qla4xxx_add_sess(struct ddb_entry *d
+ {
+ int err;
+
+- err = iscsi_add_session(ddb_entry->sess, ddb_entry->fw_ddb_index);
++ err = QL_ISCSI_ADD_SESS(ddb_entry);
++
+ if (err) {
+ DEBUG2(printk(KERN_ERR "Could not add session.\n"));
+ return err;
+ }
+
+- ddb_entry->conn = iscsi_create_conn(ddb_entry->sess, 0, 0);
++ ddb_entry->conn = QL_ISCSI_CREATE_CONN(ddb_entry);
++
+ if (!ddb_entry->conn) {
+ iscsi_remove_session(ddb_entry->sess);
+ DEBUG2(printk(KERN_ERR "Could not add connection.\n"));
+ return -ENOMEM;
+ }
+
+- ddb_entry->sess->recovery_tmo = ddb_entry->ha->port_down_retry_count;
+- if (scan)
+- scsi_scan_target(&ddb_entry->sess->dev, 0,
+- ddb_entry->sess->target_id,
+- SCAN_WILD_CARD, 0);
+- iscsi_unblock_session(ddb_entry->sess);
++ ddb_entry->sess->recovery_tmo = QL_SESS_RECOVERY_TO(ddb_entry);
++
++ qla4xxx_scan_target(ddb_entry);
++
++ QL_ISCSI_CREATE_SESS_DONE(ddb_entry);
++
+ return 0;
+ }
+
+@@ -317,13 +328,20 @@ struct ddb_entry *qla4xxx_alloc_sess(str
+ struct ddb_entry *ddb_entry;
+ struct iscsi_cls_session *sess;
+
+- sess = iscsi_alloc_session(ha->host, &qla4xxx_iscsi_transport,
+- sizeof(struct ddb_entry));
+- if (!sess)
++ int os_idx;
++
++ if ((os_idx = ql_alloc_osindex(ha)) >= MAX_DDB_ENTRIES)
++ return NULL;
++
++ sess = QL_ISCSI_ALLOC_SESSION(ha, &qla4xxx_iscsi_transport);
++ if (!sess) {
++ free_osindex(ha, os_idx);
+ return NULL;
++ }
+
+ ddb_entry = sess->dd_data;
+ memset(ddb_entry, 0, sizeof(*ddb_entry));
++ ddb_entry->os_target_id = os_idx;
+ ddb_entry->ha = ha;
+ ddb_entry->sess = sess;
+ return ddb_entry;
+@@ -371,9 +389,9 @@ void qla4xxx_mark_device_missing(struct
+ }
+
+ static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha,
+- struct ddb_entry *ddb_entry,
+- struct scsi_cmnd *cmd,
+- void (*done)(struct scsi_cmnd *))
++ struct ddb_entry *ddb_entry,
++ struct scsi_cmnd *cmd,
++ void (*done)(struct scsi_cmnd *))
+ {
+ struct srb *srb;
+
+@@ -392,17 +410,6 @@ static struct srb* qla4xxx_get_new_srb(s
+ return srb;
+ }
+
+-static void qla4xxx_srb_free_dma(struct scsi_qla_host *ha, struct srb *srb)
+-{
+- struct scsi_cmnd *cmd = srb->cmd;
+-
+- if (srb->flags & SRB_DMA_VALID) {
+- scsi_dma_unmap(cmd);
+- srb->flags &= ~SRB_DMA_VALID;
+- }
+- cmd->SCp.ptr = NULL;
+-}
+-
+ void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb)
+ {
+ struct scsi_cmnd *cmd = srb->cmd;
+@@ -418,14 +425,14 @@ void qla4xxx_srb_compl(struct scsi_qla_h
+ * qla4xxx_queuecommand - scsi layer issues scsi command to driver.
+ * @cmd: Pointer to Linux's SCSI command structure
+ * @done_fn: Function that the driver calls to notify the SCSI mid-layer
+- * that the command has been processed.
++ * that the command has been processed.
+ *
+ * Remarks:
+ * This routine is invoked by Linux to send a SCSI command to the driver.
+ * The mid-level driver tries to ensure that queuecommand never gets
+ * invoked concurrently with itself or the interrupt handler (although
+ * the interrupt handler may call this routine as part of request-
+- * completion handling). Unfortunely, it sometimes calls the scheduler
++ * completion handling). Unfortunely, it sometimes calls the scheduler
+ * in interrupt context which is a big NO! NO!.
+ **/
+ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
+@@ -546,7 +553,7 @@ static int qla4xxx_mem_alloc(struct scsi
+ align = 0;
+ if ((unsigned long)ha->queues_dma & (MEM_ALIGN_VALUE - 1))
+ align = MEM_ALIGN_VALUE - ((unsigned long)ha->queues_dma &
+- (MEM_ALIGN_VALUE - 1));
++ (MEM_ALIGN_VALUE - 1));
+
+ /* Update request and response queue pointers. */
+ ha->request_dma = ha->queues_dma + align;
+@@ -554,16 +561,16 @@ static int qla4xxx_mem_alloc(struct scsi
+ ha->response_dma = ha->queues_dma + align +
+ (REQUEST_QUEUE_DEPTH * QUEUE_SIZE);
+ ha->response_ring = (struct queue_entry *) (ha->queues + align +
+- (REQUEST_QUEUE_DEPTH *
+- QUEUE_SIZE));
++ (REQUEST_QUEUE_DEPTH *
++ QUEUE_SIZE));
+ ha->shadow_regs_dma = ha->queues_dma + align +
+ (REQUEST_QUEUE_DEPTH * QUEUE_SIZE) +
+ (RESPONSE_QUEUE_DEPTH * QUEUE_SIZE);
+ ha->shadow_regs = (struct shadow_regs *) (ha->queues + align +
+ (REQUEST_QUEUE_DEPTH *
+- QUEUE_SIZE) +
++ QUEUE_SIZE) +
+ (RESPONSE_QUEUE_DEPTH *
+- QUEUE_SIZE));
++ QUEUE_SIZE));
+
+ /* Allocate memory for srb pool. */
+ ha->srb_mempool = mempool_create(SRB_MIN_REQ, mempool_alloc_slab,
+@@ -595,12 +602,12 @@ static void qla4xxx_timer(struct scsi_ql
+ list_for_each_entry_safe(ddb_entry, dtemp, &ha->ddb_list, list) {
+ /* Count down time between sending relogins */
+ if (adapter_up(ha) &&
+- !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
+- atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) {
++ !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
++ atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) {
+ if (atomic_read(&ddb_entry->retry_relogin_timer) !=
+- INVALID_ENTRY) {
++ INVALID_ENTRY) {
+ if (atomic_read(&ddb_entry->retry_relogin_timer)
+- == 0) {
++ == 0) {
+ atomic_set(&ddb_entry->
+ retry_relogin_timer,
+ INVALID_ENTRY);
+@@ -608,9 +615,9 @@ static void qla4xxx_timer(struct scsi_ql
+ &ha->dpc_flags);
+ set_bit(DF_RELOGIN, &ddb_entry->flags);
+ DEBUG2(printk("scsi%ld: %s: index [%d]"
+- " login device\n",
+- ha->host_no, __func__,
+- ddb_entry->fw_ddb_index));
++ " login device\n",
++ ha->host_no, __func__,
++ ddb_entry->fw_ddb_index));
+ } else
+ atomic_dec(&ddb_entry->
+ retry_relogin_timer);
+@@ -619,64 +626,64 @@ static void qla4xxx_timer(struct scsi_ql
+
+ /* Wait for relogin to timeout */
+ if (atomic_read(&ddb_entry->relogin_timer) &&
+- (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) {
++ (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) {
+ /*
+ * If the relogin times out and the device is
+ * still NOT ONLINE then try and relogin again.
+ */
+ if (atomic_read(&ddb_entry->state) !=
+- DDB_STATE_ONLINE &&
+- ddb_entry->fw_ddb_device_state ==
+- DDB_DS_SESSION_FAILED) {
++ DDB_STATE_ONLINE &&
++ ddb_entry->fw_ddb_device_state ==
++ DDB_DS_SESSION_FAILED) {
+ /* Reset retry relogin timer */
+ atomic_inc(&ddb_entry->relogin_retry_count);
+ DEBUG2(printk("scsi%ld: index[%d] relogin"
+- " timed out-retrying"
+- " relogin (%d)\n",
+- ha->host_no,
+- ddb_entry->fw_ddb_index,
+- atomic_read(&ddb_entry->
++ " timed out-retrying"
++ " relogin (%d)\n",
++ ha->host_no,
++ ddb_entry->fw_ddb_index,
++ atomic_read(&ddb_entry->
+ relogin_retry_count))
+ );
+ start_dpc++;
+ DEBUG(printk("scsi%ld:%d:%d: index [%d] "
+- "initate relogin after"
+- " %d seconds\n",
+- ha->host_no, ddb_entry->bus,
+- ddb_entry->target,
+- ddb_entry->fw_ddb_index,
+- ddb_entry->default_time2wait + 4)
+- );
++ "initate relogin after"
++ " %d seconds\n",
++ ha->host_no, ddb_entry->bus,
++ ddb_entry->target,
++ ddb_entry->fw_ddb_index,
++ ddb_entry->default_time2wait + 4));
+
+ atomic_set(&ddb_entry->retry_relogin_timer,
+- ddb_entry->default_time2wait + 4);
++ ddb_entry->default_time2wait + 4);
+ }
+ }
+ }
+
+ /* Check for heartbeat interval. */
+ if (ha->firmware_options & FWOPT_HEARTBEAT_ENABLE &&
+- ha->heartbeat_interval != 0) {
++ ha->heartbeat_interval != 0) {
+ ha->seconds_since_last_heartbeat++;
+ if (ha->seconds_since_last_heartbeat >
+- ha->heartbeat_interval + 2)
++ ha->heartbeat_interval + 2)
+ set_bit(DPC_RESET_HA, &ha->dpc_flags);
+ }
+
+
+ /* Wakeup the dpc routine for this adapter, if needed. */
+ if ((start_dpc ||
+- test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
+- test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) ||
+- test_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags) ||
+- test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) ||
+- test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
+- test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) ||
+- test_bit(DPC_AEN, &ha->dpc_flags)) &&
+- ha->dpc_thread) {
++ test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
++ test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) ||
++ test_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags) ||
++ test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) ||
++ test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
++ test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) ||
++ QL_DPC_OFFLINE_SET(ha) ||
++ test_bit(DPC_AEN, &ha->dpc_flags)) &&
++ ha->dpc_thread) {
+ DEBUG2(printk("scsi%ld: %s: scheduling dpc routine"
+- " - dpc flags = 0x%lx\n",
+- ha->host_no, __func__, ha->dpc_flags));
++ " - dpc flags = 0x%lx\n",
++ ha->host_no, __func__, ha->dpc_flags));
+ queue_work(ha->dpc_thread, &ha->dpc_work);
+ }
+
+@@ -732,14 +739,15 @@ static int qla4xxx_cmd_wait(struct scsi_
+ return stat;
+ }
+
+-void qla4xxx_hw_reset(struct scsi_qla_host *ha)
++void qla4xxx_hw_reset(struct scsi_qla_host *ha, int hw_lock)
+ {
+ uint32_t ctrl_status;
+ unsigned long flags = 0;
+
+ DEBUG2(printk(KERN_ERR "scsi%ld: %s\n", ha->host_no, __func__));
+
+- spin_lock_irqsave(&ha->hardware_lock, flags);
++ if (hw_lock)
++ spin_lock_irqsave(&ha->hardware_lock, flags);
+ /*
+ * If the SCSI Reset Interrupt bit is set, clear it.
+ * Otherwise, the Soft Reset won't work.
+@@ -752,7 +760,8 @@ void qla4xxx_hw_reset(struct scsi_qla_ho
+ writel(set_rmask(CSR_SOFT_RESET), &ha->reg->ctrl_status);
+ readl(&ha->reg->ctrl_status);
+
+- spin_unlock_irqrestore(&ha->hardware_lock, flags);
++ if (hw_lock)
++ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
+
+ /**
+@@ -766,7 +775,7 @@ int qla4xxx_soft_reset(struct scsi_qla_h
+ int status = QLA_ERROR;
+ uint32_t ctrl_status;
+
+- qla4xxx_hw_reset(ha);
++ qla4xxx_hw_reset(ha, 1);
+
+ /* Wait until the Network Reset Intr bit is cleared */
+ max_wait_time = RESET_INTR_TOV;
+@@ -783,9 +792,9 @@ int qla4xxx_soft_reset(struct scsi_qla_h
+
+ if ((ctrl_status & CSR_NET_RESET_INTR) != 0) {
+ DEBUG2(printk(KERN_WARNING
+- "scsi%ld: Network Reset Intr not cleared by "
+- "Network function, clearing it now!\n",
+- ha->host_no));
++ "scsi%ld: Network Reset Intr not cleared by "
++ "Network function, clearing it now!\n",
++ ha->host_no));
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ writel(set_rmask(CSR_NET_RESET_INTR), &ha->reg->ctrl_status);
+ readl(&ha->reg->ctrl_status);
+@@ -881,14 +890,13 @@ static void qla4xxx_flush_active_srbs(st
+ * qla4xxx_recover_adapter - recovers adapter after a fatal error
+ * @ha: Pointer to host adapter structure.
+ **/
+-static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
++static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
+ {
+ int status;
+
+ /* Stall incoming I/O until we are done */
+ clear_bit(AF_ONLINE, &ha->flags);
+- DEBUG2(printk("scsi%ld: %s calling qla4xxx_cmd_wait\n", ha->host_no,
+- __func__));
++ dev_info(&ha->pdev->dev, "%s: adapter OFFLINE\n", __func__);
+
+ /* Wait for outstanding commands to complete.
+ * Stalls the driver for max 30 secs
+@@ -905,7 +913,7 @@ static int qla4xxx_recover_adapter(struc
+ */
+ if (status == QLA_SUCCESS) {
+ DEBUG2(printk(KERN_ERR "scsi%ld: %s - Performing soft reset..\n",
+- ha->host_no, __func__));
++ ha->host_no, __func__));
+ qla4xxx_flush_active_srbs(ha);
+ if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS)
+ status = qla4xxx_soft_reset(ha);
+@@ -920,24 +928,26 @@ static int qla4xxx_recover_adapter(struc
+ * with ISP interrupts enabled */
+ if (status == QLA_SUCCESS) {
+ DEBUG2(printk("scsi%ld: %s - Initializing adapter..\n",
+- ha->host_no, __func__));
++ ha->host_no, __func__));
+
+ /* If successful, AF_ONLINE flag set in
+ * qla4xxx_initialize_adapter */
++ if (ha->mac_index == 3)
++ ssleep(6);
+ status = qla4xxx_initialize_adapter(ha, PRESERVE_DDB_LIST);
+ }
+
+ /* Failed adapter initialization?
+ * Retry reset_ha only if invoked via DPC (DPC_RESET_HA) */
+ if ((test_bit(AF_ONLINE, &ha->flags) == 0) &&
+- (test_bit(DPC_RESET_HA, &ha->dpc_flags))) {
++ (test_bit(DPC_RESET_HA, &ha->dpc_flags))) {
+ /* Adapter initialization failed, see if we can retry
+ * resetting the ha */
+ if (!test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags)) {
+ ha->retry_reset_ha_cnt = MAX_RESET_HA_RETRIES;
+ DEBUG2(printk("scsi%ld: recover adapter - retrying "
+- "(%d) more times\n", ha->host_no,
+- ha->retry_reset_ha_cnt));
++ "(%d) more times\n", ha->host_no,
++ ha->retry_reset_ha_cnt));
+ set_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);
+ status = QLA_ERROR;
+ } else {
+@@ -945,9 +955,9 @@ static int qla4xxx_recover_adapter(struc
+ /* Schedule another Reset HA--DPC will retry */
+ ha->retry_reset_ha_cnt--;
+ DEBUG2(printk("scsi%ld: recover adapter - "
+- "retry remaining %d\n",
+- ha->host_no,
+- ha->retry_reset_ha_cnt));
++ "retry remaining %d\n",
++ ha->host_no,
++ ha->retry_reset_ha_cnt));
+ status = QLA_ERROR;
+ }
+
+@@ -955,8 +965,8 @@ static int qla4xxx_recover_adapter(struc
+ /* Recover adapter retries have been exhausted.
+ * Adapter DEAD */
+ DEBUG2(printk("scsi%ld: recover adapter "
+- "failed - board disabled\n",
+- ha->host_no));
++ "failed - board disabled\n",
++ ha->host_no));
+ qla4xxx_flush_active_srbs(ha);
+ clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);
+ clear_bit(DPC_RESET_HA, &ha->dpc_flags);
+@@ -991,10 +1001,9 @@ static int qla4xxx_recover_adapter(struc
+ * the mid-level tries to sleep when it reaches the driver threshold
+ * "host->can_queue". This can cause a panic if we were in our interrupt code.
+ **/
+-static void qla4xxx_do_dpc(struct work_struct *work)
++static QL_DECLARE_DPC(qla4xxx_do_dpc, data)
+ {
+- struct scsi_qla_host *ha =
+- container_of(work, struct scsi_qla_host, dpc_work);
++ struct scsi_qla_host *ha = QL_DPC_DATA_TO_HA(data);
+ struct ddb_entry *ddb_entry, *dtemp;
+ int status = QLA_ERROR;
+
+@@ -1009,11 +1018,11 @@ static void qla4xxx_do_dpc(struct work_s
+ return;
+
+ if (adapter_up(ha) ||
+- test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
+- test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
+- test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) {
++ test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
++ test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
++ test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) {
+ if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) ||
+- test_bit(DPC_RESET_HA, &ha->dpc_flags))
++ test_bit(DPC_RESET_HA, &ha->dpc_flags))
+ qla4xxx_recover_adapter(ha);
+
+ if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {
+@@ -1025,14 +1034,15 @@ static void qla4xxx_do_dpc(struct work_s
+ break;
+ msleep(1000);
+ }
++
+ if (wait_time == 0)
+ DEBUG2(printk("scsi%ld: %s: SR|FSR "
+- "bit not cleared-- resetting\n",
+- ha->host_no, __func__));
++ "bit not cleared-- resetting\n",
++ ha->host_no, __func__));
+ qla4xxx_flush_active_srbs(ha);
+ if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) {
+ qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
+- status = qla4xxx_initialize_adapter(ha,
++ status = qla4xxx_initialize_adapter(ha,
+ PRESERVE_DDB_LIST);
+ }
+ clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
+@@ -1049,13 +1059,42 @@ static void qla4xxx_do_dpc(struct work_s
+ if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))
+ qla4xxx_get_dhcp_ip_address(ha);
+
++ qla4xxx_check_dev_offline(ha);
++
++ if (test_and_clear_bit(DPC_DELETE_DEVICE, &ha->dpc_flags)) {
++ list_for_each_entry_safe(ddb_entry, dtemp,
++ &ha->ddb_list, list) {
++ if (test_and_clear_bit(DF_DELETED,
++ &ddb_entry->flags)) {
++ if (atomic_read(&ddb_entry->state) ==
++ DDB_STATE_DEAD) {
++ dev_info(&ha->pdev->dev,
++ "%s: ddb[%d] os[%d] - "
++ "delete\n",
++ __func__,
++ ddb_entry->fw_ddb_index,
++ ddb_entry->os_target_id);
++ } else {
++ dev_info(&ha->pdev->dev,
++ "%s: ddb[%d] os[%d] - "
++ "ddb state not dead but"
++ " marked for delete\n",
++ __func__,
++ ddb_entry->fw_ddb_index,
++ ddb_entry->os_target_id);
++ }
++ }
++ }
++ }
++
+ /* ---- relogin device? --- */
+ if (adapter_up(ha) &&
+- test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) {
++ test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) {
+ list_for_each_entry_safe(ddb_entry, dtemp,
+ &ha->ddb_list, list) {
+ if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) &&
+- atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE)
++ (atomic_read(&ddb_entry->state) !=
++ DDB_STATE_ONLINE))
+ qla4xxx_relogin_device(ha, ddb_entry);
+
+ /*
+@@ -1092,7 +1131,7 @@ static void qla4xxx_free_adapter(struct
+
+ /* Issue Soft Reset to put firmware in unknown state */
+ if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS)
+- qla4xxx_hw_reset(ha);
++ qla4xxx_hw_reset(ha, 1);
+
+ /* Remove timer thread, if present */
+ if (ha->timer_active)
+@@ -1142,6 +1181,7 @@ static int qla4xxx_iospace_config(struct
+ if (!(mmio_flags & IORESOURCE_MEM)) {
+ dev_err(&ha->pdev->dev,
+ "region #0 not an MMIO resource, aborting\n");
++
+ goto iospace_error_exit;
+ }
+ if (mmio_len < MIN_IOBASE_LEN) {
+@@ -1173,14 +1213,6 @@ iospace_error_exit:
+ return -ENOMEM;
+ }
+
+-static void ql4_get_aen_log(struct scsi_qla_host *ha, struct ql4_aen_log *aenl)
+-{
+- if (aenl) {
+- memcpy(aenl, &ha->aen_log, sizeof (ha->aen_log));
+- ha->aen_log.count = 0;
+- }
+-}
+-
+ /**
+ * qla4xxx_probe_adapter - callback function to probe HBA
+ * @pdev: pointer to pci_dev structure
+@@ -1191,7 +1223,7 @@ static void ql4_get_aen_log(struct scsi_
+ * the driver.
+ **/
+ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
+- const struct pci_device_id *ent)
++ const struct pci_device_id *ent)
+ {
+ int ret = -ENODEV, status;
+ struct Scsi_Host *host;
+@@ -1206,7 +1238,7 @@ static int __devinit qla4xxx_probe_adapt
+ host = scsi_host_alloc(&qla4xxx_driver_template, sizeof(*ha));
+ if (host == NULL) {
+ printk(KERN_WARNING
+- "qla4xxx: Couldn't allocate host from scsi layer!\n");
++ "qla4xxx: Couldn't allocate host from scsi layer!\n");
+ goto probe_disable_device;
+ }
+
+@@ -1218,10 +1250,7 @@ static int __devinit qla4xxx_probe_adapt
+ ha->pdev = pdev;
+ ha->host = host;
+ ha->host_no = host->host_no;
+-
+- ha->ql4mbx = qla4xxx_mailbox_command;
+- ha->ql4cmd = qla4xxx_send_command_to_isp;
+- ha->ql4getaenlog = ql4_get_aen_log;
++ set_bit(AF_OS_INDEX_VALID, &ha->flags);
+
+ /* Configure PCI I/O space. */
+ ret = qla4xxx_iospace_config(ha);
+@@ -1229,7 +1258,7 @@ static int __devinit qla4xxx_probe_adapt
+ goto probe_failed;
+
+ dev_info(&ha->pdev->dev, "Found an ISP%04x, irq %d, iobase 0x%p\n",
+- pdev->device, pdev->irq, ha->reg);
++ pdev->device, pdev->irq, ha->reg);
+
+ qla4xxx_config_dma_addressing(ha);
+
+@@ -1245,7 +1274,7 @@ static int __devinit qla4xxx_probe_adapt
+ /* Allocate dma buffers */
+ if (qla4xxx_mem_alloc(ha)) {
+ dev_warn(&ha->pdev->dev,
+- "[ERROR] Failed to allocate memory for adapter\n");
++ "[ERROR] Failed to allocate memory for adapter\n");
+
+ ret = -ENOMEM;
+ goto probe_failed;
+@@ -1258,8 +1287,8 @@ static int __devinit qla4xxx_probe_adapt
+ */
+ status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST);
+ while (status == QLA_ERROR && init_retry_count++ < MAX_INIT_RETRIES) {
+- DEBUG2(printk(KERN_ERR "scsi%ld: %s: retrying adapter initialization "
+- "(%d)\n", ha->host_no, __func__, init_retry_count));
++ DEBUG2(dev_info(&ha->pdev->dev, "%s: retry adapter init %d\n",
++ __func__, init_retry_count));
+ qla4xxx_soft_reset(ha);
+ status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST);
+ }
+@@ -1280,7 +1309,7 @@ static int __devinit qla4xxx_probe_adapt
+
+ /* Startup the kernel thread for this host adapter. */
+ DEBUG2(printk("scsi: %s: Starting kernel thread for "
+- "qla4xxx_dpc\n", __func__));
++ "qla4xxx_dpc\n", __func__));
+ sprintf(buf, "qla4xxx_%lu_dpc", ha->host_no);
+ ha->dpc_thread = create_singlethread_workqueue(buf);
+ if (!ha->dpc_thread) {
+@@ -1288,9 +1317,11 @@ static int __devinit qla4xxx_probe_adapt
+ ret = -ENODEV;
+ goto probe_failed;
+ }
+- INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc);
++ QL_INIT_WORK(ha, qla4xxx_do_dpc);
++
+ ret = request_irq(pdev->irq, qla4xxx_intr_handler,
+- IRQF_DISABLED | IRQF_SHARED, "qla4xxx", ha);
++ QL_REQ_IRQ_FLAGS, "qla4xxx", ha);
++
+ if (ret) {
+ dev_warn(&ha->pdev->dev, "Failed to reserve interrupt %d"
+ " already in use.\n", pdev->irq);
+@@ -1298,7 +1329,7 @@ static int __devinit qla4xxx_probe_adapt
+ }
+ set_bit(AF_IRQ_ATTACHED, &ha->flags);
+ host->irq = pdev->irq;
+- DEBUG(printk("scsi%d: irq %d attached\n", ha->host_no, ha->pdev->irq));
++ dev_info(&ha->pdev->dev, "irq %d attached\n", ha->pdev->irq);
+
+ qla4xxx_enable_intrs(ha);
+
+@@ -1313,6 +1344,9 @@ static int __devinit qla4xxx_probe_adapt
+ if (ret)
+ goto probe_failed;
+
++ if ((ret = QL_ISCSI_REGISTER_HOST(host, qla4xxx_scsi_transport)))
++ goto remove_host;
++
+ /* Update transport device information for all devices. */
+ list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) {
+
+@@ -1320,25 +1354,36 @@ static int __devinit qla4xxx_probe_adapt
+ set_bit(DF_SCAN_ISSUED, &ddb_entry->flags);
+
+ if (qla4xxx_add_sess(ddb_entry,
+- test_bit(DF_SCAN_ISSUED, &ddb_entry->flags)))
++ test_bit(DF_SCAN_ISSUED, &ddb_entry->flags))) {
++ QL_ISCSI_UNREGISTER_HOST(host, qla4xxx_scsi_transport);
+ goto remove_host;
++ }
+ if (!test_bit(DF_SCAN_ISSUED, &ddb_entry->flags))
+ qla4xxx_mark_device_missing(ha, ddb_entry);
+ }
+
+- printk(KERN_INFO
+- " QLogic iSCSI HBA Driver version: %s\n"
+- " QLogic ISP%04x @ %s, pdev = %p host#=%ld, fw=%02d.%02d.%02d.%02d\n",
+- qla4xxx_version_str, ha->pdev->device, pci_name(ha->pdev), pdev,
+- ha->host_no, ha->firmware_version[0], ha->firmware_version[1],
+- ha->patch_number, ha->build_number);
++ dev_info(&ha->pdev->dev, " QLogic iSCSI HBA Driver version: %s\n"
++ " QLogic ISP%04x @ %s, pdev = %p host#=%ld,"
++ " fw=%02d.%02d.%02d.%02d\n", qla4xxx_version_str,
++ ha->pdev->device, pci_name(ha->pdev), pdev,
++ ha->host_no, ha->firmware_version[0], ha->firmware_version[1],
++ ha->patch_number, ha->build_number);
+
+ /* Insert new entry into the list of adapters. */
+ klist_add_tail(&ha->node, &qla4xxx_hostlist);
+ ha->instance = atomic_inc_return(&qla4xxx_hba_count) - 1;
+
+- DEBUG2(printk("qla4xxx: listhead=%p, done adding ha=%p i=%d\n",
+- &qla4xxx_hostlist, &ha->node, ha->instance));
++ if (qla4xxx_ioctl_init(ha)) {
++ dev_info(&ha->pdev->dev, "ioctl init failed\n");
++ QL_ISCSI_UNREGISTER_HOST(host, qla4xxx_scsi_transport);
++ goto remove_host;
++ }
++
++ DEBUG2(dev_info(&ha->pdev->dev, "listhead=%p, done adding ha=%p i=%d\n",
++ &qla4xxx_hostlist, &ha->node, ha->instance));
++
++// set_bit(AF_INIT_DONE, &ha->flags);
++ dev_info(&ha->pdev->dev, "%s: AF_INIT_DONE\n", __func__);
+
+ return 0;
+
+@@ -1377,8 +1422,12 @@ static void __devexit qla4xxx_remove_ada
+ /* remove devs from iscsi_sessions to scsi_devices */
+ qla4xxx_free_ddb_list(ha);
+
++ QL_ISCSI_UNREGISTER_HOST(ha->host, qla4xxx_scsi_transport);
++
+ scsi_remove_host(ha->host);
+
++ qla4xxx_ioctl_exit(ha);
++
+ qla4xxx_free_adapter(ha);
+
+ scsi_host_put(ha->host);
+@@ -1393,7 +1442,7 @@ static void __devexit qla4xxx_remove_ada
+ * At exit, the @ha's flags.enable_64bit_addressing set to indicated
+ * supported addressing method.
+ */
+-static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha)
++void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha)
+ {
+ int retval;
+
+@@ -1402,9 +1451,9 @@ static void qla4xxx_config_dma_addressin
+ if (pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
+ dev_dbg(&ha->pdev->dev,
+ "Failed to set 64 bit PCI consistent mask; "
+- "using 32 bit.\n");
++ "using 32 bit.\n");
+ retval = pci_set_consistent_dma_mask(ha->pdev,
+- DMA_32BIT_MASK);
++ DMA_32BIT_MASK);
+ }
+ } else
+ retval = pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK);
+@@ -1412,7 +1461,7 @@ static void qla4xxx_config_dma_addressin
+
+ static int qla4xxx_slave_alloc(struct scsi_device *sdev)
+ {
+- struct iscsi_cls_session *sess = starget_to_session(sdev->sdev_target);
++ struct iscsi_cls_session *sess = QL_ISCSI_SDEV_TO_SESS(sdev);
+
+ if (sess) {
+ sdev->hostdata = sess->dd_data;
+@@ -1431,6 +1480,11 @@ static int qla4xxx_slave_configure(struc
+ return 0;
+ }
+
++static void qla4xxx_slave_destroy(struct scsi_device *sdev)
++{
++ sdev->hostdata = NULL;
++}
++
+ /**
+ * qla4xxx_del_from_active_array - returns an active srb
+ * @ha: Pointer to host adapter structure.
+@@ -1470,7 +1524,7 @@ struct srb * qla4xxx_del_from_active_arr
+ * for some max time.
+ **/
+ static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha,
+- struct scsi_cmnd *cmd)
++ struct scsi_cmnd *cmd)
+ {
+ int done = 0;
+ struct srb *rp;
+@@ -1564,8 +1618,8 @@ static int qla4xxx_eh_device_reset(struc
+ return ret;
+
+ dev_info(&ha->pdev->dev,
+- "scsi%ld:%d:%d:%d: DEVICE RESET ISSUED.\n", ha->host_no,
+- cmd->device->channel, cmd->device->id, cmd->device->lun);
++ "%s: %d:%d:%d: DEVICE RESET ISSUED.\n", __func__,
++ cmd->device->channel, cmd->device->id, cmd->device->lun);
+
+ if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) {
+ dev_info(&ha->pdev->dev, "%s: HBA OFFLINE: FAILED\n", __func__);
+@@ -1584,12 +1638,12 @@ static int qla4xxx_eh_device_reset(struc
+ */
+ if (cmd->device->host->shost_state == SHOST_RECOVERY) {
+ if (qla4xxx_eh_wait_for_active_target_commands(ha,
+- cmd->device->id,
+- cmd->device->
+- lun)) {
++ cmd->device->id,
++ cmd->device->
++ lun)) {
+ dev_info(&ha->pdev->dev,
+- "DEVICE RESET FAILED - waiting for "
+- "commands.\n");
++ "DEVICE RESET FAILED - waiting for "
++ "commands.\n");
+ goto eh_dev_reset_done;
+ }
+ }
+@@ -1598,9 +1652,9 @@ static int qla4xxx_eh_device_reset(struc
+ goto eh_dev_reset_done;
+
+ dev_info(&ha->pdev->dev,
+- "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n",
+- ha->host_no, cmd->device->channel, cmd->device->id,
+- cmd->device->lun);
++ "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n",
++ ha->host_no, cmd->device->channel, cmd->device->id,
++ cmd->device->lun);
+
+ ret = SUCCESS;
+
+@@ -1635,7 +1689,7 @@ static int qla4xxx_eh_host_reset(struct
+ }
+
+ dev_info(&ha->pdev->dev, "HOST RESET %s.\n",
+- return_status == FAILED ? "FAILED" : "SUCCEDED");
++ return_status == FAILED ? "FAILED" : "SUCCEDED");
+
+ return return_status;
+ }
+@@ -1664,7 +1718,7 @@ static struct pci_device_id qla4xxx_pci_
+ };
+ MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl);
+
+-static struct pci_driver qla4xxx_pci_driver = {
++struct pci_driver qla4xxx_pci_driver = {
+ .name = DRIVER_NAME,
+ .id_table = qla4xxx_pci_tbl,
+ .probe = qla4xxx_probe_adapter,
+@@ -1678,12 +1732,11 @@ static int __init qla4xxx_module_init(vo
+ atomic_set(&qla4xxx_hba_count, 0);
+ klist_init(&qla4xxx_hostlist, NULL, NULL);
+ /* Allocate cache for SRBs. */
+- srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0,
+- SLAB_HWCACHE_ALIGN, NULL);
++ srb_cachep = ql_kmem_cache_create();
++
+ if (srb_cachep == NULL) {
+- printk(KERN_ERR
+- "%s: Unable to allocate SRB cache..."
+- "Failing load!\n", DRIVER_NAME);
++ printk(KERN_ERR "%s: Unable to allocate SRB cache..."
++ "Failing load!\n", DRIVER_NAME);
+ ret = -ENOMEM;
+ goto no_srp_cache;
+ }
+@@ -1700,7 +1753,14 @@ static int __init qla4xxx_module_init(vo
+ goto release_srb_cache;
+ }
+
++ ret = QL_MISC_INIT;
++ if (ret) {
++ printk(KERN_INFO "QLogic iSCSI HBA Driver ioctl init failed\n");
++ goto unregister_transport;
++ }
++
+ printk(KERN_INFO "QLogic iSCSI HBA Driver\n");
++
+ ret = pci_register_driver(&qla4xxx_pci_driver);
+ if (ret)
+ goto unregister_transport;
+@@ -1718,6 +1778,9 @@ no_srp_cache:
+ static void __exit qla4xxx_module_exit(void)
+ {
+ ql4_mod_unload = 1;
++
++ QL_MISC_EXIT;
++
+ pci_unregister_driver(&qla4xxx_pci_driver);
+ iscsi_unregister_transport(&qla4xxx_iscsi_transport);
+ kmem_cache_destroy(srb_cachep);
+--- /dev/null
++++ b/drivers/scsi/qla4xxx/ql4_os.h
+@@ -0,0 +1,125 @@
++/*
++ * QLogic iSCSI HBA Driver
++ * Copyright (c) 2003-2006 QLogic Corporation
++ *
++ * See LICENSE.qla4xxx for copyright and licensing details.
++ */
++
++/*
++ * This file encapsulates RHEL5 Specific Code
++ */
++
++#ifndef __QLA4x_OS_H
++#define __QLA4x_OS_H
++
++/* Common across all O.S platforms */
++#define IOCB_CMD_TIMEOUT 30
++#define RELOGIN_TOV 18
++#define RECOVERY_TIMEOUT 20 /* ddb state MISSING -> DEAD */
++
++#define QL_IOCB_CMD_TIMEOUT(cmd)
++
++#define QL_SET_DDB_OFFLINE(ha, ddb_entry)
++
++#define QL_SESS_RECOVERY_TO(ddb_entry) ddb_entry->ha->port_down_retry_count
++
++#define QL_DPC_OFFLINE_SET(ha) 0
++
++#define QL_ISCSI_CONN_TO_SESS(conn) iscsi_dev_to_session(conn->dev.parent)
++
++#define QL_ISCSI_SDEV_TO_SESS(sdev) starget_to_session(sdev->sdev_target)
++
++#define QL_ISCSI_ADD_SESS(ddb_entry) \
++ iscsi_add_session(ddb_entry->sess, ddb_entry->os_target_id)
++
++#define QL_ISCSI_REGISTER_HOST(host, trans) 0
++#define QL_ISCSI_UNREGISTER_HOST(host, trans)
++
++#define QL_ISCSI_SESSION_ID(ddb_entry) ddb_entry->sess->sid
++#define QL_ISCSI_IF_DESTROY_SESSION_DONE(ddb_entry)
++#define QL_ISCSI_DESTROY_CONN(ddb_entry)
++#define QL_ISCSI_CREATE_CONN(ddb_entry) \
++ iscsi_create_conn(ddb_entry->sess, 0, 0)
++#define QL_ISCSI_CREATE_SESS_DONE(ddb_entry) \
++ iscsi_unblock_session(ddb_entry->sess)
++#define QL_ISCSI_ALLOC_SESSION(ha, trans) \
++ iscsi_alloc_session(ha->host, trans, sizeof(struct ddb_entry))
++
++
++#define QL_MISC_INIT 0
++#define QL_MISC_EXIT
++
++#define qla4xxx_check_dev_offline(ha)
++#define qla4xxx_proc_info NULL
++
++#define QL_SET_SCSI_RESID(cmd, residual) scsi_set_resid(cmd, residual)
++#define QL_SCSI_BUFFLEN(cmd) scsi_bufflen(cmd)
++
++#define QL_DPC_DATA_TO_HA(work) \
++ container_of((struct work_struct *)work, struct scsi_qla_host, dpc_work)
++
++#define QL_INIT_WORK(ha, dpc_func) INIT_WORK(&ha->dpc_work, dpc_func)
++
++#define QL_REQ_IRQ_FLAGS (IRQF_DISABLED | IRQF_SHARED)
++
++#define QL_DECLARE_INTR_HANDLER(intr_func, irq, dev_id, regs) \
++ irqreturn_t intr_func(int irq, void *dev_id)
++
++#define QL_DECLARE_DPC(dpc_func, data) \
++ void dpc_func(struct work_struct *data)
++
++#define QL_INIT_SESSION_DATASIZE(sessiondata_size)
++// .sessiondata_size = sizeof(struct ddb_entry),
++
++#define QL_INIT_HOST_TEMPLATE(host_template)
++// .host_template = &qla4xxx_driver_template,
++
++QL_DECLARE_INTR_HANDLER(qla4xxx_intr_handler, irq, dev_id, regs);
++
++static inline struct kmem_cache *ql_kmem_cache_create(void)
++{
++ return (kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0,
++ SLAB_HWCACHE_ALIGN, NULL));
++}
++
++static inline void qla4xxx_scan_target(struct ddb_entry * ddb_entry)
++{
++ scsi_scan_target(&ddb_entry->sess->dev, 0,
++ ddb_entry->sess->target_id, SCAN_WILD_CARD, 0);
++}
++
++static void ql4_get_aen_log(struct scsi_qla_host *ha, struct ql4_aen_log *aenl)
++{
++ if (aenl) {
++ memcpy(aenl, &ha->aen_log, sizeof (ha->aen_log));
++ ha->aen_log.count = 0;
++ }
++}
++
++static inline int qla4xxx_ioctl_init(struct scsi_qla_host *ha)
++{
++ ha->ql4mbx = qla4xxx_mailbox_command;
++ ha->ql4cmd = qla4xxx_send_command_to_isp;
++ ha->ql4getaenlog = ql4_get_aen_log;
++ return 0;
++}
++
++static inline void qla4xxx_ioctl_exit(struct scsi_qla_host *ha)
++{
++ return;
++}
++
++static inline void qla4xxx_srb_free_dma(struct scsi_qla_host *ha,
++ struct srb *srb)
++{
++ struct scsi_cmnd *cmd = srb->cmd;
++
++ if (srb->flags & SRB_DMA_VALID) {
++ scsi_dma_unmap(cmd);
++ srb->flags &= ~SRB_DMA_VALID;
++ }
++
++ cmd->SCp.ptr = NULL;
++}
++
++#endif /* _QLA4x_OS_H */
+--- a/drivers/scsi/qla4xxx/ql4_version.h
++++ b/drivers/scsi/qla4xxx/ql4_version.h
+@@ -5,6 +5,5 @@
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+-#define QLA4XXX_DRIVER_VERSION "5.01.00-k8_sles11-01"
+-
++#define QLA4XXX_DRIVER_VERSION "5.01.00-k8_sles11-03"
+