Merge branch 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-block.git] / drivers / scsi / qla2xxx / qla_init.c
index 8d1acc802a6741ef38efd09c5f5382d413a4b011..420045155ba042fbf316463fe6c087f0ba032412 100644 (file)
@@ -366,14 +366,16 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport)
        qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
 
        sp->done = qla2x00_async_prlo_sp_done;
-       rval = qla2x00_start_sp(sp);
-       if (rval != QLA_SUCCESS)
-               goto done_free_sp;
 
        ql_dbg(ql_dbg_disc, vha, 0x2070,
            "Async-prlo - hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
            sp->handle, fcport->loop_id, fcport->d_id.b.domain,
            fcport->d_id.b.area, fcport->d_id.b.al_pa);
+
+       rval = qla2x00_start_sp(sp);
+       if (rval != QLA_SUCCESS)
+               goto done_free_sp;
+
        return rval;
 
 done_free_sp:
@@ -471,9 +473,11 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
 {
        srb_t *sp;
        struct srb_iocb *lio;
-       int rval;
+       int rval = QLA_FUNCTION_FAILED;
+
+       if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
+               return rval;
 
-       rval = QLA_FUNCTION_FAILED;
        fcport->flags |= FCF_ASYNC_SENT;
        sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
        if (!sp)
@@ -644,11 +648,14 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
                                break;
                        case DSC_LS_PORT_UNAVAIL:
                        default:
-                               if (fcport->loop_id != FC_NO_LOOP_ID)
-                                       qla2x00_clear_loop_id(fcport);
-
-                               fcport->loop_id = loop_id;
-                               fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
+                               if (fcport->loop_id == FC_NO_LOOP_ID) {
+                                       qla2x00_find_new_loop_id(vha, fcport);
+                                       fcport->fw_login_state =
+                                           DSC_LS_PORT_UNAVAIL;
+                               }
+                               ql_dbg(ql_dbg_disc, vha, 0x20e5,
+                                   "%s %d %8phC\n", __func__, __LINE__,
+                                   fcport->port_name);
                                qla24xx_fcport_handle_login(vha, fcport);
                                break;
                        }
@@ -931,14 +938,14 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
 
        sp->done = qla24xx_async_gnl_sp_done;
 
-       rval = qla2x00_start_sp(sp);
-       if (rval != QLA_SUCCESS)
-               goto done_free_sp;
-
        ql_dbg(ql_dbg_disc, vha, 0x20da,
            "Async-%s - OUT WWPN %8phC hndl %x\n",
            sp->name, fcport->port_name, sp->handle);
 
+       rval = qla2x00_start_sp(sp);
+       if (rval != QLA_SUCCESS)
+               goto done_free_sp;
+
        return rval;
 
 done_free_sp:
@@ -1072,6 +1079,11 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
        if  (fcport->fc4f_nvme)
                lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
 
+       ql_dbg(ql_dbg_disc, vha, 0x211b,
+           "Async-prli - %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->fc4f_nvme ? "nvme" : "fc");
+
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS) {
                fcport->flags |= FCF_LOGIN_NEEDED;
@@ -1079,11 +1091,6 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
                goto done_free_sp;
        }
 
-       ql_dbg(ql_dbg_disc, vha, 0x211b,
-           "Async-prli - %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->fc4f_nvme ? "nvme" : "fc");
-
        return rval;
 
 done_free_sp:
@@ -1471,29 +1478,6 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
        return 0;
 }
 
