diff options
author | Greg KH <greg@press.kroah.org> | 2005-11-04 22:48:08 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-11-04 22:48:08 -0800 |
commit | c2d12c30d5b4a646b73b9213e286b2d9419d5663 (patch) | |
tree | c80cf7762d0c96ec4ae646c1f7edf2e8891beb2e /pci | |
parent | 27471708b65d260df504c9cb2249ab7a31ecc241 (diff) | |
download | patches-c2d12c30d5b4a646b73b9213e286b2d9419d5663.tar.gz |
usb and pci patches added
Diffstat (limited to 'pci')
-rw-r--r-- | pci/dlpar-regression-for-ppc64-probe-change.patch | 304 |
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); |