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