示例#1
0
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);
}
示例#2
0
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);
}
示例#3
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 */
}
示例#4
0
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);
}
示例#5
0
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);
}
示例#6
0
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 */
}
示例#7
0
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);
}
示例#8
0
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);
}
示例#9
0
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);
}
示例#10
0
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);
}
示例#11
0
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);
}
示例#12
0
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);
}