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

📄 ser_card.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
/*

  Copyright(c) 1998,1999 SIC/Hitachi,Ltd.

	Module Name:

		ser_card.c

	Revision History:

		26th April 1999		Released

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

#ifdef TARGET_NT
    #include <devemul.h>
PFN_ntecards_inb pf_ntecards_inb;
PFN_ntecards_outb pf_ntecards_outb;
#endif

UCHAR __inline READ_PORT_UCHAR(PUCHAR port)
{
    UCHAR	bTemp;

    bTemp = *(volatile unsigned char * const)port;
    return bTemp;
}

VOID __inline WRITE_PORT_UCHAR(PUCHAR port, UCHAR value)
{
//  DEBUGMSG (DBG_PORT_ACCESS, (TEXT("Setting Port @ 0x%X to 0x%X\r\n"), port, value));
    *(volatile unsigned char * const)port = value;
}

#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
             )
{
    UCHAR CFBuf[1024];
    PPARSED_CFTABLE pCf = (PPARSED_CFTABLE)CFBuf;
    UINT dataLen, r, 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};

    //    
    // 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 (r=0; r < 4; r++) {
       for ( i=0, pCf=(PPARSED_CFTABLE)CFBuf; i<dataLen; i++, pCf++ ) {
           for ( j = 0; j < pCf->NumIOEntries; j++ ) {
               if ( (pCf->IOLength[j] >= 7) && ( (pCf->IOBase[j] == ComRanges[r]))) {
                   // OK, we found a valid entry
                   *pConfigIndex = pCf->ConfigIndex;
                   *pIOAddress = pCf->IOBase[j];
   #ifdef TARGET_NT
                   *pIOLen = pCf->IOLength[j] + 1;
   #else
                   *pIOLen = pCf->IOLength[j];
   #endif
                   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;
    UCHAR ConfigIndex;

    DEBUGMSG (1|ZONE_INIT, (TEXT("+DetectModem %d, %s, %d\r\n"),
                          DevType, DevKey, DevKeyLen ));
    
#ifdef FORCE_MODEM
    DEBUGMSG (1|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) == TRUE ) {
            DEBUGMSG (1|ZONE_INIT, (TEXT("-DetectModem - Found Config %d, Addr x%X\r\n"),
                                  ConfigIndex, IOAddress ));    
            _tcscpy(DevKey, TEXT("Modem"));
            return (DevKey);
        }
        DEBUGMSG (1|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 ) {
            // Hmm, this should never happen.  What do we want to do here?
            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);
    }

    DEBUGMSG(ZONE_INIT|ZONE_ERROR,
             (TEXT("SC_INIT: RegQueryValueEx(%s) Val = %d\r\n"),
              DEVLOAD_SOCKET_VALNAME, hCardSock));

    // When we finish with registry, be sure to close it
    RegCloseKey(ActiveKey);        

    // OK, we got the handle from the registry, return it
    *pCardSock = hCardSock;
    return (TRUE);
}

#define RESET_DELAY_VALNAME TEXT("ResetDelay")
#define NOSCRATCHPAD_VALNAME TEXT("NoScratchPad")

// For some cards we store special overrides in the registry.
// This routine reads them all in, or sets the default if the
// value is not in the registry.
VOID
GetRegistryData(ULONG Identifier, PSER_CARD_INFO pHWHead)
{
    HKEY ActiveKey;
    DWORD status, ValType, ValLen;
    DWORD ResetDelay = 0;
    DWORD NoScratchPad = 0;
    TCHAR IdStr[300]; // Should be a defined constant??

    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCWSTR)Identifier,

⌨️ 快捷键说明

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