/ util / uio_usbdebug / linux / uio_ehci_pci.c
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);