From owner-svn-src-head@FreeBSD.ORG Tue Jun 7 17:01:52 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7C23E106564A; Tue, 7 Jun 2011 17:01:52 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6BF4D8FC0C; Tue, 7 Jun 2011 17:01:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p57H1qmB092372; Tue, 7 Jun 2011 17:01:52 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p57H1qvN092370; Tue, 7 Jun 2011 17:01:52 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201106071701.p57H1qvN092370@svn.freebsd.org> From: Alexander Motin Date: Tue, 7 Jun 2011 17:01:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r222826 - head/sys/dev/sound/pcm X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Jun 2011 17:01:52 -0000 Author: mav Date: Tue Jun 7 17:01:52 2011 New Revision: 222826 URL: http://svn.freebsd.org/changeset/base/222826 Log: Make automatic hw.snd.default_unit choice a bit more intelligent. Instead of just setting it to the first registered device, reevaluate it for each device registered, trying to choose best candidate, unless one was forced. For now use such preference order: play&rec, play, rec. As side effect, this should workaround the situation when HDMI audio output of the video card, usually not connected to anything, becomes default, that requires manual user intervention to make sound working. If at some point this won't be enough, we can try to fetch some additional priority flags from the device driver. Modified: head/sys/dev/sound/pcm/sound.c Modified: head/sys/dev/sound/pcm/sound.c ============================================================================== --- head/sys/dev/sound/pcm/sound.c Tue Jun 7 16:23:27 2011 (r222825) +++ head/sys/dev/sound/pcm/sound.c Tue Jun 7 17:01:52 2011 (r222826) @@ -51,7 +51,7 @@ int pcm_veto_load = 1; int snd_unit = -1; TUNABLE_INT("hw.snd.default_unit", &snd_unit); -static int snd_unit_auto = 0; +static int snd_unit_auto = -1; TUNABLE_INT("hw.snd.default_auto", &snd_unit_auto); SYSCTL_INT(_hw_snd, OID_AUTO, default_auto, CTLFLAG_RW, &snd_unit_auto, 0, "assign default unit to a newly attached device"); @@ -443,6 +443,7 @@ sysctl_hw_snd_default_unit(SYSCTL_HANDLE if (!PCM_REGISTERED(d) || CHN_EMPTY(d, channels.pcm)) return EINVAL; snd_unit = unit; + snd_unit_auto = 0; } return (error); } @@ -737,6 +738,32 @@ pcm_killchan(device_t dev) return (pcm_chn_destroy(ch)); } +static int +pcm_best_unit(int old) +{ + struct snddev_info *d; + int i, best, bestprio, prio; + + best = -1; + bestprio = -100; + for (i = 0; pcm_devclass != NULL && + i < devclass_get_maxunit(pcm_devclass); i++) { + d = devclass_get_softc(pcm_devclass, i); + if (!PCM_REGISTERED(d)) + continue; + prio = 0; + if (d->playcount == 0) + prio -= 10; + if (d->reccount == 0) + prio -= 2; + if (prio > bestprio || (prio == bestprio && i == old)) { + best = i; + bestprio = prio; + } + } + return (best); +} + int pcm_setstatus(device_t dev, char *str) { @@ -770,8 +797,12 @@ pcm_setstatus(device_t dev, char *str) PCM_UNLOCK(d); - if (snd_unit < 0 || snd_unit_auto != 0) + if (snd_unit_auto < 0) + snd_unit_auto = (snd_unit < 0) ? 1 : 0; + if (snd_unit < 0 || snd_unit_auto > 1) snd_unit = device_get_unit(dev); + else if (snd_unit_auto == 1) + snd_unit = pcm_best_unit(snd_unit); return (0); } @@ -1113,7 +1144,6 @@ pcm_unregister(device_t dev) struct snddev_info *d; struct pcm_channel *ch; struct thread *td; - int i; td = curthread; d = device_get_softc(dev); @@ -1216,21 +1246,9 @@ pcm_unregister(device_t dev) sndstat_release(td); if (snd_unit == device_get_unit(dev)) { - /* - * Reassign default unit to the next available dev, but - * first, reset snd_unit to something ridiculous. - */ - snd_unit = -1; - for (i = 0; pcm_devclass != NULL && - i < devclass_get_maxunit(pcm_devclass); i++) { - if (device_get_unit(dev) == i) - continue; - d = devclass_get_softc(pcm_devclass, i); - if (PCM_REGISTERED(d)) { - snd_unit = i; - break; - } - } + snd_unit = pcm_best_unit(-1); + if (snd_unit_auto == 0) + snd_unit_auto = 1; } return (0);