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

📄 xp_osi_inter.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 3 页
字号:
SHORT xp_osi_interrupt_channel_free(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId){    unsigned long value = 0;    UINT32  flag;    flag = os_enter_critical_section();    if((wChannelId < 0) || (wChannelId >= XP_INTERRUPT_COUNT)) {        return(XP_ERROR_CHANNEL_INVALID);    }    /*------------------------------------------------------------------------+    |  Delete all notifications associated with the channel    +------------------------------------------------------------------------*/    reset_mask(pGlobal,&pGlobal->InterInfo.XpInterChanInt[wChannelId]);    os_leave_critical_section(value);    return(0);}/*----------------------------------------------------------------------------+|   XX     XXXXXX    XXXXXX    XXXXX|  XXXX    XX   XX     XX     XX   XX| XX  XX   XX   XX     XX      XX| XX  XX   XXXXX       XX        XX| XXXXXX   XX          XX         XX| XX  XX   XX          XX     XX   XX| XX  XX   XX        XXXXXX    XXXXX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+|  xp0_interrupt_channel_notify+-----------------------------------------------------------------------------+||  FUNCTION    :  xp0_interrupt_channel_notify||  DESCRIPTION :  register a function to call for specific interrupts||  PROTOTYPE  :  short xp0_interrupt_channel_notify(|                short cmd,|                short channel_id,|                unsigned long int_mask,|                PFS notify_fn)||  ARGUMENTS  :  cmd           -  XP_INTERRUPT_NOTIFY_ADD to add a function|                                 XP_INTERRUPT_NOTIFY_DELETE to remove|                channel_id    -  the channel id as returned from the|                                 xp0_channel_allocate().|                notify_fn     -  function to call when an interrupt|                                 occurs for a specific channel|                                 NULL, the notification is disabled||  RETURNS    :  0 if successful, or non-zero if an error occurs||  ERRORS     :  XP_ERROR_CHANNEL_INVALID  -  channel_id is not defined||  COMMENTS   :  xp0_interrupt_channel_notify() is available to register|                a callback function.  The callback function executes|                under interrupt control and is expected to complete it's|                work quickly so other interrupts may be services. The|                be serviced.|                  The cmd parameter should be XP_INTERRUPT_NOTIFY_ADD, or|                XP_INTERRUPT_NOTIFY_DELETE to add or remove the notification|                callback function.|                  The int_mask parameter is a bit string which represents|                a set of interrupt types which are or'd together to form|                a mask.|+----------------------------------------------------------------------------*/SHORT xp_osi_interrupt_channel_notify(GLOBAL_RESOURCES *pGlobal,SHORT wCmd,SHORT wChannelId,                                      ULONG ulIntMask,XP_INTERRUPT_CHANNEL_FN notify_fn){    short rc;    short i;    short j;    unsigned long dcr_mask=0;    UINT32  flag;    flag = os_enter_critical_section();    if(notify_fn == NULL)    {        rc = XP_ERROR_INTER_NOTIFY_INVALID;    }    else if((wChannelId < 0) || (wChannelId >= XP_INTERRUPT_COUNT))    {        rc = XP_ERROR_CHANNEL_INVALID;    }    /*------------------------------------------------------------------------+    |  If the function is NULL, then find the matching mask and cancel    |  the callback function    +------------------------------------------------------------------------*/    else    {        ulIntMask &= QSTAT_INTERRUPT_MASK;        if(wCmd == XP_INTERRUPT_NOTIFY_DELETE)        {            rc = del_mask(pGlobal,ulIntMask, (PFS)notify_fn,                          &pGlobal->InterInfo.XpInterChanInt[wChannelId]);            if((rc == 0) &&               (pGlobal->InterInfo.XpInterChanInt[wChannelId].wNotifyCount == 0))            {                xp_osi_interrupt_channel_control(pGlobal,                            wChannelId,                          XP_INTERRUPT_CONTROL_DISABLE);            }        }        else if(wCmd == XP_INTERRUPT_NOTIFY_ADD)        {            rc = add_mask(pGlobal,ulIntMask, (PFS) notify_fn,                          &pGlobal->InterInfo.XpInterChanInt[wChannelId]);            if((rc == 0) &&               (pGlobal->InterInfo.XpInterChanInt[wChannelId].wNotifyCount > 0))            {                xp_osi_interrupt_channel_control(pGlobal,                            wChannelId,                          XP_INTERRUPT_CONTROL_ENABLE);            }        }        else        {            rc = XP_ERROR_INTER_NOTIFY_CMD;        }    }    /*------------------------------------------------------------------------+    |  Recalculate the mask and write it.  The channel mask is constructed    |  based on all the bits over all the dram channels.  The audio & video    |  mask are built upon their own channel.    +------------------------------------------------------------------------*/    if(rc == 0)    {        if(wChannelId < XP_CHANNEL_COUNT)        {            /*----------------------------------------------------------------+            |  Construct the channel mask            +----------------------------------------------------------------*/            for(i=0, pGlobal->InterInfo.XpInterChanMask=0; i<XP_INTERRUPT_COUNT; i++)            {                for(j=0; j<pGlobal->InterInfo.XpInterChanInt[i].wNotifyAlloc; j++)                {                   pGlobal->InterInfo.XpInterChanMask |=                       pGlobal->InterInfo.XpInterChanInt[i].pNotify[j].ulMask;                }            }#ifndef __DRV_FOR_VESTA__            dcr_mask = pGlobal->InterInfo.XpInterChanMask;            xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_QSTATMASK, dcr_mask);#else            dcr_mask = pGlobal->InterInfo.XpInterChanMask | pGlobal->InterInfo.XpInterPriMask | XP0_PRIMARY_SET_MASK;            xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_INTMASK, dcr_mask);#endif        }        else        {            for(j=0; j<pGlobal->InterInfo.XpInterChanInt[wChannelId].wNotifyAlloc; j++)            {                dcr_mask |= pGlobal->InterInfo.XpInterChanInt[wChannelId].pNotify[j].ulMask;            }            if(wChannelId == XP_INTERRUPT_AUDIO)            {                xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_AINTMSK, dcr_mask);            }            else            {               xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_VINTMSK, dcr_mask);            }        }    }    os_leave_critical_section(flag);    return(rc);}/*----------------------------------------------------------------------------+|  xp0_interrupt_notify+-----------------------------------------------------------------------------+||  DESCRIPTION:  register a callback function for primary interrupts||  PROTOTYPE  :  short xp0_interrupt_notify(|                short cmd,|                unsigned long int_mask,|                PFS notify_fn)||  ARGUMENTS  :  cmd           -  XP_INTERRUPT_NOTIFY_ADD to add a function|                                 XP_INTERRUPT_NOTIFY_DELETE to remove|                int_mask      -  interrupts to register function for|                notify_fn     -  notification function to call-back||  RETURNS    :  0 if successful, or non-zero if an error occurs||  ERRORS     :  XP_ERROR_INTER_NOTIFY_CMD - invalid command specified in 'cmd'||  COMMENTS   :  This function registers a callback function to be called|                when at least one of the interrupt bits matches a bit|                in the 'int_mask' argument.  The interrupt bits are|                defined in the 'xp0_interrupt.h' header file.|+----------------------------------------------------------------------------*/SHORT xp_osi_interrupt_notify(GLOBAL_RESOURCES *pGlobal,SHORT wCmd,ULONG ulIntMask,                              PFS notify_fn){    short rc;    short i;    unsigned long dcr_mask;    UINT32  flag;    flag = os_enter_critical_section();    if(notify_fn == NULL)    {        rc = XP_ERROR_INTER_NOTIFY_INVALID;    }    /*------------------------------------------------------------------------+    |  If the function is NULL, then find the matching mask and cancel    |  the callback function    +------------------------------------------------------------------------*/    else    {        if(pGlobal->uDeviceIndex == 0)            ulIntMask &= XP0_PRIMARY_INTERRUPT_MASK;        else            ulIntMask &= XP12_PRIMARY_INTERRUPT_MASK;        if(wCmd == XP_INTERRUPT_NOTIFY_DELETE)        {            rc = del_mask(pGlobal,ulIntMask, notify_fn, &pGlobal->InterInfo.XpInterPriInt);        }        else if(wCmd == XP_INTERRUPT_NOTIFY_ADD)        {            rc = add_mask(pGlobal,ulIntMask, notify_fn, &pGlobal->InterInfo.XpInterPriInt);        }        else        {            rc = XP_ERROR_INTER_NOTIFY_CMD;        }    }    /*------------------------------------------------------------------------+    |  Recalculate the mask and write it    |  Always turn on the STATUS, IREQ, AUDIO & VIDEO bits    +------------------------------------------------------------------------*/    if (rc == 0)    {        for(i=0, pGlobal->InterInfo.XpInterPriMask=0;                i<pGlobal->InterInfo.XpInterPriInt.wNotifyAlloc; i++)                {                    pGlobal->InterInfo.XpInterPriMask |=                        pGlobal->InterInfo.XpInterPriInt.pNotify[i].ulMask;                }                if(pGlobal->uDeviceIndex == 0)                {                    dcr_mask = pGlobal->InterInfo.XpInterPriMask | XP0_PRIMARY_SET_MASK;                }                else                {                    dcr_mask = pGlobal->InterInfo.XpInterPriMask | XP12_PRIMARY_SET_MASK;                }#ifdef __DRV_FOR_VESTA__            dcr_mask = pGlobal->InterInfo.XpInterChanMask | pGlobal->InterInfo.XpInterPriMask | XP0_PRIMARY_SET_MASK;#endif                flag = os_enter_critical_section();                xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_INTMASK, dcr_mask);                os_leave_critical_section(flag);    }    os_leave_critical_section(flag);    return(rc);}/*----------------------------------------------------------------------------+|  xp0_interrupt_status_notify+-----------------------------------------------------------------------------+||  DESCRIPTION:  register a callback function for demux status interrupts||  PROTOTYPE  :  short xp0_interrupt_status_notify(|                short cmd,|                unsigned long int_mask,|                PFS notify_fn)||  ARGUMENTS  :  cmd           -  XP_INTERRUPT_NOTIFY_ADD to add a function|                                 XP_INTERRUPT_NOTIFY_DELETE to remove|                int_mask      -  interrupts to register function for|                notify_fn     -  notification function to call-back||  RETURNS    :  0 if successful, or non-zero if an error occurs||  ERRORS     :  XP_ERROR_INTER_NOTIFY_CMD - invalid command specified in 'cmd'||  COMMENTS   :  This function registers a callback function to be called|                when at least one of the interrupt bits matches a bit|                in the 'int_mask' argument.  The interrupt bits are|                defined in the 'xp0_interrupt.h' header file.|+----------------------------------------------------------------------------*/SHORT xp_osi_interrupt_status_notify(GLOBAL_RESOURCES *pGlobal,SHORT wCmd,ULONG ulIntMask,                                     PFS notify_fn){    short rc;    short i;    unsigned long dcr_mask;    UINT32  flag;    flag = os_enter_critical_section();    if(notify_fn == NULL)    {        rc = XP_ERROR_INTER_NOTIFY_INVALID;    }    /*------------------------------------------------------------------------+    |  if the function is NULL, then find the matching mask and cancel    |  the callback function    +------------------------------------------------------------------------*/    else    {        if(pGlobal->uDeviceIndex == 0)            ulIntMask &= XP0_FESTAT_INTERRUPT_MASK;        else            ulIntMask &= XP12_FESTAT_INTERRUPT_MASK;        if(wCmd == XP_INTERRUPT_NOTIFY_DELETE)        {            rc = del_mask(pGlobal,ulIntMask, notify_fn, &pGlobal->InterInfo.XpInterStatInt);        }        else if(wCmd == XP_INTERRUPT_NOTIFY_ADD)        {            rc = add_mask(pGlobal,ulIntMask, notify_fn, &pGlobal->InterInfo.XpInterStatInt);        }        else        {            rc = XP_ERROR_INTER_NOTIFY_CMD;        }    }    /*------------------------------------------------------------------------+    |  Recalculate the mask and write it    +------------------------------------------------------------------------*/    if (rc == 0)    {        for(i=0, dcr_mask=0; i<pGlobal->InterInfo.XpInterStatInt.wNotifyAlloc; i++)        {            dcr_mask |= pGlobal->InterInfo.XpInterStatInt.pNotify[i].ulMask;        }        xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_FEIMASK, dcr_mask);    }    os_leave_critical_section(flag);    return(rc);}int xp_osi_interrupt_de_init(GLOBAL_RESOURCES *pGlobal){    int rc = 0;    if(pGlobal->uDeviceIndex == 0)        return os_delete_irq_task(XP_IRQ);        else if(pGlobal->uDeviceIndex == 1)                rc = xp_osi_interrupt_notify(pXp0Global,XP_INTERRUPT_NOTIFY_DELETE,                XP_INTERRUPT_IR_X1INT, (PFS)xp1_interrupt);        else if(pGlobal->uDeviceIndex == 2)                rc = xp_osi_interrupt_notify(pXp0Global,XP_INTERRUPT_NOTIFY_DELETE,                XP_INTERRUPT_IR_X2INT, (PFS)xp2_interrupt);    return 0;}

⌨️ 快捷键说明

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