diff options
author | David Brownell <david-b@pacbell.net> | 2007-05-08 03:29:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:10 -0400 |
commit | 49a4ec188f9a96c9a5567956718213d38a456a19 (patch) | |
tree | 29ac9f610ed355b3e3f752206c03180054df9bd7 /include/linux/device.h | |
parent | eb81d93046e7de51d47b8f1303d80e6f51ac9e33 (diff) |
fix hotplug for legacy platform drivers
We've had various reports of some legacy "probe the hardware" style
platform drivers having nasty problems with hotplug support.
The core issue is that those legacy drivers don't fully conform to the
driver model. They assume a role that should be the responsibility of
infrastructure code: creating device nodes.
The "modprobe" step in hotplugging relies on drivers to have split those
roles into different modules. The lack of this split causes the problems.
When a driver creates nodes for devices that don't exist (sending a hotplug
event), then exits (aborting one modprobe) before the "modprobe $MODALIAS"
step completes (by failing, since it's in the middle of a modprobe), the
result can be an endless loop of modprobe invocations ... badness.
This fix uses the newish per-device flag controlling issuance of "add"
events. (A previous version of this patch used a per-device "driver can
hotplug" flag, which only scrubbed $MODALIAS from the environment rather
than suppressing the entire hotplug event.) It also shrinks that flag to
one bit, saving a word in "struct device".
So the net of this patch is removing some nasty failures with legacy
drivers, while retaining hotplug capability for the majority of platform
drivers.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg KH <gregkh@suse.de>
Cc: Andres Salomon <dilinger@debian.org>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/device.h')
-rw-r--r-- | include/linux/device.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 6579068134d1..2e1a2988b7e1 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -412,12 +412,13 @@ struct device { | |||
412 | struct klist_node knode_parent; /* node in sibling list */ | 412 | struct klist_node knode_parent; /* node in sibling list */ |
413 | struct klist_node knode_driver; | 413 | struct klist_node knode_driver; |
414 | struct klist_node knode_bus; | 414 | struct klist_node knode_bus; |
415 | struct device * parent; | 415 | struct device *parent; |
416 | 416 | ||
417 | struct kobject kobj; | 417 | struct kobject kobj; |
418 | char bus_id[BUS_ID_SIZE]; /* position on parent bus */ | 418 | char bus_id[BUS_ID_SIZE]; /* position on parent bus */ |
419 | struct device_type *type; | 419 | struct device_type *type; |
420 | unsigned is_registered:1; | 420 | unsigned is_registered:1; |
421 | unsigned uevent_suppress:1; | ||
421 | struct device_attribute uevent_attr; | 422 | struct device_attribute uevent_attr; |
422 | struct device_attribute *devt_attr; | 423 | struct device_attribute *devt_attr; |
423 | 424 | ||
@@ -458,7 +459,6 @@ struct device { | |||
458 | struct class *class; | 459 | struct class *class; |
459 | dev_t devt; /* dev_t, creates the sysfs "dev" */ | 460 | dev_t devt; /* dev_t, creates the sysfs "dev" */ |
460 | struct attribute_group **groups; /* optional groups */ | 461 | struct attribute_group **groups; /* optional groups */ |
461 | int uevent_suppress; | ||
462 | 462 | ||
463 | void (*release)(struct device * dev); | 463 | void (*release)(struct device * dev); |
464 | }; | 464 | }; |