Module Name:    src
Committed By:   isaki
Date:           Wed Apr 20 07:11:14 UTC 2022

Modified Files:
        src/sys/dev/audio: audio.c audiodef.h

Log Message:
audio(4): Rework AUDIO_GETOOFFS.
- Count .samples/.deltablks in blocks.  It makes .deltablks integer wrap
  around safe.
- Remove suspicious one block offset from .offset.  I added the offset
  because it was observed so on NetBSD7.  But according to manpage, it
  should not be.  And it looks fine without the offset.
- Related to that, remove a comment in AUDIO_WSEEK.
  Limit the user-visible buffer to usrbuf only.


To generate a diff of this commit:
cvs rdiff -u -r1.126 -r1.127 src/sys/dev/audio/audio.c
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/audio/audiodef.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/audio/audio.c
diff -u src/sys/dev/audio/audio.c:1.126 src/sys/dev/audio/audio.c:1.127
--- src/sys/dev/audio/audio.c:1.126	Wed Apr 20 06:05:22 2022
+++ src/sys/dev/audio/audio.c	Wed Apr 20 07:11:13 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.126 2022/04/20 06:05:22 isaki Exp $	*/
+/*	$NetBSD: audio.c,v 1.127 2022/04/20 07:11:13 isaki Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -181,7 +181,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.126 2022/04/20 06:05:22 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.127 2022/04/20 07:11:13 isaki Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -2985,7 +2985,7 @@ audio_ioctl(dev_t dev, struct audio_soft
 	audio_encoding_t *ae;
 	audio_format_query_t *query;
 	u_int stamp;
-	u_int offs;
+	u_int offset;
 	int val;
 	int index;
 	int error;
@@ -3104,28 +3104,23 @@ audio_ioctl(dev_t dev, struct audio_soft
 		}
 		mutex_enter(sc->sc_lock);
 		mutex_enter(sc->sc_intr_lock);
-		/* figure out where next DMA will start */
-		stamp = track->usrbuf_stamp;
-		offs = track->usrbuf.head;
+		/* figure out where next transfer will start */
+		stamp = track->stamp;
+		offset = track->usrbuf.head;
 		mutex_exit(sc->sc_intr_lock);
 		mutex_exit(sc->sc_lock);
 
-		ao->samples = stamp;
-		ao->deltablks = (stamp / track->usrbuf_blksize) -
-		    (track->usrbuf_stamp_last / track->usrbuf_blksize);
-		track->usrbuf_stamp_last = stamp;
-		offs = rounddown(offs, track->usrbuf_blksize)
-		    + track->usrbuf_blksize;
-		if (offs >= track->usrbuf.capacity)
-			offs -= track->usrbuf.capacity;
-		ao->offset = offs;
-
+		/* samples will overflow soon but is as per spec. */
+		ao->samples = stamp * track->usrbuf_blksize;
+		ao->deltablks = stamp - track->last_stamp;
+		ao->offset = offset;
 		TRACET(2, track, "%s samples=%u deltablks=%u offset=%u",
 		    pre, ao->samples, ao->deltablks, ao->offset);
+
+		track->last_stamp = stamp;
 		break;
 
 	case AUDIO_WSEEK:
-		/* XXX return value does not include outbuf one. */
 		track = file->ptrack;
 		if (track) {
 			val = track->usrbuf.used;
@@ -4964,8 +4959,6 @@ audio_track_play(audio_track_t *track)
 	count = uimin(usrbuf->used, track->usrbuf_blksize) / framesize;
 	bytes = count * framesize;
 
-	track->usrbuf_stamp += bytes;
-
 	if (usrbuf->head + bytes < usrbuf->capacity) {
 		memcpy((uint8_t *)input->mem + auring_tail(input) * framesize,
 		    (uint8_t *)usrbuf->mem + usrbuf->head,
@@ -5060,6 +5053,8 @@ audio_track_play(audio_track_t *track)
 		track->outputcounter += track->outbuf.used - track_count_0;
 	}
 
+	track->stamp++;
+
 #if defined(AUDIO_DEBUG)
 	if (audiodebug >= 3) {
 		struct audio_track_debugbuf m;
@@ -6311,6 +6306,8 @@ audio_track_clear(struct audio_softc *sc
 	track->outbuf.used = 0;
 
 	/* Clear counters. */
+	track->stamp = 0;
+	track->last_stamp = 0;
 	track->dropframes = 0;
 
 	audio_track_lock_exit(track);
@@ -7773,7 +7770,7 @@ audiogetinfo(struct audio_softc *sc, str
 
 	if (ptrack) {
 		pi->seek = ptrack->usrbuf.used;
-		pi->samples = ptrack->usrbuf_stamp;
+		pi->samples = ptrack->stamp * ptrack->usrbuf_blksize;
 		pi->eof = ptrack->eofcounter;
 		pi->error = (ptrack->dropframes != 0) ? 1 : 0;
 		pi->open = 1;
@@ -7784,7 +7781,7 @@ audiogetinfo(struct audio_softc *sc, str
 
 	if (rtrack) {
 		ri->seek = audio_track_readablebytes(rtrack);
-		ri->samples = rtrack->usrbuf_stamp;
+		ri->samples = rtrack->stamp * rtrack->usrbuf_blksize;
 		ri->eof = 0;
 		ri->error = (rtrack->dropframes != 0) ? 1 : 0;
 		ri->open = 1;

Index: src/sys/dev/audio/audiodef.h
diff -u src/sys/dev/audio/audiodef.h:1.17 src/sys/dev/audio/audiodef.h:1.18
--- src/sys/dev/audio/audiodef.h:1.17	Wed Apr 20 06:05:22 2022
+++ src/sys/dev/audio/audiodef.h	Wed Apr 20 07:11:13 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: audiodef.h,v 1.17 2022/04/20 06:05:22 isaki Exp $	*/
+/*	$NetBSD: audiodef.h,v 1.18 2022/04/20 07:11:13 isaki Exp $	*/
 
 /*
  * Copyright (C) 2017 Tetsuya Isaki. All rights reserved.
@@ -121,8 +121,6 @@ struct audio_track {
 	u_int		usrbuf_blksize;	/* usrbuf block size in bytes */
 	struct uvm_object *uobj;
 	bool		mmapped;	/* device is mmap()-ed */
-	u_int		usrbuf_stamp;	/* transferred bytes from/to stage */
-	u_int		usrbuf_stamp_last; /* last stamp */
 	u_int		usrbuf_usedhigh;/* high water mark in bytes */
 	u_int		usrbuf_usedlow;	/* low water mark in bytes */
 
@@ -162,6 +160,13 @@ struct audio_track {
 	u_int		volume;
 #endif
 
+	/*
+	 * For AUDIO_GET[IO]OFFS.
+	 * No locks are required for these.
+	 */
+	u_int		stamp;		/* number of transferred blocks */
+	u_int		last_stamp;
+
 	audio_trackmixer_t *mixer;	/* connected track mixer */
 
 	/* Sequence number picked up by track mixer. */

Reply via email to