diff options
Diffstat (limited to 'drivers/scsi/scsi_transport_spi.c')
-rw-r--r-- | drivers/scsi/scsi_transport_spi.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 6f56f8750635..4df21c92ff1e 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
@@ -787,10 +787,12 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
787 | struct scsi_target *starget = sdev->sdev_target; | 787 | struct scsi_target *starget = sdev->sdev_target; |
788 | struct Scsi_Host *shost = sdev->host; | 788 | struct Scsi_Host *shost = sdev->host; |
789 | int len = sdev->inquiry_len; | 789 | int len = sdev->inquiry_len; |
790 | int min_period = spi_min_period(starget); | ||
791 | int max_width = spi_max_width(starget); | ||
790 | /* first set us up for narrow async */ | 792 | /* first set us up for narrow async */ |
791 | DV_SET(offset, 0); | 793 | DV_SET(offset, 0); |
792 | DV_SET(width, 0); | 794 | DV_SET(width, 0); |
793 | 795 | ||
794 | if (spi_dv_device_compare_inquiry(sdev, buffer, buffer, DV_LOOPS) | 796 | if (spi_dv_device_compare_inquiry(sdev, buffer, buffer, DV_LOOPS) |
795 | != SPI_COMPARE_SUCCESS) { | 797 | != SPI_COMPARE_SUCCESS) { |
796 | starget_printk(KERN_ERR, starget, "Domain Validation Initial Inquiry Failed\n"); | 798 | starget_printk(KERN_ERR, starget, "Domain Validation Initial Inquiry Failed\n"); |
@@ -798,9 +800,13 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
798 | return; | 800 | return; |
799 | } | 801 | } |
800 | 802 | ||
803 | if (!scsi_device_wide(sdev)) { | ||
804 | spi_max_width(starget) = 0; | ||
805 | max_width = 0; | ||
806 | } | ||
807 | |||
801 | /* test width */ | 808 | /* test width */ |
802 | if (i->f->set_width && spi_max_width(starget) && | 809 | if (i->f->set_width && max_width) { |
803 | scsi_device_wide(sdev)) { | ||
804 | i->f->set_width(starget, 1); | 810 | i->f->set_width(starget, 1); |
805 | 811 | ||
806 | if (spi_dv_device_compare_inquiry(sdev, buffer, | 812 | if (spi_dv_device_compare_inquiry(sdev, buffer, |
@@ -809,6 +815,11 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
809 | != SPI_COMPARE_SUCCESS) { | 815 | != SPI_COMPARE_SUCCESS) { |
810 | starget_printk(KERN_ERR, starget, "Wide Transfers Fail\n"); | 816 | starget_printk(KERN_ERR, starget, "Wide Transfers Fail\n"); |
811 | i->f->set_width(starget, 0); | 817 | i->f->set_width(starget, 0); |
818 | /* Make sure we don't force wide back on by asking | ||
819 | * for a transfer period that requires it */ | ||
820 | max_width = 0; | ||
821 | if (min_period < 10) | ||
822 | min_period = 10; | ||
812 | } | 823 | } |
813 | } | 824 | } |
814 | 825 | ||
@@ -828,7 +839,8 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
828 | 839 | ||
829 | /* now set up to the maximum */ | 840 | /* now set up to the maximum */ |
830 | DV_SET(offset, spi_max_offset(starget)); | 841 | DV_SET(offset, spi_max_offset(starget)); |
831 | DV_SET(period, spi_min_period(starget)); | 842 | DV_SET(period, min_period); |
843 | |||
832 | /* try QAS requests; this should be harmless to set if the | 844 | /* try QAS requests; this should be harmless to set if the |
833 | * target supports it */ | 845 | * target supports it */ |
834 | if (scsi_device_qas(sdev)) { | 846 | if (scsi_device_qas(sdev)) { |
@@ -837,14 +849,14 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
837 | DV_SET(qas, 0); | 849 | DV_SET(qas, 0); |
838 | } | 850 | } |
839 | 851 | ||
840 | if (scsi_device_ius(sdev) && spi_min_period(starget) < 9) { | 852 | if (scsi_device_ius(sdev) && min_period < 9) { |
841 | /* This u320 (or u640). Set IU transfers */ | 853 | /* This u320 (or u640). Set IU transfers */ |
842 | DV_SET(iu, 1); | 854 | DV_SET(iu, 1); |
843 | /* Then set the optional parameters */ | 855 | /* Then set the optional parameters */ |
844 | DV_SET(rd_strm, 1); | 856 | DV_SET(rd_strm, 1); |
845 | DV_SET(wr_flow, 1); | 857 | DV_SET(wr_flow, 1); |
846 | DV_SET(rti, 1); | 858 | DV_SET(rti, 1); |
847 | if (spi_min_period(starget) == 8) | 859 | if (min_period == 8) |
848 | DV_SET(pcomp_en, 1); | 860 | DV_SET(pcomp_en, 1); |
849 | } else { | 861 | } else { |
850 | DV_SET(iu, 0); | 862 | DV_SET(iu, 0); |
@@ -862,6 +874,10 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) | |||
862 | } else { | 874 | } else { |
863 | DV_SET(dt, 1); | 875 | DV_SET(dt, 1); |
864 | } | 876 | } |
877 | /* set width last because it will pull all the other | ||
878 | * parameters down to required values */ | ||
879 | DV_SET(width, max_width); | ||
880 | |||
865 | /* Do the read only INQUIRY tests */ | 881 | /* Do the read only INQUIRY tests */ |
866 | spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, | 882 | spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, |
867 | spi_dv_device_compare_inquiry); | 883 | spi_dv_device_compare_inquiry); |