git: fd6adf784e86 - stable/13 - LinuxKPI: Remove FreeBSD struct resource from all LKPI headers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 13 Oct 2021 09:19:08 UTC
The branch stable/13 has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=fd6adf784e862d043d1858aab323f3fb136cf706 commit fd6adf784e862d043d1858aab323f3fb136cf706 Author: Vladimir Kondratyev <wulf@FreeBSD.org> AuthorDate: 2021-09-29 20:12:36 +0000 Commit: Vladimir Kondratyev <wulf@FreeBSD.org> CommitDate: 2021-10-13 08:58:39 +0000 LinuxKPI: Remove FreeBSD struct resource from all LKPI headers except linux/pci.h to avoid conflicts with Linux version. This allows to #define resource in drm-kmod globally and strip some #ifdef-s Reviewed by: hselasky, manu Differential revision: https://reviews.freebsd.org/D31673 (cherry picked from commit 66ea390652d2ede405b43c168157986bd2b52bb9) --- .../linuxkpi/common/include/linux/interrupt.h | 170 ++------------ sys/compat/linuxkpi/common/src/linux_compat.c | 41 ---- sys/compat/linuxkpi/common/src/linux_interrupt.c | 252 +++++++++++++++++++++ sys/conf/files | 2 + sys/modules/linuxkpi/Makefile | 1 + 5 files changed, 272 insertions(+), 194 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/interrupt.h b/sys/compat/linuxkpi/common/include/linux/interrupt.h index 066157f9b559..4e6c859853a7 100644 --- a/sys/compat/linuxkpi/common/include/linux/interrupt.h +++ b/sys/compat/linuxkpi/common/include/linux/interrupt.h @@ -38,111 +38,31 @@ #include <linux/hardirq.h> #include <sys/param.h> -#include <sys/bus.h> -#include <sys/rman.h> #include <sys/interrupt.h> typedef irqreturn_t (*irq_handler_t)(int, void *); #define IRQF_SHARED RF_SHAREABLE -struct irq_ent { - struct list_head links; - struct device *dev; - struct resource *res; - void *arg; - irqreturn_t (*handler)(int, void *); - void *tag; - unsigned int irq; - - /* XXX All new entries must be after this in stable/13 */ - irqreturn_t (*thread_handler)(int, void *); -}; +struct irq_ent; void linux_irq_handler(void *); void lkpi_devm_irq_release(struct device *, void *); void lkpi_irq_release(struct device *, struct irq_ent *); - -static inline int -linux_irq_rid(struct device *dev, unsigned int irq) -{ - /* check for MSI- or MSIX- interrupt */ - if (irq >= dev->irq_start && irq < dev->irq_end) - return (irq - dev->irq_start + 1); - else - return (0); -} - -static inline struct irq_ent * -linux_irq_ent(struct device *dev, unsigned int irq) -{ - struct irq_ent *irqe; - - list_for_each_entry(irqe, &dev->irqents, links) - if (irqe->irq == irq) - return (irqe); - - return (NULL); -} - -static inline int -_request_irq(struct device *xdev, unsigned int irq, - irq_handler_t handler, irq_handler_t thread_handler, - unsigned long flags, const char *name, void *arg) -{ - struct resource *res; - struct irq_ent *irqe; - struct device *dev; - int error; - int rid; - - dev = linux_pci_find_irq_dev(irq); - if (dev == NULL) - return -ENXIO; - if (xdev != NULL && xdev != dev) - return -ENXIO; - rid = linux_irq_rid(dev, irq); - res = bus_alloc_resource_any(dev->bsddev, SYS_RES_IRQ, &rid, - flags | RF_ACTIVE); - if (res == NULL) - return (-ENXIO); - if (xdev != NULL) - irqe = lkpi_devres_alloc(lkpi_devm_irq_release, sizeof(*irqe), - GFP_KERNEL | __GFP_ZERO); - else - irqe = kzalloc(sizeof(*irqe), GFP_KERNEL); - irqe->dev = dev; - irqe->res = res; - irqe->arg = arg; - irqe->handler = handler; - irqe->thread_handler = thread_handler; - irqe->irq = irq; - - error = bus_setup_intr(dev->bsddev, res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, linux_irq_handler, irqe, &irqe->tag); - if (error) - goto errout; - list_add(&irqe->links, &dev->irqents); - if (xdev != NULL) - devres_add(xdev, irqe); - - return 0; - -errout: - bus_release_resource(dev->bsddev, SYS_RES_IRQ, rid, irqe->res); - if (xdev != NULL) - devres_free(irqe); - else - kfree(irqe); - return (-error); -} +int lkpi_request_irq(struct device *, unsigned int, irq_handler_t, + irq_handler_t, unsigned long, const char *, void *); +int lkpi_enable_irq(unsigned int); +void lkpi_disable_irq(unsigned int); +int lkpi_bind_irq_to_cpu(unsigned int, int); +void lkpi_free_irq(unsigned int, void *); +void lkpi_devm_free_irq(struct device *, unsigned int, void *); static inline int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *arg) { - return (_request_irq(NULL, irq, handler, NULL, flags, name, arg)); + return (lkpi_request_irq(NULL, irq, handler, NULL, flags, name, arg)); } static inline int @@ -151,7 +71,7 @@ request_threaded_irq(int irq, irq_handler_t handler, const char *name, void *arg) { - return (_request_irq(NULL, irq, handler, thread_handler, + return (lkpi_request_irq(NULL, irq, handler, thread_handler, flags, name, arg)); } @@ -161,94 +81,38 @@ devm_request_threaded_irq(struct device *dev, int irq, unsigned long flags, const char *name, void *arg) { - return (_request_irq(dev, irq, handler, thread_handler, + return (lkpi_request_irq(dev, irq, handler, thread_handler, flags, name, arg)); } static inline int enable_irq(unsigned int irq) { - struct irq_ent *irqe; - struct device *dev; - - dev = linux_pci_find_irq_dev(irq); - if (dev == NULL) - return -EINVAL; - irqe = linux_irq_ent(dev, irq); - if (irqe == NULL || irqe->tag != NULL) - return -EINVAL; - return -bus_setup_intr(dev->bsddev, irqe->res, INTR_TYPE_NET | INTR_MPSAFE, - NULL, linux_irq_handler, irqe, &irqe->tag); + return (lkpi_enable_irq(irq)); } static inline void disable_irq(unsigned int irq) { - struct irq_ent *irqe; - struct device *dev; - - dev = linux_pci_find_irq_dev(irq); - if (dev == NULL) - return; - irqe = linux_irq_ent(dev, irq); - if (irqe == NULL) - return; - if (irqe->tag != NULL) - bus_teardown_intr(dev->bsddev, irqe->res, irqe->tag); - irqe->tag = NULL; + lkpi_disable_irq(irq); } static inline int bind_irq_to_cpu(unsigned int irq, int cpu_id) { - struct irq_ent *irqe; - struct device *dev; - - dev = linux_pci_find_irq_dev(irq); - if (dev == NULL) - return (-ENOENT); - - irqe = linux_irq_ent(dev, irq); - if (irqe == NULL) - return (-ENOENT); - - return (-bus_bind_intr(dev->bsddev, irqe->res, cpu_id)); + return (lkpi_bind_irq_to_cpu(irq, cpu_id)); } static inline void -free_irq(unsigned int irq, void *device __unused) +free_irq(unsigned int irq, void *device) { - struct irq_ent *irqe; - struct device *dev; - - dev = linux_pci_find_irq_dev(irq); - if (dev == NULL) - return; - irqe = linux_irq_ent(dev, irq); - if (irqe == NULL) - return; - lkpi_irq_release(dev, irqe); - kfree(irqe); + lkpi_free_irq(irq, device); } static inline void devm_free_irq(struct device *xdev, unsigned int irq, void *p) { - struct device *dev; - struct irq_ent *irqe; - - dev = linux_pci_find_irq_dev(irq); - if (dev == NULL) - return; - if (xdev != dev) - return; - irqe = linux_irq_ent(dev, irq); - if (irqe == NULL) - return; - lkpi_irq_release(dev, irqe); - lkpi_devres_unlink(dev, irqe); - lkpi_devres_free(irqe); - return; + lkpi_devm_free_irq(xdev, irq, p); } static inline int diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index 7315a2671ead..c48d9ac3a281 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -2465,47 +2465,6 @@ list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, free(ar, M_KMALLOC); } -void -lkpi_irq_release(struct device *dev, struct irq_ent *irqe) -{ - - if (irqe->tag != NULL) - bus_teardown_intr(dev->bsddev, irqe->res, irqe->tag); - if (irqe->res != NULL) - bus_release_resource(dev->bsddev, SYS_RES_IRQ, - rman_get_rid(irqe->res), irqe->res); - list_del(&irqe->links); -} - -void -lkpi_devm_irq_release(struct device *dev, void *p) -{ - struct irq_ent *irqe; - - if (dev == NULL || p == NULL) - return; - - irqe = p; - lkpi_irq_release(dev, irqe); -} - -void -linux_irq_handler(void *ent) -{ - struct irq_ent *irqe; - - if (linux_set_current_flags(curthread, M_NOWAIT)) - return; - - irqe = ent; - if (irqe->handler(irqe->irq, irqe->arg) == IRQ_WAKE_THREAD && - irqe->thread_handler != NULL) { - THREAD_SLEEPING_OK(); - irqe->thread_handler(irqe->irq, irqe->arg); - THREAD_NO_SLEEPING(); - } -} - #if defined(__i386__) || defined(__amd64__) int linux_wbinvd_on_all_cpus(void) diff --git a/sys/compat/linuxkpi/common/src/linux_interrupt.c b/sys/compat/linuxkpi/common/src/linux_interrupt.c new file mode 100644 index 000000000000..d8b90094b49b --- /dev/null +++ b/sys/compat/linuxkpi/common/src/linux_interrupt.c @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * Copyright (c) 2013-2015 Mellanox Technologies, Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/pci.h> + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/rman.h> +#include <sys/interrupt.h> + +struct irq_ent { + struct list_head links; + struct device *dev; + struct resource *res; + void *arg; + irqreturn_t (*handler)(int, void *); + void *tag; + unsigned int irq; + + /* XXX All new entries must be after this in stable/13 */ + irqreturn_t (*thread_handler)(int, void *); +}; + +static inline int +lkpi_irq_rid(struct device *dev, unsigned int irq) +{ + /* check for MSI- or MSIX- interrupt */ + if (irq >= dev->irq_start && irq < dev->irq_end) + return (irq - dev->irq_start + 1); + else + return (0); +} + +static inline struct irq_ent * +lkpi_irq_ent(struct device *dev, unsigned int irq) +{ + struct irq_ent *irqe; + + list_for_each_entry(irqe, &dev->irqents, links) + if (irqe->irq == irq) + return (irqe); + + return (NULL); +} + +void +linux_irq_handler(void *ent) +{ + struct irq_ent *irqe; + + if (linux_set_current_flags(curthread, M_NOWAIT)) + return; + + irqe = ent; + if (irqe->handler(irqe->irq, irqe->arg) == IRQ_WAKE_THREAD && + irqe->thread_handler != NULL) { + THREAD_SLEEPING_OK(); + irqe->thread_handler(irqe->irq, irqe->arg); + THREAD_NO_SLEEPING(); + } +} + +void +lkpi_irq_release(struct device *dev, struct irq_ent *irqe) +{ + if (irqe->tag != NULL) + bus_teardown_intr(dev->bsddev, irqe->res, irqe->tag); + if (irqe->res != NULL) + bus_release_resource(dev->bsddev, SYS_RES_IRQ, + rman_get_rid(irqe->res), irqe->res); + list_del(&irqe->links); +} + +void +lkpi_devm_irq_release(struct device *dev, void *p) +{ + struct irq_ent *irqe; + + if (dev == NULL || p == NULL) + return; + + irqe = p; + lkpi_irq_release(dev, irqe); +} + +int +lkpi_request_irq(struct device *xdev, unsigned int irq, + irq_handler_t handler, irq_handler_t thread_handler, + unsigned long flags, const char *name, void *arg) +{ + struct resource *res; + struct irq_ent *irqe; + struct device *dev; + int error; + int rid; + + dev = linux_pci_find_irq_dev(irq); + if (dev == NULL) + return -ENXIO; + if (xdev != NULL && xdev != dev) + return -ENXIO; + rid = lkpi_irq_rid(dev, irq); + res = bus_alloc_resource_any(dev->bsddev, SYS_RES_IRQ, &rid, + flags | RF_ACTIVE); + if (res == NULL) + return (-ENXIO); + if (xdev != NULL) + irqe = lkpi_devres_alloc(lkpi_devm_irq_release, sizeof(*irqe), + GFP_KERNEL | __GFP_ZERO); + else + irqe = kzalloc(sizeof(*irqe), GFP_KERNEL); + irqe->dev = dev; + irqe->res = res; + irqe->arg = arg; + irqe->handler = handler; + irqe->thread_handler = thread_handler; + irqe->irq = irq; + + error = bus_setup_intr(dev->bsddev, res, INTR_TYPE_NET | INTR_MPSAFE, + NULL, linux_irq_handler, irqe, &irqe->tag); + if (error) + goto errout; + list_add(&irqe->links, &dev->irqents); + if (xdev != NULL) + devres_add(xdev, irqe); + + return 0; + +errout: + bus_release_resource(dev->bsddev, SYS_RES_IRQ, rid, irqe->res); + if (xdev != NULL) + devres_free(irqe); + else + kfree(irqe); + return (-error); +} + +int +lkpi_enable_irq(unsigned int irq) +{ + struct irq_ent *irqe; + struct device *dev; + + dev = linux_pci_find_irq_dev(irq); + if (dev == NULL) + return -EINVAL; + irqe = lkpi_irq_ent(dev, irq); + if (irqe == NULL || irqe->tag != NULL) + return -EINVAL; + return -bus_setup_intr(dev->bsddev, irqe->res, INTR_TYPE_NET | INTR_MPSAFE, + NULL, linux_irq_handler, irqe, &irqe->tag); +} + +void +lkpi_disable_irq(unsigned int irq) +{ + struct irq_ent *irqe; + struct device *dev; + + dev = linux_pci_find_irq_dev(irq); + if (dev == NULL) + return; + irqe = lkpi_irq_ent(dev, irq); + if (irqe == NULL) + return; + if (irqe->tag != NULL) + bus_teardown_intr(dev->bsddev, irqe->res, irqe->tag); + irqe->tag = NULL; +} + +int +lkpi_bind_irq_to_cpu(unsigned int irq, int cpu_id) +{ + struct irq_ent *irqe; + struct device *dev; + + dev = linux_pci_find_irq_dev(irq); + if (dev == NULL) + return (-ENOENT); + + irqe = lkpi_irq_ent(dev, irq); + if (irqe == NULL) + return (-ENOENT); + + return (-bus_bind_intr(dev->bsddev, irqe->res, cpu_id)); +} + +void +lkpi_free_irq(unsigned int irq, void *device __unused) +{ + struct irq_ent *irqe; + struct device *dev; + + dev = linux_pci_find_irq_dev(irq); + if (dev == NULL) + return; + irqe = lkpi_irq_ent(dev, irq); + if (irqe == NULL) + return; + lkpi_irq_release(dev, irqe); + kfree(irqe); +} + +void +lkpi_devm_free_irq(struct device *xdev, unsigned int irq, void *p __unused) +{ + struct device *dev; + struct irq_ent *irqe; + + dev = linux_pci_find_irq_dev(irq); + if (dev == NULL) + return; + if (xdev != dev) + return; + irqe = lkpi_irq_ent(dev, irq); + if (irqe == NULL) + return; + lkpi_irq_release(dev, irqe); + lkpi_devres_unlink(dev, irqe); + lkpi_devres_free(irqe); + return; +} diff --git a/sys/conf/files b/sys/conf/files index 69ebfe39340d..40bba75d4fbc 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -4586,6 +4586,8 @@ compat/linuxkpi/common/src/linux_firmware.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_hrtimer.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" +compat/linuxkpi/common/src/linux_interrupt.c optional compat_linuxkpi \ + compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_kthread.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_lock.c optional compat_linuxkpi \ diff --git a/sys/modules/linuxkpi/Makefile b/sys/modules/linuxkpi/Makefile index 81aa607f1302..514428a82509 100644 --- a/sys/modules/linuxkpi/Makefile +++ b/sys/modules/linuxkpi/Makefile @@ -10,6 +10,7 @@ SRCS= linux_compat.c \ linux_firmware.c \ linux_hrtimer.c \ linux_idr.c \ + linux_interrupt.c \ linux_kmod.c \ linux_kthread.c \ linux_lock.c \