X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FUSB%2FCore%2Fusb_poll.c;h=27f4728e88983550f962b94b505c9e9ecabfe88d;hb=26498f052da6c37f3361b520be8430e3897bf470;hp=6285a11efc6183af577c8c4c2bcdc78e492abaca;hpb=1797e6eb24e9840405ef348ed5b7cb73b12fdc7d;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/USB/Core/usb_poll.c b/KernelLand/Modules/USB/Core/usb_poll.c index 6285a11e..27f4728e 100644 --- a/KernelLand/Modules/USB/Core/usb_poll.c +++ b/KernelLand/Modules/USB/Core/usb_poll.c @@ -9,10 +9,7 @@ #include #include "usb.h" #include - -#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); } }