OSDN Git Service

greybus: introduce gb_operation_request_send_sync()
authorAlex Elder <elder@linaro.org>
Wed, 3 Dec 2014 14:35:09 +0000 (08:35 -0600)
committerGreg Kroah-Hartman <greg@kroah.com>
Wed, 3 Dec 2014 23:05:58 +0000 (15:05 -0800)
Define a new function used to initiate a synchronous operation.
It sends the operation request message and doesn't return until
the response has been received and/or the operation's result
has been set.

This gets rid of the convention that a null callback pointer
signifies a synchronous operation.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/staging/greybus/i2c-gb.c
drivers/staging/greybus/operation.c
drivers/staging/greybus/operation.h
drivers/staging/greybus/usb-gb.c

index 19a7df9..bd1bada 100644 (file)
@@ -285,7 +285,7 @@ static int gb_i2c_transfer_operation(struct gb_i2c_device *gb_i2c_dev,
                return -ENOMEM;
 
        /* Synchronous operation--no callback */
-       ret = gb_operation_request_send(operation, NULL);
+       ret = gb_operation_request_send_sync(operation);
        if (ret) {
                if (ret != -EAGAIN)
                        pr_err("transfer operation failed (%d)\n", ret);
index 15a6e3b..c62f200 100644 (file)
@@ -641,7 +641,6 @@ int gb_operation_request_send(struct gb_operation *operation,
        struct gb_operation_msg_hdr *header;
        unsigned long timeout;
        unsigned int cycle;
-       int ret;
 
        if (connection->state != GB_CONNECTION_STATE_ENABLED)
                return -ENOTCONN;
@@ -652,11 +651,12 @@ int gb_operation_request_send(struct gb_operation *operation,
         */
        gb_operation_get(operation);
 
-       /* A null callback pointer means synchronous return */
-       if (callback)
-               operation->callback = callback;
-       else
-               operation->callback = gb_operation_sync_callback;
+       /*
+        * Record the callback function, which is executed in
+        * non-atomic (workqueue) context when the final result
+        * of an operation has been set.
+        */
+       operation->callback = callback;
 
        /*
         * Assign the operation's id, and store it in the request header.
@@ -677,8 +677,22 @@ int gb_operation_request_send(struct gb_operation *operation,
 
        /* All set, send the request */
        gb_operation_result_set(operation, -EINPROGRESS);
-       ret = gb_message_send(operation->request);
-       if (ret || callback)
+
+       return gb_message_send(operation->request);
+}
+
+/*
+ * Send a synchronous operation.  This function is expected to
+ * block, returning only when the response has arrived, (or when an
+ * error is detected.  The return value is the result of the
+ * operation.
+ */
+int gb_operation_request_send_sync(struct gb_operation *operation)
+{
+       int ret;
+
+       ret = gb_operation_request_send(operation, gb_operation_sync_callback);
+       if (ret)
                return ret;
 
        /* Cancel the operation if interrupted */
@@ -923,8 +937,7 @@ int gb_operation_sync(struct gb_connection *connection, int type,
        if (request_size)
                memcpy(operation->request->payload, request, request_size);
 
-       /* Synchronous operation--no callback */
-       ret = gb_operation_request_send(operation, NULL);
+       ret = gb_operation_request_send_sync(operation);
        if (ret)
                pr_err("version operation failed (%d)\n", ret);
        else
index c73d9b9..3415e8b 100644 (file)
@@ -115,6 +115,7 @@ bool gb_operation_response_alloc(struct gb_operation *operation,
 
 int gb_operation_request_send(struct gb_operation *operation,
                                gb_operation_callback callback);
+int gb_operation_request_send_sync(struct gb_operation *operation);
 int gb_operation_response_send(struct gb_operation *operation, int errno);
 
 void gb_operation_cancel(struct gb_operation *operation, int errno);
index ab4e093..e5da72a 100644 (file)
@@ -169,7 +169,7 @@ static int urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
        memcpy(&request->payload, urb->transfer_buffer,
               urb->transfer_buffer_length);
 
-       ret = gb_operation_request_send(operation, NULL);
+       ret = gb_operation_request_send_sync(operation);
        gb_operation_destroy(operation);
 
        return ret;