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 int error;
47
48 if (value < 0)
49 return value;
50
51 error = verify_area(VERIFY_WRITE, addr, sizeof(int));
52 if (error)
53 return error;
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 #ifndef EXCLUDE_SEQUENCER
149 case SND_DEV_SEQ:
150 return sequencer_select (dev, &files[dev], sel_type, wait);
151 break;
152 #endif
153
154 #ifndef EXCLUDE_MIDI
155 case SND_DEV_MIDIN:
156 return MIDIbuf_select (dev, &files[dev], sel_type, wait);
157 break;
158 #endif
159
160 default:
161 return 0;
162 }
163
164 return 0;
165 }
166
167 static struct file_operations sound_fops =
168 {
169 sound_lseek,
170 sound_read,
171 sound_write,
172 NULL,
173 sound_select,
174 sound_ioctl,
175 NULL,
176 sound_open,
177 sound_release
178 };
179
180 long
181 soundcard_init (long mem_start)
182 {
183 register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
184
185 soundcard_configured = 1;
186
187 mem_start = sndtable_init (mem_start);
188
189
190 if (!(soundcards_installed = sndtable_get_cardcount ()))
191 return mem_start;
192
193 #ifndef EXCLUDE_AUDIO
194 if (num_audiodevs)
195 {
196 mem_start = DMAbuf_init (mem_start);
197 mem_start = audio_init (mem_start);
198 }
199 #endif
200
201 #ifndef EXCLUDE_MIDI
202 if (num_midis)
203 mem_start = MIDIbuf_init (mem_start);
204 #endif
205
206 #ifndef EXCLUDE_SEQUENCER
207 if (num_midis + num_synths)
208 mem_start = sequencer_init (mem_start);
209 #endif
210
211 return mem_start;
212 }
213
214 void
215 tenmicrosec (void)
216 {
217 int i;
218
219 for (i = 0; i < 16; i++)
220 inb (0x80);
221 }
222
223 int
224 snd_set_irq_handler (int interrupt_level, void (*hndlr) (int))
225 {
226 int retcode;
227
228 retcode = request_irq(interrupt_level, hndlr,
229 #ifdef SND_SA_INTERRUPT
230 SA_INTERRUPT,
231 #else
232 0,
233 #endif
234 "sound");
235
236 if (retcode < 0)
237 {
238 printk ("Sound: IRQ%d already in use\n", interrupt_level);
239 }
240
241 return retcode;
242 }
243
244 void
245 snd_release_irq (int vect)
246 {
247 free_irq (vect);
248 }
249
250 #ifndef EXCLUDE_SEQUENCER
251 void
252 request_sound_timer (int count)
253 {
254 extern unsigned long seq_time;
255
256 #if 1
257 if (count < 0)
258 count = jiffies + (-count);
259 else
260 count += seq_time;
261 timer_table[SOUND_TIMER].fn = sequencer_timer;
262 timer_table[SOUND_TIMER].expires = count;
263 timer_active |= 1 << SOUND_TIMER;
264 #endif
265 }
266
267 #endif
268
269 void
270 sound_stop_timer (void)
271 {
272 #if 1
273 timer_table[SOUND_TIMER].expires = 0;
274 timer_active &= ~(1 << SOUND_TIMER);
275 #endif
276 }
277
278 #ifndef EXCLUDE_AUDIO
279 static int
280 valid_dma_page (unsigned long addr, unsigned long dev_buffsize, unsigned long dma_pagesize)
281 {
282 if (((addr & (dma_pagesize - 1)) + dev_buffsize) <= dma_pagesize)
283 return 1;
284 else
285 return 0;
286 }
287
288 void
289 sound_mem_init (void)
290 {
291 int i, dev;
292 unsigned long start_addr, end_addr, mem_ptr, dma_pagesize;
293 struct dma_buffparms *dmap;
294
295 mem_ptr = high_memory;
296
297
298
299 if (mem_ptr > (16 * 1024 * 1024))
300 mem_ptr = 16 * 1024 * 1024;
301
302 for (dev = 0; dev < num_audiodevs; dev++)
303 if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
304 {
305 dmap = audio_devs[dev]->dmap;
306
307 if (audio_devs[dev]->flags & DMA_AUTOMODE)
308 audio_devs[dev]->buffcount = 1;
309
310 if (audio_devs[dev]->dmachan > 3 && audio_devs[dev]->buffsize > 65536)
311 dma_pagesize = 131072;
312 else
313 dma_pagesize = 65536;
314
315
316
317 if (audio_devs[dev]->buffsize > dma_pagesize)
318 audio_devs[dev]->buffsize = dma_pagesize;
319 audio_devs[dev]->buffsize &= 0xfffff000;
320 if (audio_devs[dev]->buffsize < 4096)
321 audio_devs[dev]->buffsize = 4096;
322
323
324
325 for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount; dmap->raw_count++)
326 {
327 start_addr = mem_ptr - audio_devs[dev]->buffsize;
328 if (!valid_dma_page (start_addr, audio_devs[dev]->buffsize, dma_pagesize))
329 start_addr &= ~(dma_pagesize - 1);
330
331
332 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
333
334 dmap->raw_buf[dmap->raw_count] = (char *) start_addr;
335 dmap->raw_buf_phys[dmap->raw_count] = start_addr;
336 mem_ptr = start_addr;
337
338 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
339 {
340 if (mem_map[i])
341 panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
342
343 mem_map[i] = MAP_PAGE_RESERVED;
344 }
345 }
346 }
347 }
348
349 #endif
350
351 #else
352
353 long
354 soundcard_init (long mem_start)
355 {
356 return mem_start;
357 }
358
359 #endif
360
361 #if !defined(CONFIGURE_SOUNDCARD) || defined(EXCLUDE_AUDIO)
362 void
363 sound_mem_init (void)
364 {
365
366 }
367
368 #endif