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 + -
显示快捷键?