[coreboot-gerrit] New patch to review for coreboot: 09522a6 chromeec: allow transport implementation to provide buffers for proto v3

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Mar 20 16:21:10 CET 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8827

-gerrit

commit 09522a6788d103c29a5c7200a81fa7e73ef0b5d8
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Wed Aug 6 14:34:57 2014 -0500

    chromeec: allow transport implementation to provide buffers for proto v3
    
    Depending on the transport mechanism for proto v3 different bytes
    need to be send and/or read before the request and response. Depending
    on the software and/or controller interface that requirement leads to
    needing to copy data into temporary buffers.  Avoid this by allowing
    the transport mechanism to provide the request and response
    buffers.
    
    BUG=chrome-os-partner:31148
    BRANCH=None
    TEST=Built for rush and ryu. Ran on ryu with i2c implementation.
         Also built for rambi to check x86 systems.
    
    Change-Id: I35d4d69bd1fa900fc0cfe3822496f381405bdcb1
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: c7224426e1d0bcf06ed010131a2462a6ca201d8b
    Original-Change-Id: Iad6cce566a253ca72e6f5009a97235ece0a6c1b5
    Original-Signed-off-by: Aaron Durbin <adurbin at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/211138
    Original-Reviewed-by: Furquan Shaikh <furquan at chromium.org>
---
 src/ec/google/chromeec/crosec_proto.c | 23 ++++++++++++++++-------
 src/ec/google/chromeec/ec.h           | 21 +++++++++++++++++----
 src/ec/google/chromeec/ec_spi.c       | 27 ++++++++++++++++++++++-----
 3 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/src/ec/google/chromeec/crosec_proto.c b/src/ec/google/chromeec/crosec_proto.c
index 42c7c2e..55a707d 100644
--- a/src/ec/google/chromeec/crosec_proto.c
+++ b/src/ec/google/chromeec/crosec_proto.c
@@ -27,6 +27,11 @@
 #include "ec_message.h"
 
 /* Common utilities */
+void * __attribute__((weak)) crosec_get_buffer(size_t size, int req)
+{
+	printk(BIOS_DEBUG, "crosec_get_buffer() implementation required.\n");
+	return NULL;
+}
 
 /* Dumps EC command / response data into debug output.
  *
@@ -208,23 +213,27 @@ static int send_command_proto3(struct chromeec_command *cec_command,
 {
 	int out_bytes, in_bytes;
 	int rv;
-	struct ec_command_v3 cmd = { {0}, };
-	struct ec_response_v3 resp = { {0}, };
+	struct ec_command_v3 *cmd;
+	struct ec_response_v3 *resp;
+
+	if ((cmd = crosec_get_buffer(sizeof(*cmd), 1)) == NULL)
+		return -EC_RES_ERROR;
+	if ((resp = crosec_get_buffer(sizeof(*resp), 0)) == NULL)
+		return -EC_RES_ERROR;
 
 	/* Create request packet */
-	out_bytes = create_proto3_request(cec_command, &cmd);
+	out_bytes = create_proto3_request(cec_command, cmd);
 	if (out_bytes < 0) {
 		return out_bytes;
 	}
 
 	/* Prepare response buffer */
-	in_bytes = prepare_proto3_response_buffer(cec_command, &resp);
+	in_bytes = prepare_proto3_response_buffer(cec_command, resp);
 	if (in_bytes < 0) {
 		return in_bytes;
 	}
 
-	rv = crosec_io((uint8_t *)&cmd, out_bytes, (uint8_t *)&resp, in_bytes,
-		       context);
+	rv = crosec_io(out_bytes, in_bytes, context);
 	if (rv != 0) {
 		printk(BIOS_ERR, "%s: failed to complete I/O: Err = %#x.",
 		       __func__, rv >= 0 ? rv : -rv);
@@ -232,7 +241,7 @@ static int send_command_proto3(struct chromeec_command *cec_command,
 	}
 
 	/* Process the response */
-	return handle_proto3_response(&resp, cec_command);
+	return handle_proto3_response(resp, cec_command);
 }
 
 static int crosec_command_proto_v3(struct chromeec_command *cec_command,
diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h
index a1c59b8..e0db8c1 100644
--- a/src/ec/google/chromeec/ec.h
+++ b/src/ec/google/chromeec/ec.h
@@ -69,10 +69,23 @@ struct chromeec_command {
 				   * actual received size out */
 };
 
-/* internal standard implementation for EC command protocols. */
-typedef int (*crosec_io_t)(uint8_t *write_bytes, size_t write_size,
-			   uint8_t *read_bytes, size_t read_size,
-			   void *context);
+/*
+ * There are transport level constraints for sending protov3 packets. Because
+ * of this provide a way for the generic protocol layer to request buffers
+ * so that there is zero copying being done through the layers.
+ *
+ * Request the buffer provided the size. If 'req' is non-zero then the
+ * buffer requested is for EC requests. Otherwise it's for responses. Return
+ * non-NULL on success, NULL on error.
+ */
+void *crosec_get_buffer(size_t size, int req);
+
+/*
+ * The lower level transport works on the buffers handed out to the
+ * upper level. Therefore, only the size of the request and response
+ * are required.
+ */
+typedef int (*crosec_io_t)(size_t req_size, size_t resp_size, void *context);
 int crosec_command_proto(struct chromeec_command *cec_command,
 			 crosec_io_t crosec_io, void *context);
 
diff --git a/src/ec/google/chromeec/ec_spi.c b/src/ec/google/chromeec/ec_spi.c
index f1bdd3c..6107836 100644
--- a/src/ec/google/chromeec/ec_spi.c
+++ b/src/ec/google/chromeec/ec_spi.c
@@ -25,15 +25,32 @@
 
 static const uint8_t EcFramingByte = 0xec;
 
-static int crosec_spi_io(uint8_t *write_bytes, size_t write_size,
-			 uint8_t *read_bytes, size_t read_size,
-			 void *context)
+#define PROTO3_MAX_PACKET_SIZE 268
+
+static uint8_t req_buf[PROTO3_MAX_PACKET_SIZE];
+static uint8_t resp_buf[PROTO3_MAX_PACKET_SIZE];
+
+void *crosec_get_buffer(size_t size, int req)
+{
+	if (size > PROTO3_MAX_PACKET_SIZE) {
+		printk(BIOS_DEBUG, "Proto v3 buffer request too large: %zu!\n",
+			size);
+		return NULL;
+	}
+
+	if (req)
+		return req_buf;
+	else
+		return resp_buf;
+}
+
+static int crosec_spi_io(size_t req_size, size_t resp_size, void *context)
 {
 	struct spi_slave *slave = (struct spi_slave *)context;
 
 	spi_claim_bus(slave);
 
-	if (spi_xfer(slave, write_bytes, write_size, NULL, 0)) {
+	if (spi_xfer(slave, req_buf, req_size, NULL, 0)) {
 		printk(BIOS_ERR, "%s: Failed to send request.\n", __func__);
 		spi_release_bus(slave);
 		return -1;
@@ -64,7 +81,7 @@ static int crosec_spi_io(uint8_t *write_bytes, size_t write_size,
 		}
 	}
 
-	if (spi_xfer(slave, NULL, 0, read_bytes, read_size)) {
+	if (spi_xfer(slave, NULL, 0, resp_buf, resp_size)) {
 		printk(BIOS_ERR, "%s: Failed to receive response.\n", __func__);
 		spi_release_bus(slave);
 		return -1;



More information about the coreboot-gerrit mailing list