From ac1c2840bd41e89d55fccabe86cf9a3e2d56a652 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 11 May 2015 21:16:39 -0500 Subject: [PATCH] greybus: loopback: support module-initiated requests There's no reason we can't support loopback pings or transfers initiated by the module. Allow it. Signed-off-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/loopback.c | 44 +++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index decaf71fb6e4..285e44b9431f 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -242,6 +242,48 @@ static int gb_loopback_ping(struct gb_loopback *gb, struct timeval *tping) return retval; } +static int gb_loopback_request_recv(u8 type, struct gb_operation *operation) +{ + struct gb_connection *connection = operation->connection; + struct gb_loopback_transfer_request *request; + struct gb_loopback_transfer_response *response; + u32 len; + + /* By convention, the AP initiates the version operation */ + switch (type) { + case GB_LOOPBACK_TYPE_PROTOCOL_VERSION: + dev_err(&connection->dev, + "module-initiated version operation\n"); + return -EINVAL; + case GB_LOOPBACK_TYPE_PING: + return 0; + case GB_LOOPBACK_TYPE_TRANSFER: + if (operation->request->payload_size < sizeof(*request)) { + dev_err(&connection->dev, + "transfer request too small (%zu < %zu)\n", + operation->request->payload_size, + sizeof(*request)); + return -EINVAL; /* -EMSGSIZE */ + } + request = operation->request->payload; + len = le32_to_cpu(request->len); + if (len) { + if (!gb_operation_response_alloc(operation, len)) { + dev_err(&connection->dev, + "error allocating response\n"); + return -ENOMEM; + } + response = operation->response->payload; + memcpy(response->data, request->data, len); + } + return 0; + default: + dev_err(&connection->dev, + "unsupported request: %hhu\n", type); + return -EINVAL; + } +} + static void gb_loopback_reset_stats(struct gb_loopback *gb) { struct gb_loopback_stats reset = { @@ -397,7 +439,7 @@ static struct gb_protocol loopback_protocol = { .minor = GB_LOOPBACK_VERSION_MINOR, .connection_init = gb_loopback_connection_init, .connection_exit = gb_loopback_connection_exit, - .request_recv = NULL, /* no incoming requests */ + .request_recv = gb_loopback_request_recv, }; gb_protocol_driver(&loopback_protocol); -- 2.39.5