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