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

📄 xrpci.c

📁 wince 5.0下 实现PCI8串口卡驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////
//(c) 2005 EXAR Corporation 
//All Rights Reserved.
//
//Exar Corporation ("Exar") hereby grants the User of this Exar 
//product-specific XR17C15x Windows CE.Net Device Driver (hereinafter 
//referred to as "Driver") a non-exclusive, nontransferable license 
//to use the Driver in accordance with the term set forth below.  
//Before using the Driver, the User should read the following use 
//restrictions.  If the User does not accept these terms, the Driver 
//should not be used or downloaded.
//The User is granted this limited license to use this Driver for 
//User's end product that includes the Exar XR17C158/XR17D158 Octal UART PCI 
//device, XR17C154/XR17D154 Quad UART PCI Device, and XR17C152/XR17D152 Dual UART 
//PCI Device and is not granted rights to sell, loan, rent, lease or 
//license the Driver, in whole or in part, or in modified form to anyone 
//other than User.  User may modify the Driver to suit its specific 
//applications but rights to derivative works and such modifications 
//shall belong to Exar.
//
//The Driver is provided on an "AS IS" basis and Exar makes absolutely 
//no warranty with respect to performance or the information contained 
//therein.  EXAR DISCLAIMS AND USER WAIVES ALL WARRANTIES, EXPRESS OR 
//IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 
//PARTICULAR PURPOSE.  The entire risk as to Driver quality and 
//performance is with the User.  ACCORDINGLY, IN NO EVENT SHALL EXAR 
//BE LIABLE FOR ANY DAMAGES, WHETHER IN CONTRACT OR TORT, INCLUDING 
//ANY LOST PROFITS OR OTHER INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, OR 
//PUNITIVE DAMAGES ARISING OUT OF THE USE OR APPLICATION OF THE DRIVER.  
//Further, Exar reserves the right to make changes tot eh Driver without 
//notice to improve reliability, function or design.  Exar does not 
//convey any license under patent rights or any other intellectual 
//property rights, including those of third parties.
//
//Exar is not obligated to provide maintenance or support for the Driver. 
//
////////////////////////////////////////////////////////
/*++


Module Name:

    xrpci.c

Abstract:

    Exar PCI UART card enumerator device driver

Notes:

	This driver loads to any of the Exar PCI cards (0x158/154/152 PIDs) and 
	enumerates each port on the card with the proper Memory and interrupt
	resources. This can be considered as a Bus Driver for the card.

--*/

#include <windows.h>
#include <devload.h>
#include <pm.h>
#include <nkintr.h>
#include <winioctl.h>
#include <ddkreg.h>

#include "xrpci.h"

#ifdef DEBUG

#define	DEBUGMASK(bit)		(1 << (bit))

#define	MASK_ERROR			DEBUGMASK(0)
#define	MASK_WARN			DEBUGMASK(1)
#define	MASK_INIT			DEBUGMASK(2)
#define	MASK_FUNCTION		DEBUGMASK(3)
#define	MASK_IOCTL			DEBUGMASK(4)
#define	MASK_DEVICE			DEBUGMASK(5)
#define	MASK_ACTIVITY		DEBUGMASK(6)

DBGPARAM dpCurSettings = {
    _T("PMSampleDev"), 
	{
		_T("Errors"), _T("Warnings"), _T("Init"), _T("Function"), 
		_T("Ioctl"), _T("Device"), _T("Activity"), _T(""),
		_T(""),_T(""),_T(""),_T(""),
		_T(""),_T(""),_T(""),_T("") 
	},
    MASK_ERROR | MASK_WARN | MASK_INIT | MASK_IOCTL | MASK_DEVICE
}; 

#define	ZONE_ERROR			DEBUGZONE(0)
#define	ZONE_WARN			DEBUGZONE(1)
#define	ZONE_INIT			DEBUGZONE(2)
#define	ZONE_FUNCTION		DEBUGZONE(3)
#define	ZONE_IOCTL			DEBUGZONE(4)
#define	ZONE_DEVICE			DEBUGZONE(5)
#define	ZONE_ACTIVITY		DEBUGZONE(6)

