diff options
Diffstat (limited to 'drivers/message/fusion/mptctl.c')
-rw-r--r-- | drivers/message/fusion/mptctl.c | 159 |
1 files changed, 51 insertions, 108 deletions
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 504632da4347..922d0c879f06 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -361,7 +361,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) | |||
361 | ioctl->ioc->name, mf)); | 361 | ioctl->ioc->name, mf)); |
362 | 362 | ||
363 | pScsiTm = (SCSITaskMgmt_t *) mf; | 363 | pScsiTm = (SCSITaskMgmt_t *) mf; |
364 | pScsiTm->TargetID = ioctl->target; | 364 | pScsiTm->TargetID = ioctl->id; |
365 | pScsiTm->Bus = hd->port; /* 0 */ | 365 | pScsiTm->Bus = hd->port; /* 0 */ |
366 | pScsiTm->ChainOffset = 0; | 366 | pScsiTm->ChainOffset = 0; |
367 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; | 367 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; |
@@ -1159,15 +1159,12 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1159 | struct mpt_ioctl_iocinfo *karg; | 1159 | struct mpt_ioctl_iocinfo *karg; |
1160 | MPT_ADAPTER *ioc; | 1160 | MPT_ADAPTER *ioc; |
1161 | struct pci_dev *pdev; | 1161 | struct pci_dev *pdev; |
1162 | struct Scsi_Host *sh; | ||
1163 | MPT_SCSI_HOST *hd; | ||
1164 | int iocnum; | 1162 | int iocnum; |
1165 | int numDevices = 0; | ||
1166 | unsigned int max_id; | ||
1167 | int ii; | ||
1168 | unsigned int port; | 1163 | unsigned int port; |
1169 | int cim_rev; | 1164 | int cim_rev; |
1170 | u8 revision; | 1165 | u8 revision; |
1166 | struct scsi_device *sdev; | ||
1167 | VirtDevice *vdev; | ||
1171 | 1168 | ||
1172 | dctlprintk((": mptctl_getiocinfo called.\n")); | 1169 | dctlprintk((": mptctl_getiocinfo called.\n")); |
1173 | /* Add of PCI INFO results in unaligned access for | 1170 | /* Add of PCI INFO results in unaligned access for |
@@ -1257,23 +1254,16 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1257 | 1254 | ||
1258 | /* Get number of devices | 1255 | /* Get number of devices |
1259 | */ | 1256 | */ |
1260 | if ((sh = ioc->sh) != NULL) { | 1257 | karg->numDevices = 0; |
1261 | /* sh->max_id = maximum target ID + 1 | 1258 | if (ioc->sh) { |
1262 | */ | 1259 | shost_for_each_device(sdev, ioc->sh) { |
1263 | max_id = sh->max_id - 1; | 1260 | vdev = sdev->hostdata; |
1264 | hd = (MPT_SCSI_HOST *) sh->hostdata; | 1261 | if (vdev->vtarget->tflags & |
1265 | 1262 | MPT_TARGET_FLAGS_RAID_COMPONENT) | |
1266 | /* Check all of the target structures and | 1263 | continue; |
1267 | * keep a counter. | 1264 | karg->numDevices++; |
1268 | */ | ||
1269 | if (hd && hd->Targets) { | ||
1270 | for (ii = 0; ii <= max_id; ii++) { | ||
1271 | if (hd->Targets[ii]) | ||
1272 | numDevices++; | ||
1273 | } | ||
1274 | } | 1265 | } |
1275 | } | 1266 | } |
1276 | karg->numDevices = numDevices; | ||
1277 | 1267 | ||
1278 | /* Set the BIOS and FW Version | 1268 | /* Set the BIOS and FW Version |
1279 | */ | 1269 | */ |
@@ -1319,21 +1309,16 @@ mptctl_gettargetinfo (unsigned long arg) | |||
1319 | struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; | 1309 | struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; |
1320 | struct mpt_ioctl_targetinfo karg; | 1310 | struct mpt_ioctl_targetinfo karg; |
1321 | MPT_ADAPTER *ioc; | 1311 | MPT_ADAPTER *ioc; |
1322 | struct Scsi_Host *sh; | 1312 | VirtDevice *vdev; |
1323 | MPT_SCSI_HOST *hd; | ||
1324 | VirtTarget *vdev; | ||
1325 | char *pmem; | 1313 | char *pmem; |
1326 | int *pdata; | 1314 | int *pdata; |
1327 | IOCPage2_t *pIoc2; | ||
1328 | IOCPage3_t *pIoc3; | ||
1329 | int iocnum; | 1315 | int iocnum; |
1330 | int numDevices = 0; | 1316 | int numDevices = 0; |
1331 | unsigned int max_id; | 1317 | int lun; |
1332 | int id, jj, indexed_lun, lun_index; | ||
1333 | u32 lun; | ||
1334 | int maxWordsLeft; | 1318 | int maxWordsLeft; |
1335 | int numBytes; | 1319 | int numBytes; |
1336 | u8 port, devType, bus_id; | 1320 | u8 port; |
1321 | struct scsi_device *sdev; | ||
1337 | 1322 | ||
1338 | dctlprintk(("mptctl_gettargetinfo called.\n")); | 1323 | dctlprintk(("mptctl_gettargetinfo called.\n")); |
1339 | if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { | 1324 | if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { |
@@ -1389,74 +1374,22 @@ mptctl_gettargetinfo (unsigned long arg) | |||
1389 | 1374 | ||
1390 | /* Get number of devices | 1375 | /* Get number of devices |
1391 | */ | 1376 | */ |
1392 | if ((sh = ioc->sh) != NULL) { | 1377 | if (ioc->sh){ |
1393 | 1378 | shost_for_each_device(sdev, ioc->sh) { | |
1394 | max_id = sh->max_id - 1; | 1379 | if (!maxWordsLeft) |
1395 | hd = (MPT_SCSI_HOST *) sh->hostdata; | 1380 | continue; |
1396 | 1381 | vdev = sdev->hostdata; | |
1397 | /* Check all of the target structures. | 1382 | if (vdev->vtarget->tflags & |
1398 | * Save the Id and increment the counter, | 1383 | MPT_TARGET_FLAGS_RAID_COMPONENT) |
1399 | * if ptr non-null. | 1384 | continue; |
1400 | * sh->max_id = maximum target ID + 1 | 1385 | lun = (vdev->vtarget->raidVolume) ? 0x80 : vdev->lun; |
1401 | */ | 1386 | *pdata = (((u8)lun << 16) + (vdev->vtarget->channel << 8) + |
1402 | if (hd && hd->Targets) { | 1387 | (vdev->vtarget->id )); |
1403 | mpt_findImVolumes(ioc); | 1388 | pdata++; |
1404 | pIoc2 = ioc->raid_data.pIocPg2; | 1389 | numDevices++; |
1405 | for ( id = 0; id <= max_id; ) { | 1390 | --maxWordsLeft; |
1406 | if ( pIoc2 && pIoc2->NumActiveVolumes ) { | ||
1407 | if ( id == pIoc2->RaidVolume[0].VolumeID ) { | ||
1408 | if (maxWordsLeft <= 0) { | ||
1409 | printk(KERN_ERR "mptctl_gettargetinfo - " | ||
1410 | "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices); | ||
1411 | goto data_space_full; | ||
1412 | } | ||
1413 | if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 ) | ||
1414 | devType = 0x80; | ||
1415 | else | ||
1416 | devType = 0xC0; | ||
1417 | bus_id = pIoc2->RaidVolume[0].VolumeBus; | ||
1418 | numDevices++; | ||
1419 | *pdata = ( (devType << 24) | (bus_id << 8) | id ); | ||
1420 | dctlprintk((KERN_ERR "mptctl_gettargetinfo - " | ||
1421 | "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata)); | ||
1422 | pdata++; | ||
1423 | --maxWordsLeft; | ||
1424 | goto next_id; | ||
1425 | } else { | ||
1426 | pIoc3 = ioc->raid_data.pIocPg3; | ||
1427 | for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) { | ||
1428 | if ( pIoc3->PhysDisk[jj].PhysDiskID == id ) | ||
1429 | goto next_id; | ||
1430 | } | ||
1431 | } | ||
1432 | } | ||
1433 | if ( (vdev = hd->Targets[id]) ) { | ||
1434 | for (jj = 0; jj <= MPT_LAST_LUN; jj++) { | ||
1435 | lun_index = (jj >> 5); | ||
1436 | indexed_lun = (jj % 32); | ||
1437 | lun = (1 << indexed_lun); | ||
1438 | if (vdev->luns[lun_index] & lun) { | ||
1439 | if (maxWordsLeft <= 0) { | ||
1440 | printk(KERN_ERR "mptctl_gettargetinfo - " | ||
1441 | "buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices); | ||
1442 | goto data_space_full; | ||
1443 | } | ||
1444 | bus_id = vdev->bus_id; | ||
1445 | numDevices++; | ||
1446 | *pdata = ( (jj << 16) | (bus_id << 8) | id ); | ||
1447 | dctlprintk((KERN_ERR "mptctl_gettargetinfo - " | ||
1448 | "target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata)); | ||
1449 | pdata++; | ||
1450 | --maxWordsLeft; | ||
1451 | } | ||
1452 | } | ||
1453 | } | ||
1454 | next_id: | ||
1455 | id++; | ||
1456 | } | ||
1457 | } | 1391 | } |
1458 | } | 1392 | } |
1459 | data_space_full: | ||
1460 | karg.numDevices = numDevices; | 1393 | karg.numDevices = numDevices; |
1461 | 1394 | ||
1462 | /* Copy part of the data from kernel memory to user memory | 1395 | /* Copy part of the data from kernel memory to user memory |
@@ -1821,6 +1754,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1821 | int msgContext; | 1754 | int msgContext; |
1822 | u16 req_idx; | 1755 | u16 req_idx; |
1823 | ulong timeout; | 1756 | ulong timeout; |
1757 | struct scsi_device *sdev; | ||
1824 | 1758 | ||
1825 | dctlprintk(("mptctl_do_mpt_command called.\n")); | 1759 | dctlprintk(("mptctl_do_mpt_command called.\n")); |
1826 | bufIn.kptr = bufOut.kptr = NULL; | 1760 | bufIn.kptr = bufOut.kptr = NULL; |
@@ -1902,14 +1836,13 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1902 | case MPI_FUNCTION_SCSI_IO_REQUEST: | 1836 | case MPI_FUNCTION_SCSI_IO_REQUEST: |
1903 | if (ioc->sh) { | 1837 | if (ioc->sh) { |
1904 | SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; | 1838 | SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; |
1905 | VirtTarget *pTarget = NULL; | ||
1906 | MPT_SCSI_HOST *hd = NULL; | ||
1907 | int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; | 1839 | int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; |
1908 | int scsidir = 0; | 1840 | int scsidir = 0; |
1909 | int target = (int) pScsiReq->TargetID; | ||
1910 | int dataSize; | 1841 | int dataSize; |
1842 | u32 id; | ||
1911 | 1843 | ||
1912 | if ((target < 0) || (target >= ioc->sh->max_id)) { | 1844 | id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus; |
1845 | if (pScsiReq->TargetID > id) { | ||
1913 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | 1846 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " |
1914 | "Target ID out of bounds. \n", | 1847 | "Target ID out of bounds. \n", |
1915 | __FILE__, __LINE__); | 1848 | __FILE__, __LINE__); |
@@ -1917,6 +1850,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1917 | goto done_free_mem; | 1850 | goto done_free_mem; |
1918 | } | 1851 | } |
1919 | 1852 | ||
1853 | if (pScsiReq->Bus >= ioc->number_of_buses) { | ||
1854 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | ||
1855 | "Target Bus out of bounds. \n", | ||
1856 | __FILE__, __LINE__); | ||
1857 | rc = -ENODEV; | ||
1858 | goto done_free_mem; | ||
1859 | } | ||
1860 | |||
1920 | pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; | 1861 | pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; |
1921 | pScsiReq->MsgFlags |= mpt_msg_flags(); | 1862 | pScsiReq->MsgFlags |= mpt_msg_flags(); |
1922 | 1863 | ||
@@ -1936,13 +1877,15 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1936 | cpu_to_le32(ioc->sense_buf_low_dma | 1877 | cpu_to_le32(ioc->sense_buf_low_dma |
1937 | + (req_idx * MPT_SENSE_BUFFER_ALLOC)); | 1878 | + (req_idx * MPT_SENSE_BUFFER_ALLOC)); |
1938 | 1879 | ||
1939 | if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) { | 1880 | shost_for_each_device(sdev, ioc->sh) { |
1940 | if (hd->Targets) | 1881 | struct scsi_target *starget = scsi_target(sdev); |
1941 | pTarget = hd->Targets[target]; | 1882 | VirtTarget *vtarget = starget->hostdata; |
1942 | } | ||
1943 | 1883 | ||
1944 | if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) | 1884 | if ((pScsiReq->TargetID == vtarget->id) && |
1945 | qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; | 1885 | (pScsiReq->Bus == vtarget->channel) && |
1886 | (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)) | ||
1887 | qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; | ||
1888 | } | ||
1946 | 1889 | ||
1947 | /* Have the IOCTL driver set the direction based | 1890 | /* Have the IOCTL driver set the direction based |
1948 | * on the dataOutSize (ordering issue with Sparc). | 1891 | * on the dataOutSize (ordering issue with Sparc). |
@@ -1959,7 +1902,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1959 | pScsiReq->DataLength = cpu_to_le32(dataSize); | 1902 | pScsiReq->DataLength = cpu_to_le32(dataSize); |
1960 | 1903 | ||
1961 | ioc->ioctl->reset = MPTCTL_RESET_OK; | 1904 | ioc->ioctl->reset = MPTCTL_RESET_OK; |
1962 | ioc->ioctl->target = target; | 1905 | ioc->ioctl->id = pScsiReq->TargetID; |
1963 | 1906 | ||
1964 | } else { | 1907 | } else { |
1965 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | 1908 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " |
@@ -2038,7 +1981,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
2038 | pScsiReq->DataLength = cpu_to_le32(dataSize); | 1981 | pScsiReq->DataLength = cpu_to_le32(dataSize); |
2039 | 1982 | ||
2040 | ioc->ioctl->reset = MPTCTL_RESET_OK; | 1983 | ioc->ioctl->reset = MPTCTL_RESET_OK; |
2041 | ioc->ioctl->target = pScsiReq->TargetID; | 1984 | ioc->ioctl->id = pScsiReq->TargetID; |
2042 | } else { | 1985 | } else { |
2043 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | 1986 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " |
2044 | "SCSI driver is not loaded. \n", | 1987 | "SCSI driver is not loaded. \n", |