From 339d24c8235476ceee43f7d704415ccab85e2583 Mon Sep 17 00:00:00 2001 From: Nathan Hjelm Date: Fri, 9 Jul 2021 09:17:33 -0600 Subject: [PATCH] darwin: improve support for auto-detaching a kernel driver This commit improves the code around auto attach/detach of a kernel driver: - Log a warning when a driver can not be auto-detached and continue when claiming an interface. It could be the case that the interface has no driver attached or that the claim will still succeed. - Log a warning if the driver can not be auto-attached and return success when releasing an interface. The operation did complete successfully but the re-enumeration may have failed. This can be discovered on the next device access. Signed-off-by: Nathan Hjelm --- libusb/os/darwin_usb.c | 48 ++++++++++++++++++++++++++++-------------- libusb/version_nano.h | 2 +- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index 5faf18a..d763c9d 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -2372,19 +2372,26 @@ static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, } if (dpriv->capture_count == 0) { + usbi_dbg ("attempting to detach kernel driver from device"); + + if (!darwin_has_capture_entitlements ()) { + usbi_warn (HANDLE_CTX (dev_handle), "no capture entitlements. can not detach the kernel driver for this device"); + return LIBUSB_ERROR_NOT_SUPPORTED; + } + /* request authorization */ - if (darwin_has_capture_entitlements ()) { - kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed); - if (kresult != kIOReturnSuccess) { - usbi_err (HANDLE_CTX (dev_handle), "IOServiceAuthorize: %s", darwin_error_str(kresult)); - return darwin_to_libusb (kresult); - } - /* we need start() to be called again for authorization status to refresh */ - err = darwin_reload_device (dev_handle); - if (err != LIBUSB_SUCCESS) { - return err; - } + kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed); + if (kresult != kIOReturnSuccess) { + usbi_err (HANDLE_CTX (dev_handle), "IOServiceAuthorize: %s", darwin_error_str(kresult)); + return darwin_to_libusb (kresult); } + + /* we need start() to be called again for authorization status to refresh */ + err = darwin_reload_device (dev_handle); + if (err != LIBUSB_SUCCESS) { + return err; + } + /* reset device to release existing drivers */ err = darwin_reenumerate_device (dev_handle, true); if (err != LIBUSB_SUCCESS) { @@ -2408,9 +2415,10 @@ static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, dpriv->capture_count--; if (dpriv->capture_count > 0) { return LIBUSB_SUCCESS; - } else { - dpriv->capture_count = 0; } + + usbi_dbg ("reenumerating device for kernel driver attach"); + /* reset device to attach kernel drivers */ return darwin_reenumerate_device (dev_handle, false); } @@ -2420,23 +2428,31 @@ static int darwin_capture_claim_interface(struct libusb_device_handle *dev_handl if (dev_handle->auto_detach_kernel_driver) { ret = darwin_detach_kernel_driver (dev_handle, iface); if (ret != LIBUSB_SUCCESS) { - return ret; + usbi_warn (HANDLE_CTX (dev_handle), "failed to auto-detach the kernel driver for this device, ret=%d", ret); } } + return darwin_claim_interface (dev_handle, iface); } static int darwin_capture_release_interface(struct libusb_device_handle *dev_handle, uint8_t iface) { enum libusb_error ret; + struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); ret = darwin_release_interface (dev_handle, iface); if (ret != LIBUSB_SUCCESS) { return ret; } - if (dev_handle->auto_detach_kernel_driver) { + + if (dev_handle->auto_detach_kernel_driver && dpriv->capture_count > 0) { ret = darwin_attach_kernel_driver (dev_handle, iface); + if (LIBUSB_SUCCESS != ret) { + usbi_warn (HANDLE_CTX (dev_handle), "on attempt to reattach the kernel driver got ret=%d", ret); + } + /* ignore the error as the interface was successfully released */ } - return ret; + + return LIBUSB_SUCCESS; } #endif diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 9064596..6b45e58 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11635 +#define LIBUSB_NANO 11636 -- 2.34.1