Page MenuHomeFreeBSD

D54218.id168032.diff
No OneTemporary

D54218.id168032.diff

diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -636,10 +636,17 @@
if (dev == NULL)
return (LIBUSB_ERROR_INVALID_PARAM);
- err = libusb20_dev_open(pdev, LIBUSB_NUM_SW_ENDPOINTS);
+ err = libusb20_dev_open_with_flags(pdev, LIBUSB_NUM_SW_ENDPOINTS, LIBUSB20_OPEN_EXCLUSIVE);
if (err) {
libusb_unref_device(dev);
- return (LIBUSB_ERROR_NO_MEM);
+ switch (err) {
+ case LIBUSB20_ERROR_ACCESS:
+ return LIBUSB_ERROR_ACCESS;
+ case LIBUSB20_ERROR_BUSY:
+ return LIBUSB_ERROR_BUSY;
+ default:
+ return LIBUSB_ERROR_NO_MEM;
+ }
}
/*
@@ -670,6 +677,7 @@
struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
int i;
int j;
+ int ok;
ctx = GET_CONTEXT(ctx);
if (ctx == NULL)
@@ -693,8 +701,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,13 @@
LIBUSB20_POWER_RESUME,
};
+/** \ingroup misc
+ * libusb20_dev_open_with_flags values
+ */
+enum libusb20_open_flags {
+ LIBUSB20_OPEN_EXCLUSIVE = 1,
+};
+
struct usb_device_info;
struct libusb20_transfer;
struct libusb20_backend;
@@ -252,6 +259,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,18 @@
return (error);
}
+int
+libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax)
+{
+ return libusb20_dev_open_with_flags(pdev, nTransferMax, 0);
+}
+
+int
+libusb20_dev_open_exclusive(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_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
Wed, Jan 14, 4:11 AM (5 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27634119
Default Alt Text
D54218.id168032.diff (5 KB)

Event Timeline