Modules/USB - Increased UHCI root hub poll period to 2s
[tpg/acess2.git] / KernelLand / Modules / USB / Core / usb_poll.c
index 6285a11..27f4728 100644 (file)
@@ -9,10 +9,7 @@
 #include <usb_core.h>
 #include "usb.h"
 #include <timers.h>
-
-#define POLL_ATOM      25      // 25ms atom
-#define POLL_MAX       256     // Max period that can be nominated
-#define POLL_SLOTS     ((int)(POLL_MAX/POLL_ATOM))
+#include "usb_async.h"
 
 // === IMPORTS ===
 extern tUSBHost        *gUSB_Hosts;
@@ -21,41 +18,56 @@ extern tUSBHost     *gUSB_Hosts;
 void   USB_StartPollingEndpoint(tUSBInterface *Iface, int Endpoint);
 
 // === GLOBALS ===
-tUSBEndpoint   *gUSB_PollQueues[POLL_MAX/POLL_ATOM];
- int   giUSB_PollPosition;     // Index into gUSB_PollQueues
 
 // === CODE ===
+void USB_int_PollCallback(void *Ptr, void *Data, size_t Length)
+{
+       tAsyncOp *op;
+       tUSBEndpoint    *ep = Ptr;
+       
+       op = malloc(sizeof(*op));
+
+       op->Next = NULL;
+       op->Endpt = ep;
+       op->Length = Length;
+       op->Data = ep->InputData;
+
+       LOG("op %p, endpoint %p (0x%x)", op, ep,
+               ep->Interface->Dev->Address * 16 + ep->EndpointNum);
+
+       Workqueue_AddWork(&gUSB_AsyncQueue, op);
+}
+
 void USB_StartPollingEndpoint(tUSBInterface *Iface, int Endpoint)
 {
        tUSBEndpoint    *endpt;
 
        ENTER("pIface iEndpoint", Iface, Endpoint);
-       LEAVE('-');
 
        // Some sanity checks
-       if(Endpoint <= 0 || Endpoint > Iface->nEndpoints)
+       if(Endpoint <= 0 || Endpoint > Iface->nEndpoints) {
+               LEAVE('-');
                return ;
+       }
        endpt = &Iface->Endpoints[Endpoint-1];
        LOG("endpt(%p)->PollingPeriod = %i", endpt, endpt->PollingPeriod);
-       if(endpt->PollingPeriod > POLL_MAX || endpt->PollingPeriod <= 0)
+       if(endpt->PollingPeriod > 256 || endpt->PollingPeriod <= 0) {
+               LOG("Invalid polling period");
+               LEAVE('-');
                return ;
+       }
 
        // TODO: Check that this endpoint isn't already on the queue
 
        endpt->InputData = malloc(endpt->MaxPacketSize);
-
-       // Determine polling period in atoms
-       endpt->PollingAtoms = (endpt->PollingPeriod + POLL_ATOM-1) / POLL_ATOM;
-       if(endpt->PollingAtoms > POLL_SLOTS)    endpt->PollingAtoms = POLL_SLOTS;
-       LOG("endpt(%p)->PollingAtoms = %i", endpt, endpt->PollingAtoms);
-       // Add to poll queue
-       // TODO: Locking
-       {
-                int    idx = giUSB_PollPosition + 1;
-               if(idx >= POLL_SLOTS)   idx -= POLL_SLOTS;
-               endpt->Next = gUSB_PollQueues[idx];
-               gUSB_PollQueues[idx] = endpt;
-       }
+       LOG("Polling 0x%x at %i ms", Iface->Dev->Address * 16 + endpt->EndpointNum, endpt->PollingPeriod);
+       Iface->Dev->Host->HostDef->InitInterrupt(
+               Iface->Dev->Host->Ptr, Iface->Dev->Address * 16 + endpt->EndpointNum,
+               0, endpt->PollingPeriod,
+               USB_int_PollCallback, endpt,
+               endpt->InputData, endpt->MaxPacketSize
+               );
+       LEAVE('-');
 }
 
 /**
@@ -66,75 +78,15 @@ int USB_PollThread(void *unused)
        Threads_SetName("USB Polling Thread");
        for(;;)
        {
-               tUSBEndpoint    *ep, *prev;
-
-               if(giUSB_PollPosition == 0)
+               // Check hosts
+               for( tUSBHost *host = gUSB_Hosts; host; host = host->Next )
                {
-                       // Check hosts
-                       for( tUSBHost *host = gUSB_Hosts; host; host = host->Next )
-                       {
+                       if( host->HostDef->CheckPorts )
                                host->HostDef->CheckPorts(host->Ptr);
-                       }
                }
 
-//             Log_Debug("USBPoll", "giUSB_PollPosition = %i", giUSB_PollPosition);
-
-               // A little evil for neater code
-               prev = (void*)( (tVAddr)&gUSB_PollQueues[giUSB_PollPosition] - offsetof(tUSBEndpoint, Next) );
-
-               // Process queue
-//             LOG("giUSB_PollPosition = %i", giUSB_PollPosition);
-               for( ep = gUSB_PollQueues[giUSB_PollPosition]; ep; prev = ep, ep = ep->Next )
-               {
-                        int    period_in_atoms = ep->PollingAtoms;
-                       LOG("%i: ep = %p", giUSB_PollPosition, ep);
-
-                       // Check for invalid entries
-                       if(period_in_atoms < 0 || period_in_atoms > POLL_ATOM)
-                       {
-                               Log_Warning("USB", "Endpoint on polling queue with invalid period");
-                               continue ;
-                       }
-                       // Check for entries to delete
-                       if(period_in_atoms == 0)
-                       {
-                               // Remove
-                               prev->Next = ep->Next;
-                               ep->PollingAtoms = -1;  // Mark as removed
-                               ep = prev;      // Make sure prev is kept valid
-                               continue ;
-                       }
-
-                       // Read data
-                       // TODO: Check the endpoint
-                       // TODO: Async checking?
-                       // - Send the read request on all of them then wait for the first to complete
-                       USB_RecvDataA(
-                               ep->Interface, ep->EndpointIdx+1,
-                               ep->MaxPacketSize, ep->InputData,
-                               ep->Interface->Driver->Endpoints[ep->EndpointIdx].DataAvail
-                               );
-                               
-                       // Call callback
-
-                       // Reschedule
-                       if( period_in_atoms != POLL_SLOTS )
-                       {
-                                int    newqueue_id = (giUSB_PollPosition + period_in_atoms) % POLL_SLOTS;
-                               tUSBEndpoint    **newqueue = &gUSB_PollQueues[newqueue_id];
-                               
-                               prev->Next = ep->Next;
-                               
-                               ep->Next = *newqueue;
-                               *newqueue = ep;
-                               ep = prev;
-                       }
-               }
-               giUSB_PollPosition ++;
-               if(giUSB_PollPosition == POLL_SLOTS)
-                       giUSB_PollPosition = 0;
-               // TODO: Check for a longer delay
-               Time_Delay(POLL_ATOM);
+               // 2s delay - fuck those with UHCI only :)
+               Time_Delay(2000);
        }
 }
 

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