So far, so good. Let's finish the missing PCI stuff. At first, we need a pci_device_id table for this chipset. It's a table of PCI vendor/device ID number, and some masks.
For example,
static struct pci_device_id snd_mychip_ids[] = { { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, .... { 0, } }; MODULE_DEVICE_TABLE(pci, snd_mychip_ids);
The first and second fields of the pci_device_id structure are the vendor and device IDs. If you have no reason to filter the matching devices, you can leave the remaining fields as above. The last field of the pci_device_id struct contains private data for this entry. You can specify any value here, for example, to define specific operations for supported device IDs. Such an example is found in the intel8x0 driver.
The last entry of this list is the terminator. You must specify this all-zero entry.
Then, prepare the pci_driver record:
static struct pci_driver driver = { .name = "My Own Chip", .id_table = snd_mychip_ids, .probe = snd_mychip_probe, .remove = __devexit_p(snd_mychip_remove), };
The probe
and
remove
functions have already
been defined in the previous sections.
The remove
function should
be defined with the
__devexit_p()
macro, so that it's not
defined for built-in (and non-hot-pluggable) case. The
name
field is the name string of this device. Note that you must not
use a slash “/” in this string.
And at last, the module entries:
static int __init alsa_card_mychip_init(void) { return pci_register_driver(&driver); } static void __exit alsa_card_mychip_exit(void) { pci_unregister_driver(&driver); } module_init(alsa_card_mychip_init) module_exit(alsa_card_mychip_exit)
Note that these module entries are tagged with
__init
and
__exit
prefixes, not
__devinit
nor
__devexit
.
Oh, one thing was forgotten. If you have no exported symbols, you need to declare it in 2.2 or 2.4 kernels (it's not necessary in 2.6 kernels).
EXPORT_NO_SYMBOLS;
That's all!