📄 s3c6400otgdevice.cpp
字号:
DEBUGMSG(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:
HW_USBClocks(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:
HW_USBClocks(pContext, D4); //jassi
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;
}
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);
}
CloseHandle(g_SdCardDetectThread);
g_SdCardDetectThread = 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);
FUNCTION_ENTER_MSG();
DEBUGCHK(!pContext->fRunning);
BOOL fIntInitialized = FALSE;
if (USBCurrentDriver((PUFN_CLIENT_INFO)¤tDriver))
{
if( wcscmp(currentDriver.szName, TEXT("RNDIS")) == 0 )
{
USBClassInfo = USB_RNDIS;
RETAILMSG(1,(TEXT("[UFNPDD] USB RNDIS Function Class Enabled\r\n")));
}
else if( wcscmp(currentDriver.szName, TEXT("Serial_Class")) == 0 )
{
USBClassInfo = USB_Serial;
RETAILMSG(1,(TEXT("[UFNPDD] USB Serial Function Class Enabled\r\n")));
}
else if( wcscmp(currentDriver.szName, TEXT("Mass_Storage_Class")) == 0 )
{
USBClassInfo = USB_MSF;
RETAILMSG(1,(TEXT("[UFNPDD] USB MSF Function Class Enabled\r\n")));
}
}
else
{
RETAILMSG(1,(TEXT("[UFNPDD] USB Function Class Read Error!!!!!!!\r\n")));
}
// 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));
goto EXIT;
}
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));
goto EXIT;
}
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();
goto EXIT;
}
pContext->fRunning = TRUE;
dwRet = ERROR_SUCCESS;
EXIT:
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(pContext, DAINTMSK,0); //IN, OUT EP ALL MASK
WriteReg(pContext, DOEPMSK, 0); // DOEP INT MASK
WriteReg(pContext, DIEPMSK, 0); // DIEP INT MASK
WriteReg(pContext, GINTMSK, 0); //GINT MASK
WriteReg(pContext, GAHBCFG, 0); // GLOBAL INT MASK
WriteReg(pContext, GOTGINT, 0xe0304); //OTG INT All CLEAR
WriteReg(pContext, GINTSTS, INT_RESUME | INT_IN_EP|INT_SDE|INT_RESET |INT_SUSPEND|INT_RX_FIFO_NOT_EMPTY | INT_OTG); // GINT Clear
for (DWORD dwEpIdx = 0; dwEpIdx < ENDPOINT_COUNT; ++dwEpIdx)
{
EP_STATUS *peps = GetEpStatus(pContext, dwEpIdx);
ResetEndpoint(pContext, peps);
}
pContext->fRunning = FALSE;
DEBUGMSG(ZONE_FUNCTION, (_T("%s Device has been stopped\r\n"),
pszFname));
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
DWORD
WINAPI
UfnPdd_IsConfigurationSupportable(
PVOID pvPddContext,
UFN_BUS_SPEED Speed,
PUFN_CONFIGURATION pConfiguration
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DEBUGCHK(Speed == BS_FULL_SPEED);
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
// This PDD does not have any special requirements that cannot be
// handled through IsEndpointSupportable.
DWORD dwRet = ERROR_SUCCESS;
FUNCTION_LEAVE_MSG();
return dwRet;
}
//
// Is this endpoint supportable.
DWORD
WINAPI
UfnPdd_IsEndpointSupportable(
PVOID pvPddContext,
DWORD dwEndpoint,
UFN_BUS_SPEED Speed,
PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc,
BYTE bConfigurationValue,
BYTE bInterfaceNumber,
BYTE bAlternateSetting
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DEBUGCHK(EP_VALID(dwEndpoint));
DEBUGCHK(Speed == BS_FULL_SPEED);
DWORD dwRet = ERROR_SUCCESS;
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
// Special case for endpoint 0
if (dwEndpoint == 0)
{
DEBUGCHK(pEndpointDesc->bmAttributes == USB_ENDPOINT_TYPE_CONTROL);
// Endpoint 0 only supports 8 or 16 byte packet size
if (pEndpointDesc->wMaxPacketSize < EP_0_PACKET_SIZE)
{
DEBUGMSG(ZONE_ERROR, (_T("%s Endpoint 0 only supports %u byte packets\r\n"), pszFname, EP_0_PACKET_SIZE));
dwRet = ERROR_INVALID_PARAMETER;
}
else
{
// Larger than EP 0 Max Packet Size - reduce to Max
pEndpointDesc->wMaxPacketSize = EP_0_PACKET_SIZE;
}
}
else if (dwEndpoint < ENDPOINT_COUNT)
{
BYTE bTransferType = pEndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
DEBUGCHK(bTransferType != USB_ENDPOINT_TYPE_CONTROL);
// Validate and adjust packet size
DWORD wPacketSize = (pEndpointDesc->wMaxPacketSize & USB_ENDPOINT_MAX_PACKET_SIZE_MASK);
switch(bTransferType)
{
// Isoch not currently supported by Samsung HW
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
DEBUGMSG(ZONE_ERROR, (_T("%s Isochronous endpoints are not supported\r\n"), pszFname));
dwRet = ERROR_INVALID_PARAMETER;
break;
case USB_ENDPOINT_TYPE_BULK:
case USB_ENDPOINT_TYPE_INTERRUPT:
// HW Can only Support 8, 16, 32, 64 byte packets
if((wPacketSize >= 8) && (wPacketSize < 16))
{
wPacketSize = 8;
}
else if ((wPacketSize >= 16) && (wPacketSize < 32))
{
wPacketSize = 16;
}
else if((wPacketSize >= 32) && (wPacketSize < 64))
{
wPacketSize = 32;
}
else if ((wPacketSize >= 64) && (wPacketSize < 128))
{
wPacketSize = 64;
}
else if((wPacketSize >= 128) && (wPacketSize < 256))
{
wPacketSize = 128;
}
else if ((wPacketSize >= 256) && (wPacketSize < 512))
{
wPacketSize = 256;
}
else if (wPacketSize >= 512)
{
wPacketSize = 512;
}
else
{ // wPacketSize < 8
dwRet = ERROR_INVALID_PARAMETER;
}
break;
default:
dwRet = ERROR_INVALID_PARAMETER;
break;
}
// If Requested Size is larger than what is supported ... change it.
// Note only try and change it if no errors so far... meaning Ep is
// Supportable.
if ( (wPacketSize != (pEndpointDesc->wMaxPacketSize & USB_ENDPOINT_MAX_PACKET_SIZE_MASK)) && (dwRet == ERROR_SUCCESS) )
{
pEndpointDesc->wMaxPacketSize &= ~USB_ENDPOINT_MAX_PACKET_SIZE_MASK;
pEndpointDesc->wMaxPacketSize |= wPacketSize;
}
}
FUNCTION_LEAVE_MSG();
return dwRet;
}
// Clear an endpoint stall.
DWORD
WINAPI
UfnPdd_ClearEndpointStall(
PVOID pvPddContext,
DWORD dwEndpoint
)
{
DWORD dwRet = ERROR_SUCCESS;
RETAILMSG(0, (TEXT("[UFNPDD] UfnPdd_ClearEndpointStall: dwEndpoint %x \r\n"),dwEndpoint));
SETFNAME();
FUNCTION_ENTER_MSG();
DEBUGCHK(EP_VALID(dwEndpoint));
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
LOCK_ENDPOINT(peps);
if (dwEndpoint == 0)
{
WriteReg(pContext, DIEPCTL0, (0<<31)|(0<<26)|(0<<21)|(1<<11)|(0<<0));
WriteReg(pContext, DOEPCTL0, (0<<31)|(0<<26)|(0<<21)|(0<<0));
}
else if (peps->dwDirectionAssigned == USB_IN_TRANSFER)
{
WriteEPSpecificReg(pContext, dwEndpoint, DIEPCTL, 0<<30|0<<27|0<<21|2<<18|1<<15|1<<11|peps->dwPacketSizeAssigned);
}
else
{ // Out Endpoint
WriteEPSpecificReg(pContext, dwEndpoint, DOEPCTL, 0<<21|2<<18|1<<15|1<<11|peps->dwPacketSizeAssigned);
}
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
// Initialize an endpoint.
DWORD
WINAPI
UfnPdd_InitEndpoint(
PVOID pvPddContext,
DWORD dwEndpoint,
UFN_BUS_SPEED Speed,
PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc,
PVOID pvReserved,
BYTE bConfigurationValue,
BYTE bInterfaceNumber,
BYTE bAlternateSetting
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DEBUGCHK(EP_VALID(dwEndpoint));
PREFAST_DEBUGCHK(pEndpointDesc);
#ifdef DEBUG
{
USB_ENDPOINT_DESCRIPTOR EndpointDesc;
memcpy(&EndpointDesc, pEndpointDesc, sizeof(EndpointDesc));
DEBUGCHK(UfnPdd_IsEndpointSupportable(pvPddContext, dwEndpoint, Speed,
&EndpointDesc, bConfigurationValue, bInterfaceNumber, bAlternateSetting) == ERROR_SUCCESS);
DEBUGCHK(memcmp(&EndpointDesc, pEndpointDesc, sizeof(EndpointDesc)) == 0);
}
#endif
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
BYTE bEndpointAddress = 0;
DWORD dwRegTemp = 0;
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
DEBUGCHK(!peps->fInitialized);
InitializeCriticalSection(&peps->cs);
DWORD wMaxPacketSize = pEndpointDesc->wMaxPacketSize & USB_ENDPOINT_MAX_PACKET_SIZE_MASK;
DEBUGCHK(wMaxPacketSize);
// If the target is endpoint 0, then only allow the function driver
// to register a notification function.
if (dwEndpoint == 0)
{
peps->dwPacketSizeAssigned = wMaxPacketSize;
// Interrupts for endpoint 0 are enabled in ISTMain
}
else if (dwEndpoint < ENDPOINT_COUNT)
{
bEndpointAddress = pEndpointDesc->bEndpointAddress;
BOOL fModeOut = USB_ENDPOINT_DIRECTION_OUT(bEndpointAddress);
if (fModeOut)
{
peps->dwDirectionAssigned = USB_OUT_TRANSFER;
}
else
{
peps->dwDirectionAssigned = USB_IN_TRANSFER;
}
// Set Transfer Type
BYTE bTransferType = pEndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
DEBUGCHK(bTransferType != USB_ENDPOINT_TYPE_CONTROL);
switch(bTransferType)
{
case USB_ENDPOINT_TYPE_ISOCHRONOUS:
if ( peps->dwDirectionAssigned == USB_IN_TRANSFER)
{
dwRegTemp |= SET_TYPE_ISO;
}
else
{
dwRegTemp |= SET_TYPE_ISO;
}
break;
case USB_ENDPOINT_TYPE_BULK:
case USB_ENDPOINT_TYPE_INTERRUPT:
default:
// Clear ISO bit - Set type to Bulk
if ( peps->dwDirectionAssigned == USB_IN_TRANSFER)
{
dwRegTemp |= SET_TYPE_BULK;
}
else
{
dwRegTemp |= SET_TYPE_BULK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -