On Mon, 15 Nov 2021 11:09:18 -0500
stern@rowland.harvard.edu wrote:
On Sun, Nov 14, 2021 at 10:02:22PM -0500, David Niklas wrote:
quoted
<snip>
Has this device ever worked with any version of Linux?
I am unaware of this device working on any version of Linux. I assumed
when I bought it that it would a least be able to connect to the USB port
correctly. I might then have to make a contribution to add support for it
to nut or apcupsd.
<snip>
The kernel sends a Set-Idle request to the device, telling it not to
send any data reports when nothing has changed. This is done
automatically by the usbhid driver for every USB HID device, including
keyboards and mice as well as your UPS.
ffff93eaa3edad80 2136086737 S Ci:3:009:0 s 81 06 2200 0000 03e4 996 <
ffff93eaa3edad80 2136122734 C Ci:3:009:0 0 996 = 05840904 a1010924
a1028501 09fe7901 75089501 150026ff 00b12285 0209ff79
The kernel reads the device's HID descriptor. (The usbmon trace shows
only the first 32 bytes of the 996-byte descriptor.) Again, this is
normal and necessary for using any HID device.
ffff93e482efb440 2139520170 C Ii:3:001:1 0:2048 1 = 08
ffff93e482efb440 2139520180 S Ii:3:001:1 -115:2048 4 <
At this point the USB controller tells the kernel that there has been a
status change on port 3 of bus 3.
ffff93eaa2ff8240 2139520188 S Ci:3:001:0 s a3 00 0000 0003 0004 4 <
ffff93eaa2ff8240 2139520197 C Ci:3:001:0 0 4 = 00010100
The kernel reads the port's status and sees that there is a "connection
status change" bit set and the port is no longer connected. In other
words, the UPS device has disconnected itself electronically from the
USB bus.
ffff93eaa2ff8240 2139520200 S Co:3:001:0 s 23 01 0010 0003 0000 0
ffff93eaa2ff8240 2139520203 C Co:3:001:0 0 0
The kernel clears the "connection status change" flag. Following this
the cycle repeats.
Out of all this information, the only conclusion I can draw is that the
UPS is not behaving like a normal device. One possibility is that it
doesn't like the Set-Idle request (although if that is the case, why
did it remain connected long enough to send the HID descriptor?).
Thanks for the detailed breakdown!
You can test the theory by patching the kernel, if you want. The code
to change is in the source file drivers/hid/usbhid/hid-core.c, and the
function in question is hid_set_idle() located around line 659 in the
file. Just change the statement:
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
(idle << 8) | report, ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
to:
return 0;
to prevent the Set-Idle request from being sent. If the device still
insists on disconnecting then we'll know that this wasn't the reason.
Will do tomorrow. (I'm busy ATM)
Also, if you have another system (say, one running Windows) which the
UPS does work properly with, you could try collecting the equivalent of
a usbmon trace from that system for purposes of comparison. (On
Windows, I believe you can use Wireshark to trace USB communications.)
Alan Stern
I'll have to look into that.
Thanks again!
David