?? s3c6410otgdevice.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include "s3c6410otgdevice.h"
#define USB_DD_VERSION 100
static volatile BSP_ARGS *v_gBspArgs;
// Caution: Turning on more debug zones can cause STALLs due
// to corrupted setup packets.
UFN_GENERATE_DPCURSETTINGS(__MODULE__,
_T("Power"), _T("Trace"), _T(""), _T(""),
USBFNCTL_ZONES);
#define UDC_REG_PRIORITY_VAL _T("Priority256")
#define LOCK_ENDPOINT(peps) EnterCriticalSection(&peps->cs)
#define UNLOCK_ENDPOINT(peps) LeaveCriticalSection(&peps->cs)
// Return the irq bit for this endpoint.
#define EpToIrqStatBit(dwEndpoint) (0x1<<(BYTE)dwEndpoint)
#define EP_0_PACKET_SIZE 0x40 // USB2.0
#define ENDPOINT_COUNT 16
#define EP_VALID(x) ((x) < ENDPOINT_COUNT)
#define DEFAULT_PRIORITY 120
#define SET TRUE
#define CLEAR FALSE
// This function is for checking the current usb client driver.
extern BOOL USBCurrentDriver(PUFN_CLIENT_INFO pDriverList);
#define PIPELINED_FIFO_DEPTH 2
#define GET_NEXT_PF_IDX(i) (((i+1) >= PIPELINED_FIFO_DEPTH) ? 0 : (i+1))
#define GET_PREV_PF_IDX(i) (((i-1) < 0) ? (PIPELINED_FIFO_DEPTH-1) : (i-1))
typedef struct CTRL_PDD_CONTEXT {
volatile S3C6410_SYSCON_REG * pSYSCONregs;
PVOID pvMddContext;
DWORD dwSig;
HANDLE hIST;
HANDLE hevInterrupt;
BOOL fRunning;
CRITICAL_SECTION csRegisterAccess;
BOOL fSpeedReported;
BOOL fRestartIST;
BOOL fExitIST;
BOOL attachedState;
BOOL sendDataEnd;
BOOL IsFirstReset;
EP0_STATE Ep0State;
DWORD dwEp0MaxPktSize;
DWORD dwDetectedSpeed;
// registry
DWORD dwSysIntr;
DWORD dwIrq;
DWORD dwISTPriority;
USB_DEVICE_REQUEST UDR;
EP_STATUS rgEpStatus[ENDPOINT_COUNT];
PFN_UFN_MDD_NOTIFY pfnNotify;
HANDLE hBusAccess;
CEDEVICE_POWER_STATE cpsCurrent;
DWORD dwUSBClassInfo;
PDWORD pVAddrEP[ENDPOINT_COUNT][PIPELINED_FIFO_DEPTH];
DWORD pPAddrEP[ENDPOINT_COUNT][PIPELINED_FIFO_DEPTH];
DWORD dwPipelinedXfered[ENDPOINT_COUNT][PIPELINED_FIFO_DEPTH];
DWORD dwPipelinedStrIdx;
DWORD dwPipelinedEndIdx;
DWORD dwPipelinedXferSize;
DWORD dwPipelinedPktCnt;
DWORD dwPipelinedEP;
BOOL bRingBufferFull;
BOOL bRdySetupPkt;
DWORD dwInEPRunning[ENDPOINT_COUNT];
DWORD dwXmittingEP;
DWORD dwXmitReadyCnt;
DWORD dwUsingEPCnt;
BOOL bOutEPDMAStartFlag;
BOOL bMemoryAllocFlag;
} *PCTRLR_PDD_CONTEXT;
// Global variables
volatile BYTE *g_pUDCBase;
#define SC6410_SIG '6410' // "S3C6410" signature
#define IS_VALID_SC6410_CONTEXT(ptr) \
( (ptr != NULL) && (ptr->dwSig == SC6410_SIG) )
#ifdef DEBUG
// Validate the context.
static
VOID
ValidateContext(
PCTRLR_PDD_CONTEXT pContext
)
{
PREFAST_DEBUGCHK(pContext);
DEBUGCHK(pContext->dwSig == SC6410_SIG);
DEBUGCHK(!pContext->hevInterrupt || pContext->hIST);
DEBUGCHK(VALID_DX(pContext->cpsCurrent));
DEBUGCHK(pContext->pfnNotify);
}
#else
#define ValidateContext(ptr)
#endif
#define CTRLR_BASE_REG_ADDR(offset) ((volatile ULONG*) ( (g_pUDCBase) + (offset)))
BOOL SetOtgDevicePower (
PCTRLR_PDD_CONTEXT pContext,
CEDEVICE_POWER_STATE cpsNew);
static
void
Delay(
DWORD count
)
{
volatile int i, j = 0;
volatile static int loop = S3C6410_ACLK/100000;
for(; count > 0; count--)
{
for(i=0; i < loop; i++)
{
j++;
}
}
}
// Read a register.
inline
DWORD
ReadReg(
DWORD dwOffset
)
{
volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
DWORD bValue = (DWORD) *pbReg;
return bValue;
}
// Write a register.
inline
VOID
WriteReg(
DWORD dwOffset,
DWORD bValue
)
{
volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
*pbReg = (ULONG) bValue;
}
// Read from Endpoint Specific Register
inline
DWORD
ReadEPSpecificReg(
DWORD dwEndpoint,
DWORD regOffset
)
{
DWORD bValue = ReadReg(regOffset + (dwEndpoint*0x20));
return bValue;
}
// Write to Endpoint Specific Register
inline
VOID
WriteEPSpecificReg(
DWORD dwEndpoint,
DWORD regOffset,
DWORD bValue
)
{
WriteReg(regOffset + (dwEndpoint*0x20), bValue);
}
inline
DWORD
SetClearReg(
DWORD dwOffset,
DWORD dwMask,
BOOL bSet
)
{
volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
volatile DWORD bValue = (DWORD) *pbReg;
if (bSet)
{
bValue |= dwMask;
}
else
{
bValue &= ~dwMask;
}
*pbReg = bValue;
return bValue;
}
// Set or Clear for specific bit of register.
inline
DWORD
SetClearEPSpecificReg(
DWORD dwEndpoint,
DWORD dwOffset,
DWORD dwMask,
BOOL bSet
)
{
DWORD bValue = 0;
// Now Write the Register associated with this Endpoint for a given offset
bValue = SetClearReg(dwOffset+ (dwEndpoint*0x20), dwMask, bSet);
return bValue;
}
/*++
Routine Description:
Return the data register of an endpoint.
Arguments:
dwEndpoint - the target endpoint
Return Value:
The data register of the target endpoint.
--*/
static
volatile ULONG*
_GetDataRegister(
DWORD dwEndpoint
)
{
volatile ULONG *pulDataReg = NULL;
//
// find the data register (non-uniform offset)
//
switch (dwEndpoint)
{
case 0: pulDataReg = CTRLR_BASE_REG_ADDR(EP0_FIFO); break;
case 1: pulDataReg = CTRLR_BASE_REG_ADDR(EP1_FIFO); break;
case 2: pulDataReg = CTRLR_BASE_REG_ADDR(EP2_FIFO); break;
case 3: pulDataReg = CTRLR_BASE_REG_ADDR(EP3_FIFO); break;
case 4: pulDataReg = CTRLR_BASE_REG_ADDR(EP4_FIFO); break;
case 5: pulDataReg = CTRLR_BASE_REG_ADDR(EP5_FIFO); break;
case 6: pulDataReg = CTRLR_BASE_REG_ADDR(EP6_FIFO); break;
case 7: pulDataReg = CTRLR_BASE_REG_ADDR(EP7_FIFO); break;
case 8: pulDataReg = CTRLR_BASE_REG_ADDR(EP8_FIFO); break;
case 9: pulDataReg = CTRLR_BASE_REG_ADDR(EP9_FIFO); break;
case 10: pulDataReg = CTRLR_BASE_REG_ADDR(EP10_FIFO); break;
case 11: pulDataReg = CTRLR_BASE_REG_ADDR(EP11_FIFO); break;
case 12: pulDataReg = CTRLR_BASE_REG_ADDR(EP12_FIFO); break;
case 13: pulDataReg = CTRLR_BASE_REG_ADDR(EP13_FIFO); break;
case 14: pulDataReg = CTRLR_BASE_REG_ADDR(EP14_FIFO); break;
case 15: pulDataReg = CTRLR_BASE_REG_ADDR(EP15_FIFO); break;
default:
DEBUGCHK(FALSE);
break;
}
return pulDataReg;
} // _GetDataRegister
// Retrieve the endpoint status structure.
inline
static
PEP_STATUS
GetEpStatus(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwEndpoint
)
{
PEP_STATUS peps = &pContext->rgEpStatus[dwEndpoint];
return peps;
}
/*++
Routine Description:
Enable the interrupt of an endpoint.
Arguments:
dwEndpoint - the target endpoint
Return Value:
None.
--*/
static
VOID
EnableDisableEndpointInterrupt(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwEndpoint,
DWORD dwDirection,
BOOL fEnable
)
{
EnterCriticalSection(&pContext->csRegisterAccess);
volatile DWORD bEpIntReg = ReadReg(DAINTMSK);
DWORD bIrqEnBit = EpToIrqStatBit(dwEndpoint);
if (dwEndpoint == 0)
{
if (dwDirection == USB_OUT_TRANSFER)
{
bIrqEnBit = bIrqEnBit << ENDPOINT_COUNT;
}
else if (dwDirection == USB_IN_TRANSFER)
{
bIrqEnBit = bIrqEnBit;
}
}
else
{
if (dwDirection == USB_OUT_TRANSFER)
{
bIrqEnBit = bIrqEnBit << ENDPOINT_COUNT;
}
else if (dwDirection == USB_IN_TRANSFER)
{
bIrqEnBit = bIrqEnBit;
}
}
if (fEnable)
{
bEpIntReg |= bIrqEnBit;
}
else
{
bEpIntReg &= ~bIrqEnBit;
}
WriteReg(DAINTMSK, bEpIntReg);
LeaveCriticalSection(&pContext->csRegisterAccess);
}
static
inline
VOID
EnableEndpointInterrupt(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwEndpoint,
DWORD dwDirection
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
EnableDisableEndpointInterrupt(pContext, dwEndpoint, dwDirection, TRUE);
FUNCTION_LEAVE_MSG();
}
static
inline
VOID
DisableEndpointInterrupt(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwEndpoint,
DWORD dwDirection
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
EnableDisableEndpointInterrupt(pContext, dwEndpoint, dwDirection, FALSE);
FUNCTION_LEAVE_MSG();
}
// Reset an endpoint
static
VOID
ResetEndpoint(
PCTRLR_PDD_CONTEXT pContext,
EP_STATUS *peps
)
{
SETFNAME();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -