aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_spi.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2009-09-08 20:55:21 -0400
committerDan Williams <dan.j.williams@intel.com>2009-09-08 20:55:21 -0400
commitbbb20089a3275a19e475dbc21320c3742e3ca423 (patch)
tree216fdc1cbef450ca688135c5b8969169482d9a48 /drivers/scsi/scsi_transport_spi.c
parent3e48e656903e9fd8bc805c6a2c4264d7808d315b (diff)
parent657a77fa7284d8ae28dfa48f1dc5d919bf5b2843 (diff)
Merge branch 'dmaengine' into async-tx-next
Conflicts: crypto/async_tx/async_xor.c drivers/dma/ioat/dma_v2.h drivers/dma/ioat/pci.c drivers/md/raid5.c
Diffstat (limited to 'drivers/scsi/scsi_transport_spi.c')
-rw-r--r--drivers/scsi/scsi_transport_spi.c65
1 files changed, 57 insertions, 8 deletions
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index f49f55c6bfc8..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 */
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;
@@ -234,8 +257,10 @@ static int spi_setup_transport_attrs(struct transport_container *tc,
234 spi_width(starget) = 0; /* narrow */ 257 spi_width(starget) = 0; /* narrow */
235 spi_max_width(starget) = 1; 258 spi_max_width(starget) = 1;
236 spi_iu(starget) = 0; /* no IU */ 259 spi_iu(starget) = 0; /* no IU */
260 spi_max_iu(starget) = 1;
237 spi_dt(starget) = 0; /* ST */ 261 spi_dt(starget) = 0; /* ST */
238 spi_qas(starget) = 0; 262 spi_qas(starget) = 0;
263 spi_max_qas(starget) = 1;
239 spi_wr_flow(starget) = 0; 264 spi_wr_flow(starget) = 0;
240 spi_rd_strm(starget) = 0; 265 spi_rd_strm(starget) = 0;
241 spi_rti(starget) = 0; 266 spi_rti(starget) = 0;
@@ -360,9 +385,9 @@ static DEVICE_ATTR(field, S_IRUGO, \
360/* The Parallel SCSI Tranport Attributes: */ 385/* The Parallel SCSI Tranport Attributes: */
361spi_transport_max_attr(offset, "%d\n"); 386spi_transport_max_attr(offset, "%d\n");
362spi_transport_max_attr(width, "%d\n"); 387spi_transport_max_attr(width, "%d\n");
363spi_transport_rd_attr(iu, "%d\n"); 388spi_transport_max_attr(iu, "%d\n");
364spi_transport_rd_attr(dt, "%d\n"); 389spi_transport_rd_attr(dt, "%d\n");
365spi_transport_rd_attr(qas, "%d\n"); 390spi_transport_max_attr(qas, "%d\n");
366spi_transport_rd_attr(wr_flow, "%d\n"); 391spi_transport_rd_attr(wr_flow, "%d\n");
367spi_transport_rd_attr(rd_strm, "%d\n"); 392spi_transport_rd_attr(rd_strm, "%d\n");
368spi_transport_rd_attr(rti, "%d\n"); 393spi_transport_rd_attr(rti, "%d\n");
@@ -831,7 +856,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
831 return; 856 return;
832 } 857 }
833 858
834 if (!scsi_device_wide(sdev)) { 859 if (!spi_support_wide(starget)) {
835 spi_max_width(starget) = 0; 860 spi_max_width(starget) = 0;
836 max_width = 0; 861 max_width = 0;
837 } 862 }
@@ -858,7 +883,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
858 return; 883 return;
859 884
860 /* device can't handle synchronous */ 885 /* device can't handle synchronous */
861 if (!scsi_device_sync(sdev) && !scsi_device_dt(sdev)) 886 if (!spi_support_sync(starget) && !spi_support_dt(starget))
862 return; 887 return;
863 888
864 /* len == -1 is the signal that we need to ascertain the 889 /* len == -1 is the signal that we need to ascertain the
@@ -874,13 +899,14 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
874 899
875 /* try QAS requests; this should be harmless to set if the 900 /* try QAS requests; this should be harmless to set if the
876 * target supports it */ 901 * target supports it */
877 if (scsi_device_qas(sdev)) { 902 if (spi_support_qas(starget) && spi_max_qas(starget)) {
878 DV_SET(qas, 1); 903 DV_SET(qas, 1);
879 } else { 904 } else {
880 DV_SET(qas, 0); 905 DV_SET(qas, 0);
881 } 906 }
882 907
883 if (scsi_device_ius(sdev) && min_period < 9) { 908 if (spi_support_ius(starget) && spi_max_iu(starget) &&
909 min_period < 9) {
884 /* This u320 (or u640). Set IU transfers */ 910 /* This u320 (or u640). Set IU transfers */
885 DV_SET(iu, 1); 911 DV_SET(iu, 1);
886 /* Then set the optional parameters */ 912 /* Then set the optional parameters */
@@ -900,7 +926,7 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
900 i->f->get_signalling(shost); 926 i->f->get_signalling(shost);
901 if (spi_signalling(shost) == SPI_SIGNAL_SE || 927 if (spi_signalling(shost) == SPI_SIGNAL_SE ||
902 spi_signalling(shost) == SPI_SIGNAL_HVD || 928 spi_signalling(shost) == SPI_SIGNAL_HVD ||
903 !scsi_device_dt(sdev)) { 929 !spi_support_dt(starget)) {
904 DV_SET(dt, 0); 930 DV_SET(dt, 0);
905 } else { 931 } else {
906 DV_SET(dt, 1); 932 DV_SET(dt, 1);
@@ -1412,12 +1438,18 @@ static mode_t target_attribute_is_visible(struct kobject *kobj,
1412 else if (attr == &dev_attr_iu.attr && 1438 else if (attr == &dev_attr_iu.attr &&
1413 spi_support_ius(starget)) 1439 spi_support_ius(starget))
1414 return TARGET_ATTRIBUTE_HELPER(iu); 1440 return TARGET_ATTRIBUTE_HELPER(iu);
1441 else if (attr == &dev_attr_max_iu.attr &&
1442 spi_support_ius(starget))
1443 return TARGET_ATTRIBUTE_HELPER(iu);
1415 else if (attr == &dev_attr_dt.attr && 1444 else if (attr == &dev_attr_dt.attr &&
1416 spi_support_dt(starget)) 1445 spi_support_dt(starget))
1417 return TARGET_ATTRIBUTE_HELPER(dt); 1446 return TARGET_ATTRIBUTE_HELPER(dt);
1418 else if (attr == &dev_attr_qas.attr && 1447 else if (attr == &dev_attr_qas.attr &&
1419 spi_support_qas(starget)) 1448 spi_support_qas(starget))
1420 return TARGET_ATTRIBUTE_HELPER(qas); 1449 return TARGET_ATTRIBUTE_HELPER(qas);
1450 else if (attr == &dev_attr_max_qas.attr &&
1451 spi_support_qas(starget))
1452 return TARGET_ATTRIBUTE_HELPER(qas);
1421 else if (attr == &dev_attr_wr_flow.attr && 1453 else if (attr == &dev_attr_wr_flow.attr &&
1422 spi_support_ius(starget)) 1454 spi_support_ius(starget))
1423 return TARGET_ATTRIBUTE_HELPER(wr_flow); 1455 return TARGET_ATTRIBUTE_HELPER(wr_flow);
@@ -1447,8 +1479,10 @@ static struct attribute *target_attributes[] = {
1447 &dev_attr_width.attr, 1479 &dev_attr_width.attr,
1448 &dev_attr_max_width.attr, 1480 &dev_attr_max_width.attr,
1449 &dev_attr_iu.attr, 1481 &dev_attr_iu.attr,
1482 &dev_attr_max_iu.attr,
1450 &dev_attr_dt.attr, 1483 &dev_attr_dt.attr,
1451 &dev_attr_qas.attr, 1484 &dev_attr_qas.attr,
1485 &dev_attr_max_qas.attr,
1452 &dev_attr_wr_flow.attr, 1486 &dev_attr_wr_flow.attr,
1453 &dev_attr_rd_strm.attr, 1487 &dev_attr_rd_strm.attr,
1454 &dev_attr_rti.attr, 1488 &dev_attr_rti.attr,
@@ -1513,7 +1547,21 @@ EXPORT_SYMBOL(spi_release_transport);
1513 1547
1514static __init int spi_transport_init(void) 1548static __init int spi_transport_init(void)
1515{ 1549{
1516 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);
1517 if (error) 1565 if (error)
1518 return error; 1566 return error;
1519 error = anon_transport_class_register(&spi_device_class); 1567 error = anon_transport_class_register(&spi_device_class);
@@ -1525,6 +1573,7 @@ static void __exit spi_transport_exit(void)
1525 transport_class_unregister(&spi_transport_class); 1573 transport_class_unregister(&spi_transport_class);
1526 anon_transport_class_unregister(&spi_device_class); 1574 anon_transport_class_unregister(&spi_device_class);
1527 transport_class_unregister(&spi_host_class); 1575 transport_class_unregister(&spi_host_class);
1576 scsi_dev_info_remove_list(SCSI_DEVINFO_SPI);
1528} 1577}
1529 1578
1530MODULE_AUTHOR("Martin Hicks"); 1579MODULE_AUTHOR("Martin Hicks");