From 057ee7771b151d0c11739a0db4a47547e08494ec Mon Sep 17 00:00:00 2001 From: Matt Merhar Date: Sun, 10 Dec 2023 00:59:58 -0500 Subject: [PATCH] drivers/libusb1.c: reset driver parameters while enumerating With an Arduino Leonardo compatible board attached alongside a CyberPower CP1500PFCLCD, usbhid-ups would incorrectly conclude that there was no kernel driver attached to the UPS and then fail subsequent steps accordingly. The cause is the global usb_communication_subdriver_t struct; when a subdriver (e.g. arduino-hid) sets different values during the enumeration loop, they're not set back to defaults afterwards, causing issues with other subdrivers (e.g. cps-hid). So, if a subdriver doesn't match, set a selection of fields back to their default values using the newly added nut_usb_subdriver_defaults() before the next attempt. Signed-off-by: Matt Merhar --- NEWS.adoc | 5 +++++ drivers/libusb1.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index cd67bfce9c..4927b8dcdf 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -147,6 +147,11 @@ https://github.com/networkupstools/nut/milestone/11 by default: `powercom_sdcmd_byte_order_fallback`. [PR #2480] * `cps-hid` subdriver now supports more variables, as available on e.g. CP1350EPFCLCD model. [PR #2540] + * USB parameters (per `usb_communication_subdriver_t`) are now set back to + their default values during enumeration after probing each subdriver. + Having an unrelated device connected with a VID:PID matching the + `arduino-hid` subdriver prevented use of an actual `usb-hid` device due to + changes made to this struct during probe. [#2611] - bicker_ser: added new driver for Bicker 12/24Vdc UPS via RS-232 serial communication protocol, which supports any UPS shipped with the PSZ-1053 diff --git a/drivers/libusb1.c b/drivers/libusb1.c index 2f325f30f1..a75815f732 100644 --- a/drivers/libusb1.c +++ b/drivers/libusb1.c @@ -153,6 +153,20 @@ static int nut_usb_set_altinterface(libusb_device_handle *udev) return ret; } +static void nut_usb_subdriver_defaults(usb_communication_subdriver_t *subdriver) +{ + if (!getval("usb_config_index")) + subdriver->usb_config_index = LIBUSB_DEFAULT_CONF_INDEX; + if (!getval("usb_hid_rep_index")) + subdriver->hid_rep_index = LIBUSB_DEFAULT_INTERFACE; + if (!getval("usb_hid_desc_index")) + subdriver->hid_desc_index = LIBUSB_DEFAULT_DESC_INDEX; + if (!getval("usb_hid_ep_in")) + subdriver->hid_ep_in = LIBUSB_DEFAULT_HID_EP_IN; + if (!getval("usb_hid_ep_out")) + subdriver->hid_ep_out = LIBUSB_DEFAULT_HID_EP_OUT; +} + /* On success, fill in the curDevice structure and return the report * descriptor length. On failure, return -1. * Note: When callback is not NULL, the report descriptor will be @@ -870,6 +884,8 @@ static int nut_libusb_open(libusb_device_handle **udevp, /* if (if_claimed) libusb_release_interface(udev, usb_subdriver.hid_rep_index); */ libusb_close(udev); + /* reset any parameters modified by unmatched drivers back to defaults */ + nut_usb_subdriver_defaults(&usb_subdriver); } *udevp = NULL;