#endif


DWORD
XRP_Init(
    PVOID Context
    )
{
	DWORD dwStatus, dwType, dwSize;
	HKEY hkDevice;
	TCHAR szName[16];
	UCHAR i, dwPorts;

	HKEY hk;
	DWORD dwDisp, dwMemBase, dwSysIntr;
	WCHAR szLine[MAX_PATH];
	DWORD bMemLength;
	DWORD dwRegStride;

	DWORD dwPortInstanceOnChip;
			
	PXRPCI_INFO   pHWHead;

    UNREFERENCED_PARAMETER(Context);

    DEBUGMSG(ZONE_INIT, (_T("XRP_Init: context %s\n"), Context));

	// get our activation information
	dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) Context, 0, 0, &hkDevice);
	if(dwStatus != ERROR_SUCCESS) 
	{
		DEBUGMSG(ZONE_ERROR, (_T("XRP_Init: OpenDeviceKey('%s') failed %u\r\n"), Context, dwStatus));
		return 0;
	}
	
	dwSize = sizeof(szName);
	dwStatus = RegQueryValueEx(hkDevice, DEVLOAD_DEVNAME_VALNAME, NULL, &dwType, (LPBYTE) szName, &dwSize);
	if(dwStatus != ERROR_SUCCESS || dwType != DEVLOAD_DEVNAME_VALTYPE) 
	{
		DEBUGMSG(ZONE_ERROR, (_T("XRP_Init: RegQueryValueEx('%s', '%s') failed %u\r\n"),
			Context, DEVLOAD_DEVNAME_VALNAME, dwStatus));
		RegCloseKey(hkDevice);
		return 0;
	}
	DEBUGMSG(ZONE_INIT, (_T("XRP_Init: device name is '%s'\r\n"), szName));
	RegCloseKey(hkDevice);

	// Get the PCI data
	
	// Allocate for our main data structure and one of it's fields.
	pHWHead = (PXRPCI_INFO)LocalAlloc( LMEM_ZEROINIT|LMEM_FIXED ,
									 sizeof(XRPCI_INFO) );
	if ( !pHWHead )
		return( 0 );

	if ( ! XRPCI_GetRegistryData(pHWHead, (LPCTSTR)Context) ) 
	{
		DEBUGMSG (ZONE_INIT|ZONE_ERROR,
				  (TEXT("XRPCI_GetRegistryData - Unable to read registry data.  Failing Init !!! \r\n")));
		return 0;
	}
	
	//
	// populate the ports based on the the Device ID
	//
	dwPorts = (UCHAR)(pHWHead->dwDeviceId & 0x0F);
	
	//
	// Memory space for each port 
	//
	bMemLength = 0x200;
	
	//
	// UART register stride (default = 1 byte).
	//
	dwRegStride = 1;
	
	DEBUGMSG(1, (_T("dwPorts = %d  \r\n"), dwPorts));

	for (i = 0; i < dwPorts; i++)	
	{
		//
		//we are ready for loading drivers for the ports, so update the registry
		//
		dwMemBase = pHWHead->dwMemBase + (i * 0x200);
		if( !KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &pHWHead->dwIrq, sizeof(pHWHead->dwIrq), &dwSysIntr, sizeof(dwSysIntr), NULL) )
		{
			//error just use the default System Interrupt ; This should not happen though...
			dwSysIntr = pHWHead->dwSysIntr;
		}

		wsprintf (szLine, L"Drivers\\BuiltIn\\PCI\\Template\\xrserial%d", i);
		if (ERROR_SUCCESS == RegCreateKeyEx (HKEY_LOCAL_MACHINE, szLine, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, &dwDisp)) 
		{
			RegSetValueEx (hk, L"SysInterrupt", 0, REG_DWORD, (BYTE *)&dwSysIntr, sizeof(DWORD));
			RegSetValueEx (hk, L"IRQ", 0, REG_DWORD, (BYTE *)&pHWHead->dwIrq, sizeof(DWORD));
			RegSetValueEx (hk, L"DevIndex", 0, REG_DWORD, (BYTE *)&pHWHead->dwDevIndex, sizeof(DWORD));
			RegSetValueEx (hk, L"InterfaceType", 0, REG_DWORD, (BYTE *)&pHWHead->dwInterfaceType, sizeof(DWORD));
			RegSetValueEx (hk, L"BusNumber", 0, REG_DWORD, (BYTE *)&pHWHead->dwBusNumber, sizeof(DWORD));
			RegSetValueEx (hk, L"MemBase", 0, REG_DWORD, (BYTE *)&dwMemBase, sizeof(DWORD));
			RegSetValueEx (hk, L"MemLength", 0, REG_DWORD, (BYTE*)&bMemLength, sizeof(DWORD));
			RegSetValueEx (hk, L"RegStride", 0, REG_DWORD, (BYTE *)&dwRegStride, sizeof(DWORD));
			RegSetValueEx (hk, L"IsrDll", 0, REG_SZ, (BYTE *)L"xrisr.dll", sizeof(L"xrisr.dll"));
			RegSetValueEx (hk, L"IsrHandler", 0, REG_SZ, (BYTE *)L"ISRHandler", sizeof(L"ISRHandler"));
			
			dwPortInstanceOnChip = i;
			RegSetValueEx (hk, L"PortInstanceOnChip", 0, REG_DWORD, (BYTE*)&dwPortInstanceOnChip, sizeof(DWORD));

			RegCloseKey (hk);
		}
		else
		{
			DEBUGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("Failed to set registry values; \r\n")));       
		}		
		

		//
		// Everything is set for the port driver, now Activate(Register) it.
		//
		pHWHead->hDevice[i] = ActivateDevice(szLine, 0);
		if (pHWHead->hDevice[i])
		{
			DEBUGMSG (ZONE_INIT, (TEXT("ActivateDeviceEx success !!! \r\n")));			
		}
		else
		{
			DEBUGMSG (ZONE_INIT|ZONE_ERROR, (TEXT("ActivateDeviceEx failure !!! \r\n")));
		}
	}

	pHWHead->dwTotalPortsActivated = i;
	
    DEBUGMSG(ZONE_INIT, (_T("XRP_Init: returning 0x%08x\r\n"), pHWHead));
	DEBUGMSG(1, (_T("XRP_Init: returning 0x%08x\r\n"), pHWHead));
	return ((DWORD)pHWHead); // return pHWHead. as this can be used in DeInit for Deactivating the port drivers
}


