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>
diff --git a/init/devices.c b/init/devices.c
index 3b4d369..125f981 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -63,6 +63,7 @@
     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 @@
     uevent->minor = -1;
     uevent->partition_name = NULL;
     uevent->partition_num = -1;
+    uevent->device_name = NULL;
 
         /* currently ignoring SEQNUM */
     while(*msg) {
@@ -362,9 +364,12 @@
         } 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 @@
 
     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;