VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / scsi / qla2xxx / qla_init.c
index 661ca6c..e31b5fe 100644 (file)
  * General Public License for more details.
  *
  */
-#include "qla_os.h"
 #include "qla_def.h"
+
+#include <linux/delay.h>
+
 #include "qla_devtbl.h"
 
 /* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */
@@ -102,13 +104,13 @@ int
 qla2x00_initialize_adapter(scsi_qla_host_t *ha)
 {
        int     rval;
-       uint8_t isp_init = 0;
        uint8_t restart_risc = 0;
        uint8_t retry;
+       uint32_t wait_time;
 
        /* Clear adapter flags. */
-       ha->flags.online = FALSE;
-       ha->flags.reset_active = FALSE;
+       ha->flags.online = 0;
+       ha->flags.reset_active = 0;
        atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
        atomic_set(&ha->loop_state, LOOP_DOWN);
        ha->device_flags = 0;
@@ -133,14 +135,9 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
        /* Initialize target map database. */
        qla2x00_init_tgt_map(ha);
 
-       /* Get Flash Version */
-       qla2x00_get_flash_version(ha);
-
        qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
        qla2x00_nvram_config(ha);
 
-       ha->retry_count = ql2xretrycount;
-
        qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n");
 
 #if 0
@@ -161,7 +158,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
         */
        do {
                restart_risc = 0;
-               isp_init = 0;
 
                /* If firmware needs to be loaded */
                if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) {
@@ -180,21 +176,22 @@ check_fw_ready_again:
                         * value OR a minimum of 4 seconds OR If no 
                         * cable, only 5 seconds.
                         */
-                       if (!qla2x00_fw_ready(ha)) {
+                       rval = qla2x00_fw_ready(ha);
+                       if (rval == QLA_SUCCESS) {
                                clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
 
                                /*
-                                * Go setup flash database devices with proper
-                                * Loop ID's.
+                                * Wait at most MAX_TARGET RSCNs for a stable
+                                * link.
                                 */
+                               wait_time = 256;
                                do {
                                        clear_bit(LOOP_RESYNC_NEEDED,
                                            &ha->dpc_flags);
                                        rval = qla2x00_configure_loop(ha);
 
-                                       if (test_bit(ISP_ABORT_NEEDED,
+                                       if (test_and_clear_bit(ISP_ABORT_NEEDED,
                                            &ha->dpc_flags)) {
-
                                                restart_risc = 1;
                                                break;
                                        }
@@ -209,34 +206,29 @@ check_fw_ready_again:
                                            LOOP_DOWN && retry--) {
                                                goto check_fw_ready_again;
                                        }
+                                       wait_time--;
                                } while (!atomic_read(&ha->loop_down_timer) &&
                                    retry &&
-                                   (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)));
+                                   wait_time &&
+                                   (test_bit(LOOP_RESYNC_NEEDED,
+                                       &ha->dpc_flags)));
+
+                               if (wait_time == 0)
+                                       rval = QLA_FUNCTION_FAILED;
+                               if (ha->mem_err)
+                                       restart_risc = 1;
                        }
-
-                       if (ha->mem_err) {
-                               restart_risc = 1;
-                       }
-                       isp_init = 1;
-
                }
        } while (restart_risc && retry--);
 
-       if (isp_init) {
-               /* Retrieve firmware information */
-               qla2x00_get_fw_version(ha, &ha->fw_major_version,
-                   &ha->fw_minor_version, &ha->fw_subminor_version,
-                   &ha->fw_attributes);
-
+       if (rval == QLA_SUCCESS) {
                clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
                ha->marker_needed = 1;
                qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
                ha->marker_needed = 0;
 
-               ha->flags.online = TRUE;
-       }
-
-       if (rval) {
+               ha->flags.online = 1;
+       } else {
                DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__));
        }
 
@@ -290,7 +282,7 @@ qla2x00_pci_config(scsi_qla_host_t *ha)
                /* PCI Specification Revision 2.3 changes */
                if (IS_QLA2322(ha) || IS_QLA6322(ha))
                        /* Command Register - Reset Interrupt Disable. */
