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

Jaroslav Kysela
2026-03-09T09:45:22Z

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@perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.