linux/drivers/hid/hid-core.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  HID support for Linux
 *
 *  Copyright (c) 1999 Andreas Gal
 *  Copyright (c) 2000-2005 Vojtech Pavlik <[email protected]>
 *  Copyright (c) 2005 Michael Haboustak <[email protected]> for Concept2, Inc
 *  Copyright (c) 2006-2012 Jiri Kosina
 */

/*
 */

#define pr_fmt(fmt)

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>
#include <linux/input.h>
#include <linux/wait.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/semaphore.h>

#include <linux/hid.h>
#include <linux/hiddev.h>
#include <linux/hid-debug.h>
#include <linux/hidraw.h>

#include "hid-ids.h"

/*
 * Version Information
 */

#define DRIVER_DESC

static int hid_ignore_special_drivers =;
module_param_named(ignore_special_drivers, hid_ignore_special_drivers, int, 0600);
MODULE_PARM_DESC();

/*
 * Register a new report for a device.
 */

struct hid_report *hid_register_report(struct hid_device *device,
				       enum hid_report_type type, unsigned int id,
				       unsigned int application)
{}
EXPORT_SYMBOL_GPL();

/*
 * Register a new field for this report.
 */

static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages)
{}

/*
 * Open a collection. The type/usage is pushed on the stack.
 */

static int open_collection(struct hid_parser *parser, unsigned type)
{}

/*
 * Close a collection.
 */

static int close_collection(struct hid_parser *parser)
{}

/*
 * Climb up the stack, search for the specified collection type
 * and return the usage.
 */

static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
{}

/*
 * Concatenate usage which defines 16 bits or less with the
 * currently defined usage page to form a 32 bit usage
 */

static void complete_usage(struct hid_parser *parser, unsigned int index)
{}

/*
 * Add a usage to the temporary parser table.
 */

static int hid_add_usage(struct hid_parser *parser, unsigned usage, u8 size)
{}

/*
 * Register a new field for this report.
 */

static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags)
{}

/*
 * Read data value from item.
 */

static u32 item_udata(struct hid_item *item)
{}

static s32 item_sdata(struct hid_item *item)
{}

/*
 * Process a global item.
 */

static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
{}

/*
 * Process a local item.
 */

static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
{}

/*
 * Concatenate Usage Pages into Usages where relevant:
 * As per specification, 6.2.2.8: "When the parser encounters a main item it
 * concatenates the last declared Usage Page with a Usage to form a complete
 * usage value."
 */

static void hid_concatenate_last_usage_page(struct hid_parser *parser)
{}

/*
 * Process a main item.
 */

static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
{}

/*
 * Process a reserved item.
 */

static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
{}

/*
 * Free a report and all registered fields. The field->usage and
 * field->value table's are allocated behind the field, so we need
 * only to free(field) itself.
 */

static void hid_free_report(struct hid_report *report)
{}

/*
 * Close report. This function returns the device
 * state to the point prior to hid_open_report().
 */
static void hid_close_report(struct hid_device *device)
{}

/*
 * Free a device structure, all reports, and all fields.
 */

void hiddev_free(struct kref *ref)
{}

static void hid_device_release(struct device *dev)
{}

/*
 * Fetch a report description item from the data stream. We support long
 * items, though they are not used yet.
 */

static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
{}

static void hid_scan_input_usage(struct hid_parser *parser, u32 usage)
{}

static void hid_scan_feature_usage(struct hid_parser *parser, u32 usage)
{}

static void hid_scan_collection(struct hid_parser *parser, unsigned type)
{}

static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
{}

/*
 * Scan a report descriptor before the device is added to the bus.
 * Sets device groups and other properties that determine what driver
 * to load.
 */
static int hid_scan_report(struct hid_device *hid)
{}

/**
 * hid_parse_report - parse device report
 *
 * @hid: hid device
 * @start: report start
 * @size: report size
 *
 * Allocate the device report as read by the bus driver. This function should
 * only be called from parse() in ll drivers.
 */
int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size)
{}
EXPORT_SYMBOL_GPL();