-                       w &= ~BIT_10;
+                       w &= ~PCI_COMMAND_INTX_DISABLE;
 
                /*
                 * If this is a 2300 card and not 2312, reset the
@@ -603,10 +595,11 @@ qla2x00_chip_diag(scsi_qla_host_t *ha)
        ha->product_id[3] = mb[4];
 
        /* Adjust fw RISC transfer size */
-       if (REQUEST_ENTRY_CNT > 1024)
+       if (ha->request_q_length > 1024)
                ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024;
        else
-               ha->fw_transfer_size = REQUEST_ENTRY_SIZE * REQUEST_ENTRY_CNT;
+               ha->fw_transfer_size = REQUEST_ENTRY_SIZE *
+                   ha->request_q_length;
 
        if (IS_QLA2200(ha) &&
            RD_MAILBOX_REG(ha, reg, 7) == QLA2200A_RISC_ROM_VER) {
@@ -734,6 +727,14 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
                            "firmware.\n", ha->host_no));
 
                        rval = qla2x00_execute_fw(ha);
+                       /* Retrieve firmware information. */
+                       if (rval == QLA_SUCCESS && ha->fw_major_version == 0) {
+                               qla2x00_get_fw_version(ha,
+                                   &ha->fw_major_version,
+                                   &ha->fw_minor_version,
+                                   &ha->fw_subminor_version,
+                                   &ha->fw_attributes, &ha->fw_memory_size);
+                       }
                }
                else {
                        DEBUG2(printk(KERN_INFO
@@ -773,6 +774,54 @@ qla2x00_init_response_q_entries(scsi_qla_host_t *ha)
 
 }
 
+/**
+ * qla2x00_update_fw_options() - Read and process firmware options.
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+static void
+qla2x00_update_fw_options(scsi_qla_host_t *ha)
+{
+       /* Setup seriallink options */
+       uint16_t swing, emphasis;
+
+       memset(ha->fw_options, 0, sizeof(ha->fw_options));
+       qla2x00_get_fw_options(ha, ha->fw_options);
+
+       if (IS_QLA2100(ha) || IS_QLA2200(ha))
+               return;
+
+       /* Serial Link options. */
+       DEBUG3(printk("scsi(%ld): Serial link options:\n",
+           ha->host_no));
+       DEBUG3(qla2x00_dump_buffer((uint8_t *)&ha->fw_seriallink_options,
+           sizeof(ha->fw_seriallink_options)));
+
+       ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
+       if (ha->fw_seriallink_options[1] & BIT_2)
+               ha->fw_options[1] |= FO1_SET_EMPHASIS_SWING;
+
+       /*  1G settings */
+       swing = ha->fw_seriallink_options[0] & (BIT_2 | BIT_1 | BIT_0);
+       emphasis = ha->fw_seriallink_options[0] & (BIT_4 | BIT_3);
+       emphasis >>= 3;
+       ha->fw_options[10] = (emphasis << 14) | (swing << 8) | 0x3;
+
+       /*  2G settings */
+       swing = ha->fw_seriallink_options[0] & (BIT_7 | BIT_6 | BIT_5);
+       swing >>= 5;
+       emphasis = ha->fw_seriallink_options[1] & (BIT_1 | BIT_0);
+       ha->fw_options[11] = (emphasis << 14) | (swing << 8) | 0x3;
+
+       /* FCP2 options. */
+       /*  Return command IOCBs without waiting for an ABTS to complete. */
+       ha->fw_options[3] |= BIT_13;
+
+       /* Update Serial Link options. */
+       qla2x00_set_fw_options(ha, ha->fw_options);
+}
+
 /**
  * qla2x00_init_rings() - Initializes firmware.
  * @ha: HA context
@@ -805,7 +854,7 @@ qla2x00_init_rings(scsi_qla_host_t *ha)
        /* Initialize firmware. */
        ha->request_ring_ptr  = ha->request_ring;
        ha->req_ring_index    = 0;
-       ha->req_q_cnt         = REQUEST_ENTRY_CNT;
+       ha->req_q_cnt         = ha->request_q_length;
        ha->response_ring_ptr = ha->response_ring;
        ha->rsp_ring_index    = 0;
 
@@ -826,35 +875,8 @@ qla2x00_init_rings(scsi_qla_host_t *ha)
                DEBUG2_3(printk("scsi(%ld): Init firmware **** FAILED ****.\n",
                    ha->host_no));
        } else {
-               /* Setup seriallink options */
-               uint16_t swing, emphasis;
-
-               DEBUG3(printk("scsi(%ld): Serial link options:\n",
-                   ha->host_no));
-               DEBUG3(qla2x00_dump_buffer(
-                   (uint8_t *)&ha->fw_seriallink_options,
-                   sizeof(ha->fw_seriallink_options)));
-
-               memset(ha->fw_options, 0, sizeof(ha->fw_options));
-               qla2x00_get_fw_options(ha, ha->fw_options);
-
-               ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
-               if (ha->fw_seriallink_options[1] & BIT_2)
-                       ha->fw_options[1] |= FO1_SET_EMPHASIS_SWING;
-
-               /* 1G settings */
-               swing = ha->fw_seriallink_options[0] & (BIT_2 | BIT_1 | BIT_0);
-               emphasis = ha->fw_seriallink_options[0] & (BIT_4 | BIT_3);
-               emphasis >>= 3;
-               ha->fw_options[10] = (emphasis << 14) | (swing << 8) | 0x3;
-
-               /* 2G settings */
-               swing = ha->fw_seriallink_options[0] & (BIT_7 | BIT_6 | BIT_5);
-               swing >>= 5;
-               emphasis = ha->fw_seriallink_options[1] & (BIT_1 | BIT_0);
-               ha->fw_options[11] = (emphasis << 14) | (swing << 8) | 0x3;
-
-               qla2x00_set_fw_options(ha, ha->fw_options);
+               /* Update any ISP specific firmware options. */
+               qla2x00_update_fw_options(ha);
 
                DEBUG3(printk("scsi(%ld): Init firmware -- success.\n",
                    ha->host_no));
@@ -924,7 +946,8 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
                        rval = QLA_FUNCTION_FAILED;
 
                        if (atomic_read(&ha->loop_down_timer) &&
-                           fw_state >= FSTATE_LOSS_OF_SYNC) {
+                           (fw_state >= FSTATE_LOSS_OF_SYNC ||
+                               fw_state == FSTATE_WAIT_AL_PA)) {
                                /* Loop down. Timeout on min_wait for states
                                 * other than Wait for Login. 
                                 */     
@@ -946,7 +969,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
                        break;
 
                /* Delay for a while */
-               set_current_state(TASK_INTERRUPTIBLE);
+               set_current_state(TASK_UNINTERRUPTIBLE);
                schedule_timeout(HZ / 2);
 
                DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",
@@ -1005,10 +1028,6 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
 
        ha->loop_id = loop_id;
 
-       /* Make sure 2100 only has loop, in case of any firmware bug. */
-       if (IS_QLA2100(ha))
-               topo = 0;
-
        /* initialize */
        ha->min_external_loopid = SNS_FIRST_LOOP_ID;
        ha->operating_mode = LOOP;
@@ -1097,7 +1116,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
        nvram_t *nv    = (nvram_t *)ha->request_ring;
        uint16_t  *wptr  = (uint16_t *)ha->request_ring;
        device_reg_t *reg = ha->iobase;
-       uint16_t  timer_mode;
+       uint8_t  timer_mode;
 
        rval = QLA_SUCCESS;
 
@@ -1151,7 +1170,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
                } else if (IS_QLA2200(ha)) {
                        nv->firmware_options[0] = BIT_2 | BIT_1;
                        nv->firmware_options[1] = BIT_7 | BIT_5;
-                       nv->add_firmware_options[0] = BIT_5 | BIT_4;
+                       nv->add_firmware_options[0] = BIT_5;
                        nv->add_firmware_options[1] = BIT_5 | BIT_4;
                        nv->frame_payload_size = __constant_cpu_to_le16(1024);
                } else if (IS_QLA2100(ha)) {
@@ -1249,6 +1268,16 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
                }
        } else if (IS_QLA2200(ha)) {
                nv->firmware_options[0] |= BIT_2;
+               /*
+                * 'Point-to-point preferred, else loop' is not a safe
+                * connection mode setting.
+                */
+               if ((nv->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) ==
+                   (BIT_5 | BIT_4)) {
+                       /* Force 'loop preferred, else point-to-point'. */
+                       nv->add_firmware_options[0] &= ~(BIT_6 | BIT_5 | BIT_4);
+                       nv->add_firmware_options[0] |= BIT_5;
+               }
                strcpy(ha->model_number, "QLA22xx");
        } else /*if (IS_QLA2100(ha))*/ {
                strcpy(ha->model_number, "QLA2100");
@@ -1381,7 +1410,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
         */
        icb->request_q_outpointer = __constant_cpu_to_le16(0);
        icb->response_q_inpointer = __constant_cpu_to_le16(0);
-       icb->request_q_length = __constant_cpu_to_le16(REQUEST_ENTRY_CNT);
+       icb->request_q_length = cpu_to_le16(ha->request_q_length);
        icb->response_q_length = cpu_to_le16(ha->response_q_length);
        icb->request_q_address[0] = cpu_to_le32(LSD(ha->request_dma));
        icb->request_q_address[1] = cpu_to_le32(MSD(ha->request_dma));
@@ -1404,23 +1433,22 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
 
                ha->flags.process_response_queue = 1;
        } else {
-               /* TEST ZIO:
-                *
-                * icb->add_firmware_options[0] &=
-                *    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
-                * icb->add_firmware_options[0] |= (BIT_2 | BIT_0);
-                */
+               /* Enable ZIO -- Support mode 5 only. */
                timer_mode = icb->add_firmware_options[0] &
                    (BIT_3 | BIT_2 | BIT_1 | BIT_0);
-               if (timer_mode == 5) {
+               icb->add_firmware_options[0] &=
+                   ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
+               if (ql2xenablezio)
+                       timer_mode = BIT_2 | BIT_0;
+               if (timer_mode == (BIT_2 | BIT_0)) {
                        DEBUG2(printk("scsi(%ld): ZIO enabled; timer delay "
                            "(%d).\n", ha->host_no, ql2xintrdelaytimer));
                        qla_printk(KERN_INFO, ha,
                            "ZIO enabled; timer delay (%d).\n",
                            ql2xintrdelaytimer);
 
+                       icb->add_firmware_options[0] |= timer_mode;
                        icb->interrupt_delay_timer = ql2xintrdelaytimer;
-       
                        ha->flags.process_response_queue = 1;
                }
        }
@@ -1496,24 +1524,24 @@ static int
 qla2x00_configure_loop(scsi_qla_host_t *ha) 
 {
        int  rval;
-       uint8_t  rval1 = 0;
        unsigned long flags, save_flags;
 
        rval = QLA_SUCCESS;
 
        /* Get Initiator ID */
-       if (qla2x00_configure_hba(ha)) {
-               DEBUG(printk("scsi(%ld): Unable to configure HBA.\n",
-                   ha->host_no));
-               return (QLA_FUNCTION_FAILED);
+       if (test_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags)) {
+               rval = qla2x00_configure_hba(ha);
+               if (rval != QLA_SUCCESS) {
+                       DEBUG(printk("scsi(%ld): Unable to configure HBA.\n",
+                           ha->host_no));
+                       return (rval);
+               }
        }
 
        save_flags = flags = ha->dpc_flags;
        DEBUG(printk("scsi(%ld): Configure loop -- dpc flags =0x%lx\n",
            ha->host_no, flags));
 
-       /* dg 02/26/02 ha->dpc_flags &= ~(LOCAL_LOOP_UPDATE | RSCN_UPDATE); */
-
        /*
         * If we have both an RSCN and PORT UPDATE pending then handle them
         * both at the same time.
@@ -1526,68 +1554,50 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
        if (ha->current_topology == ISP_CFG_FL &&
            (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
 
-               ha->flags.rscn_queue_overflow = TRUE;
+               ha->flags.rscn_queue_overflow = 1;
                set_bit(RSCN_UPDATE, &flags);
 
        } else if (ha->current_topology == ISP_CFG_F &&
            (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
 
-               ha->flags.rscn_queue_overflow = TRUE;
+               ha->flags.rscn_queue_overflow = 1;
                set_bit(RSCN_UPDATE, &flags);
                clear_bit(LOCAL_LOOP_UPDATE, &flags);
 
        } else if (!ha->flags.online ||
            (test_bit(ABORT_ISP_ACTIVE, &flags))) {
 
-               ha->flags.rscn_queue_overflow = TRUE;
+               ha->flags.rscn_queue_overflow = 1;
                set_bit(RSCN_UPDATE, &flags);
                set_bit(LOCAL_LOOP_UPDATE, &flags);
        }
 
-       do {
-               if (test_bit(LOCAL_LOOP_UPDATE, &flags)) {
-                       rval = rval | qla2x00_configure_local_loop(ha);
-               }
-
-               if (test_bit(RSCN_UPDATE, &flags)) {
-                       rval1 = qla2x00_configure_fabric(ha);
-                       if ((rval1 & BIT_0) && ha->sns_retry_cnt < 8) {
-                               ha->sns_retry_cnt++;
-                               set_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags);
-                       }
+       if (test_bit(LOCAL_LOOP_UPDATE, &flags)) {
+               if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
+                       rval = QLA_FUNCTION_FAILED;
+               } else {
+                       rval = qla2x00_configure_local_loop(ha);
                }
+       }
 
-               /* Isolate error status. */
-               if (rval & BIT_0) {
-                       rval = 1;
+       if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) {
+               if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
+                       rval = QLA_FUNCTION_FAILED;
                } else {
-                       rval = QLA_SUCCESS;
+                       rval = qla2x00_configure_fabric(ha);
                }
+       }
 
-       } while (rval != QLA_SUCCESS);
-
-       if (!atomic_read(&ha->loop_down_timer) &&
-           !(test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))) {
-
-               qla2x00_config_os(ha);
-
-               /* If we found all devices then go ready */
-               if (!(test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags))) {
+       if (rval == QLA_SUCCESS) {
+               if (atomic_read(&ha->loop_down_timer) ||
+                   test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
+                       rval = QLA_FUNCTION_FAILED;
+               } else {
+                       qla2x00_config_os(ha);
                        atomic_set(&ha->loop_state, LOOP_READY);
 
                        DEBUG(printk("scsi(%ld): LOOP READY\n", ha->host_no));
-               } else {
-                       if (test_bit(LOCAL_LOOP_UPDATE, &save_flags))
-                               set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
-                       if (test_bit(RSCN_UPDATE, &save_flags))
-                               set_bit(RSCN_UPDATE, &ha->dpc_flags);
                }
-       } else {
-               DEBUG(printk("scsi(%ld): Loop down counter running= %d or "
-                   "Resync needed- dpc flags= %ld\n",
-                   ha->host_no,
-                   atomic_read(&ha->loop_down_timer), ha->dpc_flags));
-               /* ???? dg 02/26/02  rval = 1; */
        }
 
        if (rval) {
@@ -1619,7 +1629,6 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
  *
  * Returns:
  *     0 = success.
- *     BIT_0 = error.
  */
 static int
 qla2x00_configure_local_loop(scsi_qla_host_t *ha) 
@@ -1644,19 +1653,9 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
        uint16_t        loop_id;
        uint8_t         domain, area, al_pa;
 
-       rval = QLA_SUCCESS;
        found_devs = 0;
        new_fcport = NULL;
 
-       /*
-        * No point in continuing if the loop is in a volatile state -- 
-        * reschedule LOCAL_LOOP_UPDATE for later processing
-        */
-       if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
-               set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
-               return (rval);
-       }
-
        entries = MAX_FIBRE_DEVICES;
        id_list = pci_alloc_consistent(ha->pdev, MAX_ID_LIST_SIZE,
            &id_list_dma);
@@ -1668,7 +1667,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
                    "Memory Allocation failed - port_list");
 
                ha->mem_err++;
-               return (BIT_0);
+               return (QLA_MEMORY_ALLOC_FAILED);
        }
        memset(id_list, 0, MAX_ID_LIST_SIZE);
 
@@ -1677,8 +1676,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
 
        /* Get list of logged in devices. */
        rval = qla2x00_get_id_list(ha, id_list, id_list_dma, &entries);
-       if (rval) {
-               rval = BIT_0;
+       if (rval != QLA_SUCCESS) {
                goto cleanup_allocation;
        }
 
@@ -1690,7 +1688,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
        /* Allocate temporary fcport for any new fcports discovered. */
        new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
        if (new_fcport == NULL) {
-               rval = BIT_0;
+               rval = QLA_MEMORY_ALLOC_FAILED;
                goto cleanup_allocation;
        }
        new_fcport->flags &= ~FCF_FABRIC_DEVICE;
@@ -1783,7 +1781,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
                        fcport = new_fcport;
                        new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
                        if (new_fcport == NULL) {
-                               rval = BIT_0;
+                               rval = QLA_MEMORY_ALLOC_FAILED;
                                goto cleanup_allocation;
                        }
                        new_fcport->flags &= ~FCF_FABRIC_DEVICE;
@@ -1800,7 +1798,7 @@ cleanup_allocation:
        if (new_fcport)
                kfree(new_fcport);
 
-       if (rval & BIT_0) {
+       if (rval != QLA_SUCCESS) {
                DEBUG2(printk("scsi(%ld): Configure local loop error exit: "
                    "rval=%x\n", ha->host_no, rval));
        }
@@ -2339,19 +2337,19 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
        /* Mark devices that need re-synchronization. */
        rval2 = qla2x00_device_resync(ha);
        if (rval2 == QLA_RSCNS_HANDLED) {
-               /* No, point doing the scan, just continue. */
+               /* No point doing the scan, just continue. */
                return (QLA_SUCCESS);
        }
        do {
                /* Ensure we are logged into the SNS. */
                qla2x00_login_fabric(ha, SIMPLE_NAME_SERVER, 0xff, 0xff, 0xfc,
-                   mb, BIT_0);
+                   mb, BIT_1 | BIT_0);
                if (mb[0] != MBS_COMMAND_COMPLETE) {
-                       qla_printk(KERN_INFO, ha,
+                       DEBUG2(qla_printk(KERN_INFO, ha,
                            "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x "
                            "mb[2]=%x mb[6]=%x mb[7]=%x\n", SIMPLE_NAME_SERVER,
-                           mb[0], mb[1], mb[2], mb[6], mb[7]);
-                       return (QLA_FUNCTION_FAILED);
+                           mb[0], mb[1], mb[2], mb[6], mb[7]));
+                       return (QLA_SUCCESS);
                }
 
                if (test_and_clear_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags)) {
@@ -2489,7 +2487,6 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
  *
  * Returns:
  *     0 = success.
- *     BIT_0 = error.
  *
  * Context:
  *     Kernel context.
@@ -2596,11 +2593,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0)
                        continue;
 
-               /* Bypass if same domain and area of adapter. */
-               if ((new_fcport->d_id.b24 & 0xffff00) ==
-                   (ha->d_id.b24 & 0xffff00))
-                       continue;
-
                /* Locate matching device in database. */
                found = 0;
                list_for_each_entry(fcport, &ha->fcports, list) {
@@ -2610,6 +2602,15 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
 
                        found++;
 
+                       /*
+                        * If address the same and state FCS_ONLINE, nothing
+                        * changed.
+                        */
+                       if (fcport->d_id.b24 == new_fcport->d_id.b24 &&
+                           atomic_read(&fcport->state) == FCS_ONLINE) {
+                               break;
+                       }
+
                        /*
                         * If device was not a fabric device before.
                         */
@@ -2622,15 +2623,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                                break;
                        }
 
-                       /*
-                        * If address the same and state FCS_ONLINE, nothing
-                        * changed.
-                        */
-                       if (fcport->d_id.b24 == new_fcport->d_id.b24 &&
-                           atomic_read(&fcport->state) == FCS_ONLINE) {
-                               break;
-                       }
-
                        /*
                         * Port ID changed or device was marked to be updated;
                         * Log it out if still logged in and mark it for
@@ -2900,7 +2892,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport,
 
        rval = qla2x00_fabric_login(ha, fcport, next_loopid);
        if (rval == QLA_SUCCESS) {
-               rval = qla2x00_get_port_database(ha, fcport, BIT_1 | BIT_0);
+               rval = qla2x00_get_port_database(ha, fcport, 0);
                if (rval != QLA_SUCCESS) {
                        qla2x00_fabric_logout(ha, fcport->loop_id);
                } else {
@@ -3082,6 +3074,7 @@ int
 qla2x00_loop_resync(scsi_qla_host_t *ha) 
 {
        int   rval;
+       uint32_t wait_time;
 
        rval = QLA_SUCCESS;
 
@@ -3090,6 +3083,8 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
        clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
        if (ha->flags.online) {
                if (!(rval = qla2x00_fw_ready(ha))) {
+                       /* Wait at most MAX_TARGET RSCNs for a stable link. */
+                       wait_time = 256;
                        do {
                                /* v2.19.05b6 */
                                atomic_set(&ha->loop_state, LOOP_UPDATE);
@@ -3104,12 +3099,13 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
                                clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 
                                qla2x00_configure_loop(ha);
-
+                               wait_time--;
                        } while (!atomic_read(&ha->loop_down_timer) &&
                                !(test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) &&
+                               wait_time &&
                                (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)));
                }
