From 10aa801d331609c38a58e0c4e73fd31103ffa230 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 24 Nov 2014 11:19:13 -0800 Subject: [PATCH] greybus: operation: create gb_operation_sync for sending "simple" messages Everyone keeps doing the same create/send/destroy logic all over the place, so abstract that out to a simple function that can handle any arbritrary request and/or response. This will let us save lots of duplicated logic in the protocol drivers. Signed-off-by: Greg Kroah-Hartman Reviewed-by: Alex Elder --- drivers/staging/greybus/operation.c | 54 +++++++++++++++++++++++++++++ drivers/staging/greybus/operation.h | 4 +++ 2 files changed, 58 insertions(+) diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 180d02856225..35fcb882bfde 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -624,6 +624,60 @@ void gb_operation_cancel(struct gb_operation *operation, int errno) gb_message_cancel(operation->response); } +/** + * gb_operation_sync: implement a "simple" synchronous gb operation. + * @connection: the Greybus connection to send this to + * @type: the type of operation to send + * @request: pointer to a memory buffer to copy the request from + * @request_size: size of @request + * @response: pointer to a memory buffer to copy the response to + * @response_size: the size of @response. + * + * This function implements a simple synchronous Greybus operation. It sends + * the provided operation request and waits (sleeps) until the corresponding + * operation response message has been successfully received, or an error + * occurs. @request and @response are buffers to hold the request and response + * data respectively, and if they are not NULL, their size must be specified in + * @request_size and @response_size. + * + * If a response payload is to come back, and @response is not NULL, + * @response_size number of bytes will be copied into @response if the operation + * is successful. + * + * If there is an error, the response buffer is left alone. + */ +int gb_operation_sync(struct gb_connection *connection, int type, + void *request, int request_size, + void *response, int response_size) +{ + struct gb_operation *operation; + int ret; + + if ((response_size && !response) || + (request_size && !request)) + return -EINVAL; + + operation = gb_operation_create(connection, type, + request_size, response_size); + if (!operation) + return -ENOMEM; + + if (request_size) + memcpy(&operation->request->payload, request, request_size); + + /* Synchronous operation--no callback */ + ret = gb_operation_request_send(operation, NULL); + if (ret) + pr_err("version operation failed (%d)\n", ret); + else + if (response_size) + memcpy(response, operation->response->payload, + response_size); + gb_operation_destroy(operation); + + return ret; +} + int gb_operation_init(void) { gb_operation_cache = kmem_cache_create("gb_operation_cache", diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h index c391b28a4ca7..bc5c1641e1ac 100644 --- a/drivers/staging/greybus/operation.h +++ b/drivers/staging/greybus/operation.h @@ -105,6 +105,10 @@ int gb_operation_status_map(u8 status); void greybus_data_sent(struct greybus_host_device *hd, void *header, int status); +int gb_operation_sync(struct gb_connection *connection, int type, + void *request, int request_size, + void *response, int response_size); + int gb_operation_init(void); void gb_operation_exit(void); -- 2.39.5