diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/message/fusion/mptscsih.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 107 |
1 files changed, 97 insertions, 10 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index c29578614504..6796597dcee0 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | #include <linux/module.h> | 47 | #include <linux/module.h> |
48 | #include <linux/kernel.h> | 48 | #include <linux/kernel.h> |
49 | #include <linux/slab.h> | ||
49 | #include <linux/init.h> | 50 | #include <linux/init.h> |
50 | #include <linux/errno.h> | 51 | #include <linux/errno.h> |
51 | #include <linux/kdev_t.h> | 52 | #include <linux/kdev_t.h> |
@@ -792,11 +793,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
792 | * precedence! | 793 | * precedence! |
793 | */ | 794 | */ |
794 | sc->result = (DID_OK << 16) | scsi_status; | 795 | sc->result = (DID_OK << 16) | scsi_status; |
795 | if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { | 796 | if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) { |
796 | /* Have already saved the status and sense data | 797 | |
798 | /* | ||
799 | * For an Errata on LSI53C1030 | ||
800 | * When the length of request data | ||
801 | * and transfer data are different | ||
802 | * with result of command (READ or VERIFY), | ||
803 | * DID_SOFT_ERROR is set. | ||
797 | */ | 804 | */ |
798 | ; | 805 | if (ioc->bus_type == SPI) { |
799 | } else { | 806 | if (pScsiReq->CDB[0] == READ_6 || |
807 | pScsiReq->CDB[0] == READ_10 || | ||
808 | pScsiReq->CDB[0] == READ_12 || | ||
809 | pScsiReq->CDB[0] == READ_16 || | ||
810 | pScsiReq->CDB[0] == VERIFY || | ||
811 | pScsiReq->CDB[0] == VERIFY_16) { | ||
812 | if (scsi_bufflen(sc) != | ||
813 | xfer_cnt) { | ||
814 | sc->result = | ||
815 | DID_SOFT_ERROR << 16; | ||
816 | printk(KERN_WARNING "Errata" | ||
817 | "on LSI53C1030 occurred." | ||
818 | "sc->req_bufflen=0x%02x," | ||
819 | "xfer_cnt=0x%02x\n", | ||
820 | scsi_bufflen(sc), | ||
821 | xfer_cnt); | ||
822 | } | ||
823 | } | ||
824 | } | ||
825 | |||
800 | if (xfer_cnt < sc->underflow) { | 826 | if (xfer_cnt < sc->underflow) { |
801 | if (scsi_status == SAM_STAT_BUSY) | 827 | if (scsi_status == SAM_STAT_BUSY) |
802 | sc->result = SAM_STAT_BUSY; | 828 | sc->result = SAM_STAT_BUSY; |
@@ -835,7 +861,58 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
835 | sc->result = (DID_OK << 16) | scsi_status; | 861 | sc->result = (DID_OK << 16) | scsi_status; |
836 | if (scsi_state == 0) { | 862 | if (scsi_state == 0) { |
837 | ; | 863 | ; |
838 | } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { | 864 | } else if (scsi_state & |
865 | MPI_SCSI_STATE_AUTOSENSE_VALID) { | ||
866 | |||
867 | /* | ||
868 | * For potential trouble on LSI53C1030. | ||
869 | * (date:2007.xx.) | ||
870 | * It is checked whether the length of | ||
871 | * request data is equal to | ||
872 | * the length of transfer and residual. | ||
873 | * MEDIUM_ERROR is set by incorrect data. | ||
874 | */ | ||
875 | if ((ioc->bus_type == SPI) && | ||
876 | (sc->sense_buffer[2] & 0x20)) { | ||
877 | u32 difftransfer; | ||
878 | difftransfer = | ||
879 | sc->sense_buffer[3] << 24 | | ||
880 | sc->sense_buffer[4] << 16 | | ||
881 | sc->sense_buffer[5] << 8 | | ||
882 | sc->sense_buffer[6]; | ||
883 | if (((sc->sense_buffer[3] & 0x80) == | ||
884 | 0x80) && (scsi_bufflen(sc) | ||
885 | != xfer_cnt)) { | ||
886 | sc->sense_buffer[2] = | ||
887 | MEDIUM_ERROR; | ||
888 | sc->sense_buffer[12] = 0xff; | ||
889 | sc->sense_buffer[13] = 0xff; | ||
890 | printk(KERN_WARNING"Errata" | ||
891 | "on LSI53C1030 occurred." | ||
892 | "sc->req_bufflen=0x%02x," | ||
893 | "xfer_cnt=0x%02x\n" , | ||
894 | scsi_bufflen(sc), | ||
895 | xfer_cnt); | ||
896 | } | ||
897 | if (((sc->sense_buffer[3] & 0x80) | ||
898 | != 0x80) && | ||
899 | (scsi_bufflen(sc) != | ||
900 | xfer_cnt + difftransfer)) { | ||
901 | sc->sense_buffer[2] = | ||
902 | MEDIUM_ERROR; | ||
903 | sc->sense_buffer[12] = 0xff; | ||
904 | sc->sense_buffer[13] = 0xff; | ||
905 | printk(KERN_WARNING | ||
906 | "Errata on LSI53C1030 occurred" | ||
907 | "sc->req_bufflen=0x%02x," | ||
908 | " xfer_cnt=0x%02x," | ||
909 | "difftransfer=0x%02x\n", | ||
910 | scsi_bufflen(sc), | ||
911 | xfer_cnt, | ||
912 | difftransfer); | ||
913 | } | ||
914 | } | ||
915 | |||
839 | /* | 916 | /* |
840 | * If running against circa 200003dd 909 MPT f/w, | 917 | * If running against circa 200003dd 909 MPT f/w, |
841 | * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL | 918 | * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL |
@@ -1362,9 +1439,14 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1362 | && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) | 1439 | && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) |
1363 | && (SCpnt->device->tagged_supported)) { | 1440 | && (SCpnt->device->tagged_supported)) { |
1364 | scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; | 1441 | scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; |
1365 | } else { | 1442 | if (SCpnt->request && SCpnt->request->ioprio) { |
1443 | if (((SCpnt->request->ioprio & 0x7) == 1) || | ||
1444 | !(SCpnt->request->ioprio & 0x7)) | ||
1445 | scsictl |= MPI_SCSIIO_CONTROL_HEADOFQ; | ||
1446 | } | ||
1447 | } else | ||
1366 | scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED; | 1448 | scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED; |
1367 | } | 1449 | |
1368 | 1450 | ||
1369 | /* Use the above information to set up the message frame | 1451 | /* Use the above information to set up the message frame |
1370 | */ | 1452 | */ |
@@ -1720,7 +1802,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1720 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: " | 1802 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: " |
1721 | "Command not in the active list! (sc=%p)\n", ioc->name, | 1803 | "Command not in the active list! (sc=%p)\n", ioc->name, |
1722 | SCpnt)); | 1804 | SCpnt)); |
1723 | retval = 0; | 1805 | retval = SUCCESS; |
1724 | goto out; | 1806 | goto out; |
1725 | } | 1807 | } |
1726 | 1808 | ||
@@ -2275,11 +2357,12 @@ mptscsih_slave_destroy(struct scsi_device *sdev) | |||
2275 | * mptscsih_change_queue_depth - This function will set a devices queue depth | 2357 | * mptscsih_change_queue_depth - This function will set a devices queue depth |
2276 | * @sdev: per scsi_device pointer | 2358 | * @sdev: per scsi_device pointer |
2277 | * @qdepth: requested queue depth | 2359 | * @qdepth: requested queue depth |
2360 | * @reason: calling context | ||
2278 | * | 2361 | * |
2279 | * Adding support for new 'change_queue_depth' api. | 2362 | * Adding support for new 'change_queue_depth' api. |
2280 | */ | 2363 | */ |
2281 | int | 2364 | int |
2282 | mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | 2365 | mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason) |
2283 | { | 2366 | { |
2284 | MPT_SCSI_HOST *hd = shost_priv(sdev->host); | 2367 | MPT_SCSI_HOST *hd = shost_priv(sdev->host); |
2285 | VirtTarget *vtarget; | 2368 | VirtTarget *vtarget; |
@@ -2291,6 +2374,9 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | |||
2291 | starget = scsi_target(sdev); | 2374 | starget = scsi_target(sdev); |
2292 | vtarget = starget->hostdata; | 2375 | vtarget = starget->hostdata; |
2293 | 2376 | ||
2377 | if (reason != SCSI_QDEPTH_DEFAULT) | ||
2378 | return -EOPNOTSUPP; | ||
2379 | |||
2294 | if (ioc->bus_type == SPI) { | 2380 | if (ioc->bus_type == SPI) { |
2295 | if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) | 2381 | if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) |
2296 | max_depth = 1; | 2382 | max_depth = 1; |
@@ -2357,7 +2443,8 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2357 | ioc->name, vtarget->negoFlags, vtarget->maxOffset, | 2443 | ioc->name, vtarget->negoFlags, vtarget->maxOffset, |
2358 | vtarget->minSyncFactor)); | 2444 | vtarget->minSyncFactor)); |
2359 | 2445 | ||
2360 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); | 2446 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH, |
2447 | SCSI_QDEPTH_DEFAULT); | ||
2361 | dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT | 2448 | dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT |
2362 | "tagged %d, simple %d, ordered %d\n", | 2449 | "tagged %d, simple %d, ordered %d\n", |
2363 | ioc->name,sdev->tagged_supported, sdev->simple_tags, | 2450 | ioc->name,sdev->tagged_supported, sdev->simple_tags, |