Commit ad6ea5a3 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 13c5afb9 b1440482
...@@ -45,8 +45,6 @@ contains: ...@@ -45,8 +45,6 @@ contains:
id_table Pointer to table of device ID's the driver is id_table Pointer to table of device ID's the driver is
interested in. Most drivers should export this interested in. Most drivers should export this
table using MODULE_DEVICE_TABLE(pci,...). table using MODULE_DEVICE_TABLE(pci,...).
Set to NULL to call probe() function for every
PCI device known to the system.
probe Pointer to a probing function which gets called (during probe Pointer to a probing function which gets called (during
execution of pci_register_driver for already existing execution of pci_register_driver for already existing
devices or later if a new device gets inserted) for all devices or later if a new device gets inserted) for all
...@@ -83,6 +81,28 @@ Each entry consists of: ...@@ -83,6 +81,28 @@ Each entry consists of:
class_mask of the class are honored during the comparison. class_mask of the class are honored during the comparison.
driver_data Data private to the driver. driver_data Data private to the driver.
Most drivers don't need to use the driver_data field. Best practice
for use of driver_data is to use it as an index into a static list of
equivalant device types, not to use it as a pointer.
Have a table entry {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID}
to have probe() called for every PCI device known to the system.
New PCI IDs may be added to a device driver at runtime by writing
to the file /sys/bus/pci/drivers/{driver}/new_id. When added, the
driver will probe for all devices it can support.
echo "vendor device subvendor subdevice class class_mask driver_data" > \
/sys/bus/pci/drivers/{driver}/new_id
where all fields are passed in as hexadecimal values (no leading 0x).
Users need pass only as many fields as necessary; vendor, device,
subvendor, and subdevice fields default to PCI_ANY_ID (FFFFFFFF),
class and classmask fields default to 0, and driver_data defaults to
0UL. Device drivers must call
pci_dynids_set_use_driver_data(pci_driver *, 1)
in order for the driver_data field to get passed to the driver.
Otherwise, only a 0 is passed in that field.
When the driver exits, it just calls pci_unregister_driver() and the PCI layer When the driver exits, it just calls pci_unregister_driver() and the PCI layer
automatically calls the remove hook for all devices handled by the driver. automatically calls the remove hook for all devices handled by the driver.
......
...@@ -316,7 +316,7 @@ static int device_attach(struct device * dev) ...@@ -316,7 +316,7 @@ static int device_attach(struct device * dev)
* Note that we ignore the error from bus_match(), since it's perfectly * Note that we ignore the error from bus_match(), since it's perfectly
* valid for a driver not to bind to any devices. * valid for a driver not to bind to any devices.
*/ */
static void driver_attach(struct device_driver * drv) void driver_attach(struct device_driver * drv)
{ {
struct bus_type * bus = drv->bus; struct bus_type * bus = drv->bus;
struct list_head * entry; struct list_head * entry;
......
...@@ -92,7 +92,7 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) ...@@ -92,7 +92,7 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
if (!list_empty(&dev->global_list)) if (!list_empty(&dev->global_list))
continue; continue;
device_register(&dev->dev); device_add(&dev->dev);
list_add_tail(&dev->global_list, &pci_devices); list_add_tail(&dev->global_list, &pci_devices);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
pci_proc_attach_device(dev); pci_proc_attach_device(dev);
......
...@@ -207,26 +207,6 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp, ...@@ -207,26 +207,6 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
#endif /* CONFIG_HOTPLUG */ #endif /* CONFIG_HOTPLUG */
/**
* pci_insert_device - insert a pci device
* @dev: the device to insert
* @bus: where to insert it
*
* Link the device to both the global PCI device chain and the
* per-bus list of devices, add the /proc entry.
*/
void
pci_insert_device(struct pci_dev *dev, struct pci_bus *bus)
{
list_add_tail(&dev->bus_list, &bus->devices);
list_add_tail(&dev->global_list, &pci_devices);
#ifdef CONFIG_PROC_FS
pci_proc_attach_device(dev);
#endif
/* add sysfs device files */
pci_create_sysfs_dev_files(dev);
}
static void static void
pci_free_resources(struct pci_dev *dev) pci_free_resources(struct pci_dev *dev)
{ {
...@@ -275,7 +255,7 @@ void pci_remove_bus_device(struct pci_dev *dev) ...@@ -275,7 +255,7 @@ void pci_remove_bus_device(struct pci_dev *dev)
pci_proc_detach_device(dev); pci_proc_detach_device(dev);
#endif #endif
kfree(dev); pci_put_dev(dev);
} }
/** /**
...@@ -300,7 +280,6 @@ void pci_remove_behind_bridge(struct pci_dev *dev) ...@@ -300,7 +280,6 @@ void pci_remove_behind_bridge(struct pci_dev *dev)
} }
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pci_insert_device);
EXPORT_SYMBOL(pci_remove_bus_device); EXPORT_SYMBOL(pci_remove_bus_device);
EXPORT_SYMBOL(pci_remove_behind_bridge); EXPORT_SYMBOL(pci_remove_behind_bridge);
#endif #endif
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h>
#include <linux/pci-dynids.h>
#include "pci.h" #include "pci.h"
/* /*
...@@ -13,7 +15,29 @@ ...@@ -13,7 +15,29 @@
*/ */
/** /**
* pci_match_device - Tell if a PCI device structure has a matching PCI device id structure * pci_match_one_device - Tell if a PCI device structure has a matching
* PCI device id structure
* @id: single PCI device id structure to match
* @dev: the PCI device structure to match against
*
* Returns the matching pci_device_id structure or %NULL if there is no match.
*/
static inline const struct pci_device_id *
pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
{
if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
(id->device == PCI_ANY_ID || id->device == dev->device) &&
(id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
(id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
!((id->class ^ dev->class) & id->class_mask))
return id;
return NULL;
}
/**
* 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 * @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
* *
...@@ -25,17 +49,87 @@ const struct pci_device_id * ...@@ -25,17 +49,87 @@ const struct pci_device_id *
pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
{ {
while (ids->vendor || ids->subvendor || ids->class_mask) { while (ids->vendor || ids->subvendor || ids->class_mask) {
if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) && if (pci_match_one_device(ids, dev))
(ids->device == PCI_ANY_ID || ids->device == dev->device) &&
(ids->subvendor == PCI_ANY_ID || ids->subvendor == dev->subsystem_vendor) &&
(ids->subdevice == PCI_ANY_ID || ids->subdevice == dev->subsystem_device) &&
!((ids->class ^ dev->class) & ids->class_mask))
return ids; return ids;
ids++; ids++;
} }
return NULL; return NULL;
} }
/**
* pci_device_probe_static()
*
* returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
*/
static int
pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
{
int error = -ENODEV;
const struct pci_device_id *id;
if (!drv->id_table)
return error;
id = pci_match_device(drv->id_table, pci_dev);
if (id)
error = drv->probe(pci_dev, id);
if (error >= 0) {
pci_dev->driver = drv;
return 0;
}
return error;
}
/**
* 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;
}
/**
* __pci_device_probe()
*
* returns 0 on success, else error.
* side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
*/
static int
__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{
int error = 0;
if (!pci_dev->driver && drv->probe) {
error = pci_device_probe_static(drv, pci_dev);
if (error >= 0)
return error;
error = pci_device_probe_dynamic(drv, pci_dev);
}
return error;
}
static int pci_device_probe(struct device * dev) static int pci_device_probe(struct device * dev)
{ {
int error = 0; int error = 0;
...@@ -44,17 +138,9 @@ static int pci_device_probe(struct device * dev) ...@@ -44,17 +138,9 @@ static int pci_device_probe(struct device * dev)
drv = to_pci_driver(dev->driver); drv = to_pci_driver(dev->driver);
pci_dev = to_pci_dev(dev); pci_dev = to_pci_dev(dev);
if (get_device(dev)) {
if (!pci_dev->driver && drv->probe) { error = __pci_device_probe(drv, pci_dev);
const struct pci_device_id *id; put_device(dev);
id = pci_match_device(drv->id_table, pci_dev);
if (id)
error = drv->probe(pci_dev, id);
if (error >= 0) {
pci_dev->driver = drv;
error = 0;
}
} }
return error; return error;
} }
...@@ -101,6 +187,134 @@ static int pci_device_resume(struct device * dev, u32 level) ...@@ -101,6 +187,134 @@ static int pci_device_resume(struct device * dev, u32 level)
return 0; return 0;
} }
static inline void
dynid_init(struct dynid *dynid)
{
memset(dynid, 0, sizeof(*dynid));
INIT_LIST_HEAD(&dynid->node);
}
/**
* store_new_id
* @ pdrv
* @ buf
* @ count
*
* Adds a new dynamic pci device ID to this driver,
* and causes the driver to probe for all devices again.
*/
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_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;
unsigned long driver_data=0;
int fields=0;
fields = sscanf(buf, "%x %x %x %x %x %x %lux",
&vendor, &device, &subvendor, &subdevice,
&class, &class_mask, &driver_data);
if (fields < 0)
return -EINVAL;
dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
if (!dynid)
return -ENOMEM;
dynid_init(dynid);
dynid->id.vendor = vendor;
dynid->id.device = device;
dynid->id.subvendor = subvendor;
dynid->id.subdevice = subdevice;
dynid->id.class = class;
dynid->id.class_mask = class_mask;
dynid->id.driver_data = pdrv->dynids.use_driver_data ?
driver_data : 0UL;
spin_lock(&pdrv->dynids.lock);
list_add(&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);
}
return count;
}
static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
#define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj)
#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
static ssize_t
pci_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
{
struct device_driver *driver = kobj_to_pci_driver(kobj);
struct driver_attribute *dattr = attr_to_driver_attribute(attr);
ssize_t ret = 0;
if (get_driver(driver)) {
if (dattr->show)
ret = dattr->show(driver, buf);
put_driver(driver);
}
return ret;
}
static ssize_t
pci_driver_attr_store(struct kobject * kobj, struct attribute *attr,
const char *buf, size_t count)
{
struct device_driver *driver = kobj_to_pci_driver(kobj);
struct driver_attribute *dattr = attr_to_driver_attribute(attr);
ssize_t ret = 0;
if (get_driver(driver)) {
if (dattr->store)
ret = dattr->store(driver, buf, count);
put_driver(driver);
}
return ret;
}
static struct sysfs_ops pci_driver_sysfs_ops = {
.show = pci_driver_attr_show,
.store = pci_driver_attr_store,
};
static struct kobj_type pci_driver_kobj_type = {
.sysfs_ops = &pci_driver_sysfs_ops,
};
static int
pci_populate_driver_dir(struct pci_driver * drv)
{
int error = 0;
if (drv->probe != NULL)
error = sysfs_create_file(&drv->driver.kobj,
&driver_attr_new_id.attr);
return error;
}
static inline void
pci_init_dynids(struct pci_dynids *dynids)
{
memset(dynids, 0, sizeof(*dynids));
spin_lock_init(&dynids->lock);
INIT_LIST_HEAD(&dynids->list);
}
/** /**
* pci_register_driver - register a new pci driver * pci_register_driver - register a new pci driver
* @drv: the driver structure to register * @drv: the driver structure to register
...@@ -122,9 +336,16 @@ pci_register_driver(struct pci_driver *drv) ...@@ -122,9 +336,16 @@ pci_register_driver(struct pci_driver *drv)
drv->driver.resume = pci_device_resume; drv->driver.resume = pci_device_resume;
drv->driver.suspend = pci_device_suspend; drv->driver.suspend = pci_device_suspend;
drv->driver.remove = pci_device_remove; drv->driver.remove = pci_device_remove;
drv->driver.kobj.ktype = &pci_driver_kobj_type;
pci_init_dynids(&drv->dynids);
/* register with core */ /* register with core */
count = driver_register(&drv->driver); count = driver_register(&drv->driver);
if (count >= 0) {
pci_populate_driver_dir(drv);
}
return count ? count : 1; return count ? count : 1;
} }
...@@ -180,25 +401,72 @@ pci_dev_driver(const struct pci_dev *dev) ...@@ -180,25 +401,72 @@ pci_dev_driver(const struct pci_dev *dev)
*/ */
static int pci_bus_match(struct device * dev, struct device_driver * drv) static int pci_bus_match(struct device * dev, struct device_driver * drv)
{ {
struct pci_dev * pci_dev = to_pci_dev(dev); const struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * pci_drv = to_pci_driver(drv); struct pci_driver * pci_drv = to_pci_driver(drv);
const struct pci_device_id * ids = pci_drv->id_table; const struct pci_device_id * ids = pci_drv->id_table;
const struct pci_device_id *found_id;
struct list_head *pos;
struct dynid *dynid;
if (!ids) if (!ids)
return 0; return 0;
while (ids->vendor || ids->subvendor || ids->class_mask) { found_id = pci_match_device(ids, pci_dev);
if ((ids->vendor == PCI_ANY_ID || ids->vendor == pci_dev->vendor) && if (found_id)
(ids->device == PCI_ANY_ID || ids->device == pci_dev->device) && return 1;
(ids->subvendor == PCI_ANY_ID || ids->subvendor == pci_dev->subsystem_vendor) &&
(ids->subdevice == PCI_ANY_ID || ids->subdevice == pci_dev->subsystem_device) && spin_lock(&pci_drv->dynids.lock);
!((ids->class ^ pci_dev->class) & ids->class_mask)) 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; return 1;
ids++; }
} }
spin_unlock(&pci_drv->dynids.lock);
return 0; return 0;
} }
/**
* pci_get_dev - increments the reference count of the pci device structure
* @dev: the device being referenced
*
* Each live reference to a device should be refcounted.
*
* Drivers for PCI devices should normally record such references in
* their probe() methods, when they bind to a device, and release
* them by calling pci_put_dev(), in their disconnect() methods.
*
* A pointer to the device with the incremented reference counter is returned.
*/
struct pci_dev *pci_get_dev (struct pci_dev *dev)
{
struct device *tmp;
if (!dev)
return NULL;
tmp = get_device(&dev->dev);
if (tmp)
return to_pci_dev(tmp);
else
return NULL;
}
/**
* pci_put_dev - release a use of the pci device structure
* @dev: device that's been disconnected
*
* Must be called when a user of a device is finished with it. When the last
* user of the device calls this function, the memory of the device is freed.
*/
void pci_put_dev(struct pci_dev *dev)
{
if (dev)
put_device(&dev->dev);
}
struct bus_type pci_bus_type = { struct bus_type pci_bus_type = {
.name = "pci", .name = "pci",
.match = pci_bus_match, .match = pci_bus_match,
...@@ -217,3 +485,5 @@ EXPORT_SYMBOL(pci_register_driver); ...@@ -217,3 +485,5 @@ EXPORT_SYMBOL(pci_register_driver);
EXPORT_SYMBOL(pci_unregister_driver); EXPORT_SYMBOL(pci_unregister_driver);
EXPORT_SYMBOL(pci_dev_driver); EXPORT_SYMBOL(pci_dev_driver);
EXPORT_SYMBOL(pci_bus_type); EXPORT_SYMBOL(pci_bus_type);
EXPORT_SYMBOL(pci_get_dev);
EXPORT_SYMBOL(pci_put_dev);
...@@ -462,6 +462,21 @@ int pci_setup_device(struct pci_dev * dev) ...@@ -462,6 +462,21 @@ int pci_setup_device(struct pci_dev * dev)
return 0; return 0;
} }
/**
* pci_release_dev - free a pci device structure when all users of it are finished.
* @dev: device that's been disconnected
*
* Will be called only by the device core when all users of this pci device are
* done.
*/
static void pci_release_dev(struct device *dev)
{
struct pci_dev *pci_dev;
pci_dev = to_pci_dev(dev);
kfree(pci_dev);
}
/* /*
* Read the config data for a PCI device, sanity-check it * Read the config data for a PCI device, sanity-check it
* and fill in the dev structure... * and fill in the dev structure...
...@@ -506,6 +521,9 @@ pci_scan_device(struct pci_bus *bus, int devfn) ...@@ -506,6 +521,9 @@ pci_scan_device(struct pci_bus *bus, int devfn)
kfree(dev); kfree(dev);
return NULL; return NULL;
} }
device_initialize(&dev->dev);
dev->dev.release = pci_release_dev;
pci_get_dev(dev);
pci_name_device(dev); pci_name_device(dev);
......
...@@ -319,6 +319,7 @@ extern void device_del(struct device * dev); ...@@ -319,6 +319,7 @@ extern void device_del(struct device * dev);
*/ */
extern void device_bind_driver(struct device * dev); extern void device_bind_driver(struct device * dev);
extern void device_release_driver(struct device * dev); extern void device_release_driver(struct device * dev);
extern void driver_attach(struct device_driver * drv);
/* driverfs interface for exporting device attributes */ /* driverfs interface for exporting device attributes */
......
/*
* PCI defines and function prototypes
* Copyright 2003 Dell Computer Corporation
* 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
...@@ -490,10 +490,16 @@ struct pci_bus_region { ...@@ -490,10 +490,16 @@ struct pci_bus_region {
unsigned long end; unsigned long end;
}; };
struct pci_dynids {
spinlock_t lock; /* protects list, index */
struct list_head list; /* for IDs added at runtime */
unsigned int use_driver_data:1; /* pci_driver->driver_data is used */
};
struct pci_driver { struct pci_driver {
struct list_head node; struct list_head node;
char *name; char *name;
const struct pci_device_id *id_table; /* NULL if wants all devices */ const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
int (*save_state) (struct pci_dev *dev, u32 state); /* Save Device Context */ int (*save_state) (struct pci_dev *dev, u32 state); /* Save Device Context */
...@@ -502,6 +508,7 @@ struct pci_driver { ...@@ -502,6 +508,7 @@ struct pci_driver {
int (*enable_wake) (struct pci_dev *dev, u32 state, int enable); /* Enable wake event */ int (*enable_wake) (struct pci_dev *dev, u32 state, int enable); /* Enable wake event */
struct device_driver driver; struct device_driver driver;
struct pci_dynids dynids;
}; };
#define to_pci_driver(drv) container_of(drv,struct pci_driver, driver) #define to_pci_driver(drv) container_of(drv,struct pci_driver, driver)
...@@ -556,6 +563,8 @@ void pci_read_bridge_bases(struct pci_bus *child); ...@@ -556,6 +563,8 @@ void pci_read_bridge_bases(struct pci_bus *child);
struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res); struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
int pci_setup_device(struct pci_dev *dev); int pci_setup_device(struct pci_dev *dev);
int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
extern struct pci_dev *pci_get_dev(struct pci_dev *dev);
extern void pci_put_dev(struct pci_dev *dev);
/* Generic PCI functions exported to card drivers */ /* Generic PCI functions exported to card drivers */
...@@ -651,7 +660,6 @@ void pci_enable_bridges(struct pci_bus *bus); ...@@ -651,7 +660,6 @@ void pci_enable_bridges(struct pci_bus *bus);
/* New-style probing supporting hot-pluggable devices */ /* New-style probing supporting hot-pluggable devices */
int pci_register_driver(struct pci_driver *); int pci_register_driver(struct pci_driver *);
void pci_unregister_driver(struct pci_driver *); void pci_unregister_driver(struct pci_driver *);
void pci_insert_device(struct pci_dev *, struct pci_bus *);
void pci_remove_bus_device(struct pci_dev *); void pci_remove_bus_device(struct pci_dev *);
void pci_remove_behind_bridge(struct pci_dev *); void pci_remove_behind_bridge(struct pci_dev *);
struct pci_driver *pci_dev_driver(const struct pci_dev *); struct pci_driver *pci_dev_driver(const struct pci_dev *);
...@@ -702,6 +710,12 @@ extern int pci_visit_dev(struct pci_visit *fn, ...@@ -702,6 +710,12 @@ extern int pci_visit_dev(struct pci_visit *fn,
struct pci_bus_wrapped *wrapped_parent); struct pci_bus_wrapped *wrapped_parent);
extern int pci_remove_device_safe(struct pci_dev *dev); extern int pci_remove_device_safe(struct pci_dev *dev);
static inline void
pci_dynids_set_use_driver_data(struct pci_driver *pdrv, int val)
{
pdrv->dynids.use_driver_data = val;
}
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
/* Include architecture-dependent settings and functions */ /* Include architecture-dependent settings and functions */
...@@ -750,6 +764,7 @@ static inline void pci_unregister_driver(struct pci_driver *drv) { } ...@@ -750,6 +764,7 @@ static inline void pci_unregister_driver(struct pci_driver *drv) { }
static inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir; } static inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir; }
static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; } static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
static inline void pci_dynids_set_use_driver_data(struct pci_driver *pdrv, int val) { }
/* Power management related routines */ /* Power management related routines */
static inline int pci_save_state(struct pci_dev *dev, u32 *buffer) { return 0; } static inline int pci_save_state(struct pci_dev *dev, u32 *buffer) { return 0; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment