add a realtime scheduler class and priority-inheritance mutexes with timeouts and abandonment, add an HDA audio driver and a SYS_AUDIO_* syscall family, flesh out kernel32 with Win32 threads, events, mutexes, critical sections, and condition variables, add SYS_RESUME_THREAD for suspended thread creation, add KeInitializeMemoryTypes to reprogram MTRRs and install a canonical PAT for WB/WC/UC control, rework the display pipeline with a pitched present path and console output flush, bring back disk.vhd with mtools since vvfat fucking sucks, harden AHCI with serialized cache flush, USB mass storage with SCSI sense-data decoding, and xHCI with cleaner DMA teardown, fix the last stray for(;;) in HalStopProcessor to while(true), pile on smoke tests for audio, win32 sync primitives, and thread suspend, implement AHCI timeout, kill readahead since it was desperetaly trying to murder me, fix doom sound x2.
This commit is contained in:
1 parent
8b254f84f4
commit
4add6789ba
177 files changed
+22565
-3070
No files matched your search
+83
-40
@@ -124,6 +124,7 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
|
||||
#define XHCI_TRB_SETUP_TRT_IN (3u << 16)
|
||||
#define XHCI_TRB_STATUS_DIR_IN (1u << 16)
|
||||
|
||||
#define XHCI_HCC1_AC64 (1u << 0)
|
||||
#define XHCI_HCC1_CSZ (1u << 2)
|
||||
|
||||
#define XHCI_CONTEXT_ENTRIES(n) ((uint32_t)(n) << 27)
|
||||
@@ -199,6 +200,7 @@ static __inline void UsbTrace(const char* fmt, ...) { (void)fmt; }
|
||||
#define SCSI_INQUIRY 0x12u
|
||||
#define SCSI_READ_10 0x28u
|
||||
#define SCSI_WRITE_10 0x2Au
|
||||
#define SCSI_SYNCHRONIZE_CACHE_10 0x35u
|
||||
#define SCSI_READ_CAPACITY_10 0x25u
|
||||
|
||||
#define XHCI_RING_TRBS 256u
|
||||
@@ -393,7 +395,11 @@ typedef struct USB_HCD_OPERATIONS {
|
||||
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);
|
||||
void (*DestroyPipe)(USB_HCD* hcd, USB_PIPE* pipe);
|
||||
void* (*AllocateDma)(USB_HCD* hcd,
|
||||
size_t pages,
|
||||
uint64_t* outDeviceAddress,
|
||||
IO_DMA_BUFFER** outBuffer);
|
||||
} USB_HCD_OPERATIONS;
|
||||
|
||||
struct USB_HCD {
|
||||
@@ -454,7 +460,7 @@ struct USB_URB {
|
||||
USB_PIPE* Pipe;
|
||||
USB_SETUP_PACKET Setup;
|
||||
void* Buffer;
|
||||
PHYSICAL_ADDRESS BufferPhys;
|
||||
uint64_t BufferDeviceAddress;
|
||||
uint32_t Length;
|
||||
uint32_t ActualLength;
|
||||
uint32_t HcdCompletionCode;
|
||||
@@ -521,8 +527,9 @@ typedef struct USB_HUB_EXTENSION {
|
||||
uint32_t PendingHubPorts[1];
|
||||
SPINLOCK PendingLock;
|
||||
SEMAPHORE* WorkerSemaphore;
|
||||
EVENT* WorkerFinished;
|
||||
THREAD* WorkerThread;
|
||||
bool WorkerRunning;
|
||||
volatile bool WorkerRunning;
|
||||
bool InitialScanPending;
|
||||
bool InitialScanComplete;
|
||||
bool InitialScanInProgress;
|
||||
@@ -533,7 +540,8 @@ typedef struct USB_HUB_EXTENSION {
|
||||
uint8_t InterruptInterval;
|
||||
USB_PIPE* InterruptPipe;
|
||||
uint8_t* ChangeBitmap;
|
||||
PHYSICAL_ADDRESS ChangeBitmapPhys;
|
||||
uint64_t ChangeBitmapDeviceAddress;
|
||||
IO_DMA_BUFFER* ChangeBitmapDma;
|
||||
USB_URB ChangeUrb;
|
||||
bool ChangeUrbPending;
|
||||
uint8_t PowerOnToPowerGoodMs;
|
||||
@@ -573,7 +581,8 @@ typedef struct USB_HID_EXTENSION {
|
||||
|
||||
USB_PIPE* InterruptPipe;
|
||||
uint8_t* ReportBuffer;
|
||||
PHYSICAL_ADDRESS ReportBufferPhys;
|
||||
uint64_t ReportBufferDeviceAddress;
|
||||
IO_DMA_BUFFER* ReportBufferDma;
|
||||
uint16_t ReportLength;
|
||||
USB_URB InterruptUrb;
|
||||
bool InterruptPending;
|
||||
@@ -584,6 +593,12 @@ typedef struct USB_HID_EXTENSION {
|
||||
uint32_t InputDeviceId;
|
||||
} USB_HID_EXTENSION;
|
||||
|
||||
typedef enum USB_STORAGE_FLUSH_CAPABILITY {
|
||||
UsbStorageFlushUnknown = 0,
|
||||
UsbStorageFlushSupported,
|
||||
UsbStorageFlushUnsupported,
|
||||
} USB_STORAGE_FLUSH_CAPABILITY;
|
||||
|
||||
typedef enum USB_STORAGE_EXTENSION_KIND {
|
||||
UsbStorageExtensionInterface = 0x55534946u,
|
||||
UsbStorageExtensionDisk = 0x5553444Bu,
|
||||
@@ -620,6 +635,7 @@ struct USB_STORAGE_EXTENSION {
|
||||
uint32_t Tag;
|
||||
uint32_t BlockSize;
|
||||
uint64_t BlockCount;
|
||||
USB_STORAGE_FLUSH_CAPABILITY FlushCapability;
|
||||
volatile long IoBusy;
|
||||
};
|
||||
|
||||
@@ -630,14 +646,15 @@ struct USB_STORAGE_DISK_EXTENSION {
|
||||
|
||||
typedef struct XHCI_PIPE_CONTEXT {
|
||||
XHCI_TRB* Ring;
|
||||
PHYSICAL_ADDRESS RingPhys;
|
||||
uint64_t RingDeviceAddress;
|
||||
IO_DMA_BUFFER* RingDma;
|
||||
uint32_t Enqueue;
|
||||
uint8_t Cycle;
|
||||
uint8_t EndpointId;
|
||||
USB_PIPE_TYPE Type;
|
||||
bool Configured;
|
||||
bool ActiveTransfer;
|
||||
uint64_t ActiveTrbPhys;
|
||||
uint64_t ActiveTrbDeviceAddress;
|
||||
USB_URB* ActiveUrb;
|
||||
} XHCI_PIPE_CONTEXT;
|
||||
|
||||
@@ -683,7 +700,7 @@ typedef struct XHCI_DEVICE {
|
||||
uint8_t HidLastModifiers;
|
||||
uint8_t HidLastKeys[6];
|
||||
uint8_t HidLastButtons;
|
||||
uint64_t HidLastTrbPhys;
|
||||
uint64_t HidLastTrbDeviceAddress;
|
||||
|
||||
bool MassCandidate;
|
||||
bool MassActive;
|
||||
@@ -708,15 +725,25 @@ typedef struct XHCI_DEVICE {
|
||||
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;
|
||||
uint64_t InputContextDeviceAddress;
|
||||
uint64_t DeviceContextDeviceAddress;
|
||||
uint64_t Ep0RingDeviceAddress;
|
||||
uint64_t HidRingDeviceAddress;
|
||||
uint64_t MassInRingDeviceAddress;
|
||||
uint64_t MassOutRingDeviceAddress;
|
||||
uint64_t DescriptorDeviceAddress;
|
||||
uint64_t HidBufferDeviceAddress;
|
||||
uint64_t MassBufferDeviceAddress;
|
||||
|
||||
IO_DMA_BUFFER* InputContextDma;
|
||||
IO_DMA_BUFFER* DeviceContextDma;
|
||||
IO_DMA_BUFFER* Ep0RingDma;
|
||||
IO_DMA_BUFFER* HidRingDma;
|
||||
IO_DMA_BUFFER* MassInRingDma;
|
||||
IO_DMA_BUFFER* MassOutRingDma;
|
||||
IO_DMA_BUFFER* DescriptorDma;
|
||||
IO_DMA_BUFFER* HidBufferDma;
|
||||
IO_DMA_BUFFER* MassBufferDma;
|
||||
|
||||
uint8_t* InputContext;
|
||||
uint8_t* DeviceContext;
|
||||
@@ -746,8 +773,8 @@ typedef struct XHCI_TRANSFER_RESULT {
|
||||
|
||||
typedef struct XHCI_WAIT_TARGET {
|
||||
struct XHCI_WAIT_TARGET* Next;
|
||||
uint64_t CommandPhys;
|
||||
uint64_t TransferPhys;
|
||||
uint64_t CommandDeviceAddress;
|
||||
uint64_t TransferDeviceAddress;
|
||||
uint8_t TransferSlotId;
|
||||
uint8_t TransferEndpointId;
|
||||
volatile bool CommandMatched;
|
||||
@@ -793,12 +820,20 @@ typedef struct XHCI_CONTROLLER {
|
||||
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 DcbaaDeviceAddress;
|
||||
uint64_t ScratchpadArrayDeviceAddress;
|
||||
uint64_t ScratchpadDeviceAddress[XHCI_MAX_SCRATCHPADS];
|
||||
uint64_t CommandRingDeviceAddress;
|
||||
uint64_t EventRingDeviceAddress;
|
||||
uint64_t ErstDeviceAddress;
|
||||
|
||||
IO_DMA_ADAPTER* DmaAdapter;
|
||||
IO_DMA_BUFFER* DcbaaDma;
|
||||
IO_DMA_BUFFER* ScratchpadArrayDma;
|
||||
IO_DMA_BUFFER* ScratchpadDma[XHCI_MAX_SCRATCHPADS];
|
||||
IO_DMA_BUFFER* CommandRingDma;
|
||||
IO_DMA_BUFFER* EventRingDma;
|
||||
IO_DMA_BUFFER* ErstDma;
|
||||
|
||||
uint64_t* Dcbaa;
|
||||
uint64_t* ScratchpadArray;
|
||||
@@ -825,6 +860,7 @@ typedef struct XHCI_CONTROLLER {
|
||||
XHCI_WAIT_TARGET* WaiterList;
|
||||
|
||||
volatile bool Running;
|
||||
bool SurpriseRemoved;
|
||||
|
||||
USB_HCD Hcd;
|
||||
} XHCI_CONTROLLER;
|
||||
@@ -867,7 +903,11 @@ 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);
|
||||
void* UsbAllocateDmaBuffer(USB_DEVICE* dev,
|
||||
size_t pages,
|
||||
uint64_t* outDeviceAddress,
|
||||
IO_DMA_BUFFER** outBuffer);
|
||||
void UsbFreeDmaBuffer(IO_DMA_BUFFER* buffer);
|
||||
KSTATUS UsbDispatchPdoPnp(DEVICE_OBJECT* device, IRP* irp);
|
||||
KSTATUS UsbDispatchInternalDeviceControl(DEVICE_OBJECT* device, IRP* irp);
|
||||
|
||||
@@ -882,7 +922,11 @@ 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);
|
||||
void* UsbDmaAllocPages(XHCI_CONTROLLER* xhci,
|
||||
size_t pages,
|
||||
uint64_t* outDeviceAddress,
|
||||
IO_DMA_BUFFER** outBuffer);
|
||||
void XhciReleaseDeviceDma(XHCI_DEVICE* dev);
|
||||
uint16_t XhciScratchpadCount(uint32_t hcs2);
|
||||
uint32_t XhciTrbType(const XHCI_TRB* trb);
|
||||
uint32_t XhciCompletionCode(const XHCI_TRB* trb);
|
||||
@@ -918,7 +962,7 @@ 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);
|
||||
uint64_t XhciCommandTrbDeviceAddress(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);
|
||||
@@ -931,17 +975,17 @@ 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);
|
||||
uint64_t XhciEp0TrbDeviceAddress(XHCI_DEVICE* dev, uint32_t index);
|
||||
KSTATUS XhciEp0AppendTrb(XHCI_DEVICE* dev, uint64_t parameter, uint32_t status, uint32_t controlWithoutCycle, uint64_t* outDeviceAddress);
|
||||
KSTATUS XhciControlInTimeout(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_SETUP_PACKET* setup, void* buffer, uint64_t bufferDeviceAddress, uint16_t length, uint32_t timeoutUs);
|
||||
KSTATUS XhciControlIn(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, const USB_SETUP_PACKET* setup, void* buffer, uint64_t bufferDeviceAddress, 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);
|
||||
KSTATUS XhciRingAppend(XHCI_TRB* ring, uint64_t ringDeviceAddress, uint32_t trbCount, uint32_t* enqueue, uint8_t* cycle, uint64_t parameter, uint32_t status, uint32_t controlWithoutCycle, uint64_t* outDeviceAddress);
|
||||
bool XhciHidKeyInReport(const uint8_t* keys, uint8_t key);
|
||||
INPUT_KEY XhciHidModifierKey(uint8_t bit);
|
||||
void XhciSubmitHidKey(INPUT_KEY key, bool pressed);
|
||||
@@ -949,24 +993,23 @@ void XhciProcessBootKeyboardReport(XHCI_DEVICE* dev, const uint8_t* report, uint
|
||||
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);
|
||||
void XhciHandleAsyncTransferEvent(XHCI_CONTROLLER* xhci, uint64_t trbDeviceAddress, 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);
|
||||
void XhciInitialiseTransferRing(XHCI_TRB* ring, uint64_t ringDeviceAddress, 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);
|
||||
KSTATUS XhciBulkTransfer(XHCI_CONTROLLER* xhci, XHCI_DEVICE* dev, uint8_t endpointId, XHCI_TRB* ring, uint64_t ringDeviceAddress, uint32_t* enqueue, uint8_t* cycle, uint64_t bufferDeviceAddress, uint32_t length, uint32_t* outActual);
|
||||
KSTATUS UsbStorageBulkIn(USB_STORAGE_EXTENSION* storage, uint64_t deviceAddress, uint32_t length, uint32_t* outActual);
|
||||
KSTATUS UsbStorageBulkOut(USB_STORAGE_EXTENSION* storage, uint64_t deviceAddress, uint32_t length, uint32_t* outActual);
|
||||
KSTATUS UsbStorageBotCommand(USB_STORAGE_EXTENSION* storage, const uint8_t* cdb, uint8_t cdbLen, void* data, uint64_t dataDeviceAddress, 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);
|
||||
|
||||
Reference in new issue
Block a user