Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-block.git] / drivers / scsi / qla2xxx / qla_os.c
index 1fbd16c8c9a7b1db0e12334468dc177625e57871..42b8f0d3e580da932237826d07c2c36e49bfa7f3 100644 (file)
@@ -2816,6 +2816,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ha->link_data_rate = PORT_SPEED_UNKNOWN;
        ha->optrom_size = OPTROM_SIZE_2300;
        ha->max_exchg = FW_MAX_EXCHANGES_CNT;
+       atomic_set(&ha->num_pend_mbx_stage1, 0);
+       atomic_set(&ha->num_pend_mbx_stage2, 0);
+       atomic_set(&ha->num_pend_mbx_stage3, 0);
 
        /* Assign ISP specific operations. */
        if (IS_QLA2100(ha)) {
@@ -3046,7 +3049,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        host = base_vha->host;
        base_vha->req = req;
        if (IS_QLA2XXX_MIDTYPE(ha))
-               base_vha->mgmt_svr_loop_id = NPH_MGMT_SERVER;
+               base_vha->mgmt_svr_loop_id =
+                       qla2x00_reserve_mgmt_server_loop_id(base_vha);
        else
                base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER +
                                                base_vha->vp_idx;
@@ -3830,14 +3834,6 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
                return;
 
        set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
-
-       if (fcport->login_retry == 0) {
-               fcport->login_retry = vha->hw->login_retry_count;
-
-               ql_dbg(ql_dbg_disc, vha, 0x20a3,
-                   "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
-                   fcport->port_name, fcport->loop_id, fcport->login_retry);
-       }
 }
 
 /*
@@ -4785,7 +4781,6 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
        struct qlt_plogi_ack_t *pla =
            (struct qlt_plogi_ack_t *)e->u.new_sess.pla;
        uint8_t free_fcport = 0;
-       u64 wwn;
 
        ql_dbg(ql_dbg_disc, vha, 0xffff,
            "%s %d %8phC enter\n",
@@ -4813,10 +4808,10 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
                        fcport->d_id = e->u.new_sess.id;
                        fcport->flags |= FCF_FABRIC_DEVICE;
                        fcport->fw_login_state = DSC_LS_PLOGI_PEND;
-                       if (e->u.new_sess.fc4_type & FS_FC4TYPE_FCP)
+                       if (e->u.new_sess.fc4_type == FS_FC4TYPE_FCP)
                                fcport->fc4_type = FC4_TYPE_FCP_SCSI;
 
-                       if (e->u.new_sess.fc4_type & FS_FC4TYPE_NVME) {
+                       if (e->u.new_sess.fc4_type == FS_FC4TYPE_NVME) {
                                fcport->fc4_type = FC4_TYPE_OTHER;
                                fcport->fc4f_nvme = FC4_TYPE_NVME;
                        }
@@ -4858,9 +4853,6 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
        if (fcport) {
-               if (N2N_TOPO(vha->hw))
-                       fcport->flags &= ~FCF_FABRIC_DEVICE;
-
                fcport->id_changed = 1;
                fcport->scan_state = QLA_FCPORT_FOUND;
                memcpy(fcport->node_name, e->u.new_sess.node_name, WWN_SIZE);
@@ -4921,12 +4913,22 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
                        if (dfcp)
                                qlt_schedule_sess_for_deletion(tfcp);
 
-                       wwn = wwn_to_u64(fcport->node_name);
 
-                       if (!wwn)
-                               qla24xx_async_gnnid(vha, fcport);
-                       else
-                               qla24xx_async_gnl(vha, fcport);
+                       if (N2N_TOPO(vha->hw))
+                               fcport->flags &= ~FCF_FABRIC_DEVICE;
+
+                       if (N2N_TOPO(vha->hw)) {
+                               if (vha->flags.nvme_enabled) {
+                                       fcport->fc4f_nvme = 1;
+                                       fcport->n2n_flag = 1;
+                               }
+                               fcport->fw_login_state = 0;
+                               /*
+                                * wait link init done before sending login
+                                */
+                       } else {
+                               qla24xx_fcport_handle_login(vha, fcport);
+                       }
                }
        }
 
@@ -5061,6 +5063,10 @@ qla2x00_do_work(struct scsi_qla_host *vha)
                case QLA_EVT_IIDMA:
                        qla_do_iidma_work(vha, e->u.fcport.fcport);
                        break;
+               case QLA_EVT_ELS_PLOGI:
+                       qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI,
+                           e->u.fcport.fcport, false);
+                       break;
                }
                if (e->flags & QLA_EVT_FLAG_FREE)
                        kfree(e);
@@ -5090,7 +5096,7 @@ int qla24xx_post_relogin_work(struct scsi_qla_host *vha)
 void qla2x00_relogin(struct scsi_qla_host *vha)
 {
        fc_port_t       *fcport;
-       int status;
+       int status, relogin_needed = 0;
        struct event_arg ea;
 
        list_for_each_entry(fcport, &vha->vp_fcports, list) {
@@ -5099,47 +5105,59 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
                 * to it if we haven't run out of retries.
                 */
                if (atomic_read(&fcport->state) != FCS_ONLINE &&
-                   fcport->login_retry &&
-                   !(fcport->flags & (FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE))) {
-                       if (vha->hw->current_topology != ISP_CFG_NL) {
-                               ql_dbg(ql_dbg_disc, fcport->vha, 0x2108,
-                                   "%s %8phC DS %d LS %d\n", __func__,
-                                   fcport->port_name, fcport->disc_state,
-                                   fcport->fw_login_state);
-                               memset(&ea, 0, sizeof(ea));
-                               ea.event = FCME_RELOGIN;
-                               ea.fcport = fcport;
-                               qla2x00_fcport_event_handler(vha, &ea);
-                       } else if (vha->hw->current_topology == ISP_CFG_NL) {
-                               fcport->login_retry--;
-                               status = qla2x00_local_device_login(vha,
-                                                               fcport);
-                               if (status == QLA_SUCCESS) {
-                                       fcport->old_loop_id = fcport->loop_id;
-                                       ql_dbg(ql_dbg_disc, vha, 0x2003,
-                                           "Port login OK: logged in ID 0x%x.\n",
-                                           fcport->loop_id);
-                                       qla2x00_update_fcport(vha, fcport);
-                               } else if (status == 1) {
-                                       set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
-                                       /* retry the login again */
-                                       ql_dbg(ql_dbg_disc, vha, 0x2007,
-                                           "Retrying %d login again loop_id 0x%x.\n",
-                                           fcport->login_retry,
-                                           fcport->loop_id);
-                               } else {
-                                       fcport->login_retry = 0;
-                               }
+                   fcport->login_retry) {
+                       if (fcport->scan_state != QLA_FCPORT_FOUND ||
+                           fcport->disc_state == DSC_LOGIN_COMPLETE)
+                               continue;
+
+                       if (fcport->flags & (FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE) ||
+                               fcport->disc_state == DSC_DELETE_PEND) {
+                               relogin_needed = 1;
+                       } else {
+                               if (vha->hw->current_topology != ISP_CFG_NL) {
+                                       memset(&ea, 0, sizeof(ea));
+                                       ea.event = FCME_RELOGIN;
+                                       ea.fcport = fcport;
+                                       qla2x00_fcport_event_handler(vha, &ea);
+                               } else if (vha->hw->current_topology ==
+                                   ISP_CFG_NL) {
+                                       fcport->login_retry--;
+                                       status =
+                                           qla2x00_local_device_login(vha,
+                                               fcport);
+                                       if (status == QLA_SUCCESS) {
+                                               fcport->old_loop_id =
+                                                   fcport->loop_id;
+                                               ql_dbg(ql_dbg_disc, vha, 0x2003,
+                                                   "Port login OK: logged in ID 0x%x.\n",
+                                                   fcport->loop_id);
+                                               qla2x00_update_fcport
+                                                       (vha, fcport);
+                                       } else if (status == 1) {
+                                               set_bit(RELOGIN_NEEDED,
+                                                   &vha->dpc_flags);
+                                               /* retry the login again */
+                                               ql_dbg(ql_dbg_disc, vha, 0x2007,
+                                                   "Retrying %d login again loop_id 0x%x.\n",
+                                                   fcport->login_retry,
+                                                   fcport->loop_id);
+                                       } else {
+                                               fcport->login_retry = 0;
+                                       }
 
-                               if (fcport->login_retry == 0 &&
-                                   status != QLA_SUCCESS)
-                                       qla2x00_clear_loop_id(fcport);
+                                       if (fcport->login_retry == 0 &&
+                                           status != QLA_SUCCESS)
+                                               qla2x00_clear_loop_id(fcport);
+                               }
                        }
                }
                if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
                        break;
        }
 
+       if (relogin_needed)
+               set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+
        ql_dbg(ql_dbg_disc, vha, 0x400e,
            "Relogin end.\n");
 }
@@ -6179,6 +6197,11 @@ intr_on_check:
                if (!IS_QLAFX00(ha))
                        qla2x00_do_dpc_all_vps(base_vha);
 
+               if (test_and_clear_bit(N2N_LINK_RESET,
+                       &base_vha->dpc_flags)) {
+                       qla2x00_lip_reset(base_vha);
+               }
+
                ha->dpc_active = 0;
 end_loop:
                set_current_state(TASK_INTERRUPTIBLE);