patch-2.4.7 linux/drivers/sound/esssolo1.c

Next file: linux/drivers/sound/maestro.c
Previous file: linux/drivers/sound/dev_table.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.6/linux/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c
@@ -1,4 +1,4 @@
-/*****************************************************************************/
+/****************************************************************************/
 
 /*
  *      esssolo1.c  --  ESS Technology Solo1 (ES1946) audio driver.
@@ -79,6 +79,9 @@
  *                       for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
  *    15.05.2001         pci_enable_device moved, return values in probe cleaned
  *                       up. Marcus Meissner <mm@caldera.de>
+ *    22.05.2001   0.19  more cleanups, changed PM to PCI 2.4 style, got rid
+ *                       of global list of devices, using pci device data.
+ *                       Marcus Meissner <mm@caldera.de>
  */
 
 /*****************************************************************************/
@@ -94,7 +97,6 @@
 #include <linux/soundcard.h>
 #include <linux/pci.h>
 #include <linux/bitops.h>
-#include <linux/pm.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <linux/init.h>
@@ -104,25 +106,9 @@
 #include <linux/wrapper.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
-
-#include "dm.h"
-
-#if defined(CONFIG_INPUT_ANALOG) || defined(CONFIG_INPUT_ANALOG_MODULE)
 #include <linux/gameport.h>
-#else
-struct gameport {
-	int io;
-	int size;
-};
 
-extern inline void gameport_register_port(struct gameport *gameport)
-{
-}
-
-extern inline void gameport_unregister_port(struct gameport *gameport)
-{
-}
-#endif
+#include "dm.h"
 
 /* --------------------------------------------------------------------- */
 
@@ -147,6 +133,7 @@
 #define VCBASE_EXTENT             (DDMABASE_EXTENT+DDMABASE_OFFSET)
 #define MPUBASE_EXTENT            4
 #define GPBASE_EXTENT             4
+#define GAMEPORT_EXTENT		  4
 
 #define FMSYNTH_EXTENT            4
 
@@ -161,15 +148,14 @@
 
 #define FMODE_DMFM 0x10
 
+static struct pci_driver solo1_driver;
+
 /* --------------------------------------------------------------------- */
 
 struct solo1_state {
 	/* magic */
 	unsigned int magic;
 
-	/* list of esssolo1 devices */
-	struct list_head devs;
-	
 	/* the corresponding pci_dev structure */
 	struct pci_dev *dev;
 
@@ -244,10 +230,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static LIST_HEAD(devs);
-
-/* --------------------------------------------------------------------- */
-
 extern inline void write_seq(struct solo1_state *s, unsigned char data)
 {
         int i;
@@ -939,16 +921,22 @@
 static int solo1_open_mixdev(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
-	struct list_head *list;
-	struct solo1_state *s;
+	struct solo1_state *s = NULL;
+	struct pci_dev *pci_dev;
 
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct solo1_state, devs);
+	pci_for_each_dev(pci_dev) {
+		struct pci_driver *drvr;
+		drvr = pci_dev_driver (pci_dev);
+		if (drvr != &solo1_driver)
+			continue;
+		s = (struct solo1_state*)pci_get_drvdata(pci_dev);
+		if (!s)
+			continue;
 		if (s->dev_mixer == minor)
 			break;
 	}
+	if (!s)
+		return -ENODEV;
        	VALIDATE_STATE(s);
 	file->private_data = s;
 	return 0;
@@ -1611,16 +1599,23 @@
 {
 	int minor = MINOR(inode->i_rdev);
 	DECLARE_WAITQUEUE(wait, current);
-	struct list_head *list;
-	struct solo1_state *s;
+	struct solo1_state *s = NULL;
+	struct pci_dev *pci_dev;
 	
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct solo1_state, devs);
+	pci_for_each_dev(pci_dev) {
+		struct pci_driver *drvr;
+
+		drvr = pci_dev_driver(pci_dev);
+		if (drvr != &solo1_driver)
+			continue;
+		s = (struct solo1_state*)pci_get_drvdata(pci_dev);
+		if (!s)
+			continue;
 		if (!((s->dev_audio ^ minor) & ~0xf))
 			break;
 	}
+	if (!s)
+		return -ENODEV;
        	VALIDATE_STATE(s);
 	file->private_data = s;
 	/* wait for device to become free */
@@ -1894,16 +1889,23 @@
 	int minor = MINOR(inode->i_rdev);
 	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
-	struct list_head *list;
-	struct solo1_state *s;
+	struct solo1_state *s = NULL;
+	struct pci_dev *pci_dev;
+
+	pci_for_each_dev(pci_dev) {
+		struct pci_driver *drvr;
 
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct solo1_state, devs);
+		drvr = pci_dev_driver(pci_dev);
+		if (drvr != &solo1_driver)
+			continue;
+		s = (struct solo1_state*)pci_get_drvdata(pci_dev);
+		if (!s)
+			continue;
 		if (s->dev_midi == minor)
 			break;
 	}
+	if (!s)
+		return -ENODEV;
        	VALIDATE_STATE(s);
 	file->private_data = s;
 	/* wait for device to become free */
@@ -2112,16 +2114,23 @@
 {
 	int minor = MINOR(inode->i_rdev);
 	DECLARE_WAITQUEUE(wait, current);
-	struct list_head *list;
-	struct solo1_state *s;
+	struct solo1_state *s = NULL;
+	struct pci_dev *pci_dev;
 
-	for (list = devs.next; ; list = list->next) {
-		if (list == &devs)
-			return -ENODEV;
-		s = list_entry(list, struct solo1_state, devs);
+	pci_for_each_dev(pci_dev) {
+		struct pci_driver *drvr;
+
+		drvr = pci_dev_driver(pci_dev);
+		if (drvr != &solo1_driver)
+			continue;
+		s = (struct solo1_state*)pci_get_drvdata(pci_dev);
+		if (!s)
+			continue;
 		if (s->dev_dmfm == minor)
 			break;
 	}
+	if (!s)
+		return -ENODEV;
        	VALIDATE_STATE(s);
 	file->private_data = s;
 	/* wait for device to become free */
@@ -2256,33 +2265,31 @@
 	return 0;
 }
 
-static int solo1_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-{
-	struct solo1_state *s = (struct solo1_state*) dev->data;
-	if (s) {
-		switch(rqst) {
-		case PM_RESUME:
-			setup_solo1(s);
-			break;
+static void
+solo1_suspend(struct pci_dev *pci_dev) {
+	struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
+	if (!s)
+		return;
+	outb(0, s->iobase+6);
+	/* DMA master clear */
+	outb(0, s->ddmabase+0xd); 
+	/* reset sequencer and FIFO */
+	outb(3, s->sbbase+6); 
+	/* turn off DDMA controller address space */
+	pci_write_config_word(s->dev, 0x60, 0); 
+}
 
-		case PM_SUSPEND:
-			outb(0, s->iobase+6);
-			/* DMA master clear */
-			outb(0, s->ddmabase+0xd); 
-			/* reset sequencer and FIFO */
-			outb(3, s->sbbase+6); 
-			/* turn off DDMA controller address space */
-			pci_write_config_word(s->dev, 0x60, 0); 
-			break;
-		}
-	}
-	return 0;
+static void
+solo1_resume(struct pci_dev *pci_dev) {
+	struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
+	if (!s)
+		return;
+	setup_solo1(s);
 }
 
 static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
 	struct solo1_state *s;
-	struct pm_dev *pmdev;
 	int ret;
 
  	if ((ret=pci_enable_device(pcidev)))
@@ -2324,7 +2331,6 @@
 	s->ddmabase = s->vcbase + DDMABASE_OFFSET;
 	s->mpubase = pci_resource_start(pcidev, 3);
 	s->gameport.io = pci_resource_start(pcidev, 4);
-	s->gameport.size = pci_resource_len(pcidev,4);
 	s->irq = pcidev->irq;
 	ret = -EBUSY;
 	if (!request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1")) {
@@ -2343,11 +2349,9 @@
 		printk(KERN_ERR "solo1: io ports in use\n");
 		goto err_region4;
 	}
-	if (!s->gameport.size)
-		s->gameport.io = 0;
-	if (s->gameport.io && !request_region(s->gameport.io, s->gameport.size, "ESS Solo1")) {
+	if (s->gameport.io && !request_region(s->gameport.io, GAMEPORT_EXTENT, "ESS Solo1")) {
 		printk(KERN_ERR "solo1: gameport io ports in use\n");
-		s->gameport.io = s->gameport.size = 0;
+		s->gameport.io = 0;
 	}
 	if ((ret=request_irq(s->irq,solo1_interrupt,SA_SHIRQ,"ESS Solo1",s))) {
 		printk(KERN_ERR "solo1: irq %u in use\n", s->irq);
@@ -2379,13 +2383,6 @@
 	gameport_register_port(&s->gameport);
 	/* store it in the driver field */
 	pci_set_drvdata(pcidev, s);
-	/* put it into driver list */
-	list_add_tail(&s->devs, &devs);
-
-	pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev), solo1_pm_callback);
-	if (pmdev)
-		pmdev->data = s;
-
 	return 0;
 
  err:
@@ -2401,7 +2398,7 @@
 	free_irq(s->irq, s);
  err_irq:
 	if (s->gameport.io)
-		release_region(s->gameport.io, s->gameport.size);
+		release_region(s->gameport.io, GAMEPORT_EXTENT);
 	release_region(s->iobase, IOBASE_EXTENT);
  err_region4:
 	release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
@@ -2420,7 +2417,6 @@
 	
 	if (!s)
 		return;
-	list_del(&s->devs);
 	/* stop DMA controller */
 	outb(0, s->iobase+6);
 	outb(0, s->ddmabase+0xd); /* DMA master clear */
@@ -2430,7 +2426,7 @@
 	free_irq(s->irq, s);
 	if (s->gameport.io) {
 		gameport_unregister_port(&s->gameport);
-		release_region(s->gameport.io, s->gameport.size);
+		release_region(s->gameport.io, GAMEPORT_EXTENT);
 	}
 	release_region(s->iobase, IOBASE_EXTENT);
 	release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
@@ -2455,7 +2451,9 @@
 	name: "ESS Solo1",
 	id_table: id_table,
 	probe: solo1_probe,
-	remove: solo1_remove
+	remove: solo1_remove,
+	suspend: solo1_suspend,
+	resume: solo1_resume
 };
 
 
@@ -2463,7 +2461,7 @@
 {
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
-	printk(KERN_INFO "solo1: version v0.18 time " __TIME__ " " __DATE__ "\n");
+	printk(KERN_INFO "solo1: version v0.19 time " __TIME__ " " __DATE__ "\n");
 	if (!pci_register_driver(&solo1_driver)) {
 		pci_unregister_driver(&solo1_driver);
                 return -ENODEV;
@@ -2480,7 +2478,6 @@
 {
 	printk(KERN_INFO "solo1: unloading\n");
 	pci_unregister_driver(&solo1_driver);
-	pm_unregister_all(solo1_pm_callback);
 }
 
 /* --------------------------------------------------------------------- */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)