HID: fix data access in implement()
[linux-3.10.git] / drivers / hid / hid-picolcd_debugfs.c
1 /***************************************************************************
2  *   Copyright (C) 2010-2012 by Bruno PrĂ©mont <bonbons@linux-vserver.org>  *
3  *                                                                         *
4  *   Based on Logitech G13 driver (v0.4)                                   *
5  *     Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu>   *
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, version 2 of the License.               *
10  *                                                                         *
11  *   This driver is distributed in the hope that it will be useful, but    *
12  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
14  *   General Public License for more details.                              *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this software. If not see <http://www.gnu.org/licenses/>.  *
18  ***************************************************************************/
19
20 #include <linux/hid.h>
21 #include <linux/hid-debug.h>
22
23 #include <linux/fb.h>
24 #include <linux/seq_file.h>
25 #include <linux/debugfs.h>
26
27 #include <linux/module.h>
28 #include <linux/uaccess.h>
29
30 #include "hid-picolcd.h"
31
32
33 static int picolcd_debug_reset_show(struct seq_file *f, void *p)
34 {
35         if (picolcd_fbinfo((struct picolcd_data *)f->private))
36                 seq_printf(f, "all fb\n");
37         else
38                 seq_printf(f, "all\n");
39         return 0;
40 }
41
42 static int picolcd_debug_reset_open(struct inode *inode, struct file *f)
43 {
44         return single_open(f, picolcd_debug_reset_show, inode->i_private);
45 }
46
47 static ssize_t picolcd_debug_reset_write(struct file *f, const char __user *user_buf,
48                 size_t count, loff_t *ppos)
49 {
50         struct picolcd_data *data = ((struct seq_file *)f->private_data)->private;
51         char buf[32];
52         size_t cnt = min(count, sizeof(buf)-1);
53         if (copy_from_user(buf, user_buf, cnt))
54                 return -EFAULT;
55
56         while (cnt > 0 && (buf[cnt-1] == ' ' || buf[cnt-1] == '\n'))
57                 cnt--;
58         buf[cnt] = '\0';
59         if (strcmp(buf, "all") == 0) {
60                 picolcd_reset(data->hdev);
61                 picolcd_fb_reset(data, 1);
62         } else if (strcmp(buf, "fb") == 0) {
63                 picolcd_fb_reset(data, 1);
64         } else {
65                 return -EINVAL;
66         }
67         return count;
68 }
69
70 static const struct file_operations picolcd_debug_reset_fops = {
71         .owner    = THIS_MODULE,
72         .open     = picolcd_debug_reset_open,
73         .read     = seq_read,
74         .llseek   = seq_lseek,
75         .write    = picolcd_debug_reset_write,
76         .release  = single_release,
77 };
78
79 /*
80  * The "eeprom" file
81  */
82 static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u,
83                 size_t s, loff_t *off)
84 {
85         struct picolcd_data *data = f->private_data;
86         struct picolcd_pending *resp;
87         u8 raw_data[3];
88         ssize_t ret = -EIO;
89
90         if (s == 0)
91                 return -EINVAL;
92         if (*off > 0x0ff)
93                 return 0;
94
95         /* prepare buffer with info about what we want to read (addr & len) */
96         raw_data[0] = *off & 0xff;
97         raw_data[1] = (*off >> 8) & 0xff;
98         raw_data[2] = s < 20 ? s : 20;
99         if (*off + raw_data[2] > 0xff)
100                 raw_data[2] = 0x100 - *off;
101         resp = picolcd_send_and_wait(data->hdev, REPORT_EE_READ, raw_data,
102                         sizeof(raw_data));
103         if (!resp)
104                 return -EIO;
105
106         if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
107                 /* successful read :) */
108                 ret = resp->raw_data[2];
109                 if (ret > s)
110                         ret = s;
111                 if (copy_to_user(u, resp->raw_data+3, ret))
112                         ret = -EFAULT;
113                 else
114                         *off += ret;
115         } /* anything else is some kind of IO error */
116
117         kfree(resp);
118         return ret;
119 }
120
121 static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u,
122                 size_t s, loff_t *off)
123 {
124         struct picolcd_data *data = f->private_data;
125         struct picolcd_pending *resp;
126         ssize_t ret = -EIO;
127         u8 raw_data[23];
128
129         if (s == 0)
130                 return -EINVAL;
131         if (*off > 0x0ff)
132                 return -ENOSPC;
133
134         memset(raw_data, 0, sizeof(raw_data));
135         raw_data[0] = *off & 0xff;
136         raw_data[1] = (*off >> 8) & 0xff;
137         raw_data[2] = min_t(size_t, 20, s);
138         if (*off + raw_data[2] > 0xff)
139                 raw_data[2] = 0x100 - *off;
140
141         if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2])))
142                 return -EFAULT;
143         resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data,
144                         sizeof(raw_data));
145
146         if (!resp)
147                 return -EIO;
148
149         if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
150                 /* check if written data matches */
151                 if (memcmp(raw_data, resp->raw_data, 3+raw_data[2]) == 0) {
152                         *off += raw_data[2];
153                         ret = raw_data[2];
154                 }
155         }
156         kfree(resp);
157         return ret;
158 }
159
160 /*
161  * Notes:
162  * - read/write happens in chunks of at most 20 bytes, it's up to userspace
163  *   to loop in order to get more data.
164  * - on write errors on otherwise correct write request the bytes
165  *   that should have been written are in undefined state.
166  */
167 static const struct file_operations picolcd_debug_eeprom_fops = {
168         .owner    = THIS_MODULE,
169         .open     = simple_open,
170         .read     = picolcd_debug_eeprom_read,
171         .write    = picolcd_debug_eeprom_write,
172         .llseek   = generic_file_llseek,
173 };
174
175 /*
176  * The "flash" file
177  */
178 /* record a flash address to buf (bounds check to be done by caller) */
179 static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off)
180 {
181         buf[0] = off & 0xff;
182         buf[1] = (off >> 8) & 0xff;
183         if (data->addr_sz == 3)
184                 buf[2] = (off >> 16) & 0xff;
185         return data->addr_sz == 2 ? 2 : 3;
186 }
187
188 /* read a given size of data (bounds check to be done by caller) */
189 static ssize_t _picolcd_flash_read(struct picolcd_data *data, int report_id,
190                 char __user *u, size_t s, loff_t *off)
191 {
192         struct picolcd_pending *resp;
193         u8 raw_data[4];
194         ssize_t ret = 0;
195         int len_off, err = -EIO;
196
197         while (s > 0) {
198                 err = -EIO;
199                 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
200                 raw_data[len_off] = s > 32 ? 32 : s;
201                 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off+1);
202                 if (!resp || !resp->in_report)
203                         goto skip;
204                 if (resp->in_report->id == REPORT_MEMORY ||
205                         resp->in_report->id == REPORT_BL_READ_MEMORY) {
206                         if (memcmp(raw_data, resp->raw_data, len_off+1) != 0)
207                                 goto skip;
208                         if (copy_to_user(u+ret, resp->raw_data+len_off+1, raw_data[len_off])) {
209                                 err = -EFAULT;
210                                 goto skip;
211                         }
212                         *off += raw_data[len_off];
213                         s    -= raw_data[len_off];
214                         ret  += raw_data[len_off];
215                         err   = 0;
216                 }
217 skip:
218                 kfree(resp);
219                 if (err)
220                         return ret > 0 ? ret : err;
221         }
222         return ret;
223 }
224
225 static ssize_t picolcd_debug_flash_read(struct file *f, char __user *u,
226                 size_t s, loff_t *off)
227 {
228         struct picolcd_data *data = f->private_data;
229
230         if (s == 0)
231                 return -EINVAL;
232         if (*off > 0x05fff)
233                 return 0;
234         if (*off + s > 0x05fff)
235                 s = 0x06000 - *off;
236
237         if (data->status & PICOLCD_BOOTLOADER)
238                 return _picolcd_flash_read(data, REPORT_BL_READ_MEMORY, u, s, off);
239         else
240                 return _picolcd_flash_read(data, REPORT_READ_MEMORY, u, s, off);
241 }
242
243 /* erase block aligned to 64bytes boundary */
244 static ssize_t _picolcd_flash_erase64(struct picolcd_data *data, int report_id,
245                 loff_t *off)
246 {
247         struct picolcd_pending *resp;
248         u8 raw_data[3];
249         int len_off;
250         ssize_t ret = -EIO;
251
252         if (*off & 0x3f)
253                 return -EINVAL;
254
255         len_off = _picolcd_flash_setaddr(data, raw_data, *off);
256         resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off);
257         if (!resp || !resp->in_report)
258                 goto skip;
259         if (resp->in_report->id == REPORT_MEMORY ||
260                 resp->in_report->id == REPORT_BL_ERASE_MEMORY) {
261                 if (memcmp(raw_data, resp->raw_data, len_off) != 0)
262                         goto skip;
263                 ret = 0;
264         }
265 skip:
266         kfree(resp);
267         return ret;
268 }
269
270 /* write a given size of data (bounds check to be done by caller) */
271 static ssize_t _picolcd_flash_write(struct picolcd_data *data, int report_id,
272                 const char __user *u, size_t s, loff_t *off)
273 {
274         struct picolcd_pending *resp;
275         u8 raw_data[36];
276         ssize_t ret = 0;
277         int len_off, err = -EIO;
278
279         while (s > 0) {
280                 err = -EIO;
281                 len_off = _picolcd_flash_setaddr(data, raw_data, *off);
282                 raw_data[len_off] = s > 32 ? 32 : s;
283                 if (copy_from_user(raw_data+len_off+1, u, raw_data[len_off])) {
284                         err = -EFAULT;
285                         break;
286                 }
287                 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data,
288                                 len_off+1+raw_data[len_off]);
289                 if (!resp || !resp->in_report)
290                         goto skip;
291                 if (resp->in_report->id == REPORT_MEMORY ||
292                         resp->in_report->id == REPORT_BL_WRITE_MEMORY) {
293                         if (memcmp(raw_data, resp->raw_data, len_off+1+raw_data[len_off]) != 0)
294                                 goto skip;
295                         *off += raw_data[len_off];
296                         s    -= raw_data[len_off];
297                         ret  += raw_data[len_off];
298                         err   = 0;
299                 }
300 skip:
301                 kfree(resp);
302                 if (err)
303                         break;
304         }
305         return ret > 0 ? ret : err;
306 }
307
308 static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u,
309                 size_t s, loff_t *off)
310 {
311         struct picolcd_data *data = f->private_data;
312         ssize_t err, ret = 0;
313         int report_erase, report_write;
314
315         if (s == 0)
316                 return -EINVAL;
317         if (*off > 0x5fff)
318                 return -ENOSPC;
319         if (s & 0x3f)
320                 return -EINVAL;
321         if (*off & 0x3f)
322                 return -EINVAL;
323
324         if (data->status & PICOLCD_BOOTLOADER) {
325                 report_erase = REPORT_BL_ERASE_MEMORY;
326                 report_write = REPORT_BL_WRITE_MEMORY;
327         } else {
328                 report_erase = REPORT_ERASE_MEMORY;
329                 report_write = REPORT_WRITE_MEMORY;
330         }
331         mutex_lock(&data->mutex_flash);
332         while (s > 0) {
333                 err = _picolcd_flash_erase64(data, report_erase, off);
334                 if (err)
335                         break;
336                 err = _picolcd_flash_write(data, report_write, u, 64, off);
337                 if (err < 0)
338                         break;
339                 ret += err;
340                 *off += err;
341                 s -= err;
342                 if (err != 64)
343                         break;
344         }
345         mutex_unlock(&data->mutex_flash);
346         return ret > 0 ? ret : err;
347 }
348
349 /*
350  * Notes:
351  * - concurrent writing is prevented by mutex and all writes must be
352  *   n*64 bytes and 64-byte aligned, each write being preceded by an
353  *   ERASE which erases a 64byte block.
354  *   If less than requested was written or an error is returned for an
355  *   otherwise correct write request the next 64-byte block which should
356  *   have been written is in undefined state (mostly: original, erased,
357  *   (half-)written with write error)
358  * - reading can happen without special restriction
359  */
360 static const struct file_operations picolcd_debug_flash_fops = {
361         .owner    = THIS_MODULE,
362         .open     = simple_open,
363         .read     = picolcd_debug_flash_read,
364         .write    = picolcd_debug_flash_write,
365         .llseek   = generic_file_llseek,
366 };
367
368
369 /*
370  * Helper code for HID report level dumping/debugging
371  */
372 static const char * const error_codes[] = {
373         "success", "parameter missing", "data_missing", "block readonly",
374         "block not erasable", "block too big", "section overflow",
375         "invalid command length", "invalid data length",
376 };
377
378 static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data,
379                 const size_t data_len)
380 {
381         int i, j;
382         for (i = j = 0; i < data_len && j + 4 < dst_sz; i++) {
383                 dst[j++] = hex_asc[(data[i] >> 4) & 0x0f];
384                 dst[j++] = hex_asc[data[i] & 0x0f];
385                 dst[j++] = ' ';
386         }
387         dst[j]   = '\0';
388         if (j > 0)
389                 dst[j-1] = '\n';
390         if (i < data_len && j > 2)
391                 dst[j-2] = dst[j-3] = '.';
392 }
393
394 void picolcd_debug_out_report(struct picolcd_data *data,
395                 struct hid_device *hdev, struct hid_report *report)
396 {
397         u8 *raw_data;
398         int raw_size = (report->size >> 3) + 1;
399         char *buff;
400 #define BUFF_SZ 256
401
402         /* Avoid unnecessary overhead if debugfs is disabled */
403         if (list_empty(&hdev->debug_list))
404                 return;
405
406         buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
407         if (!buff)
408                 return;
409
410         raw_data = hid_alloc_report_buf(report, GFP_ATOMIC);
411         if (!raw_data) {
412                 kfree(buff);
413                 return;
414         }
415
416         snprintf(buff, BUFF_SZ, "\nout report %d (size %d) =  ",
417                         report->id, raw_size);
418         hid_debug_event(hdev, buff);
419         raw_data[0] = report->id;
420         hid_output_report(report, raw_data);
421         dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
422         hid_debug_event(hdev, buff);
423
424         switch (report->id) {
425         case REPORT_LED_STATE:
426                 /* 1 data byte with GPO state */
427                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
428                         "REPORT_LED_STATE", report->id, raw_size-1);
429                 hid_debug_event(hdev, buff);
430                 snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]);
431                 hid_debug_event(hdev, buff);
432                 break;
433         case REPORT_BRIGHTNESS:
434                 /* 1 data byte with brightness */
435                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
436                         "REPORT_BRIGHTNESS", report->id, raw_size-1);
437                 hid_debug_event(hdev, buff);
438                 snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]);
439                 hid_debug_event(hdev, buff);
440                 break;
441         case REPORT_CONTRAST:
442                 /* 1 data byte with contrast */
443                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
444                         "REPORT_CONTRAST", report->id, raw_size-1);
445                 hid_debug_event(hdev, buff);
446                 snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]);
447                 hid_debug_event(hdev, buff);
448                 break;
449         case REPORT_RESET:
450                 /* 2 data bytes with reset duration in ms */
451                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
452                         "REPORT_RESET", report->id, raw_size-1);
453                 hid_debug_event(hdev, buff);
454                 snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n",
455                                 raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]);
456                 hid_debug_event(hdev, buff);
457                 break;
458         case REPORT_LCD_CMD:
459                 /* 63 data bytes with LCD commands */
460                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
461                         "REPORT_LCD_CMD", report->id, raw_size-1);
462                 hid_debug_event(hdev, buff);
463                 /* TODO: format decoding */
464                 break;
465         case REPORT_LCD_DATA:
466                 /* 63 data bytes with LCD data */
467                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
468                         "REPORT_LCD_CMD", report->id, raw_size-1);
469                 /* TODO: format decoding */
470                 hid_debug_event(hdev, buff);
471                 break;
472         case REPORT_LCD_CMD_DATA:
473                 /* 63 data bytes with LCD commands and data */
474                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
475                         "REPORT_LCD_CMD", report->id, raw_size-1);
476                 /* TODO: format decoding */
477                 hid_debug_event(hdev, buff);
478                 break;
479         case REPORT_EE_READ:
480                 /* 3 data bytes with read area description */
481                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
482                         "REPORT_EE_READ", report->id, raw_size-1);
483                 hid_debug_event(hdev, buff);
484                 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
485                                 raw_data[2], raw_data[1]);
486                 hid_debug_event(hdev, buff);
487                 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
488                 hid_debug_event(hdev, buff);
489                 break;
490         case REPORT_EE_WRITE:
491                 /* 3+1..20 data bytes with write area description */
492                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
493                         "REPORT_EE_WRITE", report->id, raw_size-1);
494                 hid_debug_event(hdev, buff);
495                 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
496                                 raw_data[2], raw_data[1]);
497                 hid_debug_event(hdev, buff);
498                 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
499                 hid_debug_event(hdev, buff);
500                 if (raw_data[3] == 0) {
501                         snprintf(buff, BUFF_SZ, "\tNo data\n");
502                 } else if (raw_data[3] + 4 <= raw_size) {
503                         snprintf(buff, BUFF_SZ, "\tData: ");
504                         hid_debug_event(hdev, buff);
505                         dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
506                 } else {
507                         snprintf(buff, BUFF_SZ, "\tData overflowed\n");
508                 }
509                 hid_debug_event(hdev, buff);
510                 break;
511         case REPORT_ERASE_MEMORY:
512         case REPORT_BL_ERASE_MEMORY:
513                 /* 3 data bytes with pointer inside erase block */
514                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
515                         "REPORT_ERASE_MEMORY", report->id, raw_size-1);
516                 hid_debug_event(hdev, buff);
517                 switch (data->addr_sz) {
518                 case 2:
519                         snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n",
520                                         raw_data[2], raw_data[1]);
521                         break;
522                 case 3:
523                         snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n",
524                                         raw_data[3], raw_data[2], raw_data[1]);
525                         break;
526                 default:
527                         snprintf(buff, BUFF_SZ, "\tNot supported\n");
528                 }
529                 hid_debug_event(hdev, buff);
530                 break;
531         case REPORT_READ_MEMORY:
532         case REPORT_BL_READ_MEMORY:
533                 /* 4 data bytes with read area description */
534                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
535                         "REPORT_READ_MEMORY", report->id, raw_size-1);
536                 hid_debug_event(hdev, buff);
537                 switch (data->addr_sz) {
538                 case 2:
539                         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
540                                         raw_data[2], raw_data[1]);
541                         hid_debug_event(hdev, buff);
542                         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
543                         break;
544                 case 3:
545                         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
546                                         raw_data[3], raw_data[2], raw_data[1]);
547                         hid_debug_event(hdev, buff);
548                         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
549                         break;
550                 default:
551                         snprintf(buff, BUFF_SZ, "\tNot supported\n");
552                 }
553                 hid_debug_event(hdev, buff);
554                 break;
555         case REPORT_WRITE_MEMORY:
556         case REPORT_BL_WRITE_MEMORY:
557                 /* 4+1..32 data bytes with write adrea description */
558                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
559                         "REPORT_WRITE_MEMORY", report->id, raw_size-1);
560                 hid_debug_event(hdev, buff);
561                 switch (data->addr_sz) {
562                 case 2:
563                         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
564                                         raw_data[2], raw_data[1]);
565                         hid_debug_event(hdev, buff);
566                         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
567                         hid_debug_event(hdev, buff);
568                         if (raw_data[3] == 0) {
569                                 snprintf(buff, BUFF_SZ, "\tNo data\n");
570                         } else if (raw_data[3] + 4 <= raw_size) {
571                                 snprintf(buff, BUFF_SZ, "\tData: ");
572                                 hid_debug_event(hdev, buff);
573                                 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
574                         } else {
575                                 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
576                         }
577                         break;
578                 case 3:
579                         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
580                                         raw_data[3], raw_data[2], raw_data[1]);
581                         hid_debug_event(hdev, buff);
582                         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
583                         hid_debug_event(hdev, buff);
584                         if (raw_data[4] == 0) {
585                                 snprintf(buff, BUFF_SZ, "\tNo data\n");
586                         } else if (raw_data[4] + 5 <= raw_size) {
587                                 snprintf(buff, BUFF_SZ, "\tData: ");
588                                 hid_debug_event(hdev, buff);
589                                 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
590                         } else {
591                                 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
592                         }
593                         break;
594                 default:
595                         snprintf(buff, BUFF_SZ, "\tNot supported\n");
596                 }
597                 hid_debug_event(hdev, buff);
598                 break;
599         case REPORT_SPLASH_RESTART:
600                 /* TODO */
601                 break;
602         case REPORT_EXIT_KEYBOARD:
603                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
604                         "REPORT_EXIT_KEYBOARD", report->id, raw_size-1);
605                 hid_debug_event(hdev, buff);
606                 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
607                                 raw_data[1] | (raw_data[2] << 8),
608                                 raw_data[2], raw_data[1]);
609                 hid_debug_event(hdev, buff);
610                 break;
611         case REPORT_VERSION:
612                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
613                         "REPORT_VERSION", report->id, raw_size-1);
614                 hid_debug_event(hdev, buff);
615                 break;
616         case REPORT_DEVID:
617                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
618                         "REPORT_DEVID", report->id, raw_size-1);
619                 hid_debug_event(hdev, buff);
620                 break;
621         case REPORT_SPLASH_SIZE:
622                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
623                         "REPORT_SPLASH_SIZE", report->id, raw_size-1);
624                 hid_debug_event(hdev, buff);
625                 break;
626         case REPORT_HOOK_VERSION:
627                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
628                         "REPORT_HOOK_VERSION", report->id, raw_size-1);
629                 hid_debug_event(hdev, buff);
630                 break;
631         case REPORT_EXIT_FLASHER:
632                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
633                         "REPORT_VERSION", report->id, raw_size-1);
634                 hid_debug_event(hdev, buff);
635                 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
636                                 raw_data[1] | (raw_data[2] << 8),
637                                 raw_data[2], raw_data[1]);
638                 hid_debug_event(hdev, buff);
639                 break;
640         default:
641                 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
642                         "<unknown>", report->id, raw_size-1);
643                 hid_debug_event(hdev, buff);
644                 break;
645         }
646         wake_up_interruptible(&hdev->debug_wait);
647         kfree(raw_data);
648         kfree(buff);
649 }
650
651 void picolcd_debug_raw_event(struct picolcd_data *data,
652                 struct hid_device *hdev, struct hid_report *report,
653                 u8 *raw_data, int size)
654 {
655         char *buff;
656
657 #define BUFF_SZ 256
658         /* Avoid unnecessary overhead if debugfs is disabled */
659         if (list_empty(&hdev->debug_list))
660                 return;
661
662         buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
663         if (!buff)
664                 return;
665
666         switch (report->id) {
667         case REPORT_ERROR_CODE:
668                 /* 2 data bytes with affected report and error code */
669                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
670                         "REPORT_ERROR_CODE", report->id, size-1);
671                 hid_debug_event(hdev, buff);
672                 if (raw_data[2] < ARRAY_SIZE(error_codes))
673                         snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
674                                         raw_data[2], error_codes[raw_data[2]], raw_data[1]);
675                 else
676                         snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
677                                         raw_data[2], raw_data[1]);
678                 hid_debug_event(hdev, buff);
679                 break;
680         case REPORT_KEY_STATE:
681                 /* 2 data bytes with key state */
682                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
683                         "REPORT_KEY_STATE", report->id, size-1);
684                 hid_debug_event(hdev, buff);
685                 if (raw_data[1] == 0)
686                         snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
687                 else if (raw_data[2] == 0)
688                         snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
689                                         raw_data[1], raw_data[1]);
690                 else
691                         snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
692                                         raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
693                 hid_debug_event(hdev, buff);
694                 break;
695         case REPORT_IR_DATA:
696                 /* Up to 20 byes of IR scancode data */
697                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
698                         "REPORT_IR_DATA", report->id, size-1);
699                 hid_debug_event(hdev, buff);
700                 if (raw_data[1] == 0) {
701                         snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
702                         hid_debug_event(hdev, buff);
703                 } else if (raw_data[1] + 1 <= size) {
704                         snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
705                                         raw_data[1]);
706                         hid_debug_event(hdev, buff);
707                         dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]);
708                         hid_debug_event(hdev, buff);
709                 } else {
710                         snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
711                                         raw_data[1]-1);
712                         hid_debug_event(hdev, buff);
713                 }
714                 break;
715         case REPORT_EE_DATA:
716                 /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
717                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
718                         "REPORT_EE_DATA", report->id, size-1);
719                 hid_debug_event(hdev, buff);
720                 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
721                                 raw_data[2], raw_data[1]);
722                 hid_debug_event(hdev, buff);
723                 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
724                 hid_debug_event(hdev, buff);
725                 if (raw_data[3] == 0) {
726                         snprintf(buff, BUFF_SZ, "\tNo data\n");
727                         hid_debug_event(hdev, buff);
728                 } else if (raw_data[3] + 4 <= size) {
729                         snprintf(buff, BUFF_SZ, "\tData: ");
730                         hid_debug_event(hdev, buff);
731                         dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
732                         hid_debug_event(hdev, buff);
733                 } else {
734                         snprintf(buff, BUFF_SZ, "\tData overflowed\n");
735                         hid_debug_event(hdev, buff);
736                 }
737                 break;
738         case REPORT_MEMORY:
739                 /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRTIE_MEMORY */
740                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
741                         "REPORT_MEMORY", report->id, size-1);
742                 hid_debug_event(hdev, buff);
743                 switch (data->addr_sz) {
744                 case 2:
745                         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
746                                         raw_data[2], raw_data[1]);
747                         hid_debug_event(hdev, buff);
748                         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
749                         hid_debug_event(hdev, buff);
750                         if (raw_data[3] == 0) {
751                                 snprintf(buff, BUFF_SZ, "\tNo data\n");
752                         } else if (raw_data[3] + 4 <= size) {
753                                 snprintf(buff, BUFF_SZ, "\tData: ");
754                                 hid_debug_event(hdev, buff);
755                                 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
756                         } else {
757                                 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
758                         }
759                         break;
760                 case 3:
761                         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
762                                         raw_data[3], raw_data[2], raw_data[1]);
763                         hid_debug_event(hdev, buff);
764                         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
765                         hid_debug_event(hdev, buff);
766                         if (raw_data[4] == 0) {
767                                 snprintf(buff, BUFF_SZ, "\tNo data\n");
768                         } else if (raw_data[4] + 5 <= size) {
769                                 snprintf(buff, BUFF_SZ, "\tData: ");
770                                 hid_debug_event(hdev, buff);
771                                 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
772                         } else {
773                                 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
774                         }
775                         break;
776                 default:
777                         snprintf(buff, BUFF_SZ, "\tNot supported\n");
778                 }
779                 hid_debug_event(hdev, buff);
780                 break;
781         case REPORT_VERSION:
782                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
783                         "REPORT_VERSION", report->id, size-1);
784                 hid_debug_event(hdev, buff);
785                 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
786                                 raw_data[2], raw_data[1]);
787                 hid_debug_event(hdev, buff);
788                 break;
789         case REPORT_BL_ERASE_MEMORY:
790                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
791                         "REPORT_BL_ERASE_MEMORY", report->id, size-1);
792                 hid_debug_event(hdev, buff);
793                 /* TODO */
794                 break;
795         case REPORT_BL_READ_MEMORY:
796                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
797                         "REPORT_BL_READ_MEMORY", report->id, size-1);
798                 hid_debug_event(hdev, buff);
799                 /* TODO */
800                 break;
801         case REPORT_BL_WRITE_MEMORY:
802                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
803                         "REPORT_BL_WRITE_MEMORY", report->id, size-1);
804                 hid_debug_event(hdev, buff);
805                 /* TODO */
806                 break;
807         case REPORT_DEVID:
808                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
809                         "REPORT_DEVID", report->id, size-1);
810                 hid_debug_event(hdev, buff);
811                 snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
812                                 raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
813                 hid_debug_event(hdev, buff);
814                 snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
815                                 raw_data[5]);
816                 hid_debug_event(hdev, buff);
817                 break;
818         case REPORT_SPLASH_SIZE:
819                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
820                         "REPORT_SPLASH_SIZE", report->id, size-1);
821                 hid_debug_event(hdev, buff);
822                 snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
823                                 (raw_data[2] << 8) | raw_data[1]);
824                 hid_debug_event(hdev, buff);
825                 snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
826                                 (raw_data[4] << 8) | raw_data[3]);
827                 hid_debug_event(hdev, buff);
828                 break;
829         case REPORT_HOOK_VERSION:
830                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
831                         "REPORT_HOOK_VERSION", report->id, size-1);
832                 hid_debug_event(hdev, buff);
833                 snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
834                                 raw_data[1], raw_data[2]);
835                 hid_debug_event(hdev, buff);
836                 break;
837         default:
838                 snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
839                         "<unknown>", report->id, size-1);
840                 hid_debug_event(hdev, buff);
841                 break;
842         }
843         wake_up_interruptible(&hdev->debug_wait);
844         kfree(buff);
845 }
846
847 void picolcd_init_devfs(struct picolcd_data *data,
848                 struct hid_report *eeprom_r, struct hid_report *eeprom_w,
849                 struct hid_report *flash_r, struct hid_report *flash_w,
850                 struct hid_report *reset)
851 {
852         struct hid_device *hdev = data->hdev;
853
854         mutex_init(&data->mutex_flash);
855
856         /* reset */
857         if (reset)
858                 data->debug_reset = debugfs_create_file("reset", 0600,
859                                 hdev->debug_dir, data, &picolcd_debug_reset_fops);
860
861         /* eeprom */
862         if (eeprom_r || eeprom_w)
863                 data->debug_eeprom = debugfs_create_file("eeprom",
864                         (eeprom_w ? S_IWUSR : 0) | (eeprom_r ? S_IRUSR : 0),
865                         hdev->debug_dir, data, &picolcd_debug_eeprom_fops);
866
867         /* flash */
868         if (flash_r && flash_r->maxfield == 1 && flash_r->field[0]->report_size == 8)
869                 data->addr_sz = flash_r->field[0]->report_count - 1;
870         else
871                 data->addr_sz = -1;
872         if (data->addr_sz == 2 || data->addr_sz == 3) {
873                 data->debug_flash = debugfs_create_file("flash",
874                         (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0),
875                         hdev->debug_dir, data, &picolcd_debug_flash_fops);
876         } else if (flash_r || flash_w)
877                 hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n");
878 }
879
880 void picolcd_exit_devfs(struct picolcd_data *data)
881 {
882         struct dentry *dent;
883
884         dent = data->debug_reset;
885         data->debug_reset = NULL;
886         if (dent)
887                 debugfs_remove(dent);
888         dent = data->debug_eeprom;
889         data->debug_eeprom = NULL;
890         if (dent)
891                 debugfs_remove(dent);
892         dent = data->debug_flash;
893         data->debug_flash = NULL;
894         if (dent)
895                 debugfs_remove(dent);
896         mutex_destroy(&data->mutex_flash);
897 }
898