summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorOleksij Rempel <o.rempel@pengutronix.de>2017-03-02 15:43:12 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-03-03 07:24:07 +0100
commit65c50e5859c5886283b92ef178d0bcabeeeb0cf0 (patch)
tree708f0f6a473616650d058cab76ba815f471a33bd /scripts
parent6d76aaf1bc38d4fa07315843c00607393cbe1796 (diff)
downloadbarebox-65c50e5859c5886283b92ef178d0bcabeeeb0cf0.tar.gz
barebox-65c50e5859c5886283b92ef178d0bcabeeeb0cf0.tar.xz
scripts: imx imx-usb-loader: add usb path support
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> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/imx/imx-usb-loader.c99
1 files changed, 86 insertions, 13 deletions
diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c
index 4105adeda9..2c8a118923 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;
@@ -197,9 +203,64 @@ static const struct mach_id *imx_device(unsigned short vid, unsigned short pid)
return NULL;
}
-static libusb_device *find_imx_dev(libusb_device **devs, const 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, const struct mach_id **pp_id,
+ const char *location)
{
int i = 0;
+ int err;
const struct mach_id *p;
for (;;) {
@@ -217,10 +278,24 @@ static libusb_device *find_imx_dev(libusb_device **devs, const struct mach_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;
@@ -1378,6 +1453,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);
@@ -1398,10 +1474,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;
@@ -1414,6 +1491,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;
@@ -1441,19 +1521,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);