summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_vport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_vport.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c93
1 files changed, 57 insertions, 36 deletions
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index dcb415e717c3..9fad7663c117 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -125,15 +125,26 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport)
pmb->vport = vport;
rc = lpfc_sli_issue_mbox_wait(phba, pmb, phba->fc_ratov * 2);
if (rc != MBX_SUCCESS) {
- lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT | LOG_VPORT,
- "1818 VPort failed init, mbxCmd x%x "
- "READ_SPARM mbxStatus x%x, rc = x%x\n",
- mb->mbxCommand, mb->mbxStatus, rc);
- lpfc_mbuf_free(phba, mp->virt, mp->phys);
- kfree(mp);
- if (rc != MBX_TIMEOUT)
- mempool_free(pmb, phba->mbox_mem_pool);
- return -EIO;
+ if (signal_pending(current)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT | LOG_VPORT,
+ "1830 Signal aborted mbxCmd x%x\n",
+ mb->mbxCommand);
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ if (rc != MBX_TIMEOUT)
+ mempool_free(pmb, phba->mbox_mem_pool);
+ return -EINTR;
+ } else {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT | LOG_VPORT,
+ "1818 VPort failed init, mbxCmd x%x "
+ "READ_SPARM mbxStatus x%x, rc = x%x\n",
+ mb->mbxCommand, mb->mbxStatus, rc);
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
+ kfree(mp);
+ if (rc != MBX_TIMEOUT)
+ mempool_free(pmb, phba->mbox_mem_pool);
+ return -EIO;
+ }
}
memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm));
@@ -204,6 +215,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
int instance;
int vpi;
int rc = VPORT_ERROR;
+ int status;
if ((phba->sli_rev < 3) ||
!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
@@ -248,13 +260,19 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
vport->vpi = vpi;
lpfc_debugfs_initialize(vport);
- if (lpfc_vport_sparm(phba, vport)) {
- lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
- "1813 Create VPORT failed. "
- "Cannot get sparam\n");
+ if ((status = lpfc_vport_sparm(phba, vport))) {
+ if (status == -EINTR) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1831 Create VPORT Interrupted.\n");
+ rc = VPORT_ERROR;
+ } else {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1813 Create VPORT failed. "
+ "Cannot get sparam\n");
+ rc = VPORT_NORESOURCES;
+ }
lpfc_free_vpi(phba, vpi);
destroy_port(vport);
- rc = VPORT_NORESOURCES;
goto error_out;
}
@@ -427,7 +445,6 @@ int
lpfc_vport_delete(struct fc_vport *fc_vport)
{
struct lpfc_nodelist *ndlp = NULL;
- struct lpfc_nodelist *next_ndlp;
struct Scsi_Host *shost = (struct Scsi_Host *) fc_vport->shost;
struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
struct lpfc_hba *phba = vport->phba;
@@ -482,8 +499,18 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
- phba->link_state >= LPFC_LINK_UP) {
-
+ phba->link_state >= LPFC_LINK_UP) {
+ if (vport->cfg_enable_da_id) {
+ timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
+ if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0))
+ while (vport->ct_flags && timeout)
+ timeout = schedule_timeout(timeout);
+ else
+ lpfc_printf_log(vport->phba, KERN_WARNING,
+ LOG_VPORT,
+ "1829 CT command failed to "
+ "delete objects on fabric. \n");
+ }
/* First look for the Fabric ndlp */
ndlp = lpfc_findnode_did(vport, Fabric_DID);
if (!ndlp) {
@@ -503,23 +530,20 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
}
skip_logo:
+ lpfc_cleanup(vport);
lpfc_sli_host_down(vport);
- list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
- lpfc_disc_state_machine(vport, ndlp, NULL,
- NLP_EVT_DEVICE_RECOVERY);
- lpfc_disc_state_machine(vport, ndlp, NULL,
- NLP_EVT_DEVICE_RM);
- }
-
lpfc_stop_vport_timers(vport);
lpfc_unreg_all_rpis(vport);
- lpfc_unreg_default_rpis(vport);
- /*
- * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) does the
- * scsi_host_put() to release the vport.
- */
- lpfc_mbx_unreg_vpi(vport);
+
+ if (!(phba->pport->load_flag & FC_UNLOADING)) {
+ lpfc_unreg_default_rpis(vport);
+ /*
+ * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi)
+ * does the scsi_host_put() to release the vport.
+ */
+ lpfc_mbx_unreg_vpi(vport);
+ }
lpfc_free_vpi(phba, vport->vpi);
vport->work_port_events = 0;
@@ -532,16 +556,13 @@ skip_logo:
return VPORT_OK;
}
-EXPORT_SYMBOL(lpfc_vport_create);
-EXPORT_SYMBOL(lpfc_vport_delete);
-
struct lpfc_vport **
lpfc_create_vport_work_array(struct lpfc_hba *phba)
{
struct lpfc_vport *port_iterator;
struct lpfc_vport **vports;
int index = 0;
- vports = kzalloc(LPFC_MAX_VPORTS * sizeof(struct lpfc_vport *),
+ vports = kzalloc((phba->max_vpi + 1) * sizeof(struct lpfc_vport *),
GFP_KERNEL);
if (vports == NULL)
return NULL;
@@ -560,12 +581,12 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba)
}
void
-lpfc_destroy_vport_work_array(struct lpfc_vport **vports)
+lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports)
{
int i;
if (vports == NULL)
return;
- for (i=0; vports[i] != NULL && i < LPFC_MAX_VPORTS; i++)
+ for (i=0; vports[i] != NULL && i <= phba->max_vpi; i++)
scsi_host_put(lpfc_shost_from_vport(vports[i]));
kfree(vports);
}
OpenPOWER on IntegriCloud