[PATCH 4/5] media: hws: harden video DMA queue ownership

From: Ben Hoff

Date: Thu Jun 25 2026 - 06:22:25 EST


---
drivers/media/pci/hws/hws_video.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/media/pci/hws/hws_video.c b/drivers/media/pci/hws/hws_video.c
index 3a7b2abda502..58bcc2e7030d 100644
--- a/drivers/media/pci/hws/hws_video.c
+++ b/drivers/media/pci/hws/hws_video.c
@@ -330,8 +330,8 @@ static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
struct hws_pcie_dev *hws;
unsigned long flags;
struct hwsvideo_buffer *buf = NULL, *next = NULL;
- bool have_next = false;
bool programmed = false;
+ int ret = 0;

if (!v)
return false;
@@ -354,22 +354,31 @@ static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
if (v->next_prepared) {
next = v->next_prepared;
v->next_prepared = NULL;
- next->slot = HWS_VIDEO_DIRECT_SLOT;
v->active = next;
- have_next = true;
+ programmed = true;
} else if (!list_empty(&v->capture_queue)) {
next = list_first_entry(&v->capture_queue,
struct hwsvideo_buffer, list);
list_del_init(&next->list);
if (v->queued_count)
v->queued_count--;
- next->slot = HWS_VIDEO_DIRECT_SLOT;
- v->active = next;
- have_next = true;
+ ret = hws_program_dma_for_buffer(hws, v->channel_index, next);
+ if (ret) {
+ list_add(&next->list, &v->capture_queue);
+ v->queued_count++;
+ next = NULL;
+ } else {
+ v->active = next;
+ programmed = true;
+ }
} else {
v->active = NULL;
}
spin_unlock_irqrestore(&v->irq_lock, flags);
+ if (ret)
+ dev_warn_ratelimited(&hws->pdev->dev,
+ "%s: failed to arm no-signal buffer ch=%u ret=%d\n",
+ tag, v->channel_index, ret);
if (!buf)
return false;
/* Complete buffer with a neutral frame so dequeuers keep running. */
@@ -385,10 +394,6 @@ static bool hws_force_no_signal_frame(struct hws_video *v, const char *tag)
vb2v->vb2_buf.timestamp = ktime_get_ns();
vb2_buffer_done(&vb2v->vb2_buf, VB2_BUF_STATE_DONE);
}
- if (have_next && next) {
- if (!hws_program_dma_for_buffer(hws, v->channel_index, next))
- programmed = true;
- }
if (programmed) {
wmb(); /* ensure descriptors visible before enabling capture */
hws_enable_video_capture(hws, v->channel_index, true);
--
2.54.0