libusb: replace LOG_LEVEL with DEBUG_LEVEL

The libusb set debug level by libusb_log_level instead of
libusb_debug_level. We switch to libusb_log_level for better
compatibility with the upstream libusb.

Additionally, The upstream libusb has an option allows user to override the log
function with a user-defined callback.
To support the callback function with a single string without va_arg, we
refactor the log facility as a function instead of a macro and parse all
va_args inside.

The legacy debug_level enum has been removed to enforce maintainer migrate from their
deprecated source code.

Reviewed by:    kevans
Approved by:    markj (mentor), lwhsu (mentor)
MFC after:      2 weeks
Sponsored by:   FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D50680
This commit is contained in:
ShengYi Hung 2025-06-04 17:57:30 +08:00
parent 0849d876b1
commit bca5df4565
4 changed files with 55 additions and 47 deletions

View file

@ -243,17 +243,6 @@ enum libusb_log_level {
LIBUSB_LOG_LEVEL_DEBUG
};
/* XXX */
/* libusb_set_debug should take parameters from libusb_log_level
* above according to
* https://libusb.sourceforge.io/api-1.0/group__libusb__lib.html
*/
enum libusb_debug_level {
LIBUSB_DEBUG_NO=0,
LIBUSB_DEBUG_FUNCTION=1,
LIBUSB_DEBUG_TRANSFER=2,
};
#define LIBUSB_HOTPLUG_MATCH_ANY -1
typedef enum {

View file

@ -35,6 +35,7 @@
#include <poll.h>
#include <pthread.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -48,6 +49,7 @@
#endif
#define libusb_device_handle libusb20_device
#define LIBUSB_LOG_BUFFER_SIZE 1024
#include "libusb20.h"
#include "libusb20_desc.h"
@ -128,7 +130,7 @@ libusb_interrupt_event_handler(libusb_context *ctx)
err = eventfd_write(ctx->event, 1);
if (err < 0) {
/* ignore error, if any */
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "Waking up event loop failed!");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_ERROR, "Waking up event loop failed!");
}
}
@ -253,7 +255,7 @@ libusb_init_context(libusb_context **context,
if (context)
*context = ctx;
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_init complete");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_INFO, "libusb_init complete");
signal(SIGPIPE, SIG_IGN);
@ -625,7 +627,7 @@ libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id,
if (ctx == NULL)
return (NULL); /* be NULL safe */
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_with_vid_pid enter");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_open_device_with_vid_pid enter");
if ((i = libusb_get_device_list(ctx, &devs)) < 0)
return (NULL);
@ -649,7 +651,7 @@ libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id,
}
libusb_free_device_list(devs, 1);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_with_vid_pid leave");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_open_device_with_vid_pid leave");
return (pdev);
}
@ -1536,7 +1538,7 @@ libusb_submit_transfer(struct libusb_transfer *uxfer)
dev = libusb_get_device(uxfer->dev_handle);
DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter");
DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_submit_transfer enter");
sxfer = (struct libusb_super_transfer *)(
(uint8_t *)uxfer - sizeof(*sxfer));
@ -1571,7 +1573,7 @@ libusb_submit_transfer(struct libusb_transfer *uxfer)
CTX_UNLOCK(dev->ctx);
DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave %d", err);
DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_submit_transfer leave %d", err);
return (err);
}
@ -1600,7 +1602,7 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer)
dev = libusb_get_device(devh);
DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter");
DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_cancel_transfer enter");
sxfer = (struct libusb_super_transfer *)(
(uint8_t *)uxfer - sizeof(*sxfer));
@ -1661,7 +1663,7 @@ libusb_cancel_transfer(struct libusb_transfer *uxfer)
CTX_UNLOCK(dev->ctx);
DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave");
DPRINTF(dev->ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_cancel_transfer leave");
return (retval);
}
@ -1811,3 +1813,32 @@ libusb_has_capability(uint32_t capability)
return (0);
}
}
void
libusb_log_va_args(struct libusb_context *ctx, enum libusb_log_level level,
const char *fmt, ...)
{
static const char *log_prefix[5] = {
[LIBUSB_LOG_LEVEL_ERROR] = "LIBUSB_ERROR",
[LIBUSB_LOG_LEVEL_WARNING] = "LIBUSB_WARN",
[LIBUSB_LOG_LEVEL_INFO] = "LIBUSB_INFO",
[LIBUSB_LOG_LEVEL_DEBUG] = "LIBUSB_DEBUG",
};
char buffer[LIBUSB_LOG_BUFFER_SIZE];
char new_fmt[LIBUSB_LOG_BUFFER_SIZE];
va_list args;
ctx = GET_CONTEXT(ctx);
if (ctx->debug < level)
return;
va_start(args, fmt);
snprintf(new_fmt, sizeof(new_fmt), "%s: %s\n", log_prefix[level], fmt);
vsnprintf(buffer, sizeof(buffer), new_fmt, args);
fputs(buffer, stdout);
va_end(args);
}

