Skip to content

Commit

Permalink
usb: Allow selecting board by serial number
Browse files Browse the repository at this point in the history
When working on a host with multiple boards attached being able to
select a specific board by serial number becomes necessary.

In the EDL USB descriptors a device serial number is available as part
of the iProduct string, so this can be used for comparison.

As libusb requires a handle the libusb_open() needs to be moved into the
loop.

Signed-off-by: Bjorn Andersson <[email protected]>
  • Loading branch information
quic-bjorande committed May 8, 2024
1 parent 399b3fd commit 60485ad
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 29 deletions.
9 changes: 7 additions & 2 deletions qdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ int main(int argc, char **argv)
{
char *prog_mbn, *storage="ufs";
char *incdir = NULL;
char *serial = NULL;
int type;
int ret;
int opt;
Expand All @@ -115,11 +116,12 @@ int main(int argc, char **argv)
{"debug", no_argument, 0, 'd'},
{"include", required_argument, 0, 'i'},
{"finalize-provisioning", no_argument, 0, 'l'},
{"serial", required_argument, 0, 'S'},
{"storage", required_argument, 0, 's'},
{0, 0, 0, 0}
};

while ((opt = getopt_long(argc, argv, "di:", options, NULL )) != -1) {
while ((opt = getopt_long(argc, argv, "di:S:", options, NULL )) != -1) {
switch (opt) {
case 'd':
qdl_debug = true;
Expand All @@ -133,6 +135,9 @@ int main(int argc, char **argv)
case 's':
storage = optarg;
break;
case 'S':
serial = optarg;
break;
default:
print_usage();
return 1;
Expand Down Expand Up @@ -174,7 +179,7 @@ int main(int argc, char **argv)
}
} while (++optind < argc);

ret = qdl_open(&qdl);
ret = qdl_open(&qdl, serial);
if (ret)
return 1;

Expand Down
2 changes: 1 addition & 1 deletion qdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct qdl_device {
char *mappings[MAPPING_SZ]; // array index is the id from the device
};

int qdl_open(struct qdl_device *qdl);
int qdl_open(struct qdl_device *qdl, const char *serial);
int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout);
int qdl_write(struct qdl_device *qdl, const void *buf, size_t len);

Expand Down
9 changes: 7 additions & 2 deletions ramdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,28 @@ int main(int argc, char **argv)
struct qdl_device qdl;
char *ramdump_path = ".";
char *filter = NULL;
char *serial = NULL;
int ret;
int opt;

static struct option options[] = {
{"debug", no_argument, 0, 'd'},
{"output", required_argument, 0, 'o'},
{"serial", required_argument, 0, 'S'},
{0, 0, 0, 0}
};

while ((opt = getopt_long(argc, argv, "do:", options, NULL )) != -1) {
while ((opt = getopt_long(argc, argv, "do:S:", options, NULL )) != -1) {
switch (opt) {
case 'd':
qdl_debug = true;
break;
case 'o':
ramdump_path = optarg;
break;
case 'S':
serial = optarg;
break;
default:
print_usage();
}
Expand All @@ -49,7 +54,7 @@ int main(int argc, char **argv)
if (optind != argc)
print_usage();

ret = qdl_open(&qdl);
ret = qdl_open(&qdl, serial);
if (ret)
return 1;

Expand Down
80 changes: 56 additions & 24 deletions usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,48 @@
#include <sys/types.h>
#include <err.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libusb-1.0/libusb.h>

#include "qdl.h"

static int qdl_parse_usb_descriptors(libusb_device *dev, struct qdl_device *qdl, int *intf)
static bool qdl_match_usb_serial(struct libusb_device_handle *handle, const char *serial,
const struct libusb_device_descriptor *desc)
{
char buf[128];
char *p;
int ret;

/* If no serial is requested, consider everything a match */
if (!serial)
return true;

ret = libusb_get_string_descriptor_ascii(handle, desc->iProduct, (unsigned char *)buf, sizeof(buf));
if (ret < 0) {
warnx("failed to read iProduct descriptor: %s", libusb_strerror(ret));
return false;
}

p = strstr(buf, "_SN:");
if (!p)
return false;

p += strlen("_SN:");
p[strcspn(p, " _")] = '\0';

return strcmp(p, serial) == 0;
}

static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char *serial)
{
const struct libusb_endpoint_descriptor *endpoint;
const struct libusb_interface_descriptor *ifc;
struct libusb_config_descriptor *config;
struct libusb_device_descriptor desc;
struct libusb_device_handle *handle;
size_t out_size;
size_t in_size;
uint8_t type;
Expand Down Expand Up @@ -78,26 +107,42 @@ static int qdl_parse_usb_descriptors(libusb_device *dev, struct qdl_device *qdl,
ifc->bInterfaceProtocol != 17)
continue;

ret = libusb_open(dev, &handle);
if (ret < 0) {
warnx("unable to open USB device");
continue;
}

if (!qdl_match_usb_serial(handle, serial, &desc)) {
libusb_close(handle);
continue;
}

ret = libusb_claim_interface(handle, ifc->bInterfaceNumber);
if (ret < 0) {
warnx("failed to claim USB interface");
libusb_close(handle);
continue;
}

qdl->usb_handle = handle;
qdl->in_ep = in;
qdl->out_ep = out;
qdl->in_maxpktsize = in_size;
qdl->out_maxpktsize = out_size;

*intf = ifc->bInterfaceNumber;

return 1;
}

return 0;
}

int qdl_open(struct qdl_device *qdl)
int qdl_open(struct qdl_device *qdl, const char *serial)
{
struct libusb_device_handle *handle;
struct libusb_device **devs;
struct libusb_device *dev;
bool wait_printed = false;
int intf_num;
bool found = false;
ssize_t n;
int ret;
int i;
Expand All @@ -114,29 +159,16 @@ int qdl_open(struct qdl_device *qdl)
for (i = 0; devs[i]; i++) {
dev = devs[i];

ret = qdl_parse_usb_descriptors(dev, qdl, &intf_num);
if (ret != 1)
continue;

ret = libusb_open(dev, &handle);
if (ret < 0) {
warnx("unable to open USB device");
continue;
ret = qdl_try_open(dev, qdl, serial);
if (ret == 1) {
found = true;
break;
}

ret = libusb_claim_interface(handle, intf_num);
if (ret < 0) {
warnx("failed to claim USB interface");
libusb_close(handle);
}

qdl->usb_handle = handle;
break;
}

libusb_free_device_list(devs, 1);

if (qdl->usb_handle)
if (found)
return 0;

if (!wait_printed) {
Expand Down

0 comments on commit 60485ad

Please sign in to comment.