PERFORCE change 161665 for review
Sylvestre Gallon
syl at FreeBSD.org
Wed May 6 18:47:48 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=161665
Change 161665 by syl at syl_atuin on 2009/05/06 18:47:12
- remove zero length array entries in libusb.h
- implement libusb_reset_device
- implement libusb_submit_transfer
- implement libusb_handle_event
- implement libusb_control_transfer
- implement libusb_bulk_transfer
- implement libusb_interrupt_transfer
libusb10 needs more work on I/Os to have functional synchronous
transfer supported.
Affected files ...
.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb.h#5 edit
.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#3 edit
Differences ...
==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb.h#5 (text+ko) ====
@@ -329,7 +329,7 @@
void *user_data;
unsigned char *buffer;
int num_iso_packets;
- struct libusb_iso_packet_descriptor iso_packet_desc[0];
+ struct libusb_iso_packet_descriptor *iso_packet_desc;
} libusb_transfer __aligned(sizeof(void *));
typedef struct libusb_pollfd {
==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#3 (text+ko) ====
@@ -412,6 +412,10 @@
int
libusb_reset_device(libusb_device_handle * dev)
{
+ if (dev == NULL)
+ return (LIBUSB20_ERROR_NO_MEM);
+
+ libusb20_dev_reset(dev->os_priv);
return (0);
}
@@ -467,76 +471,55 @@
}
void
-libusb_free_transfer(struct libusb_transfer *transfer)
+libusb_free_transfer(struct libusb_transfer *tr)
{
- if (transfer == NULL)
+ if (tr == NULL)
return ;
- if (transfer->buffer)
- free(transfer->buffer);
- if (transfer->user_data)
- free(transfer->user_data);
+ if (tr->buffer)
+ free(tr->buffer);
+ if (tr->user_data)
+ free(tr->user_data);
- free (transfer);
+ free(tr);
return;
}
-int
-libusb_submit_transfer(struct libusb_transfer *transfer)
+
+static void
+libusb10_proxy(struct libusb20_transfer *xfer)
{
- return (0);
+ ((libusb_transfer_cb_fn)libusb20_tr_get_priv_sc0(xfer))(libusb20_tr_get_priv_sc1(xfer));
}
int
-libusb_cancel_transfer(struct libusb_transfer *transfer)
+libusb_submit_transfer(struct libusb_transfer *tr)
{
- return (0);
-}
+ struct libusb20_transfer xfer;
+ int ret;
-static unsigned char *
-libusb_control_transfer_get_data(struct libusb_transfer *transfer)
-{
- return (NULL);
-}
+ libusb20_tr_open(&xfer, tr->length, tr->num_iso_packets, tr->endpoint);
+ libusb20_tr_set_timeout(&xfer, tr->timeout);
+ libusb20_tr_set_buffer(&xfer, tr->buffer, tr->num_iso_packets);
+ libusb20_tr_set_length(&xfer, tr->length, tr->num_iso_packets);
+ libusb20_tr_set_priv_sc0(&xfer, tr->callback);
+ libusb20_tr_set_priv_sc1(&xfer, tr->user_data);
+ libusb20_tr_set_callback(&xfer, libusb10_proxy);
+ libusb20_tr_submit(&xfer);
-static struct libusb_control_setup *
-libusb_control_transfer_get_setup(struct libusb_transfer *transfer)
-{
- return (NULL);
+ switch (libusb20_tr_get_status(&xfer)) {
+ case 1:
+ default:
+ ret = LIBUSB_ERROR_OTHER;
+ }
+ return (ret);
}
-static void
-libusb_fill_control_setup(unsigned char *buffer, uint8_t bmRequestType,
- uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength)
+int
+libusb_cancel_transfer(struct libusb_transfer *transfer)
{
- return;
+ return (0);
}
-static void
-libusb_fill_control_transfer(struct libusb_transfer *transfer,
- libusb_device_handle * dev_handle, unsigned char *buffer,
- libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout)
-{
- return;
-}
-
-static void
-libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
- libusb_device_handle * dev_handle, unsigned char endpoint,
- unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
- void *user_data, unsigned int timeout)
-{
- return;
-}
-
-static void
-libusb_fill_interrupt_transfer(struct libusb_transfer *transfer,
- libusb_device_handle * dev_handle, unsigned char endpoint,
- unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
- void *user_data, unsigned int timeout)
-{
- return;
-}
-
/* Polling and timing */
int
@@ -596,7 +579,11 @@
int
libusb_handle_events(libusb_context * ctx)
{
- return (0);
+ struct timeval tv;
+
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+ return (libusb_handle_events_timeout(ctx, &tv));
}
int
@@ -627,26 +614,156 @@
/* Synchronous device I/O */
+static void ctrl_tr_cb(struct libusb_transfer *transfer)
+{
+ int *complet = transfer->user_data;
+
+ *complet = 1;
+}
+
int
-libusb_control_transfer(libusb_device_handle * dev_handle,
+libusb_control_transfer(libusb_device_handle * devh,
uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
unsigned char *data, uint16_t wLength, unsigned int timeout)
{
- return (0);
+ struct libusb_transfer *tr;
+ struct libusb_control_setup *ctr;
+ unsigned char *buff;
+ int complet;
+ int ret;
+
+ if (devh == NULL || data == NULL)
+ return (LIBUSB_ERROR_NO_MEM);
+
+ tr = libusb_alloc_transfer(0);
+ if (tr == NULL)
+ return (LIBUSB_ERROR_NO_MEM);
+
+ buff = malloc(sizeof(libusb_control_setup) + wLength);
+ if (buff == NULL) {
+ libusb_free_transfer(tr);
+ return (LIBUSB_ERROR_NO_MEM);
+ }
+
+ ctr = (libusb_control_setup *)buff;
+ ctr->bmRequestType = bmRequestType;
+ ctr->bRequest = bRequest;
+ ctr->wValue = wValue;
+ ctr->wIndex = wIndex;
+ ctr->wLength = wLength;
+ if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
+ memcpy(buff + sizeof(libusb_control_setup), data, wLength);
+
+ tr->dev_handle = devh;
+ tr->endpoint = 0;
+ tr->type = LIBUSB_TRANSFER_TYPE_CONTROL;
+ tr->timeout = timeout;
+ tr->buffer = buff;
+ tr->length = sizeof(libusb_control_setup) + wLength;
+ tr->user_data = &complet;
+ tr->callback = ctrl_tr_cb;
+ tr->flags = LIBUSB_TRANSFER_FREE_TRANSFER;
+ complet = 0;
+
+ if ((ret = libusb_submit_transfer(tr)) < 0) {
+ libusb_free_transfer(tr);
+ return (ret);
+ }
+
+ while (!complet)
+ if ((ret = libusb_handle_events(devh->dev->ctx)) < 0) {
+ libusb_cancel_transfer(tr);
+ libusb_free_transfer(tr);
+ while (!complet)
+ if (libusb_handle_events(devh->dev->ctx))
+ break;
+ return (ret);
+ }
+
+ if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
+ memcpy(data, buff + sizeof(libusb_control_setup), wLength);
+
+ switch (tr->status) {
+ case LIBUSB_TRANSFER_COMPLETED:
+ ret = tr->actual_length;
+ break;
+ case LIBUSB_TRANSFER_TIMED_OUT:
+ case LIBUSB_TRANSFER_STALL:
+ case LIBUSB_TRANSFER_NO_DEVICE:
+ ret = tr->status;
+ break;
+ default:
+ ret = LIBUSB_ERROR_OTHER;
+ }
+ libusb_free_transfer(tr);
+ return (ret);
}
int
-libusb_bulk_transfer(struct libusb_device_handle *dev_handle,
+libusb_bulk_transfer(struct libusb_device_handle *devh,
unsigned char endpoint, unsigned char *data, int length,
int *transferred, unsigned int timeout)
{
+ struct libusb_transfer *tr;
+ int complet;
+ int ret;
+
+ if (devh == NULL || data == NULL)
+ return (LIBUSB_ERROR_NO_MEM);
+
+ tr = libusb_alloc_transfer(0);
+ if (tr == NULL)
+ return (LIBUSB_ERROR_NO_MEM);
+
+ tr->dev_handle = devh;
+ tr->endpoint = endpoint;
+ tr->type = LIBUSB_TRANSFER_TYPE_BULK;
+ tr->timeout = timeout;
+ tr->buffer = data;
+ tr->length = length;
+ tr->user_data = &complet;
+ tr->callback = ctrl_tr_cb;
+ complet = 0;
+
+ if ((ret = libusb_submit_transfer(tr)) < 0) {
+ libusb_free_transfer(tr);
+ return (ret);
+ }
+
+ while (!complet)
+ if ((ret = libusb_handle_events(devh->dev->ctx)) < 0) {
+ libusb_cancel_transfer(tr);
+ libusb_free_transfer(tr);
+ while (!complet)
+ if (libusb_handle_events(devh->dev->ctx))
+ break;
+ return (ret);
+ }
+
+ *transferred = tr->actual_length;
+ switch (tr->status) {
+ case LIBUSB_TRANSFER_COMPLETED:
+ ret = tr->actual_length;
+ break;
+ case LIBUSB_TRANSFER_TIMED_OUT:
+ case LIBUSB_TRANSFER_OVERFLOW:
+ case LIBUSB_TRANSFER_STALL:
+ case LIBUSB_TRANSFER_NO_DEVICE:
+ ret = tr->status;
+ break;
+ default:
+ ret = LIBUSB_ERROR_OTHER;
+ }
+
+ libusb_free_transfer(tr);
return (0);
}
int
-libusb_interrupt_transfer(struct libusb_device_handle *dev_handle,
+libusb_interrupt_transfer(struct libusb_device_handle *devh,
unsigned char endpoint, unsigned char *data, int length, int *transferred,
unsigned int timeout)
{
- return (0);
+ return (libusb_bulk_transfer(devh, endpoint, data, length,
+ transferred, timeout));
}
More information about the p4-projects
mailing list