View file

@ -29,6 +29,7 @@
#define __LIBUSB10_H__
#ifndef LIBUSB_GLOBAL_INCLUDE_FILE
#include <sys/cdefs.h>
#include <sys/queue.h>
#include <netlink/netlink.h>
#include <netlink/netlink_generic.h>
@ -46,24 +47,11 @@
#define HOTPLUG_LOCK(ctx) pthread_mutex_lock(&(ctx)->hotplug_lock)
#define HOTPLUG_UNLOCK(ctx) pthread_mutex_unlock(&(ctx)->hotplug_lock)
#define DPRINTF(ctx, dbg, format, ...) do { \
switch (dbg) { \
case LIBUSB_DEBUG_FUNCTION: \
if ((ctx)->debug & LIBUSB_DEBUG_FUNCTION) { \
printf("LIBUSB_FUNCTION: " \
format "\n", ## __VA_ARGS__); \
} \
break; \
case LIBUSB_DEBUG_TRANSFER: \
if ((ctx)->debug & LIBUSB_DEBUG_TRANSFER) { \
printf("LIBUSB_TRANSFER: " \
format "\n", ## __VA_ARGS__); \
} \
break; \
default: \
break; \
} \
} while (0)
void libusb_log_va_args(struct libusb_context *ctx, enum libusb_log_level level,
const char *fmt, ...) __printflike(3, 4);
#define DPRINTF(ctx, dbg, format, ...) \
libusb_log_va_args(ctx, dbg, format, ##__VA_ARGS__)
/* internal structures */

View file

@ -108,7 +108,7 @@ libusb10_handle_events_sub(struct libusb_context *ctx, struct timeval *tv)
int i;
int err;
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb10_handle_events_sub enter");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb10_handle_events_sub enter");
nfds = 0;
i = 0;
@ -230,7 +230,7 @@ do_done:
/* Wakeup other waiters */
pthread_cond_broadcast(&ctx->ctx_cond);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb10_handle_events_sub complete");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb10_handle_events_sub complete");
return (err);
}
@ -314,7 +314,7 @@ libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
int err;
ctx = GET_CONTEXT(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_wait_for_event enter");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_wait_for_event enter");
if (tv == NULL) {
pthread_cond_wait(&ctx->ctx_cond,
@ -358,7 +358,7 @@ libusb_handle_events_timeout_completed(libusb_context *ctx,
ctx = GET_CONTEXT(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed enter");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_handle_events_timeout_completed enter");
libusb_lock_events(ctx);
@ -374,7 +374,7 @@ libusb_handle_events_timeout_completed(libusb_context *ctx,
libusb_unlock_events(ctx);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_handle_events_timeout_completed exit");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_handle_events_timeout_completed exit");
return (err);
}
@ -523,7 +523,7 @@ libusb10_do_transfer_cb(struct libusb_transfer *transfer)
ctx = libusb10_get_context_by_device_handle(transfer->dev_handle);
DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "sync I/O done");
pdone = transfer->user_data;
*pdone = 1;
@ -613,12 +613,12 @@ libusb_bulk_transfer(libusb_device_handle *devh,
ctx = libusb10_get_context_by_device_handle(devh);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_bulk_transfer enter");
ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
timeout, LIBUSB_TRANSFER_TYPE_BULK);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer leave");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_bulk_transfer leave");
return (ret);
}
@ -632,12 +632,12 @@ libusb_interrupt_transfer(libusb_device_handle *devh,
ctx = libusb10_get_context_by_device_handle(devh);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_interrupt_transfer enter");
ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT);
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer leave");
DPRINTF(ctx, LIBUSB_LOG_LEVEL_DEBUG, "libusb_interrupt_transfer leave");
return (ret);
}