diff options
-rw-r--r-- | libusb/os/linux_netlink.c | 2 | ||||
-rw-r--r-- | libusb/os/linux_udev.c | 2 | ||||
-rw-r--r-- | libusb/os/linux_usbfs.c | 23 | ||||
-rw-r--r-- | libusb/os/linux_usbfs.h | 2 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
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 |