PCI Entries

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).

  EXPORT_NO_SYMBOLS;
          

That's all!