Add fallback on /proc/bus/usb
authorDaniel Drake <dsd@gentoo.org>
Sat, 8 Mar 2008 11:53:33 +0000 (11:53 +0000)
committerDaniel Drake <dsd@gentoo.org>
Sat, 8 Mar 2008 12:58:32 +0000 (12:58 +0000)
/dev/bus/usb is a relatively new thing probably not present on every
system

TODO
libusb/core.c
libusb/libusbi.h

diff --git a/TODO b/TODO
index 08ab497..4f367dc 100644 (file)
--- a/TODO
+++ b/TODO
@@ -8,7 +8,6 @@ API docs
 isochronous endpoint I/O
 thread safety
 abstraction for cross-platform-ness
-fallback on /proc/bus/usb on linux
 error codes
 
 for 1.1 or future
@@ -26,3 +25,4 @@ urbh in general (should this be a transfer handle?)
 config struct/function naming
 typedef _cb or _cb_fn or _cb_t?
 typedef as-is or pointers? libusb_dev_t rather than libusb_dev *?
+FP_ urb status codes
index ab5eca3..8d68b9a 100644 (file)
 
 struct list_head usb_devs;
 struct list_head open_devs;
+static const char *usbfs_path = NULL;
+
+static int check_usb_vfs(const char *dirname)
+{
+       DIR *dir;
+       struct dirent *entry;
+       int found = 0;
+
+       dir = opendir(dirname);
+       if (!dir)
+               return 0;
+
+       while ((entry = readdir(dir)) != NULL) {
+               if (entry->d_name[0] == '.')
+                       continue;
+
+               /* We assume if we find any files that it must be the right place */
+               found = 1;
+               break;
+       }
+
+       closedir(dir);
+       return found;
+}
+
+static const char *find_usbfs_path(void)
+{
+       const char *path = "/dev/bus/usb";
+       const char *ret = NULL;
+
+       if (check_usb_vfs(path)) {
+               ret = path;
+       } else {
+               path = "/proc/bus/usb";
+               if (check_usb_vfs(path))
+                       ret = path;
+       }
+
+       usbi_dbg("found usbfs at %s", ret);
+       return ret;
+}
 
 /* we traverse usbfs without knowing how many devices we are going to find.
  * so we create this discovered_devs model which is similar to a linked-list
@@ -120,7 +161,7 @@ static struct libusb_device *device_new(uint8_t busnum, uint8_t devaddr)
        dev->nodepath = NULL;
        dev->config = NULL;
 
-       snprintf(path, PATH_MAX, "/dev/bus/usb/%03d/%03d", busnum, devaddr);
+       snprintf(path, PATH_MAX, "%s/%03d/%03d", usbfs_path, busnum, devaddr);
        usbi_dbg("%s", path);
        fd = open(path, O_RDWR);
        if (!fd) {
@@ -281,7 +322,7 @@ static int scan_busdir(struct discovered_devs **_discdevs, uint8_t busnum)
        struct discovered_devs *discdevs = *_discdevs;
        int r = 0;
 
-       snprintf(dirpath, PATH_MAX, "%s/%03d", USBFS_PATH, busnum);
+       snprintf(dirpath, PATH_MAX, "%s/%03d", usbfs_path, busnum);
        usbi_dbg("%s", dirpath);
        dir = opendir(dirpath);
        if (!dir) {
@@ -328,7 +369,7 @@ API_EXPORTED int libusb_get_device_list(struct libusb_device ***list)
        if (!discdevs)
                return -ENOMEM;
 
-       buses = opendir(USBFS_PATH);
+       buses = opendir(usbfs_path);
        if (!buses) {
                usbi_err("opendir buses failed errno=%d", errno);
                return -1;
@@ -529,8 +570,13 @@ API_EXPORTED int libusb_release_interface(struct libusb_dev_handle *dev,
 
 API_EXPORTED int libusb_init(void)
 {
-       /* FIXME: find correct usb node path */
        usbi_dbg("");
+       usbfs_path = find_usbfs_path();
+       if (!usbfs_path) {
+               usbi_err("could not find usbfs");
+               return -ENODEV;
+       }
+
        list_init(&usb_devs);
        list_init(&open_devs);
        usbi_io_init();
index fecaeb0..4ff8e38 100644 (file)
@@ -31,7 +31,6 @@
 #include <libusb.h>
 #include <usbfs.h>
 
-#define USBFS_PATH "/dev/bus/usb"
 #define DEVICE_DESC_LENGTH             18
 
 #define USB_MAXENDPOINTS       32