Update to initiator driver from 2.6.27
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 20 Nov 2008 18:58:53 +0000 (18:58 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 20 Nov 2008 18:58:53 +0000 (18:58 +0000)
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@578 d57e44dd-8a1f-0410-8b47-8ef2f437770f

15 files changed:
qla2x00t/qla2x00-target/README
qla2x00t/qla2x00-target/qla2x00t.c
qla2x00t/qla_attr.c
qla2x00t/qla_dbg.c
qla2x00t/qla_def.h
qla2x00t/qla_gbl.h
qla2x00t/qla_gs.c
qla2x00t/qla_init.c
qla2x00t/qla_iocb.c
qla2x00t/qla_isr.c
qla2x00t/qla_mbx.c
qla2x00t/qla_mid.c
qla2x00t/qla_os.c
qla2x00t/qla_sup.c
qla2x00t/qla_version.h

index 42312c3..fbfe745 100644 (file)
@@ -13,15 +13,16 @@ all necessary callbacks, but it's still capable to work as initiator
 only. Mode, when a host acts as the initiator and the target
 simultaneously, is supported as well.
 
-This version is compatible with SCST core version 1.0.0 and higher and
-Linux kernel 2.6.26 and higher. Backport patches to kernels earlier than
-2.6.26 are welcome.
+This version is compatible with SCST core version 1.0.1 and higher and
+Linux kernel 2.6.27 and higher. Backport patches to kernels earlier than
+2.6.27 are welcome.
 
-The original initiator driver was taken from the kernel 2.6.26.
+The original initiator driver was taken from the kernel 2.6.27.
 
-If you need to use this driver on kernels prior 2.6.26, it is
+If you need to use this driver on kernels prior 2.6.27, it is
 recommended to use version 1.0.0.x of this driver, taken from branch
-1.0.0.x.
+1.0.0.x. For 2.6.26 you can also use version of this driver from SVN
+trunk/ revision 577.
 
 See also "ToDo" file for list of known issues and unimplemented 
 features.
index 3ef2d10..accfabc 100644 (file)
@@ -178,7 +178,7 @@ static void __q2t_send_notify_ack(scsi_qla_host_t *ha,
        /* Send marker if required */
        if (tgt_data.issue_marker(ha) != QLA_SUCCESS) {
                PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
-                           "failed", ha->instance);
+                           "failed", ha->host_no);
                goto out;
        }
 
@@ -310,7 +310,7 @@ static void q2t_unreg_sess(struct q2t_sess *sess)
        list_del(&sess->list);
 
        PRINT_INFO("qla2x00tgt(%ld): session for loop_id %d deleted",
-               sess->tgt->ha->instance, sess->loop_id);
+               sess->tgt->ha->host_no, sess->loop_id);
 
        /*
         * Any commands for this session will be finished regularly,
@@ -431,7 +431,7 @@ out:
 
 out_err:
        PRINT_ERROR("qla2x00tgt(%ld): PCI mapping failed: sg_cnt=%d",
-               prm->tgt->ha->instance, prm->sg_cnt);
+               prm->tgt->ha->host_no, prm->sg_cnt);
        res = -1;
        goto out;
 }
@@ -689,7 +689,7 @@ static int q2t_xmit_response(struct scst_cmd *scst_cmd)
 
                TRACE(TRACE_MGMT_MINOR, "qla2x00tgt(%ld): terminating exchange "
                        "for aborted scst_cmd=%p (tag=%lld)",
-                       ha->instance, scst_cmd, scst_cmd_get_tag(scst_cmd));
+                       ha->host_no, scst_cmd, scst_cmd_get_tag(scst_cmd));
 
                scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED);
 
@@ -721,7 +721,7 @@ static int q2t_xmit_response(struct scst_cmd *scst_cmd)
        if (!is_send_status) {
                /* ToDo, after it's done in SCST */
                PRINT_ERROR("qla2x00tgt(%ld): is_send_status not set: "
-                    "feature not implemented", prm.tgt->ha->instance);
+                    "feature not implemented", prm.tgt->ha->host_no);
                res = SCST_TGT_RES_FATAL_ERROR;
                goto out;
        }
@@ -732,12 +732,12 @@ static int q2t_xmit_response(struct scst_cmd *scst_cmd)
        /* Send marker if required */
        if (tgt_data.issue_marker(prm.tgt->ha) != QLA_SUCCESS) {
                PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
-                           "failed", prm.tgt->ha->instance);
+                           "failed", prm.tgt->ha->host_no);
                res = SCST_TGT_RES_FATAL_ERROR;
                goto out_unlock;
        }
 
-       TRACE_DBG("CTIO start: ha(%d)", (int) prm.tgt->ha->instance);
+       TRACE_DBG("CTIO start: ha(%d)", (int) prm.tgt->ha->host_no);
 
        if (q2t_has_data(scst_cmd)) {
                if (q2t_pci_map_calc_cnt(&prm) != 0) {
@@ -854,12 +854,12 @@ static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd)
        /* Send marker if required */
        if (tgt_data.issue_marker(prm.tgt->ha) != QLA_SUCCESS) {
                PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
-                           "failed", prm.tgt->ha->instance);
+                           "failed", prm.tgt->ha->host_no);
                res = SCST_TGT_RES_FATAL_ERROR;
                goto out_unlock;
        }
 
-       TRACE_DBG("CTIO_start: ha(%d)", (int) prm.tgt->ha->instance);
+       TRACE_DBG("CTIO_start: ha(%d)", (int) prm.tgt->ha->host_no);
 
        /* Calculate number of entries and segments required */
        if (q2t_pci_map_calc_cnt(&prm) != 0) {
@@ -906,14 +906,14 @@ static void q2t_send_term_exchange(scsi_qla_host_t *ha, struct q2t_cmd *cmd,
        /* Send marker if required */
        if (tgt_data.issue_marker(ha) != QLA_SUCCESS) {
                PRINT_ERROR("qla2x00tgt(%ld): __QLA2X00_MARKER() "
-                           "failed", ha->instance);
+                           "failed", ha->host_no);
                goto out_unlock;
        }
 
        ctio = (ctio_ret_entry_t *)tgt_data.req_pkt(ha);
        if (ctio == NULL) {
                PRINT_ERROR("qla2x00tgt(%ld): %s failed: unable to allocate "
-                       "request packet", ha->instance, __func__);
+                       "request packet", ha->host_no, __func__);
                goto out_unlock;
        }
 
@@ -1038,19 +1038,19 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                        TRACE(TRACE_MGMT_MINOR, "qla2x00tgt(%ld): CTIO with "
                                "status %#x received (LIP_RESET=e, ABORTED=2, "
                                "TARGET_RESET=17, TIMEOUT=b, "
-                               "INVALID_RX_ID=8)", ha->instance, status);
+                               "INVALID_RX_ID=8)", ha->host_no, status);
                        break;
 
                case CTIO_PORT_LOGGED_OUT:
                case CTIO_PORT_UNAVAILABLE:
                        PRINT_INFO("qla2x00tgt(%ld): CTIO with PORT LOGGED "
                                "OUT (29) or PORT UNAVAILABLE (28) status %x "
-                               "received", ha->instance, status);
+                               "received", ha->host_no, status);
                        break;
 
                default:
                        PRINT_ERROR("qla2x00tgt(%ld): CTIO with error status "
-                                   "0x%x received", ha->instance, status);
+                                   "0x%x received", ha->host_no, status);
                        break;
                }
                q2t_modify_command_count(ha, 1, 0);
@@ -1067,7 +1067,7 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                if (unlikely(scst_cmd == NULL)) {
                        PRINT_INFO("qla2x00tgt(%ld): Suspicious: unable to "
                                   "find the command with handle %x",
-                                  ha->instance, handle);
+                                  ha->host_no, handle);
                        goto out;
                }
                if (unlikely(err)) {
@@ -1082,7 +1082,7 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                        PRINT_INFO("qla2x00tgt(%ld): Suspicious: "
                                   "ctio_completion for non-existing session "
                                   "(loop_id %d, tag %d)",
-                                  ha->instance, loop_id, tag);
+                                  ha->host_no, loop_id, tag);
                        goto out;
                }
 
