summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libusb/os/linux_netlink.c2
-rw-r--r--libusb/os/linux_udev.c2
-rw-r--r--libusb/os/linux_usbfs.c23
-rw-r--r--libusb/os/linux_usbfs.h2
-rw-r--r--libusb/version_nano.h2
5 files changed, 25 insertions, 6 deletions
diff --git a/libusb/os/linux_netlink.c b/libusb/os/linux_netlink.c
index 40f3fef..f1c1be1 100644
--- a/libusb/os/linux_netlink.c
+++ b/libusb/os/linux_netlink.c
@@ -293,7 +293,7 @@ static int linux_netlink_read_message(void)
/* signal device is available (or not) to all contexts */
if (detached)
- linux_hotplug_disconnected(busnum, devaddr, sys_name);
+ linux_device_disconnected(busnum, devaddr, sys_name);
else
linux_hotplug_enumerate(busnum, devaddr, sys_name);
diff --git a/libusb/os/linux_udev.c b/libusb/os/linux_udev.c
index 70f632d..99ac943 100644
--- a/libusb/os/linux_udev.c
+++ b/libusb/os/linux_udev.c
@@ -240,7 +240,7 @@ static void udev_hotplug_event(struct udev_device* udev_dev)
if (strncmp(udev_action, "add", 3) == 0) {
linux_hotplug_enumerate(busnum, devaddr, sys_name);
} else if (detached) {
- linux_hotplug_disconnected(busnum, devaddr, sys_name);
+ linux_device_disconnected(busnum, devaddr, sys_name);
} else {
usbi_err(NULL, "ignoring udev action %s", udev_action);
}
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 8c0ef6f..142fa2b 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -1090,7 +1090,7 @@ void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_na
usbi_mutex_static_unlock(&active_contexts_lock);
}
-void linux_hotplug_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name)
+void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name)
{
struct libusb_context *ctx;
struct libusb_device *dev;
@@ -1265,8 +1265,20 @@ static int op_open(struct libusb_device_handle *handle)
int r;
hpriv->fd = _get_usbfs_fd(handle->dev, O_RDWR, 0);
- if (hpriv->fd < 0)
+ if (hpriv->fd < 0) {
+ if (hpriv->fd == LIBUSB_ERROR_NO_DEVICE) {
+ /* device will still be marked as attached if hotplug monitor thread
+ * hasn't processed remove event yet */
+ usbi_mutex_static_lock(&linux_hotplug_lock);
+ if (handle->dev->attached) {
+ usbi_dbg("open failed with no device, but device still attached");
+ linux_device_disconnected(handle->dev->bus_number,
+ handle->dev->device_address, NULL);
+ }
+ usbi_mutex_static_unlock(&linux_hotplug_lock);
+ }
return hpriv->fd;
+ }
r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps);
if (r < 0) {
@@ -2500,6 +2512,13 @@ static int op_handle_events(struct libusb_context *ctx,
if (pollfd->revents & POLLERR) {
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd);
usbi_handle_disconnect(handle);
+ /* device will still be marked as attached if hotplug monitor thread
+ * hasn't processed remove event yet */
+ usbi_mutex_static_lock(&linux_hotplug_lock);
+ if (handle->dev->attached)
+ linux_device_disconnected(handle->dev->bus_number,
+ handle->dev->device_address, NULL);
+ usbi_mutex_static_unlock(&linux_hotplug_lock);
continue;
}
diff --git a/libusb/os/linux_usbfs.h b/libusb/os/linux_usbfs.h
index 499bab7..1f5b191 100644
--- a/libusb/os/linux_usbfs.h
+++ b/libusb/os/linux_usbfs.h
@@ -170,7 +170,7 @@ void linux_netlink_hotplug_poll(void);
#endif
void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name);
-void linux_hotplug_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name);
+void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name);
int linux_get_device_address (struct libusb_context *ctx, int detached,
uint8_t *busnum, uint8_t *devaddr, const char *dev_node,
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 4c3e712..b5a3ca9 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10816
+#define LIBUSB_NANO 10817