X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FUSB%2FCore%2Fusb.c;h=0b4bc638f3e4c7f939c6d33aff4f799b31d81cf9;hb=662713ac7494f05339cee056a3d9f72e2357c492;hp=60bf3f230bc3993ae5f40d8db5b29ea69bd19a82;hpb=351dd3b194833c923bad0292e9019320fb2a41fa;p=tpg%2Facess2.git diff --git a/Modules/USB/Core/usb.c b/Modules/USB/Core/usb.c index 60bf3f23..0b4bc638 100644 --- a/Modules/USB/Core/usb.c +++ b/Modules/USB/Core/usb.c @@ -7,31 +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_MakeToken(void *Buf, int PID, int Addr, int EndP) +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) { - Uint8 *tok = Buf; - int crc = 0; - tok[0] = PID & 0xFF; - tok[1] = (Addr & 0x7F) | ((EndP&1)<<7); - tok[2] = ((EndP >> 1) & 0x7) | crc; } -#if 0 -void USB_SendData(int Controller, int Dev, int Endpoint, void *Data, int Length) +void *USB_GetDeviceDataPtr(tUSBDevice *Dev) { return Dev->Data; } +void USB_SetDeviceDataPtr(tUSBDevice *Dev, void *Ptr) { Dev->Data = Ptr; } + +int USB_int_AllocateAddress(tUSBHost *Host) { - Uint8 buf[Length+3+2/*?*/]; + 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, int Address) +{ + 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->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; - USB_MakeToken(buf, PID_DATA0, Dev, Endpoint); + Dev->Host->HostDef->SendSETUP( + Dev->Host->Ptr, Dev->Address, Endpoint, + 0, FALSE, + &req, sizeof(req) + ); - switch(Controller & 0xF00) + while( Length > ciMaxPacketSize ) { - case 1: // UHCI - UHCI_SendPacket(Controller & 0xFF); - break; + Dev->Host->HostDef->SendIN( + Dev->Host->Ptr, Dev->Address, Endpoint, + 1, FALSE, + Dest, ciMaxPacketSize + ); + Length -= ciMaxPacketSize; } + + // TODO: Complete and get completion + + return 0; } -#endif