Bug 168611

Summary: nut UPS problems with USB ports
Product: [openSUSE] SUSE Linux 10.1 Reporter: Graham Smith <gqs>
Component: BasesystemAssignee: Stanislav Brabec <sbrabec>
Status: RESOLVED FIXED QA Contact: E-mail List <qa-bugs>
Severity: Major    
Priority: P5 - None CC: suse+build, suse-beta
Version: RC 2   
Target Milestone: ---   
Hardware: Other   
OS: SuSE Linux 10.1   
Whiteboard:
Found By: Other Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Attachments: /etc/init.d/upsd
/etc/init.d/upsd

Description Graham Smith 2006-04-22 15:43:44 UTC
I have a Powerware 3105 UPS and am trying to get nut to work with it. The UPS 
communicates via a USB port using the bcmxcp_usb driver.

I am using SuSE 10.0 which comes with nut 2.02 which does not support this UPS so I downloaded nut-2.0.3-13.src.rpm from the 10.1 factory depository and 
compiled it without any problems. 

There is a problem with the port configuration and permissions relating to the USB Bus arrising from the startup script /etc/init.d/upsd.

From lsusb I get the following output
Bus 002 Device 006: ID 0592:0002 Powerware Corp.

If I change the owner of /proc/bus/usb/002/006 to upsd:root I can get the 
bcmxcp_usb driver to load. From the man pages on bcmxcp_usb driver it recommends /etc/ups/ups.conf be set as follows
[pw3105]
      driver = bcmxcp_usb
      port = auto

Now in the startup script /etc/init.d/upsd if you assign 'auto' to the port setting the script will fail as it requires a physical port to be entered so that the program can change ownership of the port. I believe the script will only work with serial ports. USB ports appear to be configured differently.
Comment 1 Stanislav Brabec 2006-04-24 13:05:30 UTC
I know about this problem. But I didn't know about auto keyword, which breaks device permissins in the init script. See the bug 156614 comment #1. We need udev integration for fixing of this problem.
Comment 2 Stanislav Brabec 2006-04-25 15:34:26 UTC
Kay Sievers wrote:

> I guess I need to configure of udev.

That will probably not work that way, cause udev can't tell you what kind of
device it is.

> But I don't know, how to do it,
> because I do not know, how go get the correct DEVNAME
> (/dev/bus/usb/003/012) from udev. Additionally, it is created much later
> than udev sends PRODUCT (51d/2/6).

Yeah, it's a known inconvenience with the current libusb device node access.
You have to wait for it to appear and it's a different event. Only HAL works
around this and until we get the next version of raw usb access, Greg is
working on, we have to work around this.

> Details:
> 
> Not all devices in the list are HID.
> 
> Owner must not be dependend on user logged in (it must be "upsd" in all
> cases).

It's impossible with udev, without matching on vendor/product and create
custom device nodes with that group. The only instance on the system
knowing that it's a UPS is HAL, but HAL does not change device
permissions. So there is currently no way besides matching on
vendor/product and listing all known devices.

Kay
Comment 3 Stanislav Brabec 2006-04-25 17:32:15 UTC
Now setting permissions for all known USB "auto" devices in the init script.
Comment 4 Stanislav Brabec 2006-04-26 10:21:35 UTC
Created attachment 80176 [details]
/etc/init.d/upsd

New init script attached. Could you test it, please?
Comment 5 Stanislav Brabec 2006-04-26 10:27:56 UTC
With my (newhidups) it does exactly what it should do (sets permissions for device you proposed), but the newhidups seems not to work properly here.

I even tried to set owner of /dev/bus/usb/004/001 (which is bad, because the permission is not returned back after unplugging and replugging), but it does not help, too.

[pid  5756] open("/dev/bus/usb/004/003", O_RDWR) = 4
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 4
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 52
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 4
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 74
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 4
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 26
[pid  5756] ioctl(4, USBDEVFS_CLAIMINTERFACE, 0x7fffa019609c) = 0
[pid  5756] ioctl(4, USBDEVFS_SETINTERFACE, 0x7fffa0196090) = 0
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0196090) = 9
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0196090) = -1 EINVAL (Invalid argument)
[pid  5756] close(4)                    = 0
[pid  5756] open("/dev/bus/usb/004/001", O_RDWR) = 4
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 4
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 67
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 4
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 43
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 4
[pid  5756] ioctl(4, USBDEVFS_CONTROL, 0x7fffa0195f40) = 27
[pid  5756] close(4)                    = 0

Accesses to other USB devices returned EACCES, exactly as expected.
Comment 6 Graham Smith 2006-04-26 20:51:07 UTC
I just tried the new init.d script. I'm getting the following error:
root@gq-serv:/etc/init.d>./upsd start
./upsd: invalid /dev/bus/usb/002/008 in /etc/ups/ups.conf            failed

