aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2006-05-15 16:04:59 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-05-18 00:32:21 -0400
commit24d3bf884e093f9de52d31c97187f4b9b4ad7dcb (patch)
tree3580e6023f813b1167df65be37298c278434b2d7 /drivers
parentcb46c3701fb7b738de1e22ac4f2d06d18f547a74 (diff)
[PATCH] sbp2: consolidate workarounds
Grand unification of the three types of workarounds we have so far. The "skip mode page 8" workaround is now limited to devices which pretend to be of TYPE_DISK instead of TYPE_RBC. This workaround is no longer enabled for Initio bridges. Patch update in anticipation of more workarounds: - Add module parameter "workarounds". - Deprecate parameter "force_inquiry_hack". - Compose the blacklist of a compound type for better readability and extensibility. - Remove a now unused #define. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ieee1394/sbp2.c152
-rw-r--r--drivers/ieee1394/sbp2.h16
2 files changed, 97 insertions, 71 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index f4206604db03..ecd59ef8c8a3 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -42,6 +42,7 @@
42#include <linux/kernel.h> 42#include <linux/kernel.h>
43#include <linux/list.h> 43#include <linux/list.h>
44#include <linux/string.h> 44#include <linux/string.h>
45#include <linux/stringify.h>
45#include <linux/slab.h> 46#include <linux/slab.h>
46#include <linux/interrupt.h> 47#include <linux/interrupt.h>
47#include <linux/fs.h> 48#include <linux/fs.h>
@@ -117,7 +118,8 @@ MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers (default
117 */ 118 */
118static int max_sectors = SBP2_MAX_SECTORS; 119static int max_sectors = SBP2_MAX_SECTORS;
119module_param(max_sectors, int, 0444); 120module_param(max_sectors, int, 0444);
120MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported (default = 255)"); 121MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported (default = "
122 __stringify(SBP2_MAX_SECTORS) ")");
121 123
122/* 124/*
123 * Exclusive login to sbp2 device? In most cases, the sbp2 driver should 125 * Exclusive login to sbp2 device? In most cases, the sbp2 driver should
@@ -135,18 +137,33 @@ module_param(exclusive_login, int, 0644);
135MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device (default = 1)"); 137MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device (default = 1)");
136 138
137/* 139/*
138 * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on 140 * If any of the following workarounds is required for your device to work,
139 * if your sbp2 device is not properly handling the SCSI inquiry command. 141 * please submit the kernel messages logged by sbp2 to the linux1394-devel
140 * This hack makes the inquiry look more like a typical MS Windows inquiry 142 * mailing list.
141 * by enforcing 36 byte inquiry and avoiding access to mode_sense page 8.
142 * 143 *
143 * If force_inquiry_hack=1 is required for your device to work, 144 * - 128kB max transfer
144 * please submit the logged sbp2_firmware_revision value of this device to 145 * Limit transfer size. Necessary for some old bridges.
145 * the linux1394-devel mailing list. 146 *
147 * - 36 byte inquiry
148 * When scsi_mod probes the device, let the inquiry command look like that
149 * from MS Windows.
150 *
151 * - skip mode page 8
152 * Suppress sending of mode_sense for mode page 8 if the device pretends to
153 * support the SCSI Primary Block commands instead of Reduced Block Commands.
146 */ 154 */
155static int sbp2_default_workarounds;
156module_param_named(workarounds, sbp2_default_workarounds, int, 0644);
157MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
158 ", 128kB max transfer = " __stringify(SBP2_WORKAROUND_128K_MAX_TRANS)
159 ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
160 ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
161 ", or a combination)");
162
163/* legacy parameter */
147static int force_inquiry_hack; 164static int force_inquiry_hack;
148module_param(force_inquiry_hack, int, 0644); 165module_param(force_inquiry_hack, int, 0644);
149MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)"); 166MODULE_PARM_DESC(force_inquiry_hack, "Deprecated, use 'workarounds'");
150 167
151/* 168/*
152 * Export information about protocols/devices supported by this driver. 169 * Export information about protocols/devices supported by this driver.
@@ -266,14 +283,29 @@ static struct hpsb_protocol_driver sbp2_driver = {
266}; 283};
267 284
268/* 285/*
269 * List of device firmwares that require the inquiry hack. 286 * List of devices with known bugs.
270 * Yields a few false positives but did not break other devices so far. 287 *
288 * The firmware_revision field, masked with 0xffff00, is the best indicator
289 * for the type of bridge chip of a device. It yields a few false positives
290 * but this did not break correctly behaving devices so far.
271 */ 291 */
272static u32 sbp2_broken_inquiry_list[] = { 292static const struct {
273 0x00002800, /* Stefan Richter <stefanr@s5r6.in-berlin.de> */ 293 u32 firmware_revision;
274 /* DViCO Momobay CX-1 */ 294 unsigned workarounds;
275 0x00000200 /* Andreas Plesch <plesch@fas.harvard.edu> */ 295} sbp2_workarounds_table[] = {
276 /* QPS Fire DVDBurner */ 296 /* TSB42AA9 */ {
297 .firmware_revision = 0x002800,
298 .workarounds = SBP2_WORKAROUND_INQUIRY_36 |
299 SBP2_WORKAROUND_MODE_SENSE_8,
300 },
301 /* Initio bridges, actually only needed for some older ones */ {
302 .firmware_revision = 0x000200,
303 .workarounds = SBP2_WORKAROUND_INQUIRY_36,
304 },
305 /* Symbios bridge */ {
306 .firmware_revision = 0xa0b800,
307 .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS,
308 }
277}; 309};
278 310
279/************************************** 311/**************************************
@@ -1450,7 +1482,8 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
1450 struct csr1212_dentry *dentry; 1482 struct csr1212_dentry *dentry;
1451 u64 management_agent_addr; 1483 u64 management_agent_addr;
1452 u32 command_set_spec_id, command_set, unit_characteristics, 1484 u32 command_set_spec_id, command_set, unit_characteristics,
1453 firmware_revision, workarounds; 1485 firmware_revision;
1486 unsigned workarounds;
1454 int i; 1487 int i;
1455 1488
1456 SBP2_DEBUG_ENTER(); 1489 SBP2_DEBUG_ENTER();
@@ -1506,12 +1539,8 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
1506 case SBP2_FIRMWARE_REVISION_KEY: 1539 case SBP2_FIRMWARE_REVISION_KEY:
1507 /* Firmware revision */ 1540 /* Firmware revision */
1508 firmware_revision = kv->value.immediate; 1541 firmware_revision = kv->value.immediate;
1509 if (force_inquiry_hack) 1542 SBP2_DEBUG("sbp2_firmware_revision = %x",
1510 SBP2_INFO("sbp2_firmware_revision = %x", 1543 (unsigned int)firmware_revision);
1511 (unsigned int)firmware_revision);
1512 else
1513 SBP2_DEBUG("sbp2_firmware_revision = %x",
1514 (unsigned int)firmware_revision);
1515 break; 1544 break;
1516 1545
1517 default: 1546 default:
@@ -1519,42 +1548,37 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
1519 } 1548 }
1520 } 1549 }
1521 1550
1522 /* This is the start of our broken device checking. We try to hack 1551 workarounds = sbp2_default_workarounds;
1523 * around oddities and known defects. */ 1552 if (force_inquiry_hack) {
1524 workarounds = 0x0; 1553 SBP2_WARN("force_inquiry_hack is deprecated. "
1554 "Use parameter 'workarounds' instead.");
1555 workarounds |= SBP2_WORKAROUND_INQUIRY_36;
1556 }
1525 1557
1526 /* If the vendor id is 0xa0b8 (Symbios vendor id), then we have a 1558 for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) {
1527 * bridge with 128KB max transfer size limitation. For sanity, we 1559 if (sbp2_workarounds_table[i].firmware_revision !=
1528 * only voice this when the current max_sectors setting 1560 (firmware_revision & 0xffff00))
1529 * exceeds the 128k limit. By default, that is not the case. 1561 continue;
1530 * 1562 workarounds |= sbp2_workarounds_table[i].workarounds;
1531 * It would be really nice if we could detect this before the scsi 1563 break;
1532 * host gets initialized. That way we can down-force the
1533 * max_sectors to account for it. That is not currently
1534 * possible. */
1535 if ((firmware_revision & 0xffff00) ==
1536 SBP2_128KB_BROKEN_FIRMWARE &&
1537 (max_sectors * 512) > (128*1024)) {
1538 SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.",
1539 NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid));
1540 SBP2_WARN("WARNING: Current max_sectors setting is larger than 128KB (%d sectors)!",
1541 max_sectors);
1542 workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER;
1543 }
1544
1545 /* Check for a blacklisted set of devices that require us to force
1546 * a 36 byte host inquiry. This can be overriden as a module param
1547 * (to force all hosts). */
1548 for (i = 0; i < ARRAY_SIZE(sbp2_broken_inquiry_list); i++) {
1549 if ((firmware_revision & 0xffff00) ==
1550 sbp2_broken_inquiry_list[i]) {
1551 SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround",
1552 NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid));
1553 workarounds |= SBP2_BREAKAGE_INQUIRY_HACK;
1554 break; /* No need to continue. */
1555 }
1556 } 1564 }
1557 1565
1566 if (workarounds)
1567 SBP2_INFO("Workarounds for node " NODE_BUS_FMT ": "
1568 "0x%x (firmware_revision 0x%x)",
1569 NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid),
1570 workarounds, firmware_revision);
1571
1572 /* We would need one SCSI host template for each target to adjust
1573 * max_sectors on the fly, therefore warn only. */
1574 if (workarounds & SBP2_WORKAROUND_128K_MAX_TRANS &&
1575 (max_sectors * 512) > (128 * 1024))
1576 SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB "
1577 "max transfer size. WARNING: Current max_sectors "
1578 "setting is larger than 128KB (%d sectors)",
1579 NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid),
1580 max_sectors);
1581
1558 /* If this is a logical unit directory entry, process the parent 1582 /* If this is a logical unit directory entry, process the parent
1559 * to get the values. */ 1583 * to get the values. */
1560 if (ud->flags & UNIT_DIRECTORY_LUN_DIRECTORY) { 1584 if (ud->flags & UNIT_DIRECTORY_LUN_DIRECTORY) {
@@ -2447,19 +2471,23 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
2447 2471
2448 scsi_id->sdev = sdev; 2472 scsi_id->sdev = sdev;
2449 2473
2450 if (force_inquiry_hack || 2474 if (scsi_id->workarounds & SBP2_WORKAROUND_INQUIRY_36)
2451 scsi_id->workarounds & SBP2_BREAKAGE_INQUIRY_HACK) {
2452 sdev->inquiry_len = 36; 2475 sdev->inquiry_len = 36;
2453 sdev->skip_ms_page_8 = 1;
2454 }
2455 return 0; 2476 return 0;
2456} 2477}
2457 2478
2458static int sbp2scsi_slave_configure(struct scsi_device *sdev) 2479static int sbp2scsi_slave_configure(struct scsi_device *sdev)
2459{ 2480{
2481 struct scsi_id_instance_data *scsi_id =
2482 (struct scsi_id_instance_data *)sdev->host->hostdata[0];
2483
2460 blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); 2484 blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
2461 sdev->use_10_for_rw = 1; 2485 sdev->use_10_for_rw = 1;
2462 sdev->use_10_for_ms = 1; 2486 sdev->use_10_for_ms = 1;
2487
2488 if (sdev->type == TYPE_DISK &&
2489 scsi_id->workarounds & SBP2_WORKAROUND_MODE_SENSE_8)
2490 sdev->skip_ms_page_8 = 1;
2463 return 0; 2491 return 0;
2464} 2492}
2465 2493
@@ -2603,7 +2631,9 @@ static int sbp2_module_init(void)
2603 scsi_driver_template.cmd_per_lun = 1; 2631 scsi_driver_template.cmd_per_lun = 1;
2604 } 2632 }
2605 2633
2606 /* Set max sectors (module load option). Default is 255 sectors. */ 2634 if (sbp2_default_workarounds & SBP2_WORKAROUND_128K_MAX_TRANS &&
2635 (max_sectors * 512) > (128 * 1024))
2636 max_sectors = 128 * 1024 / 512;
2607 scsi_driver_template.max_sectors = max_sectors; 2637 scsi_driver_template.max_sectors = max_sectors;
2608 2638
2609 /* Register our high level driver with 1394 stack */ 2639 /* Register our high level driver with 1394 stack */
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index e2d357a9ea3a..e40caf5d61ac 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -227,11 +227,6 @@ struct sbp2_status_block {
227#define SBP2_SW_VERSION_ENTRY 0x00010483 227#define SBP2_SW_VERSION_ENTRY 0x00010483
228 228
229/* 229/*
230 * Other misc defines
231 */
232#define SBP2_128KB_BROKEN_FIRMWARE 0xa0b800
233
234/*
235 * SCSI specific stuff 230 * SCSI specific stuff
236 */ 231 */
237 232
@@ -239,6 +234,11 @@ struct sbp2_status_block {
239#define SBP2_MAX_SECTORS 255 /* Max sectors supported */ 234#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
240#define SBP2_MAX_CMDS 8 /* This should be safe */ 235#define SBP2_MAX_CMDS 8 /* This should be safe */
241 236
237/* Flags for detected oddities and brokeness */
238#define SBP2_WORKAROUND_128K_MAX_TRANS 0x1
239#define SBP2_WORKAROUND_INQUIRY_36 0x2
240#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
241
242/* This is the two dma types we use for cmd_dma below */ 242/* This is the two dma types we use for cmd_dma below */
243enum cmd_dma_types { 243enum cmd_dma_types {
244 CMD_DMA_NONE, 244 CMD_DMA_NONE,
@@ -268,10 +268,6 @@ struct sbp2_command_info {
268 268
269}; 269};
270 270
271/* A list of flags for detected oddities and brokeness. */
272#define SBP2_BREAKAGE_128K_MAX_TRANSFER 0x1
273#define SBP2_BREAKAGE_INQUIRY_HACK 0x2
274
275struct sbp2scsi_host_info; 271struct sbp2scsi_host_info;
276 272
277/* 273/*
@@ -345,7 +341,7 @@ struct scsi_id_instance_data {
345 struct Scsi_Host *scsi_host; 341 struct Scsi_Host *scsi_host;
346 342
347 /* Device specific workarounds/brokeness */ 343 /* Device specific workarounds/brokeness */
348 u32 workarounds; 344 unsigned workarounds;
349}; 345};
350 346
351/* Sbp2 host data structure (one per IEEE1394 host) */ 347/* Sbp2 host data structure (one per IEEE1394 host) */