usb_if: use the device with the matching serial number
There might be multiple devices with the same VID:PID connected to the host. Use the serial number to find the correct device if it is given. BUG=none BRANCH=none TEST=none Change-Id: I96f31e8e7ceb0dd2c3c643771b38752da88a2a9e Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1600500 Reviewed-by: Matthew Blecker <matthewb@chromium.org>
This commit is contained in:
parent
e02b08ceca
commit
d68548eebb
|
@ -2533,7 +2533,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (td.ep_type == usb_xfer) {
|
||||
if (usb_findit(vid, pid, USB_SUBCLASS_GOOGLE_CR50,
|
||||
if (usb_findit(NULL, vid, pid, USB_SUBCLASS_GOOGLE_CR50,
|
||||
USB_PROTOCOL_GOOGLE_CR50_NON_HC_FW_UPDATE,
|
||||
&td.uep))
|
||||
exit(update_error);
|
||||
|
|
|
@ -809,7 +809,7 @@ static int connect_to_ccd_i2c_bridge(struct common_hnd *chnd)
|
|||
{
|
||||
int rv;
|
||||
|
||||
rv = usb_findit(chnd->conf.usb_vid, chnd->conf.usb_pid,
|
||||
rv = usb_findit(NULL, chnd->conf.usb_vid, chnd->conf.usb_pid,
|
||||
CR50_I2C_SUBCLASS, CR50_I2C_PROTOCOL, &chnd->uep);
|
||||
|
||||
if (rv) {
|
||||
|
|
|
@ -66,26 +66,85 @@ out:
|
|||
return iface_num;
|
||||
}
|
||||
|
||||
int usb_findit(uint16_t vid, uint16_t pid, uint16_t subclass,
|
||||
uint16_t protocol, struct usb_endpoint *uep)
|
||||
static libusb_device_handle *check_device(libusb_device *dev,
|
||||
uint16_t vid, uint16_t pid, const char *serial)
|
||||
{
|
||||
int iface_num, r;
|
||||
struct libusb_device_descriptor desc;
|
||||
libusb_device_handle *handle = NULL;
|
||||
char sn[256];
|
||||
size_t sn_size = 0;
|
||||
|
||||
if (libusb_get_device_descriptor(dev, &desc) < 0)
|
||||
return NULL;
|
||||
|
||||
if (libusb_open(dev, &handle) != LIBUSB_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
if (desc.iSerialNumber && serial) {
|
||||
sn_size = libusb_get_string_descriptor_ascii(handle,
|
||||
desc.iSerialNumber, (unsigned char *)sn,
|
||||
sizeof(sn));
|
||||
}
|
||||
/*
|
||||
* If the VID, PID, and serial number don't match, then it's not the
|
||||
* correct device. Close the handle and return NULL.
|
||||
*/
|
||||
if ((vid && vid != desc.idVendor) ||
|
||||
(pid && pid != desc.idProduct) ||
|
||||
(serial && ((sn_size != strlen(serial)) ||
|
||||
memcmp(sn, serial, sn_size)))) {
|
||||
libusb_close(handle);
|
||||
return NULL;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
int usb_findit(const char *serial, uint16_t vid, uint16_t pid,
|
||||
uint16_t subclass, uint16_t protocol, struct usb_endpoint *uep)
|
||||
{
|
||||
int iface_num, r, i;
|
||||
libusb_device **devs;
|
||||
libusb_device_handle *devh = NULL;
|
||||
ssize_t count;
|
||||
|
||||
memset(uep, 0, sizeof(*uep));
|
||||
|
||||
/* Must supply either serial or vendor and product ids. */
|
||||
if (!serial && !(vid && pid))
|
||||
goto terminate_usb_findit;
|
||||
|
||||
r = libusb_init(NULL);
|
||||
if (r < 0) {
|
||||
USB_ERROR("libusb_init", r);
|
||||
goto terminate_usb_findit;
|
||||
}
|
||||
|
||||
printf("open_device %04x:%04x\n", vid, pid);
|
||||
/* NOTE: This doesn't handle multiple matches! */
|
||||
uep->devh = libusb_open_device_with_vid_pid(NULL, vid, pid);
|
||||
if (!uep->devh) {
|
||||
printf("finding_device ");
|
||||
if (vid)
|
||||
printf("%04x:%04x ", vid, pid);
|
||||
if (serial)
|
||||
printf("%s", serial);
|
||||
printf("\n");
|
||||
|
||||
count = libusb_get_device_list(NULL, &devs);
|
||||
if (count < 0)
|
||||
goto terminate_usb_findit;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
devh = check_device(devs[i], vid, pid, serial);
|
||||
if (devh) {
|
||||
printf("Found device.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_device_list(devs, 1);
|
||||
|
||||
if (!devh) {
|
||||
fprintf(stderr, "Can't find device\n");
|
||||
goto terminate_usb_findit;
|
||||
}
|
||||
uep->devh = devh;
|
||||
|
||||
iface_num = find_interface(subclass, protocol, uep);
|
||||
if (iface_num < 0) {
|
||||
|
|
|
@ -17,14 +17,16 @@ struct usb_endpoint {
|
|||
};
|
||||
|
||||
/*
|
||||
* Find the requested USB endpoint, as determined by vid, pid, subclass and
|
||||
* protocol parameters. If found, fill up the uep structure. If succeeded,
|
||||
* usb_shut_down() must be invoked before program exits.
|
||||
* Find the requested USB endpoint. This finds the device using the device
|
||||
* serial number, vendor id, and product id. The subclass and protocol are used
|
||||
* to find the correct endpoint. If a matching endpoint is found, fill up the
|
||||
* uep structure. If succeeded, usb_shut_down() must be invoked before program
|
||||
* exits.
|
||||
*
|
||||
* Return 0 on success, -1 on failure.
|
||||
*/
|
||||
int usb_findit(uint16_t vid, uint16_t pid, uint16_t subclass,
|
||||
uint16_t protocol, struct usb_endpoint *uep);
|
||||
int usb_findit(const char *serialno, uint16_t vid, uint16_t pid,
|
||||
uint16_t subclass, uint16_t protocol, struct usb_endpoint *uep);
|
||||
|
||||
/*
|
||||
* Actual USB transfer function, the 'allow_less' flag indicates that the
|
||||
|
|
Loading…
Reference in New Issue