Index: sys/compat/linuxkpi/common/include/linux/interrupt.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/interrupt.h +++ sys/compat/linuxkpi/common/include/linux/interrupt.h @@ -38,109 +38,31 @@ #include #include -#include -#include #include 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 *); - irqreturn_t (*thread_handler)(int, void *); - void *tag; - unsigned int irq; -}; +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 @@ -149,7 +71,7 @@ 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)); } @@ -159,94 +81,38 @@ 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) { - 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 Index: sys/compat/linuxkpi/common/src/linux_compat.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_compat.c +++ sys/compat/linuxkpi/common/src/linux_compat.c @@ -2464,47 +2464,6 @@ 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) Index: sys/compat/linuxkpi/common/src/linux_interrupt.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_interrupt.c +++ sys/compat/linuxkpi/common/src/linux_interrupt.c @@ -28,23 +28,17 @@ * * $FreeBSD$ */ -#ifndef _LINUX_INTERRUPT_H_ -#define _LINUX_INTERRUPT_H_ -#include #include +#include #include -#include -#include #include #include #include #include -typedef irqreturn_t (*irq_handler_t)(int, void *); - -#define IRQF_SHARED RF_SHAREABLE +#undef resource struct irq_ent { struct list_head links; @@ -57,12 +51,8 @@ unsigned int irq; }; -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) +lkpi_irq_rid(struct device *dev, unsigned int irq) { /* check for MSI- or MSIX- interrupt */ if (irq >= dev->irq_start && irq < dev->irq_end) @@ -72,7 +62,7 @@ } static inline struct irq_ent * -linux_irq_ent(struct device *dev, unsigned int irq) +lkpi_irq_ent(struct device *dev, unsigned int irq) { struct irq_ent *irqe; @@ -83,8 +73,48 @@ return (NULL); } -static inline int -_request_irq(struct device *xdev, unsigned int irq, +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) { @@ -99,7 +129,7 @@ return -ENXIO; if (xdev != NULL && xdev != dev) return -ENXIO; - rid = linux_irq_rid(dev, irq); + rid = lkpi_irq_rid(dev, irq); res = bus_alloc_resource_any(dev->bsddev, SYS_RES_IRQ, &rid, flags | RF_ACTIVE); if (res == NULL) @@ -135,36 +165,8 @@ return (-error); } -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)); -} - -static inline int -request_threaded_irq(int irq, irq_handler_t handler, - irq_handler_t thread_handler, unsigned long flags, - const char *name, void *arg) -{ - - return (_request_irq(NULL, irq, handler, thread_handler, - flags, name, arg)); -} - -static inline int -devm_request_threaded_irq(struct device *dev, int irq, - irq_handler_t handler, irq_handler_t thread_handler, - unsigned long flags, const char *name, void *arg) -{ - - return (_request_irq(dev, irq, handler, thread_handler, - flags, name, arg)); -} - -static inline int -enable_irq(unsigned int irq) +int +lkpi_enable_irq(unsigned int irq) { struct irq_ent *irqe; struct device *dev; @@ -172,15 +174,15 @@ dev = linux_pci_find_irq_dev(irq); if (dev == NULL) return -EINVAL; - irqe = linux_irq_ent(dev, irq); + 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); } -static inline void -disable_irq(unsigned int irq) +void +lkpi_disable_irq(unsigned int irq) { struct irq_ent *irqe; struct device *dev; @@ -188,7 +190,7 @@ dev = linux_pci_find_irq_dev(irq); if (dev == NULL) return; - irqe = linux_irq_ent(dev, irq); + irqe = lkpi_irq_ent(dev, irq); if (irqe == NULL) return; if (irqe->tag != NULL) @@ -196,8 +198,8 @@ irqe->tag = NULL; } -static inline int -bind_irq_to_cpu(unsigned int irq, int cpu_id) +int +lkpi_bind_irq_to_cpu(unsigned int irq, int cpu_id) { struct irq_ent *irqe; struct device *dev; @@ -206,15 +208,15 @@ if (dev == NULL) return (-ENOENT); - irqe = linux_irq_ent(dev, irq); + irqe = lkpi_irq_ent(dev, irq); if (irqe == NULL) return (-ENOENT); return (-bus_bind_intr(dev->bsddev, irqe->res, cpu_id)); } -static inline void -free_irq(unsigned int irq, void *device __unused) +void +lkpi_free_irq(unsigned int irq, void *device __unused) { struct irq_ent *irqe; struct device *dev; @@ -222,15 +224,15 @@ dev = linux_pci_find_irq_dev(irq); if (dev == NULL) return; - irqe = linux_irq_ent(dev, irq); + irqe = lkpi_irq_ent(dev, irq); if (irqe == NULL) return; lkpi_irq_release(dev, irqe); kfree(irqe); } -static inline void -devm_free_irq(struct device *xdev, unsigned int irq, void *p) +void +lkpi_devm_free_irq(struct device *xdev, unsigned int irq, void *p) { struct device *dev; struct irq_ent *irqe; @@ -240,7 +242,7 @@ return; if (xdev != dev) return; - irqe = linux_irq_ent(dev, irq); + irqe = lkpi_irq_ent(dev, irq); if (irqe == NULL) return; lkpi_irq_release(dev, irqe); @@ -249,47 +251,3 @@ return; } -static inline int -irq_set_affinity_hint(int vector, cpumask_t *mask) -{ - int error; - - if (mask != NULL) - error = intr_setaffinity(vector, CPU_WHICH_IRQ, mask); - else - error = intr_setaffinity(vector, CPU_WHICH_IRQ, cpuset_root); - - return (-error); -} - -/* - * LinuxKPI tasklet support - */ -typedef void tasklet_func_t(unsigned long); - -struct tasklet_struct { - TAILQ_ENTRY(tasklet_struct) entry; - tasklet_func_t *func; - /* Our "state" implementation is different. Avoid same name as Linux. */ - volatile u_int tasklet_state; - atomic_t count; - unsigned long data; -}; - -#define DECLARE_TASKLET(_name, _func, _data) \ -struct tasklet_struct _name = { .func = (_func), .data = (_data) } - -#define tasklet_hi_schedule(t) tasklet_schedule(t) - -extern void tasklet_schedule(struct tasklet_struct *); -extern void tasklet_kill(struct tasklet_struct *); -extern void tasklet_init(struct tasklet_struct *, tasklet_func_t *, - unsigned long data); -extern void tasklet_enable(struct tasklet_struct *); -extern void tasklet_disable(struct tasklet_struct *); -extern void tasklet_disable_nosync(struct tasklet_struct *); -extern int tasklet_trylock(struct tasklet_struct *); -extern void tasklet_unlock(struct tasklet_struct *); -extern void tasklet_unlock_wait(struct tasklet_struct *ts); - -#endif /* _LINUX_INTERRUPT_H_ */ Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -4584,6 +4584,8 @@ 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 \ Index: sys/modules/linuxkpi/Makefile =================================================================== --- sys/modules/linuxkpi/Makefile +++ sys/modules/linuxkpi/Makefile @@ -11,6 +11,7 @@ linux_fpu.c \ linux_hrtimer.c \ linux_idr.c \ + linux_interrupt.c \ linux_kmod.c \ linux_kthread.c \ linux_lock.c \