X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FUSB%2FEHCI%2Fehci.h;h=598c8d4978c56e34bf658db89a925f1d109381c6;hb=36b950d17b828c7cd2e5e9dbe5fb4cbded89889c;hp=431b039146496546032be78ff9ed7006aba373c6;hpb=aaf85604703ec62e863eb1a1d0bb327c838bb621;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/USB/EHCI/ehci.h b/KernelLand/Modules/USB/EHCI/ehci.h index 431b0391..598c8d49 100644 --- a/KernelLand/Modules/USB/EHCI/ehci.h +++ b/KernelLand/Modules/USB/EHCI/ehci.h @@ -8,6 +8,18 @@ #ifndef _EHCI_H_ #define _EHCI_H_ +#include + +#define PERIODIC_SIZE 1024 + +typedef struct sEHCI_CapRegs tEHCI_CapRegs; +typedef struct sEHCI_OpRegs tEHCI_OpRegs; +typedef struct sEHCI_iTD tEHCI_iTD; +typedef struct sEHCI_siTD tEHCI_siTD; +typedef struct sEHCI_qTD tEHCI_qTD; +typedef struct sEHCI_QH tEHCI_QH; +typedef struct sEHCI_Controller tEHCI_Controller; + struct sEHCI_CapRegs { Uint8 CapLength; // Byte offset of Operational registers @@ -82,7 +94,7 @@ struct sEHCI_OpRegs * 15 = Asynchronous Schedule Status * 16:31 = Reserved ?(Zero) */ - Uint32 USBSts; + volatile Uint32 USBSts; /** * USB Interrupt Enable Register * @@ -100,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 * @@ -149,7 +161,142 @@ struct sEHCI_OpRegs * 22 = Wake on Over-current Enable * 23:31 = Reserved (ZERO) */ - Uint32 PortSC[15]; + volatile Uint32 PortSC[15]; +}; + +#define USBCMD_Run 0x0001 +#define USBCMD_HCReset 0x0002 +#define USBCMD_PeriodicEnable 0x0010 +#define USBCMD_AsyncEnable 0x0020 + +#define USBINTR_IOC 0x0001 +#define USBINTR_Error 0x0002 +#define USBINTR_PortChange 0x0004 +#define USBINTR_FrameRollover 0x0008 +#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; + struct { + Uint16 Offset; + Uint16 LengthSts; + } Transactions[8]; + // -- 0 -- + // 0:6 - Device + // 7 - Reserved + // 8:11 - Endpoint + // -- 1 -- + // 0:10 - Max packet size + // 11 - IN/OUT + Uint32 BufferPointers[8]; // Page aligned, low 12 bits are overloaded +}; + +// Split Transaction Isochronous Transfer Descriptor +struct sEHCI_siTD +{ + Uint32 Link; + Uint32 Dest; + Uint32 uFrame; + Uint32 StatusLength; + Uint32 Page0; + Uint32 Page1; + 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; + 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; + + tEHCI_qTD *DeadTD; + + 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