-static
-void qla24xx_handle_rscn_event(fc_port_t *fcport, struct event_arg *ea)
-{
-       fcport->rscn_gen++;
-
-       ql_dbg(ql_dbg_disc, fcport->vha, 0x210c,
-           "%s %8phC DS %d LS %d\n",
-           __func__, fcport->port_name, fcport->disc_state,
-           fcport->fw_login_state);
-
-       if (fcport->flags & FCF_ASYNC_SENT)
-               return;
-
-       switch (fcport->disc_state) {
-       case DSC_DELETED:
-       case DSC_LOGIN_COMPLETE:
-               qla24xx_post_gpnid_work(fcport->vha, &ea->id);
-               break;
-       default:
-               break;
-       }
-}
-
 int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id,
     u8 *port_name, u8 *node_name, void *pla, u8 fc4_type)
 {
@@ -1560,8 +1544,6 @@ static void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
 
 void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
 {
-       fc_port_t *f, *tf;
-       uint32_t id = 0, mask, rid;
        fc_port_t *fcport;
 
        switch (ea->event) {
@@ -1574,10 +1556,6 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
        case FCME_RSCN:
                if (test_bit(UNLOADING, &vha->dpc_flags))
                        return;
-               switch (ea->id.b.rsvd_1) {
-               case RSCN_PORT_ADDR:
-#define BIGSCAN 1
-#if defined BIGSCAN & BIGSCAN > 0
                {
                        unsigned long flags;
                        fcport = qla2x00_find_fcport_by_nportid
@@ -1596,59 +1574,6 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
                        }
                        spin_unlock_irqrestore(&vha->work_lock, flags);
                }
-#else
-               {
-                       int rc;
-                       fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
-                       if (!fcport) {
-                               /* cable moved */
-                                rc = qla24xx_post_gpnid_work(vha, &ea->id);
-                                if (rc) {
-                                        ql_log(ql_log_warn, vha, 0xd044,
-                                            "RSCN GPNID work failed %06x\n",
-                                            ea->id.b24);
-                                }
-                       } else {
-                               ea->fcport = fcport;
-                               fcport->scan_needed = 1;
-                               qla24xx_handle_rscn_event(fcport, ea);
-                       }
-               }
-#endif
-                       break;
-               case RSCN_AREA_ADDR:
-               case RSCN_DOM_ADDR:
-                       if (ea->id.b.rsvd_1 == RSCN_AREA_ADDR) {
-                               mask = 0xffff00;
-                               ql_dbg(ql_dbg_async, vha, 0x5044,
-                                   "RSCN: Area 0x%06x was affected\n",
-                                   ea->id.b24);
-                       } else {
-                               mask = 0xff0000;
-                               ql_dbg(ql_dbg_async, vha, 0x507a,
-                                   "RSCN: Domain 0x%06x was affected\n",
-                                   ea->id.b24);
-                       }
-
-                       rid = ea->id.b24 & mask;
-                       list_for_each_entry_safe(f, tf, &vha->vp_fcports,
-                           list) {
-                               id = f->d_id.b24 & mask;
-                               if (rid == id) {
-                                       ea->fcport = f;
-                                       qla24xx_handle_rscn_event(f, ea);
-                               }
-                       }
-                       break;
-               case RSCN_FAB_ADDR:
-               default:
-                       ql_log(ql_log_warn, vha, 0xd045,
-                           "RSCN: Fabric was affected. Addr format %d\n",
-                           ea->id.b.rsvd_1);
-                       qla2x00_mark_all_devices_lost(vha, 1);
-                       set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
-                       set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
-               }
                break;
        case FCME_GNL_DONE:
                qla24xx_handle_gnl_done_event(vha, ea);
@@ -1709,11 +1634,7 @@ void qla_rscn_replay(fc_port_t *fcport)
                ea.event = FCME_RSCN;
                ea.id = fcport->d_id;
                ea.id.b.rsvd_1 = RSCN_PORT_ADDR;
-#if defined BIGSCAN & BIGSCAN > 0
                qla2x00_fcport_event_handler(fcport->vha, &ea);
-#else
-               qla24xx_post_gpnid_work(fcport->vha, &ea.id);
-#endif
        }
 }
 
@@ -1784,8 +1705,8 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
                lun = (uint16_t)tm_iocb->u.tmf.lun;
 
                /* Issue Marker IOCB */
-               qla2x00_marker(vha, vha->hw->req_q_map[0],
-                   vha->hw->rsp_q_map[0], fcport->loop_id, lun,
+               qla2x00_marker(vha, vha->hw->base_qpair,
+                   fcport->loop_id, lun,
                    flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
        }
 
@@ -1829,7 +1750,7 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
        int rval = QLA_FUNCTION_FAILED;
 
        sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
-           GFP_KERNEL);
+           GFP_ATOMIC);
        if (!sp)
                goto done;
 
@@ -1912,6 +1833,12 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
 
                ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
                ea->fcport->logout_on_delete = 1;
+               ea->fcport->nvme_prli_service_param = ea->iop[0];
+               if (ea->iop[0] & NVME_PRLI_SP_FIRST_BURST)
+                       ea->fcport->nvme_first_burst_size =
+                           (ea->iop[1] & 0xffff) * 512;
+               else
+                       ea->fcport->nvme_first_burst_size = 0;
                qla24xx_post_gpdb_work(vha, ea->fcport, 0);
                break;
        default:
@@ -3955,8 +3882,17 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
                WRT_REG_DWORD(&reg->isp24.rsp_q_in, 0);
                WRT_REG_DWORD(&reg->isp24.rsp_q_out, 0);
        }
+
        qlt_24xx_config_rings(vha);
 
