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:
parent
ed190ad06a
commit
390065b18e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=195957
@ -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
|
||||
|
@ -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
@ -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__ */
|
||||
|
@ -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
@ -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
|
||||
.
|
||||
|
@ -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 *
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user