22#include "pedigree/kernel/Spinlock.h"
23#include "pedigree/kernel/compiler.h"
24#include "pedigree/kernel/machine/IrqHandler.h"
25#include "pedigree/kernel/machine/types.h"
26#include "pedigree/kernel/process/Mutex.h"
27#include "pedigree/kernel/process/OperationBarrier.h"
28#include "pedigree/kernel/process/OwnedThread.h"
29#include "pedigree/kernel/process/Semaphore.h"
30#include "pedigree/kernel/processor/InterruptHandler.h"
31#include "pedigree/kernel/processor/MemoryRegion.h"
32#include "pedigree/kernel/processor/state_forward.h"
33#include "pedigree/kernel/processor/types.h"
34#include "pedigree/kernel/utilities/ExtensibleBitmap.h"
35#include "pedigree/kernel/utilities/RequestQueue.h"
36#include "pedigree/kernel/utilities/String.h"
40#include "CallbackDelivery.h"
41#include "EhciHandoff.h"
42#include "PortChangeRequest.h"
43#include "TransferCompletion.h"
44#include "modules/system/usb/Usb.h"
45#include "modules/system/usb/UsbHub.h"
69 bool initialiseController();
70 void startFirmwareRecovery();
73 uint32_t bNextInvalid : 1;
76 uint32_t bAltNextInvalid : 1;
78 uint32_t pAltNext : 27;
85 uint32_t bDataToggle : 1;
86 uint32_t nOffset : 12;
105 uint16_t nBufferSize;
117 UsbError getError() {
118 if (nStatus & Halted)
120 return TransactionError;
124 static_assert(
sizeof(
qTD) == 64);
125 static_assert(
alignof(
qTD) == 4);
128 uint32_t bNextInvalid : 1;
129 uint32_t nNextType : 2;
132 uint32_t nAddress : 7;
133 uint32_t bInactiveNext : 1;
134 uint32_t nEndpoint : 4;
136 uint32_t bDataToggleSrc : 1;
138 uint32_t nMaxPacketSize : 11;
139 uint32_t bControlEndpoint : 1;
140 uint32_t nNakReload : 4;
143 uint32_t nHubAddress : 7;
144 uint32_t nHubPort : 7;
155 periodicGeneration(0),
156 periodicFrameIndex(
static_cast<size_t>(-1)),
158 periodicPending(
false),
174 size_t periodicGeneration;
175 size_t periodicFrameIndex;
176 size_t periodicInterval;
177 bool periodicPending;
178 qTD periodicTemplate;
195 static_assert(__builtin_offsetof(
QH, overlay) == 0x10);
197 str.assign(
"EHCI", 5);
201 uintptr_t pBuffer,
size_t nBytes);
205 void (*pCallback)(uintptr_t, ssize_t) = 0,
206 uintptr_t pParam = 0);
209 void (*pCallback)(uintptr_t, ssize_t),
211 uintptr_t pParam = 0);
217 virtual void interrupt(
size_t number, InterruptState& state);
222 virtual bool portReset(uint8_t nPort,
bool bErrorResponse =
false);
225 virtual void cancelAsyncAndDrain(uintptr_t pTransaction,
void (*pCallback)(uintptr_t, ssize_t),
228 void (*callback)(uintptr_t, ssize_t),
230 bool producerAlreadyStopped)
override;
236 virtual uint64_t
executeRequest(uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0,
237 uint64_t p4 = 0, uint64_t p5 = 0, uint64_t p6 = 0,
238 uint64_t p7 = 0, uint64_t p8 = 0);
243 EHCI_CAPLENGTH = 0x00,
244 EHCI_HCIVERSION = 0x02,
245 EHCI_HCSPARAMS = 0x04,
246 EHCI_HCCPARAMS = 0x08,
251 EHCI_CTRLDSEG = 0x10,
253 EHCI_PERIODICLP = 0x14,
258 EHCI_CMD_ASYNCLE = 0x20,
259 EHCI_CMD_PERIODICLE = 0x10,
260 EHCI_CMD_HCRES = 0x02,
263 EHCI_STS_HALTED = 0x1000,
264 EHCI_STS_SYSERR = 0x10,
265 EHCI_STS_ASYNCADVANCE = 0x20,
266 EHCI_STS_PORTCH = 0x4,
270 EHCI_PORTSC_PPOW = 0x1000,
271 EHCI_PORTSC_PRES = 0x100,
272 EHCI_PORTSC_OCCH = 0x20,
273 EHCI_PORTSC_ENCH = 0x8,
274 EHCI_PORTSC_EN = 0x4,
275 EHCI_PORTSC_CSCH = 0x2,
276 EHCI_PORTSC_CONN = 0x1,
281 return value & ~(EHCI_PORTSC_OCCH | EHCI_PORTSC_ENCH | EHCI_PORTSC_CSCH);
284 void modifyPortControl(
size_t portRegister, uint32_t clearMask, uint32_t setMask);
286 uintptr_t createTransactionAdmitted(
UsbEndpoint endpointInfo);
287 void addTransferToTransactionAdmitted(uintptr_t pTransaction,
bool bToggle, UsbPid pid,
288 uintptr_t pBuffer,
size_t nBytes);
289 void releaseQtdChainLocked(QH* qh);
290 void reclaimQhLocked(
size_t transaction);
291 void captureCompletionLocked(
size_t transaction, QH* qh,
295 static void finishDeferredCompletion(
void* context);
296 static void rearmPeriodicCompletion(
void* context);
297 static void destroyPeriodicCompletion(
void* context);
298 void rebuildPeriodicScheduleLocked();
300 bool beginStartupActivity()
override;
301 void endStartupActivity(UsbStartup::Outcome outcome)
override;
302 void completeInitialPort(
size_t port);
303 void shutdownController();
304 bool acquireFirmware(uint16_t capability);
305 void returnToFirmware();
306 static int recoverFirmware(
void* parameter);
309 uint16_t m_FirmwarePciCommand = 0;
310 bool m_ControllerStopped =
false;
311 bool m_HardwareTouched =
false;
314 uint16_t m_InitialPortMask = 0;
320 bool m_HardwareOwned =
false;
322 uint8_t m_nOpRegsOffset;
336 uintptr_t m_pQHListPhys;
339 uint32_t* m_pFrameList;
340 uintptr_t m_pFrameListPhys;
344 uintptr_t m_pqTDListPhys;
349 QH* m_pCurrentQueueTail;
353 QH* m_pCurrentQueueHead;
369 bool m_InterruptHandlerRegistered;
374 void operator=(
const Ehci&);
UsbHcd::CallbackDeliveryQueue m_CompletionDeliveries
MUST_USE_RESULT bool cancelInterruptInAndDrain(const UsbInterruptInToken &token, void(*callback)(uintptr_t, ssize_t), uintptr_t parameter, bool producerAlreadyStopped) override
virtual void getName(String &str)
void replaySuppressedConnectionChange(size_t port) override
IrqDisposition irq(irq_id_t number) override
IRQ handler.
static uint32_t portControlValue(uint32_t value)
virtual void addTransferToTransaction(uintptr_t pTransaction, bool bToggle, UsbPid pid, uintptr_t pBuffer, size_t nBytes)
Adds a new transfer to an existent transaction.
virtual bool portReset(uint8_t nPort, bool bErrorResponse=false)
Gets a UsbDevice from a given vendor:product pair.
virtual MUST_USE_RESULT bool doAsync(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t)=0, uintptr_t pParam=0)
IrqProcessingLock m_IrqProcessingLock
Atomic< size_t > m_InterruptClosure
OperationBarrier m_SubmissionOperations
virtual void cancelAsyncAndDrain(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t), uintptr_t pParam)
virtual uint64_t executeRequest(uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0)
OperationBarrier m_CallbackOperations
OperationBarrier m_CancelOperations
virtual MUST_USE_RESULT bool addInterruptInHandler(UsbEndpoint endpointInfo, uintptr_t pBuffer, uint16_t nBytes, void(*pCallback)(uintptr_t, ssize_t), UsbInterruptInHandle &handle, uintptr_t pParam=0)
Adds an owned recurring interrupt-IN transaction.
void cancelRequest(const Request &request) override
virtual uintptr_t createTransaction(UsbEndpoint endpointInfo)
Creates a new transaction with the given endpoint data.
bool inInterruptCallbackContext() const override
Abstract base class for interrupt-handlers.
Abstrace base class for hardware I/O capabilities.
Special memory entity in the kernel's virtual address space.
static bool isInCallbackContext()