Commit abd184cb authored by Linus Torvalds's avatar Linus Torvalds

sd.c: be more cautious in asking for mode page 8 data,

sanity-checking the information more carefully. 

The old code basically just used a random-number approach
to determine how much to read.
parent dd7937d3
...@@ -1108,14 +1108,26 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ...@@ -1108,14 +1108,26 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
/* cautiously ask */ /* cautiously ask */
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data); res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
if (scsi_status_is_good(res)) { if (!scsi_status_is_good(res))
/* that went OK, now ask for the proper length */ goto bad_sense;
len = data.length;
if (len > 128) /* that went OK, now ask for the proper length */
len = 128; len = data.length;
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer,
len, &data); /*
} * We're only interested in the first three bytes, actually.
* But the data cache page is defined for the first 20.
*/
if (len < 3)
goto bad_sense;
if (len > 20)
len = 20;
/* Take headers and block descriptors into account */
len += data.header_length + data.block_descriptor_length;
/* Get the data */
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, len, &data);
if (scsi_status_is_good(res)) { if (scsi_status_is_good(res)) {
const char *types[] = { const char *types[] = {
...@@ -1133,23 +1145,26 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ...@@ -1133,23 +1145,26 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n", printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n",
diskname, types[ct]); diskname, types[ct]);
return;
}
bad_sense:
if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70
&& (SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST
/* ASC 0x24 ASCQ 0x00: Invalid field in CDB */
&& SRpnt->sr_sense_buffer[12] == 0x24
&& SRpnt->sr_sense_buffer[13] == 0x00) {
printk(KERN_NOTICE "%s: cache data unavailable\n",
diskname);
} else { } else {
if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 printk(KERN_ERR "%s: asking for cache data failed\n",
&& (SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST
/* ASC 0x24 ASCQ 0x00: Invalid field in CDB */
&& SRpnt->sr_sense_buffer[12] == 0x24
&& SRpnt->sr_sense_buffer[13] == 0x00) {
printk(KERN_NOTICE "%s: cache data unavailable\n",
diskname);
} else {
printk(KERN_ERR "%s: asking for cache data failed\n",
diskname);
}
printk(KERN_ERR "%s: assuming drive cache: write through\n",
diskname); diskname);
sdkp->WCE = 0;
sdkp->RCD = 0;
} }
printk(KERN_ERR "%s: assuming drive cache: write through\n",
diskname);
sdkp->WCE = 0;
sdkp->RCD = 0;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment