diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index cd9697edf860..8da8fc69227f 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -621,6 +621,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
621 | /** | 621 | /** |
622 | * lpfc_hba_init_link - Initialize the FC link | 622 | * lpfc_hba_init_link - Initialize the FC link |
623 | * @phba: pointer to lpfc hba data structure. | 623 | * @phba: pointer to lpfc hba data structure. |
624 | * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT | ||
624 | * | 625 | * |
625 | * This routine will issue the INIT_LINK mailbox command call. | 626 | * This routine will issue the INIT_LINK mailbox command call. |
626 | * It is available to other drivers through the lpfc_hba data | 627 | * It is available to other drivers through the lpfc_hba data |
@@ -632,7 +633,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
632 | * Any other value - error | 633 | * Any other value - error |
633 | **/ | 634 | **/ |
634 | int | 635 | int |
635 | lpfc_hba_init_link(struct lpfc_hba *phba) | 636 | lpfc_hba_init_link(struct lpfc_hba *phba, uint32_t flag) |
636 | { | 637 | { |
637 | struct lpfc_vport *vport = phba->pport; | 638 | struct lpfc_vport *vport = phba->pport; |
638 | LPFC_MBOXQ_t *pmb; | 639 | LPFC_MBOXQ_t *pmb; |
@@ -651,7 +652,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba) | |||
651 | phba->cfg_link_speed); | 652 | phba->cfg_link_speed); |
652 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 653 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
653 | lpfc_set_loopback_flag(phba); | 654 | lpfc_set_loopback_flag(phba); |
654 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 655 | rc = lpfc_sli_issue_mbox(phba, pmb, flag); |
655 | if (rc != MBX_SUCCESS) { | 656 | if (rc != MBX_SUCCESS) { |
656 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 657 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
657 | "0498 Adapter failed to init, mbxCmd x%x " | 658 | "0498 Adapter failed to init, mbxCmd x%x " |
@@ -664,17 +665,21 @@ lpfc_hba_init_link(struct lpfc_hba *phba) | |||
664 | writel(0xffffffff, phba->HAregaddr); | 665 | writel(0xffffffff, phba->HAregaddr); |
665 | readl(phba->HAregaddr); /* flush */ | 666 | readl(phba->HAregaddr); /* flush */ |
666 | phba->link_state = LPFC_HBA_ERROR; | 667 | phba->link_state = LPFC_HBA_ERROR; |
667 | if (rc != MBX_BUSY) | 668 | if (rc != MBX_BUSY || flag == MBX_POLL) |
668 | mempool_free(pmb, phba->mbox_mem_pool); | 669 | mempool_free(pmb, phba->mbox_mem_pool); |
669 | return -EIO; | 670 | return -EIO; |
670 | } | 671 | } |
671 | phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK; | 672 | phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK; |
673 | if (flag == MBX_POLL) | ||
674 | mempool_free(pmb, phba->mbox_mem_pool); | ||
672 | 675 | ||
673 | return 0; | 676 | return 0; |
674 | } | 677 | } |
675 | 678 | ||
676 | /** | 679 | /** |
677 | * lpfc_hba_down_link - this routine downs the FC link | 680 | * lpfc_hba_down_link - this routine downs the FC link |
681 | * @phba: pointer to lpfc hba data structure. | ||
682 | * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT | ||
678 | * | 683 | * |
679 | * This routine will issue the DOWN_LINK mailbox command call. | 684 | * This routine will issue the DOWN_LINK mailbox command call. |
680 | * It is available to other drivers through the lpfc_hba data | 685 | * It is available to other drivers through the lpfc_hba data |
@@ -685,7 +690,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba) | |||
685 | * Any other value - error | 690 | * Any other value - error |
686 | **/ | 691 | **/ |
687 | int | 692 | int |
688 | lpfc_hba_down_link(struct lpfc_hba *phba) | 693 | lpfc_hba_down_link(struct lpfc_hba *phba, uint32_t flag) |
689 | { | 694 | { |
690 | LPFC_MBOXQ_t *pmb; | 695 | LPFC_MBOXQ_t *pmb; |
691 | int rc; | 696 | int rc; |
@@ -701,7 +706,7 @@ lpfc_hba_down_link(struct lpfc_hba *phba) | |||
701 | "0491 Adapter Link is disabled.\n"); | 706 | "0491 Adapter Link is disabled.\n"); |
702 | lpfc_down_link(phba, pmb); | 707 | lpfc_down_link(phba, pmb); |
703 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 708 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
704 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 709 | rc = lpfc_sli_issue_mbox(phba, pmb, flag); |
705 | if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) { | 710 | if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) { |
706 | lpfc_printf_log(phba, | 711 | lpfc_printf_log(phba, |
707 | KERN_ERR, LOG_INIT, | 712 | KERN_ERR, LOG_INIT, |
@@ -711,6 +716,9 @@ lpfc_hba_down_link(struct lpfc_hba *phba) | |||
711 | mempool_free(pmb, phba->mbox_mem_pool); | 716 | mempool_free(pmb, phba->mbox_mem_pool); |
712 | return -EIO; | 717 | return -EIO; |
713 | } | 718 | } |
719 | if (flag == MBX_POLL) | ||
720 | mempool_free(pmb, phba->mbox_mem_pool); | ||
721 | |||
714 | return 0; | 722 | return 0; |
715 | } | 723 | } |
716 | 724 | ||
@@ -2279,10 +2287,32 @@ static void | |||
2279 | lpfc_block_mgmt_io(struct lpfc_hba * phba) | 2287 | lpfc_block_mgmt_io(struct lpfc_hba * phba) |
2280 | { | 2288 | { |
2281 | unsigned long iflag; | 2289 | unsigned long iflag; |
2290 | uint8_t actcmd = MBX_HEARTBEAT; | ||
2291 | unsigned long timeout; | ||
2292 | |||
2282 | 2293 | ||
2283 | spin_lock_irqsave(&phba->hbalock, iflag); | 2294 | spin_lock_irqsave(&phba->hbalock, iflag); |
2284 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; | 2295 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; |
2296 | if (phba->sli.mbox_active) | ||
2297 | actcmd = phba->sli.mbox_active->u.mb.mbxCommand; | ||
2285 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 2298 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
2299 | /* Determine how long we might wait for the active mailbox | ||
2300 | * command to be gracefully completed by firmware. | ||
2301 | */ | ||
2302 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, actcmd) * 1000) + | ||
2303 | jiffies; | ||
2304 | /* Wait for the outstnading mailbox command to complete */ | ||
2305 | while (phba->sli.mbox_active) { | ||
2306 | /* Check active mailbox complete status every 2ms */ | ||
2307 | msleep(2); | ||
2308 | if (time_after(jiffies, timeout)) { | ||
2309 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
2310 | "2813 Mgmt IO is Blocked %x " | ||
2311 | "- mbox cmd %x still active\n", | ||
2312 | phba->sli.sli_flag, actcmd); | ||
2313 | break; | ||
2314 | } | ||
2315 | } | ||
2286 | } | 2316 | } |
2287 | 2317 | ||
2288 | /** | 2318 | /** |