aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c221
1 files changed, 148 insertions, 73 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 74cfa963dfc..eb5c75c45ba 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -185,6 +185,38 @@ lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
185} 185}
186 186
187/** 187/**
188 * lpfc_sli_cancel_iocbs - Cancel all iocbs from a list.
189 * @phba: Pointer to HBA context object.
190 * @iocblist: List of IOCBs.
191 * @ulpstatus: ULP status in IOCB command field.
192 * @ulpWord4: ULP word-4 in IOCB command field.
193 *
194 * This function is called with a list of IOCBs to cancel. It cancels the IOCB
195 * on the list by invoking the complete callback function associated with the
196 * IOCB with the provided @ulpstatus and @ulpword4 set to the IOCB commond
197 * fields.
198 **/
199void
200lpfc_sli_cancel_iocbs(struct lpfc_hba *phba, struct list_head *iocblist,
201 uint32_t ulpstatus, uint32_t ulpWord4)
202{
203 struct lpfc_iocbq *piocb;
204
205 while (!list_empty(iocblist)) {
206 list_remove_head(iocblist, piocb, struct lpfc_iocbq, list);
207
208 if (!piocb->iocb_cmpl)
209 lpfc_sli_release_iocbq(phba, piocb);
210 else {
211 piocb->iocb.ulpStatus = ulpstatus;
212 piocb->iocb.un.ulpWord[4] = ulpWord4;
213 (piocb->iocb_cmpl) (phba, piocb, piocb);
214 }
215 }
216 return;
217}
218
219/**
188 * lpfc_sli_iocb_cmd_type - Get the iocb type 220 * lpfc_sli_iocb_cmd_type - Get the iocb type
189 * @iocb_cmnd: iocb command code. 221 * @iocb_cmnd: iocb command code.
190 * 222 *
@@ -818,8 +850,8 @@ static struct lpfc_hbq_init lpfc_els_hbq = {
818 .profile = 0, 850 .profile = 0,
819 .ring_mask = (1 << LPFC_ELS_RING), 851 .ring_mask = (1 << LPFC_ELS_RING),
820 .buffer_count = 0, 852 .buffer_count = 0,
821 .init_count = 20, 853 .init_count = 40,
822 .add_count = 5, 854 .add_count = 40,
823}; 855};
824 856
825/* HBQ for the extra ring if needed */ 857/* HBQ for the extra ring if needed */
@@ -1596,7 +1628,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
1596 * Ring <ringno> handler: unexpected completion IoTag 1628 * Ring <ringno> handler: unexpected completion IoTag
1597 * <IoTag> 1629 * <IoTag>
1598 */ 1630 */
1599 lpfc_printf_vlog(cmdiocbp->vport, KERN_WARNING, LOG_SLI, 1631 lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
1600 "0322 Ring %d handler: " 1632 "0322 Ring %d handler: "
1601 "unexpected completion IoTag x%x " 1633 "unexpected completion IoTag x%x "
1602 "Data: x%x x%x x%x x%x\n", 1634 "Data: x%x x%x x%x x%x\n",
@@ -2324,7 +2356,6 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
2324{ 2356{
2325 LIST_HEAD(completions); 2357 LIST_HEAD(completions);
2326 struct lpfc_iocbq *iocb, *next_iocb; 2358 struct lpfc_iocbq *iocb, *next_iocb;
2327 IOCB_t *cmd = NULL;
2328 2359
2329 if (pring->ringno == LPFC_ELS_RING) { 2360 if (pring->ringno == LPFC_ELS_RING) {
2330 lpfc_fabric_abort_hba(phba); 2361 lpfc_fabric_abort_hba(phba);
@@ -2343,19 +2374,9 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
2343 2374
2344 spin_unlock_irq(&phba->hbalock); 2375 spin_unlock_irq(&phba->hbalock);
2345 2376
2346 while (!list_empty(&completions)) { 2377 /* Cancel all the IOCBs from the completions list */
2347 iocb = list_get_first(&completions, struct lpfc_iocbq, list); 2378 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
2348 cmd = &iocb->iocb; 2379 IOERR_SLI_ABORTED);
2349 list_del_init(&iocb->list);
2350
2351 if (!iocb->iocb_cmpl)
2352 lpfc_sli_release_iocbq(phba, iocb);
2353 else {
2354 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
2355 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
2356 (iocb->iocb_cmpl) (phba, iocb, iocb);
2357 }
2358 }
2359} 2380}
2360 2381
2361/** 2382/**
@@ -2373,8 +2394,6 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
2373{ 2394{
2374 LIST_HEAD(txq); 2395 LIST_HEAD(txq);
2375 LIST_HEAD(txcmplq); 2396 LIST_HEAD(txcmplq);
2376 struct lpfc_iocbq *iocb;
2377 IOCB_t *cmd = NULL;
2378 struct lpfc_sli *psli = &phba->sli; 2397 struct lpfc_sli *psli = &phba->sli;
2379 struct lpfc_sli_ring *pring; 2398 struct lpfc_sli_ring *pring;
2380 2399
@@ -2392,34 +2411,12 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
2392 spin_unlock_irq(&phba->hbalock); 2411 spin_unlock_irq(&phba->hbalock);
2393 2412
2394 /* Flush the txq */ 2413 /* Flush the txq */
2395 while (!list_empty(&txq)) { 2414 lpfc_sli_cancel_iocbs(phba, &txq, IOSTAT_LOCAL_REJECT,
2396 iocb = list_get_first(&txq, struct lpfc_iocbq, list); 2415 IOERR_SLI_DOWN);
2397 cmd = &iocb->iocb;
2398 list_del_init(&iocb->list);
2399
2400 if (!iocb->iocb_cmpl)
2401 lpfc_sli_release_iocbq(phba, iocb);
2402 else {
2403 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
2404 cmd->un.ulpWord[4] = IOERR_SLI_DOWN;
2405 (iocb->iocb_cmpl) (phba, iocb, iocb);
2406 }
2407 }
2408 2416
2409 /* Flush the txcmpq */ 2417 /* Flush the txcmpq */
2410 while (!list_empty(&txcmplq)) { 2418 lpfc_sli_cancel_iocbs(phba, &txcmplq, IOSTAT_LOCAL_REJECT,
2411 iocb = list_get_first(&txcmplq, struct lpfc_iocbq, list); 2419 IOERR_SLI_DOWN);
2412 cmd = &iocb->iocb;
2413 list_del_init(&iocb->list);
2414
2415 if (!iocb->iocb_cmpl)
2416 lpfc_sli_release_iocbq(phba, iocb);
2417 else {
2418 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
2419 cmd->un.ulpWord[4] = IOERR_SLI_DOWN;
2420 (iocb->iocb_cmpl) (phba, iocb, iocb);
2421 }
2422 }
2423} 2420}
2424 2421
2425/** 2422/**
@@ -3251,6 +3248,21 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
3251 struct lpfc_sli *psli = &phba->sli; 3248 struct lpfc_sli *psli = &phba->sli;
3252 struct lpfc_sli_ring *pring; 3249 struct lpfc_sli_ring *pring;
3253 3250
3251 /* Check the pmbox pointer first. There is a race condition
3252 * between the mbox timeout handler getting executed in the
3253 * worklist and the mailbox actually completing. When this
3254 * race condition occurs, the mbox_active will be NULL.
3255 */
3256 spin_lock_irq(&phba->hbalock);
3257 if (pmbox == NULL) {
3258 lpfc_printf_log(phba, KERN_WARNING,
3259 LOG_MBOX | LOG_SLI,
3260 "0353 Active Mailbox cleared - mailbox timeout "
3261 "exiting\n");
3262 spin_unlock_irq(&phba->hbalock);
3263 return;
3264 }
3265
3254 /* Mbox cmd <mbxCommand> timeout */ 3266 /* Mbox cmd <mbxCommand> timeout */
3255 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, 3267 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
3256 "0310 Mailbox command x%x timeout Data: x%x x%x x%p\n", 3268 "0310 Mailbox command x%x timeout Data: x%x x%x x%p\n",
@@ -3258,6 +3270,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
3258 phba->pport->port_state, 3270 phba->pport->port_state,
3259 phba->sli.sli_flag, 3271 phba->sli.sli_flag,
3260 phba->sli.mbox_active); 3272 phba->sli.mbox_active);
3273 spin_unlock_irq(&phba->hbalock);
3261 3274
3262 /* Setting state unknown so lpfc_sli_abort_iocb_ring 3275 /* Setting state unknown so lpfc_sli_abort_iocb_ring
3263 * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing 3276 * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing
@@ -3364,6 +3377,12 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
3364 goto out_not_finished; 3377 goto out_not_finished;
3365 } 3378 }
3366 3379
3380 /* If HBA has a deferred error attention, fail the iocb. */
3381 if (unlikely(phba->hba_flag & DEFER_ERATT)) {
3382 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
3383 goto out_not_finished;
3384 }
3385
3367 psli = &phba->sli; 3386 psli = &phba->sli;
3368 3387
3369 mb = &pmbox->mb; 3388 mb = &pmbox->mb;
@@ -3728,6 +3747,10 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3728 if (unlikely(pci_channel_offline(phba->pcidev))) 3747 if (unlikely(pci_channel_offline(phba->pcidev)))
3729 return IOCB_ERROR; 3748 return IOCB_ERROR;
3730 3749
3750 /* If HBA has a deferred error attention, fail the iocb. */
3751 if (unlikely(phba->hba_flag & DEFER_ERATT))
3752 return IOCB_ERROR;
3753
3731 /* 3754 /*
3732 * We should never get an IOCB if we are in a < LINK_DOWN state 3755 * We should never get an IOCB if we are in a < LINK_DOWN state
3733 */ 3756 */
@@ -3906,6 +3929,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
3906 uint16_t temp; 3929 uint16_t temp;
3907 struct temp_event temp_event_data; 3930 struct temp_event temp_event_data;
3908 struct Scsi_Host *shost; 3931 struct Scsi_Host *shost;
3932 uint32_t *iocb_w;
3909 3933
3910 icmd = &iocbq->iocb; 3934 icmd = &iocbq->iocb;
3911 evt_code = icmd->un.asyncstat.evt_code; 3935 evt_code = icmd->un.asyncstat.evt_code;
@@ -3913,13 +3937,23 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
3913 3937
3914 if ((evt_code != ASYNC_TEMP_WARN) && 3938 if ((evt_code != ASYNC_TEMP_WARN) &&
3915 (evt_code != ASYNC_TEMP_SAFE)) { 3939 (evt_code != ASYNC_TEMP_SAFE)) {
3940 iocb_w = (uint32_t *) icmd;
3916 lpfc_printf_log(phba, 3941 lpfc_printf_log(phba,
3917 KERN_ERR, 3942 KERN_ERR,
3918 LOG_SLI, 3943 LOG_SLI,
3919 "0346 Ring %d handler: unexpected ASYNC_STATUS" 3944 "0346 Ring %d handler: unexpected ASYNC_STATUS"
3920 " evt_code 0x%x\n", 3945 " evt_code 0x%x \n"
3946 "W0 0x%08x W1 0x%08x W2 0x%08x W3 0x%08x\n"
3947 "W4 0x%08x W5 0x%08x W6 0x%08x W7 0x%08x\n"
3948 "W8 0x%08x W9 0x%08x W10 0x%08x W11 0x%08x\n"
3949 "W12 0x%08x W13 0x%08x W14 0x%08x W15 0x%08x\n",
3921 pring->ringno, 3950 pring->ringno,
3922 icmd->un.asyncstat.evt_code); 3951 icmd->un.asyncstat.evt_code,
3952 iocb_w[0], iocb_w[1], iocb_w[2], iocb_w[3],
3953 iocb_w[4], iocb_w[5], iocb_w[6], iocb_w[7],
3954 iocb_w[8], iocb_w[9], iocb_w[10], iocb_w[11],
3955 iocb_w[12], iocb_w[13], iocb_w[14], iocb_w[15]);
3956
3923 return; 3957 return;
3924 } 3958 }
3925 temp_event_data.data = (uint32_t)temp; 3959 temp_event_data.data = (uint32_t)temp;
@@ -4178,17 +4212,9 @@ lpfc_sli_host_down(struct lpfc_vport *vport)
4178 4212
4179 spin_unlock_irqrestore(&phba->hbalock, flags); 4213 spin_unlock_irqrestore(&phba->hbalock, flags);
4180 4214
4181 while (!list_empty(&completions)) { 4215 /* Cancel all the IOCBs from the completions list */
4182 list_remove_head(&completions, iocb, struct lpfc_iocbq, list); 4216 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
4183 4217 IOERR_SLI_DOWN);
4184 if (!iocb->iocb_cmpl)
4185 lpfc_sli_release_iocbq(phba, iocb);
4186 else {
4187 iocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT;
4188 iocb->iocb.un.ulpWord[4] = IOERR_SLI_DOWN;
4189 (iocb->iocb_cmpl) (phba, iocb, iocb);
4190 }
4191 }
4192 return 1; 4218 return 1;
4193} 4219}
4194 4220
@@ -4215,8 +4241,6 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
4215 struct lpfc_sli_ring *pring; 4241 struct lpfc_sli_ring *pring;
4216 struct lpfc_dmabuf *buf_ptr; 4242 struct lpfc_dmabuf *buf_ptr;
4217 LPFC_MBOXQ_t *pmb; 4243 LPFC_MBOXQ_t *pmb;
4218 struct lpfc_iocbq *iocb;
4219 IOCB_t *cmd = NULL;
4220 int i; 4244 int i;
4221 unsigned long flags = 0; 4245 unsigned long flags = 0;
4222 4246
@@ -4244,18 +4268,9 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
4244 } 4268 }
4245 spin_unlock_irqrestore(&phba->hbalock, flags); 4269 spin_unlock_irqrestore(&phba->hbalock, flags);
4246 4270
4247 while (!list_empty(&completions)) { 4271 /* Cancel all the IOCBs from the completions list */
4248 list_remove_head(&completions, iocb, struct lpfc_iocbq, list); 4272 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
4249 cmd = &iocb->iocb; 4273 IOERR_SLI_DOWN);
4250
4251 if (!iocb->iocb_cmpl)
4252 lpfc_sli_release_iocbq(phba, iocb);
4253 else {
4254 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
4255 cmd->un.ulpWord[4] = IOERR_SLI_DOWN;
4256 (iocb->iocb_cmpl) (phba, iocb, iocb);
4257 }
4258 }
4259 4274
4260 spin_lock_irqsave(&phba->hbalock, flags); 4275 spin_lock_irqsave(&phba->hbalock, flags);
4261 list_splice_init(&phba->elsbuf, &completions); 4276 list_splice_init(&phba->elsbuf, &completions);
@@ -5137,11 +5152,31 @@ lpfc_sli_check_eratt(struct lpfc_hba *phba)
5137 return 0; 5152 return 0;
5138 } 5153 }
5139 5154
5155 /*
5156 * If there is deferred error attention, do not check for error
5157 * attention
5158 */
5159 if (unlikely(phba->hba_flag & DEFER_ERATT)) {
5160 spin_unlock_irq(&phba->hbalock);
5161 return 0;
5162 }
5163
5140 /* Read chip Host Attention (HA) register */ 5164 /* Read chip Host Attention (HA) register */
5141 ha_copy = readl(phba->HAregaddr); 5165 ha_copy = readl(phba->HAregaddr);
5142 if (ha_copy & HA_ERATT) { 5166 if (ha_copy & HA_ERATT) {
5143 /* Read host status register to retrieve error event */ 5167 /* Read host status register to retrieve error event */
5144 lpfc_sli_read_hs(phba); 5168 lpfc_sli_read_hs(phba);
5169
5170 /* Check if there is a deferred error condition is active */
5171 if ((HS_FFER1 & phba->work_hs) &&
5172 ((HS_FFER2 | HS_FFER3 | HS_FFER4 | HS_FFER5 |
5173 HS_FFER6 | HS_FFER7) & phba->work_hs)) {
5174 phba->hba_flag |= DEFER_ERATT;
5175 /* Clear all interrupt enable conditions */
5176 writel(0, phba->HCregaddr);
5177 readl(phba->HCregaddr);
5178 }
5179
5145 /* Set the driver HA work bitmap */ 5180 /* Set the driver HA work bitmap */
5146 phba->work_ha |= HA_ERATT; 5181 phba->work_ha |= HA_ERATT;
5147 /* Indicate polling handles this ERATT */ 5182 /* Indicate polling handles this ERATT */
@@ -5230,6 +5265,16 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
5230 /* Indicate interrupt handler handles ERATT */ 5265 /* Indicate interrupt handler handles ERATT */
5231 phba->hba_flag |= HBA_ERATT_HANDLED; 5266 phba->hba_flag |= HBA_ERATT_HANDLED;
5232 } 5267 }
5268
5269 /*
5270 * If there is deferred error attention, do not check for any
5271 * interrupt.
5272 */
5273 if (unlikely(phba->hba_flag & DEFER_ERATT)) {
5274 spin_unlock_irq(&phba->hbalock);
5275 return IRQ_NONE;
5276 }
5277
5233 /* Clear up only attention source related to slow-path */ 5278 /* Clear up only attention source related to slow-path */
5234 writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)), 5279 writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)),
5235 phba->HAregaddr); 5280 phba->HAregaddr);
@@ -5301,8 +5346,22 @@ lpfc_sp_intr_handler(int irq, void *dev_id)
5301 } 5346 }
5302 } 5347 }
5303 spin_lock_irqsave(&phba->hbalock, iflag); 5348 spin_lock_irqsave(&phba->hbalock, iflag);
5304 if (work_ha_copy & HA_ERATT) 5349 if (work_ha_copy & HA_ERATT) {
5305 lpfc_sli_read_hs(phba); 5350 lpfc_sli_read_hs(phba);
5351 /*
5352 * Check if there is a deferred error condition
5353 * is active
5354 */
5355 if ((HS_FFER1 & phba->work_hs) &&
5356 ((HS_FFER2 | HS_FFER3 | HS_FFER4 | HS_FFER5 |
5357 HS_FFER6 | HS_FFER7) & phba->work_hs)) {
5358 phba->hba_flag |= DEFER_ERATT;
5359 /* Clear all interrupt enable conditions */
5360 writel(0, phba->HCregaddr);
5361 readl(phba->HCregaddr);
5362 }
5363 }
5364
5306 if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) { 5365 if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) {
5307 pmb = phba->sli.mbox_active; 5366 pmb = phba->sli.mbox_active;
5308 pmbox = &pmb->mb; 5367 pmbox = &pmb->mb;
@@ -5466,6 +5525,14 @@ lpfc_fp_intr_handler(int irq, void *dev_id)
5466 ha_copy = readl(phba->HAregaddr); 5525 ha_copy = readl(phba->HAregaddr);
5467 /* Clear up only attention source related to fast-path */ 5526 /* Clear up only attention source related to fast-path */
5468 spin_lock_irqsave(&phba->hbalock, iflag); 5527 spin_lock_irqsave(&phba->hbalock, iflag);
5528 /*
5529 * If there is deferred error attention, do not check for
5530 * any interrupt.
5531 */
5532 if (unlikely(phba->hba_flag & DEFER_ERATT)) {
5533 spin_unlock_irq(&phba->hbalock);
5534 return IRQ_NONE;
5535 }
5469 writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)), 5536 writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)),
5470 phba->HAregaddr); 5537 phba->HAregaddr);
5471 readl(phba->HAregaddr); /* flush */ 5538 readl(phba->HAregaddr); /* flush */
@@ -5558,6 +5625,14 @@ lpfc_intr_handler(int irq, void *dev_id)
5558 phba->hba_flag |= HBA_ERATT_HANDLED; 5625 phba->hba_flag |= HBA_ERATT_HANDLED;
5559 } 5626 }
5560 5627
5628 /*
5629 * If there is deferred error attention, do not check for any interrupt.
5630 */
5631 if (unlikely(phba->hba_flag & DEFER_ERATT)) {
5632 spin_unlock_irq(&phba->hbalock);
5633 return IRQ_NONE;
5634 }
5635
5561 /* Clear attention sources except link and error attentions */ 5636 /* Clear attention sources except link and error attentions */
5562 writel((phba->ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); 5637 writel((phba->ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr);
5563 readl(phba->HAregaddr); /* flush */ 5638 readl(phba->HAregaddr); /* flush */