\r
EHCI transfer scheduling routines.\r
\r
-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\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
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
//\r
Ehc->MemPool = UsbHcInitMemPool (\r
PciIo,\r
- EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT),\r
+ Ehc->Support64BitDma,\r
EHC_HIGH_32BIT (PhyAddr)\r
);\r
\r
}\r
}\r
\r
+/**\r
+ Insert a single asynchronous interrupt transfer for\r
+ the device and endpoint.\r
+\r
+ @param Ehc The EHCI device.\r
+ @param DevAddr The device address.\r
+ @param EpAddr Endpoint addrress & its direction.\r
+ @param DevSpeed The device speed.\r
+ @param Toggle Initial data toggle to use.\r
+ @param MaxPacket The max packet length of the endpoint.\r
+ @param Hub The transaction translator to use.\r
+ @param DataLen The length of data buffer.\r
+ @param Callback The function to call when data is transferred.\r
+ @param Context The context to the callback.\r
+ @param Interval The interval for interrupt transfer.\r
+\r
+ @return Created URB or NULL.\r
+\r
+**/\r
+URB *\r
+EhciInsertAsyncIntTransfer (\r
+ IN USB2_HC_DEV *Ehc,\r
+ IN UINT8 DevAddr,\r
+ IN UINT8 EpAddr,\r
+ IN UINT8 DevSpeed,\r
+ IN UINT8 Toggle,\r
+ IN UINTN MaxPacket,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub,\r
+ IN UINTN DataLen,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,\r
+ IN VOID *Context,\r
+ IN UINTN Interval\r
+ )\r
+{\r
+ VOID *Data;\r
+ URB *Urb;\r
+\r
+ Data = AllocatePool (DataLen);\r
+\r
+ if (Data == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "%a: failed to allocate buffer\n", __FUNCTION__));\r
+ return NULL;\r
+ }\r
+\r
+ Urb = EhcCreateUrb (\r
+ Ehc,\r
+ DevAddr,\r
+ EpAddr,\r
+ DevSpeed,\r
+ Toggle,\r
+ MaxPacket,\r
+ Hub,\r
+ EHC_INT_TRANSFER_ASYNC,\r
+ NULL,\r
+ Data,\r
+ DataLen,\r
+ Callback,\r
+ Context,\r
+ Interval\r
+ );\r
+\r
+ if (Urb == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "%a: failed to create URB\n", __FUNCTION__));\r
+ gBS->FreePool (Data);\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // New asynchronous transfer must inserted to the head.\r
+ // Check the comments in EhcMoniteAsyncRequests\r
+ //\r
+ EhcLinkQhToPeriod (Ehc, Urb->Qh);\r
+ InsertHeadList (&Ehc->AsyncIntTransfers, &Urb->UrbList);\r
+\r
+ return Urb;\r
+}\r
\r
/**\r
Flush data from PCI controller specific address to mapped system\r
//\r
// calculate physical address by offset.\r
//\r
- PciAddr = (UINTN)Urb->DataPhy + ((UINTN)Qtd->Data - (UINTN)Urb->Data); \r
+ PciAddr = (UINTN)Urb->DataPhy + ((UINTN)Qtd->Data - (UINTN)Urb->Data);\r
QtdHw->Page[0] = EHC_LOW_32BIT (PciAddr);\r
QtdHw->PageHigh[0]= EHC_HIGH_32BIT (PciAddr);\r
}\r
ProcBuf = NULL;\r
\r
if (Urb->Result == EFI_USB_NOERROR) {\r
- ASSERT (Urb->Completed <= Urb->DataLen);\r
-\r
- ProcBuf = AllocatePool (Urb->Completed);\r
+ //\r
+ // Make sure the data received from HW is no more than expected.\r
+ //\r
+ if (Urb->Completed <= Urb->DataLen) {\r
+ ProcBuf = AllocatePool (Urb->Completed);\r
+ }\r
\r
if (ProcBuf == NULL) {\r
EhcUpdateAsyncRequest (Ehc, Urb);\r