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