From: John Hodge Date: Sat, 25 Feb 2012 14:21:03 +0000 (+0800) Subject: Modules/USB - Slight correctness fixes, and fixed a race condition X-Git-Tag: rel0.15~752 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=5f36351f213bb3983b70059814cdbf87d850e563;p=tpg%2Facess2.git Modules/USB - Slight correctness fixes, and fixed a race condition - Still has interrupt issues, possibly a transaction causing the entire queue to stop --- diff --git a/KernelLand/Modules/USB/Core/usb_io.c b/KernelLand/Modules/USB/Core/usb_io.c index 38509d34..dada0deb 100644 --- a/KernelLand/Modules/USB/Core/usb_io.c +++ b/KernelLand/Modules/USB/Core/usb_io.c @@ -79,6 +79,7 @@ void USB_RecvDataA(tUSBInterface *Dev, int Endpoint, int Length, void *DataBuf, op->Data = DataBuf; // TODO: Handle transfers that are larger than one packet + // TODO: Data toggle host = Dev->Dev->Host; LOG("IN from %p %i:%i", host->Ptr, Dev->Dev->Address, op->Endpt->EndpointNum); diff --git a/KernelLand/Modules/USB/Core/usb_lowlevel.c b/KernelLand/Modules/USB/Core/usb_lowlevel.c index 23822971..033be8dc 100644 --- a/KernelLand/Modules/USB/Core/usb_lowlevel.c +++ b/KernelLand/Modules/USB/Core/usb_lowlevel.c @@ -41,36 +41,35 @@ void *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, in // TODO: Data toggle? // TODO: Multi-packet transfers - if( Type & 0x80 ) + if( Len > 0 ) { - void *hdl2; - - LOG("IN"); - hdl = Host->HostDef->SendIN(Host->Ptr, dest, 0, NULL, NULL, Data, Len); - - LOG("OUT (Done)"); - hdl2 = Host->HostDef->SendOUT(Host->Ptr, dest, 0, INVLPTR, NULL, NULL, 0); - LOG("Wait..."); - while( Host->HostDef->IsOpComplete(Host->Ptr, hdl2) == 0 ) - Time_Delay(1); + if( Type & 0x80 ) + { + LOG("IN"); + hdl = Host->HostDef->SendIN(Host->Ptr, dest, 1, NULL, NULL, Data, Len); + + LOG("OUT (Status)"); + hdl = Host->HostDef->SendOUT(Host->Ptr, dest, 1, INVLPTR, NULL, NULL, 0); + } + else + { + LOG("OUT"); + Host->HostDef->SendOUT(Host->Ptr, dest, 1, NULL, NULL, Data, Len); + + // Status phase (DataToggle=1) + LOG("IN (Status)"); + hdl = Host->HostDef->SendIN(Host->Ptr, dest, 1, INVLPTR, NULL, NULL, 0); + } } else { - void *hdl2; - - LOG("OUT"); - if( Len > 0 ) - hdl = Host->HostDef->SendOUT(Host->Ptr, dest, 0, NULL, NULL, Data, Len); - else - hdl = NULL; - + // Zero length, IN status LOG("IN (Status)"); - // Status phase (DataToggle=1) - hdl2 = Host->HostDef->SendIN(Host->Ptr, dest, 1, INVLPTR, NULL, NULL, 0); - LOG("Wait..."); - while( Host->HostDef->IsOpComplete(Host->Ptr, hdl2) == 0 ) - Time_Delay(1); + hdl = Host->HostDef->SendIN(Host->Ptr, dest, 1, INVLPTR, NULL, NULL, 0); } + LOG("Wait..."); + while( Host->HostDef->IsOpComplete(Host->Ptr, hdl) == 0 ) + Time_Delay(1); LEAVE('p', hdl); return hdl; } @@ -122,12 +121,15 @@ int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, i } LOG("IN (final)"); - final = Dev->Host->HostDef->SendIN( + Dev->Host->HostDef->SendIN( Dev->Host->Ptr, dest, - bToggle, INVLPTR, NULL, + bToggle, NULL, NULL, Dest, Length ); + LOG("OUT (Status)"); + final = Dev->Host->HostDef->SendOUT(Dev->Host->Ptr, dest, 1, INVLPTR, NULL, NULL, 0); + LOG("Waiting"); while( Dev->Host->HostDef->IsOpComplete(Dev->Host->Ptr, final) == 0 ) Threads_Yield(); // BAD BAD BAD diff --git a/KernelLand/Modules/USB/UHCI/uhci.c b/KernelLand/Modules/USB/UHCI/uhci.c index 1293ce7c..48960c21 100644 --- a/KernelLand/Modules/USB/UHCI/uhci.c +++ b/KernelLand/Modules/USB/UHCI/uhci.c @@ -311,14 +311,14 @@ int UHCI_IsTransferComplete(void *Ptr, void *Handle) tUHCI_TD *td = Handle; #if DEBUG tUHCI_Controller *Cont = &gUHCI_Controllers[0]; - LOG("%p->Control = 0x%0x", td, td->Control); + LOG("%p->Control = 0x%08x", td, td->Control); LOG("USBSTS = 0x%x, USBINTR = 0x%x", _InWord(Cont, USBSTS), _InWord(Cont, USBINTR)); LOG("Cont->BulkQH.Child = %x", Cont->BulkQH.Child); #endif if(td->Control & (1 << 23)) { return 0; } -// LOG("inactive, waiting for completion"); + LOG("inactive, waiting for completion"); if(td->_info.bComplete) { td->_info.bActive = 0; @@ -451,6 +451,8 @@ void UHCI_int_InterruptThread(void *Unused) if( td->_info.bActive == 0 ) continue ; // Skip ones that are still in use if( td->Control & (1 << 23) ) continue ; + // Skip ones that are waiting for ACK + if( td->_info.bComplete == 1 ) continue ; // If no callback/alt buffer, mark as free and move on if( td->_info.ExtraInfo )