<?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>Chapter 4. PCI Resource Management</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="index.html" title="Writing an ALSA Driver" /><link rel="prev" href="ch03s04.html" title="Registration and Release" /><link rel="next" href="ch04s02.html" title="Some Hafta's" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 4. PCI Resource Management</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch03s04.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch04s02.html">Next</a></td></tr></table><hr /></div><div class="chapter" title="Chapter 4. PCI Resource Management"><div class="titlepage"><div><div><h2 class="title"><a id="pci-resource"></a>Chapter 4. PCI Resource Management</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="ch04.html#pci-resource-example">Full Code Example</a></span></dt><dt><span class="section"><a href="ch04s02.html">Some Hafta's</a></span></dt><dt><span class="section"><a href="ch04s03.html">Resource Allocation</a></span></dt><dt><span class="section"><a href="ch04s04.html">Registration of Device Struct</a></span></dt><dt><span class="section"><a href="ch04s05.html">PCI Entries</a></span></dt></dl></div><div class="section" title="Full Code Example"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="pci-resource-example"></a>Full Code Example</h2></div></div></div><p> In this section, we'll complete the chip-specific constructor, destructor and PCI entries. Example code is shown first, below. </p><div class="example"><a id="id2945204"></a><p class="title"><b>Example 4.1. PCI Resource Management Example</b></p><div class="example-contents"><pre class="programlisting"> struct mychip { struct snd_card *card; struct pci_dev *pci; unsigned long port; int irq; }; static int snd_mychip_free(struct mychip *chip) { /* disable hardware here if any */ .... /* (not implemented in this document) */ /* release the irq */ if (chip->irq >= 0) free_irq(chip->irq, chip); /* release the I/O ports & memory */ pci_release_regions(chip->pci); /* disable the PCI entry */ pci_disable_device(chip->pci); /* release the data */ kfree(chip); return 0; } /* chip-specific constructor */ 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; /* initialize the PCI entry */ err = pci_enable_device(pci); if (err < 0) return err; /* check PCI availability (28bit DMA) */ if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { printk(KERN_ERR "error to set 28bit mask DMA\n"); pci_disable_device(pci); return -ENXIO; } chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) { pci_disable_device(pci); return -ENOMEM; } /* initialize the stuff */ chip->card = card; chip->pci = pci; chip->irq = -1; /* (1) PCI resource allocation */ err = pci_request_regions(pci, "My Chip"); if (err < 0) { kfree(chip); pci_disable_device(pci); return err; } chip->port = pci_resource_start(pci, 0); if (request_irq(pci->irq, snd_mychip_interrupt, IRQF_SHARED, "My Chip", chip)) { printk(KERN_ERR "cannot grab irq %d\n", pci->irq); snd_mychip_free(chip); return -EBUSY; } chip->irq = pci->irq; /* (2) initialization of the chip hardware */ .... /* (not implemented in this document) */ 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; } /* PCI IDs */ 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); /* pci_driver definition */ static struct pci_driver driver = { .name = "My Own Chip", .id_table = snd_mychip_ids, .probe = snd_mychip_probe, .remove = __devexit_p(snd_mychip_remove), }; /* module initialization */ static int __init alsa_card_mychip_init(void) { return pci_register_driver(&driver); } /* module clean up */ static void __exit alsa_card_mychip_exit(void) { pci_unregister_driver(&driver); } module_init(alsa_card_mychip_init) module_exit(alsa_card_mychip_exit) EXPORT_NO_SYMBOLS; /* for old kernels only */ </pre></div></div><p><br class="example-break" /> </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch03s04.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch04s02.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Registration and Release </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Some Hafta's</td></tr></table></div></body></html>