libusbhost: It's no longer assumed that "bus/usb" exists once "bus" was created

On some devices there is a slight delay between the creation of "/dev/bus"
and "/dev/bus/usb". Previously, the code assumed that both are created in the
same time which caused "watch_existing_subdirs" to fail and libusbhost to stop
working until the device is rebooted. The fix will setup an inotify event on the
creation of the "bus/usb" so it will not be missed once it's created.

Change-Id: I17f06dd167e61573307425e48898e12ebc954093
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index b967342..8be393e 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -51,7 +51,8 @@
 #include "usbhost/usbhost.h"
 
 #define DEV_DIR             "/dev"
-#define USB_FS_DIR          DEV_DIR "/bus/usb"
+#define DEV_BUS_DIR         DEV_DIR "/bus"
+#define USB_FS_DIR          DEV_BUS_DIR "/usb"
 #define USB_FS_ID_SCANNER   USB_FS_DIR "/%d/%d"
 #define USB_FS_ID_FORMAT    USB_FS_DIR "/%03d/%03d"
 
@@ -68,6 +69,7 @@
     void                        *data;
     int                         wds[MAX_USBFS_WD_COUNT];
     int                         wdd;
+    int                         wddbus;
 };
 
 struct usb_device {
@@ -195,6 +197,7 @@
     D("Created device discovery thread\n");
 
     /* watch for files added and deleted within USB_FS_DIR */
+    context->wddbus = -1;
     for (i = 0; i < MAX_USBFS_WD_COUNT; i++)
         context->wds[i] = -1;
 
@@ -228,15 +231,25 @@
 
     ret = read(context->fd, event_buf, sizeof(event_buf));
     if (ret >= (int)sizeof(struct inotify_event)) {
-        while (offset < ret) {
+        while (offset < ret && !done) {
             event = (struct inotify_event*)&event_buf[offset];
             done = 0;
             wd = event->wd;
             if (wd == context->wdd) {
                 if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) {
+                    context->wddbus = inotify_add_watch(context->fd, DEV_BUS_DIR, IN_CREATE | IN_DELETE);
+                    if (context->wddbus < 0) {
+                        done = 1;
+                    } else {
+                        watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
+                        done = find_existing_devices(context->cb_added, context->data);
+                    }
+                }
+            } else if (wd == context->wddbus) {
+                if ((event->mask & IN_CREATE) && !strcmp(event->name, "usb")) {
                     watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
                     done = find_existing_devices(context->cb_added, context->data);
-                } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) {
+                } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "usb")) {
                     for (i = 0; i < MAX_USBFS_WD_COUNT; i++) {
                         if (context->wds[i] >= 0) {
                             inotify_rm_watch(context->fd, context->wds[i]);