Commit c7d0f258 authored by Alex Elder's avatar Alex Elder Committed by Greg Kroah-Hartman

greybus: reference count operations

Add a reference counter to the operations structure.  We'll
need this when operations are actually allowed to complete
asynchronously.
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 78496db0
......@@ -274,6 +274,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
operation->callback = NULL; /* set at submit time */
init_completion(&operation->completion);
INIT_DELAYED_WORK(&operation->timeout_work, operation_timeout);
kref_init(&operation->kref);
spin_lock_irq(&gb_operations_lock);
list_add_tail(&operation->links, &connection->operations);
......@@ -292,10 +293,11 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
/*
* Destroy a previously created operation.
*/
void gb_operation_destroy(struct gb_operation *operation)
static void _gb_operation_destroy(struct kref *kref)
{
if (WARN_ON(!operation))
return;
struct gb_operation *operation;
operation = container_of(kref, struct gb_operation, kref);
/* XXX Make sure it's not in flight */
spin_lock_irq(&gb_operations_lock);
......@@ -308,6 +310,12 @@ void gb_operation_destroy(struct gb_operation *operation)
kmem_cache_free(gb_operation_cache, operation);
}
void gb_operation_put(struct gb_operation *operation)
{
if (!WARN_ON(!operation))
kref_put(&operation->kref, _gb_operation_destroy);
}
/*
* Send an operation request message. The caller has filled in
* any payload so the request message is ready to go. If non-null,
......
......@@ -65,6 +65,7 @@ struct gb_operation {
struct completion completion; /* Used if no callback */
struct delayed_work timeout_work;
struct kref kref;
struct list_head links; /* connection->{operations,pending} */
/* These are what's used by caller */
......@@ -78,7 +79,12 @@ void gb_connection_operation_recv(struct gb_connection *connection,
struct gb_operation *gb_operation_create(struct gb_connection *connection,
u8 type, size_t request_size,
size_t response_size);
void gb_operation_destroy(struct gb_operation *operation);
struct gb_operation *gb_operation_get(struct gb_operation *operation);
void gb_operation_put(struct gb_operation *operation);
static inline void gb_operation_destroy(struct gb_operation *operation)
{
gb_operation_put(operation);
}
int gb_operation_request_send(struct gb_operation *operation,
gb_operation_callback callback);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment