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

📄 wendyser.c

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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.
Copyright (c) 1997  Socket Communications, Inc.

Module Name:  

    wendyser.c

Abstract:  

Holds implementation of pcmcia serial driver interface for the WENDY CF+ BlueTooth
card (Wendy).  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 <cardserv.h>
#include <sockserv.h>
#include <tuple.h>

#include <serhw.h>
#include "ser16950.h"
#include <hw16550.h>
#include "wendyser.h"
#include <devload.h>
#include "serpriv.h"

#include <excpt.h>

#include <pcmfuncs.h>

#include <serdbg.h>

#ifdef DEBUG
#pragma message ("Compile DEBUG is on:WendySer[wendyser.c]")
#endif


#define BASE_EVENT_MASK 0x02FF  // all of them.
//#define INB(pInfo, reg) (*((pInfo)->reg))    
//#define OUTB(pInfo, reg, value) (*((pInfo)->reg)) = ((unsigned char)(value))
#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION 
#define INB(pInfo, reg) (READ_PORT_UCHAR((UCHAR *)((pInfo)->reg)))
#define OUTB(pInfo, reg, value) (WRITE_PORT_UCHAR((UCHAR *)((pInfo)->reg), (unsigned char)(value)))


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

// Declare an array of pointers to CARD_INFO structures.  This should really
// be a linked list, but that seems like overkill since we currently have
// no products with more than two slots.
#define MAX_CARDS 4
PWENDY_CARD_SER_INFO CardInfoList[MAX_CARDS];

VOID
WendySerialEventHandler(UINT32 uISRContext)                         
{
    extern SerialEventHandler(PVOID);

    PWENDY_CARD_SER_INFO pCardInfo = (PWENDY_CARD_SER_INFO)uISRContext;
    DEBUGMSG (ZONE_THREAD | ZONE_FUNCTION,
	           (TEXT("+CFTestSerialEventHandler : Context x%X\r\n"),
               uISRContext ));
//$$$$bugbug$$$$

//	if (pCardInfo != CardInfoList[0])
//		return;
//$$$$bugbug$$$$

	if (pCardInfo->cOpenCount)
    {
        DEBUGMSG (ZONE_THREAD | ZONE_FUNCTION,
                  (TEXT("CioEventHandler : Check serial port (x%X) interrupt\r\n"),
                   pCardInfo ));
        SerialEventHandler((PVOID)(pCardInfo->pMddHead));
    }
}

//
// FindComConfig - 
//
// Return the configuration information in the first CIS config found
// in pConfigIndex, pIOAddress and pIOLen and return TRUE.
//
// Return FALSE if any error getting Config Table.
//
// CIo : Device Configuration
BOOL
FindComConfig(
    PWENDY_CARD_SER_INFO pHWHead,
    PUCHAR pConfigIndex,
    PUINT pIOAddress,
    PUINT pIOLen
    )
{
    UCHAR CFBuf[1024];
#ifdef DEBUG  // For debug loads, dump info about card
    UINT	i;
#endif
    PPARSED_CFTABLE pCf = (PPARSED_CFTABLE)CFBuf;
    UINT dataLen;
    STATUS status;

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

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

	if (dataLen == 0)
    {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("CFIo : CardGetParsedTuple datalen = %d\n"), dataLen) );
        return FALSE;
    }

    DEBUGMSG (ZONE_INIT | ZONE_ERROR,
              (TEXT("CFIo: CardGetParsedTuple : %d entries\n"),
               dataLen));

#ifdef DEBUG  // For debug loads, dump info about card
    DEBUGMSG (ZONE_INIT, (TEXT("\r\nCFIo : Device Configuration\r\n")) );
    for( i=0; i<dataLen; i++, pCf++ )
    {
        int j;
        
        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]));
        }
    }
    pCf = (PPARSED_CFTABLE)CFBuf;
#endif
    
    // Just use the FIRST config...

    *pConfigIndex = pCf->ConfigIndex;
    //*pConfigIndex = 4;// added by EricG, need to be fix
//#pragma message ("Using 0x60 for address!")
#pragma message ("Using 0x60 for address!")
#ifdef x86
    *pIOAddress = pCf->IOBase[0]+0x100;
