dynids: call driver_attach() when new IDs are added
This causes the driver to create proper device symlinks in sysfs when
new IDs are added and thus new devices found by the driver.
drivers/base/bus.c
make driver_attach non-static
drivers/pci/pci-driver.c
delete probe_each_pci_dev, call driver_attach instead.
Whitespace cleanups.
include/linux/device.h
add declaration of driver_attach.
drivers/base/bus.c | 2 -
drivers/pci/pci-driver.c | 82 ++++++++++++++++++-----------------------------
include/linux/device.h | 1
3 files changed, 35 insertions(+), 50 deletions(-)
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c Thu May 22 14:51:15 2003
+++ b/drivers/base/bus.c Thu May 22 14:51:15 2003
@@ -316,7 +316,7 @@
* Note that we ignore the error from bus_match(), since it's perfectly
* 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 list_head * entry;
diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c Thu May 22 14:51:15 2003
+++ b/drivers/pci/pci-driver.c Thu May 22 14:51:15 2003
@@ -15,7 +15,8 @@
*/
/**
- * pci_match_one_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
*
@@ -35,7 +36,8 @@
}
/**
- * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure
+ * 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
*
@@ -48,7 +50,7 @@
{
while (ids->vendor || ids->subvendor || ids->class_mask) {
if (pci_match_one_device(ids, dev))
- return ids;
+ return ids;
ids++;
}
return NULL;
@@ -60,8 +62,7 @@
* 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)
+pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
{
int error = -ENODEV;
const struct pci_device_id *id;
@@ -85,13 +86,12 @@
* 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)
+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);
@@ -116,8 +116,7 @@
* 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)
+__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{
int error = 0;
@@ -188,28 +187,6 @@
return 0;
}
-/*
- * If __pci_device_probe() returns 0, it matched at least one previously
- * unclaimed device. If it returns -ENODEV, it didn't match. Both are
- * alright in this case, just keep searching for new devices.
- */
-
-static int
-probe_each_pci_dev(struct pci_driver *drv)
-{
- struct pci_dev *pci_dev=NULL;
- int error = 0;
- pci_for_each_dev(pci_dev) {
- if (get_device(&pci_dev->dev)) {
- error = __pci_device_probe(drv, pci_dev);
- put_device(&pci_dev->dev);
- if (error && error != -ENODEV)
- return error;
- }
- }
- return error;
-}
-
static inline void
dynid_init(struct dynid *dynid)
{
@@ -230,19 +207,22 @@
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, error=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;
+ if (fields < 0)
+ return -EINVAL;
dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
- if (!dynid) return -ENOMEM;
+ if (!dynid)
+ return -ENOMEM;
dynid_init(dynid);
dynid->id.vendor = vendor;
@@ -251,21 +231,24 @@
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;
+ 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);
- if (get_driver(&pdrv->driver)) {
- error = probe_each_pci_dev(pdrv);
- put_driver(&pdrv->driver);
- }
- if (error < 0)
- return error;
- return count;
-
-
+ 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;
}
@@ -310,7 +293,7 @@
.store = pci_driver_attr_store,
};
static struct kobj_type pci_driver_kobj_type = {
- .sysfs_ops = &pci_driver_sysfs_ops,
+ .sysfs_ops = &pci_driver_sysfs_ops,
};
static int
@@ -319,7 +302,8 @@
int error = 0;
if (drv->probe != NULL)
- error = sysfs_create_file(&drv->driver.kobj,&driver_attr_new_id.attr);
+ error = sysfs_create_file(&drv->driver.kobj,
+ &driver_attr_new_id.attr);
return error;
}
@@ -361,7 +345,7 @@
if (count >= 0) {
pci_populate_driver_dir(drv);
}
-
+
return count ? count : 1;
}
@@ -428,7 +412,7 @@
return 0;
found_id = pci_match_device(ids, pci_dev);
- if (found_id)
+ if (found_id)
return 1;
spin_lock(&pci_drv->dynids.lock);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h Thu May 22 14:51:15 2003
+++ b/include/linux/device.h Thu May 22 14:51:15 2003
@@ -318,6 +318,7 @@
*/
extern void device_bind_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 */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/