1diff --git a/third_party/libusb/src/libusb/core.c b/third_party/libusb/src/libusb/core.c
2index e816284..abc4f89 100644
3--- a/third_party/libusb/src/libusb/core.c
4+++ b/third_party/libusb/src/libusb/core.c
5@@ -1129,6 +1129,83 @@ int API_EXPORTED libusb_open(libusb_device *dev,
6 }
7
8 /** \ingroup dev
9+ * Open a device and obtain a device handle. A handle allows you to perform
10+ * I/O on the device in question.
11+ *
12+ * Instead of opening the device itself this function accepts an open file
13+ * descriptor that it will take ownership of.
14+ *
15+ * Internally, this function adds a reference to the device and makes it
16+ * available to you through libusb_get_device(). This reference is removed
17+ * during libusb_close().
18+ *
19+ * This is a non-blocking function; no requests are sent over the bus.
20+ *
21+ * \param dev the device to open
22+ * \param fd open file handle to the device
23+ * \param handle output location for the returned device handle pointer. Only
24+ * populated when the return code is 0.
25+ * \returns 0 on success
26+ * \returns LIBUSB_ERROR_NO_MEM on memory allocation failure
27+ * \returns LIBUSB_ERROR_ACCESS if the user has insufficient permissions
28+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
29+ * \returns another LIBUSB_ERROR code on other failure
30+ */
31+int API_EXPORTED libusb_open_fd(libusb_device *dev,
32+  int fd,
33+  libusb_device_handle **handle)
34+{
35+  struct libusb_context *ctx = DEVICE_CTX(dev);
36+  struct libusb_device_handle *_handle;
37+  size_t priv_size = usbi_backend->device_handle_priv_size;
38+  int r;
39+  usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);
40+
41+  if (!dev->attached) {
42+    return LIBUSB_ERROR_NO_DEVICE;
43+  }
44+
45+  _handle = malloc(sizeof(*_handle) + priv_size);
46+  if (!_handle)
47+    return LIBUSB_ERROR_NO_MEM;
48+
49+  r = usbi_mutex_init(&_handle->lock, NULL);
50+  if (r) {
51+    free(_handle);
52+    return LIBUSB_ERROR_OTHER;
53+  }
54+
55+  _handle->dev = libusb_ref_device(dev);
56+  _handle->auto_detach_kernel_driver = 0;
57+  _handle->claimed_interfaces = 0;
58+  memset(&_handle->os_priv, 0, priv_size);
59+
60+  r = usbi_backend->open_fd(_handle, fd);
61+  if (r < 0) {
62+    usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r);
63+    libusb_unref_device(dev);
64+    usbi_mutex_destroy(&_handle->lock);
65+    free(_handle);
66+    return r;
67+  }
68+
69+  usbi_mutex_lock(&ctx->open_devs_lock);
70+  list_add(&_handle->list, &ctx->open_devs);
71+  usbi_mutex_unlock(&ctx->open_devs_lock);
72+  *handle = _handle;
73+
74+  /* At this point, we want to interrupt any existing event handlers so
75+   * that they realise the addition of the new device's poll fd. One
76+   * example when this is desirable is if the user is running a separate
77+   * dedicated libusbx events handling thread, which is running with a long
78+   * or infinite timeout. We want to interrupt that iteration of the loop,
79+   * so that it picks up the new fd, and then continues. */
80+  usbi_fd_notification(ctx);
81+
82+  return 0;
83+}
84+
85+/** \ingroup dev
86  * Convenience function for finding a device with a particular
87  * <tt>idVendor</tt>/<tt>idProduct</tt> combination. This function is intended
88  * for those scenarios where you are using libusbx to knock up a quick test
89diff --git a/third_party/libusb/src/libusb/libusb.h b/third_party/libusb/src/libusb/libusb.h
90index d144b3e..5d60951 100644
91--- a/third_party/libusb/src/libusb/libusb.h
92+++ b/third_party/libusb/src/libusb/libusb.h
93@@ -1371,6 +1371,8 @@ int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev,
94 	unsigned char endpoint);
95
96 int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle);
97+int LIBUSB_CALL libusb_open_fd(libusb_device *dev, int fd,
98+	libusb_device_handle **handle);
99 void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle);
100 libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle);
101
102diff --git a/third_party/libusb/src/libusb/libusbi.h b/third_party/libusb/src/libusb/libusbi.h
103index bc608b92..eb2f0e6 100644
104--- a/third_party/libusb/src/libusb/libusbi.h
105+++ b/third_party/libusb/src/libusb/libusbi.h
106@@ -615,6 +615,11 @@ struct usbi_os_backend {
107 	 */
108 	int (*open)(struct libusb_device_handle *handle);
109
110+	/* Like open() above but uses the file descriptor provided instead of opening
111+	 * one on its own.
112+	 */
113+	int (*open_fd)(struct libusb_device_handle *handle, int fd);
114+
115 	/* Close a device such that the handle cannot be used again. Your backend
116 	 * should destroy any resources that were allocated in the open path.
117 	 * This may also be a good place to call usbi_remove_pollfd() to inform
118diff --git a/third_party/libusb/src/libusb/os/darwin_usb.c b/third_party/libusb/src/libusb/os/darwin_usb.c
119index f95706a..f6b397e 100644
120--- a/third_party/libusb/src/libusb/os/darwin_usb.c
121+++ b/third_party/libusb/src/libusb/os/darwin_usb.c
122@@ -1877,6 +1877,7 @@ const struct usbi_os_backend darwin_backend = {
123         .get_config_descriptor = darwin_get_config_descriptor,
124
125         .open = darwin_open,
126+        .open_fd = NULL, /* not implemented */
127         .close = darwin_close,
128         .get_configuration = darwin_get_configuration,
129         .set_configuration = darwin_set_configuration,
130diff --git a/third_party/libusb/src/libusb/os/linux_usbfs.c b/third_party/libusb/src/libusb/os/linux_usbfs.c
131index 142fa2b..e965856 100644
132--- a/third_party/libusb/src/libusb/os/linux_usbfs.c
133+++ b/third_party/libusb/src/libusb/os/linux_usbfs.c
134@@ -1259,26 +1259,12 @@ static int linux_default_scan_devices (struct libusb_context *ctx)
135 }
136 #endif
137
138-static int op_open(struct libusb_device_handle *handle)
139+static int op_open_fd(struct libusb_device_handle *handle, int fd)
140 {
141 	struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
142 	int r;
143
144-	hpriv->fd = _get_usbfs_fd(handle->dev, O_RDWR, 0);
145-	if (hpriv->fd < 0) {
146-		if (hpriv->fd == LIBUSB_ERROR_NO_DEVICE) {
147-			/* device will still be marked as attached if hotplug monitor thread
148-			 * hasn't processed remove event yet */
149-			usbi_mutex_static_lock(&linux_hotplug_lock);
150-			if (handle->dev->attached) {
151-				usbi_dbg("open failed with no device, but device still attached");
152-				linux_device_disconnected(handle->dev->bus_number,
153-						handle->dev->device_address, NULL);
154-			}
155-			usbi_mutex_static_unlock(&linux_hotplug_lock);
156-		}
157-		return hpriv->fd;
158-	}
159+	hpriv->fd = fd;
160
161 	r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps);
162 	if (r < 0) {
163@@ -1296,6 +1282,29 @@ static int op_open(struct libusb_device_handle *handle)
164 	return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);
165 }
166
167+static int op_open(struct libusb_device_handle *handle)
168+{
169+	struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
170+	int fd = _get_usbfs_fd(handle->dev, O_RDWR, 0);
171+
172+	if (fd < 0) {
173+		if (fd == LIBUSB_ERROR_NO_DEVICE) {
174+			/* device will still be marked as attached if hotplug monitor thread
175+			 * hasn't processed remove event yet */
176+			usbi_mutex_static_lock(&linux_hotplug_lock);
177+			if (handle->dev->attached) {
178+				usbi_dbg("open failed with no device, but device still attached");
179+				linux_device_disconnected(handle->dev->bus_number,
180+						handle->dev->device_address, NULL);
181+			}
182+			usbi_mutex_static_unlock(&linux_hotplug_lock);
183+		}
184+		return fd;
185+	}
186+
187+	return op_open_fd(handle, fd);
188+}
189+
190 static void op_close(struct libusb_device_handle *dev_handle)
191 {
192 	int fd = _device_handle_priv(dev_handle)->fd;
193@@ -2570,6 +2579,7 @@ const struct usbi_os_backend linux_usbfs_backend = {
194 	.get_config_descriptor_by_value = op_get_config_descriptor_by_value,
195
196 	.open = op_open,
197+	.open_fd = op_open_fd,
198 	.close = op_close,
199 	.get_configuration = op_get_configuration,
200 	.set_configuration = op_set_configuration,
201diff --git a/third_party/libusb/src/libusb/os/openbsd_usb.c b/third_party/libusb/src/libusb/os/openbsd_usb.c
202index 2997e53..2d24f2c 100644
203--- a/third_party/libusb/src/libusb/os/openbsd_usb.c
204+++ b/third_party/libusb/src/libusb/os/openbsd_usb.c
205@@ -98,6 +98,7 @@ const struct usbi_os_backend openbsd_backend = {
206 	obsd_get_device_list,
207 	NULL,				/* hotplug_poll */
208 	obsd_open,
209+	NULL,       /* open_fd */
210 	obsd_close,
211
212 	obsd_get_device_descriptor,
213diff --git a/third_party/libusb/src/libusb/os/wince_usb.c b/third_party/libusb/src/libusb/os/wince_usb.c
214index 90c129b..c069c56 100644
215--- a/third_party/libusb/src/libusb/os/wince_usb.c
216+++ b/third_party/libusb/src/libusb/os/wince_usb.c
217@@ -990,6 +990,7 @@ const struct usbi_os_backend wince_backend = {
218         wince_get_device_list,
219 	NULL,				/* hotplug_poll */
220         wince_open,
221+        NULL, /* open_fd */
222         wince_close,
223
224         wince_get_device_descriptor,
225diff --git a/third_party/libusb/src/libusb/os/windows_usb.c b/third_party/libusb/src/libusb/os/windows_usb.c
226index 4469992..bc4def6 100644
227--- a/third_party/libusb/src/libusb/os/windows_usb.c
228+++ b/third_party/libusb/src/libusb/os/windows_usb.c
229@@ -2290,6 +2290,7 @@ const struct usbi_os_backend windows_backend = {
230 	windows_get_device_list,
231 	NULL,				/* hotplug_poll */
232 	windows_open,
233+	NULL,       /* open_fd */
234 	windows_close,
235
236 	windows_get_device_descriptor,
237