--- /dev/null
+/** @file\r
+This file contains URB request, each request is warpped in a\r
+URB (Usb Request Block).\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+\r
+#include "OhcPeim.h"\r
+\r
+\r
+/**\r
+\r
+ Create a TD\r
+\r
+ @Param Ohc UHC private data\r
+\r
+ @retval TD structure pointer\r
+\r
+**/\r
+TD_DESCRIPTOR *\r
+OhciCreateTD (\r
+ IN USB_OHCI_HC_DEV *Ohc\r
+ )\r
+{\r
+ TD_DESCRIPTOR *Td;\r
+\r
+ Td = UsbHcAllocateMem(Ohc->MemPool, sizeof(TD_DESCRIPTOR));\r
+ if (Td == NULL) {\r
+ return NULL;\r
+ }\r
+ Td->CurrBufferPointer = NULL;\r
+ Td->NextTD = NULL;\r
+ Td->BufferEndPointer = NULL;\r
+ Td->NextTDPointer = NULL;\r
+\r
+ return Td;\r
+}\r
+\r
+\r
+/**\r
+\r
+ Free a TD\r
+\r
+ @Param Ohc UHC private data\r
+ @Param Td Pointer to a TD to free\r
+\r
+ @retval EFI_SUCCESS TD freed\r
+\r
+**/\r
+EFI_STATUS\r
+OhciFreeTD (\r
+ IN USB_OHCI_HC_DEV *Ohc,\r
+ IN TD_DESCRIPTOR *Td\r
+ )\r
+{\r
+ if (Td == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+\r
+ Create a ED\r
+\r
+ @Param Ohc Device private data\r
+\r
+ @retval ED descriptor pointer\r
+\r
+**/\r
+ED_DESCRIPTOR *\r
+OhciCreateED (\r
+ USB_OHCI_HC_DEV *Ohc\r
+ )\r
+{\r
+ ED_DESCRIPTOR *Ed;\r
+ Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));\r
+ if (Ed == NULL) {\r
+ return NULL;\r
+ }\r
+ Ed->Word0.Skip = 1;\r
+ Ed->TdTailPointer = NULL;\r
+ Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) NULL);\r
+ Ed->NextED = NULL;\r
+\r
+ return Ed;\r
+}\r
+\r
+/**\r
+\r
+ Free a ED\r
+\r
+ @Param Ohc UHC private data\r
+ @Param Ed Pointer to a ED to free\r
+\r
+ @retval EFI_SUCCESS ED freed\r
+\r
+**/\r
+\r
+EFI_STATUS\r
+OhciFreeED (\r
+ IN USB_OHCI_HC_DEV *Ohc,\r
+ IN ED_DESCRIPTOR *Ed\r
+ )\r
+{\r
+ if (Ed == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+ Free ED\r
+\r
+ @Param Ohc Device private data\r
+ @Param Ed Pointer to a ED to free\r
+\r
+ @retval EFI_SUCCESS ED freed\r
+\r
+**/\r
+EFI_STATUS\r
+OhciFreeAllTDFromED (\r
+ IN USB_OHCI_HC_DEV *Ohc,\r
+ IN ED_DESCRIPTOR *Ed\r
+ )\r
+{\r
+ TD_DESCRIPTOR *HeadTd;\r
+ TD_DESCRIPTOR *TailTd;\r
+ TD_DESCRIPTOR *Td;\r
+ TD_DESCRIPTOR *TempTd;\r
+\r
+ if (Ed == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ HeadTd = TD_PTR (Ed->Word2.TdHeadPointer);\r
+ TailTd = Ed->TdTailPointer;\r
+\r
+ Td = HeadTd;\r
+ while (Td != TailTd) {\r
+ TempTd = Td;\r
+ Td = Td->NextTDPointer;\r
+ OhciFreeTD (Ohc, TempTd);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+ Attach an ED\r
+\r
+ @Param Ed Ed to be attached\r
+ @Param NewEd Ed to attach\r
+\r
+ @retval EFI_SUCCESS NewEd attached to Ed\r
+ @retval EFI_INVALID_PARAMETER Ed is NULL\r
+\r
+**/\r
+EFI_STATUS\r
+OhciAttachED (\r
+ IN ED_DESCRIPTOR *Ed,\r
+ IN ED_DESCRIPTOR *NewEd\r
+ )\r
+{\r
+ ED_DESCRIPTOR *Temp;\r
+\r
+ if (Ed == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Ed->NextED == NULL){\r
+ Ed->NextED = NewEd;\r
+ } else {\r
+ Temp = Ed->NextED;\r
+ Ed->NextED = NewEd;\r
+ NewEd->NextED = Temp;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+/**\r
+\r
+ Attach an ED to an ED list\r
+\r
+ @Param OHC UHC private data\r
+ @Param ListType Type of the ED list\r
+ @Param Ed ED to attach\r
+ @Param EdList ED list to be attached\r
+\r
+ @retval EFI_SUCCESS ED attached to ED list\r
+\r
+**/\r
+EFI_STATUS\r
+OhciAttachEDToList (\r
+ IN USB_OHCI_HC_DEV *Ohc,\r
+ IN DESCRIPTOR_LIST_TYPE ListType,\r
+ IN ED_DESCRIPTOR *Ed,\r
+ IN ED_DESCRIPTOR *EdList\r
+ )\r
+{\r
+ ED_DESCRIPTOR *HeadEd;\r
+\r
+ switch(ListType) {\r
+ case CONTROL_LIST:\r
+ HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_CONTROL_HEAD);\r
+ if (HeadEd == NULL) {\r
+ OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, Ed);\r
+ } else {\r
+ OhciAttachED (HeadEd, Ed);\r
+ }\r
+ break;\r
+\r
+ case BULK_LIST:\r
+ HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_BULK_HEAD);\r
+ if (HeadEd == NULL) {\r
+ OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, Ed);\r
+ } else {\r
+ OhciAttachED (HeadEd, Ed);\r
+ }\r
+ break;\r
+\r
+ case INTERRUPT_LIST:\r
+ OhciAttachED (EdList, Ed);\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+/**\r
+\r
+ Link Td2 to the end of Td1\r
+\r
+ @Param Td1 TD to be linked\r
+ @Param Td2 TD to link\r
+\r
+ @retval EFI_SUCCESS TD successfully linked\r
+ @retval EFI_INVALID_PARAMETER Td1 is NULL\r
+\r
+**/\r
+EFI_STATUS\r
+OhciLinkTD (\r
+ IN TD_DESCRIPTOR *Td1,\r
+ IN TD_DESCRIPTOR *Td2\r
+ )\r
+{\r
+ TD_DESCRIPTOR *TempTd;\r
+\r
+ if (Td1 == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Td1 == Td2) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ TempTd = Td1;\r
+ while (TempTd->NextTD != NULL) {\r
+ TempTd = TempTd->NextTD;\r
+ }\r
+\r
+ TempTd->NextTD = Td2;\r
+ TempTd->NextTDPointer = Td2;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+\r
+ Attach TD list to ED\r
+\r
+ @Param Ed ED which TD list attach on\r
+ @Param HeadTd Head of the TD list to attach\r
+\r
+ @retval EFI_SUCCESS TD list attached on the ED\r
+\r
+**/\r
+EFI_STATUS\r
+OhciAttachTDListToED (\r
+ IN ED_DESCRIPTOR *Ed,\r
+ IN TD_DESCRIPTOR *HeadTd\r
+ )\r
+{\r
+ TD_DESCRIPTOR *TempTd;\r
+\r
+ TempTd = TD_PTR (Ed->Word2.TdHeadPointer);\r
+\r
+ if (TempTd != NULL) {\r
+ while (TempTd->NextTD != NULL) {\r
+ TempTd = TempTd->NextTD;\r
+ }\r
+ TempTd->NextTD = HeadTd;\r
+ TempTd->NextTDPointer = HeadTd;\r
+ } else {\r
+ Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) HeadTd);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+\r
+ Set value to ED specific field\r
+\r
+ @Param Ed ED to be set\r
+ @Param Field Field to be set\r
+ @Param Value Value to set\r
+\r
+ @retval EFI_SUCCESS Value set\r
+\r
+**/\r
+EFI_STATUS\r
+OhciSetEDField (\r
+ IN ED_DESCRIPTOR *Ed,\r
+ IN UINT32 Field,\r
+ IN UINT32 Value\r
+ )\r
+{\r
+ if (Field & ED_FUNC_ADD) {\r
+ Ed->Word0.FunctionAddress = Value;\r
+ }\r
+ if (Field & ED_ENDPT_NUM) {\r
+ Ed->Word0.EndPointNum = Value;\r
+ }\r
+ if (Field & ED_DIR) {\r
+ Ed->Word0.Direction = Value;\r
+ }\r
+ if (Field & ED_SPEED) {\r
+ Ed->Word0.Speed = Value;\r
+ }\r
+ if (Field & ED_SKIP) {\r
+ Ed->Word0.Skip = Value;\r
+ }\r
+ if (Field & ED_FORMAT) {\r
+ Ed->Word0.Format = Value;\r
+ }\r
+ if (Field & ED_MAX_PACKET) {\r
+ Ed->Word0.MaxPacketSize = Value;\r
+ }\r
+ if (Field & ED_PDATA) {\r
+ Ed->Word0.FreeSpace = Value;\r
+ }\r
+ if (Field & ED_ZERO) {\r
+ Ed->Word2.Zero = Value;\r
+ }\r
+ if (Field & ED_TDTAIL_PTR) {\r
+ Ed->TdTailPointer = (VOID *) Value;\r
+ }\r
+\r
+ if (Field & ED_HALTED) {\r
+ Ed->Word2.Halted = Value;\r
+ }\r
+ if (Field & ED_DTTOGGLE) {\r
+ Ed->Word2.ToggleCarry = Value;\r
+ }\r
+ if (Field & ED_TDHEAD_PTR) {\r
+ Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 (Value);\r
+ }\r
+\r
+ if (Field & ED_NEXT_EDPTR) {\r
+ Ed->NextED = (VOID *) Value;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+ Get value from an ED's specific field\r
+\r
+ @Param Ed ED pointer\r
+ @Param Field Field to get value from\r
+\r
+ @retval Value of the field\r
+\r
+**/\r
+UINT32\r
+OhciGetEDField (\r
+ IN ED_DESCRIPTOR *Ed,\r
+ IN UINT32 Field\r
+ )\r
+{\r
+ switch (Field) {\r
+ case ED_FUNC_ADD:\r
+ return Ed->Word0.FunctionAddress;\r
+ break;\r
+ case ED_ENDPT_NUM:\r
+ return Ed->Word0.EndPointNum;\r
+ break;\r
+ case ED_DIR:\r
+ return Ed->Word0.Direction;\r
+ break;\r
+ case ED_SPEED:\r
+ return Ed->Word0.Speed;\r
+ break;\r
+ case ED_SKIP:\r
+ return Ed->Word0.Skip;\r
+ break;\r
+ case ED_FORMAT:\r
+ return Ed->Word0.Format;\r
+ break;\r
+ case ED_MAX_PACKET:\r
+ return Ed->Word0.MaxPacketSize;\r
+ break;\r
+\r
+ case ED_TDTAIL_PTR:\r
+ return (UINT32) Ed->TdTailPointer;\r
+ break;\r
+\r
+ case ED_HALTED:\r
+ return Ed->Word2.Halted;\r
+ break;\r
+\r
+ case ED_DTTOGGLE:\r
+ return Ed->Word2.ToggleCarry;\r
+ break;\r
+\r
+ case ED_TDHEAD_PTR:\r
+ return Ed->Word2.TdHeadPointer << 4;\r
+ break;\r
+\r
+ case ED_NEXT_EDPTR:\r
+ return (UINT32) Ed->NextED;\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+/**\r
+\r
+ Set value to TD specific field\r
+\r
+ @Param Td TD to be set\r
+ @Param Field Field to be set\r
+ @Param Value Value to set\r
+\r
+ @retval EFI_SUCCESS Value set\r
+\r
+**/\r
+EFI_STATUS\r
+OhciSetTDField (\r
+ IN TD_DESCRIPTOR *Td,\r
+ IN UINT32 Field,\r
+ IN UINT32 Value\r
+ )\r
+{\r
+ if (Field & TD_PDATA) {\r
+ Td->Word0.Reserved = Value;\r
+ }\r
+ if (Field & TD_BUFFER_ROUND) {\r
+ Td->Word0.BufferRounding = Value;\r
+ }\r
+ if (Field & TD_DIR_PID) {\r
+ Td->Word0.DirPID = Value;\r
+ }\r
+ if (Field & TD_DELAY_INT) {\r
+ Td->Word0.DelayInterrupt = Value;\r
+ }\r
+ if (Field & TD_DT_TOGGLE) {\r
+ Td->Word0.DataToggle = Value | 0x2;\r
+ }\r
+ if (Field & TD_ERROR_CNT) {\r
+ Td->Word0.ErrorCount = Value;\r
+ }\r
+ if (Field & TD_COND_CODE) {\r
+ Td->Word0.ConditionCode = Value;\r
+ }\r
+\r
+ if (Field & TD_CURR_BUFFER_PTR) {\r
+ Td->CurrBufferPointer = (VOID *) Value;\r
+ }\r
+\r
+\r
+ if (Field & TD_NEXT_PTR) {\r
+ Td->NextTD = (VOID *) Value;\r
+ }\r
+\r
+ if (Field & TD_BUFFER_END_PTR) {\r
+ Td->BufferEndPointer = (VOID *) Value;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+\r
+ Get value from ED specific field\r
+\r
+ @Param Td TD pointer\r
+ @Param Field Field to get value from\r
+\r
+ @retval Value of the field\r
+\r
+**/\r
+\r
+UINT32\r
+OhciGetTDField (\r
+ IN TD_DESCRIPTOR *Td,\r
+ IN UINT32 Field\r
+ )\r
+{\r
+ switch (Field){\r
+ case TD_BUFFER_ROUND:\r
+ return Td->Word0.BufferRounding;\r
+ break;\r
+ case TD_DIR_PID:\r
+ return Td->Word0.DirPID;\r
+ break;\r
+ case TD_DELAY_INT:\r
+ return Td->Word0.DelayInterrupt;\r
+ break;\r
+ case TD_DT_TOGGLE:\r
+ return Td->Word0.DataToggle;\r
+ break;\r
+ case TD_ERROR_CNT:\r
+ return Td->Word0.ErrorCount;\r
+ break;\r
+ case TD_COND_CODE:\r
+ return Td->Word0.ConditionCode;\r
+ break;\r
+ case TD_CURR_BUFFER_PTR:\r
+ return (UINT32) Td->CurrBufferPointer;\r
+ break;\r
+\r
+ case TD_NEXT_PTR:\r
+ return (UINT32) Td->NextTD;\r
+ break;\r
+\r
+ case TD_BUFFER_END_PTR:\r
+ return (UINT32) Td->BufferEndPointer;\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ }\r
+\r
+ return 0;\r
+}\r