audk/QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c

1391 lines
28 KiB
C

/** @file
The OHCI register operation routines.
Copyright (c) 2013-2015 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Ohci.h"
/**
Get OHCI operational reg value
@param PciIo PciIo protocol instance
@param Offset Offset of the operational reg
@retval Value of the register
**/
UINT32
OhciGetOperationalReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 Offset
)
{
UINT32 Value;
PciIo->Mem.Read(PciIo, EfiPciIoWidthUint32, OHC_BAR_INDEX, Offset, 1, &Value);
return Value;
}
/**
Set OHCI operational reg value
@param PciIo PCI Bus Io protocol instance
@param Offset Offset of the operational reg
@param Value Value to set
@retval EFI_SUCCESS Value set to the reg
**/
EFI_STATUS
OhciSetOperationalReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 Offset,
IN VOID *Value
)
{
EFI_STATUS Status;
Status = PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, OHC_BAR_INDEX, Offset, 1, Value);
return Status;
}
/**
Get HcRevision reg value
@param PciIo PCI Bus Io protocol instance
@retval Value of the register
**/
UINT32
OhciGetHcRevision (
IN EFI_PCI_IO_PROTOCOL *PciIo
)
{
return OhciGetOperationalReg (PciIo, HC_REVISION);
}
/**
Set HcReset reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcReset (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Field,
IN UINT32 Value
)
{
HcRESET Reset;
*(UINT32 *) &Reset = OhciGetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR);
if (Field & RESET_SYSTEM_BUS) {
Reset.FSBIR = Value;
}
if (Field & RESET_HOST_CONTROLLER) {
Reset.FHR = Value;
}
if (Field & RESET_CLOCK_GENERATION) {
Reset.CGR = Value;
}
if (Field & RESET_SSE_GLOBAL) {
Reset.SSE = Value;
}
if (Field & RESET_PSPL) {
Reset.PSPL = Value;
}
if (Field & RESET_PCPL) {
Reset.PCPL = Value;
}
if (Field & RESET_SSEP1) {
Reset.SSEP1 = Value;
}
if (Field & RESET_SSEP2) {
Reset.SSEP2 = Value;
}
if (Field & RESET_SSEP3) {
Reset.SSEP3 = Value;
}
OhciSetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR, &Reset);
return EFI_SUCCESS;
}
/**
Get specific field of HcReset reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcReset (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Field
)
{
HcRESET Reset;
UINT32 Value;
*(UINT32 *) &Reset = OhciGetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR);
Value = 0;
switch (Field) {
case RESET_SYSTEM_BUS:
Value = Reset.FSBIR;
break;
case RESET_HOST_CONTROLLER:
Value = Reset.FHR;
break;
case RESET_CLOCK_GENERATION:
Value = Reset.CGR;
break;
case RESET_SSE_GLOBAL:
Value = Reset.SSE;
break;
case RESET_PSPL:
Value = Reset.PSPL;
break;
case RESET_PCPL:
Value = Reset.PCPL;
break;
case RESET_SSEP1:
Value = Reset.SSEP1;
break;
case RESET_SSEP2:
Value = Reset.SSEP2;
break;
case RESET_SSEP3:
Value = Reset.SSEP3;
break;
default:
ASSERT (FALSE);
}
return Value;
}
/**
Set HcControl reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
)
{
EFI_STATUS Status;
HcCONTROL Control;
*(UINT32 *) &Control = OhciGetOperationalReg (Ohc->PciIo, HC_CONTROL);
if (Field & CONTROL_BULK_RATIO) {
Control.ControlBulkRatio = Value;
}
if (Field & HC_FUNCTIONAL_STATE) {
Control.FunctionalState = Value;
}
if (Field & PERIODIC_ENABLE) {
Control.PeriodicEnable = Value;
}
if (Field & CONTROL_ENABLE) {
Control.ControlEnable = Value;
}
if (Field & ISOCHRONOUS_ENABLE) {
Control.IsochronousEnable = Value;
}
if (Field & BULK_ENABLE) {
Control.BulkEnable = Value;
}
if (Field & INTERRUPT_ROUTING) {
Control.InterruptRouting = Value;
}
Status = OhciSetOperationalReg (Ohc->PciIo, HC_CONTROL, &Control);
return Status;
}
/**
Get specific field of HcControl reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
HcCONTROL Control;
*(UINT32 *) &Control = OhciGetOperationalReg (Ohc->PciIo, HC_CONTROL);
switch (Field) {
case CONTROL_BULK_RATIO:
return Control.ControlBulkRatio;
break;
case PERIODIC_ENABLE:
return Control.PeriodicEnable;
break;
case CONTROL_ENABLE:
return Control.ControlEnable;
break;
case BULK_ENABLE:
return Control.BulkEnable;
break;
case ISOCHRONOUS_ENABLE:
return Control.IsochronousEnable;
break;
case HC_FUNCTIONAL_STATE:
return Control.FunctionalState;
break;
case INTERRUPT_ROUTING:
return Control.InterruptRouting;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set HcCommand reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcCommandStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
)
{
EFI_STATUS Status;
HcCOMMAND_STATUS CommandStatus;
ZeroMem (&CommandStatus, sizeof (HcCOMMAND_STATUS));
if(Field & HC_RESET){
CommandStatus.HcReset = Value;
}
if(Field & CONTROL_LIST_FILLED){
CommandStatus.ControlListFilled = Value;
}
if(Field & BULK_LIST_FILLED){
CommandStatus.BulkListFilled = Value;
}
if(Field & CHANGE_OWNER_REQUEST){
CommandStatus.ChangeOwnerRequest = Value;
}
if(Field & SCHEDULE_OVERRUN_COUNT){
CommandStatus.ScheduleOverrunCount = Value;
}
Status = OhciSetOperationalReg (Ohc->PciIo, HC_COMMAND_STATUS, &CommandStatus);
return Status;
}
/**
Get specific field of HcCommand reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcCommandStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
HcCOMMAND_STATUS CommandStatus;
*(UINT32 *) &CommandStatus = OhciGetOperationalReg (Ohc->PciIo, HC_COMMAND_STATUS);
switch (Field){
case HC_RESET:
return CommandStatus.HcReset;
break;
case CONTROL_LIST_FILLED:
return CommandStatus.ControlListFilled;
break;
case BULK_LIST_FILLED:
return CommandStatus.BulkListFilled;
break;
case CHANGE_OWNER_REQUEST:
return CommandStatus.ChangeOwnerRequest;
break;
case SCHEDULE_OVERRUN_COUNT:
return CommandStatus.ScheduleOverrunCount;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Clear specific fields of Interrupt Status
@param Ohc UHC private data
@param Field Field to clear
@retval EFI_SUCCESS Fields cleared
**/
EFI_STATUS
OhciClearInterruptStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
EFI_STATUS Status;
HcINTERRUPT_STATUS InterruptStatus;
ZeroMem (&InterruptStatus, sizeof (HcINTERRUPT_STATUS));
if(Field & SCHEDULE_OVERRUN){
InterruptStatus.SchedulingOverrun = 1;
}
if(Field & WRITEBACK_DONE_HEAD){
InterruptStatus.WriteBackDone = 1;
}
if(Field & START_OF_FRAME){
InterruptStatus.Sof = 1;
}
if(Field & RESUME_DETECT){
InterruptStatus.ResumeDetected = 1;
}
if(Field & UNRECOVERABLE_ERROR){
InterruptStatus.UnrecoverableError = 1;
}
if(Field & FRAME_NUMBER_OVERFLOW){
InterruptStatus.FrameNumOverflow = 1;
}
if(Field & ROOTHUB_STATUS_CHANGE){
InterruptStatus.RHStatusChange = 1;
}
if(Field & OWNERSHIP_CHANGE){
InterruptStatus.OwnerChange = 1;
}
Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_STATUS, &InterruptStatus);
return Status;
}
/**
Get fields of HcInterrupt reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcInterruptStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
HcINTERRUPT_STATUS InterruptStatus;
*(UINT32 *) &InterruptStatus = OhciGetOperationalReg (Ohc->PciIo, HC_INTERRUPT_STATUS);
switch (Field){
case SCHEDULE_OVERRUN:
return InterruptStatus.SchedulingOverrun;
break;
case WRITEBACK_DONE_HEAD:
return InterruptStatus.WriteBackDone;
break;
case START_OF_FRAME:
return InterruptStatus.Sof;
break;
case RESUME_DETECT:
return InterruptStatus.ResumeDetected;
break;
case UNRECOVERABLE_ERROR:
return InterruptStatus.UnrecoverableError;
break;
case FRAME_NUMBER_OVERFLOW:
return InterruptStatus.FrameNumOverflow;
break;
case ROOTHUB_STATUS_CHANGE:
return InterruptStatus.RHStatusChange;
break;
case OWNERSHIP_CHANGE:
return InterruptStatus.OwnerChange;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set Interrupt Control reg value
@param Ohc UHC private data
@param StatEnable Enable or Disable
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetInterruptControl (
IN USB_OHCI_HC_DEV *Ohc,
IN BOOLEAN StatEnable,
IN UINTN Field,
IN UINT32 Value
)
{
EFI_STATUS Status;
HcINTERRUPT_CONTROL InterruptState;
ZeroMem (&InterruptState, sizeof (HcINTERRUPT_CONTROL));
if(Field & SCHEDULE_OVERRUN) {
InterruptState.SchedulingOverrunInt = Value;
}
if(Field & WRITEBACK_DONE_HEAD) {
InterruptState.WriteBackDoneInt = Value;
}
if(Field & START_OF_FRAME) {
InterruptState.SofInt = Value;
}
if(Field & RESUME_DETECT) {
InterruptState.ResumeDetectedInt = Value;
}
if(Field & UNRECOVERABLE_ERROR) {
InterruptState.UnrecoverableErrorInt = Value;
}
if(Field & FRAME_NUMBER_OVERFLOW) {
InterruptState.FrameNumOverflowInt = Value;
}
if(Field & ROOTHUB_STATUS_CHANGE) {
InterruptState.RHStatusChangeInt = Value;
}
if(Field & OWNERSHIP_CHANGE) {
InterruptState.OwnerChangedInt = Value;
}
if(Field & MASTER_INTERRUPT) {
InterruptState.MasterInterruptEnable = Value;
}
if (StatEnable) {
Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_ENABLE, &InterruptState);
} else {
Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_DISABLE, &InterruptState);
}
return Status;
}
/**
Get field of HcInterruptControl reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcInterruptControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
HcINTERRUPT_CONTROL InterruptState;
*(UINT32 *) &InterruptState = OhciGetOperationalReg (Ohc->PciIo, HC_INTERRUPT_ENABLE);
switch (Field){
case SCHEDULE_OVERRUN:
return InterruptState.SchedulingOverrunInt;
break;
case WRITEBACK_DONE_HEAD:
return InterruptState.WriteBackDoneInt;
break;
case START_OF_FRAME:
return InterruptState.SofInt;
break;
case RESUME_DETECT:
return InterruptState.ResumeDetectedInt;
break;
case UNRECOVERABLE_ERROR:
return InterruptState.UnrecoverableErrorInt;
break;
case FRAME_NUMBER_OVERFLOW:
return InterruptState.FrameNumOverflowInt;
break;
case ROOTHUB_STATUS_CHANGE:
return InterruptState.RHStatusChangeInt;
break;
case OWNERSHIP_CHANGE:
return InterruptState.OwnerChangedInt;
break;
case MASTER_INTERRUPT:
return InterruptState.MasterInterruptEnable;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set memory pointer of specific type
@param Ohc UHC private data
@param PointerType Type of the pointer to set
@param Value Value to set
@retval EFI_SUCCESS Memory pointer set
**/
EFI_STATUS
OhciSetMemoryPointer(
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 PointerType,
IN VOID *Value
)
{
EFI_STATUS Status;
UINT32 Verify;
Status = OhciSetOperationalReg (Ohc->PciIo, PointerType, &Value);
if (EFI_ERROR (Status)) {
return Status;
}
Verify = OhciGetOperationalReg (Ohc->PciIo, PointerType);
while (Verify != (UINT32)(UINTN) Value) {
gBS->Stall(1000);
Verify = OhciGetOperationalReg (Ohc->PciIo, PointerType);
};
return Status;
}
/**
Get memory pointer of specific type
@param Ohc UHC private data
@param PointerType Type of pointer
@retval Memory pointer of the specific type
**/
VOID *
OhciGetMemoryPointer (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 PointerType
)
{
return (VOID *)(UINTN) OhciGetOperationalReg (Ohc->PciIo, PointerType);
}
/**
Set Frame Interval value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameInterval (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
)
{
EFI_STATUS Status;
HcFRM_INTERVAL FrameInterval;
*(UINT32 *) &FrameInterval = OhciGetOperationalReg(Ohc->PciIo, HC_FRM_INTERVAL);
if (Field & FRAME_INTERVAL) {
FrameInterval.FrmIntervalToggle = !FrameInterval.FrmIntervalToggle;
FrameInterval.FrameInterval = Value;
}
if (Field & FS_LARGEST_DATA_PACKET) {
FrameInterval.FSMaxDataPacket = Value;
}
if (Field & FRMINT_TOGGLE) {
FrameInterval.FrmIntervalToggle = Value;
}
Status = OhciSetOperationalReg (
Ohc->PciIo,
HC_FRM_INTERVAL,
&FrameInterval
);
return Status;
}
/**
Get field of frame interval reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetFrameInterval (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
HcFRM_INTERVAL FrameInterval;
*(UINT32 *) &FrameInterval = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_INTERVAL);
switch (Field){
case FRAME_INTERVAL:
return FrameInterval.FrameInterval;
break;
case FS_LARGEST_DATA_PACKET:
return FrameInterval.FSMaxDataPacket;
break;
case FRMINT_TOGGLE:
return FrameInterval.FrmIntervalToggle;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set Frame Remaining reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameRemaining (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
)
{
EFI_STATUS Status;
HcFRAME_REMAINING FrameRemaining;
*(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING);
FrameRemaining.FrameRemaining = Value;
FrameRemaining.FrameRemainingToggle = !FrameRemaining.FrameRemainingToggle;
Status = OhciSetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING, &FrameRemaining);
return Status;
}
/**
Get value of frame remaining reg
@param Ohc UHC private data
@param Field Field to get
@retval Value of frame remaining reg
**/
UINT32
OhciGetFrameRemaining (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
HcFRAME_REMAINING FrameRemaining;
*(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING);
switch (Field){
case FRAME_REMAINING:
return FrameRemaining.FrameRemaining;
break;
case FRAME_REMAIN_TOGGLE:
return FrameRemaining.FrameRemainingToggle;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set frame number reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameNumber(
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
)
{
EFI_STATUS Status;
Status = OhciSetOperationalReg (Ohc->PciIo, HC_FRM_NUMBER, &Value);
return Status;
}
/**
Get frame number reg value
@param Ohc UHC private data
@retval Value of frame number reg
**/
UINT32
OhciGetFrameNumber (
IN USB_OHCI_HC_DEV *Ohc
)
{
return OhciGetOperationalReg(Ohc->PciIo, HC_FRM_NUMBER);
}
/**
Set period start reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetPeriodicStart (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
)
{
EFI_STATUS Status;
Status = OhciSetOperationalReg (Ohc->PciIo, HC_PERIODIC_START, &Value);
return Status;
}
/**
Get periodic start reg value
@param Ohc UHC private data
@param Value of periodic start reg
**/
UINT32
OhciGetPeriodicStart (
IN USB_OHCI_HC_DEV *Ohc
)
{
return OhciGetOperationalReg(Ohc->PciIo, HC_PERIODIC_START);
}
/**
Set Ls Threshold reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetLsThreshold (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
)
{
EFI_STATUS Status;
Status = OhciSetOperationalReg (Ohc->PciIo, HC_LS_THREASHOLD, &Value);
return Status;
}
/**
Get Ls Threshold reg value
@param Ohc UHC private data
@retval Value of Ls Threshold reg
**/
UINT32
OhciGetLsThreshold (
IN USB_OHCI_HC_DEV *Ohc
)
{
return OhciGetOperationalReg(Ohc->PciIo, HC_LS_THREASHOLD);
}
/**
Set Root Hub Descriptor reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubDescriptor (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
)
{
EFI_STATUS Status;
HcRH_DESC_A DescriptorA;
HcRH_DESC_B DescriptorB;
if (Field & (RH_DEV_REMOVABLE | RH_PORT_PWR_CTRL_MASK)) {
*(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_B);
if(Field & RH_DEV_REMOVABLE) {
DescriptorB.DeviceRemovable = Value;
}
if(Field & RH_PORT_PWR_CTRL_MASK) {
DescriptorB.PortPowerControlMask = Value;
}
Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_DESC_B, &DescriptorB);
return Status;
}
*(UINT32 *)&DescriptorA = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_A);
if(Field & RH_NUM_DS_PORTS) {
DescriptorA.NumDownStrmPorts = Value;
}
if(Field & RH_NO_PSWITCH) {
DescriptorA.NoPowerSwitch = Value;
}
if(Field & RH_PSWITCH_MODE) {
DescriptorA.PowerSwitchMode = Value;
}
if(Field & RH_DEVICE_TYPE) {
DescriptorA.DeviceType = Value;
}
if(Field & RH_OC_PROT_MODE) {
DescriptorA.OverCurrentProtMode = Value;
}
if(Field & RH_NOC_PROT) {
DescriptorA.NoOverCurrentProtMode = Value;
}
if(Field & RH_NO_POTPGT) {
DescriptorA.PowerOnToPowerGoodTime = Value;
}
Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_DESC_A, &DescriptorA);
return Status;
}
/**
Get Root Hub Descriptor reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetRootHubDescriptor (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
HcRH_DESC_A DescriptorA;
HcRH_DESC_B DescriptorB;
*(UINT32 *) &DescriptorA = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_A);
*(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_B);
switch (Field){
case RH_DEV_REMOVABLE:
return DescriptorB.DeviceRemovable;
break;
case RH_PORT_PWR_CTRL_MASK:
return DescriptorB.PortPowerControlMask;
break;
case RH_NUM_DS_PORTS:
return DescriptorA.NumDownStrmPorts;
break;
case RH_NO_PSWITCH:
return DescriptorA.NoPowerSwitch;
break;
case RH_PSWITCH_MODE:
return DescriptorA.PowerSwitchMode;
break;
case RH_DEVICE_TYPE:
return DescriptorA.DeviceType;
break;
case RH_OC_PROT_MODE:
return DescriptorA.OverCurrentProtMode;
break;
case RH_NOC_PROT:
return DescriptorA.NoOverCurrentProtMode;
break;
case RH_NO_POTPGT:
return DescriptorA.PowerOnToPowerGoodTime;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set Root Hub Status reg value
@param Ohc UHC private data
@param Field Field to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
EFI_STATUS Status;
HcRH_STATUS RootHubStatus;
ZeroMem (&RootHubStatus, sizeof(HcRH_STATUS));
if(Field & RH_LOCAL_PSTAT){
RootHubStatus.LocalPowerStat = 1;
}
if(Field & RH_OC_ID){
RootHubStatus.OverCurrentIndicator = 1;
}
if(Field & RH_REMOTE_WK_ENABLE){
RootHubStatus.DevRemoteWakeupEnable = 1;
}
if(Field & RH_LOCAL_PSTAT_CHANGE){
RootHubStatus.LocalPowerStatChange = 1;
}
if(Field & RH_OC_ID_CHANGE){
RootHubStatus.OverCurrentIndicatorChange = 1;
}
if(Field & RH_CLR_RMT_WK_ENABLE){
RootHubStatus.ClearRemoteWakeupEnable = 1;
}
Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_STATUS, &RootHubStatus);
return Status;
}
/**
Get Root Hub Status reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetRootHubStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
)
{
HcRH_STATUS RootHubStatus;
*(UINT32 *) &RootHubStatus = OhciGetOperationalReg (Ohc->PciIo, HC_RH_STATUS);
switch (Field) {
case RH_LOCAL_PSTAT:
return RootHubStatus.LocalPowerStat;
break;
case RH_OC_ID:
return RootHubStatus.OverCurrentIndicator;
break;
case RH_REMOTE_WK_ENABLE:
return RootHubStatus.DevRemoteWakeupEnable;
break;
case RH_LOCAL_PSTAT_CHANGE:
return RootHubStatus.LocalPowerStatChange;
break;
case RH_OC_ID_CHANGE:
return RootHubStatus.OverCurrentIndicatorChange;
break;
case RH_CLR_RMT_WK_ENABLE:
return RootHubStatus.ClearRemoteWakeupEnable;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set Root Hub Port Status reg value
@param Ohc UHC private data
@param Index Index of the port
@param Field Field to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubPortStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Index,
IN UINTN Field
)
{
EFI_STATUS Status;
HcRHPORT_STATUS PortStatus;
ZeroMem (&PortStatus, sizeof(HcRHPORT_STATUS));
if (Field & RH_CLEAR_PORT_ENABLE) {
PortStatus.CurrentConnectStat = 1;
}
if (Field & RH_SET_PORT_ENABLE) {
PortStatus.EnableStat = 1;
}
if (Field & RH_SET_PORT_SUSPEND) {
PortStatus.SuspendStat = 1;
}
if (Field & RH_CLEAR_SUSPEND_STATUS) {
PortStatus.OCIndicator = 1;
}
if (Field & RH_SET_PORT_RESET) {
PortStatus.ResetStat = 1;
}
if (Field & RH_SET_PORT_POWER) {
PortStatus.PowerStat = 1;
}
if (Field & RH_CLEAR_PORT_POWER) {
PortStatus.LsDeviceAttached = 1;
}
if (Field & RH_CONNECT_STATUS_CHANGE) {
PortStatus.ConnectStatChange = 1;
}
if (Field & RH_PORT_ENABLE_STAT_CHANGE) {
PortStatus.EnableStatChange = 1;
}
if (Field & RH_PORT_SUSPEND_STAT_CHANGE) {
PortStatus.SuspendStatChange = 1;
}
if (Field & RH_OC_INDICATOR_CHANGE) {
PortStatus.OCIndicatorChange = 1;
}
if (Field & RH_PORT_RESET_STAT_CHANGE ) {
PortStatus.ResetStatChange = 1;
}
Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_PORT_STATUS + (Index * 4), &PortStatus);
return Status;
}
/**
Get Root Hub Port Status reg value
@param Ohc UHC private data
@param Index Index of the port
@param Field Field to get
@retval Value of the field and index
**/
UINT32
OhciReadRootHubPortStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Index,
IN UINTN Field
)
{
HcRHPORT_STATUS PortStatus;
*(UINT32 *) &PortStatus = OhciGetOperationalReg (
Ohc->PciIo,
HC_RH_PORT_STATUS + (Index * 4)
);
switch (Field){
case RH_CURR_CONNECT_STAT:
return PortStatus.CurrentConnectStat;
break;
case RH_PORT_ENABLE_STAT:
return PortStatus.EnableStat;
break;
case RH_PORT_SUSPEND_STAT:
return PortStatus.SuspendStat;
break;
case RH_PORT_OC_INDICATOR:
return PortStatus.OCIndicator;
break;
case RH_PORT_RESET_STAT:
return PortStatus.ResetStat;
break;
case RH_PORT_POWER_STAT:
return PortStatus.PowerStat;
break;
case RH_LSDEVICE_ATTACHED:
return PortStatus.LsDeviceAttached;
break;
case RH_CONNECT_STATUS_CHANGE:
return PortStatus.ConnectStatChange;
break;
case RH_PORT_ENABLE_STAT_CHANGE:
return PortStatus.EnableStatChange;
break;
case RH_PORT_SUSPEND_STAT_CHANGE:
return PortStatus.SuspendStatChange;
break;
case RH_OC_INDICATOR_CHANGE:
return PortStatus.OCIndicatorChange;
break;
case RH_PORT_RESET_STAT_CHANGE:
return PortStatus.ResetStatChange;
break;
default:
ASSERT (FALSE);
}
return 0;
}