23 #include "modules/system/usb/Usb.h" 24 #include "modules/system/usb/UsbHub.h" 25 #include "pedigree/kernel/Spinlock.h" 26 #include "pedigree/kernel/compiler.h" 27 #include "pedigree/kernel/machine/IrqHandler.h" 28 #include "pedigree/kernel/machine/types.h" 29 #include "pedigree/kernel/process/Mutex.h" 30 #include "pedigree/kernel/process/Semaphore.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/List.h" 36 #include "pedigree/kernel/utilities/RequestQueue.h" 37 #include "pedigree/kernel/utilities/String.h" 38 #include "pedigree/kernel/utilities/new" 57 IsochronousList = 0x8,
69 uint32_t bBuffRounding : 1;
71 uint32_t nIntDelay : 3;
72 uint32_t bDataToggleSrc : 1;
73 uint32_t bDataToggle : 1;
74 uint32_t nErrorCount : 2;
76 uint32_t pBufferStart;
83 uint16_t nNextTDIndex;
104 return TransactionError;
112 uint32_t nAddress : 7;
113 uint32_t nEndpoint : 4;
116 uint32_t bLoSpeed : 1;
119 uint32_t nMaxPacketSize : 11;
121 uint32_t pTailTD : 28;
122 uint32_t bHalted : 1;
123 uint32_t bToggleCarry : 1;
125 uint32_t pHeadTD : 28;
131 void (*pCallback)(uintptr_t, ssize_t);
159 uint32_t pInterruptEDList[32];
160 uint16_t nFrameNumber;
171 uintptr_t pTransaction,
bool bToggle, UsbPid pid, uintptr_t pBuffer,
176 uintptr_t pTransaction,
void (*pCallback)(uintptr_t, ssize_t) = 0,
177 uintptr_t pParam = 0);
179 UsbEndpoint endpointInfo, uintptr_t pBuffer, uint16_t nBytes,
180 void (*pCallback)(uintptr_t, ssize_t), uintptr_t pParam = 0);
184 virtual bool irq(irq_id_t number, InterruptState &state);
186 virtual void interrupt(
size_t number, InterruptState &state);
189 virtual bool portReset(uint8_t nPort,
bool bErrorResponse =
false);
193 uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0, uint64_t p4 = 0,
194 uint64_t p5 = 0, uint64_t p6 = 0, uint64_t p7 = 0, uint64_t p8 = 0);
209 if (!pED || !pED->pMetaData)
212 size_t id = pED->pMetaData->id & 0xFFF;
213 Lists type = pED->pMetaData->edType;
217 return m_pControlEDListPhys + (
id *
sizeof(
ED));
219 return m_pBulkEDListPhys + (
id *
sizeof(
ED));
234 if ((m_pControlEDListPhys <= phys) &&
235 (phys < (m_pControlEDListPhys + 0x1000)))
237 return &m_pControlEDList[phys & 0xFFF];
240 (m_pBulkEDListPhys <= phys) &&
241 (phys < (m_pBulkEDListPhys + 0x1000)))
243 return &m_pBulkEDList[phys & 0xFFF];
253 OhciCommandStatus = 0x08,
254 OhciInterruptStatus = 0x0c,
255 OhciInterruptEnable = 0x10,
256 OhciInterruptDisable = 0x14,
258 OhciControlHeadED = 0x20,
259 OhciControlCurrentED = 0x24,
260 OhciBulkHeadED = 0x28,
261 OhciBulkCurrentED = 0x2c,
262 OhciFmInterval = 0x34,
263 OhciRhDescriptorA = 0x48,
265 OhciRhPortStatus = 0x54,
267 OhciControlStateFunctionalMask = 0xC0,
269 OhciControlInterruptRoute = 0x100,
270 OhciControlStateRunning =
272 OhciControlListsEnable = 0x30,
276 OhciCommandRequestOwnership = 0x08,
277 OhciCommandBulkListFilled = 0x04,
278 OhciCommandControlListFilled = 0x02,
279 OhciCommandHcReset = 0x01,
281 OhciInterruptMIE = 0x80000000,
282 OhciInterruptRhStsChange = 0x40,
283 OhciInterruptUnrecoverableError = 0x10,
284 OhciInterruptWbDoneHead = 0x02,
285 OhciInterruptStartOfFrame = 0x04,
287 OhciRhPortStsResCh = 0x100000,
288 OhciRhPortStsConnStsCh = 0x10000,
289 OhciRhPortStsLoSpeed = 0x200,
290 OhciRhPortStsPower = 0x100,
291 OhciRhPortStsReset = 0x10,
292 OhciRhPortStsEnable = 0x02,
293 OhciRhPortStsConnected = 0x01,
304 uintptr_t m_pHccaPhys;
318 ED *m_pPeriodicEDList;
319 uintptr_t m_pPeriodicEDListPhys;
322 ED *m_pControlEDList;
323 uintptr_t m_pControlEDListPhys;
327 uintptr_t m_pBulkEDListPhys;
331 uintptr_t m_pTDListPhys;
335 ED *m_pBulkQueueHead;
336 ED *m_pControlQueueHead;
339 ED *m_pBulkQueueTail;
340 ED *m_pControlQueueTail;
343 ED *m_pPeriodicQueueTail;
361 void operator=(
const Ohci &);
Spinlock m_PeriodicListChangeLock
Lock for changing the periodic list.
virtual bool portReset(uint8_t nPort, bool bErrorResponse=false)
Gets a UsbDevice from a given vendor:product pair.
virtual void addTransferToTransaction(uintptr_t pTransaction, bool bToggle, UsbPid pid, uintptr_t pBuffer, size_t nBytes)
Adds a new transfer to an existent transaction.
void stop(Lists list)
Stops the controller from processing the given list.
List< ED * > m_FullSchedule
ED * ptv_ed(physical_uintptr_t phys)
Converts a physical address to an ED pointer. Maybe.
virtual void doAsync(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t)=0, uintptr_t pParam=0)
virtual void addInterruptInHandler(UsbEndpoint endpointInfo, uintptr_t pBuffer, uint16_t nBytes, void(*pCallback)(uintptr_t, ssize_t), uintptr_t pParam=0)
Adds a new handler for an interrupt IN transaction.
virtual void getName(String &str)
physical_uintptr_t vtp_ed(ED *pED)
Converts a software ED pointer to a physical address.
Spinlock m_ControlListChangeLock
Lock for changing the control list.
Abstrace base class for hardware I/O capabilities.
Spinlock m_DequeueListLock
Dequeue list lock.
Spinlock m_ScheduleChangeLock
Lock for modifying the schedule list itself (m_FullSchedule)
Spinlock m_BulkListChangeLock
Lock for changing the bulk list.
Special memory entity in the kernel's virtual address space.
Mutex m_Mutex
Global lock.
Semaphore m_DequeueCount
Semaphore for the dequeue list.
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)
void removeED(ED *pED)
Prepares an ED to be reclaimed.
List< ED * > m_DequeueList
List of EDs ready for dequeue (reclaiming)
Abstract base class for interrupt-handlers.
virtual uintptr_t createTransaction(UsbEndpoint endpointInfo)
Creates a new transaction with the given endpoint data.
void start(Lists list)
Starts processing of the given list.
virtual bool irq(irq_id_t number, InterruptState &state)
IRQ handler.
Lists
Enumeration of lists that can be stopped or started.