hid-picolcd_debugfs.c (26894B)
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 23static 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 32static 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 37static 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 60static 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 */ 72static 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 111static 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 */ 157static 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) */ 169static 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) */ 179static 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 } 207skip: 208 kfree(resp); 209 if (err) 210 return ret > 0 ? ret : err; 211 } 212 return ret; 213} 214 215static 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 */ 234static 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 } 255skip: 256 kfree(resp); 257 return ret; 258} 259 260/* write a given size of data (bounds check to be done by caller) */ 261static 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 } 290skip: 291 kfree(resp); 292 if (err) 293 break; 294 } 295 return ret > 0 ? ret : err; 296} 297 298static 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 */ 350static 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 */ 362static 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 368static 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 384void 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 641void 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 837void 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 870void 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