56 static constexpr size_t EdRegionBytes = 4096;
57 static constexpr size_t EdRegionOffsetMask = EdRegionBytes - 1;
74 enum Lists { PeriodicList = 0x4, IsochronousList = 0x8, ControlList = 0x10, BulkList = 0x20 };
80 bool initialised()
const {
86 uint32_t bBuffRounding : 1;
88 uint32_t nIntDelay : 3;
89 uint32_t bDataToggleSrc : 1;
90 uint32_t bDataToggle : 1;
91 uint32_t nErrorCount : 2;
93 uint32_t pBufferStart;
100 uint16_t nNextTDIndex;
106 enum StatusCodes { CrcError = 1, Stall = 4 };
108 UsbError getError() {
115 return TransactionError;
122 uint32_t nAddress : 7;
123 uint32_t nEndpoint : 4;
126 uint32_t bLoSpeed : 1;
129 uint32_t nMaxPacketSize : 11;
131 uint32_t pTailTD : 28;
132 uint32_t bHalted : 1;
133 uint32_t bToggleCarry : 1;
135 uint32_t pHeadTD : 28;
164 bool acceptedOperation;
171 uint32_t pInterruptEDList[32];
172 uint16_t nFrameNumber;
174 volatile uint32_t pDoneHead;
178 str.assign(
"OHCI", 5);
182 uintptr_t pBuffer,
size_t nBytes);
186 void (*pCallback)(uintptr_t, ssize_t) = 0,
187 uintptr_t pParam = 0);
190 void (*pCallback)(uintptr_t, ssize_t),
192 uintptr_t pParam = 0);
199 virtual bool portReset(uint8_t nPort,
bool bErrorResponse =
false);
202 virtual void cancelAsyncAndDrain(uintptr_t pTransaction,
void (*pCallback)(uintptr_t, ssize_t),
205 void (*callback)(uintptr_t, ssize_t),
207 bool producerAlreadyStopped)
override;
213 virtual uint64_t
executeRequest(uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0,
214 uint64_t p4 = 0, uint64_t p5 = 0, uint64_t p6 = 0,
215 uint64_t p7 = 0, uint64_t p8 = 0);
223 void start(
Lists list);
261 static void finishDeferredCompletion(
void* context);
265 if (!pED || !pED->pMetaData)
268 size_t id = pED->pMetaData->id & EdRegionOffsetMask;
269 Lists type = pED->pMetaData->edType;
272 return m_pControlEDListPhys + (
id *
sizeof(
ED));
274 return m_pBulkEDListPhys + (
id *
sizeof(
ED));
288 if ((m_pControlEDListPhys <= phys) && (phys < (m_pControlEDListPhys + EdRegionBytes))) {
289 return &m_pControlEDList[(phys - m_pControlEDListPhys) /
sizeof(
ED)];
290 }
else if ((m_pBulkEDListPhys <= phys) && (phys < (m_pBulkEDListPhys + EdRegionBytes))) {
291 return &m_pBulkEDList[(phys - m_pBulkEDListPhys) /
sizeof(
ED)];
299 OhciCommandStatus = 0x08,
300 OhciInterruptStatus = 0x0c,
301 OhciInterruptEnable = 0x10,
302 OhciInterruptDisable = 0x14,
304 OhciControlHeadED = 0x20,
305 OhciControlCurrentED = 0x24,
306 OhciBulkHeadED = 0x28,
307 OhciBulkCurrentED = 0x2c,
308 OhciFmInterval = 0x34,
309 OhciRhDescriptorA = 0x48,
311 OhciRhPortStatus = 0x54,
313 OhciControlStateFunctionalMask = 0xC0,
315 OhciControlInterruptRoute = 0x100,
316 OhciControlStateRunning = 0x80,
317 OhciControlStateSuspended = 0xC0,
318 OhciControlListsEnable = 0x30,
322 OhciCommandRequestOwnership = 0x08,
323 OhciCommandBulkListFilled = 0x04,
324 OhciCommandControlListFilled = 0x02,
325 OhciCommandHcReset = 0x01,
327 OhciInterruptMIE = 0x80000000,
328 OhciInterruptOwnershipChange = 0x40000000,
329 OhciInterruptRhStsChange = 0x40,
330 OhciInterruptFrameNumberOverflow = 0x20,
331 OhciInterruptUnrecoverableError = 0x10,
332 OhciInterruptResumeDetected = 0x08,
333 OhciInterruptWbDoneHead = 0x02,
334 OhciInterruptSchedulingOverrun = 0x01,
335 OhciInterruptStartOfFrame = 0x04,
336 OhciInterruptAll = OhciInterruptMIE | OhciInterruptOwnershipChange | 0x7F,
337 OhciInterruptOperational = OhciInterruptMIE | OhciInterruptFrameNumberOverflow |
338 OhciInterruptUnrecoverableError | OhciInterruptWbDoneHead |
339 OhciInterruptSchedulingOverrun,
343 OhciRhHubStsSetGlobalPower = 0x10000,
344 OhciRhHubStsOverCurrentCh = 0x20000,
346 OhciRhPortStsResCh = 0x100000,
347 OhciRhPortStsOverCurrentCh = 0x80000,
348 OhciRhPortStsSuspendCh = 0x40000,
349 OhciRhPortStsEnableCh = 0x20000,
350 OhciRhPortStsConnStsCh = 0x10000,
351 OhciRhPortStsChangeMask = OhciRhPortStsResCh | OhciRhPortStsOverCurrentCh |
352 OhciRhPortStsSuspendCh | OhciRhPortStsEnableCh |
353 OhciRhPortStsConnStsCh,
354 OhciRhPortStsLoSpeed = 0x200,
355 OhciRhPortStsPower = 0x100,
356 OhciRhPortStsReset = 0x10,
357 OhciRhPortStsEnable = 0x02,
358 OhciRhPortStsConnected = 0x01,
376 uintptr_t m_pHccaPhys;
386 bool m_RootHubStatusChangeDesired;
387 bool m_PortResetActive;
401 ED* m_pPeriodicEDList;
402 uintptr_t m_pPeriodicEDListPhys;
405 ED* m_pControlEDList;
406 uintptr_t m_pControlEDListPhys;
410 uintptr_t m_pBulkEDListPhys;
414 uintptr_t m_pTDListPhys;
418 ED* m_pBulkQueueHead;
419 ED* m_pControlQueueHead;
422 ED* m_pBulkQueueTail;
423 ED* m_pControlQueueTail;
426 ED* m_pPeriodicQueueTail;
457 void operator=(
const Ohci&);