Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3510

kernel-2.6.18-194.11.1.el5.src.rpm

From: Tomas Henzl <thenzl@redhat.com>
Date: Thu, 15 Oct 2009 12:11:28 +0200
Subject: [scsi] mpt: errata 28 fix on LSI53C1030
Message-id: 4AD6F550.1010700@redhat.com
O-Subject: [RHEL5.5 Patch] mpt: errata 28 fix on LSI53C1030
Bugzilla: 518689
RH-Acked-by: David Milburn <dmilburn@redhat.com>

This is for BZ#518689

We were asked to include a patch for 'errata 28 on LSI53C1030'.

The customer is facing this issue :
"After issuing a "SCSI READ command" to a tape device,
"Read Compare Error" can occur in the data comparison,
and the data doesn't transfer correctly like the
following.
Problem No.1: The received data lengths shorten.
Problem No.2: The received data lengths are correct,
                 but the last two bytes are filled with
                 NULL forcibly
"

>From the reporter :
"However, I don't have a test environment that reproduces
this matter currently.
Therefore, I confirmed only the boot, and the route.
I also checked the source and the fix logic was the same as
RHEL4 that was proven, so I concluded that there was no
problem."

This patch is in RHEL4 for more then a year and is also
in the 'in house' LSI driver.
Kashyap (LSI) accepted this patch and promised now
that they (LSI) will work on upstream posting.

Tomas

diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index fefcaf3..60db8e4 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -787,11 +787,32 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 			 *  precedence!
 			 */
 			sc->result = (DID_OK << 16) | scsi_status;
-			if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
-				/* Have already saved the status and sense data
+			if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
+
+				/*
+				 * For an Errata on LSI53C1030
+				 * When the length of request data
+				 * and transfer data are different
+				 * with result of command (READ or VERIFY),
+				 * DID_SOFT_ERROR is set.
 				 */
-				;
-			} else {
+				if (ioc->bus_type == SPI) {
+					if (pScsiReq->CDB[0] == READ_6  ||
+					    pScsiReq->CDB[0] == READ_10 ||
+					    pScsiReq->CDB[0] == READ_12 ||
+					    pScsiReq->CDB[0] == READ_16 ||
+					    pScsiReq->CDB[0] == VERIFY  ||
+					    pScsiReq->CDB[0] == VERIFY_16) {
+						if (sc->request_bufflen !=
+						    xfer_cnt) {
+						    sc->result = DID_SOFT_ERROR << 16;
+						    printk(KERN_WARNING "Errata"
+						    "on LSI53C1030 occurred. sc->request_bufflen=0x%02x, "
+						    "xfer_cnt=0x%02x\n", sc->request_bufflen, xfer_cnt);
+						}
+					}
+				}
+
 				if (xfer_cnt < sc->underflow) {
 					if (scsi_status == SAM_STAT_BUSY)
 						sc->result = SAM_STAT_BUSY;
@@ -831,6 +852,44 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 			if (scsi_state == 0) {
 				;
 			} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
+
+				/*
+				 * For potential trouble on LSI53C1030. (date:2007.xx.)
+				 * It is checked whether the length of request data is equal to
+				 * the length of transfer and residual.
+				 * MEDIUM_ERROR is set by incorrect data.
+				 */
+				if (ioc->bus_type == SPI){
+					if (sc->sense_buffer[2] & 0x20) {
+					    u32	 difftransfer;
+					    difftransfer =
+					    sc->sense_buffer[3] << 24 |
+					    sc->sense_buffer[4] << 16 |
+					    sc->sense_buffer[5] << 8 |
+					    sc->sense_buffer[6];
+					    if ((sc->sense_buffer[3] & 0x80) == 0x80) {
+						if (sc->request_bufflen != xfer_cnt) {
+						    sc->sense_buffer[2] = MEDIUM_ERROR;
+						    sc->sense_buffer[12] = 0xff;
+						    sc->sense_buffer[13] = 0xff;
+						    printk(KERN_WARNING "Errata on "
+						    "LSI53C1030 occurred. sc->request_bufflen=0x%02x,"
+						    "xfer_cnt=0x%02x\n" ,sc->request_bufflen, xfer_cnt);
+						}
+					} else {
+						if (sc->request_bufflen != xfer_cnt + difftransfer) {
+						    sc->sense_buffer[2] = MEDIUM_ERROR;
+						    sc->sense_buffer[12] = 0xff;
+						    sc->sense_buffer[13] = 0xff;
+						    printk(KERN_WARNING "Errata on "
+						    "LSI53C1030 occurred. sc->request_bufflen=0x%02x,"
+						    " xfer_cnt=0x%02x, difftransfer=0x%02x\n",
+						    sc->request_bufflen , xfer_cnt, difftransfer);
+						}
+						}
+					}
+				}
+
 				/*
 				 * If running against circa 200003dd 909 MPT f/w,
 				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL