aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2006-05-09 03:50:31 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-19 17:13:24 -0400
commit9c64f9774805ba5d5ad4129899bdd822f61874e9 (patch)
treeafa3c4325d7867f3417b44fecd4915b8f529c776
parent9df7fde52c33075b9f9148ee31215c03824fcc38 (diff)
[PATCH] PCI Hotplug: Fix recovery path from errors during pcie_init()
Signed-off-by: Jan Beulich <jbeulich@novell.com> Cc: Kristen Accardi <kristen.c.accardi@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 081dfef4fe62..d77138ecb098 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1471,7 +1471,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1471 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); 1471 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1472 if (rc) { 1472 if (rc) {
1473 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 1473 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1474 goto abort_free_ctlr; 1474 goto abort_free_irq;
1475 } 1475 }
1476 1476
1477 intr_enable = intr_enable | PRSN_DETECT_ENABLE; 1477 intr_enable = intr_enable | PRSN_DETECT_ENABLE;
@@ -1497,19 +1497,19 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1497 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); 1497 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1498 if (rc) { 1498 if (rc) {
1499 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 1499 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1500 goto abort_free_ctlr; 1500 goto abort_free_irq;
1501 } 1501 }
1502 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 1502 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
1503 if (rc) { 1503 if (rc) {
1504 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 1504 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1505 goto abort_free_ctlr; 1505 goto abort_disable_intr;
1506 } 1506 }
1507 1507
1508 temp_word = 0x1F; /* Clear all events */ 1508 temp_word = 0x1F; /* Clear all events */
1509 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); 1509 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
1510 if (rc) { 1510 if (rc) {
1511 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); 1511 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1512 goto abort_free_ctlr; 1512 goto abort_disable_intr;
1513 } 1513 }
1514 1514
1515 if (pciehp_force) { 1515 if (pciehp_force) {
@@ -1518,7 +1518,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1518 } else { 1518 } else {
1519 rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev); 1519 rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
1520 if (rc) 1520 if (rc)
1521 goto abort_free_ctlr; 1521 goto abort_disable_intr;
1522 } 1522 }
1523 1523
1524 /* Add this HPC instance into the HPC list */ 1524 /* Add this HPC instance into the HPC list */
@@ -1545,6 +1545,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1545 return 0; 1545 return 0;
1546 1546
1547 /* We end up here for the many possible ways to fail this API. */ 1547 /* We end up here for the many possible ways to fail this API. */
1548abort_disable_intr:
1549 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1550 if (!rc) {
1551 temp_word &= ~(intr_enable | HP_INTR_ENABLE);
1552 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1553 }
1554 if (rc)
1555 err("%s : disabling interrupts failed\n", __FUNCTION__);
1556
1557abort_free_irq:
1558 if (pciehp_poll_mode)
1559 del_timer_sync(&php_ctlr->int_poll_timer);
1560 else
1561 free_irq(php_ctlr->irq, ctrl);
1562
1548abort_free_ctlr: 1563abort_free_ctlr:
1549 pcie_cap_base = saved_cap_base; 1564 pcie_cap_base = saved_cap_base;
1550 kfree(php_ctlr); 1565 kfree(php_ctlr);