]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.c
MdeMdeModulePkg/Usb: Coding style alignment
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / EhciPei / EhcPeim.c
CommitLineData
4b1bf81c 1/** @file\r
2PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
3which is used to enable recovery function from USB Drivers.\r
4\r
5Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
6 \r
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions\r
9of the BSD License which accompanies this distribution. The\r
10full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12\r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include "EhcPeim.h"\r
19\r
20//\r
21// Two arrays used to translate the EHCI port state (change)\r
22// to the UEFI protocol's port state (change).\r
23//\r
24USB_PORT_STATE_MAP mUsbPortStateMap[] = {\r
25 {PORTSC_CONN, USB_PORT_STAT_CONNECTION},\r
26 {PORTSC_ENABLED, USB_PORT_STAT_ENABLE},\r
27 {PORTSC_SUSPEND, USB_PORT_STAT_SUSPEND},\r
28 {PORTSC_OVERCUR, USB_PORT_STAT_OVERCURRENT},\r
29 {PORTSC_RESET, USB_PORT_STAT_RESET},\r
30 {PORTSC_POWER, USB_PORT_STAT_POWER},\r
31 {PORTSC_OWNER, USB_PORT_STAT_OWNER}\r
32};\r
33\r
34USB_PORT_STATE_MAP mUsbPortChangeMap[] = {\r
35 {PORTSC_CONN_CHANGE, USB_PORT_STAT_C_CONNECTION},\r
36 {PORTSC_ENABLE_CHANGE, USB_PORT_STAT_C_ENABLE},\r
37 {PORTSC_OVERCUR_CHANGE, USB_PORT_STAT_C_OVERCURRENT}\r
38};\r
39\r
40/**\r
41 Read Ehc Operation register.\r
42 \r
43 @param Ehc The EHCI device.\r
44 @param Offset The operation register offset.\r
45\r
46 @retval the register content read.\r
47\r
48**/\r
49UINT32\r
50EhcReadOpReg (\r
51 IN PEI_USB2_HC_DEV *Ehc,\r
52 IN UINT32 Offset\r
53 )\r
54{\r
55 UINT32 Data;\r
56 \r
57 ASSERT (Ehc->CapLen != 0);\r
58\r
59 Data = MmioRead32 (Ehc->UsbHostControllerBaseAddress + Ehc->CapLen + Offset);\r
60 \r
61 return Data;\r
62}\r
63\r
64/**\r
65 Write the data to the EHCI operation register.\r
66 \r
67 @param Ehc The EHCI device.\r
68 @param Offset EHCI operation register offset.\r
69 @param Data The data to write.\r
70\r
71**/\r
72VOID\r
73EhcWriteOpReg (\r
74 IN PEI_USB2_HC_DEV *Ehc,\r
75 IN UINT32 Offset,\r
76 IN UINT32 Data\r
77 )\r
78{\r
79\r
80 ASSERT (Ehc->CapLen != 0);\r
81\r
82 MmioWrite32(Ehc->UsbHostControllerBaseAddress + Ehc->CapLen + Offset, Data);\r
83\r
84}\r
85\r
86/**\r
87 Set one bit of the operational register while keeping other bits.\r
88 \r
89 @param Ehc The EHCI device.\r
90 @param Offset The offset of the operational register.\r
91 @param Bit The bit mask of the register to set.\r
92\r
93**/\r
94VOID\r
95EhcSetOpRegBit (\r
96 IN PEI_USB2_HC_DEV *Ehc,\r
97 IN UINT32 Offset,\r
98 IN UINT32 Bit\r
99 )\r
100{\r
101 UINT32 Data;\r
102\r
103 Data = EhcReadOpReg (Ehc, Offset);\r
104 Data |= Bit;\r
105 EhcWriteOpReg (Ehc, Offset, Data);\r
106}\r
107\r
108/**\r
109 Clear one bit of the operational register while keeping other bits.\r
110 \r
111 @param Ehc The EHCI device.\r
112 @param Offset The offset of the operational register.\r
113 @param Bit The bit mask of the register to clear.\r
114\r
115**/\r
116VOID\r
117EhcClearOpRegBit (\r
118 IN PEI_USB2_HC_DEV *Ehc,\r
119 IN UINT32 Offset,\r
120 IN UINT32 Bit\r
121 )\r
122{\r
123 UINT32 Data;\r
124\r
125 Data = EhcReadOpReg (Ehc, Offset);\r
126 Data &= ~Bit;\r
127 EhcWriteOpReg (Ehc, Offset, Data);\r
128}\r
129\r
130/**\r
131 Wait the operation register's bit as specified by Bit \r
132 to become set (or clear).\r
133 \r
134 @param Ehc The EHCI device.\r
135 @param Offset The offset of the operational register.\r
136 @param Bit The bit mask of the register to wait for.\r
137 @param WaitToSet Wait the bit to set or clear.\r
138 @param Timeout The time to wait before abort (in millisecond).\r
139\r
140 @retval EFI_SUCCESS The bit successfully changed by host controller.\r
141 @retval EFI_TIMEOUT The time out occurred.\r
142\r
143**/\r
144EFI_STATUS\r
145EhcWaitOpRegBit (\r
146 IN PEI_USB2_HC_DEV *Ehc,\r
147 IN UINT32 Offset,\r
148 IN UINT32 Bit,\r
149 IN BOOLEAN WaitToSet,\r
150 IN UINT32 Timeout\r
151 )\r
152{\r
153 UINT32 Index;\r
154\r
155 for (Index = 0; Index < Timeout / EHC_SYNC_POLL_INTERVAL + 1; Index++) {\r
156 if (EHC_REG_BIT_IS_SET (Ehc, Offset, Bit) == WaitToSet) {\r
157 return EFI_SUCCESS;\r
158 }\r
159\r
160 MicroSecondDelay (EHC_SYNC_POLL_INTERVAL);\r
161 }\r
162\r
163 return EFI_TIMEOUT;\r
164}\r
165\r
166/**\r
167 Read EHCI capability register.\r
168 \r
169 @param Ehc The EHCI device.\r
170 @param Offset Capability register address.\r
171\r
172 @retval the register content read.\r
173\r
174**/\r
175UINT32\r
176EhcReadCapRegister (\r
177 IN PEI_USB2_HC_DEV *Ehc,\r
178 IN UINT32 Offset\r
179 )\r
180{\r
181 UINT32 Data;\r
182 \r
183 Data = MmioRead32(Ehc->UsbHostControllerBaseAddress + Offset);\r
184 \r
185 return Data;\r
186}\r
187\r
188/**\r
189 Set door bell and wait it to be ACKed by host controller.\r
190 This function is used to synchronize with the hardware.\r
191 \r
192 @param Ehc The EHCI device.\r
193 @param Timeout The time to wait before abort (in millisecond, ms).\r
194\r
195 @retval EFI_TIMEOUT Time out happened while waiting door bell to set.\r
196 @retval EFI_SUCCESS Synchronized with the hardware.\r
197\r
198**/\r
199EFI_STATUS\r
200EhcSetAndWaitDoorBell (\r
201 IN PEI_USB2_HC_DEV *Ehc,\r
202 IN UINT32 Timeout\r
203 )\r
204{\r
205 EFI_STATUS Status;\r
206 UINT32 Data;\r
207\r
208 EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_IAAD);\r
209\r
210 Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_IAA, TRUE, Timeout);\r
211\r
212 //\r
213 // ACK the IAA bit in USBSTS register. Make sure other\r
214 // interrupt bits are not ACKed. These bits are WC (Write Clean).\r
215 //\r
216 Data = EhcReadOpReg (Ehc, EHC_USBSTS_OFFSET);\r
217 Data &= ~USBSTS_INTACK_MASK;\r
218 Data |= USBSTS_IAA;\r
219\r
220 EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, Data);\r
221\r
222 return Status;\r
223}\r
224\r
225/**\r
226 Clear all the interrutp status bits, these bits \r
227 are Write-Clean.\r
228 \r
229 @param Ehc The EHCI device.\r
230\r
231**/\r
232VOID\r
233EhcAckAllInterrupt (\r
234 IN PEI_USB2_HC_DEV *Ehc\r
235 )\r
236{\r
237 EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, USBSTS_INTACK_MASK);\r
238}\r
239\r
240/**\r
241 Enable the periodic schedule then wait EHC to \r
242 actually enable it.\r
243 \r
244 @param Ehc The EHCI device.\r
245 @param Timeout The time to wait before abort (in millisecond, ms).\r
246\r
247 @retval EFI_TIMEOUT Time out happened while enabling periodic schedule.\r
248 @retval EFI_SUCCESS The periodical schedule is enabled.\r
249\r
250**/\r
251EFI_STATUS\r
252EhcEnablePeriodSchd (\r
253 IN PEI_USB2_HC_DEV *Ehc,\r
254 IN UINT32 Timeout\r
255 )\r
256{\r
257 EFI_STATUS Status;\r
258\r
259 EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_PERIOD);\r
260\r
261 Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_PERIOD_ENABLED, TRUE, Timeout);\r
262 return Status;\r
263}\r
264\r
265/**\r
266 Enable asynchrounous schedule.\r
267 \r
268 @param Ehc The EHCI device.\r
269 @param Timeout Time to wait before abort.\r
270\r
271 @retval EFI_SUCCESS The EHCI asynchronous schedule is enabled.\r
272 @retval Others Failed to enable the asynchronous scheudle.\r
273\r
274**/\r
275EFI_STATUS\r
276EhcEnableAsyncSchd (\r
277 IN PEI_USB2_HC_DEV *Ehc,\r
278 IN UINT32 Timeout\r
279 )\r
280{\r
281 EFI_STATUS Status;\r
282\r
283 EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_ASYNC);\r
284\r
285 Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_ASYNC_ENABLED, TRUE, Timeout);\r
286 return Status;\r
287}\r
288\r
289/**\r
290 Check whether Ehc is halted.\r
291 \r
292 @param Ehc The EHCI device.\r
293\r
294 @retval TRUE The controller is halted.\r
295 @retval FALSE The controller isn't halted.\r
296\r
297**/\r
298BOOLEAN\r
299EhcIsHalt (\r
300 IN PEI_USB2_HC_DEV *Ehc\r
301 )\r
302{\r
303 return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT);\r
304}\r
305\r
306/**\r
307 Check whether system error occurred.\r
308 \r
309 @param Ehc The EHCI device.\r
310\r
311 @retval TRUE System error happened.\r
312 @retval FALSE No system error.\r
313\r
314**/\r
315BOOLEAN\r
316EhcIsSysError (\r
317 IN PEI_USB2_HC_DEV *Ehc\r
318 )\r
319{\r
320 return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR);\r
321}\r
322\r
323/**\r
324 Reset the host controller.\r
325 \r
326 @param Ehc The EHCI device.\r
327 @param Timeout Time to wait before abort (in millisecond, ms).\r
328\r
329 @retval EFI_TIMEOUT The transfer failed due to time out.\r
330 @retval Others Failed to reset the host.\r
331\r
332**/\r
333EFI_STATUS\r
334EhcResetHC (\r
335 IN PEI_USB2_HC_DEV *Ehc,\r
336 IN UINT32 Timeout\r
337 )\r
338{\r
339 EFI_STATUS Status;\r
340\r
341 //\r
342 // Host can only be reset when it is halt. If not so, halt it\r
343 //\r
344 if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r
345 Status = EhcHaltHC (Ehc, Timeout);\r
346\r
347 if (EFI_ERROR (Status)) {\r
348 return Status;\r
349 }\r
350 }\r
351\r
352 EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET);\r
353 Status = EhcWaitOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET, FALSE, Timeout);\r
354 return Status;\r
355}\r
356\r
357/**\r
358 Halt the host controller.\r
359 \r
360 @param Ehc The EHCI device.\r
361 @param Timeout Time to wait before abort.\r
362\r
363 @retval EFI_TIMEOUT Failed to halt the controller before Timeout.\r
364 @retval EFI_SUCCESS The EHCI is halt.\r
365\r
366**/\r
367EFI_STATUS\r
368EhcHaltHC (\r
369 IN PEI_USB2_HC_DEV *Ehc,\r
370 IN UINT32 Timeout\r
371 )\r
372{\r
373 EFI_STATUS Status;\r
374\r
375 EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);\r
376 Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, TRUE, Timeout);\r
377 return Status;\r
378}\r
379\r
380/**\r
381 Set the EHCI to run.\r
382 \r
383 @param Ehc The EHCI device.\r
384 @param Timeout Time to wait before abort.\r
385\r
386 @retval EFI_SUCCESS The EHCI is running.\r
387 @retval Others Failed to set the EHCI to run.\r
388\r
389**/\r
390EFI_STATUS\r
391EhcRunHC (\r
392 IN PEI_USB2_HC_DEV *Ehc,\r
393 IN UINT32 Timeout\r
394 )\r
395{\r
396 EFI_STATUS Status;\r
397\r
398 EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);\r
399 Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, FALSE, Timeout);\r
400 return Status;\r
401}\r
402\r
403/**\r
404 Initialize the HC hardware. \r
405 EHCI spec lists the five things to do to initialize the hardware.\r
406 1. Program CTRLDSSEGMENT.\r
407 2. Set USBINTR to enable interrupts.\r
408 3. Set periodic list base.\r
409 4. Set USBCMD, interrupt threshold, frame list size etc.\r
410 5. Write 1 to CONFIGFLAG to route all ports to EHCI.\r
411 \r
412 @param Ehc The EHCI device.\r
413\r
414 @retval EFI_SUCCESS The EHCI has come out of halt state.\r
415 @retval EFI_TIMEOUT Time out happened.\r
416\r
417**/\r
418EFI_STATUS\r
419EhcInitHC (\r
420 IN PEI_USB2_HC_DEV *Ehc\r
421 )\r
422{\r
423 EFI_STATUS Status;\r
424 EFI_PHYSICAL_ADDRESS TempPtr;\r
425 UINTN PageNumber;\r
426 \r
427 ASSERT (EhcIsHalt (Ehc));\r
428\r
429 //\r
430 // Allocate the periodic frame and associated memeory\r
431 // management facilities if not already done.\r
432 //\r
433 if (Ehc->PeriodFrame != NULL) {\r
434 EhcFreeSched (Ehc);\r
435 }\r
436 PageNumber = sizeof(PEI_URB)/PAGESIZE +1;\r
437 Status = PeiServicesAllocatePages (\r
438 EfiBootServicesCode,\r
439 PageNumber,\r
440 &TempPtr\r
441 );\r
442 Ehc->Urb = (PEI_URB *) ((UINTN) TempPtr);\r
443 if (Ehc->Urb == NULL) {\r
444 return Status;\r
445 }\r
446 \r
447 Status = EhcInitSched (Ehc);\r
448\r
449 if (EFI_ERROR (Status)) {\r
450 return Status;\r
451 }\r
452 //\r
453 // 1. Program the CTRLDSSEGMENT register with the high 32 bit addr\r
454 //\r
455 EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, Ehc->High32bitAddr);\r
456\r
457 //\r
458 // 2. Clear USBINTR to disable all the interrupt. UEFI works by polling\r
459 //\r
460 EhcWriteOpReg (Ehc, EHC_USBINTR_OFFSET, 0);\r
461\r
462 //\r
463 // 3. Program periodic frame list, already done in EhcInitSched\r
464 // 4. Start the Host Controller\r
465 //\r
466 EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);\r
467\r
468 //\r
469 // 5. Set all ports routing to EHC\r
470 //\r
471 EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);\r
472\r
473 //\r
474 // Wait roothub port power stable\r
475 //\r
476 MicroSecondDelay (EHC_ROOT_PORT_RECOVERY_STALL);\r
477\r
478 Status = EhcEnablePeriodSchd (Ehc, EHC_GENERIC_TIMEOUT);\r
479\r
480 if (EFI_ERROR (Status)) {\r
481 return Status;\r
482 }\r
483\r
484 Status = EhcEnableAsyncSchd (Ehc, EHC_GENERIC_TIMEOUT);\r
485\r
486 if (EFI_ERROR (Status)) {\r
487 return Status;\r
488 }\r
489\r
490 return EFI_SUCCESS;\r
491}\r
492\r
493/**\r
494 Submits bulk transfer to a bulk endpoint of a USB device.\r
495 \r
496 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
497 @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI.\r
498 @param DeviceAddress Target device address.\r
499 @param EndPointAddress Endpoint number and its direction in bit 7.\r
500 @param DeviceSpeed Device speed, Low speed device doesn't support \r
501 bulk transfer.\r
502 @param MaximumPacketLength Maximum packet size the endpoint is capable of \r
503 sending or receiving.\r
504 @param Data Array of pointers to the buffers of data to transmit \r
505 from or receive into.\r
506 @param DataLength The lenght of the data buffer.\r
507 @param DataToggle On input, the initial data toggle for the transfer;\r
508 On output, it is updated to to next data toggle to use of \r
509 the subsequent bulk transfer.\r
510 @param TimeOut Indicates the maximum time, in millisecond, which the\r
511 transfer is allowed to complete.\r
512 @param Translator A pointr to the transaction translator data. \r
513 @param TransferResult A pointer to the detailed result information of the\r
514 bulk transfer.\r
515\r
516 @retval EFI_SUCCESS The transfer was completed successfully.\r
517 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.\r
518 @retval EFI_INVALID_PARAMETER Parameters are invalid.\r
519 @retval EFI_TIMEOUT The transfer failed due to timeout.\r
520 @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.\r
521\r
522**/\r
523EFI_STATUS\r
524EFIAPI\r
525EhcBulkTransfer (\r
526 IN EFI_PEI_SERVICES **PeiServices,\r
527 IN PEI_USB2_HOST_CONTROLLER_PPI *This,\r
528 IN UINT8 DeviceAddress,\r
529 IN UINT8 EndPointAddress,\r
530 IN UINT8 DeviceSpeed,\r
531 IN UINTN MaximumPacketLength,\r
532 IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
533 IN OUT UINTN *DataLength,\r
534 IN OUT UINT8 *DataToggle,\r
535 IN UINTN TimeOut,\r
536 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
537 OUT UINT32 *TransferResult\r
538 )\r
539{\r
540 PEI_USB2_HC_DEV *Ehc;\r
541 PEI_URB *Urb;\r
542 EFI_STATUS Status;\r
543\r
544 //\r
545 // Validate the parameters\r
546 //\r
547 if ((DataLength == NULL) || (*DataLength == 0) || \r
548 (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) {\r
549 return EFI_INVALID_PARAMETER;\r
550 }\r
551\r
552 if ((*DataToggle != 0) && (*DataToggle != 1)) {\r
553 return EFI_INVALID_PARAMETER;\r
554 }\r
555\r
556 if ((DeviceSpeed == EFI_USB_SPEED_LOW) ||\r
557 ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||\r
558 ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512))) {\r
559 return EFI_INVALID_PARAMETER;\r
560 }\r
561\r
562 Ehc =PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS(This);\r
563 *TransferResult = EFI_USB_ERR_SYSTEM;\r
564 Status = EFI_DEVICE_ERROR;\r
565\r
566 if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
567 EhcAckAllInterrupt (Ehc);\r
568 goto ON_EXIT;\r
569 }\r
570\r
571 EhcAckAllInterrupt (Ehc);\r
572\r
573 //\r
574 // Create a new URB, insert it into the asynchronous\r
575 // schedule list, then poll the execution status.\r
576 //\r
577 Urb = EhcCreateUrb (\r
578 Ehc,\r
579 DeviceAddress,\r
580 EndPointAddress,\r
581 DeviceSpeed,\r
582 *DataToggle,\r
583 MaximumPacketLength,\r
584 Translator,\r
585 EHC_BULK_TRANSFER,\r
586 NULL,\r
587 Data[0],\r
588 *DataLength,\r
589 NULL,\r
590 NULL,\r
591 1\r
592 );\r
593\r
594 if (Urb == NULL) {\r
595 Status = EFI_OUT_OF_RESOURCES;\r
596 goto ON_EXIT;\r
597 }\r
598\r
599 EhcLinkQhToAsync (Ehc, Urb->Qh);\r
600 Status = EhcExecTransfer (Ehc, Urb, TimeOut);\r
601 EhcUnlinkQhFromAsync (Ehc, Urb->Qh);\r
602\r
603 *TransferResult = Urb->Result;\r
604 *DataLength = Urb->Completed;\r
605 *DataToggle = Urb->DataToggle;\r
606\r
607 if (*TransferResult == EFI_USB_NOERROR) {\r
608 Status = EFI_SUCCESS;\r
609 }\r
610\r
611 EhcAckAllInterrupt (Ehc);\r
612 EhcFreeUrb (Ehc, Urb);\r
613\r
614ON_EXIT:\r
615 return Status;\r
616}\r
617\r
618/**\r
619 Retrieves the number of root hub ports.\r
620\r
621 @param[in] PeiServices The pointer to the PEI Services Table.\r
622 @param[in] This The pointer to this instance of the \r
623 PEI_USB2_HOST_CONTROLLER_PPI.\r
624 @param[out] PortNumber The pointer to the number of the root hub ports. \r
625 \r
626 @retval EFI_SUCCESS The port number was retrieved successfully.\r
627 @retval EFI_INVALID_PARAMETER PortNumber is NULL.\r
628\r
629**/\r
630EFI_STATUS\r
631EFIAPI\r
632EhcGetRootHubPortNumber (\r
633 IN EFI_PEI_SERVICES **PeiServices,\r
634 IN PEI_USB2_HOST_CONTROLLER_PPI *This,\r
635 OUT UINT8 *PortNumber\r
636 )\r
637{\r
638\r
639 PEI_USB2_HC_DEV *EhcDev;\r
640 EhcDev = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This);\r
641 \r
642 if (PortNumber == NULL) {\r
643 return EFI_INVALID_PARAMETER;\r
644 } \r
645 \r
646 *PortNumber = (UINT8)(EhcDev->HcStructParams & HCSP_NPORTS);\r
647 return EFI_SUCCESS;\r
648 \r
649}\r
650\r
651/**\r
652 Clears a feature for the specified root hub port.\r
653 \r
654 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
655 @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI.\r
656 @param PortNumber Specifies the root hub port whose feature\r
657 is requested to be cleared.\r
658 @param PortFeature Indicates the feature selector associated with the\r
659 feature clear request.\r
660\r
661 @retval EFI_SUCCESS The feature specified by PortFeature was cleared \r
662 for the USB root hub port specified by PortNumber.\r
663 @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
664\r
665**/\r
666EFI_STATUS\r
667EFIAPI\r
668EhcClearRootHubPortFeature (\r
669 IN EFI_PEI_SERVICES **PeiServices,\r
670 IN PEI_USB2_HOST_CONTROLLER_PPI *This,\r
671 IN UINT8 PortNumber,\r
672 IN EFI_USB_PORT_FEATURE PortFeature\r
673 )\r
674{\r
675 PEI_USB2_HC_DEV *Ehc;\r
676 UINT32 Offset;\r
677 UINT32 State;\r
678 UINT32 TotalPort;\r
679 EFI_STATUS Status;\r
680\r
681 Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This);\r
682 Status = EFI_SUCCESS;\r
683\r
684 TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
685\r
686 if (PortNumber >= TotalPort) {\r
687 Status = EFI_INVALID_PARAMETER;\r
688 goto ON_EXIT;\r
689 }\r
690\r
691 Offset = EHC_PORT_STAT_OFFSET + (4 * PortNumber);\r
692 State = EhcReadOpReg (Ehc, Offset);\r
693 State &= ~PORTSC_CHANGE_MASK;\r
694\r
695 switch (PortFeature) {\r
696 case EfiUsbPortEnable:\r
697 //\r
698 // Clear PORT_ENABLE feature means disable port.\r
699 //\r
700 State &= ~PORTSC_ENABLED;\r
701 EhcWriteOpReg (Ehc, Offset, State);\r
702 break;\r
703\r
704 case EfiUsbPortSuspend:\r
705 //\r
706 // A write of zero to this bit is ignored by the host\r
707 // controller. The host controller will unconditionally\r
708 // set this bit to a zero when:\r
709 // 1. software sets the Forct Port Resume bit to a zero from a one.\r
710 // 2. software sets the Port Reset bit to a one frome a zero.\r
711 //\r
712 State &= ~PORSTSC_RESUME;\r
713 EhcWriteOpReg (Ehc, Offset, State);\r
714 break;\r
715\r
716 case EfiUsbPortReset:\r
717 //\r
718 // Clear PORT_RESET means clear the reset signal.\r
719 //\r
720 State &= ~PORTSC_RESET;\r
721 EhcWriteOpReg (Ehc, Offset, State);\r
722 break;\r
723\r
724 case EfiUsbPortOwner:\r
725 //\r
726 // Clear port owner means this port owned by EHC\r
727 //\r
728 State &= ~PORTSC_OWNER;\r
729 EhcWriteOpReg (Ehc, Offset, State);\r
730 break;\r
731\r
732 case EfiUsbPortConnectChange:\r
733 //\r
734 // Clear connect status change\r
735 //\r
736 State |= PORTSC_CONN_CHANGE;\r
737 EhcWriteOpReg (Ehc, Offset, State);\r
738 break;\r
739\r
740 case EfiUsbPortEnableChange:\r
741 //\r
742 // Clear enable status change\r
743 //\r
744 State |= PORTSC_ENABLE_CHANGE;\r
745 EhcWriteOpReg (Ehc, Offset, State);\r
746 break;\r
747\r
748 case EfiUsbPortOverCurrentChange:\r
749 //\r
750 // Clear PortOverCurrent change\r
751 //\r
752 State |= PORTSC_OVERCUR_CHANGE;\r
753 EhcWriteOpReg (Ehc, Offset, State);\r
754 break;\r
755\r
756 case EfiUsbPortPower:\r
757 case EfiUsbPortSuspendChange:\r
758 case EfiUsbPortResetChange:\r
759 //\r
760 // Not supported or not related operation\r
761 //\r
762 break;\r
763\r
764 default:\r
765 Status = EFI_INVALID_PARAMETER;\r
766 break;\r
767 }\r
768\r
769ON_EXIT:\r
770 return Status;\r
771}\r
772\r
773/**\r
774 Sets a feature for the specified root hub port.\r
775 \r
776 @param PeiServices The pointer of EFI_PEI_SERVICES\r
777 @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI\r
778 @param PortNumber Root hub port to set.\r
779 @param PortFeature Feature to set.\r
780\r
781 @retval EFI_SUCCESS The feature specified by PortFeature was set.\r
782 @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
783 @retval EFI_TIMEOUT The time out occurred.\r
784\r
785**/\r
786EFI_STATUS\r
787EFIAPI\r
788EhcSetRootHubPortFeature (\r
789 IN EFI_PEI_SERVICES **PeiServices,\r
790 IN PEI_USB2_HOST_CONTROLLER_PPI *This,\r
791 IN UINT8 PortNumber,\r
792 IN EFI_USB_PORT_FEATURE PortFeature\r
793 )\r
794{\r
795 PEI_USB2_HC_DEV *Ehc;\r
796 UINT32 Offset;\r
797 UINT32 State;\r
798 UINT32 TotalPort;\r
799 EFI_STATUS Status;\r
800\r
801 Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This);\r
802 Status = EFI_SUCCESS;\r
803\r
804 TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
805\r
806 if (PortNumber >= TotalPort) {\r
807 Status = EFI_INVALID_PARAMETER;\r
808 goto ON_EXIT;\r
809 }\r
810\r
811 Offset = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
812 State = EhcReadOpReg (Ehc, Offset);\r
813\r
814 //\r
815 // Mask off the port status change bits, these bits are\r
816 // write clean bit\r
817 //\r
818 State &= ~PORTSC_CHANGE_MASK;\r
819\r
820 switch (PortFeature) {\r
821 case EfiUsbPortEnable:\r
822 //\r
823 // Sofeware can't set this bit, Port can only be enable by\r
824 // EHCI as a part of the reset and enable\r
825 //\r
826 State |= PORTSC_ENABLED;\r
827 EhcWriteOpReg (Ehc, Offset, State);\r
828 break;\r
829\r
830 case EfiUsbPortSuspend:\r
831 State |= PORTSC_SUSPEND;\r
832 EhcWriteOpReg (Ehc, Offset, State);\r
833 break;\r
834\r
835 case EfiUsbPortReset:\r
836 //\r
837 // Make sure Host Controller not halt before reset it\r
838 //\r
839 if (EhcIsHalt (Ehc)) {\r
840 Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
841\r
842 if (EFI_ERROR (Status)) {\r
843 break;\r
844 }\r
845 }\r
846 \r
847 //\r
848 // Set one to PortReset bit must also set zero to PortEnable bit\r
849 //\r
850 State |= PORTSC_RESET;\r
851 State &= ~PORTSC_ENABLED;\r
852 EhcWriteOpReg (Ehc, Offset, State);\r
853 break;\r
854\r
855 case EfiUsbPortPower:\r
856 //\r
857 // Not supported, ignore the operation\r
858 //\r
859 Status = EFI_SUCCESS;\r
860 break;\r
861\r
862 case EfiUsbPortOwner:\r
863 State |= PORTSC_OWNER;\r
864 EhcWriteOpReg (Ehc, Offset, State);\r
865 break;\r
866\r
867 default:\r
868 Status = EFI_INVALID_PARAMETER;\r
869 }\r
870\r
871ON_EXIT:\r
872 return Status;\r
873}\r
874\r
875/**\r
876 Retrieves the current status of a USB root hub port.\r
877 \r
878 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
879 @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI.\r
880 @param PortNumber The root hub port to retrieve the state from. \r
881 @param PortStatus Variable to receive the port state.\r
882\r
883 @retval EFI_SUCCESS The status of the USB root hub port specified.\r
884 by PortNumber was returned in PortStatus.\r
885 @retval EFI_INVALID_PARAMETER PortNumber is invalid.\r
886\r
887**/\r
888EFI_STATUS\r
889EFIAPI\r
890EhcGetRootHubPortStatus (\r
891 IN EFI_PEI_SERVICES **PeiServices,\r
892 IN PEI_USB2_HOST_CONTROLLER_PPI *This,\r
893 IN UINT8 PortNumber,\r
894 OUT EFI_USB_PORT_STATUS *PortStatus\r
895 )\r
896{\r
897 PEI_USB2_HC_DEV *Ehc;\r
898 UINT32 Offset;\r
899 UINT32 State;\r
900 UINT32 TotalPort;\r
901 UINTN Index;\r
902 UINTN MapSize;\r
903 EFI_STATUS Status;\r
904\r
905 if (PortStatus == NULL) {\r
906 return EFI_INVALID_PARAMETER;\r
907 }\r
908\r
909 Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS(This);\r
910 Status = EFI_SUCCESS;\r
911\r
912 TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
913\r
914 if (PortNumber >= TotalPort) {\r
915 Status = EFI_INVALID_PARAMETER;\r
916 goto ON_EXIT;\r
917 }\r
918\r
919 Offset = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
920 PortStatus->PortStatus = 0;\r
921 PortStatus->PortChangeStatus = 0;\r
922\r
923 State = EhcReadOpReg (Ehc, Offset);\r
924\r
925 //\r
926 // Identify device speed. If in K state, it is low speed.\r
927 // If the port is enabled after reset, the device is of \r
928 // high speed. The USB bus driver should retrieve the actual\r
929 // port speed after reset. \r
930 //\r
931 if (EHC_BIT_IS_SET (State, PORTSC_LINESTATE_K)) {\r
932 PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
933\r
934 } else if (EHC_BIT_IS_SET (State, PORTSC_ENABLED)) {\r
935 PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;\r
936 }\r
937 \r
938 //\r
939 // Convert the EHCI port/port change state to UEFI status\r
940 //\r
941 MapSize = sizeof (mUsbPortStateMap) / sizeof (USB_PORT_STATE_MAP);\r
942\r
943 for (Index = 0; Index < MapSize; Index++) {\r
944 if (EHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) {\r
945 PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState);\r
946 }\r
947 }\r
948\r
949 MapSize = sizeof (mUsbPortChangeMap) / sizeof (USB_PORT_STATE_MAP);\r
950\r
951 for (Index = 0; Index < MapSize; Index++) {\r
952 if (EHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) {\r
953 PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState);\r
954 }\r
955 }\r
956\r
957ON_EXIT:\r
958 return Status;\r
959}\r
960\r
961/**\r
962 Submits control transfer to a target USB device.\r
963 \r
964 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
965 @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI.\r
966 @param DeviceAddress The target device address.\r
967 @param DeviceSpeed Target device speed.\r
968 @param MaximumPacketLength Maximum packet size the default control transfer \r
969 endpoint is capable of sending or receiving.\r
970 @param Request USB device request to send.\r
971 @param TransferDirection Specifies the data direction for the data stage.\r
972 @param Data Data buffer to be transmitted or received from USB device.\r
973 @param DataLength The size (in bytes) of the data buffer.\r
974 @param TimeOut Indicates the maximum timeout, in millisecond.\r
975 @param Translator Transaction translator to be used by this device.\r
976 @param TransferResult Return the result of this control transfer.\r
977\r
978 @retval EFI_SUCCESS Transfer was completed successfully.\r
979 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources.\r
980 @retval EFI_INVALID_PARAMETER Some parameters are invalid.\r
981 @retval EFI_TIMEOUT Transfer failed due to timeout.\r
982 @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error.\r
983\r
984**/\r
985EFI_STATUS\r
986EFIAPI\r
987EhcControlTransfer (\r
988 IN EFI_PEI_SERVICES **PeiServices,\r
989 IN PEI_USB2_HOST_CONTROLLER_PPI *This,\r
990 IN UINT8 DeviceAddress,\r
991 IN UINT8 DeviceSpeed,\r
992 IN UINTN MaximumPacketLength,\r
993 IN EFI_USB_DEVICE_REQUEST *Request,\r
994 IN EFI_USB_DATA_DIRECTION TransferDirection,\r
995 IN OUT VOID *Data,\r
996 IN OUT UINTN *DataLength,\r
997 IN UINTN TimeOut,\r
998 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
999 OUT UINT32 *TransferResult\r
1000 )\r
1001{\r
1002 PEI_USB2_HC_DEV *Ehc;\r
1003 PEI_URB *Urb;\r
1004 UINT8 Endpoint;\r
1005 EFI_STATUS Status;\r
1006\r
1007 //\r
1008 // Validate parameters\r
1009 //\r
1010 if ((Request == NULL) || (TransferResult == NULL)) {\r
1011 return EFI_INVALID_PARAMETER;\r
1012 }\r
1013\r
1014 if ((TransferDirection != EfiUsbDataIn) &&\r
1015 (TransferDirection != EfiUsbDataOut) &&\r
1016 (TransferDirection != EfiUsbNoData)) {\r
1017 return EFI_INVALID_PARAMETER;\r
1018 }\r
1019\r
1020 if ((TransferDirection == EfiUsbNoData) && \r
1021 ((Data != NULL) || (*DataLength != 0))) {\r
1022 return EFI_INVALID_PARAMETER;\r
1023 }\r
1024\r
1025 if ((TransferDirection != EfiUsbNoData) && \r
1026 ((Data == NULL) || (*DataLength == 0))) {\r
1027 return EFI_INVALID_PARAMETER;\r
1028 }\r
1029\r
1030 if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) &&\r
1031 (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) {\r
1032 return EFI_INVALID_PARAMETER;\r
1033 }\r
1034\r
1035\r
1036 if ((DeviceSpeed == EFI_USB_SPEED_LOW) ||\r
1037 ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||\r
1038 ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512))) {\r
1039 return EFI_INVALID_PARAMETER;\r
1040 }\r
1041\r
1042 Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This);\r
1043\r
1044 Status = EFI_DEVICE_ERROR;\r
1045 *TransferResult = EFI_USB_ERR_SYSTEM;\r
1046\r
1047 if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
1048 EhcAckAllInterrupt (Ehc);\r
1049 goto ON_EXIT;\r
1050 }\r
1051\r
1052 EhcAckAllInterrupt (Ehc);\r
1053\r
1054 //\r
1055 // Create a new URB, insert it into the asynchronous\r
1056 // schedule list, then poll the execution status.\r
1057 //\r
1058 //\r
1059 // Encode the direction in address, although default control\r
1060 // endpoint is bidirectional. EhcCreateUrb expects this\r
1061 // combination of Ep addr and its direction.\r
1062 //\r
1063 Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));\r
1064 Urb = EhcCreateUrb (\r
1065 Ehc,\r
1066 DeviceAddress,\r
1067 Endpoint,\r
1068 DeviceSpeed,\r
1069 0,\r
1070 MaximumPacketLength,\r
1071 Translator,\r
1072 EHC_CTRL_TRANSFER,\r
1073 Request,\r
1074 Data,\r
1075 *DataLength,\r
1076 NULL,\r
1077 NULL,\r
1078 1\r
1079 );\r
1080\r
1081 if (Urb == NULL) {\r
1082 Status = EFI_OUT_OF_RESOURCES;\r
1083 goto ON_EXIT;\r
1084 }\r
1085\r
1086 EhcLinkQhToAsync (Ehc, Urb->Qh);\r
1087 Status = EhcExecTransfer (Ehc, Urb, TimeOut);\r
1088 EhcUnlinkQhFromAsync (Ehc, Urb->Qh);\r
1089\r
1090 //\r
1091 // Get the status from URB. The result is updated in EhcCheckUrbResult\r
1092 // which is called by EhcExecTransfer\r
1093 //\r
1094 *TransferResult = Urb->Result;\r
1095 *DataLength = Urb->Completed;\r
1096\r
1097 if (*TransferResult == EFI_USB_NOERROR) {\r
1098 Status = EFI_SUCCESS;\r
1099 }\r
1100\r
1101 EhcAckAllInterrupt (Ehc);\r
1102 EhcFreeUrb (Ehc, Urb);\r
1103\r
1104ON_EXIT:\r
1105 return Status;\r
1106}\r
1107\r
1108/**\r
1109 @param FileHandle Handle of the file being invoked.\r
1110 @param PeiServices Describes the list of possible PEI Services.\r
1111\r
1112 @retval EFI_SUCCESS PPI successfully installed.\r
1113\r
1114**/\r
1115EFI_STATUS\r
1116EFIAPI\r
1117EhcPeimEntry (\r
1118 IN EFI_PEI_FILE_HANDLE FileHandle,\r
1119 IN CONST EFI_PEI_SERVICES **PeiServices\r
1120 )\r
1121{\r
1122 PEI_USB_CONTROLLER_PPI *ChipSetUsbControllerPpi;\r
1123 EFI_STATUS Status;\r
1124 UINT8 Index;\r
1125 UINTN ControllerType;\r
1126 UINTN BaseAddress;\r
1127 UINTN MemPages;\r
1128 PEI_USB2_HC_DEV *EhcDev;\r
1129 EFI_PHYSICAL_ADDRESS TempPtr;\r
1130\r
1131 //\r
1132 // Shadow this PEIM to run from memory\r
1133 //\r
1134 if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {\r
1135 return EFI_SUCCESS;\r
1136 }\r
1137\r
1138 Status = PeiServicesLocatePpi (\r
1139 &gPeiUsbControllerPpiGuid,\r
1140 0,\r
1141 NULL,\r
1142 (VOID **) &ChipSetUsbControllerPpi\r
1143 );\r
1144 if (EFI_ERROR (Status)) {\r
1145 return EFI_UNSUPPORTED;\r
1146 }\r
1147\r
1148 Index = 0;\r
1149 while (TRUE) {\r
1150 Status = ChipSetUsbControllerPpi->GetUsbController (\r
1151 (EFI_PEI_SERVICES **) PeiServices,\r
1152 ChipSetUsbControllerPpi,\r
1153 Index,\r
1154 &ControllerType,\r
1155 &BaseAddress\r
1156 );\r
1157 //\r
1158 // When status is error, meant no controller is found\r
1159 //\r
1160 if (EFI_ERROR (Status)) {\r
1161 break;\r
1162 }\r
1163 \r
1164 //\r
1165 // This PEIM is for UHC type controller.\r
1166 //\r
1167 if (ControllerType != PEI_EHCI_CONTROLLER) {\r
1168 Index++;\r
1169 continue;\r
1170 }\r
1171\r
1172 MemPages = sizeof (PEI_USB2_HC_DEV) / PAGESIZE + 1;\r
1173 Status = PeiServicesAllocatePages (\r
1174 EfiBootServicesCode,\r
1175 MemPages,\r
1176 &TempPtr\r
1177 );\r
1178 if (EFI_ERROR (Status)) {\r
1179 return EFI_OUT_OF_RESOURCES;\r
1180 }\r
1181\r
1182 ZeroMem((VOID *)(UINTN)TempPtr, MemPages*PAGESIZE);\r
1183 EhcDev = (PEI_USB2_HC_DEV *) ((UINTN) TempPtr);\r
1184\r
1185 EhcDev->Signature = USB2_HC_DEV_SIGNATURE;\r
1186\r
1187 EhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress;\r
1188\r
1189\r
1190 EhcDev->HcStructParams = EhcReadCapRegister (EhcDev, EHC_HCSPARAMS_OFFSET);\r
1191 EhcDev->HcCapParams = EhcReadCapRegister (EhcDev, EHC_HCCPARAMS_OFFSET);\r
1192 EhcDev->CapLen = EhcReadCapRegister (EhcDev, EHC_CAPLENGTH_OFFSET) & 0x0FF;\r
1193 //\r
1194 // Initialize Uhc's hardware\r
1195 //\r
1196 Status = InitializeUsbHC (EhcDev);\r
1197 if (EFI_ERROR (Status)) {\r
1198 return Status;\r
1199 }\r
1200\r
1201 EhcDev->Usb2HostControllerPpi.ControlTransfer = EhcControlTransfer;\r
1202 EhcDev->Usb2HostControllerPpi.BulkTransfer = EhcBulkTransfer;\r
1203 EhcDev->Usb2HostControllerPpi.GetRootHubPortNumber = EhcGetRootHubPortNumber;\r
1204 EhcDev->Usb2HostControllerPpi.GetRootHubPortStatus = EhcGetRootHubPortStatus;\r
1205 EhcDev->Usb2HostControllerPpi.SetRootHubPortFeature = EhcSetRootHubPortFeature;\r
1206 EhcDev->Usb2HostControllerPpi.ClearRootHubPortFeature = EhcClearRootHubPortFeature;\r
1207\r
1208 EhcDev->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
1209 EhcDev->PpiDescriptor.Guid = &gPeiUsb2HostControllerPpiGuid;\r
1210 EhcDev->PpiDescriptor.Ppi = &EhcDev->Usb2HostControllerPpi;\r
1211\r
1212 Status = PeiServicesInstallPpi (&EhcDev->PpiDescriptor);\r
1213 if (EFI_ERROR (Status)) {\r
1214 Index++;\r
1215 continue;\r
1216 }\r
1217\r
1218 Index++;\r
1219 }\r
1220\r
1221 return EFI_SUCCESS;\r
1222}\r
1223\r
1224/**\r
1225 @param EhcDev EHCI Device.\r
1226\r
1227 @retval EFI_SUCCESS EHCI successfully initialized.\r
1228 @retval EFI_ABORTED EHCI was failed to be initialized.\r
1229\r
1230**/\r
1231EFI_STATUS\r
1232InitializeUsbHC (\r
1233 IN PEI_USB2_HC_DEV *EhcDev \r
1234 )\r
1235{\r
1236 EFI_STATUS Status;\r
1237\r
1238 \r
1239 EhcResetHC (EhcDev, EHC_RESET_TIMEOUT);\r
1240\r
1241 Status = EhcInitHC (EhcDev);\r
1242\r
1243 if (EFI_ERROR (Status)) {\r
1244 return EFI_ABORTED; \r
1245 }\r
1246 \r
1247 return EFI_SUCCESS;\r
1248}\r