virtio_pcm_ops.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * virtio-snd: Virtio sound device
  4. * Copyright (C) 2021 OpenSynergy GmbH
  5. */
  6. #include <sound/pcm_params.h>
  7. #include "virtio_card.h"
  8. /*
  9. * I/O messages lifetime
  10. * ---------------------
  11. *
  12. * Allocation:
  13. * Messages are initially allocated in the ops->hw_params() after the size and
  14. * number of periods have been successfully negotiated.
  15. *
  16. * Freeing:
  17. * Messages can be safely freed after the queue has been successfully flushed
  18. * (RELEASE command in the ops->sync_stop()) and the ops->hw_free() has been
  19. * called.
  20. *
  21. * When the substream stops, the ops->sync_stop() waits until the device has
  22. * completed all pending messages. This wait can be interrupted either by a
  23. * signal or due to a timeout. In this case, the device can still access
  24. * messages even after calling ops->hw_free(). It can also issue an interrupt,
  25. * and the interrupt handler will also try to access message structures.
  26. *
  27. * Therefore, freeing of already allocated messages occurs:
  28. *
  29. * - in ops->hw_params(), if this operator was called several times in a row,
  30. * or if ops->hw_free() failed to free messages previously;
  31. *
  32. * - in ops->hw_free(), if the queue has been successfully flushed;
  33. *
  34. * - in dev->release().
  35. */
  36. /* Map for converting ALSA format to VirtIO format. */
  37. struct virtsnd_a2v_format {
  38. snd_pcm_format_t alsa_bit;
  39. unsigned int vio_bit;
  40. };
  41. static const struct virtsnd_a2v_format g_a2v_format_map[] = {
  42. { SNDRV_PCM_FORMAT_IMA_ADPCM, VIRTIO_SND_PCM_FMT_IMA_ADPCM },
  43. { SNDRV_PCM_FORMAT_MU_LAW, VIRTIO_SND_PCM_FMT_MU_LAW },
  44. { SNDRV_PCM_FORMAT_A_LAW, VIRTIO_SND_PCM_FMT_A_LAW },
  45. { SNDRV_PCM_FORMAT_S8, VIRTIO_SND_PCM_FMT_S8 },
  46. { SNDRV_PCM_FORMAT_U8, VIRTIO_SND_PCM_FMT_U8 },
  47. { SNDRV_PCM_FORMAT_S16_LE, VIRTIO_SND_PCM_FMT_S16 },
  48. { SNDRV_PCM_FORMAT_U16_LE, VIRTIO_SND_PCM_FMT_U16 },
  49. { SNDRV_PCM_FORMAT_S18_3LE, VIRTIO_SND_PCM_FMT_S18_3 },
  50. { SNDRV_PCM_FORMAT_U18_3LE, VIRTIO_SND_PCM_FMT_U18_3 },
  51. { SNDRV_PCM_FORMAT_S20_3LE, VIRTIO_SND_PCM_FMT_S20_3 },
  52. { SNDRV_PCM_FORMAT_U20_3LE, VIRTIO_SND_PCM_FMT_U20_3 },
  53. { SNDRV_PCM_FORMAT_S24_3LE, VIRTIO_SND_PCM_FMT_S24_3 },
  54. { SNDRV_PCM_FORMAT_U24_3LE, VIRTIO_SND_PCM_FMT_U24_3 },
  55. { SNDRV_PCM_FORMAT_S20_LE, VIRTIO_SND_PCM_FMT_S20 },
  56. { SNDRV_PCM_FORMAT_U20_LE, VIRTIO_SND_PCM_FMT_U20 },
  57. { SNDRV_PCM_FORMAT_S24_LE, VIRTIO_SND_PCM_FMT_S24 },
  58. { SNDRV_PCM_FORMAT_U24_LE, VIRTIO_SND_PCM_FMT_U24 },
  59. { SNDRV_PCM_FORMAT_S32_LE, VIRTIO_SND_PCM_FMT_S32 },
  60. { SNDRV_PCM_FORMAT_U32_LE, VIRTIO_SND_PCM_FMT_U32 },
  61. { SNDRV_PCM_FORMAT_FLOAT_LE, VIRTIO_SND_PCM_FMT_FLOAT },
  62. { SNDRV_PCM_FORMAT_FLOAT64_LE, VIRTIO_SND_PCM_FMT_FLOAT64 },
  63. { SNDRV_PCM_FORMAT_DSD_U8, VIRTIO_SND_PCM_FMT_DSD_U8 },
  64. { SNDRV_PCM_FORMAT_DSD_U16_LE, VIRTIO_SND_PCM_FMT_DSD_U16 },
  65. { SNDRV_PCM_FORMAT_DSD_U32_LE, VIRTIO_SND_PCM_FMT_DSD_U32 },
  66. { SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE,
  67. VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME }
  68. };
  69. /* Map for converting ALSA frame rate to VirtIO frame rate. */
  70. struct virtsnd_a2v_rate {
  71. unsigned int rate;
  72. unsigned int vio_bit;
  73. };
  74. static const struct virtsnd_a2v_rate g_a2v_rate_map[] = {
  75. { 5512, VIRTIO_SND_PCM_RATE_5512 },
  76. { 8000, VIRTIO_SND_PCM_RATE_8000 },
  77. { 11025, VIRTIO_SND_PCM_RATE_11025 },
  78. { 16000, VIRTIO_SND_PCM_RATE_16000 },
  79. { 22050, VIRTIO_SND_PCM_RATE_22050 },
  80. { 32000, VIRTIO_SND_PCM_RATE_32000 },
  81. { 44100, VIRTIO_SND_PCM_RATE_44100 },
  82. { 48000, VIRTIO_SND_PCM_RATE_48000 },
  83. { 64000, VIRTIO_SND_PCM_RATE_64000 },
  84. { 88200, VIRTIO_SND_PCM_RATE_88200 },
  85. { 96000, VIRTIO_SND_PCM_RATE_96000 },
  86. { 176400, VIRTIO_SND_PCM_RATE_176400 },
  87. { 192000, VIRTIO_SND_PCM_RATE_192000 }
  88. };
  89. static int virtsnd_pcm_sync_stop(struct snd_pcm_substream *substream);
  90. /**
  91. * virtsnd_pcm_open() - Open the PCM substream.
  92. * @substream: Kernel ALSA substream.
  93. *
  94. * Context: Process context.
  95. * Return: 0 on success, -errno on failure.
  96. */
  97. static int virtsnd_pcm_open(struct snd_pcm_substream *substream)
  98. {
  99. struct virtio_pcm *vpcm = snd_pcm_substream_chip(substream);
  100. struct virtio_pcm_stream *vs = &vpcm->streams[substream->stream];
  101. struct virtio_pcm_substream *vss = vs->substreams[substream->number];
  102. substream->runtime->hw = vss->hw;
  103. substream->private_data = vss;
  104. snd_pcm_hw_constraint_integer(substream->runtime,
  105. SNDRV_PCM_HW_PARAM_PERIODS);
  106. vss->stopped = !!virtsnd_pcm_msg_pending_num(vss);
  107. vss->suspended = false;
  108. /*
  109. * If the substream has already been used, then the I/O queue may be in
  110. * an invalid state. Just in case, we do a check and try to return the
  111. * queue to its original state, if necessary.
  112. */
  113. return virtsnd_pcm_sync_stop(substream);
  114. }
  115. /**
  116. * virtsnd_pcm_close() - Close the PCM substream.
  117. * @substream: Kernel ALSA substream.
  118. *
  119. * Context: Process context.
  120. * Return: 0.
  121. */
  122. static int virtsnd_pcm_close(struct snd_pcm_substream *substream)
  123. {
  124. return 0;
  125. }
  126. /**
  127. * virtsnd_pcm_dev_set_params() - Set the parameters of the PCM substream on
  128. * the device side.
  129. * @vss: VirtIO PCM substream.
  130. * @buffer_bytes: Size of the hardware buffer.
  131. * @period_bytes: Size of the hardware period.
  132. * @channels: Selected number of channels.
  133. * @format: Selected sample format (SNDRV_PCM_FORMAT_XXX).
  134. * @rate: Selected frame rate.
  135. *
  136. * Context: Any context that permits to sleep.
  137. * Return: 0 on success, -errno on failure.
  138. */
  139. static int virtsnd_pcm_dev_set_params(struct virtio_pcm_substream *vss,
  140. unsigned int buffer_bytes,
  141. unsigned int period_bytes,
  142. unsigned int channels,
  143. snd_pcm_format_t format,
  144. unsigned int rate)
  145. {
  146. struct virtio_snd_msg *msg;
  147. struct virtio_snd_pcm_set_params *request;
  148. unsigned int i;
  149. int vformat = -1;
  150. int vrate = -1;
  151. for (i = 0; i < ARRAY_SIZE(g_a2v_format_map); ++i)
  152. if (g_a2v_format_map[i].alsa_bit == format) {
  153. vformat = g_a2v_format_map[i].vio_bit;
  154. break;
  155. }
  156. for (i = 0; i < ARRAY_SIZE(g_a2v_rate_map); ++i)
  157. if (g_a2v_rate_map[i].rate == rate) {
  158. vrate = g_a2v_rate_map[i].vio_bit;
  159. break;
  160. }
  161. if (vformat == -1 || vrate == -1)
  162. return -EINVAL;
  163. msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_SET_PARAMS,
  164. GFP_KERNEL);
  165. if (!msg)
  166. return -ENOMEM;
  167. request = virtsnd_ctl_msg_request(msg);
  168. request->buffer_bytes = cpu_to_le32(buffer_bytes);
  169. request->period_bytes = cpu_to_le32(period_bytes);
  170. request->channels = channels;
  171. request->format = vformat;
  172. request->rate = vrate;
  173. if (vss->features & (1U << VIRTIO_SND_PCM_F_MSG_POLLING))
  174. request->features |=
  175. cpu_to_le32(1U << VIRTIO_SND_PCM_F_MSG_POLLING);
  176. if (vss->features & (1U << VIRTIO_SND_PCM_F_EVT_XRUNS))
  177. request->features |=
  178. cpu_to_le32(1U << VIRTIO_SND_PCM_F_EVT_XRUNS);
  179. return virtsnd_ctl_msg_send_sync(vss->snd, msg);
  180. }
  181. /**
  182. * virtsnd_pcm_hw_params() - Set the parameters of the PCM substream.
  183. * @substream: Kernel ALSA substream.
  184. * @hw_params: Hardware parameters.
  185. *
  186. * Context: Process context.
  187. * Return: 0 on success, -errno on failure.
  188. */
  189. static int virtsnd_pcm_hw_params(struct snd_pcm_substream *substream,
  190. struct snd_pcm_hw_params *hw_params)
  191. {
  192. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  193. struct virtio_device *vdev = vss->snd->vdev;
  194. int rc;
  195. if (virtsnd_pcm_msg_pending_num(vss)) {
  196. dev_err(&vdev->dev, "SID %u: invalid I/O queue state\n",
  197. vss->sid);
  198. return -EBADFD;
  199. }
  200. rc = virtsnd_pcm_dev_set_params(vss, params_buffer_bytes(hw_params),
  201. params_period_bytes(hw_params),
  202. params_channels(hw_params),
  203. params_format(hw_params),
  204. params_rate(hw_params));
  205. if (rc)
  206. return rc;
  207. /*
  208. * Free previously allocated messages if ops->hw_params() is called
  209. * several times in a row, or if ops->hw_free() failed to free messages.
  210. */
  211. virtsnd_pcm_msg_free(vss);
  212. return virtsnd_pcm_msg_alloc(vss, params_periods(hw_params),
  213. params_period_bytes(hw_params));
  214. }
  215. /**
  216. * virtsnd_pcm_hw_free() - Reset the parameters of the PCM substream.
  217. * @substream: Kernel ALSA substream.
  218. *
  219. * Context: Process context.
  220. * Return: 0
  221. */
  222. static int virtsnd_pcm_hw_free(struct snd_pcm_substream *substream)
  223. {
  224. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  225. /* If the queue is flushed, we can safely free the messages here. */
  226. if (!virtsnd_pcm_msg_pending_num(vss))
  227. virtsnd_pcm_msg_free(vss);
  228. return 0;
  229. }
  230. /**
  231. * virtsnd_pcm_prepare() - Prepare the PCM substream.
  232. * @substream: Kernel ALSA substream.
  233. *
  234. * Context: Process context.
  235. * Return: 0 on success, -errno on failure.
  236. */
  237. static int virtsnd_pcm_prepare(struct snd_pcm_substream *substream)
  238. {
  239. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  240. struct virtio_device *vdev = vss->snd->vdev;
  241. struct virtio_snd_msg *msg;
  242. if (!vss->suspended) {
  243. if (virtsnd_pcm_msg_pending_num(vss)) {
  244. dev_err(&vdev->dev, "SID %u: invalid I/O queue state\n",
  245. vss->sid);
  246. return -EBADFD;
  247. }
  248. vss->buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
  249. vss->hw_ptr = 0;
  250. } else {
  251. struct snd_pcm_runtime *runtime = substream->runtime;
  252. unsigned int buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
  253. unsigned int period_bytes = snd_pcm_lib_period_bytes(substream);
  254. int rc;
  255. rc = virtsnd_pcm_dev_set_params(vss, buffer_bytes, period_bytes,
  256. runtime->channels,
  257. runtime->format, runtime->rate);
  258. if (rc)
  259. return rc;
  260. }
  261. vss->xfer_xrun = false;
  262. vss->suspended = false;
  263. vss->msg_count = 0;
  264. memset(&vss->pcm_indirect, 0, sizeof(vss->pcm_indirect));
  265. vss->pcm_indirect.sw_buffer_size =
  266. vss->pcm_indirect.hw_buffer_size =
  267. snd_pcm_lib_buffer_bytes(substream);
  268. msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_PREPARE,
  269. GFP_KERNEL);
  270. if (!msg)
  271. return -ENOMEM;
  272. return virtsnd_ctl_msg_send_sync(vss->snd, msg);
  273. }
  274. /**
  275. * virtsnd_pcm_trigger() - Process command for the PCM substream.
  276. * @substream: Kernel ALSA substream.
  277. * @command: Substream command (SNDRV_PCM_TRIGGER_XXX).
  278. *
  279. * Context: Any context. Takes and releases the VirtIO substream spinlock.
  280. * May take and release the tx/rx queue spinlock.
  281. * Return: 0 on success, -errno on failure.
  282. */
  283. static int virtsnd_pcm_trigger(struct snd_pcm_substream *substream, int command)
  284. {
  285. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  286. struct virtio_snd *snd = vss->snd;
  287. struct virtio_snd_queue *queue;
  288. struct virtio_snd_msg *msg;
  289. unsigned long flags;
  290. int rc = 0;
  291. switch (command) {
  292. case SNDRV_PCM_TRIGGER_START:
  293. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  294. queue = virtsnd_pcm_queue(vss);
  295. spin_lock_irqsave(&queue->lock, flags);
  296. spin_lock(&vss->lock);
  297. if (vss->direction == SNDRV_PCM_STREAM_CAPTURE)
  298. rc = virtsnd_pcm_msg_send(vss, 0, vss->buffer_bytes);
  299. if (!rc)
  300. vss->xfer_enabled = true;
  301. spin_unlock(&vss->lock);
  302. spin_unlock_irqrestore(&queue->lock, flags);
  303. if (rc)
  304. return rc;
  305. msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_START,
  306. GFP_KERNEL);
  307. if (!msg) {
  308. spin_lock_irqsave(&vss->lock, flags);
  309. vss->xfer_enabled = false;
  310. spin_unlock_irqrestore(&vss->lock, flags);
  311. return -ENOMEM;
  312. }
  313. return virtsnd_ctl_msg_send_sync(snd, msg);
  314. case SNDRV_PCM_TRIGGER_SUSPEND:
  315. vss->suspended = true;
  316. fallthrough;
  317. case SNDRV_PCM_TRIGGER_STOP:
  318. vss->stopped = true;
  319. fallthrough;
  320. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  321. spin_lock_irqsave(&vss->lock, flags);
  322. vss->xfer_enabled = false;
  323. spin_unlock_irqrestore(&vss->lock, flags);
  324. msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_STOP,
  325. GFP_KERNEL);
  326. if (!msg)
  327. return -ENOMEM;
  328. return virtsnd_ctl_msg_send_sync(snd, msg);
  329. default:
  330. return -EINVAL;
  331. }
  332. }
  333. /**
  334. * virtsnd_pcm_sync_stop() - Synchronous PCM substream stop.
  335. * @substream: Kernel ALSA substream.
  336. *
  337. * The function can be called both from the upper level or from the driver
  338. * itself.
  339. *
  340. * Context: Process context. Takes and releases the VirtIO substream spinlock.
  341. * Return: 0 on success, -errno on failure.
  342. */
  343. static int virtsnd_pcm_sync_stop(struct snd_pcm_substream *substream)
  344. {
  345. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  346. struct virtio_snd *snd = vss->snd;
  347. struct virtio_snd_msg *msg;
  348. unsigned int js = msecs_to_jiffies(virtsnd_msg_timeout_ms);
  349. int rc;
  350. cancel_work_sync(&vss->elapsed_period);
  351. if (!vss->stopped)
  352. return 0;
  353. msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_RELEASE,
  354. GFP_KERNEL);
  355. if (!msg)
  356. return -ENOMEM;
  357. rc = virtsnd_ctl_msg_send_sync(snd, msg);
  358. if (rc)
  359. return rc;
  360. /*
  361. * The spec states that upon receipt of the RELEASE command "the device
  362. * MUST complete all pending I/O messages for the specified stream ID".
  363. * Thus, we consider the absence of I/O messages in the queue as an
  364. * indication that the substream has been released.
  365. */
  366. rc = wait_event_interruptible_timeout(vss->msg_empty,
  367. !virtsnd_pcm_msg_pending_num(vss),
  368. js);
  369. if (rc <= 0) {
  370. dev_warn(&snd->vdev->dev, "SID %u: failed to flush I/O queue\n",
  371. vss->sid);
  372. return !rc ? -ETIMEDOUT : rc;
  373. }
  374. vss->stopped = false;
  375. return 0;
  376. }
  377. /**
  378. * virtsnd_pcm_pb_pointer() - Get the current hardware position for the PCM
  379. * substream for playback.
  380. * @substream: Kernel ALSA substream.
  381. *
  382. * Context: Any context.
  383. * Return: Hardware position in frames inside [0 ... buffer_size) range.
  384. */
  385. static snd_pcm_uframes_t
  386. virtsnd_pcm_pb_pointer(struct snd_pcm_substream *substream)
  387. {
  388. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  389. return snd_pcm_indirect_playback_pointer(substream,
  390. &vss->pcm_indirect,
  391. vss->hw_ptr);
  392. }
  393. /**
  394. * virtsnd_pcm_cp_pointer() - Get the current hardware position for the PCM
  395. * substream for capture.
  396. * @substream: Kernel ALSA substream.
  397. *
  398. * Context: Any context.
  399. * Return: Hardware position in frames inside [0 ... buffer_size) range.
  400. */
  401. static snd_pcm_uframes_t
  402. virtsnd_pcm_cp_pointer(struct snd_pcm_substream *substream)
  403. {
  404. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  405. return snd_pcm_indirect_capture_pointer(substream,
  406. &vss->pcm_indirect,
  407. vss->hw_ptr);
  408. }
  409. static void virtsnd_pcm_trans_copy(struct snd_pcm_substream *substream,
  410. struct snd_pcm_indirect *rec, size_t bytes)
  411. {
  412. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  413. virtsnd_pcm_msg_send(vss, rec->sw_data, bytes);
  414. }
  415. static int virtsnd_pcm_pb_ack(struct snd_pcm_substream *substream)
  416. {
  417. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  418. struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss);
  419. unsigned long flags;
  420. int rc;
  421. spin_lock_irqsave(&queue->lock, flags);
  422. spin_lock(&vss->lock);
  423. rc = snd_pcm_indirect_playback_transfer(substream, &vss->pcm_indirect,
  424. virtsnd_pcm_trans_copy);
  425. spin_unlock(&vss->lock);
  426. spin_unlock_irqrestore(&queue->lock, flags);
  427. return rc;
  428. }
  429. static int virtsnd_pcm_cp_ack(struct snd_pcm_substream *substream)
  430. {
  431. struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream);
  432. struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss);
  433. unsigned long flags;
  434. int rc;
  435. spin_lock_irqsave(&queue->lock, flags);
  436. spin_lock(&vss->lock);
  437. rc = snd_pcm_indirect_capture_transfer(substream, &vss->pcm_indirect,
  438. virtsnd_pcm_trans_copy);
  439. spin_unlock(&vss->lock);
  440. spin_unlock_irqrestore(&queue->lock, flags);
  441. return rc;
  442. }
  443. /* PCM substream operators map. */
  444. const struct snd_pcm_ops virtsnd_pcm_ops[] = {
  445. {
  446. .open = virtsnd_pcm_open,
  447. .close = virtsnd_pcm_close,
  448. .ioctl = snd_pcm_lib_ioctl,
  449. .hw_params = virtsnd_pcm_hw_params,
  450. .hw_free = virtsnd_pcm_hw_free,
  451. .prepare = virtsnd_pcm_prepare,
  452. .trigger = virtsnd_pcm_trigger,
  453. .sync_stop = virtsnd_pcm_sync_stop,
  454. .pointer = virtsnd_pcm_pb_pointer,
  455. .ack = virtsnd_pcm_pb_ack,
  456. },
  457. {
  458. .open = virtsnd_pcm_open,
  459. .close = virtsnd_pcm_close,
  460. .ioctl = snd_pcm_lib_ioctl,
  461. .hw_params = virtsnd_pcm_hw_params,
  462. .hw_free = virtsnd_pcm_hw_free,
  463. .prepare = virtsnd_pcm_prepare,
  464. .trigger = virtsnd_pcm_trigger,
  465. .sync_stop = virtsnd_pcm_sync_stop,
  466. .pointer = virtsnd_pcm_cp_pointer,
  467. .ack = virtsnd_pcm_cp_ack,
  468. },
  469. };