diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 128 |
1 files changed, 82 insertions, 46 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 49bed3e8c95d..9feeaff47a52 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -494,7 +494,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | |||
494 | * | 494 | * |
495 | * Returns sglq ponter = success, NULL = Failure. | 495 | * Returns sglq ponter = success, NULL = Failure. |
496 | **/ | 496 | **/ |
497 | static struct lpfc_sglq * | 497 | struct lpfc_sglq * |
498 | __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) | 498 | __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) |
499 | { | 499 | { |
500 | uint16_t adj_xri; | 500 | uint16_t adj_xri; |
@@ -526,6 +526,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba) | |||
526 | return NULL; | 526 | return NULL; |
527 | adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; | 527 | adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; |
528 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; | 528 | phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; |
529 | sglq->state = SGL_ALLOCATED; | ||
529 | return sglq; | 530 | return sglq; |
530 | } | 531 | } |
531 | 532 | ||
@@ -580,15 +581,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) | |||
580 | else | 581 | else |
581 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); | 582 | sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); |
582 | if (sglq) { | 583 | if (sglq) { |
583 | if (iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) { | 584 | if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && |
585 | (sglq->state != SGL_XRI_ABORTED)) { | ||
584 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, | 586 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, |
585 | iflag); | 587 | iflag); |
586 | list_add(&sglq->list, | 588 | list_add(&sglq->list, |
587 | &phba->sli4_hba.lpfc_abts_els_sgl_list); | 589 | &phba->sli4_hba.lpfc_abts_els_sgl_list); |
588 | spin_unlock_irqrestore( | 590 | spin_unlock_irqrestore( |
589 | &phba->sli4_hba.abts_sgl_list_lock, iflag); | 591 | &phba->sli4_hba.abts_sgl_list_lock, iflag); |
590 | } else | 592 | } else { |
593 | sglq->state = SGL_FREED; | ||
591 | list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); | 594 | list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); |
595 | } | ||
592 | } | 596 | } |
593 | 597 | ||
594 | 598 | ||
@@ -2258,41 +2262,56 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
2258 | spin_unlock_irqrestore(&phba->hbalock, | 2262 | spin_unlock_irqrestore(&phba->hbalock, |
2259 | iflag); | 2263 | iflag); |
2260 | } | 2264 | } |
2261 | if ((phba->sli_rev == LPFC_SLI_REV4) && | 2265 | if (phba->sli_rev == LPFC_SLI_REV4) { |
2262 | (saveq->iocb_flag & LPFC_EXCHANGE_BUSY)) { | 2266 | if (saveq->iocb_flag & |
2263 | /* Set cmdiocb flag for the exchange | 2267 | LPFC_EXCHANGE_BUSY) { |
2264 | * busy so sgl (xri) will not be | 2268 | /* Set cmdiocb flag for the |
2265 | * released until the abort xri is | 2269 | * exchange busy so sgl (xri) |
2266 | * received from hba, clear the | 2270 | * will not be released until |
2267 | * LPFC_DRIVER_ABORTED bit in case | 2271 | * the abort xri is received |
2268 | * it was driver initiated abort. | 2272 | * from hba. |
2269 | */ | 2273 | */ |
2270 | spin_lock_irqsave(&phba->hbalock, | 2274 | spin_lock_irqsave( |
2271 | iflag); | 2275 | &phba->hbalock, iflag); |
2272 | cmdiocbp->iocb_flag &= | 2276 | cmdiocbp->iocb_flag |= |
2273 | ~LPFC_DRIVER_ABORTED; | 2277 | LPFC_EXCHANGE_BUSY; |
2274 | cmdiocbp->iocb_flag |= | 2278 | spin_unlock_irqrestore( |
2275 | LPFC_EXCHANGE_BUSY; | 2279 | &phba->hbalock, iflag); |
2276 | spin_unlock_irqrestore(&phba->hbalock, | 2280 | } |
2277 | iflag); | 2281 | if (cmdiocbp->iocb_flag & |
2278 | cmdiocbp->iocb.ulpStatus = | 2282 | LPFC_DRIVER_ABORTED) { |
2279 | IOSTAT_LOCAL_REJECT; | 2283 | /* |
2280 | cmdiocbp->iocb.un.ulpWord[4] = | 2284 | * Clear LPFC_DRIVER_ABORTED |
2281 | IOERR_ABORT_REQUESTED; | 2285 | * bit in case it was driver |
2282 | /* | 2286 | * initiated abort. |
2283 | * For SLI4, irsiocb contains NO_XRI | 2287 | */ |
2284 | * in sli_xritag, it shall not affect | 2288 | spin_lock_irqsave( |
2285 | * releasing sgl (xri) process. | 2289 | &phba->hbalock, iflag); |
2286 | */ | 2290 | cmdiocbp->iocb_flag &= |
2287 | saveq->iocb.ulpStatus = | 2291 | ~LPFC_DRIVER_ABORTED; |
2288 | IOSTAT_LOCAL_REJECT; | 2292 | spin_unlock_irqrestore( |
2289 | saveq->iocb.un.ulpWord[4] = | 2293 | &phba->hbalock, iflag); |
2290 | IOERR_SLI_ABORTED; | 2294 | cmdiocbp->iocb.ulpStatus = |
2291 | spin_lock_irqsave(&phba->hbalock, | 2295 | IOSTAT_LOCAL_REJECT; |
2292 | iflag); | 2296 | cmdiocbp->iocb.un.ulpWord[4] = |
2293 | saveq->iocb_flag |= LPFC_DELAY_MEM_FREE; | 2297 | IOERR_ABORT_REQUESTED; |
2294 | spin_unlock_irqrestore(&phba->hbalock, | 2298 | /* |
2295 | iflag); | 2299 | * For SLI4, irsiocb contains |
2300 | * NO_XRI in sli_xritag, it | ||
2301 | * shall not affect releasing | ||
2302 | * sgl (xri) process. | ||
2303 | */ | ||
2304 | saveq->iocb.ulpStatus = | ||
2305 | IOSTAT_LOCAL_REJECT; | ||
2306 | saveq->iocb.un.ulpWord[4] = | ||
2307 | IOERR_SLI_ABORTED; | ||
2308 | spin_lock_irqsave( | ||
2309 | &phba->hbalock, iflag); | ||
2310 | saveq->iocb_flag |= | ||
2311 | LPFC_DELAY_MEM_FREE; | ||
2312 | spin_unlock_irqrestore( | ||
2313 | &phba->hbalock, iflag); | ||
2314 | } | ||
2296 | } | 2315 | } |
2297 | } | 2316 | } |
2298 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); | 2317 | (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); |
@@ -2515,14 +2534,16 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, | |||
2515 | 2534 | ||
2516 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, | 2535 | cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, |
2517 | &rspiocbq); | 2536 | &rspiocbq); |
2518 | if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { | 2537 | if (unlikely(!cmdiocbq)) |
2519 | spin_unlock_irqrestore(&phba->hbalock, | 2538 | break; |
2520 | iflag); | 2539 | if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) |
2521 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, | 2540 | cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED; |
2522 | &rspiocbq); | 2541 | if (cmdiocbq->iocb_cmpl) { |
2523 | spin_lock_irqsave(&phba->hbalock, | 2542 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
2524 | iflag); | 2543 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, |
2525 | } | 2544 | &rspiocbq); |
2545 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
2546 | } | ||
2526 | break; | 2547 | break; |
2527 | case LPFC_UNSOL_IOCB: | 2548 | case LPFC_UNSOL_IOCB: |
2528 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 2549 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
@@ -7451,6 +7472,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, | |||
7451 | { | 7472 | { |
7452 | wait_queue_head_t *pdone_q; | 7473 | wait_queue_head_t *pdone_q; |
7453 | unsigned long iflags; | 7474 | unsigned long iflags; |
7475 | struct lpfc_scsi_buf *lpfc_cmd; | ||
7454 | 7476 | ||
7455 | spin_lock_irqsave(&phba->hbalock, iflags); | 7477 | spin_lock_irqsave(&phba->hbalock, iflags); |
7456 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; | 7478 | cmdiocbq->iocb_flag |= LPFC_IO_WAKE; |
@@ -7458,6 +7480,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, | |||
7458 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, | 7480 | memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, |
7459 | &rspiocbq->iocb, sizeof(IOCB_t)); | 7481 | &rspiocbq->iocb, sizeof(IOCB_t)); |
7460 | 7482 | ||
7483 | /* Set the exchange busy flag for task management commands */ | ||
7484 | if ((cmdiocbq->iocb_flag & LPFC_IO_FCP) && | ||
7485 | !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) { | ||
7486 | lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf, | ||
7487 | cur_iocbq); | ||
7488 | lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY; | ||
7489 | } | ||
7490 | |||
7461 | pdone_q = cmdiocbq->context_un.wait_queue; | 7491 | pdone_q = cmdiocbq->context_un.wait_queue; |
7462 | if (pdone_q) | 7492 | if (pdone_q) |
7463 | wake_up(pdone_q); | 7493 | wake_up(pdone_q); |
@@ -9076,6 +9106,12 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, | |||
9076 | /* Fake the irspiocb and copy necessary response information */ | 9106 | /* Fake the irspiocb and copy necessary response information */ |
9077 | lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe); | 9107 | lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe); |
9078 | 9108 | ||
9109 | if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) { | ||
9110 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
9111 | cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED; | ||
9112 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
9113 | } | ||
9114 | |||
9079 | /* Pass the cmd_iocb and the rsp state to the upper layer */ | 9115 | /* Pass the cmd_iocb and the rsp state to the upper layer */ |
9080 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq); | 9116 | (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq); |
9081 | } | 9117 | } |