git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git]
/
sound
/
oss
/
msnd_pinnacle.c
diff --git
a/sound/oss/msnd_pinnacle.c
b/sound/oss/msnd_pinnacle.c
index
aea4a65
..
eb345b6
100644
(file)
--- a/
sound/oss/msnd_pinnacle.c
+++ b/
sound/oss/msnd_pinnacle.c
@@
-212,6
+212,7
@@
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
LPDAQD lpDAQ, lpDARQ;
audio_buf_info abinfo;
unsigned long flags;
LPDAQD lpDAQ, lpDARQ;
audio_buf_info abinfo;
unsigned long flags;
+ int __user *p = (int __user *)arg;
lpDAQ = dev.base + DAPQ_DATA_BUFF;
lpDARQ = dev.base + DARQ_DATA_BUFF;
lpDAQ = dev.base + DAPQ_DATA_BUFF;
lpDARQ = dev.base + DARQ_DATA_BUFF;
@@
-238,7
+239,7
@@
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize;
abinfo.fragments = abinfo.bytes / abinfo.fragsize;
spin_unlock_irqrestore(&dev.lock, flags);
abinfo.fragstotal = dev.DAPF.n / abinfo.fragsize;
abinfo.fragments = abinfo.bytes / abinfo.fragsize;
spin_unlock_irqrestore(&dev.lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user((void
__user
*)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
case SNDCTL_DSP_GETISPACE:
if (!(file->f_mode & FMODE_READ))
@@
-249,7
+250,7
@@
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
abinfo.fragstotal = dev.DARF.n / abinfo.fragsize;
abinfo.fragments = abinfo.bytes / abinfo.fragsize;
spin_unlock_irqrestore(&dev.lock, flags);
abinfo.fragstotal = dev.DARF.n / abinfo.fragsize;
abinfo.fragments = abinfo.bytes / abinfo.fragsize;
spin_unlock_irqrestore(&dev.lock, flags);
- return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ return copy_to_user((void
__user
*)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
case SNDCTL_DSP_RESET:
dev.nresets = 0;
case SNDCTL_DSP_RESET:
dev.nresets = 0;
@@
-262,18
+263,18
@@
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case SNDCTL_DSP_GETBLKSIZE:
tmp = dsp_get_frag_size();
case SNDCTL_DSP_GETBLKSIZE:
tmp = dsp_get_frag_size();
- if (put_user(tmp,
(int *)arg
))
+ if (put_user(tmp,
p
))
return -EFAULT;
return 0;
case SNDCTL_DSP_GETFMTS:
val = AFMT_S16_LE | AFMT_U8;
return -EFAULT;
return 0;
case SNDCTL_DSP_GETFMTS:
val = AFMT_S16_LE | AFMT_U8;
- if (put_user(val,
(int *)arg
))
+ if (put_user(val,
p
))
return -EFAULT;
return 0;
case SNDCTL_DSP_SETFMT:
return -EFAULT;
return 0;
case SNDCTL_DSP_SETFMT:
- if (get_user(val,
(int *)arg
))
+ if (get_user(val,
p
))
return -EFAULT;
if (file->f_mode & FMODE_WRITE)
return -EFAULT;
if (file->f_mode & FMODE_WRITE)
@@
-285,7
+286,7
@@
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
? dev.rec_sample_size
: dsp_set_format(file, val);
? dev.rec_sample_size
: dsp_set_format(file, val);
- if (put_user(data,
(int *)arg
))
+ if (put_user(data,
p
))
return -EFAULT;
return 0;
return -EFAULT;
return 0;
@@
-299,12
+300,12
@@
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case SNDCTL_DSP_GETCAPS:
val = DSP_CAP_DUPLEX | DSP_CAP_BATCH;
case SNDCTL_DSP_GETCAPS:
val = DSP_CAP_DUPLEX | DSP_CAP_BATCH;
- if (put_user(val,
(int *)arg
))
+ if (put_user(val,
p
))
return -EFAULT;
return 0;
case SNDCTL_DSP_SPEED:
return -EFAULT;
return 0;
case SNDCTL_DSP_SPEED:
- if (get_user(val,
(int *)arg
))
+ if (get_user(val,
p
))
return -EFAULT;
if (val < 8000)
return -EFAULT;
if (val < 8000)
@@
-326,13
+327,13
@@
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (file->f_mode & FMODE_READ)
dev.rec_sample_rate = data;
if (file->f_mode & FMODE_READ)
dev.rec_sample_rate = data;
- if (put_user(data,
(int *)arg
))
+ if (put_user(data,
p
))
return -EFAULT;
return 0;
case SNDCTL_DSP_CHANNELS:
case SNDCTL_DSP_STEREO:
return -EFAULT;
return 0;
case SNDCTL_DSP_CHANNELS:
case SNDCTL_DSP_STEREO:
- if (get_user(val,
(int *)arg
))
+ if (get_user(val,
p
))
return -EFAULT;
if (cmd == SNDCTL_DSP_CHANNELS) {
return -EFAULT;
if (cmd == SNDCTL_DSP_CHANNELS) {
@@
-369,7
+370,7
@@
static int dsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (file->f_mode & FMODE_READ)
dev.rec_channels = data;
if (file->f_mode & FMODE_READ)
dev.rec_channels = data;
- if (put_user(val,
(int *)arg
))
+ if (put_user(val,
p
))
return -EFAULT;
return 0;
}
return -EFAULT;
return 0;
}
@@
-565,13
+566,13
@@
static int mixer_ioctl(unsigned int cmd, unsigned long arg)
mixer_info info;
set_mixer_info();
info.modify_counter = dev.mixer_mod_count;
mixer_info info;
set_mixer_info();
info.modify_counter = dev.mixer_mod_count;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void
__user
*)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
} else if (cmd == SOUND_OLD_MIXER_INFO) {
_old_mixer_info info;
set_mixer_info();
return -EFAULT;
return 0;
} else if (cmd == SOUND_OLD_MIXER_INFO) {
_old_mixer_info info;
set_mixer_info();
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ if (copy_to_user((void
__user
*)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
} else if (cmd == SOUND_MIXER_PRIVATE1) {
return -EFAULT;
return 0;
} else if (cmd == SOUND_MIXER_PRIVATE1) {
@@
-584,19
+585,19
@@
static int mixer_ioctl(unsigned int cmd, unsigned long arg)
if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
switch (cmd & 0xff) {
case SOUND_MIXER_RECSRC:
if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
switch (cmd & 0xff) {
case SOUND_MIXER_RECSRC:
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int
__user
*)arg))
return -EFAULT;
val = set_recsrc(val);
break;
default:
return -EFAULT;
val = set_recsrc(val);
break;
default:
- if (get_user(val, (int *)arg))
+ if (get_user(val, (int
__user
*)arg))
return -EFAULT;
val = mixer_set(cmd & 0xff, val);
break;
}
++dev.mixer_mod_count;
return -EFAULT;
val = mixer_set(cmd & 0xff, val);
break;
}
++dev.mixer_mod_count;
- return put_user(val, (int *)arg);
+ return put_user(val, (int
__user
*)arg);
} else {
switch (cmd & 0xff) {
case SOUND_MIXER_RECSRC:
} else {
switch (cmd & 0xff) {
case SOUND_MIXER_RECSRC:
@@
-638,7
+639,7
@@
static int mixer_ioctl(unsigned int cmd, unsigned long arg)
}
}
}
}
- return put_user(val, (int *)arg);
+ return put_user(val, (int
__user
*)arg);
}
return -EINVAL;
}
return -EINVAL;
@@
-650,7
+651,7
@@
static int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
if (cmd == OSS_GETVERSION) {
int sound_version = SOUND_VERSION;
if (cmd == OSS_GETVERSION) {
int sound_version = SOUND_VERSION;
- return put_user(sound_version, (int *)arg);
+ return put_user(sound_version, (int
__user
*)arg);
}
if (minor == dev.dsp_minor)
}
if (minor == dev.dsp_minor)
@@
-809,7
+810,7
@@
static int dev_release(struct inode *inode, struct file *file)
static __inline__ int pack_DARQ_to_DARF(register int bank)
{
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;
register WORD wTmp;
LPDAQD DAQD;
@@
-830,13
+831,10
@@
static __inline__ int pack_DARQ_to_DARF(register int bank)
/* 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);
/* 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),
&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;
outb(HPBLKSEL_0, dev.io + HP_BLKS);
return 1;
@@
-858,21
+856,16
@@
static __inline__ int pack_DAPF_to_DAPQ(register int start)
if (protect) {
/* Critical section: protect fifo in non-interrupt */
spin_lock_irqsave(&dev.lock, flags);
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),
&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 {
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),
&dev.DAPF,
(char *)(dev.base + bank_num * DAP_BUFF_SIZE),
- DAP_BUFF_SIZE, 0)) < 0) {
- return n;
- }
+ DAP_BUFF_SIZE);
}
if (!n)
break;
}
if (!n)
break;
@@
-896,33
+889,46
@@
static __inline__ int pack_DAPF_to_DAPQ(register int start)
return nbanks;
}
return nbanks;
}
-static int dsp_read(char *buf, size_t len)
+static int dsp_read(char
__user
*buf, size_t len)
{
int count = len;
{
int count = len;
+ char *page = (char *)__get_free_page(PAGE_SIZE);
+
+ if (!page)
+ return -ENOMEM;
while (count > 0) {
while (count > 0) {
- int n;
+ int n
, k
;
unsigned long flags;
unsigned long flags;
+ k = PAGE_SIZE;
+ if (k > count)
+ k = count;
+
/* Critical section: protect fifo in non-interrupt */
spin_lock_irqsave(&dev.lock, flags);
/* 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);
spin_unlock_irqrestore(&dev.lock, flags);
+ if (copy_to_user(buf, page, n)) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
buf += n;
count -= n;
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 (!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;
return count == len ? -EAGAIN : len - count;
+ }
if (count > 0) {
set_bit(F_READBLOCK, &dev.flags);
if (count > 0) {
set_bit(F_READBLOCK, &dev.flags);
@@
-931,41
+937,57
@@
static int dsp_read(char *buf, size_t len)
get_rec_delay_jiffies(DAR_BUFF_SIZE)))
clear_bit(F_READING, &dev.flags);
clear_bit(F_READBLOCK, &dev.flags);
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;
return -EINTR;
+ }
}
}
}
}
-
+ free_page((unsigned long)page);
return len - count;
}
return len - count;
}
-static int dsp_write(const char *buf, size_t len)
+static int dsp_write(const char
__user
*buf, size_t len)
{
int count = len;
{
int count = len;
+ char *page = (char *)__get_free_page(GFP_KERNEL);
+
+ if (!page)
+ return -ENOMEM;
while (count > 0) {
while (count > 0) {
- int n;
+ int n
, k
;
unsigned long flags;
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);
/* 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;
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 (!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;
return count == len ? -EAGAIN : len - count;
+ }
if (count > 0) {
set_bit(F_WRITEBLOCK, &dev.flags);
if (count > 0) {
set_bit(F_WRITEBLOCK, &dev.flags);
@@
-973,15
+995,18
@@
static int dsp_write(const char *buf, size_t len)
&dev.writeblock,
get_play_delay_jiffies(DAP_BUFF_SIZE));
clear_bit(F_WRITEBLOCK, &dev.flags);
&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;
return -EINTR;
+ }
}
}
}
}
+ free_page((unsigned long)page);
return len - count;
}
return len - count;
}
-static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off)
+static ssize_t dev_read(struct file *file, char
__user
*buf, size_t count, loff_t *off)
{
int minor = iminor(file->f_dentry->d_inode);
if (minor == dev.dsp_minor)
{
int minor = iminor(file->f_dentry->d_inode);
if (minor == dev.dsp_minor)
@@
-990,7
+1015,7
@@
static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off)
return -EINVAL;
}
return -EINVAL;
}
-static ssize_t dev_write(struct file *file, const char *buf, size_t count, loff_t *off)
+static ssize_t dev_write(struct file *file, const char
__user
*buf, size_t count, loff_t *off)
{
int minor = iminor(file->f_dentry->d_inode);
if (minor == dev.dsp_minor)
{
int minor = iminor(file->f_dentry->d_inode);
if (minor == dev.dsp_minor)
@@
-1120,11
+1145,10
@@
static int __init probe_multisound(void)
char *pinfiji = "Pinnacle/Fiji";
#endif
char *pinfiji = "Pinnacle/Fiji";
#endif
- if (
check_region(dev.io, dev.numio
)) {
+ if (
!request_region(dev.io, dev.numio, "probing"
)) {
printk(KERN_ERR LOGNAME ": I/O port conflict\n");
return -ENODEV;
}
printk(KERN_ERR LOGNAME ": I/O port conflict\n");
return -ENODEV;
}
- request_region(dev.io, dev.numio, "probing");
if (reset_dsp() < 0) {
release_region(dev.io, dev.numio);
if (reset_dsp() < 0) {
release_region(dev.io, dev.numio);
@@
-1808,12
+1832,11
@@
static int __init msnd_init(void)
/* Joystick */
pinnacle_devs[3].io0 = joystick_io;
/* Joystick */
pinnacle_devs[3].io0 = joystick_io;
- if (
check_region(cfg, 2
)) {
+ if (
!request_region(cfg, 2, "Pinnacle/Fiji Config"
)) {
printk(KERN_ERR LOGNAME ": Config port 0x%x conflict\n", cfg);
return -EIO;
}
printk(KERN_ERR LOGNAME ": Config port 0x%x conflict\n", cfg);
return -EIO;
}
- request_region(cfg, 2, "Pinnacle/Fiji Config");
if (msnd_pinnacle_cfg_devices(cfg, reset, pinnacle_devs)) {
printk(KERN_ERR LOGNAME ": Device configuration error\n");
release_region(cfg, 2);
if (msnd_pinnacle_cfg_devices(cfg, reset, pinnacle_devs)) {
printk(KERN_ERR LOGNAME ": Device configuration error\n");
release_region(cfg, 2);