aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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