📄 xp_osi_inter.c
字号:
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 + -