[PATCH 2/4] libusbip: use per vhci_hcd controller attributes

From: Salvador Fandino
Date: Tue Jan 30 2018 - 03:44:22 EST


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