Home | History | Annotate | Download | only in Dxe
      1 /** @file
      2 The OHCI register operation routines.
      3 
      4 Copyright (c) 2013-2015 Intel Corporation.
      5 
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD License
      8 which accompanies this distribution.  The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 
     17 #include "Ohci.h"
     18 
     19 /**
     20 
     21   Get OHCI operational reg value
     22 
     23   @param  PciIo                 PciIo protocol instance
     24   @param  Offset                Offset of the operational reg
     25 
     26   @retval                       Value of the register
     27 
     28 **/
     29 UINT32
     30 OhciGetOperationalReg (
     31   IN EFI_PCI_IO_PROTOCOL  *PciIo,
     32   IN UINT32               Offset
     33   )
     34 {
     35   UINT32                  Value;
     36   EFI_STATUS              Status;
     37 
     38   Status = PciIo->Mem.Read(PciIo, EfiPciIoWidthUint32, OHC_BAR_INDEX, Offset, 1, &Value);
     39 
     40   return Value;
     41 }
     42 /**
     43 
     44   Set OHCI operational reg value
     45 
     46   @param  PciIo                  PCI Bus Io protocol instance
     47   @param  Offset                 Offset of the operational reg
     48   @param  Value                  Value to set
     49 
     50   @retval EFI_SUCCESS            Value set to the reg
     51 
     52 **/
     53 
     54 
     55 EFI_STATUS
     56 OhciSetOperationalReg (
     57   IN EFI_PCI_IO_PROTOCOL  *PciIo,
     58   IN UINT32               Offset,
     59   IN VOID                 *Value
     60   )
     61 {
     62   EFI_STATUS Status;
     63 
     64   Status = PciIo->Mem.Write(PciIo, EfiPciIoWidthUint32, OHC_BAR_INDEX, Offset, 1, Value);
     65 
     66   return Status;
     67 }
     68 /**
     69 
     70   Get HcRevision reg value
     71 
     72   @param  PciIo                 PCI Bus Io protocol instance
     73 
     74   @retval                       Value of the register
     75 
     76 **/
     77 
     78 
     79 UINT32
     80 OhciGetHcRevision (
     81   IN EFI_PCI_IO_PROTOCOL  *PciIo
     82   )
     83 {
     84   return OhciGetOperationalReg (PciIo, HC_REVISION);
     85 }
     86 /**
     87 
     88   Set HcReset reg value
     89 
     90   @param  Ohc                   UHC private data
     91   @param  Field                 Field to set
     92   @param  Value                 Value to set
     93 
     94   @retval EFI_SUCCESS           Value set
     95 
     96 **/
     97 
     98 EFI_STATUS
     99 OhciSetHcReset (
    100   IN USB_OHCI_HC_DEV            *Ohc,
    101   IN UINT32                     Field,
    102   IN UINT32                     Value
    103   )
    104 {
    105   EFI_STATUS                    Status;
    106   HcRESET                       Reset;
    107 
    108   Status = EFI_SUCCESS;
    109   *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR);
    110 
    111   if (Field & RESET_SYSTEM_BUS) {
    112     Reset.FSBIR = Value;
    113   }
    114 
    115   if (Field & RESET_HOST_CONTROLLER) {
    116     Reset.FHR = Value;
    117   }
    118 
    119   if (Field & RESET_CLOCK_GENERATION) {
    120     Reset.CGR = Value;
    121   }
    122 
    123   if (Field & RESET_SSE_GLOBAL) {
    124     Reset.SSE = Value;
    125   }
    126 
    127   if (Field & RESET_PSPL) {
    128     Reset.PSPL = Value;
    129   }
    130 
    131   if (Field & RESET_PCPL) {
    132     Reset.PCPL = Value;
    133   }
    134 
    135   if (Field & RESET_SSEP1) {
    136     Reset.SSEP1 = Value;
    137   }
    138 
    139   if (Field & RESET_SSEP2) {
    140     Reset.SSEP2 = Value;
    141   }
    142 
    143   if (Field & RESET_SSEP3) {
    144     Reset.SSEP3 = Value;
    145   }
    146 
    147   OhciSetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR, &Reset);
    148 
    149   return EFI_SUCCESS;
    150 }
    151 
    152 /**
    153 
    154   Get specific field of HcReset reg value
    155 
    156   @param  Ohc                   UHC private data
    157   @param  Field                 Field to get
    158 
    159   @retval                       Value of the field
    160 
    161 **/
    162 
    163 UINT32
    164 OhciGetHcReset (
    165   IN USB_OHCI_HC_DEV      *Ohc,
    166   IN UINT32               Field
    167   )
    168 {
    169   HcRESET                 Reset;
    170   UINT32                  Value;
    171 
    172 
    173   *(UINT32 *) &Reset = OhciGetOperationalReg (Ohc->PciIo, USBHOST_OFFSET_UHCHR);
    174   Value = 0;
    175 
    176   switch (Field) {
    177   case RESET_SYSTEM_BUS:
    178     Value = Reset.FSBIR;
    179     break;
    180 
    181   case RESET_HOST_CONTROLLER:
    182     Value = Reset.FHR;
    183     break;
    184 
    185   case RESET_CLOCK_GENERATION:
    186     Value = Reset.CGR;
    187     break;
    188 
    189   case RESET_SSE_GLOBAL:
    190     Value = Reset.SSE;
    191     break;
    192 
    193   case RESET_PSPL:
    194     Value = Reset.PSPL;
    195     break;
    196 
    197   case RESET_PCPL:
    198     Value = Reset.PCPL;
    199     break;
    200 
    201   case RESET_SSEP1:
    202     Value = Reset.SSEP1;
    203     break;
    204 
    205   case RESET_SSEP2:
    206     Value = Reset.SSEP2;
    207     break;
    208 
    209   case RESET_SSEP3:
    210     Value = Reset.SSEP3;
    211     break;
    212 
    213   default:
    214     ASSERT (FALSE);
    215   }
    216 
    217 
    218   return Value;
    219 }
    220 
    221 /**
    222 
    223   Set HcControl reg value
    224 
    225   @param  Ohc                   UHC private data
    226   @param  Field                 Field to set
    227   @param  Value                 Value to set
    228 
    229   @retval  EFI_SUCCESS          Value set
    230 
    231 **/
    232 
    233 EFI_STATUS
    234 OhciSetHcControl (
    235   IN USB_OHCI_HC_DEV      *Ohc,
    236   IN UINTN                Field,
    237   IN UINT32               Value
    238   )
    239 {
    240   EFI_STATUS              Status;
    241   HcCONTROL               Control;
    242 
    243 
    244 
    245   *(UINT32 *) &Control = OhciGetOperationalReg (Ohc->PciIo, HC_CONTROL);
    246 
    247   if (Field & CONTROL_BULK_RATIO) {
    248     Control.ControlBulkRatio = Value;
    249   }
    250 
    251   if (Field & HC_FUNCTIONAL_STATE) {
    252     Control.FunctionalState = Value;
    253   }
    254 
    255   if (Field & PERIODIC_ENABLE) {
    256     Control.PeriodicEnable = Value;
    257   }
    258 
    259   if (Field & CONTROL_ENABLE) {
    260     Control.ControlEnable = Value;
    261   }
    262 
    263   if (Field & ISOCHRONOUS_ENABLE) {
    264     Control.IsochronousEnable = Value;
    265   }
    266 
    267   if (Field & BULK_ENABLE) {
    268     Control.BulkEnable = Value;
    269   }
    270 
    271   if (Field & INTERRUPT_ROUTING) {
    272     Control.InterruptRouting = Value;
    273   }
    274 
    275   Status = OhciSetOperationalReg (Ohc->PciIo, HC_CONTROL, &Control);
    276 
    277   return Status;
    278 }
    279 
    280 
    281 /**
    282 
    283   Get specific field of HcControl reg value
    284 
    285   @param  Ohc                   UHC private data
    286   @param  Field                 Field to get
    287 
    288   @retval                       Value of the field
    289 
    290 **/
    291 
    292 
    293 UINT32
    294 OhciGetHcControl (
    295   IN USB_OHCI_HC_DEV   *Ohc,
    296   IN UINTN             Field
    297   )
    298 {
    299   HcCONTROL     Control;
    300 
    301   *(UINT32 *) &Control = OhciGetOperationalReg (Ohc->PciIo, HC_CONTROL);
    302 
    303   switch (Field) {
    304   case CONTROL_BULK_RATIO:
    305     return Control.ControlBulkRatio;
    306     break;
    307   case PERIODIC_ENABLE:
    308     return Control.PeriodicEnable;
    309     break;
    310   case CONTROL_ENABLE:
    311     return Control.ControlEnable;
    312     break;
    313   case BULK_ENABLE:
    314     return Control.BulkEnable;
    315     break;
    316   case ISOCHRONOUS_ENABLE:
    317     return Control.IsochronousEnable;
    318     break;
    319   case HC_FUNCTIONAL_STATE:
    320     return Control.FunctionalState;
    321     break;
    322   case INTERRUPT_ROUTING:
    323     return Control.InterruptRouting;
    324     break;
    325   default:
    326     ASSERT (FALSE);
    327   }
    328 
    329   return 0;
    330 }
    331 
    332 /**
    333 
    334   Set HcCommand reg value
    335 
    336   @param  Ohc                   UHC private data
    337   @param  Field                 Field to set
    338   @param  Value                 Value to set
    339 
    340   @retval EFI_SUCCESS           Value set
    341 
    342 **/
    343 
    344 EFI_STATUS
    345 OhciSetHcCommandStatus (
    346   IN USB_OHCI_HC_DEV      *Ohc,
    347   IN UINTN                Field,
    348   IN UINT32               Value
    349   )
    350 {
    351   EFI_STATUS              Status;
    352   HcCOMMAND_STATUS        CommandStatus;
    353 
    354   ZeroMem (&CommandStatus, sizeof (HcCOMMAND_STATUS));
    355 
    356   if(Field & HC_RESET){
    357     CommandStatus.HcReset = Value;
    358   }
    359 
    360   if(Field & CONTROL_LIST_FILLED){
    361     CommandStatus.ControlListFilled = Value;
    362   }
    363 
    364   if(Field & BULK_LIST_FILLED){
    365     CommandStatus.BulkListFilled = Value;
    366   }
    367 
    368   if(Field & CHANGE_OWNER_REQUEST){
    369     CommandStatus.ChangeOwnerRequest = Value;
    370   }
    371 
    372   if(Field & SCHEDULE_OVERRUN_COUNT){
    373     CommandStatus.ScheduleOverrunCount = Value;
    374   }
    375 
    376   Status = OhciSetOperationalReg (Ohc->PciIo, HC_COMMAND_STATUS, &CommandStatus);
    377 
    378   return Status;
    379 }
    380 
    381 /**
    382 
    383   Get specific field of HcCommand reg value
    384 
    385   @param  Ohc                   UHC private data
    386   @param  Field                 Field to get
    387 
    388   @retval                       Value of the field
    389 
    390 **/
    391 
    392 UINT32
    393 OhciGetHcCommandStatus (
    394   IN USB_OHCI_HC_DEV      *Ohc,
    395   IN UINTN                Field
    396   )
    397 {
    398   HcCOMMAND_STATUS        CommandStatus;
    399 
    400   *(UINT32 *) &CommandStatus = OhciGetOperationalReg (Ohc->PciIo, HC_COMMAND_STATUS);
    401 
    402   switch (Field){
    403   case HC_RESET:
    404     return CommandStatus.HcReset;
    405     break;
    406   case CONTROL_LIST_FILLED:
    407     return CommandStatus.ControlListFilled;
    408     break;
    409   case BULK_LIST_FILLED:
    410     return CommandStatus.BulkListFilled;
    411     break;
    412   case CHANGE_OWNER_REQUEST:
    413     return CommandStatus.ChangeOwnerRequest;
    414     break;
    415   case SCHEDULE_OVERRUN_COUNT:
    416     return CommandStatus.ScheduleOverrunCount;
    417     break;
    418   default:
    419     ASSERT (FALSE);
    420   }
    421 
    422   return 0;
    423 }
    424 
    425 /**
    426 
    427   Clear specific fields of Interrupt Status
    428 
    429   @param  Ohc                   UHC private data
    430   @param  Field                 Field to clear
    431 
    432   @retval EFI_SUCCESS           Fields cleared
    433 
    434 **/
    435 
    436 EFI_STATUS
    437 OhciClearInterruptStatus (
    438   IN USB_OHCI_HC_DEV      *Ohc,
    439   IN UINTN                Field
    440   )
    441 {
    442   EFI_STATUS              Status;
    443   HcINTERRUPT_STATUS      InterruptStatus;
    444 
    445   ZeroMem (&InterruptStatus, sizeof (HcINTERRUPT_STATUS));
    446 
    447   if(Field & SCHEDULE_OVERRUN){
    448     InterruptStatus.SchedulingOverrun = 1;
    449   }
    450 
    451   if(Field & WRITEBACK_DONE_HEAD){
    452     InterruptStatus.WriteBackDone = 1;
    453   }
    454   if(Field & START_OF_FRAME){
    455     InterruptStatus.Sof = 1;
    456   }
    457 
    458   if(Field & RESUME_DETECT){
    459     InterruptStatus.ResumeDetected = 1;
    460   }
    461 
    462   if(Field & UNRECOVERABLE_ERROR){
    463     InterruptStatus.UnrecoverableError = 1;
    464   }
    465 
    466   if(Field & FRAME_NUMBER_OVERFLOW){
    467     InterruptStatus.FrameNumOverflow = 1;
    468   }
    469 
    470   if(Field & ROOTHUB_STATUS_CHANGE){
    471     InterruptStatus.RHStatusChange = 1;
    472   }
    473 
    474   if(Field & OWNERSHIP_CHANGE){
    475     InterruptStatus.OwnerChange = 1;
    476   }
    477 
    478   Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_STATUS, &InterruptStatus);
    479 
    480   return Status;
    481 }
    482 
    483 /**
    484 
    485   Get fields of HcInterrupt reg value
    486 
    487   @param  Ohc                   UHC private data
    488   @param  Field                 Field to get
    489 
    490   @retval                       Value of the field
    491 
    492 **/
    493 
    494 UINT32
    495 OhciGetHcInterruptStatus (
    496   IN USB_OHCI_HC_DEV      *Ohc,
    497   IN UINTN                Field
    498   )
    499 {
    500   HcINTERRUPT_STATUS      InterruptStatus;
    501 
    502   *(UINT32 *) &InterruptStatus = OhciGetOperationalReg (Ohc->PciIo, HC_INTERRUPT_STATUS);
    503 
    504   switch (Field){
    505   case SCHEDULE_OVERRUN:
    506     return InterruptStatus.SchedulingOverrun;
    507     break;
    508 
    509   case  WRITEBACK_DONE_HEAD:
    510     return InterruptStatus.WriteBackDone;
    511     break;
    512 
    513   case START_OF_FRAME:
    514     return InterruptStatus.Sof;
    515     break;
    516 
    517   case RESUME_DETECT:
    518     return InterruptStatus.ResumeDetected;
    519     break;
    520 
    521   case UNRECOVERABLE_ERROR:
    522     return InterruptStatus.UnrecoverableError;
    523     break;
    524 
    525   case FRAME_NUMBER_OVERFLOW:
    526     return InterruptStatus.FrameNumOverflow;
    527     break;
    528 
    529   case ROOTHUB_STATUS_CHANGE:
    530     return InterruptStatus.RHStatusChange;
    531     break;
    532 
    533   case OWNERSHIP_CHANGE:
    534     return InterruptStatus.OwnerChange;
    535     break;
    536 
    537   default:
    538     ASSERT (FALSE);
    539   }
    540 
    541   return 0;
    542 }
    543 
    544 /**
    545 
    546   Set Interrupt Control reg value
    547 
    548   @param  Ohc                   UHC private data
    549   @param  StatEnable            Enable or Disable
    550   @param  Field                 Field to set
    551   @param  Value                 Value to set
    552 
    553   @retval EFI_SUCCESS           Value set
    554 
    555 **/
    556 
    557 EFI_STATUS
    558 OhciSetInterruptControl (
    559   IN USB_OHCI_HC_DEV      *Ohc,
    560   IN BOOLEAN              StatEnable,
    561   IN UINTN                Field,
    562   IN UINT32               Value
    563   )
    564 {
    565   EFI_STATUS              Status;
    566   HcINTERRUPT_CONTROL     InterruptState;
    567 
    568 
    569   ZeroMem (&InterruptState, sizeof (HcINTERRUPT_CONTROL));
    570 
    571   if(Field & SCHEDULE_OVERRUN) {
    572     InterruptState.SchedulingOverrunInt = Value;
    573   }
    574 
    575   if(Field & WRITEBACK_DONE_HEAD) {
    576     InterruptState.WriteBackDoneInt = Value;
    577   }
    578   if(Field & START_OF_FRAME) {
    579     InterruptState.SofInt = Value;
    580   }
    581 
    582   if(Field & RESUME_DETECT) {
    583     InterruptState.ResumeDetectedInt = Value;
    584   }
    585 
    586   if(Field & UNRECOVERABLE_ERROR) {
    587     InterruptState.UnrecoverableErrorInt = Value;
    588   }
    589 
    590   if(Field & FRAME_NUMBER_OVERFLOW) {
    591     InterruptState.FrameNumOverflowInt = Value;
    592   }
    593 
    594   if(Field & ROOTHUB_STATUS_CHANGE) {
    595     InterruptState.RHStatusChangeInt = Value;
    596   }
    597 
    598   if(Field & OWNERSHIP_CHANGE) {
    599     InterruptState.OwnerChangedInt = Value;
    600   }
    601 
    602   if(Field & MASTER_INTERRUPT) {
    603     InterruptState.MasterInterruptEnable = Value;
    604   }
    605 
    606   if (StatEnable) {
    607     Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_ENABLE, &InterruptState);
    608   } else {
    609     Status = OhciSetOperationalReg (Ohc->PciIo, HC_INTERRUPT_DISABLE, &InterruptState);
    610   }
    611 
    612   return Status;
    613 }
    614 
    615 /**
    616 
    617   Get field of HcInterruptControl reg value
    618 
    619   @param  Ohc                   UHC private data
    620   @param  Field                 Field to get
    621 
    622   @retval                       Value of the field
    623 
    624 **/
    625 
    626 UINT32
    627 OhciGetHcInterruptControl (
    628   IN USB_OHCI_HC_DEV      *Ohc,
    629   IN UINTN                Field
    630   )
    631 {
    632   HcINTERRUPT_CONTROL     InterruptState;
    633 
    634   *(UINT32 *) &InterruptState = OhciGetOperationalReg (Ohc->PciIo, HC_INTERRUPT_ENABLE);
    635 
    636   switch (Field){
    637     case SCHEDULE_OVERRUN:
    638       return InterruptState.SchedulingOverrunInt;
    639       break;
    640 
    641     case WRITEBACK_DONE_HEAD:
    642       return InterruptState.WriteBackDoneInt;
    643       break;
    644 
    645     case START_OF_FRAME:
    646       return InterruptState.SofInt;
    647       break;
    648 
    649     case RESUME_DETECT:
    650       return InterruptState.ResumeDetectedInt;
    651       break;
    652 
    653     case UNRECOVERABLE_ERROR:
    654       return InterruptState.UnrecoverableErrorInt;
    655       break;
    656 
    657     case FRAME_NUMBER_OVERFLOW:
    658       return InterruptState.FrameNumOverflowInt;
    659       break;
    660 
    661     case ROOTHUB_STATUS_CHANGE:
    662       return InterruptState.RHStatusChangeInt;
    663       break;
    664 
    665     case OWNERSHIP_CHANGE:
    666       return InterruptState.OwnerChangedInt;
    667       break;
    668 
    669     case MASTER_INTERRUPT:
    670       return InterruptState.MasterInterruptEnable;
    671       break;
    672 
    673     default:
    674       ASSERT (FALSE);
    675   }
    676 
    677   return 0;
    678 }
    679 
    680 /**
    681 
    682   Set memory pointer of specific type
    683 
    684   @param  Ohc                   UHC private data
    685   @param  PointerType           Type of the pointer to set
    686   @param  Value                 Value to set
    687 
    688   @retval EFI_SUCCESS           Memory pointer set
    689 
    690 **/
    691 
    692 EFI_STATUS
    693 OhciSetMemoryPointer(
    694   IN USB_OHCI_HC_DEV      *Ohc,
    695   IN UINT32               PointerType,
    696   IN VOID                 *Value
    697   )
    698 {
    699   EFI_STATUS              Status;
    700   UINT32                  Verify;
    701 
    702   Status = OhciSetOperationalReg (Ohc->PciIo, PointerType, &Value);
    703 
    704   if (EFI_ERROR (Status)) {
    705     return Status;
    706   }
    707 
    708   Verify = OhciGetOperationalReg (Ohc->PciIo, PointerType);
    709 
    710   while (Verify != (UINT32)(UINTN) Value) {
    711     gBS->Stall(1000);
    712     Verify = OhciGetOperationalReg (Ohc->PciIo, PointerType);
    713   };
    714 
    715 
    716   return Status;
    717 }
    718 
    719 /**
    720 
    721   Get memory pointer of specific type
    722 
    723   @param  Ohc                   UHC private data
    724   @param  PointerType           Type of pointer
    725 
    726   @retval                       Memory pointer of the specific type
    727 
    728 **/
    729 
    730 VOID *
    731 OhciGetMemoryPointer (
    732   IN USB_OHCI_HC_DEV      *Ohc,
    733   IN UINT32               PointerType
    734   )
    735 {
    736 
    737   return (VOID *)(UINTN) OhciGetOperationalReg (Ohc->PciIo, PointerType);
    738 }
    739 
    740 
    741 /**
    742 
    743   Set Frame Interval value
    744 
    745   @param  Ohc                   UHC private data
    746   @param  Field                 Field to set
    747   @param  Value                 Value to set
    748 
    749   @retval  EFI_SUCCESS          Value set
    750 
    751 **/
    752 
    753 EFI_STATUS
    754 OhciSetFrameInterval (
    755   IN USB_OHCI_HC_DEV      *Ohc,
    756   IN UINTN                Field,
    757   IN UINT32               Value
    758   )
    759 {
    760   EFI_STATUS              Status;
    761   HcFRM_INTERVAL          FrameInterval;
    762 
    763 
    764   *(UINT32 *) &FrameInterval = OhciGetOperationalReg(Ohc->PciIo, HC_FRM_INTERVAL);
    765 
    766   if (Field & FRAME_INTERVAL) {
    767     FrameInterval.FrmIntervalToggle = !FrameInterval.FrmIntervalToggle;
    768     FrameInterval.FrameInterval = Value;
    769   }
    770 
    771   if (Field & FS_LARGEST_DATA_PACKET) {
    772     FrameInterval.FSMaxDataPacket = Value;
    773   }
    774 
    775   if (Field & FRMINT_TOGGLE) {
    776     FrameInterval.FrmIntervalToggle = Value;
    777   }
    778 
    779   Status = OhciSetOperationalReg (
    780              Ohc->PciIo,
    781              HC_FRM_INTERVAL,
    782              &FrameInterval
    783              );
    784 
    785   return Status;
    786 }
    787 
    788 
    789 /**
    790 
    791   Get field of frame interval reg value
    792 
    793   @param  Ohc                   UHC private data
    794   @param  Field                 Field to get
    795 
    796   @retval                       Value of the field
    797 
    798 **/
    799 
    800 UINT32
    801 OhciGetFrameInterval (
    802   IN USB_OHCI_HC_DEV      *Ohc,
    803   IN UINTN                Field
    804   )
    805 {
    806   HcFRM_INTERVAL          FrameInterval;
    807 
    808   *(UINT32 *) &FrameInterval = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_INTERVAL);
    809 
    810   switch (Field){
    811     case FRAME_INTERVAL:
    812       return FrameInterval.FrameInterval;
    813       break;
    814 
    815     case FS_LARGEST_DATA_PACKET:
    816       return FrameInterval.FSMaxDataPacket;
    817       break;
    818 
    819     case FRMINT_TOGGLE:
    820       return FrameInterval.FrmIntervalToggle;
    821       break;
    822 
    823     default:
    824       ASSERT (FALSE);
    825   }
    826 
    827   return 0;
    828 }
    829 
    830 /**
    831 
    832   Set Frame Remaining reg value
    833 
    834   @param  Ohc                   UHC private data
    835   @param  Value                 Value to set
    836 
    837   @retval  EFI_SUCCESS          Value set
    838 
    839 **/
    840 
    841 EFI_STATUS
    842 OhciSetFrameRemaining (
    843   IN USB_OHCI_HC_DEV      *Ohc,
    844   IN UINT32               Value
    845   )
    846 {
    847   EFI_STATUS              Status;
    848   HcFRAME_REMAINING       FrameRemaining;
    849 
    850 
    851   *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING);
    852 
    853   FrameRemaining.FrameRemaining = Value;
    854   FrameRemaining.FrameRemainingToggle = !FrameRemaining.FrameRemainingToggle;
    855 
    856   Status = OhciSetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING, &FrameRemaining);
    857 
    858   return Status;
    859 }
    860 /**
    861 
    862   Get value of frame remaining reg
    863 
    864   @param  Ohc                   UHC private data
    865   @param  Field                 Field to get
    866 
    867   @retval                       Value of frame remaining reg
    868 
    869 **/
    870 UINT32
    871 OhciGetFrameRemaining (
    872   IN USB_OHCI_HC_DEV      *Ohc,
    873   IN UINTN                Field
    874   )
    875 
    876 {
    877   HcFRAME_REMAINING       FrameRemaining;
    878 
    879 
    880   *(UINT32 *) &FrameRemaining = OhciGetOperationalReg (Ohc->PciIo, HC_FRM_REMAINING);
    881 
    882   switch (Field){
    883     case FRAME_REMAINING:
    884       return FrameRemaining.FrameRemaining;
    885       break;
    886 
    887     case FRAME_REMAIN_TOGGLE:
    888       return FrameRemaining.FrameRemainingToggle;
    889       break;
    890 
    891     default:
    892       ASSERT (FALSE);
    893   }
    894 
    895   return 0;
    896 }
    897 
    898 /**
    899 
    900   Set frame number reg value
    901 
    902   @param  Ohc                   UHC private data
    903   @param  Value                 Value to set
    904 
    905   @retval  EFI_SUCCESS          Value set
    906 
    907 **/
    908 
    909 EFI_STATUS
    910 OhciSetFrameNumber(
    911   IN USB_OHCI_HC_DEV      *Ohc,
    912   IN UINT32               Value
    913   )
    914 {
    915   EFI_STATUS              Status;
    916 
    917   Status = OhciSetOperationalReg (Ohc->PciIo, HC_FRM_NUMBER, &Value);
    918 
    919   return Status;
    920 }
    921 
    922 /**
    923 
    924   Get frame number reg value
    925 
    926   @param  Ohc                   UHC private data
    927 
    928   @retval                       Value of frame number reg
    929 
    930 **/
    931 
    932 UINT32
    933 OhciGetFrameNumber (
    934   IN USB_OHCI_HC_DEV      *Ohc
    935   )
    936 {
    937   return OhciGetOperationalReg(Ohc->PciIo, HC_FRM_NUMBER);
    938 }
    939 
    940 /**
    941 
    942   Set period start reg value
    943 
    944   @param  Ohc                   UHC private data
    945   @param  Value                 Value to set
    946 
    947   @retval EFI_SUCCESS           Value set
    948 
    949 **/
    950 
    951 EFI_STATUS
    952 OhciSetPeriodicStart (
    953   IN USB_OHCI_HC_DEV      *Ohc,
    954   IN UINT32               Value
    955   )
    956 {
    957   EFI_STATUS              Status;
    958 
    959 
    960   Status = OhciSetOperationalReg (Ohc->PciIo, HC_PERIODIC_START, &Value);
    961 
    962   return Status;
    963 }
    964 
    965 
    966 /**
    967 
    968   Get periodic start reg value
    969 
    970   @param  Ohc                   UHC private data
    971 
    972   @param                        Value of periodic start reg
    973 
    974 **/
    975 
    976 UINT32
    977 OhciGetPeriodicStart (
    978   IN USB_OHCI_HC_DEV      *Ohc
    979   )
    980 {
    981   return OhciGetOperationalReg(Ohc->PciIo, HC_PERIODIC_START);
    982 }
    983 
    984 
    985 /**
    986 
    987   Set Ls Threshold reg value
    988 
    989   @param  Ohc                   UHC private data
    990   @param  Value                 Value to set
    991 
    992   @retval  EFI_SUCCESS          Value set
    993 
    994 **/
    995 
    996 EFI_STATUS
    997 OhciSetLsThreshold (
    998   IN USB_OHCI_HC_DEV      *Ohc,
    999   IN UINT32               Value
   1000   )
   1001 {
   1002   EFI_STATUS              Status;
   1003 
   1004 
   1005   Status = OhciSetOperationalReg (Ohc->PciIo, HC_LS_THREASHOLD, &Value);
   1006 
   1007   return Status;
   1008 }
   1009 
   1010 
   1011 /**
   1012 
   1013   Get Ls Threshold reg value
   1014 
   1015   @param  Ohc                   UHC private data
   1016 
   1017   @retval                       Value of Ls Threshold reg
   1018 
   1019 **/
   1020 
   1021 UINT32
   1022 OhciGetLsThreshold (
   1023   IN USB_OHCI_HC_DEV      *Ohc
   1024   )
   1025 {
   1026   return OhciGetOperationalReg(Ohc->PciIo, HC_LS_THREASHOLD);
   1027 }
   1028 
   1029 /**
   1030 
   1031   Set Root Hub Descriptor reg value
   1032 
   1033   @param  Ohc                   UHC private data
   1034   @param  Field                 Field to set
   1035   @param  Value                 Value to set
   1036 
   1037   @retval  EFI_SUCCESS          Value set
   1038 
   1039 **/
   1040 EFI_STATUS
   1041 OhciSetRootHubDescriptor (
   1042   IN USB_OHCI_HC_DEV      *Ohc,
   1043   IN UINTN                Field,
   1044   IN UINT32               Value
   1045   )
   1046 {
   1047   EFI_STATUS              Status;
   1048   HcRH_DESC_A             DescriptorA;
   1049   HcRH_DESC_B             DescriptorB;
   1050 
   1051 
   1052   if (Field & (RH_DEV_REMOVABLE | RH_PORT_PWR_CTRL_MASK)) {
   1053     *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_B);
   1054 
   1055     if(Field & RH_DEV_REMOVABLE) {
   1056       DescriptorB.DeviceRemovable = Value;
   1057     }
   1058     if(Field & RH_PORT_PWR_CTRL_MASK) {
   1059       DescriptorB.PortPowerControlMask = Value;
   1060     }
   1061 
   1062     Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_DESC_B, &DescriptorB);
   1063 
   1064     return Status;
   1065   }
   1066 
   1067   *(UINT32 *)&DescriptorA = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_A);
   1068 
   1069   if(Field & RH_NUM_DS_PORTS) {
   1070     DescriptorA.NumDownStrmPorts = Value;
   1071   }
   1072   if(Field & RH_NO_PSWITCH) {
   1073     DescriptorA.NoPowerSwitch = Value;
   1074   }
   1075   if(Field & RH_PSWITCH_MODE) {
   1076     DescriptorA.PowerSwitchMode = Value;
   1077   }
   1078   if(Field & RH_DEVICE_TYPE) {
   1079     DescriptorA.DeviceType = Value;
   1080   }
   1081   if(Field & RH_OC_PROT_MODE) {
   1082     DescriptorA.OverCurrentProtMode = Value;
   1083   }
   1084   if(Field & RH_NOC_PROT) {
   1085     DescriptorA.NoOverCurrentProtMode = Value;
   1086   }
   1087   if(Field & RH_NO_POTPGT) {
   1088     DescriptorA.PowerOnToPowerGoodTime = Value;
   1089   }
   1090 
   1091   Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_DESC_A, &DescriptorA);
   1092 
   1093   return Status;
   1094 }
   1095 
   1096 
   1097 /**
   1098 
   1099   Get Root Hub Descriptor reg value
   1100 
   1101   @param  Ohc                   UHC private data
   1102   @param  Field                 Field to get
   1103 
   1104   @retval                       Value of the field
   1105 
   1106 **/
   1107 
   1108 UINT32
   1109 OhciGetRootHubDescriptor (
   1110   IN USB_OHCI_HC_DEV     *Ohc,
   1111   IN UINTN               Field
   1112   )
   1113 {
   1114   HcRH_DESC_A             DescriptorA;
   1115   HcRH_DESC_B             DescriptorB;
   1116 
   1117 
   1118   *(UINT32 *) &DescriptorA = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_A);
   1119   *(UINT32 *) &DescriptorB = OhciGetOperationalReg (Ohc->PciIo, HC_RH_DESC_B);
   1120 
   1121   switch (Field){
   1122     case RH_DEV_REMOVABLE:
   1123       return DescriptorB.DeviceRemovable;
   1124       break;
   1125 
   1126     case RH_PORT_PWR_CTRL_MASK:
   1127       return DescriptorB.PortPowerControlMask;
   1128       break;
   1129 
   1130     case RH_NUM_DS_PORTS:
   1131       return DescriptorA.NumDownStrmPorts;
   1132       break;
   1133 
   1134     case RH_NO_PSWITCH:
   1135       return DescriptorA.NoPowerSwitch;
   1136       break;
   1137 
   1138     case RH_PSWITCH_MODE:
   1139       return DescriptorA.PowerSwitchMode;
   1140       break;
   1141 
   1142     case RH_DEVICE_TYPE:
   1143       return DescriptorA.DeviceType;
   1144       break;
   1145 
   1146     case RH_OC_PROT_MODE:
   1147       return DescriptorA.OverCurrentProtMode;
   1148       break;
   1149 
   1150     case RH_NOC_PROT:
   1151       return DescriptorA.NoOverCurrentProtMode;
   1152       break;
   1153 
   1154     case RH_NO_POTPGT:
   1155       return DescriptorA.PowerOnToPowerGoodTime;
   1156       break;
   1157 
   1158     default:
   1159       ASSERT (FALSE);
   1160   }
   1161 
   1162   return 0;
   1163 }
   1164 
   1165 
   1166 /**
   1167 
   1168   Set Root Hub Status reg value
   1169 
   1170   @param  Ohc                   UHC private data
   1171   @param  Field                 Field to set
   1172 
   1173   @retval  EFI_SUCCESS          Value set
   1174 
   1175 **/
   1176 
   1177 EFI_STATUS
   1178 OhciSetRootHubStatus (
   1179   IN USB_OHCI_HC_DEV      *Ohc,
   1180   IN UINTN                Field
   1181   )
   1182 {
   1183   EFI_STATUS              Status;
   1184   HcRH_STATUS             RootHubStatus;
   1185 
   1186 
   1187   ZeroMem (&RootHubStatus, sizeof(HcRH_STATUS));
   1188 
   1189   if(Field & RH_LOCAL_PSTAT){
   1190     RootHubStatus.LocalPowerStat = 1;
   1191   }
   1192   if(Field & RH_OC_ID){
   1193     RootHubStatus.OverCurrentIndicator = 1;
   1194   }
   1195   if(Field & RH_REMOTE_WK_ENABLE){
   1196     RootHubStatus.DevRemoteWakeupEnable = 1;
   1197   }
   1198   if(Field & RH_LOCAL_PSTAT_CHANGE){
   1199     RootHubStatus.LocalPowerStatChange = 1;
   1200   }
   1201   if(Field & RH_OC_ID_CHANGE){
   1202     RootHubStatus.OverCurrentIndicatorChange = 1;
   1203   }
   1204   if(Field & RH_CLR_RMT_WK_ENABLE){
   1205     RootHubStatus.ClearRemoteWakeupEnable = 1;
   1206   }
   1207 
   1208   Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_STATUS, &RootHubStatus);
   1209 
   1210   return Status;
   1211 }
   1212 
   1213 
   1214 /**
   1215 
   1216   Get Root Hub Status reg value
   1217 
   1218   @param  Ohc                   UHC private data
   1219   @param  Field                 Field to get
   1220 
   1221   @retval                       Value of the field
   1222 
   1223 **/
   1224 
   1225 UINT32
   1226 OhciGetRootHubStatus (
   1227   IN USB_OHCI_HC_DEV      *Ohc,
   1228   IN UINTN                Field
   1229   )
   1230 {
   1231   HcRH_STATUS             RootHubStatus;
   1232 
   1233 
   1234   *(UINT32 *) &RootHubStatus = OhciGetOperationalReg (Ohc->PciIo, HC_RH_STATUS);
   1235 
   1236   switch (Field) {
   1237     case RH_LOCAL_PSTAT:
   1238       return RootHubStatus.LocalPowerStat;
   1239       break;
   1240     case RH_OC_ID:
   1241       return RootHubStatus.OverCurrentIndicator;
   1242       break;
   1243     case RH_REMOTE_WK_ENABLE:
   1244       return RootHubStatus.DevRemoteWakeupEnable;
   1245       break;
   1246     case RH_LOCAL_PSTAT_CHANGE:
   1247       return RootHubStatus.LocalPowerStatChange;
   1248       break;
   1249     case RH_OC_ID_CHANGE:
   1250       return RootHubStatus.OverCurrentIndicatorChange;
   1251       break;
   1252     case RH_CLR_RMT_WK_ENABLE:
   1253       return RootHubStatus.ClearRemoteWakeupEnable;
   1254       break;
   1255     default:
   1256       ASSERT (FALSE);
   1257   }
   1258 
   1259   return 0;
   1260 }
   1261 
   1262 
   1263 /**
   1264 
   1265   Set Root Hub Port Status reg value
   1266 
   1267   @param  Ohc                   UHC private data
   1268   @param  Index                 Index of the port
   1269   @param  Field                 Field to set
   1270 
   1271   @retval  EFI_SUCCESS          Value set
   1272 
   1273 **/
   1274 
   1275 EFI_STATUS
   1276 OhciSetRootHubPortStatus (
   1277   IN USB_OHCI_HC_DEV      *Ohc,
   1278   IN UINT32               Index,
   1279   IN UINTN                Field
   1280   )
   1281 {
   1282   EFI_STATUS              Status;
   1283   HcRHPORT_STATUS         PortStatus;
   1284 
   1285 
   1286   ZeroMem (&PortStatus, sizeof(HcRHPORT_STATUS));
   1287 
   1288   if (Field & RH_CLEAR_PORT_ENABLE) {
   1289     PortStatus.CurrentConnectStat = 1;
   1290   }
   1291   if (Field & RH_SET_PORT_ENABLE) {
   1292     PortStatus.EnableStat = 1;
   1293   }
   1294   if (Field & RH_SET_PORT_SUSPEND) {
   1295     PortStatus.SuspendStat = 1;
   1296   }
   1297   if (Field & RH_CLEAR_SUSPEND_STATUS) {
   1298     PortStatus.OCIndicator = 1;
   1299   }
   1300   if (Field & RH_SET_PORT_RESET) {
   1301     PortStatus.ResetStat = 1;
   1302   }
   1303   if (Field & RH_SET_PORT_POWER) {
   1304     PortStatus.PowerStat = 1;
   1305   }
   1306   if (Field & RH_CLEAR_PORT_POWER) {
   1307     PortStatus.LsDeviceAttached = 1;
   1308   }
   1309   if (Field & RH_CONNECT_STATUS_CHANGE) {
   1310     PortStatus.ConnectStatChange = 1;
   1311   }
   1312   if (Field & RH_PORT_ENABLE_STAT_CHANGE) {
   1313     PortStatus.EnableStatChange = 1;
   1314   }
   1315   if (Field & RH_PORT_SUSPEND_STAT_CHANGE) {
   1316     PortStatus.SuspendStatChange = 1;
   1317   }
   1318   if (Field & RH_OC_INDICATOR_CHANGE) {
   1319     PortStatus.OCIndicatorChange = 1;
   1320   }
   1321   if (Field & RH_PORT_RESET_STAT_CHANGE ) {
   1322     PortStatus.ResetStatChange = 1;
   1323   }
   1324 
   1325   Status = OhciSetOperationalReg (Ohc->PciIo, HC_RH_PORT_STATUS + (Index * 4), &PortStatus);
   1326 
   1327   return Status;
   1328 }
   1329 
   1330 
   1331 /**
   1332 
   1333   Get Root Hub Port Status reg value
   1334 
   1335   @param  Ohc                   UHC private data
   1336   @param  Index                 Index of the port
   1337   @param  Field                 Field to get
   1338 
   1339   @retval                       Value of the field and index
   1340 
   1341 **/
   1342 
   1343 UINT32
   1344 OhciReadRootHubPortStatus (
   1345   IN USB_OHCI_HC_DEV      *Ohc,
   1346   IN UINT32               Index,
   1347   IN UINTN                Field
   1348   )
   1349 {
   1350   HcRHPORT_STATUS         PortStatus;
   1351 
   1352   *(UINT32 *) &PortStatus = OhciGetOperationalReg (
   1353                               Ohc->PciIo,
   1354                               HC_RH_PORT_STATUS + (Index * 4)
   1355                               );
   1356 
   1357   switch (Field){
   1358   case RH_CURR_CONNECT_STAT:
   1359     return PortStatus.CurrentConnectStat;
   1360     break;
   1361   case RH_PORT_ENABLE_STAT:
   1362     return PortStatus.EnableStat;
   1363     break;
   1364   case RH_PORT_SUSPEND_STAT:
   1365     return PortStatus.SuspendStat;
   1366     break;
   1367   case RH_PORT_OC_INDICATOR:
   1368     return PortStatus.OCIndicator;
   1369     break;
   1370   case RH_PORT_RESET_STAT:
   1371     return PortStatus.ResetStat;
   1372     break;
   1373   case RH_PORT_POWER_STAT:
   1374     return PortStatus.PowerStat;
   1375     break;
   1376   case RH_LSDEVICE_ATTACHED:
   1377     return PortStatus.LsDeviceAttached;
   1378     break;
   1379   case RH_CONNECT_STATUS_CHANGE:
   1380     return PortStatus.ConnectStatChange;
   1381     break;
   1382   case RH_PORT_ENABLE_STAT_CHANGE:
   1383     return PortStatus.EnableStatChange;
   1384     break;
   1385   case RH_PORT_SUSPEND_STAT_CHANGE:
   1386     return PortStatus.SuspendStatChange;
   1387     break;
   1388   case RH_OC_INDICATOR_CHANGE:
   1389     return PortStatus.OCIndicatorChange;
   1390     break;
   1391   case RH_PORT_RESET_STAT_CHANGE:
   1392     return PortStatus.ResetStatChange;
   1393     break;
   1394   default:
   1395     ASSERT (FALSE);
   1396   }
   1397 
   1398   return 0;
   1399 }
   1400