aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/Kconfig6
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-elecom.c57
-rw-r--r--drivers/hid/hid-ids.h81
-rw-r--r--drivers/hid/hid-input.c3
-rw-r--r--drivers/hid/hid-picolcd.c199
-rw-r--r--drivers/hid/hidraw.c2
8 files changed, 276 insertions, 74 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 434099369058..d51f0144a3b9 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -148,6 +148,12 @@ config HID_EGALAX
148 ---help--- 148 ---help---
149 Support for the eGalax dual-touch panel. 149 Support for the eGalax dual-touch panel.
150 150
151config HID_ELECOM
152 tristate "ELECOM"
153 depends on BT_HIDP
154 ---help---
155 Support for the ELECOM BM084 (bluetooth mouse).
156
151config HID_EZKEY 157config HID_EZKEY
152 tristate "Ezkey" if EMBEDDED 158 tristate "Ezkey" if EMBEDDED
153 depends on USB_HID 159 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 987fa0627367..2ec042f57138 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
32obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o 32obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
33obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o 33obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o
34obj-$(CONFIG_HID_EGALAX) += hid-egalax.o 34obj-$(CONFIG_HID_EGALAX) += hid-egalax.o
35obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
35obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o 36obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
36obj-$(CONFIG_HID_GYRATION) += hid-gyration.o 37obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
37obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o 38obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 866e54ec5fb2..a204d092e2d7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1294,6 +1294,7 @@ static const struct hid_device_id hid_blacklist[] = {
1294 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, 1294 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
1295 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, 1295 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
1296 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, 1296 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
1297 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
1297 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, 1298 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
1298 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, 1299 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
1299 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, 1300 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
new file mode 100644
index 000000000000..7a40878f46b4
--- /dev/null
+++ b/drivers/hid/hid-elecom.c
@@ -0,0 +1,57 @@
1/*
2 * HID driver for Elecom BM084 (bluetooth mouse).
3 * Removes a non-existing horizontal wheel from
4 * the HID descriptor.
5 * (This module is based on "hid-ortek".)
6 *
7 * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 */
16
17#include <linux/device.h>
18#include <linux/hid.h>
19#include <linux/module.h>
20
21#include "hid-ids.h"
22
23static void elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
24 unsigned int rsize)
25{
26 if (rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
27 dev_info(&hdev->dev, "Fixing up Elecom BM084 "
28 "report descriptor.\n");
29 rdesc[47] = 0x00;
30 }
31}
32
33static const struct hid_device_id elecom_devices[] = {
34 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084)},
35 { }
36};
37MODULE_DEVICE_TABLE(hid, elecom_devices);
38
39static struct hid_driver elecom_driver = {
40 .name = "elecom",
41 .id_table = elecom_devices,
42 .report_fixup = elecom_report_fixup
43};
44
45static int __init elecom_init(void)
46{
47 return hid_register_driver(&elecom_driver);
48}
49
50static void __exit elecom_exit(void)
51{
52 hid_unregister_driver(&elecom_driver);
53}
54
55module_init(elecom_init);
56module_exit(elecom_exit);
57MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 31601eef25dd..7f0e40bdb47e 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -34,7 +34,7 @@
34#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 34#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
35#define USB_DEVICE_ID_ACECAD_302 0x0008 35#define USB_DEVICE_ID_ACECAD_302 0x0008
36 36
37#define USB_VENDOR_ID_ADS_TECH 0x06e1 37#define USB_VENDOR_ID_ADS_TECH 0x06e1
38#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 38#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
39 39
40#define USB_VENDOR_ID_AFATECH 0x15a4 40#define USB_VENDOR_ID_AFATECH 0x15a4
@@ -81,12 +81,12 @@
81#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 81#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
82#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 82#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
83#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 83#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
84#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 84#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
85#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a 85#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
86#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b 86#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
87#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c 87#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
88#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d 88#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
89#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e 89#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
90#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 90#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
91#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 91#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
92#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 92#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
@@ -118,8 +118,8 @@
118#define USB_VENDOR_ID_AVERMEDIA 0x07ca 118#define USB_VENDOR_ID_AVERMEDIA 0x07ca
119#define USB_DEVICE_ID_AVER_FM_MR800 0xb800 119#define USB_DEVICE_ID_AVER_FM_MR800 0xb800
120 120
121#define USB_VENDOR_ID_BELKIN 0x050d 121#define USB_VENDOR_ID_BELKIN 0x050d
122#define USB_DEVICE_ID_FLIP_KVM 0x3201 122#define USB_DEVICE_ID_FLIP_KVM 0x3201
123 123
124#define USB_VENDOR_ID_BERKSHIRE 0x0c98 124#define USB_VENDOR_ID_BERKSHIRE 0x0c98
125#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 125#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
@@ -128,7 +128,7 @@
128#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 128#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
129 129
130#define USB_VENDOR_ID_CANDO 0x2087 130#define USB_VENDOR_ID_CANDO 0x2087
131#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 131#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01
132#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 132#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03
133 133
134#define USB_VENDOR_ID_CH 0x068e 134#define USB_VENDOR_ID_CH 0x068e
@@ -175,7 +175,7 @@
175#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a 175#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a
176 176
177#define USB_VENDOR_ID_DELORME 0x1163 177#define USB_VENDOR_ID_DELORME 0x1163
178#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 178#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
179#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 179#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
180 180
181#define USB_VENDOR_ID_DMI 0x0c0b 181#define USB_VENDOR_ID_DMI 0x0c0b
@@ -187,19 +187,22 @@
187#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 187#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
188#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d 188#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
189 189
190#define USB_VENDOR_ID_ELECOM 0x056e
191#define USB_DEVICE_ID_ELECOM_BM084 0x0061
192
190#define USB_VENDOR_ID_ELO 0x04E7 193#define USB_VENDOR_ID_ELO 0x04E7
191#define USB_DEVICE_ID_ELO_TS2700 0x0020 194#define USB_DEVICE_ID_ELO_TS2700 0x0020
192 195
193#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f 196#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
194#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 197#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
195 198
196#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
197#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
198
199#define USB_VENDOR_ID_ETT 0x0664 199#define USB_VENDOR_ID_ETT 0x0664
200#define USB_DEVICE_ID_TC5UH 0x0309 200#define USB_DEVICE_ID_TC5UH 0x0309
201 201
202#define USB_VENDOR_ID_EZKEY 0x0518 202#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
203#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
204
205#define USB_VENDOR_ID_EZKEY 0x0518
203#define USB_DEVICE_ID_BTC_8193 0x0002 206#define USB_DEVICE_ID_BTC_8193 0x0002
204 207
205#define USB_VENDOR_ID_GAMERON 0x0810 208#define USB_VENDOR_ID_GAMERON 0x0810
@@ -296,9 +299,16 @@
296#define USB_VENDOR_ID_KBGEAR 0x084e 299#define USB_VENDOR_ID_KBGEAR 0x084e
297#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 300#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
298 301
302#define USB_VENDOR_ID_KENSINGTON 0x047d
303#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
304
299#define USB_VENDOR_ID_KWORLD 0x1b80 305#define USB_VENDOR_ID_KWORLD 0x1b80
300#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 306#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
301 307
308#define USB_VENDOR_ID_KYE 0x0458
309#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
310#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
311
302#define USB_VENDOR_ID_LABTEC 0x1020 312#define USB_VENDOR_ID_LABTEC 0x1020
303#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 313#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
304 314
@@ -318,9 +328,6 @@
318#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 328#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
319#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 329#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
320 330
321#define USB_VENDOR_ID_KENSINGTON 0x047d
322#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
323
324#define USB_VENDOR_ID_LOGITECH 0x046d 331#define USB_VENDOR_ID_LOGITECH 0x046d
325#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 332#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
326#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 333#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
@@ -376,23 +383,23 @@
376#define USB_VENDOR_ID_MONTEREY 0x0566 383#define USB_VENDOR_ID_MONTEREY 0x0566
377#define USB_DEVICE_ID_GENIUS_KB29E 0x3004 384#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
378 385
386#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
387#define USB_DEVICE_ID_N_S_HARMONY 0xc359
388
389#define USB_VENDOR_ID_NATSU 0x08b7
390#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
391
379#define USB_VENDOR_ID_NCR 0x0404 392#define USB_VENDOR_ID_NCR 0x0404
380#define USB_DEVICE_ID_NCR_FIRST 0x0300 393#define USB_DEVICE_ID_NCR_FIRST 0x0300
381#define USB_DEVICE_ID_NCR_LAST 0x03ff 394#define USB_DEVICE_ID_NCR_LAST 0x03ff
382 395
383#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
384#define USB_DEVICE_ID_N_S_HARMONY 0xc359
385
386#define USB_VENDOR_ID_NATSU 0x08b7
387#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
388
389#define USB_VENDOR_ID_NEC 0x073e 396#define USB_VENDOR_ID_NEC 0x073e
390#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 397#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
391 398
392#define USB_VENDOR_ID_NEXTWINDOW 0x1926 399#define USB_VENDOR_ID_NEXTWINDOW 0x1926
393#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 400#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
394 401
395#define USB_VENDOR_ID_NTRIG 0x1b96 402#define USB_VENDOR_ID_NTRIG 0x1b96
396#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 403#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
397#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 404#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003
398#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004 405#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004
@@ -427,7 +434,7 @@
427#define USB_VENDOR_ID_PETALYNX 0x18b1 434#define USB_VENDOR_ID_PETALYNX 0x18b1
428#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 435#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
429 436
430#define USB_VENDOR_ID_PHILIPS 0x0471 437#define USB_VENDOR_ID_PHILIPS 0x0471
431#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 438#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
432 439
433#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 440#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
@@ -439,16 +446,16 @@
439#define USB_VENDOR_ID_PRODIGE 0x05af 446#define USB_VENDOR_ID_PRODIGE 0x05af
440#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 447#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
441 448
449#define USB_VENDOR_ID_QUANTA 0x0408
450#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
451#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
452
442#define USB_VENDOR_ID_ROCCAT 0x1e7d 453#define USB_VENDOR_ID_ROCCAT 0x1e7d
443#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced 454#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
444 455
445#define USB_VENDOR_ID_SAITEK 0x06a3 456#define USB_VENDOR_ID_SAITEK 0x06a3
446#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 457#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
447 458
448#define USB_VENDOR_ID_QUANTA 0x0408
449#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
450#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
451
452#define USB_VENDOR_ID_SAMSUNG 0x0419 459#define USB_VENDOR_ID_SAMSUNG 0x0419
453#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 460#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
454#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 461#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
@@ -472,20 +479,20 @@
472 479
473#define USB_VENDOR_ID_THRUSTMASTER 0x044f 480#define USB_VENDOR_ID_THRUSTMASTER 0x044f
474 481
475#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
476#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
477
478#define USB_VENDOR_ID_TOPMAX 0x0663 482#define USB_VENDOR_ID_TOPMAX 0x0663
479#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 483#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
480 484
481#define USB_VENDOR_ID_TOPSEED 0x0766 485#define USB_VENDOR_ID_TOPSEED 0x0766
482#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 486#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
483 487
488#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
489#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
490
484#define USB_VENDOR_ID_TURBOX 0x062a 491#define USB_VENDOR_ID_TURBOX 0x062a
485#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 492#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
486 493
487#define USB_VENDOR_ID_TWINHAN 0x6253 494#define USB_VENDOR_ID_TWINHAN 0x6253
488#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 495#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
489 496
490#define USB_VENDOR_ID_UCLOGIC 0x5543 497#define USB_VENDOR_ID_UCLOGIC 0x5543
491#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 498#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
@@ -522,9 +529,5 @@
522#define USB_VENDOR_ID_ZYDACRON 0x13EC 529#define USB_VENDOR_ID_ZYDACRON 0x13EC
523#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 530#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
524 531
525#define USB_VENDOR_ID_KYE 0x0458
526#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
527#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
528
529 532
530#endif 533#endif
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7a0d2e4661a1..6b10e5afe770 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -301,6 +301,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
301 301
302 case HID_UP_DIGITIZER: 302 case HID_UP_DIGITIZER:
303 switch (usage->hid & 0xff) { 303 switch (usage->hid & 0xff) {
304 case 0x00: /* Undefined */
305 goto ignore;
306
304 case 0x30: /* TipPressure */ 307 case 0x30: /* TipPressure */
305 if (!test_bit(BTN_TOUCH, input->keybit)) { 308 if (!test_bit(BTN_TOUCH, input->keybit)) {
306 device->quirks |= HID_QUIRK_NOTOUCH; 309 device->quirks |= HID_QUIRK_NOTOUCH;
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
index 7aabf65c48ef..346f0e34987e 100644
--- a/drivers/hid/hid-picolcd.c
+++ b/drivers/hid/hid-picolcd.c
@@ -127,6 +127,26 @@ static const struct fb_var_screeninfo picolcdfb_var = {
127 .height = 26, 127 .height = 26,
128 .bits_per_pixel = 1, 128 .bits_per_pixel = 1,
129 .grayscale = 1, 129 .grayscale = 1,
130 .red = {
131 .offset = 0,
132 .length = 1,
133 .msb_right = 0,
134 },
135 .green = {
136 .offset = 0,
137 .length = 1,
138 .msb_right = 0,
139 },
140 .blue = {
141 .offset = 0,
142 .length = 1,
143 .msb_right = 0,
144 },
145 .transp = {
146 .offset = 0,
147 .length = 0,
148 .msb_right = 0,
149 },
130}; 150};
131#endif /* CONFIG_HID_PICOLCD_FB */ 151#endif /* CONFIG_HID_PICOLCD_FB */
132 152
@@ -188,6 +208,7 @@ struct picolcd_data {
188 /* Framebuffer stuff */ 208 /* Framebuffer stuff */
189 u8 fb_update_rate; 209 u8 fb_update_rate;
190 u8 fb_bpp; 210 u8 fb_bpp;
211 u8 fb_force;
191 u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */ 212 u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */
192 u8 *fb_bitmap; /* framebuffer */ 213 u8 *fb_bitmap; /* framebuffer */
193 struct fb_info *fb_info; 214 struct fb_info *fb_info;
@@ -346,7 +367,7 @@ static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
346 const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32; 367 const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32;
347 for (i = 0; i < 64; i++) { 368 for (i = 0; i < 64; i++) {
348 tdata[i] <<= 1; 369 tdata[i] <<= 1;
349 tdata[i] |= (bdata[i/8] >> (7 - i % 8)) & 0x01; 370 tdata[i] |= (bdata[i/8] >> (i % 8)) & 0x01;
350 } 371 }
351 } 372 }
352 } else if (bpp == 8) { 373 } else if (bpp == 8) {
@@ -399,13 +420,10 @@ static int picolcd_fb_reset(struct picolcd_data *data, int clear)
399 420
400 if (data->fb_bitmap) { 421 if (data->fb_bitmap) {
401 if (clear) { 422 if (clear) {
402 memset(data->fb_vbitmap, 0xff, PICOLCDFB_SIZE); 423 memset(data->fb_vbitmap, 0, PICOLCDFB_SIZE);
403 memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp); 424 memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp);
404 } else {
405 /* invert 1 byte in each tile to force resend */
406 for (i = 0; i < PICOLCDFB_SIZE; i += 64)
407 data->fb_vbitmap[i] = ~data->fb_vbitmap[i];
408 } 425 }
426 data->fb_force = 1;
409 } 427 }
410 428
411 /* schedule first output of framebuffer */ 429 /* schedule first output of framebuffer */
@@ -421,6 +439,9 @@ static void picolcd_fb_update(struct picolcd_data *data)
421 int chip, tile, n; 439 int chip, tile, n;
422 unsigned long flags; 440 unsigned long flags;
423 441
442 if (!data)
443 return;
444
424 spin_lock_irqsave(&data->lock, flags); 445 spin_lock_irqsave(&data->lock, flags);
425 if (!(data->status & PICOLCD_READY_FB)) { 446 if (!(data->status & PICOLCD_READY_FB)) {
426 spin_unlock_irqrestore(&data->lock, flags); 447 spin_unlock_irqrestore(&data->lock, flags);
@@ -440,14 +461,18 @@ static void picolcd_fb_update(struct picolcd_data *data)
440 for (chip = 0; chip < 4; chip++) 461 for (chip = 0; chip < 4; chip++)
441 for (tile = 0; tile < 8; tile++) 462 for (tile = 0; tile < 8; tile++)
442 if (picolcd_fb_update_tile(data->fb_vbitmap, 463 if (picolcd_fb_update_tile(data->fb_vbitmap,
443 data->fb_bitmap, data->fb_bpp, chip, tile)) { 464 data->fb_bitmap, data->fb_bpp, chip, tile) ||
465 data->fb_force) {
444 n += 2; 466 n += 2;
467 if (!data->fb_info->par)
468 return; /* device lost! */
445 if (n >= HID_OUTPUT_FIFO_SIZE / 2) { 469 if (n >= HID_OUTPUT_FIFO_SIZE / 2) {
446 usbhid_wait_io(data->hdev); 470 usbhid_wait_io(data->hdev);
447 n = 0; 471 n = 0;
448 } 472 }
449 picolcd_fb_send_tile(data->hdev, chip, tile); 473 picolcd_fb_send_tile(data->hdev, chip, tile);
450 } 474 }
475 data->fb_force = false;
451 if (n) 476 if (n)
452 usbhid_wait_io(data->hdev); 477 usbhid_wait_io(data->hdev);
453} 478}
@@ -511,11 +536,23 @@ static int picolcd_fb_blank(int blank, struct fb_info *info)
511static void picolcd_fb_destroy(struct fb_info *info) 536static void picolcd_fb_destroy(struct fb_info *info)
512{ 537{
513 struct picolcd_data *data = info->par; 538 struct picolcd_data *data = info->par;
539 u32 *ref_cnt = info->pseudo_palette;
540 int may_release;
541
514 info->par = NULL; 542 info->par = NULL;
515 if (data) 543 if (data)
516 data->fb_info = NULL; 544 data->fb_info = NULL;
517 fb_deferred_io_cleanup(info); 545 fb_deferred_io_cleanup(info);
518 framebuffer_release(info); 546
547 ref_cnt--;
548 mutex_lock(&info->lock);
549 (*ref_cnt)--;
550 may_release = !ref_cnt;
551 mutex_unlock(&info->lock);
552 if (may_release) {
553 framebuffer_release(info);
554 vfree((u8 *)info->fix.smem_start);
555 }
519} 556}
520 557
521static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 558static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -526,29 +563,37 @@ static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *i
526 /* only allow 1/8 bit depth (8-bit is grayscale) */ 563 /* only allow 1/8 bit depth (8-bit is grayscale) */
527 *var = picolcdfb_var; 564 *var = picolcdfb_var;
528 var->activate = activate; 565 var->activate = activate;
529 if (bpp >= 8) 566 if (bpp >= 8) {
530 var->bits_per_pixel = 8; 567 var->bits_per_pixel = 8;
531 else 568 var->red.length = 8;
569 var->green.length = 8;
570 var->blue.length = 8;
571 } else {
532 var->bits_per_pixel = 1; 572 var->bits_per_pixel = 1;
573 var->red.length = 1;
574 var->green.length = 1;
575 var->blue.length = 1;
576 }
533 return 0; 577 return 0;
534} 578}
535 579
536static int picolcd_set_par(struct fb_info *info) 580static int picolcd_set_par(struct fb_info *info)
537{ 581{
538 struct picolcd_data *data = info->par; 582 struct picolcd_data *data = info->par;
539 u8 *o_fb, *n_fb; 583 u8 *tmp_fb, *o_fb;
584 if (!data)
585 return -ENODEV;
540 if (info->var.bits_per_pixel == data->fb_bpp) 586 if (info->var.bits_per_pixel == data->fb_bpp)
541 return 0; 587 return 0;
542 /* switch between 1/8 bit depths */ 588 /* switch between 1/8 bit depths */
543 if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8) 589 if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8)
544 return -EINVAL; 590 return -EINVAL;
545 591
546 o_fb = data->fb_bitmap; 592 o_fb = data->fb_bitmap;
547 n_fb = vmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel); 593 tmp_fb = kmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel, GFP_KERNEL);
548 if (!n_fb) 594 if (!tmp_fb)
549 return -ENOMEM; 595 return -ENOMEM;
550 596
551 fb_deferred_io_cleanup(info);
552 /* translate FB content to new bits-per-pixel */ 597 /* translate FB content to new bits-per-pixel */
553 if (info->var.bits_per_pixel == 1) { 598 if (info->var.bits_per_pixel == 1) {
554 int i, b; 599 int i, b;
@@ -558,24 +603,87 @@ static int picolcd_set_par(struct fb_info *info)
558 p <<= 1; 603 p <<= 1;
559 p |= o_fb[i*8+b] ? 0x01 : 0x00; 604 p |= o_fb[i*8+b] ? 0x01 : 0x00;
560 } 605 }
606 tmp_fb[i] = p;
561 } 607 }
608 memcpy(o_fb, tmp_fb, PICOLCDFB_SIZE);
562 info->fix.visual = FB_VISUAL_MONO01; 609 info->fix.visual = FB_VISUAL_MONO01;
563 info->fix.line_length = PICOLCDFB_WIDTH / 8; 610 info->fix.line_length = PICOLCDFB_WIDTH / 8;
564 } else { 611 } else {
565 int i; 612 int i;
613 memcpy(tmp_fb, o_fb, PICOLCDFB_SIZE);
566 for (i = 0; i < PICOLCDFB_SIZE * 8; i++) 614 for (i = 0; i < PICOLCDFB_SIZE * 8; i++)
567 n_fb[i] = o_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00; 615 o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
568 info->fix.visual = FB_VISUAL_TRUECOLOR; 616 info->fix.visual = FB_VISUAL_DIRECTCOLOR;
569 info->fix.line_length = PICOLCDFB_WIDTH; 617 info->fix.line_length = PICOLCDFB_WIDTH;
570 } 618 }
571 619
572 data->fb_bitmap = n_fb; 620 kfree(tmp_fb);
573 data->fb_bpp = info->var.bits_per_pixel; 621 data->fb_bpp = info->var.bits_per_pixel;
574 info->screen_base = (char __force __iomem *)n_fb; 622 return 0;
575 info->fix.smem_start = (unsigned long)n_fb; 623}
576 info->fix.smem_len = PICOLCDFB_SIZE*data->fb_bpp; 624
577 fb_deferred_io_init(info); 625/* Do refcounting on our FB and cleanup per worker if FB is
578 vfree(o_fb); 626 * closed after unplug of our device
627 * (fb_release holds info->lock and still touches info after
628 * we return so we can't release it immediately.
629 */
630struct picolcd_fb_cleanup_item {
631 struct fb_info *info;
632 struct picolcd_fb_cleanup_item *next;
633};
634static struct picolcd_fb_cleanup_item *fb_pending;
635DEFINE_SPINLOCK(fb_pending_lock);
636
637static void picolcd_fb_do_cleanup(struct work_struct *data)
638{
639 struct picolcd_fb_cleanup_item *item;
640 unsigned long flags;
641
642 do {
643 spin_lock_irqsave(&fb_pending_lock, flags);
644 item = fb_pending;
645 fb_pending = item ? item->next : NULL;
646 spin_unlock_irqrestore(&fb_pending_lock, flags);
647
648 if (item) {
649 u8 *fb = (u8 *)item->info->fix.smem_start;
650 /* make sure we do not race against fb core when
651 * releasing */
652 mutex_lock(&item->info->lock);
653 mutex_unlock(&item->info->lock);
654 framebuffer_release(item->info);
655 vfree(fb);
656 }
657 } while (item);
658}
659
660DECLARE_WORK(picolcd_fb_cleanup, picolcd_fb_do_cleanup);
661
662static int picolcd_fb_open(struct fb_info *info, int u)
663{
664 u32 *ref_cnt = info->pseudo_palette;
665 ref_cnt--;
666
667 (*ref_cnt)++;
668 return 0;
669}
670
671static int picolcd_fb_release(struct fb_info *info, int u)
672{
673 u32 *ref_cnt = info->pseudo_palette;
674 ref_cnt--;
675
676 (*ref_cnt)++;
677 if (!*ref_cnt) {
678 unsigned long flags;
679 struct picolcd_fb_cleanup_item *item = (struct picolcd_fb_cleanup_item *)ref_cnt;
680 item--;
681 spin_lock_irqsave(&fb_pending_lock, flags);
682 item->next = fb_pending;
683 fb_pending = item;
684 spin_unlock_irqrestore(&fb_pending_lock, flags);
685 schedule_work(&picolcd_fb_cleanup);
686 }
579 return 0; 687 return 0;
580} 688}
581 689
@@ -583,6 +691,8 @@ static int picolcd_set_par(struct fb_info *info)
583static struct fb_ops picolcdfb_ops = { 691static struct fb_ops picolcdfb_ops = {
584 .owner = THIS_MODULE, 692 .owner = THIS_MODULE,
585 .fb_destroy = picolcd_fb_destroy, 693 .fb_destroy = picolcd_fb_destroy,
694 .fb_open = picolcd_fb_open,
695 .fb_release = picolcd_fb_release,
586 .fb_read = fb_sys_read, 696 .fb_read = fb_sys_read,
587 .fb_write = picolcd_fb_write, 697 .fb_write = picolcd_fb_write,
588 .fb_blank = picolcd_fb_blank, 698 .fb_blank = picolcd_fb_blank,
@@ -660,11 +770,12 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
660{ 770{
661 struct device *dev = &data->hdev->dev; 771 struct device *dev = &data->hdev->dev;
662 struct fb_info *info = NULL; 772 struct fb_info *info = NULL;
663 int error = -ENOMEM; 773 int i, error = -ENOMEM;
664 u8 *fb_vbitmap = NULL; 774 u8 *fb_vbitmap = NULL;
665 u8 *fb_bitmap = NULL; 775 u8 *fb_bitmap = NULL;
776 u32 *palette;
666 777
667 fb_bitmap = vmalloc(PICOLCDFB_SIZE*picolcdfb_var.bits_per_pixel); 778 fb_bitmap = vmalloc(PICOLCDFB_SIZE*8);
668 if (fb_bitmap == NULL) { 779 if (fb_bitmap == NULL) {
669 dev_err(dev, "can't get a free page for framebuffer\n"); 780 dev_err(dev, "can't get a free page for framebuffer\n");
670 goto err_nomem; 781 goto err_nomem;
@@ -678,18 +789,29 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
678 789
679 data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT; 790 data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT;
680 data->fb_defio = picolcd_fb_defio; 791 data->fb_defio = picolcd_fb_defio;
681 info = framebuffer_alloc(0, dev); 792 /* The extra memory is:
793 * - struct picolcd_fb_cleanup_item
794 * - u32 for ref_count
795 * - 256*u32 for pseudo_palette
796 */
797 info = framebuffer_alloc(257 * sizeof(u32) + sizeof(struct picolcd_fb_cleanup_item), dev);
682 if (info == NULL) { 798 if (info == NULL) {
683 dev_err(dev, "failed to allocate a framebuffer\n"); 799 dev_err(dev, "failed to allocate a framebuffer\n");
684 goto err_nomem; 800 goto err_nomem;
685 } 801 }
686 802
803 palette = info->par + sizeof(struct picolcd_fb_cleanup_item);
804 *palette = 1;
805 palette++;
806 for (i = 0; i < 256; i++)
807 palette[i] = i > 0 && i < 16 ? 0xff : 0;
808 info->pseudo_palette = palette;
687 info->fbdefio = &data->fb_defio; 809 info->fbdefio = &data->fb_defio;
688 info->screen_base = (char __force __iomem *)fb_bitmap; 810 info->screen_base = (char __force __iomem *)fb_bitmap;
689 info->fbops = &picolcdfb_ops; 811 info->fbops = &picolcdfb_ops;
690 info->var = picolcdfb_var; 812 info->var = picolcdfb_var;
691 info->fix = picolcdfb_fix; 813 info->fix = picolcdfb_fix;
692 info->fix.smem_len = PICOLCDFB_SIZE; 814 info->fix.smem_len = PICOLCDFB_SIZE*8;
693 info->fix.smem_start = (unsigned long)fb_bitmap; 815 info->fix.smem_start = (unsigned long)fb_bitmap;
694 info->par = data; 816 info->par = data;
695 info->flags = FBINFO_FLAG_DEFAULT; 817 info->flags = FBINFO_FLAG_DEFAULT;
@@ -707,18 +829,20 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
707 dev_err(dev, "failed to create sysfs attributes\n"); 829 dev_err(dev, "failed to create sysfs attributes\n");
708 goto err_cleanup; 830 goto err_cleanup;
709 } 831 }
832 fb_deferred_io_init(info);
710 data->fb_info = info; 833 data->fb_info = info;
711 error = register_framebuffer(info); 834 error = register_framebuffer(info);
712 if (error) { 835 if (error) {
713 dev_err(dev, "failed to register framebuffer\n"); 836 dev_err(dev, "failed to register framebuffer\n");
714 goto err_sysfs; 837 goto err_sysfs;
715 } 838 }
716 fb_deferred_io_init(info);
717 /* schedule first output of framebuffer */ 839 /* schedule first output of framebuffer */
840 data->fb_force = 1;
718 schedule_delayed_work(&info->deferred_work, 0); 841 schedule_delayed_work(&info->deferred_work, 0);
719 return 0; 842 return 0;
720 843
721err_sysfs: 844err_sysfs:
845 fb_deferred_io_cleanup(info);
722 device_remove_file(dev, &dev_attr_fb_update_rate); 846 device_remove_file(dev, &dev_attr_fb_update_rate);
723err_cleanup: 847err_cleanup:
724 data->fb_vbitmap = NULL; 848 data->fb_vbitmap = NULL;
@@ -737,19 +861,17 @@ static void picolcd_exit_framebuffer(struct picolcd_data *data)
737{ 861{
738 struct fb_info *info = data->fb_info; 862 struct fb_info *info = data->fb_info;
739 u8 *fb_vbitmap = data->fb_vbitmap; 863 u8 *fb_vbitmap = data->fb_vbitmap;
740 u8 *fb_bitmap = data->fb_bitmap;
741 864
742 if (!info) 865 if (!info)
743 return; 866 return;
744 867
868 info->par = NULL;
869 device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
870 unregister_framebuffer(info);
745 data->fb_vbitmap = NULL; 871 data->fb_vbitmap = NULL;
746 data->fb_bitmap = NULL; 872 data->fb_bitmap = NULL;
747 data->fb_bpp = 0; 873 data->fb_bpp = 0;
748 data->fb_info = NULL; 874 data->fb_info = NULL;
749 device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
750 fb_deferred_io_cleanup(info);
751 unregister_framebuffer(info);
752 vfree(fb_bitmap);
753 kfree(fb_vbitmap); 875 kfree(fb_vbitmap);
754} 876}
755 877
@@ -2566,6 +2688,13 @@ static void picolcd_remove(struct hid_device *hdev)
2566 spin_lock_irqsave(&data->lock, flags); 2688 spin_lock_irqsave(&data->lock, flags);
2567 data->status |= PICOLCD_FAILED; 2689 data->status |= PICOLCD_FAILED;
2568 spin_unlock_irqrestore(&data->lock, flags); 2690 spin_unlock_irqrestore(&data->lock, flags);
2691#ifdef CONFIG_HID_PICOLCD_FB
2692 /* short-circuit FB as early as possible in order to
2693 * avoid long delays if we host console.
2694 */
2695 if (data->fb_info)
2696 data->fb_info->par = NULL;
2697#endif
2569 2698
2570 picolcd_exit_devfs(data); 2699 picolcd_exit_devfs(data);
2571 device_remove_file(&hdev->dev, &dev_attr_operation_mode); 2700 device_remove_file(&hdev->dev, &dev_attr_operation_mode);
@@ -2623,6 +2752,10 @@ static int __init picolcd_init(void)
2623static void __exit picolcd_exit(void) 2752static void __exit picolcd_exit(void)
2624{ 2753{
2625 hid_unregister_driver(&picolcd_driver); 2754 hid_unregister_driver(&picolcd_driver);
2755#ifdef CONFIG_HID_PICOLCD_FB
2756 flush_scheduled_work();
2757 WARN_ON(fb_pending);
2758#endif
2626} 2759}
2627 2760
2628module_init(picolcd_init); 2761module_init(picolcd_init);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 3ccd47850677..47d70c523d93 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -46,7 +46,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
46{ 46{
47 struct hidraw_list *list = file->private_data; 47 struct hidraw_list *list = file->private_data;
48 int ret = 0, len; 48 int ret = 0, len;
49 char *report;
50 DECLARE_WAITQUEUE(wait, current); 49 DECLARE_WAITQUEUE(wait, current);
51 50
52 mutex_lock(&list->read_mutex); 51 mutex_lock(&list->read_mutex);
@@ -84,7 +83,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
84 if (ret) 83 if (ret)
85 goto out; 84 goto out;
86 85
87 report = list->buffer[list->tail].value;
88 len = list->buffer[list->tail].len > count ? 86 len = list->buffer[list->tail].len > count ?
89 count : list->buffer[list->tail].len; 87 count : list->buffer[list->tail].len;
90 88