xref: /qemu/hw/audio/soundhw.c (revision 9c50b8aa)
1 /*
2  * QEMU System Emulator
3  *
4  * Copyright (c) 2003-2008 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "qemu/osdep.h"
25 #include "qemu/option.h"
26 #include "qemu/help_option.h"
27 #include "qemu/error-report.h"
28 #include "qapi/error.h"
29 #include "qom/object.h"
30 #include "hw/isa/isa.h"
31 #include "hw/pci/pci.h"
32 #include "hw/audio/soundhw.h"
33 
34 struct soundhw {
35     const char *name;
36     const char *descr;
37     const char *typename;
38     int isa;
39     int (*init_pci) (PCIBus *bus);
40 };
41 
42 static struct soundhw soundhw[9];
43 static int soundhw_count;
44 
45 void pci_register_soundhw(const char *name, const char *descr,
46                           int (*init_pci)(PCIBus *bus))
47 {
48     assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
49     soundhw[soundhw_count].name = name;
50     soundhw[soundhw_count].descr = descr;
51     soundhw[soundhw_count].isa = 0;
52     soundhw[soundhw_count].init_pci = init_pci;
53     soundhw_count++;
54 }
55 
56 void deprecated_register_soundhw(const char *name, const char *descr,
57                                  int isa, const char *typename)
58 {
59     assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
60     soundhw[soundhw_count].name = name;
61     soundhw[soundhw_count].descr = descr;
62     soundhw[soundhw_count].isa = isa;
63     soundhw[soundhw_count].typename = typename;
64     soundhw_count++;
65 }
66 
67 static struct soundhw *selected = NULL;
68 
69 void select_soundhw(const char *optarg)
70 {
71     struct soundhw *c;
72 
73     if (selected) {
74         error_setg(&error_fatal, "only one -soundhw option is allowed");
75     }
76 
77     if (is_help_option(optarg)) {
78     show_valid_cards:
79 
80         if (soundhw_count) {
81              printf("Valid sound card names (comma separated):\n");
82              for (c = soundhw; c->name; ++c) {
83                  printf ("%-11s %s\n", c->name, c->descr);
84              }
85              printf("\n-soundhw all will enable all of the above\n");
86         } else {
87              printf("Machine has no user-selectable audio hardware "
88                     "(it may or may not have always-present audio hardware).\n");
89         }
90         exit(!is_help_option(optarg));
91     }
92     else {
93         for (c = soundhw; c->name; ++c) {
94             if (g_str_equal(c->name, optarg)) {
95                 selected = c;
96                 break;
97             }
98         }
99 
100         if (!c->name) {
101             error_report("Unknown sound card name `%s'", optarg);
102             goto show_valid_cards;
103         }
104     }
105 }
106 
107 void soundhw_init(void)
108 {
109     struct soundhw *c = selected;
110     ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, NULL);
111     PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
112 
113     if (!c) {
114         return;
115     }
116     if (c->typename) {
117         warn_report("'-soundhw %s' is deprecated, "
118                     "please use '-device %s' instead",
119                     c->name, c->typename);
120         if (c->isa) {
121             isa_create_simple(isa_bus, c->typename);
122         } else {
123             pci_create_simple(pci_bus, -1, c->typename);
124         }
125     } else {
126         assert(!c->isa);
127         if (!pci_bus) {
128             error_report("PCI bus not available for %s", c->name);
129             exit(1);
130         }
131         c->init_pci(pci_bus);
132     }
133 }
134 
135