X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Foss%2Frme96xx.c;h=f17d25b6f8369b62ba256cdd63a9ade83b55b4b2;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=9e966932095277f98e6de08b71d1ddbb21333b82;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c index 9e9669320..f17d25b6f 100644 --- a/sound/oss/rme96xx.c +++ b/sound/oss/rme96xx.c @@ -44,7 +44,6 @@ TODO: #define RMEVERSION "0.8" #endif -#include #include #include #include @@ -54,11 +53,12 @@ TODO: #include #include #include -#include +#include #include #include #include #include +#include #include #include @@ -68,7 +68,7 @@ TODO: #define NR_DEVICE 2 static int devices = 1; -MODULE_PARM(devices, "1-" __MODULE_STRING(NR_DEVICE) "i"); +module_param(devices, int, 0); MODULE_PARM_DESC(devices, "number of dsp devices allocated by the driver"); @@ -273,7 +273,7 @@ typedef struct _rme96xx_info { /* hardware settings */ int magic; struct pci_dev * pcidev; /* pci_dev structure */ - unsigned long *iobase; + unsigned long __iomem *iobase; unsigned int irq; /* list of rme96xx devices */ @@ -327,7 +327,7 @@ typedef struct _rme96xx_info { /* waiting and locking */ wait_queue_head_t wait; - struct semaphore open_sem; + struct mutex open_mutex; wait_queue_head_t open_wait; } dma[RME96xx_MAX_DEVS]; @@ -339,7 +339,7 @@ typedef struct _rme96xx_info { /* fiddling with the card (first level hardware control) */ -inline void rme96xx_set_ctrl(rme96xx_info* s,int mask) +static inline void rme96xx_set_ctrl(rme96xx_info* s,int mask) { s->control_register|=mask; @@ -347,7 +347,7 @@ inline void rme96xx_set_ctrl(rme96xx_info* s,int mask) } -inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask) +static inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask) { s->control_register&=(~mask); @@ -355,7 +355,7 @@ inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask) } -inline int rme96xx_get_sample_rate_status(rme96xx_info* s) +static inline int rme96xx_get_sample_rate_status(rme96xx_info* s) { int val; u32 status; @@ -366,7 +366,7 @@ inline int rme96xx_get_sample_rate_status(rme96xx_info* s) return val; } -inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s) +static inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s) { int val; val = (s->control_register & RME96xx_freq) ? 48000 : 44100; @@ -539,7 +539,7 @@ static inline int rme96xx_spdif_sample_rate (rme96xx_info *s, int *spdifrate) /* the function returns the hardware pointer in bytes */ #define RME96xx_BURSTBYTES -64 /* bytes by which hwptr could be off */ -inline int rme96xx_gethwptr(rme96xx_info* s,int exact) +static inline int rme96xx_gethwptr(rme96xx_info* s,int exact) { unsigned long flags; if (exact) { @@ -557,7 +557,7 @@ inline int rme96xx_gethwptr(rme96xx_info* s,int exact) return (s->hwbufid ? s->fragsize : 0); } -inline void rme96xx_setlatency(rme96xx_info* s,int l) +static inline void rme96xx_setlatency(rme96xx_info* s,int l) { s->latency = l; s->fragsize = 1<<(8+l); @@ -626,7 +626,7 @@ static int rme96xx_startcard(rme96xx_info *s,int stop) } -inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp) +static inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp) { int cnt; int swptr; @@ -643,7 +643,7 @@ inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp) return cnt; } -inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp) +static inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp) { int cnt; int swptr; @@ -661,13 +661,13 @@ inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp) } -inline int rme96xx_copyfromuser(struct dmabuf* dma,const char* buffer,int count,int hop) +static inline int rme96xx_copyfromuser(struct dmabuf* dma,const char __user * buffer,int count,int hop) { int swptr = dma->writeptr; switch (dma->format) { case AFMT_S32_BLOCKED: { - char* buf = (char*)buffer; + char __user * buf = (char __user *)buffer; int cnt = count/dma->outchannels; int i; for (i=0;i < dma->outchannels;i++) { @@ -686,7 +686,7 @@ inline int rme96xx_copyfromuser(struct dmabuf* dma,const char* buffer,int count, int i,j; int cnt = count/dma->outchannels; for (i=0;i < dma->outchannels + dma->mono;i++) { - short* sbuf = (short*)buffer + i*(!dma->mono); + short __user * sbuf = (short __user *)buffer + i*(!dma->mono); short* hwbuf =(short*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES]; hwbuf+=(swptr>>1); for (j=0;j<(cnt>>1);j++) { @@ -710,13 +710,13 @@ inline int rme96xx_copyfromuser(struct dmabuf* dma,const char* buffer,int count, } /* The count argument is the number of bytes */ -inline int rme96xx_copytouser(struct dmabuf* dma,const char* buffer,int count,int hop) +static inline int rme96xx_copytouser(struct dmabuf* dma,const char __user* buffer,int count,int hop) { int swptr = dma->readptr; switch (dma->format) { case AFMT_S32_BLOCKED: { - char* buf = (char*)buffer; + char __user * buf = (char __user *)buffer; int cnt = count/dma->inchannels; int i; @@ -736,7 +736,7 @@ inline int rme96xx_copytouser(struct dmabuf* dma,const char* buffer,int count,in int i,j; int cnt = count/dma->inchannels; for (i=0;i < dma->inchannels;i++) { - short* sbuf = (short*)buffer + i; + short __user * sbuf = (short __user *)buffer + i; short* hwbuf =(short*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES]; hwbuf+=(swptr>>1); for (j=0;j<(cnt>>1);j++) { @@ -793,7 +793,7 @@ static irqreturn_t rme96xx_interrupt(int irq, void *dev_id, struct pt_regs *regs PCI detection and module initialization stuff ----------------------------------------------------------------------------*/ -void* busmaster_malloc(int size) { +static void* busmaster_malloc(int size) { int pg; /* 2 s exponent of memory size */ char *buf; @@ -807,7 +807,7 @@ void* busmaster_malloc(int size) { struct page* page, *last_page; page = virt_to_page(buf); - last_page = virt_to_page(buf + (1 << pg)); + last_page = page + (1 << pg); DBG(printk("setting reserved bit\n")); while (page < last_page) { SetPageReserved(page); @@ -819,7 +819,7 @@ void* busmaster_malloc(int size) { return NULL; } -void busmaster_free(void* ptr,int size) { +static void busmaster_free(void* ptr,int size) { int pg; struct page* page, *last_page; @@ -843,7 +843,7 @@ void busmaster_free(void* ptr,int size) { static int rme96xx_dmabuf_init(rme96xx_info * s,struct dmabuf* dma,int ioffset,int ooffset) { - init_MUTEX(&dma->open_sem); + mutex_init(&dma->open_mutex); init_waitqueue_head(&dma->open_wait); init_waitqueue_head(&dma->wait); dma->s = s; @@ -866,7 +866,7 @@ static int rme96xx_dmabuf_init(rme96xx_info * s,struct dmabuf* dma,int ioffset,i } -int rme96xx_init(rme96xx_info* s) +static int rme96xx_init(rme96xx_info* s) { int i; int status; @@ -994,7 +994,7 @@ static int __devinit rme96xx_probe(struct pci_dev *pcidev, const struct pci_devi if (pci_enable_device(pcidev)) goto err_irq; - if (request_irq(s->irq, rme96xx_interrupt, SA_SHIRQ, "rme96xx", s)) { + if (request_irq(s->irq, rme96xx_interrupt, IRQF_SHARED, "rme96xx", s)) { printk(KERN_ERR RME_MESS" irq %u in use\n", s->irq); goto err_irq; } @@ -1096,7 +1096,7 @@ static int __init init_rme96xx(void) devices = ((devices-1) & RME96xx_MASK_DEVS) + 1; printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices); numcards = 0; - return pci_module_init(&rme96xx_driver); + return pci_register_driver(&rme96xx_driver); } static void __exit cleanup_rme96xx(void) @@ -1121,7 +1121,6 @@ module_exit(cleanup_rme96xx); static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg) { - struct dmabuf * dma = (struct dmabuf *)file->private_data; rme96xx_info *s = dma->s; unsigned long flags; @@ -1129,6 +1128,8 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, count_info cinfo; int count; int val = 0; + void __user *argp = (void __user *)arg; + int __user *p = argp; VALIDATE_STATE(s); @@ -1136,7 +1137,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, switch (cmd) { case OSS_GETVERSION: - return put_user(SOUND_VERSION, (int *)arg); + return put_user(SOUND_VERSION, p); case SNDCTL_DSP_SYNC: #if 0 @@ -1149,14 +1150,14 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, return 0; case SNDCTL_DSP_GETCAPS: - return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg); + return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); case SNDCTL_DSP_RESET: // rme96xx_clearbufs(dma); return 0; case SNDCTL_DSP_SPEED: - if (get_user(val, (int *)arg)) + if (get_user(val, p)) return -EFAULT; if (val >= 0) { /* generally it's not a problem if we change the speed @@ -1195,10 +1196,10 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, spin_unlock_irqrestore(&s->lock, flags); } DBG(printk("speed set to %d\n",val)); - return put_user(val, (int *)arg); + return put_user(val, p); case SNDCTL_DSP_STEREO: /* this plays a mono file on two channels */ - if (get_user(val, (int *)arg)) + if (get_user(val, p)) return -EFAULT; if (!val) { @@ -1216,7 +1217,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, return 0; case SNDCTL_DSP_CHANNELS: /* remember to check for resonable offset/channel pairs here */ - if (get_user(val, (int *)arg)) + if (get_user(val, p)) return -EFAULT; if (file->f_mode & FMODE_WRITE) { @@ -1236,14 +1237,14 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, dma->mono=0; - return put_user(val, (int *)arg); + return put_user(val, p); case SNDCTL_DSP_GETFMTS: /* Returns a mask */ - return put_user(RME96xx_FMT, (int *)arg); + return put_user(RME96xx_FMT, p); case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ DBG(printk("setting to format %x\n",val)); - if (get_user(val, (int *)arg)) + if (get_user(val, p)) return -EFAULT; if (val != AFMT_QUERY) { if (val & RME96xx_FMT) @@ -1257,7 +1258,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, break; } } - return put_user(dma->format, (int *)arg); + return put_user(dma->format, p); case SNDCTL_DSP_POST: return 0; @@ -1270,10 +1271,10 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) val |= PCM_ENABLE_OUTPUT; #endif - return put_user(val, (int *)arg); + return put_user(val, p); case SNDCTL_DSP_SETTRIGGER: - if (get_user(val, (int *)arg)) + if (get_user(val, p)) return -EFAULT; #if 0 if (file->f_mode & FMODE_READ) { @@ -1309,7 +1310,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, abinfo.fragstotal = 2; abinfo.fragments = (count > s->fragsize); - return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; case SNDCTL_DSP_GETISPACE: if (!(file->f_mode & FMODE_READ)) @@ -1323,7 +1324,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, abinfo.bytes = (count*dma->inchannels)>>dma->formatshift; abinfo.fragstotal = 2; abinfo.fragments = count > s->fragsize; - return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; case SNDCTL_DSP_NONBLOCK: file->f_flags |= O_NONBLOCK; @@ -1339,7 +1340,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, if (count < 0) count += s->fragsize<<1; - return put_user(count, (int *)arg); + return put_user(count, p); /* check out how to use mmaped mode (can only be blocked !!!) */ @@ -1359,7 +1360,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, dma->readptr &= s->fragsize<<1; spin_unlock_irqrestore(&s->lock,flags); - if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo))) + if (copy_to_user(argp, &cinfo, sizeof(cinfo))) return -EFAULT; return 0; @@ -1378,14 +1379,14 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, if (dma->mmapped) dma->writeptr &= s->fragsize<<1; spin_unlock_irqrestore(&s->lock,flags); - if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo))) + if (copy_to_user(argp, &cinfo, sizeof(cinfo))) return -EFAULT; return 0; case SNDCTL_DSP_GETBLKSIZE: - return put_user(s->fragsize, (int *)arg); + return put_user(s->fragsize, p); case SNDCTL_DSP_SETFRAGMENT: - if (get_user(val, (int *)arg)) + if (get_user(val, p)) return -EFAULT; val&=0xffff; val -= 7; @@ -1399,7 +1400,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision)) return -EINVAL; - if (get_user(val, (int *)arg)) + if (get_user(val, p)) return -EFAULT; if (val != 1 && val != 2 && val != 4) return -EINVAL; @@ -1413,10 +1414,10 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, case SOUND_PCM_READ_RATE: /* HP20020201 */ s->rate = rme96xx_get_sample_rate_status(s); - return put_user(s->rate, (int *)arg); + return put_user(s->rate, p); case SOUND_PCM_READ_CHANNELS: - return put_user(dma->outchannels, (int *)arg); + return put_user(dma->outchannels, p); case SOUND_PCM_READ_BITS: switch (dma->format) { @@ -1427,7 +1428,7 @@ static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, val = 16; break; } - return put_user(val, (int *)arg); + return put_user(val, p); case SOUND_PCM_WRITE_FILTER: case SNDCTL_DSP_SETSYNCRO: @@ -1453,6 +1454,7 @@ static int rme96xx_open(struct inode *in, struct file *f) DBG(printk("device num %d open\n",devnum)); + nonseekable_open(in, f); for (list = devs.next; ; list = list->next) { if (list == &devs) return -ENODEV; @@ -1468,21 +1470,21 @@ static int rme96xx_open(struct inode *in, struct file *f) dma = &s->dma[devnum]; f->private_data = dma; /* wait for device to become free */ - down(&dma->open_sem); + mutex_lock(&dma->open_mutex); while (dma->open_mode & f->f_mode) { if (f->f_flags & O_NONBLOCK) { - up(&dma->open_sem); + mutex_unlock(&dma->open_mutex); return -EBUSY; } add_wait_queue(&dma->open_wait, &wait); __set_current_state(TASK_INTERRUPTIBLE); - up(&dma->open_sem); + mutex_unlock(&dma->open_mutex); schedule(); remove_wait_queue(&dma->open_wait, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; - down(&dma->open_sem); + mutex_lock(&dma->open_mutex); } COMM ("hardware open") @@ -1491,7 +1493,7 @@ static int rme96xx_open(struct inode *in, struct file *f) dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE)); dma->opened = 1; - up(&dma->open_sem); + mutex_unlock(&dma->open_mutex); DBG(printk("device num %d open finished\n",devnum)); return 0; @@ -1523,13 +1525,13 @@ static int rme96xx_release(struct inode *in, struct file *file) } wake_up(&dma->open_wait); - up(&dma->open_sem); + mutex_unlock(&dma->open_mutex); return 0; } -static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) +static ssize_t rme96xx_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { struct dmabuf *dma = (struct dmabuf *)file->private_data; ssize_t ret = 0; @@ -1542,9 +1544,6 @@ static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count if(dma == NULL || (dma->s) == NULL) return -ENXIO; - if (ppos != &file->f_pos) - return -ESPIPE; - if (dma->mmapped || !dma->opened) return -ENXIO; @@ -1597,7 +1596,7 @@ static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count return ret; } -static ssize_t rme96xx_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +static ssize_t rme96xx_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { struct dmabuf *dma = (struct dmabuf *)file->private_data; ssize_t ret = 0; @@ -1610,9 +1609,6 @@ static ssize_t rme96xx_read(struct file *file, char *buffer, size_t count, loff_ if(dma == NULL || (dma->s) == NULL) return -ENXIO; - if (ppos != &file->f_pos) - return -ESPIPE; - if (dma->mmapped || !dma->opened) return -ENXIO; @@ -1689,14 +1685,14 @@ static int rm96xx_mmap(struct file *file, struct vm_area_struct *vma) { if (vma->vm_flags & VM_WRITE) { if (!s->started) rme96xx_startcard(s,1); - if (remap_page_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->outoffset*RME96xx_DMA_MAX_SIZE), size, vma->vm_page_prot)) { + if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->outoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) { unlock_kernel(); return -EAGAIN; } } else if (vma->vm_flags & VM_READ) { if (!s->started) rme96xx_startcard(s,1); - if (remap_page_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->inoffset*RME96xx_DMA_MAX_SIZE), size, vma->vm_page_prot)) { + if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->inoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) { unlock_kernel(); return -EAGAIN; } @@ -1754,9 +1750,7 @@ static unsigned int rme96xx_poll(struct file *file, struct poll_table_struct *wa static struct file_operations rme96xx_audio_fops = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) .owner = THIS_MODULE, -#endif .read = rme96xx_read, .write = rme96xx_write, .poll = rme96xx_poll, @@ -1774,6 +1768,7 @@ static int rme96xx_mixer_open(struct inode *inode, struct file *file) COMM ("mixer open"); + nonseekable_open(inode, file); for (list = devs.next; ; list = list->next) { if (list == &devs) return -ENODEV; @@ -1793,6 +1788,8 @@ static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned rme96xx_info *s = (rme96xx_info *)file->private_data; u32 status; int spdifrate; + void __user *argp = (void __user *)arg; + int __user *p = argp; status = readl(s->iobase + RME96xx_status_register); /* hack to convert rev 1.5 SPDIF rate to "crystalrate" format HP 20020201 */ @@ -1802,7 +1799,7 @@ static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned VALIDATE_STATE(s); if (cmd == SOUND_MIXER_PRIVATE1) { rme_mixer mixer; - if (copy_from_user(&mixer,(void*)arg,sizeof(mixer))) + if (copy_from_user(&mixer,argp,sizeof(mixer))) return -EFAULT; mixer.devnr &= RME96xx_MASK_DEVS; @@ -1825,14 +1822,14 @@ static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned mixer.o_offset = s->dma[mixer.devnr].outoffset; mixer.i_offset = s->dma[mixer.devnr].inoffset; - return copy_to_user((void *)arg, &mixer, sizeof(mixer)) ? -EFAULT : 0; + return copy_to_user(argp, &mixer, sizeof(mixer)) ? -EFAULT : 0; } if (cmd == SOUND_MIXER_PRIVATE2) { - return put_user(status, (int *)arg); + return put_user(status, p); } if (cmd == SOUND_MIXER_PRIVATE3) { u32 control; - if (copy_from_user(&control,(void*)arg,sizeof(control))) + if (copy_from_user(&control,argp,sizeof(control))) return -EFAULT; if (file->f_mode & FMODE_WRITE) { s->control_register &= ~RME96xx_mixer_allowed; @@ -1840,7 +1837,7 @@ static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned writel(control,s->iobase + RME96xx_control_register); } - return put_user(s->control_register, (int *)arg); + return put_user(s->control_register, p); } return -1; } @@ -1853,9 +1850,7 @@ static int rme96xx_mixer_release(struct inode *inode, struct file *file) } static /*const*/ struct file_operations rme96xx_mixer_fops = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) .owner = THIS_MODULE, -#endif .ioctl = rme96xx_mixer_ioctl, .open = rme96xx_mixer_open, .release = rme96xx_mixer_release,