From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.215.175 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794458144; b=gw5RQFAEeStJUgPZlQPsdMxPd/Bi7KtPsjT5wDzwbSH73RXtvNLBTbaj9B3DMiFUl2jO qY61QNLDN9mwYafwouwaVVTTOeyD8vIc5VK4gWTyFgCLrod16aq/v93XiKJBy1oPZ2M9o 3TSClS5Skf2MBwf+PKB5zJXmiRrMtfOPcaT5Hk2gUUGSTqqpIrNrTB4vQuGMGHht0fl0/ furOYjAoqvX7KrZ/HS7VYwZHm/V/mRXrbZnK/udBU8WVgEQsLg033lX+H7XdyX8DB5Peo AqvKlTanK89G0vPs1XP2uwvUiiAhXhMzI2QztNRdZ0HY+vTPE5wdv/a145AtAmKz1oQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794458144; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: From:To:Cc:Subject:Date:Message-ID:X-Mailer:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding; bh=+F52bmHA0YPZtsmxGOVRSP0y4qFlAaBYlea7RyACx8E=; b=AON7NFlV4C12py3fCEzxyHu1H/I11dUAinB96MUOnIctzihljaOfmC6kr7PBLI1+wRyg 55ugmNb12mGYyF9sf36K1EaO+M8lcONgfcRifDo9ewahfpN0BnvInKL+enbbc7pezzUWZ TF9Vabgk1DvYk5FsNYuSJ/YCzNutCBqOH4x1ctS8DKigxrYn4dzYadoFfYZyW3YTHTZ5O Dylo4Rg1FVXUFf3grMExbF7ABGCUD2l/s11LKmAhvOxyAs7QANn5n1pcsjJou9AOxaQ5G QkObLg6nvq0/yjbJlfRkNKE6iE7gBZLvXqPL2M40bisTHEVAhMwZhSq0gBjFaHpjqHQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=SECbivIQ; arc=none smtp.remote-ip=209.85.215.175 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9770B60A263B for ; Thu, 12 Nov 2026 04:35:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 9770B60A263B Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=SECbivIQ Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-cdba1bbde0bso1464171a12.2 for ; Wed, 11 Nov 2026 20:35:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1794458143; x=1795062943; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=+F52bmHA0YPZtsmxGOVRSP0y4qFlAaBYlea7RyACx8E=; b=SECbivIQ+YxRkx8gnVhJurDmlYgFnYvZqKuT3rR7xJDntkz7NkyNGfZQ44EOZXnmuZ USrjT+youKYfjGFiBcSHVE6xbvLqX+r9UK6kcn0V8OfyfTYvR2QyiK/sVumS5lgoGqW9 31o7rduGo6etyPLLNuOFuiaa3CCQmX/4rlok1c0VcRcfgk05JBPfON1N1gkEhMYDx9ap N6KBtI9WQevgVwbwEDDB0WQPUm1T+/MUdIgXo1OLxr3u5pacNOzbBfj64xhp1iXJ6sHC 1X/00OrGqAeII1RfJnvb6XjoVeE/TUf08OltYh48+ueYNY0fQhcWtedSxeOnQ76xPO1W bmoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1794458143; x=1795062943; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=+F52bmHA0YPZtsmxGOVRSP0y4qFlAaBYlea7RyACx8E=; b=Mzoe7m8ZzCyjuwXEref1lC8g+TTfeDVWVJinHsXnv7jKyUUt4blsyIWUeHkO3ndR85 pNtWI7L8LQEBBse6s3ewtHxa8peJb/xzMflNJ2WzJ2HRo8ruYGuMkXv+L+mE5JWrofTB Buw4oXJNJWOjHHmyLYGJ3SKEeCsFkfB5cdgx0WMbhrIVrV7nguXxraJ39qUXWt86AaeB 1v9xVcVeeo4WOT7/45gIYNT17suXdrUw45laKp+1Kpl8YUWvp7z2gbMhq/a7jABPufY6 jyJo1BTHWF3TbLu/m68e2AZ0W11CF49j3yFe//YqK8JGpWJ+C8UraKHwpGDe5hokDdvF 4DVg== X-Forwarded-Encrypted: i=1; AL+hErFKNRE9VB8ea+N1SPF86TLoU3iSH6kZ6BjpGNCPDMDEkQTzCem5i49E4mrJ49qnA7GnYdSPFNdSLaY=@vger.kernel.org X-Gm-Message-State: APuU4Z+1XajaN7vXIJa8UKwrtM9550YaHQHVLGeXi04vmrCHsJ23JluV 8Sf57l9rzJb7+5Q6qxxVlsSvmbzVjc/Xg80w/qNbGtgDWBvZA7pzmbA1 X-Gm-Gg: AYBFou3C2k5YwC3N7Sg0qTJQ62WJJlxDZjABQAkEciZqO6ajPwE0TzvBWrnml7AdJY1 sANOa3eaD9YrPyqAVYqZ6kAfkbEvgktKsnb9LaSwHKHjarOjJvqcdIFLsw018I+HRteyUGf9xtP 2oIw83oW2sPkMa+DjnRqBNfVMdNwCGfgAn4PuYLErAj4BfSdfYu8POoZ0i6yQQ5iO+PtWkssUrU 9RVMBojamhp4lCufSj7fqA18rILKZ48TPDaG2QXitkamOHEf3Oj6bGnXBmzIE28v3YJoQFGGyqq lBCD64I2Btrs1lJmw1Yg2lX7hTjvrN33swba8eVxfH65P+biSxB2AyBlAqDziry6/KKQV14Zdwb r7vRp5PZDQJiGrA2iqaBmg7xtZ9HMlUzh4Jprtz/DuCPyU0MN3yYQSAC8dVhmwW+mCUyJQRILY+ ZxxKKSk8lUU3+7brrvgklkJN6TLPNqz3S+7m8I86oOuWBbxDSYSXlNCcnT64jc60GL/o6+S8AFK IhmfIlIdKQrvrTMJ4GIjK/CQikJU0Lh3E5fld6tKjL/5r3mzBda7WvddIPtU8zqvcUUjhNGIgxI q27hCR9QqHzlk7UG7WzSO4fYN5UVLu8FEJTiRhgcwQM0uEkbqLBISa7CD3cUMVGlfgB4LmhcwQz UHs+RBd06cje8IhrXGM/9F+GCwwzES2AhCnjeua3km1enkzE= X-Received: by 2002:a17:90b:5810:b0:39e:4c81:6c5f with SMTP id 98e67ed59e1d1-3b182f26c64mr4221712a91.26.1794458142740; Wed, 11 Nov 2026 20:35:42 -0800 (PST) Received: from localhost.localdomain ([183.96.175.225]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3b197c8b287sm2470466a91.15.2026.11.11.20.35.39 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 11 Nov 2026 20:35:42 -0800 (PST) From: Joonho Lee To: linux-sound@vger.kernel.org Cc: tiwai@suse.com, perex@perex.cz, anton.yakovlev@opensynergy.com, mst@redhat.com, virtualization@lists.linux.dev, linux-kernel@vger.kernel.org, corbet@lwn.net, skhan@linuxfoundation.org, rdunlap@infradead.org, linux-doc@vger.kernel.org, Joonho Lee Subject: [PATCH v28 06/17] ALSA: virtio: propagate playback send failures through ACK Date: Thu, 12 Nov 2026 13:35:05 +0900 Message-ID: <20261112043516.37010-7-mynameisjune111@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20261112043516.37010-1-mynameisjune111@gmail.com> References: <20261112043516.37010-1-mynameisjune111@gmail.com> X-Mailing-List: linux-doc@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Propagate playback submission failures through ACK and commit indirect accounting only after transport submission succeeds. Keep the PCM state and buffer-access checks synchronized with playback transfer admission. The existing capture ACK callback and initial queue reservation behavior remain together until the request-owned capture conversion in patch 12. That conversion introduces RX reservation, validation and refill as one contract. Fixes: fe981e67568c ("ALSA: virtio: use ack callback") Assisted-by: LLM Signed-off-by: Joonho Lee --- sound/virtio/virtio_pcm.h | 6 + sound/virtio/virtio_pcm_msg.c | 12 ++ sound/virtio/virtio_pcm_ops.c | 237 ++++++++++++++++++++++++++++++++++++----- 3 files changed, 228 insertions(+), 27 deletions(-) diff --git a/sound/virtio/virtio_pcm.h b/sound/virtio/virtio_pcm.h --- a/sound/virtio/virtio_pcm.h +++ b/sound/virtio/virtio_pcm.h @@ -33,6 +33,10 @@ * @xfer_xrun: Data underflow/overflow state (0 - no xrun, 1 - xrun). * @stopped: True if the substream is stopped and must be released on the device * side. + * @prepared: True after device PREPARE and the core pointer reset succeed; + * protected by @lock. + * @preparing: ACK gate through teardown and prepare's core reset; + * protected by @lock. * @suspended: True if the substream is suspended and must be reconfigured on * the device side at resume. * @msgs: Allocated I/O messages. @@ -56,6 +60,8 @@ bool xfer_enabled; bool xfer_xrun; bool stopped; + bool prepared; + bool preparing; bool suspended; struct virtio_pcm_msg **msgs; unsigned int nmsgs; diff --git a/sound/virtio/virtio_pcm_msg.c b/sound/virtio/virtio_pcm_msg.c --- a/sound/virtio/virtio_pcm_msg.c +++ b/sound/virtio/virtio_pcm_msg.c @@ -260,6 +260,18 @@ dev_err(&vdev->dev, "SID %u: failed to send I/O message\n", vss->sid); + msg->length -= n; + + /* + * Do not leave earlier messages queued without notifying + * the device when a later message could not be added. + */ + if (msg_count != vss->msg_count && + !(vss->features & + (1U << VIRTIO_SND_PCM_F_MSG_POLLING)) && + virtqueue_kick_prepare(vqueue)) + virtqueue_notify(vqueue); + return rc; } diff --git a/sound/virtio/virtio_pcm_ops.c b/sound/virtio/virtio_pcm_ops.c --- a/sound/virtio/virtio_pcm_ops.c +++ b/sound/virtio/virtio_pcm_ops.c @@ -97,6 +97,38 @@ static int virtsnd_pcm_sync_stop(struct snd_pcm_substream *substream); /** + * virtsnd_pcm_close_ack() - Update PCM prepare admission state. + * @substream: Kernel ALSA substream. + * @preparing: True while driver prepare and the core pointer reset are active. + * + * Context: Process context. + */ +static void virtsnd_pcm_close_ack(struct snd_pcm_substream *substream, + bool preparing) +{ + struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); + + scoped_guard(pcm_stream_lock_irqsave, substream) { + guard(spinlock_irqsave)(&vss->lock); + vss->prepared = false; + vss->xfer_enabled = false; + vss->preparing = preparing; + } +} + +/* Keep completed RX data valid while RELEASE drains the device queue. */ +static void virtsnd_pcm_block_ack(struct snd_pcm_substream *substream) +{ + struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); + + scoped_guard(pcm_stream_lock_irqsave, substream) { + guard(spinlock_irqsave)(&vss->lock); + vss->preparing = true; + vss->xfer_enabled = false; + } +} + +/** * virtsnd_pcm_open() - Open the PCM substream. * @substream: Kernel ALSA substream. * @@ -115,7 +147,8 @@ snd_pcm_hw_constraint_integer(substream->runtime, SNDRV_PCM_HW_PARAM_PERIODS); - vss->stopped = !!virtsnd_pcm_msg_pending_num(vss); + scoped_guard(spinlock_irqsave, &vss->lock) + vss->stopped = !!vss->msg_count; vss->suspended = false; /* @@ -219,6 +252,8 @@ struct virtio_device *vdev = vss->snd->vdev; int rc; + virtsnd_pcm_close_ack(substream, false); + if (virtsnd_pcm_msg_pending_num(vss)) { dev_err(&vdev->dev, "SID %u: invalid I/O queue state\n", vss->sid); @@ -254,6 +289,8 @@ { struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); + virtsnd_pcm_close_ack(substream, false); + /* If the queue is flushed, we can safely free the messages here. */ if (!virtsnd_pcm_msg_pending_num(vss)) virtsnd_pcm_msg_free(vss); @@ -262,17 +299,18 @@ } /** - * virtsnd_pcm_prepare() - Prepare the PCM substream. + * virtsnd_pcm_prepare_device() - Prepare the PCM substream on the device. * @substream: Kernel ALSA substream. * * Context: Process context. * Return: 0 on success, -errno on failure. */ -static int virtsnd_pcm_prepare(struct snd_pcm_substream *substream) +static int virtsnd_pcm_prepare_device(struct snd_pcm_substream *substream) { struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); struct virtio_device *vdev = vss->snd->vdev; struct virtio_snd_msg *msg; + int rc; if (!vss->suspended) { if (virtsnd_pcm_msg_pending_num(vss)) { @@ -287,16 +325,14 @@ struct snd_pcm_runtime *runtime = substream->runtime; unsigned int buffer_bytes = snd_pcm_lib_buffer_bytes(substream); unsigned int period_bytes = snd_pcm_lib_period_bytes(substream); - int rc; rc = virtsnd_pcm_dev_set_params(vss, buffer_bytes, period_bytes, - runtime->channels, - runtime->format, runtime->rate); + runtime->channels, + runtime->format, runtime->rate); if (rc) return rc; } - vss->xfer_xrun = false; vss->suspended = false; vss->msg_count = 0; virtsnd_pcm_msg_reset(vss); @@ -311,7 +347,33 @@ if (!msg) return -ENOMEM; - return virtsnd_ctl_msg_send_sync(vss->snd, msg); + rc = virtsnd_ctl_msg_send_sync(vss->snd, msg); + if (rc) + return rc; + + scoped_guard(spinlock_irqsave, &vss->lock) { + vss->xfer_xrun = false; + } + return 0; +} + +/* Keep ACK closed through the core's locked pointer reset. */ +static int virtsnd_pcm_prepare(struct snd_pcm_substream *substream) +{ + virtsnd_pcm_close_ack(substream, true); + return virtsnd_pcm_prepare_device(substream); +} + +/* Complete admission only after the linked core prepare action ends. */ +static void virtsnd_pcm_prepare_complete( + struct snd_pcm_substream *substream, bool success) +{ + struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); + + scoped_guard(spinlock_irqsave, &vss->lock) { + vss->prepared = success; + vss->preparing = false; + } } /** @@ -338,6 +400,8 @@ scoped_guard(spinlock_irqsave, &queue->lock) { guard(spinlock)(&vss->lock); + if (vss->preparing || !vss->prepared) + return -EBADFD; if (vss->direction == SNDRV_PCM_STREAM_CAPTURE) rc = virtsnd_pcm_msg_send(vss, 0, vss->buffer_bytes); if (rc) @@ -356,10 +420,12 @@ return virtsnd_ctl_msg_send_sync(snd, msg); case SNDRV_PCM_TRIGGER_SUSPEND: - vss->suspended = true; + scoped_guard(spinlock_irqsave, &vss->lock) + vss->suspended = true; fallthrough; case SNDRV_PCM_TRIGGER_STOP: - vss->stopped = true; + scoped_guard(spinlock_irqsave, &vss->lock) + vss->stopped = true; fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: scoped_guard(spinlock_irqsave, &vss->lock) { @@ -393,11 +459,16 @@ struct virtio_snd *snd = vss->snd; struct virtio_snd_msg *msg; unsigned int js = msecs_to_jiffies(virtsnd_msg_timeout_ms); + bool stopped; int rc; + virtsnd_pcm_block_ack(substream); + cancel_work_sync(&vss->elapsed_period); - if (!vss->stopped) + scoped_guard(spinlock_irqsave, &vss->lock) + stopped = vss->stopped; + if (!stopped) return 0; msg = virtsnd_pcm_ctl_msg_alloc(vss, VIRTIO_SND_R_PCM_RELEASE, @@ -425,7 +496,8 @@ return !rc ? -ETIMEDOUT : rc; } - vss->stopped = false; + scoped_guard(spinlock_irqsave, &vss->lock) + vss->stopped = false; return 0; } @@ -442,6 +514,10 @@ virtsnd_pcm_pb_pointer(struct snd_pcm_substream *substream) { struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); + + scoped_guard(spinlock_irqsave, &vss->lock) + if (vss->xfer_xrun) + return SNDRV_PCM_POS_XRUN; return snd_pcm_indirect_playback_pointer(substream, &vss->pcm_indirect, @@ -461,41 +537,144 @@ { struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); + scoped_guard(spinlock_irqsave, &vss->lock) + if (vss->xfer_xrun) + return SNDRV_PCM_POS_XRUN; + return snd_pcm_indirect_capture_pointer(substream, &vss->pcm_indirect, vss->hw_ptr); } +struct virtsnd_pcm_transfer { + struct snd_pcm_indirect indirect; + int error; +}; + static void virtsnd_pcm_trans_copy(struct snd_pcm_substream *substream, struct snd_pcm_indirect *rec, size_t bytes) { struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); + struct virtsnd_pcm_transfer *transfer = + container_of(rec, struct virtsnd_pcm_transfer, indirect); + + if (transfer->error) + return; + + transfer->error = virtsnd_pcm_msg_send(vss, rec->sw_data, bytes); +} + +/* Caller holds vss->lock. */ +static void virtsnd_pcm_transfer_failed(struct virtio_pcm_substream *vss) +{ + vss->xfer_enabled = false; + vss->stopped = true; + vss->xfer_xrun = true; + vss->substream->runtime->stop_operating = true; +} + +/* The caller holds the PCM lock, also used by DROP and state transitions. */ +static int virtsnd_pcm_ack_state(struct snd_pcm_substream *substream) +{ + switch (substream->runtime->state) { + case SNDRV_PCM_STATE_XRUN: + /* The member is already XRUN; avoid stopping its linked group twice. */ + return -EBADFD; + case SNDRV_PCM_STATE_PREPARED: + case SNDRV_PCM_STATE_RUNNING: + case SNDRV_PCM_STATE_PAUSED: + case SNDRV_PCM_STATE_DRAINING: + if (atomic_read(&substream->runtime->buffer_accessing) < 0) + return -EBADFD; + return 0; + default: + return -EBADFD; + } +} + +static int virtsnd_pcm_pb_ack(struct snd_pcm_substream *substream) +{ + struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); + struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss); + struct virtsnd_pcm_transfer transfer = {}; + int rc; + + rc = virtsnd_pcm_ack_state(substream); + if (rc) + return rc; + + scoped_guard(spinlock_irqsave, &queue->lock) { + guard(spinlock)(&vss->lock); + if (vss->preparing || !vss->prepared) + return -EBADFD; + if (vss->stopped) + return -EBADFD; + if (vss->xfer_xrun) { + rc = -EPIPE; + } else { + transfer.indirect = vss->pcm_indirect; + rc = snd_pcm_indirect_playback_transfer(substream, + &transfer.indirect, + virtsnd_pcm_trans_copy); + if (!rc) + rc = transfer.error; + } + if (rc) + virtsnd_pcm_transfer_failed(vss); + else + vss->pcm_indirect = transfer.indirect; + } + if (rc) { + dev_err(&vss->snd->vdev->dev, + "SID %u: playback ACK transfer failed: %d\n", + vss->sid, rc); + return -EPIPE; + } + + return 0; +} + +static void virtsnd_pcm_legacy_capture_copy(struct snd_pcm_substream *substream, + struct snd_pcm_indirect *rec, size_t bytes) +{ + struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); virtsnd_pcm_msg_send(vss, rec->sw_data, bytes); } -static int virtsnd_pcm_pb_ack(struct snd_pcm_substream *substream) +static int virtsnd_pcm_cp_ack(struct snd_pcm_substream *substream) { struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss); - + int rc; + + rc = virtsnd_pcm_ack_state(substream); + if (rc) + return rc; guard(spinlock_irqsave)(&queue->lock); guard(spinlock)(&vss->lock); - - return snd_pcm_indirect_playback_transfer(substream, &vss->pcm_indirect, - virtsnd_pcm_trans_copy); -} - -static int virtsnd_pcm_cp_ack(struct snd_pcm_substream *substream) -{ - struct virtio_pcm_substream *vss = snd_pcm_substream_chip(substream); - struct virtio_snd_queue *queue = virtsnd_pcm_queue(vss); - - guard(spinlock_irqsave)(&queue->lock); - guard(spinlock)(&vss->lock); + if (vss->preparing || !vss->prepared) + return -EBADFD; + if (vss->xfer_xrun) + return -EPIPE; + if (vss->stopped && + substream->runtime->state != SNDRV_PCM_STATE_DRAINING) + return -EBADFD; return snd_pcm_indirect_capture_transfer(substream, &vss->pcm_indirect, - virtsnd_pcm_trans_copy); + virtsnd_pcm_legacy_capture_copy); +} + +/** + * virtsnd_pcm_reset() - Reset PCM pointers. + * @substream: Kernel ALSA substream. + * + * Context: PCM stream lock held. + * Return: 0 on success, -errno on failure. + */ +static int virtsnd_pcm_reset(struct snd_pcm_substream *substream) +{ + return snd_pcm_lib_reset(substream); } /* PCM substream operators map. */ @@ -507,6 +686,8 @@ .hw_params = virtsnd_pcm_hw_params, .hw_free = virtsnd_pcm_hw_free, .prepare = virtsnd_pcm_prepare, + .prepare_complete = virtsnd_pcm_prepare_complete, + .reset = virtsnd_pcm_reset, .trigger = virtsnd_pcm_trigger, .sync_stop = virtsnd_pcm_sync_stop, .pointer = virtsnd_pcm_pb_pointer, @@ -519,6 +700,8 @@ .hw_params = virtsnd_pcm_hw_params, .hw_free = virtsnd_pcm_hw_free, .prepare = virtsnd_pcm_prepare, + .prepare_complete = virtsnd_pcm_prepare_complete, + .reset = virtsnd_pcm_reset, .trigger = virtsnd_pcm_trigger, .sync_stop = virtsnd_pcm_sync_stop, .pointer = virtsnd_pcm_cp_pointer,