Modules/USB - Slight correctness fixes, and fixed a race condition
authorJohn Hodge <[email protected]>
Sat, 25 Feb 2012 14:21:03 +0000 (22:21 +0800)
committerJohn Hodge <[email protected]>
Sat, 25 Feb 2012 14:21:03 +0000 (22:21 +0800)
- Still has interrupt issues, possibly a transaction causing the entire
  queue to stop

KernelLand/Modules/USB/Core/usb_io.c
KernelLand/Modules/USB/Core/usb_lowlevel.c
KernelLand/Modules/USB/UHCI/uhci.c

index 38509d3..dada0de 100644 (file)
@@ -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);
index 2382297..033be8d 100644 (file)
@@ -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
index 1293ce7..48960c2 100644 (file)
@@ -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 )

UCC git Repository :: git.ucc.asn.au