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 if (res)
85 pINFO(sc, "send sig %d to %d: res=%d", fd->sig, fd->pid, res);
86#elif __NetBSD__
87 psignal(fd->p, fd->sig);
88#endif
89 }
90 }
91#ifdef __NetBSD__
92 wakeup(&sc->remoteirq_wait);
93 selwakeup(&sc->sel);
94#elif __linux__
95 wake_up_interruptible(&sc->remoteirq_wait);
96#endif
97}
98
99#ifdef __linux__
100int
101#else
102void
103#endif
104sis1100_irq_thread(void* data)
105{
106 struct sis1100_softc* sc=(struct sis1100_softc*)data;
107 enum handlercomm command;
108 DECLARE_SPINLOCKFLAGS(flags);
109
110 pINFO(sc, "sis1100_irq_thread started");
111
112#ifdef __linux__
113#if LINUX_VERSION_CODE < 0x20600
114 daemonize();
115 snprintf(current->comm, sizeof(current->comm), "sis1100_%02d", sc->unit);
116 SPIN_LOCK_IRQSAVE(current->sigmask_lock, flags);
117 sigemptyset(&current->blocked);
118 recalc_sigpending(current);
119 SPIN_UNLOCK_IRQRESTORE(current->sigmask_lock, flags);
120#else
121 daemonize("sis1100_%02d", sc->unit);
122 SPIN_LOCK_IRQSAVE(current->sighand->siglock, flags);
123 sigemptyset(&current->blocked);
124 recalc_sigpending();
125 SPIN_UNLOCK_IRQRESTORE(current->sighand->siglock, flags);
126#endif
127#endif /*__linux__*/
128
129 while (1) {
130#ifdef __NetBSD__
131 tsleep(&sc->handler_wait, PCATCH, "thread_vmeirq", 0);
132#elif __linux__
133 wait_event(sc->handler_wait, sc->handlercommand.command);
134#endif
135 SPIN_LOCK_IRQSAVE(sc->handlercommand.lock, flags);
136 command=sc->handlercommand.command;
137 sc->handlercommand.command=0;
138 SPIN_UNLOCK_IRQRESTORE(sc->handlercommand.lock, flags);
139
140 /*pINFO(sc, "irq_thread aufgewacht, command=0x%x", command);*/
141
142 sc->new_irqs=0;
143
144 if (command&handlercomm_die) {
145 pINFO(sc, "sis1100_irq_thread terminated");
146#ifdef __NetBSD__
147 SPIN_LOCK_IRQSAVE(sc->handlercommand.lock, flags);
148 sc->handlercommand.command=0;
149 wakeup(sc);
150 SPIN_UNLOCK_IRQRESTORE(sc->handlercommand.lock, flags);
151 kthread_exit(0);
152#elif __linux__
153 complete_and_exit(&sc->handler_completion, 0);
154#endif
155 }
156 _sis1100_irq_thread(sc, command);
157
158#ifdef __linux__
159 if (signal_pending (current)) {
160 SPIN_LOCK_IRQSAVE(current->SIGMASK_LOCK, flags);
161 flush_signals(current);
162 SPIN_UNLOCK_IRQRESTORE(current->SIGMASK_LOCK, flags);
163 }
164#endif /*__linux__*/
165
166 }
167#ifdef __linux__
168 return 0;
169#endif
170}
Note: See TracBrowser for help on using the repository browser.