From 3ab2857efdcb81ce34dabf4d07b39ad6f5ab0b4a Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 28 Nov 2011 18:28:47 +0800 Subject: [PATCH] Modules/USB - Working on driver support, little headache --- Modules/USB/Core/hub.c | 66 +++++++++++++++++++++++++ Modules/USB/Core/include/usb_core.h | 40 +++++++++------ Modules/USB/Core/include/usb_hub.h | 4 +- Modules/USB/Core/main.c | 6 +-- Modules/USB/Core/usb.c | 75 ++++++++++++++++++++--------- Modules/USB/Core/usb.h | 36 ++++++++++++-- Modules/USB/Core/usb_proto.h | 4 +- Modules/USB/UHCI/uhci.c | 8 --- 8 files changed, 182 insertions(+), 57 deletions(-) create mode 100644 Modules/USB/Core/hub.c diff --git a/Modules/USB/Core/hub.c b/Modules/USB/Core/hub.c new file mode 100644 index 00000000..4afde693 --- /dev/null +++ b/Modules/USB/Core/hub.c @@ -0,0 +1,66 @@ +/* + * Acess2 USB Stack + * - By John Hodge (thePowersGang) + * + * hub.c + * - Basic hub driver + */ +#include + +struct sHubInfo +{ + int nPorts; +}; + +// === PROTOTYPES === +void Hub_Connected(tUSBInterface *Dev); +void Hub_Disconnected(tUSBInterface *Dev); +void Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data); + +// === GLOBALS === +tUSBDriver gUSBHub_Driver = { + .Name = "Hub", + .Match = {.Class = {0x090000, 0xFF0000}}, + .Connected = Hub_Connected, + .Disconnected = Hub_Disconnected, + .MaxEndpoints = 1, + .Endpoints = { + {0x83, Hub_PortStatusChange} + }; +}; + +// === CODE === +void Hub_Connected(tUSBInterface *Dev) +{ + // Register poll on endpoint + USB_PollEndpoint(Dev, 0); + + USB_RegisterHub(Dev, nPorts); +} + +void Hub_Disconnected(tUSBInterface *Dev) +{ +} + +void Hub_PortStatusChange(tUSBInterface *Dev, int Length, void *Data) +{ + int i; + Uint8 *status = Data; + for( i = 0; i < info->nPorts; i += 8, status ++ ) + { + if( i/8 >= Length ) break; + if( *status == 0 ) continue; + + for( int j = 0; j < 8; j ++ ) + if( *status & (1 << j) ) + Hub_int_HandleChange(Dev, i+j); + } +} + +void Hub_int_HandleChange(tUSBInterface *Dev, int Port) +{ + Uint16 status[2]; // Status, Change + // Get change status + USB_Request(Dev, 0, 0xA3, 0, 0, Port, 4, status); +} + diff --git a/Modules/USB/Core/include/usb_core.h b/Modules/USB/Core/include/usb_core.h index d8d16363..2a8ce9d8 100644 --- a/Modules/USB/Core/include/usb_core.h +++ b/Modules/USB/Core/include/usb_core.h @@ -8,7 +8,7 @@ #ifndef _USB_CORE_H_ #define _USB_CORE_H_ -typedef struct sUSBDevice tUSBDevice; +typedef struct sUSBInterface tUSBInterface; typedef struct sUSBDriver tUSBDriver; /** @@ -18,29 +18,39 @@ struct sUSBDriver tUSBDriver *Next; const char *Name; - - // 23:16 - Interface Class - // 15:8 - Interface Sub Class - // 7:0 - Interface Protocol - Uint32 ClassMask; - Uint32 ClassCode; - void (*Connected)(tUSBDevice *Dev); - void (*Disconnected)(tUSBDevice *Dev); + int MatchType; // 0: Interface, 1: Device, 2: Vendor + union { + struct { + // 23:16 - Interface Class + // 15:8 - Interface Sub Class + // 7:0 - Interface Protocol + Uint32 ClassMask; + Uint32 ClassCode; + } Class; + struct { + Uint16 VendorID; + Uint16 DeviceID; + } VendorDev; + } Match; + + void (*Connected)(tUSBInterface *Dev); + void (*Disconnected)(tUSBInterface *Dev); int MaxEndpoints; struct { - // 0: Bulk, 1: Control, 2: Interrupt - int Type; + // USB Attrbute byte + // NOTE: Top bit indicates the direction (1=Input) + Uint8 Attributes; // Data availiable Callback - void (*Interrupt)(tUSBDevice *Dev, int Length, void *Data); + void (*DataAvail)(tUSBInterface *Dev, int Length, void *Data); } Endpoints[]; }; -extern void *USB_GetDeviceDataPtr(tUSBDevice *Dev); -extern void USB_SetDeviceDataPtr(tUSBDevice *Dev, void *Ptr); +extern void *USB_GetDeviceDataPtr(tUSBInterface *Dev); +extern void USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr); -extern void USB_SendData(tUSBDevice *Dev, int Endpoint, int Length, void *Data); +extern void USB_SendData(tUSBInterface *Dev, int Endpoint, int Length, void *Data); #endif diff --git a/Modules/USB/Core/include/usb_hub.h b/Modules/USB/Core/include/usb_hub.h index f48936bc..42fbeabc 100644 --- a/Modules/USB/Core/include/usb_hub.h +++ b/Modules/USB/Core/include/usb_hub.h @@ -12,14 +12,12 @@ typedef struct sUSBHub tUSBHub; -typedef void (*tUSB_HubPoll)(tUSBHub *Hub, tUSBDevice *HubDev); - /** * \brief Register a device as a hub * * Used by the hub class initialisation routine. */ -extern tUSBHub USB_RegisterHub(tUSBDevice *Device, int nPorts, tUSB_HubPoll PollCallback); +extern tUSBHub USB_RegisterHub(tUSBInterface *Device, int nPorts); extern void USB_DeviceConnected(tUSBHub *Hub, int Port); extern void USB_DeviceDisconnected(tUSBHub *Hub, int Port); diff --git a/Modules/USB/Core/main.c b/Modules/USB/Core/main.c index d99ef3a5..277cf7c6 100644 --- a/Modules/USB/Core/main.c +++ b/Modules/USB/Core/main.c @@ -30,8 +30,8 @@ tDevFS_Driver gUSB_DrvInfo = { } }; tUSBHost *gUSB_Hosts = NULL; -tUSBDevice *gUSB_InterruptDevs = NULL; -tUSBDevice *gUSB_InterruptLast = NULL; +tUSBInterface *gUSB_InterruptDevs = NULL; +tUSBInterface *gUSB_InterruptLast = NULL; // === CODE === /** @@ -50,7 +50,7 @@ int USB_PollThread(void *unused) { for(;;) { - for( tUSBDevice *dev = gUSB_InterruptDevs; dev; dev = dev->Next ) + for( tUSBInterface *dev = gUSB_InterruptDevs; dev; dev = dev->Next ) { // hub->CheckPorts(hub, hub->Device); } diff --git a/Modules/USB/Core/usb.c b/Modules/USB/Core/usb.c index 52968e30..7713435b 100644 --- a/Modules/USB/Core/usb.c +++ b/Modules/USB/Core/usb.c @@ -18,8 +18,8 @@ extern tUSBHost *gUSB_Hosts; 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); +void *USB_GetDeviceDataPtr(tUSBInterface *Dev); +void USB_SetDeviceDataPtr(tUSBInterface *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); @@ -41,12 +41,12 @@ 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.Next = NULL; host->RootHubDev.ParentHub = NULL; host->RootHubDev.Host = host; host->RootHubDev.Address = 0; - host->RootHubDev.Driver = NULL; - host->RootHubDev.Data = NULL; +// host->RootHubDev.Driver = NULL; +// host->RootHubDev.Data = NULL; host->RootHub.Device = &host->RootHubDev; host->RootHub.CheckPorts = NULL; @@ -72,12 +72,12 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port) // Create structure dev = malloc(sizeof(tUSBDevice)); - dev->Next = NULL; +// dev->Next = NULL; dev->ParentHub = Hub; dev->Host = Hub->Device->Host; dev->Address = 0; - dev->Driver = 0; - dev->Data = 0; +// dev->Driver = 0; +// dev->Data = 0; // 1. Assign an address dev->Address = USB_int_AllocateAddress(dev->Host); @@ -171,7 +171,7 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port) // TODO: Sanity check with remaining space cur_ptr += sizeof(*iface); - LOG("Interface %i/%i = {"); + LOG("Interface %i/%i = {", i, j); LOG(" .InterfaceNum = %i", iface->InterfaceNum); LOG(" .NumEndpoints = %i", iface->NumEndpoints); LOG(" .InterfaceClass = 0x%x", iface->InterfaceClass); @@ -192,7 +192,12 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port) // TODO: Sanity check with remaining space cur_ptr += sizeof(*endpt); - + LOG("Endpoint %i/%i/%i = {", i, j, k); + LOG(" .Address = 0x%2x", endpt->Address); + LOG(" .Attributes = 0b%8b", endpt->Attributes); + LOG(" .MaxPacketSize = %i", LittleEndian16(endpt->MaxPacketSize)); + LOG(" .PollingInterval = %i", endpt->PollingInterval); + LOG("}"); } } @@ -208,8 +213,8 @@ 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; } +void *USB_GetDeviceDataPtr(tUSBInterface *Dev) { return Dev->Data; } +void USB_SetDeviceDataPtr(tUSBInterface *Dev, void *Ptr) { Dev->Data = Ptr; } int USB_int_AllocateAddress(tUSBHost *Host) { @@ -229,6 +234,34 @@ void USB_int_DeallocateAddress(tUSBHost *Host, int Address) Host->AddressBitmap[Address/8] &= ~(1 << (Address%8)); } +void *USB_int_Request(tUSBHost *Host, int Addr, int EndPt, int Type, int Req, int Val, int Indx, int Len, void *Data) +{ + void *hdl; + // TODO: Sanity check (and check that Type is valid) + struct sDeviceRequest req; + req.ReqType = Type; + req.Request = Req; + req.Value = LittleEndian16( Val ); + req.Index = LittleEndian16( Indx ); + req.Length = LittleEndian16( Len ); + + hdl = Host->HostDef->SendSETUP(Host->Ptr, Addr, EndPt, 0, NULL, &req, sizeof(req)); + + // TODO: Data toggle? + // TODO: Correct sequence? (Some OUT requests need an IN) + if( Type & 0x80 ) + { + hdl = Host->HostDef->SendIN(Host->Ptr, Addr, EndPt, 0, NULL, Data, Len); + while( Host->HostDef->IsOpComplete(Host->Ptr, hdl) == 0 ) + Time_Delay(1); + } + else + { + hdl = Host->HostDef->SendOUT(Host->Ptr, Addr, EndPt, 0, NULL, Data, Len); + } + return hdl; +} + int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address) { void *hdl; @@ -241,12 +274,11 @@ int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address) 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)); + hdl = Host->HostDef->SendSETUP(Host->Ptr, 0, 0, 0, NULL, &req, sizeof(req)); if(!hdl) return 1; - // TODO: Data toggle? - hdl = Host->HostDef->SendIN(Host->Ptr, 0, 0, 0, FALSE, NULL, 0); + hdl = Host->HostDef->SendIN(Host->Ptr, 0, 0, 0, NULL, NULL, 0); while( Host->HostDef->IsOpComplete(Host->Ptr, hdl) == 0 ) Time_Delay(1); @@ -304,13 +336,12 @@ char *USB_int_GetDeviceString(tUSBDevice *Dev, int Endpoint, int Index) char *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); - } +// if(str.Length > sizeof(str)) { +// // IMPOSSIBLE! +// Log_Error("USB", "String is %i bytes, which is over prealloc size (%i)", +// str.Length, sizeof(str) +// ); +// } src_len = (str.Length - 2) / sizeof(str.Data[0]); new_len = _UTF16to8(str.Data, src_len, NULL); diff --git a/Modules/USB/Core/usb.h b/Modules/USB/Core/usb.h index 177d7c7f..c293c7db 100644 --- a/Modules/USB/Core/usb.h +++ b/Modules/USB/Core/usb.h @@ -10,6 +10,8 @@ #include typedef struct sUSBHost tUSBHost; +typedef struct sUSBDevice tUSBDevice; +typedef struct sUSBEndpoint tUSBEndpoint; // === STRUCTURES === /** @@ -25,12 +27,38 @@ struct sUSBHub tUSBDevice *Devices[]; }; +struct sUSBEndpoint +{ + tUSBInterface *Interface; + tUSBEndpoint *Next; // In the poll list + int PollingPeriod; // In 1ms intervals + int MaxPacketSize; // In bytes + + char Direction; // 1 Polled Input, 0 Output + + Uint8 Type; // Same as sDescriptor_Endpoint.Type +}; + +/** + * \brief Structure for a device's interface + */ +struct sUSBInterface +{ + tUSBInterface *Next; + tUSBDevice *Dev; + + tUSBDriver *Driver; + void *Data; + + int nEndpoints; + tUSBEndpoint Endpoints[]; +}; + /** * \brief Defines a single device on the USB Bus */ struct sUSBDevice { - tUSBDevice *Next; tUSBHub *ParentHub; /** @@ -38,9 +66,9 @@ struct sUSBDevice */ tUSBHost *Host; int Address; - - tUSBDriver *Driver; - void *Data; + + int nInterfaces; + tUSBInterface *Interfaces[]; }; struct sUSBHost diff --git a/Modules/USB/Core/usb_proto.h b/Modules/USB/Core/usb_proto.h index b5399e8e..2ac2781f 100644 --- a/Modules/USB/Core/usb_proto.h +++ b/Modules/USB/Core/usb_proto.h @@ -53,7 +53,7 @@ struct sDescriptor_String Uint8 Length; Uint8 Type; // = 3 - Uint16 Data[62]; // 62 is arbitary + Uint16 Data[128-1]; // (256 bytes - 2 bytes) / Uint16 } PACKED; struct sDescriptor_Interface @@ -76,7 +76,7 @@ struct sDescriptor_Endpoint { Uint8 Length; Uint8 Type; // = 5 - Uint8 Address; // 3:0 Endpoint Num, 7: Direction (IN/OUT) + Uint8 Address; // 3:0 Endpoint Num, 7: Direction (1=IN) /** * 1:0 - Transfer Type * - 00 = Control diff --git a/Modules/USB/UHCI/uhci.c b/Modules/USB/UHCI/uhci.c index aa1dd129..9fd82303 100644 --- a/Modules/USB/UHCI/uhci.c +++ b/Modules/USB/UHCI/uhci.c @@ -27,7 +27,6 @@ void *UHCI_DataIN(void *Ptr, int Fcn, int Endpt, int DataTgl, tUSBHostCb Cb, voi void *UHCI_DataOUT(void *Ptr, int Fcn, int Endpt, int DataTgl, tUSBHostCb Cb, void *Data, size_t Length); void *UHCI_SendSetup(void *Ptr, int Fcn, int Endpt, int DataTgl, tUSBHostCb Cb, void *Data, size_t Length); int UHCI_IsTransferComplete(void *Ptr, void *Handle); -void UHCI_Hub_Poll(tUSBHub *Hub, tUSBDevice *Dev); int UHCI_Int_InitHost(tUHCI_Controller *Host); void UHCI_CheckPortUpdate(tUHCI_Controller *Host); void UHCI_InterruptHandler(int IRQ, void *Ptr); @@ -245,13 +244,6 @@ int UHCI_IsTransferComplete(void *Ptr, void *Handle) return !(td->Control & (1 << 23)); } -void UHCI_Hub_Poll(tUSBHub *Hub, tUSBDevice *Dev) -{ - tUHCI_Controller *cont = USB_GetDeviceDataPtr(Dev); - - UHCI_CheckPortUpdate(cont); -} - // === INTERNAL FUNCTIONS === /** * \fn int UHCI_Int_InitHost(tUCHI_Controller *Host) -- 2.20.1