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