aboutsummaryrefslogtreecommitdiff
path: root/lib/libusb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libusb')
-rw-r--r--lib/libusb/Makefile3
-rw-r--r--lib/libusb/libusb10.c25
-rw-r--r--lib/libusb/libusb10_io.c10
-rw-r--r--lib/libusb/libusb20.322
-rw-r--r--lib/libusb/libusb20.c9
-rw-r--r--lib/libusb/libusb20.h1
-rw-r--r--lib/libusb/libusb20_int.h2
-rw-r--r--lib/libusb/libusb20_ugen20.c32
8 files changed, 81 insertions, 23 deletions
diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile
index 7a9bd1b23678..d45dd567b437 100644
--- a/lib/libusb/Makefile
+++ b/lib/libusb/Makefile
@@ -18,6 +18,9 @@ NOGCCERROR=
WARNS?= 2
+DPADD= ${LIBPTHREAD}
+LDADD= -lpthread
+
MLINKS+= libusb.3 usb.3
# libusb 0.1 compat
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
index 44331bc6ad3c..256d67e93bc5 100644
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -92,6 +92,7 @@ int
libusb_init(libusb_context **context)
{
struct libusb_context *ctx;
+ pthread_condattr_t attr;
char *debug;
int ret;
@@ -110,8 +111,28 @@ libusb_init(libusb_context **context)
TAILQ_INIT(&ctx->pollfds);
TAILQ_INIT(&ctx->tr_done);
- pthread_mutex_init(&ctx->ctx_lock, NULL);
- pthread_cond_init(&ctx->ctx_cond, NULL);
+ if (pthread_mutex_init(&ctx->ctx_lock, NULL) != 0) {
+ free(ctx);
+ return (LIBUSB_ERROR_NO_MEM);
+ }
+ if (pthread_condattr_init(&attr) != 0) {
+ pthread_mutex_destroy(&ctx->ctx_lock);
+ free(ctx);
+ return (LIBUSB_ERROR_NO_MEM);
+ }
+ if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) != 0) {
+ pthread_mutex_destroy(&ctx->ctx_lock);
+ pthread_condattr_destroy(&attr);
+ free(ctx);
+ return (LIBUSB_ERROR_OTHER);
+ }
+ if (pthread_cond_init(&ctx->ctx_cond, &attr) != 0) {
+ pthread_mutex_destroy(&ctx->ctx_lock);
+ pthread_condattr_destroy(&attr);
+ free(ctx);
+ return (LIBUSB_ERROR_NO_MEM);
+ }
+ pthread_condattr_destroy(&attr);
ctx->ctx_handler = NO_THREAD;
diff --git a/lib/libusb/libusb10_io.c b/lib/libusb/libusb10_io.c
index 63f833af8828..302fdb8dda32 100644
--- a/lib/libusb/libusb10_io.c
+++ b/lib/libusb/libusb10_io.c
@@ -307,12 +307,16 @@ libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
&ctx->ctx_lock);
return (0);
}
- err = clock_gettime(CLOCK_REALTIME, &ts);
+ err = clock_gettime(CLOCK_MONOTONIC, &ts);
if (err < 0)
return (LIBUSB_ERROR_OTHER);
- ts.tv_sec = tv->tv_sec;
- ts.tv_nsec = tv->tv_usec * 1000;
+ /*
+ * The "tv" arguments points to a relative time structure and
+ * not an absolute time structure.
+ */
+ ts.tv_sec += tv->tv_sec;
+ ts.tv_nsec += tv->tv_usec * 1000;
if (ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000;
ts.tv_sec++;
diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3
index 2253ece27779..af80c6ca564e 100644
--- a/lib/libusb/libusb20.3
+++ b/lib/libusb/libusb20.3
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 14, 2010
+.Dd August 13, 2012
.Dt LIBUSB20 3
.Os
.Sh NAME
@@ -48,6 +48,7 @@ USB access library (libusb -lusb)
.Fn libusb20_tr_close "struct libusb20_transfer *xfer"
.Ft int
.Fn libusb20_tr_open "struct libusb20_transfer *xfer" "uint32_t max_buf_size" "uint32_t max_frame_count" "uint8_t ep_no"
+.Fn libusb20_tr_open_stream "struct libusb20_transfer *xfer" "uint32_t max_buf_size" "uint32_t max_frame_count" "uint8_t ep_no" "uint16_t stream_id"
.Ft struct libusb20_transfer*
.Fn libusb20_tr_get_pointer "struct libusb20_device *pdev" "uint16_t tr_index"
.Ft uint16_t
@@ -284,6 +285,16 @@ Non-zero return values indicate a LIBUSB20_ERROR value.
.
.Pp
.
+.Fn libusb20_tr_open_stream
+is identical to
+.Fn libusb20_tr_open
+except that a stream ID can be specified for BULK endpoints having
+such a feature.
+.Fn libusb20_tr_open
+can be used to open stream ID zero.
+.
+.Pp
+.
.Fn libusb20_tr_get_pointer
will return a pointer to the allocated USB transfer according to the
.Fa pdev
@@ -401,7 +412,7 @@ The callback type is defined by libusb20_tr_callback_t.
.
.Fn libusb20_tr_set_flags
is used to set various USB flags for the given USB transfer.
-.Bl -tag
+.Bl -tag -width "LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK"
.It LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK
Report a short frame as error.
.It LIBUSB20_TRANSFER_MULTI_SHORT_NOT_OK
@@ -709,13 +720,14 @@ This function returns zero if the device is still connected else a LIBUSB20_ERRO
sets the power mode of the USB device.
.
Valid power modes:
-.Bl -tag
+.Bl -tag -width "LIBUSB20_POWER_OFF"
.It LIBUSB20_POWER_OFF
.It LIBUSB20_POWER_ON
.It LIBUSB20_POWER_SAVE
.It LIBUSB20_POWER_SUSPEND
.It LIBUSB20_POWER_RESUME
.El
+.Pp
.
This function returns zero on success else a LIBUSB20_ERROR value is
returned.
@@ -793,7 +805,7 @@ Valid bus numbers start at zero.
returns the current operation mode of the USB entity.
.
Valid return values are:
-.Bl -tag
+.Bl -tag -width "LIBUSB20_MODE_DEVICE"
.It LIBUSB20_MODE_HOST
.It LIBUSB20_MODE_DEVICE
.El
@@ -803,7 +815,7 @@ Valid return values are:
.Fn libusb20_dev_get_speed
returns the current speed of the given USB device.
.
-.Bl -tag
+.Bl -tag -width "LIBUSB20_SPEED_VARIABLE"
.It LIBUSB20_SPEED_UNKNOWN
.It LIBUSB20_SPEED_LOW
.It LIBUSB20_SPEED_FULL
diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c
index 75af7a1865c1..aa459913ec98 100644
--- a/lib/libusb/libusb20.c
+++ b/lib/libusb/libusb20.c
@@ -155,6 +155,13 @@ int
libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize,
uint32_t MaxFrameCount, uint8_t ep_no)
{
+ return (libusb20_tr_open_stream(xfer, MaxBufSize, MaxFrameCount, ep_no, 0));
+}
+
+int
+libusb20_tr_open_stream(struct libusb20_transfer *xfer, uint32_t MaxBufSize,
+ uint32_t MaxFrameCount, uint8_t ep_no, uint16_t stream_id)
+{
uint32_t size;
uint8_t pre_scale;
int error;
@@ -188,7 +195,7 @@ libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize,
memset(xfer->ppBuffer, 0, size);
error = xfer->pdev->methods->tr_open(xfer, MaxBufSize,
- MaxFrameCount, ep_no, pre_scale);
+ MaxFrameCount, ep_no, stream_id, pre_scale);
if (error) {
free(xfer->ppBuffer);
diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h
index e4359fcb1549..87e057262067 100644
--- a/lib/libusb/libusb20.h
+++ b/lib/libusb/libusb20.h
@@ -202,6 +202,7 @@ struct libusb20_quirk {
/* USB transfer operations */
int libusb20_tr_close(struct libusb20_transfer *xfer);
int libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t max_buf_size, uint32_t max_frame_count, uint8_t ep_no);
+int libusb20_tr_open_stream(struct libusb20_transfer *xfer, uint32_t max_buf_size, uint32_t max_frame_count, uint8_t ep_no, uint16_t stream_id);
struct libusb20_transfer *libusb20_tr_get_pointer(struct libusb20_device *pdev, uint16_t tr_index);
uint16_t libusb20_tr_get_time_complete(struct libusb20_transfer *xfer);
uint32_t libusb20_tr_get_actual_frames(struct libusb20_transfer *xfer);
diff --git a/lib/libusb/libusb20_int.h b/lib/libusb/libusb20_int.h
index bef4d02737c5..0251c5f6ed07 100644
--- a/lib/libusb/libusb20_int.h
+++ b/lib/libusb/libusb20_int.h
@@ -110,7 +110,7 @@ typedef int (libusb20_set_config_index_t)(struct libusb20_device *pdev, uint8_t
typedef int (libusb20_check_connected_t)(struct libusb20_device *pdev);
/* USB transfer specific */
-typedef int (libusb20_tr_open_t)(struct libusb20_transfer *xfer, uint32_t MaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no, uint8_t pre_scale);
+typedef int (libusb20_tr_open_t)(struct libusb20_transfer *xfer, uint32_t MaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no, uint16_t stream_id, uint8_t pre_scale);
typedef int (libusb20_tr_close_t)(struct libusb20_transfer *xfer);
typedef int (libusb20_tr_clear_stall_sync_t)(struct libusb20_transfer *xfer);
typedef void (libusb20_tr_submit_t)(struct libusb20_transfer *xfer);
diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c
index 17c948b4ac38..2c677783d850 100644
--- a/lib/libusb/libusb20_ugen20.c
+++ b/lib/libusb/libusb20_ugen20.c
@@ -741,9 +741,13 @@ ugen20_process(struct libusb20_device *pdev)
static int
ugen20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize,
- uint32_t MaxFrameCount, uint8_t ep_no, uint8_t pre_scale)
+ uint32_t MaxFrameCount, uint8_t ep_no, uint16_t stream_id,
+ uint8_t pre_scale)
{
- struct usb_fs_open temp;
+ union {
+ struct usb_fs_open fs_open;
+ struct usb_fs_open_stream fs_open_stream;
+ } temp;
struct usb_fs_endpoint *fsep;
if (pre_scale)
@@ -754,20 +758,26 @@ ugen20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize,
fsep = xfer->pdev->privBeData;
fsep += xfer->trIndex;
- temp.max_bufsize = MaxBufSize;
- temp.max_frames = MaxFrameCount;
- temp.ep_index = xfer->trIndex;
- temp.ep_no = ep_no;
+ temp.fs_open.max_bufsize = MaxBufSize;
+ temp.fs_open.max_frames = MaxFrameCount;
+ temp.fs_open.ep_index = xfer->trIndex;
+ temp.fs_open.ep_no = ep_no;
- if (ioctl(xfer->pdev->file, USB_FS_OPEN, &temp)) {
- return (LIBUSB20_ERROR_INVALID_PARAM);
+ if (stream_id != 0) {
+ temp.fs_open_stream.stream_id = stream_id;
+
+ if (ioctl(xfer->pdev->file, USB_FS_OPEN_STREAM, &temp.fs_open_stream))
+ return (LIBUSB20_ERROR_INVALID_PARAM);
+ } else {
+ if (ioctl(xfer->pdev->file, USB_FS_OPEN, &temp.fs_open))
+ return (LIBUSB20_ERROR_INVALID_PARAM);
}
/* maximums might have changed - update */
- xfer->maxFrames = temp.max_frames;
+ xfer->maxFrames = temp.fs_open.max_frames;
/* "max_bufsize" should be multiple of "max_packet_length" */
- xfer->maxTotalLength = temp.max_bufsize;
- xfer->maxPacketLen = temp.max_packet_length;
+ xfer->maxTotalLength = temp.fs_open.max_bufsize;
+ xfer->maxPacketLen = temp.fs_open.max_packet_length;
/* setup buffer and length lists using zero copy */
fsep->ppBuffer = libusb20_pass_ptr(xfer->ppBuffer);