Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 May 2009 11:28:16 GMT
From:      Sylvestre Gallon <syl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 163077 for review
Message-ID:  <200905301128.n4UBSGad022347@repoman.freebsd.org>

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

Change 163077 by syl@syl_rincewind on 2009/05/30 11:28:06

	- Remove ; at the end of a if in handle_timeouts.
	- Finish the implementation of handle_events.
	- Implement the usb_handle_disconnect helper.
	- Implement the usb_handle_transfer_completion helper.
	- Inline usb_add_pollfd and usb_remove_pollfd into libusb10.h.

Affected files ...

.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#20 edit
.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.h#3 edit
.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10_io.c#4 edit

Differences ...

==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.c#20 (text+ko) ====

@@ -57,59 +57,6 @@
 		ctx->debug = level;
 }
 
-static int
-usb_add_pollfd(libusb_context *ctx, int fd, short events)
-{
-	struct usb_pollfd *pollfd;
-
-	if (ctx == NULL)
-		return (LIBUSB_ERROR_INVALID_PARAM);
-	
-	pollfd = malloc(sizeof(*pollfd));
-	if (pollfd == NULL)
-		return (LIBUSB_ERROR_NO_MEM);
-
-	pollfd->pollfd.fd = fd;
-	pollfd->pollfd.events = events;
-
-	pthread_mutex_lock(&ctx->pollfds_lock);
-	LIST_ADD_TAIL(&pollfd->list, &ctx->pollfds);
-	pthread_mutex_unlock(&ctx->pollfds_lock);
-
-	if (ctx->fd_added_cb)
-		ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
-	return (0);
-}
-
-static void
-usb_remove_pollfd(libusb_context *ctx, int fd)
-{
-	struct usb_pollfd *pollfd;
-	int found;
-
-	found = 0;
-	pthread_mutex_lock(&ctx->pollfds_lock);
-
-	LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) {
-		if (pollfd->pollfd.fd == fd) {
-			found = 1;
-			break ;
-		}
-	}
-
-	if (found == 0) {
-		pthread_mutex_unlock(&ctx->pollfds_lock);
-		return ;
-	}
-
-	LIST_DEL(&pollfd->list);
-	pthread_mutex_unlock(&ctx->pollfds_lock);
-	free(pollfd);
-
-	if (ctx->fd_removed_cb)
-		ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
-}
-
 int
 libusb_init(libusb_context ** context)
 {

==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10.h#3 (text+ko) ====

@@ -95,4 +95,127 @@
 	uint8_t flags;
 };
 
+static inline int
+usb_add_pollfd(libusb_context *ctx, int fd, short events)
+{
+	struct usb_pollfd *pollfd;
+
+	if (ctx == NULL)
+		return (LIBUSB_ERROR_INVALID_PARAM);
+	
+	pollfd = malloc(sizeof(*pollfd));
+	if (pollfd == NULL)
+		return (LIBUSB_ERROR_NO_MEM);
+
+	pollfd->pollfd.fd = fd;
+	pollfd->pollfd.events = events;
+
+	pthread_mutex_lock(&ctx->pollfds_lock);
+	LIST_ADD_TAIL(&pollfd->list, &ctx->pollfds);
+	pthread_mutex_unlock(&ctx->pollfds_lock);
+
+	if (ctx->fd_added_cb)
+		ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
+	return (0);
+}
+
+static inline void
+usb_remove_pollfd(libusb_context *ctx, int fd)
+{
+	struct usb_pollfd *pollfd;
+	int found;
+
+	found = 0;
+	pthread_mutex_lock(&ctx->pollfds_lock);
+
+	LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) {
+		if (pollfd->pollfd.fd == fd) {
+			found = 1;
+			break ;
+		}
+	}
+
+	if (found == 0) {
+		pthread_mutex_unlock(&ctx->pollfds_lock);
+		return ;
+	}
+
+	LIST_DEL(&pollfd->list);
+	pthread_mutex_unlock(&ctx->pollfds_lock);
+	free(pollfd);
+
+	if (ctx->fd_removed_cb)
+		ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
+}
+
+static inline void
+usb_handle_transfer_completion(struct usb_transfer *uxfer, 
+    enum libusb_transfer_status status)
+{
+	libusb_transfer *xfer;
+	libusb_context *ctx;
+	int len;
+
+	xfer = (struct libusb_transfer *) ((uint8_t *)uxfer + 
+	    sizeof(struct usb_transfer));
+	ctx = xfer->dev_handle->dev->ctx;
+
+	pthread_mutex_lock(&ctx->flying_transfers_lock);
+	LIST_DEL(&uxfer->list);
+	pthread_mutex_unlock(&ctx->flying_transfers_lock);
+
+	if (status == LIBUSB_TRANSFER_COMPLETED && xfer->flags &
+	    LIBUSB_TRANSFER_SHORT_NOT_OK) {
+		len = xfer->length;
+		if (xfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
+			len -= sizeof(libusb_control_setup);
+		if (len != uxfer->transferred) {
+			status = LIBUSB_TRANSFER_ERROR;
+		}
+	}
+
+	xfer->status = status;
+	xfer->actual_length = uxfer->transferred;
+
+	if (xfer->callback)
+		xfer->callback(xfer);
+	if (xfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER)
+		libusb_free_transfer(xfer);
+
+	pthread_mutex_lock(&ctx->event_waiters_lock);
+	pthread_cond_broadcast(&ctx->event_waiters_cond);
+	pthread_mutex_unlock(&ctx->event_waiters_lock);
+}
+
+static inline void
+usb_handle_disconnect(struct libusb_device_handle *devh)
+{
+	struct libusb_context *ctx;
+	struct libusb_transfer *xfer;
+	struct usb_transfer *cur;
+	struct usb_transfer *to_cancel;
+
+	ctx = devh->dev->ctx;
+
+	while (1) {
+		pthread_mutex_lock(&ctx->flying_transfers_lock);
+		to_cancel = NULL;
+		LIST_FOREACH_ENTRY(cur, &ctx->flying_transfers, list) {
+			xfer = (struct libusb_transfer *) ((uint8_t *)cur + 
+	    		    sizeof(struct usb_transfer));
+			if (xfer->dev_handle == devh) {
+				to_cancel = cur;
+				break ;
+			}
+		}
+		pthread_mutex_unlock(&ctx->flying_transfers_lock);
+
+		if (to_cancel == NULL)
+			break ;
+		
+		usb_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE);
+	}
+	return ;
+}
+
 #endif /*__LIBUSB10_H__*/

