reactos/drivers/usb/usbehci/roothub.c

711 lines
20 KiB
C
Raw Permalink Normal View History

/*
* 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);
}