Esempio n. 1
0
static void
do_msc_reset(uint8_t lun)
{
	struct LIBUSB20_CONTROL_SETUP_DECODED setup;

	LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup);

	setup.bmRequestType = LIBUSB20_REQUEST_TYPE_CLASS |
	    LIBUSB20_RECIPIENT_INTERFACE;
	setup.bRequest = 0xFF;		/* BBB reset */
	setup.wValue = 0;
	setup.wIndex = usb_iface;
	setup.wLength = 0;

	if (libusb20_dev_request_sync(usb_pdev, &setup, NULL, NULL, 5000, 0)) {
		printf("ERROR: %s\n", __FUNCTION__);
		stats.xfer_error++;
	}
	libusb20_tr_clear_stall_sync(xfer_in);
	libusb20_tr_clear_stall_sync(xfer_out);

	stats.xfer_reset++;

	usb_request_sense(lun);
}
Esempio n. 2
0
int
libusb20_dev_req_string_sync(struct libusb20_device *pdev,
    uint8_t str_index, uint16_t langid, void *ptr, uint16_t len)
{
	struct LIBUSB20_CONTROL_SETUP_DECODED req;
	int error;

	/* make sure memory is initialised */
	memset(ptr, 0, len);

	if (len < 4) {
		/* invalid length */
		return (LIBUSB20_ERROR_INVALID_PARAM);
	}
	LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);

	/*
	 * We need to read the USB string in two steps else some USB
	 * devices will complain.
	 */
	req.bmRequestType =
	    LIBUSB20_REQUEST_TYPE_STANDARD |
	    LIBUSB20_RECIPIENT_DEVICE |
	    LIBUSB20_ENDPOINT_IN;
	req.bRequest = LIBUSB20_REQUEST_GET_DESCRIPTOR;
	req.wValue = (LIBUSB20_DT_STRING << 8) | str_index;
	req.wIndex = langid;
	req.wLength = 4;		/* bytes */

	error = libusb20_dev_request_sync(pdev, &req,
	    ptr, NULL, 1000, LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK);
	if (error) {
		return (error);
	}
	req.wLength = *(uint8_t *)ptr;	/* bytes */
	if (req.wLength > len) {
		/* partial string read */
		req.wLength = len;
	}
	error = libusb20_dev_request_sync(pdev, &req,
	    ptr, NULL, 1000, LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK);

	if (error) {
		return (error);
	}
	if (((uint8_t *)ptr)[1] != LIBUSB20_DT_STRING) {
		return (LIBUSB20_ERROR_OTHER);
	}
	return (0);			/* success */
}
Esempio n. 3
0
int
usb_control_msg(usb_dev_handle * dev, int requesttype, int request,
    int value, int wIndex, char *bytes, int size, int timeout)
{
	struct LIBUSB20_CONTROL_SETUP_DECODED req;
	int err;
	uint16_t actlen;

	LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);

	req.bmRequestType = requesttype;
	req.bRequest = request;
	req.wValue = value;
	req.wIndex = wIndex;
	req.wLength = size;

	err = libusb20_dev_request_sync((void *)dev, &req, bytes,
	    &actlen, timeout, 0);

	if (err)
		return (-1);

	return (actlen);
}
Esempio n. 4
0
static void
usb_modem_control_ep_test(struct modem *p, uint32_t duration, uint8_t flag)
{
	struct timeval sub_tv;
	struct timeval ref_tv;
	struct timeval res_tv;
	struct LIBUSB20_CONTROL_SETUP_DECODED setup;
	struct usb_cdc_abstract_state ast;
	struct usb_cdc_line_state ls;
	uint16_t feature = UCDC_ABSTRACT_STATE;
	uint16_t state = UCDC_DATA_MULTIPLEXED;
	uint8_t iface_no;
	uint8_t buf[4];
	int id = 0;
	int iter = 0;

	time_t last_sec;

	iface_no = p->usb_iface - 1;

	gettimeofday(&ref_tv, 0);

	last_sec = ref_tv.tv_sec;

	printf("\nTest=%d\n", (int)flag);

	while (1) {

		gettimeofday(&sub_tv, 0);

		if (last_sec != sub_tv.tv_sec) {

			printf("STATUS: ID=%u, COUNT=%u tests/sec ERR=%u\n",
			    (int)id,
			    (int)iter,
			    (int)p->errors);

			fflush(stdout);

			last_sec = sub_tv.tv_sec;

			id++;

			iter = 0;
		}
		timersub(&sub_tv, &ref_tv, &res_tv);

		if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration))
			break;

		LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup);

		if (flag & 1) {
			setup.bmRequestType = UT_READ_CLASS_INTERFACE;
			setup.bRequest = 0x03;
			setup.wValue = 0x0001;
			setup.wIndex = iface_no;
			setup.wLength = 0x0002;

			if (libusb20_dev_request_sync(p->usb_dev, &setup, buf, NULL, 250, 0)) {
				p->errors++;
			}
		}
		if (flag & 2) {
			setup.bmRequestType = UT_WRITE_CLASS_INTERFACE;
			setup.bRequest = UCDC_SET_COMM_FEATURE;
			setup.wValue = feature;
			setup.wIndex = iface_no;
			setup.wLength = UCDC_ABSTRACT_STATE_LENGTH;
			USETW(ast.wState, state);

			if (libusb20_dev_request_sync(p->usb_dev, &setup, &ast, NULL, 250, 0)) {
				p->errors++;
			}
		}
		if (flag & 4) {
			USETDW(ls.dwDTERate, 115200);
			ls.bCharFormat = UCDC_STOP_BIT_1;
			ls.bParityType = UCDC_PARITY_NONE;
			ls.bDataBits = 8;

			setup.bmRequestType = UT_WRITE_CLASS_INTERFACE;
			setup.bRequest = UCDC_SET_LINE_CODING;
			setup.wValue = 0;
			setup.wIndex = iface_no;
			setup.wLength = sizeof(ls);

			if (libusb20_dev_request_sync(p->usb_dev, &setup, &ls, NULL, 250, 0)) {
				p->errors++;
			}
		}
		iter++;
	}

	printf("\nModem control endpoint test done!\n");
}
Esempio n. 5
0
int
main(int argc, char **argv)
{
  unsigned int vid = UINT_MAX, pid = UINT_MAX; /* impossible VID:PID */
  int c;

  /*
   * Initialize setup struct.  This step is required, and initializes
   * internal fields in the struct.
   *
   * All the "public" fields are named exactly the way as the USB
   * standard describes them, namely:
   *
   *	setup.bmRequestType: bitmask, bit 7 is direction
   *	                              bits 6/5 is request type
   *	                                       (standard, class, vendor)
   *	                              bits 4..0 is recipient
   *	                                       (device, interface, endpoint,
   *	                                        other)
   *	setup.bRequest:      the request itself (see get_req() for standard
   *	                                         requests, or specific value)
   *	setup.wValue:        a 16-bit value
   *	setup.wIndex:        another 16-bit value
   *	setup.wLength:       length of associated data transfer, direction
   *	                     depends on bit 7 of bmRequestType
   */
  LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup);

  while ((c = getopt(argc, argv, "i:p:v:")) != -1)
    switch (c)
      {
      case 'i':
	intr_ep = strtol(optarg, NULL, 0);
	break;

      case 'p':
	pid = strtol(optarg, NULL, 0);
	break;

      case 'v':
	vid = strtol(optarg, NULL, 0);
	break;

      default:
	usage();
	break;
      }
  argc -= optind;
  argv += optind;

  if (vid != UINT_MAX || pid != UINT_MAX)
    {
      if (intr_ep != 0 && (intr_ep & 0x80) == 0)
	{
	  fprintf(stderr, "Interrupt endpoint must be of type IN\n");
	  usage();
	}

      if (argc > 0)
	{
	  do_request = true;

	  int rv = parse_req(argc, argv);
	  if (rv < 0)
	    return EX_USAGE;
	  argc = rv;

	  if (argc > 0)
	    {
	      for (out_len = 0; argc > 0 && out_len < BUFLEN; out_len++, argc--)
		{
		  unsigned n = strtoul(argv[out_len], 0, 0);
		  if (n > 255)
		    fprintf(stderr,
			    "Warning: data #%d 0x%0x > 0xff, truncating\n",
			    out_len, n);
		  out_buf[out_len] = (uint8_t)n;
		}
	      out_len++;
	      if (argc > 0)
		fprintf(stderr,
			"Data count exceeds maximum of %d, ignoring %d elements\n",
			BUFLEN, optind);
	    }
	}
    }

  struct libusb20_backend *be;
  struct libusb20_device *dev;

  if ((be = libusb20_be_alloc_default()) == NULL)
    {
      perror("libusb20_be_alloc()");
      return 1;
    }

  dev = NULL;
  while ((dev = libusb20_be_device_foreach(be, dev)) != NULL)
    {
      struct LIBUSB20_DEVICE_DESC_DECODED *ddp =
      libusb20_dev_get_device_desc(dev);

      printf("Found device %s (VID:PID = 0x%04x:0x%04x)\n",
	     libusb20_dev_get_desc(dev),
	     ddp->idVendor, ddp->idProduct);

      if (ddp->idVendor == vid && ddp->idProduct == pid)
	doit(dev);
    }

  libusb20_be_free(be);
  return 0;
}
Esempio n. 6
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);
}
Esempio n. 7
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);
}
Esempio n. 8
0
static int
ugen20_enumerate(struct libusb20_device *pdev, const char *id)
{
	const char *tmp = id;
	struct usb_device_descriptor ddesc;
	struct usb_device_info devinfo;
	uint32_t plugtime;
	char buf[64];
	int f;
	int error;

	pdev->bus_number = ugen20_path_convert_one(&tmp);
	pdev->device_address = ugen20_path_convert_one(&tmp);

	snprintf(buf, sizeof(buf), "/dev/" USB_GENERIC_NAME "%u.%u",
	    pdev->bus_number, pdev->device_address);

	f = open(buf, O_RDWR);
	if (f < 0) {
		return (LIBUSB20_ERROR_OTHER);
	}
	if (ioctl(f, IOUSB(USB_GET_PLUGTIME), &plugtime)) {
		error = LIBUSB20_ERROR_OTHER;
		goto done;
	}
	/* store when the device was plugged */
	pdev->session_data.plugtime = plugtime;

	if (ioctl(f, IOUSB(USB_GET_DEVICE_DESC), &ddesc)) {
		error = LIBUSB20_ERROR_OTHER;
		goto done;
	}
	LIBUSB20_INIT(LIBUSB20_DEVICE_DESC, &(pdev->ddesc));

	libusb20_me_decode(&ddesc, sizeof(ddesc), &(pdev->ddesc));

	if (pdev->ddesc.bNumConfigurations == 0) {
		error = LIBUSB20_ERROR_OTHER;
		goto done;
	} else if (pdev->ddesc.bNumConfigurations >= 8) {
		error = LIBUSB20_ERROR_OTHER;
		goto done;
	}
	if (ioctl(f, IOUSB(USB_GET_DEVICEINFO), &devinfo)) {
		error = LIBUSB20_ERROR_OTHER;
		goto done;
	}
	switch (devinfo.udi_mode) {
	case USB_MODE_DEVICE:
		pdev->usb_mode = LIBUSB20_MODE_DEVICE;
		break;
	default:
		pdev->usb_mode = LIBUSB20_MODE_HOST;
		break;
	}

	switch (devinfo.udi_speed) {
	case USB_SPEED_LOW:
		pdev->usb_speed = LIBUSB20_SPEED_LOW;
		break;
	case USB_SPEED_FULL:
		pdev->usb_speed = LIBUSB20_SPEED_FULL;
		break;
	case USB_SPEED_HIGH:
		pdev->usb_speed = LIBUSB20_SPEED_HIGH;
		break;
	case USB_SPEED_VARIABLE:
		pdev->usb_speed = LIBUSB20_SPEED_VARIABLE;
		break;
	case USB_SPEED_SUPER:
		pdev->usb_speed = LIBUSB20_SPEED_SUPER;
		break;
	default:
		pdev->usb_speed = LIBUSB20_SPEED_UNKNOWN;
		break;
	}

	/* get parent HUB index and port */

	pdev->parent_address = devinfo.udi_hubindex;
	pdev->parent_port = devinfo.udi_hubport;

	/* generate a nice description for printout */

	snprintf(pdev->usb_desc, sizeof(pdev->usb_desc),
	    USB_GENERIC_NAME "%u.%u: <%s %s> at usbus%u", pdev->bus_number,
	    pdev->device_address, devinfo.udi_product,
	    devinfo.udi_vendor, pdev->bus_number);

	error = 0;
done:
	close(f);
	return (error);
}