mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 03:01:41 +02:00
ALSA: usb-audio: Refine string-descriptor-based quirk matching
Remove snd_usb_get_string() and use the manufacturer and product strings stored in struct usb_device directly to match quirk table entries. Their NULLity can be checked to determine if the device has no these strings. This simplifies the code a lot. Meanwhile, allow quirk table entries to match "no string" explicitly, and add appropriate comments to show the expected usages of DEVICE_STRING_FLG() and VENDOR_STRING_FLG(). These changes are tiny and doesn't form another separate patch, so that back-and-forth changes can be avoided. Suggested-by: Terry Junge <linuxsound@cosmicgizmosystems.com> Link: https://lore.kernel.org/r/b59da54a-9c80-4212-a337-c5ea98da52d1@cosmicgizmosystems.com Signed-off-by: Rong Zhang <i@rong.moe> Link: https://patch.msgid.link/20260305174711.1106324-1-i@rong.moe Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
b364a0d23c
commit
9558a2cbec
|
|
@ -2153,7 +2153,28 @@ struct usb_audio_quirk_flags_table {
|
|||
{ .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. */
|
||||
/*
|
||||
* Use as a last resort if using DEVICE_FLG() is prone to VID/PID conflicts.
|
||||
*
|
||||
* Usage:
|
||||
* // match vid, pid, "manufacturer", and "product"
|
||||
* DEVICE_STRING_FLG(vid, pid, "manufacturer", "product", flags)
|
||||
*
|
||||
* // match vid, pid, "manufacturer", and any product string
|
||||
* DEVICE_STRING_FLG(vid, pid, "manufacturer", NULL, flags)
|
||||
*
|
||||
* // match vid, pid, "manufacturer", and device must have no product string
|
||||
* DEVICE_STRING_FLG(vid, pid, "manufacturer", "", flags)
|
||||
*
|
||||
* // match vid, pid, any manufacturer string, and "product"
|
||||
* DEVICE_STRING_FLG(vid, pid, NULL, "product", flags)
|
||||
*
|
||||
* // match vid, pid, no manufacturer string, and "product"
|
||||
* DEVICE_STRING_FLG(vid, pid, "", "product", flags)
|
||||
*
|
||||
* // match vid, pid, no manufacturer string, and no product string
|
||||
* DEVICE_STRING_FLG(vid, pid, "", "", flags)
|
||||
*/
|
||||
#define DEVICE_STRING_FLG(vid, pid, _manufacturer, _product, _flags) \
|
||||
{ \
|
||||
.id = USB_ID(vid, pid), \
|
||||
|
|
@ -2164,7 +2185,16 @@ struct usb_audio_quirk_flags_table {
|
|||
.flags = (_flags), \
|
||||
}
|
||||
|
||||
/* Use as a last resort if using VENDOR_FLG() is prone to VID conflicts. */
|
||||
/*
|
||||
* Use as a last resort if using VENDOR_FLG() is prone to VID conflicts.
|
||||
*
|
||||
* Usage:
|
||||
* // match vid, and "manufacturer"
|
||||
* VENDOR_STRING_FLG(vid, "manufacturer", flags)
|
||||
*
|
||||
* // match vid, and device must have no manufacturer string
|
||||
* VENDOR_STRING_FLG(vid, "", flags)
|
||||
*/
|
||||
#define VENDOR_STRING_FLG(vid, _manufacturer, _flags) \
|
||||
DEVICE_STRING_FLG(vid, 0, _manufacturer, NULL, _flags)
|
||||
|
||||
|
|
@ -2595,63 +2625,23 @@ void snd_usb_apply_flag_dbg(const char *reason,
|
|||
}
|
||||
}
|
||||
|
||||
#define USB_STRING_SIZE 128
|
||||
|
||||
static char *snd_usb_get_string(struct snd_usb_audio *chip, int id)
|
||||
{
|
||||
char *buf;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Devices without the corresponding string descriptor.
|
||||
* This is non-fatal as *_STRING_FLG have nothing to do in this case.
|
||||
*/
|
||||
if (id == 0)
|
||||
return ERR_PTR(-ENODATA);
|
||||
|
||||
buf = kmalloc(USB_STRING_SIZE, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = usb_string(chip->dev, id, buf, USB_STRING_SIZE);
|
||||
if (ret < 0) {
|
||||
usb_audio_warn(chip, "failed to get string for id%d: %d\n", id, ret);
|
||||
kfree(buf);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void snd_usb_init_quirk_flags_table(struct snd_usb_audio *chip)
|
||||
{
|
||||
const struct usb_audio_quirk_flags_table *p;
|
||||
char *manufacturer __free(kfree) = NULL;
|
||||
char *product __free(kfree) = NULL;
|
||||
|
||||
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))) {
|
||||
/* Handle DEVICE_STRING_FLG/VENDOR_STRING_FLG. */
|
||||
if (p->usb_string_match && p->usb_string_match->manufacturer) {
|
||||
if (!manufacturer) {
|
||||
manufacturer = snd_usb_get_string(chip,
|
||||
chip->dev->descriptor.iManufacturer);
|
||||
}
|
||||
if (IS_ERR_OR_NULL(manufacturer) ||
|
||||
strcmp(p->usb_string_match->manufacturer, manufacturer))
|
||||
continue;
|
||||
}
|
||||
if (p->usb_string_match && p->usb_string_match->product) {
|
||||
if (!product) {
|
||||
product = snd_usb_get_string(chip,
|
||||
chip->dev->descriptor.iProduct);
|
||||
}
|
||||
if (IS_ERR_OR_NULL(product) ||
|
||||
strcmp(p->usb_string_match->product, product))
|
||||
continue;
|
||||
}
|
||||
if (p->usb_string_match && p->usb_string_match->manufacturer &&
|
||||
strcmp(p->usb_string_match->manufacturer,
|
||||
chip->dev->manufacturer ? chip->dev->manufacturer : ""))
|
||||
continue;
|
||||
if (p->usb_string_match && p->usb_string_match->product &&
|
||||
strcmp(p->usb_string_match->product,
|
||||
chip->dev->product ? chip->dev->product : ""))
|
||||
continue;
|
||||
|
||||
snd_usb_apply_flag_dbg("builtin table", chip, p->flags);
|
||||
chip->quirk_flags |= p->flags;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user