summaryrefslogtreecommitdiffstats
path: root/libusbhost
diff options
context:
space:
mode:
authorZiv Hendel <ziv@primesense.com>2013-08-07 19:29:17 +0300
committerBenoit Goby <benoit@android.com>2013-08-20 17:51:13 -0700
commita306ced1ac383557dabfb38c70e5f5e2a2ec0510 (patch)
tree04e28ce8cafb41676a52b84d84aefe2d7d3987d8 /libusbhost
parent18860c524915bc991a9015bdbab32e918f5298d7 (diff)
downloadsystem_core-a306ced1ac383557dabfb38c70e5f5e2a2ec0510.zip
system_core-a306ced1ac383557dabfb38c70e5f5e2a2ec0510.tar.gz
system_core-a306ced1ac383557dabfb38c70e5f5e2a2ec0510.tar.bz2
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
Diffstat (limited to 'libusbhost')
-rw-r--r--libusbhost/usbhost.c19
1 files changed, 16 insertions, 3 deletions
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 @@ 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]);