diff options
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 997 |
1 files changed, 352 insertions, 645 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index f0cca3ea93b2..c417ae0b5fe6 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. | 4 | * running LSI Logic Fusion MPT (Message Passing Technology) firmware. |
5 | * | 5 | * |
6 | * Copyright (c) 1999-2007 LSI Logic Corporation | 6 | * Copyright (c) 1999-2007 LSI Logic Corporation |
7 | * (mailto:mpt_linux_developer@lsil.com) | 7 | * (mailto:mpt_linux_developer@lsi.com) |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 10 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -79,43 +79,6 @@ MODULE_LICENSE("GPL"); | |||
79 | MODULE_VERSION(my_VERSION); | 79 | MODULE_VERSION(my_VERSION); |
80 | 80 | ||
81 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 81 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
82 | |||
83 | typedef struct _BIG_SENSE_BUF { | ||
84 | u8 data[MPT_SENSE_BUFFER_ALLOC]; | ||
85 | } BIG_SENSE_BUF; | ||
86 | |||
87 | #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */ | ||
88 | #define MPT_SCANDV_DID_RESET (0x00000001) | ||
89 | #define MPT_SCANDV_SENSE (0x00000002) | ||
90 | #define MPT_SCANDV_SOME_ERROR (0x00000004) | ||
91 | #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008) | ||
92 | #define MPT_SCANDV_ISSUE_SENSE (0x00000010) | ||
93 | #define MPT_SCANDV_FALLBACK (0x00000020) | ||
94 | |||
95 | #define MPT_SCANDV_MAX_RETRIES (10) | ||
96 | |||
97 | #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ | ||
98 | #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ | ||
99 | #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */ | ||
100 | #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */ | ||
101 | #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */ | ||
102 | #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ | ||
103 | #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ | ||
104 | |||
105 | typedef struct _internal_cmd { | ||
106 | char *data; /* data pointer */ | ||
107 | dma_addr_t data_dma; /* data dma address */ | ||
108 | int size; /* transfer size */ | ||
109 | u8 cmd; /* SCSI Op Code */ | ||
110 | u8 bus; /* bus number */ | ||
111 | u8 id; /* SCSI ID (virtual) */ | ||
112 | u8 lun; | ||
113 | u8 flags; /* Bit Field - See above */ | ||
114 | u8 physDiskNum; /* Phys disk number, -1 else */ | ||
115 | u8 rsvd2; | ||
116 | u8 rsvd; | ||
117 | } INTERNAL_CMD; | ||
118 | |||
119 | /* | 82 | /* |
120 | * Other private/forward protos... | 83 | * Other private/forward protos... |
121 | */ | 84 | */ |
@@ -131,14 +94,11 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); | |||
131 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); | 94 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); |
132 | static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); | 95 | static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); |
133 | 96 | ||
134 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | 97 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); |
135 | 98 | ||
136 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 99 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
137 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | 100 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); |
138 | 101 | ||
139 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); | ||
140 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); | ||
141 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); | ||
142 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); | 102 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); |
143 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); | 103 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); |
144 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); | 104 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); |
@@ -517,16 +477,100 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, | |||
517 | 477 | ||
518 | SEPMsg = (SEPRequest_t *)mf; | 478 | SEPMsg = (SEPRequest_t *)mf; |
519 | SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; | 479 | SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; |
520 | SEPMsg->Bus = vtarget->bus_id; | 480 | SEPMsg->Bus = vtarget->channel; |
521 | SEPMsg->TargetID = vtarget->target_id; | 481 | SEPMsg->TargetID = vtarget->id; |
522 | SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; | 482 | SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; |
523 | SEPMsg->SlotStatus = SlotStatus; | 483 | SEPMsg->SlotStatus = SlotStatus; |
524 | devtverboseprintk((MYIOC_s_WARN_FMT | 484 | devtverboseprintk((MYIOC_s_WARN_FMT |
525 | "Sending SEP cmd=%x id=%d bus=%d\n", | 485 | "Sending SEP cmd=%x channel=%d id=%d\n", |
526 | ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus)); | 486 | ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID)); |
527 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | 487 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); |
528 | } | 488 | } |
529 | 489 | ||
490 | #ifdef MPT_DEBUG_REPLY | ||
491 | /** | ||
492 | * mptscsih_iocstatus_info_scsiio - IOCSTATUS information for SCSIIO | ||
493 | * @ioc: Pointer to MPT_ADAPTER structure | ||
494 | * @ioc_status: U32 IOCStatus word from IOC | ||
495 | * @scsi_status: U8 sam status from target | ||
496 | * @scsi_state: U8 scsi state | ||
497 | * @sc: original scsi cmnd pointer | ||
498 | * @mf: Pointer to MPT request frame | ||
499 | * | ||
500 | * Refer to lsi/mpi.h. | ||
501 | **/ | ||
502 | static void | ||
503 | mptscsih_iocstatus_info_scsiio(MPT_ADAPTER *ioc, u32 ioc_status, | ||
504 | u8 scsi_status, u8 scsi_state, struct scsi_cmnd *sc) | ||
505 | { | ||
506 | char extend_desc[EVENT_DESCR_STR_SZ]; | ||
507 | char *desc = NULL; | ||
508 | |||
509 | switch (ioc_status) { | ||
510 | |||
511 | case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ | ||
512 | desc = "SCSI Invalid Bus"; | ||
513 | break; | ||
514 | |||
515 | case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ | ||
516 | desc = "SCSI Invalid TargetID"; | ||
517 | break; | ||
518 | |||
519 | case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ | ||
520 | /* | ||
521 | * Inquiry is issued for device scanning | ||
522 | */ | ||
523 | if (sc->cmnd[0] != 0x12) | ||
524 | desc = "SCSI Device Not There"; | ||
525 | break; | ||
526 | |||
527 | case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ | ||
528 | desc = "SCSI Data Overrun"; | ||
529 | break; | ||
530 | |||
531 | case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ | ||
532 | desc = "SCSI I/O Data Error"; | ||
533 | break; | ||
534 | |||
535 | case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ | ||
536 | desc = "SCSI Protocol Error"; | ||
537 | break; | ||
538 | |||
539 | case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ | ||
540 | desc = "SCSI Task Terminated"; | ||
541 | break; | ||
542 | |||
543 | case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ | ||
544 | desc = "SCSI Residual Mismatch"; | ||
545 | break; | ||
546 | |||
547 | case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ | ||
548 | desc = "SCSI Task Management Failed"; | ||
549 | break; | ||
550 | |||
551 | case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ | ||
552 | desc = "SCSI IOC Terminated"; | ||
553 | break; | ||
554 | |||
555 | case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ | ||
556 | desc = "SCSI Ext Terminated"; | ||
557 | break; | ||
558 | } | ||
559 | |||
560 | if (!desc) | ||
561 | return; | ||
562 | |||
563 | snprintf(extend_desc, EVENT_DESCR_STR_SZ, | ||
564 | "[%d:%d:%d:%d] cmd=%02Xh, sam_status=%02Xh state=%02Xh", | ||
565 | sc->device->host->host_no, | ||
566 | sc->device->channel, sc->device->id, sc->device->lun, | ||
567 | sc->cmnd[0], scsi_status, scsi_state); | ||
568 | |||
569 | printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n", | ||
570 | ioc->name, ioc_status, desc, extend_desc); | ||
571 | } | ||
572 | #endif | ||
573 | |||
530 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 574 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
531 | /* | 575 | /* |
532 | * mptscsih_io_done - Main SCSI IO callback routine registered to | 576 | * mptscsih_io_done - Main SCSI IO callback routine registered to |
@@ -613,12 +657,14 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
613 | u32 xfer_cnt; | 657 | u32 xfer_cnt; |
614 | u16 status; | 658 | u16 status; |
615 | u8 scsi_state, scsi_status; | 659 | u8 scsi_state, scsi_status; |
660 | u32 log_info; | ||
616 | 661 | ||
617 | status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; | 662 | status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; |
618 | scsi_state = pScsiReply->SCSIState; | 663 | scsi_state = pScsiReply->SCSIState; |
619 | scsi_status = pScsiReply->SCSIStatus; | 664 | scsi_status = pScsiReply->SCSIStatus; |
620 | xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); | 665 | xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); |
621 | sc->resid = sc->request_bufflen - xfer_cnt; | 666 | sc->resid = sc->request_bufflen - xfer_cnt; |
667 | log_info = le32_to_cpu(pScsiReply->IOCLogInfo); | ||
622 | 668 | ||
623 | /* | 669 | /* |
624 | * if we get a data underrun indication, yet no data was | 670 | * if we get a data underrun indication, yet no data was |
@@ -633,13 +679,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
633 | status = MPI_IOCSTATUS_SUCCESS; | 679 | status = MPI_IOCSTATUS_SUCCESS; |
634 | } | 680 | } |
635 | 681 | ||
636 | dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" | ||
637 | "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" | ||
638 | "resid=%d bufflen=%d xfer_cnt=%d\n", | ||
639 | ioc->id, sc->device->id, sc->device->lun, | ||
640 | status, scsi_state, scsi_status, sc->resid, | ||
641 | sc->request_bufflen, xfer_cnt)); | ||
642 | |||
643 | if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) | 682 | if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) |
644 | mptscsih_copy_sense_data(sc, hd, mf, pScsiReply); | 683 | mptscsih_copy_sense_data(sc, hd, mf, pScsiReply); |
645 | 684 | ||
@@ -648,9 +687,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
648 | */ | 687 | */ |
649 | if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID && | 688 | if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID && |
650 | pScsiReply->ResponseInfo) { | 689 | pScsiReply->ResponseInfo) { |
651 | printk(KERN_NOTICE "ha=%d id=%d lun=%d: " | 690 | printk(KERN_NOTICE "[%d:%d:%d:%d] " |
652 | "FCP_ResponseInfo=%08xh\n", | 691 | "FCP_ResponseInfo=%08xh\n", |
653 | ioc->id, sc->device->id, sc->device->lun, | 692 | sc->device->host->host_no, sc->device->channel, |
693 | sc->device->id, sc->device->lun, | ||
654 | le32_to_cpu(pScsiReply->ResponseInfo)); | 694 | le32_to_cpu(pScsiReply->ResponseInfo)); |
655 | } | 695 | } |
656 | 696 | ||
@@ -695,9 +735,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
695 | if ( ioc->bus_type == SAS ) { | 735 | if ( ioc->bus_type == SAS ) { |
696 | u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus); | 736 | u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus); |
697 | if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { | 737 | if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { |
698 | u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo); | 738 | if ((log_info & SAS_LOGINFO_MASK) |
699 | log_info &=SAS_LOGINFO_MASK; | 739 | == SAS_LOGINFO_NEXUS_LOSS) { |
700 | if (log_info == SAS_LOGINFO_NEXUS_LOSS) { | ||
701 | sc->result = (DID_BUS_BUSY << 16); | 740 | sc->result = (DID_BUS_BUSY << 16); |
702 | break; | 741 | break; |
703 | } | 742 | } |
@@ -735,7 +774,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
735 | else /* Sufficient data transfer occurred */ | 774 | else /* Sufficient data transfer occurred */ |
736 | sc->result = (DID_OK << 16) | scsi_status; | 775 | sc->result = (DID_OK << 16) | scsi_status; |
737 | dreplyprintk((KERN_NOTICE | 776 | dreplyprintk((KERN_NOTICE |
738 | "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id)); | 777 | "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n", |
778 | sc->result, sc->device->channel, sc->device->id)); | ||
739 | break; | 779 | break; |
740 | 780 | ||
741 | case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ | 781 | case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ |
@@ -848,7 +888,28 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
848 | 888 | ||
849 | } /* switch(status) */ | 889 | } /* switch(status) */ |
850 | 890 | ||
851 | dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result)); | 891 | #ifdef MPT_DEBUG_REPLY |
892 | if (sc->result) { | ||
893 | |||
894 | mptscsih_iocstatus_info_scsiio(ioc, status, | ||
895 | scsi_status, scsi_state, sc); | ||
896 | |||
897 | dreplyprintk(("%s: [%d:%d:%d:%d] cmd=0x%02x " | ||
898 | "result=0x%08x\n\tiocstatus=0x%04X " | ||
899 | "scsi_state=0x%02X scsi_status=0x%02X " | ||
900 | "loginfo=0x%08X\n", __FUNCTION__, | ||
901 | sc->device->host->host_no, sc->device->channel, sc->device->id, | ||
902 | sc->device->lun, sc->cmnd[0], sc->result, status, | ||
903 | scsi_state, scsi_status, log_info)); | ||
904 | |||
905 | dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d " | ||
906 | "bufflen=%d xfer_cnt=%d\n", __FUNCTION__, | ||
907 | sc->device->host->host_no, sc->device->channel, sc->device->id, | ||
908 | sc->device->lun, sc->resid, sc->request_bufflen, | ||
909 | xfer_cnt)); | ||
910 | } | ||
911 | #endif | ||
912 | |||
852 | } /* end of address reply case */ | 913 | } /* end of address reply case */ |
853 | 914 | ||
854 | /* Unmap the DMA buffers, if any. */ | 915 | /* Unmap the DMA buffers, if any. */ |
@@ -955,9 +1016,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
955 | int ii; | 1016 | int ii; |
956 | int max = hd->ioc->req_depth; | 1017 | int max = hd->ioc->req_depth; |
957 | struct scsi_cmnd *sc; | 1018 | struct scsi_cmnd *sc; |
1019 | struct scsi_lun lun; | ||
958 | 1020 | ||
959 | dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", | 1021 | dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n", |
960 | vdevice->vtarget->target_id, vdevice->lun, max)); | 1022 | vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); |
961 | 1023 | ||
962 | for (ii=0; ii < max; ii++) { | 1024 | for (ii=0; ii < max; ii++) { |
963 | if ((sc = hd->ScsiLookup[ii]) != NULL) { | 1025 | if ((sc = hd->ScsiLookup[ii]) != NULL) { |
@@ -965,10 +1027,14 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
965 | mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); | 1027 | mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); |
966 | if (mf == NULL) | 1028 | if (mf == NULL) |
967 | continue; | 1029 | continue; |
968 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", | 1030 | int_to_scsilun(vdevice->lun, &lun); |
969 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); | 1031 | if ((mf->Bus != vdevice->vtarget->channel) || |
970 | if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) | 1032 | (mf->TargetID != vdevice->vtarget->id) || |
1033 | memcmp(lun.scsi_lun, mf->LUN, 8)) | ||
971 | continue; | 1034 | continue; |
1035 | dsprintk(( "search_running: found (sc=%p, mf = %p) " | ||
1036 | "channel %d id %d, lun %d \n", hd->ScsiLookup[ii], | ||
1037 | mf, mf->Bus, mf->TargetID, vdevice->lun)); | ||
972 | 1038 | ||
973 | /* Cleanup | 1039 | /* Cleanup |
974 | */ | 1040 | */ |
@@ -1065,12 +1131,6 @@ mptscsih_remove(struct pci_dev *pdev) | |||
1065 | hd->ScsiLookup = NULL; | 1131 | hd->ScsiLookup = NULL; |
1066 | } | 1132 | } |
1067 | 1133 | ||
1068 | /* | ||
1069 | * Free pointer array. | ||
1070 | */ | ||
1071 | kfree(hd->Targets); | ||
1072 | hd->Targets = NULL; | ||
1073 | |||
1074 | dprintk((MYIOC_s_INFO_FMT | 1134 | dprintk((MYIOC_s_INFO_FMT |
1075 | "Free'd ScsiLookup (%d) memory\n", | 1135 | "Free'd ScsiLookup (%d) memory\n", |
1076 | hd->ioc->name, sz1)); | 1136 | hd->ioc->name, sz1)); |
@@ -1317,14 +1377,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1317 | return SCSI_MLQUEUE_HOST_BUSY; | 1377 | return SCSI_MLQUEUE_HOST_BUSY; |
1318 | } | 1378 | } |
1319 | 1379 | ||
1320 | if ((hd->ioc->bus_type == SPI) && | ||
1321 | vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT && | ||
1322 | mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) { | ||
1323 | SCpnt->result = DID_NO_CONNECT << 16; | ||
1324 | done(SCpnt); | ||
1325 | return 0; | ||
1326 | } | ||
1327 | |||
1328 | /* | 1380 | /* |
1329 | * Put together a MPT SCSI request... | 1381 | * Put together a MPT SCSI request... |
1330 | */ | 1382 | */ |
@@ -1368,8 +1420,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1368 | 1420 | ||
1369 | /* Use the above information to set up the message frame | 1421 | /* Use the above information to set up the message frame |
1370 | */ | 1422 | */ |
1371 | pScsiReq->TargetID = (u8) vdev->vtarget->target_id; | 1423 | pScsiReq->TargetID = (u8) vdev->vtarget->id; |
1372 | pScsiReq->Bus = vdev->vtarget->bus_id; | 1424 | pScsiReq->Bus = vdev->vtarget->channel; |
1373 | pScsiReq->ChainOffset = 0; | 1425 | pScsiReq->ChainOffset = 0; |
1374 | if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) | 1426 | if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) |
1375 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; | 1427 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; |
@@ -1379,14 +1431,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1379 | pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; | 1431 | pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; |
1380 | pScsiReq->Reserved = 0; | 1432 | pScsiReq->Reserved = 0; |
1381 | pScsiReq->MsgFlags = mpt_msg_flags(); | 1433 | pScsiReq->MsgFlags = mpt_msg_flags(); |
1382 | pScsiReq->LUN[0] = 0; | 1434 | int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN); |
1383 | pScsiReq->LUN[1] = lun; | ||
1384 | pScsiReq->LUN[2] = 0; | ||
1385 | pScsiReq->LUN[3] = 0; | ||
1386 | pScsiReq->LUN[4] = 0; | ||
1387 | pScsiReq->LUN[5] = 0; | ||
1388 | pScsiReq->LUN[6] = 0; | ||
1389 | pScsiReq->LUN[7] = 0; | ||
1390 | pScsiReq->Control = cpu_to_le32(scsictl); | 1435 | pScsiReq->Control = cpu_to_le32(scsictl); |
1391 | 1436 | ||
1392 | /* | 1437 | /* |
@@ -1491,14 +1536,14 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) | |||
1491 | */ | 1536 | */ |
1492 | 1537 | ||
1493 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1538 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1494 | /* | 1539 | /** |
1495 | * mptscsih_TMHandler - Generic handler for SCSI Task Management. | 1540 | * mptscsih_TMHandler - Generic handler for SCSI Task Management. |
1496 | * Fall through to mpt_HardResetHandler if: not operational, too many | 1541 | * Fall through to mpt_HardResetHandler if: not operational, too many |
1497 | * failed TM requests or handshake failure. | 1542 | * failed TM requests or handshake failure. |
1498 | * | 1543 | * |
1499 | * @ioc: Pointer to MPT_ADAPTER structure | 1544 | * @ioc: Pointer to MPT_ADAPTER structure |
1500 | * @type: Task Management type | 1545 | * @type: Task Management type |
1501 | * @target: Logical Target ID for reset (if appropriate) | 1546 | * @id: Logical Target ID for reset (if appropriate) |
1502 | * @lun: Logical Unit for reset (if appropriate) | 1547 | * @lun: Logical Unit for reset (if appropriate) |
1503 | * @ctx2abort: Context for the task to be aborted (if appropriate) | 1548 | * @ctx2abort: Context for the task to be aborted (if appropriate) |
1504 | * | 1549 | * |
@@ -1507,28 +1552,17 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) | |||
1507 | * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC | 1552 | * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC |
1508 | * will be active. | 1553 | * will be active. |
1509 | * | 1554 | * |
1510 | * Returns 0 for SUCCESS or -1 if FAILED. | 1555 | * Returns 0 for SUCCESS, or FAILED. |
1511 | */ | 1556 | **/ |
1512 | int | 1557 | int |
1513 | mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) | 1558 | mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) |
1514 | { | 1559 | { |
1515 | MPT_ADAPTER *ioc; | 1560 | MPT_ADAPTER *ioc; |
1516 | int rc = -1; | 1561 | int rc = -1; |
1517 | int doTask = 1; | ||
1518 | u32 ioc_raw_state; | 1562 | u32 ioc_raw_state; |
1519 | unsigned long flags; | 1563 | unsigned long flags; |
1520 | 1564 | ||
1521 | /* If FW is being reloaded currently, return success to | ||
1522 | * the calling function. | ||
1523 | */ | ||
1524 | if (hd == NULL) | ||
1525 | return 0; | ||
1526 | |||
1527 | ioc = hd->ioc; | 1565 | ioc = hd->ioc; |
1528 | if (ioc == NULL) { | ||
1529 | printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n"); | ||
1530 | return FAILED; | ||
1531 | } | ||
1532 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); | 1566 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); |
1533 | 1567 | ||
1534 | // SJR - CHECKME - Can we avoid this here? | 1568 | // SJR - CHECKME - Can we avoid this here? |
@@ -1541,8 +1575,10 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1541 | spin_unlock_irqrestore(&ioc->diagLock, flags); | 1575 | spin_unlock_irqrestore(&ioc->diagLock, flags); |
1542 | 1576 | ||
1543 | /* Wait a fixed amount of time for the TM pending flag to be cleared. | 1577 | /* Wait a fixed amount of time for the TM pending flag to be cleared. |
1544 | * If we time out and not bus reset, then we return a FAILED status to the caller. | 1578 | * If we time out and not bus reset, then we return a FAILED status |
1545 | * The call to mptscsih_tm_pending_wait() will set the pending flag if we are | 1579 | * to the caller. |
1580 | * The call to mptscsih_tm_pending_wait() will set the pending flag | ||
1581 | * if we are | ||
1546 | * successful. Otherwise, reload the FW. | 1582 | * successful. Otherwise, reload the FW. |
1547 | */ | 1583 | */ |
1548 | if (mptscsih_tm_pending_wait(hd) == FAILED) { | 1584 | if (mptscsih_tm_pending_wait(hd) == FAILED) { |
@@ -1552,18 +1588,16 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1552 | hd->ioc->name, hd->tmPending)); | 1588 | hd->ioc->name, hd->tmPending)); |
1553 | return FAILED; | 1589 | return FAILED; |
1554 | } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { | 1590 | } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { |
1555 | dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: " | 1591 | dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target " |
1556 | "Timed out waiting for last TM (%d) to complete! \n", | 1592 | "reset: Timed out waiting for last TM (%d) " |
1557 | hd->ioc->name, hd->tmPending)); | 1593 | "to complete! \n", hd->ioc->name, |
1594 | hd->tmPending)); | ||
1558 | return FAILED; | 1595 | return FAILED; |
1559 | } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { | 1596 | } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { |
1560 | dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " | 1597 | dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " |
1561 | "Timed out waiting for last TM (%d) to complete! \n", | 1598 | "Timed out waiting for last TM (%d) to complete! \n", |
1562 | hd->ioc->name, hd->tmPending)); | 1599 | hd->ioc->name, hd->tmPending)); |
1563 | if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) | 1600 | return FAILED; |
1564 | return FAILED; | ||
1565 | |||
1566 | doTask = 0; | ||
1567 | } | 1601 | } |
1568 | } else { | 1602 | } else { |
1569 | spin_lock_irqsave(&hd->ioc->FreeQlock, flags); | 1603 | spin_lock_irqsave(&hd->ioc->FreeQlock, flags); |
@@ -1571,47 +1605,40 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1571 | spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); | 1605 | spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); |
1572 | } | 1606 | } |
1573 | 1607 | ||
1574 | /* Is operational? | ||
1575 | */ | ||
1576 | ioc_raw_state = mpt_GetIocState(hd->ioc, 0); | 1608 | ioc_raw_state = mpt_GetIocState(hd->ioc, 0); |
1577 | 1609 | ||
1578 | #ifdef MPT_DEBUG_RESET | ||
1579 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { | 1610 | if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { |
1580 | printk(MYIOC_s_WARN_FMT | 1611 | printk(MYIOC_s_WARN_FMT |
1581 | "TM Handler: IOC Not operational(0x%x)!\n", | 1612 | "TM Handler for type=%x: IOC Not operational (0x%x)!\n", |
1582 | hd->ioc->name, ioc_raw_state); | 1613 | ioc->name, type, ioc_raw_state); |
1583 | } | 1614 | printk(KERN_WARNING " Issuing HardReset!!\n"); |
1584 | #endif | 1615 | if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) |
1585 | 1616 | printk((KERN_WARNING "TMHandler: HardReset " | |
1586 | if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) | 1617 | "FAILED!!\n")); |
1587 | && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) { | 1618 | return FAILED; |
1588 | |||
1589 | /* Isse the Task Mgmt request. | ||
1590 | */ | ||
1591 | if (hd->hard_resets < -1) | ||
1592 | hd->hard_resets++; | ||
1593 | rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout); | ||
1594 | if (rc) { | ||
1595 | printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); | ||
1596 | } else { | ||
1597 | dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name)); | ||
1598 | } | ||
1599 | } | 1619 | } |
1600 | 1620 | ||
1601 | /* Only fall through to the HRH if this is a bus reset | 1621 | if (ioc_raw_state & MPI_DOORBELL_ACTIVE) { |
1602 | */ | 1622 | printk(MYIOC_s_WARN_FMT |
1603 | if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc || | 1623 | "TM Handler for type=%x: ioc_state: " |
1604 | ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { | 1624 | "DOORBELL_ACTIVE (0x%x)!\n", |
1605 | dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", | 1625 | ioc->name, type, ioc_raw_state); |
1606 | hd->ioc->name)); | 1626 | return FAILED; |
1607 | rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); | ||
1608 | } | 1627 | } |
1609 | 1628 | ||
1610 | /* | 1629 | /* Isse the Task Mgmt request. |
1611 | * Check IOCStatus from TM reply message | ||
1612 | */ | 1630 | */ |
1613 | if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS) | 1631 | if (hd->hard_resets < -1) |
1614 | rc = FAILED; | 1632 | hd->hard_resets++; |
1633 | |||
1634 | rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, | ||
1635 | ctx2abort, timeout); | ||
1636 | if (rc) | ||
1637 | printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", | ||
1638 | hd->ioc->name); | ||
1639 | else | ||
1640 | dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", | ||
1641 | hd->ioc->name)); | ||
1615 | 1642 | ||
1616 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); | 1643 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); |
1617 | 1644 | ||
@@ -1620,11 +1647,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1620 | 1647 | ||
1621 | 1648 | ||
1622 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1649 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1623 | /* | 1650 | /** |
1624 | * mptscsih_IssueTaskMgmt - Generic send Task Management function. | 1651 | * mptscsih_IssueTaskMgmt - Generic send Task Management function. |
1625 | * @hd: Pointer to MPT_SCSI_HOST structure | 1652 | * @hd: Pointer to MPT_SCSI_HOST structure |
1626 | * @type: Task Management type | 1653 | * @type: Task Management type |
1627 | * @target: Logical Target ID for reset (if appropriate) | 1654 | * @id: Logical Target ID for reset (if appropriate) |
1628 | * @lun: Logical Unit for reset (if appropriate) | 1655 | * @lun: Logical Unit for reset (if appropriate) |
1629 | * @ctx2abort: Context for the task to be aborted (if appropriate) | 1656 | * @ctx2abort: Context for the task to be aborted (if appropriate) |
1630 | * | 1657 | * |
@@ -1633,11 +1660,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1633 | * | 1660 | * |
1634 | * Not all fields are meaningfull for all task types. | 1661 | * Not all fields are meaningfull for all task types. |
1635 | * | 1662 | * |
1636 | * Returns 0 for SUCCESS, -999 for "no msg frames", | 1663 | * Returns 0 for SUCCESS, or FAILED. |
1637 | * else other non-zero value returned. | 1664 | * |
1638 | */ | 1665 | **/ |
1639 | static int | 1666 | static int |
1640 | mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) | 1667 | mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) |
1641 | { | 1668 | { |
1642 | MPT_FRAME_HDR *mf; | 1669 | MPT_FRAME_HDR *mf; |
1643 | SCSITaskMgmt_t *pScsiTm; | 1670 | SCSITaskMgmt_t *pScsiTm; |
@@ -1657,7 +1684,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun | |||
1657 | /* Format the Request | 1684 | /* Format the Request |
1658 | */ | 1685 | */ |
1659 | pScsiTm = (SCSITaskMgmt_t *) mf; | 1686 | pScsiTm = (SCSITaskMgmt_t *) mf; |
1660 | pScsiTm->TargetID = target; | 1687 | pScsiTm->TargetID = id; |
1661 | pScsiTm->Bus = channel; | 1688 | pScsiTm->Bus = channel; |
1662 | pScsiTm->ChainOffset = 0; | 1689 | pScsiTm->ChainOffset = 0; |
1663 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; | 1690 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; |
@@ -1668,42 +1695,59 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun | |||
1668 | pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) | 1695 | pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) |
1669 | ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; | 1696 | ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; |
1670 | 1697 | ||
1671 | for (ii= 0; ii < 8; ii++) { | 1698 | int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN); |
1672 | pScsiTm->LUN[ii] = 0; | ||
1673 | } | ||
1674 | pScsiTm->LUN[1] = lun; | ||
1675 | 1699 | ||
1676 | for (ii=0; ii < 7; ii++) | 1700 | for (ii=0; ii < 7; ii++) |
1677 | pScsiTm->Reserved2[ii] = 0; | 1701 | pScsiTm->Reserved2[ii] = 0; |
1678 | 1702 | ||
1679 | pScsiTm->TaskMsgContext = ctx2abort; | 1703 | pScsiTm->TaskMsgContext = ctx2abort; |
1680 | 1704 | ||
1681 | dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", | 1705 | dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) " |
1682 | hd->ioc->name, ctx2abort, type)); | 1706 | "type=%d\n", hd->ioc->name, ctx2abort, type)); |
1683 | 1707 | ||
1684 | DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); | 1708 | DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); |
1685 | 1709 | ||
1686 | if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, | 1710 | if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, |
1687 | sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, | 1711 | sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) { |
1688 | CAN_SLEEP)) != 0) { | 1712 | dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!" |
1689 | dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!" | 1713 | " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd, |
1690 | " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, | 1714 | hd->ioc, mf, retval)); |
1691 | hd->ioc, mf)); | 1715 | goto fail_out; |
1692 | mpt_free_msg_frame(hd->ioc, mf); | ||
1693 | return retval; | ||
1694 | } | 1716 | } |
1695 | 1717 | ||
1696 | if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { | 1718 | if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { |
1697 | dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!" | 1719 | dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!" |
1698 | " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, | 1720 | " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, |
1699 | hd->ioc, mf)); | 1721 | hd->ioc, mf)); |
1700 | mpt_free_msg_frame(hd->ioc, mf); | ||
1701 | dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", | 1722 | dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", |
1702 | hd->ioc->name)); | 1723 | hd->ioc->name)); |
1703 | retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); | 1724 | retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); |
1725 | dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n", | ||
1726 | hd->ioc->name, retval)); | ||
1727 | goto fail_out; | ||
1704 | } | 1728 | } |
1705 | 1729 | ||
1730 | /* | ||
1731 | * Handle success case, see if theres a non-zero ioc_status. | ||
1732 | */ | ||
1733 | if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS || | ||
1734 | hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED || | ||
1735 | hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED) | ||
1736 | retval = 0; | ||
1737 | else | ||
1738 | retval = FAILED; | ||
1739 | |||
1706 | return retval; | 1740 | return retval; |
1741 | |||
1742 | fail_out: | ||
1743 | |||
1744 | /* | ||
1745 | * Free task managment mf, and corresponding tm flags | ||
1746 | */ | ||
1747 | mpt_free_msg_frame(hd->ioc, mf); | ||
1748 | hd->tmPending = 0; | ||
1749 | hd->tmState = TM_STATE_NONE; | ||
1750 | return FAILED; | ||
1707 | } | 1751 | } |
1708 | 1752 | ||
1709 | static int | 1753 | static int |
@@ -1728,7 +1772,7 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc) | |||
1728 | * (linux scsi_host_template.eh_abort_handler routine) | 1772 | * (linux scsi_host_template.eh_abort_handler routine) |
1729 | * | 1773 | * |
1730 | * Returns SUCCESS or FAILED. | 1774 | * Returns SUCCESS or FAILED. |
1731 | */ | 1775 | **/ |
1732 | int | 1776 | int |
1733 | mptscsih_abort(struct scsi_cmnd * SCpnt) | 1777 | mptscsih_abort(struct scsi_cmnd * SCpnt) |
1734 | { | 1778 | { |
@@ -1764,9 +1808,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1764 | return SUCCESS; | 1808 | return SUCCESS; |
1765 | } | 1809 | } |
1766 | 1810 | ||
1767 | if (hd->resetPending) { | 1811 | if (hd->resetPending) |
1768 | return FAILED; | 1812 | return FAILED; |
1769 | } | ||
1770 | 1813 | ||
1771 | if (hd->timeouts < -1) | 1814 | if (hd->timeouts < -1) |
1772 | hd->timeouts++; | 1815 | hd->timeouts++; |
@@ -1789,13 +1832,12 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1789 | 1832 | ||
1790 | vdev = SCpnt->device->hostdata; | 1833 | vdev = SCpnt->device->hostdata; |
1791 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, | 1834 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, |
1792 | vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, | 1835 | vdev->vtarget->channel, vdev->vtarget->id, vdev->lun, |
1793 | ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); | 1836 | ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); |
1794 | 1837 | ||
1795 | if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && | 1838 | if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && |
1796 | SCpnt->serial_number == sn) { | 1839 | SCpnt->serial_number == sn) |
1797 | retval = FAILED; | 1840 | retval = FAILED; |
1798 | } | ||
1799 | 1841 | ||
1800 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", | 1842 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", |
1801 | hd->ioc->name, | 1843 | hd->ioc->name, |
@@ -1803,12 +1845,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1803 | 1845 | ||
1804 | if (retval == 0) | 1846 | if (retval == 0) |
1805 | return SUCCESS; | 1847 | return SUCCESS; |
1806 | 1848 | else | |
1807 | if(retval != FAILED ) { | 1849 | return FAILED; |
1808 | hd->tmPending = 0; | ||
1809 | hd->tmState = TM_STATE_NONE; | ||
1810 | } | ||
1811 | return FAILED; | ||
1812 | } | 1850 | } |
1813 | 1851 | ||
1814 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1852 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -1819,7 +1857,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1819 | * (linux scsi_host_template.eh_dev_reset_handler routine) | 1857 | * (linux scsi_host_template.eh_dev_reset_handler routine) |
1820 | * | 1858 | * |
1821 | * Returns SUCCESS or FAILED. | 1859 | * Returns SUCCESS or FAILED. |
1822 | */ | 1860 | **/ |
1823 | int | 1861 | int |
1824 | mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | 1862 | mptscsih_dev_reset(struct scsi_cmnd * SCpnt) |
1825 | { | 1863 | { |
@@ -1845,7 +1883,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1845 | 1883 | ||
1846 | vdev = SCpnt->device->hostdata; | 1884 | vdev = SCpnt->device->hostdata; |
1847 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | 1885 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, |
1848 | vdev->vtarget->bus_id, vdev->vtarget->target_id, | 1886 | vdev->vtarget->channel, vdev->vtarget->id, |
1849 | 0, 0, mptscsih_get_tm_timeout(hd->ioc)); | 1887 | 0, 0, mptscsih_get_tm_timeout(hd->ioc)); |
1850 | 1888 | ||
1851 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", | 1889 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", |
@@ -1854,14 +1892,11 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1854 | 1892 | ||
1855 | if (retval == 0) | 1893 | if (retval == 0) |
1856 | return SUCCESS; | 1894 | return SUCCESS; |
1857 | 1895 | else | |
1858 | if(retval != FAILED ) { | 1896 | return FAILED; |
1859 | hd->tmPending = 0; | ||
1860 | hd->tmState = TM_STATE_NONE; | ||
1861 | } | ||
1862 | return FAILED; | ||
1863 | } | 1897 | } |
1864 | 1898 | ||
1899 | |||
1865 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1900 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1866 | /** | 1901 | /** |
1867 | * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant | 1902 | * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant |
@@ -1870,7 +1905,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1870 | * (linux scsi_host_template.eh_bus_reset_handler routine) | 1905 | * (linux scsi_host_template.eh_bus_reset_handler routine) |
1871 | * | 1906 | * |
1872 | * Returns SUCCESS or FAILED. | 1907 | * Returns SUCCESS or FAILED. |
1873 | */ | 1908 | **/ |
1874 | int | 1909 | int |
1875 | mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | 1910 | mptscsih_bus_reset(struct scsi_cmnd * SCpnt) |
1876 | { | 1911 | { |
@@ -1896,7 +1931,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
1896 | 1931 | ||
1897 | vdev = SCpnt->device->hostdata; | 1932 | vdev = SCpnt->device->hostdata; |
1898 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | 1933 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, |
1899 | vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); | 1934 | vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); |
1900 | 1935 | ||
1901 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", | 1936 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", |
1902 | hd->ioc->name, | 1937 | hd->ioc->name, |
@@ -1904,12 +1939,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
1904 | 1939 | ||
1905 | if (retval == 0) | 1940 | if (retval == 0) |
1906 | return SUCCESS; | 1941 | return SUCCESS; |
1907 | 1942 | else | |
1908 | if(retval != FAILED ) { | 1943 | return FAILED; |
1909 | hd->tmPending = 0; | ||
1910 | hd->tmState = TM_STATE_NONE; | ||
1911 | } | ||
1912 | return FAILED; | ||
1913 | } | 1944 | } |
1914 | 1945 | ||
1915 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1946 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -1992,7 +2023,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) | |||
1992 | /** | 2023 | /** |
1993 | * mptscsih_tm_wait_for_completion - wait for completion of TM task | 2024 | * mptscsih_tm_wait_for_completion - wait for completion of TM task |
1994 | * @hd: Pointer to MPT host structure. | 2025 | * @hd: Pointer to MPT host structure. |
1995 | * @timeout: timeout in seconds | ||
1996 | * | 2026 | * |
1997 | * Returns {SUCCESS,FAILED}. | 2027 | * Returns {SUCCESS,FAILED}. |
1998 | */ | 2028 | */ |
@@ -2066,7 +2096,7 @@ mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code) | |||
2066 | * load/init time via the mpt_register() API call. | 2096 | * load/init time via the mpt_register() API call. |
2067 | * | 2097 | * |
2068 | * Returns 1 indicating alloc'd request frame ptr should be freed. | 2098 | * Returns 1 indicating alloc'd request frame ptr should be freed. |
2069 | */ | 2099 | **/ |
2070 | int | 2100 | int |
2071 | mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | 2101 | mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) |
2072 | { | 2102 | { |
@@ -2076,78 +2106,85 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m | |||
2076 | unsigned long flags; | 2106 | unsigned long flags; |
2077 | u16 iocstatus; | 2107 | u16 iocstatus; |
2078 | u8 tmType; | 2108 | u8 tmType; |
2109 | u32 termination_count; | ||
2079 | 2110 | ||
2080 | dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n", | 2111 | dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n", |
2081 | ioc->name, mf, mr)); | 2112 | ioc->name, mf, mr)); |
2082 | if (ioc->sh) { | 2113 | if (!ioc->sh) { |
2083 | /* Depending on the thread, a timer is activated for | 2114 | dtmprintk((MYIOC_s_WARN_FMT |
2084 | * the TM request. Delete this timer on completion of TM. | 2115 | "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name)); |
2085 | * Decrement count of outstanding TM requests. | ||
2086 | */ | ||
2087 | hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; | ||
2088 | } else { | ||
2089 | dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n", | ||
2090 | ioc->name)); | ||
2091 | return 1; | 2116 | return 1; |
2092 | } | 2117 | } |
2093 | 2118 | ||
2094 | if (mr == NULL) { | 2119 | if (mr == NULL) { |
2095 | dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n", | 2120 | dtmprintk((MYIOC_s_WARN_FMT |
2096 | ioc->name, mf)); | 2121 | "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf)); |
2097 | return 1; | 2122 | return 1; |
2098 | } else { | 2123 | } |
2099 | pScsiTmReply = (SCSITaskMgmtReply_t*)mr; | ||
2100 | pScsiTmReq = (SCSITaskMgmt_t*)mf; | ||
2101 | |||
2102 | /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ | ||
2103 | tmType = pScsiTmReq->TaskType; | ||
2104 | 2124 | ||
2105 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && | 2125 | hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; |
2106 | pScsiTmReply->ResponseCode) | 2126 | pScsiTmReply = (SCSITaskMgmtReply_t*)mr; |
2107 | mptscsih_taskmgmt_response_code(ioc, | 2127 | pScsiTmReq = (SCSITaskMgmt_t*)mf; |
2108 | pScsiTmReply->ResponseCode); | 2128 | tmType = pScsiTmReq->TaskType; |
2129 | iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; | ||
2130 | termination_count = le32_to_cpu(pScsiTmReply->TerminationCount); | ||
2131 | |||
2132 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && | ||
2133 | pScsiTmReply->ResponseCode) | ||
2134 | mptscsih_taskmgmt_response_code(ioc, | ||
2135 | pScsiTmReply->ResponseCode); | ||
2136 | DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); | ||
2137 | |||
2138 | #if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM) | ||
2139 | printk("%s: ha=%d [%d:%d:0] task_type=0x%02X " | ||
2140 | "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X " | ||
2141 | "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus, | ||
2142 | pScsiTmReply->TargetID, pScsiTmReq->TaskType, | ||
2143 | le16_to_cpu(pScsiTmReply->IOCStatus), | ||
2144 | le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode, | ||
2145 | le32_to_cpu(pScsiTmReply->TerminationCount)); | ||
2146 | #endif | ||
2147 | if (!iocstatus) { | ||
2148 | dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name)); | ||
2149 | hd->abortSCpnt = NULL; | ||
2150 | goto out; | ||
2151 | } | ||
2109 | 2152 | ||
2110 | dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", | 2153 | /* Error? (anything non-zero?) */ |
2111 | ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); | ||
2112 | DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); | ||
2113 | 2154 | ||
2114 | iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; | 2155 | /* clear flags and continue. |
2115 | hd->tm_iocstatus = iocstatus; | 2156 | */ |
2116 | dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", | 2157 | switch (tmType) { |
2117 | ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); | ||
2118 | /* Error? (anything non-zero?) */ | ||
2119 | if (iocstatus) { | ||
2120 | 2158 | ||
2121 | /* clear flags and continue. | 2159 | case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK: |
2122 | */ | 2160 | if (termination_count == 1) |
2123 | if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) | 2161 | iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED; |
2124 | hd->abortSCpnt = NULL; | 2162 | hd->abortSCpnt = NULL; |
2163 | break; | ||
2125 | 2164 | ||
2126 | /* If an internal command is present | 2165 | case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS: |
2127 | * or the TM failed - reload the FW. | ||
2128 | * FC FW may respond FAILED to an ABORT | ||
2129 | */ | ||
2130 | if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { | ||
2131 | if ((hd->cmdPtr) || | ||
2132 | (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) { | ||
2133 | if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) { | ||
2134 | printk((KERN_WARNING | ||
2135 | " Firmware Reload FAILED!!\n")); | ||
2136 | } | ||
2137 | } | ||
2138 | } | ||
2139 | } else { | ||
2140 | dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name)); | ||
2141 | 2166 | ||
2142 | hd->abortSCpnt = NULL; | 2167 | /* If an internal command is present |
2168 | * or the TM failed - reload the FW. | ||
2169 | * FC FW may respond FAILED to an ABORT | ||
2170 | */ | ||
2171 | if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED || | ||
2172 | hd->cmdPtr) | ||
2173 | if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) | ||
2174 | printk((KERN_WARNING " Firmware Reload FAILED!!\n")); | ||
2175 | break; | ||
2143 | 2176 | ||
2144 | } | 2177 | case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET: |
2178 | default: | ||
2179 | break; | ||
2145 | } | 2180 | } |
2146 | 2181 | ||
2182 | out: | ||
2147 | spin_lock_irqsave(&ioc->FreeQlock, flags); | 2183 | spin_lock_irqsave(&ioc->FreeQlock, flags); |
2148 | hd->tmPending = 0; | 2184 | hd->tmPending = 0; |
2149 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); | ||
2150 | hd->tmState = TM_STATE_NONE; | 2185 | hd->tmState = TM_STATE_NONE; |
2186 | hd->tm_iocstatus = iocstatus; | ||
2187 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); | ||
2151 | 2188 | ||
2152 | return 1; | 2189 | return 1; |
2153 | } | 2190 | } |
@@ -2191,7 +2228,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, | |||
2191 | 2228 | ||
2192 | dprintk((KERN_NOTICE | 2229 | dprintk((KERN_NOTICE |
2193 | ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n", | 2230 | ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n", |
2194 | sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors)); | 2231 | sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors)); |
2195 | 2232 | ||
2196 | return 0; | 2233 | return 0; |
2197 | } | 2234 | } |
@@ -2200,115 +2237,78 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, | |||
2200 | * | 2237 | * |
2201 | */ | 2238 | */ |
2202 | int | 2239 | int |
2203 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) | 2240 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id) |
2204 | { | 2241 | { |
2242 | struct inactive_raid_component_info *component_info; | ||
2205 | int i; | 2243 | int i; |
2244 | int rc = 0; | ||
2206 | 2245 | ||
2207 | if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) | 2246 | if (!ioc->raid_data.pIocPg3) |
2208 | return 0; | 2247 | goto out; |
2209 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { | 2248 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { |
2210 | if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) | 2249 | if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) && |
2211 | return 1; | 2250 | (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) { |
2212 | } | 2251 | rc = 1; |
2213 | return 0; | 2252 | goto out; |
2214 | } | 2253 | } |
2215 | EXPORT_SYMBOL(mptscsih_is_phys_disk); | ||
2216 | |||
2217 | int | ||
2218 | mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid) | ||
2219 | { | ||
2220 | int i; | ||
2221 | |||
2222 | if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3) | ||
2223 | return -ENXIO; | ||
2224 | |||
2225 | for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) { | ||
2226 | if (physdiskid == | ||
2227 | hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) | ||
2228 | return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum; | ||
2229 | } | 2254 | } |
2230 | 2255 | ||
2231 | return -ENXIO; | 2256 | /* |
2232 | } | 2257 | * Check inactive list for matching phys disks |
2233 | EXPORT_SYMBOL(mptscsih_raid_id_to_num); | 2258 | */ |
2259 | if (list_empty(&ioc->raid_data.inactive_list)) | ||
2260 | goto out; | ||
2234 | 2261 | ||
2235 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2262 | down(&ioc->raid_data.inactive_list_mutex); |
2236 | /* | 2263 | list_for_each_entry(component_info, &ioc->raid_data.inactive_list, |
2237 | * OS entry point to allow host driver to alloc memory | 2264 | list) { |
2238 | * for each scsi target. Called once per device the bus scan. | 2265 | if ((component_info->d.PhysDiskID == id) && |
2239 | * Return non-zero if allocation fails. | 2266 | (component_info->d.PhysDiskBus == channel)) |
2240 | */ | 2267 | rc = 1; |
2241 | int | 2268 | } |
2242 | mptscsih_target_alloc(struct scsi_target *starget) | 2269 | up(&ioc->raid_data.inactive_list_mutex); |
2243 | { | ||
2244 | VirtTarget *vtarget; | ||
2245 | 2270 | ||
2246 | vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); | 2271 | out: |
2247 | if (!vtarget) | 2272 | return rc; |
2248 | return -ENOMEM; | ||
2249 | starget->hostdata = vtarget; | ||
2250 | vtarget->starget = starget; | ||
2251 | return 0; | ||
2252 | } | 2273 | } |
2274 | EXPORT_SYMBOL(mptscsih_is_phys_disk); | ||
2253 | 2275 | ||
2254 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2276 | u8 |
2255 | /* | 2277 | mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id) |
2256 | * OS entry point to allow host driver to alloc memory | ||
2257 | * for each scsi device. Called once per device the bus scan. | ||
2258 | * Return non-zero if allocation fails. | ||
2259 | */ | ||
2260 | int | ||
2261 | mptscsih_slave_alloc(struct scsi_device *sdev) | ||
2262 | { | 2278 | { |
2263 | struct Scsi_Host *host = sdev->host; | 2279 | struct inactive_raid_component_info *component_info; |
2264 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 2280 | int i; |
2265 | VirtTarget *vtarget; | 2281 | int rc = -ENXIO; |
2266 | VirtDevice *vdev; | ||
2267 | struct scsi_target *starget; | ||
2268 | 2282 | ||
2269 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); | 2283 | if (!ioc->raid_data.pIocPg3) |
2270 | if (!vdev) { | 2284 | goto out; |
2271 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | 2285 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { |
2272 | hd->ioc->name, sizeof(VirtDevice)); | 2286 | if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) && |
2273 | return -ENOMEM; | 2287 | (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) { |
2288 | rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum; | ||
2289 | goto out; | ||
2290 | } | ||
2274 | } | 2291 | } |
2275 | 2292 | ||
2276 | vdev->lun = sdev->lun; | 2293 | /* |
2277 | sdev->hostdata = vdev; | 2294 | * Check inactive list for matching phys disks |
2278 | 2295 | */ | |
2279 | starget = scsi_target(sdev); | 2296 | if (list_empty(&ioc->raid_data.inactive_list)) |
2280 | vtarget = starget->hostdata; | 2297 | goto out; |
2281 | 2298 | ||
2282 | vdev->vtarget = vtarget; | 2299 | down(&ioc->raid_data.inactive_list_mutex); |
2283 | 2300 | list_for_each_entry(component_info, &ioc->raid_data.inactive_list, | |
2284 | if (vtarget->num_luns == 0) { | 2301 | list) { |
2285 | hd->Targets[sdev->id] = vtarget; | 2302 | if ((component_info->d.PhysDiskID == id) && |
2286 | vtarget->ioc_id = hd->ioc->id; | 2303 | (component_info->d.PhysDiskBus == channel)) |
2287 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | 2304 | rc = component_info->d.PhysDiskNum; |
2288 | vtarget->target_id = sdev->id; | ||
2289 | vtarget->bus_id = sdev->channel; | ||
2290 | if (hd->ioc->bus_type == SPI && sdev->channel == 0 && | ||
2291 | hd->ioc->raid_data.isRaid & (1 << sdev->id)) { | ||
2292 | vtarget->raidVolume = 1; | ||
2293 | ddvtprintk((KERN_INFO | ||
2294 | "RAID Volume @ id %d\n", sdev->id)); | ||
2295 | } | ||
2296 | } | 2305 | } |
2297 | vtarget->num_luns++; | 2306 | up(&ioc->raid_data.inactive_list_mutex); |
2298 | return 0; | ||
2299 | } | ||
2300 | 2307 | ||
2301 | /* | 2308 | out: |
2302 | * OS entry point to allow for host driver to free allocated memory | 2309 | return rc; |
2303 | * Called if no device present or device being unloaded | ||
2304 | */ | ||
2305 | void | ||
2306 | mptscsih_target_destroy(struct scsi_target *starget) | ||
2307 | { | ||
2308 | if (starget->hostdata) | ||
2309 | kfree(starget->hostdata); | ||
2310 | starget->hostdata = NULL; | ||
2311 | } | 2310 | } |
2311 | EXPORT_SYMBOL(mptscsih_raid_id_to_num); | ||
2312 | 2312 | ||
2313 | /* | 2313 | /* |
2314 | * OS entry point to allow for host driver to free allocated memory | 2314 | * OS entry point to allow for host driver to free allocated memory |
@@ -2328,11 +2328,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev) | |||
2328 | vdevice = sdev->hostdata; | 2328 | vdevice = sdev->hostdata; |
2329 | 2329 | ||
2330 | mptscsih_search_running_cmds(hd, vdevice); | 2330 | mptscsih_search_running_cmds(hd, vdevice); |
2331 | vtarget->luns[0] &= ~(1 << vdevice->lun); | ||
2332 | vtarget->num_luns--; | 2331 | vtarget->num_luns--; |
2333 | if (vtarget->num_luns == 0) { | ||
2334 | hd->Targets[sdev->id] = NULL; | ||
2335 | } | ||
2336 | mptscsih_synchronize_cache(hd, vdevice); | 2332 | mptscsih_synchronize_cache(hd, vdevice); |
2337 | kfree(vdevice); | 2333 | kfree(vdevice); |
2338 | sdev->hostdata = NULL; | 2334 | sdev->hostdata = NULL; |
@@ -2394,15 +2390,14 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2394 | VirtDevice *vdevice; | 2390 | VirtDevice *vdevice; |
2395 | struct scsi_target *starget; | 2391 | struct scsi_target *starget; |
2396 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; | 2392 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; |
2397 | int indexed_lun, lun_index; | ||
2398 | 2393 | ||
2399 | starget = scsi_target(sdev); | 2394 | starget = scsi_target(sdev); |
2400 | vtarget = starget->hostdata; | 2395 | vtarget = starget->hostdata; |
2401 | vdevice = sdev->hostdata; | 2396 | vdevice = sdev->hostdata; |
2402 | 2397 | ||
2403 | dsprintk((MYIOC_s_INFO_FMT | 2398 | dsprintk((MYIOC_s_INFO_FMT |
2404 | "device @ %p, id=%d, LUN=%d, channel=%d\n", | 2399 | "device @ %p, channel=%d, id=%d, lun=%d\n", |
2405 | hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel)); | 2400 | hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun)); |
2406 | if (hd->ioc->bus_type == SPI) | 2401 | if (hd->ioc->bus_type == SPI) |
2407 | dsprintk((MYIOC_s_INFO_FMT | 2402 | dsprintk((MYIOC_s_INFO_FMT |
2408 | "sdtr %d wdtr %d ppr %d inq length=%d\n", | 2403 | "sdtr %d wdtr %d ppr %d inq length=%d\n", |
@@ -2415,11 +2410,7 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2415 | goto slave_configure_exit; | 2410 | goto slave_configure_exit; |
2416 | } | 2411 | } |
2417 | 2412 | ||
2418 | vdevice->configured_lun=1; | 2413 | vdevice->configured_lun = 1; |
2419 | lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */ | ||
2420 | indexed_lun = (vdevice->lun % 32); | ||
2421 | vtarget->luns[lun_index] |= (1 << indexed_lun); | ||
2422 | mptscsih_initTarget(hd, vtarget, sdev); | ||
2423 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); | 2414 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); |
2424 | 2415 | ||
2425 | dsprintk((MYIOC_s_INFO_FMT | 2416 | dsprintk((MYIOC_s_INFO_FMT |
@@ -2683,285 +2674,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
2683 | 2674 | ||
2684 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2675 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2685 | /* | 2676 | /* |
2686 | * mptscsih_initTarget - Target, LUN alloc/free functionality. | ||
2687 | * @hd: Pointer to MPT_SCSI_HOST structure | ||
2688 | * @vtarget: per target private data | ||
2689 | * @sdev: SCSI device | ||
2690 | * | ||
2691 | * NOTE: It's only SAFE to call this routine if data points to | ||
2692 | * sane & valid STANDARD INQUIRY data! | ||
2693 | * | ||
2694 | * Allocate and initialize memory for this target. | ||
2695 | * Save inquiry data. | ||
2696 | * | ||
2697 | */ | ||
2698 | static void | ||
2699 | mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, | ||
2700 | struct scsi_device *sdev) | ||
2701 | { | ||
2702 | dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", | ||
2703 | hd->ioc->name, vtarget->bus_id, vtarget->target_id, | ||
2704 | sdev->lun, hd)); | ||
2705 | |||
2706 | /* Is LUN supported? If so, upper 2 bits will be 0 | ||
2707 | * in first byte of inquiry data. | ||
2708 | */ | ||
2709 | if (sdev->inq_periph_qual != 0) | ||
2710 | return; | ||
2711 | |||
2712 | if (vtarget == NULL) | ||
2713 | return; | ||
2714 | |||
2715 | vtarget->type = sdev->type; | ||
2716 | |||
2717 | if (hd->ioc->bus_type != SPI) | ||
2718 | return; | ||
2719 | |||
2720 | if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { | ||
2721 | /* Treat all Processors as SAF-TE if | ||
2722 | * command line option is set */ | ||
2723 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
2724 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); | ||
2725 | }else if ((sdev->type == TYPE_PROCESSOR) && | ||
2726 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { | ||
2727 | if (sdev->inquiry_len > 49 ) { | ||
2728 | if (sdev->inquiry[44] == 'S' && | ||
2729 | sdev->inquiry[45] == 'A' && | ||
2730 | sdev->inquiry[46] == 'F' && | ||
2731 | sdev->inquiry[47] == '-' && | ||
2732 | sdev->inquiry[48] == 'T' && | ||
2733 | sdev->inquiry[49] == 'E' ) { | ||
2734 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
2735 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); | ||
2736 | } | ||
2737 | } | ||
2738 | } | ||
2739 | mptscsih_setTargetNegoParms(hd, vtarget, sdev); | ||
2740 | } | ||
2741 | |||
2742 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2743 | /* | ||
2744 | * Update the target negotiation parameters based on the | ||
2745 | * the Inquiry data, adapter capabilities, and NVRAM settings. | ||
2746 | * | ||
2747 | */ | ||
2748 | static void | ||
2749 | mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | ||
2750 | struct scsi_device *sdev) | ||
2751 | { | ||
2752 | SpiCfgData *pspi_data = &hd->ioc->spi_data; | ||
2753 | int id = (int) target->target_id; | ||
2754 | int nvram; | ||
2755 | u8 width = MPT_NARROW; | ||
2756 | u8 factor = MPT_ASYNC; | ||
2757 | u8 offset = 0; | ||
2758 | u8 nfactor; | ||
2759 | u8 noQas = 1; | ||
2760 | |||
2761 | target->negoFlags = pspi_data->noQas; | ||
2762 | |||
2763 | /* noQas == 0 => device supports QAS. */ | ||
2764 | |||
2765 | if (sdev->scsi_level < SCSI_2) { | ||
2766 | width = 0; | ||
2767 | factor = MPT_ULTRA2; | ||
2768 | offset = pspi_data->maxSyncOffset; | ||
2769 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
2770 | } else { | ||
2771 | if (scsi_device_wide(sdev)) { | ||
2772 | width = 1; | ||
2773 | } | ||
2774 | |||
2775 | if (scsi_device_sync(sdev)) { | ||
2776 | factor = pspi_data->minSyncFactor; | ||
2777 | if (!scsi_device_dt(sdev)) | ||
2778 | factor = MPT_ULTRA2; | ||
2779 | else { | ||
2780 | if (!scsi_device_ius(sdev) && | ||
2781 | !scsi_device_qas(sdev)) | ||
2782 | factor = MPT_ULTRA160; | ||
2783 | else { | ||
2784 | factor = MPT_ULTRA320; | ||
2785 | if (scsi_device_qas(sdev)) { | ||
2786 | ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id)); | ||
2787 | noQas = 0; | ||
2788 | } | ||
2789 | if (sdev->type == TYPE_TAPE && | ||
2790 | scsi_device_ius(sdev)) | ||
2791 | target->negoFlags |= MPT_TAPE_NEGO_IDP; | ||
2792 | } | ||
2793 | } | ||
2794 | offset = pspi_data->maxSyncOffset; | ||
2795 | |||
2796 | /* If RAID, never disable QAS | ||
2797 | * else if non RAID, do not disable | ||
2798 | * QAS if bit 1 is set | ||
2799 | * bit 1 QAS support, non-raid only | ||
2800 | * bit 0 IU support | ||
2801 | */ | ||
2802 | if (target->raidVolume == 1) { | ||
2803 | noQas = 0; | ||
2804 | } | ||
2805 | } else { | ||
2806 | factor = MPT_ASYNC; | ||
2807 | offset = 0; | ||
2808 | } | ||
2809 | } | ||
2810 | |||
2811 | if (!sdev->tagged_supported) { | ||
2812 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
2813 | } | ||
2814 | |||
2815 | /* Update tflags based on NVRAM settings. (SCSI only) | ||
2816 | */ | ||
2817 | if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
2818 | nvram = pspi_data->nvram[id]; | ||
2819 | nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; | ||
2820 | |||
2821 | if (width) | ||
2822 | width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; | ||
2823 | |||
2824 | if (offset > 0) { | ||
2825 | /* Ensure factor is set to the | ||
2826 | * maximum of: adapter, nvram, inquiry | ||
2827 | */ | ||
2828 | if (nfactor) { | ||
2829 | if (nfactor < pspi_data->minSyncFactor ) | ||
2830 | nfactor = pspi_data->minSyncFactor; | ||
2831 | |||
2832 | factor = max(factor, nfactor); | ||
2833 | if (factor == MPT_ASYNC) | ||
2834 | offset = 0; | ||
2835 | } else { | ||
2836 | offset = 0; | ||
2837 | factor = MPT_ASYNC; | ||
2838 | } | ||
2839 | } else { | ||
2840 | factor = MPT_ASYNC; | ||
2841 | } | ||
2842 | } | ||
2843 | |||
2844 | /* Make sure data is consistent | ||
2845 | */ | ||
2846 | if ((!width) && (factor < MPT_ULTRA2)) { | ||
2847 | factor = MPT_ULTRA2; | ||
2848 | } | ||
2849 | |||
2850 | /* Save the data to the target structure. | ||
2851 | */ | ||
2852 | target->minSyncFactor = factor; | ||
2853 | target->maxOffset = offset; | ||
2854 | target->maxWidth = width; | ||
2855 | |||
2856 | target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; | ||
2857 | |||
2858 | /* Disable unused features. | ||
2859 | */ | ||
2860 | if (!width) | ||
2861 | target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; | ||
2862 | |||
2863 | if (!offset) | ||
2864 | target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; | ||
2865 | |||
2866 | if ( factor > MPT_ULTRA320 ) | ||
2867 | noQas = 0; | ||
2868 | |||
2869 | if (noQas && (pspi_data->noQas == 0)) { | ||
2870 | pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; | ||
2871 | target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | ||
2872 | |||
2873 | /* Disable QAS in a mixed configuration case | ||
2874 | */ | ||
2875 | |||
2876 | ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); | ||
2877 | } | ||
2878 | } | ||
2879 | |||
2880 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2881 | |||
2882 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2883 | /* | ||
2884 | * SCSI Config Page functionality ... | ||
2885 | */ | ||
2886 | |||
2887 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2888 | /* mptscsih_writeIOCPage4 - write IOC Page 4 | ||
2889 | * @hd: Pointer to a SCSI Host Structure | ||
2890 | * @target_id: write IOC Page4 for this ID & Bus | ||
2891 | * | ||
2892 | * Return: -EAGAIN if unable to obtain a Message Frame | ||
2893 | * or 0 if success. | ||
2894 | * | ||
2895 | * Remark: We do not wait for a return, write pages sequentially. | ||
2896 | */ | ||
2897 | static int | ||
2898 | mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) | ||
2899 | { | ||
2900 | MPT_ADAPTER *ioc = hd->ioc; | ||
2901 | Config_t *pReq; | ||
2902 | IOCPage4_t *IOCPage4Ptr; | ||
2903 | MPT_FRAME_HDR *mf; | ||
2904 | dma_addr_t dataDma; | ||
2905 | u16 req_idx; | ||
2906 | u32 frameOffset; | ||
2907 | u32 flagsLength; | ||
2908 | int ii; | ||
2909 | |||
2910 | /* Get a MF for this command. | ||
2911 | */ | ||
2912 | if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { | ||
2913 | dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", | ||
2914 | ioc->name)); | ||
2915 | return -EAGAIN; | ||
2916 | } | ||
2917 | |||
2918 | /* Set the request and the data pointers. | ||
2919 | * Place data at end of MF. | ||
2920 | */ | ||
2921 | pReq = (Config_t *)mf; | ||
2922 | |||
2923 | req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); | ||
2924 | frameOffset = ioc->req_sz - sizeof(IOCPage4_t); | ||
2925 | |||
2926 | /* Complete the request frame (same for all requests). | ||
2927 | */ | ||
2928 | pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
2929 | pReq->Reserved = 0; | ||
2930 | pReq->ChainOffset = 0; | ||
2931 | pReq->Function = MPI_FUNCTION_CONFIG; | ||
2932 | pReq->ExtPageLength = 0; | ||
2933 | pReq->ExtPageType = 0; | ||
2934 | pReq->MsgFlags = 0; | ||
2935 | for (ii=0; ii < 8; ii++) { | ||
2936 | pReq->Reserved2[ii] = 0; | ||
2937 | } | ||
2938 | |||
2939 | IOCPage4Ptr = ioc->spi_data.pIocPg4; | ||
2940 | dataDma = ioc->spi_data.IocPg4_dma; | ||
2941 | ii = IOCPage4Ptr->ActiveSEP++; | ||
2942 | IOCPage4Ptr->SEP[ii].SEPTargetID = target_id; | ||
2943 | IOCPage4Ptr->SEP[ii].SEPBus = bus; | ||
2944 | pReq->Header = IOCPage4Ptr->Header; | ||
2945 | pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 )); | ||
2946 | |||
2947 | /* Add a SGE to the config request. | ||
2948 | */ | ||
2949 | flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | | ||
2950 | (IOCPage4Ptr->Header.PageLength + ii) * 4; | ||
2951 | |||
2952 | mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); | ||
2953 | |||
2954 | dinitprintk((MYIOC_s_INFO_FMT | ||
2955 | "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", | ||
2956 | ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus)); | ||
2957 | |||
2958 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | ||
2959 | |||
2960 | return 0; | ||
2961 | } | ||
2962 | |||
2963 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2964 | /* | ||
2965 | * Bus Scan and Domain Validation functionality ... | 2677 | * Bus Scan and Domain Validation functionality ... |
2966 | */ | 2678 | */ |
2967 | 2679 | ||
@@ -3343,7 +3055,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3343 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; | 3055 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; |
3344 | } else { | 3056 | } else { |
3345 | pScsiReq->TargetID = io->id; | 3057 | pScsiReq->TargetID = io->id; |
3346 | pScsiReq->Bus = io->bus; | 3058 | pScsiReq->Bus = io->channel; |
3347 | pScsiReq->ChainOffset = 0; | 3059 | pScsiReq->ChainOffset = 0; |
3348 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; | 3060 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; |
3349 | } | 3061 | } |
@@ -3356,9 +3068,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3356 | pScsiReq->MsgFlags = mpt_msg_flags(); | 3068 | pScsiReq->MsgFlags = mpt_msg_flags(); |
3357 | /* MsgContext set in mpt_get_msg_fram call */ | 3069 | /* MsgContext set in mpt_get_msg_fram call */ |
3358 | 3070 | ||
3359 | for (ii=0; ii < 8; ii++) | 3071 | int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN); |
3360 | pScsiReq->LUN[ii] = 0; | ||
3361 | pScsiReq->LUN[1] = io->lun; | ||
3362 | 3072 | ||
3363 | if (io->flags & MPT_ICFLAG_TAGGED_CMD) | 3073 | if (io->flags & MPT_ICFLAG_TAGGED_CMD) |
3364 | pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ); | 3074 | pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ); |
@@ -3379,7 +3089,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3379 | + (my_idx * MPT_SENSE_BUFFER_ALLOC)); | 3089 | + (my_idx * MPT_SENSE_BUFFER_ALLOC)); |
3380 | 3090 | ||
3381 | ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n", | 3091 | ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n", |
3382 | hd->ioc->name, cmd, io->bus, io->id, io->lun)); | 3092 | hd->ioc->name, cmd, io->channel, io->id, io->lun)); |
3383 | 3093 | ||
3384 | if (dir == MPI_SCSIIO_CONTROL_READ) { | 3094 | if (dir == MPI_SCSIIO_CONTROL_READ) { |
3385 | mpt_add_sge((char *) &pScsiReq->SGL, | 3095 | mpt_add_sge((char *) &pScsiReq->SGL, |
@@ -3462,9 +3172,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
3462 | iocmd.data_dma = -1; | 3172 | iocmd.data_dma = -1; |
3463 | iocmd.size = 0; | 3173 | iocmd.size = 0; |
3464 | iocmd.rsvd = iocmd.rsvd2 = 0; | 3174 | iocmd.rsvd = iocmd.rsvd2 = 0; |
3465 | iocmd.bus = vdevice->vtarget->bus_id; | 3175 | iocmd.channel = vdevice->vtarget->channel; |
3466 | iocmd.id = vdevice->vtarget->target_id; | 3176 | iocmd.id = vdevice->vtarget->id; |
3467 | iocmd.lun = (u8)vdevice->lun; | 3177 | iocmd.lun = vdevice->lun; |
3468 | 3178 | ||
3469 | if ((vdevice->vtarget->type == TYPE_DISK) && | 3179 | if ((vdevice->vtarget->type == TYPE_DISK) && |
3470 | (vdevice->configured_lun)) | 3180 | (vdevice->configured_lun)) |
@@ -3480,9 +3190,6 @@ EXPORT_SYMBOL(mptscsih_resume); | |||
3480 | EXPORT_SYMBOL(mptscsih_proc_info); | 3190 | EXPORT_SYMBOL(mptscsih_proc_info); |
3481 | EXPORT_SYMBOL(mptscsih_info); | 3191 | EXPORT_SYMBOL(mptscsih_info); |
3482 | EXPORT_SYMBOL(mptscsih_qcmd); | 3192 | EXPORT_SYMBOL(mptscsih_qcmd); |
3483 | EXPORT_SYMBOL(mptscsih_target_alloc); | ||
3484 | EXPORT_SYMBOL(mptscsih_slave_alloc); | ||
3485 | EXPORT_SYMBOL(mptscsih_target_destroy); | ||
3486 | EXPORT_SYMBOL(mptscsih_slave_destroy); | 3193 | EXPORT_SYMBOL(mptscsih_slave_destroy); |
3487 | EXPORT_SYMBOL(mptscsih_slave_configure); | 3194 | EXPORT_SYMBOL(mptscsih_slave_configure); |
3488 | EXPORT_SYMBOL(mptscsih_abort); | 3195 | EXPORT_SYMBOL(mptscsih_abort); |