I am trying to figure out how to handle the buggy USB firmware in my UPS (see 
misc@ thread from last week).  With some kernel debug enabled, I see 
"usb_transfer_complete: short transfer 3<5" messages.  Since the BatteryPresent 
sensor could not be read, all battery-related sensors were forced into UNKNOWN 
state.

It appears that apcupsd adjusts the expected HID report length as soon as a 
bogus request is detected:
http://sourceforge.net/p/apcupsd/svn/2273/tree/branches/Branch-3_14/src/drivers/usb/generic/generic-usb.c#l254

The patch below handles my particular case but is probably too generic/sloppy.  
Is there any interest in workarounds, either like this or something less 
terrible?

Thanks.

--david

OpenBSD 5.6-current (GENERIC) #0: Thu Dec  4 16:24:54 EST 2014
    vm@vm.localdomain:/home/vm/src/sys/arch/i386/compile/GENERIC
cpu0: Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz ("GenuineIntel" 686-class) 
2.40 GHz
cpu0: 
FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,NXE,LONG,SSE3,SSSE3,CX16,LAHF,PERF,ITSC
real mem  = 267866112 (255MB)
avail mem = 251166720 (239MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: AT/286+ BIOS, date 09/20/12, BIOS32 rev. 0 @ 0xfd780, SMBIOS 
rev. 2.4 @ 0xe0010 (364 entries)
bios0: vendor Phoenix Technologies LTD version "6.00" date 09/20/2012
bios0: VMware, Inc. VMware Virtual Platform
acpi0 at bios0: rev 2
acpi0: sleep states S0 S1 S4 S5
acpi0: tables DSDT FACP BOOT APIC MCFG SRAT HPET WAET
acpi0: wakeup devices PCI0(S3) USB_(S1) P2P0(S3) S1F0(S3) S2F0(S3) S3F0(S3) 
S4F0(S3) S5F0(S3) S6F0(S3) S7F0(S3) S8F0(S3) S9F0(S3) Z00Q(S3) Z00R(S3) 
Z00S(S3) Z00T(S3) [...]
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 65MHz
ioapic0 at mainbus0: apid 1 pa 0xfec00000, version 11, 24 pins
acpimcfg0 at acpi0 addr 0xe0000000, bus 0-255
acpihpet0 at acpi0: 14318179 Hz
acpiprt0 at acpi0: bus 0 (PCI0)
acpicpu0 at acpi0
acpibat0 at acpi0: BAT1 not present
acpibat1 at acpi0: BAT2 not present
acpiac0 at acpi0: AC unit online
acpibtn0 at acpi0: SLPB
acpibtn1 at acpi0: LID_
bios0: ROM list: 0xc0000/0x8000 0xc8000/0x1000 0xdc000/0x4000! 0xe0000/0x8000!
vmt0 at mainbus0
pci0 at mainbus0 bus 0: configuration mode 1 (bios)
pchb0 at pci0 dev 0 function 0 "Intel 82443BX AGP" rev 0x01
ppb0 at pci0 dev 1 function 0 "Intel 82443BX AGP" rev 0x01
pci1 at ppb0 bus 1
piixpcib0 at pci0 dev 7 function 0 "Intel 82371AB PIIX4 ISA" rev 0x08
pciide0 at pci0 dev 7 function 1 "Intel 82371AB IDE" rev 0x01: DMA, channel 0 
configured to compatibility, channel 1 configured to compatibility
wd0 at pciide0 channel 0 drive 0: <VMware Virtual IDE Hard Drive>
wd0: 64-sector PIO, LBA, 8192MB, 16777216 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2
pciide0: channel 1 disabled (no drives)
piixpm0 at pci0 dev 7 function 3 "Intel 82371AB Power" rev 0x08: SMBus disabled
"VMware VMCI" rev 0x10 at pci0 dev 7 function 7 not configured
vga1 at pci0 dev 15 function 0 "VMware SVGA II" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
ppb1 at pci0 dev 17 function 0 "VMware PCI" rev 0x02
pci2 at ppb1 bus 2
vic0 at pci2 dev 0 function 0 "AMD 79c970 PCnet-PCI" rev 0x10: apic 1 int 18, 
address 00:0c:29:23:6c:31
uhci0 at pci2 dev 2 function 0 "VMware UHCI" rev 0x00: apic 1 int 16
ehci0 at pci2 dev 3 function 0 "VMware EHCI" rev 0x00: apic 1 int 17
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 "VMware EHCI root hub" rev 2.00/1.00 addr 1
usb1 at uhci0: USB revision 1.0
uhub1 at usb1 "VMware UHCI root hub" rev 1.00/1.00 addr 1
ppb2 at pci0 dev 21 function 0 "VMware PCIE" rev 0x01
pci3 at ppb2 bus 3
ppb3 at pci0 dev 21 function 1 "VMware PCIE" rev 0x01
pci4 at ppb3 bus 4
ppb4 at pci0 dev 21 function 2 "VMware PCIE" rev 0x01
pci5 at ppb4 bus 5
ppb5 at pci0 dev 21 function 3 "VMware PCIE" rev 0x01
pci6 at ppb5 bus 6
ppb6 at pci0 dev 21 function 4 "VMware PCIE" rev 0x01
pci7 at ppb6 bus 7
ppb7 at pci0 dev 21 function 5 "VMware PCIE" rev 0x01
pci8 at ppb7 bus 8
ppb8 at pci0 dev 21 function 6 "VMware PCIE" rev 0x01
pci9 at ppb8 bus 9
ppb9 at pci0 dev 21 function 7 "VMware PCIE" rev 0x01
pci10 at ppb9 bus 10
ppb10 at pci0 dev 22 function 0 "VMware PCIE" rev 0x01
pci11 at ppb10 bus 11
ppb11 at pci0 dev 22 function 1 "VMware PCIE" rev 0x01
pci12 at ppb11 bus 12
ppb12 at pci0 dev 22 function 2 "VMware PCIE" rev 0x01
pci13 at ppb12 bus 13
ppb13 at pci0 dev 22 function 3 "VMware PCIE" rev 0x01
pci14 at ppb13 bus 14
ppb14 at pci0 dev 22 function 4 "VMware PCIE" rev 0x01
pci15 at ppb14 bus 15
ppb15 at pci0 dev 22 function 5 "VMware PCIE" rev 0x01
pci16 at ppb15 bus 16
ppb16 at pci0 dev 22 function 6 "VMware PCIE" rev 0x01
pci17 at ppb16 bus 17
ppb17 at pci0 dev 22 function 7 "VMware PCIE" rev 0x01
pci18 at ppb17 bus 18
ppb18 at pci0 dev 23 function 0 "VMware PCIE" rev 0x01
pci19 at ppb18 bus 19
ppb19 at pci0 dev 23 function 1 "VMware PCIE" rev 0x01
pci20 at ppb19 bus 20
ppb20 at pci0 dev 23 function 2 "VMware PCIE" rev 0x01
pci21 at ppb20 bus 21
ppb21 at pci0 dev 23 function 3 "VMware PCIE" rev 0x01
pci22 at ppb21 bus 22
ppb22 at pci0 dev 23 function 4 "VMware PCIE" rev 0x01
pci23 at ppb22 bus 23
ppb23 at pci0 dev 23 function 5 "VMware PCIE" rev 0x01
pci24 at ppb23 bus 24
ppb24 at pci0 dev 23 function 6 "VMware PCIE" rev 0x01
pci25 at ppb24 bus 25
ppb25 at pci0 dev 23 function 7 "VMware PCIE" rev 0x01
pci26 at ppb25 bus 26
ppb26 at pci0 dev 24 function 0 "VMware PCIE" rev 0x01
pci27 at ppb26 bus 27
ppb27 at pci0 dev 24 function 1 "VMware PCIE" rev 0x01
pci28 at ppb27 bus 28
ppb28 at pci0 dev 24 function 2 "VMware PCIE" rev 0x01
pci29 at ppb28 bus 29
ppb29 at pci0 dev 24 function 3 "VMware PCIE" rev 0x01
pci30 at ppb29 bus 30
ppb30 at pci0 dev 24 function 4 "VMware PCIE" rev 0x01
pci31 at ppb30 bus 31
ppb31 at pci0 dev 24 function 5 "VMware PCIE" rev 0x01
pci32 at ppb31 bus 32
ppb32 at pci0 dev 24 function 6 "VMware PCIE" rev 0x01
pci33 at ppb32 bus 33
ppb33 at pci0 dev 24 function 7 "VMware PCIE" rev 0x01
pci34 at ppb33 bus 34
isa0 at piixpcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
com1 at isa0 port 0x2f8/8 irq 3: ns16550a, 16 byte fifo
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
lpt0 at isa0 port 0x378/4 irq 7
npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
uhidev0 at uhub1 port 1 configuration 1 interface 0 "VMware VMware Virtual USB 
Mouse" rev 1.10/1.02 addr 2
uhidev0: iclass 3/0
ums0 at uhidev0: 16 buttons, Z dir
wsmouse1 at ums0 mux 0
uhidev1 at uhub1 port 1 configuration 1 interface 1 "VMware VMware Virtual USB 
Mouse" rev 1.10/1.02 addr 2
uhidev1: iclass 3/0
ums1 at uhidev1: 16 buttons, Z dir
wsmouse2 at ums1 mux 0
uhub2 at uhub1 port 2 "VMware VMware Virtual USB Hub" rev 1.10/1.00 addr 3
uhidev2 at uhub2 port 1 configuration 1 interface 0 "American Power Conversion 
Back-UPS ES 750 FW:841.I3 .D USB FW:I3" rev 1.10/1.01 addr 4
uhidev2: iclass 3/0, 146 report ids
upd0 at uhidev2
vscsi0 at root
scsibus1 at vscsi0: 256 targets
softraid0 at root
scsibus2 at softraid0: 256 targets
root on wd0a (cbb10cf24115d20e.a) swap on wd0b dump on wd0b


[vm@vm ~]$ # before
[vm@vm ~]$ sysctl hw.sensors.upd0
hw.sensors.upd0.indicator3=Off (ShutdownImminent), OK

[vm@vm ~]$ # after
[vm@vm ~]$ sysctl hw.sensors.upd0
hw.sensors.upd0.indicator0=Off (Charging), OK
hw.sensors.upd0.indicator1=Off (Discharging), OK
hw.sensors.upd0.indicator2=On (ACPresent), OK
hw.sensors.upd0.indicator3=Off (ShutdownImminent), OK
hw.sensors.upd0.indicator4=On (BatteryPresent), OK
hw.sensors.upd0.percent0=100.00% (RemainingCapacity), OK
hw.sensors.upd0.percent1=100.00% (FullChargeCapacity), OK

Index: upd.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/upd.c,v
retrieving revision 1.10
diff -u -p -r1.10 upd.c
--- upd.c       12 Jul 2014 18:48:52 -0000      1.10
+++ upd.c       4 Dec 2014 21:08:46 -0000
@@ -280,6 +280,10 @@ upd_refresh(void *arg)
                if (err) {
                        DPRINTF(("read failure: reportid=%02x err=%d\n", repid,
                            err));
+
+                       /* XXX attempt to work around broken firmware */
+                       if (err == USBD_SHORT_XFER)
+                               report->size /= 2;
                        continue;
                }

Reply via email to