All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Herrmann <dh.herrmann@googlemail.com>
To: linux-input@vger.kernel.org
Cc: jkosina@suse.cz, padovan@profusion.mobi, dh.herrmann@googlemail.com
Subject: [PATCH 16/16] HID: wiimote: Allow EEPROM debugfs access
Date: Thu, 28 Jul 2011 18:08:36 +0200	[thread overview]
Message-ID: <1311869316-17128-17-git-send-email-dh.herrmann@googlemail.com> (raw)
In-Reply-To: <1311869316-17128-1-git-send-email-dh.herrmann@googlemail.com>

Add "eeprom" file to debugfs for every wiimote. Reading from this file allows to
read the internal EEPROM of a wiimote. Writing to eeprom is currently not
allowed and eeprom memory hasn't been reverse-engineered, yet.

This file shall only be used for debugging. Reading large blocks from this file
may block other access to the wiimote, hence, each block has been limited to 16
bytes to avoid large memory transfers while holding the wiimote lock.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
 drivers/hid/hid-wiimote.c |  131 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index 64200e5..56cdb3b 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -12,12 +12,14 @@
 
 #include <linux/atomic.h>
 #include <linux/completion.h>
+#include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
+#include <linux/uaccess.h>
 #include "hid-ids.h"
 
 #define WIIMOTE_VERSION "0.1"