@@ -1090,7 +1090,7 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                if (scst_cmd == NULL) {
                        PRINT_INFO("qla2x00tgt(%ld): Suspicious: unable to "
                             "find the command with tag %d (loop_id %d)",
-                            ha->instance, tag, loop_id);
+                            ha->host_no, tag, loop_id);
                        goto out;
                }
                if (unlikely(err)) {
@@ -1139,7 +1139,7 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                goto out_free;
        } else {
                PRINT_ERROR("qla2x00tgt(%ld): A command in state (%d) should "
-                       "not return a CTIO complete", ha->instance, cmd->state);
+                       "not return a CTIO complete", ha->host_no, cmd->state);
                goto out_free;
        }
 
@@ -1225,7 +1225,7 @@ static int q2t_do_send_cmd_to_scst(scsi_qla_host_t *ha, struct q2t_cmd *cmd)
 
        if (cmd->scst_cmd == NULL) {
                PRINT_ERROR("qla2x00tgt(%ld): scst_rx_cmd() failed for "
-                    "host %ld(%p)", ha->instance, ha->host_no, ha);
+                    "host %ld(%p)", ha->host_no, ha->host_no, ha);
                res = -EFAULT;
                goto out;
        }
@@ -1258,7 +1258,7 @@ static int q2t_do_send_cmd_to_scst(scsi_qla_host_t *ha, struct q2t_cmd *cmd)
                break;
        default:
                PRINT_ERROR("qla2x00tgt(%ld): Unknown task code %x, use "
-                       "ORDERED instead", ha->instance, cmd->atio.task_codes);
+                       "ORDERED instead", ha->host_no, cmd->atio.task_codes);
                cmd->scst_cmd->queue_type = SCST_CMD_QUEUE_ORDERED;
                break;
        }
@@ -1291,7 +1291,7 @@ static void q2t_alloc_session_done(struct scst_session *scst_sess,
                unsigned long flags;
 
                PRINT_INFO("qla2x00tgt(%ld): Session initialization failed",
-                          ha->instance);
+                          ha->host_no);
 
                spin_lock_irqsave(&ha->hardware_lock, flags);
                q2t_unreg_sess(sess);
@@ -1330,7 +1330,7 @@ static char *q2t_find_name(scsi_qla_host_t *ha, int loop_id)
 
        if (wwn_found == 0) {
                TRACE_MGMT_DBG("qla2x00tgt(%ld): Unable to find wwn login for "
-                       "loop id %d", ha->instance, loop_id);
+                       "loop id %d", ha->host_no, loop_id);
                kfree(wwn_str);
                wwn_str = NULL;
        }
@@ -1372,8 +1372,8 @@ static int q2t_send_cmd_to_scst(scsi_qla_host_t *ha, atio_entry_t *atio)
        loop_id = GET_TARGET_ID(ha, atio);
 
        pn = (uint16_t *)(((char *)atio)+0x2a);
-       TRACE_DBG("To SCST instance=%ld l_id=%d tag=%d wwpn=%04x%04x%04x%04x",
-                 ha->instance, loop_id, le16_to_cpu(atio->exchange_id),
+       TRACE_DBG("To SCST host_no=%ld l_id=%d tag=%d wwpn=%04x%04x%04x%04x",
+                 ha->host_no, loop_id, le16_to_cpu(atio->exchange_id),
                  le16_to_cpu(pn[0]),
                  le16_to_cpu(pn[1]),
                  le16_to_cpu(pn[2]),
@@ -1442,7 +1442,7 @@ static int q2t_send_cmd_to_scst(scsi_qla_host_t *ha, atio_entry_t *atio)
 
                if (sess->scst_sess == NULL) {
                        PRINT_ERROR("qla2x00tgt(%ld): scst_register_session() failed "
-                            "for host %ld(%p)", ha->instance, ha->host_no, ha);
+                            "for host %ld(%p)", ha->host_no, ha->host_no, ha);
                        res = -EFAULT;
                        goto out_free_sess;
                }
@@ -1492,7 +1492,7 @@ static int q2t_handle_task_mgmt(scsi_qla_host_t *ha, notify_entry_t *iocb)
        sess = q2t_find_sess_by_lid(tgt, loop_id);
        if (sess == NULL) {
                TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task mgmt fn 0x%x for "
-                     "non-existant session", ha->instance, iocb->task_flags);
+                     "non-existant session", ha->host_no, iocb->task_flags);
                res = -EFAULT;
                goto out;
        }
@@ -1545,13 +1545,13 @@ static int q2t_handle_task_mgmt(scsi_qla_host_t *ha, notify_entry_t *iocb)
 
        default:
                PRINT_ERROR("qla2x00tgt(%ld): Unknown task mgmt fn 0x%x",
-                           ha->instance, iocb->task_flags);
+                           ha->host_no, iocb->task_flags);
                break;
        }
 
        if (rc != 0) {
                PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_lun() failed: %d",
-                           ha->instance, rc);
+                           ha->host_no, rc);
                res = -EFAULT;
                goto out_free;
        }
@@ -1582,7 +1582,7 @@ static int q2t_abort_task(scsi_qla_host_t *ha, notify_entry_t *iocb)
        sess = q2t_find_sess_by_lid(ha->tgt, loop_id);
        if (sess == NULL) {
                TRACE(TRACE_MGMT, "qla2x00tgt(%ld): task abort for unexisting "
-                       "session", ha->instance);
+                       "session", ha->host_no);
                res = -EFAULT;
                goto out;
        }
@@ -1601,7 +1601,7 @@ static int q2t_abort_task(scsi_qla_host_t *ha, notify_entry_t *iocb)
                SCST_ATOMIC, mcmd);
        if (rc != 0) {
                PRINT_ERROR("qla2x00tgt(%ld): scst_rx_mgmt_fn_tag() failed: %d",
-                           ha->instance, rc);
+                           ha->host_no, rc);
                res = -EFAULT;
                goto out_free;
        }
@@ -1684,7 +1684,7 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, notify_entry_t *iocb)
 
        case IMM_NTFY_IOCB_OVERFLOW:
                PRINT_ERROR("qla2x00tgt(%ld): Cannot provide requested "
-                       "capability (IOCB overflow)", ha->instance);
+                       "capability (IOCB overflow)", ha->host_no);
                break;
 
        case IMM_NTFY_ABORT_TASK:
@@ -1721,7 +1721,7 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, notify_entry_t *iocb)
 
        case IMM_NTFY_RESOURCE:
                PRINT_ERROR("qla2x00tgt(%ld): Out of resources, host %ld",
-                           ha->instance, ha->host_no);
+                           ha->host_no, ha->host_no);
                break;
 
        case IMM_NTFY_MSG_RX:
@@ -1732,7 +1732,7 @@ static void q2t_handle_imm_notify(scsi_qla_host_t *ha, notify_entry_t *iocb)
 
        default:
                PRINT_ERROR("qla2x00tgt(%ld): Received unknown immediate "
-                       "notify status %x", ha->instance, status);
+                       "notify status %x", ha->host_no, status);
                break;
        }
 
@@ -1765,7 +1765,7 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
 
        if (pkt->entry_status != 0) {
                PRINT_ERROR("qla2x00tgt(%ld): Received response packet %x "
-                    "with error status %x", ha->instance, pkt->entry_type,
+                    "with error status %x", ha->host_no, pkt->entry_type,
                     pkt->entry_status);
                goto out;
        }
