mdd.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,337 行 · 第 1/4 页
C
1,337 行
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
Module Name:
mdd.c
Abstract:
This file contains the parallel mdd (model device driver) code.
Functions:
LPT_Init
LPT_Open
LPT_Close
LPT_Deinit
LPT_Read
LPT_Write
LPT_Seek
LPT_PowerUp
LPT_PowerDown
LPT_IOControl
ParallelDllEntry
Notes:
--*/
#include <windows.h>
#include <wdm.h>
#include <types.h>
#include <memory.h>
#include <nkintr.h>
//#include <oalintr.h>
#include <pegdpar.h>
#include "parpriv.h"
#include "pardbg.h"
#include "1284comm.h"
#include "tmtick.h"
#include "comdef.h"
#include "1284neg.h"
#include "lptio.h"
#include "ecpreg.h"
#include "findecp.h"
/* Debug Zones.
*/
#ifdef DEBUG
#define DBG_INIT 0x0001
#define DBG_OPEN 0x0002
#define DBG_READ 0x0004
#define DBG_WRITE 0x0008
#define DBG_CLOSE 0x0010
#define DBG_IOCTL 0x0020
#define DBG_THREAD 0x0040
#define DBG_EVENTS 0x0080
#define DBG_CRITSEC 0x0100
#define DBG_IO 0x0200
#define DBG_MAXIO 0x0400
#define DBG_UNUSED2 0x0800
#define DBG_ALLOC 0x1000
#define DBG_FUNCTION 0x2000
#define DBG_WARNING 0x4000
#define DBG_ERROR 0x8000
DBGPARAM dpCurSettings = {
TEXT("Parallel"), {
TEXT("Init"),TEXT("Open"),TEXT("Read"),TEXT("Write"),
TEXT("Close"),TEXT("Ioctl"),TEXT("Thread"),TEXT("Events"),
TEXT("CritSec"),TEXT("IO"),TEXT("MaxIO"),TEXT("Unused2"),
TEXT("Alloc"),TEXT("Function"),TEXT("Warning"),TEXT("Error") },
DBG_WARNING | DBG_ERROR
};
#endif
#define swapbyte(wA) (WORD)(((wA>>8) & 0x00FF) | (wA<<8))
// Define some internally used functions
BOOL LPT_Close(PPortInformation pPortObj);
BOOL LPT_Deinit(PPortInformation pPortObj);
INT Get_DJ400_Dev_Status(ULONG port_base, PUCHAR buffer);
// NOTENOTE: for x86 platforms
//
// CEPC device drivers should get their IRQ number from the registry and use
// MapIrq2SysIntr to get the appropriate SYSINTR_* number to use.
#ifdef x86
_inline
DWORD
MapIrq2SysIntr(DWORD _Irq)
{
if( _Irq<=15 )
return ( SYSINTR_FIRMWARE + _Irq );
else
return (0xffffffff);
}
#endif
/*
@doc INTERNAL
@func BOOL | ParallelDllEntry | Process attach/detach api.
*
@rdesc The return is a BOOL, representing success (TRUE) or failure (FALSE).
*/
BOOL
ParallelDllEntry(
HINSTANCE hinstDll, /*@parm Instance pointer. */
DWORD dwReason, /*@parm Reason routine is called. */
LPVOID lpReserved /*@parm system parameter. */
)
{
DEBUGMSG(ZONE_IO,(TEXT("ParallelDllEntry: entry\r\n")));
if ( dwReason == DLL_PROCESS_ATTACH ) {
DEBUGREGISTER(hinstDll);
DEBUGMSG (ZONE_INIT, (TEXT("parallel port process attach\r\n")));
}
if ( dwReason == DLL_PROCESS_DETACH ) {
DEBUGMSG (ZONE_INIT, (TEXT("parallel port process detach called\r\n")));
}
return TRUE;
}
// ****************************************************************
//
// @doc EXTERNAL
// @func HANDLE | LPT_INIT | Parallel device initialization.
//
// @parm ULONG | Identifier | Port identifier. The device loader
// passes in the registry key that contains information
// about the active device.
//
// @remark This routine is called at device load time in order
// to perform any initialization. Typically the init
// routine does as little as possible, postponing memory
// allocation and device power-on to Open time.
//
// @rdesc Returns a pointer to the serial head which is passed into
// the LPT_OPEN and LPT_DEINIT entry points as a device handle.
//
PPortInformation
LPT_Init(
ULONG Identifier
)
{
PPortInformation pPortObj;
DEBUGMSG(ZONE_IO,(TEXT("[LPT_Init]: entry.\r\n")));
//allocate new data buffer
pPortObj = (PPortInformation)LocalAlloc(LPTR,(ULONG)sizeof(PortInformation));
if (!pPortObj) {
DEBUGMSG(ZONE_ERROR,(TEXT("[LPT_Init]: ERROR: Unable to allocate PortInformation buffer.\r\n")));
return 0;
}
return pPortObj;
}
// Miscellaneous internal routines.
PUCHAR
static
Par_InternalMapRegisterAddresses(
ULONG HWAddress,
ULONG Size
)
{
PUCHAR ioPortBase;
ULONG inIoSpace = 1;
PHYSICAL_ADDRESS ioPhysicalBase = { HWAddress, 0 };
DEBUGMSG(ZONE_FUNCTION,
(TEXT("Par_InternalMapRegisterAddresses : HalTranslateBusAddress\r\n")));
if (HalTranslateBusAddress(Isa, 0, ioPhysicalBase, &inIoSpace,
&ioPhysicalBase))
{
DEBUGMSG(ZONE_INIT,
(TEXT("Par_InternalMapRegisterAddresses : HalTranslateBusAddress - OK\r\n")));
if (!inIoSpace)
{
DEBUGMSG(ZONE_INIT,
(TEXT("Par_InternalMapRegisterAddresses : ! IO Space\r\n")));
if ((ioPortBase = (PUCHAR)MmMapIoSpace(ioPhysicalBase,
Size, FALSE)) == NULL)
{
// We may as well not continue
DEBUGMSG(ZONE_INIT | ZONE_ERROR,
(TEXT("Error mapping I/O Ports\r\n")));
return(NULL);
}
}
else
{
DEBUGMSG(ZONE_INIT,
(TEXT("Par_InternalMapRegisterAddresses : IO Space\r\n")));
ioPortBase = (PUCHAR)ioPhysicalBase.LowPart;
}
}
else
{
DEBUGMSG(ZONE_INIT | ZONE_ERROR,
(TEXT("Error translating I/O Ports.\r\n")));
return(NULL);
}
DEBUGMSG(ZONE_FUNCTION,
(TEXT("Par_InternalMapRegisterAddresses : %d\r\n"),
ioPortBase ));
return ioPortBase;
}
//
// Function to get the I/O port range from the registry
//
// NOTE: lpRegPath is assumed to be under HKEY_LOCAL_MACHINE
//
// Returns ERROR_SUCCESS on success or a Win32 error code on failure
//
DWORD
GetRegistryConfig(
LPWSTR lpRegPath,
DWORD * lpdwIoBase,
DWORD * lpdwIoLen,
UINT * lpuIrq,
ULONG * lpulTimeout,
BOOL * lpfEcpEnable,
UINT * lpcTimeouts
)
{
HKEY hConfig;
DWORD dwData;
DWORD dwSize;
DWORD dwType;
DWORD dwRet;
*lpdwIoBase = LPT_DEFAULT_IOBASE; // setup to default values
*lpdwIoLen = LPT_DEFAULT_IOLEN;
*lpuIrq = LPT_DEFAULT_IRQ;
*lpulTimeout = ECP_HARD_CODED_TIMEOUT;
*lpfEcpEnable = TRUE;
*lpcTimeouts = ECP_MAX_CONSEC_TIMEOUTS;
dwRet = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
lpRegPath,
0,
0,
&hConfig);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT,
(TEXT("PARALLEL:GetRegistryConfig RegOpenKeyEx(%s) failed %d\r\n"),
lpRegPath, dwRet));
return dwRet;
}
dwSize = sizeof(DWORD);
dwRet = RegQueryValueEx(
hConfig,
IOBASE_VALUE_NAME,
0,
&dwType,
(PUCHAR)&dwData,
&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT,
(TEXT("PARALLEL:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
IOBASE_VALUE_NAME, dwRet));
goto grc_fail;
}
*lpdwIoBase = dwData;
dwSize = sizeof(DWORD);
dwRet = RegQueryValueEx(
hConfig,
IOLEN_VALUE_NAME,
0,
&dwType,
(PUCHAR)&dwData,
&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT,
(TEXT("PARALLEL:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
IOLEN_VALUE_NAME, dwRet));
goto grc_fail;
}
*lpdwIoLen = dwData;
/*
"ECPTimeoutMS"=dword:7D0
"ECPNumTimeouts"=dword:2
"ECPIRQ"=dword:5
"ECPEnable"=dword:1
*/
dwSize = sizeof(DWORD);
dwRet = RegQueryValueEx(
hConfig,
TEXT("ECPTimeoutMS"),
0,
&dwType,
(PUCHAR)&dwData,
&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT,
(TEXT("PARALLEL:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
L"ECPTimeoutMS", dwRet));
goto grc_fail;
}
*lpulTimeout = dwData;
dwSize = sizeof(DWORD);
dwRet = RegQueryValueEx(
hConfig,
TEXT("ECPNumTimeouts"),
0,
&dwType,
(PUCHAR)&dwData,
&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT,
(TEXT("PARALLEL:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
L"ECPNumTimeouts", dwRet));
goto grc_fail;
}
*lpcTimeouts = dwData;
dwSize = sizeof(DWORD);
dwRet = RegQueryValueEx(
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?