Beispiel #1
0
static int
ugen20_get_config_desc_full(struct libusb20_device *pdev,
    uint8_t **ppbuf, uint16_t *plen, uint8_t cfg_index)
{
	struct usb_gen_descriptor gen_desc;
	struct usb_config_descriptor cdesc;
	uint8_t *ptr;
	uint16_t len;
	int error;

	/* make sure memory is initialised */
	memset(&cdesc, 0, sizeof(cdesc));
	memset(&gen_desc, 0, sizeof(gen_desc));

	gen_desc.ugd_data = libusb20_pass_ptr(&cdesc);
	gen_desc.ugd_maxlen = sizeof(cdesc);
	gen_desc.ugd_config_index = cfg_index;

	error = ioctl(pdev->file_ctrl, IOUSB(USB_GET_FULL_DESC), &gen_desc);
	if (error) {
		return (LIBUSB20_ERROR_OTHER);
	}
	len = UGETW(cdesc.wTotalLength);
	if (len < sizeof(cdesc)) {
		/* corrupt descriptor */
		return (LIBUSB20_ERROR_OTHER);
	}
	ptr = malloc(len);
	if (!ptr) {
		return (LIBUSB20_ERROR_NO_MEM);
	}

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

	gen_desc.ugd_data = libusb20_pass_ptr(ptr);
	gen_desc.ugd_maxlen = len;

	error = ioctl(pdev->file_ctrl, IOUSB(USB_GET_FULL_DESC), &gen_desc);
	if (error) {
		free(ptr);
		return (LIBUSB20_ERROR_OTHER);
	}
	/* make sure that the device doesn't fool us */
	memcpy(ptr, &cdesc, sizeof(cdesc));

	*ppbuf = ptr;
	*plen = len;

	return (0);			/* success */
}
Beispiel #2
0
static int
ugen20_do_request_sync(struct libusb20_device *pdev,
    struct LIBUSB20_CONTROL_SETUP_DECODED *setup,
    void *data, uint16_t *pactlen, uint32_t timeout, uint8_t flags)
{
	struct usb_ctl_request req;

	memset(&req, 0, sizeof(req));

	req.ucr_data = libusb20_pass_ptr(data);
	if (!(flags & LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK)) {
		req.ucr_flags |= USB_SHORT_XFER_OK;
	}
	if (libusb20_me_encode(&req.ucr_request,
	    sizeof(req.ucr_request), setup)) {
		/* ignore */
	}
	if (ioctl(pdev->file_ctrl, IOUSB(USB_DO_REQUEST), &req)) {
		return (LIBUSB20_ERROR_OTHER);
	}
	if (pactlen) {
		/* get actual length */
		*pactlen = req.ucr_actlen;
	}
	return (0);			/* request was successful */
}
Beispiel #3
0
static int
ugen20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize,
    uint32_t MaxFrameCount, uint8_t ep_no, uint16_t stream_id,
    uint8_t pre_scale)
{
	union {
		struct usb_fs_open fs_open;
		struct usb_fs_open_stream fs_open_stream;
	} temp;
	struct usb_fs_endpoint *fsep;

	if (pre_scale)
		MaxFrameCount |= USB_FS_MAX_FRAMES_PRE_SCALE;

	memset(&temp, 0, sizeof(temp));

	fsep = xfer->pdev->privBeData;
	fsep += xfer->trIndex;

	temp.fs_open.max_bufsize = MaxBufSize;
	temp.fs_open.max_frames = MaxFrameCount;
	temp.fs_open.ep_index = xfer->trIndex;
	temp.fs_open.ep_no = ep_no;

	if (stream_id != 0) {
		temp.fs_open_stream.stream_id = stream_id;

		if (ioctl(xfer->pdev->file, IOUSB(USB_FS_OPEN_STREAM), &temp.fs_open_stream))
			return (LIBUSB20_ERROR_INVALID_PARAM);
	} else {
		if (ioctl(xfer->pdev->file, IOUSB(USB_FS_OPEN), &temp.fs_open))
			return (LIBUSB20_ERROR_INVALID_PARAM);
	}
	/* maximums might have changed - update */
	xfer->maxFrames = temp.fs_open.max_frames;

	/* "max_bufsize" should be multiple of "max_packet_length" */
	xfer->maxTotalLength = temp.fs_open.max_bufsize;
	xfer->maxPacketLen = temp.fs_open.max_packet_length;

	/* setup buffer and length lists using zero copy */
	fsep->ppBuffer = libusb20_pass_ptr(xfer->ppBuffer);
	fsep->pLength = libusb20_pass_ptr(xfer->pLength);

	return (0);			/* success */
}
Beispiel #4
0
void
libusb20_tr_setup_intr(struct libusb20_transfer *xfer, void *pBuf, uint32_t length, uint32_t timeout)
{
	xfer->ppBuffer[0] = libusb20_pass_ptr(pBuf);
	xfer->pLength[0] = length;
	xfer->timeout = timeout;
	xfer->nFrames = 1;
	return;
}
Beispiel #5
0
void
libusb20_tr_setup_isoc(struct libusb20_transfer *xfer, void *pBuf, uint32_t length, uint16_t frIndex)
{
	if (frIndex >= xfer->maxFrames) {
		/* should not happen */
		return;
	}
	xfer->ppBuffer[frIndex] = libusb20_pass_ptr(pBuf);
	xfer->pLength[frIndex] = length;
	return;
}
Beispiel #6
0
void
libusb20_tr_setup_control(struct libusb20_transfer *xfer, void *psetup, void *pBuf, uint32_t timeout)
{
	uint16_t len;

	xfer->ppBuffer[0] = libusb20_pass_ptr(psetup);
	xfer->pLength[0] = 8;		/* fixed */
	xfer->timeout = timeout;

	len = ((uint8_t *)psetup)[6] | (((uint8_t *)psetup)[7] << 8);

	if (len != 0) {
		xfer->nFrames = 2;
		xfer->ppBuffer[1] = libusb20_pass_ptr(pBuf);
		xfer->pLength[1] = len;
	} else {
		xfer->nFrames = 1;
	}
	return;
}
Beispiel #7
0
static int
ugen20_dev_get_iface_desc(struct libusb20_device *pdev, 
    uint8_t iface_index, char *buf, uint8_t len)
{
	struct usb_gen_descriptor ugd;

	memset(&ugd, 0, sizeof(ugd));

	ugd.ugd_data = libusb20_pass_ptr(buf);
	ugd.ugd_maxlen = len;
	ugd.ugd_iface_index = iface_index;

	if (ioctl(pdev->file, IOUSB(USB_GET_IFACE_DRIVER), &ugd)) {
		return (LIBUSB20_ERROR_INVALID_PARAM);
	}
	return (0);
}
Beispiel #8
0
static int
ugen20_tr_renew(struct libusb20_device *pdev)
{
	struct usb_fs_init fs_init;
	struct usb_fs_endpoint *pfse;
	int error;
	uint32_t size;
	uint16_t nMaxTransfer;

	nMaxTransfer = pdev->nTransfer;
	error = 0;

	if (nMaxTransfer == 0) {
		goto done;
	}
	size = nMaxTransfer * sizeof(*pfse);

	if (pdev->privBeData == NULL) {
		pfse = malloc(size);
		if (pfse == NULL) {
			error = LIBUSB20_ERROR_NO_MEM;
			goto done;
		}
		pdev->privBeData = pfse;
	}
	/* reset endpoint data */
	memset(pdev->privBeData, 0, size);

	memset(&fs_init, 0, sizeof(fs_init));

	fs_init.pEndpoints = libusb20_pass_ptr(pdev->privBeData);
	fs_init.ep_index_max = nMaxTransfer;

	if (ioctl(pdev->file, IOUSB(USB_FS_INIT), &fs_init)) {
		error = LIBUSB20_ERROR_OTHER;
		goto done;
	}
done:
	return (error);
}
Beispiel #9
0
static int
ugen20_readdir(struct ugen20_urd_state *st)
{
	;				/* style fix */
repeat:
	if (st->ptr == NULL) {
		st->urd.urd_startentry += st->nparsed;
		st->urd.urd_data = libusb20_pass_ptr(st->buf);
		st->urd.urd_maxlen = sizeof(st->buf);
		st->nparsed = 0;

		if (ioctl(st->f, IOUSB(USB_READ_DIR), &st->urd)) {
			return (EINVAL);
		}
		st->ptr = st->buf;
	}
	if (st->ptr[0] == 0) {
		if (st->nparsed) {
			st->ptr = NULL;
			goto repeat;
		} else {
			return (ENXIO);
		}
	}
	st->src = (void *)(st->ptr + 1);
	st->dst = st->src + strlen(st->src) + 1;
	st->ptr = st->ptr + st->ptr[0];
	st->nparsed++;

	if ((st->ptr < st->buf) ||
	    (st->ptr > st->dummy_zero)) {
		/* invalid entry */
		return (EINVAL);
	}
	return (0);
}
Beispiel #10
0
void
libusb20_tr_set_buffer(struct libusb20_transfer *xfer, void *buffer, uint16_t frIndex)
{
	xfer->ppBuffer[frIndex] = libusb20_pass_ptr(buffer);
	return;
}