<?xml version="1.0" encoding="ANSI_X3.4-1968" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968" /><title>Full Code Example</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><link rel="home" href="index.html" title="Writing an ALSA Driver" /><link rel="up" href="ch02.html" title="Chapter 2. Basic Flow for PCI Drivers" /><link rel="prev" href="ch02.html" title="Chapter 2. Basic Flow for PCI Drivers" /><link rel="next" href="ch02s03.html" title="Constructor" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Full Code Example</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch02.html">Prev</a> </td><th width="60%" align="center">Chapter 2. Basic Flow for PCI Drivers</th><td width="20%" align="right"> <a accesskey="n" href="ch02s03.html">Next</a></td></tr></table><hr /></div><div class="section" title="Full Code Example"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="basic-flow-example"></a>Full Code Example</h2></div></div></div><p> The code example is shown below. Some parts are kept unimplemented at this moment but will be filled in the next sections. The numbers in the comment lines of the <code class="function">snd_mychip_probe()</code> function refer to details explained in the following section. </p><div class="example"><a id="id2896240"></a><p class="title"><b>Example 2.1. Basic Flow for PCI Drivers - Example</b></p><div class="example-contents"><pre class="programlisting"> #include <linux/init.h> #include <linux/pci.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> /* module parameters (see "Module Parameters") */ /* SNDRV_CARDS: maximum number of cards supported by this module */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* definition of the chip-specific record */ struct mychip { struct snd_card *card; /* the rest of the implementation will be in section * "PCI Resource Management" */ }; /* chip-specific destructor * (see "PCI Resource Management") */ static int snd_mychip_free(struct mychip *chip) { .... /* will be implemented later... */ } /* component-destructor * (see "Management of Cards and Components") */ static int snd_mychip_dev_free(struct snd_device *device) { return snd_mychip_free(device->device_data); } /* chip-specific constructor * (see "Management of Cards and Components") */ static int __devinit snd_mychip_create(struct snd_card *card, struct pci_dev *pci, struct mychip **rchip) { struct mychip *chip; int err; static struct snd_device_ops ops = { .dev_free = snd_mychip_dev_free, }; *rchip = NULL; /* check PCI availability here * (see "PCI Resource Management") */ .... /* allocate a chip-specific data with zero filled */ chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->card = card; /* rest of initialization here; will be implemented * later, see "PCI Resource Management" */ .... err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { snd_mychip_free(chip); return err; } snd_card_set_dev(card, &pci->dev); *rchip = chip; return 0; } /* constructor -- see "Constructor" sub-section */ static int __devinit snd_mychip_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; struct snd_card *card; struct mychip *chip; int err; /* (1) */ if (dev >= SNDRV_CARDS) return -ENODEV; if (!enable[dev]) { dev++; return -ENOENT; } /* (2) */ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); if (err < 0) return err; /* (3) */ err = snd_mychip_create(card, pci, &chip); if (err < 0) { snd_card_free(card); return err; } /* (4) */ strcpy(card->driver, "My Chip"); strcpy(card->shortname, "My Own Chip 123"); sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->ioport, chip->irq); /* (5) */ .... /* implemented later */ /* (6) */ err = snd_card_register(card); if (err < 0) { snd_card_free(card); return err; } /* (7) */ pci_set_drvdata(pci, card); dev++; return 0; } /* destructor -- see the "Destructor" sub-section */ static void __devexit snd_mychip_remove(struct pci_dev *pci) { snd_card_free(pci_get_drvdata(pci)); pci_set_drvdata(pci, NULL); } </pre></div></div><p><br class="example-break" /> </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch02.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch02s03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. Basic Flow for PCI Drivers </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Constructor</td></tr></table></div></body></html>