aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-17 15:05:05 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-21 11:52:46 -0400
commita9e0edb687151617fe89cc5ab0086ebfc73ffccb (patch)
treecaac2147c99dee9650da01384c2605b21f2ec5bb /drivers
parent9872b81cf9f4b163e9c558d79e76b832c58a4814 (diff)
scsi_transport_spi: Blacklist Ultrium-3 tape for IU transfers
There have been several bug reports which identified the Ultrium-3 tape as just hanging up on the bus during certain types of IU transfer. The identified culpret is type 0x02 (MULTIPLE COMMAND) transfers. The only way to prevent this tape wedging is to prevent it from using IU transfers at all. So this patch uses the exported blacklist matching technology to recognise the drive and force it not to use IU transfers. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/scsi_transport_spi.c40
2 files changed, 40 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index b4e49cd6e75..00264aab8c8 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -43,6 +43,7 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
43/* list of keys for the lists */ 43/* list of keys for the lists */
44enum { 44enum {
45 SCSI_DEVINFO_GLOBAL = 0, 45 SCSI_DEVINFO_GLOBAL = 0,
46 SCSI_DEVINFO_SPI,
46}; 47};
47 48
48extern int scsi_get_device_flags(struct scsi_device *sdev, 49extern int scsi_get_device_flags(struct scsi_device *sdev,
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 00cfb40b5ef..c25bd9a34e0 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -46,6 +46,22 @@
46#define DV_RETRIES 3 /* should only need at most 46#define DV_RETRIES 3 /* should only need at most
47 * two cc/ua clears */ 47 * two cc/ua clears */
48 48
49/* Our blacklist flags */
50enum {
51 SPI_BLIST_NOIUS = 0x1,
52};
53
54/* blacklist table, modelled on scsi_devinfo.c */
55static struct {
56 char *vendor;
57 char *model;
58 unsigned flags;
59} spi_static_device_list[] __initdata = {
60 {"HP", "Ultrium 3-SCSI", SPI_BLIST_NOIUS },
61 {"IBM", "ULTRIUM-TD3", SPI_BLIST_NOIUS },
62 {NULL, NULL, 0}
63};
64
49/* Private data accessors (keep these out of the header file) */ 65/* Private data accessors (keep these out of the header file) */
50#define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress) 66#define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress)
51#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex) 67#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex)
@@ -207,6 +223,9 @@ static int spi_device_configure(struct transport_container *tc,
207{ 223{
208 struct scsi_device *sdev = to_scsi_device(dev); 224 struct scsi_device *sdev = to_scsi_device(dev);
209 struct scsi_target *starget = sdev->sdev_target; 225 struct scsi_target *starget = sdev->sdev_target;
226 unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8],
227 &sdev->inquiry[16],
228 SCSI_DEVINFO_SPI);
210 229
211 /* Populate the target capability fields with the values 230 /* Populate the target capability fields with the values
212 * gleaned from the device inquiry */ 231 * gleaned from the device inquiry */
@@ -216,6 +235,10 @@ static int spi_device_configure(struct transport_container *tc,
216 spi_support_dt(starget) = scsi_device_dt(sdev); 235 spi_support_dt(starget) = scsi_device_dt(sdev);
217 spi_support_dt_only(starget) = scsi_device_dt_only(sdev); 236 spi_support_dt_only(starget) = scsi_device_dt_only(sdev);
218 spi_support_ius(starget) = scsi_device_ius(sdev); 237 spi_support_ius(starget) = scsi_device_ius(sdev);
238 if (bflags & SPI_BLIST_NOIUS) {
239 dev_info(dev, "Information Units disabled by blacklist\n");
240 spi_support_ius(starget) = 0;
241 }
219 spi_support_qas(starget) = scsi_device_qas(sdev); 242 spi_support_qas(starget) = scsi_device_qas(sdev);
220 243
221 return 0; 244 return 0;
@@ -1524,7 +1547,21 @@ EXPORT_SYMBOL(spi_release_transport);
1524 1547
1525static __init int spi_transport_init(void) 1548static __init int spi_transport_init(void)
1526{ 1549{
1527 int error = transport_class_register(&spi_transport_class); 1550 int error = scsi_dev_info_add_list(SCSI_DEVINFO_SPI,
1551 "SCSI Parallel Transport Class");
1552 if (!error) {
1553 int i;
1554
1555 for (i = 0; spi_static_device_list[i].vendor; i++)
1556 scsi_dev_info_list_add_keyed(1, /* compatible */
1557 spi_static_device_list[i].vendor,
1558 spi_static_device_list[i].model,
1559 NULL,
1560 spi_static_device_list[i].flags,
1561 SCSI_DEVINFO_SPI);
1562 }
1563
1564 error = transport_class_register(&spi_transport_class);
1528 if (error) 1565 if (error)
1529 return error; 1566 return error;
1530 error = anon_transport_class_register(&spi_device_class); 1567 error = anon_transport_class_register(&spi_device_class);
@@ -1536,6 +1573,7 @@ static void __exit spi_transport_exit(void)
1536 transport_class_unregister(&spi_transport_class); 1573 transport_class_unregister(&spi_transport_class);
1537 anon_transport_class_unregister(&spi_device_class); 1574 anon_transport_class_unregister(&spi_device_class);
1538 transport_class_unregister(&spi_host_class); 1575 transport_class_unregister(&spi_host_class);
1576 scsi_dev_info_remove_list(SCSI_DEVINFO_SPI);
1539} 1577}
1540 1578
1541MODULE_AUTHOR("Martin Hicks"); 1579MODULE_AUTHOR("Martin Hicks");