Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Greybus operations |
| 3 | * |
| 4 | * Copyright 2014 Google Inc. |
| 5 | * |
| 6 | * Released under the GPLv2 only. |
| 7 | */ |
| 8 | |
| 9 | #ifndef __OPERATION_H |
| 10 | #define __OPERATION_H |
| 11 | |
| 12 | #include <linux/completion.h> |
| 13 | |
| 14 | enum gb_operation_status { |
| 15 | GB_OP_SUCCESS = 0, |
| 16 | GB_OP_INVALID = 1, |
| 17 | GB_OP_NO_MEMORY = 2, |
| 18 | GB_OP_INTERRUPTED = 3, |
Alex Elder | d752868 | 2014-10-17 05:09:21 -0500 | [diff] [blame] | 19 | GB_OP_RETRY = 4, |
| 20 | GB_OP_PROTOCOL_BAD = 5, |
Greg Kroah-Hartman | 708971e | 2014-10-27 15:40:09 +0800 | [diff] [blame] | 21 | GB_OP_TIMEOUT = 0xff, |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 22 | }; |
| 23 | |
| 24 | /* |
| 25 | * A Greybus operation is a remote procedure call performed over a |
| 26 | * connection between the AP and a function on Greybus module. |
| 27 | * Every operation consists of a request message sent to the other |
| 28 | * end of the connection coupled with a reply returned to the |
| 29 | * sender. |
| 30 | * |
| 31 | * The state for managing active requests on a connection is held in |
| 32 | * the connection structure. |
| 33 | * |
| 34 | * YADA YADA |
| 35 | * |
| 36 | * submitting each request and providing its matching response to |
| 37 | * the caller when it arrives. Operations normally complete |
| 38 | * asynchronously, and when an operation's response arrives its |
| 39 | * callback function is executed. The callback pointer is supplied |
| 40 | * at the time the operation is submitted; a null callback pointer |
| 41 | * causes synchronous operation--the caller is blocked until |
| 42 | * the response arrives. In addition, it is possible to await |
| 43 | * the completion of a submitted asynchronous operation. |
| 44 | * |
| 45 | * A Greybus device operation includes a Greybus buffer to hold the |
| 46 | * data sent to the device. The only field within a Greybus |
| 47 | * operation that should be used by a caller is the payload pointer, |
| 48 | * which should be used to populate the request data. This pointer |
| 49 | * is guaranteed to be 64-bit aligned. |
| 50 | * XXX and callback? |
| 51 | */ |
| 52 | struct gb_operation; |
| 53 | typedef void (*gb_operation_callback)(struct gb_operation *); |
| 54 | struct gb_operation { |
| 55 | struct gb_connection *connection; |
Alex Elder | 22b320f | 2014-10-16 06:35:31 -0500 | [diff] [blame] | 56 | struct gbuf *request; |
| 57 | struct gbuf *response; |
Alex Elder | 84d148b | 2014-10-16 06:35:32 -0500 | [diff] [blame] | 58 | u16 id; |
Alex Elder | e1158df | 2014-10-22 02:04:29 -0500 | [diff] [blame] | 59 | bool canceled; |
Alex Elder | 22b320f | 2014-10-16 06:35:31 -0500 | [diff] [blame] | 60 | |
Alex Elder | 84d148b | 2014-10-16 06:35:32 -0500 | [diff] [blame] | 61 | u8 result; |
Alex Elder | 2eb585f | 2014-10-16 06:35:34 -0500 | [diff] [blame] | 62 | struct work_struct recv_work; |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 63 | gb_operation_callback callback; /* If asynchronous */ |
| 64 | struct completion completion; /* Used if no callback */ |
Greg Kroah-Hartman | 708971e | 2014-10-27 15:40:09 +0800 | [diff] [blame] | 65 | struct delayed_work timeout_work; |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 66 | |
| 67 | struct list_head links; /* connection->operations */ |
Alex Elder | 84d148b | 2014-10-16 06:35:32 -0500 | [diff] [blame] | 68 | struct rb_node node; /* connection->pending */ |
Alex Elder | 22b320f | 2014-10-16 06:35:31 -0500 | [diff] [blame] | 69 | |
| 70 | /* These are what's used by caller */ |
| 71 | void *request_payload; |
| 72 | void *response_payload; |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 73 | }; |
| 74 | |
Alex Elder | d90c25b | 2014-10-16 06:35:33 -0500 | [diff] [blame] | 75 | void gb_connection_operation_recv(struct gb_connection *connection, |
| 76 | void *data, size_t size); |
| 77 | |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 78 | struct gb_operation *gb_operation_create(struct gb_connection *connection, |
Alex Elder | 22b320f | 2014-10-16 06:35:31 -0500 | [diff] [blame] | 79 | u8 type, size_t request_size, |
| 80 | size_t response_size); |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 81 | void gb_operation_destroy(struct gb_operation *operation); |
| 82 | |
Alex Elder | d90c25b | 2014-10-16 06:35:33 -0500 | [diff] [blame] | 83 | int gb_operation_request_send(struct gb_operation *operation, |
| 84 | gb_operation_callback callback); |
| 85 | int gb_operation_response_send(struct gb_operation *operation); |
| 86 | |
Alex Elder | e1158df | 2014-10-22 02:04:29 -0500 | [diff] [blame] | 87 | void gb_operation_cancel(struct gb_operation *operation); |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 88 | int gb_operation_wait(struct gb_operation *operation); |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 89 | |
Alex Elder | 2eb585f | 2014-10-16 06:35:34 -0500 | [diff] [blame] | 90 | int gb_operation_init(void); |
| 91 | void gb_operation_exit(void); |
| 92 | |
Alex Elder | e88afa5 | 2014-10-01 21:54:15 -0500 | [diff] [blame] | 93 | #endif /* !__OPERATION_H */ |