📄 pdd.c
字号:
//
//------------------------------------------------------------------------------
CEDEVICE_POWER_STATE UpdateDevicePower(USBFN_PDD *pPdd)
{
CEDEVICE_POWER_STATE cpsNew;
PREFAST_ASSERT(pPdd!=NULL);
cpsNew= min (pPdd->m_CurPMPowerState, pPdd->m_CurSelfPowerState);
DEBUGMSG(ZONE_FUNCTION, (_T("UpdateDevicePower Going from D%d to D%d\r\n"), pPdd->m_CurActualPowerState , cpsNew));
if ( (cpsNew < pPdd->m_CurActualPowerState) && pPdd->hParentBus)
{
BOOL bBusSucceed = SetDevicePowerState(pPdd->hParentBus, cpsNew, NULL);
if (bBusSucceed &&
(pPdd->m_CurActualPowerState==D3 || pPdd->m_CurActualPowerState==D4))
{
UfnPdd_PowerUp((PVOID)pPdd);
}
}
if ( (cpsNew > pPdd->m_CurActualPowerState ) && pPdd->hParentBus )
{
BOOL bBusSucceed = SetDevicePowerState(pPdd->hParentBus, cpsNew, NULL);
if (bBusSucceed && (cpsNew == D4 ||cpsNew == D3 ))
{
RETAILMSG(1, (TEXT("UpdateDevicePower to powerdown\r\n")));
UfnPdd_PowerDown((PVOID)pPdd);
}
}
pPdd->m_CurActualPowerState = cpsNew ;
return (cpsNew) ;
}
//------------------------------------------------------------------------------
//
// Function: SetupInterrupt
//
// This function handles setup packet interrupts.
//
// Parameter :
// pPdd - Pointer to USBFN_PDD
//
// Return:
// NULL
//
//--------------------------------------------------------------------------------
static VOID SetupEvent(USBFN_PDD *pPdd)
{
CSP_USB_REGS*pUSBDRegs = pPdd->pUSBDRegs;
DWORD data[2];
USB_DEVICE_REQUEST *pSetup = (USB_DEVICE_REQUEST*)data;
LOCK();
if (pPdd->devState==0) // Why no bit set in PORTSC???
{
// Let MDD process change
USB_PORTSC_T state;
DWORD * t1;
int i;
DEBUGMSG(ZONE_PDD, (L"Device Attach\r\n"));
//
// Get device state & change
t1=(DWORD *)&state;
*t1 = INREG32(&pUSBDRegs->OTG.PORTSC[USBD_PORT_NUM]);
pPdd->devState=1;
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_ATTACH);
LOCK();
if (state.PSPD==0x2)
{
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_SPEED, BS_HIGH_SPEED);
DEBUGMSG(1,(_T(" BS_HIGH_SPEED %x\r\n"),BS_HIGH_SPEED) );
LOCK();
}
else
{
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_SPEED, BS_FULL_SPEED);
DEBUGMSG(1,(_T(" BS_FULL_SPEED %x\r\n"),BS_FULL_SPEED) );
LOCK();
}
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_RESET);
LOCK();
DEBUGMSG(1,(_T(" state.PSPD %x\r\n"),state.PSPD) );
if (state.PSPD==2)
{
pPdd->highspeed=1;
for (i=0;i<USBD_EP_COUNT;i++)
pPdd->ep[i]=&pPdd->eph[i];
}
else
{
pPdd->highspeed=0;
for (i=0;i<USBD_EP_COUNT;i++)
pPdd->ep[i]=&pPdd->epf[i];
}
}
GetSetupPacket(pPdd, data);
// DEBUGMSG(ZONE_PDD,(_T("Setup: %x %x\r\n"),data[0],data[1]) );
DEBUGMSG(1,(_T("Setup: %x %x\r\n"),data[0],data[1]) );
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_SETUP_PACKET, (DWORD)data);
}
//----------------------------------------------------------------
//
// Function: DumpDeviceState
//
// Dump the connection status based on the PORTSC register
//
// Parameter:
// state - Pointer to PORTSC register
//
// Return
// NULL
//
//----------------------------------------------------------------
void DumpDeviceState( USB_PORTSC_T * state)
{
if (state->CCS)
RETAILMSG(1, (L"\t\tCurrent Connect Status: Attached\r\n"));
if (state->CSC)
RETAILMSG(1, (L"\t\tConnect Status Change: Changed\r\n"));
if (state->PE)
RETAILMSG(1, (L"\t\tPort Enabled\r\n"));
if (state->PEC)
RETAILMSG(1, (L"\t\tPort Enable/Disable Change\r\n"));
if (state->OCA)
RETAILMSG(1, (L"\t\tOver-current Active\r\n"));
if (state->OCC)
RETAILMSG(1, (L"\t\tOver-current Change\r\n"));
if (state->FPR)
RETAILMSG(1, (L"\t\tForce Port Resume\r\n"));
if (state->SUSP)
RETAILMSG(1, (L"\t\tSuspend\r\n"));
if (state->PR)
RETAILMSG(1, (L"\t\tPort Reset\r\n"));
if (state->HSP)
RETAILMSG(1, (L"\t\tHigh-Speed Port \r\n"));
RETAILMSG(1, (L"\t\tLine Status: %x", state->LS));
switch (state->LS)
{
case 0:
RETAILMSG(1, (L"\t\t\tSE0\r\n"));
break;
case 1:
RETAILMSG(1, (L"\t\t\tJ-state\r\n"));
break;
case 2:
RETAILMSG(1, (L"\t\t\tK-state\r\n"));
break;
case 3:
default:
RETAILMSG(1, (L"\t\t\tUndefined\r\n"));
break;
}
if (state->PP)
RETAILMSG(1, (L"\t\t??? Should be 0 for device\r\n"));
if (state->PO)
RETAILMSG(1, (L"\t\tPort Owner\r\n"));
if (state->PIC)
{
RETAILMSG(1, (L"\t\tPort Indicator Control"));
switch (state->PIC)
{
case 1:
RETAILMSG(1, (L"\t\t\tAmber\r\n"));
break;
case 2:
RETAILMSG(1, (L"\t\t\tGreen\r\n"));
break;
case 3:
default:
RETAILMSG(1, (L"\t\t\tUndefined\r\n"));
break;
}
}
if (state->PTC)
RETAILMSG(1, (L"\t\tPort Test Control: %x\r\n", state->PTC));
if (state->WKCN)
RETAILMSG(1, (L"\t\tWake on Connect Enable (WKCNNT_E)\r\n"));
if (state->WKDC)
RETAILMSG(1, (L"\t\tWake on Disconnect Enable (WKDSCNNT_E) \r\n"));
if (state->WKOC)
RETAILMSG(1, (L"\t\tWake on Over-current Enable (WKOC_E) \r\n"));
if (state->PHCD)
RETAILMSG(1, (L"\t\tPHY Low Power Suspend - Clock Disable (PLPSCD) \r\n"));
if (state->PFSC)
RETAILMSG(1, (L"\t\tPort Force Full Speed Connect \r\n"));
RETAILMSG(1, (L"\t\tPort Speed: %x->", state->PSPD));
switch (state->PSPD)
{
case 0:
RETAILMSG(1, (L"\t\t\tFull Speed\r\n"));
break;
case 1:
RETAILMSG(1, (L"\t\t\tLow Speed\r\n"));
break;
case 2:
RETAILMSG(1, (L"\t\t\tHigh Speed\r\n"));
break;
case 3:
default:
RETAILMSG(1, (L"\t\t\tUndefined\r\n"));
break;
}
RETAILMSG(1, (L"\t\tParallel Transceiver Width:%x->", state->PTW));
if (state->PTW)
RETAILMSG(1, (L"\t\t\t16 bits\r\n"));
else
RETAILMSG(1, (L"\t\t\t8 bits\r\n"));
if (state->STS)
RETAILMSG(1, (L"\t\tSerial Transceiver Select \r\n"));
RETAILMSG(1, (L"\t\tParallel Transceiver Select:%x->", state->PTS));
switch (state->PTS)
{
case 0:
RETAILMSG(1, (L"\t\t\tUTMI/UTMI+\r\n"));
break;
case 1:
RETAILMSG(1, (L"\t\t\tPhilips Classic\r\n"));
break;
case 2:
RETAILMSG(1, (L"\t\t\tULPI\r\n"));
break;
case 3:
RETAILMSG(1, (L"\t\t\tSerial/1.1 PHY (FS Only)\r\n"));
break;
default:
RETAILMSG(1, (L"\t\t\tUndefined\r\n"));
break;
}
}
//------------------------------------------------------------------------------
//
// Function: DevStatEvent
//
// This function handles device state change interrupts.
//
// Called with context LOCKed
//
// Parameters:
//
// pPdd - Pointer to USBFN_PDD structure
//
// Return:
//
// NULL
//
//-------------------------------------------------------------------------------
static VOID DevStatEvent (USBFN_PDD *pPdd)
{
CSP_USB_REGS *pUSBDRegs = pPdd->pUSBDRegs;
DWORD *t1;
USB_PORTSC_T state;
// Get device state & change
t1=(DWORD *)&state;
*t1 = INREG32(&pUSBDRegs->OTG.PORTSC[USBD_PORT_NUM]);
//DumpDeviceState( & state);
//Reset
//Deattach
if (pPdd->devState&&state.SUSP)
{
// TODO: Call bus driver (OTG?) to move HW to deep sleep
// Let MDD process change
DEBUGMSG(ZONE_PDD, (_T("Device Detach\r\n")));
// Don't process other changes (we are disconnected)
pPdd->devState=0;
UNLOCK();
pPdd->pfnNotify(pPdd->pMddContext, UFN_MSG_BUS_EVENTS, UFN_DETACH);
LOCK();
// SetSelfPowerState to D4
pPdd->m_CurSelfPowerState = D4; // Do we need set to D3 as wake up source?
UpdateDevicePower(pPdd);
OUTREG32(&pPdd->pUSBDRegs->OTG.T_154H.USBADR, 0);
}
}
//------------------------------------------------------------------------------
//
// Function: CopyFromUncachedBuffer
//
// This function copies the data from the uncached memory back to the user buffers
//
//
// Parameters:
//
// pPdd - Pointer to USBFN_PDD structure
//
// EpNum - endpoint for which copy needs to be done
//
// len - length of data to be copied
//
// Return:
//
// NULL
//
//-------------------------------------------------------------------------------
void CopyFromUncachedBuffer(USBFN_PDD *pPdd, int EpNum, DWORD len )
{
DWORD dwOffset = ((DWORD)pPdd->ep[EpNum]->pMappedBufPtr) & (UserKInfo[KINX_PAGESIZE] - 1);
DWORD TdLen, BPCount, EndDataSize, BuffLen = len;
DEBUGMSG(1,(_T("+CopyFromUncachedBuffer(EP = %d, dwOffset = %d)\r\n"),EpNum,dwOffset));
// Get the length transfered in the first page, from the offset
if (len > (MAX_SIZE_PER_BP - dwOffset))
{
TdLen = (MAX_SIZE_PER_BP - dwOffset);
len -= TdLen;
}
else
{
TdLen = len;
len = 0; // first bp contains all the data
}
//If first page had all the data, then need to check if offset or the length is aligned
if ((dwOffset % 32) != 0 || ((BuffLen < (MAX_SIZE_PER_BP - dwOffset)) && ((BuffLen % 32) != 0)))
{
DEBUGMSG(0,(_T("Copying for bp0\r\n")));
memcpy(pPdd->ep[EpNum]->pMappedBufPtr, ((PUCHAR)Buffer_Td1 + dwOffset), TdLen );
}
// If the data > 16k then need to check for the Endsize that might have been unaligned,
// need this only if the Endsize comes in the same page where a 16k size ends.
if(BuffLen > MAX_SIZE_PER_TD)
{
EndDataSize = BuffLen % MAX_SIZE_PER_TD;
if((EndDataSize + dwOffset) <= MAX_SIZE_PER_BP)
{
if ((EndDataSize % 32) != 0)
{
memcpy((pPdd->ep[EpNum]->pMappedBufPtr + ( (pPdd->ep[EpNum]->dwNumPages - 1) * MAX_SIZE_PER_BP)),
Buffer_Td2, EndDataSize );
}
// All the data has been checked for alignement , so no need to go in the flow.
len = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -