aboutsummaryrefslogtreecommitdiffstats
path: root/pci
diff options
context:
space:
mode:
authorGreg KH <greg@press.(none)>2005-10-18 19:23:54 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-18 19:23:54 -0700
commite1066393df50f590b1eb5c97b95cc767cda9e51f (patch)
tree7c58a5977bbe06cbdb2f998da9158136fdcf2ff2 /pci
parent4c6041c8a1daba108640353acad7812c10769dcc (diff)
downloadpatches-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.patch211
-rw-r--r--pci/acpiphp-allocate-resources-for-adapters-with-bridges.patch45
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);