Rework URB API naming

Now refer to everything as "transfers" as consistent with the USB spec
libusb_transfer is now a kind of transfer handle. To reduce confusion
with libusb_bulk_transfer and libusb_control_transfer, those have been
renamed to libusb_{control,bulk}_transfer_request.
This commit is contained in:
Daniel Drake 2008-03-08 12:48:35 +00:00
parent fd6fb3cc09
commit d21ebe47ce
5 changed files with 264 additions and 251 deletions

5
TODO
View file

@ -9,6 +9,7 @@ isochronous endpoint I/O
thread safety thread safety
abstraction for cross-platform-ness abstraction for cross-platform-ness
error codes error codes
fixme review
for 1.1 or future for 1.1 or future
================== ==================
@ -21,8 +22,8 @@ use poll() rather than select()?
struct libusb_(bulk|control)_transfer or parameters? struct libusb_(bulk|control)_transfer or parameters?
devh in general devh in general
urbh in general (should this be a transfer handle?) separate transfer allocation and submission
config struct/function naming config struct/function naming
typedef _cb or _cb_fn or _cb_t? typedef _cb or _cb_fn or _cb_t?
typedef as-is or pointers? libusb_dev_t rather than libusb_dev *? typedef as-is or pointers? libusb_dev_t rather than libusb_dev *?
FP_ urb status codes remove "_transfer" from libusb_{control,bulk}_transfer_request?

View file

