Commit 10806930 authored by Patrick Mochel's avatar Patrick Mochel

PCI Update:

- Change pci_match_device to pci_bus_bind, which becomes bind callback of pci_bus_type
- Remove explicit driver binding; let the device core handle it
parent 403892ab
......@@ -2,8 +2,6 @@
#include <linux/module.h>
#include <linux/kmod.h> /* for hotplug_path */
extern int pci_announce_device(struct pci_driver *drv, struct pci_dev *dev);
#ifndef FALSE
#define FALSE (0)
#define TRUE (!FALSE)
......@@ -48,28 +46,6 @@ run_sbin_hotplug(struct pci_dev *pdev, int insert)
call_usermodehelper (argv [0], argv, envp);
}
/**
* pci_announce_device_to_drivers - tell the drivers a new device has appeared
* @dev: the device that has shown up
*
* Notifys the drivers that a new device has appeared, and also notifys
* userspace through /sbin/hotplug.
*/
void
pci_announce_device_to_drivers(struct pci_dev *dev)
{
struct list_head *ln;
for(ln=pci_bus_type.drivers.next; ln != &pci_bus_type.drivers; ln=ln->next) {
struct pci_driver *drv = list_entry(ln, struct pci_driver, node);
if (drv->remove && pci_announce_device(drv, dev))
break;
}
/* notify userspace of new hotplug device */
run_sbin_hotplug(dev, TRUE);
}
/**
* pci_insert_device - insert a hotplug device
* @dev: the device to insert
......@@ -85,7 +61,8 @@ pci_insert_device(struct pci_dev *dev, struct pci_bus *bus)
#ifdef CONFIG_PROC_FS
pci_proc_attach_device(dev);
#endif
pci_announce_device_to_drivers(dev);
/* notify userspace of new hotplug device */
run_sbin_hotplug(dev, TRUE);
}
static void
......@@ -110,11 +87,7 @@ pci_free_resources(struct pci_dev *dev)
void
pci_remove_device(struct pci_dev *dev)
{
if (dev->driver) {
if (dev->driver->remove)
dev->driver->remove(dev);
dev->driver = NULL;
}
put_device(&dev->dev);
list_del(&dev->bus_list);
list_del(&dev->global_list);
pci_free_resources(dev);
......@@ -128,4 +101,3 @@ pci_remove_device(struct pci_dev *dev)
EXPORT_SYMBOL(pci_insert_device);
EXPORT_SYMBOL(pci_remove_device);
EXPORT_SYMBOL(pci_announce_device_to_drivers);
......@@ -10,56 +10,6 @@
* Registration of PCI drivers and handling of hot-pluggable devices.
*/
/**
* 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
*
* 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.
*/
const struct pci_device_id *
pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
{
while (ids->vendor || ids->subvendor || ids->class_mask) {
if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) &&
(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;
ids++;
}
return NULL;
}
int
pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
{
const struct pci_device_id *id;
int ret = 0;
if (drv->id_table) {
id = pci_match_device(drv->id_table, dev);
if (!id) {
ret = 0;
goto out;
}
} else
id = NULL;
dev_probe_lock();
if (drv->probe(dev, id) >= 0) {
dev->driver = drv;
ret = 1;
}
dev_probe_unlock();
out:
return ret;
}
static int pci_device_probe(struct device * dev)
{
int error = 0;
......@@ -69,7 +19,6 @@ static int pci_device_probe(struct device * dev)
if (drv->probe)
error = drv->probe(pci_dev,NULL);
printk("%s: returning %d\n",__FUNCTION__,error);
return error > 0 ? 0 : -ENODEV;
}
......@@ -123,7 +72,6 @@ int
pci_register_driver(struct pci_driver *drv)
{
int count = 0;
struct pci_dev * dev;
/* initialize common driver fields */
drv->driver.name = drv->name;
......@@ -135,11 +83,6 @@ pci_register_driver(struct pci_driver *drv)
/* register with core */
count = driver_register(&drv->driver);
pci_for_each_dev(dev) {
if (!pci_dev_driver(dev))
pci_announce_device(drv, dev);
}
return count ? count : 1;
}
......@@ -156,20 +99,6 @@ pci_register_driver(struct pci_driver *drv)
void
pci_unregister_driver(struct pci_driver *drv)
{
list_t * node;
node = drv->driver.devices.next;
while (node != &drv->driver.devices) {
struct device * dev = list_entry(node,struct device,driver_list);
struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev);
if (drv->remove)
drv->remove(pci_dev);
pci_dev->driver = NULL;
dev->driver = NULL;
list_del_init(&dev->driver_list);
}
put_driver(&drv->driver);
}
......@@ -198,8 +127,39 @@ pci_dev_driver(const struct pci_dev *dev)
return NULL;
}
/**
* pci_bus_bind - 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
*
* 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_bus_bind(struct device * dev, struct device_driver * drv)
{
struct pci_dev * pci_dev = list_entry(dev, struct pci_dev, dev);
struct pci_driver * pci_drv = list_entry(drv,struct pci_driver,driver);
const struct pci_device_id * ids = pci_drv->id_table;
if (!ids)
return 0;
while (ids->vendor || ids->subvendor || ids->class_mask) {
if ((ids->vendor == PCI_ANY_ID || ids->vendor == pci_dev->vendor) &&
(ids->device == PCI_ANY_ID || ids->device == pci_dev->device) &&
(ids->subvendor == PCI_ANY_ID || ids->subvendor == pci_dev->subsystem_vendor) &&
(ids->subdevice == PCI_ANY_ID || ids->subdevice == pci_dev->subsystem_device) &&
!((ids->class ^ pci_dev->class) & ids->class_mask))
return 1;
ids++;
}
return 0;
}
struct bus_type pci_bus_type = {
name: "pci",
bind: pci_bus_bind,
};
static int __init pci_driver_init(void)
......@@ -209,7 +169,6 @@ static int __init pci_driver_init(void)
subsys_initcall(pci_driver_init);
EXPORT_SYMBOL(pci_match_device);
EXPORT_SYMBOL(pci_register_driver);
EXPORT_SYMBOL(pci_unregister_driver);
EXPORT_SYMBOL(pci_dev_driver);
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