From owner-svn-src-head@FreeBSD.ORG Fri Jul 10 14:15:53 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D6ADE1065672; Fri, 10 Jul 2009 14:15:53 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A950D8FC19; Fri, 10 Jul 2009 14:15:53 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n6AEFrBg022383; Fri, 10 Jul 2009 14:15:53 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n6AEFrb8022379; Fri, 10 Jul 2009 14:15:53 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200907101415.n6AEFrb8022379@svn.freebsd.org> From: Andrew Thompson Date: Fri, 10 Jul 2009 14:15:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r195560 - head/lib/libusb X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Jul 2009 14:15:54 -0000 Author: thompsa Date: Fri Jul 10 14:15:53 2009 New Revision: 195560 URL: http://svn.freebsd.org/changeset/base/195560 Log: Sync the libusb 1.0 exported api to the latest GSoC code. - Fix possible uninitialised variables and null derefs - Support big transfers - Various bug fixes and style changes Submitted by: Sylvestre Gallon Sponsored by: Google Summer of Code 2009 Approved by: re (kib) Modified: head/lib/libusb/libusb.h head/lib/libusb/libusb10.c head/lib/libusb/libusb10.h head/lib/libusb/libusb10_desc.c head/lib/libusb/libusb10_io.c Modified: head/lib/libusb/libusb.h ============================================================================== --- head/lib/libusb/libusb.h Fri Jul 10 13:33:22 2009 (r195559) +++ head/lib/libusb/libusb.h Fri Jul 10 14:15:53 2009 (r195560) @@ -27,14 +27,16 @@ #ifndef __LIBUSB_H__ #define __LIBUSB_H__ +#include +#include +#include +#include + #include #include #include #include -#include -#include -#include #ifdef __cplusplus extern "C" { @@ -44,10 +46,6 @@ extern "C" { #endif -struct list_head { - struct list_head *prev, *next; -}; - /* libusb enums */ enum libusb_class_code { @@ -183,6 +181,33 @@ enum libusb_debug_level { LIBUSB_DEBUG_TRANSFER=2, }; +/* internal structures */ + +typedef struct libusb_pollfd { + int fd; + short events; +} libusb_pollfd; + +struct usb_pollfd { + TAILQ_ENTRY(usb_pollfd) list; + struct libusb_pollfd pollfd; +}; + +struct usb_transfer { + TAILQ_ENTRY(usb_transfer) list; + int num_iso_packets; + struct timeval timeout; + int transferred; + uint8_t flags; +}; + +struct usb_ep_tr { + TAILQ_ENTRY(usb_ep_tr) list; + uint8_t addr; + uint8_t idx; + uint8_t flags; + void *os_priv; +}; /* libusb structures */ typedef void (*libusb_pollfd_added_cb) (int fd, short events, void *user_data); @@ -194,16 +219,16 @@ typedef struct libusb_context { int ctrl_pipe[2]; - struct list_head usb_devs; + TAILQ_HEAD(usb_devs_list, libusb_device) usb_devs; pthread_mutex_t usb_devs_lock; - struct list_head open_devs; + TAILQ_HEAD(open_devs_list, libusb_device_handle) open_devs; pthread_mutex_t open_devs_lock; - struct list_head flying_transfers; + TAILQ_HEAD(flying_transfers_list, usb_transfer) flying_transfers; pthread_mutex_t flying_transfers_lock; - struct list_head pollfds; + TAILQ_HEAD(pollfds_list, usb_pollfd) pollfds; pthread_mutex_t pollfds_lock; unsigned int pollfd_modify; @@ -230,7 +255,7 @@ typedef struct libusb_device { uint8_t device_address; uint8_t num_configurations; - struct list_head list; + TAILQ_ENTRY(libusb_device) list; unsigned long session_data; void *os_priv; } libusb_device; @@ -239,9 +264,10 @@ typedef struct libusb_device_handle { pthread_mutex_t lock; unsigned long claimed_interfaces; - struct list_head list; + TAILQ_ENTRY(libusb_device_handle) list; struct libusb_device *dev; void *os_priv; + TAILQ_HEAD(ep_list, usb_ep_tr) ep_list; } libusb_device_handle; typedef struct libusb_device_descriptor { @@ -343,11 +369,6 @@ typedef struct libusb_transfer { struct libusb_iso_packet_descriptor iso_packet_desc[0]; } libusb_transfer __aligned(sizeof(void *)); -typedef struct libusb_pollfd { - int fd; - short events; -} libusb_pollfd; - /* Library initialisation */ void libusb_set_debug(libusb_context * ctx, int level); @@ -360,6 +381,7 @@ ssize_t libusb_get_device_list(libusb_co void libusb_free_device_list(libusb_device ** list, int unref_devices); uint8_t libusb_get_bus_number(libusb_device * dev); uint8_t libusb_get_device_address(libusb_device * dev); +int libusb_clear_halt(libusb_device_handle *devh, unsigned char endpoint); int libusb_get_max_packet_size(libusb_device * dev, unsigned char endpoint); libusb_device *libusb_ref_device(libusb_device * dev); void libusb_unref_device(libusb_device * dev); Modified: head/lib/libusb/libusb10.c ============================================================================== --- head/lib/libusb/libusb10.c Fri Jul 10 13:33:22 2009 (r195559) +++ head/lib/libusb/libusb10.c Fri Jul 10 14:15:53 2009 (r195560) @@ -75,8 +75,8 @@ libusb_init(libusb_context ** context) pthread_mutex_init(&ctx->usb_devs_lock, NULL); pthread_mutex_init(&ctx->open_devs_lock, NULL); - USB_LIST_INIT(&ctx->usb_devs); - USB_LIST_INIT(&ctx->open_devs); + TAILQ_INIT(&ctx->usb_devs); + TAILQ_INIT(&ctx->open_devs); pthread_mutex_init(&ctx->flying_transfers_lock, NULL); pthread_mutex_init(&ctx->pollfds_lock, NULL); @@ -85,8 +85,8 @@ libusb_init(libusb_context ** context) pthread_mutex_init(&ctx->event_waiters_lock, NULL); pthread_cond_init(&ctx->event_waiters_cond, NULL); - USB_LIST_INIT(&ctx->flying_transfers); - USB_LIST_INIT(&ctx->pollfds); + TAILQ_INIT(&ctx->flying_transfers); + TAILQ_INIT(&ctx->pollfds); ret = pipe(ctx->ctrl_pipe); if (ret < 0) { @@ -123,7 +123,7 @@ libusb_exit(libusb_context * ctx) { GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit enter"); usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); close(ctx->ctrl_pipe[0]); close(ctx->ctrl_pipe[1]); @@ -135,7 +135,7 @@ libusb_exit(libusb_context * ctx) pthread_mutex_unlock(&default_context_lock); free(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit leave"); } /* Device handling and initialisation. */ @@ -150,7 +150,7 @@ libusb_get_device_list(libusb_context * int i; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list enter"); usb_backend = libusb20_be_alloc_default(); if (usb_backend == NULL) @@ -178,6 +178,10 @@ libusb_get_device_list(libusb_context * ddesc = libusb20_dev_get_device_desc(pdev); dev = malloc(sizeof(*dev)); if (dev == NULL) { + while (i != 0) { + libusb_unref_device((*list)[i - 1]); + i--; + } free(*list); libusb20_be_free(usb_backend); return (LIBUSB_ERROR_NO_MEM); @@ -194,7 +198,7 @@ libusb_get_device_list(libusb_context * dev->os_priv = pdev; pthread_mutex_lock(&ctx->usb_devs_lock); - LIST_ADD(&dev->list, &ctx->usb_devs); + TAILQ_INSERT_HEAD(&ctx->usb_devs, dev, list); pthread_mutex_unlock(&ctx->usb_devs_lock); (*list)[i] = libusb_ref_device(dev); @@ -203,7 +207,7 @@ libusb_get_device_list(libusb_context * (*list)[i] = NULL; libusb20_be_free(usb_backend); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list leave"); return (i); } @@ -219,7 +223,7 @@ libusb_free_device_list(libusb_device ** ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list enter"); if (list == NULL) return ; @@ -229,7 +233,7 @@ libusb_free_device_list(libusb_device ** libusb_unref_device(list[i]); } free(list); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list leave"); } uint8_t @@ -239,11 +243,11 @@ libusb_get_bus_number(libusb_device * de ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number enter"); if (dev == NULL) return (LIBUSB_ERROR_NO_DEVICE); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number leave"); return (dev->bus_number); } @@ -254,11 +258,11 @@ libusb_get_device_address(libusb_device ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address enter"); if (dev == NULL) return (LIBUSB_ERROR_NO_DEVICE); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address leave"); return (dev->device_address); } @@ -274,7 +278,7 @@ libusb_get_max_packet_size(libusb_device ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size enter"); if (dev == NULL) return (LIBUSB_ERROR_NO_DEVICE); @@ -299,7 +303,7 @@ libusb_get_max_packet_size(libusb_device out: libusb_free_config_descriptor(pdconf); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size leave"); return (ret); } @@ -310,7 +314,7 @@ libusb_ref_device(libusb_device * dev) ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device enter"); if (dev == NULL) return (NULL); @@ -319,7 +323,7 @@ libusb_ref_device(libusb_device * dev) dev->refcnt++; pthread_mutex_unlock(&dev->lock); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device leave"); return (dev); } @@ -330,7 +334,7 @@ libusb_unref_device(libusb_device * dev) ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device enter"); if (dev == NULL) return; @@ -341,13 +345,13 @@ libusb_unref_device(libusb_device * dev) if (dev->refcnt == 0) { pthread_mutex_lock(&dev->ctx->usb_devs_lock); - LIST_DEL(&dev->list); + TAILQ_REMOVE(&ctx->usb_devs, dev, list); pthread_mutex_unlock(&dev->ctx->usb_devs_lock); libusb20_dev_free(dev->os_priv); free(dev); } - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device leave"); } int @@ -360,7 +364,7 @@ libusb_open(libusb_device * dev, libusb_ int err; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open enter"); dummy = 1; if (devh == NULL) @@ -378,6 +382,7 @@ libusb_open(libusb_device * dev, libusb_ memset(hdl, 0, sizeof(*hdl)); pthread_mutex_init(&hdl->lock, NULL); + TAILQ_INIT(&hdl->ep_list); hdl->dev = libusb_ref_device(dev); hdl->claimed_interfaces = 0; hdl->os_priv = dev->os_priv; @@ -390,7 +395,7 @@ libusb_open(libusb_device * dev, libusb_ } pthread_mutex_lock(&ctx->open_devs_lock); - LIST_ADD(&hdl->list, &ctx->open_devs); + TAILQ_INSERT_HEAD(&ctx->open_devs, hdl, list); pthread_mutex_unlock(&ctx->open_devs_lock); *devh = hdl; @@ -414,7 +419,7 @@ libusb_open(libusb_device * dev, libusb_ pthread_mutex_unlock(&ctx->pollfd_modify_lock); libusb_unlock_events(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open leave"); return (0); } @@ -429,7 +434,7 @@ libusb_open_device_with_vid_pid(libusb_c int i, j; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter"); devh = NULL; @@ -440,13 +445,15 @@ libusb_open_device_with_vid_pid(libusb_c pdev = (struct libusb20_device *)devs[j]->os_priv; pdesc = libusb20_dev_get_device_desc(pdev); if (pdesc->idVendor == vendor_id && - pdesc->idProduct == product_id) + pdesc->idProduct == product_id) { if (libusb_open(devs[j], &devh) < 0) devh = NULL; + break ; + } } libusb_free_device_list(devs, 1); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave"); return (devh); } @@ -455,6 +462,7 @@ libusb_close(libusb_device_handle * devh { libusb_context *ctx; struct libusb20_device *pdev; + struct usb_ep_tr *eptr; unsigned char dummy = 1; int err; @@ -465,7 +473,7 @@ libusb_close(libusb_device_handle * devh pdev = devh->os_priv; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close enter"); pthread_mutex_lock(&ctx->pollfd_modify_lock); ctx->pollfd_modify++; @@ -475,12 +483,21 @@ libusb_close(libusb_device_handle * devh if (err <= 0) { pthread_mutex_lock(&ctx->open_devs_lock); - LIST_DEL(&devh->list); + TAILQ_REMOVE(&ctx->open_devs, devh, list); pthread_mutex_unlock(&ctx->open_devs_lock); usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev)); - libusb_unref_device(devh->dev); libusb20_dev_close(pdev); + libusb_unref_device(devh->dev); + TAILQ_FOREACH(eptr, &devh->ep_list, list) { + TAILQ_REMOVE(&devh->ep_list, eptr, list); + libusb20_tr_close(((struct libusb20_transfer **) + eptr->os_priv)[0]); + if (eptr->flags) + libusb20_tr_close(((struct libusb20_transfer **) + eptr->os_priv)[1]); + free((struct libusb20_transfer **)eptr->os_priv); + } free(devh); pthread_mutex_lock(&ctx->pollfd_modify_lock); @@ -492,12 +509,21 @@ libusb_close(libusb_device_handle * devh read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy)); pthread_mutex_lock(&ctx->open_devs_lock); - LIST_DEL(&devh->list); + TAILQ_REMOVE(&ctx->open_devs, devh, list); pthread_mutex_unlock(&ctx->open_devs_lock); usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev)); - libusb_unref_device(devh->dev); libusb20_dev_close(pdev); + libusb_unref_device(devh->dev); + TAILQ_FOREACH(eptr, &devh->ep_list, list) { + TAILQ_REMOVE(&devh->ep_list, eptr, list); + libusb20_tr_close(((struct libusb20_transfer **) + eptr->os_priv)[0]); + if (eptr->flags) + libusb20_tr_close(((struct libusb20_transfer **) + eptr->os_priv)[1]); + free((struct libusb20_transfer **)eptr->os_priv); + } free(devh); pthread_mutex_lock(&ctx->pollfd_modify_lock); @@ -505,7 +531,7 @@ libusb_close(libusb_device_handle * devh pthread_mutex_unlock(&ctx->pollfd_modify_lock); libusb_unlock_events(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close leave"); } libusb_device * @@ -515,12 +541,12 @@ libusb_get_device(libusb_device_handle * ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device enter"); if (devh == NULL) return (NULL); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device leave"); return (devh->dev); } @@ -531,7 +557,7 @@ libusb_get_configuration(libusb_device_h ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration enter"); if (devh == NULL || config == NULL) return (LIBUSB_ERROR_INVALID_PARAM); @@ -539,14 +565,10 @@ libusb_get_configuration(libusb_device_h *config = libusb20_dev_get_config_index((struct libusb20_device *) devh->dev->os_priv); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration leave"); return (0); } -/* - * XXX this code is wrong. need update. - */ - int libusb_set_configuration(libusb_device_handle * devh, int configuration) { @@ -555,16 +577,15 @@ libusb_set_configuration(libusb_device_h ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration enter"); if (devh == NULL) return (LIBUSB_ERROR_INVALID_PARAM); pdev = (struct libusb20_device *)devh->dev->os_priv; - libusb20_dev_set_alt_index(pdev, libusb20_dev_get_config_index(pdev), - configuration); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration leave"); + libusb20_dev_set_config_index(pdev, configuration); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration leave"); return (0); } @@ -576,7 +597,7 @@ libusb_claim_interface(libusb_device_han ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface enter"); if (dev == NULL) return (LIBUSB_ERROR_INVALID_PARAM); @@ -592,7 +613,7 @@ libusb_claim_interface(libusb_device_han dev->claimed_interfaces |= (1 << interface_number); pthread_mutex_unlock(&(dev->lock)); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface leave"); return (ret); } @@ -604,7 +625,7 @@ libusb_release_interface(libusb_device_h ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface enter"); ret = 0; if (dev == NULL) @@ -621,7 +642,7 @@ libusb_release_interface(libusb_device_h dev->claimed_interfaces &= ~(1 << interface_number); pthread_mutex_unlock(&(dev->lock)); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface leave"); return (ret); } @@ -630,11 +651,10 @@ libusb_set_interface_alt_setting(libusb_ int interface_number, int alternate_setting) { libusb_context *ctx; - int ret; ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting enter"); if (dev == NULL) return (LIBUSB_ERROR_INVALID_PARAM); @@ -653,7 +673,7 @@ libusb_set_interface_alt_setting(libusb_ alternate_setting) != 0) return (LIBUSB_ERROR_OTHER); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting leave"); return (0); } @@ -661,14 +681,19 @@ int libusb_clear_halt(libusb_device_handle * devh, unsigned char endpoint) { struct libusb20_transfer *xfer; + struct libusb20_device *pdev; libusb_context *ctx; int ret; ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt enter"); - - GET_XFER(xfer, endpoint, devh->os_priv); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt enter"); + + pdev = devh->os_priv; + xfer = libusb20_tr_get_pointer(pdev, + ((endpoint / 0x40) | (endpoint * 4)) % (16 * 4)); + if (xfer == NULL) + return (LIBUSB_ERROR_NO_MEM); pthread_mutex_lock(&libusb20_lock); ret = libusb20_tr_open(xfer, 0, 0, endpoint); @@ -682,7 +707,7 @@ libusb_clear_halt(libusb_device_handle * libusb20_tr_close(xfer); pthread_mutex_unlock(&libusb20_lock); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt leave"); return (0); } @@ -693,13 +718,13 @@ libusb_reset_device(libusb_device_handle ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device enter"); if (dev == NULL) return (LIBUSB20_ERROR_INVALID_PARAM); libusb20_dev_reset(dev->os_priv); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device leave"); return (0); } @@ -710,12 +735,12 @@ libusb_kernel_driver_active(libusb_devic ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active enter"); if (devh == NULL) return (LIBUSB_ERROR_INVALID_PARAM); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active leave"); return (libusb20_dev_kernel_driver_active(devh->os_priv, interface)); } @@ -727,7 +752,7 @@ libusb_detach_kernel_driver(libusb_devic ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver enter"); if (devh == NULL) return (LIBUSB_ERROR_INVALID_PARAM); @@ -736,7 +761,7 @@ libusb_detach_kernel_driver(libusb_devic if (libusb20_dev_detach_kernel_driver(pdev, interface) == LIBUSB20_ERROR_OTHER) return (LIBUSB_ERROR_OTHER); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver leave"); return (0); } @@ -751,12 +776,12 @@ libusb_attach_kernel_driver(libusb_devic ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver enter"); if (devh == NULL) return (LIBUSB_ERROR_INVALID_PARAM); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver leave"); return (0); } @@ -772,7 +797,7 @@ libusb_alloc_transfer(int iso_packets) ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer enter"); len = sizeof(struct libusb_transfer) + sizeof(struct usb_transfer) + @@ -788,7 +813,7 @@ libusb_alloc_transfer(int iso_packets) xfer = (struct libusb_transfer *) ((uint8_t *)bxfer + sizeof(struct usb_transfer)); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer leave"); return (xfer); } @@ -800,7 +825,7 @@ libusb_free_transfer(struct libusb_trans ctx = NULL; GET_CONTEXT(ctx); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer enter"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer enter"); if (xfer == NULL) return ; @@ -809,10 +834,85 @@ libusb_free_transfer(struct libusb_trans sizeof(struct usb_transfer)); free(bxfer); - dprintf(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer leave"); + DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer leave"); return; } +static int +libusb_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer) +{ + int ret; + int usb_speed; + + usb_speed = libusb20_dev_get_speed(pdev); + + switch (xfer->type) { + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + switch (usb_speed) { + case LIBUSB20_SPEED_LOW: + case LIBUSB20_SPEED_FULL: + ret = 60 * 1; + break ; + default : + ret = 60 * 8; + break ; + } + break ; + case LIBUSB_TRANSFER_TYPE_CONTROL: + ret = 2; + break ; + default: + ret = 1; + break ; + } + + return ret; +} + +static int +libusb_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer) +{ + int ret; + int usb_speed; + + usb_speed = libusb20_dev_get_speed(pdev); + + switch (xfer->type) { + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + ret = 0; + break ; + case LIBUSB_TRANSFER_TYPE_CONTROL: + switch (usb_speed) { + case LIBUSB20_SPEED_LOW: + ret = 8; + break ; + case LIBUSB20_SPEED_FULL: + ret = 64; + break ; + default: + ret = 64; + break ; + } + ret += 8; + break ; + default : + switch (usb_speed) { + case LIBUSB20_SPEED_LOW: + ret = 256; + break ; + case LIBUSB20_SPEED_FULL: + ret = 4096; + break ; + default: + ret = 16384; + break ; + } + break ; + } + + return ret; +} + static void libusb10_proxy(struct libusb20_transfer *xfer) { @@ -820,6 +920,9 @@ libusb10_proxy(struct libusb20_transfer struct libusb20_device *pdev; libusb_transfer *usb_xfer; libusb_context *ctx; + uint32_t pos; + uint32_t max; + uint32_t size; uint8_t status; uint32_t iso_packets; int i; @@ -834,172 +937,97 @@ libusb10_proxy(struct libusb20_transfer switch (status) { case LIBUSB20_TRANSFER_COMPLETED: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMIT"); - usb_xfer->actual_length += libusb20_tr_get_actual_length(xfer); - usb_xfer->callback(usb_xfer); - - pthread_mutex_lock(&ctx->flying_transfers_lock); - LIST_DEL(&usb_backend->list); - pthread_mutex_unlock(&ctx->flying_transfers_lock); + usb_backend->transferred += libusb20_tr_get_actual_length(xfer); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER %i bytes", + usb_backend->transferred); + if (usb_backend->transferred != usb_xfer->length) + goto tr_start; + + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER COMPLETE"); + usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_COMPLETED); + break ; case LIBUSB20_TRANSFER_START: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 START"); +tr_start: + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 START"); + max = libusb_get_buffsize(pdev, usb_xfer); + pos = usb_backend->transferred; + size = (usb_xfer->length - pos); + size = (size > max) ? max : size; usb_xfer->actual_length = 0; switch (usb_xfer->type) { case LIBUSB_TRANSFER_TYPE_CONTROL: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE CTR"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE CTR"); libusb20_tr_setup_control(xfer, usb_xfer->buffer, - (void *)(((uint8_t *) usb_xfer->buffer) + + (void *)(((uint8_t *) &usb_xfer->buffer[pos]) + sizeof(libusb_control_setup)), usb_xfer->timeout); break ; case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE ISO"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE ISO"); iso_packets = libusb20_tr_get_max_frames(xfer); if (usb_xfer->num_iso_packets > iso_packets) usb_xfer->num_iso_packets = iso_packets; for (i = 0 ; i < usb_xfer->num_iso_packets ; i++) { libusb20_tr_setup_isoc(xfer, - usb_xfer->buffer, usb_xfer->length, i); + &usb_xfer->buffer[pos], size, i); } libusb20_tr_set_total_frames(xfer, i); break ; case LIBUSB_TRANSFER_TYPE_BULK: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE BULK"); - libusb20_tr_setup_bulk(xfer, usb_xfer->buffer, - usb_xfer->length, usb_xfer->timeout); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE BULK"); + libusb20_tr_setup_bulk(xfer, &usb_xfer->buffer[pos], + size, usb_xfer->timeout); break ; case LIBUSB_TRANSFER_TYPE_INTERRUPT: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE INTR"); - libusb20_tr_setup_intr(xfer, usb_xfer->buffer, - usb_xfer->length, usb_xfer->timeout); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE INTR"); + libusb20_tr_setup_intr(xfer, &usb_xfer->buffer[pos], + size, usb_xfer->timeout); break ; } libusb20_tr_submit(xfer); - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMITED"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMITED"); break ; default: - if (ctx->debug == LIBUSB_DEBUG_TRANSFER) - printf("LIBUSB TRANSFER DEFAULT 0x%x\n", status); - usb_xfer->actual_length = 0; - usb_xfer->status = LIBUSB_TRANSFER_CANCELLED; - - pthread_mutex_lock(&ctx->flying_transfers_lock); - LIST_DEL(&usb_backend->list); - pthread_mutex_unlock(&ctx->flying_transfers_lock); - usb_xfer->callback(usb_xfer); - + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TRANSFER DEFAULT 0x%x\n", + status); + usb_backend->transferred = 0; + usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_CANCELLED); break ; } switch (status) { case LIBUSB20_TRANSFER_COMPLETED: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS COMPLETED"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS COMPLETED"); usb_xfer->status = LIBUSB_TRANSFER_COMPLETED; break ; case LIBUSB20_TRANSFER_OVERFLOW: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR OVERFLOW"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR OVERFLOW"); usb_xfer->status = LIBUSB_TRANSFER_OVERFLOW; break ; case LIBUSB20_TRANSFER_NO_DEVICE: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR NO DEVICE"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR NO DEVICE"); usb_xfer->status = LIBUSB_TRANSFER_NO_DEVICE; break ; case LIBUSB20_TRANSFER_STALL: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR STALL"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR STALL"); usb_xfer->status = LIBUSB_TRANSFER_STALL; break ; case LIBUSB20_TRANSFER_CANCELLED: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR CANCELLED"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR CANCELLED"); usb_xfer->status = LIBUSB_TRANSFER_CANCELLED; break ; case LIBUSB20_TRANSFER_TIMED_OUT: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR TIMEOUT"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR TIMEOUT"); usb_xfer->status = LIBUSB_TRANSFER_TIMED_OUT; break ; case LIBUSB20_TRANSFER_ERROR: - dprintf(ctx, LIBUSB_DEBUG_TRANSFER, "ERROR"); + DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "ERROR"); usb_xfer->status = LIBUSB_TRANSFER_ERROR; break ; } } -static int -libusb_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer) -{ - int ret; - int usb_speed; - - usb_speed = libusb20_dev_get_speed(pdev); - - switch (xfer->type) { - case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: - switch (usb_speed) { - case LIBUSB20_SPEED_LOW: - case LIBUSB20_SPEED_FULL: - ret = 60 * 1; - break ; - default : - ret = 60 * 8; - break ; - } - break ; - case LIBUSB_TRANSFER_TYPE_CONTROL: - ret = 2; - break ; - default: - ret = 1; - break ; - } - - return ret; -} - -static int -libusb_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer) -{ - int ret; - int usb_speed; - - usb_speed = libusb20_dev_get_speed(pdev); - - switch (xfer->type) { - case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: - ret = 0; - break ; - case LIBUSB_TRANSFER_TYPE_CONTROL: - switch (usb_speed) { - case LIBUSB20_SPEED_LOW: - ret = 8; - break ; - case LIBUSB20_SPEED_FULL: - ret = 64; - break ; - case LIBUSB20_SPEED_HIGH: - ret = 64; - break ; - } - /*add */ - ret += 8; - break ; - default : - switch (usb_speed) { - case LIBUSB20_SPEED_LOW: - ret = 256; - break ; - case LIBUSB20_SPEED_FULL: - ret = 4096; - break ; - default: - ret = 16384; - break ; - } - break ; - } - - return ret; -} - int libusb_submit_transfer(struct libusb_transfer *xfer) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***