Page MenuHomeFreeBSD

D54218.id168494.diff
No OneTemporary

D54218.id168494.diff

diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -670,6 +670,7 @@
struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
int i;
int j;
+ int ok;
ctx = GET_CONTEXT(ctx);
if (ctx == NULL)
@@ -693,8 +694,12 @@
*/
if (pdesc->idVendor == vendor_id &&
pdesc->idProduct == product_id) {
- libusb_open(devs[j], &pdev);
- break;
+ ok = libusb_open(devs[j], &pdev);
+ /*
+ * If this fails, try the next one.
+ */
+ if (ok == 0)
+ break;
}
}
diff --git a/lib/libusb/libusb20.h b/lib/libusb/libusb20.h
--- a/lib/libusb/libusb20.h
+++ b/lib/libusb/libusb20.h
@@ -173,6 +173,14 @@
LIBUSB20_POWER_RESUME,
};
+/** \ingroup misc
+ * libusb20_dev_open_with_flags values
+ */
+enum libusb20_open_flags {
+ LIBUSB20_OPEN_SHARED = 0,
+ LIBUSB20_OPEN_EXCLUSIVE = 1,
+};
+
struct usb_device_info;
struct libusb20_transfer;
struct libusb20_backend;
@@ -252,6 +260,8 @@
int libusb20_dev_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstat);
int libusb20_dev_kernel_driver_active(struct libusb20_device *pdev, uint8_t iface_index);
int libusb20_dev_open(struct libusb20_device *pdev, uint16_t transfer_max);
+int libusb20_dev_open_exclusive(struct libusb20_device *pdev, uint16_t transfer_max);
+int libusb20_dev_open_with_flags(struct libusb20_device *pdev, uint16_t transfer_max, int flags);
int libusb20_dev_process(struct libusb20_device *pdev);
int libusb20_dev_request_sync(struct libusb20_device *pdev, struct LIBUSB20_CONTROL_SETUP_DECODED *setup, void *data, uint16_t *pactlen, uint32_t timeout, uint8_t flags);
int libusb20_dev_req_string_sync(struct libusb20_device *pdev, uint8_t index, uint16_t langid, void *ptr, uint16_t len);
diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c
--- a/lib/libusb/libusb20.c
+++ b/lib/libusb/libusb20.c
@@ -657,8 +657,9 @@
return (error);
}
+/* Only flag implemented is LIBUSB20_OPEN_EXCLUSIVE. */
int
-libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax)
+libusb20_dev_open_with_flags(struct libusb20_device *pdev, uint16_t nTransferMax, int flags)
{
struct libusb20_transfer *xfer;
uint32_t size;
@@ -691,7 +692,7 @@
/* set "nTransfer" early */
pdev->nTransfer = nTransferMax;
- error = pdev->beMethods->open_device(pdev, nTransferMax);
+ error = pdev->beMethods->open_device(pdev, nTransferMax, flags);
if (error) {
if (pdev->pTransfer != NULL) {
@@ -707,6 +708,12 @@
return (error);
}
+int
+libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax)
+{
+ return libusb20_dev_open_with_flags(pdev, nTransferMax, LIBUSB20_OPEN_EXCLUSIVE);
+}
+
int
libusb20_dev_reset(struct libusb20_device *pdev)
{
diff --git a/lib/libusb/libusb20_dev_open.3 b/lib/libusb/libusb20_dev_open.3
new file mode 100644
--- /dev/null
+++ b/lib/libusb/libusb20_dev_open.3
@@ -0,0 +1,110 @@
+.\"
+.\" Copyright (c) 2025 Rick Parrish <unitrunker@unitrunker.net>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd December 14, 2025
+.Dt LIBUSB20 3
+.Os
+.Sh NAME
+.Nm libusb20_dev_open
+.Nd open a USB device to retrieve descriptors and initiate transfers
+.Sh SYNOPSIS
+.Lb libusb
+.In libusb20.h
+.Ft int
+.Fn libusb20_dev_open "struct libusb20_device *pdev" "uin16_t transfer_max"
+.Ft int
+.Fn libusb20_dev_open_with_flags "struct libusb20_device *pdev" "uin16_t transfer_max" "int flags"
+.Sh DESCRIPTION
+The
+.Nm
+and
+.Fn libusb20_dev_open_with_flags
+functions open a USB device to retrieve descriptors and initiate transfers.
+.Nm
+accepts a pointer as
+.Fa pdev
+to a
+.Xr libusb20_device 3
+obtained from
+.Xr libusb20_be_device_foreach 3 .
+A zero for
+.Fa transfer_max
+limits the device to only control transfers.
+.Fn libusb20_dev_open_with_flags
+also accepts a
+.Fa flags
+argument which may be LIBUSB20_OPEN_SHARED or LIBUSB20_OPEN_EXCLUSIVE.
+Calling
+.Nm
+is the same as calling
+.Fn libusb20_dev_open_with_flags
+with
+.Fa flags
+set to LIBUSB20_OPEN_EXCLUSIVE.
+Call
+.Xr libusb20_dev_close 3
+to free resources taken by the open device handle.
+.Sh ERRORS
+.Nm
+and
+.Fn libusb20_dev_open_with_flags
+return one of the following to report success or failure:
+.Bl -tag -width "LIBUSB20_ERROR_NO_DEVICE" -compact
+.It Er LIBUSB20_SUCCESS
+The operation succeeds.
+.It Er LIBUSB20_ERROR_BUSY
+The device is in use elsewhere.
+.It Er LIBUSB20_ERROR_ACCESS
+A permissions issue.
+.It Er LIBUSB20_ERROR_NO_DEVICE
+The device detached.
+.It Er LIBUSB20_ERROR_NO_MEM
+This library could not allocate memory.
+.It More errors in
+.Xr libusb20 3
+and
+.In libusb20.h
+.El
+.Sh EXAMPLES
+.Nm
+.Bd -literal
+ #include <libusb20.h>
+ struct libusb20_backend *be = libusb20_be_alloc_default();
+ struct libusb20_device *device = NULL;
+ while ( (device = libusb20_be_device_foreach(be, device)) != NULL ) {
+ code = libusb20_dev_open(device, 4);
+ if (code == LIBUSB20_SUCCESS) {
+ /* do something */
+ libusb20_dev_close(device);
+ }
+ else if (code == LIBUSB20_ERROR_BUSY) {
+ printf("Device already in use.\n");
+ }
+ }
+ libusb20_be_free(be);
+.Ed
+.Fn libusb20_dev_open_with_flags
+.Bd -literal
+ #include <libusb20.h>
+ int code;
+ struct libusb20_backend *be = libusb20_be_alloc_default();
+ struct libusb20_device *device = NULL;
+ while ( (device = libusb20_be_device_foreach(be, device)) != NULL ) {
+ code = libusb20_dev_open_with_flags(device, 4, LIBUSB20_OPEN_EXCLUSIVE);
+ if (code == LIBUSB20_SUCCESS) {
+ /* do something */
+ libusb20_dev_close(device);
+ }
+ else if (code == LIBUSB20_ERROR_BUSY) {
+ printf("Device already in use.\n");
+ }
+ }
+ libusb20_be_free(be);
+.Ed
+.Pg
+.Sh SEE ALSO
+.Xr libusb20_be_device_foreach 3 ,
+.Xr libusb20_dev_close 3 ,
+.Xr libusb20 3
diff --git a/lib/libusb/libusb20_int.h b/lib/libusb/libusb20_int.h
--- a/lib/libusb/libusb20_int.h
+++ b/lib/libusb/libusb20_int.h
@@ -53,7 +53,7 @@
typedef int (libusb20_dev_get_info_t)(struct libusb20_device *pdev, struct usb_device_info *pinfo);
typedef int (libusb20_dev_get_iface_desc_t)(struct libusb20_device *pdev, uint8_t iface_index, char *buf, uint8_t len);
typedef int (libusb20_init_backend_t)(struct libusb20_backend *pbe);
-typedef int (libusb20_open_device_t)(struct libusb20_device *pdev, uint16_t transfer_count_max);
+typedef int (libusb20_open_device_t)(struct libusb20_device *pdev, uint16_t transfer_count_max, int flags);
typedef void (libusb20_exit_backend_t)(struct libusb20_backend *pbe);
typedef int (libusb20_root_set_template_t)(struct libusb20_backend *pbe, int temp);
typedef int (libusb20_root_get_template_t)(struct libusb20_backend *pbe, int *ptemp);
diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c
--- a/lib/libusb/libusb20_ugen20.c
+++ b/lib/libusb/libusb20_ugen20.c
@@ -375,13 +375,13 @@
}
static int
-ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer)
+ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer, int flags)
{
uint32_t plugtime;
char buf[64];
int f;
int g;
- int error;
+ int error, arg;
snprintf(buf, sizeof(buf), "/dev/" USB_GENERIC_NAME "%u.%u",
pdev->bus_number, pdev->device_address);
@@ -409,6 +409,13 @@
error = LIBUSB20_ERROR_NO_DEVICE;
goto done;
}
+ arg = ((flags & LIBUSB20_OPEN_EXCLUSIVE) != 0) ? LOCK_EX|LOCK_NB : LOCK_SH|LOCK_NB;
+ if (flock(f, arg) != 0) {
+ close(f);
+ close(g);
+ error = LIBUSB20_ERROR_BUSY;
+ goto done;
+ }
/* need to set this before "tr_renew()" */
pdev->file = f;
pdev->file_ctrl = g;

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 11:30 AM (12 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27647932
Default Alt Text
D54218.id168494.diff (7 KB)

Event Timeline