+       /* If the user has configured the speed, set it here */
+       if (ha->set_data_rate) {
+               ql_dbg(ql_dbg_init, vha, 0x00fd,
+                   "Speed set by user : %s Gbps \n",
+                   qla2x00_get_link_speed_str(ha, ha->set_data_rate));
+               icb->firmware_options_3 = (ha->set_data_rate << 13);
+       }
+
        /* PCI posting */
        RD_REG_DWORD(&ioreg->hccr);
 }
@@ -4755,6 +4691,16 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
        if (!fcport)
                return NULL;
 
+       fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev,
+               sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma,
+               flags);
+       if (!fcport->ct_desc.ct_sns) {
+               ql_log(ql_log_warn, vha, 0xd049,
+                   "Failed to allocate ct_sns request.\n");
+               kfree(fcport);
+               return NULL;
+       }
+
        /* Setup fcport template structure. */
        fcport->vha = vha;
        fcport->port_type = FCT_UNKNOWN;
@@ -4763,13 +4709,11 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
        fcport->supported_classes = FC_COS_UNSPECIFIED;
        fcport->fp_speed = PORT_SPEED_UNKNOWN;
 
-       fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev,
-               sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma,
-               flags);
        fcport->disc_state = DSC_DELETED;
        fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
        fcport->deleted = QLA_SESS_DELETED;
        fcport->login_retry = vha->hw->login_retry_count;
+       fcport->chip_reset = vha->hw->base_qpair->chip_reset;
        fcport->logout_on_delete = 1;
 
        if (!fcport->ct_desc.ct_sns) {
@@ -4778,6 +4722,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
                kfree(fcport);
                fcport = NULL;
        }
+
        INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn);
        INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
        INIT_LIST_HEAD(&fcport->gnl_entry);
@@ -5046,11 +4991,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
                if ((domain & 0xf0) == 0xf0)
                        continue;
 
-               /* Bypass if not same domain and area of adapter. */
-               if (area && domain &&
-                   (area != vha->d_id.b.area || domain != vha->d_id.b.domain))
-                       continue;
-
                /* Bypass invalid local loop ID. */
                if (loop_id > LAST_LOCAL_LOOP_ID)
                        continue;
@@ -6101,11 +6041,6 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
 {
        int rval = QLA_SUCCESS;
        uint32_t wait_time;
-       struct req_que *req;
-       struct rsp_que *rsp;
-
-       req = vha->req;
-       rsp = req->rsp;
 
        clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
        if (vha->flags.online) {
@@ -6118,8 +6053,8 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
                                         * Issue a marker after FW becomes
                                         * ready.
                                         */
-                                       qla2x00_marker(vha, req, rsp, 0, 0,
-                                               MK_SYNC_ALL);
+                                       qla2x00_marker(vha, vha->hw->base_qpair,
+                                           0, 0, MK_SYNC_ALL);
                                        vha->marker_needed = 0;
                                }
 
@@ -6857,8 +6792,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
 {
        int status = 0;
        struct qla_hw_data *ha = vha->hw;
-       struct req_que *req = ha->req_q_map[0];
-       struct rsp_que *rsp = ha->rsp_q_map[0];
 
        /* If firmware needs to be loaded */
        if (qla2x00_isp_firmware(vha)) {
@@ -6878,7 +6811,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
                status = qla2x00_fw_ready(vha);
                if (!status) {
                        /* Issue a marker after FW becomes ready. */
-                       qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
+                       qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
                        set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
                }
 
@@ -7933,22 +7866,15 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha)
        uint16_t mb[MAILBOX_REGISTER_COUNT];
        struct qla_hw_data *ha = vha->hw;
        struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
-       struct req_que *req;
-       struct rsp_que *rsp;
 
        if (!vha->vp_idx)
                return -EINVAL;
 
        rval = qla2x00_fw_ready(base_vha);
-       if (vha->qpair)
-               req = vha->qpair->req;
-       else
-               req = ha->req_q_map[0];
-       rsp = req->rsp;
 
        if (rval == QLA_SUCCESS) {
                clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
-               qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
+               qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
        }
 
        vha->flags.management_server_logged_in = 0;
@@ -8340,8 +8266,6 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
 {
        int status, rval;
        struct qla_hw_data *ha = vha->hw;
-       struct req_que *req = ha->req_q_map[0];
-       struct rsp_que *rsp = ha->rsp_q_map[0];
        struct scsi_qla_host *vp;
        unsigned long flags;
 
@@ -8353,7 +8277,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
                status = qla2x00_fw_ready(vha);
                if (!status) {
                        /* Issue a marker after FW becomes ready. */
-                       qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
+                       qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
                        vha->flags.online = 1;
                        set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
                }