* mpu401_pnp
@ 2004-08-31 20:50 castet.matthieu
2005-02-07 8:46 ` mpu401_pnp Clemens Ladisch
0 siblings, 1 reply; 11+ messages in thread
From: castet.matthieu @ 2004-08-31 20:50 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 677 bytes --]
Hello,
I send you a mpu401 modules that support pnpbios.
I don't add it to the mpu401 because it would add too much define.
I am not a specialist in Kconfig edit, so for testing on my comptuter, I only
remplace traditionnal mpu401 with mpu401_pnp.
Also I clear the function that create the mpu (snd_card_mpu401_add), and I think
you could re-use it for acpi_pnp insted of adding define.
As you can see, because of a bug in pnpbios code, sometime it doesn't find a
irq, so it add a litle hack waiting the bug is fix in the kernel.
With that, an some script (hotplug for example), the mpu401 is automatiquely
detected(at least on my i810 chipset).
Matthieu
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: mpu401_pnp.c --]
[-- Type: text/x-csrc; name="mpu401_pnp.c", Size: 5575 bytes --]
/*
* Driver for generic MPU-401 boards (UART mode only)
* Copyright (c) by Jaroslav Kysela <perex@suse.cz>
*
* Copyright (c) 2004 by Castet Matthieu <castet.matthieu@free.fr>
* portd on mpu401.c
* Copyright (c) 2002-2003 Matthew Wilcox for Hewlett-Packard
* Copyright (C) 2004 Hewlett-Packard Co
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/mpu401.h>
#include <sound/initval.h>
#include <linux/pnp.h>
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("MPU-401 UART");
MODULE_LICENSE("GPL");
MODULE_CLASSES("{sound}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static int boot_devs;
module_param_array(index, int, boot_devs, 0444);
MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
module_param_array(id, charp, boot_devs, 0444);
MODULE_PARM_DESC(id, "ID string for MPU-401 device.");
MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
module_param_array(enable, bool, boot_devs, 0444);
MODULE_PARM_DESC(enable, "Enable MPU-401 device.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
#define IO_EXTENT 2
#define BROKEN_PNPBIOS
static int snd_card_mpu401_add(int dev, snd_card_t **pcard, long port, int irq, char * optional_description)
{
int err;
snd_card_t *card;
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
strcpy(card->driver, "MPU-401 UART");
strcpy(card->shortname, card->driver);
sprintf(card->longname, "%s at 0x%lx, ", card->shortname, port);
if (irq >= 0) {
sprintf(card->longname + strlen(card->longname), "IRQ %d", irq);
} else {
strcat(card->longname, "polled");
}
if (optional_description)
strlcat(card->longname, optional_description, sizeof(card->longname));
if (snd_mpu401_uart_new(card, 0,
MPU401_HW_MPU401,
port, 0,
irq, irq >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port);
snd_card_free(card);
return -ENODEV;
}
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);
return err;
}
*pcard = card;
return 0;
}
static struct pnp_device_id pnp_devids[] = {
{ .id = "PNPb006", .driver_data = 0 },
{ .id = "", },
};
MODULE_DEVICE_TABLE(pnp, pnp_devids);
static int __devinit snd_card_mpu401_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *did) {
long port;
int irq;
snd_card_t *card = NULL;
int ret;
static int card_dev = 0;
if (card_dev >= SNDRV_CARDS)
return -ENODEV;
if (!enable[card_dev]) {
card_dev++;
return -ENOENT;
}
#ifdef BROKEN_PNPBIOS
retry:
#endif
if (!pnp_port_valid(dev, 0) ||
pnp_port_flags(dev,0) & IORESOURCE_DISABLED) {
printk(KERN_WARNING "No io port !\n");
return -ENODEV;
}
if (pnp_port_len(dev, 0) < IO_EXTENT) {
printk(KERN_WARNING "io port len : %ld (expected : %d) !\n",
pnp_port_len(dev, 0),
IO_EXTENT);
return -ENODEV;
}
port = pnp_port_start(dev,0);
if (!pnp_irq_valid(dev,0)||
pnp_irq_flags(dev,0) & IORESOURCE_DISABLED) {
#ifdef BROKEN_PNPBIOS
//XXX parser bug
static int retry = 0;
if (dev->dependent && !retry) {
dev->active = 0;
printk(KERN_WARNING "broken pnpbios retry : %d!\n",pnp_assign_resources(dev, 2));
dev->active = 1;
retry = 1;
goto retry;
}
#endif
printk(KERN_WARNING "No irq !\n");
irq = -1;
}
else {
irq = pnp_irq(dev,0);
}
printk(KERN_INFO "snd_card_mpu401 pnpbios :"
"%s port 0x%03lx, irq=%d\n",
pnp_dev_name(dev), port, irq);
//XXX pnp_dev_name(pnp_dev) give me a empty string ...
/*
strcat(option, ", ");
strlcat(option, pnp_dev_name(pnp_dev), sizeof(card->longname));
*/
ret = snd_card_mpu401_add(card_dev, &card, port, irq, NULL);
if (ret >= 0)
pnp_set_drvdata(dev, card);
return ret;
}
static void snd_card_mpu401_pnp_remove(struct pnp_dev *dev) {
snd_card_t *card = (snd_card_t *)pnp_get_drvdata(dev);
if (!card) {
BUG();
return;
}
snd_card_disconnect(card);
snd_card_free_in_thread(card);
}
static struct pnp_driver snd_mpu401_pnp_driver = {
.name = "mpu401",
.id_table = pnp_devids,
.probe = snd_card_mpu401_pnp_probe,
.remove = snd_card_mpu401_pnp_remove,
};
static int __init alsa_card_mpu401_init(void)
{
int ret = pnp_register_driver(&snd_mpu401_pnp_driver);
if (ret == 0) {
pnp_unregister_driver(&snd_mpu401_pnp_driver);
}
if (ret <= 0) {
return -ENODEV;
}
return 0;
}
static void __exit alsa_card_mpu401_exit(void)
{
pnp_unregister_driver(&snd_mpu401_pnp_driver);
}
module_init(alsa_card_mpu401_init)
module_exit(alsa_card_mpu401_exit)
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: mpu401_pnp
2004-08-31 20:50 mpu401_pnp castet.matthieu
@ 2005-02-07 8:46 ` Clemens Ladisch
2005-02-07 10:40 ` mpu401_pnp castet.matthieu
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Clemens Ladisch @ 2005-02-07 8:46 UTC (permalink / raw)
To: castet.matthieu; +Cc: alsa-devel
castet.matthieu@free.fr wrote:
> I send you a mpu401 modules that support pnpbios.
Applied (merged with mpu401.c), thanks.
(I didn't read your mail from Friday until I had written the patch. :)
> As you can see, because of a bug in pnpbios code, sometime it doesn't find a
> irq, so it add a litle hack waiting the bug is fix in the kernel.
I didn't add this workaround. Is this bug still in the kernel?
Best regards,
Clemens
-------------------------------------------------------
This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
Tool for open source databases. Create drag-&-drop reports. Save time
by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
Download a FREE copy at http://www.intelliview.com/go/osdn_nl
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: mpu401_pnp
2005-02-07 8:46 ` mpu401_pnp Clemens Ladisch
@ 2005-02-07 10:40 ` castet.matthieu
2005-02-07 12:10 ` mpu401_pnp matthieu castet
2005-02-07 12:59 ` mpu401_pnp matthieu castet
2 siblings, 0 replies; 11+ messages in thread
From: castet.matthieu @ 2005-02-07 10:40 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel
Quoting Clemens Ladisch <clemens@ladisch.de>:
> castet.matthieu@free.fr wrote:
> > I send you a mpu401 modules that support pnpbios.
>
> Applied (merged with mpu401.c), thanks.
>
> (I didn't read your mail from Friday until I had written the patch. :)
>
> > As you can see, because of a bug in pnpbios code, sometime it doesn't find
> a
> > irq, so it add a litle hack waiting the bug is fix in the kernel.
>
> I didn't add this workaround. Is this bug still in the kernel?
>
No it was corrected in 2.6.9 or 2.6.10.
Regards,
Matthieu
-------------------------------------------------------
This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
Tool for open source databases. Create drag-&-drop reports. Save time
by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
Download a FREE copy at http://www.intelliview.com/go/osdn_nl
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mpu401_pnp
2005-02-07 8:46 ` mpu401_pnp Clemens Ladisch
2005-02-07 10:40 ` mpu401_pnp castet.matthieu
@ 2005-02-07 12:10 ` matthieu castet
2005-02-07 12:59 ` mpu401_pnp matthieu castet
2 siblings, 0 replies; 11+ messages in thread
From: matthieu castet @ 2005-02-07 12:10 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel
Hi,
Clemens Ladisch wrote:
> castet.matthieu@free.fr wrote:
>
>>I send you a mpu401 modules that support pnpbios.
>
>
> Applied (merged with mpu401.c), thanks.
>
> (I didn't read your mail from Friday until I had written the patch. :)
Ok, I found a bug in your patch : when you call pnp_register_driver, you
should check that it is >= 0. If not you shouldn't call
pnp_unregister_driver.
Matthieu
-------------------------------------------------------
This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
Tool for open source databases. Create drag-&-drop reports. Save time
by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
Download a FREE copy at http://www.intelliview.com/go/osdn_nl
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mpu401_pnp
2005-02-07 8:46 ` mpu401_pnp Clemens Ladisch
2005-02-07 10:40 ` mpu401_pnp castet.matthieu
2005-02-07 12:10 ` mpu401_pnp matthieu castet
@ 2005-02-07 12:59 ` matthieu castet
2005-02-07 15:54 ` mpu401_pnp Clemens Ladisch
2005-02-11 10:00 ` mpu401_pnp Clemens Ladisch
2 siblings, 2 replies; 11+ messages in thread
From: matthieu castet @ 2005-02-07 12:59 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 210 bytes --]
Hi,
attached a version more readable with less ifdef.
It is untested, but it should work.
One question : does snd_card_set_dev(card, &device->dev) is important ?
It wasn't use with acpi.
regards,
Matthieu
[-- Attachment #2: mpu.patch --]
[-- Type: text/x-patch, Size: 5318 bytes --]
--- mpu401.c?rev=1.22 2005-02-07 13:26:09.000000000 +0100
+++ mpu401.c 2005-02-07 13:55:30.000000000 +0100
@@ -57,68 +57,13 @@
MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
static snd_card_t *snd_mpu401_legacy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static int pnp_registered = 0;
-#ifdef CONFIG_PNP
-
-#define IO_EXTENT 2
-
-static struct pnp_device_id snd_mpu401_pnpids[] = {
- { .id = "PNPb006" },
- { .id = "" }
-};
-
-MODULE_DEVICE_TABLE(pnp, snd_mpu401_pnpids);
-
-static int __init snd_mpu401_pnp(int dev, struct pnp_dev *device,
- const struct pnp_device_id *id)
-{
- if (!pnp_port_valid(device, 0) ||
- pnp_port_flags(device, 0) & IORESOURCE_DISABLED) {
- snd_printk(KERN_ERR "no PnP port\n");
- return -ENODEV;
- }
- if (pnp_port_len(device, 0) < IO_EXTENT) {
- snd_printk(KERN_ERR "PnP port length is %ld, expected %d\n",
- pnp_port_len(device, 0), IO_EXTENT);
- return -ENODEV;
- }
- port[dev] = pnp_port_start(device, 0);
-
- if (!pnp_irq_valid(device, 0) ||
- pnp_irq_flags(device, 0) & IORESOURCE_DISABLED) {
- snd_printk(KERN_WARNING "no PnP irq, using polling\n");
- irq[dev] = -1;
- } else {
- irq[dev] = pnp_irq(device, 0);
- }
- return 0;
-}
-#endif
-
-static int __devinit snd_card_mpu401_probe(int dev, struct pnp_dev *device,
- const struct pnp_device_id *pnp_id)
+static int snd_card_mpu401_add(int dev)
{
snd_card_t *card;
int err;
-#ifdef CONFIG_PNP
- if (!device) {
-#endif
- if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify port\n");
- return -EINVAL;
- }
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- snd_printk(KERN_ERR "specify or disable IRQ\n");
- return -EINVAL;
- }
-#ifdef CONFIG_PNP
- } else {
- if ((err = snd_mpu401_pnp(dev, device, pnp_id)) < 0)
- return err;
- }
-#endif
-
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -130,11 +75,13 @@
} else {
strcat(card->longname, "polled");
}
-#ifdef CONFIG_PNP
+
+ /*
if (device) {
snd_card_set_dev(card, &device->dev);
}
-#endif
+ */
+
if (snd_mpu401_uart_new(card, 0,
MPU401_HW_MPU401,
port[dev], 0,
@@ -147,16 +94,59 @@
snd_card_free(card);
return err;
}
-#ifdef CONFIG_PNP
- if (device)
- pnp_set_drvdata(device, card);
- else
-#endif
snd_mpu401_legacy_cards[dev] = card;
return 0;
}
+static int __devinit snd_card_mpu401_probe(int dev)
+{
+ if (port[dev] == SNDRV_AUTO_PORT) {
+ snd_printk(KERN_ERR "specify port\n");
+ return -EINVAL;
+ }
+ if (irq[dev] == SNDRV_AUTO_IRQ) {
+ snd_printk(KERN_ERR "specify or disable IRQ\n");
+ return -EINVAL;
+ }
+ return snd_card_mpu401_add(dev);
+}
+
#ifdef CONFIG_PNP
+
+#define IO_EXTENT 2
+
+static struct pnp_device_id snd_mpu401_pnpids[] = {
+ { .id = "PNPb006" },
+ { .id = "" }
+};
+
+MODULE_DEVICE_TABLE(pnp, snd_mpu401_pnpids);
+
+static int __init snd_mpu401_pnp(int dev, struct pnp_dev *device,
+ const struct pnp_device_id *id)
+{
+ if (!pnp_port_valid(device, 0) ||
+ pnp_port_flags(device, 0) & IORESOURCE_DISABLED) {
+ snd_printk(KERN_ERR "no PnP port\n");
+ return -ENODEV;
+ }
+ if (pnp_port_len(device, 0) < IO_EXTENT) {
+ snd_printk(KERN_ERR "PnP port length is %ld, expected %d\n",
+ pnp_port_len(device, 0), IO_EXTENT);
+ return -ENODEV;
+ }
+ port[dev] = pnp_port_start(device, 0);
+
+ if (!pnp_irq_valid(device, 0) ||
+ pnp_irq_flags(device, 0) & IORESOURCE_DISABLED) {
+ snd_printk(KERN_WARNING "no PnP irq, using polling\n");
+ irq[dev] = -1;
+ } else {
+ irq[dev] = pnp_irq(device, 0);
+ }
+ return snd_card_mpu401_add(dev);
+}
+
static int __devinit snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
const struct pnp_device_id *id)
{
@@ -166,9 +156,11 @@
for ( ; dev < SNDRV_CARDS; ++dev) {
if (!enable[dev] || !pnp[dev])
continue;
- err = snd_card_mpu401_probe(dev, pnp_dev, id);
+ err = snd_mpu401_pnp(dev, pnp_dev, id);
if (err < 0)
return err;
+ pnp_set_drvdata(pnp_dev, snd_mpu401_legacy_cards[dev]);
+ snd_mpu401_legacy_cards[dev] = NULL;
++dev;
return 0;
}
@@ -189,11 +181,14 @@
.probe = snd_mpu401_pnp_probe,
.remove = __devexit_p(snd_mpu401_pnp_remove),
};
+#else
+static struct pnp_driver snd_mpu401_pnp_driver;
#endif
static int __init alsa_card_mpu401_init(void)
{
int dev, devices = 0;
+ int err;
for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev])
@@ -202,19 +197,20 @@
if (pnp[dev])
continue;
#endif
- if (snd_card_mpu401_probe(dev, NULL, NULL) >= 0)
+ if (snd_card_mpu401_probe(dev) >= 0)
devices++;
}
-#ifdef CONFIG_PNP
- devices += pnp_register_driver(&snd_mpu401_pnp_driver);
-#endif
+ if ((err = pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) {
+ pnp_registered = 1;
+ devices += err;
+ }
+
if (!devices) {
#ifdef MODULE
printk(KERN_ERR "MPU-401 device not found or device busy\n");
#endif
-#ifdef CONFIG_PNP
- pnp_unregister_driver(&snd_mpu401_pnp_driver);
-#endif
+ if (pnp_registered)
+ pnp_unregister_driver(&snd_mpu401_pnp_driver);
return -ENODEV;
}
return 0;
@@ -224,9 +220,8 @@
{
int idx;
-#ifdef CONFIG_PNP
- pnp_unregister_driver(&snd_mpu401_pnp_driver);
-#endif
+ if (pnp_registered)
+ pnp_unregister_driver(&snd_mpu401_pnp_driver);
for (idx = 0; idx < SNDRV_CARDS; idx++)
snd_card_free(snd_mpu401_legacy_cards[idx]);
}
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: mpu401_pnp
2005-02-07 12:59 ` mpu401_pnp matthieu castet
@ 2005-02-07 15:54 ` Clemens Ladisch
2005-02-07 19:13 ` mpu401_pnp matthieu castet
` (2 more replies)
2005-02-11 10:00 ` mpu401_pnp Clemens Ladisch
1 sibling, 3 replies; 11+ messages in thread
From: Clemens Ladisch @ 2005-02-07 15:54 UTC (permalink / raw)
To: matthieu castet; +Cc: alsa-devel
matthieu castet wrote:
> Ok, I found a bug in your patch : when you call pnp_register_driver, you
> should check that it is >= 0. If not you shouldn't call
> pnp_unregister_driver.
I just copied this from the other ALSA PnP drivers. It seems those
have all the same bug.
> One question : does snd_card_set_dev(card, &device->dev) is important ?
Well, this pointer should be set if possible, but I'm not sure if it's
actually used anywhere.
> It wasn't use with acpi.
Well, it should have been used. :-) I adapted the ACPI code from the
serial driver which of course didn't have this, and the 2.4 kernel I
developed this on didn't have 'struct device' anyway.
Best regards,
Clemens
-------------------------------------------------------
This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting
Tool for open source databases. Create drag-&-drop reports. Save time
by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc.
Download a FREE copy at http://www.intelliview.com/go/osdn_nl
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: mpu401_pnp
2005-02-07 15:54 ` mpu401_pnp Clemens Ladisch
@ 2005-02-07 19:13 ` matthieu castet
2005-02-07 19:23 ` mpu401_pnp matthieu castet
2005-02-09 14:17 ` mpu401_pnp matthieu castet
2 siblings, 0 replies; 11+ messages in thread
From: matthieu castet @ 2005-02-07 19:13 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 271 bytes --]
Hi,
Clemens Ladisch wrote:
>>One question : does snd_card_set_dev(card, &device->dev) is important ?
>
>
> Well, this pointer should be set if possible, but I'm not sure if it's
> actually used anywhere.
>
Ok, I update my patch in order to use it.
Regards
Matthieu
[-- Attachment #2: mpu.patch --]
[-- Type: text/x-patch, Size: 4950 bytes --]
--- mpu401.c?rev=1.22 2005-02-07 20:08:05.000000000 +0100
+++ mpu401.c 2005-02-07 20:07:57.000000000 +0100
@@ -57,6 +57,53 @@
MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
static snd_card_t *snd_mpu401_legacy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static int pnp_registered = 0;
+
+static int snd_card_mpu401_add(int dev)
+{
+ snd_card_t *card;
+ int err;
+
+ card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ if (card == NULL)
+ return -ENOMEM;
+ strcpy(card->driver, "MPU-401 UART");
+ strcpy(card->shortname, card->driver);
+ sprintf(card->longname, "%s at %#lx, ", card->shortname, port[dev]);
+ if (irq[dev] >= 0) {
+ sprintf(card->longname + strlen(card->longname), "irq %d", irq[dev]);
+ } else {
+ strcat(card->longname, "polled");
+ }
+
+ if (snd_mpu401_uart_new(card, 0,
+ MPU401_HW_MPU401,
+ port[dev], 0,
+ irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
+ printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
+ snd_card_free(card);
+ return -ENODEV;
+ }
+ if ((err = snd_card_register(card)) < 0) {
+ snd_card_free(card);
+ return err;
+ }
+ snd_mpu401_legacy_cards[dev] = card;
+ return 0;
+}
+
+static int __devinit snd_card_mpu401_probe(int dev)
+{
+ if (port[dev] == SNDRV_AUTO_PORT) {
+ snd_printk(KERN_ERR "specify port\n");
+ return -EINVAL;
+ }
+ if (irq[dev] == SNDRV_AUTO_IRQ) {
+ snd_printk(KERN_ERR "specify or disable IRQ\n");
+ return -EINVAL;
+ }
+ return snd_card_mpu401_add(dev);
+}
#ifdef CONFIG_PNP
@@ -91,72 +138,9 @@
} else {
irq[dev] = pnp_irq(device, 0);
}
- return 0;
+ return snd_card_mpu401_add(dev);
}
-#endif
-
-static int __devinit snd_card_mpu401_probe(int dev, struct pnp_dev *device,
- const struct pnp_device_id *pnp_id)
-{
- snd_card_t *card;
- int err;
-#ifdef CONFIG_PNP
- if (!device) {
-#endif
- if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify port\n");
- return -EINVAL;
- }
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- snd_printk(KERN_ERR "specify or disable IRQ\n");
- return -EINVAL;
- }
-#ifdef CONFIG_PNP
- } else {
- if ((err = snd_mpu401_pnp(dev, device, pnp_id)) < 0)
- return err;
- }
-#endif
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
- strcpy(card->driver, "MPU-401 UART");
- strcpy(card->shortname, card->driver);
- sprintf(card->longname, "%s at %#lx, ", card->shortname, port[dev]);
- if (irq[dev] >= 0) {
- sprintf(card->longname + strlen(card->longname), "irq %d", irq[dev]);
- } else {
- strcat(card->longname, "polled");
- }
-#ifdef CONFIG_PNP
- if (device) {
- snd_card_set_dev(card, &device->dev);
- }
-#endif
- if (snd_mpu401_uart_new(card, 0,
- MPU401_HW_MPU401,
- port[dev], 0,
- irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
- printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
- snd_card_free(card);
- return -ENODEV;
- }
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
-#ifdef CONFIG_PNP
- if (device)
- pnp_set_drvdata(device, card);
- else
-#endif
- snd_mpu401_legacy_cards[dev] = card;
- return 0;
-}
-
-#ifdef CONFIG_PNP
static int __devinit snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
const struct pnp_device_id *id)
{
@@ -166,9 +150,12 @@
for ( ; dev < SNDRV_CARDS; ++dev) {
if (!enable[dev] || !pnp[dev])
continue;
- err = snd_card_mpu401_probe(dev, pnp_dev, id);
+ err = snd_mpu401_pnp(dev, pnp_dev, id);
if (err < 0)
return err;
+ snd_card_set_dev(snd_mpu401_legacy_cards[dev], &device->dev);
+ pnp_set_drvdata(pnp_dev, snd_mpu401_legacy_cards[dev]);
+ snd_mpu401_legacy_cards[dev] = NULL;
++dev;
return 0;
}
@@ -189,11 +176,14 @@
.probe = snd_mpu401_pnp_probe,
.remove = __devexit_p(snd_mpu401_pnp_remove),
};
+#else
+static struct pnp_driver snd_mpu401_pnp_driver;
#endif
static int __init alsa_card_mpu401_init(void)
{
int dev, devices = 0;
+ int err;
for (dev = 0; dev < SNDRV_CARDS; dev++) {
if (!enable[dev])
@@ -202,19 +192,20 @@
if (pnp[dev])
continue;
#endif
- if (snd_card_mpu401_probe(dev, NULL, NULL) >= 0)
+ if (snd_card_mpu401_probe(dev) >= 0)
devices++;
}
-#ifdef CONFIG_PNP
- devices += pnp_register_driver(&snd_mpu401_pnp_driver);
-#endif
+ if ((err = pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) {
+ pnp_registered = 1;
+ devices += err;
+ }
+
if (!devices) {
#ifdef MODULE
printk(KERN_ERR "MPU-401 device not found or device busy\n");
#endif
-#ifdef CONFIG_PNP
- pnp_unregister_driver(&snd_mpu401_pnp_driver);
-#endif
+ if (pnp_registered)
+ pnp_unregister_driver(&snd_mpu401_pnp_driver);
return -ENODEV;
}
return 0;
@@ -224,9 +215,8 @@
{
int idx;
-#ifdef CONFIG_PNP
- pnp_unregister_driver(&snd_mpu401_pnp_driver);
-#endif
+ if (pnp_registered)
+ pnp_unregister_driver(&snd_mpu401_pnp_driver);
for (idx = 0; idx < SNDRV_CARDS; idx++)
snd_card_free(snd_mpu401_legacy_cards[idx]);
}
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: mpu401_pnp
2005-02-07 15:54 ` mpu401_pnp Clemens Ladisch
2005-02-07 19:13 ` mpu401_pnp matthieu castet
@ 2005-02-07 19:23 ` matthieu castet
2005-02-09 16:46 ` mpu401_pnp Clemens Ladisch
2005-02-09 14:17 ` mpu401_pnp matthieu castet
2 siblings, 1 reply; 11+ messages in thread
From: matthieu castet @ 2005-02-07 19:23 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel
Hi,
Clemens Ladisch wrote:
> matthieu castet wrote:
>
>>Ok, I found a bug in your patch : when you call pnp_register_driver, you
>>should check that it is >= 0. If not you shouldn't call
>>pnp_unregister_driver.
>
>
> I just copied this from the other ALSA PnP drivers. It seems those
> have all the same bug.
$grep -rI pnp_register_driver /usr/src/linux/sound/
/usr/src/linux/sound/oss/opl3sa2.c:
pnp_register_driver(&opl3sa2_driver);
/usr/src/linux/sound/oss/awe_wave.c: ret =
pnp_register_driver(&awe_pnp_driver);
/usr/src/linux/sound/oss/cs4232.c:
(pnp_register_driver(&cs4232_driver) > 0)
/usr/src/linux/sound/oss/cs4232.c: if
(pnp_register_driver(&cs4232_driver) > 0)
/usr/src/linux/sound/drivers/mpu401/mpu401.c: if ((err =
pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) {
only old oss driver seem to use it, the other alsa driver use
pnp_register_card_driver that seem only provide >= 0 res
Matthieu
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: mpu401_pnp
2005-02-07 19:23 ` mpu401_pnp matthieu castet
@ 2005-02-09 16:46 ` Clemens Ladisch
0 siblings, 0 replies; 11+ messages in thread
From: Clemens Ladisch @ 2005-02-09 16:46 UTC (permalink / raw)
To: matthieu castet; +Cc: alsa-devel
matthieu castet wrote:
> Clemens Ladisch wrote:
> > matthieu castet wrote:
> >
> >>Ok, I found a bug in your patch : when you call pnp_register_driver, you
> >>should check that it is >= 0. If not you shouldn't call
> >>pnp_unregister_driver.
> >
> > I just copied this from the other ALSA PnP drivers. It seems those
> > have all the same bug.
>
> only old oss driver seem to use it, the other alsa driver use
> pnp_register_card_driver that seem only provide >= 0 res
It seems both pnp_register_driver() and pnp_register_card_driver()
can return a negative value (when CONFIG_PNP isn't set). I'll fix it
when I've found out how the 2.2/2.4 wrappers behave.
Best regards,
Clemens
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mpu401_pnp
2005-02-07 15:54 ` mpu401_pnp Clemens Ladisch
2005-02-07 19:13 ` mpu401_pnp matthieu castet
2005-02-07 19:23 ` mpu401_pnp matthieu castet
@ 2005-02-09 14:17 ` matthieu castet
2 siblings, 0 replies; 11+ messages in thread
From: matthieu castet @ 2005-02-09 14:17 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel
Hi,
could you apply my patch in the cvs or if you don't like it, just
correct the bug ?
Thanks,
Matthieu
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: mpu401_pnp
2005-02-07 12:59 ` mpu401_pnp matthieu castet
2005-02-07 15:54 ` mpu401_pnp Clemens Ladisch
@ 2005-02-11 10:00 ` Clemens Ladisch
1 sibling, 0 replies; 11+ messages in thread
From: Clemens Ladisch @ 2005-02-11 10:00 UTC (permalink / raw)
To: matthieu castet; +Cc: alsa-devel
matthieu castet wrote:
> attached a version more readable with less ifdef.
Applied, thanks.
Clemens
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2005-02-11 10:00 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-31 20:50 mpu401_pnp castet.matthieu
2005-02-07 8:46 ` mpu401_pnp Clemens Ladisch
2005-02-07 10:40 ` mpu401_pnp castet.matthieu
2005-02-07 12:10 ` mpu401_pnp matthieu castet
2005-02-07 12:59 ` mpu401_pnp matthieu castet
2005-02-07 15:54 ` mpu401_pnp Clemens Ladisch
2005-02-07 19:13 ` mpu401_pnp matthieu castet
2005-02-07 19:23 ` mpu401_pnp matthieu castet
2005-02-09 16:46 ` mpu401_pnp Clemens Ladisch
2005-02-09 14:17 ` mpu401_pnp matthieu castet
2005-02-11 10:00 ` mpu401_pnp Clemens Ladisch
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.