@@ -1,13 +1,23 @@
#ifndef HW_SOUNDHW_H
#define HW_SOUNDHW_H
-void isa_register_soundhw(const char *name, const char *descr,
- int (*init_isa)(ISABus *bus));
-
-void pci_register_soundhw(const char *name, const char *descr,
- int (*init_pci)(PCIBus *bus));
+#include "qom/object.h"
void soundhw_init(void);
void select_soundhw(const char *optarg);
+#define SOUNDHW_CMDLINE_INTERFACE "soundhw-deprecated"
+
+#define SOUNDHW_CMDLINE_CLASS(class) \
+ OBJECT_CLASS_CHECK(SoundHwCmdlineClass, (class), SOUNDHW_CMDLINE_INTERFACE)
+
+typedef struct SoundHwCmdlineClass {
+ /*< private >*/
+ InterfaceClass parent_class;
+ /*< public >*/
+
+ const char *cmdline_name;
+ bool option_used;
+} SoundHwCmdlineClass;
+
#endif
@@ -1395,12 +1395,6 @@ static void ac97_exit(PCIDevice *dev)
AUD_remove_card(&s->card);
}
-static int ac97_init (PCIBus *bus)
-{
- pci_create_simple(bus, -1, TYPE_AC97);
- return 0;
-}
-
static Property ac97_properties[] = {
DEFINE_AUDIO_PROPERTIES(AC97LinkState, card),
DEFINE_PROP_END_OF_LIST (),
@@ -1410,6 +1404,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS (klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
+ SoundHwCmdlineClass *sk = SOUNDHW_CMDLINE_CLASS(klass);
k->realize = ac97_realize;
k->exit = ac97_exit;
@@ -1422,6 +1417,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ac97;
device_class_set_props(dc, ac97_properties);
dc->reset = ac97_on_reset;
+ sk->cmdline_name = "ac97";
}
static const TypeInfo ac97_info = {
@@ -1431,6 +1427,7 @@ static const TypeInfo ac97_info = {
.class_init = ac97_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { SOUNDHW_CMDLINE_INTERFACE },
{ },
},
};
@@ -1438,7 +1435,6 @@ static const TypeInfo ac97_info = {
static void ac97_register_types (void)
{
type_register_static (&ac97_info);
- pci_register_soundhw("ac97", "Intel 82801AA AC97 Audio", ac97_init);
}
type_init (ac97_register_types)
@@ -308,11 +308,13 @@ static Property adlib_properties[] = {
static void adlib_class_initfn (ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS (klass);
+ SoundHwCmdlineClass *sk = SOUNDHW_CMDLINE_CLASS(klass);
dc->realize = adlib_realizefn;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = ADLIB_DESC;
device_class_set_props(dc, adlib_properties);
+ sk->cmdline_name = "adlib";
}
static const TypeInfo adlib_info = {
@@ -320,18 +322,15 @@ static const TypeInfo adlib_info = {
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof (AdlibState),
.class_init = adlib_class_initfn,
+ .interfaces = (InterfaceInfo[]) {
+ { SOUNDHW_CMDLINE_INTERFACE },
+ { },
+ },
};
-static int Adlib_init (ISABus *bus)
-{
- isa_create_simple (bus, TYPE_ADLIB);
- return 0;
-}
-
static void adlib_register_types (void)
{
type_register_static (&adlib_info);
- isa_register_soundhw("adlib", ADLIB_DESC, Adlib_init);
}
type_init (adlib_register_types)
@@ -683,12 +683,6 @@ static void cs4231a_realizefn (DeviceState *dev, Error **errp)
AUD_register_card ("cs4231a", &s->card);
}
-static int cs4231a_init (ISABus *bus)
-{
- isa_create_simple (bus, TYPE_CS4231A);
- return 0;
-}
-
static Property cs4231a_properties[] = {
DEFINE_AUDIO_PROPERTIES(CSState, card),
DEFINE_PROP_UINT32 ("iobase", CSState, port, 0x534),
@@ -700,6 +694,7 @@ static Property cs4231a_properties[] = {
static void cs4231a_class_initfn (ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS (klass);
+ SoundHwCmdlineClass *sk = SOUNDHW_CMDLINE_CLASS(klass);
dc->realize = cs4231a_realizefn;
dc->reset = cs4231a_reset;
@@ -707,6 +702,7 @@ static void cs4231a_class_initfn (ObjectClass *klass, void *data)
dc->desc = "Crystal Semiconductor CS4231A";
dc->vmsd = &vmstate_cs4231a;
device_class_set_props(dc, cs4231a_properties);
+ sk->cmdline_name = "cs4231a";
}
static const TypeInfo cs4231a_info = {
@@ -715,12 +711,15 @@ static const TypeInfo cs4231a_info = {
.instance_size = sizeof (CSState),
.instance_init = cs4231a_initfn,
.class_init = cs4231a_class_initfn,
+ .interfaces = (InterfaceInfo[]) {
+ { SOUNDHW_CMDLINE_INTERFACE },
+ { },
+ },
};
static void cs4231a_register_types (void)
{
type_register_static (&cs4231a_info);
- isa_register_soundhw("cs4231a", "CS4231A", cs4231a_init);
}
type_init (cs4231a_register_types)
@@ -881,12 +881,6 @@ static void es1370_exit(PCIDevice *dev)
AUD_remove_card(&s->card);
}
-static int es1370_init (PCIBus *bus)
-{
- pci_create_simple (bus, -1, TYPE_ES1370);
- return 0;
-}
-
static Property es1370_properties[] = {
DEFINE_AUDIO_PROPERTIES(ES1370State, card),
DEFINE_PROP_END_OF_LIST(),
@@ -896,6 +890,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS (klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
+ SoundHwCmdlineClass *sk = SOUNDHW_CMDLINE_CLASS(klass);
k->realize = es1370_realize;
k->exit = es1370_exit;
@@ -909,6 +904,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)
dc->vmsd = &vmstate_es1370;
dc->reset = es1370_on_reset;
device_class_set_props(dc, es1370_properties);
+ sk->cmdline_name = "es1370";
}
static const TypeInfo es1370_info = {
@@ -918,6 +914,7 @@ static const TypeInfo es1370_info = {
.class_init = es1370_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { SOUNDHW_CMDLINE_INTERFACE },
{ },
},
};
@@ -925,7 +922,6 @@ static const TypeInfo es1370_info = {
static void es1370_register_types (void)
{
type_register_static (&es1370_info);
- pci_register_soundhw("es1370", "ENSONIQ AudioPCI ES1370", es1370_init);
}
type_init (es1370_register_types)
@@ -292,12 +292,6 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
AUD_set_active_out (s->voice, 1);
}
-static int GUS_init (ISABus *bus)
-{
- isa_create_simple (bus, TYPE_GUS);
- return 0;
-}
-
static Property gus_properties[] = {
DEFINE_AUDIO_PROPERTIES(GUSState, card),
DEFINE_PROP_UINT32 ("freq", GUSState, freq, 44100),
@@ -310,12 +304,14 @@ static Property gus_properties[] = {
static void gus_class_initfn (ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS (klass);
+ SoundHwCmdlineClass *sk = SOUNDHW_CMDLINE_CLASS(klass);
dc->realize = gus_realizefn;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "Gravis Ultrasound GF1";
dc->vmsd = &vmstate_gus;
device_class_set_props(dc, gus_properties);
+ sk->cmdline_name = "gus";
}
static const TypeInfo gus_info = {
@@ -323,12 +319,15 @@ static const TypeInfo gus_info = {
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof (GUSState),
.class_init = gus_class_initfn,
+ .interfaces = (InterfaceInfo[]) {
+ { SOUNDHW_CMDLINE_INTERFACE },
+ { },
+ },
};
static void gus_register_types (void)
{
type_register_static (&gus_info);
- isa_register_soundhw("gus", "Gravis Ultrasound GF1", GUS_init);
}
type_init (gus_register_types)
@@ -1281,11 +1281,15 @@ static const TypeInfo intel_hda_info_ich9 = {
static void hda_codec_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
+ SoundHwCmdlineClass *shc = SOUNDHW_CMDLINE_CLASS(klass);
+
k->realize = hda_codec_dev_realize;
k->unrealize = hda_codec_dev_unrealize;
set_bit(DEVICE_CATEGORY_SOUND, k->categories);
k->bus_type = TYPE_HDA_BUS;
device_class_set_props(k, hda_props);
+ k->desc = "Intel HD Audio";
+ shc->cmdline_name = "hda";
}
static const TypeInfo hda_codec_device_type_info = {
@@ -1295,6 +1299,10 @@ static const TypeInfo hda_codec_device_type_info = {
.abstract = true,
.class_size = sizeof(HDACodecDeviceClass),
.class_init = hda_codec_device_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { SOUNDHW_CMDLINE_INTERFACE },
+ { },
+ },
};
/*
@@ -1321,7 +1329,10 @@ static void intel_hda_register_types(void)
type_register_static(&intel_hda_info_ich6);
type_register_static(&intel_hda_info_ich9);
type_register_static(&hda_codec_device_type_info);
- pci_register_soundhw("hda", "Intel HD Audio", intel_hda_and_codec_init);
+
+ if (0) {
+ intel_hda_and_codec_init(NULL); /* XXX */
+ }
}
type_init(intel_hda_register_types)
@@ -112,7 +112,7 @@ static void pcspk_callback(void *opaque, int free)
}
}
-static int pcspk_audio_init(ISABus *bus)
+static int pcspk_audio_init(BusState *bus)
{
PCSpkState *s = pcspk_state;
struct audsettings as = {PCSPK_SAMPLE_RATE, 1, AUDIO_FORMAT_U8, 0};
@@ -218,14 +218,21 @@ static Property pcspk_properties[] = {
static void pcspk_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ SoundHwCmdlineClass *sk = SOUNDHW_CMDLINE_CLASS(klass);
dc->realize = pcspk_realizefn;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
+ dc->desc = "PC speaker";
dc->vmsd = &vmstate_spk;
device_class_set_props(dc, pcspk_properties);
/* Reason: realize sets global pcspk_state */
/* Reason: pit object link */
dc->user_creatable = false;
+ sk->cmdline_name = "pcspk";
+
+ if (0) {
+ pcspk_audio_init(NULL); /* XXX */
+ }
}
static const TypeInfo pcspk_info = {
@@ -234,11 +241,14 @@ static const TypeInfo pcspk_info = {
.instance_size = sizeof(PCSpkState),
.instance_init = pcspk_initfn,
.class_init = pcspk_class_initfn,
+ .interfaces = (InterfaceInfo[]) {
+ { SOUNDHW_CMDLINE_INTERFACE },
+ { },
+ },
};
static void pcspk_register(void)
{
type_register_static(&pcspk_info);
- isa_register_soundhw("pcspk", "PC speaker", pcspk_audio_init);
}
type_init(pcspk_register)
@@ -1415,12 +1415,6 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
AUD_register_card ("sb16", &s->card);
}
-static int SB16_init (ISABus *bus)
-{
- isa_create_simple (bus, TYPE_SB16);
- return 0;
-}
-
static Property sb16_properties[] = {
DEFINE_AUDIO_PROPERTIES(SB16State, card),
DEFINE_PROP_UINT32 ("version", SB16State, ver, 0x0405), /* 4.5 */
@@ -1434,12 +1428,14 @@ static Property sb16_properties[] = {
static void sb16_class_initfn (ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS (klass);
+ SoundHwCmdlineClass *sk = SOUNDHW_CMDLINE_CLASS(klass);
dc->realize = sb16_realizefn;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "Creative Sound Blaster 16";
dc->vmsd = &vmstate_sb16;
device_class_set_props(dc, sb16_properties);
+ sk->cmdline_name = "sb16";
}
static const TypeInfo sb16_info = {
@@ -1448,12 +1444,15 @@ static const TypeInfo sb16_info = {
.instance_size = sizeof (SB16State),
.instance_init = sb16_initfn,
.class_init = sb16_class_initfn,
+ .interfaces = (InterfaceInfo[]) {
+ { SOUNDHW_CMDLINE_INTERFACE },
+ { },
+ },
};
static void sb16_register_types (void)
{
type_register_static (&sb16_info);
- isa_register_soundhw("sb16", "Creative Sound Blaster 16", SB16_init);
}
type_init (sb16_register_types)
@@ -31,125 +31,140 @@
struct soundhw {
const char *name;
- const char *descr;
- int enabled;
- int isa;
- union {
- int (*init_isa) (ISABus *bus);
- int (*init_pci) (PCIBus *bus);
- } init;
+ bool is_found;
};
-static struct soundhw soundhw[9];
-static int soundhw_count;
-
-void isa_register_soundhw(const char *name, const char *descr,
- int (*init_isa)(ISABus *bus))
+static gint soundhw_list_compare(gconstpointer a, gconstpointer b)
{
- assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
- soundhw[soundhw_count].name = name;
- soundhw[soundhw_count].descr = descr;
- soundhw[soundhw_count].isa = 1;
- soundhw[soundhw_count].init.init_isa = init_isa;
- soundhw_count++;
+ SoundHwCmdlineClass *sc_a = SOUNDHW_CMDLINE_CLASS(a);
+ SoundHwCmdlineClass *sc_b = SOUNDHW_CMDLINE_CLASS(b);
+
+ return strcmp(sc_a->cmdline_name, sc_b->cmdline_name);
}
-void pci_register_soundhw(const char *name, const char *descr,
- int (*init_pci)(PCIBus *bus))
+static void soundhw_list_entry(gpointer data, gpointer user_data)
{
- assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
- soundhw[soundhw_count].name = name;
- soundhw[soundhw_count].descr = descr;
- soundhw[soundhw_count].isa = 0;
- soundhw[soundhw_count].init.init_pci = init_pci;
- soundhw_count++;
+ SoundHwCmdlineClass *sc = SOUNDHW_CMDLINE_CLASS(data);
+ DeviceClass *dc = DEVICE_CLASS(data);
+
+ printf("%-11s %s\n", sc->cmdline_name, dc->desc);
+}
+
+static void soundhw_check_enable_entry(gpointer data, gpointer user_data)
+{
+ SoundHwCmdlineClass *sc = SOUNDHW_CMDLINE_CLASS(data);
+ struct soundhw *d = user_data;
+
+ if (g_str_equal(d->name, "all") || g_str_equal(d->name, sc->cmdline_name)) {
+ sc->option_used = d->is_found = true;
+ }
+}
+
+static void soundhw_list(GSList *list)
+{
+ if (!list) {
+ printf("Machine has no user-selectable audio hardware "
+ "(it may or may not have always-present audio hardware).\n");
+ return;
+ }
+ list = g_slist_sort(list, soundhw_list_compare);
+ printf("Valid sound card names (comma separated):\n");
+ g_slist_foreach(list, soundhw_list_entry, NULL);
+ printf("\n-soundhw all will enable all of the above\n");
}
void select_soundhw(const char *optarg)
{
- struct soundhw *c;
+ struct soundhw data;
+ GSList *list;
+
+ list = object_class_get_list(SOUNDHW_CMDLINE_INTERFACE, false);
if (is_help_option(optarg)) {
- show_valid_cards:
-
- if (soundhw_count) {
- printf("Valid sound card names (comma separated):\n");
- for (c = soundhw; c->name; ++c) {
- printf ("%-11s %s\n", c->name, c->descr);
- }
- printf("\n-soundhw all will enable all of the above\n");
- } else {
- printf("Machine has no user-selectable audio hardware "
- "(it may or may not have always-present audio hardware).\n");
- }
- exit(!is_help_option(optarg));
+ soundhw_list(list);
+ exit(0);
}
- else {
- size_t l;
- const char *p;
- char *e;
- int bad_card = 0;
- if (!strcmp(optarg, "all")) {
- for (c = soundhw; c->name; ++c) {
- c->enabled = 1;
+ if (strchr(optarg, ',')) {
+ char **parts = g_strsplit(optarg, ",", 0);
+ char **tmp;
+
+ for (tmp = parts; tmp && *tmp; tmp++) {
+ data = (struct soundhw){ .name = *tmp };
+ g_slist_foreach(list, soundhw_check_enable_entry, &data);
+ if (!data.is_found) {
+ goto invalid_name;
}
- return;
}
-
- p = optarg;
- while (*p) {
- e = strchr(p, ',');
- l = !e ? strlen(p) : (size_t) (e - p);
-
- for (c = soundhw; c->name; ++c) {
- if (!strncmp(c->name, p, l) && !c->name[l]) {
- c->enabled = 1;
- break;
- }
- }
-
- if (!c->name) {
- if (l > 80) {
- error_report("Unknown sound card name (too big to show)");
- }
- else {
- error_report("Unknown sound card name `%.*s'",
- (int) l, p);
- }
- bad_card = 1;
- }
- p += l + (e != NULL);
+ g_strfreev(parts);
+ } else {
+ data = (struct soundhw){ .name = optarg };
+ g_slist_foreach(list, soundhw_check_enable_entry, &data);
+ if (!data.is_found) {
+ goto invalid_name;
}
+ }
+ g_slist_free(list);
+ return;
- if (bad_card) {
- goto show_valid_cards;
+invalid_name:
+ error_report("Unknown sound card name `%s'", data.name);
+ soundhw_list(list);
+ exit(1);
+}
+
+static void soundhw_create_entry(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ SoundHwCmdlineClass *sc = SOUNDHW_CMDLINE_CLASS(oc);
+ const char *typename = object_class_get_name(oc);
+ BusState *bus;
+
+ if (!sc->option_used) {
+ return;
+ }
+
+ warn_report("'-soundhw %s' is deprecated, please use '-device %s' instead",
+ sc->cmdline_name, typename);
+
+ if (object_class_dynamic_cast(oc, TYPE_ISA_DEVICE)) {
+ bus = (BusState *)object_resolve_path_type("", TYPE_ISA_BUS, NULL);
+ if (!bus) {
+ error_report("ISA bus not available for %s", sc->cmdline_name);
+ exit(1);
}
+ isa_create_simple(ISA_BUS(bus), typename);
+ }
+ if (object_class_dynamic_cast(oc, TYPE_PCI_DEVICE)) {
+ bus = (BusState *)object_resolve_path_type("", TYPE_PCI_BUS, NULL);
+ if (!bus) {
+ error_report("PCI bus not available for %s", sc->cmdline_name);
+ exit(1);
+ }
+ pci_create_simple(PCI_BUS(bus), -1, typename);
}
}
void soundhw_init(void)
{
- struct soundhw *c;
- ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, NULL);
- PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
+ GSList *list;
- for (c = soundhw; c->name; ++c) {
- if (c->enabled) {
- if (c->isa) {
- if (!isa_bus) {
- error_report("ISA bus not available for %s", c->name);
- exit(1);
- }
- c->init.init_isa(isa_bus);
- } else {
- if (!pci_bus) {
- error_report("PCI bus not available for %s", c->name);
- exit(1);
- }
- c->init.init_pci(pci_bus);
- }
- }
+ list = object_class_get_list(SOUNDHW_CMDLINE_INTERFACE, false);
+ if (list) {
+ g_slist_foreach(list, soundhw_create_entry, NULL);
+ g_slist_free(list);
}
}
+static const TypeInfo soundhw_interface_info = {
+ .name = SOUNDHW_CMDLINE_INTERFACE,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(SoundHwCmdlineClass),
+};
+
+static void soundhw_register_types(void)
+{
+ type_register_static(&soundhw_interface_info);
+}
+
+type_init(soundhw_register_types)