diff options
author | jdike <jdike> | 2003-04-24 16:44:36 +0000 |
---|---|---|
committer | jdike <jdike> | 2003-04-24 16:44:36 +0000 |
commit | 605052a9ab45d10e2037db42f270b0a10d6612e5 (patch) | |
tree | ef63eea1448e15f4a21f4bbf147aff68aba4f0b1 | |
parent | e6def878bb9e56179081659805aa6c093f23484f (diff) | |
download | uml-history-605052a9ab45d10e2037db42f270b0a10d6612e5.tar.gz |
Added copy_user stuff so that sound works in skas mode.
-rw-r--r-- | arch/um/drivers/hostaudio_kern.c | 79 |
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){ |