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