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

📄 register.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
字号:
//
// 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:  

    register.c

Abstract:  

    This file implements the PCMCIA model device driver client registration
    functions.  This is provided as a sample to platform writers and is
    expected to be able to be used without modification on most (if not
    all) hardware platforms.

Functions:

    CardRegisterClient()
    CardDeregisterClient()

Notes:


--*/

#include <windows.h>
#include <types.h>
#include <cardserv.h>
#include <sockserv.h>
#include <linklist.h>
#include <pcmcia.h>
#include <extern.h>


//
// CardRegisterClient
//
// @doc DRIVERS
//
// @func    CARD_CLIENT_HANDLE | CardRegisterClient | Card services client driver registration.
// @rdesc   Returns a client driver handle or NULL for failure.  GetLastError will
//          return either CERR_BAD_ARGS or CERR_OUT_OF_RESOURCE.
//
// @comm    Registers a client driver with PCMCIA card services and specifies the
//          type of driver (I/O or memory).  Artificial insertion callbacks can be
//          requested for cards inserted before the client registered.
//          Callbacks:
//               CE_CARD_INSERTION - artificial insertion notifications, and
//               CE_REGISTRATION_COMPLETE - indicates status of registration.
//          When the client driver is unloaded, it must call CardDeregisterClient
//          which will free up any PCMCIA resources allocated to the client.
// @xref    <f CardDeregisterClient> <t CARD_EVENT>
//
CARD_CLIENT_HANDLE
CardRegisterClient(
    CLIENT_CALLBACK CallBackFn, // @parm Pointer to the client driver's callback function.
    PCARD_REGISTER_PARMS pParms // @parm Pointer to a <t CARD_REGISTER_PARMS> structure.
    )
{
    PCLIENT_DRIVER pClient;
    UINT16 tmp;
    STATUS status = CERR_SUCCESS;
    CARD_CLIENT_HANDLE x;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CardRegisterClient entered\r\n")));

    pClient = NULL;
    if (pParms == NULL) {
        status = CERR_BAD_ARGS;
        goto reg_exit;
    }

    //
    // Client type can be only one of three things
    //
    tmp = pParms->fAttributes & (CLIENT_ATTR_MEM_DRIVER|
                                 CLIENT_ATTR_MTD_DRIVER|CLIENT_ATTR_IO_DRIVER);

    if ((tmp != CLIENT_ATTR_MEM_DRIVER) &&
        (tmp != CLIENT_ATTR_MTD_DRIVER) &&
        (tmp != CLIENT_ATTR_IO_DRIVER)) {
        status = CERR_BAD_ARGS;
        goto reg_exit;
    }

    pClient = alloc(sizeof(CLIENT_DRIVER));
    if (pClient == NULL) {
        status = CERR_OUT_OF_RESOURCE;
        goto reg_exit;
    }
#ifdef MYMEMTRACKING
    v_TrackClientDrivers++;
#endif
#ifdef MEMTRACKING
    AddTrackedItem( v_TrackClientDrivers, pClient, NULL, GetCurrentProcessId(),
        sizeof(CLIENT_DRIVER), 0, 0);
#endif

    pClient->CallBackFn = CallBackFn;
    pClient->Parms = *pParms;
    pClient->fClosing = FALSE;
    while (1) {
        x = (CARD_CLIENT_HANDLE)(((int)v_hNextClient)++);
        if (x != NULL && FindClient(x, TRUE, FALSE) == NULL)
            break;
    }
    pClient->hClient = x;

    //
    // Set additional event mask to simplify callback processing
    //
    if (pParms->fAttributes & CLIENT_ATTR_NOTIFY_EXCLUSIVE) {
        pClient->Parms.fEventMask |= EVENT_MASK_EXCLUSIVE;
    }
    pClient->pCsock = NULL;

    //
    // Link it according to the callback ordering of the driver type specified
    //
    EnterCriticalSection(&v_ClientCrit);
    if (pParms->fAttributes & CLIENT_ATTR_IO_DRIVER) {
        InsertHeadList(&v_ClientList, &pClient->List);
    } else {
        InsertTailList(&v_ClientList, &pClient->List);
    }
    LeaveCriticalSection(&v_ClientCrit);

    //
    // Power on the PCMCIA system. PcmciaPowerOn() ignores sockets in which
    // a card is not present so it's OK to call it at any time.
    //
    for (tmp = 0; tmp < v_cSockets; tmp++) {
        PcmciaPowerOn(tmp);
    }
    
    CallbackSockets(pClient);
    Sleep(100);
        
reg_exit:
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
            (TEXT("CardRegisterClient failed %d\r\n"), status));
        SetLastError(status);
        return NULL;
    } else {
        DEBUGMSG(ZONE_FUNCTION, (TEXT("CardRegisterClient succeeded\r\n")));
        return (CARD_CLIENT_HANDLE) x;
    }
}   // CardRegisterClient


