diff options
-rw-r--r-- | drivers/message/fusion/Makefile | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.c | 29 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 12 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.c | 159 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 51 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 73 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 301 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.h | 42 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 188 |
9 files changed, 380 insertions, 477 deletions
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 341691390e86..3217076b40f4 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile | |||
@@ -8,6 +8,7 @@ | |||
8 | #EXTRA_CFLAGS += -DMPT_DEBUG_INIT | 8 | #EXTRA_CFLAGS += -DMPT_DEBUG_INIT |
9 | #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT | 9 | #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT |
10 | #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL | 10 | #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL |
11 | #EXTRA_CFLAGS += -DMPT_DEBUG_TM | ||
11 | 12 | ||
12 | # | 13 | # |
13 | # driver/module specifics... | 14 | # driver/module specifics... |
@@ -22,7 +23,6 @@ | |||
22 | # For mptscsih: | 23 | # For mptscsih: |
23 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_DV | 24 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_DV |
24 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO | 25 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO |
25 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_TM | ||
26 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI | 26 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI |
27 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY | 27 | #CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY |
28 | # | 28 | # |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index b3f28a03b6a9..a07f0f81f96b 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -82,6 +82,10 @@ static int mpt_msi_enable; | |||
82 | module_param(mpt_msi_enable, int, 0); | 82 | module_param(mpt_msi_enable, int, 0); |
83 | MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); | 83 | MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); |
84 | 84 | ||
85 | static int mpt_channel_mapping; | ||
86 | module_param(mpt_channel_mapping, int, 0); | ||
87 | MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)"); | ||
88 | |||
85 | #ifdef MFCNT | 89 | #ifdef MFCNT |
86 | static int mfcounter = 0; | 90 | static int mfcounter = 0; |
87 | #define PRINT_MF_COUNT 20000 | 91 | #define PRINT_MF_COUNT 20000 |
@@ -2505,6 +2509,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) | |||
2505 | int ii; | 2509 | int ii; |
2506 | int req_sz; | 2510 | int req_sz; |
2507 | int reply_sz; | 2511 | int reply_sz; |
2512 | int max_id; | ||
2508 | 2513 | ||
2509 | /* IOC *must* NOT be in RESET state! */ | 2514 | /* IOC *must* NOT be in RESET state! */ |
2510 | if (ioc->last_state == MPI_IOC_STATE_RESET) { | 2515 | if (ioc->last_state == MPI_IOC_STATE_RESET) { |
@@ -2552,6 +2557,21 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) | |||
2552 | pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); | 2557 | pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); |
2553 | pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); | 2558 | pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); |
2554 | 2559 | ||
2560 | max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID : | ||
2561 | pfacts->MaxDevices; | ||
2562 | ioc->devices_per_bus = (max_id > 255) ? 256 : max_id; | ||
2563 | ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256; | ||
2564 | |||
2565 | /* | ||
2566 | * Place all the devices on channels | ||
2567 | * | ||
2568 | * (for debuging) | ||
2569 | */ | ||
2570 | if (mpt_channel_mapping) { | ||
2571 | ioc->devices_per_bus = 1; | ||
2572 | ioc->number_of_buses = (max_id > 255) ? 255 : max_id; | ||
2573 | } | ||
2574 | |||
2555 | return 0; | 2575 | return 0; |
2556 | } | 2576 | } |
2557 | 2577 | ||
@@ -2592,13 +2612,8 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) | |||
2592 | ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n", | 2612 | ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n", |
2593 | ioc->name, ioc->upload_fw, ioc->facts.Flags)); | 2613 | ioc->name, ioc->upload_fw, ioc->facts.Flags)); |
2594 | 2614 | ||
2595 | if(ioc->bus_type == SAS) | 2615 | ioc_init.MaxDevices = (U8)ioc->devices_per_bus; |
2596 | ioc_init.MaxDevices = ioc->facts.MaxDevices; | 2616 | ioc_init.MaxBuses = (U8)ioc->number_of_buses; |
2597 | else if(ioc->bus_type == FC) | ||
2598 | ioc_init.MaxDevices = MPT_MAX_FC_DEVICES; | ||
2599 | else | ||
2600 | ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES; | ||
2601 | ioc_init.MaxBuses = MPT_MAX_BUS; | ||
2602 | dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n", | 2617 | dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n", |
2603 | ioc->name, ioc->facts.MsgVersion)); | 2618 | ioc->name, ioc->facts.MsgVersion)); |
2604 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { | 2619 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index e316708f76bd..f82a817de81f 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -334,8 +334,8 @@ typedef struct _VirtTarget { | |||
334 | struct scsi_target *starget; | 334 | struct scsi_target *starget; |
335 | u8 tflags; | 335 | u8 tflags; |
336 | u8 ioc_id; | 336 | u8 ioc_id; |
337 | u8 target_id; | 337 | u8 id; |
338 | u8 bus_id; | 338 | u8 channel; |
339 | u8 minSyncFactor; /* 0xFF is async */ | 339 | u8 minSyncFactor; /* 0xFF is async */ |
340 | u8 maxOffset; /* 0 if async */ | 340 | u8 maxOffset; /* 0 if async */ |
341 | u8 maxWidth; /* 0 if narrow, 1 if wide */ | 341 | u8 maxWidth; /* 0 if narrow, 1 if wide */ |
@@ -344,13 +344,12 @@ typedef struct _VirtTarget { | |||
344 | u8 type; /* byte 0 of Inquiry data */ | 344 | u8 type; /* byte 0 of Inquiry data */ |
345 | u8 deleted; /* target in process of being removed */ | 345 | u8 deleted; /* target in process of being removed */ |
346 | u32 num_luns; | 346 | u32 num_luns; |
347 | u32 luns[8]; /* Max LUNs is 256 */ | ||
348 | } VirtTarget; | 347 | } VirtTarget; |
349 | 348 | ||
350 | typedef struct _VirtDevice { | 349 | typedef struct _VirtDevice { |
351 | VirtTarget *vtarget; | 350 | VirtTarget *vtarget; |
352 | u8 configured_lun; | 351 | u8 configured_lun; |
353 | u32 lun; | 352 | int lun; |
354 | } VirtDevice; | 353 | } VirtDevice; |
355 | 354 | ||
356 | /* | 355 | /* |
@@ -412,7 +411,7 @@ typedef struct _MPT_IOCTL { | |||
412 | u8 rsvd; | 411 | u8 rsvd; |
413 | u8 status; /* current command status */ | 412 | u8 status; /* current command status */ |
414 | u8 reset; /* 1 if bus reset allowed */ | 413 | u8 reset; /* 1 if bus reset allowed */ |
415 | u8 target; /* target for reset */ | 414 | u8 id; /* target for reset */ |
416 | struct mutex ioctl_mutex; | 415 | struct mutex ioctl_mutex; |
417 | } MPT_IOCTL; | 416 | } MPT_IOCTL; |
418 | 417 | ||
@@ -528,6 +527,8 @@ typedef struct _MPT_ADAPTER | |||
528 | u32 mem_phys; /* == f4020000 (mmap) */ | 527 | u32 mem_phys; /* == f4020000 (mmap) */ |
529 | u32 pio_mem_phys; /* Programmed IO (downloadboot) */ | 528 | u32 pio_mem_phys; /* Programmed IO (downloadboot) */ |
530 | int mem_size; /* mmap memory size */ | 529 | int mem_size; /* mmap memory size */ |
530 | int number_of_buses; | ||
531 | int devices_per_bus; | ||
531 | int alloc_total; | 532 | int alloc_total; |
532 | u32 last_state; | 533 | u32 last_state; |
533 | int active; | 534 | int active; |
@@ -957,7 +958,6 @@ typedef struct _MPT_SCSI_HOST { | |||
957 | int port; | 958 | int port; |
958 | u32 pad0; | 959 | u32 pad0; |
959 | struct scsi_cmnd **ScsiLookup; | 960 | struct scsi_cmnd **ScsiLookup; |
960 | VirtTarget **Targets; | ||
961 | MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ | 961 | MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ |
962 | struct timer_list timer; | 962 | struct timer_list timer; |
963 | /* Pool of memory for holding SCpnts before doing | 963 | /* Pool of memory for holding SCpnts before doing |
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", |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index c819c23b55b1..cd8fa39ec270 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -86,6 +86,12 @@ MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the " | |||
86 | " return following a device loss event." | 86 | " return following a device loss event." |
87 | " Default=60."); | 87 | " Default=60."); |
88 | 88 | ||
89 | /* scsi-mid layer global parmeter is max_report_luns, which is 511 */ | ||
90 | #define MPTFC_MAX_LUN (16895) | ||
91 | static int max_lun = MPTFC_MAX_LUN; | ||
92 | module_param(max_lun, int, 0); | ||
93 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); | ||
94 | |||
89 | static int mptfcDoneCtx = -1; | 95 | static int mptfcDoneCtx = -1; |
90 | static int mptfcTaskCtx = -1; | 96 | static int mptfcTaskCtx = -1; |
91 | static int mptfcInternalCtx = -1; /* Used only for internal commands */ | 97 | static int mptfcInternalCtx = -1; /* Used only for internal commands */ |
@@ -292,10 +298,9 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port, | |||
292 | U32 port_id = 0xffffff; | 298 | U32 port_id = 0xffffff; |
293 | int num_targ = 0; | 299 | int num_targ = 0; |
294 | int max_bus = ioc->facts.MaxBuses; | 300 | int max_bus = ioc->facts.MaxBuses; |
295 | int max_targ = ioc->facts.MaxDevices; | 301 | int max_targ; |
296 | 302 | ||
297 | if (max_bus == 0 || max_targ == 0) | 303 | max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices; |
298 | goto out; | ||
299 | 304 | ||
300 | data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ; | 305 | data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ; |
301 | p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL); | 306 | p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL); |
@@ -467,8 +472,8 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) | |||
467 | if (ri->starget) { | 472 | if (ri->starget) { |
468 | vtarget = ri->starget->hostdata; | 473 | vtarget = ri->starget->hostdata; |
469 | if (vtarget) { | 474 | if (vtarget) { |
470 | vtarget->target_id = pg0->CurrentTargetID; | 475 | vtarget->id = pg0->CurrentTargetID; |
471 | vtarget->bus_id = pg0->CurrentBus; | 476 | vtarget->channel = pg0->CurrentBus; |
472 | } | 477 | } |
473 | } | 478 | } |
474 | *((struct mptfc_rport_info **)rport->dd_data) = ri; | 479 | *((struct mptfc_rport_info **)rport->dd_data) = ri; |
@@ -540,8 +545,8 @@ mptfc_target_alloc(struct scsi_target *starget) | |||
540 | if (rport) { | 545 | if (rport) { |
541 | ri = *((struct mptfc_rport_info **)rport->dd_data); | 546 | ri = *((struct mptfc_rport_info **)rport->dd_data); |
542 | if (ri) { /* better be! */ | 547 | if (ri) { /* better be! */ |
543 | vtarget->target_id = ri->pg0.CurrentTargetID; | 548 | vtarget->id = ri->pg0.CurrentTargetID; |
544 | vtarget->bus_id = ri->pg0.CurrentBus; | 549 | vtarget->channel = ri->pg0.CurrentBus; |
545 | ri->starget = starget; | 550 | ri->starget = starget; |
546 | rc = 0; | 551 | rc = 0; |
547 | } | 552 | } |
@@ -592,7 +597,6 @@ mptfc_slave_alloc(struct scsi_device *sdev) | |||
592 | if (vtarget->num_luns == 0) { | 597 | if (vtarget->num_luns == 0) { |
593 | vtarget->ioc_id = hd->ioc->id; | 598 | vtarget->ioc_id = hd->ioc->id; |
594 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | 599 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; |
595 | hd->Targets[sdev->id] = vtarget; | ||
596 | } | 600 | } |
597 | 601 | ||
598 | vdev->vtarget = vtarget; | 602 | vdev->vtarget = vtarget; |
@@ -630,16 +634,17 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
630 | struct mptfc_rport_info *ri; | 634 | struct mptfc_rport_info *ri; |
631 | struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); | 635 | struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); |
632 | int err; | 636 | int err; |
637 | VirtDevice *vdev = SCpnt->device->hostdata; | ||
633 | 638 | ||
634 | err = fc_remote_port_chkready(rport); | 639 | if (!vdev || !vdev->vtarget) { |
635 | if (unlikely(err)) { | 640 | SCpnt->result = DID_NO_CONNECT << 16; |
636 | SCpnt->result = err; | ||
637 | done(SCpnt); | 641 | done(SCpnt); |
638 | return 0; | 642 | return 0; |
639 | } | 643 | } |
640 | 644 | ||
641 | if (!SCpnt->device->hostdata) { /* vdev */ | 645 | err = fc_remote_port_chkready(rport); |
642 | SCpnt->result = DID_NO_CONNECT << 16; | 646 | if (unlikely(err)) { |
647 | SCpnt->result = err; | ||
643 | done(SCpnt); | 648 | done(SCpnt); |
644 | return 0; | 649 | return 0; |
645 | } | 650 | } |
@@ -1143,7 +1148,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1143 | printk(MYIOC_s_WARN_FMT | 1148 | printk(MYIOC_s_WARN_FMT |
1144 | "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", | 1149 | "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", |
1145 | ioc->name, ioc); | 1150 | ioc->name, ioc); |
1146 | return -ENODEV; | 1151 | return 0; |
1147 | } | 1152 | } |
1148 | 1153 | ||
1149 | sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); | 1154 | sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); |
@@ -1173,10 +1178,9 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1173 | /* set 16 byte cdb's */ | 1178 | /* set 16 byte cdb's */ |
1174 | sh->max_cmd_len = 16; | 1179 | sh->max_cmd_len = 16; |
1175 | 1180 | ||
1176 | sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; | 1181 | sh->max_id = ioc->pfacts->MaxDevices; |
1182 | sh->max_lun = max_lun; | ||
1177 | 1183 | ||
1178 | sh->max_lun = MPT_LAST_LUN + 1; | ||
1179 | sh->max_channel = 0; | ||
1180 | sh->this_id = ioc->pfacts[0].PortSCSIID; | 1184 | sh->this_id = ioc->pfacts[0].PortSCSIID; |
1181 | 1185 | ||
1182 | /* Required entry. | 1186 | /* Required entry. |
@@ -1230,19 +1234,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1230 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", | 1234 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", |
1231 | ioc->name, hd->ScsiLookup)); | 1235 | ioc->name, hd->ScsiLookup)); |
1232 | 1236 | ||
1233 | /* Allocate memory for the device structures. | ||
1234 | * A non-Null pointer at an offset | ||
1235 | * indicates a device exists. | ||
1236 | * max_id = 1 + maximum id (hosts.h) | ||
1237 | */ | ||
1238 | hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); | ||
1239 | if (!hd->Targets) { | ||
1240 | error = -ENOMEM; | ||
1241 | goto out_mptfc_probe; | ||
1242 | } | ||
1243 | |||
1244 | dprintk((KERN_INFO " vdev @ %p\n", hd->Targets)); | ||
1245 | |||
1246 | /* Clear the TM flags | 1237 | /* Clear the TM flags |
1247 | */ | 1238 | */ |
1248 | hd->tmPending = 0; | 1239 | hd->tmPending = 0; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 09e9a9d96410..f7c5e0d97890 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -83,6 +83,12 @@ MODULE_PARM_DESC(mpt_pt_clear, | |||
83 | " Clear persistency table: enable=1 " | 83 | " Clear persistency table: enable=1 " |
84 | "(default=MPTSCSIH_PT_CLEAR=0)"); | 84 | "(default=MPTSCSIH_PT_CLEAR=0)"); |
85 | 85 | ||
86 | /* scsi-mid layer global parmeter is max_report_luns, which is 511 */ | ||
87 | #define MPTSAS_MAX_LUN (16895) | ||
88 | static int max_lun = MPTSAS_MAX_LUN; | ||
89 | module_param(max_lun, int, 0); | ||
90 | MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); | ||
91 | |||
86 | static int mptsasDoneCtx = -1; | 92 | static int mptsasDoneCtx = -1; |
87 | static int mptsasTaskCtx = -1; | 93 | static int mptsasTaskCtx = -1; |
88 | static int mptsasInternalCtx = -1; /* Used only for internal commands */ | 94 | static int mptsasInternalCtx = -1; /* Used only for internal commands */ |
@@ -568,12 +574,12 @@ mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget) | |||
568 | 574 | ||
569 | if (mptscsih_TMHandler(hd, | 575 | if (mptscsih_TMHandler(hd, |
570 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | 576 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, |
571 | vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) { | 577 | vtarget->channel, vtarget->id, 0, 0, 5) < 0) { |
572 | hd->tmPending = 0; | 578 | hd->tmPending = 0; |
573 | hd->tmState = TM_STATE_NONE; | 579 | hd->tmState = TM_STATE_NONE; |
574 | printk(MYIOC_s_WARN_FMT | 580 | printk(MYIOC_s_WARN_FMT |
575 | "Error processing TaskMgmt id=%d TARGET_RESET\n", | 581 | "Error processing TaskMgmt id=%d TARGET_RESET\n", |
576 | ioc->name, vtarget->target_id); | 582 | ioc->name, vtarget->id); |
577 | } | 583 | } |
578 | } | 584 | } |
579 | 585 | ||
@@ -661,8 +667,7 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
661 | struct Scsi_Host *host = dev_to_shost(&starget->dev); | 667 | struct Scsi_Host *host = dev_to_shost(&starget->dev); |
662 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 668 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; |
663 | VirtTarget *vtarget; | 669 | VirtTarget *vtarget; |
664 | u32 target_id; | 670 | u8 id, channel; |
665 | u32 channel; | ||
666 | struct sas_rphy *rphy; | 671 | struct sas_rphy *rphy; |
667 | struct mptsas_portinfo *p; | 672 | struct mptsas_portinfo *p; |
668 | int i; | 673 | int i; |
@@ -673,15 +678,19 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
673 | 678 | ||
674 | vtarget->starget = starget; | 679 | vtarget->starget = starget; |
675 | vtarget->ioc_id = hd->ioc->id; | 680 | vtarget->ioc_id = hd->ioc->id; |
676 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; | 681 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; |
677 | 682 | id = starget->id; | |
678 | target_id = starget->id; | ||
679 | channel = 0; | 683 | channel = 0; |
680 | 684 | ||
681 | hd->Targets[target_id] = vtarget; | 685 | /* |
682 | 686 | * RAID volumes placed beyond the last expected port. | |
683 | if (starget->channel == MPTSAS_RAID_CHANNEL) | 687 | */ |
688 | if (starget->channel == MPTSAS_RAID_CHANNEL) { | ||
689 | for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) | ||
690 | if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID) | ||
691 | channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus; | ||
684 | goto out; | 692 | goto out; |
693 | } | ||
685 | 694 | ||
686 | rphy = dev_to_rphy(starget->dev.parent); | 695 | rphy = dev_to_rphy(starget->dev.parent); |
687 | mutex_lock(&hd->ioc->sas_topology_mutex); | 696 | mutex_lock(&hd->ioc->sas_topology_mutex); |
@@ -690,16 +699,16 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
690 | if (p->phy_info[i].attached.sas_address != | 699 | if (p->phy_info[i].attached.sas_address != |
691 | rphy->identify.sas_address) | 700 | rphy->identify.sas_address) |
692 | continue; | 701 | continue; |
693 | target_id = p->phy_info[i].attached.id; | 702 | id = p->phy_info[i].attached.id; |
694 | channel = p->phy_info[i].attached.channel; | 703 | channel = p->phy_info[i].attached.channel; |
695 | mptsas_set_starget(&p->phy_info[i], starget); | 704 | mptsas_set_starget(&p->phy_info[i], starget); |
696 | 705 | ||
697 | /* | 706 | /* |
698 | * Exposing hidden raid components | 707 | * Exposing hidden raid components |
699 | */ | 708 | */ |
700 | if (mptscsih_is_phys_disk(hd->ioc, target_id)) { | 709 | if (mptscsih_is_phys_disk(hd->ioc, channel, id)) { |
701 | target_id = mptscsih_raid_id_to_num(hd, | 710 | id = mptscsih_raid_id_to_num(hd->ioc, |
702 | target_id); | 711 | channel, id); |
703 | vtarget->tflags |= | 712 | vtarget->tflags |= |
704 | MPT_TARGET_FLAGS_RAID_COMPONENT; | 713 | MPT_TARGET_FLAGS_RAID_COMPONENT; |
705 | } | 714 | } |
@@ -713,8 +722,8 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
713 | return -ENXIO; | 722 | return -ENXIO; |
714 | 723 | ||
715 | out: | 724 | out: |
716 | vtarget->target_id = target_id; | 725 | vtarget->id = id; |
717 | vtarget->bus_id = channel; | 726 | vtarget->channel = channel; |
718 | starget->hostdata = vtarget; | 727 | starget->hostdata = vtarget; |
719 | return 0; | 728 | return 0; |
720 | } | 729 | } |
@@ -786,7 +795,8 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
786 | * Exposing hidden raid components | 795 | * Exposing hidden raid components |
787 | */ | 796 | */ |
788 | if (mptscsih_is_phys_disk(hd->ioc, | 797 | if (mptscsih_is_phys_disk(hd->ioc, |
789 | p->phy_info[i].attached.id)) | 798 | p->phy_info[i].attached.channel, |
799 | p->phy_info[i].attached.id)) | ||
790 | sdev->no_uld_attach = 1; | 800 | sdev->no_uld_attach = 1; |
791 | mutex_unlock(&hd->ioc->sas_topology_mutex); | 801 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
792 | goto out; | 802 | goto out; |
@@ -808,13 +818,14 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
808 | { | 818 | { |
809 | VirtDevice *vdev = SCpnt->device->hostdata; | 819 | VirtDevice *vdev = SCpnt->device->hostdata; |
810 | 820 | ||
811 | // scsi_print_command(SCpnt); | 821 | if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) { |
812 | if (vdev->vtarget->deleted) { | ||
813 | SCpnt->result = DID_NO_CONNECT << 16; | 822 | SCpnt->result = DID_NO_CONNECT << 16; |
814 | done(SCpnt); | 823 | done(SCpnt); |
815 | return 0; | 824 | return 0; |
816 | } | 825 | } |
817 | 826 | ||
827 | // scsi_print_command(SCpnt); | ||
828 | |||
818 | return mptscsih_qcmd(SCpnt,done); | 829 | return mptscsih_qcmd(SCpnt,done); |
819 | } | 830 | } |
820 | 831 | ||
@@ -1976,7 +1987,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc) | |||
1976 | goto out; | 1987 | goto out; |
1977 | if (!ioc->raid_data.pIocPg2->NumActiveVolumes) | 1988 | if (!ioc->raid_data.pIocPg2->NumActiveVolumes) |
1978 | goto out; | 1989 | goto out; |
1979 | for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { | 1990 | for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { |
1980 | scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, | 1991 | scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, |
1981 | ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); | 1992 | ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); |
1982 | } | 1993 | } |
@@ -2160,7 +2171,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2160 | * Handling RAID components | 2171 | * Handling RAID components |
2161 | */ | 2172 | */ |
2162 | if (ev->phys_disk_num_valid) { | 2173 | if (ev->phys_disk_num_valid) { |
2163 | vtarget->target_id = ev->phys_disk_num; | 2174 | vtarget->id = ev->phys_disk_num; |
2164 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | 2175 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; |
2165 | mptsas_reprobe_target(starget, 1); | 2176 | mptsas_reprobe_target(starget, 1); |
2166 | break; | 2177 | break; |
@@ -2233,7 +2244,7 @@ mptsas_hotplug_work(struct work_struct *work) | |||
2233 | */ | 2244 | */ |
2234 | if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2245 | if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { |
2235 | vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; | 2246 | vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; |
2236 | vtarget->target_id = ev->id; | 2247 | vtarget->id = ev->id; |
2237 | mptsas_reprobe_target(starget, 0); | 2248 | mptsas_reprobe_target(starget, 0); |
2238 | } | 2249 | } |
2239 | break; | 2250 | break; |
@@ -2611,12 +2622,11 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2611 | /* set 16 byte cdb's */ | 2622 | /* set 16 byte cdb's */ |
2612 | sh->max_cmd_len = 16; | 2623 | sh->max_cmd_len = 16; |
2613 | 2624 | ||
2614 | sh->max_id = ioc->pfacts->MaxDevices + 1; | 2625 | sh->max_id = ioc->pfacts[0].PortSCSIID; |
2626 | sh->max_lun = max_lun; | ||
2615 | 2627 | ||
2616 | sh->transportt = mptsas_transport_template; | 2628 | sh->transportt = mptsas_transport_template; |
2617 | 2629 | ||
2618 | sh->max_lun = MPT_LAST_LUN + 1; | ||
2619 | sh->max_channel = 0; | ||
2620 | sh->this_id = ioc->pfacts[0].PortSCSIID; | 2630 | sh->this_id = ioc->pfacts[0].PortSCSIID; |
2621 | 2631 | ||
2622 | /* Required entry. | 2632 | /* Required entry. |
@@ -2676,19 +2686,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2676 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", | 2686 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", |
2677 | ioc->name, hd->ScsiLookup)); | 2687 | ioc->name, hd->ScsiLookup)); |
2678 | 2688 | ||
2679 | /* Allocate memory for the device structures. | ||
2680 | * A non-Null pointer at an offset | ||
2681 | * indicates a device exists. | ||
2682 | * max_id = 1 + maximum id (hosts.h) | ||
2683 | */ | ||
2684 | hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); | ||
2685 | if (!hd->Targets) { | ||
2686 | error = -ENOMEM; | ||
2687 | goto out_mptsas_probe; | ||
2688 | } | ||
2689 | |||
2690 | dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets)); | ||
2691 | |||
2692 | /* Clear the TM flags | 2689 | /* Clear the TM flags |
2693 | */ | 2690 | */ |
2694 | hd->tmPending = 0; | 2691 | hd->tmPending = 0; |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index f0cca3ea93b2..ce58431bee8e 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -79,43 +79,6 @@ MODULE_LICENSE("GPL"); | |||
79 | MODULE_VERSION(my_VERSION); | 79 | MODULE_VERSION(my_VERSION); |
80 | 80 | ||
81 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 81 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
82 | |||
83 | typedef struct _BIG_SENSE_BUF { | ||
84 | u8 data[MPT_SENSE_BUFFER_ALLOC]; | ||
85 | } BIG_SENSE_BUF; | ||
86 | |||
87 | #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */ | ||
88 | #define MPT_SCANDV_DID_RESET (0x00000001) | ||
89 | #define MPT_SCANDV_SENSE (0x00000002) | ||
90 | #define MPT_SCANDV_SOME_ERROR (0x00000004) | ||
91 | #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008) | ||
92 | #define MPT_SCANDV_ISSUE_SENSE (0x00000010) | ||
93 | #define MPT_SCANDV_FALLBACK (0x00000020) | ||
94 | |||
95 | #define MPT_SCANDV_MAX_RETRIES (10) | ||
96 | |||
97 | #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ | ||
98 | #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ | ||
99 | #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */ | ||
100 | #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */ | ||
101 | #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */ | ||
102 | #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ | ||
103 | #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ | ||
104 | |||
105 | typedef struct _internal_cmd { | ||
106 | char *data; /* data pointer */ | ||
107 | dma_addr_t data_dma; /* data dma address */ | ||
108 | int size; /* transfer size */ | ||
109 | u8 cmd; /* SCSI Op Code */ | ||
110 | u8 bus; /* bus number */ | ||
111 | u8 id; /* SCSI ID (virtual) */ | ||
112 | u8 lun; | ||
113 | u8 flags; /* Bit Field - See above */ | ||
114 | u8 physDiskNum; /* Phys disk number, -1 else */ | ||
115 | u8 rsvd2; | ||
116 | u8 rsvd; | ||
117 | } INTERNAL_CMD; | ||
118 | |||
119 | /* | 82 | /* |
120 | * Other private/forward protos... | 83 | * Other private/forward protos... |
121 | */ | 84 | */ |
@@ -131,14 +94,14 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); | |||
131 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); | 94 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); |
132 | static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); | 95 | static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); |
133 | 96 | ||
134 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | 97 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); |
135 | 98 | ||
136 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 99 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
137 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | 100 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); |
138 | 101 | ||
139 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); | 102 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); |
140 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); | 103 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); |
141 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); | 104 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int channel, int id); |
142 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); | 105 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); |
143 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); | 106 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); |
144 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); | 107 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); |
@@ -517,13 +480,13 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, | |||
517 | 480 | ||
518 | SEPMsg = (SEPRequest_t *)mf; | 481 | SEPMsg = (SEPRequest_t *)mf; |
519 | SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; | 482 | SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; |
520 | SEPMsg->Bus = vtarget->bus_id; | 483 | SEPMsg->Bus = vtarget->channel; |
521 | SEPMsg->TargetID = vtarget->target_id; | 484 | SEPMsg->TargetID = vtarget->id; |
522 | SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; | 485 | SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; |
523 | SEPMsg->SlotStatus = SlotStatus; | 486 | SEPMsg->SlotStatus = SlotStatus; |
524 | devtverboseprintk((MYIOC_s_WARN_FMT | 487 | devtverboseprintk((MYIOC_s_WARN_FMT |
525 | "Sending SEP cmd=%x id=%d bus=%d\n", | 488 | "Sending SEP cmd=%x channel=%d id=%d\n", |
526 | ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus)); | 489 | ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID)); |
527 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | 490 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); |
528 | } | 491 | } |
529 | 492 | ||
@@ -955,9 +918,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
955 | int ii; | 918 | int ii; |
956 | int max = hd->ioc->req_depth; | 919 | int max = hd->ioc->req_depth; |
957 | struct scsi_cmnd *sc; | 920 | struct scsi_cmnd *sc; |
921 | struct scsi_lun lun; | ||
958 | 922 | ||
959 | dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", | 923 | dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n", |
960 | vdevice->vtarget->target_id, vdevice->lun, max)); | 924 | vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max)); |
961 | 925 | ||
962 | for (ii=0; ii < max; ii++) { | 926 | for (ii=0; ii < max; ii++) { |
963 | if ((sc = hd->ScsiLookup[ii]) != NULL) { | 927 | if ((sc = hd->ScsiLookup[ii]) != NULL) { |
@@ -965,10 +929,14 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
965 | mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); | 929 | mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); |
966 | if (mf == NULL) | 930 | if (mf == NULL) |
967 | continue; | 931 | continue; |
968 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", | 932 | int_to_scsilun(vdevice->lun, &lun); |
969 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); | 933 | if ((mf->Bus != vdevice->vtarget->channel) || |
970 | if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) | 934 | (mf->TargetID != vdevice->vtarget->id) || |
935 | memcmp(lun.scsi_lun, mf->LUN, 8)) | ||
971 | continue; | 936 | continue; |
937 | dsprintk(( "search_running: found (sc=%p, mf = %p) " | ||
938 | "channel %d id %d, lun %d \n", hd->ScsiLookup[ii], | ||
939 | mf, mf->Bus, mf->TargetID, vdevice->lun)); | ||
972 | 940 | ||
973 | /* Cleanup | 941 | /* Cleanup |
974 | */ | 942 | */ |
@@ -1065,12 +1033,6 @@ mptscsih_remove(struct pci_dev *pdev) | |||
1065 | hd->ScsiLookup = NULL; | 1033 | hd->ScsiLookup = NULL; |
1066 | } | 1034 | } |
1067 | 1035 | ||
1068 | /* | ||
1069 | * Free pointer array. | ||
1070 | */ | ||
1071 | kfree(hd->Targets); | ||
1072 | hd->Targets = NULL; | ||
1073 | |||
1074 | dprintk((MYIOC_s_INFO_FMT | 1036 | dprintk((MYIOC_s_INFO_FMT |
1075 | "Free'd ScsiLookup (%d) memory\n", | 1037 | "Free'd ScsiLookup (%d) memory\n", |
1076 | hd->ioc->name, sz1)); | 1038 | hd->ioc->name, sz1)); |
@@ -1317,14 +1279,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1317 | return SCSI_MLQUEUE_HOST_BUSY; | 1279 | return SCSI_MLQUEUE_HOST_BUSY; |
1318 | } | 1280 | } |
1319 | 1281 | ||
1320 | if ((hd->ioc->bus_type == SPI) && | ||
1321 | vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT && | ||
1322 | mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) { | ||
1323 | SCpnt->result = DID_NO_CONNECT << 16; | ||
1324 | done(SCpnt); | ||
1325 | return 0; | ||
1326 | } | ||
1327 | |||
1328 | /* | 1282 | /* |
1329 | * Put together a MPT SCSI request... | 1283 | * Put together a MPT SCSI request... |
1330 | */ | 1284 | */ |
@@ -1368,8 +1322,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1368 | 1322 | ||
1369 | /* Use the above information to set up the message frame | 1323 | /* Use the above information to set up the message frame |
1370 | */ | 1324 | */ |
1371 | pScsiReq->TargetID = (u8) vdev->vtarget->target_id; | 1325 | pScsiReq->TargetID = (u8) vdev->vtarget->id; |
1372 | pScsiReq->Bus = vdev->vtarget->bus_id; | 1326 | pScsiReq->Bus = vdev->vtarget->channel; |
1373 | pScsiReq->ChainOffset = 0; | 1327 | pScsiReq->ChainOffset = 0; |
1374 | if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) | 1328 | if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) |
1375 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; | 1329 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; |
@@ -1379,14 +1333,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1379 | pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; | 1333 | pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; |
1380 | pScsiReq->Reserved = 0; | 1334 | pScsiReq->Reserved = 0; |
1381 | pScsiReq->MsgFlags = mpt_msg_flags(); | 1335 | pScsiReq->MsgFlags = mpt_msg_flags(); |
1382 | pScsiReq->LUN[0] = 0; | 1336 | int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN); |
1383 | pScsiReq->LUN[1] = lun; | ||
1384 | pScsiReq->LUN[2] = 0; | ||
1385 | pScsiReq->LUN[3] = 0; | ||
1386 | pScsiReq->LUN[4] = 0; | ||
1387 | pScsiReq->LUN[5] = 0; | ||
1388 | pScsiReq->LUN[6] = 0; | ||
1389 | pScsiReq->LUN[7] = 0; | ||
1390 | pScsiReq->Control = cpu_to_le32(scsictl); | 1337 | pScsiReq->Control = cpu_to_le32(scsictl); |
1391 | 1338 | ||
1392 | /* | 1339 | /* |
@@ -1498,7 +1445,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) | |||
1498 | * | 1445 | * |
1499 | * @ioc: Pointer to MPT_ADAPTER structure | 1446 | * @ioc: Pointer to MPT_ADAPTER structure |
1500 | * @type: Task Management type | 1447 | * @type: Task Management type |
1501 | * @target: Logical Target ID for reset (if appropriate) | 1448 | * @id: Logical Target ID for reset (if appropriate) |
1502 | * @lun: Logical Unit for reset (if appropriate) | 1449 | * @lun: Logical Unit for reset (if appropriate) |
1503 | * @ctx2abort: Context for the task to be aborted (if appropriate) | 1450 | * @ctx2abort: Context for the task to be aborted (if appropriate) |
1504 | * | 1451 | * |
@@ -1510,7 +1457,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) | |||
1510 | * Returns 0 for SUCCESS or -1 if FAILED. | 1457 | * Returns 0 for SUCCESS or -1 if FAILED. |
1511 | */ | 1458 | */ |
1512 | int | 1459 | int |
1513 | mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) | 1460 | mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) |
1514 | { | 1461 | { |
1515 | MPT_ADAPTER *ioc; | 1462 | MPT_ADAPTER *ioc; |
1516 | int rc = -1; | 1463 | int rc = -1; |
@@ -1590,7 +1537,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1590 | */ | 1537 | */ |
1591 | if (hd->hard_resets < -1) | 1538 | if (hd->hard_resets < -1) |
1592 | hd->hard_resets++; | 1539 | hd->hard_resets++; |
1593 | rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout); | 1540 | rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, ctx2abort, timeout); |
1594 | if (rc) { | 1541 | if (rc) { |
1595 | printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); | 1542 | printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); |
1596 | } else { | 1543 | } else { |
@@ -1624,7 +1571,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1624 | * mptscsih_IssueTaskMgmt - Generic send Task Management function. | 1571 | * mptscsih_IssueTaskMgmt - Generic send Task Management function. |
1625 | * @hd: Pointer to MPT_SCSI_HOST structure | 1572 | * @hd: Pointer to MPT_SCSI_HOST structure |
1626 | * @type: Task Management type | 1573 | * @type: Task Management type |
1627 | * @target: Logical Target ID for reset (if appropriate) | 1574 | * @id: Logical Target ID for reset (if appropriate) |
1628 | * @lun: Logical Unit for reset (if appropriate) | 1575 | * @lun: Logical Unit for reset (if appropriate) |
1629 | * @ctx2abort: Context for the task to be aborted (if appropriate) | 1576 | * @ctx2abort: Context for the task to be aborted (if appropriate) |
1630 | * | 1577 | * |
@@ -1637,7 +1584,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1637 | * else other non-zero value returned. | 1584 | * else other non-zero value returned. |
1638 | */ | 1585 | */ |
1639 | static int | 1586 | static int |
1640 | mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) | 1587 | mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) |
1641 | { | 1588 | { |
1642 | MPT_FRAME_HDR *mf; | 1589 | MPT_FRAME_HDR *mf; |
1643 | SCSITaskMgmt_t *pScsiTm; | 1590 | SCSITaskMgmt_t *pScsiTm; |
@@ -1657,7 +1604,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun | |||
1657 | /* Format the Request | 1604 | /* Format the Request |
1658 | */ | 1605 | */ |
1659 | pScsiTm = (SCSITaskMgmt_t *) mf; | 1606 | pScsiTm = (SCSITaskMgmt_t *) mf; |
1660 | pScsiTm->TargetID = target; | 1607 | pScsiTm->TargetID = id; |
1661 | pScsiTm->Bus = channel; | 1608 | pScsiTm->Bus = channel; |
1662 | pScsiTm->ChainOffset = 0; | 1609 | pScsiTm->ChainOffset = 0; |
1663 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; | 1610 | pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; |
@@ -1668,10 +1615,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun | |||
1668 | pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) | 1615 | pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) |
1669 | ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; | 1616 | ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; |
1670 | 1617 | ||
1671 | for (ii= 0; ii < 8; ii++) { | 1618 | int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN); |
1672 | pScsiTm->LUN[ii] = 0; | ||
1673 | } | ||
1674 | pScsiTm->LUN[1] = lun; | ||
1675 | 1619 | ||
1676 | for (ii=0; ii < 7; ii++) | 1620 | for (ii=0; ii < 7; ii++) |
1677 | pScsiTm->Reserved2[ii] = 0; | 1621 | pScsiTm->Reserved2[ii] = 0; |
@@ -1789,7 +1733,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1789 | 1733 | ||
1790 | vdev = SCpnt->device->hostdata; | 1734 | vdev = SCpnt->device->hostdata; |
1791 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, | 1735 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, |
1792 | vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, | 1736 | vdev->vtarget->channel, vdev->vtarget->id, vdev->lun, |
1793 | ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); | 1737 | ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); |
1794 | 1738 | ||
1795 | if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && | 1739 | if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && |
@@ -1845,7 +1789,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1845 | 1789 | ||
1846 | vdev = SCpnt->device->hostdata; | 1790 | vdev = SCpnt->device->hostdata; |
1847 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | 1791 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, |
1848 | vdev->vtarget->bus_id, vdev->vtarget->target_id, | 1792 | vdev->vtarget->channel, vdev->vtarget->id, |
1849 | 0, 0, mptscsih_get_tm_timeout(hd->ioc)); | 1793 | 0, 0, mptscsih_get_tm_timeout(hd->ioc)); |
1850 | 1794 | ||
1851 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", | 1795 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", |
@@ -1896,7 +1840,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
1896 | 1840 | ||
1897 | vdev = SCpnt->device->hostdata; | 1841 | vdev = SCpnt->device->hostdata; |
1898 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | 1842 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, |
1899 | vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); | 1843 | vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); |
1900 | 1844 | ||
1901 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", | 1845 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", |
1902 | hd->ioc->name, | 1846 | hd->ioc->name, |
@@ -2191,7 +2135,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, | |||
2191 | 2135 | ||
2192 | dprintk((KERN_NOTICE | 2136 | dprintk((KERN_NOTICE |
2193 | ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n", | 2137 | ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n", |
2194 | sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors)); | 2138 | sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors)); |
2195 | 2139 | ||
2196 | return 0; | 2140 | return 0; |
2197 | } | 2141 | } |
@@ -2200,115 +2144,46 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, | |||
2200 | * | 2144 | * |
2201 | */ | 2145 | */ |
2202 | int | 2146 | int |
2203 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) | 2147 | mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id) |
2204 | { | 2148 | { |
2205 | int i; | 2149 | int i; |
2150 | int rc = 0; | ||
2206 | 2151 | ||
2207 | if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) | 2152 | if (!ioc->raid_data.pIocPg3) |
2208 | return 0; | 2153 | goto out; |
2209 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { | 2154 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { |
2210 | if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) | 2155 | if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) && |
2211 | return 1; | 2156 | (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) { |
2212 | } | 2157 | rc = 1; |
2213 | return 0; | 2158 | goto out; |
2214 | } | 2159 | } |
2215 | EXPORT_SYMBOL(mptscsih_is_phys_disk); | ||
2216 | |||
2217 | int | ||
2218 | mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid) | ||
2219 | { | ||
2220 | int i; | ||
2221 | |||
2222 | if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3) | ||
2223 | return -ENXIO; | ||
2224 | |||
2225 | for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) { | ||
2226 | if (physdiskid == | ||
2227 | hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) | ||
2228 | return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum; | ||
2229 | } | 2160 | } |
2230 | 2161 | ||
2231 | return -ENXIO; | 2162 | out: |
2232 | } | 2163 | return rc; |
2233 | EXPORT_SYMBOL(mptscsih_raid_id_to_num); | ||
2234 | |||
2235 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2236 | /* | ||
2237 | * OS entry point to allow host driver to alloc memory | ||
2238 | * for each scsi target. Called once per device the bus scan. | ||
2239 | * Return non-zero if allocation fails. | ||
2240 | */ | ||
2241 | int | ||
2242 | mptscsih_target_alloc(struct scsi_target *starget) | ||
2243 | { | ||
2244 | VirtTarget *vtarget; | ||
2245 | |||
2246 | vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); | ||
2247 | if (!vtarget) | ||
2248 | return -ENOMEM; | ||
2249 | starget->hostdata = vtarget; | ||
2250 | vtarget->starget = starget; | ||
2251 | return 0; | ||
2252 | } | 2164 | } |
2165 | EXPORT_SYMBOL(mptscsih_is_phys_disk); | ||
2253 | 2166 | ||
2254 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2167 | u8 |
2255 | /* | 2168 | mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id) |
2256 | * OS entry point to allow host driver to alloc memory | ||
2257 | * for each scsi device. Called once per device the bus scan. | ||
2258 | * Return non-zero if allocation fails. | ||
2259 | */ | ||
2260 | int | ||
2261 | mptscsih_slave_alloc(struct scsi_device *sdev) | ||
2262 | { | 2169 | { |
2263 | struct Scsi_Host *host = sdev->host; | 2170 | int i; |
2264 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | 2171 | int rc = -ENXIO; |
2265 | VirtTarget *vtarget; | ||
2266 | VirtDevice *vdev; | ||
2267 | struct scsi_target *starget; | ||
2268 | |||
2269 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); | ||
2270 | if (!vdev) { | ||
2271 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | ||
2272 | hd->ioc->name, sizeof(VirtDevice)); | ||
2273 | return -ENOMEM; | ||
2274 | } | ||
2275 | |||
2276 | vdev->lun = sdev->lun; | ||
2277 | sdev->hostdata = vdev; | ||
2278 | |||
2279 | starget = scsi_target(sdev); | ||
2280 | vtarget = starget->hostdata; | ||
2281 | 2172 | ||
2282 | vdev->vtarget = vtarget; | 2173 | if (!ioc->raid_data.pIocPg3) |
2283 | 2174 | goto out; | |
2284 | if (vtarget->num_luns == 0) { | 2175 | for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { |
2285 | hd->Targets[sdev->id] = vtarget; | 2176 | if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) && |
2286 | vtarget->ioc_id = hd->ioc->id; | 2177 | (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) { |
2287 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | 2178 | rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum; |
2288 | vtarget->target_id = sdev->id; | 2179 | goto out; |
2289 | vtarget->bus_id = sdev->channel; | ||
2290 | if (hd->ioc->bus_type == SPI && sdev->channel == 0 && | ||
2291 | hd->ioc->raid_data.isRaid & (1 << sdev->id)) { | ||
2292 | vtarget->raidVolume = 1; | ||
2293 | ddvtprintk((KERN_INFO | ||
2294 | "RAID Volume @ id %d\n", sdev->id)); | ||
2295 | } | 2180 | } |
2296 | } | 2181 | } |
2297 | vtarget->num_luns++; | ||
2298 | return 0; | ||
2299 | } | ||
2300 | 2182 | ||
2301 | /* | 2183 | out: |
2302 | * OS entry point to allow for host driver to free allocated memory | 2184 | return rc; |
2303 | * Called if no device present or device being unloaded | ||
2304 | */ | ||
2305 | void | ||
2306 | mptscsih_target_destroy(struct scsi_target *starget) | ||
2307 | { | ||
2308 | if (starget->hostdata) | ||
2309 | kfree(starget->hostdata); | ||
2310 | starget->hostdata = NULL; | ||
2311 | } | 2185 | } |
2186 | EXPORT_SYMBOL(mptscsih_raid_id_to_num); | ||
2312 | 2187 | ||
2313 | /* | 2188 | /* |
2314 | * OS entry point to allow for host driver to free allocated memory | 2189 | * OS entry point to allow for host driver to free allocated memory |
@@ -2328,11 +2203,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev) | |||
2328 | vdevice = sdev->hostdata; | 2203 | vdevice = sdev->hostdata; |
2329 | 2204 | ||
2330 | mptscsih_search_running_cmds(hd, vdevice); | 2205 | mptscsih_search_running_cmds(hd, vdevice); |
2331 | vtarget->luns[0] &= ~(1 << vdevice->lun); | ||
2332 | vtarget->num_luns--; | 2206 | vtarget->num_luns--; |
2333 | if (vtarget->num_luns == 0) { | ||
2334 | hd->Targets[sdev->id] = NULL; | ||
2335 | } | ||
2336 | mptscsih_synchronize_cache(hd, vdevice); | 2207 | mptscsih_synchronize_cache(hd, vdevice); |
2337 | kfree(vdevice); | 2208 | kfree(vdevice); |
2338 | sdev->hostdata = NULL; | 2209 | sdev->hostdata = NULL; |
@@ -2394,15 +2265,14 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2394 | VirtDevice *vdevice; | 2265 | VirtDevice *vdevice; |
2395 | struct scsi_target *starget; | 2266 | struct scsi_target *starget; |
2396 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; | 2267 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; |
2397 | int indexed_lun, lun_index; | ||
2398 | 2268 | ||
2399 | starget = scsi_target(sdev); | 2269 | starget = scsi_target(sdev); |
2400 | vtarget = starget->hostdata; | 2270 | vtarget = starget->hostdata; |
2401 | vdevice = sdev->hostdata; | 2271 | vdevice = sdev->hostdata; |
2402 | 2272 | ||
2403 | dsprintk((MYIOC_s_INFO_FMT | 2273 | dsprintk((MYIOC_s_INFO_FMT |
2404 | "device @ %p, id=%d, LUN=%d, channel=%d\n", | 2274 | "device @ %p, channel=%d, id=%d, lun=%d\n", |
2405 | hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel)); | 2275 | hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun)); |
2406 | if (hd->ioc->bus_type == SPI) | 2276 | if (hd->ioc->bus_type == SPI) |
2407 | dsprintk((MYIOC_s_INFO_FMT | 2277 | dsprintk((MYIOC_s_INFO_FMT |
2408 | "sdtr %d wdtr %d ppr %d inq length=%d\n", | 2278 | "sdtr %d wdtr %d ppr %d inq length=%d\n", |
@@ -2415,10 +2285,7 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2415 | goto slave_configure_exit; | 2285 | goto slave_configure_exit; |
2416 | } | 2286 | } |
2417 | 2287 | ||
2418 | vdevice->configured_lun=1; | 2288 | vdevice->configured_lun = 1; |
2419 | lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */ | ||
2420 | indexed_lun = (vdevice->lun % 32); | ||
2421 | vtarget->luns[lun_index] |= (1 << indexed_lun); | ||
2422 | mptscsih_initTarget(hd, vtarget, sdev); | 2289 | mptscsih_initTarget(hd, vtarget, sdev); |
2423 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); | 2290 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); |
2424 | 2291 | ||
@@ -2699,8 +2566,8 @@ static void | |||
2699 | mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, | 2566 | mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, |
2700 | struct scsi_device *sdev) | 2567 | struct scsi_device *sdev) |
2701 | { | 2568 | { |
2702 | dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", | 2569 | dinitprintk((MYIOC_s_INFO_FMT "initTarget channel=%d id=%d lun=%d hd=%p\n", |
2703 | hd->ioc->name, vtarget->bus_id, vtarget->target_id, | 2570 | hd->ioc->name, vtarget->channel, vtarget->id, |
2704 | sdev->lun, hd)); | 2571 | sdev->lun, hd)); |
2705 | 2572 | ||
2706 | /* Is LUN supported? If so, upper 2 bits will be 0 | 2573 | /* Is LUN supported? If so, upper 2 bits will be 0 |
@@ -2721,7 +2588,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, | |||
2721 | /* Treat all Processors as SAF-TE if | 2588 | /* Treat all Processors as SAF-TE if |
2722 | * command line option is set */ | 2589 | * command line option is set */ |
2723 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | 2590 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; |
2724 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); | 2591 | mptscsih_writeIOCPage4(hd, vtarget->channel, vtarget->id); |
2725 | }else if ((sdev->type == TYPE_PROCESSOR) && | 2592 | }else if ((sdev->type == TYPE_PROCESSOR) && |
2726 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { | 2593 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { |
2727 | if (sdev->inquiry_len > 49 ) { | 2594 | if (sdev->inquiry_len > 49 ) { |
@@ -2732,7 +2599,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, | |||
2732 | sdev->inquiry[48] == 'T' && | 2599 | sdev->inquiry[48] == 'T' && |
2733 | sdev->inquiry[49] == 'E' ) { | 2600 | sdev->inquiry[49] == 'E' ) { |
2734 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | 2601 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; |
2735 | mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id); | 2602 | mptscsih_writeIOCPage4(hd, vtarget->channel, vtarget->id); |
2736 | } | 2603 | } |
2737 | } | 2604 | } |
2738 | } | 2605 | } |
@@ -2750,7 +2617,7 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | |||
2750 | struct scsi_device *sdev) | 2617 | struct scsi_device *sdev) |
2751 | { | 2618 | { |
2752 | SpiCfgData *pspi_data = &hd->ioc->spi_data; | 2619 | SpiCfgData *pspi_data = &hd->ioc->spi_data; |
2753 | int id = (int) target->target_id; | 2620 | int id = (int) target->id; |
2754 | int nvram; | 2621 | int nvram; |
2755 | u8 width = MPT_NARROW; | 2622 | u8 width = MPT_NARROW; |
2756 | u8 factor = MPT_ASYNC; | 2623 | u8 factor = MPT_ASYNC; |
@@ -2887,7 +2754,8 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | |||
2887 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2754 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2888 | /* mptscsih_writeIOCPage4 - write IOC Page 4 | 2755 | /* mptscsih_writeIOCPage4 - write IOC Page 4 |
2889 | * @hd: Pointer to a SCSI Host Structure | 2756 | * @hd: Pointer to a SCSI Host Structure |
2890 | * @target_id: write IOC Page4 for this ID & Bus | 2757 | * @channel: write IOC Page4 for this Bus |
2758 | * @id: write IOC Page4 for this ID | ||
2891 | * | 2759 | * |
2892 | * Return: -EAGAIN if unable to obtain a Message Frame | 2760 | * Return: -EAGAIN if unable to obtain a Message Frame |
2893 | * or 0 if success. | 2761 | * or 0 if success. |
@@ -2895,7 +2763,7 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | |||
2895 | * Remark: We do not wait for a return, write pages sequentially. | 2763 | * Remark: We do not wait for a return, write pages sequentially. |
2896 | */ | 2764 | */ |
2897 | static int | 2765 | static int |
2898 | mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) | 2766 | mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int channel, int id) |
2899 | { | 2767 | { |
2900 | MPT_ADAPTER *ioc = hd->ioc; | 2768 | MPT_ADAPTER *ioc = hd->ioc; |
2901 | Config_t *pReq; | 2769 | Config_t *pReq; |
@@ -2936,13 +2804,13 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) | |||
2936 | pReq->Reserved2[ii] = 0; | 2804 | pReq->Reserved2[ii] = 0; |
2937 | } | 2805 | } |
2938 | 2806 | ||
2939 | IOCPage4Ptr = ioc->spi_data.pIocPg4; | 2807 | IOCPage4Ptr = ioc->spi_data.pIocPg4; |
2940 | dataDma = ioc->spi_data.IocPg4_dma; | 2808 | dataDma = ioc->spi_data.IocPg4_dma; |
2941 | ii = IOCPage4Ptr->ActiveSEP++; | 2809 | ii = IOCPage4Ptr->ActiveSEP++; |
2942 | IOCPage4Ptr->SEP[ii].SEPTargetID = target_id; | 2810 | IOCPage4Ptr->SEP[ii].SEPTargetID = id; |
2943 | IOCPage4Ptr->SEP[ii].SEPBus = bus; | 2811 | IOCPage4Ptr->SEP[ii].SEPBus = channel; |
2944 | pReq->Header = IOCPage4Ptr->Header; | 2812 | pReq->Header = IOCPage4Ptr->Header; |
2945 | pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 )); | 2813 | pReq->PageAddress = cpu_to_le32(id | (channel << 8 )); |
2946 | 2814 | ||
2947 | /* Add a SGE to the config request. | 2815 | /* Add a SGE to the config request. |
2948 | */ | 2816 | */ |
@@ -2952,8 +2820,8 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) | |||
2952 | mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); | 2820 | mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); |
2953 | 2821 | ||
2954 | dinitprintk((MYIOC_s_INFO_FMT | 2822 | dinitprintk((MYIOC_s_INFO_FMT |
2955 | "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", | 2823 | "writeIOCPage4: MaxSEP=%d ActiveSEP=%d channel=%d id=%d \n", |
2956 | ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus)); | 2824 | ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, channel, id)); |
2957 | 2825 | ||
2958 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | 2826 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); |
2959 | 2827 | ||
@@ -3343,7 +3211,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3343 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; | 3211 | pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; |
3344 | } else { | 3212 | } else { |
3345 | pScsiReq->TargetID = io->id; | 3213 | pScsiReq->TargetID = io->id; |
3346 | pScsiReq->Bus = io->bus; | 3214 | pScsiReq->Bus = io->channel; |
3347 | pScsiReq->ChainOffset = 0; | 3215 | pScsiReq->ChainOffset = 0; |
3348 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; | 3216 | pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; |
3349 | } | 3217 | } |
@@ -3356,9 +3224,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3356 | pScsiReq->MsgFlags = mpt_msg_flags(); | 3224 | pScsiReq->MsgFlags = mpt_msg_flags(); |
3357 | /* MsgContext set in mpt_get_msg_fram call */ | 3225 | /* MsgContext set in mpt_get_msg_fram call */ |
3358 | 3226 | ||
3359 | for (ii=0; ii < 8; ii++) | 3227 | int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN); |
3360 | pScsiReq->LUN[ii] = 0; | ||
3361 | pScsiReq->LUN[1] = io->lun; | ||
3362 | 3228 | ||
3363 | if (io->flags & MPT_ICFLAG_TAGGED_CMD) | 3229 | if (io->flags & MPT_ICFLAG_TAGGED_CMD) |
3364 | pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ); | 3230 | pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ); |
@@ -3379,7 +3245,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3379 | + (my_idx * MPT_SENSE_BUFFER_ALLOC)); | 3245 | + (my_idx * MPT_SENSE_BUFFER_ALLOC)); |
3380 | 3246 | ||
3381 | ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n", | 3247 | ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n", |
3382 | hd->ioc->name, cmd, io->bus, io->id, io->lun)); | 3248 | hd->ioc->name, cmd, io->channel, io->id, io->lun)); |
3383 | 3249 | ||
3384 | if (dir == MPI_SCSIIO_CONTROL_READ) { | 3250 | if (dir == MPI_SCSIIO_CONTROL_READ) { |
3385 | mpt_add_sge((char *) &pScsiReq->SGL, | 3251 | mpt_add_sge((char *) &pScsiReq->SGL, |
@@ -3462,9 +3328,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
3462 | iocmd.data_dma = -1; | 3328 | iocmd.data_dma = -1; |
3463 | iocmd.size = 0; | 3329 | iocmd.size = 0; |
3464 | iocmd.rsvd = iocmd.rsvd2 = 0; | 3330 | iocmd.rsvd = iocmd.rsvd2 = 0; |
3465 | iocmd.bus = vdevice->vtarget->bus_id; | 3331 | iocmd.channel = vdevice->vtarget->channel; |
3466 | iocmd.id = vdevice->vtarget->target_id; | 3332 | iocmd.id = vdevice->vtarget->id; |
3467 | iocmd.lun = (u8)vdevice->lun; | 3333 | iocmd.lun = vdevice->lun; |
3468 | 3334 | ||
3469 | if ((vdevice->vtarget->type == TYPE_DISK) && | 3335 | if ((vdevice->vtarget->type == TYPE_DISK) && |
3470 | (vdevice->configured_lun)) | 3336 | (vdevice->configured_lun)) |
@@ -3480,9 +3346,6 @@ EXPORT_SYMBOL(mptscsih_resume); | |||
3480 | EXPORT_SYMBOL(mptscsih_proc_info); | 3346 | EXPORT_SYMBOL(mptscsih_proc_info); |
3481 | EXPORT_SYMBOL(mptscsih_info); | 3347 | EXPORT_SYMBOL(mptscsih_info); |
3482 | EXPORT_SYMBOL(mptscsih_qcmd); | 3348 | EXPORT_SYMBOL(mptscsih_qcmd); |
3483 | EXPORT_SYMBOL(mptscsih_target_alloc); | ||
3484 | EXPORT_SYMBOL(mptscsih_slave_alloc); | ||
3485 | EXPORT_SYMBOL(mptscsih_target_destroy); | ||
3486 | EXPORT_SYMBOL(mptscsih_slave_destroy); | 3349 | EXPORT_SYMBOL(mptscsih_slave_destroy); |
3487 | EXPORT_SYMBOL(mptscsih_slave_configure); | 3350 | EXPORT_SYMBOL(mptscsih_slave_configure); |
3488 | EXPORT_SYMBOL(mptscsih_abort); | 3351 | EXPORT_SYMBOL(mptscsih_abort); |
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 187c8af0890b..43b4f236adf9 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h | |||
@@ -53,6 +53,24 @@ | |||
53 | * SCSI Public stuff... | 53 | * SCSI Public stuff... |
54 | */ | 54 | */ |
55 | 55 | ||
56 | #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */ | ||
57 | #define MPT_SCANDV_DID_RESET (0x00000001) | ||
58 | #define MPT_SCANDV_SENSE (0x00000002) | ||
59 | #define MPT_SCANDV_SOME_ERROR (0x00000004) | ||
60 | #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008) | ||
61 | #define MPT_SCANDV_ISSUE_SENSE (0x00000010) | ||
62 | #define MPT_SCANDV_FALLBACK (0x00000020) | ||
63 | |||
64 | #define MPT_SCANDV_MAX_RETRIES (10) | ||
65 | |||
66 | #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ | ||
67 | #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ | ||
68 | #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */ | ||
69 | #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */ | ||
70 | #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */ | ||
71 | #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ | ||
72 | #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ | ||
73 | |||
56 | #define MPT_SCSI_CMD_PER_DEV_HIGH 64 | 74 | #define MPT_SCSI_CMD_PER_DEV_HIGH 64 |
57 | #define MPT_SCSI_CMD_PER_DEV_LOW 32 | 75 | #define MPT_SCSI_CMD_PER_DEV_LOW 32 |
58 | 76 | ||
@@ -69,9 +87,22 @@ | |||
69 | #define MPTSCSIH_SAF_TE 0 | 87 | #define MPTSCSIH_SAF_TE 0 |
70 | #define MPTSCSIH_PT_CLEAR 0 | 88 | #define MPTSCSIH_PT_CLEAR 0 |
71 | 89 | ||
72 | |||
73 | #endif | 90 | #endif |
74 | 91 | ||
92 | typedef struct _internal_cmd { | ||
93 | char *data; /* data pointer */ | ||
94 | dma_addr_t data_dma; /* data dma address */ | ||
95 | int size; /* transfer size */ | ||
96 | u8 cmd; /* SCSI Op Code */ | ||
97 | u8 channel; /* bus number */ | ||
98 | u8 id; /* SCSI ID (virtual) */ | ||
99 | int lun; | ||
100 | u8 flags; /* Bit Field - See above */ | ||
101 | u8 physDiskNum; /* Phys disk number, -1 else */ | ||
102 | u8 rsvd2; | ||
103 | u8 rsvd; | ||
104 | } INTERNAL_CMD; | ||
105 | |||
75 | extern void mptscsih_remove(struct pci_dev *); | 106 | extern void mptscsih_remove(struct pci_dev *); |
76 | extern void mptscsih_shutdown(struct pci_dev *); | 107 | extern void mptscsih_shutdown(struct pci_dev *); |
77 | #ifdef CONFIG_PM | 108 | #ifdef CONFIG_PM |
@@ -81,9 +112,6 @@ extern int mptscsih_resume(struct pci_dev *pdev); | |||
81 | extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); | 112 | extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); |
82 | extern const char * mptscsih_info(struct Scsi_Host *SChost); | 113 | extern const char * mptscsih_info(struct Scsi_Host *SChost); |
83 | extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); | 114 | extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); |
84 | extern int mptscsih_target_alloc(struct scsi_target *starget); | ||
85 | extern int mptscsih_slave_alloc(struct scsi_device *device); | ||
86 | extern void mptscsih_target_destroy(struct scsi_target *starget); | ||
87 | extern void mptscsih_slave_destroy(struct scsi_device *device); | 115 | extern void mptscsih_slave_destroy(struct scsi_device *device); |
88 | extern int mptscsih_slave_configure(struct scsi_device *device); | 116 | extern int mptscsih_slave_configure(struct scsi_device *device); |
89 | extern int mptscsih_abort(struct scsi_cmnd * SCpnt); | 117 | extern int mptscsih_abort(struct scsi_cmnd * SCpnt); |
@@ -98,6 +126,6 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE | |||
98 | extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 126 | extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
99 | extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); | 127 | extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); |
100 | extern void mptscsih_timer_expired(unsigned long data); | 128 | extern void mptscsih_timer_expired(unsigned long data); |
101 | extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | 129 | extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout); |
102 | extern int mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid); | 130 | extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id); |
103 | extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); | 131 | extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id); |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 203c661d2c79..aec0c2fe221f 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -95,25 +95,76 @@ static int mptspiDoneCtx = -1; | |||
95 | static int mptspiTaskCtx = -1; | 95 | static int mptspiTaskCtx = -1; |
96 | static int mptspiInternalCtx = -1; /* Used only for internal commands */ | 96 | static int mptspiInternalCtx = -1; /* Used only for internal commands */ |
97 | 97 | ||
98 | |||
99 | /** | ||
100 | * mptspi_is_raid - Determines whether target is belonging to volume | ||
101 | * @hd: Pointer to a SCSI HOST structure | ||
102 | * @id: target device id | ||
103 | * | ||
104 | * Return: | ||
105 | * non-zero = true | ||
106 | * zero = false | ||
107 | * | ||
108 | */ | ||
109 | static int | ||
110 | mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id) | ||
111 | { | ||
112 | int i, rc = 0; | ||
113 | |||
114 | if (!hd->ioc->raid_data.pIocPg2) | ||
115 | goto out; | ||
116 | |||
117 | if (!hd->ioc->raid_data.pIocPg2->NumActiveVolumes) | ||
118 | goto out; | ||
119 | for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { | ||
120 | if (hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) { | ||
121 | rc = 1; | ||
122 | goto out; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | out: | ||
127 | return rc; | ||
128 | } | ||
129 | |||
98 | static int mptspi_target_alloc(struct scsi_target *starget) | 130 | static int mptspi_target_alloc(struct scsi_target *starget) |
99 | { | 131 | { |
100 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); | 132 | struct Scsi_Host *shost = dev_to_shost(&starget->dev); |
101 | struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; | 133 | struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; |
102 | int ret; | 134 | VirtTarget *vtarget; |
103 | 135 | ||
104 | if (hd == NULL) | 136 | if (hd == NULL) |
105 | return -ENODEV; | 137 | return -ENODEV; |
106 | 138 | ||
107 | ret = mptscsih_target_alloc(starget); | 139 | vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); |
108 | if (ret) | 140 | if (!vtarget) |
109 | return ret; | 141 | return -ENOMEM; |
142 | |||
143 | vtarget->ioc_id = hd->ioc->id; | ||
144 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; | ||
145 | vtarget->id = (u8)starget->id; | ||
146 | vtarget->channel = (u8)starget->channel; | ||
147 | vtarget->starget = starget; | ||
148 | starget->hostdata = vtarget; | ||
149 | |||
150 | if (starget->channel == 1) { | ||
151 | if (mptscsih_is_phys_disk(hd->ioc, 0, starget->id) == 0) | ||
152 | return 0; | ||
153 | vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
154 | /* The real channel for this device is zero */ | ||
155 | vtarget->channel = 0; | ||
156 | /* The actual physdisknum (for RAID passthrough) */ | ||
157 | vtarget->id = mptscsih_raid_id_to_num(hd->ioc, 0, | ||
158 | starget->id); | ||
159 | } | ||
110 | 160 | ||
111 | /* if we're a device on virtual channel 1 and we're not part | 161 | if (starget->channel == 0 && |
112 | * of an array, just return here (otherwise the setup below | 162 | mptspi_is_raid(hd, starget->id)) { |
113 | * may actually affect a real physical device on channel 0 */ | 163 | vtarget->raidVolume = 1; |
114 | if (starget->channel == 1 && | 164 | ddvprintk((KERN_INFO |
115 | mptscsih_raid_id_to_num(hd, starget->id) < 0) | 165 | "RAID Volume @ channel=%d id=%d\n", starget->channel, |
116 | return 0; | 166 | starget->id)); |
167 | } | ||
117 | 168 | ||
118 | if (hd->ioc->spi_data.nvram && | 169 | if (hd->ioc->spi_data.nvram && |
119 | hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { | 170 | hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { |
@@ -132,6 +183,14 @@ static int mptspi_target_alloc(struct scsi_target *starget) | |||
132 | return 0; | 183 | return 0; |
133 | } | 184 | } |
134 | 185 | ||
186 | void | ||
187 | mptspi_target_destroy(struct scsi_target *starget) | ||
188 | { | ||
189 | if (starget->hostdata) | ||
190 | kfree(starget->hostdata); | ||
191 | starget->hostdata = NULL; | ||
192 | } | ||
193 | |||
135 | static int mptspi_read_spi_device_pg0(struct scsi_target *starget, | 194 | static int mptspi_read_spi_device_pg0(struct scsi_target *starget, |
136 | struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0) | 195 | struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0) |
137 | { | 196 | { |
@@ -147,7 +206,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget, | |||
147 | 206 | ||
148 | /* No SPI parameters for RAID devices */ | 207 | /* No SPI parameters for RAID devices */ |
149 | if (starget->channel == 0 && | 208 | if (starget->channel == 0 && |
150 | (hd->ioc->raid_data.isRaid & (1 << starget->id))) | 209 | mptspi_is_raid(hd, starget->id)) |
151 | return -1; | 210 | return -1; |
152 | 211 | ||
153 | size = ioc->spi_data.sdp0length * 4; | 212 | size = ioc->spi_data.sdp0length * 4; |
@@ -233,7 +292,7 @@ static void mptspi_read_parameters(struct scsi_target *starget) | |||
233 | } | 292 | } |
234 | 293 | ||
235 | static int | 294 | static int |
236 | mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk) | 295 | mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id) |
237 | { | 296 | { |
238 | MpiRaidActionRequest_t *pReq; | 297 | MpiRaidActionRequest_t *pReq; |
239 | MPT_FRAME_HDR *mf; | 298 | MPT_FRAME_HDR *mf; |
@@ -253,8 +312,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk) | |||
253 | pReq->Reserved1 = 0; | 312 | pReq->Reserved1 = 0; |
254 | pReq->ChainOffset = 0; | 313 | pReq->ChainOffset = 0; |
255 | pReq->Function = MPI_FUNCTION_RAID_ACTION; | 314 | pReq->Function = MPI_FUNCTION_RAID_ACTION; |
256 | pReq->VolumeID = disk; | 315 | pReq->VolumeID = id; |
257 | pReq->VolumeBus = 0; | 316 | pReq->VolumeBus = channel; |
258 | pReq->PhysDiskNum = 0; | 317 | pReq->PhysDiskNum = 0; |
259 | pReq->MsgFlags = 0; | 318 | pReq->MsgFlags = 0; |
260 | pReq->Reserved2 = 0; | 319 | pReq->Reserved2 = 0; |
@@ -263,8 +322,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk) | |||
263 | mpt_add_sge((char *)&pReq->ActionDataSGE, | 322 | mpt_add_sge((char *)&pReq->ActionDataSGE, |
264 | MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); | 323 | MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); |
265 | 324 | ||
266 | ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n", | 325 | ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action=%x channel=%d id=%d\n", |
267 | hd->ioc->name, action, io->id)); | 326 | hd->ioc->name, pReq->Action, channel, id)); |
268 | 327 | ||
269 | hd->pLocal = NULL; | 328 | hd->pLocal = NULL; |
270 | hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ | 329 | hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ |
@@ -292,12 +351,12 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, | |||
292 | 351 | ||
293 | /* no DV on RAID devices */ | 352 | /* no DV on RAID devices */ |
294 | if (sdev->channel == 0 && | 353 | if (sdev->channel == 0 && |
295 | (hd->ioc->raid_data.isRaid & (1 << sdev->id))) | 354 | mptspi_is_raid(hd, sdev->id)) |
296 | return; | 355 | return; |
297 | 356 | ||
298 | /* If this is a piece of a RAID, then quiesce first */ | 357 | /* If this is a piece of a RAID, then quiesce first */ |
299 | if (sdev->channel == 1 && | 358 | if (sdev->channel == 1 && |
300 | mptscsih_quiesce_raid(hd, 1, vtarget->target_id) < 0) { | 359 | mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) { |
301 | starget_printk(KERN_ERR, scsi_target(sdev), | 360 | starget_printk(KERN_ERR, scsi_target(sdev), |
302 | "Integrated RAID quiesce failed\n"); | 361 | "Integrated RAID quiesce failed\n"); |
303 | return; | 362 | return; |
@@ -306,7 +365,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, | |||
306 | spi_dv_device(sdev); | 365 | spi_dv_device(sdev); |
307 | 366 | ||
308 | if (sdev->channel == 1 && | 367 | if (sdev->channel == 1 && |
309 | mptscsih_quiesce_raid(hd, 0, vtarget->target_id) < 0) | 368 | mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0) |
310 | starget_printk(KERN_ERR, scsi_target(sdev), | 369 | starget_printk(KERN_ERR, scsi_target(sdev), |
311 | "Integrated RAID resume failed\n"); | 370 | "Integrated RAID resume failed\n"); |
312 | 371 | ||
@@ -317,33 +376,32 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, | |||
317 | 376 | ||
318 | static int mptspi_slave_alloc(struct scsi_device *sdev) | 377 | static int mptspi_slave_alloc(struct scsi_device *sdev) |
319 | { | 378 | { |
320 | int ret; | ||
321 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; | 379 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; |
322 | /* gcc doesn't see that all uses of this variable occur within | 380 | VirtTarget *vtarget; |
323 | * the if() statements, so stop it from whining */ | 381 | VirtDevice *vdev; |
324 | int physdisknum = 0; | 382 | struct scsi_target *starget; |
325 | |||
326 | if (sdev->channel == 1) { | ||
327 | physdisknum = mptscsih_raid_id_to_num(hd, sdev->id); | ||
328 | 383 | ||
329 | if (physdisknum < 0) | 384 | if (sdev->channel == 1 && |
330 | return physdisknum; | 385 | mptscsih_is_phys_disk(hd->ioc, 0, sdev->id) == 0) |
386 | return -ENXIO; | ||
387 | |||
388 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); | ||
389 | if (!vdev) { | ||
390 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | ||
391 | hd->ioc->name, sizeof(VirtDevice)); | ||
392 | return -ENOMEM; | ||
331 | } | 393 | } |
332 | 394 | ||
333 | ret = mptscsih_slave_alloc(sdev); | 395 | vdev->lun = sdev->lun; |
396 | sdev->hostdata = vdev; | ||
334 | 397 | ||
335 | if (ret) | 398 | starget = scsi_target(sdev); |
336 | return ret; | 399 | vtarget = starget->hostdata; |
400 | vdev->vtarget = vtarget; | ||
401 | vtarget->num_luns++; | ||
337 | 402 | ||
338 | if (sdev->channel == 1) { | 403 | if (sdev->channel == 1) |
339 | VirtDevice *vdev = sdev->hostdata; | ||
340 | sdev->no_uld_attach = 1; | 404 | sdev->no_uld_attach = 1; |
341 | vdev->vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; | ||
342 | /* The real channel for this device is zero */ | ||
343 | vdev->vtarget->bus_id = 0; | ||
344 | /* The actual physdisknum (for RAID passthrough) */ | ||
345 | vdev->vtarget->target_id = physdisknum; | ||
346 | } | ||
347 | 405 | ||
348 | return 0; | 406 | return 0; |
349 | } | 407 | } |
@@ -358,13 +416,35 @@ static int mptspi_slave_configure(struct scsi_device *sdev) | |||
358 | return ret; | 416 | return ret; |
359 | 417 | ||
360 | if ((sdev->channel == 1 || | 418 | if ((sdev->channel == 1 || |
361 | !(hd->ioc->raid_data.isRaid & (1 << sdev->id))) && | 419 | !(mptspi_is_raid(hd, sdev->id))) && |
362 | !spi_initial_dv(sdev->sdev_target)) | 420 | !spi_initial_dv(sdev->sdev_target)) |
363 | mptspi_dv_device(hd, sdev); | 421 | mptspi_dv_device(hd, sdev); |
364 | 422 | ||
365 | return 0; | 423 | return 0; |
366 | } | 424 | } |
367 | 425 | ||
426 | static int | ||
427 | mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | ||
428 | { | ||
429 | struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; | ||
430 | VirtDevice *vdev = SCpnt->device->hostdata; | ||
431 | |||
432 | if (!vdev || !vdev->vtarget) { | ||
433 | SCpnt->result = DID_NO_CONNECT << 16; | ||
434 | done(SCpnt); | ||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | if (SCpnt->device->channel == 1 && | ||
439 | mptscsih_is_phys_disk(hd->ioc, 0, SCpnt->device->id) == 0) { | ||
440 | SCpnt->result = DID_NO_CONNECT << 16; | ||
441 | done(SCpnt); | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | return mptscsih_qcmd(SCpnt,done); | ||
446 | } | ||
447 | |||
368 | static void mptspi_slave_destroy(struct scsi_device *sdev) | 448 | static void mptspi_slave_destroy(struct scsi_device *sdev) |
369 | { | 449 | { |
370 | struct scsi_target *starget = scsi_target(sdev); | 450 | struct scsi_target *starget = scsi_target(sdev); |
@@ -392,11 +472,11 @@ static struct scsi_host_template mptspi_driver_template = { | |||
392 | .proc_info = mptscsih_proc_info, | 472 | .proc_info = mptscsih_proc_info, |
393 | .name = "MPT SPI Host", | 473 | .name = "MPT SPI Host", |
394 | .info = mptscsih_info, | 474 | .info = mptscsih_info, |
395 | .queuecommand = mptscsih_qcmd, | 475 | .queuecommand = mptspi_qcmd, |
396 | .target_alloc = mptspi_target_alloc, | 476 | .target_alloc = mptspi_target_alloc, |
397 | .slave_alloc = mptspi_slave_alloc, | 477 | .slave_alloc = mptspi_slave_alloc, |
398 | .slave_configure = mptspi_slave_configure, | 478 | .slave_configure = mptspi_slave_configure, |
399 | .target_destroy = mptscsih_target_destroy, | 479 | .target_destroy = mptspi_target_destroy, |
400 | .slave_destroy = mptspi_slave_destroy, | 480 | .slave_destroy = mptspi_slave_destroy, |
401 | .change_queue_depth = mptscsih_change_queue_depth, | 481 | .change_queue_depth = mptscsih_change_queue_depth, |
402 | .eh_abort_handler = mptscsih_abort, | 482 | .eh_abort_handler = mptscsih_abort, |
@@ -427,7 +507,7 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget, | |||
427 | 507 | ||
428 | /* don't allow updating nego parameters on RAID devices */ | 508 | /* don't allow updating nego parameters on RAID devices */ |
429 | if (starget->channel == 0 && | 509 | if (starget->channel == 0 && |
430 | (hd->ioc->raid_data.isRaid & (1 << starget->id))) | 510 | mptspi_is_raid(hd, starget->id)) |
431 | return -1; | 511 | return -1; |
432 | 512 | ||
433 | size = ioc->spi_data.sdp1length * 4; | 513 | size = ioc->spi_data.sdp1length * 4; |
@@ -672,9 +752,9 @@ static void mpt_work_wrapper(struct work_struct *work) | |||
672 | if (sdev->channel != 1) | 752 | if (sdev->channel != 1) |
673 | continue; | 753 | continue; |
674 | 754 | ||
675 | /* The target_id is the raid PhysDiskNum, even if | 755 | /* The id is the raid PhysDiskNum, even if |
676 | * starget->id is the actual target address */ | 756 | * starget->id is the actual target address */ |
677 | if(vtarget->target_id != disk) | 757 | if(vtarget->id != disk) |
678 | continue; | 758 | continue; |
679 | 759 | ||
680 | starget_printk(KERN_INFO, vtarget->starget, | 760 | starget_printk(KERN_INFO, vtarget->starget, |
@@ -727,7 +807,7 @@ mptspi_deny_binding(struct scsi_target *starget) | |||
727 | { | 807 | { |
728 | struct _MPT_SCSI_HOST *hd = | 808 | struct _MPT_SCSI_HOST *hd = |
729 | (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata; | 809 | (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata; |
730 | return ((hd->ioc->raid_data.isRaid & (1 << starget->id)) && | 810 | return ((mptspi_is_raid(hd, starget->id)) && |
731 | starget->channel == 0) ? 1 : 0; | 811 | starget->channel == 0) ? 1 : 0; |
732 | } | 812 | } |
733 | 813 | ||
@@ -945,7 +1025,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
945 | * max_lun = 1 + actual last lun, | 1025 | * max_lun = 1 + actual last lun, |
946 | * see hosts.h :o( | 1026 | * see hosts.h :o( |
947 | */ | 1027 | */ |
948 | sh->max_id = MPT_MAX_SCSI_DEVICES; | 1028 | sh->max_id = ioc->devices_per_bus; |
949 | 1029 | ||
950 | sh->max_lun = MPT_LAST_LUN + 1; | 1030 | sh->max_lun = MPT_LAST_LUN + 1; |
951 | /* | 1031 | /* |
@@ -1009,20 +1089,6 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1009 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", | 1089 | dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", |
1010 | ioc->name, hd->ScsiLookup)); | 1090 | ioc->name, hd->ScsiLookup)); |
1011 | 1091 | ||
1012 | /* Allocate memory for the device structures. | ||
1013 | * A non-Null pointer at an offset | ||
1014 | * indicates a device exists. | ||
1015 | * max_id = 1 + maximum id (hosts.h) | ||
1016 | */ | ||
1017 | hd->Targets = kcalloc(sh->max_id * (sh->max_channel + 1), | ||
1018 | sizeof(void *), GFP_ATOMIC); | ||
1019 | if (!hd->Targets) { | ||
1020 | error = -ENOMEM; | ||
1021 | goto out_mptspi_probe; | ||
1022 | } | ||
1023 | |||
1024 | dprintk((KERN_INFO " vdev @ %p\n", hd->Targets)); | ||
1025 | |||
1026 | /* Clear the TM flags | 1092 | /* Clear the TM flags |
1027 | */ | 1093 | */ |
1028 | hd->tmPending = 0; | 1094 | hd->tmPending = 0; |