usb: plug and play -- hot-plug, unplug, every interface, real mice
Devices can now arrive and leave after boot. A "usbhotplug" kernel thread handles root-port changes, which it is told about by Port Status Change events and also checks for every quarter second. It also handles changes behind hubs, which each hub reports on its status-change endpoint. An unplugged device has its endpoints closed and any transfer in flight failed. Then its drivers' disconnect hooks run, the slot is disabled and its memory is freed. Everything behind a hub that goes goes with it. This needed the interrupt handler to file command and endpoint-0 completions for their waiters, so that enumeration can run while keyboards interrupt. On real hardware: the controller is taken from the firmware through USB Legacy Support before reset, with SMIs off. On Intel 7/8/9 series parts the ports are switched over from EHCI, which is where firmware leaves them. Every interface of a device is offered to the class drivers, not just the first, so a receiver's mouse on interface 1 gets a driver. Configure Endpoint now copies the slot context from the controller. Before, it rebuilt it and lost the route string and TT fields of devices behind hubs. HID: pointers are read in report protocol from their report descriptor. That covers buttons, X/Y and wheel, relative or absolute, and report IDs. Boot protocol is kept as the fallback for mice and for keyboards. Non-pointer HID interfaces are declined rather than treated as tablets. USB keyboards get software key repeat. Mass storage handles up to four sticks, each unregistered from the block layer when it is pulled out, along with its cached blocks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HH7xukt4aaiGj1nQEAoQf1
This commit is contained in:
parent
c1e52e172f
commit
fa7669254e
13 changed files with 1367 additions and 240 deletions
|
|
@ -33,6 +33,18 @@
|
|||
#define HCC1_CSZ (1 << 2) // contexts are 64 bytes, not 32
|
||||
#define HCC1_XECP(x) (((x) >> 16) & 0xFFFF) // extended caps, in dwords
|
||||
|
||||
// Extended capabilities: a chain of dwords, each with an ID in bits 7:0 and
|
||||
// the distance to the next, in dwords, in bits 15:8.
|
||||
#define XECP_ID(v) ((v) & 0xFF)
|
||||
#define XECP_NEXT(v) (((v) >> 8) & 0xFF)
|
||||
#define XECP_LEGACY 1 // USB Legacy Support
|
||||
#define LEGSUP_BIOS_OWNED (1u << 16)
|
||||
#define LEGSUP_OS_OWNED (1u << 24)
|
||||
// USBLEGCTLSTS, the dword after it: the SMI enables to clear and the
|
||||
// write-one-to-clear SMI events, as xHCI 1.2 section 7.1.2 lays them out.
|
||||
#define LEGCTL_KEEP ((0x7u << 1) | (0xFFu << 5) | (0x7u << 17))
|
||||
#define LEGCTL_EVENTS (0x7u << 29)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Operational registers -- at BAR0 + CAPLENGTH
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -71,6 +83,7 @@
|
|||
#define PORT_CSC (1 << 17)
|
||||
#define PORT_PEC (1 << 18)
|
||||
#define PORT_PRC (1 << 21)
|
||||
#define PORT_CHANGES 0x00FE0000u // every change bit, 17..23
|
||||
#define PORT_RW1C 0x00FE0002u // change bits 17..23, plus PED
|
||||
|
||||
// PORTSC speed encoding. These are the same numbers as USB_SPEED_* in usb.h,
|
||||
|
|
|
|||
Loading…
Reference in a new issue