git: ebe18cb1a545 - stable/14 - snd_uaudio(4): Fix sample rate selection after 42fdcd9fd917.

From: Christos Margiolis <christos_at_FreeBSD.org>
Date: Mon, 04 Mar 2024 00:39:14 UTC
The branch stable/14 has been updated by christos:

URL: https://cgit.FreeBSD.org/src/commit/?id=ebe18cb1a545f41ce071f20494869c775d9255bf

commit ebe18cb1a545f41ce071f20494869c775d9255bf
Author:     Florian Walpen <dev@submerge.ch>
AuthorDate: 2024-02-26 23:27:47 +0000
Commit:     Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2024-03-04 00:38:58 +0000

    snd_uaudio(4): Fix sample rate selection after 42fdcd9fd917.
    
    The sample rate selection of snd_uaudio(4) at runtime was implicitly
    relying on a specific order in the device config list. In case a default
    was set through the hw.usb.uaudio.default_rate sysctl tunable, commit
    42fdcd9fd917 removed a duplicate sample rate entry from that list, which
    inadvertently broke sample rate selection at runtime. Implement sample
    rate selection in a way that works for any order in the device config
    list.
    
    Reported by:    Lexi Winter <lexi@le-fay.org>
    MFC after:      1 week
    Reviewed by:    christos
    Differential Revision:  https://reviews.freebsd.org/D44051
    
    (cherry picked from commit a9341f0f0ae01b4d249dbf3bacfa420152c46aef)
---
 sys/dev/sound/usb/uaudio.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index 26d95bf3ee9f..5d7396c527e0 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -2768,20 +2768,19 @@ int
 uaudio_chan_set_param_speed(struct uaudio_chan *ch, uint32_t speed)
 {
 	struct uaudio_softc *sc;
-	uint8_t x;
+	uint8_t x, y;
 
 	sc = ch->priv_sc;
 
-	for (x = 0; x < ch->num_alt; x++) {
-		if (ch->usb_alt[x].sample_rate < speed) {
-			/* sample rate is too low */
-			break;
-		}
+	for (x = 0, y = 1; y < ch->num_alt; y++) {
+		/* prefer sample rate closer to and greater than requested */
+		if ((ch->usb_alt[x].sample_rate < speed &&
+		    ch->usb_alt[x].sample_rate < ch->usb_alt[y].sample_rate) ||
+		    (speed <= ch->usb_alt[y].sample_rate &&
+		    ch->usb_alt[y].sample_rate < ch->usb_alt[x].sample_rate))
+			x = y;
 	}
 
-	if (x != 0)
-		x--;
-
 	usb_proc_explore_lock(sc->sc_udev);
 	ch->set_alt = x;
 	usb_proc_explore_unlock(sc->sc_udev);