# DF-5476 — ubsa(4) cfg callbacks chain synchronous 1000 ms-timeout EP0 vendor requests with discarded errors: an evil Belkin/eTek/GoHubs/Peracom adapter stretches every tcsetattr to 5.1 s (7.1 s for B0) and the first-open line-state cycle to 3.0 s of uninterruptible ucom-taskqueue occupancy, blocking close(2) SIGKILL-immune behind it (measured 9.97 s with one queued B0 tcsetattr) and stalling the USB hub event thread on unplug (user-amplifiable)

Production file: `sys/bus/u4b/serial/ubsa.c`. Evidence class:
**KLD-harness-with-production-code** (no Belkin F5U103/eTek/GoHubs/Peracom
USB device model on the QEMU guest; same rig family as DF-5425 uslcom /
DF-5424 uftdi / DF-5449 uvscom / DF-5456 umoscom).

## What the harness is

`ub5476stall_harness.c` drives the REAL in-kernel u4b `usb_process`
machinery (`usb_proc_create`/`msignal`/`mwait`/`drain`) — the same
taskqueue ucom's cfg callbacks run on — with ubsa's exact production
request counts, the production first-open queueing order **including the
LL_READY gate** (see below), and the production 1000 ms per-request
timeout. Each "request" is one `lksleep("WXFER", 1000ms)` on a unique
per-request wait channel — the exact production cost of an EP0
data/status stage an evil device never answers (usb_request.c:643,
:700-704).

## Pass-2 accounting precision (LL_READY gate)

The first-open `cfg_param` task is queued at `usb_serial.c:842` BEFORE
`ucom_cfg_open` (`:865`) and `ucom_cfg_param` bails at `:1626-1628`
unless `UCOM_FLAG_LL_READY` is set by the open task — so **the first-open
param task is a no-op for every ucom driver**, and ubsa (which registers
no `ucom_cfg_open`, so the core's hz/10 pause at `usb_serial.c:777` does
not run either) issues only **3 × 1000 ms** on first open, all from the
one coalesced line-state task (DTR+RTS+BREAK-off). The heavy chains arm
on **every later tcsetattr** while the tty is open.

## Production chain accounting

| cycle | requests | ubsa.c | worst case |
|---|---|---|---|
| first open(2) | line-state 3 × write | :374,:384,:394 | **3.0 s** |
| every tcsetattr (rate) | param 5 × write + core pause | :449,:460,:478,:482,:491 + usb_serial.c:1636 | **5.1 s** |
| every tcsetattr (B0 hangup) | param 7 × write + core pause | :433,:434,:435,:460,:478,:482,:491 | **7.1 s** |
| TIOCMSET (DTR+RTS) | line-state 2 × write | :374,:384 | 2.0 s |
| TIOCSBRK/TIOCCBRK | line-state 1 × write | :394 | 1.0 s |
| open/status/close tasks | 0 (no callbacks / cached) | :216-228, :535-543 | — |

close(2) is synchronous against the queue (`ucom_queue_command` →
`usb_proc_mwait`, usb_serial.c:671-672 + 955-957, uninterruptible
`cv_wait` per usb_process.c:364-393): the closer waits out every queued
param/line task. Unplug mid-cycle stalls the USB hub event thread via
`ucom_detach()` → `usb_proc_drain()` (usb_serial.c:394). A device
answering at just-under-timeout makes every request *succeed* — same
occupancy, no error anywhere.

## Build

```
sh build.sh     # /usr/src/sys/bus/u4b/serial/ub5476 + make (in-tree kmod)
```

## Run

```
sh run.sh       # kldload ubsa5476stall.ko (all phases at MOD_LOAD); dmesg
```

## Expected (decisive) output — final measured values

```
UB5476[A]: closer: unblocked  ELAPSED=2877 ms   first open + close
UB5476[2]: closer: unblocked  ELAPSED=7893 ms   + 1 tcsetattr@9600
UB5476[0]: closer: unblocked  ELAPSED=9974 ms   + 1 tcsetattr@B0 (7 reqs)
UB5476[B]: closer: unblocked  ELAPSED=2035 ms   fix #1: abort on first error
UB5476[C]: closer: unblocked  ELAPSED=557 ms    fix #1+#2: abort + 250 ms
```

## Fix

`fix.diff` — bound the cfg-path control timeout (1000 → 250 ms via
`UBSA_CFG_TIMEOUT`), make `ubsa_cfg_request()` return the `usb_error_t`,
abort the `ubsa_cfg_param()` chain on the first failed request. Runtime
mechanism validated by phases B/C (9974 → 2035 → 557 ms); patched
production `ubsa.ko` builds clean on the guest (`fix_compile.log`,
9/9 hunks, zero compiler warnings).
