====== Lyx OS – XHCI-Treiber ====== Der XHCI-Treiber (''kernel/xhci.lyx'') implementiert den USB 3.x Host-Controller-Treiber für Lyx OS. Er läuft vollständig in Ring-0 und wird von keiner externen USB-Stack-Library abhängig. Die Ring-3-Syscalls für USB sind noch **nicht vergeben** — Syscalls 150–155 sind durch Vega-Fensterverwaltung (150–152), RAM-Disk (153–154) und IOFS-mkfs (155) belegt. USB-Syscalls werden im XHCI-WP in einem freien Bereich ab 156+ zugewiesen. → [[lyxos:syscalls|Syscall-ABI]] · [[lyxos:kernel|Kernel-Interna]] · [[lyxos:start|Übersicht]] ---- ===== 1. Überblick ===== XHCI (Extensible Host Controller Interface) ist der USB-Host-Controller-Standard ab USB 3.0. Er ersetzt EHCI (USB 2.0), OHCI und UHCI und unterstützt alle USB-Generationen (1.0–3.2) in einem einzigen Controller. **Zuständigkeiten des Treibers:** ^ Schicht ^ Zuständigkeit ^ | PCI-Erkennung | XHCI-Controller auf dem PCI-Bus finden (Class 0x0C / Sub 0x03 / ProgIF 0x30) | | MMIO-Mapping | Capability-, Operational-, Runtime- und Doorbell-Register in Kernel-Address-Space mappen | | HC-Initialisierung | Controller-Reset, Slot-Enable, Command-Ring und Event-Ring einrichten | | Port-Management | Port-Reset, Speed-Erkennung, Gerät adressieren | | Transfer-Engine | TRB-Ringe für Control-, Bulk- und Interrupt-Transfers verwalten | | Ring-3-Interface | USB-Syscalls TBD (ab 156+, erst mit XHCI-WP vergeben; 150–155 = Vega/RAM-Disk/IOFS) | **Quelldatei:** ''kernel/xhci.lyx'' ---- ===== 2. PCI-Erkennung ===== Der XHCI-Controller wird als PCI-Gerät erkannt: ^ Feld ^ Wert ^ Bedeutung ^ | Class Code | 0x0C | Serial Bus Controller | | Subclass | 0x03 | USB Controller | | Prog IF | 0x30 | xHCI | // PCI-Scan: XHCI-Controller finden con XHCI_PCI_CLASS : int64 := 0x0C; con XHCI_PCI_SUB : int64 := 0x03; con XHCI_PCI_PROGIF : int64 := 0x30; Der Treiber liest die BAR0-Basisadresse aus dem PCI-Konfigurationsraum (BAR0 ist immer MMIO, 64-bit). Die physische Adresse wird via ''sys_mmap_device'' in den Kernel-Address-Space gemappt. ---- ===== 3. MMIO-Register-Layout ===== XHCI kennt vier Register-Bereiche, alle relativ zur BAR0-Basisadresse: BAR0 ──┬── Capability Registers (Offset 0, Länge = CAPLENGTH) ├── Operational Registers (Offset = CAPLENGTH) ├── Runtime Registers (Offset = RTSOFF, aus CapRegs) └── Doorbell Array (Offset = DBOFF, aus CapRegs) ==== 3.1 Capability Registers (CapRegs) ==== Nur lesbar. Beschreiben die Hardware-Eigenschaften des Controllers. ^ Offset ^ Name ^ Beschreibung ^ | +0 | ''CAPLENGTH'' (uint8) | Länge des CapRegs-Blocks; Startadresse der OpRegs | | +2 | ''HCIVERSION'' (uint16) | xHCI-Spezifikationsversion (z.B. 0x0100 = v1.0) | | +4 | ''HCSPARAMS1'' (uint32) | Bits[7:0]=MaxSlots, Bits[18:8]=MaxIntrs, Bits[31:24]=MaxPorts | | +8 | ''HCSPARAMS2'' (uint32) | IST, ERST_MAX, MAX_SCRATCHPAD_BUFS | | +12 | ''HCSPARAMS3'' (uint32) | U1/U2-Exit-Latenzzeiten | | +16 | ''HCCPARAMS1'' (uint32) | Capability-Bits: 64-bit Addressing, BNC, AC64, CSZ usw. | | +20 | ''DBOFF'' (uint32) | Byte-Offset der Doorbell-Array-Base relativ zu BAR0 | | +24 | ''RTSOFF'' (uint32) | Byte-Offset der Runtime-Register-Base relativ zu BAR0 | | +28 | ''HCCPARAMS2'' (uint32) | Erweiterte Capability-Bits (USB 3.1+) | con XHCI_CAP_CAPLENGTH : int64 := 0; con XHCI_CAP_HCIVERSION : int64 := 2; con XHCI_CAP_HCSPARAMS1 : int64 := 4; con XHCI_CAP_HCSPARAMS2 : int64 := 8; con XHCI_CAP_HCCPARAMS1 : int64 := 16; con XHCI_CAP_DBOFF : int64 := 20; con XHCI_CAP_RTSOFF : int64 := 24; ==== 3.2 Operational Registers (OpRegs) ==== Lese-/schreibbar. Steuern den Controller-Betrieb. ^ Offset ^ Name ^ Beschreibung ^ | +0 | ''USBCMD'' (uint32) | Run/Stop (Bit 0), HC-Reset (Bit 1), Interrupt-Enable (Bit 2) | | +4 | ''USBSTS'' (uint32) | HCHalted (Bit 0), Host-Error (Bit 2), Event-Int (Bit 3) | | +8 | ''PAGESIZE'' (uint32) | Bits[15:0]: unterstützte Page-Größen (Bit N = 2^(N+12) Bytes) | | +20 | ''DNCTRL'' (uint32) | Device-Notification-Control | | +24 | ''CRCR'' (uint64) | Command-Ring-Control: RCS, CS, CA, CRR, Ring-Pointer | | +48 | ''DCBAAP'' (uint64) | Device-Context-Base-Address-Array-Pointer | | +56 | ''CONFIG'' (uint32) | Bits[7:0]: MaxSlotsEn (max. aktivierte Slots) | con XHCI_OP_USBCMD : int64 := 0; con XHCI_OP_USBSTS : int64 := 4; con XHCI_OP_PAGESIZE: int64 := 8; con XHCI_OP_DNCTRL : int64 := 20; con XHCI_OP_CRCR : int64 := 24; con XHCI_OP_DCBAAP : int64 := 48; con XHCI_OP_CONFIG : int64 := 56; // USBCMD-Bits con XHCI_CMD_RUN : int64 := 1; // Run/Stop con XHCI_CMD_HCRST : int64 := 2; // HC-Reset con XHCI_CMD_INTE : int64 := 4; // Interrupter-Enable con XHCI_CMD_HSEE : int64 := 8; // Host-System-Error-Enable // USBSTS-Bits con XHCI_STS_HCH : int64 := 1; // HC Halted con XHCI_STS_HSE : int64 := 4; // Host System Error con XHCI_STS_EINT : int64 := 8; // Event Interrupt con XHCI_STS_PCD : int64 := 16; // Port Change Detected con XHCI_STS_CNR : int64 := 0x800; // Controller Not Ready ==== 3.3 Runtime Registers ==== ^ Offset ^ Name ^ Beschreibung ^ | +0 | ''MFINDEX'' (uint32) | Microframe-Index (125 µs-Ticks) | | +32 | ''IR[0]'' | Interrupter-Register-Set 0 (IMAN, IMOD, ERSTSZ, ERSTBA, ERDP) | Interrupter-0-Offsets (relativ zu IR[0]-Basis = RTSOFF + 32): ^ Offset ^ Name ^ Beschreibung ^ | +0 | ''IMAN'' (uint32) | Interrupt-Management: IE (Bit 1), IP (Bit 0) | | +4 | ''IMOD'' (uint32) | Interrupt-Moderation: IMODI (Bits[15:0]) | | +8 | ''ERSTSZ'' (uint32) | Event-Ring-Segment-Table-Size | | +16 | ''ERSTBA'' (uint64) | Event-Ring-Segment-Table-Base-Address | | +24 | ''ERDP'' (uint64) | Event-Ring-Dequeue-Pointer | con XHCI_RT_MFINDEX : int64 := 0; con XHCI_RT_IR0 : int64 := 32; // Basis des ersten Interrupters // Offsets innerhalb IR[0] con XHCI_IR_IMAN : int64 := 0; con XHCI_IR_IMOD : int64 := 4; con XHCI_IR_ERSTSZ : int64 := 8; con XHCI_IR_ERSTBA : int64 := 16; con XHCI_IR_ERDP : int64 := 24; ==== 3.4 Doorbell Array ==== Ein 32-bit-Eintrag pro Slot (Slot 0 = Host-Controller-Command-Ring). Schreiben löst einen Transfer aus. con XHCI_DB_HC : int64 := 0; // Doorbell 0: Command-Ring // Doorbell N (N = Slot-ID): DB_TARGET = Endpoint-Index (Bits[7:0]) ---- ===== 4. Datenstrukturen ===== ==== 4.1 Transfer Request Block (TRB) ==== Jede Operation in XHCI ist ein 16-Byte-TRB. TRBs werden in Ringen arrangiert. Byte 0– 7: Parameter (Adresse, Daten, abhängig vom TRB-Typ) Byte 8–11: Status (Byte-Count, Interrupter-Target) Byte 12–15: Control (Bits[9:0]=TRB-Typ, Bit15=C=Cycle-Bit, typ-spezifische Flags) con XHCI_TRB_SIZE : int64 := 16; // TRB-Typen (Control-Bits[9:0]) con TRB_NORMAL : int64 := 1; // Bulk / Interrupt Transfer con TRB_SETUP : int64 := 2; // Control Setup-Paket con TRB_DATA : int64 := 3; // Control Data-Phase con TRB_STATUS : int64 := 4; // Control Status-Phase con TRB_ISOCH : int64 := 5; // Isochroner Transfer con TRB_LINK : int64 := 6; // Ring-Link (letzter TRB im Ring) con TRB_EVT_DATA : int64 := 7; // Event-Data con TRB_NOOP : int64 := 8; // No-Op Transfer con TRB_ENABLE_SLOT : int64 := 9; // Command: Slot aktivieren con TRB_DISABLE_SLOT : int64 := 10; // Command: Slot deaktivieren con TRB_ADDRESS_DEV : int64 := 11; // Command: Gerät adressieren con TRB_CONFIG_EP : int64 := 12; // Command: Endpoint konfigurieren con TRB_EVAL_CTX : int64 := 13; // Command: Context evaluieren con TRB_NOOP_CMD : int64 := 23; // No-Op Command con TRB_XFER_EVENT : int64 := 32; // Event: Transfer abgeschlossen con TRB_CMD_COMPL : int64 := 33; // Event: Command abgeschlossen con TRB_PORT_STATUS : int64 := 34; // Event: Port-Status geändert // TRB-Control-Bits con TRB_C : int64 := 1; // Cycle-Bit con TRB_TC : int64 := 2; // Toggle-Cycle (nur LINK-TRB) con TRB_ISP : int64 := 4; // Interrupt-on-Short-Packet con TRB_IOC : int64 := 0x20; // Interrupt-on-Completion con TRB_IDT : int64 := 0x40; // Immediate-Data (≤8 Bytes direkt im TRB) ==== 4.2 Event-Ring-Segment-Table-Eintrag (ERSTE) ==== con XHCI_ERST_SIZE : int64 := 16; // +0 (uint64): Ring-Segment-Base-Address (4K-aligned) // +8 (uint32): Ring-Segment-Size (Anzahl TRBs im Segment) // +12 (uint32): reserviert ==== 4.3 Device-Context-Base-Address-Array (DCBAA) ==== Ein Array von uint64-Zeigern (Slot 0 bis MaxSlots). Slot 0 zeigt auf den Scratchpad-Buffer-Array (oder 0 wenn MaxScratchpad=0). Jeder weitere Eintrag zeigt auf den Output-Device-Context des entsprechenden Slots. ==== 4.4 Input-Context ==== Wird für ''ADDRESS_DEVICE''- und ''CONFIGURE_ENDPOINT''-Commands genutzt. Besteht aus: * Input-Control-Context (32 Bytes): Drop-Flags + Add-Flags je Endpoint * Slot-Context (32 Bytes): Geschwindigkeit, Root-Hub-Port, Anzahl Endpoints * Endpoint-Contexte (32 Bytes je EP): EP-Typ, Max-Packet-Size, TR-Dequeue-Pointer con XHCI_CTX_SIZE : int64 := 32; // Wenn CSZ=0 in HCCPARAMS1 con XHCI_CTX_SIZE_64 : int64 := 64; // Wenn CSZ=1 (64-Byte-Contexts) // Slot-Context-Felder (+0 im Slot-Context-Block) // Bits[19:10] = Root-Hub-Port-Num, Bits[23:20] = NumContextEntries, // Bits[29:27] = Speed (1=Full, 2=Low, 3=High, 4=SuperSpeed) con XHCI_SPEED_FS : int64 := 1; con XHCI_SPEED_LS : int64 := 2; con XHCI_SPEED_HS : int64 := 3; con XHCI_SPEED_SS : int64 := 4; // Endpoint-Typ (EP-Context Bits[5:3]) con XHCI_EP_ISOCH_OUT : int64 := 1; con XHCI_EP_BULK_OUT : int64 := 2; con XHCI_EP_INTR_OUT : int64 := 3; con XHCI_EP_CTRL : int64 := 4; con XHCI_EP_ISOCH_IN : int64 := 5; con XHCI_EP_BULK_IN : int64 := 6; con XHCI_EP_INTR_IN : int64 := 7; ---- ===== 5. Initialisierung ===== Die Initialisierungsreihenfolge folgt dem xHCI-Spec §4.2: 1. BAR0 lesen, MMIO mappen 2. Warten bis USBSTS.CNR = 0 (Controller Ready) 3. USBCMD.RUN = 0 setzen → Controller anhalten 4. Warten bis USBSTS.HCH = 1 5. USBCMD.HCRST = 1 → Controller-Reset 6. Warten bis HCRST = 0 und CNR = 0 7. DCBAAP setzen (alloc + nullen) 8. Command-Ring initialisieren (CRCR setzen, Cycle-Bit = 1) 9. Event-Ring initialisieren (ERST alloc, ERSTBA + ERSTSZ im IR[0] setzen) 10. Interrupter-0 aktivieren: IMAN.IE = 1 11. MaxSlotsEn in CONFIG setzen 12. USBCMD.RUN = 1 → Controller starten 13. Warten bis USBSTS.HCH = 0 14. Ports scannen (→ Abschnitt 6) **Wichtig:** Alle Ring-Puffer müssen physisch kontiguös und auf 64 Bytes aligned sein. Der Treiber nutzt den Kernel-PMM direkt (kein VFS-Alloc). ---- ===== 6. Port-Management & Geräteerkennung ===== ==== Port-Register-Offsets ==== Jeder Port hat einen 16-Byte-Block ab OpRegs + 0x400: con XHCI_PORT_BASE : int64 := 0x400; // Offset in OpRegs con XHCI_PORT_STRIDE : int64 := 16; // Bytes pro Port // Innerhalb eines Port-Blocks: con XHCI_PORT_SC : int64 := 0; // Port-Status-and-Control (uint32) con XHCI_PORT_PMSC : int64 := 4; // Port-Power-Management-Status-and-Control con XHCI_PORT_LI : int64 := 8; // Port-Link-Info con XHCI_PORT_HLPMC : int64 := 12; // Port-Hardware-LPM-Control // PORTSC-Bits con XHCI_PORTSC_CCS : int64 := 1; // Current Connect Status con XHCI_PORTSC_PED : int64 := 2; // Port Enabled/Disabled con XHCI_PORTSC_PR : int64 := 0x10; // Port Reset con XHCI_PORTSC_PLS : int64 := 0x1E0; // Port-Link-State (Bits[8:5]) con XHCI_PORTSC_PP : int64 := 0x200; // Port Power con XHCI_PORTSC_SPD : int64 := 0x3C00; // Port-Speed (Bits[13:10]) con XHCI_PORTSC_PRC : int64 := 0x200000; // Port-Reset-Change (quittieren) ==== Geräte-Enumeration (pro Port) ==== 1. PORTSC.CCS prüfen → Gerät angeschlossen? 2. PORTSC.PR = 1 setzen → Port-Reset 3. Warten auf PORTSC.PRC = 1 (Reset abgeschlossen), dann quittieren 4. PORTSC.SPD lesen → Geschwindigkeit bestimmen 5. Command: ENABLE_SLOT → Slot-ID erhalten 6. Input-Context allozieren, Slot-Context befüllen (Port, Geschwindigkeit) 7. Control-Endpoint-0-Context befüllen (MaxPacketSize nach Speed) 8. DCBAA[slot_id] = Output-Context-Adresse 9. Command: ADDRESS_DEVICE (BSR=1 = Block Set Address Request für ersten Get-Descriptor) 10. Control-Transfer: GET_DESCRIPTOR (Device, 8 Bytes) → bMaxPacketSize0 lesen 11. Command: ADDRESS_DEVICE (BSR=0) → SET_ADDRESS automatisch vom HC 12. Control-Transfer: GET_DESCRIPTOR (Device, 18 Bytes) → VID/PID, Class, Configs 13. Gerät in interner Tabelle eintragen (vid, pid, slot_id, port) ---- ===== 7. Transfer-Mechanismus ===== ==== 7.1 Transfer-Ringe ==== Jeder aktive Endpoint hat einen eigenen Transfer-Ring (TR). Der TR ist ein zirkulärer Puffer aus TRBs, abgeschlossen durch einen LINK-TRB der zurück auf den Ring-Anfang zeigt. Consumer: XHCI-Hardware liest TRBs vom Dequeue-Pointer Producer: Treiber schreibt TRBs ab Enqueue-Pointer Cycle-Bit (C): unterscheidet alte von neuen TRBs (toggelt bei jedem Rindumlauf) ==== 7.2 Control Transfer ==== Ein Control-Transfer besteht aus 3 TRBs (Setup → Data → Status): // 1. Setup-TRB (TRB_SETUP) // Parameter[0..7] = 8-Byte-USB-Setup-Packet (bmReqType, bReq, wVal, wIdx, wLen) // Status: Bits[16:0] = 8 (Länge des Setup-Packets) // Control: TRB_SETUP | IDT=1 (Immediate Data) | TRT (Transfer Type: 2=OUT, 3=IN) // 2. Data-TRB (TRB_DATA) — optional, nur wenn wLength > 0 // Parameter = physische Adresse des Datenpuffers // Status: Bits[16:0] = wLength // Control: TRB_DATA | DIR=1 wenn IN | IOC=1 // 3. Status-TRB (TRB_STATUS) // Control: TRB_STATUS | DIR (umgekehrt zur Data-Phase) | IOC=1 ==== 7.3 Bulk / Interrupt Transfer ==== Einzelner NORMAL-TRB (oder Kette via Chain-Bit für >64 KB): // Normal-TRB (TRB_NORMAL) // Parameter = physische Adresse des Datenpuffers // Status: Bits[16:0] = Byte-Count, Bits[31:22] = Interrupter-Target (0) // Control: TRB_NORMAL | IOC=1 Nach dem Schreiben des TRB: **Doorbell klingeln** (poke32 auf DB[slot_id], EP-Index). ==== 7.4 Completion-Event abwarten ==== 1. ERDP aus IR[0] lesen (aktueller Dequeue-Pointer) 2. Auf TRB_XFER_EVENT oder TRB_CMD_COMPL warten: - Cycle-Bit am aktuellen ERDP muss gleich dem Producer-Cycle-Bit sein - Event-TRB enthält: Completion-Code (Bits[31:24] in Status), Slot-ID, EP-Index 3. ERDP um XHCI_TRB_SIZE vorwärtssetzen (mit HC-Handshake-Bit = 1) 4. IMOD-Timer zurücksetzen (IMAN.IP = 1 schreiben) **Completion-Codes:** ^ Code ^ Wert ^ Bedeutung ^ | ''CC_SUCCESS'' | 1 | Transfer erfolgreich | | ''CC_DATA_BUFFER_ERROR'' | 2 | DMA-Fehler | | ''CC_BABBLE_DETECTED'' | 3 | Gerät sendet zu viele Daten | | ''CC_USB_TRANSACTION_ERROR'' | 4 | USB-Bus-Fehler (CRC, Timeout) | | ''CC_TRB_ERROR'' | 5 | Ungültiger TRB | | ''CC_STALL_ERROR'' | 6 | Endpoint STALL | | ''CC_SHORT_PACKET'' | 13 | Weniger Daten als angefordert (kein Fehler) | | ''CC_STOPPED'' | 26 | Transfer durch ''STOP_ENDPOINT''-Command gestoppt | con XHCI_CC_SUCCESS : int64 := 1; con XHCI_CC_TRB_ERROR : int64 := 5; con XHCI_CC_STALL : int64 := 6; con XHCI_CC_SHORT : int64 := 13; ---- ===== 8. Ring-3-Syscall-Binding ===== Die USB-Syscall-Nummern sind noch **nicht vergeben**. Syscalls 150–155 sind belegt: ^ Syscall-Nr ^ Belegt durch ^ | 150 | ''sys_win_get_title'' (WP27) | | 151 | ''sys_win_get_geom'' (WP29) | | 152 | ''sys_win_get_pid'' (WP29) | | 153 | ''sys_ramdisk_create'' (WP30) → [[lyxos:ramdisk|RAM-Disk]] | | 154 | ''sys_ramdisk_fmt'' (WP30) → [[lyxos:ramdisk|RAM-Disk]] | | 155 | ''sys_mkfs_iofs'' (WP01+WP09) → [[lyxos:iofs|IOFS]] | Die geplante USB-Ring-3-Schnittstelle wird im XHCI-WP auf freien Nummern ab 156+ definiert: ^ Geplante Funktion ^ Treiber-Funktion ^ Bemerkung ^ | ''sys_usb_enum'' (TBD) | ''XhciEnumDevices(buf, max)'' | Geräteliste in Ring-3-Puffer kopieren | | ''sys_usb_open'' (TBD) | ''XhciOpenByVidPid(vid, pid)'' | Gerät per VID/PID öffnen → ''usb_fd'' | | ''sys_usb_ctrl'' (TBD) | ''XhciControlTransfer(slot, setup, data, len)'' | Control Transfer mit Bounce-Buffer | | ''sys_usb_bulk'' (TBD) | ''XhciBulkTransfer(slot, ep, buf, len)'' | Bulk Transfer via DMA | | ''sys_usb_intr_read'' (TBD) | ''XhciIntrRead(slot, ep, buf, len)'' | Interrupt-Endpoint, blockierend | | ''sys_usb_close'' (TBD) | ''XhciClose(slot)'' | ''DISABLE_SLOT'' + Tabellenplatz freigeben | **Bounce-Buffer-Strategie:** Control-Transfers nutzen einen kleinen Kernel-seitigen Puffer (max. 4096 Bytes), der sicher ins Ring-3-VA zurückkopiert wird. Bulk/Interrupt nutzen direkte DMA auf die physische Adresse des Ring-3-Puffers (Boundary: Ring-3-Seiten müssen im PMM bekannt sein). ---- ===== 9. Interne Gerätetabelle ===== Der Treiber hält eine statische Tabelle für max. 32 gleichzeitig angeschlossene Geräte: // Eintrag: 64 Bytes // +0 vid (int64) // +8 pid (int64) // +16 slot_id (int64) — XHCI-Slot (1–MaxSlots) // +24 port (int64) — Root-Hub-Port-Nummer // +32 speed (int64) — XHCI_SPEED_* // +40 ep0_ring (int64) — physische Adresse des EP0-Transfer-Rings // +48 state (int64) — 0=frei, 1=aktiv, 2=error // +56 (reserviert) con XHCI_DEV_ENTRY_SIZE : int64 := 64; con XHCI_MAX_DEVICES : int64 := 32; ---- ===== 10. Hinweise ===== * **Physisch kontiguöser Speicher:** Alle XHCI-Datenstrukturen (Ringe, Contexts, ERST, DCBAA) müssen physisch kontiguös liegen — kein VFS-Alloc, direkter PMM-Aufruf (''PmmAllocContig''). * **Alignment:** DCBAA muss 64-byte-aligned sein, Ringe und Contexts ebenfalls 64-byte-aligned; Input-Context sogar 16-byte-aligned nach Spec §6.2.5. * **Scratchpad Buffers:** Wenn ''HCSPARAMS2.MaxScratchpadBufs > 0'', muss der Treiber entsprechend viele 4K-Seiten allozieren und deren Adressen in ein Array schreiben — Slot-0 des DCBAA zeigt auf dieses Array. * **Speed-abhängige MaxPacketSize für EP0:** FS=64, LS=8, HS=64, SS=512. * **USB-2-Ports hinter einem Companion-Controller:** Manche Boards haben EHCI + XHCI parallel. Prüfe HCCPARAMS1.AC64 und Extended Capability List (''HCCPARAMS1 >> 16'' × 4 = Offset der Ext-Cap-Liste) für USB2-Port-Mapping. * **Polling vs. Interrupt:** Im Kernel läuft der Treiber zunächst im Polling-Modus (busy-wait auf Event-Ring-Cycle-Bit). IRQ-Binding via ''sys_irq_bind'' wird als Ausbaustufe implementiert. ---- ===== 11. Quelldatei ===== ^ Modul ^ Datei ^ | XHCI-Treiber | ''kernel/xhci.lyx'' | Letzte Aktualisierung: 2026-06-17