2 Usb Hub Request Support In PEI Phase
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 Get a given hub port status.
24 @param PeiServices General-purpose services that are available to every PEIM.
25 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
26 @param Port Usb hub port number (starting from 1).
27 @param PortStatus Current Hub port status and change status.
29 @retval EFI_SUCCESS Port status is obtained successfully.
30 @retval EFI_DEVICE_ERROR Cannot get the port status due to a hardware error.
31 @retval Others Other failure occurs.
36 IN EFI_PEI_SERVICES
**PeiServices
,
37 IN PEI_USB_IO_PPI
*UsbIoPpi
,
39 OUT UINT32
*PortStatus
42 EFI_USB_DEVICE_REQUEST DeviceRequest
;
44 ZeroMem (&DeviceRequest
, sizeof (EFI_USB_DEVICE_REQUEST
));
47 // Fill Device request packet
49 DeviceRequest
.RequestType
= USB_HUB_GET_PORT_STATUS_REQ_TYPE
;
50 DeviceRequest
.Request
= USB_HUB_GET_PORT_STATUS
;
51 DeviceRequest
.Index
= Port
;
52 DeviceRequest
.Length
= (UINT16
) sizeof (UINT32
);
55 return UsbIoPpi
->UsbControlTransfer (
60 PcdGet32 (PcdUsbTransferTimeoutValue
),
68 Set specified feature to a given hub port.
70 @param PeiServices General-purpose services that are available to every PEIM.
71 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
72 @param Port Usb hub port number (starting from 1).
73 @param Value New feature value.
75 @retval EFI_SUCCESS Port feature is set successfully.
76 @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error.
77 @retval Others Other failure occurs.
81 PeiHubSetPortFeature (
82 IN EFI_PEI_SERVICES
**PeiServices
,
83 IN PEI_USB_IO_PPI
*UsbIoPpi
,
88 EFI_USB_DEVICE_REQUEST DeviceRequest
;
90 ZeroMem (&DeviceRequest
, sizeof (EFI_USB_DEVICE_REQUEST
));
93 // Fill Device request packet
95 DeviceRequest
.RequestType
= USB_HUB_SET_PORT_FEATURE_REQ_TYPE
;
96 DeviceRequest
.Request
= USB_HUB_SET_PORT_FEATURE
;
97 DeviceRequest
.Value
= Value
;
98 DeviceRequest
.Index
= Port
;
100 return UsbIoPpi
->UsbControlTransfer (
105 PcdGet32 (PcdUsbTransferTimeoutValue
),
112 Clear specified feature on a given hub port.
114 @param PeiServices General-purpose services that are available to every PEIM.
115 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
116 @param Port Usb hub port number (starting from 1).
117 @param Value Feature value that will be cleared from the hub port.
119 @retval EFI_SUCCESS Port feature is cleared successfully.
120 @retval EFI_DEVICE_ERROR Cannot clear the port feature due to a hardware error.
121 @retval Others Other failure occurs.
125 PeiHubClearPortFeature (
126 IN EFI_PEI_SERVICES
**PeiServices
,
127 IN PEI_USB_IO_PPI
*UsbIoPpi
,
132 EFI_USB_DEVICE_REQUEST DeviceRequest
;
134 ZeroMem (&DeviceRequest
, sizeof (EFI_USB_DEVICE_REQUEST
));
137 // Fill Device request packet
139 DeviceRequest
.RequestType
= USB_HUB_CLEAR_FEATURE_PORT_REQ_TYPE
;
140 DeviceRequest
.Request
= USB_HUB_CLEAR_FEATURE_PORT
;
141 DeviceRequest
.Value
= Value
;
142 DeviceRequest
.Index
= Port
;
144 return UsbIoPpi
->UsbControlTransfer (
149 PcdGet32 (PcdUsbTransferTimeoutValue
),
156 Get a given hub status.
158 @param PeiServices General-purpose services that are available to every PEIM.
159 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
160 @param HubStatus Current Hub status and change status.
162 @retval EFI_SUCCESS Hub status is obtained successfully.
163 @retval EFI_DEVICE_ERROR Cannot get the hub status due to a hardware error.
164 @retval Others Other failure occurs.
169 IN EFI_PEI_SERVICES
**PeiServices
,
170 IN PEI_USB_IO_PPI
*UsbIoPpi
,
171 OUT UINT32
*HubStatus
174 EFI_USB_DEVICE_REQUEST DeviceRequest
;
176 ZeroMem (&DeviceRequest
, sizeof (EFI_USB_DEVICE_REQUEST
));
179 // Fill Device request packet
181 DeviceRequest
.RequestType
= USB_HUB_GET_HUB_STATUS_REQ_TYPE
;
182 DeviceRequest
.Request
= USB_HUB_GET_HUB_STATUS
;
183 DeviceRequest
.Length
= (UINT16
) sizeof (UINT32
);
185 return UsbIoPpi
->UsbControlTransfer (
190 PcdGet32 (PcdUsbTransferTimeoutValue
),
197 Set specified feature to a given hub.
199 @param PeiServices General-purpose services that are available to every PEIM.
200 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
201 @param Value New feature value.
203 @retval EFI_SUCCESS Port feature is set successfully.
204 @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error.
205 @retval Others Other failure occurs.
209 PeiHubSetHubFeature (
210 IN EFI_PEI_SERVICES
**PeiServices
,
211 IN PEI_USB_IO_PPI
*UsbIoPpi
,
215 EFI_USB_DEVICE_REQUEST DeviceRequest
;
217 ZeroMem (&DeviceRequest
, sizeof (EFI_USB_DEVICE_REQUEST
));
220 // Fill Device request packet
222 DeviceRequest
.RequestType
= USB_HUB_SET_HUB_FEATURE_REQ_TYPE
;
223 DeviceRequest
.Request
= USB_HUB_SET_HUB_FEATURE
;
224 DeviceRequest
.Value
= Value
;
226 return UsbIoPpi
->UsbControlTransfer (
231 PcdGet32 (PcdUsbTransferTimeoutValue
),
238 Clear specified feature on a given hub.
240 @param PeiServices General-purpose services that are available to every PEIM.
241 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
242 @param Value Feature value that will be cleared from the hub port.
244 @retval EFI_SUCCESS Hub feature is cleared successfully.
245 @retval EFI_DEVICE_ERROR Cannot clear the hub feature due to a hardware error.
246 @retval Others Other failure occurs.
250 PeiHubClearHubFeature (
251 IN EFI_PEI_SERVICES
**PeiServices
,
252 IN PEI_USB_IO_PPI
*UsbIoPpi
,
256 EFI_USB_DEVICE_REQUEST DeviceRequest
;
258 ZeroMem (&DeviceRequest
, sizeof (EFI_USB_DEVICE_REQUEST
));
261 // Fill Device request packet
263 DeviceRequest
.RequestType
= USB_HUB_CLEAR_FEATURE_REQ_TYPE
;
264 DeviceRequest
.Request
= USB_HUB_CLEAR_FEATURE
;
265 DeviceRequest
.Value
= Value
;
267 return UsbIoPpi
->UsbControlTransfer (
272 PcdGet32 (PcdUsbTransferTimeoutValue
),
279 Get a given hub descriptor.
281 @param PeiServices General-purpose services that are available to every PEIM.
282 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
283 @param DescriptorSize The length of Hub Descriptor buffer.
284 @param HubDescriptor Caller allocated buffer to store the hub descriptor if
285 successfully returned.
287 @retval EFI_SUCCESS Hub descriptor is obtained successfully.
288 @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error.
289 @retval Others Other failure occurs.
293 PeiGetHubDescriptor (
294 IN EFI_PEI_SERVICES
**PeiServices
,
295 IN PEI_USB_IO_PPI
*UsbIoPpi
,
296 IN UINTN DescriptorSize
,
297 OUT EFI_USB_HUB_DESCRIPTOR
*HubDescriptor
300 EFI_USB_DEVICE_REQUEST DevReq
;
301 ZeroMem (&DevReq
, sizeof (EFI_USB_DEVICE_REQUEST
));
304 // Fill Device request packet
306 DevReq
.RequestType
= USB_RT_HUB
| 0x80;
307 DevReq
.Request
= USB_HUB_GET_DESCRIPTOR
;
308 DevReq
.Value
= USB_DT_HUB
<< 8;
309 DevReq
.Length
= (UINT16
)DescriptorSize
;
311 return UsbIoPpi
->UsbControlTransfer (
316 PcdGet32 (PcdUsbTransferTimeoutValue
),
318 (UINT16
)DescriptorSize
323 Get a given SuperSpeed hub descriptor.
325 @param PeiServices General-purpose services that are available to every PEIM.
326 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
327 @param HubDescriptor Caller allocated buffer to store the hub descriptor if
328 successfully returned.
330 @retval EFI_SUCCESS Hub descriptor is obtained successfully.
331 @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error.
332 @retval Others Other failure occurs.
336 PeiGetSuperSpeedHubDesc (
337 IN EFI_PEI_SERVICES
**PeiServices
,
338 IN PEI_USB_IO_PPI
*UsbIoPpi
,
339 OUT EFI_USB_HUB_DESCRIPTOR
*HubDescriptor
342 EFI_USB_DEVICE_REQUEST DevReq
;
343 ZeroMem (&DevReq
, sizeof (EFI_USB_DEVICE_REQUEST
));
346 // Fill Device request packet
348 DevReq
.RequestType
= USB_RT_HUB
| 0x80;
349 DevReq
.Request
= USB_HUB_GET_DESCRIPTOR
;
350 DevReq
.Value
= USB_DT_SUPERSPEED_HUB
<< 8;
353 return UsbIoPpi
->UsbControlTransfer (
358 PcdGet32 (PcdUsbTransferTimeoutValue
),
365 Read the whole usb hub descriptor. It is necessary
366 to do it in two steps because hub descriptor is of
369 @param PeiServices General-purpose services that are available to every PEIM.
370 @param PeiUsbDevice Indicates the hub controller device.
371 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
372 @param HubDescriptor Caller allocated buffer to store the hub descriptor if
373 successfully returned.
375 @retval EFI_SUCCESS Hub descriptor is obtained successfully.
376 @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error.
377 @retval Others Other failure occurs.
382 IN EFI_PEI_SERVICES
**PeiServices
,
383 IN PEI_USB_DEVICE
*PeiUsbDevice
,
384 IN PEI_USB_IO_PPI
*UsbIoPpi
,
385 OUT EFI_USB_HUB_DESCRIPTOR
*HubDescriptor
390 if (PeiUsbDevice
->DeviceSpeed
== EFI_USB_SPEED_SUPER
) {
392 // Get the super speed hub descriptor
394 Status
= PeiGetSuperSpeedHubDesc (PeiServices
, UsbIoPpi
, HubDescriptor
);
398 // First get the hub descriptor length
400 Status
= PeiGetHubDescriptor (PeiServices
, UsbIoPpi
, 2, HubDescriptor
);
402 if (EFI_ERROR (Status
)) {
407 // Get the whole hub descriptor
409 Status
= PeiGetHubDescriptor (PeiServices
, UsbIoPpi
, HubDescriptor
->Length
, HubDescriptor
);
416 USB hub control transfer to set the hub depth.
418 @param PeiServices General-purpose services that are available to every PEIM.
419 @param PeiUsbDevice Indicates the hub controller device.
420 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
422 @retval EFI_SUCCESS Depth of the hub is set.
423 @retval Others Failed to set the depth.
427 PeiUsbHubCtrlSetHubDepth (
428 IN EFI_PEI_SERVICES
**PeiServices
,
429 IN PEI_USB_DEVICE
*PeiUsbDevice
,
430 IN PEI_USB_IO_PPI
*UsbIoPpi
433 EFI_USB_DEVICE_REQUEST DevReq
;
434 ZeroMem (&DevReq
, sizeof (EFI_USB_DEVICE_REQUEST
));
437 // Fill Device request packet
439 DevReq
.RequestType
= USB_RT_HUB
;
440 DevReq
.Request
= USB_HUB_REQ_SET_DEPTH
;
441 DevReq
.Value
= PeiUsbDevice
->Tier
;
444 return UsbIoPpi
->UsbControlTransfer (
449 PcdGet32 (PcdUsbTransferTimeoutValue
),
456 Configure a given hub.
458 @param PeiServices General-purpose services that are available to every PEIM.
459 @param PeiUsbDevice Indicating the hub controller device that will be configured
461 @retval EFI_SUCCESS Hub configuration is done successfully.
462 @retval EFI_DEVICE_ERROR Cannot configure the hub due to a hardware error.
467 IN EFI_PEI_SERVICES
**PeiServices
,
468 IN PEI_USB_DEVICE
*PeiUsbDevice
471 EFI_USB_HUB_DESCRIPTOR HubDescriptor
;
473 EFI_USB_HUB_STATUS HubStatus
;
475 PEI_USB_IO_PPI
*UsbIoPpi
;
477 ZeroMem (&HubDescriptor
, sizeof (HubDescriptor
));
478 UsbIoPpi
= &PeiUsbDevice
->UsbIoPpi
;
481 // Get the hub descriptor
483 Status
= PeiUsbHubReadDesc (
489 if (EFI_ERROR (Status
)) {
490 return EFI_DEVICE_ERROR
;
493 PeiUsbDevice
->DownStreamPortNo
= HubDescriptor
.NbrPorts
;
495 if (PeiUsbDevice
->DeviceSpeed
== EFI_USB_SPEED_SUPER
) {
496 DEBUG ((EFI_D_INFO
, "PeiDoHubConfig: Set Hub Depth as 0x%x\n", PeiUsbDevice
->Tier
));
497 PeiUsbHubCtrlSetHubDepth (
504 // Power all the hub ports
506 for (Index
= 0; Index
< PeiUsbDevice
->DownStreamPortNo
; Index
++) {
507 Status
= PeiHubSetPortFeature (
513 if (EFI_ERROR (Status
)) {
514 DEBUG (( EFI_D_ERROR
, "PeiDoHubConfig: PeiHubSetPortFeature EfiUsbPortPower failed %x\n", Index
));
519 DEBUG (( EFI_D_INFO
, "PeiDoHubConfig: HubDescriptor.PwrOn2PwrGood: 0x%x\n", HubDescriptor
.PwrOn2PwrGood
));
520 if (HubDescriptor
.PwrOn2PwrGood
> 0) {
521 MicroSecondDelay (HubDescriptor
.PwrOn2PwrGood
* USB_SET_PORT_POWER_STALL
);
525 // Clear Hub Status Change
527 Status
= PeiHubGetHubStatus (
530 (UINT32
*) &HubStatus
532 if (EFI_ERROR (Status
)) {
533 return EFI_DEVICE_ERROR
;
536 // Hub power supply change happens
538 if ((HubStatus
.HubChangeStatus
& HUB_CHANGE_LOCAL_POWER
) != 0) {
539 PeiHubClearHubFeature (
546 // Hub change overcurrent happens
548 if ((HubStatus
.HubChangeStatus
& HUB_CHANGE_OVERCURRENT
) != 0) {
549 PeiHubClearHubFeature (
562 Send reset signal over the given root hub port.
564 @param PeiServices General-purpose services that are available to every PEIM.
565 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
566 @param PortNum Usb hub port number (starting from 1).
571 IN EFI_PEI_SERVICES
**PeiServices
,
572 IN PEI_USB_IO_PPI
*UsbIoPpi
,
578 EFI_USB_PORT_STATUS HubPortStatus
;
580 MicroSecondDelay (100 * 1000);
585 PeiHubSetPortFeature (
593 // Drive the reset signal for worst 20ms. Check USB 2.0 Spec
594 // section 7.1.7.5 for timing requirements.
596 MicroSecondDelay (USB_SET_PORT_RESET_STALL
);
599 // Check USB_PORT_STAT_C_RESET bit to see if the resetting state is done.
601 ZeroMem (&HubPortStatus
, sizeof (EFI_USB_PORT_STATUS
));
603 for (Index
= 0; Index
< USB_WAIT_PORT_STS_CHANGE_LOOP
; Index
++) {
604 Status
= PeiHubGetPortStatus (
608 (UINT32
*) &HubPortStatus
611 if (EFI_ERROR (Status
)) {
615 if (USB_BIT_IS_SET (HubPortStatus
.PortChangeStatus
, USB_PORT_STAT_C_RESET
)) {
619 MicroSecondDelay (USB_WAIT_PORT_STS_CHANGE_STALL
);
622 if (Index
== USB_WAIT_PORT_STS_CHANGE_LOOP
) {
623 DEBUG ((EFI_D_ERROR
, "PeiResetHubPort: reset not finished in time on port %d\n", PortNum
));
628 // clear reset change root port
630 PeiHubClearPortFeature (
634 EfiUsbPortResetChange
637 MicroSecondDelay (1 * 1000);
639 PeiHubClearPortFeature (
643 EfiUsbPortConnectChange
649 PeiHubSetPortFeature (
657 // Clear any change status
660 PeiHubClearPortFeature (
664 EfiUsbPortEnableChange
667 MicroSecondDelay (10 * 1000);