Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c64f977 authored by Jan Beulich's avatar Jan Beulich Committed by Greg Kroah-Hartman
Browse files

[PATCH] PCI Hotplug: Fix recovery path from errors during pcie_init()



Signed-off-by: default avatarJan Beulich <jbeulich@novell.com>
Cc: Kristen Accardi <kristen.c.accardi@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9df7fde5
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -1471,7 +1471,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
	rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
	if (rc) {
		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
		goto abort_free_ctlr;
		goto abort_free_irq;
	}

	intr_enable = intr_enable | PRSN_DETECT_ENABLE;
@@ -1497,19 +1497,19 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
	rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
	if (rc) {
		err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
		goto abort_free_ctlr;
		goto abort_free_irq;
	}
	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
	if (rc) {
		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
		goto abort_free_ctlr;
		goto abort_disable_intr;
	}
	
	temp_word =  0x1F; /* Clear all events */
	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
	if (rc) {
		err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
		goto abort_free_ctlr;
		goto abort_disable_intr;
	}
	
	if (pciehp_force) {
@@ -1518,7 +1518,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
	} else {
		rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
		if (rc)
			goto abort_free_ctlr;
			goto abort_disable_intr;
	}

	/*  Add this HPC instance into the HPC list */
@@ -1545,6 +1545,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
	return 0;

	/* We end up here for the many possible ways to fail this API.  */
abort_disable_intr:
	rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
	if (!rc) {
		temp_word &= ~(intr_enable | HP_INTR_ENABLE);
		rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
	}
	if (rc)
		err("%s : disabling interrupts failed\n", __FUNCTION__);

abort_free_irq:
	if (pciehp_poll_mode)
		del_timer_sync(&php_ctlr->int_poll_timer);
	else
		free_irq(php_ctlr->irq, ctrl);

abort_free_ctlr:
	pcie_cap_base = saved_cap_base;
	kfree(php_ctlr);