usb hubs, hotplug support, unplug support, saving log files to disk, smt

This commit is contained in:
maksw committed 2026-06-09 09:14:24 +02:00
1 parent b838f8d83d
commit 27b31f62b6
39 files changed
+6294 -735

No files matched your search

+440 -16
View File
@@ -16,6 +16,8 @@
#include <kernel/ke_dpc.h>
#include <kernel/ke_irp.h>
#include <kernel/ke_spinlock.h>
#include <kernel/ke_semaphore.h>
#include <kernel/ke_thread.h>
#include <kernel/mm_phys.h>
#include <kernel/mm_virt.h>
@@ -114,6 +116,7 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
#define XHCI_TRB_TYPE_DATA 3u
#define XHCI_TRB_TYPE_STATUS 4u
#define XHCI_TRB_TYPE_ENABLE_SLOT 9u
#define XHCI_TRB_TYPE_DISABLE_SLOT 10u
#define XHCI_TRB_TYPE_ADDRESS_DEVICE 11u
#define XHCI_TRB_TYPE_CONFIGURE_ENDPOINT 12u
@@ -144,10 +147,15 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
#define USB_REQ_SET_CONFIGURATION 0x09u
#define USB_REQ_SET_IDLE 0x0Au
#define USB_REQ_SET_PROTOCOL 0x0Bu
#define USB_REQ_GET_STATUS 0x00u
#define USB_REQ_CLEAR_FEATURE 0x01u
#define USB_REQ_SET_FEATURE 0x03u
#define USB_DESC_DEVICE 0x01u
#define USB_DESC_CONFIGURATION 0x02u
#define USB_DESC_INTERFACE 0x04u
#define USB_DESC_ENDPOINT 0x05u
#define USB_DESC_HUB 0x29u
#define USB_DESC_SUPERSPEED_HUB 0x2Au
#define USB_DESC_HID 0x21u
#define USB_DESC_CS_INTERFACE 0x24u
#define USB_DIR_OUT 0x00u
@@ -155,6 +163,7 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
#define USB_TYPE_STANDARD 0x00u
#define USB_TYPE_CLASS 0x20u
#define USB_RECIP_DEVICE 0x00u
#define USB_RECIP_OTHER 0x03u
#define USB_RECIP_INTERFACE 0x01u
#define USB_ENDPOINT_DIR_IN 0x80u
#define USB_ENDPOINT_NUMBER_MASK 0x0Fu
@@ -165,6 +174,23 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03u
#define USB_CLASS_HID 0x03u
#define USB_CLASS_MASS_STORAGE 0x08u
#define USB_CLASS_HUB 0x09u
#define USB_HUB_PORT_FEAT_CONNECTION 0u
#define USB_HUB_PORT_FEAT_ENABLE 1u
#define USB_HUB_PORT_FEAT_SUSPEND 2u
#define USB_HUB_PORT_FEAT_OVER_CURRENT 3u
#define USB_HUB_PORT_FEAT_RESET 4u
#define USB_HUB_PORT_FEAT_POWER 8u
#define USB_HUB_PORT_FEAT_C_CONNECTION 16u
#define USB_HUB_PORT_FEAT_C_ENABLE 17u
#define USB_HUB_PORT_FEAT_C_RESET 20u
#define USB_HUB_PORT_STATUS_CONNECTION (1u << 0)
#define USB_HUB_PORT_STATUS_ENABLE (1u << 1)
#define USB_HUB_PORT_STATUS_LOW_SPEED (1u << 9)
#define USB_HUB_PORT_STATUS_HIGH_SPEED (1u << 10)
#define USB_HUB_PORT_CHANGE_CONNECTION (1u << 0)
#define USB_HUB_PORT_CHANGE_ENABLE (1u << 1)
#define USB_HUB_PORT_CHANGE_RESET (1u << 4)
#define USB_MASS_SUBCLASS_SCSI 0x06u
#define USB_MASS_PROTOCOL_BOT 0x50u
#define USB_HID_SUBCLASS_BOOT 0x01u
@@ -193,12 +219,22 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
#define XHCI_EP0_RING_TRBS 256u
#define XHCI_HID_RING_TRBS 256u
#define XHCI_BULK_RING_TRBS 256u
#define XHCI_PIPE_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
#define USB_MAX_DEVICE_ID_TEXT 96u
#define USB_MAX_PIPES 32u
#define USB_IOCTL_SUBMIT_URB 0x55534201u /* USB1 */
#define USB_ROOT_HUB_MAX_PORTS XHCI_MAX_ROOT_PORTS
#define USB_EXTERNAL_HUB_MAX_PORTS 31u
#define USB_ROOT_PORT_ENUM_RETRIES 3u
#define USB_XHCI_CONTROL_TIMEOUT_US 1000000u
#define USB_XHCI_ENUM_CONTROL_TIMEOUT_US 120000u
#define USB_HUB_CHANGE_BITMAP_BYTES 8u
#pragma pack(push, 1)
typedef struct XHCI_TRB {
@@ -271,6 +307,21 @@ typedef struct USB_ENDPOINT_DESCRIPTOR {
uint8_t bInterval;
} USB_ENDPOINT_DESCRIPTOR;
typedef struct USB_HUB_DESCRIPTOR {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bNbrPorts;
uint16_t wHubCharacteristics;
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
uint8_t DeviceRemovable[1];
} USB_HUB_DESCRIPTOR;
typedef struct USB_HUB_PORT_STATUS {
uint16_t Status;
uint16_t Change;
} USB_HUB_PORT_STATUS;
typedef struct USB_MASS_CBW {
uint32_t Signature;
uint32_t Tag;
@@ -308,6 +359,309 @@ typedef struct USB_BAR {
uint8_t Index;
} USB_BAR;
typedef enum USB_DEVICE_STATE {
UsbDeviceAttached = 0,
UsbDevicePowered,
UsbDeviceDefault,
UsbDeviceAddressed,
UsbDeviceConfigured,
UsbDeviceSuspended,
UsbDeviceSurpriseRemoved,
UsbDeviceRemoved,
} USB_DEVICE_STATE;
typedef struct USB_PORT_PATH {
uint8_t RootPort;
uint8_t Depth;
uint32_t RouteString;
uint8_t ParentHubSlot;
uint8_t ParentHubPort;
bool BehindHub;
} USB_PORT_PATH;
typedef enum USB_PIPE_TYPE {
UsbPipeControl = 0,
UsbPipeBulk,
UsbPipeInterrupt,
UsbPipeIsochronous,
} USB_PIPE_TYPE;
typedef enum USB_TRANSFER_DIRECTION {
UsbTransferNoData = 0,
UsbTransferOut,
UsbTransferIn,
} USB_TRANSFER_DIRECTION;
typedef enum USB_URB_FUNCTION {
UrbFunctionControlTransfer = 0,
UrbFunctionBulkTransfer,
UrbFunctionInterruptTransfer,
UrbFunctionSelectConfiguration,
UrbFunctionSelectInterface,
UrbFunctionResetPipe,
UrbFunctionAbortPipe,
} USB_URB_FUNCTION;
typedef struct USB_HCD USB_HCD;
typedef struct USB_DEVICE USB_DEVICE;
typedef struct USB_PIPE USB_PIPE;
typedef struct USB_URB USB_URB;
typedef struct XHCI_DEVICE XHCI_DEVICE;
typedef void (*USB_URB_COMPLETION)(USB_URB* urb, void* context);
typedef struct USB_HCD_OPERATIONS {
KSTATUS (*SubmitUrb)(USB_HCD* hcd, USB_URB* urb);
KSTATUS (*CancelUrb)(USB_HCD* hcd, USB_URB* urb);
KSTATUS (*ResetRootPort)(USB_HCD* hcd, uint8_t port, uint8_t* outSpeed);
KSTATUS (*ClearRootPortChanges)(USB_HCD* hcd, uint8_t port);
void* (*AllocateDma)(USB_HCD* hcd, size_t pages, PHYSICAL_ADDRESS* outPhys);
} USB_HCD_OPERATIONS;
struct USB_HCD {
const USB_HCD_OPERATIONS* Operations;
void* ControllerContext;
DRIVER_OBJECT* DriverObject;
DEVICE_OBJECT* ControllerPdo;
DEVICE_OBJECT* RootHubPdo;
void* RootHubContext;
uint8_t ControllerIndex;
uint8_t MaxRootPorts;
};
struct USB_DEVICE {
OBJECT Header;
USB_HCD* Hcd;
DEVICE_OBJECT* Pdo;
void* HcdDeviceContext;
USB_DEVICE_STATE State;
USB_PORT_PATH Path;
uint8_t Address;
uint8_t SlotId;
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;
IO_REMOVE_LOCK RemoveLock;
bool RemoveLockReady;
};
struct USB_PIPE {
OBJECT Header;
USB_DEVICE* Device;
USB_PIPE_TYPE Type;
uint8_t EndpointAddress;
uint8_t EndpointId;
uint16_t MaxPacketSize;
uint8_t Interval;
bool Open;
bool Halted;
void* HcdPipeContext;
};
struct USB_URB {
LIST_ENTRY Link;
USB_URB_FUNCTION Function;
USB_TRANSFER_DIRECTION Direction;
USB_DEVICE* Device;
USB_PIPE* Pipe;
USB_SETUP_PACKET Setup;
void* Buffer;
PHYSICAL_ADDRESS BufferPhys;
uint32_t Length;
uint32_t ActualLength;
KSTATUS Status;
IRP* Irp;
USB_URB_COMPLETION Complete;
void* CompleteContext;
bool Pending;
bool Cancelled;
};
typedef enum USB_PDO_KIND {
UsbPdoController = 1,
UsbPdoDevice = 2,
UsbPdoInterface = 3,
UsbPdoRootHub = 4,
} USB_PDO_KIND;
typedef struct USB_PDO_EXTENSION {
USB_PDO_KIND Kind;
USB_HCD* Hcd;
USB_DEVICE* Device;
uint8_t InterfaceIndex;
USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
uint8_t EndpointCount;
USB_ENDPOINT_DESCRIPTOR Endpoints[USB_MAX_TRACKED_ENDPOINTS];
} USB_PDO_EXTENSION;
typedef enum USB_HUB_KIND {
UsbHubKindRoot = 1,
UsbHubKindExternal = 2,
} USB_HUB_KIND;
typedef enum USB_HUB_PORT_STATE {
UsbHubPortDisconnected = 0,
UsbHubPortPowered,
UsbHubPortConnectedDebounce,
UsbHubPortResetting,
UsbHubPortEnabled,
UsbHubPortEnumerating,
UsbHubPortChildPresent,
UsbHubPortFailedConnected,
UsbHubPortRemoving,
} USB_HUB_PORT_STATE;
typedef struct USB_HUB_EXTENSION {
DEVICE_OBJECT* Self;
DEVICE_OBJECT* LowerDevice;
DEVICE_OBJECT* HubPdo;
USB_HUB_KIND Kind;
USB_HCD* Hcd;
USB_DEVICE* Device;
IO_REMOVE_LOCK RemoveLock;
bool RemoveLockReady;
bool Started;
bool SurpriseRemoved;
bool Removed;
uint8_t PortCount;
uint8_t RootPortSlot[USB_ROOT_HUB_MAX_PORTS + 1u];
uint8_t RootPortFailCount[USB_ROOT_HUB_MAX_PORTS + 1u];
USB_HUB_PORT_STATE RootPortState[USB_ROOT_HUB_MAX_PORTS + 1u];
uint8_t ChildSlot[USB_EXTERNAL_HUB_MAX_PORTS + 1u];
USB_HUB_PORT_STATE ChildPortState[USB_EXTERNAL_HUB_MAX_PORTS + 1u];
uint32_t PendingRootPorts[8];
uint32_t PendingHubPorts[1];
SPINLOCK PendingLock;
SEMAPHORE* WorkerSemaphore;
THREAD* WorkerThread;
bool WorkerRunning;
bool InitialScanPending;
bool InitialScanComplete;
bool InitialScanInProgress;
uint8_t InterfaceNumber;
uint8_t InterruptEndpointAddress;
uint16_t InterruptMaxPacket;
uint8_t InterruptInterval;
USB_PIPE* InterruptPipe;
uint8_t* ChangeBitmap;
PHYSICAL_ADDRESS ChangeBitmapPhys;
USB_URB ChangeUrb;
bool ChangeUrbPending;
uint8_t PowerOnToPowerGoodMs;
} USB_HUB_EXTENSION;
typedef struct USB_COMPOSITE_EXTENSION {
DEVICE_OBJECT* Self;
DEVICE_OBJECT* LowerDevice;
DEVICE_OBJECT* DevicePdo;
USB_DEVICE* Device;
bool Started;
bool InterfacesCreated;
} USB_COMPOSITE_EXTENSION;
typedef struct USB_HID_EXTENSION {
DEVICE_OBJECT* Self;
DEVICE_OBJECT* LowerDevice;
DEVICE_OBJECT* InterfacePdo;
USB_DEVICE* Device;
IO_REMOVE_LOCK RemoveLock;
bool RemoveLockReady;
bool Started;
bool SurpriseRemoved;
bool Removed;
bool Keyboard;
bool Mouse;
uint8_t InterfaceNumber;
uint8_t Protocol;
uint8_t EndpointAddress;
uint16_t MaxPacketSize;
uint8_t Interval;
USB_PIPE* InterruptPipe;
uint8_t* ReportBuffer;
PHYSICAL_ADDRESS ReportBufferPhys;
uint16_t ReportLength;
USB_URB InterruptUrb;
bool InterruptPending;
uint8_t LastModifiers;
uint8_t LastKeys[6];
uint8_t LastButtons;
uint32_t InputDeviceId;
} USB_HID_EXTENSION;
typedef enum USB_STORAGE_EXTENSION_KIND {
UsbStorageExtensionInterface = 0x55534946u,
UsbStorageExtensionDisk = 0x5553444Bu,
} USB_STORAGE_EXTENSION_KIND;
typedef struct USB_STORAGE_EXTENSION USB_STORAGE_EXTENSION;
typedef struct USB_STORAGE_DISK_EXTENSION USB_STORAGE_DISK_EXTENSION;
struct USB_STORAGE_EXTENSION {
USB_STORAGE_EXTENSION_KIND Kind;
DEVICE_OBJECT* Self;
DEVICE_OBJECT* LowerDevice;
DEVICE_OBJECT* InterfacePdo;
DEVICE_OBJECT* DiskDevice;
USB_DEVICE* Device;
XHCI_DEVICE* XhciDevice;
USB_PIPE* BulkInPipe;
USB_PIPE* BulkOutPipe;
IO_REMOVE_LOCK RemoveLock;
bool RemoveLockReady;
bool Started;
bool SurpriseRemoved;
bool Removed;
uint8_t InterfaceNumber;
uint8_t BulkInAddress;
uint8_t BulkOutAddress;
uint16_t BulkInMaxPacket;
uint16_t BulkOutMaxPacket;
uint32_t Tag;
uint32_t BlockSize;
uint64_t BlockCount;
volatile long IoBusy;
};
struct USB_STORAGE_DISK_EXTENSION {
USB_STORAGE_EXTENSION_KIND Kind;
USB_STORAGE_EXTENSION* Storage;
};
typedef struct XHCI_PIPE_CONTEXT {
XHCI_TRB* Ring;
PHYSICAL_ADDRESS RingPhys;
uint32_t Enqueue;
uint8_t Cycle;
uint8_t EndpointId;
USB_PIPE_TYPE Type;
bool Configured;
bool ActiveTransfer;
uint64_t ActiveTrbPhys;
USB_URB* ActiveUrb;
} XHCI_PIPE_CONTEXT;
typedef struct XHCI_DEVICE {
bool Allocated;
bool Addressed;
@@ -324,6 +678,11 @@ typedef struct XHCI_DEVICE {
uint8_t DeviceProtocol;
uint8_t ConfigurationValue;
bool Configured;
USB_DEVICE* UsbDevice;
DEVICE_OBJECT* UsbPdo;
DEVICE_OBJECT* ParentDeviceObject;
USB_PORT_PATH Path;
USB_PIPE* EndpointPipes[32];
uint8_t InterfaceCount;
USB_TRACKED_INTERFACE Interfaces[USB_MAX_TRACKED_INTERFACES];
@@ -364,6 +723,10 @@ typedef struct XHCI_DEVICE {
uint32_t MassBlockSize;
uint64_t MassBlockCount;
DEVICE_OBJECT* MassDeviceObject;
IO_REMOVE_LOCK MassRemoveLock;
bool MassRemoveLockReady;
bool MassSurpriseRemoved;
bool MassRemoved;
volatile long MassIoBusy;
PHYSICAL_ADDRESS InputContextPhys;
@@ -403,12 +766,14 @@ typedef struct XHCI_TRANSFER_RESULT {
} XHCI_TRANSFER_RESULT;
typedef struct XHCI_WAIT_TARGET {
struct XHCI_WAIT_TARGET* Next;
uint64_t CommandPhys;
uint64_t TransferPhys;
uint8_t TransferSlotId;
uint8_t TransferEndpointId;
bool CommandMatched;
bool TransferMatched;
volatile bool CommandMatched;
volatile bool TransferMatched;
volatile bool Registered;
XHCI_COMMAND_RESULT Command;
XHCI_TRANSFER_RESULT Transfer;
} XHCI_WAIT_TARGET;
@@ -470,15 +835,58 @@ typedef struct XHCI_CONTROLLER {
volatile uint32_t InterruptCount;
volatile uint32_t EventDpcCount;
SPINLOCK EventLock;
SPINLOCK WaitLock;
SPINLOCK CommandLock;
XHCI_WAIT_TARGET* WaiterList;
volatile XHCI_WAIT_TARGET* ActiveWait;
volatile bool Running;
USB_HCD Hcd;
} XHCI_CONTROLLER;
extern XHCI_CONTROLLER gXhci;
extern bool gHaveXhci;
extern DRIVER_OBJECT gUsbStorageDriver;
extern DRIVER_OBJECT gUsbBusDriver;
extern DRIVER_OBJECT gUsbCompositeDriver;
extern DRIVER_OBJECT gUsbHidDriver;
extern DRIVER_OBJECT gUsbHubDriver;
KSTATUS UsbInitializeBusModel(void);
KSTATUS UsbInitializeCompositeDriver(void);
KSTATUS UsbInitializeHidDriver(void);
KSTATUS UsbInitializeStorageDriver(void);
KSTATUS UsbInitializeHubDriver(void);
KSTATUS UsbCompositeAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject);
KSTATUS UsbCompositeDispatchPnp(DEVICE_OBJECT* device, IRP* irp);
void UsbInitializeHcd(USB_HCD* hcd,
const USB_HCD_OPERATIONS* ops,
void* controllerContext,
uint8_t controllerIndex,
uint8_t maxRootPorts);
KSTATUS UsbCreateControllerPdo(USB_HCD* hcd, uint16_t vendor, uint16_t device);
KSTATUS UsbCreateRootHubPdo(USB_HCD* hcd);
KSTATUS UsbRemoveDeviceObjectChildren(DEVICE_OBJECT* parent, bool surprise);
KSTATUS UsbRemovePdoSubtree(DEVICE_OBJECT* pdo, bool surprise);
KSTATUS UsbCreateDevicePdo(USB_HCD* hcd, XHCI_DEVICE* xhciDev, DEVICE_OBJECT* parent);
KSTATUS UsbCreateInterfacePdos(USB_HCD* hcd, XHCI_DEVICE* xhciDev, DEVICE_OBJECT* parent);
KSTATUS UsbCreatePipe(USB_DEVICE* dev,
USB_PIPE_TYPE type,
uint8_t endpointAddress,
uint16_t maxPacketSize,
uint8_t interval,
USB_PIPE** outPipe);
void UsbReferenceDevice(USB_DEVICE* dev);
void UsbDereferenceDevice(USB_DEVICE* dev);
void UsbReferencePipe(USB_PIPE* pipe);
void UsbDereferencePipe(USB_PIPE* pipe);
KSTATUS UsbSubmitUrbSync(DEVICE_OBJECT* target, USB_URB* urb);
KSTATUS UsbSubmitUrbAsync(DEVICE_OBJECT* target, USB_URB* urb);
KSTATUS UsbCancelUrb(USB_URB* urb);
void* UsbAllocateDmaBuffer(USB_DEVICE* dev, size_t pages, PHYSICAL_ADDRESS* outPhys);
KSTATUS UsbDispatchPdoPnp(DEVICE_OBJECT* device, IRP* irp);
KSTATUS UsbDispatchInternalDeviceControl(DEVICE_OBJECT* device, IRP* irp);
uint32_t UsbAlignUp32(uint32_t value, uint32_t align);
void XhciBarrier(void);
@@ -512,11 +920,15 @@ 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 XhciPowerRootPorts(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);
void XhciRegisterWaitTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target);
void XhciUnregisterWaitTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target);
KSTATUS XhciWaitForArmedTarget(XHCI_CONTROLLER* xhci, XHCI_WAIT_TARGET* target, uint32_t timeoutUs);
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);
@@ -535,12 +947,15 @@ 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 XhciDisableSlot(XHCI_CONTROLLER* xhci, uint8_t slotId);
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 XhciControlInTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_SETUP_PACKET* setup, void* buffer, PHYSICAL_ADDRESS bufferPhys, uint16_t length, uint32_t timeoutUs);
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 XhciGetDeviceDescriptorTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_DEVICE_DESCRIPTOR* outDesc, uint32_t timeoutUs);
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);
@@ -561,33 +976,42 @@ 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);
KSTATUS UsbHidAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject);
KSTATUS UsbHidDispatchPnp(DEVICE_OBJECT* device, IRP* irp);
void XhciInitialiseTransferRing(XHCI_TRB* ring, PHYSICAL_ADDRESS ringPhys, uint32_t trbCount, uint8_t cycle);
KSTATUS XhciConfigurePipeEndpoint(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, USB_PIPE* pipe);
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);
KSTATUS UsbStorageBulkIn(USB_STORAGE_EXTENSION* storage, PHYSICAL_ADDRESS phys, uint32_t length, uint32_t* outActual);
KSTATUS UsbStorageBulkOut(USB_STORAGE_EXTENSION* storage, PHYSICAL_ADDRESS phys, uint32_t length, uint32_t* outActual);
KSTATUS UsbStorageBotCommand(USB_STORAGE_EXTENSION* storage, 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 UsbStorageInquiry(USB_STORAGE_EXTENSION* storage);
KSTATUS UsbStorageRequestSense(USB_STORAGE_EXTENSION* storage);
KSTATUS UsbStorageTestUnitReady(USB_STORAGE_EXTENSION* storage);
KSTATUS UsbStorageReadCapacity(USB_STORAGE_EXTENSION* storage);
KSTATUS UsbStorageReadWriteSectors(USB_STORAGE_EXTENSION* storage, bool write, uint64_t lba, uint32_t sectors, void* buffer);
void UsbStorageAcquireIo(USB_STORAGE_EXTENSION* storage);
void UsbStorageReleaseIo(USB_STORAGE_EXTENSION* storage);
KSTATUS UsbStorageDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp);
KSTATUS UsbStorageDispatchPnp(DEVICE_OBJECT* device, IRP* irp);
KSTATUS UsbStorageAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject);
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);
KSTATUS UsbStorageRegisterDisk(USB_STORAGE_EXTENSION* storage);
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 XhciEnumeratePortEx(XHCI_CONTROLLER* xhci, uint8_t port, uint8_t* outSlotId);
KSTATUS XhciEnumerateHubPortEx(XHCI_CONTROLLER* xhci, USB_HUB_EXTENSION* hub, uint8_t hubPort, uint8_t speed, uint8_t* outSlotId);
KSTATUS XhciEnumeratePort(XHCI_CONTROLLER* xhci, uint8_t port);
void XhciEnumerateRootPorts(XHCI_CONTROLLER* xhci);
KSTATUS UsbHubScheduleRootScan(USB_HCD* hcd);
void UsbHubQueueRootPortChange(USB_HCD* hcd, uint8_t port);
void UsbHubQueueExternalPortChange(USB_HUB_EXTENSION* hub, uint8_t port);
extern const USB_HCD_OPERATIONS gXhciHcdOperations;
KSTATUS XhciInitialise(const HAL_API* hal, uint8_t bus, uint8_t dev, uint8_t fn, uint16_t vendor, uint16_t device);