]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c
MdeModulePkg XhciPei/UsbBusPei: Add XHCI recovery support.
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusPei / HubPeim.c
CommitLineData
4b1bf81c 1/** @file\r
2Usb Hub Request Support In PEI Phase\r
3\r
d987459f 4Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
4b1bf81c 5 \r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions\r
8of the BSD License which accompanies this distribution. The\r
9full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "UsbPeim.h"\r
18#include "HubPeim.h"\r
19#include "PeiUsbLib.h"\r
20\r
21/**\r
22 Get a given hub port status.\r
23\r
24 @param PeiServices General-purpose services that are available to every PEIM.\r
25 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
26 @param Port Usb hub port number (starting from 1).\r
27 @param PortStatus Current Hub port status and change status.\r
28\r
29 @retval EFI_SUCCESS Port status is obtained successfully.\r
30 @retval EFI_DEVICE_ERROR Cannot get the port status due to a hardware error.\r
31 @retval Others Other failure occurs.\r
32\r
33**/\r
34EFI_STATUS\r
35PeiHubGetPortStatus (\r
36 IN EFI_PEI_SERVICES **PeiServices,\r
37 IN PEI_USB_IO_PPI *UsbIoPpi,\r
38 IN UINT8 Port,\r
39 OUT UINT32 *PortStatus\r
40 )\r
41{\r
42 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
43\r
44 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
45\r
46 //\r
47 // Fill Device request packet\r
48 //\r
49 DeviceRequest.RequestType = USB_HUB_GET_PORT_STATUS_REQ_TYPE;\r
50 DeviceRequest.Request = USB_HUB_GET_PORT_STATUS;\r
51 DeviceRequest.Index = Port;\r
52 DeviceRequest.Length = (UINT16) sizeof (UINT32);\r
53\r
54\r
55 return UsbIoPpi->UsbControlTransfer (\r
56 PeiServices,\r
57 UsbIoPpi,\r
58 &DeviceRequest,\r
59 EfiUsbDataIn,\r
60 PcdGet32 (PcdUsbTransferTimeoutValue),\r
61 PortStatus,\r
62 sizeof (UINT32)\r
63 );\r
64\r
65}\r
66\r
67/**\r
68 Set specified feature to a given hub port.\r
69\r
70 @param PeiServices General-purpose services that are available to every PEIM.\r
71 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
72 @param Port Usb hub port number (starting from 1).\r
73 @param Value New feature value.\r
74\r
75 @retval EFI_SUCCESS Port feature is set successfully.\r
76 @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error.\r
77 @retval Others Other failure occurs.\r
78\r
79**/\r
80EFI_STATUS\r
81PeiHubSetPortFeature (\r
82 IN EFI_PEI_SERVICES **PeiServices,\r
83 IN PEI_USB_IO_PPI *UsbIoPpi,\r
84 IN UINT8 Port,\r
85 IN UINT8 Value\r
86 )\r
87{\r
88 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
89\r
90 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
91\r
92 //\r
93 // Fill Device request packet\r
94 //\r
95 DeviceRequest.RequestType = USB_HUB_SET_PORT_FEATURE_REQ_TYPE;\r
96 DeviceRequest.Request = USB_HUB_SET_PORT_FEATURE;\r
97 DeviceRequest.Value = Value;\r
98 DeviceRequest.Index = Port;\r
99\r
100 return UsbIoPpi->UsbControlTransfer (\r
101 PeiServices,\r
102 UsbIoPpi,\r
103 &DeviceRequest,\r
104 EfiUsbNoData,\r
105 PcdGet32 (PcdUsbTransferTimeoutValue),\r
106 NULL,\r
107 0\r
108 );\r
109}\r
110\r
111/**\r
112 Clear specified feature on a given hub port.\r
113\r
114 @param PeiServices General-purpose services that are available to every PEIM.\r
115 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
116 @param Port Usb hub port number (starting from 1).\r
117 @param Value Feature value that will be cleared from the hub port.\r
118\r
119 @retval EFI_SUCCESS Port feature is cleared successfully.\r
120 @retval EFI_DEVICE_ERROR Cannot clear the port feature due to a hardware error.\r
121 @retval Others Other failure occurs.\r
122\r
123**/\r
124EFI_STATUS\r
125PeiHubClearPortFeature (\r
126 IN EFI_PEI_SERVICES **PeiServices,\r
127 IN PEI_USB_IO_PPI *UsbIoPpi,\r
128 IN UINT8 Port,\r
129 IN UINT8 Value\r
130 )\r
131{\r
132 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
133\r
134 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
135\r
136 //\r
137 // Fill Device request packet\r
138 //\r
139 DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_PORT_REQ_TYPE;\r
140 DeviceRequest.Request = USB_HUB_CLEAR_FEATURE_PORT;\r
141 DeviceRequest.Value = Value;\r
142 DeviceRequest.Index = Port;\r
143\r
144 return UsbIoPpi->UsbControlTransfer (\r
145 PeiServices,\r
146 UsbIoPpi,\r
147 &DeviceRequest,\r
148 EfiUsbNoData,\r
149 PcdGet32 (PcdUsbTransferTimeoutValue),\r
150 NULL,\r
151 0\r
152 );\r
153}\r
154\r
155/**\r
156 Get a given hub status.\r
157\r
158 @param PeiServices General-purpose services that are available to every PEIM.\r
159 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
160 @param HubStatus Current Hub status and change status.\r
161\r
162 @retval EFI_SUCCESS Hub status is obtained successfully.\r
163 @retval EFI_DEVICE_ERROR Cannot get the hub status due to a hardware error.\r
164 @retval Others Other failure occurs.\r
165\r
166**/\r
167EFI_STATUS\r
168PeiHubGetHubStatus (\r
169 IN EFI_PEI_SERVICES **PeiServices,\r
170 IN PEI_USB_IO_PPI *UsbIoPpi,\r
171 OUT UINT32 *HubStatus\r
172 )\r
173{\r
174 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
175\r
176 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
177\r
178 //\r
179 // Fill Device request packet\r
180 //\r
181 DeviceRequest.RequestType = USB_HUB_GET_HUB_STATUS_REQ_TYPE;\r
182 DeviceRequest.Request = USB_HUB_GET_HUB_STATUS;\r
183 DeviceRequest.Length = (UINT16) sizeof (UINT32);\r
184\r
185 return UsbIoPpi->UsbControlTransfer (\r
186 PeiServices,\r
187 UsbIoPpi,\r
188 &DeviceRequest,\r
189 EfiUsbDataIn,\r
190 PcdGet32 (PcdUsbTransferTimeoutValue),\r
191 HubStatus,\r
192 sizeof (UINT32)\r
193 );\r
194}\r
195\r
196/**\r
197 Set specified feature to a given hub.\r
198\r
199 @param PeiServices General-purpose services that are available to every PEIM.\r
200 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
201 @param Value New feature value.\r
202\r
203 @retval EFI_SUCCESS Port feature is set successfully.\r
204 @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error.\r
205 @retval Others Other failure occurs.\r
206\r
207**/\r
208EFI_STATUS\r
209PeiHubSetHubFeature (\r
210 IN EFI_PEI_SERVICES **PeiServices,\r
211 IN PEI_USB_IO_PPI *UsbIoPpi,\r
212 IN UINT8 Value\r
213 )\r
214{\r
215 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
216\r
217 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
218\r
219 //\r
220 // Fill Device request packet\r
221 //\r
222 DeviceRequest.RequestType = USB_HUB_SET_HUB_FEATURE_REQ_TYPE;\r
223 DeviceRequest.Request = USB_HUB_SET_HUB_FEATURE;\r
224 DeviceRequest.Value = Value;\r
225\r
226 return UsbIoPpi->UsbControlTransfer (\r
227 PeiServices,\r
228 UsbIoPpi,\r
229 &DeviceRequest,\r
230 EfiUsbNoData,\r
231 PcdGet32 (PcdUsbTransferTimeoutValue),\r
232 NULL,\r
233 0\r
234 );\r
235}\r
236\r
237/**\r
238 Clear specified feature on a given hub.\r
239\r
240 @param PeiServices General-purpose services that are available to every PEIM.\r
241 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
242 @param Value Feature value that will be cleared from the hub port.\r
243\r
244 @retval EFI_SUCCESS Hub feature is cleared successfully.\r
245 @retval EFI_DEVICE_ERROR Cannot clear the hub feature due to a hardware error.\r
246 @retval Others Other failure occurs.\r
247\r
248**/\r
249EFI_STATUS\r
250PeiHubClearHubFeature (\r
251 IN EFI_PEI_SERVICES **PeiServices,\r
252 IN PEI_USB_IO_PPI *UsbIoPpi,\r
253 IN UINT8 Value\r
254 )\r
255{\r
256 EFI_USB_DEVICE_REQUEST DeviceRequest;\r
257\r
258 ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));\r
259\r
260 //\r
261 // Fill Device request packet\r
262 //\r
263 DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_REQ_TYPE;\r
264 DeviceRequest.Request = USB_HUB_CLEAR_FEATURE;\r
265 DeviceRequest.Value = Value;\r
266\r
267 return UsbIoPpi->UsbControlTransfer (\r
268 PeiServices,\r
269 UsbIoPpi,\r
270 &DeviceRequest,\r
271 EfiUsbNoData,\r
272 PcdGet32 (PcdUsbTransferTimeoutValue),\r
273 NULL,\r
274 0\r
275 );\r
276}\r
277\r
278/**\r
279 Get a given hub descriptor.\r
280\r
281 @param PeiServices General-purpose services that are available to every PEIM.\r
282 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
283 @param DescriptorSize The length of Hub Descriptor buffer.\r
284 @param HubDescriptor Caller allocated buffer to store the hub descriptor if\r
285 successfully returned.\r
286\r
287 @retval EFI_SUCCESS Hub descriptor is obtained successfully.\r
288 @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error.\r
289 @retval Others Other failure occurs.\r
290\r
291**/\r
292EFI_STATUS\r
293PeiGetHubDescriptor (\r
294 IN EFI_PEI_SERVICES **PeiServices,\r
295 IN PEI_USB_IO_PPI *UsbIoPpi,\r
296 IN UINTN DescriptorSize,\r
297 OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor\r
298 )\r
299{\r
300 EFI_USB_DEVICE_REQUEST DevReq;\r
301 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
302\r
303 //\r
304 // Fill Device request packet\r
305 //\r
306 DevReq.RequestType = USB_RT_HUB | 0x80;\r
307 DevReq.Request = USB_HUB_GET_DESCRIPTOR;\r
308 DevReq.Value = USB_DT_HUB << 8;\r
309 DevReq.Length = (UINT16)DescriptorSize;\r
310\r
311 return UsbIoPpi->UsbControlTransfer (\r
312 PeiServices,\r
313 UsbIoPpi,\r
314 &DevReq,\r
315 EfiUsbDataIn,\r
316 PcdGet32 (PcdUsbTransferTimeoutValue),\r
317 HubDescriptor,\r
318 (UINT16)DescriptorSize\r
319 );\r
320}\r
321\r
d987459f
SZ
322/**\r
323 Get a given SuperSpeed hub descriptor.\r
324\r
325 @param PeiServices General-purpose services that are available to every PEIM.\r
326 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
327 @param HubDescriptor Caller allocated buffer to store the hub descriptor if\r
328 successfully returned.\r
329\r
330 @retval EFI_SUCCESS Hub descriptor is obtained successfully.\r
331 @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error.\r
332 @retval Others Other failure occurs.\r
333\r
334**/\r
335EFI_STATUS\r
336PeiGetSuperSpeedHubDesc (\r
337 IN EFI_PEI_SERVICES **PeiServices,\r
338 IN PEI_USB_IO_PPI *UsbIoPpi,\r
339 OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor\r
340 )\r
341{\r
342 EFI_USB_DEVICE_REQUEST DevReq;\r
343 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
344\r
345 //\r
346 // Fill Device request packet\r
347 //\r
348 DevReq.RequestType = USB_RT_HUB | 0x80;\r
349 DevReq.Request = USB_HUB_GET_DESCRIPTOR;\r
350 DevReq.Value = USB_DT_SUPERSPEED_HUB << 8;\r
351 DevReq.Length = 12;\r
352\r
353 return UsbIoPpi->UsbControlTransfer (\r
354 PeiServices,\r
355 UsbIoPpi,\r
356 &DevReq,\r
357 EfiUsbDataIn,\r
358 PcdGet32 (PcdUsbTransferTimeoutValue),\r
359 HubDescriptor,\r
360 12\r
361 );\r
362}\r
363\r
364/**\r
365 Read the whole usb hub descriptor. It is necessary\r
366 to do it in two steps because hub descriptor is of\r
367 variable length.\r
368\r
369 @param PeiServices General-purpose services that are available to every PEIM.\r
370 @param PeiUsbDevice Indicates the hub controller device.\r
371 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
372 @param HubDescriptor Caller allocated buffer to store the hub descriptor if\r
373 successfully returned.\r
374\r
375 @retval EFI_SUCCESS Hub descriptor is obtained successfully.\r
376 @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error.\r
377 @retval Others Other failure occurs.\r
378\r
379**/\r
380EFI_STATUS\r
381PeiUsbHubReadDesc (\r
382 IN EFI_PEI_SERVICES **PeiServices,\r
383 IN PEI_USB_DEVICE *PeiUsbDevice,\r
384 IN PEI_USB_IO_PPI *UsbIoPpi,\r
385 OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor\r
386 )\r
387{\r
388 EFI_STATUS Status;\r
389\r
390 if (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
391 //\r
392 // Get the super speed hub descriptor\r
393 //\r
394 Status = PeiGetSuperSpeedHubDesc (PeiServices, UsbIoPpi, HubDescriptor);\r
395 } else {\r
396\r
397 //\r
398 // First get the hub descriptor length\r
399 //\r
400 Status = PeiGetHubDescriptor (PeiServices, UsbIoPpi, 2, HubDescriptor);\r
401\r
402 if (EFI_ERROR (Status)) {\r
403 return Status;\r
404 }\r
405\r
406 //\r
407 // Get the whole hub descriptor\r
408 //\r
409 Status = PeiGetHubDescriptor (PeiServices, UsbIoPpi, HubDescriptor->Length, HubDescriptor);\r
410 }\r
411\r
412 return Status;\r
413}\r
414\r
415/**\r
416 USB hub control transfer to set the hub depth.\r
417\r
418 @param PeiServices General-purpose services that are available to every PEIM.\r
419 @param PeiUsbDevice Indicates the hub controller device.\r
420 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
421\r
422 @retval EFI_SUCCESS Depth of the hub is set.\r
423 @retval Others Failed to set the depth.\r
424\r
425**/\r
426EFI_STATUS\r
427PeiUsbHubCtrlSetHubDepth (\r
428 IN EFI_PEI_SERVICES **PeiServices,\r
429 IN PEI_USB_DEVICE *PeiUsbDevice,\r
430 IN PEI_USB_IO_PPI *UsbIoPpi\r
431 )\r
432{\r
433 EFI_USB_DEVICE_REQUEST DevReq;\r
434 ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
435\r
436 //\r
437 // Fill Device request packet\r
438 //\r
439 DevReq.RequestType = USB_RT_HUB;\r
440 DevReq.Request = USB_HUB_REQ_SET_DEPTH;\r
441 DevReq.Value = PeiUsbDevice->Tier;\r
442 DevReq.Length = 0;\r
443\r
444 return UsbIoPpi->UsbControlTransfer (\r
445 PeiServices,\r
446 UsbIoPpi,\r
447 &DevReq,\r
448 EfiUsbNoData,\r
449 PcdGet32 (PcdUsbTransferTimeoutValue),\r
450 NULL,\r
451 0\r
452 );\r
453}\r
454\r
4b1bf81c 455/**\r
456 Configure a given hub.\r
457\r
458 @param PeiServices General-purpose services that are available to every PEIM.\r
459 @param PeiUsbDevice Indicating the hub controller device that will be configured\r
460\r
461 @retval EFI_SUCCESS Hub configuration is done successfully.\r
462 @retval EFI_DEVICE_ERROR Cannot configure the hub due to a hardware error.\r
463\r
464**/\r
465EFI_STATUS\r
466PeiDoHubConfig (\r
467 IN EFI_PEI_SERVICES **PeiServices,\r
468 IN PEI_USB_DEVICE *PeiUsbDevice\r
469 )\r
470{\r
471 EFI_USB_HUB_DESCRIPTOR HubDescriptor;\r
472 EFI_STATUS Status;\r
473 EFI_USB_HUB_STATUS HubStatus;\r
474 UINTN Index;\r
4b1bf81c 475 PEI_USB_IO_PPI *UsbIoPpi;\r
476\r
477 ZeroMem (&HubDescriptor, sizeof (HubDescriptor));\r
478 UsbIoPpi = &PeiUsbDevice->UsbIoPpi;\r
479\r
480 //\r
d987459f 481 // Get the hub descriptor \r
4b1bf81c 482 //\r
d987459f 483 Status = PeiUsbHubReadDesc (\r
4b1bf81c 484 PeiServices,\r
d987459f 485 PeiUsbDevice,\r
4b1bf81c 486 UsbIoPpi,\r
4b1bf81c 487 &HubDescriptor\r
488 );\r
489 if (EFI_ERROR (Status)) {\r
490 return EFI_DEVICE_ERROR;\r
491 }\r
492\r
493 PeiUsbDevice->DownStreamPortNo = HubDescriptor.NbrPorts;\r
494\r
d987459f
SZ
495 if (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_SUPER) {\r
496 DEBUG ((EFI_D_INFO, "PeiDoHubConfig: Set Hub Depth as 0x%x\n", PeiUsbDevice->Tier));\r
497 PeiUsbHubCtrlSetHubDepth (\r
498 PeiServices,\r
499 PeiUsbDevice,\r
500 UsbIoPpi\r
501 );\r
4b1bf81c 502 } else {\r
503 //\r
d987459f 504 // Power all the hub ports\r
4b1bf81c 505 //\r
d987459f
SZ
506 for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) {\r
507 Status = PeiHubSetPortFeature (\r
508 PeiServices,\r
509 UsbIoPpi,\r
510 (UINT8) (Index + 1),\r
511 EfiUsbPortPower\r
512 );\r
513 if (EFI_ERROR (Status)) {\r
514 DEBUG (( EFI_D_ERROR, "PeiDoHubConfig: PeiHubSetPortFeature EfiUsbPortPower failed %x\n", Index));\r
515 continue;\r
516 }\r
4b1bf81c 517 }\r
d987459f
SZ
518\r
519 DEBUG (( EFI_D_INFO, "PeiDoHubConfig: HubDescriptor.PwrOn2PwrGood: 0x%x\n", HubDescriptor.PwrOn2PwrGood));\r
520 if (HubDescriptor.PwrOn2PwrGood > 0) {\r
521 MicroSecondDelay (HubDescriptor.PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);\r
522 }\r
523\r
4b1bf81c 524 //\r
d987459f 525 // Clear Hub Status Change\r
4b1bf81c 526 //\r
d987459f
SZ
527 Status = PeiHubGetHubStatus (\r
528 PeiServices,\r
529 UsbIoPpi,\r
530 (UINT32 *) &HubStatus\r
531 );\r
532 if (EFI_ERROR (Status)) {\r
533 return EFI_DEVICE_ERROR;\r
534 } else {\r
535 //\r
536 // Hub power supply change happens\r
537 //\r
538 if ((HubStatus.HubChangeStatus & HUB_CHANGE_LOCAL_POWER) != 0) {\r
539 PeiHubClearHubFeature (\r
540 PeiServices,\r
541 UsbIoPpi,\r
542 C_HUB_LOCAL_POWER\r
543 );\r
544 }\r
545 //\r
546 // Hub change overcurrent happens\r
547 //\r
548 if ((HubStatus.HubChangeStatus & HUB_CHANGE_OVERCURRENT) != 0) {\r
549 PeiHubClearHubFeature (\r
550 PeiServices,\r
551 UsbIoPpi,\r
552 C_HUB_OVER_CURRENT\r
553 );\r
554 }\r
4b1bf81c 555 }\r
556 }\r
557\r
558 return EFI_SUCCESS;\r
559}\r
560\r
561/**\r
562 Send reset signal over the given root hub port.\r
563\r
564 @param PeiServices General-purpose services that are available to every PEIM.\r
565 @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.\r
566 @param PortNum Usb hub port number (starting from 1).\r
567\r
568**/\r
569VOID\r
570PeiResetHubPort (\r
571 IN EFI_PEI_SERVICES **PeiServices,\r
572 IN PEI_USB_IO_PPI *UsbIoPpi,\r
573 IN UINT8 PortNum\r
574 )\r
575{\r
d987459f
SZ
576 EFI_STATUS Status;\r
577 UINTN Index;\r
4b1bf81c 578 EFI_USB_PORT_STATUS HubPortStatus;\r
579\r
4b1bf81c 580 MicroSecondDelay (100 * 1000);\r
581\r
582 //\r
583 // reset root port\r
584 //\r
585 PeiHubSetPortFeature (\r
586 PeiServices,\r
587 UsbIoPpi,\r
588 PortNum,\r
589 EfiUsbPortReset\r
590 );\r
591\r
d987459f
SZ
592 //\r
593 // Drive the reset signal for worst 20ms. Check USB 2.0 Spec\r
594 // section 7.1.7.5 for timing requirements.\r
595 //\r
596 MicroSecondDelay (USB_SET_PORT_RESET_STALL);\r
4b1bf81c 597\r
d987459f
SZ
598 //\r
599 // Check USB_PORT_STAT_C_RESET bit to see if the resetting state is done.\r
600 //\r
601 ZeroMem (&HubPortStatus, sizeof (EFI_USB_PORT_STATUS));\r
602\r
603 for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {\r
604 Status = PeiHubGetPortStatus (\r
605 PeiServices,\r
606 UsbIoPpi,\r
607 PortNum,\r
608 (UINT32 *) &HubPortStatus\r
609 );\r
610\r
611 if (EFI_ERROR (Status)) {\r
612 return;\r
613 }\r
614\r
615 if (USB_BIT_IS_SET (HubPortStatus.PortChangeStatus, USB_PORT_STAT_C_RESET)) {\r
616 break;\r
617 }\r
618\r
619 MicroSecondDelay (USB_WAIT_PORT_STS_CHANGE_STALL);\r
620 }\r
621\r
622 if (Index == USB_WAIT_PORT_STS_CHANGE_LOOP) {\r
623 DEBUG ((EFI_D_ERROR, "PeiResetHubPort: reset not finished in time on port %d\n", PortNum));\r
624 return;\r
625 }\r
4b1bf81c 626\r
627 //\r
d987459f 628 // clear reset change root port\r
4b1bf81c 629 //\r
630 PeiHubClearPortFeature (\r
631 PeiServices,\r
632 UsbIoPpi,\r
633 PortNum,\r
d987459f 634 EfiUsbPortResetChange\r
4b1bf81c 635 );\r
636\r
637 MicroSecondDelay (1 * 1000);\r
638\r
639 PeiHubClearPortFeature (\r
640 PeiServices,\r
641 UsbIoPpi,\r
642 PortNum,\r
643 EfiUsbPortConnectChange\r
644 );\r
645\r
646 //\r
647 // Set port enable\r
648 //\r
649 PeiHubSetPortFeature (\r
650 PeiServices,\r
651 UsbIoPpi,\r
652 PortNum,\r
653 EfiUsbPortEnable\r
654 );\r
655\r
656 //\r
657 // Clear any change status\r
658 //\r
659\r
660 PeiHubClearPortFeature (\r
661 PeiServices,\r
662 UsbIoPpi,\r
663 PortNum,\r
664 EfiUsbPortEnableChange\r
665 );\r
666\r
667 MicroSecondDelay (10 * 1000);\r
668\r
669 return;\r
670}\r