summaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/operation.c
diff options
context:
space:
mode:
authorAlex Elder2014-11-20 23:09:13 +0100
committerGreg Kroah-Hartman2014-11-21 21:23:34 +0100
commit8b337308e7ff71cd6ae6d9c04260f8ada6e98c9e (patch)
tree947fb6966f46b3e3f8fa5aa3966e0c0695f81f3e /drivers/staging/greybus/operation.c
parentgreybus: complete overflow responses (diff)
downloadkernel-qcow2-linux-8b337308e7ff71cd6ae6d9c04260f8ada6e98c9e.tar.gz
kernel-qcow2-linux-8b337308e7ff71cd6ae6d9c04260f8ada6e98c9e.tar.xz
kernel-qcow2-linux-8b337308e7ff71cd6ae6d9c04260f8ada6e98c9e.zip
greybus: have greybus allocate its own buffers
Rather than having the host driver allocate the buffers that the Greybus core uses to hold its data for sending or receiving, have the host driver define what it requires those buffers to look like. Two constraints define what the host driver requires: the maximum number of bytes that the host device can send in a single request; and a statement of the "headroom" that needs to be present for use by the host device. The direct description of the headroom is that it's the extra byte the host device needs at the beginning of the "data" portion of the buffer so the ES1 driver can insert the destination CPort id. But more generally, the host driver could put other data in there as well. By stating these two parameters, Greybus can allocate the buffers it uses by itself. The host driver still allocates the buffers it uses for receiving data--the content of those are copied as needed into Greybus buffers when data arrives. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
Diffstat (limited to 'drivers/staging/greybus/operation.c')
-rw-r--r--drivers/staging/greybus/operation.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c
index d91cd5b4b65a..6c66c264891e 100644
--- a/drivers/staging/greybus/operation.c
+++ b/drivers/staging/greybus/operation.c
@@ -229,6 +229,27 @@ static void operation_timeout(struct work_struct *work)
gb_operation_complete(operation);
}
+static void *
+gb_buffer_alloc(struct greybus_host_device *hd, size_t size, gfp_t gfp_flags)
+{
+ u8 *buffer;
+
+ buffer = kzalloc(hd->buffer_headroom + size, gfp_flags);
+ if (buffer)
+ buffer += hd->buffer_headroom;
+
+ return buffer;
+}
+
+static void
+gb_buffer_free(struct greybus_host_device *hd, void *buffer)
+{
+ u8 *allocated = buffer;
+
+ if (allocated)
+ kfree(allocated - hd->buffer_headroom);
+}
+
/*
* Allocate a buffer to be used for an operation request or response
* message. For outgoing messages, both types of message contain a
@@ -246,9 +267,9 @@ static int gb_operation_message_init(struct gb_operation *operation,
struct gb_message *message;
struct gb_operation_msg_hdr *header;
- if (size > GB_OPERATION_MESSAGE_SIZE_MAX)
- return -E2BIG;
size += sizeof(*header);
+ if (size > hd->buffer_size_max)
+ return -E2BIG;
if (request) {
message = &operation->request;
@@ -257,7 +278,7 @@ static int gb_operation_message_init(struct gb_operation *operation,
type |= GB_OPERATION_TYPE_RESPONSE;
}
- message->buffer = hd->driver->buffer_alloc(size, gfp_flags);
+ message->buffer = gb_buffer_alloc(hd, size, gfp_flags);
if (!message->buffer)
return -ENOMEM;
message->buffer_size = size;
@@ -279,7 +300,7 @@ static void gb_operation_message_exit(struct gb_message *message)
struct greybus_host_device *hd;
hd = message->operation->connection->hd;
- hd->driver->buffer_free(message->buffer);
+ gb_buffer_free(hd, message->buffer);
message->operation = NULL;
message->payload = NULL;