static const char * const hid_report_names[] =;
/**
 * hid_validate_values - validate existing device report's value indexes
 *
 * @hid: hid device
 * @type: which report type to examine
 * @id: which report ID to examine (0 for first)
 * @field_index: which report field to examine
 * @report_counts: expected number of values
 *
 * Validate the number of values in a given field of a given report, after
 * parsing.
 */
struct hid_report *hid_validate_values(struct hid_device *hid,
				       enum hid_report_type type, unsigned int id,
				       unsigned int field_index,
				       unsigned int report_counts)
{}
EXPORT_SYMBOL_GPL();

static int hid_calculate_multiplier(struct hid_device *hid,
				     struct hid_field *multiplier)
{}

static void hid_apply_multiplier_to_field(struct hid_device *hid,
					  struct hid_field *field,
					  struct hid_collection *multiplier_collection,
					  int effective_multiplier)
{}

static void hid_apply_multiplier(struct hid_device *hid,
				 struct hid_field *multiplier)
{}

/*
 * hid_setup_resolution_multiplier - set up all resolution multipliers
 *
 * @device: hid device
 *
 * Search for all Resolution Multiplier Feature Reports and apply their
 * value to all matching Input items. This only updates the internal struct
 * fields.
 *
 * The Resolution Multiplier is applied by the hardware. If the multiplier
 * is anything other than 1, the hardware will send pre-multiplied events
 * so that the same physical interaction generates an accumulated
 *	accumulated_value = value * * multiplier
 * This may be achieved by sending
 * - "value * multiplier" for each event, or
 * - "value" but "multiplier" times as frequently, or
 * - a combination of the above
 * The only guarantee is that the same physical interaction always generates
 * an accumulated 'value * multiplier'.
 *
 * This function must be called before any event processing and after
 * any SetRequest to the Resolution Multiplier.
 */
void hid_setup_resolution_multiplier(struct hid_device *hid)
{}
EXPORT_SYMBOL_GPL();

/**
 * hid_open_report - open a driver-specific device report
 *
 * @device: hid device
 *
 * Parse a report description into a hid_device structure. Reports are
 * enumerated, fields are attached to these reports.
 * 0 returned on success, otherwise nonzero error value.
 *
 * This function (or the equivalent hid_parse() macro) should only be
 * called from probe() in drivers, before starting the device.
 */
int hid_open_report(struct hid_device *device)
{}
EXPORT_SYMBOL_GPL();

/*
 * Convert a signed n-bit integer to signed 32-bit integer. Common
 * cases are done through the compiler, the screwed things has to be
 * done by hand.
 */

static s32 snto32(__u32 value, unsigned n)
{}

s32 hid_snto32(__u32 value, unsigned n)
{}
EXPORT_SYMBOL_GPL();

/*
 * Convert a signed 32-bit integer to a signed n-bit integer.
 */

static u32 s32ton(__s32 value, unsigned n)
{}

/*
 * Extract/implement a data field from/to a little endian report (bit array).
 *
 * Code sort-of follows HID spec:
 *     http://www.usb.org/developers/hidpage/HID1_11.pdf
 *
 * While the USB HID spec allows unlimited length bit fields in "report
 * descriptors", most devices never use more than 16 bits.
 * One model of UPS is claimed to report "LINEV" as a 32-bit field.
 * Search linux-kernel and linux-usb-devel archives for "hid-core extract".
 */

static u32 __extract(u8 *report, unsigned offset, int n)
{}

u32 hid_field_extract(const struct hid_device *hid, u8 *report,
			unsigned offset, unsigned n)
{}
EXPORT_SYMBOL_GPL();

/*
 * "implement" : set bits in a little endian bit stream.
 * Same concepts as "extract" (see comments above).
 * The data mangled in the bit stream remains in little endian
 * order the whole time. It make more sense to talk about
 * endianness of register values by considering a register
 * a "cached" copy of the little endian bit stream.
 */

static void __implement(u8 *report, unsigned offset, int n, u32 value)
{}

static void implement(const struct hid_device *hid, u8 *report,
		      unsigned offset, unsigned n, u32 value)
{}

