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

📄 devclnt.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
字号:
/* -*-C-*- * * $Revision: 1.1 $ *   $Author: rivimey $ *     $Date: 1999/03/11 11:53:36 $ * * Copyright (c) 1996 Advanced RISC Machines Limited. * All Rights Reserved. * *   Project: ANGEL * *     Title: Public client interface to devices */#include "devclnt.h"#include "devdriv.h"#include "logging.h"/* private globals *//* all the read callback info for a device */typedef struct ReadCallbacks{    DevRead_CB_Fn callback;    void *cb_data;    DevGetBuff_Fn get_buff;    void *getb_data;} ReadCallbacks;/* all the callback info for a device */typedef struct DevCallbacks{    DevWrite_CB_Fn write_callback;      /* current write */    void *write_cb_data;                /* current write */        ReadCallbacks read[DC_NUM_CHANNELS];} DevCallbacks;/* stored callbacks and callback data for each device */static DevCallbacks dev_cb[DI_NUM_DEVICES];/* useful for debugging packets */#if DEBUG == 1static void debug_packet(log_id mod, p_Buffer buffer, unsigned int length){#ifndef NO_LOG_INFO    log_dump_buffer(WL_INFO, mod, 16, (char*)buffer, length);#endif}#else#define debug_packet(mod, buff, length)#endifDevError angel_DeviceWrite(DeviceID devID, p_Buffer buff,                  unsigned length, DevWrite_CB_Fn callback,                  void *cb_data, DevChanID chanID){#ifdef CHECK_PARAMS    if (devID >= DI_NUM_DEVICES)    {        return DE_NO_DEV;    }        if (chanID >= DC_NUM_CHANNELS)    {        return DE_BAD_CHAN;    }    if (angel_Device[devID]->type != DT_ANGEL)    {        return DE_BAD_DEV;    }#endif        Angel_EnterSVC();    if (angel_DeviceStatus[devID] & DEV_WRITE_BUSY)    {        Angel_ExitToUSR();        return DE_BUSY;    }    angel_DeviceStatus[devID] |= DEV_WRITE_BUSY;  /* cleared by device */    Angel_ExitToUSR();        LogInfo(LOG_DEVCLNT, ("angel_DeviceWrite: devid %d, cb %x, devchan %d\n",                          devID, callback, chanID));        debug_packet(LOG_DEVCLNT, buff, length);    /* Okay, we've passed the checks, let's get on with it */    dev_cb[devID].write_callback = callback;    dev_cb[devID].write_cb_data = cb_data;    LogInfo(LOG_DEVCLNT, ("angel_DeviceWrite: chaining to device async write.\n"));        return angel_Device[devID]->rw.angel.async_write(devID,                                                     buff, length, chanID);}DevError angel_DeviceRegisterRead(DeviceID devID,                         DevRead_CB_Fn callback, void *cb_data,                         DevGetBuff_Fn get_buff, void *getb_data,                         DevChanID devchanID){    LogInfo(LOG_DEVCLNT, ("angel_DeviceRegisterRead: devID %d, cb %x, devchan %d\n",                            devID, callback, devchanID));#ifdef CHECK_PARAMS    if (devID >= DI_NUM_DEVICES)        return DE_NO_DEV;    if (devchanID >= DC_NUM_CHANNELS)        return DE_BAD_CHAN;    if (angel_Device[devID]->type != DT_ANGEL)        return DE_BAD_DEV;#endif        Angel_EnterSVC();    if (angel_DeviceStatus[devID] & DEV_READ_BUSY(devchanID))    {        Angel_ExitToUSR();        return DE_BUSY;    }    angel_DeviceStatus[devID] |= DEV_READ_BUSY(devchanID);    Angel_ExitToUSR();    /* Okay, we've passed the checks, let's get on with it */    dev_cb[devID].read[devchanID].callback = callback;    dev_cb[devID].read[devchanID].cb_data = cb_data;    dev_cb[devID].read[devchanID].get_buff = get_buff;    dev_cb[devID].read[devchanID].getb_data = getb_data;    LogInfo(LOG_DEVCLNT, ("angel_DeviceRegisterRead: calling device register.\n"));        return angel_Device[devID]->rw.angel.register_read(devID, devchanID);}/* *  Function: angel_DeviceControl *   Purpose:  * *    Params: *       Input:  * *   Returns: . */DevError angel_DeviceControl(DeviceID devID, DeviceControl op, void *arg){    LogInfo(LOG_DEVCLNT, ("angel_DeviceControl: devID %d, op %d, arg %x\n",                            devID, op, arg));#ifdef CHECK_PARAMS    if (devID >= DI_NUM_DEVICES)        return DE_NO_DEV;#endif        return angel_Device[devID]->control(devID, op, arg);}/* *  Function: angel_ControlAll *   Purpose:  * *    Params: *       Input:  * *   Returns: . */static void angel_ControlAll(DeviceControl op, void *arg){    int i;    LogInfo(LOG_DEVCLNT, ( "angel_ControlAll: op %d, arg %x\n", op, arg));    for (i = 0; i < DI_NUM_DEVICES; ++i)        angel_Device[i]->control(i, op, arg);}/* *  Function: angel_ReceiveMode *   Purpose:  * *    Params: *       Input:  * *   Returns: . */void angel_ReceiveMode(DevRecvMode mode){    angel_ControlAll(DC_RECEIVE_MODE, (void *)mode);}/* *  Function: angel_ResetDevices *   Purpose:  * *    Params: *       Input:  * *   Returns: . */void angel_ResetDevices(void){    angel_ControlAll(DC_RESET, NULL);}/* *  Function: angel_InitialiseDevices *   Purpose: To call the device initialise code of all devices *            configured under Angel. * *    Params: *       Input: none * *   Returns: none */void angel_InitialiseDevices(void){    int i;    LogInfo(LOG_DEVCLNT, ( "angel_InitialiseDevices\n"));    Angel_InitChannels();    Angel_InitBuffers();    for (i = 0; i < DI_NUM_DEVICES; ++i)    {        angel_DeviceStatus[i] = 0;        angel_Device[i]->control(i, DC_INIT, NULL);    }    /* err, thats all? */    LogInfo(LOG_DEVCLNT, ( "angel_InitialiseDevices complete.\n"));}/* *  Function: angel_IsAngelDevice * *   Purpose: To return TRUE if the device is an Angel Packet device, *            FALSE if it is a RAW device. * *    Params: *       Input: devid - the device ID code associated with the device. * *   Returns: bool - TRUE or FALSE. */bool angel_IsAngelDevice(DeviceID devID){    ASSERT(devID < DI_NUM_DEVICES, ("illegal device"));    return (angel_Device[devID]->type == DT_ANGEL);}/* *  Function: angel_DD_GotPacket * *   Purpose: Handle receipt of a packet callback. The routine  *            is called from the High priority task called from *            the device ISR, which is expected to convert the *            byte- (or other-) formatted data into packet form. * *            Various checks are performed to ensure the call *            is correct before indexing the callback array to *            find the function which will process the packet. * *            The callback task will be queued for later action; *            this routine *does* return to the caller. * *    Params: *       Input: devID - the ID code of device which read the data *              buff -  the buffer in which the data has been placed *              length - the length of the data in the buffer *              status - DS_DONE if data considered good, else *                       data is considered bad (e.g. CRC fail, bad *                       length). *              devchanID - the device channel. typically DC_DBUG *                      for debug (RDI,etc) data, DC_APPL for *                      other (application) data. * *   Returns: nothing. */void angel_DD_GotPacket(DeviceID devID, p_Buffer buff, unsigned length,                   DevStatus status, DevChanID devchanID){    LogInfo(LOG_DEVCLNT, ("angel_DD_GotPacket: dev %d, buff %x, len %d, stat %s, "                            "chan %d, [reason %s]\n",                            devID, buff, length, status == DS_DONE ? "ok" : "*BAD*",                            devchanID, log_adpname(*(long*)(buff+4))));    ASSERT(devID < DI_NUM_DEVICES, ("devID bad"));    ASSERT(devchanID < DC_NUM_CHANNELS, ("devchanID bad"));    ASSERT(dev_cb[devID].read[devchanID].callback != NULL,           ("no read callback"));    if (buff != NULL && length > 0)        debug_packet(LOG_DEVCLNT, buff, length);    /*      * do the call: "callback(buff, length, status, cb_data);"     */    Angel_QueueCallback(dev_cb[devID].read[devchanID].callback, TP_AngelCallBack,                        (void *)buff, (void *)length, (void *)status,                        (void *)dev_cb[devID].read[devchanID].cb_data);        LogInfo(LOG_DEVCLNT, ("angel_DD_GotPacket: returning\n"));}/* *  Function: angel_DD_SentPacket * *   Purpose: Handle transmission completion. Called as a result of *            the device having pulled all the data from the device *            ring buffer (more generally: called when a packet send, *            initiated with AsyncWrite, has completed). * *            Various checks are performed to ensure the call *            is correct before indexing the callback array to *            find the function which will process the packet. * *            The call is used to initiate further action by the code *            sending the data. It must also ensure the device BUSY *            flag has been reset, indicating that the device can be *            used to send something else. * *            The callback task will be queued for later action; *            this routine *does* return to the caller. * *    Params: *       Input: devID - which device *              buff -  pointer to data *              length - how much done *              status -  success code *              devchanID - appl or chan * *   Returns: nothing */void angel_DD_SentPacket(DeviceID devID, p_Buffer buff, unsigned length,                    DevStatus status, DevChanID devchanID){    unsigned int s;    angel_TaskQueueItem *tqi;    LogInfo(LOG_DEVCLNT, ("angel_DD_SentPacket: dev %d, buff %x, len %d, stat %d, "                          "chan %d, [reason %s]\n",                          devID, buff, length, status,                          devchanID, log_adpname(*(long*)(buff+4))));        ASSERT(devID < DI_NUM_DEVICES, ("devID bad"));    ASSERT(devchanID < DC_NUM_CHANNELS, ("devchanID bad"));    ASSERT(dev_cb[devID].write_callback != NULL, ("no write callback"));    /*     * We need to protect this     */    s = Angel_DisableInterruptsFromSVC();    angel_DeviceStatus[devID] &= ~DEV_WRITE_BUSY;    Angel_RestoreInterruptsFromSVC(s);    /*      * do the call: "callback(buff, length, status, cb_data);"     */    tqi = Angel_QueueCallback(dev_cb[devID].write_callback, TP_AngelCallBack,                        (void *)buff, (void *)length, (void *)status,                        (void *)dev_cb[devID].write_cb_data);        /*     * set priority of this higher than normal: we need this task complete ASAP     */    angel_SetPriority(tqi, TaskPriorityOf(TP_AngelCallBack) + 1);    LogInfo(LOG_DEVCLNT, ("angel_DD_SentPacket: returning\n"));}/* *  Function: angel_DD_GetBuffer * *   Purpose: To get a buffer from the Angel buffer pool. This will *            usually imply a call to the Angel Buffer management *            functions, but the exact implementation is hidden behind *            the specified "get_buff" function pointer, which allows *            a caller to specify it's own buffer management. * * *    Params: *       Input: devID - the ID of the device requesting the buffer *              devchanID - the device channel; typically DC_DBUG *              req_size - the minimum number of bytes buffer space *                         needed * *   Returns: a pointer to the buffer, or NULL if not avaiable. *            (no distinction is made between no buffer available, *            and no buffer of a sufficient size). */p_Buffer angel_DD_GetBuffer(DeviceID devID, DevChanID devchanID,                   unsigned req_size){    p_Buffer ret_buffer;    LogInfo(LOG_DEVCLNT, ("angel_DD_GetBuffer: dev %d, chanID %d, size %d\n",                            devID, devchanID, req_size));    ASSERT(devID < DI_NUM_DEVICES, ("devID bad"));    ASSERT(devchanID < DC_NUM_CHANNELS, ("devchanID bad"));    {        struct ReadCallbacks *rcb = &dev_cb[devID].read[devchanID];        if (rcb->get_buff == NULL)        {            LogError(LOG_DEVCLNT, ( "angel_DD_GetBuffer: No alloc fn! (rcb = %p)\n", rcb));            return NULL;        }        ret_buffer = rcb->get_buff(req_size, rcb->getb_data);    }    if (ret_buffer == NULL)        LogError(LOG_DEVCLNT, ( "angel_DD_GetBuffer: get_buff returned NULL\n"));    else        LogInfo(LOG_DEVCLNT, ( "angel_DD_GetBuffer: returning buffer 0x%x\n", ret_buffer));    return ret_buffer;}/* EOF devclnt.c */

⌨️ 快捷键说明

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