The script identifies the correct USB device.
lsusb
Bus 005 Device 001: ID 0000:0000
Bus 004 Device 002: ID 04b8:0110 Seiko Epson Corp. Perfection 1650
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 008: ID 0592:0002 Powerware Corp.
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000

cat /proc/bus/usb/devices
T:  Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  8 Spd=1.5 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=0592 ProdID=0002 Rev= 0.80
S:  Manufacturer=Powerware
S:  Product=Powerware UPS
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  2mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none)
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=20ms


Now when I check /dev/bus/usb/002/008 I find it is a link. So changing the
owner of this entry will not work.

ll /dev/bus/usb/2
total 0
lrwxrwxrwx  1 root root 18 2006-04-20 16:44 1 -> ../../../usbdev2.1
lrwxrwxrwx  1 root root 18 2006-04-27 06:04 8 -> ../../../usbdev2.8

As can be seen here the actual device is /dev/usbdev2.8
ll /dev/usbd*
crw-rw----  1 root root 189,   0 2006-04-20 16:44 /dev/usbdev1.1
crw-rw----  1 root root 189, 128 2006-04-20 16:44 /dev/usbdev2.1
crw-rw----  1 root root 189, 135 2006-04-27 06:04 /dev/usbdev2.8
crw-rw----  1 root root 189, 256 2006-04-20 16:44 /dev/usbdev3.1
crw-rw----  1 root root 189, 384 2006-04-20 16:44 /dev/usbdev4.1
crw-rw----  1 root root 189, 385 2006-04-20 16:44 /dev/usbdev4.2
crw-rw----  1 root root 189, 512 2006-04-20 16:44 /dev/usbdev5.1

So you are looking at the wrong device entry as far as I can tell you should be looking at the /dev/usbdev2.8

Comment 7 Stanislav Brabec 2006-04-27 11:43:11 UTC
Created attachment 80490 [details]
/etc/init.d/upsd

Another attempt for fix the problem completely:

Thu Apr 27 13:40:30 CEST 2006 - sbrabec@suse.cz

- Work correctly, if port is a symlink (168611#c6).
Comment 8 Graham Smith 2006-04-27 12:50:25 UTC
Just tried the new init.d script. Unfortunately it failed because you have changed the way the usb bus numbers are created. 

Unfortunately I do not understand the syntax of the way you create the port in the following line otherwise I would try and fix it for you.
PORT=$(LANG=C LC_ALL=C lsusb | grep '\(0463:ffff\|0463:0001\|051d:0002\|0592:0002\|09ae:0001\)' | sed 's:^:/dev/bus/usb/:;s/Bus //;s/ Device /\//;s/: .*//')

The above resolves to /dev/bus/usb/002/008
but the path is incorrect as the file is as below
ls -l /dev/bus/usb/2
lrwxrwxrwx  1 root root 18 2006-04-20 16:44 1 -> ../../../usbdev2.1
lrwxrwxrwx  1 root root 18 2006-04-27 06:04 8 -> ../../../usbdev2.8

So the actual link is now  /dev/bus/usb/2/8

 
Comment 9 Stanislav Brabec 2006-04-27 15:26:39 UTC
The syntax is simple: Remove all standard strings from lsusb and keep only reported numbers. On my system, /dev/bus and lsusb report exactly the same, including the leading zeroes and the node was /dev/bus/usb/005/013.

Please note, that on my SuSE Linux 10.1 RC1 x86_64, usbdevfs is not mounted by default.

To Kay Sievers: Can you advice a method, which will return exact device associated with defined ID, which works on any hardware?
Comment 10 Kay Sievers 2006-04-27 15:33:52 UTC
Ick, that's not a default setup. There are no links in /dev/bus/usb, there are real nodes.

Stanislav, what do you mean with "ID" and "association" and "device"?
Comment 11 Stanislav Brabec 2006-04-27 16:12:57 UTC
I have a list of idVendor:idProduct of known USB UPS device.

When starting the upsd, I need to set owner of /dev/bus/usb/x/y nodes created for one of these devices.

On my machine, there are files with file/dir names with leadind zeroes, on Graham Smith's machine there are symlinks with file/names without leading zeroes, but lsusb still reports them with leading zeroes.
Comment 12 Kay Sievers 2006-04-27 16:18:38 UTC
His setup is broken, it's not a correct 10.1 installation. We don't do symlinks here. We always have real nodes with leading zeros.
Comment 13 Kay Sievers 2006-04-27 16:22:47 UTC
Oh, why is the bug against 10.1 when the user mentions a 10.0 system?
Comment 14 Stanislav Brabec 2006-10-26 15:01:57 UTC
It seems, that the solution in 10.1 is not portable to 10.0. Please retry in 10.1 and newer and reopen, if the bug appears again.

WONTFIX for 10.0