From: Salvador Fandiño <sa...@qindel.com>

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 <sa...@qindel.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to