linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / sound / oss / sonicvibes.c
index 8ea532d..71b05e2 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/smp_lock.h>
 #include <linux/gameport.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -331,7 +328,7 @@ struct sv_state {
        unsigned char fmt, enable;
 
        spinlock_t lock;
-       struct mutex open_mutex;
+       struct semaphore open_sem;
        mode_t open_mode;
        wait_queue_head_t open_wait;
 
@@ -408,6 +405,24 @@ static inline unsigned ld2(unsigned int x)
        return r;
 }
 
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#ifdef hweight32
+#undef hweight32
+#endif
+
+static inline unsigned int hweight32(unsigned int w)
+{
+        unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
+        res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+        res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+        res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+        return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+
 /* --------------------------------------------------------------------- */
 
 /*
@@ -1907,21 +1922,21 @@ static int sv_open(struct inode *inode, struct file *file)
                VALIDATE_STATE(s);
        file->private_data = s;
        /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
+       down(&s->open_sem);
        while (s->open_mode & file->f_mode) {
                if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
+                       up(&s->open_sem);
                        return -EBUSY;
                }
                add_wait_queue(&s->open_wait, &wait);
                __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
+               up(&s->open_sem);
                schedule();
                remove_wait_queue(&s->open_wait, &wait);
                set_current_state(TASK_RUNNING);
                if (signal_pending(current))
                        return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
+               down(&s->open_sem);
        }
        if (file->f_mode & FMODE_READ) {
                fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT);
@@ -1941,7 +1956,7 @@ static int sv_open(struct inode *inode, struct file *file)
        }
        set_fmt(s, fmtm, fmts);
        s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
+       up(&s->open_sem);
        return nonseekable_open(inode, file);
 }
 
@@ -1953,7 +1968,7 @@ static int sv_release(struct inode *inode, struct file *file)
        lock_kernel();
        if (file->f_mode & FMODE_WRITE)
                drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
+       down(&s->open_sem);
        if (file->f_mode & FMODE_WRITE) {
                stop_dac(s);
                dealloc_dmabuf(s, &s->dma_dac);
@@ -1964,7 +1979,7 @@ static int sv_release(struct inode *inode, struct file *file)
        }
        s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
        wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
+       up(&s->open_sem);
        unlock_kernel();
        return 0;
 }
@@ -2152,21 +2167,21 @@ static int sv_midi_open(struct inode *inode, struct file *file)
                VALIDATE_STATE(s);
        file->private_data = s;
        /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
+       down(&s->open_sem);
        while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
                if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
+                       up(&s->open_sem);
                        return -EBUSY;
                }
                add_wait_queue(&s->open_wait, &wait);
                __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
+               up(&s->open_sem);
                schedule();
                remove_wait_queue(&s->open_wait, &wait);
                set_current_state(TASK_RUNNING);
                if (signal_pending(current))
                        return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
+               down(&s->open_sem);
        }
        spin_lock_irqsave(&s->lock, flags);
        if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -2195,7 +2210,7 @@ static int sv_midi_open(struct inode *inode, struct file *file)
        }
        spin_unlock_irqrestore(&s->lock, flags);
        s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_mutex);
+       up(&s->open_sem);
        return nonseekable_open(inode, file);
 }
 
@@ -2233,7 +2248,7 @@ static int sv_midi_release(struct inode *inode, struct file *file)
                remove_wait_queue(&s->midi.owait, &wait);
                set_current_state(TASK_RUNNING);
        }
-       mutex_lock(&s->open_mutex);
+       down(&s->open_sem);
        s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
        spin_lock_irqsave(&s->lock, flags);
        if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -2242,7 +2257,7 @@ static int sv_midi_release(struct inode *inode, struct file *file)
        }
        spin_unlock_irqrestore(&s->lock, flags);
        wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
+       up(&s->open_sem);
        unlock_kernel();
        return 0;
 }
@@ -2373,21 +2388,21 @@ static int sv_dmfm_open(struct inode *inode, struct file *file)
                VALIDATE_STATE(s);
        file->private_data = s;
        /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
+       down(&s->open_sem);
        while (s->open_mode & FMODE_DMFM) {
                if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
+                       up(&s->open_sem);
                        return -EBUSY;
                }
                add_wait_queue(&s->open_wait, &wait);
                __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
+               up(&s->open_sem);
                schedule();
                remove_wait_queue(&s->open_wait, &wait);
                set_current_state(TASK_RUNNING);
                if (signal_pending(current))
                        return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
+               down(&s->open_sem);
        }
        /* init the stuff */
        outb(1, s->iosynth);
@@ -2397,7 +2412,7 @@ static int sv_dmfm_open(struct inode *inode, struct file *file)
        outb(5, s->iosynth+2);
        outb(1, s->iosynth+3);  /* enable OPL3 */
        s->open_mode |= FMODE_DMFM;
-       mutex_unlock(&s->open_mutex);
+       up(&s->open_sem);
        return nonseekable_open(inode, file);
 }
 
@@ -2408,7 +2423,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
 
        VALIDATE_STATE(s);
        lock_kernel();
-       mutex_lock(&s->open_mutex);
+       down(&s->open_sem);
        s->open_mode &= ~FMODE_DMFM;
        for (regb = 0xb0; regb < 0xb9; regb++) {
                outb(regb, s->iosynth);
@@ -2417,7 +2432,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
                outb(0, s->iosynth+3);
        }
        wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
+       up(&s->open_sem);
        unlock_kernel();
        return 0;
 }
@@ -2536,7 +2551,7 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id
                return -ENODEV;
        if (pcidev->irq == 0)
                return -ENODEV;
-       if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK)) {
+       if (pci_set_dma_mask(pcidev, 0x00ffffff)) {
                printk(KERN_WARNING "sonicvibes: architecture does not support 24bit PCI busmaster DMA\n");
                return -ENODEV;
        }
@@ -2567,7 +2582,7 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id
        init_waitqueue_head(&s->open_wait);
        init_waitqueue_head(&s->midi.iwait);
        init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_mutex);
+       init_MUTEX(&s->open_sem);
        spin_lock_init(&s->lock);
        s->magic = SV_MAGIC;
        s->dev = pcidev;
@@ -2632,7 +2647,7 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id
        wrindir(s, SV_CIPCMSR1, ((8000 * 65536 / FULLRATE) >> 8) & 0xff);
        wrindir(s, SV_CIADCOUTPUT, 0);
        /* request irq */
-       if ((ret=request_irq(s->irq,sv_interrupt,IRQF_SHARED,"S3 SonicVibes",s))) {
+       if ((ret=request_irq(s->irq,sv_interrupt,SA_SHIRQ,"S3 SonicVibes",s))) {
                printk(KERN_ERR "sv: irq %u in use\n", s->irq);
                goto err_irq;
        }