• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
OhciGetOperationalReg(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT32 Offset)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
OhciSetOperationalReg(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT32 Offset,IN VOID * Value)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
OhciGetHcRevision(IN EFI_PCI_IO_PROTOCOL * PciIo)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
OhciSetHcReset(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Field,IN UINT32 Value)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
OhciGetHcReset(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Field)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
OhciSetHcControl(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field,IN UINT32 Value)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
OhciGetHcControl(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciSetHcCommandStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field,IN UINT32 Value)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
OhciGetHcCommandStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciClearInterruptStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciGetHcInterruptStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciSetInterruptControl(IN USB_OHCI_HC_DEV * Ohc,IN BOOLEAN StatEnable,IN UINTN Field,IN UINT32 Value)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
OhciGetHcInterruptControl(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciSetMemoryPointer(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 PointerType,IN VOID * Value)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 *
OhciGetMemoryPointer(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 PointerType)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
OhciSetFrameInterval(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field,IN UINT32 Value)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
OhciGetFrameInterval(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciSetFrameRemaining(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Value)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
OhciGetFrameRemaining(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciSetFrameNumber(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Value)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
OhciGetFrameNumber(IN USB_OHCI_HC_DEV * Ohc)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
OhciSetPeriodicStart(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Value)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
OhciGetPeriodicStart(IN USB_OHCI_HC_DEV * Ohc)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
OhciSetLsThreshold(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Value)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
OhciGetLsThreshold(IN USB_OHCI_HC_DEV * Ohc)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
OhciSetRootHubDescriptor(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field,IN UINT32 Value)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
OhciGetRootHubDescriptor(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciSetRootHubStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciGetRootHubStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINTN Field)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
OhciSetRootHubPortStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Index,IN UINTN Field)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
OhciReadRootHubPortStatus(IN USB_OHCI_HC_DEV * Ohc,IN UINT32 Index,IN UINTN Field)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