Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / sound / oss / via82cxxx_audio.c
index 2c83d03..1a921ee 100644 (file)
@@ -10,7 +10,7 @@
  * NO WARRANTY
  *
  * For a list of known bugs (errata) and documentation,
- * see via-audio.pdf in linux/Documentation/DocBook.
+ * see via-audio.pdf in Documentation/DocBook.
  * If this documentation does not exist, run "make pdfdocs".
  */
 
 #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
@@ -315,8 +312,8 @@ struct via_info {
        
        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;
        }
 
@@ -1580,7 +1565,7 @@ match:
        file->private_data = card->ac97;
 
        DPRINTK ("EXIT, returning 0\n");
-       return 0;
+       return nonseekable_open(inode, file);
 }
 
 static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
@@ -1625,7 +1610,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);
@@ -2179,7 +2164,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 +2229,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 +2257,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 +2287,7 @@ handle_one_block:
                        break;
                }
 
-               up(&card->syscall_sem);
+               mutex_unlock(&card->syscall_mutex);
 
                DPRINTK ("Sleeping on block %d\n", n);
                schedule();
@@ -2401,11 +2386,6 @@ static ssize_t via_dsp_read(struct file *file, char __user *buffer, size_t count
        card = file->private_data;
        assert (card != NULL);
 
-       if (ppos != &file->f_pos) {
-               DPRINTK ("EXIT, returning -ESPIPE\n");
-               return -ESPIPE;
-       }
-
        rc = via_syscall_down (card, nonblock);
        if (rc) goto out;
 
@@ -2423,7 +2403,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;
@@ -2447,7 +2427,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)
@@ -2477,7 +2457,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();
@@ -2589,11 +2569,6 @@ static ssize_t via_dsp_write(struct file *file, const char __user *buffer, size_
        card = file->private_data;
        assert (card != NULL);
 
-       if (ppos != &file->f_pos) {
-               DPRINTK ("EXIT, returning -ESPIPE\n");
-               return -ESPIPE;
-       }
-
        rc = via_syscall_down (card, nonblock);
        if (rc) goto out;
 
@@ -2611,7 +2586,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;
@@ -2660,7 +2635,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,
@@ -2718,7 +2693,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();
@@ -2774,7 +2749,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,
@@ -2819,7 +2794,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,
@@ -3247,7 +3222,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;
 }
@@ -3290,12 +3265,12 @@ static int via_dsp_open (struct inode *inode, struct file *file)
 
 match:
        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;
                }
@@ -3345,7 +3320,7 @@ match:
        }
 
        DPRINTK ("EXIT, returning 0\n");
-       return 0;
+       return nonseekable_open(inode, file);
 }
 
 
@@ -3381,8 +3356,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;
@@ -3418,10 +3393,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;
 
@@ -3440,8 +3415,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);
@@ -3493,22 +3468,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",
@@ -3548,9 +3514,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);
 
@@ -3592,7 +3555,6 @@ 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);
 
@@ -3625,21 +3587,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;
 }
@@ -3650,7 +3603,6 @@ static void __exit cleanup_via82cxxx_audio(void)
        DPRINTK ("ENTER\n");
 
        pci_unregister_driver (&via_driver);
-       via_cleanup_proc ();
 
        DPRINTK ("EXIT\n");
 }
@@ -3663,181 +3615,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 */