📄 pdd.c
字号:
}
// Come here if the Data is not over in the first page itself, or did not go in to the above condition
BPCount = 1; // First page has been taken care of , so start from second page
while (len > 0)
{
// Flow through the user buffer till the end and then check for the alignment of the length
if ( len > MAX_SIZE_PER_BP )
{
len -= MAX_SIZE_PER_BP;
BPCount++;
}
else
{
if ((len % 32) != 0)
{
memcpy((pPdd->ep[EpNum]->pMappedBufPtr + ((BPCount * MAX_SIZE_PER_BP) - dwOffset)),
Buffer_Td2, len );
}
len = 0;
}
}
DEBUGMSG(1,(_T("-CopyFromUncachedBuffer\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: DumpInterruptSource
//
// This function dump the value on the interrupt register USBSTS
//
//
// Parameters:
//
// source - pointer to USBSTS
//
// Return:
//
// NULL
//
//-------------------------------------------------------------------------------
void DumpInterruptSource(USB_USBSTS_T * source)
{
if (source->UI)
RETAILMSG(1, (L"\tUSB Interrupt (USBINT)\r\n"));
if (source->UEI)
RETAILMSG(1, (L"\tUSB Error Interrupt (USBERRINT)\r\n"));
if (source->PCI)
RETAILMSG(1, (L"\tPort Change Detect\r\n"));
if (source->FRI)
RETAILMSG(1, (L"\tFrame List Rollover\r\n"));
if (source->SEI)
RETAILMSG(1, (L"\tSystem Error\r\n"));
if (source->AAI)
RETAILMSG(1, (L"\tInterrupt on Async Advance\r\n"));
if (source->URI)
RETAILMSG(1, (L"\tUSB Reset Received \r\n"));
if (source->SRI)
RETAILMSG(1, (L"\tSOF Received \r\n"));
if (source->SLI)
RETAILMSG(1, (L"\tDCSuspend \r\n"));
if (source->ULPII)
RETAILMSG(1, (L"\tULPI Interrupt\r\n"));
if (source->HCH)
RETAILMSG(1, (L"\tHCHaIted \r\n"));
if (source->RCL)
RETAILMSG(1, (L"\tReclamation,Only used by the host controller. \r\n"));
if (source->PS)
RETAILMSG(1, (L"\tPeriodic Schedule Status. \r\n"));
if (source->AS)
RETAILMSG(1, (L"\tAsynchronous Schedule Status. \r\n"));
}
//------------------------------------------------------------------------------
//
// Function: CheckEndpoint
//
// This function handles the interrupt due to endpoint complete
//
//
// Parameters:
//
// pPdd - Pointer to USBFN_PDD structure
//
// i - endpoint to be examined
//
// Return:
//
// NULL
//
//-------------------------------------------------------------------------------
static void CheckEndpoint(USBFN_PDD *pPdd, int i )
{
CSP_USB_REGS* pUSBDRegs = pPdd->pUSBDRegs;
STransfer * pTransfer;
USB_ENDPTCOMPLETE_T edptcomp;
DWORD *pEpc;
pEpc = (DWORD*)&edptcomp;
LOCK();
// OUT endpoint
*pEpc = INREG32(&pUSBDRegs->OTG.ENDPTCOMPLETE);
if (edptcomp.ERCE&(1<<i))
{
pTransfer=pPdd->ep[i]->pTransfer;
if (i)
{
PUSBD_dTD_R_T pTd;
PUSBD_dQH_T pQh;
pQh=&(pPdd->qhbuffer->qh[i*2]);
pTd=TDVirtual(pQh->curr_dTD);
if (pPdd->qhbuffer->qh[i*2].dtd.status)
RETAILMSG(1,(L"Status is not 0 on recv %x =%x",i,pPdd->qhbuffer->qh[i*2].dtd.status));
if (pTransfer&&pPdd->qhbuffer->qh[i*2].dtd.status!=0x80)
{
// calculate how much we were trying to tranfer in this TD
DWORD len=pTransfer->cbBuffer-pTransfer->cbTransferred;
if (len>MAX_SIZE_PER_TD)
len=MAX_SIZE_PER_TD;
len-=pPdd->qhbuffer->qh[i*2].dtd.tb; // reduce by any bytes outstanding
// len is how much was actually transferred
pTransfer->cbTransferred+=len;
DEBUGMSG(0, (TEXT("ENDPTCOMPLETE %x\r\n"),(1<<i)));
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (1<<i));
if (pPdd->qhbuffer->qh[i*2].dtd.status && pPdd->qhbuffer->qh[i*2].dtd.status!=0x80)
{
RETAILMSG(1,(_T("CheckEndpoint(ep=%d): BUFFER_ERROR\r\n"),i) );
DEBUGMSG(ZONE_ERROR,(_T("CheckEndpoint(ep=%d): BUFFER_ERROR\r\n"), i) );
pTransfer->dwUsbError=UFN_CLIENT_BUFFER_ERROR;
}
else if ( (len == MAX_SIZE_PER_TD) &&
(pTransfer->cbTransferred < pTransfer->cbBuffer) )
{
/* RETAILMSG(1, (_T("More data need to send (0x%x) ep(%d)\r\n"),
pTransfer->cbBuffer-pTransfer->cbTransferred, i)); */
pTransfer->dwUsbError=UFN_MORE_DATA;
UNLOCK();
UfnPdd_IssueTransfer(pPdd, i,pTransfer);
LOCK();
}
else
{
pTransfer->dwUsbError=UFN_NO_ERROR;
}
pPdd->qhbuffer->bPrimed[i] = FALSE;
if (pTransfer->dwUsbError != UFN_MORE_DATA )
{
CacheSync(CACHE_SYNC_DISCARD);
//CacheRangeFlush(pTransfer->pvBuffer, pTransfer->cbBuffer, CACHE_SYNC_DISCARD);
// For copying from Uncached memory to user buffers
if ( pTransfer->cbBuffer > 0 )
{
CopyFromUncachedBuffer(pPdd,i,pTransfer->cbBuffer);
}
if ( pPdd->ep[i]->bPagesLocked )
{
DEBUGCHK( pPdd->ep[i]->pMappedBufPtr != NULL );
UnlockPages(pPdd->ep[i]->pMappedBufPtr, pTransfer->cbBuffer);
if (pPdd->ep[i]->pMappedBufPtr)
{
if(FAILED(CeCloseCallerBuffer(pPdd->ep[i]->pMappedBufPtr,
(LPVOID)pTransfer->pvBuffer,
pTransfer->cbBuffer,
ARG_IO_PTR)))
RETAILMSG(1, (TEXT("Failed to CloseCallerBuffer\r\n")));
pPdd->ep[i]->pMappedBufPtr = NULL;
}
pPdd->ep[i]->bPagesLocked = 0;
}
pPdd->ep[i]->pTransfer=NULL;
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_TRANSFER_COMPLETE, (DWORD)pTransfer);
DEBUGMSG(0, (TEXT("OUT %s Completed for endpoint %d\r\n"),
pTransfer->dwUsbError == UFN_NO_ERROR ? TEXT("Normal") : TEXT("Cancel"),
i));
LOCK();
}
}
else //(pTransfer&&pPdd->qhbuffer->qh[i*2].dtd.status!=0x80)
{
RETAILMSG(1, (TEXT("############# ENDPTCOMPLETE %x NULL pTransfer or bad status (0x%x)!\r\n"),
(1<<i),
pPdd->qhbuffer->qh[i*2].dtd.status
));
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (1<<i));
}
}
else // Endpoint 0 OUT Transaction if (i)
{
DWORD len;
// OUT transcation of endpoint 0
// pTransfer=pPdd->ep[USBD_EP_COUNT-1]->pTransfer;
pTransfer=pPdd->ep[0]->pTransfer;
if (pTransfer)
{
len=pTransfer->cbBuffer-pPdd->qhbuffer->td[0].tb;
if (len)
{
pTransfer->cbTransferred+=len;
pPdd->qhbuffer->bPrimed[0] = FALSE;
if (pTransfer->cbTransferred < pTransfer->cbBuffer)
{
RETAILMSG(1,(L"##### more data to receive on EP0 (status=0x%x)",
pPdd->qhbuffer->td[0].status));
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), 1);
UNLOCK();
UfnPdd_IssueTransfer(pPdd, 0,pTransfer);
LOCK();
// EP0 is treated just like any other EP at this point (no setup phase ready)
}
else
{
pTransfer->dwUsbError=UFN_NO_ERROR;
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), 1);
// For copying from Uncached memory buffers to user buffers
if ( pTransfer->cbBuffer > 0 )
{
CopyFromUncachedBuffer(pPdd,0,pTransfer->cbBuffer);
}
CacheSync(CACHE_SYNC_DISCARD);
if ( pPdd->ep[0]->bPagesLocked && pTransfer->pvBuffer )
{
DEBUGCHK( pPdd->ep[0]->pMappedBufPtr != NULL );
UnlockPages(pPdd->ep[0]->pMappedBufPtr, pTransfer->cbBuffer);
if (pPdd->ep[0]->pMappedBufPtr)
{
if(FAILED(CeCloseCallerBuffer(pPdd->ep[0]->pMappedBufPtr,
(LPVOID)pTransfer->pvBuffer,
pTransfer->cbBuffer,
ARG_IO_PTR)))
RETAILMSG(1, (TEXT("Failed to CloseCallerBuffer\r\n")));
}
pPdd->ep[0]->pMappedBufPtr = NULL;
pPdd->ep[0]->bPagesLocked = 0;
}
pPdd->ep[0]->pTransfer=NULL;
DEBUGMSG(1, (TEXT("CheckEndpoint:EP0 OUT %d bytes notify (%s)\r\n"),
pTransfer->cbTransferred,
(pTransfer->dwUsbError == UFN_NO_ERROR) ? TEXT("Normal") : TEXT("Cancel")
) );
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_TRANSFER_COMPLETE, (DWORD)pTransfer);
LOCK();
}
}
else
{
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), 1);
}
DEBUGMSG(1, (_T("CheckEndpoint:EP0 OUT %d bytes completed\r\n"), pTransfer->cbTransferred) );
}
else // if (pTransfer)
{
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), 1);
DEBUGMSG(1, (_T("CheckEndpoint:EP0 OUT NULL transfer complete\r\n")) );
}
} // if (pTransfer&&pPdd->qhbuffer->qh[i*2].dtd.status!=0x80)
} // if (edptcomp.ERCE&(1<<i))
// IN packet transcation
if (edptcomp.ETCE&(1<<i))
{
DWORD mapped_epNum = i;
if (i == 0)
{
/*
* If this is the completion of a SetAddress (the status handshake part is an "IN") then
* we should set the address now. We only set the address after the command.
* Address is & 0x80 as a flag to tell us to set the address.
*/
if (pPdd->addr & 0x80)
{
DWORD addr;
pPdd->addr&=0x7f;
addr=pPdd->addr;
addr<<=25;
OUTREG32(&pPdd->pUSBDRegs->OTG.T_154H.USBADR, addr);
DEBUGMSG(1, (L"CheckEndpoint:Set Address: %x(%x), USBADR(%x)=%x \r\n",
addr, pPdd->addr, offset(CSP_USB_REG, T_154H.USBADR) ,
INREG32(&pPdd->pUSBDRegs->OTG.T_154H.USBADR)));
}
mapped_epNum = USBD_EP_COUNT-1;
}
pTransfer=pPdd->ep[mapped_epNum]->pTransfer;
if (pPdd->qhbuffer->qh[i*2+1].dtd.status)
RETAILMSG(1,(L"Status is not 0 on sent %x =%x\r\n",i,pPdd->qhbuffer->qh[i*2+1].dtd.status));
if (pTransfer && pPdd->qhbuffer->qh[i*2+1].dtd.status!=0x80)
{
// calculate how much we were trying to transfer
int len=pTransfer->cbBuffer-pTransfer->cbTransferred;
if (len>MAX_SIZE_PER_TD)
len=MAX_SIZE_PER_TD;
len -= pPdd->qhbuffer->qh[i*2+1].dtd.tb; // reduce by what's still to go in the TD
pTransfer->cbTransferred += len;
pPdd->qhbuffer->bPrimed[mapped_epNum] = FALSE;
if (pPdd->qhbuffer->qh[i*2+1].dtd.tb)
{
RETAILMSG(1,(L"Send error?? len=%x, status=%x, tb=%x\r\n",
pTransfer->cbBuffer, pPdd->qhbuffer->qh[i*2+1].dtd.status, pPdd->qhbuffer->qh[i*2+1].dtd.tb));
pTransfer->cbTransferred=pTransfer->cbBuffer;
}
if (pTransfer->cbTransferred<pTransfer->cbBuffer)
{
pTransfer->dwUsbError=UFN_MORE_DATA;
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (0x10000UL<<i));
UNLOCK();
UfnPdd_IssueTransfer(pPdd, i, pTransfer);
LOCK();
}
else
{
pTransfer->dwUsbError=UFN_NO_ERROR;
OUTREG32(&(pUSBDRegs->OTG.ENDPTCOMPLETE), (0x10000UL<<i));
if ( pPdd->ep[mapped_epNum]->bPagesLocked )
{
DEBUGCHK( pPdd->ep[mapped_epNum]->pMappedBufPtr != NULL );
UnlockPages(pPdd->ep[mapped_epNum]->pMappedBufPtr, pTransfer->cbBuffer);
if (pPdd->ep[mapped_epNum]->pMappedBufPtr)
{
if(FAILED(CeCloseCallerBuffer(pPdd->ep[mapped_epNum]->pMappedBufPtr,
(LPVOID)pTransfer->pvBuffer,
pTransfer->cbBuffer,
ARG_IO_PTR)))
RETAILMSG(1, (TEXT("Failed to CloseCallerBuffer\r\n")));
}
pPdd->ep[mapped_epNum]->pMappedBufPtr = NULL;
pPdd->ep[mapped_epNum]->bPagesLocked = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -