[SCSI] SPI DV: be more conservative about echo buffer usage
authorJames Bottomley <James.Bottomley@steeleye.com>
Mon, 28 Nov 2005 21:41:58 +0000 (15:41 -0600)
committerJames Bottomley <jejb@mulgrave.(none)>
Thu, 1 Dec 2005 21:59:43 +0000 (15:59 -0600)
Some SCSI devices apparently get very confused if we try to use the
echo buffer on a non-DT negotiated bus (this mirrors the problems of
using PPR on non-LVD for some devices).  The fix is to be far more
conservative about when we use an echo buffer.  With this patch, we'll
now see what parameters are negotiated by the read only test, and only
look for an echo buffer if DT is negotiated.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/scsi_transport_spi.c

index 718a2bc4ed5e6fcbe777637661bdc08769691c5e..38a53b5f9e9a53e8cbc06a545f87070e4989a248 100644 (file)
@@ -812,12 +812,10 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
        if (!scsi_device_sync(sdev) && !scsi_device_dt(sdev))
                return;
 
-       /* see if the device has an echo buffer.  If it does we can
-        * do the SPI pattern write tests */
-
-       len = 0;
-       if (scsi_device_dt(sdev))
-               len = spi_dv_device_get_echo_buffer(sdev, buffer);
+       /* len == -1 is the signal that we need to ascertain the
+        * presence of an echo buffer before trying to use it.  len ==
+        * 0 means we don't have an echo buffer */
+       len = -1;
 
  retry:
 
@@ -840,11 +838,23 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
                if (spi_min_period(starget) == 8)
                        DV_SET(pcomp_en, 1);
        }
+       /* Do the read only INQUIRY tests */
+       spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len,
+                      spi_dv_device_compare_inquiry);
+       /* See if we actually managed to negotiate and sustain DT */
+       if (i->f->get_dt)
+               i->f->get_dt(starget);
+
+       /* see if the device has an echo buffer.  If it does we can do
+        * the SPI pattern write tests.  Because of some broken
+        * devices, we *only* try this on a device that has actually
+        * negotiated DT */
+
+       if (len == -1 && spi_dt(starget))
+               len = spi_dv_device_get_echo_buffer(sdev, buffer);
 
-       if (len == 0) {
+       if (len <= 0) {
                starget_printk(KERN_INFO, starget, "Domain Validation skipping write tests\n");
-               spi_dv_retrain(sdev, buffer, buffer + len,
-                              spi_dv_device_compare_inquiry);
                return;
        }