Commit 4f2c08ab authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

greybus: operation: allow drivers to define custom timeouts



Add new interface gb_operation_request_send_sync_timeout, which allows
drivers to define a custom operation timeout instead of the default
one-second timeout.

The timeout is expected to depend on protocol and operation and
therefore needs to be configurable.

Note that that a timeout of zero is used to wait indefinitely.

Reviewed-by: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 5a3be769
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

#include "greybus.h"

/* The default amount of time a request is given to complete */
#define OPERATION_TIMEOUT_DEFAULT	1000	/* milliseconds */

static struct kmem_cache *gb_operation_cache;
static struct kmem_cache *gb_message_cache;

@@ -690,18 +687,24 @@ EXPORT_SYMBOL_GPL(gb_operation_request_send);
 * error is detected.  The return value is the result of the
 * operation.
 */
int gb_operation_request_send_sync(struct gb_operation *operation)
int gb_operation_request_send_sync_timeout(struct gb_operation *operation,
						unsigned int timeout)
{
	int ret;
	unsigned long timeout;
	unsigned long timeout_jiffies;

	ret = gb_operation_request_send(operation, gb_operation_sync_callback,
					GFP_KERNEL);
	if (ret)
		return ret;

	timeout = msecs_to_jiffies(OPERATION_TIMEOUT_DEFAULT);
	ret = wait_for_completion_interruptible_timeout(&operation->completion, timeout);
	if (timeout)
		timeout_jiffies = msecs_to_jiffies(timeout);
	else
		timeout_jiffies = MAX_SCHEDULE_TIMEOUT;

	ret = wait_for_completion_interruptible_timeout(&operation->completion,
							timeout_jiffies);
	if (ret < 0) {
		/* Cancel the operation if interrupted */
		gb_operation_cancel(operation, -ECANCELED);
@@ -712,7 +715,7 @@ int gb_operation_request_send_sync(struct gb_operation *operation)

	return gb_operation_result(operation);
}
EXPORT_SYMBOL_GPL(gb_operation_request_send_sync);
EXPORT_SYMBOL_GPL(gb_operation_request_send_sync_timeout);

/*
 * Send a response for an incoming operation request.  A non-zero
+11 −1
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@

struct gb_operation;

/* The default amount of time a request is given to complete */
#define GB_OPERATION_TIMEOUT_DEFAULT	1000	/* milliseconds */

/*
 * No protocol may define an operation that has numeric value 0x00.
 * It is reserved as an explicitly invalid value.
@@ -168,7 +171,14 @@ bool gb_operation_response_alloc(struct gb_operation *operation,
int gb_operation_request_send(struct gb_operation *operation,
				gb_operation_callback callback,
				gfp_t gfp);
int gb_operation_request_send_sync(struct gb_operation *operation);
int gb_operation_request_send_sync_timeout(struct gb_operation *operation,
						unsigned int timeout);
static inline int
gb_operation_request_send_sync(struct gb_operation *operation)
{
	return gb_operation_request_send_sync_timeout(operation,
			GB_OPERATION_TIMEOUT_DEFAULT);
}

void gb_operation_cancel(struct gb_operation *operation, int errno);
void gb_operation_cancel_incoming(struct gb_operation *operation, int errno);