1 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
2 
3 /*
4  * Xen para-virtual sound device
5  *
6  * Copyright (C) 2016-2018 EPAM Systems Inc.
7  *
8  * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
9  */
10 
11 #ifndef __XEN_SND_FRONT_EVTCHNL_H
12 #define __XEN_SND_FRONT_EVTCHNL_H
13 
14 #include <xen/interface/io/sndif.h>
15 
16 struct xen_snd_front_info;
17 
18 #ifndef GRANT_INVALID_REF
19 /*
20  * FIXME: usage of grant reference 0 as invalid grant reference:
21  * grant reference 0 is valid, but never exposed to a PV driver,
22  * because of the fact it is already in use/reserved by the PV console.
23  */
24 #define GRANT_INVALID_REF	0
25 #endif
26 
27 /* Timeout in ms to wait for backend to respond. */
28 #define VSND_WAIT_BACK_MS	3000
29 
30 enum xen_snd_front_evtchnl_state {
31 	EVTCHNL_STATE_DISCONNECTED,
32 	EVTCHNL_STATE_CONNECTED,
33 };
34 
35 enum xen_snd_front_evtchnl_type {
36 	EVTCHNL_TYPE_REQ,
37 	EVTCHNL_TYPE_EVT,
38 };
39 
40 struct xen_snd_front_evtchnl {
41 	struct xen_snd_front_info *front_info;
42 	int gref;
43 	int port;
44 	int irq;
45 	int index;
46 	/* State of the event channel. */
47 	enum xen_snd_front_evtchnl_state state;
48 	enum xen_snd_front_evtchnl_type type;
49 	/* Either response id or incoming event id. */
50 	u16 evt_id;
51 	/* Next request id or next expected event id. */
52 	u16 evt_next_id;
53 	/* Shared ring access lock. */
54 	struct mutex ring_io_lock;
55 	union {
56 		struct {
57 			struct xen_sndif_front_ring ring;
58 			struct completion completion;
59 			/* Serializer for backend IO: request/response. */
60 			struct mutex req_io_lock;
61 
62 			/* Latest response status. */
63 			int resp_status;
64 			union {
65 				struct xensnd_query_hw_param hw_param;
66 			} resp;
67 		} req;
68 		struct {
69 			struct xensnd_event_page *page;
70 			/* This is needed to handle XENSND_EVT_CUR_POS event. */
71 			struct snd_pcm_substream *substream;
72 		} evt;
73 	} u;
74 };
75 
76 struct xen_snd_front_evtchnl_pair {
77 	struct xen_snd_front_evtchnl req;
78 	struct xen_snd_front_evtchnl evt;
79 };
80 
81 int xen_snd_front_evtchnl_create_all(struct xen_snd_front_info *front_info,
82 				     int num_streams);
83 
84 void xen_snd_front_evtchnl_free_all(struct xen_snd_front_info *front_info);
85 
86 int xen_snd_front_evtchnl_publish_all(struct xen_snd_front_info *front_info);
87 
88 void xen_snd_front_evtchnl_flush(struct xen_snd_front_evtchnl *evtchnl);
89 
90 void xen_snd_front_evtchnl_pair_set_connected(struct xen_snd_front_evtchnl_pair *evt_pair,
91 					      bool is_connected);
92 
93 void xen_snd_front_evtchnl_pair_clear(struct xen_snd_front_evtchnl_pair *evt_pair);
94 
95 #endif /* __XEN_SND_FRONT_EVTCHNL_H */
96