xref: /linux/sound/xen/xen_snd_front_evtchnl.c (revision bfd5bb6f90af092aa345b15cd78143956a13c2a8)
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 #include <xen/events.h>
12 #include <xen/grant_table.h>
13 #include <xen/xen.h>
14 #include <xen/xenbus.h>
15 
16 #include "xen_snd_front.h"
17 #include "xen_snd_front_alsa.h"
18 #include "xen_snd_front_cfg.h"
19 #include "xen_snd_front_evtchnl.h"
20 
21 static irqreturn_t evtchnl_interrupt_req(int irq, void *dev_id)
22 {
23 	struct xen_snd_front_evtchnl *channel = dev_id;
24 	struct xen_snd_front_info *front_info = channel->front_info;
25 	struct xensnd_resp *resp;
26 	RING_IDX i, rp;
27 
28 	if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
29 		return IRQ_HANDLED;
30 
31 	mutex_lock(&channel->ring_io_lock);
32 
33 again:
34 	rp = channel->u.req.ring.sring->rsp_prod;
35 	/* Ensure we see queued responses up to rp. */
36 	rmb();
37 
38 	/*
39 	 * Assume that the backend is trusted to always write sane values
40 	 * to the ring counters, so no overflow checks on frontend side
41 	 * are required.
42 	 */
43 	for (i = channel->u.req.ring.rsp_cons; i != rp; i++) {
44 		resp = RING_GET_RESPONSE(&channel->u.req.ring, i);
45 		if (resp->id != channel->evt_id)
46 			continue;
47 		switch (resp->operation) {
48 		case XENSND_OP_OPEN:
49 			/* fall through */
50 		case XENSND_OP_CLOSE:
51 			/* fall through */
52 		case XENSND_OP_READ:
53 			/* fall through */
54 		case XENSND_OP_WRITE:
55 			/* fall through */
56 		case XENSND_OP_TRIGGER:
57 			channel->u.req.resp_status = resp->status;
58 			complete(&channel->u.req.completion);
59 			break;
60 		case XENSND_OP_HW_PARAM_QUERY:
61 			channel->u.req.resp_status = resp->status;
62 			channel->u.req.resp.hw_param =
63 					resp->resp.hw_param;
64 			complete(&channel->u.req.completion);
65 			break;
66 
67 		default:
68 			dev_err(&front_info->xb_dev->dev,
69 				"Operation %d is not supported\n",
70 				resp->operation);
71 			break;
72 		}
73 	}
74 
75 	channel->u.req.ring.rsp_cons = i;
76 	if (i != channel->u.req.ring.req_prod_pvt) {
77 		int more_to_do;
78 
79 		RING_FINAL_CHECK_FOR_RESPONSES(&channel->u.req.ring,
80 					       more_to_do);
81 		if (more_to_do)
82 			goto again;
83 	} else {
84 		channel->u.req.ring.sring->rsp_event = i + 1;
85 	}
86 
87 	mutex_unlock(&channel->ring_io_lock);
88 	return IRQ_HANDLED;
89 }
90 
91 static irqreturn_t evtchnl_interrupt_evt(int irq, void *dev_id)
92 {
93 	struct xen_snd_front_evtchnl *channel = dev_id;
94 	struct xensnd_event_page *page = channel->u.evt.page;
95 	u32 cons, prod;
96 
97 	if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED))
98 		return IRQ_HANDLED;
99 
100 	mutex_lock(&channel->ring_io_lock);
101 
102 	prod = page->in_prod;
103 	/* Ensure we see ring contents up to prod. */
104 	virt_rmb();
105 	if (prod == page->in_cons)
106 		goto out;
107 
108 	/*
109 	 * Assume that the backend is trusted to always write sane values
110 	 * to the ring counters, so no overflow checks on frontend side
111 	 * are required.
112 	 */
113 	for (cons = page->in_cons; cons != prod; cons++) {
114 		struct xensnd_evt *event;
115 
116 		event = &XENSND_IN_RING_REF(page, cons);
117 		if (unlikely(event->id != channel->evt_id++))
118 			continue;
119 
120 		switch (event->type) {
121 		case XENSND_EVT_CUR_POS:
122 			xen_snd_front_alsa_handle_cur_pos(channel,
123 							  event->op.cur_pos.position);
124 			break;
125 		}
126 	}
127 
128 	page->in_cons = cons;
129 	/* Ensure ring contents. */
130 	virt_wmb();
131 
132 out:
133 	mutex_unlock(&channel->ring_io_lock);
134 	return IRQ_HANDLED;
135 }
136 
137 void xen_snd_front_evtchnl_flush(struct xen_snd_front_evtchnl *channel)
138 {
139 	int notify;
140 
141 	channel->u.req.ring.req_prod_pvt++;
142 	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&channel->u.req.ring, notify);
143 	if (notify)
144 		notify_remote_via_irq(channel->irq);
145 }
146 
147 static void evtchnl_free(struct xen_snd_front_info *front_info,
148 			 struct xen_snd_front_evtchnl *channel)
149 {
150 	unsigned long page = 0;
151 
152 	if (channel->type == EVTCHNL_TYPE_REQ)
153 		page = (unsigned long)channel->u.req.ring.sring;
154 	else if (channel->type == EVTCHNL_TYPE_EVT)
155 		page = (unsigned long)channel->u.evt.page;
156 
157 	if (!page)
158 		return;
159 
160 	channel->state = EVTCHNL_STATE_DISCONNECTED;
161 	if (channel->type == EVTCHNL_TYPE_REQ) {
162 		/* Release all who still waits for response if any. */
163 		channel->u.req.resp_status = -EIO;
164 		complete_all(&channel->u.req.completion);
165 	}
166 
167 	if (channel->irq)
168 		unbind_from_irqhandler(channel->irq, channel);
169 
170 	if (channel->port)
171 		xenbus_free_evtchn(front_info->xb_dev, channel->port);
172 
173 	/* End access and free the page. */
174 	if (channel->gref != GRANT_INVALID_REF)
175 		gnttab_end_foreign_access(channel->gref, 0, page);
176 	else
177 		free_page(page);
178 
179 	memset(channel, 0, sizeof(*channel));
180 }
181 
182 void xen_snd_front_evtchnl_free_all(struct xen_snd_front_info *front_info)
183 {
184 	int i;
185 
186 	if (!front_info->evt_pairs)
187 		return;
188 
189 	for (i = 0; i < front_info->num_evt_pairs; i++) {
190 		evtchnl_free(front_info, &front_info->evt_pairs[i].req);
191 		evtchnl_free(front_info, &front_info->evt_pairs[i].evt);
192 	}
193 
194 	kfree(front_info->evt_pairs);
195 	front_info->evt_pairs = NULL;
196 }
197 
198 static int evtchnl_alloc(struct xen_snd_front_info *front_info, int index,
199 			 struct xen_snd_front_evtchnl *channel,
200 			 enum xen_snd_front_evtchnl_type type)
201 {
202 	struct xenbus_device *xb_dev = front_info->xb_dev;
203 	unsigned long page;
204 	grant_ref_t gref;
205 	irq_handler_t handler;
206 	char *handler_name = NULL;
207 	int ret;
208 
209 	memset(channel, 0, sizeof(*channel));
210 	channel->type = type;
211 	channel->index = index;
212 	channel->front_info = front_info;
213 	channel->state = EVTCHNL_STATE_DISCONNECTED;
214 	channel->gref = GRANT_INVALID_REF;
215 	page = get_zeroed_page(GFP_KERNEL);
216 	if (!page) {
217 		ret = -ENOMEM;
218 		goto fail;
219 	}
220 
221 	handler_name = kasprintf(GFP_KERNEL, "%s-%s", XENSND_DRIVER_NAME,
222 				 type == EVTCHNL_TYPE_REQ ?
223 				 XENSND_FIELD_RING_REF :
224 				 XENSND_FIELD_EVT_RING_REF);
225 	if (!handler_name) {
226 		ret = -ENOMEM;
227 		goto fail;
228 	}
229 
230 	mutex_init(&channel->ring_io_lock);
231 
232 	if (type == EVTCHNL_TYPE_REQ) {
233 		struct xen_sndif_sring *sring = (struct xen_sndif_sring *)page;
234 
235 		init_completion(&channel->u.req.completion);
236 		mutex_init(&channel->u.req.req_io_lock);
237 		SHARED_RING_INIT(sring);
238 		FRONT_RING_INIT(&channel->u.req.ring, sring, XEN_PAGE_SIZE);
239 
240 		ret = xenbus_grant_ring(xb_dev, sring, 1, &gref);
241 		if (ret < 0) {
242 			channel->u.req.ring.sring = NULL;
243 			goto fail;
244 		}
245 
246 		handler = evtchnl_interrupt_req;
247 	} else {
248 		ret = gnttab_grant_foreign_access(xb_dev->otherend_id,
249 						  virt_to_gfn((void *)page), 0);
250 		if (ret < 0)
251 			goto fail;
252 
253 		channel->u.evt.page = (struct xensnd_event_page *)page;
254 		gref = ret;
255 		handler = evtchnl_interrupt_evt;
256 	}
257 
258 	channel->gref = gref;
259 
260 	ret = xenbus_alloc_evtchn(xb_dev, &channel->port);
261 	if (ret < 0)
262 		goto fail;
263 
264 	ret = bind_evtchn_to_irq(channel->port);
265 	if (ret < 0) {
266 		dev_err(&xb_dev->dev,
267 			"Failed to bind IRQ for domid %d port %d: %d\n",
268 			front_info->xb_dev->otherend_id, channel->port, ret);
269 		goto fail;
270 	}
271 
272 	channel->irq = ret;
273 
274 	ret = request_threaded_irq(channel->irq, NULL, handler,
275 				   IRQF_ONESHOT, handler_name, channel);
276 	if (ret < 0) {
277 		dev_err(&xb_dev->dev, "Failed to request IRQ %d: %d\n",
278 			channel->irq, ret);
279 		goto fail;
280 	}
281 
282 	kfree(handler_name);
283 	return 0;
284 
285 fail:
286 	if (page)
287 		free_page(page);
288 	kfree(handler_name);
289 	dev_err(&xb_dev->dev, "Failed to allocate ring: %d\n", ret);
290 	return ret;
291 }
292 
293 int xen_snd_front_evtchnl_create_all(struct xen_snd_front_info *front_info,
294 				     int num_streams)
295 {
296 	struct xen_front_cfg_card *cfg = &front_info->cfg;
297 	struct device *dev = &front_info->xb_dev->dev;
298 	int d, ret = 0;
299 
300 	front_info->evt_pairs =
301 			kcalloc(num_streams,
302 				sizeof(struct xen_snd_front_evtchnl_pair),
303 				GFP_KERNEL);
304 	if (!front_info->evt_pairs)
305 		return -ENOMEM;
306 
307 	/* Iterate over devices and their streams and create event channels. */
308 	for (d = 0; d < cfg->num_pcm_instances; d++) {
309 		struct xen_front_cfg_pcm_instance *pcm_instance;
310 		int s, index;
311 
312 		pcm_instance = &cfg->pcm_instances[d];
313 
314 		for (s = 0; s < pcm_instance->num_streams_pb; s++) {
315 			index = pcm_instance->streams_pb[s].index;
316 
317 			ret = evtchnl_alloc(front_info, index,
318 					    &front_info->evt_pairs[index].req,
319 					    EVTCHNL_TYPE_REQ);
320 			if (ret < 0) {
321 				dev_err(dev, "Error allocating control channel\n");
322 				goto fail;
323 			}
324 
325 			ret = evtchnl_alloc(front_info, index,
326 					    &front_info->evt_pairs[index].evt,
327 					    EVTCHNL_TYPE_EVT);
328 			if (ret < 0) {
329 				dev_err(dev, "Error allocating in-event channel\n");
330 				goto fail;
331 			}
332 		}
333 
334 		for (s = 0; s < pcm_instance->num_streams_cap; s++) {
335 			index = pcm_instance->streams_cap[s].index;
336 
337 			ret = evtchnl_alloc(front_info, index,
338 					    &front_info->evt_pairs[index].req,
339 					    EVTCHNL_TYPE_REQ);
340 			if (ret < 0) {
341 				dev_err(dev, "Error allocating control channel\n");
342 				goto fail;
343 			}
344 
345 			ret = evtchnl_alloc(front_info, index,
346 					    &front_info->evt_pairs[index].evt,
347 					    EVTCHNL_TYPE_EVT);
348 			if (ret < 0) {
349 				dev_err(dev, "Error allocating in-event channel\n");
350 				goto fail;
351 			}
352 		}
353 	}
354 
355 	front_info->num_evt_pairs = num_streams;
356 	return 0;
357 
358 fail:
359 	xen_snd_front_evtchnl_free_all(front_info);
360 	return ret;
361 }
362 
363 static int evtchnl_publish(struct xenbus_transaction xbt,
364 			   struct xen_snd_front_evtchnl *channel,
365 			   const char *path, const char *node_ring,
366 			   const char *node_chnl)
367 {
368 	struct xenbus_device *xb_dev = channel->front_info->xb_dev;
369 	int ret;
370 
371 	/* Write control channel ring reference. */
372 	ret = xenbus_printf(xbt, path, node_ring, "%u", channel->gref);
373 	if (ret < 0) {
374 		dev_err(&xb_dev->dev, "Error writing ring-ref: %d\n", ret);
375 		return ret;
376 	}
377 
378 	/* Write event channel ring reference. */
379 	ret = xenbus_printf(xbt, path, node_chnl, "%u", channel->port);
380 	if (ret < 0) {
381 		dev_err(&xb_dev->dev, "Error writing event channel: %d\n", ret);
382 		return ret;
383 	}
384 
385 	return 0;
386 }
387 
388 int xen_snd_front_evtchnl_publish_all(struct xen_snd_front_info *front_info)
389 {
390 	struct xen_front_cfg_card *cfg = &front_info->cfg;
391 	struct xenbus_transaction xbt;
392 	int ret, d;
393 
394 again:
395 	ret = xenbus_transaction_start(&xbt);
396 	if (ret < 0) {
397 		xenbus_dev_fatal(front_info->xb_dev, ret,
398 				 "starting transaction");
399 		return ret;
400 	}
401 
402 	for (d = 0; d < cfg->num_pcm_instances; d++) {
403 		struct xen_front_cfg_pcm_instance *pcm_instance;
404 		int s, index;
405 
406 		pcm_instance = &cfg->pcm_instances[d];
407 
408 		for (s = 0; s < pcm_instance->num_streams_pb; s++) {
409 			index = pcm_instance->streams_pb[s].index;
410 
411 			ret = evtchnl_publish(xbt,
412 					      &front_info->evt_pairs[index].req,
413 					      pcm_instance->streams_pb[s].xenstore_path,
414 					      XENSND_FIELD_RING_REF,
415 					      XENSND_FIELD_EVT_CHNL);
416 			if (ret < 0)
417 				goto fail;
418 
419 			ret = evtchnl_publish(xbt,
420 					      &front_info->evt_pairs[index].evt,
421 					      pcm_instance->streams_pb[s].xenstore_path,
422 					      XENSND_FIELD_EVT_RING_REF,
423 					      XENSND_FIELD_EVT_EVT_CHNL);
424 			if (ret < 0)
425 				goto fail;
426 		}
427 
428 		for (s = 0; s < pcm_instance->num_streams_cap; s++) {
429 			index = pcm_instance->streams_cap[s].index;
430 
431 			ret = evtchnl_publish(xbt,
432 					      &front_info->evt_pairs[index].req,
433 					      pcm_instance->streams_cap[s].xenstore_path,
434 					      XENSND_FIELD_RING_REF,
435 					      XENSND_FIELD_EVT_CHNL);
436 			if (ret < 0)
437 				goto fail;
438 
439 			ret = evtchnl_publish(xbt,
440 					      &front_info->evt_pairs[index].evt,
441 					      pcm_instance->streams_cap[s].xenstore_path,
442 					      XENSND_FIELD_EVT_RING_REF,
443 					      XENSND_FIELD_EVT_EVT_CHNL);
444 			if (ret < 0)
445 				goto fail;
446 		}
447 	}
448 	ret = xenbus_transaction_end(xbt, 0);
449 	if (ret < 0) {
450 		if (ret == -EAGAIN)
451 			goto again;
452 
453 		xenbus_dev_fatal(front_info->xb_dev, ret,
454 				 "completing transaction");
455 		goto fail_to_end;
456 	}
457 	return 0;
458 fail:
459 	xenbus_transaction_end(xbt, 1);
460 fail_to_end:
461 	xenbus_dev_fatal(front_info->xb_dev, ret, "writing XenStore");
462 	return ret;
463 }
464 
465 void xen_snd_front_evtchnl_pair_set_connected(struct xen_snd_front_evtchnl_pair *evt_pair,
466 					      bool is_connected)
467 {
468 	enum xen_snd_front_evtchnl_state state;
469 
470 	if (is_connected)
471 		state = EVTCHNL_STATE_CONNECTED;
472 	else
473 		state = EVTCHNL_STATE_DISCONNECTED;
474 
475 	mutex_lock(&evt_pair->req.ring_io_lock);
476 	evt_pair->req.state = state;
477 	mutex_unlock(&evt_pair->req.ring_io_lock);
478 
479 	mutex_lock(&evt_pair->evt.ring_io_lock);
480 	evt_pair->evt.state = state;
481 	mutex_unlock(&evt_pair->evt.ring_io_lock);
482 }
483 
484 void xen_snd_front_evtchnl_pair_clear(struct xen_snd_front_evtchnl_pair *evt_pair)
485 {
486 	mutex_lock(&evt_pair->req.ring_io_lock);
487 	evt_pair->req.evt_next_id = 0;
488 	mutex_unlock(&evt_pair->req.ring_io_lock);
489 
490 	mutex_lock(&evt_pair->evt.ring_io_lock);
491 	evt_pair->evt.evt_next_id = 0;
492 	mutex_unlock(&evt_pair->evt.ring_io_lock);
493 }
494 
495