Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 May 2009 18:47:46 GMT
From:      Sylvestre Gallon <syl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 161665 for review
Message-ID:  <200905061847.n46Ilj9l009463@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=161665

Change 161665 by syl@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));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905061847.n46Ilj9l009463>