Remove some useless functions for EhciPei driver.

Signed-off-by: lzeng14
Reviewed-by: erictian

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12677 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lzeng14 2011-11-09 09:38:56 +00:00
parent d40b2ee60e
commit 008d25427c
2 changed files with 1 additions and 501 deletions

View File

@ -287,164 +287,6 @@ EhcUnlinkQhFromAsync (
return; return;
} }
/**
Link a queue head for interrupt transfer to the periodic
schedule frame list. This code is very much the same as
that in UHCI.
@param Ehc The EHCI device.
@param Qh The queue head to link.
**/
VOID
EhcLinkQhToPeriod (
IN PEI_USB2_HC_DEV *Ehc,
IN PEI_EHC_QH *Qh
)
{
UINT32 *Frames;
UINTN Index;
PEI_EHC_QH *Prev;
PEI_EHC_QH *Next;
Frames = Ehc->PeriodFrame;
for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {
//
// First QH can't be NULL because we always keep PeriodOne
// heads on the frame list
//
ASSERT (!EHC_LINK_TERMINATED (Frames[Index]));
Next = EHC_ADDR (Ehc->High32bitAddr, Frames[Index]);
Prev = NULL;
//
// Now, insert the queue head (Qh) into this frame:
// 1. Find a queue head with the same poll interval, just insert
// Qh after this queue head, then we are done.
//
// 2. Find the position to insert the queue head into:
// Previous head's interval is bigger than Qh's
// Next head's interval is less than Qh's
// Then, insert the Qh between then
//
while (Next->Interval > Qh->Interval) {
Prev = Next;
Next = Next->NextQh;
}
ASSERT (Next != NULL);
//
// The entry may have been linked into the frame by early insertation.
// For example: if insert a Qh with Qh.Interval == 4, and there is a Qh
// with Qh.Interval == 8 on the frame. If so, we are done with this frame.
// It isn't necessary to compare all the QH with the same interval to
// Qh. This is because if there is other QH with the same interval, Qh
// should has been inserted after that at Frames[0] and at Frames[0] it is
// impossible for (Next == Qh)
//
if (Next == Qh) {
continue;
}
if (Next->Interval == Qh->Interval) {
//
// If there is a QH with the same interval, it locates at
// Frames[0], and we can simply insert it after this QH. We
// are all done.
//
ASSERT ((Index == 0) && (Qh->NextQh == NULL));
Prev = Next;
Next = Next->NextQh;
Qh->NextQh = Next;
Prev->NextQh = Qh;
Qh->QhHw.HorizonLink = Prev->QhHw.HorizonLink;
Prev->QhHw.HorizonLink = QH_LINK (Qh, EHC_TYPE_QH, FALSE);
break;
}
//
// OK, find the right position, insert it in. If Qh's next
// link has already been set, it is in position. This is
// guarranted by 2^n polling interval.
//
if (Qh->NextQh == NULL) {
Qh->NextQh = Next;
Qh->QhHw.HorizonLink = QH_LINK (Next, EHC_TYPE_QH, FALSE);
}
if (Prev == NULL) {
Frames[Index] = QH_LINK (Qh, EHC_TYPE_QH, FALSE);
} else {
Prev->NextQh = Qh;
Prev->QhHw.HorizonLink = QH_LINK (Qh, EHC_TYPE_QH, FALSE);
}
}
}
/**
Unlink an interrupt queue head from the periodic
schedule frame list.
@param Ehc The EHCI device.
@param Qh The queue head to unlink.
**/
VOID
EhcUnlinkQhFromPeriod (
IN PEI_USB2_HC_DEV *Ehc,
IN PEI_EHC_QH *Qh
)
{
UINT32 *Frames;
UINTN Index;
PEI_EHC_QH *Prev;
PEI_EHC_QH *This;
Frames = Ehc->PeriodFrame;
for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {
//
// Frame link can't be NULL because we always keep PeroidOne
// on the frame list
//
ASSERT (!EHC_LINK_TERMINATED (Frames[Index]));
This = EHC_ADDR (Ehc->High32bitAddr, Frames[Index]);
Prev = NULL;
//
// Walk through the frame's QH list to find the
// queue head to remove
//
while ((This != NULL) && (This != Qh)) {
Prev = This;
This = This->NextQh;
}
//
// Qh may have already been unlinked from this frame
// by early action. See the comments in EhcLinkQhToPeriod.
//
if (This == NULL) {
continue;
}
if (Prev == NULL) {
//
// Qh is the first entry in the frame
//
Frames[Index] = Qh->QhHw.HorizonLink;
} else {
Prev->NextQh = Qh->NextQh;
Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink;
}
}
}
/** /**
Check the URB's execution result and update the URB's Check the URB's execution result and update the URB's
result accordingly. result accordingly.
@ -607,265 +449,3 @@ EhcExecTransfer (
return Status; return Status;
} }
/**
Delete a single asynchronous interrupt transfer for
the device and endpoint.
@param Ehc The EHCI device.
@param DevAddr The address of the target device.
@param EpNum The endpoint of the target.
@param DataToggle Return the next data toggle to use.
@retval EFI_NOT_FOUND No transfer for the device is found.
@retval EFI_SUCCESS An asynchronous transfer is removed.
**/
EFI_STATUS
EhciDelAsyncIntTransfer (
IN PEI_USB2_HC_DEV *Ehc,
IN UINT8 DevAddr,
IN UINT8 EpNum,
OUT UINT8 *DataToggle
)
{
EFI_LIST_ENTRY *Entry;
EFI_LIST_ENTRY *Next;
PEI_URB *Urb;
EFI_USB_DATA_DIRECTION Direction;
Direction = (((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut);
EpNum &= 0x0F;
EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Ehc->AsyncIntTransfers) {
Urb = EFI_LIST_CONTAINER (Entry, PEI_URB, UrbList);
if ((Urb->Ep.DevAddr == DevAddr) && (Urb->Ep.EpAddr == EpNum) &&
(Urb->Ep.Direction == Direction)) {
//
// Check the URB status to retrieve the next data toggle
// from the associated queue head.
//
EhcCheckUrbResult (Ehc, Urb);
*DataToggle = Urb->DataToggle;
EhcUnlinkQhFromPeriod (Ehc, Urb->Qh);
RemoveEntryList (&Urb->UrbList);
EhcFreeUrb (Ehc, Urb);
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
/**
Remove all the asynchronous interrutp transfers.
@param Ehc The EHCI device.
**/
VOID
EhciDelAllAsyncIntTransfers (
IN PEI_USB2_HC_DEV *Ehc
)
{
EFI_LIST_ENTRY *Entry;
EFI_LIST_ENTRY *Next;
PEI_URB *Urb;
EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Ehc->AsyncIntTransfers) {
Urb = EFI_LIST_CONTAINER (Entry, PEI_URB, UrbList);
EhcUnlinkQhFromPeriod (Ehc, Urb->Qh);
RemoveEntryList (&Urb->UrbList);
EhcFreeUrb (Ehc, Urb);
}
}
/**
Flush data from PCI controller specific address to mapped system
memory address.
@param Ehc The EHCI device.
@param Urb The URB to unmap.
@retval EFI_DEVICE_ERROR Fail to flush data to mapped system memory.
@retval EFI_SUCCESS Success to flush data to mapped system memory.
**/
EFI_STATUS
EhcFlushAsyncIntMap (
IN PEI_USB2_HC_DEV *Ehc,
IN PEI_URB *Urb
)
{
EFI_PHYSICAL_ADDRESS PhyAddr;
Urb->DataMap = NULL;
PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) Urb->Data;
Urb->DataPhy = (VOID *) ((UINTN) PhyAddr);
return EFI_SUCCESS;
}
/**
Update the queue head for next round of asynchronous transfer.
@param Urb The URB to update.
**/
VOID
EhcUpdateAsyncRequest (
IN PEI_URB *Urb
)
{
EFI_LIST_ENTRY *Entry;
PEI_EHC_QTD *FirstQtd;
QH_HW *QhHw;
PEI_EHC_QTD *Qtd;
QTD_HW *QtdHw;
UINTN Index;
Qtd = NULL;
if (Urb->Result == EFI_USB_NOERROR) {
FirstQtd = NULL;
EFI_LIST_FOR_EACH (Entry, &Urb->Qh->Qtds) {
Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);
if (FirstQtd == NULL) {
FirstQtd = Qtd;
}
//
// Update the QTD for next round of transfer. Host control
// may change dt/Total Bytes to Transfer/C_Page/Cerr/Status/
// Current Offset. These fields need to be updated. DT isn't
// used by interrupt transfer. It uses DT in queue head.
// Current Offset is in Page[0], only need to reset Page[0]
// to initial data buffer.
//
QtdHw = &Qtd->QtdHw;
QtdHw->Status = QTD_STAT_ACTIVE;
QtdHw->ErrCnt = QTD_MAX_ERR;
QtdHw->CurPage = 0;
QtdHw->TotalBytes = (UINT32) Qtd->DataLen;
QtdHw->Page[0] = EHC_LOW_32BIT (Qtd->Data);
}
//
// Update QH for next round of transfer. Host control only
// touch the fields in transfer overlay area. Only need to
// zero out the overlay area and set NextQtd to the first
// QTD. DateToggle bit is left untouched.
//
QhHw = &Urb->Qh->QhHw;
QhHw->CurQtd = QTD_LINK (0, TRUE);
QhHw->AltQtd = 0;
QhHw->Status = 0;
QhHw->Pid = 0;
QhHw->ErrCnt = 0;
QhHw->CurPage = 0;
QhHw->Ioc = 0;
QhHw->TotalBytes = 0;
for (Index = 0; Index < 5; Index++) {
QhHw->Page[Index] = 0;
QhHw->PageHigh[Index] = 0;
}
QhHw->NextQtd = QTD_LINK (FirstQtd, FALSE);
}
return ;
}
/**
Remove all the asynchronous interrutp transfers.
@param Event Interrupt event.
@param Context Pointer to PEI_USB2_HC_DEV.
**/
VOID
EFIAPI
EhcMoniteAsyncRequests (
IN EFI_EVENT Event,
IN VOID *Context
)
{
PEI_USB2_HC_DEV *Ehc;
EFI_LIST_ENTRY *Entry;
EFI_LIST_ENTRY *Next;
BOOLEAN Finished;
UINT8 *ProcBuf;
PEI_URB *Urb;
UINTN PageNumber;
Ehc = (PEI_USB2_HC_DEV *) Context;
EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Ehc->AsyncIntTransfers) {
Urb = EFI_LIST_CONTAINER (Entry, PEI_URB, UrbList);
//
// Check the result of URB execution. If it is still
// active, check the next one.
//
Finished = EhcCheckUrbResult (Ehc, Urb);
if (!Finished) {
continue;
}
//
// Flush any PCI posted write transactions from a PCI host
// bridge to system memory.
//
EhcFlushAsyncIntMap (Ehc, Urb);
//
// Allocate a buffer then copy the transferred data for user.
// If failed to allocate the buffer, update the URB for next
// round of transfer. Ignore the data of this round.
//
ProcBuf = NULL;
if (Urb->Result == EFI_USB_NOERROR) {
ASSERT (Urb->Completed <= Urb->DataLen);
PageNumber = Urb->Completed/PAGESIZE +1;
PeiServicesAllocatePages (
EfiBootServicesCode,
PageNumber,
(EFI_PHYSICAL_ADDRESS *)ProcBuf
);
if (ProcBuf == NULL) {
EhcUpdateAsyncRequest (Urb);
continue;
}
CopyMem (ProcBuf, Urb->Data, Urb->Completed);
}
EhcUpdateAsyncRequest (Urb);
//
// Leave error recovery to its related device driver. A
// common case of the error recovery is to re-submit the
// interrupt transfer which is linked to the head of the
// list. This function scans from head to tail. So the
// re-submitted interrupt transfer's callback function
// will not be called again in this round. Don't touch this
// URB after the callback, it may have been removed by the
// callback.
//
if (Urb->Callback != NULL) {
(Urb->Callback) (ProcBuf, Urb->Completed, Urb->Context, Urb->Result);
}
if (ProcBuf != NULL) {
}
}
}

View File

@ -1,7 +1,7 @@
/** @file /** @file
Private Header file for Usb Host Controller PEIM Private Header file for Usb Host Controller PEIM
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -77,37 +77,6 @@ EhcUnlinkQhFromAsync (
) )
; ;
/**
Link a queue head for interrupt transfer to the periodic
schedule frame list. This code is very much the same as
that in UHCI.
@param Ehc The EHCI device.
@param Qh The queue head to link.
**/
VOID
EhcLinkQhToPeriod (
IN PEI_USB2_HC_DEV *Ehc,
IN PEI_EHC_QH *Qh
)
;
/**
Unlink an interrupt queue head from the periodic
schedule frame list.
@param Ehc The EHCI device.
@param Qh The queue head to unlink.
**/
VOID
EhcUnlinkQhFromPeriod (
IN PEI_USB2_HC_DEV *Ehc,
IN PEI_EHC_QH *Qh
)
;
/** /**
Execute the transfer by polling the URB. This is a synchronous operation. Execute the transfer by polling the URB. This is a synchronous operation.
@ -128,53 +97,4 @@ EhcExecTransfer (
) )
; ;
/**
Delete a single asynchronous interrupt transfer for
the device and endpoint.
@param Ehc The EHCI device.
@param DevAddr The address of the target device.
@param EpNum The endpoint of the target.
@param DataToggle Return the next data toggle to use.
@retval EFI_NOT_FOUND No transfer for the device is found.
@retval EFI_SUCCESS An asynchronous transfer is removed.
**/
EFI_STATUS
EhciDelAsyncIntTransfer (
IN PEI_USB2_HC_DEV *Ehc,
IN UINT8 DevAddr,
IN UINT8 EpNum,
OUT UINT8 *DataToggle
)
;
/**
Remove all the asynchronous interrutp transfers.
@param Ehc The EHCI device.
**/
VOID
EhciDelAllAsyncIntTransfers (
IN PEI_USB2_HC_DEV *Ehc
)
;
/**
Remove all the asynchronous interrutp transfers.
@param Event Interrupt event.
@param Context Pointer to PEI_USB2_HC_DEV.
**/
VOID
EFIAPI
EhcMoniteAsyncRequests (
IN EFI_EVENT Event,
IN VOID *Context
)
;
#endif #endif