aboutsummaryrefslogtreecommitdiffstats
path: root/pci
diff options
context:
space:
mode:
authorGreg KH <greg@press.kroah.org>2005-11-04 22:48:08 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2005-11-04 22:48:08 -0800
commitc2d12c30d5b4a646b73b9213e286b2d9419d5663 (patch)
treec80cf7762d0c96ec4ae646c1f7edf2e8891beb2e /pci
parent27471708b65d260df504c9cb2249ab7a31ecc241 (diff)
downloadpatches-c2d12c30d5b4a646b73b9213e286b2d9419d5663.tar.gz
usb and pci patches added
Diffstat (limited to 'pci')
-rw-r--r--pci/dlpar-regression-for-ppc64-probe-change.patch304
1 files changed, 304 insertions, 0 deletions
diff --git a/pci/dlpar-regression-for-ppc64-probe-change.patch b/pci/dlpar-regression-for-ppc64-probe-change.patch
new file mode 100644
index 0000000000000..c1e33b9fd5e5c
--- /dev/null
+++ b/pci/dlpar-regression-for-ppc64-probe-change.patch
@@ -0,0 +1,304 @@
+From johnrose@austin.ibm.com Fri Nov 4 13:54:51 2005
+Subject: [PATCH] dlpar regression for ppc64 - probe change
+From: John Rose <johnrose@austin.ibm.com>
+To: Greg KH <greg@kroah.com>
+Cc: Linas Vepstas <linas@austin.ibm.com>, Raymond Harney <harney@us.ibm.com>
+Message-Id: <1131140329.9574.58.camel@sinatra.austin.ibm.com>
+Date: Fri, 04 Nov 2005 15:38:50 -0600
+
+This patch contains the driver bits for enabling DLPAR and PCI Hotplug
+for the new OF-based PCI probe. This functionality was regressed when
+the new PCI approach was introduced. Please apply if appropriate.
+
+Signed-off-by: John Rose <johnrose@austin.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/rpadlpar_core.c | 79 ++++++++++--------------------------
+ drivers/pci/hotplug/rpaphp.h | 2
+ drivers/pci/hotplug/rpaphp_pci.c | 76 +++++++++++++++++++++++++---------
+ 3 files changed, 81 insertions(+), 76 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/rpadlpar_core.c
++++ gregkh-2.6/drivers/pci/hotplug/rpadlpar_core.c
+@@ -134,43 +134,6 @@ static void rpadlpar_claim_one_bus(struc
+ rpadlpar_claim_one_bus(child_bus);
+ }
+
+-static int pci_add_secondary_bus(struct device_node *dn,
+- struct pci_dev *bridge_dev)
+-{
+- struct pci_dn *pdn = dn->data;
+- struct pci_controller *hose = pdn->phb;
+- struct pci_bus *child;
+- u8 sec_busno;
+-
+- /* Get busno of downstream bus */
+- pci_read_config_byte(bridge_dev, PCI_SECONDARY_BUS, &sec_busno);
+-
+- /* Allocate and add to children of bridge_dev->bus */
+- child = pci_add_new_bus(bridge_dev->bus, bridge_dev, sec_busno);
+- if (!child) {
+- printk(KERN_ERR "%s: could not add secondary bus\n", __FUNCTION__);
+- return -ENOMEM;
+- }
+-
+- sprintf(child->name, "PCI Bus #%02x", child->number);
+-
+- /* Fixup subordinate bridge bases and resources */
+- pcibios_fixup_bus(child);
+-
+- /* Claim new bus resources */
+- rpadlpar_claim_one_bus(bridge_dev->bus);
+-
+- if (hose->last_busno < child->number)
+- hose->last_busno = child->number;
+-
+- pdn->bussubno = child->number;
+-
+- /* ioremap() for child bus, which may or may not succeed */
+- remap_bus_range(child);
+-
+- return 0;
+-}
+-
+ static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
+ struct device_node *dev_dn)
+ {
+@@ -188,29 +151,41 @@ static struct pci_dev *dlpar_find_new_de
+ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
+ {
+ struct pci_dn *pdn = dn->data;
+- struct pci_controller *hose = pdn->phb;
++ struct pci_controller *phb = pdn->phb;
+ struct pci_dev *dev = NULL;
+
+- /* Scan phb bus for EADS device, adding new one to bus->devices */
+- if (!pci_scan_single_device(hose->bus, pdn->devfn)) {
+- printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__);
++ rpaphp_eeh_init_nodes(dn);
++ /* Add EADS device to PHB bus, adding new entry to bus->devices */
++ dev = of_create_pci_dev(dn, phb->bus, pdn->devfn);
++ if (!dev) {
++ printk(KERN_ERR "%s: failed to create pci dev for %s\n",
++ __FUNCTION__, dn->full_name);
+ return NULL;
+ }
+
++ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
++ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
++ of_scan_pci_bridge(dn, dev);
++
++ rpaphp_init_new_devs(dev->subordinate);
++
++ /* Claim new bus resources */
++ rpadlpar_claim_one_bus(dev->bus);
++
++ /* ioremap() for child bus, which may or may not succeed */
++ (void) remap_bus_range(dev->bus);
++
+ /* Add new devices to global lists. Register in proc, sysfs. */
+- pci_bus_add_devices(hose->bus);
++ pci_bus_add_devices(phb->bus);
+
+ /* Confirm new bridge dev was created */
+- dev = dlpar_find_new_dev(hose->bus, dn);
++ dev = dlpar_find_new_dev(phb->bus, dn);
+ if (dev) {
+ if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
+ printk(KERN_ERR "%s: unexpected header type %d\n",
+ __FUNCTION__, dev->hdr_type);
+ return NULL;
+ }
+-
+- if (pci_add_secondary_bus(dn, dev))
+- return NULL;
+ }
+
+ return dev;
+@@ -219,7 +194,6 @@ static struct pci_dev *dlpar_pci_add_bus
+ static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
+ {
+ struct pci_dev *dev;
+- int rc;
+
+ if (rpaphp_find_pci_bus(dn))
+ return -EINVAL;
+@@ -232,15 +206,6 @@ static int dlpar_add_pci_slot(char *drc_
+ return -EIO;
+ }
+
+- if (dn->child) {
+- rc = rpaphp_config_pci_adapter(dev->subordinate);
+- if (rc < 0) {
+- printk(KERN_ERR "%s: unable to enable slot %s\n",
+- __FUNCTION__, drc_name);
+- return -EIO;
+- }
+- }
+-
+ /* Add hotplug slot */
+ if (rpaphp_add_slot(dn)) {
+ printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
+@@ -435,6 +400,8 @@ int dlpar_remove_pci_slot(char *drc_name
+ __FUNCTION__, drc_name);
+ return -EIO;
+ }
++ } else {
++ rpaphp_unconfig_pci_adapter(bus);
+ }
+
+ if (unmap_bus_range(bus)) {
+--- gregkh-2.6.orig/drivers/pci/hotplug/rpaphp_pci.c
++++ gregkh-2.6/drivers/pci/hotplug/rpaphp_pci.c
+@@ -154,8 +154,7 @@ exit:
+ }
+
+ /* Must be called before pci_bus_add_devices */
+-static void
+-rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
++void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
+ {
+ struct pci_dev *dev;
+
+@@ -184,6 +183,20 @@ rpaphp_fixup_new_pci_devices(struct pci_
+ }
+ }
+
++static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
++{
++ struct pci_dev *dev;
++
++ list_for_each_entry(dev, &bus->devices, bus_list) {
++ eeh_add_device_late(dev);
++ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
++ struct pci_bus *subbus = dev->subordinate;
++ if (subbus)
++ rpaphp_eeh_add_bus_device (subbus);
++ }
++ }
++}
++
+ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
+ {
+ u8 sec_busno;
+@@ -217,6 +230,13 @@ static int rpaphp_pci_config_bridge(stru
+ return 0;
+ }
+
++void rpaphp_init_new_devs(struct pci_bus *bus)
++{
++ rpaphp_fixup_new_pci_devices(bus, 0);
++ rpaphp_eeh_add_bus_device(bus);
++}
++EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
++
+ /*****************************************************************************
+ rpaphp_pci_config_slot() will configure all devices under the
+ given slot->dn and return the the first pci_dev.
+@@ -233,36 +253,51 @@ rpaphp_pci_config_slot(struct pci_bus *b
+ if (!dn || !dn->child)
+ return NULL;
+
+- slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
++ if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
++ of_scan_bus(dn, bus);
++ if (list_empty(&bus->devices)) {
++ err("%s: No new device found\n", __FUNCTION__);
++ return NULL;
++ }
+
+- /* pci_scan_slot should find all children */
+- num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
+- if (num) {
+- rpaphp_fixup_new_pci_devices(bus, 1);
++ rpaphp_init_new_devs(bus);
+ pci_bus_add_devices(bus);
+- }
+- if (list_empty(&bus->devices)) {
+- err("%s: No new device found\n", __FUNCTION__);
+- return NULL;
+- }
+- list_for_each_entry(dev, &bus->devices, bus_list) {
+- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+- rpaphp_pci_config_bridge(dev);
++ dev = list_entry(&bus->devices, struct pci_dev, bus_list);
++ } else {
++ slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
++
++ /* pci_scan_slot should find all children */
++ num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
++ if (num) {
++ rpaphp_fixup_new_pci_devices(bus, 1);
++ pci_bus_add_devices(bus);
++ }
++ if (list_empty(&bus->devices)) {
++ err("%s: No new device found\n", __FUNCTION__);
++ return NULL;
++ }
++ list_for_each_entry(dev, &bus->devices, bus_list) {
++ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
++ rpaphp_pci_config_bridge(dev);
++
++ rpaphp_eeh_add_bus_device(bus);
++ }
+ }
+
+ return dev;
+ }
+
+-static void enable_eeh(struct device_node *dn)
++void rpaphp_eeh_init_nodes(struct device_node *dn)
+ {
+ struct device_node *sib;
+
+ for (sib = dn->child; sib; sib = sib->sibling)
+- enable_eeh(sib);
++ rpaphp_eeh_init_nodes(sib);
+ eeh_add_device_early(dn);
+ return;
+
+ }
++EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes);
+
+ static void print_slot_pci_funcs(struct pci_bus *bus)
+ {
+@@ -289,7 +324,7 @@ int rpaphp_config_pci_adapter(struct pci
+ if (!dn)
+ goto exit;
+
+- enable_eeh(dn);
++ rpaphp_eeh_init_nodes(dn);
+ dev = rpaphp_pci_config_slot(bus);
+ if (!dev) {
+ err("%s: can't find any devices.\n", __FUNCTION__);
+@@ -331,6 +366,7 @@ int rpaphp_unconfig_pci_adapter(struct p
+ }
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
+
+ static int setup_pci_hotplug_slot_info(struct slot *slot)
+ {
+@@ -444,8 +480,8 @@ int rpaphp_enable_pci_slot(struct slot *
+ retval = rpaphp_config_pci_adapter(slot->bus);
+ if (!retval) {
+ slot->state = CONFIGURED;
+- dbg("%s: PCI devices in slot[%s] has been configured\n",
+- __FUNCTION__, slot->name);
++ info("%s: devices in slot[%s] configured\n",
++ __FUNCTION__, slot->name);
+ } else {
+ slot->state = NOT_CONFIGURED;
+ dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
+--- gregkh-2.6.orig/drivers/pci/hotplug/rpaphp.h
++++ gregkh-2.6/drivers/pci/hotplug/rpaphp.h
+@@ -93,6 +93,8 @@ extern int rpaphp_claim_resource(struct
+ extern int rpaphp_enable_pci_slot(struct slot *slot);
+ extern int register_pci_slot(struct slot *slot);
+ extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
++extern void rpaphp_init_new_devs(struct pci_bus *bus);
++extern void rpaphp_eeh_init_nodes(struct device_node *dn);
+
+ extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
+ extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus);