On Dec 4, 2014, at 4:30 PM, David Higgs <hig...@gmail.com> wrote:

> 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?

Below is an updated diff against -current, and dmesg when applied to -stable 
(no change).  On my non-virtual hardware, upd(4) connects via ohci(4), which 
didn’t report USBD_SHORT_XFER.  Also, I fixed a format string warning when 
UPD_DEBUG was enabled.

Please let me know if my diffs are still being mangled, so I can resend as 
attachments and keep searching for a solution.

Feedback is welcome.

--david

####

OpenBSD 5.6-stable (GENERIC) #8: Fri Dec  5 13:25:33 EST 2014
    vm@vm.localdomain:/home/vm/src/sys/arch/i386/compile/GENERIC
cpu0: Geode(TM) Integrated Processor by AMD PCS ("AuthenticAMD" 586-class) 499 
MHz
cpu0: FPU,DE,PSE,TSC,MSR,CX8,SEP,PGE,CMOV,CFLUSH,MMX,MMXX,3DNOW2,3DNOW
real mem  = 267943936 (255MB)
avail mem = 251113472 (239MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: AT/286+ BIOS, date 11/05/08, BIOS32 rev. 0 @ 0xfd088
pcibios0 at bios0: rev 2.1 @ 0xf0000/0x10000
pcibios0: pcibios_get_intr_routing - function not supported
pcibios0: PCI IRQ Routing information unavailable.
pcibios0: PCI bus #0 is the last bus
bios0: ROM list: 0xe0000/0xa800
cpu0 at mainbus0: (uniprocessor)
mtrr: K6-family MTRR support (2 registers)
pci0 at mainbus0 bus 0: configuration mode 1 (bios)
pchb0 at pci0 dev 1 function 0 "AMD Geode LX" rev 0x33
glxsb0 at pci0 dev 1 function 2 "AMD Geode LX Crypto" rev 0x00: RNG AES
vr0 at pci0 dev 9 function 0 "VIA VT6105M RhineIII" rev 0x96: irq 10, address 
00:0d:b9:1e:60:7c
ukphy0 at vr0 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x004063, 
model 0x0034
vr1 at pci0 dev 10 function 0 "VIA VT6105M RhineIII" rev 0x96: irq 11, address 
00:0d:b9:1e:60:7d
ukphy1 at vr1 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x004063, 
model 0x0034
vr2 at pci0 dev 11 function 0 "VIA VT6105M RhineIII" rev 0x96: irq 15, address 
00:0d:b9:1e:60:7e
ukphy2 at vr2 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x004063, 
model 0x0034
glxpcib0 at pci0 dev 15 function 0 "AMD CS5536 ISA" rev 0x03: rev 3, 32-bit 
3579545Hz timer, watchdog, gpio, i2c
gpio0 at glxpcib0: 32 pins
iic0 at glxpcib0
maxtmp0 at iic0 addr 0x4c: lm86
pciide0 at pci0 dev 15 function 2 "AMD CS5536 IDE" rev 0x01: DMA, channel 0 
wired to compatibility, channel 1 wired to compatibility
wd0 at pciide0 channel 0 drive 0: <TS16GCF133>
wd0: 1-sector PIO, LBA, 15296MB, 31326208 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2
pciide0: channel 1 ignored (disabled)
ohci0 at pci0 dev 15 function 4 "AMD CS5536 USB" rev 0x02: irq 12, version 1.0, 
legacy support
ehci0 at pci0 dev 15 function 5 "AMD CS5536 USB" rev 0x02: irq 12
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 "AMD EHCI root hub" rev 2.00/1.00 addr 1
isa0 at glxpcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
com0: console
com1 at isa0 port 0x2f8/8 irq 3: ns16550a, 16 byte fifo
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
usb1 at ohci0: USB revision 1.0
uhub1 at usb1 "AMD OHCI root hub" rev 1.00/1.00 addr 1
nvram: invalid checksum
uhidev0 at uhub1 port 2 configuration 1 interface 0 "American Power Conversion 
Back-UPS ES 750 FW:841.I3 .D USB FW:I3" rev 1.10/1.01 addr 2
uhidev0: iclass 3/0, 146 report ids
upd0 at uhidev0
vscsi0 at root
scsibus1 at vscsi0: 256 targets
softraid0 at root
scsibus2 at softraid0: 256 targets
root on wd0a (295fd65258ac0a48.a) swap on wd0b dump on wd0b
clock: unknown CMOS layout


Index: ohci.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ohci.c,v
retrieving revision 1.140
diff -u -p -r1.140 ohci.c
--- ohci.c      5 Oct 2014 08:40:29 -0000       1.140
+++ ohci.c      5 Dec 2014 18:45:40 -0000
@@ -1311,6 +1311,8 @@ ohci_softintr(void *v)
 
                        if (cc == OHCI_CC_STALL)
                                xfer->status = USBD_STALLED;
+                       else if (cc == OHCI_CC_DATA_UNDERRUN)
+                               xfer->status = USBD_SHORT_XFER;
                        else
                                xfer->status = USBD_IOERROR;
                        s = splusb();
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       5 Dec 2014 18:45:40 -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;
                }
 
@@ -364,7 +368,7 @@ upd_update_sensors(struct upd_softc *sc,
                sensor->ksensor.value = hdata * adjust;
                sensor->ksensor.status = SENSOR_S_OK;
                sensor->ksensor.flags &= ~SENSOR_FINVALID;
-               DPRINTF(("%s: hidget data: %d\n",
+               DPRINTF(("%s: hidget data: %ld\n",
                    sc->sc_sensordev.xname, hdata));
        }
 }


Reply via email to