fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / sound / oss / via82cxxx_audio.c
index dc1c256..c96cc8c 100644 (file)
 #define VIA_VERSION    "1.9.1-ac4-2.5"
 
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
+#include <linux/poison.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
 #include "sound_config.h"
 #include "dev_table.h"
 #include "mpu401.h"
         }
 #endif
 
-#if defined(CONFIG_PROC_FS) && \
-    defined(CONFIG_SOUND_VIA82CXXX_PROCFS)
-#define VIA_PROC_FS 1
-#endif
-
 #define VIA_SUPPORT_MMAP 1 /* buggy, for now... */
 
 #define MAX_CARDS      1
@@ -311,12 +308,12 @@ struct via_info {
        unsigned sixchannel: 1; /* 8233/35 with 6 channel support */
        unsigned volume: 1;
 
-       int locked_rate : 1;
+       unsigned locked_rate : 1;
        
        int mixer_vol;          /* 8233/35 volume  - not yet implemented */
 
-       struct semaphore syscall_sem;
-       struct semaphore open_sem;
+       struct mutex syscall_mutex;
+       struct mutex open_mutex;
 
        /* The 8233/8235 have 4 DX audio channels, two record and
           one six channel out. We bind ch_in to DX 1, ch_out to multichannel
@@ -366,18 +363,6 @@ static void via_chan_clear (struct via_info *card, struct via_channel *chan);
 static void via_chan_pcm_fmt (struct via_channel *chan, int reset);
 static void via_chan_buffer_free (struct via_info *card, struct via_channel *chan);
 
-#ifdef VIA_PROC_FS
-static int via_init_proc (void);
-static void via_cleanup_proc (void);
-static int via_card_init_proc (struct via_info *card);
-static void via_card_cleanup_proc (struct via_info *card);
-#else
-static inline int via_init_proc (void) { return 0; }
-static inline void via_cleanup_proc (void) {}
-static inline int via_card_init_proc (struct via_info *card) { return 0; }
-static inline void via_card_cleanup_proc (struct via_info *card) {}
-#endif
-
 
 /****************************************************************
  *
@@ -521,10 +506,10 @@ static inline int via_syscall_down (struct via_info *card, int nonblock)
        nonblock = 0;
 
        if (nonblock) {
-               if (down_trylock (&card->syscall_sem))
+               if (!mutex_trylock(&card->syscall_mutex))
                        return -EAGAIN;
        } else {
-               if (down_interruptible (&card->syscall_sem))
+               if (mutex_lock_interruptible(&card->syscall_mutex))
                        return -ERESTARTSYS;
        }
 
@@ -1562,7 +1547,7 @@ static int via_mixer_open (struct inode *inode, struct file *file)
 
        DPRINTK ("ENTER\n");
 
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+       while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
                drvr = pci_dev_driver (pdev);
                if (drvr == &via_driver) {
                        assert (pci_get_drvdata (pdev) != NULL);
@@ -1577,6 +1562,7 @@ static int via_mixer_open (struct inode *inode, struct file *file)
        return -ENODEV;
 
 match:
+       pci_dev_put(pdev);
        file->private_data = card->ac97;
 
        DPRINTK ("EXIT, returning 0\n");
@@ -1625,7 +1611,7 @@ static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int
 #endif
        rc = codec->mixer_ioctl(codec, cmd, arg);
 
-       up (&card->syscall_sem);
+       mutex_unlock(&card->syscall_mutex);
 
 out:
        DPRINTK ("EXIT, returning %d\n", rc);
@@ -1926,7 +1912,7 @@ static void via_intr_channel (struct via_info *card, struct via_channel *chan)
 }
 
 
-static irqreturn_t  via_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t  via_interrupt(int irq, void *dev_id)
 {
        struct via_info *card = dev_id;
        u32 status32;
@@ -1941,7 +1927,7 @@ static irqreturn_t  via_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         {
 #ifdef CONFIG_MIDI_VIA82CXXX
                 if (card->midi_devc)
-                       uart401intr(irq, card->midi_devc, regs);
+                       uart401intr(irq, card->midi_devc);
 #endif
                return IRQ_HANDLED;
        }
@@ -1964,7 +1950,7 @@ static irqreturn_t  via_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t via_new_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t via_new_interrupt(int irq, void *dev_id)
 {
        struct via_info *card = dev_id;
        u32 status32;
@@ -2028,7 +2014,7 @@ static int via_interrupt_init (struct via_info *card)
                        tmp8 |= VIA_CR48_FM_TRAP_TO_NMI;
                        pci_write_config_byte (card->pdev, VIA_FM_NMI_CTRL, tmp8);
                }
-               if (request_irq (card->pdev->irq, via_interrupt, SA_SHIRQ, VIA_MODULE_NAME, card)) {
+               if (request_irq (card->pdev->irq, via_interrupt, IRQF_SHARED, VIA_MODULE_NAME, card)) {
                        printk (KERN_ERR PFX "unable to obtain IRQ %d, aborting\n",
                                card->pdev->irq);
                        DPRINTK ("EXIT, returning -EBUSY\n");
@@ -2037,7 +2023,7 @@ static int via_interrupt_init (struct via_info *card)
        }
        else 
        {
-               if (request_irq (card->pdev->irq, via_new_interrupt, SA_SHIRQ, VIA_MODULE_NAME, card)) {
+               if (request_irq (card->pdev->irq, via_new_interrupt, IRQF_SHARED, VIA_MODULE_NAME, card)) {
                        printk (KERN_ERR PFX "unable to obtain IRQ %d, aborting\n",
                                card->pdev->irq);
                        DPRINTK ("EXIT, returning -EBUSY\n");
@@ -2134,8 +2120,8 @@ static struct page * via_mm_nopage (struct vm_area_struct * vma,
                return NOPAGE_SIGBUS; /* Disallow mremap */
        }
         if (!card) {
-               DPRINTK ("EXIT, returning NOPAGE_OOM\n");
-               return NOPAGE_OOM;      /* Nothing allocated */
+               DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n");
+               return NOPAGE_SIGBUS;   /* Nothing allocated */
        }
 
        pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT);
