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 <greg@kroah.com> Reviewed-by: Alex Elder <elder@linaro.org>
This commit is contained in:
Родитель
10c6939904
Коммит
10aa801d33
|
@ -624,6 +624,60 @@ void gb_operation_cancel(struct gb_operation *operation, int errno)
|
||||||
gb_message_cancel(operation->response);
|
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)
|
int gb_operation_init(void)
|
||||||
{
|
{
|
||||||
gb_operation_cache = kmem_cache_create("gb_operation_cache",
|
gb_operation_cache = kmem_cache_create("gb_operation_cache",
|
||||||
|
|
|
@ -105,6 +105,10 @@ int gb_operation_status_map(u8 status);
|
||||||
void greybus_data_sent(struct greybus_host_device *hd,
|
void greybus_data_sent(struct greybus_host_device *hd,
|
||||||
void *header, int status);
|
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);
|
int gb_operation_init(void);
|
||||||
void gb_operation_exit(void);
|
void gb_operation_exit(void);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче