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

📄 sc2413pdd.cpp-ori

📁 支持三星原产的S3C2413开发板
💻 CPP-ORI
📖 第 1 页 / 共 5 页
字号:
	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->dwIrq, 
			sizeof(DWORD), NULL, 0, NULL);
	}
	
	DeleteCriticalSection(&pContext->csIndexedRegisterAccess);

	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();

	DWORD dwRet;
	PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
	ValidateContext(pContext);

	// RETAILMSG(1, (TEXT("UfnPDD_start.\n")));
	
	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 = 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;

	ResetDevice(pContext);

	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);

	PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);

	// 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) {
		pEndpointDesc->wMaxPacketSize = 64;
		BYTE bTransferType = pEndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
		DEBUGCHK(bTransferType != USB_ENDPOINT_TYPE_CONTROL);

		// Validate and adjust packet size
		WORD 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 = 64;
			}
			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;

	SETFNAME();
	FUNCTION_ENTER_MSG();

	DEBUGCHK(EP_VALID(dwEndpoint));

//	RETAILMSG(1, (_T("UfnPdd_ClearEndpointStall \r\n")));

	PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
	ValidateContext(pContext);

	PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
	LOCK_ENDPOINT(peps);

	if (dwEndpoint == 0){
		// Must Clear both Send and Sent Stall
		SetClearIndexedReg(pContext,dwEndpoint, EP0_CSR_REG_OFFSET, (EP0_SEND_STALL | EP0_SENT_STALL), CLEAR);
	}
	else if (peps->dwDirectionAssigned == USB_IN_TRANSFER){
		// Must Clear both Send and Sent Stall
		SetClearIndexedReg(pContext,dwEndpoint, IN_CSR1_REG_OFFSET, (FLUSH_IN_FIFO | IN_CLR_DATA_TOGGLE), SET);
		SetClearIndexedReg(pContext,dwEndpoint, IN_CSR1_REG_OFFSET, (IN_SEND_STALL | IN_SENT_STALL), CLEAR);			   
	}
	else{ // Out Endpoint
		// Must Clear both Send and Sent Stall
		SetClearIndexedReg(pContext,dwEndpoint, OUT_CSR1_REG_OFFSET, (FLUSH_OUT_FIFO | OUT_CLR_DATA_TOGGLE), SET);
		SetClearIndexedReg(pContext,dwEndpoint, OUT_CSR1_REG_OFFSET, (OUT_SEND_STALL | OUT_SENT_STALL), CLEAR);
	}
	
	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;

	PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
	DEBUGCHK(!peps->fInitialized);

	InitializeCriticalSection(&peps->cs);

	WORD 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) {
		// Clear all Status bits and leave the Endpoint interrupt disabled
		// Clear Fifos, and all register bits
		ResetEndpoint(pContext,peps);

		// Clear all bits in CSR2 - Disable DMA for now...
		WriteIndexedReg(pContext, dwEndpoint, IN_CSR2_REG_OFFSET, 0); 

		// Setup Direction (mode_in bit) 
		bEndpointAddress = pEndpointDesc->bEndpointAddress;
		BOOL fModeOut = USB_ENDPOINT_DIRECTION_OUT(bEndpointAddress);
		if (fModeOut) {
			SetClearIndexedReg(pContext, dwEndpoint,IN_CSR2_REG_OFFSET, 
				SET_MODE_IN, CLEAR);			  
			peps->dwDirectionAssigned = USB_OUT_TRANSFER;
		}
		else {
			SetClearIndexedReg(pContext, dwEndpoint, IN_CSR2_REG_OFFSET, 
				SET_MODE_IN, SET);
			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:
				// Set the ISO bit
				SetClearIndexedReg(pContext, dwEndpoint,IN_CSR2_REG_OFFSET, 
					SET_TYPE_ISO, SET);
				break;

			case USB_ENDPOINT_TYPE_BULK:
			case USB_ENDPOINT_TYPE_INTERRUPT:
			default:
				// Clear ISO bit - Set type to Bulk
				SetClearIndexedReg(pContext, dwEndpoint,IN_CSR2_REG_OFFSET, 
					SET_TYPE_ISO, CLEAR);
		}

		peps->dwEndpointType = bTransferType;
		peps->dwPacketSizeAssigned = wMaxPacketSize;
		
		// Set the Max Packet Size Register
		BYTE maxPacketBits = (BYTE) (peps->dwPacketSizeAssigned >> 3);
		WriteIndexedReg(pContext, dwEndpoint, MAX_PKT_SIZE_REG_OFFSET, 
			maxPacketBits); 

		UfnPdd_ClearEndpointStall(pvPddContext,dwEndpoint);

		// Clear outstanding interrupts
		ClearEndpointInterrupt(pContext, dwEndpoint);
	}
	
	peps->fInitialized = TRUE;
	FUNCTION_LEAVE_MSG();

	return ERROR_SUCCESS;
}


// Deinitialize an endpoint.
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);

	// Clear endpoint interrupts
	ClearEndpointInterrupt(pContext, dwEndpoint);

	peps->fInitialized = FALSE;
	UNLOCK_ENDPOINT(peps);

	D

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -