aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorWei Zhong <wzhong@google.com>2012-03-23 14:15:34 -0700
committerWei Zhong <wzhong@google.com>2012-03-23 14:16:37 -0700
commitf97b887848cc64e7d88d27f198b7721c9f2f8ec8 (patch)
tree6d3ee84a255223b752cd6c200f03dd10697797be /init
parente148601ee2a5cd83a6db80c3c4e24f3dc5a9ab31 (diff)
downloadsystem_core-f97b887848cc64e7d88d27f198b7721c9f2f8ec8.tar.gz
system_core-f97b887848cc64e7d88d27f198b7721c9f2f8ec8.tar.bz2
system_core-f97b887848cc64e7d88d27f198b7721c9f2f8ec8.zip
Add handling for DEVNAME for usb devices
When creating device node, user-space handler should honor device node provided by kernel if present. Bug: 6105248 Change-Id: I9ab3810563f29f065c239e15149882db28f08893 Signed-off-by: Wei Zhong <wzhong@google.com>
Diffstat (limited to 'init')
-rw-r--r--init/devices.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/init/devices.c b/init/devices.c
index 3b4d369d..125f9815 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -63,6 +63,7 @@ struct uevent {
const char *subsystem;
const char *firmware;
const char *partition_name;
+ const char *device_name;
int partition_num;
int major;
int minor;
@@ -335,6 +336,7 @@ static void parse_event(const char *msg, struct uevent *uevent)
uevent->minor = -1;
uevent->partition_name = NULL;
uevent->partition_num = -1;
+ uevent->device_name = NULL;
/* currently ignoring SEQNUM */
while(*msg) {
@@ -362,9 +364,12 @@ static void parse_event(const char *msg, struct uevent *uevent)
} else if(!strncmp(msg, "PARTNAME=", 9)) {
msg += 9;
uevent->partition_name = msg;
+ } else if(!strncmp(msg, "DEVNAME=", 8)) {
+ msg += 8;
+ uevent->device_name = msg;
}
- /* advance to after the next \0 */
+ /* advance to after the next \0 */
while(*msg++)
;
}
@@ -579,18 +584,39 @@ static void handle_generic_device_event(struct uevent *uevent)
if (!strncmp(uevent->subsystem, "usb", 3)) {
if (!strcmp(uevent->subsystem, "usb")) {
- /* This imitates the file system that would be created
- * if we were using devfs instead.
- * Minors are broken up into groups of 128, starting at "001"
- */
- int bus_id = uevent->minor / 128 + 1;
- int device_id = uevent->minor % 128 + 1;
- /* build directories */
- make_dir("/dev/bus", 0755);
- make_dir("/dev/bus/usb", 0755);
- snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
- make_dir(devpath, 0755);
- snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
+ if (uevent->device_name) {
+ /*
+ * create device node provided by kernel if present
+ * see drivers/base/core.c
+ */
+ char *p = devpath;
+ snprintf(devpath, sizeof(devpath), "/dev/%s", uevent->device_name);
+ /* skip leading /dev/ */
+ p += 5;
+ /* build directories */
+ while (*p) {
+ if (*p == '/') {
+ *p = 0;
+ make_dir(devpath, 0755);
+ *p = '/';
+ }
+ p++;
+ }
+ }
+ else {
+ /* This imitates the file system that would be created
+ * if we were using devfs instead.
+ * Minors are broken up into groups of 128, starting at "001"
+ */
+ int bus_id = uevent->minor / 128 + 1;
+ int device_id = uevent->minor % 128 + 1;
+ /* build directories */
+ make_dir("/dev/bus", 0755);
+ make_dir("/dev/bus/usb", 0755);
+ snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);
+ make_dir(devpath, 0755);
+ snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);
+ }
} else {
/* ignore other USB events */
return;