So far, so good. Let's finish the rest of missing PCI
stuffs. 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
pci_device_id struct are the vendor and
device IDs. If you have nothing special to filter the matching
devices, you can use the rest of fields like above. The last
field of pci_device_id struct is a
private data for this entry. You can specify any value here, for
example, to tell the type of different operations per each
device IDs. Such an example is found in 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 are what we already
defined in
the previous sections. The remove should
be defined with
__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 on 2.2 or 2.4 kernels (on 2.6 kernels it's not necessary, though).
That's all!