[PATCH v2] scripts: imx imx-usb-loader: add usb path support
Sascha Hauer
s.hauer at pengutronix.de
Thu Mar 2 22:25:09 PST 2017
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 at 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 at 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 |
More information about the barebox
mailing list