summaryrefslogtreecommitdiffstats
path: root/libusbhost
diff options
context:
space:
mode:
authorBenoit Goby <benoit@android.com>2012-07-31 19:22:06 -0700
committerBenoit Goby <benoit@android.com>2012-08-02 12:19:30 -0700
commit6cc883ca098f34bd126478a6aa19d5cce48d71a9 (patch)
tree6a952d419bb7f456ce9bd1cb088aa93714fe81ad /libusbhost
parent35fc46d8e338181ee3caedc30f3627bad2ffe35e (diff)
downloadsystem_core-6cc883ca098f34bd126478a6aa19d5cce48d71a9.zip
system_core-6cc883ca098f34bd126478a6aa19d5cce48d71a9.tar.gz
system_core-6cc883ca098f34bd126478a6aa19d5cce48d71a9.tar.bz2
libusbhost: Fix possible missed "device added" notification
When a new bus is added, check for existing devices in the bus directory, since devices may have been added before calling inotify_add_watch. Also add missing inotify_rm_watch calls. Change-Id: Ie69fc995a3e8b18431099b252be86f0054fe5531
Diffstat (limited to 'libusbhost')
-rw-r--r--libusbhost/usbhost.c63
1 files changed, 43 insertions, 20 deletions
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index 5d261cd..6be99dc 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -77,13 +77,35 @@ static inline int badname(const char *name)
return 0;
}
+static int find_existing_devices_bus(char *busname,
+ usb_device_added_cb added_cb,
+ void *client_data)
+{
+ char devname[32];
+ DIR *devdir;
+ struct dirent *de;
+ int done = 0;
+
+ devdir = opendir(busname);
+ if(devdir == 0) return 0;
+
+ while ((de = readdir(devdir)) && !done) {
+ if(badname(de->d_name)) continue;
+
+ snprintf(devname, sizeof(devname), "%s/%s", busname, de->d_name);
+ done = added_cb(devname, client_data);
+ } // end of devdir while
+ closedir(devdir);
+
+ return done;
+}
+
/* returns true if one of the callbacks indicates we are done */
static int find_existing_devices(usb_device_added_cb added_cb,
- usb_device_removed_cb removed_cb,
void *client_data)
{
- char busname[32], devname[32];
- DIR *busdir , *devdir ;
+ char busname[32];
+ DIR *busdir;
struct dirent *de;
int done = 0;
@@ -93,18 +115,10 @@ static int find_existing_devices(usb_device_added_cb added_cb,
while ((de = readdir(busdir)) != 0 && !done) {
if(badname(de->d_name)) continue;
- snprintf(busname, sizeof busname, "%s/%s", USB_FS_DIR, de->d_name);
- devdir = opendir(busname);
- if(devdir == 0) continue;
-
- while ((de = readdir(devdir)) && !done) {
- if(badname(de->d_name)) continue;
-
- snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name);
- done = added_cb(devname, client_data);
- } // end of devdir while
- closedir(devdir);
- } //end of busdir while
+ snprintf(busname, sizeof(busname), "%s/%s", USB_FS_DIR, de->d_name);
+ done = find_existing_devices_bus(busname, added_cb,
+ client_data);
+ }
closedir(busdir);
return done;
@@ -167,7 +181,7 @@ void usb_host_run(struct usb_host_context *context,
}
/* check for existing devices first, after we have inotify set up */
- done = find_existing_devices(added_cb, removed_cb, client_data);
+ done = find_existing_devices(added_cb, client_data);
if (discovery_done_cb)
done |= discovery_done_cb(client_data);
@@ -179,11 +193,20 @@ void usb_host_run(struct usb_host_context *context,
if (wd == wds[0]) {
i = atoi(event->name);
snprintf(path, sizeof(path), "%s/%s", USB_FS_DIR, event->name);
- D("new subdirectory %s: index: %d\n", path, i);
+ D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ?
+ "new" : "gone", path, i);
if (i > 0 && i < wd_count) {
- ret = inotify_add_watch(context->fd, path, IN_CREATE | IN_DELETE);
- if (ret > 0)
- wds[i] = ret;
+ if (event->mask & IN_CREATE) {
+ ret = inotify_add_watch(context->fd, path,
+ IN_CREATE | IN_DELETE);
+ if (ret > 0)
+ wds[i] = ret;
+ done = find_existing_devices_bus(path, added_cb,
+ client_data);
+ } else if (event->mask & IN_DELETE) {
+ inotify_rm_watch(context->fd, wds[i]);
+ wds[i] = -1;
+ }
}
} else {
for (i = 1; i < wd_count && !done; i++) {