Error Trace
[Home]
Bug # 60
Show/hide error trace Error trace
-__BLAST_initialize_/work/ldvuser/ref_launch/work/current--X--drivers--X--defaultlinux-4.0-rc1.tar.xz--X--151_1a/linux-4.0-rc1.tar.xz/csd_deg_dscv/564/dscv_tempdir/dscv/rcv/151_1a/main-ldv_main0_sequence_infinite_withcheck_stateful/preprocess/1-cpp/drivers/hid/hid-lenovo.o.i() { 15 -LDV_SYSFS_GROUPS = 0; dev_attr_fn_lock_cptkbd.attr.name = "fn_lock"; dev_attr_fn_lock_cptkbd.attr.mode = 420; dev_attr_fn_lock_cptkbd.attr.ignore_lockdep = 0; dev_attr_fn_lock_cptkbd.attr.key = 0; dev_attr_fn_lock_cptkbd.attr.skey.subkeys[ 0 ].__one_byte = 0; dev_attr_fn_lock_cptkbd.attr.skey.subkeys[ 1 ].__one_byte = 0; dev_attr_fn_lock_cptkbd.attr.skey.subkeys[ 2 ].__one_byte = 0; dev_attr_fn_lock_cptkbd.attr.skey.subkeys[ 3 ].__one_byte = 0; dev_attr_fn_lock_cptkbd.attr.skey.subkeys[ 4 ].__one_byte = 0; dev_attr_fn_lock_cptkbd.attr.skey.subkeys[ 5 ].__one_byte = 0; dev_attr_fn_lock_cptkbd.attr.skey.subkeys[ 6 ].__one_byte = 0; dev_attr_fn_lock_cptkbd.attr.skey.subkeys[ 7 ].__one_byte = 0; dev_attr_fn_lock_cptkbd.show = &(attr_fn_lock_show_cptkbd); dev_attr_fn_lock_cptkbd.store = &(attr_fn_lock_store_cptkbd); dev_attr_sensitivity_cptkbd.attr.name = "sensitivity"; dev_attr_sensitivity_cptkbd.attr.mode = 420; dev_attr_sensitivity_cptkbd.attr.ignore_lockdep = 0; dev_attr_sensitivity_cptkbd.attr.key = 0; dev_attr_sensitivity_cptkbd.attr.skey.subkeys[ 0 ].__one_byte = 0; dev_attr_sensitivity_cptkbd.attr.skey.subkeys[ 1 ].__one_byte = 0; dev_attr_sensitivity_cptkbd.attr.skey.subkeys[ 2 ].__one_byte = 0; dev_attr_sensitivity_cptkbd.attr.skey.subkeys[ 3 ].__one_byte = 0; dev_attr_sensitivity_cptkbd.attr.skey.subkeys[ 4 ].__one_byte = 0; dev_attr_sensitivity_cptkbd.attr.skey.subkeys[ 5 ].__one_byte = 0; dev_attr_sensitivity_cptkbd.attr.skey.subkeys[ 6 ].__one_byte = 0; dev_attr_sensitivity_cptkbd.attr.skey.subkeys[ 7 ].__one_byte = 0; dev_attr_sensitivity_cptkbd.show = &(attr_sensitivity_show_cptkbd); dev_attr_sensitivity_cptkbd.store = &(attr_sensitivity_store_cptkbd); lenovo_attributes_cptkbd[ 0 ] = &(&(dev_attr_fn_lock_cptkbd))->attr; lenovo_attributes_cptkbd[ 1 ] = &(&(dev_attr_sensitivity_cptkbd))->attr; lenovo_attributes_cptkbd[ 2 ] = 0; lenovo_attr_group_cptkbd.name = 0; lenovo_attr_group_cptkbd.is_visible = 0; lenovo_attr_group_cptkbd.attrs = &(lenovo_attributes_cptkbd); lenovo_attr_group_cptkbd.bin_attrs = 0; dev_attr_press_to_select_tpkbd.attr.name = "press_to_select"; dev_attr_press_to_select_tpkbd.attr.mode = 420; dev_attr_press_to_select_tpkbd.attr.ignore_lockdep = 0; dev_attr_press_to_select_tpkbd.attr.key = 0; dev_attr_press_to_select_tpkbd.attr.skey.subkeys[ 0 ].__one_byte = 0; dev_attr_press_to_select_tpkbd.attr.skey.subkeys[ 1 ].__one_byte = 0; dev_attr_press_to_select_tpkbd.attr.skey.subkeys[ 2 ].__one_byte = 0; dev_attr_press_to_select_tpkbd.attr.skey.subkeys[ 3 ].__one_byte = 0; dev_attr_press_to_select_tpkbd.attr.skey.subkeys[ 4 ].__one_byte = 0; dev_attr_press_to_select_tpkbd.attr.skey.subkeys[ 5 ].__one_byte = 0; dev_attr_press_to_select_tpkbd.attr.skey.subkeys[ 6 ].__one_byte = 0; dev_attr_press_to_select_tpkbd.attr.skey.subkeys[ 7 ].__one_byte = 0; dev_attr_press_to_select_tpkbd.show = &(attr_press_to_select_show_tpkbd); dev_attr_press_to_select_tpkbd.store = &(attr_press_to_select_store_tpkbd); dev_attr_dragging_tpkbd.attr.name = "dragging"; dev_attr_dragging_tpkbd.attr.mode = 420; dev_attr_dragging_tpkbd.attr.ignore_lockdep = 0; dev_attr_dragging_tpkbd.attr.key = 0; dev_attr_dragging_tpkbd.attr.skey.subkeys[ 0 ].__one_byte = 0; dev_attr_dragging_tpkbd.attr.skey.subkeys[ 1 ].__one_byte = 0; dev_attr_dragging_tpkbd.attr.skey.subkeys[ 2 ].__one_byte = 0; dev_attr_dragging_tpkbd.attr.skey.subkeys[ 3 ].__one_byte = 0; dev_attr_dragging_tpkbd.attr.skey.subkeys[ 4 ].__one_byte = 0; dev_attr_dragging_tpkbd.attr.skey.subkeys[ 5 ].__one_byte = 0; dev_attr_dragging_tpkbd.attr.skey.subkeys[ 6 ].__one_byte = 0; dev_attr_dragging_tpkbd.attr.skey.subkeys[ 7 ].__one_byte = 0; dev_attr_dragging_tpkbd.show = &(attr_dragging_show_tpkbd); dev_attr_dragging_tpkbd.store = &(attr_dragging_store_tpkbd); dev_attr_release_to_select_tpkbd.attr.name = "release_to_select"; dev_attr_release_to_select_tpkbd.attr.mode = 420; dev_attr_release_to_select_tpkbd.attr.ignore_lockdep = 0; dev_attr_release_to_select_tpkbd.attr.key = 0; dev_attr_release_to_select_tpkbd.attr.skey.subkeys[ 0 ].__one_byte = 0; dev_attr_release_to_select_tpkbd.attr.skey.subkeys[ 1 ].__one_byte = 0; dev_attr_release_to_select_tpkbd.attr.skey.subkeys[ 2 ].__one_byte = 0; dev_attr_release_to_select_tpkbd.attr.skey.subkeys[ 3 ].__one_byte = 0; dev_attr_release_to_select_tpkbd.attr.skey.subkeys[ 4 ].__one_byte = 0; dev_attr_release_to_select_tpkbd.attr.skey.subkeys[ 5 ].__one_byte = 0; dev_attr_release_to_select_tpkbd.attr.skey.subkeys[ 6 ].__one_byte = 0; dev_attr_release_to_select_tpkbd.attr.skey.subkeys[ 7 ].__one_byte = 0; dev_attr_release_to_select_tpkbd.show = &(attr_release_to_select_show_tpkbd); dev_attr_release_to_select_tpkbd.store = &(attr_release_to_select_store_tpkbd); dev_attr_select_right_tpkbd.attr.name = "select_right"; dev_attr_select_right_tpkbd.attr.mode = 420; dev_attr_select_right_tpkbd.attr.ignore_lockdep = 0; dev_attr_select_right_tpkbd.attr.key = 0; dev_attr_select_right_tpkbd.attr.skey.subkeys[ 0 ].__one_byte = 0; dev_attr_select_right_tpkbd.attr.skey.subkeys[ 1 ].__one_byte = 0; dev_attr_select_right_tpkbd.attr.skey.subkeys[ 2 ].__one_byte = 0; dev_attr_select_right_tpkbd.attr.skey.subkeys[ 3 ].__one_byte = 0; dev_attr_select_right_tpkbd.attr.skey.subkeys[ 4 ].__one_byte = 0; dev_attr_select_right_tpkbd.attr.skey.subkeys[ 5 ].__one_byte = 0; dev_attr_select_right_tpkbd.attr.skey.subkeys[ 6 ].__one_byte = 0; dev_attr_select_right_tpkbd.attr.skey.subkeys[ 7 ].__one_byte = 0; dev_attr_select_right_tpkbd.show = &(attr_select_right_show_tpkbd); dev_attr_select_right_tpkbd.store = &(attr_select_right_store_tpkbd); dev_attr_sensitivity_tpkbd.attr.name = "sensitivity"; dev_attr_sensitivity_tpkbd.attr.mode = 420; dev_attr_sensitivity_tpkbd.attr.ignore_lockdep = 0; dev_attr_sensitivity_tpkbd.attr.key = 0; dev_attr_sensitivity_tpkbd.attr.skey.subkeys[ 0 ].__one_byte = 0; dev_attr_sensitivity_tpkbd.attr.skey.subkeys[ 1 ].__one_byte = 0; dev_attr_sensitivity_tpkbd.attr.skey.subkeys[ 2 ].__one_byte = 0; dev_attr_sensitivity_tpkbd.attr.skey.subkeys[ 3 ].__one_byte = 0; dev_attr_sensitivity_tpkbd.attr.skey.subkeys[ 4 ].__one_byte = 0; dev_attr_sensitivity_tpkbd.attr.skey.subkeys[ 5 ].__one_byte = 0; dev_attr_sensitivity_tpkbd.attr.skey.subkeys[ 6 ].__one_byte = 0; dev_attr_sensitivity_tpkbd.attr.skey.subkeys[ 7 ].__one_byte = 0; dev_attr_sensitivity_tpkbd.show = &(attr_sensitivity_show_tpkbd); dev_attr_sensitivity_tpkbd.store = &(attr_sensitivity_store_tpkbd); dev_attr_press_speed_tpkbd.attr.name = "press_speed"; dev_attr_press_speed_tpkbd.attr.mode = 420; dev_attr_press_speed_tpkbd.attr.ignore_lockdep = 0; dev_attr_press_speed_tpkbd.attr.key = 0; dev_attr_press_speed_tpkbd.attr.skey.subkeys[ 0 ].__one_byte = 0; dev_attr_press_speed_tpkbd.attr.skey.subkeys[ 1 ].__one_byte = 0; dev_attr_press_speed_tpkbd.attr.skey.subkeys[ 2 ].__one_byte = 0; dev_attr_press_speed_tpkbd.attr.skey.subkeys[ 3 ].__one_byte = 0; dev_attr_press_speed_tpkbd.attr.skey.subkeys[ 4 ].__one_byte = 0; dev_attr_press_speed_tpkbd.attr.skey.subkeys[ 5 ].__one_byte = 0; dev_attr_press_speed_tpkbd.attr.skey.subkeys[ 6 ].__one_byte = 0; dev_attr_press_speed_tpkbd.attr.skey.subkeys[ 7 ].__one_byte = 0; dev_attr_press_speed_tpkbd.show = &(attr_press_speed_show_tpkbd); dev_attr_press_speed_tpkbd.store = &(attr_press_speed_store_tpkbd); lenovo_attributes_tpkbd[ 0 ] = &(&(dev_attr_press_to_select_tpkbd))->attr; lenovo_attributes_tpkbd[ 1 ] = &(&(dev_attr_dragging_tpkbd))->attr; lenovo_attributes_tpkbd[ 2 ] = &(&(dev_attr_release_to_select_tpkbd))->attr; lenovo_attributes_tpkbd[ 3 ] = &(&(dev_attr_select_right_tpkbd))->attr; lenovo_attributes_tpkbd[ 4 ] = &(&(dev_attr_sensitivity_tpkbd))->attr; lenovo_attributes_tpkbd[ 5 ] = &(&(dev_attr_press_speed_tpkbd))->attr; lenovo_attributes_tpkbd[ 6 ] = 0; lenovo_attr_group_tpkbd.name = 0; lenovo_attr_group_tpkbd.is_visible = 0; lenovo_attr_group_tpkbd.attrs = &(lenovo_attributes_tpkbd); lenovo_attr_group_tpkbd.bin_attrs = 0; return ; } -__BLAST_initialize_/work/ldvuser/ref_launch/work/current--X--drivers--X--defaultlinux-4.0-rc1.tar.xz--X--151_1a/linux-4.0-rc1.tar.xz/csd_deg_dscv/564/dscv_tempdir/dscv/rcv/151_1a/main-ldv_main0_sequence_infinite_withcheck_stateful/preprocess/1-cpp//work/ldvuser/ref_launch/work/current--X--drivers--X--defaultlinux-4.0-rc1.tar.xz--X--151_1a/linux-4.0-rc1.tar.xz/csd_deg_dscv/564/dscv_tempdir/rule-instrumentor/151_1a/common-model/ldv_common_model.o.i() { return ; } { 891 ldv_initialize() { /* Function call is skipped due to function is undefined */} 896 tmp___0 = nondet_int() { /* Function call is skipped due to function is undefined */} 900 tmp = nondet_int() { /* Function call is skipped due to function is undefined */} { { 935 cil_6 = *(*(hdev).ll_driver).start; 935 tmp = *(cil_6)(hdev) { /* Function call is skipped due to function is undefined */} 935 ret = tmp; 938 ret = hid_connect(hdev, connect_mask) { /* Function call is skipped due to function is undefined */} 941 __retres9 = ret; } { 648 -descriptor.modname = "hid_lenovo"; descriptor.function = "lenovo_probe_cptkbd"; descriptor.filename = "/work/ldvuser/ref_launch/work/current--X--drivers--X--defaultlinux-4.0-rc1.tar.xz--X--151_1a/linux-4.0-rc1.tar.xz/csd_deg_dscv/564/dscv_tempdir/dscv/ri/151_1a/drivers/hid/hid-lenovo.c"; descriptor.format = "Ignoring keyboard half of device\n"; descriptor.lineno = 648; descriptor.flags = 0; 649 __retres7 = 0; } 718 __retres4 = 0; } 914 ldv_check_return_value(res_lenovo_probe_27) { /* Function call is skipped due to function is undefined */} 915 ldv_check_return_value_probe(res_lenovo_probe_27) { /* Function call is skipped due to function is undefined */} 918 ldv_s_lenovo_driver_hid_driver = ldv_s_lenovo_driver_hid_driver + 1; 896 tmp___0 = nondet_int() { /* Function call is skipped due to function is undefined */} 900 tmp = nondet_int() { /* Function call is skipped due to function is undefined */} 936 ldv_handler_precall() { /* Function call is skipped due to function is undefined */} { { 747 -ldv_sysfs_remove_group_8(&(&(hdev)->dev)->kobj /* ldv_func_arg1 */, &(lenovo_attr_group_cptkbd) /* ldv_func_arg2 */) 745 return ; } { 954 hid_disconnect(hdev) { /* Function call is skipped due to function is undefined */} 955 cil_3 = *(*(hdev).ll_driver).stop; 955 *(cil_3)(hdev) { /* Function call is skipped due to function is undefined */} 952 return ; } 751 return ; } 938 ldv_s_lenovo_driver_hid_driver = 0; 896 tmp___0 = nondet_int() { /* Function call is skipped due to function is undefined */} } | Source code 1
2 /*
3 * HID driver for Lenovo:
4 * - ThinkPad USB Keyboard with TrackPoint (tpkbd)
5 * - ThinkPad Compact Bluetooth Keyboard with TrackPoint (cptkbd)
6 * - ThinkPad Compact USB Keyboard with TrackPoint (cptkbd)
7 *
8 * Copyright (c) 2012 Bernhard Seibold
9 * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk>
10 */
11
12 /*
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 */
18
19 #include <linux/module.h>
20 #include <linux/sysfs.h>
21 #include <linux/device.h>
22 #include <linux/hid.h>
23 #include <linux/input.h>
24 #include <linux/leds.h>
25
26 #include "hid-ids.h"
27
28 struct lenovo_drvdata_tpkbd {
29 int led_state;
30 struct led_classdev led_mute;
31 struct led_classdev led_micmute;
32 int press_to_select;
33 int dragging;
34 int release_to_select;
35 int select_right;
36 int sensitivity;
37 int press_speed;
38 };
39
40 struct lenovo_drvdata_cptkbd {
41 bool fn_lock;
42 int sensitivity;
43 };
44
45 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
46
47 static int lenovo_input_mapping_tpkbd(struct hid_device *hdev,
48 struct hid_input *hi, struct hid_field *field,
49 struct hid_usage *usage, unsigned long **bit, int *max)
50 {
51 if (usage->hid == (HID_UP_BUTTON | 0x0010)) {
52 /* This sub-device contains trackpoint, mark it */
53 hid_set_drvdata(hdev, (void *)1);
54 map_key_clear(KEY_MICMUTE);
55 return 1;
56 }
57 return 0;
58 }
59
60 static int lenovo_input_mapping_cptkbd(struct hid_device *hdev,
61 struct hid_input *hi, struct hid_field *field,
62 struct hid_usage *usage, unsigned long **bit, int *max)
63 {
64 /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */
65 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR ||
66 (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) {
67 switch (usage->hid & HID_USAGE) {
68 case 0x00f1: /* Fn-F4: Mic mute */
69 map_key_clear(KEY_MICMUTE);
70 return 1;
71 case 0x00f2: /* Fn-F5: Brightness down */
72 map_key_clear(KEY_BRIGHTNESSDOWN);
73 return 1;
74 case 0x00f3: /* Fn-F6: Brightness up */
75 map_key_clear(KEY_BRIGHTNESSUP);
76 return 1;
77 case 0x00f4: /* Fn-F7: External display (projector) */
78 map_key_clear(KEY_SWITCHVIDEOMODE);
79 return 1;
80 case 0x00f5: /* Fn-F8: Wireless */
81 map_key_clear(KEY_WLAN);
82 return 1;
83 case 0x00f6: /* Fn-F9: Control panel */
84 map_key_clear(KEY_CONFIG);
85 return 1;
86 case 0x00f8: /* Fn-F11: View open applications (3 boxes) */
87 map_key_clear(KEY_SCALE);
88 return 1;
89 case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */
90 /* NB: This mapping is invented in raw_event below */
91 map_key_clear(KEY_FILE);
92 return 1;
93 case 0x00fa: /* Fn-Esc: Fn-lock toggle */
94 map_key_clear(KEY_FN_ESC);
95 return 1;
96 case 0x00fb: /* Middle mouse button (in native mode) */
97 map_key_clear(BTN_MIDDLE);
98 return 1;
99 }
100 }
101
102 /* Compatibility middle/wheel mappings should be ignored */
103 if (usage->hid == HID_GD_WHEEL)
104 return -1;
105 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON &&
106 (usage->hid & HID_USAGE) == 0x003)
107 return -1;
108 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER &&
109 (usage->hid & HID_USAGE) == 0x238)
110 return -1;
111
112 /* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */
113 if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 ||
114 (usage->hid & HID_USAGE_PAGE) == 0xffa10000) {
115 field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE;
116 field->logical_minimum = -127;
117 field->logical_maximum = 127;
118
119 switch (usage->hid & HID_USAGE) {
120 case 0x0000:
121 hid_map_usage(hi, usage, bit, max, EV_REL, 0x06);
122 return 1;
123 case 0x0001:
124 hid_map_usage(hi, usage, bit, max, EV_REL, 0x08);
125 return 1;
126 default:
127 return -1;
128 }
129 }
130
131 return 0;
132 }
133
134 static int lenovo_input_mapping(struct hid_device *hdev,
135 struct hid_input *hi, struct hid_field *field,
136 struct hid_usage *usage, unsigned long **bit, int *max)
137 {
138 switch (hdev->product) {
139 case USB_DEVICE_ID_LENOVO_TPKBD:
140 return lenovo_input_mapping_tpkbd(hdev, hi, field,
141 usage, bit, max);
142 case USB_DEVICE_ID_LENOVO_CUSBKBD:
143 case USB_DEVICE_ID_LENOVO_CBTKBD:
144 return lenovo_input_mapping_cptkbd(hdev, hi, field,
145 usage, bit, max);
146 default:
147 return 0;
148 }
149 }
150
151 #undef map_key_clear
152
153 /* Send a config command to the keyboard */
154 static int lenovo_send_cmd_cptkbd(struct hid_device *hdev,
155 unsigned char byte2, unsigned char byte3)
156 {
157 int ret;
158 unsigned char buf[] = {0x18, byte2, byte3};
159
160 switch (hdev->product) {
161 case USB_DEVICE_ID_LENOVO_CUSBKBD:
162 ret = hid_hw_raw_request(hdev, 0x13, buf, sizeof(buf),
163 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
164 break;
165 case USB_DEVICE_ID_LENOVO_CBTKBD:
166 ret = hid_hw_output_report(hdev, buf, sizeof(buf));
167 break;
168 default:
169 ret = -EINVAL;
170 break;
171 }
172
173 return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */
174 }
175
176 static void lenovo_features_set_cptkbd(struct hid_device *hdev)
177 {
178 int ret;
179 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
180
181 ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock);
182 ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity);
183 if (ret)
184 hid_err(hdev, "Fn-lock setting failed: %d\n", ret);
185 }
186
187 static ssize_t attr_fn_lock_show_cptkbd(struct device *dev,
188 struct device_attribute *attr,
189 char *buf)
190 {
191 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
192 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
193
194 return snprintf(buf, PAGE_SIZE, "%u\n", cptkbd_data->fn_lock);
195 }
196
197 static ssize_t attr_fn_lock_store_cptkbd(struct device *dev,
198 struct device_attribute *attr,
199 const char *buf,
200 size_t count)
201 {
202 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
203 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
204 int value;
205
206 if (kstrtoint(buf, 10, &value))
207 return -EINVAL;
208 if (value < 0 || value > 1)
209 return -EINVAL;
210
211 cptkbd_data->fn_lock = !!value;
212 lenovo_features_set_cptkbd(hdev);
213
214 return count;
215 }
216
217 static ssize_t attr_sensitivity_show_cptkbd(struct device *dev,
218 struct device_attribute *attr,
219 char *buf)
220 {
221 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
222 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
223
224 return snprintf(buf, PAGE_SIZE, "%u\n",
225 cptkbd_data->sensitivity);
226 }
227
228 static ssize_t attr_sensitivity_store_cptkbd(struct device *dev,
229 struct device_attribute *attr,
230 const char *buf,
231 size_t count)
232 {
233 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
234 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
235 int value;
236
237 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
238 return -EINVAL;
239
240 cptkbd_data->sensitivity = value;
241 lenovo_features_set_cptkbd(hdev);
242
243 return count;
244 }
245
246
247 static struct device_attribute dev_attr_fn_lock_cptkbd =
248 __ATTR(fn_lock, S_IWUSR | S_IRUGO,
249 attr_fn_lock_show_cptkbd,
250 attr_fn_lock_store_cptkbd);
251
252 static struct device_attribute dev_attr_sensitivity_cptkbd =
253 __ATTR(sensitivity, S_IWUSR | S_IRUGO,
254 attr_sensitivity_show_cptkbd,
255 attr_sensitivity_store_cptkbd);
256
257
258 static struct attribute *lenovo_attributes_cptkbd[] = {
259 &dev_attr_fn_lock_cptkbd.attr,
260 &dev_attr_sensitivity_cptkbd.attr,
261 NULL
262 };
263
264 static const struct attribute_group lenovo_attr_group_cptkbd = {
265 .attrs = lenovo_attributes_cptkbd,
266 };
267
268 static int lenovo_raw_event(struct hid_device *hdev,
269 struct hid_report *report, u8 *data, int size)
270 {
271 /*
272 * Compact USB keyboard's Fn-F12 report holds down many other keys, and
273 * its own key is outside the usage page range. Remove extra
274 * keypresses and remap to inside usage page.
275 */
276 if (unlikely(hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
277 && size == 3
278 && data[0] == 0x15
279 && data[1] == 0x94
280 && data[2] == 0x01)) {
281 data[1] = 0x00;
282 data[2] = 0x01;
283 }
284
285 return 0;
286 }
287
288 static int lenovo_features_set_tpkbd(struct hid_device *hdev)
289 {
290 struct hid_report *report;
291 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
292
293 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4];
294
295 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02;
296 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08;
297 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20;
298 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40;
299 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver
300 report->field[2]->value[0] = data_pointer->sensitivity;
301 report->field[3]->value[0] = data_pointer->press_speed;
302
303 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
304 return 0;
305 }
306
307 static ssize_t attr_press_to_select_show_tpkbd(struct device *dev,
308 struct device_attribute *attr,
309 char *buf)
310 {
311 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
312 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
313
314 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select);
315 }
316
317 static ssize_t attr_press_to_select_store_tpkbd(struct device *dev,
318 struct device_attribute *attr,
319 const char *buf,
320 size_t count)
321 {
322 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
323 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
324 int value;
325
326 if (kstrtoint(buf, 10, &value))
327 return -EINVAL;
328 if (value < 0 || value > 1)
329 return -EINVAL;
330
331 data_pointer->press_to_select = value;
332 lenovo_features_set_tpkbd(hdev);
333
334 return count;
335 }
336
337 static ssize_t attr_dragging_show_tpkbd(struct device *dev,
338 struct device_attribute *attr,
339 char *buf)
340 {
341 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
342 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
343
344 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging);
345 }
346
347 static ssize_t attr_dragging_store_tpkbd(struct device *dev,
348 struct device_attribute *attr,
349 const char *buf,
350 size_t count)
351 {
352 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
353 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
354 int value;
355
356 if (kstrtoint(buf, 10, &value))
357 return -EINVAL;
358 if (value < 0 || value > 1)
359 return -EINVAL;
360
361 data_pointer->dragging = value;
362 lenovo_features_set_tpkbd(hdev);
363
364 return count;
365 }
366
367 static ssize_t attr_release_to_select_show_tpkbd(struct device *dev,
368 struct device_attribute *attr,
369 char *buf)
370 {
371 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
372 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
373
374 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select);
375 }
376
377 static ssize_t attr_release_to_select_store_tpkbd(struct device *dev,
378 struct device_attribute *attr,
379 const char *buf,
380 size_t count)
381 {
382 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
383 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
384 int value;
385
386 if (kstrtoint(buf, 10, &value))
387 return -EINVAL;
388 if (value < 0 || value > 1)
389 return -EINVAL;
390
391 data_pointer->release_to_select = value;
392 lenovo_features_set_tpkbd(hdev);
393
394 return count;
395 }
396
397 static ssize_t attr_select_right_show_tpkbd(struct device *dev,
398 struct device_attribute *attr,
399 char *buf)
400 {
401 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
402 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
403
404 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right);
405 }
406
407 static ssize_t attr_select_right_store_tpkbd(struct device *dev,
408 struct device_attribute *attr,
409 const char *buf,
410 size_t count)
411 {
412 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
413 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
414 int value;
415
416 if (kstrtoint(buf, 10, &value))
417 return -EINVAL;
418 if (value < 0 || value > 1)
419 return -EINVAL;
420
421 data_pointer->select_right = value;
422 lenovo_features_set_tpkbd(hdev);
423
424 return count;
425 }
426
427 static ssize_t attr_sensitivity_show_tpkbd(struct device *dev,
428 struct device_attribute *attr,
429 char *buf)
430 {
431 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
432 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
433
434 return snprintf(buf, PAGE_SIZE, "%u\n",
435 data_pointer->sensitivity);
436 }
437
438 static ssize_t attr_sensitivity_store_tpkbd(struct device *dev,
439 struct device_attribute *attr,
440 const char *buf,
441 size_t count)
442 {
443 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
444 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
445 int value;
446
447 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
448 return -EINVAL;
449
450 data_pointer->sensitivity = value;
451 lenovo_features_set_tpkbd(hdev);
452
453 return count;
454 }
455
456 static ssize_t attr_press_speed_show_tpkbd(struct device *dev,
457 struct device_attribute *attr,
458 char *buf)
459 {
460 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
461 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
462
463 return snprintf(buf, PAGE_SIZE, "%u\n",
464 data_pointer->press_speed);
465 }
466
467 static ssize_t attr_press_speed_store_tpkbd(struct device *dev,
468 struct device_attribute *attr,
469 const char *buf,
470 size_t count)
471 {
472 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
473 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
474 int value;
475
476 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
477 return -EINVAL;
478
479 data_pointer->press_speed = value;
480 lenovo_features_set_tpkbd(hdev);
481
482 return count;
483 }
484
485 static struct device_attribute dev_attr_press_to_select_tpkbd =
486 __ATTR(press_to_select, S_IWUSR | S_IRUGO,
487 attr_press_to_select_show_tpkbd,
488 attr_press_to_select_store_tpkbd);
489
490 static struct device_attribute dev_attr_dragging_tpkbd =
491 __ATTR(dragging, S_IWUSR | S_IRUGO,
492 attr_dragging_show_tpkbd,
493 attr_dragging_store_tpkbd);
494
495 static struct device_attribute dev_attr_release_to_select_tpkbd =
496 __ATTR(release_to_select, S_IWUSR | S_IRUGO,
497 attr_release_to_select_show_tpkbd,
498 attr_release_to_select_store_tpkbd);
499
500 static struct device_attribute dev_attr_select_right_tpkbd =
501 __ATTR(select_right, S_IWUSR | S_IRUGO,
502 attr_select_right_show_tpkbd,
503 attr_select_right_store_tpkbd);
504
505 static struct device_attribute dev_attr_sensitivity_tpkbd =
506 __ATTR(sensitivity, S_IWUSR | S_IRUGO,
507 attr_sensitivity_show_tpkbd,
508 attr_sensitivity_store_tpkbd);
509
510 static struct device_attribute dev_attr_press_speed_tpkbd =
511 __ATTR(press_speed, S_IWUSR | S_IRUGO,
512 attr_press_speed_show_tpkbd,
513 attr_press_speed_store_tpkbd);
514
515 static struct attribute *lenovo_attributes_tpkbd[] = {
516 &dev_attr_press_to_select_tpkbd.attr,
517 &dev_attr_dragging_tpkbd.attr,
518 &dev_attr_release_to_select_tpkbd.attr,
519 &dev_attr_select_right_tpkbd.attr,
520 &dev_attr_sensitivity_tpkbd.attr,
521 &dev_attr_press_speed_tpkbd.attr,
522 NULL
523 };
524
525 static const struct attribute_group lenovo_attr_group_tpkbd = {
526 .attrs = lenovo_attributes_tpkbd,
527 };
528
529 static enum led_brightness lenovo_led_brightness_get_tpkbd(
530 struct led_classdev *led_cdev)
531 {
532 struct device *dev = led_cdev->dev->parent;
533 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
534 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
535 int led_nr = 0;
536
537 if (led_cdev == &data_pointer->led_micmute)
538 led_nr = 1;
539
540 return data_pointer->led_state & (1 << led_nr)
541 ? LED_FULL
542 : LED_OFF;
543 }
544
545 static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev,
546 enum led_brightness value)
547 {
548 struct device *dev = led_cdev->dev->parent;
549 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
550 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
551 struct hid_report *report;
552 int led_nr = 0;
553
554 if (led_cdev == &data_pointer->led_micmute)
555 led_nr = 1;
556
557 if (value == LED_OFF)
558 data_pointer->led_state &= ~(1 << led_nr);
559 else
560 data_pointer->led_state |= 1 << led_nr;
561
562 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
563 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
564 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
565 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
566 }
567
568 static int lenovo_probe_tpkbd(struct hid_device *hdev)
569 {
570 struct device *dev = &hdev->dev;
571 struct lenovo_drvdata_tpkbd *data_pointer;
572 size_t name_sz = strlen(dev_name(dev)) + 16;
573 char *name_mute, *name_micmute;
574 int i;
575 int ret;
576
577 /*
578 * Only register extra settings against subdevice where input_mapping
579 * set drvdata to 1, i.e. the trackpoint.
580 */
581 if (!hid_get_drvdata(hdev))
582 return 0;
583
584 hid_set_drvdata(hdev, NULL);
585
586 /* Validate required reports. */
587 for (i = 0; i < 4; i++) {
588 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
589 return -ENODEV;
590 }
591 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2))
592 return -ENODEV;
593
594 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd);
595 if (ret)
596 hid_warn(hdev, "Could not create sysfs group: %d\n", ret);
597
598 data_pointer = devm_kzalloc(&hdev->dev,
599 sizeof(struct lenovo_drvdata_tpkbd),
600 GFP_KERNEL);
601 if (data_pointer == NULL) {
602 hid_err(hdev, "Could not allocate memory for driver data\n");
603 return -ENOMEM;
604 }
605
606 // set same default values as windows driver
607 data_pointer->sensitivity = 0xa0;
608 data_pointer->press_speed = 0x38;
609
610 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
611 name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
612 if (name_mute == NULL || name_micmute == NULL) {
613 hid_err(hdev, "Could not allocate memory for led data\n");
614 return -ENOMEM;
615 }
616 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
617 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
618
619 hid_set_drvdata(hdev, data_pointer);
620
621 data_pointer->led_mute.name = name_mute;
622 data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd;
623 data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd;
624 data_pointer->led_mute.dev = dev;
625 led_classdev_register(dev, &data_pointer->led_mute);
626
627 data_pointer->led_micmute.name = name_micmute;
628 data_pointer->led_micmute.brightness_get =
629 lenovo_led_brightness_get_tpkbd;
630 data_pointer->led_micmute.brightness_set =
631 lenovo_led_brightness_set_tpkbd;
632 data_pointer->led_micmute.dev = dev;
633 led_classdev_register(dev, &data_pointer->led_micmute);
634
635 lenovo_features_set_tpkbd(hdev);
636
637 return 0;
638 }
639
640 static int lenovo_probe_cptkbd(struct hid_device *hdev)
641 {
642 int ret;
643 struct lenovo_drvdata_cptkbd *cptkbd_data;
644
645 /* All the custom action happens on the USBMOUSE device for USB */
646 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
647 && hdev->type != HID_TYPE_USBMOUSE) {
648 hid_dbg(hdev, "Ignoring keyboard half of device\n");
649 return 0;
650 }
651
652 cptkbd_data = devm_kzalloc(&hdev->dev,
653 sizeof(*cptkbd_data),
654 GFP_KERNEL);
655 if (cptkbd_data == NULL) {
656 hid_err(hdev, "can't alloc keyboard descriptor\n");
657 return -ENOMEM;
658 }
659 hid_set_drvdata(hdev, cptkbd_data);
660
661 /*
662 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into
663 * regular keys
664 */
665 ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03);
666 if (ret)
667 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
668
669 /* Switch middle button to native mode */
670 ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01);
671 if (ret)
672 hid_warn(hdev, "Failed to switch middle button: %d\n", ret);
673
674 /* Set keyboard settings to known state */
675 cptkbd_data->fn_lock = true;
676 cptkbd_data->sensitivity = 0x05;
677 lenovo_features_set_cptkbd(hdev);
678
679 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
680 if (ret)
681 hid_warn(hdev, "Could not create sysfs group: %d\n", ret);
682
683 return 0;
684 }
685
686 static int lenovo_probe(struct hid_device *hdev,
687 const struct hid_device_id *id)
688 {
689 int ret;
690
691 ret = hid_parse(hdev);
692 if (ret) {
693 hid_err(hdev, "hid_parse failed\n");
694 goto err;
695 }
696
697 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
698 if (ret) {
699 hid_err(hdev, "hid_hw_start failed\n");
700 goto err;
701 }
702
703 switch (hdev->product) {
704 case USB_DEVICE_ID_LENOVO_TPKBD:
705 ret = lenovo_probe_tpkbd(hdev);
706 break;
707 case USB_DEVICE_ID_LENOVO_CUSBKBD:
708 case USB_DEVICE_ID_LENOVO_CBTKBD:
709 ret = lenovo_probe_cptkbd(hdev);
710 break;
711 default:
712 ret = 0;
713 break;
714 }
715 if (ret)
716 goto err_hid;
717
718 return 0;
719 err_hid:
720 hid_hw_stop(hdev);
721 err:
722 return ret;
723 }
724
725 static void lenovo_remove_tpkbd(struct hid_device *hdev)
726 {
727 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
728
729 /*
730 * Only the trackpoint half of the keyboard has drvdata and stuff that
731 * needs unregistering.
732 */
733 if (data_pointer == NULL)
734 return;
735
736 sysfs_remove_group(&hdev->dev.kobj,
737 &lenovo_attr_group_tpkbd);
738
739 led_classdev_unregister(&data_pointer->led_micmute);
740 led_classdev_unregister(&data_pointer->led_mute);
741
742 hid_set_drvdata(hdev, NULL);
743 }
744
745 static void lenovo_remove_cptkbd(struct hid_device *hdev)
746 {
747 sysfs_remove_group(&hdev->dev.kobj,
748 &lenovo_attr_group_cptkbd);
749 }
750
751 static void lenovo_remove(struct hid_device *hdev)
752 {
753 switch (hdev->product) {
754 case USB_DEVICE_ID_LENOVO_TPKBD:
755 lenovo_remove_tpkbd(hdev);
756 break;
757 case USB_DEVICE_ID_LENOVO_CUSBKBD:
758 case USB_DEVICE_ID_LENOVO_CBTKBD:
759 lenovo_remove_cptkbd(hdev);
760 break;
761 }
762
763 hid_hw_stop(hdev);
764 }
765
766 static const struct hid_device_id lenovo_devices[] = {
767 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
768 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
769 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
770 { }
771 };
772
773 MODULE_DEVICE_TABLE(hid, lenovo_devices);
774
775 static struct hid_driver lenovo_driver = {
776 .name = "lenovo",
777 .id_table = lenovo_devices,
778 .input_mapping = lenovo_input_mapping,
779 .probe = lenovo_probe,
780 .remove = lenovo_remove,
781 .raw_event = lenovo_raw_event,
782 };
783 module_hid_driver(lenovo_driver);
784
785 MODULE_LICENSE("GPL");
786
787
788
789
790
791 /* LDV_COMMENT_BEGIN_MAIN */
792 #ifdef LDV_MAIN0_sequence_infinite_withcheck_stateful
793
794 /*###########################################################################*/
795
796 /*############## Driver Environment Generator 0.2 output ####################*/
797
798 /*###########################################################################*/
799
800
801
802 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Test if all kernel resources are correctly released by driver before driver will be unloaded. */
803 void ldv_check_final_state(void);
804
805 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Test correct return result. */
806 void ldv_check_return_value(int res);
807
808 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Test correct return result of probe() function. */
809 void ldv_check_return_value_probe(int res);
810
811 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Initializes the model. */
812 void ldv_initialize(void);
813
814 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Reinitializes the model between distinct model function calls. */
815 void ldv_handler_precall(void);
816
817 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Returns arbitrary interger value. */
818 int nondet_int(void);
819
820 /* LDV_COMMENT_VAR_DECLARE_LDV Special variable for LDV verifier. */
821 int LDV_IN_INTERRUPT;
822
823 /* LDV_COMMENT_FUNCTION_MAIN Main function for LDV verifier. */
824 void ldv_main0_sequence_infinite_withcheck_stateful(void) {
825
826
827
828 /* LDV_COMMENT_BEGIN_VARIABLE_DECLARATION_PART */
829 /*============================= VARIABLE DECLARATION PART =============================*/
830 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
831 /* content: static int lenovo_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max)*/
832 /* LDV_COMMENT_BEGIN_PREP */
833 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
834 /* LDV_COMMENT_END_PREP */
835 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
836 struct hid_device * var_group1;
837 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
838 struct hid_input * var_group2;
839 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
840 struct hid_field * var_lenovo_input_mapping_2_p2;
841 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
842 struct hid_usage * var_lenovo_input_mapping_2_p3;
843 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
844 unsigned long ** var_lenovo_input_mapping_2_p4;
845 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
846 int * var_lenovo_input_mapping_2_p5;
847 /* LDV_COMMENT_BEGIN_PREP */
848 #undef map_key_clear
849 /* LDV_COMMENT_END_PREP */
850 /* content: static int lenovo_probe(struct hid_device *hdev, const struct hid_device_id *id)*/
851 /* LDV_COMMENT_BEGIN_PREP */
852 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
853 #undef map_key_clear
854 /* LDV_COMMENT_END_PREP */
855 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_probe" */
856 const struct hid_device_id * var_lenovo_probe_27_p1;
857 /* LDV_COMMENT_VAR_DECLARE Variable declaration for test return result from function call "lenovo_probe" */
858 static int res_lenovo_probe_27;
859 /* content: static void lenovo_remove(struct hid_device *hdev)*/
860 /* LDV_COMMENT_BEGIN_PREP */
861 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
862 #undef map_key_clear
863 /* LDV_COMMENT_END_PREP */
864 /* content: static int lenovo_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)*/
865 /* LDV_COMMENT_BEGIN_PREP */
866 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
867 #undef map_key_clear
868 /* LDV_COMMENT_END_PREP */
869 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_raw_event" */
870 struct hid_report * var_group3;
871 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_raw_event" */
872 u8 * var_lenovo_raw_event_9_p2;
873 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_raw_event" */
874 int var_lenovo_raw_event_9_p3;
875
876
877
878
879 /* LDV_COMMENT_END_VARIABLE_DECLARATION_PART */
880 /* LDV_COMMENT_BEGIN_VARIABLE_INITIALIZING_PART */
881 /*============================= VARIABLE INITIALIZING PART =============================*/
882 LDV_IN_INTERRUPT=1;
883
884
885
886
887 /* LDV_COMMENT_END_VARIABLE_INITIALIZING_PART */
888 /* LDV_COMMENT_BEGIN_FUNCTION_CALL_SECTION */
889 /*============================= FUNCTION CALL SECTION =============================*/
890 /* LDV_COMMENT_FUNCTION_CALL Initialize LDV model. */
891 ldv_initialize();
892 int ldv_s_lenovo_driver_hid_driver = 0;
893
894
895
896 while( nondet_int()
897 || !(ldv_s_lenovo_driver_hid_driver == 0)
898 ) {
899
900 switch(nondet_int()) {
901
902 case 0: {
903
904 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
905 if(ldv_s_lenovo_driver_hid_driver==0) {
906
907 /* content: static int lenovo_probe(struct hid_device *hdev, const struct hid_device_id *id)*/
908 /* LDV_COMMENT_BEGIN_PREP */
909 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
910 #undef map_key_clear
911 /* LDV_COMMENT_END_PREP */
912 /* LDV_COMMENT_FUNCTION_CALL Function from field "probe" from driver structure with callbacks "lenovo_driver". Standart function test for correct return result. */
913 res_lenovo_probe_27 = lenovo_probe( var_group1, var_lenovo_probe_27_p1);
914 ldv_check_return_value(res_lenovo_probe_27);
915 ldv_check_return_value_probe(res_lenovo_probe_27);
916 if(res_lenovo_probe_27)
917 goto ldv_module_exit;
918 ldv_s_lenovo_driver_hid_driver++;
919
920 }
921
922 }
923
924 break;
925 case 1: {
926
927 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
928 if(ldv_s_lenovo_driver_hid_driver==1) {
929
930 /* content: static void lenovo_remove(struct hid_device *hdev)*/
931 /* LDV_COMMENT_BEGIN_PREP */
932 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
933 #undef map_key_clear
934 /* LDV_COMMENT_END_PREP */
935 /* LDV_COMMENT_FUNCTION_CALL Function from field "remove" from driver structure with callbacks "lenovo_driver" */
936 ldv_handler_precall();
937 lenovo_remove( var_group1);
938 ldv_s_lenovo_driver_hid_driver=0;
939
940 }
941
942 }
943
944 break;
945 case 2: {
946
947 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
948
949
950 /* content: static int lenovo_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max)*/
951 /* LDV_COMMENT_BEGIN_PREP */
952 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
953 /* LDV_COMMENT_END_PREP */
954 /* LDV_COMMENT_FUNCTION_CALL Function from field "input_mapping" from driver structure with callbacks "lenovo_driver" */
955 ldv_handler_precall();
956 lenovo_input_mapping( var_group1, var_group2, var_lenovo_input_mapping_2_p2, var_lenovo_input_mapping_2_p3, var_lenovo_input_mapping_2_p4, var_lenovo_input_mapping_2_p5);
957 /* LDV_COMMENT_BEGIN_PREP */
958 #undef map_key_clear
959 /* LDV_COMMENT_END_PREP */
960
961
962
963
964 }
965
966 break;
967 case 3: {
968
969 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
970
971
972 /* content: static int lenovo_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)*/
973 /* LDV_COMMENT_BEGIN_PREP */
974 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
975 #undef map_key_clear
976 /* LDV_COMMENT_END_PREP */
977 /* LDV_COMMENT_FUNCTION_CALL Function from field "raw_event" from driver structure with callbacks "lenovo_driver" */
978 ldv_handler_precall();
979 lenovo_raw_event( var_group1, var_group3, var_lenovo_raw_event_9_p2, var_lenovo_raw_event_9_p3);
980
981
982
983
984 }
985
986 break;
987 default: break;
988
989 }
990
991 }
992
993 ldv_module_exit:
994
995 /* LDV_COMMENT_FUNCTION_CALL Checks that all resources and locks are correctly released before the driver will be unloaded. */
996 ldv_final: ldv_check_final_state();
997
998 /* LDV_COMMENT_END_FUNCTION_CALL_SECTION */
999 return;
1000
1001 }
1002 #endif
1003
1004 /* LDV_COMMENT_END_MAIN */ 1
2 #include <linux/kernel.h>
3 bool ldv_is_err(const void *ptr);
4 bool ldv_is_err_or_null(const void *ptr);
5 void* ldv_err_ptr(long error);
6 long ldv_ptr_err(const void *ptr);
7
8
9 #include <linux/sysfs.h>
10 #include <verifier/rcv.h>
11 #include <verifier/multimap.h>
12
13 # 1 "/home/ldvuser/ldv/inst/kernel-rules/kernel-model/ERR.inc" 1
14 #ifndef _LDV_ERR_
15 #define _LDV_ERR_
16
17 #include <linux/kernel.h>
18
19 /* LDV_COMMENT_MODEL_FUNCTION_DEFENITION(name='ldv_is_err') This function return result of checking if pointer is impossible. */
20 bool ldv_is_err(const void *ptr)
21 {
22 /*LDV_COMMENT_RETURN Return value of function ldv_is_err_val().*/
23 return ((unsigned long)ptr > LDV_PTR_MAX);
24 }
25
26 /* LDV_COMMENT_MODEL_FUNCTION_DEFENITION(name='ldv_err_ptr') This function return pointer. */
27 void* ldv_err_ptr(long error)
28 {
29 /*LDV_COMMENT_RETURN Return error pointer.*/
30 return (void *)(LDV_PTR_MAX - error);
31 }
32
33 /* LDV_COMMENT_MODEL_FUNCTION_DEFENITION(name='ldv_ptr_err') This function return error if pointer is impossible. */
34 long ldv_ptr_err(const void *ptr)
35 {
36 /*LDV_COMMENT_RETURN Return error code.*/
37 return (long)(LDV_PTR_MAX - (unsigned long)ptr);
38 }
39
40 /* LDV_COMMENT_MODEL_FUNCTION_DEFENITION(name='ldv_is_err_or_null') This function check if pointer is impossible or null. */
41 bool ldv_is_err_or_null(const void *ptr)
42 {
43 /*LDV_COMMENT_RETURN Return 0 if pointer is possible and not zero, and 1 in other cases*/
44 return !ptr || ldv_is_err((unsigned long)ptr);
45 }
46
47 #endif /* _LDV_ERR_ */
48 # 11 "/home/ldvuser/ldv/inst/kernel-rules/models/0151.aspect" 2
49
50 MultiMap LDV_SYSFS_GROUPS = ldv_multimap_init(LDV_SYSFS_GROUPS);
51
52
53 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='ldv_sysfs_create_group') Create some sysfs group for specified kernel object */
54 int ldv_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) {
55 ldv_assert(ldv_multimap_not_contains_key_value(LDV_SYSFS_GROUPS, kobj, grp));
56 if (ldv_undef_int()) {
57 ldv_multimap_put(LDV_SYSFS_GROUPS, kobj, grp);
58 return 0;
59 }
60 return ldv_undef_int_negative();
61 }
62
63 /* LDV_COMMENT_MODEL_FUNCTION_DEFINITION(name='ldv_sysfs_remove_group') Remove some sysfs group from specified kernel object */
64 void ldv_sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp) {
65 ldv_multimap_remove_value(LDV_SYSFS_GROUPS, kobj, grp);
66 }
67
68 void ldv_check_final_state(void) {
69 ldv_assert(ldv_multimap_is_empty(LDV_SYSFS_GROUPS));
70 }
71 #line 1 "/work/ldvuser/ref_launch/work/current--X--drivers--X--defaultlinux-4.0-rc1.tar.xz--X--151_1a/linux-4.0-rc1.tar.xz/csd_deg_dscv/564/dscv_tempdir/dscv/ri/151_1a/drivers/hid/hid-lenovo.c"
72
73 /*
74 * HID driver for Lenovo:
75 * - ThinkPad USB Keyboard with TrackPoint (tpkbd)
76 * - ThinkPad Compact Bluetooth Keyboard with TrackPoint (cptkbd)
77 * - ThinkPad Compact USB Keyboard with TrackPoint (cptkbd)
78 *
79 * Copyright (c) 2012 Bernhard Seibold
80 * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk>
81 */
82
83 /*
84 * This program is free software; you can redistribute it and/or modify it
85 * under the terms of the GNU General Public License as published by the Free
86 * Software Foundation; either version 2 of the License, or (at your option)
87 * any later version.
88 */
89
90 #include <linux/module.h>
91 #include <linux/sysfs.h>
92 #include <linux/device.h>
93 #include <linux/hid.h>
94 #include <linux/input.h>
95 #include <linux/leds.h>
96
97 #include "hid-ids.h"
98
99 struct lenovo_drvdata_tpkbd {
100 int led_state;
101 struct led_classdev led_mute;
102 struct led_classdev led_micmute;
103 int press_to_select;
104 int dragging;
105 int release_to_select;
106 int select_right;
107 int sensitivity;
108 int press_speed;
109 };
110
111 struct lenovo_drvdata_cptkbd {
112 bool fn_lock;
113 int sensitivity;
114 };
115
116 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
117
118 static int lenovo_input_mapping_tpkbd(struct hid_device *hdev,
119 struct hid_input *hi, struct hid_field *field,
120 struct hid_usage *usage, unsigned long **bit, int *max)
121 {
122 if (usage->hid == (HID_UP_BUTTON | 0x0010)) {
123 /* This sub-device contains trackpoint, mark it */
124 hid_set_drvdata(hdev, (void *)1);
125 map_key_clear(KEY_MICMUTE);
126 return 1;
127 }
128 return 0;
129 }
130
131 static int lenovo_input_mapping_cptkbd(struct hid_device *hdev,
132 struct hid_input *hi, struct hid_field *field,
133 struct hid_usage *usage, unsigned long **bit, int *max)
134 {
135 /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */
136 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR ||
137 (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) {
138 switch (usage->hid & HID_USAGE) {
139 case 0x00f1: /* Fn-F4: Mic mute */
140 map_key_clear(KEY_MICMUTE);
141 return 1;
142 case 0x00f2: /* Fn-F5: Brightness down */
143 map_key_clear(KEY_BRIGHTNESSDOWN);
144 return 1;
145 case 0x00f3: /* Fn-F6: Brightness up */
146 map_key_clear(KEY_BRIGHTNESSUP);
147 return 1;
148 case 0x00f4: /* Fn-F7: External display (projector) */
149 map_key_clear(KEY_SWITCHVIDEOMODE);
150 return 1;
151 case 0x00f5: /* Fn-F8: Wireless */
152 map_key_clear(KEY_WLAN);
153 return 1;
154 case 0x00f6: /* Fn-F9: Control panel */
155 map_key_clear(KEY_CONFIG);
156 return 1;
157 case 0x00f8: /* Fn-F11: View open applications (3 boxes) */
158 map_key_clear(KEY_SCALE);
159 return 1;
160 case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */
161 /* NB: This mapping is invented in raw_event below */
162 map_key_clear(KEY_FILE);
163 return 1;
164 case 0x00fa: /* Fn-Esc: Fn-lock toggle */
165 map_key_clear(KEY_FN_ESC);
166 return 1;
167 case 0x00fb: /* Middle mouse button (in native mode) */
168 map_key_clear(BTN_MIDDLE);
169 return 1;
170 }
171 }
172
173 /* Compatibility middle/wheel mappings should be ignored */
174 if (usage->hid == HID_GD_WHEEL)
175 return -1;
176 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON &&
177 (usage->hid & HID_USAGE) == 0x003)
178 return -1;
179 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER &&
180 (usage->hid & HID_USAGE) == 0x238)
181 return -1;
182
183 /* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */
184 if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 ||
185 (usage->hid & HID_USAGE_PAGE) == 0xffa10000) {
186 field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE;
187 field->logical_minimum = -127;
188 field->logical_maximum = 127;
189
190 switch (usage->hid & HID_USAGE) {
191 case 0x0000:
192 hid_map_usage(hi, usage, bit, max, EV_REL, 0x06);
193 return 1;
194 case 0x0001:
195 hid_map_usage(hi, usage, bit, max, EV_REL, 0x08);
196 return 1;
197 default:
198 return -1;
199 }
200 }
201
202 return 0;
203 }
204
205 static int lenovo_input_mapping(struct hid_device *hdev,
206 struct hid_input *hi, struct hid_field *field,
207 struct hid_usage *usage, unsigned long **bit, int *max)
208 {
209 switch (hdev->product) {
210 case USB_DEVICE_ID_LENOVO_TPKBD:
211 return lenovo_input_mapping_tpkbd(hdev, hi, field,
212 usage, bit, max);
213 case USB_DEVICE_ID_LENOVO_CUSBKBD:
214 case USB_DEVICE_ID_LENOVO_CBTKBD:
215 return lenovo_input_mapping_cptkbd(hdev, hi, field,
216 usage, bit, max);
217 default:
218 return 0;
219 }
220 }
221
222 #undef map_key_clear
223
224 /* Send a config command to the keyboard */
225 static int lenovo_send_cmd_cptkbd(struct hid_device *hdev,
226 unsigned char byte2, unsigned char byte3)
227 {
228 int ret;
229 unsigned char buf[] = {0x18, byte2, byte3};
230
231 switch (hdev->product) {
232 case USB_DEVICE_ID_LENOVO_CUSBKBD:
233 ret = hid_hw_raw_request(hdev, 0x13, buf, sizeof(buf),
234 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
235 break;
236 case USB_DEVICE_ID_LENOVO_CBTKBD:
237 ret = hid_hw_output_report(hdev, buf, sizeof(buf));
238 break;
239 default:
240 ret = -EINVAL;
241 break;
242 }
243
244 return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */
245 }
246
247 static void lenovo_features_set_cptkbd(struct hid_device *hdev)
248 {
249 int ret;
250 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
251
252 ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock);
253 ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity);
254 if (ret)
255 hid_err(hdev, "Fn-lock setting failed: %d\n", ret);
256 }
257
258 static ssize_t attr_fn_lock_show_cptkbd(struct device *dev,
259 struct device_attribute *attr,
260 char *buf)
261 {
262 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
263 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
264
265 return snprintf(buf, PAGE_SIZE, "%u\n", cptkbd_data->fn_lock);
266 }
267
268 static ssize_t attr_fn_lock_store_cptkbd(struct device *dev,
269 struct device_attribute *attr,
270 const char *buf,
271 size_t count)
272 {
273 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
274 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
275 int value;
276
277 if (kstrtoint(buf, 10, &value))
278 return -EINVAL;
279 if (value < 0 || value > 1)
280 return -EINVAL;
281
282 cptkbd_data->fn_lock = !!value;
283 lenovo_features_set_cptkbd(hdev);
284
285 return count;
286 }
287
288 static ssize_t attr_sensitivity_show_cptkbd(struct device *dev,
289 struct device_attribute *attr,
290 char *buf)
291 {
292 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
293 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
294
295 return snprintf(buf, PAGE_SIZE, "%u\n",
296 cptkbd_data->sensitivity);
297 }
298
299 static ssize_t attr_sensitivity_store_cptkbd(struct device *dev,
300 struct device_attribute *attr,
301 const char *buf,
302 size_t count)
303 {
304 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
305 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev);
306 int value;
307
308 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
309 return -EINVAL;
310
311 cptkbd_data->sensitivity = value;
312 lenovo_features_set_cptkbd(hdev);
313
314 return count;
315 }
316
317
318 static struct device_attribute dev_attr_fn_lock_cptkbd =
319 __ATTR(fn_lock, S_IWUSR | S_IRUGO,
320 attr_fn_lock_show_cptkbd,
321 attr_fn_lock_store_cptkbd);
322
323 static struct device_attribute dev_attr_sensitivity_cptkbd =
324 __ATTR(sensitivity, S_IWUSR | S_IRUGO,
325 attr_sensitivity_show_cptkbd,
326 attr_sensitivity_store_cptkbd);
327
328
329 static struct attribute *lenovo_attributes_cptkbd[] = {
330 &dev_attr_fn_lock_cptkbd.attr,
331 &dev_attr_sensitivity_cptkbd.attr,
332 NULL
333 };
334
335 static const struct attribute_group lenovo_attr_group_cptkbd = {
336 .attrs = lenovo_attributes_cptkbd,
337 };
338
339 static int lenovo_raw_event(struct hid_device *hdev,
340 struct hid_report *report, u8 *data, int size)
341 {
342 /*
343 * Compact USB keyboard's Fn-F12 report holds down many other keys, and
344 * its own key is outside the usage page range. Remove extra
345 * keypresses and remap to inside usage page.
346 */
347 if (unlikely(hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
348 && size == 3
349 && data[0] == 0x15
350 && data[1] == 0x94
351 && data[2] == 0x01)) {
352 data[1] = 0x00;
353 data[2] = 0x01;
354 }
355
356 return 0;
357 }
358
359 static int lenovo_features_set_tpkbd(struct hid_device *hdev)
360 {
361 struct hid_report *report;
362 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
363
364 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4];
365
366 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02;
367 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08;
368 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20;
369 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40;
370 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver
371 report->field[2]->value[0] = data_pointer->sensitivity;
372 report->field[3]->value[0] = data_pointer->press_speed;
373
374 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
375 return 0;
376 }
377
378 static ssize_t attr_press_to_select_show_tpkbd(struct device *dev,
379 struct device_attribute *attr,
380 char *buf)
381 {
382 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
383 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
384
385 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select);
386 }
387
388 static ssize_t attr_press_to_select_store_tpkbd(struct device *dev,
389 struct device_attribute *attr,
390 const char *buf,
391 size_t count)
392 {
393 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
394 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
395 int value;
396
397 if (kstrtoint(buf, 10, &value))
398 return -EINVAL;
399 if (value < 0 || value > 1)
400 return -EINVAL;
401
402 data_pointer->press_to_select = value;
403 lenovo_features_set_tpkbd(hdev);
404
405 return count;
406 }
407
408 static ssize_t attr_dragging_show_tpkbd(struct device *dev,
409 struct device_attribute *attr,
410 char *buf)
411 {
412 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
413 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
414
415 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging);
416 }
417
418 static ssize_t attr_dragging_store_tpkbd(struct device *dev,
419 struct device_attribute *attr,
420 const char *buf,
421 size_t count)
422 {
423 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
424 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
425 int value;
426
427 if (kstrtoint(buf, 10, &value))
428 return -EINVAL;
429 if (value < 0 || value > 1)
430 return -EINVAL;
431
432 data_pointer->dragging = value;
433 lenovo_features_set_tpkbd(hdev);
434
435 return count;
436 }
437
438 static ssize_t attr_release_to_select_show_tpkbd(struct device *dev,
439 struct device_attribute *attr,
440 char *buf)
441 {
442 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
443 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
444
445 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select);
446 }
447
448 static ssize_t attr_release_to_select_store_tpkbd(struct device *dev,
449 struct device_attribute *attr,
450 const char *buf,
451 size_t count)
452 {
453 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
454 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
455 int value;
456
457 if (kstrtoint(buf, 10, &value))
458 return -EINVAL;
459 if (value < 0 || value > 1)
460 return -EINVAL;
461
462 data_pointer->release_to_select = value;
463 lenovo_features_set_tpkbd(hdev);
464
465 return count;
466 }
467
468 static ssize_t attr_select_right_show_tpkbd(struct device *dev,
469 struct device_attribute *attr,
470 char *buf)
471 {
472 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
473 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
474
475 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right);
476 }
477
478 static ssize_t attr_select_right_store_tpkbd(struct device *dev,
479 struct device_attribute *attr,
480 const char *buf,
481 size_t count)
482 {
483 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
484 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
485 int value;
486
487 if (kstrtoint(buf, 10, &value))
488 return -EINVAL;
489 if (value < 0 || value > 1)
490 return -EINVAL;
491
492 data_pointer->select_right = value;
493 lenovo_features_set_tpkbd(hdev);
494
495 return count;
496 }
497
498 static ssize_t attr_sensitivity_show_tpkbd(struct device *dev,
499 struct device_attribute *attr,
500 char *buf)
501 {
502 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
503 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
504
505 return snprintf(buf, PAGE_SIZE, "%u\n",
506 data_pointer->sensitivity);
507 }
508
509 static ssize_t attr_sensitivity_store_tpkbd(struct device *dev,
510 struct device_attribute *attr,
511 const char *buf,
512 size_t count)
513 {
514 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
515 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
516 int value;
517
518 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
519 return -EINVAL;
520
521 data_pointer->sensitivity = value;
522 lenovo_features_set_tpkbd(hdev);
523
524 return count;
525 }
526
527 static ssize_t attr_press_speed_show_tpkbd(struct device *dev,
528 struct device_attribute *attr,
529 char *buf)
530 {
531 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
532 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
533
534 return snprintf(buf, PAGE_SIZE, "%u\n",
535 data_pointer->press_speed);
536 }
537
538 static ssize_t attr_press_speed_store_tpkbd(struct device *dev,
539 struct device_attribute *attr,
540 const char *buf,
541 size_t count)
542 {
543 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
544 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
545 int value;
546
547 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
548 return -EINVAL;
549
550 data_pointer->press_speed = value;
551 lenovo_features_set_tpkbd(hdev);
552
553 return count;
554 }
555
556 static struct device_attribute dev_attr_press_to_select_tpkbd =
557 __ATTR(press_to_select, S_IWUSR | S_IRUGO,
558 attr_press_to_select_show_tpkbd,
559 attr_press_to_select_store_tpkbd);
560
561 static struct device_attribute dev_attr_dragging_tpkbd =
562 __ATTR(dragging, S_IWUSR | S_IRUGO,
563 attr_dragging_show_tpkbd,
564 attr_dragging_store_tpkbd);
565
566 static struct device_attribute dev_attr_release_to_select_tpkbd =
567 __ATTR(release_to_select, S_IWUSR | S_IRUGO,
568 attr_release_to_select_show_tpkbd,
569 attr_release_to_select_store_tpkbd);
570
571 static struct device_attribute dev_attr_select_right_tpkbd =
572 __ATTR(select_right, S_IWUSR | S_IRUGO,
573 attr_select_right_show_tpkbd,
574 attr_select_right_store_tpkbd);
575
576 static struct device_attribute dev_attr_sensitivity_tpkbd =
577 __ATTR(sensitivity, S_IWUSR | S_IRUGO,
578 attr_sensitivity_show_tpkbd,
579 attr_sensitivity_store_tpkbd);
580
581 static struct device_attribute dev_attr_press_speed_tpkbd =
582 __ATTR(press_speed, S_IWUSR | S_IRUGO,
583 attr_press_speed_show_tpkbd,
584 attr_press_speed_store_tpkbd);
585
586 static struct attribute *lenovo_attributes_tpkbd[] = {
587 &dev_attr_press_to_select_tpkbd.attr,
588 &dev_attr_dragging_tpkbd.attr,
589 &dev_attr_release_to_select_tpkbd.attr,
590 &dev_attr_select_right_tpkbd.attr,
591 &dev_attr_sensitivity_tpkbd.attr,
592 &dev_attr_press_speed_tpkbd.attr,
593 NULL
594 };
595
596 static const struct attribute_group lenovo_attr_group_tpkbd = {
597 .attrs = lenovo_attributes_tpkbd,
598 };
599
600 static enum led_brightness lenovo_led_brightness_get_tpkbd(
601 struct led_classdev *led_cdev)
602 {
603 struct device *dev = led_cdev->dev->parent;
604 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
605 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
606 int led_nr = 0;
607
608 if (led_cdev == &data_pointer->led_micmute)
609 led_nr = 1;
610
611 return data_pointer->led_state & (1 << led_nr)
612 ? LED_FULL
613 : LED_OFF;
614 }
615
616 static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev,
617 enum led_brightness value)
618 {
619 struct device *dev = led_cdev->dev->parent;
620 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
621 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
622 struct hid_report *report;
623 int led_nr = 0;
624
625 if (led_cdev == &data_pointer->led_micmute)
626 led_nr = 1;
627
628 if (value == LED_OFF)
629 data_pointer->led_state &= ~(1 << led_nr);
630 else
631 data_pointer->led_state |= 1 << led_nr;
632
633 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
634 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
635 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
636 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
637 }
638
639 static int lenovo_probe_tpkbd(struct hid_device *hdev)
640 {
641 struct device *dev = &hdev->dev;
642 struct lenovo_drvdata_tpkbd *data_pointer;
643 size_t name_sz = strlen(dev_name(dev)) + 16;
644 char *name_mute, *name_micmute;
645 int i;
646 int ret;
647
648 /*
649 * Only register extra settings against subdevice where input_mapping
650 * set drvdata to 1, i.e. the trackpoint.
651 */
652 if (!hid_get_drvdata(hdev))
653 return 0;
654
655 hid_set_drvdata(hdev, NULL);
656
657 /* Validate required reports. */
658 for (i = 0; i < 4; i++) {
659 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
660 return -ENODEV;
661 }
662 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2))
663 return -ENODEV;
664
665 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd);
666 if (ret)
667 hid_warn(hdev, "Could not create sysfs group: %d\n", ret);
668
669 data_pointer = devm_kzalloc(&hdev->dev,
670 sizeof(struct lenovo_drvdata_tpkbd),
671 GFP_KERNEL);
672 if (data_pointer == NULL) {
673 hid_err(hdev, "Could not allocate memory for driver data\n");
674 return -ENOMEM;
675 }
676
677 // set same default values as windows driver
678 data_pointer->sensitivity = 0xa0;
679 data_pointer->press_speed = 0x38;
680
681 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
682 name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
683 if (name_mute == NULL || name_micmute == NULL) {
684 hid_err(hdev, "Could not allocate memory for led data\n");
685 return -ENOMEM;
686 }
687 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
688 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
689
690 hid_set_drvdata(hdev, data_pointer);
691
692 data_pointer->led_mute.name = name_mute;
693 data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd;
694 data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd;
695 data_pointer->led_mute.dev = dev;
696 led_classdev_register(dev, &data_pointer->led_mute);
697
698 data_pointer->led_micmute.name = name_micmute;
699 data_pointer->led_micmute.brightness_get =
700 lenovo_led_brightness_get_tpkbd;
701 data_pointer->led_micmute.brightness_set =
702 lenovo_led_brightness_set_tpkbd;
703 data_pointer->led_micmute.dev = dev;
704 led_classdev_register(dev, &data_pointer->led_micmute);
705
706 lenovo_features_set_tpkbd(hdev);
707
708 return 0;
709 }
710
711 static int lenovo_probe_cptkbd(struct hid_device *hdev)
712 {
713 int ret;
714 struct lenovo_drvdata_cptkbd *cptkbd_data;
715
716 /* All the custom action happens on the USBMOUSE device for USB */
717 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD
718 && hdev->type != HID_TYPE_USBMOUSE) {
719 hid_dbg(hdev, "Ignoring keyboard half of device\n");
720 return 0;
721 }
722
723 cptkbd_data = devm_kzalloc(&hdev->dev,
724 sizeof(*cptkbd_data),
725 GFP_KERNEL);
726 if (cptkbd_data == NULL) {
727 hid_err(hdev, "can't alloc keyboard descriptor\n");
728 return -ENOMEM;
729 }
730 hid_set_drvdata(hdev, cptkbd_data);
731
732 /*
733 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into
734 * regular keys
735 */
736 ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03);
737 if (ret)
738 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret);
739
740 /* Switch middle button to native mode */
741 ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01);
742 if (ret)
743 hid_warn(hdev, "Failed to switch middle button: %d\n", ret);
744
745 /* Set keyboard settings to known state */
746 cptkbd_data->fn_lock = true;
747 cptkbd_data->sensitivity = 0x05;
748 lenovo_features_set_cptkbd(hdev);
749
750 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
751 if (ret)
752 hid_warn(hdev, "Could not create sysfs group: %d\n", ret);
753
754 return 0;
755 }
756
757 static int lenovo_probe(struct hid_device *hdev,
758 const struct hid_device_id *id)
759 {
760 int ret;
761
762 ret = hid_parse(hdev);
763 if (ret) {
764 hid_err(hdev, "hid_parse failed\n");
765 goto err;
766 }
767
768 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
769 if (ret) {
770 hid_err(hdev, "hid_hw_start failed\n");
771 goto err;
772 }
773
774 switch (hdev->product) {
775 case USB_DEVICE_ID_LENOVO_TPKBD:
776 ret = lenovo_probe_tpkbd(hdev);
777 break;
778 case USB_DEVICE_ID_LENOVO_CUSBKBD:
779 case USB_DEVICE_ID_LENOVO_CBTKBD:
780 ret = lenovo_probe_cptkbd(hdev);
781 break;
782 default:
783 ret = 0;
784 break;
785 }
786 if (ret)
787 goto err_hid;
788
789 return 0;
790 err_hid:
791 hid_hw_stop(hdev);
792 err:
793 return ret;
794 }
795
796 static void lenovo_remove_tpkbd(struct hid_device *hdev)
797 {
798 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
799
800 /*
801 * Only the trackpoint half of the keyboard has drvdata and stuff that
802 * needs unregistering.
803 */
804 if (data_pointer == NULL)
805 return;
806
807 sysfs_remove_group(&hdev->dev.kobj,
808 &lenovo_attr_group_tpkbd);
809
810 led_classdev_unregister(&data_pointer->led_micmute);
811 led_classdev_unregister(&data_pointer->led_mute);
812
813 hid_set_drvdata(hdev, NULL);
814 }
815
816 static void lenovo_remove_cptkbd(struct hid_device *hdev)
817 {
818 sysfs_remove_group(&hdev->dev.kobj,
819 &lenovo_attr_group_cptkbd);
820 }
821
822 static void lenovo_remove(struct hid_device *hdev)
823 {
824 switch (hdev->product) {
825 case USB_DEVICE_ID_LENOVO_TPKBD:
826 lenovo_remove_tpkbd(hdev);
827 break;
828 case USB_DEVICE_ID_LENOVO_CUSBKBD:
829 case USB_DEVICE_ID_LENOVO_CBTKBD:
830 lenovo_remove_cptkbd(hdev);
831 break;
832 }
833
834 hid_hw_stop(hdev);
835 }
836
837 static const struct hid_device_id lenovo_devices[] = {
838 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
839 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
840 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
841 { }
842 };
843
844 MODULE_DEVICE_TABLE(hid, lenovo_devices);
845
846 static struct hid_driver lenovo_driver = {
847 .name = "lenovo",
848 .id_table = lenovo_devices,
849 .input_mapping = lenovo_input_mapping,
850 .probe = lenovo_probe,
851 .remove = lenovo_remove,
852 .raw_event = lenovo_raw_event,
853 };
854 module_hid_driver(lenovo_driver);
855
856 MODULE_LICENSE("GPL");
857
858
859
860
861
862 /* LDV_COMMENT_BEGIN_MAIN */
863 #ifdef LDV_MAIN0_sequence_infinite_withcheck_stateful
864
865 /*###########################################################################*/
866
867 /*############## Driver Environment Generator 0.2 output ####################*/
868
869 /*###########################################################################*/
870
871
872
873 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Test if all kernel resources are correctly released by driver before driver will be unloaded. */
874 void ldv_check_final_state(void);
875
876 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Test correct return result. */
877 void ldv_check_return_value(int res);
878
879 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Test correct return result of probe() function. */
880 void ldv_check_return_value_probe(int res);
881
882 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Initializes the model. */
883 void ldv_initialize(void);
884
885 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Reinitializes the model between distinct model function calls. */
886 void ldv_handler_precall(void);
887
888 /* LDV_COMMENT_FUNCTION_DECLARE_LDV Special function for LDV verifier. Returns arbitrary interger value. */
889 int nondet_int(void);
890
891 /* LDV_COMMENT_VAR_DECLARE_LDV Special variable for LDV verifier. */
892 int LDV_IN_INTERRUPT;
893
894 /* LDV_COMMENT_FUNCTION_MAIN Main function for LDV verifier. */
895 void ldv_main0_sequence_infinite_withcheck_stateful(void) {
896
897
898
899 /* LDV_COMMENT_BEGIN_VARIABLE_DECLARATION_PART */
900 /*============================= VARIABLE DECLARATION PART =============================*/
901 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
902 /* content: static int lenovo_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max)*/
903 /* LDV_COMMENT_BEGIN_PREP */
904 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
905 /* LDV_COMMENT_END_PREP */
906 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
907 struct hid_device * var_group1;
908 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
909 struct hid_input * var_group2;
910 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
911 struct hid_field * var_lenovo_input_mapping_2_p2;
912 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
913 struct hid_usage * var_lenovo_input_mapping_2_p3;
914 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
915 unsigned long ** var_lenovo_input_mapping_2_p4;
916 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_input_mapping" */
917 int * var_lenovo_input_mapping_2_p5;
918 /* LDV_COMMENT_BEGIN_PREP */
919 #undef map_key_clear
920 /* LDV_COMMENT_END_PREP */
921 /* content: static int lenovo_probe(struct hid_device *hdev, const struct hid_device_id *id)*/
922 /* LDV_COMMENT_BEGIN_PREP */
923 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
924 #undef map_key_clear
925 /* LDV_COMMENT_END_PREP */
926 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_probe" */
927 const struct hid_device_id * var_lenovo_probe_27_p1;
928 /* LDV_COMMENT_VAR_DECLARE Variable declaration for test return result from function call "lenovo_probe" */
929 static int res_lenovo_probe_27;
930 /* content: static void lenovo_remove(struct hid_device *hdev)*/
931 /* LDV_COMMENT_BEGIN_PREP */
932 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
933 #undef map_key_clear
934 /* LDV_COMMENT_END_PREP */
935 /* content: static int lenovo_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)*/
936 /* LDV_COMMENT_BEGIN_PREP */
937 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
938 #undef map_key_clear
939 /* LDV_COMMENT_END_PREP */
940 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_raw_event" */
941 struct hid_report * var_group3;
942 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_raw_event" */
943 u8 * var_lenovo_raw_event_9_p2;
944 /* LDV_COMMENT_VAR_DECLARE Variable declaration for function "lenovo_raw_event" */
945 int var_lenovo_raw_event_9_p3;
946
947
948
949
950 /* LDV_COMMENT_END_VARIABLE_DECLARATION_PART */
951 /* LDV_COMMENT_BEGIN_VARIABLE_INITIALIZING_PART */
952 /*============================= VARIABLE INITIALIZING PART =============================*/
953 LDV_IN_INTERRUPT=1;
954
955
956
957
958 /* LDV_COMMENT_END_VARIABLE_INITIALIZING_PART */
959 /* LDV_COMMENT_BEGIN_FUNCTION_CALL_SECTION */
960 /*============================= FUNCTION CALL SECTION =============================*/
961 /* LDV_COMMENT_FUNCTION_CALL Initialize LDV model. */
962 ldv_initialize();
963 int ldv_s_lenovo_driver_hid_driver = 0;
964
965
966
967 while( nondet_int()
968 || !(ldv_s_lenovo_driver_hid_driver == 0)
969 ) {
970
971 switch(nondet_int()) {
972
973 case 0: {
974
975 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
976 if(ldv_s_lenovo_driver_hid_driver==0) {
977
978 /* content: static int lenovo_probe(struct hid_device *hdev, const struct hid_device_id *id)*/
979 /* LDV_COMMENT_BEGIN_PREP */
980 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
981 #undef map_key_clear
982 /* LDV_COMMENT_END_PREP */
983 /* LDV_COMMENT_FUNCTION_CALL Function from field "probe" from driver structure with callbacks "lenovo_driver". Standart function test for correct return result. */
984 res_lenovo_probe_27 = lenovo_probe( var_group1, var_lenovo_probe_27_p1);
985 ldv_check_return_value(res_lenovo_probe_27);
986 ldv_check_return_value_probe(res_lenovo_probe_27);
987 if(res_lenovo_probe_27)
988 goto ldv_module_exit;
989 ldv_s_lenovo_driver_hid_driver++;
990
991 }
992
993 }
994
995 break;
996 case 1: {
997
998 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
999 if(ldv_s_lenovo_driver_hid_driver==1) {
1000
1001 /* content: static void lenovo_remove(struct hid_device *hdev)*/
1002 /* LDV_COMMENT_BEGIN_PREP */
1003 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
1004 #undef map_key_clear
1005 /* LDV_COMMENT_END_PREP */
1006 /* LDV_COMMENT_FUNCTION_CALL Function from field "remove" from driver structure with callbacks "lenovo_driver" */
1007 ldv_handler_precall();
1008 lenovo_remove( var_group1);
1009 ldv_s_lenovo_driver_hid_driver=0;
1010
1011 }
1012
1013 }
1014
1015 break;
1016 case 2: {
1017
1018 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
1019
1020
1021 /* content: static int lenovo_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max)*/
1022 /* LDV_COMMENT_BEGIN_PREP */
1023 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
1024 /* LDV_COMMENT_END_PREP */
1025 /* LDV_COMMENT_FUNCTION_CALL Function from field "input_mapping" from driver structure with callbacks "lenovo_driver" */
1026 ldv_handler_precall();
1027 lenovo_input_mapping( var_group1, var_group2, var_lenovo_input_mapping_2_p2, var_lenovo_input_mapping_2_p3, var_lenovo_input_mapping_2_p4, var_lenovo_input_mapping_2_p5);
1028 /* LDV_COMMENT_BEGIN_PREP */
1029 #undef map_key_clear
1030 /* LDV_COMMENT_END_PREP */
1031
1032
1033
1034
1035 }
1036
1037 break;
1038 case 3: {
1039
1040 /** STRUCT: struct type: hid_driver, struct name: lenovo_driver **/
1041
1042
1043 /* content: static int lenovo_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size)*/
1044 /* LDV_COMMENT_BEGIN_PREP */
1045 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
1046 #undef map_key_clear
1047 /* LDV_COMMENT_END_PREP */
1048 /* LDV_COMMENT_FUNCTION_CALL Function from field "raw_event" from driver structure with callbacks "lenovo_driver" */
1049 ldv_handler_precall();
1050 lenovo_raw_event( var_group1, var_group3, var_lenovo_raw_event_9_p2, var_lenovo_raw_event_9_p3);
1051
1052
1053
1054
1055 }
1056
1057 break;
1058 default: break;
1059
1060 }
1061
1062 }
1063
1064 ldv_module_exit:
1065
1066 /* LDV_COMMENT_FUNCTION_CALL Checks that all resources and locks are correctly released before the driver will be unloaded. */
1067 ldv_final: ldv_check_final_state();
1068
1069 /* LDV_COMMENT_END_FUNCTION_CALL_SECTION */
1070 return;
1071
1072 }
1073 #endif
1074
1075 /* LDV_COMMENT_END_MAIN */
1076
1077 #line 71 "/work/ldvuser/ref_launch/work/current--X--drivers--X--defaultlinux-4.0-rc1.tar.xz--X--151_1a/linux-4.0-rc1.tar.xz/csd_deg_dscv/564/dscv_tempdir/dscv/ri/151_1a/drivers/hid/hid-lenovo.o.c.prepared" 1 #ifndef _LDV_RCV_H_
2 #define _LDV_RCV_H_
3
4 /* If expr evaluates to zero, ldv_assert() causes a program to reach the error
5 label like the standard assert(). */
6 #define ldv_assert(expr) ((expr) ? 0 : ldv_error())
7
8 /* The error label wrapper. It is used because of some static verifiers (like
9 BLAST) don't accept multiple error labels through a program. */
10 static inline void ldv_error(void)
11 {
12 LDV_ERROR: goto LDV_ERROR;
13 }
14
15 /* If expr evaluates to zero, ldv_assume() causes an infinite loop that is
16 avoided by verifiers. */
17 #define ldv_assume(expr) ((expr) ? 0 : ldv_stop())
18
19 /* Infinite loop, that causes verifiers to skip such paths. */
20 static inline void ldv_stop(void) {
21 LDV_STOP: goto LDV_STOP;
22 }
23
24 /* Special nondeterministic functions. */
25 int ldv_undef_int(void);
26 void *ldv_undef_ptr(void);
27 unsigned long ldv_undef_ulong(void);
28 long ldv_undef_long(void);
29 /* Return nondeterministic negative integer number. */
30 static inline int ldv_undef_int_negative(void)
31 {
32 int ret = ldv_undef_int();
33
34 ldv_assume(ret < 0);
35
36 return ret;
37 }
38 /* Return nondeterministic nonpositive integer number. */
39 static inline int ldv_undef_int_nonpositive(void)
40 {
41 int ret = ldv_undef_int();
42
43 ldv_assume(ret <= 0);
44
45 return ret;
46 }
47
48 /* Add explicit model for __builin_expect GCC function. Without the model a
49 return value will be treated as nondetermined by verifiers. */
50 long __builtin_expect(long exp, long c)
51 {
52 return exp;
53 }
54
55 /* This function causes the program to exit abnormally. GCC implements this
56 function by using a target-dependent mechanism (such as intentionally executing
57 an illegal instruction) or by calling abort. The mechanism used may vary from
58 release to release so you should not rely on any particular implementation.
59 http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
60 void __builtin_trap(void)
61 {
62 ldv_assert(0);
63 }
64
65 /* The constant is for simulating an error of ldv_undef_ptr() function. */
66 #define LDV_PTR_MAX 2012
67
68 #endif /* _LDV_RCV_H_ */ 1 /*
2 * Copyright (c) 1999 Andreas Gal
3 * Copyright (c) 2000-2001 Vojtech Pavlik
4 * Copyright (c) 2006-2007 Jiri Kosina
5 */
6 /*
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Should you need to contact me, the author, you can do so either by
22 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
23 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
24 */
25 #ifndef __HID_H
26 #define __HID_H
27
28
29 #include <linux/types.h>
30 #include <linux/slab.h>
31 #include <linux/list.h>
32 #include <linux/mod_devicetable.h> /* hid_device_id */
33 #include <linux/timer.h>
34 #include <linux/workqueue.h>
35 #include <linux/input.h>
36 #include <linux/semaphore.h>
37 #include <linux/power_supply.h>
38 #include <uapi/linux/hid.h>
39
40 /*
41 * We parse each description item into this structure. Short items data
42 * values are expanded to 32-bit signed int, long items contain a pointer
43 * into the data area.
44 */
45
46 struct hid_item {
47 unsigned format;
48 __u8 size;
49 __u8 type;
50 __u8 tag;
51 union {
52 __u8 u8;
53 __s8 s8;
54 __u16 u16;
55 __s16 s16;
56 __u32 u32;
57 __s32 s32;
58 __u8 *longdata;
59 } data;
60 };
61
62 /*
63 * HID report item format
64 */
65
66 #define HID_ITEM_FORMAT_SHORT 0
67 #define HID_ITEM_FORMAT_LONG 1
68
69 /*
70 * Special tag indicating long items
71 */
72
73 #define HID_ITEM_TAG_LONG 15
74
75 /*
76 * HID report descriptor item type (prefix bit 2,3)
77 */
78
79 #define HID_ITEM_TYPE_MAIN 0
80 #define HID_ITEM_TYPE_GLOBAL 1
81 #define HID_ITEM_TYPE_LOCAL 2
82 #define HID_ITEM_TYPE_RESERVED 3
83
84 /*
85 * HID report descriptor main item tags
86 */
87
88 #define HID_MAIN_ITEM_TAG_INPUT 8
89 #define HID_MAIN_ITEM_TAG_OUTPUT 9
90 #define HID_MAIN_ITEM_TAG_FEATURE 11
91 #define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10
92 #define HID_MAIN_ITEM_TAG_END_COLLECTION 12
93
94 /*
95 * HID report descriptor main item contents
96 */
97
98 #define HID_MAIN_ITEM_CONSTANT 0x001
99 #define HID_MAIN_ITEM_VARIABLE 0x002
100 #define HID_MAIN_ITEM_RELATIVE 0x004
101 #define HID_MAIN_ITEM_WRAP 0x008
102 #define HID_MAIN_ITEM_NONLINEAR 0x010
103 #define HID_MAIN_ITEM_NO_PREFERRED 0x020
104 #define HID_MAIN_ITEM_NULL_STATE 0x040
105 #define HID_MAIN_ITEM_VOLATILE 0x080
106 #define HID_MAIN_ITEM_BUFFERED_BYTE 0x100
107
108 /*
109 * HID report descriptor collection item types
110 */
111
112 #define HID_COLLECTION_PHYSICAL 0
113 #define HID_COLLECTION_APPLICATION 1
114 #define HID_COLLECTION_LOGICAL 2
115
116 /*
117 * HID report descriptor global item tags
118 */
119
120 #define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0
121 #define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1
122 #define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2
123 #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3
124 #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4
125 #define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5
126 #define HID_GLOBAL_ITEM_TAG_UNIT 6
127 #define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7
128 #define HID_GLOBAL_ITEM_TAG_REPORT_ID 8
129 #define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9
130 #define HID_GLOBAL_ITEM_TAG_PUSH 10
131 #define HID_GLOBAL_ITEM_TAG_POP 11
132
133 /*
134 * HID report descriptor local item tags
135 */
136
137 #define HID_LOCAL_ITEM_TAG_USAGE 0
138 #define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1
139 #define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2
140 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3
141 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4
142 #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5
143 #define HID_LOCAL_ITEM_TAG_STRING_INDEX 7
144 #define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8
145 #define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9
146 #define HID_LOCAL_ITEM_TAG_DELIMITER 10
147
148 /*
149 * HID usage tables
150 */
151
152 #define HID_USAGE_PAGE 0xffff0000
153
154 #define HID_UP_UNDEFINED 0x00000000
155 #define HID_UP_GENDESK 0x00010000
156 #define HID_UP_SIMULATION 0x00020000
157 #define HID_UP_GENDEVCTRLS 0x00060000
158 #define HID_UP_KEYBOARD 0x00070000
159 #define HID_UP_LED 0x00080000
160 #define HID_UP_BUTTON 0x00090000
161 #define HID_UP_ORDINAL 0x000a0000
162 #define HID_UP_CONSUMER 0x000c0000
163 #define HID_UP_DIGITIZER 0x000d0000
164 #define HID_UP_PID 0x000f0000
165 #define HID_UP_HPVENDOR 0xff7f0000
166 #define HID_UP_HPVENDOR2 0xff010000
167 #define HID_UP_MSVENDOR 0xff000000
168 #define HID_UP_CUSTOM 0x00ff0000
169 #define HID_UP_LOGIVENDOR 0xffbc0000
170 #define HID_UP_LNVENDOR 0xffa00000
171 #define HID_UP_SENSOR 0x00200000
172
173 #define HID_USAGE 0x0000ffff
174
175 #define HID_GD_POINTER 0x00010001
176 #define HID_GD_MOUSE 0x00010002
177 #define HID_GD_JOYSTICK 0x00010004
178 #define HID_GD_GAMEPAD 0x00010005
179 #define HID_GD_KEYBOARD 0x00010006
180 #define HID_GD_KEYPAD 0x00010007
181 #define HID_GD_MULTIAXIS 0x00010008
182 #define HID_GD_X 0x00010030
183 #define HID_GD_Y 0x00010031
184 #define HID_GD_Z 0x00010032
185 #define HID_GD_RX 0x00010033
186 #define HID_GD_RY 0x00010034
187 #define HID_GD_RZ 0x00010035
188 #define HID_GD_SLIDER 0x00010036
189 #define HID_GD_DIAL 0x00010037
190 #define HID_GD_WHEEL 0x00010038
191 #define HID_GD_HATSWITCH 0x00010039
192 #define HID_GD_BUFFER 0x0001003a
193 #define HID_GD_BYTECOUNT 0x0001003b
194 #define HID_GD_MOTION 0x0001003c
195 #define HID_GD_START 0x0001003d
196 #define HID_GD_SELECT 0x0001003e
197 #define HID_GD_VX 0x00010040
198 #define HID_GD_VY 0x00010041
199 #define HID_GD_VZ 0x00010042
200 #define HID_GD_VBRX 0x00010043
201 #define HID_GD_VBRY 0x00010044
202 #define HID_GD_VBRZ 0x00010045
203 #define HID_GD_VNO 0x00010046
204 #define HID_GD_FEATURE 0x00010047
205 #define HID_GD_SYSTEM_CONTROL 0x00010080
206 #define HID_GD_UP 0x00010090
207 #define HID_GD_DOWN 0x00010091
208 #define HID_GD_RIGHT 0x00010092
209 #define HID_GD_LEFT 0x00010093
210
211 #define HID_DC_BATTERYSTRENGTH 0x00060020
212
213 #define HID_CP_CONSUMER_CONTROL 0x000c0001
214
215 #define HID_DG_DIGITIZER 0x000d0001
216 #define HID_DG_PEN 0x000d0002
217 #define HID_DG_LIGHTPEN 0x000d0003
218 #define HID_DG_TOUCHSCREEN 0x000d0004
219 #define HID_DG_TOUCHPAD 0x000d0005
220 #define HID_DG_STYLUS 0x000d0020
221 #define HID_DG_PUCK 0x000d0021
222 #define HID_DG_FINGER 0x000d0022
223 #define HID_DG_TIPPRESSURE 0x000d0030
224 #define HID_DG_BARRELPRESSURE 0x000d0031
225 #define HID_DG_INRANGE 0x000d0032
226 #define HID_DG_TOUCH 0x000d0033
227 #define HID_DG_UNTOUCH 0x000d0034
228 #define HID_DG_TAP 0x000d0035
229 #define HID_DG_TABLETFUNCTIONKEY 0x000d0039
230 #define HID_DG_PROGRAMCHANGEKEY 0x000d003a
231 #define HID_DG_INVERT 0x000d003c
232 #define HID_DG_TIPSWITCH 0x000d0042
233 #define HID_DG_TIPSWITCH2 0x000d0043
234 #define HID_DG_BARRELSWITCH 0x000d0044
235 #define HID_DG_ERASER 0x000d0045
236 #define HID_DG_TABLETPICK 0x000d0046
237
238 #define HID_CP_CONSUMERCONTROL 0x000c0001
239 #define HID_CP_NUMERICKEYPAD 0x000c0002
240 #define HID_CP_PROGRAMMABLEBUTTONS 0x000c0003
241 #define HID_CP_MICROPHONE 0x000c0004
242 #define HID_CP_HEADPHONE 0x000c0005
243 #define HID_CP_GRAPHICEQUALIZER 0x000c0006
244 #define HID_CP_FUNCTIONBUTTONS 0x000c0036
245 #define HID_CP_SELECTION 0x000c0080
246 #define HID_CP_MEDIASELECTION 0x000c0087
247 #define HID_CP_SELECTDISC 0x000c00ba
248 #define HID_CP_PLAYBACKSPEED 0x000c00f1
249 #define HID_CP_PROXIMITY 0x000c0109
250 #define HID_CP_SPEAKERSYSTEM 0x000c0160
251 #define HID_CP_CHANNELLEFT 0x000c0161
252 #define HID_CP_CHANNELRIGHT 0x000c0162
253 #define HID_CP_CHANNELCENTER 0x000c0163
254 #define HID_CP_CHANNELFRONT 0x000c0164
255 #define HID_CP_CHANNELCENTERFRONT 0x000c0165
256 #define HID_CP_CHANNELSIDE 0x000c0166
257 #define HID_CP_CHANNELSURROUND 0x000c0167
258 #define HID_CP_CHANNELLOWFREQUENCYENHANCEMENT 0x000c0168
259 #define HID_CP_CHANNELTOP 0x000c0169
260 #define HID_CP_CHANNELUNKNOWN 0x000c016a
261 #define HID_CP_APPLICATIONLAUNCHBUTTONS 0x000c0180
262 #define HID_CP_GENERICGUIAPPLICATIONCONTROLS 0x000c0200
263
264 #define HID_DG_CONFIDENCE 0x000d0047
265 #define HID_DG_WIDTH 0x000d0048
266 #define HID_DG_HEIGHT 0x000d0049
267 #define HID_DG_CONTACTID 0x000d0051
268 #define HID_DG_INPUTMODE 0x000d0052
269 #define HID_DG_DEVICEINDEX 0x000d0053
270 #define HID_DG_CONTACTCOUNT 0x000d0054
271 #define HID_DG_CONTACTMAX 0x000d0055
272 #define HID_DG_BARRELSWITCH2 0x000d005a
273 #define HID_DG_TOOLSERIALNUMBER 0x000d005b
274
275 /*
276 * HID report types --- Ouch! HID spec says 1 2 3!
277 */
278
279 #define HID_INPUT_REPORT 0
280 #define HID_OUTPUT_REPORT 1
281 #define HID_FEATURE_REPORT 2
282
283 #define HID_REPORT_TYPES 3
284
285 /*
286 * HID connect requests
287 */
288
289 #define HID_CONNECT_HIDINPUT 0x01
290 #define HID_CONNECT_HIDINPUT_FORCE 0x02
291 #define HID_CONNECT_HIDRAW 0x04
292 #define HID_CONNECT_HIDDEV 0x08
293 #define HID_CONNECT_HIDDEV_FORCE 0x10
294 #define HID_CONNECT_FF 0x20
295 #define HID_CONNECT_DRIVER 0x40
296 #define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \
297 HID_CONNECT_HIDDEV|HID_CONNECT_FF)
298
299 /*
300 * HID device quirks.
301 */
302
303 /*
304 * Increase this if you need to configure more HID quirks at module load time
305 */
306 #define MAX_USBHID_BOOT_QUIRKS 4
307
308 #define HID_QUIRK_INVERT 0x00000001
309 #define HID_QUIRK_NOTOUCH 0x00000002
310 #define HID_QUIRK_IGNORE 0x00000004
311 #define HID_QUIRK_NOGET 0x00000008
312 #define HID_QUIRK_HIDDEV_FORCE 0x00000010
313 #define HID_QUIRK_BADPAD 0x00000020
314 #define HID_QUIRK_MULTI_INPUT 0x00000040
315 #define HID_QUIRK_HIDINPUT_FORCE 0x00000080
316 #define HID_QUIRK_NO_EMPTY_INPUT 0x00000100
317 #define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200
318 #define HID_QUIRK_ALWAYS_POLL 0x00000400
319 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
320 #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000
321 #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000
322 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
323 #define HID_QUIRK_NO_INIT_REPORTS 0x20000000
324 #define HID_QUIRK_NO_IGNORE 0x40000000
325 #define HID_QUIRK_NO_INPUT_SYNC 0x80000000
326
327 /*
328 * HID device groups
329 *
330 * Note: HID_GROUP_ANY is declared in linux/mod_devicetable.h
331 * and has a value of 0x0000
332 */
333 #define HID_GROUP_GENERIC 0x0001
334 #define HID_GROUP_MULTITOUCH 0x0002
335 #define HID_GROUP_SENSOR_HUB 0x0003
336 #define HID_GROUP_MULTITOUCH_WIN_8 0x0004
337
338 /*
339 * Vendor specific HID device groups
340 */
341 #define HID_GROUP_RMI 0x0100
342 #define HID_GROUP_WACOM 0x0101
343 #define HID_GROUP_LOGITECH_DJ_DEVICE 0x0102
344
345 /*
346 * This is the global environment of the parser. This information is
347 * persistent for main-items. The global environment can be saved and
348 * restored with PUSH/POP statements.
349 */
350
351 struct hid_global {
352 unsigned usage_page;
353 __s32 logical_minimum;
354 __s32 logical_maximum;
355 __s32 physical_minimum;
356 __s32 physical_maximum;
357 __s32 unit_exponent;
358 unsigned unit;
359 unsigned report_id;
360 unsigned report_size;
361 unsigned report_count;
362 };
363
364 /*
365 * This is the local environment. It is persistent up the next main-item.
366 */
367
368 #define HID_MAX_USAGES 12288
369 #define HID_DEFAULT_NUM_COLLECTIONS 16
370
371 struct hid_local {
372 unsigned usage[HID_MAX_USAGES]; /* usage array */
373 unsigned collection_index[HID_MAX_USAGES]; /* collection index array */
374 unsigned usage_index;
375 unsigned usage_minimum;
376 unsigned delimiter_depth;
377 unsigned delimiter_branch;
378 };
379
380 /*
381 * This is the collection stack. We climb up the stack to determine
382 * application and function of each field.
383 */
384
385 struct hid_collection {
386 unsigned type;
387 unsigned usage;
388 unsigned level;
389 };
390
391 struct hid_usage {
392 unsigned hid; /* hid usage code */
393 unsigned collection_index; /* index into collection array */
394 unsigned usage_index; /* index into usage array */
395 /* hidinput data */
396 __u16 code; /* input driver code */
397 __u8 type; /* input driver type */
398 __s8 hat_min; /* hat switch fun */
399 __s8 hat_max; /* ditto */
400 __s8 hat_dir; /* ditto */
401 };
402
403 struct hid_input;
404
405 struct hid_field {
406 unsigned physical; /* physical usage for this field */
407 unsigned logical; /* logical usage for this field */
408 unsigned application; /* application usage for this field */
409 struct hid_usage *usage; /* usage table for this function */
410 unsigned maxusage; /* maximum usage index */
411 unsigned flags; /* main-item flags (i.e. volatile,array,constant) */
412 unsigned report_offset; /* bit offset in the report */
413 unsigned report_size; /* size of this field in the report */
414 unsigned report_count; /* number of this field in the report */
415 unsigned report_type; /* (input,output,feature) */
416 __s32 *value; /* last known value(s) */
417 __s32 logical_minimum;
418 __s32 logical_maximum;
419 __s32 physical_minimum;
420 __s32 physical_maximum;
421 __s32 unit_exponent;
422 unsigned unit;
423 struct hid_report *report; /* associated report */
424 unsigned index; /* index into report->field[] */
425 /* hidinput data */
426 struct hid_input *hidinput; /* associated input structure */
427 __u16 dpad; /* dpad input code */
428 };
429
430 #define HID_MAX_FIELDS 256
431
432 struct hid_report {
433 struct list_head list;
434 unsigned id; /* id of this report */
435 unsigned type; /* report type */
436 struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
437 unsigned maxfield; /* maximum valid field index */
438 unsigned size; /* size of the report (bits) */
439 struct hid_device *device; /* associated device */
440 };
441
442 #define HID_MAX_IDS 256
443
444 struct hid_report_enum {
445 unsigned numbered;
446 struct list_head report_list;
447 struct hid_report *report_id_hash[HID_MAX_IDS];
448 };
449
450 #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */
451 #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */
452 #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */
453 #define HID_OUTPUT_FIFO_SIZE 64
454
455 struct hid_control_fifo {
456 unsigned char dir;
457 struct hid_report *report;
458 char *raw_report;
459 };
460
461 struct hid_output_fifo {
462 struct hid_report *report;
463 char *raw_report;
464 };
465
466 #define HID_CLAIMED_INPUT 1
467 #define HID_CLAIMED_HIDDEV 2
468 #define HID_CLAIMED_HIDRAW 4
469 #define HID_CLAIMED_DRIVER 8
470
471 #define HID_STAT_ADDED 1
472 #define HID_STAT_PARSED 2
473
474 struct hid_input {
475 struct list_head list;
476 struct hid_report *report;
477 struct input_dev *input;
478 };
479
480 enum hid_type {
481 HID_TYPE_OTHER = 0,
482 HID_TYPE_USBMOUSE,
483 HID_TYPE_USBNONE
484 };
485
486 struct hid_driver;
487 struct hid_ll_driver;
488
489 struct hid_device { /* device report descriptor */
490 __u8 *dev_rdesc;
491 unsigned dev_rsize;
492 __u8 *rdesc;
493 unsigned rsize;
494 struct hid_collection *collection; /* List of HID collections */
495 unsigned collection_size; /* Number of allocated hid_collections */
496 unsigned maxcollection; /* Number of parsed collections */
497 unsigned maxapplication; /* Number of applications */
498 __u16 bus; /* BUS ID */
499 __u16 group; /* Report group */
500 __u32 vendor; /* Vendor ID */
501 __u32 product; /* Product ID */
502 __u32 version; /* HID version */
503 enum hid_type type; /* device type (mouse, kbd, ...) */
504 unsigned country; /* HID country */
505 struct hid_report_enum report_enum[HID_REPORT_TYPES];
506 struct work_struct led_work; /* delayed LED worker */
507
508 struct semaphore driver_lock; /* protects the current driver, except during input */
509 struct semaphore driver_input_lock; /* protects the current driver */
510 struct device dev; /* device */
511 struct hid_driver *driver;
512 struct hid_ll_driver *ll_driver;
513
514 #ifdef CONFIG_HID_BATTERY_STRENGTH
515 /*
516 * Power supply information for HID devices which report
517 * battery strength. power_supply is registered iff
518 * battery.name is non-NULL.
519 */
520 struct power_supply battery;
521 __s32 battery_min;
522 __s32 battery_max;
523 __s32 battery_report_type;
524 __s32 battery_report_id;
525 #endif
526
527 unsigned int status; /* see STAT flags above */
528 unsigned claimed; /* Claimed by hidinput, hiddev? */
529 unsigned quirks; /* Various quirks the device can pull on us */
530 bool io_started; /* Protected by driver_lock. If IO has started */
531
532 struct list_head inputs; /* The list of inputs */
533 void *hiddev; /* The hiddev structure */
534 void *hidraw;
535 int minor; /* Hiddev minor number */
536
537 int open; /* is the device open by anyone? */
538 char name[128]; /* Device name */
539 char phys[64]; /* Device physical location */
540 char uniq[64]; /* Device unique identifier (serial #) */
541
542 void *driver_data;
543
544 /* temporary hid_ff handling (until moved to the drivers) */
545 int (*ff_init)(struct hid_device *);
546
547 /* hiddev event handler */
548 int (*hiddev_connect)(struct hid_device *, unsigned int);
549 void (*hiddev_disconnect)(struct hid_device *);
550 void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
551 struct hid_usage *, __s32);
552 void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
553
554 /* debugging support via debugfs */
555 unsigned short debug;
556 struct dentry *debug_dir;
557 struct dentry *debug_rdesc;
558 struct dentry *debug_events;
559 struct list_head debug_list;
560 spinlock_t debug_list_lock;
561 wait_queue_head_t debug_wait;
562 };
563
564 static inline void *hid_get_drvdata(struct hid_device *hdev)
565 {
566 return dev_get_drvdata(&hdev->dev);
567 }
568
569 static inline void hid_set_drvdata(struct hid_device *hdev, void *data)
570 {
571 dev_set_drvdata(&hdev->dev, data);
572 }
573
574 #define HID_GLOBAL_STACK_SIZE 4
575 #define HID_COLLECTION_STACK_SIZE 4
576
577 #define HID_SCAN_FLAG_MT_WIN_8 BIT(0)
578 #define HID_SCAN_FLAG_VENDOR_SPECIFIC BIT(1)
579 #define HID_SCAN_FLAG_GD_POINTER BIT(2)
580
581 struct hid_parser {
582 struct hid_global global;
583 struct hid_global global_stack[HID_GLOBAL_STACK_SIZE];
584 unsigned global_stack_ptr;
585 struct hid_local local;
586 unsigned collection_stack[HID_COLLECTION_STACK_SIZE];
587 unsigned collection_stack_ptr;
588 struct hid_device *device;
589 unsigned scan_flags;
590 };
591
592 struct hid_class_descriptor {
593 __u8 bDescriptorType;
594 __le16 wDescriptorLength;
595 } __attribute__ ((packed));
596
597 struct hid_descriptor {
598 __u8 bLength;
599 __u8 bDescriptorType;
600 __le16 bcdHID;
601 __u8 bCountryCode;
602 __u8 bNumDescriptors;
603
604 struct hid_class_descriptor desc[1];
605 } __attribute__ ((packed));
606
607 #define HID_DEVICE(b, g, ven, prod) \
608 .bus = (b), .group = (g), .vendor = (ven), .product = (prod)
609 #define HID_USB_DEVICE(ven, prod) \
610 .bus = BUS_USB, .vendor = (ven), .product = (prod)
611 #define HID_BLUETOOTH_DEVICE(ven, prod) \
612 .bus = BUS_BLUETOOTH, .vendor = (ven), .product = (prod)
613 #define HID_I2C_DEVICE(ven, prod) \
614 .bus = BUS_I2C, .vendor = (ven), .product = (prod)
615
616 #define HID_REPORT_ID(rep) \
617 .report_type = (rep)
618 #define HID_USAGE_ID(uhid, utype, ucode) \
619 .usage_hid = (uhid), .usage_type = (utype), .usage_code = (ucode)
620 /* we don't want to catch types and codes equal to 0 */
621 #define HID_TERMINATOR (HID_ANY_ID - 1)
622
623 struct hid_report_id {
624 __u32 report_type;
625 };
626 struct hid_usage_id {
627 __u32 usage_hid;
628 __u32 usage_type;
629 __u32 usage_code;
630 };
631
632 /**
633 * struct hid_driver
634 * @name: driver name (e.g. "Footech_bar-wheel")
635 * @id_table: which devices is this driver for (must be non-NULL for probe
636 * to be called)
637 * @dyn_list: list of dynamically added device ids
638 * @dyn_lock: lock protecting @dyn_list
639 * @probe: new device inserted
640 * @remove: device removed (NULL if not a hot-plug capable driver)
641 * @report_table: on which reports to call raw_event (NULL means all)
642 * @raw_event: if report in report_table, this hook is called (NULL means nop)
643 * @usage_table: on which events to call event (NULL means all)
644 * @event: if usage in usage_table, this hook is called (NULL means nop)
645 * @report: this hook is called after parsing a report (NULL means nop)
646 * @report_fixup: called before report descriptor parsing (NULL means nop)
647 * @input_mapping: invoked on input registering before mapping an usage
648 * @input_mapped: invoked on input registering after mapping an usage
649 * @input_configured: invoked just before the device is registered
650 * @feature_mapping: invoked on feature registering
651 * @suspend: invoked on suspend (NULL means nop)
652 * @resume: invoked on resume if device was not reset (NULL means nop)
653 * @reset_resume: invoked on resume if device was reset (NULL means nop)
654 *
655 * probe should return -errno on error, or 0 on success. During probe,
656 * input will not be passed to raw_event unless hid_device_io_start is
657 * called.
658 *
659 * raw_event and event should return 0 on no action performed, 1 when no
660 * further processing should be done and negative on error
661 *
662 * input_mapping shall return a negative value to completely ignore this usage
663 * (e.g. doubled or invalid usage), zero to continue with parsing of this
664 * usage by generic code (no special handling needed) or positive to skip
665 * generic parsing (needed special handling which was done in the hook already)
666 * input_mapped shall return negative to inform the layer that this usage
667 * should not be considered for further processing or zero to notify that
668 * no processing was performed and should be done in a generic manner
669 * Both these functions may be NULL which means the same behavior as returning
670 * zero from them.
671 */
672 struct hid_driver {
673 char *name;
674 const struct hid_device_id *id_table;
675
676 struct list_head dyn_list;
677 spinlock_t dyn_lock;
678
679 int (*probe)(struct hid_device *dev, const struct hid_device_id *id);
680 void (*remove)(struct hid_device *dev);
681
682 const struct hid_report_id *report_table;
683 int (*raw_event)(struct hid_device *hdev, struct hid_report *report,
684 u8 *data, int size);
685 const struct hid_usage_id *usage_table;
686 int (*event)(struct hid_device *hdev, struct hid_field *field,
687 struct hid_usage *usage, __s32 value);
688 void (*report)(struct hid_device *hdev, struct hid_report *report);
689
690 __u8 *(*report_fixup)(struct hid_device *hdev, __u8 *buf,
691 unsigned int *size);
692
693 int (*input_mapping)(struct hid_device *hdev,
694 struct hid_input *hidinput, struct hid_field *field,
695 struct hid_usage *usage, unsigned long **bit, int *max);
696 int (*input_mapped)(struct hid_device *hdev,
697 struct hid_input *hidinput, struct hid_field *field,
698 struct hid_usage *usage, unsigned long **bit, int *max);
699 void (*input_configured)(struct hid_device *hdev,
700 struct hid_input *hidinput);
701 void (*feature_mapping)(struct hid_device *hdev,
702 struct hid_field *field,
703 struct hid_usage *usage);
704 #ifdef CONFIG_PM
705 int (*suspend)(struct hid_device *hdev, pm_message_t message);
706 int (*resume)(struct hid_device *hdev);
707 int (*reset_resume)(struct hid_device *hdev);
708 #endif
709 /* private: */
710 struct device_driver driver;
711 };
712
713 /**
714 * hid_ll_driver - low level driver callbacks
715 * @start: called on probe to start the device
716 * @stop: called on remove
717 * @open: called by input layer on open
718 * @close: called by input layer on close
719 * @parse: this method is called only once to parse the device data,
720 * shouldn't allocate anything to not leak memory
721 * @request: send report request to device (e.g. feature report)
722 * @wait: wait for buffered io to complete (send/recv reports)
723 * @raw_request: send raw report request to device (e.g. feature report)
724 * @output_report: send output report to device
725 * @idle: send idle request to device
726 */
727 struct hid_ll_driver {
728 int (*start)(struct hid_device *hdev);
729 void (*stop)(struct hid_device *hdev);
730
731 int (*open)(struct hid_device *hdev);
732 void (*close)(struct hid_device *hdev);
733
734 int (*power)(struct hid_device *hdev, int level);
735
736 int (*parse)(struct hid_device *hdev);
737
738 void (*request)(struct hid_device *hdev,
739 struct hid_report *report, int reqtype);
740
741 int (*wait)(struct hid_device *hdev);
742
743 int (*raw_request) (struct hid_device *hdev, unsigned char reportnum,
744 __u8 *buf, size_t len, unsigned char rtype,
745 int reqtype);
746
747 int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len);
748
749 int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype);
750 };
751
752 #define PM_HINT_FULLON 1<<5
753 #define PM_HINT_NORMAL 1<<1
754
755 /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
756 /* We ignore a few input applications that are not widely used */
757 #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || ((a >= 0x000d0002) && (a <= 0x000d0006)))
758
759 /* HID core API */
760
761 extern int hid_debug;
762
763 extern bool hid_ignore(struct hid_device *);
764 extern int hid_add_device(struct hid_device *);
765 extern void hid_destroy_device(struct hid_device *);
766
767 extern int __must_check __hid_register_driver(struct hid_driver *,
768 struct module *, const char *mod_name);
769
770 /* use a define to avoid include chaining to get THIS_MODULE & friends */
771 #define hid_register_driver(driver) \
772 __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
773
774 extern void hid_unregister_driver(struct hid_driver *);
775
776 /**
777 * module_hid_driver() - Helper macro for registering a HID driver
778 * @__hid_driver: hid_driver struct
779 *
780 * Helper macro for HID drivers which do not do anything special in module
781 * init/exit. This eliminates a lot of boilerplate. Each module may only
782 * use this macro once, and calling it replaces module_init() and module_exit()
783 */
784 #define module_hid_driver(__hid_driver) \
785 module_driver(__hid_driver, hid_register_driver, \
786 hid_unregister_driver)
787
788 extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
789 extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
790 extern int hidinput_connect(struct hid_device *hid, unsigned int force);
791 extern void hidinput_disconnect(struct hid_device *);
792
793 int hid_set_field(struct hid_field *, unsigned, __s32);
794 int hid_input_report(struct hid_device *, int type, u8 *, int, int);
795 int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
796 struct hid_field *hidinput_get_led_field(struct hid_device *hid);
797 unsigned int hidinput_count_leds(struct hid_device *hid);
798 __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);
799 void hid_output_report(struct hid_report *report, __u8 *data);
800 void __hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype);
801 u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
802 struct hid_device *hid_allocate_device(void);
803 struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
804 int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
805 struct hid_report *hid_validate_values(struct hid_device *hid,
806 unsigned int type, unsigned int id,
807 unsigned int field_index,
808 unsigned int report_counts);
809 int hid_open_report(struct hid_device *device);
810 int hid_check_keys_pressed(struct hid_device *hid);
811 int hid_connect(struct hid_device *hid, unsigned int connect_mask);
812 void hid_disconnect(struct hid_device *hid);
813 const struct hid_device_id *hid_match_id(struct hid_device *hdev,
814 const struct hid_device_id *id);
815 s32 hid_snto32(__u32 value, unsigned n);
816
817 /**
818 * hid_device_io_start - enable HID input during probe, remove
819 *
820 * @hid - the device
821 *
822 * This should only be called during probe or remove and only be
823 * called by the thread calling probe or remove. It will allow
824 * incoming packets to be delivered to the driver.
825 */
826 static inline void hid_device_io_start(struct hid_device *hid) {
827 if (hid->io_started) {
828 dev_warn(&hid->dev, "io already started");
829 return;
830 }
831 hid->io_started = true;
832 up(&hid->driver_input_lock);
833 }
834
835 /**
836 * hid_device_io_stop - disable HID input during probe, remove
837 *
838 * @hid - the device
839 *
840 * Should only be called after hid_device_io_start. It will prevent
841 * incoming packets from going to the driver for the duration of
842 * probe, remove. If called during probe, packets will still go to the
843 * driver after probe is complete. This function should only be called
844 * by the thread calling probe or remove.
845 */
846 static inline void hid_device_io_stop(struct hid_device *hid) {
847 if (!hid->io_started) {
848 dev_warn(&hid->dev, "io already stopped");
849 return;
850 }
851 hid->io_started = false;
852 down(&hid->driver_input_lock);
853 }
854
855 /**
856 * hid_map_usage - map usage input bits
857 *
858 * @hidinput: hidinput which we are interested in
859 * @usage: usage to fill in
860 * @bit: pointer to input->{}bit (out parameter)
861 * @max: maximal valid usage->code to consider later (out parameter)
862 * @type: input event type (EV_KEY, EV_REL, ...)
863 * @c: code which corresponds to this usage and type
864 */
865 static inline void hid_map_usage(struct hid_input *hidinput,
866 struct hid_usage *usage, unsigned long **bit, int *max,
867 __u8 type, __u16 c)
868 {
869 struct input_dev *input = hidinput->input;
870
871 usage->type = type;
872 usage->code = c;
873
874 switch (type) {
875 case EV_ABS:
876 *bit = input->absbit;
877 *max = ABS_MAX;
878 break;
879 case EV_REL:
880 *bit = input->relbit;
881 *max = REL_MAX;
882 break;
883 case EV_KEY:
884 *bit = input->keybit;
885 *max = KEY_MAX;
886 break;
887 case EV_LED:
888 *bit = input->ledbit;
889 *max = LED_MAX;
890 break;
891 }
892 }
893
894 /**
895 * hid_map_usage_clear - map usage input bits and clear the input bit
896 *
897 * The same as hid_map_usage, except the @c bit is also cleared in supported
898 * bits (@bit).
899 */
900 static inline void hid_map_usage_clear(struct hid_input *hidinput,
901 struct hid_usage *usage, unsigned long **bit, int *max,
902 __u8 type, __u16 c)
903 {
904 hid_map_usage(hidinput, usage, bit, max, type, c);
905 clear_bit(c, *bit);
906 }
907
908 /**
909 * hid_parse - parse HW reports
910 *
911 * @hdev: hid device
912 *
913 * Call this from probe after you set up the device (if needed). Your
914 * report_fixup will be called (if non-NULL) after reading raw report from
915 * device before passing it to hid layer for real parsing.
916 */
917 static inline int __must_check hid_parse(struct hid_device *hdev)
918 {
919 return hid_open_report(hdev);
920 }
921
922 /**
923 * hid_hw_start - start underlaying HW
924 *
925 * @hdev: hid device
926 * @connect_mask: which outputs to connect, see HID_CONNECT_*
927 *
928 * Call this in probe function *after* hid_parse. This will setup HW buffers
929 * and start the device (if not deffered to device open). hid_hw_stop must be
930 * called if this was successful.
931 */
932 static inline int __must_check hid_hw_start(struct hid_device *hdev,
933 unsigned int connect_mask)
934 {
935 int ret = hdev->ll_driver->start(hdev);
936 if (ret || !connect_mask)
937 return ret;
938 ret = hid_connect(hdev, connect_mask);
939 if (ret)
940 hdev->ll_driver->stop(hdev);
941 return ret;
942 }
943
944 /**
945 * hid_hw_stop - stop underlaying HW
946 *
947 * @hdev: hid device
948 *
949 * This is usually called from remove function or from probe when something
950 * failed and hid_hw_start was called already.
951 */
952 static inline void hid_hw_stop(struct hid_device *hdev)
953 {
954 hid_disconnect(hdev);
955 hdev->ll_driver->stop(hdev);
956 }
957
958 /**
959 * hid_hw_open - signal underlaying HW to start delivering events
960 *
961 * @hdev: hid device
962 *
963 * Tell underlying HW to start delivering events from the device.
964 * This function should be called sometime after successful call
965 * to hid_hiw_start().
966 */
967 static inline int __must_check hid_hw_open(struct hid_device *hdev)
968 {
969 return hdev->ll_driver->open(hdev);
970 }
971
972 /**
973 * hid_hw_close - signal underlaying HW to stop delivering events
974 *
975 * @hdev: hid device
976 *
977 * This function indicates that we are not interested in the events
978 * from this device anymore. Delivery of events may or may not stop,
979 * depending on the number of users still outstanding.
980 */
981 static inline void hid_hw_close(struct hid_device *hdev)
982 {
983 hdev->ll_driver->close(hdev);
984 }
985
986 /**
987 * hid_hw_power - requests underlying HW to go into given power mode
988 *
989 * @hdev: hid device
990 * @level: requested power level (one of %PM_HINT_* defines)
991 *
992 * This function requests underlying hardware to enter requested power
993 * mode.
994 */
995
996 static inline int hid_hw_power(struct hid_device *hdev, int level)
997 {
998 return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0;
999 }
1000
1001
1002 /**
1003 * hid_hw_request - send report request to device
1004 *
1005 * @hdev: hid device
1006 * @report: report to send
1007 * @reqtype: hid request type
1008 */
1009 static inline void hid_hw_request(struct hid_device *hdev,
1010 struct hid_report *report, int reqtype)
1011 {
1012 if (hdev->ll_driver->request)
1013 return hdev->ll_driver->request(hdev, report, reqtype);
1014
1015 __hid_request(hdev, report, reqtype);
1016 }
1017
1018 /**
1019 * hid_hw_raw_request - send report request to device
1020 *
1021 * @hdev: hid device
1022 * @reportnum: report ID
1023 * @buf: in/out data to transfer
1024 * @len: length of buf
1025 * @rtype: HID report type
1026 * @reqtype: HID_REQ_GET_REPORT or HID_REQ_SET_REPORT
1027 *
1028 * @return: count of data transfered, negative if error
1029 *
1030 * Same behavior as hid_hw_request, but with raw buffers instead.
1031 */
1032 static inline int hid_hw_raw_request(struct hid_device *hdev,
1033 unsigned char reportnum, __u8 *buf,
1034 size_t len, unsigned char rtype, int reqtype)
1035 {
1036 if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
1037 return -EINVAL;
1038
1039 return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
1040 rtype, reqtype);
1041 }
1042
1043 /**
1044 * hid_hw_output_report - send output report to device
1045 *
1046 * @hdev: hid device
1047 * @buf: raw data to transfer
1048 * @len: length of buf
1049 *
1050 * @return: count of data transfered, negative if error
1051 */
1052 static inline int hid_hw_output_report(struct hid_device *hdev, __u8 *buf,
1053 size_t len)
1054 {
1055 if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
1056 return -EINVAL;
1057
1058 if (hdev->ll_driver->output_report)
1059 return hdev->ll_driver->output_report(hdev, buf, len);
1060
1061 return -ENOSYS;
1062 }
1063
1064 /**
1065 * hid_hw_idle - send idle request to device
1066 *
1067 * @hdev: hid device
1068 * @report: report to control
1069 * @idle: idle state
1070 * @reqtype: hid request type
1071 */
1072 static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle,
1073 int reqtype)
1074 {
1075 if (hdev->ll_driver->idle)
1076 return hdev->ll_driver->idle(hdev, report, idle, reqtype);
1077
1078 return 0;
1079 }
1080
1081 /**
1082 * hid_hw_wait - wait for buffered io to complete
1083 *
1084 * @hdev: hid device
1085 */
1086 static inline void hid_hw_wait(struct hid_device *hdev)
1087 {
1088 if (hdev->ll_driver->wait)
1089 hdev->ll_driver->wait(hdev);
1090 }
1091
1092 /**
1093 * hid_report_len - calculate the report length
1094 *
1095 * @report: the report we want to know the length
1096 */
1097 static inline int hid_report_len(struct hid_report *report)
1098 {
1099 /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
1100 return ((report->size - 1) >> 3) + 1 + (report->id > 0);
1101 }
1102
1103 int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
1104 int interrupt);
1105
1106 /* HID quirks API */
1107 u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct);
1108 int usbhid_quirks_init(char **quirks_param);
1109 void usbhid_quirks_exit(void);
1110
1111 #ifdef CONFIG_HID_PID
1112 int hid_pidff_init(struct hid_device *hid);
1113 #else
1114 #define hid_pidff_init NULL
1115 #endif
1116
1117 #define dbg_hid(format, arg...) \
1118 do { \
1119 if (hid_debug) \
1120 printk(KERN_DEBUG "%s: " format, __FILE__, ##arg); \
1121 } while (0)
1122
1123 #define hid_printk(level, hid, fmt, arg...) \
1124 dev_printk(level, &(hid)->dev, fmt, ##arg)
1125 #define hid_emerg(hid, fmt, arg...) \
1126 dev_emerg(&(hid)->dev, fmt, ##arg)
1127 #define hid_crit(hid, fmt, arg...) \
1128 dev_crit(&(hid)->dev, fmt, ##arg)
1129 #define hid_alert(hid, fmt, arg...) \
1130 dev_alert(&(hid)->dev, fmt, ##arg)
1131 #define hid_err(hid, fmt, arg...) \
1132 dev_err(&(hid)->dev, fmt, ##arg)
1133 #define hid_notice(hid, fmt, arg...) \
1134 dev_notice(&(hid)->dev, fmt, ##arg)
1135 #define hid_warn(hid, fmt, arg...) \
1136 dev_warn(&(hid)->dev, fmt, ##arg)
1137 #define hid_info(hid, fmt, arg...) \
1138 dev_info(&(hid)->dev, fmt, ##arg)
1139 #define hid_dbg(hid, fmt, arg...) \
1140 dev_dbg(&(hid)->dev, fmt, ##arg)
1141
1142 #endif |
Here is an explanation of a rule violation arisen while checking your driver against a corresponding kernel.
Note that it may be false positive, i.e. there isn't a real error indeed. Please analyze a given error trace and related source code to understand whether there is an error in your driver.
Error trace column contains a path on which the given rule is violated. You can expand/collapse some entity classes by clicking on corresponding checkboxes in a main menu or in an advanced Others menu. Also you can expand/collapse each particular entity by clicking on +/-. In hovering on some entities you can see some tips. Also the error trace is bound with related source code. Line numbers may be shown as links on the left. You can click on them to open corresponding lines in source code.
Source code column contains a content of files related with the error trace. There is source code of your driver (note that there are some LDV modifications at the end), kernel headers and rule model. Tabs show a currently opened file and other available files. In hovering on them you can see full file names. On clicking a corresponding file content will be shown.
Kernel | Module | Rule | Verifier | Verdict | Status | Timestamp | Bug report |
linux-4.0-rc1.tar.xz | drivers/hid/hid-lenovo.ko | 151_1a | BLAST | Bug | Fixed | 2015-05-13 13:33:18 | L0196 |
Comment
Описание ошибки по старой трассе. В функции lenovo_probe_tpkbd в случае, если группа lenovo_attr_group_tpkbd (строка 594) создана, а затем вызов devm_kzalloc на строке 598 выполнился с ошибкой, группа не удаляется.
[Home]