diff options
Diffstat (limited to 'drivers/scsi/scsi_error.c')
| -rw-r--r-- | drivers/scsi/scsi_error.c | 22 | 
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 771c16bfdbac..cbe38e5e7955 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -189,6 +189,7 @@ scsi_abort_command(struct scsi_cmnd *scmd)  		/*  		 * Retry after abort failed, escalate to next level.  		 */ +		scmd->eh_eflags &= ~SCSI_EH_ABORT_SCHEDULED;  		SCSI_LOG_ERROR_RECOVERY(3,  			scmd_printk(KERN_INFO, scmd,  				    "scmd %p previous abort failed\n", scmd)); @@ -920,10 +921,12 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,  	ses->prot_op = scmd->prot_op;  	scmd->prot_op = SCSI_PROT_NORMAL; +	scmd->eh_eflags = 0;  	scmd->cmnd = ses->eh_cmnd;  	memset(scmd->cmnd, 0, BLK_MAX_CDB);  	memset(&scmd->sdb, 0, sizeof(scmd->sdb));  	scmd->request->next_rq = NULL; +	scmd->result = 0;  	if (sense_bytes) {  		scmd->sdb.length = min_t(unsigned, SCSI_SENSE_BUFFERSIZE, @@ -1026,6 +1029,7 @@ retry:  		rtn = NEEDS_RETRY;  	} else {  		timeleft = wait_for_completion_timeout(&done, timeout); +		rtn = SUCCESS;  	}  	shost->eh_action = NULL; @@ -1157,6 +1161,15 @@ int scsi_eh_get_sense(struct list_head *work_q,  					     __func__));  			break;  		} +		if (status_byte(scmd->result) != CHECK_CONDITION) +			/* +			 * don't request sense if there's no check condition +			 * status because the error we're processing isn't one +			 * that has a sense code (and some devices get +			 * confused by sense requests out of the blue) +			 */ +			continue; +  		SCSI_LOG_ERROR_RECOVERY(2, scmd_printk(KERN_INFO, scmd,  						  "%s: requesting sense\n",  						  current->comm)); @@ -1939,6 +1952,8 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)  	 */  	req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL); +	blk_rq_set_block_pc(req); +  	req->cmd[0] = ALLOW_MEDIUM_REMOVAL;  	req->cmd[1] = 0;  	req->cmd[2] = 0; @@ -1948,7 +1963,6 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)  	req->cmd_len = COMMAND_SIZE(req->cmd[0]); -	req->cmd_type = REQ_TYPE_BLOCK_PC;  	req->cmd_flags |= REQ_QUIET;  	req->timeout = 10 * HZ;  	req->retries = 5; @@ -2294,6 +2308,12 @@ scsi_reset_provider(struct scsi_device *dev, int flag)  	}  	scmd = scsi_get_command(dev, GFP_KERNEL); +	if (!scmd) { +		rtn = FAILED; +		put_device(&dev->sdev_gendev); +		goto out_put_autopm_host; +	} +  	blk_rq_init(NULL, &req);  	scmd->request = &req;  |