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