Skip to content

Comments

control: ucm: add ioctl to retrieve full card components#494

Draft
mstrozek wants to merge 1 commit intoalsa-project:masterfrom
mstrozek:components
Draft

control: ucm: add ioctl to retrieve full card components#494
mstrozek wants to merge 1 commit intoalsa-project:masterfrom
mstrozek:components

Conversation

@mstrozek
Copy link

@mstrozek mstrozek commented Jan 22, 2026

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] link to v3

mstrozek added a commit to mstrozek/alsa-utils that referenced this pull request Jan 22, 2026
Changes added to kernel [1] and alsa-lib [2] allow usage of an extended
components string, amend amixer to allow display of the new string.

[1] https://lore.kernel.org/all/20260122111249.67319-1-mstrozek@opensource.cirrus.com/
[2] alsa-project/alsa-lib#494
Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
@mstrozek mstrozek marked this pull request as ready for review January 22, 2026 11:19
@perexg
Copy link
Member

perexg commented Jan 22, 2026

Thanks for your change, but the situation with new components string can be handled using new internal structure in alsa-lib like:

diff --git a/include/local.h b/include/local.h
index a6996759..97701754 100644
--- a/include/local.h
+++ b/include/local.h
@@ -101,7 +101,19 @@
 #define _snd_pcm_sw_params snd_pcm_sw_params
 #define _snd_pcm_status snd_pcm_status
 
-#define _snd_ctl_card_info snd_ctl_card_info
+/* V2 structure - increased components string from 128 bytes to 512 bytes */
+struct _snd_ctl_card_info {
+       int card;                       /* card number */
+       int pad;                        /* reserved for future (was type) */
+       unsigned char id[16];           /* ID of card (user selectable) */
+       unsigned char driver[16];       /* Driver name */
+       unsigned char name[32];         /* Short name of soundcard */
+       unsigned char longname[80];     /* name + info text about soundcard */
+       unsigned char reserved_[16];    /* reserved for future (was ID of mixer) */
+       unsigned char mixername[80];    /* visual mixer identification */
+       unsigned char components[512];  /* card components / fine identification, delimited with one space (AC97 etc..) */
+};
+
 #define _snd_ctl_elem_id snd_ctl_elem_id
 #define _snd_ctl_elem_list snd_ctl_elem_list
 #define _snd_ctl_elem_info snd_ctl_elem_info
diff --git a/src/control/control_hw.c b/src/control/control_hw.c
index 962cd796..30825a80 100644
--- a/src/control/control_hw.c
+++ b/src/control/control_hw.c
@@ -129,10 +129,14 @@ static int snd_ctl_hw_subscribe_events(snd_ctl_t *handle, int subscribe)
 static int snd_ctl_hw_card_info(snd_ctl_t *handle, snd_ctl_card_info_t *info)
 {
        snd_ctl_hw_t *hw = handle->private_data;
-       if (ioctl(hw->fd, SNDRV_CTL_IOCTL_CARD_INFO, info) < 0) {
+       struct snd_ctl_card_info kinfo;
+       if (ioctl(hw->fd, SNDRV_CTL_IOCTL_CARD_INFO, &kinfo) < 0) {
                snd_errornum(CONTROL, "SNDRV_CTL_IOCTL_CARD_INFO failed");
                return -errno;
        }
+       snd_ctl_card_info_clear(info);
+       ... copy data from kinfo to info here..
+       ... if necessary ('>' postfix in the components string) - call SNDRV_CTL_IOCTL_CARD_COMPONENTS ...
        return 0;
 }

Difference for memory allocations should be already covered using snd_ctl_card_info_sizeof(), snd_ctl_card_info_alloca() and snd_ctl_card_info_malloc() functions.

@mstrozek mstrozek marked this pull request as draft January 29, 2026 10:45
@mstrozek mstrozek force-pushed the components branch 2 times, most recently from d90ae37 to e1352ee Compare February 19, 2026 13:51
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] link to v3

Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
snd_strlcpy((char *)info->longname, (char *)kinfo.longname, sizeof(info->longname));
snd_strlcpy((char *)info->reserved_, (char *)kinfo.reserved_, sizeof(info->reserved_));
snd_strlcpy((char *)info->mixername, (char *)kinfo.mixername, sizeof(info->mixername));
if (strnlen((char *)kinfo.components, sizeof(kinfo.components)) > 0 &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string lenght must be exactly "sizeof(kinfo.components) - 1" here.

return -errno;
}
comp.length = sizeof(comp.components);
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_CARD_COMPONENTS, &comp) < 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow the second call. If the ioctl structure defined array with 512 bytes, it cannot be beyond sizeof(comp.components). Perhaps, you may just add assert to assure that "sizeof(info.components) == sizeof(comp.components)" and keep the bogus comp.length check.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does not make much sense if the size is fixed to 512 bytes... or do you think it might be better to make 'components' a dynamic array? and allocate it to the queried length received in the first call?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think that Takashi meant to use pointer to the string array in the structure like we do in e.g. struct snd_xferi. Note: The ioctl for 32-bit code must be added to sound/core/control_compat.c (kernel) for this variant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants