]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
add scsi patch to stable queue
authorChris Wright <chrisw@sous-sol.org>
Thu, 27 Sep 2007 23:39:33 +0000 (16:39 -0700)
committerChris Wright <chrisw@sous-sol.org>
Thu, 27 Sep 2007 23:39:33 +0000 (16:39 -0700)
queue-2.6.22/scsi_transport_spi-fix-domain-validation-failure-from-incorrect-width-setting.patch [new file with mode: 0644]
queue-2.6.22/series [new file with mode: 0644]

diff --git a/queue-2.6.22/scsi_transport_spi-fix-domain-validation-failure-from-incorrect-width-setting.patch b/queue-2.6.22/scsi_transport_spi-fix-domain-validation-failure-from-incorrect-width-setting.patch
new file mode 100644 (file)
index 0000000..8eb8bca
--- /dev/null
@@ -0,0 +1,111 @@
+From stable-bounces@linux.kernel.org  Thu Sep 27 15:52:26 2007
+From: James Bottomley <James.Bottomley@SteelEye.com>
+To: stable@kernel.org
+Date: Thu, 27 Sep 2007 18:51:57 -0400
+Message-Id: <1190933517.5392.27.camel@localhost.localdomain>
+Subject: [SCSI] scsi_transport_spi: fix domain validation failure from incorrect width setting
+
+Domain Validation in the SPI transport class is failing on boxes with
+damaged cables (and failing to the extent that the box hangs).  The
+problem is that the first test it does is a cable integrity test for
+wide transfers and if this fails, it turns the wide bit off.  The
+problem is that the next set of tests it does turns wide back on
+again, with the result that it runs through the entirety of DV with a
+known bad setting and then hangs the system.
+
+The attached patch fixes the problem by physically nailing the wide
+setting to what it deduces it should be for the whole of Domain
+Validation.
+
+Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
+---
+This one's a long standing bug which can cause a machine hang on certain
+boxes with cabling problems, it just went upstream as commit
+
+2302827c95fe0f441025acd5133e532d2eef322b
+
+ drivers/scsi/scsi_transport_spi.c |   28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+--- linux-2.6.22.9.orig/drivers/scsi/scsi_transport_spi.c
++++ linux-2.6.22.9/drivers/scsi/scsi_transport_spi.c
+@@ -787,10 +787,12 @@ spi_dv_device_internal(struct scsi_devic
+       struct scsi_target *starget = sdev->sdev_target;
+       struct Scsi_Host *shost = sdev->host;
+       int len = sdev->inquiry_len;
++      int min_period = spi_min_period(starget);
++      int max_width = spi_max_width(starget);
+       /* first set us up for narrow async */
+       DV_SET(offset, 0);
+       DV_SET(width, 0);
+-      
++
+       if (spi_dv_device_compare_inquiry(sdev, buffer, buffer, DV_LOOPS)
+           != SPI_COMPARE_SUCCESS) {
+               starget_printk(KERN_ERR, starget, "Domain Validation Initial Inquiry Failed\n");
+@@ -798,9 +800,13 @@ spi_dv_device_internal(struct scsi_devic
+               return;
+       }
++      if (!scsi_device_wide(sdev)) {
++              spi_max_width(starget) = 0;
++              max_width = 0;
++      }
++
+       /* test width */
+-      if (i->f->set_width && spi_max_width(starget) &&
+-          scsi_device_wide(sdev)) {
++      if (i->f->set_width && max_width) {
+               i->f->set_width(starget, 1);
+               if (spi_dv_device_compare_inquiry(sdev, buffer,
+@@ -809,6 +815,11 @@ spi_dv_device_internal(struct scsi_devic
+                   != SPI_COMPARE_SUCCESS) {
+                       starget_printk(KERN_ERR, starget, "Wide Transfers Fail\n");
+                       i->f->set_width(starget, 0);
++                      /* Make sure we don't force wide back on by asking
++                       * for a transfer period that requires it */
++                      max_width = 0;
++                      if (min_period < 10)
++                              min_period = 10;
+               }
+       }
+@@ -828,7 +839,8 @@ spi_dv_device_internal(struct scsi_devic
+       /* now set up to the maximum */
+       DV_SET(offset, spi_max_offset(starget));
+-      DV_SET(period, spi_min_period(starget));
++      DV_SET(period, min_period);
++
+       /* try QAS requests; this should be harmless to set if the
+        * target supports it */
+       if (scsi_device_qas(sdev)) {
+@@ -837,14 +849,14 @@ spi_dv_device_internal(struct scsi_devic
+               DV_SET(qas, 0);
+       }
+-      if (scsi_device_ius(sdev) && spi_min_period(starget) < 9) {
++      if (scsi_device_ius(sdev) && min_period < 9) {
+               /* This u320 (or u640). Set IU transfers */
+               DV_SET(iu, 1);
+               /* Then set the optional parameters */
+               DV_SET(rd_strm, 1);
+               DV_SET(wr_flow, 1);
+               DV_SET(rti, 1);
+-              if (spi_min_period(starget) == 8)
++              if (min_period == 8)
+                       DV_SET(pcomp_en, 1);
+       } else {
+               DV_SET(iu, 0);
+@@ -862,6 +874,10 @@ spi_dv_device_internal(struct scsi_devic
+       } else {
+               DV_SET(dt, 1);
+       }
++      /* set width last because it will pull all the other
++       * parameters down to required values */
++      DV_SET(width, max_width);
++
+       /* Do the read only INQUIRY tests */
+       spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len,
+                      spi_dv_device_compare_inquiry);
diff --git a/queue-2.6.22/series b/queue-2.6.22/series
new file mode 100644 (file)
index 0000000..309fd33
--- /dev/null
@@ -0,0 +1 @@
+scsi_transport_spi-fix-domain-validation-failure-from-incorrect-width-setting.patch