root/drivers/hid/hid-picolcd_debugfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. picolcd_debug_reset_show
  2. picolcd_debug_reset_open
  3. picolcd_debug_reset_write
  4. picolcd_debug_eeprom_read
  5. picolcd_debug_eeprom_write
  6. _picolcd_flash_setaddr
  7. _picolcd_flash_read
  8. picolcd_debug_flash_read
  9. _picolcd_flash_erase64
  10. _picolcd_flash_write
  11. picolcd_debug_flash_write
  12. dump_buff_as_hex
  13. picolcd_debug_out_report
  14. picolcd_debug_raw_event
  15. picolcd_init_devfs
  16. picolcd_exit_devfs

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

/* [<][>][^][v][top][bottom][index][help] */