From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.210.177 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794466198; b=UTaZSW6XNMZdC55rFz4NnvQioHKgxXCa3KJLX/gjWn61ZsLKZBU0w6TO+4NmbIJFYQNu MAMDPbH65IEFbBRjKIgk9SBS4DebNgC5itlVGmWHObRg1TC9RCXS9g+kSWnbbNKdb/5GR +b9i37NqYufYixAqNEKga+iI2pL+suM2uzWbZ1uIEfLDgeMgp7q8OQfVnJSqtHxZj8mMy 6BrJ9jzm6lu+zLQY7CMIVBbkSP7gCDKi5Gt2QtP5cz8iVRV1z06dyVkleqEgBdZZnaP03 hWWDhzZK8KIVd+5KDCXSvZCUYuzSsr2O2Hc0bNZ/AYvc44lPZQu4JT8pbSyerNw9wOg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794466198; 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=hZMkTas/cq2wAsauHa9MKhr2E2lQh0yaqya+wnY/2/bATsR8p1tX/RVMom87m0eOKIU4 L/mIHenBDIpL0R235HThvaF5TzSoxFoT7XiFXrYtM7xXVgEPAEO+8ZQGaCQFlzjnLFUlG eaFAalPcWTwdnkJK+mNtyZBmol1TRO9TGBfFXvZFRuHxekmyPMVe/t/H0puSHzhuP5fvL SLrxIMg5wKLGVERiVVPL7i3mOUT2S+xoYrUPSMTNILkVRfs0nTgoU2H5NxFP9t8w9szLN N8tYLoMB9ofPs6bn3K7jKPf09cDS268Id2vSPr8K6/nMjQtaGzxA6RFy2U3WQ0yG56A== 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=HhrMj1gM; arc=none smtp.remote-ip=209.85.210.177 Received: from mail-pf1-f177.google.com (mail-pf1-f177.google.com [209.85.210.177]) (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 74B0060A261A for ; Thu, 12 Nov 2026 06:49:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 74B0060A261A 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=HhrMj1gM Received: by mail-pf1-f177.google.com with SMTP id d2e1a72fcca58-8b66d1a08ccso510455b3a.1 for ; Wed, 11 Nov 2026 22:49:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1794466198; x=1795070998; 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=HhrMj1gM1Dx7RyNnsbLEfL1xhogW+Zt5L/2DFDSwxKFGP0Q+cHMcGl4cwFPGxS6Nl2 MRznm48j6WsfVRz02JYj9kbaJ8aRlkK2AarTH23gf+9y3OMViJO2uapbEg/DM4tdxKZL z07ZAsGAyLo+gz6yguJVB5P29K4F/xr1dm2ycG4C9GjenmTTfxhgWVoIAvigJNNnjCV3 43kccBdXJ5mzAMm5oVtxfQgR3z/wnnPVhw4v0SpbT7qjKyvZnx1/QZhyGJ+FoMeooQq9 vZ3MKDptp3oEMQkGZERJLTQfR7B5sMzI2eP5XvvqmOk7ZUrxLNQljmV9CUI0SsEhRhsJ hUlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1794466198; x=1795070998; 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=c5kVSzk/G47n+sdmLo2+gutE5sWtxgBbO4ojecx96IA1ThZ1RxQM3m3WqUbWwrxb7j ETz9kKDYHrT93mDE53KO7H131PBzaUDfSAGpT2IfzoeVxe/MZCnaFdGjLCfWVVAIRLcj Q8fDtYLmjCdYubuIBG/58S3207KBsNq6bIDObL77iAhWiWin6hcjpbhqE9gZdfTc3JEu 3YoK+OWounPsQGOMq3Ps/kftAL14gXUceMhQZ3NSEpzvdSq6r/hTE3COPmJY+yaS3aCh 9Unos9f8WsoTX7oTOinJAjIlH8JA5JHxwD8oRW7+Jmdlqbep0YBw+K+h5YMBAXkYNzGV hgpA== X-Forwarded-Encrypted: i=1; AL+hErG4c0yzf+Ms7ZvNwrWOfAYIKEtz1gmSoqVYu51/IPGJ0Zj7pbgvwuUbnwIDeSf7f2nXrYEGRFMPcixJuTk=@vger.kernel.org X-Gm-Message-State: APuU4Z95anVMIUopNmecb0o8uLr1L4C0QF6lMui4RCUvKWbSOPGQwjws XhKS43MIDtS442RGoGqyyfuGswcutyMET1hAi3fvXpZkKyfd5oG0o8LN X-Gm-Gg: AYBFou3WHtWzNO1X1Cnwm7lv83FOxxzCqD+M6sCaMBOlDZAR5y+Nmz2sBJIXVYxF1oT T2HRCVixm05gFqomyssY1Ot4j1Zaifgs65db+tGw67w6QEge5XppMiTaLHofyCyZpvijZOVuElW t4FZ/U5WqtrAhrnh3Xwr9nNiU7QkkbvwadTsJ7EzIHqV1n1de21Wu77NCvNhLiP199DTZeFb9BN Xr3+GSmPPCliR92C3FYOoTq6QwLa33GxkPxMuyShQrCeu4vKRRFjgrAVMQkEbgudLABrgWJQFu8 QZnMX0bAForSn3t9sZ2AcVCD1wGLRj8yzm6YDopE2nAxyMxgcTrELmlHAh72bnUcOMiT4usnnbp isP+HC3Fxsbci1FrWkXlY1J5ag1j3MNBUd4uIFZth2y0pvpigrYel8cndkp9DE8x7INtA3aqKg5 KXrLNETmAI1SqYxKDtscbSAL1SwZ6HLUj+0RZ/fEYZEVP2Iss/Bs23XFCjX1qsI5DOaVwheVJpl e+nuPaq7UDpjaUHB8CRmfMBlE/J9loLaldr3gEeD7ZN5A+S7rtvUHLYoi8QmyRqn7YJS/SwEWbg hIduuk9UhoJHaTur/OuOg89rKGmnax/W/khWHT7Uc8963lK04hAqZmwjIzWFQOYz0Ad1G4PPVw/ dDgbZx9e+yC8B0qO6db+7+oTeRVbf5X0aimzPl4izXVCC7Hw= X-Received: by 2002:a05:6a00:4b0d:b0:89f:3053:9af2 with SMTP id d2e1a72fcca58-8bc1b9f004fmr4813563b3a.12.1794466197865; Wed, 11 Nov 2026 22:49:57 -0800 (PST) Received: from localhost.localdomain ([183.96.175.225]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8baab1228e2sm3097511b3a.41.2026.11.11.22.49.54 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 11 Nov 2026 22:49:57 -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 v31 06/17] ALSA: virtio: propagate playback send failures through ACK Date: Thu, 12 Nov 2026 15:49:18 +0900 Message-ID: <20261112064929.11211-7-mynameisjune111@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20261112064929.11211-1-mynameisjune111@gmail.com> References: <20261112064929.11211-1-mynameisjune111@gmail.com> X-Mailing-List: linux-kernel@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,