Files
nt-lite/code/drivers/bus/usb/usb.h
T

594 lines
22 KiB
C

// usb.h - internal USB/xHCI driver interfaces shared across usb.sys translation units.
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <intrin.h>
#include <ntlite/ddi/hal_api.h>
#include <ntlite/ddi/input_device.h>
#include <ntlite/ddi/io_driver.h>
#include <ntlite/status.h>
#include <kernel/ke_debug.h>
#include <kernel/ke_irq.h>
#include <kernel/ke_dpc.h>
#include <kernel/ke_irp.h>
#include <kernel/ke_spinlock.h>
#include <kernel/mm_phys.h>
#include <kernel/mm_virt.h>
#ifndef USB_DEBUG_VERBOSE
#define USB_DEBUG_VERBOSE 0
#endif
#if USB_DEBUG_VERBOSE
#define UsbTrace DbgPrint
#else
static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
#endif
#define PCI_VENDOR_INVALID 0xFFFFu
#define PCI_CLASS_SERIAL_BUS 0x0Cu
#define PCI_SUBCLASS_USB 0x03u
#define PCI_PROGIF_XHCI 0x30u
#define PCI_REG_VENDOR_DEVICE 0x00u
#define PCI_REG_COMMAND 0x04u
#define PCI_REG_CLASS 0x08u
#define PCI_REG_BAR0 0x10u
#define PCI_COMMAND_MEMORY (1u << 1)
#define PCI_COMMAND_MASTER (1u << 2)
#define PCI_COMMAND_INTX_DISABLE (1u << 10)
#define XHCI_CAP_CAPLENGTH 0x00u
#define XHCI_CAP_HCSPARAMS1 0x04u
#define XHCI_CAP_HCSPARAMS2 0x08u
#define XHCI_CAP_HCCPARAMS1 0x10u
#define XHCI_CAP_DBOFF 0x14u
#define XHCI_CAP_RTSOFF 0x18u
#define XHCI_OP_USBCMD 0x00u
#define XHCI_OP_USBSTS 0x04u
#define XHCI_OP_PAGESIZE 0x08u
#define XHCI_OP_DNCTRL 0x14u
#define XHCI_OP_CRCR 0x18u
#define XHCI_OP_DCBAAP 0x30u
#define XHCI_OP_CONFIG 0x38u
#define XHCI_OP_PORT_BASE 0x400u
#define XHCI_OP_PORT_STRIDE 0x10u
#define XHCI_USBCMD_RS (1u << 0)
#define XHCI_USBCMD_HCRST (1u << 1)
#define XHCI_USBCMD_INTE (1u << 2)
#define XHCI_USBCMD_HSEE (1u << 3)
#define XHCI_USBSTS_HCH (1u << 0)
#define XHCI_USBSTS_HSE (1u << 2)
#define XHCI_USBSTS_EINT (1u << 3)
#define XHCI_USBSTS_PCD (1u << 4)
#define XHCI_USBSTS_CNR (1u << 11)
#define XHCI_USBSTS_HCE (1u << 12)
#define XHCI_USBSTS_CLEAR_MASK (XHCI_USBSTS_HSE | XHCI_USBSTS_EINT | \
XHCI_USBSTS_PCD | XHCI_USBSTS_HCE)
#define XHCI_IMAN_IP (1u << 0)
#define XHCI_IMAN_IE (1u << 1)
#define XHCI_PORTSC_CCS (1u << 0)
#define XHCI_PORTSC_PED (1u << 1)
#define XHCI_PORTSC_OCA (1u << 3)
#define XHCI_PORTSC_PR (1u << 4)
#define XHCI_PORTSC_PP (1u << 9)
#define XHCI_PORTSC_SPEED_SHIFT 10u
#define XHCI_PORTSC_SPEED_MASK (0xFu << XHCI_PORTSC_SPEED_SHIFT)
#define XHCI_PORTSC_CSC (1u << 17)
#define XHCI_PORTSC_PEC (1u << 18)
#define XHCI_PORTSC_WRC (1u << 19)
#define XHCI_PORTSC_OCC (1u << 20)
#define XHCI_PORTSC_PRC (1u << 21)
#define XHCI_PORTSC_PLC (1u << 22)
#define XHCI_PORTSC_CEC (1u << 23)
#define XHCI_PORTSC_CHANGE_MASK (XHCI_PORTSC_CSC | XHCI_PORTSC_PEC | \
XHCI_PORTSC_WRC | XHCI_PORTSC_OCC | \
XHCI_PORTSC_PRC | XHCI_PORTSC_PLC | \
XHCI_PORTSC_CEC)
#define XHCI_EXT_CAP_LEGACY 0x01u
#define XHCI_EXT_CAP_PROTOCOL 0x02u
#define XHCI_LEGSUP_BIOS_OWNED (1u << 16)
#define XHCI_LEGSUP_OS_OWNED (1u << 24)
#define XHCI_TRB_TYPE_SHIFT 10u
#define XHCI_TRB_TYPE_MASK 0x3Fu
#define XHCI_TRB_CYCLE (1u << 0)
#define XHCI_TRB_LINK_TC (1u << 1)
#define XHCI_TRB_TYPE_LINK 6u
#define XHCI_TRB_TYPE_NOOP_CMD 23u
#define XHCI_TRB_TYPE_CMD_DONE 33u
#define XHCI_TRB_TYPE_PORT_SC 34u
#define XHCI_TRB_TYPE_TRANSFER 32u
#define XHCI_TRB_TYPE_NORMAL 1u
#define XHCI_TRB_TYPE_SETUP 2u
#define XHCI_TRB_TYPE_DATA 3u
#define XHCI_TRB_TYPE_STATUS 4u
#define XHCI_TRB_TYPE_ENABLE_SLOT 9u
#define XHCI_TRB_TYPE_ADDRESS_DEVICE 11u
#define XHCI_TRB_TYPE_CONFIGURE_ENDPOINT 12u
#define XHCI_CC_SUCCESS 1u
#define XHCI_TRB_ISP (1u << 2)
#define XHCI_TRB_IOC (1u << 5)
#define XHCI_TRB_IDT (1u << 6)
#define XHCI_TRB_DATA_DIR_IN (1u << 16)
#define XHCI_TRB_SETUP_TRT_NONE (0u << 16)
#define XHCI_TRB_SETUP_TRT_IN (3u << 16)
#define XHCI_TRB_STATUS_DIR_IN (1u << 16)
#define XHCI_HCC1_CSZ (1u << 2)
#define XHCI_CONTEXT_ENTRIES(n) ((uint32_t)(n) << 27)
#define XHCI_SLOT_SPEED(s) ((uint32_t)(s) << 20)
#define XHCI_SLOT_ROOT_PORT(p) ((uint32_t)(p) << 16)
#define XHCI_EP_TYPE_CONTROL (4u << 3)
#define XHCI_EP_TYPE_BULK_OUT (2u << 3)
#define XHCI_EP_TYPE_BULK_IN (6u << 3)
#define XHCI_EP_TYPE_INT_IN (7u << 3)
#define XHCI_EP_CERR_3 (3u << 1)
#define XHCI_EP_DCS 1ull
#define USB_REQ_GET_DESCRIPTOR 0x06u
#define USB_REQ_SET_CONFIGURATION 0x09u
#define USB_REQ_SET_IDLE 0x0Au
#define USB_REQ_SET_PROTOCOL 0x0Bu
#define USB_DESC_DEVICE 0x01u
#define USB_DESC_CONFIGURATION 0x02u
#define USB_DESC_INTERFACE 0x04u
#define USB_DESC_ENDPOINT 0x05u
#define USB_DESC_HID 0x21u
#define USB_DESC_CS_INTERFACE 0x24u
#define USB_DIR_OUT 0x00u
#define USB_DIR_IN 0x80u
#define USB_TYPE_STANDARD 0x00u
#define USB_TYPE_CLASS 0x20u
#define USB_RECIP_DEVICE 0x00u
#define USB_RECIP_INTERFACE 0x01u
#define USB_ENDPOINT_DIR_IN 0x80u
#define USB_ENDPOINT_NUMBER_MASK 0x0Fu
#define USB_ENDPOINT_ATTR_TYPE_MASK 0x03u
#define USB_ENDPOINT_TYPE_CONTROL 0x00u
#define USB_ENDPOINT_TYPE_ISOCH 0x01u
#define USB_ENDPOINT_TYPE_BULK 0x02u
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03u
#define USB_CLASS_HID 0x03u
#define USB_CLASS_MASS_STORAGE 0x08u
#define USB_MASS_SUBCLASS_SCSI 0x06u
#define USB_MASS_PROTOCOL_BOT 0x50u
#define USB_HID_SUBCLASS_BOOT 0x01u
#define USB_HID_PROTOCOL_KEYBOARD 0x01u
#define USB_HID_PROTOCOL_MOUSE 0x02u
#define USB_MASS_BOT_CBW_SIGNATURE 0x43425355u
#define USB_MASS_BOT_CSW_SIGNATURE 0x53425355u
#define USB_MASS_BOT_CSW_PASSED 0u
#define USB_MASS_BOT_CSW_FAILED 1u
#define SCSI_TEST_UNIT_READY 0x00u
#define SCSI_REQUEST_SENSE 0x03u
#define SCSI_INQUIRY 0x12u
#define SCSI_READ_10 0x28u
#define SCSI_WRITE_10 0x2Au
#define SCSI_READ_CAPACITY_10 0x25u
#define XHCI_RING_TRBS 256u
#define XHCI_EVENT_TRBS 256u
#define XHCI_DCBAA_ENTRIES 256u
#define XHCI_MMIO_FLOOR_BYTES 0x10000u
#define XHCI_MAX_SCRATCHPADS 1024u
#define XHCI_MAX_TRACKED_SLOTS 64u
#define XHCI_MAX_ROOT_PORTS 255u
#define XHCI_EP0_RING_TRBS 256u
#define XHCI_HID_RING_TRBS 256u
#define XHCI_BULK_RING_TRBS 256u
#define XHCI_MAX_HID_REPORT 16u
#define USB_STORAGE_DMA_PAGES 1u
#define USB_STORAGE_MAX_BYTES (USB_STORAGE_DMA_PAGES * PAGE_SIZE)
#define USB_STORAGE_SECTOR_SIZE 512u
#define USB_MAX_TRACKED_INTERFACES 8u
#define USB_MAX_TRACKED_ENDPOINTS 8u
#pragma pack(push, 1)
typedef struct XHCI_TRB {
uint32_t ParameterLo;
uint32_t ParameterHi;
uint32_t Status;
uint32_t Control;
} XHCI_TRB;
typedef struct XHCI_ERST_ENTRY {
uint64_t RingSegmentBase;
uint32_t RingSegmentSize;
uint32_t Reserved;
} XHCI_ERST_ENTRY;
typedef struct USB_SETUP_PACKET {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} USB_SETUP_PACKET;
typedef struct USB_DEVICE_DESCRIPTOR {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} USB_DEVICE_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} USB_CONFIGURATION_DESCRIPTOR;
typedef struct USB_INTERFACE_DESCRIPTOR {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} USB_INTERFACE_DESCRIPTOR;
typedef struct USB_ENDPOINT_DESCRIPTOR {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} USB_ENDPOINT_DESCRIPTOR;
typedef struct USB_MASS_CBW {
uint32_t Signature;
uint32_t Tag;
uint32_t DataTransferLength;
uint8_t Flags;
uint8_t Lun;
uint8_t CommandBlockLength;
uint8_t CommandBlock[16];
} USB_MASS_CBW;
typedef struct USB_MASS_CSW {
uint32_t Signature;
uint32_t Tag;
uint32_t DataResidue;
uint8_t Status;
} USB_MASS_CSW;
#pragma pack(pop)
typedef struct USB_TRACKED_INTERFACE {
bool Present;
USB_INTERFACE_DESCRIPTOR Descriptor;
uint8_t EndpointCount;
USB_ENDPOINT_DESCRIPTOR Endpoints[USB_MAX_TRACKED_ENDPOINTS];
} USB_TRACKED_INTERFACE;
typedef enum USB_BAR_KIND {
UsbBarNone,
UsbBarIo,
UsbBarMmio
} USB_BAR_KIND;
typedef struct USB_BAR {
USB_BAR_KIND Kind;
uint64_t Base;
uint8_t Index;
} USB_BAR;
typedef struct XHCI_DEVICE {
bool Allocated;
bool Addressed;
uint8_t SlotId;
uint8_t Port;
uint8_t Speed;
uint16_t MaxPacketSize0;
uint16_t VendorId;
uint16_t ProductId;
uint16_t BcdUsb;
uint16_t BcdDevice;
uint8_t DeviceClass;
uint8_t DeviceSubclass;
uint8_t DeviceProtocol;
uint8_t ConfigurationValue;
bool Configured;
uint8_t InterfaceCount;
USB_TRACKED_INTERFACE Interfaces[USB_MAX_TRACKED_INTERFACES];
bool HidCandidate;
bool HidActive;
bool HidKeyboard;
bool HidMouse;
bool HidArmed;
uint8_t HidInterface;
uint8_t HidProtocol;
uint8_t HidEndpointAddress;
uint8_t HidEndpointId;
uint8_t HidInterval;
uint16_t HidMaxPacket;
uint16_t HidReportLength;
uint32_t HidEnqueue;
uint8_t HidCycle;
uint8_t HidLastModifiers;
uint8_t HidLastKeys[6];
uint8_t HidLastButtons;
uint64_t HidLastTrbPhys;
bool MassCandidate;
bool MassActive;
uint8_t MassInterface;
uint8_t MassBulkInAddress;
uint8_t MassBulkOutAddress;
uint8_t MassBulkInEndpointId;
uint8_t MassBulkOutEndpointId;
uint16_t MassBulkInMaxPacket;
uint16_t MassBulkOutMaxPacket;
uint32_t MassInEnqueue;
uint8_t MassInCycle;
uint32_t MassOutEnqueue;
uint8_t MassOutCycle;
uint32_t MassTag;
uint32_t MassBlockSize;
uint64_t MassBlockCount;
DEVICE_OBJECT* MassDeviceObject;
volatile long MassIoBusy;
PHYSICAL_ADDRESS InputContextPhys;
PHYSICAL_ADDRESS DeviceContextPhys;
PHYSICAL_ADDRESS Ep0RingPhys;
PHYSICAL_ADDRESS HidRingPhys;
PHYSICAL_ADDRESS MassInRingPhys;
PHYSICAL_ADDRESS MassOutRingPhys;
PHYSICAL_ADDRESS DescriptorPhys;
PHYSICAL_ADDRESS HidBufferPhys;
PHYSICAL_ADDRESS MassBufferPhys;
uint8_t* InputContext;
uint8_t* DeviceContext;
XHCI_TRB* Ep0Ring;
XHCI_TRB* HidRing;
XHCI_TRB* MassInRing;
XHCI_TRB* MassOutRing;
uint8_t* DescriptorBuffer;
uint8_t* HidBuffer;
uint8_t* MassBuffer;
uint32_t Ep0Enqueue;
uint8_t Ep0Cycle;
} XHCI_DEVICE;
typedef struct XHCI_COMMAND_RESULT {
uint32_t CompletionCode;
uint8_t SlotId;
} XHCI_COMMAND_RESULT;
typedef struct XHCI_TRANSFER_RESULT {
uint32_t CompletionCode;
uint8_t SlotId;
uint8_t EndpointId;
uint32_t Residue;
} XHCI_TRANSFER_RESULT;
typedef struct XHCI_WAIT_TARGET {
uint64_t CommandPhys;
uint64_t TransferPhys;
uint8_t TransferSlotId;
uint8_t TransferEndpointId;
bool CommandMatched;
bool TransferMatched;
XHCI_COMMAND_RESULT Command;
XHCI_TRANSFER_RESULT Transfer;
} XHCI_WAIT_TARGET;
typedef struct XHCI_CONTROLLER {
const HAL_API* Hal;
uint8_t Bus;
uint8_t Dev;
uint8_t Fn;
uint8_t Irq;
bool UsingMsi;
uint64_t MmioPhys;
uint32_t MmioBytes;
volatile uint8_t* Mmio;
volatile uint8_t* Cap;
volatile uint8_t* Op;
volatile uint8_t* Runtime;
volatile uint8_t* Doorbells;
uint8_t CapLength;
uint16_t Version;
uint32_t Hcs1;
uint32_t Hcs2;
uint32_t Hcc1;
uint32_t DbOff;
uint32_t RtsOff;
uint8_t MaxSlots;
uint16_t MaxIntrs;
uint8_t MaxPorts;
uint16_t ScratchpadCount;
uint8_t PortProtocolMajor[XHCI_MAX_ROOT_PORTS + 1u];
uint8_t PortProtocolMinor[XHCI_MAX_ROOT_PORTS + 1u];
PHYSICAL_ADDRESS DcbaaPhys;
PHYSICAL_ADDRESS ScratchpadArrayPhys;
PHYSICAL_ADDRESS ScratchpadPhys[XHCI_MAX_SCRATCHPADS];
PHYSICAL_ADDRESS CommandRingPhys;
PHYSICAL_ADDRESS EventRingPhys;
PHYSICAL_ADDRESS ErstPhys;
uint64_t* Dcbaa;
uint64_t* ScratchpadArray;
XHCI_TRB* CommandRing;
XHCI_TRB* EventRing;
XHCI_ERST_ENTRY* Erst;
uint32_t CommandEnqueue;
uint8_t CommandCycle;
uint32_t EventDequeue;
uint8_t EventCycle;
uint8_t ContextBytes;
XHCI_DEVICE Devices[XHCI_MAX_TRACKED_SLOTS + 1u];
uint32_t HidDeviceCount;
KDPC EventDpc;
volatile bool InterruptsEnabled;
volatile uint32_t InterruptCount;
volatile uint32_t EventDpcCount;
SPINLOCK EventLock;
volatile XHCI_WAIT_TARGET* ActiveWait;
volatile bool Running;
} XHCI_CONTROLLER;
extern XHCI_CONTROLLER gXhci;
extern bool gHaveXhci;
extern DRIVER_OBJECT gUsbStorageDriver;
uint32_t UsbAlignUp32(uint32_t value, uint32_t align);
void XhciBarrier(void);
uint8_t XhciRead8(volatile uint8_t* base, uint32_t reg);
uint16_t XhciRead16(volatile uint8_t* base, uint32_t reg);
uint32_t XhciRead32(volatile uint8_t* base, uint32_t reg);
void XhciWrite32(volatile uint8_t* base, uint32_t reg, uint32_t value);
uint64_t XhciRead64(volatile uint8_t* base, uint32_t reg);
void XhciWrite64(volatile uint8_t* base, uint32_t reg, uint64_t value);
void UsbDelayUs(const HAL_API* hal, uint32_t us);
bool UsbWaitSet32(const HAL_API* hal, volatile uint8_t* base, uint32_t reg, uint32_t mask, uint32_t timeoutUs);
bool UsbWaitClear32(const HAL_API* hal, volatile uint8_t* base, uint32_t reg, uint32_t mask, uint32_t timeoutUs);
bool UsbReadBar(const HAL_API* hal, uint8_t bus, uint8_t dev, uint8_t fn, uint8_t index, USB_BAR* out);
KSTATUS UsbMapMmio(const HAL_API* hal, uint64_t physBase, uint32_t bytes, volatile uint8_t** outMmio);
void* UsbDmaAllocPages(XHCI_CONTROLLER* xhci, size_t pages, PHYSICAL_ADDRESS* outPhys);
uint16_t XhciScratchpadCount(uint32_t hcs2);
uint32_t XhciTrbType(const XHCI_TRB* trb);
uint32_t XhciCompletionCode(const XHCI_TRB* trb);
uint8_t XhciEventSlotId(const XHCI_TRB* trb);
uint8_t XhciEventEndpointId(const XHCI_TRB* trb);
uint32_t XhciTransferResidue(const XHCI_TRB* trb);
uint32_t* XhciInputControlContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
uint32_t* XhciInputSlotContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
uint32_t* XhciInputEndpointContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint8_t endpointId);
uint32_t XhciEpMaxPacket(uint8_t speed);
uint64_t UsbSetupPacketToU64(const USB_SETUP_PACKET* setup);
const char* XhciPortSpeedName(uint32_t speed);
void XhciParseSupportedProtocols(XHCI_CONTROLLER* xhci);
uint8_t XhciPortProtocolMajor(XHCI_CONTROLLER* xhci, uint8_t port, uint32_t portsc);
const char* UsbEndpointTypeName(uint8_t type);
const char* UsbDirectionName(uint8_t endpointAddress);
const char* UsbInterfaceClassName(uint8_t klass, uint8_t subclass, uint8_t proto);
void XhciLogPortStatus(XHCI_CONTROLLER* xhci);
void XhciAckInterrupter0(XHCI_CONTROLLER* xhci);
void XhciUpdateErdp(XHCI_CONTROLLER* xhci);
bool XhciDrainEventRing(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target);
bool XhciDrainEventRingLocked(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target);
bool XhciWaitTargetComplete(const XHCI_WAIT_TARGET* target);
KSTATUS XhciWaitForTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target, uint32_t timeoutUs);
void XhciEventDpcRoutine(KDPC* dpc, void* context, void* systemArgument1, void* systemArgument2);
void XhciIsr(void);
KSTATUS XhciBiosHandoff(XHCI_CONTROLLER* xhci);
KSTATUS XhciStopAndReset(XHCI_CONTROLLER* xhci);
KSTATUS XhciAllocateScratchpads(XHCI_CONTROLLER* xhci);
KSTATUS XhciAllocateRuntimeMemory(XHCI_CONTROLLER* xhci);
KSTATUS XhciProgramRuntime(XHCI_CONTROLLER* xhci);
uint64_t XhciCommandTrbPhys(XHCI_CONTROLLER* xhci, uint32_t index);
KSTATUS XhciSubmitCommand(XHCI_CONTROLLER* xhci, uint64_t parameter, uint32_t status, uint32_t controlWithoutCycle, XHCI_COMMAND_RESULT* outResult);
KSTATUS XhciSubmitNoopCommand(XHCI_CONTROLLER* xhci);
KSTATUS XhciEnableSlot(XHCI_CONTROLLER* xhci, uint8_t* outSlotId);
KSTATUS XhciAddressDevice(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciStart(XHCI_CONTROLLER* xhci);
void XhciEnableInterrupts(XHCI_CONTROLLER* xhci);
uint32_t XhciPortReg(uint8_t port);
void XhciClearPortChanges(XHCI_CONTROLLER* xhci, uint8_t port);
KSTATUS XhciResetPort(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSpeed);
KSTATUS XhciAllocateDeviceMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
void XhciBuildDefaultControlContext(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
uint64_t XhciEp0TrbPhys(XHCI_DEVICE* dev, uint32_t index);
KSTATUS XhciEp0AppendTrb(XHCI_DEVICE* dev, uint64_t parameter, uint32_t status, uint32_t controlWithoutCycle, uint64_t* outPhys);
KSTATUS XhciControlIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_SETUP_PACKET* setup, void* buffer, PHYSICAL_ADDRESS bufferPhys, uint16_t length);
KSTATUS XhciControlNoData(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_SETUP_PACKET* setup);
KSTATUS XhciGetDeviceDescriptor(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_DEVICE_DESCRIPTOR* outDesc);
KSTATUS XhciGetConfigurationDescriptor(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint8_t configurationIndex, USB_CONFIGURATION_DESCRIPTOR* outConfig, uint16_t* outTotalLength);
uint8_t XhciEndpointIdFromAddress(uint8_t endpointAddress);
uint8_t XhciInterruptInterval(uint8_t speed, uint8_t usbInterval);
KSTATUS XhciRingAppend(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, uint32_t trbCount, uint32_t* enqueue, uint8_t* cycle, uint64_t parameter, uint32_t status, uint32_t controlWithoutCycle, uint64_t* outPhys);
bool XhciHidKeyInReport(const uint8_t* keys, uint8_t key);
INPUT_KEY XhciHidModifierKey(uint8_t bit);
void XhciSubmitHidKey(INPUT_KEY key, bool pressed);
void XhciProcessBootKeyboardReport(XHCI_DEVICE* dev, const uint8_t* report, uint16_t len);
void XhciProcessBootMouseReport(XHCI_DEVICE* dev, const uint8_t* report, uint16_t len);
KSTATUS XhciArmHidInterruptIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
void XhciArmAllHid(XHCI_CONTROLLER* xhci);
void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbPhys, uint32_t completionCode, uint8_t slotId, uint8_t endpointId, uint32_t residue);
KSTATUS XhciStartHidInterrupts(XHCI_CONTROLLER* xhci);
KSTATUS XhciSetHidBootProtocol(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciAllocateHidMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciConfigureHidEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
const IO_PUBLISHED_USB_ENDPOINT* UsbFindEndpoint(const IO_PUBLISHED_DEVICE* pub, uint8_t endpointType, bool wantIn);
bool UsbHidMatch(const IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbHidBind(IO_PUBLISHED_DEVICE* pub, void* context);
void XhciInitialiseTransferRing(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, uint32_t trbCount, uint8_t cycle);
KSTATUS XhciBulkTransfer(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint8_t endpointId, XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, uint32_t* enqueue, uint8_t* cycle, PHYSICAL_ADDRESS bufferPhys, uint32_t length, uint32_t* outActual);
KSTATUS UsbStorageBulkIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, PHYSICAL_ADDRESS phys, uint32_t length, uint32_t* outActual);
KSTATUS UsbStorageBulkOut(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, PHYSICAL_ADDRESS phys, uint32_t length, uint32_t* outActual);
KSTATUS UsbStorageBotCommand(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const uint8_t* cdb, uint8_t cdbLen, void* data, PHYSICAL_ADDRESS dataPhys, uint32_t dataLength, bool dataIn);
uint32_t UsbBe32(const uint8_t* p);
void UsbStoreBe32(uint8_t* p, uint32_t v);
void UsbStoreBe16(uint8_t* p, uint16_t v);
KSTATUS UsbStorageInquiry(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS UsbStorageRequestSense(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS UsbStorageTestUnitReady(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS UsbStorageReadCapacity(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS UsbStorageReadWriteSectors(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, bool write, uint64_t lba, uint32_t sectors, void* buffer);
void UsbStorageAcquireIo(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
void UsbStorageReleaseIo(XHCI_DEVICE* dev);
KSTATUS UsbStorageDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp);
KSTATUS XhciAllocateMassStorageMemory(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciConfigureMassStorageEndpoints(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
uint8_t UsbFindFreeDiskIndex(void);
KSTATUS UsbStorageRegisterDisk(XHCI_DEVICE* dev);
bool UsbStorageMatch(const IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbStorageBind(IO_PUBLISHED_DEVICE* pub, void* context);
KSTATUS UsbRegisterClassMatchers(void);
KSTATUS XhciSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint8_t configurationValue);
void XhciLogConfigurationTree(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_CONFIGURATION_DESCRIPTOR* config, uint16_t totalLength);
void XhciPublishUsbInterfaces(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev);
KSTATUS XhciDiscoverAndSetConfiguration(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_DEVICE_DESCRIPTOR* devDesc);
KSTATUS XhciEnumeratePort(XHCI_CONTROLLER* xhci, uint8_t port);
void XhciEnumerateRootPorts(XHCI_CONTROLLER* xhci);
KSTATUS XhciInitialise(const HAL_API* hal, uint8_t bus, uint8_t dev, uint8_t fn, uint16_t vendor, uint16_t device);