/*
 @doc EXTERNAL
 @func	BOOL | XRP_Deinit | De-initialize serial card.
 @parm DWORD | pHWHead | Context pointer returned from XRP_Init
 *
 @rdesc None.
 */
BOOL
XRP_Deinit(
    DWORD dwContext
    )
{
	PXRPCI_INFO   pHWHead = (PXRPCI_INFO)dwContext;
	DWORD i;

	if ( !pHWHead ) 
	{
        /* Can't do much without this */
        DEBUGMSG (ZONE_INIT|ZONE_ERROR,
                  (TEXT("XRP_Deinit can't find pHWHead\r\n")));
        SetLastError(ERROR_INVALID_HANDLE);
        return(FALSE);
    }

	if (pHWHead->dwTotalPortsActivated)
	{
		for(i = 0; i < pHWHead->dwTotalPortsActivated; i++)
		{
			DeactivateDevice(pHWHead->hDevice[i]);
		}
	}

	LocalFree(pHWHead);
    return TRUE;
}


BOOL
XRP_IOControl(
    DWORD  dwContext,
    DWORD  Ioctl,
    PUCHAR pInBuf,
    DWORD  InBufLen, 
    PUCHAR pOutBuf,
    DWORD  OutBufLen,
    PDWORD pdwBytesTransferred
   )
{
	//
	// we don't support any IOCTLs at this point

⌨️ 快捷键说明

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