@@ -1775,10 +1775,10 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
                if (ha->flags.enable_target_mode && ha->tgt != NULL) {
                        int rc;
                        atio = (atio_entry_t *)pkt;
-                       TRACE_DBG("ACCEPT_TGT_IO instance %ld status %04x "
+                       TRACE_DBG("ACCEPT_TGT_IO host_no %ld status %04x "
                                  "lun %04x read/write %d data_length %08x "
                                  "target_id %02x exchange_id %04x ",
-                                 ha->instance, le16_to_cpu(atio->status),
+                                 ha->host_no, le16_to_cpu(atio->status),
                                  le16_to_cpu(atio->lun),
                                  atio->execution_codes,
                                  le32_to_cpu(atio->data_length),
@@ -1787,7 +1787,7 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
                        if (atio->status !=
                                __constant_cpu_to_le16(ATIO_CDB_VALID)) {
                                PRINT_ERROR("qla2x00tgt(%ld): ATIO with error "
-                                           "status %x received", ha->instance,
+                                           "status %x received", ha->host_no,
                                            le16_to_cpu(atio->status));
                                break;
                        }
@@ -1806,41 +1806,41 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
                                                PRINT_INFO("qla2x00tgt(%ld): Unable to "
                                                    "send the command to SCSI target "
                                                    "mid-level, sending BUSY status",
-                                                   ha->instance);
+                                                   ha->host_no);
                                        }
                                        q2t_send_busy(ha, atio);
                                }
                        }
                } else if (!ha->tgt->tgt_shutdown) {
                        PRINT_ERROR("qla2x00tgt(%ld): ATIO, but target mode "
-                               "disabled", ha->instance);
+                               "disabled", ha->host_no);
                }
                break;
 
        case CONTINUE_TGT_IO_TYPE:
                if (ha->flags.enable_target_mode && ha->tgt != NULL) {
                        ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
-                       TRACE_DBG("CONTINUE_TGT_IO: instance %ld",
-                                 ha->instance);
+                       TRACE_DBG("CONTINUE_TGT_IO: host_no %ld",
+                                 ha->host_no);
                        q2t_do_ctio_completion(ha, entry->handle,
                                               le16_to_cpu(entry->status),
                                               entry);
                } else if (!ha->tgt->tgt_shutdown) {
                        PRINT_ERROR("qla2x00tgt(%ld): CTIO, but target mode "
-                               "disabled", ha->instance);
+                               "disabled", ha->host_no);
                }
                break;
 
        case CTIO_A64_TYPE:
                if (ha->flags.enable_target_mode && ha->tgt != NULL) {
                        ctio_common_entry_t *entry = (ctio_common_entry_t *)pkt;
-                       TRACE_DBG("CTIO_A64: instance %ld", ha->instance);
+                       TRACE_DBG("CTIO_A64: host_no %ld", ha->host_no);
                        q2t_do_ctio_completion(ha, entry->handle,
                                               le16_to_cpu(entry->status),
                                               entry);
                } else if (!ha->tgt->tgt_shutdown) {
                        PRINT_ERROR("qla2x00tgt(%ld): CTIO_A64, but target "
-                               "mode disabled", ha->instance);
+                               "mode disabled", ha->host_no);
                }
                break;
 
@@ -1852,7 +1852,7 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
        case NOTIFY_ACK_TYPE:
                if (ha->tgt == NULL) {
                        PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK recieved "
-                               "with NULL tgt", ha->instance);
+                               "with NULL tgt", ha->host_no);
                } else if (ha->tgt->notify_ack_expected > 0) {
                        nack_entry_t *entry = (nack_entry_t *)pkt;
                        TRACE_DBG("NOTIFY_ACK seq %04x status %x",
@@ -1862,12 +1862,12 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
                        if (entry->status !=
                                __constant_cpu_to_le16(NOTIFY_ACK_SUCCESS)) {
                                PRINT_ERROR("qla2x00tgt(%ld): NOTIFY_ACK "
-                                           "failed %x", ha->instance,
+                                           "failed %x", ha->host_no,
                                            le16_to_cpu(entry->status));
                        }
                } else {
                        PRINT_ERROR("qla2x00tgt(%ld): Unexpected NOTIFY_ACK "
-                                   "received", ha->instance);
+                                   "received", ha->host_no);
                }
                break;
 
@@ -1888,13 +1888,13 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
                        tgt->modify_lun_expected--;
                        if (entry->status != MODIFY_LUN_SUCCESS) {
                                PRINT_ERROR("qla2x00tgt(%ld): MODIFY_LUN "
-                                           "failed %x", ha->instance,
+                                           "failed %x", ha->host_no,
                                            entry->status);
                        }
                        tgt->disable_lun_status = entry->status;
                } else {
                        PRINT_ERROR("qla2x00tgt(%ld): Unexpected MODIFY_LUN "
-                                   "received", (ha != NULL) ?ha->instance :-1);
+                               "received", (ha != NULL) ? ha->host_no : -1);
                }
                break;
 
@@ -1917,7 +1917,7 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
                        } else if (entry->status != ENABLE_LUN_SUCCESS) {
                                PRINT_ERROR("qla2x00tgt(%ld): ENABLE_LUN "
                                            "failed %x",
-                                           ha->instance, entry->status);
+                                           ha->host_no, entry->status);
                                ha->flags.enable_target_mode =
                                        ~ha->flags.enable_target_mode;
                        } /* else success */
@@ -1927,7 +1927,7 @@ static void q2t_response_pkt(scsi_qla_host_t *ha, sts_entry_t *pkt)
 
        default:
                PRINT_INFO("qla2x00tgt(%ld): Received unknown response pkt "
-                    "type %x", ha->instance, pkt->entry_type);
+                    "type %x", ha->host_no, pkt->entry_type);
                break;
        }
 
@@ -2051,7 +2051,7 @@ static void q2t_host_action(scsi_qla_host_t *ha,
 
                if (ha->flags.enable_64bit_addressing) {
                        PRINT_INFO("qla2x00tgt(%ld): 64 Bit PCI "
-                                  "Addressing Enabled", ha->instance);
+                                  "Addressing Enabled", ha->host_no);
                        tgt->tgt_enable_64bit_addr = 1;
                        /* 3 is reserved */
                        sg_tablesize =
@@ -2060,7 +2060,7 @@ static void q2t_host_action(scsi_qla_host_t *ha,
                        tgt->datasegs_per_cont = DATASEGS_PER_CONT64;
                } else {
                        PRINT_INFO("qla2x00tgt(%ld): Using 32 Bit "
-                                  "PCI Addressing", ha->instance);
+                                  "PCI Addressing", ha->host_no);
                        sg_tablesize =
                                QLA_MAX_SG32(ha->request_q_length - 3);
                        tgt->datasegs_per_cmd = DATASEGS_PER_COMMAND32;
@@ -2076,7 +2076,7 @@ static void q2t_host_action(scsi_qla_host_t *ha,
                kfree(wwn);
                if (!tgt->scst_tgt) {
                        PRINT_ERROR("qla2x00tgt(%ld): scst_register() "
-                                   "failed for host %ld(%p)", ha->instance,
+                                   "failed for host %ld(%p)", ha->host_no,
                                    ha->host_no, ha);
                        kfree(tgt);
                        goto out;
@@ -2090,7 +2090,7 @@ static void q2t_host_action(scsi_qla_host_t *ha,
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
                TRACE_DBG("Enable lun for host %ld(%ld,%p)",
-                         ha->host_no, ha->instance, ha);
+                         ha->host_no, ha->host_no, ha);
                tgt_data.enable_lun(ha);
 
                break;
@@ -2113,7 +2113,7 @@ static void q2t_host_action(scsi_qla_host_t *ha,
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
                TRACE_DBG("Shutting down host %ld(%ld,%p)",
-                         ha->host_no, ha->instance, ha);
+                         ha->host_no, ha->host_no, ha);
                scst_unregister(tgt->scst_tgt);
                /*
                 * Free of tgt happens via callback q2t_target_release
index 4e47a6a..0d98794 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kthread.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
+#include <linux/delay.h>
 #include <linux/version.h>
 
 #ifdef CONFIG_SCSI_QLA2XXX_TARGET
@@ -325,7 +326,6 @@ qla2x00_update_portdb(struct device *dev, struct device_attribute *attr,
        return size;
 }
 
-
 static DEVICE_ATTR(port_database,
                         S_IRUGO|S_IWUSR,
                         qla2x00_show_port_database,
@@ -340,18 +340,12 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj,
 {
        struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
            struct device, kobj)));
-       char *rbuf = (char *)ha->fw_dump;
 
        if (ha->fw_dump_reading == 0)
                return 0;
-       if (off > ha->fw_dump_len)
-                return 0;
-       if (off + count > ha->fw_dump_len)
-               count = ha->fw_dump_len - off;
-
-       memcpy(buf, &rbuf[off], count);
 
-       return (count);
+       return memory_read_from_buffer(buf, count, &off, ha->fw_dump,
+                                       ha->fw_dump_len);
 }
 
 static ssize_t
@@ -414,20 +408,13 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
 {
        struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
            struct device, kobj)));
-       int             size = ha->nvram_size;
-       char            *nvram_cache = ha->nvram;
 
-       if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
+       if (!capable(CAP_SYS_ADMIN))
                return 0;
-       if (off + count > size) {
-               size -= off;
-               count = size;
-       }
 
        /* Read NVRAM data from cache. */
-       memcpy(buf, &nvram_cache[off], count);
-
-       return count;
+       return memory_read_from_buffer(buf, count, &off, ha->nvram,
+                                       ha->nvram_size);
 }
 
 static ssize_t
@@ -495,14 +482,9 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj,
 
        if (ha->optrom_state != QLA_SREADING)
                return 0;
-       if (off > ha->optrom_region_size)
-               return 0;
-       if (off + count > ha->optrom_region_size)
-               count = ha->optrom_region_size - off;
 
-       memcpy(buf, &ha->optrom_buffer[off], count);
-
-       return count;
+       return memory_read_from_buffer(buf, count, &off, ha->optrom_buffer,
+                                       ha->optrom_region_size);
 }
 
 static ssize_t
@@ -694,20 +676,12 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
 {
        struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
            struct device, kobj)));
