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