Previously, this driver switched on more verbose messages based on
DIAGNOSTIC. But, the messages weren't about an impossible-to-reach
condition, just extra keys. Change the condition to USBVERBOSE,
documented as serving this purpose.
as "PixArt USB Optical Mouse") that likes to disconnect after 60 seconds
and then reattach 2 seconds later (ad nauseum) unless it's kept open,
so use the "always open" quirk on that device as well.
uhid(4) from attaching and leave it to ugen(4) so libusb can query it.
It is used by some UPS peripherals for their management, especially the
ones from Infosec and Megatec.
Tested with Infosec E3 UPS through ups-nut-usb and `blazer_usb' driver
using the following configuration (ups.conf):
[infosec]
driver = blazer_usb
port = auto
vendorid = 0665
productid = 5161
Make sure the associated /dev/ugenXXX is accessible to `nut' user if you
use ups-nut.
It is used by some UPS devices, notably Infosec and Megatec.
The vendor ID (0x0665) is known differently from various mainstream OSes;
but it is officially registered by USB-IF as `WayTech Development, Inc.'. So
be it.
These assertions were only valid for pipes at UE_IN_DIR, UE_INTERRUPT
endpoints created with usbd_open_pipe_intr, which uses up_intrxfer to
pass the struct usbd_xfer object to usbd_close_pipe to free later.
In contrast, for pipes at UE_OUT_DIR, UE_INTERRUPT endpoints,
up_intrxfer is never initialized, so the assertion cannot be right.
In principle we might even have more than one outstanding interrupt
transfer at a time, rendering the point of the assertion moot anyway.
Found by interrupting a uhidev write to a u2f device.
ok nick
In PR kern/22646 some TDs can be on the done queue when the abort start
and, if this is the case, they need to processed after the WDH interrupt.
Instead of waiting for WDH we release TDs that have been touched by the
HC and replace them with new ones. Once WDH happens the floating TDs
will be returned to the free list.
Also addresses the issue seen in PR kern/55835
Thanks to both Andreas Gustafsson and Edgar Fuß for testing. Apologies to
Andreas Gustafsson for not committing this to HEAD for 4y6m.w
USB xfer callbacks already run in softint context at IPL_SOFTSERIAL,
and I see no reason why the call to psignal must happen instead at
the lower priority of IPL_SOFTCLOCK, so let's avoid using up the
scarce resource of softints for something that doesn't need 'em.
While here, use atomic_store_relaxed to update sc->sc_async and
atomic_load_relaxed to optimisitcally test it without acquiring
proc_lock.
- uhidev API rules:
1. Call uhidev_open when you want exclusive use of a report id.
After it succeeds, you will get interrupts.
2. Call uhidev_close when done with exclusive use of a report id.
After it returns, you will no longer get interrupts.
=> uhidev_open/close do not nest.
3. uhidev_write no longer requires the caller to have exclusive
access -- if there is a write in progress, it will block
interruptibly until done. This way drivers for individual
report ids need not work separately to coordinate their writes.
4. You must uhidev_stop to abort any pending writes on the same
report id. (uhidev_stop no longer does anything else -- to
ensure no more interrupts, just use uhidev_close.)
- Fix uhidev_open/close locking -- uhidev now has an interruptible
config lock held only on first open and last close by any report id
in the device, to serialize the transition between zero and nonzero
numbers of references which requires opening/closing pipes and
allocating/freeing buffers.
- Make /dev/uhidN selnotify(POLLHUP) when the device is yanked.
- Factor uhid device lookup and reference counting and dying
detection and so on into uhid_enter/exit.
- Nix struct uhid_softc::sc_access_lock. This served no purpose but
to confuse me when trying to understand the logic of this beast
(and to ensure uhidev_write exclusion, but it was uninterruptible,
which is wrong for something that implements userland operations,
and didn't actually work because uhidev_write did nothing to
coordinate between different report ids).
- Fix locking in select/poll.
- Use atomics to manage UHID_IMMED to keep it simple. (sc_lock would
be fine too but it makes the code more verbose.)
- Omit needless UHID_ASLP -- cv_broadcast already has this
micro-optimization.
With these changes, my Pinebook survives
for i in `jot 100`; do
echo '###' $i
for j in `jot 16`; do
usbhidctl -rf /dev/uhid$j >/dev/null &
done
wait
done
while plugging and unplugging uhid(4) devices (U2F keys), and the U2F
keys still work as U2F keys.
ok nick, mrg
XXX pullup-9
XXX pullup-8?
Note on ABI and pullups: This changes the layout of struct
uhidev_softc, but with the sole exception of ucycom(4) -- which at
the moment is completely broken and unusable -- the only members that
USB HID drivers use are sc_udev and sc_iface, which haven't changed.
The layout of struct uhidev, which is allocated by each USB HID
driver in its own softc structure, is unchanged.