source: GPL/branches/uniaud32-2.1.x/lib32/irq.c@ 519

Last change on this file since 519 was 519, checked in by David Azarewicz, 15 years ago

Changes to PCI bus scan, malloc, cleanup all warnings, misc other changes

File size: 7.9 KB
Line 
1/* $Id: irq.c,v 1.1.1.1 2003/07/02 13:57:02 eleph Exp $ */
2/*
3 * OS/2 implementation of Linux irq kernel services
4 *
5 * (C) 2000-2002 InnoTek Systemberatung GmbH
6 * (C) 2000-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
21 * USA.
22 *
23 */
24
25#include "linux.h"
26#include <linux/init.h>
27#include <linux/poll.h>
28#include <asm/uaccess.h>
29#include <asm/hardirq.h>
30
31#define LINUX
32#include <ossidc.h>
33#include <ossidc32.h>
34#include <osspci.h>
35#include <dbgos2.h>
36#include "irqos2.h"
37
38
39BOOL fInInterrupt = FALSE;
40extern BOOL fSuspended; //pci.c
41
42
43//******************************************************************************
44//******************************************************************************
45
46static IRQ_SLOT arSlots[MAX_IRQ_SLOTS] = { 0 };
47static ULONG eoiIrq[255] = {0};
48
49
50//******************************************************************************
51//******************************************************************************
52static IRQ_SLOT *FindSlot(unsigned irq)
53{
54 IRQ_SLOT *pSlot;
55
56 for( pSlot = arSlots; pSlot != &arSlots[MAX_IRQ_SLOTS]; pSlot++ )
57 {
58 if( pSlot->irqNo == irq ) return pSlot;
59 }
60
61 return NULL;
62}
63
64
65//******************************************************************************
66//******************************************************************************
67
68int request_irq(unsigned irq, irq_handler_t handler,
69 unsigned long x0, const char *x1, void *x2)
70{
71 IRQ_SLOT *pSlot = FindSlot(irq & 0xff);
72 unsigned u, uSlotNo = (unsigned)-1;
73 if( !pSlot )
74 {
75 // find empty slot
76 for( uSlotNo = 0; uSlotNo < MAX_IRQ_SLOTS; uSlotNo++ )
77 {
78 if( arSlots[uSlotNo].flHandlers == 0 )
79 {
80 pSlot = &arSlots[uSlotNo]; break;
81 }
82 }
83
84 }
85
86 if( pSlot )
87 {
88 if(RMRequestIRQ(/*hResMgr,*/ irq , (x0 & SA_SHIRQ) != 0) == FALSE) {
89 rprintf(("RMRequestIRQ failed for irq %d", irq));
90 // return 0;
91 }
92
93 for( u = 0; u < MAX_SHAREDIRQS; u++ )
94 {
95 if( pSlot->irqHandlers[u].handler == NULL )
96 {
97 pSlot->irqNo = irq & 0xff;
98 pSlot->irqHandlers[u].handler = handler;
99 pSlot->irqHandlers[u].x0 = x0;
100 pSlot->irqHandlers[u].x1 = (char *)x1;
101 pSlot->irqHandlers[u].x2 = x2;
102
103 if( pSlot->flHandlers != 0 ||
104 ALSA_SetIrq( irq & 0xff, uSlotNo, (x0 & SA_SHIRQ) != 0) )
105 {
106 pSlot->flHandlers |= 1 << u;
107 return 0;
108 }
109
110 break;
111 }
112 }
113 }
114
115 rprintf(("request_irq: Unable to register irq handler for irq %d\n", irq & 0xff ));
116 return 1;
117}
118
119
120//******************************************************************************
121//******************************************************************************
122void free_irq(unsigned int irq, void *userdata)
123{
124 unsigned u;
125 IRQ_SLOT *pSlot;
126
127 if( (pSlot = FindSlot(irq)) != NULL )
128 {
129 for( u = 0; u < MAX_SHAREDIRQS; u++ )
130 {
131 if( pSlot->irqHandlers[u].x2 == userdata )
132 {
133 pSlot->flHandlers &= ~(1 << u);
134 if( pSlot->flHandlers == 0 )
135 {
136 ALSA_FreeIrq(pSlot->irqNo);
137 pSlot->irqNo = 0;
138 // pSlot->fEOI = 0;
139 }
140
141 pSlot->irqHandlers[u].handler = NULL;
142 pSlot->irqHandlers[u].x0 = 0;
143 pSlot->irqHandlers[u].x1 = NULL;
144 pSlot->irqHandlers[u].x2 = NULL;
145
146 return;
147
148 }
149 }
150 }
151}
152
153
154//******************************************************************************
155//******************************************************************************
156void eoi_irq(unsigned int irq)
157{
158 /*(void)irq; */
159 /*
160 IRQ_SLOT *pSlot = FindSlot(irq);
161
162 if( pSlot ) pSlot->fEOI = 1;
163 */
164 eoiIrq[irq & 0xff]++;
165}
166
167
168//******************************************************************************
169//******************************************************************************
170BOOL process_interrupt(ULONG ulSlotNo, ULONG *pulIrq)
171{
172 unsigned u;
173 int rc;
174 IRQ_SLOT *pSlot;
175
176 //dprintf(("enter int proc %d %d",ulSlotNo, *pulIrq));
177
178 if(fSuspended)
179 {//If our device is suspended, then we can't receive interrupts, so it must
180 //be for some other device
181 //Don't pass it to the linux handler as the device doesn't respond as expected
182 //when suspended
183 dprintf(("Slot %d IRQ %d suspended",ulSlotNo, *pulIrq));
184 return FALSE;
185 }
186
187 if( ulSlotNo < MAX_IRQ_SLOTS )
188 {
189 pSlot = &arSlots[ulSlotNo];
190
191 for( u = 0; u < MAX_SHAREDIRQS; u++ )
192 {
193 if(pSlot && pSlot->irqHandlers[u].handler )
194 {
195 fInInterrupt = TRUE;
196#if 0
197 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,
198 pSlot->irqHandlers[u].x2, 0);
199#else
200 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,
201 pSlot->irqHandlers[u].x2);
202#endif
203
204 // HDA Hardware generates controller interrupts and stream interrupts
205 // the uniaud16 driver only cares about stream interrupts.
206 // azx_interrupt in alsa-kernel/pci/hda/hda_intel.c will return rc 2 if
207 // the interrupt is from the controller. There is no need to call uniaud16
208 // for these interrupts
209 if ( rc == 2 ) {
210 fInInterrupt = FALSE;
211 *pulIrq = pSlot->irqNo;
212 eoiIrq[pSlot->irqNo] = 0;
213 return TRUE;
214 }
215
216 if (rc == 1) eoi_irq(pSlot->irqNo);
217 rc = (eoiIrq[pSlot->irqNo] > 0);
218 fInInterrupt = FALSE;
219
220 if( rc /*== 1 || pSlot->fEOI*/ ) {
221
222 *pulIrq = pSlot->irqNo;
223 // pSlot->fEOI = 0;
224
225 //ok, this interrupt was intended for us; notify the 16 bits MMPM/2 driver
226 OSS32_ProcessIRQ();
227 //dprintf(("exit(1) int proc %d %d",ulSlotNo, *pulIrq));
228 eoiIrq[pSlot->irqNo] = 0;
229 return TRUE;
230 }
231 }
232 }
233 }
234 //dprintf(("exit(0) int proc %d %d",ulSlotNo, *pulIrq));
235
236 return FALSE;
237}
238
239
240//******************************************************************************
241//******************************************************************************
242int in_interrupt()
243{
244 return fInInterrupt;
245}
246
247
248//******************************************************************************
249//******************************************************************************
250void disable_irq(int irq)
251{
252 dprintf(("disable_irq %d NOT implemented", irq));
253}
254
255//******************************************************************************
256//******************************************************************************
257
Note: See TracBrowser for help on using the repository browser.