📄 pxa25xpdd.cpp
字号:
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
LOCK_ENDPOINT(peps);
DEBUGCHK(peps->fInitialized);
ValidateTransferDirection(pContext, peps, pTransfer);
DEBUGCHK(pTransfer == peps->pTransfer);
if (dwEndpoint == 0) {
pContext->fEndpoint0AckNeeded = FALSE;
}
ResetEndpoint(pContext, peps);
CompleteTransfer(pContext, peps, UFN_CANCELED_ERROR);
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
static
VOID
FreePxaContext(
PCTRLR_PDD_CONTEXT pContext
)
{
PREFAST_DEBUGCHK(pContext);
DEBUGCHK(!pContext->hevInterrupt);
DEBUGCHK(!pContext->hIST);
DEBUGCHK(!pContext->fRunning);
pContext->dwSig = GARBAGE_DWORD;
if (pContext->pvLibContext) Pxa25xLibDeinit(pContext->pvLibContext);
UnmapRegisterSet();
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->dwIrq,
sizeof(DWORD), NULL, 0, NULL);
}
DeleteCriticalSection(&pContext->csIsrCtrlAccess);
LocalFree(pContext);
}
// Deinitialize the device.
DWORD
WINAPI
UfnPdd_Deinit(
PVOID pvPddContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
FreePxaContext(pContext);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
// Start the Device.
DWORD
WINAPI
UfnPdd_Start(
PVOID pvPddContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet;
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
FUNCTION_ENTER_MSG();
DEBUGCHK(!pContext->fRunning);
BOOL fIntInitialized = FALSE;
// 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 = Pxa25xLibStart(pContext->pvLibContext);
EXIT:
if (dwRet != ERROR_SUCCESS) {
if (fIntInitialized) InterruptDisable(pContext->dwSysIntr);
if (pContext->fRunning) {
pContext->fExitIST = TRUE;
InterruptDisable(pContext->dwSysIntr);
SetEvent(pContext->hevInterrupt);
WaitForSingleObject(pContext->hIST, INFINITE);
CloseHandle(pContext->hIST);
pContext->hIST = NULL;
pContext->fRunning = FALSE;
}
if (pContext->hevInterrupt) CloseHandle(pContext->hevInterrupt);
pContext->hevInterrupt = NULL;
}
FUNCTION_LEAVE_MSG();
return dwRet;
}
// Stop the Device
// TODO: Move to Common PDD Lib?
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;
ResetDevice(pContext);
pContext->fRunning = FALSE;
Pxa25xLibStop(pContext->pvLibContext);
DEBUGMSG(ZONE_PIPE, (_T("%s Device has been disabled\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;
}
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));
DWORD dwRet = ERROR_SUCCESS;
BYTE bEndpointAddress = 0;
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
PREFAST_DEBUGCHK(pEndpointDesc);
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
// Special case for endpoint 0
if (dwEndpoint == 0) {
DEBUGCHK(pEndpointDesc->bmAttributes == USB_ENDPOINT_TYPE_CONTROL);
}
else if (dwEndpoint < ENDPOINT_COUNT) {
BYTE bTransferType = pEndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
if (bTransferType != peps->dwTypeSupported) {
DEBUGMSG(ZONE_PIPE, (_T("%s endpoint %u does not support transfer type -> %u \r\n"),
pszFname, dwEndpoint, bTransferType));
dwRet = ERROR_INVALID_PARAMETER;
goto EXIT;
}
bEndpointAddress = pEndpointDesc->bEndpointAddress;
DWORD dwDirection;
if (USB_ENDPOINT_DIRECTION_IN(pEndpointDesc->bEndpointAddress)) {
dwDirection = USB_IN_TRANSFER;
}
else {
dwDirection = USB_OUT_TRANSFER;
}
if (peps->dwDirectionSupported == dwDirection) {
// Change the Address
bEndpointAddress &= USB_ENDPOINT_DIRECTION_MASK;
bEndpointAddress |= dwEndpoint;
}
else {
DEBUGMSG(ZONE_PIPE, (_T("%s endpoint %u does not support direction -> %u \r\n"),
pszFname, dwEndpoint, dwDirection));
dwRet = ERROR_INVALID_PARAMETER;
goto EXIT;
}
}
// if requested size is smaller than supported then return fail
if (peps->dwPacketSizeSupported > pEndpointDesc->wMaxPacketSize) {
DEBUGMSG(ZONE_ERROR, (_T("%s endpoint %u does not support packet size -> %u \r\n"),
pszFname, dwEndpoint, pEndpointDesc->wMaxPacketSize));
dwRet = ERROR_INVALID_PARAMETER;
goto EXIT;
}
// If Requested Size is larger than what is supported ... change it.
// Note only try and change it if no errors so far... meaning node is
// Supportable.
if (peps->dwPacketSizeSupported < pEndpointDesc->wMaxPacketSize) {
// Change the packet Size if Necessary
pEndpointDesc->wMaxPacketSize &= ~USB_ENDPOINT_MAX_PACKET_SIZE_MASK;
pEndpointDesc->wMaxPacketSize |= peps->dwPacketSizeSupported;
}
// Change the endpoint address if necessary
if (pEndpointDesc->bEndpointAddress != bEndpointAddress) {
pEndpointDesc->bEndpointAddress = bEndpointAddress;
}
EXIT:
FUNCTION_LEAVE_MSG();
return dwRet;
}
// 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);
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
DEBUGCHK(!peps->fInitialized);
InitializeCriticalSection(&peps->cs);
DEBUGCHK(pEndpointDesc->wMaxPacketSize == peps->dwPacketSizeSupported);
// Endpoints are always active.
peps->fInitialized = TRUE;
peps->fInIST = FALSE;
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
// Deinitialize an endpoint.
// TODO: Could be made to be part of Common PDD LIB
// this
DWORD
WINAPI
UfnPdd_DeinitEndpoint(
PVOID pvPddContext,
DWORD 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);
DEBUGCHK(peps->fInitialized);
DEBUGCHK(peps->pTransfer == NULL);
// Reset and disable the endpoint
// Mask endpoint interrupts
ResetEndpoint(pContext, peps);
peps->fInitialized = FALSE;
UNLOCK_ENDPOINT(peps);
DeleteCriticalSection(&peps->cs);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
// Stall an endpoint.
DWORD
WINAPI
UfnPdd_StallEndpoint(
PVOID pvPddContext,
DWORD dwEndpoint
)
{
DWORD dwRet = ERR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -