656 lines
17 KiB
Diff
656 lines
17 KiB
Diff
--- linux/net/decnet/dn_dev.c.bak Wed Jun 16 14:42:24 2004
|
|
+++ linux/net/decnet/dn_dev.c Wed Jun 16 14:42:34 2004
|
|
@@ -1070,31 +1070,39 @@ int dnet_gifconf(struct net_device *dev,
|
|
{
|
|
struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr;
|
|
struct dn_ifaddr *ifa;
|
|
- struct ifreq *ifr = (struct ifreq *)buf;
|
|
+ char buffer[DN_IFREQ_SIZE];
|
|
+ struct ifreq *ifr = (struct ifreq *)buffer;
|
|
+ struct sockaddr_dn *addr = (struct sockaddr_dn *)&ifr->ifr_addr;
|
|
int done = 0;
|
|
|
|
if ((dn_db == NULL) || ((ifa = dn_db->ifa_list) == NULL))
|
|
return 0;
|
|
|
|
for(; ifa; ifa = ifa->ifa_next) {
|
|
- if (!ifr) {
|
|
+ if (!buf) {
|
|
done += sizeof(DN_IFREQ_SIZE);
|
|
continue;
|
|
}
|
|
if (len < DN_IFREQ_SIZE)
|
|
return done;
|
|
- memset(ifr, 0, DN_IFREQ_SIZE);
|
|
+ memset(buffer, 0, DN_IFREQ_SIZE);
|
|
|
|
if (ifa->ifa_label)
|
|
strcpy(ifr->ifr_name, ifa->ifa_label);
|
|
else
|
|
strcpy(ifr->ifr_name, dev->name);
|
|
|
|
- (*(struct sockaddr_dn *) &ifr->ifr_addr).sdn_family = AF_DECnet;
|
|
- (*(struct sockaddr_dn *) &ifr->ifr_addr).sdn_add.a_len = 2;
|
|
- (*(dn_address *)(*(struct sockaddr_dn *) &ifr->ifr_addr).sdn_add.a_addr) = ifa->ifa_local;
|
|
+ addr->sdn_family = AF_DECnet;
|
|
+ addr->sdn_add.a_len = 2;
|
|
+ memcpy(addr->sdn_add.a_addr, &ifa->ifa_local,
|
|
+ sizeof(dn_address));
|
|
|
|
- ifr = (struct ifreq *)((char *)ifr + DN_IFREQ_SIZE);
|
|
+ if (copy_to_user(buf, buffer, DN_IFREQ_SIZE)) {
|
|
+ done = -EFAULT;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ buf += DN_IFREQ_SIZE;
|
|
len -= DN_IFREQ_SIZE;
|
|
done += DN_IFREQ_SIZE;
|
|
}
|
|
--- linux-2.4.21/drivers/net/wireless/airo.c 2003-06-13 15:51:35.000000000 +0100
|
|
+++ linux-2.4.21/drivers/net/wireless/airo.c.plasmaroo 2004-06-24 11:09:08.260352168 +0100
|
|
@@ -3012,19 +3012,22 @@
|
|
size_t len,
|
|
loff_t *offset )
|
|
{
|
|
- int i;
|
|
- int pos;
|
|
+ loff_t pos = *offset;
|
|
struct proc_data *priv = (struct proc_data*)file->private_data;
|
|
|
|
- if( !priv->rbuffer ) return -EINVAL;
|
|
+ if (!priv->rbuffer)
|
|
+ return -EINVAL;
|
|
|
|
- pos = *offset;
|
|
- for( i = 0; i+pos < priv->readlen && i < len; i++ ) {
|
|
- if (put_user( priv->rbuffer[i+pos], buffer+i ))
|
|
- return -EFAULT;
|
|
- }
|
|
- *offset += i;
|
|
- return i;
|
|
+ if (pos < 0)
|
|
+ return -EINVAL;
|
|
+ if (pos >= priv->readlen)
|
|
+ return 0;
|
|
+ if (len > priv->readlen - pos)
|
|
+ len = priv->readlen - pos;
|
|
+ if (copy_to_user(buffer, priv->rbuffer + pos, len))
|
|
+ return -EFAULT;
|
|
+ *offset = pos + len;
|
|
+ return len;
|
|
}
|
|
|
|
/*
|
|
@@ -3036,24 +3039,24 @@
|
|
size_t len,
|
|
loff_t *offset )
|
|
{
|
|
- int i;
|
|
- int pos;
|
|
+ loff_t pos = *offset;
|
|
struct proc_data *priv = (struct proc_data*)file->private_data;
|
|
|
|
- if ( !priv->wbuffer ) {
|
|
+ if (!priv->wbuffer)
|
|
return -EINVAL;
|
|
- }
|
|
-
|
|
- pos = *offset;
|
|
|
|
- for( i = 0; i + pos < priv->maxwritelen &&
|
|
- i < len; i++ ) {
|
|
- if (get_user( priv->wbuffer[i+pos], buffer + i ))
|
|
- return -EFAULT;
|
|
- }
|
|
- if ( i+pos > priv->writelen ) priv->writelen = i+file->f_pos;
|
|
- *offset += i;
|
|
- return i;
|
|
+ if (pos < 0)
|
|
+ return -EINVAL;
|
|
+ if (pos >= priv->maxwritelen)
|
|
+ return 0;
|
|
+ if (len > priv->maxwritelen - pos)
|
|
+ len = priv->maxwritelen - pos;
|
|
+ if (copy_from_user(priv->wbuffer + pos, buffer, len))
|
|
+ return -EFAULT;
|
|
+ if (pos + len > priv->writelen)
|
|
+ priv->writelen = pos + len;
|
|
+ *offset = pos + len;
|
|
+ return len;
|
|
}
|
|
|
|
static int proc_status_open( struct inode *inode, struct file *file ) {
|
|
--- linux/drivers/sound/mpu401.c.bak Wed Jun 16 14:42:24 2004
|
|
+++ linux/drivers/sound/mpu401.c Wed Jun 16 14:42:34 2004
|
|
@@ -1493,14 +1493,16 @@ static unsigned long mpu_timer_get_time(
|
|
static int mpu_timer_ioctl(int dev, unsigned int command, caddr_t arg)
|
|
{
|
|
int midi_dev = sound_timer_devs[dev]->devlink;
|
|
+ int *p = (int *)arg;
|
|
|
|
switch (command)
|
|
{
|
|
case SNDCTL_TMR_SOURCE:
|
|
{
|
|
int parm;
|
|
-
|
|
- parm = *(int *) arg;
|
|
+
|
|
+ if (get_user(parm, p))
|
|
+ return -EFAULT;
|
|
parm &= timer_caps;
|
|
|
|
if (parm != 0)
|
|
@@ -1512,7 +1514,9 @@ static int mpu_timer_ioctl(int dev, unsi
|
|
else if (timer_mode & TMR_MODE_SMPTE)
|
|
mpu_cmd(midi_dev, 0x3d, 0); /* Use SMPTE sync */
|
|
}
|
|
- return (*(int *) arg = timer_mode);
|
|
+ if (put_user(timer_mode, p))
|
|
+ return -EFAULT;
|
|
+ return timer_mode;
|
|
}
|
|
break;
|
|
|
|
@@ -1537,10 +1541,13 @@ static int mpu_timer_ioctl(int dev, unsi
|
|
{
|
|
int val;
|
|
|
|
- val = *(int *) arg;
|
|
+ if (get_user(val, p))
|
|
+ return -EFAULT;
|
|
if (val)
|
|
set_timebase(midi_dev, val);
|
|
- return (*(int *) arg = curr_timebase);
|
|
+ if (put_user(curr_timebase, p))
|
|
+ return -EFAULT;
|
|
+ return curr_timebase;
|
|
}
|
|
break;
|
|
|
|
@@ -1549,7 +1556,8 @@ static int mpu_timer_ioctl(int dev, unsi
|
|
int val;
|
|
int ret;
|
|
|
|
- val = *(int *) arg;
|
|
+ if (get_user(val, p))
|
|
+ return -EFAULT;
|
|
|
|
if (val)
|
|
{
|
|
@@ -1564,7 +1572,9 @@ static int mpu_timer_ioctl(int dev, unsi
|
|
}
|
|
curr_tempo = val;
|
|
}
|
|
- return (*(int *) arg = curr_tempo);
|
|
+ if (put_user(curr_tempo, p))
|
|
+ return -EFAULT;
|
|
+ return curr_tempo;
|
|
}
|
|
break;
|
|
|
|
@@ -1572,18 +1582,25 @@ static int mpu_timer_ioctl(int dev, unsi
|
|
{
|
|
int val;
|
|
|
|
- val = *(int *) arg;
|
|
+ if (get_user(val, p))
|
|
+ return -EFAULT;
|
|
if (val != 0) /* Can't change */
|
|
return -EINVAL;
|
|
- return (*(int *) arg = ((curr_tempo * curr_timebase) + 30) / 60);
|
|
+ val = (curr_tempo * curr_timebase + 30) / 60;
|
|
+ if (put_user(val, p))
|
|
+ return -EFAULT;
|
|
+ return val;
|
|
}
|
|
break;
|
|
|
|
case SNDCTL_SEQ_GETTIME:
|
|
- return (*(int *) arg = curr_ticks);
|
|
+ if (put_user(curr_ticks, p))
|
|
+ return -EFAULT;
|
|
+ return curr_ticks;
|
|
|
|
case SNDCTL_TMR_METRONOME:
|
|
- metronome_mode = *(int *) arg;
|
|
+ if (get_user(metronome_mode, p))
|
|
+ return -EFAULT;
|
|
setup_metronome(midi_dev);
|
|
return 0;
|
|
|
|
--- linux/drivers/sound/msnd.c.bak Wed Jun 16 14:42:24 2004
|
|
+++ linux/drivers/sound/msnd.c Wed Jun 16 14:42:34 2004
|
|
@@ -155,13 +155,10 @@ void msnd_fifo_make_empty(msnd_fifo *f)
|
|
f->len = f->tail = f->head = 0;
|
|
}
|
|
|
|
-int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user)
|
|
+int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len)
|
|
{
|
|
int count = 0;
|
|
|
|
- if (f->len == f->n)
|
|
- return 0;
|
|
-
|
|
while ((count < len) && (f->len != f->n)) {
|
|
|
|
int nwritten;
|
|
@@ -177,11 +174,7 @@ int msnd_fifo_write(msnd_fifo *f, const
|
|
nwritten = len - count;
|
|
}
|
|
|
|
- if (user) {
|
|
- if (copy_from_user(f->data + f->tail, buf, nwritten))
|
|
- return -EFAULT;
|
|
- } else
|
|
- isa_memcpy_fromio(f->data + f->tail, (unsigned long) buf, nwritten);
|
|
+ isa_memcpy_fromio(f->data + f->tail, (unsigned long) buf, nwritten);
|
|
|
|
count += nwritten;
|
|
buf += nwritten;
|
|
@@ -193,13 +186,10 @@ int msnd_fifo_write(msnd_fifo *f, const
|
|
return count;
|
|
}
|
|
|
|
-int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user)
|
|
+int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len)
|
|
{
|
|
int count = 0;
|
|
|
|
- if (f->len == 0)
|
|
- return f->len;
|
|
-
|
|
while ((count < len) && (f->len > 0)) {
|
|
|
|
int nread;
|
|
@@ -215,11 +205,7 @@ int msnd_fifo_read(msnd_fifo *f, char *b
|
|
nread = len - count;
|
|
}
|
|
|
|
- if (user) {
|
|
- if (copy_to_user(buf, f->data + f->head, nread))
|
|
- return -EFAULT;
|
|
- } else
|
|
- isa_memcpy_toio((unsigned long) buf, f->data + f->head, nread);
|
|
+ isa_memcpy_toio((unsigned long) buf, f->data + f->head, nread);
|
|
|
|
count += nread;
|
|
buf += nread;
|
|
--- linux/drivers/sound/msnd.h.bak Wed Jun 16 14:42:24 2004
|
|
+++ linux/drivers/sound/msnd.h Wed Jun 16 14:42:34 2004
|
|
@@ -266,8 +266,8 @@ void msnd_fifo_init(msnd_fifo *f);
|
|
void msnd_fifo_free(msnd_fifo *f);
|
|
int msnd_fifo_alloc(msnd_fifo *f, size_t n);
|
|
void msnd_fifo_make_empty(msnd_fifo *f);
|
|
-int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len, int user);
|
|
-int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len, int user);
|
|
+int msnd_fifo_write(msnd_fifo *f, const char *buf, size_t len);
|
|
+int msnd_fifo_read(msnd_fifo *f, char *buf, size_t len);
|
|
|
|
int msnd_wait_TXDE(multisound_dev_t *dev);
|
|
int msnd_wait_HC0(multisound_dev_t *dev);
|
|
--- linux/drivers/sound/msnd_pinnacle.c.bak Wed Jun 16 14:42:24 2004
|
|
+++ linux/drivers/sound/msnd_pinnacle.c Wed Jun 16 14:42:34 2004
|
|
@@ -804,7 +804,7 @@ static int dev_release(struct inode *ino
|
|
|
|
static __inline__ int pack_DARQ_to_DARF(register int bank)
|
|
{
|
|
- register int size, n, timeout = 3;
|
|
+ register int size, timeout = 3;
|
|
register WORD wTmp;
|
|
LPDAQD DAQD;
|
|
|
|
@@ -825,13 +825,10 @@ static __inline__ int pack_DARQ_to_DARF(
|
|
/* Read data from the head (unprotected bank 1 access okay
|
|
since this is only called inside an interrupt) */
|
|
outb(HPBLKSEL_1, dev.io + HP_BLKS);
|
|
- if ((n = msnd_fifo_write(
|
|
+ msnd_fifo_write(
|
|
&dev.DARF,
|
|
(char *)(dev.base + bank * DAR_BUFF_SIZE),
|
|
- size, 0)) <= 0) {
|
|
- outb(HPBLKSEL_0, dev.io + HP_BLKS);
|
|
- return n;
|
|
- }
|
|
+ size);
|
|
outb(HPBLKSEL_0, dev.io + HP_BLKS);
|
|
|
|
return 1;
|
|
@@ -853,21 +850,16 @@ static __inline__ int pack_DAPF_to_DAPQ(
|
|
if (protect) {
|
|
/* Critical section: protect fifo in non-interrupt */
|
|
spin_lock_irqsave(&dev.lock, flags);
|
|
- if ((n = msnd_fifo_read(
|
|
+ n = msnd_fifo_read(
|
|
&dev.DAPF,
|
|
(char *)(dev.base + bank_num * DAP_BUFF_SIZE),
|
|
- DAP_BUFF_SIZE, 0)) < 0) {
|
|
- spin_unlock_irqrestore(&dev.lock, flags);
|
|
- return n;
|
|
- }
|
|
+ DAP_BUFF_SIZE);
|
|
spin_unlock_irqrestore(&dev.lock, flags);
|
|
} else {
|
|
- if ((n = msnd_fifo_read(
|
|
+ n = msnd_fifo_read(
|
|
&dev.DAPF,
|
|
(char *)(dev.base + bank_num * DAP_BUFF_SIZE),
|
|
- DAP_BUFF_SIZE, 0)) < 0) {
|
|
- return n;
|
|
- }
|
|
+ DAP_BUFF_SIZE);
|
|
}
|
|
if (!n)
|
|
break;
|
|
@@ -894,30 +886,43 @@ static __inline__ int pack_DAPF_to_DAPQ(
|
|
static int dsp_read(char *buf, size_t len)
|
|
{
|
|
int count = len;
|
|
+ char *page = (char *)__get_free_page(PAGE_SIZE);
|
|
+
|
|
+ if (!page)
|
|
+ return -ENOMEM;
|
|
|
|
while (count > 0) {
|
|
- int n;
|
|
+ int n, k;
|
|
unsigned long flags;
|
|
|
|
+ k = PAGE_SIZE;
|
|
+ if (k > count)
|
|
+ k = count;
|
|
+
|
|
/* Critical section: protect fifo in non-interrupt */
|
|
spin_lock_irqsave(&dev.lock, flags);
|
|
- if ((n = msnd_fifo_read(&dev.DARF, buf, count, 1)) < 0) {
|
|
- printk(KERN_WARNING LOGNAME ": FIFO read error\n");
|
|
- spin_unlock_irqrestore(&dev.lock, flags);
|
|
- return n;
|
|
- }
|
|
+ n = msnd_fifo_read(&dev.DARF, page, k);
|
|
spin_unlock_irqrestore(&dev.lock, flags);
|
|
+ if (copy_to_user(buf, page, n)) {
|
|
+ free_page((unsigned long)page);
|
|
+ return -EFAULT;
|
|
+ }
|
|
buf += n;
|
|
count -= n;
|
|
|
|
+ if (n == k && count)
|
|
+ continue;
|
|
+
|
|
if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) {
|
|
dev.last_recbank = -1;
|
|
if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0)
|
|
set_bit(F_READING, &dev.flags);
|
|
}
|
|
|
|
- if (dev.rec_ndelay)
|
|
+ if (dev.rec_ndelay) {
|
|
+ free_page((unsigned long)page);
|
|
return count == len ? -EAGAIN : len - count;
|
|
+ }
|
|
|
|
if (count > 0) {
|
|
set_bit(F_READBLOCK, &dev.flags);
|
|
@@ -926,41 +931,57 @@ static int dsp_read(char *buf, size_t le
|
|
get_rec_delay_jiffies(DAR_BUFF_SIZE)))
|
|
clear_bit(F_READING, &dev.flags);
|
|
clear_bit(F_READBLOCK, &dev.flags);
|
|
- if (signal_pending(current))
|
|
+ if (signal_pending(current)) {
|
|
+ free_page((unsigned long)page);
|
|
return -EINTR;
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
+ free_page((unsigned long)page);
|
|
return len - count;
|
|
}
|
|
|
|
static int dsp_write(const char *buf, size_t len)
|
|
{
|
|
int count = len;
|
|
+ char *page = (char *)__get_free_page(GFP_KERNEL);
|
|
+
|
|
+ if (!page)
|
|
+ return -ENOMEM;
|
|
|
|
while (count > 0) {
|
|
- int n;
|
|
+ int n, k;
|
|
unsigned long flags;
|
|
|
|
+ k = PAGE_SIZE;
|
|
+ if (k > count)
|
|
+ k = count;
|
|
+
|
|
+ if (copy_from_user(page, buf, k)) {
|
|
+ free_page((unsigned long)page);
|
|
+ return -EFAULT;
|
|
+ }
|
|
+
|
|
/* Critical section: protect fifo in non-interrupt */
|
|
spin_lock_irqsave(&dev.lock, flags);
|
|
- if ((n = msnd_fifo_write(&dev.DAPF, buf, count, 1)) < 0) {
|
|
- printk(KERN_WARNING LOGNAME ": FIFO write error\n");
|
|
- spin_unlock_irqrestore(&dev.lock, flags);
|
|
- return n;
|
|
- }
|
|
+ n = msnd_fifo_write(&dev.DAPF, page, k);
|
|
spin_unlock_irqrestore(&dev.lock, flags);
|
|
buf += n;
|
|
count -= n;
|
|
|
|
+ if (count && n == k)
|
|
+ continue;
|
|
+
|
|
if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
|
|
dev.last_playbank = -1;
|
|
if (pack_DAPF_to_DAPQ(1) > 0)
|
|
set_bit(F_WRITING, &dev.flags);
|
|
}
|
|
|
|
- if (dev.play_ndelay)
|
|
+ if (dev.play_ndelay) {
|
|
+ free_page((unsigned long)page);
|
|
return count == len ? -EAGAIN : len - count;
|
|
+ }
|
|
|
|
if (count > 0) {
|
|
set_bit(F_WRITEBLOCK, &dev.flags);
|
|
@@ -968,11 +989,14 @@ static int dsp_write(const char *buf, si
|
|
&dev.writeblock,
|
|
get_play_delay_jiffies(DAP_BUFF_SIZE));
|
|
clear_bit(F_WRITEBLOCK, &dev.flags);
|
|
- if (signal_pending(current))
|
|
+ if (signal_pending(current)) {
|
|
+ free_page((unsigned long)page);
|
|
return -EINTR;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ free_page((unsigned long)page);
|
|
return len - count;
|
|
}
|
|
|
|
--- linux/drivers/sound/pss.c.bak Wed Jun 16 14:42:24 2004
|
|
+++ linux/drivers/sound/pss.c Wed Jun 16 14:42:34 2004
|
|
@@ -450,20 +450,36 @@ static void pss_mixer_reset(pss_confdata
|
|
}
|
|
}
|
|
|
|
-static void arg_to_volume_mono(unsigned int volume, int *aleft)
|
|
+static int set_volume_mono(caddr_t p, int *aleft)
|
|
{
|
|
int left;
|
|
+ unsigned volume;
|
|
+ if (get_user(volume, (unsigned *)p))
|
|
+ return -EFAULT;
|
|
|
|
- left = volume & 0x00ff;
|
|
+ left = volume & 0xff;
|
|
if (left > 100)
|
|
left = 100;
|
|
*aleft = left;
|
|
+ return 0;
|
|
}
|
|
|
|
-static void arg_to_volume_stereo(unsigned int volume, int *aleft, int *aright)
|
|
+static int set_volume_stereo(caddr_t p, int *aleft, int *aright)
|
|
{
|
|
- arg_to_volume_mono(volume, aleft);
|
|
- arg_to_volume_mono(volume >> 8, aright);
|
|
+ int left, right;
|
|
+ unsigned volume;
|
|
+ if (get_user(volume, (unsigned *)p))
|
|
+ return -EFAULT;
|
|
+
|
|
+ left = volume & 0xff;
|
|
+ if (left > 100)
|
|
+ left = 100;
|
|
+ right = (volume >> 8) & 0xff;
|
|
+ if (right > 100)
|
|
+ right = 100;
|
|
+ *aleft = left;
|
|
+ *aright = right;
|
|
+ return 0;
|
|
}
|
|
|
|
static int ret_vol_mono(int left)
|
|
@@ -510,33 +526,38 @@ static int pss_mixer_ioctl (int dev, uns
|
|
return call_ad_mixer(devc, cmd, arg);
|
|
else
|
|
{
|
|
- if (*(int *)arg != 0)
|
|
+ int v;
|
|
+ if (get_user(v, (int *)arg))
|
|
+ return -EFAULT;
|
|
+ if (v != 0)
|
|
return -EINVAL;
|
|
return 0;
|
|
}
|
|
case SOUND_MIXER_VOLUME:
|
|
- arg_to_volume_stereo(*(unsigned int *)arg, &devc->mixer.volume_l,
|
|
- &devc->mixer.volume_r);
|
|
+ if (set_volume_stereo(arg,
|
|
+ &devc->mixer.volume_l,
|
|
+ &devc->mixer.volume_r))
|
|
+ return -EFAULT;
|
|
set_master_volume(devc, devc->mixer.volume_l,
|
|
devc->mixer.volume_r);
|
|
return ret_vol_stereo(devc->mixer.volume_l,
|
|
devc->mixer.volume_r);
|
|
|
|
case SOUND_MIXER_BASS:
|
|
- arg_to_volume_mono(*(unsigned int *)arg,
|
|
- &devc->mixer.bass);
|
|
+ if (set_volume_mono(arg, &devc->mixer.bass))
|
|
+ return -EFAULT;
|
|
set_bass(devc, devc->mixer.bass);
|
|
return ret_vol_mono(devc->mixer.bass);
|
|
|
|
case SOUND_MIXER_TREBLE:
|
|
- arg_to_volume_mono(*(unsigned int *)arg,
|
|
- &devc->mixer.treble);
|
|
+ if (set_volume_mono(arg, &devc->mixer.treble))
|
|
+ return -EFAULT;
|
|
set_treble(devc, devc->mixer.treble);
|
|
return ret_vol_mono(devc->mixer.treble);
|
|
|
|
case SOUND_MIXER_SYNTH:
|
|
- arg_to_volume_mono(*(unsigned int *)arg,
|
|
- &devc->mixer.synth);
|
|
+ if (set_volume_mono(arg, &devc->mixer.synth))
|
|
+ return -EFAULT;
|
|
set_synth_volume(devc, devc->mixer.synth);
|
|
return ret_vol_mono(devc->mixer.synth);
|
|
|
|
@@ -546,54 +567,67 @@ static int pss_mixer_ioctl (int dev, uns
|
|
}
|
|
else
|
|
{
|
|
+ int val, and_mask = 0, or_mask = 0;
|
|
/*
|
|
* Return parameters
|
|
*/
|
|
switch (cmdf)
|
|
{
|
|
-
|
|
case SOUND_MIXER_DEVMASK:
|
|
if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
|
|
- *(int *)arg = 0; /* no mixer devices */
|
|
- return (*(int *)arg |= SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH);
|
|
+ break;
|
|
+ and_mask = ~0;
|
|
+ or_mask = SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH;
|
|
+ break;
|
|
|
|
case SOUND_MIXER_STEREODEVS:
|
|
if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
|
|
- *(int *)arg = 0; /* no stereo devices */
|
|
- return (*(int *)arg |= SOUND_MASK_VOLUME);
|
|
+ break;
|
|
+ and_mask = ~0;
|
|
+ or_mask = SOUND_MASK_VOLUME;
|
|
+ break;
|
|
|
|
case SOUND_MIXER_RECMASK:
|
|
if (devc->ad_mixer_dev != NO_WSS_MIXER)
|
|
return call_ad_mixer(devc, cmd, arg);
|
|
- else
|
|
- return (*(int *)arg = 0); /* no record devices */
|
|
+ break;
|
|
|
|
case SOUND_MIXER_CAPS:
|
|
if (devc->ad_mixer_dev != NO_WSS_MIXER)
|
|
return call_ad_mixer(devc, cmd, arg);
|
|
- else
|
|
- return (*(int *)arg = SOUND_CAP_EXCL_INPUT);
|
|
+ or_mask = SOUND_CAP_EXCL_INPUT;
|
|
+ break;
|
|
|
|
case SOUND_MIXER_RECSRC:
|
|
if (devc->ad_mixer_dev != NO_WSS_MIXER)
|
|
return call_ad_mixer(devc, cmd, arg);
|
|
- else
|
|
- return (*(int *)arg = 0); /* no record source */
|
|
+ break;
|
|
|
|
case SOUND_MIXER_VOLUME:
|
|
- return (*(int *)arg = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r));
|
|
+ or_mask = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r);
|
|
+ break;
|
|
|
|
case SOUND_MIXER_BASS:
|
|
- return (*(int *)arg = ret_vol_mono(devc->mixer.bass));
|
|
+ or_mask = ret_vol_mono(devc->mixer.bass);
|
|
+ break;
|
|
|
|
case SOUND_MIXER_TREBLE:
|
|
- return (*(int *)arg = ret_vol_mono(devc->mixer.treble));
|
|
+ or_mask = ret_vol_mono(devc->mixer.treble);
|
|
+ break;
|
|
|
|
case SOUND_MIXER_SYNTH:
|
|
- return (*(int *)arg = ret_vol_mono(devc->mixer.synth));
|
|
+ or_mask = ret_vol_mono(devc->mixer.synth);
|
|
+ break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
+ if (get_user(val, (int *)arg))
|
|
+ return -EFAULT;
|
|
+ val &= and_mask;
|
|
+ val |= or_mask;
|
|
+ if (put_user(val, (int *)arg))
|
|
+ return -EFAULT;
|
|
+ return val;
|
|
}
|
|
}
|
|
|