From fd969dab2878836fd8e9ac7d8fb92d1ede594f37 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 14 Oct 2023 14:11:15 +0900 Subject: [PATCH] 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 --- spa/plugins/alsa/alsa-udev.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/spa/plugins/alsa/alsa-udev.c b/spa/plugins/alsa/alsa-udev.c index 3048d7363..58ff5032d 100644 --- a/spa/plugins/alsa/alsa-udev.c +++ b/spa/plugins/alsa/alsa-udev.c @@ -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",