TianoCore EDK2 master
Loading...
Searching...
No Matches
HubPeim.c
Go to the documentation of this file.
1
10#include "UsbPeim.h"
11#include "HubPeim.h"
12#include "PeiUsbLib.h"
13
29 IN EFI_PEI_SERVICES **PeiServices,
30 IN PEI_USB_IO_PPI *UsbIoPpi,
31 IN UINT8 Port,
32 OUT UINT32 *PortStatus
33 )
34{
35 EFI_USB_DEVICE_REQUEST DeviceRequest;
36
37 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
38
39 //
40 // Fill Device request packet
41 //
42 DeviceRequest.RequestType = USB_HUB_GET_PORT_STATUS_REQ_TYPE;
43 DeviceRequest.Request = USB_HUB_GET_PORT_STATUS;
44 DeviceRequest.Index = Port;
45 DeviceRequest.Length = (UINT16)sizeof (UINT32);
46
47 return UsbIoPpi->UsbControlTransfer (
48 PeiServices,
49 UsbIoPpi,
50 &DeviceRequest,
51 EfiUsbDataIn,
52 PcdGet32 (PcdUsbTransferTimeoutValue),
53 PortStatus,
54 sizeof (UINT32)
55 );
56}
57
73 IN EFI_PEI_SERVICES **PeiServices,
74 IN PEI_USB_IO_PPI *UsbIoPpi,
75 IN UINT8 Port,
76 IN UINT8 Value
77 )
78{
79 EFI_USB_DEVICE_REQUEST DeviceRequest;
80
81 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
82
83 //
84 // Fill Device request packet
85 //
86 DeviceRequest.RequestType = USB_HUB_SET_PORT_FEATURE_REQ_TYPE;
87 DeviceRequest.Request = USB_HUB_SET_PORT_FEATURE;
88 DeviceRequest.Value = Value;
89 DeviceRequest.Index = Port;
90
91 return UsbIoPpi->UsbControlTransfer (
92 PeiServices,
93 UsbIoPpi,
94 &DeviceRequest,
95 EfiUsbNoData,
96 PcdGet32 (PcdUsbTransferTimeoutValue),
97 NULL,
98 0
99 );
100}
101
117 IN EFI_PEI_SERVICES **PeiServices,
118 IN PEI_USB_IO_PPI *UsbIoPpi,
119 IN UINT8 Port,
120 IN UINT8 Value
121 )
122{
123 EFI_USB_DEVICE_REQUEST DeviceRequest;
124
125 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
126
127 //
128 // Fill Device request packet
129 //
130 DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_PORT_REQ_TYPE;
131 DeviceRequest.Request = USB_HUB_CLEAR_FEATURE_PORT;
132 DeviceRequest.Value = Value;
133 DeviceRequest.Index = Port;
134
135 return UsbIoPpi->UsbControlTransfer (
136 PeiServices,
137 UsbIoPpi,
138 &DeviceRequest,
139 EfiUsbNoData,
140 PcdGet32 (PcdUsbTransferTimeoutValue),
141 NULL,
142 0
143 );
144}
145
160 IN EFI_PEI_SERVICES **PeiServices,
161 IN PEI_USB_IO_PPI *UsbIoPpi,
162 OUT UINT32 *HubStatus
163 )
164{
165 EFI_USB_DEVICE_REQUEST DeviceRequest;
166
167 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
168
169 //
170 // Fill Device request packet
171 //
172 DeviceRequest.RequestType = USB_HUB_GET_HUB_STATUS_REQ_TYPE;
173 DeviceRequest.Request = USB_HUB_GET_HUB_STATUS;
174 DeviceRequest.Length = (UINT16)sizeof (UINT32);
175
176 return UsbIoPpi->UsbControlTransfer (
177 PeiServices,
178 UsbIoPpi,
179 &DeviceRequest,
180 EfiUsbDataIn,
181 PcdGet32 (PcdUsbTransferTimeoutValue),
182 HubStatus,
183 sizeof (UINT32)
184 );
185}
186
201 IN EFI_PEI_SERVICES **PeiServices,
202 IN PEI_USB_IO_PPI *UsbIoPpi,
203 IN UINT8 Value
204 )
205{
206 EFI_USB_DEVICE_REQUEST DeviceRequest;
207
208 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
209
210 //
211 // Fill Device request packet
212 //
213 DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_REQ_TYPE;
214 DeviceRequest.Request = USB_HUB_CLEAR_FEATURE;
215 DeviceRequest.Value = Value;
216
217 return UsbIoPpi->UsbControlTransfer (
218 PeiServices,
219 UsbIoPpi,
220 &DeviceRequest,
221 EfiUsbNoData,
222 PcdGet32 (PcdUsbTransferTimeoutValue),
223 NULL,
224 0
225 );
226}
227
245 IN EFI_PEI_SERVICES **PeiServices,
246 IN PEI_USB_DEVICE *PeiUsbDevice,
247 IN PEI_USB_IO_PPI *UsbIoPpi,
248 IN UINTN DescriptorSize,
249 OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor
250 )
251{
253 UINT8 DescType;
254
255 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
256
257 DescType = (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_SUPER) ?
258 USB_DT_SUPERSPEED_HUB :
259 USB_DT_HUB;
260
261 //
262 // Fill Device request packet
263 //
264 DevReq.RequestType = USB_RT_HUB | 0x80;
265 DevReq.Request = USB_HUB_GET_DESCRIPTOR;
266 DevReq.Value = (UINT16)(DescType << 8);
267 DevReq.Length = (UINT16)DescriptorSize;
268
269 return UsbIoPpi->UsbControlTransfer (
270 PeiServices,
271 UsbIoPpi,
272 &DevReq,
273 EfiUsbDataIn,
274 PcdGet32 (PcdUsbTransferTimeoutValue),
275 HubDescriptor,
276 (UINT16)DescriptorSize
277 );
278}
279
298 IN EFI_PEI_SERVICES **PeiServices,
299 IN PEI_USB_DEVICE *PeiUsbDevice,
300 IN PEI_USB_IO_PPI *UsbIoPpi,
301 OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor
302 )
303{
304 EFI_STATUS Status;
305
306 //
307 // First get the hub descriptor length
308 //
309 Status = PeiGetHubDescriptor (PeiServices, PeiUsbDevice, UsbIoPpi, 2, HubDescriptor);
310
311 if (EFI_ERROR (Status)) {
312 return Status;
313 }
314
315 //
316 // Get the whole hub descriptor
317 //
318 return PeiGetHubDescriptor (PeiServices, PeiUsbDevice, UsbIoPpi, HubDescriptor->Length, HubDescriptor);
319}
320
334 IN EFI_PEI_SERVICES **PeiServices,
335 IN PEI_USB_DEVICE *PeiUsbDevice,
336 IN PEI_USB_IO_PPI *UsbIoPpi
337 )
338{
340
341 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
342
343 //
344 // Fill Device request packet
345 //
346 DevReq.RequestType = USB_RT_HUB;
347 DevReq.Request = USB_HUB_REQ_SET_DEPTH;
348 DevReq.Value = PeiUsbDevice->Tier;
349 DevReq.Length = 0;
350
351 return UsbIoPpi->UsbControlTransfer (
352 PeiServices,
353 UsbIoPpi,
354 &DevReq,
355 EfiUsbNoData,
356 PcdGet32 (PcdUsbTransferTimeoutValue),
357 NULL,
358 0
359 );
360}
361
374 IN EFI_PEI_SERVICES **PeiServices,
375 IN PEI_USB_DEVICE *PeiUsbDevice
376 )
377{
378 UINT8 HubDescBuffer[256];
379 EFI_USB_HUB_DESCRIPTOR *HubDescriptor;
380 EFI_STATUS Status;
381 EFI_USB_HUB_STATUS HubStatus;
382 UINTN Index;
383 PEI_USB_IO_PPI *UsbIoPpi;
384
385 UsbIoPpi = &PeiUsbDevice->UsbIoPpi;
386
387 //
388 // The length field of descriptor is UINT8 type, so the buffer
389 // with 256 bytes is enough to hold the descriptor data.
390 //
391 HubDescriptor = (EFI_USB_HUB_DESCRIPTOR *)HubDescBuffer;
392
393 //
394 // Get the hub descriptor
395 //
396 Status = PeiUsbHubReadDesc (
397 PeiServices,
398 PeiUsbDevice,
399 UsbIoPpi,
400 HubDescriptor
401 );
402 if (EFI_ERROR (Status)) {
403 return EFI_DEVICE_ERROR;
404 }
405
406 PeiUsbDevice->DownStreamPortNo = HubDescriptor->NbrPorts;
407
408 if (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_SUPER) {
409 DEBUG ((DEBUG_INFO, "PeiDoHubConfig: Set Hub Depth as 0x%x\n", PeiUsbDevice->Tier));
411 PeiServices,
412 PeiUsbDevice,
413 UsbIoPpi
414 );
415 } else {
416 //
417 // Power all the hub ports
418 //
419 for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) {
420 Status = PeiHubSetPortFeature (
421 PeiServices,
422 UsbIoPpi,
423 (UINT8)(Index + 1),
424 EfiUsbPortPower
425 );
426 if (EFI_ERROR (Status)) {
427 DEBUG ((DEBUG_ERROR, "PeiDoHubConfig: PeiHubSetPortFeature EfiUsbPortPower failed %x\n", Index));
428 continue;
429 }
430 }
431
432 DEBUG ((DEBUG_INFO, "PeiDoHubConfig: HubDescriptor.PwrOn2PwrGood: 0x%x\n", HubDescriptor->PwrOn2PwrGood));
433 if (HubDescriptor->PwrOn2PwrGood > 0) {
434 MicroSecondDelay (HubDescriptor->PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);
435 }
436
437 //
438 // Clear Hub Status Change
439 //
440 Status = PeiHubGetHubStatus (
441 PeiServices,
442 UsbIoPpi,
443 (UINT32 *)&HubStatus
444 );
445 if (EFI_ERROR (Status)) {
446 return EFI_DEVICE_ERROR;
447 } else {
448 //
449 // Hub power supply change happens
450 //
451 if ((HubStatus.HubChangeStatus & HUB_CHANGE_LOCAL_POWER) != 0) {
453 PeiServices,
454 UsbIoPpi,
455 C_HUB_LOCAL_POWER
456 );
457 }
458
459 //
460 // Hub change overcurrent happens
461 //
462 if ((HubStatus.HubChangeStatus & HUB_CHANGE_OVERCURRENT) != 0) {
464 PeiServices,
465 UsbIoPpi,
466 C_HUB_OVER_CURRENT
467 );
468 }
469 }
470 }
471
472 return EFI_SUCCESS;
473}
474
483VOID
485 IN EFI_PEI_SERVICES **PeiServices,
486 IN PEI_USB_IO_PPI *UsbIoPpi,
487 IN UINT8 PortNum
488 )
489{
490 EFI_STATUS Status;
491 UINTN Index;
492 EFI_USB_PORT_STATUS HubPortStatus;
493
494 MicroSecondDelay (100 * 1000);
495
496 //
497 // reset root port
498 //
500 PeiServices,
501 UsbIoPpi,
502 PortNum,
503 EfiUsbPortReset
504 );
505
506 //
507 // Drive the reset signal for worst 20ms. Check USB 2.0 Spec
508 // section 7.1.7.5 for timing requirements.
509 //
510 MicroSecondDelay (USB_SET_PORT_RESET_STALL);
511
512 //
513 // Check USB_PORT_STAT_C_RESET bit to see if the resetting state is done.
514 //
515 ZeroMem (&HubPortStatus, sizeof (EFI_USB_PORT_STATUS));
516
517 for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
518 Status = PeiHubGetPortStatus (
519 PeiServices,
520 UsbIoPpi,
521 PortNum,
522 (UINT32 *)&HubPortStatus
523 );
524
525 if (EFI_ERROR (Status)) {
526 return;
527 }
528
529 if (USB_BIT_IS_SET (HubPortStatus.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
530 break;
531 }
532
533 MicroSecondDelay (USB_WAIT_PORT_STS_CHANGE_STALL);
534 }
535
536 if (Index == USB_WAIT_PORT_STS_CHANGE_LOOP) {
537 DEBUG ((DEBUG_ERROR, "PeiResetHubPort: reset not finished in time on port %d\n", PortNum));
538 return;
539 }
540
541 //
542 // clear reset change root port
543 //
545 PeiServices,
546 UsbIoPpi,
547 PortNum,
548 EfiUsbPortResetChange
549 );
550
551 MicroSecondDelay (1 * 1000);
552
554 PeiServices,
555 UsbIoPpi,
556 PortNum,
557 EfiUsbPortConnectChange
558 );
559
560 //
561 // Set port enable
562 //
564 PeiServices,
565 UsbIoPpi,
566 PortNum,
567 EfiUsbPortEnable
568 );
569
570 //
571 // Clear any change status
572 //
573
575 PeiServices,
576 UsbIoPpi,
577 PortNum,
578 EfiUsbPortEnableChange
579 );
580
581 MicroSecondDelay (10 * 1000);
582
583 return;
584}
UINT64 UINTN
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS PeiGetHubDescriptor(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_DEVICE *PeiUsbDevice, IN PEI_USB_IO_PPI *UsbIoPpi, IN UINTN DescriptorSize, OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor)
Definition: HubPeim.c:244
EFI_STATUS PeiHubClearPortFeature(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_IO_PPI *UsbIoPpi, IN UINT8 Port, IN UINT8 Value)
Definition: HubPeim.c:116
EFI_STATUS PeiDoHubConfig(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_DEVICE *PeiUsbDevice)
Definition: HubPeim.c:373
EFI_STATUS PeiUsbHubReadDesc(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_DEVICE *PeiUsbDevice, IN PEI_USB_IO_PPI *UsbIoPpi, OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor)
Definition: HubPeim.c:297
VOID PeiResetHubPort(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_IO_PPI *UsbIoPpi, IN UINT8 PortNum)
Definition: HubPeim.c:484
EFI_STATUS PeiHubGetHubStatus(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_IO_PPI *UsbIoPpi, OUT UINT32 *HubStatus)
Definition: HubPeim.c:159
EFI_STATUS PeiHubClearHubFeature(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_IO_PPI *UsbIoPpi, IN UINT8 Value)
Definition: HubPeim.c:200
EFI_STATUS PeiHubGetPortStatus(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_IO_PPI *UsbIoPpi, IN UINT8 Port, OUT UINT32 *PortStatus)
Definition: HubPeim.c:28
EFI_STATUS PeiUsbHubCtrlSetHubDepth(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_DEVICE *PeiUsbDevice, IN PEI_USB_IO_PPI *UsbIoPpi)
Definition: HubPeim.c:333
EFI_STATUS PeiHubSetPortFeature(IN EFI_PEI_SERVICES **PeiServices, IN PEI_USB_IO_PPI *UsbIoPpi, IN UINT8 Port, IN UINT8 Value)
Definition: HubPeim.c:72
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define EFI_USB_SPEED_SUPER
4.8 Gb/s, USB 3.0 XHCI HC.
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112