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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux