Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /***************************************************************************
0003  *   Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org>  *
0004  *                                                                         *
0005  *   Based on Logitech G13 driver (v0.4)                                   *
0006  *     Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu>   *
0007  *                                                                         *
0008  ***************************************************************************/
0009 
0010 #include <linux/hid.h>
0011 #include <linux/hid-debug.h>
0012 
0013 #include <linux/fb.h>
0014 #include <linux/seq_file.h>
0015 #include <linux/debugfs.h>
0016 
0017 #include <linux/module.h>
0018 #include <linux/uaccess.h>
0019 
0020 #include "hid-picolcd.h"
0021 
0022 
0023 static int picolcd_debug_reset_show(struct seq_file *f, void *p)
0024 {
0025     if (picolcd_fbinfo((struct picolcd_data *)f->private))
0026         seq_printf(f, "all fb\n");
0027     else
0028         seq_printf(f, "all\n");
0029     return 0;
0030 }
0031 
0032 static int picolcd_debug_reset_open(struct inode *inode, struct file *f)
0033 {
0034     return single_open(f, picolcd_debug_reset_show, inode->i_private);
0035 }
0036 
0037 static ssize_t picolcd_debug_reset_write(struct file *f, const char __user *user_buf,
0038         size_t count, loff_t *ppos)
0039 {
0040     struct picolcd_data *data = ((struct seq_file *)f->private_data)->private;
0041     char buf[32];
0042     size_t cnt = min(count, sizeof(buf)-1);
0043     if (copy_from_user(buf, user_buf, cnt))
0044         return -EFAULT;
0045 
0046     while (cnt > 0 && (buf[cnt-1] == ' ' || buf[cnt-1] == '\n'))
0047         cnt--;
0048     buf[cnt] = '\0';
0049     if (strcmp(buf, "all") == 0) {
0050         picolcd_reset(data->hdev);
0051         picolcd_fb_reset(data, 1);
0052     } else if (strcmp(buf, "fb") == 0) {
0053         picolcd_fb_reset(data, 1);
0054     } else {
0055         return -EINVAL;
0056     }
0057     return count;
0058 }
0059 
0060 static const struct file_operations picolcd_debug_reset_fops = {
0061     .owner    = THIS_MODULE,
0062     .open     = picolcd_debug_reset_open,
0063     .read     = seq_read,
0064     .llseek   = seq_lseek,
0065     .write    = picolcd_debug_reset_write,
0066     .release  = single_release,
0067 };
0068 
0069 /*
0070  * The "eeprom" file
0071  */
0072 static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u,
0073         size_t s, loff_t *off)
0074 {
0075     struct picolcd_data *data = f->private_data;
0076     struct picolcd_pending *resp;
0077     u8 raw_data[3];
0078     ssize_t ret = -EIO;
0079 
0080     if (s == 0)
0081         return -EINVAL;
0082     if (*off > 0x0ff)
0083         return 0;
0084 
0085     /* prepare buffer with info about what we want to read (addr & len) */
0086     raw_data[0] = *off & 0xff;
0087     raw_data[1] = (*off >> 8) & 0xff;
0088     raw_data[2] = s < 20 ? s : 20;
0089     if (*off + raw_data[2] > 0xff)
0090         raw_data[2] = 0x100 - *off;
0091     resp = picolcd_send_and_wait(data->hdev, REPORT_EE_READ, raw_data,
0092             sizeof(raw_data));
0093     if (!resp)
0094         return -EIO;
0095 
0096     if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
0097         /* successful read :) */
0098         ret = resp->raw_data[2];
0099         if (ret > s)
0100             ret = s;
0101         if (copy_to_user(u, resp->raw_data+3, ret))
0102             ret = -EFAULT;
0103         else
0104             *off += ret;
0105     } /* anything else is some kind of IO error */
0106 
0107     kfree(resp);
0108     return ret;
0109 }
0110 
0111 static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u,
0112         size_t s, loff_t *off)
0113 {
0114     struct picolcd_data *data = f->private_data;
0115     struct picolcd_pending *resp;
0116     ssize_t ret = -EIO;
0117     u8 raw_data[23];
0118 
0119     if (s == 0)
0120         return -EINVAL;
0121     if (*off > 0x0ff)
0122         return -ENOSPC;
0123 
0124     memset(raw_data, 0, sizeof(raw_data));
0125     raw_data[0] = *off & 0xff;
0126     raw_data[1] = (*off >> 8) & 0xff;
0127     raw_data[2] = min_t(size_t, 20, s);
0128     if (*off + raw_data[2] > 0xff)
0129         raw_data[2] = 0x100 - *off;
0130 
0131     if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2])))
0132         return -EFAULT;
0133     resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data,
0134             sizeof(raw_data));
0135 
0136     if (!resp)
0137         return -EIO;
0138 
0139     if (resp->in_report && resp->in_report->id == REPORT_EE_DATA) {
0140         /* check if written data matches */
0141         if (memcmp(raw_data, resp->raw_data, 3+raw_data[2]) == 0) {
0142             *off += raw_data[2];
0143             ret = raw_data[2];
0144         }
0145     }
0146     kfree(resp);
0147     return ret;
0148 }
0149 
0150 /*
0151  * Notes:
0152  * - read/write happens in chunks of at most 20 bytes, it's up to userspace
0153  *   to loop in order to get more data.
0154  * - on write errors on otherwise correct write request the bytes
0155  *   that should have been written are in undefined state.
0156  */
0157 static const struct file_operations picolcd_debug_eeprom_fops = {
0158     .owner    = THIS_MODULE,
0159     .open     = simple_open,
0160     .read     = picolcd_debug_eeprom_read,
0161     .write    = picolcd_debug_eeprom_write,
0162     .llseek   = generic_file_llseek,
0163 };
0164 
0165 /*
0166  * The "flash" file
0167  */
0168 /* record a flash address to buf (bounds check to be done by caller) */
0169 static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off)
0170 {
0171     buf[0] = off & 0xff;
0172     buf[1] = (off >> 8) & 0xff;
0173     if (data->addr_sz == 3)
0174         buf[2] = (off >> 16) & 0xff;
0175     return data->addr_sz == 2 ? 2 : 3;
0176 }
0177 
0178 /* read a given size of data (bounds check to be done by caller) */
0179 static ssize_t _picolcd_flash_read(struct picolcd_data *data, int report_id,
0180         char __user *u, size_t s, loff_t *off)
0181 {
0182     struct picolcd_pending *resp;
0183     u8 raw_data[4];
0184     ssize_t ret = 0;
0185     int len_off, err = -EIO;
0186 
0187     while (s > 0) {
0188         err = -EIO;
0189         len_off = _picolcd_flash_setaddr(data, raw_data, *off);
0190         raw_data[len_off] = s > 32 ? 32 : s;
0191         resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off+1);
0192         if (!resp || !resp->in_report)
0193             goto skip;
0194         if (resp->in_report->id == REPORT_MEMORY ||
0195             resp->in_report->id == REPORT_BL_READ_MEMORY) {
0196             if (memcmp(raw_data, resp->raw_data, len_off+1) != 0)
0197                 goto skip;
0198             if (copy_to_user(u+ret, resp->raw_data+len_off+1, raw_data[len_off])) {
0199                 err = -EFAULT;
0200                 goto skip;
0201             }
0202             *off += raw_data[len_off];
0203             s    -= raw_data[len_off];
0204             ret  += raw_data[len_off];
0205             err   = 0;
0206         }
0207 skip:
0208         kfree(resp);
0209         if (err)
0210             return ret > 0 ? ret : err;
0211     }
0212     return ret;
0213 }
0214 
0215 static ssize_t picolcd_debug_flash_read(struct file *f, char __user *u,
0216         size_t s, loff_t *off)
0217 {
0218     struct picolcd_data *data = f->private_data;
0219 
0220     if (s == 0)
0221         return -EINVAL;
0222     if (*off > 0x05fff)
0223         return 0;
0224     if (*off + s > 0x05fff)
0225         s = 0x06000 - *off;
0226 
0227     if (data->status & PICOLCD_BOOTLOADER)
0228         return _picolcd_flash_read(data, REPORT_BL_READ_MEMORY, u, s, off);
0229     else
0230         return _picolcd_flash_read(data, REPORT_READ_MEMORY, u, s, off);
0231 }
0232 
0233 /* erase block aligned to 64bytes boundary */
0234 static ssize_t _picolcd_flash_erase64(struct picolcd_data *data, int report_id,
0235         loff_t *off)
0236 {
0237     struct picolcd_pending *resp;
0238     u8 raw_data[3];
0239     int len_off;
0240     ssize_t ret = -EIO;
0241 
0242     if (*off & 0x3f)
0243         return -EINVAL;
0244 
0245     len_off = _picolcd_flash_setaddr(data, raw_data, *off);
0246     resp = picolcd_send_and_wait(data->hdev, report_id, raw_data, len_off);
0247     if (!resp || !resp->in_report)
0248         goto skip;
0249     if (resp->in_report->id == REPORT_MEMORY ||
0250         resp->in_report->id == REPORT_BL_ERASE_MEMORY) {
0251         if (memcmp(raw_data, resp->raw_data, len_off) != 0)
0252             goto skip;
0253         ret = 0;
0254     }
0255 skip:
0256     kfree(resp);
0257     return ret;
0258 }
0259 
0260 /* write a given size of data (bounds check to be done by caller) */
0261 static ssize_t _picolcd_flash_write(struct picolcd_data *data, int report_id,
0262         const char __user *u, size_t s, loff_t *off)
0263 {
0264     struct picolcd_pending *resp;
0265     u8 raw_data[36];
0266     ssize_t ret = 0;
0267     int len_off, err = -EIO;
0268 
0269     while (s > 0) {
0270         err = -EIO;
0271         len_off = _picolcd_flash_setaddr(data, raw_data, *off);
0272         raw_data[len_off] = s > 32 ? 32 : s;
0273         if (copy_from_user(raw_data+len_off+1, u, raw_data[len_off])) {
0274             err = -EFAULT;
0275             break;
0276         }
0277         resp = picolcd_send_and_wait(data->hdev, report_id, raw_data,
0278                 len_off+1+raw_data[len_off]);
0279         if (!resp || !resp->in_report)
0280             goto skip;
0281         if (resp->in_report->id == REPORT_MEMORY ||
0282             resp->in_report->id == REPORT_BL_WRITE_MEMORY) {
0283             if (memcmp(raw_data, resp->raw_data, len_off+1+raw_data[len_off]) != 0)
0284                 goto skip;
0285             *off += raw_data[len_off];
0286             s    -= raw_data[len_off];
0287             ret  += raw_data[len_off];
0288             err   = 0;
0289         }
0290 skip:
0291         kfree(resp);
0292         if (err)
0293             break;
0294     }
0295     return ret > 0 ? ret : err;
0296 }
0297 
0298 static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u,
0299         size_t s, loff_t *off)
0300 {
0301     struct picolcd_data *data = f->private_data;
0302     ssize_t err, ret = 0;
0303     int report_erase, report_write;
0304 
0305     if (s == 0)
0306         return -EINVAL;
0307     if (*off > 0x5fff)
0308         return -ENOSPC;
0309     if (s & 0x3f)
0310         return -EINVAL;
0311     if (*off & 0x3f)
0312         return -EINVAL;
0313 
0314     if (data->status & PICOLCD_BOOTLOADER) {
0315         report_erase = REPORT_BL_ERASE_MEMORY;
0316         report_write = REPORT_BL_WRITE_MEMORY;
0317     } else {
0318         report_erase = REPORT_ERASE_MEMORY;
0319         report_write = REPORT_WRITE_MEMORY;
0320     }
0321     mutex_lock(&data->mutex_flash);
0322     while (s > 0) {
0323         err = _picolcd_flash_erase64(data, report_erase, off);
0324         if (err)
0325             break;
0326         err = _picolcd_flash_write(data, report_write, u, 64, off);
0327         if (err < 0)
0328             break;
0329         ret += err;
0330         *off += err;
0331         s -= err;
0332         if (err != 64)
0333             break;
0334     }
0335     mutex_unlock(&data->mutex_flash);
0336     return ret > 0 ? ret : err;
0337 }
0338 
0339 /*
0340  * Notes:
0341  * - concurrent writing is prevented by mutex and all writes must be
0342  *   n*64 bytes and 64-byte aligned, each write being preceded by an
0343  *   ERASE which erases a 64byte block.
0344  *   If less than requested was written or an error is returned for an
0345  *   otherwise correct write request the next 64-byte block which should
0346  *   have been written is in undefined state (mostly: original, erased,
0347  *   (half-)written with write error)
0348  * - reading can happen without special restriction
0349  */
0350 static const struct file_operations picolcd_debug_flash_fops = {
0351     .owner    = THIS_MODULE,
0352     .open     = simple_open,
0353     .read     = picolcd_debug_flash_read,
0354     .write    = picolcd_debug_flash_write,
0355     .llseek   = generic_file_llseek,
0356 };
0357 
0358 
0359 /*
0360  * Helper code for HID report level dumping/debugging
0361  */
0362 static const char * const error_codes[] = {
0363     "success", "parameter missing", "data_missing", "block readonly",
0364     "block not erasable", "block too big", "section overflow",
0365     "invalid command length", "invalid data length",
0366 };
0367 
0368 static void dump_buff_as_hex(char *dst, size_t dst_sz, const u8 *data,
0369         const size_t data_len)
0370 {
0371     int i, j;
0372     for (i = j = 0; i < data_len && j + 4 < dst_sz; i++) {
0373         dst[j++] = hex_asc[(data[i] >> 4) & 0x0f];
0374         dst[j++] = hex_asc[data[i] & 0x0f];
0375         dst[j++] = ' ';
0376     }
0377     dst[j]   = '\0';
0378     if (j > 0)
0379         dst[j-1] = '\n';
0380     if (i < data_len && j > 2)
0381         dst[j-2] = dst[j-3] = '.';
0382 }
0383 
0384 void picolcd_debug_out_report(struct picolcd_data *data,
0385         struct hid_device *hdev, struct hid_report *report)
0386 {
0387     u8 *raw_data;
0388     int raw_size = (report->size >> 3) + 1;
0389     char *buff;
0390 #define BUFF_SZ 256
0391 
0392     /* Avoid unnecessary overhead if debugfs is disabled */
0393     if (list_empty(&hdev->debug_list))
0394         return;
0395 
0396     buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
0397     if (!buff)
0398         return;
0399 
0400     raw_data = hid_alloc_report_buf(report, GFP_ATOMIC);
0401     if (!raw_data) {
0402         kfree(buff);
0403         return;
0404     }
0405 
0406     snprintf(buff, BUFF_SZ, "\nout report %d (size %d) =  ",
0407             report->id, raw_size);
0408     hid_debug_event(hdev, buff);
0409     raw_data[0] = report->id;
0410     hid_output_report(report, raw_data);
0411     dump_buff_as_hex(buff, BUFF_SZ, raw_data, raw_size);
0412     hid_debug_event(hdev, buff);
0413 
0414     switch (report->id) {
0415     case REPORT_LED_STATE:
0416         /* 1 data byte with GPO state */
0417         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0418             "REPORT_LED_STATE", report->id, raw_size-1);
0419         hid_debug_event(hdev, buff);
0420         snprintf(buff, BUFF_SZ, "\tGPO state: 0x%02x\n", raw_data[1]);
0421         hid_debug_event(hdev, buff);
0422         break;
0423     case REPORT_BRIGHTNESS:
0424         /* 1 data byte with brightness */
0425         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0426             "REPORT_BRIGHTNESS", report->id, raw_size-1);
0427         hid_debug_event(hdev, buff);
0428         snprintf(buff, BUFF_SZ, "\tBrightness: 0x%02x\n", raw_data[1]);
0429         hid_debug_event(hdev, buff);
0430         break;
0431     case REPORT_CONTRAST:
0432         /* 1 data byte with contrast */
0433         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0434             "REPORT_CONTRAST", report->id, raw_size-1);
0435         hid_debug_event(hdev, buff);
0436         snprintf(buff, BUFF_SZ, "\tContrast: 0x%02x\n", raw_data[1]);
0437         hid_debug_event(hdev, buff);
0438         break;
0439     case REPORT_RESET:
0440         /* 2 data bytes with reset duration in ms */
0441         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0442             "REPORT_RESET", report->id, raw_size-1);
0443         hid_debug_event(hdev, buff);
0444         snprintf(buff, BUFF_SZ, "\tDuration: 0x%02x%02x (%dms)\n",
0445                 raw_data[2], raw_data[1], raw_data[2] << 8 | raw_data[1]);
0446         hid_debug_event(hdev, buff);
0447         break;
0448     case REPORT_LCD_CMD:
0449         /* 63 data bytes with LCD commands */
0450         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0451             "REPORT_LCD_CMD", report->id, raw_size-1);
0452         hid_debug_event(hdev, buff);
0453         /* TODO: format decoding */
0454         break;
0455     case REPORT_LCD_DATA:
0456         /* 63 data bytes with LCD data */
0457         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0458             "REPORT_LCD_CMD", report->id, raw_size-1);
0459         /* TODO: format decoding */
0460         hid_debug_event(hdev, buff);
0461         break;
0462     case REPORT_LCD_CMD_DATA:
0463         /* 63 data bytes with LCD commands and data */
0464         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0465             "REPORT_LCD_CMD", report->id, raw_size-1);
0466         /* TODO: format decoding */
0467         hid_debug_event(hdev, buff);
0468         break;
0469     case REPORT_EE_READ:
0470         /* 3 data bytes with read area description */
0471         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0472             "REPORT_EE_READ", report->id, raw_size-1);
0473         hid_debug_event(hdev, buff);
0474         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
0475                 raw_data[2], raw_data[1]);
0476         hid_debug_event(hdev, buff);
0477         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
0478         hid_debug_event(hdev, buff);
0479         break;
0480     case REPORT_EE_WRITE:
0481         /* 3+1..20 data bytes with write area description */
0482         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0483             "REPORT_EE_WRITE", report->id, raw_size-1);
0484         hid_debug_event(hdev, buff);
0485         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
0486                 raw_data[2], raw_data[1]);
0487         hid_debug_event(hdev, buff);
0488         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
0489         hid_debug_event(hdev, buff);
0490         if (raw_data[3] == 0) {
0491             snprintf(buff, BUFF_SZ, "\tNo data\n");
0492         } else if (raw_data[3] + 4 <= raw_size) {
0493             snprintf(buff, BUFF_SZ, "\tData: ");
0494             hid_debug_event(hdev, buff);
0495             dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
0496         } else {
0497             snprintf(buff, BUFF_SZ, "\tData overflowed\n");
0498         }
0499         hid_debug_event(hdev, buff);
0500         break;
0501     case REPORT_ERASE_MEMORY:
0502     case REPORT_BL_ERASE_MEMORY:
0503         /* 3 data bytes with pointer inside erase block */
0504         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0505             "REPORT_ERASE_MEMORY", report->id, raw_size-1);
0506         hid_debug_event(hdev, buff);
0507         switch (data->addr_sz) {
0508         case 2:
0509             snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x\n",
0510                     raw_data[2], raw_data[1]);
0511             break;
0512         case 3:
0513             snprintf(buff, BUFF_SZ, "\tAddress inside 64 byte block: 0x%02x%02x%02x\n",
0514                     raw_data[3], raw_data[2], raw_data[1]);
0515             break;
0516         default:
0517             snprintf(buff, BUFF_SZ, "\tNot supported\n");
0518         }
0519         hid_debug_event(hdev, buff);
0520         break;
0521     case REPORT_READ_MEMORY:
0522     case REPORT_BL_READ_MEMORY:
0523         /* 4 data bytes with read area description */
0524         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0525             "REPORT_READ_MEMORY", report->id, raw_size-1);
0526         hid_debug_event(hdev, buff);
0527         switch (data->addr_sz) {
0528         case 2:
0529             snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
0530                     raw_data[2], raw_data[1]);
0531             hid_debug_event(hdev, buff);
0532             snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
0533             break;
0534         case 3:
0535             snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
0536                     raw_data[3], raw_data[2], raw_data[1]);
0537             hid_debug_event(hdev, buff);
0538             snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
0539             break;
0540         default:
0541             snprintf(buff, BUFF_SZ, "\tNot supported\n");
0542         }
0543         hid_debug_event(hdev, buff);
0544         break;
0545     case REPORT_WRITE_MEMORY:
0546     case REPORT_BL_WRITE_MEMORY:
0547         /* 4+1..32 data bytes with write adrea description */
0548         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0549             "REPORT_WRITE_MEMORY", report->id, raw_size-1);
0550         hid_debug_event(hdev, buff);
0551         switch (data->addr_sz) {
0552         case 2:
0553             snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
0554                     raw_data[2], raw_data[1]);
0555             hid_debug_event(hdev, buff);
0556             snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
0557             hid_debug_event(hdev, buff);
0558             if (raw_data[3] == 0) {
0559                 snprintf(buff, BUFF_SZ, "\tNo data\n");
0560             } else if (raw_data[3] + 4 <= raw_size) {
0561                 snprintf(buff, BUFF_SZ, "\tData: ");
0562                 hid_debug_event(hdev, buff);
0563                 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
0564             } else {
0565                 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
0566             }
0567             break;
0568         case 3:
0569             snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
0570                     raw_data[3], raw_data[2], raw_data[1]);
0571             hid_debug_event(hdev, buff);
0572             snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
0573             hid_debug_event(hdev, buff);
0574             if (raw_data[4] == 0) {
0575                 snprintf(buff, BUFF_SZ, "\tNo data\n");
0576             } else if (raw_data[4] + 5 <= raw_size) {
0577                 snprintf(buff, BUFF_SZ, "\tData: ");
0578                 hid_debug_event(hdev, buff);
0579                 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
0580             } else {
0581                 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
0582             }
0583             break;
0584         default:
0585             snprintf(buff, BUFF_SZ, "\tNot supported\n");
0586         }
0587         hid_debug_event(hdev, buff);
0588         break;
0589     case REPORT_SPLASH_RESTART:
0590         /* TODO */
0591         break;
0592     case REPORT_EXIT_KEYBOARD:
0593         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0594             "REPORT_EXIT_KEYBOARD", report->id, raw_size-1);
0595         hid_debug_event(hdev, buff);
0596         snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
0597                 raw_data[1] | (raw_data[2] << 8),
0598                 raw_data[2], raw_data[1]);
0599         hid_debug_event(hdev, buff);
0600         break;
0601     case REPORT_VERSION:
0602         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0603             "REPORT_VERSION", report->id, raw_size-1);
0604         hid_debug_event(hdev, buff);
0605         break;
0606     case REPORT_DEVID:
0607         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0608             "REPORT_DEVID", report->id, raw_size-1);
0609         hid_debug_event(hdev, buff);
0610         break;
0611     case REPORT_SPLASH_SIZE:
0612         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0613             "REPORT_SPLASH_SIZE", report->id, raw_size-1);
0614         hid_debug_event(hdev, buff);
0615         break;
0616     case REPORT_HOOK_VERSION:
0617         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0618             "REPORT_HOOK_VERSION", report->id, raw_size-1);
0619         hid_debug_event(hdev, buff);
0620         break;
0621     case REPORT_EXIT_FLASHER:
0622         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0623             "REPORT_VERSION", report->id, raw_size-1);
0624         hid_debug_event(hdev, buff);
0625         snprintf(buff, BUFF_SZ, "\tRestart delay: %dms (0x%02x%02x)\n",
0626                 raw_data[1] | (raw_data[2] << 8),
0627                 raw_data[2], raw_data[1]);
0628         hid_debug_event(hdev, buff);
0629         break;
0630     default:
0631         snprintf(buff, BUFF_SZ, "out report %s (%d, size=%d)\n",
0632             "<unknown>", report->id, raw_size-1);
0633         hid_debug_event(hdev, buff);
0634         break;
0635     }
0636     wake_up_interruptible(&hdev->debug_wait);
0637     kfree(raw_data);
0638     kfree(buff);
0639 }
0640 
0641 void picolcd_debug_raw_event(struct picolcd_data *data,
0642         struct hid_device *hdev, struct hid_report *report,
0643         u8 *raw_data, int size)
0644 {
0645     char *buff;
0646 
0647 #define BUFF_SZ 256
0648     /* Avoid unnecessary overhead if debugfs is disabled */
0649     if (list_empty(&hdev->debug_list))
0650         return;
0651 
0652     buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
0653     if (!buff)
0654         return;
0655 
0656     switch (report->id) {
0657     case REPORT_ERROR_CODE:
0658         /* 2 data bytes with affected report and error code */
0659         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0660             "REPORT_ERROR_CODE", report->id, size-1);
0661         hid_debug_event(hdev, buff);
0662         if (raw_data[2] < ARRAY_SIZE(error_codes))
0663             snprintf(buff, BUFF_SZ, "\tError code 0x%02x (%s) in reply to report 0x%02x\n",
0664                     raw_data[2], error_codes[raw_data[2]], raw_data[1]);
0665         else
0666             snprintf(buff, BUFF_SZ, "\tError code 0x%02x in reply to report 0x%02x\n",
0667                     raw_data[2], raw_data[1]);
0668         hid_debug_event(hdev, buff);
0669         break;
0670     case REPORT_KEY_STATE:
0671         /* 2 data bytes with key state */
0672         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0673             "REPORT_KEY_STATE", report->id, size-1);
0674         hid_debug_event(hdev, buff);
0675         if (raw_data[1] == 0)
0676             snprintf(buff, BUFF_SZ, "\tNo key pressed\n");
0677         else if (raw_data[2] == 0)
0678             snprintf(buff, BUFF_SZ, "\tOne key pressed: 0x%02x (%d)\n",
0679                     raw_data[1], raw_data[1]);
0680         else
0681             snprintf(buff, BUFF_SZ, "\tTwo keys pressed: 0x%02x (%d), 0x%02x (%d)\n",
0682                     raw_data[1], raw_data[1], raw_data[2], raw_data[2]);
0683         hid_debug_event(hdev, buff);
0684         break;
0685     case REPORT_IR_DATA:
0686         /* Up to 20 byes of IR scancode data */
0687         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0688             "REPORT_IR_DATA", report->id, size-1);
0689         hid_debug_event(hdev, buff);
0690         if (raw_data[1] == 0) {
0691             snprintf(buff, BUFF_SZ, "\tUnexpectedly 0 data length\n");
0692             hid_debug_event(hdev, buff);
0693         } else if (raw_data[1] + 1 <= size) {
0694             snprintf(buff, BUFF_SZ, "\tData length: %d\n\tIR Data: ",
0695                     raw_data[1]);
0696             hid_debug_event(hdev, buff);
0697             dump_buff_as_hex(buff, BUFF_SZ, raw_data+2, raw_data[1]);
0698             hid_debug_event(hdev, buff);
0699         } else {
0700             snprintf(buff, BUFF_SZ, "\tOverflowing data length: %d\n",
0701                     raw_data[1]-1);
0702             hid_debug_event(hdev, buff);
0703         }
0704         break;
0705     case REPORT_EE_DATA:
0706         /* Data buffer in response to REPORT_EE_READ or REPORT_EE_WRITE */
0707         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0708             "REPORT_EE_DATA", report->id, size-1);
0709         hid_debug_event(hdev, buff);
0710         snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
0711                 raw_data[2], raw_data[1]);
0712         hid_debug_event(hdev, buff);
0713         snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
0714         hid_debug_event(hdev, buff);
0715         if (raw_data[3] == 0) {
0716             snprintf(buff, BUFF_SZ, "\tNo data\n");
0717             hid_debug_event(hdev, buff);
0718         } else if (raw_data[3] + 4 <= size) {
0719             snprintf(buff, BUFF_SZ, "\tData: ");
0720             hid_debug_event(hdev, buff);
0721             dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
0722             hid_debug_event(hdev, buff);
0723         } else {
0724             snprintf(buff, BUFF_SZ, "\tData overflowed\n");
0725             hid_debug_event(hdev, buff);
0726         }
0727         break;
0728     case REPORT_MEMORY:
0729         /* Data buffer in response to REPORT_READ_MEMORY or REPORT_WRITE_MEMORY */
0730         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0731             "REPORT_MEMORY", report->id, size-1);
0732         hid_debug_event(hdev, buff);
0733         switch (data->addr_sz) {
0734         case 2:
0735             snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x\n",
0736                     raw_data[2], raw_data[1]);
0737             hid_debug_event(hdev, buff);
0738             snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[3]);
0739             hid_debug_event(hdev, buff);
0740             if (raw_data[3] == 0) {
0741                 snprintf(buff, BUFF_SZ, "\tNo data\n");
0742             } else if (raw_data[3] + 4 <= size) {
0743                 snprintf(buff, BUFF_SZ, "\tData: ");
0744                 hid_debug_event(hdev, buff);
0745                 dump_buff_as_hex(buff, BUFF_SZ, raw_data+4, raw_data[3]);
0746             } else {
0747                 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
0748             }
0749             break;
0750         case 3:
0751             snprintf(buff, BUFF_SZ, "\tData address: 0x%02x%02x%02x\n",
0752                     raw_data[3], raw_data[2], raw_data[1]);
0753             hid_debug_event(hdev, buff);
0754             snprintf(buff, BUFF_SZ, "\tData length: %d\n", raw_data[4]);
0755             hid_debug_event(hdev, buff);
0756             if (raw_data[4] == 0) {
0757                 snprintf(buff, BUFF_SZ, "\tNo data\n");
0758             } else if (raw_data[4] + 5 <= size) {
0759                 snprintf(buff, BUFF_SZ, "\tData: ");
0760                 hid_debug_event(hdev, buff);
0761                 dump_buff_as_hex(buff, BUFF_SZ, raw_data+5, raw_data[4]);
0762             } else {
0763                 snprintf(buff, BUFF_SZ, "\tData overflowed\n");
0764             }
0765             break;
0766         default:
0767             snprintf(buff, BUFF_SZ, "\tNot supported\n");
0768         }
0769         hid_debug_event(hdev, buff);
0770         break;
0771     case REPORT_VERSION:
0772         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0773             "REPORT_VERSION", report->id, size-1);
0774         hid_debug_event(hdev, buff);
0775         snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
0776                 raw_data[2], raw_data[1]);
0777         hid_debug_event(hdev, buff);
0778         break;
0779     case REPORT_BL_ERASE_MEMORY:
0780         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0781             "REPORT_BL_ERASE_MEMORY", report->id, size-1);
0782         hid_debug_event(hdev, buff);
0783         /* TODO */
0784         break;
0785     case REPORT_BL_READ_MEMORY:
0786         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0787             "REPORT_BL_READ_MEMORY", report->id, size-1);
0788         hid_debug_event(hdev, buff);
0789         /* TODO */
0790         break;
0791     case REPORT_BL_WRITE_MEMORY:
0792         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0793             "REPORT_BL_WRITE_MEMORY", report->id, size-1);
0794         hid_debug_event(hdev, buff);
0795         /* TODO */
0796         break;
0797     case REPORT_DEVID:
0798         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0799             "REPORT_DEVID", report->id, size-1);
0800         hid_debug_event(hdev, buff);
0801         snprintf(buff, BUFF_SZ, "\tSerial: 0x%02x%02x%02x%02x\n",
0802                 raw_data[1], raw_data[2], raw_data[3], raw_data[4]);
0803         hid_debug_event(hdev, buff);
0804         snprintf(buff, BUFF_SZ, "\tType: 0x%02x\n",
0805                 raw_data[5]);
0806         hid_debug_event(hdev, buff);
0807         break;
0808     case REPORT_SPLASH_SIZE:
0809         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0810             "REPORT_SPLASH_SIZE", report->id, size-1);
0811         hid_debug_event(hdev, buff);
0812         snprintf(buff, BUFF_SZ, "\tTotal splash space: %d\n",
0813                 (raw_data[2] << 8) | raw_data[1]);
0814         hid_debug_event(hdev, buff);
0815         snprintf(buff, BUFF_SZ, "\tUsed splash space: %d\n",
0816                 (raw_data[4] << 8) | raw_data[3]);
0817         hid_debug_event(hdev, buff);
0818         break;
0819     case REPORT_HOOK_VERSION:
0820         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0821             "REPORT_HOOK_VERSION", report->id, size-1);
0822         hid_debug_event(hdev, buff);
0823         snprintf(buff, BUFF_SZ, "\tFirmware version: %d.%d\n",
0824                 raw_data[1], raw_data[2]);
0825         hid_debug_event(hdev, buff);
0826         break;
0827     default:
0828         snprintf(buff, BUFF_SZ, "report %s (%d, size=%d)\n",
0829             "<unknown>", report->id, size-1);
0830         hid_debug_event(hdev, buff);
0831         break;
0832     }
0833     wake_up_interruptible(&hdev->debug_wait);
0834     kfree(buff);
0835 }
0836 
0837 void picolcd_init_devfs(struct picolcd_data *data,
0838         struct hid_report *eeprom_r, struct hid_report *eeprom_w,
0839         struct hid_report *flash_r, struct hid_report *flash_w,
0840         struct hid_report *reset)
0841 {
0842     struct hid_device *hdev = data->hdev;
0843 
0844     mutex_init(&data->mutex_flash);
0845 
0846     /* reset */
0847     if (reset)
0848         data->debug_reset = debugfs_create_file("reset", 0600,
0849                 hdev->debug_dir, data, &picolcd_debug_reset_fops);
0850 
0851     /* eeprom */
0852     if (eeprom_r || eeprom_w)
0853         data->debug_eeprom = debugfs_create_file("eeprom",
0854             (eeprom_w ? S_IWUSR : 0) | (eeprom_r ? S_IRUSR : 0),
0855             hdev->debug_dir, data, &picolcd_debug_eeprom_fops);
0856 
0857     /* flash */
0858     if (flash_r && flash_r->maxfield == 1 && flash_r->field[0]->report_size == 8)
0859         data->addr_sz = flash_r->field[0]->report_count - 1;
0860     else
0861         data->addr_sz = -1;
0862     if (data->addr_sz == 2 || data->addr_sz == 3) {
0863         data->debug_flash = debugfs_create_file("flash",
0864             (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0),
0865             hdev->debug_dir, data, &picolcd_debug_flash_fops);
0866     } else if (flash_r || flash_w)
0867         hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n");
0868 }
0869 
0870 void picolcd_exit_devfs(struct picolcd_data *data)
0871 {
0872     struct dentry *dent;
0873 
0874     dent = data->debug_reset;
0875     data->debug_reset = NULL;
0876     debugfs_remove(dent);
0877     dent = data->debug_eeprom;
0878     data->debug_eeprom = NULL;
0879     debugfs_remove(dent);
0880     dent = data->debug_flash;
0881     data->debug_flash = NULL;
0882     debugfs_remove(dent);
0883     mutex_destroy(&data->mutex_flash);
0884 }
0885