void usb_set_config_test(uint16_t vid, uint16_t pid, uint32_t duration) { struct libusb20_device *pdev; struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; int x; int error; int failed; int exp; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 0); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } failed = 0; printf("Starting set config test for " "VID=0x%04x PID=0x%04x\n", vid, pid); for (x = 255; x > -1; x--) { error = libusb20_dev_set_config_index(pdev, x); if (error == 0) { if (x == 255) { printf("Unconfiguring USB device " "was successful\n"); } else { printf("Setting configuration %d " "was successful\n", x); } } else { failed++; } } ddesc = libusb20_dev_get_device_desc(pdev); if (ddesc != NULL) exp = ddesc->bNumConfigurations + 1; else exp = 1; printf("\n\n" "Set configuration summary\n" "Valid count: %d/%d %s\n" "Failed count: %d\n", 256 - failed, exp, (exp == (256 - failed)) ? "(expected)" : "(unexpected)", failed); libusb20_dev_free(pdev); }
int usb_close(usb_dev_handle * udev) { struct usb_device *dev; int err; err = libusb20_dev_close((void *)udev); if (err) return (-1); if (usb_backend != NULL) { /* * Enqueue USB device to backend queue so that it gets freed * when the backend is re-scanned: */ libusb20_be_enqueue_device(usb_backend, (void *)udev); } else { /* * The backend is gone. Free device data so that we * don't start leaking memory! */ dev = usb_device(udev); libusb20_dev_free((void *)udev); LIST_DEL(usb_global_bus.devices, dev); free(dev); } return (0); }
static int ugen20_init_backend(struct libusb20_backend *pbe) { struct ugen20_urd_state state; struct libusb20_device *pdev; memset(&state, 0, sizeof(state)); state.f = open("/dev/" USB_DEVICE_NAME, O_RDONLY); if (state.f < 0) return (LIBUSB20_ERROR_OTHER); while (ugen20_readdir(&state) == 0) { if ((state.src[0] != 'u') || (state.src[1] != 'g') || (state.src[2] != 'e') || (state.src[3] != 'n')) { continue; } pdev = libusb20_dev_alloc(); if (pdev == NULL) { continue; } if (ugen20_enumerate(pdev, state.src + 4)) { libusb20_dev_free(pdev); continue; } /* put the device on the backend list */ libusb20_be_enqueue_device(pbe, pdev); } close(state.f); return (0); /* success */ }
void usb_get_descriptor_test(uint16_t vid, uint16_t pid, uint32_t duration) { struct libusb20_device *pdev; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } libusb20_dev_free(pdev); }
static void exec_host_modem_test(struct modem *p, uint16_t vid, uint16_t pid) { struct libusb20_device *pdev; uint8_t ntest = 0; uint8_t x; uint8_t in_ep; uint8_t out_ep; uint8_t iface; int error; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } if (p->use_vendor_specific) find_usb_endpoints(pdev, 255, 255, 255, 0, &iface, &in_ep, &out_ep, 0); else find_usb_endpoints(pdev, 2, 2, 1, 0, &iface, &in_ep, &out_ep, 1); if ((in_ep == 0) || (out_ep == 0)) { printf("Could not find USB endpoints\n"); libusb20_dev_free(pdev); return; } printf("Attaching to: %s @ iface %d\n", libusb20_dev_get_desc(pdev), iface); if (libusb20_dev_open(pdev, 2)) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } if (libusb20_dev_detach_kernel_driver(pdev, iface)) { printf("WARNING: Could not detach kernel driver\n"); } p->xfer_in = libusb20_tr_get_pointer(pdev, 0); error = libusb20_tr_open(p->xfer_in, 65536 / 4, 1, in_ep); if (error) { printf("Could not open USB endpoint %d\n", in_ep); libusb20_dev_free(pdev); return; } p->xfer_out = libusb20_tr_get_pointer(pdev, 1); error = libusb20_tr_open(p->xfer_out, 65536 / 4, 1, out_ep); if (error) { printf("Could not open USB endpoint %d\n", out_ep); libusb20_dev_free(pdev); return; } p->usb_dev = pdev; p->usb_iface = iface; p->errors = 0; if (p->control_ep_test) ntest += 7; if (p->data_stress_test) ntest += 1; if (ntest == 0) { printf("No tests selected\n"); } else { if (p->control_ep_test) { for (x = 1; x != 8; x++) { usb_modem_control_ep_test(p, (p->duration + ntest - 1) / ntest, x); } } if (p->data_stress_test) { usb_modem_data_stress_test(p, (p->duration + ntest - 1) / ntest); } } printf("\nDone\n"); libusb20_dev_free(pdev); }
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 */ }
void usb_control_ep_error_test(uint16_t vid, uint16_t pid) { struct LIBUSB20_CONTROL_SETUP_DECODED req; struct libusb20_device *pdev; uint8_t buffer[256]; int error; int fail = 0; int bus; int dev; int cfg; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 0); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } bus = libusb20_dev_get_bus_number(pdev); dev = libusb20_dev_get_address(pdev); for (cfg = 0; cfg != 255; cfg++) { LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req); req.bmRequestType = 0x80; /* read */ req.bRequest = 0x06; /* descriptor */ req.wValue = 0x0200 | cfg; /* config descriptor */ req.wIndex = 0; req.wLength = 255; printf("Test #%d.1/3 ...\n", cfg); set_ctrl_ep_fail(-1,-1,0,0); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); if (error != 0) { printf("Last configuration index is: %d\n", cfg - 1); break; } printf("Test #%d.2/3 ...\n", cfg); set_ctrl_ep_fail(bus,dev,1,1); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); set_ctrl_ep_fail(-1,-1,0,0); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); if (error != 0) { printf("Cannot fetch descriptor (unexpected)\n"); fail++; } printf("Test #%d.3/3 ...\n", cfg); set_ctrl_ep_fail(bus,dev,0,1); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); set_ctrl_ep_fail(-1,-1,0,0); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); if (error != 0) { printf("Cannot fetch descriptor (unexpected)\n"); fail++; } } libusb20_dev_close(pdev); libusb20_dev_free(pdev); printf("Test completed detecting %d failures\nDone\n\n", fail); }
void usb_set_alt_interface_test(uint16_t vid, uint16_t pid) { struct libusb20_device *pdev; struct libusb20_config *config; int iter; int error; int errcnt; int n; int m; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } printf("Starting set alternate setting test " "for VID=0x%04x PID=0x%04x\n", vid, pid); config = libusb20_dev_alloc_config(pdev, libusb20_dev_get_config_index(pdev)); if (config == NULL) { printf("Could not get configuration descriptor\n"); libusb20_dev_free(pdev); return; } iter = 0; errcnt = 0; for (n = 0; n != config->num_interface; n++) { /* detach kernel driver */ libusb20_dev_detach_kernel_driver(pdev, n); error = libusb20_dev_open(pdev, 0); if (error) printf("ERROR could not open device\n"); /* Try the alternate settings */ for (m = 0; m != config->interface[n].num_altsetting; m++) { iter++; if (libusb20_dev_set_alt_index(pdev, n, m + 1)) { printf("ERROR on interface %d alt %d\n", n, m + 1); errcnt++; } } /* Restore to default */ iter++; if (libusb20_dev_set_alt_index(pdev, n, 0)) { printf("ERROR on interface %d alt %d\n", n, 0); errcnt++; } libusb20_dev_close(pdev); } libusb20_dev_free(pdev); printf("\n" "Test summary\n" "============\n" "Interfaces tested: %d\n" "Errors: %d\n", iter, errcnt); }
void usb_set_and_clear_stall_test(uint16_t vid, uint16_t pid) { struct libusb20_device *pdev; struct libusb20_transfer *pxfer; int iter; int error; int errcnt; int ep; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 1); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } printf("Starting set and clear stall test " "for VID=0x%04x PID=0x%04x\n", vid, pid); iter = 0; errcnt = 0; for (ep = 2; ep != 32; ep++) { struct LIBUSB20_CONTROL_SETUP_DECODED setup_set_stall; struct LIBUSB20_CONTROL_SETUP_DECODED setup_get_status; uint8_t epno = ((ep / 2) | ((ep & 1) << 7)); uint8_t buf[1]; LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup_set_stall); setup_set_stall.bmRequestType = 0x02; /* write endpoint */ setup_set_stall.bRequest = 0x03; /* set feature */ setup_set_stall.wValue = 0x00; /* UF_ENDPOINT_HALT */ setup_set_stall.wIndex = epno; setup_set_stall.wLength = 0; LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup_get_status); setup_get_status.bmRequestType = 0x82; /* read endpoint */ setup_get_status.bRequest = 0x00; /* get status */ setup_get_status.wValue = 0x00; setup_get_status.wIndex = epno; setup_get_status.wLength = 1; if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } pxfer = libusb20_tr_get_pointer(pdev, 0); error = libusb20_tr_open(pxfer, 1, 1, epno); if (error != 0) { printf("Endpoint 0x%02x does not exist " "in current setting. (%s, ignored)\n", epno, libusb20_strerror(error)); continue; } printf("Stalling endpoint 0x%02x\n", epno); /* set stall */ error = libusb20_dev_request_sync(pdev, &setup_set_stall, NULL, NULL, 250, 0); if (error != 0) { printf("Endpoint 0x%02x does not allow " "setting of stall. (%s)\n", epno, libusb20_strerror(error)); errcnt++; } /* get EP status */ buf[0] = 0; error = libusb20_dev_request_sync(pdev, &setup_get_status, buf, NULL, 250, 0); if (error != 0) { printf("Endpoint 0x%02x does not allow " "reading status. (%s)\n", epno, libusb20_strerror(error)); errcnt++; } else { if (!(buf[0] & 1)) { printf("Endpoint 0x%02x status is " "not set to stalled\n", epno); errcnt++; } } buf[0] = 0; error = libusb20_tr_bulk_intr_sync(pxfer, buf, 1, NULL, 250); if (error != LIBUSB20_TRANSFER_STALL) { printf("Endpoint 0x%02x does not appear to " "have stalled. Missing stall PID!\n", epno); errcnt++; } printf("Unstalling endpoint 0x%02x\n", epno); libusb20_tr_clear_stall_sync(pxfer); /* get EP status */ buf[0] = 0; error = libusb20_dev_request_sync(pdev, &setup_get_status, buf, NULL, 250, 0); if (error != 0) { printf("Endpoint 0x%02x does not allow " "reading status. (%s)\n", epno, libusb20_strerror(error)); errcnt++; } else { if (buf[0] & 1) { printf("Endpoint 0x%02x status is " "still stalled\n", epno); errcnt++; } } libusb20_tr_close(pxfer); iter++; } libusb20_dev_free(pdev); printf("\n" "Test summary\n" "============\n" "Endpoints tested: %d\n" "Errors: %d\n", iter, errcnt); }
void usb_suspend_resume_test(uint16_t vid, uint16_t pid, uint32_t duration) { struct timeval sub_tv; struct timeval ref_tv; struct timeval res_tv; struct libusb20_device *pdev; time_t last_sec; int iter; int error; int ptimo; int errcnt; int power_old; ptimo = 1; /* second(s) */ error = sysctlbyname("hw.usb.power_timeout", NULL, NULL, &ptimo, sizeof(ptimo)); if (error != 0) { printf("WARNING: Could not set power " "timeout to 1 (error=%d) \n", errno); } pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 0); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } power_old = libusb20_dev_get_power_mode(pdev); printf("Starting suspend and resume " "test for VID=0x%04x PID=0x%04x\n", vid, pid); iter = 0; errcnt = 0; gettimeofday(&ref_tv, 0); last_sec = ref_tv.tv_sec; while (1) { if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } gettimeofday(&sub_tv, 0); if (last_sec != sub_tv.tv_sec) { printf("STATUS: ID=%u, ERR=%u\n", (int)iter, (int)errcnt); fflush(stdout); last_sec = sub_tv.tv_sec; } timersub(&sub_tv, &ref_tv, &res_tv); if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration)) break; error = libusb20_dev_set_power_mode(pdev, (iter & 1) ? LIBUSB20_POWER_ON : LIBUSB20_POWER_SAVE); if (error) errcnt++; /* wait before switching power mode */ usleep(4100000 + (((uint32_t)usb_ts_rand_noise()) % 2000000U)); iter++; } /* restore default power mode */ libusb20_dev_set_power_mode(pdev, power_old); libusb20_dev_free(pdev); }
void usb_port_reset_test(uint16_t vid, uint16_t pid, uint32_t duration) { struct timeval sub_tv; struct timeval ref_tv; struct timeval res_tv; struct libusb20_device *pdev; int error; int iter; int errcnt; time_t last_sec; /* sysctl() - no set config */ pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 0); if (error) { libusb20_dev_free(pdev); printf("Could not open USB device\n"); return; } iter = 0; errcnt = 0; gettimeofday(&ref_tv, 0); last_sec = ref_tv.tv_sec; while (1) { gettimeofday(&sub_tv, 0); if (last_sec != sub_tv.tv_sec) { printf("STATUS: ID=%u, ERR=%u\n", (int)iter, (int)errcnt); fflush(stdout); last_sec = sub_tv.tv_sec; } timersub(&sub_tv, &ref_tv, &res_tv); if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration)) break; if (libusb20_dev_reset(pdev)) { errcnt++; usleep(50000); } if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } iter++; } libusb20_dev_reset(pdev); libusb20_dev_free(pdev); }
void usb_get_string_desc_test(uint16_t vid, uint16_t pid) { struct libusb20_device *pdev; uint32_t x; uint32_t y; uint32_t valid; uint8_t *buf; int error; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 0); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } buf = malloc(256); if (buf == NULL) { printf("Cannot allocate memory\n"); libusb20_dev_free(pdev); return; } valid = 0; printf("Starting string descriptor test for " "VID=0x%04x PID=0x%04x\n", vid, pid); for (x = 0; x != 256; x++) { if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } printf("%d .. ", (int)x); fflush(stdout); error = libusb20_dev_req_string_simple_sync(pdev, x, buf, 255); if (error == 0) { printf("\nINDEX=%d, STRING='%s' (Default language)\n", (int)x, buf); fflush(stdout); } else { continue; } valid = 0; for (y = 0; y != 65536; y++) { if (libusb20_dev_check_connected(pdev) != 0) { printf("Device disconnected\n"); break; } error = libusb20_dev_req_string_sync(pdev, x, y, buf, 256); if (error == 0) valid++; } printf("String at INDEX=%d responds to %d " "languages\n", (int)x, (int)valid); } printf("\nDone\n"); free(buf); libusb20_dev_free(pdev); }