control: ucm: add ioctl to retrieve full card components

The fixed-size components field in SNDRV_CTL_IOCTL_CARD_INFO can be too
small on systems with many audio devices. The kernel [1] will provide a
new ioctl to read the full string while truncating the original in
card_info if it grows too big. Make sure alsa-lib can read the full
string if the original is truncated.

[1] https://lore.kernel.org/all/20260430110302.3745917-2-mstrozek@opensource.cirrus.com/

Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
This commit is contained in:
Maciej Strozek 2026-02-19 13:46:20 +00:00
parent 75ed5f05ba
commit ac4f15b5cd
4 changed files with 70 additions and 6 deletions

View file

@ -1044,7 +1044,7 @@ struct snd_timer_tread {
* *
****************************************************************************/
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 9)
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 10)
struct snd_ctl_card_info {
int card; /* card number */
@ -1058,6 +1058,24 @@ struct snd_ctl_card_info {
unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */
};
/*
* Card components can exceed the fixed 128 bytes in snd_ctl_card_info.
* Use SNDRV_CTL_IOCTL_CARD_BYTES with type SND_CTL_CARD_BTYPE_COMPONENTS
* to retrieve the full string.
*/
/* Type values for struct snd_ctl_card_bytes::type */
enum {
SND_CTL_CARD_BTYPE_COMPONENTS = 1, /* full card components string */
};
struct snd_ctl_card_bytes {
unsigned int type; /* SND_CTL_CARD_BTYPE_* */
unsigned int data_allocated; /* size of @data buffer in bytes */
unsigned int data_len; /* in/out: actual data length in bytes */
unsigned char *data; /* user buffer */
};
typedef int __bitwise snd_ctl_elem_type_t;
#define SNDRV_CTL_ELEM_TYPE_NONE ((snd_ctl_elem_type_t) 0) /* invalid */
#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((snd_ctl_elem_type_t) 1) /* boolean type */
@ -1184,6 +1202,7 @@ struct snd_ctl_tlv {
#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info)
#define SNDRV_CTL_IOCTL_CARD_BYTES _IOWR('U', 0x02, struct snd_ctl_card_bytes)
#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list)
#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info)
#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value)