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