USB quirks and NUT
-
Notes on USB quirks
If you are using a locally attached USB UPS, and the driver fails to start, it is likely that there is no USB quirk in FreeBSD for your UPS. You can test this by adding
user=root
to the Extra Arguments to driver section. If this allows the NUT driver to start, this means that there is no quirk for your UPS.
Please do not stop here. Help the world.
You can address this by developing quirk for your UPS, and then you can help others that by submitting the quirk for inclusion in FreeBSD.
The basic format of a quirk for a UPS looks like this:
0x051d 0x0002 0x0000 0xffff UQ_HID_IGNORE
Where
0x051d
is the Vendor ID0x0002
is the Product ID0x0000
is the LowRevision0xffff
is the HighRevisionUQ_HID_IGNORE
is the USB quirk (ignore)
This quirk tells the operating system to ignore (not attach a driver) to that particular type of USB device when it is connected to the system. By default, if there is no quirk saying to ignore a device, the kernel will attach a default driver to the device. It requires root privileges to replace the default driver which prevents NUT from being able to access the device unless it is running as root. This is why we need to create a quirk to allow NUT to run without root privilege.
To create a new quirk, we need to determine what the appropriate Vendor and Product IDs will be. The following command will dump USB information for your system:
usbconfig -v
This command can generate quite a bit of output. We are looking for a section that looks like this:
ugen0.2: <American Power Conversion Smart-UPS1000 FW:UPS 16.1 / ID1047> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (10mA) bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0200 bDeviceClass = 0x0000 <Probed by interface class> bDeviceSubClass = 0x0000 bDeviceProtocol = 0x0000 bMaxPacketSize0 = 0x0040 idVendor = 0x051d idProduct = 0x0003 bcdDevice = 0x0001 iManufacturer = 0x0001 <American Power Conversion > iProduct = 0x0002 <Smart-UPS_1000 FW:UPS 16.1 / ID=1047> iSerialNumber = 0x0003 <ASXXXXXXXXX > bNumConfigurations = 0x0001
The fields we are interested in are 'idVendor' and 'idProduct'. These fields equate to Vendor ID and Product ID as shown in the quirk format above.
Notice that in the usbconfig output the idVendor field matches the ID in quirk above, but the idProduct field does not match. This is because the vendor introduced a new generation of UPS systems and updated the Product ID. To address this, we need to create a new quirk.
The quirk we want to create looks like this:
0x051d 0x0003 0x0000 0xffff UQ_HID_IGNORE
[Note: We are only interested in the Vendor ID and Product ID fields. The other fields will always be the same.]
Now that we have our quirk, we can test it by adding it to the system with the following command:
usbconfig add_dev_quirk_vplh 0x051d 0x0003 0x0000 0xffff UQ_HID_IGNORE
Following that, disconnect and reconnect the USB cable to the UPS and try to start NUT. If the NUT USB driver starts, you've got your quirk.
Adding the quirk via the usbconfig command is temporary, and does not survive a reboot. To permanently add the quirk, we need to add an entry to /boot/loader.conf.local that looks like this:
hw.usb.quirk.0="0x051d 0x0003 0x0000 0xffff UQ_HID_IGNORE"
Note that the number following 'hw.usb.quirk' must be unique, so in the unlikely event you need to add multiple quirks in /boot/loader.conf.local, it would look like this:
hw.usb.quirk.0="0x051d 0x0002 0x0000 0xffff UQ_HID_IGNORE" hw.usb.quirk.1="0x051d 0x0003 0x0000 0xffff UQ_HID_IGNORE"
If you develop a new quirk, please let the world know. Either post about it here, or submit it directly to FreeBSD.
Additional information:
Detailed information regarding quirks can be found here.
Full documentation on usbconfig can be found here.
You can see the attached kernel driver with the following command:
usbconfig -d ugen0.2 show_ifdrv
which will product output like so:
ugen0.2: <American Power Conversion Smart-UPS1000 FW:UPS 16.0 / ID1047> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (10mA) ugen0.2.0: uhid0: <American Power Conversion Smart-UPS1000 FW:UPS 16.0 / ID1047, class 0/0, rev 2.00/0.01, addr 4>
The second line indicates that there is an attached kernel driver (uhid0).
You can detach the kernel driver with the following command:
usbconfig -d ugen0.2 detach_kernel_driver
After detaching the driver, or if you have an installed quirk, show_ifdrv will just have the first line:
ugen0.2: <American Power Conversion Smart-UPS1000 FW:UPS 16.0 / ID1047> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (10mA)
You can see all the relevant quirks in your system with the following command:
usbconfig dump_device_quirks | grep HID_IGNORE
The quirks discussed above will show up like so:
VID=0x051d PID=0x0002 REVLO=0x0000 REVHI=0xffff QUIRK=UQ_HID_IGNORE VID=0x051d PID=0x0003 REVLO=0x0000 REVHI=0xffff QUIRK=UQ_HID_IGNORE
-
I developed a quirk for the Tripp Lite SU1000RTXLCD2U. It uses the usbhid-ups driver.
I executed the following commands from the pfSense Diagnostics > Command Prompt menu
loader.conf.local didn't exist yet...
touch /boot/loader.conf.local
add this line to it:
echo "hw.usb.quirk.0=\"0x09ae 0x4004 0x0000 0xffff UQ_HID_IGNORE\"" >> /boot/loader.conf.local
Diagnostics > Reboot
After reboot...
usbconfig dump_device_quirks | grep HID_IGNORE
outputs on the last line of numerous other quirks:
VID=0x09ae PID=0x4004 REVLO=0x0000 REVHI=0xffff QUIRK=UQ_HID_IGNORE
ls -l /boot/loader.conf.local
outputs:
-rw-r--r-- 1 root wheel 59 Apr 20 00:37 /boot/loader.conf.local
Because I'm never logged into pfSense as root, are the above permissions incorrect for /boot/loader.conf.local?
Should I remove user=root from the Additional configuration lines for ups.conf now that I added the quirk?
Is it best practice to have the UPS plugged into USB bus 0? I had it plugged into bus 1 for years, but recent lost connections with the UPS after upgrading to pfSense 2.7 prompted me to make these changes in hopes of reliability.
Also:
usbconfig -d ugen1.3 show_ifdrv
outputs just 1 line (which I think is correct behavior):
ugen1.3: <TRIPPLITE TRIPPLITE UPS> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (50mA)
-
@serengeti said in NUT Package (2.8.1 and above):
I developed a quirk for the Tripp Lite SU1000RTXLCD2U. It uses the usbhid-ups driver.
Awesome job!
-
-
-
-
-
@dennypage thank you so much for this info. I've struggled to connect my various pfSense appliances to UPS's for quite some time.
I also read this reddit page to find a bit more info on testing the USB connected UPS.
After seeing my pfSense show ALL the information available from the APC UPS, I followed this AWESOME post to create a Quirk, test (disconnect / reconnect the USB cable) and add the Quirk to the /boot/loader.conf.local
I've just rebooted my pfSense appliance and am very happy to see Service --> NUT --> Status with a UPS and all its details.
-
@Josho_SAI said in USB quirks and NUT:
@dennypage thank you so much for this info.
You are most welcome.