aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@parcelfarce.linux.theplanet.co.uk>2005-05-15 20:59:55 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-05-26 09:41:15 -0400
commit631e8a1398ce4cfef8b30678d51daf0c64313a09 (patch)
tree14d3b601b4a7160568c58d53a94a0a4711094588
parent53222b906903fd861dc24ebccfa07ee125941313 (diff)
[SCSI] TYPE_RBC cache fixes (sbp2.c affected)
a) TYPE_SDAD renamed to TYPE_RBC and taken to scsi.h b) in sbp2.c remapping of TYPE_RPB to TYPE_DISK turned off c) relevant places in midlayer and sd.c taught to accept TYPE_RBC d) sd.c::sd_read_cache_type() looks into page 6 when dealing with TYPE_RBC - these guys have writeback cache flag there and are not guaranteed to have page 8 at all. e) sd_read_cache_type() got an extra sanity check - it checks that it got the page it asked for before using its contents. And screams if mismatch had happened. Rationale: there are broken devices out there that are "helpful" enough to go for "I don't have a page you've asked for, here, have another one". For example, PL3507 had been caught doing just that... f) sbp2 sets sdev->use_10_for_rw and sdev->use_10_for_ms instead of bothering to remap READ6/WRITE6/MOD_SENSE, so most of the conversions in there are gone now. Incidentally, I wonder if USB storage devices that have no mode page 8 are simply RBC ones. I haven't touched that, but it might be interesting to check... Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/ieee1394/sbp2.c130
-rw-r--r--drivers/ieee1394/sbp2.h4
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/sd.c36
-rw-r--r--include/scsi/scsi.h1
5 files changed, 32 insertions, 140 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 00c7b958361a..094e646ed4de 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1070,7 +1070,7 @@ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_
1070static __inline__ int sbp2_command_conversion_device_type(u8 device_type) 1070static __inline__ int sbp2_command_conversion_device_type(u8 device_type)
1071{ 1071{
1072 return (((device_type == TYPE_DISK) || 1072 return (((device_type == TYPE_DISK) ||
1073 (device_type == TYPE_SDAD) || 1073 (device_type == TYPE_RBC) ||
1074 (device_type == TYPE_ROM)) ? 1:0); 1074 (device_type == TYPE_ROM)) ? 1:0);
1075} 1075}
1076 1076
@@ -2111,102 +2111,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
2111 */ 2111 */
2112static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd) 2112static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
2113{ 2113{
2114 unchar new_cmd[16];
2115 u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
2116
2117 SBP2_DEBUG("sbp2_check_sbp2_command");
2118
2119 switch (*cmd) {
2120
2121 case READ_6:
2122
2123 if (sbp2_command_conversion_device_type(device_type)) {
2124
2125 SBP2_DEBUG("Convert READ_6 to READ_10");
2126
2127 /*
2128 * Need to turn read_6 into read_10
2129 */
2130 new_cmd[0] = 0x28;
2131 new_cmd[1] = (cmd[1] & 0xe0);
2132 new_cmd[2] = 0x0;
2133 new_cmd[3] = (cmd[1] & 0x1f);
2134 new_cmd[4] = cmd[2];
2135 new_cmd[5] = cmd[3];
2136 new_cmd[6] = 0x0;
2137 new_cmd[7] = 0x0;
2138 new_cmd[8] = cmd[4];
2139 new_cmd[9] = cmd[5];
2140
2141 memcpy(cmd, new_cmd, 10);
2142
2143 }
2144
2145 break;
2146
2147 case WRITE_6:
2148
2149 if (sbp2_command_conversion_device_type(device_type)) {
2150
2151 SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
2152
2153 /*
2154 * Need to turn write_6 into write_10
2155 */
2156 new_cmd[0] = 0x2a;
2157 new_cmd[1] = (cmd[1] & 0xe0);
2158 new_cmd[2] = 0x0;
2159 new_cmd[3] = (cmd[1] & 0x1f);
2160 new_cmd[4] = cmd[2];
2161 new_cmd[5] = cmd[3];
2162 new_cmd[6] = 0x0;
2163 new_cmd[7] = 0x0;
2164 new_cmd[8] = cmd[4];
2165 new_cmd[9] = cmd[5];
2166
2167 memcpy(cmd, new_cmd, 10);
2168
2169 }
2170
2171 break;
2172
2173 case MODE_SENSE:
2174
2175 if (sbp2_command_conversion_device_type(device_type)) {
2176
2177 SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
2178
2179 /*
2180 * Need to turn mode_sense_6 into mode_sense_10
2181 */
2182 new_cmd[0] = 0x5a;
2183 new_cmd[1] = cmd[1];
2184 new_cmd[2] = cmd[2];
2185 new_cmd[3] = 0x0;
2186 new_cmd[4] = 0x0;
2187 new_cmd[5] = 0x0;
2188 new_cmd[6] = 0x0;
2189 new_cmd[7] = 0x0;
2190 new_cmd[8] = cmd[4];
2191 new_cmd[9] = cmd[5];
2192
2193 memcpy(cmd, new_cmd, 10);
2194
2195 }
2196
2197 break;
2198
2199 case MODE_SELECT:
2200
2201 /*
2202 * TODO. Probably need to change mode select to 10 byte version
2203 */
2204
2205 default:
2206 break;
2207 }
2208
2209 return;
2210} 2114}
2211 2115
2212/* 2116/*
@@ -2272,14 +2176,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
2272 } 2176 }
2273 2177
2274 /* 2178 /*
2275 * Check for Simple Direct Access Device and change it to TYPE_DISK
2276 */
2277 if ((scsi_buf[0] & 0x1f) == TYPE_SDAD) {
2278 SBP2_DEBUG("Changing TYPE_SDAD to TYPE_DISK");
2279 scsi_buf[0] &= 0xe0;
2280 }
2281
2282 /*
2283 * Fix ansi revision and response data format 2179 * Fix ansi revision and response data format
2284 */ 2180 */
2285 scsi_buf[2] |= 2; 2181 scsi_buf[2] |= 2;
@@ -2287,27 +2183,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
2287 2183
2288 break; 2184 break;
2289 2185
2290 case MODE_SENSE:
2291
2292 if (sbp2_command_conversion_device_type(device_type)) {
2293
2294 SBP2_DEBUG("Modify mode sense response (10 byte version)");
2295
2296 scsi_buf[0] = scsi_buf[1]; /* Mode data length */
2297 scsi_buf[1] = scsi_buf[2]; /* Medium type */
2298 scsi_buf[2] = scsi_buf[3]; /* Device specific parameter */
2299 scsi_buf[3] = scsi_buf[7]; /* Block descriptor length */
2300 memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]);
2301 }
2302
2303 break;
2304
2305 case MODE_SELECT:
2306
2307 /*
2308 * TODO. Probably need to change mode select to 10 byte version
2309 */
2310
2311 default: 2186 default:
2312 break; 2187 break;
2313 } 2188 }
@@ -2690,7 +2565,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
2690static int sbp2scsi_slave_configure (struct scsi_device *sdev) 2565static int sbp2scsi_slave_configure (struct scsi_device *sdev)
2691{ 2566{
2692 blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); 2567 blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
2693 2568 sdev->use_10_for_rw = 1;
2569 sdev->use_10_for_ms = 1;
2694 return 0; 2570 return 0;
2695} 2571}
2696 2572
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index a84b039a05b9..cd425be74841 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -266,10 +266,6 @@ struct sbp2_status_block {
266#define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */ 266#define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */
267#define SBP2_MAX_SECTORS 255 /* Max sectors supported */ 267#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
268 268
269#ifndef TYPE_SDAD
270#define TYPE_SDAD 0x0e /* simplified direct access device */
271#endif
272
273/* 269/*
274 * SCSI direction table... 270 * SCSI direction table...
275 * (now used as a back-up in case the direction passed down from above is "unknown") 271 * (now used as a back-up in case the direction passed down from above is "unknown")
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index cca772624ae7..588611568d14 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -625,6 +625,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
625 case TYPE_MEDIUM_CHANGER: 625 case TYPE_MEDIUM_CHANGER:
626 case TYPE_ENCLOSURE: 626 case TYPE_ENCLOSURE:
627 case TYPE_COMM: 627 case TYPE_COMM:
628 case TYPE_RBC:
628 sdev->writeable = 1; 629 sdev->writeable = 1;
629 break; 630 break;
630 case TYPE_WORM: 631 case TYPE_WORM:
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 19afb25e44d3..bb8235598787 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1368,17 +1368,26 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
1368 */ 1368 */
1369static void 1369static void
1370sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, 1370sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
1371 struct scsi_request *SRpnt, unsigned char *buffer) { 1371 struct scsi_request *SRpnt, unsigned char *buffer)
1372{
1372 int len = 0, res; 1373 int len = 0, res;
1373 1374
1374 const int dbd = 0; /* DBD */ 1375 int dbd;
1375 const int modepage = 0x08; /* current values, cache page */ 1376 int modepage;
1376 struct scsi_mode_data data; 1377 struct scsi_mode_data data;
1377 struct scsi_sense_hdr sshdr; 1378 struct scsi_sense_hdr sshdr;
1378 1379
1379 if (sdkp->device->skip_ms_page_8) 1380 if (sdkp->device->skip_ms_page_8)
1380 goto defaults; 1381 goto defaults;
1381 1382
1383 if (sdkp->device->type == TYPE_RBC) {
1384 modepage = 6;
1385 dbd = 8;
1386 } else {
1387 modepage = 8;
1388 dbd = 0;
1389 }
1390
1382 /* cautiously ask */ 1391 /* cautiously ask */
1383 res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data); 1392 res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
1384 1393
@@ -1409,11 +1418,20 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
1409 "write back, no read (daft)" 1418 "write back, no read (daft)"
1410 }; 1419 };
1411 int ct = 0; 1420 int ct = 0;
1412 int offset = data.header_length + 1421 int offset = data.header_length + data.block_descriptor_length;
1413 data.block_descriptor_length + 2;
1414 1422
1415 sdkp->WCE = ((buffer[offset] & 0x04) != 0); 1423 if ((buffer[offset] & 0x3f) != modepage) {
1416 sdkp->RCD = ((buffer[offset] & 0x01) != 0); 1424 printk(KERN_ERR "%s: got wrong page\n", diskname);
1425 goto defaults;
1426 }
1427
1428 if (modepage == 8) {
1429 sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
1430 sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
1431 } else {
1432 sdkp->WCE = ((buffer[offset + 2] & 0x01) == 0);
1433 sdkp->RCD = 0;
1434 }
1417 1435
1418 ct = sdkp->RCD + 2*sdkp->WCE; 1436 ct = sdkp->RCD + 2*sdkp->WCE;
1419 1437
@@ -1533,7 +1551,7 @@ static int sd_probe(struct device *dev)
1533 int error; 1551 int error;
1534 1552
1535 error = -ENODEV; 1553 error = -ENODEV;
1536 if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD)) 1554 if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC)
1537 goto out; 1555 goto out;
1538 1556
1539 SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", 1557 SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
@@ -1570,7 +1588,7 @@ static int sd_probe(struct device *dev)
1570 sdkp->openers = 0; 1588 sdkp->openers = 0;
1571 1589
1572 if (!sdp->timeout) { 1590 if (!sdp->timeout) {
1573 if (sdp->type == TYPE_DISK) 1591 if (sdp->type != TYPE_MOD)
1574 sdp->timeout = SD_TIMEOUT; 1592 sdp->timeout = SD_TIMEOUT;
1575 else 1593 else
1576 sdp->timeout = SD_MOD_TIMEOUT; 1594 sdp->timeout = SD_MOD_TIMEOUT;
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index ca1e3b4a3183..1fb233741513 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -213,6 +213,7 @@ static inline int scsi_status_is_good(int status)
213#define TYPE_COMM 0x09 /* Communications device */ 213#define TYPE_COMM 0x09 /* Communications device */
214#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ 214#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */
215#define TYPE_RAID 0x0c 215#define TYPE_RAID 0x0c
216#define TYPE_RBC 0x0e
216#define TYPE_NO_LUN 0x7f 217#define TYPE_NO_LUN 0x7f
217 218
218/* 219/*