summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--libusb/core.c54
-rw-r--r--libusb/libusbi.h1
3 files changed, 51 insertions, 6 deletions
diff --git a/TODO b/TODO
index 08ab497..4f367dc 100644
--- 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
diff --git a/libusb/core.c b/libusb/core.c
index ab5eca3..8d68b9a 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -39,6 +39,47 @@
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();
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index fecaeb0..4ff8e38 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -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