From c48a03f1dc8ce161a6e680c6ea64ba3754ed572f Mon Sep 17 00:00:00 2001 From: ratchov Date: Tue, 18 May 2021 10:02:00 +0000 Subject: [PATCH] Add pre-DMA-write barrier after data is stored to memory There's already such a barrier in usbd_transfer() code-path, but this one is called when the frames are queued to the HC ring. The audio samples are stored in memory by userland later, *after* the frames are scheduled (but before they are sent on the wire) so a barrier is needed there. Without this change, the data produced by userland may stay in the CPU caches and is not "seen" by the HC's DMA engine, in turn the device plays noise on certain arm64 machines (RPI4, for instance). Fix mostly from Luca Castagnini with few tweaks from me. OK patrick@ --- sys/dev/usb/uaudio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 61d1ff837a1..3b1270ed7ca 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uaudio.c,v 1.160 2020/06/11 16:00:10 ratchov Exp $ */ +/* $OpenBSD: uaudio.c,v 1.161 2021/05/18 10:02:00 ratchov Exp $ */ /* * Copyright (c) 2018 Alexandre Ratchov * @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef UAUDIO_DEBUG #define DPRINTF(...) \ @@ -3173,6 +3174,8 @@ uaudio_pdata_copy(struct uaudio_softc *sc) } s->ubuf_pos += count; if (s->ubuf_pos == xfer->size) { + usb_syncmem(&xfer->usb_xfer->dmabuf, 0, xfer->size, + BUS_DMASYNC_PREWRITE); s->ubuf_pos = 0; #ifdef DIAGNOSTIC if (s->ubuf_xfer == s->nxfers) { -- 2.20.1