996 lines
34 KiB
C
996 lines
34 KiB
C
// USB core declarations shared by bus, class, hub, HID, storage, and xHCI code.
|
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <intrin.h>
|
|
|
|
#include <ntlite/ddk/ddk.h>
|
|
#include <ntlite/ddi/input_device.h>
|
|
#include <ntlite/ddi/io_driver.h>
|
|
#include <ntlite/ddi/pci.h>
|
|
#include <ntlite/status.h>
|
|
#include <ntlite/ddk/debug.h>
|
|
#include <ntlite/ddk/interrupt.h>
|
|
#include <ntlite/ddk/dpc.h>
|
|
#include <ntlite/ddk/irp.h>
|
|
#include <ntlite/ddk/sync.h>
|
|
#include <ntlite/ddk/semaphore.h>
|
|
#include <ntlite/ddk/thread.h>
|
|
#include <ntlite/ddk/memory.h>
|
|
|
|
#ifndef USB_DEBUG_VERBOSE
|
|
#define USB_DEBUG_VERBOSE 0
|
|
#endif
|
|
|
|
#if USB_DEBUG_VERBOSE
|
|
#define UsbTrace DbgPrint
|
|
#else
|
|
// Implements the trace operation.
|
|
static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
|
|
#endif
|
|
|
|
#define PCI_CLASS_SERIAL_BUS 0x0Cu
|
|
#define PCI_SUBCLASS_USB 0x03u
|
|
#define PCI_PROGIF_XHCI 0x30u
|
|
|
|
#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_DISABLE_SLOT 10u
|
|
#define XHCI_TRB_TYPE_ADDRESS_DEVICE 11u
|
|
#define XHCI_TRB_TYPE_CONFIGURE_ENDPOINT 12u
|
|
|
|
#define XHCI_CC_SUCCESS 1u
|
|
#define XHCI_CC_SHORT_PACKET 13u
|
|
|
|
#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_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
|
|
#define USB_DIR_IN 0x80u
|
|
#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
|
|
#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_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
|
|
#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_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_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 {
|
|
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_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;
|
|
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_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* ControllerDevice;
|
|
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;
|
|
uint32_t HcdCompletionCode;
|
|
KSTATUS Status;
|
|
IRP* Irp;
|
|
USB_URB_COMPLETION Complete;
|
|
void* CompleteContext;
|
|
bool Pending;
|
|
bool Cancelled;
|
|
};
|
|
|
|
typedef enum USB_PDO_KIND {
|
|
UsbPdoRootHub = 1,
|
|
UsbPdoDevice = 2,
|
|
UsbPdoInterface = 3,
|
|
} 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;
|
|
bool AbsoluteMouse;
|
|
uint16_t AbsoluteMaxX;
|
|
uint16_t AbsoluteMaxY;
|
|
uint16_t LastAbsoluteX;
|
|
uint16_t LastAbsoluteY;
|
|
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;
|
|
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;
|
|
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];
|
|
|
|
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;
|
|
IO_REMOVE_LOCK MassRemoveLock;
|
|
bool MassRemoveLockReady;
|
|
bool MassSurpriseRemoved;
|
|
bool MassRemoved;
|
|
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 {
|
|
struct XHCI_WAIT_TARGET* Next;
|
|
uint64_t CommandPhys;
|
|
uint64_t TransferPhys;
|
|
uint8_t TransferSlotId;
|
|
uint8_t TransferEndpointId;
|
|
volatile bool CommandMatched;
|
|
volatile bool TransferMatched;
|
|
volatile bool Registered;
|
|
XHCI_COMMAND_RESULT Command;
|
|
XHCI_TRANSFER_RESULT Transfer;
|
|
} XHCI_WAIT_TARGET;
|
|
|
|
typedef struct XHCI_CONTROLLER {
|
|
uint32_t Magic;
|
|
const NTL_DDK* Ddk;
|
|
DEVICE_OBJECT* Fdo;
|
|
DEVICE_OBJECT* Pdo;
|
|
DEVICE_OBJECT* LowerDevice;
|
|
PCI_DEVICE_INFO PciInfo;
|
|
PCI_BAR MmioBar;
|
|
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;
|
|
SPINLOCK WaitLock;
|
|
SPINLOCK CommandLock;
|
|
XHCI_WAIT_TARGET* WaiterList;
|
|
|
|
volatile bool Running;
|
|
|
|
USB_HCD Hcd;
|
|
} XHCI_CONTROLLER;
|
|
|
|
extern DRIVER_OBJECT gUsbStorageDriver;
|
|
extern DRIVER_OBJECT gUsbBusDriver;
|
|
extern DRIVER_OBJECT gUsbCompositeDriver;
|
|
extern DRIVER_OBJECT gUsbHidDriver;
|
|
extern DRIVER_OBJECT gUsbHubDriver;
|
|
extern DRIVER_OBJECT gXhciDriver;
|
|
extern const NTL_DDK* gUsbDdk;
|
|
|
|
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 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);
|
|
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 NTL_DDK* ddk, uint32_t us);
|
|
bool UsbWaitSet32(const NTL_DDK* ddk, volatile uint8_t* base, uint32_t reg, uint32_t mask, uint32_t timeoutUs);
|
|
bool UsbWaitClear32(const NTL_DDK* ddk, volatile uint8_t* base, uint32_t reg, uint32_t mask, uint32_t timeoutUs);
|
|
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 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);
|
|
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 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);
|
|
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);
|
|
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(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(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(USB_STORAGE_EXTENSION* storage);
|
|
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);
|
|
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 XhciStartController(XHCI_CONTROLLER* xhci);
|
|
KSTATUS XhciAddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject);
|
|
KSTATUS XhciDispatchPnp(DEVICE_OBJECT* device, IRP* irp);
|