source: drsdaq/VME/struck/sis1100/V2.02/dev/pci/sis1100_irq_handler.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: 6.8 KB
Line 
1/* $ZEL: sis1100_irq_handler.c,v 1.4 2004/05/27 23:10:23 wuestner Exp $ */
2
3/*
4 * Copyright (c) 2001-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#if !defined(__NetBSD__) && ! defined(__linux__)
32#error Wrong Operating System
33#endif
34
35int
36sis1100_irq_ctl(struct sis1100_softc* sc, struct sis1100_fdata* fd,
37 struct sis1100_irq_ctl* data)
38{
39 int foreign_irqs;
40 struct list_head* curr;
41 u_int32_t mask;
42
43/*pINFO(sc, "irq_ctl: signal=%d mask=0x%x", data->signal, data->irq_mask);*/
44
45 if (data->signal) {
46 foreign_irqs=0;
47 SEM_LOCK(sc->sem_fdata_list);
48 /* irq already in use? */
49 list_for_each(curr, &sc->fdata_list_head) {
50 struct sis1100_fdata* fd;
51 fd=list_entry(curr, struct sis1100_fdata, list);
52 foreign_irqs |= fd->owned_irqs;
53 }
54 SEM_UNLOCK(sc->sem_fdata_list);
55 if (foreign_irqs & data->irq_mask) {
56 pINFO(sc, "irq_ctl: IRQs owned by other programs: 0x%08x\n",
57 foreign_irqs);
58 return EBUSY;
59 }
60
61#ifdef __NetBSD__
62 fd->pid=fd->p->p_pid;
63#elif __linux__
64 fd->pid=current->pid;
65#endif
66 fd->sig=data->signal;
67 fd->owned_irqs |= data->irq_mask;
68 fd->old_remote_hw=sc->remote_hw;
69
70 switch (sc->remote_hw) {
71 case sis1100_hw_vme:
72 sis3100rem_enable_irqs(sc, fd, data->irq_mask);
73 break;
74 case sis1100_hw_camac:
75 sis5100rem_enable_irqs(sc, fd, data->irq_mask);
76 break;
77 case sis1100_hw_pci: break; /* do nothing */
78 case sis1100_hw_f1: break; /* nothing to be done */
79 case sis1100_hw_vertex: break; /* do nothing */
80 case sis1100_hw_invalid: break; /* do nothing */
81 }
82 /* enable PCI-FRONT-IRQs and MBX0_IRQ */
83 mask=0;
84 if (data->irq_mask & SIS1100_FRONT_IRQS) {
85 mask|=(data->irq_mask & SIS1100_FRONT_IRQS)>>4;
86 }
87 if (data->irq_mask & SIS1100_MBX0_IRQ) {
88 mask|=0x400;
89 }
90 if (mask) sis1100_enable_irq(sc, 0, mask);
91 } else {
92 int irqs;
93 irqs=fd->owned_irqs & data->irq_mask;
94
95 switch (sc->remote_hw) {
96 case sis1100_hw_vme:
97 sis3100rem_disable_irqs(sc, fd, irqs);
98 break;
99 case sis1100_hw_camac:
100 sis5100rem_disable_irqs(sc, fd, irqs);
101 break;
102 case sis1100_hw_pci: break; /* do nothing */
103 case sis1100_hw_f1: break; /* do nothing */
104 case sis1100_hw_vertex: break; /* do nothing */
105 case sis1100_hw_invalid: break; /* do nothing */
106 }
107 /* disable PCI-FRONT-IRQs and MBX0_IRQ */
108 mask=0;
109 if (irqs & SIS1100_FRONT_IRQS) {
110 mask|=(irqs & SIS1100_FRONT_IRQS)>>4;
111 }
112 if (irqs & SIS1100_MBX0_IRQ) {
113 mask|=irq_mbx0;
114 }
115 if (mask) sis1100_disable_irq(sc, 0, mask);
116
117 fd->owned_irqs &= ~data->irq_mask;
118 }
119 /*pINFO(sc, "irq_ctl: sig=%d owned_irqs=0x%x old_remote_hw=%d",
120 fd->sig, fd->owned_irqs, fd->old_remote_hw);*/
121 return 0;
122}
123
124int
125sis1100_irq_ack(struct sis1100_softc* sc, struct sis1100_fdata* fd,
126 struct sis1100_irq_ack* data)
127{
128 int irqs;
129
130/*
131 * pINFO(sc, "irq_ack: mask=0x%x", data->irq_mask);
132 */
133 irqs=fd->owned_irqs & data->irq_mask & sc->pending_irqs;
134 sc->pending_irqs&=~irqs;
135
136 switch (sc->remote_hw) {
137 case sis1100_hw_vme:
138 sis3100rem_irq_ack(sc, irqs);
139 break;
140 case sis1100_hw_camac:
141 sis5100rem_irq_ack(sc, irqs);
142 break;
143 case sis1100_hw_pci: break; /* do nothing */
144 case sis1100_hw_f1: break; /* do nothing */
145 case sis1100_hw_vertex: break; /* do nothing */
146 case sis1100_hw_invalid: break; /* do nothing */
147 }
148
149 return 0;
150}
151
152int
153sis1100_irq_get(struct sis1100_softc* sc, struct sis1100_fdata* fd,
154 struct sis1100_irq_get* data)
155{
156 data->irqs=sc->pending_irqs & fd->owned_irqs;
157 if (fd->old_remote_hw!=sc->remote_hw) {
158 if (sc->remote_hw!=sis1100_hw_invalid)
159 data->remote_status=1;
160 else
161 data->remote_status=-1;
162 fd->old_remote_hw=sc->remote_hw;
163 } else
164 data->remote_status=0;
165
166 if (sc->remote_hw==sis1100_hw_vme)
167 sis3100rem_get_vector(sc, data->irqs & data->irq_mask, data);
168 else {
169 data->level=0;
170 data->vector=0;
171 }
172 return 0;
173}
174
175int
176sis1100_irq_wait(struct sis1100_softc* sc, struct sis1100_fdata* fd,
177 struct sis1100_irq_get* data)
178{
179 int res=0;
180/*
181 pINFO(sc, "irq_wait: pending=0x%x mask=0x%x",
182 sc->pending_irqs, data->irq_mask);
183*/
184#ifdef __NetBSD__
185 {
186 int s;
187 s = splbio();
188 while (!(res || irq_pending(sc, fd, data->irq_mask))) {
189 res = tsleep(&sc->remoteirq_wait, PCATCH, "sis1100_irq", 0);
190 }
191 splx(s);
192 }
193#elif __linux__
194 res=wait_event_interruptible(sc->remoteirq_wait,
195 irq_pending(sc, fd, data->irq_mask)
196 );
197
198 if (res) return EINTR;
199#endif
200 data->irqs=sc->pending_irqs & fd->owned_irqs;
201 if (fd->old_remote_hw!=sc->remote_hw) {
202 if (sc->remote_hw!=sis1100_hw_invalid)
203 data->remote_status=1;
204 else
205 data->remote_status=-1;
206 fd->old_remote_hw=sc->remote_hw;
207 } else
208 data->remote_status=0;
209
210 data->opt_status=sc->last_opt_csr;
211
212 if (sc->remote_hw==sis1100_hw_vme)
213 sis3100rem_get_vector(sc, data->irqs & data->irq_mask, data);
214 else {
215 data->level=0;
216 data->vector=0;
217 }
218
219 data->mbx0=sc->mbx0;
220
221 return 0;
222}
Note: See TracBrowser for help on using the repository browser.