aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_config.c
diff options
context:
space:
mode:
authornagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com>2011-10-21 00:38:07 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-30 04:56:55 -0400
commit35116db95c42937061bfca93998291f6562e9e92 (patch)
treeca1c8d23186c78d8796c8786d8d566c7fc845f64 /drivers/scsi/mpt2sas/mpt2sas_config.c
parent6faace2a0e418b45728bcea6d3626922cf16b14b (diff)
[SCSI] mpt2sas: Fix for Panic when inactive volume is tried deleting
The driver was setting the action to MPI2_CONFIG_ACTION_PAGE_READ_CURRENT, which only returns active volumes. In order to get info on inactive volumes, the driver needs to change the action to MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM, and traverse each config till the iocstatus is MPI2_IOCSTATUS_CONFIG_INVALID_PAGE returned. Added a change in the driver to remove the instance of sas_device object when the driver returns "1" from the slave_configure callback. Also fixed code to report the hot spares to the operating system with a /dev/sg assigned. Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com> Cc: stable@kernel.org Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_config.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c67
1 files changed, 44 insertions, 23 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 2b1101076cfe..36ea0b2d8020 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -1356,6 +1356,9 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1356 Mpi2ConfigReply_t mpi_reply; 1356 Mpi2ConfigReply_t mpi_reply;
1357 int r, i, config_page_sz; 1357 int r, i, config_page_sz;
1358 u16 ioc_status; 1358 u16 ioc_status;
1359 int config_num;
1360 u16 element_type;
1361 u16 phys_disk_dev_handle;
1359 1362
1360 *volume_handle = 0; 1363 *volume_handle = 0;
1361 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); 1364 memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
@@ -1371,35 +1374,53 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
1371 if (r) 1374 if (r)
1372 goto out; 1375 goto out;
1373 1376
1374 mpi_request.PageAddress =
1375 cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG);
1376 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; 1377 mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
1377 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); 1378 config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
1378 config_page = kmalloc(config_page_sz, GFP_KERNEL); 1379 config_page = kmalloc(config_page_sz, GFP_KERNEL);
1379 if (!config_page) 1380 if (!config_page) {
1380 goto out; 1381 r = -1;
1381 r = _config_request(ioc, &mpi_request, &mpi_reply,
1382 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1383 config_page_sz);
1384 if (r)
1385 goto out; 1382 goto out;
1386 1383 }
1387 r = -1; 1384 config_num = 0xff;
1388 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; 1385 while (1) {
1389 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) 1386 mpi_request.PageAddress = cpu_to_le32(config_num +
1390 goto out; 1387 MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM);
1391 for (i = 0; i < config_page->NumElements; i++) { 1388 r = _config_request(ioc, &mpi_request, &mpi_reply,
1392 if ((le16_to_cpu(config_page->ConfigElement[i].ElementFlags) & 1389 MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
1393 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) != 1390 config_page_sz);
1394 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT) 1391 if (r)
1395 continue; 1392 goto out;
1396 if (le16_to_cpu(config_page->ConfigElement[i]. 1393 r = -1;
1397 PhysDiskDevHandle) == pd_handle) { 1394 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
1398 *volume_handle = le16_to_cpu(config_page-> 1395 MPI2_IOCSTATUS_MASK;
1399 ConfigElement[i].VolDevHandle); 1396 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
1400 r = 0;
1401 goto out; 1397 goto out;
1398 for (i = 0; i < config_page->NumElements; i++) {
1399 element_type = le16_to_cpu(config_page->
1400 ConfigElement[i].ElementFlags) &
1401 MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE;
1402 if (element_type ==
1403 MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT ||
1404 element_type ==
1405 MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) {
1406 phys_disk_dev_handle =
1407 le16_to_cpu(config_page->ConfigElement[i].
1408 PhysDiskDevHandle);
1409 if (phys_disk_dev_handle == pd_handle) {
1410 *volume_handle =
1411 le16_to_cpu(config_page->
1412 ConfigElement[i].VolDevHandle);
1413 r = 0;
1414 goto out;
1415 }
1416 } else if (element_type ==
1417 MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) {
1418 *volume_handle = 0;
1419 r = 0;
1420 goto out;
1421 }
1402 } 1422 }
1423 config_num = config_page->ConfigNum;
1403 } 1424 }
1404 out: 1425 out:
1405 kfree(config_page); 1426 kfree(config_page);