diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-17 17:29:22 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-17 17:29:22 -0800 |
commit | f88df26c66503b2782e54f6d08a227313710baed (patch) | |
tree | a16409f1ed0c2352dd52d2af6f1e2c995780c0c2 /pci | |
parent | e86084aa82842642c723e5eee6cb67716cb61b43 (diff) | |
download | patches-f88df26c66503b2782e54f6d08a227313710baed.tar.gz |
4 pci patches
Diffstat (limited to 'pci')
-rw-r--r-- | pci/pci-hotplug-acpiphp-handle-dock-bridges.patch | 330 | ||||
-rw-r--r-- | pci/pci-hotplug-convert-semaphores-to-mutex.patch | 34 | ||||
-rw-r--r-- | pci/pci-quirk-for-ibm-dock-ii-cardbus-controllers.patch | 54 | ||||
-rw-r--r-- | pci/pci-really-fix-parent-s-subordinate-busnr.patch | 33 | ||||
-rw-r--r-- | pci/pci-return-max-reserved-busnr.patch | 58 |
5 files changed, 501 insertions, 8 deletions
diff --git a/pci/pci-hotplug-acpiphp-handle-dock-bridges.patch b/pci/pci-hotplug-acpiphp-handle-dock-bridges.patch new file mode 100644 index 0000000000000..6e828b9da83ec --- /dev/null +++ b/pci/pci-hotplug-acpiphp-handle-dock-bridges.patch @@ -0,0 +1,330 @@ +From kristen.c.accardi@intel.com Tue Jan 17 16:54:09 2006 +From: Kristen Accardi <kristen.c.accardi@intel.com> +Subject: PCI Hotplug: acpiphp: handle dock bridges +Cc: <len.brown@intel.com>, <pavel@ucw.cz> +Date: Tue, 17 Jan 2006 16:56:59 -0800 +Message-Id: <1137545819.19858.47.camel@whizzy> + +This patch will modify the acpiphp driver to handle docking and undocking +events and hot adding of the PCI devices on the dock station. It currently +has a workaround for a problem with acpi where the +acpi threads will deadlock and never return from executing the _DCK method. +As a workaround, I spawn a separate thread to do the dock. In addition, +I've found that some _DCK methods do some bad things, so have implemented +a fixups section for after docking that will no doubt grow as more laptops +get tested. This patch CONFLICTS with some acpi plugins that try to do +their own docking support (such as ibm_acpi), so you cannot use this driver +and the conflicting driver simultaneously. + + +Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/pci/hotplug/acpiphp.h | 2 + drivers/pci/hotplug/acpiphp_glue.c | 207 ++++++++++++++++++++++++++++++++++++- + 2 files changed, 204 insertions(+), 5 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp.h ++++ gregkh-2.6/drivers/pci/hotplug/acpiphp.h +@@ -188,6 +188,7 @@ struct acpiphp_attention_info + #define SLOT_POWEREDON (0x00000001) + #define SLOT_ENABLED (0x00000002) + #define SLOT_MULTIFUNCTION (0x00000004) ++#define SLOT_DOCKING (0x00000008) + + /* function flags */ + +@@ -197,6 +198,7 @@ struct acpiphp_attention_info + #define FUNC_HAS_PS1 (0x00000020) + #define FUNC_HAS_PS2 (0x00000040) + #define FUNC_HAS_PS3 (0x00000080) ++#define FUNC_HAS_DCK (0x00000100) + + /* function prototypes */ + +--- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp_glue.c ++++ gregkh-2.6/drivers/pci/hotplug/acpiphp_glue.c +@@ -55,12 +55,14 @@ + static LIST_HEAD(bridge_list); + + #define MY_NAME "acpiphp_glue" +- ++static struct work_struct dock_task; ++static int enable_device(struct acpiphp_slot *slot); + 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); +- ++static void dock(void *data); ++static unsigned int get_slot_status(struct acpiphp_slot *slot); + + /* + * initialization & terminatation routines +@@ -118,6 +120,30 @@ is_ejectable_slot(acpi_handle handle, u3 + } + + ++static acpi_status handle_dock(struct acpiphp_func *func, int dock) ++{ ++ acpi_status status; ++ struct acpi_object_list arg_list; ++ union acpi_object arg; ++ struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; ++ ++ dbg("%s: enter\n", __FUNCTION__); ++ ++ /* _DCK method has one argument */ ++ arg_list.count = 1; ++ arg_list.pointer = &arg; ++ arg.type = ACPI_TYPE_INTEGER; ++ arg.integer.value = dock; ++ status = acpi_evaluate_object(func->handle, "_DCK", ++ &arg_list, &buffer); ++ if (ACPI_FAILURE(status)) ++ err("%s: failed to dock!!\n", MY_NAME); ++ ++ return status; ++} ++ ++ ++ + /* callback routine to register each ACPI PCI slot object */ + static acpi_status + register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) +@@ -210,6 +236,12 @@ register_slot(acpi_handle handle, u32 lv + slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); + } + ++ /* install dock notify handler */ ++ if (ACPI_SUCCESS(acpi_get_handle(handle, "_DCK", &tmp))) { ++ newfunc->flags |= FUNC_HAS_DCK; ++ INIT_WORK(&dock_task, dock, slot); ++ } ++ + /* install notify handler */ + status = acpi_install_notify_handler(handle, + ACPI_SYSTEM_NOTIFY, +@@ -681,6 +713,88 @@ static int acpiphp_configure_ioapics(acp + return 0; + } + ++/* ++ * the _DCK method can do funny things... and sometimes not ++ * hah-hah funny. ++ */ ++static void post_dock_fixups(struct acpiphp_slot *slot, ++ struct acpiphp_func *func) ++{ ++ struct pci_bus *bus = slot->bridge->pci_bus; ++ u32 buses; ++ ++ /* fixup bad _DCK function that rewrites ++ * secondary bridge on slot ++ */ ++ pci_read_config_dword(bus->self, ++ PCI_PRIMARY_BUS, ++ &buses); ++ ++ if (((buses >> 8) & 0xff) != bus->secondary) { ++ buses = (buses & 0xff000000) ++ | ((unsigned int)(bus->primary) << 0) ++ | ((unsigned int)(bus->secondary) << 8) ++ | ((unsigned int)(bus->subordinate) << 16); ++ pci_write_config_dword(bus->self, ++ PCI_PRIMARY_BUS, ++ buses); ++ } ++} ++ ++ ++static int acpiphp_bus_add(struct acpiphp_func *func) ++{ ++ acpi_handle phandle; ++ struct acpi_device *device, *pdevice; ++ int ret_val; ++ ++ acpi_get_parent(func->handle, &phandle); ++ if (acpi_bus_get_device(phandle, &pdevice)) { ++ dbg("no parent device, assuming NULL\n"); ++ pdevice = NULL; ++ } ++ ret_val = acpi_bus_add(&device, pdevice, func->handle, ++ ACPI_BUS_TYPE_DEVICE); ++ if (ret_val) ++ dbg("cannot add bridge to acpi list\n"); ++ ++ /* ++ * try to start anyway. We could have failed to add ++ * simply because this bus had previously been added ++ * on another dock. Don't bother with the return value ++ * we just keep going. ++ */ ++ ret_val = acpi_bus_start(device); ++ ++ return ret_val; ++} ++ ++ ++ ++static void dock(void *data) ++{ ++ struct list_head *l; ++ struct acpiphp_func *func; ++ struct acpiphp_slot *slot = data; ++ ++ down(&slot->crit_sect); ++ list_for_each(l, &slot->funcs) { ++ func = list_entry(l, struct acpiphp_func, sibling); ++ if (func->flags & FUNC_HAS_DCK) { ++ handle_dock(func, 1); ++ post_dock_fixups(slot, func); ++ slot->flags |= SLOT_POWEREDON; ++ if (get_slot_status(slot) == ACPI_STA_ALL) { ++ enable_device(slot); ++ } ++ } ++ } ++ slot->flags &= (~SLOT_DOCKING); ++ up(&slot->crit_sect); ++} ++ ++ ++ + static int power_on_slot(struct acpiphp_slot *slot) + { + acpi_status status; +@@ -705,6 +819,19 @@ static int power_on_slot(struct acpiphp_ + } else + break; + } ++ ++ if (func->flags & FUNC_HAS_DCK) { ++ dbg("%s: executing _DCK\n", __FUNCTION__); ++ slot->flags |= SLOT_DOCKING; ++ /* ++ * FIXME - work around for acpi. Right ++ * now if we call _DCK from this thread, ++ * we block forever. ++ */ ++ schedule_work(&dock_task); ++ retval = -1; ++ goto err_exit; ++ } + } + + /* TBD: evaluate _STA to check if the slot is enabled */ +@@ -730,7 +857,11 @@ static int power_off_slot(struct acpiphp + + list_for_each (l, &slot->funcs) { + func = list_entry(l, struct acpiphp_func, sibling); +- ++ if (func->flags & FUNC_HAS_DCK) { ++ dbg("%s: undock commencing\n", __FUNCTION__); ++ handle_dock(func, 0); ++ dbg("%s: undock complete\n", __FUNCTION__); ++ } + if (func->flags & FUNC_HAS_PS3) { + status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); + if (ACPI_FAILURE(status)) { +@@ -752,6 +883,63 @@ static int power_off_slot(struct acpiphp + + + /** ++ * get_func - given pci_dev & slot, get the matching acpiphp_func ++ * @slot: slot to be scanned. ++ * @dev: pci_dev to match ++ * ++ * This function will check the list of acpiphp functions for ++ * this slot and return the one that represents the given ++ * pci_dev structure. ++ */ ++static struct acpiphp_func * get_func(struct acpiphp_slot *slot, ++ struct pci_dev *dev) ++{ ++ struct list_head *l; ++ struct acpiphp_func *func; ++ struct pci_bus *bus = slot->bridge->pci_bus; ++ ++ list_for_each (l, &slot->funcs) { ++ func = list_entry(l, struct acpiphp_func, sibling); ++ if (pci_get_slot(bus, PCI_DEVFN(slot->device, ++ func->function)) == dev) ++ return func; ++ } ++ return NULL; ++} ++ ++ ++ ++/** acpiphp_max_busnr - find the max reserved busnr for this bus ++ * @bus: the bus to scan ++ */ ++static unsigned char ++acpiphp_max_busnr(struct pci_bus *bus) ++{ ++ struct list_head *tmp; ++ unsigned char max, n; ++ ++ /* ++ * pci_bus_max_busnr will return the highest ++ * reserved busnr for all these children. ++ * that is equivalent to the bus->subordinate ++ * value. We don't want to use the parent's ++ * bus->subordinate value because it could have ++ * padding in it. ++ */ ++ max = bus->secondary; ++ ++ list_for_each(tmp, &bus->children) { ++ n = pci_bus_max_busnr(pci_bus_b(tmp)); ++ if (n > max) ++ max = n; ++ } ++ return max; ++} ++ ++ ++ ++ ++/** + * enable_device - enable, configure a slot + * @slot: slot to be enabled + * +@@ -788,7 +976,7 @@ static int enable_device(struct acpiphp_ + goto err_exit; + } + +- max = bus->secondary; ++ max = acpiphp_max_busnr(bus); + for (pass = 0; pass < 2; pass++) { + list_for_each_entry(dev, &bus->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != slot->device) +@@ -796,8 +984,12 @@ static int enable_device(struct acpiphp_ + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { + max = pci_scan_bridge(bus, dev, max, pass); +- if (pass && dev->subordinate) ++ if (pass && dev->subordinate) { + pci_bus_size_bridges(dev->subordinate); ++ func = get_func(slot, dev); ++ if (func) ++ acpiphp_bus_add(func); ++ } + } + } + } +@@ -1231,6 +1423,11 @@ static void handle_hotplug_event_func(ac + + case ACPI_NOTIFY_EJECT_REQUEST: + /* request device eject */ ++ if (func->slot->flags & SLOT_DOCKING) { ++ /* ignore if we are in the middle of docking */ ++ dbg("eject request in the middle of a dock\n"); ++ break; ++ } + dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); + if (!(acpiphp_disable_slot(func->slot))) + acpiphp_eject_slot(func->slot); diff --git a/pci/pci-hotplug-convert-semaphores-to-mutex.patch b/pci/pci-hotplug-convert-semaphores-to-mutex.patch index 3f00c231d51dc..a40cbb1b8fa9e 100644 --- a/pci/pci-hotplug-convert-semaphores-to-mutex.patch +++ b/pci/pci-hotplug-convert-semaphores-to-mutex.patch @@ -22,7 +22,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- drivers/pci/hotplug/acpiphp.h | 3 - - drivers/pci/hotplug/acpiphp_glue.c | 12 ++-- + drivers/pci/hotplug/acpiphp_glue.c | 16 +++--- drivers/pci/hotplug/cpqphp.h | 3 - drivers/pci/hotplug/cpqphp_core.c | 14 ++--- drivers/pci/hotplug/cpqphp_ctrl.c | 56 ++++++++++----------- @@ -34,7 +34,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/pci/hotplug/shpchp.h | 3 - drivers/pci/hotplug/shpchp_ctrl.c | 98 ++++++++++++++++++------------------- drivers/pci/hotplug/shpchp_hpc.c | 2 - 13 files changed, 143 insertions(+), 137 deletions(-) + 13 files changed, 145 insertions(+), 139 deletions(-) --- gregkh-2.6.orig/drivers/pci/hotplug/acpiphp.h +++ gregkh-2.6/drivers/pci/hotplug/acpiphp.h @@ -66,7 +66,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> #include "../pci.h" #include "pci_hotplug.h" -@@ -188,7 +188,7 @@ register_slot(acpi_handle handle, u32 lv +@@ -214,7 +214,7 @@ register_slot(acpi_handle handle, u32 lv slot->device = device; slot->sun = sun; INIT_LIST_HEAD(&slot->funcs); @@ -75,7 +75,25 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> slot->next = bridge->slots; bridge->slots = slot; -@@ -1401,7 +1401,7 @@ int acpiphp_enable_slot(struct acpiphp_s +@@ -777,7 +777,7 @@ static void dock(void *data) + struct acpiphp_func *func; + struct acpiphp_slot *slot = data; + +- down(&slot->crit_sect); ++ mutex_lock(&slot->crit_sect); + list_for_each(l, &slot->funcs) { + func = list_entry(l, struct acpiphp_func, sibling); + if (func->flags & FUNC_HAS_DCK) { +@@ -790,7 +790,7 @@ static void dock(void *data) + } + } + slot->flags &= (~SLOT_DOCKING); +- up(&slot->crit_sect); ++ mutex_unlock(&slot->crit_sect); + } + + +@@ -1598,7 +1598,7 @@ int acpiphp_enable_slot(struct acpiphp_s { int retval; @@ -84,7 +102,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> /* wake up all functions */ retval = power_on_slot(slot); -@@ -1413,7 +1413,7 @@ int acpiphp_enable_slot(struct acpiphp_s +@@ -1610,7 +1610,7 @@ int acpiphp_enable_slot(struct acpiphp_s retval = enable_device(slot); err_exit: @@ -93,7 +111,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> return retval; } -@@ -1424,7 +1424,7 @@ int acpiphp_disable_slot(struct acpiphp_ +@@ -1621,7 +1621,7 @@ int acpiphp_disable_slot(struct acpiphp_ { int retval = 0; @@ -102,7 +120,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> /* unconfigure all functions */ retval = disable_device(slot); -@@ -1437,7 +1437,7 @@ int acpiphp_disable_slot(struct acpiphp_ +@@ -1634,7 +1634,7 @@ int acpiphp_disable_slot(struct acpiphp_ goto err_exit; err_exit: @@ -1182,7 +1200,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> p_slot->is_a_board = 1; -@@ -915,27 +915,27 @@ int shpchp_disable_slot (struct slot *p_ +@@ -925,27 +925,27 @@ int shpchp_disable_slot (struct slot *p_ return -ENODEV; /* Check to see if (latch closed, card present, power on) */ diff --git a/pci/pci-quirk-for-ibm-dock-ii-cardbus-controllers.patch b/pci/pci-quirk-for-ibm-dock-ii-cardbus-controllers.patch new file mode 100644 index 0000000000000..008a53a89228e --- /dev/null +++ b/pci/pci-quirk-for-ibm-dock-ii-cardbus-controllers.patch @@ -0,0 +1,54 @@ +From kristen.c.accardi@intel.com Tue Jan 17 16:54:13 2006 +From: Kristen Accardi <kristen.c.accardi@intel.com> +Subject: PCI: quirk for IBM Dock II cardbus controllers +Cc: <len.brown@intel.com>, <pavel@ucw.cz> +Date: Tue, 17 Jan 2006 16:57:04 -0800 +Message-Id: <1137545824.19858.49.camel@whizzy> + +The IBM Dock II cardbus bridges require some extra configuration +before Yenta is loaded in order to setup the Interrupts to be +routed properly. + +Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/quirks.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- gregkh-2.6.orig/drivers/pci/quirks.c ++++ gregkh-2.6/drivers/pci/quirks.c +@@ -1239,6 +1239,33 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IN + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV, quirk_pcie_pxh); + + ++/* ++ * Fixup the cardbus bridges on the IBM Dock II docking station ++ */ ++static void __devinit quirk_ibm_dock2_cardbus(struct pci_dev *dev) ++{ ++ u32 val; ++ ++ /* ++ * tie the 2 interrupt pins to INTA, and configure the ++ * multifunction routing register to handle this. ++ */ ++ if ((dev->subsystem_vendor == PCI_VENDOR_ID_IBM) && ++ (dev->subsystem_device == 0x0148)) { ++ printk(KERN_INFO "PCI: Found IBM Dock II Cardbus Bridge " ++ "applying quirk\n"); ++ pci_read_config_dword(dev, 0x8c, &val); ++ val = ((val & 0xffffff00) | 0x1002); ++ pci_write_config_dword(dev, 0x8c, val); ++ pci_read_config_dword(dev, 0x80, &val); ++ val = ((val & 0x00ffff00) | 0x2864c077); ++ pci_write_config_dword(dev, 0x80, val); ++ } ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1420, ++ quirk_ibm_dock2_cardbus); ++ + static void __devinit quirk_netmos(struct pci_dev *dev) + { + unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4; diff --git a/pci/pci-really-fix-parent-s-subordinate-busnr.patch b/pci/pci-really-fix-parent-s-subordinate-busnr.patch new file mode 100644 index 0000000000000..58bbbb0d33129 --- /dev/null +++ b/pci/pci-really-fix-parent-s-subordinate-busnr.patch @@ -0,0 +1,33 @@ +From kristen.c.accardi@intel.com Tue Jan 17 16:54:14 2006 +From: Kristen Accardi <kristen.c.accardi@intel.com> +Subject: PCI: really fix parent's subordinate busnr +Cc: <len.brown@intel.com>, <pavel@ucw.cz> +Date: Tue, 17 Jan 2006 16:57:01 -0800 +Message-Id: <1137545822.19858.48.camel@whizzy> + +After you find the maximum value of the subordinate buses below the child +bus, you must fix the parent's subordinate bus number again, otherwise +it may be too small. + +Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/pci/probe.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- gregkh-2.6.orig/drivers/pci/probe.c ++++ gregkh-2.6/drivers/pci/probe.c +@@ -537,6 +537,11 @@ int __devinit pci_scan_bridge(struct pci + pci_fixup_parent_subordinate_busnr(child, max); + /* Now we can scan all subordinate buses... */ + max = pci_scan_child_bus(child); ++ /* ++ * now fix it up again since we have found ++ * the real value of max. ++ */ ++ pci_fixup_parent_subordinate_busnr(child, max); + } else { + /* + * For CardBus bridges, we leave 4 bus numbers diff --git a/pci/pci-return-max-reserved-busnr.patch b/pci/pci-return-max-reserved-busnr.patch new file mode 100644 index 0000000000000..074134e4737c9 --- /dev/null +++ b/pci/pci-return-max-reserved-busnr.patch @@ -0,0 +1,58 @@ +From kristen.c.accardi@intel.com Tue Jan 17 16:54:10 2006 +From: Kristen Accardi <kristen.c.accardi@intel.com> +Subject: PCI: return max reserved busnr +Cc: <len.brown@intel.com>, <pavel@ucw.cz> +Date: Tue, 17 Jan 2006 16:56:56 -0800 +Message-Id: <1137545816.19858.46.camel@whizzy> + +Change the semantics of this call to return the max reserved +bus number instead of just the max assigned bus number. + +Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/pci/pci.c | 5 +++-- + include/linux/pci.h | 1 + + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/pci.c ++++ gregkh-2.6/drivers/pci/pci.c +@@ -19,7 +19,6 @@ + #include <asm/dma.h> /* isa_dma_bridge_buggy */ + #include "pci.h" + +-#if 0 + + /** + * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children +@@ -34,7 +33,7 @@ pci_bus_max_busnr(struct pci_bus* bus) + struct list_head *tmp; + unsigned char max, n; + +- max = bus->number; ++ max = bus->subordinate; + list_for_each(tmp, &bus->children) { + n = pci_bus_max_busnr(pci_bus_b(tmp)); + if(n > max) +@@ -42,7 +41,9 @@ pci_bus_max_busnr(struct pci_bus* bus) + } + return max; + } ++EXPORT_SYMBOL_GPL(pci_bus_max_busnr); + ++#if 0 + /** + * pci_max_busnr - returns maximum PCI bus number + * +--- gregkh-2.6.orig/include/linux/pci.h ++++ gregkh-2.6/include/linux/pci.h +@@ -516,6 +516,7 @@ int pci_scan_bridge(struct pci_bus *bus, + void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), + void *userdata); + int pci_cfg_space_size(struct pci_dev *dev); ++unsigned char pci_bus_max_busnr(struct pci_bus* bus); + + /* kmem_cache style wrapper around pci_alloc_consistent() */ + |