# DF-5487 — uvisor cfg_close: one synchronous 1000 ms-timeout EP0 vendor
# control-IN with discarded error; an evil Handspring/Palm-VID:PID device
# stretches every close(2) to ~1 s of uninterruptible ucom-taskqueue occupancy

## The chain (production code)

uvisor has the smallest cfg surface in the ucom serial family
(uvisor.c:224-231): no `ucom_cfg_param`, no status/line callbacks, and
`uvisor_cfg_open()` is EMPTY (uvisor.c:519-523). So open(2) costs only the
core `hz/10` pause (usb_serial.c:777) and **zero** EP0 requests, and
tcsetattr costs nothing (core `ucom_cfg_param` returns before its pause
when the driver callback is NULL, usb_serial.c:1623-1637).

The **only** EP0 request in the driver's cfg path is the close chain:

| # | task | requests | uvisor.c |
|---|------|----------|----------|
| 1 | `ucom_close()` → `ucom_shutdown()` HUPCL → line-state task | 0 (no callbacks) | usb_serial.c:694-696 |
| 2 | `ucom_cfg_close` → `uvisor_cfg_close` → `ucom_cfg_do_request(..., buffer, 0, 1000)` | 1× CLOSE_NOTIFICATION vendor control-IN | 529-545, req at 539-540 |

whose `usb_error_t` is **discarded** (DPRINTFN only, uvisor.c:541-544).
`ucom_cfg_do_request` expands to `usbd_do_request_proc(..., timo)`
(usb_serial.h:220-221), and close(2) is **synchronous against the queue**:
`ucom_queue_command()` does `usb_proc_mwait()` for `ucom_cfg_close`
(usb_serial.c:671-672, 955-957) — uninterruptible.

An evil Visor-VID:PID device (HANDSPRING 082d:0100 etc., uvisor.c:248-278)
that NAKs the CLOSE_NOTIFICATION data stage makes the request eat its full
1000 ms timeout (usb_request.c:642-644 "WXFER" lksleep loop, 699-704), so:

* every **close(2)** of /dev/ttyUxx blocks **~1 s, SIGKILL-immune**
  (measured: closer behind a just-issued open: 1080/1093 ms);
* **unplug** mid-cycle stalls the per-bus USB hub event thread the same
  way (`uvisor_detach` → `ucom_detach` → `usb_proc_drain`,
  usb_serial.c:394), plus the per-device enum lock each request holds
  (usb_request.c:467);
* the block is repeatable at will (open+close cycles), but bounded at
  ~1 s per cycle — the weakest member of the family (DF-5476 ubsa ~10 s,
  DF-5456 umoscom ~14 s, DF-5449 uvscom ~6.1 s, all Low).

## Evidence class

No Handspring/Palm VID:PID QEMU device model exists — **KLD-harness-with-
production-code** (same class as DF-5367/5383/5421/5424/5425/5449/5456/
5476): the harness drives the real in-kernel `usb_process` machinery
(usb_proc_create / msignal / mwait / drain) that ucom's synchronous close
and detach drain go through, with uvisor's production request counts
(0 per open chain, 1 per close chain) and 1000 ms timeout. One timed-out
EP0 request is modeled by its exact production cost: `lksleep("WXFER",
1000 ms)` (usb_request.c:642-644).

## Reproduce

```
./build.sh   # in-tree kmod build at /usr/src/sys/bus/u4b/serial/hx5487, -Werror clean
./run.sh     # kldload; dmesg | grep HX5487
```

Expected baseline: `HX5487[A]: closer: unblocked  ELAPSED=~1100 ms`
(open-chain hz/10 pause + 1×1000 ms cfg-close request).
Expected fix mechanism (phase B, 250 ms cfg-path timeout bound):
`HX5487[B]: closer: unblocked  ELAPSED=~350 ms`.

Observed: A = 1080 / 1093 ms; B = 346 / 363 ms (run.log, run.2.log).

## Fix

`fix.diff` bounds the cfg-path control timeout to 250 ms
(`UVISOR_CFG_TIMEOUT`, same bound as the ubsa DF-5476 / uvscom DF-5449
family fixes). The patched production uvisor.ko compiles -Werror clean
(fix_compile.log).
