diff options
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 968 |
1 files changed, 478 insertions, 490 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index b7b9846ff3fd..93a16fa3c4ba 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -150,28 +150,29 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 tar | |||
150 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 150 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
151 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | 151 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); |
152 | 152 | ||
153 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen); | 153 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen); |
154 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56); | 154 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56); |
155 | static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq); | ||
156 | static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); | 155 | static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); |
157 | static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id); | 156 | static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc); |
158 | static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); | 157 | static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); |
159 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); | 158 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); |
160 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); | 159 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); |
161 | 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); |
162 | static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); | 161 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); |
162 | static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget); | ||
163 | static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); | ||
163 | 164 | ||
164 | static struct work_struct mptscsih_persistTask; | 165 | static struct work_struct mptscsih_persistTask; |
165 | 166 | ||
166 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | 167 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION |
167 | static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); | 168 | static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); |
168 | static void mptscsih_domainValidation(void *hd); | 169 | static void mptscsih_domainValidation(void *hd); |
169 | static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); | ||
170 | static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id); | 170 | static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id); |
171 | static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); | 171 | static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); |
172 | static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); | 172 | static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); |
173 | static void mptscsih_fillbuf(char *buffer, int size, int index, int width); | 173 | static void mptscsih_fillbuf(char *buffer, int size, int index, int width); |
174 | static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id); | 174 | static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id); |
175 | static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc); | ||
175 | #endif | 176 | #endif |
176 | 177 | ||
177 | void mptscsih_remove(struct pci_dev *); | 178 | void mptscsih_remove(struct pci_dev *); |
@@ -627,7 +628,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
627 | dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" | 628 | dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" |
628 | "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" | 629 | "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" |
629 | "resid=%d bufflen=%d xfer_cnt=%d\n", | 630 | "resid=%d bufflen=%d xfer_cnt=%d\n", |
630 | ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], | 631 | ioc->id, sc->device->id, sc->device->lun, |
631 | status, scsi_state, scsi_status, sc->resid, | 632 | status, scsi_state, scsi_status, sc->resid, |
632 | sc->request_bufflen, xfer_cnt)); | 633 | sc->request_bufflen, xfer_cnt)); |
633 | 634 | ||
@@ -641,7 +642,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
641 | pScsiReply->ResponseInfo) { | 642 | pScsiReply->ResponseInfo) { |
642 | printk(KERN_NOTICE "ha=%d id=%d lun=%d: " | 643 | printk(KERN_NOTICE "ha=%d id=%d lun=%d: " |
643 | "FCP_ResponseInfo=%08xh\n", | 644 | "FCP_ResponseInfo=%08xh\n", |
644 | ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], | 645 | ioc->id, sc->device->id, sc->device->lun, |
645 | le32_to_cpu(pScsiReply->ResponseInfo)); | 646 | le32_to_cpu(pScsiReply->ResponseInfo)); |
646 | } | 647 | } |
647 | 648 | ||
@@ -677,8 +678,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
677 | sc->result = DID_RESET << 16; | 678 | sc->result = DID_RESET << 16; |
678 | 679 | ||
679 | /* GEM Workaround. */ | 680 | /* GEM Workaround. */ |
680 | if (ioc->bus_type == SCSI) | 681 | if (ioc->bus_type == SPI) |
681 | mptscsih_no_negotiate(hd, sc->device->id); | 682 | mptscsih_no_negotiate(hd, sc); |
682 | break; | 683 | break; |
683 | 684 | ||
684 | case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ | 685 | case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ |
@@ -892,16 +893,15 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) | |||
892 | * when a lun is disable by mid-layer. | 893 | * when a lun is disable by mid-layer. |
893 | * Do NOT access the referenced scsi_cmnd structure or | 894 | * Do NOT access the referenced scsi_cmnd structure or |
894 | * members. Will cause either a paging or NULL ptr error. | 895 | * members. Will cause either a paging or NULL ptr error. |
895 | * @hd: Pointer to a SCSI HOST structure | 896 | * @hd: Pointer to a SCSI HOST structure |
896 | * @target: target id | 897 | * @vdevice: per device private data |
897 | * @lun: lun | ||
898 | * | 898 | * |
899 | * Returns: None. | 899 | * Returns: None. |
900 | * | 900 | * |
901 | * Called from slave_destroy. | 901 | * Called from slave_destroy. |
902 | */ | 902 | */ |
903 | static void | 903 | static void |
904 | mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) | 904 | mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) |
905 | { | 905 | { |
906 | SCSIIORequest_t *mf = NULL; | 906 | SCSIIORequest_t *mf = NULL; |
907 | int ii; | 907 | int ii; |
@@ -909,7 +909,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) | |||
909 | struct scsi_cmnd *sc; | 909 | struct scsi_cmnd *sc; |
910 | 910 | ||
911 | dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", | 911 | dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", |
912 | target, lun, max)); | 912 | vdevice->target_id, vdevice->lun, max)); |
913 | 913 | ||
914 | for (ii=0; ii < max; ii++) { | 914 | for (ii=0; ii < max; ii++) { |
915 | if ((sc = hd->ScsiLookup[ii]) != NULL) { | 915 | if ((sc = hd->ScsiLookup[ii]) != NULL) { |
@@ -919,7 +919,7 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) | |||
919 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", | 919 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", |
920 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); | 920 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); |
921 | 921 | ||
922 | if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun))) | 922 | if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) |
923 | continue; | 923 | continue; |
924 | 924 | ||
925 | /* Cleanup | 925 | /* Cleanup |
@@ -993,8 +993,10 @@ mptscsih_remove(struct pci_dev *pdev) | |||
993 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); | 993 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); |
994 | struct Scsi_Host *host = ioc->sh; | 994 | struct Scsi_Host *host = ioc->sh; |
995 | MPT_SCSI_HOST *hd; | 995 | MPT_SCSI_HOST *hd; |
996 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | ||
996 | int count; | 997 | int count; |
997 | unsigned long flags; | 998 | unsigned long flags; |
999 | #endif | ||
998 | int sz1; | 1000 | int sz1; |
999 | 1001 | ||
1000 | if(!host) { | 1002 | if(!host) { |
@@ -1075,11 +1077,6 @@ mptscsih_shutdown(struct pci_dev *pdev) | |||
1075 | 1077 | ||
1076 | hd = (MPT_SCSI_HOST *)host->hostdata; | 1078 | hd = (MPT_SCSI_HOST *)host->hostdata; |
1077 | 1079 | ||
1078 | /* Flush the cache of this adapter | ||
1079 | */ | ||
1080 | if(hd != NULL) | ||
1081 | mptscsih_synchronize_cache(hd, 0); | ||
1082 | |||
1083 | } | 1080 | } |
1084 | 1081 | ||
1085 | #ifdef CONFIG_PM | 1082 | #ifdef CONFIG_PM |
@@ -1286,7 +1283,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1286 | MPT_SCSI_HOST *hd; | 1283 | MPT_SCSI_HOST *hd; |
1287 | MPT_FRAME_HDR *mf; | 1284 | MPT_FRAME_HDR *mf; |
1288 | SCSIIORequest_t *pScsiReq; | 1285 | SCSIIORequest_t *pScsiReq; |
1289 | VirtDevice *pTarget = SCpnt->device->hostdata; | 1286 | VirtDevice *vdev = SCpnt->device->hostdata; |
1290 | int lun; | 1287 | int lun; |
1291 | u32 datalen; | 1288 | u32 datalen; |
1292 | u32 scsictl; | 1289 | u32 scsictl; |
@@ -1341,8 +1338,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1341 | /* Default to untagged. Once a target structure has been allocated, | 1338 | /* Default to untagged. Once a target structure has been allocated, |
1342 | * use the Inquiry data to determine if device supports tagged. | 1339 | * use the Inquiry data to determine if device supports tagged. |
1343 | */ | 1340 | */ |
1344 | if (pTarget | 1341 | if (vdev |
1345 | && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) | 1342 | && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) |
1346 | && (SCpnt->device->tagged_supported)) { | 1343 | && (SCpnt->device->tagged_supported)) { |
1347 | scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; | 1344 | scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; |
1348 | } else { | 1345 | } else { |
@@ -1351,8 +1348,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1351 | 1348 | ||
1352 | /* Use the above information to set up the message frame | 1349 | /* Use the above information to set up the message frame |
1353 | */ | 1350 | */ |
1354 | pScsiReq->TargetID = (u8) pTarget->target_id; | 1351 | pScsiReq->TargetID = (u8) vdev->target_id; |
1355 | pScsiReq->Bus = pTarget->bus_id; | 1352 | pScsiReq->Bus = vdev->bus_id; |
1356 | pScsiReq->ChainOffset = 0; | 1353 | pScsiReq->ChainOffset = 0; |
1357 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; | 1354 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; |
1358 | pScsiReq->CDBLength = SCpnt->cmd_len; | 1355 | pScsiReq->CDBLength = SCpnt->cmd_len; |
@@ -1403,8 +1400,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1403 | SCpnt->host_scribble = NULL; | 1400 | SCpnt->host_scribble = NULL; |
1404 | 1401 | ||
1405 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | 1402 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION |
1406 | if (hd->ioc->bus_type == SCSI) { | 1403 | if (hd->ioc->bus_type == SPI) { |
1407 | int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id]; | 1404 | int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id]; |
1408 | int issueCmd = 1; | 1405 | int issueCmd = 1; |
1409 | 1406 | ||
1410 | if (dvStatus || hd->ioc->spi_data.forceDv) { | 1407 | if (dvStatus || hd->ioc->spi_data.forceDv) { |
@@ -1437,7 +1434,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1437 | /* Set the DV flags. | 1434 | /* Set the DV flags. |
1438 | */ | 1435 | */ |
1439 | if (dvStatus & MPT_SCSICFG_DV_NOT_DONE) | 1436 | if (dvStatus & MPT_SCSICFG_DV_NOT_DONE) |
1440 | mptscsih_set_dvflags(hd, pScsiReq); | 1437 | mptscsih_set_dvflags(hd, SCpnt); |
1441 | 1438 | ||
1442 | if (!issueCmd) | 1439 | if (!issueCmd) |
1443 | goto fail; | 1440 | goto fail; |
@@ -1741,6 +1738,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1741 | u32 ctx2abort; | 1738 | u32 ctx2abort; |
1742 | int scpnt_idx; | 1739 | int scpnt_idx; |
1743 | int retval; | 1740 | int retval; |
1741 | VirtDevice *vdev; | ||
1744 | 1742 | ||
1745 | /* If we can't locate our host adapter structure, return FAILED status. | 1743 | /* If we can't locate our host adapter structure, return FAILED status. |
1746 | */ | 1744 | */ |
@@ -1790,8 +1788,9 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1790 | 1788 | ||
1791 | hd->abortSCpnt = SCpnt; | 1789 | hd->abortSCpnt = SCpnt; |
1792 | 1790 | ||
1791 | vdev = SCpnt->device->hostdata; | ||
1793 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, | 1792 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, |
1794 | SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, | 1793 | vdev->bus_id, vdev->target_id, vdev->lun, |
1795 | ctx2abort, 2 /* 2 second timeout */); | 1794 | ctx2abort, 2 /* 2 second timeout */); |
1796 | 1795 | ||
1797 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", | 1796 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", |
@@ -1822,6 +1821,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1822 | { | 1821 | { |
1823 | MPT_SCSI_HOST *hd; | 1822 | MPT_SCSI_HOST *hd; |
1824 | int retval; | 1823 | int retval; |
1824 | VirtDevice *vdev; | ||
1825 | 1825 | ||
1826 | /* If we can't locate our host adapter structure, return FAILED status. | 1826 | /* If we can't locate our host adapter structure, return FAILED status. |
1827 | */ | 1827 | */ |
@@ -1839,8 +1839,9 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1839 | hd->ioc->name, SCpnt); | 1839 | hd->ioc->name, SCpnt); |
1840 | scsi_print_command(SCpnt); | 1840 | scsi_print_command(SCpnt); |
1841 | 1841 | ||
1842 | vdev = SCpnt->device->hostdata; | ||
1842 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | 1843 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, |
1843 | SCpnt->device->channel, SCpnt->device->id, | 1844 | vdev->bus_id, vdev->target_id, |
1844 | 0, 0, 5 /* 5 second timeout */); | 1845 | 0, 0, 5 /* 5 second timeout */); |
1845 | 1846 | ||
1846 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", | 1847 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", |
@@ -1871,6 +1872,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
1871 | { | 1872 | { |
1872 | MPT_SCSI_HOST *hd; | 1873 | MPT_SCSI_HOST *hd; |
1873 | int retval; | 1874 | int retval; |
1875 | VirtDevice *vdev; | ||
1874 | 1876 | ||
1875 | /* If we can't locate our host adapter structure, return FAILED status. | 1877 | /* If we can't locate our host adapter structure, return FAILED status. |
1876 | */ | 1878 | */ |
@@ -1888,8 +1890,9 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
1888 | if (hd->timeouts < -1) | 1890 | if (hd->timeouts < -1) |
1889 | hd->timeouts++; | 1891 | hd->timeouts++; |
1890 | 1892 | ||
1893 | vdev = SCpnt->device->hostdata; | ||
1891 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | 1894 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, |
1892 | SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */); | 1895 | vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */); |
1893 | 1896 | ||
1894 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", | 1897 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", |
1895 | hd->ioc->name, | 1898 | hd->ioc->name, |
@@ -2151,23 +2154,36 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, | |||
2151 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2154 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2152 | /* | 2155 | /* |
2153 | * OS entry point to allow host driver to alloc memory | 2156 | * OS entry point to allow host driver to alloc memory |
2157 | * for each scsi target. Called once per device the bus scan. | ||
2158 | * Return non-zero if allocation fails. | ||
2159 | */ | ||
2160 | int | ||
2161 | mptscsih_target_alloc(struct scsi_target *starget) | ||
2162 | { | ||
2163 | VirtTarget *vtarget; | ||
2164 | |||
2165 | vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL); | ||
2166 | if (!vtarget) | ||
2167 | return -ENOMEM; | ||
2168 | memset(vtarget, 0, sizeof(VirtTarget)); | ||
2169 | starget->hostdata = vtarget; | ||
2170 | return 0; | ||
2171 | } | ||
2172 | |||
2173 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2174 | /* | ||
2175 | * OS entry point to allow host driver to alloc memory | ||
2154 | * for each scsi device. Called once per device the bus scan. | 2176 | * for each scsi device. Called once per device the bus scan. |
2155 | * Return non-zero if allocation fails. | 2177 | * Return non-zero if allocation fails. |
2156 | * Init memory once per id (not LUN). | ||
2157 | */ | 2178 | */ |
2158 | int | 2179 | int |
2159 | mptscsih_slave_alloc(struct scsi_device *device) | 2180 | mptscsih_slave_alloc(struct scsi_device *sdev) |
2160 | { | 2181 | { |
2161 | struct Scsi_Host *host = device->host; | 2182 | struct Scsi_Host *host = sdev->host; |
2162 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 2183 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
2184 | VirtTarget *vtarget; | ||
2163 | VirtDevice *vdev; | 2185 | VirtDevice *vdev; |
2164 | uint target = device->id; | 2186 | struct scsi_target *starget; |
2165 | |||
2166 | if (hd == NULL) | ||
2167 | return -ENODEV; | ||
2168 | |||
2169 | if ((vdev = hd->Targets[target]) != NULL) | ||
2170 | goto out; | ||
2171 | 2187 | ||
2172 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); | 2188 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); |
2173 | if (!vdev) { | 2189 | if (!vdev) { |
@@ -2177,25 +2193,33 @@ mptscsih_slave_alloc(struct scsi_device *device) | |||
2177 | } | 2193 | } |
2178 | 2194 | ||
2179 | memset(vdev, 0, sizeof(VirtDevice)); | 2195 | memset(vdev, 0, sizeof(VirtDevice)); |
2180 | vdev->tflags = MPT_TARGET_FLAGS_Q_YES; | ||
2181 | vdev->ioc_id = hd->ioc->id; | 2196 | vdev->ioc_id = hd->ioc->id; |
2182 | vdev->target_id = device->id; | 2197 | vdev->target_id = sdev->id; |
2183 | vdev->bus_id = device->channel; | 2198 | vdev->bus_id = sdev->channel; |
2184 | vdev->raidVolume = 0; | 2199 | vdev->lun = sdev->lun; |
2185 | hd->Targets[device->id] = vdev; | 2200 | sdev->hostdata = vdev; |
2186 | if (hd->ioc->bus_type == SCSI) { | 2201 | |
2187 | if (hd->ioc->raid_data.isRaid & (1 << device->id)) { | 2202 | starget = scsi_target(sdev); |
2188 | vdev->raidVolume = 1; | 2203 | vtarget = starget->hostdata; |
2189 | ddvtprintk((KERN_INFO | 2204 | vdev->vtarget = vtarget; |
2190 | "RAID Volume @ id %d\n", device->id)); | 2205 | |
2206 | if (vtarget->num_luns == 0) { | ||
2207 | hd->Targets[sdev->id] = vtarget; | ||
2208 | vtarget->ioc_id = hd->ioc->id; | ||
2209 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | ||
2210 | vtarget->target_id = sdev->id; | ||
2211 | vtarget->bus_id = sdev->channel; | ||
2212 | if (hd->ioc->bus_type == SPI) { | ||
2213 | if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) { | ||
2214 | vtarget->raidVolume = 1; | ||
2215 | ddvtprintk((KERN_INFO | ||
2216 | "RAID Volume @ id %d\n", sdev->id)); | ||
2217 | } | ||
2218 | } else { | ||
2219 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
2191 | } | 2220 | } |
2192 | } else { | ||
2193 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
2194 | } | 2221 | } |
2195 | 2222 | vtarget->num_luns++; | |
2196 | out: | ||
2197 | vdev->num_luns++; | ||
2198 | device->hostdata = vdev; | ||
2199 | return 0; | 2223 | return 0; |
2200 | } | 2224 | } |
2201 | 2225 | ||
@@ -2204,40 +2228,52 @@ mptscsih_slave_alloc(struct scsi_device *device) | |||
2204 | * Called if no device present or device being unloaded | 2228 | * Called if no device present or device being unloaded |
2205 | */ | 2229 | */ |
2206 | void | 2230 | void |
2207 | mptscsih_slave_destroy(struct scsi_device *device) | 2231 | mptscsih_target_destroy(struct scsi_target *starget) |
2208 | { | 2232 | { |
2209 | struct Scsi_Host *host = device->host; | 2233 | if (starget->hostdata) |
2210 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 2234 | kfree(starget->hostdata); |
2211 | VirtDevice *vdev; | 2235 | starget->hostdata = NULL; |
2212 | uint target = device->id; | 2236 | } |
2213 | uint lun = device->lun; | ||
2214 | |||
2215 | if (hd == NULL) | ||
2216 | return; | ||
2217 | |||
2218 | mptscsih_search_running_cmds(hd, target, lun); | ||
2219 | |||
2220 | vdev = hd->Targets[target]; | ||
2221 | vdev->luns[0] &= ~(1 << lun); | ||
2222 | if (--vdev->num_luns) | ||
2223 | return; | ||
2224 | |||
2225 | kfree(hd->Targets[target]); | ||
2226 | hd->Targets[target] = NULL; | ||
2227 | |||
2228 | if (hd->ioc->bus_type == SCSI) { | ||
2229 | if (mptscsih_is_phys_disk(hd->ioc, target)) { | ||
2230 | hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; | ||
2231 | } else { | ||
2232 | hd->ioc->spi_data.dvStatus[target] = | ||
2233 | MPT_SCSICFG_NEGOTIATE; | ||
2234 | 2237 | ||
2235 | if (!hd->negoNvram) { | 2238 | /* |
2236 | hd->ioc->spi_data.dvStatus[target] |= | 2239 | * OS entry point to allow for host driver to free allocated memory |
2237 | MPT_SCSICFG_DV_NOT_DONE; | 2240 | * Called if no device present or device being unloaded |
2241 | */ | ||
2242 | void | ||
2243 | mptscsih_slave_destroy(struct scsi_device *sdev) | ||
2244 | { | ||
2245 | struct Scsi_Host *host = sdev->host; | ||
2246 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
2247 | VirtTarget *vtarget; | ||
2248 | VirtDevice *vdevice; | ||
2249 | struct scsi_target *starget; | ||
2250 | |||
2251 | starget = scsi_target(sdev); | ||
2252 | vtarget = starget->hostdata; | ||
2253 | vdevice = sdev->hostdata; | ||
2254 | |||
2255 | mptscsih_search_running_cmds(hd, vdevice); | ||
2256 | vtarget->luns[0] &= ~(1 << vdevice->lun); | ||
2257 | vtarget->num_luns--; | ||
2258 | if (vtarget->num_luns == 0) { | ||
2259 | mptscsih_negotiate_to_asyn_narrow(hd, vtarget); | ||
2260 | if (hd->ioc->bus_type == SPI) { | ||
2261 | if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) { | ||
2262 | hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; | ||
2263 | } else { | ||
2264 | hd->ioc->spi_data.dvStatus[vtarget->target_id] = | ||
2265 | MPT_SCSICFG_NEGOTIATE; | ||
2266 | if (!hd->negoNvram) { | ||
2267 | hd->ioc->spi_data.dvStatus[vtarget->target_id] |= | ||
2268 | MPT_SCSICFG_DV_NOT_DONE; | ||
2269 | } | ||
2238 | } | 2270 | } |
2239 | } | 2271 | } |
2272 | hd->Targets[sdev->id] = NULL; | ||
2240 | } | 2273 | } |
2274 | mptscsih_synchronize_cache(hd, vdevice); | ||
2275 | kfree(vdevice); | ||
2276 | sdev->hostdata = NULL; | ||
2241 | } | 2277 | } |
2242 | 2278 | ||
2243 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2279 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
@@ -2251,22 +2287,21 @@ mptscsih_slave_destroy(struct scsi_device *device) | |||
2251 | int | 2287 | int |
2252 | mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | 2288 | mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) |
2253 | { | 2289 | { |
2254 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; | 2290 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; |
2255 | VirtDevice *pTarget; | 2291 | VirtTarget *vtarget; |
2256 | int max_depth; | 2292 | struct scsi_target *starget; |
2257 | int tagged; | 2293 | int max_depth; |
2258 | 2294 | int tagged; | |
2259 | if (hd == NULL) | 2295 | |
2260 | return 0; | 2296 | starget = scsi_target(sdev); |
2261 | if (!(pTarget = hd->Targets[sdev->id])) | 2297 | vtarget = starget->hostdata; |
2262 | return 0; | 2298 | |
2263 | 2299 | if (hd->ioc->bus_type == SPI) { | |
2264 | if (hd->ioc->bus_type == SCSI) { | 2300 | if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { |
2265 | if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { | 2301 | if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) |
2266 | if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) | ||
2267 | max_depth = 1; | 2302 | max_depth = 1; |
2268 | else if (((pTarget->inq_data[0] & 0x1f) == 0x00) && | 2303 | else if (((vtarget->inq_data[0] & 0x1f) == 0x00) && |
2269 | (pTarget->minSyncFactor <= MPT_ULTRA160 )) | 2304 | (vtarget->minSyncFactor <= MPT_ULTRA160 )) |
2270 | max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; | 2305 | max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; |
2271 | else | 2306 | else |
2272 | max_depth = MPT_SCSI_CMD_PER_DEV_LOW; | 2307 | max_depth = MPT_SCSI_CMD_PER_DEV_LOW; |
@@ -2295,64 +2330,58 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | |||
2295 | * Return non-zero if fails. | 2330 | * Return non-zero if fails. |
2296 | */ | 2331 | */ |
2297 | int | 2332 | int |
2298 | mptscsih_slave_configure(struct scsi_device *device) | 2333 | mptscsih_slave_configure(struct scsi_device *sdev) |
2299 | { | 2334 | { |
2300 | struct Scsi_Host *sh = device->host; | 2335 | struct Scsi_Host *sh = sdev->host; |
2301 | VirtDevice *pTarget; | 2336 | VirtTarget *vtarget; |
2337 | VirtDevice *vdevice; | ||
2338 | struct scsi_target *starget; | ||
2302 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; | 2339 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; |
2340 | int indexed_lun, lun_index; | ||
2303 | 2341 | ||
2304 | if ((hd == NULL) || (hd->Targets == NULL)) { | 2342 | starget = scsi_target(sdev); |
2305 | return 0; | 2343 | vtarget = starget->hostdata; |
2306 | } | 2344 | vdevice = sdev->hostdata; |
2307 | 2345 | ||
2308 | dsprintk((MYIOC_s_INFO_FMT | 2346 | dsprintk((MYIOC_s_INFO_FMT |
2309 | "device @ %p, id=%d, LUN=%d, channel=%d\n", | 2347 | "device @ %p, id=%d, LUN=%d, channel=%d\n", |
2310 | hd->ioc->name, device, device->id, device->lun, device->channel)); | 2348 | hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel)); |
2311 | dsprintk((MYIOC_s_INFO_FMT | 2349 | if (hd->ioc->bus_type == SPI) |
2312 | "sdtr %d wdtr %d ppr %d inq length=%d\n", | 2350 | dsprintk((MYIOC_s_INFO_FMT |
2313 | hd->ioc->name, device->sdtr, device->wdtr, | 2351 | "sdtr %d wdtr %d ppr %d inq length=%d\n", |
2314 | device->ppr, device->inquiry_len)); | 2352 | hd->ioc->name, sdev->sdtr, sdev->wdtr, |
2315 | 2353 | sdev->ppr, sdev->inquiry_len)); | |
2316 | if (device->id > sh->max_id) { | 2354 | |
2355 | if (sdev->id > sh->max_id) { | ||
2317 | /* error case, should never happen */ | 2356 | /* error case, should never happen */ |
2318 | scsi_adjust_queue_depth(device, 0, 1); | 2357 | scsi_adjust_queue_depth(sdev, 0, 1); |
2319 | goto slave_configure_exit; | ||
2320 | } | ||
2321 | |||
2322 | pTarget = hd->Targets[device->id]; | ||
2323 | |||
2324 | if (pTarget == NULL) { | ||
2325 | /* Driver doesn't know about this device. | ||
2326 | * Kernel may generate a "Dummy Lun 0" which | ||
2327 | * may become a real Lun if a | ||
2328 | * "scsi add-single-device" command is executed | ||
2329 | * while the driver is active (hot-plug a | ||
2330 | * device). LSI Raid controllers need | ||
2331 | * queue_depth set to DEV_HIGH for this reason. | ||
2332 | */ | ||
2333 | scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, | ||
2334 | MPT_SCSI_CMD_PER_DEV_HIGH); | ||
2335 | goto slave_configure_exit; | 2358 | goto slave_configure_exit; |
2336 | } | 2359 | } |
2337 | 2360 | ||
2338 | mptscsih_initTarget(hd, device->channel, device->id, device->lun, | 2361 | vdevice->configured_lun=1; |
2339 | device->inquiry, device->inquiry_len ); | 2362 | lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */ |
2340 | mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH); | 2363 | indexed_lun = (vdevice->lun % 32); |
2364 | vtarget->luns[lun_index] |= (1 << indexed_lun); | ||
2365 | mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry, | ||
2366 | sdev->inquiry_len ); | ||
2367 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); | ||
2341 | 2368 | ||
2342 | dsprintk((MYIOC_s_INFO_FMT | 2369 | dsprintk((MYIOC_s_INFO_FMT |
2343 | "Queue depth=%d, tflags=%x\n", | 2370 | "Queue depth=%d, tflags=%x\n", |
2344 | hd->ioc->name, device->queue_depth, pTarget->tflags)); | 2371 | hd->ioc->name, sdev->queue_depth, vtarget->tflags)); |
2345 | 2372 | ||
2346 | dsprintk((MYIOC_s_INFO_FMT | 2373 | if (hd->ioc->bus_type == SPI) |
2347 | "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n", | 2374 | dsprintk((MYIOC_s_INFO_FMT |
2348 | hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor)); | 2375 | "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n", |
2376 | hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset, | ||
2377 | vtarget->minSyncFactor)); | ||
2349 | 2378 | ||
2350 | slave_configure_exit: | 2379 | slave_configure_exit: |
2351 | 2380 | ||
2352 | dsprintk((MYIOC_s_INFO_FMT | 2381 | dsprintk((MYIOC_s_INFO_FMT |
2353 | "tagged %d, simple %d, ordered %d\n", | 2382 | "tagged %d, simple %d, ordered %d\n", |
2354 | hd->ioc->name,device->tagged_supported, device->simple_tags, | 2383 | hd->ioc->name,sdev->tagged_supported, sdev->simple_tags, |
2355 | device->ordered_tags)); | 2384 | sdev->ordered_tags)); |
2356 | 2385 | ||
2357 | return 0; | 2386 | return 0; |
2358 | } | 2387 | } |
@@ -2370,16 +2399,14 @@ slave_configure_exit: | |||
2370 | static void | 2399 | static void |
2371 | mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply) | 2400 | mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply) |
2372 | { | 2401 | { |
2373 | VirtDevice *target; | 2402 | VirtDevice *vdev; |
2374 | SCSIIORequest_t *pReq; | 2403 | SCSIIORequest_t *pReq; |
2375 | u32 sense_count = le32_to_cpu(pScsiReply->SenseCount); | 2404 | u32 sense_count = le32_to_cpu(pScsiReply->SenseCount); |
2376 | int index; | ||
2377 | 2405 | ||
2378 | /* Get target structure | 2406 | /* Get target structure |
2379 | */ | 2407 | */ |
2380 | pReq = (SCSIIORequest_t *) mf; | 2408 | pReq = (SCSIIORequest_t *) mf; |
2381 | index = (int) pReq->TargetID; | 2409 | vdev = sc->device->hostdata; |
2382 | target = hd->Targets[index]; | ||
2383 | 2410 | ||
2384 | if (sense_count) { | 2411 | if (sense_count) { |
2385 | u8 *sense_data; | 2412 | u8 *sense_data; |
@@ -2393,7 +2420,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR | |||
2393 | /* Log SMART data (asc = 0x5D, non-IM case only) if required. | 2420 | /* Log SMART data (asc = 0x5D, non-IM case only) if required. |
2394 | */ | 2421 | */ |
2395 | if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { | 2422 | if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { |
2396 | if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) { | 2423 | if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) { |
2397 | int idx; | 2424 | int idx; |
2398 | MPT_ADAPTER *ioc = hd->ioc; | 2425 | MPT_ADAPTER *ioc = hd->ioc; |
2399 | 2426 | ||
@@ -2403,7 +2430,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR | |||
2403 | 2430 | ||
2404 | ioc->events[idx].data[0] = (pReq->LUN[1] << 24) || | 2431 | ioc->events[idx].data[0] = (pReq->LUN[1] << 24) || |
2405 | (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) || | 2432 | (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) || |
2406 | (pReq->Bus << 8) || pReq->TargetID; | 2433 | (sc->device->channel << 8) || sc->device->id; |
2407 | 2434 | ||
2408 | ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; | 2435 | ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; |
2409 | 2436 | ||
@@ -2503,9 +2530,9 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
2503 | /* 2. Chain Buffer initialization | 2530 | /* 2. Chain Buffer initialization |
2504 | */ | 2531 | */ |
2505 | 2532 | ||
2506 | /* 4. Renegotiate to all devices, if SCSI | 2533 | /* 4. Renegotiate to all devices, if SPI |
2507 | */ | 2534 | */ |
2508 | if (ioc->bus_type == SCSI) { | 2535 | if (ioc->bus_type == SPI) { |
2509 | dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n")); | 2536 | dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n")); |
2510 | mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM); | 2537 | mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM); |
2511 | } | 2538 | } |
@@ -2534,7 +2561,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
2534 | 2561 | ||
2535 | /* 7. Set flag to force DV and re-read IOC Page 3 | 2562 | /* 7. Set flag to force DV and re-read IOC Page 3 |
2536 | */ | 2563 | */ |
2537 | if (ioc->bus_type == SCSI) { | 2564 | if (ioc->bus_type == SPI) { |
2538 | ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; | 2565 | ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; |
2539 | ddvtprintk(("Set reload IOC Pg3 Flag\n")); | 2566 | ddvtprintk(("Set reload IOC Pg3 Flag\n")); |
2540 | } | 2567 | } |
@@ -2576,7 +2603,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
2576 | break; | 2603 | break; |
2577 | case MPI_EVENT_IOC_BUS_RESET: /* 04 */ | 2604 | case MPI_EVENT_IOC_BUS_RESET: /* 04 */ |
2578 | case MPI_EVENT_EXT_BUS_RESET: /* 05 */ | 2605 | case MPI_EVENT_EXT_BUS_RESET: /* 05 */ |
2579 | if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1)) | 2606 | if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1)) |
2580 | hd->soft_resets++; | 2607 | hd->soft_resets++; |
2581 | break; | 2608 | break; |
2582 | case MPI_EVENT_LOGOUT: /* 09 */ | 2609 | case MPI_EVENT_LOGOUT: /* 09 */ |
@@ -2597,11 +2624,11 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
2597 | 2624 | ||
2598 | case MPI_EVENT_INTEGRATED_RAID: /* 0B */ | 2625 | case MPI_EVENT_INTEGRATED_RAID: /* 0B */ |
2599 | { | 2626 | { |
2627 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | ||
2600 | pMpiEventDataRaid_t pRaidEventData = | 2628 | pMpiEventDataRaid_t pRaidEventData = |
2601 | (pMpiEventDataRaid_t) pEvReply->Data; | 2629 | (pMpiEventDataRaid_t) pEvReply->Data; |
2602 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | ||
2603 | /* Domain Validation Needed */ | 2630 | /* Domain Validation Needed */ |
2604 | if (ioc->bus_type == SCSI && | 2631 | if (ioc->bus_type == SPI && |
2605 | pRaidEventData->ReasonCode == | 2632 | pRaidEventData->ReasonCode == |
2606 | MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) | 2633 | MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) |
2607 | mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum); | 2634 | mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum); |
@@ -2632,8 +2659,7 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
2632 | /* | 2659 | /* |
2633 | * mptscsih_initTarget - Target, LUN alloc/free functionality. | 2660 | * mptscsih_initTarget - Target, LUN alloc/free functionality. |
2634 | * @hd: Pointer to MPT_SCSI_HOST structure | 2661 | * @hd: Pointer to MPT_SCSI_HOST structure |
2635 | * @bus_id: Bus number (?) | 2662 | * @vtarget: per target private data |
2636 | * @target_id: SCSI target id | ||
2637 | * @lun: SCSI LUN id | 2663 | * @lun: SCSI LUN id |
2638 | * @data: Pointer to data | 2664 | * @data: Pointer to data |
2639 | * @dlen: Number of INQUIRY bytes | 2665 | * @dlen: Number of INQUIRY bytes |
@@ -2646,15 +2672,14 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
2646 | * | 2672 | * |
2647 | */ | 2673 | */ |
2648 | static void | 2674 | static void |
2649 | mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen) | 2675 | mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen) |
2650 | { | 2676 | { |
2651 | int indexed_lun, lun_index; | ||
2652 | VirtDevice *vdev; | ||
2653 | SpiCfgData *pSpi; | 2677 | SpiCfgData *pSpi; |
2654 | char data_56; | 2678 | char data_56; |
2679 | int inq_len; | ||
2655 | 2680 | ||
2656 | dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", | 2681 | dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", |
2657 | hd->ioc->name, bus_id, target_id, lun, hd)); | 2682 | hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd)); |
2658 | 2683 | ||
2659 | /* | 2684 | /* |
2660 | * If the peripheral qualifier filter is enabled then if the target reports a 0x1 | 2685 | * If the peripheral qualifier filter is enabled then if the target reports a 0x1 |
@@ -2674,75 +2699,68 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * | |||
2674 | if (data[0] & 0xe0) | 2699 | if (data[0] & 0xe0) |
2675 | return; | 2700 | return; |
2676 | 2701 | ||
2677 | if ((vdev = hd->Targets[target_id]) == NULL) { | 2702 | if (vtarget == NULL) |
2678 | return; | 2703 | return; |
2679 | } | ||
2680 | 2704 | ||
2681 | lun_index = (lun >> 5); /* 32 luns per lun_index */ | 2705 | if (data) |
2682 | indexed_lun = (lun % 32); | 2706 | vtarget->type = data[0]; |
2683 | vdev->luns[lun_index] |= (1 << indexed_lun); | 2707 | |
2684 | 2708 | if (hd->ioc->bus_type != SPI) | |
2685 | if (hd->ioc->bus_type == SCSI) { | 2709 | return; |
2686 | if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { | 2710 | |
2687 | /* Treat all Processors as SAF-TE if | 2711 | if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { |
2688 | * command line option is set */ | 2712 | /* Treat all Processors as SAF-TE if |
2689 | vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | 2713 | * command line option is set */ |
2690 | mptscsih_writeIOCPage4(hd, target_id, bus_id); | 2714 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; |
2691 | }else if ((data[0] == TYPE_PROCESSOR) && | 2715 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); |
2692 | !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { | 2716 | }else if ((data[0] == TYPE_PROCESSOR) && |
2693 | if ( dlen > 49 ) { | 2717 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { |
2694 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | 2718 | if ( dlen > 49 ) { |
2695 | if ( data[44] == 'S' && | 2719 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; |
2696 | data[45] == 'A' && | 2720 | if ( data[44] == 'S' && |
2697 | data[46] == 'F' && | 2721 | data[45] == 'A' && |
2698 | data[47] == '-' && | 2722 | data[46] == 'F' && |
2699 | data[48] == 'T' && | 2723 | data[47] == '-' && |
2700 | data[49] == 'E' ) { | 2724 | data[48] == 'T' && |
2701 | vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | 2725 | data[49] == 'E' ) { |
2702 | mptscsih_writeIOCPage4(hd, target_id, bus_id); | 2726 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; |
2703 | } | 2727 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); |
2704 | } | 2728 | } |
2705 | } | 2729 | } |
2706 | if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { | 2730 | } |
2707 | if ( dlen > 8 ) { | 2731 | if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { |
2708 | memcpy (vdev->inq_data, data, 8); | 2732 | inq_len = dlen < 8 ? dlen : 8; |
2709 | } else { | 2733 | memcpy (vtarget->inq_data, data, inq_len); |
2710 | memcpy (vdev->inq_data, data, dlen); | 2734 | /* If have not done DV, set the DV flag. |
2711 | } | 2735 | */ |
2736 | pSpi = &hd->ioc->spi_data; | ||
2737 | if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) { | ||
2738 | if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE) | ||
2739 | pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV; | ||
2740 | } | ||
2741 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
2712 | 2742 | ||
2713 | /* If have not done DV, set the DV flag. | 2743 | data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */ |
2744 | if (dlen > 56) { | ||
2745 | if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) { | ||
2746 | /* Update the target capabilities | ||
2714 | */ | 2747 | */ |
2715 | pSpi = &hd->ioc->spi_data; | 2748 | data_56 = data[56]; |
2716 | if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) { | 2749 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56; |
2717 | if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE) | ||
2718 | pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV; | ||
2719 | } | ||
2720 | |||
2721 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
2722 | |||
2723 | |||
2724 | data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */ | ||
2725 | if (dlen > 56) { | ||
2726 | if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { | ||
2727 | /* Update the target capabilities | ||
2728 | */ | ||
2729 | data_56 = data[56]; | ||
2730 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; | ||
2731 | } | ||
2732 | } | 2750 | } |
2733 | mptscsih_setTargetNegoParms(hd, vdev, data_56); | 2751 | } |
2734 | } else { | 2752 | mptscsih_setTargetNegoParms(hd, vtarget, data_56); |
2735 | /* Initial Inquiry may not request enough data bytes to | 2753 | } else { |
2736 | * obtain byte 57. DV will; if target doesn't return | 2754 | /* Initial Inquiry may not request enough data bytes to |
2737 | * at least 57 bytes, data[56] will be zero. */ | 2755 | * obtain byte 57. DV will; if target doesn't return |
2738 | if (dlen > 56) { | 2756 | * at least 57 bytes, data[56] will be zero. */ |
2739 | if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { | 2757 | if (dlen > 56) { |
2740 | /* Update the target capabilities | 2758 | if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) { |
2741 | */ | 2759 | /* Update the target capabilities |
2742 | data_56 = data[56]; | 2760 | */ |
2743 | vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; | 2761 | data_56 = data[56]; |
2744 | mptscsih_setTargetNegoParms(hd, vdev, data_56); | 2762 | vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56; |
2745 | } | 2763 | mptscsih_setTargetNegoParms(hd, vtarget, data_56); |
2746 | } | 2764 | } |
2747 | } | 2765 | } |
2748 | } | 2766 | } |
@@ -2755,12 +2773,12 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char * | |||
2755 | * | 2773 | * |
2756 | */ | 2774 | */ |
2757 | static void | 2775 | static void |
2758 | mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) | 2776 | mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56) |
2759 | { | 2777 | { |
2760 | SpiCfgData *pspi_data = &hd->ioc->spi_data; | 2778 | SpiCfgData *pspi_data = &hd->ioc->spi_data; |
2761 | int id = (int) target->target_id; | 2779 | int id = (int) target->target_id; |
2762 | int nvram; | 2780 | int nvram; |
2763 | VirtDevice *vdev; | 2781 | VirtTarget *vtarget; |
2764 | int ii; | 2782 | int ii; |
2765 | u8 width = MPT_NARROW; | 2783 | u8 width = MPT_NARROW; |
2766 | u8 factor = MPT_ASYNC; | 2784 | u8 factor = MPT_ASYNC; |
@@ -2905,9 +2923,9 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) | |||
2905 | 2923 | ||
2906 | ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); | 2924 | ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); |
2907 | for (ii = 0; ii < id; ii++) { | 2925 | for (ii = 0; ii < id; ii++) { |
2908 | if ( (vdev = hd->Targets[ii]) ) { | 2926 | if ( (vtarget = hd->Targets[ii]) ) { |
2909 | vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | 2927 | vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; |
2910 | mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags); | 2928 | mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags); |
2911 | } | 2929 | } |
2912 | } | 2930 | } |
2913 | } | 2931 | } |
@@ -2926,105 +2944,17 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) | |||
2926 | } | 2944 | } |
2927 | 2945 | ||
2928 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2946 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2929 | /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return. | ||
2930 | * Else set the NEED_DV flag after Read Capacity Issued (disks) | ||
2931 | * or Mode Sense (cdroms). | ||
2932 | * | ||
2933 | * Tapes, initTarget will set this flag on completion of Inquiry command. | ||
2934 | * Called only if DV_NOT_DONE flag is set | ||
2935 | */ | ||
2936 | static void | ||
2937 | mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) | ||
2938 | { | ||
2939 | MPT_ADAPTER *ioc = hd->ioc; | ||
2940 | u8 cmd; | ||
2941 | SpiCfgData *pSpi; | ||
2942 | |||
2943 | ddvtprintk((MYIOC_s_NOTE_FMT | ||
2944 | " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", | ||
2945 | hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0])); | ||
2946 | |||
2947 | if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0)) | ||
2948 | return; | ||
2949 | |||
2950 | cmd = pReq->CDB[0]; | ||
2951 | |||
2952 | if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { | ||
2953 | pSpi = &ioc->spi_data; | ||
2954 | if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) { | ||
2955 | /* Set NEED_DV for all hidden disks | ||
2956 | */ | ||
2957 | Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; | ||
2958 | int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; | ||
2959 | |||
2960 | while (numPDisk) { | ||
2961 | pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; | ||
2962 | ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID)); | ||
2963 | pPDisk++; | ||
2964 | numPDisk--; | ||
2965 | } | ||
2966 | } | ||
2967 | pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV; | ||
2968 | ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID)); | ||
2969 | } | ||
2970 | } | ||
2971 | |||
2972 | /* mptscsih_raid_set_dv_flags() | ||
2973 | * | ||
2974 | * New or replaced disk. Set DV flag and schedule DV. | ||
2975 | */ | ||
2976 | static void | ||
2977 | mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id) | ||
2978 | { | ||
2979 | MPT_ADAPTER *ioc = hd->ioc; | ||
2980 | SpiCfgData *pSpi = &ioc->spi_data; | ||
2981 | Ioc3PhysDisk_t *pPDisk; | ||
2982 | int numPDisk; | ||
2983 | |||
2984 | if (hd->negoNvram != 0) | ||
2985 | return; | ||
2986 | |||
2987 | ddvtprintk(("DV requested for phys disk id %d\n", id)); | ||
2988 | if (ioc->raid_data.pIocPg3) { | ||
2989 | pPDisk = ioc->raid_data.pIocPg3->PhysDisk; | ||
2990 | numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; | ||
2991 | while (numPDisk) { | ||
2992 | if (id == pPDisk->PhysDiskNum) { | ||
2993 | pSpi->dvStatus[pPDisk->PhysDiskID] = | ||
2994 | (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE); | ||
2995 | pSpi->forceDv = MPT_SCSICFG_NEED_DV; | ||
2996 | ddvtprintk(("NEED_DV set for phys disk id %d\n", | ||
2997 | pPDisk->PhysDiskID)); | ||
2998 | break; | ||
2999 | } | ||
3000 | pPDisk++; | ||
3001 | numPDisk--; | ||
3002 | } | ||
3003 | |||
3004 | if (numPDisk == 0) { | ||
3005 | /* The physical disk that needs DV was not found | ||
3006 | * in the stored IOC Page 3. The driver must reload | ||
3007 | * this page. DV routine will set the NEED_DV flag for | ||
3008 | * all phys disks that have DV_NOT_DONE set. | ||
3009 | */ | ||
3010 | pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; | ||
3011 | ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id)); | ||
3012 | } | ||
3013 | } | ||
3014 | } | ||
3015 | |||
3016 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
3017 | /* | 2947 | /* |
3018 | * If no Target, bus reset on 1st I/O. Set the flag to | 2948 | * If no Target, bus reset on 1st I/O. Set the flag to |
3019 | * prevent any future negotiations to this device. | 2949 | * prevent any future negotiations to this device. |
3020 | */ | 2950 | */ |
3021 | static void | 2951 | static void |
3022 | mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id) | 2952 | mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc) |
3023 | { | 2953 | { |
2954 | VirtDevice *vdev; | ||
3024 | 2955 | ||
3025 | if ((hd->Targets) && (hd->Targets[target_id] == NULL)) | 2956 | if ((vdev = sc->device->hostdata) != NULL) |
3026 | hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO; | 2957 | hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO; |
3027 | |||
3028 | return; | 2958 | return; |
3029 | } | 2959 | } |
3030 | 2960 | ||
@@ -3100,7 +3030,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) | |||
3100 | MPT_ADAPTER *ioc = hd->ioc; | 3030 | MPT_ADAPTER *ioc = hd->ioc; |
3101 | Config_t *pReq; | 3031 | Config_t *pReq; |
3102 | SCSIDevicePage1_t *pData; | 3032 | SCSIDevicePage1_t *pData; |
3103 | VirtDevice *pTarget=NULL; | 3033 | VirtTarget *vtarget=NULL; |
3104 | MPT_FRAME_HDR *mf; | 3034 | MPT_FRAME_HDR *mf; |
3105 | dma_addr_t dataDma; | 3035 | dma_addr_t dataDma; |
3106 | u16 req_idx; | 3036 | u16 req_idx; |
@@ -3180,11 +3110,11 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) | |||
3180 | /* If id is not a raid volume, get the updated | 3110 | /* If id is not a raid volume, get the updated |
3181 | * transmission settings from the target structure. | 3111 | * transmission settings from the target structure. |
3182 | */ | 3112 | */ |
3183 | if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) { | 3113 | if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) { |
3184 | width = pTarget->maxWidth; | 3114 | width = vtarget->maxWidth; |
3185 | factor = pTarget->minSyncFactor; | 3115 | factor = vtarget->minSyncFactor; |
3186 | offset = pTarget->maxOffset; | 3116 | offset = vtarget->maxOffset; |
3187 | negoFlags = pTarget->negoFlags; | 3117 | negoFlags = vtarget->negoFlags; |
3188 | } | 3118 | } |
3189 | 3119 | ||
3190 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | 3120 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION |
@@ -3904,149 +3834,139 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3904 | 3834 | ||
3905 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 3835 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
3906 | /** | 3836 | /** |
3907 | * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. | 3837 | * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state |
3908 | * @hd: Pointer to MPT_SCSI_HOST structure | 3838 | * @hd: Pointer to a SCSI HOST structure |
3909 | * @portnum: IOC port number | 3839 | * @vtarget: per device private data |
3910 | * | 3840 | * |
3911 | * Uses the ISR, but with special processing. | 3841 | * Uses the ISR, but with special processing. |
3912 | * MUST be single-threaded. | 3842 | * MUST be single-threaded. |
3913 | * | 3843 | * |
3914 | * Return: 0 on completion | ||
3915 | */ | 3844 | */ |
3916 | static int | 3845 | static void |
3917 | mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) | 3846 | mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) |
3918 | { | 3847 | { |
3919 | MPT_ADAPTER *ioc= hd->ioc; | 3848 | MPT_ADAPTER *ioc= hd->ioc; |
3920 | VirtDevice *pTarget; | 3849 | SCSIDevicePage1_t *pcfg1Data; |
3921 | SCSIDevicePage1_t *pcfg1Data = NULL; | ||
3922 | INTERNAL_CMD iocmd; | ||
3923 | CONFIGPARMS cfg; | 3850 | CONFIGPARMS cfg; |
3924 | dma_addr_t cfg1_dma_addr = -1; | 3851 | dma_addr_t cfg1_dma_addr; |
3925 | ConfigPageHeader_t header1; | 3852 | ConfigPageHeader_t header; |
3926 | int bus = 0; | 3853 | int id; |
3927 | int id = 0; | 3854 | int requested, configuration, data,i; |
3928 | int lun; | ||
3929 | int indexed_lun, lun_index; | ||
3930 | int hostId = ioc->pfacts[portnum].PortSCSIID; | ||
3931 | int max_id; | ||
3932 | int requested, configuration, data; | ||
3933 | int doConfig = 0; | ||
3934 | u8 flags, factor; | 3855 | u8 flags, factor; |
3935 | 3856 | ||
3936 | max_id = ioc->sh->max_id - 1; | 3857 | if (ioc->bus_type != SPI) |
3937 | 3858 | return; | |
3938 | /* Following parameters will not change | ||
3939 | * in this routine. | ||
3940 | */ | ||
3941 | iocmd.cmd = SYNCHRONIZE_CACHE; | ||
3942 | iocmd.flags = 0; | ||
3943 | iocmd.physDiskNum = -1; | ||
3944 | iocmd.data = NULL; | ||
3945 | iocmd.data_dma = -1; | ||
3946 | iocmd.size = 0; | ||
3947 | iocmd.rsvd = iocmd.rsvd2 = 0; | ||
3948 | |||
3949 | /* No SCSI hosts | ||
3950 | */ | ||
3951 | if (hd->Targets == NULL) | ||
3952 | return 0; | ||
3953 | |||
3954 | /* Skip the host | ||
3955 | */ | ||
3956 | if (id == hostId) | ||
3957 | id++; | ||
3958 | |||
3959 | /* Write SDP1 for all SCSI devices | ||
3960 | * Alloc memory and set up config buffer | ||
3961 | */ | ||
3962 | if (ioc->bus_type == SCSI) { | ||
3963 | if (ioc->spi_data.sdp1length > 0) { | ||
3964 | pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev, | ||
3965 | ioc->spi_data.sdp1length * 4, &cfg1_dma_addr); | ||
3966 | |||
3967 | if (pcfg1Data != NULL) { | ||
3968 | doConfig = 1; | ||
3969 | header1.PageVersion = ioc->spi_data.sdp1version; | ||
3970 | header1.PageLength = ioc->spi_data.sdp1length; | ||
3971 | header1.PageNumber = 1; | ||
3972 | header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; | ||
3973 | cfg.cfghdr.hdr = &header1; | ||
3974 | cfg.physAddr = cfg1_dma_addr; | ||
3975 | cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
3976 | cfg.dir = 1; | ||
3977 | cfg.timeout = 0; | ||
3978 | } | ||
3979 | } | ||
3980 | } | ||
3981 | 3859 | ||
3982 | /* loop through all devices on this port | 3860 | if (!ioc->spi_data.sdp1length) |
3983 | */ | 3861 | return; |
3984 | while (bus < MPT_MAX_BUS) { | ||
3985 | iocmd.bus = bus; | ||
3986 | iocmd.id = id; | ||
3987 | pTarget = hd->Targets[(int)id]; | ||
3988 | 3862 | ||
3989 | if (doConfig) { | 3863 | pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev, |
3864 | ioc->spi_data.sdp1length * 4, &cfg1_dma_addr); | ||
3990 | 3865 | ||
3991 | /* Set the negotiation flags */ | 3866 | if (pcfg1Data == NULL) |
3992 | if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) { | 3867 | return; |
3993 | flags = pTarget->negoFlags; | ||
3994 | } else { | ||
3995 | flags = hd->ioc->spi_data.noQas; | ||
3996 | if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
3997 | data = hd->ioc->spi_data.nvram[id]; | ||
3998 | 3868 | ||
3999 | if (data & MPT_NVRAM_WIDE_DISABLE) | 3869 | header.PageVersion = ioc->spi_data.sdp1version; |
4000 | flags |= MPT_TARGET_NO_NEGO_WIDE; | 3870 | header.PageLength = ioc->spi_data.sdp1length; |
3871 | header.PageNumber = 1; | ||
3872 | header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; | ||
3873 | cfg.cfghdr.hdr = &header; | ||
3874 | cfg.physAddr = cfg1_dma_addr; | ||
3875 | cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
3876 | cfg.dir = 1; | ||
3877 | cfg.timeout = 0; | ||
4001 | 3878 | ||
4002 | factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; | 3879 | if (vtarget->raidVolume && ioc->raid_data.pIocPg3) { |
4003 | if ((factor == 0) || (factor == MPT_ASYNC)) | 3880 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { |
4004 | flags |= MPT_TARGET_NO_NEGO_SYNC; | 3881 | id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID; |
4005 | } | 3882 | flags = hd->ioc->spi_data.noQas; |
3883 | if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
3884 | data = hd->ioc->spi_data.nvram[id]; | ||
3885 | if (data & MPT_NVRAM_WIDE_DISABLE) | ||
3886 | flags |= MPT_TARGET_NO_NEGO_WIDE; | ||
3887 | factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; | ||
3888 | if ((factor == 0) || (factor == MPT_ASYNC)) | ||
3889 | flags |= MPT_TARGET_NO_NEGO_SYNC; | ||
4006 | } | 3890 | } |
4007 | |||
4008 | /* Force to async, narrow */ | ||
4009 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, | 3891 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, |
4010 | &configuration, flags); | 3892 | &configuration, flags); |
4011 | dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " | 3893 | dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " |
4012 | "offset=0 negoFlags=%x request=%x config=%x\n", | 3894 | "offset=0 negoFlags=%x request=%x config=%x\n", |
4013 | id, flags, requested, configuration)); | 3895 | id, flags, requested, configuration)); |
4014 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); | 3896 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); |
4015 | pcfg1Data->Reserved = 0; | 3897 | pcfg1Data->Reserved = 0; |
4016 | pcfg1Data->Configuration = cpu_to_le32(configuration); | 3898 | pcfg1Data->Configuration = cpu_to_le32(configuration); |
4017 | cfg.pageAddr = (bus<<8) | id; | 3899 | cfg.pageAddr = (vtarget->bus_id<<8) | id; |
4018 | mpt_config(hd->ioc, &cfg); | 3900 | mpt_config(hd->ioc, &cfg); |
4019 | } | 3901 | } |
3902 | } else { | ||
3903 | flags = vtarget->negoFlags; | ||
3904 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, | ||
3905 | &configuration, flags); | ||
3906 | dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " | ||
3907 | "offset=0 negoFlags=%x request=%x config=%x\n", | ||
3908 | vtarget->target_id, flags, requested, configuration)); | ||
3909 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); | ||
3910 | pcfg1Data->Reserved = 0; | ||
3911 | pcfg1Data->Configuration = cpu_to_le32(configuration); | ||
3912 | cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id; | ||
3913 | mpt_config(hd->ioc, &cfg); | ||
3914 | } | ||
4020 | 3915 | ||
4021 | /* If target Ptr NULL or if this target is NOT a disk, skip. | 3916 | if (pcfg1Data) |
4022 | */ | 3917 | pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr); |
4023 | if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){ | 3918 | } |
4024 | for (lun=0; lun <= MPT_LAST_LUN; lun++) { | ||
4025 | /* If LUN present, issue the command | ||
4026 | */ | ||
4027 | lun_index = (lun >> 5); /* 32 luns per lun_index */ | ||
4028 | indexed_lun = (lun % 32); | ||
4029 | if (pTarget->luns[lun_index] & (1<<indexed_lun)) { | ||
4030 | iocmd.lun = lun; | ||
4031 | (void) mptscsih_do_cmd(hd, &iocmd); | ||
4032 | } | ||
4033 | } | ||
4034 | } | ||
4035 | 3919 | ||
4036 | /* get next relevant device */ | 3920 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
4037 | id++; | 3921 | /** |
3922 | * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. | ||
3923 | * @hd: Pointer to a SCSI HOST structure | ||
3924 | * @vtarget: per device private data | ||
3925 | * @lun: lun | ||
3926 | * | ||
3927 | * Uses the ISR, but with special processing. | ||
3928 | * MUST be single-threaded. | ||
3929 | * | ||
3930 | */ | ||
3931 | static void | ||
3932 | mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | ||
3933 | { | ||
3934 | INTERNAL_CMD iocmd; | ||
4038 | 3935 | ||
4039 | if (id == hostId) | 3936 | /* Following parameters will not change |
4040 | id++; | 3937 | * in this routine. |
3938 | */ | ||
3939 | iocmd.cmd = SYNCHRONIZE_CACHE; | ||
3940 | iocmd.flags = 0; | ||
3941 | iocmd.physDiskNum = -1; | ||
3942 | iocmd.data = NULL; | ||
3943 | iocmd.data_dma = -1; | ||
3944 | iocmd.size = 0; | ||
3945 | iocmd.rsvd = iocmd.rsvd2 = 0; | ||
3946 | iocmd.bus = vdevice->bus_id; | ||
3947 | iocmd.id = vdevice->target_id; | ||
3948 | iocmd.lun = (u8)vdevice->lun; | ||
4041 | 3949 | ||
4042 | if (id > max_id) { | 3950 | if ((vdevice->vtarget->type & TYPE_DISK) && |
4043 | id = 0; | 3951 | (vdevice->configured_lun)) |
4044 | bus++; | 3952 | mptscsih_do_cmd(hd, &iocmd); |
4045 | } | 3953 | } |
4046 | } | ||
4047 | 3954 | ||
4048 | if (pcfg1Data) { | 3955 | /* Search IOC page 3 to determine if this is hidden physical disk |
4049 | pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr); | 3956 | */ |
3957 | /* Search IOC page 3 to determine if this is hidden physical disk | ||
3958 | */ | ||
3959 | static int | ||
3960 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) | ||
3961 | { | ||
3962 | int i; | ||
3963 | |||
3964 | if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) | ||
3965 | return 0; | ||
3966 | |||
3967 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { | ||
3968 | if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) | ||
3969 | return 1; | ||
4050 | } | 3970 | } |
4051 | 3971 | ||
4052 | return 0; | 3972 | return 0; |
@@ -4101,8 +4021,8 @@ mptscsih_domainValidation(void *arg) | |||
4101 | 4021 | ||
4102 | msleep(250); | 4022 | msleep(250); |
4103 | 4023 | ||
4104 | /* DV only to SCSI adapters */ | 4024 | /* DV only to SPI adapters */ |
4105 | if (ioc->bus_type != SCSI) | 4025 | if (ioc->bus_type != SPI) |
4106 | continue; | 4026 | continue; |
4107 | 4027 | ||
4108 | /* Make sure everything looks ok */ | 4028 | /* Make sure everything looks ok */ |
@@ -4205,32 +4125,12 @@ mptscsih_domainValidation(void *arg) | |||
4205 | return; | 4125 | return; |
4206 | } | 4126 | } |
4207 | 4127 | ||
4208 | /* Search IOC page 3 to determine if this is hidden physical disk | ||
4209 | */ | ||
4210 | /* Search IOC page 3 to determine if this is hidden physical disk | ||
4211 | */ | ||
4212 | static int | ||
4213 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) | ||
4214 | { | ||
4215 | int i; | ||
4216 | |||
4217 | if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) | ||
4218 | return 0; | ||
4219 | |||
4220 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { | ||
4221 | if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) | ||
4222 | return 1; | ||
4223 | } | ||
4224 | |||
4225 | return 0; | ||
4226 | } | ||
4227 | |||
4228 | /* Write SDP1 if no QAS has been enabled | 4128 | /* Write SDP1 if no QAS has been enabled |
4229 | */ | 4129 | */ |
4230 | static void | 4130 | static void |
4231 | mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) | 4131 | mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) |
4232 | { | 4132 | { |
4233 | VirtDevice *pTarget; | 4133 | VirtTarget *vtarget; |
4234 | int ii; | 4134 | int ii; |
4235 | 4135 | ||
4236 | if (hd->Targets == NULL) | 4136 | if (hd->Targets == NULL) |
@@ -4243,11 +4143,11 @@ mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) | |||
4243 | if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0) | 4143 | if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0) |
4244 | continue; | 4144 | continue; |
4245 | 4145 | ||
4246 | pTarget = hd->Targets[ii]; | 4146 | vtarget = hd->Targets[ii]; |
4247 | 4147 | ||
4248 | if ((pTarget != NULL) && (!pTarget->raidVolume)) { | 4148 | if ((vtarget != NULL) && (!vtarget->raidVolume)) { |
4249 | if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) { | 4149 | if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) { |
4250 | pTarget->negoFlags |= hd->ioc->spi_data.noQas; | 4150 | vtarget->negoFlags |= hd->ioc->spi_data.noQas; |
4251 | dnegoprintk(("writeSDP1: id=%d flags=0\n", id)); | 4151 | dnegoprintk(("writeSDP1: id=%d flags=0\n", id)); |
4252 | mptscsih_writeSDP1(hd, 0, ii, 0); | 4152 | mptscsih_writeSDP1(hd, 0, ii, 0); |
4253 | } | 4153 | } |
@@ -4287,7 +4187,7 @@ static int | |||
4287 | mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | 4187 | mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) |
4288 | { | 4188 | { |
4289 | MPT_ADAPTER *ioc = hd->ioc; | 4189 | MPT_ADAPTER *ioc = hd->ioc; |
4290 | VirtDevice *pTarget; | 4190 | VirtTarget *vtarget; |
4291 | SCSIDevicePage1_t *pcfg1Data; | 4191 | SCSIDevicePage1_t *pcfg1Data; |
4292 | SCSIDevicePage0_t *pcfg0Data; | 4192 | SCSIDevicePage0_t *pcfg0Data; |
4293 | u8 *pbuf1; | 4193 | u8 *pbuf1; |
@@ -4358,12 +4258,12 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
4358 | iocmd.physDiskNum = -1; | 4258 | iocmd.physDiskNum = -1; |
4359 | iocmd.rsvd = iocmd.rsvd2 = 0; | 4259 | iocmd.rsvd = iocmd.rsvd2 = 0; |
4360 | 4260 | ||
4361 | pTarget = hd->Targets[id]; | 4261 | vtarget = hd->Targets[id]; |
4362 | 4262 | ||
4363 | /* Use tagged commands if possible. | 4263 | /* Use tagged commands if possible. |
4364 | */ | 4264 | */ |
4365 | if (pTarget) { | 4265 | if (vtarget) { |
4366 | if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) | 4266 | if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) |
4367 | iocmd.flags |= MPT_ICFLAG_TAGGED_CMD; | 4267 | iocmd.flags |= MPT_ICFLAG_TAGGED_CMD; |
4368 | else { | 4268 | else { |
4369 | if (hd->ioc->facts.FWVersion.Word < 0x01000600) | 4269 | if (hd->ioc->facts.FWVersion.Word < 0x01000600) |
@@ -4579,7 +4479,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
4579 | /* Reset the size for disks | 4479 | /* Reset the size for disks |
4580 | */ | 4480 | */ |
4581 | inq0 = (*pbuf1) & 0x1F; | 4481 | inq0 = (*pbuf1) & 0x1F; |
4582 | if ((inq0 == 0) && pTarget && !pTarget->raidVolume) { | 4482 | if ((inq0 == 0) && vtarget && !vtarget->raidVolume) { |
4583 | sz = 0x40; | 4483 | sz = 0x40; |
4584 | iocmd.size = sz; | 4484 | iocmd.size = sz; |
4585 | } | 4485 | } |
@@ -4589,8 +4489,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
4589 | */ | 4489 | */ |
4590 | if (inq0 == TYPE_PROCESSOR) { | 4490 | if (inq0 == TYPE_PROCESSOR) { |
4591 | mptscsih_initTarget(hd, | 4491 | mptscsih_initTarget(hd, |
4592 | bus, | 4492 | vtarget, |
4593 | id, | ||
4594 | lun, | 4493 | lun, |
4595 | pbuf1, | 4494 | pbuf1, |
4596 | sz); | 4495 | sz); |
@@ -4604,22 +4503,22 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
4604 | goto target_done; | 4503 | goto target_done; |
4605 | 4504 | ||
4606 | if (sz == 0x40) { | 4505 | if (sz == 0x40) { |
4607 | if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A) | 4506 | if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A) |
4608 | && (pTarget->minSyncFactor > 0x09)) { | 4507 | && (vtarget->minSyncFactor > 0x09)) { |
4609 | if ((pbuf1[56] & 0x04) == 0) | 4508 | if ((pbuf1[56] & 0x04) == 0) |
4610 | ; | 4509 | ; |
4611 | else if ((pbuf1[56] & 0x01) == 1) { | 4510 | else if ((pbuf1[56] & 0x01) == 1) { |
4612 | pTarget->minSyncFactor = | 4511 | vtarget->minSyncFactor = |
4613 | nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; | 4512 | nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; |
4614 | } else { | 4513 | } else { |
4615 | pTarget->minSyncFactor = | 4514 | vtarget->minSyncFactor = |
4616 | nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; | 4515 | nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; |
4617 | } | 4516 | } |
4618 | 4517 | ||
4619 | dv.max.factor = pTarget->minSyncFactor; | 4518 | dv.max.factor = vtarget->minSyncFactor; |
4620 | 4519 | ||
4621 | if ((pbuf1[56] & 0x02) == 0) { | 4520 | if ((pbuf1[56] & 0x02) == 0) { |
4622 | pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | 4521 | vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; |
4623 | hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; | 4522 | hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; |
4624 | ddvprintk((MYIOC_s_NOTE_FMT | 4523 | ddvprintk((MYIOC_s_NOTE_FMT |
4625 | "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", | 4524 | "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", |
@@ -4702,8 +4601,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) | |||
4702 | "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); | 4601 | "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); |
4703 | hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; | 4602 | hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; |
4704 | mptscsih_initTarget(hd, | 4603 | mptscsih_initTarget(hd, |
4705 | bus, | 4604 | vtarget, |
4706 | id, | ||
4707 | lun, | 4605 | lun, |
4708 | pbuf1, | 4606 | pbuf1, |
4709 | sz); | 4607 | sz); |
@@ -5204,7 +5102,7 @@ target_done: | |||
5204 | static void | 5102 | static void |
5205 | mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) | 5103 | mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) |
5206 | { | 5104 | { |
5207 | VirtDevice *pTarget; | 5105 | VirtTarget *vtarget; |
5208 | SCSIDevicePage0_t *pPage0; | 5106 | SCSIDevicePage0_t *pPage0; |
5209 | SCSIDevicePage1_t *pPage1; | 5107 | SCSIDevicePage1_t *pPage1; |
5210 | int val = 0, data, configuration; | 5108 | int val = 0, data, configuration; |
@@ -5224,11 +5122,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) | |||
5224 | * already throttled back. | 5122 | * already throttled back. |
5225 | */ | 5123 | */ |
5226 | negoFlags = hd->ioc->spi_data.noQas; | 5124 | negoFlags = hd->ioc->spi_data.noQas; |
5227 | if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) { | 5125 | if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) { |
5228 | width = pTarget->maxWidth; | 5126 | width = vtarget->maxWidth; |
5229 | offset = pTarget->maxOffset; | 5127 | offset = vtarget->maxOffset; |
5230 | factor = pTarget->minSyncFactor; | 5128 | factor = vtarget->minSyncFactor; |
5231 | negoFlags |= pTarget->negoFlags; | 5129 | negoFlags |= vtarget->negoFlags; |
5232 | } else { | 5130 | } else { |
5233 | if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { | 5131 | if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { |
5234 | data = hd->ioc->spi_data.nvram[id]; | 5132 | data = hd->ioc->spi_data.nvram[id]; |
@@ -5430,11 +5328,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) | |||
5430 | * or overwrite nvram (phys disks only). | 5328 | * or overwrite nvram (phys disks only). |
5431 | */ | 5329 | */ |
5432 | 5330 | ||
5433 | if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) { | 5331 | if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) { |
5434 | pTarget->maxWidth = dv->now.width; | 5332 | vtarget->maxWidth = dv->now.width; |
5435 | pTarget->maxOffset = dv->now.offset; | 5333 | vtarget->maxOffset = dv->now.offset; |
5436 | pTarget->minSyncFactor = dv->now.factor; | 5334 | vtarget->minSyncFactor = dv->now.factor; |
5437 | pTarget->negoFlags = dv->now.flags; | 5335 | vtarget->negoFlags = dv->now.flags; |
5438 | } else { | 5336 | } else { |
5439 | /* Preserv all flags, use | 5337 | /* Preserv all flags, use |
5440 | * read-modify-write algorithm | 5338 | * read-modify-write algorithm |
@@ -5588,6 +5486,94 @@ mptscsih_fillbuf(char *buffer, int size, int index, int width) | |||
5588 | break; | 5486 | break; |
5589 | } | 5487 | } |
5590 | } | 5488 | } |
5489 | |||
5490 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
5491 | /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return. | ||
5492 | * Else set the NEED_DV flag after Read Capacity Issued (disks) | ||
5493 | * or Mode Sense (cdroms). | ||
5494 | * | ||
5495 | * Tapes, initTarget will set this flag on completion of Inquiry command. | ||
5496 | * Called only if DV_NOT_DONE flag is set | ||
5497 | */ | ||
5498 | static void | ||
5499 | mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc) | ||
5500 | { | ||
5501 | MPT_ADAPTER *ioc = hd->ioc; | ||
5502 | u8 cmd; | ||
5503 | SpiCfgData *pSpi; | ||
5504 | |||
5505 | ddvtprintk((MYIOC_s_NOTE_FMT | ||
5506 | " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", | ||
5507 | hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0])); | ||
5508 | |||
5509 | if ((sc->device->lun != 0) || (hd->negoNvram != 0)) | ||
5510 | return; | ||
5511 | |||
5512 | cmd = sc->cmnd[0]; | ||
5513 | |||
5514 | if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { | ||
5515 | pSpi = &ioc->spi_data; | ||
5516 | if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) { | ||
5517 | /* Set NEED_DV for all hidden disks | ||
5518 | */ | ||
5519 | Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; | ||
5520 | int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; | ||
5521 | |||
5522 | while (numPDisk) { | ||
5523 | pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; | ||
5524 | ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID)); | ||
5525 | pPDisk++; | ||
5526 | numPDisk--; | ||
5527 | } | ||
5528 | } | ||
5529 | pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV; | ||
5530 | ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id)); | ||
5531 | } | ||
5532 | } | ||
5533 | |||
5534 | /* mptscsih_raid_set_dv_flags() | ||
5535 | * | ||
5536 | * New or replaced disk. Set DV flag and schedule DV. | ||
5537 | */ | ||
5538 | static void | ||
5539 | mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id) | ||
5540 | { | ||
5541 | MPT_ADAPTER *ioc = hd->ioc; | ||
5542 | SpiCfgData *pSpi = &ioc->spi_data; | ||
5543 | Ioc3PhysDisk_t *pPDisk; | ||
5544 | int numPDisk; | ||
5545 | |||
5546 | if (hd->negoNvram != 0) | ||
5547 | return; | ||
5548 | |||
5549 | ddvtprintk(("DV requested for phys disk id %d\n", id)); | ||
5550 | if (ioc->raid_data.pIocPg3) { | ||
5551 | pPDisk = ioc->raid_data.pIocPg3->PhysDisk; | ||
5552 | numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; | ||
5553 | while (numPDisk) { | ||
5554 | if (id == pPDisk->PhysDiskNum) { | ||
5555 | pSpi->dvStatus[pPDisk->PhysDiskID] = | ||
5556 | (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE); | ||
5557 | pSpi->forceDv = MPT_SCSICFG_NEED_DV; | ||
5558 | ddvtprintk(("NEED_DV set for phys disk id %d\n", | ||
5559 | pPDisk->PhysDiskID)); | ||
5560 | break; | ||
5561 | } | ||
5562 | pPDisk++; | ||
5563 | numPDisk--; | ||
5564 | } | ||
5565 | |||
5566 | if (numPDisk == 0) { | ||
5567 | /* The physical disk that needs DV was not found | ||
5568 | * in the stored IOC Page 3. The driver must reload | ||
5569 | * this page. DV routine will set the NEED_DV flag for | ||
5570 | * all phys disks that have DV_NOT_DONE set. | ||
5571 | */ | ||
5572 | pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; | ||
5573 | ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id)); | ||
5574 | } | ||
5575 | } | ||
5576 | } | ||
5591 | #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ | 5577 | #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ |
5592 | 5578 | ||
5593 | EXPORT_SYMBOL(mptscsih_remove); | 5579 | EXPORT_SYMBOL(mptscsih_remove); |
@@ -5599,7 +5585,9 @@ EXPORT_SYMBOL(mptscsih_resume); | |||
5599 | EXPORT_SYMBOL(mptscsih_proc_info); | 5585 | EXPORT_SYMBOL(mptscsih_proc_info); |
5600 | EXPORT_SYMBOL(mptscsih_info); | 5586 | EXPORT_SYMBOL(mptscsih_info); |
5601 | EXPORT_SYMBOL(mptscsih_qcmd); | 5587 | EXPORT_SYMBOL(mptscsih_qcmd); |
5588 | EXPORT_SYMBOL(mptscsih_target_alloc); | ||
5602 | EXPORT_SYMBOL(mptscsih_slave_alloc); | 5589 | EXPORT_SYMBOL(mptscsih_slave_alloc); |
5590 | EXPORT_SYMBOL(mptscsih_target_destroy); | ||
5603 | EXPORT_SYMBOL(mptscsih_slave_destroy); | 5591 | EXPORT_SYMBOL(mptscsih_slave_destroy); |
5604 | EXPORT_SYMBOL(mptscsih_slave_configure); | 5592 | EXPORT_SYMBOL(mptscsih_slave_configure); |
5605 | EXPORT_SYMBOL(mptscsih_abort); | 5593 | EXPORT_SYMBOL(mptscsih_abort); |