Commit c7f82d5d authored by Alex Elder's avatar Alex Elder Committed by Greg Kroah-Hartman

greybus: start using struct gb_message

This converts some of the operation code to start leveraging the
new gb_message type.  Instead of creating the request and response
gbufs, we initialize (and tear down with a new function) the
request and response message structures.
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 3690a826
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
/* /*
* XXX This needs to be coordinated with host driver parameters * XXX This needs to be coordinated with host driver parameters
* XXX May need to reduce to allow for message header within a page
*/ */
#define GB_OPERATION_MESSAGE_SIZE_MAX 4096 #define GB_OPERATION_MESSAGE_SIZE_MAX 4096
...@@ -196,36 +197,56 @@ static void operation_timeout(struct work_struct *work) ...@@ -196,36 +197,56 @@ static void operation_timeout(struct work_struct *work)
* initialize it here (it'll be overwritten by the incoming * initialize it here (it'll be overwritten by the incoming
* message). * message).
*/ */
static struct gbuf *gb_operation_gbuf_create(struct gb_operation *operation, static int gb_operation_message_init(struct gb_operation *operation,
u8 type, size_t size, u8 type, size_t size,
bool data_out) bool request, bool data_out)
{ {
struct gb_connection *connection = operation->connection; struct gb_connection *connection = operation->connection;
struct gb_message *message;
struct gb_operation_msg_hdr *header; struct gb_operation_msg_hdr *header;
struct gbuf *gbuf;
gfp_t gfp_flags = data_out ? GFP_KERNEL : GFP_ATOMIC; gfp_t gfp_flags = data_out ? GFP_KERNEL : GFP_ATOMIC;
u16 dest_cport_id; u16 dest_cport_id;
if (size > GB_OPERATION_MESSAGE_SIZE_MAX) if (size > GB_OPERATION_MESSAGE_SIZE_MAX)
return NULL; /* Message too big */ return -E2BIG;
if (request) {
message = &operation->request;
} else {
message = &operation->response;
type |= GB_OPERATION_TYPE_RESPONSE;
}
if (data_out) if (data_out)
dest_cport_id = connection->interface_cport_id; dest_cport_id = connection->interface_cport_id;
else else
dest_cport_id = CPORT_ID_BAD; dest_cport_id = CPORT_ID_BAD;
if (message->gbuf)
return -EALREADY; /* Sanity check */
size += sizeof(*header); size += sizeof(*header);
gbuf = greybus_alloc_gbuf(connection->hd, dest_cport_id, message->gbuf = greybus_alloc_gbuf(connection->hd, dest_cport_id,
size, gfp_flags); size, gfp_flags);
if (!gbuf) if (!message->gbuf)
return NULL; return -ENOMEM;
/* Fill in the header structure */ /* Fill in the header structure */
header = (struct gb_operation_msg_hdr *)gbuf->transfer_buffer; header = (struct gb_operation_msg_hdr *)message->gbuf->transfer_buffer;
header->size = cpu_to_le16(size); header->size = cpu_to_le16(size);
header->id = 0; /* Filled in when submitted */ header->id = 0; /* Filled in when submitted */
header->type = type; header->type = type;
return gbuf; message->payload = header + 1;
message->operation = operation;
return 0;
}
static void gb_operation_message_exit(struct gb_message *message)
{
message->operation = NULL;
message->payload = NULL;
greybus_free_gbuf(message->gbuf);
message->gbuf = NULL;
} }
/* /*
...@@ -251,32 +272,23 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection, ...@@ -251,32 +272,23 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
struct gb_operation *operation; struct gb_operation *operation;
gfp_t gfp_flags = response_size ? GFP_KERNEL : GFP_ATOMIC; gfp_t gfp_flags = response_size ? GFP_KERNEL : GFP_ATOMIC;
bool outgoing = response_size != 0; bool outgoing = response_size != 0;
int ret;
operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags); operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags);
if (!operation) if (!operation)
return NULL; return NULL;
operation->connection = connection; operation->connection = connection;
operation->request.gbuf = gb_operation_gbuf_create(operation, type, ret = gb_operation_message_init(operation, type, request_size,
request_size, true, outgoing);
outgoing); if (ret)
if (!operation->request.gbuf)
goto err_cache; goto err_cache;
operation->request.operation = operation;
operation->request.payload = operation->request.gbuf->transfer_buffer +
sizeof(struct gb_operation_msg_hdr);
if (outgoing) { if (outgoing) {
type |= GB_OPERATION_TYPE_RESPONSE; ret = gb_operation_message_init(operation, type, response_size,
operation->response.gbuf = gb_operation_gbuf_create(operation, false, false);
type, response_size, if (ret)
false);
if (!operation->response.gbuf)
goto err_request; goto err_request;
operation->response.operation = operation;
operation->response.payload =
operation->response.gbuf->transfer_buffer +
sizeof(struct gb_operation_msg_hdr);
} }
INIT_WORK(&operation->recv_work, gb_operation_recv_work); INIT_WORK(&operation->recv_work, gb_operation_recv_work);
...@@ -292,7 +304,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection, ...@@ -292,7 +304,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
return operation; return operation;
err_request: err_request:
greybus_free_gbuf(operation->request.gbuf); gb_operation_message_exit(&operation->request);
err_cache: err_cache:
kmem_cache_free(gb_operation_cache, operation); kmem_cache_free(gb_operation_cache, operation);
...@@ -313,8 +325,8 @@ static void _gb_operation_destroy(struct kref *kref) ...@@ -313,8 +325,8 @@ static void _gb_operation_destroy(struct kref *kref)
list_del(&operation->links); list_del(&operation->links);
spin_unlock_irq(&gb_operations_lock); spin_unlock_irq(&gb_operations_lock);
greybus_free_gbuf(operation->response.gbuf); gb_operation_message_exit(&operation->response);
greybus_free_gbuf(operation->request.gbuf); gb_operation_message_exit(&operation->request);
kmem_cache_free(gb_operation_cache, operation); kmem_cache_free(gb_operation_cache, operation);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment