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

📄 xp_osi_inter.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 3 页
字号:
static SHORT del_mask(GLOBAL_RESOURCES * pGlobal,ULONG ulMask,PFS notify_fn,                      INTERRUPT_INFO_PTR pInfo){    short i;    short count=0;    for (i=0; i<pInfo->wNotifyAlloc; i++)    {        if((ulMask == pInfo->pNotify[i].ulMask) &&           (notify_fn == pInfo->pNotify[i].notify_fn))        {            pInfo->pNotify[i].ulMask = 0;            pInfo->pNotify[i].notify_fn = NULL;            pInfo->wNotifyCount--;            count++;        }    }    if(count == 0)    {        return(XP_ERROR_INTER_MASK);    }    return(0);}/*----------------------------------------------------------------------------+|  reset_mask+----------------------------------------------------------------------------*/static void reset_mask(GLOBAL_RESOURCES *pGlobal,INTERRUPT_INFO_PTR pInfo){    if(pInfo->wNotifyAlloc > 0)    {      pInfo->wNotifyAlloc = 0;      FREE(pInfo->pNotify);      pInfo->pNotify = NULL;    }    pInfo->wNotifyCount = 0;}/*----------------------------------------------------------------------------+| XXXXXXX  XXX XXX   XXXXXX  XXXXXXX  XXXXXX   XX   XX     XX    XXXX|  XX   X   XX XX    X XX X   XX   X   XX  XX  XXX  XX    XXXX    XX|  XX X      XXX       XX     XX X     XX  XX  XXXX XX   XX  XX   XX|  XXXX       X        XX     XXXX     XXXXX   XX XXXX   XX  XX   XX|  XX X      XXX       XX     XX X     XX XX   XX  XXX   XXXXXX   XX|  XX   X   XX XX      XX     XX   X   XX  XX  XX   XX   XX  XX   XX  XX| XXXXXXX  XXX XXX    XXXX   XXXXXXX  XXX  XX  XX   XX   XX  XX  XXXXXXX+----------------------------------------------------------------------------*/void *xp_osi_task(QUEUE_T *pQueue){    XP_OS_MSG_TYPE msg;                  /* message received                 */    /*------------------------------------------------------------------------+    |  Wait for and process messages    +------------------------------------------------------------------------*/    while(os_irq_task_get_msg(pQueue, &msg) >= 0)    {        (*msg.notify_fn)(msg.pGlobal, msg.wChannelId, msg.ulInterrupt);    }    return (NULL);}/*----------------------------------------------------------------------------+|  xp0_interrupt+-----------------------------------------------------------------------------+||  FUNCTION    :  xp0_interrupt||  DESCRIPTION :  process all interrupts from transport|+----------------------------------------------------------------------------*/void xp_osi_interrupt(){    short i, j;    unsigned long interrupt;    /*------------------------------------------------------------------------+    |  Read & clear the primary interrupts.    |  Process all the interrupt bits which were set    +------------------------------------------------------------------------*/    if(pXp0Global == NULL)          return;    interrupt = xp_atom_dcr_read_interrupt(pXp0Global->uDeviceIndex);    for(i=0, j=0; i<pXp0Global->InterInfo.XpInterPriInt.wNotifyAlloc &&                  j<pXp0Global->InterInfo.XpInterPriInt.wNotifyCount; i++)    {        if(interrupt & pXp0Global->InterInfo.XpInterPriInt.pNotify[i].ulMask)        {            j++;            if(pXp0Global->InterInfo.XpInterPriInt.pNotify[i].notify_fn)            {                (*pXp0Global->InterInfo.XpInterPriInt.pNotify[i].notify_fn)(pXp0Global, interrupt);            }        }    }    /*------------------------------------------------------------------------+    |  Call primary handlers for interrupt hierarchy    +------------------------------------------------------------------------*/    if(interrupt & XP_INTERRUPT_IR_QUE)    {        channel_interrupt(pXp0Global);    }    if(interrupt & XP_INTERRUPT_IR_FES)    {        status_interrupt(pXp0Global);    }    if(interrupt & XP_INTERRUPT_IR_VID)    {        video_interrupt(pXp0Global);    }    if(interrupt & XP_INTERRUPT_IR_AUD)    {        audio_interrupt(pXp0Global);    }}void xp1_interrupt(GLOBAL_RESOURCES *pXp0Global, ULONG ulXp0Int){    short         i, j;    unsigned long interrupt;    GLOBAL_RESOURCES *pGlobal;    pGlobal = pXp1Global;    if(pGlobal == NULL)    {        return;    }    /*------------------------------------------------------------------------+    |  Read & clear the primary interrupts.    |  Process all the interrupt bits which were set    +------------------------------------------------------------------------*///  flag = os_enter_critical_section();    interrupt = xp_atom_dcr_read_interrupt(pGlobal->uDeviceIndex);//  os_leave_critical_section(flag);    for(i=0, j=0; i<pGlobal->InterInfo.XpInterPriInt.wNotifyAlloc &&                  j<pGlobal->InterInfo.XpInterPriInt.wNotifyCount; i++)    {        if(interrupt & pGlobal->InterInfo.XpInterPriInt.pNotify[i].ulMask)        {            j++;            if(pGlobal->InterInfo.XpInterPriInt.pNotify[i].notify_fn)            {                (*pGlobal->InterInfo.XpInterPriInt.pNotify[i].notify_fn)(pGlobal, interrupt);            }        }    }    /*------------------------------------------------------------------------+    |  Call primary handlers for interrupt hierarchy    +------------------------------------------------------------------------*/    if(interrupt & XP_INTERRUPT_IR_QUE)    {        channel_interrupt(pGlobal);    }    if(interrupt & XP_INTERRUPT_IR_FES)    {        status_interrupt(pGlobal);    }}void xp2_interrupt(GLOBAL_RESOURCES *pXp0Global, ULONG ulXp0Int){    short         i, j;    unsigned long interrupt;    GLOBAL_RESOURCES *pGlobal;    pGlobal = pXp2Global;    if(pGlobal == NULL)    {        return;    }    /*------------------------------------------------------------------------+    |  Read & clear the primary interrupts.    |  Process all the interrupt bits which were set    +------------------------------------------------------------------------*///  flag = os_enter_critical_section();    interrupt = xp_atom_dcr_read_interrupt(pGlobal->uDeviceIndex);//  os_leave_critical_section(flag);    for(i=0, j=0; i<pGlobal->InterInfo.XpInterPriInt.wNotifyAlloc &&                  j<pGlobal->InterInfo.XpInterPriInt.wNotifyCount; i++)    {        if(interrupt & pGlobal->InterInfo.XpInterPriInt.pNotify[i].ulMask)        {            j++;            if(pGlobal->InterInfo.XpInterPriInt.pNotify[i].notify_fn)            {                (*pGlobal->InterInfo.XpInterPriInt.pNotify[i].notify_fn)(pGlobal, interrupt);            }        }    }    /*------------------------------------------------------------------------+    |  Call primary handlers for interrupt hierarchy    +------------------------------------------------------------------------*/    if(interrupt & XP_INTERRUPT_IR_QUE)    {        channel_interrupt(pGlobal);    }    if(interrupt & XP_INTERRUPT_IR_FES)    {        status_interrupt(pGlobal);    }}/*----------------------------------------------------------------------------+|  xp0_interrupt_init+----------------------------------------------------------------------------*/SHORT xp_osi_interrupt_init(GLOBAL_RESOURCES *pGlobal){    short rc = 0;    UINT32  flag;    PDEBUG("pGlobal->uDeviceIndex = %x\n",pGlobal->uDeviceIndex);    switch(pGlobal->uDeviceIndex)    {    case 0:        pXp0Global = pGlobal;        break;    case 1:        pXp1Global = pGlobal;        break;    case 2:        pXp2Global = pGlobal;        break;    default:        break;    }     /*------------------------------------------------------------------------+    |  Initialize all the interrupt structures    +------------------------------------------------------------------------*/    memset(&pGlobal->InterInfo.XpInterStatInt, 0, sizeof(pGlobal->InterInfo.XpInterStatInt));    memset(&pGlobal->InterInfo.XpInterPriInt,  0, sizeof(pGlobal->InterInfo.XpInterPriInt));    memset(&pGlobal->InterInfo.XpInterChanInt, 0, sizeof(pGlobal->InterInfo.XpInterChanInt));    if(pGlobal->uDeviceIndex == 0)    {        flag = os_enter_critical_section();        xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_INTMASK, XP0_PRIMARY_SET_MASK);        os_leave_critical_section(flag);    }    else    {        flag = os_enter_critical_section();        xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_INTMASK, XP12_PRIMARY_SET_MASK);        os_leave_critical_section(flag);    }    pGlobal->InterInfo.XpInterChanMask = 0;    pGlobal->InterInfo.XpInterPriMask = 0;    if(pXp0Global == NULL)        return -1;    if(pGlobal->uDeviceIndex == 0)    {            if(os_add_irq_task(XP_IRQ,(void*)xp_osi_task,sizeof(XP_OS_MSG_TYPE),QUEUE_SIZE))                return -1;    }    if(pGlobal->uDeviceIndex == 1)        rc = xp_osi_interrupt_notify(pXp0Global,XP_INTERRUPT_NOTIFY_ADD,        XP_INTERRUPT_IR_X1INT, (PFS)xp1_interrupt);    else if(pGlobal->uDeviceIndex == 2)        rc = xp_osi_interrupt_notify(pXp0Global,XP_INTERRUPT_NOTIFY_ADD,        XP_INTERRUPT_IR_X2INT, (PFS)xp2_interrupt);    return(rc);}/*----------------------------------------------------------------------------+|  xp0_interrupt_channel_control+----------------------------------------------------------------------------*/SHORT xp_osi_interrupt_channel_control(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId,                                       XP_INTERRUPT_CONTROL_TYPE cmd){    unsigned long addr;    unsigned long bit;    unsigned long ireq;    unsigned long new_ireq;    UINT32  flag;    if((wChannelId < 0) || (wChannelId >= XP_INTERRUPT_COUNT))    {        return(XP_ERROR_CHANNEL_INVALID);    }    /*------------------------------------------------------------------------+    |  Clear any interrupts which may be pending    +------------------------------------------------------------------------*/    if(cmd == XP_INTERRUPT_CONTROL_RESET)    {        switch(wChannelId)        {        case XP_INTERRUPT_AUDIO:            addr = XP_DCR_ADDR_ASTATUS;            break;        case XP_INTERRUPT_VIDEO:            addr = XP_DCR_ADDR_VSTATUS;            break;        default:            addr = XP_DCR_ADDR_BASE_QSTAT + wChannelId;            break;        }        flag = os_enter_critical_section();        xp_atom_dcr_write(pGlobal->uDeviceIndex,addr, 0xFFFFFFFF);        os_leave_critical_section(flag);    }    /*------------------------------------------------------------------------+    |  Enable or disable any interrupts for a channel using the ireq register    |  Contruct the value used to control the ireq field    +------------------------------------------------------------------------*/    else    {        if (wChannelId < XP_CHANNEL_COUNT)        {            bit = 1 << (31 - wChannelId);            flag = os_enter_critical_section();            new_ireq = ireq = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_QINTMSK);            os_leave_critical_section(flag);          switch(cmd)          {          case XP_INTERRUPT_CONTROL_DISABLE:              new_ireq &= ~bit;              break;          case XP_INTERRUPT_CONTROL_ENABLE:              new_ireq |= bit;              break;          default:              return(XP_ERROR_INTERNAL);          }          if(ireq != new_ireq)          {              flag = os_enter_critical_section();              xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_QINTMSK, new_ireq);              os_leave_critical_section(flag);          }       }    }    return(0);}/*----------------------------------------------------------------------------+|  xp0_interrupt_channel_free+----------------------------------------------------------------------------*/

⌨️ 快捷键说明

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