This source file includes following definitions.
- snd_ioctl_return
- sound_read
- sound_write
- sound_lseek
- sound_open
- sound_release
- sound_ioctl
- sound_select
- soundcard_init
- tenmicrosec
- snd_set_irq_handler
- snd_release_irq
- request_sound_timer
- sound_stop_timer
- valid_dma_page
- sound_mem_init
- soundcard_init
- sound_mem_init
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 #include "sound_config.h"
32
33 #ifdef CONFIGURE_SOUNDCARD
34
35 #include <linux/major.h>
36
37 extern long seq_time;
38
39 static int soundcards_installed = 0;
40
41 static int soundcard_configured = 0;
42
43 static struct fileinfo files[SND_NDEVS];
44
45 extern char *snd_raw_buf[MAX_DSP_DEV][DSP_BUFFCOUNT];
46 extern unsigned long snd_raw_buf_phys[MAX_DSP_DEV][DSP_BUFFCOUNT];
47 extern int snd_raw_count[MAX_DSP_DEV];
48
49 int
50 snd_ioctl_return (int *addr, int value)
51 {
52 if (value < 0)
53 return value;
54
55 PUT_WORD_TO_USER (addr, 0, value);
56 return 0;
57 }
58
59 static int
60 sound_read (struct inode *inode, struct file *file, char *buf, int count)
61 {
62 int dev;
63
64 dev = inode->i_rdev;
65 dev = MINOR (dev);
66
67 return sound_read_sw (dev, &files[dev], buf, count);
68 }
69
70 static int
71 sound_write (struct inode *inode, struct file *file, char *buf, int count)
72 {
73 int dev;
74
75 dev = inode->i_rdev;
76 dev = MINOR (dev);
77
78 return sound_write_sw (dev, &files[dev], buf, count);
79 }
80
81 static int
82 sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
83 {
84 return RET_ERROR (EPERM);
85 }
86
87 static int
88 sound_open (struct inode *inode, struct file *file)
89 {
90 int dev;
91
92 dev = inode->i_rdev;
93 dev = MINOR (dev);
94
95 if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
96 {
97 printk ("SoundCard Error: The soundcard system has not been configured\n");
98 return RET_ERROR (ENXIO);
99 }
100
101 files[dev].mode = 0;
102
103 if ((file->f_flags & O_ACCMODE) == O_RDWR)
104 files[dev].mode = OPEN_READWRITE;
105 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
106 files[dev].mode = OPEN_READ;
107 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
108 files[dev].mode = OPEN_WRITE;
109
110 return sound_open_sw (dev, &files[dev]);
111 }
112
113 static void
114 sound_release (struct inode *inode, struct file *file)
115 {
116 int dev;
117
118 dev = inode->i_rdev;
119 dev = MINOR (dev);
120
121 sound_release_sw (dev, &files[dev]);
122 }
123
124 static int
125 sound_ioctl (struct inode *inode, struct file *file,
126 unsigned int cmd, unsigned long arg)
127 {
128 int dev;
129
130 dev = inode->i_rdev;
131 dev = MINOR (dev);
132
133 return sound_ioctl_sw (dev, &files[dev], cmd, arg);
134 }
135
136 static int
137 sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
138 {
139 int dev;
140
141 dev = inode->i_rdev;
142 dev = MINOR (dev);
143
144 DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
145
146 switch (dev & 0x0f)
147 {
148 case SND_DEV_SEQ:
149 return sequencer_select (dev, &files[dev], sel_type, wait);
150 break;
151
152 default:
153 return 0;
154 }
155
156 return 0;
157 }
158
159 static struct file_operations sound_fops =
160 {
161 sound_lseek,
162 sound_read,
163 sound_write,
164 NULL,
165 sound_select,
166 sound_ioctl,
167 NULL,
168 sound_open,
169 sound_release
170 };
171
172 long
173 soundcard_init (long mem_start)
174 {
175 register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
176
177 soundcard_configured = 1;
178
179 mem_start = sndtable_init (mem_start);
180
181
182 if (!(soundcards_installed = sndtable_get_cardcount ()))
183 return mem_start;
184
185 if (num_dspdevs)
186 {
187 mem_start = DMAbuf_init (mem_start);
188 mem_start = audio_init (mem_start);
189 }
190
191 #ifndef EXCLUDE_MPU401
192 if (num_midis)
193 mem_start = MIDIbuf_init (mem_start);
194 #endif
195
196 if (num_midis + num_synths)
197 mem_start = sequencer_init (mem_start);
198
199 return mem_start;
200 }
201
202 void
203 tenmicrosec (void)
204 {
205 int i;
206
207 for (i = 0; i < 16; i++)
208 inb (0x80);
209 }
210
211 int
212 snd_set_irq_handler (int interrupt_level, void(*hndlr)(int))
213 {
214 int retcode;
215
216 struct sigaction sa;
217
218 sa.sa_handler = hndlr;
219
220 #ifdef SND_SA_INTERRUPT
221 sa.sa_flags = SA_INTERRUPT;
222 #else
223 sa.sa_flags = 0;
224 #endif
225
226 sa.sa_mask = 0;
227 sa.sa_restorer = NULL;
228
229 retcode = irqaction (interrupt_level, &sa);
230
231 if (retcode < 0)
232 {
233 printk ("Sound: IRQ%d already in use\n", interrupt_level);
234 }
235
236 return retcode;
237 }
238
239 void
240 snd_release_irq(int vect)
241 {
242 free_irq(vect);
243 }
244
245 void
246 request_sound_timer (int count)
247 {
248 #ifndef EXCLUDE_SEQUENCER
249 if (count < 0)
250 count = jiffies + (-count);
251 else
252 count += seq_time;
253 timer_table[SOUND_TIMER].fn = sequencer_timer;
254 timer_table[SOUND_TIMER].expires = count;
255 timer_active |= 1 << SOUND_TIMER;
256 #endif
257 }
258
259 void
260 sound_stop_timer (void)
261 {
262 #ifndef EXCLUDE_SEQUENCER
263 timer_table[SOUND_TIMER].expires = 0;
264 timer_active &= ~(1 << SOUND_TIMER);
265 #endif
266 }
267
268 #ifndef EXCLUDE_AUDIO
269 static int
270 valid_dma_page (unsigned long addr, unsigned long dev_buffsize, unsigned long dma_pagesize)
271 {
272 if (((addr & (dma_pagesize - 1)) + dev_buffsize) <= dma_pagesize)
273 return 1;
274 else
275 return 0;
276 }
277
278 void
279 sound_mem_init (void)
280 {
281 int i, dev;
282 unsigned long start_addr, end_addr, mem_ptr, dma_pagesize;
283
284 mem_ptr = high_memory;
285
286
287
288 if (mem_ptr > (16 * 1024 * 1024))
289 mem_ptr = 16 * 1024 * 1024;
290
291 for (dev = 0; dev < num_dspdevs; dev++)
292 if (sound_buffcounts[dev] > 0 && sound_dsp_dmachan[dev] > 0)
293 {
294 if (sound_dma_automode[dev])
295 sound_buffcounts[dev] = 1;
296
297 if (sound_dsp_dmachan[dev] > 3 && sound_buffsizes[dev] > 65536)
298 dma_pagesize = 131072;
299 else
300 dma_pagesize = 65536;
301
302
303
304 if (sound_buffsizes[dev] > dma_pagesize)
305 sound_buffsizes[dev] = dma_pagesize;
306 sound_buffsizes[dev] &= 0xfffff000;
307 if (sound_buffsizes[dev] < 4096)
308 sound_buffsizes[dev] = 4096;
309
310
311
312 for (snd_raw_count[dev] = 0; snd_raw_count[dev] < sound_buffcounts[dev]; snd_raw_count[dev]++)
313 {
314 start_addr = mem_ptr - sound_buffsizes[dev];
315 if (!valid_dma_page (start_addr, sound_buffsizes[dev], dma_pagesize))
316 start_addr &= ~(dma_pagesize - 1);
317
318
319 end_addr = start_addr + sound_buffsizes[dev] - 1;
320
321 snd_raw_buf[dev][snd_raw_count[dev]] = (char *) start_addr;
322 snd_raw_buf_phys[dev][snd_raw_count[dev]] = start_addr;
323 mem_ptr = start_addr;
324
325 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
326 {
327 if (mem_map[i])
328 panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
329
330 mem_map[i] = MAP_PAGE_RESERVED;
331 }
332 }
333 }
334 }
335
336 #endif
337
338 #else
339
340 long
341 soundcard_init (long mem_start)
342 {
343 return mem_start;
344 }
345
346 #endif
347
348 #if !defined(CONFIGURE_SOUNDCARD) || defined(EXCLUDE_AUDIO)
349 void
350 sound_mem_init (void)
351 {
352
353 }
354
355 #endif