/*
 * Search an array for a value.
 */

static int search(__s32 *array, __s32 value, unsigned n)
{}

/**
 * hid_match_report - check if driver's raw_event should be called
 *
 * @hid: hid device
 * @report: hid report to match against
 *
 * compare hid->driver->report_table->report_type to report->type
 */
static int hid_match_report(struct hid_device *hid, struct hid_report *report)
{}

/**
 * hid_match_usage - check if driver's event should be called
 *
 * @hid: hid device
 * @usage: usage to match against
 *
 * compare hid->driver->usage_table->usage_{type,code} to
 * usage->usage_{type,code}
 */
static int hid_match_usage(struct hid_device *hid, struct hid_usage *usage)
{}

static void hid_process_event(struct hid_device *hid, struct hid_field *field,
		struct hid_usage *usage, __s32 value, int interrupt)
{}

/*
 * Checks if the given value is valid within this field
 */
static inline int hid_array_value_is_valid(struct hid_field *field,
					   __s32 value)
{}

/*
 * Fetch the field from the data. The field content is stored for next
 * report processing (we do differential reporting to the layer).
 */
static void hid_input_fetch_field(struct hid_device *hid,
				  struct hid_field *field,
				  __u8 *data)
{}

/*
 * Process a received variable field.
 */

static void hid_input_var_field(struct hid_device *hid,
				struct hid_field *field,
				int interrupt)
{}

/*
 * Process a received array field. The field content is stored for
 * next report processing (we do differential reporting to the layer).
 */

static void hid_input_array_field(struct hid_device *hid,
				  struct hid_field *field,
				  int interrupt)
{}

/*
 * Analyse a received report, and fetch the data from it. The field
 * content is stored for next report processing (we do differential
 * reporting to the layer).
 */
static void hid_process_report(struct hid_device *hid,
			       struct hid_report *report,
			       __u8 *data,
			       int interrupt)
{}

/*
 * Insert a given usage_index in a field in the list
 * of processed usages in the report.
 *
 * The elements of lower priority score are processed
 * first.
 */
static void __hid_insert_field_entry(struct hid_device *hid,
				     struct hid_report *report,
				     struct hid_field_entry *entry,
				     struct hid_field *field,
				     unsigned int usage_index)
{}

static void hid_report_process_ordering(struct hid_device *hid,
					struct hid_report *report)
{}

static void hid_process_ordering(struct hid_device *hid)
{}

/*
 * Output the field into the report.
 */

static void hid_output_field(const struct hid_device *hid,
			     struct hid_field *field, __u8 *data)
{}

/*
 * Compute the size of a report.
 */
static size_t hid_compute_report_size(struct hid_report *report)
{}

/*
 * Create a report. 'data' has to be allocated using
 * hid_alloc_report_buf() so that it has proper size.
 */

void hid_output_report(struct hid_report *report, __u8 *data)
{}
EXPORT_SYMBOL_GPL();

/*
 * Allocator for buffer that is going to be passed to hid_output_report()
 */
u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
{}
EXPORT_SYMBOL_GPL();

/*
 * Set a field value. The report this field belongs to has to be
 * created and transferred to the device, to set this value in the
 * device.
 */

int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
{}
EXPORT_SYMBOL_GPL();

static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
		const u8 *data)
{}

/*
 * Implement a generic .request() callback, using .raw_request()
 * DO NOT USE in hid drivers directly, but through hid_hw_request instead.
 */
int __hid_request(struct hid_device *hid, struct hid_report *report,
		enum hid_class_request reqtype)
{}
EXPORT_SYMBOL_GPL();

int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
			 int interrupt)
{}
EXPORT_SYMBOL_GPL();


static int __hid_input_report(struct hid_device *hid, enum hid_report_type type,
			      u8 *data, u32 size, int interrupt, u64 source, bool from_bpf,
			      bool lock_already_taken)
{}

/**
 * hid_input_report - report data from lower layer (usb, bt...)
 *
 * @hid: hid device
 * @type: HID report type (HID_*_REPORT)
 * @data: report contents
 * @size: size of data parameter
 * @interrupt: distinguish between interrupt and control transfers
 *
 * This is data entry for lower layers.
 */
