PCI Entries

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!