[USBUHCI_NEW] Bring-in the USB UHCI miniport driver created by Vadim Galyant. (#245)
[reactos.git] / drivers / usb / usbuhci_new / hardware.h
1 #define UHCI_FRAME_LIST_MAX_ENTRIES 1024 // Number of frames in Frame List
2 #define UHCI_NUM_ROOT_HUB_PORTS 2
3
4 /* UHCI HC I/O Registers offset (PUSHORT) */
5 #define UHCI_USBCMD 0 // USB Command R/W
6 #define UHCI_USBSTS 1 // USB Status R/WC
7 #define UHCI_USBINTR 2 // USB Interrupt Enable R/W
8 #define UHCI_FRNUM 3 // Frame Number R/W WORD writeable only
9 #define UHCI_FRBASEADD 4 // Frame List Base Address R/W // 32 bit
10 #define UHCI_SOFMOD 6 // Start Of Frame Modify R/W // 8 bit
11 #define UHCI_PORTSC1 8 // Port 1 Status/Control R/WC WORD writeable only
12 #define UHCI_PORTSC2 9 // Port 2 Status/Control R/WC WORD writeable only
13
14 /* PCI Legacy Support */
15 #define PCI_LEGSUP 0xC0 // Legacy Support register offset. R/WC
16 #define PCI_LEGSUP_USBPIRQDEN 0x2000
17 #define PCI_LEGSUP_CLEAR_SMI 0x8F00
18
19 /* LEGSUP Legacy support register (PCI Configuration - Function 2) */
20 typedef union _UHCI_PCI_LEGSUP {
21 struct {
22 USHORT Smi60Read : 1; // (60REN) Trap/SMI On 60h Read Enable. R/W.
23 USHORT Smi60Write : 1; // (60WEN) Trap/SMI On 60h Write Enable. R/W.
24 USHORT Smi64Read : 1; // (64REN) Trap/SMI On 64h Read Enable. R/W.
25 USHORT Smi64Write : 1; // (64WEN) Trap/SMI On 64h Write Enable. R/W.
26 USHORT SmiIrq : 1; // (USBSMIEN) Trap/SMI ON IRQ Enable. R/W.
27 USHORT A20Gate : 1; // (A20PTEN) A20Gate Pass Through Enable. R/W.
28 USHORT PassThroughStatus : 1; // (PSS) Pass Through Status. RO.
29 USHORT SmiEndPassThrough : 1; // (SMIEPTE) SMI At End Of Pass Through Enable. R/W.
30 USHORT TrapBy60ReadStatus : 1; // (TBY60R) Trap By 60h Read Status. R/WC.
31 USHORT TrapBy60WriteStatus : 1; // (TBY60W) Trap By 60h Write Status. R/WC.
32 USHORT TrapBy64ReadStatus : 1; // (TBY64R) Trap By 64h Read Status. R/WC.
33 USHORT TrapBy64WriteStatus : 1; // (TBY64W) Trap By 64h Write Status. R/WC.
34 USHORT UsbIrqStatus : 1; // (USBIRQS) USB IRQ Status. RO.
35 USHORT UsbPIRQ : 1; // (USBPIRQDEN) USB PIRQ Enable. R/W.
36 USHORT Reserved : 1;
37 USHORT EndA20GateStatus : 1; // (A20PTS) End OF A20GATE Pass Through Status. R/WC.
38 };
39 USHORT AsUSHORT;
40 } UHCI_PCI_LEGSUP;
41
42 C_ASSERT(sizeof(UHCI_PCI_LEGSUP) == sizeof(USHORT));
43
44 /* USBCMD Command register */
45 typedef union _UHCI_USB_COMMAND {
46 struct {
47 USHORT Run : 1;
48 USHORT HcReset : 1;
49 USHORT GlobalReset : 1;
50 USHORT GlobalSuspend : 1;
51 USHORT GlobalResume : 1; // Force Global Resume
52 USHORT SoftwareDebug : 1; // 0 - Normal Mode, 1 - Debug mode
53 USHORT ConfigureFlag : 1; // no effect on the hardware
54 USHORT MaxPacket : 1; // 0 = 32, 1 = 64
55 USHORT Reserved : 8;
56 };
57 USHORT AsUSHORT;
58 } UHCI_USB_COMMAND;
59
60 C_ASSERT(sizeof(UHCI_USB_COMMAND) == sizeof(USHORT));
61
62 /* USBSTS Status register */
63 #define UHCI_USB_STATUS_MASK 0x3F
64
65 typedef union _UHCI_USB_STATUS {
66 struct {
67 USHORT Interrupt : 1; // due to IOC (Interrupt On Complete)
68 USHORT ErrorInterrupt : 1; // due to error
69 USHORT ResumeDetect : 1;
70 USHORT HostSystemError : 1; // PCI problems
71 USHORT HcProcessError : 1; // Schedule is buggy
72 USHORT HcHalted : 1;
73 USHORT Reserved : 10;
74 };
75 USHORT AsUSHORT;
76 } UHCI_USB_STATUS;
77
78 C_ASSERT(sizeof(UHCI_USB_STATUS) == sizeof(USHORT));
79
80 /* USBINTR Interrupt enable register */
81 typedef union _UHCI_INTERRUPT_ENABLE {
82 struct {
83 USHORT TimeoutCRC : 1; // Timeout/CRC error enable
84 USHORT ResumeInterrupt : 1;
85 USHORT InterruptOnComplete : 1;
86 USHORT ShortPacket : 1;
87 USHORT Reserved : 12;
88 };
89 USHORT AsUSHORT;
90 } UHCI_INTERRUPT_ENABLE;
91
92 C_ASSERT(sizeof(UHCI_INTERRUPT_ENABLE) == sizeof(USHORT));
93
94 /* FRNUM Frame Number register */
95 #define UHCI_FRNUM_FRAME_MASK 0x7FF
96 #define UHCI_FRNUM_INDEX_MASK 0x3FF
97 #define UHCI_FRNUM_OVERFLOW_LIST 0x400
98
99 /* PORTSC(1|2) USB port status and control registers */
100 typedef union _UHCI_PORT_STATUS_CONTROL {
101 struct {
102 USHORT CurrentConnectStatus : 1;
103 USHORT ConnectStatusChange : 1;
104 USHORT PortEnabledDisabled : 1;
105 USHORT PortEnableDisableChange : 1;
106 USHORT LineStatus : 2; // D+ and D-
107 USHORT ResumeDetect : 1;
108 USHORT Reserved1 : 1; // always 1
109 USHORT LowSpeedDevice : 1; // LS device Attached
110 USHORT PortReset : 1;
111 USHORT Reserved2 : 2; // Intel use it (not UHCI 1.1d spec)
112 USHORT Suspend : 1;
113 USHORT Reserved3 : 3; // write zeroes
114 };
115 USHORT AsUSHORT;
116 } UHCI_PORT_STATUS_CONTROL;
117
118 C_ASSERT(sizeof(UHCI_PORT_STATUS_CONTROL) == sizeof(USHORT));
119
120 typedef struct _UHCI_HW_REGISTERS {
121 UHCI_USB_COMMAND HcCommand; // R/W
122 UHCI_USB_STATUS HcStatus; // R/WC
123 UHCI_INTERRUPT_ENABLE HcInterruptEnable; // R/W
124 USHORT FrameNumber; // R/W WORD writeable only
125 ULONG FrameAddress; // R/W
126 UCHAR SOF_Modify; // R/W
127 UCHAR Reserved[3];
128 UHCI_PORT_STATUS_CONTROL PortControl[UHCI_NUM_ROOT_HUB_PORTS]; // R/WC WORD writeable only
129 } UHCI_HW_REGISTERS, *PUHCI_HW_REGISTERS;
130
131 /* Transfer Descriptor (TD) */
132 #define UHCI_TD_STS_ACTIVE (1 << 7)
133 #define UHCI_TD_STS_STALLED (1 << 6)
134 #define UHCI_TD_STS_DATA_BUFFER_ERROR (1 << 5)
135 #define UHCI_TD_STS_BABBLE_DETECTED (1 << 4)
136 #define UHCI_TD_STS_NAK_RECEIVED (1 << 3)
137 #define UHCI_TD_STS_TIMEOUT_CRC_ERROR (1 << 2)
138 #define UHCI_TD_STS_BITSTUFF_ERROR (1 << 1)
139 //#define UHCI_TD_STS_Reserved (1 << 0)
140
141 #define UHCI_TD_VALID_LENGTH 0x4FF
142 #define UHCI_TD_LENGTH_INVALID 0x7FE
143 #define UHCI_TD_LENGTH_NULL 0x7FF
144
145 typedef union _UHCI_CONTROL_STATUS {
146 struct {
147 ULONG ActualLength : 11; // encoded as n - 1
148 ULONG Reserved1 : 5;
149 ULONG Status : 8; // UHCI_TD_STS_ xxx
150 ULONG InterruptOnComplete : 1;
151 ULONG IsochronousType : 1;
152 ULONG LowSpeedDevice : 1;
153 ULONG ErrorCounter : 2;
154 ULONG ShortPacketDetect : 1;
155 ULONG Reserved2 : 2;
156 };
157 ULONG AsULONG;
158 } UHCI_CONTROL_STATUS;
159
160 C_ASSERT(sizeof(UHCI_CONTROL_STATUS) == sizeof(ULONG));
161
162 #define UHCI_TD_PID_IN 0x69
163 #define UHCI_TD_PID_OUT 0xE1
164 #define UHCI_TD_PID_SETUP 0x2D
165
166 #define UHCI_TD_PID_DATA0 0
167 #define UHCI_TD_PID_DATA1 1
168
169 typedef union _UHCI_TD_TOKEN {
170 struct {
171 ULONG PIDCode : 8;
172 ULONG DeviceAddress : 7;
173 ULONG Endpoint : 4;
174 ULONG DataToggle : 1;
175 ULONG Reserved : 1;
176 ULONG MaximumLength : 11;
177 };
178 ULONG AsULONG;
179 } UHCI_TD_TOKEN;
180
181 C_ASSERT(sizeof(UHCI_TD_TOKEN) == sizeof(ULONG));
182
183 #define UHCI_TD_LINK_PTR_VALID (0 << 0)
184 #define UHCI_TD_LINK_PTR_TERMINATE (1 << 0)
185 #define UHCI_TD_LINK_PTR_TD (0 << 1)
186 #define UHCI_TD_LINK_PTR_QH (1 << 1)
187 #define UHCI_TD_LINK_PTR_BREADTH_FIRST (0 << 2)
188 #define UHCI_TD_LINK_PTR_DEPTH_FIRST (1 << 2)
189 #define UHCI_TD_LINK_POINTER_MASK 0xFFFFFFF0
190
191 typedef struct _UHCI_TD { // Transfer Descriptors always aligned on 16-byte boundaries
192 ULONG NextElement;
193 UHCI_CONTROL_STATUS ControlStatus;
194 UHCI_TD_TOKEN Token;
195 ULONG Buffer;
196 } UHCI_TD, *PUHCI_TD;
197
198 C_ASSERT(sizeof(UHCI_TD) == 16);
199
200 /* Queue Header (QH) */
201 #define UHCI_QH_HEAD_LINK_PTR_VALID (0 << 0)
202 #define UHCI_QH_HEAD_LINK_PTR_TERMINATE (1 << 0)
203 #define UHCI_QH_HEAD_LINK_PTR_TD (0 << 1)
204 #define UHCI_QH_HEAD_LINK_PTR_QH (1 << 1)
205 #define UHCI_QH_HEAD_LINK_POINTER_MASK 0xFFFFFFF0
206
207 #define UHCI_QH_ELEMENT_LINK_PTR_VALID (0 << 0)
208 #define UHCI_QH_ELEMENT_LINK_PTR_TERMINATE (1 << 0)
209 #define UHCI_QH_ELEMENT_LINK_PTR_TD (0 << 1)
210 #define UHCI_QH_ELEMENT_LINK_PTR_QH (1 << 1)
211 #define UHCI_QH_ELEMENT_LINK_POINTER_MASK 0xFFFFFFF0
212
213 typedef struct _UHCI_QH { // Queue Heads must be aligned on a 16-byte boundary
214 ULONG NextQH;
215 ULONG NextElement;
216 } UHCI_QH, *PUHCI_QH;
217
218 C_ASSERT(sizeof(UHCI_QH) == 8);