From owner-svn-src-stable-10@freebsd.org Mon Apr 13 08:33:50 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 27D0A2B7006; Mon, 13 Apr 2020 08:33:50 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49122k02r0z4GyN; Mon, 13 Apr 2020 08:33:50 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id F0CF1186FB; Mon, 13 Apr 2020 08:33:49 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03D8XntG083376; Mon, 13 Apr 2020 08:33:49 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03D8XnLU083375; Mon, 13 Apr 2020 08:33:49 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004130833.03D8XnLU083375@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 08:33:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359847 - stable/10/sys/dev/mlx5/mlx5_en X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/mlx5/mlx5_en X-SVN-Commit-Revision: 359847 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 08:33:50 -0000 Author: hselasky Date: Mon Apr 13 08:33:49 2020 New Revision: 359847 URL: https://svnweb.freebsd.org/changeset/base/359847 Log: MFC r359654: Ensure a minimum inline size of 16 bytes in mlx5en(4). This includes 14 bytes of ethernet header and 2 bytes of VLAN header. This allows for making assumptions about the inline size limit in the fast transmit path later on. Use a signed integer variable to catch underflow. Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c ============================================================================== --- stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Mon Apr 13 08:28:02 2020 (r359846) +++ stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Mon Apr 13 08:33:49 2020 (r359847) @@ -2880,11 +2880,19 @@ mlx5e_check_required_hca_cap(struct mlx5_core_dev *mde static u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev) { - int bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2; + const int min_size = ETHER_VLAN_ENCAP_LEN + ETHER_HDR_LEN; + const int max_size = MLX5E_MAX_TX_INLINE; + const int bf_buf_size = + ((1U << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2U) - + (sizeof(struct mlx5e_tx_wqe) - 2); - return bf_buf_size - - sizeof(struct mlx5e_tx_wqe) + - 2 /*sizeof(mlx5e_tx_wqe.inline_hdr_start)*/; + /* verify against driver limits */ + if (bf_buf_size > max_size) + return (max_size); + else if (bf_buf_size < min_size) + return (min_size); + else + return (bf_buf_size); } static void From owner-svn-src-stable-10@freebsd.org Mon Apr 13 09:02:18 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 079EC2B7C90; Mon, 13 Apr 2020 09:02:18 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4912gY6WHDz4KVF; Mon, 13 Apr 2020 09:02:17 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DAB8A18D08; Mon, 13 Apr 2020 09:02:17 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03D92HCn001980; Mon, 13 Apr 2020 09:02:17 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03D92H7h001978; Mon, 13 Apr 2020 09:02:17 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004130902.03D92H7h001978@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 09:02:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359855 - stable/10/sys/dev/mlx5/mlx5_en X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/mlx5/mlx5_en X-SVN-Commit-Revision: 359855 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 09:02:18 -0000 Author: hselasky Date: Mon Apr 13 09:02:17 2020 New Revision: 359855 URL: https://svnweb.freebsd.org/changeset/base/359855 Log: MFC r359653: Count number of times transmit ring is out of buffers in mlx5en(4). Differential Revision: https://reviews.freebsd.org/D24273 Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/mlx5/mlx5_en/en.h stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/mlx5/mlx5_en/en.h ============================================================================== --- stable/10/sys/dev/mlx5/mlx5_en/en.h Mon Apr 13 09:01:46 2020 (r359854) +++ stable/10/sys/dev/mlx5/mlx5_en/en.h Mon Apr 13 09:02:17 2020 (r359855) @@ -355,6 +355,7 @@ struct mlx5e_rq_stats { m(+1, u64 csum_offload_none, "csum_offload_none", "Transmitted packets") \ m(+1, u64 defragged, "defragged", "Transmitted packets") \ m(+1, u64 dropped, "dropped", "Transmitted packets") \ + m(+1, u64 enobuf, "enobuf", "Transmitted packets") \ m(+1, u64 nop, "nop", "Transmitted packets") #define MLX5E_SQ_STATS_NUM (0 MLX5E_SQ_STATS(MLX5E_STATS_COUNT)) Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c ============================================================================== --- stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Mon Apr 13 09:01:46 2020 (r359854) +++ stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Mon Apr 13 09:02:17 2020 (r359855) @@ -255,6 +255,7 @@ mlx5e_sq_xmit(struct mlx5e_sq *sq, struct mbuf **mbp) * of the mbuf into the drbr (see mlx5e_xmit_locked) */ if (unlikely(!mlx5e_sq_has_room_for(sq, 2 * MLX5_SEND_WQE_MAX_WQEBBS))) { + sq->stats.enobuf++; return (ENOBUFS); } @@ -264,8 +265,10 @@ mlx5e_sq_xmit(struct mlx5e_sq *sq, struct mbuf **mbp) /* Send one multi NOP message instead of many */ mlx5e_send_nop(sq, (pi + 1) * MLX5_SEND_WQEBB_NUM_DS); pi = ((~sq->pc) & sq->wq.sz_m1); - if (pi < (MLX5_SEND_WQE_MAX_WQEBBS - 1)) + if (pi < (MLX5_SEND_WQE_MAX_WQEBBS - 1)) { + sq->stats.enobuf++; return (ENOMEM); + } } /* Setup local variables */ From owner-svn-src-stable-10@freebsd.org Mon Apr 13 16:19:46 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id A0FE92C25E3; Mon, 13 Apr 2020 16:19:46 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491DNL1yPHz3KdH; Mon, 13 Apr 2020 16:19:46 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3E69B1E1F7; Mon, 13 Apr 2020 16:19:46 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03DGJkkO080501; Mon, 13 Apr 2020 16:19:46 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03DGJkZD080500; Mon, 13 Apr 2020 16:19:46 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004131619.03DGJkZD080500@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 16:19:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359869 - stable/10/sys/dev/sound/usb X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/sound/usb X-SVN-Commit-Revision: 359869 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 16:19:46 -0000 Author: hselasky Date: Mon Apr 13 16:19:45 2020 New Revision: 359869 URL: https://svnweb.freebsd.org/changeset/base/359869 Log: MFC r359320: Avoid scaling USB audio mixer values twice. Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/sound/usb/uaudio.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sound/usb/uaudio.c ============================================================================== --- stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:19:12 2020 (r359868) +++ stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:19:45 2020 (r359869) @@ -558,10 +558,7 @@ static void uaudio_mixer_add_ctl(struct uaudio_softc * struct uaudio_mixer_node *); static void uaudio_mixer_fill_info(struct uaudio_softc *, struct usb_device *, void *); -static void uaudio_mixer_ctl_set(struct uaudio_softc *, - struct uaudio_mixer_node *, uint8_t, int32_t val); static int uaudio_mixer_signext(uint8_t, int); -static int uaudio_mixer_bsd2value(struct uaudio_mixer_node *, int32_t val); static void uaudio_mixer_init(struct uaudio_softc *); static const struct uaudio_terminal_node *uaudio_mixer_get_input( const struct uaudio_terminal_node *, uint8_t); @@ -5379,7 +5376,7 @@ uaudio_mixer_signext(uint8_t type, int val) } static int -uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int32_t val) +uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int val) { if (mc->type == MIX_ON_OFF) { val = (val != 0); @@ -5391,7 +5388,7 @@ uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, i } else { /* compute actual volume */ - val = (val * mc->mul) / 255; + val = (val * mc->mul) / 100; /* add lower offset */ val = val + mc->minval; @@ -5410,7 +5407,7 @@ uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, i static void uaudio_mixer_ctl_set(struct uaudio_softc *sc, struct uaudio_mixer_node *mc, - uint8_t chan, int32_t val) + uint8_t chan, int val) { val = uaudio_mixer_bsd2value(mc, val); @@ -5499,8 +5496,7 @@ uaudio_mixer_set(struct uaudio_softc *sc, unsigned typ if (mc->ctl == type) { for (chan = 0; chan < mc->nchan; chan++) { uaudio_mixer_ctl_set(sc, mc, chan, - (int)((chan == 0 ? left : right) * - 255) / 100); + chan == 0 ? left : right); } } } From owner-svn-src-stable-10@freebsd.org Mon Apr 13 16:22:15 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C039B2C28D1; Mon, 13 Apr 2020 16:22:15 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491DRC4nllz3LFJ; Mon, 13 Apr 2020 16:22:15 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9DCE91E29D; Mon, 13 Apr 2020 16:22:15 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03DGMFxL083838; Mon, 13 Apr 2020 16:22:15 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03DGMFmw083837; Mon, 13 Apr 2020 16:22:15 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004131622.03DGMFmw083837@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 16:22:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359872 - stable/10/sys/dev/sound/usb X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/sound/usb X-SVN-Commit-Revision: 359872 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 16:22:15 -0000 Author: hselasky Date: Mon Apr 13 16:22:15 2020 New Revision: 359872 URL: https://svnweb.freebsd.org/changeset/base/359872 Log: MFC r359321: Factor out USB audio mixer value range check. Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/sound/usb/uaudio.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sound/usb/uaudio.c ============================================================================== --- stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:21:38 2020 (r359871) +++ stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:22:15 2020 (r359872) @@ -5380,25 +5380,19 @@ uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, i { if (mc->type == MIX_ON_OFF) { val = (val != 0); - } else if (mc->type == MIX_SELECTOR) { - if ((val < mc->minval) || - (val > mc->maxval)) { - val = mc->minval; - } - } else { + } else if (mc->type != MIX_SELECTOR) { /* compute actual volume */ val = (val * mc->mul) / 100; /* add lower offset */ val = val + mc->minval; - - /* make sure we don't write a value out of range */ - if (val > mc->maxval) - val = mc->maxval; - else if (val < mc->minval) - val = mc->minval; } + /* make sure we don't write a value out of range */ + if (val > mc->maxval) + val = mc->maxval; + else if (val < mc->minval) + val = mc->minval; DPRINTFN(6, "type=0x%03x val=%d min=%d max=%d val=%d\n", mc->type, val, mc->minval, mc->maxval, val); From owner-svn-src-stable-10@freebsd.org Mon Apr 13 16:24:22 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9DD3A2C2A56; Mon, 13 Apr 2020 16:24:22 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491DTf3k9dz3Lcs; Mon, 13 Apr 2020 16:24:22 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7AD091E3ED; Mon, 13 Apr 2020 16:24:22 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03DGOMr7086640; Mon, 13 Apr 2020 16:24:22 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03DGOMQw086639; Mon, 13 Apr 2020 16:24:22 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004131624.03DGOMQw086639@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 16:24:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359875 - stable/10/sys/dev/sound/usb X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/sound/usb X-SVN-Commit-Revision: 359875 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 16:24:22 -0000 Author: hselasky Date: Mon Apr 13 16:24:21 2020 New Revision: 359875 URL: https://svnweb.freebsd.org/changeset/base/359875 Log: MFC r359322: Make mute controls available for USB audio mixers. Submitted by: Horse Ma Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/sound/usb/uaudio.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sound/usb/uaudio.c ============================================================================== --- stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:23:46 2020 (r359874) +++ stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:24:21 2020 (r359875) @@ -3579,7 +3579,7 @@ uaudio_mixer_add_feature(struct uaudio_softc *sc, switch (ctl) { case MUTE_CONTROL: MIX(sc).type = MIX_ON_OFF; - MIX(sc).ctl = SOUND_MIXER_NRDEVICES; + MIX(sc).ctl = SOUND_MIXER_MUTE; MIX(sc).name = "mute"; break; @@ -3694,7 +3694,7 @@ uaudio20_mixer_add_feature(struct uaudio_softc *sc, switch (ctl) { case (3 << 0): MIX(sc).type = MIX_ON_OFF; - MIX(sc).ctl = SOUND_MIXER_NRDEVICES; + MIX(sc).ctl = SOUND_MIXER_MUTE; MIX(sc).name = "mute"; what = MUTE_CONTROL; break; From owner-svn-src-stable-10@freebsd.org Mon Apr 13 16:26:16 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 51AF92C2BC1; Mon, 13 Apr 2020 16:26:16 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491DWr1Xyvz3Lyf; Mon, 13 Apr 2020 16:26:16 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2DEFA1E3F0; Mon, 13 Apr 2020 16:26:16 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03DGQGL5086948; Mon, 13 Apr 2020 16:26:16 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03DGQGgE086947; Mon, 13 Apr 2020 16:26:16 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004131626.03DGQGgE086947@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 16:26:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359878 - stable/10/sys/dev/sound/usb X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/sound/usb X-SVN-Commit-Revision: 359878 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 16:26:16 -0000 Author: hselasky Date: Mon Apr 13 16:26:15 2020 New Revision: 359878 URL: https://svnweb.freebsd.org/changeset/base/359878 Log: MFC r359323: Be more intelligent when classifying USB audio terminal types, so that we don't end up using SOUND_MIXER_VOLUME for all undefined types. Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/sound/usb/uaudio.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sound/usb/uaudio.c ============================================================================== --- stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:25:44 2020 (r359877) +++ stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:26:15 2020 (r359878) @@ -4515,52 +4515,61 @@ static const struct uaudio_tt_to_feature uaudio_tt_to_ {UATF_MULTITRACK, SOUND_MIXER_VOLUME}, {0xffff, SOUND_MIXER_VOLUME}, - /* default */ - {0x0000, SOUND_MIXER_VOLUME}, + /* end */ + {} }; static uint16_t -uaudio_mixer_feature_name(const struct uaudio_terminal_node *iot, - struct uaudio_mixer_node *mix) +uaudio_mixer_feature_name_sub(uint16_t terminal_type) { const struct uaudio_tt_to_feature *uat = uaudio_tt_to_feature; - uint16_t terminal_type = uaudio_mixer_determine_class(iot, mix); + uint16_t retval; - if ((mix->class == UAC_RECORD) && (terminal_type == 0)) { - return (SOUND_MIXER_IMIX); - } - while (uat->terminal_type) { - if (uat->terminal_type == terminal_type) { - break; + while (1) { + if (uat->terminal_type == 0) { + switch (terminal_type >> 8) { + case UATI_UNDEFINED >> 8: + retval = SOUND_MIXER_RECLEV; + goto done; + case UATO_UNDEFINED >> 8: + retval = SOUND_MIXER_PCM; + goto done; + default: + retval = SOUND_MIXER_VOLUME; + goto done; + } + } else if (uat->terminal_type == terminal_type) { + retval = uat->feature; + goto done; } uat++; } - +done: DPRINTF("terminal_type=0x%04x -> %d\n", - terminal_type, uat->feature); + terminal_type, retval); + return (retval); +} - return (uat->feature); +static uint16_t +uaudio_mixer_feature_name(const struct uaudio_terminal_node *iot, + struct uaudio_mixer_node *mix) +{ + uint16_t terminal_type = uaudio_mixer_determine_class(iot, mix); + + if (mix->class == UAC_RECORD && terminal_type == 0) + return (SOUND_MIXER_IMIX); + return (uaudio_mixer_feature_name_sub(terminal_type)); } static uint16_t uaudio20_mixer_feature_name(const struct uaudio_terminal_node *iot, struct uaudio_mixer_node *mix) { - const struct uaudio_tt_to_feature *uat; uint16_t terminal_type = uaudio20_mixer_determine_class(iot, mix); - if ((mix->class == UAC_RECORD) && (terminal_type == 0)) + if (mix->class == UAC_RECORD && terminal_type == 0) return (SOUND_MIXER_IMIX); - - for (uat = uaudio_tt_to_feature; uat->terminal_type != 0; uat++) { - if (uat->terminal_type == terminal_type) - break; - } - - DPRINTF("terminal_type=0x%04x -> %d\n", - terminal_type, uat->feature); - - return (uat->feature); + return (uaudio_mixer_feature_name_sub(terminal_type)); } static const struct uaudio_terminal_node * From owner-svn-src-stable-10@freebsd.org Mon Apr 13 16:28:16 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 3BB452C2D52; Mon, 13 Apr 2020 16:28:16 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491DZ815rzz3MLN; Mon, 13 Apr 2020 16:28:16 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 20DBE1E3F3; Mon, 13 Apr 2020 16:28:16 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03DGSGMs087233; Mon, 13 Apr 2020 16:28:16 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03DGSG7j087232; Mon, 13 Apr 2020 16:28:16 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004131628.03DGSG7j087232@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 16:28:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359881 - stable/10/sys/dev/sound/usb X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/sound/usb X-SVN-Commit-Revision: 359881 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 16:28:16 -0000 Author: hselasky Date: Mon Apr 13 16:28:15 2020 New Revision: 359881 URL: https://svnweb.freebsd.org/changeset/base/359881 Log: MFC r359355: Improve USB audio mixer support for USB audio class 1 and 2. - make sure volume controls are correctly mapped to "pcm" and "rec" depending on how they deliver audio to the USB host. - make sure there are no duplicate record selections. - remove internal only mixer class type. - don't add software volume controls for recording only. - some minor mixer code cleanup. Tested by: Horse Ma Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/sound/usb/uaudio.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sound/usb/uaudio.c ============================================================================== --- stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:27:40 2020 (r359880) +++ stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:28:15 2020 (r359881) @@ -198,7 +198,6 @@ struct uaudio_mixer_node { #define MAX_SELECTOR_INPUT_PIN 256 uint8_t slctrtype[MAX_SELECTOR_INPUT_PIN]; - uint8_t class; uint8_t val_default; uint8_t desc[64]; @@ -459,19 +458,6 @@ static const struct uaudio_format uaudio20_formats[] = {0, 0, 0, NULL} }; -#define UAC_OUTPUT 0 -#define UAC_INPUT 1 -#define UAC_EQUAL 2 -#define UAC_RECORD 3 -#define UAC_NCLASSES 4 - -#ifdef USB_DEBUG -static const char *uac_names[] = { - "outputs", "inputs", "equalization", "record" -}; - -#endif - /* prototypes */ static device_probe_t uaudio_probe; @@ -515,10 +501,7 @@ static void uaudio_mixer_add_extension(struct uaudio_s const struct uaudio_terminal_node *, int); static struct usb_audio_cluster uaudio_mixer_get_cluster(uint8_t, const struct uaudio_terminal_node *); -static uint16_t uaudio_mixer_determine_class(const struct uaudio_terminal_node *, - struct uaudio_mixer_node *); -static uint16_t uaudio_mixer_feature_name(const struct uaudio_terminal_node *, - struct uaudio_mixer_node *); +static uint16_t uaudio_mixer_determine_class(const struct uaudio_terminal_node *); static void uaudio_mixer_find_inputs_sub(struct uaudio_terminal_node *, const uint8_t *, uint8_t, struct uaudio_search_result *); static const void *uaudio_mixer_verify_desc(const void *, uint32_t); @@ -536,10 +519,7 @@ static void uaudio20_mixer_add_feature(struct uaudio_s const struct uaudio_terminal_node *, int); static struct usb_audio20_cluster uaudio20_mixer_get_cluster(uint8_t, const struct uaudio_terminal_node *); -static uint16_t uaudio20_mixer_determine_class(const struct uaudio_terminal_node *, - struct uaudio_mixer_node *); -static uint16_t uaudio20_mixer_feature_name(const struct uaudio_terminal_node *, - struct uaudio_mixer_node *); +static uint16_t uaudio20_mixer_determine_class(const struct uaudio_terminal_node *); static void uaudio20_mixer_find_inputs_sub(struct uaudio_terminal_node *, const uint8_t *, uint8_t, struct uaudio_search_result *); static const void *uaudio20_mixer_verify_desc(const void *, uint32_t); @@ -560,12 +540,6 @@ static void uaudio_mixer_fill_info(struct uaudio_softc struct usb_device *, void *); static int uaudio_mixer_signext(uint8_t, int); static void uaudio_mixer_init(struct uaudio_softc *); -static const struct uaudio_terminal_node *uaudio_mixer_get_input( - const struct uaudio_terminal_node *, uint8_t); -static const struct uaudio_terminal_node *uaudio_mixer_get_output( - const struct uaudio_terminal_node *, uint8_t); -static void uaudio_mixer_find_outputs_sub(struct uaudio_terminal_node *, - uint8_t, uint8_t, struct uaudio_search_result *); static uint8_t umidi_convert_to_usb(struct umidi_sub_chan *, uint8_t, uint8_t); static struct umidi_sub_chan *umidi_sub_by_fifo(struct usb_fifo *); static void umidi_start_read(struct usb_fifo *); @@ -1142,7 +1116,8 @@ uaudio_attach_sub(device_t dev, kobj_class_t mixer_cla DPRINTF("hardware has swapped left and right\n"); /* uaudio_pcm_setflags(dev, SD_F_PSWAPLR); */ } - if (!(sc->sc_mix_info & SOUND_MASK_PCM)) { + if (sc->sc_play_chan.num_alt > 0 && + (sc->sc_mix_info & SOUND_MASK_PCM) == 0) { DPRINTF("emulating master volume\n"); @@ -2966,7 +2941,6 @@ uaudio_mixer_controls_create_ftu(struct uaudio_softc * memset(&MIX(sc), 0, sizeof(MIX(sc))); MIX(sc).wIndex = MAKE_WORD(6, sc->sc_mixer_iface_no); MIX(sc).wValue[0] = MAKE_WORD(8, 0); - MIX(sc).class = UAC_OUTPUT; MIX(sc).type = MIX_UNSIGNED_16; MIX(sc).ctl = SOUND_MIXER_NRDEVICES; MIX(sc).name = "effect"; @@ -3013,7 +2987,6 @@ uaudio_mixer_controls_create_ftu(struct uaudio_softc * memset(&MIX(sc), 0, sizeof(MIX(sc))); MIX(sc).wIndex = MAKE_WORD(6, sc->sc_mixer_iface_no); MIX(sc).wValue[0] = MAKE_WORD(2, 0); - MIX(sc).class = UAC_OUTPUT; MIX(sc).type = MIX_SIGNED_8; MIX(sc).ctl = SOUND_MIXER_NRDEVICES; MIX(sc).name = "effect_vol"; @@ -3030,7 +3003,6 @@ uaudio_mixer_controls_create_ftu(struct uaudio_softc * memset(&MIX(sc), 0, sizeof(MIX(sc))); MIX(sc).wIndex = MAKE_WORD(6, sc->sc_mixer_iface_no); MIX(sc).wValue[0] = MAKE_WORD(3, 0); - MIX(sc).class = UAC_OUTPUT; MIX(sc).type = MIX_SIGNED_16; MIX(sc).ctl = SOUND_MIXER_NRDEVICES; MIX(sc).name = "effect_dur"; @@ -3047,7 +3019,6 @@ uaudio_mixer_controls_create_ftu(struct uaudio_softc * memset(&MIX(sc), 0, sizeof(MIX(sc))); MIX(sc).wIndex = MAKE_WORD(6, sc->sc_mixer_iface_no); MIX(sc).wValue[0] = MAKE_WORD(4, 0); - MIX(sc).class = UAC_OUTPUT; MIX(sc).type = MIX_SIGNED_8; MIX(sc).ctl = SOUND_MIXER_NRDEVICES; MIX(sc).name = "effect_fb"; @@ -3169,12 +3140,7 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct u { int32_t res; - if (mc->class < UAC_NCLASSES) { - DPRINTF("adding %s.%d\n", - uac_names[mc->class], mc->ctl); - } else { - DPRINTF("adding %d\n", mc->ctl); - } + DPRINTF("adding %d\n", mc->ctl); if (mc->type == MIX_ON_OFF) { mc->minval = 0; @@ -3266,7 +3232,6 @@ uaudio_mixer_add_mixer(struct uaudio_softc *sc, memset(&MIX(sc), 0, sizeof(MIX(sc))); MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); - uaudio_mixer_determine_class(&iot[id], &MIX(sc)); MIX(sc).type = MIX_SIGNED_16; if (uaudio_mixer_verify_desc(d0, ((ichs * ochs) + 7) / 8) == NULL) @@ -3345,7 +3310,6 @@ uaudio20_mixer_add_mixer(struct uaudio_softc *sc, memset(&MIX(sc), 0, sizeof(MIX(sc))); MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); - uaudio20_mixer_determine_class(&iot[id], &MIX(sc)); MIX(sc).type = MIX_SIGNED_16; if (uaudio20_mixer_verify_desc(d0, ((ichs * ochs) + 7) / 8) == NULL) @@ -3385,6 +3349,58 @@ uaudio20_mixer_add_mixer(struct uaudio_softc *sc, } static void +uaudio_mixer_check_selectors(struct uaudio_softc *sc) +{ + uint8_t reserve_feature[] = { + SOUND_MIXER_LINE, + SOUND_MIXER_LINE1, + SOUND_MIXER_LINE2, + SOUND_MIXER_LINE3, + SOUND_MIXER_DIGITAL1, + SOUND_MIXER_DIGITAL2, + SOUND_MIXER_DIGITAL3, + }; + const uint16_t reserve_max = + sizeof(reserve_feature) / sizeof(reserve_feature[0]); + uint16_t i; + uint16_t j; + uint16_t k; + + /* remove existing selector types from the reserve */ + for (i = 0; i < MIX(sc).maxval; i++) { + if (MIX(sc).slctrtype[i] == SOUND_MIXER_NRDEVICES) + continue; + for (j = 0; j != reserve_max; j++) { + if (reserve_feature[j] == MIX(sc).slctrtype[i]) + reserve_feature[j] = SOUND_MIXER_NRDEVICES; + } + } + + /* make sure selector types are not overlapping */ + for (i = 0; i < MIX(sc).maxval; i++) { + if (MIX(sc).slctrtype[i] == SOUND_MIXER_NRDEVICES) + continue; + for (j = i + 1; j < MIX(sc).maxval; j++) { + if (MIX(sc).slctrtype[j] == SOUND_MIXER_NRDEVICES) + continue; + if (MIX(sc).slctrtype[i] != MIX(sc).slctrtype[j]) + continue; + for (k = 0; k != reserve_max; k++) { + if (reserve_feature[k] == SOUND_MIXER_NRDEVICES) + continue; + MIX(sc).slctrtype[j] = reserve_feature[k]; + reserve_feature[k] = SOUND_MIXER_NRDEVICES; + break; + } + if (k == reserve_max) { + DPRINTF("Selector type %d is not selectable!\n", j); + MIX(sc).slctrtype[j] = SOUND_MIXER_NRDEVICES; + } + } + } +} + +static void uaudio_mixer_add_selector(struct uaudio_softc *sc, const struct uaudio_terminal_node *iot, int id) { @@ -3401,7 +3417,6 @@ uaudio_mixer_add_selector(struct uaudio_softc *sc, MIX(sc).wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no); MIX(sc).wValue[0] = MAKE_WORD(0, 0); - uaudio_mixer_determine_class(&iot[id], &MIX(sc)); MIX(sc).nchan = 1; MIX(sc).type = MIX_SELECTOR; MIX(sc).ctl = SOUND_MIXER_NRDEVICES; @@ -3416,21 +3431,19 @@ uaudio_mixer_add_selector(struct uaudio_softc *sc, MIX(sc).desc[0] = 0; } - if (MIX(sc).maxval > MAX_SELECTOR_INPUT_PIN) { + if (MIX(sc).maxval > MAX_SELECTOR_INPUT_PIN) MIX(sc).maxval = MAX_SELECTOR_INPUT_PIN; - } - MIX(sc).mul = (MIX(sc).maxval - MIX(sc).minval); - for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) { - MIX(sc).slctrtype[i] = SOUND_MIXER_NRDEVICES; - } + MIX(sc).mul = MIX(sc).maxval - MIX(sc).minval; + for (i = 0; i < MIX(sc).maxval; i++) { - MIX(sc).slctrtype[i] = uaudio_mixer_feature_name( - &iot[d->baSourceId[i]], &MIX(sc)); + MIX(sc).slctrtype[i] = + uaudio_mixer_determine_class(&iot[d->baSourceId[i]]); } + for (; i < MAX_SELECTOR_INPUT_PIN; i++) + MIX(sc).slctrtype[i] = SOUND_MIXER_NRDEVICES; - MIX(sc).class = 0; /* not used */ - + uaudio_mixer_check_selectors(sc); uaudio_mixer_add_ctl(sc, &MIX(sc)); } @@ -3451,7 +3464,6 @@ uaudio20_mixer_add_selector(struct uaudio_softc *sc, MIX(sc).wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no); MIX(sc).wValue[0] = MAKE_WORD(0, 0); - uaudio20_mixer_determine_class(&iot[id], &MIX(sc)); MIX(sc).nchan = 1; MIX(sc).type = MIX_SELECTOR; MIX(sc).ctl = SOUND_MIXER_NRDEVICES; @@ -3469,17 +3481,16 @@ uaudio20_mixer_add_selector(struct uaudio_softc *sc, if (MIX(sc).maxval > MAX_SELECTOR_INPUT_PIN) MIX(sc).maxval = MAX_SELECTOR_INPUT_PIN; - MIX(sc).mul = (MIX(sc).maxval - MIX(sc).minval); - for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) - MIX(sc).slctrtype[i] = SOUND_MIXER_NRDEVICES; + MIX(sc).mul = MIX(sc).maxval - MIX(sc).minval; for (i = 0; i < MIX(sc).maxval; i++) { - MIX(sc).slctrtype[i] = uaudio20_mixer_feature_name( - &iot[d->baSourceId[i]], &MIX(sc)); + MIX(sc).slctrtype[i] = + uaudio20_mixer_determine_class(&iot[d->baSourceId[i]]); } + for (; i < MAX_SELECTOR_INPUT_PIN; i++) + MIX(sc).slctrtype[i] = SOUND_MIXER_NRDEVICES; - MIX(sc).class = 0; /* not used */ - + uaudio_mixer_check_selectors(sc); uaudio_mixer_add_ctl(sc, &MIX(sc)); } @@ -3540,9 +3551,9 @@ uaudio_mixer_add_feature(struct uaudio_softc *sc, cmask |= uaudio_mixer_feature_get_bmaControls(d, chan); } - if (nchan > MIX_MAX_CHAN) { + if (nchan > MIX_MAX_CHAN) nchan = MIX_MAX_CHAN; - } + MIX(sc).wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no); i = d->bmaControls[d->bControlSize]; @@ -3574,7 +3585,7 @@ uaudio_mixer_add_feature(struct uaudio_softc *sc, continue; } - mixernumber = uaudio_mixer_feature_name(&iot[id], &MIX(sc)); + mixernumber = uaudio_mixer_determine_class(&iot[id]); switch (ctl) { case MUTE_CONTROL: @@ -3689,7 +3700,7 @@ uaudio20_mixer_add_feature(struct uaudio_softc *sc, for (ctl = 3; ctl != 0; ctl <<= 2) { - mixernumber = uaudio20_mixer_feature_name(&iot[id], &MIX(sc)); + mixernumber = uaudio20_mixer_determine_class(&iot[id]); switch (ctl) { case (3 << 0): @@ -3812,7 +3823,6 @@ uaudio_mixer_add_processing_updown(struct uaudio_softc MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); MIX(sc).nchan = 1; MIX(sc).wValue[0] = MAKE_WORD(UD_MODE_SELECT_CONTROL, 0); - uaudio_mixer_determine_class(&iot[id], &MIX(sc)); MIX(sc).type = MIX_ON_OFF; /* XXX */ for (i = 0; i < ud->bNrModes; i++) { @@ -3846,7 +3856,6 @@ uaudio_mixer_add_processing(struct uaudio_softc *sc, MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); MIX(sc).nchan = 1; MIX(sc).wValue[0] = MAKE_WORD(XX_ENABLE_CONTROL, 0); - uaudio_mixer_determine_class(&iot[id], &MIX(sc)); MIX(sc).type = MIX_ON_OFF; uaudio_mixer_add_ctl(sc, &MIX(sc)); } @@ -3891,7 +3900,6 @@ uaudio_mixer_add_extension(struct uaudio_softc *sc, MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); MIX(sc).nchan = 1; MIX(sc).wValue[0] = MAKE_WORD(UA_EXT_ENABLE, 0); - uaudio_mixer_determine_class(&iot[id], &MIX(sc)); MIX(sc).type = MIX_ON_OFF; uaudio_mixer_add_ctl(sc, &MIX(sc)); @@ -4321,114 +4329,42 @@ done: return (r); } -static uint16_t -uaudio_mixer_determine_class(const struct uaudio_terminal_node *iot, - struct uaudio_mixer_node *mix) +static bool +uaudio_mixer_foreach_input(const struct uaudio_terminal_node *iot, uint8_t *pindex) { - uint16_t terminal_type = 0x0000; - const struct uaudio_terminal_node *input[2]; - const struct uaudio_terminal_node *output[2]; + uint8_t n; - input[0] = uaudio_mixer_get_input(iot, 0); - input[1] = uaudio_mixer_get_input(iot, 1); + n = *pindex; - output[0] = uaudio_mixer_get_output(iot, 0); - output[1] = uaudio_mixer_get_output(iot, 1); - - /* - * check if there is only - * one output terminal: - */ - if (output[0] && (!output[1])) { - terminal_type = - UGETW(output[0]->u.ot_v1->wTerminalType); + while (1) { + if (!n--) + n = iot->usr.id_max; + if (n == 0) + return (false); + if (iot->usr.bit_input[n / 8] & (1 << (n % 8))) + break; } - /* - * If the only output terminal is USB, - * the class is UAC_RECORD. - */ - if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) { - - mix->class = UAC_RECORD; - if (input[0] && (!input[1])) { - terminal_type = - UGETW(input[0]->u.it_v1->wTerminalType); - } else { - terminal_type = 0; - } - goto done; - } - /* - * if the unit is connected to just - * one input terminal, the - * class is UAC_INPUT: - */ - if (input[0] && (!input[1])) { - mix->class = UAC_INPUT; - terminal_type = - UGETW(input[0]->u.it_v1->wTerminalType); - goto done; - } - /* - * Otherwise, the class is UAC_OUTPUT. - */ - mix->class = UAC_OUTPUT; -done: - return (terminal_type); + *pindex = n; + return (true); } -static uint16_t -uaudio20_mixer_determine_class(const struct uaudio_terminal_node *iot, - struct uaudio_mixer_node *mix) +static bool +uaudio_mixer_foreach_output(const struct uaudio_terminal_node *iot, uint8_t *pindex) { - uint16_t terminal_type = 0x0000; - const struct uaudio_terminal_node *input[2]; - const struct uaudio_terminal_node *output[2]; + uint8_t n; - input[0] = uaudio_mixer_get_input(iot, 0); - input[1] = uaudio_mixer_get_input(iot, 1); + n = *pindex; - output[0] = uaudio_mixer_get_output(iot, 0); - output[1] = uaudio_mixer_get_output(iot, 1); - - /* - * check if there is only - * one output terminal: - */ - if (output[0] && (!output[1])) - terminal_type = UGETW(output[0]->u.ot_v2->wTerminalType); - /* - * If the only output terminal is USB, - * the class is UAC_RECORD. - */ - if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) { - - mix->class = UAC_RECORD; - if (input[0] && (!input[1])) { - terminal_type = - UGETW(input[0]->u.it_v2->wTerminalType); - } else { - terminal_type = 0; - } - goto done; + while (1) { + if (!n--) + n = iot->usr.id_max; + if (n == 0) + return (false); + if (iot->usr.bit_output[n / 8] & (1 << (n % 8))) + break; } - /* - * if the unit is connected to just - * one input terminal, the - * class is UAC_INPUT: - */ - if (input[0] && (!input[1])) { - mix->class = UAC_INPUT; - terminal_type = - UGETW(input[0]->u.it_v2->wTerminalType); - goto done; - } - /* - * Otherwise, the class is UAC_OUTPUT. - */ - mix->class = UAC_OUTPUT; -done: - return (terminal_type); + *pindex = n; + return (true); } struct uaudio_tt_to_feature { @@ -4438,8 +4374,6 @@ struct uaudio_tt_to_feature { static const struct uaudio_tt_to_feature uaudio_tt_to_feature[] = { - {UAT_STREAM, SOUND_MIXER_PCM}, - {UATI_MICROPHONE, SOUND_MIXER_MIC}, {UATI_DESKMICROPHONE, SOUND_MIXER_MIC}, {UATI_PERSONALMICROPHONE, SOUND_MIXER_MIC}, @@ -4447,11 +4381,6 @@ static const struct uaudio_tt_to_feature uaudio_tt_to_ {UATI_MICROPHONEARRAY, SOUND_MIXER_MIC}, {UATI_PROCMICROPHONEARR, SOUND_MIXER_MIC}, - {UATO_SPEAKER, SOUND_MIXER_SPEAKER}, - {UATO_DESKTOPSPEAKER, SOUND_MIXER_SPEAKER}, - {UATO_ROOMSPEAKER, SOUND_MIXER_SPEAKER}, - {UATO_COMMSPEAKER, SOUND_MIXER_SPEAKER}, - {UATE_ANALOGCONN, SOUND_MIXER_LINE}, {UATE_LINECONN, SOUND_MIXER_LINE}, {UATE_LEGACYCONN, SOUND_MIXER_LINE}, @@ -4469,63 +4398,21 @@ static const struct uaudio_tt_to_feature uaudio_tt_to_ {UATF_DVDAUDIO, SOUND_MIXER_VIDEO}, {UATF_TVTUNERAUDIO, SOUND_MIXER_VIDEO}, - /* telephony terminal types */ - {UATT_UNDEFINED, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */ - {UATT_PHONELINE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */ - {UATT_TELEPHONE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */ - {UATT_DOWNLINEPHONE, SOUND_MIXER_PHONEIN}, /* SOUND_MIXER_PHONEOUT */ - {UATF_RADIORECV, SOUND_MIXER_RADIO}, {UATF_RADIOXMIT, SOUND_MIXER_RADIO}, - {UAT_UNDEFINED, SOUND_MIXER_VOLUME}, - {UAT_VENDOR, SOUND_MIXER_VOLUME}, - {UATI_UNDEFINED, SOUND_MIXER_VOLUME}, - - /* output terminal types */ - {UATO_UNDEFINED, SOUND_MIXER_VOLUME}, - {UATO_DISPLAYAUDIO, SOUND_MIXER_VOLUME}, - {UATO_SUBWOOFER, SOUND_MIXER_VOLUME}, - {UATO_HEADPHONES, SOUND_MIXER_VOLUME}, - - /* bidir terminal types */ - {UATB_UNDEFINED, SOUND_MIXER_VOLUME}, - {UATB_HANDSET, SOUND_MIXER_VOLUME}, - {UATB_HEADSET, SOUND_MIXER_VOLUME}, - {UATB_SPEAKERPHONE, SOUND_MIXER_VOLUME}, - {UATB_SPEAKERPHONEESUP, SOUND_MIXER_VOLUME}, - {UATB_SPEAKERPHONEECANC, SOUND_MIXER_VOLUME}, - - /* external terminal types */ - {UATE_UNDEFINED, SOUND_MIXER_VOLUME}, - - /* embedded function terminal types */ - {UATF_UNDEFINED, SOUND_MIXER_VOLUME}, - {UATF_CALIBNOISE, SOUND_MIXER_VOLUME}, - {UATF_EQUNOISE, SOUND_MIXER_VOLUME}, - {UATF_DAT, SOUND_MIXER_VOLUME}, - {UATF_DCC, SOUND_MIXER_VOLUME}, - {UATF_MINIDISK, SOUND_MIXER_VOLUME}, - {UATF_ANALOGTAPE, SOUND_MIXER_VOLUME}, - {UATF_PHONOGRAPH, SOUND_MIXER_VOLUME}, - {UATF_VCRAUDIO, SOUND_MIXER_VOLUME}, - {UATF_SATELLITE, SOUND_MIXER_VOLUME}, - {UATF_CABLETUNER, SOUND_MIXER_VOLUME}, - {UATF_DSS, SOUND_MIXER_VOLUME}, - {UATF_MULTITRACK, SOUND_MIXER_VOLUME}, - {0xffff, SOUND_MIXER_VOLUME}, - - /* end */ - {} + {} /* END */ }; static uint16_t -uaudio_mixer_feature_name_sub(uint16_t terminal_type) +uaudio_mixer_get_feature_by_tt(uint16_t terminal_type, uint16_t default_type) { const struct uaudio_tt_to_feature *uat = uaudio_tt_to_feature; uint16_t retval; - while (1) { + if (terminal_type == 0) { + retval = default_type; + } else while (1) { if (uat->terminal_type == 0) { switch (terminal_type >> 8) { case UATI_UNDEFINED >> 8: @@ -4534,8 +4421,11 @@ uaudio_mixer_feature_name_sub(uint16_t terminal_type) case UATO_UNDEFINED >> 8: retval = SOUND_MIXER_PCM; goto done; + case UATT_UNDEFINED >> 8: + retval = SOUND_MIXER_PHONEIN; + goto done; default: - retval = SOUND_MIXER_VOLUME; + retval = default_type; goto done; } } else if (uat->terminal_type == terminal_type) { @@ -4545,65 +4435,138 @@ uaudio_mixer_feature_name_sub(uint16_t terminal_type) uat++; } done: - DPRINTF("terminal_type=0x%04x -> %d\n", - terminal_type, retval); + DPRINTF("terminal_type=0x%04x RET=%d DEF=%d\n", + terminal_type, retval, default_type); return (retval); } static uint16_t -uaudio_mixer_feature_name(const struct uaudio_terminal_node *iot, - struct uaudio_mixer_node *mix) +uaudio_mixer_determine_class(const struct uaudio_terminal_node *iot) { - uint16_t terminal_type = uaudio_mixer_determine_class(iot, mix); + const struct uaudio_terminal_node *ptr; + uint16_t terminal_type_input = 0; + uint16_t terminal_type_output = 0; + uint16_t temp; + uint8_t match = 0; + uint8_t i; - if (mix->class == UAC_RECORD && terminal_type == 0) + for (i = 0; uaudio_mixer_foreach_input(iot, &i); ) { + ptr = iot->root + i; + temp = UGETW(ptr->u.it_v1->wTerminalType); + + if (temp == 0) + continue; + else if (temp == UAT_STREAM) + match |= 1; + else if ((temp & 0xFF00) != (UAT_UNDEFINED & 0xff00)) + terminal_type_input = temp; + } + + for (i = 0; uaudio_mixer_foreach_output(iot, &i); ) { + ptr = iot->root + i; + temp = UGETW(ptr->u.ot_v1->wTerminalType); + + if (temp == 0) + continue; + else if (temp == UAT_STREAM) + match |= 2; + else if ((temp & 0xFF00) != (UAT_UNDEFINED & 0xff00)) + terminal_type_output = temp; + } + + DPRINTF("MATCH=%d IN=0x%04x OUT=0x%04x\n", + match, terminal_type_input, terminal_type_output); + + switch (match) { + case 0: /* not connected to USB */ + if (terminal_type_output != 0) { + return (uaudio_mixer_get_feature_by_tt( + terminal_type_output, SOUND_MIXER_MONITOR)); + } else { + return (uaudio_mixer_get_feature_by_tt( + terminal_type_input, SOUND_MIXER_MONITOR)); + } + case 3: /* connected to both USB input and USB output */ return (SOUND_MIXER_IMIX); - return (uaudio_mixer_feature_name_sub(terminal_type)); + case 2: /* connected to USB output */ + return (uaudio_mixer_get_feature_by_tt( + terminal_type_input, SOUND_MIXER_RECLEV)); + case 1: /* connected to USB input */ + return (uaudio_mixer_get_feature_by_tt( + terminal_type_output, SOUND_MIXER_PCM)); + default: + return (SOUND_MIXER_NRDEVICES); + } } static uint16_t -uaudio20_mixer_feature_name(const struct uaudio_terminal_node *iot, - struct uaudio_mixer_node *mix) +uaudio20_mixer_determine_class(const struct uaudio_terminal_node *iot) { - uint16_t terminal_type = uaudio20_mixer_determine_class(iot, mix); + const struct uaudio_terminal_node *ptr; + uint16_t terminal_type_input = 0; + uint16_t terminal_type_output = 0; + uint16_t temp; + uint8_t match = 0; + uint8_t i; - if (mix->class == UAC_RECORD && terminal_type == 0) - return (SOUND_MIXER_IMIX); - return (uaudio_mixer_feature_name_sub(terminal_type)); -} + for (i = 0; uaudio_mixer_foreach_input(iot, &i); ) { + ptr = iot->root + i; + temp = UGETW(ptr->u.it_v2->wTerminalType); -static const struct uaudio_terminal_node * -uaudio_mixer_get_input(const struct uaudio_terminal_node *iot, uint8_t i) -{ - struct uaudio_terminal_node *root = iot->root; - uint8_t n; + if (temp == 0) + continue; + else if (temp == UAT_STREAM) + match |= 1; + else if ((temp & 0xFF00) != (UAT_UNDEFINED & 0xff00)) + terminal_type_input = temp; + } - n = iot->usr.id_max; - do { - if (iot->usr.bit_input[n / 8] & (1 << (n % 8))) { - if (!i--) - return (root + n); - } - } while (n--); + for (i = 0; uaudio_mixer_foreach_output(iot, &i); ) { + ptr = iot->root + i; + temp = UGETW(ptr->u.ot_v2->wTerminalType); - return (NULL); -} + if (temp == 0) + continue; + else if (temp == UAT_STREAM) + match |= 2; + else if ((temp & 0xFF00) != (UAT_UNDEFINED & 0xff00)) + terminal_type_output = temp; + } -static const struct uaudio_terminal_node * -uaudio_mixer_get_output(const struct uaudio_terminal_node *iot, uint8_t i) -{ - struct uaudio_terminal_node *root = iot->root; - uint8_t n; + DPRINTF("MATCH=%d IN=0x%04x OUT=0x%04x\n", + match, terminal_type_input, terminal_type_output); - n = iot->usr.id_max; - do { - if (iot->usr.bit_output[n / 8] & (1 << (n % 8))) { - if (!i--) - return (root + n); + switch (match) { + case 0: /* not connected to USB */ + if (terminal_type_output != 0) { + return (uaudio_mixer_get_feature_by_tt( + terminal_type_output, SOUND_MIXER_MONITOR)); + } else { + return (uaudio_mixer_get_feature_by_tt( + terminal_type_input, SOUND_MIXER_MONITOR)); } - } while (n--); + case 3: /* connected to both USB input and USB output */ + return (SOUND_MIXER_IMIX); + case 2: /* connected to USB output */ + return (uaudio_mixer_get_feature_by_tt( + terminal_type_input, SOUND_MIXER_RECLEV)); + case 1: /* connected to USB input */ + return (uaudio_mixer_get_feature_by_tt( + terminal_type_output, SOUND_MIXER_PCM)); + default: + return (SOUND_MIXER_NRDEVICES); + } +} - return (NULL); +static void +uaudio_mixer_merge_outputs(struct uaudio_search_result *dst, + const struct uaudio_search_result *src) +{ + const uint8_t max = sizeof(src->bit_output) / sizeof(src->bit_output[0]); + uint8_t x; + + for (x = 0; x != max; x++) + dst->bit_output[x] |= src->bit_output[x]; } static void @@ -4614,9 +4577,7 @@ uaudio_mixer_find_inputs_sub(struct uaudio_terminal_no struct uaudio_terminal_node *iot; uint8_t n; uint8_t i; - uint8_t is_last; -top: for (n = 0; n < n_id; n++) { i = p_id[n]; @@ -4633,72 +4594,48 @@ top: if (iot->u.desc == NULL) continue; - is_last = ((n + 1) == n_id); - switch (iot->u.desc->bDescriptorSubtype) { case UDESCSUB_AC_INPUT: + uaudio_mixer_merge_outputs(&iot->usr, info); info->bit_input[i / 8] |= (1 << (i % 8)); break; case UDESCSUB_AC_FEATURE: - if (is_last) { - p_id = &iot->u.fu_v1->bSourceId; - n_id = 1; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio_mixer_find_inputs_sub( root, &iot->u.fu_v1->bSourceId, 1, info); break; case UDESCSUB_AC_OUTPUT: - if (is_last) { - p_id = &iot->u.ot_v1->bSourceId; - n_id = 1; - goto top; - } + info->bit_output[i / 8] |= (1 << (i % 8)); uaudio_mixer_find_inputs_sub( root, &iot->u.ot_v1->bSourceId, 1, info); + info->bit_output[i / 8] &= ~(1 << (i % 8)); break; case UDESCSUB_AC_MIXER: - if (is_last) { - p_id = iot->u.mu_v1->baSourceId; - n_id = iot->u.mu_v1->bNrInPins; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio_mixer_find_inputs_sub( root, iot->u.mu_v1->baSourceId, iot->u.mu_v1->bNrInPins, info); break; case UDESCSUB_AC_SELECTOR: - if (is_last) { - p_id = iot->u.su_v1->baSourceId; - n_id = iot->u.su_v1->bNrInPins; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio_mixer_find_inputs_sub( root, iot->u.su_v1->baSourceId, iot->u.su_v1->bNrInPins, info); break; case UDESCSUB_AC_PROCESSING: - if (is_last) { - p_id = iot->u.pu_v1->baSourceId; - n_id = iot->u.pu_v1->bNrInPins; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio_mixer_find_inputs_sub( root, iot->u.pu_v1->baSourceId, iot->u.pu_v1->bNrInPins, info); break; case UDESCSUB_AC_EXTENSION: - if (is_last) { - p_id = iot->u.eu_v1->baSourceId; - n_id = iot->u.eu_v1->bNrInPins; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio_mixer_find_inputs_sub( root, iot->u.eu_v1->baSourceId, iot->u.eu_v1->bNrInPins, info); @@ -4718,9 +4655,7 @@ uaudio20_mixer_find_inputs_sub(struct uaudio_terminal_ struct uaudio_terminal_node *iot; uint8_t n; uint8_t i; - uint8_t is_last; -top: for (n = 0; n < n_id; n++) { i = p_id[n]; @@ -4737,94 +4672,62 @@ top: if (iot->u.desc == NULL) continue; - is_last = ((n + 1) == n_id); - switch (iot->u.desc->bDescriptorSubtype) { case UDESCSUB_AC_INPUT: + uaudio_mixer_merge_outputs(&iot->usr, info); info->bit_input[i / 8] |= (1 << (i % 8)); break; case UDESCSUB_AC_OUTPUT: - if (is_last) { - p_id = &iot->u.ot_v2->bSourceId; - n_id = 1; - goto top; - } + info->bit_output[i / 8] |= (1 << (i % 8)); uaudio20_mixer_find_inputs_sub( root, &iot->u.ot_v2->bSourceId, 1, info); + info->bit_output[i / 8] &= ~(1 << (i % 8)); break; case UDESCSUB_AC_MIXER: - if (is_last) { - p_id = iot->u.mu_v2->baSourceId; - n_id = iot->u.mu_v2->bNrInPins; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio20_mixer_find_inputs_sub( root, iot->u.mu_v2->baSourceId, iot->u.mu_v2->bNrInPins, info); break; case UDESCSUB_AC_SELECTOR: - if (is_last) { - p_id = iot->u.su_v2->baSourceId; - n_id = iot->u.su_v2->bNrInPins; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio20_mixer_find_inputs_sub( root, iot->u.su_v2->baSourceId, iot->u.su_v2->bNrInPins, info); break; case UDESCSUB_AC_SAMPLE_RT: - if (is_last) { - p_id = &iot->u.ru_v2->bSourceId; - n_id = 1; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio20_mixer_find_inputs_sub( root, &iot->u.ru_v2->bSourceId, 1, info); break; case UDESCSUB_AC_EFFECT: - if (is_last) { - p_id = &iot->u.ef_v2->bSourceId; - n_id = 1; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio20_mixer_find_inputs_sub( root, &iot->u.ef_v2->bSourceId, 1, info); break; case UDESCSUB_AC_FEATURE: - if (is_last) { - p_id = &iot->u.fu_v2->bSourceId; - n_id = 1; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio20_mixer_find_inputs_sub( root, &iot->u.fu_v2->bSourceId, 1, info); break; case UDESCSUB_AC_PROCESSING_V2: - if (is_last) { - p_id = iot->u.pu_v2->baSourceId; - n_id = iot->u.pu_v2->bNrInPins; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio20_mixer_find_inputs_sub( root, iot->u.pu_v2->baSourceId, iot->u.pu_v2->bNrInPins, info); break; case UDESCSUB_AC_EXTENSION_V2: - if (is_last) { - p_id = iot->u.eu_v2->baSourceId; - n_id = iot->u.eu_v2->bNrInPins; - goto top; - } + uaudio_mixer_merge_outputs(&iot->usr, info); uaudio20_mixer_find_inputs_sub( root, iot->u.eu_v2->baSourceId, iot->u.eu_v2->bNrInPins, info); @@ -4933,31 +4836,6 @@ top: } static void -uaudio_mixer_find_outputs_sub(struct uaudio_terminal_node *root, uint8_t id, - uint8_t n_id, struct uaudio_search_result *info) -{ - struct uaudio_terminal_node *iot = (root + id); - uint8_t j; - - j = n_id; - do { - if ((j != id) && ((root + j)->u.desc) && - ((root + j)->u.desc->bDescriptorSubtype == UDESCSUB_AC_OUTPUT)) { - - /* - * "j" (output) <--- virtual wire <--- "id" (input) - * - * if "j" has "id" on the input, then "id" have "j" on - * the output, because they are connected: - */ - if ((root + j)->usr.bit_input[id / 8] & (1 << (id % 8))) { - iot->usr.bit_output[j / 8] |= (1 << (j % 8)); - } - } - } while (j--); -} - -static void uaudio_mixer_fill_info(struct uaudio_softc *sc, struct usb_device *udev, void *desc) { @@ -5049,16 +4927,6 @@ uaudio_mixer_fill_info(struct uaudio_softc *sc, } } while (i--); - /* - * determine outputs for - * all nodes in the tree: - */ - i = ID_max; - do { - uaudio_mixer_find_outputs_sub(iot, - i, ID_max, &((iot + i)->usr)); - } while (i--); - /* set "id_max" and "root" */ i = ID_max; *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-stable-10@freebsd.org Mon Apr 13 16:30:10 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id B3C532C2F07; Mon, 13 Apr 2020 16:30:10 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491DcL3tG3z3Mjb; Mon, 13 Apr 2020 16:30:10 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 801E81E402; Mon, 13 Apr 2020 16:30:10 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03DGUAVL087568; Mon, 13 Apr 2020 16:30:10 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03DGUAhB087567; Mon, 13 Apr 2020 16:30:10 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004131630.03DGUAhB087567@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 16:30:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359884 - stable/10/sys/dev/sound/pcm X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/sound/pcm X-SVN-Commit-Revision: 359884 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 16:30:10 -0000 Author: hselasky Date: Mon Apr 13 16:30:10 2020 New Revision: 359884 URL: https://svnweb.freebsd.org/changeset/base/359884 Log: MFC r359356: Change default microphone level from 0 to 25. Discussed with: Horse Ma Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/sound/pcm/mixer.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sound/pcm/mixer.c ============================================================================== --- stable/10/sys/dev/sound/pcm/mixer.c Mon Apr 13 16:29:35 2020 (r359883) +++ stable/10/sys/dev/sound/pcm/mixer.c Mon Apr 13 16:30:10 2020 (r359884) @@ -82,7 +82,7 @@ static u_int16_t snd_mixerdefaults[SOUND_MIXER_NRDEVIC [SOUND_MIXER_PCM] = 75, [SOUND_MIXER_SPEAKER] = 75, [SOUND_MIXER_LINE] = 75, - [SOUND_MIXER_MIC] = 0, + [SOUND_MIXER_MIC] = 25, [SOUND_MIXER_CD] = 75, [SOUND_MIXER_IGAIN] = 0, [SOUND_MIXER_LINE1] = 75, From owner-svn-src-stable-10@freebsd.org Mon Apr 13 16:32:19 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2A5AA2C31D6; Mon, 13 Apr 2020 16:32:19 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491Dfq0JTqz3NLm; Mon, 13 Apr 2020 16:32:19 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 05B5A1E5EB; Mon, 13 Apr 2020 16:32:19 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03DGWIjI093216; Mon, 13 Apr 2020 16:32:18 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03DGWIj5093214; Mon, 13 Apr 2020 16:32:18 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004131632.03DGWIj5093214@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 16:32:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359887 - stable/10/sys/dev/sound/pcm X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/sound/pcm X-SVN-Commit-Revision: 359887 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 16:32:19 -0000 Author: hselasky Date: Mon Apr 13 16:32:18 2020 New Revision: 359887 URL: https://svnweb.freebsd.org/changeset/base/359887 Log: MFC r359440: Implement new mixer API to return the device pointer based on the mixer pointer. Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/sound/pcm/mixer.c stable/10/sys/dev/sound/pcm/mixer.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sound/pcm/mixer.c ============================================================================== --- stable/10/sys/dev/sound/pcm/mixer.c Mon Apr 13 16:31:46 2020 (r359886) +++ stable/10/sys/dev/sound/pcm/mixer.c Mon Apr 13 16:32:18 2020 (r359887) @@ -1031,6 +1031,14 @@ mix_get_type(struct snd_mixer *m) return (m->type); } +device_t +mix_get_dev(struct snd_mixer *m) +{ + KASSERT(m != NULL, ("NULL snd_mixer")); + + return (m->dev); +} + /* ----------------------------------------------------------------------- */ static int Modified: stable/10/sys/dev/sound/pcm/mixer.h ============================================================================== --- stable/10/sys/dev/sound/pcm/mixer.h Mon Apr 13 16:31:46 2020 (r359886) +++ stable/10/sys/dev/sound/pcm/mixer.h Mon Apr 13 16:32:18 2020 (r359887) @@ -54,6 +54,7 @@ int mix_get(struct snd_mixer *m, u_int dev); int mix_setrecsrc(struct snd_mixer *m, u_int32_t src); u_int32_t mix_getrecsrc(struct snd_mixer *m); int mix_get_type(struct snd_mixer *m); +device_t mix_get_dev(struct snd_mixer *m); void mix_setdevs(struct snd_mixer *m, u_int32_t v); void mix_setrecdevs(struct snd_mixer *m, u_int32_t v); From owner-svn-src-stable-10@freebsd.org Mon Apr 13 16:34:22 2020 Return-Path: Delivered-To: svn-src-stable-10@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 7C9152C34CB; Mon, 13 Apr 2020 16:34:22 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 491DjB31YTz3NvC; Mon, 13 Apr 2020 16:34:22 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4874D1E607; Mon, 13 Apr 2020 16:34:22 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 03DGYM5L093519; Mon, 13 Apr 2020 16:34:22 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 03DGYLiv093516; Mon, 13 Apr 2020 16:34:21 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <202004131634.03DGYLiv093516@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 13 Apr 2020 16:34:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r359890 - stable/10/sys/dev/sound/usb X-SVN-Group: stable-10 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/10/sys/dev/sound/usb X-SVN-Commit-Revision: 359890 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Apr 2020 16:34:22 -0000 Author: hselasky Date: Mon Apr 13 16:34:21 2020 New Revision: 359890 URL: https://svnweb.freebsd.org/changeset/base/359890 Log: MFC r359446: Add support for multiple playback and recording devices per physical USB audio device. This requires some structural refactoring inside the driver, mostly about converting existing audio channel structures into arrays. The main audio mixer is provided by the first PCM instance. The non-first audio instances may only have a software mixer for PCM playback. Tested by: Horse Ma Sponsored by: Mellanox Technologies Modified: stable/10/sys/dev/sound/usb/uaudio.c stable/10/sys/dev/sound/usb/uaudio.h stable/10/sys/dev/sound/usb/uaudio_pcm.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sound/usb/uaudio.c ============================================================================== --- stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:33:45 2020 (r359889) +++ stable/10/sys/dev/sound/usb/uaudio.c Mon Apr 13 16:34:21 2020 (r359890) @@ -264,6 +264,8 @@ struct uaudio_chan { #define CHAN_OP_START 1 #define CHAN_OP_STOP 2 #define CHAN_OP_DRAIN 3 + + uint8_t iface_index; }; #define UMIDI_EMB_JACK_MAX 16 /* units */ @@ -349,37 +351,45 @@ struct uaudio_hid { #define UAUDIO_SPDIF_OUT_96K 0x04 /* Out sample rate = 96K */ #define UAUDIO_SPDIF_IN_MIX 0x10 /* Input mix enable */ +#define UAUDIO_MAX_CHILD 2 + +struct uaudio_softc_child { + device_t pcm_device; + struct mtx *mixer_lock; + struct snd_mixer *mixer_dev; + + uint32_t mix_info; + uint32_t recsrc_info; + + uint8_t pcm_registered:1; + uint8_t mixer_init:1; +}; + struct uaudio_softc { struct sbuf sc_sndstat; struct sndcard_func sc_sndcard_func; - struct uaudio_chan sc_rec_chan; - struct uaudio_chan sc_play_chan; + struct uaudio_chan sc_rec_chan[UAUDIO_MAX_CHILD]; + struct uaudio_chan sc_play_chan[UAUDIO_MAX_CHILD]; struct umidi_chan sc_midi_chan; struct uaudio_hid sc_hid; struct uaudio_search_result sc_mixer_clocks; struct uaudio_mixer_node sc_mixer_node; struct uaudio_configure_msg sc_config_msg[2]; + struct uaudio_softc_child sc_child[UAUDIO_MAX_CHILD]; - struct mtx *sc_mixer_lock; - struct snd_mixer *sc_mixer_dev; struct usb_device *sc_udev; struct usb_xfer *sc_mixer_xfer[1]; struct uaudio_mixer_node *sc_mixer_root; struct uaudio_mixer_node *sc_mixer_curr; int (*sc_set_spdif_fn) (struct uaudio_softc *, int); - uint32_t sc_mix_info; - uint32_t sc_recsrc_info; - uint16_t sc_audio_rev; uint16_t sc_mixer_count; - uint8_t sc_sndstat_valid; uint8_t sc_mixer_iface_index; uint8_t sc_mixer_iface_no; uint8_t sc_mixer_chan; - uint8_t sc_pcm_registered:1; - uint8_t sc_mixer_init:1; + uint8_t sc_sndstat_valid:1; uint8_t sc_uq_audio_swap_lr:1; uint8_t sc_uq_au_inp_async:1; uint8_t sc_uq_au_no_xu:1; @@ -479,7 +489,7 @@ static usb_proc_callback_t uaudio_configure_msg; static int uaudio_mixer_sysctl_handler(SYSCTL_HANDLER_ARGS); static void uaudio_mixer_ctl_free(struct uaudio_softc *); -static void uaudio_mixer_register_sysctl(struct uaudio_softc *, device_t); +static void uaudio_mixer_register_sysctl(struct uaudio_softc *, device_t, unsigned); static void uaudio_mixer_reload_all(struct uaudio_softc *); static void uaudio_mixer_controls_create_ftu(struct uaudio_softc *); @@ -539,7 +549,7 @@ static void uaudio_mixer_add_ctl(struct uaudio_softc * static void uaudio_mixer_fill_info(struct uaudio_softc *, struct usb_device *, void *); static int uaudio_mixer_signext(uint8_t, int); -static void uaudio_mixer_init(struct uaudio_softc *); +static void uaudio_mixer_init(struct uaudio_softc *, unsigned); static uint8_t umidi_convert_to_usb(struct umidi_sub_chan *, uint8_t, uint8_t); static struct umidi_sub_chan *umidi_sub_by_fifo(struct usb_fifo *); static void umidi_start_read(struct usb_fifo *); @@ -829,6 +839,33 @@ static const STRUCT_USB_HOST_ID __used uaudio_devs[] = USB_IFACE_SUBCLASS(UISUBCLASS_MIDISTREAM),}, }; +static unsigned +uaudio_get_child_index_by_dev(struct uaudio_softc *sc, device_t dev) +{ + unsigned i; + + for (i = 0; i != UAUDIO_MAX_CHILD; i++) { + if (dev == sc->sc_child[i].pcm_device) + return (i); + } + panic("uaudio_get_child_index_dev: Invalid device: %p\n", dev); + return (0); +} + +static unsigned +uaudio_get_child_index_by_chan(struct uaudio_softc *sc, struct uaudio_chan *ch) +{ + unsigned i; + + for (i = 0; i != UAUDIO_MAX_CHILD; i++) { + if ((sc->sc_play_chan + i) == ch || + (sc->sc_rec_chan + i) == ch) + return (i); + } + panic("uaudio_get_child_index_by_chan: Invalid chan: %p\n", ch); + return (0); +} + static int uaudio_probe(device_t dev) { @@ -917,10 +954,8 @@ uaudio_attach(device_t dev) struct uaudio_softc *sc = device_get_softc(dev); struct usb_interface_descriptor *id; usb_error_t err; - device_t child; + unsigned i; - sc->sc_play_chan.priv_sc = sc; - sc->sc_rec_chan.priv_sc = sc; sc->sc_udev = uaa->device; sc->sc_mixer_iface_index = uaa->info.bIfaceIndex; sc->sc_mixer_iface_no = uaa->info.bIfaceNum; @@ -978,57 +1013,63 @@ uaudio_attach(device_t dev) DPRINTF("%d mixer controls\n", sc->sc_mixer_count); - if (sc->sc_play_chan.num_alt > 0) { + for (i = 0; i != UAUDIO_MAX_CHILD; i++) { uint8_t x; + if (sc->sc_play_chan[i].num_alt <= 0) + break; + /* * Need to set a default alternate interface, else * some USB audio devices might go into an infinte * re-enumeration loop: */ err = usbd_set_alt_interface_index(sc->sc_udev, - sc->sc_play_chan.usb_alt[0].iface_index, - sc->sc_play_chan.usb_alt[0].iface_alt_index); + sc->sc_play_chan[i].usb_alt[0].iface_index, + sc->sc_play_chan[i].usb_alt[0].iface_alt_index); if (err) { DPRINTF("setting of alternate index failed: %s!\n", usbd_errstr(err)); } - for (x = 0; x != sc->sc_play_chan.num_alt; x++) { - device_printf(dev, "Play: %d Hz, %d ch, %s format, " - "2x8ms buffer.\n", - sc->sc_play_chan.usb_alt[x].sample_rate, - sc->sc_play_chan.usb_alt[x].channels, - sc->sc_play_chan.usb_alt[x].p_fmt->description); + for (x = 0; x != sc->sc_play_chan[i].num_alt; x++) { + device_printf(dev, "Play[%u]: %d Hz, %d ch, %s format, " + "2x8ms buffer.\n", i, + sc->sc_play_chan[i].usb_alt[x].sample_rate, + sc->sc_play_chan[i].usb_alt[x].channels, + sc->sc_play_chan[i].usb_alt[x].p_fmt->description); } - } else { - device_printf(dev, "No playback.\n"); } + if (i == 0) + device_printf(dev, "No playback.\n"); - if (sc->sc_rec_chan.num_alt > 0) { + for (i = 0; i != UAUDIO_MAX_CHILD; i++) { uint8_t x; + if (sc->sc_rec_chan[i].num_alt <= 0) + break; + /* * Need to set a default alternate interface, else * some USB audio devices might go into an infinte * re-enumeration loop: */ err = usbd_set_alt_interface_index(sc->sc_udev, - sc->sc_rec_chan.usb_alt[0].iface_index, - sc->sc_rec_chan.usb_alt[0].iface_alt_index); + sc->sc_rec_chan[i].usb_alt[0].iface_index, + sc->sc_rec_chan[i].usb_alt[0].iface_alt_index); if (err) { DPRINTF("setting of alternate index failed: %s!\n", usbd_errstr(err)); } - for (x = 0; x != sc->sc_rec_chan.num_alt; x++) { - device_printf(dev, "Record: %d Hz, %d ch, %s format, " - "2x8ms buffer.\n", - sc->sc_rec_chan.usb_alt[x].sample_rate, - sc->sc_rec_chan.usb_alt[x].channels, - sc->sc_rec_chan.usb_alt[x].p_fmt->description); + for (x = 0; x != sc->sc_rec_chan[i].num_alt; x++) { + device_printf(dev, "Record[%u]: %d Hz, %d ch, %s format, " + "2x8ms buffer.\n", i, + sc->sc_rec_chan[i].usb_alt[x].sample_rate, + sc->sc_rec_chan[i].usb_alt[x].channels, + sc->sc_rec_chan[i].usb_alt[x].p_fmt->description); } - } else { - device_printf(dev, "No recording.\n"); } + if (i == 0) + device_printf(dev, "No recording.\n"); if (sc->sc_midi_chan.valid == 0) { if (usbd_lookup_id_by_uaa(uaudio_vendor_midi, @@ -1060,16 +1101,20 @@ uaudio_attach(device_t dev) * Only attach a PCM device if we have a playback, recording * or mixer device present: */ - if (sc->sc_play_chan.num_alt > 0 || - sc->sc_rec_chan.num_alt > 0 || - sc->sc_mix_info) { - child = device_add_child(dev, "pcm", -1); + for (i = 0; i != UAUDIO_MAX_CHILD; i++) { + if (sc->sc_play_chan[i].num_alt <= 0 && + sc->sc_rec_chan[i].num_alt <= 0 && + sc->sc_child[i].mix_info == 0) + continue; + sc->sc_child[i].pcm_device = + device_add_child(dev, "pcm", -1); - if (child == NULL) { + if (sc->sc_child[i].pcm_device == NULL) { DPRINTF("out of memory\n"); goto detach; } - device_set_ivars(child, &sc->sc_sndcard_func); + device_set_ivars(sc->sc_child[i].pcm_device, + &sc->sc_sndcard_func); } if (bus_generic_attach(dev)) { @@ -1108,16 +1153,17 @@ int uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_class) { struct uaudio_softc *sc = device_get_softc(device_get_parent(dev)); + unsigned i = uaudio_get_child_index_by_dev(sc, dev); char status[SND_STATUSLEN]; - uaudio_mixer_init(sc); + uaudio_mixer_init(sc, i); if (sc->sc_uq_audio_swap_lr) { DPRINTF("hardware has swapped left and right\n"); /* uaudio_pcm_setflags(dev, SD_F_PSWAPLR); */ } - if (sc->sc_play_chan.num_alt > 0 && - (sc->sc_mix_info & SOUND_MASK_PCM) == 0) { + if (sc->sc_play_chan[i].num_alt > 0 && + (sc->sc_child[i].mix_info & SOUND_MASK_PCM) == 0) { DPRINTF("emulating master volume\n"); @@ -1133,34 +1179,39 @@ uaudio_attach_sub(device_t dev, kobj_class_t mixer_cla } if (mixer_init(dev, mixer_class, sc)) goto detach; - sc->sc_mixer_init = 1; + sc->sc_child[i].mixer_init = 1; mixer_hwvol_init(dev); snprintf(status, sizeof(status), "at ? %s", PCM_KLDSTRING(snd_uaudio)); if (pcm_register(dev, sc, - (sc->sc_play_chan.num_alt > 0) ? 1 : 0, - (sc->sc_rec_chan.num_alt > 0) ? 1 : 0)) { + (sc->sc_play_chan[i].num_alt > 0) ? 1 : 0, + (sc->sc_rec_chan[i].num_alt > 0) ? 1 : 0)) { goto detach; } uaudio_pcm_setflags(dev, SD_F_MPSAFE); - sc->sc_pcm_registered = 1; + sc->sc_child[i].pcm_registered = 1; - if (sc->sc_play_chan.num_alt > 0) { - pcm_addchan(dev, PCMDIR_PLAY, chan_class, sc); + if (sc->sc_play_chan[i].num_alt > 0) { + sc->sc_play_chan[i].priv_sc = sc; + pcm_addchan(dev, PCMDIR_PLAY, chan_class, + &sc->sc_play_chan[i]); } - if (sc->sc_rec_chan.num_alt > 0) { - pcm_addchan(dev, PCMDIR_REC, chan_class, sc); + + if (sc->sc_rec_chan[i].num_alt > 0) { + sc->sc_rec_chan[i].priv_sc = sc; + pcm_addchan(dev, PCMDIR_REC, chan_class, + &sc->sc_rec_chan[i]); } pcm_setstatus(dev, status); - uaudio_mixer_register_sysctl(sc, dev); + uaudio_mixer_register_sysctl(sc, dev, i); SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, - "feedback_rate", CTLFLAG_RD, &sc->sc_play_chan.feedback_rate, + "feedback_rate", CTLFLAG_RD, &sc->sc_play_chan[i].feedback_rate, 0, "Feedback sample rate in Hz"); return (0); /* success */ @@ -1174,18 +1225,15 @@ int uaudio_detach_sub(device_t dev) { struct uaudio_softc *sc = device_get_softc(device_get_parent(dev)); + unsigned i = uaudio_get_child_index_by_dev(sc, dev); int error = 0; - /* disable S/PDIF output, if any */ - (void) sc->sc_set_spdif_fn(sc, 0); - repeat: - if (sc->sc_pcm_registered) { + if (sc->sc_child[i].pcm_registered) { error = pcm_unregister(dev); } else { - if (sc->sc_mixer_init) { + if (sc->sc_child[i].mixer_init) error = mixer_uninit(dev); - } } if (error) { @@ -1200,6 +1248,7 @@ static int uaudio_detach(device_t dev) { struct uaudio_softc *sc = device_get_softc(dev); + unsigned i; /* * Stop USB transfers early so that any audio applications @@ -1207,14 +1256,18 @@ uaudio_detach(device_t dev) * any. */ usb_proc_explore_lock(sc->sc_udev); - sc->sc_play_chan.operation = CHAN_OP_DRAIN; - sc->sc_rec_chan.operation = CHAN_OP_DRAIN; + for (i = 0; i != UAUDIO_MAX_CHILD; i++) { + sc->sc_play_chan[i].operation = CHAN_OP_DRAIN; + sc->sc_rec_chan[i].operation = CHAN_OP_DRAIN; + } usb_proc_explore_mwait(sc->sc_udev, &sc->sc_config_msg[0], &sc->sc_config_msg[1]); usb_proc_explore_unlock(sc->sc_udev); - usbd_transfer_unsetup(sc->sc_play_chan.xfer, UAUDIO_NCHANBUFS + 1); - usbd_transfer_unsetup(sc->sc_rec_chan.xfer, UAUDIO_NCHANBUFS + 1); + for (i = 0; i != UAUDIO_MAX_CHILD; i++) { + usbd_transfer_unsetup(sc->sc_play_chan[i].xfer, UAUDIO_NCHANBUFS + 1); + usbd_transfer_unsetup(sc->sc_rec_chan[i].xfer, UAUDIO_NCHANBUFS + 1); + } uaudio_hid_detach(sc); @@ -1230,6 +1283,9 @@ uaudio_detach(device_t dev) uaudio_mixer_ctl_free(sc); + /* disable S/PDIF output, if any */ + (void) sc->sc_set_spdif_fn(sc, 0); + return (0); } @@ -1420,10 +1476,13 @@ static void uaudio_configure_msg(struct usb_proc_msg *pm) { struct uaudio_softc *sc = ((struct uaudio_configure_msg *)pm)->sc; + unsigned i; usb_proc_explore_unlock(sc->sc_udev); - uaudio_configure_msg_sub(sc, &sc->sc_play_chan, PCMDIR_PLAY); - uaudio_configure_msg_sub(sc, &sc->sc_rec_chan, PCMDIR_REC); + for (i = 0; i != UAUDIO_MAX_CHILD; i++) { + uaudio_configure_msg_sub(sc, &sc->sc_play_chan[i], PCMDIR_PLAY); + uaudio_configure_msg_sub(sc, &sc->sc_rec_chan[i], PCMDIR_REC); + } usb_proc_explore_lock(sc->sc_udev); } @@ -1589,6 +1648,22 @@ uaudio20_check_rate(struct usb_device *udev, uint8_t i return (USB_ERR_INVAL); } +static struct uaudio_chan * +uaudio_get_chan(struct uaudio_softc *sc, struct uaudio_chan *chan, + uint8_t iface_index) +{ + unsigned i; + + for (i = 0; i != UAUDIO_MAX_CHILD; i++, chan++) { + if (chan->num_alt == 0) { + chan->iface_index = iface_index; + return (chan); + } else if (chan->iface_index == iface_index) + return (chan); + } + return (NULL); +} + static void uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev, uint32_t rate, uint8_t channels, uint8_t bit_resolution) @@ -1896,8 +1971,12 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, str } } - chan = (ep_dir == UE_DIR_IN) ? - &sc->sc_rec_chan : &sc->sc_play_chan; + chan = uaudio_get_chan(sc, (ep_dir == UE_DIR_OUT) ? &sc->sc_play_chan[0] : + &sc->sc_rec_chan[0], curidx); + if (chan == NULL) { + DPRINTF("More than %d sub devices. (skipped)\n", UAUDIO_MAX_CHILD); + goto next_ep; + } if (usbd_get_iface(udev, curidx) == NULL) { DPRINTF("Interface is not valid\n"); @@ -1916,8 +1995,8 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, str uaudio_chan_dump_ep_desc(ed1); #endif DPRINTF("Sample rate = %dHz, channels = %d, " - "bits = %d, format = %s\n", rate, channels, - bit_resolution, p_fmt->description); + "bits = %d, format = %s, ep 0x%02x, chan %p\n", rate, channels, + bit_resolution, p_fmt->description, ed1->bEndpointAddress, chan); chan_alt->sample_rate = rate; chan_alt->p_asf1d = asf1d; @@ -2101,12 +2180,15 @@ uaudio_chan_play_sync_callback(struct usb_xfer *xfer, uint64_t sample_rate; uint8_t buf[4]; uint64_t temp; + unsigned i; int len; int actlen; int nframes; usbd_xfer_status(xfer, &actlen, NULL, NULL, &nframes); + i = uaudio_get_child_index_by_chan(ch->priv_sc, ch); + switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -2157,7 +2239,7 @@ uaudio_chan_play_sync_callback(struct usb_xfer *xfer, * Use feedback value as fallback when there is no * recording channel: */ - if (ch->priv_sc->sc_rec_chan.num_alt == 0) { + if (ch->priv_sc->sc_rec_chan[i].num_alt == 0) { int32_t jitter_max = howmany(sample_rate, 16000); /* @@ -2183,7 +2265,7 @@ uaudio_chan_play_sync_callback(struct usb_xfer *xfer, * source of jitter information to save some * isochronous bandwidth: */ - if (ch->priv_sc->sc_rec_chan.num_alt != 0 && + if (ch->priv_sc->sc_rec_chan[i].num_alt != 0 && uaudio_debug == 0) break; usbd_xfer_set_frames(xfer, 1); @@ -2214,6 +2296,7 @@ uaudio_chan_play_callback(struct usb_xfer *xfer, usb_e uint32_t blockcount; uint32_t n; uint32_t offset; + unsigned i; int sample_size; int actlen; int sumlen; @@ -2223,10 +2306,12 @@ uaudio_chan_play_callback(struct usb_xfer *xfer, usb_e return; } - /* check if there is a record channel */ - if (ch->priv_sc->sc_rec_chan.num_alt > 0) - ch_rec = &ch->priv_sc->sc_rec_chan; - else + i = uaudio_get_child_index_by_chan(ch->priv_sc, ch); + + /* check if there is a valid record channel */ + ch_rec = ch->priv_sc->sc_rec_chan + i; + + if (ch_rec->num_alt == 0) ch_rec = NULL; usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); @@ -2490,11 +2575,9 @@ tr_setup: } void * -uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, +uaudio_chan_init(struct uaudio_chan *ch, struct snd_dbuf *b, struct pcm_channel *c, int dir) { - struct uaudio_chan *ch = ((dir == PCMDIR_PLAY) ? - &sc->sc_play_chan : &sc->sc_rec_chan); uint32_t buf_size; uint8_t x; @@ -2685,36 +2768,36 @@ uaudio_chan_start_sub(struct uaudio_chan *ch) } static int -uaudio_chan_need_both(struct uaudio_softc *sc) +uaudio_chan_need_both(struct uaudio_chan *pchan, struct uaudio_chan *rchan) { - return (sc->sc_play_chan.num_alt > 0 && - sc->sc_play_chan.running != 0 && - uaudio_chan_is_async(&sc->sc_play_chan, - sc->sc_play_chan.set_alt) != 0 && - sc->sc_rec_chan.num_alt > 0 && - sc->sc_rec_chan.running == 0); + return (pchan->num_alt > 0 && + pchan->running != 0 && + uaudio_chan_is_async(pchan, pchan->set_alt) != 0 && + rchan->num_alt > 0 && + rchan->running == 0); } static int -uaudio_chan_need_none(struct uaudio_softc *sc) +uaudio_chan_need_none(struct uaudio_chan *pchan, struct uaudio_chan *rchan) { - return (sc->sc_play_chan.num_alt > 0 && - sc->sc_play_chan.running == 0 && - sc->sc_rec_chan.num_alt > 0 && - sc->sc_rec_chan.running == 0); + return (pchan->num_alt > 0 && + pchan->running == 0 && + rchan->num_alt > 0 && + rchan->running == 0); } void uaudio_chan_start(struct uaudio_chan *ch) { struct uaudio_softc *sc = ch->priv_sc; + unsigned i = uaudio_get_child_index_by_chan(sc, ch); /* make operation atomic */ usb_proc_explore_lock(sc->sc_udev); /* check if not running */ if (ch->running == 0) { - uint32_t temp; + uint32_t temp; /* get current buffer size */ temp = 2 * uaudio_get_buffer_size(ch, ch->set_alt); @@ -2727,13 +2810,15 @@ uaudio_chan_start(struct uaudio_chan *ch) ch->end = ch->buf + temp; ch->cur = ch->buf; - if (uaudio_chan_need_both(sc)) { + if (uaudio_chan_need_both( + &sc->sc_play_chan[i], + &sc->sc_rec_chan[i])) { /* * Start both endpoints because of need for * jitter information: */ - uaudio_chan_start_sub(&sc->sc_rec_chan); - uaudio_chan_start_sub(&sc->sc_play_chan); + uaudio_chan_start_sub(&sc->sc_rec_chan[i]); + uaudio_chan_start_sub(&sc->sc_play_chan[i]); } else { uaudio_chan_start_sub(ch); } @@ -2771,6 +2856,7 @@ void uaudio_chan_stop(struct uaudio_chan *ch) { struct uaudio_softc *sc = ch->priv_sc; + unsigned i = uaudio_get_child_index_by_chan(sc, ch); /* make operation atomic */ usb_proc_explore_lock(sc->sc_udev); @@ -2780,18 +2866,22 @@ uaudio_chan_stop(struct uaudio_chan *ch) /* clear running flag */ ch->running = 0; - if (uaudio_chan_need_both(sc)) { + if (uaudio_chan_need_both( + &sc->sc_play_chan[i], + &sc->sc_rec_chan[i])) { /* * Leave the endpoints running because we need * information about jitter! */ - } else if (uaudio_chan_need_none(sc)) { + } else if (uaudio_chan_need_none( + &sc->sc_play_chan[i], + &sc->sc_rec_chan[i])) { /* * Stop both endpoints in case the one was used for * jitter information: */ - uaudio_chan_stop_sub(&sc->sc_rec_chan); - uaudio_chan_stop_sub(&sc->sc_play_chan); + uaudio_chan_stop_sub(&sc->sc_rec_chan[i]); + uaudio_chan_stop_sub(&sc->sc_play_chan[i]); } else { uaudio_chan_stop_sub(ch); } @@ -2818,12 +2908,12 @@ uaudio_mixer_sysctl_handler(SYSCTL_HANDLER_ARGS) sc = (struct uaudio_softc *)oidp->oid_arg1; hint = oidp->oid_arg2; - if (sc->sc_mixer_lock == NULL) + if (sc->sc_child[0].mixer_lock == NULL) return (ENXIO); /* lookup mixer node */ - mtx_lock(sc->sc_mixer_lock); + mtx_lock(sc->sc_child[0].mixer_lock); for (pmc = sc->sc_mixer_root; pmc != NULL; pmc = pmc->next) { for (chan = 0; chan != (int)pmc->nchan; chan++) { if (pmc->wValue[chan] != -1 && @@ -2834,7 +2924,7 @@ uaudio_mixer_sysctl_handler(SYSCTL_HANDLER_ARGS) } } found: - mtx_unlock(sc->sc_mixer_lock); + mtx_unlock(sc->sc_child[0].mixer_lock); error = sysctl_handle_int(oidp, &temp, 0, req); if (error != 0 || req->newptr == NULL) @@ -2842,7 +2932,7 @@ found: /* update mixer value */ - mtx_lock(sc->sc_mixer_lock); + mtx_lock(sc->sc_child[0].mixer_lock); if (pmc != NULL && temp >= pmc->minval && temp <= pmc->maxval) { @@ -2853,7 +2943,7 @@ found: /* start the transfer, if not already started */ usbd_transfer_start(sc->sc_mixer_xfer[0]); } - mtx_unlock(sc->sc_mixer_lock); + mtx_unlock(sc->sc_child[0].mixer_lock); return (0); } @@ -2870,7 +2960,8 @@ uaudio_mixer_ctl_free(struct uaudio_softc *sc) } static void -uaudio_mixer_register_sysctl(struct uaudio_softc *sc, device_t dev) +uaudio_mixer_register_sysctl(struct uaudio_softc *sc, device_t dev, + unsigned index) { struct uaudio_mixer_node *pmc; struct sysctl_oid *mixer_tree; @@ -2879,6 +2970,9 @@ uaudio_mixer_register_sysctl(struct uaudio_softc *sc, int chan; int n; + if (index != 0) + return; + mixer_tree = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "mixer", CTLFLAG_RD, NULL, ""); @@ -3082,10 +3176,10 @@ uaudio_mixer_reload_all(struct uaudio_softc *sc) struct uaudio_mixer_node *pmc; int chan; - if (sc->sc_mixer_lock == NULL) + if (sc->sc_child[0].mixer_lock == NULL) return; - mtx_lock(sc->sc_mixer_lock); + mtx_lock(sc->sc_child[0].mixer_lock); for (pmc = sc->sc_mixer_root; pmc != NULL; pmc = pmc->next) { /* use reset defaults for non-oss controlled settings */ if (pmc->ctl == SOUND_MIXER_NRDEVICES) @@ -3097,7 +3191,7 @@ uaudio_mixer_reload_all(struct uaudio_softc *sc) /* start HID volume keys, if any */ usbd_transfer_start(sc->sc_hid.xfer[0]); - mtx_unlock(sc->sc_mixer_lock); + mtx_unlock(sc->sc_child[0].mixer_lock); } static void @@ -5291,11 +5385,13 @@ uaudio_mixer_ctl_set(struct uaudio_softc *sc, struct u } static void -uaudio_mixer_init(struct uaudio_softc *sc) +uaudio_mixer_init(struct uaudio_softc *sc, unsigned index) { struct uaudio_mixer_node *mc; int32_t i; + if (index != 0) + return; for (mc = sc->sc_mixer_root; mc; mc = mc->next) { if (mc->ctl != SOUND_MIXER_NRDEVICES) { @@ -5303,7 +5399,7 @@ uaudio_mixer_init(struct uaudio_softc *sc) * Set device mask bits. See * /usr/include/machine/soundcard.h */ - sc->sc_mix_info |= 1U << mc->ctl; + sc->sc_child[index].mix_info |= 1U << mc->ctl; } if ((mc->ctl == SOUND_MIXER_NRDEVICES) && (mc->type == MIX_SELECTOR)) { @@ -5311,7 +5407,7 @@ uaudio_mixer_init(struct uaudio_softc *sc) for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) { if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES) continue; - sc->sc_recsrc_info |= 1U << mc->slctrtype[i - 1]; + sc->sc_child[index].recsrc_info |= 1U << mc->slctrtype[i - 1]; } } } @@ -5320,50 +5416,57 @@ uaudio_mixer_init(struct uaudio_softc *sc) int uaudio_mixer_init_sub(struct uaudio_softc *sc, struct snd_mixer *m) { - DPRINTF("\n"); + unsigned i = uaudio_get_child_index_by_dev(sc, mix_get_dev(m)); - sc->sc_mixer_lock = mixer_get_lock(m); - sc->sc_mixer_dev = m; + DPRINTF("child=%u\n", i); - if (usbd_transfer_setup(sc->sc_udev, &sc->sc_mixer_iface_index, + sc->sc_child[i].mixer_lock = mixer_get_lock(m); + sc->sc_child[i].mixer_dev = m; + + if (i == 0 && + usbd_transfer_setup(sc->sc_udev, &sc->sc_mixer_iface_index, sc->sc_mixer_xfer, uaudio_mixer_config, 1, sc, - sc->sc_mixer_lock)) { - DPRINTFN(0, "could not allocate USB " - "transfer for audio mixer!\n"); + sc->sc_child[i].mixer_lock)) { + DPRINTFN(0, "could not allocate USB transfer for mixer!\n"); return (ENOMEM); } - if (sc->sc_play_chan.num_alt > 0 && - (sc->sc_mix_info & SOUND_MASK_VOLUME) == 0) { + if (sc->sc_play_chan[i].num_alt > 0 && + (sc->sc_child[i].mix_info & SOUND_MASK_VOLUME) == 0) { mix_setparentchild(m, SOUND_MIXER_VOLUME, SOUND_MASK_PCM); mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE); } - mix_setdevs(m, sc->sc_mix_info); - mix_setrecdevs(m, sc->sc_recsrc_info); + mix_setdevs(m, sc->sc_child[i].mix_info); + mix_setrecdevs(m, sc->sc_child[i].recsrc_info); return (0); } int -uaudio_mixer_uninit_sub(struct uaudio_softc *sc) +uaudio_mixer_uninit_sub(struct uaudio_softc *sc, struct snd_mixer *m) { - DPRINTF("\n"); + unsigned index = uaudio_get_child_index_by_dev(sc, mix_get_dev(m)); - usbd_transfer_unsetup(sc->sc_mixer_xfer, 1); + DPRINTF("child=%u\n", index); - sc->sc_mixer_lock = NULL; + if (index == 0) + usbd_transfer_unsetup(sc->sc_mixer_xfer, 1); + sc->sc_child[index].mixer_lock = NULL; + return (0); } void -uaudio_mixer_set(struct uaudio_softc *sc, unsigned type, - unsigned left, unsigned right) +uaudio_mixer_set(struct uaudio_softc *sc, struct snd_mixer *m, + unsigned type, unsigned left, unsigned right) { + unsigned index = uaudio_get_child_index_by_dev(sc, mix_get_dev(m)); struct uaudio_mixer_node *mc; int chan; + if (index != 0) + return; for (mc = sc->sc_mixer_root; mc != NULL; mc = mc->next) { - if (mc->ctl == type) { for (chan = 0; chan < mc->nchan; chan++) { uaudio_mixer_ctl_set(sc, mc, chan, @@ -5374,13 +5477,16 @@ uaudio_mixer_set(struct uaudio_softc *sc, unsigned typ } uint32_t -uaudio_mixer_setrecsrc(struct uaudio_softc *sc, uint32_t src) +uaudio_mixer_setrecsrc(struct uaudio_softc *sc, struct snd_mixer *m, uint32_t src) { + unsigned index = uaudio_get_child_index_by_dev(sc, mix_get_dev(m)); struct uaudio_mixer_node *mc; uint32_t mask; uint32_t temp; int32_t i; + if (index != 0) + return (0); for (mc = sc->sc_mixer_root; mc; mc = mc->next) { if ((mc->ctl == SOUND_MIXER_NRDEVICES) && @@ -6008,7 +6114,7 @@ uaudio_hid_rx_callback(struct usb_xfer *xfer, usb_erro id = 0; } - m = sc->sc_mixer_dev; + m = sc->sc_child[0].mixer_dev; if ((sc->sc_hid.flags & UAUDIO_HID_HAS_MUTE) && (sc->sc_hid.mute_id == id) && @@ -6073,7 +6179,7 @@ uaudio_hid_probe(struct uaudio_softc *sc, if (!(sc->sc_hid.flags & UAUDIO_HID_VALID)) return (-1); - if (sc->sc_mixer_lock == NULL) + if (sc->sc_child[0].mixer_lock == NULL) return (-1); /* Get HID descriptor */ @@ -6134,7 +6240,7 @@ uaudio_hid_probe(struct uaudio_softc *sc, /* allocate USB transfers */ error = usbd_transfer_setup(uaa->device, &sc->sc_hid.iface_index, sc->sc_hid.xfer, uaudio_hid_config, UAUDIO_HID_N_TRANSFER, - sc, sc->sc_mixer_lock); + sc, sc->sc_child[0].mixer_lock); if (error) { DPRINTF("error=%s\n", usbd_errstr(error)); return (-1); Modified: stable/10/sys/dev/sound/usb/uaudio.h ============================================================================== --- stable/10/sys/dev/sound/usb/uaudio.h Mon Apr 13 16:33:45 2020 (r359889) +++ stable/10/sys/dev/sound/usb/uaudio.h Mon Apr 13 16:34:21 2020 (r359890) @@ -39,7 +39,7 @@ struct pcm_channel; extern int uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_class); extern int uaudio_detach_sub(device_t dev); -extern void *uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b, +extern void *uaudio_chan_init(struct uaudio_chan *ch, struct snd_dbuf *b, struct pcm_channel *c, int dir); extern int uaudio_chan_free(struct uaudio_chan *ch); extern int uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, @@ -56,12 +56,12 @@ extern int uaudio_chan_set_param_format(struct uaudio_ uint32_t format); extern void uaudio_chan_start(struct uaudio_chan *ch); extern void uaudio_chan_stop(struct uaudio_chan *ch); -extern int uaudio_mixer_init_sub(struct uaudio_softc *sc, - struct snd_mixer *m); -extern int uaudio_mixer_uninit_sub(struct uaudio_softc *sc); -extern void uaudio_mixer_set(struct uaudio_softc *sc, unsigned type, - unsigned left, unsigned right); -extern uint32_t uaudio_mixer_setrecsrc(struct uaudio_softc *sc, uint32_t src); +extern int uaudio_mixer_init_sub(struct uaudio_softc *, struct snd_mixer *); +extern int uaudio_mixer_uninit_sub(struct uaudio_softc *, struct snd_mixer *); +extern void uaudio_mixer_set(struct uaudio_softc *, struct snd_mixer *, + unsigned type, unsigned left, unsigned right); +extern uint32_t uaudio_mixer_setrecsrc(struct uaudio_softc *, struct snd_mixer *, + uint32_t src); int uaudio_get_vendor(device_t dev); int uaudio_get_product(device_t dev); Modified: stable/10/sys/dev/sound/usb/uaudio_pcm.c ============================================================================== --- stable/10/sys/dev/sound/usb/uaudio_pcm.c Mon Apr 13 16:33:45 2020 (r359889) +++ stable/10/sys/dev/sound/usb/uaudio_pcm.c Mon Apr 13 16:34:21 2020 (r359890) @@ -144,7 +144,7 @@ ua_mixer_set(struct snd_mixer *m, unsigned type, unsig do_unlock = 1; mtx_lock(mtx); } - uaudio_mixer_set(mix_getdevinfo(m), type, left, right); + uaudio_mixer_set(mix_getdevinfo(m), m, type, left, right); if (do_unlock) { mtx_unlock(mtx); } @@ -164,7 +164,7 @@ ua_mixer_setrecsrc(struct snd_mixer *m, uint32_t src) do_unlock = 1; mtx_lock(mtx); } - retval = uaudio_mixer_setrecsrc(mix_getdevinfo(m), src); + retval = uaudio_mixer_setrecsrc(mix_getdevinfo(m), m, src); if (do_unlock) { mtx_unlock(mtx); } @@ -174,7 +174,7 @@ ua_mixer_setrecsrc(struct snd_mixer *m, uint32_t src) static int ua_mixer_uninit(struct snd_mixer *m) { - return (uaudio_mixer_uninit_sub(mix_getdevinfo(m))); + return (uaudio_mixer_uninit_sub(mix_getdevinfo(m), m)); } static kobj_method_t ua_mixer_methods[] = {