aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@suse.de>2011-03-23 10:58:28 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-03-23 13:53:09 -0400
commit3dea642afd9187728d119fce5c82a7ed9faa9b6a (patch)
treee19500e36674b99c91db2afed6168b2eb08a4233 /drivers
parentfee787129d4d6a5e967a69ea3dea3e38ba556b3d (diff)
[SCSI] Revert "[SCSI] Retrieve the Caching mode page"
This reverts commit 24d720b726c1a85f1962831ac30ad4d2ef8276b1. Previously we thought there was little possibility that devices would crash with this, but some have been found. Reported-by: Alan Stern <stern@rowland.harvard.edu> Cc: Luben Tuikov <ltuikov@yahoo.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/sd.c63
1 files changed, 16 insertions, 47 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 7ff61d76b4c5..b61ebec6bca7 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2027,14 +2027,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
2027 int old_rcd = sdkp->RCD; 2027 int old_rcd = sdkp->RCD;
2028 int old_dpofua = sdkp->DPOFUA; 2028 int old_dpofua = sdkp->DPOFUA;
2029 2029
2030 if (sdp->skip_ms_page_8) { 2030 if (sdp->skip_ms_page_8)
2031 if (sdp->type == TYPE_RBC) 2031 goto defaults;
2032 goto defaults; 2032
2033 else { 2033 if (sdp->type == TYPE_RBC) {
2034 modepage = 0x3F;
2035 dbd = 0;
2036 }
2037 } else if (sdp->type == TYPE_RBC) {
2038 modepage = 6; 2034 modepage = 6;
2039 dbd = 8; 2035 dbd = 8;
2040 } else { 2036 } else {
@@ -2062,11 +2058,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
2062 */ 2058 */
2063 if (len < 3) 2059 if (len < 3)
2064 goto bad_sense; 2060 goto bad_sense;
2065 else if (len > SD_BUF_SIZE) { 2061 if (len > 20)
2066 sd_printk(KERN_NOTICE, sdkp, "Truncating mode parameter " 2062 len = 20;
2067 "data from %d to %d bytes\n", len, SD_BUF_SIZE); 2063
2068 len = SD_BUF_SIZE; 2064 /* Take headers and block descriptors into account */
2069 } 2065 len += data.header_length + data.block_descriptor_length;
2066 if (len > SD_BUF_SIZE)
2067 goto bad_sense;
2070 2068
2071 /* Get the data */ 2069 /* Get the data */
2072 res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); 2070 res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
@@ -2074,45 +2072,16 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
2074 if (scsi_status_is_good(res)) { 2072 if (scsi_status_is_good(res)) {
2075 int offset = data.header_length + data.block_descriptor_length; 2073 int offset = data.header_length + data.block_descriptor_length;
2076 2074
2077 while (offset < len) { 2075 if (offset >= SD_BUF_SIZE - 2) {
2078 u8 page_code = buffer[offset] & 0x3F; 2076 sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n");
2079 u8 spf = buffer[offset] & 0x40; 2077 goto defaults;
2080
2081 if (page_code == 8 || page_code == 6) {
2082 /* We're interested only in the first 3 bytes.
2083 */
2084 if (len - offset <= 2) {
2085 sd_printk(KERN_ERR, sdkp, "Incomplete "
2086 "mode parameter data\n");
2087 goto defaults;
2088 } else {
2089 modepage = page_code;
2090 goto Page_found;
2091 }
2092 } else {
2093 /* Go to the next page */
2094 if (spf && len - offset > 3)
2095 offset += 4 + (buffer[offset+2] << 8) +
2096 buffer[offset+3];
2097 else if (!spf && len - offset > 1)
2098 offset += 2 + buffer[offset+1];
2099 else {
2100 sd_printk(KERN_ERR, sdkp, "Incomplete "
2101 "mode parameter data\n");
2102 goto defaults;
2103 }
2104 }
2105 } 2078 }
2106 2079
2107 if (modepage == 0x3F) { 2080 if ((buffer[offset] & 0x3f) != modepage) {
2108 sd_printk(KERN_ERR, sdkp, "No Caching mode page "
2109 "present\n");
2110 goto defaults;
2111 } else if ((buffer[offset] & 0x3f) != modepage) {
2112 sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); 2081 sd_printk(KERN_ERR, sdkp, "Got wrong page\n");
2113 goto defaults; 2082 goto defaults;
2114 } 2083 }
2115 Page_found: 2084
2116 if (modepage == 8) { 2085 if (modepage == 8) {
2117 sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); 2086 sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
2118 sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0); 2087 sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);