-               qla2x00_restart_queues(ha,TRUE);
+               qla2x00_restart_queues(ha, 1);
        }
 
        if (test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) {
@@ -3150,6 +3146,10 @@ qla2x00_restart_queues(scsi_qla_host_t *ha, uint8_t flush)
                spin_lock_irqsave(&ha->list_lock,flags);
                list_for_each_safe(list, temp, &ha->pending_queue) {
                        sp = list_entry(list, srb_t, list);
+
+                       if ((sp->flags & SRB_TAPE))
+                               continue;
+                        
                        /* 
                         * When time expire return request back to OS as BUSY 
                         */
@@ -3292,6 +3292,7 @@ qla2x00_config_os(scsi_qla_host_t *ha)
 static uint16_t
 qla2x00_fcport_bind(scsi_qla_host_t *ha, fc_port_t *fcport) 
 {
+       int             found;
        uint16_t        tgt;
        os_tgt_t        *tq;
 
@@ -3300,18 +3301,32 @@ qla2x00_fcport_bind(scsi_qla_host_t *ha, fc_port_t *fcport)
                if ((tq = TGT_Q(ha, tgt)) == NULL)
                        continue;
 
-               if (ha->binding_type == BIND_BY_PORT_ID &&
-                   fcport->d_id.b24 == tq->d_id.b24) {
-                       memcpy(tq->node_name, fcport->node_name, WWN_SIZE);
-                       memcpy(tq->port_name, fcport->port_name, WWN_SIZE);
+               found = 0;
+               switch (ha->binding_type) {
+               case BIND_BY_PORT_ID:
+                       if (fcport->d_id.b24 == tq->d_id.b24) {
+                               memcpy(tq->node_name, fcport->node_name,
+                                   WWN_SIZE);
+                               memcpy(tq->port_name, fcport->port_name,
+                                   WWN_SIZE);
+                               found++;
+                       }
                        break;
-               }
-
-               if (memcmp(fcport->port_name, tq->port_name, WWN_SIZE) == 0) {
-                       /* In case of persistent binding, update the WWNN */
-                       memcpy(tq->node_name, fcport->node_name, WWN_SIZE);
+               case BIND_BY_PORT_NAME:    
+                       if (memcmp(fcport->port_name, tq->port_name,
+                           WWN_SIZE) == 0) {
+                               /*
+                                * In case of persistent binding, update the
+                                * WWNN.
+                                */
+                               memcpy(tq->node_name, fcport->node_name,
+                                   WWN_SIZE);
+                               found++;
+                       }
                        break;
                }
+               if (found)
+                   break;      
        }
 
        /* TODO: honor the ConfigRequired flag */
@@ -4093,7 +4108,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
        uint8_t        status = 0;
 
        if (ha->flags.online) {
-               ha->flags.online = FALSE;
+               ha->flags.online = 0;
                clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
                qla2x00_stats.ispAbort++;
                ha->total_isp_aborts++;  /* used by ioctl */
@@ -4103,10 +4118,14 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                    "Performing ISP error recovery - ha= %p.\n", ha);
                qla2x00_reset_chip(ha);
 
+               atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
                        atomic_set(&ha->loop_state, LOOP_DOWN);
-                       atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
                        qla2x00_mark_all_devices_lost(ha);
+               } else {
+                       if (!atomic_read(&ha->loop_down_timer))
+                               atomic_set(&ha->loop_down_timer,
+                                   LOOP_DOWN_TIME);
                }
 
                spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -4118,23 +4137,27 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                                if (ha->actthreads)
                                        ha->actthreads--;
                                sp->lun_queue->out_cnt--;
-                               sp->flags = 0;
 
                                /*
                                 * Set the cmd host_byte status depending on
                                 * whether the scsi_error_handler is
                                 * active or not.
                                 */
-                               if (ha->host->eh_active != EH_ACTIVE) {
-                                       sp->cmd->result = DID_BUS_BUSY << 16;
+                               if (sp->flags & SRB_TAPE) {
+                                       sp->cmd->result = DID_NO_CONNECT << 16;
                                } else {
-                                       sp->cmd->result = DID_RESET << 16;
+                                       if (ha->host->eh_active != EH_ACTIVE)
+                                               sp->cmd->result =
+                                                   DID_BUS_BUSY << 16;
+                                       else
+                                               sp->cmd->result =
+                                                   DID_RESET << 16;
                                }
+                               sp->flags = 0;
                                sp->cmd->host_scribble = (unsigned char *)NULL;
                                add_to_done_queue(ha, sp);
                        }
                }
-
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
                qla2x00_nvram_config(ha);
@@ -4150,20 +4173,20 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                                ha->marker_needed = 1;
                        }
 
