LibUSB v1.0:

- Significantly improve libusb10 support.
        - Many minor issues fixed.
        - P4 ID: 166189, 165853, 165991, 166052, 166069

Submitted by:	hps
Approved by:	re
This commit is contained in:
Alfred Perlstein 2009-07-30 00:11:41 +00:00
parent ed190ad06a
commit 390065b18e
9 changed files with 1438 additions and 1613 deletions

View File

@ -294,7 +294,7 @@ LIBUSB_ERROR code on failure.
.
.Pp
.Ft void
.Fn libusb_free_config_descriptor "libusb_config_descriptor *config`"
.Fn libusb_free_config_descriptor "libusb_config_descriptor *config"
Free a configuration descriptor.
.
.Pp

View File

@ -30,7 +30,6 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/endian.h>
#include <sys/queue.h>
#include <stdint.h>
#include <time.h>
@ -181,95 +180,25 @@ 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 */
struct libusb_context;
struct libusb_device;
struct libusb_transfer;
struct libusb20_device;
struct libusb_pollfd {
int fd;
short events;
};
typedef struct libusb_context libusb_context;
typedef struct libusb_device libusb_device;
typedef struct libusb20_device libusb_device_handle;
typedef struct libusb_pollfd libusb_pollfd;
typedef void (*libusb_pollfd_added_cb) (int fd, short events, void *user_data);
typedef void (*libusb_pollfd_removed_cb) (int fd, void *user_data);
typedef struct libusb_context {
int debug;
int debug_fixed;
int ctrl_pipe[2];
TAILQ_HEAD(usb_devs_list, libusb_device) usb_devs;
pthread_mutex_t usb_devs_lock;
TAILQ_HEAD(open_devs_list, libusb_device_handle) open_devs;
pthread_mutex_t open_devs_lock;
TAILQ_HEAD(flying_transfers_list, usb_transfer) flying_transfers;
pthread_mutex_t flying_transfers_lock;
TAILQ_HEAD(pollfds_list, usb_pollfd) pollfds;
pthread_mutex_t pollfds_lock;
unsigned int pollfd_modify;
pthread_mutex_t pollfd_modify_lock;
libusb_pollfd_added_cb fd_added_cb;
libusb_pollfd_removed_cb fd_removed_cb;
void *fd_cb_user_data;
pthread_mutex_t events_lock;
int event_handler_active;
pthread_mutex_t event_waiters_lock;
pthread_cond_t event_waiters_cond;
} libusb_context;
typedef struct libusb_device {
pthread_mutex_t lock;
int refcnt;
struct libusb_context *ctx;
uint8_t bus_number;
uint8_t device_address;
uint8_t num_configurations;
TAILQ_ENTRY(libusb_device) list;
unsigned long session_data;
void *os_priv;
} libusb_device;
typedef struct libusb_device_handle {
pthread_mutex_t lock;
unsigned long claimed_interfaces;
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 {
uint8_t bLength;
uint8_t bDescriptorType;
@ -296,7 +225,7 @@ typedef struct libusb_endpoint_descriptor {
uint8_t bInterval;
uint8_t bRefresh;
uint8_t bSynchAddress;
unsigned char *extra;
uint8_t *extra;
int extra_length;
} libusb_endpoint_descriptor __aligned(sizeof(void *));
@ -311,7 +240,7 @@ typedef struct libusb_interface_descriptor {
uint8_t bInterfaceProtocol;
uint8_t iInterface;
struct libusb_endpoint_descriptor *endpoint;
unsigned char *extra;
uint8_t *extra;
int extra_length;
} libusb_interface_descriptor __aligned(sizeof(void *));
@ -330,7 +259,7 @@ typedef struct libusb_config_descriptor {
uint8_t bmAttributes;
uint8_t MaxPower;
struct libusb_interface *interface;
unsigned char *extra;
uint8_t *extra;
int extra_length;
} libusb_config_descriptor __aligned(sizeof(void *));
@ -348,22 +277,20 @@ typedef struct libusb_iso_packet_descriptor {
enum libusb_transfer_status status;
} libusb_iso_packet_descriptor __aligned(sizeof(void *));
struct libusb_transfer;
typedef void (*libusb_transfer_cb_fn) (struct libusb_transfer *transfer);
typedef struct libusb_transfer {
libusb_device_handle *dev_handle;
uint8_t flags;
unsigned int endpoint;
unsigned char type;
uint8_t type;
unsigned int timeout;
enum libusb_transfer_status status;
int length;
int actual_length;
libusb_transfer_cb_fn callback;
void *user_data;
unsigned char *buffer;
uint8_t *buffer;
void *os_priv;
int num_iso_packets;
struct libusb_iso_packet_descriptor iso_packet_desc[0];
@ -381,8 +308,8 @@ ssize_t libusb_get_device_list(libusb_context * ctx, libusb_device *** list);
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);
int libusb_clear_halt(libusb_device_handle *devh, uint8_t endpoint);
int libusb_get_max_packet_size(libusb_device * dev, uint8_t endpoint);
libusb_device *libusb_ref_device(libusb_device * dev);
void libusb_unref_device(libusb_device * dev);
int libusb_open(libusb_device * dev, libusb_device_handle ** devh);
@ -393,6 +320,7 @@ int libusb_get_configuration(libusb_device_handle * devh, int *config);
int libusb_set_configuration(libusb_device_handle * devh, int configuration);
int libusb_claim_interface(libusb_device_handle * devh, int interface_number);
int libusb_release_interface(libusb_device_handle * devh, int interface_number);
int libusb_reset_device(libusb_device_handle * dev);
int libusb_kernel_driver_active(libusb_device_handle * devh, int interface);
int libusb_detach_kernel_driver(libusb_device_handle * devh, int interface);
int libusb_attach_kernel_driver(libusb_device_handle * devh, int interface);
@ -405,15 +333,15 @@ int libusb_get_active_config_descriptor(libusb_device * dev, struct libusb_confi
int libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index, struct libusb_config_descriptor **config);
int libusb_get_config_descriptor_by_value(libusb_device * dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config);
void libusb_free_config_descriptor(struct libusb_config_descriptor *config);
int libusb_get_string_descriptor_ascii(libusb_device_handle * dev, uint8_t desc_index, unsigned char *data, int length);
int libusb_get_string_descriptor_ascii(libusb_device_handle * dev, uint8_t desc_index, uint8_t *data, int length);
/* Asynchronous device I/O*/
/* Asynchronous device I/O */
struct libusb_transfer *libusb_alloc_transfer(int iso_packets);
void libusb_free_transfer(struct libusb_transfer *transfer);
int libusb_submit_transfer(struct libusb_transfer *transfer);
int libusb_cancel_transfer(struct libusb_transfer *transfer);
unsigned char *libusb_get_iso_packet_buffer_simple(struct libusb_transfer *transfer, unsigned int packet);
uint8_t *libusb_get_iso_packet_buffer_simple(struct libusb_transfer *transfer, unsigned int packet);
/* Polling and timing */
@ -434,9 +362,9 @@ struct libusb_pollfd **libusb_get_pollfds(libusb_context * ctx);
/* Synchronous device I/O */
int 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);
int libusb_bulk_transfer(struct libusb_device_handle *devh, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout);
int libusb_interrupt_transfer(struct libusb_device_handle *devh, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout);
int libusb_control_transfer(libusb_device_handle * devh, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t wLength, unsigned int timeout);
int libusb_bulk_transfer(libusb_device_handle *devh, uint8_t endpoint, uint8_t *data, int length, int *transferred, unsigned int timeout);
int libusb_interrupt_transfer(libusb_device_handle *devh, uint8_t endpoint, uint8_t *data, int length, int *transferred, unsigned int timeout);
#if 0
{ /* indent fix */

File diff suppressed because it is too large Load Diff

View File

@ -25,46 +25,89 @@
*/
#ifndef __LIBUSB10_H__
#define __LIBUSB10_H__
#define __LIBUSB10_H__
/*
* The two following macros were taken from the original LibUSB v1.0
* for sake of compatibility:
*/
#include <sys/queue.h>
static int get_next_timeout(libusb_context *ctx, struct timeval *tv, struct timeval *out);
static int handle_timeouts(struct libusb_context *ctx);
static int handle_events(struct libusb_context *ctx, struct timeval *tv);
extern struct libusb_context *usbi_default_context;
extern pthread_mutex_t libusb20_lock;
#define GET_CONTEXT(ctx) (((ctx) == NULL) ? usbi_default_context : (ctx))
#define UNEXPORTED __attribute__((__visibility__("hidden")))
#define CTX_LOCK(ctx) pthread_mutex_lock(&(ctx)->ctx_lock)
#define CTX_TRYLOCK(ctx) pthread_mutex_trylock(&(ctx)->ctx_lock)
#define CTX_UNLOCK(ctx) pthread_mutex_unlock(&(ctx)->ctx_lock)
/* if ctx is NULL use default context*/
#define GET_CONTEXT(ctx) \
if (ctx == NULL) ctx = usbi_default_context;
#define MAX(a,b) (((a)>(b))?(a):(b))
#define USB_TIMED_OUT (1<<0)
#define UNEXPORTED __attribute__((__visibility__("hidden")))
#define DPRINTF(ctx, dbg, format, args...) \
if (ctx->debug == dbg) { \
printf("LIBUSB_%s : ", (ctx->debug == LIBUSB_DEBUG_FUNCTION) ? "FUNCTION" : "TRANSFER"); \
switch(ctx->debug) { \
case LIBUSB_DEBUG_FUNCTION: \
printf(format, ## args);\
break ; \
case LIBUSB_DEBUG_TRANSFER: \
printf(format, ## args);\
break ; \
#define DPRINTF(ctx, dbg, format, args...) do { \
if ((ctx)->debug == dbg) { \
switch (dbg) { \
case LIBUSB_DEBUG_FUNCTION: \
printf("LIBUSB_FUNCTION: " \
format "\n", ## args); \
break; \
case LIBUSB_DEBUG_TRANSFER: \
printf("LIBUSB_TRANSFER: " \
format "\n", ## args); \
break; \
default: \
break; \
} \
printf("\n"); \
}
} \
} while(0)
UNEXPORTED int usb_add_pollfd(libusb_context *ctx, int fd, short events);
UNEXPORTED void usb_remove_pollfd(libusb_context *ctx, int fd);
UNEXPORTED void usb_handle_transfer_completion(struct usb_transfer *uxfer,
enum libusb_transfer_status status);
UNEXPORTED void usb_handle_disconnect(struct libusb_device_handle *devh);
/* internal structures */
#endif /*__LIBUSB10_H__*/
struct libusb_super_pollfd {
TAILQ_ENTRY(libusb_super_pollfd) entry;
struct libusb20_device *pdev;
struct libusb_pollfd pollfd;
};
struct libusb_super_transfer {
TAILQ_ENTRY(libusb_super_transfer) entry;
uint8_t *curr_data;
uint32_t rem_len;
uint32_t last_len;
uint8_t flags;
};
struct libusb_context {
int debug;
int debug_fixed;
int ctrl_pipe[2];
int tr_done_ref;
int tr_done_gen;
pthread_mutex_t ctx_lock;
pthread_cond_t ctx_cond;
pthread_t ctx_handler;
#define NO_THREAD ((pthread_t)-1)
TAILQ_HEAD(, libusb_super_pollfd) pollfds;
TAILQ_HEAD(, libusb_super_transfer) tr_done;
struct libusb_super_pollfd ctx_poll;
libusb_pollfd_added_cb fd_added_cb;
libusb_pollfd_removed_cb fd_removed_cb;
void *fd_cb_user_data;
};
struct libusb_device {
int refcnt;
uint32_t claimed_interfaces;
struct libusb_super_pollfd dev_poll;
struct libusb_context *ctx;
TAILQ_HEAD(, libusb_super_transfer) tr_head;
struct libusb20_device *os_priv;
};
extern struct libusb_context *usbi_default_context;
void libusb10_add_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd, struct libusb20_device *pdev, int fd, short events);
void libusb10_remove_pollfd(libusb_context *ctx, struct libusb_super_pollfd *pollfd);
void libusb10_cancel_all_transfer(libusb_device *dev);
#endif /* __LIBUSB10_H__ */

View File

@ -24,10 +24,10 @@
* SUCH DAMAGE.
*/
#include <sys/queue.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/queue.h>
#include "libusb20.h"
#include "libusb20_desc.h"
@ -38,16 +38,11 @@
/* USB descriptors */
int
libusb_get_device_descriptor(libusb_device * dev,
libusb_get_device_descriptor(libusb_device *dev,
struct libusb_device_descriptor *desc)
{
struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
struct libusb20_device *pdev;
libusb_context *ctx;
ctx = NULL;
GET_CONTEXT(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_descriptor enter");
if ((dev == NULL) || (desc == NULL))
return (LIBUSB_ERROR_INVALID_PARAM);
@ -70,54 +65,47 @@ libusb_get_device_descriptor(libusb_device * dev,
desc->iSerialNumber = pdesc->iSerialNumber;
desc->bNumConfigurations = pdesc->bNumConfigurations;
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_descriptor leave");
return (0);
}
int
libusb_get_active_config_descriptor(libusb_device * dev,
libusb_get_active_config_descriptor(libusb_device *dev,
struct libusb_config_descriptor **config)
{
struct libusb20_device *pdev;
libusb_context *ctx;
uint8_t idx;
ctx = NULL;
GET_CONTEXT(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_active_config_descriptor enter");
uint8_t config_index;
pdev = dev->os_priv;
idx = libusb20_dev_get_config_index(pdev);
config_index = libusb20_dev_get_config_index(pdev);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_active_config_descriptor leave");
return (libusb_get_config_descriptor(dev, idx, config));
return (libusb_get_config_descriptor(dev, config_index, config));
}
/*
* XXX Need to check if extra need a dup because
* XXX free pconf could free this char *
*/
int
libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index,
libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index,
struct libusb_config_descriptor **config)
{
struct libusb20_device *pdev;
struct libusb20_config *pconf;
struct libusb20_interface *pinf;
struct libusb20_endpoint *pend;
libusb_interface_descriptor *ifd;
libusb_endpoint_descriptor *endd;
libusb_context *ctx;
uint8_t nif, nend, nalt, i, j, k;
uint32_t if_idx, endp_idx;
ctx = NULL;
GET_CONTEXT(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_config_descriptor enter");
struct libusb_config_descriptor *pconfd;
struct libusb_interface_descriptor *ifd;
struct libusb_endpoint_descriptor *endd;
uint8_t *pextra;
uint16_t nextra;
uint8_t nif;
uint8_t nep;
uint8_t nalt;
uint8_t i;
uint8_t j;
uint8_t k;
if (dev == NULL || config == NULL)
return (LIBUSB_ERROR_INVALID_PARAM);
*config = NULL;
pdev = dev->os_priv;
pconf = libusb20_dev_alloc_config(pdev, config_index);
@ -125,75 +113,101 @@ libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index,
return (LIBUSB_ERROR_NOT_FOUND);
nalt = nif = pconf->num_interface;
nend = 0;
for (i = 0 ; i < nif ; i++) {
if (pconf->interface[i].num_altsetting > 0)
{
nalt += pconf->interface[i].num_altsetting;
for (j = 0 ; j < nalt ; j++) {
nend += pconf->interface[i].altsetting[j].num_endpoints;
}
nep = 0;
nextra = pconf->extra.len;
for (i = 0; i < nif; i++) {
pinf = pconf->interface + i;
nextra += pinf->extra.len;
nep += pinf->num_endpoints;
k = pinf->num_endpoints;
pend = pinf->endpoints;
while (k--) {
nextra += pend->extra.len;
pend++;
}
j = pinf->num_altsetting;
nalt += pinf->num_altsetting;
pinf = pinf->altsetting;
while (j--) {
nextra += pinf->extra.len;
nep += pinf->num_endpoints;
k = pinf->num_endpoints;
pend = pinf->endpoints;
while (k--) {
nextra += pend->extra.len;
pend++;
}
pinf++;
}
nend += pconf->interface[i].num_endpoints;
}
*config = malloc(sizeof(libusb_config_descriptor) +
nextra = nextra +
(1 * sizeof(libusb_config_descriptor)) +
(nif * sizeof(libusb_interface)) +
(nalt * sizeof(libusb_interface_descriptor)) +
(nend * sizeof(libusb_endpoint_descriptor)));
if (*config == NULL) {
(nep * sizeof(libusb_endpoint_descriptor));
pconfd = malloc(nextra);
if (pconfd == NULL) {
free(pconf);
return (LIBUSB_ERROR_NO_MEM);
}
/* make sure memory is clean */
memset(pconfd, 0, nextra);
(*config)->interface = (libusb_interface *)(*config +
pconfd->interface = (libusb_interface *) (pconfd +
sizeof(libusb_config_descriptor));
for (i = if_idx = endp_idx = 0 ; i < nif ; if_idx, i++) {
(*config)->interface[i].altsetting = (libusb_interface_descriptor *)
(*config + sizeof(libusb_config_descriptor) +
(nif * sizeof(libusb_interface)) +
(if_idx * sizeof(libusb_interface_descriptor)));
(*config)->interface[i].altsetting[0].endpoint =
(libusb_endpoint_descriptor *) (*config +
sizeof(libusb_config_descriptor) +
(nif * sizeof(libusb_interface)) +
(nalt * sizeof(libusb_interface_descriptor)) +
(endp_idx * sizeof(libusb_endpoint_descriptor)));
endp_idx += pconf->interface[i].num_endpoints;
if (pconf->interface[i].num_altsetting > 0)
{
for (j = 0 ; j < pconf->interface[i].num_altsetting ; j++, if_idx++) {
(*config)->interface[i].altsetting[j + 1].endpoint =
(libusb_endpoint_descriptor *) (*config +
sizeof(libusb_config_descriptor) +
(nif * sizeof(libusb_interface)) +
(nalt * sizeof(libusb_interface_descriptor)) +
(endp_idx * sizeof(libusb_endpoint_descriptor)));
endp_idx += pconf->interface[i].altsetting[j].num_endpoints;
}
ifd = (libusb_interface_descriptor *) (pconfd->interface + nif);
endd = (libusb_endpoint_descriptor *) (ifd + nalt);
pextra = (uint8_t *)(endd + nep);
/* fill in config descriptor */
pconfd->bLength = pconf->desc.bLength;
pconfd->bDescriptorType = pconf->desc.bDescriptorType;
pconfd->wTotalLength = pconf->desc.wTotalLength;
pconfd->bNumInterfaces = pconf->desc.bNumInterfaces;
pconfd->bConfigurationValue = pconf->desc.bConfigurationValue;
pconfd->iConfiguration = pconf->desc.iConfiguration;
pconfd->bmAttributes = pconf->desc.bmAttributes;
pconfd->MaxPower = pconf->desc.bMaxPower;
if (pconf->extra.len != 0) {
pconfd->extra_length = pconf->extra.len;
pconfd->extra = pextra;
memcpy(pextra, pconf->extra.ptr, pconfd->extra_length);
pextra += pconfd->extra_length;
}
/* setup all interface and endpoint pointers */
for (i = 0; i < nif; i++) {
pconfd->interface[i].altsetting = ifd;
ifd->endpoint = endd;
endd += pconf->interface[i].num_endpoints;
ifd++;
for (j = 0; j < pconf->interface[i].num_altsetting; j++) {
ifd->endpoint = endd;
endd += pconf->interface[i].altsetting[j].num_endpoints;
ifd++;
}
}
(*config)->bLength = pconf->desc.bLength;
(*config)->bDescriptorType = pconf->desc.bDescriptorType;
(*config)->wTotalLength = pconf->desc.wTotalLength;
(*config)->bNumInterfaces = pconf->desc.bNumInterfaces;
(*config)->bConfigurationValue = pconf->desc.bConfigurationValue;
(*config)->iConfiguration = pconf->desc.iConfiguration;
(*config)->bmAttributes = pconf->desc.bmAttributes;
(*config)->MaxPower = pconf->desc.bMaxPower;
(*config)->extra_length = pconf->extra.len;
if ((*config)->extra_length != 0)
(*config)->extra = pconf->extra.ptr;
/* fill in all interface and endpoint data */
for (i = 0 ; i < nif ; i++) {
for (i = 0; i < nif; i++) {
pinf = &pconf->interface[i];
(*config)->interface[i].num_altsetting = pinf->num_altsetting + 1;
for (j = 0 ; j < (*config)->interface[i].num_altsetting ; j++) {
pconfd->interface[i].num_altsetting = pinf->num_altsetting + 1;
for (j = 0; j < pconfd->interface[i].num_altsetting; j++) {
if (j != 0)
pinf = &pconf->interface[i].altsetting[j - 1];
ifd = &(*config)->interface[i].altsetting[j];
ifd = &pconfd->interface[i].altsetting[j];
ifd->bLength = pinf->desc.bLength;
ifd->bDescriptorType = pinf->desc.bDescriptorType;
ifd->bInterfaceNumber = pinf->desc.bInterfaceNumber;
@ -203,10 +217,13 @@ libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index,
ifd->bInterfaceSubClass = pinf->desc.bInterfaceSubClass;
ifd->bInterfaceProtocol = pinf->desc.bInterfaceProtocol;
ifd->iInterface = pinf->desc.iInterface;
ifd->extra_length = pinf->extra.len;
if (ifd->extra_length != 0)
ifd->extra = pinf->extra.ptr;
for (k = 0 ; k < pinf->num_endpoints ; k++) {
if (pinf->extra.len != 0) {
ifd->extra_length = pinf->extra.len;
ifd->extra = pextra;
memcpy(pextra, pinf->extra.ptr, pinf->extra.len);
pextra += pinf->extra.len;
}
for (k = 0; k < pinf->num_endpoints; k++) {
pend = &pinf->endpoints[k];
endd = &ifd->endpoint[k];
endd->bLength = pend->desc.bLength;
@ -217,82 +234,71 @@ libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index,
endd->bInterval = pend->desc.bInterval;
endd->bRefresh = pend->desc.bRefresh;
endd->bSynchAddress = pend->desc.bSynchAddress;
endd->extra_length = pend->extra.len;
if (endd->extra_length != 0)
endd->extra = pend->extra.ptr;
if (pend->extra.len != 0) {
endd->extra_length = pend->extra.len;
endd->extra = pextra;
memcpy(pextra, pend->extra.ptr, pend->extra.len);
pextra += pend->extra.len;
}
}
}
}
}
free(pconf);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_config_descriptor leave");
return (0);
*config = pconfd;
return (0); /* success */
}
int
libusb_get_config_descriptor_by_value(libusb_device * dev,
libusb_get_config_descriptor_by_value(libusb_device *dev,
uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
{
struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
struct libusb20_device *pdev;
struct libusb20_config *pconf;
libusb_context *ctx;
int i;
ctx = NULL;
GET_CONTEXT(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_config_descriptor_by_value enter");
int err;
if (dev == NULL || config == NULL)
return (LIBUSB_ERROR_INVALID_PARAM);
pdev = dev->os_priv;
pdesc = libusb20_dev_get_device_desc(pdev);
for (i = 0 ; i < pdesc->bNumConfigurations ; i++) {
pconf = libusb20_dev_alloc_config(pdev, i);
if (pconf->desc.bConfigurationValue == bConfigurationValue) {
free(pconf);
return libusb_get_config_descriptor(dev, i, config);
for (i = 0; i < pdesc->bNumConfigurations; i++) {
err = libusb_get_config_descriptor(dev, i, config);
if (err)
return (err);
}
free(pconf);
if ((*config)->bConfigurationValue == bConfigurationValue)
return (0); /* success */
libusb_free_config_descriptor(*config);
}
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_config_descriptor_by_value leave");
*config = NULL;
return (LIBUSB_ERROR_NOT_FOUND);
}
void
libusb_free_config_descriptor(struct libusb_config_descriptor *config)
{
libusb_context *ctx;
ctx = NULL;
GET_CONTEXT(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_config_descriptor enter");
free(config);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_config_descriptor leave");
}
int
libusb_get_string_descriptor_ascii(libusb_device_handle * dev,
libusb_get_string_descriptor_ascii(libusb_device_handle *pdev,
uint8_t desc_index, unsigned char *data, int length)
{
struct libusb20_device *pdev;
libusb_context *ctx;
ctx = NULL;
GET_CONTEXT(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_string_descriptor_ascii enter");
if (dev == NULL || data == NULL)
if (pdev == NULL || data == NULL || length < 1)
return (LIBUSB20_ERROR_INVALID_PARAM);
pdev = dev->os_priv;
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_string_descriptor_ascii leave");
if (libusb20_dev_req_string_simple_sync(pdev, desc_index,
/* put some default data into the destination buffer */
data[0] = 0;
if (libusb20_dev_req_string_simple_sync(pdev, desc_index,
data, length) == 0)
return (strlen(data));

File diff suppressed because it is too large Load Diff

View File

@ -310,8 +310,13 @@ packets are avoided for proxy buffers.
.Pp
.
.Fn libusb20_tr_get_max_total_length
function will return the maximum value for the length sum of all
USB frames associated with an USB transfer.
function will return the maximum value for the data length sum of all USB
frames associated with an USB transfer.
In case of control transfers the value returned does not include the
length of the SETUP packet, 8 bytes, which is part of frame zero.
The returned value of this function is always aligned to the maximum
packet size, wMaxPacketSize, of the endpoint which the USB transfer is
bound to.
.
.Pp
.

View File

@ -835,7 +835,7 @@ usb_find_devices(void)
/* close all opened devices, if any */
while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) {
udev = pdev->priv01Data;
udev = pdev->privLuData;
libusb20_be_dequeue_device(usb_backend, pdev);
libusb20_dev_free(pdev);
if (udev != NULL) {
@ -893,7 +893,7 @@ usb_find_devices(void)
}
/* link together the two structures */
udev->dev = pdev;
pdev->priv01Data = udev;
pdev->privLuData = udev;
err = libusb20_dev_open(pdev, 0);
if (err == 0) {
@ -914,7 +914,7 @@ usb_device(usb_dev_handle * dev)
pdev = (void *)dev;
return (pdev->priv01Data);
return (pdev->privLuData);
}
struct usb_bus *

View File

@ -191,8 +191,8 @@ struct libusb20_device {
/* private backend data */
void *privBeData;
/* libUSB v0.1 compat data */
void *priv01Data;
/* libUSB v0.1 and v1.0 compat data */
void *privLuData;
/* claimed interface */
uint8_t claimed_interface;