-       int           size = ha->vpd_size;
-       char          *vpd_cache = ha->vpd;
 
-       if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
+       if (!capable(CAP_SYS_ADMIN))
                return 0;
-       if (off + count > size) {
-               size -= off;
-               count = size;
-       }
 
        /* Read NVRAM data from cache. */
-       memcpy(buf, &vpd_cache[off], count);
-
-       return count;
+       return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
 }
 
 static ssize_t
@@ -877,8 +851,10 @@ qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr,
        scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
        uint32_t sn;
 
-       if (IS_FWI2_CAPABLE(ha))
-               return snprintf(buf, PAGE_SIZE, "\n");
+       if (IS_FWI2_CAPABLE(ha)) {
+               qla2xxx_get_vpd_field(ha, "SN", buf, PAGE_SIZE);
+               return snprintf(buf, PAGE_SIZE, "%s\n", buf);
+       }
 
        sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1;
        return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000,
@@ -1129,6 +1105,16 @@ qla2x00_optrom_fw_version_show(struct device *dev,
            ha->fw_revision[3]);
 }
 
+static ssize_t
+qla2x00_total_isp_aborts_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
+
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+           ha->qla_stats.total_isp_aborts);
+}
+
 static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
 static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
 static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
@@ -1151,6 +1137,8 @@ static DEVICE_ATTR(optrom_fcode_version, S_IRUGO,
                   qla2x00_optrom_fcode_version_show, NULL);
 static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show,
                   NULL);
+static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
+                  NULL);
 
 struct device_attribute *qla2x00_host_attrs[] = {
        &dev_attr_driver_version,
@@ -1169,10 +1157,11 @@ struct device_attribute *qla2x00_host_attrs[] = {
        &dev_attr_optrom_efi_version,
        &dev_attr_optrom_fcode_version,
        &dev_attr_optrom_fw_version,
+       &dev_attr_total_isp_aborts,
 #ifdef CONFIG_SCSI_QLA2XXX_TARGET
-       &dev_attr_target_mode_enabled,
-       &dev_attr_resource_counts,
-       &dev_attr_port_database,
+       &dev_attr_target_mode_enabled,
+       &dev_attr_resource_counts,
+       &dev_attr_port_database,
 #endif
        NULL,
 };
@@ -1297,26 +1286,50 @@ qla2x00_get_starget_port_id(struct scsi_target *starget)
 }
 
 static void
-qla2x00_get_rport_loss_tmo(struct fc_rport *rport)
+qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
 {
-       struct Scsi_Host *host = rport_to_shost(rport);
-       scsi_qla_host_t *ha = shost_priv(host);
-
-       rport->dev_loss_tmo = ha->port_down_retry_count + 5;
+       if (timeout)
+               rport->dev_loss_tmo = timeout;
+       else
+               rport->dev_loss_tmo = 1;
 }
 
 static void
-qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
+qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
 {
        struct Scsi_Host *host = rport_to_shost(rport);
-       scsi_qla_host_t *ha = shost_priv(host);
+       fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+
+       qla2x00_abort_fcport_cmds(fcport);
+
+       /*
+        * Transport has effectively 'deleted' the rport, clear
+        * all local references.
+        */
+       spin_lock_irq(host->host_lock);
+       fcport->rport = NULL;
+       *((fc_port_t **)rport->dd_data) = NULL;
+       spin_unlock_irq(host->host_lock);
+}
 
-       if (timeout)
-               ha->port_down_retry_count = timeout;
-       else
-               ha->port_down_retry_count = 1;
+static void
+qla2x00_terminate_rport_io(struct fc_rport *rport)
+{
+       fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+
+       /*
+        * At this point all fcport's software-states are cleared.  Perform any
+        * final cleanup of firmware resources (PCBs and XCBs).
+        */
+       if (fcport->loop_id != FC_NO_LOOP_ID) {
+               fcport->ha->isp_ops->fabric_logout(fcport->ha, fcport->loop_id,
+                   fcport->d_id.b.domain, fcport->d_id.b.area,
+                   fcport->d_id.b.al_pa);
+               fcport->loop_id = FC_NO_LOOP_ID;
+       }
 
-       rport->dev_loss_tmo = ha->port_down_retry_count + 5;
+       qla2x00_abort_fcport_cmds(fcport);
+       scsi_target_unblock(&rport->dev);
 }
 
 static int
@@ -1370,6 +1383,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
        pfc_host_stat->invalid_tx_word_count = stats->inval_xmit_word_cnt;
        pfc_host_stat->invalid_crc_count = stats->inval_crc_cnt;
        if (IS_FWI2_CAPABLE(ha)) {
+               pfc_host_stat->lip_count = stats->lip_cnt;
                pfc_host_stat->tx_frames = stats->tx_frames;
                pfc_host_stat->rx_frames = stats->rx_frames;
                pfc_host_stat->dumped_frames = stats->dumped_frames;
@@ -1498,17 +1512,16 @@ vport_create_failed_2:
 static int
 qla24xx_vport_delete(struct fc_vport *fc_vport)
 {
-       scsi_qla_host_t *ha = shost_priv(fc_vport->shost);
        scsi_qla_host_t *vha = fc_vport->dd_data;
+       scsi_qla_host_t *pha = to_qla_parent(vha);
+
+       while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
+           test_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags))
+               msleep(1000);
 
        qla24xx_disable_vp(vha);
        qla24xx_deallocate_vp_id(vha);
 
-       mutex_lock(&ha->vport_lock);
-       ha->cur_vport_count--;
-       clear_bit(vha->vp_idx, ha->vp_idx_map);
-       mutex_unlock(&ha->vport_lock);
-
        kfree(vha->node_name);
        kfree(vha->port_name);
 
@@ -1573,11 +1586,12 @@ struct fc_function_template qla2xxx_transport_functions = {
        .get_starget_port_id  = qla2x00_get_starget_port_id,
        .show_starget_port_id = 1,
 
-       .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
        .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
        .show_rport_dev_loss_tmo = 1,
 
        .issue_fc_host_lip = qla2x00_issue_lip,
+       .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
+       .terminate_rport_io = qla2x00_terminate_rport_io,
        .get_fc_host_stats = qla2x00_get_fc_host_stats,
 
        .vport_create = qla24xx_vport_create,
@@ -1616,11 +1630,12 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
        .get_starget_port_id  = qla2x00_get_starget_port_id,
        .show_starget_port_id = 1,
 
-       .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
        .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
        .show_rport_dev_loss_tmo = 1,
 
        .issue_fc_host_lip = qla2x00_issue_lip,
+       .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
+       .terminate_rport_io = qla2x00_terminate_rport_io,
        .get_fc_host_stats = qla2x00_get_fc_host_stats,
 };
 
index cbef785..510ba64 100644 (file)
@@ -216,7 +216,7 @@ qla24xx_soft_reset(scsi_qla_host_t *ha)
 
 static int
 qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram,
