@samitouri / QOSamiQemu / commits / 8c24dd8a7e

audio/oss: convert to QOM lifecycle methods

Migrate the OSS audio backend from the legacy driver init/fini callbacks to proper QOM realize method. The oss_audio_init() function is replaced with audio_oss_realize(), which performs the same device accessibility check before delegating to the parent class realize method. The empty oss_audio_fini() is removed. Access to the Audiodev is now through hw->s->dev instead of the drv_opaque pointer. Reviewed-by: Mark Cave-Ayland <mark.caveayland@nutanix.com> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Marc-André Lureau committed Jan 16, 2026 at 11:55 UTC 8c24dd8a7e502f307a72716ac259d992c383b6a0
1 file changed +23 -18
audio/ossaudio.c
+23 -18
@@ -23,6 +23,7 @@
23 */
24
25 #include "qemu/osdep.h"
26 +#include "qapi-types-audio.h"
27 #include <sys/ioctl.h>
28 #include <sys/soundcard.h>
29 #include "qemu/main-loop.h"
@@ -39,19 +40,14 @@
40 #define TYPE_AUDIO_OSS "audio-oss"
41 OBJECT_DECLARE_SIMPLE_TYPE(AudioOss, AUDIO_OSS)
42
43 +static AudioBackendClass *audio_oss_parent_class;
44 +
45 struct AudioOss {
46 AudioMixengBackend parent_obj;
47 };
48
49 static struct audio_driver oss_audio_driver;
50
48 -static void audio_oss_class_init(ObjectClass *klass, const void *data)
49 -{
50 - AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
51 -
52 - k->driver = &oss_audio_driver;
53 -}
54 -
51 #if defined OSS_GETVERSION && defined SNDCTL_DSP_POLICY
52 #define USE_DSP_POLICY
53 #endif
@@ -505,7 +501,7 @@ static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
501 int err;
502 int fd;
503 struct audsettings obt_as;
508 - Audiodev *dev = drv_opaque;
504 + Audiodev *dev = hw->s->dev;
505 AudiodevOssOptions *oopts = &dev->u.oss;
506
507 oss->fd = -1;
@@ -636,7 +632,7 @@ static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
632 int err;
633 int fd;
634 struct audsettings obt_as;
639 - Audiodev *dev = drv_opaque;
635 + Audiodev *dev = hw->s->dev;
636
637 oss->fd = -1;
638
@@ -737,7 +733,8 @@ static void oss_init_per_direction(AudiodevOssPerDirectionOptions *opdo)
733 }
734 }
735
740 -static void *oss_audio_init(Audiodev *dev, Error **errp)
736 +static bool
737 +audio_oss_realize(AudioBackend *abe, Audiodev *dev, Error **errp)
738 {
739 AudiodevOssOptions *oopts;
740 assert(dev->driver == AUDIODEV_DRIVER_OSS);
@@ -748,17 +745,16 @@ static void *oss_audio_init(Audiodev *dev, Error **errp)
745
746 if (access(oopts->in->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
747 error_setg_errno(errp, errno, "%s not accessible", oopts->in->dev ?: "/dev/dsp");
751 - return NULL;
748 + qapi_free_Audiodev(dev);
749 + return false;
750 }
751 if (access(oopts->out->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
752 error_setg_errno(errp, errno, "%s not accessible", oopts->out->dev ?: "/dev/dsp");
755 - return NULL;
753 + qapi_free_Audiodev(dev);
754 + return false;
755 }
757 - return dev;
758 -}
756
760 -static void oss_audio_fini (void *opaque)
761 -{
757 + return audio_oss_parent_class->realize(abe, dev, errp);
758 }
759
760 static struct audio_pcm_ops oss_pcm_ops = {
@@ -780,8 +776,6 @@ static struct audio_pcm_ops oss_pcm_ops = {
776
777 static struct audio_driver oss_audio_driver = {
778 .name = "oss",
783 - .init = oss_audio_init,
784 - .fini = oss_audio_fini,
779 .pcm_ops = &oss_pcm_ops,
780 .max_voices_out = INT_MAX,
781 .max_voices_in = INT_MAX,
@@ -789,6 +783,17 @@ static struct audio_driver oss_audio_driver = {
783 .voice_size_in = sizeof (OSSVoiceIn)
784 };
785
786 +static void audio_oss_class_init(ObjectClass *klass, const void *data)
787 +{
788 + AudioBackendClass *b = AUDIO_BACKEND_CLASS(klass);
789 + AudioMixengBackendClass *k = AUDIO_MIXENG_BACKEND_CLASS(klass);
790 +
791 + audio_oss_parent_class = AUDIO_BACKEND_CLASS(object_class_get_parent(klass));
792 +
793 + b->realize = audio_oss_realize;
794 + k->driver = &oss_audio_driver;
795 +}
796 +
797 static const TypeInfo audio_types[] = {
798 {
799 .name = TYPE_AUDIO_OSS,