aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2014-09-29 22:38:53 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2014-09-30 03:15:07 -0400
commit316233ff878451e198e3633fd9165c437007a309 (patch)
tree0aad8e32ff12769a6a362ba93587e07f1055e4d4
parent0d5ee5205e62908172bf5e1a5fd171ba262fdb75 (diff)
powerpc/eeh: Reenable PCI devices after reset
The PCI devices that have been passed through are enabled before reset, we need restore to the enabled state after reset. Otherwise, MMIO access might be issued to disabled devices after reset and causes exceptional recursive EEH error. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/kernel/eeh.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 633f6bf965c3..6b4690f315d3 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -1342,6 +1342,53 @@ int eeh_pe_get_state(struct eeh_pe *pe)
1342} 1342}
1343EXPORT_SYMBOL_GPL(eeh_pe_get_state); 1343EXPORT_SYMBOL_GPL(eeh_pe_get_state);
1344 1344
1345static int eeh_pe_reenable_devices(struct eeh_pe *pe)
1346{
1347 struct eeh_dev *edev, *tmp;
1348 struct pci_dev *pdev;
1349 int ret = 0;
1350
1351 /* Restore config space */
1352 eeh_pe_restore_bars(pe);
1353
1354 /*
1355 * Reenable PCI devices as the devices passed
1356 * through are always enabled before the reset.
1357 */
1358 eeh_pe_for_each_dev(pe, edev, tmp) {
1359 pdev = eeh_dev_to_pci_dev(edev);
1360 if (!pdev)
1361 continue;
1362
1363 ret = pci_reenable_device(pdev);
1364 if (ret) {
1365 pr_warn("%s: Failure %d reenabling %s\n",
1366 __func__, ret, pci_name(pdev));
1367 return ret;
1368 }
1369 }
1370
1371 /* The PE is still in frozen state */
1372 ret = eeh_ops->set_option(pe, EEH_OPT_THAW_MMIO);
1373 if (ret) {
1374 pr_warn("%s: Failure %d enabling MMIO for PHB#%x-PE#%x\n",
1375 __func__, ret, pe->phb->global_number, pe->addr);
1376 return ret;
1377 }
1378
1379 ret = eeh_ops->set_option(pe, EEH_OPT_THAW_DMA);
1380 if (ret) {
1381 pr_warn("%s: Failure %d enabling DMA for PHB#%x-PE#%x\n",
1382 __func__, ret, pe->phb->global_number, pe->addr);
1383 return ret;
1384 }
1385
1386 /* Clear software isolated state */
1387 eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
1388
1389 return ret;
1390}
1391
1345/** 1392/**
1346 * eeh_pe_reset - Issue PE reset according to specified type 1393 * eeh_pe_reset - Issue PE reset according to specified type
1347 * @pe: EEH PE 1394 * @pe: EEH PE
@@ -1368,17 +1415,7 @@ int eeh_pe_reset(struct eeh_pe *pe, int option)
1368 if (ret) 1415 if (ret)
1369 break; 1416 break;
1370 1417
1371 /* 1418 ret = eeh_pe_reenable_devices(pe);
1372 * The PE is still in frozen state and we need to clear
1373 * that. It's good to clear frozen state after deassert
1374 * to avoid messy IO access during reset, which might
1375 * cause recursive frozen PE.
1376 */
1377 ret = eeh_ops->set_option(pe, EEH_OPT_THAW_MMIO);
1378 if (!ret)
1379 ret = eeh_ops->set_option(pe, EEH_OPT_THAW_DMA);
1380 if (!ret)
1381 eeh_pe_state_clear(pe, EEH_PE_ISOLATED);
1382 break; 1419 break;
1383 case EEH_RESET_HOT: 1420 case EEH_RESET_HOT:
1384 case EEH_RESET_FUNDAMENTAL: 1421 case EEH_RESET_FUNDAMENTAL:
@@ -1417,9 +1454,6 @@ int eeh_pe_configure(struct eeh_pe *pe)
1417 if (!pe) 1454 if (!pe)
1418 return -ENODEV; 1455 return -ENODEV;
1419 1456
1420 /* Restore config space for the affected devices */
1421 eeh_pe_restore_bars(pe);
1422
1423 return ret; 1457 return ret;
1424} 1458}
1425EXPORT_SYMBOL_GPL(eeh_pe_configure); 1459EXPORT_SYMBOL_GPL(eeh_pe_configure);