FreeBSD Bugzilla – Attachment 219983 Details for
Bug 251390
new kernel module for GPIO input interrupt to kevent
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
simple kernel module for catching Interrupts and forward to a kevent
gpioiitk.patch (text/plain), 88.61 KB, created by
Oskar Holmlund
on 2020-11-26 01:58:47 UTC
(
hide
)
Description:
simple kernel module for catching Interrupts and forward to a kevent
Filename:
MIME Type:
Creator:
Oskar Holmlund
Created:
2020-11-26 01:58:47 UTC
Size:
88.61 KB
patch
obsolete
>diff -ruN drvGPIOIITK.orig/BB-GPIOIITK.dts drvGPIOIITK/BB-GPIOIITK.dts >--- drvGPIOIITK.orig/BB-GPIOIITK.dts 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/BB-GPIOIITK.dts 2020-11-26 04:44:40.316988000 +0100 >@@ -0,0 +1,43 @@ >+/dts-v1/; >+/plugin/; >+ >+#include <dt-bindings/gpio/gpio.h> >+#include <dt-bindings/pinctrl/am33xx.h> >+#include <dt-bindings/board/am335x-bbw-bbb-base.h> >+ >+/ { >+ compatible = "ti,am335x-bone-black"; >+ >+ /* identification */ >+ part-number = "BB-GPIOIITK"; >+ version = "00A0"; >+ >+ fragment@0 { >+ target = <&am33xx_pinmux>; >+ __overlay__ { >+ input_pins: pinmux-input-pins { >+ pinctrl-single,pins = < >+ /* P8_08 (T7) gpio2_3 */ >+ AM33XX_IOPAD(0x0894, PIN_INPUT | MUX_MODE7) >+ >+ /* P8_10 (U6) gpio2_4 */ >+ AM33XX_IOPAD(0x0898, PIN_INPUT | MUX_MODE7) >+ >; >+ }; >+ }; >+ }; >+ >+ fragment@1 { >+ target-path="/"; >+ __overlay__ { >+ gpio_int_test { >+ pinctrl-names = "default"; >+ pinctrl-0 = <&input_pins>; >+ compatible = "gpioiitk"; >+ >+ input-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>, >+ <&gpio2 4 GPIO_ACTIVE_HIGH>; >+ }; >+ }; >+ }; >+}; >diff -ruN drvGPIOIITK.orig/Makefile drvGPIOIITK/Makefile >--- drvGPIOIITK.orig/Makefile 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/Makefile 2020-11-26 04:44:40.316685000 +0100 >@@ -0,0 +1,4 @@ >+KMOD= gpioiitk >+SRCS= gpioiitk.c >+ >+.include <bsd.kmod.mk> >diff -ruN drvGPIOIITK.orig/bus_if.h drvGPIOIITK/bus_if.h >--- drvGPIOIITK.orig/bus_if.h 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/bus_if.h 2020-11-26 04:44:40.316737000 +0100 >@@ -0,0 +1,1255 @@ >+/* >+ * This file is @generated automatically. >+ * Do not modify anything in here by hand. >+ * >+ * Created from source file >+ * /usr/src/sys/kern/bus_if.m >+ * with >+ * makeobjops.awk >+ * >+ * See the source file for legal information >+ */ >+ >+/** >+ * @defgroup BUS bus - KObj methods for drivers of devices with children >+ * @brief A set of methods required device drivers that support >+ * child devices. >+ * @{ >+ */ >+ >+#ifndef _bus_if_h_ >+#define _bus_if_h_ >+ >+/** @brief Unique descriptor for the BUS_PRINT_CHILD() method */ >+extern struct kobjop_desc bus_print_child_desc; >+/** @brief A function implementing the BUS_PRINT_CHILD() method */ >+typedef int bus_print_child_t(device_t _dev, device_t _child); >+/** >+ * @brief Print a description of a child device >+ * >+ * This is called from system code which prints out a description of a >+ * device. It should describe the attachment that the child has with >+ * the parent. For instance the TurboLaser bus prints which node the >+ * device is attached to. See bus_generic_print_child() for more >+ * information. >+ * >+ * @param _dev the device whose child is being printed >+ * @param _child the child device to describe >+ * >+ * @returns the number of characters output. >+ */ >+ >+static __inline int BUS_PRINT_CHILD(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_print_child); >+ rc = ((bus_print_child_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_PROBE_NOMATCH() method */ >+extern struct kobjop_desc bus_probe_nomatch_desc; >+/** @brief A function implementing the BUS_PROBE_NOMATCH() method */ >+typedef void bus_probe_nomatch_t(device_t _dev, device_t _child); >+/** >+ * @brief Print a notification about an unprobed child device. >+ * >+ * Called for each child device that did not succeed in probing for a >+ * driver. >+ * >+ * @param _dev the device whose child was being probed >+ * @param _child the child device which failed to probe >+ */ >+ >+static __inline void BUS_PROBE_NOMATCH(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_probe_nomatch); >+ ((bus_probe_nomatch_t *) _m)(_dev, _child); >+} >+ >+/** @brief Unique descriptor for the BUS_READ_IVAR() method */ >+extern struct kobjop_desc bus_read_ivar_desc; >+/** @brief A function implementing the BUS_READ_IVAR() method */ >+typedef int bus_read_ivar_t(device_t _dev, device_t _child, int _index, >+ uintptr_t *_result); >+/** >+ * @brief Read the value of a bus-specific attribute of a device >+ * >+ * This method, along with BUS_WRITE_IVAR() manages a bus-specific set >+ * of instance variables of a child device. The intention is that >+ * each different type of bus defines a set of appropriate instance >+ * variables (such as ports and irqs for ISA bus etc.) >+ * >+ * This information could be given to the child device as a struct but >+ * that makes it hard for a bus to add or remove variables without >+ * forcing an edit and recompile for all drivers which may not be >+ * possible for vendor supplied binary drivers. >+ * >+ * This method copies the value of an instance variable to the >+ * location specified by @p *_result. >+ * >+ * @param _dev the device whose child was being examined >+ * @param _child the child device whose instance variable is >+ * being read >+ * @param _index the instance variable to read >+ * @param _result a location to receive the instance variable >+ * value >+ * >+ * @retval 0 success >+ * @retval ENOENT no such instance variable is supported by @p >+ * _dev >+ */ >+ >+static __inline int BUS_READ_IVAR(device_t _dev, device_t _child, int _index, >+ uintptr_t *_result) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_read_ivar); >+ rc = ((bus_read_ivar_t *) _m)(_dev, _child, _index, _result); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_WRITE_IVAR() method */ >+extern struct kobjop_desc bus_write_ivar_desc; >+/** @brief A function implementing the BUS_WRITE_IVAR() method */ >+typedef int bus_write_ivar_t(device_t _dev, device_t _child, int _indx, >+ uintptr_t _value); >+/** >+ * @brief Write the value of a bus-specific attribute of a device >+ * >+ * This method sets the value of an instance variable to @p _value. >+ * >+ * @param _dev the device whose child was being updated >+ * @param _child the child device whose instance variable is >+ * being written >+ * @param _index the instance variable to write >+ * @param _value the value to write to that instance variable >+ * >+ * @retval 0 success >+ * @retval ENOENT no such instance variable is supported by @p >+ * _dev >+ * @retval EINVAL the instance variable was recognised but >+ * contains a read-only value >+ */ >+ >+static __inline int BUS_WRITE_IVAR(device_t _dev, device_t _child, int _indx, >+ uintptr_t _value) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_write_ivar); >+ rc = ((bus_write_ivar_t *) _m)(_dev, _child, _indx, _value); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_CHILD_DELETED() method */ >+extern struct kobjop_desc bus_child_deleted_desc; >+/** @brief A function implementing the BUS_CHILD_DELETED() method */ >+typedef void bus_child_deleted_t(device_t _dev, device_t _child); >+/** >+ * @brief Notify a bus that a child was deleted >+ * >+ * Called at the beginning of device_delete_child() to allow the parent >+ * to teardown any bus-specific state for the child. >+ * >+ * @param _dev the device whose child is being deleted >+ * @param _child the child device which is being deleted >+ */ >+ >+static __inline void BUS_CHILD_DELETED(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_deleted); >+ ((bus_child_deleted_t *) _m)(_dev, _child); >+} >+ >+/** @brief Unique descriptor for the BUS_CHILD_DETACHED() method */ >+extern struct kobjop_desc bus_child_detached_desc; >+/** @brief A function implementing the BUS_CHILD_DETACHED() method */ >+typedef void bus_child_detached_t(device_t _dev, device_t _child); >+/** >+ * @brief Notify a bus that a child was detached >+ * >+ * Called after the child's DEVICE_DETACH() method to allow the parent >+ * to reclaim any resources allocated on behalf of the child. >+ * >+ * @param _dev the device whose child changed state >+ * @param _child the child device which changed state >+ */ >+ >+static __inline void BUS_CHILD_DETACHED(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_detached); >+ ((bus_child_detached_t *) _m)(_dev, _child); >+} >+ >+/** @brief Unique descriptor for the BUS_DRIVER_ADDED() method */ >+extern struct kobjop_desc bus_driver_added_desc; >+/** @brief A function implementing the BUS_DRIVER_ADDED() method */ >+typedef void bus_driver_added_t(device_t _dev, driver_t *_driver); >+/** >+ * @brief Notify a bus that a new driver was added >+ * >+ * Called when a new driver is added to the devclass which owns this >+ * bus. The generic implementation of this method attempts to probe and >+ * attach any un-matched children of the bus. >+ * >+ * @param _dev the device whose devclass had a new driver >+ * added to it >+ * @param _driver the new driver which was added >+ */ >+ >+static __inline void BUS_DRIVER_ADDED(device_t _dev, driver_t *_driver) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_driver_added); >+ ((bus_driver_added_t *) _m)(_dev, _driver); >+} >+ >+/** @brief Unique descriptor for the BUS_ADD_CHILD() method */ >+extern struct kobjop_desc bus_add_child_desc; >+/** @brief A function implementing the BUS_ADD_CHILD() method */ >+typedef device_t bus_add_child_t(device_t _dev, u_int _order, const char *_name, >+ int _unit); >+/** >+ * @brief Create a new child device >+ * >+ * For buses which use use drivers supporting DEVICE_IDENTIFY() to >+ * enumerate their devices, this method is used to create new >+ * device instances. The new device will be added after the last >+ * existing child with the same order. Implementations of bus_add_child >+ * call device_add_child_ordered to add the child and often add >+ * a suitable ivar to the device specific to that bus. >+ * >+ * @param _dev the bus device which will be the parent of the >+ * new child device >+ * @param _order a value which is used to partially sort the >+ * children of @p _dev - devices created using >+ * lower values of @p _order appear first in @p >+ * _dev's list of children >+ * @param _name devclass name for new device or @c NULL if not >+ * specified >+ * @param _unit unit number for new device or @c -1 if not >+ * specified >+ */ >+ >+static __inline device_t BUS_ADD_CHILD(device_t _dev, u_int _order, >+ const char *_name, int _unit) >+{ >+ kobjop_t _m; >+ device_t rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_add_child); >+ rc = ((bus_add_child_t *) _m)(_dev, _order, _name, _unit); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_RESCAN() method */ >+extern struct kobjop_desc bus_rescan_desc; >+/** @brief A function implementing the BUS_RESCAN() method */ >+typedef int bus_rescan_t(device_t _dev); >+/** >+ * @brief Rescan the bus >+ * >+ * This method is called by a parent bridge or devctl to trigger a bus >+ * rescan. The rescan should delete devices no longer present and >+ * enumerate devices that have newly arrived. >+ * >+ * @param _dev the bus device >+ */ >+ >+static __inline int BUS_RESCAN(device_t _dev) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_rescan); >+ rc = ((bus_rescan_t *) _m)(_dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_ALLOC_RESOURCE() method */ >+extern struct kobjop_desc bus_alloc_resource_desc; >+/** @brief A function implementing the BUS_ALLOC_RESOURCE() method */ >+typedef struct resource * bus_alloc_resource_t(device_t _dev, device_t _child, >+ int _type, int *_rid, >+ rman_res_t _start, >+ rman_res_t _end, >+ rman_res_t _count, u_int _flags); >+/** >+ * @brief Allocate a system resource >+ * >+ * This method is called by child devices of a bus to allocate resources. >+ * The types are defined in <machine/resource.h>; the meaning of the >+ * resource-ID field varies from bus to bus (but @p *rid == 0 is always >+ * valid if the resource type is). If a resource was allocated and the >+ * caller did not use the RF_ACTIVE to specify that it should be >+ * activated immediately, the caller is responsible for calling >+ * BUS_ACTIVATE_RESOURCE() when it actually uses the resource. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which is requesting an allocation >+ * @param _type the type of resource to allocate >+ * @param _rid a pointer to the resource identifier >+ * @param _start hint at the start of the resource range - pass >+ * @c 0 for any start address >+ * @param _end hint at the end of the resource range - pass >+ * @c ~0 for any end address >+ * @param _count hint at the size of range required - pass @c 1 >+ * for any size >+ * @param _flags any extra flags to control the resource >+ * allocation - see @c RF_XXX flags in >+ * <sys/rman.h> for details >+ * >+ * @returns the resource which was allocated or @c NULL if no >+ * resource could be allocated >+ */ >+ >+static __inline struct resource * BUS_ALLOC_RESOURCE(device_t _dev, >+ device_t _child, int _type, >+ int *_rid, >+ rman_res_t _start, >+ rman_res_t _end, >+ rman_res_t _count, >+ u_int _flags) >+{ >+ kobjop_t _m; >+ struct resource * rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_alloc_resource); >+ rc = ((bus_alloc_resource_t *) _m)(_dev, _child, _type, _rid, _start, _end, _count, _flags); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_ACTIVATE_RESOURCE() method */ >+extern struct kobjop_desc bus_activate_resource_desc; >+/** @brief A function implementing the BUS_ACTIVATE_RESOURCE() method */ >+typedef int bus_activate_resource_t(device_t _dev, device_t _child, int _type, >+ int _rid, struct resource *_r); >+/** >+ * @brief Activate a resource >+ * >+ * Activate a resource previously allocated with >+ * BUS_ALLOC_RESOURCE(). This may enable decoding of this resource in a >+ * device for instance. It will also establish a mapping for the resource >+ * unless RF_UNMAPPED was set when allocating the resource. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _type the type of resource >+ * @param _rid the resource identifier >+ * @param _r the resource to activate >+ */ >+ >+static __inline int BUS_ACTIVATE_RESOURCE(device_t _dev, device_t _child, >+ int _type, int _rid, >+ struct resource *_r) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_activate_resource); >+ rc = ((bus_activate_resource_t *) _m)(_dev, _child, _type, _rid, _r); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_MAP_RESOURCE() method */ >+extern struct kobjop_desc bus_map_resource_desc; >+/** @brief A function implementing the BUS_MAP_RESOURCE() method */ >+typedef int bus_map_resource_t(device_t _dev, device_t _child, int _type, >+ struct resource *_r, >+ struct resource_map_request *_args, >+ struct resource_map *_map); >+/** >+ * @brief Map a resource >+ * >+ * Allocate a mapping for a range of an active resource. The mapping >+ * is described by a struct resource_map object. This may for instance >+ * map a memory region into the kernel's virtual address space. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _type the type of resource >+ * @param _r the resource to map >+ * @param _args optional attributes of the mapping >+ * @param _map the mapping >+ */ >+ >+static __inline int BUS_MAP_RESOURCE(device_t _dev, device_t _child, int _type, >+ struct resource *_r, >+ struct resource_map_request *_args, >+ struct resource_map *_map) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_map_resource); >+ rc = ((bus_map_resource_t *) _m)(_dev, _child, _type, _r, _args, _map); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_UNMAP_RESOURCE() method */ >+extern struct kobjop_desc bus_unmap_resource_desc; >+/** @brief A function implementing the BUS_UNMAP_RESOURCE() method */ >+typedef int bus_unmap_resource_t(device_t _dev, device_t _child, int _type, >+ struct resource *_r, >+ struct resource_map *_map); >+/** >+ * @brief Unmap a resource >+ * >+ * Release a mapping previously allocated with >+ * BUS_MAP_RESOURCE(). This may for instance unmap a memory region >+ * from the kernel's virtual address space. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _type the type of resource >+ * @param _r the resource >+ * @param _map the mapping to release >+ */ >+ >+static __inline int BUS_UNMAP_RESOURCE(device_t _dev, device_t _child, >+ int _type, struct resource *_r, >+ struct resource_map *_map) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_unmap_resource); >+ rc = ((bus_unmap_resource_t *) _m)(_dev, _child, _type, _r, _map); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_DEACTIVATE_RESOURCE() method */ >+extern struct kobjop_desc bus_deactivate_resource_desc; >+/** @brief A function implementing the BUS_DEACTIVATE_RESOURCE() method */ >+typedef int bus_deactivate_resource_t(device_t _dev, device_t _child, int _type, >+ int _rid, struct resource *_r); >+/** >+ * @brief Deactivate a resource >+ * >+ * Deactivate a resource previously allocated with >+ * BUS_ALLOC_RESOURCE(). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _type the type of resource >+ * @param _rid the resource identifier >+ * @param _r the resource to deactivate >+ */ >+ >+static __inline int BUS_DEACTIVATE_RESOURCE(device_t _dev, device_t _child, >+ int _type, int _rid, >+ struct resource *_r) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_deactivate_resource); >+ rc = ((bus_deactivate_resource_t *) _m)(_dev, _child, _type, _rid, _r); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_ADJUST_RESOURCE() method */ >+extern struct kobjop_desc bus_adjust_resource_desc; >+/** @brief A function implementing the BUS_ADJUST_RESOURCE() method */ >+typedef int bus_adjust_resource_t(device_t _dev, device_t _child, int _type, >+ struct resource *_res, rman_res_t _start, >+ rman_res_t _end); >+/** >+ * @brief Adjust a resource >+ * >+ * Adjust the start and/or end of a resource allocated by >+ * BUS_ALLOC_RESOURCE. At least part of the new address range must overlap >+ * with the existing address range. If the successful, the resource's range >+ * will be adjusted to [start, end] on return. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _type the type of resource >+ * @param _res the resource to adjust >+ * @param _start the new starting address of the resource range >+ * @param _end the new ending address of the resource range >+ */ >+ >+static __inline int BUS_ADJUST_RESOURCE(device_t _dev, device_t _child, >+ int _type, struct resource *_res, >+ rman_res_t _start, rman_res_t _end) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_adjust_resource); >+ rc = ((bus_adjust_resource_t *) _m)(_dev, _child, _type, _res, _start, _end); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_TRANSLATE_RESOURCE() method */ >+extern struct kobjop_desc bus_translate_resource_desc; >+/** @brief A function implementing the BUS_TRANSLATE_RESOURCE() method */ >+typedef int bus_translate_resource_t(device_t _dev, int _type, >+ rman_res_t _start, rman_res_t *_newstart); >+/** >+ * @brief translate a resource value >+ * >+ * >+ * @param _dev the device associated with the resource >+ * @param _type the type of resource >+ * @param _start the starting address of the resource range >+ * @param _newstart the new starting address of the resource range >+ */ >+ >+static __inline int BUS_TRANSLATE_RESOURCE(device_t _dev, int _type, >+ rman_res_t _start, >+ rman_res_t *_newstart) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_translate_resource); >+ rc = ((bus_translate_resource_t *) _m)(_dev, _type, _start, _newstart); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_RELEASE_RESOURCE() method */ >+extern struct kobjop_desc bus_release_resource_desc; >+/** @brief A function implementing the BUS_RELEASE_RESOURCE() method */ >+typedef int bus_release_resource_t(device_t _dev, device_t _child, int _type, >+ int _rid, struct resource *_res); >+/** >+ * @brief Release a resource >+ * >+ * Free a resource allocated by the BUS_ALLOC_RESOURCE. The @p _rid >+ * value must be the same as the one returned by BUS_ALLOC_RESOURCE() >+ * (which is not necessarily the same as the one the client passed). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _type the type of resource >+ * @param _rid the resource identifier >+ * @param _r the resource to release >+ */ >+ >+static __inline int BUS_RELEASE_RESOURCE(device_t _dev, device_t _child, >+ int _type, int _rid, >+ struct resource *_res) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_release_resource); >+ rc = ((bus_release_resource_t *) _m)(_dev, _child, _type, _rid, _res); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_SETUP_INTR() method */ >+extern struct kobjop_desc bus_setup_intr_desc; >+/** @brief A function implementing the BUS_SETUP_INTR() method */ >+typedef int bus_setup_intr_t(device_t _dev, device_t _child, >+ struct resource *_irq, int _flags, >+ driver_filter_t *_filter, driver_intr_t *_intr, >+ void *_arg, void **_cookiep); >+/** >+ * @brief Install an interrupt handler >+ * >+ * This method is used to associate an interrupt handler function with >+ * an irq resource. When the interrupt triggers, the function @p _intr >+ * will be called with the value of @p _arg as its single >+ * argument. The value returned in @p *_cookiep is used to cancel the >+ * interrupt handler - the caller should save this value to use in a >+ * future call to BUS_TEARDOWN_INTR(). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _irq the resource representing the interrupt >+ * @param _flags a set of bits from enum intr_type specifying >+ * the class of interrupt >+ * @param _intr the function to call when the interrupt >+ * triggers >+ * @param _arg a value to use as the single argument in calls >+ * to @p _intr >+ * @param _cookiep a pointer to a location to receive a cookie >+ * value that may be used to remove the interrupt >+ * handler >+ */ >+ >+static __inline int BUS_SETUP_INTR(device_t _dev, device_t _child, >+ struct resource *_irq, int _flags, >+ driver_filter_t *_filter, >+ driver_intr_t *_intr, void *_arg, >+ void **_cookiep) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_setup_intr); >+ rc = ((bus_setup_intr_t *) _m)(_dev, _child, _irq, _flags, _filter, _intr, _arg, _cookiep); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_TEARDOWN_INTR() method */ >+extern struct kobjop_desc bus_teardown_intr_desc; >+/** @brief A function implementing the BUS_TEARDOWN_INTR() method */ >+typedef int bus_teardown_intr_t(device_t _dev, device_t _child, >+ struct resource *_irq, void *_cookie); >+/** >+ * @brief Uninstall an interrupt handler >+ * >+ * This method is used to disassociate an interrupt handler function >+ * with an irq resource. The value of @p _cookie must be the value >+ * returned from a previous call to BUS_SETUP_INTR(). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _irq the resource representing the interrupt >+ * @param _cookie the cookie value returned when the interrupt >+ * was originally registered >+ */ >+ >+static __inline int BUS_TEARDOWN_INTR(device_t _dev, device_t _child, >+ struct resource *_irq, void *_cookie) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_teardown_intr); >+ rc = ((bus_teardown_intr_t *) _m)(_dev, _child, _irq, _cookie); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_SUSPEND_INTR() method */ >+extern struct kobjop_desc bus_suspend_intr_desc; >+/** @brief A function implementing the BUS_SUSPEND_INTR() method */ >+typedef int bus_suspend_intr_t(device_t _dev, device_t _child, >+ struct resource *_irq); >+/** >+ * @brief Suspend an interrupt handler >+ * >+ * This method is used to mark a handler as suspended in the case >+ * that the associated device is powered down and cannot be a source >+ * for the, typically shared, interrupt. >+ * The value of @p _irq must be the interrupt resource passed >+ * to a previous call to BUS_SETUP_INTR(). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _irq the resource representing the interrupt >+ */ >+ >+static __inline int BUS_SUSPEND_INTR(device_t _dev, device_t _child, >+ struct resource *_irq) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_suspend_intr); >+ rc = ((bus_suspend_intr_t *) _m)(_dev, _child, _irq); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_RESUME_INTR() method */ >+extern struct kobjop_desc bus_resume_intr_desc; >+/** @brief A function implementing the BUS_RESUME_INTR() method */ >+typedef int bus_resume_intr_t(device_t _dev, device_t _child, >+ struct resource *_irq); >+/** >+ * @brief Resume an interrupt handler >+ * >+ * This method is used to clear suspended state of a handler when >+ * the associated device is powered up and can be an interrupt source >+ * again. >+ * The value of @p _irq must be the interrupt resource passed >+ * to a previous call to BUS_SETUP_INTR(). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _irq the resource representing the interrupt >+ */ >+ >+static __inline int BUS_RESUME_INTR(device_t _dev, device_t _child, >+ struct resource *_irq) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_resume_intr); >+ rc = ((bus_resume_intr_t *) _m)(_dev, _child, _irq); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_SET_RESOURCE() method */ >+extern struct kobjop_desc bus_set_resource_desc; >+/** @brief A function implementing the BUS_SET_RESOURCE() method */ >+typedef int bus_set_resource_t(device_t _dev, device_t _child, int _type, >+ int _rid, rman_res_t _start, rman_res_t _count); >+/** >+ * @brief Define a resource which can be allocated with >+ * BUS_ALLOC_RESOURCE(). >+ * >+ * This method is used by some buses (typically ISA) to allow a >+ * driver to describe a resource range that it would like to >+ * allocate. The resource defined by @p _type and @p _rid is defined >+ * to start at @p _start and to include @p _count indices in its >+ * range. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which owns the resource >+ * @param _type the type of resource >+ * @param _rid the resource identifier >+ * @param _start the start of the resource range >+ * @param _count the size of the resource range >+ */ >+ >+static __inline int BUS_SET_RESOURCE(device_t _dev, device_t _child, int _type, >+ int _rid, rman_res_t _start, >+ rman_res_t _count) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_set_resource); >+ rc = ((bus_set_resource_t *) _m)(_dev, _child, _type, _rid, _start, _count); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_GET_RESOURCE() method */ >+extern struct kobjop_desc bus_get_resource_desc; >+/** @brief A function implementing the BUS_GET_RESOURCE() method */ >+typedef int bus_get_resource_t(device_t _dev, device_t _child, int _type, >+ int _rid, rman_res_t *_startp, >+ rman_res_t *_countp); >+/** >+ * @brief Describe a resource >+ * >+ * This method allows a driver to examine the range used for a given >+ * resource without actually allocating it. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which owns the resource >+ * @param _type the type of resource >+ * @param _rid the resource identifier >+ * @param _start the address of a location to receive the start >+ * index of the resource range >+ * @param _count the address of a location to receive the size >+ * of the resource range >+ */ >+ >+static __inline int BUS_GET_RESOURCE(device_t _dev, device_t _child, int _type, >+ int _rid, rman_res_t *_startp, >+ rman_res_t *_countp) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_resource); >+ rc = ((bus_get_resource_t *) _m)(_dev, _child, _type, _rid, _startp, _countp); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_DELETE_RESOURCE() method */ >+extern struct kobjop_desc bus_delete_resource_desc; >+/** @brief A function implementing the BUS_DELETE_RESOURCE() method */ >+typedef void bus_delete_resource_t(device_t _dev, device_t _child, int _type, >+ int _rid); >+/** >+ * @brief Delete a resource. >+ * >+ * Use this to delete a resource (possibly one previously added with >+ * BUS_SET_RESOURCE()). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which owns the resource >+ * @param _type the type of resource >+ * @param _rid the resource identifier >+ */ >+ >+static __inline void BUS_DELETE_RESOURCE(device_t _dev, device_t _child, >+ int _type, int _rid) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_delete_resource); >+ ((bus_delete_resource_t *) _m)(_dev, _child, _type, _rid); >+} >+ >+/** @brief Unique descriptor for the BUS_GET_RESOURCE_LIST() method */ >+extern struct kobjop_desc bus_get_resource_list_desc; >+/** @brief A function implementing the BUS_GET_RESOURCE_LIST() method */ >+typedef struct resource_list * bus_get_resource_list_t(device_t _dev, >+ device_t _child); >+/** >+ * @brief Return a struct resource_list. >+ * >+ * Used by drivers which use bus_generic_rl_alloc_resource() etc. to >+ * implement their resource handling. It should return the resource >+ * list of the given child device. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which owns the resource list >+ */ >+ >+static __inline struct resource_list * BUS_GET_RESOURCE_LIST(device_t _dev, >+ device_t _child) >+{ >+ kobjop_t _m; >+ struct resource_list * rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_resource_list); >+ rc = ((bus_get_resource_list_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_CHILD_PRESENT() method */ >+extern struct kobjop_desc bus_child_present_desc; >+/** @brief A function implementing the BUS_CHILD_PRESENT() method */ >+typedef int bus_child_present_t(device_t _dev, device_t _child); >+/** >+ * @brief Is the hardware described by @p _child still attached to the >+ * system? >+ * >+ * This method should return 0 if the device is not present. It >+ * should return -1 if it is present. Any errors in determining >+ * should be returned as a normal errno value. Client drivers are to >+ * assume that the device is present, even if there is an error >+ * determining if it is there. Buses are to try to avoid returning >+ * errors, but newcard will return an error if the device fails to >+ * implement this method. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which is being examined >+ */ >+ >+static __inline int BUS_CHILD_PRESENT(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_present); >+ rc = ((bus_child_present_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_CHILD_PNPINFO_STR() method */ >+extern struct kobjop_desc bus_child_pnpinfo_str_desc; >+/** @brief A function implementing the BUS_CHILD_PNPINFO_STR() method */ >+typedef int bus_child_pnpinfo_str_t(device_t _dev, device_t _child, char *_buf, >+ size_t _buflen); >+/** >+ * @brief Returns the pnp info for this device. >+ * >+ * Return it as a string. If the storage is insufficient for the >+ * string, then return EOVERFLOW. >+ * >+ * The string must be formatted as a space-separated list of >+ * name=value pairs. Names may only contain alphanumeric characters, >+ * underscores ('_') and hyphens ('-'). Values can contain any >+ * non-whitespace characters. Values containing whitespace can be >+ * quoted with double quotes ('"'). Double quotes and backslashes in >+ * quoted values can be escaped with backslashes ('\'). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which is being examined >+ * @param _buf the address of a buffer to receive the pnp >+ * string >+ * @param _buflen the size of the buffer pointed to by @p _buf >+ */ >+ >+static __inline int BUS_CHILD_PNPINFO_STR(device_t _dev, device_t _child, >+ char *_buf, size_t _buflen) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_pnpinfo_str); >+ rc = ((bus_child_pnpinfo_str_t *) _m)(_dev, _child, _buf, _buflen); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_CHILD_LOCATION_STR() method */ >+extern struct kobjop_desc bus_child_location_str_desc; >+/** @brief A function implementing the BUS_CHILD_LOCATION_STR() method */ >+typedef int bus_child_location_str_t(device_t _dev, device_t _child, char *_buf, >+ size_t _buflen); >+/** >+ * @brief Returns the location for this device. >+ * >+ * Return it as a string. If the storage is insufficient for the >+ * string, then return EOVERFLOW. >+ * >+ * The string must be formatted as a space-separated list of >+ * name=value pairs. Names may only contain alphanumeric characters, >+ * underscores ('_') and hyphens ('-'). Values can contain any >+ * non-whitespace characters. Values containing whitespace can be >+ * quoted with double quotes ('"'). Double quotes and backslashes in >+ * quoted values can be escaped with backslashes ('\'). >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which is being examined >+ * @param _buf the address of a buffer to receive the location >+ * string >+ * @param _buflen the size of the buffer pointed to by @p _buf >+ */ >+ >+static __inline int BUS_CHILD_LOCATION_STR(device_t _dev, device_t _child, >+ char *_buf, size_t _buflen) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_child_location_str); >+ rc = ((bus_child_location_str_t *) _m)(_dev, _child, _buf, _buflen); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_BIND_INTR() method */ >+extern struct kobjop_desc bus_bind_intr_desc; >+/** @brief A function implementing the BUS_BIND_INTR() method */ >+typedef int bus_bind_intr_t(device_t _dev, device_t _child, >+ struct resource *_irq, int _cpu); >+/** >+ * @brief Allow drivers to request that an interrupt be bound to a specific >+ * CPU. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _irq the resource representing the interrupt >+ * @param _cpu the CPU to bind the interrupt to >+ */ >+ >+static __inline int BUS_BIND_INTR(device_t _dev, device_t _child, >+ struct resource *_irq, int _cpu) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_bind_intr); >+ rc = ((bus_bind_intr_t *) _m)(_dev, _child, _irq, _cpu); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_CONFIG_INTR() method */ >+extern struct kobjop_desc bus_config_intr_desc; >+/** @brief A function implementing the BUS_CONFIG_INTR() method */ >+typedef int bus_config_intr_t(device_t _dev, int _irq, enum intr_trigger _trig, >+ enum intr_polarity _pol); >+/** >+ * @brief Allow (bus) drivers to specify the trigger mode and polarity >+ * of the specified interrupt. >+ * >+ * @param _dev the bus device >+ * @param _irq the interrupt number to modify >+ * @param _trig the trigger mode required >+ * @param _pol the interrupt polarity required >+ */ >+ >+static __inline int BUS_CONFIG_INTR(device_t _dev, int _irq, >+ enum intr_trigger _trig, >+ enum intr_polarity _pol) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_config_intr); >+ rc = ((bus_config_intr_t *) _m)(_dev, _irq, _trig, _pol); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_DESCRIBE_INTR() method */ >+extern struct kobjop_desc bus_describe_intr_desc; >+/** @brief A function implementing the BUS_DESCRIBE_INTR() method */ >+typedef int bus_describe_intr_t(device_t _dev, device_t _child, >+ struct resource *_irq, void *_cookie, >+ const char *_descr); >+/** >+ * @brief Allow drivers to associate a description with an active >+ * interrupt handler. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device which allocated the resource >+ * @param _irq the resource representing the interrupt >+ * @param _cookie the cookie value returned when the interrupt >+ * was originally registered >+ * @param _descr the description to associate with the interrupt >+ */ >+ >+static __inline int BUS_DESCRIBE_INTR(device_t _dev, device_t _child, >+ struct resource *_irq, void *_cookie, >+ const char *_descr) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_describe_intr); >+ rc = ((bus_describe_intr_t *) _m)(_dev, _child, _irq, _cookie, _descr); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_HINTED_CHILD() method */ >+extern struct kobjop_desc bus_hinted_child_desc; >+/** @brief A function implementing the BUS_HINTED_CHILD() method */ >+typedef void bus_hinted_child_t(device_t _dev, const char *_dname, int _dunit); >+/** >+ * @brief Notify a (bus) driver about a child that the hints mechanism >+ * believes it has discovered. >+ * >+ * The bus is responsible for then adding the child in the right order >+ * and discovering other things about the child. The bus driver is >+ * free to ignore this hint, to do special things, etc. It is all up >+ * to the bus driver to interpret. >+ * >+ * This method is only called in response to the parent bus asking for >+ * hinted devices to be enumerated. >+ * >+ * @param _dev the bus device >+ * @param _dname the name of the device w/o unit numbers >+ * @param _dunit the unit number of the device >+ */ >+ >+static __inline void BUS_HINTED_CHILD(device_t _dev, const char *_dname, >+ int _dunit) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_hinted_child); >+ ((bus_hinted_child_t *) _m)(_dev, _dname, _dunit); >+} >+ >+/** @brief Unique descriptor for the BUS_GET_DMA_TAG() method */ >+extern struct kobjop_desc bus_get_dma_tag_desc; >+/** @brief A function implementing the BUS_GET_DMA_TAG() method */ >+typedef bus_dma_tag_t bus_get_dma_tag_t(device_t _dev, device_t _child); >+/** >+ * @brief Returns bus_dma_tag_t for use w/ devices on the bus. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device to which the tag will belong >+ */ >+ >+static __inline bus_dma_tag_t BUS_GET_DMA_TAG(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ bus_dma_tag_t rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_dma_tag); >+ rc = ((bus_get_dma_tag_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_GET_BUS_TAG() method */ >+extern struct kobjop_desc bus_get_bus_tag_desc; >+/** @brief A function implementing the BUS_GET_BUS_TAG() method */ >+typedef bus_space_tag_t bus_get_bus_tag_t(device_t _dev, device_t _child); >+/** >+ * @brief Returns bus_space_tag_t for use w/ devices on the bus. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device to which the tag will belong >+ */ >+ >+static __inline bus_space_tag_t BUS_GET_BUS_TAG(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ bus_space_tag_t rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_bus_tag); >+ rc = ((bus_get_bus_tag_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_HINT_DEVICE_UNIT() method */ >+extern struct kobjop_desc bus_hint_device_unit_desc; >+/** @brief A function implementing the BUS_HINT_DEVICE_UNIT() method */ >+typedef void bus_hint_device_unit_t(device_t _dev, device_t _child, >+ const char *_name, int *_unitp); >+/** >+ * @brief Allow the bus to determine the unit number of a device. >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device whose unit is to be wired >+ * @param _name the name of the device's new devclass >+ * @param _unitp a pointer to the device's new unit value >+ */ >+ >+static __inline void BUS_HINT_DEVICE_UNIT(device_t _dev, device_t _child, >+ const char *_name, int *_unitp) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_hint_device_unit); >+ ((bus_hint_device_unit_t *) _m)(_dev, _child, _name, _unitp); >+} >+ >+/** @brief Unique descriptor for the BUS_NEW_PASS() method */ >+extern struct kobjop_desc bus_new_pass_desc; >+/** @brief A function implementing the BUS_NEW_PASS() method */ >+typedef void bus_new_pass_t(device_t _dev); >+/** >+ * @brief Notify a bus that the bus pass level has been changed >+ * >+ * @param _dev the bus device >+ */ >+ >+static __inline void BUS_NEW_PASS(device_t _dev) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_new_pass); >+ ((bus_new_pass_t *) _m)(_dev); >+} >+ >+/** @brief Unique descriptor for the BUS_REMAP_INTR() method */ >+extern struct kobjop_desc bus_remap_intr_desc; >+/** @brief A function implementing the BUS_REMAP_INTR() method */ >+typedef int bus_remap_intr_t(device_t _dev, device_t _child, u_int _irq); >+/** >+ * @brief Notify a bus that specified child's IRQ should be remapped. >+ * >+ * @param _dev the bus device >+ * @param _child the child device >+ * @param _irq the irq number >+ */ >+ >+static __inline int BUS_REMAP_INTR(device_t _dev, device_t _child, u_int _irq) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_remap_intr); >+ rc = ((bus_remap_intr_t *) _m)(_dev, _child, _irq); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_SUSPEND_CHILD() method */ >+extern struct kobjop_desc bus_suspend_child_desc; >+/** @brief A function implementing the BUS_SUSPEND_CHILD() method */ >+typedef int bus_suspend_child_t(device_t _dev, device_t _child); >+/** >+ * @brief Suspend a given child >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device to suspend >+ */ >+ >+static __inline int BUS_SUSPEND_CHILD(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_suspend_child); >+ rc = ((bus_suspend_child_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_RESUME_CHILD() method */ >+extern struct kobjop_desc bus_resume_child_desc; >+/** @brief A function implementing the BUS_RESUME_CHILD() method */ >+typedef int bus_resume_child_t(device_t _dev, device_t _child); >+/** >+ * @brief Resume a given child >+ * >+ * @param _dev the parent device of @p _child >+ * @param _child the device to resume >+ */ >+ >+static __inline int BUS_RESUME_CHILD(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_resume_child); >+ rc = ((bus_resume_child_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_GET_DOMAIN() method */ >+extern struct kobjop_desc bus_get_domain_desc; >+/** @brief A function implementing the BUS_GET_DOMAIN() method */ >+typedef int bus_get_domain_t(device_t _dev, device_t _child, int *_domain); >+/** >+ * @brief Get the VM domain handle for the given bus and child. >+ * >+ * @param _dev the bus device >+ * @param _child the child device >+ * @param _domain a pointer to the bus's domain handle identifier >+ */ >+ >+static __inline int BUS_GET_DOMAIN(device_t _dev, device_t _child, int *_domain) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_domain); >+ rc = ((bus_get_domain_t *) _m)(_dev, _child, _domain); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_GET_CPUS() method */ >+extern struct kobjop_desc bus_get_cpus_desc; >+/** @brief A function implementing the BUS_GET_CPUS() method */ >+typedef int bus_get_cpus_t(device_t _dev, device_t _child, enum cpu_sets _op, >+ size_t _setsize, struct _cpuset *_cpuset); >+/** >+ * @brief Request a set of CPUs >+ * >+ * @param _dev the bus device >+ * @param _child the child device >+ * @param _op type of CPUs to request >+ * @param _setsize the size of the set passed in _cpuset >+ * @param _cpuset a pointer to a cpuset to receive the requested >+ * set of CPUs >+ */ >+ >+static __inline int BUS_GET_CPUS(device_t _dev, device_t _child, >+ enum cpu_sets _op, size_t _setsize, >+ struct _cpuset *_cpuset) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_get_cpus); >+ rc = ((bus_get_cpus_t *) _m)(_dev, _child, _op, _setsize, _cpuset); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_RESET_PREPARE() method */ >+extern struct kobjop_desc bus_reset_prepare_desc; >+/** @brief A function implementing the BUS_RESET_PREPARE() method */ >+typedef int bus_reset_prepare_t(device_t _dev, device_t _child); >+/** >+ * @brief Prepares the given child of the bus for reset >+ * >+ * Typically bus detaches or suspends children' drivers, and then >+ * calls this method to save bus-specific information, for instance, >+ * PCI config space, which is damaged by reset. >+ * >+ * The bus_helper_reset_prepare() helper is provided to ease >+ * implementing bus reset methods. >+ * >+ * @param _dev the bus device >+ * @param _child the child device >+ */ >+ >+static __inline int BUS_RESET_PREPARE(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_reset_prepare); >+ rc = ((bus_reset_prepare_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_RESET_POST() method */ >+extern struct kobjop_desc bus_reset_post_desc; >+/** @brief A function implementing the BUS_RESET_POST() method */ >+typedef int bus_reset_post_t(device_t _dev, device_t _child); >+/** >+ * @brief Restores the child operations after the reset >+ * >+ * The bus_helper_reset_post() helper is provided to ease >+ * implementing bus reset methods. >+ * >+ * @param _dev the bus device >+ * @param _child the child device >+ */ >+ >+static __inline int BUS_RESET_POST(device_t _dev, device_t _child) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_reset_post); >+ rc = ((bus_reset_post_t *) _m)(_dev, _child); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the BUS_RESET_CHILD() method */ >+extern struct kobjop_desc bus_reset_child_desc; >+/** @brief A function implementing the BUS_RESET_CHILD() method */ >+typedef int bus_reset_child_t(device_t _dev, device_t _child, int _flags); >+/** >+ * @brief Performs reset of the child >+ * >+ * @param _dev the bus device >+ * @param _child the child device >+ * @param _flags DEVF_RESET_ flags >+ */ >+ >+static __inline int BUS_RESET_CHILD(device_t _dev, device_t _child, int _flags) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)_dev)->ops,bus_reset_child); >+ rc = ((bus_reset_child_t *) _m)(_dev, _child, _flags); >+ return (rc); >+} >+ >+#endif /* _bus_if_h_ */ >diff -ruN drvGPIOIITK.orig/device_if.h drvGPIOIITK/device_if.h >--- drvGPIOIITK.orig/device_if.h 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/device_if.h 2020-11-26 04:44:40.316773000 +0100 >@@ -0,0 +1,402 @@ >+/* >+ * This file is @generated automatically. >+ * Do not modify anything in here by hand. >+ * >+ * Created from source file >+ * /usr/src/sys/kern/device_if.m >+ * with >+ * makeobjops.awk >+ * >+ * See the source file for legal information >+ */ >+ >+/** >+ * @defgroup DEVICE device - KObj methods for all device drivers >+ * @brief A basic set of methods required for all device drivers. >+ * >+ * The device interface is used to match devices to drivers during >+ * autoconfiguration and provides methods to allow drivers to handle >+ * system-wide events such as suspend, resume or shutdown. >+ * @{ >+ */ >+ >+#ifndef _device_if_h_ >+#define _device_if_h_ >+ >+ >+#include <sys/tslog.h> >+ >+/** @brief Unique descriptor for the DEVICE_PROBE() method */ >+extern struct kobjop_desc device_probe_desc; >+/** @brief A function implementing the DEVICE_PROBE() method */ >+typedef int device_probe_t(device_t dev); >+/** >+ * @brief Probe to see if a device matches a driver. >+ * >+ * Users should not call this method directly. Normally, this >+ * is called via device_probe_and_attach() to select a driver >+ * calling the DEVICE_PROBE() of all candidate drivers and attach >+ * the winning driver (if any) to the device. >+ * >+ * This function is used to match devices to device drivers. >+ * Typically, the driver will examine the device to see if >+ * it is suitable for this driver. This might include checking >+ * the values of various device instance variables or reading >+ * hardware registers. >+ * >+ * In some cases, there may be more than one driver available >+ * which can be used for a device (for instance there might >+ * be a generic driver which works for a set of many types of >+ * device and a more specific driver which works for a subset >+ * of devices). Because of this, a driver should not assume >+ * that it will be the driver that attaches to the device even >+ * if it returns a success status from DEVICE_PROBE(). In particular, >+ * a driver must free any resources which it allocated during >+ * the probe before returning. The return value of DEVICE_PROBE() >+ * is used to elect which driver is used - the driver which returns >+ * the largest non-error value wins the election and attaches to >+ * the device. Common non-error values are described in the >+ * DEVICE_PROBE(9) manual page. >+ * >+ * If a driver matches the hardware, it should set the device >+ * description string using device_set_desc() or >+ * device_set_desc_copy(). This string is used to generate an >+ * informative message when DEVICE_ATTACH() is called. >+ * >+ * As a special case, if a driver returns zero, the driver election >+ * is cut short and that driver will attach to the device >+ * immediately. This should rarely be used. >+ * >+ * For example, a probe method for a PCI device driver might look >+ * like this: >+ * >+ * @code >+ * int >+ * foo_probe(device_t dev) >+ * { >+ * if (pci_get_vendor(dev) == FOOVENDOR && >+ * pci_get_device(dev) == FOODEVICE) { >+ * device_set_desc(dev, "Foo device"); >+ * return (BUS_PROBE_DEFAULT); >+ * } >+ * return (ENXIO); >+ * } >+ * @endcode >+ * >+ * To include this method in a device driver, use a line like this >+ * in the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_probe, foo_probe) >+ * @endcode >+ * >+ * @param dev the device to probe >+ * >+ * @retval 0 if this is the only possible driver for this >+ * device >+ * @retval negative if the driver can match this device - the >+ * least negative value is used to select the >+ * driver >+ * @retval ENXIO if the driver does not match the device >+ * @retval positive if some kind of error was detected during >+ * the probe, a regular unix error code should >+ * be returned to indicate the type of error >+ * @see DEVICE_ATTACH(), pci_get_vendor(), pci_get_device() >+ */ >+ >+static __inline int DEVICE_PROBE(device_t dev) >+{ >+ kobjop_t _m; >+ int rc; >+ >+TSENTER2(device_get_name(dev)); >+ >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,device_probe); >+ rc = ((device_probe_t *) _m)(dev); >+ >+TSEXIT2(device_get_name(dev)); >+ >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the DEVICE_IDENTIFY() method */ >+extern struct kobjop_desc device_identify_desc; >+/** @brief A function implementing the DEVICE_IDENTIFY() method */ >+typedef void device_identify_t(driver_t *driver, device_t parent); >+/** >+ * @brief Allow a device driver to detect devices not otherwise enumerated. >+ * >+ * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA >+ * bus driver) to help populate the bus device with a useful set of >+ * child devices, normally by calling the BUS_ADD_CHILD() method of >+ * the parent device. For instance, the ISA bus driver uses several >+ * special drivers, including the isahint driver and the pnp driver to >+ * create child devices based on configuration hints and PnP bus >+ * probes respectively. >+ * >+ * Many bus drivers which support true plug-and-play do not need to >+ * use this method at all since child devices can be discovered >+ * automatically without help from child drivers. >+ * >+ * To include this method in a device driver, use a line like this >+ * in the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_identify, foo_identify) >+ * @endcode >+ * >+ * @param driver the driver whose identify method is being called >+ * @param parent the parent device to use when adding new children >+ */ >+ >+static __inline void DEVICE_IDENTIFY(driver_t *driver, device_t parent) >+{ >+ kobjop_t _m; >+ KOBJOPLOOKUP(driver->ops,device_identify); >+ ((device_identify_t *) _m)(driver, parent); >+} >+ >+/** @brief Unique descriptor for the DEVICE_ATTACH() method */ >+extern struct kobjop_desc device_attach_desc; >+/** @brief A function implementing the DEVICE_ATTACH() method */ >+typedef int device_attach_t(device_t dev); >+/** >+ * @brief Attach a device to a device driver >+ * >+ * Normally only called via device_probe_and_attach(), this is called >+ * when a driver has succeeded in probing against a device. >+ * This method should initialise the hardware and allocate other >+ * system resources (e.g. devfs entries) as required. >+ * >+ * To include this method in a device driver, use a line like this >+ * in the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_attach, foo_attach) >+ * @endcode >+ * >+ * @param dev the device to probe >+ * >+ * @retval 0 success >+ * @retval non-zero if some kind of error was detected during >+ * the attach, a regular unix error code should >+ * be returned to indicate the type of error >+ * @see DEVICE_PROBE() >+ */ >+ >+static __inline int DEVICE_ATTACH(device_t dev) >+{ >+ kobjop_t _m; >+ int rc; >+ >+TSENTER2(device_get_name(dev)); >+ >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,device_attach); >+ rc = ((device_attach_t *) _m)(dev); >+ >+TSEXIT2(device_get_name(dev)); >+ >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the DEVICE_DETACH() method */ >+extern struct kobjop_desc device_detach_desc; >+/** @brief A function implementing the DEVICE_DETACH() method */ >+typedef int device_detach_t(device_t dev); >+/** >+ * @brief Detach a driver from a device. >+ * >+ * This can be called if the user is replacing the >+ * driver software or if a device is about to be physically removed >+ * from the system (e.g. for removable hardware such as USB or PCCARD). >+ * >+ * To include this method in a device driver, use a line like this >+ * in the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_detach, foo_detach) >+ * @endcode >+ * >+ * @param dev the device to detach >+ * >+ * @retval 0 success >+ * @retval non-zero the detach could not be performed, e.g. if the >+ * driver does not support detaching. >+ * >+ * @see DEVICE_ATTACH() >+ */ >+ >+static __inline int DEVICE_DETACH(device_t dev) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,device_detach); >+ rc = ((device_detach_t *) _m)(dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the DEVICE_SHUTDOWN() method */ >+extern struct kobjop_desc device_shutdown_desc; >+/** @brief A function implementing the DEVICE_SHUTDOWN() method */ >+typedef int device_shutdown_t(device_t dev); >+/** >+ * @brief Called during system shutdown. >+ * >+ * This method allows drivers to detect when the system is being shut down. >+ * Some drivers need to use this to place their hardware in a consistent >+ * state before rebooting the computer. >+ * >+ * To include this method in a device driver, use a line like this >+ * in the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_shutdown, foo_shutdown) >+ * @endcode >+ */ >+ >+static __inline int DEVICE_SHUTDOWN(device_t dev) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,device_shutdown); >+ rc = ((device_shutdown_t *) _m)(dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the DEVICE_SUSPEND() method */ >+extern struct kobjop_desc device_suspend_desc; >+/** @brief A function implementing the DEVICE_SUSPEND() method */ >+typedef int device_suspend_t(device_t dev); >+/** >+ * @brief This is called by the power-management subsystem when a >+ * suspend has been requested by the user or by some automatic >+ * mechanism. >+ * >+ * This gives drivers a chance to veto the suspend or save their >+ * configuration before power is removed. >+ * >+ * To include this method in a device driver, use a line like this in >+ * the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_suspend, foo_suspend) >+ * @endcode >+ * >+ * @param dev the device being suspended >+ * >+ * @retval 0 success >+ * @retval non-zero an error occurred while attempting to prepare the >+ * device for suspension >+ * >+ * @see DEVICE_RESUME() >+ */ >+ >+static __inline int DEVICE_SUSPEND(device_t dev) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,device_suspend); >+ rc = ((device_suspend_t *) _m)(dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the DEVICE_RESUME() method */ >+extern struct kobjop_desc device_resume_desc; >+/** @brief A function implementing the DEVICE_RESUME() method */ >+typedef int device_resume_t(device_t dev); >+/** >+ * @brief This is called when the system resumes after a suspend. >+ * >+ * To include this method in a device driver, use a line like this >+ * in the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_resume, foo_resume) >+ * @endcode >+ * >+ * @param dev the device being resumed >+ * >+ * @retval 0 success >+ * @retval non-zero an error occurred while attempting to restore the >+ * device from suspension >+ * >+ * @see DEVICE_SUSPEND() >+ */ >+ >+static __inline int DEVICE_RESUME(device_t dev) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,device_resume); >+ rc = ((device_resume_t *) _m)(dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the DEVICE_QUIESCE() method */ >+extern struct kobjop_desc device_quiesce_desc; >+/** @brief A function implementing the DEVICE_QUIESCE() method */ >+typedef int device_quiesce_t(device_t dev); >+/** >+ * @brief This is called when the driver is asked to quiesce itself. >+ * >+ * The driver should arrange for the orderly shutdown of this device. >+ * All further access to the device should be curtailed. Soon there >+ * will be a request to detach, but there won't necessarily be one. >+ * >+ * To include this method in a device driver, use a line like this >+ * in the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_quiesce, foo_quiesce) >+ * @endcode >+ * >+ * @param dev the device being quiesced >+ * >+ * @retval 0 success >+ * @retval non-zero an error occurred while attempting to quiesce the >+ * device >+ * >+ * @see DEVICE_DETACH() >+ */ >+ >+static __inline int DEVICE_QUIESCE(device_t dev) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,device_quiesce); >+ rc = ((device_quiesce_t *) _m)(dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the DEVICE_REGISTER() method */ >+extern struct kobjop_desc device_register_desc; >+/** @brief A function implementing the DEVICE_REGISTER() method */ >+typedef void * device_register_t(device_t dev); >+/** >+ * @brief This is called when the driver is asked to register handlers. >+ * >+ * >+ * To include this method in a device driver, use a line like this >+ * in the driver's method list: >+ * >+ * @code >+ * KOBJMETHOD(device_register, foo_register) >+ * @endcode >+ * >+ * @param dev the device for which handlers are being registered >+ * >+ * @retval NULL method not implemented >+ * @retval non-NULL a pointer to implementation specific static driver state >+ * >+ */ >+ >+static __inline void * DEVICE_REGISTER(device_t dev) >+{ >+ kobjop_t _m; >+ void * rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,device_register); >+ rc = ((device_register_t *) _m)(dev); >+ return (rc); >+} >+ >+#endif /* _device_if_h_ */ >diff -ruN drvGPIOIITK.orig/gpio_if.h drvGPIOIITK/gpio_if.h >--- drvGPIOIITK.orig/gpio_if.h 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/gpio_if.h 2020-11-26 04:44:40.316805000 +0100 >@@ -0,0 +1,206 @@ >+/* >+ * This file is @generated automatically. >+ * Do not modify anything in here by hand. >+ * >+ * Created from source file >+ * /usr/src/sys/dev/gpio/gpio_if.m >+ * with >+ * makeobjops.awk >+ * >+ * See the source file for legal information >+ */ >+ >+ >+#ifndef _gpio_if_h_ >+#define _gpio_if_h_ >+ >+ >+#include <dev/ofw/openfirm.h> >+ >+/** @brief Unique descriptor for the GPIO_GET_BUS() method */ >+extern struct kobjop_desc gpio_get_bus_desc; >+/** @brief A function implementing the GPIO_GET_BUS() method */ >+typedef device_t gpio_get_bus_t(device_t dev); >+ >+static __inline device_t GPIO_GET_BUS(device_t dev) >+{ >+ kobjop_t _m; >+ device_t rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_get_bus); >+ rc = ((gpio_get_bus_t *) _m)(dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_MAX() method */ >+extern struct kobjop_desc gpio_pin_max_desc; >+/** @brief A function implementing the GPIO_PIN_MAX() method */ >+typedef int gpio_pin_max_t(device_t dev, int *maxpin); >+ >+static __inline int GPIO_PIN_MAX(device_t dev, int *maxpin) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_max); >+ rc = ((gpio_pin_max_t *) _m)(dev, maxpin); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_SET() method */ >+extern struct kobjop_desc gpio_pin_set_desc; >+/** @brief A function implementing the GPIO_PIN_SET() method */ >+typedef int gpio_pin_set_t(device_t dev, uint32_t pin_num, uint32_t pin_value); >+ >+static __inline int GPIO_PIN_SET(device_t dev, uint32_t pin_num, >+ uint32_t pin_value) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_set); >+ rc = ((gpio_pin_set_t *) _m)(dev, pin_num, pin_value); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_GET() method */ >+extern struct kobjop_desc gpio_pin_get_desc; >+/** @brief A function implementing the GPIO_PIN_GET() method */ >+typedef int gpio_pin_get_t(device_t dev, uint32_t pin_num, uint32_t *pin_value); >+ >+static __inline int GPIO_PIN_GET(device_t dev, uint32_t pin_num, >+ uint32_t *pin_value) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_get); >+ rc = ((gpio_pin_get_t *) _m)(dev, pin_num, pin_value); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_TOGGLE() method */ >+extern struct kobjop_desc gpio_pin_toggle_desc; >+/** @brief A function implementing the GPIO_PIN_TOGGLE() method */ >+typedef int gpio_pin_toggle_t(device_t dev, uint32_t pin_num); >+ >+static __inline int GPIO_PIN_TOGGLE(device_t dev, uint32_t pin_num) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_toggle); >+ rc = ((gpio_pin_toggle_t *) _m)(dev, pin_num); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_GETCAPS() method */ >+extern struct kobjop_desc gpio_pin_getcaps_desc; >+/** @brief A function implementing the GPIO_PIN_GETCAPS() method */ >+typedef int gpio_pin_getcaps_t(device_t dev, uint32_t pin_num, uint32_t *caps); >+ >+static __inline int GPIO_PIN_GETCAPS(device_t dev, uint32_t pin_num, >+ uint32_t *caps) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_getcaps); >+ rc = ((gpio_pin_getcaps_t *) _m)(dev, pin_num, caps); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_GETFLAGS() method */ >+extern struct kobjop_desc gpio_pin_getflags_desc; >+/** @brief A function implementing the GPIO_PIN_GETFLAGS() method */ >+typedef int gpio_pin_getflags_t(device_t dev, uint32_t pin_num, >+ uint32_t *flags); >+ >+static __inline int GPIO_PIN_GETFLAGS(device_t dev, uint32_t pin_num, >+ uint32_t *flags) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_getflags); >+ rc = ((gpio_pin_getflags_t *) _m)(dev, pin_num, flags); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_GETNAME() method */ >+extern struct kobjop_desc gpio_pin_getname_desc; >+/** @brief A function implementing the GPIO_PIN_GETNAME() method */ >+typedef int gpio_pin_getname_t(device_t dev, uint32_t pin_num, char *name); >+ >+static __inline int GPIO_PIN_GETNAME(device_t dev, uint32_t pin_num, char *name) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_getname); >+ rc = ((gpio_pin_getname_t *) _m)(dev, pin_num, name); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_SETFLAGS() method */ >+extern struct kobjop_desc gpio_pin_setflags_desc; >+/** @brief A function implementing the GPIO_PIN_SETFLAGS() method */ >+typedef int gpio_pin_setflags_t(device_t dev, uint32_t pin_num, uint32_t flags); >+ >+static __inline int GPIO_PIN_SETFLAGS(device_t dev, uint32_t pin_num, >+ uint32_t flags) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_setflags); >+ rc = ((gpio_pin_setflags_t *) _m)(dev, pin_num, flags); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_MAP_GPIOS() method */ >+extern struct kobjop_desc gpio_map_gpios_desc; >+/** @brief A function implementing the GPIO_MAP_GPIOS() method */ >+typedef int gpio_map_gpios_t(device_t bus, phandle_t dev, phandle_t gparent, >+ int gcells, pcell_t *gpios, uint32_t *pin, >+ uint32_t *flags); >+ >+static __inline int GPIO_MAP_GPIOS(device_t bus, phandle_t dev, >+ phandle_t gparent, int gcells, >+ pcell_t *gpios, uint32_t *pin, >+ uint32_t *flags) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)bus)->ops,gpio_map_gpios); >+ rc = ((gpio_map_gpios_t *) _m)(bus, dev, gparent, gcells, gpios, pin, flags); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_ACCESS_32() method */ >+extern struct kobjop_desc gpio_pin_access_32_desc; >+/** @brief A function implementing the GPIO_PIN_ACCESS_32() method */ >+typedef int gpio_pin_access_32_t(device_t dev, uint32_t first_pin, >+ uint32_t clear_pins, uint32_t change_pins, >+ uint32_t *orig_pins); >+ >+static __inline int GPIO_PIN_ACCESS_32(device_t dev, uint32_t first_pin, >+ uint32_t clear_pins, >+ uint32_t change_pins, >+ uint32_t *orig_pins) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_access_32); >+ rc = ((gpio_pin_access_32_t *) _m)(dev, first_pin, clear_pins, change_pins, orig_pins); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the GPIO_PIN_CONFIG_32() method */ >+extern struct kobjop_desc gpio_pin_config_32_desc; >+/** @brief A function implementing the GPIO_PIN_CONFIG_32() method */ >+typedef int gpio_pin_config_32_t(device_t dev, uint32_t first_pin, >+ uint32_t num_pins, uint32_t *pin_flags); >+ >+static __inline int GPIO_PIN_CONFIG_32(device_t dev, uint32_t first_pin, >+ uint32_t num_pins, uint32_t *pin_flags) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)dev)->ops,gpio_pin_config_32); >+ rc = ((gpio_pin_config_32_t *) _m)(dev, first_pin, num_pins, pin_flags); >+ return (rc); >+} >+ >+#endif /* _gpio_if_h_ */ >diff -ruN drvGPIOIITK.orig/gpioiitk.c drvGPIOIITK/gpioiitk.c >--- drvGPIOIITK.orig/gpioiitk.c 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/gpioiitk.c 2020-11-26 04:44:40.316838000 +0100 >@@ -0,0 +1,454 @@ >+/*- >+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD >+ * >+ * Copyright (c) 2019 Oskar Holmlund. >+ * >+ * 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, 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 AND CONTRIBUTORS ``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. >+ * >+ * GPIO input interrupt to kevent. >+ * >+ * DTS example check out BB-GPIOIITK.dts >+ * >+ * Inspired by GSoC 2018 User space interface for GPIO interrupts >+ * by Christian Krämer >+ * >+ * $FreeBSD$ >+ */ >+ >+#include <sys/cdefs.h> >+__FBSDID("$FreeBSD$"); >+ >+#include <sys/param.h> >+#include <sys/module.h> >+#include <sys/kernel.h> >+#include <sys/systm.h> >+#include <sys/conf.h> >+#include <sys/uio.h> >+#include <sys/bus.h> >+#include <sys/mutex.h> >+#include <sys/gpio.h> >+#include <sys/event.h> >+ >+#include <dev/gpio/gpiobusvar.h> >+#include <dev/fdt/fdt_common.h> >+#include <dev/ofw/ofw_bus_subr.h> >+#include <dev/ofw/openfirm.h> >+ >+#include "gpio_if.h" >+#include "gpioiitk_ioctl.h" >+ >+#define GPIOIITK_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) >+#define GPIOIITK_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) >+#define GPIOIITK_LOCK_INIT(_sc) \ >+ mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_device), \ >+ "gpio_mux", MTX_DEF) >+#define GPIOIITK_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); >+#define GPIOIITK_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); >+#define GPIOIITK_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); >+ >+/* Defines for the ofw_compat_data table */ >+#define GPIOIITK 0x01 >+#define GPIOIITK_END 0x00 >+ >+static d_open_t gpioiitk_open; >+static d_close_t gpioiitk_close; >+static d_ioctl_t gpioiitk_ioctl; >+static d_kqfilter_t gpioiitk_kqfilter; >+ >+static int gpioiitk_kqread(struct knote*, long); >+static void gpioiitk_kqdetach(struct knote*); >+static void input_intr(void *); >+static int gpioiitk_detach(device_t); >+ >+static struct cdevsw gpioiitk_cdevsw = { >+ .d_version = D_VERSION, >+ .d_open = gpioiitk_open, >+ .d_close = gpioiitk_close, >+ .d_ioctl = gpioiitk_ioctl, >+ .d_kqfilter = gpioiitk_kqfilter, >+ .d_name = GPIOIITK_NAME >+}; >+ >+static struct filterops gpioiitk_read_filterops = { >+ .f_isfd = true, >+ .f_attach = NULL, >+ .f_detach = gpioiitk_kqdetach, >+ .f_event = gpioiitk_kqread, >+ .f_touch = NULL >+}; >+ >+/* compatible */ >+static struct ofw_compat_data compat_data[] = { >+ { "gpioiitk", GPIOIITK }, >+ { NULL, GPIOIITK_END }, >+}; >+ >+#define MAX_INPUTS 10 >+struct gpio_input_softc; >+ >+struct gpio_input_pin { >+ struct gpio_input_softc *sc_parent; >+ >+ gpio_pin_t sc_pin; >+ int sc_irid; >+ struct resource *sc_ires; >+ void *sc_ihandler; >+ >+ uint16_t sc_counter; >+ bool sc_state; >+}; >+ >+struct gpio_input_softc { >+ struct mtx sc_mtx; >+ device_t sc_device; >+ >+ struct gpio_input_pin sc_inputs[MAX_INPUTS]; >+ uint8_t sc_num_inputs; >+ bool sc_changed; >+ >+ /* Character device interface */ >+ struct cdev *sc_cdev; >+ >+ /* Kernel events */ >+ struct knlist sc_note; >+}; >+ >+/* --- Device methods --- */ >+static int >+gpioiitk_probe(device_t dev) >+{ >+ const struct ofw_compat_data *compatible; >+ >+ if (!ofw_bus_status_okay(dev)) >+ return (ENXIO); >+ >+ compatible = ofw_bus_search_compatible(dev, compat_data); >+ >+ switch (compatible->ocd_data) { >+ case GPIOIITK_END: >+ return (ENXIO); >+ case GPIOIITK: >+ device_set_desc(dev, "GPIO Input Interrupt To Kevent"); >+ break; >+ } >+ >+ return (BUS_PROBE_DEFAULT); >+} >+ >+static int >+gpioiitk_attach(device_t dev) >+{ >+ struct gpio_input_softc *sc; >+ const struct ofw_compat_data *compatible; >+ int unit, err, pincaps, idx; >+ phandle_t node; >+ >+ sc = device_get_softc(dev); >+ sc->sc_device = dev; >+ GPIOIITK_LOCK_INIT(sc); >+ >+ knlist_init_mtx(&sc->sc_note, &sc->sc_mtx); >+ >+ /* Look at the dts again and grab the type */ >+ compatible = ofw_bus_search_compatible(sc->sc_device, compat_data); >+ >+ node = ofw_bus_get_node(sc->sc_device); >+ >+ for (idx = 0; idx < MAX_INPUTS; idx++) { >+ >+ /* ------ Get the pin ------ */ >+ err = gpio_pin_get_by_ofw_propidx(sc->sc_device, node, >+ "input-gpios", idx, &sc->sc_inputs[idx].sc_pin); >+ if (err != 0 && idx == 0) { >+ /* Error at the first pin */ >+ /* something are actually wrong */ >+ /* probably no pins in DTS */ >+ device_printf(sc->sc_device, "inputs[%d]: err %d\n", >+ idx, err); >+ break; >+ } else if (err != 0) { >+ /* Error later on indicates the last pin are found */ >+ err = 0; >+ >+ /* sc_num_inputs are total number of pins >+ (not 0-index based) */ >+ sc->sc_num_inputs = idx; >+ break; >+ } >+ >+ >+ /* Check the state of the gpio pin */ >+ err = GPIO_PIN_GETFLAGS(sc->sc_inputs[idx].sc_pin->dev, >+ sc->sc_inputs[idx].sc_pin->pin, &pincaps); >+ if (err != 0) { >+ device_printf(dev, "Failed to get pin flags gpio[%d]\n", >+ idx); >+ break; >+ } >+ >+ /* Ensure the pin are in INPUT mode */ >+ if (!(pincaps & GPIO_PIN_INPUT)) { >+ device_printf(dev, "pin[%x] IS NOT in input mode\n", >+ idx); >+ err = 1; >+ break; >+ } >+ >+ /* Allocate interrupt resource */ >+ /* Available options are: >+ * GPIO_INTR_EDGE_BOTH >+ * GPIO_INTR_EDGE_FALLING >+ * GPIO_INTR_EDGE_RISING >+ * >+ * Set this in DTS? >+ */ >+ sc->sc_inputs[idx].sc_ires = gpio_alloc_intr_resource( >+ sc->sc_device, &sc->sc_inputs[idx].sc_irid, RF_ACTIVE, >+ sc->sc_inputs[idx].sc_pin, GPIO_INTR_EDGE_BOTH); >+ if (sc->sc_inputs[idx].sc_ires == NULL) { >+ device_printf(sc->sc_device, "Cannot allocate IRQ\n"); >+ err = 1; >+ break; >+ } >+ >+ /* Attach to interrupt handler function */ >+ err = bus_setup_intr(sc->sc_device, sc->sc_inputs[idx].sc_ires, >+ INTR_TYPE_BIO | INTR_MPSAFE, NULL, input_intr, >+ &sc->sc_inputs[idx], &sc->sc_inputs[idx].sc_ihandler); >+ if (err != 0) { >+ device_printf(sc->sc_device, "Unable to setup IRQ\n"); >+ break; >+ } >+ >+ sc->sc_inputs[idx].sc_counter = 0; >+ sc->sc_inputs[idx].sc_parent = sc; >+ gpio_pin_is_active(sc->sc_inputs[idx].sc_pin, >+ &sc->sc_inputs[idx].sc_state); >+ } >+ >+ if (err != 0) { >+ /* -- Free allocated resource -- */ >+ gpioiitk_detach(sc->sc_device); >+ return (ENXIO); >+ } >+ >+ /* -- Create device -- */ >+ unit = device_get_unit(sc->sc_device); >+ sc->sc_cdev = make_dev(&gpioiitk_cdevsw, unit, >+ UID_ROOT, GID_WHEEL, 0666, >+ "gpioiitk_%d", unit); >+ sc->sc_cdev->si_drv1 = sc; >+ >+ return (0); >+} >+ >+static int >+gpioiitk_detach(device_t dev) >+{ >+ struct gpio_input_softc *sc; >+ int idx; >+ >+ sc = device_get_softc(dev); >+ >+ if (sc->sc_cdev) >+ destroy_dev(sc->sc_cdev); >+ >+ /* Free input IRQ handler and pins */ >+ for (idx = 0; idx < MAX_INPUTS; idx++) { >+ if (sc->sc_inputs[idx].sc_ihandler) { >+ bus_teardown_intr(sc->sc_device, >+ sc->sc_inputs[idx].sc_ires, >+ sc->sc_inputs[idx].sc_ihandler); >+ } >+ if (sc->sc_inputs[idx].sc_pin) { >+ gpio_pin_release(sc->sc_inputs[idx].sc_pin); >+ } >+ if (sc->sc_inputs[idx].sc_ires) { >+ bus_release_resource(sc->sc_device, SYS_RES_IRQ, 0, >+ sc->sc_inputs[idx].sc_ires); >+ } >+ } >+ >+ KASSERT(mtx_initialized(&sc->sc_mtx), ("gpioiitk mtx not initialized")); >+ >+ GPIOIITK_LOCK_DESTROY(sc); >+ >+ return (0); >+} >+ >+static phandle_t >+gpioiitk_get_node(device_t bus, device_t dev) >+{ >+ struct gpio_input_softc *sc; >+ sc = device_get_softc(dev); >+ return (ofw_bus_get_node(bus)); >+} >+ >+/* >+ * Character device interface >+ */ >+ >+static int >+gpioiitk_open(struct cdev *dev, int oflags, int devtype, struct thread *td) >+{ >+ return 0; >+} >+ >+static int >+gpioiitk_close(struct cdev *dev, int fflags, int devtype, struct thread *td) >+{ >+ return 0; >+} >+ >+static int >+gpioiitk_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, >+ struct thread *td) >+{ >+ struct gpio_input_softc *sc = dev->si_drv1; >+ uint32_t *INx; >+ uint16_t *counter; >+ uint8_t idx; >+ >+ GPIOIITK_LOCK(sc); >+ switch (cmd) >+ { >+ case GPIOIITK_GET_COUNTER: >+ counter = (uint16_t *)data; >+ for (idx = 0; idx < sc->sc_num_inputs; idx++) { >+ counter[idx] = sc->sc_inputs[idx].sc_counter; >+ sc->sc_inputs[idx].sc_counter=0; >+ } >+ break; >+ >+ /* Get the cached state on all input pins */ >+ case GPIOIITK_GET_CACHE: >+ INx = (uint32_t *) data; >+ *INx = 0; >+ for (idx = 0; idx < sc->sc_num_inputs; idx++) { >+ *INx |= (uint32_t)(sc->sc_inputs[idx].sc_state << idx); >+ } >+ break; >+ >+ /* Refetch the input state from HW */ >+ case GPIOIITK_GET: >+ INx = (uint32_t *) data; >+ *INx = 0; >+ for (idx = 0; idx < sc->sc_num_inputs; idx++) { >+ gpio_pin_is_active(sc->sc_inputs[idx].sc_pin, >+ &sc->sc_inputs[idx].sc_state); >+ *INx |= (uint32_t)(sc->sc_inputs[idx].sc_state << idx); >+ } >+ break; >+ } >+ GPIOIITK_UNLOCK(sc); >+ >+ return 0; >+} >+ >+/* Interrupt handler for input pin */ >+static void >+input_intr(void *arg) >+{ >+ struct gpio_input_pin *input = (struct gpio_input_pin *)arg; >+ >+ GPIOIITK_LOCK(input->sc_parent); >+ gpio_pin_is_active(input->sc_pin, &input->sc_state); >+ input->sc_parent->sc_changed = true; >+ input->sc_counter++; >+ >+ KNOTE_LOCKED(&input->sc_parent->sc_note, 1); >+ GPIOIITK_UNLOCK(input->sc_parent); >+} >+ >+static int >+gpioiitk_kqfilter(struct cdev *dev, struct knote *kn) >+{ >+ struct gpio_input_softc *sc = dev->si_drv1; >+ >+ switch(kn->kn_filter) { >+ case EVFILT_READ: >+ kn->kn_fop = &gpioiitk_read_filterops; >+ kn->kn_hook = (void *)sc; >+ break; >+ default: >+ return (EOPNOTSUPP); >+ } >+ >+ knlist_add(&sc->sc_note, kn, 0); >+ >+ return (0); >+} >+ >+static int >+gpioiitk_kqread(struct knote *kn, long hint) >+{ >+ struct gpio_input_softc *sc = kn->kn_hook; >+ int ret; >+ >+ kn->kn_data = >+ (sc->sc_inputs[0].sc_state) | >+ (sc->sc_inputs[1].sc_state<<1) | >+ (sc->sc_inputs[2].sc_state<<2) | >+ (sc->sc_inputs[3].sc_state<<3) | >+ (sc->sc_inputs[4].sc_state<<4) | >+ (sc->sc_inputs[5].sc_state<<5) | >+ (sc->sc_inputs[6].sc_state<<6) | >+ (sc->sc_inputs[7].sc_state<<7) | >+ (sc->sc_inputs[8].sc_state<<8) | >+ (sc->sc_inputs[9].sc_state<<9); >+ >+ ret = sc->sc_changed; >+ if (hint == 0) >+ sc->sc_changed = false; >+ >+ return (ret); >+} >+ >+static void >+gpioiitk_kqdetach(struct knote *kn) >+{ >+ struct gpio_input_softc *sc = kn->kn_hook; >+ >+ knlist_remove(&sc->sc_note, kn, 0); >+} >+ >+static device_method_t gpioiitk_methods[] = { >+ /* Device interface */ >+ DEVMETHOD(device_probe, gpioiitk_probe), >+ DEVMETHOD(device_attach, gpioiitk_attach), >+ DEVMETHOD(device_detach, gpioiitk_detach), >+ >+ /* ofw_bus interface */ >+ DEVMETHOD(ofw_bus_get_node, gpioiitk_get_node), >+ >+ DEVMETHOD_END >+}; >+ >+static devclass_t gpioiitk_devclass; >+ >+DEFINE_CLASS_0(gpioiitk, gpioiitk_driver, gpioiitk_methods, >+ sizeof(struct gpio_input_softc)); >+ >+DRIVER_MODULE(gpioiitk, ofwbus, gpioiitk_driver, gpioiitk_devclass, NULL, NULL); >+DRIVER_MODULE(gpioiitk, simplebus, gpioiitk_driver, gpioiitk_devclass, >+ NULL, NULL); >+MODULE_DEPEND(gpioiitk, gpiobus, 1, 1, 1); >+ >diff -ruN drvGPIOIITK.orig/gpioiitk_ioctl.h drvGPIOIITK/gpioiitk_ioctl.h >--- drvGPIOIITK.orig/gpioiitk_ioctl.h 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/gpioiitk_ioctl.h 2020-11-26 04:44:40.316930000 +0100 >@@ -0,0 +1,38 @@ >+/*- >+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD >+ * >+ * Copyright (c) 2019 Oskar Holmlund. >+ * >+ * 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, 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 AND CONTRIBUTORS ``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. >+ */ >+ >+#ifndef __GPIOIITK_IOCTL__ >+#define __GPIOIITK_IOCTL__ >+ >+#include <sys/stdint.h> >+ >+#define GPIOIITK_NAME "gpioiitk" >+ >+#define GPIOIITK_GET _IOR('b', 1, uint32_t) >+#define GPIOIITK_GET_CACHE _IOR('b', 2, uint32_t) >+#define GPIOIITK_GET_COUNTER _IOR('b', 3, uint16_t[10]) >+ >+#endif /* __GPIOIITK_IOCTL__ */ >diff -ruN drvGPIOIITK.orig/ofw_bus_if.h drvGPIOIITK/ofw_bus_if.h >--- drvGPIOIITK.orig/ofw_bus_if.h 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/ofw_bus_if.h 2020-11-26 04:44:40.316871000 +0100 >@@ -0,0 +1,130 @@ >+/* >+ * This file is @generated automatically. >+ * Do not modify anything in here by hand. >+ * >+ * Created from source file >+ * /usr/src/sys/dev/ofw/ofw_bus_if.m >+ * with >+ * makeobjops.awk >+ * >+ * See the source file for legal information >+ */ >+ >+ >+#ifndef _ofw_bus_if_h_ >+#define _ofw_bus_if_h_ >+ >+ >+struct ofw_bus_devinfo { >+ phandle_t obd_node; >+ char *obd_compat; >+ char *obd_model; >+ char *obd_name; >+ char *obd_type; >+ char *obd_status; >+}; >+ >+/** @brief Unique descriptor for the OFW_BUS_GET_DEVINFO() method */ >+extern struct kobjop_desc ofw_bus_get_devinfo_desc; >+/** @brief A function implementing the OFW_BUS_GET_DEVINFO() method */ >+typedef const struct ofw_bus_devinfo * ofw_bus_get_devinfo_t(device_t bus, >+ device_t dev); >+ >+static __inline const struct ofw_bus_devinfo * OFW_BUS_GET_DEVINFO(device_t bus, >+ device_t dev) >+{ >+ kobjop_t _m; >+ const struct ofw_bus_devinfo * rc; >+ KOBJOPLOOKUP(((kobj_t)bus)->ops,ofw_bus_get_devinfo); >+ rc = ((ofw_bus_get_devinfo_t *) _m)(bus, dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the OFW_BUS_GET_COMPAT() method */ >+extern struct kobjop_desc ofw_bus_get_compat_desc; >+/** @brief A function implementing the OFW_BUS_GET_COMPAT() method */ >+typedef const char * ofw_bus_get_compat_t(device_t bus, device_t dev); >+ >+static __inline const char * OFW_BUS_GET_COMPAT(device_t bus, device_t dev) >+{ >+ kobjop_t _m; >+ const char * rc; >+ KOBJOPLOOKUP(((kobj_t)bus)->ops,ofw_bus_get_compat); >+ rc = ((ofw_bus_get_compat_t *) _m)(bus, dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the OFW_BUS_GET_MODEL() method */ >+extern struct kobjop_desc ofw_bus_get_model_desc; >+/** @brief A function implementing the OFW_BUS_GET_MODEL() method */ >+typedef const char * ofw_bus_get_model_t(device_t bus, device_t dev); >+ >+static __inline const char * OFW_BUS_GET_MODEL(device_t bus, device_t dev) >+{ >+ kobjop_t _m; >+ const char * rc; >+ KOBJOPLOOKUP(((kobj_t)bus)->ops,ofw_bus_get_model); >+ rc = ((ofw_bus_get_model_t *) _m)(bus, dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the OFW_BUS_GET_NAME() method */ >+extern struct kobjop_desc ofw_bus_get_name_desc; >+/** @brief A function implementing the OFW_BUS_GET_NAME() method */ >+typedef const char * ofw_bus_get_name_t(device_t bus, device_t dev); >+ >+static __inline const char * OFW_BUS_GET_NAME(device_t bus, device_t dev) >+{ >+ kobjop_t _m; >+ const char * rc; >+ KOBJOPLOOKUP(((kobj_t)bus)->ops,ofw_bus_get_name); >+ rc = ((ofw_bus_get_name_t *) _m)(bus, dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the OFW_BUS_GET_NODE() method */ >+extern struct kobjop_desc ofw_bus_get_node_desc; >+/** @brief A function implementing the OFW_BUS_GET_NODE() method */ >+typedef phandle_t ofw_bus_get_node_t(device_t bus, device_t dev); >+ >+static __inline phandle_t OFW_BUS_GET_NODE(device_t bus, device_t dev) >+{ >+ kobjop_t _m; >+ phandle_t rc; >+ KOBJOPLOOKUP(((kobj_t)bus)->ops,ofw_bus_get_node); >+ rc = ((ofw_bus_get_node_t *) _m)(bus, dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the OFW_BUS_GET_TYPE() method */ >+extern struct kobjop_desc ofw_bus_get_type_desc; >+/** @brief A function implementing the OFW_BUS_GET_TYPE() method */ >+typedef const char * ofw_bus_get_type_t(device_t bus, device_t dev); >+ >+static __inline const char * OFW_BUS_GET_TYPE(device_t bus, device_t dev) >+{ >+ kobjop_t _m; >+ const char * rc; >+ KOBJOPLOOKUP(((kobj_t)bus)->ops,ofw_bus_get_type); >+ rc = ((ofw_bus_get_type_t *) _m)(bus, dev); >+ return (rc); >+} >+ >+/** @brief Unique descriptor for the OFW_BUS_MAP_INTR() method */ >+extern struct kobjop_desc ofw_bus_map_intr_desc; >+/** @brief A function implementing the OFW_BUS_MAP_INTR() method */ >+typedef int ofw_bus_map_intr_t(device_t bus, device_t dev, phandle_t iparent, >+ int icells, pcell_t *interrupt); >+ >+static __inline int OFW_BUS_MAP_INTR(device_t bus, device_t dev, >+ phandle_t iparent, int icells, >+ pcell_t *interrupt) >+{ >+ kobjop_t _m; >+ int rc; >+ KOBJOPLOOKUP(((kobj_t)bus)->ops,ofw_bus_map_intr); >+ rc = ((ofw_bus_map_intr_t *) _m)(bus, dev, iparent, icells, interrupt); >+ return (rc); >+} >+ >+#endif /* _ofw_bus_if_h_ */ >diff -ruN drvGPIOIITK.orig/opt_platform.h drvGPIOIITK/opt_platform.h >--- drvGPIOIITK.orig/opt_platform.h 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/opt_platform.h 2020-11-26 04:44:40.316901000 +0100 >@@ -0,0 +1,2 @@ >+#define FDT 1 >+#define EFI 1 >diff -ruN drvGPIOIITK.orig/test.c drvGPIOIITK/test.c >--- drvGPIOIITK.orig/test.c 1970-01-01 01:00:00.000000000 +0100 >+++ drvGPIOIITK/test.c 2020-11-26 04:44:40.316960000 +0100 >@@ -0,0 +1,94 @@ >+#include <stdio.h> >+#include <fcntl.h> >+#include <unistd.h> >+#include <stdlib.h> >+#include <string.h> >+#include <errno.h> >+#include <err.h> >+#include <inttypes.h> >+ >+#include <sys/ioctl.h> >+#include <sys/types.h> >+#include <sys/select.h> >+#include <sys/event.h> >+ >+#include "gpioiitk_ioctl.h" >+ >+int main(int argc, char **argv) { >+ >+ struct kevent event[1]; >+ struct kevent tevent[1]; >+ int kq = -1; >+ int nev = -1; >+ struct timespec tv; >+ struct timespec *tv_ptr; >+ int res; >+ >+ tv.tv_sec = 2; >+ tv.tv_nsec = 0; >+ tv_ptr = &tv; >+ >+ uint32_t status; >+ uint16_t counters[10]; >+ int fd,ret, loop; >+ char device[32]; >+ snprintf(device, sizeof(device), "/dev/gpioiitk_%d", 0); >+ >+ fd = open(device, O_RDONLY); >+ if (fd < 0) { >+ printf("Failed to open device\n"); >+ return (1); >+ } >+ >+ ret = ioctl(fd, GPIOIITK_GET, &status); >+ if (ret < 0) { >+ close(fd); >+ printf("ioctl(GPIOIITK_GET)\n"); >+ return (1); >+ } >+ >+ printf("status: %x\n", status); >+ >+ ret = ioctl(fd, GPIOIITK_GET_COUNTER, counters); >+ if (ret < 0) { >+ close(fd); >+ printf("ioctl(GPIOIITK_GET_COUNTER)\n"); >+ return (1); >+ } >+ printf("counters[0]: %d\n", counters[0]); >+ printf("counters[1]: %d\n", counters[1]); >+ printf("counters[2]: %d\n", counters[2]); >+ >+ kq = kqueue(); >+ if (kq == -1) { >+ close(fd); >+ printf("kqueue()"); >+ return (1); >+ } >+ >+ EV_SET(&event[0], fd, EVFILT_READ, EV_ADD, 0, 0, NULL); >+ nev = kevent(kq, event, 1, NULL, 0, NULL); >+ if (nev == -1) { >+ printf("kevent()"); >+ close(fd); >+ return (1); >+ } >+ >+ while (1) { >+ nev = kevent(kq, NULL, 0, tevent, 1, tv_ptr); >+ if (nev == -1) { >+ printf("kevent()\n"); >+ break; >+ } else if (nev > 0) { >+ printf("keveturned %i events (flags: %d data %" PRIu64 ")\n", >+ nev, tevent[0].flags, tevent[0].data); >+ if (tevent[0].flags & EV_EOF) { >+ printf("Recieved EV_EOF\n"); >+ break; >+ } >+ } >+ } >+ >+ close(fd); >+ return (0); >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 251390
: 219983