1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Greybus operations
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright 2014 Google Inc.
6*4882a593Smuzhiyun * Copyright 2014 Linaro Ltd.
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #ifndef __OPERATION_H
10*4882a593Smuzhiyun #define __OPERATION_H
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/completion.h>
13*4882a593Smuzhiyun #include <linux/kref.h>
14*4882a593Smuzhiyun #include <linux/timer.h>
15*4882a593Smuzhiyun #include <linux/types.h>
16*4882a593Smuzhiyun #include <linux/workqueue.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun struct gb_host_device;
19*4882a593Smuzhiyun struct gb_operation;
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /* The default amount of time a request is given to complete */
22*4882a593Smuzhiyun #define GB_OPERATION_TIMEOUT_DEFAULT 1000 /* milliseconds */
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun * The top bit of the type in an operation message header indicates
26*4882a593Smuzhiyun * whether the message is a request (bit clear) or response (bit set)
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun #define GB_MESSAGE_TYPE_RESPONSE ((u8)0x80)
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun enum gb_operation_result {
31*4882a593Smuzhiyun GB_OP_SUCCESS = 0x00,
32*4882a593Smuzhiyun GB_OP_INTERRUPTED = 0x01,
33*4882a593Smuzhiyun GB_OP_TIMEOUT = 0x02,
34*4882a593Smuzhiyun GB_OP_NO_MEMORY = 0x03,
35*4882a593Smuzhiyun GB_OP_PROTOCOL_BAD = 0x04,
36*4882a593Smuzhiyun GB_OP_OVERFLOW = 0x05,
37*4882a593Smuzhiyun GB_OP_INVALID = 0x06,
38*4882a593Smuzhiyun GB_OP_RETRY = 0x07,
39*4882a593Smuzhiyun GB_OP_NONEXISTENT = 0x08,
40*4882a593Smuzhiyun GB_OP_UNKNOWN_ERROR = 0xfe,
41*4882a593Smuzhiyun GB_OP_MALFUNCTION = 0xff,
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define GB_OPERATION_MESSAGE_SIZE_MIN sizeof(struct gb_operation_msg_hdr)
45*4882a593Smuzhiyun #define GB_OPERATION_MESSAGE_SIZE_MAX U16_MAX
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /*
48*4882a593Smuzhiyun * Protocol code should only examine the payload and payload_size fields, and
49*4882a593Smuzhiyun * host-controller drivers may use the hcpriv field. All other fields are
50*4882a593Smuzhiyun * intended to be private to the operations core code.
51*4882a593Smuzhiyun */
52*4882a593Smuzhiyun struct gb_message {
53*4882a593Smuzhiyun struct gb_operation *operation;
54*4882a593Smuzhiyun struct gb_operation_msg_hdr *header;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun void *payload;
57*4882a593Smuzhiyun size_t payload_size;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun void *buffer;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun void *hcpriv;
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #define GB_OPERATION_FLAG_INCOMING BIT(0)
65*4882a593Smuzhiyun #define GB_OPERATION_FLAG_UNIDIRECTIONAL BIT(1)
66*4882a593Smuzhiyun #define GB_OPERATION_FLAG_SHORT_RESPONSE BIT(2)
67*4882a593Smuzhiyun #define GB_OPERATION_FLAG_CORE BIT(3)
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun #define GB_OPERATION_FLAG_USER_MASK (GB_OPERATION_FLAG_SHORT_RESPONSE | \
70*4882a593Smuzhiyun GB_OPERATION_FLAG_UNIDIRECTIONAL)
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /*
73*4882a593Smuzhiyun * A Greybus operation is a remote procedure call performed over a
74*4882a593Smuzhiyun * connection between two UniPro interfaces.
75*4882a593Smuzhiyun *
76*4882a593Smuzhiyun * Every operation consists of a request message sent to the other
77*4882a593Smuzhiyun * end of the connection coupled with a reply message returned to
78*4882a593Smuzhiyun * the sender. Every operation has a type, whose interpretation is
79*4882a593Smuzhiyun * dependent on the protocol associated with the connection.
80*4882a593Smuzhiyun *
81*4882a593Smuzhiyun * Only four things in an operation structure are intended to be
82*4882a593Smuzhiyun * directly usable by protocol handlers: the operation's connection
83*4882a593Smuzhiyun * pointer; the operation type; the request message payload (and
84*4882a593Smuzhiyun * size); and the response message payload (and size). Note that a
85*4882a593Smuzhiyun * message with a 0-byte payload has a null message payload pointer.
86*4882a593Smuzhiyun *
87*4882a593Smuzhiyun * In addition, every operation has a result, which is an errno
88*4882a593Smuzhiyun * value. Protocol handlers access the operation result using
89*4882a593Smuzhiyun * gb_operation_result().
90*4882a593Smuzhiyun */
91*4882a593Smuzhiyun typedef void (*gb_operation_callback)(struct gb_operation *);
92*4882a593Smuzhiyun struct gb_operation {
93*4882a593Smuzhiyun struct gb_connection *connection;
94*4882a593Smuzhiyun struct gb_message *request;
95*4882a593Smuzhiyun struct gb_message *response;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun unsigned long flags;
98*4882a593Smuzhiyun u8 type;
99*4882a593Smuzhiyun u16 id;
100*4882a593Smuzhiyun int errno; /* Operation result */
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun struct work_struct work;
103*4882a593Smuzhiyun gb_operation_callback callback;
104*4882a593Smuzhiyun struct completion completion;
105*4882a593Smuzhiyun struct timer_list timer;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun struct kref kref;
108*4882a593Smuzhiyun atomic_t waiters;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun int active;
111*4882a593Smuzhiyun struct list_head links; /* connection->operations */
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun void *private;
114*4882a593Smuzhiyun };
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun static inline bool
gb_operation_is_incoming(struct gb_operation * operation)117*4882a593Smuzhiyun gb_operation_is_incoming(struct gb_operation *operation)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun return operation->flags & GB_OPERATION_FLAG_INCOMING;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun static inline bool
gb_operation_is_unidirectional(struct gb_operation * operation)123*4882a593Smuzhiyun gb_operation_is_unidirectional(struct gb_operation *operation)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun return operation->flags & GB_OPERATION_FLAG_UNIDIRECTIONAL;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun static inline bool
gb_operation_short_response_allowed(struct gb_operation * operation)129*4882a593Smuzhiyun gb_operation_short_response_allowed(struct gb_operation *operation)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun return operation->flags & GB_OPERATION_FLAG_SHORT_RESPONSE;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
gb_operation_is_core(struct gb_operation * operation)134*4882a593Smuzhiyun static inline bool gb_operation_is_core(struct gb_operation *operation)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun return operation->flags & GB_OPERATION_FLAG_CORE;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun void gb_connection_recv(struct gb_connection *connection,
140*4882a593Smuzhiyun void *data, size_t size);
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun int gb_operation_result(struct gb_operation *operation);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun size_t gb_operation_get_payload_size_max(struct gb_connection *connection);
145*4882a593Smuzhiyun struct gb_operation *
146*4882a593Smuzhiyun gb_operation_create_flags(struct gb_connection *connection,
147*4882a593Smuzhiyun u8 type, size_t request_size,
148*4882a593Smuzhiyun size_t response_size, unsigned long flags,
149*4882a593Smuzhiyun gfp_t gfp);
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun static inline struct gb_operation *
gb_operation_create(struct gb_connection * connection,u8 type,size_t request_size,size_t response_size,gfp_t gfp)152*4882a593Smuzhiyun gb_operation_create(struct gb_connection *connection,
153*4882a593Smuzhiyun u8 type, size_t request_size,
154*4882a593Smuzhiyun size_t response_size, gfp_t gfp)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun return gb_operation_create_flags(connection, type, request_size,
157*4882a593Smuzhiyun response_size, 0, gfp);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun struct gb_operation *
161*4882a593Smuzhiyun gb_operation_create_core(struct gb_connection *connection,
162*4882a593Smuzhiyun u8 type, size_t request_size,
163*4882a593Smuzhiyun size_t response_size, unsigned long flags,
164*4882a593Smuzhiyun gfp_t gfp);
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun void gb_operation_get(struct gb_operation *operation);
167*4882a593Smuzhiyun void gb_operation_put(struct gb_operation *operation);
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun bool gb_operation_response_alloc(struct gb_operation *operation,
170*4882a593Smuzhiyun size_t response_size, gfp_t gfp);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun int gb_operation_request_send(struct gb_operation *operation,
173*4882a593Smuzhiyun gb_operation_callback callback,
174*4882a593Smuzhiyun unsigned int timeout,
175*4882a593Smuzhiyun gfp_t gfp);
176*4882a593Smuzhiyun int gb_operation_request_send_sync_timeout(struct gb_operation *operation,
177*4882a593Smuzhiyun unsigned int timeout);
178*4882a593Smuzhiyun static inline int
gb_operation_request_send_sync(struct gb_operation * operation)179*4882a593Smuzhiyun gb_operation_request_send_sync(struct gb_operation *operation)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun return gb_operation_request_send_sync_timeout(operation,
182*4882a593Smuzhiyun GB_OPERATION_TIMEOUT_DEFAULT);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun void gb_operation_cancel(struct gb_operation *operation, int errno);
186*4882a593Smuzhiyun void gb_operation_cancel_incoming(struct gb_operation *operation, int errno);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun void greybus_message_sent(struct gb_host_device *hd,
189*4882a593Smuzhiyun struct gb_message *message, int status);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun int gb_operation_sync_timeout(struct gb_connection *connection, int type,
192*4882a593Smuzhiyun void *request, int request_size,
193*4882a593Smuzhiyun void *response, int response_size,
194*4882a593Smuzhiyun unsigned int timeout);
195*4882a593Smuzhiyun int gb_operation_unidirectional_timeout(struct gb_connection *connection,
196*4882a593Smuzhiyun int type, void *request, int request_size,
197*4882a593Smuzhiyun unsigned int timeout);
198*4882a593Smuzhiyun
gb_operation_sync(struct gb_connection * connection,int type,void * request,int request_size,void * response,int response_size)199*4882a593Smuzhiyun static inline int gb_operation_sync(struct gb_connection *connection, int type,
200*4882a593Smuzhiyun void *request, int request_size,
201*4882a593Smuzhiyun void *response, int response_size)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun return gb_operation_sync_timeout(connection, type,
204*4882a593Smuzhiyun request, request_size, response, response_size,
205*4882a593Smuzhiyun GB_OPERATION_TIMEOUT_DEFAULT);
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun
gb_operation_unidirectional(struct gb_connection * connection,int type,void * request,int request_size)208*4882a593Smuzhiyun static inline int gb_operation_unidirectional(struct gb_connection *connection,
209*4882a593Smuzhiyun int type, void *request, int request_size)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun return gb_operation_unidirectional_timeout(connection, type,
212*4882a593Smuzhiyun request, request_size, GB_OPERATION_TIMEOUT_DEFAULT);
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
gb_operation_get_data(struct gb_operation * operation)215*4882a593Smuzhiyun static inline void *gb_operation_get_data(struct gb_operation *operation)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun return operation->private;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun
gb_operation_set_data(struct gb_operation * operation,void * data)220*4882a593Smuzhiyun static inline void gb_operation_set_data(struct gb_operation *operation,
221*4882a593Smuzhiyun void *data)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun operation->private = data;
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun int gb_operation_init(void);
227*4882a593Smuzhiyun void gb_operation_exit(void);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun #endif /* !__OPERATION_H */
230