source: drsdaq/VME/struck/sis1100/V2.02/dev/pci/sis1100_irq_thread.c@ 23

Last change on this file since 23 was 22, checked in by ogrimm, 16 years ago
First commit of drsdaq program
File size: 5.4 KB
Line 
1/* $ZEL: sis1100_irq_thread.c,v 1.5 2004/05/27 23:10:24 wuestner Exp $ */
2
3/*
4 * Copyright (c) 2002-2004
5 * Peter Wuestner. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include "sis1100_sc.h"
30
31/*
32 * this is a kernel thread which sleeps on sc->handler_wait;
33 * it is waked up by doorbell irq, irq_synch_chg, irq_lemo_in_chg
34 * and link_up_timer;
35 * it is responsable to inform the user process about VME interrupts,
36 * CAMAC LAMs, interrupts caused by front panel IO and insertion or removal
37 * of the optical link
38 */
39
40#if !defined(__NetBSD__) && ! defined(__linux__)
41#error Wrong Operating System
42#endif
43
44static void
45_sis1100_irq_thread(struct sis1100_softc* sc, enum handlercomm command)
46{
47 struct list_head* curr;
48 if (command&handlercomm_doorbell) {
49 switch (sc->remote_hw) {
50 case sis1100_hw_vme:
51 sis3100rem_irq_handler(sc);
52 break;
53 case sis1100_hw_camac:
54 sis5100rem_irq_handler(sc);
55 break;
56 case sis1100_hw_pci: break; /* do nothing */
57 case sis1100_hw_f1: break; /* do nothing */
58 case sis1100_hw_vertex: break; /* do nothing */
59 case sis1100_hw_invalid: break; /* do nothing */
60 }
61 }
62
63 if (command&handlercomm_lemo) {
64 sis1100_lemo_handler(sc);
65 }
66
67 if (command&handlercomm_mbx0) {
68 sis1100_mbox0_handler(sc);
69 }
70
71 if (command&handlercomm_synch) {
72 sis1100_synch_handler(sc);
73 }
74
75 list_for_each(curr, &sc->fdata_list_head) {
76 struct sis1100_fdata* fd;
77 fd=list_entry(curr, struct sis1100_fdata, list);
78 if (fd->sig && (fd->sig!=-1) &&
79 ((sc->new_irqs & fd->owned_irqs)||
80 (sc->old_remote_hw!=sc->remote_hw))) {
81#ifdef __linux__
82 int res;
83 /* res=kill_proc_info(fd->sig, (void*)0, fd->pid); */
84 /* replaced according to struck */
85 res=kill_proc(fd->pid,fd->sig,0);
86 if (res)
87 pINFO(sc, "send sig %d to %d: res=%d", fd->sig, fd->pid, res);
88#elif __NetBSD__
89 psignal(fd->p, fd->sig);
90#endif
91 }
92 }
93#ifdef __NetBSD__
94 wakeup(&sc->remoteirq_wait);
95 selwakeup(&sc->sel);
96#elif __linux__
97 wake_up_interruptible(&sc->remoteirq_wait);
98#endif
99}
100
101#ifdef __linux__
102int
103#else
104void
105#endif
106sis1100_irq_thread(void* data)
107{
108 struct sis1100_softc* sc=(struct sis1100_softc*)data;
109 enum handlercomm command;
110 DECLARE_SPINLOCKFLAGS(flags);
111
112 pINFO(sc, "sis1100_irq_thread started");
113
114#ifdef __linux__
115#if LINUX_VERSION_CODE < 0x20600
116 daemonize();
117 snprintf(current->comm, sizeof(current->comm), "sis1100_%02d", sc->unit);
118 SPIN_LOCK_IRQSAVE(current->sigmask_lock, flags);
119 sigemptyset(&current->blocked);
120 recalc_sigpending(current);
121 SPIN_UNLOCK_IRQRESTORE(current->sigmask_lock, flags);
122#else
123 daemonize("sis1100_%02d", sc->unit);
124 SPIN_LOCK_IRQSAVE(current->sighand->siglock, flags);
125 sigemptyset(&current->blocked);
126 recalc_sigpending();
127 SPIN_UNLOCK_IRQRESTORE(current->sighand->siglock, flags);
128#endif
129#endif /*__linux__*/
130
131 while (1) {
132#ifdef __NetBSD__
133 tsleep(&sc->handler_wait, PCATCH, "thread_vmeirq", 0);
134#elif __linux__
135 wait_event(sc->handler_wait, sc->handlercommand.command);
136#endif
137 SPIN_LOCK_IRQSAVE(sc->handlercommand.lock, flags);
138 command=sc->handlercommand.command;
139 sc->handlercommand.command=0;
140 SPIN_UNLOCK_IRQRESTORE(sc->handlercommand.lock, flags);
141
142 /*pINFO(sc, "irq_thread aufgewacht, command=0x%x", command);*/
143
144 sc->new_irqs=0;
145
146 if (command&handlercomm_die) {
147 pINFO(sc, "sis1100_irq_thread terminated");
148#ifdef __NetBSD__
149 SPIN_LOCK_IRQSAVE(sc->handlercommand.lock, flags);
150 sc->handlercommand.command=0;
151 wakeup(sc);
152 SPIN_UNLOCK_IRQRESTORE(sc->handlercommand.lock, flags);
153 kthread_exit(0);
154#elif __linux__
155 complete_and_exit(&sc->handler_completion, 0);
156#endif
157 }
158 _sis1100_irq_thread(sc, command);
159
160#ifdef __linux__
161 if (signal_pending (current)) {
162 SPIN_LOCK_IRQSAVE(current->SIGMASK_LOCK, flags);
163 flush_signals(current);
164 SPIN_UNLOCK_IRQRESTORE(current->SIGMASK_LOCK, flags);
165 }
166#endif /*__linux__*/
167
168 }
169#ifdef __linux__
170 return 0;
171#endif
172}
Note: See TracBrowser for help on using the repository browser.