@@ -43,6 +45,8 @@ struct wiimote_state {
 	/* results of synchronous requests */
 	__u8 cmd_battery;
 	__u8 cmd_err;
+	__u8 *cmd_read_buf;
+	__u8 cmd_read_size;
 };
 
 struct wiimote_data {
@@ -57,6 +61,10 @@ struct wiimote_data {
 	struct work_struct worker;
 
 	struct wiimote_state state;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debug_eeprom;
+#endif
 };
 
 #define WIIPROTO_FLAG_LED1		0x01
@@ -815,6 +823,110 @@ static ssize_t wiifs_ir_set(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(ir, S_IRUGO | S_IWUSR, wiifs_ir_show, wiifs_ir_set);
 
+#ifdef CONFIG_DEBUG_FS
+
+static int wiifs_eeprom_open(struct inode *i, struct file *f)
+{
+	f->private_data = i->i_private;
+	return 0;
+}
+
+static ssize_t wiifs_eeprom_read(struct file *f, char __user *u, size_t s,
+								loff_t *off)
+{
+	struct wiimote_data *wdata = f->private_data;
+	unsigned long flags;
+	ssize_t ret;
+	char *buf;
+	__u16 size;
+
+	if (s == 0)
+		return -EINVAL;
+	if (*off > 0xffffff)
+		return 0;
+	if (s > 16)
+		s = 16;
+
+	if (!atomic_read(&wdata->ready))
+		return -EBUSY;
+	/* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
+	smp_rmb();
+
+	buf = kmalloc(s, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = wiimote_cmd_acquire(wdata);
+	if (ret)
+		goto error;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.cmd_read_size = s;
+	wdata->state.cmd_read_buf = buf;
+	wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, *off & 0xffff);
+	wiiproto_req_reeprom(wdata, *off, s);
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	ret = wiimote_cmd_wait(wdata);
+	if (!ret)
+		size = wdata->state.cmd_read_size;
+
+	spin_lock_irqsave(&wdata->state.lock, flags);
+	wdata->state.cmd_read_buf = NULL;
+	spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+	wiimote_cmd_release(wdata);
+
+	if (ret)
+		goto error;
+	if (size == 0) {
+		ret = -EIO;
+		goto error;
+	}
+	if (copy_to_user(u, buf, size)) {
+		ret = -EFAULT;
+		goto error;
+	}
+
+	*off += size;
+	ret = size;
+
+error:
+	kfree(buf);
+	return ret;
+}
+
+static const struct file_operations wiifs_eeprom_fops = {
+	.owner = THIS_MODULE,
+	.open = wiifs_eeprom_open,
+	.read = wiifs_eeprom_read,
+	.llseek = generic_file_llseek,
+};
+
+static void wiimote_debugfs_init(struct wiimote_data *wdata)
+{
+	wdata->debug_eeprom = debugfs_create_file("eeprom", S_IRUSR,
+			wdata->hdev->debug_dir, wdata, &wiifs_eeprom_fops);
+}
+
+static void wiimote_debugfs_deinit(struct wiimote_data *wdata)
+{
+	if (wdata->debug_eeprom)
+		debugfs_remove(wdata->debug_eeprom);
+}
+
+#else /* CONFIG_DEBUG_FS */
+
+static void wiimote_debugfs_init(void *s)
+{
+}
+
+static void wiimote_debugfs_deinit(void *s)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
 static int wiimote_input_event(struct input_dev *dev, unsigned int type,
 						unsigned int code, int value)
 {
@@ -929,7 +1041,23 @@ static void handler_status(struct wiimote_data *wdata, const __u8 *payload)
 
 static void handler_data(struct wiimote_data *wdata, const __u8 *payload)
 {
+	__u16 offset = payload[3] << 8 | payload[4];
+	__u8 size = (payload[2] >> 4) + 1;
+	__u8 err = payload[2] & 0x0f;
+
 	handler_keys(wdata, payload);
+
+	if (wiimote_cmd_pending(wdata, WIIPROTO_REQ_RMEM, offset)) {
+		if (err)
+			size = 0;
+		else if (size > wdata->state.cmd_read_size)
+			size = wdata->state.cmd_read_size;
+
+		wdata->state.cmd_read_size = size;
+		if (wdata->state.cmd_read_buf)
+			memcpy(wdata->state.cmd_read_buf, &payload[5], size);
+		wiimote_cmd_complete(wdata);
+	}
 }
 
 static void handler_return(struct wiimote_data *wdata, const __u8 *payload)
@@ -1222,6 +1350,8 @@ static int wiimote_hid_probe(struct hid_device *hdev,
 		goto err_stop;
 	}
 
+	wiimote_debugfs_init(wdata);
+
 	/* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */
 	smp_wmb();
 	atomic_set(&wdata->ready, 1);
@@ -1256,6 +1386,7 @@ static void wiimote_hid_remove(struct hid_device *hdev)
 
 	hid_info(hdev, "Device removed\n");
 
+	wiimote_debugfs_deinit(wdata);
 	device_remove_file(&hdev->dev, &dev_attr_led1);
 	device_remove_file(&hdev->dev, &dev_attr_led2);
 	device_remove_file(&hdev->dev, &dev_attr_led3);
-- 
1.7.6


      parent reply	other threads:[~2011-07-28 16:09 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-28 16:08 [PATCH 00/16] Extended wiimote support David Herrmann
2011-07-28 16:08 ` [PATCH 01/16] HID: wiimote: Support rumble device David Herrmann
2011-07-28 16:08 ` [PATCH 02/16] HID: wiimote: Add sysfs rumble attribute David Herrmann
2011-07-28 16:08 ` [PATCH 03/16] HID: wiimote: Add drm request David Herrmann
2011-07-28 18:05   ` Oliver Neukum
2011-07-28 18:41     ` David Herrmann
2011-07-28 18:47       ` Oliver Neukum
2011-07-28 16:08 ` [PATCH 04/16] HID: wiimote: Add status and return request handlers David Herrmann
2011-07-28 16:08 ` [PATCH 05/16] HID: wiimote: Reduce input syncs David Herrmann
2011-07-28 16:08 ` [PATCH 06/16] HID: wiimote: Enable accelerometer on request David Herrmann
2011-07-28 18:08   ` Oliver Neukum
2011-07-28 19:01     ` David Herrmann
2011-07-28 19:32       ` Oliver Neukum
2011-07-28 16:08 ` [PATCH 07/16] HID: wiimote: Parse accelerometer data David Herrmann
2011-07-28 18:12   ` Oliver Neukum
2011-07-28 18:51     ` David Herrmann
2011-08-10 11:55       ` Jiri Kosina
2011-07-28 16:08 ` [PATCH 08/16] HID: wiimote: Parse IR input and report to userspace David Herrmann
2011-07-28 16:08 ` [PATCH 09/16] HID: wiimote: Add missing extension DRM handlers David Herrmann
2011-07-28 16:08 ` [PATCH 10/16] HID: wiimote: Add register/eeprom memory support David Herrmann
2011-07-28 16:08 ` [PATCH 11/16] HID: wiimote: Helper functions for synchronous requests David Herrmann
2011-07-28 16:08 ` [PATCH 12/16] HID: wiimote: Add write-register helpers David Herrmann
2011-07-28 16:08 ` [PATCH 13/16] HID: wiimote: Add IR initializer David Herrmann
2011-07-28 16:08 ` [PATCH 14/16] HID: wiimote: Allow userspace to control IR cam David Herrmann
2011-07-28 16:08 ` [PATCH 15/16] HID: wiimote: Read wiimote battery charge level David Herrmann
2011-07-28 16:08 ` David Herrmann [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1311869316-17128-17-git-send-email-dh.herrmann@googlemail.com \
    --to=dh.herrmann@googlemail.com \
    --cc=jkosina@suse.cz \
    --cc=linux-input@vger.kernel.org \
    --cc=padovan@profusion.mobi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.