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 | |
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')
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 114 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 47 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 51 |
7 files changed, 168 insertions, 56 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index d982ac78009e..8cca3619c745 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -312,6 +312,7 @@ struct lpfc_vport { | |||
312 | #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ | 312 | #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ |
313 | #define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */ | 313 | #define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */ |
314 | #define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */ | 314 | #define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */ |
315 | #define FC_VPORT_NEEDS_INIT_VPI 0x200000 /* Need to INIT_VPI before FDISC */ | ||
315 | 316 | ||
316 | uint32_t ct_flags; | 317 | uint32_t ct_flags; |
317 | #define FC_CT_RFF_ID 0x1 /* RFF_ID accepted by switch */ | 318 | #define FC_CT_RFF_ID 0x1 /* RFF_ID accepted by switch */ |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index d52aa3310551..48943d344143 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -25,7 +25,7 @@ void lpfc_down_link(struct lpfc_hba *, LPFC_MBOXQ_t *); | |||
25 | void lpfc_sli_read_link_ste(struct lpfc_hba *); | 25 | void lpfc_sli_read_link_ste(struct lpfc_hba *); |
26 | void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t); | 26 | void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t); |
27 | void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); | 27 | void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); |
28 | void lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); | 28 | int lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); |
29 | int lpfc_dump_fcoe_param(struct lpfc_hba *, struct lpfcMboxq *); | 29 | int lpfc_dump_fcoe_param(struct lpfc_hba *, struct lpfcMboxq *); |
30 | void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); | 30 | void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); |
31 | void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | 31 | void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); |
@@ -184,7 +184,7 @@ int lpfc_mbox_dev_check(struct lpfc_hba *); | |||
184 | int lpfc_mbox_tmo_val(struct lpfc_hba *, int); | 184 | int lpfc_mbox_tmo_val(struct lpfc_hba *, int); |
185 | void lpfc_init_vfi(struct lpfcMboxq *, struct lpfc_vport *); | 185 | void lpfc_init_vfi(struct lpfcMboxq *, struct lpfc_vport *); |
186 | void lpfc_reg_vfi(struct lpfcMboxq *, struct lpfc_vport *, dma_addr_t); | 186 | void lpfc_reg_vfi(struct lpfcMboxq *, struct lpfc_vport *, dma_addr_t); |
187 | void lpfc_init_vpi(struct lpfcMboxq *, uint16_t); | 187 | void lpfc_init_vpi(struct lpfc_hba *, struct lpfcMboxq *, uint16_t); |
188 | void lpfc_unreg_vfi(struct lpfcMboxq *, uint16_t); | 188 | void lpfc_unreg_vfi(struct lpfcMboxq *, uint16_t); |
189 | void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *); | 189 | void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *); |
190 | void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t); | 190 | void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index cc4b6ba9e4d5..491c53fd1ca4 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 | } |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index a7f32ed256bd..18bc5905c44c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -2155,6 +2155,8 @@ lpfc_online(struct lpfc_hba *phba) | |||
2155 | vports[i]->fc_flag &= ~FC_OFFLINE_MODE; | 2155 | vports[i]->fc_flag &= ~FC_OFFLINE_MODE; |
2156 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 2156 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) |
2157 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 2157 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
2158 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
2159 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | ||
2158 | spin_unlock_irq(shost->host_lock); | 2160 | spin_unlock_irq(shost->host_lock); |
2159 | } | 2161 | } |
2160 | lpfc_destroy_vport_work_array(phba, vports); | 2162 | lpfc_destroy_vport_work_array(phba, vports); |
@@ -7371,6 +7373,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
7371 | /* Perform post initialization setup */ | 7373 | /* Perform post initialization setup */ |
7372 | lpfc_post_init_setup(phba); | 7374 | lpfc_post_init_setup(phba); |
7373 | 7375 | ||
7376 | /* Check if there are static vports to be created. */ | ||
7377 | lpfc_create_static_vport(phba); | ||
7378 | |||
7374 | return 0; | 7379 | return 0; |
7375 | 7380 | ||
7376 | out_disable_intr: | 7381 | out_disable_intr: |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 245945f2f3a0..a776f86bbcc3 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -52,30 +52,51 @@ | |||
52 | * This routine prepares the mailbox command for dumping list of static | 52 | * This routine prepares the mailbox command for dumping list of static |
53 | * vports to be created. | 53 | * vports to be created. |
54 | **/ | 54 | **/ |
55 | void | 55 | int |
56 | lpfc_dump_static_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, | 56 | lpfc_dump_static_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, |
57 | uint16_t offset) | 57 | uint16_t offset) |
58 | { | 58 | { |
59 | MAILBOX_t *mb; | 59 | MAILBOX_t *mb; |
60 | void *ctx; | 60 | struct lpfc_dmabuf *mp; |
61 | 61 | ||
62 | mb = &pmb->u.mb; | 62 | mb = &pmb->u.mb; |
63 | ctx = pmb->context2; | ||
64 | 63 | ||
65 | /* Setup to dump vport info region */ | 64 | /* Setup to dump vport info region */ |
66 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); | 65 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); |
67 | mb->mbxCommand = MBX_DUMP_MEMORY; | 66 | mb->mbxCommand = MBX_DUMP_MEMORY; |
68 | mb->un.varDmp.cv = 1; | ||
69 | mb->un.varDmp.type = DMP_NV_PARAMS; | 67 | mb->un.varDmp.type = DMP_NV_PARAMS; |
70 | mb->un.varDmp.entry_index = offset; | 68 | mb->un.varDmp.entry_index = offset; |
71 | mb->un.varDmp.region_id = DMP_REGION_VPORT; | 69 | mb->un.varDmp.region_id = DMP_REGION_VPORT; |
72 | mb->un.varDmp.word_cnt = DMP_RSP_SIZE/sizeof(uint32_t); | ||
73 | mb->un.varDmp.co = 0; | ||
74 | mb->un.varDmp.resp_offset = 0; | ||
75 | pmb->context2 = ctx; | ||
76 | mb->mbxOwner = OWN_HOST; | 70 | mb->mbxOwner = OWN_HOST; |
77 | 71 | ||
78 | return; | 72 | /* For SLI3 HBAs data is embedded in mailbox */ |
73 | if (phba->sli_rev != LPFC_SLI_REV4) { | ||
74 | mb->un.varDmp.cv = 1; | ||
75 | mb->un.varDmp.word_cnt = DMP_RSP_SIZE/sizeof(uint32_t); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | /* For SLI4 HBAs driver need to allocate memory */ | ||
80 | mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | ||
81 | if (mp) | ||
82 | mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys); | ||
83 | |||
84 | if (!mp || !mp->virt) { | ||
85 | kfree(mp); | ||
86 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
87 | "2605 lpfc_dump_static_vport: memory" | ||
88 | " allocation failed\n"); | ||
89 | return 1; | ||
90 | } | ||
91 | memset(mp->virt, 0, LPFC_BPL_SIZE); | ||
92 | INIT_LIST_HEAD(&mp->list); | ||
93 | /* save address for completion */ | ||
94 | pmb->context2 = (uint8_t *) mp; | ||
95 | mb->un.varWords[3] = putPaddrLow(mp->phys); | ||
96 | mb->un.varWords[4] = putPaddrHigh(mp->phys); | ||
97 | mb->un.varDmp.sli4_length = sizeof(struct static_vport_info); | ||
98 | |||
99 | return 0; | ||
79 | } | 100 | } |
80 | 101 | ||
81 | /** | 102 | /** |
@@ -1805,6 +1826,7 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) | |||
1805 | 1826 | ||
1806 | /** | 1827 | /** |
1807 | * lpfc_init_vpi - Initialize the INIT_VPI mailbox command | 1828 | * lpfc_init_vpi - Initialize the INIT_VPI mailbox command |
1829 | * @phba: pointer to the hba structure to init the VPI for. | ||
1808 | * @mbox: pointer to lpfc mbox command to initialize. | 1830 | * @mbox: pointer to lpfc mbox command to initialize. |
1809 | * @vpi: VPI to be initialized. | 1831 | * @vpi: VPI to be initialized. |
1810 | * | 1832 | * |
@@ -1815,11 +1837,14 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) | |||
1815 | * successful virtual NPort login. | 1837 | * successful virtual NPort login. |
1816 | **/ | 1838 | **/ |
1817 | void | 1839 | void |
1818 | lpfc_init_vpi(struct lpfcMboxq *mbox, uint16_t vpi) | 1840 | lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi) |
1819 | { | 1841 | { |
1820 | memset(mbox, 0, sizeof(*mbox)); | 1842 | memset(mbox, 0, sizeof(*mbox)); |
1821 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI); | 1843 | bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI); |
1822 | bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi, vpi); | 1844 | bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi, |
1845 | vpi + phba->vpi_base); | ||
1846 | bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi, | ||
1847 | phba->pport->vfi + phba->vfi_base); | ||
1823 | } | 1848 | } |
1824 | 1849 | ||
1825 | /** | 1850 | /** |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a0f973e7acb3..62f98b343b8b 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -11341,7 +11341,7 @@ lpfc_sli4_init_vpi(struct lpfc_hba *phba, uint16_t vpi) | |||
11341 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 11341 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
11342 | if (!mboxq) | 11342 | if (!mboxq) |
11343 | return -ENOMEM; | 11343 | return -ENOMEM; |
11344 | lpfc_init_vpi(mboxq, vpi); | 11344 | lpfc_init_vpi(phba, mboxq, vpi); |
11345 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI); | 11345 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI); |
11346 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); | 11346 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); |
11347 | if (rc != MBX_TIMEOUT) | 11347 | if (rc != MBX_TIMEOUT) |
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index e0b49922193e..9ba2a01c0e38 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -313,22 +313,6 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
313 | goto error_out; | 313 | goto error_out; |
314 | } | 314 | } |
315 | 315 | ||
316 | /* | ||
317 | * In SLI4, the vpi must be activated before it can be used | ||
318 | * by the port. | ||
319 | */ | ||
320 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
321 | rc = lpfc_sli4_init_vpi(phba, vpi); | ||
322 | if (rc) { | ||
323 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, | ||
324 | "1838 Failed to INIT_VPI on vpi %d " | ||
325 | "status %d\n", vpi, rc); | ||
326 | rc = VPORT_NORESOURCES; | ||
327 | lpfc_free_vpi(phba, vpi); | ||
328 | goto error_out; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | /* Assign an unused board number */ | 316 | /* Assign an unused board number */ |
333 | if ((instance = lpfc_get_instance()) < 0) { | 317 | if ((instance = lpfc_get_instance()) < 0) { |
334 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, | 318 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, |
@@ -367,12 +351,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
367 | goto error_out; | 351 | goto error_out; |
368 | } | 352 | } |
369 | 353 | ||
370 | memcpy(vport->fc_portname.u.wwn, vport->fc_sparam.portName.u.wwn, 8); | 354 | u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn); |
371 | memcpy(vport->fc_nodename.u.wwn, vport->fc_sparam.nodeName.u.wwn, 8); | 355 | u64_to_wwn(fc_vport->port_name, vport->fc_portname.u.wwn); |
372 | if (fc_vport->node_name != 0) | ||
373 | u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn); | ||
374 | if (fc_vport->port_name != 0) | ||
375 | u64_to_wwn(fc_vport->port_name, vport->fc_portname.u.wwn); | ||
376 | 356 | ||
377 | memcpy(&vport->fc_sparam.portName, vport->fc_portname.u.wwn, 8); | 357 | memcpy(&vport->fc_sparam.portName, vport->fc_portname.u.wwn, 8); |
378 | memcpy(&vport->fc_sparam.nodeName, vport->fc_nodename.u.wwn, 8); | 358 | memcpy(&vport->fc_sparam.nodeName, vport->fc_nodename.u.wwn, 8); |
@@ -404,7 +384,34 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
404 | *(struct lpfc_vport **)fc_vport->dd_data = vport; | 384 | *(struct lpfc_vport **)fc_vport->dd_data = vport; |
405 | vport->fc_vport = fc_vport; | 385 | vport->fc_vport = fc_vport; |
406 | 386 | ||
387 | /* | ||
388 | * In SLI4, the vpi must be activated before it can be used | ||
389 | * by the port. | ||
390 | */ | ||
391 | if ((phba->sli_rev == LPFC_SLI_REV4) && | ||
392 | (pport->vfi_state & LPFC_VFI_REGISTERED)) { | ||
393 | rc = lpfc_sli4_init_vpi(phba, vpi); | ||
394 | if (rc) { | ||
395 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, | ||
396 | "1838 Failed to INIT_VPI on vpi %d " | ||
397 | "status %d\n", vpi, rc); | ||
398 | rc = VPORT_NORESOURCES; | ||
399 | lpfc_free_vpi(phba, vpi); | ||
400 | goto error_out; | ||
401 | } | ||
402 | } else if (phba->sli_rev == LPFC_SLI_REV4) { | ||
403 | /* | ||
404 | * Driver cannot INIT_VPI now. Set the flags to | ||
405 | * init_vpi when reg_vfi complete. | ||
406 | */ | ||
407 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | ||
408 | lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN); | ||
409 | rc = VPORT_OK; | ||
410 | goto out; | ||
411 | } | ||
412 | |||
407 | if ((phba->link_state < LPFC_LINK_UP) || | 413 | if ((phba->link_state < LPFC_LINK_UP) || |
414 | (pport->port_state < LPFC_FABRIC_CFG_LINK) || | ||
408 | (phba->fc_topology == TOPOLOGY_LOOP)) { | 415 | (phba->fc_topology == TOPOLOGY_LOOP)) { |
409 | lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN); | 416 | lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN); |
410 | rc = VPORT_OK; | 417 | rc = VPORT_OK; |