#include <linux/slab.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
+#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/minors.h>
#include <sound/pcm.h>
static int dsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0};
static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
static int nonblock_open;
+static int boot_devs;
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-project.org>");
MODULE_DESCRIPTION("PCM OSS emulation for ALSA.");
MODULE_LICENSE("GPL");
-MODULE_PARM(dsp_map, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(dsp_map, int, boot_devs, 0444);
MODULE_PARM_DESC(dsp_map, "PCM device number assigned to 1st OSS device.");
MODULE_PARM_SYNTAX(dsp_map, "default:0,skill:advanced");
-MODULE_PARM(adsp_map, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+module_param_array(adsp_map, int, boot_devs, 0444);
MODULE_PARM_DESC(adsp_map, "PCM device number assigned to 2nd OSS device.");
MODULE_PARM_SYNTAX(adsp_map, "default:1,skill:advanced");
-MODULE_PARM(nonblock_open, "i");
+module_param(nonblock_open, bool, 0644);
MODULE_PARM_DESC(nonblock_open, "Don't block opening busy PCM devices.");
MODULE_PARM_SYNTAX(nonblock_open, "default:0,skill:advanced");
MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM);
return bytes;
}
-static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char *buf, size_t bytes)
+static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char __user *buf, size_t bytes)
{
size_t xfer = 0;
ssize_t tmp;
return bytes;
}
-static ssize_t snd_pcm_oss_read1(snd_pcm_substream_t *substream, char *buf, size_t bytes)
+static ssize_t snd_pcm_oss_read1(snd_pcm_substream_t *substream, char __user *buf, size_t bytes)
{
size_t xfer = 0;
ssize_t tmp;
snd_pcm_lib_write(substream, runtime->oss.buffer, size1);
}
} else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
- void *buffers[runtime->channels];
+ void __user *buffers[runtime->channels];
memset(buffers, 0, runtime->channels * sizeof(void *));
- snd_pcm_lib_writev(substream, (void **)buffers, size);
+ snd_pcm_lib_writev(substream, buffers, size);
}
}
/*
return snd_pcm_oss_bytes(substream, delay);
}
-static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct count_info * _info)
+static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct count_info __user * _info)
{
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
runtime->oss.prev_hw_ptr_interrupt = delay;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_pcm_oss_simulate_fill(substream, delay);
- info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr);
+ info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
} else {
delay = snd_pcm_oss_bytes(substream, delay) + fixup;
info.blocks = delay / runtime->oss.period_bytes;
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- info.bytes = runtime->oss.bytes - delay;
+ info.bytes = (runtime->oss.bytes - delay) & INT_MAX;
else
- info.bytes = runtime->oss.bytes + delay;
+ info.bytes = (runtime->oss.bytes + delay) & INT_MAX;
}
if (copy_to_user(_info, &info, sizeof(info)))
return -EFAULT;
return 0;
}
-static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct audio_buf_info *_info)
+static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct audio_buf_info __user *_info)
{
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
return 0;
}
-static int snd_pcm_oss_get_mapbuf(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct buffmem_desc * _info)
+static int snd_pcm_oss_get_mapbuf(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct buffmem_desc __user * _info)
{
// it won't be probably implemented
// snd_printd("TODO: snd_pcm_oss_get_mapbuf\n");
unsigned int cmd, unsigned long arg)
{
snd_pcm_oss_file_t *pcm_oss_file;
+ int __user *p = (int __user *)arg;
int res;
pcm_oss_file = snd_magic_cast(snd_pcm_oss_file_t, file->private_data, return -ENXIO);
if (cmd == OSS_GETVERSION)
- return put_user(SNDRV_OSS_VERSION, (int *)arg);
+ return put_user(SNDRV_OSS_VERSION, p);
if (cmd == OSS_ALSAEMULVER)
- return put_user(1, (int *)arg);
+ return put_user(1, p);
#if defined(CONFIG_SND_MIXER_OSS) || (defined(MODULE) && defined(CONFIG_SND_MIXER_OSS_MODULE))
if (((cmd >> 8) & 0xff) == 'M') { /* mixer ioctl - for OSS compatibility */
snd_pcm_substream_t *substream;
case SNDCTL_DSP_SYNC:
return snd_pcm_oss_sync(pcm_oss_file);
case SNDCTL_DSP_SPEED:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
if ((res = snd_pcm_oss_set_rate(pcm_oss_file, res))<0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SOUND_PCM_READ_RATE:
res = snd_pcm_oss_get_rate(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_STEREO:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
res = res > 0 ? 2 : 1;
if ((res = snd_pcm_oss_set_channels(pcm_oss_file, res)) < 0)
return res;
- return put_user(--res, (int *)arg);
+ return put_user(--res, p);
case SNDCTL_DSP_GETBLKSIZE:
res = snd_pcm_oss_get_block_size(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_SETFMT:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
res = snd_pcm_oss_set_format(pcm_oss_file, res);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SOUND_PCM_READ_BITS:
res = snd_pcm_oss_get_format(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_CHANNELS:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
res = snd_pcm_oss_set_channels(pcm_oss_file, res);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SOUND_PCM_READ_CHANNELS:
res = snd_pcm_oss_get_channels(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SOUND_PCM_WRITE_FILTER:
case SOUND_PCM_READ_FILTER:
return -EIO;
case SNDCTL_DSP_POST:
return snd_pcm_oss_post(pcm_oss_file);
case SNDCTL_DSP_SUBDIVIDE:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
res = snd_pcm_oss_set_subdivide(pcm_oss_file, res);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
return snd_pcm_oss_set_fragment(pcm_oss_file, res);
case SNDCTL_DSP_GETFMTS:
res = snd_pcm_oss_get_formats(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_GETOSPACE:
case SNDCTL_DSP_GETISPACE:
return snd_pcm_oss_get_space(pcm_oss_file,
cmd == SNDCTL_DSP_GETISPACE ?
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct audio_buf_info *) arg);
+ (struct audio_buf_info __user *) arg);
case SNDCTL_DSP_NONBLOCK:
return snd_pcm_oss_nonblock(file);
case SNDCTL_DSP_GETCAPS:
res = snd_pcm_oss_get_caps(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_GETTRIGGER:
res = snd_pcm_oss_get_trigger(pcm_oss_file);
if (res < 0)
return res;
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_SETTRIGGER:
- if (get_user(res, (int *)arg))
+ if (get_user(res, p))
return -EFAULT;
return snd_pcm_oss_set_trigger(pcm_oss_file, res);
case SNDCTL_DSP_GETIPTR:
return snd_pcm_oss_get_ptr(pcm_oss_file,
cmd == SNDCTL_DSP_GETIPTR ?
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct count_info *) arg);
+ (struct count_info __user *) arg);
case SNDCTL_DSP_MAPINBUF:
case SNDCTL_DSP_MAPOUTBUF:
return snd_pcm_oss_get_mapbuf(pcm_oss_file,
cmd == SNDCTL_DSP_MAPINBUF ?
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
- (struct buffmem_desc *) arg);
+ (struct buffmem_desc __user *) arg);
case SNDCTL_DSP_SETSYNCRO:
/* stop DMA now.. */
return 0;
res = snd_pcm_oss_get_odelay(pcm_oss_file);
if (res < 0) {
/* it's for sure, some broken apps don't check for error codes */
- put_user(0, (int *)arg);
+ put_user(0, p);
return res;
}
- return put_user(res, (int *)arg);
+ return put_user(res, p);
case SNDCTL_DSP_PROFILE:
return 0; /* silently ignore */
default:
return -EINVAL;
}
-static ssize_t snd_pcm_oss_read(struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
snd_pcm_oss_file_t *pcm_oss_file;
snd_pcm_substream_t *substream;
#endif
}
-static ssize_t snd_pcm_oss_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
snd_pcm_oss_file_t *pcm_oss_file;
snd_pcm_substream_t *substream;
module_init(alsa_pcm_oss_init)
module_exit(alsa_pcm_oss_exit)
-
-#ifndef MODULE
-
-/* format is: snd-pcm-oss=dsp_map,adsp_map[,nonblock_open] */
-
-static int __init alsa_pcm_oss_setup(char *str)
-{
- static unsigned __initdata nr_dev = 0;
-
- if (nr_dev >= SNDRV_CARDS)
- return 0;
- (void)(get_option(&str,&dsp_map[nr_dev]) == 2 &&
- get_option(&str,&adsp_map[nr_dev]) == 2);
- (void)(get_option(&str,&nonblock_open) == 2);
- nr_dev++;
- return 1;
-}
-
-__setup("snd-pcm-oss=", alsa_pcm_oss_setup);
-
-#endif /* !MODULE */