/src/edk2/MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c
Line | Count | Source |
1 | | /** @file |
2 | | Usb Hub Request Support In PEI Phase |
3 | | |
4 | | Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> |
5 | | |
6 | | SPDX-License-Identifier: BSD-2-Clause-Patent |
7 | | |
8 | | **/ |
9 | | |
10 | | #include "UsbPeim.h" |
11 | | #include "HubPeim.h" |
12 | | #include "PeiUsbLib.h" |
13 | | |
14 | | /** |
15 | | Get a given hub port status. |
16 | | |
17 | | @param PeiServices General-purpose services that are available to every PEIM. |
18 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
19 | | @param Port Usb hub port number (starting from 1). |
20 | | @param PortStatus Current Hub port status and change status. |
21 | | |
22 | | @retval EFI_SUCCESS Port status is obtained successfully. |
23 | | @retval EFI_DEVICE_ERROR Cannot get the port status due to a hardware error. |
24 | | @retval Others Other failure occurs. |
25 | | |
26 | | **/ |
27 | | EFI_STATUS |
28 | | PeiHubGetPortStatus ( |
29 | | IN EFI_PEI_SERVICES **PeiServices, |
30 | | IN PEI_USB_IO_PPI *UsbIoPpi, |
31 | | IN UINT8 Port, |
32 | | OUT UINT32 *PortStatus |
33 | | ) |
34 | 0 | { |
35 | 0 | EFI_USB_DEVICE_REQUEST DeviceRequest; |
36 | |
|
37 | 0 | ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); |
38 | | |
39 | | // |
40 | | // Fill Device request packet |
41 | | // |
42 | 0 | DeviceRequest.RequestType = USB_HUB_GET_PORT_STATUS_REQ_TYPE; |
43 | 0 | DeviceRequest.Request = USB_HUB_GET_PORT_STATUS; |
44 | 0 | DeviceRequest.Index = Port; |
45 | 0 | DeviceRequest.Length = (UINT16)sizeof (UINT32); |
46 | |
|
47 | 0 | return UsbIoPpi->UsbControlTransfer ( |
48 | 0 | PeiServices, |
49 | 0 | UsbIoPpi, |
50 | 0 | &DeviceRequest, |
51 | 0 | EfiUsbDataIn, |
52 | 0 | PcdGet32 (PcdUsbTransferTimeoutValue), |
53 | 0 | PortStatus, |
54 | 0 | sizeof (UINT32) |
55 | 0 | ); |
56 | 0 | } |
57 | | |
58 | | /** |
59 | | Set specified feature to a given hub port. |
60 | | |
61 | | @param PeiServices General-purpose services that are available to every PEIM. |
62 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
63 | | @param Port Usb hub port number (starting from 1). |
64 | | @param Value New feature value. |
65 | | |
66 | | @retval EFI_SUCCESS Port feature is set successfully. |
67 | | @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error. |
68 | | @retval Others Other failure occurs. |
69 | | |
70 | | **/ |
71 | | EFI_STATUS |
72 | | PeiHubSetPortFeature ( |
73 | | IN EFI_PEI_SERVICES **PeiServices, |
74 | | IN PEI_USB_IO_PPI *UsbIoPpi, |
75 | | IN UINT8 Port, |
76 | | IN UINT8 Value |
77 | | ) |
78 | 0 | { |
79 | 0 | EFI_USB_DEVICE_REQUEST DeviceRequest; |
80 | |
|
81 | 0 | ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); |
82 | | |
83 | | // |
84 | | // Fill Device request packet |
85 | | // |
86 | 0 | DeviceRequest.RequestType = USB_HUB_SET_PORT_FEATURE_REQ_TYPE; |
87 | 0 | DeviceRequest.Request = USB_HUB_SET_PORT_FEATURE; |
88 | 0 | DeviceRequest.Value = Value; |
89 | 0 | DeviceRequest.Index = Port; |
90 | |
|
91 | 0 | return UsbIoPpi->UsbControlTransfer ( |
92 | 0 | PeiServices, |
93 | 0 | UsbIoPpi, |
94 | 0 | &DeviceRequest, |
95 | 0 | EfiUsbNoData, |
96 | 0 | PcdGet32 (PcdUsbTransferTimeoutValue), |
97 | 0 | NULL, |
98 | 0 | 0 |
99 | 0 | ); |
100 | 0 | } |
101 | | |
102 | | /** |
103 | | Clear specified feature on a given hub port. |
104 | | |
105 | | @param PeiServices General-purpose services that are available to every PEIM. |
106 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
107 | | @param Port Usb hub port number (starting from 1). |
108 | | @param Value Feature value that will be cleared from the hub port. |
109 | | |
110 | | @retval EFI_SUCCESS Port feature is cleared successfully. |
111 | | @retval EFI_DEVICE_ERROR Cannot clear the port feature due to a hardware error. |
112 | | @retval Others Other failure occurs. |
113 | | |
114 | | **/ |
115 | | EFI_STATUS |
116 | | PeiHubClearPortFeature ( |
117 | | IN EFI_PEI_SERVICES **PeiServices, |
118 | | IN PEI_USB_IO_PPI *UsbIoPpi, |
119 | | IN UINT8 Port, |
120 | | IN UINT8 Value |
121 | | ) |
122 | 0 | { |
123 | 0 | EFI_USB_DEVICE_REQUEST DeviceRequest; |
124 | |
|
125 | 0 | ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); |
126 | | |
127 | | // |
128 | | // Fill Device request packet |
129 | | // |
130 | 0 | DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_PORT_REQ_TYPE; |
131 | 0 | DeviceRequest.Request = USB_HUB_CLEAR_FEATURE_PORT; |
132 | 0 | DeviceRequest.Value = Value; |
133 | 0 | DeviceRequest.Index = Port; |
134 | |
|
135 | 0 | return UsbIoPpi->UsbControlTransfer ( |
136 | 0 | PeiServices, |
137 | 0 | UsbIoPpi, |
138 | 0 | &DeviceRequest, |
139 | 0 | EfiUsbNoData, |
140 | 0 | PcdGet32 (PcdUsbTransferTimeoutValue), |
141 | 0 | NULL, |
142 | 0 | 0 |
143 | 0 | ); |
144 | 0 | } |
145 | | |
146 | | /** |
147 | | Get a given hub status. |
148 | | |
149 | | @param PeiServices General-purpose services that are available to every PEIM. |
150 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
151 | | @param HubStatus Current Hub status and change status. |
152 | | |
153 | | @retval EFI_SUCCESS Hub status is obtained successfully. |
154 | | @retval EFI_DEVICE_ERROR Cannot get the hub status due to a hardware error. |
155 | | @retval Others Other failure occurs. |
156 | | |
157 | | **/ |
158 | | EFI_STATUS |
159 | | PeiHubGetHubStatus ( |
160 | | IN EFI_PEI_SERVICES **PeiServices, |
161 | | IN PEI_USB_IO_PPI *UsbIoPpi, |
162 | | OUT UINT32 *HubStatus |
163 | | ) |
164 | 0 | { |
165 | 0 | EFI_USB_DEVICE_REQUEST DeviceRequest; |
166 | |
|
167 | 0 | ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); |
168 | | |
169 | | // |
170 | | // Fill Device request packet |
171 | | // |
172 | 0 | DeviceRequest.RequestType = USB_HUB_GET_HUB_STATUS_REQ_TYPE; |
173 | 0 | DeviceRequest.Request = USB_HUB_GET_HUB_STATUS; |
174 | 0 | DeviceRequest.Length = (UINT16)sizeof (UINT32); |
175 | |
|
176 | 0 | return UsbIoPpi->UsbControlTransfer ( |
177 | 0 | PeiServices, |
178 | 0 | UsbIoPpi, |
179 | 0 | &DeviceRequest, |
180 | 0 | EfiUsbDataIn, |
181 | 0 | PcdGet32 (PcdUsbTransferTimeoutValue), |
182 | 0 | HubStatus, |
183 | 0 | sizeof (UINT32) |
184 | 0 | ); |
185 | 0 | } |
186 | | |
187 | | /** |
188 | | Clear specified feature on a given hub. |
189 | | |
190 | | @param PeiServices General-purpose services that are available to every PEIM. |
191 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
192 | | @param Value Feature value that will be cleared from the hub port. |
193 | | |
194 | | @retval EFI_SUCCESS Hub feature is cleared successfully. |
195 | | @retval EFI_DEVICE_ERROR Cannot clear the hub feature due to a hardware error. |
196 | | @retval Others Other failure occurs. |
197 | | |
198 | | **/ |
199 | | EFI_STATUS |
200 | | PeiHubClearHubFeature ( |
201 | | IN EFI_PEI_SERVICES **PeiServices, |
202 | | IN PEI_USB_IO_PPI *UsbIoPpi, |
203 | | IN UINT8 Value |
204 | | ) |
205 | 0 | { |
206 | 0 | EFI_USB_DEVICE_REQUEST DeviceRequest; |
207 | |
|
208 | 0 | ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); |
209 | | |
210 | | // |
211 | | // Fill Device request packet |
212 | | // |
213 | 0 | DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_REQ_TYPE; |
214 | 0 | DeviceRequest.Request = USB_HUB_CLEAR_FEATURE; |
215 | 0 | DeviceRequest.Value = Value; |
216 | |
|
217 | 0 | return UsbIoPpi->UsbControlTransfer ( |
218 | 0 | PeiServices, |
219 | 0 | UsbIoPpi, |
220 | 0 | &DeviceRequest, |
221 | 0 | EfiUsbNoData, |
222 | 0 | PcdGet32 (PcdUsbTransferTimeoutValue), |
223 | 0 | NULL, |
224 | 0 | 0 |
225 | 0 | ); |
226 | 0 | } |
227 | | |
228 | | /** |
229 | | Get a given (SuperSpeed) hub descriptor. |
230 | | |
231 | | @param PeiServices General-purpose services that are available to every PEIM. |
232 | | @param PeiUsbDevice Indicates the hub controller device. |
233 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
234 | | @param DescriptorSize The length of Hub Descriptor buffer. |
235 | | @param HubDescriptor Caller allocated buffer to store the hub descriptor if |
236 | | successfully returned. |
237 | | |
238 | | @retval EFI_SUCCESS Hub descriptor is obtained successfully. |
239 | | @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error. |
240 | | @retval Others Other failure occurs. |
241 | | |
242 | | **/ |
243 | | EFI_STATUS |
244 | | PeiGetHubDescriptor ( |
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 | 0 | { |
252 | 0 | EFI_USB_DEVICE_REQUEST DevReq; |
253 | 0 | UINT8 DescType; |
254 | |
|
255 | 0 | ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); |
256 | |
|
257 | 0 | DescType = (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_SUPER) ? |
258 | 0 | USB_DT_SUPERSPEED_HUB : |
259 | 0 | USB_DT_HUB; |
260 | | |
261 | | // |
262 | | // Fill Device request packet |
263 | | // |
264 | 0 | DevReq.RequestType = USB_RT_HUB | 0x80; |
265 | 0 | DevReq.Request = USB_HUB_GET_DESCRIPTOR; |
266 | 0 | DevReq.Value = (UINT16)(DescType << 8); |
267 | 0 | DevReq.Length = (UINT16)DescriptorSize; |
268 | |
|
269 | 0 | return UsbIoPpi->UsbControlTransfer ( |
270 | 0 | PeiServices, |
271 | 0 | UsbIoPpi, |
272 | 0 | &DevReq, |
273 | 0 | EfiUsbDataIn, |
274 | 0 | PcdGet32 (PcdUsbTransferTimeoutValue), |
275 | 0 | HubDescriptor, |
276 | 0 | (UINT16)DescriptorSize |
277 | 0 | ); |
278 | 0 | } |
279 | | |
280 | | /** |
281 | | Read the whole usb hub descriptor. It is necessary |
282 | | to do it in two steps because hub descriptor is of |
283 | | variable length. |
284 | | |
285 | | @param PeiServices General-purpose services that are available to every PEIM. |
286 | | @param PeiUsbDevice Indicates the hub controller device. |
287 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
288 | | @param HubDescriptor Caller allocated buffer to store the hub descriptor if |
289 | | successfully returned. |
290 | | |
291 | | @retval EFI_SUCCESS Hub descriptor is obtained successfully. |
292 | | @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error. |
293 | | @retval Others Other failure occurs. |
294 | | |
295 | | **/ |
296 | | EFI_STATUS |
297 | | PeiUsbHubReadDesc ( |
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 | 0 | { |
304 | 0 | EFI_STATUS Status; |
305 | | |
306 | | // |
307 | | // First get the hub descriptor length |
308 | | // |
309 | 0 | Status = PeiGetHubDescriptor (PeiServices, PeiUsbDevice, UsbIoPpi, 2, HubDescriptor); |
310 | |
|
311 | 0 | if (EFI_ERROR (Status)) { |
312 | 0 | return Status; |
313 | 0 | } |
314 | | |
315 | | // |
316 | | // Get the whole hub descriptor |
317 | | // |
318 | 0 | return PeiGetHubDescriptor (PeiServices, PeiUsbDevice, UsbIoPpi, HubDescriptor->Length, HubDescriptor); |
319 | 0 | } |
320 | | |
321 | | /** |
322 | | USB hub control transfer to set the hub depth. |
323 | | |
324 | | @param PeiServices General-purpose services that are available to every PEIM. |
325 | | @param PeiUsbDevice Indicates the hub controller device. |
326 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
327 | | |
328 | | @retval EFI_SUCCESS Depth of the hub is set. |
329 | | @retval Others Failed to set the depth. |
330 | | |
331 | | **/ |
332 | | EFI_STATUS |
333 | | PeiUsbHubCtrlSetHubDepth ( |
334 | | IN EFI_PEI_SERVICES **PeiServices, |
335 | | IN PEI_USB_DEVICE *PeiUsbDevice, |
336 | | IN PEI_USB_IO_PPI *UsbIoPpi |
337 | | ) |
338 | 0 | { |
339 | 0 | EFI_USB_DEVICE_REQUEST DevReq; |
340 | |
|
341 | 0 | ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); |
342 | | |
343 | | // |
344 | | // Fill Device request packet |
345 | | // |
346 | 0 | DevReq.RequestType = USB_RT_HUB; |
347 | 0 | DevReq.Request = USB_HUB_REQ_SET_DEPTH; |
348 | 0 | DevReq.Value = PeiUsbDevice->Tier; |
349 | 0 | DevReq.Length = 0; |
350 | |
|
351 | 0 | return UsbIoPpi->UsbControlTransfer ( |
352 | 0 | PeiServices, |
353 | 0 | UsbIoPpi, |
354 | 0 | &DevReq, |
355 | 0 | EfiUsbNoData, |
356 | 0 | PcdGet32 (PcdUsbTransferTimeoutValue), |
357 | 0 | NULL, |
358 | 0 | 0 |
359 | 0 | ); |
360 | 0 | } |
361 | | |
362 | | /** |
363 | | Configure a given hub. |
364 | | |
365 | | @param PeiServices General-purpose services that are available to every PEIM. |
366 | | @param PeiUsbDevice Indicating the hub controller device that will be configured |
367 | | |
368 | | @retval EFI_SUCCESS Hub configuration is done successfully. |
369 | | @retval EFI_DEVICE_ERROR Cannot configure the hub due to a hardware error. |
370 | | |
371 | | **/ |
372 | | EFI_STATUS |
373 | | PeiDoHubConfig ( |
374 | | IN EFI_PEI_SERVICES **PeiServices, |
375 | | IN PEI_USB_DEVICE *PeiUsbDevice |
376 | | ) |
377 | 0 | { |
378 | 0 | UINT8 HubDescBuffer[256]; |
379 | 0 | EFI_USB_HUB_DESCRIPTOR *HubDescriptor; |
380 | 0 | EFI_STATUS Status; |
381 | 0 | EFI_USB_HUB_STATUS HubStatus; |
382 | 0 | UINTN Index; |
383 | 0 | PEI_USB_IO_PPI *UsbIoPpi; |
384 | |
|
385 | 0 | 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 | 0 | HubDescriptor = (EFI_USB_HUB_DESCRIPTOR *)HubDescBuffer; |
392 | | |
393 | | // |
394 | | // Get the hub descriptor |
395 | | // |
396 | 0 | Status = PeiUsbHubReadDesc ( |
397 | 0 | PeiServices, |
398 | 0 | PeiUsbDevice, |
399 | 0 | UsbIoPpi, |
400 | 0 | HubDescriptor |
401 | 0 | ); |
402 | 0 | if (EFI_ERROR (Status)) { |
403 | 0 | return EFI_DEVICE_ERROR; |
404 | 0 | } |
405 | | |
406 | 0 | PeiUsbDevice->DownStreamPortNo = HubDescriptor->NbrPorts; |
407 | |
|
408 | 0 | if (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_SUPER) { |
409 | 0 | DEBUG ((DEBUG_INFO, "PeiDoHubConfig: Set Hub Depth as 0x%x\n", PeiUsbDevice->Tier)); |
410 | 0 | PeiUsbHubCtrlSetHubDepth ( |
411 | 0 | PeiServices, |
412 | 0 | PeiUsbDevice, |
413 | 0 | UsbIoPpi |
414 | 0 | ); |
415 | 0 | } else { |
416 | | // |
417 | | // Power all the hub ports |
418 | | // |
419 | 0 | for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) { |
420 | 0 | Status = PeiHubSetPortFeature ( |
421 | 0 | PeiServices, |
422 | 0 | UsbIoPpi, |
423 | 0 | (UINT8)(Index + 1), |
424 | 0 | EfiUsbPortPower |
425 | 0 | ); |
426 | 0 | if (EFI_ERROR (Status)) { |
427 | 0 | DEBUG ((DEBUG_ERROR, "PeiDoHubConfig: PeiHubSetPortFeature EfiUsbPortPower failed %x\n", Index)); |
428 | 0 | continue; |
429 | 0 | } |
430 | 0 | } |
431 | |
|
432 | 0 | DEBUG ((DEBUG_INFO, "PeiDoHubConfig: HubDescriptor.PwrOn2PwrGood: 0x%x\n", HubDescriptor->PwrOn2PwrGood)); |
433 | 0 | if (HubDescriptor->PwrOn2PwrGood > 0) { |
434 | 0 | MicroSecondDelay (HubDescriptor->PwrOn2PwrGood * USB_SET_PORT_POWER_STALL); |
435 | 0 | } |
436 | | |
437 | | // |
438 | | // Clear Hub Status Change |
439 | | // |
440 | 0 | Status = PeiHubGetHubStatus ( |
441 | 0 | PeiServices, |
442 | 0 | UsbIoPpi, |
443 | 0 | (UINT32 *)&HubStatus |
444 | 0 | ); |
445 | 0 | if (EFI_ERROR (Status)) { |
446 | 0 | return EFI_DEVICE_ERROR; |
447 | 0 | } else { |
448 | | // |
449 | | // Hub power supply change happens |
450 | | // |
451 | 0 | if ((HubStatus.HubChangeStatus & HUB_CHANGE_LOCAL_POWER) != 0) { |
452 | 0 | PeiHubClearHubFeature ( |
453 | 0 | PeiServices, |
454 | 0 | UsbIoPpi, |
455 | 0 | C_HUB_LOCAL_POWER |
456 | 0 | ); |
457 | 0 | } |
458 | | |
459 | | // |
460 | | // Hub change overcurrent happens |
461 | | // |
462 | 0 | if ((HubStatus.HubChangeStatus & HUB_CHANGE_OVERCURRENT) != 0) { |
463 | 0 | PeiHubClearHubFeature ( |
464 | 0 | PeiServices, |
465 | 0 | UsbIoPpi, |
466 | 0 | C_HUB_OVER_CURRENT |
467 | 0 | ); |
468 | 0 | } |
469 | 0 | } |
470 | 0 | } |
471 | | |
472 | 0 | return EFI_SUCCESS; |
473 | 0 | } |
474 | | |
475 | | /** |
476 | | Send reset signal over the given root hub port. |
477 | | |
478 | | @param PeiServices General-purpose services that are available to every PEIM. |
479 | | @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. |
480 | | @param PortNum Usb hub port number (starting from 1). |
481 | | |
482 | | **/ |
483 | | VOID |
484 | | PeiResetHubPort ( |
485 | | IN EFI_PEI_SERVICES **PeiServices, |
486 | | IN PEI_USB_IO_PPI *UsbIoPpi, |
487 | | IN UINT8 PortNum |
488 | | ) |
489 | 0 | { |
490 | 0 | EFI_STATUS Status; |
491 | 0 | UINTN Index; |
492 | 0 | EFI_USB_PORT_STATUS HubPortStatus; |
493 | |
|
494 | 0 | MicroSecondDelay (100 * 1000); |
495 | | |
496 | | // |
497 | | // reset root port |
498 | | // |
499 | 0 | PeiHubSetPortFeature ( |
500 | 0 | PeiServices, |
501 | 0 | UsbIoPpi, |
502 | 0 | PortNum, |
503 | 0 | EfiUsbPortReset |
504 | 0 | ); |
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 | 0 | 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 | 0 | ZeroMem (&HubPortStatus, sizeof (EFI_USB_PORT_STATUS)); |
516 | |
|
517 | 0 | for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) { |
518 | 0 | Status = PeiHubGetPortStatus ( |
519 | 0 | PeiServices, |
520 | 0 | UsbIoPpi, |
521 | 0 | PortNum, |
522 | 0 | (UINT32 *)&HubPortStatus |
523 | 0 | ); |
524 | |
|
525 | 0 | if (EFI_ERROR (Status)) { |
526 | 0 | return; |
527 | 0 | } |
528 | | |
529 | 0 | if (USB_BIT_IS_SET (HubPortStatus.PortChangeStatus, USB_PORT_STAT_C_RESET)) { |
530 | 0 | break; |
531 | 0 | } |
532 | | |
533 | 0 | MicroSecondDelay (USB_WAIT_PORT_STS_CHANGE_STALL); |
534 | 0 | } |
535 | | |
536 | 0 | if (Index == USB_WAIT_PORT_STS_CHANGE_LOOP) { |
537 | 0 | DEBUG ((DEBUG_ERROR, "PeiResetHubPort: reset not finished in time on port %d\n", PortNum)); |
538 | 0 | return; |
539 | 0 | } |
540 | | |
541 | | // |
542 | | // clear reset change root port |
543 | | // |
544 | 0 | PeiHubClearPortFeature ( |
545 | 0 | PeiServices, |
546 | 0 | UsbIoPpi, |
547 | 0 | PortNum, |
548 | 0 | EfiUsbPortResetChange |
549 | 0 | ); |
550 | |
|
551 | 0 | MicroSecondDelay (1 * 1000); |
552 | |
|
553 | 0 | PeiHubClearPortFeature ( |
554 | 0 | PeiServices, |
555 | 0 | UsbIoPpi, |
556 | 0 | PortNum, |
557 | 0 | EfiUsbPortConnectChange |
558 | 0 | ); |
559 | | |
560 | | // |
561 | | // Set port enable |
562 | | // |
563 | 0 | PeiHubSetPortFeature ( |
564 | 0 | PeiServices, |
565 | 0 | UsbIoPpi, |
566 | 0 | PortNum, |
567 | 0 | EfiUsbPortEnable |
568 | 0 | ); |
569 | | |
570 | | // |
571 | | // Clear any change status |
572 | | // |
573 | |
|
574 | 0 | PeiHubClearPortFeature ( |
575 | 0 | PeiServices, |
576 | 0 | UsbIoPpi, |
577 | 0 | PortNum, |
578 | 0 | EfiUsbPortEnableChange |
579 | 0 | ); |
580 | |
|
581 | 0 | MicroSecondDelay (10 * 1000); |
582 | |
|
583 | 0 | return; |
584 | 0 | } |