ChangeLog: - add comments to scsi_end_request() noting what its bool return value means - change some variable names in scsi_io_completion() - reword some inline comments; move some comments that seemed to be separated from the code they referred to Signed-off-by: Douglas Gilbert <dgilbert@xxxxxxxxxxxx> --- drivers/scsi/scsi_lib.c | 54 ++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 142400476d84..92eea43cfa6f 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -650,6 +650,7 @@ static void scsi_release_bidi_buffers(struct scsi_cmnd *cmd) cmd->request->next_rq->special = NULL; } +/* Returns false when no more bytes to process, true if there are more */ static bool scsi_end_request(struct request *req, blk_status_t error, unsigned int bytes, unsigned int bidi_bytes) { @@ -772,10 +773,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) int result = cmd->result; struct request_queue *q = cmd->device->request_queue; struct request *req = cmd->request; - blk_status_t error = BLK_STS_OK; + blk_status_t blk_stat = BLK_STS_OK; /* u8: BLK_STS_OK is only 0 */ struct scsi_sense_hdr sshdr; bool sense_valid = false; - int sense_deferred = 0, level = 0; + bool sense_current = true; /* false implies "deferred sense" */ + int level = 0; enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY, ACTION_DELAYED_RETRY} action; unsigned long wait_for = (cmd->allowed + 1) * req->timeout; @@ -783,7 +785,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) if (result) { sense_valid = scsi_command_normalize_sense(cmd, &sshdr); if (sense_valid) - sense_deferred = scsi_sense_is_deferred(&sshdr); + sense_current = !scsi_sense_is_deferred(&sshdr); } if (blk_rq_is_passthrough(req)) { @@ -796,8 +798,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) min(8 + cmd->sense_buffer[7], SCSI_SENSE_BUFFERSIZE); } - if (!sense_deferred) - error = __scsi_error_from_host_byte(cmd, result); + if (sense_current) + blk_stat = __scsi_error_from_host_byte(cmd, + result); } /* * __scsi_error_from_host_byte may have reset the host_byte @@ -816,13 +819,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) BUG(); return; } - } else if (blk_rq_bytes(req) == 0 && result && !sense_deferred) { + } else if (blk_rq_bytes(req) == 0 && result && sense_current) { /* * Flush commands do not transfers any data, and thus cannot use * good_bytes != blk_rq_bytes(req) as the signal for an error. - * This sets the error explicitly for the problem case. + * This sets blk_stat explicitly for the problem case. */ - error = __scsi_error_from_host_byte(cmd, result); + blk_stat = __scsi_error_from_host_byte(cmd, result); } /* no bidi support for !blk_rq_is_passthrough yet */ @@ -852,8 +855,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) else if (!(req->rq_flags & RQF_QUIET)) scsi_print_sense(cmd); result = 0; - /* for passthrough error may be set */ - error = BLK_STS_OK; + /* for passthrough, blk_stat may be set */ + blk_stat = BLK_STS_OK; } /* * Another corner case: the SCSI status byte is non-zero but 'good'. @@ -864,23 +867,24 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) */ if (status_byte(result) && scsi_status_is_good(result)) { result = 0; - error = BLK_STS_OK; + blk_stat = BLK_STS_OK; } /* - * special case: failed zero length commands always need to - * drop down into the retry code. Otherwise, if we finished - * all bytes in the request we are done now. + * Next deal with any sectors which we were able to correctly + * handle. Failed, zero length commands always need to drop down + * to retry code. Fast path should return in this block. */ - if (!(blk_rq_bytes(req) == 0 && error) && - !scsi_end_request(req, error, good_bytes, 0)) - return; + if (blk_rq_bytes(req) > 0 || blk_stat == BLK_STS_OK) { + if (!scsi_end_request(req, blk_stat, good_bytes, 0)) + return; /* no bytes remaining */ + } /* * Kill remainder if no retrys. */ - if (error && scsi_noretry_cmd(cmd)) { - if (scsi_end_request(req, error, blk_rq_bytes(req), 0)) + if (blk_stat && scsi_noretry_cmd(cmd)) { + if (scsi_end_request(req, blk_stat, blk_rq_bytes(req), 0)) BUG(); return; } @@ -892,7 +896,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) if (result == 0) goto requeue; - error = __scsi_error_from_host_byte(cmd, result); + blk_stat = __scsi_error_from_host_byte(cmd, result); if (host_byte(result) == DID_RESET) { /* Third party bus reset or reset for error recovery @@ -900,7 +904,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) * happens. */ action = ACTION_RETRY; - } else if (sense_valid && !sense_deferred) { + } else if (sense_valid && sense_current) { switch (sshdr.sense_key) { case UNIT_ATTENTION: if (cmd->device->removable) { @@ -936,18 +940,18 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) action = ACTION_REPREP; } else if (sshdr.asc == 0x10) /* DIX */ { action = ACTION_FAIL; - error = BLK_STS_PROTECTION; + blk_stat = BLK_STS_PROTECTION; /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { action = ACTION_FAIL; - error = BLK_STS_TARGET; + blk_stat = BLK_STS_TARGET; } else action = ACTION_FAIL; break; case ABORTED_COMMAND: action = ACTION_FAIL; if (sshdr.asc == 0x10) /* DIF */ - error = BLK_STS_PROTECTION; + blk_stat = BLK_STS_PROTECTION; break; case NOT_READY: /* If the device is in the process of becoming @@ -1010,7 +1014,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) scsi_print_command(cmd); } } - if (!scsi_end_request(req, error, blk_rq_err_bytes(req), 0)) + if (!scsi_end_request(req, blk_stat, blk_rq_err_bytes(req), 0)) return; /*FALLTHRU*/ case ACTION_REPREP: -- 2.14.1