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

greybus: define operation_cancel()

Define a new function operation_cancel() that cancels an
outstanding operation.  Use it to clear out any operations that
might be pending at the time a connection is torn down.

Note:  This code isn't really functional yet, partially because
greybus_kill_gbuf() is not implemented.
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent e816e374
...@@ -162,12 +162,19 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface, ...@@ -162,12 +162,19 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface,
*/ */
void gb_connection_destroy(struct gb_connection *connection) void gb_connection_destroy(struct gb_connection *connection)
{ {
struct gb_operation *operation;
struct gb_operation *next;
if (WARN_ON(!connection)) if (WARN_ON(!connection))
return; return;
/* XXX Need to wait for any outstanding requests to complete */ /* XXX Need to wait for any outstanding requests to complete */
WARN_ON(!list_empty(&connection->operations)); WARN_ON(!list_empty(&connection->operations));
list_for_each_entry_safe(operation, next, &connection->operations,
links) {
gb_operation_cancel(operation);
}
spin_lock_irq(&gb_connections_lock); spin_lock_irq(&gb_connections_lock);
list_del(&connection->interface_links); list_del(&connection->interface_links);
_gb_hd_connection_remove(connection); _gb_hd_connection_remove(connection);
......
...@@ -501,6 +501,24 @@ void gb_connection_operation_recv(struct gb_connection *connection, ...@@ -501,6 +501,24 @@ void gb_connection_operation_recv(struct gb_connection *connection,
queue_work(gb_operation_recv_workqueue, &operation->recv_work); queue_work(gb_operation_recv_workqueue, &operation->recv_work);
} }
/*
* Cancel an operation.
*/
void gb_operation_cancel(struct gb_operation *operation)
{
int ret;
operation->canceled = true;
ret = greybus_kill_gbuf(operation->request);
if (ret)
pr_warn("error %d killing request gbuf\n", ret);
if (operation->response) {
ret = greybus_kill_gbuf(operation->response);
if (ret)
pr_warn("error %d killing response gbuf\n", ret);
}
}
int gb_operation_init(void) int gb_operation_init(void)
{ {
gb_operation_cache = kmem_cache_create("gb_operation_cache", gb_operation_cache = kmem_cache_create("gb_operation_cache",
......
...@@ -55,6 +55,7 @@ struct gb_operation { ...@@ -55,6 +55,7 @@ struct gb_operation {
struct gbuf *request; struct gbuf *request;
struct gbuf *response; struct gbuf *response;
u16 id; u16 id;
bool canceled;
u8 result; u8 result;
struct work_struct recv_work; struct work_struct recv_work;
...@@ -81,6 +82,7 @@ int gb_operation_request_send(struct gb_operation *operation, ...@@ -81,6 +82,7 @@ int gb_operation_request_send(struct gb_operation *operation,
gb_operation_callback callback); gb_operation_callback callback);
int gb_operation_response_send(struct gb_operation *operation); int gb_operation_response_send(struct gb_operation *operation);
void gb_operation_cancel(struct gb_operation *operation);
int gb_operation_wait(struct gb_operation *operation); int gb_operation_wait(struct gb_operation *operation);
void gb_operation_complete(struct gb_operation *operation); void gb_operation_complete(struct gb_operation *operation);
......
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