/* * Have got an event to handle: */ fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { int ret, retval = 0, status = 0; trace_kernel_irq_entry(irq, !(user_mode(regs))); if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); do { ret = action->handler(irq, action->dev_id, regs); if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); trace_kernel_irq_exit(); return retval; }
/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @regs: pointer to a register structure * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; trace_irq_entry(irq, regs); handle_dynamic_tick(action); if (!(action->flags & IRQF_DISABLED)) local_irq_enable_in_hardirq(); do { ret = action->handler(irq, action->dev_id, regs); if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); trace_irq_exit(irq, retval); return retval; }
static inline void device_interrupt(int irq, int ack, struct pt_regs * regs) { struct irqaction * action; if ((unsigned) irq > NR_IRQS) { printk("device_interrupt: unexpected interrupt %d\n", irq); return; } kstat.interrupts[irq]++; action = irq_action[irq]; /* * For normal interrupts, we mask it out, and then ACK it. * This way another (more timing-critical) interrupt can * come through while we're doing this one. * * Note! A irq without a handler gets masked and acked, but * never unmasked. The autoirq stuff depends on this (it looks * at the masks before and after doing the probing). */ mask_irq(ack); ack_irq(ack); if (!action) return; if (action->flags & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); do { action->handler(irq, action->dev_id, regs); action = action->next; } while (action); unmask_irq(ack); }
/* * This should really return information about whether * we should do bottom half handling etc. Right now we * end up _always_ checking the bottom half, which is a * waste of time and is not what some drivers would * prefer. */ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) { int status; int cpu = smp_processor_id(); irq_enter(cpu, irq); status = 1; /* Force the "do bottom halves" bit */ if (!(action->flags & SA_INTERRUPT)) __sti(); do { status |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); __cli(); irq_exit(cpu, irq); return status; }
static void sn1_handle_irq(int irq, void *dummy, struct pt_regs *regs) { int bit, cnode; struct sn1_cnode_action_list *alp; struct sn1_intr_action *ap; void (*handler)(int, void *, struct pt_regs *); unsigned long flags = 0; int cpuid = smp_processor_id(); bit = irq_to_bit_pos(irq); LOCAL_HUB_CLR_INTR(bit); cnode = cpuid_to_cnodeid(cpuid); alp = sn1_node_actions[cnode]; ap = alp[irq].action_list; if (ap == NULL) { return; } while (ap) { flags |= ap->flags; handler = ap->handler; (*handler)(irq,ap->intr_arg,regs); ap = ap->next; } if ((flags & SA_SAMPLE_RANDOM) != 0) add_interrupt_randomness(irq); return; }
/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; struct pt_regs *regs = get_irq_regs(); trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u", irq, (regs)?(!user_mode(regs)):(1)); handle_dynamic_tick(action); if (!(action->flags & IRQF_DISABLED)) local_irq_enable_in_hardirq(); do { ret = action->handler(irq, action->dev_id); if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); trace_mark(kernel_irq_exit, MARK_NOARGS); return retval; }
asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { struct irqaction *action; int do_random, cpu; cpu = smp_processor_id(); irq_enter(cpu); kstat.irqs[cpu][irq]++; action = irq_action[irq]; if (action) { if (!(action->flags & SA_INTERRUPT)) __sti(); action = irq_action[irq]; do_random = 0; do { do_random |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); __cli(); } irq_exit(cpu); if (softirq_pending(cpu)) do_softirq(); /* unmasking and bottom half handling is done magically for us. */ }
static int inline handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) #endif { int status; int cpu = smp_processor_id(); irq_enter(cpu, irq); status = 1; /* Force the "do bottom halves" bit */ #if 0 if (!(action->flags & SA_INTERRUPT)) __sti(); #endif //sc_yang => open shared IRQ #if 1 //#ifndef JACKSON_NET_WORK do { status |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); #else action->handler(irq, action->dev_id, regs); #endif //__cli(); irq_exit(cpu, irq); return status; }
/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; handle_dynamic_tick(action); //如果第一个处理程序函数中没有设置IRQF_DISABLED, //则用local_irq_enable_in_hardirq启用(当前CPU的)中断。 //换句话说,该处理程序可以被其他IRQ中断。但根据电流类型, //也可能一直屏蔽刚处理的IRQ if (!(action->flags & IRQF_DISABLED)) local_irq_enable_in_hardirq(); //在共享IRQ时 do { ret = action->handler(irq, action->dev_id); if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); //如果该IRQ设置了IRQF_SAMPLE_RANDOM, //则调用add_interrupt_randomness,将事件的时间作为熵池的一个源 //(如果中断是随机发生的,那么他们是理想的源) if (status & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq); //禁用中断。 //因为中断的启用和禁用是不嵌套的,与中断在处理开始时是否启用是不相关的。 //handle_IRQ_event在调用时禁用中断,在退出时然然预期禁用中断 local_irq_disable(); return retval; }
/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; do { trace_irq_handler_entry(irq, action); ret = action->handler(irq, action->dev_id); trace_irq_handler_exit(irq, action, ret); switch (ret) { case IRQ_WAKE_THREAD: /* * Set result to handled so the spurious check * does not trigger. */ ret = IRQ_HANDLED; /* * Catch drivers which return WAKE_THREAD but * did not set up a thread function */ if (unlikely(!action->thread_fn)) { warn_no_thread(irq, action); break; } /* * Wake up the handler thread for this * action. In case the thread crashed and was * killed we just pretend that we handled the * interrupt. The hardirq handler above has * disabled the device interrupt, so no irq * storm is lurking. */ if (likely(!test_bit(IRQTF_DIED, &action->thread_flags))) { set_bit(IRQTF_RUNTHREAD, &action->thread_flags); wake_up_process(action->thread); } /* Fall through to add to randomness */ case IRQ_HANDLED: status |= action->flags; break; default: break; } retval |= ret; action = action->next; } while (action); if (status & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); return retval; }
/* * do_IRQ handles IRQ's that have been installed without the * SA_INTERRUPT flag: it uses the full signal-handling return * and runs with other interrupts enabled. All relatively slow * IRQ's should use this format: notably the keyboard/timer * routines. */ static void do_IRQ(int irq, struct pt_regs * regs) { struct irqaction *action; int do_random, cpu; cpu = smp_processor_id(); irq_enter(cpu); kstat.irqs[cpu][irq]++; mask_irq(irq); action = *(irq + irq_action); if (action) { if (!(action->flags & SA_INTERRUPT)) __sti(); action = *(irq + irq_action); do_random = 0; do { do_random |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); __cli(); } else { printk("do_IRQ: Unregistered IRQ (0x%X) occured\n", irq); } unmask_irq(irq); irq_exit(cpu); /* unmasking and bottom half handling is done magically for us. */ }
irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) { irqreturn_t retval = IRQ_NONE; unsigned int random = 0, irq = desc->irq_data.irq; do { irqreturn_t res; #ifdef CONFIG_SEC_DEBUG sec_debug_timer_log(4444, (int)irqs_disabled(), (void *)action->handler); #endif trace_irq_handler_entry(irq, action); res = action->handler(irq, action->dev_id); trace_irq_handler_exit(irq, action, res); #ifdef CONFIG_SEC_DEBUG sec_debug_timer_log(5555, (int)irqs_disabled(), (void *)action->handler); /* sec_debug_irq_sched_log(irq, (void *)action->handler, 2); */ #endif if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n", irq, action->handler)) local_irq_disable(); switch (res) { case IRQ_WAKE_THREAD: /* * Catch drivers which return WAKE_THREAD but * did not set up a thread function */ if (unlikely(!action->thread_fn)) { warn_no_thread(irq, action); break; } irq_wake_thread(desc, action); /* Fall through to add to randomness */ case IRQ_HANDLED: random |= action->flags; break; default: break; } retval |= res; action = action->next; } while (action); if (random & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq); if (!noirqdebug) note_interrupt(irq, desc, retval); return retval; }
irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) { irqreturn_t retval = IRQ_NONE; unsigned int flags = 0, irq = desc->irq_data.irq; #ifdef CONFIG_FOOTPRINT_IRQ update_handle_irqs_this_cpu(irq); #endif do { irqreturn_t res; trace_irq_handler_entry(irq, action); res = action->handler(irq, action->dev_id); trace_irq_handler_exit(irq, action, res); if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n", irq, action->handler)) local_irq_disable(); switch (res) { case IRQ_WAKE_THREAD: /* * Catch drivers which return WAKE_THREAD but * did not set up a thread function */ if (unlikely(!action->thread_fn)) { warn_no_thread(irq, action); break; } irq_wake_thread(desc, action); /* Fall through to add to randomness */ case IRQ_HANDLED: flags |= action->flags; break; default: break; } retval |= res; action = action->next; } while (action); add_interrupt_randomness(irq, flags); if (!noirqdebug) note_interrupt(irq, desc, retval); #ifdef CONFIG_FOOTPRINT_IRQ release_handle_irqs_this_cpu(irq); #endif return retval; }
irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) { irqreturn_t retval = IRQ_NONE; unsigned int flags = 0, irq = desc->irq_data.irq; while (action) { irqreturn_t res; if(!action->handler) { printk(KERN_WARNING "IRQ %d device %s get event " "but no action handle function available.", irq, action->name); action = action->next; continue; } trace_irq_handler_entry(irq, action); res = action->handler(irq, action->dev_id); trace_irq_handler_exit(irq, action, res); if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n", irq, action->handler)) local_irq_disable(); switch (res) { case IRQ_WAKE_THREAD: /* * Catch drivers which return WAKE_THREAD but * did not set up a thread function */ if (unlikely(!action->thread_fn)) { warn_no_thread(irq, action); break; } irq_wake_thread(desc, action); /* Fall through to add to randomness */ case IRQ_HANDLED: flags |= action->flags; break; default: break; } retval |= res; action = action->next; } add_interrupt_randomness(irq, flags); if (!noirqdebug) note_interrupt(irq, desc, retval); return retval; }
irqreturn_t handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action) { irqreturn_t retval = IRQ_NONE; unsigned int random = 0, irq = desc->irq_data.irq; do { irqreturn_t res; trace_irq_handler_entry(irq, action); res = action->handler(irq, action->dev_id); trace_irq_handler_exit(irq, action, res); if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n", irq, action->handler)) local_irq_disable(); switch (res) { case IRQ_WAKE_THREAD: /* * Set result to handled so the spurious check * does not trigger. */ res = IRQ_HANDLED; /* * Catch drivers which return WAKE_THREAD but * did not set up a thread function */ if (unlikely(!action->thread_fn)) { warn_no_thread(irq, action); break; } irq_wake_thread(desc, action); /* Fall through to add to randomness */ case IRQ_HANDLED: random |= action->flags; break; default: break; } retval |= res; action = action->next; } while (action); if (random & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq); if (!noirqdebug) note_interrupt(irq, desc, retval); return retval; }
/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; #ifdef __i386__ if (debug_direct_keyboard && irq == 1) lockdep_off(); #endif handle_dynamic_tick(action); /* * Unconditionally enable interrupts for threaded * IRQ handlers: */ if (!hardirq_count() || !(action->flags & IRQF_DISABLED)) local_irq_enable(); do { unsigned int preempt_count = preempt_count(); ret = action->handler(irq, action->dev_id); if (preempt_count() != preempt_count) { stop_trace(); print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler); printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count()); dump_stack(); preempt_count() = preempt_count; } if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & IRQF_SAMPLE_RANDOM) { local_irq_enable(); add_interrupt_randomness(irq); } local_irq_disable(); #ifdef __i386__ if (debug_direct_keyboard && irq == 1) lockdep_on(); #endif return retval; }
asmlinkage void process_int(int irq, struct pt_regs *fp) { irq_enter(); h8300_clear_isr(irq); if (irq >= NR_TRAPS && irq < NR_IRQS) { if (irq_list[irq]) { irq_list[irq]->handler(irq, irq_list[irq]->dev_id, fp); irq_list[irq]->count++; if (irq_list[irq]->flags & IRQF_SAMPLE_RANDOM) add_interrupt_randomness(irq); } } else { BUG(); } irq_exit(); }
static void usbic_device_irq(u32 irq, irq_desc_t * desc) { struct irqaction * action; const u32 cpu = smp_processor_id(); desc->status |= IRQ_LEVEL; if(!desc->depth) { kstat_cpu(cpu).irqs[irq]++; action = desc->action; if(action) { int ret; int status = 0; int retval = 0; local_irq_enable(); do{ ret = action->handler(irq, action->dev_id); if(ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; }while(action); if(status & IRQF_SAMPLE_RANDOM) { // kmsg("sample randomness\n"); add_interrupt_randomness(irq); } local_irq_disable(); if(retval != IRQ_HANDLED) ; // kmsg("Error!!! irq %d cannot handle irq\n", irq); } else ;// kmsg("irq %d has no ISR\n", irq); } else ; // kmsg("irq %d is disabled\n",irq); }
/* * do_IRQ handles IRQ's that have been installed without the * SA_INTERRUPT flag: it uses the full signal-handling return * and runs with other interrupts enabled. All relatively slow * IRQ's should use this format: notably the keyboard/timer * routines. */ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { struct irqaction * action = *(irq + irq_action); int do_random = 0; int c,intm,mask; #ifdef IRQ_DEBUG static int count; if (smp_processor_id() != 0 && count++ < 1000) printk("IRQ %d: done by CPU %d\n",irq,smp_processor_id()); #endif if (irq >= 8) { c = cache_A1; intm = inb(0xA1); mask = 1 << (irq - 8); } else { c = cache_21; intm = inb(0x21); mask = 1 << irq; } if (!(c & mask) || !(intm & mask)) { #ifdef IRQ_DEBUG printk("IRQ %d (proc %d):cache_x1=0x%x,INT mask=0x%x\n", irq, smp_processor_id(),c,intm); #endif /* better to return because the interrupt may be asserted again, the bad thing is that we may loose some interrupts */ return; } #ifdef __SMP__ if(smp_threads_ready && active_kernel_processor!=smp_processor_id()) panic("IRQ %d: active processor set wrongly(%d not %d).\n", irq, active_kernel_processor, smp_processor_id()); #endif kstat.interrupts[irq]++; #ifdef __SMP_PROF__ int_count[smp_processor_id()][irq]++; #endif while (action) { do_random |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); }
asmlinkage void process_int(int vec, struct pt_regs *fp) { irq_enter(0,0); /* ISR clear */ /* compatible i386 */ if (vec >= EXT_IRQ0 && vec <= EXT_IRQ5) *(volatile unsigned char *)ISR &= ~(1 << (vec - EXT_IRQ0)); if (vec < NR_IRQS) { if (irq_list[vec]) { irq_list[vec]->handler(vec, irq_list[vec]->dev_id, fp); irq_list[vec]->count++; if (irq_list[vec]->flags & SA_SAMPLE_RANDOM) add_interrupt_randomness(vec); } } else { BUG(); } irq_exit(0,0); }
/** * handle_IRQ_event - irq action chain handler * @irq: the interrupt number * @regs: pointer to a register structure * @action: the interrupt action chain for this irq * * Handles the action chain of an irq event */ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { irqreturn_t ret, retval = IRQ_NONE; unsigned int status = 0; MARK(kernel_irq_entry, "%u %u", irq, (regs)?(!user_mode(regs)):(1)); handle_dynamic_tick(action); /* * Unconditionally enable interrupts for threaded * IRQ handlers: */ if (!hardirq_count() || !(action->flags & IRQF_DISABLED)) local_irq_enable(); do { unsigned int preempt_count = preempt_count(); ret = action->handler(irq, action->dev_id, regs); if (preempt_count() != preempt_count) { stop_trace(); print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler); printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count()); dump_stack(); preempt_count() = preempt_count; } if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & IRQF_SAMPLE_RANDOM) { local_irq_enable(); add_interrupt_randomness(irq); } local_irq_disable(); MARK(kernel_irq_exit, MARK_NOARGS); return retval; }
/* * This is a threaded interrupt handler so we can make some * I2C calls etc. */ static irqreturn_t ab3100_irq_handler(int irq, void *data) { struct ab3100 *ab3100 = data; u8 event_regs[3]; u32 fatevent; int err; add_interrupt_randomness(irq); err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, event_regs, 3); if (err) goto err_event; fatevent = (event_regs[0] << 16) | (event_regs[1] << 8) | event_regs[2]; if (!ab3100->startup_events_read) { ab3100->startup_events[0] = event_regs[0]; ab3100->startup_events[1] = event_regs[1]; ab3100->startup_events[2] = event_regs[2]; ab3100->startup_events_read = true; } /* * The notified parties will have to mask out the events * they're interested in and react to them. They will be * notified on all events, then they use the fatevent value * to determine if they're interested. */ blocking_notifier_call_chain(&ab3100->event_subscribers, fatevent, NULL); dev_dbg(ab3100->dev, "IRQ Event: 0x%08x\n", fatevent); return IRQ_HANDLED; err_event: dev_dbg(ab3100->dev, "error reading event status\n"); return IRQ_HANDLED; }
static irqreturn_t ab3100_irq_handler(int irq, void *data) { struct ab3100 *ab3100 = data; u8 event_regs[3]; u32 fatevent; int err; add_interrupt_randomness(irq); err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, event_regs, 3); if (err) goto err_event; fatevent = (event_regs[0] << 16) | (event_regs[1] << 8) | event_regs[2]; if (!ab3100->startup_events_read) { ab3100->startup_events[0] = event_regs[0]; ab3100->startup_events[1] = event_regs[1]; ab3100->startup_events[2] = event_regs[2]; ab3100->startup_events_read = true; } /* */ blocking_notifier_call_chain(&ab3100->event_subscribers, fatevent, NULL); dev_dbg(ab3100->dev, "IRQ Event: 0x%08x\n", fatevent); return IRQ_HANDLED; err_event: dev_dbg(ab3100->dev, "error reading event status\n"); return IRQ_HANDLED; }
asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { struct irqaction *action; int do_random, cpu; int retval = 0; cpu = smp_processor_id(); irq_enter(); kstat_cpu(cpu).irqs[irq]++; action = irq_action[irq]; if (action) { if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); action = irq_action[irq]; do_random = 0; do { do_random |= action->flags; retval |= action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (retval != 1) { if (retval) { printk("irq event %d: bogus retval mask %x\n", irq, retval); } else { printk("irq %d: nobody cared\n", irq); } } if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); } irq_exit(); if (softirq_pending(cpu)) do_softirq(); /* unmasking and bottom half handling is done magically for us. */ }
int Loop() { pid_t pid; int status; while(link_count > 0) { pid = Receive(0, &msg, sizeof(msg)); if(pid == -1) { if(errno != EINTR) { Log("Receive() failed: [%d] %s", ERR(errno)); } continue; } if(pid == IrqProxy()) { while(Creceive(pid, 0, 0) == pid) ; // clear out any proxy overruns add_interrupt_randomness(options.irq); // Log("Irq: random size %d\n", get_random_size()); // now that we have more entropy... SelectTrigger(); DoReadQueue(); continue; } status = Service(pid, &msg); Log("Service() returned status %d (%s), link_count %d", status, status == -1 ? "none" : strerror(status), link_count); if(status >= EOK) { msg.status = status; ReplyMsg(pid, &msg, sizeof(msg.status)); } } return 0; }
static void __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) { unsigned int status; spin_unlock(&irq_controller_lock); if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); status = 0; do { status |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); spin_lock_irq(&irq_controller_lock); }
int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { int status = 1; /* Force the "do bottom halves" bit */ do { if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); else local_irq_disable(); status |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); return status; }
asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { struct irqaction *action; int do_random, cpu; int ret, retval = 0; cpu = smp_processor_id(); irq_enter(); kstat_cpu(cpu).irqs[irq - FIRST_IRQ]++; action = irq_action[irq - FIRST_IRQ]; if (action) { if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); do_random = 0; do { ret = action->handler(irq, action->dev_id, regs); if (ret == IRQ_HANDLED) do_random |= action->flags; retval |= ret; action = action->next; } while (action); if (retval != 1) { if (retval) { printk("irq event %d: bogus retval mask %x\n", irq, retval); } else { printk("irq %d: nobody cared\n", irq); } } if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); } irq_exit(); }
/* * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return * stuff - the handler is also running with interrupts disabled unless * it explicitly enables them later. */ asmlinkage void do_fast_IRQ(int irq) { struct irqaction * action = *(irq + irq_action); int do_random = 0; #ifdef __SMP__ /* IRQ 13 is allowed - that's a flush tlb */ if(smp_threads_ready && active_kernel_processor!=smp_processor_id() && irq!=13) panic("fast_IRQ %d: active processor set wrongly(%d not %d).\n", irq, active_kernel_processor, smp_processor_id()); #endif kstat.interrupts[irq]++; #ifdef __SMP_PROF__ int_count[smp_processor_id()][irq]++; #endif while (action) { do_random |= action->flags; action->handler(irq, action->dev_id, NULL); action = action->next; } if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); }
/* * Have got an event to handle: */ fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { int ret, retval = 0, status = 0; /* * Unconditionally enable interrupts for threaded * IRQ handlers: */ if (!hardirq_count() || !(action->flags & SA_INTERRUPT)) local_irq_enable(); do { unsigned int preempt_count = preempt_count(); ret = action->handler(irq, action->dev_id, regs); if (preempt_count() != preempt_count) { stop_trace(); print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler); printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count()); dump_stack(); preempt_count() = preempt_count; } if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) { local_irq_enable(); add_interrupt_randomness(irq); } local_irq_disable(); return retval; }