Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b53b392 authored by Kashyap, Desai's avatar Kashyap, Desai Committed by James Bottomley
Browse files

[SCSI] mptspi: Fix for incorrect data underrun errata



Errata:
Certain conditions on the scsi bus may casue the 53C1030 to incorrectly signal
a SCSI_DATA_UNDERRUN to the host.

Workaround 1:
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.

Workaround 2:
For potential trouble on LSI53C1030. 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.

Signed-off-by: default avatarKashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent e39e145d
Loading
Loading
Loading
Loading
+81 −5
Original line number Diff line number Diff line
@@ -792,11 +792,36 @@ 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 (scsi_bufflen(sc) !=
							xfer_cnt) {
							sc->result =
							DID_SOFT_ERROR << 16;
						    printk(KERN_WARNING "Errata"
						    "on LSI53C1030 occurred."
						    "sc->req_bufflen=0x%02x,"
						    "xfer_cnt=0x%02x\n",
						    scsi_bufflen(sc),
						    xfer_cnt);
						}
					}
				}

				if (xfer_cnt < sc->underflow) {
					if (scsi_status == SAM_STAT_BUSY)
						sc->result = SAM_STAT_BUSY;
@@ -835,7 +860,58 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
			sc->result = (DID_OK << 16) | scsi_status;
			if (scsi_state == 0) {
				;
			} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
			} 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) &&
					(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) && (scsi_bufflen(sc)
						!= 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->req_bufflen=0x%02x,"
						"xfer_cnt=0x%02x\n" ,
						scsi_bufflen(sc),
						xfer_cnt);
					}
					if (((sc->sense_buffer[3] & 0x80)
						!= 0x80) &&
						(scsi_bufflen(sc) !=
						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->req_bufflen=0x%02x,"
						" xfer_cnt=0x%02x,"
						"difftransfer=0x%02x\n",
						scsi_bufflen(sc),
						xfer_cnt,
						difftransfer);
					}
				}

				/*
				 * If running against circa 200003dd 909 MPT f/w,
				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL