1 /** @file
2 Private Header file for Usb Host Controller PEIM
3 
4 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
5 
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
11 
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.
14 
15 **/
16 
17 #ifndef _RECOVERY_UHC_H_
18 #define _RECOVERY_UHC_H_
19 
20 
21 #include <PiPei.h>
22 
23 #include <Ppi/UsbController.h>
24 #include <Ppi/UsbHostController.h>
25 
26 #include <Library/DebugLib.h>
27 #include <Library/PeimEntryPoint.h>
28 #include <Library/PeiServicesLib.h>
29 #include <Library/BaseMemoryLib.h>
30 #include <Library/TimerLib.h>
31 #include <Library/IoLib.h>
32 #include <Library/PeiServicesLib.h>
33 
34 #define USB_SLOW_SPEED_DEVICE 0x01
35 #define USB_FULL_SPEED_DEVICE 0x02
36 
37 //
38 // One memory block uses 16 page
39 //
40 #define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 16
41 
42 #define USBCMD                            0       /* Command Register Offset 00-01h */
43 #define USBCMD_RS                         BIT0    /* Run/Stop */
44 #define USBCMD_HCRESET                    BIT1    /* Host reset */
45 #define USBCMD_GRESET                     BIT2    /* Global reset */
46 #define USBCMD_EGSM                       BIT3    /* Global Suspend Mode */
47 #define USBCMD_FGR                        BIT4    /* Force Global Resume */
48 #define USBCMD_SWDBG                      BIT5    /* SW Debug mode */
49 #define USBCMD_CF                         BIT6    /* Config Flag (sw only) */
50 #define USBCMD_MAXP                       BIT7    /* Max Packet (0 = 32, 1 = 64) */
51 
52 /* Status register */
53 #define USBSTS        2       /* Status Register Offset 02-03h */
54 #define USBSTS_USBINT BIT0    /* Interrupt due to IOC */
55 #define USBSTS_ERROR  BIT1    /* Interrupt due to error */
56 #define USBSTS_RD     BIT2    /* Resume Detect */
57 #define USBSTS_HSE    BIT3    /* Host System Error - basically PCI problems */
58 #define USBSTS_HCPE   BIT4    /* Host Controller Process Error - the scripts were buggy */
59 #define USBSTS_HCH    BIT5    /* HC Halted */
60 
61 /* Interrupt enable register */
62 #define USBINTR         4       /* Interrupt Enable Register 04-05h */
63 #define USBINTR_TIMEOUT BIT0    /* Timeout/CRC error enable */
64 #define USBINTR_RESUME  BIT1    /* Resume interrupt enable */
65 #define USBINTR_IOC     BIT2    /* Interrupt On Complete enable */
66 #define USBINTR_SP      BIT3    /* Short packet interrupt enable */
67 
68 /* Frame Number Register Offset 06-08h */
69 #define USBFRNUM  6
70 
71 /* Frame List Base Address Register Offset 08-0Bh */
72 #define USBFLBASEADD  8
73 
74 /* Start of Frame Modify Register Offset 0Ch */
75 #define USBSOF  0x0c
76 
77 /* USB port status and control registers */
78 #define USBPORTSC1            0x10      /*Port 1 offset 10-11h */
79 #define USBPORTSC2            0x12      /*Port 2 offset 12-13h */
80 
81 #define USBPORTSC_CCS         BIT0      /* Current Connect Status ("device present") */
82 #define USBPORTSC_CSC         BIT1      /* Connect Status Change */
83 #define USBPORTSC_PED         BIT2      /* Port Enable / Disable */
84 #define USBPORTSC_PEDC        BIT3      /* Port Enable / Disable Change */
85 #define USBPORTSC_LSL         BIT4      /* Line Status Low bit*/
86 #define USBPORTSC_LSH         BIT5      /* Line Status High bit*/
87 #define USBPORTSC_RD          BIT6      /* Resume Detect */
88 #define USBPORTSC_LSDA        BIT8      /* Low Speed Device Attached */
89 #define USBPORTSC_PR          BIT9      /* Port Reset */
90 #define USBPORTSC_SUSP        BIT12     /* Suspend */
91 
92 #define SETUP_PACKET_ID       0x2D
93 #define INPUT_PACKET_ID       0x69
94 #define OUTPUT_PACKET_ID      0xE1
95 #define ERROR_PACKET_ID       0x55
96 
97 #define STALL_1_MICRO_SECOND  1
98 #define STALL_1_MILLI_SECOND  1000
99 
100 
101 #pragma pack(1)
102 
103 typedef struct {
104   UINT32  FrameListPtrTerminate : 1;
105   UINT32  FrameListPtrQSelect : 1;
106   UINT32  FrameListRsvd : 2;
107   UINT32  FrameListPtr : 28;
108 } FRAMELIST_ENTRY;
109 
110 typedef struct {
111   UINT32  QHHorizontalTerminate : 1;
112   UINT32  QHHorizontalQSelect : 1;
113   UINT32  QHHorizontalRsvd : 2;
114   UINT32  QHHorizontalPtr : 28;
115   UINT32  QHVerticalTerminate : 1;
116   UINT32  QHVerticalQSelect : 1;
117   UINT32  QHVerticalRsvd : 2;
118   UINT32  QHVerticalPtr : 28;
119 } QUEUE_HEAD;
120 
121 typedef struct {
122   QUEUE_HEAD  QueueHead;
123   UINT32      Reserved1;
124   UINT32      Reserved2;
125   VOID        *PtrNext;
126   VOID        *PtrDown;
127   VOID        *Reserved3;
128   UINT32      Reserved4;
129 } QH_STRUCT;
130 
131 typedef struct {
132   UINT32  TDLinkPtrTerminate : 1;
133   UINT32  TDLinkPtrQSelect : 1;
134   UINT32  TDLinkPtrDepthSelect : 1;
135   UINT32  TDLinkPtrRsvd : 1;
136   UINT32  TDLinkPtr : 28;
137   UINT32  TDStatusActualLength : 11;
138   UINT32  TDStatusRsvd : 5;
139   UINT32  TDStatus : 8;
140   UINT32  TDStatusIOC : 1;
141   UINT32  TDStatusIOS : 1;
142   UINT32  TDStatusLS : 1;
143   UINT32  TDStatusErr : 2;
144   UINT32  TDStatusSPD : 1;
145   UINT32  TDStatusRsvd2 : 2;
146   UINT32  TDTokenPID : 8;
147   UINT32  TDTokenDevAddr : 7;
148   UINT32  TDTokenEndPt : 4;
149   UINT32  TDTokenDataToggle : 1;
150   UINT32  TDTokenRsvd : 1;
151   UINT32  TDTokenMaxLen : 11;
152   UINT32  TDBufferPtr;
153 } TD;
154 
155 typedef struct {
156   TD      TDData;
157   UINT8   *PtrTDBuffer;
158   VOID    *PtrNextTD;
159   VOID    *PtrNextQH;
160   UINT16  TDBufferLength;
161   UINT16  Reserved;
162 } TD_STRUCT;
163 
164 #pragma pack()
165 
166 typedef struct _MEMORY_MANAGE_HEADER MEMORY_MANAGE_HEADER;
167 
168 struct _MEMORY_MANAGE_HEADER {
169   UINT8                         *BitArrayPtr;
170   UINTN                         BitArraySizeInBytes;
171   UINT8                         *MemoryBlockPtr;
172   UINTN                         MemoryBlockSizeInBytes;
173   MEMORY_MANAGE_HEADER          *Next;
174 };
175 
176 #define USB_UHC_DEV_SIGNATURE SIGNATURE_32 ('p', 'u', 'h', 'c')
177 typedef struct {
178   UINTN                       Signature;
179   PEI_USB_HOST_CONTROLLER_PPI UsbHostControllerPpi;
180   EFI_PEI_PPI_DESCRIPTOR      PpiDescriptor;
181 
182   UINT32                      UsbHostControllerBaseAddress;
183   FRAMELIST_ENTRY             *FrameListEntry;
184   QH_STRUCT                   *ConfigQH;
185   QH_STRUCT                   *BulkQH;
186   //
187   // Header1 used for QH,TD memory blocks management
188   //
189   MEMORY_MANAGE_HEADER        *Header1;
190 
191 } USB_UHC_DEV;
192 
193 #define PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS(a)  CR (a, USB_UHC_DEV, UsbHostControllerPpi, USB_UHC_DEV_SIGNATURE)
194 
195 /**
196   Submits control transfer to a target USB device.
197 
198   @param  PeiServices            The pointer of EFI_PEI_SERVICES.
199   @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
200   @param  DeviceAddress          The target device address.
201   @param  DeviceSpeed            Target device speed.
202   @param  MaximumPacketLength    Maximum packet size the default control transfer
203                                  endpoint is capable of sending or receiving.
204   @param  Request                USB device request to send.
205   @param  TransferDirection      Specifies the data direction for the data stage.
206   @param  Data                   Data buffer to be transmitted or received from USB device.
207   @param  DataLength             The size (in bytes) of the data buffer.
208   @param  TimeOut                Indicates the maximum timeout, in millisecond.
209   @param  TransferResult         Return the result of this control transfer.
210 
211   @retval EFI_SUCCESS            Transfer was completed successfully.
212   @retval EFI_OUT_OF_RESOURCES   The transfer failed due to lack of resources.
213   @retval EFI_INVALID_PARAMETER  Some parameters are invalid.
214   @retval EFI_TIMEOUT            Transfer failed due to timeout.
215   @retval EFI_DEVICE_ERROR       Transfer failed due to host controller or device error.
216 
217 **/
218 EFI_STATUS
219 EFIAPI
220 UhcControlTransfer (
221   IN EFI_PEI_SERVICES               **PeiServices,
222   IN PEI_USB_HOST_CONTROLLER_PPI    * This,
223   IN     UINT8                      DeviceAddress,
224   IN     UINT8                      DeviceSpeed,
225   IN     UINT8                      MaximumPacketLength,
226   IN     EFI_USB_DEVICE_REQUEST     * Request,
227   IN     EFI_USB_DATA_DIRECTION     TransferDirection,
228   IN OUT VOID                       *Data OPTIONAL,
229   IN OUT UINTN                      *DataLength OPTIONAL,
230   IN     UINTN                      TimeOut,
231   OUT    UINT32                     *TransferResult
232   );
233 
234 /**
235   Submits bulk transfer to a bulk endpoint of a USB device.
236 
237   @param  PeiServices           The pointer of EFI_PEI_SERVICES.
238   @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
239   @param  DeviceAddress         Target device address.
240   @param  EndPointAddress       Endpoint number and its direction in bit 7.
241   @param  MaximumPacketLength   Maximum packet size the endpoint is capable of
242                                 sending or receiving.
243   @param  Data                  Array of pointers to the buffers of data to transmit
244                                 from or receive into.
245   @param  DataLength            The lenght of the data buffer.
246   @param  DataToggle            On input, the initial data toggle for the transfer;
247                                 On output, it is updated to to next data toggle to use of
248                                 the subsequent bulk transfer.
249   @param  TimeOut               Indicates the maximum time, in millisecond, which the
250                                 transfer is allowed to complete.
251   @param  TransferResult        A pointer to the detailed result information of the
252                                 bulk transfer.
253 
254   @retval EFI_SUCCESS           The transfer was completed successfully.
255   @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.
256   @retval EFI_INVALID_PARAMETER Parameters are invalid.
257   @retval EFI_TIMEOUT           The transfer failed due to timeout.
258   @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.
259 
260 **/
261 EFI_STATUS
262 EFIAPI
263 UhcBulkTransfer (
264   IN EFI_PEI_SERVICES               **PeiServices,
265   IN PEI_USB_HOST_CONTROLLER_PPI    *This,
266   IN  UINT8                         DeviceAddress,
267   IN  UINT8                         EndPointAddress,
268   IN  UINT8                         MaximumPacketLength,
269   IN OUT VOID                       *Data,
270   IN OUT UINTN                      *DataLength,
271   IN OUT UINT8                      *DataToggle,
272   IN  UINTN                         TimeOut,
273   OUT UINT32                        *TransferResult
274   );
275 
276 /**
277   Retrieves the number of root hub ports.
278 
279   @param[in]  PeiServices   The pointer to the PEI Services Table.
280   @param[in]  This          The pointer to this instance of the
281                             PEI_USB_HOST_CONTROLLER_PPI.
282   @param[out] PortNumber    The pointer to the number of the root hub ports.
283 
284   @retval EFI_SUCCESS           The port number was retrieved successfully.
285   @retval EFI_INVALID_PARAMETER PortNumber is NULL.
286 
287 **/
288 EFI_STATUS
289 EFIAPI
290 UhcGetRootHubPortNumber (
291   IN EFI_PEI_SERVICES               **PeiServices,
292   IN PEI_USB_HOST_CONTROLLER_PPI    *This,
293   OUT UINT8                         *PortNumber
294   );
295 
296 /**
297   Retrieves the current status of a USB root hub port.
298 
299   @param  PeiServices            The pointer of EFI_PEI_SERVICES.
300   @param  This                   The pointer of PEI_USB_HOST_CONTROLLER_PPI.
301   @param  PortNumber             The root hub port to retrieve the state from.
302   @param  PortStatus             Variable to receive the port state.
303 
304   @retval EFI_SUCCESS            The status of the USB root hub port specified.
305                                  by PortNumber was returned in PortStatus.
306   @retval EFI_INVALID_PARAMETER  PortNumber is invalid.
307 
308 **/
309 EFI_STATUS
310 EFIAPI
311 UhcGetRootHubPortStatus (
312   IN EFI_PEI_SERVICES               **PeiServices,
313   IN PEI_USB_HOST_CONTROLLER_PPI    *This,
314   IN  UINT8                         PortNumber,
315   OUT EFI_USB_PORT_STATUS           *PortStatus
316   );
317 
318 /**
319   Sets a feature for the specified root hub port.
320 
321   @param  PeiServices           The pointer of EFI_PEI_SERVICES
322   @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI
323   @param  PortNumber            Root hub port to set.
324   @param  PortFeature           Feature to set.
325 
326   @retval EFI_SUCCESS            The feature specified by PortFeature was set.
327   @retval EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.
328   @retval EFI_TIMEOUT            The time out occurred.
329 
330 **/
331 EFI_STATUS
332 EFIAPI
333 UhcSetRootHubPortFeature (
334   IN EFI_PEI_SERVICES               **PeiServices,
335   IN PEI_USB_HOST_CONTROLLER_PPI    *This,
336   IN UINT8                          PortNumber,
337   IN EFI_USB_PORT_FEATURE           PortFeature
338   );
339 
340 /**
341   Clears a feature for the specified root hub port.
342 
343   @param  PeiServices           The pointer of EFI_PEI_SERVICES.
344   @param  This                  The pointer of PEI_USB_HOST_CONTROLLER_PPI.
345   @param  PortNumber            Specifies the root hub port whose feature
346                                 is requested to be cleared.
347   @param  PortFeature           Indicates the feature selector associated with the
348                                 feature clear request.
349 
350   @retval EFI_SUCCESS            The feature specified by PortFeature was cleared
351                                  for the USB root hub port specified by PortNumber.
352   @retval EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.
353 
354 **/
355 EFI_STATUS
356 EFIAPI
357 UhcClearRootHubPortFeature (
358   IN EFI_PEI_SERVICES               **PeiServices,
359   IN PEI_USB_HOST_CONTROLLER_PPI    *This,
360   IN UINT8                          PortNumber,
361   IN EFI_USB_PORT_FEATURE           PortFeature
362   );
363 
364 /**
365   Initialize UHCI.
366 
367   @param  UhcDev                 UHCI Device.
368 
369   @retval EFI_SUCCESS            UHCI successfully initialized.
370   @retval EFI_OUT_OF_RESOURCES   Resource can not be allocated.
371 
372 **/
373 EFI_STATUS
374 InitializeUsbHC (
375   IN USB_UHC_DEV          *UhcDev
376   );
377 
378 /**
379   Create Frame List Structure.
380 
381   @param  UhcDev                 UHCI device.
382 
383   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
384   @retval EFI_SUCCESS            Success.
385 
386 **/
387 EFI_STATUS
388 CreateFrameList (
389   USB_UHC_DEV             *UhcDev
390   );
391 
392 /**
393   Read a 16bit width data from Uhc HC IO space register.
394 
395   @param  UhcDev  The UHCI device.
396   @param  Port    The IO space address of the register.
397 
398   @retval the register content read.
399 
400 **/
401 UINT16
402 USBReadPortW (
403   IN  USB_UHC_DEV   *UhcDev,
404   IN  UINT32        Port
405   );
406 
407 /**
408   Write a 16bit width data into Uhc HC IO space register.
409 
410   @param  UhcDev  The UHCI device.
411   @param  Port    The IO space address of the register.
412   @param  Data    The data written into the register.
413 
414 **/
415 VOID
416 USBWritePortW (
417   IN  USB_UHC_DEV   *UhcDev,
418   IN  UINT32        Port,
419   IN  UINT16        Data
420   );
421 
422 /**
423   Write a 32bit width data into Uhc HC IO space register.
424 
425   @param  UhcDev  The UHCI device.
426   @param  Port    The IO space address of the register.
427   @param  Data    The data written into the register.
428 
429 **/
430 VOID
431 USBWritePortDW (
432   IN  USB_UHC_DEV   *UhcDev,
433   IN  UINT32        Port,
434   IN  UINT32        Data
435   );
436 
437 /**
438   Clear the content of UHCI's Status Register.
439 
440   @param  UhcDev       The UHCI device.
441   @param  StatusAddr   The IO space address of the register.
442 
443 **/
444 VOID
445 ClearStatusReg (
446   IN  USB_UHC_DEV   *UhcDev,
447   IN  UINT32        StatusAddr
448   );
449 
450 /**
451   Check whether the host controller operates well.
452 
453   @param  UhcDev        The UHCI device.
454   @param  StatusRegAddr The io address of status register.
455 
456   @retval TRUE          Host controller is working.
457   @retval FALSE         Host controller is halted or system error.
458 
459 **/
460 BOOLEAN
461 IsStatusOK (
462   IN USB_UHC_DEV     *UhcDev,
463   IN UINT32          StatusRegAddr
464   );
465 
466 /**
467   Get Current Frame Number.
468 
469   @param  UhcDev          The UHCI device.
470   @param  FrameNumberAddr The address of frame list register.
471 
472   @retval The content of the frame list register.
473 
474 **/
475 UINT16
476 GetCurrentFrameNumber (
477   IN USB_UHC_DEV   *UhcDev,
478   IN UINT32        FrameNumberAddr
479   );
480 
481 /**
482   Set Frame List Base Address.
483 
484   @param  UhcDev           The UHCI device.
485   @param  FrameListRegAddr The address of frame list register.
486   @param  Addr             The address of frame list table.
487 
488 **/
489 VOID
490 SetFrameListBaseAddress (
491   IN USB_UHC_DEV   *UhcDev,
492   IN UINT32        FrameListRegAddr,
493   IN UINT32        Addr
494   );
495 
496 /**
497   Create QH and initialize.
498 
499   @param  UhcDev               The UHCI device.
500   @param  PtrQH                Place to store QH_STRUCT pointer.
501 
502   @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
503   @retval EFI_SUCCESS        Success.
504 
505 **/
506 EFI_STATUS
507 CreateQH (
508   IN  USB_UHC_DEV  *UhcDev,
509   OUT QH_STRUCT    **PtrQH
510   );
511 
512 /**
513   Set the horizontal link pointer in QH.
514 
515   @param  PtrQH               Place to store QH_STRUCT pointer.
516   @param  PtrNext             Place to the next QH_STRUCT.
517 
518 **/
519 VOID
520 SetQHHorizontalLinkPtr (
521   IN QH_STRUCT  *PtrQH,
522   IN VOID       *PtrNext
523   );
524 
525 /**
526   Get the horizontal link pointer in QH.
527 
528   @param  PtrQH     Place to store QH_STRUCT pointer.
529 
530   @retval The horizontal link pointer in QH.
531 
532 **/
533 VOID  *
534 GetQHHorizontalLinkPtr (
535   IN QH_STRUCT  *PtrQH
536   );
537 
538 /**
539   Set a QH or TD horizontally to be connected with a specific QH.
540 
541   @param  PtrQH      Place to store QH_STRUCT pointer.
542   @param  IsQH       Specify QH or TD is connected.
543 
544 **/
545 VOID
546 SetQHHorizontalQHorTDSelect (
547   IN QH_STRUCT  *PtrQH,
548   IN BOOLEAN    IsQH
549   );
550 
551 /**
552   Set the horizontal validor bit in QH.
553 
554   @param  PtrQH      Place to store QH_STRUCT pointer.
555   @param  IsValid    Specify the horizontal linker is valid or not.
556 
557 **/
558 VOID
559 SetQHHorizontalValidorInvalid (
560   IN QH_STRUCT  *PtrQH,
561   IN BOOLEAN    IsValid
562   );
563 
564 /**
565   Set the vertical link pointer in QH.
566 
567   @param  PtrQH       Place to store QH_STRUCT pointer.
568   @param  PtrNext     Place to the next QH_STRUCT.
569 
570 **/
571 VOID
572 SetQHVerticalLinkPtr (
573   IN QH_STRUCT  *PtrQH,
574   IN VOID       *PtrNext
575   );
576 
577 /**
578   Set a QH or TD vertically to be connected with a specific QH.
579 
580   @param  PtrQH      Place to store QH_STRUCT pointer.
581   @param  IsQH       Specify QH or TD is connected.
582 
583 **/
584 VOID
585 SetQHVerticalQHorTDSelect (
586   IN QH_STRUCT  *PtrQH,
587   IN BOOLEAN    IsQH
588   );
589 
590 /**
591   Set the vertical validor bit in QH.
592 
593   @param  PtrQH      Place to store QH_STRUCT pointer.
594   @param  IsValid    Specify the vertical linker is valid or not.
595 
596 **/
597 VOID
598 SetQHVerticalValidorInvalid (
599   IN QH_STRUCT  *PtrQH,
600   IN BOOLEAN    IsValid
601   );
602 
603 /**
604   Get the vertical validor bit in QH.
605 
606   @param  PtrQH      Place to store QH_STRUCT pointer.
607 
608   @retval The vertical linker is valid or not.
609 
610 **/
611 BOOLEAN
612 GetQHHorizontalValidorInvalid (
613   IN QH_STRUCT  *PtrQH
614   );
615 
616 /**
617   Allocate TD or QH Struct.
618 
619   @param  UhcDev                 The UHCI device.
620   @param  Size                   The size of allocation.
621   @param  PtrStruct              Place to store TD_STRUCT pointer.
622 
623   @return EFI_SUCCESS            Allocate successfully.
624   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.
625 
626 **/
627 EFI_STATUS
628 AllocateTDorQHStruct (
629   IN  USB_UHC_DEV   *UhcDev,
630   IN  UINT32        Size,
631   OUT VOID          **PtrStruct
632   );
633 
634 /**
635   Create a TD Struct.
636 
637   @param  UhcDev                 The UHCI device.
638   @param  PtrTD                  Place to store TD_STRUCT pointer.
639 
640   @return EFI_SUCCESS            Allocate successfully.
641   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.
642 
643 **/
644 EFI_STATUS
645 CreateTD (
646   IN  USB_UHC_DEV     *UhcDev,
647   OUT TD_STRUCT       **PtrTD
648   );
649 
650 /**
651   Generate Setup Stage TD.
652 
653   @param  UhcDev       The UHCI device.
654   @param  DevAddr      Device address.
655   @param  Endpoint     Endpoint number.
656   @param  DeviceSpeed  Device Speed.
657   @param  DevRequest   Device reuquest.
658   @param  RequestLen   Request length.
659   @param  PtrTD        TD_STRUCT generated.
660 
661   @return EFI_SUCCESS            Generate setup stage TD successfully.
662   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.
663 
664 **/
665 EFI_STATUS
666 GenSetupStageTD (
667   IN  USB_UHC_DEV     *UhcDev,
668   IN  UINT8           DevAddr,
669   IN  UINT8           Endpoint,
670   IN  UINT8           DeviceSpeed,
671   IN  UINT8           *DevRequest,
672   IN  UINT8           RequestLen,
673   OUT TD_STRUCT       **PtrTD
674   );
675 
676 /**
677   Generate Data Stage TD.
678 
679   @param  UhcDev       The UHCI device.
680   @param  DevAddr      Device address.
681   @param  Endpoint     Endpoint number.
682   @param  PtrData      Data buffer.
683   @param  Len          Data length.
684   @param  PktID        PacketID.
685   @param  Toggle       Data toggle value.
686   @param  DeviceSpeed  Device Speed.
687   @param  PtrTD        TD_STRUCT generated.
688 
689   @return EFI_SUCCESS            Generate data stage TD successfully.
690   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.
691 
692 **/
693 EFI_STATUS
694 GenDataTD (
695   IN  USB_UHC_DEV     *UhcDev,
696   IN  UINT8           DevAddr,
697   IN  UINT8           Endpoint,
698   IN  UINT8           *PtrData,
699   IN  UINT8           Len,
700   IN  UINT8           PktID,
701   IN  UINT8           Toggle,
702   IN  UINT8           DeviceSpeed,
703   OUT TD_STRUCT       **PtrTD
704   );
705 
706 /**
707   Generate Status Stage TD.
708 
709   @param  UhcDev       The UHCI device.
710   @param  DevAddr      Device address.
711   @param  Endpoint     Endpoint number.
712   @param  PktID        PacketID.
713   @param  DeviceSpeed  Device Speed.
714   @param  PtrTD        TD_STRUCT generated.
715 
716   @return EFI_SUCCESS            Generate status stage TD successfully.
717   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resource.
718 
719 **/
720 EFI_STATUS
721 CreateStatusTD (
722   IN  USB_UHC_DEV     *UhcDev,
723   IN  UINT8           DevAddr,
724   IN  UINT8           Endpoint,
725   IN  UINT8           PktID,
726   IN  UINT8           DeviceSpeed,
727   OUT TD_STRUCT       **PtrTD
728   );
729 
730 /**
731   Set the link pointer validor bit in TD.
732 
733   @param  PtrTDStruct  Place to store TD_STRUCT pointer.
734   @param  IsValid      Specify the linker pointer is valid or not.
735 
736 **/
737 VOID
738 SetTDLinkPtrValidorInvalid (
739   IN  TD_STRUCT *PtrTDStruct,
740   IN  BOOLEAN   IsValid
741   );
742 
743 /**
744   Set the Link Pointer pointing to a QH or TD.
745 
746   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
747   @param  IsQH          Specify QH or TD is connected.
748 
749 **/
750 VOID
751 SetTDLinkPtrQHorTDSelect (
752   IN  TD_STRUCT *PtrTDStruct,
753   IN  BOOLEAN   IsQH
754   );
755 
756 /**
757   Set the traverse is depth-first or breadth-first.
758 
759   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
760   @param  IsDepth       Specify the traverse is depth-first or breadth-first.
761 
762 **/
763 VOID
764 SetTDLinkPtrDepthorBreadth (
765   IN  TD_STRUCT *PtrTDStruct,
766   IN  BOOLEAN   IsDepth
767   );
768 
769 /**
770   Set TD Link Pointer in TD.
771 
772   @param  PtrTDStruct  Place to store TD_STRUCT pointer.
773   @param  PtrNext      Place to the next TD_STRUCT.
774 
775 **/
776 VOID
777 SetTDLinkPtr (
778   IN  TD_STRUCT *PtrTDStruct,
779   IN  VOID      *PtrNext
780   );
781 
782 /**
783   Get TD Link Pointer.
784 
785   @param  PtrTDStruct     Place to store TD_STRUCT pointer.
786 
787   @retval Get TD Link Pointer in TD.
788 
789 **/
790 VOID*
791 GetTDLinkPtr (
792   IN  TD_STRUCT *PtrTDStruct
793   );
794 
795 /**
796   Get the information about whether the Link Pointer field pointing to
797   a QH or a TD.
798 
799   @param  PtrTDStruct     Place to store TD_STRUCT pointer.
800 
801   @retval whether the Link Pointer field pointing to a QH or a TD.
802 
803 **/
804 BOOLEAN
805 IsTDLinkPtrQHOrTD (
806   IN  TD_STRUCT *PtrTDStruct
807   );
808 
809 /**
810   Enable/Disable short packet detection mechanism.
811 
812   @param  PtrTDStruct  Place to store TD_STRUCT pointer.
813   @param  IsEnable     Enable or disable short packet detection mechanism.
814 
815 **/
816 VOID
817 EnableorDisableTDShortPacket (
818   IN  TD_STRUCT *PtrTDStruct,
819   IN  BOOLEAN   IsEnable
820   );
821 
822 /**
823   Set the max error counter in TD.
824 
825   @param  PtrTDStruct  Place to store TD_STRUCT pointer.
826   @param  MaxErrors    The number of allowable error.
827 
828 **/
829 VOID
830 SetTDControlErrorCounter (
831   IN  TD_STRUCT *PtrTDStruct,
832   IN  UINT8     MaxErrors
833   );
834 
835 /**
836   Set the TD is targeting a low-speed device or not.
837 
838   @param  PtrTDStruct       Place to store TD_STRUCT pointer.
839   @param  IsLowSpeedDevice  Whether The device is low-speed.
840 
841 **/
842 VOID
843 SetTDLoworFullSpeedDevice (
844   IN  TD_STRUCT *PtrTDStruct,
845   IN  BOOLEAN   IsLowSpeedDevice
846   );
847 
848 /**
849   Set the TD is isochronous transfer type or not.
850 
851   @param  PtrTDStruct       Place to store TD_STRUCT pointer.
852   @param  IsIsochronous     Whether the transaction isochronous transfer type.
853 
854 **/
855 VOID
856 SetTDControlIsochronousorNot (
857   IN  TD_STRUCT *PtrTDStruct,
858   IN  BOOLEAN   IsIsochronous
859   );
860 
861 /**
862   Set if UCHI should issue an interrupt on completion of the frame
863   in which this TD is executed
864 
865   @param  PtrTDStruct       Place to store TD_STRUCT pointer.
866   @param  IsSet             Whether HC should issue an interrupt on completion.
867 
868 **/
869 VOID
870 SetorClearTDControlIOC (
871   IN  TD_STRUCT *PtrTDStruct,
872   IN  BOOLEAN   IsSet
873   );
874 
875 /**
876   Set if the TD is active and can be executed.
877 
878   @param  PtrTDStruct       Place to store TD_STRUCT pointer.
879   @param  IsActive          Whether the TD is active and can be executed.
880 
881 **/
882 VOID
883 SetTDStatusActiveorInactive (
884   IN  TD_STRUCT *PtrTDStruct,
885   IN  BOOLEAN   IsActive
886   );
887 
888 /**
889   Specifies the maximum number of data bytes allowed for the transfer.
890 
891   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
892   @param  MaxLen        The maximum number of data bytes allowed.
893 
894   @retval The allowed maximum number of data.
895 **/
896 UINT16
897 SetTDTokenMaxLength (
898   IN  TD_STRUCT *PtrTDStruct,
899   IN  UINT16    MaxLen
900   );
901 
902 /**
903   Set the data toggle bit to DATA1.
904 
905   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
906 
907 **/
908 VOID
909 SetTDTokenDataToggle1 (
910   IN  TD_STRUCT *PtrTDStruct
911   );
912 
913 /**
914   Set the data toggle bit to DATA0.
915 
916   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
917 
918 **/
919 VOID
920 SetTDTokenDataToggle0 (
921   IN  TD_STRUCT *PtrTDStruct
922   );
923 
924 /**
925   Set EndPoint Number the TD is targeting at.
926 
927   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
928   @param  EndPoint      The Endport number of the target.
929 
930 **/
931 VOID
932 SetTDTokenEndPoint (
933   IN  TD_STRUCT *PtrTDStruct,
934   IN  UINTN     EndPoint
935   );
936 
937 /**
938   Set Device Address the TD is targeting at.
939 
940   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
941   @param  DevAddr       The Device Address of the target.
942 
943 **/
944 VOID
945 SetTDTokenDeviceAddress (
946   IN  TD_STRUCT *PtrTDStruct,
947   IN  UINTN     DevAddr
948   );
949 
950 /**
951   Set Packet Identification the TD is targeting at.
952 
953   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
954   @param  PacketID      The Packet Identification of the target.
955 
956 **/
957 VOID
958 SetTDTokenPacketID (
959   IN  TD_STRUCT *PtrTDStruct,
960   IN  UINT8     PacketID
961   );
962 
963 /**
964   Set the beginning address of the data buffer that will be used
965   during the transaction.
966 
967   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
968 
969 **/
970 VOID
971 SetTDDataBuffer (
972   IN  TD_STRUCT *PtrTDStruct
973   );
974 
975 /**
976   Detect whether the TD is active.
977 
978   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
979 
980   @retval The TD is active or not.
981 
982 **/
983 BOOLEAN
984 IsTDStatusActive (
985   IN  TD_STRUCT *PtrTDStruct
986   );
987 
988 /**
989   Detect whether the TD is stalled.
990 
991   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
992 
993   @retval The TD is stalled or not.
994 
995 **/
996 BOOLEAN
997 IsTDStatusStalled (
998   IN  TD_STRUCT *PtrTDStruct
999   );
1000 
1001 /**
1002   Detect whether Data Buffer Error is happened.
1003 
1004   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
1005 
1006   @retval The Data Buffer Error is happened or not.
1007 
1008 **/
1009 BOOLEAN
1010 IsTDStatusBufferError (
1011   IN  TD_STRUCT *PtrTDStruct
1012   );
1013 
1014 /**
1015   Detect whether Babble Error is happened.
1016 
1017   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
1018 
1019   @retval The Babble Error is happened or not.
1020 
1021 **/
1022 BOOLEAN
1023 IsTDStatusBabbleError (
1024   IN  TD_STRUCT *PtrTDStruct
1025   );
1026 
1027 /**
1028   Detect whether NAK is received.
1029 
1030   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
1031 
1032   @retval The NAK is received or not.
1033 
1034 **/
1035 BOOLEAN
1036 IsTDStatusNAKReceived (
1037   IN  TD_STRUCT *PtrTDStruct
1038   );
1039 
1040 /**
1041   Detect whether CRC/Time Out Error is encountered.
1042 
1043   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
1044 
1045   @retval The CRC/Time Out Error is encountered or not.
1046 
1047 **/
1048 BOOLEAN
1049 IsTDStatusCRCTimeOutError (
1050   IN  TD_STRUCT *PtrTDStruct
1051   );
1052 
1053 /**
1054   Detect whether Bitstuff Error is received.
1055 
1056   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
1057 
1058   @retval The Bitstuff Error is received or not.
1059 
1060 **/
1061 BOOLEAN
1062 IsTDStatusBitStuffError (
1063   IN  TD_STRUCT *PtrTDStruct
1064   );
1065 
1066 /**
1067   Retrieve the actual number of bytes that were tansferred.
1068 
1069   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
1070 
1071   @retval The actual number of bytes that were tansferred.
1072 
1073 **/
1074 UINT16
1075 GetTDStatusActualLength (
1076   IN  TD_STRUCT *PtrTDStruct
1077   );
1078 
1079 /**
1080   Retrieve the information of whether the Link Pointer field is valid or not.
1081 
1082   @param  PtrTDStruct   Place to store TD_STRUCT pointer.
1083 
1084   @retval The linker pointer field is valid or not.
1085 
1086 **/
1087 BOOLEAN
1088 GetTDLinkPtrValidorInvalid (
1089   IN  TD_STRUCT *PtrTDStruct
1090   );
1091 
1092 /**
1093   Count TD Number from PtrFirstTD.
1094 
1095   @param  PtrFirstTD   Place to store TD_STRUCT pointer.
1096 
1097   @retval The queued TDs number.
1098 
1099 **/
1100 UINTN
1101 CountTDsNumber (
1102   IN  TD_STRUCT *PtrFirstTD
1103   );
1104 
1105 /**
1106   Link TD To QH.
1107 
1108   @param  PtrQH   Place to store QH_STRUCT pointer.
1109   @param  PtrTD   Place to store TD_STRUCT pointer.
1110 
1111 **/
1112 VOID
1113 LinkTDToQH (
1114   IN  QH_STRUCT *PtrQH,
1115   IN  TD_STRUCT *PtrTD
1116   );
1117 
1118 /**
1119   Link TD To TD.
1120 
1121   @param  PtrPreTD  Place to store TD_STRUCT pointer.
1122   @param  PtrTD     Place to store TD_STRUCT pointer.
1123 
1124 **/
1125 VOID
1126 LinkTDToTD (
1127   IN  TD_STRUCT *PtrPreTD,
1128   IN  TD_STRUCT *PtrTD
1129   );
1130 
1131 /**
1132   Execute Control Transfer.
1133 
1134   @param  UhcDev            The UCHI device.
1135   @param  PtrTD             A pointer to TD_STRUCT data.
1136   @param  ActualLen         Actual transfer Length.
1137   @param  TimeOut           TimeOut value.
1138   @param  TransferResult    Transfer Result.
1139 
1140   @return EFI_DEVICE_ERROR  The transfer failed due to transfer error.
1141   @return EFI_TIMEOUT       The transfer failed due to time out.
1142   @return EFI_SUCCESS       The transfer finished OK.
1143 
1144 **/
1145 EFI_STATUS
1146 ExecuteControlTransfer (
1147   IN  USB_UHC_DEV *UhcDev,
1148   IN  TD_STRUCT   *PtrTD,
1149   OUT UINTN       *ActualLen,
1150   IN  UINTN       TimeOut,
1151   OUT UINT32      *TransferResult
1152   );
1153 
1154 /**
1155   Execute Bulk Transfer.
1156 
1157   @param  UhcDev            The UCHI device.
1158   @param  PtrTD             A pointer to TD_STRUCT data.
1159   @param  ActualLen         Actual transfer Length.
1160   @param  DataToggle        DataToggle value.
1161   @param  TimeOut           TimeOut value.
1162   @param  TransferResult    Transfer Result.
1163 
1164   @return EFI_DEVICE_ERROR  The transfer failed due to transfer error.
1165   @return EFI_TIMEOUT       The transfer failed due to time out.
1166   @return EFI_SUCCESS       The transfer finished OK.
1167 
1168 **/
1169 EFI_STATUS
1170 ExecBulkTransfer (
1171   IN     USB_UHC_DEV *UhcDev,
1172   IN     TD_STRUCT   *PtrTD,
1173   IN OUT UINTN     *ActualLen,
1174   IN     UINT8     *DataToggle,
1175   IN     UINTN     TimeOut,
1176   OUT    UINT32    *TransferResult
1177   );
1178 
1179 /**
1180   Delete Queued TDs.
1181 
1182   @param  UhcDev       The UCHI device.
1183   @param  PtrFirstTD   Place to store TD_STRUCT pointer.
1184 
1185 **/
1186 VOID
1187 DeleteQueuedTDs (
1188   IN USB_UHC_DEV     *UhcDev,
1189   IN TD_STRUCT       *PtrFirstTD
1190   );
1191 
1192 /**
1193   Check TDs Results.
1194 
1195   @param  PtrTD               A pointer to TD_STRUCT data.
1196   @param  Result              The result to return.
1197   @param  ErrTDPos            The Error TD position.
1198   @param  ActualTransferSize  Actual transfer size.
1199 
1200   @retval The TD is executed successfully or not.
1201 
1202 **/
1203 BOOLEAN
1204 CheckTDsResults (
1205   IN  TD_STRUCT               *PtrTD,
1206   OUT UINT32                  *Result,
1207   OUT UINTN                   *ErrTDPos,
1208   OUT UINTN                   *ActualTransferSize
1209   );
1210 
1211 /**
1212   Create Memory Block.
1213 
1214   @param  UhcDev                   The UCHI device.
1215   @param  MemoryHeader             The Pointer to allocated memory block.
1216   @param  MemoryBlockSizeInPages   The page size of memory block to be allocated.
1217 
1218   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
1219   @retval EFI_SUCCESS            Success.
1220 
1221 **/
1222 EFI_STATUS
1223 CreateMemoryBlock (
1224   IN  USB_UHC_DEV           *UhcDev,
1225   OUT MEMORY_MANAGE_HEADER  **MemoryHeader,
1226   IN  UINTN                 MemoryBlockSizeInPages
1227   );
1228 
1229 /**
1230   Initialize UHCI memory management.
1231 
1232   @param  UhcDev                 The UCHI device.
1233 
1234   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
1235   @retval EFI_SUCCESS            Success.
1236 
1237 **/
1238 EFI_STATUS
1239 InitializeMemoryManagement (
1240   IN USB_UHC_DEV           *UhcDev
1241   );
1242 
1243 /**
1244   Initialize UHCI memory management.
1245 
1246   @param  UhcDev           The UCHI device.
1247   @param  Pool             Buffer pointer to store the buffer pointer.
1248   @param  AllocSize        The size of the pool to be allocated.
1249 
1250   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
1251   @retval EFI_SUCCESS            Success.
1252 
1253 **/
1254 EFI_STATUS
1255 UhcAllocatePool (
1256   IN  USB_UHC_DEV     *UhcDev,
1257   OUT UINT8           **Pool,
1258   IN  UINTN           AllocSize
1259   );
1260 
1261 /**
1262   Alloc Memory In MemoryBlock.
1263 
1264   @param  MemoryHeader           The pointer to memory manage header.
1265   @param  Pool                   Buffer pointer to store the buffer pointer.
1266   @param  NumberOfMemoryUnit     The size of the pool to be allocated.
1267 
1268   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
1269   @retval EFI_SUCCESS            Success.
1270 
1271 **/
1272 EFI_STATUS
1273 AllocMemInMemoryBlock (
1274   IN  MEMORY_MANAGE_HEADER  *MemoryHeader,
1275   OUT VOID                  **Pool,
1276   IN  UINTN                 NumberOfMemoryUnit
1277   );
1278 
1279 /**
1280   Uhci Free Pool.
1281 
1282   @param  UhcDev                 The UHCI device.
1283   @param  Pool                   A pointer to store the buffer address.
1284   @param  AllocSize              The size of the pool to be freed.
1285 
1286 **/
1287 VOID
1288 UhcFreePool (
1289   IN USB_UHC_DEV     *UhcDev,
1290   IN UINT8           *Pool,
1291   IN UINTN           AllocSize
1292   );
1293 
1294 /**
1295   Insert a new memory header into list.
1296 
1297   @param  MemoryHeader         A pointer to the memory header list.
1298   @param  NewMemoryHeader      A new memory header to be inserted into the list.
1299 
1300 **/
1301 VOID
1302 InsertMemoryHeaderToList (
1303   IN MEMORY_MANAGE_HEADER  *MemoryHeader,
1304   IN MEMORY_MANAGE_HEADER  *NewMemoryHeader
1305   );
1306 
1307 /**
1308   Judge the memory block in the memory header is empty or not.
1309 
1310   @param  MemoryHeaderPtr   A pointer to the memory header list.
1311 
1312   @retval Whether the memory block in the memory header is empty or not.
1313 
1314 **/
1315 BOOLEAN
1316 IsMemoryBlockEmptied (
1317   IN MEMORY_MANAGE_HEADER  *MemoryHeaderPtr
1318   );
1319 
1320 /**
1321   remove a memory header from list.
1322 
1323   @param  FirstMemoryHeader   A pointer to the memory header list.
1324   @param  FreeMemoryHeader    A memory header to be removed into the list.
1325 
1326 **/
1327 VOID
1328 DelinkMemoryBlock (
1329   IN MEMORY_MANAGE_HEADER    *FirstMemoryHeader,
1330   IN MEMORY_MANAGE_HEADER    *FreeMemoryHeader
1331   );
1332 
1333 #endif
1334