Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+40 -1
+1
drivers/scsi/scsi_priv.h
··· 43 43 /* list of keys for the lists */ 44 44 enum { 45 45 SCSI_DEVINFO_GLOBAL = 0, 46 + SCSI_DEVINFO_SPI, 46 47 }; 47 48 48 49 extern int scsi_get_device_flags(struct scsi_device *sdev,
+39 -1
drivers/scsi/scsi_transport_spi.c
··· 46 46 #define DV_RETRIES 3 /* should only need at most 47 47 * two cc/ua clears */ 48 48 49 + /* Our blacklist flags */ 50 + enum { 51 + SPI_BLIST_NOIUS = 0x1, 52 + }; 53 + 54 + /* blacklist table, modelled on scsi_devinfo.c */ 55 + static 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 65 /* Private data accessors (keep these out of the header file) */ 50 66 #define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress) 51 67 #define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex) ··· 223 207 { 224 208 struct scsi_device *sdev = to_scsi_device(dev); 225 209 struct scsi_target *starget = sdev->sdev_target; 210 + unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8], 211 + &sdev->inquiry[16], 212 + SCSI_DEVINFO_SPI); 226 213 227 214 /* Populate the target capability fields with the values 228 215 * gleaned from the device inquiry */ ··· 235 216 spi_support_dt(starget) = scsi_device_dt(sdev); 236 217 spi_support_dt_only(starget) = scsi_device_dt_only(sdev); 237 218 spi_support_ius(starget) = scsi_device_ius(sdev); 219 + if (bflags & SPI_BLIST_NOIUS) { 220 + dev_info(dev, "Information Units disabled by blacklist\n"); 221 + spi_support_ius(starget) = 0; 222 + } 238 223 spi_support_qas(starget) = scsi_device_qas(sdev); 239 224 240 225 return 0; ··· 1547 1524 1548 1525 static __init int spi_transport_init(void) 1549 1526 { 1550 - int error = transport_class_register(&spi_transport_class); 1527 + int error = scsi_dev_info_add_list(SCSI_DEVINFO_SPI, 1528 + "SCSI Parallel Transport Class"); 1529 + if (!error) { 1530 + int i; 1531 + 1532 + for (i = 0; spi_static_device_list[i].vendor; i++) 1533 + scsi_dev_info_list_add_keyed(1, /* compatible */ 1534 + spi_static_device_list[i].vendor, 1535 + spi_static_device_list[i].model, 1536 + NULL, 1537 + spi_static_device_list[i].flags, 1538 + SCSI_DEVINFO_SPI); 1539 + } 1540 + 1541 + error = transport_class_register(&spi_transport_class); 1551 1542 if (error) 1552 1543 return error; 1553 1544 error = anon_transport_class_register(&spi_device_class); ··· 1573 1536 transport_class_unregister(&spi_transport_class); 1574 1537 anon_transport_class_unregister(&spi_device_class); 1575 1538 transport_class_unregister(&spi_host_class); 1539 + scsi_dev_info_remove_list(SCSI_DEVINFO_SPI); 1576 1540 } 1577 1541 1578 1542 MODULE_AUTHOR("Martin Hicks");