]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
greybus: cancel operation on timeout
authorAlex Elder <elder@linaro.org>
Sat, 22 Nov 2014 01:29:17 +0000 (19:29 -0600)
committerGreg Kroah-Hartman <greg@kroah.com>
Sat, 22 Nov 2014 03:36:42 +0000 (19:36 -0800)
If an operation times out, we need to cancel whatever message it
has in-flight.  Do that instead of completing the operation, in the
timeout handler.  When the in-flight request message is canceled its
completion function will lead to the proper completion of the
operation.

Change gb_operation_cancel() so it takes the errno that it's
supposed to assign as the result of the operation.

Note that we want to preserve the original -ETIMEDOUT error, so
don't overwrite the operation result value if it has already been
set.

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

index 8cb2af37c25b71e9ef01a6d53e9762854b16def1..6503546ccc018f2dd18b48ee578c52a0e0304622 100644 (file)
@@ -212,7 +212,7 @@ void gb_connection_destroy(struct gb_connection *connection)
        if (WARN_ON(!list_empty(&connection->operations))) {
                list_for_each_entry_safe(operation, next,
                                         &connection->operations, links)
-                       gb_operation_cancel(operation);
+                       gb_operation_cancel(operation, -ESHUTDOWN);
        }
        spin_lock_irq(&gb_connections_lock);
        list_del(&connection->interface_links);
index 32cd2358ab1cb192c3fc3708e5e23d27db3121ba..dc12e6df043d78abd491d0ed4453c892c5796ab8 100644 (file)
@@ -215,20 +215,13 @@ static void gb_operation_work(struct work_struct *work)
 
 /*
  * Timeout call for the operation.
- *
- * If this fires, something went wrong, so mark the result as timed out, and
- * run the completion handler, which (hopefully) should clean up the operation
- * properly.
  */
-static void operation_timeout(struct work_struct *work)
+static void gb_operation_timeout(struct work_struct *work)
 {
        struct gb_operation *operation;
 
        operation = container_of(work, struct gb_operation, timeout_work.work);
-       pr_debug("%s: timeout!\n", __func__);
-
-       operation->errno = -ETIMEDOUT;
-       gb_operation_complete(operation);
+       gb_operation_cancel(operation, -ETIMEDOUT);
 }
 
 /*
@@ -376,7 +369,7 @@ gb_operation_create_common(struct gb_connection *connection, bool outgoing,
        INIT_WORK(&operation->work, gb_operation_work);
        operation->callback = NULL;     /* set at submit time */
        init_completion(&operation->completion);
-       INIT_DELAYED_WORK(&operation->timeout_work, operation_timeout);
+       INIT_DELAYED_WORK(&operation->timeout_work, gb_operation_timeout);
        kref_init(&operation->kref);
 
        spin_lock_irq(&gb_operations_lock);
@@ -633,11 +626,11 @@ void gb_connection_recv(struct gb_connection *connection,
 }
 
 /*
- * Cancel an operation.
+ * Cancel an operation, and record the given error to indicate why.
  */
-void gb_operation_cancel(struct gb_operation *operation)
+void gb_operation_cancel(struct gb_operation *operation, int errno)
 {
-       operation->canceled = true;
+       operation->errno = errno;
        gb_message_cancel(operation->request);
        gb_message_cancel(operation->response);
 }
index befce156aa67a0e16dd5538744e809f04abae40a..d24e5e0d18f0876b6e1433088499e6306d2047c8 100644 (file)
@@ -69,7 +69,6 @@ struct gb_operation {
        struct gb_message       *request;
        struct gb_message       *response;
        u16                     id;
-       bool                    canceled;
 
        int                     errno;          /* Operation result */
 
@@ -99,7 +98,7 @@ int gb_operation_request_send(struct gb_operation *operation,
                                gb_operation_callback callback);
 int gb_operation_response_send(struct gb_operation *operation);
 
-void gb_operation_cancel(struct gb_operation *operation);
+void gb_operation_cancel(struct gb_operation *operation, int errno);
 int gb_operation_wait(struct gb_operation *operation);
 
 int gb_operation_status_map(u8 status);