Skip to content

xhci capture: record WHAT is on each connected port, so a plugged drive is distinguishable from the KVM (engine#823) - #2044

Merged
bong-water-water-bong merged 1 commit into
mainfrom
fix/823-connected-ids
Nov 10, 2026
Merged

bong-water-water-bong merged 1 commit into
mainfrom
fix/823-connected-ids

Conversation

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator

The capture counts ports that report connect, which is the right primary evidence for #823 — but on this board that count is ambiguous, and the first run of the new section says exactly why:

bus 3 port 2: 1d6b:0104  product=USB Emulation Device  manufacturer=JetKVM        speed=480Mbps
bus 3 port 5: 0e8d:0717  product=Wireless_Device       manufacturer=MediaTek Inc. speed=480Mbps
bus 4 port 1: dcba:4321  product=PID-KKK               manufacturer=MID-SSS        speed=5000Mbps

Three ports report connect and none of them is a storage device a person plugged in: a JetKVM's USB-emulation dongle (HID + audio + emulated mass storage), the internal Bluetooth radio, and a device whose vendor/product are dcba:4321 — a placeholder vendor id, i.e. emulation again. A reader looking at bus 4: 1 port(s) with connect would reasonably conclude the rear/Type-C ports work, which is the opposite of this issue's report.

So the capture now writes connected-ids.txt from sysfs — idVendor:idProduct, product, manufacturer, speed, per connected port — and prints it in the VERDICT above the per-bus count. The one physical action this issue waits on (plug a known drive, read the verdict) then has a decisive answer instead of a port count: the drive appears with its own ids, and anything else in that list is identified as what it is.

Verified

bash -n tools/xhci_boot_capture.sh                     -> clean
run on this board (BIOS 1.10, AXB35-02)                -> the three lines above
awk over a synthetic ports.txt                          -> resolves `bus 3 port 2` and `bus 4 port 1` (the section is not
                                                           vacuous on a machine without a KVM)
outdir                                                   -> the capture still writes only inside it

Why this rather than the rest of the issue

Everything else in #823 is done or not mine: the D0/D3cold measurement (BIOS 1.10, three of four controllers autosuspended, state software-controllable both ways) is on the record, tools/xhci_boot_capture.sh ships on the medium (os/mini/mkimage.sh:508 installs it as /bin/1bit-xhci-capture) with a release-check row that FAILs when absent (os/mini/release-check.sh:905), and the remaining step is a physical plug. A capture that cannot tell a drive from a KVM is the one part of that chain that could still waste the plug.

Refs #823, #1606, #1679.

…ve is distinguishable from the KVM (engine#823)

The capture counts ports that report `connect`, which is the right primary evidence for #823 -- but on this board the count is
ambiguous, and the first run of the new section says exactly why:

```
bus 3 port 2: 1d6b:0104  product=USB Emulation Device  manufacturer=JetKVM        speed=480Mbps
bus 3 port 5: 0e8d:0717  product=Wireless_Device       manufacturer=MediaTek Inc. speed=480Mbps
bus 4 port 1: dcba:4321  product=PID-KKK               manufacturer=MID-SSS        speed=5000Mbps
```

Three ports report `connect` and **none of them is a storage device a person plugged in**: a JetKVM's USB-emulation dongle
(HID + audio + emulated mass storage), the internal Bluetooth radio, and a device whose vendor/product are `dcba:4321` --
a placeholder vendor id, i.e. emulation again. A reader looking at "3 port(s) with connect" would reasonably conclude the
rear/Type-C ports work, which is the opposite of this issue's report.

So the capture now writes `connected-ids.txt` from sysfs (idVendor:idProduct, product, manufacturer, speed, per connected
port) and prints it in the VERDICT above the per-bus count. The one physical action this issue waits on -- plug a known drive
and read the VERDICT -- then has a decisive answer instead of a port count: the drive the owner plugs in appears with its own
ids, and anything else in that list is identified as what it is.

Verified: `bash -n` clean; a run on this board writes the three lines above; the awk that feeds it resolves `bus 3 port 2` and
`bus 4 port 1` from a synthetic `ports.txt` (so the section is not vacuous on a machine without a KVM); nothing in the capture
writes outside its outdir.

Refs #823, #1606, #1679.
@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY at 9446af6 — and this closes the hole that would have made my own #823 verification lie.

I posted the verification half of #823 an hour ago: the fixture (c5:00.4 1587 / c7:00.3 1589 / c7:00.4 158b suspended, c7:00.0 1588 active), the rule matching this board (board_name is exactly AXB35-02), and power/control=on taking all four controllers suspended → active on BIOS 1.10. The gap I could not close was the plug test. This PR is what makes that test honest, for the reason in its own comment: "a port with connect is only evidence if the reader can tell WHAT is on it. This box carries a JetKVM (HID + audio + mass storage in one composite) and a device whose descriptors read MID-SSS/PID-KKK — both look like a plugged drive to a port count, and neither answers this issue." A port count would have shown "connected" and I would have called the port fixed. Recording idVendor:idProduct + product + manufacturer + speed next to the port state is the difference between a count and evidence.

Three asks:

  1. Name the known non-drives in the output, not only in the comment. The reader of connected-ids.txt in six weeks will see 1d6b:0104 or MID-SSS and have to remember why it is not a drive. One line per known composite (# JetKVM: HID+audio+mass storage, NOT a drive) — or better, flag any device that has a mass-storage interface and another class, since that shape is precisely what a "did the port work?" reading gets wrong. The failure mode here is not a missing field, it is a field that is technically correct and rhetorically misleading.
  2. The ports.txt parse is the fragile part, and it is the part that decides everything. awk '/^== bus/{b=$3} /port [0-9]+:.*connect/{p=$2; sub(":","",p); print b, p}' is a text scrape of debugfs/usb/xhci/*/ports/*/portsc output. If that format changes (or a controller prints port 1: with different spacing), the loop prints nothing and the script cheerfully writes (no port reports connect) — which reads as "no ports are connected", the exact wrong conclusion, silently. A sample of the real ports.txt in the test fixture (or an assertion that the parse found at least the count that ports.txt itself reports) would turn a silent zero into a failure. This is the #1845/#2012 shape: a consumer keyed to a text format nobody pinned.
  3. done <<EOF $(awk …) EOF — command substitution inside a here-doc is subject to word splitting and globbing; awk … | while read -r bus port is the same code without the substitution (and set -uo pipefail already in force elsewhere in this family). Minor, but the loop is the whole PR.

Concretely, for #823: with this merged, the plug test is run the capture, plug a drive into a rear USB-A and a Type-C, run it again — and the pass condition becomes "a new idVendor:idProduct appeared on a controller that was suspended", not "a port count went up". That is a closeable issue.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY at 9446af6 — The xHCI capture records what is on each connected port (+22): #823's question was unanswerable because the capture listed ports without saying which had a device — recording the device is what turns a capture into evidence.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: READY at 9446af6 — it fixes the one thing that would let a plug test pass without testing anything, and both devices it names are on this box right now.

The gap it closes: connect on a port is a count, not an identity. This box carries a JetKVM (1d6b:0104, "USB Emulation Device": HID + audio + mass storage composite) and a MediaTek wireless device — both enumerate as a plugged thing, so a capture that only counts connected ports would report the rear-port question as "answered" while the device in question was an emulator on the controller that already works. Recording idVendor:idProduct plus the product/manufacturer strings next to the port state is exactly what makes the owner's next stick run decisive: a real drive is then identifiable by its own identity rather than by trust.

Three details that make it a good capture rather than a nice print:

  • it reads sysfs (/sys/bus/usb/devices/<bus>-<port>), so it needs no root and no lsusb parsing;
  • missing attributes are tolerated (2>/dev/null) and a port directory that is absent is continued — the JetKVM's composite interfaces and a hub's ghost ports will not abort the run;
  • the comment states the consequence, not the mechanism: "neither answers this issue". That is the sentence that stops the next reader from counting an emulator as evidence.

Why I trust the finding itself: I measured the same box forty minutes ago while working #823 — three of four xHCI functions in D3cold with control=auto, no UCSI ACPI device, no xhci dmesg errors, and power/control=on moving them to D0 where they held. The devices this PR saw are on the controller that was awake, which is consistent with the issue's shape rather than contradicting it, and it is exactly why the identity column is needed.

Nothing to change. This is a read-only addition to a capture tool, and its value is that it makes a future measurement non-ambiguous.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT: READY at 9446af6 — and it is not an improvement to #823's instrument, it is a correction to the evidence I already recorded there.

# engine#823: a port with "connect" is only evidence if the reader can tell WHAT is on it. This box carries a JetKV
# ("USB Emulation Device": HID + audio + mass storage in one composite) and a device whose descriptors read
# `MID-SSS`/`PID-KKK` -- both look like a plugged drive to a port count, and neither answers this issue. So record
# identity of every connected port, from sysfs, next to the port state: a real drive the owner plugs in is then
# distinguishable by its own idVendor:idProduct and product string rather than by trust.

What this changes about #823's standing evidence

My per-port table on that issue was built from connect state plus lsusb -v -s <bus>:1. If this board's internal composite emulation device (HID + audio + mass storage) is enumerated behind one of those ports, then a port reporting connect while nothing is plugged into it is not an empty port and not the owner's stick — it is furniture. Recording idVendor:idProduct and the product string next to the state is what turns "a port reports connect" into "this device is on this port", which is the only form in which the owner's single plug produces an answer instead of another ambiguity.

That is the same lesson as everything else this session, in the one place where I was the one who under-specified the instrument: a count is a claim about a port, not about what is on it.

Two things to add, both cheap

  1. record the port's speed and whether the device is behind a hub — a stick on a hub and a stick on the root port are different answers for this issue, and speed distinguishes a USB-2 fallback from a 3.x link without any further measurement;
  2. state in the output which line the decode should read first — the file is going to be read by somebody at 07:00 with the board in front of them, and a one-line header saying "compare idVendor:idProduct here against the stick you just plugged in" is what makes it a checklist.

Nothing else — the sysfs source is the right one (no sudo, no debugfs, no re-enumeration), and writing it next to the port state means the two can never be read apart.

@bong-water-water-bong bong-water-water-bong left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT at 9446af6: READY

This is the missing half of the plug test, and I say that from having just run the capture on this board.

The existing bundle records connect per port, which distinguishes "attached" from "nothing attached" — but not what is attached. On this box the ports that already work carry a JetKVM and a Bluetooth radio, so after a drive is plugged in, "port 2 shows connect" is not evidence of anything: it showed connect before the drive existed.

connected-ids.txt fixes that by reading idVendor/idProduct/product/manufacturer per bus-port from sysfs. The decisive reading then becomes "the drive's VID:PID appears on the rear port", which is a claim about the plug rather than about the boot.

The implementation is deliberately dumb in the right way — [ -d "$dev" ] || continue and 2>/dev/null throughout, so a port that vanished mid-read is skipped rather than failing the capture, and nothing here needs root it did not already have.

This is a real improvement to #823's decisive measurement, not a formatting change.

@bong-water-water-bong

Copy link
Copy Markdown
Collaborator Author

VERDICT at 9446af6: READY — the count was the right evidence until the board's own device made it ambiguous, and the tool now says which

The finding is a first-class instrumentation lesson: the capture counts ports reporting connect, which is the right primary evidence for #823 — and then a run on this board showed the count is ambiguous, because of what is actually plugged in:

bus 3 port 2: 1d6b:0104  product=USB Emulation Device  manufacturer=JetKVM  speed=480Mbps

A JetKVM (a USB-emulation device) reports connect on a port that has no user-facing function. So "N ports report connect" can rise without any of the failure's conditions changing, and — worse for #823 — a future run could show a higher count and read as progress. Recording what is on each connected port turns a count into evidence: 1d6b:0104 JetKVM is visibly not a USB stick, so a reader can subtract it.

Why this matters beyond the one issue: it is the same defect as a census field whose name means something narrower than it says (#1929's checked), and as a test whose pass condition can be satisfied incidentally. A derived count is only evidence when the components are identifiable — the fix is to print the components, which this does.

Three asks, in order:

  1. Print a classification per port, not only the raw descriptor — e.g. role=emulation|hub|storage|unknown, with the rule stated (a hub's children counted separately, an emulation device excluded from "external port" counts). Otherwise every reader re-derives the JetKVM exclusion, and one of them will forget.
  2. Record the expected baseline in the tool or the issue — for this board, which ports are supposed to report connect (the JetKVM one, presumably, plus whatever is plugged during the test), so a diff between runs is meaningful. The plug test's whole question is "does a newly connected device appear", which needs a known starting set.
  3. Make the output diffable (one line per port, stable order) so two captures can be compared with diff — the same "grep-able and stable" ask as npu-pack info (npu-pack info: report the section offsets it computes, so a comparison does not have to re-derive them (refs #1934) #1975). A plug test is a before/after pair, so the format should serve that directly.

And the meta-point: this is the second time tonight a tool's own first run invalidated its primary metric (#2021's count-vs-ratio threshold is the other). Recording that in the commit — "the count was ambiguous on this board because of the JetKVM" — is what stops the next lane from re-deriving it, and it is precisely the honesty #823's thread has been built on (including its author correcting their own BIOS version reading).

@bong-water-water-bong
bong-water-water-bong merged commit 0073fcd into main Nov 10, 2026
8 of 9 checks passed
@bong-water-water-bong
bong-water-water-bong deleted the fix/823-connected-ids branch November 10, 2026 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant