Merge branch 'master' of github.com:thepowersgang/acess2
[tpg/acess2.git] / KernelLand / Modules / USB / EHCI / ehci.h
index 120c2f4..9cc4bb2 100644 (file)
@@ -8,6 +8,10 @@
 #ifndef _EHCI_H_
 #define _EHCI_H_
 
+#include <threads.h>
+
+#define PERIODIC_SIZE  1024
+
 typedef struct sEHCI_CapRegs   tEHCI_CapRegs;
 typedef struct sEHCI_OpRegs    tEHCI_OpRegs;
 typedef struct sEHCI_iTD       tEHCI_iTD;
@@ -90,7 +94,7 @@ struct sEHCI_OpRegs
         * 15    = Asynchronous Schedule Status
         * 16:31 = Reserved ?(Zero)
         */
-       Uint32  USBSts;
+       volatile Uint32 USBSts;
        /**
         * USB Interrupt Enable Register
         *
@@ -108,7 +112,7 @@ struct sEHCI_OpRegs
         * 
         * Bits 14:3 are used as n index into PeridocListBase
         */
-       Uint32  FrIndex;
+       volatile Uint32 FrIndex;
        /**
         * Control Data Structure Segment Register
         *
@@ -157,7 +161,7 @@ struct sEHCI_OpRegs
         * 22    = Wake on Over-current Enable
         * 23:31 = Reserved (ZERO)
         */
-       Uint32  PortSC[15];
+       volatile Uint32 PortSC[15];
 };
 
 #define USBCMD_Run     0x0001
@@ -172,6 +176,29 @@ struct sEHCI_OpRegs
 #define USBINTR_HostSystemError        0x0010
 #define USBINTR_AsyncAdvance   0x0020
 
+#define PORTSC_CurrentConnectStatus    0x0001
+#define PORTSC_ConnectStatusChange     0x0002
+#define PORTSC_PortEnabled     0x0004
+#define PORTSC_PortEnableChange        0x0008
+#define PORTSC_OvercurrentActive       0x0010
+#define PORTSC_OvercurrentChange       0x0020
+#define PORTSC_ForcePortResume 0x0040
+#define PORTSC_Suspend         0x0080
+#define PORTSC_PortReset       0x0100
+#define PORTSC_Reserved1       0x0200
+#define PORTSC_LineStatus_MASK 0x0C00
+#define PORTSC_LineStatus_SE0          0x0000
+#define PORTSC_LineStatus_Jstate       0x0400
+#define PORTSC_LineStatus_Kstate       0x0800
+#define PORTSC_LineStatus_Undef        0x0C00
+#define PORTSC_PortPower       0x1000
+#define PORTSC_PortOwner       0x2000
+#define PORTSC_PortIndicator_MASK      0xC000
+#define PORTSC_PortIndicator_Off       0x0000
+#define PORTSC_PortIndicator_Amber     0x4000
+#define PORTSC_PortIndicator_Green     0x800
+
+// Isochronous (High-Speed) Transfer Descriptor
 struct sEHCI_iTD
 {
        Uint32  Link;
@@ -189,6 +216,7 @@ struct sEHCI_iTD
        Uint32  BufferPointers[8];      // Page aligned, low 12 bits are overloaded
 };
 
+// Split Transaction Isochronous Transfer Descriptor
 struct sEHCI_siTD
 {
        Uint32  Link;
@@ -200,30 +228,73 @@ struct sEHCI_siTD
        Uint32  BackLink;
 };
 
+// Queue Element Transfer Descriptor
 struct sEHCI_qTD
 {
        Uint32  Link;
        Uint32  Link2;  // Used when there's a short packet
        Uint32  Token;
        Uint32  Pages[5];       //First has offset in low 12 bits
-};
+       
+       // Internals (32 bytes = 4x 64-bit pointers)
+       tUSBHostCb      *Callback;
+       void    *CallbackData;
+       tEHCI_qTD       *Next;
+} __attribute__((aligned(32)));
+// sizeof = 64
 
+// Queue Head
 struct sEHCI_QH
 {
        Uint32  HLink;  // Horizontal link
        Uint32  Endpoint;
        Uint32  EndpointExt;
        Uint32  CurrentTD;
-       tEHCI_qTD       Overlay;
-};
+       struct {
+               Uint32  Link;
+               Uint32  Link2;
+               Uint32  Token;
+               Uint32  Pages[5];
+       }       Overlay;
+       struct {
+               Uint8   IntOfs;
+               Uint8   IntPeriodPow;
+               tEHCI_QH        *Next;
+       } Impl;
+} __attribute__((aligned(32)));
+// sizeof = 48 (round up to 64)
+
+#define PID_OUT        0
+#define PID_IN         1
+#define PID_SETUP      2
+
+#define TD_POOL_SIZE   (PAGE_SIZE/sizeof(tEHCI_qTD))
+// - 256 addresses * 16 endpoints
+#define QH_POOL_SIZE   (256*16)
+#define QH_POOL_PAGES  (QH_POOL_SIZE*sizeof(tEHCI_QH)/PAGE_SIZE)
+#define QH_POOL_NPERPAGE       (PAGE_SIZE/sizeof(tEHCI_QH))
 
 struct sEHCI_Controller
 {
+       tUSBHub *RootHub;
+       tThread *InterruptThread;
+        int    nPorts;
+
        tPAddr  PhysBase;
        tEHCI_CapRegs   *CapRegs;
        tEHCI_OpRegs    *OpRegs;
 
-       Uint32  *PeriodicQueue;
+        int    InterruptLoad[PERIODIC_SIZE];
+       tEHCI_QH        *LastAsyncHead;
+       
+       tMutex          PeriodicListLock;
+       Uint32          *PeriodicQueue;
+       tEHCI_QH        *PeriodicQueueV[PERIODIC_SIZE];
+       
+       tMutex  QHPoolMutex;
+       tEHCI_QH        *QHPools[QH_POOL_PAGES];        // [PAGE_SIZE/64]
+       tMutex  TDPoolMutex;
+       tEHCI_qTD       *TDPool;        // [TD_POOL_SIZE]
 };
 
 #endif

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