X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FUSB%2FCore%2Fusb.c;h=0b4bc638f3e4c7f939c6d33aff4f799b31d81cf9;hb=662713ac7494f05339cee056a3d9f72e2357c492;hp=ab9a48940e8748ae31839a6ed34eb0b2bdb84396;hpb=1474ce5c1ba164bbccfefa411883805d12a0dc62;p=tpg%2Facess2.git diff --git a/Modules/USB/Core/usb.c b/Modules/USB/Core/usb.c index ab9a4894..0b4bc638 100644 --- a/Modules/USB/Core/usb.c +++ b/Modules/USB/Core/usb.c @@ -7,24 +7,154 @@ #include #include #include "usb.h" +#include "usb_proto.h" +// === IMPORTS === +extern tUSBHost *gUSB_Hosts; + +// === STRUCTURES === + +// === PROTOTYPES === +tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts); +void USB_DeviceConnected(tUSBHub *Hub, int Port); +void USB_DeviceDisconnected(tUSBHub *Hub, int Port); +void *USB_GetDeviceDataPtr(tUSBDevice *Dev); +void USB_SetDeviceDataPtr(tUSBDevice *Dev, void *Ptr); + int USB_int_AllocateAddress(tUSBHost *Host); + int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address); // === CODE === -void USB_RegisterHost(tUSBHost *HostDef, void *ControllerPtr) +tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts) +{ + tUSBHost *host; + + host = malloc(sizeof(tUSBHost) + nPorts*sizeof(void*)); + if(!host) { + // Oh, bugger. + return NULL; + } + host->HostDef = HostDef; + host->Ptr = ControllerPtr; + memset(host->AddressBitmap, 0, sizeof(host->AddressBitmap)); + + host->RootHubDev.Next = NULL; + host->RootHubDev.ParentHub = NULL; + host->RootHubDev.Host = host; + host->RootHubDev.Address = 0; + host->RootHubDev.Driver = NULL; + host->RootHubDev.Data = NULL; + + host->RootHub.Device = NULL; + host->RootHub.CheckPorts = NULL; + host->RootHub.nPorts = nPorts; + memset(host->RootHub.Devices, 0, sizeof(void*)*nPorts); + + // TODO: Lock + host->Next = gUSB_Hosts; + gUSB_Hosts = host; + + // Initialise? + HostDef->CheckPorts(ControllerPtr); + + return &host->RootHub; +} + +void USB_DeviceConnected(tUSBHub *Hub, int Port) +{ + tUSBDevice *dev; + if( Port >= Hub->nPorts ) return ; + if( Hub->Devices[Port] ) return ; + + ENTER("pHub iPort", Hub, Port); + + // 0. Perform port init? (done in hub?) + + // Create structure + dev = malloc(sizeof(tUSBDevice)); + dev->Next = NULL; + dev->ParentHub = Hub; + dev->Host = Hub->Device->Host; + dev->Address = 0; + dev->Driver = 0; + dev->Data = 0; + + // 1. Assign an address + dev->Address = USB_int_AllocateAddress(dev->Host); + if(dev->Address == 0) { + Log_Error("USB", "No addresses avaliable on host %p", dev->Host); + free(dev); + LEAVE('-'); + return ; + } + USB_int_SendSetupSetAddress(dev->Host, dev->Address); + LOG("Assigned address %i", dev->Address); + + // 2. Get device information + + // Done. + LEAVE('-'); +} + +void USB_DeviceDisconnected(tUSBHub *Hub, int Port) +{ + +} + +void *USB_GetDeviceDataPtr(tUSBDevice *Dev) { return Dev->Data; } +void USB_SetDeviceDataPtr(tUSBDevice *Dev, void *Ptr) { Dev->Data = Ptr; } + +int USB_int_AllocateAddress(tUSBHost *Host) { - // TODO: + int i; + for( i = 1; i < 128; i ++ ) + { + if(Host->AddressBitmap[i/8] & (1 << i)) + continue ; + return i; + } + return 0; } -int USB_int_SendSetupSetAddress(tUSBHost *Host, void *Ptr, int Address) +int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address) { - Uint8 data[8]; - data[0] = 0; // bmRequestType - data[1] = 5; // SET_ADDRESS - data[2] = Address & 0x7F; // wValue (low) - data[3] = 0; // wValue (high) - data[4] = 0; // wLength - data[6] = 0; // wLength + struct sDeviceRequest req; + req.ReqType = 0; // bmRequestType + req.Request = 5; // SET_ADDRESS + req.Value = Address & 0x7F; // wValue + req.Index = 0; // wIndex + req.Length = 0; // wLength // Addr 0:0, Data Toggle = 0, no interrupt - return Host->SendSETUP(Ptr, 0, 0, 0, FALSE, data, 8) == NULL; + return Host->HostDef->SendSETUP(Host->Ptr, 0, 0, 0, FALSE, &req, sizeof(req)) == NULL; +} + +int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest) +{ + struct sDeviceRequest req; + const int ciMaxPacketSize = 0x400; + req.ReqType = 0x80; + req.Request = 6; // GET_DESCRIPTOR + req.Value = ((Type & 0xFF) << 8) | (Index & 0xFF); + req.Index = 0; // TODO: Language ID + req.Length = Length; + + Dev->Host->HostDef->SendSETUP( + Dev->Host->Ptr, Dev->Address, Endpoint, + 0, FALSE, + &req, sizeof(req) + ); + + while( Length > ciMaxPacketSize ) + { + Dev->Host->HostDef->SendIN( + Dev->Host->Ptr, Dev->Address, Endpoint, + 1, FALSE, + Dest, ciMaxPacketSize + ); + Length -= ciMaxPacketSize; + } + + // TODO: Complete and get completion + + return 0; }