int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
		     int interrupt)
{}
EXPORT_SYMBOL_GPL();

bool hid_match_one_id(const struct hid_device *hdev,
		      const struct hid_device_id *id)
{}

const struct hid_device_id *hid_match_id(const struct hid_device *hdev,
		const struct hid_device_id *id)
{}
EXPORT_SYMBOL_GPL();

static const struct hid_device_id hid_hiddev_list[] =;

static bool hid_hiddev(struct hid_device *hdev)
{}


static ssize_t
read_report_descriptor(struct file *filp, struct kobject *kobj,
		struct bin_attribute *attr,
		char *buf, loff_t off, size_t count)
{}

static ssize_t
show_country(struct device *dev, struct device_attribute *attr,
		char *buf)
{}

static struct bin_attribute dev_bin_attr_report_desc =;

static const struct device_attribute dev_attr_country =;

int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
{}
EXPORT_SYMBOL_GPL();

void hid_disconnect(struct hid_device *hdev)
{}
EXPORT_SYMBOL_GPL();

/**
 * hid_hw_start - start underlying HW
 * @hdev: hid device
 * @connect_mask: which outputs to connect, see HID_CONNECT_*
 *
 * Call this in probe function *after* hid_parse. This will setup HW
 * buffers and start the device (if not defeirred to device open).
 * hid_hw_stop must be called if this was successful.
 */
int hid_hw_start(struct hid_device *hdev, unsigned int connect_mask)
{}
EXPORT_SYMBOL_GPL();

/**
 * hid_hw_stop - stop underlying HW
 * @hdev: hid device
 *
 * This is usually called from remove function or from probe when something
 * failed and hid_hw_start was called already.
 */
void hid_hw_stop(struct hid_device *hdev)
{}
EXPORT_SYMBOL_GPL();

/**
 * hid_hw_open - signal underlying HW to start delivering events
 * @hdev: hid device
 *
 * Tell underlying HW to start delivering events from the device.
 * This function should be called sometime after successful call
 * to hid_hw_start().
 */
int hid_hw_open(struct hid_device *hdev)
{}
EXPORT_SYMBOL_GPL();

/**
 * hid_hw_close - signal underlaying HW to stop delivering events
 *
 * @hdev: hid device
 *
 * This function indicates that we are not interested in the events
 * from this device anymore. Delivery of events may or may not stop,
 * depending on the number of users still outstanding.
 */
void hid_hw_close(struct hid_device *hdev)
{}
EXPORT_SYMBOL_GPL();

/**
 * hid_hw_request - send report request to device
 *
 * @hdev: hid device
 * @report: report to send
 * @reqtype: hid request type
 */
void hid_hw_request(struct hid_device *hdev,
		    struct hid_report *report, enum hid_class_request reqtype)
{}
EXPORT_SYMBOL_GPL();

int __hid_hw_raw_request(struct hid_device *hdev,
			 unsigned char reportnum, __u8 *buf,
			 size_t len, enum hid_report_type rtype,
			 enum hid_class_request reqtype,
			 u64 source, bool from_bpf)
{}

/**
 * hid_hw_raw_request - send report request to device
 *
 * @hdev: hid device
 * @reportnum: report ID
 * @buf: in/out data to transfer
 * @len: length of buf
 * @rtype: HID report type
 * @reqtype: HID_REQ_GET_REPORT or HID_REQ_SET_REPORT
 *
 * Return: count of data transferred, negative if error
 *
 * Same behavior as hid_hw_request, but with raw buffers instead.
 */
int hid_hw_raw_request(struct hid_device *hdev,
		       unsigned char reportnum, __u8 *buf,
		       size_t len, enum hid_report_type rtype, enum hid_class_request reqtype)
{}
EXPORT_SYMBOL_GPL();

int __hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len, u64 source,
			   bool from_bpf)
{}

/**
 * hid_hw_output_report - send output report to device
 *
 * @hdev: hid device
 * @buf: raw data to transfer
 * @len: length of buf
 *
 * Return: count of data transferred, negative if error
 */