-    uint16_t ram_words, void **nxt)
+    uint32_t ram_words, void **nxt)
 {
        int rval;
        uint32_t cnt, stat, timer, words, idx;
index 6c34987..8eadc48 100644 (file)
@@ -864,7 +864,8 @@ struct link_statistics {
        uint32_t prim_seq_err_cnt;
        uint32_t inval_xmit_word_cnt;
        uint32_t inval_crc_cnt;
-       uint32_t unused1[0x1b];
+       uint32_t lip_cnt;
+       uint32_t unused1[0x1a];
        uint32_t tx_frames;
        uint32_t rx_frames;
        uint32_t dumped_frames;
@@ -1544,7 +1545,6 @@ typedef struct fc_port {
        int login_retry;
        atomic_t port_down_timer;
 
-       spinlock_t rport_lock;
        struct fc_rport *rport, *drport;
        u32 supported_classes;
 
@@ -2155,6 +2155,10 @@ struct qla_chip_state_84xx {
        uint32_t gold_fw_version;
 };
 
+struct qla_statistics {
+       uint32_t total_isp_aborts;
+};
+
 /*
  * Linux Host Adapter structure
  */
@@ -2166,7 +2170,6 @@ typedef struct scsi_qla_host {
        struct pci_dev  *pdev;
 
        unsigned long   host_no;
-       unsigned long   instance;
 
        volatile struct {
                uint32_t        init_done               :1;
@@ -2238,6 +2241,7 @@ typedef struct scsi_qla_host {
 #define REGISTER_FDMI_NEEDED   26
 #define FCPORT_UPDATE_NEEDED   27
 #define VP_DPC_NEEDED          28      /* wake up for VP dpc handling */
+#define UNLOADING              29
 
        uint32_t        device_flags;
 #define DFLG_LOCAL_DEVICES             BIT_0
@@ -2527,7 +2531,7 @@ typedef struct scsi_qla_host {
 
        uint8_t         model_number[16+1];
 #define BINZERO                "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-       char            *model_desc;
+       char            model_desc[80];
        uint8_t         adapter_id[16+1];
 
        uint8_t         *node_name;
@@ -2614,6 +2618,7 @@ typedef struct scsi_qla_host {
        int             cur_vport_count;
 
        struct qla_chip_state_84xx *cs84xx;
+       struct qla_statistics qla_stats;
 } scsi_qla_host_t;
 
 /* Wait type for qla2x00_eh_wait_for_pending_commands() */
index 1dbb7fa..f2fb203 100644 (file)
@@ -66,7 +66,7 @@ extern int ql2xfdmienable;
 extern int ql2xallocfwdump;
 extern int ql2xextended_error_logging;
 extern int ql2xqfullrampup;
-extern int num_hosts;
+extern int ql2xiidmaenable;
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -75,6 +75,8 @@ extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
 extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
     uint16_t, uint16_t);
 
+extern void qla2x00_abort_fcport_cmds(fc_port_t *);
+
 /*
  * Global Functions in qla_mid.c source file.
  */
@@ -320,6 +322,7 @@ extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
     uint16_t, uint16_t);
 
 extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
+extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
 
 /*
  * Global Function Prototypes in qla_dbg.c source file.
index 6f78368..853f1d3 100644 (file)
@@ -1670,6 +1670,12 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha)
 {
        int rval;
 
+       if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
+               DEBUG2(printk("scsi(%ld): FDMI unsupported on "
+                   "ISP2100/ISP2200.\n", ha->host_no));
+               return QLA_SUCCESS;
+       }
+
        rval = qla2x00_mgmt_svr_login(ha);
        if (rval)
                return rval;
index 0a41873..b1a6693 100644 (file)
@@ -344,6 +344,8 @@ static int
 qla2x00_isp_firmware(scsi_qla_host_t *ha)
 {
        int  rval;
+       uint16_t loop_id, topo, sw_cap;
+       uint8_t domain, area, al_pa;
 
        /* Assume loading risc code */
        rval = QLA_FUNCTION_FAILED;
@@ -355,6 +357,11 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha)
 
                /* Verify checksum of loaded RISC code. */
                rval = qla2x00_verify_checksum(ha, ha->fw_srisc_address);
+               if (rval == QLA_SUCCESS) {
+                       /* And, verify we are not in ROM code. */
+                       rval = qla2x00_get_adapter_id(ha, &loop_id, &al_pa,
+                           &area, &domain, &topo, &sw_cap);
+               }
        }
 
        if (rval) {
@@ -749,7 +756,7 @@ qla24xx_chip_diag(scsi_qla_host_t *ha)
        /* Perform RISC reset. */
        qla24xx_reset_risc(ha);
 
-       ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024;
+       ha->fw_transfer_size = REQUEST_ENTRY_SIZE * ha->request_q_length;
 
        rval = qla2x00_mbx_reg_test(ha);
        if (rval) {
@@ -795,42 +802,16 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha)
                mem_size = (ha->fw_memory_size - 0x100000 + 1) *
                    sizeof(uint32_t);
 
-               /* Allocate memory for Extended Trace Buffer. */
-               tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
-                   GFP_KERNEL);
-               if (!tc) {
-                       qla_printk(KERN_WARNING, ha, "Unable to allocate "
-                           "(%d KB) for EFT.\n", EFT_SIZE / 1024);
-                       goto cont_alloc;
-               }
-
-               memset(tc, 0, EFT_SIZE);
-               rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS);
-               if (rval) {
-                       qla_printk(KERN_WARNING, ha, "Unable to initialize "
-                           "EFT (%d).\n", rval);
-                       dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc,
-                           tc_dma);
-                       goto cont_alloc;
-               }
-
-               qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n",
-                   EFT_SIZE / 1024);
-
-               eft_size = EFT_SIZE;
-               ha->eft_dma = tc_dma;
-               ha->eft = tc;
-
                /* Allocate memory for Fibre Channel Event Buffer. */
                if (!IS_QLA25XX(ha))
-                       goto cont_alloc;
+                       goto try_eft;
 
                tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
                    GFP_KERNEL);
                if (!tc) {
                        qla_printk(KERN_WARNING, ha, "Unable to allocate "
                            "(%d KB) for FCE.\n", FCE_SIZE / 1024);
-                       goto cont_alloc;
+                       goto try_eft;
                }
 
                memset(tc, 0, FCE_SIZE);
@@ -842,7 +823,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha)
                        dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc,
                            tc_dma);
                        ha->flags.fce_enabled = 0;
-                       goto cont_alloc;
+                       goto try_eft;
                }
 
                qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n",
@@ -852,6 +833,32 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha)
                ha->flags.fce_enabled = 1;
                ha->fce_dma = tc_dma;
                ha->fce = tc;
+try_eft:
+               /* Allocate memory for Extended Trace Buffer. */
+               tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
+                   GFP_KERNEL);
+               if (!tc) {
+                       qla_printk(KERN_WARNING, ha, "Unable to allocate "
+                           "(%d KB) for EFT.\n", EFT_SIZE / 1024);
+                       goto cont_alloc;
+               }
+
+               memset(tc, 0, EFT_SIZE);
+               rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS);
+               if (rval) {
+                       qla_printk(KERN_WARNING, ha, "Unable to initialize "
+                           "EFT (%d).\n", rval);
+                       dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc,
+                           tc_dma);
+                       goto cont_alloc;
+               }
+
+               qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n",
+                   EFT_SIZE / 1024);
+
+               eft_size = EFT_SIZE;
+               ha->eft_dma = tc_dma;
+               ha->eft = tc;
        }
 cont_alloc:
        req_q_size = ha->request_q_length * sizeof(request_t);
@@ -996,8 +1003,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
                                    &ha->fw_attributes, &ha->fw_memory_size);
                                qla2x00_resize_request_q(ha);
                                ha->flags.npiv_supported = 0;
-                               if ((IS_QLA24XX(ha) || IS_QLA25XX(ha)) &&
-                                   (ha->fw_attributes & BIT_2)) {
+                               if ((IS_QLA24XX(ha) || IS_QLA25XX(ha) ||
+                                    IS_QLA84XX(ha)) &&
+                                        (ha->fw_attributes & BIT_2)) {
                                        ha->flags.npiv_supported = 1;
                                        if ((!ha->max_npiv_vports) ||
                                            ((ha->max_npiv_vports + 1) %
@@ -1528,18 +1536,25 @@ qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *de
                index = (ha->pdev->subsystem_device & 0xff);
                if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
                    index < QLA_MODEL_NAMES)
-                       ha->model_desc = qla2x00_model_name[index * 2 + 1];
+                       strncpy(ha->model_desc,
+                           qla2x00_model_name[index * 2 + 1],
+                           sizeof(ha->model_desc) - 1);
        } else {
                index = (ha->pdev->subsystem_device & 0xff);
                if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
                    index < QLA_MODEL_NAMES) {
                        strcpy(ha->model_number,
                            qla2x00_model_name[index * 2]);
-                       ha->model_desc = qla2x00_model_name[index * 2 + 1];
+                       strncpy(ha->model_desc,
+                           qla2x00_model_name[index * 2 + 1],
+                           sizeof(ha->model_desc) - 1);
                } else {
                        strcpy(ha->model_number, def);
                }
        }
+       if (IS_FWI2_CAPABLE(ha))
+               qla2xxx_get_vpd_field(ha, "\x82", ha->model_desc,
+                   sizeof(ha->model_desc));
 }
 
 /* On sparc systems, obtain port and node WWN from firmware
@@ -1897,12 +1912,11 @@ qla2x00_rport_del(void *data)
 {
        fc_port_t *fcport = data;
        struct fc_rport *rport;
-       unsigned long flags;
 
-       spin_lock_irqsave(&fcport->rport_lock, flags);
+       spin_lock_irq(fcport->ha->host->host_lock);
        rport = fcport->drport;
        fcport->drport = NULL;
-       spin_unlock_irqrestore(&fcport->rport_lock, flags);
+       spin_unlock_irq(fcport->ha->host->host_lock);
        if (rport)
                fc_remote_port_delete(rport);
 }
@@ -1931,7 +1945,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
        atomic_set(&fcport->state, FCS_UNCONFIGURED);
        fcport->flags = FCF_RLC_SUPPORT;
        fcport->supported_classes = FC_COS_UNSPECIFIED;
-       spin_lock_init(&fcport->rport_lock);
 
        return fcport;
 }
@@ -2040,8 +2053,10 @@ qla2x00_configure_loop(scsi_qla_host_t *ha)
        if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
                if (test_bit(LOCAL_LOOP_UPDATE, &save_flags))
                        set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
-               if (test_bit(RSCN_UPDATE, &save_flags))
+               if (test_bit(RSCN_UPDATE, &save_flags)) {
+                       ha->flags.rscn_queue_overflow = 1;
                        set_bit(RSCN_UPDATE, &ha->dpc_flags);
+               }
        }
 
        return (rval);
@@ -2276,28 +2291,24 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
 {
        struct fc_rport_identifiers rport_ids;
        struct fc_rport *rport;
-       unsigned long flags;
 
        if (fcport->drport)
                qla2x00_rport_del(fcport);
-       if (fcport->rport)
-               return;
 
        rport_ids.node_name = wwn_to_u64(fcport->node_name);
        rport_ids.port_name = wwn_to_u64(fcport->port_name);
        rport_ids.port_id = fcport->d_id.b.domain << 16 |
            fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
        rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
-       rport = fc_remote_port_add(ha->host, 0, &rport_ids);
+       fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids);
        if (!rport) {
                qla_printk(KERN_WARNING, ha,
                    "Unable to allocate fc remote port!\n");
                return;
        }
-       spin_lock_irqsave(&fcport->rport_lock, flags);
-       fcport->rport = rport;
+       spin_lock_irq(fcport->ha->host->host_lock);
        *((fc_port_t **)rport->dd_data) = fcport;
-       spin_unlock_irqrestore(&fcport->rport_lock, flags);
+       spin_unlock_irq(fcport->ha->host->host_lock);
 
        rport->supported_classes = fcport->supported_classes;
 
@@ -2601,7 +2612,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) {
                        kfree(swl);
                        swl = NULL;
-               } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) {
+               } else if (ql2xiidmaenable &&
+                   qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) {
                        qla2x00_gpsc(ha, swl);
                }
        }
@@ -3256,7 +3268,8 @@ qla2x00_update_fcports(scsi_qla_host_t *ha)
 
        /* Go with deferred removal of rport references. */
        list_for_each_entry_rcu(fcport, &ha->fcports, list)
-               if (fcport->drport)
+               if (fcport->drport &&
+                   atomic_read(&fcport->state) != FCS_UNCONFIGURED)
                        qla2x00_rport_del(fcport);
 }
 
@@ -3275,10 +3288,12 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 {
        int rval;
        uint8_t        status = 0;
+       scsi_qla_host_t *vha;
 
        if (ha->flags.online) {
                ha->flags.online = 0;
                clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+               ha->qla_stats.total_isp_aborts++;
 
                qla_printk(KERN_INFO, ha,
                    "Performing ISP error recovery - ha= %p.\n", ha);
@@ -3288,6 +3303,8 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
                        atomic_set(&ha->loop_state, LOOP_DOWN);
                        qla2x00_mark_all_devices_lost(ha, 0);
+                       list_for_each_entry(vha, &ha->vp_list, vp_list)
+                              qla2x00_mark_all_devices_lost(vha, 0);
                } else {
                        if (!atomic_read(&ha->loop_down_timer))
                                atomic_set(&ha->loop_down_timer,
@@ -3325,17 +3342,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                        ha->isp_abort_cnt = 0;
                        clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
 
-                       if (ha->eft) {
-                               memset(ha->eft, 0, EFT_SIZE);
-                               rval = qla2x00_enable_eft_trace(ha,
-                                   ha->eft_dma, EFT_NUM_BUFFERS);
-                               if (rval) {
-                                       qla_printk(KERN_WARNING, ha,
-                                           "Unable to reinitialize EFT "
-                                           "(%d).\n", rval);
-                               }
-                       }
-
                        if (ha->fce) {
                                ha->flags.fce_enabled = 1;
                                memset(ha->fce, 0,
@@ -3350,6 +3356,17 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                                        ha->flags.fce_enabled = 0;
                                }
                        }
+
+                       if (ha->eft) {
+                               memset(ha->eft, 0, EFT_SIZE);
+                               rval = qla2x00_enable_eft_trace(ha,
+                                   ha->eft_dma, EFT_NUM_BUFFERS);
+                               if (rval) {
+                                       qla_printk(KERN_WARNING, ha,
+                                           "Unable to reinitialize EFT "
+                                           "(%d).\n", rval);
+                               }
+                       }
                } else {        /* failed the ISP abort */
                        ha->flags.online = 1;
                        if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) {
@@ -4068,8 +4085,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha)
        ret = qla2x00_stop_firmware(ha);
        for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT &&
            retries ; retries--) {
-               qla2x00_reset_chip(ha);
-               if (qla2x00_chip_diag(ha) != QLA_SUCCESS)
+               ha->isp_ops->reset_chip(ha);
+               if (ha->isp_ops->chip_diag(ha) != QLA_SUCCESS)
                        continue;
                if (qla2x00_setup_chip(ha) != QLA_SUCCESS)
                        continue;
@@ -4091,7 +4108,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha)
        rval = qla2x00_fw_ready(ha->parent);
        if (rval == QLA_SUCCESS) {
                clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
-               qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL);
+               qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
        }
 
        ha->flags.management_server_logged_in = 0;
index 3b4a8ef..2609b26 100644 (file)
@@ -453,10 +453,11 @@ qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
 {
        int ret;
        unsigned long flags = 0;
+       scsi_qla_host_t *pha = to_qla_parent(ha);
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&pha->hardware_lock, flags);
        ret = __qla2x00_marker(ha, loop_id, lun, type);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&pha->hardware_lock, flags);
 
        return (ret);
 }
@@ -671,7 +672,7 @@ qla24xx_start_scsi(srb_t *sp)
 {
        int             ret, nseg;
        unsigned long   flags;
-       scsi_qla_host_t *ha;
+       scsi_qla_host_t *ha, *pha;
        struct scsi_cmnd *cmd;
        uint32_t        *clr_ptr;
        uint32_t        index;
@@ -685,6 +686,7 @@ qla24xx_start_scsi(srb_t *sp)
        /* Setup device pointers. */
        ret = 0;
        ha = sp->ha;
+       pha = to_qla_parent(ha);
        reg = &ha->iobase->isp24;
        cmd = sp->cmd;
        /* So we know we haven't pci_map'ed anything yet */
@@ -699,7 +701,7 @@ qla24xx_start_scsi(srb_t *sp)
        }
 
        /* Acquire ring specific lock */
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&pha->hardware_lock, flags);
 
        /* Check for room in outstanding command list. */
        handle = ha->current_outstanding_cmd;
@@ -794,14 +796,14 @@ qla24xx_start_scsi(srb_t *sp)
            ha->response_ring_ptr->signature != RESPONSE_PROCESSED)
                qla24xx_process_response_queue(ha);
 
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&pha->hardware_lock, flags);
        return QLA_SUCCESS;
 
 queuing_error:
        if (tot_dsds)
                scsi_dma_unmap(cmd);
 
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&pha->hardware_lock, flags);
 
        return QLA_FUNCTION_FAILED;
 }
index a116fd7..9856a70 100644 (file)
@@ -609,10 +609,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                break;
 
        case MBA_PORT_UPDATE:           /* Port database update */
-               /* Only handle SCNs for our Vport index. */
-               if (ha->parent && ha->vp_idx != (mb[3] & 0xff))
-                       break;
-
                /*
                 * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
                 * event etc. earlier indicating loop is down) then process
@@ -988,11 +984,12 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
        sp->request_sense_ptr += sense_len;
        sp->request_sense_length -= sense_len;
        if (sp->request_sense_length != 0)
-               sp->ha->status_srb = sp;
+               sp->fcport->ha->status_srb = sp;
 
        DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) "
-           "cmd=%p pid=%ld\n", __func__, sp->ha->host_no, cp->device->channel,
-           cp->device->id, cp->device->lun, cp, cp->serial_number));
+           "cmd=%p pid=%ld\n", __func__, sp->fcport->ha->host_no,
+           cp->device->channel, cp->device->id, cp->device->lun, cp,
+           cp->serial_number));
        if (sense_len)
                DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
                    CMD_ACTUAL_SNSLEN(cp)));
@@ -1311,9 +1308,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                    atomic_read(&fcport->state)));
 
                cp->result = DID_BUS_BUSY << 16;
-               if (atomic_read(&fcport->state) == FCS_ONLINE) {
-                       qla2x00_mark_device_lost(ha, fcport, 1, 1);
-               }
+               if (atomic_read(&fcport->state) == FCS_ONLINE)
+                       qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
                break;
 
        case CS_RESET:
@@ -1356,7 +1352,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
 
                /* Check to see if logout occurred. */
                if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
-                       qla2x00_mark_device_lost(ha, fcport, 1, 1);
+                       qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
                break;
 
        default:
@@ -1961,7 +1957,6 @@ clear_risc_ints:
                WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
        }
        spin_unlock_irq(&ha->hardware_lock);
-       ha->isp_ops->enable_intrs(ha);
 
 fail:
        return ret;
index 0d2aa33..7b96e77 100644 (file)
@@ -918,6 +918,8 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
        rval = qla2x00_mailbox_command(ha, mcp);
        if (mcp->mb[0] == MBS_COMMAND_ERROR)
                rval = QLA_COMMAND_ERROR;
+       else if (mcp->mb[0] == MBS_INVALID_COMMAND)
+               rval = QLA_INVALID_COMMAND;
 
        /* Return data. */
        *id = mcp->mb[1];
@@ -2165,17 +2167,18 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
        struct abort_entry_24xx *abt;
        dma_addr_t      abt_dma;
        uint32_t        handle;
+       scsi_qla_host_t *pha = to_qla_parent(ha);
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
 
        fcport = sp->fcport;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
+       spin_lock_irqsave(&pha->hardware_lock, flags);
        for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
-               if (ha->outstanding_cmds[handle] == sp)
+               if (pha->outstanding_cmds[handle] == sp)
                        break;
        }
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       spin_unlock_irqrestore(&pha->hardware_lock, flags);
        if (handle == MAX_OUTSTANDING_COMMANDS) {
                /* Command not found. */
                return QLA_FUNCTION_FAILED;
index 0fd28ac..893fc51 100644 (file)
@@ -6,7 +6,6 @@
  */
 #include "qla_def.h"
 
-#include <linux/version.h>
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
@@ -43,6 +42,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
 
        set_bit(vp_id, ha->vp_idx_map);
        ha->num_vhosts++;
+       ha->cur_vport_count++;
        vha->vp_idx = vp_id;
        list_add_tail(&vha->vp_list, &ha->vp_list);
        mutex_unlock(&ha->vport_lock);
@@ -58,6 +58,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
        mutex_lock(&ha->vport_lock);
        vp_id = vha->vp_idx;
        ha->num_vhosts--;
+       ha->cur_vport_count--;
        clear_bit(vp_id, ha->vp_idx_map);
        list_del(&vha->vp_list);
        mutex_unlock(&ha->vport_lock);
@@ -103,8 +104,8 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha)
                    "loop_id=0x%04x :%x\n",
                    vha->host_no, fcport->loop_id, fcport->vp_idx));
 
-               atomic_set(&fcport->state, FCS_DEVICE_DEAD);
                qla2x00_mark_device_lost(vha, fcport, 0, 0);
+               atomic_set(&fcport->state, FCS_UNCONFIGURED);
        }
 }
 
@@ -276,7 +277,8 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
                clear_bit(RESET_ACTIVE, &vha->dpc_flags);
        }
 
-       if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
+       if (atomic_read(&vha->vp_state) == VP_ACTIVE &&
+           test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
                if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) {
                        qla2x00_loop_resync(vha);
                        clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags);
@@ -390,7 +392,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
        vha->parent = ha;
        vha->fc_vport = fc_vport;
        vha->device_flags = 0;
-       vha->instance = num_hosts;
        vha->vp_idx = qla24xx_allocate_vp_id(vha);
        if (vha->vp_idx > ha->max_npiv_vports) {
                DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n",
@@ -428,7 +429,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
        host->max_cmd_len = MAX_CMDSZ;
        host->max_channel = MAX_BUSES - 1;
        host->max_lun = MAX_LUNS;
-       host->unique_id = vha->instance;
+       host->unique_id = host->host_no;
        host->max_id = MAX_TARGETS_2200;
        host->transportt = qla2xxx_transport_vport_template;
 
@@ -436,12 +437,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
            vha->host_no, vha));
 
        vha->flags.init_done = 1;
-       num_hosts++;
-
-       mutex_lock(&ha->vport_lock);
-       set_bit(vha->vp_idx, ha->vp_idx_map);
-       ha->cur_vport_count++;
-       mutex_unlock(&ha->vport_lock);
 
        return vha;
 
index 732aaa9..31091f1 100644 (file)
@@ -31,7 +31,6 @@ char qla2x00_version_str[40];
  */
 static struct kmem_cache *srb_cachep;
 
-int num_hosts;
 int ql2xlogintimeout = 20;
 module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
 MODULE_PARM_DESC(ql2xlogintimeout,
@@ -91,6 +90,13 @@ MODULE_PARM_DESC(ql2xqfullrampup,
                "depth for a device after a queue-full condition has been "
                "detected.  Default is 120 seconds.");
 
+int ql2xiidmaenable=1;
+module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xiidmaenable,
+               "Enables iIDMA settings "
+               "Default is 1 - perform iIDMA. 0 - no iIDMA.");
+
+
 /*
  * SCSI host template entry points
  */
@@ -392,7 +398,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        }
 
        /* Close window on fcport/rport state-transitioning. */
-       if (!*(fc_port_t **)rport->dd_data) {
+       if (fcport->drport) {
                cmd->result = DID_IMM_RETRY << 16;
                goto qc_fail_command;
        }
@@ -447,7 +453,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        int rval;
        scsi_qla_host_t *pha = to_qla_parent(ha);
 
-       if (unlikely(pci_channel_offline(ha->pdev))) {
+       if (unlikely(pci_channel_offline(pha->pdev))) {
                cmd->result = DID_REQUEUE << 16;
                goto qc24_fail_command;
        }
@@ -459,7 +465,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        }
 
        /* Close window on fcport/rport state-transitioning. */
-       if (!*(fc_port_t **)rport->dd_data) {
+       if (fcport->drport) {
                cmd->result = DID_IMM_RETRY << 16;
                goto qc24_fail_command;
        }
@@ -621,6 +627,40 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
        return (return_status);
 }
 
+void
+qla2x00_abort_fcport_cmds(fc_port_t *fcport)
+{
+       int cnt;
+       unsigned long flags;
+       srb_t *sp;
+       scsi_qla_host_t *ha = fcport->ha;
+       scsi_qla_host_t *pha = to_qla_parent(ha);
+
+       spin_lock_irqsave(&pha->hardware_lock, flags);
+       for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
+               sp = pha->outstanding_cmds[cnt];
+               if (!sp)
+                       continue;
+               if (sp->fcport != fcport)
+                       continue;
+
+               spin_unlock_irqrestore(&pha->hardware_lock, flags);
+               if (ha->isp_ops->abort_command(ha, sp)) {
+                       DEBUG2(qla_printk(KERN_WARNING, ha,
+                           "Abort failed --  %lx\n", sp->cmd->serial_number));
+               } else {
+                       if (qla2x00_eh_wait_on_command(ha, sp->cmd) !=
+                           QLA_SUCCESS)
+                               DEBUG2(qla_printk(KERN_WARNING, ha,
+                                   "Abort failed while waiting --  %lx\n",
+                                   sp->cmd->serial_number));
+
+               }
+               spin_lock_irqsave(&pha->hardware_lock, flags);
+       }
+       spin_unlock_irqrestore(&pha->hardware_lock, flags);
+}
+
 static void
 qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
 {
@@ -738,7 +778,8 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t,
                sp = pha->outstanding_cmds[cnt];
                if (!sp)
                        continue;
-               if (ha->vp_idx != sp->ha->vp_idx)
+
+               if (ha->vp_idx != sp->fcport->ha->vp_idx)
                        continue;
                match = 0;
                switch (type) {
@@ -1038,9 +1079,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res)
                sp = ha->outstanding_cmds[cnt];
                if (sp) {
                        ha->outstanding_cmds[cnt] = NULL;
-                       sp->flags = 0;
                        sp->cmd->result = res;
-                       sp->cmd->host_scribble = (unsigned char *)NULL;
                        qla2x00_sp_compl(ha, sp);
                }
        }
@@ -1071,7 +1110,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
        else
                scsi_deactivate_tcq(sdev, ha->max_q_depth);
 
-       rport->dev_loss_tmo = ha->port_down_retry_count + 5;
+       rport->dev_loss_tmo = ha->port_down_retry_count;
 
        return 0;
 }
@@ -1627,9 +1666,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        }
        host->can_queue = ha->request_q_length + 128;
 
-       /* load the F/W, read paramaters, and init the H/W */
-       ha->instance = num_hosts;
-
        spin_lock_init(&ha->dpc_lock);
 
        mutex_init(&ha->vport_lock);
@@ -1679,7 +1715,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        host->this_id = 255;
        host->cmd_per_lun = 3;
-       host->unique_id = ha->instance;
+       host->unique_id = host->host_no;
        host->max_cmd_len = MAX_CMDSZ;
        host->max_channel = MAX_BUSES - 1;
        host->max_lun = MAX_LUNS;
@@ -1700,12 +1736,12 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ha->flags.init_done = 1;
        ha->flags.online = 1;
 
-       num_hosts++;
-
        ret = scsi_add_host(host, &pdev->dev);
        if (ret)
                goto probe_failed;
 
+       ha->isp_ops->enable_intrs(ha);
+
        scsi_scan_host(host);
 
        qla2x00_alloc_sysfs_attr(ha);
@@ -1741,10 +1777,15 @@ probe_out:
 static void
 qla2x00_remove_one(struct pci_dev *pdev)
 {
-       scsi_qla_host_t *ha;
+       scsi_qla_host_t *ha, *vha, *temp;
 
        ha = pci_get_drvdata(pdev);
 
+       list_for_each_entry_safe(vha, temp, &ha->vp_list, vp_list)
+               fc_vport_terminate(vha->fc_vport);
+
+       set_bit(UNLOADING, &ha->dpc_flags);
+
 #if defined(CONFIG_SCSI_QLA2XXX_TARGET)
        ha->flags.host_shutting_down = 1;
        if (qla_target.tgt_host_action != NULL)
@@ -1830,27 +1871,22 @@ static inline void
 qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
     int defer)
 {
-       unsigned long flags;
        struct fc_rport *rport;
+       scsi_qla_host_t *pha = to_qla_parent(ha);
 
        if (!fcport->rport)
                return;
 
        rport = fcport->rport;
        if (defer) {
-               spin_lock_irqsave(&fcport->rport_lock, flags);
+               unsigned long flags;
+               spin_lock_irqsave(ha->host->host_lock, flags);
                fcport->drport = rport;
-               fcport->rport = NULL;
-               *(fc_port_t **)rport->dd_data = NULL;
-               spin_unlock_irqrestore(&fcport->rport_lock, flags);
-               set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
-       } else {
-               spin_lock_irqsave(&fcport->rport_lock, flags);
-               fcport->rport = NULL;
-               *(fc_port_t **)rport->dd_data = NULL;
-               spin_unlock_irqrestore(&fcport->rport_lock, flags);
+               spin_unlock_irqrestore(ha->host->host_lock, flags);
+               set_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags);
+               qla2xxx_wake_dpc(pha);
+       } else
                fc_remote_port_delete(rport);
-       }
 }
 
 /*
@@ -1920,7 +1956,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
        scsi_qla_host_t *pha = to_qla_parent(ha);
 
        list_for_each_entry_rcu(fcport, &pha->fcports, list) {
-               if (ha->vp_idx != 0 && ha->vp_idx != fcport->vp_idx)
+               if (ha->vp_idx != fcport->vp_idx)
                        continue;
                /*
                 * No point in marking the device as lost, if the device is
@@ -1928,17 +1964,10 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
                 */
                if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
                        continue;
-               if (atomic_read(&fcport->state) == FCS_ONLINE) {
-                       if (defer)
-                               qla2x00_schedule_rport_del(ha, fcport, defer);
-                       else if (ha->vp_idx == fcport->vp_idx)
-                               qla2x00_schedule_rport_del(ha, fcport, defer);
-               }
+               if (atomic_read(&fcport->state) == FCS_ONLINE)
+                       qla2x00_schedule_rport_del(ha, fcport, defer);
                atomic_set(&fcport->state, FCS_DEVICE_LOST);
        }
-
-       if (defer)
-               qla2xxx_wake_dpc(ha);
 }
 
 /*
@@ -2173,7 +2202,7 @@ qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type,
 static int
 qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked)
 {
-       unsigned long flags;
+       unsigned long uninitialized_var(flags);
        scsi_qla_host_t *pha = to_qla_parent(ha);
 
        if (!locked)
@@ -2330,8 +2359,10 @@ qla2x00_do_dpc(void *data)
                            ha->host_no));
                }
 
-               if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
+               if (test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) {
                        qla2x00_update_fcports(ha);
+                       clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
+               }
 
                if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
                    (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
@@ -2444,10 +2475,13 @@ qla2x00_do_dpc(void *data)
 void
 qla2xxx_wake_dpc(scsi_qla_host_t *ha)
 {
+       struct task_struct *t;
        unsigned long flags;
+
        spin_lock_irqsave(&ha->dpc_lock, flags);
-       if (ha->dpc_thread)
-               wake_up_process(ha->dpc_thread);
+       t = ha->dpc_thread;
+       if (!test_bit(UNLOADING, &ha->dpc_flags) && t)
+               wake_up_process(t);
        spin_unlock_irqrestore(&ha->dpc_lock, flags);
 }
 
index 1728ab3..1bca744 100644 (file)
@@ -869,11 +869,9 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
        uint32_t i;
        uint32_t *dwptr;
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-       unsigned long flags;
 
        ret = QLA_SUCCESS;
 
-       spin_lock_irqsave(&ha->hardware_lock, flags);
        /* Enable flash write. */
        WRT_REG_DWORD(&reg->ctrl_status,
            RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
@@ -907,7 +905,6 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
        WRT_REG_DWORD(&reg->ctrl_status,
            RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
        RD_REG_DWORD(&reg->ctrl_status);        /* PCI Posting. */
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        return ret;
 }
@@ -2305,6 +2302,51 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
        return ret;
 }
 
+static int
+qla2xxx_is_vpd_valid(uint8_t *pos, uint8_t *end)
+{
+       if (pos >= end || *pos != 0x82)
+               return 0;
+
+       pos += 3 + pos[1];
+       if (pos >= end || *pos != 0x90)
+               return 0;
+
+       pos += 3 + pos[1];
+       if (pos >= end || *pos != 0x78)
+               return 0;
+
+       return 1;
+}
+
+int
+qla2xxx_get_vpd_field(scsi_qla_host_t *ha, char *key, char *str, size_t size)
+{
+       uint8_t *pos = ha->vpd;
+       uint8_t *end = pos + ha->vpd_size;
+       int len = 0;
+
+       if (!IS_FWI2_CAPABLE(ha) || !qla2xxx_is_vpd_valid(pos, end))
+               return 0;
+
+       while (pos < end && *pos != 0x78) {
+               len = (*pos == 0x82) ? pos[1] : pos[2];
+
+               if (!strncmp(pos, key, strlen(key)))
+                       break;
+
+               if (*pos != 0x90 && *pos != 0x91)
+                       pos += len;
+
+               pos += 3;
+       }
+
+       if (pos < end - len && *pos != 0x78)
+               return snprintf(str, size, "%.*s", len, pos + 3);
+
+       return 0;
+}
+
 static int
 qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata)
 {
index d058c88..4160e4c 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.02.01-k4"
+#define QLA2XXX_VERSION      "8.02.01-k7"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   2