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 #include "usbhid/usbhid.h" 23 #include <linux/usb.h> 24 25 #include <linux/fb.h> 26 #include <linux/seq_file.h> 27 #include <linux/debugfs.h> 28 29 #include <linux/module.h> 30 31 #include "hid-picolcd.h" 32 33 34 static int picolcd_debug_reset_show(struct seq_file *f, void *p) 35 { 36 if (picolcd_fbinfo((struct picolcd_data *)f->private)) 37 seq_printf(f, "all fb\n"); 38 else 39 seq_printf(f, "all\n"); 40 return 0; 41 } 42 43 static int picolcd_debug_reset_open(struct inode *inode, struct file *f) 44 { 45 return single_open(f, picolcd_debug_reset_show, inode->i_private); 46 } 47 48 static ssize_t picolcd_debug_reset_write(struct file *f, const char __user *user_buf, 49 size_t count, loff_t *ppos) 50 { 51 struct picolcd_data *data = ((struct seq_file *)f->private_data)->private; 52 char buf[32]; 53 size_t cnt = min(count, sizeof(buf)-1); 54 if (copy_from_user(buf, user_buf, cnt)) 55 return -EFAULT; 56 57 while (cnt > 0 && (buf[cnt-1] == ' ' || buf[cnt-1] == '\n')) 58 cnt--; 59 buf[cnt] = '\0'; 60 if (strcmp(buf, "all") == 0) { 61 picolcd_reset(data->hdev); 62 picolcd_fb_reset(data, 1); 63 } else if (strcmp(buf, "fb") == 0) { 64 picolcd_fb_reset(data, 1); 65 } else { 66 return -EINVAL; 67 } 68 return count; 69 } 70 71 static const struct file_operations picolcd_debug_reset_fops = { 72 .owner = THIS_MODULE, 73 .open = picolcd_debug_reset_open, 74 .read = seq_read, 75 .llseek = seq_lseek, 76 .write = picolcd_debug_reset_write, 77 .release = single_release, 78 }; 79 80 /* 81 * The "eeprom" file 82 */ 83 static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u, 84 size_t s, loff_t *off) 85 { 86 struct picolcd_data *data = f->private_data; 87 struct picolcd_pending *resp; 88 u8 raw_data[3]; 89 ssize_t ret = -EIO; 90 91 if (s == 0) 92 return -EINVAL; 93 if (*off > 0x0ff) 94 return 0; 95 96 /* prepare buffer with info about what we want to read (addr & len) */ 97 raw_data[0] = *off & 0xff; 98 raw_data[1] = (*off >> 8) & 0xff; 99 raw_data[2] = s < 20 ? s : 20; 100 if (*off + raw_data[2] > 0xff) 101 raw_data[2] = 0x100 - *off; 102 resp = picolcd_send_and_wait(data->hdev, REPORT_EE_READ, raw_data, 103 sizeof(raw_data)); 104 if (!resp) 105 return -EIO; 106 107 if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) { 108 /* successful read :) */ 109 ret = resp->raw_data[2]; 110 if (ret > s) 111 ret = s; 112 if (copy_to_user(u, resp->raw_data+3, ret)) 113 ret = -EFAULT; 114 else 115 *off += ret; 116 } /* anything else is some kind of IO error */ 117 118 kfree(resp); 119 return ret; 120 } 121 122 static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u, 123 size_t s, loff_t *off) 124 { 125 struct picolcd_data *data = f->private_data; 126 struct picolcd_pending *resp; 127 ssize_t ret = -EIO; 128 u8 raw_data[23]; 129 130 if (s == 0) 131 return -EINVAL; 132 if (*off > 0x0ff) 133 return -ENOSPC; 134 135 memset(raw_data, 0, sizeof(raw_data)); 136 raw_data[0] = *off & 0xff; 137 raw_data[1] = (*off >> 8) & 0xff; 138 raw_data[2] = min_t(size_t, 20, s); 139 if (*off + raw_data[2] > 0xff) 140 raw_data[2] = 0x100 - *off; 141 142 if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2]))) 143 return -EFAULT; 144 resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data, 145 sizeof(raw_data)); 146 147 if (!resp) 148 return -EIO; 149 150 if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) { 151 /* check if written data matches */ 152 if (memcmp(raw_data, resp->raw_data, 3+raw_data[2]) == 0) { 153 *off += raw_data[2]; 154 ret = raw_data[2]; 155 } 156 } 157 kfree(resp); 158 return ret; 159 } 160 161 /* 162 * Notes: 163 * - read/write happens in chunks of at most 20 bytes, it's up to userspace 164 * to loop in order to get more data. 165 * - on write errors on otherwise correct write request the bytes 166 * that should have been written are in undefined state. 167 */ 168 static const struct file_operations picolcd_debug_eeprom_fops = { 169 .owner = THIS_MODULE, 170 .open = simple_open, 171 .read = picolcd_debug_eeprom_read, 172 .write = picolcd_debug_eeprom_write, 173 .llseek = generic_file_llseek, 174 }; 175 176 /* 177 * The "flash" file 178 */ 179 /* record a flash address to buf (bounds check to be done by caller) */ 180 static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off) 181 { 182 buf[0] = off & 0xff; 183 buf[1] = (off >> 8) & 0xff; 184 if (data->addr_sz == 3) 185 buf[2] = (off >> 16) & 0xff; 186 return data->addr_sz == 2 ? 2 : 3; 187 } 188 189 /* read a given size of data (bounds check to be done by caller) */ 190 static ssize_t _picolcd_flash_read(struct picolcd_data *data, int report_id, 191 char __user *u, size_t s, loff_t *off) 192 { 193 struct picolcd_pending *resp; 194 u8 raw_data[4]; 195 ssize_t ret = 0; 196 int len_off, err = -EIO; 197 198 while (s > 0) { 199 err = -EIO; 200 len_off = _picolcd_flash_setaddr(data, raw_data, *off); 201 raw_data[len_off] = s > 32 ? 32 : s; 202 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off+1); 203 if (!resp || !resp->in_report) 204 goto skip; 205 if (resp->in_report->id == REPORT_MEMORY || 206 resp->in_report->id == REPORT_BL_READ_MEMORY) { 207 if (memcmp(raw_data, resp->raw_data, len_off+1) != 0) 208 goto skip; 209 if (copy_to_user(u+ret, resp->raw_data+len_off+1, raw_data[len_off])) { 210 err = -EFAULT; 211 goto skip; 212 } 213 *off += raw_data[len_off]; 214 s -= raw_data[len_off]; 215 ret += raw_data[len_off]; 216 err = 0; 217 } 218 skip: 219 kfree(resp); 220 if (err) 221 return ret > 0 ? ret : err; 222 } 223 return ret; 224 } 225 226 static ssize_t picolcd_debug_flash_read(struct file *f, char __user *u, 227 size_t s, loff_t *off) 228 { 229 struct picolcd_data *data = f->private_data; 230 231 if (s == 0) 232 return -EINVAL; 233 if (*off > 0x05fff) 234 return 0; 235 if (*off + s > 0x05fff) 236 s = 0x06000 - *off; 237 238 if (data->status & PICOLCD_BOOTLOADER) 239 return _picolcd_flash_read(data, REPORT_BL_READ_MEMORY, u, s, off); 240 else 241 return _picolcd_flash_read(data, REPORT_READ_MEMORY, u, s, off); 242 } 243 244 /* erase block aligned to 64bytes boundary */ 245 static ssize_t _picolcd_flash_erase64(struct picolcd_data *data, int report_id, 246 loff_t *off) 247 { 248 struct picolcd_pending *resp; 249 u8 raw_data[3]; 250 int len_off; 251 ssize_t ret = -EIO; 252 253 if (*off & 0x3f) 254 return -EINVAL; 255 256 len_off = _picolcd_flash_setaddr(data, raw_data, *off); 257 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off); 258 if (!resp || !resp->in_report) 259 goto skip; 260 if (resp->in_report->id == REPORT_MEMORY || 261 resp->in_report->id == REPORT_BL_ERASE_MEMORY) { 262 if (memcmp(raw_data, resp->raw_data, len_off) != 0) 263 goto skip; 264 ret = 0; 265 } 266 skip: 267 kfree(resp); 268 return ret; 269 } 270 271 /* write a given size of data (bounds check to be done by caller) */ 272 static ssize_t _picolcd_flash_write(struct picolcd_data *data, int report_id, 273 const char __user *u, size_t s, loff_t *off) 274 { 275 struct picolcd_pending *resp; 276 u8 raw_data[36]; 277 ssize_t ret = 0; 278 int len_off, err = -EIO; 279 280 while (s > 0) { 281 err = -EIO; 282 len_off = _picolcd_flash_setaddr(data, raw_data, *off); 283 raw_data[len_off] = s > 32 ? 32 : s; 284 if (copy_from_user(raw_data+len_off+1, u, raw_data[len_off])) { 285 err = -EFAULT; 286 break; 287 } 288 resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, 289 len_off+1+raw_data[len_off]); 290 if (!resp || !resp->in_report) 291 goto skip; 292 if (resp->in_report->id == REPORT_MEMORY || 293 resp->in_report->id == REPORT_BL_WRITE_MEMORY) { 294 if (memcmp(raw_data, resp->raw_data, len_off+1+raw_data[len_off]) != 0) 295 goto skip; 296 *off += raw_data[len_off]; 297 s -= raw_data[len_off]; 298 ret += raw_data[len_off]; 299 err = 0; 300 } 301 skip: 302 kfree(resp); 303 if (err) 304 break; 305 } 306 return ret > 0 ? ret : err; 307 } 308 309 static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u, 310 size_t s, loff_t *off) 311 { 312 struct picolcd_data *data = f->private_data; 313 ssize_t err, ret = 0; 314 int report_erase, report_write; 315 316 if (s == 0) 317 return -EINVAL; 318 if (*off > 0x5fff) 319 return -ENOSPC; 320 if (s & 0x3f) 321 return -EINVAL; 322 if (*off & 0x3f) 323 return -EINVAL; 324 325 if (data->status & PICOLCD_BOOTLOADER) { 326 report_erase = REPORT_BL_ERASE_MEMORY; 327 report_write = REPORT_BL_WRITE_MEMORY; 328 } else { 329 report_erase = REPORT_ERASE_MEMORY; 330 report_write = REPORT_WRITE_MEMORY; 331 } 332 mutex_lock(&data->mutex_flash); 333 while (s > 0) { 334 err = _picolcd_flash_erase64(data, report_erase, off); 335 if (err) 336 break; 337 err = _picolcd_flash_write(data, report_write, u, 64, off); 338 if (err < 0) 339 break; 340 ret += err; 341 *off += err; 342 s -= err; 343 if (err != 64) 344 break; 345 } 346 mutex_unlock(&data->mutex_flash); 347 return ret > 0 ? ret : err; 348 } 349 350 /* 351 * Notes: 352 * - concurrent writing is prevented by mutex and all writes must be 353 * n*64 bytes and 64-byte aligned, each write being preceded by an 354 * ERASE which erases a 64byte block. 355 * If less than requested was written or an error is returned for an 356 * otherwise correct write request the next 64-byte block which should 357 * have been written is in undefined state (mostly: original, erased, 358 * (half-)written with write error) 359 * - reading can happen without special restriction 360 */ 361 static const struct file_operations picolcd_debug_flash_fops = { 362 .owner = THIS_MODULE, 363 .open = simple_open, 364 .read = picolcd_debug_flash_read, 365 .write = picolcd_debug_flash_write, 366 .llseek = generic_file_llseek, 367 }; 368 369 370 /* 371 * Helper code for HID report level dumping/debugging 372 */ 373 static const char * const error_codes[] = { 374 "success", "parameter missing", "data_missing", "block readonly", 375 "block not erasable", "block too big", "section overflow", 376 "invalid command length", "invalid data length", 377 }; 378 379 static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data, 380 const size_t data_len) 381 { 382 int i, j; 383 for (i = j = 0; i < data_len && j + 3 < dst_sz; i++) { 384 dst[j++] = hex_asc[(data[i] >> 4) & 0x0f]; 385 dst[j++] = hex_asc[data[i] & 0x0f]; 386 dst[j++] = ' '; 387 } 388 if (j < dst_sz) { 389 dst[j--] = '\0'; 390 dst[j] = '\n'; 391 } else 392 dst[j] = '\0'; 393 } 394 395 void picolcd_debug_out_report(struct picolcd_data *data, 396 struct hid_device *hdev, struct hid_report *report) 397 { 398 u8 raw_data[70]; 399 int raw_size = (report->size >> 3) + 1; 400 char *buff; 401 #define BUFF_SZ 256 402 403 /* Avoid unnecessary overhead if debugfs is disabled */ 404 if (!hdev->debug_events) 405 return; 406 407 buff = kmalloc(BUFF_SZ, GFP_ATOMIC); 408 if (!buff) 409 return; 410 411 snprintf(buff, BUFF_SZ, "\nout report %d (size %d) = ", 412 report->id, raw_size); 413 hid_debug_event(hdev, buff); 414 if (raw_size + 5 > sizeof(raw_data)) { 415 kfree(buff); 416 hid_debug_event(hdev, " TOO BIG\n"); 417 return; 418 } else { 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 425 switch (report->id) { 426 case REPORT_LED_STATE: 427 /* 1 data byte with GPO state */ 428 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 429 "REPORT_LED_STATE", report->id, raw_size-1); 430 hid_debug_event(hdev, buff); 431 snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]); 432 hid_debug_event(hdev, buff); 433 break; 434 case REPORT_BRIGHTNESS: 435 /* 1 data byte with brightness */ 436 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 437 "REPORT_BRIGHTNESS", report->id, raw_size-1); 438 hid_debug_event(hdev, buff); 439 snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]); 440 hid_debug_event(hdev, buff); 441 break; 442 case REPORT_CONTRAST: 443 /* 1 data byte with contrast */ 444 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 445 "REPORT_CONTRAST", report->id, raw_size-1); 446 hid_debug_event(hdev, buff); 447 snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]); 448 hid_debug_event(hdev, buff); 449 break; 450 case REPORT_RESET: 451 /* 2 data bytes with reset duration in ms */ 452 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 453 "REPORT_RESET", report->id, raw_size-1); 454 hid_debug_event(hdev, buff); 455 snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n", 456 raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]); 457 hid_debug_event(hdev, buff); 458 break; 459 case REPORT_LCD_CMD: 460 /* 63 data bytes with LCD commands */ 461 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 462 "REPORT_LCD_CMD", report->id, raw_size-1); 463 hid_debug_event(hdev, buff); 464 /* TODO: format decoding */ 465 break; 466 case REPORT_LCD_DATA: 467 /* 63 data bytes with LCD data */ 468 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 469 "REPORT_LCD_CMD", report->id, raw_size-1); 470 /* TODO: format decoding */ 471 hid_debug_event(hdev, buff); 472 break; 473 case REPORT_LCD_CMD_DATA: 474 /* 63 data bytes with LCD commands and data */ 475 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 476 "REPORT_LCD_CMD", report->id, raw_size-1); 477 /* TODO: format decoding */ 478 hid_debug_event(hdev, buff); 479 break; 480 case REPORT_EE_READ: 481 /* 3 data bytes with read area description */ 482 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 483 "REPORT_EE_READ", 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 break; 491 case REPORT_EE_WRITE: 492 /* 3+1..20 data bytes with write area description */ 493 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 494 "REPORT_EE_WRITE", report->id, raw_size-1); 495 hid_debug_event(hdev, buff); 496 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 497 raw_data[2], raw_data[1]); 498 hid_debug_event(hdev, buff); 499 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 500 hid_debug_event(hdev, buff); 501 if (raw_data[3] == 0) { 502 snprintf(buff, BUFF_SZ, "\tNo data\n"); 503 } else if (raw_data[3] + 4 <= raw_size) { 504 snprintf(buff, BUFF_SZ, "\tData: "); 505 hid_debug_event(hdev, buff); 506 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]); 507 } else { 508 snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 509 } 510 hid_debug_event(hdev, buff); 511 break; 512 case REPORT_ERASE_MEMORY: 513 case REPORT_BL_ERASE_MEMORY: 514 /* 3 data bytes with pointer inside erase block */ 515 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 516 "REPORT_ERASE_MEMORY", report->id, raw_size-1); 517 hid_debug_event(hdev, buff); 518 switch (data->addr_sz) { 519 case 2: 520 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n", 521 raw_data[2], raw_data[1]); 522 break; 523 case 3: 524 snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n", 525 raw_data[3], raw_data[2], raw_data[1]); 526 break; 527 default: 528 snprintf(buff, BUFF_SZ, "\tNot supported\n"); 529 } 530 hid_debug_event(hdev, buff); 531 break; 532 case REPORT_READ_MEMORY: 533 case REPORT_BL_READ_MEMORY: 534 /* 4 data bytes with read area description */ 535 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 536 "REPORT_READ_MEMORY", report->id, raw_size-1); 537 hid_debug_event(hdev, buff); 538 switch (data->addr_sz) { 539 case 2: 540 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 541 raw_data[2], raw_data[1]); 542 hid_debug_event(hdev, buff); 543 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 544 break; 545 case 3: 546 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n", 547 raw_data[3], raw_data[2], raw_data[1]); 548 hid_debug_event(hdev, buff); 549 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]); 550 break; 551 default: 552 snprintf(buff, BUFF_SZ, "\tNot supported\n"); 553 } 554 hid_debug_event(hdev, buff); 555 break; 556 case REPORT_WRITE_MEMORY: 557 case REPORT_BL_WRITE_MEMORY: 558 /* 4+1..32 data bytes with write adrea description */ 559 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 560 "REPORT_WRITE_MEMORY", report->id, raw_size-1); 561 hid_debug_event(hdev, buff); 562 switch (data->addr_sz) { 563 case 2: 564 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n", 565 raw_data[2], raw_data[1]); 566 hid_debug_event(hdev, buff); 567 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]); 568 hid_debug_event(hdev, buff); 569 if (raw_data[3] == 0) { 570 snprintf(buff, BUFF_SZ, "\tNo data\n"); 571 } else if (raw_data[3] + 4 <= raw_size) { 572 snprintf(buff, BUFF_SZ, "\tData: "); 573 hid_debug_event(hdev, buff); 574 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]); 575 } else { 576 snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 577 } 578 break; 579 case 3: 580 snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n", 581 raw_data[3], raw_data[2], raw_data[1]); 582 hid_debug_event(hdev, buff); 583 snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]); 584 hid_debug_event(hdev, buff); 585 if (raw_data[4] == 0) { 586 snprintf(buff, BUFF_SZ, "\tNo data\n"); 587 } else if (raw_data[4] + 5 <= raw_size) { 588 snprintf(buff, BUFF_SZ, "\tData: "); 589 hid_debug_event(hdev, buff); 590 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]); 591 } else { 592 snprintf(buff, BUFF_SZ, "\tData overflowed\n"); 593 } 594 break; 595 default: 596 snprintf(buff, BUFF_SZ, "\tNot supported\n"); 597 } 598 hid_debug_event(hdev, buff); 599 break; 600 case REPORT_SPLASH_RESTART: 601 /* TODO */ 602 break; 603 case REPORT_EXIT_KEYBOARD: 604 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 605 "REPORT_EXIT_KEYBOARD", report->id, raw_size-1); 606 hid_debug_event(hdev, buff); 607 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n", 608 raw_data[1] | (raw_data[2] << 8), 609 raw_data[2], raw_data[1]); 610 hid_debug_event(hdev, buff); 611 break; 612 case REPORT_VERSION: 613 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 614 "REPORT_VERSION", report->id, raw_size-1); 615 hid_debug_event(hdev, buff); 616 break; 617 case REPORT_DEVID: 618 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 619 "REPORT_DEVID", report->id, raw_size-1); 620 hid_debug_event(hdev, buff); 621 break; 622 case REPORT_SPLASH_SIZE: 623 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 624 "REPORT_SPLASH_SIZE", report->id, raw_size-1); 625 hid_debug_event(hdev, buff); 626 break; 627 case REPORT_HOOK_VERSION: 628 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 629 "REPORT_HOOK_VERSION", report->id, raw_size-1); 630 hid_debug_event(hdev, buff); 631 break; 632 case REPORT_EXIT_FLASHER: 633 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 634 "REPORT_VERSION", report->id, raw_size-1); 635 hid_debug_event(hdev, buff); 636 snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n", 637 raw_data[1] | (raw_data[2] << 8), 638 raw_data[2], raw_data[1]); 639 hid_debug_event(hdev, buff); 640 break; 641 default: 642 snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n", 643 "<unknown>", report->id, raw_size-1); 644 hid_debug_event(hdev, buff); 645 break; 646 } 647 wake_up_interruptible(&hdev->debug_wait); 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 (!hdev->debug_events) 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]-1); 706 hid_debug_event(hdev, buff); 707 dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]-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 if (dent) 887 debugfs_remove(dent); 888 dent = data->debug_eeprom; 889 data->debug_eeprom = NULL; 890 if (dent) 891 debugfs_remove(dent); 892 dent = data->debug_flash; 893 data->debug_flash = NULL; 894 if (dent) 895 debugfs_remove(dent); 896 mutex_destroy(&data->mutex_flash); 897 } 898 899