diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index fa757b251f82..5b6e5395c8eb 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -145,8 +145,10 @@ lpfc_config_port_prep(struct lpfc_hba *phba) | |||
145 | return -ERESTART; | 145 | return -ERESTART; |
146 | } | 146 | } |
147 | 147 | ||
148 | if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp) | 148 | if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp) { |
149 | mempool_free(pmb, phba->mbox_mem_pool); | ||
149 | return -EINVAL; | 150 | return -EINVAL; |
151 | } | ||
150 | 152 | ||
151 | /* Save information as VPD data */ | 153 | /* Save information as VPD data */ |
152 | vp->rev.rBit = 1; | 154 | vp->rev.rBit = 1; |
@@ -551,18 +553,18 @@ static void | |||
551 | lpfc_hb_timeout(unsigned long ptr) | 553 | lpfc_hb_timeout(unsigned long ptr) |
552 | { | 554 | { |
553 | struct lpfc_hba *phba; | 555 | struct lpfc_hba *phba; |
556 | uint32_t tmo_posted; | ||
554 | unsigned long iflag; | 557 | unsigned long iflag; |
555 | 558 | ||
556 | phba = (struct lpfc_hba *)ptr; | 559 | phba = (struct lpfc_hba *)ptr; |
557 | spin_lock_irqsave(&phba->pport->work_port_lock, iflag); | 560 | spin_lock_irqsave(&phba->pport->work_port_lock, iflag); |
558 | if (!(phba->pport->work_port_events & WORKER_HB_TMO)) | 561 | tmo_posted = phba->pport->work_port_events & WORKER_HB_TMO; |
562 | if (!tmo_posted) | ||
559 | phba->pport->work_port_events |= WORKER_HB_TMO; | 563 | phba->pport->work_port_events |= WORKER_HB_TMO; |
560 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); | 564 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); |
561 | 565 | ||
562 | spin_lock_irqsave(&phba->hbalock, iflag); | 566 | if (!tmo_posted) |
563 | if (phba->work_wait) | 567 | lpfc_worker_wake_up(phba); |
564 | wake_up(phba->work_wait); | ||
565 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
566 | return; | 568 | return; |
567 | } | 569 | } |
568 | 570 | ||
@@ -851,6 +853,8 @@ lpfc_handle_latt(struct lpfc_hba *phba) | |||
851 | lpfc_read_la(phba, pmb, mp); | 853 | lpfc_read_la(phba, pmb, mp); |
852 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; | 854 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; |
853 | pmb->vport = vport; | 855 | pmb->vport = vport; |
856 | /* Block ELS IOCBs until we have processed this mbox command */ | ||
857 | phba->sli.ring[LPFC_ELS_RING].flag |= LPFC_STOP_IOCB_EVENT; | ||
854 | rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT); | 858 | rc = lpfc_sli_issue_mbox (phba, pmb, MBX_NOWAIT); |
855 | if (rc == MBX_NOT_FINISHED) { | 859 | if (rc == MBX_NOT_FINISHED) { |
856 | rc = 4; | 860 | rc = 4; |
@@ -866,6 +870,7 @@ lpfc_handle_latt(struct lpfc_hba *phba) | |||
866 | return; | 870 | return; |
867 | 871 | ||
868 | lpfc_handle_latt_free_mbuf: | 872 | lpfc_handle_latt_free_mbuf: |
873 | phba->sli.ring[LPFC_ELS_RING].flag &= ~LPFC_STOP_IOCB_EVENT; | ||
869 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 874 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
870 | lpfc_handle_latt_free_mp: | 875 | lpfc_handle_latt_free_mp: |
871 | kfree(mp); | 876 | kfree(mp); |
@@ -1194,8 +1199,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
1194 | /* Returns the number of buffers NOT posted. */ | 1199 | /* Returns the number of buffers NOT posted. */ |
1195 | /**************************************************/ | 1200 | /**************************************************/ |
1196 | int | 1201 | int |
1197 | lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt, | 1202 | lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt) |
1198 | int type) | ||
1199 | { | 1203 | { |
1200 | IOCB_t *icmd; | 1204 | IOCB_t *icmd; |
1201 | struct lpfc_iocbq *iocb; | 1205 | struct lpfc_iocbq *iocb; |
@@ -1295,7 +1299,7 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba) | |||
1295 | struct lpfc_sli *psli = &phba->sli; | 1299 | struct lpfc_sli *psli = &phba->sli; |
1296 | 1300 | ||
1297 | /* Ring 0, ELS / CT buffers */ | 1301 | /* Ring 0, ELS / CT buffers */ |
1298 | lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], LPFC_BUF_RING0, 1); | 1302 | lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], LPFC_BUF_RING0); |
1299 | /* Ring 2 - FCP no buffers needed */ | 1303 | /* Ring 2 - FCP no buffers needed */ |
1300 | 1304 | ||
1301 | return 0; | 1305 | return 0; |
@@ -1454,6 +1458,15 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1454 | 1458 | ||
1455 | lpfc_disc_state_machine(vport, ndlp, NULL, | 1459 | lpfc_disc_state_machine(vport, ndlp, NULL, |
1456 | NLP_EVT_DEVICE_RM); | 1460 | NLP_EVT_DEVICE_RM); |
1461 | |||
1462 | /* nlp_type zero is not defined, nlp_flag zero also not defined, | ||
1463 | * nlp_state is unused, this happens when | ||
1464 | * an initiator has logged | ||
1465 | * into us so cleanup this ndlp. | ||
1466 | */ | ||
1467 | if ((ndlp->nlp_type == 0) && (ndlp->nlp_flag == 0) && | ||
1468 | (ndlp->nlp_state == 0)) | ||
1469 | lpfc_nlp_put(ndlp); | ||
1457 | } | 1470 | } |
1458 | 1471 | ||
1459 | /* At this point, ALL ndlp's should be gone | 1472 | /* At this point, ALL ndlp's should be gone |
@@ -2101,6 +2114,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
2101 | phba->work_ha_mask = (HA_ERATT|HA_MBATT|HA_LATT); | 2114 | phba->work_ha_mask = (HA_ERATT|HA_MBATT|HA_LATT); |
2102 | phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4)); | 2115 | phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4)); |
2103 | 2116 | ||
2117 | /* Initialize the wait queue head for the kernel thread */ | ||
2118 | init_waitqueue_head(&phba->work_waitq); | ||
2119 | |||
2104 | /* Startup the kernel thread for this host adapter. */ | 2120 | /* Startup the kernel thread for this host adapter. */ |
2105 | phba->worker_thread = kthread_run(lpfc_do_work, phba, | 2121 | phba->worker_thread = kthread_run(lpfc_do_work, phba, |
2106 | "lpfc_worker_%d", phba->brd_no); | 2122 | "lpfc_worker_%d", phba->brd_no); |