cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

operation.h (6686B)


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