diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 285 |
1 files changed, 189 insertions, 96 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index e50c5ad252f9..4dd0f1aa09e8 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
30 | #include <linux/ctype.h> | ||
30 | 31 | ||
31 | #include <scsi/scsi.h> | 32 | #include <scsi/scsi.h> |
32 | #include <scsi/scsi_device.h> | 33 | #include <scsi/scsi_device.h> |
@@ -40,21 +41,18 @@ | |||
40 | #include "lpfc.h" | 41 | #include "lpfc.h" |
41 | #include "lpfc_logmsg.h" | 42 | #include "lpfc_logmsg.h" |
42 | #include "lpfc_crtn.h" | 43 | #include "lpfc_crtn.h" |
44 | #include "lpfc_vport.h" | ||
43 | #include "lpfc_version.h" | 45 | #include "lpfc_version.h" |
46 | #include "lpfc_vport.h" | ||
44 | 47 | ||
45 | static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); | 48 | static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); |
46 | static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); | 49 | static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); |
47 | static int lpfc_post_rcv_buf(struct lpfc_hba *); | 50 | static int lpfc_post_rcv_buf(struct lpfc_hba *); |
48 | 51 | ||
49 | static struct scsi_transport_template *lpfc_transport_template = NULL; | 52 | static struct scsi_transport_template *lpfc_transport_template = NULL; |
53 | static struct scsi_transport_template *lpfc_vport_transport_template = NULL; | ||
50 | static DEFINE_IDR(lpfc_hba_index); | 54 | static DEFINE_IDR(lpfc_hba_index); |
51 | 55 | ||
52 | int lpfc_sli_mode = 0; | ||
53 | module_param(lpfc_sli_mode, int, 0); | ||
54 | MODULE_PARM_DESC(lpfc_sli_mode, "SLI mode selector:" | ||
55 | " 0 - auto (SLI-3 if supported)," | ||
56 | " 2 - select SLI-2 even on SLI-3 capable HBAs," | ||
57 | " 3 - select SLI-3"); | ||
58 | 56 | ||
59 | 57 | ||
60 | /************************************************************************/ | 58 | /************************************************************************/ |
@@ -123,6 +121,8 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
123 | sizeof(phba->wwpn)); | 121 | sizeof(phba->wwpn)); |
124 | } | 122 | } |
125 | 123 | ||
124 | phba->sli3_options = 0x0; | ||
125 | |||
126 | /* Setup and issue mailbox READ REV command */ | 126 | /* Setup and issue mailbox READ REV command */ |
127 | lpfc_read_rev(phba, pmb); | 127 | lpfc_read_rev(phba, pmb); |
128 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | 128 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); |
@@ -136,6 +136,7 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
136 | return -ERESTART; | 136 | return -ERESTART; |
137 | } | 137 | } |
138 | 138 | ||
139 | |||
139 | /* | 140 | /* |
140 | * The value of rr must be 1 since the driver set the cv field to 1. | 141 | * The value of rr must be 1 since the driver set the cv field to 1. |
141 | * This setting requires the FW to set all revision fields. | 142 | * This setting requires the FW to set all revision fields. |
@@ -155,6 +156,7 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
155 | 156 | ||
156 | /* Save information as VPD data */ | 157 | /* Save information as VPD data */ |
157 | vp->rev.rBit = 1; | 158 | vp->rev.rBit = 1; |
159 | memcpy(&vp->sli3Feat, &mb->un.varRdRev.sli3Feat, sizeof(uint32_t)); | ||
158 | vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev; | 160 | vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev; |
159 | memcpy(vp->rev.sli1FwName, (char*) mb->un.varRdRev.sli1FwName, 16); | 161 | memcpy(vp->rev.sli1FwName, (char*) mb->un.varRdRev.sli1FwName, 16); |
160 | vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev; | 162 | vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev; |
@@ -170,6 +172,13 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
170 | vp->rev.postKernRev = mb->un.varRdRev.postKernRev; | 172 | vp->rev.postKernRev = mb->un.varRdRev.postKernRev; |
171 | vp->rev.opFwRev = mb->un.varRdRev.opFwRev; | 173 | vp->rev.opFwRev = mb->un.varRdRev.opFwRev; |
172 | 174 | ||
175 | /* If the sli feature level is less then 9, we must | ||
176 | * tear down all RPIs and VPIs on link down if NPIV | ||
177 | * is enabled. | ||
178 | */ | ||
179 | if (vp->rev.feaLevelHigh < 9) | ||
180 | phba->sli3_options |= LPFC_SLI3_VPORT_TEARDOWN; | ||
181 | |||
173 | if (lpfc_is_LC_HBA(phba->pcidev->device)) | 182 | if (lpfc_is_LC_HBA(phba->pcidev->device)) |
174 | memcpy(phba->RandomData, (char *)&mb->un.varWords[24], | 183 | memcpy(phba->RandomData, (char *)&mb->un.varWords[24], |
175 | sizeof (phba->RandomData)); | 184 | sizeof (phba->RandomData)); |
@@ -197,7 +206,7 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
197 | if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) | 206 | if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) |
198 | mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; | 207 | mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; |
199 | lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset, | 208 | lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset, |
200 | mb->un.varDmp.word_cnt); | 209 | mb->un.varDmp.word_cnt); |
201 | offset += mb->un.varDmp.word_cnt; | 210 | offset += mb->un.varDmp.word_cnt; |
202 | } while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE); | 211 | } while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE); |
203 | lpfc_parse_vpd(phba, lpfc_vpd_data, offset); | 212 | lpfc_parse_vpd(phba, lpfc_vpd_data, offset); |
@@ -240,7 +249,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
240 | mb = &pmb->mb; | 249 | mb = &pmb->mb; |
241 | 250 | ||
242 | /* Get login parameters for NID. */ | 251 | /* Get login parameters for NID. */ |
243 | lpfc_read_sparam(phba, pmb); | 252 | lpfc_read_sparam(phba, pmb, 0); |
244 | pmb->vport = vport; | 253 | pmb->vport = vport; |
245 | if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { | 254 | if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { |
246 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 255 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -431,10 +440,9 @@ lpfc_hba_down_prep(struct lpfc_hba *phba) | |||
431 | writel(0, phba->HCregaddr); | 440 | writel(0, phba->HCregaddr); |
432 | readl(phba->HCregaddr); /* flush */ | 441 | readl(phba->HCregaddr); /* flush */ |
433 | 442 | ||
434 | /* Cleanup potential discovery resources */ | 443 | list_for_each_entry(vport, &phba->port_list, listentry) { |
435 | lpfc_els_flush_rscn(vport); | 444 | lpfc_cleanup_discovery_resources(vport); |
436 | lpfc_els_flush_cmd(vport); | 445 | } |
437 | lpfc_disc_flush_list(vport); | ||
438 | 446 | ||
439 | return 0; | 447 | return 0; |
440 | } | 448 | } |
@@ -456,13 +464,17 @@ lpfc_hba_down_post(struct lpfc_hba *phba) | |||
456 | struct lpfc_dmabuf *mp, *next_mp; | 464 | struct lpfc_dmabuf *mp, *next_mp; |
457 | int i; | 465 | int i; |
458 | 466 | ||
459 | /* Cleanup preposted buffers on the ELS ring */ | 467 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) |
460 | pring = &psli->ring[LPFC_ELS_RING]; | 468 | lpfc_sli_hbqbuf_free_all(phba); |
461 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { | 469 | else { |
462 | list_del(&mp->list); | 470 | /* Cleanup preposted buffers on the ELS ring */ |
463 | pring->postbufq_cnt--; | 471 | pring = &psli->ring[LPFC_ELS_RING]; |
464 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 472 | list_for_each_entry_safe(mp, next_mp, &pring->postbufq, list) { |
465 | kfree(mp); | 473 | list_del(&mp->list); |
474 | pring->postbufq_cnt--; | ||
475 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
476 | kfree(mp); | ||
477 | } | ||
466 | } | 478 | } |
467 | 479 | ||
468 | for (i = 0; i < psli->num_rings; i++) { | 480 | for (i = 0; i < psli->num_rings; i++) { |
@@ -485,10 +497,11 @@ void | |||
485 | lpfc_handle_eratt(struct lpfc_hba *phba) | 497 | lpfc_handle_eratt(struct lpfc_hba *phba) |
486 | { | 498 | { |
487 | struct lpfc_vport *vport = phba->pport; | 499 | struct lpfc_vport *vport = phba->pport; |
488 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
489 | struct lpfc_sli *psli = &phba->sli; | 500 | struct lpfc_sli *psli = &phba->sli; |
490 | struct lpfc_sli_ring *pring; | 501 | struct lpfc_sli_ring *pring; |
502 | struct lpfc_vport *port_iterator; | ||
491 | uint32_t event_data; | 503 | uint32_t event_data; |
504 | struct Scsi_Host *shost; | ||
492 | 505 | ||
493 | /* If the pci channel is offline, ignore possible errors, | 506 | /* If the pci channel is offline, ignore possible errors, |
494 | * since we cannot communicate with the pci card anyway. */ | 507 | * since we cannot communicate with the pci card anyway. */ |
@@ -503,10 +516,17 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
503 | "Data: x%x x%x x%x\n", | 516 | "Data: x%x x%x x%x\n", |
504 | phba->brd_no, phba->work_hs, | 517 | phba->brd_no, phba->work_hs, |
505 | phba->work_status[0], phba->work_status[1]); | 518 | phba->work_status[0], phba->work_status[1]); |
506 | spin_lock_irq(shost->host_lock); | 519 | list_for_each_entry(port_iterator, &phba->port_list, |
507 | vport->fc_flag |= FC_ESTABLISH_LINK; | 520 | listentry) { |
521 | shost = lpfc_shost_from_vport(port_iterator); | ||
522 | |||
523 | spin_lock_irq(shost->host_lock); | ||
524 | port_iterator->fc_flag |= FC_ESTABLISH_LINK; | ||
525 | spin_unlock_irq(shost->host_lock); | ||
526 | } | ||
527 | spin_lock_irq(&phba->hbalock); | ||
508 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 528 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
509 | spin_unlock_irq(shost->host_lock); | 529 | spin_unlock_irq(&phba->hbalock); |
510 | 530 | ||
511 | /* | 531 | /* |
512 | * Firmware stops when it triggled erratt with HS_FFER6. | 532 | * Firmware stops when it triggled erratt with HS_FFER6. |
@@ -543,11 +563,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
543 | phba->work_status[0], phba->work_status[1]); | 563 | phba->work_status[0], phba->work_status[1]); |
544 | 564 | ||
545 | event_data = FC_REG_DUMP_EVENT; | 565 | event_data = FC_REG_DUMP_EVENT; |
566 | shost = lpfc_shost_from_vport(vport); | ||
546 | fc_host_post_vendor_event(shost, fc_get_event_number(), | 567 | fc_host_post_vendor_event(shost, fc_get_event_number(), |
547 | sizeof(event_data), (char *) &event_data, | 568 | sizeof(event_data), (char *) &event_data, |
548 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 569 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); |
549 | 570 | ||
571 | spin_lock_irq(&phba->hbalock); | ||
550 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 572 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
573 | spin_unlock_irq(&phba->hbalock); | ||
551 | lpfc_offline_prep(phba); | 574 | lpfc_offline_prep(phba); |
552 | lpfc_offline(phba); | 575 | lpfc_offline(phba); |
553 | lpfc_unblock_mgmt_io(phba); | 576 | lpfc_unblock_mgmt_io(phba); |
@@ -569,6 +592,7 @@ lpfc_handle_latt(struct lpfc_hba *phba) | |||
569 | { | 592 | { |
570 | struct lpfc_vport *vport = phba->pport; | 593 | struct lpfc_vport *vport = phba->pport; |
571 | struct lpfc_sli *psli = &phba->sli; | 594 | struct lpfc_sli *psli = &phba->sli; |
595 | struct lpfc_vport *port_iterator; | ||
572 | LPFC_MBOXQ_t *pmb; | 596 | LPFC_MBOXQ_t *pmb; |
573 | volatile uint32_t control; | 597 | volatile uint32_t control; |
574 | struct lpfc_dmabuf *mp; | 598 | struct lpfc_dmabuf *mp; |
@@ -589,7 +613,8 @@ lpfc_handle_latt(struct lpfc_hba *phba) | |||
589 | rc = -EIO; | 613 | rc = -EIO; |
590 | 614 | ||
591 | /* Cleanup any outstanding ELS commands */ | 615 | /* Cleanup any outstanding ELS commands */ |
592 | lpfc_els_flush_cmd(vport); | 616 | list_for_each_entry(port_iterator, &phba->port_list, listentry) |
617 | lpfc_els_flush_cmd(port_iterator); | ||
593 | 618 | ||
594 | psli->slistat.link_event++; | 619 | psli->slistat.link_event++; |
595 | lpfc_read_la(phba, pmb, mp); | 620 | lpfc_read_la(phba, pmb, mp); |
@@ -1023,9 +1048,8 @@ lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt, | |||
1023 | return cnt; | 1048 | return cnt; |
1024 | } | 1049 | } |
1025 | lpfc_sli_ringpostbuf_put(phba, pring, mp1); | 1050 | lpfc_sli_ringpostbuf_put(phba, pring, mp1); |
1026 | if (mp2) { | 1051 | if (mp2) |
1027 | lpfc_sli_ringpostbuf_put(phba, pring, mp2); | 1052 | lpfc_sli_ringpostbuf_put(phba, pring, mp2); |
1028 | } | ||
1029 | } | 1053 | } |
1030 | pring->missbufcnt = 0; | 1054 | pring->missbufcnt = 0; |
1031 | return 0; | 1055 | return 0; |
@@ -1175,34 +1199,45 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1175 | static void | 1199 | static void |
1176 | lpfc_establish_link_tmo(unsigned long ptr) | 1200 | lpfc_establish_link_tmo(unsigned long ptr) |
1177 | { | 1201 | { |
1178 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | 1202 | struct lpfc_hba *phba = (struct lpfc_hba *) ptr; |
1179 | struct lpfc_vport *vport = phba->pport; | 1203 | struct lpfc_vport *vport = phba->pport; |
1180 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1181 | unsigned long iflag; | 1204 | unsigned long iflag; |
1182 | 1205 | ||
1183 | |||
1184 | /* Re-establishing Link, timer expired */ | 1206 | /* Re-establishing Link, timer expired */ |
1185 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 1207 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
1186 | "%d:1300 Re-establishing Link, timer expired " | 1208 | "%d:1300 Re-establishing Link, timer expired " |
1187 | "Data: x%x x%x\n", | 1209 | "Data: x%x x%x\n", |
1188 | phba->brd_no, vport->fc_flag, | 1210 | phba->brd_no, vport->fc_flag, |
1189 | vport->port_state); | 1211 | vport->port_state); |
1190 | spin_lock_irqsave(shost->host_lock, iflag); | 1212 | list_for_each_entry(vport, &phba->port_list, listentry) { |
1191 | vport->fc_flag &= ~FC_ESTABLISH_LINK; | 1213 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1192 | spin_unlock_irqrestore(shost->host_lock, iflag); | 1214 | |
1215 | spin_lock_irqsave(shost->host_lock, iflag); | ||
1216 | vport->fc_flag &= ~FC_ESTABLISH_LINK; | ||
1217 | spin_unlock_irqrestore(shost->host_lock, iflag); | ||
1218 | } | ||
1219 | } | ||
1220 | |||
1221 | void | ||
1222 | lpfc_stop_vport_timers(struct lpfc_vport *vport) | ||
1223 | { | ||
1224 | del_timer_sync(&vport->els_tmofunc); | ||
1225 | del_timer_sync(&vport->fc_fdmitmo); | ||
1226 | lpfc_can_disctmo(vport); | ||
1227 | return; | ||
1193 | } | 1228 | } |
1194 | 1229 | ||
1195 | static void | 1230 | static void |
1196 | lpfc_stop_timer(struct lpfc_hba *phba) | 1231 | lpfc_stop_phba_timers(struct lpfc_hba *phba) |
1197 | { | 1232 | { |
1198 | struct lpfc_vport *vport = phba->pport; | 1233 | struct lpfc_vport *vport; |
1199 | 1234 | ||
1200 | del_timer_sync(&phba->fcp_poll_timer); | 1235 | del_timer_sync(&phba->fcp_poll_timer); |
1201 | del_timer_sync(&phba->fc_estabtmo); | 1236 | del_timer_sync(&phba->fc_estabtmo); |
1202 | del_timer_sync(&vport->els_tmofunc); | 1237 | list_for_each_entry(vport, &phba->port_list, listentry) |
1203 | del_timer_sync(&vport->fc_fdmitmo); | 1238 | lpfc_stop_vport_timers(vport); |
1204 | del_timer_sync(&vport->fc_disctmo); | ||
1205 | del_timer_sync(&phba->sli.mbox_tmo); | 1239 | del_timer_sync(&phba->sli.mbox_tmo); |
1240 | del_timer_sync(&phba->fabric_block_timer); | ||
1206 | return; | 1241 | return; |
1207 | } | 1242 | } |
1208 | 1243 | ||
@@ -1210,7 +1245,6 @@ int | |||
1210 | lpfc_online(struct lpfc_hba *phba) | 1245 | lpfc_online(struct lpfc_hba *phba) |
1211 | { | 1246 | { |
1212 | struct lpfc_vport *vport = phba->pport; | 1247 | struct lpfc_vport *vport = phba->pport; |
1213 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1214 | 1248 | ||
1215 | if (!phba) | 1249 | if (!phba) |
1216 | return 0; | 1250 | return 0; |
@@ -1234,9 +1268,14 @@ lpfc_online(struct lpfc_hba *phba) | |||
1234 | return 1; | 1268 | return 1; |
1235 | } | 1269 | } |
1236 | 1270 | ||
1237 | spin_lock_irq(shost->host_lock); | 1271 | list_for_each_entry(vport, &phba->port_list, listentry) { |
1238 | vport->fc_flag &= ~FC_OFFLINE_MODE; | 1272 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1239 | spin_unlock_irq(shost->host_lock); | 1273 | spin_lock_irq(shost->host_lock); |
1274 | vport->fc_flag &= ~FC_OFFLINE_MODE; | ||
1275 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | ||
1276 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | ||
1277 | spin_unlock_irq(shost->host_lock); | ||
1278 | } | ||
1240 | 1279 | ||
1241 | lpfc_unblock_mgmt_io(phba); | 1280 | lpfc_unblock_mgmt_io(phba); |
1242 | return 0; | 1281 | return 0; |
@@ -1288,31 +1327,37 @@ lpfc_offline(struct lpfc_hba *phba) | |||
1288 | { | 1327 | { |
1289 | struct lpfc_vport *vport = phba->pport; | 1328 | struct lpfc_vport *vport = phba->pport; |
1290 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1329 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1291 | unsigned long iflag; | 1330 | struct lpfc_vport *port_iterator; |
1292 | 1331 | ||
1293 | if (vport->fc_flag & FC_OFFLINE_MODE) | 1332 | if (vport->fc_flag & FC_OFFLINE_MODE) |
1294 | return; | 1333 | return; |
1295 | 1334 | ||
1296 | /* stop all timers associated with this hba */ | 1335 | /* stop all timers associated with this hba */ |
1297 | lpfc_stop_timer(phba); | 1336 | lpfc_stop_phba_timers(phba); |
1337 | list_for_each_entry(port_iterator, &phba->port_list, listentry) { | ||
1338 | port_iterator->work_port_events = 0; | ||
1339 | } | ||
1298 | 1340 | ||
1299 | lpfc_printf_log(phba, | 1341 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, |
1300 | KERN_WARNING, | ||
1301 | LOG_INIT, | ||
1302 | "%d:0460 Bring Adapter offline\n", | 1342 | "%d:0460 Bring Adapter offline\n", |
1303 | phba->brd_no); | 1343 | phba->brd_no); |
1304 | 1344 | ||
1305 | /* Bring down the SLI Layer and cleanup. The HBA is offline | 1345 | /* Bring down the SLI Layer and cleanup. The HBA is offline |
1306 | now. */ | 1346 | now. */ |
1307 | lpfc_sli_hba_down(phba); | 1347 | lpfc_sli_hba_down(phba); |
1308 | lpfc_cleanup(vport); | 1348 | spin_lock_irq(&phba->hbalock); |
1309 | spin_lock_irqsave(shost->host_lock, iflag); | ||
1310 | spin_lock(&phba->hbalock); | ||
1311 | phba->work_ha = 0; | 1349 | phba->work_ha = 0; |
1312 | vport->work_port_events = 0; | ||
1313 | vport->fc_flag |= FC_OFFLINE_MODE; | 1350 | vport->fc_flag |= FC_OFFLINE_MODE; |
1314 | spin_unlock(&phba->hbalock); | 1351 | spin_unlock_irq(&phba->hbalock); |
1315 | spin_unlock_irqrestore(shost->host_lock, iflag); | 1352 | list_for_each_entry(port_iterator, &phba->port_list, listentry) { |
1353 | shost = lpfc_shost_from_vport(port_iterator); | ||
1354 | |||
1355 | lpfc_cleanup(port_iterator); | ||
1356 | spin_lock_irq(shost->host_lock); | ||
1357 | vport->work_port_events = 0; | ||
1358 | vport->fc_flag |= FC_OFFLINE_MODE; | ||
1359 | spin_unlock_irq(shost->host_lock); | ||
1360 | } | ||
1316 | } | 1361 | } |
1317 | 1362 | ||
1318 | /****************************************************************************** | 1363 | /****************************************************************************** |
@@ -1332,7 +1377,7 @@ lpfc_scsi_free(struct lpfc_hba *phba) | |||
1332 | list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { | 1377 | list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { |
1333 | list_del(&sb->list); | 1378 | list_del(&sb->list); |
1334 | pci_pool_free(phba->lpfc_scsi_dma_buf_pool, sb->data, | 1379 | pci_pool_free(phba->lpfc_scsi_dma_buf_pool, sb->data, |
1335 | sb->dma_handle); | 1380 | sb->dma_handle); |
1336 | kfree(sb); | 1381 | kfree(sb); |
1337 | phba->total_scsi_bufs--; | 1382 | phba->total_scsi_bufs--; |
1338 | } | 1383 | } |
@@ -1349,8 +1394,9 @@ lpfc_scsi_free(struct lpfc_hba *phba) | |||
1349 | return 0; | 1394 | return 0; |
1350 | } | 1395 | } |
1351 | 1396 | ||
1397 | |||
1352 | struct lpfc_vport * | 1398 | struct lpfc_vport * |
1353 | lpfc_create_port(struct lpfc_hba *phba, int instance) | 1399 | lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport) |
1354 | { | 1400 | { |
1355 | struct lpfc_vport *vport; | 1401 | struct lpfc_vport *vport; |
1356 | struct Scsi_Host *shost; | 1402 | struct Scsi_Host *shost; |
@@ -1364,6 +1410,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance) | |||
1364 | vport->phba = phba; | 1410 | vport->phba = phba; |
1365 | 1411 | ||
1366 | vport->load_flag |= FC_LOADING; | 1412 | vport->load_flag |= FC_LOADING; |
1413 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | ||
1367 | 1414 | ||
1368 | shost->unique_id = instance; | 1415 | shost->unique_id = instance; |
1369 | shost->max_id = LPFC_MAX_TARGET; | 1416 | shost->max_id = LPFC_MAX_TARGET; |
@@ -1376,7 +1423,13 @@ lpfc_create_port(struct lpfc_hba *phba, int instance) | |||
1376 | * max xri value determined in hba setup. | 1423 | * max xri value determined in hba setup. |
1377 | */ | 1424 | */ |
1378 | shost->can_queue = phba->cfg_hba_queue_depth - 10; | 1425 | shost->can_queue = phba->cfg_hba_queue_depth - 10; |
1379 | shost->transportt = lpfc_transport_template; | 1426 | if (fc_vport != NULL) { |
1427 | shost->transportt = lpfc_vport_transport_template; | ||
1428 | vport->port_type = LPFC_NPIV_PORT; | ||
1429 | } else { | ||
1430 | shost->transportt = lpfc_transport_template; | ||
1431 | vport->port_type = LPFC_PHYSICAL_PORT; | ||
1432 | } | ||
1380 | 1433 | ||
1381 | /* Initialize all internally managed lists. */ | 1434 | /* Initialize all internally managed lists. */ |
1382 | INIT_LIST_HEAD(&vport->fc_nodes); | 1435 | INIT_LIST_HEAD(&vport->fc_nodes); |
@@ -1384,22 +1437,28 @@ lpfc_create_port(struct lpfc_hba *phba, int instance) | |||
1384 | 1437 | ||
1385 | init_timer(&vport->fc_disctmo); | 1438 | init_timer(&vport->fc_disctmo); |
1386 | vport->fc_disctmo.function = lpfc_disc_timeout; | 1439 | vport->fc_disctmo.function = lpfc_disc_timeout; |
1387 | vport->fc_disctmo.data = (unsigned long) vport; | 1440 | vport->fc_disctmo.data = (unsigned long)vport; |
1388 | 1441 | ||
1389 | init_timer(&vport->fc_fdmitmo); | 1442 | init_timer(&vport->fc_fdmitmo); |
1390 | vport->fc_fdmitmo.function = lpfc_fdmi_tmo; | 1443 | vport->fc_fdmitmo.function = lpfc_fdmi_tmo; |
1391 | vport->fc_fdmitmo.data = (unsigned long) vport; | 1444 | vport->fc_fdmitmo.data = (unsigned long)vport; |
1392 | 1445 | ||
1393 | init_timer(&vport->els_tmofunc); | 1446 | init_timer(&vport->els_tmofunc); |
1394 | vport->els_tmofunc.function = lpfc_els_timeout; | 1447 | vport->els_tmofunc.function = lpfc_els_timeout; |
1395 | vport->els_tmofunc.data = (unsigned long) vport; | 1448 | vport->els_tmofunc.data = (unsigned long)vport; |
1396 | 1449 | ||
1397 | error = scsi_add_host(shost, &phba->pcidev->dev); | 1450 | if (fc_vport != NULL) { |
1451 | error = scsi_add_host(shost, &fc_vport->dev); | ||
1452 | } else { | ||
1453 | error = scsi_add_host(shost, &phba->pcidev->dev); | ||
1454 | } | ||
1398 | if (error) | 1455 | if (error) |
1399 | goto out_put_shost; | 1456 | goto out_put_shost; |
1400 | 1457 | ||
1458 | if (!shost->shost_classdev.kobj.dentry) | ||
1459 | goto out_put_shost; | ||
1460 | |||
1401 | list_add_tail(&vport->listentry, &phba->port_list); | 1461 | list_add_tail(&vport->listentry, &phba->port_list); |
1402 | scsi_scan_host(shost); | ||
1403 | return vport; | 1462 | return vport; |
1404 | 1463 | ||
1405 | out_put_shost: | 1464 | out_put_shost: |
@@ -1411,19 +1470,40 @@ out: | |||
1411 | void | 1470 | void |
1412 | destroy_port(struct lpfc_vport *vport) | 1471 | destroy_port(struct lpfc_vport *vport) |
1413 | { | 1472 | { |
1414 | lpfc_cleanup(vport); | 1473 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1415 | list_del(&vport->listentry); | 1474 | struct lpfc_hba *phba = vport->phba; |
1475 | |||
1476 | kfree(vport->vname); | ||
1416 | lpfc_free_sysfs_attr(vport); | 1477 | lpfc_free_sysfs_attr(vport); |
1417 | fc_remove_host(lpfc_shost_from_vport(vport)); | 1478 | |
1418 | scsi_remove_host(lpfc_shost_from_vport(vport)); | 1479 | fc_remove_host(shost); |
1480 | scsi_remove_host(shost); | ||
1481 | |||
1482 | spin_lock_irq(&phba->hbalock); | ||
1483 | list_del_init(&vport->listentry); | ||
1484 | spin_unlock_irq(&phba->hbalock); | ||
1485 | |||
1486 | lpfc_cleanup(vport); | ||
1419 | return; | 1487 | return; |
1420 | } | 1488 | } |
1421 | 1489 | ||
1490 | int | ||
1491 | lpfc_get_instance(void) | ||
1492 | { | ||
1493 | int instance = 0; | ||
1494 | |||
1495 | /* Assign an unused number */ | ||
1496 | if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL)) | ||
1497 | return -1; | ||
1498 | if (idr_get_new(&lpfc_hba_index, NULL, &instance)) | ||
1499 | return -1; | ||
1500 | return instance; | ||
1501 | } | ||
1502 | |||
1422 | static void | 1503 | static void |
1423 | lpfc_remove_device(struct lpfc_vport *vport) | 1504 | lpfc_remove_device(struct lpfc_vport *vport) |
1424 | { | 1505 | { |
1425 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1506 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1426 | struct lpfc_hba *phba = vport->phba; | ||
1427 | 1507 | ||
1428 | lpfc_free_sysfs_attr(vport); | 1508 | lpfc_free_sysfs_attr(vport); |
1429 | 1509 | ||
@@ -1433,8 +1513,6 @@ lpfc_remove_device(struct lpfc_vport *vport) | |||
1433 | 1513 | ||
1434 | fc_remove_host(shost); | 1514 | fc_remove_host(shost); |
1435 | scsi_remove_host(shost); | 1515 | scsi_remove_host(shost); |
1436 | |||
1437 | kthread_stop(phba->worker_thread); | ||
1438 | } | 1516 | } |
1439 | 1517 | ||
1440 | void lpfc_scan_start(struct Scsi_Host *shost) | 1518 | void lpfc_scan_start(struct Scsi_Host *shost) |
@@ -1442,7 +1520,7 @@ void lpfc_scan_start(struct Scsi_Host *shost) | |||
1442 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 1520 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1443 | struct lpfc_hba *phba = vport->phba; | 1521 | struct lpfc_hba *phba = vport->phba; |
1444 | 1522 | ||
1445 | if (lpfc_alloc_sysfs_attr(vport)) | 1523 | if (lpfc_sli_hba_setup(phba)) |
1446 | goto error; | 1524 | goto error; |
1447 | 1525 | ||
1448 | /* | 1526 | /* |
@@ -1486,6 +1564,14 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) | |||
1486 | return 0; | 1564 | return 0; |
1487 | 1565 | ||
1488 | finished: | 1566 | finished: |
1567 | lpfc_host_attrib_init(shost); | ||
1568 | return 1; | ||
1569 | } | ||
1570 | |||
1571 | void lpfc_host_attrib_init(struct Scsi_Host *shost) | ||
1572 | { | ||
1573 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
1574 | struct lpfc_hba *phba = vport->phba; | ||
1489 | /* | 1575 | /* |
1490 | * Set fixed host attributes. Must done after lpfc_sli_hba_setup(). | 1576 | * Set fixed host attributes. Must done after lpfc_sli_hba_setup(). |
1491 | */ | 1577 | */ |
@@ -1499,7 +1585,8 @@ finished: | |||
1499 | fc_host_supported_fc4s(shost)[2] = 1; | 1585 | fc_host_supported_fc4s(shost)[2] = 1; |
1500 | fc_host_supported_fc4s(shost)[7] = 1; | 1586 | fc_host_supported_fc4s(shost)[7] = 1; |
1501 | 1587 | ||
1502 | lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(shost)); | 1588 | lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost), |
1589 | sizeof fc_host_symbolic_name(shost)); | ||
1503 | 1590 | ||
1504 | fc_host_supported_speeds(shost) = 0; | 1591 | fc_host_supported_speeds(shost) = 0; |
1505 | if (phba->lmt & LMT_10Gb) | 1592 | if (phba->lmt & LMT_10Gb) |
@@ -1521,11 +1608,10 @@ finished: | |||
1521 | fc_host_active_fc4s(shost)[2] = 1; | 1608 | fc_host_active_fc4s(shost)[2] = 1; |
1522 | fc_host_active_fc4s(shost)[7] = 1; | 1609 | fc_host_active_fc4s(shost)[7] = 1; |
1523 | 1610 | ||
1611 | fc_host_max_npiv_vports(shost) = phba->max_vpi; | ||
1524 | spin_lock_irq(shost->host_lock); | 1612 | spin_lock_irq(shost->host_lock); |
1525 | vport->fc_flag &= ~FC_LOADING; | 1613 | vport->fc_flag &= ~FC_LOADING; |
1526 | spin_unlock_irq(shost->host_lock); | 1614 | spin_unlock_irq(shost->host_lock); |
1527 | |||
1528 | return 1; | ||
1529 | } | 1615 | } |
1530 | 1616 | ||
1531 | static int __devinit | 1617 | static int __devinit |
@@ -1555,20 +1641,17 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1555 | phba->pcidev = pdev; | 1641 | phba->pcidev = pdev; |
1556 | 1642 | ||
1557 | /* Assign an unused board number */ | 1643 | /* Assign an unused board number */ |
1558 | if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL)) | 1644 | if ((phba->brd_no = lpfc_get_instance()) < 0) |
1559 | goto out_free_phba; | ||
1560 | |||
1561 | error = idr_get_new(&lpfc_hba_index, NULL, &phba->brd_no); | ||
1562 | if (error) | ||
1563 | goto out_free_phba; | 1645 | goto out_free_phba; |
1564 | 1646 | ||
1565 | INIT_LIST_HEAD(&phba->port_list); | 1647 | INIT_LIST_HEAD(&phba->port_list); |
1566 | 1648 | INIT_LIST_HEAD(&phba->hbq_buffer_list); | |
1567 | /* | 1649 | /* |
1568 | * Get all the module params for configuring this host and then | 1650 | * Get all the module params for configuring this host and then |
1569 | * establish the host. | 1651 | * establish the host. |
1570 | */ | 1652 | */ |
1571 | lpfc_get_cfgparam(phba); | 1653 | lpfc_get_cfgparam(phba); |
1654 | phba->max_vpi = LPFC_MAX_VPI; | ||
1572 | 1655 | ||
1573 | /* Initialize timers used by driver */ | 1656 | /* Initialize timers used by driver */ |
1574 | init_timer(&phba->fc_estabtmo); | 1657 | init_timer(&phba->fc_estabtmo); |
@@ -1581,6 +1664,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1581 | init_timer(&phba->fcp_poll_timer); | 1664 | init_timer(&phba->fcp_poll_timer); |
1582 | phba->fcp_poll_timer.function = lpfc_poll_timeout; | 1665 | phba->fcp_poll_timer.function = lpfc_poll_timeout; |
1583 | phba->fcp_poll_timer.data = (unsigned long) phba; | 1666 | phba->fcp_poll_timer.data = (unsigned long) phba; |
1667 | init_timer(&phba->fabric_block_timer); | ||
1668 | phba->fabric_block_timer.function = lpfc_fabric_block_timeout; | ||
1669 | phba->fabric_block_timer.data = (unsigned long) phba; | ||
1584 | 1670 | ||
1585 | pci_set_master(pdev); | 1671 | pci_set_master(pdev); |
1586 | retval = pci_set_mwi(pdev); | 1672 | retval = pci_set_mwi(pdev); |
@@ -1696,15 +1782,17 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1696 | spin_lock_init(&phba->scsi_buf_list_lock); | 1782 | spin_lock_init(&phba->scsi_buf_list_lock); |
1697 | INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); | 1783 | INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); |
1698 | 1784 | ||
1699 | vport = lpfc_create_port(phba, phba->brd_no); | 1785 | /* Initialize list of fabric iocbs */ |
1786 | INIT_LIST_HEAD(&phba->fabric_iocb_list); | ||
1787 | |||
1788 | vport = lpfc_create_port(phba, phba->brd_no, NULL); | ||
1700 | if (!vport) | 1789 | if (!vport) |
1701 | goto out_kthread_stop; | 1790 | goto out_kthread_stop; |
1702 | 1791 | ||
1703 | shost = lpfc_shost_from_vport(vport); | 1792 | shost = lpfc_shost_from_vport(vport); |
1704 | vport->port_type = LPFC_PHYSICAL_PORT; | ||
1705 | phba->pport = vport; | 1793 | phba->pport = vport; |
1706 | 1794 | ||
1707 | pci_set_drvdata(pdev, lpfc_shost_from_vport(vport)); | 1795 | pci_set_drvdata(pdev, shost); |
1708 | 1796 | ||
1709 | if (phba->cfg_use_msi) { | 1797 | if (phba->cfg_use_msi) { |
1710 | error = pci_enable_msi(phba->pcidev); | 1798 | error = pci_enable_msi(phba->pcidev); |
@@ -1720,7 +1808,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1720 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1808 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1721 | "%d:0451 Enable interrupt handler failed\n", | 1809 | "%d:0451 Enable interrupt handler failed\n", |
1722 | phba->brd_no); | 1810 | phba->brd_no); |
1723 | goto out_destroy_port; | 1811 | goto out_disable_msi; |
1724 | } | 1812 | } |
1725 | 1813 | ||
1726 | phba->MBslimaddr = phba->slim_memmap_p; | 1814 | phba->MBslimaddr = phba->slim_memmap_p; |
@@ -1729,10 +1817,10 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1729 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; | 1817 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; |
1730 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; | 1818 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; |
1731 | 1819 | ||
1732 | error = lpfc_sli_hba_setup(phba); | 1820 | if (lpfc_alloc_sysfs_attr(vport)) |
1733 | if (error) | ||
1734 | goto out_free_irq; | 1821 | goto out_free_irq; |
1735 | 1822 | ||
1823 | scsi_scan_host(shost); | ||
1736 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) { | 1824 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) { |
1737 | spin_lock_irq(shost->host_lock); | 1825 | spin_lock_irq(shost->host_lock); |
1738 | lpfc_poll_start_timer(phba); | 1826 | lpfc_poll_start_timer(phba); |
@@ -1742,11 +1830,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1742 | return 0; | 1830 | return 0; |
1743 | 1831 | ||
1744 | out_free_irq: | 1832 | out_free_irq: |
1745 | lpfc_stop_timer(phba); | 1833 | lpfc_stop_phba_timers(phba); |
1746 | phba->pport->work_port_events = 0; | 1834 | phba->pport->work_port_events = 0; |
1747 | free_irq(phba->pcidev->irq, phba); | 1835 | free_irq(phba->pcidev->irq, phba); |
1836 | out_disable_msi: | ||
1748 | pci_disable_msi(phba->pcidev); | 1837 | pci_disable_msi(phba->pcidev); |
1749 | out_destroy_port: | ||
1750 | destroy_port(vport); | 1838 | destroy_port(vport); |
1751 | out_kthread_stop: | 1839 | out_kthread_stop: |
1752 | kthread_stop(phba->worker_thread); | 1840 | kthread_stop(phba->worker_thread); |
@@ -1786,9 +1874,9 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
1786 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 1874 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
1787 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | 1875 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1788 | struct lpfc_hba *phba = vport->phba; | 1876 | struct lpfc_hba *phba = vport->phba; |
1789 | 1877 | struct lpfc_vport *port_iterator; | |
1790 | vport->load_flag |= FC_UNLOADING; | 1878 | list_for_each_entry(port_iterator, &phba->port_list, listentry) |
1791 | lpfc_remove_device(vport); | 1879 | port_iterator->load_flag |= FC_UNLOADING; |
1792 | 1880 | ||
1793 | /* | 1881 | /* |
1794 | * Bring down the SLI Layer. This step disable all interrupts, | 1882 | * Bring down the SLI Layer. This step disable all interrupts, |
@@ -1798,7 +1886,7 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
1798 | lpfc_sli_hba_down(phba); | 1886 | lpfc_sli_hba_down(phba); |
1799 | lpfc_sli_brdrestart(phba); | 1887 | lpfc_sli_brdrestart(phba); |
1800 | 1888 | ||
1801 | lpfc_stop_timer(phba); | 1889 | lpfc_stop_phba_timers(phba); |
1802 | 1890 | ||
1803 | kthread_stop(phba->worker_thread); | 1891 | kthread_stop(phba->worker_thread); |
1804 | 1892 | ||
@@ -1806,7 +1894,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
1806 | free_irq(phba->pcidev->irq, phba); | 1894 | free_irq(phba->pcidev->irq, phba); |
1807 | pci_disable_msi(phba->pcidev); | 1895 | pci_disable_msi(phba->pcidev); |
1808 | 1896 | ||
1809 | vport->work_port_events = 0; | ||
1810 | destroy_port(vport); | 1897 | destroy_port(vport); |
1811 | 1898 | ||
1812 | pci_set_drvdata(pdev, NULL); | 1899 | pci_set_drvdata(pdev, NULL); |
@@ -1892,13 +1979,14 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
1892 | pci_set_master(pdev); | 1979 | pci_set_master(pdev); |
1893 | 1980 | ||
1894 | /* Re-establishing Link */ | 1981 | /* Re-establishing Link */ |
1895 | spin_lock_irq(&phba->hbalock); | ||
1896 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; | ||
1897 | spin_unlock_irq(&phba->hbalock); | ||
1898 | spin_lock_irq(host->host_lock); | 1982 | spin_lock_irq(host->host_lock); |
1899 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 1983 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; |
1900 | spin_unlock_irq(host->host_lock); | 1984 | spin_unlock_irq(host->host_lock); |
1901 | 1985 | ||
1986 | spin_lock_irq(&phba->hbalock); | ||
1987 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | ||
1988 | spin_unlock_irq(&phba->hbalock); | ||
1989 | |||
1902 | 1990 | ||
1903 | /* Take device offline; this will perform cleanup */ | 1991 | /* Take device offline; this will perform cleanup */ |
1904 | lpfc_offline(phba); | 1992 | lpfc_offline(phba); |
@@ -2020,11 +2108,15 @@ lpfc_init(void) | |||
2020 | 2108 | ||
2021 | lpfc_transport_template = | 2109 | lpfc_transport_template = |
2022 | fc_attach_transport(&lpfc_transport_functions); | 2110 | fc_attach_transport(&lpfc_transport_functions); |
2023 | if (!lpfc_transport_template) | 2111 | lpfc_vport_transport_template = |
2112 | fc_attach_transport(&lpfc_vport_transport_functions); | ||
2113 | if (!lpfc_transport_template || !lpfc_vport_transport_template) | ||
2024 | return -ENOMEM; | 2114 | return -ENOMEM; |
2025 | error = pci_register_driver(&lpfc_driver); | 2115 | error = pci_register_driver(&lpfc_driver); |
2026 | if (error) | 2116 | if (error) { |
2027 | fc_release_transport(lpfc_transport_template); | 2117 | fc_release_transport(lpfc_transport_template); |
2118 | fc_release_transport(lpfc_vport_transport_template); | ||
2119 | } | ||
2028 | 2120 | ||
2029 | return error; | 2121 | return error; |
2030 | } | 2122 | } |
@@ -2034,6 +2126,7 @@ lpfc_exit(void) | |||
2034 | { | 2126 | { |
2035 | pci_unregister_driver(&lpfc_driver); | 2127 | pci_unregister_driver(&lpfc_driver); |
2036 | fc_release_transport(lpfc_transport_template); | 2128 | fc_release_transport(lpfc_transport_template); |
2129 | fc_release_transport(lpfc_vport_transport_template); | ||
2037 | } | 2130 | } |
2038 | 2131 | ||
2039 | module_init(lpfc_init); | 2132 | module_init(lpfc_init); |