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