Repository navigation
S1 of the xHCI move into usbd: a FAT entry that grows its file is written a cache flush after its chain and data, held by a module test that stops the disk inside a flush epoch - #901
Conversation
Design review, round 1: head
|
|
Rulings on round 1's five questions (#901 (comment)), as the review recommends:
The BLOCKERs and NOTEs 1-5 are taken as written. NOTE 6, correcting the small-kernel track's step 10 and stage 7 step 2 text, is mine to brief separately. |
Design round 2: round 1's review, mappedAnswers round 1's review under the rulings on its questions and the input ruling. The body is rewritten. Head Round 1's S3 to S7 are S1 to S5 now. Its S1 and S2 are gone, and its S8 folds into S5. BLOCKERs
NOTEs
The five Linux sites, from the specifications
Every specification is pinned by hash in T14 RUN REQUESTED: the S0 scout's |
|
S0 on the T14, run by the orchestrator from |
Design review, round 2: head
|
|
Rulings on round 2 (#901 (comment)). BLOCKER 1 is taken as written. BLOCKER 2: the device number is #899's |
|
Design round 3: the answer to round 2's review (#901 (comment)), under the rulings in #901 (comment). The body is rewritten in place; nothing is built, and the head is still BLOCKERs
NOTEs
|
Design review, round 3: head
|
|
Rulings on round 3 (#901 (comment)).
With these the design is accepted and goes to build. No further design review: the build review checks them. |
|
S1 held before building: as staged, it ships machinery that nothing in any image uses until S3 or S5. The head is still What the tree shows at
Under root What does have a user now: the two module tests the step-10 exit owes. They are the FAT append-and-sync test on Two ways to re-stage it. The choice is the owner's or the orchestrator's; I have built neither:
Nothing in sections 1 to 9 changes either way. Only the Staging table does. |
|
Ruling on the S1 hold (#901 (comment)): option 1. S1 becomes the two owed module tests alone: the FAT append-and-sync test, and the session reopen test. |
…release, not a keyboard claim Step 10's exit named "the keyboard's by stage 7 step 2's kernel test on usbd's claim", and stage 7 step 2 refused a keyboard claim while no source existed and owed a kernel test of a keyboard claim handed to the next claimant. Under the input ruling (#899, applied to usbd on #901) neither driver holds a keyboard claim, so all three presupposed a kernel feed that is gone. Step 10's exit now holds a key usbd held at its death to the owner of input's `toyos-input` release test, as #901's accepted design maps it. Stage 7 step 2 names ps2server's one kernel claim, the `isa` row, and its kernel test is `isa_lines_reach_their_holder`'s dead holder leaving no record to the next, as #899's accepted design maps it. Taken here by the ruling on #904 that widened its fence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…s chain and data The cache writes its dirty blocks lowest first, and a FAT volume's directory clusters lie below the data it allocates later. So a sync put the grown entry, the chain and the data in one flush, and the disk took the entry before the clusters it names: a machine stopped there mounts a file whose appended bytes are whatever those clusters held. A disk with a volatile write cache keeps no order between writes until a flush either. `level` now flushes the cache before it writes an entry that reaches more than the disk holds (`File::needs_reconcile`), so the chain and the data are durable before the entry is in the cache. The module test the step-10 exit owes holds it: an append and its sync, stopped after each block write in turn, mount and read back either the last whole sync's bytes or the append's, never anything else. Without the flush it is red at block write 9 of 13: a 15,288-byte file that is neither the 3,000 bytes the last sync held nor the append. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
… owner of input, not the screen's Review round 1 on #904. Step 10's exit now fails while `keyboard.rs`, `mouse.rs`, `input_merge_test.rs` or a `Keyboard`/`Mouse` class in `sdk/abi` remains. Step 10 and stage 7 step 2 deliver to the owner of input, as the ruling names it, not the screen's owner. The `toyos-input` test's controls are #901's two, exactly. Stage 7 step 2 states the kernel merge's deletion in #899's words. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
98c6ea0 to
92c22a2
Compare
|
Accepted: shape A for the reopen test. diskserver's open order moves into one function that a host test calls, red under the mutation that moves the stores after the answer. The FAT fix, which flushes before writing an entry that grows its file, is accepted as built. Its second device flush is a cost to measure on the T14 when S1 is staged for metal. Finish S1. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…one function a host test reopens a session through A client that opens its session again sends the page its killed server left, and looks at it the moment it hears. So the server's stores of its two cursors come before its answer. That order spanned `Service::open`, which made the ends, and `handshake`, which sent the answer, and both stand on syscalls, so no host test reached it. `answer` now makes the ends and only then calls the closure that tells the client; `handshake` passes it the `MSG_OPENED` send. Its test leaves a used page, a request asked, taken and answered and the server gone, makes the client's ends again as `Session::reconnect` does, and looks at the page from inside the answer: room for every request and nothing to read. With the answer told before `Opened::over`, it reads `Err(HeadPastTail)`. Closes issues/nothing-reopens-a-diskserver-session-over-a-used-page.md: the test is the one its exit and the track's step-10 exit name. What the client glue does with such a page is still read off the code, and is issues/nothing-runs-a-block-sessions-client-glue-on-a-host.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
T14 at The extra flush's cost, from the timed write and sync of a grown file on |
Build review, S1: head
|
|
Rulings on the S1 build review (#901 (comment)).
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…en issue keeps the client's half `answer` and its host test go (ruling 6139586864, from review 6139576035's BLOCKER 4): `Opened::over` already makes a server's ends of the session page and its answer together, and nothing but `Opened::over` or the client's `decode` makes an `Opened`, so the order the test held is a type's. `handshake` now calls `Opened::over` at the `MSG_OPENED` send; `Service::open` no longer makes the ends before the claim is told. `issues/nothing-reopens-a-diskserver-session-over-a-used-page.md` stays open, narrowed to the client's half: a reopen over a used page ends the session with `Io` by `drain`'s `Tag` refusal, held by a client host test red with that refusal removed. The client-glue issue this branch had filed folds into it. The submission-ring hang the review found (`Session::pump` stops on `HeadPastTail` and nothing ends the session, so `wait` blocks in `poller.wait(1, u64::MAX, ..)`) is filed as its own defect, `issues/a-block-session-waits-forever-on-a-server-past-its-submission-ring.md`. The kernel-is-small track's two citations name the type and the issue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
…n103's checker judges each stop
Review 6139576035's NOTEs 1 and 2, taken by ruling 6139586864.
`Traced` keeps the blocks it is written per flush epoch, and the test
stops with every earlier epoch on the disk and any subset of one epoch's
writes: the disk keeps no order between flushes, so a prefix of an
in-order trace was a model of the cache's order, not the disk's. 70
stops on this append and its sync.
Each stop's image is judged by `toyos-fat32-check`, written from
fatgen103 and sharing no code with `toyos-fat32`, before the driver
mounts it. Allowed by name: `LostChain`, `FsInfoFreeCount` and
`FatMirror`, which the review named, and `ChainTooLong` on `/a.txt` at
the last sync's 3000 bytes alone. That last one is the window the
module header names between a growing file's chain and its entry, and
the one `toyos-fat32`'s own `a_stop_at_any_write_leaves_only_the_named_windows`
admits; without it the fixed code reds at its first stop past the chain
("DIR_FileSize is 3000 bytes, which needs 6 clusters, and the chain
holds 30"), which is the order this branch chose and not a defect.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Build review, S1 round 2: head
|
… the append's bytes The stop with every flush epoch on the disk is the sync whole. The ChainTooLong allowance, the window between the chain's epoch and the entry's, and the last sync's bytes are admitted only before it; at it, fatgen103's checker refuses nothing and the file reads as the append made it. Before, the allowance held at every stop, so a sync that returned Ok and never made the append's size durable passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Build review, S1 round 3: head
|
Design accepted (comment 6138717771), with round 3's review answered as ruled. The build is staged below. S1 is re-staged as ruled (comment 6138751364's option 1): it is the two module tests the step-10 exit owes, alone, and
each,pci@, several block services, the settled listing andlib/blockservemove into S3, where usbd'sblock@is their second user. This is the design for step 10 ofissues/the-kernel-is-small-interrupts-post-and-threads-wait.md: the whole xHCI driver moves out of the kernel and into/system/bin/usbd. Three other steps go with it:SYS_PARTITION_*and the supervisor's partition claims;BudgetExpired,DEADMANandbetween_attempts.The branch is S1, built, at
c7201d375, withorigin/mainmerged atbc8429e71(section "S1, as built"). Round 2's review is answered point by point in the round-3 mapping comment, and round 1's in the round-2 one.What this was read from:
mainat858da4d42, which carries #893's sweep, #900's track text and #902's clean-room rule; the owner's input ruling (comment 6137234651); the rulings on round 1's questions (comment 6137620475); the rulings on round 2 (comment 6138559523); #899's accepted design (its round 6, accepted in comment 6138254697), for theinputport; #904, for the track's input text; S0's T14 reading (below); and the specifications below, fetched from their publishers and pinned by hash inspecs.txt. A page cited as "p." is the PDF's own page index in that file.The rulings this design follows:
inputport to the owner of input, the port ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899 builds. The port is extended once, with a device number, which round 2's ruling makes ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899'ssource, and a per-devicegone. There is no kernel feed claim.The rulings on round 2:
source, extended to the key record and togone, with one numbering (section 3).inputconnection at its first HID bind and drops it with its last device'sgone, so a connection to the owner is a controller that has an input device (section 3).The rulings on round 3 (comment 6138717771, on the review):
S1, as built
Head
c7201d375, onorigin/mainatbc8429e71:92c22a2c6: the FAT fix and its test;4238b8b7band8eb4cf09f: merges oforigin/main;671e5c736: the reopen test, since taken out;7978cdecf:answerand its test out, and the issues as ruled;17ea52983: the FAT test under flush epochs, judged bytoyos-fat32-check;c7201d375: the FAT test's stop with every epoch on the disk held to a clean check and the append's bytes.17ea52983answered the S1 build review as ruled;c7201d375answers round 2's (section "The final stop"). Net againstorigin/main(git diff --shortstat origin/main...HEAD: 7 files, +203 −45):fat.rs, and fileserver's dev-dependency (+5, and oneCargo.lockline);The FAT append-and-sync test, and the flush it found missing
The test.
an_append_stopped_with_any_writes_of_a_flush_on_the_disk_reads_back_the_last_syncis insystem/fileserver/src/fat.rs.toyos-fat32-check's tests build byte by byte, not on a volume the driver wrote.Traced, keeps every block it is written in its flush epoch: a flush opens the next epoch.toyos-fat32-check(now a dev-dependency), which is written from fatgen103 and shares no code withtoyos-fat32. Then the driver mounts the image, and the file must read whole as either the 3,000 bytes the last sync held or the 15,288 the append made.LostChain,FsInfoFreeCountandFatMirror, as the review named them.ChainTooLong, only on/a.txtat the last sync's 3,000 bytes, and only before the sync is whole on the disk. This is the window the module header names between a growing file's chain and its entry: an append's sync writes the chain and the data in one flush epoch and the entry in the next, so a stop between the two leaves the chain grown under the old entry.toyos-fat32's owna_stop_at_any_write_leaves_only_the_named_windowsadmits it as "the handle's own window a growth leaves untilflush_meta". Ordering the chain before the entry chooses this window; the other order leavesChainTooShort, which reads bytes that were never written. With the three-name list alone, the fixed code is red at its first stop past the chain:stopped in flush epoch 2 of 5 with writes 0b1 of its 6: /a.txt: DIR_FileSize is 3000 bytes, which needs 6 clusters, and the chain holds 30(exit 101, log, patch, atc7201d375).checkmust return nothing, and the file must read as the 15,288 bytes the append made, not the 3,000 the last sync held. A sync that returnedOkand left the old size on the disk is red there.Red before the fix, measured at the merge base in the last round with the prefix version of the test: block write 9 of 13 (log). Under the epoch model, the whole fix reverted is red too (
fat-m1below).Cache::flushwrites dirty blocks lowest first. A sync put the grown entry, the chain and the data into one flush. The root directory's cluster lies below the clusters the append allocated, so the disk took the entry before the data it names.The fix, in one site (
FatVolume::level). Before the entry of a file whose entry and handle differ (File::needs_reconcile) is written into the cache, the cache is flushed. That flush isCache::flush, which ends in the disk's own flush. The module header says the two writes are a cache flush apart.usbwrite's timed write and sync (below).needs_reconcilealso names. That leaves a shrink's order as it was: a probe of a truncate and its sync, stopped the same way, readsIoat stops 10 to 12 of 13 (probe, log). The entry still names clusters the stop had already freed.issues/a-shrink-frees-clusters-before-the-entry-stops-naming-them.mdrecords this, and S1 does not fix it.issues/nothing-reclaims-what-a-stop-leaves-on-a-fat-volume.md's.Oracle. fatgen103, through
toyos-fat32-checkon each stop's image, which is the tree's outside judge for the volumes it writes, and through the checker's fixture. Why a host test: the stop is a disk model, and no guest reaches a stop inside a flush epoch.The reopen: the server's half is a type, and the client's half stays open
answerand its test are deleted.Opened::overalready makes a server's ends of the session page and its answer together. Thecompile_faildoctest atlib/blockring/src/wire.rsrefuses building one from its fields. So the order the test held is a type's, and a test of it would test what a type refuses.handshakenow callsOpened::overinline at theMSG_OPENEDsend, andadmittakes the ends and the answer.Service::openkeeps the partition's length inOpeningin their place, so it no longer makes ends before an answer exists.decodeis the one other way to make anOpened. It is left as it is. Closing it by type would changetoyos-blockring's wire API, which is outside this fence, and the ruling asks for it only "if [it] must close".issues/nothing-reopens-a-diskserver-session-over-a-used-page.mdstays open, narrowed to the client's half.Io, bydrain'sTagrefusal. The test must be red with that refusal removed.The submission-ring hang is filed as its own defect,
issues/a-block-session-waits-forever-on-a-server-past-its-submission-ring.md, owned by the orchestrator.Session::pumpmeets the producer'sHeadPastTailand only stops pushing.drainreads only the completion ring, sowaitblocks inpoller.wait(1, u64::MAX, ..)until the server hangs up.The kernel-is-small track's two pointers (step 3's exit and step 10's storage clause) name
wire::Opened::overfor the server's order and the reopen issue for the client's half.The final stop, measured at
c7201d375Round 2's review found the allowance held at every stop, the one after the last flush included, so the test could not fail on its own claim.
c7201d375holds that stop to a clean check andout == whole. Each command iscargo test -p fileserver --lib an_append_stopped, run byrun.shandrun2.sh, which apply a patch, run, restore, and logRESTORED_CLEAN=yes.c7201d375record_metapatch: the append's sync rewrites the entry with its old size17ea52983c7201d375stopped in flush epoch 3 of 5 with writes 0b11 of its 2: /a.txt: DIR_FileSize is 3000 bytes, which needs 6 clusters, and the chain holds 30ChainTooLongallowed nowherec7201d375epoch 2 of 5 with writes 0b1 of its 6c7201d375epoch 1 of 3 with writes 0b1000 of its 8: /a.txt: DIR_FileSize is 15288 bytes, which needs 30 clusters, and the chain holds 6Under (b) at
c7201d375, the red stop is0b11 of its 2in epoch 3: the append's entry epoch, whole, which is the image with every epoch on the disk.Mutations at
17ea52983Each patch is applied as a checked patch, run with
cargo test -p fileserver --lib an_append_stopped, and restored clean byrun.sh. Every log endsRESTORED_CLEAN=yes.fat-m1-no-barrierepoch 1 of 3 with writes 0b1000 of its 8: /a.txt: DIR_FileSize is 15288 bytes, which needs 30 clusters, and the chain holds 6(log)fat-m2-entry-before-chainChainTooShortat writes0b10000of 8 (log)fat-m3-cache-highest-firstfat-m4-no-disk-flushCache::flushwithout the disk's flush, so no epoch ever closesa.txt(log)fat-m4is what the old prefix test could not see withoutcache.rs's flush-count test (the review's NOTE 2).Gates
c7201d375changes only the FAT test (git diff --stat 17ea52983..c7201d375:system/fileserver/src/fat.rs, +7 −3, all inmod tests), so the guest suite's run at17ea52983is of this head's production code and image contents, and no guest test reaches the change.cargo run -- --ci hostc7201d375system/fileserver's step ran the FAT testcargo run -- --build-onlyc7201d375cargo test --test toyos-build(the whole guest suite: every boot's/logis the FAT file server's, and every boot that starts diskserver opens its sessions throughhandshake)17ea5298317ea52983The extra flush's cost on the T14: read
The row is
usb_reset_hands_devices_back.metaldevicecaseboot (tests/images/metaldevicecase.toml) runsusbwritefirst./log/metal-write.bin, writes its bytes in 64 KiB chunks, andsync_alls it. That is a sync of a grown file on the stick's FAT volume, with the sync inside the timed span (tests/guest/metalprobe/src/usb.rs).exit: usbwrite pid=N code=<µs>in the kernel log.The two arms, staged in the last round (S1 stage, base stage):
671e5c736.8e39da48e, which is671e5c736withfat-m1-no-barrierapplied: the whole FAT change reverted.671e5c736's FAT production code is this head's. This round changes only diskserver's open and the FAT test.Each log below is the judge's log, the readback's
verdict.txt, andkernel.loglines 347–357, from===TEST_START usbwrite===to===TEST_END usbwrite. Each is masked with the orchestrator's mask, and the mask's own check counts 0 in it.usbwritespan671e5c736PASS usb_reset_hands_devices_back, "1 passed, 0 failed, 2 boot(s)", "0 past its record"exit: usbwrite pid=9 code=70480)8e39da48ecode=55656)The cost is 14,824 µs for one grown-file sync on the stick: one device flush more. That is one reading per arm. It is reported, and no bound judges it.
S0: what the T14 read
Read. The orchestrator ran
usbd_s0_readouton the T14 from the scout atb5c3b14f8: judge exit 0, 1 passed, 0 failed, 1 boot. Itspci-readoutlines are published masked onpr-901ass0-t14-pci-readout.log. Each line there carries its line number in the readback's kernel log: 00:0d.0 is lines 105 to 115, and 00:14.0 is lines 116 to 126. The scout is deleted, locally and onorigin.00:14.0,
8086:a0ed, the boot controller:0x0290, so the Capabilities List bit is set. The pointer at 0x34 is0x70.0x70id 0x01 (Power Management) →0x80id 0x05 (MSI) →0x90id 0x09 (vendor-specific) →0xb0id 0x09 →next=0x00: "walk reached the terminator after 4 link(s)".0x80: control0x0086, 64-bit, 8 vectors, no per-vector mask, not enabled.msix none. There is no PCI Express capability, so no Function Level Reset, and no Advanced Features capability.00:0d.0,
8086:9a13, the Type-C controller, has the same shape link for link.usbd_drives_the_type_c_controlleralready claims it.What it decides:
CapsTruncated(kernel/src/pcidev/mod.rs:830). It takes theAbsentarm and arms MSI (:831-833). The scout walked with the samecaps::CapWalkthatcapability()uses.nec-usb-xhciand for the AMD bench, and on AMD-Vi stages 5 and 6, as ruled.Where it starts
kernel/srcis 64,063 lines at858da4d42(find kernel/src -name '*.rs' | xargs cat | wc -l). The xHCI driver is 6,525 of them, inkernel/src/drivers/xhci/.xhci-leave=leaves alone. It does the handoff, a reset, its rings in one grant, MSI through the claim, and names every device. It binds no class.8086:a0ed, has 16 ports. On it are the boot stick and four devices that bind no class: a fingerprint reader, a camera, a smart-card reader and Bluetooth.8086:9a13, is the Type-C controller. It is empty on the bench.usbd_drives_the_type_c_controllerclaims it today, so its walk reaches the terminator with no MSI-X.Boot: storage ready (484ms).1022:1639. Each has one memory BAR, and the kernel armed each on MSI-X, so each MSI-X table is in BAR 0.0xd0000000..0xd0500000. 03:00.3's BAR 0 is at0xd0000000and 03:00.4's at0xd0100000(The metal suite targets a second bench: --metal-host, every machine's record in the host's store, the home read off the machine, and the stick read off the record #852's AMD log, its PCI lines).placement::reserveoffers no candidate inside a bridge's forwarded range (issues/pcidev-moves-a-bar-behind-a-bridge-out-of-the-range-the-bridge-forwards.md). So a claim there failsNoPlacementuntil P1 places BARs in place, even once AMD-Vi isolates.NotRemappedtoday (issues/an-amd-vi-machine-isolates-no-device.md, stages 5 and 6).Boot: storage ready (406ms).irqchip::its::msi) and refuses its function, so ARM has no USB today. ARM claims wait on Enable isolated ARM PCI claims and exclude ECAM from BAR placement #869.nec-usb-xhci. Its MSI-X table isbar0+0x3000(the scout's QEMU run, exit 0, log, lines 137 to 156), sopcidevrefuses a claim on it today (NoMappableBar). P1 lifts that.1. What usbd is
One usbd per xHCI function, which is the stage-0 ruling. The supervisor starts one for every function its row's selectors match, and starts it again when it ends other than cleanly (ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899's restart rule). usbd never exits cleanly.
One thread waits on one poller (stage 1's rule). It runs straight-line
async fns:A task awaits one of two things: the completion event of the TRB it submitted, matched by that TRB's address, or a deadline. Nothing spins after bring-up.
A deadline is never a cancellation. An operation the controller still owns is a value its task holds until the completion or the abort hands it back. Dropping one is a panic by name, because a TRB the controller holds cannot be forgotten. A deadline is an outcome the operation returns (
Silent), and the code that follows it is the specification's recovery:The driver is a crate on the driver boundary (
issues/a-driver-is-tested-on-the-host-and-its-real-implementation-is-one-instruction-deep.md), shaped astoyos-i219is:toyos-device-memory'sRegistersandDmaBuffers, plus the crate's ownClockandInterrupts, are generic parameters;toyos-pci-claim;publishbefore a doorbell,observeafter a cycle bit) is the trait's. That is where the ARM track's owed xHCI ordering check lives.toyos-xhcimoves intosystem/usbd/xhci/at the cutover, because usbd is then its one user.descriptor,xecp,protocol,portsc,ring,configureandidentity.port::PortState.enumerate,recovery,reset_recovery,ladder,call,job,scan,lateandbot's phase machine.sim/becomesstub.rs, an xHC written from xHCI 1.2 clause by clause, as thetoyos-i219stub is written. Every latitude the specification allows is aPermitsentry that is on by default, and every run takes a seed. The three sim tests the step-10 exit names keep their names in it:a_controller_that_never_answers_still_releases_the_port,a_recovery_the_controller_refuses_lets_the_device_goandno_sequence_breaks_an_invariant.Two crates are split out:
lib/scsi(toyos-scsi,no_std, with no dependency on xHCI). That isissues/scsi-is-decoded-inside-the-xhci-crate.md's exit.kernel/usbhidbecomeslib/usbhid, because the kernel stops using it.2. The boot path
xhci::init,gpt::probe_usb_disksandrootfs::hold_sourcego.Boot: completeloses what the scan costs today: 484 ms on the T14 and 406 ms on the AMD bench./logmounts, the kernel's records are on its ring, the console, the panel and the black box./logmounts is read from the black box, which the next loader prints, as a panic is today.toyos-gpt;block@<location>port.Scope::Unique, writing). It lists each service and opens its partition where it is served./logthrough that file server.What changes for each volume:
--running), as diskserver already does.ReadOnly. That closesissues/the-boot-volumes-server-holds-a-claim-that-writes.md.updatewrites are read and granted through the block service that lists the slot table. On the T14 that is its usbd.Claimeddisk,toyos::PartitionDev,DeviceType::Partition, thepart:request andSYS_PARTITION_READ/WRITE. The supervisor mints no partition claim.3. The keyboard and the pointer
Every HID interface is bound by its report descriptor, in report protocol. There is one decode path.
toyos-usbhidreads it into the interface's top-level application collections.source(below).issues/a-hid-interface-outside-the-boot-subclass-is-read-as-qemus-tablet.md's exit.SET_PROTOCOL(Report). "When initialized, all devices default to report protocol. However the host should not make any assumptions about the device's state and should set the desired protocol whenever initializing a device" (HID 1.11 §7.2.6, p.64). The request is "required only for boot devices" (§7.2, p.61), so only those are sent it. Boot protocol is never asked for, and Appendix B's fixed layouts are not decoded.SET_IDLE(0)(§7.2.4, p.63), so a report comes only on a change. That request is optional outside the boot subclass (§7.2's table). A device that stalls it keeps reporting at its polling rate, and an unchanged report is no transition.A key field is read as HID 1.11 and HUT 1.5 define it. There are three rules, and each has its own §8 test.
usb.hid.unlistedand not delivered.00to03is never delivered as a key. HUT 1.5 p.96, note 1, says01to03are "Sent as a member of the keyboard array. Not a physical key", and00is reserved. A bitmap that starts at Usage Minimum 0 has such controls; their bits are ignored, so ErrorRollOver never reaches the owner as a press.00(p.90),A5-AF(p.94),DE-DF(p.95) andE8-FFFF(p.96).00is an empty slot: an index that reaches it asserts nothing, as an idle array reports in every field (§6.2.2.5's remarks, p.42), and is not counted.usb.hid.reservedand not delivered.The wheel is wherever the descriptor puts it. Appendix B.2 leaves byte 3 onwards "Device specific (optional)" (p.71). Under boot protocol every boot mouse would lose its wheel, which is why boot protocol is never asked for.
Absolute motion is scaled into #899's range. #899 refuses an absolute position outside
0..=32767.Every field is bounded to #899's record before it is sent. #899's owner drops a source whose frame does not decode, and that source is usbd's whole connection, so one device's out-of-record value would release every device on its controller.
usb.hid.unsent_buttonand not delivered; the device's other fields still are.scroll,dxordysaturates to that field's range, as the summed motion already does.0..=32767.Transitions go to the owner of input, over the
inputport #899 builds. The owner is the program that owns the screen until #868's inputserver lands: the compositor inimages/system.tomlandtests/images/metalcase.toml, and/system/bin/consoleinimages/console.toml.usbd's row receives
input. The build's refusal ofinput(ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899) names ps2server's row and usbd's.usbd opens its connection when it binds its first HID collection, and drops it after its last device's
gone. So a connection to the owner is a controller that has an input device bound. A usbd whose controller carries only storage, cameras or readers holds no connection, and takes none of ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899's four.One rule while an input device is bound and usbd holds no connection, whatever ended it: the owner went away, or refused the connection as its fifth (an open is queued on the port and never refused by the kernel,
sdk/toyos/src/port.rs:7-11, so the two look the same to usbd).Full.usb.input.unownedand dropped; the device's current state still moves, so the reopen sends it.The device number is ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899's
source, with one numbering. ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899'sMouseEventcarriessource, "the pointer it came from", and ps2server's one pointer is source 0. S4 extends that one field:RawKeyEvent, so every key and pointer record names its device bysource;gone(below).u16in all three records; S4 widens it if ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899's build lands it narrower. A connection whose numbers would wrap is dropped and opened again, which releases everything and resends each device's current state.source, as ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899'sPointeralready keys pointers.gonenames asource, in place of ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899'sLOST. It releases what that one device holds.gonefor source 1, its keyboard.LOSTtrigger, sendsgonefor the device the byte came from: source 0 when its status hadAUXBset, source 1 when not. S4 changes ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899'sstream.rstest to match.toyos-inputMergeholds aKeysand a button byte per (connection,source). A connection's end releases every device on it, as ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899's does.A key held at usbd's death is released by the owner: usbd's connection ends with its process, and
Mergereleases every device on it. That is the owner's module test (section 8).usbd never blocks on the owner. It writes each wake's records in one
ipc::try_send. AtFull, it sends nothing more and watches the connection forWRITABLEon its one poller. Meanwhile it holds no queue. Per device it keeps two things only:When the connection takes writes again, usbd sends, per device, the transitions from the first to the second, with the summed motion as one record. A release is never lost, because the current state is what is sent. A press and its release that both fall while the connection is full are never delivered; usbd counts them as
usb.input.coalescedoninspect. The owner side is ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899's: the owner never blocks on a source.An image whose usbd row receives no
input(testcases,jobcase) binds no HID collection. usbd names each one it leaves unbound once.The panic console never depends on usbd. It takes no input (stage 7.1). After the cutover, the kernel's reset and panic paths touch no USB register (section 6).
4. pcidev: P1 serves usbd's claim
P1 of the Wi-Fi track (
issues/there-is-no-wifi.md, track order item 4) is the route, whole, as #900 ruled. It keeps a BAR where firmware put it, hands it over in 4 KiB pages, and maps the MSI-X table's page with the rest, under the owner's Q2 ruling. This design adds nothing to P1. It depends on three things P1 lands:nec-usb-xhci, QEMU's boot controller, keeps its table atbar0+0x3000. Its claim is refusedNoMappableBaruntil P1.qemu-xhciwith its MSI-X left on, which the track names as the sign that P1 serves usbd:usbd_drives_the_sparepasses on it.1022:1639keep their tables in BAR 0 behind bridge 00:08.1 (Where it starts). Both P1 halves are needed there: the table's page, and the in-place placement inside the bridge's forwarded range.Round 1's S1 built P1's table-page half at 2 MiB windows. That is gone:
bring_uparms MSI-X beforeplace_bars(kernel/src/pcidev/mod.rs:826-839);arm_claimed_msixkeeps anMmioat the entry's address before the move, held inArmed::Msix(kernel/src/drivers/pci.rs:482-486).What P1 owes for source verification. Round 1 proposed reading QEMU's VT-d source. Under #902 another implementation's source is read only clean-room. The cheaper reading is a mutation: clear
VERIFY_SOURCE_ID(kernel/src/arch/x86_64/vtd/interrupt.rs:62), and the guest test that rewrites a held table entry towards another claim's handle must go red. That test and its mutation are P1's, not this design's.The location selector stays here (S3).
pci@<bus>:<dev>.<fn>is a newDeviceRequest. The vendor:device spelling cannot name either of the AMD bench's two1022:1639functions: it answersAmbiguous.5. Recovery and hot-plug, written once
Boot discovery is hot-plug. Each port's task starts at bring-up. A device present then and one plugged in an hour later run the same code. The task follows the port's protocol, which the Supported Protocol capability names (xHCI §7.2):
WPR) out of SS.Inactive (§4.19.1.2), awaited on Port Reset Change, with the same zero recovery.port::PortState.Gone, the endpoints stop and the slot is disabled.An endpoint's recovery is one function, chosen by the endpoint's state as its events report it (§4.8.3), as
toyos-xhci::recoverydecides today:CLEAR_FEATURE(ENDPOINT_HALT)(USB 2.0 §9.4.5);A disk's recovery is the ladder, as straight-line code:
A disk whose device leaves is held for
identity::RETURN_WINDOW; for example, a reset can move a SuperSpeed stick to its companion port. Its sessions wait meanwhile.identity::samesays: its sessions resume, andtoyos-blockring's client issues again the writes no flush covered.Gone, and nothing is issued again. Writes issued again to a different device would be data loss on that device.A command the controller does not answer is aborted (§4.6.1.2).
usbd_drives_the_type_c_controllerreads the release asreset by nothing (Express: no capability; AF: no capability; PM: No_Soft_Reset set).kernel/src/pcidev/mod.rs:70-83).:85-90).usbd_serves_the_boot_stickprints the release's line for 00:14.0 (section 9), which reads the No_Soft_Reset bit.Where a specification bounds a wait, the wait is that bound: a standard request with no data stage completes "within 50 ms of receipt" (USB 3.2 §9.2.6.4, p.358), and USB "sets an upper limit of 5 seconds for any command to be processed" (§9.2.6.1). Where none does, the bound is a policy stated at its site. BOT and SBC give a command no time limit, and the T14's stick has answered later than 2 s (
issues/a-stick-that-answers-late-is-broken-by-the-two-second-abandon.md). The proposed bound is 10 s, on the reasoning behind diskserver'sCOMMAND_SILENCE, and it is measured on both benches' sticks.A Bulk-Only command is a CBW, a data phase and a CSW (§5.1, §5.2).
SYS_DEVICE_DMA_MAP), as diskserver does.A flush is decided by the Caching mode page's WCE bit (SBC-3 §6.4.5) where the device answers MODE SENSE for it, and by SYNCHRONIZE CACHE's own answer where it does not.
UAS (USB-IF UASP 1.0, T10 UAS-2) is not built. It needs streams (xHCI §4.12), and no device on either bench offers it. SCSI stays apart from its transport, and the build files UAS as a feature.
6. Reboot, shutdown, panic
quiescelosesflush_disksandseal_shut.usbloadrow (section 9) measures whether the stick comes back.stop::before_resetis the one place the kernel stops a function's bus mastering before the reset register: the xHCI's, which the kernel drives. A function a process claims is left armed today. Once the xHCI is claimed too, a generic stop replaces it, lock-free, for every bound function. That is the second answer ofissues/a-reset-stops-xhci-and-leaves-every-claimed-pci-function-armed.md. What it writes, by the function's capabilities:per-vector-mask=non both T14 controllers, so there is no vector to mask, and Enable is the one bit every MSI capability has;7. The supervisor and the manifest
One instance per function. A row may start one instance per PCI function that any of its selectors matches:
each = ["pci-class:0c0330"], or ids,each = ["pci:1033:0194"]. Each instance is endowed:pci@<bus>:<dev>.<fn>;block@00:14.0,usb@00:14.0);input.A row that receives a name an
eachrow serves gets one connector per instance.Every row that serves
blockis a block service. Each is told--running. A file server is endowed one connector per block service, minted for its role's grant.The generic half of diskserver becomes a crate,
lib/blockserve, that both block services stand on. That half is: accepting, grants, holds, the listing, sessions withwire::Opened::over, region lending and the partition table's read. It moves with its tests. The device beneath it is NVMe, or a Bulk-Only disk.The rows:
images/system.toml's[programs.usbd]getseach = ["pci-class:0c0330"],serves = ["block", "usb"],receives = ["input"],serviceandrestart.images/console.toml's row is the same.each = ["pci:1033:0194", "pci:8086:a0ed", "pci:1022:1639"]. QEMU's spare (1b36:000d) and the T14's Type-C controller (8086:9a13) stay free, forusbd_spareto claim, asxhci-leave=leaves them today.inspectreceivesusb, andtoyos_inspect::USBjoinsOWNERS.What is deleted
kernel/srcat858da4d42is 64,063 lines.wc -l)drivers/xhci/:mod1,727,wait/msc1,772,device913,stop716,wait/boot546,wait/mod455,legacy246,hid150gpt.rs. The loader-named GUIDs the supervisor reads, about 40 lines, move rather than go.block.rs.BlockErrorandBlockResult, about 15 lines, stay with the page cache until step 9's VFS half.drivers/usb_storage.rsusb_gate.rsarch/x86_64/idt/xhci.rskeyboard.rsmouse.rsinput_merge_test.rs#899 lands first (track order item 1) and takes about 205 of the last three rows' lines. S5 measures what is left at its own base.
The kernel's input goes whole. Once ps2server delivers to the owner, the kernel xHCI's HID is the last source of the kernel's keyboard and mouse streams, so S5 deletes:
keyboard.rs,mouse.rsandinput_merge_test.rs, withmain.rs's two modules and its call;keyboardandmousedevice classes:DeviceType::Keyboard(3) andMouse(7), theirDeviceRequestnames,FileType::KeyboardandMouse,device.rs's claim arms,syscall/device.rs's arms (:173-174,:462-463), and inobject/ops.rsthe read-watch arms (:286-287), the event reads (:421-445), the readiness arms (:830-831), the stat arms (:684-685) and the arms at:358-363,:763-764and:905-906;syscall/io.rs'sReadBlock::Keyboard, its wait, andread_block_device's keyboard arm;KObjectRef::Console's keyboard watch (object/ops.rs:284) andReadBlock::Console's wait onkeyboard::WATCH. Nothing posts that watch for a serial byte today. A console's blocking read parks on its own re-poll deadline alone. Its poller watch has no source and is refusedNotSupportedat registration (inbox::arm), where today it registers a watch serial input never completes (issues/a-console-watch-waits-on-the-keyboard-not-the-serial-line.md, whose exit stays open);toyos::KeyboardandMousewith their endowment arms;sdk/std's andsdk/libc'sFileType::Keyboardarms;lib/manifest's andlib/inspect's two classes; thekeyboardandmousedevices of the compositor's and the console's rows inimages/system.toml,images/console.toml,tests/images/metalcase.tomlandtests/images/panelcase.toml.endowment_deniednames the framebuffer class where it names the keyboard's.toyos_abi::input's records, which the kernel no longer speaks, move totoyos-input.What the console image's shell reads instead: nothing new. The shell reads its
surfacefrom/system/bin/console, as today. The console reads key transitions from the connections on itsinputacceptor, ps2server's and every usbd's, in place of the kernel's keyboard claim.Parts of files: about 900 lines, by reading. The build measures them.
device.rs,object/device.rs,object/ops.rs'suntil_answered,partition_fsyncandpartition_word,syscall/device.rs'ssys_partition_transfer, and the dispatch arm.rootfs::hold_source.sync::OwedLock, its fence and its feature. Its one user isXHCI.xhci-leave=,xhci-xecp-selftest,xhci-descriptor-selftest,usb-transport-breakandusb-reset-under-load.quiesce's block budget,machine.rs's USB calls, andacpi.rsandpower.rs's stop.drain_irqs's and the idle loop's xHCI checks.IrqSource::Xhci, with its census and trace arms, and AArch64'sDriverIrq::Xhci.main's storage phase.Added in the kernel: about 70 lines, estimated. The location selector is about 30, and the generic reset stop about 40.
Net: about −9,000 lines of
kernel/src, roughly 14%.toyos-xhci,toyos-usbhid,toyos-gptandtoyos-blockholdgo, and so doeskernel/loom/tests/owed_lock.rs(64 lines).Xhci,poll_if_pending,port_work_pendingandOwedLockappear nowhere.irq_ringis gone: ps2server tookI8042, and this takesXhci.git grep -n -e BudgetExpired -e DEADMAN -e between_attempts -e until_answered -- kernelfinds nothing.Outside the kernel:
toyos-xhci,call(546),late(120) andscan(116) are deleted outright.enumerate(427),recovery(322),reset_recovery(626),ladder(481),job(474) andbot's phase machine (bot.rsis 741) become usbd's straight-line tasks.sim/src/driver.rs(701) is replaced by the stub.Claimed, the supervisor's kernel-partition half,toyos::PartitionDev,SYS_PARTITION_*,DeviceType::Partition, andRecord::Usb,BlockandPartition.Staging
Round 1's S3 to S7 are S1 to S5 here. Its S1 and S2 are gone, and its S8 folds into S5.
usbd_s0_readoutrow on the T14, fromb5c3b14f8(section "S0"). Done: the walk reached its terminator, and the scout is deleted.system/fileserver/src/fat.rs's append and sync, stopped inside a flush epoch and judged bytoyos-fat32-check, with the flush it found missing. diskserver's open answers throughOpened::overinline. The reopen's client half staysissues/nothing-reopens-a-diskserver-session-over-a-used-page.md's, as ruled (comment 6139586864).qemu-xhcispare and the T14's Type-C controller, whichxhci-leave=leaves.usbd_drives_the_spareonqemu-xhciwith MSI-X on;usbd_drives_the_type_c_controllertoyos-scsisplit out with the sense fix; the Bulk-Only disk, the ladder, identity and flush;block@on the spare. And what has its second user here, moved from round 3's S1:eachwith its selectors, thepci@location selector, several block services,lib/blockservetaken out of diskserver, fileserver over several block services, and a listing answered once settledissues/sense-data-is-read-as-fixed-format-whatever-its-response-code-says.md's exit; diskserver's guests unchanged and green; the manifest and blockserve host testslib/usbhidwith the report-descriptor parser,SET_PROTOCOL(Report)andSET_IDLE; theinputextension in ps2server,toyos-inputand the owners; usbd's connection and its full-connection rule. The stub test the step-10 exit owes: a stick whose bulk endpoint never answers leaves a keyboard on the same controller delivering every report.lib/xhcimoved intosystem/usbd;FLASHABLEwithoutxhci-leave=S5's exit is the track's step-10 exit as it stands once #904 lands:
usbd_drives_the_spareon the defaultqemu-xhciandusbd_drives_the_type_c_controller. The exit's third clause, "the keyboard's by stage 7 step 2's kernel test on usbd's claim", has no subject under the input ruling: there is no keyboard claim.a_controller_that_never_answers_still_releases_the_port,a_recovery_the_controller_refuses_lets_the_device_goandno_sequence_breaks_an_invariant, moved to the stub under their names; and S4's stub test./log's, what a killed usbd had on the wire: stage 3'stoyos-blockringtests for the transport;wire::Opened::over, which moves with the session open intolib/blockserveat S3, and the client testissues/nothing-reopens-a-diskserver-session-over-a-used-page.mdowes, for usbd's session open; and S1's FAT test.On ARM, usbd claims
virt's xHCI once #869 lands. That stays the ARM track's.Until S5, the kernel's driver and usbd's run side by side, as since #827. The kernel's copies of the sequences are a compromise owned by S5, and their exit is the kernel's driver deleted. The track already records such a compromise for the descriptor decoder and the extended-capability walk.
8. Checks under the testing ruling
Units and modules, on the host. These carry the weight.
Aborted;Gone, with nothing issued again;inputconnection no record waits in usbd; a release that falls while it is full reaches the owner once it drains; a press and release inside it are countedcoalesced;inputconnection; the first HID bind opens one; the last device'sgoneis sent and the connection dropped. Red when usbd opens its connection at bring-up, and red when it keeps the connection after the lastgone.usb.input.unowned, and the first report a second after it opens again, while a report inside that second opens nothing. Red under the HID-bind-only trigger, and red when every report opens.toyos-scsi: SPC-4's sense formats (the sense issue's exit). The INQUIRY and READ CAPACITY refusals move with their tests.toyos-usbhid: the report-descriptor parser, on QEMU's tablet descriptor, its keyboard's, and another layout, with refusals by name and a no-panic fuzz.a_rollover_report_believes_its_modifiers_and_not_its_slotsholds rollover. Each of section 3's key rules has its own test, each red under its own mutation:a), index 0x62 delivers usage 0x65, index 0 asserts nothing, and index 0x63 asserts nothing. Red when the usage is read as the raw index, and red when the range check is made on the usage instead of the index;00to03: a bitmap from Usage Minimum 0, with bits 0 to 3 set, delivers no press. Red when they are delivered as keys;reservedand not delivered, while 0xA4, 0xB0, 0xDD and 0xE7 beside them are; an idle array's 0x00 slots assert nothing and count nothing. Red when any one of the three ranges is taken out of the check;unsent_button, while button 1 in the same report is delivered. Red when bits past 5 are passed through;toyos-input(ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899's crate): agonenaming onesourcereleases what that device held and nothing anothersourceon the same connection holds; a connection's end releases every device it carried; ps2server's pointer at source 0 and keyboard at source 1 are two devices. This is the owner's test that a key held at usbd's death is released, red withMerge's release on a connection's end removed, and red withgonereleasing its whole connection.lib/blockserve: grants, holds,--running, the boot volume's read-only grant, moved from diskserver with their tests (S3).system/fileserver/src/fat.rs: a disk stopped after each block write in turn of an append and its sync mounts at every stop and reads back all the last whole sync held.lib/manifest:each's parsing and its refusals.The kernel's claims, as the kernel's integration.
usbd_drives_the_spare(QEMU) stays, on the defaultqemu-xhcifrom S2. Its drive arm hands the claim to usbd and kills it, and its fault arm claims the function again: a dead holder's claim handed over again, which is the exit's kernel part.xhci-leave=goes. The spare is free because the test image's usbd row does not name it (section 7). The control arm becomes a claim on the boot controller, which the image's usbd holds: refused as held.usbd_drives_the_type_c_controller(T14) stays, on 00:0d.0, the same at S5.usb-kbdandusb-tablet, go through usbd and the owner'sinputport. The suite is the smoke test.Cut at S5, each with what holds it:
usb_keyboard_rollover(QEMU):toyos-usbhid's rollover test.xhci_xecp_walkandxhci_descriptor_walk: their actuators go, andxecp's anddescriptor's host tests hold the decoders.usb_stick_left: its actuator goes, and the ladder's breaks are the stub's.usb_reset_hands_devices_back: its judge readsstop.rs's account, which goes. The rewrittenusbloadrow holds the stick's survival of a reset.input_merge_test: the merge istoyos-input's.partition_grantwas cut by #893, so it is not in this list.Negative control, per stage: the whole stage reverted onto the base its green arm ran on, with its new checks red.
Independent oracles:
9. Metal rows
On the T14 and the AMD bench, at S5:
/logoff the stick, so every row passes through usbd's storage path.usbd_serves_the_boot_stickholds the kernel's part only, asusbd_drives_the_type_c_controllerdoes for 00:0d.0: the boot controller's claim handed over (00:14.0; 03:00.3 and 03:00.4), its message in remappable format through its remapping entry, and the first message on its slot raised by the No-Op. Its hand-over prints the release's line for the boot controller, which reads 00:14.0's PM No_Soft_Reset bit (section 5).Boot: completeand the time/logmounted are reported against the base's, and judged by nothing. The suite's boots through usbd are the smoke test of its naming and serving.stick_survives_a_reset_under_loadrewritesusb_reset_records_the_phase_it_cut'susbloadboot.boot.usbload.stick_secsagainst its ceiling.mask_windowsis read under a stick-write load: each CPU's longest interrupts-off and preemption-off windows, against the base, by the track's rule. Stage 5's exit asks for no window longer than a register access.tone_beside_a_stick_write, a new row:issues/a-megabyte-written-to-the-stick-starves-a-tone-beside-it.md's exit, on the T14. A job writes a mebibyte to/logwhilehda_tone's tone plays, and soundserver'sunderruns=0over the tone's window is the verdict.underrunsis soundserver's count of its thread being run too late. Neither program's behaviour is judged.The specifications it follows
Each is pinned by hash in
specs.txt.1022:1639. A stubPermitsentry specific to a controller comes from these.The five sites that cite another operating system, decided from the specifications
The build deletes each citation and each decision that rested on it:
lib/xhci/src/ladder.rs:229:RESET_RECOVERY_NS, 50 ms, rested on another implementation. Now by protocol: a USB 2 port waits TRSTRCY, 10 ms (USB 2.0 §7.1.7.5, §9.2.6.2), and a USB 3 port waits nothing (USB 3.2 §9.2.6.2).issues/the-tree-names-linux-as-an-authority.md's sweep (wt/toyos-linux-sweep) coverslib/xhcitoo. Whichever lands second carries the other's decision, so the value is decided once.lib/xhci/src/port.rs:20: the debounce is USB 2.0 §7.1.7.3's TATTDB, 100 ms, and it applies to a USB 2 port alone. The name beside it goes.lib/xhci/src/enumerate.rs:25: reading 8 bytes at full speed is xHCI §4.3.4 and USB 2.0 §9.6.1. The name beside it goes, and the module becomes straight-line code.kernel/usbhid/src/keyboard.rs:21and:27: rollover is HID 1.11 Appendix C. Now: an array field's value is an index, range-checked against Logical Minimum to Maximum and read through the field's usage list (§6.2.2.5); a key variable field is a bitmap of usages; a usage HUT 1.5 reserves (00,A5-AF,DE-DF,E8-FFFF) names no key (section 3).kernel/usbhid/src/pointer.rs:17: now the wheel is the Generic Desktop Wheel usage, wherever the report descriptor puts it. Byte 3 is not read as anything by position.This design rests on no other implementation.
Roast
Enumeration,Recovery,Quiescing,Ladder,AfterBreak. They exist so that two drivers, one blocking and one stepped, could share an order. With one driver, the compiler writes them from code read top to bottom.inputconnection loses a whole keystroke. A press and its release that both fall while the owner is not reading are never delivered. Queueing them would put a slow owner's backlog in usbd's memory, and blocking would stall the stick's ring behind the screen. They are counted by name; no key is ever left held.issues/a-cut-bulk-only-command-does-not-brick-the-benchs-stick.md).usbloadrow is kept, rewritten, so a red reads there./logstays the kernel's on the stick.each, and several block services.1022:1639controllers cannot be named by id.port::PortStatestays a state machine./logmounts later in the boot than the kernel's disk is ready today./logmounts, records wait in the rings. S5 counts the ones the rings refused, and reports that count and the time/logmounted.xhci-leave=lives through S2 to S4, with two drivers side by side. That is the compromise usbd drives one xHCI controller the kernel was told to leave alone (xhci-leave=), naming every device over inspect #827 already records, and S5 ends it.issues/a-console-watch-waits-on-the-keyboard-not-the-serial-line.mdgives the serial line a watch.pollanswers.pollreads every completed token as ready, a refusal included (sdk/libc/src/posix_io.rs:629-638), andPoller::waitdoes not filter refusals. So after S5,pollon a console fd answersPOLLINat once, where today it waits. A caller that polls a console in a loop spins.tone_beside_a_stick_writeandstick_survives_a_reset_under_loadeach name what of theirs is the kernel's (section 9). Without them, the tone issue's exit and the reset stop's deletion would be judged by no machine.sourceis au16that one connection never reuses. A connection that binds 65,536 devices is dropped and opened again. That costs one resend of every device's state, and keeps a late record from ever reaching a later device.What I am unsure of
ChainTooLongpast the review's list. The FAT test allows it only on/a.txtat the last sync's size, and only before the sync is whole on the disk: the window between chain and entry thattoyos-fat32's own stop test names ("S1, as built"). Round 2's review ruled the window a property of the design, and (a) measures it closed inside the sync.inputconnection can take a reopen after its owner is started again on the same port. ps2server: the i8042 driver leaves the kernel, and the owner of input merges every source #899's owner side is not built.wc -lat858da4d42.Issues this closes or moves
Closed at their stage:
scsi-is-decoded-inside-the-xhci-cratesense-data-is-read-as-fixed-format-whatever-its-response-code-saysa-hid-interface-outside-the-boot-subclass-is-read-as-qemus-tabletthe-boot-volumes-server-holds-a-claim-that-writesa-machine-that-boots-off-nvme-looks-1500-ms-for-a-usb-boot-disk(its wait is deleted)xhci-waits-are-spinsa-disk-plugged-in-after-boot-is-bound-inside-a-scheduling-passhotplug-blocks-a-scheduler-passscheduler-pass-blocks-in-xhcistorage-still-comes-up-before-the-supervisor-runsa-megabyte-written-to-the-stick-starves-a-tone-beside-it(its row)nothing-reopens-a-diskserver-session-over-a-used-page: stays open, narrowed at S1 to the client's half; S1 filesa-block-session-waits-forever-on-a-server-past-its-submission-ringMoved:
a-reset-stops-xhci-and-leaves-every-claimed-pci-function-armed: its register half.the-supervisors-claim-of-a-pci-function-the-t14-lacks-holds-preemption-off-for-3-8-ms: a claim by location reads one function.a-file-server-waits-30-s-on-a-block-port-nobody-serves-and-says-nothing: S3's bounded listing.every-driver-is-still-in-the-kernel: its USB HID bullet.a-controller-whose-msix-table-is-in-bar-0-cannot-be-driven-from-userlandis P1's. The build accounts for every other USB issue at the stage that touches it.The gates S1 claims are in "S1, as built". The other commands whose exits this body reports are the scout's QEMU run (exit 0) and the orchestrator's T14 run of
usbd_s0_readout(exit 0).🤖 Generated with Claude Code
https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy