Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / sound / oss / maestro.c
index 4a670f4..e647f2f 100644 (file)
 #include <linux/reboot.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/mutex.h>
+
 
 #include <asm/current.h>
 #include <asm/dma.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
-#include <linux/pm.h>
-static int maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *d);
-
 #include "maestro.h"
 
 static struct pci_driver maestro_pci_driver;
@@ -262,11 +261,11 @@ MODULE_DESCRIPTION("ESS Maestro Driver");
 MODULE_LICENSE("GPL");
 
 #ifdef M_DEBUG
-MODULE_PARM(debug,"i");
+module_param(debug, bool, 0644);
 #endif
-MODULE_PARM(dsps_order,"i");
-MODULE_PARM(use_pm,"i");
-MODULE_PARM(clocking, "i");
+module_param(dsps_order, int, 0);
+module_param(use_pm, int, 0);
+module_param(clocking, int, 0);
 
 /* --------------------------------------------------------------------- */
 #define DRIVER_VERSION "0.15"
@@ -344,7 +343,7 @@ enum {
 
 /* these masks indicate which units we care about at
        which states */
-u16 acpi_state_mask[] = {
+static u16 acpi_state_mask[] = {
        [ACPI_D0] = ACPI_ALL,
        [ACPI_D1] = ACPI_SLEEP,
        [ACPI_D2] = ACPI_SLEEP,
@@ -400,7 +399,7 @@ struct ess_state {
        /* this locks around the oss state in the driver */
        spinlock_t lock;
        /* only let 1 be opening at a time */
-       struct semaphore open_sem;
+       struct mutex open_mutex;
        wait_queue_head_t open_wait;
        mode_t open_mode;
 
@@ -610,7 +609,7 @@ static u16 maestro_ac97_get(struct ess_card *card, u8 cmd)
        be sure to fill it in if you add oss mixers
        to anyone's supported mixer defines */
 
- unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = {
+static unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = {
        [SOUND_MIXER_VOLUME] =          0x3232,
        [SOUND_MIXER_BASS] =            0x3232,
        [SOUND_MIXER_TREBLE] =          0x3232,
@@ -2158,7 +2157,7 @@ static int ess_open_mixdev(struct inode *inode, struct file *file)
        if (!card)
                return -ENODEV;
        file->private_data = card;
-       return 0;
+       return nonseekable_open(inode, file);
 }
 
 static int ess_release_mixdev(struct inode *inode, struct file *file)
@@ -2274,8 +2273,6 @@ ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
        unsigned char *combbuf = NULL;
        
        VALIDATE_STATE(s);
-       if (ppos != &file->f_pos)
-               return -ESPIPE;
        if (s->dma_adc.mapped)
                return -ENXIO;
        if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
@@ -2358,7 +2355,7 @@ ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
        }
 
 rec_return_free:
-       if(combbuf) kfree(combbuf);
+       kfree(combbuf);
        return ret;
 }
 
@@ -2372,8 +2369,6 @@ ess_write(struct file *file, const char __user *buffer, size_t count, loff_t *pp
        int cnt;
        
        VALIDATE_STATE(s);
-       if (ppos != &file->f_pos)
-               return -ESPIPE;
        if (s->dma_dac.mapped)
                return -ENXIO;
        if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
@@ -2524,7 +2519,9 @@ static int ess_mmap(struct file *file, struct vm_area_struct *vma)
        if (size > (PAGE_SIZE << db->buforder))
                goto out;
        ret = -EAGAIN;
-       if (remap_page_range(vma, vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
+       if (remap_pfn_range(vma, vma->vm_start,
+                       virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
+                       size, vma->vm_page_prot))
                goto out;
        db->mapped = 1;
        ret = 0;
@@ -2957,7 +2954,7 @@ allocate_buffers(struct ess_state *s)
 
        }
 
-       /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
+       /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
        pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
        for (page = virt_to_page(rawbuf); page <= pend; page++)
                SetPageReserved(page);
@@ -3025,26 +3022,26 @@ ess_open(struct inode *inode, struct file *file)
                VALIDATE_STATE(s);
        file->private_data = s;
        /* wait for device to become free */
-       down(&s->open_sem);
+       mutex_lock(&s->open_mutex);
        while (s->open_mode & file->f_mode) {
                if (file->f_flags & O_NONBLOCK) {
-                       up(&s->open_sem);
+                       mutex_unlock(&s->open_mutex);
                        return -EWOULDBLOCK;
                }
-               up(&s->open_sem);
+               mutex_unlock(&s->open_mutex);
                interruptible_sleep_on(&s->open_wait);
                if (signal_pending(current))
                        return -ERESTARTSYS;
-               down(&s->open_sem);
+               mutex_lock(&s->open_mutex);
        }
 
        /* under semaphore.. */
        if ((s->card->dmapages==NULL) && allocate_buffers(s)) {
-               up(&s->open_sem);
+               mutex_unlock(&s->open_mutex);
                return -ENOMEM;
        }
 
-       /* we're covered by the open_sem */
+       /* we're covered by the open_mutex */
        if( ! s->card->dsps_open )  {
                maestro_power(s->card,ACPI_D0);
                start_bob(s);
@@ -3081,8 +3078,8 @@ ess_open(struct inode *inode, struct file *file)
        set_fmt(s, fmtm, fmts);
        s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
 
-       up(&s->open_sem);
-       return 0;
+       mutex_unlock(&s->open_mutex);
+       return nonseekable_open(inode, file);
 }
 
 static int 
@@ -3094,7 +3091,7 @@ ess_release(struct inode *inode, struct file *file)
        lock_kernel();
        if (file->f_mode & FMODE_WRITE)
                drain_dac(s, file->f_flags & O_NONBLOCK);
-       down(&s->open_sem);
+       mutex_lock(&s->open_mutex);
        if (file->f_mode & FMODE_WRITE) {
                stop_dac(s);
        }
@@ -3103,7 +3100,7 @@ ess_release(struct inode *inode, struct file *file)
        }
                
        s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-       /* we're covered by the open_sem */
+       /* we're covered by the open_mutex */
        M_printk("maestro: %d dsps now alive\n",s->card->dsps_open-1);
        if( --s->card->dsps_open <= 0) {
                s->card->dsps_open = 0;
@@ -3111,7 +3108,7 @@ ess_release(struct inode *inode, struct file *file)
                free_buffers(s);
                maestro_power(s->card,ACPI_D2);
        }
-       up(&s->open_sem);
+       mutex_unlock(&s->open_mutex);
        wake_up(&s->open_wait);
        unlock_kernel();
        return 0;
@@ -3365,7 +3362,7 @@ maestro_config(struct ess_card *card)
 /* this guy tries to find the pci power management
  * register bank.  this should really be in core
  * code somewhere.  1 on success. */
-int
+static int
 parse_power(struct ess_card *card, struct pci_dev *pcidev)
 {
        u32 n;
@@ -3405,7 +3402,6 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
        int i, ret;
        struct ess_card *card;
        struct ess_state *ess;
-       struct pm_dev *pmdev;
        int num = 0;
 
 /* when built into the kernel, we only print version if device is found */
@@ -3451,11 +3447,6 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
        memset(card, 0, sizeof(*card));
        card->pcidev = pcidev;
 
-       pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev),
-                       maestro_pm_callback);
-       if (pmdev)
-               pmdev->data = card;
-
        card->iobase = iobase;
        card->card_type = card_type;
        card->irq = pcidev->irq;
@@ -3477,7 +3468,7 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
                init_waitqueue_head(&s->dma_dac.wait);
                init_waitqueue_head(&s->open_wait);
                spin_lock_init(&s->lock);
-               init_MUTEX(&s->open_sem);
+               mutex_init(&s->open_mutex);
                s->magic = ESS_STATE_MAGIC;
                
                s->apu[0] = 6*i;
@@ -3631,11 +3622,11 @@ static struct pci_driver maestro_pci_driver = {
        .remove   = maestro_remove,
 };
 
-int __init init_maestro(void)
+static int __init init_maestro(void)
 {
        int rc;
 
-       rc = pci_module_init(&maestro_pci_driver);
+       rc = pci_register_driver(&maestro_pci_driver);
        if (rc < 0)
                return rc;
 
@@ -3668,10 +3659,9 @@ static int maestro_notifier(struct notifier_block *nb, unsigned long event, void
 /* --------------------------------------------------------------------- */
 
 
-void cleanup_maestro(void) {
+static void cleanup_maestro(void) {
        M_printk("maestro: unloading\n");
        pci_unregister_driver(&maestro_pci_driver);
-       pm_unregister_all(maestro_pm_callback);
        unregister_reboot_notifier(&maestro_nb);
 }
 
@@ -3692,143 +3682,5 @@ check_suspend(struct ess_card *card)
        current->state = TASK_RUNNING;
 }
 
-static int 
-maestro_suspend(struct ess_card *card)
-{
-       unsigned long flags;
-       int i,j;
-
-       spin_lock_irqsave(&card->lock,flags); /* over-kill */
-
-       M_printk("maestro: apm in dev %p\n",card);
-
-       /* we have to read from the apu regs, need
-               to power it up */
-       maestro_power(card,ACPI_D0);
-
-       for(i=0;i<NR_DSPS;i++) {
-               struct ess_state *s = &card->channels[i];
-
-               if(s->dev_audio == -1)
-                       continue;
-
-               M_printk("maestro: stopping apus for device %d\n",i);
-               stop_dac(s);
-               stop_adc(s);
-               for(j=0;j<6;j++) 
-                       card->apu_map[s->apu[j]][5]=apu_get_register(s,j,5);
-
-       }
-
-       /* get rid of interrupts? */
-       if( card->dsps_open > 0)
-               stop_bob(&card->channels[0]);
-
-       card->in_suspend++;
-
-       spin_unlock_irqrestore(&card->lock,flags);
-
-       /* we trust in the bios to power down the chip on suspend.
-        * XXX I'm also not sure that in_suspend will protect
-        * against all reg accesses from here on out. 
-        */
-       return 0;
-}
-static int 
-maestro_resume(struct ess_card *card)
-{
-       unsigned long flags;
-       int i;
-
-       spin_lock_irqsave(&card->lock,flags); /* over-kill */
-
-       card->in_suspend = 0;
-
-       M_printk("maestro: resuming card at %p\n",card);
-
-       /* restore all our config */
-       maestro_config(card);
-       /* need to restore the base pointers.. */ 
-       if(card->dmapages) 
-               set_base_registers(&card->channels[0],card->dmapages);
-
-       mixer_push_state(card);
-
-       /* set each channels' apu control registers before
-        * restoring audio 
-        */
-       for(i=0;i<NR_DSPS;i++) {
-               struct ess_state *s = &card->channels[i];
-               int chan,reg;
-
-               if(s->dev_audio == -1)
-                       continue;
-
-               for(chan = 0 ; chan < 6 ; chan++) {
-                       wave_set_register(s,s->apu[chan]<<3,s->apu_base[chan]);
-                       for(reg = 1 ; reg < NR_APU_REGS ; reg++)  
-                               apu_set_register(s,chan,reg,s->card->apu_map[s->apu[chan]][reg]);
-               }
-               for(chan = 0 ; chan < 6 ; chan++)  
-                       apu_set_register(s,chan,0,s->card->apu_map[s->apu[chan]][0] & 0xFF0F);
-       }
-
-       /* now we flip on the music */
-
-       if( card->dsps_open <= 0) {
-               /* this card's idle */
-               maestro_power(card,ACPI_D2);
-       } else {
-               /* ok, we're actually playing things on
-                       this card */
-               maestro_power(card,ACPI_D0);
-               start_bob(&card->channels[0]);
-               for(i=0;i<NR_DSPS;i++) {
-                       struct ess_state *s = &card->channels[i];
-
-                       /* these use the apu_mode, and can handle
-                               spurious calls */
-                       start_dac(s);   
-                       start_adc(s);   
-               }
-       }
-
-       spin_unlock_irqrestore(&card->lock,flags);
-
-       /* all right, we think things are ready, 
-               wake up people who were using the device
-               when we suspended */
-       wake_up(&(card->suspend_queue));
-
-       return 0;
-}
-
-int 
-maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) 
-{
-       struct ess_card *card = (struct ess_card*) dev->data;
-
-       if ( ! card ) goto out;
-
-       M_printk("maestro: pm event 0x%x received for card %p\n", rqst, card);
-       
-       switch (rqst) {
-               case PM_SUSPEND: 
-                       maestro_suspend(card);
-               break;
-               case PM_RESUME: 
-                       maestro_resume(card);
-               break;
-               /*
-                * we'd also like to find out about
-                * power level changes because some biosen
-                * do mean things to the maestro when they
-                * change their power state.
-                */
-        }
-out:
-       return 0;
-}
-
 module_init(init_maestro);
 module_exit(cleanup_maestro);