Пример #1
0
static void susb_issue_call(struct aura_node *node, struct aura_buffer *buf)
{
	struct aura_object *o = buf->object;
	struct usb_dev_info *inf = aura_get_transportdata(node);
	uint8_t rqtype;
	uint16_t wIndex, wValue, *ptr;
	size_t datalen; /*Actual data in packet, save for setup */

	if (o->retlen) {
		rqtype = LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN;
		datalen = o->retlen;
	} else {
		datalen = o->arglen - 2 * sizeof(uint16_t);
		rqtype = LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT;
	}
	ptr = (uint16_t *)&buf->data[buf->pos];
	wValue = *ptr++;
	wIndex = *ptr++;

	memmove(&buf->data[buf->pos], ptr, datalen);

	/*
	 * VUSB-based devices (or libusb?) do not seem to play nicely when we have the
	 * setup packet with no data. Transfers may fail instantly.
	 * A typical run at my box gives:
	 *
	 * 9122 succeeded, 878 failed total 10000
	 *
	 * See tests-transports/test-susb-stability-none
	 * Adding just one byte of data to the packet fix the issue.
	 * Posible workarounds are:
	 * 1. Retry N times
	 * 2. Add just one dummy byte for the transfer
	 * Since nobody reported this workaround breaking support for their
	 * hardware - we'll do it the second way. For now.
	 */

	if (!datalen)
		datalen++; /* buffer's big enough anyway */

	/* e.g if device is big endian, but has le descriptors
	 * we have to be extra careful here
	 */

	if (node->need_endian_swap) {
		wValue = __swap16(wValue);
		wIndex = __swap16(wValue);
	}

	inf->current_buffer = buf;
	libusb_fill_control_setup((unsigned char *)buf->data, rqtype, o->id, wValue, wIndex,
				  datalen);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle,
				     (unsigned char *)buf->data, cb_call_done, node, 4000);
	inf->control_retry_count = 0;
	submit_control(node);
}
Пример #2
0
static void request_object(struct aura_node *node, int id)
{
	struct usb_dev_info *inf = aura_get_transportdata(node);
	libusb_fill_control_setup(inf->ctrlbuf, 
				  LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
				  RQ_GET_OBJ_INFO,
				  0, id, inf->io_buf_size - LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle, inf->ctrlbuf, cb_parse_object, node, 1500);
	submit_control(node);	
}
Пример #3
0
static void submit_call_write(struct aura_node *node, struct aura_buffer *buf)
{
	struct aura_object *o = buf->object;
	struct usb_dev_info *inf = aura_get_transportdata(node);
	
	slog(4, SLOG_DEBUG, "Writing call %s data to device, %d bytes", o->name, buf->size);
	inf->current_buffer = buf; 
	libusb_fill_control_setup((unsigned char *)buf->data,
				  LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
				  RQ_PUT_CALL,
				  0, 0, buf->size - LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle, 
				     (unsigned char *) buf->data, 
				     cb_call_write_done, node, 1500);
	submit_control(node);
}
Пример #4
0
static void submit_event_readout(struct aura_node *node)
{
	struct usb_dev_info *inf = aura_get_transportdata(node);
	struct aura_buffer *buf = aura_buffer_request(node, inf->io_buf_size);
	if (!buf) 
		return; /* Nothing bad, we'll try again later */

	slog(0, SLOG_DEBUG, "Starting evt readout, max %d bytes, pending %d", 
	     inf->io_buf_size, inf->pending);	
	libusb_fill_control_setup((unsigned char *)buf->data,
				  LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
				  RQ_GET_EVENT,
				  0, 0, buf->size - LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle, (unsigned char *)buf->data, 
				     cb_event_readout_done, node, 1500);
	inf->current_buffer = buf;
	submit_control(node);
}
Пример #5
0
static int check_control(struct libusb_transfer *transfer)
{
	struct aura_node *node = transfer->user_data;
	struct usb_dev_info *inf = aura_get_transportdata(node);
	int ret = 0;

	inf->cbusy = false;

	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
		if (inf->control_retry_count++ < inf->control_retry_max) {
			slog(0, SLOG_WARN, "Control transfer failed, retrying (%d/%d)",
			     inf->control_retry_count, inf->control_retry_max);
			submit_control(inf->node);
			return -EAGAIN;
		}
		slog(0, SLOG_ERROR, "usb: error completing control transfer");
		ncusb_print_libusb_transfer(transfer);
		usb_panic_and_reset_state(node);
		ret = -EIO;
	}
	return ret;
}