aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_nvme.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nvme.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.c107
1 files changed, 82 insertions, 25 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 609a908ea9db..0024de1c6c1f 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -316,7 +316,7 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
316 bf_set(wqe_dfctl, &wqe->gen_req.wge_ctl, 0); 316 bf_set(wqe_dfctl, &wqe->gen_req.wge_ctl, 0);
317 bf_set(wqe_si, &wqe->gen_req.wge_ctl, 1); 317 bf_set(wqe_si, &wqe->gen_req.wge_ctl, 1);
318 bf_set(wqe_la, &wqe->gen_req.wge_ctl, 1); 318 bf_set(wqe_la, &wqe->gen_req.wge_ctl, 1);
319 bf_set(wqe_rctl, &wqe->gen_req.wge_ctl, FC_RCTL_DD_UNSOL_CTL); 319 bf_set(wqe_rctl, &wqe->gen_req.wge_ctl, FC_RCTL_ELS4_REQ);
320 bf_set(wqe_type, &wqe->gen_req.wge_ctl, FC_TYPE_NVME); 320 bf_set(wqe_type, &wqe->gen_req.wge_ctl, FC_TYPE_NVME);
321 321
322 /* Word 6 */ 322 /* Word 6 */
@@ -620,15 +620,15 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport,
620 * Embed the payload in the last half of the WQE 620 * Embed the payload in the last half of the WQE
621 * WQE words 16-30 get the NVME CMD IU payload 621 * WQE words 16-30 get the NVME CMD IU payload
622 * 622 *
623 * WQE Word 16 is already setup with flags 623 * WQE words 16-19 get payload Words 1-4
624 * WQE words 17-19 get payload Words 2-4
625 * WQE words 20-21 get payload Words 6-7 624 * WQE words 20-21 get payload Words 6-7
626 * WQE words 22-29 get payload Words 16-23 625 * WQE words 22-29 get payload Words 16-23
627 */ 626 */
628 wptr = &wqe->words[17]; /* WQE ptr */ 627 wptr = &wqe->words[16]; /* WQE ptr */
629 dptr = (uint32_t *)nCmd->cmdaddr; /* payload ptr */ 628 dptr = (uint32_t *)nCmd->cmdaddr; /* payload ptr */
630 dptr += 2; /* Skip Words 0-1 in payload */ 629 dptr++; /* Skip Word 0 in payload */
631 630
631 *wptr++ = *dptr++; /* Word 1 */
632 *wptr++ = *dptr++; /* Word 2 */ 632 *wptr++ = *dptr++; /* Word 2 */
633 *wptr++ = *dptr++; /* Word 3 */ 633 *wptr++ = *dptr++; /* Word 3 */
634 *wptr++ = *dptr++; /* Word 4 */ 634 *wptr++ = *dptr++; /* Word 4 */
@@ -978,9 +978,6 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
978 bf_set(wqe_cmd_type, &wqe->generic.wqe_com, 978 bf_set(wqe_cmd_type, &wqe->generic.wqe_com,
979 NVME_WRITE_CMD); 979 NVME_WRITE_CMD);
980 980
981 /* Word 16 */
982 wqe->words[16] = LPFC_NVME_EMBED_WRITE;
983
984 phba->fc4NvmeOutputRequests++; 981 phba->fc4NvmeOutputRequests++;
985 } else { 982 } else {
986 /* Word 7 */ 983 /* Word 7 */
@@ -1002,9 +999,6 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
1002 bf_set(wqe_cmd_type, &wqe->generic.wqe_com, 999 bf_set(wqe_cmd_type, &wqe->generic.wqe_com,
1003 NVME_READ_CMD); 1000 NVME_READ_CMD);
1004 1001
1005 /* Word 16 */
1006 wqe->words[16] = LPFC_NVME_EMBED_READ;
1007
1008 phba->fc4NvmeInputRequests++; 1002 phba->fc4NvmeInputRequests++;
1009 } 1003 }
1010 } else { 1004 } else {
@@ -1026,9 +1020,6 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
1026 /* Word 11 */ 1020 /* Word 11 */
1027 bf_set(wqe_cmd_type, &wqe->generic.wqe_com, NVME_READ_CMD); 1021 bf_set(wqe_cmd_type, &wqe->generic.wqe_com, NVME_READ_CMD);
1028 1022
1029 /* Word 16 */
1030 wqe->words[16] = LPFC_NVME_EMBED_CMD;
1031
1032 phba->fc4NvmeControlRequests++; 1023 phba->fc4NvmeControlRequests++;
1033 } 1024 }
1034 /* 1025 /*
@@ -1286,6 +1277,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
1286 pnvme_fcreq->private = (void *)lpfc_ncmd; 1277 pnvme_fcreq->private = (void *)lpfc_ncmd;
1287 lpfc_ncmd->nvmeCmd = pnvme_fcreq; 1278 lpfc_ncmd->nvmeCmd = pnvme_fcreq;
1288 lpfc_ncmd->nrport = rport; 1279 lpfc_ncmd->nrport = rport;
1280 lpfc_ncmd->ndlp = ndlp;
1289 lpfc_ncmd->start_time = jiffies; 1281 lpfc_ncmd->start_time = jiffies;
1290 1282
1291 lpfc_nvme_prep_io_cmd(vport, lpfc_ncmd, ndlp); 1283 lpfc_nvme_prep_io_cmd(vport, lpfc_ncmd, ndlp);
@@ -1319,7 +1311,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
1319 "sid: x%x did: x%x oxid: x%x\n", 1311 "sid: x%x did: x%x oxid: x%x\n",
1320 ret, vport->fc_myDID, ndlp->nlp_DID, 1312 ret, vport->fc_myDID, ndlp->nlp_DID,
1321 lpfc_ncmd->cur_iocbq.sli4_xritag); 1313 lpfc_ncmd->cur_iocbq.sli4_xritag);
1322 ret = -EINVAL; 1314 ret = -EBUSY;
1323 goto out_free_nvme_buf; 1315 goto out_free_nvme_buf;
1324 } 1316 }
1325 1317
@@ -1821,10 +1813,10 @@ lpfc_post_nvme_sgl_list(struct lpfc_hba *phba,
1821 pdma_phys_sgl1, cur_xritag); 1813 pdma_phys_sgl1, cur_xritag);
1822 if (status) { 1814 if (status) {
1823 /* failure, put on abort nvme list */ 1815 /* failure, put on abort nvme list */
1824 lpfc_ncmd->exch_busy = 1; 1816 lpfc_ncmd->flags |= LPFC_SBUF_XBUSY;
1825 } else { 1817 } else {
1826 /* success, put on NVME buffer list */ 1818 /* success, put on NVME buffer list */
1827 lpfc_ncmd->exch_busy = 0; 1819 lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY;
1828 lpfc_ncmd->status = IOSTAT_SUCCESS; 1820 lpfc_ncmd->status = IOSTAT_SUCCESS;
1829 num_posted++; 1821 num_posted++;
1830 } 1822 }
@@ -1854,10 +1846,10 @@ lpfc_post_nvme_sgl_list(struct lpfc_hba *phba,
1854 struct lpfc_nvme_buf, list); 1846 struct lpfc_nvme_buf, list);
1855 if (status) { 1847 if (status) {
1856 /* failure, put on abort nvme list */ 1848 /* failure, put on abort nvme list */
1857 lpfc_ncmd->exch_busy = 1; 1849 lpfc_ncmd->flags |= LPFC_SBUF_XBUSY;
1858 } else { 1850 } else {
1859 /* success, put on NVME buffer list */ 1851 /* success, put on NVME buffer list */
1860 lpfc_ncmd->exch_busy = 0; 1852 lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY;
1861 lpfc_ncmd->status = IOSTAT_SUCCESS; 1853 lpfc_ncmd->status = IOSTAT_SUCCESS;
1862 num_posted++; 1854 num_posted++;
1863 } 1855 }
@@ -2099,7 +2091,7 @@ lpfc_release_nvme_buf(struct lpfc_hba *phba, struct lpfc_nvme_buf *lpfc_ncmd)
2099 unsigned long iflag = 0; 2091 unsigned long iflag = 0;
2100 2092
2101 lpfc_ncmd->nonsg_phys = 0; 2093 lpfc_ncmd->nonsg_phys = 0;
2102 if (lpfc_ncmd->exch_busy) { 2094 if (lpfc_ncmd->flags & LPFC_SBUF_XBUSY) {
2103 spin_lock_irqsave(&phba->sli4_hba.abts_nvme_buf_list_lock, 2095 spin_lock_irqsave(&phba->sli4_hba.abts_nvme_buf_list_lock,
2104 iflag); 2096 iflag);
2105 lpfc_ncmd->nvmeCmd = NULL; 2097 lpfc_ncmd->nvmeCmd = NULL;
@@ -2135,11 +2127,12 @@ lpfc_release_nvme_buf(struct lpfc_hba *phba, struct lpfc_nvme_buf *lpfc_ncmd)
2135int 2127int
2136lpfc_nvme_create_localport(struct lpfc_vport *vport) 2128lpfc_nvme_create_localport(struct lpfc_vport *vport)
2137{ 2129{
2130 int ret = 0;
2138 struct lpfc_hba *phba = vport->phba; 2131 struct lpfc_hba *phba = vport->phba;
2139 struct nvme_fc_port_info nfcp_info; 2132 struct nvme_fc_port_info nfcp_info;
2140 struct nvme_fc_local_port *localport; 2133 struct nvme_fc_local_port *localport;
2141 struct lpfc_nvme_lport *lport; 2134 struct lpfc_nvme_lport *lport;
2142 int len, ret = 0; 2135 int len;
2143 2136
2144 /* Initialize this localport instance. The vport wwn usage ensures 2137 /* Initialize this localport instance. The vport wwn usage ensures
2145 * that NPIV is accounted for. 2138 * that NPIV is accounted for.
@@ -2156,8 +2149,12 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport)
2156 /* localport is allocated from the stack, but the registration 2149 /* localport is allocated from the stack, but the registration
2157 * call allocates heap memory as well as the private area. 2150 * call allocates heap memory as well as the private area.
2158 */ 2151 */
2152#if (IS_ENABLED(CONFIG_NVME_FC))
2159 ret = nvme_fc_register_localport(&nfcp_info, &lpfc_nvme_template, 2153 ret = nvme_fc_register_localport(&nfcp_info, &lpfc_nvme_template,
2160 &vport->phba->pcidev->dev, &localport); 2154 &vport->phba->pcidev->dev, &localport);
2155#else
2156 ret = -ENOMEM;
2157#endif
2161 if (!ret) { 2158 if (!ret) {
2162 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME | LOG_NVME_DISC, 2159 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME | LOG_NVME_DISC,
2163 "6005 Successfully registered local " 2160 "6005 Successfully registered local "
@@ -2173,10 +2170,10 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport)
2173 lport->vport = vport; 2170 lport->vport = vport;
2174 INIT_LIST_HEAD(&lport->rport_list); 2171 INIT_LIST_HEAD(&lport->rport_list);
2175 vport->nvmei_support = 1; 2172 vport->nvmei_support = 1;
2173 len = lpfc_new_nvme_buf(vport, phba->sli4_hba.nvme_xri_max);
2174 vport->phba->total_nvme_bufs += len;
2176 } 2175 }
2177 2176
2178 len = lpfc_new_nvme_buf(vport, phba->sli4_hba.nvme_xri_max);
2179 vport->phba->total_nvme_bufs += len;
2180 return ret; 2177 return ret;
2181} 2178}
2182 2179
@@ -2193,6 +2190,7 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport)
2193void 2190void
2194lpfc_nvme_destroy_localport(struct lpfc_vport *vport) 2191lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
2195{ 2192{
2193#if (IS_ENABLED(CONFIG_NVME_FC))
2196 struct nvme_fc_local_port *localport; 2194 struct nvme_fc_local_port *localport;
2197 struct lpfc_nvme_lport *lport; 2195 struct lpfc_nvme_lport *lport;
2198 struct lpfc_nvme_rport *rport = NULL, *rport_next = NULL; 2196 struct lpfc_nvme_rport *rport = NULL, *rport_next = NULL;
@@ -2208,7 +2206,6 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
2208 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, 2206 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME,
2209 "6011 Destroying NVME localport %p\n", 2207 "6011 Destroying NVME localport %p\n",
2210 localport); 2208 localport);
2211
2212 list_for_each_entry_safe(rport, rport_next, &lport->rport_list, list) { 2209 list_for_each_entry_safe(rport, rport_next, &lport->rport_list, list) {
2213 /* The last node ref has to get released now before the rport 2210 /* The last node ref has to get released now before the rport
2214 * private memory area is released by the transport. 2211 * private memory area is released by the transport.
@@ -2222,6 +2219,7 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
2222 "6008 rport fail destroy %x\n", ret); 2219 "6008 rport fail destroy %x\n", ret);
2223 wait_for_completion_timeout(&rport->rport_unreg_done, 5); 2220 wait_for_completion_timeout(&rport->rport_unreg_done, 5);
2224 } 2221 }
2222
2225 /* lport's rport list is clear. Unregister 2223 /* lport's rport list is clear. Unregister
2226 * lport and release resources. 2224 * lport and release resources.
2227 */ 2225 */
@@ -2245,6 +2243,7 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
2245 "Failed, status x%x\n", 2243 "Failed, status x%x\n",
2246 ret); 2244 ret);
2247 } 2245 }
2246#endif
2248} 2247}
2249 2248
2250void 2249void
@@ -2275,6 +2274,7 @@ lpfc_nvme_update_localport(struct lpfc_vport *vport)
2275int 2274int
2276lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) 2275lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2277{ 2276{
2277#if (IS_ENABLED(CONFIG_NVME_FC))
2278 int ret = 0; 2278 int ret = 0;
2279 struct nvme_fc_local_port *localport; 2279 struct nvme_fc_local_port *localport;
2280 struct lpfc_nvme_lport *lport; 2280 struct lpfc_nvme_lport *lport;
@@ -2348,7 +2348,6 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2348 rpinfo.port_role |= FC_PORT_ROLE_NVME_INITIATOR; 2348 rpinfo.port_role |= FC_PORT_ROLE_NVME_INITIATOR;
2349 rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn); 2349 rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
2350 rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); 2350 rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
2351
2352 ret = nvme_fc_register_remoteport(localport, &rpinfo, 2351 ret = nvme_fc_register_remoteport(localport, &rpinfo,
2353 &remote_port); 2352 &remote_port);
2354 if (!ret) { 2353 if (!ret) {
@@ -2384,6 +2383,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2384 ndlp->nlp_type, ndlp->nlp_DID, ndlp); 2383 ndlp->nlp_type, ndlp->nlp_DID, ndlp);
2385 } 2384 }
2386 return ret; 2385 return ret;
2386#else
2387 return 0;
2388#endif
2387} 2389}
2388 2390
2389/* lpfc_nvme_unregister_port - unbind the DID and port_role from this rport. 2391/* lpfc_nvme_unregister_port - unbind the DID and port_role from this rport.
@@ -2401,6 +2403,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2401void 2403void
2402lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) 2404lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2403{ 2405{
2406#if (IS_ENABLED(CONFIG_NVME_FC))
2404 int ret; 2407 int ret;
2405 struct nvme_fc_local_port *localport; 2408 struct nvme_fc_local_port *localport;
2406 struct lpfc_nvme_lport *lport; 2409 struct lpfc_nvme_lport *lport;
@@ -2458,7 +2461,61 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
2458 return; 2461 return;
2459 2462
2460 input_err: 2463 input_err:
2464#endif
2461 lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, 2465 lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
2462 "6168: State error: lport %p, rport%p FCID x%06x\n", 2466 "6168: State error: lport %p, rport%p FCID x%06x\n",
2463 vport->localport, ndlp->rport, ndlp->nlp_DID); 2467 vport->localport, ndlp->rport, ndlp->nlp_DID);
2464} 2468}
2469
2470/**
2471 * lpfc_sli4_nvme_xri_aborted - Fast-path process of NVME xri abort
2472 * @phba: pointer to lpfc hba data structure.
2473 * @axri: pointer to the fcp xri abort wcqe structure.
2474 *
2475 * This routine is invoked by the worker thread to process a SLI4 fast-path
2476 * FCP aborted xri.
2477 **/
2478void
2479lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba,
2480 struct sli4_wcqe_xri_aborted *axri)
2481{
2482 uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
2483 uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
2484 struct lpfc_nvme_buf *lpfc_ncmd, *next_lpfc_ncmd;
2485 struct lpfc_nodelist *ndlp;
2486 unsigned long iflag = 0;
2487 int rrq_empty = 0;
2488
2489 if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME))
2490 return;
2491 spin_lock_irqsave(&phba->hbalock, iflag);
2492 spin_lock(&phba->sli4_hba.abts_nvme_buf_list_lock);
2493 list_for_each_entry_safe(lpfc_ncmd, next_lpfc_ncmd,
2494 &phba->sli4_hba.lpfc_abts_nvme_buf_list,
2495 list) {
2496 if (lpfc_ncmd->cur_iocbq.sli4_xritag == xri) {
2497 list_del(&lpfc_ncmd->list);
2498 lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY;
2499 lpfc_ncmd->status = IOSTAT_SUCCESS;
2500 spin_unlock(
2501 &phba->sli4_hba.abts_nvme_buf_list_lock);
2502
2503 rrq_empty = list_empty(&phba->active_rrq_list);
2504 spin_unlock_irqrestore(&phba->hbalock, iflag);
2505 ndlp = lpfc_ncmd->ndlp;
2506 if (ndlp) {
2507 lpfc_set_rrq_active(
2508 phba, ndlp,
2509 lpfc_ncmd->cur_iocbq.sli4_lxritag,
2510 rxid, 1);
2511 lpfc_sli4_abts_err_handler(phba, ndlp, axri);
2512 }
2513 lpfc_release_nvme_buf(phba, lpfc_ncmd);
2514 if (rrq_empty)
2515 lpfc_worker_wake_up(phba);
2516 return;
2517 }
2518 }
2519 spin_unlock(&phba->sli4_hba.abts_nvme_buf_list_lock);
2520 spin_unlock_irqrestore(&phba->hbalock, iflag);
2521}