diff options
Diffstat (limited to 'drivers/scsi/scsi_transport_spi.c')
-rw-r--r-- | drivers/scsi/scsi_transport_spi.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 654a34fb04cb..c25bd9a34e02 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 */ | ||
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 | /* 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; |
@@ -833,7 +856,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
833 | return; | 856 | return; |
834 | } | 857 | } |
835 | 858 | ||
836 | if (!scsi_device_wide(sdev)) { | 859 | if (!spi_support_wide(starget)) { |
837 | spi_max_width(starget) = 0; | 860 | spi_max_width(starget) = 0; |
838 | max_width = 0; | 861 | max_width = 0; |
839 | } | 862 | } |
@@ -860,7 +883,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
860 | return; | 883 | return; |
861 | 884 | ||
862 | /* device can't handle synchronous */ | 885 | /* device can't handle synchronous */ |
863 | if (!scsi_device_sync(sdev) && !scsi_device_dt(sdev)) | 886 | if (!spi_support_sync(starget) && !spi_support_dt(starget)) |
864 | return; | 887 | return; |
865 | 888 | ||
866 | /* len == -1 is the signal that we need to ascertain the | 889 | /* len == -1 is the signal that we need to ascertain the |
@@ -876,13 +899,14 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
876 | 899 | ||
877 | /* try QAS requests; this should be harmless to set if the | 900 | /* try QAS requests; this should be harmless to set if the |
878 | * target supports it */ | 901 | * target supports it */ |
879 | if (scsi_device_qas(sdev) && spi_max_qas(starget)) { | 902 | if (spi_support_qas(starget) && spi_max_qas(starget)) { |
880 | DV_SET(qas, 1); | 903 | DV_SET(qas, 1); |
881 | } else { | 904 | } else { |
882 | DV_SET(qas, 0); | 905 | DV_SET(qas, 0); |
883 | } | 906 | } |
884 | 907 | ||
885 | if (scsi_device_ius(sdev) && spi_max_iu(starget) && min_period < 9) { | 908 | if (spi_support_ius(starget) && spi_max_iu(starget) && |
909 | min_period < 9) { | ||
886 | /* This u320 (or u640). Set IU transfers */ | 910 | /* This u320 (or u640). Set IU transfers */ |
887 | DV_SET(iu, 1); | 911 | DV_SET(iu, 1); |
888 | /* Then set the optional parameters */ | 912 | /* Then set the optional parameters */ |
@@ -902,7 +926,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
902 | i->f->get_signalling(shost); | 926 | i->f->get_signalling(shost); |
903 | if (spi_signalling(shost) == SPI_SIGNAL_SE || | 927 | if (spi_signalling(shost) == SPI_SIGNAL_SE || |
904 | spi_signalling(shost) == SPI_SIGNAL_HVD || | 928 | spi_signalling(shost) == SPI_SIGNAL_HVD || |
905 | !scsi_device_dt(sdev)) { | 929 | !spi_support_dt(starget)) { |
906 | DV_SET(dt, 0); | 930 | DV_SET(dt, 0); |
907 | } else { | 931 | } else { |
908 | DV_SET(dt, 1); | 932 | DV_SET(dt, 1); |
@@ -1523,7 +1547,21 @@ EXPORT_SYMBOL(spi_release_transport); | |||
1523 | 1547 | ||
1524 | static __init int spi_transport_init(void) | 1548 | static __init int spi_transport_init(void) |
1525 | { | 1549 | { |
1526 | 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); | ||
1527 | if (error) | 1565 | if (error) |
1528 | return error; | 1566 | return error; |
1529 | error = anon_transport_class_register(&spi_device_class); | 1567 | error = anon_transport_class_register(&spi_device_class); |
@@ -1535,6 +1573,7 @@ static void __exit spi_transport_exit(void) | |||
1535 | transport_class_unregister(&spi_transport_class); | 1573 | transport_class_unregister(&spi_transport_class); |
1536 | anon_transport_class_unregister(&spi_device_class); | 1574 | anon_transport_class_unregister(&spi_device_class); |
1537 | transport_class_unregister(&spi_host_class); | 1575 | transport_class_unregister(&spi_host_class); |
1576 | scsi_dev_info_remove_list(SCSI_DEVINFO_SPI); | ||
1538 | } | 1577 | } |
1539 | 1578 | ||
1540 | MODULE_AUTHOR("Martin Hicks"); | 1579 | MODULE_AUTHOR("Martin Hicks"); |