diff options
| -rw-r--r-- | drivers/scsi/scsi_transport_spi.c | 30 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_spi.h | 3 |
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 29a9a53cdd1..9f070f0d0f2 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 | ||
| 52 | struct spi_internal { | 53 | struct 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 | } |
| 943 | EXPORT_SYMBOL(spi_dv_device); | 959 | EXPORT_SYMBOL(spi_dv_device); |
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h index 302680c0c0d..da180f73847 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 | ||
