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 retcode = request_irq(interrupt_level, hndlr,
223 #ifdef SND_SA_INTERRUPT
224 SA_INTERRUPT,
225 #else
226 0,
227 #endif
228 "sound");
229
230 if (retcode < 0)
231 {
232 printk ("Sound: IRQ%d already in use\n", interrupt_level);
233 }
234
235 return retcode;
236 }
237
238 void
239 snd_release_irq (int vect)
240 {
241 free_irq (vect);
242 }
243
244 #ifndef EXCLUDE_SEQUENCER
245 void
246 request_sound_timer (int count)
247 {
248 extern unsigned long seq_time;
249
250 #if 1
251 if (count < 0)
252 count = jiffies + (-count);
253 else
254 count += seq_time;
255 timer_table[SOUND_TIMER].fn = sequencer_timer;
256 timer_table[SOUND_TIMER].expires = count;
257 timer_active |= 1 << SOUND_TIMER;
258 #endif
259 }
260
261 #endif
262
263 void
264 sound_stop_timer (void)
265 {
266 #if 1
267 timer_table[SOUND_TIMER].expires = 0;
268 timer_active &= ~(1 << SOUND_TIMER);
269 #endif
270 }
271
272 #ifndef EXCLUDE_AUDIO
273 static int
274 valid_dma_page (unsigned long addr, unsigned long dev_buffsize, unsigned long dma_pagesize)
275 {
276 if (((addr & (dma_pagesize - 1)) + dev_buffsize) <= dma_pagesize)
277 return 1;
278 else
279 return 0;
280 }
281
282 void
283 sound_mem_init (void)
284 {
285 int i, dev;
286 unsigned long start_addr, end_addr, mem_ptr, dma_pagesize;
287 struct dma_buffparms *dmap;
288
289 mem_ptr = high_memory;
290
291
292
293 if (mem_ptr > (16 * 1024 * 1024))
294 mem_ptr = 16 * 1024 * 1024;
295
296 for (dev = 0; dev < num_audiodevs; dev++)
297 if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
298 {
299 dmap = audio_devs[dev]->dmap;
300
301 if (audio_devs[dev]->flags & DMA_AUTOMODE)
302 audio_devs[dev]->buffcount = 1;
303
304 if (audio_devs[dev]->dmachan > 3 && audio_devs[dev]->buffsize > 65536)
305 dma_pagesize = 131072;
306 else
307 dma_pagesize = 65536;
308
309
310
311 if (audio_devs[dev]->buffsize > dma_pagesize)
312 audio_devs[dev]->buffsize = dma_pagesize;
313 audio_devs[dev]->buffsize &= 0xfffff000;
314 if (audio_devs[dev]->buffsize < 4096)
315 audio_devs[dev]->buffsize = 4096;
316
317
318
319 for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount; dmap->raw_count++)
320 {
321 start_addr = mem_ptr - audio_devs[dev]->buffsize;
322 if (!valid_dma_page (start_addr, audio_devs[dev]->buffsize, dma_pagesize))
323 start_addr &= ~(dma_pagesize - 1);
324
325
326 end_addr = start_addr + audio_devs[dev]->buffsize - 1;
327
328 dmap->raw_buf[dmap->raw_count] = (char *) start_addr;
329 dmap->raw_buf_phys[dmap->raw_count] = start_addr;
330 mem_ptr = start_addr;
331
332 for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
333 {
334 if (mem_map[i])
335 panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
336
337 mem_map[i] = MAP_PAGE_RESERVED;
338 }
339 }
340 }
341 }
342
343 #endif
344
345 #else
346
347 long
348 soundcard_init (long mem_start)
349 {
350 return mem_start;
351 }
352
353 #endif
354
355 #if !defined(CONFIGURE_SOUNDCARD) || defined(EXCLUDE_AUDIO)
356 void
357 sound_mem_init (void)
358 {
359
360 }
361
362 #endif