greybus: operation: split incoming and outgoing cancellation
Split incoming and outgoing operation-cancellation helpers. Incoming operations are only cancelled as part of connection tear down and is specifically not needed in the driver API. Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
0eb8c11598
commit
5a3be769e9
@ -238,7 +238,11 @@ static void gb_connection_cancel_operations(struct gb_connection *connection,
|
||||
gb_operation_get(operation);
|
||||
spin_unlock_irq(&connection->lock);
|
||||
|
||||
gb_operation_cancel(operation, errno);
|
||||
if (gb_operation_is_incoming(operation))
|
||||
gb_operation_cancel_incoming(operation, errno);
|
||||
else
|
||||
gb_operation_cancel(operation, errno);
|
||||
|
||||
gb_operation_put(operation);
|
||||
|
||||
spin_lock_irq(&connection->lock);
|
||||
|
@ -922,26 +922,17 @@ void gb_connection_recv(struct gb_connection *connection,
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancel an operation synchronously, and record the given error to indicate
|
||||
* why.
|
||||
* Cancel an outgoing operation synchronously, and record the given error to
|
||||
* indicate why.
|
||||
*/
|
||||
void gb_operation_cancel(struct gb_operation *operation, int errno)
|
||||
{
|
||||
if (gb_operation_is_incoming(operation)) {
|
||||
if (!gb_operation_is_unidirectional(operation)) {
|
||||
/*
|
||||
* Make sure the request handler has submitted the
|
||||
* response before cancelling it.
|
||||
*/
|
||||
flush_work(&operation->work);
|
||||
if (!gb_operation_result_set(operation, errno))
|
||||
gb_message_cancel(operation->response);
|
||||
}
|
||||
} else {
|
||||
if (gb_operation_result_set(operation, errno)) {
|
||||
gb_message_cancel(operation->request);
|
||||
queue_work(gb_operation_workqueue, &operation->work);
|
||||
}
|
||||
if (WARN_ON(gb_operation_is_incoming(operation)))
|
||||
return;
|
||||
|
||||
if (gb_operation_result_set(operation, errno)) {
|
||||
gb_message_cancel(operation->request);
|
||||
queue_work(gb_operation_workqueue, &operation->work);
|
||||
}
|
||||
|
||||
atomic_inc(&operation->waiters);
|
||||
@ -951,6 +942,31 @@ void gb_operation_cancel(struct gb_operation *operation, int errno)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gb_operation_cancel);
|
||||
|
||||
/*
|
||||
* Cancel an incoming operation synchronously. Called during connection tear
|
||||
* down.
|
||||
*/
|
||||
void gb_operation_cancel_incoming(struct gb_operation *operation, int errno)
|
||||
{
|
||||
if (WARN_ON(!gb_operation_is_incoming(operation)))
|
||||
return;
|
||||
|
||||
if (!gb_operation_is_unidirectional(operation)) {
|
||||
/*
|
||||
* Make sure the request handler has submitted the response
|
||||
* before cancelling it.
|
||||
*/
|
||||
flush_work(&operation->work);
|
||||
if (!gb_operation_result_set(operation, errno))
|
||||
gb_message_cancel(operation->response);
|
||||
}
|
||||
|
||||
atomic_inc(&operation->waiters);
|
||||
wait_event(gb_operation_cancellation_queue,
|
||||
!gb_operation_is_active(operation));
|
||||
atomic_dec(&operation->waiters);
|
||||
}
|
||||
|
||||
/**
|
||||
* gb_operation_sync: implement a "simple" synchronous gb operation.
|
||||
* @connection: the Greybus connection to send this to
|
||||
|
@ -171,6 +171,7 @@ int gb_operation_request_send(struct gb_operation *operation,
|
||||
int gb_operation_request_send_sync(struct gb_operation *operation);
|
||||
|
||||
void gb_operation_cancel(struct gb_operation *operation, int errno);
|
||||
void gb_operation_cancel_incoming(struct gb_operation *operation, int errno);
|
||||
|
||||
void greybus_message_sent(struct greybus_host_device *hd,
|
||||
struct gb_message *message, int status);
|
||||
|
Loading…
x
Reference in New Issue
Block a user