OSDN Git Service

greybus: operation: add incoming-operation flag
authorJohan Hovold <johan@hovoldconsulting.com>
Wed, 1 Jul 2015 10:37:26 +0000 (12:37 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 1 Jul 2015 23:50:59 +0000 (16:50 -0700)
Add flag field to struct gb_operation, and a first flag
GB_OPERATION_FLAG_INCOMING to identify incoming operations.

Pass an initial set of flags when allocating new operations, and use
these to identify incoming operations rather than overloading the
meaning of GB_OPERATION_TYPE_INVALID. This also allows us to set the
type for all operations during allocation.

Also add convenience helper to identify incoming operations.

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 7adfa63..ad09599 100644 (file)
@@ -413,7 +413,7 @@ EXPORT_SYMBOL_GPL(gb_operation_response_alloc);
 static struct gb_operation *
 gb_operation_create_common(struct gb_connection *connection, u8 type,
                                size_t request_size, size_t response_size,
-                               gfp_t gfp_flags)
+                               unsigned long op_flags, gfp_t gfp_flags)
 {
        struct greybus_host_device *hd = connection->hd;
        struct gb_operation *operation;
@@ -431,11 +431,13 @@ gb_operation_create_common(struct gb_connection *connection, u8 type,
        operation->request->operation = operation;
 
        /* Allocate the response buffer for outgoing operations */
-       if (type != GB_OPERATION_TYPE_INVALID) {
+       if (!(op_flags & GB_OPERATION_FLAG_INCOMING)) {
                if (!gb_operation_response_alloc(operation, response_size))
                        goto err_request;
-               operation->type = type;
        }
+
+       operation->flags = op_flags;
+       operation->type = type;
        operation->errno = -EBADR;  /* Initial value--means "never set" */
 
        INIT_WORK(&operation->work, gb_operation_work);
@@ -475,7 +477,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
                type &= ~GB_MESSAGE_TYPE_RESPONSE;
 
        return gb_operation_create_common(connection, type,
-                                       request_size, response_size, gfp);
+                                       request_size, response_size, 0, gfp);
 }
 EXPORT_SYMBOL_GPL(gb_operation_create);
 
@@ -493,16 +495,15 @@ gb_operation_create_incoming(struct gb_connection *connection, u16 id,
 {
        struct gb_operation *operation;
        size_t request_size;
+       unsigned long flags = GB_OPERATION_FLAG_INCOMING;
 
        /* Caller has made sure we at least have a message header. */
        request_size = size - sizeof(struct gb_operation_msg_hdr);
 
-       operation = gb_operation_create_common(connection,
-                                       GB_OPERATION_TYPE_INVALID,
-                                       request_size, 0, GFP_ATOMIC);
+       operation = gb_operation_create_common(connection, type,
+                                       request_size, 0, flags, GFP_ATOMIC);
        if (operation) {
                operation->id = id;
-               operation->type = type;
                memcpy(operation->request->header, data, size);
        }
 
index 3bf7571..b6bbc84 100644 (file)
@@ -89,6 +89,8 @@ struct gb_message {
        void                            *hcpriv;
 };
 
+#define GB_OPERATION_FLAG_INCOMING             BIT(0)
+
 /*
  * A Greybus operation is a remote procedure call performed over a
  * connection between two UniPro interfaces.
@@ -113,8 +115,9 @@ struct gb_operation {
        struct gb_connection    *connection;
        struct gb_message       *request;
        struct gb_message       *response;
-       u8                      type;
 
+       unsigned long           flags;
+       u8                      type;
        u16                     id;
        int                     errno;          /* Operation result */
 
@@ -126,6 +129,12 @@ struct gb_operation {
        struct list_head        links;          /* connection->operations */
 };
 
+static inline bool
+gb_operation_is_incoming(struct gb_operation *operation)
+{
+       return operation->flags & GB_OPERATION_FLAG_INCOMING;
+}
+
 void gb_connection_recv(struct gb_connection *connection,
                                        void *data, size_t size);