|
@@ -32,6 +32,7 @@
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/moduleparam.h>
|
|
|
#include <linux/mod_devicetable.h>
|
|
|
+#include <linux/delay.h>
|
|
|
#include <linux/device.h>
|
|
|
#include <linux/scatterlist.h>
|
|
|
#include <linux/dma-mapping.h>
|
|
@@ -82,6 +83,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
|
|
|
* Avoids access beyond actual disk limits on devices with an off-by-one bug.
|
|
|
* Don't use this with devices which don't have this bug.
|
|
|
*
|
|
|
+ * - delay inquiry
|
|
|
+ * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry.
|
|
|
+ *
|
|
|
* - override internal blacklist
|
|
|
* Instead of adding to the built-in blacklist, use only the workarounds
|
|
|
* specified in the module load parameter.
|
|
@@ -91,6 +95,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
|
|
|
#define SBP2_WORKAROUND_INQUIRY_36 0x2
|
|
|
#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
|
|
|
#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
|
|
|
+#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10
|
|
|
+#define SBP2_INQUIRY_DELAY 12
|
|
|
#define SBP2_WORKAROUND_OVERRIDE 0x100
|
|
|
|
|
|
static int sbp2_param_workarounds;
|
|
@@ -100,6 +106,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
|
|
|
", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
|
|
|
", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
|
|
|
", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
|
|
|
+ ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY)
|
|
|
", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
|
|
|
", or a combination)");
|
|
|
|
|
@@ -303,6 +310,11 @@ static const struct {
|
|
|
.workarounds = SBP2_WORKAROUND_INQUIRY_36 |
|
|
|
SBP2_WORKAROUND_MODE_SENSE_8,
|
|
|
},
|
|
|
+ /* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
|
|
|
+ .firmware_revision = 0x002800,
|
|
|
+ .model = 0x000000,
|
|
|
+ .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY,
|
|
|
+ },
|
|
|
/* Initio bridges, actually only needed for some older ones */ {
|
|
|
.firmware_revision = 0x000200,
|
|
|
.model = ~0,
|
|
@@ -712,6 +724,9 @@ static void sbp2_login(struct work_struct *work)
|
|
|
PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
|
|
|
sbp2_agent_reset(lu);
|
|
|
|
|
|
+ if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY)
|
|
|
+ ssleep(SBP2_INQUIRY_DELAY);
|
|
|
+
|
|
|
memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
|
|
|
eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
|
|
|
eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
|