alsa: Ignore PCM devices with udev env ACP_IGNORE

When checking that a card has all of its PCM devices available, ignore
any specific device with the ACP_IGNORE udev environment variable. This
mirrors how we ignore whole cards, but specifically allows non-PipeWire
software to own specific PCM devices.

Note that this does not actually stop PipeWire from using those
subdevices right now, we assume UCM configs take care of that. This
should probably be implemented later to ensure PipeWire always stays
away from them, but for now this fixes the issue where it refuses to
probe the entire card.

Fixes: #3570

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2023-10-14 14:11:15 +09:00
parent 6fefd49a8a
commit fd969dab28

View file

@ -329,6 +329,27 @@ static int get_num_compress_offload_devices(unsigned int card_nr)
return errno != 0 ? -errno : num_dev;
}
static int check_udev_environment(struct udev *udev, const char *devname)
{
char path[PATH_MAX];
struct udev_device *dev;
int ret = 0;
/* Check for ACP_IGNORE on a specific PCM device (not the whole card) */
spa_scnprintf(path, sizeof(path), "/sys/class/sound/%s", devname);
dev = udev_device_new_from_syspath(udev, path);
if (dev == NULL)
return 0;
if (udev_device_get_property_value(dev, "ACP_IGNORE"))
ret = -ENXIO;
udev_device_unref(dev);
return ret;
}
static int check_pcm_device_availability(struct impl *this, struct card *card,
int *num_pcm_devices)
{
@ -376,6 +397,9 @@ static int check_pcm_device_availability(struct impl *this, struct card *card,
card->card_nr, entry->d_name+3);
if (check_device_pcm_class(path) < 0)
continue;
/* Check udev environment */
if (check_udev_environment(this->udev, path) < 0)
continue;
/* Check busy status */
spa_scnprintf(path, sizeof(path), "/proc/asound/card%u/%s",