26#include "pedigree/kernel/Spinlock.h"
27#include "pedigree/kernel/compiler.h"
28#include "pedigree/kernel/machine/IrqHandler.h"
29#include "pedigree/kernel/machine/TimerHandler.h"
30#include "pedigree/kernel/machine/types.h"
31#include "pedigree/kernel/process/Mutex.h"
32#include "pedigree/kernel/process/OperationBarrier.h"
33#include "pedigree/kernel/process/Semaphore.h"
34#include "pedigree/kernel/processor/MemoryRegion.h"
35#include "pedigree/kernel/processor/state_forward.h"
36#include "pedigree/kernel/processor/types.h"
37#include "pedigree/kernel/utilities/ExtensibleBitmap.h"
38#include "pedigree/kernel/utilities/List.h"
39#include "pedigree/kernel/utilities/RequestQueue.h"
40#include "pedigree/kernel/utilities/String.h"
41#include "pedigree/kernel/utilities/new"
43#include "CallbackDelivery.h"
44#include "PortChangeRequest.h"
45#include "TransferCompletion.h"
46#include "modules/system/usb/Usb.h"
47#include "modules/system/usb/UsbHub.h"
58 bool initialised()
const {
63 uint32_t bNextInvalid : 1;
65 uint32_t bNextDepth : 1;
68 uint32_t nActLen : 11;
72 uint32_t bIsochronus : 1;
73 uint32_t bLoSpeed : 1;
78 uint32_t nAddress : 7;
79 uint32_t nEndpoint : 4;
80 uint32_t bDataToggle : 1;
82 uint32_t nMaxLen : 11;
87 bool bShortTransferTD;
99 inline UsbError getError() {
102 else if (nStatus & Nak)
104 else if (nStatus & Babble)
106 else if (nStatus & Timeout)
109 return TransactionError;
114 uint32_t bNextInvalid : 1;
115 uint32_t bNextQH : 1;
118 uint32_t bElemInvalid : 1;
119 uint32_t bElemQH : 1;
125 void (*pPeriodicCallback)(uintptr_t, ssize_t);
126 uintptr_t pPeriodicParam;
127 size_t periodicGeneration;
128 size_t periodicInterval;
129 size_t periodicBusTime;
130 bool periodicPending;
155 str.assign(
"UHCI", 5);
159 uintptr_t pBuffer,
size_t nBytes);
163 void (*pCallback)(uintptr_t, ssize_t) = 0,
164 uintptr_t pParam = 0);
167 void (*pCallback)(uintptr_t, ssize_t),
169 uintptr_t pParam = 0);
177 void timer(uint64_t delta);
179 virtual bool portReset(uint8_t nPort,
bool bErrorResponse =
false);
182 virtual void cancelAsyncAndDrain(uintptr_t pTransaction,
void (*pCallback)(uintptr_t, ssize_t),
185 void (*callback)(uintptr_t, ssize_t),
187 bool producerAlreadyStopped)
override;
194 virtual uint64_t
executeRequest(uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0,
195 uint64_t p4 = 0, uint64_t p5 = 0, uint64_t p6 = 0,
196 uint64_t p7 = 0, uint64_t p8 = 0);
200 bool doAsyncOwned(uintptr_t transaction,
void (*callback)(uintptr_t, ssize_t),
202 size_t interruptGeneration);
206 static void rearmPeriodicCompletion(
void* context);
207 static void destroyPeriodicCompletion(
void* context);
229 void modifyPortControl(
size_t portRegister, uint16_t clearMask, uint16_t setMask);
239 UHCI_CMD_GRES = 0x04,
240 UHCI_CMD_HCRES = 0x02,
243 UHCI_STS_HALT = 0x20,
247 UHCI_PORTSC_PRES = 0x200,
248 UHCI_PORTSC_LOSPEED = 0x100,
249 UHCI_PORTSC_EDCH = 0x8,
250 UHCI_PORTSC_ENABLE = 0x4,
251 UHCI_PORTSC_CSCH = 0x2,
252 UHCI_PORTSC_CONN = 0x1,
256 bool m_HardwareOwned =
false;
257 bool m_Initialised =
false;
266 bool m_TimerRegistered;
280 Mutex m_AsyncQueueListChangeLock;
282 uint32_t* m_pFrameList;
283 uintptr_t m_pFrameListPhys;
286 uintptr_t m_pTDListPhys;
293 uintptr_t m_pQHListPhys;
327 void operator=(
const Uhci&);
Abstrace base class for hardware I/O capabilities.
Special memory entity in the kernel's virtual address space.
static void enqueueCompletedTransfer(void *context)
Mutex m_IrqProcessingLock
IrqDisposition irq(irq_id_t number) override
IRQ handler.
size_t currentRootPortGeneration(size_t port) const override
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)
QH * m_pCurrentAsyncQueueHead
virtual void getName(String &str)
void replaySuppressedConnectionChange(size_t port) override
virtual void cancelAsyncAndDrain(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t), uintptr_t pParam)
bool setLegacySupportControl(uint16_t control)
virtual MUST_USE_RESULT bool doAsync(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t)=0, uintptr_t pParam=0)
List< QH * > m_AsyncSchedule
List of QHs in the active asynchronous schedule.
Semaphore m_DequeueCount
Semaphore for the dequeue list.
virtual bool portReset(uint8_t nPort, bool bErrorResponse=false)
Gets a UsbDevice from a given vendor:product pair.
OperationBarrier m_SubmissionOperations
void cancelRequest(const Request &request) override
void rebuildPeriodicScheduleLocked()
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 detachQueueHeadLocked(QH *pQH)
void stop()
Stops the controller or panics before DMA ownership can be transferred.
void modifyPortControl(size_t portRegister, uint16_t clearMask, uint16_t setMask)
Serialises control RMWs with scanning without echoing W1C status bits.
MUST_USE_RESULT bool cancelInterruptInAndDrain(const UsbInterruptInToken &token, void(*callback)(uintptr_t, ssize_t), uintptr_t parameter, bool producerAlreadyStopped) override
List< QH * > m_DequeueList
List of QHs ready for dequeue.
virtual uintptr_t createTransaction(UsbEndpoint endpointInfo)
Creates a new transaction with the given endpoint data.
uint64_t m_nPortCheckTicks
The time passed since last port check.
void timer(uint64_t delta)
Timer callback to handle port status changes.
virtual void addTransferToTransaction(uintptr_t pTransaction, bool bToggle, UsbPid pid, uintptr_t pBuffer, size_t nBytes)
Adds a new transfer to an existent transaction.
UsbHcd::CallbackDeliveryQueue m_CompletionDeliveries
QH * m_pCurrentAsyncQueueTail
OperationBarrier m_DequeueOperations
bool inInterruptCallbackContext() const override
OperationBarrier m_TransferOperations
void reclaimQueueHeadLocked(QH *pQH)
OperationBarrier m_CancelOperations
void start()
Starts the controller or panics instead of leaving work silently stuck.
static bool isInCallbackContext()