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