@ -62,18 +62,18 @@ static int state = 0;
static struct libusb_dev_handle *devh = NULL; static struct libusb_dev_handle *devh = NULL;
static unsigned char imgbuf[0x1b340]; static unsigned char imgbuf[0x1b340];
static unsigned char irqbuf[INTR_LENGTH]; static unsigned char irqbuf[INTR_LENGTH];
static libusb_urb_handle *img_urbh = NULL; static libusb_transfer *img_urbh = NULL;
static libusb_urb_handle *irq_urbh = NULL; static libusb_transfer *irq_urbh = NULL;
static int img_idx = 0; static int img_idx = 0;
static int do_exit = 0; static int do_exit = 0;
static struct libusb_bulk_transfer imgtrf = { static struct libusb_bulk_transfer_request imgrq = {
.endpoint = EP_DATA, .endpoint = EP_DATA,
.data = imgbuf, .data = imgbuf,
.length = sizeof(imgbuf), .length = sizeof(imgbuf),
}; };
static struct libusb_bulk_transfer irqtrf = { static struct libusb_bulk_transfer_request intrrq = {
.endpoint = EP_INTR, .endpoint = EP_INTR,
.data = irqbuf, .data = irqbuf,
.length = sizeof(irqbuf), .length = sizeof(irqbuf),
@ -88,7 +88,7 @@ static int find_dpfp_device(void)
static int print_f0_data(void) static int print_f0_data(void)
{ {
unsigned char data[0x10]; unsigned char data[0x10];
struct libusb_control_transfer transfer = { struct libusb_control_transfer_request rq = {
.requesttype = CTRL_IN, .requesttype = CTRL_IN,
.request = USB_RQ, .request = USB_RQ,
.value = 0xf0, .value = 0xf0,
@ -99,7 +99,7 @@ static int print_f0_data(void)
int r; int r;
unsigned int i; unsigned int i;
r = libusb_control_transfer(devh, &transfer, 0); r = libusb_control_transfer(devh, &rq, 0);
if (r < 0) { if (r < 0) {
fprintf(stderr, "F0 error %d\n", r); fprintf(stderr, "F0 error %d\n", r);
return r; return r;
@ -118,7 +118,7 @@ static int print_f0_data(void)
static int get_hwstat(unsigned char *status) static int get_hwstat(unsigned char *status)
{ {
struct libusb_control_transfer transfer = { struct libusb_control_transfer_request rq = {
.requesttype = CTRL_IN, .requesttype = CTRL_IN,
.request = USB_RQ, .request = USB_RQ,
.value = 0x07, .value = 0x07,
@ -128,7 +128,7 @@ static int get_hwstat(unsigned char *status)
}; };
int r; int r;
r = libusb_control_transfer(devh, &transfer, 0); r = libusb_control_transfer(devh, &rq, 0);
if (r < 0) { if (r < 0) {
fprintf(stderr, "read hwstat error %d\n", r); fprintf(stderr, "read hwstat error %d\n", r);
return r; return r;
@ -145,7 +145,7 @@ static int get_hwstat(unsigned char *status)
static int set_hwstat(unsigned char data) static int set_hwstat(unsigned char data)
{ {
int r; int r;
struct libusb_control_transfer transfer = { struct libusb_control_transfer_request rq = {
.requesttype = CTRL_OUT, .requesttype = CTRL_OUT,
.request = USB_RQ, .request = USB_RQ,
.value = 0x07, .value = 0x07,
@ -156,7 +156,7 @@ static int set_hwstat(unsigned char data)
printf("set hwstat to %02x\n", data); printf("set hwstat to %02x\n", data);
r = libusb_control_transfer(devh, &transfer, 0); r = libusb_control_transfer(devh, &rq, 0);
if (r < 0) { if (r < 0) {
fprintf(stderr, "set hwstat error %d\n", r); fprintf(stderr, "set hwstat error %d\n", r);
return r; return r;
@ -172,7 +172,7 @@ static int set_hwstat(unsigned char data)
static int set_mode(unsigned char data) static int set_mode(unsigned char data)
{ {
int r; int r;
struct libusb_control_transfer transfer = { struct libusb_control_transfer_request rq = {
.requesttype = CTRL_OUT, .requesttype = CTRL_OUT,
.request = USB_RQ, .request = USB_RQ,
.value = 0x4e, .value = 0x4e,
@ -183,7 +183,7 @@ static int set_mode(unsigned char data)
printf("set mode %02x\n", data); printf("set mode %02x\n", data);
r = libusb_control_transfer(devh, &transfer, 0); r = libusb_control_transfer(devh, &rq, 0);
if (r < 0) { if (r < 0) {
fprintf(stderr, "set mode error %d\n", r); fprintf(stderr, "set mode error %d\n", r);
return r; return r;
@ -197,11 +197,11 @@ static int set_mode(unsigned char data)
} }
static void cb_mode_changed(struct libusb_dev_handle *_devh, static void cb_mode_changed(struct libusb_dev_handle *_devh,
struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status, struct libusb_transfer *urbh, enum libusb_transfer_status status,
struct libusb_ctrl_setup *setup, unsigned char *data, int actual_length, struct libusb_control_setup *setup, unsigned char *data, int actual_length,
void *user_data) void *user_data)
{ {
if (status != FP_URB_COMPLETED) { if (status != LIBUSB_TRANSFER_COMPLETED) {
fprintf(stderr, "mode change URB not completed!\n"); fprintf(stderr, "mode change URB not completed!\n");
do_exit = 2; do_exit = 2;
} }
@ -213,8 +213,8 @@ static void cb_mode_changed(struct libusb_dev_handle *_devh,
static int set_mode_async(unsigned char data) static int set_mode_async(unsigned char data)
{ {
libusb_urb_handle *urbh; libusb_transfer *urbh;
struct libusb_control_transfer transfer = { struct libusb_control_transfer_request rq = {
.requesttype = CTRL_OUT, .requesttype = CTRL_OUT,
.request = USB_RQ, .request = USB_RQ,
.value = 0x4e, .value = 0x4e,
@ -225,7 +225,7 @@ static int set_mode_async(unsigned char data)
printf("async set mode %02x\n", data); printf("async set mode %02x\n", data);
urbh = libusb_async_control_transfer(devh, &transfer, cb_mode_changed, NULL, urbh = libusb_async_control_transfer(devh, &rq, cb_mode_changed, NULL,
1000); 1000);
if (!urbh) { if (!urbh) {
fprintf(stderr, "set mode submit error\n"); fprintf(stderr, "set mode submit error\n");
@ -237,7 +237,7 @@ static int set_mode_async(unsigned char data)
static int do_sync_intr(unsigned char *data) static int do_sync_intr(unsigned char *data)
{ {
struct libusb_bulk_transfer transfer = { struct libusb_bulk_transfer_request request = {
.endpoint = EP_INTR, .endpoint = EP_INTR,
.data = data, .data = data,
.length = INTR_LENGTH, .length = INTR_LENGTH,
@ -245,7 +245,7 @@ static int do_sync_intr(unsigned char *data)
int r; int r;
int transferred; int transferred;
r = libusb_interrupt_transfer(devh, &transfer, &transferred, 1000); r = libusb_interrupt_transfer(devh, &request, &transferred, 1000);
if (r < 0) { if (r < 0) {
fprintf(stderr, "intr error %d\n", r); fprintf(stderr, "intr error %d\n", r);
return r; return r;
@ -328,13 +328,13 @@ static int next_state(void)
return 0; return 0;
} }
static void cb_irq(libusb_dev_handle *_devh, libusb_urb_handle *urbh, static void cb_irq(libusb_dev_handle *_devh, libusb_transfer *urbh,
enum libusb_urb_cb_status status, unsigned char endpoint, int rqlength, enum libusb_transfer_status status, unsigned char endpoint, int rqlength,
unsigned char *data, int actual_length, void *user_data) unsigned char *data, int actual_length, void *user_data)
{ {
unsigned char irqtype = data[0]; unsigned char irqtype = data[0];
if (status != FP_URB_COMPLETED) { if (status != LIBUSB_TRANSFER_COMPLETED) {
fprintf(stderr, "irq URB status %d?\n", status); fprintf(stderr, "irq URB status %d?\n", status);
do_exit = 2; do_exit = 2;
return; return;
@ -367,11 +367,11 @@ static void cb_irq(libusb_dev_handle *_devh, libusb_urb_handle *urbh,
do_exit = 2; do_exit = 2;
} }
static void cb_img(libusb_dev_handle *_devh, libusb_urb_handle *urbh, static void cb_img(libusb_dev_handle *_devh, libusb_transfer *urbh,
enum libusb_urb_cb_status status, unsigned char endpoint, int rqlength, enum libusb_transfer_status status, unsigned char endpoint, int rqlength,
unsigned char *data, int actual_length, void *user_data) unsigned char *data, int actual_length, void *user_data)
{ {
if (status != FP_URB_COMPLETED) { if (status != LIBUSB_TRANSFER_COMPLETED) {
fprintf(stderr, "img URB status %d?\n", status); fprintf(stderr, "img URB status %d?\n", status);
do_exit = 2; do_exit = 2;
return; return;
@ -389,15 +389,15 @@ static void cb_img(libusb_dev_handle *_devh, libusb_urb_handle *urbh,
static int submit_irq_urb(void) static int submit_irq_urb(void)
{ {
libusb_urb_handle_free(irq_urbh); libusb_transfer_free(irq_urbh);
irq_urbh = libusb_async_interrupt_transfer(devh, &irqtrf, cb_irq, NULL, 0); irq_urbh = libusb_async_interrupt_transfer(devh, &intrrq, cb_irq, NULL, 0);
return irq_urbh != NULL; return irq_urbh != NULL;
} }
static int submit_img_urb(void) static int submit_img_urb(void)
{ {
libusb_urb_handle_free(img_urbh); libusb_transfer_free(img_urbh);
img_urbh = libusb_async_bulk_transfer(devh, &imgtrf, cb_img, NULL, 0); img_urbh = libusb_async_bulk_transfer(devh, &imgrq, cb_img, NULL, 0);
return img_urbh != NULL; return img_urbh != NULL;
} }
@ -411,7 +411,7 @@ static int init_capture(void)
r = submit_img_urb(); r = submit_img_urb();
if (r < 0) { if (r < 0) {
libusb_urb_handle_cancel_sync(devh, img_urbh); libusb_transfer_cancel_sync(devh, img_urbh);
return r; return r;
} }
@ -512,11 +512,11 @@ int main(void)
printf("shutting down...\n"); printf("shutting down...\n");
r = libusb_urb_handle_cancel_sync(devh, irq_urbh); r = libusb_transfer_cancel_sync(devh, irq_urbh);
if (r < 0) if (r < 0)
goto out_deinit; goto out_deinit;
r = libusb_urb_handle_cancel_sync(devh, img_urbh); r = libusb_transfer_cancel_sync(devh, img_urbh);
if (r < 0) if (r < 0)
goto out_deinit; goto out_deinit;
@ -526,8 +526,8 @@ int main(void)
r = 1; r = 1;
out_deinit: out_deinit:
libusb_urb_handle_free(img_urbh); libusb_transfer_free(img_urbh);
libusb_urb_handle_free(irq_urbh); libusb_transfer_free(irq_urbh);
set_mode(0); set_mode(0);
set_hwstat(0x80); set_hwstat(0x80);
out_release: out_release:

View file

@ -1,6 +1,6 @@
/* /*
* I/O functions for libusb * I/O functions for libusb
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org> * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com> * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -36,7 +36,7 @@
* URBs to timeout the soonest are placed at the beginning of the list, URBs * URBs to timeout the soonest are placed at the beginning of the list, URBs
* that will time out later are placed after, and urbs with infinite timeout * that will time out later are placed after, and urbs with infinite timeout
* are always placed at the very end. */ * are always placed at the very end. */
static struct list_head flying_urbs; static struct list_head flying_transfers;
/* user callbacks for pollfd changes */ /* user callbacks for pollfd changes */
static libusb_pollfd_added_cb fd_added_cb = NULL; static libusb_pollfd_added_cb fd_added_cb = NULL;
@ -44,12 +44,12 @@ static libusb_pollfd_removed_cb fd_removed_cb = NULL;
void usbi_io_init() void usbi_io_init()
{ {
list_init(&flying_urbs); list_init(&flying_transfers);
fd_added_cb = NULL; fd_added_cb = NULL;
fd_removed_cb = NULL; fd_removed_cb = NULL;
} }
static int calculate_timeout(struct libusb_urb_handle *urbh, static int calculate_timeout(struct libusb_transfer *transfer,
unsigned int timeout) unsigned int timeout)
{ {
int r; int r;
@ -72,54 +72,54 @@ static int calculate_timeout(struct libusb_urb_handle *urbh,
current_time.tv_sec++; current_time.tv_sec++;
} }
TIMESPEC_TO_TIMEVAL(&urbh->timeout, &current_time); TIMESPEC_TO_TIMEVAL(&transfer->timeout, &current_time);
return 0; return 0;
} }
static void add_to_flying_list(struct libusb_urb_handle *urbh) static void add_to_flying_list(struct libusb_transfer *transfer)
{ {
struct libusb_urb_handle *cur; struct libusb_transfer *cur;
struct timeval *timeout = &urbh->timeout; struct timeval *timeout = &transfer->timeout;
/* if we have no other flying urbs, start the list with this one */ /* if we have no other flying transfers, start the list with this one */
if (list_empty(&flying_urbs)) { if (list_empty(&flying_transfers)) {
list_add(&urbh->list, &flying_urbs); list_add(&transfer->list, &flying_transfers);
return; return;
} }
/* if we have infinite timeout, append to end of list */ /* if we have infinite timeout, append to end of list */
if (!timerisset(timeout)) { if (!timerisset(timeout)) {
list_add_tail(&urbh->list, &flying_urbs); list_add_tail(&transfer->list, &flying_transfers);
return; return;
} }
/* otherwise, find appropriate place in list */ /* otherwise, find appropriate place in list */
list_for_each_entry(cur, &flying_urbs, list) { list_for_each_entry(cur, &flying_transfers, list) {
/* find first timeout that occurs after the urbh in question */ /* find first timeout that occurs after the transfer in question */
struct timeval *cur_tv = &cur->timeout; struct timeval *cur_tv = &cur->timeout;
if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) || if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) ||
(cur_tv->tv_sec == timeout->tv_sec && (cur_tv->tv_sec == timeout->tv_sec &&
cur_tv->tv_usec > timeout->tv_usec)) { cur_tv->tv_usec > timeout->tv_usec)) {
list_add_tail(&urbh->list, &cur->list); list_add_tail(&transfer->list, &cur->list);
return; return;
} }
} }
/* otherwise we need to be inserted at the end */ /* otherwise we need to be inserted at the end */
list_add_tail(&urbh->list, &flying_urbs); list_add_tail(&transfer->list, &flying_transfers);
} }
static int submit_urb(struct libusb_dev_handle *devh, static int submit_transfer(struct libusb_dev_handle *devh,
struct libusb_urb_handle *urbh) struct libusb_transfer *transfer)
{ {
int r; int r;
struct usb_urb *urb = &urbh->urb; struct usb_urb *urb = &transfer->urb;
int to_be_transferred = urbh->transfer_len - urbh->transferred; int to_be_transferred = transfer->transfer_len - transfer->transferred;
urb->type = urbh->urb_type; urb->type = transfer->urb_type;
urb->endpoint = urbh->endpoint; urb->endpoint = transfer->endpoint;
urb->buffer = urbh->buffer + urbh->transferred; urb->buffer = transfer->buffer + transfer->transferred;
urb->buffer_length = MIN(to_be_transferred, MAX_URB_BUFFER_LENGTH); urb->buffer_length = MIN(to_be_transferred, MAX_URB_BUFFER_LENGTH);
/* FIXME: for requests that we have to split into multiple URBs, we should /* FIXME: for requests that we have to split into multiple URBs, we should
@ -130,149 +130,153 @@ static int submit_urb(struct libusb_dev_handle *devh,
usbi_dbg("transferring %d from %d bytes", urb->buffer_length, usbi_dbg("transferring %d from %d bytes", urb->buffer_length,
to_be_transferred); to_be_transferred);
r = ioctl(devh->fd, IOCTL_USB_SUBMITURB, &urbh->urb); r = ioctl(devh->fd, IOCTL_USB_SUBMITURB, &transfer->urb);
if (r < 0) { if (r < 0) {
usbi_err("submiturb failed error %d errno=%d", r, errno); usbi_err("submiturb failed error %d errno=%d", r, errno);
return r; return r;
} }
add_to_flying_list(urbh); add_to_flying_list(transfer);
return 0; return 0;
} }
API_EXPORTED struct libusb_urb_handle *libusb_async_control_transfer( API_EXPORTED struct libusb_transfer *libusb_async_control_transfer(
struct libusb_dev_handle *devh, struct libusb_control_transfer *transfer, struct libusb_dev_handle *devh,
libusb_ctrl_cb_fn callback, void *user_data, unsigned int timeout) struct libusb_control_transfer_request *request,
libusb_control_cb_fn callback, void *user_data, unsigned int timeout)
{ {
struct libusb_urb_handle *urbh = malloc(sizeof(*urbh)); struct libusb_transfer *transfer = malloc(sizeof(*transfer));
struct libusb_ctrl_setup *setup; struct libusb_control_setup *setup;
unsigned char *urbdata; unsigned char *urbdata;
int urbdata_length = sizeof(struct libusb_ctrl_setup) + transfer->length; int urbdata_length = sizeof(struct libusb_control_setup) + request->length;
int r; int r;
if (!urbh) if (!transfer)
return NULL; return NULL;
memset(urbh, 0, sizeof(*urbh)); memset(transfer, 0, sizeof(*transfer));
urbh->devh = devh; transfer->devh = devh;
urbh->callback = callback; transfer->callback = callback;
urbh->user_data = user_data; transfer->user_data = user_data;
r = calculate_timeout(urbh, timeout); r = calculate_timeout(transfer, timeout);
if (r < 0) { if (r < 0) {
free(urbh); free(transfer);
return NULL; return NULL;
} }
urbdata = malloc(urbdata_length); urbdata = malloc(urbdata_length);
if (!urbdata) { if (!urbdata) {
free(urbh); free(transfer);
return NULL; return NULL;
} }
usbi_dbg("RQT=%02x RQ=%02x VAL=%04x IDX=%04x length=%d", usbi_dbg("RQT=%02x RQ=%02x VAL=%04x IDX=%04x length=%d",
transfer->requesttype, transfer->request, transfer->value, request->requesttype, request->request, request->value,
transfer->index, transfer->length); request->index, request->length);
setup = (struct libusb_ctrl_setup *) urbdata; setup = (struct libusb_control_setup *) urbdata;
setup->bRequestType = transfer->requesttype; setup->bRequestType = request->requesttype;
setup->bRequest = transfer->request; setup->bRequest = request->request;
setup->wValue = cpu_to_le16(transfer->value); setup->wValue = cpu_to_le16(request->value);
setup->wIndex = cpu_to_le16(transfer->index); setup->wIndex = cpu_to_le16(request->index);
setup->wLength = cpu_to_le16(transfer->length); setup->wLength = cpu_to_le16(request->length);
if ((transfer->requesttype & 0x80) == LIBUSB_ENDPOINT_OUT) if ((request->requesttype & 0x80) == LIBUSB_ENDPOINT_OUT)
memcpy(urbdata + sizeof(struct libusb_ctrl_setup), transfer->data, memcpy(urbdata + sizeof(struct libusb_control_setup), request->data,
transfer->length); request->length);
urbh->urb_type = USB_URB_TYPE_CONTROL; transfer->urb_type = USB_URB_TYPE_CONTROL;
urbh->buffer = urbdata; transfer->buffer = urbdata;
urbh->transfer_len = urbdata_length; transfer->transfer_len = urbdata_length;
r = submit_urb(devh, urbh); r = submit_transfer(devh, transfer);
if (r < 0) { if (r < 0) {
free(urbh); free(transfer);
free(urbdata); free(urbdata);
return NULL; return NULL;
} }
return urbh; return transfer;
} }
static struct libusb_urb_handle *submit_bulk_transfer( static struct libusb_transfer *submit_bulk_transfer(
struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer, struct libusb_dev_handle *devh,
struct libusb_bulk_transfer_request *request,
libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout, libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout,
unsigned char urbtype) unsigned char urbtype)
{ {
struct libusb_urb_handle *urbh = malloc(sizeof(*urbh)); struct libusb_transfer *transfer = malloc(sizeof(*transfer));
int r; int r;
usbi_dbg("length %d timeout %d", transfer->length, timeout); usbi_dbg("length %d timeout %d", request->length, timeout);
if (!urbh) if (!transfer)
return NULL; return NULL;
memset(urbh, 0, sizeof(*urbh)); memset(transfer, 0, sizeof(*transfer));
r = calculate_timeout(urbh, timeout); r = calculate_timeout(transfer, timeout);
if (r < 0) { if (r < 0) {
free(urbh); free(transfer);
return NULL; return NULL;
} }
urbh->devh = devh; transfer->devh = devh;
urbh->callback = callback; transfer->callback = callback;
urbh->user_data = user_data; transfer->user_data = user_data;
urbh->flags |= LIBUSB_URBH_DATA_BELONGS_TO_USER; transfer->flags |= USBI_TRANSFER_DATA_BELONGS_TO_USER;
urbh->endpoint = transfer->endpoint; transfer->endpoint = request->endpoint;
urbh->urb_type = urbtype; transfer->urb_type = urbtype;
urbh->buffer = transfer->data; transfer->buffer = request->data;
urbh->transfer_len = transfer->length; transfer->transfer_len = request->length;
r = submit_urb(devh, urbh); r = submit_transfer(devh, transfer);
if (r < 0) { if (r < 0) {
free(urbh); free(transfer);
return NULL; return NULL;
} }
return urbh; return transfer;
} }
API_EXPORTED struct libusb_urb_handle *libusb_async_bulk_transfer( API_EXPORTED struct libusb_transfer *libusb_async_bulk_transfer(
struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer, struct libusb_dev_handle *devh,
struct libusb_bulk_transfer_request *request,
libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout) libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout)
{ {
return submit_bulk_transfer(devh, transfer, callback, user_data, timeout, return submit_bulk_transfer(devh, request, callback, user_data, timeout,
USB_URB_TYPE_BULK); USB_URB_TYPE_BULK);
} }
API_EXPORTED struct libusb_urb_handle *libusb_async_interrupt_transfer( API_EXPORTED struct libusb_transfer *libusb_async_interrupt_transfer(
struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer, struct libusb_dev_handle *devh,
libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout) struct libusb_bulk_transfer_request *request, libusb_bulk_cb_fn callback,
void *user_data, unsigned int timeout)
{ {
return submit_bulk_transfer(devh, transfer, callback, user_data, timeout, return submit_bulk_transfer(devh, request, callback, user_data, timeout,
USB_URB_TYPE_INTERRUPT); USB_URB_TYPE_INTERRUPT);
} }
API_EXPORTED int libusb_urb_handle_cancel(struct libusb_dev_handle *devh, API_EXPORTED int libusb_transfer_cancel(struct libusb_dev_handle *devh,
struct libusb_urb_handle *urbh) struct libusb_transfer *transfer)
{ {
int r; int r;
usbi_dbg(""); usbi_dbg("");
r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &urbh->urb); r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &transfer->urb);
if (r < 0) if (r < 0)
usbi_err("cancel urb failed error %d", r); usbi_err("cancel transfer failed error %d", r);
return r; return r;
} }
API_EXPORTED int libusb_urb_handle_cancel_sync(struct libusb_dev_handle *devh, API_EXPORTED int libusb_transfer_cancel_sync(struct libusb_dev_handle *devh,
struct libusb_urb_handle *urbh) struct libusb_transfer *transfer)
{ {
int r; int r;
usbi_dbg(""); usbi_dbg("");
r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &urbh->urb); r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &transfer->urb);
if (r < 0) { if (r < 0) {
usbi_err("cancel urb failed error %d", r); usbi_err("cancel transfer failed error %d", r);
return r; return r;
} }
urbh->flags |= LIBUSB_URBH_SYNC_CANCELLED; transfer->flags |= USBI_TRANSFER_SYNC_CANCELLED;
while (urbh->flags & LIBUSB_URBH_SYNC_CANCELLED) { while (transfer->flags & USBI_TRANSFER_SYNC_CANCELLED) {
r = libusb_poll(); r = libusb_poll();
if (r < 0) if (r < 0)
return r; return r;
@ -282,57 +286,61 @@ API_EXPORTED int libusb_urb_handle_cancel_sync(struct libusb_dev_handle *devh,
} }
int handle_transfer_completion(struct libusb_dev_handle *devh, int handle_transfer_completion(struct libusb_dev_handle *devh,
struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status) struct libusb_transfer *transfer, enum libusb_transfer_status status)
{ {
struct usb_urb *urb = &urbh->urb; struct usb_urb *urb = &transfer->urb;
if (status == FP_URB_SILENT_COMPLETION) if (status == LIBUSB_TRANSFER_SILENT_COMPLETION)
return 0; return 0;
if (urb->type == USB_URB_TYPE_CONTROL) { if (transfer->urb_type == USB_URB_TYPE_CONTROL) {
libusb_ctrl_cb_fn callback = urbh->callback; libusb_control_cb_fn callback = transfer->callback;
if (callback) if (callback)
callback(devh, urbh, status, urb->buffer, callback(devh, transfer, status, urb->buffer,
urb->buffer + sizeof(struct libusb_ctrl_setup), urbh->transferred, urb->buffer + sizeof(struct libusb_control_setup),
urbh->user_data); transfer->transferred, transfer->user_data);
} else if (urb->type == USB_URB_TYPE_BULK || } else if (urb->type == USB_URB_TYPE_BULK ||
urb->type == USB_URB_TYPE_INTERRUPT) { urb->type == USB_URB_TYPE_INTERRUPT) {
libusb_bulk_cb_fn callback = urbh->callback; libusb_bulk_cb_fn callback = transfer->callback;
if (callback) if (callback)
callback(devh, urbh, status, urbh->endpoint, urbh->transfer_len, callback(devh, transfer, status, transfer->endpoint,
urbh->buffer, urbh->transferred, urbh->user_data); transfer->transfer_len, transfer->buffer,
transfer->transferred, transfer->user_data);
} }
return 0; return 0;
} }
static int handle_transfer_cancellation(struct libusb_dev_handle *devh, static int handle_transfer_cancellation(struct libusb_dev_handle *devh,
struct libusb_urb_handle *urbh) struct libusb_transfer *transfer)
{ {
/* if the URB is being cancelled synchronously, raise cancellation /* if the URB is being cancelled synchronously, raise cancellation
* completion event by unsetting flag, and ensure that user callback does * completion event by unsetting flag, and ensure that user callback does
* not get called. * not get called.
*/ */
if (urbh->flags & LIBUSB_URBH_SYNC_CANCELLED) { if (transfer->flags & USBI_TRANSFER_SYNC_CANCELLED) {
urbh->flags &= ~LIBUSB_URBH_SYNC_CANCELLED; transfer->flags &= ~USBI_TRANSFER_SYNC_CANCELLED;
usbi_dbg("detected sync. cancel"); usbi_dbg("detected sync. cancel");
return handle_transfer_completion(devh, urbh, FP_URB_SILENT_COMPLETION); return handle_transfer_completion(devh, transfer,
LIBUSB_TRANSFER_SILENT_COMPLETION);
} }
/* if the URB was cancelled due to timeout, report timeout to the user */ /* if the URB was cancelled due to timeout, report timeout to the user */
if (urbh->flags & LIBUSB_URBH_TIMED_OUT) { if (transfer->flags & USBI_TRANSFER_TIMED_OUT) {
usbi_dbg("detected timeout cancellation"); usbi_dbg("detected timeout cancellation");
return handle_transfer_completion(devh, urbh, FP_URB_TIMEOUT); return handle_transfer_completion(devh, transfer,
LIBUSB_TRANSFER_TIMED_OUT);
} }
/* otherwise its a normal async cancel */ /* otherwise its a normal async cancel */
return handle_transfer_completion(devh, urbh, FP_URB_CANCELLED); return handle_transfer_completion(devh, transfer,
LIBUSB_TRANSFER_CANCELLED);
} }
static int reap_for_devh(struct libusb_dev_handle *devh) static int reap_for_devh(struct libusb_dev_handle *devh)
{ {
int r; int r;
struct usb_urb *urb; struct usb_urb *urb;
struct libusb_urb_handle *urbh; struct libusb_transfer *transfer;
int trf_requested; int trf_requested;
r = ioctl(devh->fd, IOCTL_USB_REAPURBNDELAY, &urb); r = ioctl(devh->fd, IOCTL_USB_REAPURBNDELAY, &urb);
@ -343,45 +351,47 @@ static int reap_for_devh(struct libusb_dev_handle *devh)
return r; return r;
} }
urbh = container_of(urb, struct libusb_urb_handle, urb); transfer = container_of(urb, struct libusb_transfer, urb);
usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status, usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status,
urb->actual_length); urb->actual_length);
list_del(&urbh->list); list_del(&transfer->list);
if (urb->status == -2) if (urb->status == -2)
return handle_transfer_cancellation(devh, urbh); return handle_transfer_cancellation(devh, transfer);
/* FIXME: research what other status codes may exist */ /* FIXME: research what other status codes may exist */
if (urb->status != 0) if (urb->status != 0)
usbi_warn("unrecognised urb status %d", urb->status); usbi_warn("unrecognised urb status %d", urb->status);
/* determine how much data was asked for */ /* determine how much data was asked for */
trf_requested = MIN(urbh->transfer_len - urbh->transferred, trf_requested = MIN(transfer->transfer_len - transfer->transferred,
MAX_URB_BUFFER_LENGTH); MAX_URB_BUFFER_LENGTH);
urbh->transferred += urb->actual_length; transfer->transferred += urb->actual_length;
/* if we were provided less data than requested, then our transfer is /* if we were provided less data than requested, then our transfer is
* done */ * done */
if (urb->actual_length < trf_requested) { if (urb->actual_length < trf_requested) {
usbi_dbg("less data than requested (%d/%d) --> all done", usbi_dbg("less data than requested (%d/%d) --> all done",
urb->actual_length, trf_requested); urb->actual_length, trf_requested);
return handle_transfer_completion(devh, urbh, FP_URB_COMPLETED); return handle_transfer_completion(devh, transfer,
LIBUSB_TRANSFER_COMPLETED);
} }
/* if we've transferred all data, we're done */ /* if we've transferred all data, we're done */
if (urbh->transferred == urbh->transfer_len) { if (transfer->transferred == transfer->transfer_len) {
usbi_dbg("transfer complete --> all done"); usbi_dbg("transfer complete --> all done");
return handle_transfer_completion(devh, urbh, FP_URB_COMPLETED); return handle_transfer_completion(devh, transfer,
LIBUSB_TRANSFER_COMPLETED);
} }
/* otherwise, we have more data to transfer */ /* otherwise, we have more data to transfer */
usbi_dbg("more data to transfer..."); usbi_dbg("more data to transfer...");
memset(urb, 0, sizeof(*urb)); memset(urb, 0, sizeof(*urb));
return submit_urb(devh, urbh); return submit_transfer(devh, transfer);
} }
static void handle_timeout(struct libusb_urb_handle *urbh) static void handle_timeout(struct libusb_transfer *transfer)
{ {
/* handling timeouts is tricky, as we may race with the kernel: we may /* handling timeouts is tricky, as we may race with the kernel: we may
* detect a timeout racing with the condition that the urb has actually * detect a timeout racing with the condition that the urb has actually
@ -391,8 +401,8 @@ static void handle_timeout(struct libusb_urb_handle *urbh)
int r; int r;
urbh->flags |= LIBUSB_URBH_TIMED_OUT; transfer->flags |= USBI_TRANSFER_TIMED_OUT;
r = libusb_urb_handle_cancel(urbh->devh, urbh); r = libusb_transfer_cancel(transfer->devh, transfer);
if (r < 0) if (r < 0)
usbi_warn("async cancel failed %d errno=%d", r, errno); usbi_warn("async cancel failed %d errno=%d", r, errno);
} }
@ -401,10 +411,10 @@ static int handle_timeouts(void)
{ {
struct timespec systime_ts; struct timespec systime_ts;
struct timeval systime; struct timeval systime;
struct libusb_urb_handle *urbh; struct libusb_transfer *transfer;
int r; int r;
if (list_empty(&flying_urbs)) if (list_empty(&flying_transfers))
return 0; return 0;
/* get current time */ /* get current time */
@ -414,27 +424,27 @@ static int handle_timeouts(void)
TIMESPEC_TO_TIMEVAL(&systime, &systime_ts); TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
/* iterate through flying urbs list, finding all urbs that have expired /* iterate through flying transfers list, finding all transfers that
* timeouts */ * have expired timeouts */
list_for_each_entry(urbh, &flying_urbs, list) { list_for_each_entry(transfer, &flying_transfers, list) {
struct timeval *cur_tv = &urbh->timeout; struct timeval *cur_tv = &transfer->timeout;
/* if we've reached urbs of infinite timeout, we're all done */ /* if we've reached transfers of infinite timeout, we're all done */
if (!timerisset(cur_tv)) if (!timerisset(cur_tv))
return 0; return 0;
/* ignore timeouts we've already handled */ /* ignore timeouts we've already handled */
if (urbh->flags & LIBUSB_URBH_TIMED_OUT) if (transfer->flags & USBI_TRANSFER_TIMED_OUT)
continue; continue;
/* if urb has non-expired timeout, nothing more to do */ /* if transfer has non-expired timeout, nothing more to do */
if ((cur_tv->tv_sec > systime.tv_sec) || if ((cur_tv->tv_sec > systime.tv_sec) ||
(cur_tv->tv_sec == systime.tv_sec && (cur_tv->tv_sec == systime.tv_sec &&
cur_tv->tv_usec > systime.tv_usec)) cur_tv->tv_usec > systime.tv_usec))
return 0; return 0;
/* otherwise, we've got an expired timeout to handle */ /* otherwise, we've got an expired timeout to handle */
handle_timeout(urbh); handle_timeout(transfer);
} }
return 0; return 0;
@ -516,21 +526,21 @@ API_EXPORTED int libusb_poll(void)
API_EXPORTED int libusb_get_next_timeout(struct timeval *tv) API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
{ {
struct libusb_urb_handle *urbh; struct libusb_transfer *transfer;
struct timespec cur_ts; struct timespec cur_ts;
struct timeval cur_tv; struct timeval cur_tv;
struct timeval *next_timeout; struct timeval *next_timeout;
int r; int r;
int found = 0; int found = 0;
if (list_empty(&flying_urbs)) { if (list_empty(&flying_transfers)) {
usbi_dbg("no URBs, no timeout!"); usbi_dbg("no URBs, no timeout!");
return 0; return 0;
} }
/* find next urb which hasn't already been processed as timed out */ /* find next transfer which hasn't already been processed as timed out */
list_for_each_entry(urbh, &flying_urbs, list) { list_for_each_entry(transfer, &flying_transfers, list) {
if (!(urbh->flags & LIBUSB_URBH_TIMED_OUT)) { if (!(transfer->flags & USBI_TRANSFER_TIMED_OUT)) {
found = 1; found = 1;
break; break;
} }
@ -541,9 +551,9 @@ API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
return 0; return 0;
} }
next_timeout = &urbh->timeout; next_timeout = &transfer->timeout;
/* no timeout for next urb */ /* no timeout for next transfer */
if (!timerisset(next_timeout)) { if (!timerisset(next_timeout)) {
usbi_dbg("no URBs with timeouts, no timeout!"); usbi_dbg("no URBs with timeouts, no timeout!");
return 0; return 0;
@ -568,20 +578,20 @@ API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
} }
struct sync_ctrl_handle { struct sync_ctrl_handle {
enum libusb_urb_cb_status status; enum libusb_transfer_status status;
unsigned char *data; unsigned char *data;
int actual_length; int actual_length;
}; };
static void ctrl_transfer_cb(struct libusb_dev_handle *devh, static void ctrl_transfer_cb(struct libusb_dev_handle *devh,
struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status, struct libusb_transfer *transfer, enum libusb_transfer_status status,
struct libusb_ctrl_setup *setup, unsigned char *data, int actual_length, struct libusb_control_setup *setup, unsigned char *data, int actual_length,
void *user_data) void *user_data)
{ {
struct sync_ctrl_handle *ctrlh = (struct sync_ctrl_handle *) user_data; struct sync_ctrl_handle *ctrlh = (struct sync_ctrl_handle *) user_data;
usbi_dbg("actual_length=%d", actual_length); usbi_dbg("actual_length=%d", actual_length);
if (status == FP_URB_COMPLETED) { if (status == LIBUSB_TRANSFER_COMPLETED) {
/* copy results into user-defined buffer */ /* copy results into user-defined buffer */
if (setup->bRequestType & LIBUSB_ENDPOINT_IN) if (setup->bRequestType & LIBUSB_ENDPOINT_IN)
memcpy(ctrlh->data, data, actual_length); memcpy(ctrlh->data, data, actual_length);
@ -589,37 +599,37 @@ static void ctrl_transfer_cb(struct libusb_dev_handle *devh,
ctrlh->status = status; ctrlh->status = status;
ctrlh->actual_length = actual_length; ctrlh->actual_length = actual_length;
/* caller frees urbh */ /* caller frees transfer */
} }
API_EXPORTED int libusb_control_transfer(struct libusb_dev_handle *devh, API_EXPORTED int libusb_control_transfer(struct libusb_dev_handle *devh,
struct libusb_control_transfer *transfer, unsigned int timeout) struct libusb_control_transfer_request *request, unsigned int timeout)
{ {
struct libusb_urb_handle *urbh; struct libusb_transfer *transfer;
struct sync_ctrl_handle ctrlh; struct sync_ctrl_handle ctrlh;
memset(&ctrlh, 0, sizeof(ctrlh)); memset(&ctrlh, 0, sizeof(ctrlh));
ctrlh.data = transfer->data; ctrlh.data = request->data;
urbh = libusb_async_control_transfer(devh, transfer, ctrl_transfer_cb, transfer = libusb_async_control_transfer(devh, request, ctrl_transfer_cb,
&ctrlh, timeout); &ctrlh, timeout);
if (!urbh) if (!transfer)
return -1; return -1;
while (!ctrlh.status) { while (!ctrlh.status) {
int r = libusb_poll(); int r = libusb_poll();
if (r < 0) { if (r < 0) {
libusb_urb_handle_cancel_sync(devh, urbh); libusb_transfer_cancel_sync(devh, transfer);
libusb_urb_handle_free(urbh); libusb_transfer_free(transfer);
return r; return r;
} }
} }
libusb_urb_handle_free(urbh); libusb_transfer_free(transfer);
switch (ctrlh.status) { switch (ctrlh.status) {
case FP_URB_COMPLETED: case LIBUSB_TRANSFER_COMPLETED:
return ctrlh.actual_length; return ctrlh.actual_length;
case FP_URB_TIMEOUT: case LIBUSB_TRANSFER_TIMED_OUT:
return -ETIMEDOUT; return -ETIMEDOUT;
default: default:
usbi_warn("unrecognised status code %d", ctrlh.status); usbi_warn("unrecognised status code %d", ctrlh.status);
@ -628,12 +638,12 @@ API_EXPORTED int libusb_control_transfer(struct libusb_dev_handle *devh,
} }
struct sync_bulk_handle { struct sync_bulk_handle {
enum libusb_urb_cb_status status; enum libusb_transfer_status status;
int actual_length; int actual_length;
}; };
static void bulk_transfer_cb(struct libusb_dev_handle *devh, static void bulk_transfer_cb(struct libusb_dev_handle *devh,
struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status, struct libusb_transfer *transfer, enum libusb_transfer_status status,
unsigned char endpoint, int rqlength, unsigned char *data, unsigned char endpoint, int rqlength, unsigned char *data,
int actual_length, void *user_data) int actual_length, void *user_data)
{ {
@ -641,39 +651,39 @@ static void bulk_transfer_cb(struct libusb_dev_handle *devh,
usbi_dbg(""); usbi_dbg("");
bulkh->status = status; bulkh->status = status;
bulkh->actual_length = actual_length; bulkh->actual_length = actual_length;
/* caller frees urbh */ /* caller frees transfer */
} }
static int do_sync_bulk_transfer(struct libusb_dev_handle *devh, static int do_sync_bulk_transfer(struct libusb_dev_handle *devh,
struct libusb_bulk_transfer *transfer, int *transferred, struct libusb_bulk_transfer_request *request, int *transferred,
unsigned int timeout, unsigned char urbtype) unsigned int timeout, unsigned char urbtype)
{ {
struct libusb_urb_handle *urbh; struct libusb_transfer *transfer;
struct sync_bulk_handle bulkh; struct sync_bulk_handle bulkh;
memset(&bulkh, 0, sizeof(bulkh)); memset(&bulkh, 0, sizeof(bulkh));
urbh = submit_bulk_transfer(devh, transfer, bulk_transfer_cb, &bulkh, transfer = submit_bulk_transfer(devh, request, bulk_transfer_cb, &bulkh,
timeout, urbtype); timeout, urbtype);
if (!urbh) if (!transfer)
return -1; return -1;
while (!bulkh.status) { while (!bulkh.status) {
int r = libusb_poll(); int r = libusb_poll();
if (r < 0) { if (r < 0) {
libusb_urb_handle_cancel_sync(devh, urbh); libusb_transfer_cancel_sync(devh, transfer);
libusb_urb_handle_free(urbh); libusb_transfer_free(transfer);
return r; return r;
} }
} }
*transferred = bulkh.actual_length; *transferred = bulkh.actual_length;
libusb_urb_handle_free(urbh); libusb_transfer_free(transfer);
switch (bulkh.status) { switch (bulkh.status) {
case FP_URB_COMPLETED: case LIBUSB_TRANSFER_COMPLETED:
return 0; return 0;
case FP_URB_TIMEOUT: case LIBUSB_TRANSFER_TIMED_OUT:
return -ETIMEDOUT; return -ETIMEDOUT;
default: default:
usbi_warn("unrecognised status code %d", bulkh.status); usbi_warn("unrecognised status code %d", bulkh.status);
@ -682,29 +692,29 @@ static int do_sync_bulk_transfer(struct libusb_dev_handle *devh,
} }
API_EXPORTED int libusb_interrupt_transfer(struct libusb_dev_handle *devh, API_EXPORTED int libusb_interrupt_transfer(struct libusb_dev_handle *devh,
struct libusb_bulk_transfer *transfer, int *transferred, struct libusb_bulk_transfer_request *request, int *transferred,
unsigned int timeout) unsigned int timeout)
{ {
return do_sync_bulk_transfer(devh, transfer, transferred, timeout, return do_sync_bulk_transfer(devh, request, transferred, timeout,
USB_URB_TYPE_INTERRUPT); USB_URB_TYPE_INTERRUPT);
} }
API_EXPORTED int libusb_bulk_transfer(struct libusb_dev_handle *devh, API_EXPORTED int libusb_bulk_transfer(struct libusb_dev_handle *devh,
struct libusb_bulk_transfer *transfer, int *transferred, struct libusb_bulk_transfer_request *request, int *transferred,
unsigned int timeout) unsigned int timeout)
{ {
return do_sync_bulk_transfer(devh, transfer, transferred, timeout, return do_sync_bulk_transfer(devh, request, transferred, timeout,
USB_URB_TYPE_BULK); USB_URB_TYPE_BULK);
} }
API_EXPORTED void libusb_urb_handle_free(struct libusb_urb_handle *urbh) API_EXPORTED void libusb_transfer_free(struct libusb_transfer *transfer)
{ {
if (!urbh) if (!transfer)
return; return;
if (!(urbh->flags & LIBUSB_URBH_DATA_BELONGS_TO_USER)) if (!(transfer->flags & USBI_TRANSFER_DATA_BELONGS_TO_USER))
free(urbh->urb.buffer); free(transfer->urb.buffer);
free(urbh); free(transfer);
} }
API_EXPORTED void libusb_set_pollfd_notifiers(libusb_pollfd_added_cb added_cb, API_EXPORTED void libusb_set_pollfd_notifiers(libusb_pollfd_added_cb added_cb,

View file

@ -1,6 +1,6 @@
/* /*
* Public libusb header file * Public libusb header file
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org> * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com> * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -170,7 +170,7 @@ struct libusb_config_descriptor {
/* off-the-wire structures */ /* off-the-wire structures */
struct libusb_ctrl_setup { struct libusb_control_setup {
uint8_t bRequestType; uint8_t bRequestType;
uint8_t bRequest; uint8_t bRequest;
uint16_t wValue; uint16_t wValue;
@ -186,17 +186,17 @@ typedef struct libusb_device libusb_device;
struct libusb_dev_handle; struct libusb_dev_handle;
typedef struct libusb_dev_handle libusb_dev_handle; typedef struct libusb_dev_handle libusb_dev_handle;
struct libusb_urb_handle; struct libusb_transfer;
typedef struct libusb_urb_handle libusb_urb_handle; typedef struct libusb_transfer libusb_transfer;
enum libusb_urb_cb_status { enum libusb_transfer_status {
FP_URB_SILENT_COMPLETION = 0, LIBUSB_TRANSFER_SILENT_COMPLETION = 0,
FP_URB_COMPLETED, LIBUSB_TRANSFER_COMPLETED,
FP_URB_TIMEOUT, LIBUSB_TRANSFER_TIMED_OUT,
FP_URB_CANCELLED, LIBUSB_TRANSFER_CANCELLED,
}; };
struct libusb_control_transfer { struct libusb_control_transfer_request {
uint8_t requesttype; uint8_t requesttype;
uint8_t request; uint8_t request;
uint16_t value; uint16_t value;
@ -205,19 +205,21 @@ struct libusb_control_transfer {
unsigned char *data; unsigned char *data;
}; };
typedef void (*libusb_ctrl_cb_fn)(libusb_dev_handle *devh, libusb_urb_handle *urbh, typedef void (*libusb_control_cb_fn)(libusb_dev_handle *devh,
enum libusb_urb_cb_status status, struct libusb_ctrl_setup *setup, libusb_transfer *transfer, enum libusb_transfer_status status,
unsigned char *data, int actual_length, void *user_data); struct libusb_control_setup *setup, unsigned char *data,
int actual_length, void *user_data);
struct libusb_bulk_transfer { struct libusb_bulk_transfer_request {
unsigned char endpoint; unsigned char endpoint;
unsigned char *data; unsigned char *data;
int length; int length;
}; };
typedef void (*libusb_bulk_cb_fn)(libusb_dev_handle *devh, libusb_urb_handle *urbh, typedef void (*libusb_bulk_cb_fn)(libusb_dev_handle *devh,
enum libusb_urb_cb_status status, unsigned char endpoint, libusb_transfer *transfer, enum libusb_transfer_status status,
int rqlength, unsigned char *data, int actual_length, void *user_data); unsigned char endpoint, int rqlength, unsigned char *data,
int actual_length, void *user_data);
int libusb_init(void); int libusb_init(void);
void libusb_exit(void); void libusb_exit(void);
@ -240,30 +242,30 @@ libusb_dev_handle *libusb_open_device_with_vid_pid(uint16_t vendor_id,
/* async I/O */ /* async I/O */
libusb_urb_handle *libusb_async_control_transfer(libusb_dev_handle *devh, libusb_transfer *libusb_async_control_transfer(libusb_dev_handle *devh,
struct libusb_control_transfer *transfer, libusb_ctrl_cb_fn callback, struct libusb_control_transfer_request *request,
libusb_control_cb_fn callback, void *user_data, unsigned int timeout);
libusb_transfer *libusb_async_bulk_transfer(libusb_dev_handle *devh,
struct libusb_bulk_transfer_request *request, libusb_bulk_cb_fn callback,
void *user_data, unsigned int timeout); void *user_data, unsigned int timeout);
libusb_urb_handle *libusb_async_bulk_transfer(libusb_dev_handle *devh, libusb_transfer *libusb_async_interrupt_transfer(libusb_dev_handle *devh,
struct libusb_bulk_transfer *transfer, libusb_bulk_cb_fn callback, struct libusb_bulk_transfer_request *request, libusb_bulk_cb_fn callback,
void *user_data, unsigned int timeout);
libusb_urb_handle *libusb_async_interrupt_transfer(libusb_dev_handle *devh,
struct libusb_bulk_transfer *transfer, libusb_bulk_cb_fn callback,
void *user_data, unsigned int timeout); void *user_data, unsigned int timeout);
int libusb_urb_handle_cancel(libusb_dev_handle *devh, libusb_urb_handle *urbh); int libusb_transfer_cancel(libusb_dev_handle *devh, libusb_transfer *transfer);
int libusb_urb_handle_cancel_sync(libusb_dev_handle *devh, int libusb_transfer_cancel_sync(libusb_dev_handle *devh,
libusb_urb_handle *urbh); libusb_transfer *transfer);
void libusb_urb_handle_free(libusb_urb_handle *urbh); void libusb_transfer_free(libusb_transfer *transfer);
/* sync I/O */ /* sync I/O */
int libusb_control_transfer(libusb_dev_handle *devh, int libusb_control_transfer(libusb_dev_handle *devh,
struct libusb_control_transfer *transfer, unsigned int timeout); struct libusb_control_transfer_request *request, unsigned int timeout);
int libusb_bulk_transfer(libusb_dev_handle *devh, int libusb_bulk_transfer(libusb_dev_handle *devh,
struct libusb_bulk_transfer *transfer, int *transferred, struct libusb_bulk_transfer_request *request, int *transferred,
unsigned int timeout); unsigned int timeout);
int libusb_interrupt_transfer(libusb_dev_handle *devh, int libusb_interrupt_transfer(libusb_dev_handle *devh,
struct libusb_bulk_transfer *transfer, int *transferred, struct libusb_bulk_transfer_request *request, int *transferred,
unsigned int timeout); unsigned int timeout);
/* polling and timeouts */ /* polling and timeouts */

View file

@ -157,16 +157,16 @@ struct libusb_dev_handle {
int fd; int fd;
}; };
enum libusb_urb_type { enum libusb_transfer_type {
LIBUSB_URB_CONTROL, LIBUSB_TRANSFER_CONTROL,
LIBUSB_URB_BULK, LIBUSB_TRANSFER_BULK,
}; };
#define LIBUSB_URBH_DATA_BELONGS_TO_USER (1<<0) #define USBI_TRANSFER_DATA_BELONGS_TO_USER (1<<0)
#define LIBUSB_URBH_SYNC_CANCELLED (1<<1) #define USBI_TRANSFER_SYNC_CANCELLED (1<<1)
#define LIBUSB_URBH_TIMED_OUT (1<<2) #define USBI_TRANSFER_TIMED_OUT (1<<2)
struct libusb_urb_handle { struct libusb_transfer {
struct libusb_dev_handle *devh; struct libusb_dev_handle *devh;
struct usb_urb urb; struct usb_urb urb;
struct list_head list; struct list_head list;