Re: [PATCH v3 2/2] ALSA: control: add ioctl to retrieve full card components

From: Jaroslav Kysela

Date: Mon Mar 09 2026 - 05:47:36 EST


On 3/6/26 11:43, Takashi Iwai wrote:
On Fri, 06 Mar 2026 10:39:46 +0100,
Jaroslav Kysela wrote:

On 3/5/26 11:18, Takashi Iwai wrote:
On Thu, 05 Mar 2026 11:11:40 +0100,
Maciej Strozek wrote:

W dniu czw, 05.03.2026 o godzinie 11∶04 +0100, użytkownik Takashi Iwai
napisał:
On Thu, 05 Mar 2026 10:54:35 +0100,
Maciej Strozek wrote:

W dniu wto, 03.03.2026 o godzinie 16∶47 +0100, użytkownik Takashi
Iwai
napisał:

+ */
+struct snd_ctl_card_components {
+ int card;
+ unsigned int length;
+ unsigned char *components;
+};

And the ioctl can serve for two purposes:

- When length=0 is set, the kernel stores the current number of
bytes
  and returns without copying.  User-space can use this mode for
  allocating the buffer.

In alsa-lib all data must be allocated beforehand, so this
length==0
query is not very useful there, it will just go into a [512] array
anyway. Are there any other users that may benefit from this?

My suggested API can work even with the fixed size 512, too, if 512
is
hight enough.  It's just more flexible.  And there is no restriction
about alsa-lib data allocation; the function can query the size then
allocate, too.


Takashi

OK, will prepare v4 with this, thanks

Well, let's see how others think, too. The API design needs more
considerations because we can't change it any longer once after
defined.

I think that the indirect pointer in ioctl structure is the best at
the moment unless we decide to use the fixed char array.

OK, it might be indeed better if the user-space API is something like:

int snd_ctl_card_components(snd_ctl_t *ctl, unsigned char *buf, size_t len);

Then it's simpler to pass the pointer as is without copying.

But (for
discussion) we may try to be a bit clever and define universal bytes
ioctl which may carry also other things in future like:

enum {
SND_CTL_CARD_BTYPE_COMPONENTS = 1
};

So this is for future extensions?

struct snd_ctl_card_bytes {
unsigned int card; // this is duplication with info ioctl
// to be removed?

Right, it sounds like superfluous. I thought we were to allow
extracting a card info for a different card number, but it doesn't
look so.

unsigned int type; // e.g. SND_CTL_CARD_BTYPE_COMPONENTS
unsigned int data_allocated; // overall size of data
unsigned int data_len; // actual data len
unsigned char *data; // pointer to data array
};

Scenarios:

data_allocated = 0 or data == NULL -> driver just returns data_len
data_allocated < data_len -> driver returns -ENOMEM
data_allocated >= data_len -> driver will copy data

Note that data_len will be zero from the user space for read
operations (driver knows it). But we can eventually use this ioctl to
set some data in future, so data_len/data will be used for the write
operation.

In all cases, data_len is filled with the expected data size in
return, right?

I would return data_len only when data_allocated == 0 or when the user space array can hold complete data. When ioctl returns an error code (e.g. ENOMEM), the structure should not be modified IMHO.

Eventually, we can extend the structure to be even more universal and add 'data_offset' and 'data_overall_len' to support fully partial transfers. In this case, data_len would mean filled/used chunk size and the "overflow" error won't exist.

Jaroslav

--
Jaroslav Kysela <perex@xxxxxxxx>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.