diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 598 |
1 files changed, 229 insertions, 369 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 5a3da38a9067..3c132604fd91 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -362,7 +362,7 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc) kfree(psb); break; } - psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP; + psb->cur_iocbq.cmd_flag |= LPFC_IO_FCP; psb->fcp_cmnd = psb->data; psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd); @@ -468,7 +468,7 @@ lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *vport) spin_lock(&qp->abts_io_buf_list_lock); list_for_each_entry_safe(psb, next_psb, &qp->lpfc_abts_io_buf_list, list) { - if (psb->cur_iocbq.iocb_flag & LPFC_IO_NVME) + if (psb->cur_iocbq.cmd_flag & LPFC_IO_NVME) continue; if (psb->rdata && psb->rdata->pnode && @@ -524,7 +524,7 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, list_del_init(&psb->list); psb->flags &= ~LPFC_SBUF_XBUSY; psb->status = IOSTAT_SUCCESS; - if (psb->cur_iocbq.iocb_flag & LPFC_IO_NVME) { + if (psb->cur_iocbq.cmd_flag & LPFC_IO_NVME) { qp->abts_nvme_io_bufs--; spin_unlock(&qp->abts_io_buf_list_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); @@ -571,7 +571,7 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, * for command completion wake up the thread. */ spin_lock_irqsave(&psb->buf_lock, iflag); - psb->cur_iocbq.iocb_flag &= + psb->cur_iocbq.cmd_flag &= ~LPFC_DRIVER_ABORTED; if (psb->waitq) wake_up(psb->waitq); @@ -593,8 +593,8 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, for (i = 1; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i]; - if (!(iocbq->iocb_flag & LPFC_IO_FCP) || - (iocbq->iocb_flag & LPFC_IO_LIBDFC)) + if (!(iocbq->cmd_flag & LPFC_IO_FCP) || + (iocbq->cmd_flag & LPFC_IO_LIBDFC)) continue; if (iocbq->sli4_xritag != xri) continue; @@ -695,7 +695,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, /* Setup key fields in buffer that may have been changed * if other protocols used this buffer. */ - lpfc_cmd->cur_iocbq.iocb_flag = LPFC_IO_FCP; + lpfc_cmd->cur_iocbq.cmd_flag = LPFC_IO_FCP; lpfc_cmd->prot_seg_cnt = 0; lpfc_cmd->seg_cnt = 0; lpfc_cmd->timeout = 0; @@ -783,7 +783,7 @@ lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *psb) spin_lock_irqsave(&phba->scsi_buf_list_put_lock, iflag); psb->pCmd = NULL; - psb->cur_iocbq.iocb_flag = LPFC_IO_FCP; + psb->cur_iocbq.cmd_flag = LPFC_IO_FCP; list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list_put); spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, iflag); } @@ -931,7 +931,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) physaddr = sg_dma_address(sgel); if (phba->sli_rev == 3 && !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && - !(iocbq->iocb_flag & DSS_SECURITY_OP) && + !(iocbq->cmd_flag & DSS_SECURITY_OP) && nseg <= LPFC_EXT_DATA_BDE_COUNT) { data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; data_bde->tus.f.bdeSize = sg_dma_len(sgel); @@ -959,7 +959,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) */ if (phba->sli_rev == 3 && !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && - !(iocbq->iocb_flag & DSS_SECURITY_OP)) { + !(iocbq->cmd_flag & DSS_SECURITY_OP)) { if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { /* * The extended IOCB format can only fit 3 BDE or a BPL. @@ -2942,154 +2942,58 @@ out: * -1 - Internal error (bad profile, ...etc) */ static int -lpfc_sli4_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, - struct lpfc_wcqe_complete *wcqe) +lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, + struct lpfc_iocbq *pIocbOut) { struct scsi_cmnd *cmd = lpfc_cmd->pCmd; + struct sli3_bg_fields *bgf; int ret = 0; - u32 status = bf_get(lpfc_wcqe_c_status, wcqe); + struct lpfc_wcqe_complete *wcqe; + u32 status; u32 bghm = 0; u32 bgstat = 0; u64 failing_sector = 0; - if (status == CQE_STATUS_DI_ERROR) { - if (bf_get(lpfc_wcqe_c_bg_ge, wcqe)) /* Guard Check failed */ - bgstat |= BGS_GUARD_ERR_MASK; - if (bf_get(lpfc_wcqe_c_bg_ae, wcqe)) /* AppTag Check failed */ - bgstat |= BGS_APPTAG_ERR_MASK; - if (bf_get(lpfc_wcqe_c_bg_re, wcqe)) /* RefTag Check failed */ - bgstat |= BGS_REFTAG_ERR_MASK; - - /* Check to see if there was any good data before the error */ - if (bf_get(lpfc_wcqe_c_bg_tdpv, wcqe)) { - bgstat |= BGS_HI_WATER_MARK_PRESENT_MASK; - bghm = wcqe->total_data_placed; - } - - /* - * Set ALL the error bits to indicate we don't know what - * type of error it is. - */ - if (!bgstat) - bgstat |= (BGS_REFTAG_ERR_MASK | BGS_APPTAG_ERR_MASK | - BGS_GUARD_ERR_MASK); - } - - if (lpfc_bgs_get_guard_err(bgstat)) { - ret = 1; - - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1); - set_host_byte(cmd, DID_ABORT); - phba->bg_guard_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9059 BLKGRD: Guard Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - scsi_logical_block_count(cmd), bgstat, bghm); - } - - if (lpfc_bgs_get_reftag_err(bgstat)) { - ret = 1; + if (phba->sli_rev == LPFC_SLI_REV4) { + wcqe = &pIocbOut->wcqe_cmpl; + status = bf_get(lpfc_wcqe_c_status, wcqe); - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3); - set_host_byte(cmd, DID_ABORT); + if (status == CQE_STATUS_DI_ERROR) { + /* Guard Check failed */ + if (bf_get(lpfc_wcqe_c_bg_ge, wcqe)) + bgstat |= BGS_GUARD_ERR_MASK; - phba->bg_reftag_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9060 BLKGRD: Ref Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - scsi_logical_block_count(cmd), bgstat, bghm); - } + /* AppTag Check failed */ + if (bf_get(lpfc_wcqe_c_bg_ae, wcqe)) + bgstat |= BGS_APPTAG_ERR_MASK; - if (lpfc_bgs_get_apptag_err(bgstat)) { - ret = 1; + /* RefTag Check failed */ + if (bf_get(lpfc_wcqe_c_bg_re, wcqe)) + bgstat |= BGS_REFTAG_ERR_MASK; - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2); - set_host_byte(cmd, DID_ABORT); - - phba->bg_apptag_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9062 BLKGRD: App Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - scsi_logical_block_count(cmd), bgstat, bghm); - } - - if (lpfc_bgs_get_hi_water_mark_present(bgstat)) { - /* - * setup sense data descriptor 0 per SPC-4 as an information - * field, and put the failing LBA in it. - * This code assumes there was also a guard/app/ref tag error - * indication. - */ - cmd->sense_buffer[7] = 0xc; /* Additional sense length */ - cmd->sense_buffer[8] = 0; /* Information descriptor type */ - cmd->sense_buffer[9] = 0xa; /* Additional descriptor length */ - cmd->sense_buffer[10] = 0x80; /* Validity bit */ + /* Check to see if there was any good data before the + * error + */ + if (bf_get(lpfc_wcqe_c_bg_tdpv, wcqe)) { + bgstat |= BGS_HI_WATER_MARK_PRESENT_MASK; + bghm = wcqe->total_data_placed; + } - /* bghm is a "on the wire" FC frame based count */ - switch (scsi_get_prot_op(cmd)) { - case SCSI_PROT_READ_INSERT: - case SCSI_PROT_WRITE_STRIP: - bghm /= cmd->device->sector_size; - break; - case SCSI_PROT_READ_STRIP: - case SCSI_PROT_WRITE_INSERT: - case SCSI_PROT_READ_PASS: - case SCSI_PROT_WRITE_PASS: - bghm /= (cmd->device->sector_size + - sizeof(struct scsi_dif_tuple)); - break; + /* + * Set ALL the error bits to indicate we don't know what + * type of error it is. + */ + if (!bgstat) + bgstat |= (BGS_REFTAG_ERR_MASK | + BGS_APPTAG_ERR_MASK | + BGS_GUARD_ERR_MASK); } - failing_sector = scsi_get_lba(cmd); - failing_sector += bghm; - - /* Descriptor Information */ - put_unaligned_be64(failing_sector, &cmd->sense_buffer[12]); - } - - if (!ret) { - /* No error was reported - problem in FW? */ - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9068 BLKGRD: Unknown error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - scsi_logical_block_count(cmd), bgstat, bghm); - - /* Calculate what type of error it was */ - lpfc_calc_bg_err(phba, lpfc_cmd); + } else { + bgf = &pIocbOut->iocb.unsli3.sli3_bg; + bghm = bgf->bghm; + bgstat = bgf->bgstat; } - return ret; -} - -/* - * This function checks for BlockGuard errors detected by - * the HBA. In case of errors, the ASC/ASCQ fields in the - * sense buffer will be set accordingly, paired with - * ILLEGAL_REQUEST to signal to the kernel that the HBA - * detected corruption. - * - * Returns: - * 0 - No error found - * 1 - BlockGuard error found - * -1 - Internal error (bad profile, ...etc) - */ -static int -lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, - struct lpfc_iocbq *pIocbOut) -{ - struct scsi_cmnd *cmd = lpfc_cmd->pCmd; - struct sli3_bg_fields *bgf = &pIocbOut->iocb.unsli3.sli3_bg; - int ret = 0; - uint32_t bghm = bgf->bghm; - uint32_t bgstat = bgf->bgstat; - uint64_t failing_sector = 0; if (lpfc_bgs_get_invalid_prof(bgstat)) { cmd->result = DID_ERROR << 16; @@ -3117,7 +3021,6 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (lpfc_bgs_get_guard_err(bgstat)) { ret = 1; - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1); set_host_byte(cmd, DID_ABORT); phba->bg_guard_err_cnt++; @@ -3131,10 +3034,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (lpfc_bgs_get_reftag_err(bgstat)) { ret = 1; - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3); set_host_byte(cmd, DID_ABORT); - phba->bg_reftag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, "9056 BLKGRD: Ref Tag error in cmd " @@ -3146,10 +3047,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (lpfc_bgs_get_apptag_err(bgstat)) { ret = 1; - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2); set_host_byte(cmd, DID_ABORT); - phba->bg_apptag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, "9061 BLKGRD: App Tag error in cmd " @@ -3434,7 +3333,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) */ if ((phba->cfg_fof) && ((struct lpfc_device_data *) scsi_cmnd->device->hostdata)->oas_enabled) { - lpfc_cmd->cur_iocbq.iocb_flag |= (LPFC_IO_OAS | LPFC_IO_FOF); + lpfc_cmd->cur_iocbq.cmd_flag |= (LPFC_IO_OAS | LPFC_IO_FOF); lpfc_cmd->cur_iocbq.priority = ((struct lpfc_device_data *) scsi_cmnd->device->hostdata)->priority; @@ -3591,15 +3490,15 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, switch (scsi_get_prot_op(scsi_cmnd)) { case SCSI_PROT_WRITE_STRIP: case SCSI_PROT_READ_STRIP: - lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_DIF_STRIP; + lpfc_cmd->cur_iocbq.cmd_flag |= LPFC_IO_DIF_STRIP; break; case SCSI_PROT_WRITE_INSERT: case SCSI_PROT_READ_INSERT: - lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_DIF_INSERT; + lpfc_cmd->cur_iocbq.cmd_flag |= LPFC_IO_DIF_INSERT; break; case SCSI_PROT_WRITE_PASS: case SCSI_PROT_READ_PASS: - lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_DIF_PASS; + lpfc_cmd->cur_iocbq.cmd_flag |= LPFC_IO_DIF_PASS; break; } @@ -3630,7 +3529,7 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, */ if ((phba->cfg_fof) && ((struct lpfc_device_data *) scsi_cmnd->device->hostdata)->oas_enabled) { - lpfc_cmd->cur_iocbq.iocb_flag |= (LPFC_IO_OAS | LPFC_IO_FOF); + lpfc_cmd->cur_iocbq.cmd_flag |= (LPFC_IO_OAS | LPFC_IO_FOF); /* Word 10 */ bf_set(wqe_oas, &wqe->generic.wqe_com, 1); @@ -3640,14 +3539,14 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, } /* Word 7. DIF Flags */ - if (lpfc_cmd->cur_iocbq.iocb_flag & LPFC_IO_DIF_PASS) + if (lpfc_cmd->cur_iocbq.cmd_flag & LPFC_IO_DIF_PASS) bf_set(wqe_dif, &wqe->generic.wqe_com, LPFC_WQE_DIF_PASSTHRU); - else if (lpfc_cmd->cur_iocbq.iocb_flag & LPFC_IO_DIF_STRIP) + else if (lpfc_cmd->cur_iocbq.cmd_flag & LPFC_IO_DIF_STRIP) bf_set(wqe_dif, &wqe->generic.wqe_com, LPFC_WQE_DIF_STRIP); - else if (lpfc_cmd->cur_iocbq.iocb_flag & LPFC_IO_DIF_INSERT) + else if (lpfc_cmd->cur_iocbq.cmd_flag & LPFC_IO_DIF_INSERT) bf_set(wqe_dif, &wqe->generic.wqe_com, LPFC_WQE_DIF_INSERT); - lpfc_cmd->cur_iocbq.iocb_flag &= ~(LPFC_IO_DIF_PASS | + lpfc_cmd->cur_iocbq.cmd_flag &= ~(LPFC_IO_DIF_PASS | LPFC_IO_DIF_STRIP | LPFC_IO_DIF_INSERT); return 0; @@ -4173,7 +4072,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, * lpfc_fcp_io_cmd_wqe_cmpl - Complete a FCP IO * @phba: The hba for which this call is being executed. * @pwqeIn: The command WQE for the scsi cmnd. - * @wcqe: Pointer to driver response CQE object. + * @pwqeOut: Pointer to driver response WQE object. * * This routine assigns scsi command result by looking into response WQE * status field appropriately. This routine handles QUEUE FULL condition as @@ -4181,10 +4080,11 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, **/ static void lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, - struct lpfc_wcqe_complete *wcqe) + struct lpfc_iocbq *pwqeOut) { struct lpfc_io_buf *lpfc_cmd = (struct lpfc_io_buf *)pwqeIn->context1; + struct lpfc_wcqe_complete *wcqe = &pwqeOut->wcqe_cmpl; struct lpfc_vport *vport = pwqeIn->vport; struct lpfc_rport_data *rdata; struct lpfc_nodelist *ndlp; @@ -4194,7 +4094,6 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, struct Scsi_Host *shost; u32 logit = LOG_FCP; u32 status, idx; - unsigned long iflags = 0; u32 lat; u8 wait_xb_clr = 0; @@ -4209,30 +4108,16 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, rdata = lpfc_cmd->rdata; ndlp = rdata->pnode; - if (bf_get(lpfc_wcqe_c_xb, wcqe)) { - /* TOREMOVE - currently this flag is checked during - * the release of lpfc_iocbq. Remove once we move - * to lpfc_wqe_job construct. - * - * This needs to be done outside buf_lock - */ - spin_lock_irqsave(&phba->hbalock, iflags); - lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_EXCHANGE_BUSY; - spin_unlock_irqrestore(&phba->hbalock, iflags); - } - - /* Guard against abort handler being called at same time */ - spin_lock(&lpfc_cmd->buf_lock); - /* Sanity check on return of outstanding command */ cmd = lpfc_cmd->pCmd; if (!cmd) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "9042 I/O completion: Not an active IO\n"); - spin_unlock(&lpfc_cmd->buf_lock); lpfc_release_scsi_buf(phba, lpfc_cmd); return; } + /* Guard against abort handler being called at same time */ + spin_lock(&lpfc_cmd->buf_lock); idx = lpfc_cmd->cur_iocbq.hba_wqidx; if (phba->sli4_hba.hdwq) phba->sli4_hba.hdwq[idx].scsi_cstat.io_cmpls++; @@ -4407,12 +4292,14 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, * This is a response for a BG enabled * cmd. Parse BG error */ - lpfc_sli4_parse_bg_err(phba, lpfc_cmd, - wcqe); + lpfc_parse_bg_err(phba, lpfc_cmd, pwqeOut); break; + } else { + lpfc_printf_vlog(vport, KERN_WARNING, + LOG_BG, + "9040 non-zero BGSTAT " + "on unprotected cmd\n"); } - lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, - "9040 non-zero BGSTAT on unprotected cmd\n"); } lpfc_printf_vlog(vport, KERN_WARNING, logit, "9036 Local Reject FCP cmd x%x failed" @@ -4510,7 +4397,7 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, * wake up the thread. */ spin_lock(&lpfc_cmd->buf_lock); - lpfc_cmd->cur_iocbq.iocb_flag &= ~LPFC_DRIVER_ABORTED; + lpfc_cmd->cur_iocbq.cmd_flag &= ~LPFC_DRIVER_ABORTED; if (lpfc_cmd->waitq) wake_up(lpfc_cmd->waitq); spin_unlock(&lpfc_cmd->buf_lock); @@ -4570,7 +4457,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, lpfc_cmd->status = pIocbOut->iocb.ulpStatus; /* pick up SLI4 exchange busy status from HBA */ lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY; - if (pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY) + if (pIocbOut->cmd_flag & LPFC_EXCHANGE_BUSY) lpfc_cmd->flags |= LPFC_SBUF_XBUSY; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS @@ -4779,7 +4666,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, * wake up the thread. */ spin_lock(&lpfc_cmd->buf_lock); - lpfc_cmd->cur_iocbq.iocb_flag &= ~LPFC_DRIVER_ABORTED; + lpfc_cmd->cur_iocbq.cmd_flag &= ~LPFC_DRIVER_ABORTED; if (lpfc_cmd->waitq) wake_up(lpfc_cmd->waitq); spin_unlock(&lpfc_cmd->buf_lock); @@ -4857,8 +4744,8 @@ static int lpfc_scsi_prep_cmnd_buf_s3(struct lpfc_vport *vport, piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f); piocbq->context1 = lpfc_cmd; - if (!piocbq->iocb_cmpl) - piocbq->iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl; + if (!piocbq->cmd_cmpl) + piocbq->cmd_cmpl = lpfc_scsi_cmd_iocb_cmpl; piocbq->iocb.ulpTimeout = tmo; piocbq->vport = vport; return 0; @@ -4971,7 +4858,7 @@ static int lpfc_scsi_prep_cmnd_buf_s4(struct lpfc_vport *vport, pwqeq->vport = vport; pwqeq->context1 = lpfc_cmd; pwqeq->hba_wqidx = lpfc_cmd->hdwq_no; - pwqeq->wqe_cmpl = lpfc_fcp_io_cmd_wqe_cmpl; + pwqeq->cmd_cmpl = lpfc_fcp_io_cmd_wqe_cmpl; return 0; } @@ -5018,7 +4905,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, } /** - * lpfc_scsi_prep_task_mgmt_cmd - Convert SLI3 scsi TM cmd to FCP info unit + * lpfc_scsi_prep_task_mgmt_cmd_s3 - Convert SLI3 scsi TM cmd to FCP info unit * @vport: The virtual port for which this call is being executed. * @lpfc_cmd: Pointer to lpfc_io_buf data structure. * @lun: Logical unit number. @@ -5032,10 +4919,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, * 1 - Success **/ static int -lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, - struct lpfc_io_buf *lpfc_cmd, - uint64_t lun, - uint8_t task_mgmt_cmd) +lpfc_scsi_prep_task_mgmt_cmd_s3(struct lpfc_vport *vport, + struct lpfc_io_buf *lpfc_cmd, + u64 lun, u8 task_mgmt_cmd) { struct lpfc_iocbq *piocbq; IOCB_t *piocb; @@ -5056,15 +4942,10 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd)); int_to_scsilun(lun, &fcp_cmnd->fcp_lun); fcp_cmnd->fcpCntl2 = task_mgmt_cmd; - if (vport->phba->sli_rev == 3 && - !(vport->phba->sli3_options & LPFC_SLI3_BG_ENABLED)) + if (!(vport->phba->sli3_options & LPFC_SLI3_BG_ENABLED)) lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd); piocb->ulpCommand = CMD_FCP_ICMND64_CR; piocb->ulpContext = ndlp->nlp_rpi; - if (vport->phba->sli_rev == LPFC_SLI_REV4) { - piocb->ulpContext = - vport->phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; - } piocb->ulpFCP2Rcvy = (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) ? 1 : 0; piocb->ulpClass = (ndlp->nlp_fcp_info & 0x0f); piocb->ulpPU = 0; @@ -5080,8 +4961,79 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, } else piocb->ulpTimeout = lpfc_cmd->timeout; - if (vport->phba->sli_rev == LPFC_SLI_REV4) - lpfc_sli4_set_rsp_sgl_last(vport->phba, lpfc_cmd); + return 1; +} + +/** + * lpfc_scsi_prep_task_mgmt_cmd_s4 - Convert SLI4 scsi TM cmd to FCP info unit + * @vport: The virtual port for which this call is being executed. + * @lpfc_cmd: Pointer to lpfc_io_buf data structure. + * @lun: Logical unit number. + * @task_mgmt_cmd: SCSI task management command. + * + * This routine creates FCP information unit corresponding to @task_mgmt_cmd + * for device with SLI-4 interface spec. + * + * Return codes: + * 0 - Error + * 1 - Success + **/ +static int +lpfc_scsi_prep_task_mgmt_cmd_s4(struct lpfc_vport *vport, + struct lpfc_io_buf *lpfc_cmd, + u64 lun, u8 task_mgmt_cmd) +{ + struct lpfc_iocbq *pwqeq = &lpfc_cmd->cur_iocbq; + union lpfc_wqe128 *wqe = &pwqeq->wqe; + struct fcp_cmnd *fcp_cmnd; + struct lpfc_rport_data *rdata = lpfc_cmd->rdata; + struct lpfc_nodelist *ndlp = rdata->pnode; + + if (!ndlp || ndlp->nlp_state != NLP_STE_MAPPED_NODE) + return 0; + + pwqeq->vport = vport; + /* Initialize 64 bytes only */ + memset(wqe, 0, sizeof(union lpfc_wqe128)); + + /* From the icmnd template, initialize words 4 - 11 */ + memcpy(&wqe->words[4], &lpfc_icmnd_cmd_template.words[4], + sizeof(uint32_t) * 8); + + fcp_cmnd = lpfc_cmd->fcp_cmnd; + /* Clear out any old data in the FCP command area */ + memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd)); + int_to_scsilun(lun, &fcp_cmnd->fcp_lun); + fcp_cmnd->fcpCntl3 = 0; + fcp_cmnd->fcpCntl2 = task_mgmt_cmd; + + bf_set(payload_offset_len, &wqe->fcp_icmd, + sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); + bf_set(cmd_buff_len, &wqe->fcp_icmd, 0); + bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com, /* ulpContext */ + vport->phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); + bf_set(wqe_erp, &wqe->fcp_icmd.wqe_com, + ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) ? 1 : 0)); + bf_set(wqe_class, &wqe->fcp_icmd.wqe_com, + (ndlp->nlp_fcp_info & 0x0f)); + + /* ulpTimeout is only one byte */ + if (lpfc_cmd->timeout > 0xff) { + /* + * Do not timeout the command at the firmware level. + * The driver will provide the timeout mechanism. + */ + bf_set(wqe_tmo, &wqe->fcp_icmd.wqe_com, 0); + } else { + bf_set(wqe_tmo, &wqe->fcp_icmd.wqe_com, lpfc_cmd->timeout); + } + + lpfc_prep_embed_io(vport->phba, lpfc_cmd); + bf_set(wqe_xri_tag, &wqe->generic.wqe_com, pwqeq->sli4_xritag); + wqe->generic.wqe_com.abort_tag = pwqeq->iotag; + bf_set(wqe_reqtag, &wqe->generic.wqe_com, pwqeq->iotag); + + lpfc_sli4_set_rsp_sgl_last(vport->phba, lpfc_cmd); return 1; } @@ -5108,6 +5060,8 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3; phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s3; phba->lpfc_scsi_prep_cmnd_buf = lpfc_scsi_prep_cmnd_buf_s3; + phba->lpfc_scsi_prep_task_mgmt_cmd = + lpfc_scsi_prep_task_mgmt_cmd_s3; break; case LPFC_PCI_DEV_OC: phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4; @@ -5115,6 +5069,8 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4; phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s4; phba->lpfc_scsi_prep_cmnd_buf = lpfc_scsi_prep_cmnd_buf_s4; + phba->lpfc_scsi_prep_task_mgmt_cmd = + lpfc_scsi_prep_task_mgmt_cmd_s4; break; default: lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -5593,6 +5549,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) { struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; + struct lpfc_iocbq *cur_iocbq = NULL; struct lpfc_rport_data *rdata; struct lpfc_nodelist *ndlp; struct lpfc_io_buf *lpfc_cmd; @@ -5686,6 +5643,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) } lpfc_cmd->rx_cmd_start = start; + cur_iocbq = &lpfc_cmd->cur_iocbq; /* * Store the midlayer's command structure for the completion phase * and complete the command initialization. @@ -5693,7 +5651,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) lpfc_cmd->pCmd = cmnd; lpfc_cmd->rdata = rdata; lpfc_cmd->ndlp = ndlp; - lpfc_cmd->cur_iocbq.iocb_cmpl = NULL; + cur_iocbq->cmd_cmpl = NULL; cmnd->host_scribble = (unsigned char *)lpfc_cmd; err = lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp); @@ -5735,7 +5693,6 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) goto out_host_busy_free_buf; } - /* check the necessary and sufficient condition to support VMID */ if (lpfc_is_vmid_enabled(phba) && (ndlp->vmid_support || @@ -5748,20 +5705,19 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) if (uuid) { err = lpfc_vmid_get_appid(vport, uuid, cmnd, (union lpfc_vmid_io_tag *) - &lpfc_cmd->cur_iocbq.vmid_tag); + &cur_iocbq->vmid_tag); if (!err) - lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_VMID; + cur_iocbq->cmd_flag |= LPFC_IO_VMID; } } - atomic_inc(&ndlp->cmd_pending); + #ifdef CONFIG_SCSI_LPFC_DEBUG_FS if (unlikely(phba->hdwqstat_on & LPFC_CHECK_SCSI_IO)) this_cpu_inc(phba->sli4_hba.c_stat->xmt_io); #endif /* Issue I/O to adapter */ - err = lpfc_sli_issue_fcp_io(phba, LPFC_FCP_RING, - &lpfc_cmd->cur_iocbq, + err = lpfc_sli_issue_fcp_io(phba, LPFC_FCP_RING, cur_iocbq, SLI_IOCB_RET_IOCB); #ifdef CONFIG_SCSI_LPFC_DEBUG_FS if (start) { @@ -5774,25 +5730,25 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) #endif if (err) { lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, - "3376 FCP could not issue IOCB err %x " - "FCP cmd x%x <%d/%llu> " - "sid: x%x did: x%x oxid: x%x " - "Data: x%x x%x x%x x%x\n", - err, cmnd->cmnd[0], - cmnd->device ? cmnd->device->id : 0xffff, - cmnd->device ? cmnd->device->lun : (u64)-1, - vport->fc_myDID, ndlp->nlp_DID, - phba->sli_rev == LPFC_SLI_REV4 ? - lpfc_cmd->cur_iocbq.sli4_xritag : 0xffff, - phba->sli_rev == LPFC_SLI_REV4 ? - phba->sli4_hba.rpi_ids[ndlp->nlp_rpi] : - lpfc_cmd->cur_iocbq.iocb.ulpContext, - lpfc_cmd->cur_iocbq.iotag, - phba->sli_rev == LPFC_SLI_REV4 ? - bf_get(wqe_tmo, - &lpfc_cmd->cur_iocbq.wqe.generic.wqe_com) : - lpfc_cmd->cur_iocbq.iocb.ulpTimeout, - (uint32_t)(scsi_cmd_to_rq(cmnd)->timeout / 1000)); + "3376 FCP could not issue iocb err %x " + "FCP cmd x%x <%d/%llu> " + "sid: x%x did: x%x oxid: x%x " + "Data: x%x x%x x%x x%x\n", + err, cmnd->cmnd[0], + cmnd->device ? cmnd->device->id : 0xffff, + cmnd->device ? cmnd->device->lun : (u64)-1, + vport->fc_myDID, ndlp->nlp_DID, + phba->sli_rev == LPFC_SLI_REV4 ? + cur_iocbq->sli4_xritag : 0xffff, + phba->sli_rev == LPFC_SLI_REV4 ? + phba->sli4_hba.rpi_ids[ndlp->nlp_rpi] : + cur_iocbq->iocb.ulpContext, + cur_iocbq->iotag, + phba->sli_rev == LPFC_SLI_REV4 ? + bf_get(wqe_tmo, + &cur_iocbq->wqe.generic.wqe_com) : + cur_iocbq->iocb.ulpTimeout, + (uint32_t)(scsi_cmd_to_rq(cmnd)->timeout / 1000)); goto out_host_busy_free_buf; } @@ -5888,6 +5844,7 @@ static int lpfc_abort_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; + struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *iocb; @@ -5899,7 +5856,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) unsigned long flags; DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); - status = fc_block_scsi_eh(cmnd); + status = fc_block_rport(rport); if (status != 0 && status != SUCCESS) return status; @@ -5938,7 +5895,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) spin_lock(&pring_s4->ring_lock); } /* the command is in process of being cancelled */ - if (!(iocb->iocb_flag & LPFC_IO_ON_TXCMPLQ)) { + if (!(iocb->cmd_flag & LPFC_IO_ON_TXCMPLQ)) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "3169 SCSI Layer abort requested I/O has been " "cancelled by LLD.\n"); @@ -5961,7 +5918,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) BUG_ON(iocb->context1 != lpfc_cmd); /* abort issued in recovery is still in progress */ - if (iocb->iocb_flag & LPFC_DRIVER_ABORTED) { + if (iocb->cmd_flag & LPFC_DRIVER_ABORTED) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "3389 SCSI Layer I/O Abort Request is pending\n"); if (phba->sli_rev == LPFC_SLI_REV4) @@ -5972,15 +5929,13 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) } lpfc_cmd->waitq = &waitq; - if (phba->sli_rev == LPFC_SLI_REV4) { + if (phba->sli_rev == LPFC_SLI_REV4) spin_unlock(&pring_s4->ring_lock); - ret_val = lpfc_sli4_issue_abort_iotag(phba, iocb, - lpfc_sli4_abort_fcp_cmpl); - } else { + else pring = &phba->sli.sli3_ring[LPFC_FCP_RING]; - ret_val = lpfc_sli_issue_abort_iotag(phba, pring, iocb, - lpfc_sli_abort_fcp_cmpl); - } + + ret_val = lpfc_sli_issue_abort_iotag(phba, pring, iocb, + lpfc_sli_abort_fcp_cmpl); /* Make sure HBA is alive */ lpfc_issue_hb_tmo(phba); @@ -6004,7 +5959,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) wait_for_cmpl: /* - * iocb_flag is set to LPFC_DRIVER_ABORTED before we wait + * cmd_flag is set to LPFC_DRIVER_ABORTED before we wait * for abort to complete. */ wait_event_timeout(waitq, @@ -6141,7 +6096,7 @@ lpfc_check_fcp_rsp(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd) /** * lpfc_send_taskmgmt - Generic SCSI Task Mgmt Handler * @vport: The virtual port for which this call is being executed. - * @cmnd: Pointer to scsi_cmnd data structure. + * @rport: Pointer to remote port * @tgt_id: Target ID of remote device. * @lun_id: Lun number for the TMF * @task_mgmt_cmd: type of TMF to send @@ -6154,7 +6109,7 @@ lpfc_check_fcp_rsp(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd) * 0x2002 - Success. **/ static int -lpfc_send_taskmgmt(struct lpfc_vport *vport, struct scsi_cmnd *cmnd, +lpfc_send_taskmgmt(struct lpfc_vport *vport, struct fc_rport *rport, unsigned int tgt_id, uint64_t lun_id, uint8_t task_mgmt_cmd) { @@ -6167,21 +6122,21 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct scsi_cmnd *cmnd, int ret; int status; - rdata = lpfc_rport_data_from_scsi_device(cmnd->device); + rdata = rport->dd_data; if (!rdata || !rdata->pnode) return FAILED; pnode = rdata->pnode; - lpfc_cmd = lpfc_get_scsi_buf(phba, pnode, NULL); + lpfc_cmd = lpfc_get_scsi_buf(phba, rdata->pnode, NULL); if (lpfc_cmd == NULL) return FAILED; lpfc_cmd->timeout = phba->cfg_task_mgmt_tmo; lpfc_cmd->rdata = rdata; - lpfc_cmd->pCmd = cmnd; + lpfc_cmd->pCmd = NULL; lpfc_cmd->ndlp = pnode; - status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun_id, - task_mgmt_cmd); + status = phba->lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun_id, + task_mgmt_cmd); if (!status) { lpfc_release_scsi_buf(phba, lpfc_cmd); return FAILED; @@ -6193,38 +6148,41 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct scsi_cmnd *cmnd, lpfc_release_scsi_buf(phba, lpfc_cmd); return FAILED; } - iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; + iocbq->cmd_cmpl = lpfc_tskmgmt_def_cmpl; + iocbq->vport = vport; lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, "0702 Issue %s to TGT %d LUN %llu " "rpi x%x nlp_flag x%x Data: x%x x%x\n", lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id, pnode->nlp_rpi, pnode->nlp_flag, iocbq->sli4_xritag, - iocbq->iocb_flag); + iocbq->cmd_flag); status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING, iocbq, iocbqrsp, lpfc_cmd->timeout); if ((status != IOCB_SUCCESS) || - (iocbqrsp->iocb.ulpStatus != IOSTAT_SUCCESS)) { + (get_job_ulpstatus(phba, iocbqrsp) != IOSTAT_SUCCESS)) { if (status != IOCB_SUCCESS || - iocbqrsp->iocb.ulpStatus != IOSTAT_FCP_RSP_ERROR) + get_job_ulpstatus(phba, iocbqrsp) != IOSTAT_FCP_RSP_ERROR) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "0727 TMF %s to TGT %d LUN %llu " - "failed (%d, %d) iocb_flag x%x\n", + "failed (%d, %d) cmd_flag x%x\n", lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id, - iocbqrsp->iocb.ulpStatus, - iocbqrsp->iocb.un.ulpWord[4], - iocbq->iocb_flag); + get_job_ulpstatus(phba, iocbqrsp), + get_job_word4(phba, iocbqrsp), + iocbq->cmd_flag); /* if ulpStatus != IOCB_SUCCESS, then status == IOCB_SUCCESS */ if (status == IOCB_SUCCESS) { - if (iocbqrsp->iocb.ulpStatus == IOSTAT_FCP_RSP_ERROR) + if (get_job_ulpstatus(phba, iocbqrsp) == + IOSTAT_FCP_RSP_ERROR) /* Something in the FCP_RSP was invalid. * Check conditions */ ret = lpfc_check_fcp_rsp(vport, lpfc_cmd); else ret = FAILED; - } else if (status == IOCB_TIMEDOUT) { + } else if ((status == IOCB_TIMEDOUT) || + (status == IOCB_ABORTED)) { ret = TIMEOUT_ERROR; } else { ret = FAILED; @@ -6234,7 +6192,7 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct scsi_cmnd *cmnd, lpfc_sli_release_iocbq(phba, iocbqrsp); - if (ret != TIMEOUT_ERROR) + if (status != IOCB_TIMEDOUT) lpfc_release_scsi_buf(phba, lpfc_cmd); return ret; @@ -6243,7 +6201,7 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct scsi_cmnd *cmnd, /** * lpfc_chk_tgt_mapped - * @vport: The virtual port to check on - * @cmnd: Pointer to scsi_cmnd data structure. + * @rport: Pointer to fc_rport data structure. * * This routine delays until the scsi target (aka rport) for the * command exists (is present and logged in) or we declare it non-existent. @@ -6253,19 +6211,20 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct scsi_cmnd *cmnd, * 0x2002 - Success **/ static int -lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd) +lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct fc_rport *rport) { struct lpfc_rport_data *rdata; - struct lpfc_nodelist *pnode; + struct lpfc_nodelist *pnode = NULL; unsigned long later; - rdata = lpfc_rport_data_from_scsi_device(cmnd->device); + rdata = rport->dd_data; if (!rdata) { lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, "0797 Tgt Map rport failure: rdata x%px\n", rdata); return FAILED; } pnode = rdata->pnode; + /* * If target is not in a MAPPED state, delay until * target is rediscovered or devloss timeout expires. @@ -6277,7 +6236,7 @@ lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd) if (pnode->nlp_state == NLP_STE_MAPPED_NODE) return SUCCESS; schedule_timeout_uninterruptible(msecs_to_jiffies(500)); - rdata = lpfc_rport_data_from_scsi_device(cmnd->device); + rdata = rport->dd_data; if (!rdata) return FAILED; pnode = rdata->pnode; @@ -6348,6 +6307,7 @@ static int lpfc_device_reset_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; + struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_rport_data *rdata; struct lpfc_nodelist *pnode; @@ -6357,7 +6317,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) int status; u32 logit = LOG_FCP; - rdata = lpfc_rport_data_from_scsi_device(cmnd->device); + rdata = rport->dd_data; if (!rdata || !rdata->pnode) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "0798 Device Reset rdata failure: rdata x%px\n", @@ -6365,11 +6325,11 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) return FAILED; } pnode = rdata->pnode; - status = fc_block_scsi_eh(cmnd); + status = fc_block_rport(rport); if (status != 0 && status != SUCCESS) return status; - status = lpfc_chk_tgt_mapped(vport, cmnd); + status = lpfc_chk_tgt_mapped(vport, rport); if (status == FAILED) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "0721 Device Reset rport failure: rdata x%px\n", rdata); @@ -6385,7 +6345,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) fc_host_post_vendor_event(shost, fc_get_event_number(), sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID); - status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id, + status = lpfc_send_taskmgmt(vport, rport, tgt_id, lun_id, FCP_LUN_RESET); if (status != SUCCESS) logit = LOG_TRACE_EVENT; @@ -6422,6 +6382,7 @@ static int lpfc_target_reset_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; + struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_rport_data *rdata; struct lpfc_nodelist *pnode; @@ -6434,7 +6395,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) unsigned long flags; DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); - rdata = lpfc_rport_data_from_scsi_device(cmnd->device); + rdata = rport->dd_data; if (!rdata || !rdata->pnode) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "0799 Target Reset rdata failure: rdata x%px\n", @@ -6442,11 +6403,11 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) return FAILED; } pnode = rdata->pnode; - status = fc_block_scsi_eh(cmnd); + status = fc_block_rport(rport); if (status != 0 && status != SUCCESS) return status; - status = lpfc_chk_tgt_mapped(vport, cmnd); + status = lpfc_chk_tgt_mapped(vport, rport); if (status == FAILED) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "0722 Target Reset rport failure: rdata x%px\n", rdata); @@ -6470,7 +6431,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) fc_host_post_vendor_event(shost, fc_get_event_number(), sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID); - status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id, + status = lpfc_send_taskmgmt(vport, rport, tgt_id, lun_id, FCP_TARGET_RESET); if (status != SUCCESS) { logit = LOG_TRACE_EVENT; @@ -6529,95 +6490,6 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) } /** - * lpfc_bus_reset_handler - scsi_host_template eh_bus_reset_handler entry point - * @cmnd: Pointer to scsi_cmnd data structure. - * - * This routine does target reset to all targets on @cmnd->device->host. - * This emulates Parallel SCSI Bus Reset Semantics. - * - * Return code : - * 0x2003 - Error - * 0x2002 - Success - **/ -static int -lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) -{ - struct Scsi_Host *shost = cmnd->device->host; - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - struct lpfc_nodelist *ndlp = NULL; - struct lpfc_scsi_event_header scsi_event; - int match; - int ret = SUCCESS, status, i; - u32 logit = LOG_FCP; - - scsi_event.event_type = FC_REG_SCSI_EVENT; - scsi_event.subcategory = LPFC_EVENT_BUSRESET; - scsi_event.lun = 0; - memcpy(scsi_event.wwpn, &vport->fc_portname, sizeof(struct lpfc_name)); - memcpy(scsi_event.wwnn, &vport->fc_nodename, sizeof(struct lpfc_name)); - - fc_host_post_vendor_event(shost, fc_get_event_number(), - sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID); - - status = fc_block_scsi_eh(cmnd); - if (status != 0 && status != SUCCESS) - return status; - - /* - * Since the driver manages a single bus device, reset all - * targets known to the driver. Should any target reset - * fail, this routine returns failure to the midlayer. - */ - for (i = 0; i < LPFC_MAX_TARGET; i++) { - /* Search for mapped node by target ID */ - match = 0; - spin_lock_irq(shost->host_lock); - list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { - - if (vport->phba->cfg_fcp2_no_tgt_reset && - (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) - continue; - if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && - ndlp->nlp_sid == i && - ndlp->rport && - ndlp->nlp_type & NLP_FCP_TARGET) { - match = 1; - break; - } - } - spin_unlock_irq(shost->host_lock); - if (!match) - continue; - - status = lpfc_send_taskmgmt(vport, cmnd, - i, 0, FCP_TARGET_RESET); - - if (status != SUCCESS) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, - "0700 Bus Reset on target %d failed\n", - i); - ret = FAILED; - } - } - /* - * We have to clean up i/o as : they may be orphaned by the TMFs - * above; or if any of the TMFs failed, they may be in an - * indeterminate state. - * We will report success if all the i/o aborts successfully. - */ - - status = lpfc_reset_flush_io_context(vport, 0, 0, LPFC_CTX_HOST); - if (status != SUCCESS) - ret = FAILED; - if (ret == FAILED) - logit = LOG_TRACE_EVENT; - - lpfc_printf_vlog(vport, KERN_ERR, logit, - "0714 SCSI layer issued Bus Reset Data: x%x\n", ret); - return ret; -} - -/** * lpfc_host_reset_handler - scsi_host_template eh_host_reset_handler entry pt * @cmnd: Pointer to scsi_cmnd data structure. * @@ -7183,12 +7055,6 @@ lpfc_no_command(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) } static int -lpfc_no_handler(struct scsi_cmnd *cmnd) -{ - return FAILED; -} - -static int lpfc_no_slave(struct scsi_device *sdev) { return -ENODEV; @@ -7200,11 +7066,6 @@ struct scsi_host_template lpfc_template_nvme = { .proc_name = LPFC_DRIVER_NAME, .info = lpfc_info, .queuecommand = lpfc_no_command, - .eh_abort_handler = lpfc_no_handler, - .eh_device_reset_handler = lpfc_no_handler, - .eh_target_reset_handler = lpfc_no_handler, - .eh_bus_reset_handler = lpfc_no_handler, - .eh_host_reset_handler = lpfc_no_handler, .slave_alloc = lpfc_no_slave, .slave_configure = lpfc_no_slave, .scan_finished = lpfc_scan_finished, @@ -7228,7 +7089,6 @@ struct scsi_host_template lpfc_template = { .eh_abort_handler = lpfc_abort_handler, .eh_device_reset_handler = lpfc_device_reset_handler, .eh_target_reset_handler = lpfc_target_reset_handler, - .eh_bus_reset_handler = lpfc_bus_reset_handler, .eh_host_reset_handler = lpfc_host_reset_handler, .slave_alloc = lpfc_slave_alloc, .slave_configure = lpfc_slave_configure, |