~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/oss/soundcard.c

Version: ~ [ linux-5.8 ] ~ [ linux-5.7.12 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.55 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.136 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.191 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.232 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.232 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * linux/drivers/sound/soundcard.c
  3  *
  4  * Sound card driver for Linux
  5  *
  6  *
  7  * Copyright (C) by Hannu Savolainen 1993-1997
  8  *
  9  * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 10  * Version 2 (June 1991). See the "COPYING" file distributed with this software
 11  * for more info.
 12  *
 13  *
 14  * Thomas Sailer     : ioctl code reworked (vmalloc/vfree removed)
 15  *                   integrated sound_switch.c
 16  * Stefan Reinauer   : integrated /proc/sound (equals to /dev/sndstat,
 17  *                   which should disappear in the near future)
 18  * Eric Dumas        : devfs support (22-Jan-98) <dumas@linux.eu.org> with
 19  *                   fixups by C. Scott Ananian <cananian@alumni.princeton.edu>
 20  * Richard Gooch     : moved common (non OSS-specific) devices to sound_core.c
 21  * Rob Riggs         : Added persistent DMA buffers support (1998/10/17)
 22  * Christoph Hellwig : Some cleanup work (2000/03/01)
 23  */
 24 
 25 #include <linux/config.h>
 26 
 27 #include "sound_config.h"
 28 #include <linux/init.h>
 29 #include <linux/types.h>
 30 #include <linux/errno.h>
 31 #include <linux/signal.h>
 32 #include <linux/fcntl.h>
 33 #include <linux/ctype.h>
 34 #include <linux/stddef.h>
 35 #include <linux/kmod.h>
 36 #include <asm/dma.h>
 37 #include <asm/io.h>
 38 #include <linux/wait.h>
 39 #include <linux/slab.h>
 40 #include <linux/ioport.h>
 41 #include <linux/devfs_fs_kernel.h>
 42 #include <linux/major.h>
 43 #include <linux/delay.h>
 44 #include <linux/proc_fs.h>
 45 #include <linux/smp_lock.h>
 46 #include <linux/module.h>
 47 
 48 /*
 49  * This ought to be moved into include/asm/dma.h
 50  */
 51 #ifndef valid_dma
 52 #define valid_dma(n) ((n) >= 0 && (n) < MAX_DMA_CHANNELS && (n) != 4)
 53 #endif
 54 
 55 /*
 56  * Table for permanently allocated memory (used when unloading the module)
 57  */
 58 caddr_t         sound_mem_blocks[1024];
 59 int             sound_nblocks = 0;
 60 
 61 /* Persistent DMA buffers */
 62 #ifdef CONFIG_SOUND_DMAP
 63 int             sound_dmap_flag = 1;
 64 #else
 65 int             sound_dmap_flag = 0;
 66 #endif
 67 
 68 static char     dma_alloc_map[MAX_DMA_CHANNELS];
 69 
 70 #define DMA_MAP_UNAVAIL         0
 71 #define DMA_MAP_FREE            1
 72 #define DMA_MAP_BUSY            2
 73 
 74 
 75 unsigned long seq_time = 0;     /* Time for /dev/sequencer */
 76 
 77 /*
 78  * Table for configurable mixer volume handling
 79  */
 80 static mixer_vol_table mixer_vols[MAX_MIXER_DEV];
 81 static int num_mixer_volumes;
 82 
 83 int *load_mixer_volumes(char *name, int *levels, int present)
 84 {
 85         int             i, n;
 86 
 87         for (i = 0; i < num_mixer_volumes; i++) {
 88                 if (strcmp(name, mixer_vols[i].name) == 0) {
 89                         if (present)
 90                                 mixer_vols[i].num = i;
 91                         return mixer_vols[i].levels;
 92                 }
 93         }
 94         if (num_mixer_volumes >= MAX_MIXER_DEV) {
 95                 printk(KERN_ERR "Sound: Too many mixers (%s)\n", name);
 96                 return levels;
 97         }
 98         n = num_mixer_volumes++;
 99 
100         strcpy(mixer_vols[n].name, name);
101 
102         if (present)
103                 mixer_vols[n].num = n;
104         else
105                 mixer_vols[n].num = -1;
106 
107         for (i = 0; i < 32; i++)
108                 mixer_vols[n].levels[i] = levels[i];
109         return mixer_vols[n].levels;
110 }
111 
112 static int set_mixer_levels(caddr_t arg)
113 {
114         /* mixer_vol_table is 174 bytes, so IMHO no reason to not allocate it on the stack */
115         mixer_vol_table buf;   
116 
117         if (__copy_from_user(&buf, arg, sizeof(buf)))
118                 return -EFAULT;
119         load_mixer_volumes(buf.name, buf.levels, 0);
120         if (__copy_to_user(arg, &buf, sizeof(buf)))
121                 return -EFAULT;
122         return 0;
123 }
124 
125 static int get_mixer_levels(caddr_t arg)
126 {
127         int n;
128 
129         if (__get_user(n, (int *)(&(((mixer_vol_table *)arg)->num))))
130                 return -EFAULT;
131         if (n < 0 || n >= num_mixer_volumes)
132                 return -EINVAL;
133         if (__copy_to_user(arg, &mixer_vols[n], sizeof(mixer_vol_table)))
134                 return -EFAULT;
135         return 0;
136 }
137 
138 #ifndef MIN
139 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
140 #endif
141 
142 /* 4K page size but our output routines use some slack for overruns */
143 #define PROC_BLOCK_SIZE (3*1024)
144 
145 static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos)
146 {
147         int dev = iminor(file->f_dentry->d_inode);
148         int ret = -EINVAL;
149 
150         /*
151          *      The OSS drivers aren't remotely happy without this locking,
152          *      and unless someone fixes them when they are about to bite the
153          *      big one anyway, we might as well bandage here..
154          */
155          
156         lock_kernel();
157         
158         DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
159         switch (dev & 0x0f) {
160         case SND_DEV_DSP:
161         case SND_DEV_DSP16:
162         case SND_DEV_AUDIO:
163                 ret = audio_read(dev, file, buf, count);
164                 break;
165 
166         case SND_DEV_SEQ:
167         case SND_DEV_SEQ2:
168                 ret = sequencer_read(dev, file, buf, count);
169                 break;
170 
171         case SND_DEV_MIDIN:
172                 ret = MIDIbuf_read(dev, file, buf, count);
173         }
174         unlock_kernel();
175         return ret;
176 }
177 
178 static ssize_t sound_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
179 {
180         int dev = iminor(file->f_dentry->d_inode);
181         int ret = -EINVAL;
182         
183         lock_kernel();
184         DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count));
185         switch (dev & 0x0f) {
186         case SND_DEV_SEQ:
187         case SND_DEV_SEQ2:
188                 ret =  sequencer_write(dev, file, buf, count);
189                 break;
190 
191         case SND_DEV_DSP:
192         case SND_DEV_DSP16:
193         case SND_DEV_AUDIO:
194                 ret = audio_write(dev, file, buf, count);
195                 break;
196 
197         case SND_DEV_MIDIN:
198                 ret =  MIDIbuf_write(dev, file, buf, count);
199                 break;
200         }
201         unlock_kernel();
202         return ret;
203 }
204 
205 static int sound_open(struct inode *inode, struct file *file)
206 {
207         int dev = iminor(inode);
208         int retval;
209 
210         DEB(printk("sound_open(dev=%d)\n", dev));
211         if ((dev >= SND_NDEVS) || (dev < 0)) {
212                 printk(KERN_ERR "Invalid minor device %d\n", dev);
213                 return -ENXIO;
214         }
215         switch (dev & 0x0f) {
216         case SND_DEV_CTL:
217                 dev >>= 4;
218                 if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
219                         request_module("mixer%d", dev);
220                 }
221                 if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL))
222                         return -ENXIO;
223         
224                 if (!try_module_get(mixer_devs[dev]->owner))
225                         return -ENXIO;
226                 break;
227 
228         case SND_DEV_SEQ:
229         case SND_DEV_SEQ2:
230                 if ((retval = sequencer_open(dev, file)) < 0)
231                         return retval;
232                 break;
233 
234         case SND_DEV_MIDIN:
235                 if ((retval = MIDIbuf_open(dev, file)) < 0)
236                         return retval;
237                 break;
238 
239         case SND_DEV_DSP:
240         case SND_DEV_DSP16:
241         case SND_DEV_AUDIO:
242                 if ((retval = audio_open(dev, file)) < 0)
243                         return retval;
244                 break;
245 
246         default:
247                 printk(KERN_ERR "Invalid minor device %d\n", dev);
248                 return -ENXIO;
249         }
250 
251         return 0;
252 }
253 
254 static int sound_release(struct inode *inode, struct file *file)
255 {
256         int dev = iminor(inode);
257 
258         lock_kernel();
259         DEB(printk("sound_release(dev=%d)\n", dev));
260         switch (dev & 0x0f) {
261         case SND_DEV_CTL:
262                 module_put(mixer_devs[dev >> 4]->owner);
263                 break;
264                 
265         case SND_DEV_SEQ:
266         case SND_DEV_SEQ2:
267                 sequencer_release(dev, file);
268                 break;
269 
270         case SND_DEV_MIDIN:
271                 MIDIbuf_release(dev, file);
272                 break;
273 
274         case SND_DEV_DSP:
275         case SND_DEV_DSP16:
276         case SND_DEV_AUDIO:
277                 audio_release(dev, file);
278                 break;
279 
280         default:
281                 printk(KERN_ERR "Sound error: Releasing unknown device 0x%02x\n", dev);
282         }
283         unlock_kernel();
284 
285         return 0;
286 }
287 
288 static int get_mixer_info(int dev, caddr_t arg)
289 {
290         mixer_info info;
291         memset(&info, 0, sizeof(info));
292         strlcpy(info.id, mixer_devs[dev]->id, sizeof(info.id));
293         strlcpy(info.name, mixer_devs[dev]->name, sizeof(info.name));
294         info.modify_counter = mixer_devs[dev]->modify_counter;
295         if (__copy_to_user(arg, &info,  sizeof(info)))
296                 return -EFAULT;
297         return 0;
298 }
299 
300 static int get_old_mixer_info(int dev, caddr_t arg)
301 {
302         _old_mixer_info info;
303         memset(&info, 0, sizeof(info));
304         strlcpy(info.id, mixer_devs[dev]->id, sizeof(info.id));
305         strlcpy(info.name, mixer_devs[dev]->name, sizeof(info.name));
306         if (copy_to_user(arg, &info,  sizeof(info)))
307                 return -EFAULT;
308         return 0;
309 }
310 
311 static int sound_mixer_ioctl(int mixdev, unsigned int cmd, caddr_t arg)
312 {
313         if (mixdev < 0 || mixdev >= MAX_MIXER_DEV)
314                 return -ENXIO;
315         /* Try to load the mixer... */
316         if (mixer_devs[mixdev] == NULL) {
317                 request_module("mixer%d", mixdev);
318         }
319         if (mixdev >= num_mixers || !mixer_devs[mixdev])
320                 return -ENXIO;
321         if (cmd == SOUND_MIXER_INFO)
322                 return get_mixer_info(mixdev, arg);
323         if (cmd == SOUND_OLD_MIXER_INFO)
324                 return get_old_mixer_info(mixdev, arg);
325         if (_SIOC_DIR(cmd) & _SIOC_WRITE)
326                 mixer_devs[mixdev]->modify_counter++;
327         if (!mixer_devs[mixdev]->ioctl)
328                 return -EINVAL;
329         return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
330 }
331 
332 static int sound_ioctl(struct inode *inode, struct file *file,
333                        unsigned int cmd, unsigned long arg)
334 {
335         int err, len = 0, dtype;
336         int dev = iminor(inode);
337 
338         if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
339                 /*
340                  * Have to validate the address given by the process.
341                  */
342                 len = _SIOC_SIZE(cmd);
343                 if (len < 1 || len > 65536 || arg == 0)
344                         return -EFAULT;
345                 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
346                         if ((err = verify_area(VERIFY_READ, (void *)arg, len)) < 0)
347                                 return err;
348                 if (_SIOC_DIR(cmd) & _SIOC_READ)
349                         if ((err = verify_area(VERIFY_WRITE, (void *)arg, len)) < 0)
350                                 return err;
351         }
352         DEB(printk("sound_ioctl(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
353         if (cmd == OSS_GETVERSION)
354                 return __put_user(SOUND_VERSION, (int *)arg);
355         
356         if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 &&   /* Mixer ioctl */
357             (dev & 0x0f) != SND_DEV_CTL) {              
358                 dtype = dev & 0x0f;
359                 switch (dtype) {
360                 case SND_DEV_DSP:
361                 case SND_DEV_DSP16:
362                 case SND_DEV_AUDIO:
363                         return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
364                                                  cmd, (caddr_t)arg);
365                         
366                 default:
367                         return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
368                 }
369         }
370         switch (dev & 0x0f) {
371         case SND_DEV_CTL:
372                 if (cmd == SOUND_MIXER_GETLEVELS)
373                         return get_mixer_levels((caddr_t)arg);
374                 if (cmd == SOUND_MIXER_SETLEVELS)
375                         return set_mixer_levels((caddr_t)arg);
376                 return sound_mixer_ioctl(dev >> 4, cmd, (caddr_t)arg);
377 
378         case SND_DEV_SEQ:
379         case SND_DEV_SEQ2:
380                 return sequencer_ioctl(dev, file, cmd, (caddr_t)arg);
381 
382         case SND_DEV_DSP:
383         case SND_DEV_DSP16:
384         case SND_DEV_AUDIO:
385                 return audio_ioctl(dev, file, cmd, (caddr_t)arg);
386                 break;
387 
388         case SND_DEV_MIDIN:
389                 return MIDIbuf_ioctl(dev, file, cmd, (caddr_t)arg);
390                 break;
391 
392         }
393         return -EINVAL;
394 }
395 
396 static unsigned int sound_poll(struct file *file, poll_table * wait)
397 {
398         struct inode *inode = file->f_dentry->d_inode;
399         int dev = iminor(inode);
400 
401         DEB(printk("sound_poll(dev=%d)\n", dev));
402         switch (dev & 0x0f) {
403         case SND_DEV_SEQ:
404         case SND_DEV_SEQ2:
405                 return sequencer_poll(dev, file, wait);
406 
407         case SND_DEV_MIDIN:
408                 return MIDIbuf_poll(dev, file, wait);
409 
410         case SND_DEV_DSP:
411         case SND_DEV_DSP16:
412         case SND_DEV_AUDIO:
413                 return DMAbuf_poll(file, dev >> 4, wait);
414         }
415         return 0;
416 }
417 
418 static int sound_mmap(struct file *file, struct vm_area_struct *vma)
419 {
420         int dev_class;
421         unsigned long size;
422         struct dma_buffparms *dmap = NULL;
423         int dev = iminor(file->f_dentry->d_inode);
424 
425         dev_class = dev & 0x0f;
426         dev >>= 4;
427 
428         if (dev_class != SND_DEV_DSP && dev_class != SND_DEV_DSP16 && dev_class != SND_DEV_AUDIO) {
429                 printk(KERN_ERR "Sound: mmap() not supported for other than audio devices\n");
430                 return -EINVAL;
431         }
432         lock_kernel();
433         if (vma->vm_flags & VM_WRITE)   /* Map write and read/write to the output buf */
434                 dmap = audio_devs[dev]->dmap_out;
435         else if (vma->vm_flags & VM_READ)
436                 dmap = audio_devs[dev]->dmap_in;
437         else {
438                 printk(KERN_ERR "Sound: Undefined mmap() access\n");
439                 unlock_kernel();
440                 return -EINVAL;
441         }
442 
443         if (dmap == NULL) {
444                 printk(KERN_ERR "Sound: mmap() error. dmap == NULL\n");
445                 unlock_kernel();
446                 return -EIO;
447         }
448         if (dmap->raw_buf == NULL) {
449                 printk(KERN_ERR "Sound: mmap() called when raw_buf == NULL\n");
450                 unlock_kernel();
451                 return -EIO;
452         }
453         if (dmap->mapping_flags) {
454                 printk(KERN_ERR "Sound: mmap() called twice for the same DMA buffer\n");
455                 unlock_kernel();
456                 return -EIO;
457         }
458         if (vma->vm_pgoff != 0) {
459                 printk(KERN_ERR "Sound: mmap() offset must be 0.\n");
460                 unlock_kernel();
461                 return -EINVAL;
462         }
463         size = vma->vm_end - vma->vm_start;
464 
465         if (size != dmap->bytes_in_use) {
466                 printk(KERN_WARNING "Sound: mmap() size = %ld. Should be %d\n", size, dmap->bytes_in_use);
467         }
468         if (remap_page_range(vma, vma->vm_start, virt_to_phys(dmap->raw_buf),
469                 vma->vm_end - vma->vm_start,
470                 vma->vm_page_prot)) {
471                 unlock_kernel();
472                 return -EAGAIN;
473         }
474 
475         dmap->mapping_flags |= DMA_MAP_MAPPED;
476 
477         if( audio_devs[dev]->d->mmap)
478                 audio_devs[dev]->d->mmap(dev);
479 
480         memset(dmap->raw_buf,
481                dmap->neutral_byte,
482                dmap->bytes_in_use);
483         unlock_kernel();
484         return 0;
485 }
486 
487 struct file_operations oss_sound_fops = {
488         .owner          = THIS_MODULE,
489         .llseek         = no_llseek,
490         .read           = sound_read,
491         .write          = sound_write,
492         .poll           = sound_poll,
493         .ioctl          = sound_ioctl,
494         .mmap           = sound_mmap,
495         .open           = sound_open,
496         .release        = sound_release,
497 };
498 
499 /*
500  *      Create the required special subdevices
501  */
502  
503 static int create_special_devices(void)
504 {
505         int seq1,seq2;
506         seq1=register_sound_special(&oss_sound_fops, 1);
507         if(seq1==-1)
508                 goto bad;
509         seq2=register_sound_special(&oss_sound_fops, 8);
510         if(seq2!=-1)
511                 return 0;
512         unregister_sound_special(1);
513 bad:
514         return -1;
515 }
516 
517 
518 /* These device names follow the official Linux device list,
519  * Documentation/devices.txt.  Let us know if there are other
520  * common names we should support for compatibility.
521  * Only those devices not created by the generic code in sound_core.c are
522  * registered here.
523  */
524 static const struct {
525         unsigned short minor;
526         char *name;
527         umode_t mode;
528         int *num;
529 } dev_list[] = { /* list of minor devices */
530 /* seems to be some confusion here -- this device is not in the device list */
531         {SND_DEV_DSP16,     "dspW",      S_IWUGO | S_IRUSR | S_IRGRP,
532          &num_audiodevs},
533         {SND_DEV_AUDIO,     "audio",     S_IWUGO | S_IRUSR | S_IRGRP,
534          &num_audiodevs},
535 };
536 
537 static int dmabuf;
538 static int dmabug;
539 
540 MODULE_PARM(dmabuf, "i");
541 MODULE_PARM(dmabug, "i");
542 
543 static int __init oss_init(void)
544 {
545         int             err;
546         int i, j;
547         
548         /* drag in sound_syms.o */
549         {
550                 extern char sound_syms_symbol;
551                 sound_syms_symbol = 0;
552         }
553 
554 #ifdef CONFIG_PCI
555         if(dmabug)
556                 isa_dma_bridge_buggy = dmabug;
557 #endif
558 
559         err = create_special_devices();
560         if (err) {
561                 printk(KERN_ERR "sound: driver already loaded/included in kernel\n");
562                 return err;
563         }
564 
565         /* Protecting the innocent */
566         sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
567 
568         for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
569                 devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
570                                 S_IFCHR | dev_list[i].mode,
571                                 "sound/%s", dev_list[i].name);
572 
573                 if (!dev_list[i].num)
574                         continue;
575 
576                 for (j = 1; j < *dev_list[i].num; j++) {
577                         devfs_mk_cdev(MKDEV(SOUND_MAJOR,
578                                                 dev_list[i].minor + (j*0x10)),
579                                         S_IFCHR | dev_list[i].mode,
580                                         "sound/%s%d", dev_list[i].name, j);
581                 }
582         }
583 
584         if (sound_nblocks >= 1024)
585                 printk(KERN_ERR "Sound warning: Deallocation table was too small.\n");
586         
587         return 0;
588 }
589 
590 static void __exit oss_cleanup(void)
591 {
592         int i, j;
593 
594         for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
595                 devfs_remove("sound/%s", dev_list[i].name);
596                 if (!dev_list[i].num)
597                         continue;
598                 for (j = 1; j < *dev_list[i].num; j++)
599                         devfs_remove("sound/%s%d", dev_list[i].name, j);
600         }
601         
602         unregister_sound_special(1);
603         unregister_sound_special(8);
604 
605         sound_stop_timer();
606 
607         sequencer_unload();
608 
609         for (i = 0; i < MAX_DMA_CHANNELS; i++)
610                 if (dma_alloc_map[i] != DMA_MAP_UNAVAIL) {
611                         printk(KERN_ERR "Sound: Hmm, DMA%d was left allocated - fixed\n", i);
612                         sound_free_dma(i);
613                 }
614 
615         for (i = 0; i < sound_nblocks; i++)
616                 vfree(sound_mem_blocks[i]);
617 
618 }
619 
620 module_init(oss_init);
621 module_exit(oss_cleanup);
622 MODULE_LICENSE("GPL");
623 
624 
625 int sound_alloc_dma(int chn, char *deviceID)
626 {
627         int err;
628 
629         if ((err = request_dma(chn, deviceID)) != 0)
630                 return err;
631 
632         dma_alloc_map[chn] = DMA_MAP_FREE;
633 
634         return 0;
635 }
636 
637 int sound_open_dma(int chn, char *deviceID)
638 {
639         if (!valid_dma(chn)) {
640                 printk(KERN_ERR "sound_open_dma: Invalid DMA channel %d\n", chn);
641                 return 1;
642         }
643 
644         if (dma_alloc_map[chn] != DMA_MAP_FREE) {
645                 printk("sound_open_dma: DMA channel %d busy or not allocated (%d)\n", chn, dma_alloc_map[chn]);
646                 return 1;
647         }
648         dma_alloc_map[chn] = DMA_MAP_BUSY;
649         return 0;
650 }
651 
652 void sound_free_dma(int chn)
653 {
654         if (dma_alloc_map[chn] == DMA_MAP_UNAVAIL) {
655                 /* printk( "sound_free_dma: Bad access to DMA channel %d\n",  chn); */
656                 return;
657         }
658         free_dma(chn);
659         dma_alloc_map[chn] = DMA_MAP_UNAVAIL;
660 }
661 
662 void sound_close_dma(int chn)
663 {
664         if (dma_alloc_map[chn] != DMA_MAP_BUSY) {
665                 printk(KERN_ERR "sound_close_dma: Bad access to DMA channel %d\n", chn);
666                 return;
667         }
668         dma_alloc_map[chn] = DMA_MAP_FREE;
669 }
670 
671 static void do_sequencer_timer(unsigned long dummy)
672 {
673         sequencer_timer(0);
674 }
675 
676 
677 static struct timer_list seq_timer =
678                 TIMER_INITIALIZER(do_sequencer_timer, 0, 0);
679 
680 void request_sound_timer(int count)
681 {
682         extern unsigned long seq_time;
683 
684         if (count < 0) {
685                 seq_timer.expires = (-count) + jiffies;
686                 add_timer(&seq_timer);
687                 return;
688         }
689         count += seq_time;
690 
691         count -= jiffies;
692 
693         if (count < 1)
694                 count = 1;
695 
696         seq_timer.expires = (count) + jiffies;
697         add_timer(&seq_timer);
698 }
699 
700 void sound_stop_timer(void)
701 {
702         del_timer(&seq_timer);;
703 }
704 
705 void conf_printf(char *name, struct address_info *hw_config)
706 {
707 #ifndef CONFIG_SOUND_TRACEINIT
708         return;
709 #else
710         printk("<%s> at 0x%03x", name, hw_config->io_base);
711 
712         if (hw_config->irq)
713                 printk(" irq %d", (hw_config->irq > 0) ? hw_config->irq : -hw_config->irq);
714 
715         if (hw_config->dma != -1 || hw_config->dma2 != -1)
716         {
717                 printk(" dma %d", hw_config->dma);
718                 if (hw_config->dma2 != -1)
719                         printk(",%d", hw_config->dma2);
720         }
721         printk("\n");
722 #endif
723 }
724 
725 void conf_printf2(char *name, int base, int irq, int dma, int dma2)
726 {
727 #ifndef CONFIG_SOUND_TRACEINIT
728         return;
729 #else
730         printk("<%s> at 0x%03x", name, base);
731 
732         if (irq)
733                 printk(" irq %d", (irq > 0) ? irq : -irq);
734 
735         if (dma != -1 || dma2 != -1)
736         {
737                   printk(" dma %d", dma);
738                   if (dma2 != -1)
739                           printk(",%d", dma2);
740         }
741         printk("\n");
742 #endif
743 }
744 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp