Modules/USB - Fiddling with USB
authorJohn Hodge <[email protected]>
Fri, 25 Nov 2011 06:03:44 +0000 (14:03 +0800)
committerJohn Hodge <[email protected]>
Fri, 25 Nov 2011 06:03:44 +0000 (14:03 +0800)
Modules/USB/Core/main.c
Modules/USB/Core/usb.c
Modules/USB/Core/usb.h
Modules/USB/UHCI/uhci.c

index baf1332..d99ef3a 100644 (file)
@@ -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);
index de884e4..0b4bc63 100644 (file)
@@ -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;
 }
index 65bba9d..177d7c7 100644 (file)
@@ -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);
index 8e41e27..0f72523 100644 (file)
@@ -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

UCC git Repository :: git.ucc.asn.au