Skip to content

Commit

Permalink
scsi_transport_spi: Blacklist Ultrium-3 tape for IU transfers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
James Bottomley authored and James Bottomley committed Jun 21, 2009
1 parent 9872b81 commit a9e0edb
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/scsi/scsi_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
/* list of keys for the lists */
enum {
SCSI_DEVINFO_GLOBAL = 0,
SCSI_DEVINFO_SPI,
};

extern int scsi_get_device_flags(struct scsi_device *sdev,
Expand Down
40 changes: 39 additions & 1 deletion drivers/scsi/scsi_transport_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@
#define DV_RETRIES 3 /* should only need at most
* two cc/ua clears */

/* Our blacklist flags */
enum {
SPI_BLIST_NOIUS = 0x1,
};

/* blacklist table, modelled on scsi_devinfo.c */
static struct {
char *vendor;
char *model;
unsigned flags;
} spi_static_device_list[] __initdata = {
{"HP", "Ultrium 3-SCSI", SPI_BLIST_NOIUS },
{"IBM", "ULTRIUM-TD3", SPI_BLIST_NOIUS },
{NULL, NULL, 0}
};

/* Private data accessors (keep these out of the header file) */
#define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress)
#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex)
Expand Down Expand Up @@ -207,6 +223,9 @@ static int spi_device_configure(struct transport_container *tc,
{
struct scsi_device *sdev = to_scsi_device(dev);
struct scsi_target *starget = sdev->sdev_target;
unsigned bflags = scsi_get_device_flags_keyed(sdev, &sdev->inquiry[8],
&sdev->inquiry[16],
SCSI_DEVINFO_SPI);

/* Populate the target capability fields with the values
* gleaned from the device inquiry */
Expand All @@ -216,6 +235,10 @@ static int spi_device_configure(struct transport_container *tc,
spi_support_dt(starget) = scsi_device_dt(sdev);
spi_support_dt_only(starget) = scsi_device_dt_only(sdev);
spi_support_ius(starget) = scsi_device_ius(sdev);
if (bflags & SPI_BLIST_NOIUS) {
dev_info(dev, "Information Units disabled by blacklist\n");
spi_support_ius(starget) = 0;
}
spi_support_qas(starget) = scsi_device_qas(sdev);

return 0;
Expand Down Expand Up @@ -1524,7 +1547,21 @@ EXPORT_SYMBOL(spi_release_transport);

static __init int spi_transport_init(void)
{
int error = transport_class_register(&spi_transport_class);
int error = scsi_dev_info_add_list(SCSI_DEVINFO_SPI,
"SCSI Parallel Transport Class");
if (!error) {
int i;

for (i = 0; spi_static_device_list[i].vendor; i++)
scsi_dev_info_list_add_keyed(1, /* compatible */
spi_static_device_list[i].vendor,
spi_static_device_list[i].model,
NULL,
spi_static_device_list[i].flags,
SCSI_DEVINFO_SPI);
}

error = transport_class_register(&spi_transport_class);
if (error)
return error;
error = anon_transport_class_register(&spi_device_class);
Expand All @@ -1536,6 +1573,7 @@ static void __exit spi_transport_exit(void)
transport_class_unregister(&spi_transport_class);
anon_transport_class_unregister(&spi_device_class);
transport_class_unregister(&spi_host_class);
scsi_dev_info_remove_list(SCSI_DEVINFO_SPI);
}

MODULE_AUTHOR("Martin Hicks");
Expand Down

0 comments on commit a9e0edb

Please sign in to comment.