diff options
author | Bryan O'Donoghue <bryan.odonoghue@linaro.org> | 2015-09-14 10:48:47 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@google.com> | 2015-09-14 21:38:12 -0700 |
commit | fbb8edbafe1525c4168108a46c1134f5a7cd27c4 (patch) | |
tree | 3b31d00ae862487af849fe1835d28fd02705ec25 | |
parent | 5015115def3ed9907fb018180be969cf2f2f116d (diff) |
greybus: loopback: add gb_loopback_operation_sync
In order to extract timestamps from gb_message instead of gb_connection we
will need access to the gb_operation structure. A first step to that is to
create our own gb_loopback_operation_sync which will call
gb_operation_request_send_sync() directly. Once loopback is using this
function internally it will be possible to convert to gb_message based
timestamps and drop gb_connection based timestamps in two seperate patches.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Patrick Titiano <ptitiano@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
-rw-r--r-- | drivers/staging/greybus/loopback.c | 98 |
1 files changed, 52 insertions, 46 deletions
diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index a62e122c2bcc..6155b50b6702 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -380,22 +380,43 @@ static int gb_loopback_active(struct gb_loopback *gb) return (gb_dev.mask == 0 || (gb_dev.mask & gb->lbid)); } -static int gb_loopback_sink(struct gb_loopback *gb, u32 len) +static int gb_loopback_operation_sync(struct gb_loopback *gb, int type, + void *request, int request_size, + void *response, int response_size) { + struct gb_operation *operation; struct timeval ts, te; - struct gb_loopback_transfer_request *request; - int retval; - - request = kmalloc(len + sizeof(*request), GFP_KERNEL); - if (!request) - return -ENOMEM; - - request->len = cpu_to_le32(len); + int ret; do_gettimeofday(&ts); - retval = gb_operation_sync(gb->connection, GB_LOOPBACK_TYPE_SINK, - request, len + sizeof(*request), NULL, 0); + operation = gb_operation_create(gb->connection, type, request_size, + response_size, GFP_KERNEL); + if (!operation) { + ret = -ENOMEM; + goto error; + } + if (request_size) + memcpy(operation->request->payload, request, request_size); + + ret = gb_operation_request_send_sync(operation); + if (ret) { + dev_err(&gb->connection->dev, + "synchronous operation failed: %d\n", ret); + } else { + if (response_size == operation->response->payload_size) { + memcpy(response, operation->response->payload, + response_size); + } else { + dev_err(&gb->connection->dev, + "response size %zu expected %d\n", + operation->response->payload_size, + response_size); + } + } + gb_operation_destroy(operation); + +error: do_gettimeofday(&te); /* Calculate the total time the message took */ @@ -407,14 +428,28 @@ static int gb_loopback_sink(struct gb_loopback *gb, u32 len) gb_connection_pop_timestamp(gb->connection, &te); gb->elapsed_nsecs_gb = gb_loopback_calc_latency(&ts, &te); + return ret; +} + +static int gb_loopback_sink(struct gb_loopback *gb, u32 len) +{ + struct gb_loopback_transfer_request *request; + int retval; + + request = kmalloc(len + sizeof(*request), GFP_KERNEL); + if (!request) + return -ENOMEM; + request->len = cpu_to_le32(len); + retval = gb_loopback_operation_sync(gb, GB_LOOPBACK_TYPE_SINK, + request, len + sizeof(*request), + NULL, 0); kfree(request); return retval; } static int gb_loopback_transfer(struct gb_loopback *gb, u32 len) { - struct timeval ts, te; struct gb_loopback_transfer_request *request; struct gb_loopback_transfer_response *response; int retval; @@ -431,22 +466,9 @@ static int gb_loopback_transfer(struct gb_loopback *gb, u32 len) memset(request->data, 0x5A, len); request->len = cpu_to_le32(len); - - do_gettimeofday(&ts); - retval = gb_operation_sync(gb->connection, GB_LOOPBACK_TYPE_TRANSFER, - request, len + sizeof(*request), - response, len + sizeof(*response)); - do_gettimeofday(&te); - - /* Calculate the total time the message took */ - gb_loopback_push_latency_ts(gb, &ts, &te); - gb->elapsed_nsecs = gb_loopback_calc_latency(&ts, &te); - - /* Calculate non-greybus related component of the latency */ - gb_connection_pop_timestamp(gb->connection, &ts); - gb_connection_pop_timestamp(gb->connection, &te); - gb->elapsed_nsecs_gb = gb_loopback_calc_latency(&ts, &te); - + retval = gb_loopback_operation_sync(gb, GB_LOOPBACK_TYPE_TRANSFER, + request, len + sizeof(*request), + response, len + sizeof(*response)); if (retval) goto gb_error; @@ -464,24 +486,8 @@ gb_error: static int gb_loopback_ping(struct gb_loopback *gb) { - struct timeval ts, te; - int retval; - - do_gettimeofday(&ts); - retval = gb_operation_sync(gb->connection, GB_LOOPBACK_TYPE_PING, - NULL, 0, NULL, 0); - do_gettimeofday(&te); - - /* Calculate the total time the message took */ - gb_loopback_push_latency_ts(gb, &ts, &te); - gb->elapsed_nsecs = gb_loopback_calc_latency(&ts, &te); - - /* Calculate non-greybus related component of the latency */ - gb_connection_pop_timestamp(gb->connection, &ts); - gb_connection_pop_timestamp(gb->connection, &te); - gb->elapsed_nsecs_gb = gb_loopback_calc_latency(&ts, &te); - - return retval; + return gb_loopback_operation_sync(gb, GB_LOOPBACK_TYPE_PING, + NULL, 0, NULL, 0); } static int gb_loopback_request_recv(u8 type, struct gb_operation *operation) |