aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-sbp2.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-02-03 17:04:38 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-02-16 09:40:34 -0500
commit9220f1946209a5b3335ea2d28f8462695885791b (patch)
tree0d581c7ffca745158b9a15095f5b5a6f209ba066 /drivers/firewire/fw-sbp2.c
parentfa6e697b85d705d37b3b03829095c22bcbe95ab6 (diff)
firewire: fw-sbp2: add INQUIRY delay workaround
Several different SBP-2 bridges accept a login early while the IDE device is still powering up. They are therefore unable to respond to SCSI INQUIRY immediately, and the SCSI core has to retry the INQUIRY. One of these retries is typically successful, and all is well. But in case of Momobay FX-3A, the INQUIRY retries tend to fail entirely. This can usually be avoided by waiting a little while after login before letting the SCSI core send the INQUIRY. The old sbp2 driver handles this more gracefully for as yet unknown reasons (perhaps because it waits for fetch agent resets to complete, unlike fw-sbp2 which quickly proceeds after requesting the agent reset). Therefore the workaround is not as much necessary for sbp2. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> Signed-off-by: Jarod Wilson <jwilson@redhat.com>
Diffstat (limited to 'drivers/firewire/fw-sbp2.c')
-rw-r--r--drivers/firewire/fw-sbp2.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 72fddf5a12a3..4a118fbc7b24 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -32,6 +32,7 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34#include <linux/mod_devicetable.h> 34#include <linux/mod_devicetable.h>
35#include <linux/delay.h>
35#include <linux/device.h> 36#include <linux/device.h>
36#include <linux/scatterlist.h> 37#include <linux/scatterlist.h>
37#include <linux/dma-mapping.h> 38#include <linux/dma-mapping.h>
@@ -82,6 +83,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
82 * Avoids access beyond actual disk limits on devices with an off-by-one bug. 83 * Avoids access beyond actual disk limits on devices with an off-by-one bug.
83 * Don't use this with devices which don't have this bug. 84 * Don't use this with devices which don't have this bug.
84 * 85 *
86 * - delay inquiry
87 * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
88 *
85 * - override internal blacklist 89 * - override internal blacklist
86 * Instead of adding to the built-in blacklist, use only the workarounds 90 * Instead of adding to the built-in blacklist, use only the workarounds
87 * specified in the module load parameter. 91 * specified in the module load parameter.
@@ -91,6 +95,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
91#define SBP2_WORKAROUND_INQUIRY_36 0x2 95#define SBP2_WORKAROUND_INQUIRY_36 0x2
92#define SBP2_WORKAROUND_MODE_SENSE_8 0x4 96#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
93#define SBP2_WORKAROUND_FIX_CAPACITY 0x8 97#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
98#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
99#define SBP2_INQUIRY_DELAY 12
94#define SBP2_WORKAROUND_OVERRIDE 0x100 100#define SBP2_WORKAROUND_OVERRIDE 0x100
95 101
96static int sbp2_param_workarounds; 102static int sbp2_param_workarounds;
@@ -100,6 +106,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
100 ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) 106 ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
101 ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) 107 ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
102 ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) 108 ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
109 ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
103 ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) 110 ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
104 ", or a combination)"); 111 ", or a combination)");
105 112
@@ -303,6 +310,11 @@ static const struct {
303 .workarounds = SBP2_WORKAROUND_INQUIRY_36 | 310 .workarounds = SBP2_WORKAROUND_INQUIRY_36 |
304 SBP2_WORKAROUND_MODE_SENSE_8, 311 SBP2_WORKAROUND_MODE_SENSE_8,
305 }, 312 },
313 /* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
314 .firmware_revision = 0x002800,
315 .model = 0x000000,
316 .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
317 },
306 /* Initio bridges, actually only needed for some older ones */ { 318 /* Initio bridges, actually only needed for some older ones */ {
307 .firmware_revision = 0x000200, 319 .firmware_revision = 0x000200,
308 .model = ~0, 320 .model = ~0,
@@ -712,6 +724,9 @@ static void sbp2_login(struct work_struct *work)
712 PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); 724 PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
713 sbp2_agent_reset(lu); 725 sbp2_agent_reset(lu);
714 726
727 if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
728 ssleep(SBP2_INQUIRY_DELAY);
729
715 memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); 730 memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
716 eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff; 731 eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
717 eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff; 732 eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;