uio_ehci_pci.c
1 /* uio_ehci_pci - UIO driver for PCI EHCI devices */ 2 /* This only implements MMIO access (no interrupts). */ 3 /* SPDX-License-Identifier: GPL-2.0-only */ 4 5 #include <linux/device.h> 6 #include <linux/module.h> 7 #include <linux/pci.h> 8 #include <linux/uio_driver.h> 9 10 #define DRIVER_VERSION "0.0.1" 11 #define DRIVER_AUTHOR "Nico Huber <nico.h@gmx.de>" 12 #define DRIVER_DESC "UIO driver for PCI EHCI devices" 13 #define DRIVER_TAG "uio_ehci_pci" 14 15 static int probe(struct pci_dev *const pci_dev, 16 const struct pci_device_id *const did) 17 { 18 struct uio_info *info; 19 int ret; 20 21 ret = pci_enable_device(pci_dev); 22 if (ret) 23 goto return_; 24 25 ret = pci_request_regions(pci_dev, DRIVER_TAG); 26 if (ret) 27 goto return_disable; 28 29 info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); 30 if (!info) { 31 ret = -ENOMEM; 32 goto return_release; 33 } 34 35 info->name = DRIVER_TAG; 36 info->version = DRIVER_VERSION; 37 38 info->mem[0].name = "EHCI MMIO area"; 39 info->mem[0].addr = pci_resource_start(pci_dev, 0); 40 if (!info->mem[0].addr) { 41 ret = -ENODEV; 42 goto return_free; 43 } 44 info->mem[0].size = pci_resource_len(pci_dev, 0); 45 info->mem[0].memtype = UIO_MEM_PHYS; 46 47 ret = uio_register_device(&pci_dev->dev, info); 48 if (ret) 49 goto return_free; 50 pci_set_drvdata(pci_dev, info); 51 52 return 0; 53 return_free: 54 kfree(info); 55 return_release: 56 pci_release_regions(pci_dev); 57 return_disable: 58 pci_disable_device(pci_dev); 59 return_: 60 return ret; 61 } 62 63 static void remove(struct pci_dev *const pci_dev) 64 { 65 struct uio_info *const info = pci_get_drvdata(pci_dev); 66 67 uio_unregister_device(info); 68 kfree(info); 69 pci_release_regions(pci_dev); 70 pci_disable_device(pci_dev); 71 } 72 73 static DEFINE_PCI_DEVICE_TABLE(ehci_pci_ids) = { 74 { PCI_DEVICE(0x8086, 0x27cc) }, 75 { 0, } 76 }; 77 78 static struct pci_driver uio_ehci_pci_driver = { 79 .name = DRIVER_TAG, 80 .id_table = ehci_pci_ids, 81 .probe = probe, 82 .remove = remove, 83 }; 84 85 module_pci_driver(uio_ehci_pci_driver); 86 MODULE_VERSION(DRIVER_VERSION); 87 MODULE_LICENSE("GPL v2"); 88 MODULE_AUTHOR(DRIVER_AUTHOR); 89 MODULE_DESCRIPTION(DRIVER_DESC);