1 /* 2 * PROJECT: ReactOS USB EHCI Miniport Driver 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: USBEHCI root hub functions 5 * COPYRIGHT: Copyright 2017-2018 Vadim Galyant <vgal@rambler.ru> 6 */ 7 8 #include "usbehci.h" 9 10 #define NDEBUG 11 #include <debug.h> 12 13 #define NDEBUG_EHCI_ROOT_HUB 14 #include "dbg_ehci.h" 15 16 MPSTATUS 17 NTAPI 18 EHCI_RH_ChirpRootPort(IN PVOID ehciExtension, 19 IN USHORT Port) 20 { 21 PEHCI_EXTENSION EhciExtension = ehciExtension; 22 PULONG PortStatusReg; 23 EHCI_PORT_STATUS_CONTROL PortSC; 24 ULONG PortBit; 25 ULONG ix; 26 27 DPRINT_RH("EHCI_RH_ChirpRootPort: Port - %x\n", Port); 28 ASSERT(Port != 0); 29 30 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 31 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 32 DPRINT_RH("EHCI_RH_ChirpRootPort: PortSC - %X\n", PortSC.AsULONG); 33 34 PortBit = 1 << (Port - 1); 35 36 if (PortBit & EhciExtension->ResetPortBits) 37 { 38 DPRINT_RH("EHCI_RH_ChirpRootPort: Skip port - %x\n", Port); 39 return MP_STATUS_SUCCESS; 40 } 41 42 if (PortSC.PortPower == 0) 43 { 44 DPRINT_RH("EHCI_RH_ChirpRootPort: Skip port - %x\n", Port); 45 return MP_STATUS_SUCCESS; 46 } 47 48 if (PortSC.CurrentConnectStatus == 0 || 49 PortSC.PortEnabledDisabled == 1 || 50 PortSC.PortOwner == EHCI_PORT_OWNER_COMPANION_CONTROLLER) 51 { 52 DPRINT_RH("EHCI_RH_ChirpRootPort: No port - %x\n", Port); 53 return MP_STATUS_SUCCESS; 54 } 55 56 if (PortSC.LineStatus == EHCI_LINE_STATUS_K_STATE_LOW_SPEED && 57 PortSC.Suspend == 0 && 58 PortSC.CurrentConnectStatus == 1) 59 { 60 /* Attached device is not a high-speed device. 61 Release ownership of the port to a selected HC. 62 Companion HC owns and controls the port. Section 4.2 */ 63 PortSC.PortOwner = EHCI_PORT_OWNER_COMPANION_CONTROLLER; 64 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 65 66 DPRINT_RH("EHCI_RH_ChirpRootPort: Companion HC port - %x\n", Port); 67 return MP_STATUS_SUCCESS; 68 } 69 70 DPRINT("EHCI_RH_ChirpRootPort: EhciExtension - %p, Port - %x\n", 71 EhciExtension, 72 Port); 73 74 PortSC.PortEnabledDisabled = 0; 75 PortSC.PortReset = 1; 76 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 77 78 RegPacket.UsbPortWait(EhciExtension, 10); 79 80 do 81 { 82 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 83 84 PortSC.ConnectStatusChange = 0; 85 PortSC.PortEnableDisableChange = 0; 86 PortSC.OverCurrentChange = 0; 87 PortSC.PortReset = 0; 88 89 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 90 91 for (ix = 0; ix <= 500; ix += 20) 92 { 93 KeStallExecutionProcessor(20); 94 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 95 96 DPRINT_RH("EHCI_RH_ChirpRootPort: Reset port - %x\n", Port); 97 98 if (PortSC.PortReset == 0) 99 break; 100 } 101 } 102 while (PortSC.PortReset == 1); 103 104 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 105 106 if (PortSC.PortEnabledDisabled == 1) 107 { 108 PortSC.ConnectStatusChange = 0; 109 PortSC.PortEnabledDisabled = 0; 110 PortSC.PortEnableDisableChange = 0; 111 PortSC.OverCurrentChange = 0; 112 113 RegPacket.UsbPortWait(EhciExtension, 10); 114 115 EhciExtension->ResetPortBits |= PortBit; 116 117 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 118 DPRINT_RH("EHCI_RH_ChirpRootPort: Disable port - %x\n", Port); 119 } 120 else 121 { 122 PortSC.PortOwner = EHCI_PORT_OWNER_COMPANION_CONTROLLER; 123 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 124 DPRINT_RH("EHCI_RH_ChirpRootPort: Companion HC port - %x\n", Port); 125 } 126 127 return MP_STATUS_SUCCESS; 128 } 129 130 VOID 131 NTAPI 132 EHCI_RH_GetRootHubData(IN PVOID ehciExtension, 133 IN PVOID rootHubData) 134 { 135 PEHCI_EXTENSION EhciExtension = ehciExtension; 136 PUSBPORT_ROOT_HUB_DATA RootHubData; 137 USBPORT_HUB_20_CHARACTERISTICS HubCharacteristics; 138 139 DPRINT_RH("EHCI_RH_GetRootHubData: EhciExtension - %p, rootHubData - %p\n", 140 EhciExtension, 141 rootHubData); 142 143 RootHubData = rootHubData; 144 145 RootHubData->NumberOfPorts = EhciExtension->NumberOfPorts; 146 147 HubCharacteristics.AsUSHORT = 0; 148 149 /* Logical Power Switching Mode */ 150 if (EhciExtension->PortPowerControl == 1) 151 { 152 /* Individual port power switching */ 153 HubCharacteristics.PowerControlMode = 1; 154 } 155 else 156 { 157 /* Ganged power switching (all ports� power at once) */ 158 HubCharacteristics.PowerControlMode = 0; 159 } 160 161 HubCharacteristics.NoPowerSwitching = 0; 162 163 /* EHCI RH is not part of a compound device */ 164 HubCharacteristics.PartOfCompoundDevice = 0; 165 166 /* Global Over-current Protection */ 167 HubCharacteristics.OverCurrentProtectionMode = 0; 168 169 RootHubData->HubCharacteristics.Usb20HubCharacteristics = HubCharacteristics; 170 171 RootHubData->PowerOnToPowerGood = 2; // Time (in 2 ms intervals) 172 RootHubData->HubControlCurrent = 0; 173 } 174 175 MPSTATUS 176 NTAPI 177 EHCI_RH_GetStatus(IN PVOID ehciExtension, 178 IN PUSHORT Status) 179 { 180 DPRINT_RH("EHCI_RH_GetStatus: ... \n"); 181 *Status = USB_GETSTATUS_SELF_POWERED; 182 return MP_STATUS_SUCCESS; 183 } 184 185 MPSTATUS 186 NTAPI 187 EHCI_RH_GetPortStatus(IN PVOID ehciExtension, 188 IN USHORT Port, 189 IN PUSB_PORT_STATUS_AND_CHANGE PortStatus) 190 { 191 PEHCI_EXTENSION EhciExtension = ehciExtension; 192 PULONG PortStatusReg; 193 EHCI_PORT_STATUS_CONTROL PortSC; 194 USB_PORT_STATUS_AND_CHANGE status; 195 ULONG PortMaskBits; 196 197 ASSERT(Port != 0); 198 199 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 200 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 201 202 if (PortSC.CurrentConnectStatus) 203 { 204 DPRINT_RH("EHCI_RH_GetPortStatus: Port - %x, PortSC.AsULONG - %X\n", 205 Port, 206 PortSC.AsULONG); 207 } 208 209 PortStatus->AsUlong32 = 0; 210 211 if (PortSC.LineStatus == EHCI_LINE_STATUS_K_STATE_LOW_SPEED && 212 PortSC.PortOwner != EHCI_PORT_OWNER_COMPANION_CONTROLLER && 213 (PortSC.PortEnabledDisabled | PortSC.Suspend) && // Enable or Suspend 214 PortSC.CurrentConnectStatus == 1) // Device is present 215 { 216 DPRINT("EHCI_RH_GetPortStatus: LowSpeed device detected\n"); 217 PortSC.PortOwner = EHCI_PORT_OWNER_COMPANION_CONTROLLER; // release ownership 218 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 219 return MP_STATUS_SUCCESS; 220 } 221 222 status.AsUlong32 = 0; 223 224 status.PortStatus.Usb20PortStatus.CurrentConnectStatus = PortSC.CurrentConnectStatus; 225 status.PortStatus.Usb20PortStatus.PortEnabledDisabled = PortSC.PortEnabledDisabled; 226 status.PortStatus.Usb20PortStatus.Suspend = PortSC.Suspend; 227 status.PortStatus.Usb20PortStatus.OverCurrent = PortSC.OverCurrentActive; 228 status.PortStatus.Usb20PortStatus.Reset = PortSC.PortReset; 229 status.PortStatus.Usb20PortStatus.PortPower = PortSC.PortPower; 230 if (PortSC.PortOwner == EHCI_PORT_OWNER_COMPANION_CONTROLLER) 231 status.PortStatus.Usb20PortStatus.Reserved1 = USB20_PORT_STATUS_RESERVED1_OWNED_BY_COMPANION; 232 233 status.PortChange.Usb20PortChange.PortEnableDisableChange = PortSC.PortEnableDisableChange; 234 status.PortChange.Usb20PortChange.OverCurrentIndicatorChange = PortSC.OverCurrentChange; 235 236 PortMaskBits = 1 << (Port - 1); 237 238 if (status.PortStatus.Usb20PortStatus.CurrentConnectStatus) 239 status.PortStatus.Usb20PortStatus.LowSpeedDeviceAttached = 0; 240 241 status.PortStatus.Usb20PortStatus.HighSpeedDeviceAttached = 1; 242 243 if (PortSC.ConnectStatusChange) 244 EhciExtension->ConnectPortBits |= PortMaskBits; 245 246 if (EhciExtension->FinishResetPortBits & PortMaskBits) 247 status.PortChange.Usb20PortChange.ResetChange = 1; 248 249 if (EhciExtension->ConnectPortBits & PortMaskBits) 250 status.PortChange.Usb20PortChange.ConnectStatusChange = 1; 251 252 if (EhciExtension->SuspendPortBits & PortMaskBits) 253 status.PortChange.Usb20PortChange.SuspendChange = 1; 254 255 *PortStatus = status; 256 257 if (status.PortStatus.Usb20PortStatus.CurrentConnectStatus) 258 { 259 DPRINT_RH("EHCI_RH_GetPortStatus: Port - %x, status.AsULONG - %X\n", 260 Port, 261 status.AsUlong32); 262 } 263 264 return MP_STATUS_SUCCESS; 265 } 266 267 MPSTATUS 268 NTAPI 269 EHCI_RH_GetHubStatus(IN PVOID ehciExtension, 270 IN PUSB_HUB_STATUS_AND_CHANGE HubStatus) 271 { 272 DPRINT_RH("EHCI_RH_GetHubStatus: ... \n"); 273 HubStatus->AsUlong32 = 0; 274 return MP_STATUS_SUCCESS; 275 } 276 277 VOID 278 NTAPI 279 EHCI_RH_FinishReset(IN PVOID ehciExtension, 280 IN PVOID Context) 281 { 282 PEHCI_EXTENSION EhciExtension = ehciExtension; 283 PULONG PortStatusReg; 284 EHCI_PORT_STATUS_CONTROL PortSC; 285 PUSHORT Port = Context; 286 287 DPRINT("EHCI_RH_FinishReset: *Port - %x\n", *Port); 288 289 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[*Port - 1].AsULONG; 290 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 291 292 if (PortSC.AsULONG != -1) 293 { 294 if (!PortSC.CurrentConnectStatus) 295 DPRINT("EHCI_RH_FinishReset: PortSC.AsULONG - %X\n", PortSC.AsULONG); 296 297 if (PortSC.PortEnabledDisabled || 298 !PortSC.CurrentConnectStatus || 299 PortSC.ConnectStatusChange) 300 { 301 EhciExtension->FinishResetPortBits |= (1 << (*Port - 1)); 302 RegPacket.UsbPortInvalidateRootHub(EhciExtension); 303 } 304 else 305 { 306 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 307 PortSC.PortOwner = EHCI_PORT_OWNER_COMPANION_CONTROLLER; 308 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 309 EhciExtension->FinishResetPortBits |= (1 << (*Port - 1)); 310 } 311 312 EhciExtension->ResetPortBits &= ~(1 << (*Port - 1)); 313 } 314 } 315 316 VOID 317 NTAPI 318 EHCI_RH_PortResetComplete(IN PVOID ehciExtension, 319 IN PVOID Context) 320 { 321 PEHCI_EXTENSION EhciExtension = ehciExtension; 322 PULONG PortStatusReg; 323 EHCI_PORT_STATUS_CONTROL PortSC; 324 ULONG ix; 325 PUSHORT Port = Context; 326 327 DPRINT("EHCI_RH_PortResetComplete: *Port - %x\n", *Port); 328 329 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[*Port - 1].AsULONG; 330 331 do 332 { 333 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 334 335 PortSC.ConnectStatusChange = 0; 336 PortSC.PortEnableDisableChange = 0; 337 PortSC.OverCurrentChange = 0; 338 PortSC.PortReset = 0; 339 340 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 341 342 for (ix = 0; ix <= 500; ix += 20) 343 { 344 KeStallExecutionProcessor(20); 345 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 346 347 DPRINT("EHCI_RH_PortResetComplete: Reset port - %x\n", Port); 348 349 if (PortSC.PortReset == 0) 350 break; 351 } 352 } 353 while (PortSC.PortReset == 1 && (PortSC.AsULONG != -1)); 354 355 RegPacket.UsbPortRequestAsyncCallback(EhciExtension, 356 50, // TimerValue 357 Port, 358 sizeof(Port), 359 EHCI_RH_FinishReset); 360 } 361 362 MPSTATUS 363 NTAPI 364 EHCI_RH_SetFeaturePortReset(IN PVOID ehciExtension, 365 IN USHORT Port) 366 { 367 PEHCI_EXTENSION EhciExtension = ehciExtension; 368 PULONG PortStatusReg; 369 EHCI_PORT_STATUS_CONTROL PortSC; 370 371 DPRINT("EHCI_RH_SetFeaturePortReset: Port - %x\n", Port); 372 ASSERT(Port != 0); 373 374 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 375 376 EhciExtension->ResetPortBits |= 1 << (Port - 1); 377 378 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 379 380 PortSC.ConnectStatusChange = 0; 381 PortSC.PortEnabledDisabled = 0; 382 PortSC.PortEnableDisableChange = 0; 383 PortSC.OverCurrentChange = 0; 384 PortSC.PortReset = 1; 385 386 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 387 388 RegPacket.UsbPortRequestAsyncCallback(EhciExtension, 389 50, // TimerValue 390 &Port, 391 sizeof(Port), 392 EHCI_RH_PortResetComplete); 393 394 return MP_STATUS_SUCCESS; 395 } 396 397 MPSTATUS 398 NTAPI 399 EHCI_RH_SetFeaturePortPower(IN PVOID ehciExtension, 400 IN USHORT Port) 401 { 402 PEHCI_EXTENSION EhciExtension = ehciExtension; 403 PULONG PortStatusReg; 404 EHCI_PORT_STATUS_CONTROL PortSC; 405 406 DPRINT_RH("EHCI_RH_SetFeaturePortPower: Port - %x\n", Port); 407 ASSERT(Port != 0); 408 409 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 410 411 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 412 413 PortSC.ConnectStatusChange = 0; 414 PortSC.PortEnableDisableChange = 0; 415 PortSC.OverCurrentChange = 0; 416 PortSC.PortPower = 1; 417 418 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 419 420 return MP_STATUS_SUCCESS; 421 } 422 423 MPSTATUS 424 NTAPI 425 EHCI_RH_SetFeaturePortEnable(IN PVOID ehciExtension, 426 IN USHORT Port) 427 { 428 DPRINT_RH("EHCI_RH_SetFeaturePortEnable: Not supported\n"); 429 ASSERT(Port != 0); 430 return MP_STATUS_SUCCESS; 431 } 432 433 MPSTATUS 434 NTAPI 435 EHCI_RH_SetFeaturePortSuspend(IN PVOID ehciExtension, 436 IN USHORT Port) 437 { 438 PEHCI_EXTENSION EhciExtension = ehciExtension; 439 PULONG PortStatusReg; 440 EHCI_PORT_STATUS_CONTROL PortSC; 441 442 DPRINT("EHCI_RH_SetFeaturePortSuspend: Port - %x\n", Port); 443 ASSERT(Port != 0); 444 445 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 446 447 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 448 449 PortSC.ConnectStatusChange = 0; 450 PortSC.PortEnableDisableChange = 0; 451 PortSC.OverCurrentChange = 0; 452 PortSC.Suspend = 1; 453 454 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 455 KeStallExecutionProcessor(125); 456 457 return MP_STATUS_SUCCESS; 458 } 459 460 MPSTATUS 461 NTAPI 462 EHCI_RH_ClearFeaturePortEnable(IN PVOID ehciExtension, 463 IN USHORT Port) 464 { 465 PEHCI_EXTENSION EhciExtension = ehciExtension; 466 PULONG PortStatusReg; 467 EHCI_PORT_STATUS_CONTROL PortSC; 468 469 DPRINT("EHCI_RH_ClearFeaturePortEnable: Port - %x\n", Port); 470 ASSERT(Port != 0); 471 472 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 473 474 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 475 476 PortSC.ConnectStatusChange = 0; 477 PortSC.PortEnabledDisabled = 0; 478 PortSC.PortEnableDisableChange = 0; 479 PortSC.OverCurrentChange = 0; 480 481 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 482 483 return MP_STATUS_SUCCESS; 484 } 485 486 MPSTATUS 487 NTAPI 488 EHCI_RH_ClearFeaturePortPower(IN PVOID ehciExtension, 489 IN USHORT Port) 490 { 491 PEHCI_EXTENSION EhciExtension = ehciExtension; 492 PULONG PortStatusReg; 493 EHCI_PORT_STATUS_CONTROL PortSC; 494 495 DPRINT("EHCI_RH_ClearFeaturePortPower: Port - %x\n", Port); 496 ASSERT(Port != 0); 497 498 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 499 500 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 501 PortSC.PortPower = 0; 502 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 503 504 return MP_STATUS_SUCCESS; 505 } 506 507 VOID 508 NTAPI 509 EHCI_RH_PortResumeComplete(IN PVOID ehciExtension, 510 IN PVOID Context) 511 { 512 PEHCI_EXTENSION EhciExtension = ehciExtension; 513 PULONG PortStatusReg; 514 EHCI_PORT_STATUS_CONTROL PortSC; 515 PUSHORT Port = Context; 516 517 DPRINT("EHCI_RH_PortResumeComplete: *Port - %x\n", *Port); 518 ASSERT(Port != 0); 519 520 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[*Port - 1].AsULONG; 521 522 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 523 524 PortSC.ConnectStatusChange = 0; 525 PortSC.PortEnableDisableChange = 0; 526 PortSC.OverCurrentChange = 0; 527 PortSC.ForcePortResume = 0; 528 PortSC.Suspend = 0; 529 530 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 531 READ_REGISTER_ULONG(PortStatusReg); 532 533 EhciExtension->SuspendPortBits |= 1 << (*Port - 1); 534 } 535 536 MPSTATUS 537 NTAPI 538 EHCI_RH_ClearFeaturePortSuspend(IN PVOID ehciExtension, 539 IN USHORT Port) 540 { 541 PEHCI_EXTENSION EhciExtension = ehciExtension; 542 PULONG PortStatusReg; 543 EHCI_PORT_STATUS_CONTROL PortSC; 544 545 DPRINT("EHCI_RH_ClearFeaturePortSuspend: Port - %x\n", Port); 546 ASSERT(Port != 0); 547 548 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 549 EhciExtension->ResetPortBits |= 1 << (Port - 1); 550 551 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 552 PortSC.ForcePortResume = 1; 553 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 554 555 RegPacket.UsbPortRequestAsyncCallback(EhciExtension, 556 50, // TimerValue 557 &Port, 558 sizeof(Port), 559 EHCI_RH_PortResumeComplete); 560 561 return MP_STATUS_SUCCESS; 562 } 563 564 MPSTATUS 565 NTAPI 566 EHCI_RH_ClearFeaturePortEnableChange(IN PVOID ehciExtension, 567 IN USHORT Port) 568 { 569 PEHCI_EXTENSION EhciExtension = ehciExtension; 570 PULONG PortStatusReg; 571 EHCI_PORT_STATUS_CONTROL PortSC; 572 573 DPRINT("EHCI_RH_ClearFeaturePortEnableChange: Port - %p\n", Port); 574 ASSERT(Port != 0); 575 576 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 577 578 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 579 580 PortSC.ConnectStatusChange = 0; 581 PortSC.OverCurrentChange = 0; 582 PortSC.PortEnableDisableChange = 1; 583 584 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 585 586 return MP_STATUS_SUCCESS; 587 } 588 589 MPSTATUS 590 NTAPI 591 EHCI_RH_ClearFeaturePortConnectChange(IN PVOID ehciExtension, 592 IN USHORT Port) 593 { 594 PEHCI_EXTENSION EhciExtension = ehciExtension; 595 PULONG PortStatusReg; 596 EHCI_PORT_STATUS_CONTROL PortSC; 597 598 DPRINT_RH("EHCI_RH_ClearFeaturePortConnectChange: Port - %x\n", Port); 599 ASSERT(Port != 0); 600 601 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 602 603 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 604 605 if (PortSC.ConnectStatusChange) 606 { 607 PortSC.ConnectStatusChange = 1; 608 PortSC.PortEnableDisableChange = 0; 609 PortSC.OverCurrentChange = 0; 610 611 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 612 } 613 614 EhciExtension->ConnectPortBits &= ~(1 << (Port - 1)); 615 616 return MP_STATUS_SUCCESS; 617 } 618 619 MPSTATUS 620 NTAPI 621 EHCI_RH_ClearFeaturePortResetChange(IN PVOID ehciExtension, 622 IN USHORT Port) 623 { 624 PEHCI_EXTENSION EhciExtension = ehciExtension; 625 626 DPRINT("EHCI_RH_ClearFeaturePortConnectChange: Port - %x\n", Port); 627 ASSERT(Port != 0); 628 629 EhciExtension->FinishResetPortBits &= ~(1 << (Port - 1)); 630 return MP_STATUS_SUCCESS; 631 } 632 633 MPSTATUS 634 NTAPI 635 EHCI_RH_ClearFeaturePortSuspendChange(IN PVOID ehciExtension, 636 IN USHORT Port) 637 { 638 PEHCI_EXTENSION EhciExtension = ehciExtension; 639 640 DPRINT("EHCI_RH_ClearFeaturePortSuspendChange: Port - %x\n", Port); 641 ASSERT(Port != 0); 642 643 EhciExtension->SuspendPortBits &= ~(1 << (Port - 1)); 644 return MP_STATUS_SUCCESS; 645 } 646 647 MPSTATUS 648 NTAPI 649 EHCI_RH_ClearFeaturePortOvercurrentChange(IN PVOID ehciExtension, 650 IN USHORT Port) 651 { 652 PEHCI_EXTENSION EhciExtension = ehciExtension; 653 PULONG PortStatusReg; 654 EHCI_PORT_STATUS_CONTROL PortSC; 655 656 DPRINT_RH("EHCI_RH_ClearFeaturePortOvercurrentChange: Port - %x\n", Port); 657 ASSERT(Port != 0); 658 659 PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG; 660 661 PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg); 662 663 PortSC.ConnectStatusChange = 0; 664 PortSC.PortEnableDisableChange = 0; 665 PortSC.OverCurrentChange = 1; 666 667 WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG); 668 669 return MP_STATUS_SUCCESS; 670 } 671 672 VOID 673 NTAPI 674 EHCI_RH_DisableIrq(IN PVOID ehciExtension) 675 { 676 PEHCI_EXTENSION EhciExtension = ehciExtension; 677 PULONG IntrStsReg; 678 EHCI_INTERRUPT_ENABLE IntrSts; 679 680 DPRINT_RH("EHCI_RH_DisableIrq: ... \n"); 681 682 IntrStsReg = &EhciExtension->OperationalRegs->HcInterruptEnable.AsULONG; 683 IntrSts.AsULONG = READ_REGISTER_ULONG(IntrStsReg); 684 685 EhciExtension->InterruptMask.PortChangeInterrupt = 0; 686 IntrSts.PortChangeInterrupt = 0; 687 688 if (IntrSts.Interrupt) 689 WRITE_REGISTER_ULONG(IntrStsReg, IntrSts.AsULONG); 690 } 691 692 VOID 693 NTAPI 694 EHCI_RH_EnableIrq(IN PVOID ehciExtension) 695 { 696 PEHCI_EXTENSION EhciExtension = ehciExtension; 697 PULONG IntrStsReg; 698 EHCI_INTERRUPT_ENABLE IntrSts; 699 700 DPRINT_RH("EHCI_RH_EnableIrq: ... \n"); 701 702 IntrStsReg = &EhciExtension->OperationalRegs->HcInterruptEnable.AsULONG; 703 IntrSts.AsULONG = READ_REGISTER_ULONG(IntrStsReg); 704 705 EhciExtension->InterruptMask.PortChangeInterrupt = 1; 706 IntrSts.PortChangeInterrupt = 1; 707 708 if (IntrSts.Interrupt) 709 WRITE_REGISTER_ULONG(IntrStsReg, IntrSts.AsULONG); 710 } 711