diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-07-19 10:01:26 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-08-22 18:51:58 -0400 |
commit | 1c6834a7e85715a4ac07c1cac25a1950040decb0 (patch) | |
tree | 66e859591d7bb25b26c10999ee861ac86701cfbc /drivers/scsi/lpfc/lpfc_hbadisc.c | |
parent | 32b9793fe6ff09a85f36b8bd7d6ff214653a7497 (diff) |
[SCSI] lpfc 8.3.4: NPIV vport fixes
NPIV vport fixes
- Fixed static vport creation on SLI4 HBAs
- Fixed vport create sending init_vpi before REG_VFI
- Fix unable to create vports on SLI4 HBA's Port2
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 114 |
1 files changed, 94 insertions, 20 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index cc4b6ba9e4d..491c53fd1ca 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1634,6 +1634,39 @@ out: | |||
1634 | } | 1634 | } |
1635 | 1635 | ||
1636 | /** | 1636 | /** |
1637 | * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command. | ||
1638 | * @phba: pointer to lpfc hba data structure. | ||
1639 | * @mboxq: pointer to mailbox data structure. | ||
1640 | * | ||
1641 | * This function handles completion of init vpi mailbox command. | ||
1642 | */ | ||
1643 | static void | ||
1644 | lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1645 | { | ||
1646 | struct lpfc_vport *vport = mboxq->vport; | ||
1647 | if (mboxq->u.mb.mbxStatus) { | ||
1648 | lpfc_printf_vlog(vport, KERN_ERR, | ||
1649 | LOG_MBOX, | ||
1650 | "2609 Init VPI mailbox failed 0x%x\n", | ||
1651 | mboxq->u.mb.mbxStatus); | ||
1652 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1653 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
1654 | return; | ||
1655 | } | ||
1656 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; | ||
1657 | |||
1658 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | ||
1659 | lpfc_initial_fdisc(vport); | ||
1660 | else { | ||
1661 | lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP); | ||
1662 | lpfc_printf_vlog(vport, KERN_ERR, | ||
1663 | LOG_ELS, | ||
1664 | "2606 No NPIV Fabric support\n"); | ||
1665 | } | ||
1666 | return; | ||
1667 | } | ||
1668 | |||
1669 | /** | ||
1637 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. | 1670 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. |
1638 | * @phba: pointer to lpfc hba data structure. | 1671 | * @phba: pointer to lpfc hba data structure. |
1639 | * | 1672 | * |
@@ -1645,6 +1678,8 @@ lpfc_start_fdiscs(struct lpfc_hba *phba) | |||
1645 | { | 1678 | { |
1646 | struct lpfc_vport **vports; | 1679 | struct lpfc_vport **vports; |
1647 | int i; | 1680 | int i; |
1681 | LPFC_MBOXQ_t *mboxq; | ||
1682 | int rc; | ||
1648 | 1683 | ||
1649 | vports = lpfc_create_vport_work_array(phba); | 1684 | vports = lpfc_create_vport_work_array(phba); |
1650 | if (vports != NULL) { | 1685 | if (vports != NULL) { |
@@ -1662,6 +1697,29 @@ lpfc_start_fdiscs(struct lpfc_hba *phba) | |||
1662 | FC_VPORT_LINKDOWN); | 1697 | FC_VPORT_LINKDOWN); |
1663 | continue; | 1698 | continue; |
1664 | } | 1699 | } |
1700 | if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) { | ||
1701 | mboxq = mempool_alloc(phba->mbox_mem_pool, | ||
1702 | GFP_KERNEL); | ||
1703 | if (!mboxq) { | ||
1704 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1705 | LOG_MBOX, "2607 Failed to allocate " | ||
1706 | "init_vpi mailbox\n"); | ||
1707 | continue; | ||
1708 | } | ||
1709 | lpfc_init_vpi(phba, mboxq, vports[i]->vpi); | ||
1710 | mboxq->vport = vports[i]; | ||
1711 | mboxq->mbox_cmpl = lpfc_init_vpi_cmpl; | ||
1712 | rc = lpfc_sli_issue_mbox(phba, mboxq, | ||
1713 | MBX_NOWAIT); | ||
1714 | if (rc == MBX_NOT_FINISHED) { | ||
1715 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1716 | LOG_MBOX, "2608 Failed to issue " | ||
1717 | "init_vpi mailbox\n"); | ||
1718 | mempool_free(mboxq, | ||
1719 | phba->mbox_mem_pool); | ||
1720 | } | ||
1721 | continue; | ||
1722 | } | ||
1665 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1723 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
1666 | lpfc_initial_fdisc(vports[i]); | 1724 | lpfc_initial_fdisc(vports[i]); |
1667 | else { | 1725 | else { |
@@ -2242,13 +2300,15 @@ lpfc_create_static_vport(struct lpfc_hba *phba) | |||
2242 | LPFC_MBOXQ_t *pmb = NULL; | 2300 | LPFC_MBOXQ_t *pmb = NULL; |
2243 | MAILBOX_t *mb; | 2301 | MAILBOX_t *mb; |
2244 | struct static_vport_info *vport_info; | 2302 | struct static_vport_info *vport_info; |
2245 | int rc, i; | 2303 | int rc = 0, i; |
2246 | struct fc_vport_identifiers vport_id; | 2304 | struct fc_vport_identifiers vport_id; |
2247 | struct fc_vport *new_fc_vport; | 2305 | struct fc_vport *new_fc_vport; |
2248 | struct Scsi_Host *shost; | 2306 | struct Scsi_Host *shost; |
2249 | struct lpfc_vport *vport; | 2307 | struct lpfc_vport *vport; |
2250 | uint16_t offset = 0; | 2308 | uint16_t offset = 0; |
2251 | uint8_t *vport_buff; | 2309 | uint8_t *vport_buff; |
2310 | struct lpfc_dmabuf *mp; | ||
2311 | uint32_t byte_count = 0; | ||
2252 | 2312 | ||
2253 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 2313 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
2254 | if (!pmb) { | 2314 | if (!pmb) { |
@@ -2271,7 +2331,9 @@ lpfc_create_static_vport(struct lpfc_hba *phba) | |||
2271 | 2331 | ||
2272 | vport_buff = (uint8_t *) vport_info; | 2332 | vport_buff = (uint8_t *) vport_info; |
2273 | do { | 2333 | do { |
2274 | lpfc_dump_static_vport(phba, pmb, offset); | 2334 | if (lpfc_dump_static_vport(phba, pmb, offset)) |
2335 | goto out; | ||
2336 | |||
2275 | pmb->vport = phba->pport; | 2337 | pmb->vport = phba->pport; |
2276 | rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO); | 2338 | rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO); |
2277 | 2339 | ||
@@ -2284,17 +2346,30 @@ lpfc_create_static_vport(struct lpfc_hba *phba) | |||
2284 | goto out; | 2346 | goto out; |
2285 | } | 2347 | } |
2286 | 2348 | ||
2287 | if (mb->un.varDmp.word_cnt > | 2349 | if (phba->sli_rev == LPFC_SLI_REV4) { |
2288 | sizeof(struct static_vport_info) - offset) | 2350 | byte_count = pmb->u.mqe.un.mb_words[5]; |
2289 | mb->un.varDmp.word_cnt = | 2351 | mp = (struct lpfc_dmabuf *) pmb->context2; |
2290 | sizeof(struct static_vport_info) - offset; | 2352 | if (byte_count > sizeof(struct static_vport_info) - |
2291 | 2353 | offset) | |
2292 | lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, | 2354 | byte_count = sizeof(struct static_vport_info) |
2293 | vport_buff + offset, | 2355 | - offset; |
2294 | mb->un.varDmp.word_cnt); | 2356 | memcpy(vport_buff + offset, mp->virt, byte_count); |
2295 | offset += mb->un.varDmp.word_cnt; | 2357 | offset += byte_count; |
2358 | } else { | ||
2359 | if (mb->un.varDmp.word_cnt > | ||
2360 | sizeof(struct static_vport_info) - offset) | ||
2361 | mb->un.varDmp.word_cnt = | ||
2362 | sizeof(struct static_vport_info) | ||
2363 | - offset; | ||
2364 | byte_count = mb->un.varDmp.word_cnt; | ||
2365 | lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, | ||
2366 | vport_buff + offset, | ||
2367 | byte_count); | ||
2368 | |||
2369 | offset += byte_count; | ||
2370 | } | ||
2296 | 2371 | ||
2297 | } while (mb->un.varDmp.word_cnt && | 2372 | } while (byte_count && |
2298 | offset < sizeof(struct static_vport_info)); | 2373 | offset < sizeof(struct static_vport_info)); |
2299 | 2374 | ||
2300 | 2375 | ||
@@ -2336,16 +2411,15 @@ lpfc_create_static_vport(struct lpfc_hba *phba) | |||
2336 | } | 2411 | } |
2337 | 2412 | ||
2338 | out: | 2413 | out: |
2339 | /* | ||
2340 | * If this is timed out command, setting NULL to context2 tell SLI | ||
2341 | * layer not to use this buffer. | ||
2342 | */ | ||
2343 | spin_lock_irq(&phba->hbalock); | ||
2344 | pmb->context2 = NULL; | ||
2345 | spin_unlock_irq(&phba->hbalock); | ||
2346 | kfree(vport_info); | 2414 | kfree(vport_info); |
2347 | if (rc != MBX_TIMEOUT) | 2415 | if (rc != MBX_TIMEOUT) { |
2416 | if (pmb->context2) { | ||
2417 | mp = (struct lpfc_dmabuf *) pmb->context2; | ||
2418 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
2419 | kfree(mp); | ||
2420 | } | ||
2348 | mempool_free(pmb, phba->mbox_mem_pool); | 2421 | mempool_free(pmb, phba->mbox_mem_pool); |
2422 | } | ||
2349 | 2423 | ||
2350 | return; | 2424 | return; |
2351 | } | 2425 | } |