diff options
author | Jan Beulich <jbeulich@novell.com> | 2006-05-09 03:50:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-19 17:13:24 -0400 |
commit | 9c64f9774805ba5d5ad4129899bdd822f61874e9 (patch) | |
tree | afa3c4325d7867f3417b44fecd4915b8f529c776 /drivers/pci/hotplug | |
parent | 9df7fde52c33075b9f9148ee31215c03824fcc38 (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>
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 25 |
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. */ |
1548 | abort_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 | |||
1557 | abort_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 | |||
1548 | abort_free_ctlr: | 1563 | abort_free_ctlr: |
1549 | pcie_cap_base = saved_cap_base; | 1564 | pcie_cap_base = saved_cap_base; |
1550 | kfree(php_ctlr); | 1565 | kfree(php_ctlr); |