mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Nick Crews <ncrews@google.com>
To: linux-kernel@vger.kernel.org
Cc: Duncan Laurie <dlaurie@google.com>,
	Nick Crews <ncrews@google.com>, Olof Johansson <olof@lixom.net>,
	Benson Leung <bleung@chromium.org>
Subject: [RFC PATCH 04/10] CHROMIUM: wilco_ec: Add support for raw commands in sysfs
Date: Fri, 14 Dec 2018 17:18:37 -0700	[thread overview]
Message-ID: <20181215001843.62404-5-ncrews@google.com> (raw)
In-Reply-To: <20181215001843.62404-1-ncrews@google.com>

From: Duncan Laurie <dlaurie@google.com>

Add a sysfs attribute that allows sending raw commands to the EC.
This is useful for development and debug but should not be enabled
in a production environment.

> echo 00 f0 38 00 03 00 > /sys/bus/platform/devices/GOOG000C\:00/raw
> cat /sys/bus/platform/devices/GOOG000C\:00/raw
00 37 33 38 65 64 00...

Signed-off-by: Duncan Laurie <dlaurie@google.com>
Signed-off-by: Nick Crews <ncrews@google.com>
---

 drivers/platform/chrome/Kconfig            |  10 ++
 drivers/platform/chrome/wilco_ec.h         |   6 +
 drivers/platform/chrome/wilco_ec_mailbox.c |   6 -
 drivers/platform/chrome/wilco_ec_sysfs.c   | 126 +++++++++++++++++++++
 4 files changed, 142 insertions(+), 6 deletions(-)

diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 4168d5e6bedc..05c6d9a00395 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -61,6 +61,16 @@ config WILCO_EC
 	  To compile this driver as a module, choose M here: the
 	  module will be called wilco_ec.
 
+config WILCO_EC_SYSFS_RAW
+	bool "Enable raw access to EC via sysfs"
+	depends on WILCO_EC
+	default n
+	help
+	  If you say Y here, you get support for sending raw commands to
+	  the Wilco EC via sysfs.  These commands do not do any byte
+	  manipulation and allow for testing arbitrary commands.  This
+	  interface is intended for debug only and is disabled by default.
+
 config CROS_EC_CTL
         tristate
 
diff --git a/drivers/platform/chrome/wilco_ec.h b/drivers/platform/chrome/wilco_ec.h
index 699f4cf744dc..0b3dec4e2830 100644
--- a/drivers/platform/chrome/wilco_ec.h
+++ b/drivers/platform/chrome/wilco_ec.h
@@ -20,6 +20,12 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 
+/* Normal commands have a maximum 32 bytes of data */
+#define EC_MAILBOX_DATA_SIZE		32
+
+/* Extended commands have 256 bytes of response data */
+#define EC_MAILBOX_DATA_SIZE_EXTENDED	256
+
 #define WILCO_EC_FLAG_NO_RESPONSE	BIT(0) /* EC does not respond */
 #define WILCO_EC_FLAG_EXTENDED_DATA	BIT(1) /* EC returns 256 data bytes */
 #define WILCO_EC_FLAG_RAW_REQUEST	BIT(2) /* Do not trim request data */
diff --git a/drivers/platform/chrome/wilco_ec_mailbox.c b/drivers/platform/chrome/wilco_ec_mailbox.c
index 414ea0a8ad03..1cb34b7280fd 100644
--- a/drivers/platform/chrome/wilco_ec_mailbox.c
+++ b/drivers/platform/chrome/wilco_ec_mailbox.c
@@ -44,12 +44,6 @@
 /* Version of EC protocol */
 #define EC_MAILBOX_PROTO_VERSION	3
 
-/* Normal commands have a maximum 32 bytes of data */
-#define EC_MAILBOX_DATA_SIZE		32
-
-/* Extended commands have 256 bytes of response data */
-#define EC_MAILBOX_DATA_SIZE_EXTENDED	256
-
 /* Number of header bytes to be counted as data bytes */
 #define EC_MAILBOX_DATA_EXTRA		2
 
diff --git a/drivers/platform/chrome/wilco_ec_sysfs.c b/drivers/platform/chrome/wilco_ec_sysfs.c
index f9ae6cef6169..eeebd4ba4a39 100644
--- a/drivers/platform/chrome/wilco_ec_sysfs.c
+++ b/drivers/platform/chrome/wilco_ec_sysfs.c
@@ -23,6 +23,126 @@
 #define EC_INFO_SIZE			 9
 #define EC_COMMAND_STEALTH_MODE		0xfc
 
+#ifdef CONFIG_WILCO_EC_SYSFS_RAW
+
+/* Raw data buffer, large enough to hold extended responses */
+static size_t raw_response_size;
+static u8 raw_response_data[EC_MAILBOX_DATA_SIZE_EXTENDED];
+
+/*
+ * raw: write a raw command and return the result
+ *
+ * Bytes 0-1 indicate the message type:
+ *  00 F0 = Execute Legacy Command
+ *  00 F2 = Read/Write NVRAM Property
+ * Byte 2 provides the command code
+ * Bytes 3+ consist of the data passed in the request
+ *
+ * example: read the EC info type 1:
+ *  # echo 00 f0 38 00 01 00 > raw
+ *  # cat raw
+ *  00 38 31 34 34 66 00 00 00 00 00 00 00 00 00 00 00...
+ */
+
+static ssize_t raw_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	ssize_t count = 0;
+
+	if (raw_response_size) {
+		int i;
+
+		for (i = 0; i < raw_response_size; ++i)
+			count += scnprintf(buf + count, PAGE_SIZE - count,
+					   "%02x ", raw_response_data[i]);
+
+		count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
+
+		/* Only return response the first time it is read */
+		raw_response_size = 0;
+	}
+
+	return count;
+}
+
+static ssize_t raw_store(struct device *dev,
+			 struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct wilco_ec_device *ec = dev_get_drvdata(dev);
+	struct wilco_ec_message msg;
+	u8 raw_request_data[EC_MAILBOX_DATA_SIZE];
+	int in_offset = 0;
+	int out_offset = 0;
+	int ret;
+
+	while (in_offset < count) {
+		char word_buf[EC_MAILBOX_DATA_SIZE];
+		u8 byte;
+		int start_offset = in_offset;
+		int end_offset;
+
+		/* Find the start of the byte */
+		while (buf[start_offset] && isspace(buf[start_offset]))
+			start_offset++;
+		if (!buf[start_offset])
+			break;
+
+		/* Find the start of the next byte, if any */
+		end_offset = start_offset;
+		while (buf[end_offset] && !isspace(buf[end_offset]))
+			end_offset++;
+		if (start_offset > count || end_offset > count)
+			break;
+		if (start_offset > EC_MAILBOX_DATA_SIZE ||
+		    end_offset > EC_MAILBOX_DATA_SIZE)
+			break;
+
+		/* Copy to a new nul-terminated string */
+		memcpy(word_buf, buf + start_offset, end_offset - start_offset);
+		word_buf[end_offset - start_offset] = '\0';
+
+		/* Convert from hex string */
+		ret = kstrtou8(word_buf, 16, &byte);
+		if (ret)
+			break;
+
+		/* Fill this byte into the request buffer */
+		raw_request_data[out_offset++] = byte;
+		if (out_offset >= EC_MAILBOX_DATA_SIZE)
+			break;
+
+		in_offset = end_offset;
+	}
+	if (out_offset == 0)
+		return -EINVAL;
+
+	/* Clear response data buffer */
+	memset(raw_response_data, 0, EC_MAILBOX_DATA_SIZE_EXTENDED);
+
+	msg.type = raw_request_data[0] << 8 | raw_request_data[1];
+	msg.flags = WILCO_EC_FLAG_RAW;
+	msg.command = raw_request_data[2];
+	msg.request_data = raw_request_data + 3;
+	msg.request_size = out_offset - 3;
+	msg.response_data = raw_response_data;
+	msg.response_size = EC_MAILBOX_DATA_SIZE;
+
+	/* Telemetry commands use extended response data */
+	if (msg.type == WILCO_EC_MSG_TELEMETRY) {
+		msg.flags |= WILCO_EC_FLAG_EXTENDED_DATA;
+		msg.response_size = EC_MAILBOX_DATA_SIZE_EXTENDED;
+	}
+
+	ret = wilco_ec_mailbox(ec, &msg);
+	if (ret < 0)
+		return ret;
+	raw_response_size = ret;
+	return count;
+}
+
+#endif /* CONFIG_WILCO_EC_SYSFS_RAW */
+
 struct ec_info {
 	u8 index;
 	const char *label;
@@ -102,10 +222,16 @@ static ssize_t stealth_mode_store(struct device *dev,
 
 static DEVICE_ATTR_RO(version);
 static DEVICE_ATTR_WO(stealth_mode);
+#ifdef CONFIG_WILCO_EC_SYSFS_RAW
+static DEVICE_ATTR_RW(raw);
+#endif
 
 static struct attribute *wilco_ec_attrs[] = {
 	&dev_attr_version.attr,
 	&dev_attr_stealth_mode.attr,
+#ifdef CONFIG_WILCO_EC_SYSFS_RAW
+	&dev_attr_raw.attr,
+#endif
 	NULL
 };
 ATTRIBUTE_GROUPS(wilco_ec);
-- 
2.20.0.405.gbc1bbc6f85-goog


  parent reply	other threads:[~2018-12-15  0:19 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-15  0:18 [RFC PATCH 00/10] cros_ec: Add support for Wilco EC Nick Crews
2018-12-15  0:18 ` [RFC PATCH 01/10] CHROMIUM: cros_ec: Remove cros_ec dependency in lpc_mec Nick Crews
2018-12-17 15:50   ` Enric Balletbo Serra
2018-12-15  0:18 ` [RFC PATCH 02/10] CHROMIUM: wilco_ec: Add new driver for Wilco EC Nick Crews
2018-12-17 15:50   ` Enric Balletbo Serra
2018-12-15  0:18 ` [RFC PATCH 03/10] CHROMIUM: wilco_ec: Add sysfs attributes Nick Crews
2018-12-17 16:45   ` Enric Balletbo Serra
2018-12-17 18:12     ` Guenter Roeck
2018-12-15  0:18 ` Nick Crews [this message]
2018-12-15  0:18 ` [RFC PATCH 05/10] CHROMIUM: wilco_ec: Add RTC class driver Nick Crews
2018-12-15  0:18 ` [RFC PATCH 06/10] CHROMIUM: wilco_ec: Add event handling Nick Crews
2018-12-15  0:18 ` [RFC PATCH 07/10] CHROMIUM: wilco_ec: Move legacy attributes to separate file Nick Crews
2018-12-15  0:18 ` [RFC PATCH 08/10] CHROMIUM: wilco_ec: Add EC properties Nick Crews
2018-12-15  0:18 ` [RFC PATCH 09/10] CHROMIUM: wilco_ec: Add peakshift and adv_batt_charging Nick Crews
2018-12-15  0:18 ` [RFC PATCH 10/10] CHROMIUM: wilco_ec: Add binary telemetry attributes Nick Crews
2018-12-17 16:15 ` [RFC PATCH 00/10] cros_ec: Add support for Wilco EC Enric Balletbo Serra

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=20181215001843.62404-5-ncrews@google.com \
    --to=ncrews@google.com \
    --cc=bleung@chromium.org \
    --cc=dlaurie@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=olof@lixom.net \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®