]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/qla4xxx-5.01.00-k8_sles11-03-update
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / qla4xxx-5.01.00-k8_sles11-03-update
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/qla4xxx-5.01.00-k8_sles11-03-update b/src/patches/suse-2.6.27.31/patches.drivers/qla4xxx-5.01.00-k8_sles11-03-update
new file mode 100644 (file)
index 0000000..847c377
--- /dev/null
@@ -0,0 +1,2360 @@
+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"