8b9a4fa7b6
Replace the polling-only main loop with interrupt-driven change
detection modeled on Linux 7.1 hub_irq().
Key changes:
1. Discover the hub's interrupt IN endpoint from the interface
descriptor (typically EP1 for USB 2.x, may be absent for USB 3).
Use EndpointTy::Interrupt + EndpDirection::In to match.
2. Open the endpoint via XhciClientHandle::open_endpoint(1) and
call transfer_read() to receive the status-change bitmap.
3. Build a per-port change mask from the bitmap:
Port N is bit (N-1) of byte (N-1)/8. Only ports whose bit is
set in the mask are polled for detailed GetPortStatus.
4. Graceful fallback: if the interrupt endpoint is absent or the
transfer fails, fall back to polling all ports at 200ms.
5. Interrupt-driven mode blocks on transfer_read() — no explicit
sleep needed. Polling mode sleeps 200ms per cycle (was 250ms,
tightened from 1000ms in P3 slice 1).
6. Added XhciEndpHandle import for endpoint operations.
Cross-reference: Linux 7.1
- drivers/usb/core/hub.c: hub_irq() — URB completion handler
- drivers/usb/core/hub.c: hub_configure() — interrupt endpoint setup
- include/linux/usb/ch11.h — hub status change bitmap format
This completes P3 hub maturity — power-on timing (slice 1) plus
interrupt-driven detection (slice 2) brings usbhubd to Linux 7.1
parity for the two most important hub operations.