|
@@ -1633,6 +1633,39 @@ out:
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command.
|
|
|
+ * @phba: pointer to lpfc hba data structure.
|
|
|
+ * @mboxq: pointer to mailbox data structure.
|
|
|
+ *
|
|
|
+ * This function handles completion of init vpi mailbox command.
|
|
|
+ */
|
|
|
+static void
|
|
|
+lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
|
|
+{
|
|
|
+ struct lpfc_vport *vport = mboxq->vport;
|
|
|
+ if (mboxq->u.mb.mbxStatus) {
|
|
|
+ lpfc_printf_vlog(vport, KERN_ERR,
|
|
|
+ LOG_MBOX,
|
|
|
+ "2609 Init VPI mailbox failed 0x%x\n",
|
|
|
+ mboxq->u.mb.mbxStatus);
|
|
|
+ mempool_free(mboxq, phba->mbox_mem_pool);
|
|
|
+ lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI;
|
|
|
+
|
|
|
+ if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
|
|
|
+ lpfc_initial_fdisc(vport);
|
|
|
+ else {
|
|
|
+ lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
|
|
|
+ lpfc_printf_vlog(vport, KERN_ERR,
|
|
|
+ LOG_ELS,
|
|
|
+ "2606 No NPIV Fabric support\n");
|
|
|
+ }
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* lpfc_start_fdiscs - send fdiscs for each vports on this port.
|
|
|
* @phba: pointer to lpfc hba data structure.
|
|
@@ -1645,6 +1678,8 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
|
|
|
{
|
|
|
struct lpfc_vport **vports;
|
|
|
int i;
|
|
|
+ LPFC_MBOXQ_t *mboxq;
|
|
|
+ int rc;
|
|
|
|
|
|
vports = lpfc_create_vport_work_array(phba);
|
|
|
if (vports != NULL) {
|
|
@@ -1662,6 +1697,29 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
|
|
|
FC_VPORT_LINKDOWN);
|
|
|
continue;
|
|
|
}
|
|
|
+ if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) {
|
|
|
+ mboxq = mempool_alloc(phba->mbox_mem_pool,
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!mboxq) {
|
|
|
+ lpfc_printf_vlog(vports[i], KERN_ERR,
|
|
|
+ LOG_MBOX, "2607 Failed to allocate "
|
|
|
+ "init_vpi mailbox\n");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ lpfc_init_vpi(phba, mboxq, vports[i]->vpi);
|
|
|
+ mboxq->vport = vports[i];
|
|
|
+ mboxq->mbox_cmpl = lpfc_init_vpi_cmpl;
|
|
|
+ rc = lpfc_sli_issue_mbox(phba, mboxq,
|
|
|
+ MBX_NOWAIT);
|
|
|
+ if (rc == MBX_NOT_FINISHED) {
|
|
|
+ lpfc_printf_vlog(vports[i], KERN_ERR,
|
|
|
+ LOG_MBOX, "2608 Failed to issue "
|
|
|
+ "init_vpi mailbox\n");
|
|
|
+ mempool_free(mboxq,
|
|
|
+ phba->mbox_mem_pool);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
|
|
|
lpfc_initial_fdisc(vports[i]);
|
|
|
else {
|
|
@@ -2242,13 +2300,15 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
|
|
|
LPFC_MBOXQ_t *pmb = NULL;
|
|
|
MAILBOX_t *mb;
|
|
|
struct static_vport_info *vport_info;
|
|
|
- int rc, i;
|
|
|
+ int rc = 0, i;
|
|
|
struct fc_vport_identifiers vport_id;
|
|
|
struct fc_vport *new_fc_vport;
|
|
|
struct Scsi_Host *shost;
|
|
|
struct lpfc_vport *vport;
|
|
|
uint16_t offset = 0;
|
|
|
uint8_t *vport_buff;
|
|
|
+ struct lpfc_dmabuf *mp;
|
|
|
+ uint32_t byte_count = 0;
|
|
|
|
|
|
pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
|
|
if (!pmb) {
|
|
@@ -2271,7 +2331,9 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
|
|
|
|
|
|
vport_buff = (uint8_t *) vport_info;
|
|
|
do {
|
|
|
- lpfc_dump_static_vport(phba, pmb, offset);
|
|
|
+ if (lpfc_dump_static_vport(phba, pmb, offset))
|
|
|
+ goto out;
|
|
|
+
|
|
|
pmb->vport = phba->pport;
|
|
|
rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO);
|
|
|
|
|
@@ -2284,17 +2346,30 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- if (mb->un.varDmp.word_cnt >
|
|
|
- sizeof(struct static_vport_info) - offset)
|
|
|
- mb->un.varDmp.word_cnt =
|
|
|
- sizeof(struct static_vport_info) - offset;
|
|
|
-
|
|
|
- lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
|
|
|
- vport_buff + offset,
|
|
|
- mb->un.varDmp.word_cnt);
|
|
|
- offset += mb->un.varDmp.word_cnt;
|
|
|
+ if (phba->sli_rev == LPFC_SLI_REV4) {
|
|
|
+ byte_count = pmb->u.mqe.un.mb_words[5];
|
|
|
+ mp = (struct lpfc_dmabuf *) pmb->context2;
|
|
|
+ if (byte_count > sizeof(struct static_vport_info) -
|
|
|
+ offset)
|
|
|
+ byte_count = sizeof(struct static_vport_info)
|
|
|
+ - offset;
|
|
|
+ memcpy(vport_buff + offset, mp->virt, byte_count);
|
|
|
+ offset += byte_count;
|
|
|
+ } else {
|
|
|
+ if (mb->un.varDmp.word_cnt >
|
|
|
+ sizeof(struct static_vport_info) - offset)
|
|
|
+ mb->un.varDmp.word_cnt =
|
|
|
+ sizeof(struct static_vport_info)
|
|
|
+ - offset;
|
|
|
+ byte_count = mb->un.varDmp.word_cnt;
|
|
|
+ lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
|
|
|
+ vport_buff + offset,
|
|
|
+ byte_count);
|
|
|
+
|
|
|
+ offset += byte_count;
|
|
|
+ }
|
|
|
|
|
|
- } while (mb->un.varDmp.word_cnt &&
|
|
|
+ } while (byte_count &&
|
|
|
offset < sizeof(struct static_vport_info));
|
|
|
|
|
|
|
|
@@ -2336,16 +2411,15 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
|
|
|
}
|
|
|
|
|
|
out:
|
|
|
- /*
|
|
|
- * If this is timed out command, setting NULL to context2 tell SLI
|
|
|
- * layer not to use this buffer.
|
|
|
- */
|
|
|
- spin_lock_irq(&phba->hbalock);
|
|
|
- pmb->context2 = NULL;
|
|
|
- spin_unlock_irq(&phba->hbalock);
|
|
|
kfree(vport_info);
|
|
|
- if (rc != MBX_TIMEOUT)
|
|
|
+ if (rc != MBX_TIMEOUT) {
|
|
|
+ if (pmb->context2) {
|
|
|
+ mp = (struct lpfc_dmabuf *) pmb->context2;
|
|
|
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
|
|
+ kfree(mp);
|
|
|
+ }
|
|
|
mempool_free(pmb, phba->mbox_mem_pool);
|
|
|
+ }
|
|
|
|
|
|
return;
|
|
|
}
|