X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Foss%2Femu10k1%2Faudio.c;h=efcf589d7083401450d2c743d36b65e5cedbf6ee;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=42fae03b16a7e6745de4920304058fbef9f484c4;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/oss/emu10k1/audio.c b/sound/oss/emu10k1/audio.c index 42fae03b1..efcf589d7 100644 --- a/sound/oss/emu10k1/audio.c +++ b/sound/oss/emu10k1/audio.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "hwaccess.h" @@ -49,8 +50,11 @@ static void calculate_ofrag(struct woinst *); static void calculate_ifrag(struct wiinst *); +static void emu10k1_waveout_bh(unsigned long refdata); +static void emu10k1_wavein_bh(unsigned long refdata); + /* Audio file operations */ -static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, loff_t * ppos) +static ssize_t emu10k1_audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos) { struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data; struct wiinst *wiinst = wave_dev->wiinst; @@ -59,9 +63,6 @@ static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, DPD(3, "emu10k1_audio_read(), buffer=%p, count=%d\n", buffer, (u32) count); - if (ppos != &file->f_pos) - return -ESPIPE; - if (!access_ok(VERIFY_WRITE, buffer, count)) return -EFAULT; @@ -110,9 +111,15 @@ static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, if ((bytestocopy >= wiinst->buffer.fragment_size) || (bytestocopy >= count)) { + int rc; + bytestocopy = min_t(u32, bytestocopy, count); - emu10k1_wavein_xferdata(wiinst, (u8 *) buffer, &bytestocopy); + rc = emu10k1_wavein_xferdata(wiinst, + (u8 __user *)buffer, + &bytestocopy); + if (rc) + return rc; count -= bytestocopy; buffer += bytestocopy; @@ -137,7 +144,7 @@ static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, return ret; } -static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) +static ssize_t emu10k1_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t * ppos) { struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data; struct woinst *woinst = wave_dev->woinst; @@ -146,9 +153,6 @@ static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t DPD(3, "emu10k1_audio_write(), buffer=%p, count=%d\n", buffer, (u32) count); - if (ppos != &file->f_pos) - return -ESPIPE; - if (!access_ok(VERIFY_READ, buffer, count)) return -EFAULT; @@ -212,7 +216,7 @@ static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t bytestocopy = min_t(u32, bytestocopy, count); - emu10k1_waveout_xferdata(woinst, (u8 *) buffer, &bytestocopy); + emu10k1_waveout_xferdata(woinst, (u8 __user *) buffer, &bytestocopy); count -= bytestocopy; buffer += bytestocopy * woinst->num_voices; @@ -254,6 +258,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned int val = 0; u32 bytestocopy; unsigned long flags; + int __user *p = (int __user *)arg; DPF(4, "emu10k1_audio_ioctl()\n"); @@ -266,7 +271,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned switch (cmd) { case OSS_GETVERSION: DPF(2, "OSS_GETVERSION:\n"); - return put_user(SOUND_VERSION, (int *) arg); + return put_user(SOUND_VERSION, p); case SNDCTL_DSP_RESET: DPF(2, "SNDCTL_DSP_RESET:\n"); @@ -352,11 +357,11 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned DPF(2, "SNDCTL_DSP_GETCAPS:\n"); return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | - DSP_CAP_COPROC| DSP_CAP_MULTI, (int *) arg); + DSP_CAP_COPROC| DSP_CAP_MULTI, p); case SNDCTL_DSP_SPEED: DPF(2, "SNDCTL_DSP_SPEED:\n"); - if (get_user(val, (int *) arg)) + if (get_user(val, p)) return -EFAULT; DPD(2, "val is %d\n", val); @@ -402,21 +407,21 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned DPD(2, "set playback sampling rate -> %d\n", val); } - return put_user(val, (int *) arg); + return put_user(val, p); } else { if (file->f_mode & FMODE_READ) val = wiinst->format.samplingrate; else if (file->f_mode & FMODE_WRITE) val = woinst->format.samplingrate; - return put_user(val, (int *) arg); + return put_user(val, p); } break; case SNDCTL_DSP_STEREO: DPF(2, "SNDCTL_DSP_STEREO:\n"); - if (get_user(val, (int *) arg)) + if (get_user(val, p)) return -EFAULT; DPD(2, " val is %d\n", val); @@ -460,14 +465,14 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned DPD(2, "set playback stereo -> %d\n", val); } - return put_user(val, (int *) arg); + return put_user(val, p); break; case SNDCTL_DSP_CHANNELS: DPF(2, "SNDCTL_DSP_CHANNELS:\n"); - if (get_user(val, (int *) arg)) + if (get_user(val, p)) return -EFAULT; DPD(2, " val is %d\n", val); @@ -510,14 +515,14 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned DPD(2, "set playback number of channels -> %d\n", val); } - return put_user(val, (int *) arg); + return put_user(val, p); } else { if (file->f_mode & FMODE_READ) val = wiinst->format.channels; else if (file->f_mode & FMODE_WRITE) val = woinst->format.channels; - return put_user(val, (int *) arg); + return put_user(val, p); } break; @@ -533,12 +538,12 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned wave_dev->card->pt.enable_gpr_name) >= 0) val |= AFMT_AC3; } - return put_user(val, (int *) arg); + return put_user(val, p); case SNDCTL_DSP_SETFMT: /* Same as SNDCTL_DSP_SAMPLESIZE */ DPF(2, "SNDCTL_DSP_SETFMT:\n"); - if (get_user(val, (int *) arg)) + if (get_user(val, p)) return -EFAULT; DPD(2, " val is %d\n", val); @@ -582,14 +587,14 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned DPD(2, "set playback format -> %d\n", val); } - return put_user(val, (int *) arg); + return put_user(val, p); } else { if (file->f_mode & FMODE_READ) val = wiinst->format.id; else if (file->f_mode & FMODE_WRITE) val = woinst->format.id; - return put_user(val, (int *) arg); + return put_user(val, p); } break; @@ -600,7 +605,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned else if (file->f_mode & FMODE_WRITE) val = woinst->format.bitsperchannel; - return put_user(val, (int *) arg); + return put_user(val, p); case SOUND_PCM_READ_RATE: @@ -609,7 +614,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned else if (file->f_mode & FMODE_WRITE) val = woinst->format.samplingrate; - return put_user(val, (int *) arg); + return put_user(val, p); case SOUND_PCM_READ_CHANNELS: @@ -618,7 +623,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned else if (file->f_mode & FMODE_WRITE) val = woinst->format.channels; - return put_user(val, (int *) arg); + return put_user(val, p); case SOUND_PCM_WRITE_FILTER: DPF(2, "SOUND_PCM_WRITE_FILTER: not implemented\n"); @@ -641,12 +646,12 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned if (file->f_mode & FMODE_READ && (wave_dev->enablebits & PCM_ENABLE_INPUT)) val |= PCM_ENABLE_INPUT; - return put_user(val, (int *) arg); + return put_user(val, p); case SNDCTL_DSP_SETTRIGGER: DPF(2, "SNDCTL_DSP_SETTRIGGER:\n"); - if (get_user(val, (int *) arg)) + if (get_user(val, p)) return -EFAULT; if (file->f_mode & FMODE_WRITE) { @@ -708,7 +713,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned info.fragstotal = woinst->buffer.numfrags * woinst->num_voices; info.fragments = info.bytes / info.fragsize; - if (copy_to_user((int *) arg, &info, sizeof(info))) + if (copy_to_user(p, &info, sizeof(info))) return -EFAULT; } break; @@ -737,7 +742,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned info.fragments = info.bytes / wiinst->buffer.fragment_size; info.fragsize = wiinst->buffer.fragment_size; - if (copy_to_user((int *) arg, &info, sizeof(info))) + if (copy_to_user(p, &info, sizeof(info))) return -EFAULT; } break; @@ -765,7 +770,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned val *= woinst->num_voices; spin_unlock_irqrestore(&woinst->lock, flags); - return put_user(val, (int *) arg); + return put_user(val, p); case SNDCTL_DSP_GETIPTR: { @@ -795,7 +800,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned spin_unlock_irqrestore(&wiinst->lock, flags); - if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo))) + if (copy_to_user(p, &cinfo, sizeof(cinfo))) return -EFAULT; } break; @@ -841,7 +846,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned spin_unlock_irqrestore(&woinst->lock, flags); - if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo))) + if (copy_to_user(p, &cinfo, sizeof(cinfo))) return -EFAULT; } break; @@ -867,7 +872,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned spin_unlock_irqrestore(&wiinst->lock, flags); } - return put_user(val, (int *) arg); + return put_user(val, p); break; @@ -892,7 +897,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned case SNDCTL_DSP_SETFRAGMENT: DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n"); - if (get_user(val, (int *) arg)) + if (get_user(val, p)) return -EFAULT; DPD(2, "val is %#x\n", val); @@ -930,7 +935,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned if (!buf) return -ENOMEM; - if (copy_from_user(buf, (copr_buffer *) arg, sizeof(copr_buffer))) { + if (copy_from_user(buf, p, sizeof(copr_buffer))) { kfree (buf); return -EFAULT; } @@ -969,7 +974,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned for (i = 0; i < buf->len; i++) ((u32 *) buf->data)[i] = sblive_readptr(wave_dev->card, buf->offs + i, buf->flags); - if (copy_to_user((copr_buffer *) arg, buf, sizeof(copr_buffer))) { + if (copy_to_user(p, buf, sizeof(copr_buffer))) { kfree(buf); return -EFAULT; } @@ -1037,7 +1042,7 @@ static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned lon return dmapage; } -struct vm_operations_struct emu10k1_mm_ops = { +static struct vm_operations_struct emu10k1_mm_ops = { .nopage = emu10k1_mm_nopage, }; @@ -1134,7 +1139,7 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file) match: - wave_dev = (struct emu10k1_wavedevice *) kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL); + wave_dev = kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL); if (wave_dev == NULL) { ERROR(); @@ -1150,7 +1155,7 @@ match: /* Recording */ struct wiinst *wiinst; - if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) { + if ((wiinst = kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) { ERROR(); kfree(wave_dev); return -ENOMEM; @@ -1196,7 +1201,7 @@ match: wiinst->mmapped = 0; wiinst->total_recorded = 0; wiinst->blocks = 0; - wiinst->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&wiinst->lock); tasklet_init(&wiinst->timer.tasklet, emu10k1_wavein_bh, (unsigned long) wave_dev); wave_dev->wiinst = wiinst; emu10k1_wavein_setformat(wave_dev, &wiinst->format); @@ -1206,7 +1211,7 @@ match: struct woinst *woinst; int i; - if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) { + if ((woinst = kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) { ERROR(); kfree(wave_dev); return -ENOMEM; @@ -1240,7 +1245,7 @@ match: woinst->total_copied = 0; woinst->total_played = 0; woinst->blocks = 0; - woinst->lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&woinst->lock); tasklet_init(&woinst->timer.tasklet, emu10k1_waveout_bh, (unsigned long) wave_dev); wave_dev->woinst = woinst; emu10k1_waveout_setformat(wave_dev, &woinst->format); @@ -1248,7 +1253,7 @@ match: file->private_data = (void *) wave_dev; - return 0; + return nonseekable_open(inode, file); } static int emu10k1_audio_release(struct inode *inode, struct file *file) @@ -1511,7 +1516,7 @@ static void calculate_ifrag(struct wiinst *wiinst) return; } -void emu10k1_wavein_bh(unsigned long refdata) +static void emu10k1_wavein_bh(unsigned long refdata) { struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata; struct wiinst *wiinst = wave_dev->wiinst; @@ -1542,7 +1547,7 @@ void emu10k1_wavein_bh(unsigned long refdata) return; } -void emu10k1_waveout_bh(unsigned long refdata) +static void emu10k1_waveout_bh(unsigned long refdata) { struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata; struct woinst *woinst = wave_dev->woinst;