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 <linux/platform_device.h>
12 
13 #include <sound/core.h>
14 #include <sound/pcm.h>
15 #include <sound/pcm_params.h>
16 
17 #include <xen/xenbus.h>
18 
19 #include "xen_snd_front.h"
20 #include "xen_snd_front_alsa.h"
21 #include "xen_snd_front_cfg.h"
22 #include "xen_snd_front_evtchnl.h"
23 #include "xen_snd_front_shbuf.h"
24 
25 struct xen_snd_front_pcm_stream_info {
26 	struct xen_snd_front_info *front_info;
27 	struct xen_snd_front_evtchnl_pair *evt_pair;
28 	struct xen_snd_front_shbuf sh_buf;
29 	int index;
30 
31 	bool is_open;
32 	struct snd_pcm_hardware pcm_hw;
33 
34 	/* Number of processed frames as reported by the backend. */
35 	snd_pcm_uframes_t be_cur_frame;
36 	/* Current HW pointer to be reported via .period callback. */
37 	atomic_t hw_ptr;
38 	/* Modulo of the number of processed frames - for period detection. */
39 	u32 out_frames;
40 };
41 
42 struct xen_snd_front_pcm_instance_info {
43 	struct xen_snd_front_card_info *card_info;
44 	struct snd_pcm *pcm;
45 	struct snd_pcm_hardware pcm_hw;
46 	int num_pcm_streams_pb;
47 	struct xen_snd_front_pcm_stream_info *streams_pb;
48 	int num_pcm_streams_cap;
49 	struct xen_snd_front_pcm_stream_info *streams_cap;
50 };
51 
52 struct xen_snd_front_card_info {
53 	struct xen_snd_front_info *front_info;
54 	struct snd_card *card;
55 	struct snd_pcm_hardware pcm_hw;
56 	int num_pcm_instances;
57 	struct xen_snd_front_pcm_instance_info *pcm_instances;
58 };
59 
60 struct alsa_sndif_sample_format {
61 	u8 sndif;
62 	snd_pcm_format_t alsa;
63 };
64 
65 struct alsa_sndif_hw_param {
66 	u8 sndif;
67 	snd_pcm_hw_param_t alsa;
68 };
69 
70 static const struct alsa_sndif_sample_format ALSA_SNDIF_FORMATS[] = {
71 	{
72 		.sndif = XENSND_PCM_FORMAT_U8,
73 		.alsa = SNDRV_PCM_FORMAT_U8
74 	},
75 	{
76 		.sndif = XENSND_PCM_FORMAT_S8,
77 		.alsa = SNDRV_PCM_FORMAT_S8
78 	},
79 	{
80 		.sndif = XENSND_PCM_FORMAT_U16_LE,
81 		.alsa = SNDRV_PCM_FORMAT_U16_LE
82 	},
83 	{
84 		.sndif = XENSND_PCM_FORMAT_U16_BE,
85 		.alsa = SNDRV_PCM_FORMAT_U16_BE
86 	},
87 	{
88 		.sndif = XENSND_PCM_FORMAT_S16_LE,
89 		.alsa = SNDRV_PCM_FORMAT_S16_LE
90 	},
91 	{
92 		.sndif = XENSND_PCM_FORMAT_S16_BE,
93 		.alsa = SNDRV_PCM_FORMAT_S16_BE
94 	},
95 	{
96 		.sndif = XENSND_PCM_FORMAT_U24_LE,
97 		.alsa = SNDRV_PCM_FORMAT_U24_LE
98 	},
99 	{
100 		.sndif = XENSND_PCM_FORMAT_U24_BE,
101 		.alsa = SNDRV_PCM_FORMAT_U24_BE
102 	},
103 	{
104 		.sndif = XENSND_PCM_FORMAT_S24_LE,
105 		.alsa = SNDRV_PCM_FORMAT_S24_LE
106 	},
107 	{
108 		.sndif = XENSND_PCM_FORMAT_S24_BE,
109 		.alsa = SNDRV_PCM_FORMAT_S24_BE
110 	},
111 	{
112 		.sndif = XENSND_PCM_FORMAT_U32_LE,
113 		.alsa = SNDRV_PCM_FORMAT_U32_LE
114 	},
115 	{
116 		.sndif = XENSND_PCM_FORMAT_U32_BE,
117 		.alsa = SNDRV_PCM_FORMAT_U32_BE
118 	},
119 	{
120 		.sndif = XENSND_PCM_FORMAT_S32_LE,
121 		.alsa = SNDRV_PCM_FORMAT_S32_LE
122 	},
123 	{
124 		.sndif = XENSND_PCM_FORMAT_S32_BE,
125 		.alsa = SNDRV_PCM_FORMAT_S32_BE
126 	},
127 	{
128 		.sndif = XENSND_PCM_FORMAT_A_LAW,
129 		.alsa = SNDRV_PCM_FORMAT_A_LAW
130 	},
131 	{
132 		.sndif = XENSND_PCM_FORMAT_MU_LAW,
133 		.alsa = SNDRV_PCM_FORMAT_MU_LAW
134 	},
135 	{
136 		.sndif = XENSND_PCM_FORMAT_F32_LE,
137 		.alsa = SNDRV_PCM_FORMAT_FLOAT_LE
138 	},
139 	{
140 		.sndif = XENSND_PCM_FORMAT_F32_BE,
141 		.alsa = SNDRV_PCM_FORMAT_FLOAT_BE
142 	},
143 	{
144 		.sndif = XENSND_PCM_FORMAT_F64_LE,
145 		.alsa = SNDRV_PCM_FORMAT_FLOAT64_LE
146 	},
147 	{
148 		.sndif = XENSND_PCM_FORMAT_F64_BE,
149 		.alsa = SNDRV_PCM_FORMAT_FLOAT64_BE
150 	},
151 	{
152 		.sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE,
153 		.alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
154 	},
155 	{
156 		.sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE,
157 		.alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
158 	},
159 	{
160 		.sndif = XENSND_PCM_FORMAT_IMA_ADPCM,
161 		.alsa = SNDRV_PCM_FORMAT_IMA_ADPCM
162 	},
163 	{
164 		.sndif = XENSND_PCM_FORMAT_MPEG,
165 		.alsa = SNDRV_PCM_FORMAT_MPEG
166 	},
167 	{
168 		.sndif = XENSND_PCM_FORMAT_GSM,
169 		.alsa = SNDRV_PCM_FORMAT_GSM
170 	},
171 };
172 
173 static int to_sndif_format(snd_pcm_format_t format)
174 {
175 	int i;
176 
177 	for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++)
178 		if (ALSA_SNDIF_FORMATS[i].alsa == format)
179 			return ALSA_SNDIF_FORMATS[i].sndif;
180 
181 	return -EINVAL;
182 }
183 
184 static u64 to_sndif_formats_mask(u64 alsa_formats)
185 {
186 	u64 mask;
187 	int i;
188 
189 	mask = 0;
190 	for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++)
191 		if (1 << ALSA_SNDIF_FORMATS[i].alsa & alsa_formats)
192 			mask |= 1 << ALSA_SNDIF_FORMATS[i].sndif;
193 
194 	return mask;
195 }
196 
197 static u64 to_alsa_formats_mask(u64 sndif_formats)
198 {
199 	u64 mask;
200 	int i;
201 
202 	mask = 0;
203 	for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++)
204 		if (1 << ALSA_SNDIF_FORMATS[i].sndif & sndif_formats)
205 			mask |= 1 << ALSA_SNDIF_FORMATS[i].alsa;
206 
207 	return mask;
208 }
209 
210 static void stream_clear(struct xen_snd_front_pcm_stream_info *stream)
211 {
212 	stream->is_open = false;
213 	stream->be_cur_frame = 0;
214 	stream->out_frames = 0;
215 	atomic_set(&stream->hw_ptr, 0);
216 	xen_snd_front_evtchnl_pair_clear(stream->evt_pair);
217 	xen_snd_front_shbuf_clear(&stream->sh_buf);
218 }
219 
220 static void stream_free(struct xen_snd_front_pcm_stream_info *stream)
221 {
222 	xen_snd_front_shbuf_free(&stream->sh_buf);
223 	stream_clear(stream);
224 }
225 
226 static struct xen_snd_front_pcm_stream_info *
227 stream_get(struct snd_pcm_substream *substream)
228 {
229 	struct xen_snd_front_pcm_instance_info *pcm_instance =
230 			snd_pcm_substream_chip(substream);
231 	struct xen_snd_front_pcm_stream_info *stream;
232 
233 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
234 		stream = &pcm_instance->streams_pb[substream->number];
235 	else
236 		stream = &pcm_instance->streams_cap[substream->number];
237 
238 	return stream;
239 }
240 
241 static int alsa_hw_rule(struct snd_pcm_hw_params *params,
242 			struct snd_pcm_hw_rule *rule)
243 {
244 	struct xen_snd_front_pcm_stream_info *stream = rule->private;
245 	struct device *dev = &stream->front_info->xb_dev->dev;
246 	struct snd_mask *formats =
247 			hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
248 	struct snd_interval *rates =
249 			hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
250 	struct snd_interval *channels =
251 			hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
252 	struct snd_interval *period =
253 			hw_param_interval(params,
254 					  SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
255 	struct snd_interval *buffer =
256 			hw_param_interval(params,
257 					  SNDRV_PCM_HW_PARAM_BUFFER_SIZE);
258 	struct xensnd_query_hw_param req;
259 	struct xensnd_query_hw_param resp;
260 	struct snd_interval interval;
261 	struct snd_mask mask;
262 	u64 sndif_formats;
263 	int changed, ret;
264 
265 	/* Collect all the values we need for the query. */
266 
267 	req.formats = to_sndif_formats_mask((u64)formats->bits[0] |
268 					    (u64)(formats->bits[1]) << 32);
269 
270 	req.rates.min = rates->min;
271 	req.rates.max = rates->max;
272 
273 	req.channels.min = channels->min;
274 	req.channels.max = channels->max;
275 
276 	req.buffer.min = buffer->min;
277 	req.buffer.max = buffer->max;
278 
279 	req.period.min = period->min;
280 	req.period.max = period->max;
281 
282 	ret = xen_snd_front_stream_query_hw_param(&stream->evt_pair->req,
283 						  &req, &resp);
284 	if (ret < 0) {
285 		/* Check if this is due to backend communication error. */
286 		if (ret == -EIO || ret == -ETIMEDOUT)
287 			dev_err(dev, "Failed to query ALSA HW parameters\n");
288 		return ret;
289 	}
290 
291 	/* Refine HW parameters after the query. */
292 	changed  = 0;
293 
294 	sndif_formats = to_alsa_formats_mask(resp.formats);
295 	snd_mask_none(&mask);
296 	mask.bits[0] = (u32)sndif_formats;
297 	mask.bits[1] = (u32)(sndif_formats >> 32);
298 	ret = snd_mask_refine(formats, &mask);
299 	if (ret < 0)
300 		return ret;
301 	changed |= ret;
302 
303 	interval.openmin = 0;
304 	interval.openmax = 0;
305 	interval.integer = 1;
306 
307 	interval.min = resp.rates.min;
308 	interval.max = resp.rates.max;
309 	ret = snd_interval_refine(rates, &interval);
310 	if (ret < 0)
311 		return ret;
312 	changed |= ret;
313 
314 	interval.min = resp.channels.min;
315 	interval.max = resp.channels.max;
316 	ret = snd_interval_refine(channels, &interval);
317 	if (ret < 0)
318 		return ret;
319 	changed |= ret;
320 
321 	interval.min = resp.buffer.min;
322 	interval.max = resp.buffer.max;
323 	ret = snd_interval_refine(buffer, &interval);
324 	if (ret < 0)
325 		return ret;
326 	changed |= ret;
327 
328 	interval.min = resp.period.min;
329 	interval.max = resp.period.max;
330 	ret = snd_interval_refine(period, &interval);
331 	if (ret < 0)
332 		return ret;
333 	changed |= ret;
334 
335 	return changed;
336 }
337 
338 static int alsa_open(struct snd_pcm_substream *substream)
339 {
340 	struct xen_snd_front_pcm_instance_info *pcm_instance =
341 			snd_pcm_substream_chip(substream);
342 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
343 	struct snd_pcm_runtime *runtime = substream->runtime;
344 	struct xen_snd_front_info *front_info =
345 			pcm_instance->card_info->front_info;
346 	struct device *dev = &front_info->xb_dev->dev;
347 	int ret;
348 
349 	/*
350 	 * Return our HW properties: override defaults with those configured
351 	 * via XenStore.
352 	 */
353 	runtime->hw = stream->pcm_hw;
354 	runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
355 			      SNDRV_PCM_INFO_MMAP_VALID |
356 			      SNDRV_PCM_INFO_DOUBLE |
357 			      SNDRV_PCM_INFO_BATCH |
358 			      SNDRV_PCM_INFO_NONINTERLEAVED |
359 			      SNDRV_PCM_INFO_RESUME |
360 			      SNDRV_PCM_INFO_PAUSE);
361 	runtime->hw.info |= SNDRV_PCM_INFO_INTERLEAVED;
362 
363 	stream->evt_pair = &front_info->evt_pairs[stream->index];
364 
365 	stream->front_info = front_info;
366 
367 	stream->evt_pair->evt.u.evt.substream = substream;
368 
369 	stream_clear(stream);
370 
371 	xen_snd_front_evtchnl_pair_set_connected(stream->evt_pair, true);
372 
373 	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
374 				  alsa_hw_rule, stream,
375 				  SNDRV_PCM_HW_PARAM_FORMAT, -1);
376 	if (ret) {
377 		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_FORMAT\n");
378 		return ret;
379 	}
380 
381 	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
382 				  alsa_hw_rule, stream,
383 				  SNDRV_PCM_HW_PARAM_RATE, -1);
384 	if (ret) {
385 		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_RATE\n");
386 		return ret;
387 	}
388 
389 	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
390 				  alsa_hw_rule, stream,
391 				  SNDRV_PCM_HW_PARAM_CHANNELS, -1);
392 	if (ret) {
393 		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_CHANNELS\n");
394 		return ret;
395 	}
396 
397 	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
398 				  alsa_hw_rule, stream,
399 				  SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
400 	if (ret) {
401 		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_PERIOD_SIZE\n");
402 		return ret;
403 	}
404 
405 	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
406 				  alsa_hw_rule, stream,
407 				  SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
408 	if (ret) {
409 		dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_BUFFER_SIZE\n");
410 		return ret;
411 	}
412 
413 	return 0;
414 }
415 
416 static int alsa_close(struct snd_pcm_substream *substream)
417 {
418 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
419 
420 	xen_snd_front_evtchnl_pair_set_connected(stream->evt_pair, false);
421 	return 0;
422 }
423 
424 static int alsa_hw_params(struct snd_pcm_substream *substream,
425 			  struct snd_pcm_hw_params *params)
426 {
427 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
428 	int ret;
429 
430 	/*
431 	 * This callback may be called multiple times,
432 	 * so free the previously allocated shared buffer if any.
433 	 */
434 	stream_free(stream);
435 
436 	ret = xen_snd_front_shbuf_alloc(stream->front_info->xb_dev,
437 					&stream->sh_buf,
438 					params_buffer_bytes(params));
439 	if (ret < 0) {
440 		stream_free(stream);
441 		dev_err(&stream->front_info->xb_dev->dev,
442 			"Failed to allocate buffers for stream with index %d\n",
443 			stream->index);
444 		return ret;
445 	}
446 
447 	return 0;
448 }
449 
450 static int alsa_hw_free(struct snd_pcm_substream *substream)
451 {
452 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
453 	int ret;
454 
455 	ret = xen_snd_front_stream_close(&stream->evt_pair->req);
456 	stream_free(stream);
457 	return ret;
458 }
459 
460 static int alsa_prepare(struct snd_pcm_substream *substream)
461 {
462 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
463 
464 	if (!stream->is_open) {
465 		struct snd_pcm_runtime *runtime = substream->runtime;
466 		u8 sndif_format;
467 		int ret;
468 
469 		sndif_format = to_sndif_format(runtime->format);
470 		if (sndif_format < 0) {
471 			dev_err(&stream->front_info->xb_dev->dev,
472 				"Unsupported sample format: %d\n",
473 				runtime->format);
474 			return sndif_format;
475 		}
476 
477 		ret = xen_snd_front_stream_prepare(&stream->evt_pair->req,
478 						   &stream->sh_buf,
479 						   sndif_format,
480 						   runtime->channels,
481 						   runtime->rate,
482 						   snd_pcm_lib_buffer_bytes(substream),
483 						   snd_pcm_lib_period_bytes(substream));
484 		if (ret < 0)
485 			return ret;
486 
487 		stream->is_open = true;
488 	}
489 
490 	return 0;
491 }
492 
493 static int alsa_trigger(struct snd_pcm_substream *substream, int cmd)
494 {
495 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
496 	int type;
497 
498 	switch (cmd) {
499 	case SNDRV_PCM_TRIGGER_START:
500 		type = XENSND_OP_TRIGGER_START;
501 		break;
502 
503 	case SNDRV_PCM_TRIGGER_RESUME:
504 		type = XENSND_OP_TRIGGER_RESUME;
505 		break;
506 
507 	case SNDRV_PCM_TRIGGER_STOP:
508 		type = XENSND_OP_TRIGGER_STOP;
509 		break;
510 
511 	case SNDRV_PCM_TRIGGER_SUSPEND:
512 		type = XENSND_OP_TRIGGER_PAUSE;
513 		break;
514 
515 	default:
516 		return -EINVAL;
517 	}
518 
519 	return xen_snd_front_stream_trigger(&stream->evt_pair->req, type);
520 }
521 
522 void xen_snd_front_alsa_handle_cur_pos(struct xen_snd_front_evtchnl *evtchnl,
523 				       u64 pos_bytes)
524 {
525 	struct snd_pcm_substream *substream = evtchnl->u.evt.substream;
526 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
527 	snd_pcm_uframes_t delta, new_hw_ptr, cur_frame;
528 
529 	cur_frame = bytes_to_frames(substream->runtime, pos_bytes);
530 
531 	delta = cur_frame - stream->be_cur_frame;
532 	stream->be_cur_frame = cur_frame;
533 
534 	new_hw_ptr = (snd_pcm_uframes_t)atomic_read(&stream->hw_ptr);
535 	new_hw_ptr = (new_hw_ptr + delta) % substream->runtime->buffer_size;
536 	atomic_set(&stream->hw_ptr, (int)new_hw_ptr);
537 
538 	stream->out_frames += delta;
539 	if (stream->out_frames > substream->runtime->period_size) {
540 		stream->out_frames %= substream->runtime->period_size;
541 		snd_pcm_period_elapsed(substream);
542 	}
543 }
544 
545 static snd_pcm_uframes_t alsa_pointer(struct snd_pcm_substream *substream)
546 {
547 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
548 
549 	return (snd_pcm_uframes_t)atomic_read(&stream->hw_ptr);
550 }
551 
552 static int alsa_pb_copy_user(struct snd_pcm_substream *substream,
553 			     int channel, unsigned long pos, void __user *src,
554 			     unsigned long count)
555 {
556 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
557 
558 	if (unlikely(pos + count > stream->sh_buf.buffer_sz))
559 		return -EINVAL;
560 
561 	if (copy_from_user(stream->sh_buf.buffer + pos, src, count))
562 		return -EFAULT;
563 
564 	return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count);
565 }
566 
567 static int alsa_pb_copy_kernel(struct snd_pcm_substream *substream,
568 			       int channel, unsigned long pos, void *src,
569 			       unsigned long count)
570 {
571 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
572 
573 	if (unlikely(pos + count > stream->sh_buf.buffer_sz))
574 		return -EINVAL;
575 
576 	memcpy(stream->sh_buf.buffer + pos, src, count);
577 
578 	return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count);
579 }
580 
581 static int alsa_cap_copy_user(struct snd_pcm_substream *substream,
582 			      int channel, unsigned long pos, void __user *dst,
583 			      unsigned long count)
584 {
585 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
586 	int ret;
587 
588 	if (unlikely(pos + count > stream->sh_buf.buffer_sz))
589 		return -EINVAL;
590 
591 	ret = xen_snd_front_stream_read(&stream->evt_pair->req, pos, count);
592 	if (ret < 0)
593 		return ret;
594 
595 	return copy_to_user(dst, stream->sh_buf.buffer + pos, count) ?
596 		-EFAULT : 0;
597 }
598 
599 static int alsa_cap_copy_kernel(struct snd_pcm_substream *substream,
600 				int channel, unsigned long pos, void *dst,
601 				unsigned long count)
602 {
603 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
604 	int ret;
605 
606 	if (unlikely(pos + count > stream->sh_buf.buffer_sz))
607 		return -EINVAL;
608 
609 	ret = xen_snd_front_stream_read(&stream->evt_pair->req, pos, count);
610 	if (ret < 0)
611 		return ret;
612 
613 	memcpy(dst, stream->sh_buf.buffer + pos, count);
614 
615 	return 0;
616 }
617 
618 static int alsa_pb_fill_silence(struct snd_pcm_substream *substream,
619 				int channel, unsigned long pos,
620 				unsigned long count)
621 {
622 	struct xen_snd_front_pcm_stream_info *stream = stream_get(substream);
623 
624 	if (unlikely(pos + count > stream->sh_buf.buffer_sz))
625 		return -EINVAL;
626 
627 	memset(stream->sh_buf.buffer + pos, 0, count);
628 
629 	return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count);
630 }
631 
632 /*
633  * FIXME: The mmaped data transfer is asynchronous and there is no
634  * ack signal from user-space when it is done. This is the
635  * reason it is not implemented in the PV driver as we do need
636  * to know when the buffer can be transferred to the backend.
637  */
638 
639 static struct snd_pcm_ops snd_drv_alsa_playback_ops = {
640 	.open = alsa_open,
641 	.close = alsa_close,
642 	.ioctl = snd_pcm_lib_ioctl,
643 	.hw_params = alsa_hw_params,
644 	.hw_free = alsa_hw_free,
645 	.prepare = alsa_prepare,
646 	.trigger = alsa_trigger,
647 	.pointer = alsa_pointer,
648 	.copy_user = alsa_pb_copy_user,
649 	.copy_kernel = alsa_pb_copy_kernel,
650 	.fill_silence = alsa_pb_fill_silence,
651 };
652 
653 static struct snd_pcm_ops snd_drv_alsa_capture_ops = {
654 	.open = alsa_open,
655 	.close = alsa_close,
656 	.ioctl = snd_pcm_lib_ioctl,
657 	.hw_params = alsa_hw_params,
658 	.hw_free = alsa_hw_free,
659 	.prepare = alsa_prepare,
660 	.trigger = alsa_trigger,
661 	.pointer = alsa_pointer,
662 	.copy_user = alsa_cap_copy_user,
663 	.copy_kernel = alsa_cap_copy_kernel,
664 };
665 
666 static int new_pcm_instance(struct xen_snd_front_card_info *card_info,
667 			    struct xen_front_cfg_pcm_instance *instance_cfg,
668 			    struct xen_snd_front_pcm_instance_info *pcm_instance_info)
669 {
670 	struct snd_pcm *pcm;
671 	int ret, i;
672 
673 	dev_dbg(&card_info->front_info->xb_dev->dev,
674 		"New PCM device \"%s\" with id %d playback %d capture %d",
675 		instance_cfg->name,
676 		instance_cfg->device_id,
677 		instance_cfg->num_streams_pb,
678 		instance_cfg->num_streams_cap);
679 
680 	pcm_instance_info->card_info = card_info;
681 
682 	pcm_instance_info->pcm_hw = instance_cfg->pcm_hw;
683 
684 	if (instance_cfg->num_streams_pb) {
685 		pcm_instance_info->streams_pb =
686 				devm_kcalloc(&card_info->card->card_dev,
687 					     instance_cfg->num_streams_pb,
688 					     sizeof(struct xen_snd_front_pcm_stream_info),
689 					     GFP_KERNEL);
690 		if (!pcm_instance_info->streams_pb)
691 			return -ENOMEM;
692 	}
693 
694 	if (instance_cfg->num_streams_cap) {
695 		pcm_instance_info->streams_cap =
696 				devm_kcalloc(&card_info->card->card_dev,
697 					     instance_cfg->num_streams_cap,
698 					     sizeof(struct xen_snd_front_pcm_stream_info),
699 					     GFP_KERNEL);
700 		if (!pcm_instance_info->streams_cap)
701 			return -ENOMEM;
702 	}
703 
704 	pcm_instance_info->num_pcm_streams_pb =
705 			instance_cfg->num_streams_pb;
706 	pcm_instance_info->num_pcm_streams_cap =
707 			instance_cfg->num_streams_cap;
708 
709 	for (i = 0; i < pcm_instance_info->num_pcm_streams_pb; i++) {
710 		pcm_instance_info->streams_pb[i].pcm_hw =
711 			instance_cfg->streams_pb[i].pcm_hw;
712 		pcm_instance_info->streams_pb[i].index =
713 			instance_cfg->streams_pb[i].index;
714 	}
715 
716 	for (i = 0; i < pcm_instance_info->num_pcm_streams_cap; i++) {
717 		pcm_instance_info->streams_cap[i].pcm_hw =
718 			instance_cfg->streams_cap[i].pcm_hw;
719 		pcm_instance_info->streams_cap[i].index =
720 			instance_cfg->streams_cap[i].index;
721 	}
722 
723 	ret = snd_pcm_new(card_info->card, instance_cfg->name,
724 			  instance_cfg->device_id,
725 			  instance_cfg->num_streams_pb,
726 			  instance_cfg->num_streams_cap,
727 			  &pcm);
728 	if (ret < 0)
729 		return ret;
730 
731 	pcm->private_data = pcm_instance_info;
732 	pcm->info_flags = 0;
733 	/* we want to handle all PCM operations in non-atomic context */
734 	pcm->nonatomic = true;
735 	strncpy(pcm->name, "Virtual card PCM", sizeof(pcm->name));
736 
737 	if (instance_cfg->num_streams_pb)
738 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
739 				&snd_drv_alsa_playback_ops);
740 
741 	if (instance_cfg->num_streams_cap)
742 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
743 				&snd_drv_alsa_capture_ops);
744 
745 	pcm_instance_info->pcm = pcm;
746 	return 0;
747 }
748 
749 int xen_snd_front_alsa_init(struct xen_snd_front_info *front_info)
750 {
751 	struct device *dev = &front_info->xb_dev->dev;
752 	struct xen_front_cfg_card *cfg = &front_info->cfg;
753 	struct xen_snd_front_card_info *card_info;
754 	struct snd_card *card;
755 	int ret, i;
756 
757 	dev_dbg(dev, "Creating virtual sound card\n");
758 
759 	ret = snd_card_new(dev, 0, XENSND_DRIVER_NAME, THIS_MODULE,
760 			   sizeof(struct xen_snd_front_card_info), &card);
761 	if (ret < 0)
762 		return ret;
763 
764 	card_info = card->private_data;
765 	card_info->front_info = front_info;
766 	front_info->card_info = card_info;
767 	card_info->card = card;
768 	card_info->pcm_instances =
769 			devm_kcalloc(dev, cfg->num_pcm_instances,
770 				     sizeof(struct xen_snd_front_pcm_instance_info),
771 				     GFP_KERNEL);
772 	if (!card_info->pcm_instances) {
773 		ret = -ENOMEM;
774 		goto fail;
775 	}
776 
777 	card_info->num_pcm_instances = cfg->num_pcm_instances;
778 	card_info->pcm_hw = cfg->pcm_hw;
779 
780 	for (i = 0; i < cfg->num_pcm_instances; i++) {
781 		ret = new_pcm_instance(card_info, &cfg->pcm_instances[i],
782 				       &card_info->pcm_instances[i]);
783 		if (ret < 0)
784 			goto fail;
785 	}
786 
787 	strncpy(card->driver, XENSND_DRIVER_NAME, sizeof(card->driver));
788 	strncpy(card->shortname, cfg->name_short, sizeof(card->shortname));
789 	strncpy(card->longname, cfg->name_long, sizeof(card->longname));
790 
791 	ret = snd_card_register(card);
792 	if (ret < 0)
793 		goto fail;
794 
795 	return 0;
796 
797 fail:
798 	snd_card_free(card);
799 	return ret;
800 }
801 
802 void xen_snd_front_alsa_fini(struct xen_snd_front_info *front_info)
803 {
804 	struct xen_snd_front_card_info *card_info;
805 	struct snd_card *card;
806 
807 	card_info = front_info->card_info;
808 	if (!card_info)
809 		return;
810 
811 	card = card_info->card;
812 	if (!card)
813 		return;
814 
815 	dev_dbg(&front_info->xb_dev->dev, "Removing virtual sound card %d\n",
816 		card->number);
817 	snd_card_free(card);
818 
819 	/* Card_info will be freed when destroying front_info->xb_dev->dev. */
820 	card_info->card = NULL;
821 }
822