From 8e56be54b4e360f34aa034db01fdcc7bc8784f75 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Thu, 27 Sep 2007 16:39:33 -0700 Subject: [PATCH] add scsi patch to stable queue --- ...failure-from-incorrect-width-setting.patch | 111 ++++++++++++++++++ queue-2.6.22/series | 1 + 2 files changed, 112 insertions(+) create mode 100644 queue-2.6.22/scsi_transport_spi-fix-domain-validation-failure-from-incorrect-width-setting.patch create mode 100644 queue-2.6.22/series 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 index 00000000000..8eb8bcaf0b5 --- /dev/null +++ b/queue-2.6.22/scsi_transport_spi-fix-domain-validation-failure-from-incorrect-width-setting.patch @@ -0,0 +1,111 @@ +From stable-bounces@linux.kernel.org Thu Sep 27 15:52:26 2007 +From: James Bottomley +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 +--- +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 index 00000000000..309fd33d796 --- /dev/null +++ b/queue-2.6.22/series @@ -0,0 +1 @@ +scsi_transport_spi-fix-domain-validation-failure-from-incorrect-width-setting.patch -- 2.47.3