aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptscsih.c
diff options
context:
space:
mode:
authorMoore, Eric Dean <Eric.Moore@lsil.com>2005-09-14 20:09:10 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-19 13:45:38 -0400
commit466544d8898fc87ed6e2e62ac14af7c50ab7a1a4 (patch)
treea23688bc1424a2af986482bac159768d625b5deb /drivers/message/fusion/mptscsih.c
parent0c33b27deb93178f10778b3d2669af1674793cef (diff)
[SCSI] fusion SAS support (mptsas driver) updates
Summary of Changes: * splitting mpt_interrupt per Christophs suggestion about a month ago * rename ScsiCfgData to SpiCfgData structure, then move all the raid related info into new structure called RaidCfgData. This is done because SAS supports RAID, as well as SPI, so the raid stuff should be seperate. * incorrect timeout calculation for cntdn inside WaitForDoorbellAck and WaitForDoortbellInt * add support for interpreting SAS Log Info * Increase Event Log Size from 0xA to 0x32 * Fix bug in mptsas/mptfc/mptspi - when controller has Initiator Mode Disabled, and only running in TargetMode, the mptctl would panic when loading. The fix is to return 0, instead of -ENODEV, in SCSI LLD respective probe routines * Fix bug in mptlan.c - driver will panic if there is host reset, due to dev being set to zero in mpt_lan_ioc_reset * Fix's for SPI - Echo Buffer * Several fix's in mptscsih_io_done - FCP Response info, RESIDUAL_MISMATCH, Data Underrun, etc. * Cleanup Error Handling - EH handlers, mptscsih_flush_cmds, and zeroing out ScsiLookup from mptscsih_qcmd * Cleanup asyn event handling from mptscsih -> mptscsih_event_process. Also added support for SAS Persistent Table Full, an asyn event Signed-off-by: Eric Moore <Eric.Moore@lsil.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r--drivers/message/fusion/mptscsih.c447
1 files changed, 233 insertions, 214 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 58b5fdee009a..8dd25aac5355 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -93,8 +93,9 @@ typedef struct _BIG_SENSE_BUF {
93 93
94#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ 94#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
95#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ 95#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
96#define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */ 96#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
97#define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */ 97#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
98#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
98#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ 99#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
99#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ 100#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
100 101
@@ -159,6 +160,8 @@ int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR
159static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 160static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
160static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); 161static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
161 162
163static struct work_struct mptscsih_persistTask;
164
162#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 165#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
163static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); 166static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
164static void mptscsih_domainValidation(void *hd); 167static void mptscsih_domainValidation(void *hd);
@@ -167,6 +170,7 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
167static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); 170static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
168static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); 171static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
169static void mptscsih_fillbuf(char *buffer, int size, int index, int width); 172static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
173static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
170#endif 174#endif
171 175
172void mptscsih_remove(struct pci_dev *); 176void mptscsih_remove(struct pci_dev *);
@@ -606,11 +610,24 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
606 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); 610 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
607 sc->resid = sc->request_bufflen - xfer_cnt; 611 sc->resid = sc->request_bufflen - xfer_cnt;
608 612
613 /*
614 * if we get a data underrun indication, yet no data was
615 * transferred and the SCSI status indicates that the
616 * command was never started, change the data underrun
617 * to success
618 */
619 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
620 (scsi_status == MPI_SCSI_STATUS_BUSY ||
621 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
622 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
623 status = MPI_IOCSTATUS_SUCCESS;
624 }
625
609 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" 626 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
610 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" 627 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
611 "resid=%d bufflen=%d xfer_cnt=%d\n", 628 "resid=%d bufflen=%d xfer_cnt=%d\n",
612 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], 629 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
613 status, scsi_state, scsi_status, sc->resid, 630 status, scsi_state, scsi_status, sc->resid,
614 sc->request_bufflen, xfer_cnt)); 631 sc->request_bufflen, xfer_cnt));
615 632
616 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) 633 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
@@ -619,8 +636,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
619 /* 636 /*
620 * Look for + dump FCP ResponseInfo[]! 637 * Look for + dump FCP ResponseInfo[]!
621 */ 638 */
622 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) { 639 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
623 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n", 640 pScsiReply->ResponseInfo) {
641 printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
642 "FCP_ResponseInfo=%08xh\n",
643 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
624 le32_to_cpu(pScsiReply->ResponseInfo)); 644 le32_to_cpu(pScsiReply->ResponseInfo));
625 } 645 }
626 646
@@ -661,23 +681,13 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
661 break; 681 break;
662 682
663 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 683 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
664 if ( xfer_cnt >= sc->underflow ) { 684 sc->resid = sc->request_bufflen - xfer_cnt;
665 /* Sufficient data transfer occurred */ 685 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
686 sc->result=DID_SOFT_ERROR << 16;
687 else /* Sufficient data transfer occurred */
666 sc->result = (DID_OK << 16) | scsi_status; 688 sc->result = (DID_OK << 16) | scsi_status;
667 } else if ( xfer_cnt == 0 ) { 689 dreplyprintk((KERN_NOTICE
668 /* A CRC Error causes this condition; retry */ 690 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
669 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
670 (CHECK_CONDITION << 1);
671 sc->sense_buffer[0] = 0x70;
672 sc->sense_buffer[2] = NO_SENSE;
673 sc->sense_buffer[12] = 0;
674 sc->sense_buffer[13] = 0;
675 } else {
676 sc->result = DID_SOFT_ERROR << 16;
677 }
678 dreplyprintk((KERN_NOTICE
679 "RESIDUAL_MISMATCH: result=%x on id=%d\n",
680 sc->result, sc->device->id));
681 break; 691 break;
682 692
683 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 693 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
@@ -692,7 +702,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
692 ; 702 ;
693 } else { 703 } else {
694 if (xfer_cnt < sc->underflow) { 704 if (xfer_cnt < sc->underflow) {
695 sc->result = DID_SOFT_ERROR << 16; 705 if (scsi_status == SAM_STAT_BUSY)
706 sc->result = SAM_STAT_BUSY;
707 else
708 sc->result = DID_SOFT_ERROR << 16;
696 } 709 }
697 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) { 710 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
698 /* What to do? 711 /* What to do?
@@ -717,8 +730,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
717 730
718 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 731 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
719 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ 732 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
720 scsi_status = pScsiReply->SCSIStatus; 733 if (scsi_status == MPI_SCSI_STATUS_BUSY)
721 sc->result = (DID_OK << 16) | scsi_status; 734 sc->result = (DID_BUS_BUSY << 16) | scsi_status;
735 else
736 sc->result = (DID_OK << 16) | scsi_status;
722 if (scsi_state == 0) { 737 if (scsi_state == 0) {
723 ; 738 ;
724 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { 739 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
@@ -890,12 +905,13 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
890 SCSIIORequest_t *mf = NULL; 905 SCSIIORequest_t *mf = NULL;
891 int ii; 906 int ii;
892 int max = hd->ioc->req_depth; 907 int max = hd->ioc->req_depth;
908 struct scsi_cmnd *sc;
893 909
894 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", 910 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
895 target, lun, max)); 911 target, lun, max));
896 912
897 for (ii=0; ii < max; ii++) { 913 for (ii=0; ii < max; ii++) {
898 if (hd->ScsiLookup[ii] != NULL) { 914 if ((sc = hd->ScsiLookup[ii]) != NULL) {
899 915
900 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); 916 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
901 917
@@ -910,9 +926,22 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
910 hd->ScsiLookup[ii] = NULL; 926 hd->ScsiLookup[ii] = NULL;
911 mptscsih_freeChainBuffers(hd->ioc, ii); 927 mptscsih_freeChainBuffers(hd->ioc, ii);
912 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); 928 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
929 if (sc->use_sg) {
930 pci_unmap_sg(hd->ioc->pcidev,
931 (struct scatterlist *) sc->request_buffer,
932 sc->use_sg,
933 sc->sc_data_direction);
934 } else if (sc->request_bufflen) {
935 pci_unmap_single(hd->ioc->pcidev,
936 sc->SCp.dma_handle,
937 sc->request_bufflen,
938 sc->sc_data_direction);
939 }
940 sc->host_scribble = NULL;
941 sc->result = DID_NO_CONNECT << 16;
942 sc->scsi_done(sc);
913 } 943 }
914 } 944 }
915
916 return; 945 return;
917} 946}
918 947
@@ -967,8 +996,10 @@ mptscsih_remove(struct pci_dev *pdev)
967 unsigned long flags; 996 unsigned long flags;
968 int sz1; 997 int sz1;
969 998
970 if(!host) 999 if(!host) {
1000 mpt_detach(pdev);
971 return; 1001 return;
1002 }
972 1003
973 scsi_remove_host(host); 1004 scsi_remove_host(host);
974 1005
@@ -1422,6 +1453,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1422 return 0; 1453 return 0;
1423 1454
1424 fail: 1455 fail:
1456 hd->ScsiLookup[my_idx] = NULL;
1425 mptscsih_freeChainBuffers(hd->ioc, my_idx); 1457 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1426 mpt_free_msg_frame(hd->ioc, mf); 1458 mpt_free_msg_frame(hd->ioc, mf);
1427 return SCSI_MLQUEUE_HOST_BUSY; 1459 return SCSI_MLQUEUE_HOST_BUSY;
@@ -1709,24 +1741,23 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1709 MPT_FRAME_HDR *mf; 1741 MPT_FRAME_HDR *mf;
1710 u32 ctx2abort; 1742 u32 ctx2abort;
1711 int scpnt_idx; 1743 int scpnt_idx;
1744 int retval;
1712 1745
1713 /* If we can't locate our host adapter structure, return FAILED status. 1746 /* If we can't locate our host adapter structure, return FAILED status.
1714 */ 1747 */
1715 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) { 1748 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
1716 SCpnt->result = DID_RESET << 16; 1749 SCpnt->result = DID_RESET << 16;
1717 SCpnt->scsi_done(SCpnt); 1750 SCpnt->scsi_done(SCpnt);
1718 dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: " 1751 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
1719 "Can't locate host! (sc=%p)\n", 1752 "Can't locate host! (sc=%p)\n",
1720 SCpnt)); 1753 SCpnt));
1721 return FAILED; 1754 return FAILED;
1722 } 1755 }
1723 1756
1724 ioc = hd->ioc; 1757 ioc = hd->ioc;
1725 if (hd->resetPending) 1758 if (hd->resetPending) {
1726 return FAILED; 1759 return FAILED;
1727 1760 }
1728 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
1729 hd->ioc->name, SCpnt);
1730 1761
1731 if (hd->timeouts < -1) 1762 if (hd->timeouts < -1)
1732 hd->timeouts++; 1763 hd->timeouts++;
@@ -1734,16 +1765,20 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1734 /* Find this command 1765 /* Find this command
1735 */ 1766 */
1736 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { 1767 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1737 /* Cmd not found in ScsiLookup. 1768 /* Cmd not found in ScsiLookup.
1738 * Do OS callback. 1769 * Do OS callback.
1739 */ 1770 */
1740 SCpnt->result = DID_RESET << 16; 1771 SCpnt->result = DID_RESET << 16;
1741 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: " 1772 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
1742 "Command not in the active list! (sc=%p)\n", 1773 "Command not in the active list! (sc=%p)\n",
1743 hd->ioc->name, SCpnt)); 1774 hd->ioc->name, SCpnt));
1744 return SUCCESS; 1775 return SUCCESS;
1745 } 1776 }
1746 1777
1778 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1779 hd->ioc->name, SCpnt);
1780 scsi_print_command(SCpnt);
1781
1747 /* Most important! Set TaskMsgContext to SCpnt's MsgContext! 1782 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1748 * (the IO to be ABORT'd) 1783 * (the IO to be ABORT'd)
1749 * 1784 *
@@ -1756,38 +1791,22 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1756 1791
1757 hd->abortSCpnt = SCpnt; 1792 hd->abortSCpnt = SCpnt;
1758 1793
1759 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1794 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1760 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, 1795 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
1761 ctx2abort, 2 /* 2 second timeout */) 1796 ctx2abort, 2 /* 2 second timeout */);
1762 < 0) {
1763 1797
1764 /* The TM request failed and the subsequent FW-reload failed! 1798 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1765 * Fatal error case. 1799 hd->ioc->name,
1766 */ 1800 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1767 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
1768 hd->ioc->name, SCpnt);
1769 1801
1770 /* We must clear our pending flag before clearing our state. 1802 if (retval == 0)
1771 */ 1803 return SUCCESS;
1804
1805 if(retval != FAILED ) {
1772 hd->tmPending = 0; 1806 hd->tmPending = 0;
1773 hd->tmState = TM_STATE_NONE; 1807 hd->tmState = TM_STATE_NONE;
1774
1775 /* Unmap the DMA buffers, if any. */
1776 if (SCpnt->use_sg) {
1777 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
1778 SCpnt->use_sg, SCpnt->sc_data_direction);
1779 } else if (SCpnt->request_bufflen) {
1780 pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
1781 SCpnt->request_bufflen, SCpnt->sc_data_direction);
1782 }
1783 hd->ScsiLookup[scpnt_idx] = NULL;
1784 SCpnt->result = DID_RESET << 16;
1785 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
1786 mptscsih_freeChainBuffers(ioc, scpnt_idx);
1787 mpt_free_msg_frame(ioc, mf);
1788 return FAILED;
1789 } 1808 }
1790 return SUCCESS; 1809 return FAILED;
1791} 1810}
1792 1811
1793/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1812/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1803,11 +1822,12 @@ int
1803mptscsih_dev_reset(struct scsi_cmnd * SCpnt) 1822mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1804{ 1823{
1805 MPT_SCSI_HOST *hd; 1824 MPT_SCSI_HOST *hd;
1825 int retval;
1806 1826
1807 /* If we can't locate our host adapter structure, return FAILED status. 1827 /* If we can't locate our host adapter structure, return FAILED status.
1808 */ 1828 */
1809 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ 1829 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1810 dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: " 1830 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
1811 "Can't locate host! (sc=%p)\n", 1831 "Can't locate host! (sc=%p)\n",
1812 SCpnt)); 1832 SCpnt));
1813 return FAILED; 1833 return FAILED;
@@ -1816,24 +1836,26 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1816 if (hd->resetPending) 1836 if (hd->resetPending)
1817 return FAILED; 1837 return FAILED;
1818 1838
1819 printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n", 1839 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
1820 hd->ioc->name, SCpnt); 1840 hd->ioc->name, SCpnt);
1841 scsi_print_command(SCpnt);
1821 1842
1822 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 1843 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1823 SCpnt->device->channel, SCpnt->device->id, 1844 SCpnt->device->channel, SCpnt->device->id,
1824 0, 0, 5 /* 5 second timeout */) 1845 0, 0, 5 /* 5 second timeout */);
1825 < 0){ 1846
1826 /* The TM request failed and the subsequent FW-reload failed! 1847 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
1827 * Fatal error case. 1848 hd->ioc->name,
1828 */ 1849 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1829 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n", 1850
1830 hd->ioc->name, SCpnt); 1851 if (retval == 0)
1852 return SUCCESS;
1853
1854 if(retval != FAILED ) {
1831 hd->tmPending = 0; 1855 hd->tmPending = 0;
1832 hd->tmState = TM_STATE_NONE; 1856 hd->tmState = TM_STATE_NONE;
1833 return FAILED;
1834 } 1857 }
1835 1858 return FAILED;
1836 return SUCCESS;
1837} 1859}
1838 1860
1839/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1861/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1849,41 +1871,39 @@ int
1849mptscsih_bus_reset(struct scsi_cmnd * SCpnt) 1871mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1850{ 1872{
1851 MPT_SCSI_HOST *hd; 1873 MPT_SCSI_HOST *hd;
1852 spinlock_t *host_lock = SCpnt->device->host->host_lock; 1874 int retval;
1853 1875
1854 /* If we can't locate our host adapter structure, return FAILED status. 1876 /* If we can't locate our host adapter structure, return FAILED status.
1855 */ 1877 */
1856 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ 1878 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1857 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: " 1879 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
1858 "Can't locate host! (sc=%p)\n", 1880 "Can't locate host! (sc=%p)\n",
1859 SCpnt ) ); 1881 SCpnt ) );
1860 return FAILED; 1882 return FAILED;
1861 } 1883 }
1862 1884
1863 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n", 1885 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
1864 hd->ioc->name, SCpnt); 1886 hd->ioc->name, SCpnt);
1887 scsi_print_command(SCpnt);
1865 1888
1866 if (hd->timeouts < -1) 1889 if (hd->timeouts < -1)
1867 hd->timeouts++; 1890 hd->timeouts++;
1868 1891
1869 /* We are now ready to execute the task management request. */ 1892 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1870 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1893 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
1871 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
1872 < 0){
1873 1894
1874 /* The TM request failed and the subsequent FW-reload failed! 1895 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1875 * Fatal error case. 1896 hd->ioc->name,
1876 */ 1897 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1877 printk(MYIOC_s_WARN_FMT 1898
1878 "Error processing TaskMgmt request (sc=%p)\n", 1899 if (retval == 0)
1879 hd->ioc->name, SCpnt); 1900 return SUCCESS;
1901
1902 if(retval != FAILED ) {
1880 hd->tmPending = 0; 1903 hd->tmPending = 0;
1881 hd->tmState = TM_STATE_NONE; 1904 hd->tmState = TM_STATE_NONE;
1882 spin_lock_irq(host_lock);
1883 return FAILED;
1884 } 1905 }
1885 1906 return FAILED;
1886 return SUCCESS;
1887} 1907}
1888 1908
1889/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1909/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2165,7 +2185,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
2165 vdev->raidVolume = 0; 2185 vdev->raidVolume = 0;
2166 hd->Targets[device->id] = vdev; 2186 hd->Targets[device->id] = vdev;
2167 if (hd->ioc->bus_type == SCSI) { 2187 if (hd->ioc->bus_type == SCSI) {
2168 if (hd->ioc->spi_data.isRaid & (1 << device->id)) { 2188 if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
2169 vdev->raidVolume = 1; 2189 vdev->raidVolume = 1;
2170 ddvtprintk((KERN_INFO 2190 ddvtprintk((KERN_INFO
2171 "RAID Volume @ id %d\n", device->id)); 2191 "RAID Volume @ id %d\n", device->id));
@@ -2180,22 +2200,6 @@ mptscsih_slave_alloc(struct scsi_device *device)
2180 return 0; 2200 return 0;
2181} 2201}
2182 2202
2183static int
2184mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2185{
2186 int i;
2187
2188 if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2189 return 0;
2190
2191 for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2192 if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2193 return 1;
2194 }
2195
2196 return 0;
2197}
2198
2199/* 2203/*
2200 * OS entry point to allow for host driver to free allocated memory 2204 * OS entry point to allow for host driver to free allocated memory
2201 * Called if no device present or device being unloaded 2205 * Called if no device present or device being unloaded
@@ -2223,7 +2227,7 @@ mptscsih_slave_destroy(struct scsi_device *device)
2223 hd->Targets[target] = NULL; 2227 hd->Targets[target] = NULL;
2224 2228
2225 if (hd->ioc->bus_type == SCSI) { 2229 if (hd->ioc->bus_type == SCSI) {
2226 if (mptscsih_is_raid_volume(hd, target)) { 2230 if (mptscsih_is_phys_disk(hd->ioc, target)) {
2227 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; 2231 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2228 } else { 2232 } else {
2229 hd->ioc->spi_data.dvStatus[target] = 2233 hd->ioc->spi_data.dvStatus[target] =
@@ -2436,6 +2440,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2436{ 2440{
2437 MPT_SCSI_HOST *hd; 2441 MPT_SCSI_HOST *hd;
2438 unsigned long flags; 2442 unsigned long flags;
2443 int ii;
2439 2444
2440 dtmprintk((KERN_WARNING MYNAM 2445 dtmprintk((KERN_WARNING MYNAM
2441 ": IOC %s_reset routed to SCSI host driver!\n", 2446 ": IOC %s_reset routed to SCSI host driver!\n",
@@ -2493,11 +2498,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2493 2498
2494 /* ScsiLookup initialization 2499 /* ScsiLookup initialization
2495 */ 2500 */
2496 { 2501 for (ii=0; ii < hd->ioc->req_depth; ii++)
2497 int ii; 2502 hd->ScsiLookup[ii] = NULL;
2498 for (ii=0; ii < hd->ioc->req_depth; ii++)
2499 hd->ScsiLookup[ii] = NULL;
2500 }
2501 2503
2502 /* 2. Chain Buffer initialization 2504 /* 2. Chain Buffer initialization
2503 */ 2505 */
@@ -2546,6 +2548,16 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2546} 2548}
2547 2549
2548/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2550/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2551/* work queue thread to clear the persitency table */
2552static void
2553mptscsih_sas_persist_clear_table(void * arg)
2554{
2555 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
2556
2557 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2558}
2559
2560/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2549int 2561int
2550mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) 2562mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2551{ 2563{
@@ -2555,18 +2567,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2555 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2567 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2556 ioc->name, event)); 2568 ioc->name, event));
2557 2569
2570 if (ioc->sh == NULL ||
2571 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
2572 return 1;
2573
2558 switch (event) { 2574 switch (event) {
2559 case MPI_EVENT_UNIT_ATTENTION: /* 03 */ 2575 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2560 /* FIXME! */ 2576 /* FIXME! */
2561 break; 2577 break;
2562 case MPI_EVENT_IOC_BUS_RESET: /* 04 */ 2578 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2563 case MPI_EVENT_EXT_BUS_RESET: /* 05 */ 2579 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2564 hd = NULL; 2580 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2565 if (ioc->sh) { 2581 hd->soft_resets++;
2566 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2567 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2568 hd->soft_resets++;
2569 }
2570 break; 2582 break;
2571 case MPI_EVENT_LOGOUT: /* 09 */ 2583 case MPI_EVENT_LOGOUT: /* 09 */
2572 /* FIXME! */ 2584 /* FIXME! */
@@ -2585,69 +2597,24 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2585 break; 2597 break;
2586 2598
2587 case MPI_EVENT_INTEGRATED_RAID: /* 0B */ 2599 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2600 {
2601 pMpiEventDataRaid_t pRaidEventData =
2602 (pMpiEventDataRaid_t) pEvReply->Data;
2588#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 2603#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2589 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if 2604 /* Domain Validation Needed */
2590 * if DV disabled. Need to check for target mode. 2605 if (ioc->bus_type == SCSI &&
2591 */ 2606 pRaidEventData->ReasonCode ==
2592 hd = NULL; 2607 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
2593 if (ioc->sh) 2608 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
2594 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2595
2596 if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
2597 ScsiCfgData *pSpi;
2598 Ioc3PhysDisk_t *pPDisk;
2599 int numPDisk;
2600 u8 reason;
2601 u8 physDiskNum;
2602
2603 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
2604 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
2605 /* New or replaced disk.
2606 * Set DV flag and schedule DV.
2607 */
2608 pSpi = &ioc->spi_data;
2609 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
2610 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
2611 if (pSpi->pIocPg3) {
2612 pPDisk = pSpi->pIocPg3->PhysDisk;
2613 numPDisk =pSpi->pIocPg3->NumPhysDisks;
2614
2615 while (numPDisk) {
2616 if (physDiskNum == pPDisk->PhysDiskNum) {
2617 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2618 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2619 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
2620 break;
2621 }
2622 pPDisk++;
2623 numPDisk--;
2624 }
2625
2626 if (numPDisk == 0) {
2627 /* The physical disk that needs DV was not found
2628 * in the stored IOC Page 3. The driver must reload
2629 * this page. DV routine will set the NEED_DV flag for
2630 * all phys disks that have DV_NOT_DONE set.
2631 */
2632 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2633 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
2634 }
2635 }
2636 }
2637 }
2638#endif 2609#endif
2610 break;
2611 }
2639 2612
2640#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) 2613 /* Persistent table is full. */
2641 printk("Raid Event RF: "); 2614 case MPI_EVENT_PERSISTENT_TABLE_FULL:
2642 { 2615 INIT_WORK(&mptscsih_persistTask,
2643 u32 *m = (u32 *)pEvReply; 2616 mptscsih_sas_persist_clear_table,(void *)ioc);
2644 int ii; 2617 schedule_work(&mptscsih_persistTask);
2645 int n = (int)pEvReply->MsgLength;
2646 for (ii=6; ii < n; ii++)
2647 printk(" %08x", le32_to_cpu(m[ii]));
2648 printk("\n");
2649 }
2650#endif
2651 break; 2618 break;
2652 2619
2653 case MPI_EVENT_NONE: /* 00 */ 2620 case MPI_EVENT_NONE: /* 00 */
@@ -2684,7 +2651,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
2684{ 2651{
2685 int indexed_lun, lun_index; 2652 int indexed_lun, lun_index;
2686 VirtDevice *vdev; 2653 VirtDevice *vdev;
2687 ScsiCfgData *pSpi; 2654 SpiCfgData *pSpi;
2688 char data_56; 2655 char data_56;
2689 2656
2690 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", 2657 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
@@ -2791,7 +2758,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
2791static void 2758static void
2792mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) 2759mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2793{ 2760{
2794 ScsiCfgData *pspi_data = &hd->ioc->spi_data; 2761 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2795 int id = (int) target->target_id; 2762 int id = (int) target->target_id;
2796 int nvram; 2763 int nvram;
2797 VirtDevice *vdev; 2764 VirtDevice *vdev;
@@ -2970,11 +2937,13 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2970static void 2937static void
2971mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) 2938mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2972{ 2939{
2940 MPT_ADAPTER *ioc = hd->ioc;
2973 u8 cmd; 2941 u8 cmd;
2974 ScsiCfgData *pSpi; 2942 SpiCfgData *pSpi;
2975 2943
2976 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", 2944 ddvtprintk((MYIOC_s_NOTE_FMT
2977 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0])); 2945 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
2946 hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
2978 2947
2979 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0)) 2948 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
2980 return; 2949 return;
@@ -2982,12 +2951,12 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2982 cmd = pReq->CDB[0]; 2951 cmd = pReq->CDB[0];
2983 2952
2984 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { 2953 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
2985 pSpi = &hd->ioc->spi_data; 2954 pSpi = &ioc->spi_data;
2986 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) { 2955 if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
2987 /* Set NEED_DV for all hidden disks 2956 /* Set NEED_DV for all hidden disks
2988 */ 2957 */
2989 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk; 2958 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
2990 int numPDisk = pSpi->pIocPg3->NumPhysDisks; 2959 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
2991 2960
2992 while (numPDisk) { 2961 while (numPDisk) {
2993 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; 2962 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
@@ -3001,6 +2970,50 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
3001 } 2970 }
3002} 2971}
3003 2972
2973/* mptscsih_raid_set_dv_flags()
2974 *
2975 * New or replaced disk. Set DV flag and schedule DV.
2976 */
2977static void
2978mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
2979{
2980 MPT_ADAPTER *ioc = hd->ioc;
2981 SpiCfgData *pSpi = &ioc->spi_data;
2982 Ioc3PhysDisk_t *pPDisk;
2983 int numPDisk;
2984
2985 if (hd->negoNvram != 0)
2986 return;
2987
2988 ddvtprintk(("DV requested for phys disk id %d\n", id));
2989 if (ioc->raid_data.pIocPg3) {
2990 pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
2991 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
2992 while (numPDisk) {
2993 if (id == pPDisk->PhysDiskNum) {
2994 pSpi->dvStatus[pPDisk->PhysDiskID] =
2995 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2996 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2997 ddvtprintk(("NEED_DV set for phys disk id %d\n",
2998 pPDisk->PhysDiskID));
2999 break;
3000 }
3001 pPDisk++;
3002 numPDisk--;
3003 }
3004
3005 if (numPDisk == 0) {
3006 /* The physical disk that needs DV was not found
3007 * in the stored IOC Page 3. The driver must reload
3008 * this page. DV routine will set the NEED_DV flag for
3009 * all phys disks that have DV_NOT_DONE set.
3010 */
3011 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3012 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
3013 }
3014 }
3015}
3016
3004/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3017/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3005/* 3018/*
3006 * If no Target, bus reset on 1st I/O. Set the flag to 3019 * If no Target, bus reset on 1st I/O. Set the flag to
@@ -3088,7 +3101,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3088 MPT_ADAPTER *ioc = hd->ioc; 3101 MPT_ADAPTER *ioc = hd->ioc;
3089 Config_t *pReq; 3102 Config_t *pReq;
3090 SCSIDevicePage1_t *pData; 3103 SCSIDevicePage1_t *pData;
3091 VirtDevice *pTarget; 3104 VirtDevice *pTarget=NULL;
3092 MPT_FRAME_HDR *mf; 3105 MPT_FRAME_HDR *mf;
3093 dma_addr_t dataDma; 3106 dma_addr_t dataDma;
3094 u16 req_idx; 3107 u16 req_idx;
@@ -3187,7 +3200,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3187#endif 3200#endif
3188 3201
3189 if (flags & MPT_SCSICFG_BLK_NEGO) 3202 if (flags & MPT_SCSICFG_BLK_NEGO)
3190 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC; 3203 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3191 3204
3192 mptscsih_setDevicePage1Flags(width, factor, offset, 3205 mptscsih_setDevicePage1Flags(width, factor, offset,
3193 &requested, &configuration, negoFlags); 3206 &requested, &configuration, negoFlags);
@@ -4008,7 +4021,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
4008 4021
4009 /* If target Ptr NULL or if this target is NOT a disk, skip. 4022 /* If target Ptr NULL or if this target is NOT a disk, skip.
4010 */ 4023 */
4011 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){ 4024 if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
4012 for (lun=0; lun <= MPT_LAST_LUN; lun++) { 4025 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4013 /* If LUN present, issue the command 4026 /* If LUN present, issue the command
4014 */ 4027 */
@@ -4103,9 +4116,9 @@ mptscsih_domainValidation(void *arg)
4103 4116
4104 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) { 4117 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4105 mpt_read_ioc_pg_3(ioc); 4118 mpt_read_ioc_pg_3(ioc);
4106 if (ioc->spi_data.pIocPg3) { 4119 if (ioc->raid_data.pIocPg3) {
4107 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk; 4120 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4108 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks; 4121 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4109 4122
4110 while (numPDisk) { 4123 while (numPDisk) {
4111 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE) 4124 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
@@ -4144,7 +4157,7 @@ mptscsih_domainValidation(void *arg)
4144 isPhysDisk = mptscsih_is_phys_disk(ioc, id); 4157 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4145 if (isPhysDisk) { 4158 if (isPhysDisk) {
4146 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 4159 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4147 if (hd->ioc->spi_data.isRaid & (1 << ii)) { 4160 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4148 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING; 4161 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4149 } 4162 }
4150 } 4163 }
@@ -4163,7 +4176,7 @@ mptscsih_domainValidation(void *arg)
4163 4176
4164 if (isPhysDisk) { 4177 if (isPhysDisk) {
4165 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 4178 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4166 if (hd->ioc->spi_data.isRaid & (1 << ii)) { 4179 if (hd->ioc->raid_data.isRaid & (1 << ii)) {
4167 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING; 4180 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4168 } 4181 }
4169 } 4182 }
@@ -4185,21 +4198,21 @@ mptscsih_domainValidation(void *arg)
4185 4198
4186/* Search IOC page 3 to determine if this is hidden physical disk 4199/* Search IOC page 3 to determine if this is hidden physical disk
4187 */ 4200 */
4188static int 4201/* Search IOC page 3 to determine if this is hidden physical disk
4202 */
4203static int
4189mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) 4204mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4190{ 4205{
4191 if (ioc->spi_data.pIocPg3) { 4206 int i;
4192 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4193 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4194 4207
4195 while (numPDisk) { 4208 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
4196 if (pPDisk->PhysDiskID == id) { 4209 return 0;
4197 return 1; 4210
4198 } 4211 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
4199 pPDisk++; 4212 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
4200 numPDisk--; 4213 return 1;
4201 }
4202 } 4214 }
4215
4203 return 0; 4216 return 0;
4204} 4217}
4205 4218
@@ -4405,7 +4418,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4405 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write 4418 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
4406 */ 4419 */
4407 { 4420 {
4408 ScsiCfgData *pspi_data = &hd->ioc->spi_data; 4421 SpiCfgData *pspi_data = &hd->ioc->spi_data;
4409 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { 4422 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4410 /* Set the factor from nvram */ 4423 /* Set the factor from nvram */
4411 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8; 4424 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
@@ -4435,11 +4448,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4435 } 4448 }
4436 4449
4437 /* Finish iocmd inititialization - hidden or visible disk? */ 4450 /* Finish iocmd inititialization - hidden or visible disk? */
4438 if (ioc->spi_data.pIocPg3) { 4451 if (ioc->raid_data.pIocPg3) {
4439 /* Search IOC page 3 for matching id 4452 /* Search IOC page 3 for matching id
4440 */ 4453 */
4441 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk; 4454 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
4442 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks; 4455 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
4443 4456
4444 while (numPDisk) { 4457 while (numPDisk) {
4445 if (pPDisk->PhysDiskID == id) { 4458 if (pPDisk->PhysDiskID == id) {
@@ -4463,7 +4476,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4463 /* RAID Volume ID's may double for a physical device. If RAID but 4476 /* RAID Volume ID's may double for a physical device. If RAID but
4464 * not a physical ID as well, skip DV. 4477 * not a physical ID as well, skip DV.
4465 */ 4478 */
4466 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK)) 4479 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4467 goto target_done; 4480 goto target_done;
4468 4481
4469 4482
@@ -4812,6 +4825,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4812 notDone = 0; 4825 notDone = 0;
4813 if (iocmd.flags & MPT_ICFLAG_ECHO) { 4826 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4814 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3]; 4827 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4828 if (pbuf1[0] & 0x01)
4829 iocmd.flags |= MPT_ICFLAG_EBOS;
4815 } else { 4830 } else {
4816 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3]; 4831 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4817 } 4832 }
@@ -4908,6 +4923,9 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4908 } 4923 }
4909 iocmd.flags &= ~MPT_ICFLAG_DID_RESET; 4924 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4910 4925
4926 if (iocmd.flags & MPT_ICFLAG_EBOS)
4927 goto skip_Reserve;
4928
4911 repeat = 5; 4929 repeat = 5;
4912 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) { 4930 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4913 iocmd.cmd = RESERVE; 4931 iocmd.cmd = RESERVE;
@@ -4951,6 +4969,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4951 } 4969 }
4952 } 4970 }
4953 4971
4972skip_Reserve:
4954 mptscsih_fillbuf(pbuf1, sz, patt, 1); 4973 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4955 iocmd.cmd = WRITE_BUFFER; 4974 iocmd.cmd = WRITE_BUFFER;
4956 iocmd.data_dma = buf1_dma; 4975 iocmd.data_dma = buf1_dma;
@@ -5195,11 +5214,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5195 * If not an LVD bus, the adapter minSyncFactor has been 5214 * If not an LVD bus, the adapter minSyncFactor has been
5196 * already throttled back. 5215 * already throttled back.
5197 */ 5216 */
5217 negoFlags = hd->ioc->spi_data.noQas;
5198 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) { 5218 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5199 width = pTarget->maxWidth; 5219 width = pTarget->maxWidth;
5200 offset = pTarget->maxOffset; 5220 offset = pTarget->maxOffset;
5201 factor = pTarget->minSyncFactor; 5221 factor = pTarget->minSyncFactor;
5202 negoFlags = pTarget->negoFlags; 5222 negoFlags |= pTarget->negoFlags;
5203 } else { 5223 } else {
5204 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { 5224 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5205 data = hd->ioc->spi_data.nvram[id]; 5225 data = hd->ioc->spi_data.nvram[id];
@@ -5220,7 +5240,6 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5220 } 5240 }
5221 5241
5222 /* Set the negotiation flags */ 5242 /* Set the negotiation flags */
5223 negoFlags = hd->ioc->spi_data.noQas;
5224 if (!width) 5243 if (!width)
5225 negoFlags |= MPT_TARGET_NO_NEGO_WIDE; 5244 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5226 5245