Skip to content

Commit b4eb355

Browse files
authored
Merge pull request #1575 from jimklimov/issue-1566
Add a `usbhid-ups` driver option to toggle report descriptor fixup activation
2 parents b63b5a2 + 069d8a1 commit b4eb355

File tree

5 files changed

+49
-4
lines changed

5 files changed

+49
-4
lines changed

docs/man/usbhid-ups.txt

+15-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ This driver is known to work on:
4545
- most Linux systems,
4646
- FreeBSD (beta stage) and maybe other *BSD,
4747
- Darwin / Mac OS X,
48-
- Solaris 10.
48+
- Solaris 10 and illumos-based distributions.
4949

5050
EXTRA ARGUMENTS
5151
---------------
@@ -96,6 +96,20 @@ For most devices this combination means calibration or similar maintenance;
9696
however some UPS models (e.g. CyberPower UT series) emit `OL+DISCHRG` when
9797
wall power is lost -- and need this option to handle shutdowns.
9898

99+
*disable_fix_report_desc*::
100+
Set to disable fix-ups for broken USB encoding, etc. which we apply by default
101+
on certain models (vendors/products) which were reported as not following the
102+
protocol strictly. This flag allows to disable the feature in particular device
103+
configurations.
104+
+
105+
It is always possible that the vendors eventually release fixed firmware, or
106+
re-use identifiers by which we match suspected broken devices for unrelated
107+
products, so processing these fix-ups would be a waste of time there.
108+
+
109+
It is also always possible that NUT fix-ups cause issues on some devices,
110+
whether due to NUT bugs or because the vendor protocol implementation is
111+
broken in more than one place.
112+
99113
*vendor*='regex'::
100114
*product*='regex'::
101115
*serial*='regex'::

drivers/apc-hid.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#include "apc-hid.h"
3333
#include "usb-common.h"
3434

35-
#define APC_HID_VERSION "APC HID 0.98"
35+
#define APC_HID_VERSION "APC HID 0.99"
3636

3737
/* APC */
3838
#define APC_VENDORID 0x051d
@@ -534,6 +534,15 @@ static int apc_fix_report_desc(HIDDevice_t *pDev, HIDDesc_t *pDesc_arg) {
534534
return 0;
535535
}
536536

537+
if (disable_fix_report_desc) {
538+
upsdebugx(3,
539+
"NOT Attempting Report Descriptor fix for UPS: "
540+
"Vendor: %04x, Product: %04x "
541+
"(got disable_fix_report_desc in config)",
542+
vendorID, productID);
543+
return 0;
544+
}
545+
537546
upsdebugx(3, "Attempting Report Descriptor fix for UPS: Vendor: %04x, Product: %04x", vendorID, productID);
538547

539548
/* Look at the High Voltage Transfer logical max value:

drivers/cps-hid.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include "cps-hid.h"
3131
#include "usb-common.h"
3232

33-
#define CPS_HID_VERSION "CyberPower HID 0.6"
33+
#define CPS_HID_VERSION "CyberPower HID 0.7"
3434

3535
/* Cyber Power Systems */
3636
#define CPS_VENDORID 0x0764
@@ -286,6 +286,15 @@ static int cps_fix_report_desc(HIDDevice_t *pDev, HIDDesc_t *pDesc_arg) {
286286
return 0;
287287
}
288288

289+
if (disable_fix_report_desc) {
290+
upsdebugx(3,
291+
"NOT Attempting Report Descriptor fix for UPS: "
292+
"Vendor: %04x, Product: %04x "
293+
"(got disable_fix_report_desc in config)",
294+
vendorID, productID);
295+
return 0;
296+
}
297+
289298
upsdebugx(3, "Attempting Report Descriptor fix for UPS: Vendor: %04x, Product: %04x", vendorID, productID);
290299

291300
/* Apply the fix cautiously by looking for input voltage, high voltage transfer and output voltage report usages.

drivers/usbhid-ups.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
*/
2929

3030
#define DRIVER_NAME "Generic HID driver"
31-
#define DRIVER_VERSION "0.48"
31+
#define DRIVER_VERSION "0.49"
3232
#define HU_VAR_WAITBEFORERECONNECT "waitbeforereconnect"
3333

3434
#include "main.h"
@@ -157,6 +157,7 @@ static double interval(void);
157157
/* global variables */
158158
HIDDesc_t *pDesc = NULL; /* parsed Report Descriptor */
159159
reportbuf_t *reportbuf = NULL; /* buffer for most recent reports */
160+
int disable_fix_report_desc = 0; /* by default we apply fix-ups for broken USB encoding, etc. */
160161

161162
/* --------------------------------------------------------------- */
162163
/* Struct & data for boolean processing */
@@ -787,6 +788,9 @@ void upsdrv_makevartable(void)
787788
addvar(VAR_FLAG, "onlinedischarge",
788789
"Set to treat discharging while online as being offline");
789790

791+
addvar(VAR_FLAG, "disable_fix_report_desc",
792+
"Set to disable fix-ups for broken USB encoding, etc. which we apply by default on certain vendors/products");
793+
790794
#ifndef SHUT_MODE
791795
/* allow -x vendor=X, vendorid=X, product=X, productid=X, serial=X */
792796
nut_usb_addvars();
@@ -1071,6 +1075,10 @@ void upsdrv_initups(void)
10711075
onlinedischarge = 1;
10721076
}
10731077

1078+
if (testvar("disable_fix_report_desc")) {
1079+
disable_fix_report_desc = 1;
1080+
}
1081+
10741082
val = getval("interruptsize");
10751083
if (val) {
10761084
int ipv = atoi(val);
@@ -1327,6 +1335,9 @@ int fix_report_desc(HIDDevice_t *arg_pDev, HIDDesc_t *arg_pDesc) {
13271335
NUT_UNUSED_VARIABLE(arg_pDev);
13281336
NUT_UNUSED_VARIABLE(arg_pDesc);
13291337

1338+
/* Implementations should honor the user's toggle:
1339+
* if (disable_fix_report_desc) return 0;
1340+
*/
13301341
return 0;
13311342
}
13321343

drivers/usbhid-ups.h

+2
Original file line numberDiff line numberDiff line change
@@ -217,5 +217,7 @@ int setvar(const char *varname, const char *val);
217217

218218
void possibly_supported(const char *mfr, HIDDevice_t *hd);
219219

220+
/* by default we apply fix-ups for broken USB encoding, etc. */
221+
extern int disable_fix_report_desc;
220222
int fix_report_desc(HIDDevice_t *pDev, HIDDesc_t *arg_pDesc);
221223
#endif /* USBHID_UPS_H */

0 commit comments

Comments
 (0)