mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2] scripts: imx imx-usb-loader: add usb path support
@ 2017-03-02 14:43 Oleksij Rempel
  2017-03-03  6:25 ` Sascha Hauer
  0 siblings, 1 reply; 2+ messages in thread
From: Oleksij Rempel @ 2017-03-02 14:43 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

In some cases we need to work with more than one device attached
to one host. For this situation we need path filter to make sure
we talk with proper device.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 changes v1:
 - move loc before first if
 - fix comment style

 scripts/imx/imx-usb-loader.c | 99 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 86 insertions(+), 13 deletions(-)

diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c
index be0894fa6..e8d746785 100644
--- a/scripts/imx/imx-usb-loader.c
+++ b/scripts/imx/imx-usb-loader.c
@@ -45,6 +45,12 @@
 #define FT_DCD	0xee
 #define FT_LOAD_ONLY	0x00
 
+/*
+ * comment from libusb:
+ * As per the USB 3.0 specs, the current maximum limit for the depth is 7.
+ */
+#define MAX_USB_PORTS	7
+
 int verbose;
 static struct libusb_device_handle *usb_dev_handle;
 static struct usb_id *usb_id;
@@ -190,9 +196,64 @@ static struct mach_id *imx_device(unsigned short vid, unsigned short pid)
 	return NULL;
 }
 
-static libusb_device *find_imx_dev(libusb_device **devs, struct mach_id **pp_id)
+static int device_location_equal(libusb_device *device, const char *location)
+{
+	uint8_t port_path[MAX_USB_PORTS];
+	uint8_t dev_bus;
+	int path_step, path_len;
+	int result = 0;
+	char *ptr, *loc;
+
+	/* strtok need non const char */
+	loc = strdup(location);
+
+	path_len = libusb_get_port_numbers(device, port_path, MAX_USB_PORTS);
+	if (path_len == LIBUSB_ERROR_OVERFLOW) {
+		fprintf(stderr, "cannot determine path to usb device! (more than %i ports in path)\n",
+			MAX_USB_PORTS);
+		goto done;
+	}
+
+	ptr = strtok(loc, "-");
+	if (ptr == NULL) {
+		printf("no '-' in path\n");
+		goto done;
+	}
+
+	dev_bus = libusb_get_bus_number(device);
+	/* check bus mismatch */
+	if (atoi(ptr) != dev_bus)
+		goto done;
+
+	path_step = 0;
+	while (path_step < MAX_USB_PORTS) {
+		ptr = strtok(NULL, ".");
+
+		/* no more tokens in path */
+		if (ptr == NULL)
+			break;
+
+		/* path mismatch at some step */
+		if (path_step < path_len && atoi(ptr) != port_path[path_step])
+			break;
+
+		path_step++;
+	};
+
+	/* walked the full path, all elements match */
+	if (path_step == path_len)
+		result = 1;
+
+done:
+	free(loc);
+	return result;
+}
+
+static libusb_device *find_imx_dev(libusb_device **devs, struct mach_id **pp_id,
+		const char *location)
 {
 	int i = 0;
+	int err;
 	struct mach_id *p;
 
 	for (;;) {
@@ -210,10 +271,24 @@ static libusb_device *find_imx_dev(libusb_device **devs, struct mach_id **pp_id)
 		}
 
 		p = imx_device(desc.idVendor, desc.idProduct);
-		if (p) {
-			*pp_id = p;
-			return dev;
+		if (!p)
+			continue;
+
+		err = libusb_open(dev, &usb_dev_handle);
+		if (err) {
+			fprintf(stderr, "Could not open device vid=0x%x pid=0x%x err=%d\n",
+				p->vid, p->pid, err);
+			continue;
+		}
+
+		if (location && !device_location_equal(dev, location)) {
+			libusb_close(usb_dev_handle);
+			usb_dev_handle = NULL;
+			continue;
 		}
+
+		*pp_id = p;
+		return dev;
 	}
 	*pp_id = NULL;
 
@@ -1280,6 +1355,7 @@ static void usage(const char *prgname)
 	fprintf(stderr, "usage: %s [OPTIONS] [FILENAME]\n\n"
 		"-c           check correctness of flashed image\n"
 		"-i <cfgfile> Specify custom SoC initialization file\n"
+		"-p <devpath> Specify device path: <bus>-<port>[.<port>]...\n"
 		"-s           skip DCD included in image\n"
 		"-v           verbose (give multiple times to increase)\n"
 		"-h           this help\n", prgname);
@@ -1300,10 +1376,11 @@ int main(int argc, char *argv[])
 	struct usb_work w = {};
 	int opt;
 	char *initfile = NULL;
+	char *devpath = NULL;
 
 	w.do_dcd_once = 1;
 
-	while ((opt = getopt(argc, argv, "cvhi:s")) != -1) {
+	while ((opt = getopt(argc, argv, "cvhi:p:s")) != -1) {
 		switch (opt) {
 		case 'c':
 			verify = 1;
@@ -1316,6 +1393,9 @@ int main(int argc, char *argv[])
 		case 'i':
 			initfile = optarg;
 			break;
+		case 'p':
+			devpath = optarg;
+			break;
 		case 's':
 			w.do_dcd_once = 0;
 			break;
@@ -1343,19 +1423,12 @@ int main(int argc, char *argv[])
 		goto out;
 	}
 
-	dev = find_imx_dev(devs, &mach);
+	dev = find_imx_dev(devs, &mach, devpath);
 	if (!dev) {
 		fprintf(stderr, "no supported device found\n");
 		goto out;
 	}
 
-	err = libusb_open(dev, &usb_dev_handle);
-	if (err) {
-		fprintf(stderr, "Could not open device vid=0x%x pid=0x%x err=%d\n",
-				mach->vid, mach->pid, err);
-		goto out;
-	}
-
 	libusb_free_device_list(devs, 1);
 
 	libusb_get_configuration(usb_dev_handle, &config);
-- 
2.11.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] scripts: imx imx-usb-loader: add usb path support
  2017-03-02 14:43 [PATCH v2] scripts: imx imx-usb-loader: add usb path support Oleksij Rempel
@ 2017-03-03  6:25 ` Sascha Hauer
  0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2017-03-03  6:25 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: barebox

On Thu, Mar 02, 2017 at 03:43:12PM +0100, Oleksij Rempel wrote:
> In some cases we need to work with more than one device attached
> to one host. For this situation we need path filter to make sure
> we talk with proper device.
> 
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> ---
>  changes v1:
>  - move loc before first if
>  - fix comment style
> 
>  scripts/imx/imx-usb-loader.c | 99 ++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 86 insertions(+), 13 deletions(-)

Applied, thanks

Sascha

> 
> diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c
> index be0894fa6..e8d746785 100644
> --- a/scripts/imx/imx-usb-loader.c
> +++ b/scripts/imx/imx-usb-loader.c
> @@ -45,6 +45,12 @@
>  #define FT_DCD	0xee
>  #define FT_LOAD_ONLY	0x00
>  
> +/*
> + * comment from libusb:
> + * As per the USB 3.0 specs, the current maximum limit for the depth is 7.
> + */
> +#define MAX_USB_PORTS	7
> +
>  int verbose;
>  static struct libusb_device_handle *usb_dev_handle;
>  static struct usb_id *usb_id;
> @@ -190,9 +196,64 @@ static struct mach_id *imx_device(unsigned short vid, unsigned short pid)
>  	return NULL;
>  }
>  
> -static libusb_device *find_imx_dev(libusb_device **devs, struct mach_id **pp_id)
> +static int device_location_equal(libusb_device *device, const char *location)
> +{
> +	uint8_t port_path[MAX_USB_PORTS];
> +	uint8_t dev_bus;
> +	int path_step, path_len;
> +	int result = 0;
> +	char *ptr, *loc;
> +
> +	/* strtok need non const char */
> +	loc = strdup(location);
> +
> +	path_len = libusb_get_port_numbers(device, port_path, MAX_USB_PORTS);
> +	if (path_len == LIBUSB_ERROR_OVERFLOW) {
> +		fprintf(stderr, "cannot determine path to usb device! (more than %i ports in path)\n",
> +			MAX_USB_PORTS);
> +		goto done;
> +	}
> +
> +	ptr = strtok(loc, "-");
> +	if (ptr == NULL) {
> +		printf("no '-' in path\n");
> +		goto done;
> +	}
> +
> +	dev_bus = libusb_get_bus_number(device);
> +	/* check bus mismatch */
> +	if (atoi(ptr) != dev_bus)
> +		goto done;
> +
> +	path_step = 0;
> +	while (path_step < MAX_USB_PORTS) {
> +		ptr = strtok(NULL, ".");
> +
> +		/* no more tokens in path */
> +		if (ptr == NULL)
> +			break;
> +
> +		/* path mismatch at some step */
> +		if (path_step < path_len && atoi(ptr) != port_path[path_step])
> +			break;
> +
> +		path_step++;
> +	};
> +
> +	/* walked the full path, all elements match */
> +	if (path_step == path_len)
> +		result = 1;
> +
> +done:
> +	free(loc);
> +	return result;
> +}
> +
> +static libusb_device *find_imx_dev(libusb_device **devs, struct mach_id **pp_id,
> +		const char *location)
>  {
>  	int i = 0;
> +	int err;
>  	struct mach_id *p;
>  
>  	for (;;) {
> @@ -210,10 +271,24 @@ static libusb_device *find_imx_dev(libusb_device **devs, struct mach_id **pp_id)
>  		}
>  
>  		p = imx_device(desc.idVendor, desc.idProduct);
> -		if (p) {
> -			*pp_id = p;
> -			return dev;
> +		if (!p)
> +			continue;
> +
> +		err = libusb_open(dev, &usb_dev_handle);
> +		if (err) {
> +			fprintf(stderr, "Could not open device vid=0x%x pid=0x%x err=%d\n",
> +				p->vid, p->pid, err);
> +			continue;
> +		}
> +
> +		if (location && !device_location_equal(dev, location)) {
> +			libusb_close(usb_dev_handle);
> +			usb_dev_handle = NULL;
> +			continue;
>  		}
> +
> +		*pp_id = p;
> +		return dev;
>  	}
>  	*pp_id = NULL;
>  
> @@ -1280,6 +1355,7 @@ static void usage(const char *prgname)
>  	fprintf(stderr, "usage: %s [OPTIONS] [FILENAME]\n\n"
>  		"-c           check correctness of flashed image\n"
>  		"-i <cfgfile> Specify custom SoC initialization file\n"
> +		"-p <devpath> Specify device path: <bus>-<port>[.<port>]...\n"
>  		"-s           skip DCD included in image\n"
>  		"-v           verbose (give multiple times to increase)\n"
>  		"-h           this help\n", prgname);
> @@ -1300,10 +1376,11 @@ int main(int argc, char *argv[])
>  	struct usb_work w = {};
>  	int opt;
>  	char *initfile = NULL;
> +	char *devpath = NULL;
>  
>  	w.do_dcd_once = 1;
>  
> -	while ((opt = getopt(argc, argv, "cvhi:s")) != -1) {
> +	while ((opt = getopt(argc, argv, "cvhi:p:s")) != -1) {
>  		switch (opt) {
>  		case 'c':
>  			verify = 1;
> @@ -1316,6 +1393,9 @@ int main(int argc, char *argv[])
>  		case 'i':
>  			initfile = optarg;
>  			break;
> +		case 'p':
> +			devpath = optarg;
> +			break;
>  		case 's':
>  			w.do_dcd_once = 0;
>  			break;
> @@ -1343,19 +1423,12 @@ int main(int argc, char *argv[])
>  		goto out;
>  	}
>  
> -	dev = find_imx_dev(devs, &mach);
> +	dev = find_imx_dev(devs, &mach, devpath);
>  	if (!dev) {
>  		fprintf(stderr, "no supported device found\n");
>  		goto out;
>  	}
>  
> -	err = libusb_open(dev, &usb_dev_handle);
> -	if (err) {
> -		fprintf(stderr, "Could not open device vid=0x%x pid=0x%x err=%d\n",
> -				mach->vid, mach->pid, err);
> -		goto out;
> -	}
> -
>  	libusb_free_device_list(devs, 1);
>  
>  	libusb_get_configuration(usb_dev_handle, &config);
> -- 
> 2.11.0
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-03-03  6:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-02 14:43 [PATCH v2] scripts: imx imx-usb-loader: add usb path support Oleksij Rempel
2017-03-03  6:25 ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox