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