^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2001 Paul Stewart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2001 Vojtech Pavlik
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * HID char devices, giving access to raw HID device events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Should you need to contact me, the author, you can do so either by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * e-mail - mail your message to Paul Stewart <stewart@wetlogic.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/hiddev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "usbhid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #ifdef CONFIG_USB_DYNAMIC_MINORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define HIDDEV_MINOR_BASE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define HIDDEV_MINORS 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define HIDDEV_MINOR_BASE 96
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define HIDDEV_MINORS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define HIDDEV_BUFFER_SIZE 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct hiddev_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct fasync_struct *fasync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct hiddev *hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct mutex thread_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Find a report, given the report's type and ID. The ID can be specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * indirectly by REPORT_ID_FIRST (which returns the first report of the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * type) or by (REPORT_ID_NEXT | old_id), which returns the next report of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * given type which follows old_id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static struct hid_report *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct hid_report_enum *report_enum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (rinfo->report_type < HID_REPORT_TYPE_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) rinfo->report_type > HID_REPORT_TYPE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) report_enum = hid->report_enum +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) (rinfo->report_type - HID_REPORT_TYPE_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) switch (flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case 0: /* Nothing to do -- report_id is already set correctly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case HID_REPORT_ID_FIRST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (list_empty(&report_enum->report_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) list = report_enum->report_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) report = list_entry(list, struct hid_report, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) rinfo->report_id = report->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) case HID_REPORT_ID_NEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) report = report_enum->report_id_hash[rid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (!report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) list = report->list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (list == &report_enum->report_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) report = list_entry(list, struct hid_report, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) rinfo->report_id = report->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return report_enum->report_id_hash[rinfo->report_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * Perform an exhaustive search of the report table for a usage, given its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * type and usage id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct hid_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct hid_report_enum *report_enum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct hid_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (uref->report_type < HID_REPORT_TYPE_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) uref->report_type > HID_REPORT_TYPE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) report_enum = hid->report_enum +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) (uref->report_type - HID_REPORT_TYPE_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) list_for_each_entry(report, &report_enum->report_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) for (i = 0; i < report->maxfield; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) field = report->field[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) for (j = 0; j < field->maxusage; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (field->usage[j].hid == uref->usage_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) uref->report_id = report->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) uref->field_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) uref->usage_index = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static void hiddev_send_event(struct hid_device *hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct hiddev_usage_ref *uref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct hiddev *hiddev = hid->hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct hiddev_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) spin_lock_irqsave(&hiddev->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) list_for_each_entry(list, &hiddev->list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (uref->field_index != HID_FIELD_INDEX_NONE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) (list->flags & HIDDEV_FLAG_REPORT) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) list->buffer[list->head] = *uref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) list->head = (list->head + 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) (HIDDEV_BUFFER_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) kill_fasync(&list->fasync, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) spin_unlock_irqrestore(&hiddev->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) wake_up_interruptible(&hiddev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * This is where hid.c calls into hiddev to pass an event that occurred over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * the interrupt pipe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct hid_usage *usage, __s32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned type = field->report_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct hiddev_usage_ref uref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) uref.report_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) uref.report_id = field->report->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) uref.field_index = field->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) uref.usage_index = (usage - field->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) uref.usage_code = usage->hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) uref.value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) hiddev_send_event(hid, &uref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) EXPORT_SYMBOL_GPL(hiddev_hid_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned type = report->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct hiddev_usage_ref uref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) memset(&uref, 0, sizeof(uref));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) uref.report_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) uref.report_id = report->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) uref.field_index = HID_FIELD_INDEX_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) hiddev_send_event(hid, &uref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * fasync file op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int hiddev_fasync(int fd, struct file *file, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct hiddev_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return fasync_helper(fd, file, on, &list->fasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * release file op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static int hiddev_release(struct inode * inode, struct file * file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct hiddev_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) spin_lock_irqsave(&list->hiddev->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) list_del(&list->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) mutex_lock(&list->hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!--list->hiddev->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (list->hiddev->exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) hid_hw_close(list->hiddev->hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) hid_hw_power(list->hiddev->hid, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) mutex_unlock(&list->hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) kfree(list->hiddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) vfree(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) mutex_unlock(&list->hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) vfree(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int __hiddev_open(struct hiddev *hiddev, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct hiddev_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) lockdep_assert_held(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) list = vzalloc(sizeof(*list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (!list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mutex_init(&list->thread_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) list->hiddev = hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!hiddev->open++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) error = hid_hw_power(hiddev->hid, PM_HINT_FULLON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) goto err_drop_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) error = hid_hw_open(hiddev->hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) goto err_normal_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) spin_lock_irq(&hiddev->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) list_add_tail(&list->node, &hiddev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) spin_unlock_irq(&hiddev->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) file->private_data = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) err_normal_power:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) hid_hw_power(hiddev->hid, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) err_drop_count:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) hiddev->open--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) vfree(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * open file op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static int hiddev_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct usb_interface *intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct hid_device *hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct hiddev *hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) intf = usbhid_find_interface(iminor(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (!intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) hid = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) hiddev = hid->hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) mutex_lock(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) res = hiddev->exist ? __hiddev_open(hiddev, file) : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) mutex_unlock(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * "write" file op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * "read" file op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct hiddev_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int event_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (count < event_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* lock against other threads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) retval = mutex_lock_interruptible(&list->thread_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) while (retval == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (list->head == list->tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) while (list->head == list->tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) retval = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (!list->hiddev->exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (file->f_flags & O_NONBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) retval = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* let O_NONBLOCK tasks run */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) mutex_unlock(&list->thread_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (mutex_lock_interruptible(&list->thread_lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) finish_wait(&list->hiddev->wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) finish_wait(&list->hiddev->wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mutex_unlock(&list->thread_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) while (list->head != list->tail &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) retval + event_size <= count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct hiddev_event event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) event.hid = list->buffer[list->tail].usage_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) event.value = list->buffer[list->tail].value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mutex_unlock(&list->thread_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) retval += sizeof(struct hiddev_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) (list->flags & HIDDEV_FLAG_REPORT) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mutex_unlock(&list->thread_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) retval += sizeof(struct hiddev_usage_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mutex_unlock(&list->thread_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * "poll" file op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * No kernel lock - fine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static __poll_t hiddev_poll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct hiddev_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) poll_wait(file, &list->hiddev->wait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (list->head != list->tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return EPOLLIN | EPOLLRDNORM | EPOLLOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!list->hiddev->exist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return EPOLLERR | EPOLLHUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * "ioctl" file op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct hid_device *hid = hiddev->hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct hiddev_report_info rinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct hiddev_usage_ref_multi *uref_multi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct hiddev_usage_ref *uref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct hid_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (!uref_multi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) uref = &uref_multi->uref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (copy_from_user(uref_multi, user_arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) sizeof(*uref_multi)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) goto fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (copy_from_user(uref, user_arg, sizeof(*uref)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) goto fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) case HIDIOCGUCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) rinfo.report_type = uref->report_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) rinfo.report_id = uref->report_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (uref->field_index >= report->maxfield)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) uref->field_index = array_index_nospec(uref->field_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) report->maxfield);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) field = report->field[uref->field_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (uref->usage_index >= field->maxusage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) uref->usage_index = array_index_nospec(uref->usage_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) field->maxusage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) uref->usage_code = field->usage[uref->usage_index].hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (copy_to_user(user_arg, uref, sizeof(*uref)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) goto goodreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (cmd != HIDIOCGUSAGE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) cmd != HIDIOCGUSAGES &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) uref->report_type == HID_REPORT_TYPE_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) field = hiddev_lookup_usage(hid, uref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (field == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) rinfo.report_type = uref->report_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) rinfo.report_id = uref->report_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (uref->field_index >= report->maxfield)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) uref->field_index = array_index_nospec(uref->field_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) report->maxfield);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) field = report->field[uref->field_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (cmd == HIDIOCGCOLLECTIONINDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (uref->usage_index >= field->maxusage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) uref->usage_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) array_index_nospec(uref->usage_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) field->maxusage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) } else if (uref->usage_index >= field->report_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) uref->usage_index + uref_multi->num_values >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) field->report_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) uref->usage_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) array_index_nospec(uref->usage_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) field->report_count -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) uref_multi->num_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) case HIDIOCGUSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (uref->usage_index >= field->report_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) uref->value = field->value[uref->usage_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (copy_to_user(user_arg, uref, sizeof(*uref)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) goto fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) goto goodreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case HIDIOCSUSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (uref->usage_index >= field->report_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) field->value[uref->usage_index] = uref->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) goto goodreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case HIDIOCGCOLLECTIONINDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) i = field->usage[uref->usage_index].collection_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) kfree(uref_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) case HIDIOCGUSAGES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) for (i = 0; i < uref_multi->num_values; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) uref_multi->values[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) field->value[uref->usage_index + i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (copy_to_user(user_arg, uref_multi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) sizeof(*uref_multi)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) goto fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) goto goodreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case HIDIOCSUSAGES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) for (i = 0; i < uref_multi->num_values; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) field->value[uref->usage_index + i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) uref_multi->values[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) goto goodreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) goodreturn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) kfree(uref_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) fault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) kfree(uref_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) kfree(uref_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct hid_device *hid = hiddev->hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct usb_device *dev = hid_to_usb_dev(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int idx, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (get_user(idx, (int __user *)user_arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct hiddev_list *list = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct hiddev *hiddev = list->hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct hid_device *hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct hiddev_collection_info cinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct hiddev_report_info rinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct hiddev_field_info finfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct hiddev_devinfo dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct hid_report *report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct hid_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) void __user *user_arg = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) int i, r = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* Called without BKL by compat methods so no BKL taken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) mutex_lock(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (!hiddev->exist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) r = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) goto ret_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) hid = hiddev->hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) case HIDIOCGVERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) r = put_user(HID_VERSION, (int __user *)arg) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case HIDIOCAPPLICATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (arg >= hid->maxapplication)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) for (i = 0; i < hid->maxcollection; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (hid->collection[i].type ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) HID_COLLECTION_APPLICATION && arg-- == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (i < hid->maxcollection)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) r = hid->collection[i].usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case HIDIOCGDEVINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct usb_device *dev = hid_to_usb_dev(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct usbhid_device *usbhid = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) memset(&dinfo, 0, sizeof(dinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) dinfo.bustype = BUS_USB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) dinfo.busnum = dev->bus->busnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) dinfo.devnum = dev->devnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) dinfo.ifnum = usbhid->ifnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dinfo.num_applications = hid->maxapplication;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) case HIDIOCGFLAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) r = put_user(list->flags, (int __user *)arg) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) case HIDIOCSFLAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int newflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (get_user(newflags, (int __user *)arg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) r = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if ((newflags & ~HIDDEV_FLAGS) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) (newflags & HIDDEV_FLAG_UREF) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) list->flags = newflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) case HIDIOCGSTRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) r = hiddev_ioctl_string(hiddev, cmd, user_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) case HIDIOCINITREPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) usbhid_init_reports(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) hiddev->initialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case HIDIOCGREPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) r = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) report = hiddev_lookup_report(hid, &rinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (report == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) hid_hw_request(hid, report, HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) hid_hw_wait(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) case HIDIOCSREPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) r = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) report = hiddev_lookup_report(hid, &rinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (report == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) hid_hw_request(hid, report, HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) hid_hw_wait(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) case HIDIOCGREPORTINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) r = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) report = hiddev_lookup_report(hid, &rinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (report == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) rinfo.num_fields = report->maxfield;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case HIDIOCGFIELDINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (copy_from_user(&finfo, user_arg, sizeof(finfo))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) r = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) rinfo.report_type = finfo.report_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) rinfo.report_id = finfo.report_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) report = hiddev_lookup_report(hid, &rinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (report == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (finfo.field_index >= report->maxfield)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) finfo.field_index = array_index_nospec(finfo.field_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) report->maxfield);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) field = report->field[finfo.field_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) memset(&finfo, 0, sizeof(finfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) finfo.report_type = rinfo.report_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) finfo.report_id = rinfo.report_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) finfo.field_index = field->report_count - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) finfo.maxusage = field->maxusage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) finfo.flags = field->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) finfo.physical = field->physical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) finfo.logical = field->logical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) finfo.application = field->application;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) finfo.logical_minimum = field->logical_minimum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) finfo.logical_maximum = field->logical_maximum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) finfo.physical_minimum = field->physical_minimum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) finfo.physical_maximum = field->physical_maximum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) finfo.unit_exponent = field->unit_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) finfo.unit = field->unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) case HIDIOCGUCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case HIDIOCGUSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) case HIDIOCSUSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) case HIDIOCGUSAGES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case HIDIOCSUSAGES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) case HIDIOCGCOLLECTIONINDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (!hiddev->initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) usbhid_init_reports(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) hiddev->initialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) case HIDIOCGCOLLECTIONINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) r = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (cinfo.index >= hid->maxcollection)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) cinfo.index = array_index_nospec(cinfo.index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) hid->maxcollection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) cinfo.type = hid->collection[cinfo.index].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) cinfo.usage = hid->collection[cinfo.index].usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) cinfo.level = hid->collection[cinfo.index].level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int len = strlen(hid->name) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (len > _IOC_SIZE(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) len = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) r = copy_to_user(user_arg, hid->name, len) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) -EFAULT : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) int len = strlen(hid->phys) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (len > _IOC_SIZE(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) len = _IOC_SIZE(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) r = copy_to_user(user_arg, hid->phys, len) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) -EFAULT : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ret_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) mutex_unlock(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static const struct file_operations hiddev_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .read = hiddev_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .write = hiddev_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .poll = hiddev_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .open = hiddev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .release = hiddev_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .unlocked_ioctl = hiddev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .fasync = hiddev_fasync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .compat_ioctl = compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static char *hiddev_devnode(struct device *dev, umode_t *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static struct usb_class_driver hiddev_class = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) .name = "hiddev%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .devnode = hiddev_devnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .fops = &hiddev_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) .minor_base = HIDDEV_MINOR_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * This is where hid.c calls us to connect a hid device to the hiddev driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int hiddev_connect(struct hid_device *hid, unsigned int force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct hiddev *hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct usbhid_device *usbhid = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (!force) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) for (i = 0; i < hid->maxcollection; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (hid->collection[i].type ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) HID_COLLECTION_APPLICATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) !IS_INPUT_APPLICATION(hid->collection[i].usage))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (i == hid->maxcollection)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) init_waitqueue_head(&hiddev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) INIT_LIST_HEAD(&hiddev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) spin_lock_init(&hiddev->list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) mutex_init(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) hid->hiddev = hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) hiddev->hid = hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) hiddev->exist = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) retval = usb_register_dev(usbhid->intf, &hiddev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) hid_err(hid, "Not able to get a minor for this device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) hid->hiddev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) kfree(hiddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * If HID_QUIRK_NO_INIT_REPORTS is set, make sure we don't initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * the reports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) hiddev->initialized = hid->quirks & HID_QUIRK_NO_INIT_REPORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) hiddev->minor = usbhid->intf->minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * This is where hid.c calls us to disconnect a hiddev device from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * corresponding hid device (usually because the usb device has disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) static struct usb_class_driver hiddev_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) void hiddev_disconnect(struct hid_device *hid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct hiddev *hiddev = hid->hiddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct usbhid_device *usbhid = hid->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) usb_deregister_dev(usbhid->intf, &hiddev_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) mutex_lock(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) hiddev->exist = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (hiddev->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) hid_hw_close(hiddev->hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) wake_up_interruptible(&hiddev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) mutex_unlock(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) mutex_unlock(&hiddev->existancelock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) kfree(hiddev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }