Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-2.6-microblaze.git] / drivers / scsi / qla2xxx / qla_init.c
index 908a72e..070b636 100644 (file)
@@ -330,12 +330,9 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
                lio->u.logio.flags |= SRB_LOGIN_PRLI_ONLY;
        } else {
                if (vha->hw->flags.edif_enabled &&
-                   vha->e_dbell.db_flags & EDB_ACTIVE) {
+                   DBELL_ACTIVE(vha)) {
                        lio->u.logio.flags |=
                                (SRB_LOGIN_FCSP | SRB_LOGIN_SKIP_PRLI);
-                       ql_dbg(ql_dbg_disc, vha, 0x2072,
-                           "Async-login: w/ FCSP %8phC hdl=%x, loopid=%x portid=%06x\n",
-                           fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24);
                } else {
                        lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
                }
@@ -344,12 +341,14 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
        if (NVME_TARGET(vha->hw, fcport))
                lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;
 
+       rval = qla2x00_start_sp(sp);
+
        ql_dbg(ql_dbg_disc, vha, 0x2072,
-              "Async-login - %8phC hdl=%x, loopid=%x portid=%06x retries=%d.\n",
+              "Async-login - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
               fcport->port_name, sp->handle, fcport->loop_id,
-              fcport->d_id.b24, fcport->login_retry);
+              fcport->d_id.b24, fcport->login_retry,
+              lio->u.logio.flags & SRB_LOGIN_FCSP ? "FCSP" : "");
 
-       rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS) {
                fcport->flags |= FCF_LOGIN_NEEDED;
                set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
@@ -862,7 +861,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
                                break;
                        case DSC_LS_PLOGI_COMP:
                                if (vha->hw->flags.edif_enabled &&
-                                   vha->e_dbell.db_flags & EDB_ACTIVE) {
+                                   DBELL_ACTIVE(vha)) {
                                        /* check to see if App support secure or not */
                                        qla24xx_post_gpdb_work(vha, fcport, 0);
                                        break;
@@ -987,8 +986,6 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
            sp->name, res, sp->u.iocb_cmd.u.mbx.in_mb[1],
            sp->u.iocb_cmd.u.mbx.in_mb[2]);
 
-       if (res == QLA_FUNCTION_TIMEOUT)
-               return;
 
        sp->fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
        memset(&ea, 0, sizeof(ea));
@@ -1026,8 +1023,8 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
        spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
 
        list_for_each_entry_safe(fcport, tf, &h, gnl_entry) {
-               list_del_init(&fcport->gnl_entry);
                spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
+               list_del_init(&fcport->gnl_entry);
                fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
                spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
                ea.fcport = fcport;
@@ -1454,7 +1451,7 @@ static int        qla_chk_secure_login(scsi_qla_host_t    *vha, fc_port_t *fcport,
                        qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE,
                            fcport->d_id.b24);
 
-                       if (vha->e_dbell.db_flags ==  EDB_ACTIVE) {
+                       if (DBELL_ACTIVE(vha)) {
                                ql_dbg(ql_dbg_disc, vha, 0x20ef,
                                    "%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n",
                                    __func__, __LINE__, fcport->port_name);
@@ -1786,16 +1783,72 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
        fc_port_t *fcport;
        unsigned long flags;
 
-       fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
-       if (fcport) {
-               if (fcport->flags & FCF_FCP2_DEVICE) {
-                       ql_dbg(ql_dbg_disc, vha, 0x2115,
-                              "Delaying session delete for FCP2 portid=%06x %8phC ",
-                              fcport->d_id.b24, fcport->port_name);
-                       return;
+       switch (ea->id.b.rsvd_1) {
+       case RSCN_PORT_ADDR:
+               fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
+               if (fcport) {
+                       if (fcport->flags & FCF_FCP2_DEVICE) {
+                               ql_dbg(ql_dbg_disc, vha, 0x2115,
+                                      "Delaying session delete for FCP2 portid=%06x %8phC ",
+                                       fcport->d_id.b24, fcport->port_name);
+                               return;
+                       }
+
+                       if (vha->hw->flags.edif_enabled && DBELL_ACTIVE(vha)) {
+                               /*
+                                * On ipsec start by remote port, Target port
+                                * may use RSCN to trigger initiator to
+                                * relogin. If driver is already in the
+                                * process of a relogin, then ignore the RSCN
+                                * and allow the current relogin to continue.
+                                * This reduces thrashing of the connection.
+                                */
+                               if (atomic_read(&fcport->state) == FCS_ONLINE) {
+                                       /*
+                                        * If state = online, then set scan_needed=1 to do relogin.
+                                        * Otherwise we're already in the middle of a relogin
+                                        */
+                                       fcport->scan_needed = 1;
+                                       fcport->rscn_gen++;
+                               }
+                       } else {
+                               fcport->scan_needed = 1;
+                               fcport->rscn_gen++;
+                       }
+               }
+               break;
+       case RSCN_AREA_ADDR:
+               list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                       if (fcport->flags & FCF_FCP2_DEVICE)
+                               continue;
+
+                       if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) {
+                               fcport->scan_needed = 1;
+                               fcport->rscn_gen++;
+                       }
+               }
+               break;
+       case RSCN_DOM_ADDR:
+               list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                       if (fcport->flags & FCF_FCP2_DEVICE)
+                               continue;
+
+                       if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) {
+                               fcport->scan_needed = 1;
+                               fcport->rscn_gen++;
+                       }
+               }
+               break;
+       case RSCN_FAB_ADDR:
+       default:
+               list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                       if (fcport->flags & FCF_FCP2_DEVICE)
+                               continue;
+
+                       fcport->scan_needed = 1;
+                       fcport->rscn_gen++;
                }
-               fcport->scan_needed = 1;
-               fcport->rscn_gen++;
+               break;
        }
 
        spin_lock_irqsave(&vha->work_lock, flags);
@@ -4187,7 +4240,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
                 * fw shal not send PRLI after PLOGI Acc
                 */
                if (ha->flags.edif_enabled &&
-                   vha->e_dbell.db_flags & EDB_ACTIVE) {
+                   DBELL_ACTIVE(vha)) {
                        ha->fw_options[3] |= BIT_15;
                        ha->flags.n2n_fw_acc_sec = 1;
                } else {
@@ -4433,6 +4486,10 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
                    (ha->flags.fawwpn_enabled) ? "enabled" : "disabled");
        }
 
+       /* ELS pass through payload is limit by frame size. */
+       if (ha->flags.edif_enabled)
+               mid_init_cb->init_cb.frame_payload_size = cpu_to_le16(ELS_MAX_PAYLOAD);
+
        rval = qla2x00_init_firmware(vha, ha->init_cb_size);
 next_check:
        if (rval) {
@@ -5339,8 +5396,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
                         * use link up to wake up app to get ready for
                         * authentication.
                         */
-                       if (ha->flags.edif_enabled &&
-                           !(vha->e_dbell.db_flags & EDB_ACTIVE))
+                       if (ha->flags.edif_enabled && DBELL_INACTIVE(vha))
                                qla2x00_post_aen_work(vha, FCH_EVT_LINKUP,
                                                      ha->link_data_rate);
 
@@ -5833,6 +5889,10 @@ void qla_register_fcport_fn(struct work_struct *work)
 
        qla2x00_update_fcport(fcport->vha, fcport);
 
+       ql_dbg(ql_dbg_disc, fcport->vha, 0x911e,
+              "%s rscn gen %d/%d next DS %d\n", __func__,
+              rscn_gen, fcport->rscn_gen, fcport->next_disc_state);
+
        if (rscn_gen != fcport->rscn_gen) {
                /* RSCN(s) came in while registration */
                switch (fcport->next_disc_state) {