int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq) { rtems_interrupt_level level; printk(" BSP_install_rtems_irq_handler %d\n", irq->name ); if (!isValidInterrupt(irq->name)) { printk("Invalid interrupt vector %d\n",irq->name); return 0; } /* * Check if default handler is actually connected. If not issue an error. * You must first get the current handler via i386_get_current_idt_entry * and then disconnect it using i386_delete_idt_entry. * RATIONALE : to always have the same transition by forcing the user * to get the previous handler before accepting to disconnect. */ rtems_interrupt_disable(level); if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) { rtems_interrupt_enable(level); printk("IRQ vector %d already connected\n",irq->name); return 0; } /* * store the data provided by user */ rtems_hdl_tbl[irq->name] = *irq; rtems_hdl_tbl[irq->name].next_handler = (void *)-1; /* XXX -FIX ME !! */ if (is_pci_irq(irq->name)) { /* * Enable interrupt */ printk("is_pci_irq = TRUE - FIX THIS!\n"); } if (is_processor_irq(irq->name)) { /* * Enable exception at processor level */ printk("is_processor_irq = TRUE : Fix This\n"); } /* * Enable interrupt on device */ if (irq->on) { printk("Call 0x%x\n", irq->on ); irq->on(irq); } rtems_interrupt_enable(level); return 1; }
/* * ------------------------ RTEMS Shared Irq Handler Mngt Routines ---------------- */ int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq) { rtems_interrupt_level level; rtems_irq_connect_data* vchain; printk(" BSP_install_rtems_shared_irq_handler %d\n", irq->name ); if (!isValidInterrupt(irq->name)) { printk("Invalid interrupt vector %d\n",irq->name); return 0; } rtems_interrupt_disable(level); if ( (int)rtems_hdl_tbl[irq->name].next_handler == -1 ) { rtems_interrupt_enable(level); printk("IRQ vector %d already connected to an unshared handler\n",irq->name); return 0; } vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data)); /* save off topmost handler */ vchain[0]= rtems_hdl_tbl[irq->name]; /* * store the data provided by user */ rtems_hdl_tbl[irq->name] = *irq; /* link chain to new topmost handler */ rtems_hdl_tbl[irq->name].next_handler = (void *)vchain; /* * XXX FIX ME */ if (is_pci_irq(irq->name)) { } if (is_processor_irq(irq->name)) { /* * Enable exception at processor level */ } /* * Enable interrupt on device */ if (irq->on) irq->on(irq); rtems_interrupt_enable(level); return 1; }
int BSP_disable_irq_at_pic(const rtems_irq_number name) { #if BSP_ISA_IRQ_NUMBER > 0 if (is_isa_irq(name)) { /* * disable interrupt at PIC level */ return BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET); } #endif #if BSP_PCI_IRQ_NUMBER > 0 if (is_pci_irq(name)) { /* * disable interrupt at OPENPIC level */ return openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET); } #endif return -1; }
void BSP_enable_irq_at_pic(const rtems_irq_number name) { #if BSP_ISA_IRQ_NUMBER > 0 if (is_isa_irq(name)) { /* * Enable interrupt at PIC level */ BSP_irq_enable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET); } #endif #if BSP_PCI_IRQ_NUMBER > 0 if (is_pci_irq(name)) { /* * Enable interrupt at OPENPIC level */ openpic_enable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET); } #endif }
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq) { rtems_irq_connect_data *pchain= NULL, *vchain = NULL; rtems_interrupt_level level; printk(" BSP_remove_rtems_irq_handler %d\n", irq->name ); if (!isValidInterrupt(irq->name)) { return 0; } /* * Check if default handler is actually connected. If not issue an error. * You must first get the current handler via i386_get_current_idt_entry * and then disconnect it using i386_delete_idt_entry. * RATIONALE : to always have the same transition by forcing the user * to get the previous handler before accepting to disconnect. */ rtems_interrupt_disable(level); if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) { rtems_interrupt_enable(level); return 0; } if( (int)rtems_hdl_tbl[irq->name].next_handler != -1 ) { int found = 0; for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]); (vchain->hdl != default_rtems_entry.hdl); (pchain= vchain, vchain = (rtems_irq_connect_data*)vchain->next_handler) ) { if( vchain->hdl == irq->hdl ) { found= -1; break; } } if( !found ) { rtems_interrupt_enable(level); return 0; } } else { if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) { rtems_interrupt_enable(level); return 0; } } /* XXX - FIX ME !! */ if (is_pci_irq(irq->name)) { /* * disable interrupt */ } if (is_processor_irq(irq->name)) { /* * disable exception at processor level */ } /* * Disable interrupt on device */ if (irq->off) irq->off(irq); /* * restore the default irq value */ if( !vchain ) { /* single handler vector... */ rtems_hdl_tbl[irq->name] = default_rtems_entry; } else { if( pchain ) { /* non-first handler being removed */ pchain->next_handler = vchain->next_handler; } else { /* first handler isn't malloc'ed, so just overwrite it. Since the contents of vchain are being struct copied, vchain itself goes away */ rtems_hdl_tbl[irq->name]= *vchain; } free(vchain); } rtems_interrupt_enable(level); return 1; }