==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10_io.c#4 (text+ko) ====

@@ -74,7 +74,7 @@
 	ret = 0;
 
 	pthread_mutex_lock(&ctx->flying_transfers_lock);
-	if (USB_LIST_EMPTY(&ctx->flying_transfers));
+	if (USB_LIST_EMPTY(&ctx->flying_transfers))
 		goto out;
 
 	ret = clock_gettime(CLOCK_MONOTONIC, &sys_ts);
@@ -94,7 +94,7 @@
 			goto out;
 
 		xfer->flags |= USB_TIMED_OUT;
-		uxfer = (libusb_transfer *) (((uint8_t *)xfer) +
+		uxfer = (libusb_transfer *) ((uint8_t *)xfer +
 		    sizeof(struct usb_transfer));
 		ret = libusb_cancel_transfer(uxfer);
 	}
@@ -106,13 +106,19 @@
 static int
 handle_events(struct libusb_context *ctx, struct timeval *tv)
 {
+	struct libusb_pollfd *tmppollfd;
+	struct libusb_device_handle *devh;
 	struct usb_pollfd *ipollfd;
-	struct libusb_pollfd *tmppollfd;
+	struct usb_transfer *cur;
+	struct usb_transfer *cancel;
+	struct libusb_transfer *xfer;
 	struct pollfd *fds;
+	struct pollfd *tfds;
+	nfds_t nfds;
 	int tmpfd;
+	int tmp;
 	int ret;
 	int timeout;
-	nfds_t nfds;
 	int i;
        
 	nfds = 0;
@@ -163,7 +169,33 @@
 		}
 	}
 
-	ret = /*unknown*/0;
+	pthread_mutex_lock(&ctx->open_devs_lock);
+	for (i = 0 ; i < nfds && ret > 0 ; i++) {
+		tfds = &fds[i];
+
+		if (!tfds->revents)
+			continue;
+
+		ret--;
+		LIST_FOREACH_ENTRY(devh, &ctx->open_devs, list) {
+			if (libusb20_dev_get_fd(devh->os_priv) == tfds->fd)
+				break ;
+		}
+
+		if (tfds->revents & POLLERR) {
+			usb_remove_pollfd(ctx, libusb20_dev_get_fd(devh->os_priv));
+			usb_handle_disconnect(devh);
+			continue ;
+		}
+		ret = libusb20_dev_process(devh->os_priv);
+		if (ret == 0 || LIBUSB20_ERROR_NO_DEVICE)
+		       	continue;
+		else if (ret < 0)
+			goto out;
+	}
+out:
+	pthread_mutex_unlock(&ctx->open_devs_lock);
+
 handled:
 	free(fds);
 	return ret;



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