cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

comedi_pci.c (6855B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * comedi_pci.c
      4 * Comedi PCI driver specific functions.
      5 *
      6 * COMEDI - Linux Control and Measurement Device Interface
      7 * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
      8 */
      9
     10#include <linux/module.h>
     11#include <linux/interrupt.h>
     12#include <linux/comedi/comedi_pci.h>
     13
     14/**
     15 * comedi_to_pci_dev() - Return PCI device attached to COMEDI device
     16 * @dev: COMEDI device.
     17 *
     18 * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
     19 * a &struct device embedded in a &struct pci_dev.
     20 *
     21 * Return: Attached PCI device if @dev->hw_dev is non-%NULL.
     22 * Return %NULL if @dev->hw_dev is %NULL.
     23 */
     24struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev)
     25{
     26	return dev->hw_dev ? to_pci_dev(dev->hw_dev) : NULL;
     27}
     28EXPORT_SYMBOL_GPL(comedi_to_pci_dev);
     29
     30/**
     31 * comedi_pci_enable() - Enable the PCI device and request the regions
     32 * @dev: COMEDI device.
     33 *
     34 * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
     35 * a &struct device embedded in a &struct pci_dev.  Enable the PCI device
     36 * and request its regions.  Set @dev->ioenabled to %true if successful,
     37 * otherwise undo what was done.
     38 *
     39 * Calls to comedi_pci_enable() and comedi_pci_disable() cannot be nested.
     40 *
     41 * Return:
     42 *	0 on success,
     43 *	-%ENODEV if @dev->hw_dev is %NULL,
     44 *	-%EBUSY if regions busy,
     45 *	or some negative error number if failed to enable PCI device.
     46 *
     47 */
     48int comedi_pci_enable(struct comedi_device *dev)
     49{
     50	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
     51	int rc;
     52
     53	if (!pcidev)
     54		return -ENODEV;
     55
     56	rc = pci_enable_device(pcidev);
     57	if (rc < 0)
     58		return rc;
     59
     60	rc = pci_request_regions(pcidev, dev->board_name);
     61	if (rc < 0)
     62		pci_disable_device(pcidev);
     63	else
     64		dev->ioenabled = true;
     65
     66	return rc;
     67}
     68EXPORT_SYMBOL_GPL(comedi_pci_enable);
     69
     70/**
     71 * comedi_pci_disable() - Release the regions and disable the PCI device
     72 * @dev: COMEDI device.
     73 *
     74 * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
     75 * a &struct device embedded in a &struct pci_dev.  If the earlier call
     76 * to comedi_pci_enable() was successful, release the PCI device's regions
     77 * and disable it.  Reset @dev->ioenabled back to %false.
     78 */
     79void comedi_pci_disable(struct comedi_device *dev)
     80{
     81	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
     82
     83	if (pcidev && dev->ioenabled) {
     84		pci_release_regions(pcidev);
     85		pci_disable_device(pcidev);
     86	}
     87	dev->ioenabled = false;
     88}
     89EXPORT_SYMBOL_GPL(comedi_pci_disable);
     90
     91/**
     92 * comedi_pci_detach() - A generic "detach" handler for PCI COMEDI drivers
     93 * @dev: COMEDI device.
     94 *
     95 * COMEDI drivers for PCI devices that need no special clean-up of private data
     96 * and have no ioremapped regions other than that pointed to by @dev->mmio may
     97 * use this function as its "detach" handler called by the COMEDI core when a
     98 * COMEDI device is being detached from the low-level driver.  It may be also
     99 * called from a more specific "detach" handler that does additional clean-up.
    100 *
    101 * Free the IRQ if @dev->irq is non-zero, iounmap @dev->mmio if it is
    102 * non-%NULL, and call comedi_pci_disable() to release the PCI device's regions
    103 * and disable it.
    104 */
    105void comedi_pci_detach(struct comedi_device *dev)
    106{
    107	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
    108
    109	if (!pcidev || !dev->ioenabled)
    110		return;
    111
    112	if (dev->irq) {
    113		free_irq(dev->irq, dev);
    114		dev->irq = 0;
    115	}
    116	if (dev->mmio) {
    117		iounmap(dev->mmio);
    118		dev->mmio = NULL;
    119	}
    120	comedi_pci_disable(dev);
    121}
    122EXPORT_SYMBOL_GPL(comedi_pci_detach);
    123
    124/**
    125 * comedi_pci_auto_config() - Configure/probe a PCI COMEDI device
    126 * @pcidev: PCI device.
    127 * @driver: Registered COMEDI driver.
    128 * @context: Driver specific data, passed to comedi_auto_config().
    129 *
    130 * Typically called from the pci_driver (*probe) function.  Auto-configure
    131 * a COMEDI device, using the &struct device embedded in *@pcidev as the
    132 * hardware device.  The @context value gets passed through to @driver's
    133 * "auto_attach" handler.  The "auto_attach" handler may call
    134 * comedi_to_pci_dev() on the passed in COMEDI device to recover @pcidev.
    135 *
    136 * Return: The result of calling comedi_auto_config() (0 on success, or
    137 * a negative error number on failure).
    138 */
    139int comedi_pci_auto_config(struct pci_dev *pcidev,
    140			   struct comedi_driver *driver,
    141			   unsigned long context)
    142{
    143	return comedi_auto_config(&pcidev->dev, driver, context);
    144}
    145EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
    146
    147/**
    148 * comedi_pci_auto_unconfig() - Unconfigure/remove a PCI COMEDI device
    149 * @pcidev: PCI device.
    150 *
    151 * Typically called from the pci_driver (*remove) function.  Auto-unconfigure
    152 * a COMEDI device attached to this PCI device, using a pointer to the
    153 * &struct device embedded in *@pcidev as the hardware device.  The COMEDI
    154 * driver's "detach" handler will be called during unconfiguration of the
    155 * COMEDI device.
    156 *
    157 * Note that the COMEDI device may have already been unconfigured using the
    158 * %COMEDI_DEVCONFIG ioctl, in which case this attempt to unconfigure it
    159 * again should be ignored.
    160 */
    161void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
    162{
    163	comedi_auto_unconfig(&pcidev->dev);
    164}
    165EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);
    166
    167/**
    168 * comedi_pci_driver_register() - Register a PCI COMEDI driver
    169 * @comedi_driver: COMEDI driver to be registered.
    170 * @pci_driver: PCI driver to be registered.
    171 *
    172 * This function is called from the module_init() of PCI COMEDI driver modules
    173 * to register the COMEDI driver and the PCI driver.  Do not call it directly,
    174 * use the module_comedi_pci_driver() helper macro instead.
    175 *
    176 * Return: 0 on success, or a negative error number on failure.
    177 */
    178int comedi_pci_driver_register(struct comedi_driver *comedi_driver,
    179			       struct pci_driver *pci_driver)
    180{
    181	int ret;
    182
    183	ret = comedi_driver_register(comedi_driver);
    184	if (ret < 0)
    185		return ret;
    186
    187	ret = pci_register_driver(pci_driver);
    188	if (ret < 0) {
    189		comedi_driver_unregister(comedi_driver);
    190		return ret;
    191	}
    192
    193	return 0;
    194}
    195EXPORT_SYMBOL_GPL(comedi_pci_driver_register);
    196
    197/**
    198 * comedi_pci_driver_unregister() - Unregister a PCI COMEDI driver
    199 * @comedi_driver: COMEDI driver to be unregistered.
    200 * @pci_driver: PCI driver to be unregistered.
    201 *
    202 * This function is called from the module_exit() of PCI COMEDI driver modules
    203 * to unregister the PCI driver and the COMEDI driver.  Do not call it
    204 * directly, use the module_comedi_pci_driver() helper macro instead.
    205 */
    206void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver,
    207				  struct pci_driver *pci_driver)
    208{
    209	pci_unregister_driver(pci_driver);
    210	comedi_driver_unregister(comedi_driver);
    211}
    212EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister);
    213
    214static int __init comedi_pci_init(void)
    215{
    216	return 0;
    217}
    218module_init(comedi_pci_init);
    219
    220static void __exit comedi_pci_exit(void)
    221{
    222}
    223module_exit(comedi_pci_exit);
    224
    225MODULE_AUTHOR("https://www.comedi.org");
    226MODULE_DESCRIPTION("Comedi PCI interface module");
    227MODULE_LICENSE("GPL");