X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FUSB%2FEHCI%2Fehci.c;h=d202d067a5327e275c4c808bedad7e6fb6e42898;hb=802762ae7efd39786c0e134ed0bdfe8100d97230;hp=512b0d6eefae5944997525a66a3367494818e8a3;hpb=538fe6ae58915a502057b5dc7bc43bedd87c5067;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/USB/EHCI/ehci.c b/KernelLand/Modules/USB/EHCI/ehci.c index 512b0d6e..d202d067 100644 --- a/KernelLand/Modules/USB/EHCI/ehci.c +++ b/KernelLand/Modules/USB/EHCI/ehci.c @@ -258,11 +258,11 @@ int EHCI_InitController(tPAddr BaseAddress, Uint8 InterruptNum) _error: cont->PhysBase = 0; if( cont->CapRegs ) - MM_Deallocate( (tVAddr)cont->CapRegs ); + MM_Deallocate( cont->CapRegs ); if( cont->PeriodicQueue ) - MM_Deallocate( (tVAddr)cont->PeriodicQueue ); + MM_Deallocate( cont->PeriodicQueue ); if( cont->TDPool ) - MM_Deallocate( (tVAddr)cont->TDPool ); + MM_Deallocate( cont->TDPool ); LEAVE('i', 2); return 2; } @@ -380,6 +380,8 @@ void *EHCI_InitInterrupt(void *Ptr, int Endpoint, int bOutbound, int Period, int period_pow = _GetClosestPower2(Period); tEHCI_Endpoint *endpt = EHCI_int_AllocateEndpt(Cont, Endpoint, Length, period_pow); + endpt->Next = Cont->FirstInterruptEndpt; + Cont->FirstInterruptEndpt = endpt; // Allocate a QH tEHCI_QH *qh = EHCI_int_AllocateQH(Cont, endpt, Cb, CbData); @@ -801,6 +803,36 @@ void EHCI_int_HandlePortConnectChange(tEHCI_Controller *Cont, int Port) } } +void EHCI_int_CheckInterruptQHs(tEHCI_Controller *Cont) +{ + for( tEHCI_Endpoint *endpt = Cont->FirstInterruptEndpt; endpt; endpt = endpt->Next ) + { + tEHCI_QH *qh = endpt->ActiveQHs; + // Check if the TD of the first QH is active + if( qh->Overlay.Token & QTD_TOKEN_STS_ACTIVE ) + continue ; + // Inactive, fire interrupt and re-trigger + if( !qh->Impl.Callback ) { + // Umm... ? + } + else + { + tEHCI_qTD *last = qh->Impl.LastTD; + size_t remaining_len = (last->Token >> 16) & 0x7FFF; + if( remaining_len > last->Impl.Length ) + remaining_len = last->Impl.Length; + size_t transferred_len = last->Impl.Length - remaining_len; + + LOG("Calling %p(%p) for Intr EndPt %x (%p+0x%x)", + qh->Impl.Callback, qh->Impl.CallbackData, + qh->Impl.Endpt->EndpointID, last->Impl.Ptr, transferred_len); + qh->Impl.Callback(qh->Impl.CallbackData, last->Impl.Ptr, transferred_len); + } + qh->Impl.FirstTD->Token |= QTD_TOKEN_STS_ACTIVE; + qh->Overlay.Token |= QTD_TOKEN_STS_ACTIVE; + } +} + void EHCI_int_RetireQHs(tEHCI_Controller *Cont) { tEHCI_QH *prev = Cont->DeadQH; @@ -856,6 +888,8 @@ void EHCI_int_ReclaimQHs(tEHCI_Controller *Cont) LOG("Calling %p(%p) for EndPt %x (%p+0x%x)", qh->Impl.Callback, qh->Impl.CallbackData, qh->Impl.Endpt->EndpointID, last->Impl.Ptr, transferred_len); + //if( last->Impl.Ptr ) + // Debug_HexDump("EHCI Callback Data", last->Impl.Ptr, transferred_len); qh->Impl.Callback(qh->Impl.CallbackData, last->Impl.Ptr, transferred_len); } @@ -867,6 +901,7 @@ void EHCI_int_ReclaimQHs(tEHCI_Controller *Cont) void EHCI_int_InterruptThread(void *ControllerPtr) { tEHCI_Controller *Cont = ControllerPtr; + Threads_SetName("EHCI Interrupt Worker"); while(Cont->OpRegs) { Uint32 events; @@ -886,9 +921,8 @@ void EHCI_int_InterruptThread(void *ControllerPtr) if( events & EHCI_THREADEVENT_IOC ) { // IOC, handle completed requests - Log_Warning("EHCI", "%P IOC - TODO: Call registered callbacks and reclaim", - Cont->PhysBase); // Search periodic lists for one that fired + EHCI_int_CheckInterruptQHs(Cont); // Retire QHs // - Remove them from the queue and ask the controller to bell when they're removable EHCI_int_RetireQHs(Cont);