Rene Herman wrote:
All ALSA ISA card drivers, not just CS4236, use the same interface to
PnP (the pnp_card_driver struct) meaning they would all appear to be
broken in that exact same way as well. Or rather, _any_ ISA-PnP driver
using that pnp_card_driver interface (there's also drivers using the
pnp_driver interface -- those appear to be okay). CS4236 isn't doing
anything special...
If it helps any, I can at least confirm that it's nothing ALSA or CS4236
specific. This is a minimal, skeleton, pnp_card driver:
=== foo.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pnp.h>
MODULE_LICENSE("GPL");
static struct pnp_card_device_id foo_pnp_card_device_id_table[] = {
{ .id = "CSCa836", .devs = { { "CSCa800" } } },
/* --- */
{ .id = "" }
};
MODULE_DEVICE_TABLE(pnp_card, foo_pnp_card_device_id_table);
static int foo_pnp_probe(struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
struct pnp_dev *pdev;
printk(KERN_INFO "%s\n", __FUNCTION__);
pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
if (!pdev || pnp_activate_dev(pdev) < 0)
return -ENODEV;
// allocate, enable.
return 0;
}
static void foo_pnp_remove(struct pnp_card_link *pcard)
{
printk(KERN_INFO "%s\n", __FUNCTION__);
// disable, deallocate.
}
static struct pnp_card_driver foo_pnp_card_driver = {
.name = "foo",
.id_table = foo_pnp_card_device_id_table,
.flags = PNP_DRIVER_RES_DISABLE,
.probe = foo_pnp_probe,
.remove = foo_pnp_remove
};
int __init foo_init(void)
{
return pnp_register_card_driver(&foo_pnp_card_driver);
}
void __exit foo_exit(void)
{
pnp_unregister_card_driver(&foo_pnp_card_driver);
}
module_init(foo_init);
module_exit(foo_exit);
===
compile with
=== Makefile
ifneq ($(KERNELRELEASE),)
obj-m := foo.o
else
default:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd)
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd)
clean
endif
===
This ofcourse needs ISA-PnP support in the kernel, and actually loading
it requires replacing the PnP IDs with IDs actually present (these are
from my CS4236 soundcard).
With 2.6.15.4 and with 2.6.16-rc with Adam's fix applied, an "insmod
foo.ko && rmmod foo" shows the following in dmesg (this needs the PnP
debug messages selectable in menuconfig):
pnp: the driver 'foo' has been registered
foo_pnp_probe
pnp: match found with the PnP device '01:01.00' and the driver 'foo'
pnp: Device 01:01.00 activated.
foo_pnp_remove
pnp: Device 01:01.00 disabled.
pnp: the driver 'foo' has been unregistered
which is as it should be. On 2.6.16-rc without Adam's fix, both the
"pnp: match found with" and the "foo_pnp_remove" lines are missing:
pnp: the driver 'foo' has been registered
foo_pnp_probe
pnp: Device 01:01.00 activated.
pnp: Device 01:01.00 disabled.
pnp: the driver 'foo' has been unregistered
Of course, with this skeleton driver that's not much of a problem, but
in real drivers it certainly is; in pnp_remove you'd deactivate and
deallocate anything that was allocated and activated in/through the
pnp_probe method -- all things associated with this instance of the
card, normally.
I can also confirm that a driver using the "pnp_driver" interface isn't
affected by the bug. Same skeleton-type driver:
=== bar.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pnp.h>
MODULE_LICENSE("GPL");
static struct pnp_device_id bar_pnp_device_id_table[] = {
{ .id = "CSCa800" },
/* --- */
{ .id = "" }
};
MODULE_DEVICE_TABLE(pnp, bar_pnp_device_id_table);
static int bar_pnp_probe(struct pnp_dev *pdev,
const struct pnp_device_id *pid)
{
printk(KERN_INFO "%s\n", __FUNCTION__);
if (pnp_activate_dev(pdev) < 0)
return -ENODEV;
// allocate, enable.
return 0;
}
static void bar_pnp_remove(struct pnp_dev *pdev)
{
printk(KERN_INFO "%s\n", __FUNCTION__);
// disable, deallocate.
}
static struct pnp_driver bar_pnp_driver = {
.name = "bar",
.id_table = bar_pnp_device_id_table,
.flags = PNP_DRIVER_RES_DISABLE,
.probe = bar_pnp_probe,
.remove = bar_pnp_remove
};
int __init bar_init(void)
{
return pnp_register_driver(&bar_pnp_driver);
}
void __exit bar_exit(void)
{
pnp_unregister_driver(&bar_pnp_driver);
}
module_init(bar_init);
module_exit(bar_exit);
===
2.6.15.4, 2.6.16-rc with or without Adam's fix:
pnp: the driver 'bar' has been registered
pnp: match found with the PnP device '01:01.00' and the driver 'bar'
bar_pnp_probe
pnp: Device 01:01.00 activated.
bar_pnp_remove
pnp: Device 01:01.00 disabled.
pnp: the driver 'bar' has been unregistered
So that's all fine. As said though, all ALSA drivers for one are using
the card_driver interface, and are therefore all broken currently.
Rene.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]