TianoCore EDK2 master
Loading...
Searching...
No Matches
Uhci.c
Go to the documentation of this file.
1
10#include "Uhci.h"
11
12EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = {
16 0x20,
17 NULL,
18 NULL
19};
20
35EFIAPI
38 IN UINT16 Attributes
39 )
40{
41 USB_HC_DEV *Uhc;
42 EFI_TPL OldTpl;
43
44 if ((Attributes == EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG) ||
45 (Attributes == EFI_USB_HC_RESET_HOST_WITH_DEBUG))
46 {
47 return EFI_UNSUPPORTED;
48 }
49
50 Uhc = UHC_FROM_USB2_HC_PROTO (This);
51
52 if (Uhc->DevicePath != NULL) {
53 //
54 // Report Status Code to indicate reset happens
55 //
58 (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),
59 Uhc->DevicePath
60 );
61 }
62
63 OldTpl = gBS->RaiseTPL (UHCI_TPL);
64
65 switch (Attributes) {
66 case EFI_USB_HC_RESET_GLOBAL:
67 //
68 // Stop schedule and set the Global Reset bit in the command register
69 //
70 UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
71 UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);
72
73 gBS->Stall (UHC_ROOT_PORT_RESET_STALL);
74
75 //
76 // Clear the Global Reset bit to zero.
77 //
78 UhciClearRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);
79
80 gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);
81 break;
82
83 case EFI_USB_HC_RESET_HOST_CONTROLLER:
84 //
85 // Stop schedule and set Host Controller Reset bit to 1
86 //
87 UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
88 UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);
89
90 gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);
91 break;
92
93 default:
94 goto ON_INVAILD_PARAMETER;
95 }
96
97 //
98 // Delete all old transactions on the USB bus, then
99 // reinitialize the frame list
100 //
103 UhciInitFrameList (Uhc);
104
105 gBS->RestoreTPL (OldTpl);
106
107 return EFI_SUCCESS;
108
109ON_INVAILD_PARAMETER:
110
111 gBS->RestoreTPL (OldTpl);
112
113 return EFI_INVALID_PARAMETER;
114}
115
128EFIAPI
131 OUT EFI_USB_HC_STATE *State
132 )
133{
134 USB_HC_DEV *Uhc;
135 UINT16 UsbSts;
136 UINT16 UsbCmd;
137
138 if (State == NULL) {
139 return EFI_INVALID_PARAMETER;
140 }
141
142 Uhc = UHC_FROM_USB2_HC_PROTO (This);
143
144 UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);
145 UsbSts = UhciReadReg (Uhc->PciIo, USBSTS_OFFSET);
146
147 if ((UsbCmd & USBCMD_EGSM) != 0 ) {
148 *State = EfiUsbHcStateSuspend;
149 } else if ((UsbSts & USBSTS_HCH) != 0) {
150 *State = EfiUsbHcStateHalt;
151 } else {
153 }
154
155 return EFI_SUCCESS;
156}
157
171EFIAPI
174 IN EFI_USB_HC_STATE State
175 )
176{
177 EFI_USB_HC_STATE CurState;
178 USB_HC_DEV *Uhc;
179 EFI_TPL OldTpl;
180 EFI_STATUS Status;
181 UINT16 UsbCmd;
182
183 Uhc = UHC_FROM_USB2_HC_PROTO (This);
184 Status = Uhci2GetState (This, &CurState);
185
186 if (EFI_ERROR (Status)) {
187 return EFI_DEVICE_ERROR;
188 }
189
190 if (CurState == State) {
191 return EFI_SUCCESS;
192 }
193
194 Status = EFI_SUCCESS;
195 OldTpl = gBS->RaiseTPL (UHCI_TPL);
196
197 switch (State) {
199 Status = UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
200 break;
201
203 UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);
204
205 if (CurState == EfiUsbHcStateHalt) {
206 //
207 // Set Run/Stop bit to 1, also set the bandwidht reclamation
208 // point to 64 bytes
209 //
210 UsbCmd |= USBCMD_RS | USBCMD_MAXP;
211 UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
212 } else if (CurState == EfiUsbHcStateSuspend) {
213 //
214 // If FGR(Force Global Resume) bit is 0, set it
215 //
216 if ((UsbCmd & USBCMD_FGR) == 0) {
217 UsbCmd |= USBCMD_FGR;
218 UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
219 }
220
221 //
222 // wait 20ms to let resume complete (20ms is specified by UHCI spec)
223 //
224 gBS->Stall (UHC_FORCE_GLOBAL_RESUME_STALL);
225
226 //
227 // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
228 //
229 UsbCmd &= ~USBCMD_FGR;
230 UsbCmd &= ~USBCMD_EGSM;
231 UsbCmd |= USBCMD_RS;
232 UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
233 }
234
235 break;
236
238 Status = Uhci2SetState (This, EfiUsbHcStateHalt);
239
240 if (EFI_ERROR (Status)) {
241 Status = EFI_DEVICE_ERROR;
242 goto ON_EXIT;
243 }
244
245 //
246 // Set Enter Global Suspend Mode bit to 1.
247 //
248 UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);
249 UsbCmd |= USBCMD_EGSM;
250 UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
251 break;
252
253 default:
254 Status = EFI_INVALID_PARAMETER;
255 break;
256 }
257
258ON_EXIT:
259 gBS->RestoreTPL (OldTpl);
260 return Status;
261}
262
279EFIAPI
282 OUT UINT8 *MaxSpeed,
283 OUT UINT8 *PortNumber,
284 OUT UINT8 *Is64BitCapable
285 )
286{
287 USB_HC_DEV *Uhc;
288 UINT32 Offset;
289 UINT16 PortSC;
290 UINT32 Index;
291
292 Uhc = UHC_FROM_USB2_HC_PROTO (This);
293
294 if ((NULL == MaxSpeed) || (NULL == PortNumber) || (NULL == Is64BitCapable)) {
295 return EFI_INVALID_PARAMETER;
296 }
297
298 *MaxSpeed = EFI_USB_SPEED_FULL;
299 *Is64BitCapable = (UINT8)FALSE;
300
301 *PortNumber = 0;
302
303 for (Index = 0; Index < USB_MAX_ROOTHUB_PORT; Index++) {
304 Offset = USBPORTSC_OFFSET + Index * 2;
305 PortSC = UhciReadReg (Uhc->PciIo, Offset);
306
307 //
308 // Port status's bit 7 is reserved and always returns 1 if
309 // the port number is valid. Intel's UHCI (in EHCI controller)
310 // returns 0 in this bit if port number is invalid. Also, if
311 // PciIo IoRead returns error, 0xFFFF is returned to caller.
312 //
313 if (((PortSC & 0x80) == 0) || (PortSC == 0xFFFF)) {
314 break;
315 }
316
317 (*PortNumber)++;
318 }
319
320 Uhc->RootPorts = *PortNumber;
321
322 DEBUG ((DEBUG_INFO, "Uhci2GetCapability: %d ports\n", (UINT32)Uhc->RootPorts));
323 return EFI_SUCCESS;
324}
325
340EFIAPI
343 IN UINT8 PortNumber,
344 OUT EFI_USB_PORT_STATUS *PortStatus
345 )
346{
347 USB_HC_DEV *Uhc;
348 UINT32 Offset;
349 UINT16 PortSC;
350
351 Uhc = UHC_FROM_USB2_HC_PROTO (This);
352
353 if (PortStatus == NULL) {
354 return EFI_INVALID_PARAMETER;
355 }
356
357 if (PortNumber >= Uhc->RootPorts) {
358 return EFI_INVALID_PARAMETER;
359 }
360
361 Offset = USBPORTSC_OFFSET + PortNumber * 2;
362 PortStatus->PortStatus = 0;
363 PortStatus->PortChangeStatus = 0;
364
365 PortSC = UhciReadReg (Uhc->PciIo, Offset);
366
367 if ((PortSC & USBPORTSC_CCS) != 0) {
368 PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
369 }
370
371 if ((PortSC & USBPORTSC_PED) != 0) {
372 PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
373 }
374
375 if ((PortSC & USBPORTSC_SUSP) != 0) {
376 DEBUG ((DEBUG_INFO, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber));
377 PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
378 }
379
380 if ((PortSC & USBPORTSC_PR) != 0) {
381 PortStatus->PortStatus |= USB_PORT_STAT_RESET;
382 }
383
384 if ((PortSC & USBPORTSC_LSDA) != 0) {
385 PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
386 }
387
388 //
389 // CHC will always return one in port owner bit
390 //
391 PortStatus->PortStatus |= USB_PORT_STAT_OWNER;
392
393 if ((PortSC & USBPORTSC_CSC) != 0) {
394 PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
395 }
396
397 if ((PortSC & USBPORTSC_PEDC) != 0) {
398 PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
399 }
400
401 return EFI_SUCCESS;
402}
403
419EFIAPI
422 IN UINT8 PortNumber,
423 IN EFI_USB_PORT_FEATURE PortFeature
424 )
425{
426 USB_HC_DEV *Uhc;
427 EFI_TPL OldTpl;
428 UINT32 Offset;
429 UINT16 PortSC;
430 UINT16 Command;
431
432 Uhc = UHC_FROM_USB2_HC_PROTO (This);
433
434 if (PortNumber >= Uhc->RootPorts) {
435 return EFI_INVALID_PARAMETER;
436 }
437
438 Offset = USBPORTSC_OFFSET + PortNumber * 2;
439
440 OldTpl = gBS->RaiseTPL (UHCI_TPL);
441 PortSC = UhciReadReg (Uhc->PciIo, Offset);
442
443 switch (PortFeature) {
444 case EfiUsbPortSuspend:
445 Command = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);
446 if ((Command & USBCMD_EGSM) == 0) {
447 //
448 // if global suspend is not active, can set port suspend
449 //
450 PortSC &= 0xfff5;
451 PortSC |= USBPORTSC_SUSP;
452 }
453
454 break;
455
456 case EfiUsbPortReset:
457 PortSC &= 0xfff5;
458 PortSC |= USBPORTSC_PR;
459 break;
460
461 case EfiUsbPortPower:
462 //
463 // No action
464 //
465 break;
466
467 case EfiUsbPortEnable:
468 PortSC &= 0xfff5;
469 PortSC |= USBPORTSC_PED;
470 break;
471
472 default:
473 gBS->RestoreTPL (OldTpl);
474 return EFI_INVALID_PARAMETER;
475 }
476
477 UhciWriteReg (Uhc->PciIo, Offset, PortSC);
478 gBS->RestoreTPL (OldTpl);
479
480 return EFI_SUCCESS;
481}
482
498EFIAPI
501 IN UINT8 PortNumber,
502 IN EFI_USB_PORT_FEATURE PortFeature
503 )
504{
505 USB_HC_DEV *Uhc;
506 EFI_TPL OldTpl;
507 UINT32 Offset;
508 UINT16 PortSC;
509
510 Uhc = UHC_FROM_USB2_HC_PROTO (This);
511
512 if (PortNumber >= Uhc->RootPorts) {
513 return EFI_INVALID_PARAMETER;
514 }
515
516 Offset = USBPORTSC_OFFSET + PortNumber * 2;
517
518 OldTpl = gBS->RaiseTPL (UHCI_TPL);
519 PortSC = UhciReadReg (Uhc->PciIo, Offset);
520
521 switch (PortFeature) {
522 case EfiUsbPortEnable:
523 PortSC &= 0xfff5;
524 PortSC &= ~USBPORTSC_PED;
525 break;
526
527 case EfiUsbPortSuspend:
528 //
529 // Cause a resume on the specified port if in suspend mode.
530 //
531 PortSC &= 0xfff5;
532 PortSC &= ~USBPORTSC_SUSP;
533 break;
534
535 case EfiUsbPortPower:
536 //
537 // No action
538 //
539 break;
540
541 case EfiUsbPortReset:
542 PortSC &= 0xfff5;
543 PortSC &= ~USBPORTSC_PR;
544 break;
545
546 case EfiUsbPortConnectChange:
547 PortSC &= 0xfff5;
548 PortSC |= USBPORTSC_CSC;
549 break;
550
551 case EfiUsbPortEnableChange:
552 PortSC &= 0xfff5;
553 PortSC |= USBPORTSC_PEDC;
554 break;
555
556 case EfiUsbPortSuspendChange:
557 //
558 // Root hub does not support this
559 //
560 break;
561
562 case EfiUsbPortOverCurrentChange:
563 //
564 // Root hub does not support this
565 //
566 break;
567
568 case EfiUsbPortResetChange:
569 //
570 // Root hub does not support this
571 //
572 break;
573
574 default:
575 gBS->RestoreTPL (OldTpl);
576 return EFI_INVALID_PARAMETER;
577 }
578
579 UhciWriteReg (Uhc->PciIo, Offset, PortSC);
580 gBS->RestoreTPL (OldTpl);
581
582 return EFI_SUCCESS;
583}
584
608EFIAPI
611 IN UINT8 DeviceAddress,
612 IN UINT8 DeviceSpeed,
613 IN UINTN MaximumPacketLength,
614 IN EFI_USB_DEVICE_REQUEST *Request,
615 IN EFI_USB_DATA_DIRECTION TransferDirection,
616 IN OUT VOID *Data,
617 IN OUT UINTN *DataLength,
618 IN UINTN TimeOut,
620 OUT UINT32 *TransferResult
621 )
622{
623 USB_HC_DEV *Uhc;
624 UHCI_TD_SW *TDs;
625 EFI_TPL OldTpl;
626 EFI_STATUS Status;
627 UHCI_QH_RESULT QhResult;
628 UINT8 PktId;
629 UINT8 *RequestPhy;
630 VOID *RequestMap;
631 UINT8 *DataPhy;
632 VOID *DataMap;
633 BOOLEAN IsSlowDevice;
634 UINTN TransferDataLength;
635
636 Uhc = UHC_FROM_USB2_HC_PROTO (This);
637 TDs = NULL;
638 DataPhy = NULL;
639 DataMap = NULL;
640 RequestPhy = NULL;
641 RequestMap = NULL;
642
643 IsSlowDevice = (BOOLEAN)((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
644
645 //
646 // Parameters Checking
647 //
648 if ((Request == NULL) || (TransferResult == NULL)) {
649 return EFI_INVALID_PARAMETER;
650 }
651
652 if (IsSlowDevice && (MaximumPacketLength != 8)) {
653 return EFI_INVALID_PARAMETER;
654 }
655
656 if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) &&
657 (MaximumPacketLength != 32) && (MaximumPacketLength != 64))
658 {
659 return EFI_INVALID_PARAMETER;
660 }
661
662 if ((TransferDirection != EfiUsbNoData) && ((Data == NULL) || (DataLength == NULL))) {
663 return EFI_INVALID_PARAMETER;
664 }
665
666 if (TransferDirection == EfiUsbNoData) {
667 TransferDataLength = 0;
668 } else {
669 TransferDataLength = *DataLength;
670 }
671
672 *TransferResult = EFI_USB_ERR_SYSTEM;
673 Status = EFI_DEVICE_ERROR;
674
675 //
676 // If errors exist that cause host controller halt,
677 // clear status then return EFI_DEVICE_ERROR.
678 //
680
681 if (!UhciIsHcWorking (Uhc->PciIo)) {
682 return EFI_DEVICE_ERROR;
683 }
684
685 OldTpl = gBS->RaiseTPL (UHCI_TPL);
686
687 //
688 // Map the Request and data for bus master access,
689 // then create a list of TD for this transfer
690 //
691 Status = UhciMapUserRequest (Uhc, Request, &RequestPhy, &RequestMap);
692
693 if (EFI_ERROR (Status)) {
694 goto ON_EXIT;
695 }
696
697 Status = UhciMapUserData (Uhc, TransferDirection, Data, DataLength, &PktId, &DataPhy, &DataMap);
698
699 if (EFI_ERROR (Status)) {
700 Uhc->PciIo->Unmap (Uhc->PciIo, RequestMap);
701 goto ON_EXIT;
702 }
703
704 TDs = UhciCreateCtrlTds (
705 Uhc,
706 DeviceAddress,
707 PktId,
708 (UINT8 *)Request,
709 RequestPhy,
710 (UINT8 *)Data,
711 DataPhy,
712 TransferDataLength,
713 (UINT8)MaximumPacketLength,
714 IsSlowDevice
715 );
716
717 if (TDs == NULL) {
718 Status = EFI_OUT_OF_RESOURCES;
719 goto UNMAP_DATA;
720 }
721
722 //
723 // According to the speed of the end point, link
724 // the TD to corrosponding queue head, then check
725 // the execution result
726 //
727 UhciLinkTdToQh (Uhc, Uhc->CtrlQh, TDs);
728 Status = UhciExecuteTransfer (Uhc, Uhc->CtrlQh, TDs, TimeOut, IsSlowDevice, &QhResult);
729 UhciUnlinkTdFromQh (Uhc->CtrlQh, TDs);
730
731 Uhc->PciIo->Flush (Uhc->PciIo);
732
733 if (!EFI_ERROR (Status)) {
734 *TransferResult = QhResult.Result;
735
736 if (DataLength != NULL) {
737 *DataLength = QhResult.Complete;
738 }
739 }
740
741 UhciDestoryTds (Uhc, TDs);
742
743UNMAP_DATA:
744 Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);
745 Uhc->PciIo->Unmap (Uhc->PciIo, RequestMap);
746
747ON_EXIT:
748 gBS->RestoreTPL (OldTpl);
749 return Status;
750}
751
777EFIAPI
780 IN UINT8 DeviceAddress,
781 IN UINT8 EndPointAddress,
782 IN UINT8 DeviceSpeed,
783 IN UINTN MaximumPacketLength,
784 IN UINT8 DataBuffersNumber,
785 IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
786 IN OUT UINTN *DataLength,
787 IN OUT UINT8 *DataToggle,
788 IN UINTN TimeOut,
790 OUT UINT32 *TransferResult
791 )
792{
793 EFI_USB_DATA_DIRECTION Direction;
794 EFI_TPL OldTpl;
795 USB_HC_DEV *Uhc;
796 UHCI_TD_SW *TDs;
797 UHCI_QH_SW *BulkQh;
798 UHCI_QH_RESULT QhResult;
799 EFI_STATUS Status;
800 UINT8 PktId;
801 UINT8 *DataPhy;
802 VOID *DataMap;
803
804 Uhc = UHC_FROM_USB2_HC_PROTO (This);
805 DataPhy = NULL;
806 DataMap = NULL;
807
808 if (DeviceSpeed == EFI_USB_SPEED_LOW) {
809 return EFI_INVALID_PARAMETER;
810 }
811
812 if ((DataLength == NULL) || (*DataLength == 0) || (Data == NULL) || (TransferResult == NULL)) {
813 return EFI_INVALID_PARAMETER;
814 }
815
816 if ((*DataToggle != 1) && (*DataToggle != 0)) {
817 return EFI_INVALID_PARAMETER;
818 }
819
820 if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) &&
821 (MaximumPacketLength != 32) && (MaximumPacketLength != 64))
822 {
823 return EFI_INVALID_PARAMETER;
824 }
825
826 *TransferResult = EFI_USB_ERR_SYSTEM;
827 Status = EFI_OUT_OF_RESOURCES;
828
829 //
830 // If has errors that cause host controller halt,
831 // then return EFI_DEVICE_ERROR directly.
832 //
834
835 if (!UhciIsHcWorking (Uhc->PciIo)) {
836 return EFI_DEVICE_ERROR;
837 }
838
839 OldTpl = gBS->RaiseTPL (UHCI_TPL);
840
841 //
842 // Map the source data buffer for bus master access,
843 // then create a list of TDs
844 //
845 if ((EndPointAddress & 0x80) != 0) {
846 Direction = EfiUsbDataIn;
847 } else {
848 Direction = EfiUsbDataOut;
849 }
850
851 Status = UhciMapUserData (Uhc, Direction, *Data, DataLength, &PktId, &DataPhy, &DataMap);
852
853 if (EFI_ERROR (Status)) {
854 goto ON_EXIT;
855 }
856
857 Status = EFI_OUT_OF_RESOURCES;
859 Uhc,
860 DeviceAddress,
861 EndPointAddress,
862 PktId,
863 (UINT8 *)*Data,
864 DataPhy,
865 *DataLength,
866 DataToggle,
867 (UINT8)MaximumPacketLength,
868 FALSE
869 );
870
871 if (TDs == NULL) {
872 Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);
873 goto ON_EXIT;
874 }
875
876 //
877 // Link the TDs to bulk queue head. According to the platfore
878 // definition of UHCI_NO_BW_RECLAMATION, BulkQh is either configured
879 // to do full speed bandwidth reclamation or not.
880 //
881 BulkQh = Uhc->BulkQh;
882
883 UhciLinkTdToQh (Uhc, BulkQh, TDs);
884 Status = UhciExecuteTransfer (Uhc, BulkQh, TDs, TimeOut, FALSE, &QhResult);
885 UhciUnlinkTdFromQh (BulkQh, TDs);
886
887 Uhc->PciIo->Flush (Uhc->PciIo);
888
889 if (!EFI_ERROR (Status)) {
890 *TransferResult = QhResult.Result;
891 *DataToggle = QhResult.NextToggle;
892 *DataLength = QhResult.Complete;
893 }
894
895 UhciDestoryTds (Uhc, TDs);
896 Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);
897
898ON_EXIT:
899 gBS->RestoreTPL (OldTpl);
900 return Status;
901}
902
928EFIAPI
931 IN UINT8 DeviceAddress,
932 IN UINT8 EndPointAddress,
933 IN UINT8 DeviceSpeed,
934 IN UINTN MaximumPacketLength,
935 IN BOOLEAN IsNewTransfer,
936 IN OUT UINT8 *DataToggle,
937 IN UINTN PollingInterval,
938 IN UINTN DataLength,
940 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
941 IN VOID *Context
942 )
943{
944 USB_HC_DEV *Uhc;
945 BOOLEAN IsSlowDevice;
946 UHCI_QH_SW *Qh;
947 UHCI_TD_SW *IntTds;
948 EFI_TPL OldTpl;
949 EFI_STATUS Status;
950 UINT8 *DataPtr;
951 UINT8 *DataPhy;
952 UINT8 PktId;
953
954 Uhc = UHC_FROM_USB2_HC_PROTO (This);
955 Qh = NULL;
956 IntTds = NULL;
957 DataPtr = NULL;
958 DataPhy = NULL;
959
960 IsSlowDevice = (BOOLEAN)((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
961
962 if ((EndPointAddress & 0x80) == 0) {
963 return EFI_INVALID_PARAMETER;
964 }
965
966 //
967 // Delete Async interrupt transfer request
968 //
969 if (!IsNewTransfer) {
970 OldTpl = gBS->RaiseTPL (UHCI_TPL);
971 Status = UhciRemoveAsyncReq (Uhc, DeviceAddress, EndPointAddress, DataToggle);
972
973 gBS->RestoreTPL (OldTpl);
974 return Status;
975 }
976
977 if ((PollingInterval < 1) || (PollingInterval > 255)) {
978 return EFI_INVALID_PARAMETER;
979 }
980
981 if (DataLength == 0) {
982 return EFI_INVALID_PARAMETER;
983 }
984
985 if ((*DataToggle != 1) && (*DataToggle != 0)) {
986 return EFI_INVALID_PARAMETER;
987 }
988
989 //
990 // If has errors that cause host controller halt,
991 // then return EFI_DEVICE_ERROR directly.
992 //
994
995 if (!UhciIsHcWorking (Uhc->PciIo)) {
996 return EFI_DEVICE_ERROR;
997 }
998
999 if ((EndPointAddress & 0x80) == 0) {
1000 PktId = OUTPUT_PACKET_ID;
1001 } else {
1002 PktId = INPUT_PACKET_ID;
1003 }
1004
1005 //
1006 // Allocate and map source data buffer for bus master access.
1007 //
1008 DataPtr = UsbHcAllocateMem (Uhc->MemPool, DataLength);
1009
1010 if (DataPtr == NULL) {
1011 return EFI_OUT_OF_RESOURCES;
1012 }
1013
1014 DataPhy = (UINT8 *)(UINTN)UsbHcGetPciAddressForHostMem (Uhc->MemPool, DataPtr, DataLength);
1015
1016 OldTpl = gBS->RaiseTPL (UHCI_TPL);
1017
1018 Qh = UhciCreateQh (Uhc, PollingInterval);
1019
1020 if (Qh == NULL) {
1021 Status = EFI_OUT_OF_RESOURCES;
1022 goto FREE_DATA;
1023 }
1024
1025 IntTds = UhciCreateBulkOrIntTds (
1026 Uhc,
1027 DeviceAddress,
1028 EndPointAddress,
1029 PktId,
1030 DataPtr,
1031 DataPhy,
1032 DataLength,
1033 DataToggle,
1034 (UINT8)MaximumPacketLength,
1035 IsSlowDevice
1036 );
1037
1038 if (IntTds == NULL) {
1039 Status = EFI_OUT_OF_RESOURCES;
1040 goto DESTORY_QH;
1041 }
1042
1043 UhciLinkTdToQh (Uhc, Qh, IntTds);
1044
1045 //
1046 // Save QH-TD structures to async Interrupt transfer list,
1047 // for monitor interrupt transfer execution routine use.
1048 //
1049 Status = UhciCreateAsyncReq (
1050 Uhc,
1051 Qh,
1052 IntTds,
1053 DeviceAddress,
1054 EndPointAddress,
1055 DataLength,
1056 PollingInterval,
1057 DataPtr,
1058 CallBackFunction,
1059 Context,
1060 IsSlowDevice
1061 );
1062
1063 if (EFI_ERROR (Status)) {
1064 goto DESTORY_QH;
1065 }
1066
1067 UhciLinkQhToFrameList (Uhc, Qh);
1068
1069 gBS->RestoreTPL (OldTpl);
1070 return EFI_SUCCESS;
1071
1072DESTORY_QH:
1073 UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW));
1074
1075FREE_DATA:
1076 UsbHcFreeMem (Uhc->MemPool, DataPtr, DataLength);
1077 Uhc->PciIo->Flush (Uhc->PciIo);
1078
1079 gBS->RestoreTPL (OldTpl);
1080 return Status;
1081}
1082
1109EFIAPI
1112 IN UINT8 DeviceAddress,
1113 IN UINT8 EndPointAddress,
1114 IN UINT8 DeviceSpeed,
1115 IN UINTN MaximumPacketLength,
1116 IN OUT VOID *Data,
1117 IN OUT UINTN *DataLength,
1118 IN OUT UINT8 *DataToggle,
1119 IN UINTN TimeOut,
1121 OUT UINT32 *TransferResult
1122 )
1123{
1124 EFI_STATUS Status;
1125 USB_HC_DEV *Uhc;
1126 UHCI_TD_SW *TDs;
1127 UHCI_QH_RESULT QhResult;
1128 EFI_TPL OldTpl;
1129 UINT8 *DataPhy;
1130 VOID *DataMap;
1131 UINT8 PktId;
1132 BOOLEAN IsSlowDevice;
1133
1134 Uhc = UHC_FROM_USB2_HC_PROTO (This);
1135 DataPhy = NULL;
1136 DataMap = NULL;
1137 TDs = NULL;
1138
1139 if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
1140 return EFI_INVALID_PARAMETER;
1141 }
1142
1143 IsSlowDevice = (BOOLEAN)((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
1144
1145 if ((DataLength == NULL) || (Data == NULL) || (TransferResult == NULL)) {
1146 return EFI_INVALID_PARAMETER;
1147 }
1148
1149 if ((*DataToggle != 1) && (*DataToggle != 0)) {
1150 return EFI_INVALID_PARAMETER;
1151 }
1152
1153 if ((*DataLength == 0) || (MaximumPacketLength > 64)) {
1154 return EFI_INVALID_PARAMETER;
1155 }
1156
1157 if (IsSlowDevice && (MaximumPacketLength > 8)) {
1158 return EFI_INVALID_PARAMETER;
1159 }
1160
1161 *TransferResult = EFI_USB_ERR_SYSTEM;
1162 Status = EFI_DEVICE_ERROR;
1163
1164 UhciAckAllInterrupt (Uhc);
1165
1166 if (!UhciIsHcWorking (Uhc->PciIo)) {
1167 return Status;
1168 }
1169
1170 OldTpl = gBS->RaiseTPL (UHCI_TPL);
1171
1172 //
1173 // Map the source data buffer for bus master access.
1174 // Create Tds list, then link it to the UHC's interrupt list
1175 //
1176 Status = UhciMapUserData (
1177 Uhc,
1178 EfiUsbDataIn,
1179 Data,
1180 DataLength,
1181 &PktId,
1182 &DataPhy,
1183 &DataMap
1184 );
1185
1186 if (EFI_ERROR (Status)) {
1187 goto ON_EXIT;
1188 }
1189
1191 Uhc,
1192 DeviceAddress,
1193 EndPointAddress,
1194 PktId,
1195 (UINT8 *)Data,
1196 DataPhy,
1197 *DataLength,
1198 DataToggle,
1199 (UINT8)MaximumPacketLength,
1200 IsSlowDevice
1201 );
1202
1203 if (TDs == NULL) {
1204 Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);
1205
1206 Status = EFI_OUT_OF_RESOURCES;
1207 goto ON_EXIT;
1208 }
1209
1210 UhciLinkTdToQh (Uhc, Uhc->SyncIntQh, TDs);
1211
1212 Status = UhciExecuteTransfer (Uhc, Uhc->SyncIntQh, TDs, TimeOut, IsSlowDevice, &QhResult);
1213
1214 UhciUnlinkTdFromQh (Uhc->SyncIntQh, TDs);
1215 Uhc->PciIo->Flush (Uhc->PciIo);
1216
1217 if (!EFI_ERROR (Status)) {
1218 *TransferResult = QhResult.Result;
1219 *DataToggle = QhResult.NextToggle;
1220 *DataLength = QhResult.Complete;
1221 }
1222
1223 UhciDestoryTds (Uhc, TDs);
1224 Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);
1225
1226ON_EXIT:
1227 gBS->RestoreTPL (OldTpl);
1228 return Status;
1229}
1230
1250EFIAPI
1253 IN UINT8 DeviceAddress,
1254 IN UINT8 EndPointAddress,
1255 IN UINT8 DeviceSpeed,
1256 IN UINTN MaximumPacketLength,
1257 IN UINT8 DataBuffersNumber,
1258 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
1259 IN UINTN DataLength,
1261 OUT UINT32 *TransferResult
1262 )
1263{
1264 return EFI_UNSUPPORTED;
1265}
1266
1287EFIAPI
1290 IN UINT8 DeviceAddress,
1291 IN UINT8 EndPointAddress,
1292 IN UINT8 DeviceSpeed,
1293 IN UINTN MaximumPacketLength,
1294 IN UINT8 DataBuffersNumber,
1295 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
1296 IN UINTN DataLength,
1298 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
1299 IN VOID *Context
1300 )
1301{
1302 return EFI_UNSUPPORTED;
1303}
1304
1316EFIAPI
1318 IN EFI_HANDLE ImageHandle,
1319 IN EFI_SYSTEM_TABLE *SystemTable
1320 )
1321{
1323 ImageHandle,
1324 SystemTable,
1325 &gUhciDriverBinding,
1326 ImageHandle,
1327 &gUhciComponentName,
1328 &gUhciComponentName2
1329 );
1330}
1331
1344EFIAPI
1347 IN EFI_HANDLE Controller,
1348 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1349 )
1350{
1351 EFI_STATUS OpenStatus;
1352 EFI_STATUS Status;
1353 EFI_PCI_IO_PROTOCOL *PciIo;
1354 USB_CLASSC UsbClassCReg;
1355
1356 //
1357 // Test whether there is PCI IO Protocol attached on the controller handle.
1358 //
1359 OpenStatus = gBS->OpenProtocol (
1360 Controller,
1361 &gEfiPciIoProtocolGuid,
1362 (VOID **)&PciIo,
1363 This->DriverBindingHandle,
1364 Controller,
1365 EFI_OPEN_PROTOCOL_BY_DRIVER
1366 );
1367
1368 if (EFI_ERROR (OpenStatus)) {
1369 return OpenStatus;
1370 }
1371
1372 Status = PciIo->Pci.Read (
1373 PciIo,
1374 EfiPciIoWidthUint8,
1375 PCI_CLASSCODE_OFFSET,
1376 sizeof (USB_CLASSC) / sizeof (UINT8),
1377 &UsbClassCReg
1378 );
1379
1380 if (EFI_ERROR (Status)) {
1381 Status = EFI_UNSUPPORTED;
1382 goto ON_EXIT;
1383 }
1384
1385 //
1386 // Test whether the controller belongs to UHCI type
1387 //
1388 if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
1389 (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
1390 (UsbClassCReg.ProgInterface != PCI_IF_UHCI)
1391 )
1392 {
1393 Status = EFI_UNSUPPORTED;
1394 }
1395
1396ON_EXIT:
1397 gBS->CloseProtocol (
1398 Controller,
1399 &gEfiPciIoProtocolGuid,
1400 This->DriverBindingHandle,
1401 Controller
1402 );
1403
1404 return Status;
1405}
1406
1417USB_HC_DEV *
1419 IN EFI_PCI_IO_PROTOCOL *PciIo,
1420 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1421 IN UINT64 OriginalPciAttributes
1422 )
1423{
1424 USB_HC_DEV *Uhc;
1425 EFI_STATUS Status;
1426
1427 Uhc = AllocateZeroPool (sizeof (USB_HC_DEV));
1428
1429 if (Uhc == NULL) {
1430 return NULL;
1431 }
1432
1433 //
1434 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1435 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1436 //
1437 Uhc->Signature = USB_HC_DEV_SIGNATURE;
1438 Uhc->Usb2Hc.GetCapability = Uhci2GetCapability;
1439 Uhc->Usb2Hc.Reset = Uhci2Reset;
1440 Uhc->Usb2Hc.GetState = Uhci2GetState;
1441 Uhc->Usb2Hc.SetState = Uhci2SetState;
1442 Uhc->Usb2Hc.ControlTransfer = Uhci2ControlTransfer;
1443 Uhc->Usb2Hc.BulkTransfer = Uhci2BulkTransfer;
1444 Uhc->Usb2Hc.AsyncInterruptTransfer = Uhci2AsyncInterruptTransfer;
1445 Uhc->Usb2Hc.SyncInterruptTransfer = Uhci2SyncInterruptTransfer;
1446 Uhc->Usb2Hc.IsochronousTransfer = Uhci2IsochronousTransfer;
1447 Uhc->Usb2Hc.AsyncIsochronousTransfer = Uhci2AsyncIsochronousTransfer;
1448 Uhc->Usb2Hc.GetRootHubPortStatus = Uhci2GetRootHubPortStatus;
1449 Uhc->Usb2Hc.SetRootHubPortFeature = Uhci2SetRootHubPortFeature;
1450 Uhc->Usb2Hc.ClearRootHubPortFeature = Uhci2ClearRootHubPortFeature;
1451 Uhc->Usb2Hc.MajorRevision = 0x1;
1452 Uhc->Usb2Hc.MinorRevision = 0x1;
1453
1454 Uhc->PciIo = PciIo;
1455 Uhc->DevicePath = DevicePath;
1456 Uhc->OriginalPciAttributes = OriginalPciAttributes;
1457 Uhc->MemPool = UsbHcInitMemPool (PciIo, TRUE, 0);
1458
1459 if (Uhc->MemPool == NULL) {
1460 Status = EFI_OUT_OF_RESOURCES;
1461 goto ON_ERROR;
1462 }
1463
1464 InitializeListHead (&Uhc->AsyncIntList);
1465
1466 Status = gBS->CreateEvent (
1467 EVT_TIMER | EVT_NOTIFY_SIGNAL,
1468 TPL_NOTIFY,
1470 Uhc,
1471 &Uhc->AsyncIntMonitor
1472 );
1473
1474 if (EFI_ERROR (Status)) {
1475 UsbHcFreeMemPool (Uhc->MemPool);
1476 goto ON_ERROR;
1477 }
1478
1479 return Uhc;
1480
1481ON_ERROR:
1482 FreePool (Uhc);
1483 return NULL;
1484}
1485
1492VOID
1494 IN USB_HC_DEV *Uhc
1495 )
1496{
1497 if (Uhc->AsyncIntMonitor != NULL) {
1498 gBS->CloseEvent (Uhc->AsyncIntMonitor);
1499 }
1500
1501 if (Uhc->ExitBootServiceEvent != NULL) {
1502 gBS->CloseEvent (Uhc->ExitBootServiceEvent);
1503 }
1504
1505 if (Uhc->MemPool != NULL) {
1506 UsbHcFreeMemPool (Uhc->MemPool);
1507 }
1508
1509 if (Uhc->CtrlNameTable != NULL) {
1510 FreeUnicodeStringTable (Uhc->CtrlNameTable);
1511 }
1512
1513 FreePool (Uhc);
1514}
1515
1523VOID
1525 IN EFI_HANDLE Controller,
1527 )
1528{
1529 USB_HC_DEV *Uhc;
1530 EFI_STATUS Status;
1531
1532 //
1533 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
1534 //
1535 Uhc = UHC_FROM_USB2_HC_PROTO (This);
1536
1537 Status = gBS->UninstallProtocolInterface (
1538 Controller,
1539 &gEfiUsb2HcProtocolGuid,
1540 &Uhc->Usb2Hc
1541 );
1542 if (EFI_ERROR (Status)) {
1543 return;
1544 }
1545
1546 UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
1547 UhciFreeAllAsyncReq (Uhc);
1549
1550 //
1551 // Restore original PCI attributes
1552 //
1553 Uhc->PciIo->Attributes (
1554 Uhc->PciIo,
1556 Uhc->OriginalPciAttributes,
1557 NULL
1558 );
1559
1560 UhciFreeDev (Uhc);
1561}
1562
1570VOID
1571EFIAPI
1573 EFI_EVENT Event,
1574 VOID *Context
1575 )
1576{
1577 USB_HC_DEV *Uhc;
1578
1579 Uhc = (USB_HC_DEV *)Context;
1580
1581 //
1582 // Stop the Host Controller
1583 //
1584 UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
1585
1586 //
1587 // Reset the Host Controller
1588 //
1589 UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);
1590 gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);
1591}
1592
1607EFIAPI
1610 IN EFI_HANDLE Controller,
1611 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1612 )
1613{
1614 EFI_STATUS Status;
1615 EFI_PCI_IO_PROTOCOL *PciIo;
1616 USB_HC_DEV *Uhc;
1617 UINT64 Supports;
1618 UINT64 OriginalPciAttributes;
1619 BOOLEAN PciAttributesSaved;
1620 EFI_DEVICE_PATH_PROTOCOL *HcDevicePath;
1621
1622 //
1623 // Open PCIIO, then enable the EHC device and turn off emulation
1624 //
1625 Uhc = NULL;
1626 Status = gBS->OpenProtocol (
1627 Controller,
1628 &gEfiPciIoProtocolGuid,
1629 (VOID **)&PciIo,
1630 This->DriverBindingHandle,
1631 Controller,
1632 EFI_OPEN_PROTOCOL_BY_DRIVER
1633 );
1634
1635 if (EFI_ERROR (Status)) {
1636 return Status;
1637 }
1638
1639 //
1640 // Open Device Path Protocol for on USB host controller
1641 //
1642 HcDevicePath = NULL;
1643 Status = gBS->OpenProtocol (
1644 Controller,
1645 &gEfiDevicePathProtocolGuid,
1646 (VOID **)&HcDevicePath,
1647 This->DriverBindingHandle,
1648 Controller,
1649 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1650 );
1651
1652 PciAttributesSaved = FALSE;
1653 //
1654 // Save original PCI attributes
1655 //
1656 Status = PciIo->Attributes (
1657 PciIo,
1659 0,
1660 &OriginalPciAttributes
1661 );
1662
1663 if (EFI_ERROR (Status)) {
1664 goto CLOSE_PCIIO;
1665 }
1666
1667 PciAttributesSaved = TRUE;
1668
1669 //
1670 // Robustnesss improvement such as for UoL
1671 // Default is not required.
1672 //
1673 if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {
1675 }
1676
1677 Status = PciIo->Attributes (
1678 PciIo,
1680 0,
1681 &Supports
1682 );
1683 if (!EFI_ERROR (Status)) {
1684 Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
1685 Status = PciIo->Attributes (
1686 PciIo,
1688 Supports,
1689 NULL
1690 );
1691 }
1692
1693 if (EFI_ERROR (Status)) {
1694 goto CLOSE_PCIIO;
1695 }
1696
1697 Uhc = UhciAllocateDev (PciIo, HcDevicePath, OriginalPciAttributes);
1698
1699 if (Uhc == NULL) {
1700 Status = EFI_OUT_OF_RESOURCES;
1701 goto CLOSE_PCIIO;
1702 }
1703
1704 //
1705 // Allocate and Init Host Controller's Frame List Entry
1706 //
1707 Status = UhciInitFrameList (Uhc);
1708
1709 if (EFI_ERROR (Status)) {
1710 Status = EFI_OUT_OF_RESOURCES;
1711 goto FREE_UHC;
1712 }
1713
1714 Status = gBS->SetTimer (
1715 Uhc->AsyncIntMonitor,
1717 UHC_ASYNC_POLL_INTERVAL
1718 );
1719
1720 if (EFI_ERROR (Status)) {
1721 goto FREE_UHC;
1722 }
1723
1724 //
1725 // Install USB2_HC_PROTOCOL
1726 //
1727 Status = gBS->InstallMultipleProtocolInterfaces (
1728 &Controller,
1729 &gEfiUsb2HcProtocolGuid,
1730 &Uhc->Usb2Hc,
1731 NULL
1732 );
1733
1734 if (EFI_ERROR (Status)) {
1735 goto FREE_UHC;
1736 }
1737
1738 //
1739 // Create event to stop the HC when exit boot service.
1740 //
1741 Status = gBS->CreateEventEx (
1742 EVT_NOTIFY_SIGNAL,
1743 TPL_NOTIFY,
1745 Uhc,
1746 &gEfiEventExitBootServicesGuid,
1747 &Uhc->ExitBootServiceEvent
1748 );
1749 if (EFI_ERROR (Status)) {
1750 goto UNINSTALL_USBHC;
1751 }
1752
1753 //
1754 // Install the component name protocol
1755 //
1756 Uhc->CtrlNameTable = NULL;
1757
1759 "eng",
1760 gUhciComponentName.SupportedLanguages,
1761 &Uhc->CtrlNameTable,
1762 L"Usb Universal Host Controller",
1763 TRUE
1764 );
1766 "en",
1767 gUhciComponentName2.SupportedLanguages,
1768 &Uhc->CtrlNameTable,
1769 L"Usb Universal Host Controller",
1770 FALSE
1771 );
1772
1773 //
1774 // Start the UHCI hardware, also set its reclamation point to 64 bytes
1775 //
1776 UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, USBCMD_RS | USBCMD_MAXP);
1777
1778 return EFI_SUCCESS;
1779
1780UNINSTALL_USBHC:
1781 gBS->UninstallMultipleProtocolInterfaces (
1782 Controller,
1783 &gEfiUsb2HcProtocolGuid,
1784 &Uhc->Usb2Hc,
1785 NULL
1786 );
1787
1788FREE_UHC:
1789 UhciFreeDev (Uhc);
1790
1791CLOSE_PCIIO:
1792 if (PciAttributesSaved) {
1793 //
1794 // Restore original PCI attributes
1795 //
1796 PciIo->Attributes (
1797 PciIo,
1799 OriginalPciAttributes,
1800 NULL
1801 );
1802 }
1803
1804 gBS->CloseProtocol (
1805 Controller,
1806 &gEfiPciIoProtocolGuid,
1807 This->DriverBindingHandle,
1808 Controller
1809 );
1810
1811 return Status;
1812}
1813
1828EFIAPI
1831 IN EFI_HANDLE Controller,
1832 IN UINTN NumberOfChildren,
1833 IN EFI_HANDLE *ChildHandleBuffer
1834 )
1835{
1836 EFI_USB2_HC_PROTOCOL *Usb2Hc;
1837 EFI_STATUS Status;
1838
1839 Status = gBS->OpenProtocol (
1840 Controller,
1841 &gEfiUsb2HcProtocolGuid,
1842 (VOID **)&Usb2Hc,
1843 This->DriverBindingHandle,
1844 Controller,
1845 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1846 );
1847
1848 //
1849 // Test whether the Controller handler passed in is a valid
1850 // Usb controller handle that should be supported, if not,
1851 // return the error status directly
1852 //
1853 if (EFI_ERROR (Status)) {
1854 return Status;
1855 }
1856
1857 UhciCleanDevUp (Controller, Usb2Hc);
1858
1859 gBS->CloseProtocol (
1860 Controller,
1861 &gEfiPciIoProtocolGuid,
1862 This->DriverBindingHandle,
1863 Controller
1864 );
1865
1866 return EFI_SUCCESS;
1867}
UINT64 UINTN
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
EFI_PHYSICAL_ADDRESS UsbHcGetPciAddressForHostMem(IN USBHC_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size)
Definition: UsbHcMem.c:223
EFI_STATUS UsbHcFreeMemPool(IN USBHC_MEM_POOL *Pool)
Definition: UsbHcMem.c:385
VOID UsbHcFreeMem(IN USBHC_MEM_POOL *Pool, IN VOID *Mem, IN UINTN Size)
Definition: UsbHcMem.c:493
VOID * UsbHcAllocateMem(IN USBHC_MEM_POOL *Pool, IN UINTN Size)
Definition: UsbHcMem.c:419
USBHC_MEM_POOL * UsbHcInitMemPool(IN EFI_PCI_IO_PROTOCOL *PciIo, IN BOOLEAN Check4G, IN UINT32 Which4G)
Definition: UsbHcMem.c:348
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define VOID
Definition: Base.h:269
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:435
#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type, Value, DevicePathParameter)
@ EfiPciIoAttributeOperationGet
Definition: PciIo.h:103
@ EfiPciIoAttributeOperationEnable
Definition: PciIo.h:111
@ EfiPciIoAttributeOperationSet
Definition: PciIo.h:107
@ EfiPciIoAttributeOperationSupported
Definition: PciIo.h:119
EFI_USB_PORT_FEATURE
#define USB_PORT_STAT_C_CONNECTION
EFI_USB_HC_STATE
@ EfiUsbHcStateHalt
@ EfiUsbHcStateOperational
@ EfiUsbHcStateSuspend
#define USB_PORT_STAT_CONNECTION
EFI_USB_DATA_DIRECTION
Definition: UsbIo.h:44
EFI_STATUS(EFIAPI * EFI_ASYNC_USB_TRANSFER_CALLBACK)(IN VOID *Data, IN UINTN DataLength, IN VOID *Context, IN UINT32 Status)
Definition: UsbIo.h:80
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:44
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI AddUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable, IN CONST CHAR16 *UnicodeString, IN BOOLEAN Iso639Language)
Definition: UefiLib.c:1083
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
Definition: UefiLib.c:1253
@ TimerPeriodic
Definition: UefiSpec.h:545
EFI_STATUS EFIAPI Uhci2BulkTransfer(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN UINT8 DataBuffersNumber, IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], IN OUT UINTN *DataLength, IN OUT UINT8 *DataToggle, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *TransferResult)
Definition: Uhci.c:778
EFI_STATUS EFIAPI UhciDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: Uhci.c:1608
EFI_STATUS EFIAPI Uhci2AsyncIsochronousTransfer(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN UINT8 DataBuffersNumber, IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], IN UINTN DataLength, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, IN VOID *Context)
Definition: Uhci.c:1288
EFI_STATUS EFIAPI Uhci2ClearRootHubPortFeature(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 PortNumber, IN EFI_USB_PORT_FEATURE PortFeature)
Definition: Uhci.c:499
VOID UhciFreeDev(IN USB_HC_DEV *Uhc)
Definition: Uhci.c:1493
EFI_STATUS EFIAPI Uhci2AsyncInterruptTransfer(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN BOOLEAN IsNewTransfer, IN OUT UINT8 *DataToggle, IN UINTN PollingInterval, IN UINTN DataLength, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction, IN VOID *Context)
Definition: Uhci.c:929
EFI_STATUS EFIAPI UhciDriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: Uhci.c:1317
EFI_STATUS EFIAPI Uhci2SyncInterruptTransfer(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN OUT UINT8 *DataToggle, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *TransferResult)
Definition: Uhci.c:1110
EFI_STATUS EFIAPI Uhci2SetState(IN EFI_USB2_HC_PROTOCOL *This, IN EFI_USB_HC_STATE State)
Definition: Uhci.c:172
EFI_STATUS EFIAPI UhciDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: Uhci.c:1829
EFI_STATUS EFIAPI UhciDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: Uhci.c:1345
EFI_STATUS EFIAPI Uhci2Reset(IN EFI_USB2_HC_PROTOCOL *This, IN UINT16 Attributes)
Definition: Uhci.c:36
USB_HC_DEV * UhciAllocateDev(IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN UINT64 OriginalPciAttributes)
Definition: Uhci.c:1418
EFI_STATUS EFIAPI Uhci2SetRootHubPortFeature(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 PortNumber, IN EFI_USB_PORT_FEATURE PortFeature)
Definition: Uhci.c:420
VOID EFIAPI UhcExitBootService(EFI_EVENT Event, VOID *Context)
Definition: Uhci.c:1572
EFI_STATUS EFIAPI Uhci2GetRootHubPortStatus(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 PortNumber, OUT EFI_USB_PORT_STATUS *PortStatus)
Definition: Uhci.c:341
VOID UhciCleanDevUp(IN EFI_HANDLE Controller, IN EFI_USB2_HC_PROTOCOL *This)
Definition: Uhci.c:1524
EFI_STATUS EFIAPI Uhci2IsochronousTransfer(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 EndPointAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN UINT8 DataBuffersNumber, IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], IN UINTN DataLength, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *TransferResult)
Definition: Uhci.c:1251
EFI_STATUS EFIAPI Uhci2GetCapability(IN EFI_USB2_HC_PROTOCOL *This, OUT UINT8 *MaxSpeed, OUT UINT8 *PortNumber, OUT UINT8 *Is64BitCapable)
Definition: Uhci.c:280
EFI_STATUS EFIAPI Uhci2GetState(IN EFI_USB2_HC_PROTOCOL *This, OUT EFI_USB_HC_STATE *State)
Definition: Uhci.c:129
EFI_STATUS EFIAPI Uhci2ControlTransfer(IN EFI_USB2_HC_PROTOCOL *This, IN UINT8 DeviceAddress, IN UINT8 DeviceSpeed, IN UINTN MaximumPacketLength, IN EFI_USB_DEVICE_REQUEST *Request, IN EFI_USB_DATA_DIRECTION TransferDirection, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *TransferResult)
Definition: Uhci.c:609
VOID UhciDestoryTds(IN USB_HC_DEV *Uhc, IN UHCI_TD_SW *FirstTd)
Definition: UhciQueue.c:222
EFI_STATUS UhciMapUserRequest(IN USB_HC_DEV *Uhc, IN OUT VOID *Request, OUT UINT8 **MappedAddr, OUT VOID **Map)
Definition: UhciQueue.c:25
VOID UhciLinkTdToQh(IN USB_HC_DEV *Uhc, IN UHCI_QH_SW *Qh, IN UHCI_TD_SW *Td)
Definition: UhciQueue.c:152
UHCI_QH_SW * UhciCreateQh(IN USB_HC_DEV *Uhc, IN UINTN Interval)
Definition: UhciQueue.c:249
EFI_STATUS UhciMapUserData(IN USB_HC_DEV *Uhc, IN EFI_USB_DATA_DIRECTION Direction, IN VOID *Data, IN OUT UINTN *Len, OUT UINT8 *PktId, OUT UINT8 **MappedAddr, OUT VOID **Map)
Definition: UhciQueue.c:69
UHCI_TD_SW * UhciCreateBulkOrIntTds(IN USB_HC_DEV *Uhc, IN UINT8 DevAddr, IN UINT8 EndPoint, IN UINT8 PktId, IN UINT8 *Data, IN UINT8 *DataPhy, IN UINTN DataLen, IN OUT UINT8 *DataToggle, IN UINT8 MaxPacket, IN BOOLEAN IsLow)
Definition: UhciQueue.c:610
UHCI_TD_SW * UhciCreateCtrlTds(IN USB_HC_DEV *Uhc, IN UINT8 DeviceAddr, IN UINT8 DataPktId, IN UINT8 *Request, IN UINT8 *RequestPhy, IN UINT8 *Data, IN UINT8 *DataPhy, IN UINTN DataLen, IN UINT8 MaxPacket, IN BOOLEAN IsLow)
Definition: UhciQueue.c:475
VOID UhciUnlinkTdFromQh(IN UHCI_QH_SW *Qh, IN UHCI_TD_SW *Td)
Definition: UhciQueue.c:176
BOOLEAN UhciIsHcWorking(IN EFI_PCI_IO_PROTOCOL *PciIo)
Definition: UhciReg.c:195
EFI_STATUS UhciStopHc(IN USB_HC_DEV *Uhc, IN UINTN Timeout)
Definition: UhciReg.c:158
VOID UhciClearRegBit(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT32 Offset, IN UINT16 Bit)
Definition: UhciReg.c:110
VOID UhciTurnOffUsbEmulation(IN EFI_PCI_IO_PROTOCOL *PciIo)
Definition: UhciReg.c:251
VOID UhciWriteReg(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT32 Offset, IN UINT16 Data)
Definition: UhciReg.c:57
VOID UhciSetRegBit(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT32 Offset, IN UINT16 Bit)
Definition: UhciReg.c:88
UINT16 UhciReadReg(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT32 Offset)
Definition: UhciReg.c:22
VOID UhciAckAllInterrupt(IN USB_HC_DEV *Uhc)
Definition: UhciReg.c:131
EFI_STATUS UhciInitFrameList(IN USB_HC_DEV *Uhc)
Definition: UhciSched.c:23
EFI_STATUS UhciExecuteTransfer(IN USB_HC_DEV *Uhc, IN UHCI_QH_SW *Qh, IN UHCI_TD_SW *Td, IN UINTN TimeOut, IN BOOLEAN IsLow, OUT UHCI_QH_RESULT *QhResult)
Definition: UhciSched.c:558
VOID UhciFreeAllAsyncReq(IN USB_HC_DEV *Uhc)
Definition: UhciSched.c:907
VOID EFIAPI UhciMonitorAsyncReqList(IN EFI_EVENT Event, IN VOID *Context)
Definition: UhciSched.c:943
VOID UhciLinkQhToFrameList(USB_HC_DEV *Uhc, UHCI_QH_SW *Qh)
Definition: UhciSched.c:247
VOID UhciDestoryFrameList(IN USB_HC_DEV *Uhc)
Definition: UhciSched.c:159
EFI_STATUS UhciRemoveAsyncReq(IN USB_HC_DEV *Uhc, IN UINT8 DevAddr, IN UINT8 EndPoint, OUT UINT8 *Toggle)
Definition: UhciSched.c:808
EFI_STATUS UhciCreateAsyncReq(IN USB_HC_DEV *Uhc, IN UHCI_QH_SW *Qh, IN UHCI_TD_SW *FirstTd, IN UINT8 DevAddr, IN UINT8 EndPoint, IN UINTN DataLen, IN UINTN Interval, IN UINT8 *Data, IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, IN VOID *Context, IN BOOLEAN IsLow)
Definition: UhciSched.c:683
EFI_PCI_IO_PROTOCOL_CONFIG Read
Definition: PciIo.h:232