diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 576 |
1 files changed, 319 insertions, 257 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index dcb4ba0ecee1..e11c4cda0f3f 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -49,6 +49,8 @@ static int lpfc_post_rcv_buf(struct lpfc_hba *); | |||
49 | static struct scsi_transport_template *lpfc_transport_template = NULL; | 49 | static struct scsi_transport_template *lpfc_transport_template = NULL; |
50 | static DEFINE_IDR(lpfc_hba_index); | 50 | static DEFINE_IDR(lpfc_hba_index); |
51 | 51 | ||
52 | |||
53 | |||
52 | /************************************************************************/ | 54 | /************************************************************************/ |
53 | /* */ | 55 | /* */ |
54 | /* lpfc_config_port_prep */ | 56 | /* lpfc_config_port_prep */ |
@@ -61,7 +63,7 @@ static DEFINE_IDR(lpfc_hba_index); | |||
61 | /* */ | 63 | /* */ |
62 | /************************************************************************/ | 64 | /************************************************************************/ |
63 | int | 65 | int |
64 | lpfc_config_port_prep(struct lpfc_hba * phba) | 66 | lpfc_config_port_prep(struct lpfc_hba *phba) |
65 | { | 67 | { |
66 | lpfc_vpd_t *vp = &phba->vpd; | 68 | lpfc_vpd_t *vp = &phba->vpd; |
67 | int i = 0, rc; | 69 | int i = 0, rc; |
@@ -75,12 +77,12 @@ lpfc_config_port_prep(struct lpfc_hba * phba) | |||
75 | 77 | ||
76 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 78 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
77 | if (!pmb) { | 79 | if (!pmb) { |
78 | phba->hba_state = LPFC_HBA_ERROR; | 80 | phba->link_state = LPFC_HBA_ERROR; |
79 | return -ENOMEM; | 81 | return -ENOMEM; |
80 | } | 82 | } |
81 | 83 | ||
82 | mb = &pmb->mb; | 84 | mb = &pmb->mb; |
83 | phba->hba_state = LPFC_INIT_MBX_CMDS; | 85 | phba->link_state = LPFC_INIT_MBX_CMDS; |
84 | 86 | ||
85 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { | 87 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { |
86 | if (init_key) { | 88 | if (init_key) { |
@@ -112,7 +114,9 @@ lpfc_config_port_prep(struct lpfc_hba * phba) | |||
112 | return -ERESTART; | 114 | return -ERESTART; |
113 | } | 115 | } |
114 | memcpy(phba->wwnn, (char *)mb->un.varRDnvp.nodename, | 116 | memcpy(phba->wwnn, (char *)mb->un.varRDnvp.nodename, |
115 | sizeof (mb->un.varRDnvp.nodename)); | 117 | sizeof(phba->wwnn)); |
118 | memcpy(phba->wwpn, (char *)mb->un.varRDnvp.portname, | ||
119 | sizeof(phba->wwpn)); | ||
116 | } | 120 | } |
117 | 121 | ||
118 | /* Setup and issue mailbox READ REV command */ | 122 | /* Setup and issue mailbox READ REV command */ |
@@ -212,37 +216,24 @@ out_free_mbox: | |||
212 | /* */ | 216 | /* */ |
213 | /************************************************************************/ | 217 | /************************************************************************/ |
214 | int | 218 | int |
215 | lpfc_config_port_post(struct lpfc_hba * phba) | 219 | lpfc_config_port_post(struct lpfc_hba *phba) |
216 | { | 220 | { |
221 | struct lpfc_vport *vport = phba->pport; | ||
217 | LPFC_MBOXQ_t *pmb; | 222 | LPFC_MBOXQ_t *pmb; |
218 | MAILBOX_t *mb; | 223 | MAILBOX_t *mb; |
219 | struct lpfc_dmabuf *mp; | 224 | struct lpfc_dmabuf *mp; |
220 | struct lpfc_sli *psli = &phba->sli; | 225 | struct lpfc_sli *psli = &phba->sli; |
221 | uint32_t status, timeout; | 226 | uint32_t status, timeout; |
222 | int i, j, rc; | 227 | int i, j; |
228 | int rc; | ||
223 | 229 | ||
224 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 230 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
225 | if (!pmb) { | 231 | if (!pmb) { |
226 | phba->hba_state = LPFC_HBA_ERROR; | 232 | phba->link_state = LPFC_HBA_ERROR; |
227 | return -ENOMEM; | 233 | return -ENOMEM; |
228 | } | 234 | } |
229 | mb = &pmb->mb; | 235 | mb = &pmb->mb; |
230 | 236 | ||
231 | lpfc_config_link(phba, pmb); | ||
232 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | ||
233 | if (rc != MBX_SUCCESS) { | ||
234 | lpfc_printf_log(phba, | ||
235 | KERN_ERR, | ||
236 | LOG_INIT, | ||
237 | "%d:0447 Adapter failed init, mbxCmd x%x " | ||
238 | "CONFIG_LINK mbxStatus x%x\n", | ||
239 | phba->brd_no, | ||
240 | mb->mbxCommand, mb->mbxStatus); | ||
241 | phba->hba_state = LPFC_HBA_ERROR; | ||
242 | mempool_free( pmb, phba->mbox_mem_pool); | ||
243 | return -EIO; | ||
244 | } | ||
245 | |||
246 | /* Get login parameters for NID. */ | 237 | /* Get login parameters for NID. */ |
247 | lpfc_read_sparam(phba, pmb); | 238 | lpfc_read_sparam(phba, pmb); |
248 | if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { | 239 | if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { |
@@ -253,7 +244,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
253 | "READ_SPARM mbxStatus x%x\n", | 244 | "READ_SPARM mbxStatus x%x\n", |
254 | phba->brd_no, | 245 | phba->brd_no, |
255 | mb->mbxCommand, mb->mbxStatus); | 246 | mb->mbxCommand, mb->mbxStatus); |
256 | phba->hba_state = LPFC_HBA_ERROR; | 247 | phba->link_state = LPFC_HBA_ERROR; |
257 | mp = (struct lpfc_dmabuf *) pmb->context1; | 248 | mp = (struct lpfc_dmabuf *) pmb->context1; |
258 | mempool_free( pmb, phba->mbox_mem_pool); | 249 | mempool_free( pmb, phba->mbox_mem_pool); |
259 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 250 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
@@ -263,25 +254,27 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
263 | 254 | ||
264 | mp = (struct lpfc_dmabuf *) pmb->context1; | 255 | mp = (struct lpfc_dmabuf *) pmb->context1; |
265 | 256 | ||
266 | memcpy(&phba->fc_sparam, mp->virt, sizeof (struct serv_parm)); | 257 | memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm)); |
267 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 258 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
268 | kfree(mp); | 259 | kfree(mp); |
269 | pmb->context1 = NULL; | 260 | pmb->context1 = NULL; |
270 | 261 | ||
271 | if (phba->cfg_soft_wwnn) | 262 | if (phba->cfg_soft_wwnn) |
272 | u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn); | 263 | u64_to_wwn(phba->cfg_soft_wwnn, |
264 | vport->fc_sparam.nodeName.u.wwn); | ||
273 | if (phba->cfg_soft_wwpn) | 265 | if (phba->cfg_soft_wwpn) |
274 | u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); | 266 | u64_to_wwn(phba->cfg_soft_wwpn, |
275 | memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName, | 267 | vport->fc_sparam.portName.u.wwn); |
268 | memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName, | ||
276 | sizeof (struct lpfc_name)); | 269 | sizeof (struct lpfc_name)); |
277 | memcpy(&phba->fc_portname, &phba->fc_sparam.portName, | 270 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, |
278 | sizeof (struct lpfc_name)); | 271 | sizeof (struct lpfc_name)); |
279 | /* If no serial number in VPD data, use low 6 bytes of WWNN */ | 272 | /* If no serial number in VPD data, use low 6 bytes of WWNN */ |
280 | /* This should be consolidated into parse_vpd ? - mr */ | 273 | /* This should be consolidated into parse_vpd ? - mr */ |
281 | if (phba->SerialNumber[0] == 0) { | 274 | if (phba->SerialNumber[0] == 0) { |
282 | uint8_t *outptr; | 275 | uint8_t *outptr; |
283 | 276 | ||
284 | outptr = &phba->fc_nodename.u.s.IEEE[0]; | 277 | outptr = &vport->fc_nodename.u.s.IEEE[0]; |
285 | for (i = 0; i < 12; i++) { | 278 | for (i = 0; i < 12; i++) { |
286 | status = *outptr++; | 279 | status = *outptr++; |
287 | j = ((status & 0xf0) >> 4); | 280 | j = ((status & 0xf0) >> 4); |
@@ -311,7 +304,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
311 | "READ_CONFIG, mbxStatus x%x\n", | 304 | "READ_CONFIG, mbxStatus x%x\n", |
312 | phba->brd_no, | 305 | phba->brd_no, |
313 | mb->mbxCommand, mb->mbxStatus); | 306 | mb->mbxCommand, mb->mbxStatus); |
314 | phba->hba_state = LPFC_HBA_ERROR; | 307 | phba->link_state = LPFC_HBA_ERROR; |
315 | mempool_free( pmb, phba->mbox_mem_pool); | 308 | mempool_free( pmb, phba->mbox_mem_pool); |
316 | return -EIO; | 309 | return -EIO; |
317 | } | 310 | } |
@@ -348,7 +341,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
348 | phba->cfg_link_speed = LINK_SPEED_AUTO; | 341 | phba->cfg_link_speed = LINK_SPEED_AUTO; |
349 | } | 342 | } |
350 | 343 | ||
351 | phba->hba_state = LPFC_LINK_DOWN; | 344 | phba->link_state = LPFC_LINK_DOWN; |
352 | 345 | ||
353 | /* Only process IOCBs on ring 0 till hba_state is READY */ | 346 | /* Only process IOCBs on ring 0 till hba_state is READY */ |
354 | if (psli->ring[psli->extra_ring].cmdringaddr) | 347 | if (psli->ring[psli->extra_ring].cmdringaddr) |
@@ -362,7 +355,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
362 | lpfc_post_rcv_buf(phba); | 355 | lpfc_post_rcv_buf(phba); |
363 | 356 | ||
364 | /* Enable appropriate host interrupts */ | 357 | /* Enable appropriate host interrupts */ |
365 | spin_lock_irq(phba->host->host_lock); | 358 | spin_lock_irq(&phba->hbalock); |
366 | status = readl(phba->HCregaddr); | 359 | status = readl(phba->HCregaddr); |
367 | status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA; | 360 | status |= HC_MBINT_ENA | HC_ERINT_ENA | HC_LAINT_ENA; |
368 | if (psli->num_rings > 0) | 361 | if (psli->num_rings > 0) |
@@ -380,13 +373,13 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
380 | 373 | ||
381 | writel(status, phba->HCregaddr); | 374 | writel(status, phba->HCregaddr); |
382 | readl(phba->HCregaddr); /* flush */ | 375 | readl(phba->HCregaddr); /* flush */ |
383 | spin_unlock_irq(phba->host->host_lock); | 376 | spin_unlock_irq(&phba->hbalock); |
384 | 377 | ||
385 | /* | 378 | /* |
386 | * Setup the ring 0 (els) timeout handler | 379 | * Setup the ring 0 (els) timeout handler |
387 | */ | 380 | */ |
388 | timeout = phba->fc_ratov << 1; | 381 | timeout = phba->fc_ratov << 1; |
389 | mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); | 382 | mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); |
390 | 383 | ||
391 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); | 384 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); |
392 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 385 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
@@ -408,7 +401,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
408 | writel(0xffffffff, phba->HAregaddr); | 401 | writel(0xffffffff, phba->HAregaddr); |
409 | readl(phba->HAregaddr); /* flush */ | 402 | readl(phba->HAregaddr); /* flush */ |
410 | 403 | ||
411 | phba->hba_state = LPFC_HBA_ERROR; | 404 | phba->link_state = LPFC_HBA_ERROR; |
412 | if (rc != MBX_BUSY) | 405 | if (rc != MBX_BUSY) |
413 | mempool_free(pmb, phba->mbox_mem_pool); | 406 | mempool_free(pmb, phba->mbox_mem_pool); |
414 | return -EIO; | 407 | return -EIO; |
@@ -429,18 +422,20 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
429 | /* */ | 422 | /* */ |
430 | /************************************************************************/ | 423 | /************************************************************************/ |
431 | int | 424 | int |
432 | lpfc_hba_down_prep(struct lpfc_hba * phba) | 425 | lpfc_hba_down_prep(struct lpfc_hba *phba) |
433 | { | 426 | { |
427 | struct lpfc_vport *vport = phba->pport; | ||
428 | |||
434 | /* Disable interrupts */ | 429 | /* Disable interrupts */ |
435 | writel(0, phba->HCregaddr); | 430 | writel(0, phba->HCregaddr); |
436 | readl(phba->HCregaddr); /* flush */ | 431 | readl(phba->HCregaddr); /* flush */ |
437 | 432 | ||
438 | /* Cleanup potential discovery resources */ | 433 | /* Cleanup potential discovery resources */ |
439 | lpfc_els_flush_rscn(phba); | 434 | lpfc_els_flush_rscn(vport); |
440 | lpfc_els_flush_cmd(phba); | 435 | lpfc_els_flush_cmd(vport); |
441 | lpfc_disc_flush_list(phba); | 436 | lpfc_disc_flush_list(vport); |
442 | 437 | ||
443 | return (0); | 438 | return 0; |
444 | } | 439 | } |
445 | 440 | ||
446 | /************************************************************************/ | 441 | /************************************************************************/ |
@@ -453,7 +448,7 @@ lpfc_hba_down_prep(struct lpfc_hba * phba) | |||
453 | /* */ | 448 | /* */ |
454 | /************************************************************************/ | 449 | /************************************************************************/ |
455 | int | 450 | int |
456 | lpfc_hba_down_post(struct lpfc_hba * phba) | 451 | lpfc_hba_down_post(struct lpfc_hba *phba) |
457 | { | 452 | { |
458 | struct lpfc_sli *psli = &phba->sli; | 453 | struct lpfc_sli *psli = &phba->sli; |
459 | struct lpfc_sli_ring *pring; | 454 | struct lpfc_sli_ring *pring; |
@@ -486,11 +481,14 @@ lpfc_hba_down_post(struct lpfc_hba * phba) | |||
486 | /* */ | 481 | /* */ |
487 | /************************************************************************/ | 482 | /************************************************************************/ |
488 | void | 483 | void |
489 | lpfc_handle_eratt(struct lpfc_hba * phba) | 484 | lpfc_handle_eratt(struct lpfc_hba *phba) |
490 | { | 485 | { |
491 | struct lpfc_sli *psli = &phba->sli; | 486 | struct lpfc_vport *vport = phba->pport; |
487 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
488 | struct lpfc_sli *psli = &phba->sli; | ||
492 | struct lpfc_sli_ring *pring; | 489 | struct lpfc_sli_ring *pring; |
493 | uint32_t event_data; | 490 | uint32_t event_data; |
491 | |||
494 | /* If the pci channel is offline, ignore possible errors, | 492 | /* If the pci channel is offline, ignore possible errors, |
495 | * since we cannot communicate with the pci card anyway. */ | 493 | * since we cannot communicate with the pci card anyway. */ |
496 | if (pci_channel_offline(phba->pcidev)) | 494 | if (pci_channel_offline(phba->pcidev)) |
@@ -504,10 +502,10 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
504 | "Data: x%x x%x x%x\n", | 502 | "Data: x%x x%x x%x\n", |
505 | phba->brd_no, phba->work_hs, | 503 | phba->brd_no, phba->work_hs, |
506 | phba->work_status[0], phba->work_status[1]); | 504 | phba->work_status[0], phba->work_status[1]); |
507 | spin_lock_irq(phba->host->host_lock); | 505 | spin_lock_irq(shost->host_lock); |
508 | phba->fc_flag |= FC_ESTABLISH_LINK; | 506 | vport->fc_flag |= FC_ESTABLISH_LINK; |
509 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 507 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
510 | spin_unlock_irq(phba->host->host_lock); | 508 | spin_unlock_irq(shost->host_lock); |
511 | 509 | ||
512 | /* | 510 | /* |
513 | * Firmware stops when it triggled erratt with HS_FFER6. | 511 | * Firmware stops when it triggled erratt with HS_FFER6. |
@@ -544,7 +542,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
544 | phba->work_status[0], phba->work_status[1]); | 542 | phba->work_status[0], phba->work_status[1]); |
545 | 543 | ||
546 | event_data = FC_REG_DUMP_EVENT; | 544 | event_data = FC_REG_DUMP_EVENT; |
547 | fc_host_post_vendor_event(phba->host, fc_get_event_number(), | 545 | fc_host_post_vendor_event(shost, fc_get_event_number(), |
548 | sizeof(event_data), (char *) &event_data, | 546 | sizeof(event_data), (char *) &event_data, |
549 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); | 547 | SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); |
550 | 548 | ||
@@ -552,7 +550,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
552 | lpfc_offline_prep(phba); | 550 | lpfc_offline_prep(phba); |
553 | lpfc_offline(phba); | 551 | lpfc_offline(phba); |
554 | lpfc_unblock_mgmt_io(phba); | 552 | lpfc_unblock_mgmt_io(phba); |
555 | phba->hba_state = LPFC_HBA_ERROR; | 553 | phba->link_state = LPFC_HBA_ERROR; |
556 | lpfc_hba_down_post(phba); | 554 | lpfc_hba_down_post(phba); |
557 | } | 555 | } |
558 | } | 556 | } |
@@ -566,9 +564,10 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
566 | /* */ | 564 | /* */ |
567 | /************************************************************************/ | 565 | /************************************************************************/ |
568 | void | 566 | void |
569 | lpfc_handle_latt(struct lpfc_hba * phba) | 567 | lpfc_handle_latt(struct lpfc_hba *phba) |
570 | { | 568 | { |
571 | struct lpfc_sli *psli = &phba->sli; | 569 | struct lpfc_vport *vport = phba->pport; |
570 | struct lpfc_sli *psli = &phba->sli; | ||
572 | LPFC_MBOXQ_t *pmb; | 571 | LPFC_MBOXQ_t *pmb; |
573 | volatile uint32_t control; | 572 | volatile uint32_t control; |
574 | struct lpfc_dmabuf *mp; | 573 | struct lpfc_dmabuf *mp; |
@@ -589,20 +588,21 @@ lpfc_handle_latt(struct lpfc_hba * phba) | |||
589 | rc = -EIO; | 588 | rc = -EIO; |
590 | 589 | ||
591 | /* Cleanup any outstanding ELS commands */ | 590 | /* Cleanup any outstanding ELS commands */ |
592 | lpfc_els_flush_cmd(phba); | 591 | lpfc_els_flush_cmd(vport); |
593 | 592 | ||
594 | psli->slistat.link_event++; | 593 | psli->slistat.link_event++; |
595 | lpfc_read_la(phba, pmb, mp); | 594 | lpfc_read_la(phba, pmb, mp); |
596 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; | 595 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; |
596 | pmb->vport = vport; | ||
597 | rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); | 597 | rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); |
598 | if (rc == MBX_NOT_FINISHED) | 598 | if (rc == MBX_NOT_FINISHED) |
599 | goto lpfc_handle_latt_free_mbuf; | 599 | goto lpfc_handle_latt_free_mbuf; |
600 | 600 | ||
601 | /* Clear Link Attention in HA REG */ | 601 | /* Clear Link Attention in HA REG */ |
602 | spin_lock_irq(phba->host->host_lock); | 602 | spin_lock_irq(&phba->hbalock); |
603 | writel(HA_LATT, phba->HAregaddr); | 603 | writel(HA_LATT, phba->HAregaddr); |
604 | readl(phba->HAregaddr); /* flush */ | 604 | readl(phba->HAregaddr); /* flush */ |
605 | spin_unlock_irq(phba->host->host_lock); | 605 | spin_unlock_irq(&phba->hbalock); |
606 | 606 | ||
607 | return; | 607 | return; |
608 | 608 | ||
@@ -614,7 +614,7 @@ lpfc_handle_latt_free_pmb: | |||
614 | mempool_free(pmb, phba->mbox_mem_pool); | 614 | mempool_free(pmb, phba->mbox_mem_pool); |
615 | lpfc_handle_latt_err_exit: | 615 | lpfc_handle_latt_err_exit: |
616 | /* Enable Link attention interrupts */ | 616 | /* Enable Link attention interrupts */ |
617 | spin_lock_irq(phba->host->host_lock); | 617 | spin_lock_irq(&phba->hbalock); |
618 | psli->sli_flag |= LPFC_PROCESS_LA; | 618 | psli->sli_flag |= LPFC_PROCESS_LA; |
619 | control = readl(phba->HCregaddr); | 619 | control = readl(phba->HCregaddr); |
620 | control |= HC_LAINT_ENA; | 620 | control |= HC_LAINT_ENA; |
@@ -624,9 +624,9 @@ lpfc_handle_latt_err_exit: | |||
624 | /* Clear Link Attention in HA REG */ | 624 | /* Clear Link Attention in HA REG */ |
625 | writel(HA_LATT, phba->HAregaddr); | 625 | writel(HA_LATT, phba->HAregaddr); |
626 | readl(phba->HAregaddr); /* flush */ | 626 | readl(phba->HAregaddr); /* flush */ |
627 | spin_unlock_irq(phba->host->host_lock); | 627 | spin_unlock_irq(&phba->hbalock); |
628 | lpfc_linkdown(phba); | 628 | lpfc_linkdown(phba); |
629 | phba->hba_state = LPFC_HBA_ERROR; | 629 | phba->link_state = LPFC_HBA_ERROR; |
630 | 630 | ||
631 | /* The other case is an error from issue_mbox */ | 631 | /* The other case is an error from issue_mbox */ |
632 | if (rc == -ENOMEM) | 632 | if (rc == -ENOMEM) |
@@ -646,7 +646,7 @@ lpfc_handle_latt_err_exit: | |||
646 | /* */ | 646 | /* */ |
647 | /************************************************************************/ | 647 | /************************************************************************/ |
648 | static int | 648 | static int |
649 | lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) | 649 | lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len) |
650 | { | 650 | { |
651 | uint8_t lenlo, lenhi; | 651 | uint8_t lenlo, lenhi; |
652 | int Length; | 652 | int Length; |
@@ -785,7 +785,7 @@ lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) | |||
785 | } | 785 | } |
786 | 786 | ||
787 | static void | 787 | static void |
788 | lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | 788 | lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) |
789 | { | 789 | { |
790 | lpfc_vpd_t *vp; | 790 | lpfc_vpd_t *vp; |
791 | uint16_t dev_id = phba->pcidev->device; | 791 | uint16_t dev_id = phba->pcidev->device; |
@@ -943,7 +943,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
943 | /* Returns the number of buffers NOT posted. */ | 943 | /* Returns the number of buffers NOT posted. */ |
944 | /**************************************************/ | 944 | /**************************************************/ |
945 | int | 945 | int |
946 | lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | 946 | lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt, |
947 | int type) | 947 | int type) |
948 | { | 948 | { |
949 | IOCB_t *icmd; | 949 | IOCB_t *icmd; |
@@ -955,9 +955,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
955 | /* While there are buffers to post */ | 955 | /* While there are buffers to post */ |
956 | while (cnt > 0) { | 956 | while (cnt > 0) { |
957 | /* Allocate buffer for command iocb */ | 957 | /* Allocate buffer for command iocb */ |
958 | spin_lock_irq(phba->host->host_lock); | ||
959 | iocb = lpfc_sli_get_iocbq(phba); | 958 | iocb = lpfc_sli_get_iocbq(phba); |
960 | spin_unlock_irq(phba->host->host_lock); | ||
961 | if (iocb == NULL) { | 959 | if (iocb == NULL) { |
962 | pring->missbufcnt = cnt; | 960 | pring->missbufcnt = cnt; |
963 | return cnt; | 961 | return cnt; |
@@ -972,9 +970,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
972 | &mp1->phys); | 970 | &mp1->phys); |
973 | if (mp1 == 0 || mp1->virt == 0) { | 971 | if (mp1 == 0 || mp1->virt == 0) { |
974 | kfree(mp1); | 972 | kfree(mp1); |
975 | spin_lock_irq(phba->host->host_lock); | ||
976 | lpfc_sli_release_iocbq(phba, iocb); | 973 | lpfc_sli_release_iocbq(phba, iocb); |
977 | spin_unlock_irq(phba->host->host_lock); | ||
978 | pring->missbufcnt = cnt; | 974 | pring->missbufcnt = cnt; |
979 | return cnt; | 975 | return cnt; |
980 | } | 976 | } |
@@ -990,9 +986,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
990 | kfree(mp2); | 986 | kfree(mp2); |
991 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); | 987 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); |
992 | kfree(mp1); | 988 | kfree(mp1); |
993 | spin_lock_irq(phba->host->host_lock); | ||
994 | lpfc_sli_release_iocbq(phba, iocb); | 989 | lpfc_sli_release_iocbq(phba, iocb); |
995 | spin_unlock_irq(phba->host->host_lock); | ||
996 | pring->missbufcnt = cnt; | 990 | pring->missbufcnt = cnt; |
997 | return cnt; | 991 | return cnt; |
998 | } | 992 | } |
@@ -1018,7 +1012,6 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
1018 | icmd->ulpCommand = CMD_QUE_RING_BUF64_CN; | 1012 | icmd->ulpCommand = CMD_QUE_RING_BUF64_CN; |
1019 | icmd->ulpLe = 1; | 1013 | icmd->ulpLe = 1; |
1020 | 1014 | ||
1021 | spin_lock_irq(phba->host->host_lock); | ||
1022 | if (lpfc_sli_issue_iocb(phba, pring, iocb, 0) == IOCB_ERROR) { | 1015 | if (lpfc_sli_issue_iocb(phba, pring, iocb, 0) == IOCB_ERROR) { |
1023 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); | 1016 | lpfc_mbuf_free(phba, mp1->virt, mp1->phys); |
1024 | kfree(mp1); | 1017 | kfree(mp1); |
@@ -1030,10 +1023,8 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
1030 | } | 1023 | } |
1031 | lpfc_sli_release_iocbq(phba, iocb); | 1024 | lpfc_sli_release_iocbq(phba, iocb); |
1032 | pring->missbufcnt = cnt; | 1025 | pring->missbufcnt = cnt; |
1033 | spin_unlock_irq(phba->host->host_lock); | ||
1034 | return cnt; | 1026 | return cnt; |
1035 | } | 1027 | } |
1036 | spin_unlock_irq(phba->host->host_lock); | ||
1037 | lpfc_sli_ringpostbuf_put(phba, pring, mp1); | 1028 | lpfc_sli_ringpostbuf_put(phba, pring, mp1); |
1038 | if (mp2) { | 1029 | if (mp2) { |
1039 | lpfc_sli_ringpostbuf_put(phba, pring, mp2); | 1030 | lpfc_sli_ringpostbuf_put(phba, pring, mp2); |
@@ -1050,7 +1041,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt, | |||
1050 | /* */ | 1041 | /* */ |
1051 | /************************************************************************/ | 1042 | /************************************************************************/ |
1052 | static int | 1043 | static int |
1053 | lpfc_post_rcv_buf(struct lpfc_hba * phba) | 1044 | lpfc_post_rcv_buf(struct lpfc_hba *phba) |
1054 | { | 1045 | { |
1055 | struct lpfc_sli *psli = &phba->sli; | 1046 | struct lpfc_sli *psli = &phba->sli; |
1056 | 1047 | ||
@@ -1151,7 +1142,7 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) | |||
1151 | { | 1142 | { |
1152 | int t; | 1143 | int t; |
1153 | uint32_t *HashWorking; | 1144 | uint32_t *HashWorking; |
1154 | uint32_t *pwwnn = phba->wwnn; | 1145 | uint32_t *pwwnn = (uint32_t *) phba->wwnn; |
1155 | 1146 | ||
1156 | HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL); | 1147 | HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL); |
1157 | if (!HashWorking) | 1148 | if (!HashWorking) |
@@ -1170,16 +1161,16 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) | |||
1170 | } | 1161 | } |
1171 | 1162 | ||
1172 | static void | 1163 | static void |
1173 | lpfc_cleanup(struct lpfc_hba * phba) | 1164 | lpfc_cleanup(struct lpfc_vport *vport) |
1174 | { | 1165 | { |
1175 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1166 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1176 | 1167 | ||
1177 | /* clean up phba - lpfc specific */ | 1168 | /* clean up phba - lpfc specific */ |
1178 | lpfc_can_disctmo(phba); | 1169 | lpfc_can_disctmo(vport); |
1179 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) | 1170 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) |
1180 | lpfc_nlp_put(ndlp); | 1171 | lpfc_nlp_put(ndlp); |
1181 | 1172 | ||
1182 | INIT_LIST_HEAD(&phba->fc_nodes); | 1173 | INIT_LIST_HEAD(&vport->fc_nodes); |
1183 | 1174 | ||
1184 | return; | 1175 | return; |
1185 | } | 1176 | } |
@@ -1187,7 +1178,9 @@ lpfc_cleanup(struct lpfc_hba * phba) | |||
1187 | static void | 1178 | static void |
1188 | lpfc_establish_link_tmo(unsigned long ptr) | 1179 | lpfc_establish_link_tmo(unsigned long ptr) |
1189 | { | 1180 | { |
1190 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | 1181 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; |
1182 | struct lpfc_vport *vport = phba->pport; | ||
1183 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1191 | unsigned long iflag; | 1184 | unsigned long iflag; |
1192 | 1185 | ||
1193 | 1186 | ||
@@ -1195,34 +1188,37 @@ lpfc_establish_link_tmo(unsigned long ptr) | |||
1195 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 1188 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
1196 | "%d:1300 Re-establishing Link, timer expired " | 1189 | "%d:1300 Re-establishing Link, timer expired " |
1197 | "Data: x%x x%x\n", | 1190 | "Data: x%x x%x\n", |
1198 | phba->brd_no, phba->fc_flag, phba->hba_state); | 1191 | phba->brd_no, vport->fc_flag, |
1199 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1192 | vport->port_state); |
1200 | phba->fc_flag &= ~FC_ESTABLISH_LINK; | 1193 | spin_lock_irqsave(shost->host_lock, iflag); |
1201 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1194 | vport->fc_flag &= ~FC_ESTABLISH_LINK; |
1195 | spin_unlock_irqrestore(shost->host_lock, iflag); | ||
1202 | } | 1196 | } |
1203 | 1197 | ||
1204 | static int | 1198 | static void |
1205 | lpfc_stop_timer(struct lpfc_hba * phba) | 1199 | lpfc_stop_timer(struct lpfc_hba *phba) |
1206 | { | 1200 | { |
1207 | struct lpfc_sli *psli = &phba->sli; | 1201 | struct lpfc_vport *vport = phba->pport; |
1208 | 1202 | ||
1209 | del_timer_sync(&phba->fcp_poll_timer); | 1203 | del_timer_sync(&phba->fcp_poll_timer); |
1210 | del_timer_sync(&phba->fc_estabtmo); | 1204 | del_timer_sync(&phba->fc_estabtmo); |
1211 | del_timer_sync(&phba->fc_disctmo); | 1205 | del_timer_sync(&vport->els_tmofunc); |
1212 | del_timer_sync(&phba->fc_fdmitmo); | 1206 | del_timer_sync(&vport->fc_fdmitmo); |
1213 | del_timer_sync(&phba->els_tmofunc); | 1207 | del_timer_sync(&vport->fc_disctmo); |
1214 | psli = &phba->sli; | 1208 | del_timer_sync(&phba->sli.mbox_tmo); |
1215 | del_timer_sync(&psli->mbox_tmo); | 1209 | return; |
1216 | return(1); | ||
1217 | } | 1210 | } |
1218 | 1211 | ||
1219 | int | 1212 | int |
1220 | lpfc_online(struct lpfc_hba * phba) | 1213 | lpfc_online(struct lpfc_hba *phba) |
1221 | { | 1214 | { |
1215 | struct lpfc_vport *vport = phba->pport; | ||
1216 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1217 | |||
1222 | if (!phba) | 1218 | if (!phba) |
1223 | return 0; | 1219 | return 0; |
1224 | 1220 | ||
1225 | if (!(phba->fc_flag & FC_OFFLINE_MODE)) | 1221 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) |
1226 | return 0; | 1222 | return 0; |
1227 | 1223 | ||
1228 | lpfc_printf_log(phba, | 1224 | lpfc_printf_log(phba, |
@@ -1243,9 +1239,9 @@ lpfc_online(struct lpfc_hba * phba) | |||
1243 | return 1; | 1239 | return 1; |
1244 | } | 1240 | } |
1245 | 1241 | ||
1246 | spin_lock_irq(phba->host->host_lock); | 1242 | spin_lock_irq(shost->host_lock); |
1247 | phba->fc_flag &= ~FC_OFFLINE_MODE; | 1243 | vport->fc_flag &= ~FC_OFFLINE_MODE; |
1248 | spin_unlock_irq(phba->host->host_lock); | 1244 | spin_unlock_irq(shost->host_lock); |
1249 | 1245 | ||
1250 | lpfc_unblock_mgmt_io(phba); | 1246 | lpfc_unblock_mgmt_io(phba); |
1251 | return 0; | 1247 | return 0; |
@@ -1256,9 +1252,9 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba) | |||
1256 | { | 1252 | { |
1257 | unsigned long iflag; | 1253 | unsigned long iflag; |
1258 | 1254 | ||
1259 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1255 | spin_lock_irqsave(&phba->hbalock, iflag); |
1260 | phba->fc_flag |= FC_BLOCK_MGMT_IO; | 1256 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; |
1261 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1257 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1262 | } | 1258 | } |
1263 | 1259 | ||
1264 | void | 1260 | void |
@@ -1266,17 +1262,18 @@ lpfc_unblock_mgmt_io(struct lpfc_hba * phba) | |||
1266 | { | 1262 | { |
1267 | unsigned long iflag; | 1263 | unsigned long iflag; |
1268 | 1264 | ||
1269 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1265 | spin_lock_irqsave(&phba->hbalock, iflag); |
1270 | phba->fc_flag &= ~FC_BLOCK_MGMT_IO; | 1266 | phba->sli.sli_flag &= ~LPFC_BLOCK_MGMT_IO; |
1271 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1267 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
1272 | } | 1268 | } |
1273 | 1269 | ||
1274 | void | 1270 | void |
1275 | lpfc_offline_prep(struct lpfc_hba * phba) | 1271 | lpfc_offline_prep(struct lpfc_hba * phba) |
1276 | { | 1272 | { |
1273 | struct lpfc_vport *vport = phba->pport; | ||
1277 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1274 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1278 | 1275 | ||
1279 | if (phba->fc_flag & FC_OFFLINE_MODE) | 1276 | if (vport->fc_flag & FC_OFFLINE_MODE) |
1280 | return; | 1277 | return; |
1281 | 1278 | ||
1282 | lpfc_block_mgmt_io(phba); | 1279 | lpfc_block_mgmt_io(phba); |
@@ -1284,19 +1281,21 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
1284 | lpfc_linkdown(phba); | 1281 | lpfc_linkdown(phba); |
1285 | 1282 | ||
1286 | /* Issue an unreg_login to all nodes */ | 1283 | /* Issue an unreg_login to all nodes */ |
1287 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) | 1284 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) |
1288 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) | 1285 | if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) |
1289 | lpfc_unreg_rpi(phba, ndlp); | 1286 | lpfc_unreg_rpi(vport, ndlp); |
1290 | 1287 | ||
1291 | lpfc_sli_flush_mbox_queue(phba); | 1288 | lpfc_sli_flush_mbox_queue(phba); |
1292 | } | 1289 | } |
1293 | 1290 | ||
1294 | void | 1291 | void |
1295 | lpfc_offline(struct lpfc_hba * phba) | 1292 | lpfc_offline(struct lpfc_hba *phba) |
1296 | { | 1293 | { |
1294 | struct lpfc_vport *vport = phba->pport; | ||
1295 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1297 | unsigned long iflag; | 1296 | unsigned long iflag; |
1298 | 1297 | ||
1299 | if (phba->fc_flag & FC_OFFLINE_MODE) | 1298 | if (vport->fc_flag & FC_OFFLINE_MODE) |
1300 | return; | 1299 | return; |
1301 | 1300 | ||
1302 | /* stop all timers associated with this hba */ | 1301 | /* stop all timers associated with this hba */ |
@@ -1311,12 +1310,14 @@ lpfc_offline(struct lpfc_hba * phba) | |||
1311 | /* Bring down the SLI Layer and cleanup. The HBA is offline | 1310 | /* Bring down the SLI Layer and cleanup. The HBA is offline |
1312 | now. */ | 1311 | now. */ |
1313 | lpfc_sli_hba_down(phba); | 1312 | lpfc_sli_hba_down(phba); |
1314 | lpfc_cleanup(phba); | 1313 | lpfc_cleanup(vport); |
1315 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1314 | spin_lock_irqsave(shost->host_lock, iflag); |
1316 | phba->work_hba_events = 0; | 1315 | spin_lock(&phba->hbalock); |
1317 | phba->work_ha = 0; | 1316 | phba->work_ha = 0; |
1318 | phba->fc_flag |= FC_OFFLINE_MODE; | 1317 | vport->work_port_events = 0; |
1319 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1318 | vport->fc_flag |= FC_OFFLINE_MODE; |
1319 | spin_unlock(&phba->hbalock); | ||
1320 | spin_unlock_irqrestore(shost->host_lock, iflag); | ||
1320 | } | 1321 | } |
1321 | 1322 | ||
1322 | /****************************************************************************** | 1323 | /****************************************************************************** |
@@ -1326,12 +1327,12 @@ lpfc_offline(struct lpfc_hba * phba) | |||
1326 | * | 1327 | * |
1327 | ******************************************************************************/ | 1328 | ******************************************************************************/ |
1328 | static int | 1329 | static int |
1329 | lpfc_scsi_free(struct lpfc_hba * phba) | 1330 | lpfc_scsi_free(struct lpfc_hba *phba) |
1330 | { | 1331 | { |
1331 | struct lpfc_scsi_buf *sb, *sb_next; | 1332 | struct lpfc_scsi_buf *sb, *sb_next; |
1332 | struct lpfc_iocbq *io, *io_next; | 1333 | struct lpfc_iocbq *io, *io_next; |
1333 | 1334 | ||
1334 | spin_lock_irq(phba->host->host_lock); | 1335 | spin_lock_irq(&phba->hbalock); |
1335 | /* Release all the lpfc_scsi_bufs maintained by this host. */ | 1336 | /* Release all the lpfc_scsi_bufs maintained by this host. */ |
1336 | list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { | 1337 | list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { |
1337 | list_del(&sb->list); | 1338 | list_del(&sb->list); |
@@ -1348,130 +1349,158 @@ lpfc_scsi_free(struct lpfc_hba * phba) | |||
1348 | phba->total_iocbq_bufs--; | 1349 | phba->total_iocbq_bufs--; |
1349 | } | 1350 | } |
1350 | 1351 | ||
1351 | spin_unlock_irq(phba->host->host_lock); | 1352 | spin_unlock_irq(&phba->hbalock); |
1352 | 1353 | ||
1353 | return 0; | 1354 | return 0; |
1354 | } | 1355 | } |
1355 | 1356 | ||
1356 | void lpfc_remove_device(struct lpfc_hba *phba) | 1357 | struct lpfc_vport * |
1358 | lpfc_create_port(struct lpfc_hba *phba, int instance) | ||
1357 | { | 1359 | { |
1358 | unsigned long iflag; | 1360 | struct lpfc_vport *vport; |
1359 | 1361 | struct Scsi_Host *shost; | |
1360 | lpfc_free_sysfs_attr(phba); | 1362 | int error = 0; |
1361 | 1363 | ||
1362 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1364 | shost = scsi_host_alloc(&lpfc_template, sizeof(struct lpfc_vport)); |
1363 | phba->fc_flag |= FC_UNLOADING; | 1365 | if (!shost) |
1366 | goto out; | ||
1364 | 1367 | ||
1365 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1368 | vport = (struct lpfc_vport *) shost->hostdata; |
1369 | vport->phba = phba; | ||
1366 | 1370 | ||
1367 | fc_remove_host(phba->host); | 1371 | vport->load_flag |= FC_LOADING; |
1368 | scsi_remove_host(phba->host); | ||
1369 | |||
1370 | kthread_stop(phba->worker_thread); | ||
1371 | 1372 | ||
1373 | shost->unique_id = instance; | ||
1374 | shost->max_id = LPFC_MAX_TARGET; | ||
1375 | shost->max_lun = phba->cfg_max_luns; | ||
1376 | shost->this_id = -1; | ||
1377 | shost->max_cmd_len = 16; | ||
1372 | /* | 1378 | /* |
1373 | * Bring down the SLI Layer. This step disable all interrupts, | 1379 | * Set initial can_queue value since 0 is no longer supported and |
1374 | * clears the rings, discards all mailbox commands, and resets | 1380 | * scsi_add_host will fail. This will be adjusted later based on the |
1375 | * the HBA. | 1381 | * max xri value determined in hba setup. |
1376 | */ | 1382 | */ |
1377 | lpfc_sli_hba_down(phba); | 1383 | shost->can_queue = phba->cfg_hba_queue_depth - 10; |
1378 | lpfc_sli_brdrestart(phba); | 1384 | shost->transportt = lpfc_transport_template; |
1379 | 1385 | ||
1380 | /* Release the irq reservation */ | 1386 | /* Initialize all internally managed lists. */ |
1381 | free_irq(phba->pcidev->irq, phba); | 1387 | INIT_LIST_HEAD(&vport->fc_nodes); |
1382 | pci_disable_msi(phba->pcidev); | 1388 | spin_lock_init(&vport->work_port_lock); |
1383 | 1389 | ||
1384 | lpfc_cleanup(phba); | 1390 | init_timer(&vport->fc_disctmo); |
1385 | lpfc_stop_timer(phba); | 1391 | vport->fc_disctmo.function = lpfc_disc_timeout; |
1386 | phba->work_hba_events = 0; | 1392 | vport->fc_disctmo.data = (unsigned long) vport; |
1387 | 1393 | ||
1388 | /* | 1394 | init_timer(&vport->fc_fdmitmo); |
1389 | * Call scsi_free before mem_free since scsi bufs are released to their | 1395 | vport->fc_fdmitmo.function = lpfc_fdmi_tmo; |
1390 | * corresponding pools here. | 1396 | vport->fc_fdmitmo.data = (unsigned long) vport; |
1391 | */ | ||
1392 | lpfc_scsi_free(phba); | ||
1393 | lpfc_mem_free(phba); | ||
1394 | 1397 | ||
1395 | /* Free resources associated with SLI2 interface */ | 1398 | init_timer(&vport->els_tmofunc); |
1396 | dma_free_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE, | 1399 | vport->els_tmofunc.function = lpfc_els_timeout; |
1397 | phba->slim2p, phba->slim2p_mapping); | 1400 | vport->els_tmofunc.data = (unsigned long) vport; |
1398 | 1401 | ||
1399 | /* unmap adapter SLIM and Control Registers */ | 1402 | error = scsi_add_host(shost, &phba->pcidev->dev); |
1400 | iounmap(phba->ctrl_regs_memmap_p); | 1403 | if (error) |
1401 | iounmap(phba->slim_memmap_p); | 1404 | goto out_put_shost; |
1402 | 1405 | ||
1403 | pci_release_regions(phba->pcidev); | 1406 | list_add_tail(&vport->listentry, &phba->port_list); |
1404 | pci_disable_device(phba->pcidev); | 1407 | scsi_scan_host(shost); |
1408 | return vport; | ||
1405 | 1409 | ||
1406 | idr_remove(&lpfc_hba_index, phba->brd_no); | 1410 | out_put_shost: |
1407 | scsi_host_put(phba->host); | 1411 | scsi_host_put(shost); |
1412 | out: | ||
1413 | return NULL; | ||
1414 | } | ||
1415 | |||
1416 | void | ||
1417 | destroy_port(struct lpfc_vport *vport) | ||
1418 | { | ||
1419 | lpfc_cleanup(vport); | ||
1420 | list_del(&vport->listentry); | ||
1421 | lpfc_free_sysfs_attr(vport); | ||
1422 | fc_remove_host(lpfc_shost_from_vport(vport)); | ||
1423 | scsi_remove_host(lpfc_shost_from_vport(vport)); | ||
1424 | return; | ||
1408 | } | 1425 | } |
1409 | 1426 | ||
1410 | void lpfc_scan_start(struct Scsi_Host *host) | 1427 | static void |
1428 | lpfc_remove_device(struct lpfc_vport *vport) | ||
1411 | { | 1429 | { |
1412 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 1430 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1431 | struct lpfc_hba *phba = vport->phba; | ||
1413 | 1432 | ||
1414 | if (lpfc_alloc_sysfs_attr(phba)) | 1433 | lpfc_free_sysfs_attr(vport); |
1415 | goto error; | ||
1416 | 1434 | ||
1417 | phba->MBslimaddr = phba->slim_memmap_p; | 1435 | spin_lock_irq(shost->host_lock); |
1418 | phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET; | 1436 | vport->fc_flag |= FC_UNLOADING; |
1419 | phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET; | 1437 | spin_unlock_irq(shost->host_lock); |
1420 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; | 1438 | |
1421 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; | 1439 | fc_remove_host(shost); |
1440 | scsi_remove_host(shost); | ||
1441 | |||
1442 | kthread_stop(phba->worker_thread); | ||
1443 | } | ||
1444 | |||
1445 | void lpfc_scan_start(struct Scsi_Host *shost) | ||
1446 | { | ||
1447 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; | ||
1448 | struct lpfc_hba *phba = vport->phba; | ||
1422 | 1449 | ||
1423 | if (lpfc_sli_hba_setup(phba)) | 1450 | if (lpfc_alloc_sysfs_attr(vport)) |
1424 | goto error; | 1451 | goto error; |
1425 | 1452 | ||
1426 | /* | 1453 | /* |
1427 | * hba setup may have changed the hba_queue_depth so we need to adjust | 1454 | * hba setup may have changed the hba_queue_depth so we need to adjust |
1428 | * the value of can_queue. | 1455 | * the value of can_queue. |
1429 | */ | 1456 | */ |
1430 | host->can_queue = phba->cfg_hba_queue_depth - 10; | 1457 | shost->can_queue = phba->cfg_hba_queue_depth - 10; |
1431 | return; | 1458 | return; |
1432 | 1459 | ||
1433 | error: | 1460 | error: |
1434 | lpfc_remove_device(phba); | 1461 | lpfc_remove_device(vport); |
1435 | } | 1462 | } |
1436 | 1463 | ||
1437 | int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) | 1464 | int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) |
1438 | { | 1465 | { |
1439 | struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; | 1466 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1467 | struct lpfc_hba *phba = vport->phba; | ||
1440 | 1468 | ||
1441 | if (!phba->host) | 1469 | if (time >= 30 * HZ) { |
1442 | return 1; | 1470 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
1443 | if (time >= 30 * HZ) | 1471 | "%d:0461 Scanning longer than 30 " |
1472 | "seconds. Continuing initialization\n", | ||
1473 | phba->brd_no); | ||
1444 | goto finished; | 1474 | goto finished; |
1475 | } | ||
1476 | if (time >= 15 * HZ && phba->link_state <= LPFC_LINK_DOWN) { | ||
1477 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
1478 | "%d:0465 Link down longer than 15 " | ||
1479 | "seconds. Continuing initialization\n", | ||
1480 | phba->brd_no); | ||
1481 | goto finished; | ||
1482 | } | ||
1445 | 1483 | ||
1446 | if (phba->hba_state != LPFC_HBA_READY) | 1484 | if (vport->port_state != LPFC_VPORT_READY) |
1447 | return 0; | ||
1448 | if (phba->num_disc_nodes || phba->fc_prli_sent) | ||
1449 | return 0; | 1485 | return 0; |
1450 | if ((phba->fc_map_cnt == 0) && (time < 2 * HZ)) | 1486 | if (vport->num_disc_nodes || vport->fc_prli_sent) |
1451 | return 0; | 1487 | return 0; |
1452 | if (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) | 1488 | if (vport->fc_map_cnt == 0 && time < 2 * HZ) |
1453 | return 0; | 1489 | return 0; |
1454 | if ((phba->hba_state > LPFC_LINK_DOWN) || (time < 15 * HZ)) | 1490 | if ((phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) != 0) |
1455 | return 0; | 1491 | return 0; |
1456 | 1492 | ||
1457 | finished: | 1493 | finished: |
1458 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) { | ||
1459 | spin_lock_irq(shost->host_lock); | ||
1460 | lpfc_poll_start_timer(phba); | ||
1461 | spin_unlock_irq(shost->host_lock); | ||
1462 | } | ||
1463 | |||
1464 | /* | 1494 | /* |
1465 | * set fixed host attributes | 1495 | * Set fixed host attributes. Must done after lpfc_sli_hba_setup(). |
1466 | * Must done after lpfc_sli_hba_setup() | ||
1467 | */ | 1496 | */ |
1468 | 1497 | ||
1469 | fc_host_node_name(shost) = wwn_to_u64(phba->fc_nodename.u.wwn); | 1498 | fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn); |
1470 | fc_host_port_name(shost) = wwn_to_u64(phba->fc_portname.u.wwn); | 1499 | fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn); |
1471 | fc_host_supported_classes(shost) = FC_COS_CLASS3; | 1500 | fc_host_supported_classes(shost) = FC_COS_CLASS3; |
1472 | 1501 | ||
1473 | memset(fc_host_supported_fc4s(shost), 0, | 1502 | memset(fc_host_supported_fc4s(shost), 0, |
1474 | sizeof(fc_host_supported_fc4s(shost))); | 1503 | sizeof(fc_host_supported_fc4s(shost))); |
1475 | fc_host_supported_fc4s(shost)[2] = 1; | 1504 | fc_host_supported_fc4s(shost)[2] = 1; |
1476 | fc_host_supported_fc4s(shost)[7] = 1; | 1505 | fc_host_supported_fc4s(shost)[7] = 1; |
1477 | 1506 | ||
@@ -1488,17 +1517,17 @@ finished: | |||
1488 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT; | 1517 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT; |
1489 | 1518 | ||
1490 | fc_host_maxframe_size(shost) = | 1519 | fc_host_maxframe_size(shost) = |
1491 | ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | | 1520 | (((uint32_t) vport->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | |
1492 | (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb); | 1521 | (uint32_t) vport->fc_sparam.cmn.bbRcvSizeLsb; |
1493 | 1522 | ||
1494 | /* This value is also unchanging */ | 1523 | /* This value is also unchanging */ |
1495 | memset(fc_host_active_fc4s(shost), 0, | 1524 | memset(fc_host_active_fc4s(shost), 0, |
1496 | sizeof(fc_host_active_fc4s(shost))); | 1525 | sizeof(fc_host_active_fc4s(shost))); |
1497 | fc_host_active_fc4s(shost)[2] = 1; | 1526 | fc_host_active_fc4s(shost)[2] = 1; |
1498 | fc_host_active_fc4s(shost)[7] = 1; | 1527 | fc_host_active_fc4s(shost)[7] = 1; |
1499 | 1528 | ||
1500 | spin_lock_irq(shost->host_lock); | 1529 | spin_lock_irq(shost->host_lock); |
1501 | phba->fc_flag &= ~FC_LOADING; | 1530 | vport->fc_flag &= ~FC_LOADING; |
1502 | spin_unlock_irq(shost->host_lock); | 1531 | spin_unlock_irq(shost->host_lock); |
1503 | 1532 | ||
1504 | return 1; | 1533 | return 1; |
@@ -1507,10 +1536,11 @@ finished: | |||
1507 | static int __devinit | 1536 | static int __devinit |
1508 | lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | 1537 | lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) |
1509 | { | 1538 | { |
1510 | struct Scsi_Host *host; | 1539 | struct lpfc_vport *vport = NULL; |
1511 | struct lpfc_hba *phba; | 1540 | struct lpfc_hba *phba; |
1512 | struct lpfc_sli *psli; | 1541 | struct lpfc_sli *psli; |
1513 | struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL; | 1542 | struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL; |
1543 | struct Scsi_Host *shost = NULL; | ||
1514 | unsigned long bar0map_len, bar2map_len; | 1544 | unsigned long bar0map_len, bar2map_len; |
1515 | int error = -ENODEV, retval; | 1545 | int error = -ENODEV, retval; |
1516 | int i; | 1546 | int i; |
@@ -1521,61 +1551,41 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1521 | if (pci_request_regions(pdev, LPFC_DRIVER_NAME)) | 1551 | if (pci_request_regions(pdev, LPFC_DRIVER_NAME)) |
1522 | goto out_disable_device; | 1552 | goto out_disable_device; |
1523 | 1553 | ||
1524 | host = scsi_host_alloc(&lpfc_template, sizeof (struct lpfc_hba)); | 1554 | phba = kzalloc(sizeof (struct lpfc_hba), GFP_KERNEL); |
1525 | if (!host) | 1555 | if (!phba) |
1526 | goto out_release_regions; | 1556 | goto out_release_regions; |
1527 | 1557 | ||
1528 | phba = (struct lpfc_hba*)host->hostdata; | 1558 | spin_lock_init(&phba->hbalock); |
1529 | memset(phba, 0, sizeof (struct lpfc_hba)); | ||
1530 | phba->host = host; | ||
1531 | 1559 | ||
1532 | phba->fc_flag |= FC_LOADING; | ||
1533 | phba->pcidev = pdev; | 1560 | phba->pcidev = pdev; |
1534 | 1561 | ||
1535 | /* Assign an unused board number */ | 1562 | /* Assign an unused board number */ |
1536 | if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL)) | 1563 | if (!idr_pre_get(&lpfc_hba_index, GFP_KERNEL)) |
1537 | goto out_put_host; | 1564 | goto out_free_phba; |
1538 | 1565 | ||
1539 | error = idr_get_new(&lpfc_hba_index, NULL, &phba->brd_no); | 1566 | error = idr_get_new(&lpfc_hba_index, NULL, &phba->brd_no); |
1540 | if (error) | 1567 | if (error) |
1541 | goto out_put_host; | 1568 | goto out_free_phba; |
1569 | |||
1570 | INIT_LIST_HEAD(&phba->port_list); | ||
1542 | 1571 | ||
1543 | host->unique_id = phba->brd_no; | 1572 | /* |
1573 | * Get all the module params for configuring this host and then | ||
1574 | * establish the host. | ||
1575 | */ | ||
1576 | lpfc_get_cfgparam(phba); | ||
1544 | 1577 | ||
1545 | /* Initialize timers used by driver */ | 1578 | /* Initialize timers used by driver */ |
1546 | init_timer(&phba->fc_estabtmo); | 1579 | init_timer(&phba->fc_estabtmo); |
1547 | phba->fc_estabtmo.function = lpfc_establish_link_tmo; | 1580 | phba->fc_estabtmo.function = lpfc_establish_link_tmo; |
1548 | phba->fc_estabtmo.data = (unsigned long)phba; | 1581 | phba->fc_estabtmo.data = (unsigned long) phba; |
1549 | init_timer(&phba->fc_disctmo); | ||
1550 | phba->fc_disctmo.function = lpfc_disc_timeout; | ||
1551 | phba->fc_disctmo.data = (unsigned long)phba; | ||
1552 | |||
1553 | init_timer(&phba->fc_fdmitmo); | ||
1554 | phba->fc_fdmitmo.function = lpfc_fdmi_tmo; | ||
1555 | phba->fc_fdmitmo.data = (unsigned long)phba; | ||
1556 | init_timer(&phba->els_tmofunc); | ||
1557 | phba->els_tmofunc.function = lpfc_els_timeout; | ||
1558 | phba->els_tmofunc.data = (unsigned long)phba; | ||
1559 | psli = &phba->sli; | 1582 | psli = &phba->sli; |
1560 | init_timer(&psli->mbox_tmo); | 1583 | init_timer(&psli->mbox_tmo); |
1561 | psli->mbox_tmo.function = lpfc_mbox_timeout; | 1584 | psli->mbox_tmo.function = lpfc_mbox_timeout; |
1562 | psli->mbox_tmo.data = (unsigned long)phba; | 1585 | psli->mbox_tmo.data = (unsigned long) phba; |
1563 | |||
1564 | init_timer(&phba->fcp_poll_timer); | 1586 | init_timer(&phba->fcp_poll_timer); |
1565 | phba->fcp_poll_timer.function = lpfc_poll_timeout; | 1587 | phba->fcp_poll_timer.function = lpfc_poll_timeout; |
1566 | phba->fcp_poll_timer.data = (unsigned long)phba; | 1588 | phba->fcp_poll_timer.data = (unsigned long) phba; |
1567 | |||
1568 | /* | ||
1569 | * Get all the module params for configuring this host and then | ||
1570 | * establish the host parameters. | ||
1571 | */ | ||
1572 | lpfc_get_cfgparam(phba); | ||
1573 | |||
1574 | host->max_id = LPFC_MAX_TARGET; | ||
1575 | host->max_lun = phba->cfg_max_luns; | ||
1576 | host->this_id = -1; | ||
1577 | |||
1578 | INIT_LIST_HEAD(&phba->fc_nodes); | ||
1579 | 1589 | ||
1580 | pci_set_master(pdev); | 1590 | pci_set_master(pdev); |
1581 | retval = pci_set_mwi(pdev); | 1591 | retval = pci_set_mwi(pdev); |
@@ -1653,10 +1663,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1653 | error = -ENOMEM; | 1663 | error = -ENOMEM; |
1654 | goto out_free_iocbq; | 1664 | goto out_free_iocbq; |
1655 | } | 1665 | } |
1656 | spin_lock_irq(phba->host->host_lock); | 1666 | |
1667 | spin_lock_irq(&phba->hbalock); | ||
1657 | list_add(&iocbq_entry->list, &phba->lpfc_iocb_list); | 1668 | list_add(&iocbq_entry->list, &phba->lpfc_iocb_list); |
1658 | phba->total_iocbq_bufs++; | 1669 | phba->total_iocbq_bufs++; |
1659 | spin_unlock_irq(phba->host->host_lock); | 1670 | spin_unlock_irq(&phba->hbalock); |
1660 | } | 1671 | } |
1661 | 1672 | ||
1662 | /* Initialize HBA structure */ | 1673 | /* Initialize HBA structure */ |
@@ -1677,22 +1688,19 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1677 | goto out_free_iocbq; | 1688 | goto out_free_iocbq; |
1678 | } | 1689 | } |
1679 | 1690 | ||
1680 | /* | ||
1681 | * Set initial can_queue value since 0 is no longer supported and | ||
1682 | * scsi_add_host will fail. This will be adjusted later based on the | ||
1683 | * max xri value determined in hba setup. | ||
1684 | */ | ||
1685 | host->can_queue = phba->cfg_hba_queue_depth - 10; | ||
1686 | |||
1687 | /* Tell the midlayer we support 16 byte commands */ | ||
1688 | host->max_cmd_len = 16; | ||
1689 | |||
1690 | /* Initialize the list of scsi buffers used by driver for scsi IO. */ | 1691 | /* Initialize the list of scsi buffers used by driver for scsi IO. */ |
1691 | spin_lock_init(&phba->scsi_buf_list_lock); | 1692 | spin_lock_init(&phba->scsi_buf_list_lock); |
1692 | INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); | 1693 | INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); |
1693 | 1694 | ||
1694 | host->transportt = lpfc_transport_template; | 1695 | vport = lpfc_create_port(phba, phba->brd_no); |
1695 | pci_set_drvdata(pdev, host); | 1696 | if (!vport) |
1697 | goto out_kthread_stop; | ||
1698 | |||
1699 | shost = lpfc_shost_from_vport(vport); | ||
1700 | vport->port_type = LPFC_PHYSICAL_PORT; | ||
1701 | phba->pport = vport; | ||
1702 | |||
1703 | pci_set_drvdata(pdev, lpfc_shost_from_vport(vport)); | ||
1696 | 1704 | ||
1697 | if (phba->cfg_use_msi) { | 1705 | if (phba->cfg_use_msi) { |
1698 | error = pci_enable_msi(phba->pcidev); | 1706 | error = pci_enable_msi(phba->pcidev); |
@@ -1703,36 +1711,46 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1703 | } | 1711 | } |
1704 | 1712 | ||
1705 | error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, | 1713 | error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, |
1706 | LPFC_DRIVER_NAME, phba); | 1714 | LPFC_DRIVER_NAME, phba); |
1707 | if (error) { | 1715 | if (error) { |
1708 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1716 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1709 | "%d:0451 Enable interrupt handler failed\n", | 1717 | "%d:0451 Enable interrupt handler failed\n", |
1710 | phba->brd_no); | 1718 | phba->brd_no); |
1711 | goto out_kthread_stop; | 1719 | goto out_destroy_port; |
1712 | } | 1720 | } |
1713 | 1721 | ||
1714 | error = scsi_add_host(host, &pdev->dev); | 1722 | phba->MBslimaddr = phba->slim_memmap_p; |
1723 | phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET; | ||
1724 | phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET; | ||
1725 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; | ||
1726 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; | ||
1727 | |||
1728 | error = lpfc_sli_hba_setup(phba); | ||
1715 | if (error) | 1729 | if (error) |
1716 | goto out_free_irq; | 1730 | goto out_free_irq; |
1717 | 1731 | ||
1718 | scsi_scan_host(host); | 1732 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) { |
1733 | spin_lock_irq(shost->host_lock); | ||
1734 | lpfc_poll_start_timer(phba); | ||
1735 | spin_unlock_irq(shost->host_lock); | ||
1736 | } | ||
1719 | 1737 | ||
1720 | return 0; | 1738 | return 0; |
1721 | 1739 | ||
1722 | out_free_irq: | 1740 | out_free_irq: |
1723 | lpfc_stop_timer(phba); | 1741 | lpfc_stop_timer(phba); |
1724 | phba->work_hba_events = 0; | 1742 | phba->pport->work_port_events = 0; |
1725 | free_irq(phba->pcidev->irq, phba); | 1743 | free_irq(phba->pcidev->irq, phba); |
1726 | pci_disable_msi(phba->pcidev); | 1744 | pci_disable_msi(phba->pcidev); |
1745 | out_destroy_port: | ||
1746 | destroy_port(vport); | ||
1727 | out_kthread_stop: | 1747 | out_kthread_stop: |
1728 | kthread_stop(phba->worker_thread); | 1748 | kthread_stop(phba->worker_thread); |
1729 | out_free_iocbq: | 1749 | out_free_iocbq: |
1730 | list_for_each_entry_safe(iocbq_entry, iocbq_next, | 1750 | list_for_each_entry_safe(iocbq_entry, iocbq_next, |
1731 | &phba->lpfc_iocb_list, list) { | 1751 | &phba->lpfc_iocb_list, list) { |
1732 | spin_lock_irq(phba->host->host_lock); | ||
1733 | kfree(iocbq_entry); | 1752 | kfree(iocbq_entry); |
1734 | phba->total_iocbq_bufs--; | 1753 | phba->total_iocbq_bufs--; |
1735 | spin_unlock_irq(phba->host->host_lock); | ||
1736 | } | 1754 | } |
1737 | lpfc_mem_free(phba); | 1755 | lpfc_mem_free(phba); |
1738 | out_free_slim: | 1756 | out_free_slim: |
@@ -1744,9 +1762,8 @@ out_iounmap_slim: | |||
1744 | iounmap(phba->slim_memmap_p); | 1762 | iounmap(phba->slim_memmap_p); |
1745 | out_idr_remove: | 1763 | out_idr_remove: |
1746 | idr_remove(&lpfc_hba_index, phba->brd_no); | 1764 | idr_remove(&lpfc_hba_index, phba->brd_no); |
1747 | out_put_host: | 1765 | out_free_phba: |
1748 | phba->host = NULL; | 1766 | kfree(phba); |
1749 | scsi_host_put(host); | ||
1750 | out_release_regions: | 1767 | out_release_regions: |
1751 | pci_release_regions(pdev); | 1768 | pci_release_regions(pdev); |
1752 | out_disable_device: | 1769 | out_disable_device: |
@@ -1759,12 +1776,55 @@ out: | |||
1759 | static void __devexit | 1776 | static void __devexit |
1760 | lpfc_pci_remove_one(struct pci_dev *pdev) | 1777 | lpfc_pci_remove_one(struct pci_dev *pdev) |
1761 | { | 1778 | { |
1762 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 1779 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
1763 | struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; | 1780 | struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; |
1781 | struct lpfc_hba *phba = vport->phba; | ||
1782 | |||
1783 | vport->load_flag |= FC_UNLOADING; | ||
1784 | lpfc_remove_device(vport); | ||
1785 | |||
1786 | /* | ||
1787 | * Bring down the SLI Layer. This step disable all interrupts, | ||
1788 | * clears the rings, discards all mailbox commands, and resets | ||
1789 | * the HBA. | ||
1790 | */ | ||
1791 | lpfc_sli_hba_down(phba); | ||
1792 | lpfc_sli_brdrestart(phba); | ||
1793 | |||
1794 | lpfc_stop_timer(phba); | ||
1795 | |||
1796 | kthread_stop(phba->worker_thread); | ||
1797 | |||
1798 | /* Release the irq reservation */ | ||
1799 | free_irq(phba->pcidev->irq, phba); | ||
1800 | pci_disable_msi(phba->pcidev); | ||
1764 | 1801 | ||
1765 | lpfc_remove_device(phba); | 1802 | vport->work_port_events = 0; |
1803 | destroy_port(vport); | ||
1766 | 1804 | ||
1767 | pci_set_drvdata(pdev, NULL); | 1805 | pci_set_drvdata(pdev, NULL); |
1806 | |||
1807 | /* | ||
1808 | * Call scsi_free before mem_free since scsi bufs are released to their | ||
1809 | * corresponding pools here. | ||
1810 | */ | ||
1811 | lpfc_scsi_free(phba); | ||
1812 | lpfc_mem_free(phba); | ||
1813 | |||
1814 | /* Free resources associated with SLI2 interface */ | ||
1815 | dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, | ||
1816 | phba->slim2p, phba->slim2p_mapping); | ||
1817 | |||
1818 | /* unmap adapter SLIM and Control Registers */ | ||
1819 | iounmap(phba->ctrl_regs_memmap_p); | ||
1820 | iounmap(phba->slim_memmap_p); | ||
1821 | |||
1822 | idr_remove(&lpfc_hba_index, phba->brd_no); | ||
1823 | |||
1824 | kfree(phba); | ||
1825 | |||
1826 | pci_release_regions(pdev); | ||
1827 | pci_disable_device(pdev); | ||
1768 | } | 1828 | } |
1769 | 1829 | ||
1770 | /** | 1830 | /** |
@@ -1822,10 +1882,12 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
1822 | pci_set_master(pdev); | 1882 | pci_set_master(pdev); |
1823 | 1883 | ||
1824 | /* Re-establishing Link */ | 1884 | /* Re-establishing Link */ |
1825 | spin_lock_irq(phba->host->host_lock); | 1885 | spin_lock_irq(&phba->hbalock); |
1826 | phba->fc_flag |= FC_ESTABLISH_LINK; | 1886 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; |
1887 | spin_unlock_irq(&phba->hbalock); | ||
1888 | spin_lock_irq(host->host_lock); | ||
1827 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 1889 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
1828 | spin_unlock_irq(phba->host->host_lock); | 1890 | spin_unlock_irq(host->host_lock); |
1829 | 1891 | ||
1830 | 1892 | ||
1831 | /* Take device offline; this will perform cleanup */ | 1893 | /* Take device offline; this will perform cleanup */ |
@@ -1935,7 +1997,7 @@ static struct pci_driver lpfc_driver = { | |||
1935 | .id_table = lpfc_id_table, | 1997 | .id_table = lpfc_id_table, |
1936 | .probe = lpfc_pci_probe_one, | 1998 | .probe = lpfc_pci_probe_one, |
1937 | .remove = __devexit_p(lpfc_pci_remove_one), | 1999 | .remove = __devexit_p(lpfc_pci_remove_one), |
1938 | .err_handler = &lpfc_err_handler, | 2000 | .err_handler = &lpfc_err_handler, |
1939 | }; | 2001 | }; |
1940 | 2002 | ||
1941 | static int __init | 2003 | static int __init |