greybus: operation: add helper functions for unidirectional operations
authorJohan Hovold <johan@hovoldconsulting.com>
Fri, 29 Apr 2016 15:08:33 +0000 (17:08 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 29 Apr 2016 21:27:05 +0000 (14:27 -0700)
Add helper functions for initiating unidirectional operations and
waiting for them to have been acknowledged as sent by the host device.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/operation.c
drivers/staging/greybus/operation.h

index 9fb7993a86e80e7002e0657ef300e3fec7c1b8b2..fcae7479374066c2c6a7e7374ea64617b7c7b157 100644 (file)
@@ -1090,6 +1090,53 @@ int gb_operation_sync_timeout(struct gb_connection *connection, int type,
 }
 EXPORT_SYMBOL_GPL(gb_operation_sync_timeout);
 
+/**
+ * gb_operation_unidirectional_timeout() - initiate a unidirectional operation
+ * @connection:                connection to use
+ * @type:              type of operation to send
+ * @request:           memory buffer to copy the request from
+ * @request_size:      size of @request
+ * @timeout:           send timeout in milliseconds
+ *
+ * Initiate a unidirectional operation by sending a request message and
+ * waiting for it to be acknowledged as sent by the host device.
+ *
+ * Note that successful send of a unidirectional operation does not imply that
+ * the request as actually reached the remote end of the connection.
+ */
+int gb_operation_unidirectional_timeout(struct gb_connection *connection,
+                               int type, void *request, int request_size,
+                               unsigned int timeout)
+{
+       struct gb_operation *operation;
+       int ret;
+
+       if (request_size && !request)
+               return -EINVAL;
+
+       operation = gb_operation_create_flags(connection, type,
+                                       request_size, 0,
+                                       GB_OPERATION_FLAG_UNIDIRECTIONAL,
+                                       GFP_KERNEL);
+       if (!operation)
+               return -ENOMEM;
+
+       if (request_size)
+               memcpy(operation->request->payload, request, request_size);
+
+       ret = gb_operation_request_send_sync_timeout(operation, timeout);
+       if (ret) {
+               dev_err(&connection->hd->dev,
+                       "%s: unidirectional operation of type 0x%02x failed: %d\n",
+                       connection->name, type, ret);
+       }
+
+       gb_operation_put(operation);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(gb_operation_unidirectional_timeout);
+
 int __init gb_operation_init(void)
 {
        gb_message_cache = kmem_cache_create("gb_message_cache",
index c88efe11c22b545cc10f3242ee426802c37d4c05..8ef8f514dafa1d1591c21f16fe51c160aa945fdf 100644 (file)
@@ -178,6 +178,9 @@ int gb_operation_sync_timeout(struct gb_connection *connection, int type,
                                void *request, int request_size,
                                void *response, int response_size,
                                unsigned int timeout);
+int gb_operation_unidirectional_timeout(struct gb_connection *connection,
+                               int type, void *request, int request_size,
+                               unsigned int timeout);
 
 static inline int gb_operation_sync(struct gb_connection *connection, int type,
                      void *request, int request_size,
@@ -188,6 +191,13 @@ static inline int gb_operation_sync(struct gb_connection *connection, int type,
                        GB_OPERATION_TIMEOUT_DEFAULT);
 }
 
+static inline int gb_operation_unidirectional(struct gb_connection *connection,
+                               int type, void *request, int request_size)
+{
+       return gb_operation_unidirectional_timeout(connection, type,
+                       request, request_size, GB_OPERATION_TIMEOUT_DEFAULT);
+}
+
 int gb_operation_init(void);
 void gb_operation_exit(void);