2 The module to produce Usb Bus PPI.
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions
8 of the BSD License which accompanies this distribution. The
9 full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include "PeiUsbLib.h"
22 // UsbIo PPI interface function
24 PEI_USB_IO_PPI mUsbIoPpi
= {
25 PeiUsbControlTransfer
,
27 PeiUsbGetInterfaceDescriptor
,
28 PeiUsbGetEndpointDescriptor
,
32 EFI_PEI_PPI_DESCRIPTOR mUsbIoPpiList
= {
33 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
39 The enumeration routine to detect device change.
41 @param PeiServices Describes the list of possible PEI Services.
42 @param UsbHcPpi The pointer of PEI_USB_HOST_CONTROLLER_PPI instance.
43 @param Usb2HcPpi The pointer of PEI_USB2_HOST_CONTROLLER_PPI instance.
45 @retval EFI_SUCCESS The usb is enumerated successfully.
46 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.
47 @retval Others Other failure occurs.
52 IN EFI_PEI_SERVICES
**PeiServices
,
53 IN PEI_USB_HOST_CONTROLLER_PPI
*UsbHcPpi
,
54 IN PEI_USB2_HOST_CONTROLLER_PPI
*Usb2HcPpi
58 Configure new detected usb device.
60 @param PeiServices Describes the list of possible PEI Services.
61 @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance.
62 @param Port The port to be configured.
63 @param DeviceAddress The device address to be configured.
65 @retval EFI_SUCCESS The new detected usb device is configured successfully.
66 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.
67 @retval Others Other failure occurs.
71 PeiConfigureUsbDevice (
72 IN EFI_PEI_SERVICES
**PeiServices
,
73 IN PEI_USB_DEVICE
*PeiUsbDevice
,
75 IN OUT UINT8
*DeviceAddress
79 Get all configurations from a detected usb device.
81 @param PeiServices Describes the list of possible PEI Services.
82 @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance.
84 @retval EFI_SUCCESS The new detected usb device is configured successfully.
85 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.
86 @retval Others Other failure occurs.
90 PeiUsbGetAllConfiguration (
91 IN EFI_PEI_SERVICES
**PeiServices
,
92 IN PEI_USB_DEVICE
*PeiUsbDevice
96 Get the start position of next wanted descriptor.
98 @param Buffer Buffer containing data to parse.
99 @param Length Buffer length.
100 @param DescType Descriptor type.
101 @param DescLength Descriptor length.
102 @param ParsedBytes Bytes has been parsed.
104 @retval EFI_SUCCESS Get wanted descriptor successfully.
105 @retval EFI_DEVICE_ERROR Error occurred.
109 GetExpectedDescriptor (
114 OUT UINTN
*ParsedBytes
118 The entrypoint of the module, it will enumerate all HCs.
120 @param FileHandle Handle of the file being invoked.
121 @param PeiServices Describes the list of possible PEI Services.
123 @retval EFI_SUCCESS Usb initialization is done successfully.
124 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.
125 @retval EFI_UNSUPPORTED Can't find required PPI.
131 IN EFI_PEI_FILE_HANDLE FileHandle
,
132 IN CONST EFI_PEI_SERVICES
**PeiServices
137 PEI_USB_HOST_CONTROLLER_PPI
*UsbHcPpi
;
138 PEI_USB2_HOST_CONTROLLER_PPI
*Usb2HcPpi
;
140 if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle
))) {
145 // gPeiUsbHostControllerPpiGuid and gPeiUsb2HostControllerPpiGuid should not
146 // be produced at the same time
151 // Get UsbHcPpi at first.
153 Status
= PeiServicesLocatePpi (
154 &gPeiUsbHostControllerPpiGuid
,
159 if (EFI_ERROR (Status
)) {
161 // No more host controller, break out
165 PeiUsbEnumeration ((EFI_PEI_SERVICES
**) PeiServices
, UsbHcPpi
, NULL
);
171 // Then try to get Usb2HcPpi.
174 Status
= PeiServicesLocatePpi (
175 &gPeiUsb2HostControllerPpiGuid
,
180 if (EFI_ERROR (Status
)) {
182 // No more host controller, break out
186 PeiUsbEnumeration ((EFI_PEI_SERVICES
**) PeiServices
, NULL
, Usb2HcPpi
);
192 return EFI_UNSUPPORTED
;
199 The Hub Enumeration just scans the hub ports one time. It also
200 doesn't support hot-plug.
202 @param PeiServices Describes the list of possible PEI Services.
203 @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance.
204 @param CurrentAddress The DeviceAddress of usb device.
206 @retval EFI_SUCCESS The usb hub is enumerated successfully.
207 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.
208 @retval Others Other failure occurs.
213 IN EFI_PEI_SERVICES
**PeiServices
,
214 IN PEI_USB_DEVICE
*PeiUsbDevice
,
215 IN UINT8
*CurrentAddress
220 PEI_USB_IO_PPI
*UsbIoPpi
;
221 EFI_USB_PORT_STATUS PortStatus
;
223 EFI_PHYSICAL_ADDRESS AllocateAddress
;
224 PEI_USB_DEVICE
*NewPeiUsbDevice
;
225 UINTN InterfaceIndex
;
229 UsbIoPpi
= &PeiUsbDevice
->UsbIoPpi
;
231 for (Index
= 0; Index
< PeiUsbDevice
->DownStreamPortNo
; Index
++) {
233 Status
= PeiHubGetPortStatus (
237 (UINT32
*) &PortStatus
240 if (EFI_ERROR (Status
)) {
244 if (IsPortConnectChange (PortStatus
.PortChangeStatus
)) {
245 PeiHubClearPortFeature (
249 EfiUsbPortConnectChange
252 MicroSecondDelay (100 * 1000);
254 if (IsPortConnect (PortStatus
.PortStatus
)) {
256 PeiHubGetPortStatus (
260 (UINT32
*) &PortStatus
264 // Begin to deal with the new device
266 MemPages
= sizeof (PEI_USB_DEVICE
) / EFI_PAGE_SIZE
+ 1;
267 Status
= PeiServicesAllocatePages (
272 if (EFI_ERROR (Status
)) {
273 return EFI_OUT_OF_RESOURCES
;
276 NewPeiUsbDevice
= (PEI_USB_DEVICE
*) ((UINTN
) AllocateAddress
);
277 ZeroMem (NewPeiUsbDevice
, sizeof (PEI_USB_DEVICE
));
279 NewPeiUsbDevice
->Signature
= PEI_USB_DEVICE_SIGNATURE
;
280 NewPeiUsbDevice
->DeviceAddress
= 0;
281 NewPeiUsbDevice
->MaxPacketSize0
= 8;
282 NewPeiUsbDevice
->DataToggle
= 0;
284 &(NewPeiUsbDevice
->UsbIoPpi
),
286 sizeof (PEI_USB_IO_PPI
)
289 &(NewPeiUsbDevice
->UsbIoPpiList
),
291 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
293 NewPeiUsbDevice
->UsbIoPpiList
.Ppi
= &NewPeiUsbDevice
->UsbIoPpi
;
294 NewPeiUsbDevice
->AllocateAddress
= (UINTN
) AllocateAddress
;
295 NewPeiUsbDevice
->UsbHcPpi
= PeiUsbDevice
->UsbHcPpi
;
296 NewPeiUsbDevice
->Usb2HcPpi
= PeiUsbDevice
->Usb2HcPpi
;
297 NewPeiUsbDevice
->IsHub
= 0x0;
298 NewPeiUsbDevice
->DownStreamPortNo
= 0x0;
300 PeiResetHubPort (PeiServices
, UsbIoPpi
, (UINT8
)(Index
+ 1));
302 PeiHubGetPortStatus (
306 (UINT32
*) &PortStatus
309 NewPeiUsbDevice
->DeviceSpeed
= (UINT8
)IsPortLowSpeedDeviceAttached (PortStatus
.PortStatus
);
311 if(NewPeiUsbDevice
->DeviceSpeed
!= EFI_USB_SPEED_HIGH
) {
312 if (PeiUsbDevice
->DeviceSpeed
== EFI_USB_SPEED_HIGH
) {
313 NewPeiUsbDevice
->Translator
.TranslatorPortNumber
= (UINT8
)Index
;
314 NewPeiUsbDevice
->Translator
.TranslatorHubAddress
= *CurrentAddress
;
316 CopyMem(&(NewPeiUsbDevice
->Translator
), &(PeiUsbDevice
->Translator
), sizeof(EFI_USB2_HC_TRANSACTION_TRANSLATOR
));
321 // Configure that Usb Device
323 Status
= PeiConfigureUsbDevice (
330 if (EFI_ERROR (Status
)) {
334 Status
= PeiServicesInstallPpi (&NewPeiUsbDevice
->UsbIoPpiList
);
336 if (NewPeiUsbDevice
->InterfaceDesc
->InterfaceClass
== 0x09) {
337 NewPeiUsbDevice
->IsHub
= 0x1;
339 Status
= PeiDoHubConfig (PeiServices
, NewPeiUsbDevice
);
340 if (EFI_ERROR (Status
)) {
344 PeiHubEnumeration (PeiServices
, NewPeiUsbDevice
, CurrentAddress
);
347 for (InterfaceIndex
= 1; InterfaceIndex
< NewPeiUsbDevice
->ConfigDesc
->NumInterfaces
; InterfaceIndex
++) {
349 // Begin to deal with the new device
351 MemPages
= sizeof (PEI_USB_DEVICE
) / EFI_PAGE_SIZE
+ 1;
352 Status
= PeiServicesAllocatePages (
357 if (EFI_ERROR (Status
)) {
358 return EFI_OUT_OF_RESOURCES
;
360 CopyMem ((VOID
*)(UINTN
)AllocateAddress
, NewPeiUsbDevice
, sizeof (PEI_USB_DEVICE
));
361 NewPeiUsbDevice
= (PEI_USB_DEVICE
*) ((UINTN
) AllocateAddress
);
362 NewPeiUsbDevice
->AllocateAddress
= (UINTN
) AllocateAddress
;
363 NewPeiUsbDevice
->UsbIoPpiList
.Ppi
= &NewPeiUsbDevice
->UsbIoPpi
;
364 NewPeiUsbDevice
->InterfaceDesc
= NewPeiUsbDevice
->InterfaceDescList
[InterfaceIndex
];
365 for (EndpointIndex
= 0; EndpointIndex
< NewPeiUsbDevice
->InterfaceDesc
->NumEndpoints
; EndpointIndex
++) {
366 NewPeiUsbDevice
->EndpointDesc
[EndpointIndex
] = NewPeiUsbDevice
->EndpointDescList
[InterfaceIndex
][EndpointIndex
];
369 Status
= PeiServicesInstallPpi (&NewPeiUsbDevice
->UsbIoPpiList
);
371 if (NewPeiUsbDevice
->InterfaceDesc
->InterfaceClass
== 0x09) {
372 NewPeiUsbDevice
->IsHub
= 0x1;
374 Status
= PeiDoHubConfig (PeiServices
, NewPeiUsbDevice
);
375 if (EFI_ERROR (Status
)) {
379 PeiHubEnumeration (PeiServices
, NewPeiUsbDevice
, CurrentAddress
);
391 The enumeration routine to detect device change.
393 @param PeiServices Describes the list of possible PEI Services.
394 @param UsbHcPpi The pointer of PEI_USB_HOST_CONTROLLER_PPI instance.
395 @param Usb2HcPpi The pointer of PEI_USB2_HOST_CONTROLLER_PPI instance.
397 @retval EFI_SUCCESS The usb is enumerated successfully.
398 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.
399 @retval Others Other failure occurs.
404 IN EFI_PEI_SERVICES
**PeiServices
,
405 IN PEI_USB_HOST_CONTROLLER_PPI
*UsbHcPpi
,
406 IN PEI_USB2_HOST_CONTROLLER_PPI
*Usb2HcPpi
412 EFI_USB_PORT_STATUS PortStatus
;
413 PEI_USB_DEVICE
*PeiUsbDevice
;
415 EFI_PHYSICAL_ADDRESS AllocateAddress
;
416 UINT8 CurrentAddress
;
417 UINTN InterfaceIndex
;
421 if (Usb2HcPpi
!= NULL
) {
422 Usb2HcPpi
->GetRootHubPortNumber (
425 (UINT8
*) &NumOfRootPort
427 } else if (UsbHcPpi
!= NULL
) {
428 UsbHcPpi
->GetRootHubPortNumber (
431 (UINT8
*) &NumOfRootPort
435 return EFI_INVALID_PARAMETER
;
438 for (Index
= 0; Index
< NumOfRootPort
; Index
++) {
440 // First get root port status to detect changes happen
442 if (Usb2HcPpi
!= NULL
) {
443 Usb2HcPpi
->GetRootHubPortStatus (
450 UsbHcPpi
->GetRootHubPortStatus (
457 DEBUG ((EFI_D_INFO
, "USB Status --- ConnectChange[%04x] Status[%04x]\n", PortStatus
.PortChangeStatus
, PortStatus
.PortStatus
));
458 if (IsPortConnectChange (PortStatus
.PortChangeStatus
)) {
460 // Changes happen, first clear this change status
462 if (Usb2HcPpi
!= NULL
) {
463 Usb2HcPpi
->ClearRootHubPortFeature (
467 EfiUsbPortConnectChange
470 UsbHcPpi
->ClearRootHubPortFeature (
474 EfiUsbPortConnectChange
477 MicroSecondDelay (100 * 1000);
479 if (IsPortConnect (PortStatus
.PortStatus
)) {
480 if (Usb2HcPpi
!= NULL
) {
481 Usb2HcPpi
->GetRootHubPortStatus (
488 UsbHcPpi
->GetRootHubPortStatus (
497 // Connect change happen
499 MemPages
= sizeof (PEI_USB_DEVICE
) / EFI_PAGE_SIZE
+ 1;
500 Status
= PeiServicesAllocatePages (
505 if (EFI_ERROR (Status
)) {
506 return EFI_OUT_OF_RESOURCES
;
509 PeiUsbDevice
= (PEI_USB_DEVICE
*) ((UINTN
) AllocateAddress
);
510 ZeroMem (PeiUsbDevice
, sizeof (PEI_USB_DEVICE
));
512 PeiUsbDevice
->Signature
= PEI_USB_DEVICE_SIGNATURE
;
513 PeiUsbDevice
->DeviceAddress
= 0;
514 PeiUsbDevice
->MaxPacketSize0
= 8;
515 PeiUsbDevice
->DataToggle
= 0;
517 &(PeiUsbDevice
->UsbIoPpi
),
519 sizeof (PEI_USB_IO_PPI
)
522 &(PeiUsbDevice
->UsbIoPpiList
),
524 sizeof (EFI_PEI_PPI_DESCRIPTOR
)
526 PeiUsbDevice
->UsbIoPpiList
.Ppi
= &PeiUsbDevice
->UsbIoPpi
;
527 PeiUsbDevice
->AllocateAddress
= (UINTN
) AllocateAddress
;
528 PeiUsbDevice
->UsbHcPpi
= UsbHcPpi
;
529 PeiUsbDevice
->Usb2HcPpi
= Usb2HcPpi
;
530 PeiUsbDevice
->IsHub
= 0x0;
531 PeiUsbDevice
->DownStreamPortNo
= 0x0;
535 PeiUsbDevice
->UsbHcPpi
,
536 PeiUsbDevice
->Usb2HcPpi
,
541 if (Usb2HcPpi
!= NULL
) {
542 Usb2HcPpi
->GetRootHubPortStatus (
549 UsbHcPpi
->GetRootHubPortStatus (
557 PeiUsbDevice
->DeviceSpeed
= (UINT8
)IsPortLowSpeedDeviceAttached (PortStatus
.PortStatus
);
558 DEBUG ((EFI_D_INFO
, "Device Speed =%d\n", PeiUsbDevice
->DeviceSpeed
));
561 // Configure that Usb Device
563 Status
= PeiConfigureUsbDevice (
570 if (EFI_ERROR (Status
)) {
573 DEBUG ((EFI_D_INFO
, "PeiConfigureUsbDevice Success\n"));
575 Status
= PeiServicesInstallPpi (&PeiUsbDevice
->UsbIoPpiList
);
577 if (PeiUsbDevice
->InterfaceDesc
->InterfaceClass
== 0x09) {
578 PeiUsbDevice
->IsHub
= 0x1;
580 Status
= PeiDoHubConfig (PeiServices
, PeiUsbDevice
);
581 if (EFI_ERROR (Status
)) {
585 PeiHubEnumeration (PeiServices
, PeiUsbDevice
, &CurrentAddress
);
588 for (InterfaceIndex
= 1; InterfaceIndex
< PeiUsbDevice
->ConfigDesc
->NumInterfaces
; InterfaceIndex
++) {
590 // Begin to deal with the new device
592 MemPages
= sizeof (PEI_USB_DEVICE
) / EFI_PAGE_SIZE
+ 1;
593 Status
= PeiServicesAllocatePages (
598 if (EFI_ERROR (Status
)) {
599 return EFI_OUT_OF_RESOURCES
;
601 CopyMem ((VOID
*)(UINTN
)AllocateAddress
, PeiUsbDevice
, sizeof (PEI_USB_DEVICE
));
602 PeiUsbDevice
= (PEI_USB_DEVICE
*) ((UINTN
) AllocateAddress
);
603 PeiUsbDevice
->AllocateAddress
= (UINTN
) AllocateAddress
;
604 PeiUsbDevice
->UsbIoPpiList
.Ppi
= &PeiUsbDevice
->UsbIoPpi
;
605 PeiUsbDevice
->InterfaceDesc
= PeiUsbDevice
->InterfaceDescList
[InterfaceIndex
];
606 for (EndpointIndex
= 0; EndpointIndex
< PeiUsbDevice
->InterfaceDesc
->NumEndpoints
; EndpointIndex
++) {
607 PeiUsbDevice
->EndpointDesc
[EndpointIndex
] = PeiUsbDevice
->EndpointDescList
[InterfaceIndex
][EndpointIndex
];
610 Status
= PeiServicesInstallPpi (&PeiUsbDevice
->UsbIoPpiList
);
612 if (PeiUsbDevice
->InterfaceDesc
->InterfaceClass
== 0x09) {
613 PeiUsbDevice
->IsHub
= 0x1;
615 Status
= PeiDoHubConfig (PeiServices
, PeiUsbDevice
);
616 if (EFI_ERROR (Status
)) {
620 PeiHubEnumeration (PeiServices
, PeiUsbDevice
, &CurrentAddress
);
625 // Disconnect change happen, currently we don't support
635 Configure new detected usb device.
637 @param PeiServices Describes the list of possible PEI Services.
638 @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance.
639 @param Port The port to be configured.
640 @param DeviceAddress The device address to be configured.
642 @retval EFI_SUCCESS The new detected usb device is configured successfully.
643 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.
644 @retval Others Other failure occurs.
648 PeiConfigureUsbDevice (
649 IN EFI_PEI_SERVICES
**PeiServices
,
650 IN PEI_USB_DEVICE
*PeiUsbDevice
,
652 IN OUT UINT8
*DeviceAddress
655 EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor
;
657 PEI_USB_IO_PPI
*UsbIoPpi
;
660 UsbIoPpi
= &PeiUsbDevice
->UsbIoPpi
;
661 Status
= EFI_SUCCESS
;
662 ZeroMem (&DeviceDescriptor
, sizeof (EFI_USB_DEVICE_DESCRIPTOR
));
664 // Get USB device descriptor
667 for (Retry
= 0; Retry
< 3; Retry
++) {
669 PeiUsbDevice
->MaxPacketSize0
= 8;
671 Status
= PeiUsbGetDescriptor (
674 (USB_DT_DEVICE
<< 8),
680 if (!EFI_ERROR (Status
)) {
681 DEBUG ((EFI_D_INFO
, "PeiUsbGet Device Descriptor the %d time Sucess\n", Retry
));
687 DEBUG ((EFI_D_ERROR
, "PeiUsbGet Device Descriptor fail\n", Retry
));
691 PeiUsbDevice
->MaxPacketSize0
= DeviceDescriptor
.MaxPacketSize0
;
695 Status
= PeiUsbSetDeviceAddress (
701 if (EFI_ERROR (Status
)) {
702 DEBUG ((EFI_D_ERROR
, "PeiUsbSetDeviceAddress Failed\n"));
706 PeiUsbDevice
->DeviceAddress
= *DeviceAddress
;
709 // Get whole USB device descriptor
711 Status
= PeiUsbGetDescriptor (
714 (USB_DT_DEVICE
<< 8),
716 (UINT16
) sizeof (EFI_USB_DEVICE_DESCRIPTOR
),
720 if (EFI_ERROR (Status
)) {
721 DEBUG ((EFI_D_ERROR
, "PeiUsbGetDescriptor First Failed\n"));
726 // Get its default configuration and its first interface
728 Status
= PeiUsbGetAllConfiguration (
732 if (EFI_ERROR (Status
)) {
736 Status
= PeiUsbSetConfiguration (
741 if (EFI_ERROR (Status
)) {
749 Get all configurations from a detected usb device.
751 @param PeiServices Describes the list of possible PEI Services.
752 @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance.
754 @retval EFI_SUCCESS The new detected usb device is configured successfully.
755 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource.
756 @retval Others Other failure occurs.
760 PeiUsbGetAllConfiguration (
761 IN EFI_PEI_SERVICES
**PeiServices
,
762 IN PEI_USB_DEVICE
*PeiUsbDevice
766 EFI_USB_CONFIG_DESCRIPTOR
*ConfigDesc
;
767 PEI_USB_IO_PPI
*UsbIoPpi
;
768 UINT16 ConfigDescLength
;
772 UINTN InterfaceIndex
;
776 UsbIoPpi
= &PeiUsbDevice
->UsbIoPpi
;
779 // First get its 4-byte configuration descriptor
781 Status
= PeiUsbGetDescriptor (
784 (USB_DT_CONFIG
<< 8), // Value
787 PeiUsbDevice
->ConfigurationData
790 if (EFI_ERROR (Status
)) {
791 DEBUG ((EFI_D_ERROR
, "PeiUsbGet Config Descriptor First Failed\n"));
795 ConfigDesc
= (EFI_USB_CONFIG_DESCRIPTOR
*) PeiUsbDevice
->ConfigurationData
;
796 ConfigDescLength
= ConfigDesc
->TotalLength
;
799 // Then we get the total descriptors for this configuration
801 Status
= PeiUsbGetDescriptor (
804 (USB_DT_CONFIG
<< 8),
807 PeiUsbDevice
->ConfigurationData
810 if (EFI_ERROR (Status
)) {
811 DEBUG ((EFI_D_ERROR
, "PeiUsbGet Config Descriptor all Failed\n"));
815 // Parse this configuration descriptor
816 // First get the current config descriptor;
818 Status
= GetExpectedDescriptor (
819 PeiUsbDevice
->ConfigurationData
,
822 (UINT8
) sizeof (EFI_USB_CONFIG_DESCRIPTOR
),
826 if (EFI_ERROR (Status
)) {
830 Ptr
= PeiUsbDevice
->ConfigurationData
+ SkipBytes
;
831 PeiUsbDevice
->ConfigDesc
= (EFI_USB_CONFIG_DESCRIPTOR
*) Ptr
;
833 Ptr
+= sizeof (EFI_USB_CONFIG_DESCRIPTOR
);
834 LengthLeft
= ConfigDescLength
- SkipBytes
- sizeof (EFI_USB_CONFIG_DESCRIPTOR
);
836 for (InterfaceIndex
= 0; InterfaceIndex
< PeiUsbDevice
->ConfigDesc
->NumInterfaces
; InterfaceIndex
++) {
839 // Get the interface descriptor
841 Status
= GetExpectedDescriptor (
845 (UINT8
) sizeof (EFI_USB_INTERFACE_DESCRIPTOR
),
849 if (EFI_ERROR (Status
)) {
854 if (InterfaceIndex
== 0) {
855 PeiUsbDevice
->InterfaceDesc
= (EFI_USB_INTERFACE_DESCRIPTOR
*) Ptr
;
857 PeiUsbDevice
->InterfaceDescList
[InterfaceIndex
] = (EFI_USB_INTERFACE_DESCRIPTOR
*) Ptr
;
859 Ptr
+= sizeof (EFI_USB_INTERFACE_DESCRIPTOR
);
860 LengthLeft
-= SkipBytes
;
861 LengthLeft
-= sizeof (EFI_USB_INTERFACE_DESCRIPTOR
);
864 // Parse all the endpoint descriptor within this interface
866 NumOfEndpoint
= PeiUsbDevice
->InterfaceDescList
[InterfaceIndex
]->NumEndpoints
;
867 ASSERT (NumOfEndpoint
<= MAX_ENDPOINT
);
869 for (Index
= 0; Index
< NumOfEndpoint
; Index
++) {
871 // Get the endpoint descriptor
873 Status
= GetExpectedDescriptor (
877 (UINT8
) sizeof (EFI_USB_ENDPOINT_DESCRIPTOR
),
881 if (EFI_ERROR (Status
)) {
886 if (InterfaceIndex
== 0) {
887 PeiUsbDevice
->EndpointDesc
[Index
] = (EFI_USB_ENDPOINT_DESCRIPTOR
*) Ptr
;
889 PeiUsbDevice
->EndpointDescList
[InterfaceIndex
][Index
] = (EFI_USB_ENDPOINT_DESCRIPTOR
*) Ptr
;
891 Ptr
+= sizeof (EFI_USB_ENDPOINT_DESCRIPTOR
);
892 LengthLeft
-= SkipBytes
;
893 LengthLeft
-= sizeof (EFI_USB_ENDPOINT_DESCRIPTOR
);
901 Get the start position of next wanted descriptor.
903 @param Buffer Buffer containing data to parse.
904 @param Length Buffer length.
905 @param DescType Descriptor type.
906 @param DescLength Descriptor length.
907 @param ParsedBytes Bytes has been parsed.
909 @retval EFI_SUCCESS Get wanted descriptor successfully.
910 @retval EFI_DEVICE_ERROR Error occurred.
914 GetExpectedDescriptor (
919 OUT UINTN
*ParsedBytes
922 UINT16 DescriptorHeader
;
932 // Buffer length should not less than Desc length
934 if (Length
< DescLength
) {
935 return EFI_DEVICE_ERROR
;
938 DescriptorHeader
= (UINT16
) (*Ptr
+ ((*(Ptr
+ 1)) << 8));
943 // Check to see if it is a start of expected descriptor
945 if (DescriptorHeader
== ((DescType
<< 8) | DescLength
)) {
949 if ((UINT8
) (DescriptorHeader
>> 8) == DescType
) {
950 if (Len
> DescLength
) {
951 return EFI_DEVICE_ERROR
;
955 // Descriptor length should be at least 2
956 // and should not exceed the buffer length
959 return EFI_DEVICE_ERROR
;
963 return EFI_DEVICE_ERROR
;
966 // Skip this mismatch descriptor
973 *ParsedBytes
= Parsed
;
979 Send reset signal over the given root hub port.
981 @param PeiServices Describes the list of possible PEI Services.
982 @param UsbHcPpi The pointer of PEI_USB_HOST_CONTROLLER_PPI instance.
983 @param Usb2HcPpi The pointer of PEI_USB2_HOST_CONTROLLER_PPI instance.
984 @param PortNum The port to be reset.
985 @param RetryIndex The retry times.
990 IN EFI_PEI_SERVICES
**PeiServices
,
991 IN PEI_USB_HOST_CONTROLLER_PPI
*UsbHcPpi
,
992 IN PEI_USB2_HOST_CONTROLLER_PPI
*Usb2HcPpi
,
1000 if (Usb2HcPpi
!= NULL
) {
1001 MicroSecondDelay (200 * 1000);
1006 Status
= Usb2HcPpi
->SetRootHubPortFeature (
1013 if (EFI_ERROR (Status
)) {
1014 DEBUG ((EFI_D_ERROR
, "SetRootHubPortFeature EfiUsbPortReset Failed\n"));
1018 MicroSecondDelay (200 * 1000);
1021 // clear reset root port
1023 Status
= Usb2HcPpi
->ClearRootHubPortFeature (
1030 if (EFI_ERROR (Status
)) {
1031 DEBUG ((EFI_D_ERROR
, "ClearRootHubPortFeature EfiUsbPortReset Failed\n"));
1035 MicroSecondDelay (1 * 1000);
1037 Usb2HcPpi
->ClearRootHubPortFeature (
1041 EfiUsbPortConnectChange
1047 Usb2HcPpi
->SetRootHubPortFeature(
1054 Usb2HcPpi
->ClearRootHubPortFeature (
1058 EfiUsbPortEnableChange
1061 MicroSecondDelay ((RetryIndex
+ 1) * 50 * 1000);
1063 MicroSecondDelay (200 * 1000);
1068 Status
= UsbHcPpi
->SetRootHubPortFeature (
1075 if (EFI_ERROR (Status
)) {
1076 DEBUG ((EFI_D_ERROR
, "SetRootHubPortFeature EfiUsbPortReset Failed\n"));
1080 MicroSecondDelay (200 * 1000);
1083 // clear reset root port
1085 Status
= UsbHcPpi
->ClearRootHubPortFeature (
1092 if (EFI_ERROR (Status
)) {
1093 DEBUG ((EFI_D_ERROR
, "ClearRootHubPortFeature EfiUsbPortReset Failed\n"));
1097 MicroSecondDelay (1 * 1000);
1099 UsbHcPpi
->ClearRootHubPortFeature (
1103 EfiUsbPortConnectChange
1109 UsbHcPpi
->SetRootHubPortFeature(
1116 UsbHcPpi
->ClearRootHubPortFeature (
1120 EfiUsbPortEnableChange
1123 MicroSecondDelay ((RetryIndex
+ 1) * 50 * 1000);