^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* uio_pci_generic - generic UIO driver for PCI 2.3 devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2009 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Michael S. Tsirkin <mst@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Since the driver does not declare any device ids, you must allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * id and bind the device to the driver yourself. For example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * # echo "8086 10f5" > /sys/bus/pci/drivers/uio_pci_generic/new_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/uio_pci_generic/bind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * # ls -l /sys/bus/pci/devices/0000:00:19.0/driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * .../0000:00:19.0/driver -> ../../../bus/pci/drivers/uio_pci_generic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Driver won't bind to devices which do not support the Interrupt Disable Bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * in the command register. All devices compliant to PCI 2.3 (circa 2002) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * all compliant PCI Express devices should support this bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/uio_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DRIVER_VERSION "0.01.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define DRIVER_AUTHOR "Michael S. Tsirkin <mst@redhat.com>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DRIVER_DESC "Generic UIO driver for PCI 2.3 devices"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct uio_pci_generic_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct uio_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static inline struct uio_pci_generic_dev *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) to_uio_pci_generic_dev(struct uio_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return container_of(info, struct uio_pci_generic_dev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int release(struct uio_info *info, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * This driver is insecure when used with devices doing DMA, but some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * people (mis)use it with such devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Let's at least make sure DMA isn't left enabled after the userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * driver closes the fd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Note that there's a non-zero chance doing this will wedge the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * at least until reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) pci_clear_master(gdev->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Interrupt handler. Read/modify/write the command register to disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * the interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static irqreturn_t irqhandler(int irq, struct uio_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!pci_check_and_mask_intx(gdev->pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* UIO core will signal the user process. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static int probe(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct uio_pci_generic_dev *gdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) err = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (pdev->irq && !pci_intx_mask_supported(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) goto err_verify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (!gdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) goto err_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) gdev->info.name = "uio_pci_generic";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) gdev->info.version = DRIVER_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) gdev->info.release = release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) gdev->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (pdev->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) gdev->info.irq = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) gdev->info.irq_flags = IRQF_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) gdev->info.handler = irqhandler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dev_warn(&pdev->dev, "No IRQ assigned to device: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "no support for interrupts?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) err = uio_register_device(&pdev->dev, &gdev->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto err_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) pci_set_drvdata(pdev, gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) err_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) kfree(gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) err_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) err_verify:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) uio_unregister_device(&gdev->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) kfree(gdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static struct pci_driver uio_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .name = "uio_pci_generic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .id_table = NULL, /* only dynamic id's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .probe = probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .remove = remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) module_pci_driver(uio_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) MODULE_VERSION(DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) MODULE_DESCRIPTION(DRIVER_DESC);