1
0
Fork 0
alistair23-linux/drivers/staging/gasket/gasket_sysfs.h

180 lines
6.1 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Set of common sysfs utilities.
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
*
* Copyright (C) 2018 Google, Inc.
*/
/* The functions described here are a set of utilities to allow each file in the
* Gasket driver framework to manage their own set of sysfs entries, instead of
* centralizing all that work in one file.
*
* The goal of these utilities is to allow for sysfs entries to be easily
* created without causing a proliferation of sysfs "show" functions. This
* requires O(N) string lookups during show function execution, but as reading
* sysfs entries is rarely performance-critical, this is likely acceptible.
*/
#ifndef __GASKET_SYSFS_H__
#define __GASKET_SYSFS_H__
#include "gasket_constants.h"
#include "gasket_core.h"
#include <linux/device.h>
#include <linux/stringify.h>
#include <linux/sysfs.h>
/* The maximum number of mappings/devices a driver needs to support. */
#define GASKET_SYSFS_NUM_MAPPINGS (GASKET_FRAMEWORK_DESC_MAX * GASKET_DEV_MAX)
/* The maximum number of sysfs nodes in a directory.
*/
#define GASKET_SYSFS_MAX_NODES 196
/* End markers for sysfs struct arrays. */
#define GASKET_ARRAY_END_TOKEN GASKET_RESERVED_ARRAY_END
#define GASKET_ARRAY_END_MARKER __stringify(GASKET_ARRAY_END_TOKEN)
/*
* Terminator struct for a gasket_sysfs_attr array. Must be at the end of
* all gasket_sysfs_attribute arrays.
*/
#define GASKET_END_OF_ATTR_ARRAY \
{ \
.attr = __ATTR_NULL, \
.data.attr_type = 0, \
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
}
/*
* Pairing of sysfs attribute and user data.
* Used in lookups in sysfs "show" functions to return attribute metadata.
*/
struct gasket_sysfs_attribute {
/* The underlying sysfs device attribute associated with this data. */
struct device_attribute attr;
/* User-specified data to associate with the attribute. */
union {
struct bar_address_ {
ulong bar;
ulong offset;
} bar_address;
uint attr_type;
} data;
/*
* Function pointer to a callback to be invoked when this attribute is
* written (if so configured). The arguments are to the Gasket device
* pointer, the enclosing gasket_attr structure, and the value written.
* The callback should perform any logging necessary, as errors cannot
* be returned from the callback.
*/
void (*write_callback)(struct gasket_dev *dev,
struct gasket_sysfs_attribute *attr,
ulong value);
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
};
#define GASKET_SYSFS_RO(_name, _show_function, _attr_type) \
{ \
.attr = __ATTR(_name, S_IRUGO, _show_function, NULL), \
.data.attr_type = _attr_type \
}
/* Initializes the Gasket sysfs subsystem.
*
* Description: Performs one-time initialization. Must be called before usage
* at [Gasket] module load time.
*/
void gasket_sysfs_init(void);
/*
* Create an entry in mapping_data between a device and a Gasket device.
* @device: Device struct to map to.
* @gasket_dev: The dev struct associated with the driver controlling @device.
*
* Description: This function maps a gasket_dev* to a device*. This mapping can
* be used in sysfs_show functions to get a handle to the gasket_dev struct
* controlling the device node.
*
* If this function is not called before gasket_sysfs_create_entries, a warning
* will be logged.
*/
int gasket_sysfs_create_mapping(struct device *device,
struct gasket_dev *gasket_dev);
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
/*
* Creates bulk entries in sysfs.
* @device: Kernel device structure.
* @attrs: List of attributes/sysfs entries to create.
*
* Description: Creates each sysfs entry described in "attrs". Can be called
* multiple times for a given @device. If the gasket_dev specified in
* gasket_sysfs_create_mapping had a legacy device, the entries will be created
* for it, as well.
*/
int gasket_sysfs_create_entries(struct device *device,
const struct gasket_sysfs_attribute *attrs);
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
/*
* Removes a device mapping from the global table.
* @device: Device to unmap.
*
* Description: Removes the device->Gasket device mapping from the internal
* table.
*/
void gasket_sysfs_remove_mapping(struct device *device);
/*
* User data lookup based on kernel device structure.
* @device: Kernel device structure.
*
* Description: Returns the user data associated with "device" in a prior call
* to gasket_sysfs_create_entries. Returns NULL if no mapping can be found.
* Upon success, this call take a reference to internal sysfs data that must be
* released with gasket_sysfs_put_device_data. While this reference is held, the
* underlying device sysfs information/structure will remain valid/will not be
* deleted.
*/
struct gasket_dev *gasket_sysfs_get_device_data(struct device *device);
/*
* Releases a references to internal data.
* @device: Kernel device structure.
* @dev: Gasket device descriptor (returned by gasket_sysfs_get_device_data).
*/
void gasket_sysfs_put_device_data(struct device *device,
struct gasket_dev *gasket_dev);
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
/*
* Gasket-specific attribute lookup.
* @device: Kernel device structure.
* @attr: Device attribute to look up.
*
* Returns the Gasket sysfs attribute associated with the kernel device
* attribute and device structure itself. Upon success, this call will take a
* reference to internal sysfs data that must be released with a call to
* gasket_sysfs_put_attr. While this reference is held, the underlying device
* sysfs information/structure will remain valid/will not be deleted.
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
*/
struct gasket_sysfs_attribute *
gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr);
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
/*
* Releases a references to internal data.
* @device: Kernel device structure.
* @attr: Gasket sysfs attribute descriptor (returned by
* gasket_sysfs_get_attr).
*/
void gasket_sysfs_put_attr(struct device *device,
struct gasket_sysfs_attribute *attr);
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
/*
* Write to a register sysfs node.
* @buf: NULL-terminated data being written.
* @count: number of bytes in the "buf" argument.
*/
ssize_t gasket_sysfs_register_store(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count);
drivers/staging: Gasket driver framework + Apex driver The Gasket (Google ASIC Software, Kernel Extensions, and Tools) kernel framework is a generic, flexible system that supports thin kernel drivers. Gasket kernel drivers are expected to handle opening and closing devices, mmap'ing BAR space as requested, a small selection of ioctls, and handling page table translation (covered below). Any other functions should be handled by userspace code. The Gasket common module is not enough to run a device. In order to customize the Gasket code for a given piece of hardware, a device specific module must be created. At a minimum, this module must define a struct gasket_driver_desc containing the device-specific data for use by the framework; in addition, the module must declare an __init function that calls gasket_register_device with the module's gasket_driver_desc struct. Finally, the driver must define an exit function that calls gasket_unregister_device with the module's gasket_driver_desc struct. One of the core assumptions of the Gasket framework is that precisely one process is allowed to have an open write handle to the device node at any given time. (That process may, once it has one write handle, open any number of additional write handles.) This is accomplished by tracking open and close data for each driver instance. Signed-off-by: Rob Springer <rspringer@google.com> Signed-off-by: John Joseph <jnjoseph@google.com> Signed-off-by: Simon Que <sque@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-06-29 20:49:38 -06:00
#endif /* __GASKET_SYSFS_H__ */