This source file includes following definitions.
- put_status
- put_status_int
- init_status
- read_status
- sound_read_sw
- sound_write_sw
- sound_open_sw
- sound_release_sw
- sound_ioctl_sw
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 struct sbc_device
35 {
36 int usecount;
37 };
38
39 static struct sbc_device sbc_devices[SND_NDEVS] =
40 {
41 {0}};
42
43 static int in_use = 0;
44
45
46
47
48
49
50
51
52 static char *status_buf = NULL;
53 static int status_len, status_ptr;
54 static int status_busy = 0;
55
56 static int
57 put_status (char *s)
58 {
59 int l;
60
61 for (l = 0; l < 256, s[l]; l++);
62
63
64
65 if (status_len + l >= 4000)
66 return 0;
67
68 memcpy (&status_buf[status_len], s, l);
69 status_len += l;
70
71 return 1;
72 }
73
74 static int
75 put_status_int (unsigned int val, int radix)
76 {
77 int l, v;
78
79 static char hx[] = "0123456789abcdef";
80 char buf[11];
81
82 if (!val)
83 return put_status ("0");
84
85 l = 0;
86 buf[10] = 0;
87
88 while (val)
89 {
90 v = val % radix;
91 val = val / radix;
92
93 buf[9 - l] = hx[v];
94 l++;
95 }
96
97 if (status_len + l >= 4000)
98 return 0;
99
100 memcpy (&status_buf[status_len], &buf[10 - l], l);
101 status_len += l;
102
103 return 1;
104 }
105
106 static void
107 init_status (void)
108 {
109
110
111
112
113
114 int i;
115
116 status_ptr = 0;
117
118 #ifdef SOUND_UNAME_A
119 put_status ("VoxWare Sound Driver:" SOUND_VERSION_STRING
120 " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY ",\n"
121 SOUND_UNAME_A ")"
122 "\n");
123 #else
124 put_status ("VoxWare Sound Driver:" SOUND_VERSION_STRING
125 " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@"
126 SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")"
127 "\n");
128 #endif
129
130 if (!put_status ("Config options: "))
131 return;
132 if (!put_status_int (SELECTED_SOUND_OPTIONS, 16))
133 return;
134
135 if (!put_status ("\n\nInstalled drivers: \n"))
136 return;
137
138 for (i = 0; i < (num_sound_drivers - 1); i++)
139 {
140 if (!put_status ("Type "))
141 return;
142 if (!put_status_int (sound_drivers[i].card_type, 10))
143 return;
144 if (!put_status (": "))
145 return;
146 if (!put_status (sound_drivers[i].name))
147 return;
148
149 if (!put_status ("\n"))
150 return;
151 }
152
153 if (!put_status ("\n\nCard config: \n"))
154 return;
155
156 for (i = 0; i < (num_sound_cards - 1); i++)
157 {
158 int drv;
159
160 if (!snd_installed_cards[i].enabled)
161 if (!put_status ("("))
162 return;
163
164
165
166
167
168
169 if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) != -1)
170 if (!put_status (sound_drivers[drv].name))
171 return;
172
173 if (!put_status (" at 0x"))
174 return;
175 if (!put_status_int (snd_installed_cards[i].config.io_base, 16))
176 return;
177 if (!put_status (" irq "))
178 return;
179 if (!put_status_int (snd_installed_cards[i].config.irq, 10))
180 return;
181 if (!put_status (" drq "))
182 return;
183 if (!put_status_int (snd_installed_cards[i].config.dma, 10))
184 return;
185
186 if (!snd_installed_cards[i].enabled)
187 if (!put_status (")"))
188 return;
189
190 if (!put_status ("\n"))
191 return;
192 }
193
194 #ifdef EXCLUDE_AUDIO
195 if (!put_status ("\nAudio devices: NOT ENABLED IN CONFIG\n"))
196 return;
197 #else
198 if (!put_status ("\nAudio devices:\n"))
199 return;
200
201 for (i = 0; i < num_audiodevs; i++)
202 {
203 if (!put_status_int (i, 10))
204 return;
205 if (!put_status (": "))
206 return;
207 if (!put_status (audio_devs[i]->name))
208 return;
209 if (!put_status ("\n"))
210 return;
211 }
212 #endif
213
214 #ifdef EXCLUDE_SEQUENCER
215 if (!put_status ("\nSynth devices: NOT ENABLED IN CONFIG\n"))
216 return;
217 #else
218 if (!put_status ("\nSynth devices:\n"))
219 return;
220
221 for (i = 0; i < num_synths; i++)
222 {
223 if (!put_status_int (i, 10))
224 return;
225 if (!put_status (": "))
226 return;
227 if (!put_status (synth_devs[i]->info->name))
228 return;
229 if (!put_status ("\n"))
230 return;
231 }
232 #endif
233
234 #ifdef EXCLUDE_MIDI
235 if (!put_status ("\nMidi devices: NOT ENABLED IN CONFIG\n"))
236 return;
237 #else
238 if (!put_status ("\nMidi devices:\n"))
239 return;
240
241 for (i = 0; i < num_midis; i++)
242 {
243 if (!put_status_int (i, 10))
244 return;
245 if (!put_status (": "))
246 return;
247 if (!put_status (midi_devs[i]->info.name))
248 return;
249 if (!put_status ("\n"))
250 return;
251 }
252 #endif
253
254 if (!put_status ("\nTimers:\n"))
255 return;
256
257 for (i = 0; i < num_sound_timers; i++)
258 {
259 if (!put_status_int (i, 10))
260 return;
261 if (!put_status (": "))
262 return;
263 if (!put_status (sound_timer_devs[i]->info.name))
264 return;
265 if (!put_status ("\n"))
266 return;
267 }
268
269 if (!put_status ("\nMixers:\n"))
270 return;
271
272 for (i = 0; i < num_mixers; i++)
273 {
274 if (!put_status_int (i, 10))
275 return;
276 if (!put_status (": "))
277 return;
278 if (!put_status (mixer_devs[i]->name))
279 return;
280 if (!put_status ("\n"))
281 return;
282 }
283 }
284
285 static int
286 read_status (snd_rw_buf * buf, int count)
287 {
288
289
290
291 int l, c;
292
293 l = count;
294 c = status_len - status_ptr;
295
296 if (l > c)
297 l = c;
298 if (l <= 0)
299 return 0;
300
301 COPY_TO_USER (buf, 0, &status_buf[status_ptr], l);
302 status_ptr += l;
303
304 return l;
305 }
306
307 int
308 sound_read_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
309 {
310 DEB (printk ("sound_read_sw(dev=%d, count=%d)\n", dev, count));
311
312 switch (dev & 0x0f)
313 {
314 case SND_DEV_STATUS:
315 return read_status (buf, count);
316 break;
317
318 case SND_DEV_DSP:
319 case SND_DEV_DSP16:
320 case SND_DEV_AUDIO:
321 return audio_read (dev, file, buf, count);
322 break;
323
324 case SND_DEV_SEQ:
325 case SND_DEV_SEQ2:
326 return sequencer_read (dev, file, buf, count);
327 break;
328
329 #ifndef EXCLUDE_MIDI
330 case SND_DEV_MIDIN:
331 return MIDIbuf_read (dev, file, buf, count);
332 #endif
333
334 default:
335 printk ("Sound: Undefined minor device %d\n", dev);
336 }
337
338 return RET_ERROR (EPERM);
339 }
340
341 int
342 sound_write_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
343 {
344
345 DEB (printk ("sound_write_sw(dev=%d, count=%d)\n", dev, count));
346
347 switch (dev & 0x0f)
348 {
349
350 case SND_DEV_SEQ:
351 case SND_DEV_SEQ2:
352 return sequencer_write (dev, file, buf, count);
353 break;
354
355 case SND_DEV_DSP:
356 case SND_DEV_DSP16:
357 case SND_DEV_AUDIO:
358 return audio_write (dev, file, buf, count);
359 break;
360
361 #ifndef EXCLUDE_MIDI
362 case SND_DEV_MIDIN:
363 return MIDIbuf_write (dev, file, buf, count);
364 #endif
365
366 default:
367 return RET_ERROR (EPERM);
368 }
369
370 return count;
371 }
372
373 int
374 sound_open_sw (int dev, struct fileinfo *file)
375 {
376 int retval;
377
378 DEB (printk ("sound_open_sw(dev=%d) : usecount=%d\n", dev, sbc_devices[dev].usecount));
379
380 if ((dev >= SND_NDEVS) || (dev < 0))
381 {
382 printk ("Invalid minor device %d\n", dev);
383 return RET_ERROR (ENXIO);
384 }
385
386 switch (dev & 0x0f)
387 {
388 case SND_DEV_STATUS:
389 if (status_busy)
390 return RET_ERROR (EBUSY);
391 status_busy = 1;
392 if ((status_buf = (char *) KERNEL_MALLOC (4000)) == NULL)
393 return RET_ERROR (EIO);
394 status_len = status_ptr = 0;
395 init_status ();
396 break;
397
398 case SND_DEV_CTL:
399 return 0;
400 break;
401
402 case SND_DEV_SEQ:
403 case SND_DEV_SEQ2:
404 if ((retval = sequencer_open (dev, file)) < 0)
405 return retval;
406 break;
407
408 #ifndef EXCLUDE_MIDI
409 case SND_DEV_MIDIN:
410 if ((retval = MIDIbuf_open (dev, file)) < 0)
411 return retval;
412 break;
413 #endif
414
415 case SND_DEV_DSP:
416 case SND_DEV_DSP16:
417 case SND_DEV_AUDIO:
418 if ((retval = audio_open (dev, file)) < 0)
419 return retval;
420 break;
421
422 default:
423 printk ("Invalid minor device %d\n", dev);
424 return RET_ERROR (ENXIO);
425 }
426
427 sbc_devices[dev].usecount++;
428 in_use++;
429
430 return 0;
431 }
432
433 void
434 sound_release_sw (int dev, struct fileinfo *file)
435 {
436
437 DEB (printk ("sound_release_sw(dev=%d)\n", dev));
438
439 switch (dev & 0x0f)
440 {
441 case SND_DEV_STATUS:
442 if (status_buf)
443 KERNEL_FREE (status_buf);
444 status_buf = NULL;
445 status_busy = 0;
446 break;
447
448 case SND_DEV_CTL:
449 break;
450
451 case SND_DEV_SEQ:
452 case SND_DEV_SEQ2:
453 sequencer_release (dev, file);
454 break;
455
456 #ifndef EXCLUDE_MIDI
457 case SND_DEV_MIDIN:
458 MIDIbuf_release (dev, file);
459 break;
460 #endif
461
462 case SND_DEV_DSP:
463 case SND_DEV_DSP16:
464 case SND_DEV_AUDIO:
465 audio_release (dev, file);
466 break;
467
468 default:
469 printk ("Sound error: Releasing unknown device 0x%02x\n", dev);
470 }
471
472 sbc_devices[dev].usecount--;
473 in_use--;
474 }
475
476 int
477 sound_ioctl_sw (int dev, struct fileinfo *file,
478 unsigned int cmd, unsigned long arg)
479 {
480 DEB (printk ("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
481
482 if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0)
483 if ((dev & 0x0f) != SND_DEV_CTL)
484 {
485 int dtype = dev & 0x0f;
486 int mixdev;
487
488 switch (dtype)
489 {
490 case SND_DEV_DSP:
491 case SND_DEV_DSP16:
492 case SND_DEV_AUDIO:
493 mixdev = audio_devs[dev >> 4]->mixer_dev;
494 if (mixdev < 0 || mixdev >= num_mixers)
495 return RET_ERROR (ENXIO);
496 return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg);
497 break;
498
499 default:
500 return mixer_devs[0]->ioctl (0, cmd, arg);
501 }
502 }
503
504 switch (dev & 0x0f)
505 {
506
507 case SND_DEV_CTL:
508
509 if (!num_mixers)
510 return RET_ERROR (ENXIO);
511
512 dev = dev >> 4;
513
514 if (dev >= num_mixers)
515 return RET_ERROR (ENXIO);
516
517 return mixer_devs[dev]->ioctl (dev, cmd, arg);
518 break;
519
520 case SND_DEV_SEQ:
521 case SND_DEV_SEQ2:
522 return sequencer_ioctl (dev, file, cmd, arg);
523 break;
524
525 case SND_DEV_DSP:
526 case SND_DEV_DSP16:
527 case SND_DEV_AUDIO:
528 return audio_ioctl (dev, file, cmd, arg);
529 break;
530
531 #ifndef EXCLUDE_MIDI
532 case SND_DEV_MIDIN:
533 return MIDIbuf_ioctl (dev, file, cmd, arg);
534 break;
535 #endif
536
537 default:
538 return RET_ERROR (EPERM);
539 break;
540 }
541
542 return RET_ERROR (EPERM);
543 }
544
545 #endif