Re: [libvirt] [PATCH v2 1/3] usb: create functions to search usb device accurately
On 05/03/2012 01:17 AM, Osier Yang wrote: On 2012年05月01日 16:16, 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 Should we name it as usbFindDevByAddress? Given that both 'bus' and 'device' are used to find the device actually. the term 'address' for usb device is used by kernel maybe not a good name. The codes has been changed according to the following comments { 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())) virReportOOMError(); usbDeviceListNew has raised OOM Error in that case. Guannan Ren -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/3] usb: create functions to search usb device accurately
On 05/01/2012 10:16 AM, 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. usbDeviceSearch(): a helper function to do the actual search --- 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 * +usbDeviceSearch(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;
Re: [libvirt] [PATCH v2 1/3] usb: create functions to search usb device accurately
On 05/01/2012 02:16 AM, 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. usbDeviceSearch(): a helper function to do the actual search --- src/util/hostusb.c | 162 ++- src/util/hostusb.h | 20 ++- 2 files changed, 138 insertions(+), 44 deletions(-) Looks like a reasonable set of functions from the description. It feels a bit weird to have FindDevice spelled out but FindDevByBus abbreviated; should we rename it to FindDeviceByBus? 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 * +usbDeviceSearch(unsigned vendor, +unsigned product, +unsigned bus, +unsigned devno, +unsigned flags) Since this function is static, I think the enum that controls its behavior should live in this C file, rather than in a header included by other files that can't use this function. { DIR *dir = NULL; -int ret = -1, found = 0; +int found = 0; Is found a count (incremented for each hit) or a boolean (set to true when we find one, regardless of whether we find more)? If the latter, then s/int/bool/; s/0/false/ char *ignore = NULL; +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: I think this is not quite right. Your flags should be a bitmask: FIND_BY_VENDOR = 1, FIND_BY_BUS = 2, Then you do this pseudocode: if (flags USB_DEVICE_FIND_BY_VENDOR) continue loop unless product and vendor match if (flags USB_DEVICE_FIND_BY_BUS) continue loop unless bus and devno match if we get this far, update found This would also let you pass in flags of 0 to search for _all_ USB devices , without regards to vendor or bus (we don't have a function for this right now, but could add one if needed), as well as passing in flags of 3 (BY_VENDOR|BY_BUS) to do an exact match of all four parameters (this would be usbFindDevice). + +if (found) break; Coding conventions request writing this as two lines. +usbDevice * +usbFindDevice(unsigned vendor, + unsigned product, + unsigned bus, + unsigned devno) +{ +usbDeviceList *list; +if (!(list = usbDeviceSearch(vendor, product, + bus, devno, USB_DEVICE_FIND_BY_ALL))) +return NULL; Allocates a list... + +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); and returns the first element of the list, but loses the reference to the list itself. Memory leak. +typedef enum { +USB_DEVICE_FIND_BY_VENDOR = 0, +USB_DEVICE_FIND_BY_BUS = 1 0, +USB_DEVICE_FIND_BY_ALL = 1 1, +} usbDeviceFindFlags; See above - this enum should live in the .c file before the static function it affects, and should be a bit-mask of two separate filtering features. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/3] usb: create functions to search usb device accurately
On 2012年05月01日 16:16, 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 Should we name it as usbFindDevByAddress? Given that both 'bus' and 'device' are used to find the device actually. it returns only one usb device same as usbFindDevice usbFindDevByVendor():get usb device according to idVendor,idProduct it probably returns multiple usb devices. usbDeviceSearch(): a helper function to do the actual search --- 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 * +usbDeviceSearch(unsigned vendor, +unsigned product, +unsigned bus, +unsigned devno, +unsigned flags) Though no difference between 'unsigned' and 'unsigned int', expect more typing, should we keep consistent across the project? I.e. Don't introduce new 'unsigned', and substitute it with 'unsigned int' as a follow up patch. { 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())) virReportOOMError(); +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) As a habit: if (found_prod != product || found_vend != vendor || found_bus != bus || found_devno != devno) +continue; found = 1; Given 'found' can only be '0' and '1', why not boolean? 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) { +
[libvirt] [PATCH v2 1/3] usb: create functions to search usb device accurately
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. usbDeviceSearch(): a helper function to do the actual search --- 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 * +usbDeviceSearch(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 = usbDeviceSearch(vendor, product, 0 , 0, USB_DEVICE_FIND_BY_VENDOR))) +return NULL; + +if (list-count == 0) { +usbReportError(VIR_ERR_INTERNAL_ERROR, +