All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Terry Junge <linuxsound@cosmicgizmosystems.com>
Cc: Rong Zhang <i@rong.moe>, Jaroslav Kysela <perex@perex.cz>,
	Takashi Iwai <tiwai@suse.com>, Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	Cryolitia PukNgae <cryolitia@uniontech.com>,
	Arun Raghavan <arunr@valvesoftware.com>,
	linux-sound@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Icenowy Zheng <uwu@icenowy.me>
Subject: Re: [PATCH 4/9] ALSA: usb-audio: Support string-descriptor-based quirk table entry
Date: Thu, 05 Mar 2026 13:06:17 +0100	[thread overview]
Message-ID: <874imuxyyu.wl-tiwai@suse.de> (raw)
In-Reply-To: <b59da54a-9c80-4212-a337-c5ea98da52d1@cosmicgizmosystems.com>

On Thu, 05 Mar 2026 07:13:32 +0100,
Terry Junge wrote:
> 
> 
> 
> On 3/1/26 1:37 PM, Rong Zhang wrote:
> > Some quirky devices do not have a unique VID/PID. Matching them using
> > DEVICE_FLG() or VENDOR_FLG() may result in conflicts.
> > 
> > Add two new macros DEVICE_STRING_FLG() and VENDOR_STRING_FLG() to match
> > USB string descriptors (manufacturer and/or product) in addition to VID
> > and/or PID, so that we can deconflict these devices safely.
> > 
> > No functional change intended.
> > 
> > Signed-off-by: Rong Zhang <i@rong.moe>
> > ---
> >  sound/usb/quirks.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 82 insertions(+)
> > 
> > diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
> > index c6a78efbcaa30..495dd46ce515c 100644
> > --- a/sound/usb/quirks.c
> > +++ b/sound/usb/quirks.c
> > @@ -2,8 +2,10 @@
> >  /*
> >   */
> >  
> > +#include <linux/build_bug.h>
> >  #include <linux/init.h>
> >  #include <linux/slab.h>
> > +#include <linux/string.h>
> >  #include <linux/usb.h>
> >  #include <linux/usb/audio.h>
> >  #include <linux/usb/midi.h>
> > @@ -2135,16 +2137,39 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
> >  /*
> >   * driver behavior quirk flags
> >   */
> > +struct usb_string_match {
> > +	const char *manufacturer;
> > +	const char *product;
> > +};
> > +
> >  struct usb_audio_quirk_flags_table {
> >  	u32 id;
> >  	u32 flags;
> > +	const struct usb_string_match *usb_string_match;
> >  };
> >  
> >  #define DEVICE_FLG(vid, pid, _flags) \
> >  	{ .id = USB_ID(vid, pid), .flags = (_flags) }
> >  #define VENDOR_FLG(vid, _flags) DEVICE_FLG(vid, 0, _flags)
> >  
> > +/* Use as a last resort if using DEVICE_FLG() is prone to VID/PID conflicts. */
> > +#define DEVICE_STRING_FLG(vid, pid, _manufacturer, _product, _flags)	\
> > +{									\
> > +	.id = USB_ID(vid, pid),						\
> > +	.usb_string_match = &(const struct usb_string_match) {		\
> > +		.manufacturer = _manufacturer,				\
> > +		.product = _product,					\
> > +	},								\
> > +	.flags = (_flags),						\
> > +}
> > +
> > +/* Use as a last resort if using VENDOR_FLG() is prone to VID conflicts. */
> > +#define VENDOR_STRING_FLG(vid, _manufacturer, _flags)			\
> > +	DEVICE_STRING_FLG(vid, 0, _manufacturer, NULL, _flags)
> > +
> >  static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
> > +	/* Device and string descriptor matches */
> > +
> >  	/* Device matches */
> >  	DEVICE_FLG(0x001f, 0x0b21, /* AB13X USB Audio */
> >  		   QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY),
> > @@ -2414,6 +2439,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
> >  	DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
> >  		   QUIRK_FLAG_ALIGN_TRANSFER),
> >  
> > +	/* Vendor and string descriptor matches */
> > +
> >  	/* Vendor matches */
> >  	VENDOR_FLG(0x045e, /* MS Lifecam */
> >  		   QUIRK_FLAG_GET_SAMPLE_RATE),
> > @@ -2558,14 +2585,69 @@ void snd_usb_apply_flag_dbg(const char *reason,
> >  	}
> >  }
> >  
> > +#define USB_STRING_SIZE 128
> > +
> > +static inline int snd_usb_get_strings(struct snd_usb_audio *chip,
> > +				      char *manufacturer, char *product)
> 
> Hi Rong,
> 
> This function is not necessary.
> Both the manufacturer and product strings can be found in struct usb_device.
> 
> If the device has a manufacturer string then chip->dev->manufacturer points to it.
> Otherwise chip->dev->manufacturer is null.
> 
> Likewise, chip->dev->product points to the product string if there is one, else null.
> 
> > +{
> > +	int ret;
> > +
> > +	if (manufacturer) {
> > +		ret = usb_string(chip->dev, chip->dev->descriptor.iManufacturer,
> > +				 manufacturer, USB_STRING_SIZE);
> > +		if (ret < 0) {
> > +			usb_audio_warn(chip, "failed to get manufacturer string: %d\n", ret);
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	if (product) {
> > +		ret = usb_string(chip->dev, chip->dev->descriptor.iProduct,
> > +				 product, USB_STRING_SIZE);
> > +		if (ret < 0) {
> > +			usb_audio_warn(chip, "failed to get product string: %d\n", ret);
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	return 1; /* ok */
> > +}
> > +
> >  void snd_usb_init_quirk_flags_table(struct snd_usb_audio *chip)
> >  {
> >  	const struct usb_audio_quirk_flags_table *p;
> > +	char manufacturer[USB_STRING_SIZE];
> > +	char product[USB_STRING_SIZE];
> > +	int got_usb_strings = 0; /* <0: error, 0: pending, >0: ok */
> >  
> >  	for (p = quirk_flags_table; p->id; p++) {
> >  		if (chip->usb_id == p->id ||
> >  		    (!USB_ID_PRODUCT(p->id) &&
> >  		     USB_ID_VENDOR(chip->usb_id) == USB_ID_VENDOR(p->id))) {
> > +			if (!p->usb_string_match)
> > +				goto apply; /* DEVICE_FLG or VENDOR_FLG */
> > +
> > +			/* DEVICE_STRING_FLG or VENDOR_STRING_FLG */
> > +			if (!got_usb_strings) {
> > +				got_usb_strings = snd_usb_get_strings(chip,
> > +					p->usb_string_match->manufacturer ? manufacturer : NULL,
> > +					p->usb_string_match->product ? product : NULL);
> > +			}
> 
> No need to get the strings as they can be found at chip->dev->manufacturer and chip->dev->product
> if the device declared them.
> 
> > +
> > +			BUILD_BUG_ON(!got_usb_strings);
> > +
> > +			if (got_usb_strings < 0)
> > +				continue;
> > +
> > +			if (p->usb_string_match->manufacturer &&
> > +			    strcmp(p->usb_string_match->manufacturer, manufacturer))
> > +				continue;
> 
> Examples and intent:
> 
> DEVICE_STRING_FLG(vid, pid, "acme", "alpha", flags) // match vid, pid, "acme", and "alpha" strings
> DEVICE_STRING_FLG(vid, pid, "acme", "", flags) // match vid, pid, "acme", and device has no product string
> DEVICE_STRING_FLG(vid, pid, "acme", 0, flags) // match vid, pid, "acme", and any product string
> DEVICE_STRING_FLG(vid, pid, 0, "alpha", flags) // match vid, pid, any manufacturer string, and "alpha"
> DEVICE_STRING_FLG(vid, pid, "", "alpha", flags) // match vid, pid, no manufacturer string, and "alpha"
> DEVICE_STRING_FLG(vid, pid, "", "", flags) // match vid, pid, no manufacturer, and no product strings
> 
> This test would change to something like
> 
> 	if (p->usb_string_match->manufacturer &&
> 	    strcmp(p->usb_string_match->manufacturer, chip->dev->manufacturer ? chip->dev->manufacturer : ""))
> 		continue; 
> 
> > +
> > +			if (p->usb_string_match->product &&
> > +			    strcmp(p->usb_string_match->product, product))
> > +				continue;
> 
> Same here but product instead of manufacturer.

Thanks, that's good to know!

Rong, could you submit the cleanup patch?  I already applied your
series, so write on top of sound.git tree for-next branch.

I'll work on a clean up of the other existing code in USB-audio, too.


Takashi

  reply	other threads:[~2026-03-05 12:06 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-01 21:37 [PATCH 0/9] ALSA: usb-audio: Add quirks for linear volume devices and deconflict VID Rong Zhang
2026-03-01 21:37 ` [PATCH 1/9] Revert "ALSA: usb: Increase volume range that triggers a warning" Rong Zhang
2026-03-01 21:37 ` [PATCH 2/9] ALSA: usb-audio: Add helper function for volume range checks Rong Zhang
2026-03-01 21:37 ` [PATCH 3/9] ALSA: usb-audio: Improve " Rong Zhang
2026-03-01 21:37 ` [PATCH 4/9] ALSA: usb-audio: Support string-descriptor-based quirk table entry Rong Zhang
2026-03-02  9:54   ` Takashi Iwai
2026-03-02 12:31     ` Rong Zhang
2026-03-05  6:13   ` Terry Junge
2026-03-05 12:06     ` Takashi Iwai [this message]
2026-03-05 12:24       ` Rong Zhang
2026-03-01 21:37 ` [PATCH 5/9] ALSA: usb-audio: Deconflict VID between Focusrite Novation & MV-SILICON Rong Zhang
2026-03-01 21:37 ` [PATCH 6/9] ALSA: doc: Add doc for QUIRK_FLAG_SKIP_IFACE_SETUP of snd-usb-audio Rong Zhang
2026-03-01 21:37 ` [PATCH 7/9] ALSA: usb-audio: Add QUIRK_FLAG_MIXER_{PLAYBACK,CAPTURE}_LINEAR_VOL Rong Zhang
2026-03-01 21:37 ` [PATCH 8/9] ALSA: usb-audio: Add linear volume quirk for Hotone Audio Pulze Mini Rong Zhang
2026-03-01 21:37 ` [PATCH 9/9] ALSA: usb-audio: Apply linear volume quirk on MV-SILICON devices Rong Zhang
2026-03-02  9:59 ` [PATCH 0/9] ALSA: usb-audio: Add quirks for linear volume devices and deconflict VID Takashi Iwai
2026-03-02 12:40   ` Rong Zhang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874imuxyyu.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=arunr@valvesoftware.com \
    --cc=corbet@lwn.net \
    --cc=cryolitia@uniontech.com \
    --cc=i@rong.moe \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linuxsound@cosmicgizmosystems.com \
    --cc=perex@perex.cz \
    --cc=skhan@linuxfoundation.org \
    --cc=tiwai@suse.com \
    --cc=uwu@icenowy.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.