X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FUSB%2FCore%2Fusb.c;h=b3195804c129892969048d4ea29e7c87e1ce11f2;hb=4c717bb526a0a7b1aa44ed7fc4f07a6b7da5d2f9;hp=52968e309b9ea39261fe97015de83bb09289c149;hpb=61e738e9f111f0beac621db5efbccff0d64760a2;p=tpg%2Facess2.git diff --git a/Modules/USB/Core/usb.c b/Modules/USB/Core/usb.c index 52968e30..b3195804 100644 --- a/Modules/USB/Core/usb.c +++ b/Modules/USB/Core/usb.c @@ -1,31 +1,27 @@ /* - * Acess 2 USB Stack - * USB Packet Control + * Acess2 USB Stack + * - By John Hodge (thePowersGang) + * + * usb.c + * - USB Structure */ #define DEBUG 1 #include #include #include #include "usb.h" -#include "usb_proto.h" // === IMPORTS === extern tUSBHost *gUSB_Hosts; +extern tUSBDriver gUSBHub_Driver; // === 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); - int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest); -char *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index); - int _UTF16to8(Uint16 *Input, int InputLen, char *Dest); +// === GLOBALS === +tUSBDriver *gpUSB_InterfaceDrivers = &gUSBHub_Driver; // === CODE === tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts) @@ -41,15 +37,17 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts) 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 = &host->RootHubDev; - host->RootHub.CheckPorts = NULL; +// host->RootHubIf.Next = NULL; + host->RootHubIf.Dev = &host->RootHubDev; + host->RootHubIf.Driver = NULL; + host->RootHubIf.Data = NULL; + host->RootHubIf.nEndpoints = 0; + + host->RootHub.Interface = &host->RootHubIf; host->RootHub.nPorts = nPorts; memset(host->RootHub.Devices, 0, sizeof(void*)*nPorts); @@ -60,308 +58,51 @@ tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts) 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 - { - struct sDescriptor_Device desc; - LOG("Getting device descriptor"); - // Endpoint 0, Desc Type 1, Index 0 - USB_int_ReadDescriptor(dev, 0, 1, 0, sizeof(desc), &desc); - - LOG("Device Descriptor = {"); - LOG(" .Length = %i", desc.Length); - LOG(" .Type = %i", desc.Type); - LOG(" .USBVersion = 0x%04x", desc.USBVersion); - LOG(" .DeviceClass = 0x%02x", desc.DeviceClass); - LOG(" .DeviceSubClass = 0x%02x", desc.DeviceSubClass); - LOG(" .DeviceProtocol = 0x%02x", desc.DeviceProtocol); - LOG(" .MaxPacketSize = 0x%02x", desc.MaxPacketSize); - LOG(" .VendorID = 0x%04x", desc.VendorID); - LOG(" .ProductID = 0x%04x", desc.ProductID); - LOG(" .DeviceID = 0x%04x", desc.DeviceID); - LOG(" .ManufacturerStr = Str %i", desc.ManufacturerStr); - LOG(" .ProductStr = Str %i", desc.ProductStr); - LOG(" .SerialNumberStr = Str %i", desc.SerialNumberStr); - LOG(" .NumConfigurations = %i", desc.SerialNumberStr); - LOG("}"); - - if( desc.ManufacturerStr ) - { - char *tmp = USB_int_GetDeviceString(dev, 0, desc.ManufacturerStr); - LOG("ManufacturerStr = '%s'", tmp); - free(tmp); - } - if( desc.ProductStr ) - { - char *tmp = USB_int_GetDeviceString(dev, 0, desc.ProductStr); - LOG("ProductStr = '%s'", tmp); - free(tmp); - } - if( desc.SerialNumberStr ) - { - char *tmp = USB_int_GetDeviceString(dev, 0, desc.SerialNumberStr); - LOG("SerialNumbertStr = '%s'", tmp); - free(tmp); - } - } - - // 3. Get configurations - for( int i = 0; i < 1; i ++ ) - { - struct sDescriptor_Configuration desc; - void *full_buf; - char *cur_ptr; - - USB_int_ReadDescriptor(dev, 0, 2, i, sizeof(desc), &desc); - LOG("Configuration Descriptor %i = {", i); - LOG(" .Length = %i", desc.Length); - LOG(" .Type = %i", desc.Type); - LOG(" .TotalLength = 0x%x", LittleEndian16(desc.TotalLength)); - LOG(" .NumInterfaces = %i", desc.NumInterfaces); - LOG(" .ConfigurationValue = %i", desc.ConfigurationValue); - LOG(" .ConfigurationStr = %i", desc.ConfigurationStr); - LOG(" .AttributesBmp = 0b%b", desc.AttributesBmp); - LOG(" .MaxPower = %i (*2mA)", desc.MaxPower); - LOG("}"); - if( desc.ConfigurationStr ) { - char *tmp = USB_int_GetDeviceString(dev, 0, desc.ConfigurationStr); - LOG("ConfigurationStr = '%s'", tmp); - free(tmp); - } - - cur_ptr = full_buf = malloc( LittleEndian16(desc.TotalLength) ); - USB_int_ReadDescriptor(dev, 0, 2, i, desc.TotalLength, full_buf); - - cur_ptr += desc.Length; - - // TODO: Interfaces - for( int j = 0; j < desc.NumInterfaces; j ++ ) - { - struct sDescriptor_Interface *iface; - iface = (void*)cur_ptr; - // TODO: Sanity check with remaining space - cur_ptr += sizeof(*iface); - - LOG("Interface %i/%i = {"); - LOG(" .InterfaceNum = %i", iface->InterfaceNum); - LOG(" .NumEndpoints = %i", iface->NumEndpoints); - LOG(" .InterfaceClass = 0x%x", iface->InterfaceClass); - LOG(" .InterfaceSubClass = 0x%x", iface->InterfaceSubClass); - LOG(" .InterfaceProcol = 0x%x", iface->InterfaceProtocol); - - if( iface->InterfaceStr ) { - char *tmp = USB_int_GetDeviceString(dev, 0, iface->InterfaceStr); - LOG(" .InterfaceStr = %i '%s'", iface->InterfaceStr, tmp); - free(tmp); - } - LOG("}"); - - for( int k = 0; k < iface->NumEndpoints; k ++ ) - { - struct sDescriptor_Endpoint *endpt; - endpt = (void*)cur_ptr; - // TODO: Sanity check with remaining space - cur_ptr += sizeof(*endpt); - - - } - } - - free(full_buf); - } - - // 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) -{ - int i; - for( i = 1; i < 128; i ++ ) - { - if(Host->AddressBitmap[i/8] & (1 << (i%8))) - continue ; - Host->AddressBitmap[i/8] |= 1 << (i%8); - return i; - } - return 0; -} - -void USB_int_DeallocateAddress(tUSBHost *Host, int Address) -{ - Host->AddressBitmap[Address/8] &= ~(1 << (Address%8)); -} - -int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address) +// --- Drivers --- +void USB_RegisterDriver(tUSBDriver *Driver) { - void *hdl; - struct sDeviceRequest req; - req.ReqType = 0; // bmRequestType - req.Request = 5; // SET_ADDRESS - // TODO: Endian - req.Value = LittleEndian16( Address & 0x7F ); // wValue - req.Index = LittleEndian16( 0 ); // wIndex - req.Length = LittleEndian16( 0 ); // wLength - - // Addr 0:0, Data Toggle = 0, no interrupt - hdl = Host->HostDef->SendSETUP(Host->Ptr, 0, 0, 0, FALSE, &req, sizeof(req)); - if(!hdl) - return 1; - - // TODO: Data toggle? - hdl = Host->HostDef->SendIN(Host->Ptr, 0, 0, 0, FALSE, NULL, 0); - - while( Host->HostDef->IsOpComplete(Host->Ptr, hdl) == 0 ) - Time_Delay(1); - - return 0; + Log_Warning("USB", "TODO: Implement USB_RegisterDriver"); } -int USB_int_ReadDescriptor(tUSBDevice *Dev, int Endpoint, int Type, int Index, int Length, void *Dest) +tUSBDriver *USB_int_FindDriverByClass(Uint32 ClassCode) { - const int ciMaxPacketSize = 0x400; - struct sDeviceRequest req; - int bToggle = 0; - void *final; - - req.ReqType = 0x80; - req.Request = 6; // GET_DESCRIPTOR - req.Value = LittleEndian16( ((Type & 0xFF) << 8) | (Index & 0xFF) ); - req.Index = LittleEndian16( 0 ); // TODO: Language ID - req.Length = LittleEndian16( Length ); - - Dev->Host->HostDef->SendSETUP( - Dev->Host->Ptr, Dev->Address, Endpoint, - 0, NULL, - &req, sizeof(req) - ); - - bToggle = 1; - while( Length > ciMaxPacketSize ) + ENTER("xClassCode", ClassCode); + for( tUSBDriver *ret = gpUSB_InterfaceDrivers; ret; ret = ret->Next ) { - Dev->Host->HostDef->SendIN( - Dev->Host->Ptr, Dev->Address, Endpoint, - bToggle, NULL, - Dest, ciMaxPacketSize - ); - bToggle = !bToggle; - Length -= ciMaxPacketSize; + LOG(" 0x%x & 0x%x == 0x%x?", ClassCode, ret->Match.Class.ClassMask, ret->Match.Class.ClassCode); + if( (ClassCode & ret->Match.Class.ClassMask) == ret->Match.Class.ClassCode ) + { + LOG("Found '%s'", ret->Name); + LEAVE('p', ret); + return ret; + } } - - final = Dev->Host->HostDef->SendIN( - Dev->Host->Ptr, Dev->Address, Endpoint, - bToggle, INVLPTR, - Dest, Length - ); - - while( Dev->Host->HostDef->IsOpComplete(Dev->Host->Ptr, final) == 0 ) - Time_Delay(1); - - return 0; + LEAVE('n'); + return NULL; } -char *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index) +// --- Hub Registration --- +// NOTE: Doesn't do much nowdays +tUSBHub *USB_RegisterHub(tUSBInterface *Device, int PortCount) { - struct sDescriptor_String str; - int src_len, new_len; - char *ret; + tUSBHub *ret; - USB_int_ReadDescriptor(Dev, Endpoint, 3, Index, sizeof(str), &str); - if(str.Length > sizeof(str)) { - Log_Notice("USB", "String is %i bytes, which is over prealloc size (%i)", - str.Length, sizeof(str) - ); - // HACK: - str.Length = sizeof(str); - } - src_len = (str.Length - 2) / sizeof(str.Data[0]); - - new_len = _UTF16to8(str.Data, src_len, NULL); - ret = malloc( new_len + 1 ); - _UTF16to8(str.Data, src_len, ret); - ret[new_len] = 0; + ret = malloc(sizeof(tUSBHub) + sizeof(ret->Devices[0])*PortCount); + ret->Interface = Device; + ret->nPorts = PortCount; + memset(ret->Devices, 0, sizeof(ret->Devices[0])*PortCount); return ret; } -int _UTF16to8(Uint16 *Input, int InputLen, char *Dest) +void USB_RemoveHub(tUSBHub *Hub) { - int str_len, cp_len; - Uint32 saved_bits = 0; - str_len = 0; - for( int i = 0; i < InputLen; i ++) + for( int i = 0; i < Hub->nPorts; i ++ ) { - Uint32 cp; - Uint16 val = Input[i]; - if( val >= 0xD800 && val <= 0xDBFF ) - { - // Multibyte - Leading - if(i + 1 > InputLen) { - cp = '?'; - } - else { - saved_bits = (val - 0xD800) << 10; - saved_bits += 0x10000; - continue ; - } - } - else if( val >= 0xDC00 && val <= 0xDFFF ) + if( Hub->Devices[i] ) { - if( !saved_bits ) { - cp = '?'; - } - else { - saved_bits |= (val - 0xDC00); - cp = saved_bits; - } + USB_DeviceDisconnected( Hub, i ); } - else - cp = val; - - cp_len = WriteUTF8((Uint8*)Dest, cp); - if(Dest) - Dest += cp_len; - str_len += cp_len; - - saved_bits = 0; } - - return str_len; + free(Hub); }