hid-picolcd_debugfs.c 27 KB

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