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 <[email protected]>
> ---
>  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
> [email protected]
> 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
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to