From d6cc701c895f26d1c70873f745aae0bd807aa643 Mon Sep 17 00:00:00 2001 From: Xiaoguang Wu Date: Wed, 11 Jul 2018 14:42:23 +0800 Subject: [PATCH] DM USB: refine logic of toggling interface state Refine the logic of usb interface state transition. The libusb uses two pair of APIs to deal with usb interface: 1. libusb_claim_interface & libusb_detach_kernel_driver; 2. libusb_release_interface & libusb_attach_kernel_driver. The calling sequences of those APIs are very important, so this patch add some error handling code to make this process more robust. Change-Id: I0f7950aae806dee9a21f16cc293f51609eede0d8 Tracked-On: Signed-off-by: Xiaoguang Wu Reviewed-by: Liang Yang Acked-by: Yu Wang --- devicemodel/hw/platform/usb_pmapper.c | 30 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/devicemodel/hw/platform/usb_pmapper.c b/devicemodel/hw/platform/usb_pmapper.c index 8b772d6ec..b9416e3f4 100644 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -356,13 +356,21 @@ usb_dev_native_toggle_if(struct usb_dev *udev, int claim) for (i = 0; i < config->bNumInterfaces; i++) { if (claim == 1) r = libusb_claim_interface(udev->handle, i); - else + else { r = libusb_release_interface(udev->handle, i); - + /* according to libusb, if libusb_release_interface + * return LIBUSB_ERROR_NOT_FOUND, it means that this + * interface is not claimed before. This case should + * not be considered as an error here. + */ + if (r == LIBUSB_ERROR_NOT_FOUND) + r = 0; + } if (r) { rc = -1; - UPRINTF(LWRN, "%d-%d:%d.%d can't %s if\r\n", b, p, c, i, - claim == 1 ? "claim" : "release"); + UPRINTF(LWRN, "%d-%d:%d.%d can't %s if, r %d\r\n", b, + p, c, i, claim == 1 ? "claim" : + "release", r); } } if (rc) @@ -393,17 +401,23 @@ usb_dev_native_toggle_if_drivers(struct usb_dev *udev, int attach) return -1; } + UPRINTF(LDBG, "%s driver\r\n", attach == 1 ? "attach" : "detach"); + c = config->bConfigurationValue; for (i = 0; i < config->bNumInterfaces; i++) { if (attach == 1) r = libusb_attach_kernel_driver(udev->handle, i); - else - r = libusb_detach_kernel_driver(udev->handle, i); + else { + if (libusb_kernel_driver_active(udev->handle, i) == 1) + r = libusb_detach_kernel_driver(udev->handle, + i); + } if (r) { rc = -1; - UPRINTF(LWRN, "%d-%d:%d.%d can't %stach if driver\r\n", - b, p, c, i, attach == 1 ? "at" : "de"); + UPRINTF(LWRN, "%d-%d:%d.%d can't %stach if driver, r %d" + "\r\n", b, p, c, i, attach == 1 ? "at" : + "de", r); } } if (rc)