1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
/*
* RTLinux signal support
*
* Written by Michael Barabanov
* Copyright (C) Finite State Machine Labs Inc., 2000
* Released under the terms of the GPL Version 2
*
*/
#include <signal.h>
#include <errno.h>
#include <rtl_core.h>
#include <asm/irq.h>
static struct sigaction sigact [RTL_SIGIRQMAX];
unsigned int rtl_sig_interrupt (unsigned int irq, struct pt_regs *regs)
{
int sig = irq + RTL_SIGIRQMIN;
if (sigact[sig].sa_handler != SIG_IGN && sigact[sig].sa_handler != SIG_DFL) {
sigact[sig].sa_sigaction(sig, NULL, NULL);
}
/* shall we reenable here? */
return 0;
}
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
int irq = -1;
if (act && (act->sa_flags & SA_IRQ)) {
irq = sig;
} else {
/* for now, only hard global interrupts */
if (sig < RTL_SIGIRQMIN || sig >= RTL_SIGIRQMIN + NR_IRQS) {
errno = EINVAL;
return -1;
}
irq = sig - RTL_SIGIRQMIN;
}
if (oact) {
*oact = sigact[sig];
rtl_irq_set_affinity(irq, NULL, &oact->sa_focus);
}
if (!act) {
return 0;
}
if (sigact[sig].sa_handler != act->sa_handler) {
/* free old irq first if needed */
if (sigact[sig].sa_handler != SIG_IGN
&& sigact[sig].sa_handler != SIG_DFL) {
/* rtl_printf("freeing %d\n", sig - RTL_SIGIRQMIN); */
rtl_free_global_irq (irq);
}
/* now request */
if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) {
sigact[sig] = *act;
/* rtl_printf("requesting %d\n", sig - RTL_SIGIRQMIN); */
rtl_request_global_irq (irq, rtl_sig_interrupt);
}
}
if (act->sa_flags & SA_FOCUS) {
rtl_irq_set_affinity (irq, &act->sa_focus, NULL);
}
sigact[sig].sa_handler = act->sa_handler;
sigact[sig].sa_flags = act->sa_flags;
sigact[sig].sa_focus = act->sa_focus;
sigact[sig].sa_mask = act->sa_mask;
return 0;
}
|