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 #include <linux/mm.h>
36
37 static int soundcards_installed = 0;
38
39
40 static int soundcard_configured = 0;
41
42 static struct fileinfo files[SND_NDEVS];
43
44 int
45 snd_ioctl_return (int *addr, int value)
46 {
47 int error;
48
49 if (value < 0)
50 return value;
51
52 error = verify_area(VERIFY_WRITE, addr, sizeof(int));
53 if (error)
54 return error;
55
56 PUT_WORD_TO_USER (addr, 0, value);
57 return 0;
58 }
59
60 static int
61 sound_read (struct inode *inode, struct file *file, char *buf, int count)
62 {
63 int dev;
64
65 dev = inode->i_rdev;
66 dev = MINOR (dev);
67
68 return sound_read_sw (dev, &files[dev], buf, count);
69 }
70
71 static int
72 sound_write (struct inode *inode, struct file *file, char *buf, int count)
73 {
74 int dev;
75
76 dev = inode->i_rdev;
77 dev = MINOR (dev);
78
79 return sound_write_sw (dev, &files[dev], buf, count);
80 }
81
82 static int
83 sound_lseek (struct inode *inode, struct file *file, off_t offset, int orig)
84 {
85 return RET_ERROR (EPERM);
86 }
87
88 static int
89 sound_open (struct inode *inode, struct file *file)
90 {
91 int dev;
92
93 dev = inode->i_rdev;
94 dev = MINOR (dev);
95
96 if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)
97 {
98 printk ("SoundCard Error: The soundcard system has not been configured\n");
99 return RET_ERROR (ENXIO);
100 }
101
102 files[dev].mode = 0;
103
104 if ((file->f_flags & O_ACCMODE) == O_RDWR)
105 files[dev].mode = OPEN_READWRITE;
106 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
107 files[dev].mode = OPEN_READ;
108 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
109 files[dev].mode = OPEN_WRITE;
110
111 return sound_open_sw (dev, &files[dev]);
112 }
113
114 static void
115 sound_release (struct inode *inode, struct file *file)
116 {
117 int dev;
118
119 dev = inode->i_rdev;
120 dev = MINOR (dev);
121
122 sound_release_sw (dev, &files[dev]);
123 }
124
125 static int
126 sound_ioctl (struct inode *inode, struct file *file,
127 unsigned int cmd, unsigned long arg)
128 {
129 int dev;
130
131 dev = inode->i_rdev;
132 dev = MINOR (dev);
133
134 return sound_ioctl_sw (dev, &files[dev], cmd, arg);
135 }
136
137 static int
138 sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
139 {
140 int dev;
141
142 dev = inode->i_rdev;
143 dev = MINOR (dev);
144
145 DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
146
147 switch (dev & 0x0f)
148 {
149 #ifndef EXCLUDE_SEQUENCER
150 case SND_DEV_SEQ:
151 return sequencer_select (dev, &files[dev], sel_type, wait);
152 break;
153 #endif
154
155 #ifndef EXCLUDE_MIDI
156 case SND_DEV_MIDIN:
157 return MIDIbuf_select (dev, &files[dev], sel_type, wait);
158 break;
159 #endif
160
161 default:
162 return 0;
163 }
164
165 return 0;
166 }
167
168 static struct file_operations sound_fops =
169 {
170 sound_lseek,
171 sound_read,
172 sound_write,
173 NULL,
174 sound_select,
175 sound_ioctl,
176 NULL,
177 sound_open,
178 sound_release
179 };
180
181 long
182 soundcard_init (long mem_start)
183 {
184 register_chrdev (SOUND_MAJOR, "sound", &sound_fops);
185
186 soundcard_configured = 1;
187
188 mem_start = sndtable_init (mem_start);
189
190
191 if (!(soundcards_installed = sndtable_get_cardcount ()))
192 return mem_start;
193
194 #ifndef EXCLUDE_AUDIO
195 if (num_audiodevs)
196 {
197 mem_start = DMAbuf_init (mem_start);
198 mem_start = audio_init (mem_start);
199 }
200 #endif
201
202 #ifndef EXCLUDE_MIDI
203 if (num_midis)
204 mem_start = MIDIbuf_init (mem_start);
205 #endif
206
207 #ifndef EXCLUDE_SEQUENCER
208 if (num_midis + num_synths)
209 mem_start = sequencer_init (mem_start);
210 #endif
211
212 return mem_start;
213 }
214
215 void
216 tenmicrosec (void)
217 {
218 int i;
219
220 for (i = 0; i < 16; i++)
221 inb (0x80);
222 }
223
224 int
225 snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, struct pt_regs *))
226 {
227 int retcode;
228
229 retcode = request_irq(interrupt_level, hndlr,
230 #ifdef SND_SA_INTERRUPT
231 SA_INTERRUPT,
232 #else
233 0,
234 #endif
235 "sound");
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