#define RMEVERSION "0.8"
#endif
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <asm/hardirq.h>
+#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#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");
/* 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 */
/* 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;
}
-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);
}
-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;
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;
/* 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) {
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);
}
-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;
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;
}
-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++) {
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++) {
}
/* 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;
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++) {
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;
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);
return NULL;
}
-void busmaster_free(void* ptr,int size) {
+static void busmaster_free(void* ptr,int size) {
int pg;
struct page* page, *last_page;
}
-int rme96xx_init(rme96xx_info* s)
+static int rme96xx_init(rme96xx_info* s)
{
int i;
int status;
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)
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;
count_info cinfo;
int count;
int val = 0;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
VALIDATE_STATE(s);
switch (cmd) {
case OSS_GETVERSION:
- return put_user(SOUND_VERSION, (int *)arg);
+ return put_user(SOUND_VERSION, p);
case SNDCTL_DSP_SYNC:
#if 0
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
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) {
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) {
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)
break;
}
}
- return put_user(dma->format, (int *)arg);
+ return put_user(dma->format, p);
case SNDCTL_DSP_POST:
return 0;
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) {
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))
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;
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 !!!) */
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;
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;
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;
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) {
val = 16;
break;
}
- return put_user(val, (int *)arg);
+ return put_user(val, p);
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_SETSYNCRO:
DBG(printk("device num %d open\n",devnum));
+ nonseekable_open(in, f);
for (list = devs.next; ; list = list->next) {
if (list == &devs)
return -ENODEV;
}
-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;
if(dma == NULL || (dma->s) == NULL)
return -ENXIO;
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
if (dma->mmapped || !dma->opened)
return -ENXIO;
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;
if(dma == NULL || (dma->s) == NULL)
return -ENXIO;
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
if (dma->mmapped || !dma->opened)
return -ENXIO;
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;
}
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,
COMM ("mixer open");
+ nonseekable_open(inode, file);
for (list = devs.next; ; list = list->next) {
if (list == &devs)
return -ENODEV;
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 */
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;
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;
writel(control,s->iobase + RME96xx_control_register);
}
- return put_user(s->control_register, (int *)arg);
+ return put_user(s->control_register, p);
}
return -1;
}
}
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,