Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6

This commit is contained in:
Linus Torvalds 2005-07-05 11:35:58 -07:00
commit 346fced899
20 changed files with 205 additions and 166 deletions

View File

@ -190,7 +190,7 @@ static __init struct pci_dev *gx_detect_chipset(void)
/* detect which companion chip is used */
while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) {
if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) {
if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) {
return gx_pci;
}
}

View File

@ -165,6 +165,7 @@ static int __init pcibios_init(void)
if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
pcibios_sort();
#endif
pci_assign_unassigned_resources();
return 0;
}

View File

@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
if ((dev = bus->self)) {
for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
if (!r->start)
if (!r->flags)
continue;
pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0)
if (!r->start || !pr || request_resource(pr, r) < 0) {
printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
/* Something is wrong with the region.
Invalidate the resource to prevent child
resource allocations in this range. */
r->flags = 0;
}
}
}
pcibios_allocate_bus_resources(&bus->children);
@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask)
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
for(idx=0; idx<6; idx++) {
for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
/* Only set up the requested stuff */
if (!(mask & (1<<idx)))
continue;

View File

@ -579,7 +579,7 @@ static int __init rng_init (void)
/* Probe for Intel, AMD RNGs */
for_each_pci_dev(pdev) {
ent = pci_match_device (rng_pci_tbl, pdev);
ent = pci_match_id(rng_pci_tbl, pdev);
if (ent) {
rng_ops = &rng_vendor_ops[ent->driver_data];
goto match;

View File

@ -401,7 +401,7 @@ static unsigned char __init i8xx_tco_getdevice (void)
*/
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
if (pci_match_device(i8xx_tco_pci_tbl, dev)) {
if (pci_match_id(i8xx_tco_pci_tbl, dev)) {
i8xx_tco_pci = dev;
break;
}

View File

@ -847,7 +847,7 @@ static int __init ide_scan_pcidev(struct pci_dev *dev)
d = list_entry(l, struct pci_driver, node);
if(d->id_table)
{
const struct pci_device_id *id = pci_match_device(d->id_table, dev);
const struct pci_device_id *id = pci_match_id(d->id_table, dev);
if(id != NULL)
{
if(d->probe(dev, id) >= 0)

View File

@ -3008,7 +3008,7 @@ static int __init parport_pc_init_superio (int autoirq, int autodma)
int ret = 0;
while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
id = pci_match_device (parport_pc_pci_tbl, pdev);
id = pci_match_id(parport_pc_pci_tbl, pdev);
if (id == NULL || id->driver_data >= last_sio)
continue;

View File

@ -19,6 +19,7 @@ obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
#
# Some architectures use the generic PCI setup functions
#
obj-$(CONFIG_X86) += setup-bus.o
obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
obj-$(CONFIG_PARISC) += setup-bus.o

View File

@ -54,7 +54,7 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
envp[i++] = scratch;
length += scnprintf (scratch, buffer_size - length,
"MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
"MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device,
(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),

View File

@ -7,7 +7,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/pci-dynids.h>
#include "pci.h"
/*
@ -19,35 +18,11 @@
*/
#ifdef CONFIG_HOTPLUG
/**
* pci_device_probe_dynamic()
*
* Walk the dynamic ID list looking for a match.
* returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
*/
static int
pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
{
int error = -ENODEV;
struct list_head *pos;
struct dynid *dynid;
spin_lock(&drv->dynids.lock);
list_for_each(pos, &drv->dynids.list) {
dynid = list_entry(pos, struct dynid, node);
if (pci_match_one_device(&dynid->id, pci_dev)) {
spin_unlock(&drv->dynids.lock);
error = drv->probe(pci_dev, &dynid->id);
if (error >= 0) {
pci_dev->driver = drv;
return 0;
}
return error;
}
}
spin_unlock(&drv->dynids.lock);
return error;
}
struct pci_dynid {
struct list_head node;
struct pci_device_id id;
};
/**
* store_new_id
@ -58,8 +33,7 @@ pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
static inline ssize_t
store_new_id(struct device_driver *driver, const char *buf, size_t count)
{
struct dynid *dynid;
struct bus_type * bus;
struct pci_dynid *dynid;
struct pci_driver *pdrv = to_pci_driver(driver);
__u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
subdevice=PCI_ANY_ID, class=0, class_mask=0;
@ -91,37 +65,22 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
list_add_tail(&pdrv->dynids.list, &dynid->node);
spin_unlock(&pdrv->dynids.lock);
bus = get_bus(pdrv->driver.bus);
if (bus) {
if (get_driver(&pdrv->driver)) {
down_write(&bus->subsys.rwsem);
driver_attach(&pdrv->driver);
up_write(&bus->subsys.rwsem);
put_driver(&pdrv->driver);
}
put_bus(bus);
if (get_driver(&pdrv->driver)) {
driver_attach(&pdrv->driver);
put_driver(&pdrv->driver);
}
return count;
}
static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
static inline void
pci_init_dynids(struct pci_dynids *dynids)
{
spin_lock_init(&dynids->lock);
INIT_LIST_HEAD(&dynids->list);
}
static void
pci_free_dynids(struct pci_driver *drv)
{
struct list_head *pos, *n;
struct dynid *dynid;
struct pci_dynid *dynid, *n;
spin_lock(&drv->dynids.lock);
list_for_each_safe(pos, n, &drv->dynids.list) {
dynid = list_entry(pos, struct dynid, node);
list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
list_del(&dynid->node);
kfree(dynid);
}
@ -138,83 +97,70 @@ pci_create_newid_file(struct pci_driver *drv)
return error;
}
static int
pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
{
struct list_head *pos;
struct dynid *dynid;
spin_lock(&pci_drv->dynids.lock);
list_for_each(pos, &pci_drv->dynids.list) {
dynid = list_entry(pos, struct dynid, node);
if (pci_match_one_device(&dynid->id, pci_dev)) {
spin_unlock(&pci_drv->dynids.lock);
return 1;
}
}
spin_unlock(&pci_drv->dynids.lock);
return 0;
}
#else /* !CONFIG_HOTPLUG */
static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
{
return -ENODEV;
}
static inline void pci_init_dynids(struct pci_dynids *dynids) {}
static inline void pci_free_dynids(struct pci_driver *drv) {}
static inline int pci_create_newid_file(struct pci_driver *drv)
{
return 0;
}
static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
{
return 0;
}
#endif
/**
* pci_match_device - Tell if a PCI device structure has a matching
* PCI device id structure
* pci_match_id - See if a pci device matches a given pci_id table
* @ids: array of PCI device id structures to search in
* @dev: the PCI device structure to match against
*
* @dev: the PCI device structure to match against.
*
* Used by a driver to check whether a PCI device present in the
* system is in its list of supported devices.Returns the matching
* system is in its list of supported devices. Returns the matching
* pci_device_id structure or %NULL if there is no match.
*
* Depreciated, don't use this as it will not catch any dynamic ids
* that a driver might want to check for.
*/
const struct pci_device_id *
pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
struct pci_dev *dev)
{
while (ids->vendor || ids->subvendor || ids->class_mask) {
if (pci_match_one_device(ids, dev))
return ids;
ids++;
if (ids) {
while (ids->vendor || ids->subvendor || ids->class_mask) {
if (pci_match_one_device(ids, dev))
return ids;
ids++;
}
}
return NULL;
}
/**
* pci_device_probe_static()
*
* returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
* pci_match_device - Tell if a PCI device structure has a matching
* PCI device id structure
* @ids: array of PCI device id structures to search in
* @dev: the PCI device structure to match against
* @drv: the PCI driver to match against
*
* Used by a driver to check whether a PCI device present in the
* system is in its list of supported devices. Returns the matching
* pci_device_id structure or %NULL if there is no match.
*/
static int
pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
{
int error = -ENODEV;
const struct pci_device_id *pci_match_device(struct pci_driver *drv,
struct pci_dev *dev)
{
const struct pci_device_id *id;
struct pci_dynid *dynid;
if (!drv->id_table)
return error;
id = pci_match_device(drv->id_table, pci_dev);
id = pci_match_id(drv->id_table, dev);
if (id)
error = drv->probe(pci_dev, id);
if (error >= 0) {
pci_dev->driver = drv;
error = 0;
return id;
/* static ids didn't match, lets look at the dynamic ones */
spin_lock(&drv->dynids.lock);
list_for_each_entry(dynid, &drv->dynids.list, node) {
if (pci_match_one_device(&dynid->id, dev)) {
spin_unlock(&drv->dynids.lock);
return &dynid->id;
}
}
return error;
spin_unlock(&drv->dynids.lock);
return NULL;
}
/**
@ -225,13 +171,20 @@ pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
*/
static int
__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{
{
const struct pci_device_id *id;
int error = 0;
if (!pci_dev->driver && drv->probe) {
error = pci_device_probe_static(drv, pci_dev);
if (error == -ENODEV)
error = pci_device_probe_dynamic(drv, pci_dev);
error = -ENODEV;
id = pci_match_device(drv, pci_dev);
if (id)
error = drv->probe(pci_dev, id);
if (error >= 0) {
pci_dev->driver = drv;
error = 0;
}
}
return error;
}
@ -371,12 +324,6 @@ static struct kobj_type pci_driver_kobj_type = {
.sysfs_ops = &pci_driver_sysfs_ops,
};
static int
pci_populate_driver_dir(struct pci_driver *drv)
{
return pci_create_newid_file(drv);
}
/**
* pci_register_driver - register a new pci driver
* @drv: the driver structure to register
@ -401,13 +348,15 @@ int pci_register_driver(struct pci_driver *drv)
drv->driver.shutdown = pci_device_shutdown;
drv->driver.owner = drv->owner;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
pci_init_dynids(&drv->dynids);
spin_lock_init(&drv->dynids.lock);
INIT_LIST_HEAD(&drv->dynids.list);
/* register with core */
error = driver_register(&drv->driver);
if (!error)
pci_populate_driver_dir(drv);
error = pci_create_newid_file(drv);
return error;
}
@ -463,21 +412,17 @@ pci_dev_driver(const struct pci_dev *dev)
* system is in its list of supported devices.Returns the matching
* pci_device_id structure or %NULL if there is no match.
*/
static int pci_bus_match(struct device * dev, struct device_driver * drv)
static int pci_bus_match(struct device *dev, struct device_driver *drv)
{
const struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * pci_drv = to_pci_driver(drv);
const struct pci_device_id * ids = pci_drv->id_table;
struct pci_dev *pci_dev = to_pci_dev(dev);
struct pci_driver *pci_drv = to_pci_driver(drv);
const struct pci_device_id *found_id;
if (!ids)
return 0;
found_id = pci_match_device(ids, pci_dev);
found_id = pci_match_device(pci_drv, pci_dev);
if (found_id)
return 1;
return pci_bus_match_dynids(pci_dev, pci_drv);
return 0;
}
/**
@ -536,6 +481,7 @@ static int __init pci_driver_init(void)
postcore_initcall(pci_driver_init);
EXPORT_SYMBOL(pci_match_id);
EXPORT_SYMBOL(pci_match_device);
EXPORT_SYMBOL(pci_register_driver);
EXPORT_SYMBOL(pci_unregister_driver);

View File

@ -334,10 +334,6 @@ EXPORT_SYMBOL(pci_choose_state);
/**
* pci_save_state - save the PCI configuration space of a device before suspending
* @dev: - PCI device that we're dealing with
* @buffer: - buffer to hold config space context
*
* @buffer must be large enough to hold the entire PCI 2.2 config space
* (>= 64 bytes).
*/
int
pci_save_state(struct pci_dev *dev)
@ -352,8 +348,6 @@ pci_save_state(struct pci_dev *dev)
/**
* pci_restore_state - Restore the saved state of a PCI device
* @dev: - PCI device that we're dealing with
* @buffer: - saved PCI config space
*
*/
int
pci_restore_state(struct pci_dev *dev)

View File

@ -27,6 +27,11 @@
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
struct pcie_port_device_ext {
int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */
unsigned int saved_msi_config_space[5];
};
extern struct bus_type pcie_port_bus_type;
extern int pcie_port_device_probe(struct pci_dev *dev);
extern int pcie_port_device_register(struct pci_dev *dev);

View File

@ -275,10 +275,17 @@ int pcie_port_device_probe(struct pci_dev *dev)
int pcie_port_device_register(struct pci_dev *dev)
{
struct pcie_port_device_ext *p_ext;
int status, type, capabilities, irq_mode, i;
int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
u16 reg16;
/* Allocate port device extension */
if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
return -ENOMEM;
pci_set_drvdata(dev, p_ext);
/* Get port type */
pci_read_config_word(dev,
pci_find_capability(dev, PCI_CAP_ID_EXP) +
@ -288,6 +295,7 @@ int pcie_port_device_register(struct pci_dev *dev)
/* Now get port services */
capabilities = get_port_device_capability(dev);
irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
p_ext->interrupt_mode = irq_mode;
/* Allocate child services if any */
for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {

View File

@ -29,6 +29,78 @@ MODULE_LICENSE("GPL");
/* global data */
static const char device_name[] = "pcieport-driver";
static void pci_save_msi_state(struct pci_dev *dev)
{
struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
int i = 0, pos;
u16 control;
if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
return;
pci_read_config_dword(dev, pos, &p_ext->saved_msi_config_space[i++]);
control = p_ext->saved_msi_config_space[0] >> 16;
pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
&p_ext->saved_msi_config_space[i++]);
if (control & PCI_MSI_FLAGS_64BIT) {
pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
&p_ext->saved_msi_config_space[i++]);
pci_read_config_dword(dev, pos + PCI_MSI_DATA_64,
&p_ext->saved_msi_config_space[i++]);
} else
pci_read_config_dword(dev, pos + PCI_MSI_DATA_32,
&p_ext->saved_msi_config_space[i++]);
if (control & PCI_MSI_FLAGS_MASKBIT)
pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT,
&p_ext->saved_msi_config_space[i++]);
}
static void pci_restore_msi_state(struct pci_dev *dev)
{
struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
int i = 0, pos;
u16 control;
if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
return;
control = p_ext->saved_msi_config_space[i++] >> 16;
pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
p_ext->saved_msi_config_space[i++]);
if (control & PCI_MSI_FLAGS_64BIT) {
pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
p_ext->saved_msi_config_space[i++]);
pci_write_config_dword(dev, pos + PCI_MSI_DATA_64,
p_ext->saved_msi_config_space[i++]);
} else
pci_write_config_dword(dev, pos + PCI_MSI_DATA_32,
p_ext->saved_msi_config_space[i++]);
if (control & PCI_MSI_FLAGS_MASKBIT)
pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT,
p_ext->saved_msi_config_space[i++]);
}
static void pcie_portdrv_save_config(struct pci_dev *dev)
{
struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
pci_save_state(dev);
if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
pci_save_msi_state(dev);
}
static void pcie_portdrv_restore_config(struct pci_dev *dev)
{
struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
pci_restore_state(dev);
if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
pci_restore_msi_state(dev);
pci_enable_device(dev);
pci_set_master(dev);
}
/*
* pcie_portdrv_probe - Probe PCI-Express port devices
* @dev: PCI-Express port device being probed
@ -64,16 +136,21 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
static void pcie_portdrv_remove (struct pci_dev *dev)
{
pcie_port_device_remove(dev);
kfree(pci_get_drvdata(dev));
}
#ifdef CONFIG_PM
static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state)
{
return pcie_port_device_suspend(dev, state);
int ret = pcie_port_device_suspend(dev, state);
pcie_portdrv_save_config(dev);
return ret;
}
static int pcie_portdrv_resume (struct pci_dev *dev)
{
pcie_portdrv_restore_config(dev);
return pcie_port_device_resume(dev);
}
#endif

View File

@ -239,9 +239,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
if (dev->transparent) {
printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev));
for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++)
child->resource[i] = child->parent->resource[i];
return;
for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
child->resource[i] = child->parent->resource[i - 3];
}
for(i=0; i<3; i++)
@ -398,6 +397,16 @@ static void pci_enable_crs(struct pci_dev *dev)
pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl);
}
static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
{
struct pci_bus *parent = child->parent;
while (parent->parent && parent->subordinate < max) {
parent->subordinate = max;
pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
parent = parent->parent;
}
}
unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus);
/*
@ -499,7 +508,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
if (!is_cardbus) {
child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA;
/*
* Adjust subordinate busnr in parent buses.
* We do this before scanning for children because
* some devices may not be detected if the bios
* was lazy.
*/
pci_fixup_parent_subordinate_busnr(child, max);
/* Now we can scan all subordinate buses... */
max = pci_scan_child_bus(child);
} else {
@ -513,6 +528,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max
max+i+1))
break;
max += i;
pci_fixup_parent_subordinate_busnr(child, max);
}
/*
* Set the subordinate bus number to its real value.

View File

@ -767,6 +767,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) {
if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB)
switch(dev->subsystem_device) {
case 0x8025: /* P4B-LX */
case 0x8070: /* P4B */
case 0x8088: /* P4B533 */
case 0x1626: /* L3C notebook */

View File

@ -273,6 +273,8 @@ find_free_bus_resource(struct pci_bus *bus, unsigned long type)
for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
r = bus->resource[i];
if (r == &ioport_resource || r == &iomem_resource)
continue;
if (r && (r->flags & type_mask) == type && !r->parent)
return r;
}

View File

@ -1,18 +0,0 @@
/*
* PCI defines and function prototypes
* Copyright 2003 Dell Inc.
* by Matt Domsch <Matt_Domsch@dell.com>
*/
#ifndef LINUX_PCI_DYNIDS_H
#define LINUX_PCI_DYNIDS_H
#include <linux/list.h>
#include <linux/mod_devicetable.h>
struct dynid {
struct list_head node;
struct pci_device_id id;
};
#endif

View File

@ -586,7 +586,7 @@ struct pci_dev {
#define PCI_NUM_RESOURCES 11
#ifndef PCI_BUS_NUM_RESOURCES
#define PCI_BUS_NUM_RESOURCES 4
#define PCI_BUS_NUM_RESOURCES 8
#endif
#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
@ -860,7 +860,8 @@ int pci_register_driver(struct pci_driver *);
void pci_unregister_driver(struct pci_driver *);
void pci_remove_behind_bridge(struct pci_dev *);
struct pci_driver *pci_dev_driver(const struct pci_dev *);
const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev);
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
/* kmem_cache style wrapper around pci_alloc_consistent() */

View File

@ -804,7 +804,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
int i;
const struct pci_device_id *supported;
supported = pci_match_device(snd_bt87x_ids, pci);
supported = pci_match_device(driver, pci);
if (supported)
return supported->driver_data;