diff options
Diffstat (limited to 'pci.c')
-rw-r--r-- | pci.c | 38 |
1 files changed, 37 insertions, 1 deletions
@@ -10,16 +10,52 @@ int doom_probe(struct pci_dev *dev, const struct pci_device_id *id) { + struct doom_data *doom_data; int err = 0; + + ORFAIL(pci_enable_device(dev), error_enable); + ORFAIL(pci_request_regions(dev, "harddoom"), error_regions); + + doom_data = kmalloc(sizeof(*doom_data), GFP_KERNEL); + if (doom_data == NULL) { + err = -ENOMEM; + goto error_kmalloc; + } + pci_set_drvdata(dev, doom_data); + doom_data->iomem = pci_iomap(dev, 0, 0); + + pci_set_master(dev); + pci_set_dma_mask(dev, DMA_BIT_MASK(32)); + pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32)); + ORFAIL(new_doomdev(dev), error_doomdev); + return 0; + error_doomdev: + pci_clear_master(dev); + pci_iounmap(dev, doom_data->iomem); + kfree(doom_data); +error_kmalloc: + pci_release_regions(dev); +error_regions: + pci_disable_device(dev); +error_enable: return err; } void doom_remove (struct pci_dev *dev) { - destroy_doomdev(dev); + struct doom_data *doom_data; + + doom_data = pci_get_drvdata(dev); + + destroy_doomdev(doom_data); + pci_clear_master(dev); + pci_iounmap(dev, doom_data->iomem); + kfree(doom_data); + pci_release_regions(dev); + pci_disable_device(dev); } int doom_suspend (struct pci_dev *dev, pm_message_t state) |