-                       ha->flags.online = TRUE;
+                       ha->flags.online = 1;
 
                        /* Enable ISP interrupts. */
                        qla2x00_enable_intrs(ha);
 
                        /* v2.19.5b6 Return all commands */
-                       qla2x00_abort_queues(ha, TRUE);
+                       qla2x00_abort_queues(ha, 1);
 
                        /* Restart queues that may have been stopped. */
-                       qla2x00_restart_queues(ha,TRUE);
+                       qla2x00_restart_queues(ha, 1);
                        ha->isp_abort_cnt = 0; 
                        clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
                } else {        /* failed the ISP abort */
-                       ha->flags.online = TRUE;
+                       ha->flags.online = 1;
                        if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) {
                                if (ha->isp_abort_cnt == 0) {
                                        qla_printk(KERN_WARNING, ha,
@@ -4174,8 +4197,8 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                                         * completely.
                                         */
                                        qla2x00_reset_adapter(ha);
-                                       qla2x00_abort_queues(ha, FALSE);
-                                       ha->flags.online = FALSE;
+                                       qla2x00_abort_queues(ha, 0);
+                                       ha->flags.online = 0;
                                        clear_bit(ISP_ABORT_RETRY,
                                            &ha->dpc_flags);
                                        status = 0;
@@ -4226,10 +4249,11 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
        uint8_t         status = 0;
        device_reg_t    *reg;
        unsigned long   flags = 0;
+       uint32_t wait_time;
 
        /* If firmware needs to be loaded */
        if (qla2x00_isp_firmware(ha)) {
-               ha->flags.online = FALSE;
+               ha->flags.online = 0;
                if (!(status = qla2x00_chip_diag(ha))) {
                        if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
                                status = qla2x00_setup_chip(ha);
@@ -4268,12 +4292,16 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
                                        "status = %d\n",
                                        __func__,
                                        status);)
-                       ha->flags.online = TRUE;
+                       ha->flags.online = 1;
+                       /* Wait at most MAX_TARGET RSCNs for a stable link. */
+                       wait_time = 256;
                        do {
                                clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
                                qla2x00_configure_loop(ha);
+                               wait_time--;
                        } while (!atomic_read(&ha->loop_down_timer) &&
                                !(test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) &&
+                               wait_time &&
                                (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)));
                }
 
@@ -4301,7 +4329,7 @@ qla2x00_reset_adapter(scsi_qla_host_t *ha)
        unsigned long flags = 0;
        device_reg_t *reg = ha->iobase;
 
-       ha->flags.online = FALSE;
+       ha->flags.online = 0;
        qla2x00_disable_intrs(ha);
        /* Reset RISC processor. */
        spin_lock_irqsave(&ha->hardware_lock, flags);