On 04/28/2012 12:13 PM, Guannan Ren wrote: > usbFindDevice():get usb device according to > idVendor, idProduct, bus, device > it is the most strict search > > usbFindDevByBus():get usb device according to bus, device > it returns only one usb device same as usbFindDevice > > usbFindDevByVendor():get usb device according to idVendor,idProduct > it probably returns multiple usb devices. > > usbDeivceSearch(): a helper function to do the actual search Typo: s/Deivce/Device/ but unfortunately in the whole patch =) > --- > src/util/hostusb.c | 162 ++++++++++++++++++++++++++++++++++++++------------- > src/util/hostusb.h | 20 ++++++- > 2 files changed, 138 insertions(+), 44 deletions(-) > > diff --git a/src/util/hostusb.c b/src/util/hostusb.c > index 92f52a2..73dc959 100644 > --- a/src/util/hostusb.c > +++ b/src/util/hostusb.c > @@ -94,13 +94,22 @@ cleanup: > return ret; > } > > -static int usbFindBusByVendor(unsigned vendor, unsigned product, > - unsigned *bus, unsigned *devno) > +static usbDeviceList * > +usbDeivceSearch(unsigned vendor, > + unsigned product, > + unsigned bus, > + unsigned devno, > + unsigned flags) > { > DIR *dir = NULL; > - int ret = -1, found = 0; > + int found = 0; > char *ignore = NULL; > struct dirent *de; > + usbDeviceList *list = NULL, *ret = NULL; > + usbDevice *usb; > + > + if (!(list = usbDeviceListNew())) > + goto cleanup; > > dir = opendir(USB_SYSFS "/devices"); > if (!dir) { > @@ -111,48 +120,72 @@ static int usbFindBusByVendor(unsigned vendor, unsigned product, > } > > while ((de = readdir(dir))) { > - unsigned found_prod, found_vend; > + unsigned found_prod, found_vend, found_bus, found_devno; > + char *tmpstr = de->d_name; > + > if (de->d_name[0] == '.' || strchr(de->d_name, ':')) > continue; > > if (usbSysReadFile("idVendor", de->d_name, > 16, &found_vend) < 0) > goto cleanup; > + > if (usbSysReadFile("idProduct", de->d_name, > 16, &found_prod) < 0) > goto cleanup; > > - if (found_prod == product && found_vend == vendor) { > - /* Lookup bus.addr info */ > - char *tmpstr = de->d_name; > - unsigned found_bus, found_addr; > + if (STRPREFIX(de->d_name, "usb")) > + tmpstr += 3; > > - if (STRPREFIX(de->d_name, "usb")) > - tmpstr += 3; > + if (virStrToLong_ui(tmpstr, &ignore, 10, &found_bus) < 0) { > + usbReportError(VIR_ERR_INTERNAL_ERROR, > + _("Failed to parse dir name '%s'"), > + de->d_name); > + goto cleanup; > + } > + > + if (usbSysReadFile("devnum", de->d_name, > + 10, &found_devno) < 0) > + goto cleanup; > > - if (virStrToLong_ui(tmpstr, &ignore, 10, &found_bus) < 0) { > - usbReportError(VIR_ERR_INTERNAL_ERROR, > - _("Failed to parse dir name '%s'"), > - de->d_name); > - goto cleanup; > - } > + switch (flags) { > + /* > + * Don't set found to 1 in order to continue the loop > + * to find multiple USB devices with same idVendor and idProduct > + */ > + case USB_DEVICE_FIND_BY_VENDOR: > + if (found_prod != product || found_vend != vendor) > + continue; > + break; > > - if (usbSysReadFile("devnum", de->d_name, > - 10, &found_addr) < 0) > - goto cleanup; > + case USB_DEVICE_FIND_BY_BUS: > + if (found_bus != bus || found_devno != devno) > + continue; > + found = 1; > + break; > > - *bus = found_bus; > - *devno = found_addr; > + case USB_DEVICE_FIND_BY_ALL: > + if (found_prod != product > + || found_vend != vendor > + || found_bus != bus > + || found_devno != devno) > + continue; > found = 1; > break; > } > - } > > - if (!found) > - usbReportError(VIR_ERR_INTERNAL_ERROR, > - _("Did not find USB device %x:%x"), vendor, product); > - else > - ret = 0; > + usb = usbGetDevice(found_bus, found_devno); > + if (!usb) > + goto cleanup; > + > + if (usbDeviceListAdd(list, usb) < 0) { > + usbFreeDevice(usb); > + goto cleanup; > + } > + > + if (found) break; > + } > + ret = list; > > cleanup: > if (dir) { > @@ -160,9 +193,69 @@ cleanup: > closedir (dir); > errno = saved_errno; > } > + > + if (!ret) > + usbDeviceListFree(list); > return ret; > } > > +usbDeviceList * > +usbFindDevByVendor(unsigned vendor, unsigned product) > +{ > + > + usbDeviceList *list; > + if (!(list = usbDeivceSearch(vendor, product, 0 , 0, USB_DEVICE_FIND_BY_VENDOR))) > + return NULL; > + > + if (list->count == 0) { > + usbReportError(VIR_ERR_INTERNAL_ERROR, > + _("Did not find USB device %x:%x"), vendor, product); > + usbDeviceListFree(list); > + return NULL; > + } > + > + return list; > +} > + > +usbDevice * > +usbFindDevByBus(unsigned bus, unsigned devno) > +{ > + usbDeviceList *list; > + if (!(list = usbDeivceSearch(0, 0, bus, devno, USB_DEVICE_FIND_BY_BUS))) > + return NULL; > + > + if (list->count == 0) { > + usbReportError(VIR_ERR_INTERNAL_ERROR, > + _("Did not find USB device bus:%u device:%u"), bus, devno); > + usbDeviceListFree(list); > + return NULL; > + } > + > + return usbDeviceListGet(list, 0); > +} > + > +usbDevice * > +usbFindDevice(unsigned vendor, > + unsigned product, > + unsigned bus, > + unsigned devno) > +{ > + usbDeviceList *list; > + if (!(list = usbDeivceSearch(vendor, product, > + bus, devno, USB_DEVICE_FIND_BY_ALL))) > + return NULL; > + > + if (list->count == 0) { > + usbReportError(VIR_ERR_INTERNAL_ERROR, > + _("Did not find USB device %x:%x bus:%u device:%u"), > + vendor, product, bus, devno); > + usbDeviceListFree(list); > + return NULL; > + } > + > + return usbDeviceListGet(list, 0); > +} > + > usbDevice * > usbGetDevice(unsigned bus, > unsigned devno) > @@ -207,21 +300,6 @@ usbGetDevice(unsigned bus, > return dev; > } > > - > -usbDevice * > -usbFindDevice(unsigned vendor, > - unsigned product) > -{ > - unsigned bus = 0, devno = 0; > - > - if (usbFindBusByVendor(vendor, product, &bus, &devno) < 0) { > - return NULL; > - } > - > - return usbGetDevice(bus, devno); > -} > - > - > void > usbFreeDevice(usbDevice *dev) > { > diff --git a/src/util/hostusb.h b/src/util/hostusb.h > index afaa32f..7f18bce 100644 > --- a/src/util/hostusb.h > +++ b/src/util/hostusb.h > @@ -28,10 +28,26 @@ > typedef struct _usbDevice usbDevice; > typedef struct _usbDeviceList usbDeviceList; > > +typedef enum { > + USB_DEVICE_FIND_BY_VENDOR = 0, > + USB_DEVICE_FIND_BY_BUS = 1 << 0, > + USB_DEVICE_FIND_BY_ALL = 1 << 1, > +} usbDeviceFindFlags; > + > usbDevice *usbGetDevice(unsigned bus, > unsigned devno); > -usbDevice *usbFindDevice(unsigned vendor, > - unsigned product); > + > +usbDevice * usbFindDevByBus(unsigned bus, > + unsigned devno); > + > +usbDeviceList * usbFindDevByVendor(unsigned vendor, > + unsigned product); > + > +usbDevice * usbFindDevice(unsigned vendor, > + unsigned product, > + unsigned bus, > + unsigned devno); > + > void usbFreeDevice (usbDevice *dev); > void usbDeviceSetUsedBy(usbDevice *dev, const char *name); > const char *usbDeviceGetUsedBy(usbDevice *dev); -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list