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

📄 callback.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 3 页
字号:
                    for (pLsock = v_Sockets[pEvent->hSock.uSocket].pLsock; pLsock != NULL; pLsock = pLsock->Next) {
                        if (!(pLsock->fFlags & LOG_SOCK_FLAG_NO_SUSPEND_UNLOAD)) {
                            bUnloadDriver = TRUE;
                            break;
                        }
                   }
                }
#if 0
                // Check the PnP ID to determine if it's the same card
                // ...assuming that it is the same card, since either card is non-user accessible
                // or should have been woken on removal
                if (!bUnloadDriver) {
                    LPTSTR pch;

                    pch = v_Sockets[pEvent->hSock.uSocket].pDevId;
                    if (CreateDeviceID(pEvent->hSock.uSocket, FALSE) != CERR_SUCCESS) {
                        bUnloadDriver = TRUE;
                    } else {
                        bUnloadDriver = _tcscmp(v_Sockets[pEvent->hSock.uSocket].pDevId, pch);
                    }

                    if (v_Sockets[pEvent->hSock.uSocket].pDevId != NULL)
                        free(v_Sockets[pEvent->hSock.uSocket].pDevId);
                    v_Sockets[pEvent->hSock.uSocket].pDevId = pch;
                }
#endif

                // Reconfigure the sockets
                if (!bUnloadDriver) {
                    v_Sockets[pEvent->hSock.uSocket].PowerState = POWER_RESET;
                    v_Sockets[pEvent->hSock.uSocket].fFlags |= PHYS_SOCK_FLAG_RESETTING;
                    Sleep(750);   // sleep required
                    for (pLsock = v_Sockets[pEvent->hSock.uSocket].pLsock; pLsock != NULL; pLsock = pLsock->Next) {
                        if (ConfigureLogSock(pLsock) != CERR_SUCCESS) {
                            bUnloadDriver = TRUE;
                            PcmciaPowerOff(
                                pEvent->hSock.uSocket,
                                TRUE,
                                (CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);
                            break;
                        }
                    }
                }

                if (bUnloadDriver) {
                    v_Sockets[pEvent->hSock.uSocket].fFlags &= ~PHYS_SOCK_FLAG_RESETTING;
                    CardServFreeDriver(pEvent->hSock.uSocket);
                    DeleteFunctions(pEvent->hSock.uSocket);
                    PDCardGetSocket(pEvent->hSock.uSocket, &State);
                    State.fInterruptEvents = INITIAL_SOCKET_EVENTS;
                    PDCardSetSocket(pEvent->hSock.uSocket, &State);
                    //
                    // If this removal notice was due to a power on/off event,
                    // then change to the ON power state and signal the
                    // StatusChangeThread again causing insertion notices to
                    // be sent for any inserted cards.
                    //
                }

                if (v_Sockets[pEvent->hSock.uSocket].PowerState == POWER_OFF ||
                    v_Sockets[pEvent->hSock.uSocket].PowerState == POWER_KEPT) {
                    if (!(v_Sockets[pEvent->hSock.uSocket].fFlags & PHYS_SOCK_FLAG_RESETTING))
                        v_Sockets[pEvent->hSock.uSocket].PowerState = POWER_ON;
                    DEBUGMSG(ZONE_STSCHG,
                        (TEXT("PCMCIA:CE_CARD_REMOVAL signal StatusChangeThread PowerState for Socket %d changed to %x\r\n"),pEvent->hSock.uSocket,v_Sockets[pEvent->hSock.uSocket].PowerState));
                    // Signal IREQThread, so that interrupts can continue
                    // (Interrupts may have been disabled while PowerState was POWER_OFF)
                    SetEvent(v_StatusChangeEvent);
                    SetEvent(v_IREQEvent);
                } else if (v_Sockets[pEvent->hSock.uSocket].PowerState == POWER_RESET) {
                    v_Sockets[pEvent->hSock.uSocket].PowerState = POWER_ON;
                    DEBUGMSG(ZONE_STSCHG,
                        (TEXT("PCMCIA:CE_CARD_REMOVAL signal StatusChangeThread PowerState for Socket %d changed to %x\r\n"),pEvent->hSock.uSocket,v_Sockets[pEvent->hSock.uSocket].PowerState));
                    // Signal IREQThread, so that interrupts can continue
                    // (Interrupts may have been disabled while PowerState was POWER_OFF)
                    SetEvent(v_StatusChangeEvent);
                    SetEvent(v_IREQEvent);
                } else {
                    PcmciaPowerOff(
                        pEvent->hSock.uSocket,
                        TRUE,
                        (CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);
                }

                CallbackPmResume();
                goto cbt_next1;
        }
        
        if (!(pClient = FindClient(pEvent->pDestClient, TRUE, FALSE))) {
            DEBUGMSG(ZONE_CALLBACK|ZONE_WARNING,
                (TEXT("PCMCIA:CallbackThread: Invalid destination client!\r\n")));

            //
            // If this is the last event in a sequence, then there may be
            // more processing to do.
            //
            if (pEvent->fFlags & CALLBACK_FLAG_LAST) {
                goto cbt_process_last;
            } else {
                goto cbt_next1;
            }
        }

        Parms.uClientData = pClient->Parms.uClientData; // supply context

        //
        // Fill in parameters based on event code
        //
        switch (pEvent->SubEvent) {
        case CE_CARD_INSERTION:
            // If device ID is NULL, the card's been pulled.
            // Skip the callback, and do the insertion cleanup
            if (v_Sockets[pEvent->hSock.uSocket].pDevId == NULL) {
                goto cbt_end_insert;
            }

            Parms.Parm1 = (UINT)v_Sockets[pEvent->hSock.uSocket].pDevId;
            Parms.Parm2 = (UINT)pClient->hClient;
            break;

        case CE_REGISTRATION_COMPLETE:
            Parms.Parm1 = (UINT)pClient->hClient;
            Parms.Parm2 = 0;
            break;

        case CE_PM_RESUME:
            for (i = 0; i < (UINT8)v_cSockets; i++) {
                DEBUGMSG(ZONE_CALLBACK,
                         (TEXT("CE_PM_RESUME Socket %d PowerState = %x fFlags = %x\r\n"),i,v_Sockets[i].PowerState,v_Sockets[i].fFlags));
                v_Sockets[i].PowerState = POWER_NORMAL;
                v_Sockets[i].fFlags &= ~PHYS_SOCK_FLAG_FROM_STANDBY;
            }
            break;

        default:
            Parms.Parm1 = 0;
            Parms.Parm2 = 0;
            break;
        }

#ifdef DEBUG
MajorName = FindEventName(pEvent->MajorEvent);
SubName   = FindEventName(pEvent->SubEvent);
DEBUGMSG(ZONE_CALLBACK,
    (TEXT("PCMCIA:CallbackThread: %d:%d MajorEvent=%s, SubEvent=%s\r\n"),
     pEvent->hSock.uSocket, pEvent->hSock.uFunction, MajorName, SubName));

#endif // DEBUG

        //
        // Callback the client
        //
        status = CallClient(
                    pClient->CallBackFn,
                    pEvent->SubEvent,
                    pEvent->hSock,
                    &Parms,
                    pClient);

cbt_fail_query:
        if ((status) && (pEvent->fFlags & CALLBACK_FLAG_QUERY)) {
            //
            // One of the client drivers rejected a query request.  Remove
            // all events associated with the failing one.
            // If this is the last one in the current stage, then there is
            // nothing to clean up.
            //
            if (!(pEvent->fFlags & CALLBACK_FLAG_LAST)) {
                RemoveCallbacks(
                   FindClient(pEvent->pReqClient, TRUE, TRUE),
                   pEvent->hSock,
                   pEvent->MajorEvent,
                   REMOVE_QUERY);
            }

            //
            // Report to the requesting client that the request was denied
            //
            switch (pEvent->MajorEvent) {
            case CE_EXCLUSIVE_REQUEST:
                    NextEvent = CE_EXCLUSIVE_COMPLETE;
                    break;
/* These events are not implemented yet
            case CE_EJECTION_REQUEST:
                    NextEvent = CE_EJECTION_COMPLETE;
                    break;
            case CE_INSERTION_REQUEST:
                    NextEvent = CE_INSERTION_COMPLETE;
                    break;
*/
            default:
                    NextEvent = 0;
                    break;
            }

            if (NextEvent) {
                Parms.uClientData = FindClient(pEvent->pReqClient, TRUE, TRUE)->Parms.uClientData; // supply context
                Parms.Parm1 = status;
                CallClient(
                    FindClient(pEvent->pReqClient, TRUE, TRUE)->CallBackFn,
                    NextEvent,
                    pEvent->hSock,
                    &Parms,
                    FindClient(pEvent->pReqClient, TRUE, TRUE));
            }

            // end of callback request failure case
        } else {
            //
            // If this is the last event in the current stage then figure
            // out what to do next.
            //
            if (pEvent->fFlags & CALLBACK_FLAG_LAST) {
cbt_process_last:
                NextEvent = 0;      // assume nothing to do next
                fCallAll = FALSE;   // assume only one client

                switch (pEvent->MajorEvent) {

                //
                // Finish CardRegisterClient callback sequence
                //
                case CE_REGISTRATION_COMPLETE:
                    if (pEvent->SubEvent == CE_CARD_INSERTION) {
                        NextEvent = CE_REGISTRATION_COMPLETE;
                        //
                        // Shut down power to the PCMCIA interfaces if they
                        // are not in use.
                        //
                        for (i = 0; i < (UINT)v_cSockets; i++) {
                            PcmciaPowerOff(
                                i,
                                FALSE,
                                (CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);
                        }
                    }
                    break;

                //
                // Figure out the next stage of the callback sequence for
                // CardRequestExclusive
                //
                case CE_EXCLUSIVE_REQUEST:
                    switch (pEvent->SubEvent) {
                    //
                    // If all clients approved, then tell them the socket
                    // is going away and tell the requesting client that it
                    // is available.
                    //
                    case CE_EXCLUSIVE_REQUEST:
                        NextEvent = CE_CARD_REMOVAL;
                        fCallAll = TRUE;
                        break;

                    case CE_CARD_REMOVAL:
                        NextEvent = CE_CARD_INSERTION;
                        break;

                    case CE_CARD_INSERTION:
                        //
                        // Requesting client is now exclusive owner
                        //
                        pLsock = I_FindSocket(pEvent->hSock);
                        if (pLsock) {
                            //
                            // If the previous owner did not release the socket
                            // then the requesting client can't get it.
                            //
                            if (pLsock->hOwner != 0) {
                                status = CERR_IN_USE;
                                goto cbt_fail_query;
                            }
                            pLsock->fFlags |= OWNER_FLAG_EXCLUSIVE;
                            pLsock->hOwner = FindClient(pEvent->pReqClient, TRUE, TRUE);
                        }
                        NextEvent = CE_EXCLUSIVE_COMPLETE;
                        break;
                    }
                    break;

                //
                // Finish CardReleaseExclusive callback sequence
                //
                case CE_EXCLUSIVE_COMPLETE:
                    switch (pEvent->SubEvent) {
                    case CE_CARD_REMOVAL:
                        //
                        // Avoid giving invalid insertion notices
                        //
                        if (IsCardInserted(pEvent->hSock.uSocket)) {
                            NextEvent = CE_CARD_INSERTION;
                            fCallAll = TRUE;
                        }
                        break;
                    }
                    break;

                //
                // Real card insertion event
                //
cbt_end_insert:
                case CE_CARD_INSERTION:
                    pLsock = I_FindSocket(pEvent->hSock);
                    if (pLsock) {
                        if (!(pLsock->fFlags & OWNER_FLAG_INTERRUPT)) {
                            PDCardGetSocket(pEvent->hSock.uSocket, &State);
                            State.fInterruptEvents = DETECTED_SOCKET_EVENTS;
                            PDCardSetSocket(pEvent->hSock.uSocket, &State);
                        }
                        //
                        // If no clients are using this card, shut down power to
                        // the PCMCIA adapter, until a configuration is requested.
                        //
                        PcmciaPowerOff(
                            pEvent->hSock.uSocket,
                            FALSE,
                            (CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);

                        // This completes the off/on processing window.
                        v_Sockets[pEvent->hSock.uSocket].fFlags &= ~PHYS_SOCK_FLAG_RESUMING;
                    }
                    CallbackPmResume();
                    break;

                //
                // Real card removal event
                //
                case CE_CARD_REMOVAL:
                    //
                    // Deleting the LOG_SOCKETs had to be delayed to here
                    // so clients can release resources associated with
                    // this socket
                    //
                    DEBUGMSG(ZONE_STSCHG,
                        (TEXT("PCMCIA:CallbackThread processing last removal for Socket %d\r\n"),pEvent->hSock.uSocket));
                    break;

                }   // switch (MajorEvent)

                if (NextEvent) {
                    if (fCallAll) {
                        CallbackAll(
                            pEvent->MajorEvent,
                            NextEvent,
                            FindClient(pEvent->pReqClient, TRUE, TRUE),
                            pEvent->hSock,
                            //
                            // Clear CALLBACK_FLAG_LAST if it was set and
                            // retain CALLBACK_FLAG_QUERY
                            //
                            pEvent->fFlags & CALLBACK_FLAG_QUERY);
                    } else {
                        //
                        // Only one client, reuse this CALLBACK_STRUCT
                        //
                        if (IsValidClient(pClient)) {
                            pEvent->SubEvent = NextEvent;
                            pEvent->pDestClient = pEvent->pReqClient;
                            EnqueueEvent(pEvent);
                            StartCallbacks();
                            continue;       // avoid freeing pEvent
                        }
                    }
                }
            }   // if (last one in current stage)
        }
cbt_next1:
        free(pEvent);
    }   // while (callbacks to do)

    DEBUGMSG(ZONE_CALLBACK, (TEXT("PCMCIA:CallbackThread: done %d\r\n"), g_Reentry--));
    DEBUGCHK(FALSE);        // we should never get here
    return ERROR_SUCCESS;
}   // CallbackThread

⌨️ 快捷键说明

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