📄 xrpci.c
字号:
////////////////////////////////////////
//(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 + -