aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptscsih.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r--drivers/message/fusion/mptscsih.c997
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");
79MODULE_VERSION(my_VERSION); 79MODULE_VERSION(my_VERSION);
80 80
81/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 81/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
82
83typedef 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
105typedef 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);
131static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); 94static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
132static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); 95static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
133 96
134static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); 97static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
135 98
136int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 99int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
137int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 100int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
138 101
139static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
140static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
141static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
142int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 102int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
143static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 103static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
144static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); 104static 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 **/
502static void
503mptscsih_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 **/
1512int 1557int
1513mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) 1558mptscsih_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 **/
1639static int 1666static int
1640mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) 1667mptscsih_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
1709static int 1753static 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 **/
1732int 1776int
1733mptscsih_abort(struct scsi_cmnd * SCpnt) 1777mptscsih_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 **/
1823int 1861int
1824mptscsih_dev_reset(struct scsi_cmnd * SCpnt) 1862mptscsih_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 **/
1874int 1909int
1875mptscsih_bus_reset(struct scsi_cmnd * SCpnt) 1910mptscsih_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 **/
2070int 2100int
2071mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 2101mptscsih_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 */
2202int 2239int
2203mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) 2240mptscsih_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 }
2215EXPORT_SYMBOL(mptscsih_is_phys_disk);
2216
2217int
2218mptscsih_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
2233EXPORT_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;
2241int 2268 }
2242mptscsih_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}
2274EXPORT_SYMBOL(mptscsih_is_phys_disk);
2253 2275
2254/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2276u8
2255/* 2277mptscsih_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 */
2260int
2261mptscsih_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 */
2305void
2306mptscsih_target_destroy(struct scsi_target *starget)
2307{
2308 if (starget->hostdata)
2309 kfree(starget->hostdata);
2310 starget->hostdata = NULL;
2311} 2310}
2311EXPORT_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 */
2698static void
2699mptscsih_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 */
2748static void
2749mptscsih_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 */
2897static int
2898mptscsih_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);
3480EXPORT_SYMBOL(mptscsih_proc_info); 3190EXPORT_SYMBOL(mptscsih_proc_info);
3481EXPORT_SYMBOL(mptscsih_info); 3191EXPORT_SYMBOL(mptscsih_info);
3482EXPORT_SYMBOL(mptscsih_qcmd); 3192EXPORT_SYMBOL(mptscsih_qcmd);
3483EXPORT_SYMBOL(mptscsih_target_alloc);
3484EXPORT_SYMBOL(mptscsih_slave_alloc);
3485EXPORT_SYMBOL(mptscsih_target_destroy);
3486EXPORT_SYMBOL(mptscsih_slave_destroy); 3193EXPORT_SYMBOL(mptscsih_slave_destroy);
3487EXPORT_SYMBOL(mptscsih_slave_configure); 3194EXPORT_SYMBOL(mptscsih_slave_configure);
3488EXPORT_SYMBOL(mptscsih_abort); 3195EXPORT_SYMBOL(mptscsih_abort);