@@ -2179,7 +2165,7 @@ static int via_mm_swapout (struct page *page, struct file *filp)
 #endif /* VM_RESERVED */
 
 
-struct vm_operations_struct via_mm_ops = {
+static struct vm_operations_struct via_mm_ops = {
        .nopage         = via_mm_nopage,
 
 #ifndef VM_RESERVED
@@ -2244,7 +2230,7 @@ static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma)
        if (wr)
                card->ch_out.is_mapped = 1;
 
-       up (&card->syscall_sem);
+       mutex_unlock(&card->syscall_mutex);
        rc = 0;
 
 out:
@@ -2272,7 +2258,7 @@ handle_one_block:
        /* Thomas Sailer:
         * But also to ourselves, release semaphore if we do so */
        if (need_resched()) {
-               up(&card->syscall_sem);
+               mutex_unlock(&card->syscall_mutex);
                schedule ();
                ret = via_syscall_down (card, nonblock);
                if (ret)
@@ -2302,7 +2288,7 @@ handle_one_block:
                        break;
                }
 
-               up(&card->syscall_sem);
+               mutex_unlock(&card->syscall_mutex);
 
                DPRINTK ("Sleeping on block %d\n", n);
                schedule();
@@ -2418,7 +2404,7 @@ static ssize_t via_dsp_read(struct file *file, char __user *buffer, size_t count
        rc = via_dsp_do_read (card, buffer, count, nonblock);
 
 out_up:
-       up (&card->syscall_sem);
+       mutex_unlock(&card->syscall_mutex);
 out:
        DPRINTK ("EXIT, returning %ld\n",(long) rc);
        return rc;
@@ -2442,7 +2428,7 @@ handle_one_block:
        /* Thomas Sailer:
         * But also to ourselves, release semaphore if we do so */
        if (need_resched()) {
-               up(&card->syscall_sem);
+               mutex_unlock(&card->syscall_mutex);
                schedule ();
                ret = via_syscall_down (card, nonblock);
                if (ret)
@@ -2472,7 +2458,7 @@ handle_one_block:
                        break;
                }
 
-               up(&card->syscall_sem);
+               mutex_unlock(&card->syscall_mutex);
 
                DPRINTK ("Sleeping on page %d, tmp==%d, ir==%d\n", n, tmp, chan->is_record);
                schedule();
@@ -2601,7 +2587,7 @@ static ssize_t via_dsp_write(struct file *file, const char __user *buffer, size_
        rc = via_dsp_do_write (card, buffer, count, nonblock);
 
 out_up:
-       up (&card->syscall_sem);
+       mutex_unlock(&card->syscall_mutex);
 out:
        DPRINTK ("EXIT, returning %ld\n",(long) rc);
        return rc;
@@ -2650,7 +2636,7 @@ static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wa
  *     Sleeps until all playback has been flushed to the audio
  *     hardware.
  *
- *     Locking: inside card->syscall_sem
+ *     Locking: inside card->syscall_mutex
  */
 
 static int via_dsp_drain_playback (struct via_info *card,
@@ -2708,7 +2694,7 @@ static int via_dsp_drain_playback (struct via_info *card,
                        printk (KERN_ERR "sleeping but not active\n");
 #endif
 
-               up(&card->syscall_sem);
+               mutex_unlock(&card->syscall_mutex);
 
                DPRINTK ("sleeping, nbufs=%d\n", atomic_read (&chan->n_frags));
                schedule();
@@ -2764,7 +2750,7 @@ out:
  *
  *     Handles SNDCTL_DSP_GETISPACE and SNDCTL_DSP_GETOSPACE.
  *
- *     Locking: inside card->syscall_sem
+ *     Locking: inside card->syscall_mutex
  */
 
 static int via_dsp_ioctl_space (struct via_info *card,
@@ -2809,7 +2795,7 @@ static int via_dsp_ioctl_space (struct via_info *card,
  *
  *     Handles SNDCTL_DSP_GETIPTR and SNDCTL_DSP_GETOPTR.
  *
- *     Locking: inside card->syscall_sem
+ *     Locking: inside card->syscall_mutex
  */
 
 static int via_dsp_ioctl_ptr (struct via_info *card,
@@ -3237,7 +3223,7 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
                break;
        }
 
-       up (&card->syscall_sem);
+       mutex_unlock(&card->syscall_mutex);
        DPRINTK ("EXIT, returning %d\n", rc);
        return rc;
 }
@@ -3260,7 +3246,7 @@ static int via_dsp_open (struct inode *inode, struct file *file)
        }
 
        card = NULL;
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+       while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
                drvr = pci_dev_driver (pdev);
                if (drvr == &via_driver) {
                        assert (pci_get_drvdata (pdev) != NULL);
@@ -3279,13 +3265,14 @@ static int via_dsp_open (struct inode *inode, struct file *file)
        return -ENODEV;
 
 match:
+       pci_dev_put(pdev);
        if (nonblock) {
-               if (down_trylock (&card->open_sem)) {
+               if (!mutex_trylock(&card->open_mutex)) {
                        DPRINTK ("EXIT, returning -EAGAIN\n");
                        return -EAGAIN;
                }
        } else {
-               if (down_interruptible (&card->open_sem)) {
+               if (mutex_lock_interruptible(&card->open_mutex)) {
                        DPRINTK ("EXIT, returning -ERESTARTSYS\n");
                        return -ERESTARTSYS;
                }
@@ -3371,8 +3358,8 @@ static int via_dsp_release(struct inode *inode, struct file *file)
                via_chan_buffer_free (card, &card->ch_in);
        }
 
-       up (&card->syscall_sem);
-       up (&card->open_sem);
+       mutex_unlock(&card->syscall_mutex);
+       mutex_unlock(&card->open_mutex);
 
        DPRINTK ("EXIT, returning 0\n");
        return 0;
@@ -3408,10 +3395,10 @@ static int __devinit via_init_one (struct pci_dev *pdev, const struct pci_device
        if (rc)
                goto err_out_disable;
 
-       rc = pci_set_dma_mask(pdev, 0xffffffffULL);
+       rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc)
                goto err_out_res;
-       rc = pci_set_consistent_dma_mask(pdev, 0xffffffffULL);
+       rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc)
                goto err_out_res;
 
@@ -3430,8 +3417,8 @@ static int __devinit via_init_one (struct pci_dev *pdev, const struct pci_device
        card->card_num = via_num_cards++;
        spin_lock_init (&card->lock);
        spin_lock_init (&card->ac97_lock);
-       init_MUTEX (&card->syscall_sem);
-       init_MUTEX (&card->open_sem);
+       mutex_init(&card->syscall_mutex);
+       mutex_init(&card->open_mutex);
 
        /* we must init these now, in case the intr handler needs them */
        via_chan_init_defaults (card, &card->ch_out);
@@ -3483,22 +3470,13 @@ static int __devinit via_init_one (struct pci_dev *pdev, const struct pci_device
                goto err_out_have_mixer;
        }
 
-       /*
-        * per-card /proc info
-        */
-       rc = via_card_init_proc (card);
-       if (rc) {
-               printk (KERN_ERR PFX "card-specific /proc init failed, aborting\n");
-               goto err_out_have_dsp;
-       }
-
        /*
         * init and turn on interrupts, as the last thing we do
         */
        rc = via_interrupt_init (card);
        if (rc) {
                printk (KERN_ERR PFX "interrupt init failed, aborting\n");
-               goto err_out_have_proc;
+               goto err_out_have_dsp;
        }
 
        printk (KERN_INFO PFX "board #%d at 0x%04lX, IRQ %d\n",
@@ -3538,9 +3516,6 @@ static int __devinit via_init_one (struct pci_dev *pdev, const struct pci_device
        DPRINTK ("EXIT, returning 0\n");
        return 0;
 
-err_out_have_proc:
-       via_card_cleanup_proc (card);
-
 err_out_have_dsp:
        via_dsp_cleanup (card);
 
@@ -3549,7 +3524,7 @@ err_out_have_mixer:
 
 err_out_kfree:
 #ifndef VIA_NDEBUG
-       memset (card, 0xAB, sizeof (*card)); /* poison memory */
+       memset (card, OSS_POISON_FREE, sizeof (*card)); /* poison memory */
 #endif
        kfree (card);
 
@@ -3582,12 +3557,11 @@ static void __devexit via_remove_one (struct pci_dev *pdev)
 #endif
 
        free_irq (card->pdev->irq, card);
-       via_card_cleanup_proc (card);
        via_dsp_cleanup (card);
        via_ac97_cleanup (card);
 
 #ifndef VIA_NDEBUG
-       memset (card, 0xAB, sizeof (*card)); /* poison memory */
+       memset (card, OSS_POISON_FREE, sizeof (*card)); /* poison memory */
 #endif
        kfree (card);
 
@@ -3615,21 +3589,12 @@ static int __init init_via82cxxx_audio(void)
 
        DPRINTK ("ENTER\n");
 
-       rc = via_init_proc ();
+       rc = pci_register_driver (&via_driver);
        if (rc) {
                DPRINTK ("EXIT, returning %d\n", rc);
                return rc;
        }
 
-       rc = pci_register_driver (&via_driver);
-       if (rc < 1) {
-               if (rc == 0)
-                       pci_unregister_driver (&via_driver);
-               via_cleanup_proc ();
-               DPRINTK ("EXIT, returning -ENODEV\n");
-               return -ENODEV;
-       }
-
        DPRINTK ("EXIT, returning 0\n");
        return 0;
 }
@@ -3640,7 +3605,6 @@ static void __exit cleanup_via82cxxx_audio(void)
        DPRINTK ("ENTER\n");
 
        pci_unregister_driver (&via_driver);
-       via_cleanup_proc ();
 
        DPRINTK ("EXIT\n");
 }
@@ -3653,181 +3617,3 @@ MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("DSP audio and mixer driver for Via 82Cxxx audio devices");
 MODULE_LICENSE("GPL");
 
-
-#ifdef VIA_PROC_FS
-
-/****************************************************************
- *
- * /proc/driver/via/info
- *
- *
- */
-
-static int via_info_read_proc (char *page, char **start, off_t off,
-                              int count, int *eof, void *data)
-{
-#define YN(val,bit) (((val) & (bit)) ? "yes" : "no")
-#define ED(val,bit) (((val) & (bit)) ? "enable" : "disable")
-
-       int len = 0;
-       u8 r40, r41, r42, r44;
-       struct via_info *card = data;
-
-       DPRINTK ("ENTER\n");
-
-       assert (card != NULL);
-
-       len += sprintf (page+len, VIA_CARD_NAME "\n\n");
-
-       pci_read_config_byte (card->pdev, 0x40, &r40);
-       pci_read_config_byte (card->pdev, 0x41, &r41);
-       pci_read_config_byte (card->pdev, 0x42, &r42);
-       pci_read_config_byte (card->pdev, 0x44, &r44);
-
-       len += sprintf (page+len,
-               "Via 82Cxxx PCI registers:\n"
-               "\n"
-               "40  Codec Ready: %s\n"
-               "    Codec Low-power: %s\n"
-               "    Secondary Codec Ready: %s\n"
-               "\n"
-               "41  Interface Enable: %s\n"
-               "    De-Assert Reset: %s\n"
-               "    Force SYNC high: %s\n"
-               "    Force SDO high: %s\n"
-               "    Variable Sample Rate On-Demand Mode: %s\n"
-               "    SGD Read Channel PCM Data Out: %s\n"
-               "    FM Channel PCM Data Out: %s\n"
-               "    SB PCM Data Out: %s\n"
-               "\n"
-               "42  Game port enabled: %s\n"
-               "    SoundBlaster enabled: %s\n"
-               "    FM enabled: %s\n"
-               "    MIDI enabled: %s\n"
-               "\n"
-               "44  AC-Link Interface Access: %s\n"
-               "    Secondary Codec Support: %s\n"
-
-               "\n",
-
-               YN (r40, VIA_CR40_AC97_READY),
-               YN (r40, VIA_CR40_AC97_LOW_POWER),
-               YN (r40, VIA_CR40_SECONDARY_READY),
-
-               ED (r41, VIA_CR41_AC97_ENABLE),
-               YN (r41, (1 << 6)),
-               YN (r41, (1 << 5)),
-               YN (r41, (1 << 4)),
-               ED (r41, (1 << 3)),
-               ED (r41, (1 << 2)),
-               ED (r41, (1 << 1)),
-               ED (r41, (1 << 0)),
-
-               YN (r42, VIA_CR42_GAME_ENABLE),
-               YN (r42, VIA_CR42_SB_ENABLE),
-               YN (r42, VIA_CR42_FM_ENABLE),
-               YN (r42, VIA_CR42_MIDI_ENABLE),
-
-               YN (r44, VIA_CR44_AC_LINK_ACCESS),
-               YN (r44, VIA_CR44_SECOND_CODEC_SUPPORT)
-
-               );
-
-       DPRINTK ("EXIT, returning %d\n", len);
-       return len;
-
-#undef YN
-#undef ED
-}
-
-
-/****************************************************************
- *
- * /proc/driver/via/... setup and cleanup
- *
- *
- */
-
-static int __init via_init_proc (void)
-{
-       DPRINTK ("ENTER\n");
-
-       if (!proc_mkdir ("driver/via", 0))
-               return -EIO;
-
-       DPRINTK ("EXIT, returning 0\n");
-       return 0;
-}
-
-
-static void via_cleanup_proc (void)
-{
-       DPRINTK ("ENTER\n");
-
-       remove_proc_entry ("driver/via", NULL);
-
-       DPRINTK ("EXIT\n");
-}
-
-
-static int __devinit via_card_init_proc (struct via_info *card)
-{
-       char s[32];
-       int rc;
-
-       DPRINTK ("ENTER\n");
-
-       sprintf (s, "driver/via/%d", card->card_num);
-       if (!proc_mkdir (s, 0)) {
-               rc = -EIO;
-               goto err_out_none;
-       }
-
-       sprintf (s, "driver/via/%d/info", card->card_num);
-       if (!create_proc_read_entry (s, 0, 0, via_info_read_proc, card)) {
-               rc = -EIO;
-               goto err_out_dir;
-       }
-
-       sprintf (s, "driver/via/%d/ac97", card->card_num);
-       if (!create_proc_read_entry (s, 0, 0, ac97_read_proc, card->ac97)) {
-               rc = -EIO;
-               goto err_out_info;
-       }
-
-       DPRINTK ("EXIT, returning 0\n");
-       return 0;
-
-err_out_info:
-       sprintf (s, "driver/via/%d/info", card->card_num);
-       remove_proc_entry (s, NULL);
-
-err_out_dir:
-       sprintf (s, "driver/via/%d", card->card_num);
-       remove_proc_entry (s, NULL);
-
-err_out_none:
-       DPRINTK ("EXIT, returning %d\n", rc);
-       return rc;
-}
-
-
-static void via_card_cleanup_proc (struct via_info *card)
-{
-       char s[32];
-
-       DPRINTK ("ENTER\n");
-
-       sprintf (s, "driver/via/%d/ac97", card->card_num);
-       remove_proc_entry (s, NULL);
-
-       sprintf (s, "driver/via/%d/info", card->card_num);
-       remove_proc_entry (s, NULL);
-
-       sprintf (s, "driver/via/%d", card->card_num);
-       remove_proc_entry (s, NULL);
-
-       DPRINTK ("EXIT\n");
-}
-
-#endif /* VIA_PROC_FS */