summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c73
1 files changed, 50 insertions, 23 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 491aa95eb0f6..7e7ae786121b 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -37,6 +37,7 @@
#include <linux/miscdevice.h>
#include <linux/percpu.h>
#include <linux/msi.h>
+#include <linux/bitops.h>
#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
@@ -1253,6 +1254,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
unsigned long time_elapsed;
uint32_t tick_cqe, max_cqe, val;
uint64_t tot, data1, data2, data3;
+ struct lpfc_nvmet_tgtport *tgtp;
struct lpfc_register reg_data;
void __iomem *eqdreg = phba->sli4_hba.u.if_type2.EQDregaddr;
@@ -1281,13 +1283,11 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
/* Check outstanding IO count */
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
if (phba->nvmet_support) {
- spin_lock(&phba->sli4_hba.nvmet_ctx_get_lock);
- spin_lock(&phba->sli4_hba.nvmet_ctx_put_lock);
- tot = phba->sli4_hba.nvmet_xri_cnt -
- (phba->sli4_hba.nvmet_ctx_get_cnt +
- phba->sli4_hba.nvmet_ctx_put_cnt);
- spin_unlock(&phba->sli4_hba.nvmet_ctx_put_lock);
- spin_unlock(&phba->sli4_hba.nvmet_ctx_get_lock);
+ tgtp = phba->targetport->private;
+ /* Calculate outstanding IOs */
+ tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
+ tot += atomic_read(&tgtp->xmt_fcp_release);
+ tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
} else {
tot = atomic_read(&phba->fc4NvmeIoCmpls);
data1 = atomic_read(
@@ -3048,7 +3048,7 @@ lpfc_online(struct lpfc_hba *phba)
{
struct lpfc_vport *vport;
struct lpfc_vport **vports;
- int i;
+ int i, error = 0;
bool vpis_cleared = false;
if (!phba)
@@ -3072,6 +3072,18 @@ lpfc_online(struct lpfc_hba *phba)
if (!phba->sli4_hba.max_cfg_param.vpi_used)
vpis_cleared = true;
spin_unlock_irq(&phba->hbalock);
+
+ /* Reestablish the local initiator port.
+ * The offline process destroyed the previous lport.
+ */
+ if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
+ !phba->nvmet_support) {
+ error = lpfc_nvme_create_localport(phba->pport);
+ if (error)
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "6132 NVME restore reg failed "
+ "on nvmei error x%x\n", error);
+ }
} else {
lpfc_sli_queue_init(phba);
if (lpfc_sli_hba_setup(phba)) { /* Initialize SLI2/SLI3 HBA */
@@ -3226,6 +3238,13 @@ lpfc_offline(struct lpfc_hba *phba)
/* stop port and all timers associated with this hba */
lpfc_stop_port(phba);
+
+ /* Tear down the local and target port registrations. The
+ * nvme transports need to cleanup.
+ */
+ lpfc_nvmet_destroy_targetport(phba);
+ lpfc_nvme_destroy_localport(phba->pport);
+
vports = lpfc_create_vport_work_array(phba);
if (vports != NULL)
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
@@ -3275,7 +3294,7 @@ lpfc_scsi_free(struct lpfc_hba *phba)
list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list_put,
list) {
list_del(&sb->list);
- pci_pool_free(phba->lpfc_sg_dma_buf_pool, sb->data,
+ dma_pool_free(phba->lpfc_sg_dma_buf_pool, sb->data,
sb->dma_handle);
kfree(sb);
phba->total_scsi_bufs--;
@@ -3286,7 +3305,7 @@ lpfc_scsi_free(struct lpfc_hba *phba)
list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list_get,
list) {
list_del(&sb->list);
- pci_pool_free(phba->lpfc_sg_dma_buf_pool, sb->data,
+ dma_pool_free(phba->lpfc_sg_dma_buf_pool, sb->data,
sb->dma_handle);
kfree(sb);
phba->total_scsi_bufs--;
@@ -3317,7 +3336,7 @@ lpfc_nvme_free(struct lpfc_hba *phba)
list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
&phba->lpfc_nvme_buf_list_put, list) {
list_del(&lpfc_ncmd->list);
- pci_pool_free(phba->lpfc_sg_dma_buf_pool, lpfc_ncmd->data,
+ dma_pool_free(phba->lpfc_sg_dma_buf_pool, lpfc_ncmd->data,
lpfc_ncmd->dma_handle);
kfree(lpfc_ncmd);
phba->total_nvme_bufs--;
@@ -3328,7 +3347,7 @@ lpfc_nvme_free(struct lpfc_hba *phba)
list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next,
&phba->lpfc_nvme_buf_list_get, list) {
list_del(&lpfc_ncmd->list);
- pci_pool_free(phba->lpfc_sg_dma_buf_pool, lpfc_ncmd->data,
+ dma_pool_free(phba->lpfc_sg_dma_buf_pool, lpfc_ncmd->data,
lpfc_ncmd->dma_handle);
kfree(lpfc_ncmd);
phba->total_nvme_bufs--;
@@ -3640,7 +3659,7 @@ lpfc_sli4_scsi_sgl_update(struct lpfc_hba *phba)
list_remove_head(&scsi_sgl_list, psb,
struct lpfc_scsi_buf, list);
if (psb) {
- pci_pool_free(phba->lpfc_sg_dma_buf_pool,
+ dma_pool_free(phba->lpfc_sg_dma_buf_pool,
psb->data, psb->dma_handle);
kfree(psb);
}
@@ -3710,9 +3729,7 @@ lpfc_get_wwpn(struct lpfc_hba *phba)
if (phba->sli_rev == LPFC_SLI_REV4)
return be64_to_cpu(wwn);
else
- return (((wwn & 0xffffffff00000000) >> 32) |
- ((wwn & 0x00000000ffffffff) << 32));
-
+ return rol64(wwn, 32);
}
/**
@@ -3774,7 +3791,7 @@ lpfc_sli4_nvme_sgl_update(struct lpfc_hba *phba)
list_remove_head(&nvme_sgl_list, lpfc_ncmd,
struct lpfc_nvme_buf, list);
if (lpfc_ncmd) {
- pci_pool_free(phba->lpfc_sg_dma_buf_pool,
+ dma_pool_free(phba->lpfc_sg_dma_buf_pool,
lpfc_ncmd->data,
lpfc_ncmd->dma_handle);
kfree(lpfc_ncmd);
@@ -5930,8 +5947,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
spin_lock_init(&phba->sli4_hba.abts_nvme_buf_list_lock);
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvme_buf_list);
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list);
- INIT_LIST_HEAD(&phba->sli4_hba.lpfc_nvmet_ctx_get_list);
- INIT_LIST_HEAD(&phba->sli4_hba.lpfc_nvmet_ctx_put_list);
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_nvmet_io_wait_list);
/* Fast-path XRI aborted CQ Event work queue list */
@@ -5940,8 +5955,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
/* This abort list used by worker thread */
spin_lock_init(&phba->sli4_hba.sgl_list_lock);
- spin_lock_init(&phba->sli4_hba.nvmet_ctx_get_lock);
- spin_lock_init(&phba->sli4_hba.nvmet_ctx_put_lock);
spin_lock_init(&phba->sli4_hba.nvmet_io_wait_lock);
/*
@@ -6516,6 +6529,12 @@ lpfc_free_nvmet_sgl_list(struct lpfc_hba *phba)
lpfc_nvmet_buf_free(phba, sglq_entry->virt, sglq_entry->phys);
kfree(sglq_entry);
}
+
+ /* Update the nvmet_xri_cnt to reflect no current sgls.
+ * The next initialization cycle sets the count and allocates
+ * the sgls over again.
+ */
+ phba->sli4_hba.nvmet_xri_cnt = 0;
}
/**
@@ -6846,8 +6865,8 @@ lpfc_create_shost(struct lpfc_hba *phba)
if (phba->nvmet_support) {
/* Only 1 vport (pport) will support NVME target */
if (phba->txrdy_payload_pool == NULL) {
- phba->txrdy_payload_pool = pci_pool_create(
- "txrdy_pool", phba->pcidev,
+ phba->txrdy_payload_pool = dma_pool_create(
+ "txrdy_pool", &phba->pcidev->dev,
TXRDY_PAYLOAD_LEN, 16, 0);
if (phba->txrdy_payload_pool) {
phba->targetport = NULL;
@@ -7605,6 +7624,11 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
"3082 Mailbox (x%x) returned ldv:x0\n",
bf_get(lpfc_mqe_command, &pmb->u.mqe));
+ if (bf_get(lpfc_mbx_rd_conf_bbscn_def, rd_config)) {
+ phba->bbcredit_support = 1;
+ phba->sli4_hba.bbscn_params.word0 = rd_config->word8;
+ }
+
phba->sli4_hba.extents_in_use =
bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config);
phba->sli4_hba.max_cfg_param.max_xri =
@@ -8301,6 +8325,9 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
goto out_error;
}
+ /* Put list in known state in case driver load fails. */
+ INIT_LIST_HEAD(&qdesc->rqbp->rqb_buffer_list);
+
/* Create NVMET Receive Queue for data */
qdesc = lpfc_sli4_queue_alloc(phba,
phba->sli4_hba.rq_esize,