root/drivers/hid/hid-wiimote-debug.c

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

DEFINITIONS

This source file includes following definitions.
  1. wiidebug_eeprom_read
  2. wiidebug_drm_show
  3. wiidebug_drm_open
  4. wiidebug_drm_write
  5. wiidebug_init
  6. wiidebug_deinit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Debug support for HID Nintendo Wii / Wii U peripherals
   4  * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
   5  */
   6 
   7 /*
   8  */
   9 
  10 #include <linux/debugfs.h>
  11 #include <linux/module.h>
  12 #include <linux/seq_file.h>
  13 #include <linux/spinlock.h>
  14 #include <linux/uaccess.h>
  15 #include "hid-wiimote.h"
  16 
  17 struct wiimote_debug {
  18         struct wiimote_data *wdata;
  19         struct dentry *eeprom;
  20         struct dentry *drm;
  21 };
  22 
  23 static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s,
  24                                                                 loff_t *off)
  25 {
  26         struct wiimote_debug *dbg = f->private_data;
  27         struct wiimote_data *wdata = dbg->wdata;
  28         unsigned long flags;
  29         ssize_t ret;
  30         char buf[16];
  31         __u16 size = 0;
  32 
  33         if (s == 0)
  34                 return -EINVAL;
  35         if (*off > 0xffffff)
  36                 return 0;
  37         if (s > 16)
  38                 s = 16;
  39 
  40         ret = wiimote_cmd_acquire(wdata);
  41         if (ret)
  42                 return ret;
  43 
  44         spin_lock_irqsave(&wdata->state.lock, flags);
  45         wdata->state.cmd_read_size = s;
  46         wdata->state.cmd_read_buf = buf;
  47         wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, *off & 0xffff);
  48         wiiproto_req_reeprom(wdata, *off, s);
  49         spin_unlock_irqrestore(&wdata->state.lock, flags);
  50 
  51         ret = wiimote_cmd_wait(wdata);
  52         if (!ret)
  53                 size = wdata->state.cmd_read_size;
  54 
  55         spin_lock_irqsave(&wdata->state.lock, flags);
  56         wdata->state.cmd_read_buf = NULL;
  57         spin_unlock_irqrestore(&wdata->state.lock, flags);
  58 
  59         wiimote_cmd_release(wdata);
  60 
  61         if (ret)
  62                 return ret;
  63         else if (size == 0)
  64                 return -EIO;
  65 
  66         if (copy_to_user(u, buf, size))
  67                 return -EFAULT;
  68 
  69         *off += size;
  70         ret = size;
  71 
  72         return ret;
  73 }
  74 
  75 static const struct file_operations wiidebug_eeprom_fops = {
  76         .owner = THIS_MODULE,
  77         .open = simple_open,
  78         .read = wiidebug_eeprom_read,
  79         .llseek = generic_file_llseek,
  80 };
  81 
  82 static const char *wiidebug_drmmap[] = {
  83         [WIIPROTO_REQ_NULL] = "NULL",
  84         [WIIPROTO_REQ_DRM_K] = "K",
  85         [WIIPROTO_REQ_DRM_KA] = "KA",
  86         [WIIPROTO_REQ_DRM_KE] = "KE",
  87         [WIIPROTO_REQ_DRM_KAI] = "KAI",
  88         [WIIPROTO_REQ_DRM_KEE] = "KEE",
  89         [WIIPROTO_REQ_DRM_KAE] = "KAE",
  90         [WIIPROTO_REQ_DRM_KIE] = "KIE",
  91         [WIIPROTO_REQ_DRM_KAIE] = "KAIE",
  92         [WIIPROTO_REQ_DRM_E] = "E",
  93         [WIIPROTO_REQ_DRM_SKAI1] = "SKAI1",
  94         [WIIPROTO_REQ_DRM_SKAI2] = "SKAI2",
  95         [WIIPROTO_REQ_MAX] = NULL
  96 };
  97 
  98 static int wiidebug_drm_show(struct seq_file *f, void *p)
  99 {
 100         struct wiimote_debug *dbg = f->private;
 101         const char *str = NULL;
 102         unsigned long flags;
 103         __u8 drm;
 104 
 105         spin_lock_irqsave(&dbg->wdata->state.lock, flags);
 106         drm = dbg->wdata->state.drm;
 107         spin_unlock_irqrestore(&dbg->wdata->state.lock, flags);
 108 
 109         if (drm < WIIPROTO_REQ_MAX)
 110                 str = wiidebug_drmmap[drm];
 111         if (!str)
 112                 str = "unknown";
 113 
 114         seq_printf(f, "%s\n", str);
 115 
 116         return 0;
 117 }
 118 
 119 static int wiidebug_drm_open(struct inode *i, struct file *f)
 120 {
 121         return single_open(f, wiidebug_drm_show, i->i_private);
 122 }
 123 
 124 static ssize_t wiidebug_drm_write(struct file *f, const char __user *u,
 125                                                         size_t s, loff_t *off)
 126 {
 127         struct seq_file *sf = f->private_data;
 128         struct wiimote_debug *dbg = sf->private;
 129         unsigned long flags;
 130         char buf[16];
 131         ssize_t len;
 132         int i;
 133 
 134         if (s == 0)
 135                 return -EINVAL;
 136 
 137         len = min((size_t) 15, s);
 138         if (copy_from_user(buf, u, len))
 139                 return -EFAULT;
 140 
 141         buf[len] = 0;
 142 
 143         for (i = 0; i < WIIPROTO_REQ_MAX; ++i) {
 144                 if (!wiidebug_drmmap[i])
 145                         continue;
 146                 if (!strcasecmp(buf, wiidebug_drmmap[i]))
 147                         break;
 148         }
 149 
 150         if (i == WIIPROTO_REQ_MAX)
 151                 i = simple_strtoul(buf, NULL, 16);
 152 
 153         spin_lock_irqsave(&dbg->wdata->state.lock, flags);
 154         dbg->wdata->state.flags &= ~WIIPROTO_FLAG_DRM_LOCKED;
 155         wiiproto_req_drm(dbg->wdata, (__u8) i);
 156         if (i != WIIPROTO_REQ_NULL)
 157                 dbg->wdata->state.flags |= WIIPROTO_FLAG_DRM_LOCKED;
 158         spin_unlock_irqrestore(&dbg->wdata->state.lock, flags);
 159 
 160         return len;
 161 }
 162 
 163 static const struct file_operations wiidebug_drm_fops = {
 164         .owner = THIS_MODULE,
 165         .open = wiidebug_drm_open,
 166         .read = seq_read,
 167         .llseek = seq_lseek,
 168         .write = wiidebug_drm_write,
 169         .release = single_release,
 170 };
 171 
 172 int wiidebug_init(struct wiimote_data *wdata)
 173 {
 174         struct wiimote_debug *dbg;
 175         unsigned long flags;
 176         int ret = -ENOMEM;
 177 
 178         dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
 179         if (!dbg)
 180                 return -ENOMEM;
 181 
 182         dbg->wdata = wdata;
 183 
 184         dbg->eeprom = debugfs_create_file("eeprom", S_IRUSR,
 185                 dbg->wdata->hdev->debug_dir, dbg, &wiidebug_eeprom_fops);
 186         if (!dbg->eeprom)
 187                 goto err;
 188 
 189         dbg->drm = debugfs_create_file("drm", S_IRUSR,
 190                         dbg->wdata->hdev->debug_dir, dbg, &wiidebug_drm_fops);
 191         if (!dbg->drm)
 192                 goto err_drm;
 193 
 194         spin_lock_irqsave(&wdata->state.lock, flags);
 195         wdata->debug = dbg;
 196         spin_unlock_irqrestore(&wdata->state.lock, flags);
 197 
 198         return 0;
 199 
 200 err_drm:
 201         debugfs_remove(dbg->eeprom);
 202 err:
 203         kfree(dbg);
 204         return ret;
 205 }
 206 
 207 void wiidebug_deinit(struct wiimote_data *wdata)
 208 {
 209         struct wiimote_debug *dbg = wdata->debug;
 210         unsigned long flags;
 211 
 212         if (!dbg)
 213                 return;
 214 
 215         spin_lock_irqsave(&wdata->state.lock, flags);
 216         wdata->debug = NULL;
 217         spin_unlock_irqrestore(&wdata->state.lock, flags);
 218 
 219         debugfs_remove(dbg->drm);
 220         debugfs_remove(dbg->eeprom);
 221         kfree(dbg);
 222 }

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