summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2003-04-24 16:44:36 +0000
committerjdike <jdike>2003-04-24 16:44:36 +0000
commit605052a9ab45d10e2037db42f270b0a10d6612e5 (patch)
treeef63eea1448e15f4a21f4bbf147aff68aba4f0b1
parente6def878bb9e56179081659805aa6c093f23484f (diff)
downloaduml-history-605052a9ab45d10e2037db42f270b0a10d6612e5.tar.gz
Added copy_user stuff so that sound works in skas mode.
-rw-r--r--arch/um/drivers/hostaudio_kern.c79
1 files changed, 72 insertions, 7 deletions
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index b512783..8df2d6a 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -11,6 +11,7 @@
#include "linux/fs.h"
#include "linux/sound.h"
#include "linux/soundcard.h"
+#include "asm/uaccess.h"
#include "kern_util.h"
#include "init.h"
#include "hostaudio.h"
@@ -22,7 +23,7 @@ char *mixer = HOSTAUDIO_DEV_MIXER;
#ifndef MODULE
static int set_dsp(char *name, int *add)
{
- dsp = uml_strdup(name);
+ dsp = name;
return(0);
}
@@ -34,7 +35,7 @@ __uml_setup("dsp=", set_dsp,
static int set_mixer(char *name, int *add)
{
- mixer = uml_strdup(name);
+ mixer = name;
return(0);
}
@@ -51,23 +52,55 @@ static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
loff_t *ppos)
{
struct hostaudio_state *state = file->private_data;
+ void *kbuf;
+ int err;
#ifdef DEBUG
printk("hostaudio: read called, count = %d\n", count);
#endif
- return(hostaudio_read_user(state, buffer, count, ppos));
+ kbuf = kmalloc(count, GFP_KERNEL);
+ if(kbuf == NULL)
+ return(-ENOMEM);
+
+ err = hostaudio_read_user(state, kbuf, count, ppos);
+ if(err < 0)
+ goto out;
+
+ if(copy_to_user(buffer, kbuf, err))
+ err = -EFAULT;
+
+ out:
+ kfree(kbuf);
+ return(err);
}
static ssize_t hostaudio_write(struct file *file, const char *buffer,
size_t count, loff_t *ppos)
{
struct hostaudio_state *state = file->private_data;
+ void *kbuf;
+ int err;
#ifdef DEBUG
printk("hostaudio: write called, count = %d\n", count);
#endif
- return(hostaudio_write_user(state, buffer, count, ppos));
+
+ kbuf = kmalloc(count, GFP_KERNEL);
+ if(kbuf == NULL)
+ return(-ENOMEM);
+
+ err = -EFAULT;
+ if(copy_from_user(kbuf, buffer, count))
+ goto out;
+
+ err = hostaudio_write_user(state, kbuf, count, ppos);
+ if(err < 0)
+ goto out;
+
+ out:
+ kfree(kbuf);
+ return(err);
}
static unsigned int hostaudio_poll(struct file *file,
@@ -86,12 +119,43 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct hostaudio_state *state = file->private_data;
+ unsigned long data = 0;
+ int err;
#ifdef DEBUG
printk("hostaudio: ioctl called, cmd = %u\n", cmd);
#endif
-
- return(hostaudio_ioctl_user(state, cmd, arg));
+ switch(cmd){
+ case SNDCTL_DSP_SPEED:
+ case SNDCTL_DSP_STEREO:
+ case SNDCTL_DSP_GETBLKSIZE:
+ case SNDCTL_DSP_CHANNELS:
+ case SNDCTL_DSP_SUBDIVIDE:
+ case SNDCTL_DSP_SETFRAGMENT:
+ if(get_user(data, (int *) arg))
+ return(-EFAULT);
+ break;
+ default:
+ break;
+ }
+
+ err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
+
+ switch(cmd){
+ case SNDCTL_DSP_SPEED:
+ case SNDCTL_DSP_STEREO:
+ case SNDCTL_DSP_GETBLKSIZE:
+ case SNDCTL_DSP_CHANNELS:
+ case SNDCTL_DSP_SUBDIVIDE:
+ case SNDCTL_DSP_SETFRAGMENT:
+ if(put_user(data, (int *) arg))
+ return(-EFAULT);
+ break;
+ default:
+ break;
+ }
+
+ return(err);
}
static int hostaudio_open(struct inode *inode, struct file *file)
@@ -225,7 +289,8 @@ MODULE_LICENSE("GPL");
static int __init hostaudio_init_module(void)
{
- printk(KERN_INFO "UML Audio Relay\n");
+ printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
+ dsp, mixer);
module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
if(module_data.dev_audio < 0){