diff options
author | nagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com> | 2011-10-21 00:38:07 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-10-30 04:56:55 -0400 |
commit | 35116db95c42937061bfca93998291f6562e9e92 (patch) | |
tree | ca1c8d23186c78d8796c8786d8d566c7fc845f64 /drivers/scsi/mpt2sas/mpt2sas_config.c | |
parent | 6faace2a0e418b45728bcea6d3626922cf16b14b (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.c | 67 |
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); |