From: Salvador Fandiño <salva@xxxxxxxxxx> Now every vhci_hcd device is controlled by its own sysfs attributes (before all of them were controlled by vhci_hcd.0 attributes). This patch addapts libusbip to this new interface. Before this patch the library did not provide any mean to access a specific vhci_hcd device. In order to keep backward compatibility while at the same time allowing to access vhci_hcd devices independently the following approach has been taken: New functions accepting a vhci_hcd path or an index have been added ("usbip_vhci_driver_open_path" and "usbip_vhci_driver_open_ix" respectively). The old function "usbip_vhci_driver_open" can only be used to open "vhci_hcd.0"). That will make old programs fail to use any other vhci_hcd device, but as that functionality was broken in the kernel anyway until very recently (see 1ac7c8a78be85f84b019d3d2742d1a9f07255cc5) we consider it a good compromise. Signed-off-by: Salvador Fandiño <salva@xxxxxxxxxx> --- tools/usb/usbip/libsrc/vhci_driver.c | 105 +++++++++++++++++++++-------------- tools/usb/usbip/libsrc/vhci_driver.h | 12 +++- 2 files changed, 74 insertions(+), 43 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index c9c81614a66a..34d15167bab3 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -114,13 +114,16 @@ static int refresh_imported_device_list(void) char status[MAX_STATUS_NAME+1] = "status"; int i, ret; - for (i = 0; i < vhci_driver->ncontrollers; i++) { + for (i = 0; ; i++) { if (i > 0) snprintf(status, sizeof(status), "status.%d", i); attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device, status); if (!attr_status) { + if (i > 0) + break; + err("udev_device_get_sysattr_value failed"); return -1; } @@ -148,33 +151,6 @@ static int get_nports(void) return (int)strtoul(attr_nports, NULL, 10); } -static int vhci_hcd_filter(const struct dirent *dirent) -{ - return strcmp(dirent->d_name, "vhci_hcd") >= 0; -} - -static int get_ncontrollers(void) -{ - struct dirent **namelist; - struct udev_device *platform; - int n; - - platform = udev_device_get_parent(vhci_driver->hc_device); - if (platform == NULL) - return -1; - - n = scandir(udev_device_get_syspath(platform), &namelist, vhci_hcd_filter, NULL); - if (n < 0) - err("scandir failed"); - else { - for (int i = 0; i < n; i++) - free(namelist[i]); - free(namelist); - } - - return n; -} - /* * Read the given port's record. * @@ -199,7 +175,8 @@ static int read_record(int rhport, char *host, unsigned long host_len, if (!buffer) return -1; - snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d-%d", + vhci_driver->ix, rhport); file = fopen(path, "r"); if (!file) { @@ -238,9 +215,18 @@ static int read_record(int rhport, char *host, unsigned long host_len, return 0; } +static int vhci_path_to_ix(const char *path) +{ + int i = strlen(path); + + while (--i >= 0 && isdigit(path[i])) + ; + return atoi(path + i + 1); +} + /* ---------------------------------------------------------------------- */ -int usbip_vhci_driver_open(void) +int usbip_vhci_driver_open_path(const char *path) { udev_context = udev_new(); if (!udev_context) { @@ -252,14 +238,15 @@ int usbip_vhci_driver_open(void) /* will be freed in usbip_driver_close() */ vhci_driver->hc_device = - udev_device_new_from_subsystem_sysname(udev_context, - USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DEVICE_NAME); + udev_device_new_from_syspath(udev_context, path); + if (!vhci_driver->hc_device) { err("udev_device_new_from_subsystem_sysname failed"); goto err; } + vhci_driver->ix = vhci_path_to_ix(path); + vhci_driver->nports = get_nports(); dbg("available ports: %d", vhci_driver->nports); @@ -271,14 +258,6 @@ int usbip_vhci_driver_open(void) goto err; } - vhci_driver->ncontrollers = get_ncontrollers(); - dbg("available controllers: %d", vhci_driver->ncontrollers); - - if (vhci_driver->ncontrollers <=0) { - err("no available usb controllers"); - goto err; - } - if (refresh_imported_device_list()) goto err; @@ -297,6 +276,45 @@ int usbip_vhci_driver_open(void) return -1; } +int usbip_vhci_driver_open(void) +{ + return usbip_vhci_driver_open_ix(0); +} + +int usbip_vhci_driver_open_ix(int vhci_ix) +{ + struct udev *udev_context; + struct udev_device *dev = NULL; + char vhci_name[PATH_MAX + 1]; + int len, rc = -1; + + len = snprintf(vhci_name, PATH_MAX, + "%s.%d", USBIP_VHCI_DEVICE_NAME_PREFIX, vhci_ix); + if (len >= PATH_MAX) { + err("vhci device name is too long"); + return -1; + } + + udev_context = udev_new(); + if (!udev_context) { + err("udev_new failed"); + return -1; + } + + dev = udev_device_new_from_subsystem_sysname(udev_context, + USBIP_VHCI_BUS_TYPE, + vhci_name); + if (!dev) { + err("udev_device_from_subsystem_sysname failed to open %s", + vhci_name); + } else { + rc = usbip_vhci_driver_open_path(udev_device_get_syspath(dev)); + udev_device_unref(dev); + } + + udev_unref(udev_context); + return rc; +} void usbip_vhci_driver_close(void) { @@ -459,3 +477,8 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) return 0; } + +int usbip_vhci_driver_ix(void) +{ + return vhci_driver->ix; +} diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index 418b404d5121..40537f4f8917 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -12,7 +12,9 @@ #include "usbip_common.h" #define USBIP_VHCI_BUS_TYPE "platform" -#define USBIP_VHCI_DEVICE_NAME "vhci_hcd.0" +#define USBIP_VHCI_DEVICE_NAME_PREFIX "vhci_hcd" +#define USBIP_VHCI_DEVICE_NAME_0 (USBIP_VHCI_DEVICE_NAME_PREFIX ".0") +#define USBIP_VHCI_DEVICE_NAME_PATTERN (USBIP_VHCI_DEVICE_NAME_PREFIX ".*") #define MAXNPORT 128 enum hub_speed { @@ -39,7 +41,7 @@ struct usbip_vhci_driver { /* /sys/devices/platform/vhci_hcd */ struct udev_device *hc_device; - int ncontrollers; + int ix; int nports; struct usbip_imported_device idev[MAXNPORT]; }; @@ -47,7 +49,11 @@ struct usbip_vhci_driver { extern struct usbip_vhci_driver *vhci_driver; +/* will be removed */ int usbip_vhci_driver_open(void); + +int usbip_vhci_driver_open_path(const char *); +int usbip_vhci_driver_open_ix(int vhci_ix); void usbip_vhci_driver_close(void); int usbip_vhci_refresh_device_list(void); @@ -65,4 +71,6 @@ int usbip_vhci_detach_device(uint8_t port); int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev); +int usbip_vhci_driver_ix(void); + #endif /* __VHCI_DRIVER_H */ -- 2.14.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html