diff options
author | Greg KH <greg@press.(none)> | 2005-10-18 19:23:54 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-18 19:23:54 -0700 |
commit | e1066393df50f590b1eb5c97b95cc767cda9e51f (patch) | |
tree | 7c58a5977bbe06cbdb2f998da9158136fdcf2ff2 /pci | |
parent | 4c6041c8a1daba108640353acad7812c10769dcc (diff) | |
download | patches-e1066393df50f590b1eb5c97b95cc767cda9e51f.tar.gz |
pci and usb patches
Diffstat (limited to 'pci')
-rw-r--r-- | pci/acpi-add-ability-to-derive-irq-when-doing-a-surpriseremoval-of-an-adapter.patch | 211 | ||||
-rw-r--r-- | pci/acpiphp-allocate-resources-for-adapters-with-bridges.patch | 45 |
2 files changed, 256 insertions, 0 deletions
diff --git a/pci/acpi-add-ability-to-derive-irq-when-doing-a-surpriseremoval-of-an-adapter.patch b/pci/acpi-add-ability-to-derive-irq-when-doing-a-surpriseremoval-of-an-adapter.patch new file mode 100644 index 0000000000000..072abaf9d8fff --- /dev/null +++ b/pci/acpi-add-ability-to-derive-irq-when-doing-a-surpriseremoval-of-an-adapter.patch @@ -0,0 +1,211 @@ +From kristen.c.accardi@intel.com Tue Oct 18 17:01:04 2005 +From: Kristen Accardi <kristen.c.accardi@intel.com> +Subject: acpi: add ability to derive irq when doing a surpriseremoval of an adapter +To: greg@kroah.com +Cc: "Shah, Rajesh" <rajesh.shah@intel.com>, "Brown, Len" <len.brown@intel.com> +Date: Tue, 18 Oct 2005 16:57:57 -0700 +Message-Id: <1129679877.30588.5.camel@whizzy> + +For surprise hotplug removal, the interrupt pin must be guessed, as any +attempts to read it would obviously be invalid. This patch adds a new +function to cycle through all possible pin values, and tries to either +lookup or derive the right irq to disable. It also adds a new function +to acpi which can be used to just find the irq, without freeing it, just +in case we guess the wrong pin. + +Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/acpi/pci_irq.c | 110 ++++++++++++++++++++++++++++++++++++++++++++ + drivers/acpi/pci_link.c | 35 ++++++++++++++ + include/acpi/acpi_drivers.h | 1 + 3 files changed, 146 insertions(+) + +--- gregkh-2.6.orig/drivers/acpi/pci_irq.c ++++ gregkh-2.6/drivers/acpi/pci_irq.c +@@ -298,6 +298,28 @@ acpi_pci_free_irq(struct acpi_prt_entry + return_VALUE(irq); + } + ++ ++ ++static int ++acpi_pci_find_irq(struct acpi_prt_entry *entry, ++ int *edge_level, int *active_high_low, char **link) ++{ ++ int irq; ++ ++ ACPI_FUNCTION_TRACE("acpi_pci_find_irq"); ++ if (entry->link.handle) { ++ irq = acpi_pci_link_find_irq(entry->link.handle); ++ } else { ++ irq = entry->link.index; ++ } ++ ++ *link = (char *)entry; ++ ++ return_VALUE(irq); ++} ++ ++ ++ + /* + * acpi_pci_irq_lookup + * success: return IRQ >= 0 +@@ -491,6 +513,86 @@ void __attribute__ ((weak)) acpi_unregis + { + } + ++ ++ ++/* ++ * This function will be called only in the case of ++ * a "surprise" hot plug removal. For surprise removals, ++ * the card has either already be yanked out of the slot, or ++ * the slot's been powered off, so we have to brute force ++ * our way through all the possible interrupt pins to derive ++ * the GSI, then we double check with the value stored in the ++ * pci_dev structure to make sure we have the GSI that belongs ++ * to this IRQ. ++ */ ++void acpi_pci_irq_disable_nodev(struct pci_dev *dev) ++{ ++ int gsi = 0; ++ u8 pin = 0; ++ int edge_level = ACPI_LEVEL_SENSITIVE; ++ int active_high_low = ACPI_ACTIVE_LOW; ++ int irq; ++ struct acpi_prt_entry *entry; ++ ++ ACPI_FUNCTION_TRACE("acpi_pci_irq_disable_nodev"); ++ ++ /* ++ * since our device is not present, we ++ * can't just read the interrupt pin ++ * and use the value to derive the irq. ++ * in this case, we are going to check ++ * each returned irq value to make ++ * sure it matches our already assigned ++ * irq before we use it. ++ */ ++ for (pin = 0; pin < 4; pin++) { ++ /* ++ * First we check the PCI IRQ routing table (PRT) for an IRQ. ++ */ ++ gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, ++ &edge_level, &active_high_low, ++ (char **)&entry, ++ acpi_pci_find_irq); ++ ++ /* ++ * If no PRT entry was found, we'll try to derive an IRQ from the ++ * device's parent bridge. ++ */ ++ if (gsi < 0) ++ gsi = acpi_pci_irq_derive(dev, pin, ++ &edge_level, &active_high_low, ++ (char **)&entry, acpi_pci_find_irq); ++ ++ /* ++ * If we could not derive the IRQ, give up on this pin number ++ * and try a different one. ++ */ ++ if (gsi < 0) ++ continue; ++ ++ if (acpi_gsi_to_irq(gsi, &irq) < 0) ++ continue; ++ ++ /* ++ * make sure we got the right irq ++ */ ++ if (irq == dev->irq) { ++ acpi_pci_free_irq(entry, &edge_level, ++ &active_high_low, NULL); ++ printk(KERN_INFO PREFIX ++ "PCI interrupt for device %s disabled\n", ++ pci_name(dev)); ++ ++ acpi_unregister_gsi(gsi); ++ return_VOID; ++ } ++ } ++ return_VOID; ++} ++ ++ ++ ++ + void acpi_pci_irq_disable(struct pci_dev *dev) + { + int gsi = 0; +@@ -506,6 +608,14 @@ void acpi_pci_irq_disable(struct pci_dev + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (!pin) + return_VOID; ++ ++ /* ++ * Check to see if the device was present ++ */ ++ if (pin == 0xff) { ++ acpi_pci_irq_disable_nodev(dev); ++ return_VOID; ++ } + pin--; + + /* +--- gregkh-2.6.orig/drivers/acpi/pci_link.c ++++ gregkh-2.6/drivers/acpi/pci_link.c +@@ -665,6 +665,41 @@ acpi_pci_link_allocate_irq(acpi_handle h + return_VALUE(link->irq.active); + } + ++ ++ ++int acpi_pci_link_find_irq(acpi_handle handle) ++{ ++ struct acpi_device *device = NULL; ++ struct acpi_pci_link *link = NULL; ++ acpi_status result; ++ ++ ACPI_FUNCTION_TRACE("acpi_pci_link_find_irq"); ++ ++ result = acpi_bus_get_device(handle, &device); ++ if (result) { ++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n")); ++ return_VALUE(-1); ++ } ++ ++ link = (struct acpi_pci_link *)acpi_driver_data(device); ++ if (!link) { ++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); ++ return_VALUE(-1); ++ } ++ ++ down(&acpi_link_lock); ++ if (!link->irq.initialized) { ++ up(&acpi_link_lock); ++ ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link isn't initialized\n")); ++ return_VALUE(-1); ++ } ++ ++ up(&acpi_link_lock); ++ return_VALUE(link->irq.active); ++} ++ ++ ++ + /* + * We don't change link's irq information here. After it is reenabled, we + * continue use the info +--- gregkh-2.6.orig/include/acpi/acpi_drivers.h ++++ gregkh-2.6/include/acpi/acpi_drivers.h +@@ -55,6 +55,7 @@ int acpi_irq_penalty_init(void); + int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *edge_level, + int *active_high_low, char **name); + int acpi_pci_link_free_irq(acpi_handle handle); ++int acpi_pci_link_find_irq(acpi_handle handle); + + /* ACPI PCI Interrupt Routing (pci_irq.c) */ + diff --git a/pci/acpiphp-allocate-resources-for-adapters-with-bridges.patch b/pci/acpiphp-allocate-resources-for-adapters-with-bridges.patch new file mode 100644 index 0000000000000..9ceb224ea3078 --- /dev/null +++ b/pci/acpiphp-allocate-resources-for-adapters-with-bridges.patch @@ -0,0 +1,45 @@ +From kristen.c.accardi@intel.com Tue Oct 18 17:27:28 2005 +From: Kristen Accardi <kristen.c.accardi@intel.com> +Subject: acpiphp: allocate resources for adapters with bridges +To: greg@kroah.com +Date: Tue, 18 Oct 2005 17:21:40 -0700 +Message-Id: <1129681300.30588.12.camel@whizzy> + + +Allocate resources for adapters with bridges on them. + +Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/acpiphp_glue.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c ++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_glue.c +@@ -58,6 +58,9 @@ static LIST_HEAD(bridge_list); + + static void handle_hotplug_event_bridge (acpi_handle, u32, void *); + static void handle_hotplug_event_func (acpi_handle, u32, void *); ++static void acpiphp_sanitize_bus(struct pci_bus *bus); ++static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus); ++ + + /* + * initialization & terminatation routines +@@ -796,9 +799,14 @@ static int enable_device(struct acpiphp_ + } + } + ++ pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); ++ acpiphp_sanitize_bus(bus); ++ pci_enable_bridges(bus); + pci_bus_add_devices(bus); +- ++ acpiphp_set_hpp_values(DEVICE_ACPI_HANDLE(&bus->self->dev), bus); ++ acpiphp_configure_ioapics(DEVICE_ACPI_HANDLE(&bus->self->dev)); ++ + /* associate pci_dev to our representation */ + list_for_each (l, &slot->funcs) { + func = list_entry(l, struct acpiphp_func, sibling); |