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