int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_PM
int hid_driver_suspend(struct hid_device *hdev, pm_message_t state)
{}
EXPORT_SYMBOL_GPL();

int hid_driver_reset_resume(struct hid_device *hdev)
{}
EXPORT_SYMBOL_GPL();

int hid_driver_resume(struct hid_device *hdev)
{}
EXPORT_SYMBOL_GPL();
#endif /* CONFIG_PM */

struct hid_dynid {};

/**
 * new_id_store - add a new HID device ID to this driver and re-probe devices
 * @drv: target device driver
 * @buf: buffer for scanning device ID data
 * @count: input size
 *
 * Adds a new dynamic hid device ID to this driver,
 * and causes the driver to probe for all devices again.
 */
static ssize_t new_id_store(struct device_driver *drv, const char *buf,
		size_t count)
{}
static DRIVER_ATTR_WO(new_id);

static struct attribute *hid_drv_attrs[] =;
ATTRIBUTE_GROUPS();

static void hid_free_dynids(struct hid_driver *hdrv)
{}

const struct hid_device_id *hid_match_device(struct hid_device *hdev,
					     struct hid_driver *hdrv)
{}
EXPORT_SYMBOL_GPL();

static int hid_bus_match(struct device *dev, const struct device_driver *drv)
{}

/**
 * hid_compare_device_paths - check if both devices share the same path
 * @hdev_a: hid device
 * @hdev_b: hid device
 * @separator: char to use as separator
 *
 * Check if two devices share the same path up to the last occurrence of
 * the separator char. Both paths must exist (i.e., zero-length paths
 * don't match).
 */
bool hid_compare_device_paths(struct hid_device *hdev_a,
			      struct hid_device *hdev_b, char separator)
{}
EXPORT_SYMBOL_GPL();

static bool hid_check_device_match(struct hid_device *hdev,
				   struct hid_driver *hdrv,
				   const struct hid_device_id **id)
{}

static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
{}

static int hid_device_probe(struct device *dev)
{}

static void hid_device_remove(struct device *dev)
{}

static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
			     char *buf)
{}
static DEVICE_ATTR_RO(modalias);

static struct attribute *hid_dev_attrs[] =;
static struct bin_attribute *hid_dev_bin_attrs[] =;
static const struct attribute_group hid_dev_group =;
__ATTRIBUTE_GROUPS();

static int hid_uevent(const struct device *dev, struct kobj_uevent_env *env)
{}

const struct bus_type hid_bus_type =;
EXPORT_SYMBOL();

int hid_add_device(struct hid_device *hdev)
{}
EXPORT_SYMBOL_GPL();

/**
 * hid_allocate_device - allocate new hid device descriptor
 *
 * Allocate and initialize hid device, so that hid_destroy_device might be
 * used to free it.
 *
 * New hid_device pointer is returned on success, otherwise ERR_PTR encoded
 * error value.
 */
struct hid_device *hid_allocate_device(void)
{}
EXPORT_SYMBOL_GPL();

static void hid_remove_device(struct hid_device *hdev)
{}

/**
 * hid_destroy_device - free previously allocated device
 *
 * @hdev: hid device
 *
 * If you allocate hid_device through hid_allocate_device, you should ever
 * free by this function.
 */
void hid_destroy_device(struct hid_device *hdev)
{}
EXPORT_SYMBOL_GPL();


static int __hid_bus_reprobe_drivers(struct device *dev, void *data)
{}

static int __hid_bus_driver_added(struct device_driver *drv, void *data)
{}

static int __bus_removed_driver(struct device_driver *drv, void *data)
{}

int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
		const char *mod_name)
{}
EXPORT_SYMBOL_GPL();

void hid_unregister_driver(struct hid_driver *hdrv)
{}
EXPORT_SYMBOL_GPL();

int hid_check_keys_pressed(struct hid_device *hid)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_HID_BPF
static struct hid_ops __hid_ops =;
#endif

static int __init hid_init(void)
{}

static void __exit hid_exit(void)
{}

module_init();
module_exit(hid_exit);

MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();