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

📄 mdd.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++
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-1998  Microsoft Corporation

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 <ceddk.h>
#include <types.h>
#include <memory.h>
#include <nkintr.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"
/****************************************************************************
 * Modification done by Maneesh Gupta
 *
 * Included platform.h & cc.h
 ****************************************************************************/
#include "cc.h"
/****************************************************************************
 * End of Modification done by Maneesh Gupta
 ****************************************************************************/

/* 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))

/****************************************************************************
 * Modification done by Maneesh Gupta
 *
 * Changes for ASPEN / BIGSUR
 *
 * 1. The base address is hard coded instead of reading from the
 * registry. This is because the Companion Chip is present at a constant
 * location. There is no need to read the base address from registry.
 *
 * 2. On HD64465, the parallel port registers are present at alternate
 * bye addresses while on normal PC they are present at consecutive
 * addresses.
 * So all the register offsets get multiplied by two.
 *
 * So For ASPEN platform, a new global variable dwPrinterRegMultiplier is
 * introduced. This would be set to 2, to take care of the above mentioned
 * fact
 * Multiplier used to access the printer registers.
 ****************************************************************************/
unsigned dwPrinterRegMultiplier;
unsigned VirtualAddress(unsigned StartAddress, unsigned Length); 
/****************************************************************************
 * End of Modification done by Maneesh Gupta
 ****************************************************************************/

// Define some internally used functions
BOOL LPT_Close(PPortInformation    pPortObj);
BOOL LPT_Deinit(PPortInformation pPortObj);
int Get_DJ400_Dev_Status(unsigned long port_base, unsigned char *buffer);

/*
 @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;
     }
	memset(pPortObj,0,sizeof(PortInformation)); //Initial to zero
    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
    )
{
    HKEY hConfig;
    DWORD dwData;
    DWORD dwSize;
    DWORD dwType;
    DWORD dwRet;

     *lpdwIoBase= LPT_DEFAULT_IOBASE;   // setup to default values
     *lpdwIoLen=  LPT_DEFAULT_IOLEN;

    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("PCMCIA:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
            IOLEN_VALUE_NAME, dwRet));
        goto grc_fail;
    }
    *lpdwIoLen = dwData;

    return ERROR_SUCCESS;

grc_fail:
    RegCloseKey(hConfig);
    return dwRet;
}   // GetRegistryConfig




/*
 @doc EXTERNAL
 @func         HANDLE | LPT_Open | Parallel port driver initialization.
 *   Description: This routine must be called by the user to open the
 *   parallel device. The HANDLE returned must be used by the application in
 *   all subsequent calls to the parallel driver. This routine starts the thread
 *   which handles the parallel events.
 *   Exported to users.
 *
 @rdesc This routine returns a HANDLE representing the device.
 */
PPortInformation
LPT_Open(
     PPortInformation    pPortObj, // @parm Handle returned by LPT_Init.
     DWORD     AccessCode,         // @parm access code.
     DWORD     ShareMode      // @parm share mode - Not used in this driver.
     )
{
    char *Name;
    DWORD IoBase;
    DWORD IoLen;
    DWORD dwRet;

    DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: entry\r\n")));
    Name= LPT_DEFAULT_NAME;


/****************************************************************************
 * Modification done by Maneesh Gupta
 *
 * For Aspen, do a Virtual Allocation here, instead of reading 
 * any data from the registry.
 *
 ****************************************************************************/
    if ((dwRet = GetRegistryConfig(PARALLEL_DRIVER_KEY, &IoBase, &IoLen))
        != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_IO,
            (TEXT("LPT_Open GetRegistryConfig failed %d\r\n"),
            dwRet));
		return NULL;
    }
//	IoBase = CC_PAR_BASE_REG;
//	IoLen = 12;
	if(!(IoBase = VirtualAddress(IoBase, IoLen))) {
		ERRORMSG(1, (TEXT("Could not Allocate VirtualAddress (0x%x) to Parallel Base Register.\r\n"), IoBase));
		dwRet=0; //Just toremove a compiler warning
		return NULL;
	}

/****************************************************************************
 * End of Modification done by Maneesh Gupta
 ****************************************************************************/

    DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: Portname = %a IoBase= %Xh IoLen= %d\r\n"),Name,IoBase,IoLen));
    pPortObj->ulBase = IoBase;
    memcpy(pPortObj->Name, Name, 4);
    pPortObj->dwPortSharing = 0;
    pPortObj->blPortOpen = FALSE;
    pPortObj->pPortData.LossByte = 0;
    pPortObj->dwPortSharing |= PORT_IN_USE;
    pPortObj->wHost = HOST_NO_ECP;
    pPortObj->bCurrentMode = LPT_MODE;
    pPortObj->bCurrentPhase = FORWARD_IDLE;
    pPortObj->bFrdProtocol = ID_LPT;
    pPortObj->pPortData.PDLength = (WORD)sizeof(PortData);
    pPortObj->pPortData.PDVersion = 0x100;
    pPortObj->hOEvent = 0;
    pPortObj->hIEvent = 0;
    pPortObj->blInTransfer = FALSE;
    // turn off all notification marks
    pPortObj->dwNotifyFlags = 0;
    pPortObj->TxLO = 0xFFFFFFFF;
    pPortObj->RxHI = 0xFFFFFFFF;

/****************************************************************************
 * Modification done by Maneesh Gupta
 *
 * Assignment of dwPrinterRegMultiplier for Different platform.
 ****************************************************************************/
	dwPrinterRegMultiplier = 2;
/****************************************************************************
 * End of Modification done by Maneesh Gupta
 ****************************************************************************/
     // Init CommTimeouts.
     pPortObj->CommTimeouts.ReadIntervalTimeout = READ_TIMEOUT;
     pPortObj->CommTimeouts.ReadTotalTimeoutMultiplier =
          READ_TIMEOUT_MULTIPLIER;
     pPortObj->CommTimeouts.ReadTotalTimeoutConstant =
          READ_TIMEOUT_CONSTANT;
     pPortObj->CommTimeouts.WriteTotalTimeoutMultiplier=    WRITE_TIMEOUT_MULTIPLIER;
     pPortObj->CommTimeouts.WriteTotalTimeoutConstant  =    WRITE_TIMEOUT_CONSTANT;

    // Negotiate w/o requesting device ID string
     DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: Calling NegotiateChannel...\r\n")));
    NegotiateChannel(pPortObj,FALSE);
    if (pPortObj->bCurrentMode == NIBBLE_MODE)
    {
          DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: In NIBBLE_MODE calling TerminateChannel...\r\n")));
        // If we are in nibble mode return to the forward direction

⌨️ 快捷键说明

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