aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptscsih.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-10-07 01:57:40 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-29 13:03:24 -0400
commit9b53b39243cf23a0b68eaa16c37ce16eada69a46 (patch)
tree3802e17dde9b8329b342f781b8e5b238472d7c38 /drivers/message/fusion/mptscsih.c
parente39e145dfb78d4e20d89139d2576306b4279c126 (diff)
[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: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r--drivers/message/fusion/mptscsih.c86
1 files changed, 81 insertions, 5 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index c29578614504..f68ec48a881e 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -792,11 +792,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
792 * precedence! 792 * precedence!
793 */ 793 */
794 sc->result = (DID_OK << 16) | scsi_status; 794 sc->result = (DID_OK << 16) | scsi_status;
795 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { 795 if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
796 /* Have already saved the status and sense data 796
797 /*
798 * For an Errata on LSI53C1030
799 * When the length of request data
800 * and transfer data are different
801 * with result of command (READ or VERIFY),
802 * DID_SOFT_ERROR is set.
797 */ 803 */
798 ; 804 if (ioc->bus_type == SPI) {
799 } else { 805 if (pScsiReq->CDB[0] == READ_6 ||
806 pScsiReq->CDB[0] == READ_10 ||
807 pScsiReq->CDB[0] == READ_12 ||
808 pScsiReq->CDB[0] == READ_16 ||
809 pScsiReq->CDB[0] == VERIFY ||
810 pScsiReq->CDB[0] == VERIFY_16) {
811 if (scsi_bufflen(sc) !=
812 xfer_cnt) {
813 sc->result =
814 DID_SOFT_ERROR << 16;
815 printk(KERN_WARNING "Errata"
816 "on LSI53C1030 occurred."
817 "sc->req_bufflen=0x%02x,"
818 "xfer_cnt=0x%02x\n",
819 scsi_bufflen(sc),
820 xfer_cnt);
821 }
822 }
823 }
824
800 if (xfer_cnt < sc->underflow) { 825 if (xfer_cnt < sc->underflow) {
801 if (scsi_status == SAM_STAT_BUSY) 826 if (scsi_status == SAM_STAT_BUSY)
802 sc->result = SAM_STAT_BUSY; 827 sc->result = SAM_STAT_BUSY;
@@ -835,7 +860,58 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
835 sc->result = (DID_OK << 16) | scsi_status; 860 sc->result = (DID_OK << 16) | scsi_status;
836 if (scsi_state == 0) { 861 if (scsi_state == 0) {
837 ; 862 ;
838 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { 863 } else if (scsi_state &
864 MPI_SCSI_STATE_AUTOSENSE_VALID) {
865
866 /*
867 * For potential trouble on LSI53C1030.
868 * (date:2007.xx.)
869 * It is checked whether the length of
870 * request data is equal to
871 * the length of transfer and residual.
872 * MEDIUM_ERROR is set by incorrect data.
873 */
874 if ((ioc->bus_type == SPI) &&
875 (sc->sense_buffer[2] & 0x20)) {
876 u32 difftransfer;
877 difftransfer =
878 sc->sense_buffer[3] << 24 |
879 sc->sense_buffer[4] << 16 |
880 sc->sense_buffer[5] << 8 |
881 sc->sense_buffer[6];
882 if (((sc->sense_buffer[3] & 0x80) ==
883 0x80) && (scsi_bufflen(sc)
884 != xfer_cnt)) {
885 sc->sense_buffer[2] =
886 MEDIUM_ERROR;
887 sc->sense_buffer[12] = 0xff;
888 sc->sense_buffer[13] = 0xff;
889 printk(KERN_WARNING"Errata"
890 "on LSI53C1030 occurred."
891 "sc->req_bufflen=0x%02x,"
892 "xfer_cnt=0x%02x\n" ,
893 scsi_bufflen(sc),
894 xfer_cnt);
895 }
896 if (((sc->sense_buffer[3] & 0x80)
897 != 0x80) &&
898 (scsi_bufflen(sc) !=
899 xfer_cnt + difftransfer)) {
900 sc->sense_buffer[2] =
901 MEDIUM_ERROR;
902 sc->sense_buffer[12] = 0xff;
903 sc->sense_buffer[13] = 0xff;
904 printk(KERN_WARNING
905 "Errata on LSI53C1030 occurred"
906 "sc->req_bufflen=0x%02x,"
907 " xfer_cnt=0x%02x,"
908 "difftransfer=0x%02x\n",
909 scsi_bufflen(sc),
910 xfer_cnt,
911 difftransfer);
912 }
913 }
914
839 /* 915 /*
840 * If running against circa 200003dd 909 MPT f/w, 916 * If running against circa 200003dd 909 MPT f/w,
841 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL 917 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL