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