Files
reactos/drivers/usb/usbehci/roothub.c
2020-01-06 21:16:08 +02:00

711 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* PROJECT: ReactOS USB EHCI Miniport Driver
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: USBEHCI root hub functions
* COPYRIGHT: Copyright 2017-2018 Vadim Galyant <vgal@rambler.ru>
*/
#include "usbehci.h"
#define NDEBUG
#include <debug.h>
#define NDEBUG_EHCI_ROOT_HUB
#include "dbg_ehci.h"
MPSTATUS
NTAPI
EHCI_RH_ChirpRootPort(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
ULONG PortBit;
ULONG ix;
DPRINT_RH("EHCI_RH_ChirpRootPort: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
DPRINT_RH("EHCI_RH_ChirpRootPort: PortSC - %X\n", PortSC.AsULONG);
PortBit = 1 << (Port - 1);
if (PortBit & EhciExtension->ResetPortBits)
{
DPRINT_RH("EHCI_RH_ChirpRootPort: Skip port - %x\n", Port);
return MP_STATUS_SUCCESS;
}
if (PortSC.PortPower == 0)
{
DPRINT_RH("EHCI_RH_ChirpRootPort: Skip port - %x\n", Port);
return MP_STATUS_SUCCESS;
}
if (PortSC.CurrentConnectStatus == 0 ||
PortSC.PortEnabledDisabled == 1 ||
PortSC.PortOwner == EHCI_PORT_OWNER_COMPANION_CONTROLLER)
{
DPRINT_RH("EHCI_RH_ChirpRootPort: No port - %x\n", Port);
return MP_STATUS_SUCCESS;
}
if (PortSC.LineStatus == EHCI_LINE_STATUS_K_STATE_LOW_SPEED &&
PortSC.Suspend == 0 &&
PortSC.CurrentConnectStatus == 1)
{
/* Attached device is not a high-speed device.
Release ownership of the port to a selected HC.
Companion HC owns and controls the port. Section 4.2 */
PortSC.PortOwner = EHCI_PORT_OWNER_COMPANION_CONTROLLER;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
DPRINT_RH("EHCI_RH_ChirpRootPort: Companion HC port - %x\n", Port);
return MP_STATUS_SUCCESS;
}
DPRINT("EHCI_RH_ChirpRootPort: EhciExtension - %p, Port - %x\n",
EhciExtension,
Port);
PortSC.PortEnabledDisabled = 0;
PortSC.PortReset = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
RegPacket.UsbPortWait(EhciExtension, 10);
do
{
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
PortSC.PortReset = 0;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
for (ix = 0; ix <= 500; ix += 20)
{
KeStallExecutionProcessor(20);
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
DPRINT_RH("EHCI_RH_ChirpRootPort: Reset port - %x\n", Port);
if (PortSC.PortReset == 0)
break;
}
}
while (PortSC.PortReset == 1);
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
if (PortSC.PortEnabledDisabled == 1)
{
PortSC.ConnectStatusChange = 0;
PortSC.PortEnabledDisabled = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
RegPacket.UsbPortWait(EhciExtension, 10);
EhciExtension->ResetPortBits |= PortBit;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
DPRINT_RH("EHCI_RH_ChirpRootPort: Disable port - %x\n", Port);
}
else
{
PortSC.PortOwner = EHCI_PORT_OWNER_COMPANION_CONTROLLER;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
DPRINT_RH("EHCI_RH_ChirpRootPort: Companion HC port - %x\n", Port);
}
return MP_STATUS_SUCCESS;
}
VOID
NTAPI
EHCI_RH_GetRootHubData(IN PVOID ehciExtension,
IN PVOID rootHubData)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PUSBPORT_ROOT_HUB_DATA RootHubData;
USBPORT_HUB_20_CHARACTERISTICS HubCharacteristics;
DPRINT_RH("EHCI_RH_GetRootHubData: EhciExtension - %p, rootHubData - %p\n",
EhciExtension,
rootHubData);
RootHubData = rootHubData;
RootHubData->NumberOfPorts = EhciExtension->NumberOfPorts;
HubCharacteristics.AsUSHORT = 0;
/* Logical Power Switching Mode */
if (EhciExtension->PortPowerControl == 1)
{
/* Individual port power switching */
HubCharacteristics.PowerControlMode = 1;
}
else
{
/* Ganged power switching (all ports power at once) */
HubCharacteristics.PowerControlMode = 0;
}
HubCharacteristics.NoPowerSwitching = 0;
/* EHCI RH is not part of a compound device */
HubCharacteristics.PartOfCompoundDevice = 0;
/* Global Over-current Protection */
HubCharacteristics.OverCurrentProtectionMode = 0;
RootHubData->HubCharacteristics.Usb20HubCharacteristics = HubCharacteristics;
RootHubData->PowerOnToPowerGood = 2; // Time (in 2 ms intervals)
RootHubData->HubControlCurrent = 0;
}
MPSTATUS
NTAPI
EHCI_RH_GetStatus(IN PVOID ehciExtension,
IN PUSHORT Status)
{
DPRINT_RH("EHCI_RH_GetStatus: ... \n");
*Status = USB_GETSTATUS_SELF_POWERED;
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_GetPortStatus(IN PVOID ehciExtension,
IN USHORT Port,
IN PUSB_PORT_STATUS_AND_CHANGE PortStatus)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
USB_PORT_STATUS_AND_CHANGE status;
ULONG PortMaskBits;
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
if (PortSC.CurrentConnectStatus)
{
DPRINT_RH("EHCI_RH_GetPortStatus: Port - %x, PortSC.AsULONG - %X\n",
Port,
PortSC.AsULONG);
}
PortStatus->AsUlong32 = 0;
if (PortSC.LineStatus == EHCI_LINE_STATUS_K_STATE_LOW_SPEED &&
PortSC.PortOwner != EHCI_PORT_OWNER_COMPANION_CONTROLLER &&
(PortSC.PortEnabledDisabled | PortSC.Suspend) && // Enable or Suspend
PortSC.CurrentConnectStatus == 1) // Device is present
{
DPRINT("EHCI_RH_GetPortStatus: LowSpeed device detected\n");
PortSC.PortOwner = EHCI_PORT_OWNER_COMPANION_CONTROLLER; // release ownership
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
return MP_STATUS_SUCCESS;
}
status.AsUlong32 = 0;
status.PortStatus.Usb20PortStatus.CurrentConnectStatus = PortSC.CurrentConnectStatus;
status.PortStatus.Usb20PortStatus.PortEnabledDisabled = PortSC.PortEnabledDisabled;
status.PortStatus.Usb20PortStatus.Suspend = PortSC.Suspend;
status.PortStatus.Usb20PortStatus.OverCurrent = PortSC.OverCurrentActive;
status.PortStatus.Usb20PortStatus.Reset = PortSC.PortReset;
status.PortStatus.Usb20PortStatus.PortPower = PortSC.PortPower;
if (PortSC.PortOwner == EHCI_PORT_OWNER_COMPANION_CONTROLLER)
status.PortStatus.Usb20PortStatus.Reserved1 = USB20_PORT_STATUS_RESERVED1_OWNED_BY_COMPANION;
status.PortChange.Usb20PortChange.PortEnableDisableChange = PortSC.PortEnableDisableChange;
status.PortChange.Usb20PortChange.OverCurrentIndicatorChange = PortSC.OverCurrentChange;
PortMaskBits = 1 << (Port - 1);
if (status.PortStatus.Usb20PortStatus.CurrentConnectStatus)
status.PortStatus.Usb20PortStatus.LowSpeedDeviceAttached = 0;
status.PortStatus.Usb20PortStatus.HighSpeedDeviceAttached = 1;
if (PortSC.ConnectStatusChange)
EhciExtension->ConnectPortBits |= PortMaskBits;
if (EhciExtension->FinishResetPortBits & PortMaskBits)
status.PortChange.Usb20PortChange.ResetChange = 1;
if (EhciExtension->ConnectPortBits & PortMaskBits)
status.PortChange.Usb20PortChange.ConnectStatusChange = 1;
if (EhciExtension->SuspendPortBits & PortMaskBits)
status.PortChange.Usb20PortChange.SuspendChange = 1;
*PortStatus = status;
if (status.PortStatus.Usb20PortStatus.CurrentConnectStatus)
{
DPRINT_RH("EHCI_RH_GetPortStatus: Port - %x, status.AsULONG - %X\n",
Port,
status.AsUlong32);
}
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_GetHubStatus(IN PVOID ehciExtension,
IN PUSB_HUB_STATUS_AND_CHANGE HubStatus)
{
DPRINT_RH("EHCI_RH_GetHubStatus: ... \n");
HubStatus->AsUlong32 = 0;
return MP_STATUS_SUCCESS;
}
VOID
NTAPI
EHCI_RH_FinishReset(IN PVOID ehciExtension,
IN PVOID Context)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
PUSHORT Port = Context;
DPRINT("EHCI_RH_FinishReset: *Port - %x\n", *Port);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[*Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
if (PortSC.AsULONG != -1)
{
if (!PortSC.CurrentConnectStatus)
DPRINT("EHCI_RH_FinishReset: PortSC.AsULONG - %X\n", PortSC.AsULONG);
if (PortSC.PortEnabledDisabled ||
!PortSC.CurrentConnectStatus ||
PortSC.ConnectStatusChange)
{
EhciExtension->FinishResetPortBits |= (1 << (*Port - 1));
RegPacket.UsbPortInvalidateRootHub(EhciExtension);
}
else
{
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.PortOwner = EHCI_PORT_OWNER_COMPANION_CONTROLLER;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
EhciExtension->FinishResetPortBits |= (1 << (*Port - 1));
}
EhciExtension->ResetPortBits &= ~(1 << (*Port - 1));
}
}
VOID
NTAPI
EHCI_RH_PortResetComplete(IN PVOID ehciExtension,
IN PVOID Context)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
ULONG ix;
PUSHORT Port = Context;
DPRINT("EHCI_RH_PortResetComplete: *Port - %x\n", *Port);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[*Port - 1].AsULONG;
do
{
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
PortSC.PortReset = 0;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
for (ix = 0; ix <= 500; ix += 20)
{
KeStallExecutionProcessor(20);
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
DPRINT("EHCI_RH_PortResetComplete: Reset port - %x\n", Port);
if (PortSC.PortReset == 0)
break;
}
}
while (PortSC.PortReset == 1 && (PortSC.AsULONG != -1));
RegPacket.UsbPortRequestAsyncCallback(EhciExtension,
50, // TimerValue
Port,
sizeof(Port),
EHCI_RH_FinishReset);
}
MPSTATUS
NTAPI
EHCI_RH_SetFeaturePortReset(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT("EHCI_RH_SetFeaturePortReset: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
EhciExtension->ResetPortBits |= 1 << (Port - 1);
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.PortEnabledDisabled = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
PortSC.PortReset = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
RegPacket.UsbPortRequestAsyncCallback(EhciExtension,
50, // TimerValue
&Port,
sizeof(Port),
EHCI_RH_PortResetComplete);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_SetFeaturePortPower(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT_RH("EHCI_RH_SetFeaturePortPower: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
PortSC.PortPower = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_SetFeaturePortEnable(IN PVOID ehciExtension,
IN USHORT Port)
{
DPRINT_RH("EHCI_RH_SetFeaturePortEnable: Not supported\n");
ASSERT(Port != 0);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_SetFeaturePortSuspend(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT("EHCI_RH_SetFeaturePortSuspend: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
PortSC.Suspend = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
KeStallExecutionProcessor(125);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_ClearFeaturePortEnable(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT("EHCI_RH_ClearFeaturePortEnable: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.PortEnabledDisabled = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_ClearFeaturePortPower(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT("EHCI_RH_ClearFeaturePortPower: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.PortPower = 0;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
return MP_STATUS_SUCCESS;
}
VOID
NTAPI
EHCI_RH_PortResumeComplete(IN PVOID ehciExtension,
IN PVOID Context)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
PUSHORT Port = Context;
DPRINT("EHCI_RH_PortResumeComplete: *Port - %x\n", *Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[*Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
PortSC.ForcePortResume = 0;
PortSC.Suspend = 0;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
READ_REGISTER_ULONG(PortStatusReg);
EhciExtension->SuspendPortBits |= 1 << (*Port - 1);
}
MPSTATUS
NTAPI
EHCI_RH_ClearFeaturePortSuspend(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT("EHCI_RH_ClearFeaturePortSuspend: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
EhciExtension->ResetPortBits |= 1 << (Port - 1);
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ForcePortResume = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
RegPacket.UsbPortRequestAsyncCallback(EhciExtension,
50, // TimerValue
&Port,
sizeof(Port),
EHCI_RH_PortResumeComplete);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_ClearFeaturePortEnableChange(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT("EHCI_RH_ClearFeaturePortEnableChange: Port - %p\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.OverCurrentChange = 0;
PortSC.PortEnableDisableChange = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_ClearFeaturePortConnectChange(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT_RH("EHCI_RH_ClearFeaturePortConnectChange: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
if (PortSC.ConnectStatusChange)
{
PortSC.ConnectStatusChange = 1;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 0;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
}
EhciExtension->ConnectPortBits &= ~(1 << (Port - 1));
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_ClearFeaturePortResetChange(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
DPRINT("EHCI_RH_ClearFeaturePortConnectChange: Port - %x\n", Port);
ASSERT(Port != 0);
EhciExtension->FinishResetPortBits &= ~(1 << (Port - 1));
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_ClearFeaturePortSuspendChange(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
DPRINT("EHCI_RH_ClearFeaturePortSuspendChange: Port - %x\n", Port);
ASSERT(Port != 0);
EhciExtension->SuspendPortBits &= ~(1 << (Port - 1));
return MP_STATUS_SUCCESS;
}
MPSTATUS
NTAPI
EHCI_RH_ClearFeaturePortOvercurrentChange(IN PVOID ehciExtension,
IN USHORT Port)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG PortStatusReg;
EHCI_PORT_STATUS_CONTROL PortSC;
DPRINT_RH("EHCI_RH_ClearFeaturePortOvercurrentChange: Port - %x\n", Port);
ASSERT(Port != 0);
PortStatusReg = &EhciExtension->OperationalRegs->PortControl[Port - 1].AsULONG;
PortSC.AsULONG = READ_REGISTER_ULONG(PortStatusReg);
PortSC.ConnectStatusChange = 0;
PortSC.PortEnableDisableChange = 0;
PortSC.OverCurrentChange = 1;
WRITE_REGISTER_ULONG(PortStatusReg, PortSC.AsULONG);
return MP_STATUS_SUCCESS;
}
VOID
NTAPI
EHCI_RH_DisableIrq(IN PVOID ehciExtension)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG IntrStsReg;
EHCI_INTERRUPT_ENABLE IntrSts;
DPRINT_RH("EHCI_RH_DisableIrq: ... \n");
IntrStsReg = &EhciExtension->OperationalRegs->HcInterruptEnable.AsULONG;
IntrSts.AsULONG = READ_REGISTER_ULONG(IntrStsReg);
EhciExtension->InterruptMask.PortChangeInterrupt = 0;
IntrSts.PortChangeInterrupt = 0;
if (IntrSts.Interrupt)
WRITE_REGISTER_ULONG(IntrStsReg, IntrSts.AsULONG);
}
VOID
NTAPI
EHCI_RH_EnableIrq(IN PVOID ehciExtension)
{
PEHCI_EXTENSION EhciExtension = ehciExtension;
PULONG IntrStsReg;
EHCI_INTERRUPT_ENABLE IntrSts;
DPRINT_RH("EHCI_RH_EnableIrq: ... \n");
IntrStsReg = &EhciExtension->OperationalRegs->HcInterruptEnable.AsULONG;
IntrSts.AsULONG = READ_REGISTER_ULONG(IntrStsReg);
EhciExtension->InterruptMask.PortChangeInterrupt = 1;
IntrSts.PortChangeInterrupt = 1;
if (IntrSts.Interrupt)
WRITE_REGISTER_ULONG(IntrStsReg, IntrSts.AsULONG);
}