?? s3c6410otgdevice.cpp
字號(hào):
WriteEPSpecificReg(dwEndpoint, DOEPDMA, pContext->pPAddrEP[dwEndpoint][pContext->dwPipelinedStrIdx]);
WriteEPSpecificReg(dwEndpoint, DOEPTSIZ, pContext->dwPipelinedPktCnt<<PACKET_COUTNT_IDX | pContext->dwPipelinedXferSize);
WriteEPSpecificReg(dwEndpoint, DOEPCTL, EP_ENABLE | CLEAR_NAK | SET_TYPE_BULK | USB_ACT_EP | peps->dwPacketSizeAssigned);
}
CompleteTransfer(pContext, peps, UFN_NO_ERROR);
}
}
else
{
DWORD dwPktcnt, dwBytes;
dwPktcnt = pTransfer->cbBuffer / peps->dwPacketSizeAssigned;
dwBytes = pTransfer->cbBuffer % peps->dwPacketSizeAssigned;
if (dwBytes) dwPktcnt++;
pContext->dwPipelinedXferSize = pTransfer->cbBuffer;
EnableEndpointInterrupt(pContext, dwEndpoint, peps->dwDirectionAssigned);
WriteEPSpecificReg(dwEndpoint, DOEPDMA, pContext->pPAddrEP[dwEndpoint][pContext->dwPipelinedStrIdx]);
WriteEPSpecificReg(dwEndpoint, DOEPTSIZ, dwPktcnt<<PACKET_COUTNT_IDX | pTransfer->cbBuffer);
WriteEPSpecificReg(dwEndpoint, DOEPCTL, EP_ENABLE | CLEAR_NAK | SET_TYPE_BULK | USB_ACT_EP | peps->dwPacketSizeAssigned);
}
}
}
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
}
DWORD
WINAPI
UfnPdd_IssueTransfer(
PVOID pvPddContext,
DWORD dwEndpoint,
PSTransfer pTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DEBUGCHK(EP_VALID(dwEndpoint));
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
DEBUGCHK(peps->bInitialized);
DEBUGCHK(pTransfer->cbTransferred == 0);
DWORD dwRet = ERROR_SUCCESS;
DEBUGCHK(peps->pTransfer == NULL);
StartTransfer(pContext, peps, pTransfer);
FUNCTION_LEAVE_MSG();
return dwRet;
}
DWORD
WINAPI
UfnPdd_AbortTransfer(
PVOID pvPddContext,
DWORD dwEndpoint,
PSTransfer pTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PREFAST_DEBUGCHK(pTransfer);
DEBUGCHK(EP_VALID(dwEndpoint));
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
LOCK_ENDPOINT(peps);
DEBUGCHK(peps->bInitialized);
ValidateTransferDirection(pContext, peps, pTransfer);
DEBUGCHK(pTransfer == peps->pTransfer);
CompleteTransfer(pContext, peps, UFN_CANCELED_ERROR);
if (dwEndpoint == 0)
{
pContext->Ep0State = EP0_STATE_IDLE;
}
ResetEndpoint(pContext,peps);
DisableEndpointInterrupt(pContext, 0, USB_IN_TRANSFER);
DisableEndpointInterrupt(pContext, 0, USB_OUT_TRANSFER);
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
BOOL
SetOtgDevicePower (
PCTRLR_PDD_CONTEXT pContext,
CEDEVICE_POWER_STATE cpsNew
)
{
if (cpsNew == D0)
{
RETAILMSG(UFN_ZONE_POWER,(_T("[UFNPDD] USB_POWER : D0\r\n")));
InterruptDone(pContext->dwSysIntr);
pContext->pSYSCONregs->HCLK_GATE |= OTG_HCLK_EN; //OTG HClk enable
SetAllOutEpNak();
ClearSoftDisconnect();
ResetDevice(pContext);
ClearAllOutEpNak();
pContext->IsFirstReset = TRUE;
DWORD dwGOTGCTL = ReadReg(GOTGCTL);
if(!(dwGOTGCTL & (B_SESSION_VALID)))
{
Delay(100); //for OTG cable detahced state.
}
}
else if (cpsNew == D4)
{
RETAILMSG(UFN_ZONE_POWER,(_T("[UFNPDD] USB_POWER : D4\r\n")));
SetSoftDisconnect();
pContext->pSYSCONregs->HCLK_GATE &= ~OTG_HCLK_EN; //OTG HClk disable
}
return TRUE;
}
static
CEDEVICE_POWER_STATE
SetPowerState(
PCTRLR_PDD_CONTEXT pContext,
CEDEVICE_POWER_STATE cpsNew
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PREFAST_DEBUGCHK(pContext);
DEBUGCHK(VALID_DX(cpsNew));
ValidateContext(pContext);
// Adjust cpsNew.
if (cpsNew != pContext->cpsCurrent)
{
if (cpsNew == D1 || cpsNew == D2)
{
// D1 and D2 are not supported.
cpsNew = D0;
}
else if (pContext->cpsCurrent == D4)
{
// D4 can only go to D0.
cpsNew = D0;
}
}
if (cpsNew != pContext->cpsCurrent)
{
DEBUGMSG(UFN_ZONE_POWER, (_T("%s Going from D%u to D%u\r\n"), pszFname, pContext->cpsCurrent, cpsNew));
if ( (cpsNew < pContext->cpsCurrent) && pContext->hBusAccess )
{
SetDevicePowerState(pContext->hBusAccess, cpsNew, NULL);
}
switch (cpsNew)
{
case D0:
SetOtgDevicePower (pContext, D0);
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr, sizeof(pContext->dwSysIntr), NULL, 0, NULL);
if (pContext->fRunning)
{
// Cause the IST to restart.
pContext->fRestartIST = TRUE;
SetInterruptEvent(pContext->dwSysIntr);
}
break;
case D3:
KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &pContext->dwSysIntr, sizeof(pContext->dwSysIntr), NULL, 0, NULL);
break;
case D4:
SetOtgDevicePower (pContext, D4);
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr, sizeof(pContext->dwSysIntr), NULL, 0, NULL);
break;
}
if ( (cpsNew > pContext->cpsCurrent) && pContext->hBusAccess )
{
SetDevicePowerState(pContext->hBusAccess, cpsNew, NULL);
}
pContext->cpsCurrent = cpsNew;
}
FUNCTION_LEAVE_MSG();
return pContext->cpsCurrent;
}
static
VOID
FreeCtrlrContext(
PCTRLR_PDD_CONTEXT pContext
)
{
PREFAST_DEBUGCHK(pContext);
DEBUGCHK(!pContext->hevInterrupt);
DEBUGCHK(!pContext->hIST);
DEBUGCHK(!pContext->fRunning);
pContext->dwSig = GARBAGE_DWORD;
UnmapRegisterSet(pContext);
if (pContext->hBusAccess) CloseBusAccessHandle(pContext->hBusAccess);
if (pContext->dwSysIntr)
{
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr, sizeof(pContext->dwSysIntr), NULL, 0, NULL);
}
if (pContext->dwIrq != IRQ_UNSPECIFIED)
{
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pContext->dwSysIntr, sizeof(DWORD), NULL, 0, NULL);
}
DeleteCriticalSection(&pContext->csRegisterAccess);
LocalFree(pContext);
}
DWORD
WINAPI
UfnPdd_Deinit(
PVOID pvPddContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
FUNCTION_ENTER_MSG();
FreeCtrlrContext(pContext);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
DWORD
WINAPI
UfnPdd_Start(
PVOID pvPddContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
UFN_CLIENT_INFO currentDriver;
DWORD dwRet;
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
DEBUGCHK(!pContext->fRunning);
BOOL fIntInitialized = FALSE;
RETAILMSG(UFN_ZONE_INIT,(_T("[UFNPDD] USB DRIVER VERSION : %d\r\n"), USB_DD_VERSION));
// Some application can change the usbfn client dirver dynamically.
// In this case, below codes are needed.
if (USBCurrentDriver((PUFN_CLIENT_INFO)¤tDriver))
{
if(!wcscmp(currentDriver.szName, TEXT("RNDIS")) ||!wcscmp(currentDriver.szName, TEXT("rndis")))
{
pContext->dwUSBClassInfo = USB_RNDIS;
pContext->dwUsingEPCnt = 4;
RETAILMSG(UFN_ZONE_INIT,(_T("[UFNPDD] USB RNDIS Function Class Enabled\r\n")));
}
else if(!wcscmp(currentDriver.szName, TEXT("Serial_Class")) ||!wcscmp(currentDriver.szName, TEXT("serial_class")))
{
pContext->dwUSBClassInfo = USB_SERIAL;
pContext->dwUsingEPCnt = 3;
RETAILMSG(UFN_ZONE_INIT,(_T("[UFNPDD] USB Serial Function Class Enabled\r\n")));
}
else if(!wcscmp(currentDriver.szName, TEXT("Mass_Storage_Class")) ||!wcscmp(currentDriver.szName, TEXT("mass_storage_class")))
{
pContext->dwUSBClassInfo = USB_MSF;
pContext->dwUsingEPCnt = 3;
RETAILMSG(UFN_ZONE_INIT,(_T("[UFNPDD] USB Mass Storage Function Class Enabled\r\n")));
}
}
else
{
RETAILMSG(UFN_ZONE_ERROR,(_T("[UFNPDD] USB Function Class Read Error!!!!!!!\r\n")));
}
do
{
// Create the interrupt event
pContext->hevInterrupt = CreateEvent(0, FALSE, FALSE, NULL);
if (pContext->hevInterrupt == NULL)
{
dwRet = GetLastError();
DEBUGMSG(ZONE_ERROR, (_T("%s Error creating interrupt event. Error = %d\r\n"), pszFname, dwRet));
break;
}
fIntInitialized = InterruptInitialize(pContext->dwSysIntr, pContext->hevInterrupt, NULL, 0);
if (fIntInitialized == FALSE)
{
dwRet = ERROR_GEN_FAILURE;
DEBUGMSG(ZONE_ERROR, (_T("%s interrupt initialization failed\r\n"), pszFname));
break;
}
InterruptDone(pContext->dwSysIntr);
pContext->fExitIST = FALSE;
pContext->hIST = CreateThread(NULL, 0, ISTMain, pContext, 0, NULL);
if (pContext->hIST == NULL)
{
DEBUGMSG(ZONE_ERROR, (_T("%s IST creation failed\r\n"), pszFname));
dwRet = GetLastError();
break;
}
InitPDDContext(pContext);
if(pContext->bMemoryAllocFlag == FALSE)
{
for(DWORD i=0; i<pContext->dwUsingEPCnt; i++)
{
for(DWORD j=0; j<PIPELINED_FIFO_DEPTH; j++)
{
pContext->pVAddrEP[i][j] = (PDWORD)AllocPhysMem(pContext->dwPipelinedXferSize, PAGE_READWRITE, 0, 0, &pContext->pPAddrEP[i][j]);
memset(pContext->pVAddrEP[i][j], 0, pContext->dwPipelinedXferSize);
pContext->dwPipelinedXfered[i][j] = 0;
}
}
pContext->bMemoryAllocFlag = TRUE;
}
pContext->fRunning = TRUE;
dwRet = ERROR_SUCCESS;
}while(FALSE);
if (pContext->fRunning == FALSE)
{
DEBUGCHK(dwRet != ERROR_SUCCESS);
if (fIntInitialized) InterruptDisable(pContext->dwSysIntr);
if (pContext->hevInterrupt) CloseHandle(pContext->hevInterrupt);
pContext->hevInterrupt = NULL;
}
FUNCTION_LEAVE_MSG();
return dwRet;
}
// Stop the device.
DWORD
WINAPI
UfnPdd_Stop(
PVOID pvPddContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
DEBUGCHK(pContext->fRunning);
// Stop the IST
pContext->fExitIST = TRUE;
InterruptDisable(pContext->dwSysIntr);
SetEvent(pContext->hevInterrupt);
WaitForSingleObject(pContext->hIST, INFINITE);
CloseHandle(pContext->hevInterrupt);
CloseHandle(pContext->hIST);
pContext->hIST = NULL;
pContext->hevInterrupt = NULL;
WriteReg(DAINTMSK,0); // IN, OUT EP ALL MASK
WriteReg(DOEPMSK, 0); // DOEP INT MASK
WriteReg(DIEPMSK, 0); // DIEP INT MASK
WriteReg(GINTMSK, 0); // GINT MASK
WriteReg(GAHBCFG, 0); // GLOBAL INT MASK
WriteReg(GOTGINT, 0xE0304); // OTG INT All CLEAR
WriteReg(GINTSTS, INT_RESUME | INT_EPMIS | INT_SDE | INT_RESET | INT_SUSPEND); // GINT Clear
for (DWORD dwEpIdx = 0; dwEpIdx < ENDPOINT_COUNT; ++dwEpIdx)
{
EP_STATUS *peps = GetEpStatus(pContext, dwEpIdx);
ResetEndpoint(pContext, peps);
}
if(pContext->bMemoryAllocFlag == TRUE)
{
for(DWORD i=0; i<pContext->dwUsingEPCnt; i++)
{
for(DWORD j=0; j<PIPELINE
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -