int usb_find_devices(void) { struct libusb20_device *pdev; struct usb_device *udev; struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; int devnum; int err; /* cleanup after last device search */ /* close all opened devices, if any */ while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) { udev = pdev->privLuData; libusb20_be_dequeue_device(usb_backend, pdev); libusb20_dev_free(pdev); if (udev != NULL) { LIST_DEL(usb_global_bus.devices, udev); free(udev); } } /* free old USB backend, if any */ libusb20_be_free(usb_backend); /* do a new backend device search */ usb_backend = libusb20_be_alloc_default(); if (usb_backend == NULL) { return (-1); } /* iterate all devices */ devnum = 1; pdev = NULL; while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) { udev = malloc(sizeof(*udev)); if (udev == NULL) break; memset(udev, 0, sizeof(*udev)); udev->bus = &usb_global_bus; snprintf(udev->filename, sizeof(udev->filename), "/dev/ugen%u.%u", libusb20_dev_get_bus_number(pdev), libusb20_dev_get_address(pdev)); ddesc = libusb20_dev_get_device_desc(pdev); udev->descriptor.bLength = sizeof(udev->descriptor); udev->descriptor.bDescriptorType = ddesc->bDescriptorType; udev->descriptor.bcdUSB = ddesc->bcdUSB; udev->descriptor.bDeviceClass = ddesc->bDeviceClass; udev->descriptor.bDeviceSubClass = ddesc->bDeviceSubClass; udev->descriptor.bDeviceProtocol = ddesc->bDeviceProtocol; udev->descriptor.bMaxPacketSize0 = ddesc->bMaxPacketSize0; udev->descriptor.idVendor = ddesc->idVendor; udev->descriptor.idProduct = ddesc->idProduct; udev->descriptor.bcdDevice = ddesc->bcdDevice; udev->descriptor.iManufacturer = ddesc->iManufacturer; udev->descriptor.iProduct = ddesc->iProduct; udev->descriptor.iSerialNumber = ddesc->iSerialNumber; udev->descriptor.bNumConfigurations = ddesc->bNumConfigurations; if (udev->descriptor.bNumConfigurations > USB_MAXCONFIG) { /* truncate number of configurations */ udev->descriptor.bNumConfigurations = USB_MAXCONFIG; } udev->devnum = devnum++; /* link together the two structures */ udev->dev = pdev; pdev->privLuData = udev; err = libusb20_dev_open(pdev, 0); if (err == 0) { /* XXX get all config descriptors by default */ usb_fetch_and_parse_descriptors((void *)pdev); libusb20_dev_close(pdev); } LIST_ADD(usb_global_bus.devices, udev); } return (devnum - 1); /* success */ }
int usb_find_devices(void) { struct usb_bus *bus; int ret, changes = 0; for (bus = usb_busses; bus; bus = bus->next) { struct usb_device *devices, *dev; /* Find all of the devices and put them into a temporary list */ ret = usb_os_find_devices(bus, &devices); if (ret < 0) return ret; /* * Now walk through all of the devices we know about and compare * against this new list. Any duplicates will be removed from the new * list. If we don't find it in the new list, the device was removed. * Any devices still in the new list, are new to us. */ dev = bus->devices; while (dev) { int found = 0; struct usb_device *ndev, *tdev = dev->next; ndev = devices; while (ndev) { struct usb_device *tndev = ndev->next; if (!strcmp(dev->filename, ndev->filename)) { /* Remove it from the new devices list */ LIST_DEL(devices, ndev); usb_free_dev(ndev); found = 1; break; } ndev = tndev; } if (!found) { /* The device was removed from the system */ LIST_DEL(bus->devices, dev); usb_free_dev(dev); changes++; } dev = tdev; } /* * Anything on the *devices list is new. So add them to bus->devices and * process them like the new device it is. */ dev = devices; while (dev) { struct usb_device *tdev = dev->next; /* * Remove it from the temporary list first and add it to the real * bus->devices list. */ LIST_DEL(devices, dev); LIST_ADD(bus->devices, dev); /* * Some ports fetch the descriptors on scanning (like Linux) so we don't * need to fetch them again. */ if (!dev->config) { usb_dev_handle *udev; udev = usb_open(dev); if (udev) { usb_fetch_and_parse_descriptors(udev); usb_close(udev); } } changes++; dev = tdev; } usb_os_determine_children(bus); } return changes; }