Main Page | Modules | Class List | File List | Class Members | File Members | Related Pages

helpers.c

Go to the documentation of this file.
00001 /* $Id: helpers.c,v 1.9 2004/04/01 09:14:19 ch12 Exp $ */
00002 /*****************************************************************************/
00011 /* (c) 2003 Technische Universitaet Dresden
00012  * This file is part of DROPS, which is distributed under the terms of the
00013  * GNU General Public License 2. Please see the COPYING file for details.
00014  */
00015 
00025 /* L4 */
00026 #include <l4/env/errno.h>
00027 
00028 #include <l4/dde_linux/dde.h>
00029 #include <l4/dde_linux/sound.h>
00030 
00031 /* Linux */
00032 #include <linux/kernel.h>
00033 #include <linux/fs.h>
00034 #include <linux/soundcard.h>
00035 
00036 /* local */
00037 #include "__config.h"
00038 #include "internal.h"
00039 
00040 #include "soundcore.h"
00041 
00043 static int _initialized = 0;
00044 
00046 static struct devs
00047 {
00048   struct file file;
00049   struct inode inode;
00050   struct file_operations *fops;
00051 } devs[TYPE_MAX][NUM_MAX];
00052 
00054 static inline void show_fops(struct file_operations* f)
00055 {
00056   LOGd(DEBUG_MSG, "  open @ %p\n", f->open);
00057   LOGd(DEBUG_MSG, " close @ %p\n", f->release);
00058   LOGd(DEBUG_MSG, "  read @ %p\n", f->read);
00059   LOGd(DEBUG_MSG, " write @ %p\n", f->write);
00060   LOGd(DEBUG_MSG, " ioctl @ %p\n", f->ioctl);
00061 }
00062 
00063 /**************************************************/
00064 
00066 static int snd_open_dev(int type, int num)
00067 {
00068   int ret;
00069   struct file_operations* fops;
00070   struct file *file;
00071   struct inode *inode;
00072 
00073   fops = soundcore_req_fops(type, num);
00074   if (!fops)
00075     return -L4_ENOTFOUND; /* ENODEV */
00076 
00077   devs[type][num].fops = fops;
00078   file = &devs[type][num].file;
00079   inode = &devs[type][num].inode;
00080 
00081   file->f_mode = FMODE_READ | FMODE_WRITE;
00082   file->f_flags = O_RDWR;
00083   file->f_pos = 0;
00084 
00085   if ((ret=fops->open(inode, file)))
00086     {
00087       LOGdL(DEBUG_ERRORS, "Error: fops->open returned %d", ret);
00088       return -L4_EOPEN;
00089     }
00090 
00091 #if DEBUG_SOUND
00092   LOGd(DEBUG_MSG, "%s%d opened", type ? "mixer" : "dsp", num);
00093   show_fops(fops);
00094 #endif
00095 
00096   return (type*NUM_MAX + num);
00097 }
00098 
00102 int l4dde_snd_open_dsp(int num)
00103 {
00104   return snd_open_dev(TYPE_DSP, num);
00105 }
00106 
00110 int l4dde_snd_open_mixer(int num)
00111 {
00112   return snd_open_dev(TYPE_MIXER, num);
00113 }
00114 
00118 int l4dde_snd_close(int dev)
00119 {
00120   int ret=0;
00121   struct devs *d = (struct devs *) devs;
00122   struct file_operations* fops = d[dev].fops;
00123   struct file *file;
00124   struct inode *inode;
00125 
00126   Assert(fops);
00127   if (!fops)
00128     return -L4_ESKIPPED;
00129 
00130   file = &d[dev].file;
00131   inode = &d[dev].inode;
00132 
00133   /* should always return 0 */
00134   if (fops->release)
00135     ret = fops->release(inode, file);
00136 
00137   LOGd(DEBUG_SOUND, "device closed (%d)", ret);
00138 
00139   return 0;
00140 }
00141 
00145 int l4dde_snd_read(int dev, void *buf, int count)
00146 {
00147   int ret;
00148   struct devs *d = (struct devs *) devs;
00149   struct file_operations* fops = d[dev].fops;
00150   struct file *file;
00151 
00152   Assert(fops);
00153   if (!fops)
00154     return -L4_ESKIPPED;
00155 
00156   file = &d[dev].file;
00157 
00158   if (fops->read)
00159     ret = fops->read(file, buf, count, &file->f_pos);
00160   else
00161     ret = -L4_EINVAL;
00162 
00163   LOGd(DEBUG_SOUND_READ, "read from device (%d)", ret);
00164 
00165   return ret;
00166 }
00167 
00171 int l4dde_snd_write(int dev, const void *buf, int count)
00172 {
00173   int ret;
00174   struct devs *d = (struct devs *) devs;
00175   struct file_operations* fops = d[dev].fops;
00176   struct file *file;
00177 
00178   Assert(fops);
00179   if (!fops)
00180     return -L4_ESKIPPED;
00181 
00182   file = &d[dev].file;
00183 
00184   if (fops->write)
00185     ret = fops->write(file, buf, count, &file->f_pos);
00186   else
00187     ret = -L4_EINVAL;
00188 
00189   LOGd(DEBUG_SOUND_WRITE, "write on device (%d)", ret);
00190 
00191   return ret;
00192 }
00193 
00197 int l4dde_snd_ioctl(int dev, int req, l4_addr_t arg)
00198 {
00199   int ret;
00200   struct devs *d = (struct devs *) devs;
00201   struct file_operations* fops = d[dev].fops;
00202   struct file *file;
00203   struct inode *inode;
00204 
00205   Assert(fops);
00206   if (!fops)
00207     return -L4_ESKIPPED;
00208 
00209   file = &d[dev].file;
00210   inode = &d[dev].inode;
00211 
00212   if (fops->ioctl)
00213     ret = fops->ioctl(inode, file, req, arg);
00214   else
00215     ret = -L4_EINVAL;
00216 
00217   LOGd(DEBUG_SOUND, "ioctl on device (%d)", ret);
00218 
00219   return ret;
00220 }
00221 
00225 int l4dde_snd_init()
00226 {
00227   if (_initialized)
00228     return -L4_ESKIPPED;
00229 
00230   ++_initialized;
00231   return 0;
00232 }
00233 
00237 int l4dde_snd_exit()
00238 {
00239   if (!_initialized)
00240     return -L4_ESKIPPED;
00241 
00242   --_initialized;
00243   return 0;
00244 }

Linux DDE, written by Christian Helmuth  © 2003 Technische Universitaet Dresden