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.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