aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_transport_spi.c')
-rw-r--r--drivers/scsi/scsi_transport_spi.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index ace49d5bd9c4..9f070f0d0f2b 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -18,7 +18,6 @@
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21#include <linux/config.h>
22#include <linux/ctype.h> 21#include <linux/ctype.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/module.h> 23#include <linux/module.h>
@@ -48,6 +47,7 @@
48 47
49/* Private data accessors (keep these out of the header file) */ 48/* Private data accessors (keep these out of the header file) */
50#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)
51#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)
52 52
53struct spi_internal { 53struct spi_internal {
@@ -241,6 +241,7 @@ static int spi_setup_transport_attrs(struct transport_container *tc,
241 spi_pcomp_en(starget) = 0; 241 spi_pcomp_en(starget) = 0;
242 spi_hold_mcs(starget) = 0; 242 spi_hold_mcs(starget) = 0;
243 spi_dv_pending(starget) = 0; 243 spi_dv_pending(starget) = 0;
244 spi_dv_in_progress(starget) = 0;
244 spi_initial_dv(starget) = 0; 245 spi_initial_dv(starget) = 0;
245 mutex_init(&spi_dv_mutex(starget)); 246 mutex_init(&spi_dv_mutex(starget));
246 247
@@ -831,28 +832,37 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
831 DV_SET(period, spi_min_period(starget)); 832 DV_SET(period, spi_min_period(starget));
832 /* try QAS requests; this should be harmless to set if the 833 /* try QAS requests; this should be harmless to set if the
833 * target supports it */ 834 * target supports it */
834 if (scsi_device_qas(sdev)) 835 if (scsi_device_qas(sdev)) {
835 DV_SET(qas, 1); 836 DV_SET(qas, 1);
836 /* Also try IU transfers */ 837 } else {
837 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 */
838 DV_SET(iu, 1); 843 DV_SET(iu, 1);
839 if (spi_min_period(starget) < 9) { 844 /* Then set the optional parameters */
840 /* This u320 (or u640). Ignore the coupled parameters
841 * like DT and IU, but set the optional ones */
842 DV_SET(rd_strm, 1); 845 DV_SET(rd_strm, 1);
843 DV_SET(wr_flow, 1); 846 DV_SET(wr_flow, 1);
844 DV_SET(rti, 1); 847 DV_SET(rti, 1);
845 if (spi_min_period(starget) == 8) 848 if (spi_min_period(starget) == 8)
846 DV_SET(pcomp_en, 1); 849 DV_SET(pcomp_en, 1);
850 } else {
851 DV_SET(iu, 0);
847 } 852 }
853
848 /* now that we've done all this, actually check the bus 854 /* now that we've done all this, actually check the bus
849 * signal type (if known). Some devices are stupid on 855 * signal type (if known). Some devices are stupid on
850 * 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 */
851 if (i->f->get_signalling) 857 if (i->f->get_signalling)
852 i->f->get_signalling(shost); 858 i->f->get_signalling(shost);
853 if (spi_signalling(shost) == SPI_SIGNAL_SE || 859 if (spi_signalling(shost) == SPI_SIGNAL_SE ||
854 spi_signalling(shost) == SPI_SIGNAL_HVD) 860 spi_signalling(shost) == SPI_SIGNAL_HVD ||
861 !scsi_device_dt(sdev)) {
855 DV_SET(dt, 0); 862 DV_SET(dt, 0);
863 } else {
864 DV_SET(dt, 1);
865 }
856 /* Do the read only INQUIRY tests */ 866 /* Do the read only INQUIRY tests */
857 spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, 867 spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len,
858 spi_dv_device_compare_inquiry); 868 spi_dv_device_compare_inquiry);
@@ -908,6 +918,10 @@ spi_dv_device(struct scsi_device *sdev)
908 if (unlikely(scsi_device_get(sdev))) 918 if (unlikely(scsi_device_get(sdev)))
909 return; 919 return;
910 920
921 if (unlikely(spi_dv_in_progress(starget)))
922 return;
923 spi_dv_in_progress(starget) = 1;
924
911 buffer = kzalloc(len, GFP_KERNEL); 925 buffer = kzalloc(len, GFP_KERNEL);
912 926
913 if (unlikely(!buffer)) 927 if (unlikely(!buffer))
@@ -939,6 +953,7 @@ spi_dv_device(struct scsi_device *sdev)
939 out_free: 953 out_free:
940 kfree(buffer); 954 kfree(buffer);
941 out_put: 955 out_put:
956 spi_dv_in_progress(starget) = 0;
942 scsi_device_put(sdev); 957 scsi_device_put(sdev);
943} 958}
944EXPORT_SYMBOL(spi_dv_device); 959EXPORT_SYMBOL(spi_dv_device);