Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion include/local.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@
#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
#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
Expand Down Expand Up @@ -226,6 +225,20 @@
#include "seq_midi_event.h"
#include "list.h"

/* 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 */
char components[512];
};


struct _snd_async_handler {
enum {
SND_ASYNC_HANDLER_GENERIC,
Expand Down
21 changes: 20 additions & 1 deletion include/sound/uapi/asound.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions src/control/cards.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@
static int snd_card_load2(const char *control)
{
int open_dev;
snd_ctl_card_info_t info;
struct snd_ctl_card_info kinfo;

open_dev = snd_open_device(control, O_RDONLY);
if (open_dev >= 0) {
if (ioctl(open_dev, SNDRV_CTL_IOCTL_CARD_INFO, &info) < 0) {
if (ioctl(open_dev, SNDRV_CTL_IOCTL_CARD_INFO, &kinfo) < 0) {
int err = -errno;
close(open_dev);
return err;
}
close(open_dev);
return info.card;
return kinfo.card;
} else {
return -errno;
}
Expand Down
34 changes: 33 additions & 1 deletion src/control/control_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,42 @@ 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;
struct snd_ctl_card_bytes bytes;

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);
info->card = kinfo.card;
info->pad = kinfo.pad;
snd_strlcpy((char *)info->id, (char *)kinfo.id, sizeof(info->id));
snd_strlcpy((char *)info->driver, (char *)kinfo.driver, sizeof(info->driver));
snd_strlcpy((char *)info->name, (char *)kinfo.name, sizeof(info->name));
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)) == sizeof(kinfo.components) - 1 &&
kinfo.components[sizeof(kinfo.components) - 2] == '>') {
bytes.type = SND_CTL_CARD_BTYPE_COMPONENTS;
bytes.data = (unsigned char *)info->components;
bytes.data_allocated = sizeof(info->components);
bytes.data_len = 0;
if (ioctl(hw->fd, SNDRV_CTL_IOCTL_CARD_BYTES, &bytes) < 0) {
snd_errornum(CONTROL, "SNDRV_CTL_IOCTL_CARD_BYTES failed");
return -errno;
}
if (bytes.data_len != strnlen((char *)bytes.data, sizeof(info->components)) + 1) {
snd_error(CONTROL, "SNDRV_CTL_IOCTL_CARD_BYTES unexpected length %u, should be %zu",
bytes.data_len, strnlen((char *)bytes.data, sizeof(info->components)) + 1);
return -errno;
}
} else {
snd_strlcpy(info->components, (char *)kinfo.components, sizeof(info->components));
}

return 0;
}

Expand Down