aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 97ae98dc95d0..c3e68e0d8f74 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -297,8 +297,10 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
297 uint32_t fcpi_parm = lpfc_cmd->cur_iocbq.iocb.un.fcpi.fcpi_parm; 297 uint32_t fcpi_parm = lpfc_cmd->cur_iocbq.iocb.un.fcpi.fcpi_parm;
298 uint32_t resp_info = fcprsp->rspStatus2; 298 uint32_t resp_info = fcprsp->rspStatus2;
299 uint32_t scsi_status = fcprsp->rspStatus3; 299 uint32_t scsi_status = fcprsp->rspStatus3;
300 uint32_t *lp;
300 uint32_t host_status = DID_OK; 301 uint32_t host_status = DID_OK;
301 uint32_t rsplen = 0; 302 uint32_t rsplen = 0;
303 uint32_t logit = LOG_FCP | LOG_FCP_ERROR;
302 304
303 /* 305 /*
304 * If this is a task management command, there is no 306 * If this is a task management command, there is no
@@ -310,10 +312,25 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
310 goto out; 312 goto out;
311 } 313 }
312 314
313 lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, 315 if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
314 "%d:0730 FCP command failed: RSP " 316 uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen);
315 "Data: x%x x%x x%x x%x x%x x%x\n", 317 if (snslen > SCSI_SENSE_BUFFERSIZE)
316 phba->brd_no, resp_info, scsi_status, 318 snslen = SCSI_SENSE_BUFFERSIZE;
319
320 if (resp_info & RSP_LEN_VALID)
321 rsplen = be32_to_cpu(fcprsp->rspRspLen);
322 memcpy(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen);
323 }
324 lp = (uint32_t *)cmnd->sense_buffer;
325
326 if (!scsi_status && (resp_info & RESID_UNDER))
327 logit = LOG_FCP;
328
329 lpfc_printf_log(phba, KERN_WARNING, logit,
330 "%d:0730 FCP command x%x failed: x%x SNS x%x x%x "
331 "Data: x%x x%x x%x x%x x%x\n",
332 phba->brd_no, cmnd->cmnd[0], scsi_status,
333 be32_to_cpu(*lp), be32_to_cpu(*(lp + 3)), resp_info,
317 be32_to_cpu(fcprsp->rspResId), 334 be32_to_cpu(fcprsp->rspResId),
318 be32_to_cpu(fcprsp->rspSnsLen), 335 be32_to_cpu(fcprsp->rspSnsLen),
319 be32_to_cpu(fcprsp->rspRspLen), 336 be32_to_cpu(fcprsp->rspRspLen),
@@ -328,14 +345,6 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
328 } 345 }
329 } 346 }
330 347
331 if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {
332 uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen);
333 if (snslen > SCSI_SENSE_BUFFERSIZE)
334 snslen = SCSI_SENSE_BUFFERSIZE;
335
336 memcpy(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen);
337 }
338
339 cmnd->resid = 0; 348 cmnd->resid = 0;
340 if (resp_info & RESID_UNDER) { 349 if (resp_info & RESID_UNDER) {
341 cmnd->resid = be32_to_cpu(fcprsp->rspResId); 350 cmnd->resid = be32_to_cpu(fcprsp->rspResId);
@@ -378,7 +387,7 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd)
378 */ 387 */
379 } else if ((scsi_status == SAM_STAT_GOOD) && fcpi_parm && 388 } else if ((scsi_status == SAM_STAT_GOOD) && fcpi_parm &&
380 (cmnd->sc_data_direction == DMA_FROM_DEVICE)) { 389 (cmnd->sc_data_direction == DMA_FROM_DEVICE)) {
381 lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, 390 lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR,
382 "%d:0734 FCP Read Check Error Data: " 391 "%d:0734 FCP Read Check Error Data: "
383 "x%x x%x x%x x%x\n", phba->brd_no, 392 "x%x x%x x%x x%x\n", phba->brd_no,
384 be32_to_cpu(fcpcmd->fcpDl), 393 be32_to_cpu(fcpcmd->fcpDl),
@@ -670,6 +679,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba,
670 struct lpfc_iocbq *iocbqrsp; 679 struct lpfc_iocbq *iocbqrsp;
671 int ret; 680 int ret;
672 681
682 if (!rdata->pnode)
683 return FAILED;
684
673 lpfc_cmd->rdata = rdata; 685 lpfc_cmd->rdata = rdata;
674 ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, 686 ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun,
675 FCP_TARGET_RESET); 687 FCP_TARGET_RESET);
@@ -976,20 +988,34 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
976 988
977 lpfc_block_error_handler(cmnd); 989 lpfc_block_error_handler(cmnd);
978 spin_lock_irq(shost->host_lock); 990 spin_lock_irq(shost->host_lock);
991 loopcnt = 0;
979 /* 992 /*
980 * If target is not in a MAPPED state, delay the reset until 993 * If target is not in a MAPPED state, delay the reset until
981 * target is rediscovered or devloss timeout expires. 994 * target is rediscovered or devloss timeout expires.
982 */ 995 */
983 while ( 1 ) { 996 while ( 1 ) {
984 if (!pnode) 997 if (!pnode)
985 break; 998 return FAILED;
986 999
987 if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { 1000 if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
988 spin_unlock_irq(phba->host->host_lock); 1001 spin_unlock_irq(phba->host->host_lock);
989 schedule_timeout_uninterruptible(msecs_to_jiffies(500)); 1002 schedule_timeout_uninterruptible(msecs_to_jiffies(500));
990 spin_lock_irq(phba->host->host_lock); 1003 spin_lock_irq(phba->host->host_lock);
1004 loopcnt++;
1005 rdata = cmnd->device->hostdata;
1006 if (!rdata ||
1007 (loopcnt > ((phba->cfg_devloss_tmo * 2) + 1))) {
1008 lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
1009 "%d:0721 LUN Reset rport failure:"
1010 " cnt x%x rdata x%p\n",
1011 phba->brd_no, loopcnt, rdata);
1012 goto out;
1013 }
1014 pnode = rdata->pnode;
1015 if (!pnode)
1016 return FAILED;
991 } 1017 }
992 if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE)) 1018 if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
993 break; 1019 break;
994 } 1020 }
995 1021