I guess nobody else has tried calling uhidev_get_report_async() yet. :) First I was getting a NULL pointer deref in the uhidev async callback. Then I realized that due to USBD_NO_COPY, xfer->buffer was always NULL. Next, I tried to use the DMA buffer, but I ended up in DDB in a very cryptic way. I believe this is because the DMA buffer isn't available when the callback is invoked.
For the async callback to get a valid dmabuf, it needs to be invoked prior to usb_freemem() in usbd_transfer_complete(). The xfer->status determination would need to move up too. I'd do this myself but I don't understand the logic and ordering of pipe->repeat stuff, and am concerned about unintentionally breaking other devices. This is partially my fault, because I "tested" the original diff that added the USBD_NO_COPY semantics to verify that it didn't break my synchronous code paths, but hadn't yet written anything for upd(4) to check the async ones. Thanks. --david