diff options
author | Moore, Eric Dean <Eric.Moore@lsil.com> | 2005-09-14 20:09:10 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-09-19 13:45:38 -0400 |
commit | 466544d8898fc87ed6e2e62ac14af7c50ab7a1a4 (patch) | |
tree | a23688bc1424a2af986482bac159768d625b5deb /drivers/message/fusion/mptscsih.c | |
parent | 0c33b27deb93178f10778b3d2669af1674793cef (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.c | 447 |
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 | |||
159 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); | 160 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); |
160 | static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); | 161 | static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); |
161 | 162 | ||
163 | static struct work_struct mptscsih_persistTask; | ||
164 | |||
162 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | 165 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION |
163 | static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); | 166 | static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); |
164 | static void mptscsih_domainValidation(void *hd); | 167 | static void mptscsih_domainValidation(void *hd); |
@@ -167,6 +170,7 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id); | |||
167 | static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); | 170 | static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); |
168 | static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); | 171 | static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); |
169 | static void mptscsih_fillbuf(char *buffer, int size, int index, int width); | 172 | static void mptscsih_fillbuf(char *buffer, int size, int index, int width); |
173 | static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id); | ||
170 | #endif | 174 | #endif |
171 | 175 | ||
172 | void mptscsih_remove(struct pci_dev *); | 176 | void 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 | |||
1803 | mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | 1822 | mptscsih_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 | |||
1849 | mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | 1871 | mptscsih_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 | ||
2183 | static int | ||
2184 | mptscsih_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 */ | ||
2552 | static void | ||
2553 | mptscsih_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 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2549 | int | 2561 | int |
2550 | mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | 2562 | mptscsih_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 * | |||
2791 | static void | 2758 | static void |
2792 | mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) | 2759 | mptscsih_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) | |||
2970 | static void | 2937 | static void |
2971 | mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) | 2938 | mptscsih_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 | */ | ||
2977 | static void | ||
2978 | mptscsih_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 | */ |
4188 | static int | 4201 | /* Search IOC page 3 to determine if this is hidden physical disk |
4202 | */ | ||
4203 | static int | ||
4189 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) | 4204 | mptscsih_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 | ||
4972 | skip_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 | ||