X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FBus%2FPci%2FEhciDxe%2FEhciUrb.c;h=37cef6d130f7e5825a624f947492330f250aa038;hp=09c12776ecdbe7445149a95f6c78c690c477d513;hb=HEAD;hpb=0cd645250306b244a5d6e0e293ed1786ec101641 diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c index 09c12776ec..a2b0b99d33 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c @@ -4,19 +4,13 @@ URB (Usb Request Block). Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "Ehci.h" - /** Create a single QTD to hold the data. @@ -33,20 +27,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ EHC_QTD * EhcCreateQtd ( - IN USB2_HC_DEV *Ehc, - IN UINT8 *Data, - IN UINT8 *DataPhy, - IN UINTN DataLen, - IN UINT8 PktId, - IN UINT8 Toggle, - IN UINTN MaxPacket + IN USB2_HC_DEV *Ehc, + IN UINT8 *Data, + IN UINT8 *DataPhy, + IN UINTN DataLen, + IN UINT8 PktId, + IN UINT8 Toggle, + IN UINTN MaxPacket ) { - EHC_QTD *Qtd; - QTD_HW *QtdHw; - UINTN Index; - UINTN Len; - UINTN ThisBufLen; + EHC_QTD *Qtd; + QTD_HW *QtdHw; + UINTN Index; + UINTN Len; + UINTN ThisBufLen; ASSERT (Ehc != NULL); @@ -56,9 +50,9 @@ EhcCreateQtd ( return NULL; } - Qtd->Signature = EHC_QTD_SIG; - Qtd->Data = Data; - Qtd->DataLen = 0; + Qtd->Signature = EHC_QTD_SIG; + Qtd->Data = Data; + Qtd->DataLen = 0; InitializeListHead (&Qtd->QtdList); @@ -84,18 +78,18 @@ EhcCreateQtd ( // compute the offset and clear Reserved fields. This is already // done in the data point. // - QtdHw->Page[Index] = EHC_LOW_32BIT (DataPhy); - QtdHw->PageHigh[Index] = EHC_HIGH_32BIT (DataPhy); + QtdHw->Page[Index] = EHC_LOW_32BIT (DataPhy); + QtdHw->PageHigh[Index] = EHC_HIGH_32BIT (DataPhy); - ThisBufLen = QTD_BUF_LEN - (EHC_LOW_32BIT (DataPhy) & QTD_BUF_MASK); + ThisBufLen = QTD_BUF_LEN - (EHC_LOW_32BIT (DataPhy) & QTD_BUF_MASK); if (Len + ThisBufLen >= DataLen) { Len = DataLen; break; } - Len += ThisBufLen; - Data += ThisBufLen; + Len += ThisBufLen; + Data += ThisBufLen; DataPhy += ThisBufLen; } @@ -109,15 +103,13 @@ EhcCreateQtd ( Len = Len - Len % MaxPacket; } - QtdHw->TotalBytes = (UINT32) Len; + QtdHw->TotalBytes = (UINT32)Len; Qtd->DataLen = Len; } return Qtd; } - - /** Initialize the queue head for interrupt transfer, that is, initialize the following three fields: @@ -131,8 +123,8 @@ EhcCreateQtd ( **/ VOID EhcInitIntQh ( - IN USB_ENDPOINT *Ep, - IN QH_HW *QhHw + IN USB_ENDPOINT *Ep, + IN QH_HW *QhHw ) { // @@ -144,7 +136,7 @@ EhcInitIntQh ( // if (Ep->DevSpeed == EFI_USB_SPEED_HIGH) { QhHw->SMask = QH_MICROFRAME_0; - return ; + return; } // @@ -162,8 +154,6 @@ EhcInitIntQh ( QhHw->CMask = QH_MICROFRAME_3 | QH_MICROFRAME_4 | QH_MICROFRAME_5; } - - /** Allocate and initialize a EHCI queue head. @@ -175,12 +165,12 @@ EhcInitIntQh ( **/ EHC_QH * EhcCreateQh ( - IN USB2_HC_DEV *Ehci, - IN USB_ENDPOINT *Ep + IN USB2_HC_DEV *Ehci, + IN USB_ENDPOINT *Ep ) { - EHC_QH *Qh; - QH_HW *QhHw; + EHC_QH *Qh; + QH_HW *QhHw; Qh = UsbHcAllocateMem (Ehci->MemPool, sizeof (EHC_QH)); @@ -188,68 +178,68 @@ EhcCreateQh ( return NULL; } - Qh->Signature = EHC_QH_SIG; - Qh->NextQh = NULL; - Qh->Interval = Ep->PollRate; + Qh->Signature = EHC_QH_SIG; + Qh->NextQh = NULL; + Qh->Interval = Ep->PollRate; InitializeListHead (&Qh->Qtds); - QhHw = &Qh->QhHw; - QhHw->HorizonLink = QH_LINK (NULL, 0, TRUE); - QhHw->DeviceAddr = Ep->DevAddr; - QhHw->Inactive = 0; - QhHw->EpNum = Ep->EpAddr; - QhHw->EpSpeed = Ep->DevSpeed; - QhHw->DtCtrl = 0; - QhHw->ReclaimHead = 0; - QhHw->MaxPacketLen = (UINT32) Ep->MaxPacket; - QhHw->CtrlEp = 0; - QhHw->NakReload = QH_NAK_RELOAD; - QhHw->HubAddr = Ep->HubAddr; - QhHw->PortNum = Ep->HubPort; - QhHw->Multiplier = 1; - QhHw->DataToggle = Ep->Toggle; + QhHw = &Qh->QhHw; + QhHw->HorizonLink = QH_LINK (NULL, 0, TRUE); + QhHw->DeviceAddr = Ep->DevAddr; + QhHw->Inactive = 0; + QhHw->EpNum = Ep->EpAddr; + QhHw->EpSpeed = Ep->DevSpeed; + QhHw->DtCtrl = 0; + QhHw->ReclaimHead = 0; + QhHw->MaxPacketLen = (UINT32)Ep->MaxPacket; + QhHw->CtrlEp = 0; + QhHw->NakReload = QH_NAK_RELOAD; + QhHw->HubAddr = Ep->HubAddr; + QhHw->PortNum = Ep->HubPort; + QhHw->Multiplier = 1; + QhHw->DataToggle = Ep->Toggle; if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) { QhHw->Status |= QTD_STAT_DO_SS; } switch (Ep->Type) { - case EHC_CTRL_TRANSFER: - // - // Special initialization for the control transfer: - // 1. Control transfer initialize data toggle from each QTD - // 2. Set the Control Endpoint Flag (C) for low/full speed endpoint. - // - QhHw->DtCtrl = 1; + case EHC_CTRL_TRANSFER: + // + // Special initialization for the control transfer: + // 1. Control transfer initialize data toggle from each QTD + // 2. Set the Control Endpoint Flag (C) for low/full speed endpoint. + // + QhHw->DtCtrl = 1; - if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) { - QhHw->CtrlEp = 1; - } - break; + if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) { + QhHw->CtrlEp = 1; + } - case EHC_INT_TRANSFER_ASYNC: - case EHC_INT_TRANSFER_SYNC: - // - // Special initialization for the interrupt transfer - // to set the S-Mask and C-Mask - // - QhHw->NakReload = 0; - EhcInitIntQh (Ep, QhHw); - break; + break; - case EHC_BULK_TRANSFER: - if ((Ep->DevSpeed == EFI_USB_SPEED_HIGH) && (Ep->Direction == EfiUsbDataOut)) { - QhHw->Status |= QTD_STAT_DO_PING; - } + case EHC_INT_TRANSFER_ASYNC: + case EHC_INT_TRANSFER_SYNC: + // + // Special initialization for the interrupt transfer + // to set the S-Mask and C-Mask + // + QhHw->NakReload = 0; + EhcInitIntQh (Ep, QhHw); + break; - break; + case EHC_BULK_TRANSFER: + if ((Ep->DevSpeed == EFI_USB_SPEED_HIGH) && (Ep->Direction == EfiUsbDataOut)) { + QhHw->Status |= QTD_STAT_DO_PING; + } + + break; } return Qh; } - /** Convert the poll interval from application to that be used by EHCI interface data structure. Only need @@ -265,10 +255,10 @@ EhcCreateQh ( **/ UINTN EhcConvertPollRate ( - IN UINTN Interval + IN UINTN Interval ) { - UINTN BitCount; + UINTN BitCount; if (Interval == 0) { return 1; @@ -287,7 +277,6 @@ EhcConvertPollRate ( return (UINTN)1 << (BitCount - 1); } - /** Free a list of QTDs. @@ -297,15 +286,15 @@ EhcConvertPollRate ( **/ VOID EhcFreeQtds ( - IN USB2_HC_DEV *Ehc, - IN LIST_ENTRY *Qtds + IN USB2_HC_DEV *Ehc, + IN LIST_ENTRY *Qtds ) { - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - EHC_QTD *Qtd; + LIST_ENTRY *Entry; + LIST_ENTRY *Next; + EHC_QTD *Qtd; - EFI_LIST_FOR_EACH_SAFE (Entry, Next, Qtds) { + BASE_LIST_FOR_EACH_SAFE (Entry, Next, Qtds) { Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList); RemoveEntryList (&Qtd->QtdList); @@ -313,7 +302,6 @@ EhcFreeQtds ( } } - /** Free an allocated URB. It is possible for it to be partially inited. @@ -323,11 +311,11 @@ EhcFreeQtds ( **/ VOID EhcFreeUrb ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb + IN USB2_HC_DEV *Ehc, + IN URB *Urb ) { - EFI_PCI_IO_PROTOCOL *PciIo; + EFI_PCI_IO_PROTOCOL *PciIo; PciIo = Ehc->PciIo; @@ -339,14 +327,6 @@ EhcFreeUrb ( PciIo->Unmap (PciIo, Urb->DataMap); } - if (Urb->AllocateCommonBuffer) { - PciIo->FreeBuffer ( - PciIo, - EFI_SIZE_TO_PAGES (Urb->DataLen), - Urb->Data - ); - } - if (Urb->Qh != NULL) { // // Ensure that this queue head has been unlinked from the @@ -359,7 +339,6 @@ EhcFreeUrb ( gBS->FreePool (Urb); } - /** Create a list of QTDs for the URB. @@ -372,21 +351,21 @@ EhcFreeUrb ( **/ EFI_STATUS EhcCreateQtds ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb + IN USB2_HC_DEV *Ehc, + IN URB *Urb ) { - USB_ENDPOINT *Ep; - EHC_QH *Qh; - EHC_QTD *Qtd; - EHC_QTD *StatusQtd; - EHC_QTD *NextQtd; - LIST_ENTRY *Entry; - UINT32 AlterNext; - UINT8 Toggle; - UINTN Len; - UINT8 Pid; - EFI_PHYSICAL_ADDRESS PhyAddr; + USB_ENDPOINT *Ep; + EHC_QH *Qh; + EHC_QTD *Qtd; + EHC_QTD *StatusQtd; + EHC_QTD *NextQtd; + LIST_ENTRY *Entry; + UINT32 AlterNext; + UINT8 Toggle; + UINTN Len; + UINT8 Pid; + EFI_PHYSICAL_ADDRESS PhyAddr; ASSERT ((Urb != NULL) && (Urb->Qh != NULL)); @@ -402,7 +381,7 @@ EhcCreateQtds ( StatusQtd = NULL; AlterNext = QTD_LINK (NULL, TRUE); - PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD)); + PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD)); if (Ep->Direction == EfiUsbDataIn) { AlterNext = QTD_LINK (PhyAddr, FALSE); } @@ -461,8 +440,8 @@ EhcCreateQtds ( while (Len < Urb->DataLen) { Qtd = EhcCreateQtd ( Ehc, - (UINT8 *) Urb->Data + Len, - (UINT8 *) Urb->DataPhy + Len, + (UINT8 *)Urb->Data + Len, + (UINT8 *)Urb->DataPhy + Len, Urb->DataLen - Len, Pid, Toggle, @@ -480,7 +459,7 @@ EhcCreateQtds ( // Switch the Toggle bit if odd number of packets are included in the QTD. // if (((Qtd->DataLen + Ep->MaxPacket - 1) / Ep->MaxPacket) % 2) { - Toggle = (UINT8) (1 - Toggle); + Toggle = (UINT8)(1 - Toggle); } Len += Qtd->DataLen; @@ -496,7 +475,7 @@ EhcCreateQtds ( // // OK, all the QTDs needed are created. Now, fix the NextQtd point // - EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) { + BASE_LIST_FOR_EACH (Entry, &Qh->Qtds) { Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList); // @@ -506,17 +485,17 @@ EhcCreateQtds ( break; } - NextQtd = EFI_LIST_CONTAINER (Entry->ForwardLink, EHC_QTD, QtdList); - PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD)); - Qtd->QtdHw.NextQtd = QTD_LINK (PhyAddr, FALSE); + NextQtd = EFI_LIST_CONTAINER (Entry->ForwardLink, EHC_QTD, QtdList); + PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD)); + Qtd->QtdHw.NextQtd = QTD_LINK (PhyAddr, FALSE); } // // Link the QTDs to the queue head // - NextQtd = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, EHC_QTD, QtdList); - PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD)); - Qh->QhHw.NextQtd = QTD_LINK (PhyAddr, FALSE); + NextQtd = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, EHC_QTD, QtdList); + PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD)); + Qh->QhHw.NextQtd = QTD_LINK (PhyAddr, FALSE); return EFI_SUCCESS; ON_ERROR: @@ -524,7 +503,6 @@ ON_ERROR: return EFI_OUT_OF_RESOURCES; } - /** Create a new URB and its associated QTD. @@ -537,8 +515,7 @@ ON_ERROR: @param Hub The transaction translator to use. @param Type The transaction type. @param Request The standard USB request for control transfer. - @param AllocateCommonBuffer Indicate whether need to allocate common buffer for data transfer. - @param Data The user data to transfer, NULL if AllocateCommonBuffer is TRUE. + @param Data The user data to transfer. @param DataLen The length of data buffer. @param Callback The function to call when data is transferred. @param Context The context to the callback. @@ -549,31 +526,30 @@ ON_ERROR: **/ URB * EhcCreateUrb ( - IN USB2_HC_DEV *Ehc, - IN UINT8 DevAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINT8 Toggle, - IN UINTN MaxPacket, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN BOOLEAN AllocateCommonBuffer, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context, - IN UINTN Interval + IN USB2_HC_DEV *Ehc, + IN UINT8 DevAddr, + IN UINT8 EpAddr, + IN UINT8 DevSpeed, + IN UINT8 Toggle, + IN UINTN MaxPacket, + IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub, + IN UINTN Type, + IN EFI_USB_DEVICE_REQUEST *Request, + IN VOID *Data, + IN UINTN DataLen, + IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, + IN VOID *Context, + IN UINTN Interval ) { - USB_ENDPOINT *Ep; - EFI_PHYSICAL_ADDRESS PhyAddr; - EFI_PCI_IO_PROTOCOL_OPERATION MapOp; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINTN Len; - URB *Urb; - VOID *Map; + USB_ENDPOINT *Ep; + EFI_PHYSICAL_ADDRESS PhyAddr; + EFI_PCI_IO_PROTOCOL_OPERATION MapOp; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + UINTN Len; + URB *Urb; + VOID *Map; Urb = AllocateZeroPool (sizeof (URB)); @@ -581,54 +557,38 @@ EhcCreateUrb ( return NULL; } - Urb->Signature = EHC_URB_SIG; + Urb->Signature = EHC_URB_SIG; InitializeListHead (&Urb->UrbList); - Ep = &Urb->Ep; - Ep->DevAddr = DevAddr; - Ep->EpAddr = (UINT8) (EpAddr & 0x0F); - Ep->Direction = (((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut); - Ep->DevSpeed = DevSpeed; - Ep->MaxPacket = MaxPacket; + Ep = &Urb->Ep; + Ep->DevAddr = DevAddr; + Ep->EpAddr = (UINT8)(EpAddr & 0x0F); + Ep->Direction = (((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut); + Ep->DevSpeed = DevSpeed; + Ep->MaxPacket = MaxPacket; - Ep->HubAddr = 0; - Ep->HubPort = 0; + Ep->HubAddr = 0; + Ep->HubPort = 0; if (DevSpeed != EFI_USB_SPEED_HIGH) { ASSERT (Hub != NULL); - Ep->HubAddr = Hub->TranslatorHubAddress; - Ep->HubPort = Hub->TranslatorPortNumber; + Ep->HubAddr = Hub->TranslatorHubAddress; + Ep->HubPort = Hub->TranslatorPortNumber; } - Ep->Toggle = Toggle; - Ep->Type = Type; - Ep->PollRate = EhcConvertPollRate (Interval); - - Urb->Request = Request; - if (AllocateCommonBuffer) { - ASSERT (Data == NULL); - Status = Ehc->PciIo->AllocateBuffer ( - Ehc->PciIo, - AllocateAnyPages, - EfiBootServicesData, - EFI_SIZE_TO_PAGES (DataLen), - &Data, - 0 - ); - if (EFI_ERROR (Status) || (Data == NULL)) { - FreePool (Urb); - return NULL; - } - } - Urb->Data = Data; - Urb->DataLen = DataLen; - Urb->AllocateCommonBuffer = AllocateCommonBuffer; - Urb->Callback = Callback; - Urb->Context = Context; + Ep->Toggle = Toggle; + Ep->Type = Type; + Ep->PollRate = EhcConvertPollRate (Interval); + + Urb->Request = Request; + Urb->Data = Data; + Urb->DataLen = DataLen; + Urb->Callback = Callback; + Urb->Context = Context; - PciIo = Ehc->PciIo; - Urb->Qh = EhcCreateQh (Ehc, &Urb->Ep); + PciIo = Ehc->PciIo; + Urb->Qh = EhcCreateQh (Ehc, &Urb->Ep); if (Urb->Qh == NULL) { goto ON_ERROR; @@ -638,39 +598,35 @@ EhcCreateUrb ( // Map the request and user data // if (Request != NULL) { - Len = sizeof (EFI_USB_DEVICE_REQUEST); - MapOp = EfiPciIoOperationBusMasterRead; - Status = PciIo->Map (PciIo, MapOp, Request, &Len, &PhyAddr, &Map); + Len = sizeof (EFI_USB_DEVICE_REQUEST); + MapOp = EfiPciIoOperationBusMasterRead; + Status = PciIo->Map (PciIo, MapOp, Request, &Len, &PhyAddr, &Map); if (EFI_ERROR (Status) || (Len != sizeof (EFI_USB_DEVICE_REQUEST))) { goto ON_ERROR; } - Urb->RequestPhy = (VOID *) ((UINTN) PhyAddr); + Urb->RequestPhy = (VOID *)((UINTN)PhyAddr); Urb->RequestMap = Map; } if (Data != NULL) { - Len = DataLen; + Len = DataLen; - if (Urb->AllocateCommonBuffer) { - MapOp = EfiPciIoOperationBusMasterCommonBuffer; + if (Ep->Direction == EfiUsbDataIn) { + MapOp = EfiPciIoOperationBusMasterWrite; } else { - if (Ep->Direction == EfiUsbDataIn) { - MapOp = EfiPciIoOperationBusMasterWrite; - } else { - MapOp = EfiPciIoOperationBusMasterRead; - } + MapOp = EfiPciIoOperationBusMasterRead; } - Status = PciIo->Map (PciIo, MapOp, Data, &Len, &PhyAddr, &Map); + Status = PciIo->Map (PciIo, MapOp, Data, &Len, &PhyAddr, &Map); if (EFI_ERROR (Status) || (Len != DataLen)) { goto ON_ERROR; } - Urb->DataPhy = (VOID *) ((UINTN) PhyAddr); - Urb->DataMap = Map; + Urb->DataPhy = (VOID *)((UINTN)PhyAddr); + Urb->DataMap = Map; } Status = EhcCreateQtds (Ehc, Urb);