Some basic changes to allocation bus range, MMIO resource for SR-IOV device. And add new sysfs entry to hotplug core to pass parameter to a slot, which will be used by SR-IOV code. Signed-off-by: Yu Zhao <yu.zhao@xxxxxxxxx> Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> --- drivers/pci/bus.c | 63 +++++++++++++------------- drivers/pci/hotplug/pci_hotplug_core.c | 75 +++++++++++++++++++++++++++++--- drivers/pci/pci-sysfs.c | 4 +- drivers/pci/pci.c | 68 +++++++++++++++++++++-------- drivers/pci/pci.h | 3 + drivers/pci/probe.c | 37 ++++++++------- drivers/pci/proc.c | 7 ++- drivers/pci/remove.c | 3 +- drivers/pci/setup-bus.c | 9 ++-- drivers/pci/setup-res.c | 29 ++++++------ include/linux/pci.h | 53 ++++++++++++++++------- include/linux/pci_hotplug.h | 11 ++++- 12 files changed, 246 insertions(+), 116 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 529d9d7..15f64c9 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -105,7 +105,7 @@ int pci_bus_add_device(struct pci_dev *dev) void pci_bus_add_devices(struct pci_bus *bus) { struct pci_dev *dev; - struct pci_bus *child_bus; + struct pci_bus *child; int retval; list_for_each_entry(dev, &bus->devices, bus_list) { @@ -115,43 +115,42 @@ void pci_bus_add_devices(struct pci_bus *bus) retval = pci_bus_add_device(dev); if (retval) dev_err(&dev->dev, "Error adding device, continuing\n"); - } - - list_for_each_entry(dev, &bus->devices, bus_list) { - BUG_ON(!dev->is_added); /* * If there is an unattached subordinate bus, attach * it and then scan for unattached PCI devices. */ - if (dev->subordinate) { - if (list_empty(&dev->subordinate->node)) { - down_write(&pci_bus_sem); - list_add_tail(&dev->subordinate->node, - &dev->bus->children); - up_write(&pci_bus_sem); - } - pci_bus_add_devices(dev->subordinate); - - /* register the bus with sysfs as the parent is now - * properly registered. */ - child_bus = dev->subordinate; - if (child_bus->is_added) - continue; - child_bus->dev.parent = child_bus->bridge; - retval = device_register(&child_bus->dev); - if (retval) - dev_err(&dev->dev, "Error registering pci_bus," - " continuing...\n"); - else { - child_bus->is_added = 1; - retval = device_create_file(&child_bus->dev, - &dev_attr_cpuaffinity); - } - if (retval) - dev_err(&dev->dev, "Error creating cpuaffinity" - " file, continuing...\n"); + if (!dev->subordinate) + continue; + + if (list_empty(&dev->subordinate->node)) { + down_write(&pci_bus_sem); + list_add_tail(&dev->subordinate->node, + &dev->bus->children); + up_write(&pci_bus_sem); } + pci_bus_add_devices(dev->subordinate); + } + + list_for_each_entry(child, &bus->children, node) { + /* register the bus with sysfs as the parent is now + * properly registered. */ + if (child->is_added) + continue; + if (child->bridge) + child->dev.parent = child->bridge; + retval = device_register(&child->dev); + if (retval) { + dev_err(&dev->dev, "Error registering pci_bus," + " continuing...\n"); + continue; + } + child->is_added = 1; + retval = device_create_file(&child->dev, + &dev_attr_cpuaffinity); + if (retval) + dev_err(&dev->dev, "Error creating cpuaffinity" + " file, continuing...\n"); } } diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 5f85b1b..96f99c7 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -102,13 +102,13 @@ static int get_##name (struct hotplug_slot *slot, type *value) \ { \ struct hotplug_slot_ops *ops = slot->ops; \ int retval = 0; \ - if (try_module_get(ops->owner)) { \ - if (ops->get_##name) \ - retval = ops->get_##name(slot, value); \ - else \ - *value = slot->info->name; \ - module_put(ops->owner); \ - } \ + if (!try_module_get(ops->owner)) \ + return -ENODEV; \ + if (ops->get_##name) \ + retval = ops->get_##name(slot, value); \ + else \ + *value = slot->info->name; \ + module_put(ops->owner); \ return retval; \ } @@ -118,6 +118,7 @@ GET_STATUS(latch_status, u8) GET_STATUS(adapter_status, u8) GET_STATUS(max_bus_speed, enum pci_bus_speed) GET_STATUS(cur_bus_speed, enum pci_bus_speed) +GET_STATUS(param, const char *) static ssize_t power_read_file(struct pci_slot *slot, char *buf) { @@ -346,6 +347,41 @@ static struct pci_slot_attribute hotplug_slot_attr_test = { .store = test_write_file }; +static ssize_t param_read_file(struct pci_slot *slot, char *buf) +{ + int retval; + const char *param; + + retval = get_param(slot->hotplug, ¶m); + if (retval) + return retval; + + return param ? snprintf(buf, PAGE_SIZE, "%s\n", param) : -EPERM; +} + +static ssize_t param_write_file(struct pci_slot *slot, const char *buf, + size_t count) +{ + int retval = -EPERM; + struct hotplug_slot_ops *ops = slot->hotplug->ops; + + if (!try_module_get(ops->owner)) + return -ENODEV; + + if (ops->set_param) + retval = ops->set_param(slot->hotplug, buf, count); + + module_put(ops->owner); + + return retval ? retval : count; +} + +static struct pci_slot_attribute hotplug_slot_attr_param = { + .attr = {.name = "param", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .show = param_read_file, + .store = param_write_file +}; + static int has_power_file(struct pci_slot *pci_slot) { struct hotplug_slot *slot = pci_slot->hotplug; @@ -419,6 +455,17 @@ static int has_test_file(struct pci_slot *pci_slot) return -ENOENT; } +static int has_param_file(struct pci_slot *pci_slot) +{ + struct hotplug_slot *slot = pci_slot->hotplug; + if ((!slot) || (!slot->ops)) + return -ENODEV; + if ((slot->ops->set_param) || + (slot->ops->get_param)) + return 0; + return -ENOENT; +} + static int fs_add_slot(struct pci_slot *slot) { int retval = 0; @@ -471,8 +518,19 @@ static int fs_add_slot(struct pci_slot *slot) goto exit_test; } + if (has_param_file(slot) == 0) { + retval = sysfs_create_file(&slot->kobj, + &hotplug_slot_attr_param.attr); + if (retval) + goto exit_param; + } + goto exit; +exit_param: + if (has_param_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_param.attr); + exit_test: if (has_cur_bus_speed_file(slot) == 0) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); @@ -523,6 +581,9 @@ static void fs_remove_slot(struct pci_slot *slot) if (has_test_file(slot) == 0) sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); + + if (has_param_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_param.attr); } static struct hotplug_slot *get_slot_from_name (const char *name) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9c71858..f466937 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -100,11 +100,13 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) struct pci_dev * pci_dev = to_pci_dev(dev); char * str = buf; int i; - int max = 7; + int max; resource_size_t start, end; if (pci_dev->subordinate) max = DEVICE_COUNT_RESOURCE; + else + max = PCI_BRIDGE_RESOURCES; for (i = 0; i < max; i++) { struct resource *res = &pci_dev->resource[i]; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c9884bb..c1108ed 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -356,25 +356,10 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) static void pci_restore_bars(struct pci_dev *dev) { - int i, numres; - - switch (dev->hdr_type) { - case PCI_HEADER_TYPE_NORMAL: - numres = 6; - break; - case PCI_HEADER_TYPE_BRIDGE: - numres = 2; - break; - case PCI_HEADER_TYPE_CARDBUS: - numres = 1; - break; - default: - /* Should never get here, but just in case... */ - return; - } + int i; - for (i = 0; i < numres; i ++) - pci_update_resource(dev, &dev->resource[i], i); + for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) + pci_update_resource(dev, i); } static struct pci_platform_pm_ops *pci_platform_pm; @@ -1864,6 +1849,53 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags) return bars; } +/** + * pci_resource_alignment - get a PCI BAR resource alignment + * @dev: the PCI device + * @resno: the resource number + * + * Returns alignment size on success, or 0 on error. + */ +int pci_resource_alignment(struct pci_dev *dev, int resno) +{ + resource_size_t align; + struct resource *res = dev->resource + resno; + + align = resource_alignment(res); + if (align) + return align; + + if (resno <= PCI_ROM_RESOURCE) + return resource_size(res); + else if (resno <= PCI_BRIDGE_RES_END) + return res->start; + + dev_err(&dev->dev, "alignment: invalid resource #: %d\n", resno); + return 0; +} + +/** + * pci_resource_bar - get position of the BAR associated with a resource + * @dev: the PCI device + * @resno: the resource number + * @type: the BAR type to be filled in + * + * Returns BAR position in config space, or 0 if the BAR is invalid. + */ +int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) +{ + if (resno < PCI_ROM_RESOURCE) { + *type = pci_bar_unknown; + return PCI_BASE_ADDRESS_0 + 4 * resno; + } else if (resno == PCI_ROM_RESOURCE) { + *type = pci_bar_rom; + return dev->rom_base_reg; + } + + dev_err(&dev->dev, "BAR: invalid resource #: %d\n", resno); + return 0; +} + static void __devinit pci_no_domains(void) { #ifdef CONFIG_PCI_DOMAINS diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d807cd7..5abd69c 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -144,3 +144,6 @@ struct pci_slot_attribute { }; #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) +extern int pci_resource_alignment(struct pci_dev *dev, int resno); +extern int pci_resource_bar(struct pci_dev *dev, int resno, + enum pci_bar_type *type); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index cce2f4c..3994ea3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -203,13 +203,6 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask) return size; } -enum pci_bar_type { - pci_bar_unknown, /* Standard PCI BAR probe */ - pci_bar_io, /* An io port BAR */ - pci_bar_mem32, /* A 32-bit memory BAR */ - pci_bar_mem64, /* A 64-bit memory BAR */ -}; - static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) { if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { @@ -224,16 +217,21 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) return pci_bar_mem32; } -/* - * If the type is not unknown, we assume that the lowest bit is 'enable'. - * Returns 1 if the BAR was 64-bit and 0 if it was 32-bit. +/** + * pci_read_base - read a PCI BAR + * @dev: the PCI device + * @type: type of the BAR + * @res: resource buffer to be filled in + * @pos: BAR position in the config space + * + * Returns 1 if the BAR is 64-bit, or 0 if 32-bit. */ -static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, +int pci_read_base(struct pci_dev *dev, enum pci_bar_type type, struct resource *res, unsigned int pos) { u32 l, sz, mask; - mask = type ? ~PCI_ROM_ADDRESS_ENABLE : ~0; + mask = (type == pci_bar_rom) ? ~PCI_ROM_ADDRESS_ENABLE : ~0; res->name = pci_name(dev); @@ -258,7 +256,7 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, if (l == 0xffffffff) l = 0; - if (type == pci_bar_unknown) { + if (type != pci_bar_rom) { type = decode_bar(res, l); res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN; if (type == pci_bar_io) { @@ -321,6 +319,7 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->flags = 0; goto out; } +EXPORT_SYMBOL_GPL(pci_read_base); static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) { @@ -329,7 +328,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) for (pos = 0; pos < howmany; pos++) { struct resource *res = &dev->resource[pos]; reg = PCI_BASE_ADDRESS_0 + (pos << 2); - pos += __pci_read_base(dev, pci_bar_unknown, res, reg); + pos += pci_read_base(dev, pci_bar_unknown, res, reg); } if (rom) { @@ -338,7 +337,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_READONLY | IORESOURCE_CACHEABLE | IORESOURCE_SIZEALIGN; - __pci_read_base(dev, pci_bar_mem32, res, rom); + pci_read_base(dev, pci_bar_rom, res, rom); } } @@ -462,12 +461,10 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, if (!child) return NULL; - child->self = bridge; child->parent = parent; child->ops = parent->ops; child->sysdata = parent->sysdata; child->bus_flags = parent->bus_flags; - child->bridge = get_device(&bridge->dev); /* initialize some portions of the bus device, but don't register it * now as the parent is not properly set up yet. This device will get @@ -484,6 +481,11 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, child->primary = parent->secondary; child->subordinate = 0xff; + if (!bridge) + goto done; + + child->self = bridge; + child->bridge = get_device(&bridge->dev); /* Set up default resource pointers and names.. */ for (i = 0; i < 4; i++) { child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; @@ -491,6 +493,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, } bridge->subordinate = child; +done: return child; } diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index e1098c3..f6f2a59 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -352,15 +352,16 @@ static int show_device(struct seq_file *m, void *v) dev->vendor, dev->device, dev->irq); - /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ - for (i=0; i<7; i++) { + + /* only print standard and ROM resources to preserve compatibility */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { resource_size_t start, end; pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); seq_printf(m, "\t%16llx", (unsigned long long)(start | (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); } - for (i=0; i<7; i++) { + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { resource_size_t start, end; pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); seq_printf(m, "\t%16llx", diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index bdc2a44..3501068 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -73,7 +73,8 @@ void pci_remove_bus(struct pci_bus *pci_bus) up_write(&pci_bus_sem); pci_remove_legacy_files(pci_bus); device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity); - device_unregister(&pci_bus->dev); + if (pci_bus->is_added) + device_unregister(&pci_bus->dev); } EXPORT_SYMBOL(pci_remove_bus); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 82634a2..78f2f16 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -26,6 +26,8 @@ #include <linux/cache.h> #include <linux/slab.h> +#include "pci.h" + static void pbus_assign_resources_sorted(struct pci_bus *bus) { @@ -299,7 +301,7 @@ static void pbus_size_io(struct pci_bus *bus) if (r->parent || !(r->flags & IORESOURCE_IO)) continue; - r_size = r->end - r->start + 1; + r_size = resource_size(r); if (r_size < 0x400) /* Might be re-aligned for ISA */ @@ -350,9 +352,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long if (r->parent || (r->flags & mask) != type) continue; - r_size = r->end - r->start + 1; - /* For bridges size != alignment */ - align = (i < PCI_BRIDGE_RESOURCES) ? r_size : r->start; + r_size = resource_size(r); + align = pci_resource_alignment(dev, i); order = __ffs(align) - 20; if (order > 11) { dev_warn(&dev->dev, "BAR %d too large: " diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 1a5fc83..b6bb1ad 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -26,11 +26,13 @@ #include "pci.h" -void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) +void pci_update_resource(struct pci_dev *dev, int resno) { struct pci_bus_region region; u32 new, check, mask; int reg; + enum pci_bar_type type; + struct resource *res = dev->resource + resno; /* * Ignore resources for unimplemented BARs and unused resource slots @@ -63,17 +65,13 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) else mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; - if (resno < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resno; - } else if (resno == PCI_ROM_RESOURCE) { + reg = pci_resource_bar(dev, resno, &type); + if (!reg) + return; + if (type == pci_bar_rom) { if (!(res->flags & IORESOURCE_ROM_ENABLE)) return; new |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Hmm, non-standard resource. */ - - return; /* kill uninitialised var warning */ } pci_write_config_dword(dev, reg, new); @@ -133,10 +131,10 @@ int pci_assign_resource(struct pci_dev *dev, int resno) resource_size_t size, min, align; int ret; - size = res->end - res->start + 1; + size = resource_size(res); min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; - align = resource_alignment(res); + align = pci_resource_alignment(dev, resno); if (!align) { dev_err(&dev->dev, "BAR %d: can't allocate resource (bogus " "alignment) [%#llx-%#llx] flags %#lx\n", @@ -170,7 +168,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) } else { res->flags &= ~IORESOURCE_STARTALIGN; if (resno < PCI_BRIDGE_RESOURCES) - pci_update_resource(dev, res, resno); + pci_update_resource(dev, resno); } return ret; @@ -208,7 +206,7 @@ int pci_assign_resource_fixed(struct pci_dev *dev, int resno) (unsigned long long)res->start, (unsigned long long)res->end); } else if (resno < PCI_BRIDGE_RESOURCES) { - pci_update_resource(dev, res, resno); + pci_update_resource(dev, resno); } return ret; @@ -234,7 +232,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) if (!(r->flags) || r->parent) continue; - r_align = resource_alignment(r); + r_align = pci_resource_alignment(dev, i); if (!r_align) { dev_warn(&dev->dev, "BAR %d: bogus alignment " "[%#llx-%#llx] flags %#lx\n", @@ -247,7 +245,8 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) struct resource_list *ln = list->next; if (ln) - align = resource_alignment(ln->res); + align = pci_resource_alignment(ln->dev, + ln->res - ln->dev->resource); if (r_align > align) { tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); diff --git a/include/linux/pci.h b/include/linux/pci.h index c0e1400..687be00 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -76,7 +76,29 @@ enum pci_mmap_state { #define PCI_DMA_FROMDEVICE 2 #define PCI_DMA_NONE 3 -#define DEVICE_COUNT_RESOURCE 12 +/* + * For PCI devices, the region numbers are assigned this way: + */ +enum { + /* 0-5 standard PCI regions */ + PCI_STD_RESOURCE, + + /* expansion ROM */ + PCI_ROM_RESOURCE = 6, + + /* address space assigned to buses behind the bridge */ +#ifndef PCI_BRIDGE_NUM_RES +#define PCI_BRIDGE_NUM_RES 4 +#endif + PCI_BRIDGE_RESOURCES, + PCI_BRIDGE_RES_END = PCI_BRIDGE_RESOURCES + PCI_BRIDGE_NUM_RES - 1, + + /* total resources associated with a PCI device */ + PCI_NUM_RESOURCES, + + /* preserve this for compatibility */ + DEVICE_COUNT_RESOURCE +}; typedef int __bitwise pci_power_t; @@ -261,18 +283,6 @@ static inline void pci_add_saved_cap(struct pci_dev *pci_dev, hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); } -/* - * For PCI devices, the region numbers are assigned this way: - * - * 0-5 standard PCI regions - * 6 expansion ROM - * 7-10 bridges: address space assigned to buses behind the bridge - */ - -#define PCI_ROM_RESOURCE 6 -#define PCI_BRIDGE_RESOURCES 7 -#define PCI_NUM_RESOURCES 11 - #ifndef PCI_BUS_NUM_RESOURCES #define PCI_BUS_NUM_RESOURCES 16 #endif @@ -312,6 +322,17 @@ struct pci_bus { #define pci_bus_b(n) list_entry(n, struct pci_bus, node) #define to_pci_bus(n) container_of(n, struct pci_bus, dev) +enum pci_bar_type { + pci_bar_unknown, /* Standard PCI BAR probe */ + pci_bar_io, /* An io port BAR */ + pci_bar_mem32, /* A 32-bit memory BAR */ + pci_bar_mem64, /* A 64-bit memory BAR */ + pci_bar_rom, /* A ROM BAR */ +}; + +extern int pci_read_base(struct pci_dev *dev, enum pci_bar_type type, + struct resource *res, unsigned int reg); + /* * Error values that may be returned by PCI functions. */ @@ -456,8 +477,8 @@ struct pci_driver { /** * PCI_VDEVICE - macro used to describe a specific pci device in short form - * @vend: the vendor name - * @dev: the 16 bit PCI Device ID + * @vendor: the vendor name + * @device: the 16 bit PCI Device ID * * This macro is used to create a struct pci_device_id that matches a * specific PCI device. The subvendor, and subdevice fields will be set @@ -626,7 +647,7 @@ int pcix_get_mmrbc(struct pci_dev *dev); int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); int pcie_get_readrq(struct pci_dev *dev); int pcie_set_readrq(struct pci_dev *dev, int rq); -void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); +void pci_update_resource(struct pci_dev *dev, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); int pci_select_bars(struct pci_dev *dev, unsigned long flags); diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index a08cd06..5266d0f 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -117,8 +117,14 @@ struct hotplug_slot_ops { int (*get_attention_status) (struct hotplug_slot *slot, u8 *value); int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); - int (*get_max_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); - int (*get_cur_bus_speed) (struct hotplug_slot *slot, enum pci_bus_speed *value); + int (*get_max_bus_speed) (struct hotplug_slot *slot, + enum pci_bus_speed *value); + int (*get_cur_bus_speed) (struct hotplug_slot *slot, + enum pci_bus_speed *value); + int (*set_param) (struct hotplug_slot *slot, + const char *param, int len); + int (*get_param) (struct hotplug_slot *slot, + const char **param); }; /** @@ -138,6 +144,7 @@ struct hotplug_slot_info { u8 adapter_status; enum pci_bus_speed max_bus_speed; enum pci_bus_speed cur_bus_speed; + char *param; }; /** -- 1.5.6.4 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html