mirror of https://gitee.com/openkylin/linux.git
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: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
parent
e816e37419
commit
e1158df063
|
@ -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,
|
||||||
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 {
|
||||||
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,
|
||||||
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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue