summaryrefslogtreecommitdiff
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index f4a49623ee3b..530918cbfce2 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -143,7 +143,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
struct scsi_mode_data data;
struct scsi_sense_hdr sshdr;
static const char temp[] = "temporary ";
- int len;
+ int len, ret;
if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
/* no cache control on RBC devices; theoretically they
@@ -190,9 +190,10 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
*/
data.device_specific = 0;
- if (scsi_mode_select(sdp, 1, sp, buffer_data, len, SD_TIMEOUT,
- sdkp->max_retries, &data, &sshdr)) {
- if (scsi_sense_valid(&sshdr))
+ ret = scsi_mode_select(sdp, 1, sp, buffer_data, len, SD_TIMEOUT,
+ sdkp->max_retries, &data, &sshdr);
+ if (ret) {
+ if (ret > 0 && scsi_sense_valid(&sshdr))
sd_print_sense_hdr(sdkp, &sshdr);
return -EINVAL;
}
@@ -2258,19 +2259,21 @@ sd_spinup_disk(struct scsi_disk *sdkp)
sdkp->max_retries,
&exec_args);
- /*
- * If the drive has indicated to us that it
- * doesn't have any media in it, don't bother
- * with any more polling.
- */
- if (media_not_present(sdkp, &sshdr)) {
- if (media_was_present)
- sd_printk(KERN_NOTICE, sdkp, "Media removed, stopped polling\n");
- return;
- }
+ if (the_result > 0) {
+ /*
+ * If the drive has indicated to us that it
+ * doesn't have any media in it, don't bother
+ * with any more polling.
+ */
+ if (media_not_present(sdkp, &sshdr)) {
+ if (media_was_present)
+ sd_printk(KERN_NOTICE, sdkp,
+ "Media removed, stopped polling\n");
+ return;
+ }
- if (the_result)
sense_valid = scsi_sense_valid(&sshdr);
+ }
retries++;
} while (retries < 3 &&
(!scsi_status_is_good(the_result) ||
@@ -2302,6 +2305,10 @@ sd_spinup_disk(struct scsi_disk *sdkp)
break; /* unavailable */
if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
break; /* sanitize in progress */
+ if (sshdr.asc == 4 && sshdr.ascq == 0x24)
+ break; /* depopulation in progress */
+ if (sshdr.asc == 4 && sshdr.ascq == 0x25)
+ break; /* depopulation restoration in progress */
/*
* Issue command to spin up drive when not ready
*/
@@ -2466,11 +2473,10 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
the_result = scsi_execute_cmd(sdp, cmd, REQ_OP_DRV_IN,
buffer, RC16_LEN, SD_TIMEOUT,
sdkp->max_retries, &exec_args);
-
- if (media_not_present(sdkp, &sshdr))
- return -ENODEV;
-
if (the_result > 0) {
+ if (media_not_present(sdkp, &sshdr))
+ return -ENODEV;
+
sense_valid = scsi_sense_valid(&sshdr);
if (sense_valid &&
sshdr.sense_key == ILLEGAL_REQUEST &&
@@ -2967,7 +2973,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
}
bad_sense:
- if (scsi_sense_valid(&sshdr) &&
+ if (res == -EIO && scsi_sense_valid(&sshdr) &&
sshdr.sense_key == ILLEGAL_REQUEST &&
sshdr.asc == 0x24 && sshdr.ascq == 0x0)
/* Invalid field in CDB */
@@ -3015,7 +3021,7 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
sd_first_printk(KERN_WARNING, sdkp,
"getting Control mode page failed, assume no ATO\n");
- if (scsi_sense_valid(&sshdr))
+ if (res == -EIO && scsi_sense_valid(&sshdr))
sd_print_sense_hdr(sdkp, &sshdr);
return;