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)); } }