Thread (14 messages) flat view 14 messages, 4 authors, 2021-11-24

Re: I need advice with UPS connection. (ping)

From: David Niklas <hidden>
Date: 2021-11-16 00:11:21
Also in: linux-usb, lkml

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help