mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
mpt2sas: Fix for device scan following host reset could get stuck in a infinite loop
commit 6241f22ca1
upstream.
Modified device scan routine so each configuration page read breaks from the
while loop when the ioc_status is not equal to MPI2_IOCSTATUS_SUCCESS.
[jejb: checkpatch fixes]
Signed-off-by: Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
[bwh: Backported to 3.2; adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: Rui Xiang <rui.xiang@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
21b40f509a
commit
ce7035a6fd
1 changed files with 115 additions and 3 deletions
|
@ -7039,11 +7039,14 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|||
struct _sas_device *sas_device;
|
||||
struct _sas_node *expander_device;
|
||||
static struct _raid_device *raid_device;
|
||||
u8 retry_count;
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "scan devices: start\n", ioc->name);
|
||||
|
||||
_scsih_sas_host_refresh(ioc);
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "\tscan devices: expanders start\n",
|
||||
ioc->name);
|
||||
/* expanders */
|
||||
handle = 0xFFFF;
|
||||
while (!(mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
|
||||
|
@ -7052,19 +7055,39 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
||||
break;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
printk(MPT2SAS_INFO_FMT "\tbreak from expander scan: "
|
||||
"ioc_status(0x%04x), loginfo(0x%08x)\n",
|
||||
ioc->name, ioc_status,
|
||||
le32_to_cpu(mpi_reply.IOCLogInfo));
|
||||
break;
|
||||
}
|
||||
handle = le16_to_cpu(expander_pg0.DevHandle);
|
||||
expander_device = mpt2sas_scsih_expander_find_by_sas_address(
|
||||
ioc, le64_to_cpu(expander_pg0.SASAddress));
|
||||
if (expander_device)
|
||||
_scsih_refresh_expander_links(ioc, expander_device,
|
||||
handle);
|
||||
else
|
||||
else {
|
||||
printk(MPT2SAS_INFO_FMT "\tBEFORE adding expander: "
|
||||
"handle (0x%04x), sas_addr(0x%016llx)\n",
|
||||
ioc->name, handle, (unsigned long long)
|
||||
le64_to_cpu(expander_pg0.SASAddress));
|
||||
_scsih_expander_add(ioc, handle);
|
||||
printk(MPT2SAS_INFO_FMT "\tAFTER adding expander: "
|
||||
"handle (0x%04x), sas_addr(0x%016llx)\n",
|
||||
ioc->name, handle, (unsigned long long)
|
||||
le64_to_cpu(expander_pg0.SASAddress));
|
||||
}
|
||||
}
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "\tscan devices: expanders complete\n",
|
||||
ioc->name);
|
||||
|
||||
if (!ioc->ir_firmware)
|
||||
goto skip_to_sas;
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "\tscan devices phys disk start\n", ioc->name);
|
||||
/* phys disk */
|
||||
phys_disk_num = 0xFF;
|
||||
while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
|
||||
|
@ -7074,6 +7097,13 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
||||
break;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan:"
|
||||
"ioc_status(0x%04x), loginfo(0x%08x)\n",
|
||||
ioc->name, ioc_status,
|
||||
le32_to_cpu(mpi_reply.IOCLogInfo));
|
||||
break;
|
||||
}
|
||||
phys_disk_num = pd_pg0.PhysDiskNum;
|
||||
handle = le16_to_cpu(pd_pg0.DevHandle);
|
||||
sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
|
||||
|
@ -7083,17 +7113,46 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|||
&sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
|
||||
handle) != 0)
|
||||
continue;
|
||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
||||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan "
|
||||
"ioc_status(0x%04x), loginfo(0x%08x)\n",
|
||||
ioc->name, ioc_status,
|
||||
le32_to_cpu(mpi_reply.IOCLogInfo));
|
||||
break;
|
||||
}
|
||||
parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
|
||||
if (!_scsih_get_sas_address(ioc, parent_handle,
|
||||
&sas_address)) {
|
||||
printk(MPT2SAS_INFO_FMT "\tBEFORE adding phys disk: "
|
||||
" handle (0x%04x), sas_addr(0x%016llx)\n",
|
||||
ioc->name, handle, (unsigned long long)
|
||||
le64_to_cpu(sas_device_pg0.SASAddress));
|
||||
mpt2sas_transport_update_links(ioc, sas_address,
|
||||
handle, sas_device_pg0.PhyNum,
|
||||
MPI2_SAS_NEG_LINK_RATE_1_5);
|
||||
set_bit(handle, ioc->pd_handles);
|
||||
_scsih_add_device(ioc, handle, 0, 1);
|
||||
retry_count = 0;
|
||||
/* This will retry adding the end device.
|
||||
* _scsih_add_device() will decide on retries and
|
||||
* return "1" when it should be retried
|
||||
*/
|
||||
while (_scsih_add_device(ioc, handle, retry_count++,
|
||||
1)) {
|
||||
ssleep(1);
|
||||
}
|
||||
printk(MPT2SAS_INFO_FMT "\tAFTER adding phys disk: "
|
||||
" handle (0x%04x), sas_addr(0x%016llx)\n",
|
||||
ioc->name, handle, (unsigned long long)
|
||||
le64_to_cpu(sas_device_pg0.SASAddress));
|
||||
}
|
||||
}
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "\tscan devices: phys disk complete\n",
|
||||
ioc->name);
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "\tscan devices: volumes start\n", ioc->name);
|
||||
/* volumes */
|
||||
handle = 0xFFFF;
|
||||
while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
|
||||
|
@ -7102,6 +7161,13 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
||||
break;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: "
|
||||
"ioc_status(0x%04x), loginfo(0x%08x)\n",
|
||||
ioc->name, ioc_status,
|
||||
le32_to_cpu(mpi_reply.IOCLogInfo));
|
||||
break;
|
||||
}
|
||||
handle = le16_to_cpu(volume_pg1.DevHandle);
|
||||
raid_device = _scsih_raid_device_find_by_wwid(ioc,
|
||||
le64_to_cpu(volume_pg1.WWID));
|
||||
|
@ -7111,18 +7177,38 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|||
&volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle,
|
||||
sizeof(Mpi2RaidVolPage0_t)))
|
||||
continue;
|
||||
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
|
||||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: "
|
||||
"ioc_status(0x%04x), loginfo(0x%08x)\n",
|
||||
ioc->name, ioc_status,
|
||||
le32_to_cpu(mpi_reply.IOCLogInfo));
|
||||
break;
|
||||
}
|
||||
if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL ||
|
||||
volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE ||
|
||||
volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) {
|
||||
memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t));
|
||||
element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED;
|
||||
element.VolDevHandle = volume_pg1.DevHandle;
|
||||
printk(MPT2SAS_INFO_FMT "\tBEFORE adding volume: "
|
||||
" handle (0x%04x)\n", ioc->name,
|
||||
volume_pg1.DevHandle);
|
||||
_scsih_sas_volume_add(ioc, &element);
|
||||
printk(MPT2SAS_INFO_FMT "\tAFTER adding volume: "
|
||||
" handle (0x%04x)\n", ioc->name,
|
||||
volume_pg1.DevHandle);
|
||||
}
|
||||
}
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "\tscan devices: volumes complete\n",
|
||||
ioc->name);
|
||||
|
||||
skip_to_sas:
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "\tscan devices: end devices start\n",
|
||||
ioc->name);
|
||||
/* sas devices */
|
||||
handle = 0xFFFF;
|
||||
while (!(mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
|
||||
|
@ -7132,6 +7218,13 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|||
MPI2_IOCSTATUS_MASK;
|
||||
if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
|
||||
break;
|
||||
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
|
||||
printk(MPT2SAS_INFO_FMT "\tbreak from end device scan:"
|
||||
" ioc_status(0x%04x), loginfo(0x%08x)\n",
|
||||
ioc->name, ioc_status,
|
||||
le32_to_cpu(mpi_reply.IOCLogInfo));
|
||||
break;
|
||||
}
|
||||
handle = le16_to_cpu(sas_device_pg0.DevHandle);
|
||||
if (!(_scsih_is_end_device(
|
||||
le32_to_cpu(sas_device_pg0.DeviceInfo))))
|
||||
|
@ -7142,12 +7235,31 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
|
|||
continue;
|
||||
parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle);
|
||||
if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) {
|
||||
printk(MPT2SAS_INFO_FMT "\tBEFORE adding end device: "
|
||||
"handle (0x%04x), sas_addr(0x%016llx)\n",
|
||||
ioc->name, handle, (unsigned long long)
|
||||
le64_to_cpu(sas_device_pg0.SASAddress));
|
||||
mpt2sas_transport_update_links(ioc, sas_address, handle,
|
||||
sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
|
||||
_scsih_add_device(ioc, handle, 0, 0);
|
||||
retry_count = 0;
|
||||
/* This will retry adding the end device.
|
||||
* _scsih_add_device() will decide on retries and
|
||||
* return "1" when it should be retried
|
||||
*/
|
||||
while (_scsih_add_device(ioc, handle, retry_count++,
|
||||
0)) {
|
||||
ssleep(1);
|
||||
}
|
||||
printk(MPT2SAS_INFO_FMT "\tAFTER adding end device: "
|
||||
"handle (0x%04x), sas_addr(0x%016llx)\n",
|
||||
ioc->name, handle, (unsigned long long)
|
||||
le64_to_cpu(sas_device_pg0.SASAddress));
|
||||
}
|
||||
}
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "\tscan devices: end devices complete\n",
|
||||
ioc->name);
|
||||
|
||||
printk(MPT2SAS_INFO_FMT "scan devices: complete\n", ioc->name);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue