From 662713ac7494f05339cee056a3d9f72e2357c492 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 25 Nov 2011 14:03:44 +0800 Subject: [PATCH] Modules/USB - Fiddling with USB --- Modules/USB/Core/main.c | 8 +-- Modules/USB/Core/usb.c | 105 ++++++++++++++++++++++++++++++++++++++-- Modules/USB/Core/usb.h | 6 ++- Modules/USB/UHCI/uhci.c | 7 ++- 4 files changed, 114 insertions(+), 12 deletions(-) diff --git a/Modules/USB/Core/main.c b/Modules/USB/Core/main.c index baf13320..d99ef3a5 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; -tUSBHub *gUSB_Hubs = NULL; -tUSBHub *gUSB_HubsEnd = NULL; +tUSBDevice *gUSB_InterruptDevs = NULL; +tUSBDevice *gUSB_InterruptLast = NULL; // === CODE === /** @@ -50,9 +50,9 @@ int USB_PollThread(void *unused) { for(;;) { - for( tUSBHub *hub = gUSB_Hubs; hub; hub = hub->Next ) + for( tUSBDevice *dev = gUSB_InterruptDevs; dev; dev = dev->Next ) { - hub->CheckPorts(hub, hub->Device); +// hub->CheckPorts(hub, hub->Device); } // TODO: Fine tune Time_Delay(250); diff --git a/Modules/USB/Core/usb.c b/Modules/USB/Core/usb.c index de884e48..0b4bc638 100644 --- a/Modules/USB/Core/usb.c +++ b/Modules/USB/Core/usb.c @@ -9,24 +9,90 @@ #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 === tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts) { - // TODO: - return NULL; + 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) @@ -49,7 +115,7 @@ int USB_int_AllocateAddress(tUSBHost *Host) return 0; } -int USB_int_SendSetupSetAddress(tUSBHost *Host, void *Ptr, int Address) +int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address) { struct sDeviceRequest req; req.ReqType = 0; // bmRequestType @@ -59,5 +125,36 @@ int USB_int_SendSetupSetAddress(tUSBHost *Host, void *Ptr, int Address) req.Length = 0; // wLength // Addr 0:0, Data Toggle = 0, no interrupt - return Host->HostDef->SendSETUP(Ptr, 0, 0, 0, FALSE, &req, sizeof(req)) == 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; } diff --git a/Modules/USB/Core/usb.h b/Modules/USB/Core/usb.h index 65bba9d0..177d7c7f 100644 --- a/Modules/USB/Core/usb.h +++ b/Modules/USB/Core/usb.h @@ -17,7 +17,6 @@ typedef struct sUSBHost tUSBHost; */ struct sUSBHub { - tUSBHub *Next; tUSBDevice *Device; tUSB_HubPoll CheckPorts; @@ -32,7 +31,7 @@ struct sUSBHub struct sUSBDevice { tUSBDevice *Next; - tUSBDevice *ParentHub; + tUSBHub *ParentHub; /** * \brief Host controller used @@ -52,6 +51,9 @@ struct sUSBHost void *Ptr; Uint8 AddressBitmap[128/8]; + + tUSBDevice RootHubDev; + tUSBHub RootHub; }; extern void USB_NewDevice(tUSBHub *Hub); diff --git a/Modules/USB/UHCI/uhci.c b/Modules/USB/UHCI/uhci.c index 8e41e27a..0f725230 100644 --- a/Modules/USB/UHCI/uhci.c +++ b/Modules/USB/UHCI/uhci.c @@ -59,7 +59,6 @@ int UHCI_Initialise(const char **Arguments) // NOTE: Check "protocol" from PCI? cinfo->PciId = id; - // Assign a port range (BAR4, Reserve 32 ports) cinfo->IOBase = PCI_GetBAR(id, 4); if( !(cinfo->IOBase & 1) ) { Log_Warning("UHCI", "MMIO is not supported"); @@ -142,6 +141,7 @@ void *UHCI_int_SendTransaction(tUHCI_Controller *Cont, int Addr, Uint8 Type, int // TODO: Ensure 32-bit paddr if( ((tVAddr)Data & PAGE_SIZE) + Length > PAGE_SIZE ) { Log_Warning("UHCI", "TODO: Support non single page transfers"); + // TODO: Need to enable IOC to copy the data back // td->BufferPointer = return NULL; } @@ -150,7 +150,8 @@ void *UHCI_int_SendTransaction(tUHCI_Controller *Cont, int Addr, Uint8 Type, int } if( bIOC ) { -// td->Control + td->Control |= (1 << 24); + Log_Warning("UHCI", "TODO: Support IOC... somehow"); } UHCI_int_AppendTD(Cont, td); @@ -247,10 +248,12 @@ void UHCI_CheckPortUpdate(tUHCI_Controller *Host) { LOG("Port %i has something", i); // Reset port (set bit 9) + LOG("Reset"); outw( port, 0x0100 ); Time_Delay(50); // 50ms delay outw( port, inw(port) & ~0x0100 ); // Enable port + LOG("Enable"); Time_Delay(50); // 50ms delay outw( port, inw(port) & 0x0004 ); // Tell USB there's a new device -- 2.20.1