mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
scsi: core: Stop using DRIVER_ERROR
Return the actual error code in __scsi_execute() (which, according to the documentation, should have happened anyway). And audit all callers to cope with negative return values from __scsi_execute() and friends. [mkp: resolve conflict and return bool] Link: https://lore.kernel.org/r/20210427083046.31620-7-hare@suse.de Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
7e26e3ea02
commit
ced202f7bd
@ -409,6 +409,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
|
||||
cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
|
||||
sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
|
||||
|
||||
if (cmd_result < 0) {
|
||||
rc = cmd_result;
|
||||
goto error;
|
||||
}
|
||||
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
|
||||
u8 *desc = sensebuf + 8;
|
||||
cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
|
||||
@ -490,6 +494,10 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
|
||||
cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
|
||||
sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
|
||||
|
||||
if (cmd_result < 0) {
|
||||
rc = cmd_result;
|
||||
goto error;
|
||||
}
|
||||
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
|
||||
u8 *desc = sensebuf + 8;
|
||||
cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
|
||||
|
@ -198,7 +198,8 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
|
||||
result = scsi_execute_req(ch->device, cmd, direction, buffer,
|
||||
buflength, &sshdr, timeout * HZ,
|
||||
MAX_RETRIES, NULL);
|
||||
|
||||
if (result < 0)
|
||||
return result;
|
||||
if (driver_byte(result) == DRIVER_SENSE) {
|
||||
if (debug)
|
||||
scsi_print_sense_hdr(ch->device, ch->name, &sshdr);
|
||||
|
@ -369,7 +369,7 @@ retry:
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (driver_byte(result) == DRIVER_SENSE) {
|
||||
if (result > 0 && driver_byte(result) == DRIVER_SENSE) {
|
||||
result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
|
||||
if (result & SAM_STAT_CHECK_CONDITION) {
|
||||
switch (sshdr.sense_key) {
|
||||
|
@ -508,6 +508,8 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
|
||||
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
|
||||
&sshdr, 30 * HZ, 3, NULL);
|
||||
|
||||
if (result < 0)
|
||||
return result;
|
||||
if (result && scsi_sense_valid(&sshdr) &&
|
||||
sshdr.sense_key == ILLEGAL_REQUEST &&
|
||||
(sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00)
|
||||
|
@ -101,6 +101,8 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
|
||||
SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
|
||||
"Ioctl returned 0x%x\n", result));
|
||||
|
||||
if (result < 0)
|
||||
goto out;
|
||||
if (driver_byte(result) == DRIVER_SENSE &&
|
||||
scsi_sense_valid(&sshdr)) {
|
||||
switch (sshdr.sense_key) {
|
||||
@ -133,7 +135,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
|
||||
"IOCTL Releasing command\n"));
|
||||
return result;
|
||||
|
@ -211,20 +211,23 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
|
||||
{
|
||||
struct request *req;
|
||||
struct scsi_request *rq;
|
||||
int ret = DRIVER_ERROR << 24;
|
||||
int ret;
|
||||
|
||||
req = blk_get_request(sdev->request_queue,
|
||||
data_direction == DMA_TO_DEVICE ?
|
||||
REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
|
||||
rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0);
|
||||
if (IS_ERR(req))
|
||||
return ret;
|
||||
return PTR_ERR(req);
|
||||
|
||||
rq = scsi_req(req);
|
||||
|
||||
if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
|
||||
buffer, bufflen, GFP_NOIO))
|
||||
goto out;
|
||||
|
||||
if (bufflen) {
|
||||
ret = blk_rq_map_kern(sdev->request_queue, req,
|
||||
buffer, bufflen, GFP_NOIO);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
rq->cmd_len = COMMAND_SIZE(cmd[0]);
|
||||
memcpy(rq->cmd, cmd, rq->cmd_len);
|
||||
rq->retries = retries;
|
||||
|
@ -616,7 +616,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
|
||||
"scsi scan: INQUIRY %s with code 0x%x\n",
|
||||
result ? "failed" : "successful", result));
|
||||
|
||||
if (result) {
|
||||
if (result > 0) {
|
||||
/*
|
||||
* not-ready to ready transition [asc/ascq=0x28/0x0]
|
||||
* or power-on, reset [asc/ascq=0x29/0x0], continue.
|
||||
@ -631,7 +631,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
|
||||
(sshdr.ascq == 0))
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
} else if (result == 0) {
|
||||
/*
|
||||
* if nothing was transferred, we try
|
||||
* again. It's a workaround for some USB
|
||||
|
@ -127,7 +127,7 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd,
|
||||
REQ_FAILFAST_TRANSPORT |
|
||||
REQ_FAILFAST_DRIVER,
|
||||
RQF_PM, NULL);
|
||||
if (driver_byte(result) != DRIVER_SENSE ||
|
||||
if (result < 0 || driver_byte(result) != DRIVER_SENSE ||
|
||||
sshdr->sense_key != UNIT_ATTENTION)
|
||||
break;
|
||||
}
|
||||
|
@ -1658,7 +1658,7 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
|
||||
&sshdr);
|
||||
|
||||
/* failed to execute TUR, assume media not present */
|
||||
if (host_byte(retval)) {
|
||||
if (retval < 0 || host_byte(retval)) {
|
||||
set_media_not_present(sdkp);
|
||||
goto out;
|
||||
}
|
||||
@ -1719,6 +1719,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
|
||||
if (res) {
|
||||
sd_print_result(sdkp, "Synchronize Cache(10) failed", res);
|
||||
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
if (driver_byte(res) == DRIVER_SENSE)
|
||||
sd_print_sense_hdr(sdkp, sshdr);
|
||||
|
||||
@ -1825,7 +1828,7 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
|
||||
result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, &data, sizeof(data),
|
||||
&sshdr, SD_TIMEOUT, sdkp->max_retries, NULL);
|
||||
|
||||
if (driver_byte(result) == DRIVER_SENSE &&
|
||||
if (result > 0 && driver_byte(result) == DRIVER_SENSE &&
|
||||
scsi_sense_valid(&sshdr)) {
|
||||
sdev_printk(KERN_INFO, sdev, "PR command failed: %d\n", result);
|
||||
scsi_print_sense_hdr(sdev, NULL, &sshdr);
|
||||
@ -2177,7 +2180,7 @@ sd_spinup_disk(struct scsi_disk *sdkp)
|
||||
((driver_byte(the_result) == DRIVER_SENSE) &&
|
||||
sense_valid && sshdr.sense_key == UNIT_ATTENTION)));
|
||||
|
||||
if (driver_byte(the_result) != DRIVER_SENSE) {
|
||||
if (the_result < 0 || driver_byte(the_result) != DRIVER_SENSE) {
|
||||
/* no sense, TUR either succeeded or failed
|
||||
* with a status error */
|
||||
if(!spintime && !scsi_status_is_good(the_result)) {
|
||||
@ -2362,7 +2365,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
||||
if (media_not_present(sdkp, &sshdr))
|
||||
return -ENODEV;
|
||||
|
||||
if (the_result) {
|
||||
if (the_result > 0) {
|
||||
sense_valid = scsi_sense_valid(&sshdr);
|
||||
if (sense_valid &&
|
||||
sshdr.sense_key == ILLEGAL_REQUEST &&
|
||||
@ -2447,7 +2450,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
||||
if (media_not_present(sdkp, &sshdr))
|
||||
return -ENODEV;
|
||||
|
||||
if (the_result) {
|
||||
if (the_result > 0) {
|
||||
sense_valid = scsi_sense_valid(&sshdr);
|
||||
if (sense_valid &&
|
||||
sshdr.sense_key == UNIT_ATTENTION &&
|
||||
@ -3591,7 +3594,7 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
|
||||
SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL);
|
||||
if (res) {
|
||||
sd_print_result(sdkp, "Start/Stop Unit failed", res);
|
||||
if (driver_byte(res) == DRIVER_SENSE)
|
||||
if (res > 0 && driver_byte(res) == DRIVER_SENSE)
|
||||
sd_print_sense_hdr(sdkp, &sshdr);
|
||||
if (scsi_sense_valid(&sshdr) &&
|
||||
/* 0x3a is medium not present */
|
||||
|
@ -116,7 +116,7 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
|
||||
sd_printk(KERN_ERR, sdkp,
|
||||
"REPORT ZONES start lba %llu failed\n", lba);
|
||||
sd_print_result(sdkp, "REPORT ZONES", result);
|
||||
if (driver_byte(result) == DRIVER_SENSE &&
|
||||
if (result > 0 && driver_byte(result) == DRIVER_SENSE &&
|
||||
scsi_sense_valid(&sshdr))
|
||||
sd_print_sense_hdr(sdkp, &sshdr);
|
||||
return -EIO;
|
||||
|
@ -201,6 +201,10 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
||||
cgc->timeout, IOCTL_RETRIES, 0, 0, NULL);
|
||||
|
||||
/* Minimal error checking. Ignore cases we know about, and report the rest. */
|
||||
if (result < 0) {
|
||||
err = result;
|
||||
goto out;
|
||||
}
|
||||
if (driver_byte(result) != 0) {
|
||||
switch (sshdr->sense_key) {
|
||||
case UNIT_ATTENTION:
|
||||
|
@ -8604,7 +8604,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
|
||||
sdev_printk(KERN_WARNING, sdp,
|
||||
"START_STOP failed for power mode: %d, result %x\n",
|
||||
pwr_mode, ret);
|
||||
if (driver_byte(ret) == DRIVER_SENSE)
|
||||
if (ret > 0 && driver_byte(ret) == DRIVER_SENSE)
|
||||
scsi_print_sense_hdr(sdp, NULL, &sshdr);
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ static void virtscsi_rescan_hotunplug(struct virtio_scsi *vscsi)
|
||||
if (result == 0 && inq_result[0] >> 5) {
|
||||
/* PQ indicates the LUN is not attached */
|
||||
scsi_remove_device(sdev);
|
||||
} else if (host_byte(result) == DID_BAD_TARGET) {
|
||||
} else if (result > 0 && host_byte(result) == DID_BAD_TARGET) {
|
||||
/*
|
||||
* If all LUNs of a virtio-scsi device are unplugged
|
||||
* it will respond with BAD TARGET on any INQUIRY
|
||||
|
@ -259,10 +259,13 @@ enum scsi_disposition {
|
||||
* This returns true for known good conditions that may be treated as
|
||||
* command completed normally
|
||||
*/
|
||||
static inline int scsi_status_is_good(int status)
|
||||
static inline bool scsi_status_is_good(int status)
|
||||
{
|
||||
if (status < 0)
|
||||
return false;
|
||||
|
||||
if (host_byte(status) == DID_NO_CONNECT)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
/*
|
||||
* FIXME: bit0 is listed as reserved in SCSI-2, but is
|
||||
|
Loading…
Reference in New Issue
Block a user