//
// CardDeregisterClient
//
// @func    STATUS | CardDeregisterClient | Deregister client driver from Card services
// @rdesc   Returns one of CERR_SUCCESS, CERR_BAD_HANDLE or CERR_IN_USE.
//
// @comm    Deregisters a client driver from PCMCIA card services.  All resources
//          that the client driver obtained from card services will be freed.
//          This may involve disabling any interrupts owned by the client driver.
// @xref    <f CardReleaseWindow> <f CardReleaseIRQ>
//
STATUS
CardDeregisterClient(
    CARD_CLIENT_HANDLE hCardClient  // @parm Handle returned from <f CardRegisterClient>
    )
{
    PPHYS_WINDOW pWin;
    PLOG_WINDOW  pLog;
    PLOG_WINDOW  pTmp;
    PCLIENT_DRIVER pClient;
    CARD_SOCKET_HANDLE hSock;
    STATUS status = CERR_SUCCESS;
    UINT16 tmp;
   
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CardDeregisterClient entered\r\n")));

    EnterCriticalSection(&v_ClientCrit);
    if ((pClient = FindClient(hCardClient, FALSE, FALSE)) == NULL ||
        pClient->fClosing) {
        status = CERR_BAD_HANDLE;
        LeaveCriticalSection(&v_ClientCrit);
        goto dereg_exit;
    }
    pClient->fClosing = TRUE;
    LeaveCriticalSection(&v_ClientCrit);

    pClient->CallBackFn = NULL;

    //
    // Release any configurations, IRQs, or socket masks this client may own.
    //
    for (hSock.uSocket = 0; hSock.uSocket < v_cSockets; hSock.uSocket++) {
        for (hSock.uFunction = 0;
             hSock.uFunction < v_Sockets[hSock.uSocket].cFunctions;
             hSock.uFunction++) {
            CardReleaseConfiguration(hCardClient, hSock);
            CardReleaseIRQ(hCardClient, hSock);
            CardReleaseSocketMask(hCardClient, hSock);
            CardReleaseExclusive(hCardClient, hSock);
        }
    }

    //
    // Release all of his memory windows
    //
    EnterCriticalSection(&v_WindowCrit);
    pWin = v_pWinList;
    while (pWin) {
        pLog = pWin->pLog;
        while (pLog) {
            if (pLog->hOwner == pClient) {
                //
                // Remember the next logical window because this one will get delinked and freed
                //
                pTmp = pLog;
                pLog = pLog->Next;
                CardReleaseWindow((CARD_WINDOW_HANDLE)pTmp);
            } else {
                pLog = pLog->Next;
            }
        }
        pWin = pWin->Next;
    }
    LeaveCriticalSection(&v_WindowCrit);

    //
    // Unlink from client list
    //
    IsValidClient(pClient);
    EnterCriticalSection(&v_ClientCrit);
    RemoveEntryList((PLIST_ENTRY)&pClient->List);
    LeaveCriticalSection(&v_ClientCrit);
    IsValidClient(pClient);

    //
    // Remove all CALLBACK_STRUCTs associated with this client
    //
    RemoveCallbacks(
       pClient,
       hSock,    // ignored when deregistering
       0,        // ignored when deregistering
       REMOVE_DEREGISTER);    // deregistering

    free(pClient);

    //
    // Turn off power if it is safe to do so.
    //
    for (tmp = 0; tmp < v_cSockets; tmp++)
        PcmciaPowerOff(tmp, FALSE, hCardClient);
    
#ifdef MYMEMTRACKING
    v_TrackClientDrivers--;
#endif
#ifdef MEMTRACKING
    DeleteTrackedItem(v_TrackClientDrivers, pClient);
#endif

dereg_exit:
#ifdef DEBUG
    if (status) {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
            (TEXT("CardDeregisterClient failed %d\r\n"), status));
    } else {
        DEBUGMSG(ZONE_FUNCTION,
            (TEXT("CardDeregisterClient succeeded\r\n")));
    }
    IsValidClient(pClient);
#endif
    return status;
}   // CardDeregisterClient

⌨️ 快捷键说明

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