Lines Matching refs:operation
33 static int gb_operation_response_send(struct gb_operation *operation,
42 static int gb_operation_get_active(struct gb_operation *operation) in gb_operation_get_active() argument
44 struct gb_connection *connection = operation->connection; in gb_operation_get_active()
52 if (gb_operation_is_incoming(operation)) in gb_operation_get_active()
56 if (!gb_operation_is_core(operation)) in gb_operation_get_active()
63 if (operation->active++ == 0) in gb_operation_get_active()
64 list_add_tail(&operation->links, &connection->operations); in gb_operation_get_active()
66 trace_gb_operation_get_active(operation); in gb_operation_get_active()
79 static void gb_operation_put_active(struct gb_operation *operation) in gb_operation_put_active() argument
81 struct gb_connection *connection = operation->connection; in gb_operation_put_active()
86 trace_gb_operation_put_active(operation); in gb_operation_put_active()
88 if (--operation->active == 0) { in gb_operation_put_active()
89 list_del(&operation->links); in gb_operation_put_active()
90 if (atomic_read(&operation->waiters)) in gb_operation_put_active()
96 static bool gb_operation_is_active(struct gb_operation *operation) in gb_operation_is_active() argument
98 struct gb_connection *connection = operation->connection; in gb_operation_is_active()
103 ret = operation->active; in gb_operation_is_active()
134 static bool gb_operation_result_set(struct gb_operation *operation, int result) in gb_operation_result_set() argument
148 prev = operation->errno; in gb_operation_result_set()
150 operation->errno = result; in gb_operation_result_set()
152 operation->errno = -EILSEQ; in gb_operation_result_set()
172 prev = operation->errno; in gb_operation_result_set()
174 operation->errno = result; /* First and final result */ in gb_operation_result_set()
180 int gb_operation_result(struct gb_operation *operation) in gb_operation_result() argument
182 int result = operation->errno; in gb_operation_result()
198 struct gb_operation *operation; in gb_operation_find_outgoing() local
203 list_for_each_entry(operation, &connection->operations, links) in gb_operation_find_outgoing()
204 if (operation->id == operation_id && in gb_operation_find_outgoing()
205 !gb_operation_is_incoming(operation)) { in gb_operation_find_outgoing()
206 gb_operation_get(operation); in gb_operation_find_outgoing()
212 return found ? operation : NULL; in gb_operation_find_outgoing()
217 struct gb_connection *connection = message->operation->connection; in gb_message_send()
231 struct gb_host_device *hd = message->operation->connection->hd; in gb_message_cancel()
236 static void gb_operation_request_handle(struct gb_operation *operation) in gb_operation_request_handle() argument
238 struct gb_connection *connection = operation->connection; in gb_operation_request_handle()
243 status = connection->handler(operation); in gb_operation_request_handle()
247 connection->name, operation->type); in gb_operation_request_handle()
252 ret = gb_operation_response_send(operation, status); in gb_operation_request_handle()
256 connection->name, status, operation->type, ret); in gb_operation_request_handle()
274 struct gb_operation *operation; in gb_operation_work() local
277 operation = container_of(work, struct gb_operation, work); in gb_operation_work()
279 if (gb_operation_is_incoming(operation)) { in gb_operation_work()
280 gb_operation_request_handle(operation); in gb_operation_work()
282 ret = del_timer_sync(&operation->timer); in gb_operation_work()
285 if (gb_operation_result(operation) == -ETIMEDOUT) in gb_operation_work()
286 gb_message_cancel(operation->request); in gb_operation_work()
289 operation->callback(operation); in gb_operation_work()
292 gb_operation_put_active(operation); in gb_operation_work()
293 gb_operation_put(operation); in gb_operation_work()
298 struct gb_operation *operation = from_timer(operation, t, timer); in gb_operation_timeout() local
300 if (gb_operation_result_set(operation, -ETIMEDOUT)) { in gb_operation_timeout()
305 queue_work(gb_operation_completion_wq, &operation->work); in gb_operation_timeout()
468 bool gb_operation_response_alloc(struct gb_operation *operation, in gb_operation_response_alloc() argument
471 struct gb_host_device *hd = operation->connection->hd; in gb_operation_response_alloc()
476 type = operation->type | GB_MESSAGE_TYPE_RESPONSE; in gb_operation_response_alloc()
480 response->operation = operation; in gb_operation_response_alloc()
488 request_header = operation->request->header; in gb_operation_response_alloc()
490 operation->response = response; in gb_operation_response_alloc()
524 struct gb_operation *operation; in gb_operation_create_common() local
526 operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags); in gb_operation_create_common()
527 if (!operation) in gb_operation_create_common()
529 operation->connection = connection; in gb_operation_create_common()
531 operation->request = gb_operation_message_alloc(hd, type, request_size, in gb_operation_create_common()
533 if (!operation->request) in gb_operation_create_common()
535 operation->request->operation = operation; in gb_operation_create_common()
539 if (!gb_operation_response_alloc(operation, response_size, in gb_operation_create_common()
544 timer_setup(&operation->timer, gb_operation_timeout, 0); in gb_operation_create_common()
547 operation->flags = op_flags; in gb_operation_create_common()
548 operation->type = type; in gb_operation_create_common()
549 operation->errno = -EBADR; /* Initial value--means "never set" */ in gb_operation_create_common()
551 INIT_WORK(&operation->work, gb_operation_work); in gb_operation_create_common()
552 init_completion(&operation->completion); in gb_operation_create_common()
553 kref_init(&operation->kref); in gb_operation_create_common()
554 atomic_set(&operation->waiters, 0); in gb_operation_create_common()
556 return operation; in gb_operation_create_common()
559 gb_operation_message_free(operation->request); in gb_operation_create_common()
561 kmem_cache_free(gb_operation_cache, operation); in gb_operation_create_common()
580 struct gb_operation *operation; in gb_operation_create_flags() local
590 operation = gb_operation_create_common(connection, type, in gb_operation_create_flags()
593 if (operation) in gb_operation_create_flags()
594 trace_gb_operation_create(operation); in gb_operation_create_flags()
596 return operation; in gb_operation_create_flags()
606 struct gb_operation *operation; in gb_operation_create_core() local
610 operation = gb_operation_create_common(connection, type, in gb_operation_create_core()
613 if (operation) in gb_operation_create_core()
614 trace_gb_operation_create_core(operation); in gb_operation_create_core()
616 return operation; in gb_operation_create_core()
633 struct gb_operation *operation; in gb_operation_create_incoming() local
643 operation = gb_operation_create_common(connection, type, in gb_operation_create_incoming()
647 if (!operation) in gb_operation_create_incoming()
650 operation->id = id; in gb_operation_create_incoming()
651 memcpy(operation->request->header, data, size); in gb_operation_create_incoming()
652 trace_gb_operation_create_incoming(operation); in gb_operation_create_incoming()
654 return operation; in gb_operation_create_incoming()
660 void gb_operation_get(struct gb_operation *operation) in gb_operation_get() argument
662 kref_get(&operation->kref); in gb_operation_get()
671 struct gb_operation *operation; in _gb_operation_destroy() local
673 operation = container_of(kref, struct gb_operation, kref); in _gb_operation_destroy()
675 trace_gb_operation_destroy(operation); in _gb_operation_destroy()
677 if (operation->response) in _gb_operation_destroy()
678 gb_operation_message_free(operation->response); in _gb_operation_destroy()
679 gb_operation_message_free(operation->request); in _gb_operation_destroy()
681 kmem_cache_free(gb_operation_cache, operation); in _gb_operation_destroy()
688 void gb_operation_put(struct gb_operation *operation) in gb_operation_put() argument
690 if (WARN_ON(!operation)) in gb_operation_put()
693 kref_put(&operation->kref, _gb_operation_destroy); in gb_operation_put()
698 static void gb_operation_sync_callback(struct gb_operation *operation) in gb_operation_sync_callback() argument
700 complete(&operation->completion); in gb_operation_sync_callback()
720 int gb_operation_request_send(struct gb_operation *operation, in gb_operation_request_send() argument
725 struct gb_connection *connection = operation->connection; in gb_operation_request_send()
741 operation->callback = callback; in gb_operation_request_send()
747 if (gb_operation_is_unidirectional(operation)) { in gb_operation_request_send()
748 operation->id = 0; in gb_operation_request_send()
751 operation->id = (u16)(cycle % U16_MAX + 1); in gb_operation_request_send()
754 header = operation->request->header; in gb_operation_request_send()
755 header->operation_id = cpu_to_le16(operation->id); in gb_operation_request_send()
757 gb_operation_result_set(operation, -EINPROGRESS); in gb_operation_request_send()
763 gb_operation_get(operation); in gb_operation_request_send()
764 ret = gb_operation_get_active(operation); in gb_operation_request_send()
768 ret = gb_message_send(operation->request, gfp); in gb_operation_request_send()
773 operation->timer.expires = jiffies + msecs_to_jiffies(timeout); in gb_operation_request_send()
774 add_timer(&operation->timer); in gb_operation_request_send()
780 gb_operation_put_active(operation); in gb_operation_request_send()
782 gb_operation_put(operation); in gb_operation_request_send()
794 int gb_operation_request_send_sync_timeout(struct gb_operation *operation, in gb_operation_request_send_sync_timeout() argument
799 ret = gb_operation_request_send(operation, gb_operation_sync_callback, in gb_operation_request_send_sync_timeout()
804 ret = wait_for_completion_interruptible(&operation->completion); in gb_operation_request_send_sync_timeout()
807 gb_operation_cancel(operation, -ECANCELED); in gb_operation_request_send_sync_timeout()
810 return gb_operation_result(operation); in gb_operation_request_send_sync_timeout()
823 static int gb_operation_response_send(struct gb_operation *operation, in gb_operation_response_send() argument
826 struct gb_connection *connection = operation->connection; in gb_operation_response_send()
829 if (!operation->response && in gb_operation_response_send()
830 !gb_operation_is_unidirectional(operation)) { in gb_operation_response_send()
831 if (!gb_operation_response_alloc(operation, 0, GFP_KERNEL)) in gb_operation_response_send()
836 if (!gb_operation_result_set(operation, errno)) { in gb_operation_response_send()
842 if (gb_operation_is_unidirectional(operation)) in gb_operation_response_send()
846 gb_operation_get(operation); in gb_operation_response_send()
847 ret = gb_operation_get_active(operation); in gb_operation_response_send()
852 operation->response->header->result = gb_operation_errno_map(errno); in gb_operation_response_send()
854 ret = gb_message_send(operation->response, GFP_KERNEL); in gb_operation_response_send()
861 gb_operation_put_active(operation); in gb_operation_response_send()
863 gb_operation_put(operation); in gb_operation_response_send()
874 struct gb_operation *operation = message->operation; in greybus_message_sent() local
875 struct gb_connection *connection = operation->connection; in greybus_message_sent()
888 if (message == operation->response) { in greybus_message_sent()
892 connection->name, operation->type, status); in greybus_message_sent()
895 gb_operation_put_active(operation); in greybus_message_sent()
896 gb_operation_put(operation); in greybus_message_sent()
897 } else if (status || gb_operation_is_unidirectional(operation)) { in greybus_message_sent()
898 if (gb_operation_result_set(operation, status)) { in greybus_message_sent()
900 &operation->work); in greybus_message_sent()
917 struct gb_operation *operation; in gb_connection_recv_request() local
925 operation = gb_operation_create_incoming(connection, operation_id, in gb_connection_recv_request()
927 if (!operation) { in gb_connection_recv_request()
934 ret = gb_operation_get_active(operation); in gb_connection_recv_request()
936 gb_operation_put(operation); in gb_connection_recv_request()
939 trace_gb_message_recv_request(operation->request); in gb_connection_recv_request()
945 if (gb_operation_result_set(operation, -EINPROGRESS)) in gb_connection_recv_request()
946 queue_work(connection->wq, &operation->work); in gb_connection_recv_request()
961 struct gb_operation *operation; in gb_connection_recv_response() local
976 operation = gb_operation_find_outgoing(connection, operation_id); in gb_connection_recv_response()
977 if (!operation) { in gb_connection_recv_response()
985 message = operation->response; in gb_connection_recv_response()
994 if (gb_operation_short_response_allowed(operation)) { in gb_connection_recv_response()
1010 if (gb_operation_result_set(operation, errno)) { in gb_connection_recv_response()
1015 queue_work(gb_operation_completion_wq, &operation->work); in gb_connection_recv_response()
1018 gb_operation_put(operation); in gb_connection_recv_response()
1071 void gb_operation_cancel(struct gb_operation *operation, int errno) in gb_operation_cancel() argument
1073 if (WARN_ON(gb_operation_is_incoming(operation))) in gb_operation_cancel()
1076 if (gb_operation_result_set(operation, errno)) { in gb_operation_cancel()
1077 gb_message_cancel(operation->request); in gb_operation_cancel()
1078 queue_work(gb_operation_completion_wq, &operation->work); in gb_operation_cancel()
1080 trace_gb_message_cancel_outgoing(operation->request); in gb_operation_cancel()
1082 atomic_inc(&operation->waiters); in gb_operation_cancel()
1084 !gb_operation_is_active(operation)); in gb_operation_cancel()
1085 atomic_dec(&operation->waiters); in gb_operation_cancel()
1093 void gb_operation_cancel_incoming(struct gb_operation *operation, int errno) in gb_operation_cancel_incoming() argument
1095 if (WARN_ON(!gb_operation_is_incoming(operation))) in gb_operation_cancel_incoming()
1098 if (!gb_operation_is_unidirectional(operation)) { in gb_operation_cancel_incoming()
1103 flush_work(&operation->work); in gb_operation_cancel_incoming()
1104 if (!gb_operation_result_set(operation, errno)) in gb_operation_cancel_incoming()
1105 gb_message_cancel(operation->response); in gb_operation_cancel_incoming()
1107 trace_gb_message_cancel_incoming(operation->response); in gb_operation_cancel_incoming()
1109 atomic_inc(&operation->waiters); in gb_operation_cancel_incoming()
1111 !gb_operation_is_active(operation)); in gb_operation_cancel_incoming()
1112 atomic_dec(&operation->waiters); in gb_operation_cancel_incoming()
1143 struct gb_operation *operation; in gb_operation_sync_timeout() local
1150 operation = gb_operation_create(connection, type, in gb_operation_sync_timeout()
1153 if (!operation) in gb_operation_sync_timeout()
1157 memcpy(operation->request->payload, request, request_size); in gb_operation_sync_timeout()
1159 ret = gb_operation_request_send_sync_timeout(operation, timeout); in gb_operation_sync_timeout()
1163 connection->name, operation->id, type, ret); in gb_operation_sync_timeout()
1166 memcpy(response, operation->response->payload, in gb_operation_sync_timeout()
1171 gb_operation_put(operation); in gb_operation_sync_timeout()
1196 struct gb_operation *operation; in gb_operation_unidirectional_timeout() local
1202 operation = gb_operation_create_flags(connection, type, in gb_operation_unidirectional_timeout()
1206 if (!operation) in gb_operation_unidirectional_timeout()
1210 memcpy(operation->request->payload, request, request_size); in gb_operation_unidirectional_timeout()
1212 ret = gb_operation_request_send_sync_timeout(operation, timeout); in gb_operation_unidirectional_timeout()
1219 gb_operation_put(operation); in gb_operation_unidirectional_timeout()