libusb(3): Implement libusb_init_context() and the needed structures and definitions.

Differential Revision:	https://reviews.freebsd.org/D38212
MFC after:	1 week
Sponsored by:	NVIDIA Networking
This commit is contained in:
Hans Petter Selasky 2023-01-26 13:56:51 +01:00
parent 463c88e634
commit 4c6bcffd04
4 changed files with 69 additions and 9 deletions

View File

@ -68,6 +68,7 @@ CFLAGS+= -I ../../sys
# LibUSB v1.0
MLINKS += libusb.3 libusb_get_version.3
MLINKS += libusb.3 libusb_init.3
MLINKS += libusb.3 libusb_init_context.3
MLINKS += libusb.3 libusb_exit.3
MLINKS += libusb.3 libusb_has_capability.3
MLINKS += libusb.3 libusb_strerror.3

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd October, 2, 2022
.Dd January, 26, 2023
.Dt LIBUSB 3
.Os
.Sh NAME
@ -47,11 +47,26 @@ This function returns version information about LibUSB.
.Pp
.Ft int
.Fn libusb_init "libusb_context **ctx"
This function initialises libusb.
It must be called at the beginning
of the program, before other libusb routines are used.
This function returns 0 on success or LIBUSB_ERROR on
failure.
Call this function before any other libusb v1.0 API function, to
initialise a valid libusb v1.0 context.
If the
.Fa ctx
argument is non-NULL, a pointer to the libusb context is stored at
the given location.
This function returns 0 upon success or LIBUSB_ERROR on failure.
.Pp
.Ft int
.Fn libusb_init_context "libusb_context **ctx" "const struct libusb_init_option []" "int num_options"
Call this function before any other libusb v1.0 API function, to
initialise a valid libusb v1.0 context.
If the
.Fa ctx
argument is non-NULL, a pointer to the libusb context is stored at
the given location.
Additional options, like the USB debug level, may be given using the
second and third argument.
If no options are needed, simply use libusb_init().
This function returns 0 upon success or a LIBUSB_ERROR value on failure.
.Pp
.Ft void
.Fn libusb_exit "libusb_context *ctx"

View File

@ -266,6 +266,14 @@ typedef enum {
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 2,
} libusb_hotplug_event;
enum libusb_option {
LIBUSB_OPTION_LOG_LEVEL = 0,
LIBUSB_OPTION_USE_USBDK = 1,
LIBUSB_OPTION_NO_DEVICE_DISCOVERY = 2,
LIBUSB_OPTION_WEAK_AUTHORITY = 2,
LIBUSB_OPTION_MAX = 3,
};
/* libusb structures */
struct libusb_context;
@ -288,6 +296,13 @@ struct libusb_version {
const char *describe;
};
struct libusb_init_option {
enum libusb_option option;
union {
int64_t ival;
} value;
};
typedef struct libusb_context libusb_context;
typedef struct libusb_device libusb_device;
typedef struct libusb_device_handle libusb_device_handle;
@ -465,6 +480,7 @@ const struct libusb_version *libusb_get_version(void);
const char *libusb_strerror(int code);
const char *libusb_error_name(int code);
int libusb_init(libusb_context ** context);
int libusb_init_context(libusb_context **, const struct libusb_init_option [], int num_options);
void libusb_exit(struct libusb_context *ctx);
int libusb_has_capability(uint32_t capability);

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
* Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
* Copyright (c) 2009-2023 Hans Petter Selasky
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -135,12 +135,22 @@ libusb_interrupt_event_handler(libusb_context *ctx)
int
libusb_init(libusb_context **context)
{
return (libusb_init_context(context, NULL, 0));
}
int
libusb_init_context(libusb_context **context,
const struct libusb_init_option option[], int num_options)
{
struct libusb_context *ctx;
pthread_condattr_t attr;
char *debug, *ep;
int ret;
if (num_options < 0)
return (LIBUSB_ERROR_INVALID_PARAM);
ctx = malloc(sizeof(*ctx));
if (!ctx)
return (LIBUSB_ERROR_INVALID_PARAM);
@ -150,8 +160,9 @@ libusb_init(libusb_context **context)
debug = getenv("LIBUSB_DEBUG");
if (debug != NULL) {
/*
* If LIBUSB_DEBUG is set, we'll honor that and use it to
* override libusb_set_debug calls.
* If LIBUSB_DEBUG is set, we'll honor that first and
* use it to override any future libusb_set_debug()
* calls or init options.
*/
errno = 0;
ctx->debug = strtol(debug, &ep, 10);
@ -166,7 +177,24 @@ libusb_init(libusb_context **context)
*/
ctx->debug = 0;
}
} else {
/*
* If the LIBUSB_OPTION_LOG_LEVEL is set, honor that.
*/
for (int i = 0; i != num_options; i++) {
if (option[i].option != LIBUSB_OPTION_LOG_LEVEL)
continue;
ctx->debug = (int)option[i].value.ival;
if ((int64_t)ctx->debug == option[i].value.ival) {
ctx->debug_fixed = 1;
} else {
free(ctx);
return (LIBUSB_ERROR_INVALID_PARAM);
}
}
}
TAILQ_INIT(&ctx->pollfds);
TAILQ_INIT(&ctx->tr_done);
TAILQ_INIT(&ctx->hotplug_cbh);