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

📄 ser_card.c

📁 wince下的串口驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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.

Module Name:  

ser_card.c

Abstract:  

Holds implementation of pcmcia serial driver interface.  This serial PDD
makes use of the ser16550 library to do most of the work.

Functions:


Notes: 


--*/
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <tchar.h>
#include <ceddk.h>

#include <cardserv.h>
#include <sockserv.h>
#include <tuple.h>

#include <serhw.h>
#include <ser16550.h>
#include <hw16550.h>
#include <ser_card.h>
#include <serdbg.h>
#include <devload.h>

#include <pcmfuncs.h>

#define MAX_TUPLES 2048
#define BASE_EVENT_MASK 0x02FF  // all of them.

// Declare table of function pointers for PCMCIA.DLL
DECLARE_CARDSERVICES_TABLE;

VOID
SerialEventHandler(
                  PVOID pMddHead
                  );

BOOL
InitCardServices(VOID)
{
    return (!!InitCardServicesTable());
}

//
// FindComConfig - Look in the parsed CISTPL_CFTABLE_ENTRY list for a valid
// COM port I/O range.
//
// If a valid COM port configuration is found, return the pertinent information
// in pConfigIndex, pIOAddress and pIOLen and return TRUE.
//
// Return FALSE if the PC card doesn't look like a COM device.
//
BOOL
FindComConfig(
             CARD_SOCKET_HANDLE hSock,
             PUCHAR pConfigIndex,
             PUINT pIOAddress,
             PUINT pIOLen,
             PUINT pVcc,
             CARD_WINDOW_HANDLE hWindow,
             PVOID *pCardIOWin,
             UINT32 *pIO_Granularity
             )
{
    UCHAR CFBuf[1024];
    PPARSED_CFTABLE pCf = (PPARSED_CFTABLE)CFBuf;
    UINT dataLen, r, s, i, j;
    STATUS status;
    //
    // Cause the search to be done in reverse COMn: order to minimize conflicts
    // with built in COM ports on CEPC.
    //
    DWORD ComRanges[4] = {0x2e8, 0x3e8, 0x2f8, 0x3f8};
    DWORD VccRanges[2] = {33, 50};

    //    
    // Get the list of parsed CISTPL_CFTABLE_ENTRYs for this PC card
    //
    dataLen = sizeof( CFBuf )/sizeof(PARSED_CFTABLE);    
    status = CallCardServices(CardGetParsedTuple)( hSock,
                                                   CISTPL_CFTABLE_ENTRY,
                                                   (PVOID) pCf,
                                                   (PUINT) &dataLen );

    if ( status ) {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("SerCard : CardGetParsedTuple returned %d\n"),
                   status) );
        return (FALSE);
    }
    DEBUGMSG (ZONE_INIT | ZONE_ERROR,
              (TEXT("SerCard: CardGetParsedTuple : %d entries\n"),
               dataLen));

#ifdef DEBUG  // For debug loads, dump info about card
    DEBUGMSG (ZONE_INIT, (TEXT("\r\nSerCard : Device Configuration\r\n")) );
    for ( i=0; i<dataLen; i++, pCf++ ) {
        DEBUGMSG (ZONE_INIT, (TEXT("\tConfigIndex = 0x%x (%d entries)\r\n"),
                              pCf->ConfigIndex, pCf->NumIOEntries));
        for ( j = 0; j < pCf->NumIOEntries; j++ ) {
            DEBUGMSG (ZONE_INIT, (TEXT("\t\tRange %d at 0x%x (%d bytes)\r\n"),
                                  j+1, pCf->IOBase[j], pCf->IOLength[j]));
        }
    }
#endif

    // Now lets look for a config we can use
    for (s=0; s < 2; s++) {
        for (r=0; r < 4; r++) {
            for ( i=0, pCf=(PPARSED_CFTABLE)CFBuf; i<dataLen; i++, pCf++ ) {
                for ( j = 0; j < pCf->NumIOEntries; j++ ) {
                    if (s == 0) {
                        if ((!(pCf->VccDescr.ValidMask & PWR_AVAIL_NOMINALV) ||
                             pCf->VccDescr.NominalV < 30 || pCf->VccDescr.NominalV > 33) &&
                            (!(pCf->VccDescr.ValidMask & PWR_AVAIL_MINV) ||
                             pCf->VccDescr.MinV < 30 || pCf->VccDescr.MinV > 33))
                            continue;
                    }

                    if (pCardIOWin != NULL) {
                        *pCardIOWin = CallCardServices(CardMapWindow) ( hWindow, pCf->IOBase[j], pCf->IOLength[j] + 1, pIO_Granularity );
                        if (*pCardIOWin == NULL)
                            continue;
                    }

                    if ((pCf->IOLength[j] >= 7) && ( (pCf->IOBase[j] == ComRanges[r]))) {
                        // OK, we found a valid entry
                        *pConfigIndex = pCf->ConfigIndex;
                        *pIOAddress = pCf->IOBase[j];
                        *pIOLen = pCf->IOLength[j] + 1;
                        *pVcc = (s == 0) ? 33 : 50;
                        DEBUGMSG (ZONE_INIT, (TEXT("SerCard: FindComConfig returning TRUE\r\n")));
                        return (TRUE);
                    }
                }
            }
        }
    }
    DEBUGMSG (ZONE_INIT, (TEXT("SerCard: FindComConfig returning FALSE\r\n")));
    return (FALSE);   // not a COM type PC card
}   // FindComConfig


//
// DetectModem - called by device.exe to allow this driver to detect modem cards
//
// Return is NULL for an undetected card or else it is the name of the device key
// under HLM\Drivers\PCMCIA for this driver (i.e. "Modem")
//
// Note:
//  This function looks for the card type PCCARD_TYPE_SERIAL and for a valid COM
//  port configuration (7 bytes at either 0x3f8, 0x2f8, 0x3e8 or 0x2e8)
//
LPTSTR
DetectModem(
           CARD_SOCKET_HANDLE hSock,
           UCHAR  DevType,
           LPTSTR DevKey,
           DWORD  DevKeyLen
           )
{
    UINT IOAddress, IOLen, Vcc;
    UCHAR ConfigIndex;

    DEBUGMSG (ZONE_INIT, (TEXT("+DetectModem %d, %s, %d\r\n"),
                          DevType, DevKey, DevKeyLen ));
    
#ifdef FORCE_MODEM
    DEBUGMSG (ZONE_INIT, (TEXT("DetectModem - Forcing Modem!!!\r\n") ));
    _tcscpy(DevKey, TEXT("Modem"));
    return (DevKey);
#else
    if ( (DevType == PCCARD_TYPE_SERIAL) ||
         (DevType == PCCARD_TYPE_UNKNOWN) ) {
        // Make sure PCMCIA.DLL is available
        if ( ! InitCardServices() )
            return (UINT32)NULL;

        if ( FindComConfig(hSock, &ConfigIndex, &IOAddress, &IOLen, &Vcc, NULL, NULL, NULL) == TRUE ) {
            _tcscpy(DevKey, TEXT("Modem"));
            if (DevType == PCCARD_TYPE_SERIAL) {
                BOOL bDevice = FALSE;
                PCARD_TUPLE_PARMS pTuple;
                PCARD_DATA_PARMS pData;
                PUCHAR tupleData;
                UCHAR buffer[sizeof(CARD_TUPLE_PARMS) + 32];
                int i;
                DWORD status;

                pTuple = (PCARD_TUPLE_PARMS) buffer;
                pData = (PCARD_DATA_PARMS) buffer;
                tupleData = (PUCHAR)pData;
                tupleData += sizeof(CARD_DATA_PARMS);

                pTuple->hSocket = hSock;
                pTuple->fAttributes = 0;         // Not interested in links
                pTuple->uDesiredTuple = 0xff;    // Interested in all tuples.
                if (CallCardServices(CardGetFirstTuple)(pTuple) == CERR_SUCCESS) {
                    for (i = 0; i < MAX_TUPLES; i++) {
                        if (pTuple->uTupleCode == CISTPL_FUNCID) {
                            pData->uBufLen = sizeof(buffer) - sizeof(CARD_TUPLE_PARMS);
                            pData->uTupleOffset = 0;
                            if (CallCardServices(CardGetTupleData)(pData) != CERR_SUCCESS) {
                                break;
                            }
                            if (*tupleData == DevType)
                                bDevice = TRUE;
                            else if (bDevice) {
                                _tcscpy(DevKey, TEXT("Serial"));
                                break;
                            }
                        } else if (bDevice && pTuple->uTupleCode == CISTPL_FUNCE) {
                            pData->uBufLen = sizeof(buffer) - sizeof(CARD_TUPLE_PARMS);
                            pData->uTupleOffset = 0;
                            if (CallCardServices(CardGetTupleData)(pData) != CERR_SUCCESS ||
                                *tupleData != 0)
                                break;
                        }
                        status = CallCardServices(CardGetNextTuple)(pTuple);
                        if (status == CERR_NO_MORE_ITEMS) {
                            _tcscpy(DevKey, TEXT("Serial"));
                        }
                        if (status != CERR_SUCCESS)
                            break;
                    }
                }
            }

            DEBUGMSG (ZONE_INIT, (TEXT("-DetectModem - Found Config %d, Addr x%X (%s)\r\n"),
                                  ConfigIndex, IOAddress, DevKey ));
            return (DevKey);
        }
        DEBUGMSG (ZONE_INIT, (TEXT("-DetectModem - No Config found!!!\r\n") ));    
    }
    return (NULL);
#endif
}   // DetectModem


// Miscellaneous internal routines.

STATUS CallBackFn(
                 CARD_EVENT EventCode,
                 CARD_SOCKET_HANDLE hSocket,
                 PCARD_EVENT_PARMS pParms
                 )
{
    PSER_CARD_INFO   pHWHead;
    CARD_STATUS CardStatus;             // For CardGetStatus
    STATUS status = CERR_SUCCESS;
    STATUS ret = CERR_SUCCESS;

    //
    // Make sure everything comes in as expected.
    //
    if ( pParms == NULL ) {
        DEBUGMSG (ZONE_THREAD, (TEXT("CLNTX:CallBackFn - pParms == NULL!!!\r\n")));
        goto CBF_END;
    }

    pHWHead = (PSER_CARD_INFO)pParms->uClientData;

    DEBUGMSG (ZONE_THREAD, (TEXT("CallBackFn 0x%X - 0x%X\r\n"),
                            pParms->uClientData, EventCode ));

    switch ( EventCode ) {
    case CE_CARD_REMOVAL:
        //
        // Determine whether this is an artificial removal notice.
        //
        CardStatus.hSocket = pHWHead->hCardSock;
        ret = CallCardServices(CardGetStatus)(&CardStatus);
        if ( ret ) {
            // unexpected state.  Show error message
            DEBUGMSG (ZONE_THREAD | ZONE_ERROR, (TEXT("CallBackFn - CardGetStatus returned %d\r\n"),
                                                 ret));
        } else {
            if ( ! (CardStatus.fCardState & EVENT_MASK_CARD_DETECT) ) {
                DEBUGMSG (ZONE_THREAD, (TEXT("CallBackFn - removal notice\r\n")));
            }
        }
        break;

    default:
        // We didn't ask for any other events.  we should never get here.
        break;
    }

    CBF_END:
    return (status);
}   // CallBackFn


BOOL
GetCardHandle( ULONG Identifier,
               CARD_SOCKET_HANDLE *pCardSock
             )
{
    CARD_SOCKET_HANDLE hCardSock;
    DWORD status;
    DWORD ValType;
    DWORD ValLen;
    HKEY ActiveKey;

    status = RegOpenKeyEx(
                         HKEY_LOCAL_MACHINE,
                         (LPCWSTR)Identifier,
                         0,
                         0,
                         &ActiveKey);
    if ( status ) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                 (TEXT("SC_INIT - RegOpenKeyEx returned %d!!!\r\n"),
                  status));
        return (FALSE);
    }

    ValLen = sizeof(hCardSock);
    status = RegQueryValueEx(
                            ActiveKey,
                            DEVLOAD_SOCKET_VALNAME,
                            NULL,
                            &ValType,
                            (PUCHAR)&hCardSock,
                            &ValLen);
    if ( status != ERROR_SUCCESS ) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                 (TEXT("SC_INIT: RegQueryValueEx(%s) returned %d\r\n"),
                  DEVLOAD_SOCKET_VALNAME, status));
        //
        // We can't do PCMCIA without our handle
        //
        RegCloseKey(ActiveKey);        
        return (FALSE);
    }

⌨️ 快捷键说明

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