⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c6400otgdevice.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		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)&currentDriver)) 
	{
		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 + -