#else
    *pIOAddress = pCf->IOBase[0]+0x60;
#endif
//    *pIOAddress = pCf->IOBase[0]+0x60;
//    *pIOAddress = pCf->IOBase[0];
#pragma message ("get true length from CONFIG")
    *pIOLen = 8;
#ifdef TODO  // -- Need to store the base addr for each port            
	pHWHead->pCardInfo->wBaseAddr[0] = pCf->IOBase[0];
#endif

    
	return TRUE;
}   // 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:
//
LPTSTR
DetectModem(
    CARD_SOCKET_HANDLE hSock,
    UCHAR  DevType,
    LPTSTR DevKey,
    DWORD  DevKeyLen
    )
{
    // We never want to pick up a card that wasn't explicitly identified
    // as a WENDY Wendy CF Card.
    // Leave that type of work up to the generic ser_card driver
    return NULL;
    
}   // DetectModem


// Miscellaneous internal routines.

STATUS CallBackFn(
    CARD_EVENT EventCode,
    CARD_SOCKET_HANDLE hSocket,
    PCARD_EVENT_PARMS pParms
    )
{
	PWENDY_CARD_SER_INFO pCardInfo;
    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;
    }
    
	pCardInfo = (PWENDY_CARD_SER_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.
             //
#ifdef TODO // How to determine what card is being removed?
            CardStatus.hSocket = CardInfo.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")));
                }
            }
#endif            
            break;
            
		// added by EricG. to see if the reset operation was done completly
        case CE_RESET_COMPLETE:
			
			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("CF_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("CF_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("_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;
}


BOOL
InitPCMCIACard( PWENDY_CARD_SER_INFO pCardInfo )
{
    UCHAR ConfigNum;
    UINT32 IOAddress;
    UINT32 IOLen;
    CARD_CONFIG_INFO ConfigInfo;
    CARD_REGISTER_PARMS Parms;
    CARD_WINDOW_PARMS WinParms;     // For CardRequestWindow

    DEBUGMSG (ZONE_INIT, (TEXT("WendySer : Attempting to register\r\n")));

    Parms.fEventMask = 0xffff;
    Parms.uClientData = (UINT32)pCardInfo;

    //
    // Register as an IO client.
    //
    Parms.fAttributes = CLIENT_ATTR_IO_DRIVER | CLIENT_ATTR_NOTIFY_SHARED |
        CLIENT_ATTR_NOTIFY_EXCLUSIVE;
    pCardInfo->hCardClient = CallCardServices(CardRegisterClient) (CallBackFn, &Parms);
    DEBUGMSG (ZONE_INIT, ( TEXT("head @ 1 = 0x%X\r\n"), pCardInfo));
    if (pCardInfo->hCardClient == 0)
    {
        DEBUGMSG (ZONE_INIT, (
            TEXT("WendySer : RegisterClient - failed (%d)\r\n"),
            GetLastError()));
        return FALSE;
    }


    // Request the window.
    WinParms.fAttributes = WIN_ATTR_IO_SPACE;
    WinParms.uWindowSize = 32;
#pragma message ("Should this match what the card CIS says?")
    WinParms.fAccessSpeed = WIN_SPEED_USE_WAIT;
    WinParms.hSocket = pCardInfo->hCardSock;
    pCardInfo->hCardWindow = CallCardServices(CardRequestWindow) (pCardInfo->hCardClient, &WinParms);
    if (pCardInfo->hCardWindow == NULL)
    {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("WendySer  : CardRequestWindow failed %d\n"), 
                   GetLastError()));
        CallCardServices(CardDeregisterClient) (pCardInfo->hCardClient);
        return FALSE;
    }

    CallCardServices(CardResetFunction) (pCardInfo->hCardClient, pCardInfo->hCardSock);
    if (FindComConfig(pCardInfo, &ConfigNum, &IOAddress, &IOLen) == FALSE) {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("WendySer  : No valid PC card configuration found\n")));
        CallCardServices(CardDeregisterClient) (pCardInfo->hCardClient);
        return FALSE;
    }

    DEBUGMSG (ZONE_INIT,
              (TEXT("WendySer  : Using Configuration %d (IOAddr 0x%X, len %d)\n"), 
               ConfigNum, IOAddress, IOLen ));

    DEBUGMSG (ZONE_INIT, (TEXT("head @ 2 = 0x%X\r\n"), pCardInfo));


    DEBUGMSG (ZONE_INIT,
              (TEXT("WendySer  : Mapping Window 0x%X at 0x%X, len %d, Granularity %d\n"), 
               pCardInfo->hCardWindow, IOAddress, IOLen, pCardInfo->IO_Granularity ));


    // Now we know all the attributes, lets map the IO space
    pCardInfo->pCardIOWin = CallCardServices(CardMapWindow) (pCardInfo->hCardWindow, IOAddress, IOLen, &(pCardInfo->IO_Granularity) );
    if (pCardInfo->pCardIOWin == NULL)
    {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("WendySer  : CardMapWindow failed %d\n"), 
                   GetLastError()));
        CallCardServices(CardDeregisterClient) (pCardInfo->hCardClient);
        return FALSE;
    }
    else
    {
        DEBUGMSG (ZONE_INIT,
                  (TEXT("WendySer  : CardMapWindow pCardIOWin = 0x%X\n"), 
                   pCardInfo->pCardIOWin));
    }

    // And then use CardRequestConfig to power this baby up
    ConfigInfo.hSocket = pCardInfo->hCardSock;
    ConfigInfo.fAttributes = CFG_ATTR_VALID_CLIENT | CFG_ATTR_IRQ_STEERING;
    						 //CFG_ATTR_IRQ_WAKEUP   | CFG_ATTR_KEEP_POWERED;
//RETAILMSG(-1, TEXT("fAttributes=%08x\n\r"), ConfigInfo.fAttributes);
    ConfigInfo.uVcc = 50;
    ConfigInfo.uVpp1 = 0;
    ConfigInfo.uVpp2 = 0;
    ConfigInfo.fInterfaceType = CFG_IFACE_MEMORY_IO;
    ConfigInfo.fRegisters = CFG_REGISTER_STATUS | CFG_REGISTER_CONFIG | CFG_REGISTER_PIN;
    ConfigInfo.uStatusReg = FCR_FCSR_REQUIRED_BITS | FCR_FCSR_AUDIO;
    ConfigInfo.uPinReg = 0;
    ConfigInfo.uCopyReg = 0;
    ConfigInfo.uConfigReg = ConfigNum;
    ConfigInfo.uExtendedStatus = 0;

    if (CallCardServices(CardRequestConfiguration) (pCardInfo->hCardClient, &ConfigInfo))
    {
#if 0
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,
                  (TEXT("WendySer : CardRequestConfiguration returned %d\n"), 
                   status) );
#endif
        CallCardServices(CardDeregisterClient) (pCardInfo->hCardClient);
        return FALSE;
    }
    else
        DEBUGMSG (ZONE_INIT,
                  (TEXT("WendySer : CardRequestConfiguration completed \n")));

    return TRUE;
}


//
// @doc OEM 
// @func PVOID | CF_Init | Initializes device identified by argument.
//   This routine allocates any memory required by the driver, and
//   initializes a few of the fields.  For PCMCIA cards, that is all
//   we can do this early.  Nearly everything else is done at open
//   time in order to ensure that we do not power the PCMCIA card
//   up any sooner than required.
// 
// @rdesc The return value is a PVOID to be passed back into the other
// I_??? entrypoints as a device handle.
//
PVOID
CF_Init(
    ULONG   Identifier,	// @parm pointer to card-socket handle for PCMCIA
    PVOID	pMddHead	// @parm First argument to mdd callbacks.
    )
{
    PWENDY_CARD_SER_INFO   pCardInfo;
    CARD_SOCKET_HANDLE hCardSock;
    WORD wCardIndex;
    int i;
    

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+CF_INIT\r\n") ));
    DEBUGMSG (ZONE_INIT, (TEXT("Initializing Wendy\r\n") ));

    // First, make sure this card is valid
    if( !GetCardHandle( Identifier, &hCardSock ) )
		{
        return (UINT32)NULL;
		}
    // Next, make sure we can load the PCMCIA DLL
    if( !InitCardServicesTable() )

⌨️ 快捷键说明

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