aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2006-09-20 12:00:18 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-23 21:53:53 -0400
commitdfdc58ba354adb80d67c99f7be84f95a8e02e466 (patch)
tree9cbbe31f7d3d5be0029fd7c1a8eeaaa02e53853a
parenta07f353701acae77e023f6270e8af353b37af7c4 (diff)
[SCSI] SPI transport class: misc DV fixes
Key more of the domain validation settings off the inquiry data from the disk (in particular, don't try IU or DT unless the disk claims to support them. Also add a new dv_in_progress flag to prevent recursive DV. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/scsi_transport_spi.c30
-rw-r--r--include/scsi/scsi_transport_spi.h3
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 29a9a53cdd1a..9f070f0d0f2b 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -47,6 +47,7 @@
47 47
48/* Private data accessors (keep these out of the header file) */ 48/* Private data accessors (keep these out of the header file) */
49#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) 49#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
50#define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress)
50#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex) 51#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex)
51 52
52struct spi_internal { 53struct spi_internal {
@@ -240,6 +241,7 @@ static int spi_setup_transport_attrs(struct transport_container *tc,
240 spi_pcomp_en(starget) = 0; 241 spi_pcomp_en(starget) = 0;
241 spi_hold_mcs(starget) = 0; 242 spi_hold_mcs(starget) = 0;
242 spi_dv_pending(starget) = 0; 243 spi_dv_pending(starget) = 0;
244 spi_dv_in_progress(starget) = 0;
243 spi_initial_dv(starget) = 0; 245 spi_initial_dv(starget) = 0;
244 mutex_init(&spi_dv_mutex(starget)); 246 mutex_init(&spi_dv_mutex(starget));
245 247
@@ -830,28 +832,37 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
830 DV_SET(period, spi_min_period(starget)); 832 DV_SET(period, spi_min_period(starget));
831 /* try QAS requests; this should be harmless to set if the 833 /* try QAS requests; this should be harmless to set if the
832 * target supports it */ 834 * target supports it */
833 if (scsi_device_qas(sdev)) 835 if (scsi_device_qas(sdev)) {
834 DV_SET(qas, 1); 836 DV_SET(qas, 1);
835 /* Also try IU transfers */ 837 } else {
836 if (scsi_device_ius(sdev)) 838 DV_SET(qas, 0);
839 }
840
841 if (scsi_device_ius(sdev) && spi_min_period(starget) < 9) {
842 /* This u320 (or u640). Set IU transfers */
837 DV_SET(iu, 1); 843 DV_SET(iu, 1);
838 if (spi_min_period(starget) < 9) { 844 /* Then set the optional parameters */
839 /* This u320 (or u640). Ignore the coupled parameters
840 * like DT and IU, but set the optional ones */
841 DV_SET(rd_strm, 1); 845 DV_SET(rd_strm, 1);
842 DV_SET(wr_flow, 1); 846 DV_SET(wr_flow, 1);
843 DV_SET(rti, 1); 847 DV_SET(rti, 1);
844 if (spi_min_period(starget) == 8) 848 if (spi_min_period(starget) == 8)
845 DV_SET(pcomp_en, 1); 849 DV_SET(pcomp_en, 1);
850 } else {
851 DV_SET(iu, 0);
846 } 852 }
853
847 /* now that we've done all this, actually check the bus 854 /* now that we've done all this, actually check the bus
848 * signal type (if known). Some devices are stupid on 855 * signal type (if known). Some devices are stupid on
849 * a SE bus and still claim they can try LVD only settings */ 856 * a SE bus and still claim they can try LVD only settings */
850 if (i->f->get_signalling) 857 if (i->f->get_signalling)
851 i->f->get_signalling(shost); 858 i->f->get_signalling(shost);
852 if (spi_signalling(shost) == SPI_SIGNAL_SE || 859 if (spi_signalling(shost) == SPI_SIGNAL_SE ||
853 spi_signalling(shost) == SPI_SIGNAL_HVD) 860 spi_signalling(shost) == SPI_SIGNAL_HVD ||
861 !scsi_device_dt(sdev)) {
854 DV_SET(dt, 0); 862 DV_SET(dt, 0);
863 } else {
864 DV_SET(dt, 1);
865 }
855 /* Do the read only INQUIRY tests */ 866 /* Do the read only INQUIRY tests */
856 spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, 867 spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len,
857 spi_dv_device_compare_inquiry); 868 spi_dv_device_compare_inquiry);
@@ -907,6 +918,10 @@ spi_dv_device(struct scsi_device *sdev)
907 if (unlikely(scsi_device_get(sdev))) 918 if (unlikely(scsi_device_get(sdev)))
908 return; 919 return;
909 920
921 if (unlikely(spi_dv_in_progress(starget)))
922 return;
923 spi_dv_in_progress(starget) = 1;
924
910 buffer = kzalloc(len, GFP_KERNEL); 925 buffer = kzalloc(len, GFP_KERNEL);
911 926
912 if (unlikely(!buffer)) 927 if (unlikely(!buffer))
@@ -938,6 +953,7 @@ spi_dv_device(struct scsi_device *sdev)
938 out_free: 953 out_free:
939 kfree(buffer); 954 kfree(buffer);
940 out_put: 955 out_put:
956 spi_dv_in_progress(starget) = 0;
941 scsi_device_put(sdev); 957 scsi_device_put(sdev);
942} 958}
943EXPORT_SYMBOL(spi_dv_device); 959EXPORT_SYMBOL(spi_dv_device);
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
index 302680c0c0de..da180f738477 100644
--- a/include/scsi/scsi_transport_spi.h
+++ b/include/scsi/scsi_transport_spi.h
@@ -53,7 +53,8 @@ struct spi_transport_attrs {
53 unsigned int support_ius; /* support Information Units */ 53 unsigned int support_ius; /* support Information Units */
54 unsigned int support_qas; /* supports quick arbitration and selection */ 54 unsigned int support_qas; /* supports quick arbitration and selection */
55 /* Private Fields */ 55 /* Private Fields */
56 unsigned int dv_pending:1; /* Internal flag */ 56 unsigned int dv_pending:1; /* Internal flag: DV Requested */
57 unsigned int dv_in_progress:1; /* Internal: DV started */
57 struct mutex dv_mutex; /* semaphore to serialise dv */ 58 struct mutex dv_mutex; /* semaphore to serialise dv */
58}; 59};
59 60