blob: 1edd512d9a76774adb3fc798e810d836c4400e9b [file] [log] [blame]
Alex Eldere88afa52014-10-01 21:54:15 -05001/*
2 * Greybus operations
3 *
4 * Copyright 2014 Google Inc.
Alex Eldera46e9672014-12-12 12:08:42 -06005 * Copyright 2014 Linaro Ltd.
Alex Eldere88afa52014-10-01 21:54:15 -05006 *
7 * Released under the GPLv2 only.
8 */
9
10#ifndef __OPERATION_H
11#define __OPERATION_H
12
13#include <linux/completion.h>
14
Alex Elder3c3cef42014-11-17 18:08:30 -060015struct gb_operation;
16
Alex Elderc939c2f2014-12-02 17:25:11 -060017/*
18 * No protocol may define an operation that has numeric value 0x00.
19 * It is reserved as an explicitly invalid value.
20 */
21#define GB_OPERATION_TYPE_INVALID ((u8)0x00)
22
23/*
24 * The top bit of the type in an operation message header indicates
25 * whether the message is a request (bit clear) or response (bit set)
26 */
Alex Elder6d653372015-05-07 13:03:52 -050027#define GB_MESSAGE_TYPE_RESPONSE ((u8)0x80)
Alex Elderc939c2f2014-12-02 17:25:11 -060028
Alex Elder23383de2014-11-21 19:29:12 -060029enum gb_operation_result {
Alex Elder57248fa2014-12-01 07:53:09 -060030 GB_OP_SUCCESS = 0x00,
31 GB_OP_INTERRUPTED = 0x01,
32 GB_OP_TIMEOUT = 0x02,
33 GB_OP_NO_MEMORY = 0x03,
34 GB_OP_PROTOCOL_BAD = 0x04,
35 GB_OP_OVERFLOW = 0x05,
36 GB_OP_INVALID = 0x06,
37 GB_OP_RETRY = 0x07,
Alex Elderaa263512014-12-10 08:43:33 -060038 GB_OP_NONEXISTENT = 0x08,
Alex Elder57248fa2014-12-01 07:53:09 -060039 GB_OP_UNKNOWN_ERROR = 0xfe,
40 GB_OP_MALFUNCTION = 0xff,
Alex Eldere88afa52014-10-01 21:54:15 -050041};
42
Alex Elder7cfa6992014-12-03 12:27:44 -060043/*
Johan Hovoldac67acd2015-04-07 11:27:15 +020044 * All operation messages (both requests and responses) begin with
45 * a header that encodes the size of the message (header included).
46 * This header also contains a unique identifier, that associates a
47 * response message with its operation. The header contains an
48 * operation type field, whose interpretation is dependent on what
49 * type of protocol is used over the connection. The high bit
50 * (0x80) of the operation type field is used to indicate whether
51 * the message is a request (clear) or a response (set).
52 *
53 * Response messages include an additional result byte, which
54 * communicates the result of the corresponding request. A zero
55 * result value means the operation completed successfully. Any
56 * other value indicates an error; in this case, the payload of the
57 * response message (if any) is ignored. The result byte must be
58 * zero in the header for a request message.
59 *
60 * The wire format for all numeric fields in the header is little
61 * endian. Any operation-specific data begins immediately after the
62 * header, and is 64-bit aligned.
63 */
64struct gb_operation_msg_hdr {
65 __le16 size; /* Size in bytes of header + payload */
66 __le16 operation_id; /* Operation unique id */
67 __u8 type; /* E.g GB_I2C_TYPE_* or GB_GPIO_TYPE_* */
68 __u8 result; /* Result of request (in responses only) */
Johan Hovoldda9dd112015-04-07 11:27:18 +020069 __u8 pad[2]; /* must be zero (ignore when read) */
Johan Hovoldac67acd2015-04-07 11:27:15 +020070} __aligned(sizeof(u64));
71
Johan Hovoldc38cf102015-05-19 11:22:44 +020072#define GB_OPERATION_MESSAGE_SIZE_MAX U16_MAX
Johan Hovoldd9336672015-05-19 11:22:43 +020073
Johan Hovoldac67acd2015-04-07 11:27:15 +020074/*
Alex Elder7cfa6992014-12-03 12:27:44 -060075 * Protocol code should only examine the payload and payload_size
76 * fields. All other fields are intended to be private to the
77 * operations core code.
78 */
Alex Elder3690a822014-11-17 18:08:31 -060079struct gb_message {
Alex Elder0a4e14a2014-11-20 16:09:14 -060080 struct gb_operation *operation;
Alex Elder0a4e14a2014-11-20 16:09:14 -060081 void *cookie;
Alex Elder7cfa6992014-12-03 12:27:44 -060082 struct gb_operation_msg_hdr *header;
83
84 void *payload;
85 size_t payload_size;
Alex Elder87d208f2014-11-20 16:09:16 -060086
Johan Hovold1e5613b2015-04-07 11:27:17 +020087 void *buffer;
Alex Elder3690a822014-11-17 18:08:31 -060088};
89
Alex Eldere88afa52014-10-01 21:54:15 -050090/*
91 * A Greybus operation is a remote procedure call performed over a
Alex Elder82b5e3f2014-12-03 12:27:46 -060092 * connection between two UniPro interfaces.
93 *
Alex Eldere88afa52014-10-01 21:54:15 -050094 * Every operation consists of a request message sent to the other
Alex Elder82b5e3f2014-12-03 12:27:46 -060095 * end of the connection coupled with a reply message returned to
96 * the sender. Every operation has a type, whose interpretation is
97 * dependent on the protocol associated with the connection.
Alex Eldere88afa52014-10-01 21:54:15 -050098 *
Alex Elder82b5e3f2014-12-03 12:27:46 -060099 * Only four things in an operation structure are intended to be
100 * directly usable by protocol handlers: the operation's connection
101 * pointer; the operation type; the request message payload (and
102 * size); and the response message payload (and size). Note that a
103 * message with a 0-byte payload has a null message payload pointer.
Alex Eldere88afa52014-10-01 21:54:15 -0500104 *
Alex Elder82b5e3f2014-12-03 12:27:46 -0600105 * In addition, every operation has a result, which is an errno
106 * value. Protocol handlers access the operation result using
107 * gb_operation_result().
Alex Eldere88afa52014-10-01 21:54:15 -0500108 */
Alex Eldere88afa52014-10-01 21:54:15 -0500109typedef void (*gb_operation_callback)(struct gb_operation *);
110struct gb_operation {
111 struct gb_connection *connection;
Alex Elderc08b1dd2014-11-20 16:09:15 -0600112 struct gb_message *request;
113 struct gb_message *response;
Alex Elder82b5e3f2014-12-03 12:27:46 -0600114 u8 type;
Alex Elder22b320f2014-10-16 06:35:31 -0500115
Alex Elder82b5e3f2014-12-03 12:27:46 -0600116 u16 id;
Alex Elder23383de2014-11-21 19:29:12 -0600117 int errno; /* Operation result */
118
Alex Elderee637a92014-11-21 19:29:13 -0600119 struct work_struct work;
Alex Eldere88afa52014-10-01 21:54:15 -0500120 gb_operation_callback callback; /* If asynchronous */
121 struct completion completion; /* Used if no callback */
Alex Eldere88afa52014-10-01 21:54:15 -0500122
Alex Elderc7d0f252014-11-17 08:08:40 -0600123 struct kref kref;
Alex Elderafb2e132014-12-03 08:35:07 -0600124 struct list_head links; /* connection->operations */
Alex Eldere88afa52014-10-01 21:54:15 -0500125};
126
Alex Elder61089e82014-11-18 13:26:50 -0600127void gb_connection_recv(struct gb_connection *connection,
Alex Elderd90c25b2014-10-16 06:35:33 -0500128 void *data, size_t size);
129
Alex Elderba986b52014-11-25 11:33:13 -0600130int gb_operation_result(struct gb_operation *operation);
131
Alex Eldere88afa52014-10-01 21:54:15 -0500132struct gb_operation *gb_operation_create(struct gb_connection *connection,
Alex Elder22b320f2014-10-16 06:35:31 -0500133 u8 type, size_t request_size,
134 size_t response_size);
Alex Elderdeb4b9e2014-11-21 19:29:15 -0600135void gb_operation_get(struct gb_operation *operation);
Alex Elderc7d0f252014-11-17 08:08:40 -0600136void gb_operation_put(struct gb_operation *operation);
137static inline void gb_operation_destroy(struct gb_operation *operation)
138{
139 gb_operation_put(operation);
140}
Alex Eldere88afa52014-10-01 21:54:15 -0500141
Alex Elder82e26f72014-12-02 08:30:39 -0600142bool gb_operation_response_alloc(struct gb_operation *operation,
143 size_t response_size);
144
Alex Elderd90c25b2014-10-16 06:35:33 -0500145int gb_operation_request_send(struct gb_operation *operation,
146 gb_operation_callback callback);
Alex Elderc25572c2014-12-03 08:35:09 -0600147int gb_operation_request_send_sync(struct gb_operation *operation);
Alex Elderd2d2c0f2014-12-02 08:30:36 -0600148int gb_operation_response_send(struct gb_operation *operation, int errno);
Alex Elderd90c25b2014-10-16 06:35:33 -0500149
Alex Elderf68c05c2014-11-21 19:29:17 -0600150void gb_operation_cancel(struct gb_operation *operation, int errno);
Alex Eldere88afa52014-10-01 21:54:15 -0500151
Johan Hovold7cf7bca2015-04-07 11:27:16 +0200152void greybus_message_sent(struct greybus_host_device *hd,
153 struct gb_message *message, int status);
Alex Elderd98b52b2014-11-20 16:09:17 -0600154
Greg Kroah-Hartman10aa8012014-11-24 11:19:13 -0800155int gb_operation_sync(struct gb_connection *connection, int type,
156 void *request, int request_size,
157 void *response, int response_size);
158
Alex Elder2eb585f2014-10-16 06:35:34 -0500159int gb_operation_init(void);
160void gb_operation_exit(void);
161
Alex Eldere88afa52014-10-01 21:54:15 -0500162#endif /* !__OPERATION_H */