1 #pragma once 2 3 #include <ntddk.h> 4 5 // 6 // OHCI Operational Registers 7 // 8 9 #define OHCI_REVISION_OFFSET (0x00) 10 #define OHCI_REVISION_LOW(rev) ((rev) & 0x0f) 11 #define OHCI_REVISION_HIGH(rev) (((rev) >> 4) & 0x03) 12 13 14 // 15 // OHCI Control Register 16 // 17 #define OHCI_CONTROL_OFFSET (0x004) 18 #define OHCI_CONTROL_BULK_SERVICE_RATIO_MASK (0x003) 19 #define OHCI_CONTROL_BULK_RATIO_1_1 (0x000) 20 #define OHCI_CONTROL_BULK_RATIO_1_2 (0x001) 21 #define OHCI_CONTROL_BULK_RATIO_1_3 (0x002) 22 #define OHCI_CONTROL_BULK_RATIO_1_4 (0x003) 23 #define OHCI_PERIODIC_LIST_ENABLE (0x004) 24 #define OHCI_ISOCHRONOUS_ENABLE (0x008) 25 #define OHCI_CONTROL_LIST_ENABLE (0x010) 26 #define OHCI_BULK_LIST_ENABLE (0x020) 27 #define OHCI_HC_FUNCTIONAL_STATE_MASK (0x0C0) 28 #define OHCI_HC_FUNCTIONAL_STATE_RESET (0x000) 29 #define OHCI_HC_FUNCTIONAL_STATE_RESUME (0x040) 30 #define OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL (0x080) 31 #define OHCI_HC_FUNCTIONAL_STATE_SUSPEND (0x0c0) 32 #define OHCI_INTERRUPT_ROUTING (0x100) 33 #define OHCI_REMOTE_WAKEUP_CONNECTED (0x200) 34 #define OHCI_REMORE_WAKEUP_ENABLED (0x400) 35 36 // 37 // OHCI Command Status Register 38 // 39 #define OHCI_COMMAND_STATUS_OFFSET (0x08) 40 #define OHCI_HOST_CONTROLLER_RESET 0x00000001 41 #define OHCI_CONTROL_LIST_FILLED 0x00000002 42 #define OHCI_BULK_LIST_FILLED 0x00000004 43 #define OHCI_OWNERSHIP_CHANGE_REQUEST 0x00000008 44 #define OHCI_SCHEDULING_OVERRUN_COUNT_MASK 0x00030000 45 46 47 // 48 // OHCI Interrupt Status Register 49 // 50 #define OHCI_INTERRUPT_STATUS_OFFSET 0x0c 51 #define OHCI_SCHEDULING_OVERRUN 0x00000001 52 #define OHCI_WRITEBACK_DONE_HEAD 0x00000002 53 #define OHCI_START_OF_FRAME 0x00000004 54 #define OHCI_RESUME_DETECTED 0x00000008 55 #define OHCI_UNRECOVERABLE_ERROR 0x00000010 56 #define OHCI_FRAME_NUMBER_OVERFLOW 0x00000020 57 #define OHCI_ROOT_HUB_STATUS_CHANGE 0x00000040 58 #define OHCI_OWNERSHIP_CHANGE 0x40000000 59 #define OHCI_MASTER_INTERRUPT_ENABLE 0x80000000 60 61 62 // 63 // OHCI Interrupt Enable Register 64 // 65 #define OHCI_INTERRUPT_ENABLE_OFFSET 0x10 66 67 // 68 // OHCI Interrupt Enable Register 69 // 70 #define OHCI_INTERRUPT_DISABLE_OFFSET 0x14 71 72 // 73 // OHCI HCCA Register 74 // 75 #define OHCI_HCCA_OFFSET 0x18 76 #define OHCI_PERIOD_CURRENT_ED_OFFSET 0x1c 77 #define OHCI_CONTROL_HEAD_ED_OFFSET 0x20 78 #define OHCI_CONTROL_CURRENT_ED_OFFSET 0x24 79 #define OHCI_BULK_HEAD_ED_OFFSET 0x28 80 81 // 82 // OHCI Root Hub Descriptor A register 83 // 84 #define OHCI_RH_DESCRIPTOR_A_OFFSET 0x48 85 #define OHCI_RH_GET_PORT_COUNT(s) ((s) & 0xff) 86 #define OHCI_RH_POWER_SWITCHING_MODE 0x0100 87 #define OHCI_RH_NO_POWER_SWITCHING 0x0200 88 #define OHCI_RH_DEVICE_TYPE 0x0400 89 #define OHCI_RH_OVER_CURRENT_PROTECTION_MODE 0x0800 90 #define OHCI_RH_NO_OVER_CURRENT_PROTECTION 0x1000 91 #define OHCI_RH_GET_POWER_ON_TO_POWER_GOOD_TIME(s) ((s) >> 24) 92 93 // 94 // Frame interval register (section 7.3.1) 95 // 96 #define OHCI_FRAME_INTERVAL_OFFSET 0x34 97 #define OHCI_GET_INTERVAL_VALUE(s) ((s) & 0x3fff) 98 #define OHCI_GET_FS_LARGEST_DATA_PACKET(s) (((s) >> 16) & 0x7fff) 99 #define OHCI_FRAME_INTERVAL_TOGGLE 0x80000000 100 101 // 102 // frame interval 103 // 104 #define OHCI_FRAME_INTERVAL_NUMBER_OFFSET 0x3C 105 106 // 107 // periodic start register 108 // 109 #define OHCI_PERIODIC_START_OFFSET 0x40 110 #define OHCI_PERIODIC(i) ((i) * 9 / 10) 111 112 // 113 // Root Hub Descriptor B register (section 7.4.2) 114 // 115 116 #define OHCI_RH_DESCRIPTOR_B 0x4c 117 118 // 119 // Root Hub status register (section 7.4.3) 120 // 121 #define OHCI_RH_STATUS_OFFSET 0x50 122 #define OHCI_RH_LOCAL_POWER_STATUS 0x00000001 123 #define OHCI_RH_OVER_CURRENT_INDICATOR 0x00000002 124 #define OHCI_RH_DEVICE_REMOTE_WAKEUP_ENABLE 0x00008000 125 #define OHCI_RH_LOCAL_POWER_STATUS_CHANGE 0x00010000 126 #define OHCI_RH_OVER_CURRENT_INDICATOR_CHANGE 0x00020000 127 #define OHCI_RH_CLEAR_REMOTE_WAKEUP_ENABLE 0x80000000 128 129 // 130 // Root Hub port status (n) register (section 7.4.4) 131 // 132 #define OHCI_RH_PORT_STATUS(n) (0x54 + (n) * 4)// 0 based indexing 133 #define OHCI_RH_PORTSTATUS_CCS 0x00000001 134 #define OHCI_RH_PORTSTATUS_PES 0x00000002 135 #define OHCI_RH_PORTSTATUS_PSS 0x00000004 136 #define OHCI_RH_PORTSTATUS_POCI 0x00000008 137 #define OHCI_RH_PORTSTATUS_PRS 0x00000010 138 #define OHCI_RH_PORTSTATUS_PPS 0x00000100 139 #define OHCI_RH_PORTSTATUS_LSDA 0x00000200 140 #define OHCI_RH_PORTSTATUS_CSC 0x00010000 141 #define OHCI_RH_PORTSTATUS_PESC 0x00020000 142 #define OHCI_RH_PORTSTATUS_PSSC 0x00040000 143 #define OHCI_RH_PORTSTATUS_OCIC 0x00080000 144 #define OHCI_RH_PORTSTATUS_PRSC 0x00100000 145 146 // 147 // Enable List 148 // 149 150 #define OHCI_ENABLE_LIST (OHCI_PERIODIC_LIST_ENABLE \ 151 | OHCI_ISOCHRONOUS_ENABLE \ 152 | OHCI_CONTROL_LIST_ENABLE \ 153 | OHCI_BULK_LIST_ENABLE) 154 155 // 156 // All interupts 157 // 158 #define OHCI_ALL_INTERRUPTS (OHCI_SCHEDULING_OVERRUN \ 159 | OHCI_WRITEBACK_DONE_HEAD \ 160 | OHCI_START_OF_FRAME \ 161 | OHCI_RESUME_DETECTED \ 162 | OHCI_UNRECOVERABLE_ERROR \ 163 | OHCI_FRAME_NUMBER_OVERFLOW \ 164 | OHCI_ROOT_HUB_STATUS_CHANGE \ 165 | OHCI_OWNERSHIP_CHANGE) 166 167 // 168 // All normal interupts 169 // 170 #define OHCI_NORMAL_INTERRUPTS (OHCI_SCHEDULING_OVERRUN \ 171 | OHCI_WRITEBACK_DONE_HEAD \ 172 | OHCI_RESUME_DETECTED \ 173 | OHCI_UNRECOVERABLE_ERROR \ 174 | OHCI_ROOT_HUB_STATUS_CHANGE \ 175 | OHCI_OWNERSHIP_CHANGE) 176 177 // 178 // FSMPS 179 // 180 181 #define OHCI_FSMPS(i) (((i - 210) * 6 / 7) << 16) 182 183 // 184 // Periodic 185 // 186 187 #define OHCI_PERIODIC(i) ((i) * 9 / 10) 188 189 // -------------------------------- 190 // HCCA structure (section 4.4) 191 // 256 bytes aligned 192 // -------------------------------- 193 194 #define OHCI_NUMBER_OF_INTERRUPTS 32 195 #define OHCI_STATIC_ENDPOINT_COUNT 6 196 #define OHCI_BIGGEST_INTERVAL 32 197 198 typedef struct 199 { 200 ULONG InterruptTable[OHCI_NUMBER_OF_INTERRUPTS]; 201 ULONG CurrentFrameNumber; 202 ULONG DoneHead; 203 UCHAR Reserved[120]; 204 }OHCIHCCA, *POHCIHCCA; 205 206 #define OHCI_DONE_INTERRUPTS 1 207 #define OHCI_HCCA_SIZE 256 208 #define OHCI_HCCA_ALIGN 256 209 #define OHCI_PAGE_SIZE 0x1000 210 #define OHCI_PAGE(x) ((x) &~ 0xfff) 211 #define OHCI_PAGE_OFFSET(x) ((x) & 0xfff) 212 213 214 typedef struct _OHCI_ENDPOINT_DESCRIPTOR 215 { 216 // Hardware part 217 ULONG Flags; 218 ULONG TailPhysicalDescriptor; 219 ULONG HeadPhysicalDescriptor; 220 ULONG NextPhysicalEndpoint; 221 222 // Software part 223 PHYSICAL_ADDRESS PhysicalAddress; 224 PVOID HeadLogicalDescriptor; 225 PVOID NextDescriptor; 226 PVOID Request; 227 }OHCI_ENDPOINT_DESCRIPTOR, *POHCI_ENDPOINT_DESCRIPTOR; 228 229 230 #define OHCI_ENDPOINT_SKIP 0x00004000 231 #define OHCI_ENDPOINT_SET_DEVICE_ADDRESS(s) (s) 232 #define OHCI_ENDPOINT_GET_ENDPOINT_NUMBER(s) (((s) >> 7) & 0xf) 233 #define OHCI_ENDPOINT_SET_ENDPOINT_NUMBER(s) ((s) << 7) 234 #define OHCI_ENDPOINT_GET_MAX_PACKET_SIZE(s) (((s) >> 16) & 0x07ff) 235 #define OHCI_ENDPOINT_SET_MAX_PACKET_SIZE(s) ((s) << 16) 236 #define OHCI_ENDPOINT_LOW_SPEED 0x00002000 237 #define OHCI_ENDPOINT_FULL_SPEED 0x00000000 238 #define OHCI_ENDPOINT_DIRECTION_OUT 0x00000800 239 #define OHCI_ENDPOINT_DIRECTION_IN 0x00001000 240 #define OHCI_ENDPOINT_GENERAL_FORMAT 0x00000000 241 #define OHCI_ENDPOINT_ISOCHRONOUS_FORMAT 0x00008000 242 #define OHCI_ENDPOINT_HEAD_MASK 0xfffffffc 243 #define OHCI_ENDPOINT_HALTED 0x00000001 244 // 245 // Maximum port count set by OHCI 246 // 247 #define OHCI_MAX_PORT_COUNT 15 248 249 250 typedef struct 251 { 252 ULONG PortStatus; 253 ULONG PortChange; 254 }OHCI_PORT_STATUS; 255 256 257 typedef struct 258 { 259 // Hardware part 16 bytes 260 ULONG Flags; // Flags field 261 ULONG BufferPhysical; // Physical buffer pointer 262 ULONG NextPhysicalDescriptor; // Physical pointer next descriptor 263 ULONG LastPhysicalByteAddress; // Physical pointer to buffer end 264 // Software part 265 PHYSICAL_ADDRESS PhysicalAddress; // Physical address of this descriptor 266 PVOID NextLogicalDescriptor; 267 ULONG BufferSize; // Size of the buffer 268 PVOID BufferLogical; // Logical pointer to the buffer 269 }OHCI_GENERAL_TD, *POHCI_GENERAL_TD; 270 271 272 #define OHCI_TD_BUFFER_ROUNDING 0x00040000 273 #define OHCI_TD_DIRECTION_PID_MASK 0x00180000 274 #define OHCI_TD_DIRECTION_PID_SETUP 0x00000000 275 #define OHCI_TD_DIRECTION_PID_OUT 0x00080000 276 #define OHCI_TD_DIRECTION_PID_IN 0x00100000 277 #define OHCI_TD_GET_DELAY_INTERRUPT(x) (((x) >> 21) & 7) 278 #define OHCI_TD_SET_DELAY_INTERRUPT(x) ((x) << 21) 279 #define OHCI_TD_INTERRUPT_MASK 0x00e00000 280 #define OHCI_TD_TOGGLE_CARRY 0x00000000 281 #define OHCI_TD_TOGGLE_0 0x02000000 282 #define OHCI_TD_TOGGLE_1 0x03000000 283 #define OHCI_TD_TOGGLE_MASK 0x03000000 284 #define OHCI_TD_GET_ERROR_COUNT(x) (((x) >> 26) & 3) 285 #define OHCI_TD_GET_CONDITION_CODE(x) ((x) >> 28) 286 #define OHCI_TD_SET_CONDITION_CODE(x) ((x) << 28) 287 #define OHCI_TD_CONDITION_CODE_MASK 0xf0000000 288 289 #define OHCI_TD_INTERRUPT_IMMEDIATE 0x00 290 #define OHCI_TD_INTERRUPT_NONE 0x07 291 292 #define OHCI_TD_CONDITION_NO_ERROR 0x00 293 #define OHCI_TD_CONDITION_CRC_ERROR 0x01 294 #define OHCI_TD_CONDITION_BIT_STUFFING 0x02 295 #define OHCI_TD_CONDITION_TOGGLE_MISMATCH 0x03 296 #define OHCI_TD_CONDITION_STALL 0x04 297 #define OHCI_TD_CONDITION_NO_RESPONSE 0x05 298 #define OHCI_TD_CONDITION_PID_CHECK_FAILURE 0x06 299 #define OHCI_TD_CONDITION_UNEXPECTED_PID 0x07 300 #define OHCI_TD_CONDITION_DATA_OVERRUN 0x08 301 #define OHCI_TD_CONDITION_DATA_UNDERRUN 0x09 302 #define OHCI_TD_CONDITION_BUFFER_OVERRUN 0x0c 303 #define OHCI_TD_CONDITION_BUFFER_UNDERRUN 0x0d 304 #define OHCI_TD_CONDITION_NOT_ACCESSED 0x0f 305 306 // -------------------------------- 307 // Isochronous transfer descriptor structure (section 4.3.2) 308 // -------------------------------- 309 310 #define OHCI_ITD_NOFFSET 8 311 312 typedef struct _OHCI_ISO_TD_ 313 { 314 315 // Hardware part 32 byte 316 ULONG Flags; 317 ULONG BufferPhysical; // Physical page number of byte 0 318 ULONG NextPhysicalDescriptor; // Next isochronous transfer descriptor 319 ULONG LastPhysicalByteAddress; // Physical buffer end 320 USHORT Offset[OHCI_ITD_NOFFSET]; // Buffer offsets 321 322 // Software part 323 PHYSICAL_ADDRESS PhysicalAddress; // Physical address of this descriptor 324 struct _OHCI_ISO_TD_ * NextLogicalDescriptor; // Logical pointer next descriptor 325 }OHCI_ISO_TD, *POHCI_ISO_TD; 326 327 C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, Flags) == 0); 328 C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, BufferPhysical) == 4); 329 C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, NextPhysicalDescriptor) == 8); 330 C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, LastPhysicalByteAddress) == 12); 331 C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, Offset) == 16); 332 C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, PhysicalAddress) == 32); 333 C_ASSERT(FIELD_OFFSET(OHCI_ISO_TD, NextLogicalDescriptor) == 40); 334 C_ASSERT(sizeof(OHCI_ISO_TD) == 48); 335 336 #define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff) 337 #define OHCI_ITD_SET_STARTING_FRAME(x) ((x) & 0xffff) 338 #define OHCI_ITD_GET_DELAY_INTERRUPT(x) (((x) >> 21) & 7) 339 #define OHCI_ITD_SET_DELAY_INTERRUPT(x) ((x) << 21) 340 #define OHCI_ITD_NO_INTERRUPT 0x00e00000 341 #define OHCI_ITD_GET_FRAME_COUNT(x) ((((x) >> 24) & 7) + 1) 342 #define OHCI_ITD_SET_FRAME_COUNT(x) (((x) - 1) << 24) 343 #define OHCI_ITD_GET_CONDITION_CODE(x) ((x) >> 28) 344 #define OHCI_ITD_NO_CONDITION_CODE 0xf0000000 345 346