This patch cleans up the ISAPnP detection code in the soundblaster driver.
If you use the soundblaster driver please test this patch and let me know
the results. Patch applies to 2.3.99pre1 through pre3-3 (which was the
latest as of this writing).
Thanks in advance,
Paul Laufer
--- linux-devel-virgin/drivers/sound/sb_card.c Mon Mar 13 12:29:00 2000
+++ linux/drivers/sound/sb_card.c Thu Mar 16 12:48:53 2000
@@ -29,6 +29,8 @@
* 13-02-2000 Hopefully fixed awe/sb16 related bugs, code cleanup
* Alessandro Zummo <[EMAIL PROTECTED]>
*
+ * 13-03-2000 Unified isapnp card detection, code cleanup.
+ * Paul Laufer <[EMAIL PROTECTED]>
*/
#include <linux/config.h>
@@ -42,6 +44,7 @@
#include "sb_mixer.h"
#include "sb.h"
+#include "sb_card.h"
static int sbmpu = 0;
@@ -205,6 +208,42 @@
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static struct { unsigned short vendor, device, function; struct pci_dev *
+(*initfunc)(struct pci_bus *, struct address_info *, struct address_info *, int);
+char *name; }
+isapnp_sb_list[] __initdata = {
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024), ISAPNP_FUNCTION(0x0031),
+&sb_init_generic, "Sound Blaster 16" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0026), ISAPNP_FUNCTION(0x0031),
+&sb_init_generic, "Sound Blaster 16" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0027), ISAPNP_FUNCTION(0x0031),
+&sb_init_generic, "Sound Blaster 16" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029), ISAPNP_FUNCTION(0x0031),
+&sb_init_generic, "Sound Blaster 16" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b), ISAPNP_FUNCTION(0x0031),
+&sb_init_generic, "Sound Blaster 16" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051), ISAPNP_FUNCTION(0x0001),
+&sb_init_generic, "Sound Blaster Vibra16S" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070), ISAPNP_FUNCTION(0x0001),
+&sb_init_generic, "Sound Blaster Vibra16C" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080), ISAPNP_FUNCTION(0x0041),
+&sb_init_generic, "Sound Blaster Vibra16CL" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0), ISAPNP_FUNCTION(0x0043),
+&sb_init_generic, "Sound Blaster Vibra16X" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039), ISAPNP_FUNCTION(0x0031),
+&sb_init_awe, "Sound Blaster AWE 32" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042), ISAPNP_FUNCTION(0x0031),
+&sb_init_awe, "Sound Blaster AWE 32" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043), ISAPNP_FUNCTION(0x0031),
+&sb_init_awe, "Sound Blaster AWE 32" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044), ISAPNP_FUNCTION(0x0031),
+&sb_init_awe, "Sound Blaster AWE 32" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048), ISAPNP_FUNCTION(0x0031),
+&sb_init_awe, "Sound Blaster AWE 32" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054), ISAPNP_FUNCTION(0x0031),
+&sb_init_awe, "Sound Blaster AWE 32" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C), ISAPNP_FUNCTION(0x0041),
+&sb_init_awe, "Sound Blaster AWE 32" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D), ISAPNP_FUNCTION(0x0042),
+&sb_init_awe, "Sound Blaster AWE 64" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E), ISAPNP_FUNCTION(0x0044),
+&sb_init_awe, "Sound Blaster AWE 64 Gold" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1), ISAPNP_FUNCTION(0x0042),
+&sb_init_awe, "Sound Blaster AWE 64" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3), ISAPNP_FUNCTION(0x0045),
+&sb_init_awe, "Sound Blaster AWE 64" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5), ISAPNP_FUNCTION(0x0045),
+&sb_init_awe, "Sound Blaster AWE 64" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7), ISAPNP_FUNCTION(0x0045),
+&sb_init_awe, "Sound Blaster AWE 64" },
+ {ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4), ISAPNP_FUNCTION(0x0045),
+&sb_init_awe, "Sound Blaster AWE 64" },
+ {ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868), ISAPNP_FUNCTION(0x1868),
+&sb_init_ess, "ESS 1868" },
+ {ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868), ISAPNP_FUNCTION(0x8611),
+&sb_init_ess, "ESS 1868" },
+ {ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003), ISAPNP_FUNCTION(0x1869),
+&sb_init_ess, "ESS 1869 PnP AudioDrive" },
+ {ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869), ISAPNP_FUNCTION(0x1869),
+&sb_init_ess, "ESS 1869" },
+ {ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878), ISAPNP_FUNCTION(0x1878),
+&sb_init_ess, "ESS 1878" },
+ {ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879), ISAPNP_FUNCTION(0x1879),
+&sb_init_ess, "ESS 1879" },
+ {ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001), ISAPNP_FUNCTION(0x0001),
+&sb_init_cmi, "CMI 8330 SoundPRO" },
+ {ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688), ISAPNP_FUNCTION(0x0001),
+&sb_init_diamond, "Diamond DT0197H" },
+ {0}
+};
+
/* That's useful. */
#define show_base(devname, resname, resptr) printk(KERN_INFO "sb: %s %s base located
at %#lx\n", devname, resname, (resptr)->start)
@@ -233,9 +272,9 @@
/* Card's specific initialization functions
*/
-static struct pci_dev *sb_init_generic(struct pci_bus *bus, struct pci_dev *card,
struct address_info *hw_config, struct address_info *mpu_config)
+static struct pci_dev *sb_init_generic(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot)
{
- if((sb_dev = isapnp_find_dev(bus, card->vendor, card->device, NULL)))
+ if((sb_dev = isapnp_find_dev(bus, isapnp_sb_list[slot].vendor,
+isapnp_sb_list[slot].function, NULL)))
{
sb_dev->prepare(sb_dev);
@@ -251,9 +290,9 @@
return(sb_dev);
}
-static struct pci_dev *sb_init_ess(struct pci_bus *bus, struct pci_dev *card, struct
address_info *hw_config, struct address_info *mpu_config)
+static struct pci_dev *sb_init_ess(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot)
{
- if((sb_dev = isapnp_find_dev(bus, card->vendor, card->device, NULL)))
+ if((sb_dev = isapnp_find_dev(bus, isapnp_sb_list[slot].vendor,
+isapnp_sb_list[slot].function, NULL)))
{
sb_dev->prepare(sb_dev);
@@ -269,7 +308,7 @@
return(sb_dev);
}
-static struct pci_dev *sb_init_cmi(struct pci_bus *bus, struct pci_dev *card, struct
address_info *hw_config, struct address_info *mpu_config)
+static struct pci_dev *sb_init_cmi(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot)
{
/*
* The CMI8330/C3D is a very 'stupid' chip... where did they get al those @@@
?
@@ -365,7 +404,7 @@
return(sb_dev);
}
-static struct pci_dev *sb_init_diamond(struct pci_bus *bus, struct pci_dev *card,
struct address_info *hw_config, struct address_info *mpu_config)
+static struct pci_dev *sb_init_diamond(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot)
{
/*
* Diamonds DT0197H
@@ -459,16 +498,14 @@
* b) The joystick driver will support PnP - a little patch is available from
me....hint, hint :-)
*/
-static struct pci_dev *sb_init_awe(struct pci_bus *bus, struct pci_dev *card, struct
address_info *hw_config, struct address_info *mpu_config)
+static struct pci_dev *sb_init_awe(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot)
{
/* CTL0042:Audio SB64
* CTL0031:Audio SB32
* CTL0045:Audio SB64
*/
- if( (sb_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'),
ISAPNP_FUNCTION(0x0042), NULL)) ||
- (sb_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'),
ISAPNP_FUNCTION(0x0031), NULL)) ||
- (sb_dev = isapnp_find_dev(bus, ISAPNP_VENDOR('C','T','L'),
ISAPNP_FUNCTION(0x0045), NULL)) )
+ if((sb_dev = isapnp_find_dev(bus, isapnp_sb_list[slot].vendor,
+isapnp_sb_list[slot].function, NULL)))
{
sb_dev->prepare(sb_dev);
@@ -488,8 +525,10 @@
else
return(NULL);
}
- else
+ else {
printk(KERN_ERR "sb: AWE panic: sb base not found\n");
+ return(sb_dev); /* failed to find audio device, do not continue */
+ }
/* CTL7002:Game SB64
@@ -535,37 +574,8 @@
return(sb_dev);
}
-#define SBF_DEV 0x01
-
-
-static struct { unsigned short vendor, function, flags; struct pci_dev *
(*initfunc)(struct pci_bus *, struct pci_dev *, struct address_info *, struct
address_info *); char *name; }
-isapnp_sb_list[] __initdata = {
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), SBF_DEV,
&sb_init_generic, "Sound Blaster 16" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), SBF_DEV,
&sb_init_generic, "Sound Blaster 16" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), SBF_DEV,
&sb_init_generic, "Sound Blaster 16" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), SBF_DEV,
&sb_init_generic, "Sound Blaster 16" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043), SBF_DEV,
&sb_init_generic, "Sound Blaster 16" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), SBF_DEV,
&sb_init_generic, "Sound Blaster 16" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0, &sb_init_awe,
"Sound Blaster 32" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0039), 0, &sb_init_awe,
"Sound Blaster AWE 32" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x009D), 0, &sb_init_awe,
"Sound Blaster AWE 64" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x00C5), 0, &sb_init_awe,
"Sound Blaster AWE 64" },
- {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x00E4), 0, &sb_init_awe,
"Sound Blaster AWE 64" },
- {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968), SBF_DEV, &sb_init_ess,
"ESS 1688" },
- {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), SBF_DEV, &sb_init_ess,
"ESS 1868" },
- {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), SBF_DEV, &sb_init_ess,
"ESS 1868" },
- {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), SBF_DEV, &sb_init_ess,
"ESS 1869" },
- {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), SBF_DEV, &sb_init_ess,
"ESS 1878" },
- {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), SBF_DEV, &sb_init_ess,
"ESS 1879" },
- {ISAPNP_VENDOR('C','M','I'), ISAPNP_FUNCTION(0x0001), 0, &sb_init_cmi,
"CMI 8330 SoundPRO" },
- {ISAPNP_VENDOR('R','W','B'), ISAPNP_FUNCTION(0x1688), 0,
&sb_init_diamond, "Diamond DT0197H" },
- {0}
-};
-
-static int __init sb_init_isapnp(struct address_info *hw_config, struct address_info
*mpu_config, struct pci_bus *bus, struct pci_dev *card, int slot)
+static int __init sb_init_isapnp(struct address_info *hw_config, struct address_info
+*mpu_config, struct pci_bus *bus, int slot)
{
- struct pci_dev *idev = NULL;
-
/* You missed the init func? That's bad. */
if(isapnp_sb_list[slot].initfunc)
{
@@ -575,7 +585,7 @@
/* Initialize this baby. */
- if((idev = isapnp_sb_list[slot].initfunc(bus, card, hw_config,
mpu_config)))
+ if(isapnp_sb_list[slot].initfunc(bus, hw_config, mpu_config, slot))
{
/* We got it. */
@@ -615,40 +625,15 @@
}
for (i = isapnpjump; isapnp_sb_list[i].vendor != 0; i++) {
-
- if(!(isapnp_sb_list[i].flags & SBF_DEV))
- {
- struct pci_bus *bus = NULL;
+ struct pci_bus *bus = NULL;
- while ((bus = isapnp_find_card(
- isapnp_sb_list[i].vendor,
- isapnp_sb_list[i].function,
- bus))) {
-
- if(sb_init_isapnp(hw_config, mpu_config, bus, NULL,
i))
- return 0;
- }
- }
- }
-
- /* No cards found. I'll try now to search inside every card for a logical
device
- * that matches any entry marked with SBF_DEV in the table.
- */
+ while ((bus = isapnp_find_card(
+ isapnp_sb_list[i].vendor,
+ isapnp_sb_list[i].device,
+ bus))) {
- for (i = isapnpjump; isapnp_sb_list[i].vendor != 0; i++) {
-
- if(isapnp_sb_list[i].flags & SBF_DEV)
- {
- struct pci_dev *card = NULL;
-
- while ((card = isapnp_find_dev(NULL,
- isapnp_sb_list[i].vendor,
- isapnp_sb_list[i].function,
- card))) {
-
- if(sb_init_isapnp(hw_config, mpu_config, card->bus,
card, i))
- return 0;
- }
+ if(sb_init_isapnp(hw_config, mpu_config, bus, i))
+ return 0;
}
}
--- linux-devel-virgin/drivers/sound/sb_card.h Thu Mar 16 12:50:16 2000
+++ linux/drivers/sound/sb_card.h Wed Mar 15 21:48:38 2000
@@ -0,0 +1,9 @@
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+
+static struct pci_dev *sb_init_generic(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot);
+static struct pci_dev *sb_init_cmi(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot);
+static struct pci_dev *sb_init_awe(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot);
+static struct pci_dev *sb_init_ess(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot);
+static struct pci_dev *sb_init_diamond(struct pci_bus *bus, struct address_info
+*hw_config, struct address_info *mpu_config, int slot);
+
+#endif