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
This commit is contained in:
Ziv Hendel 2013-08-07 19:29:17 +03:00 committed by Benoit Goby
parent 18860c5249
commit a306ced1ac

View file

@ -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 @@ struct usb_host_context {
void *data;
int wds[MAX_USBFS_WD_COUNT];
int wdd;
int wddbus;
};
struct usb_device {
@ -195,6 +197,7 @@ int usb_host_load(struct usb_host_context *context,
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 @@ int usb_host_read_event(struct usb_host_context *context)
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]);