soundhw.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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/qdev-properties.h"
  31. #include "hw/isa/isa.h"
  32. #include "hw/pci/pci.h"
  33. #include "hw/audio/soundhw.h"
  34. struct soundhw {
  35. const char *name;
  36. const char *descr;
  37. const char *typename;
  38. int isa;
  39. int (*init_pci) (PCIBus *bus, const char *audiodev);
  40. };
  41. static struct soundhw soundhw[9];
  42. static int soundhw_count;
  43. void pci_register_soundhw(const char *name, const char *descr,
  44. int (*init_pci)(PCIBus *bus, const char *audiodev))
  45. {
  46. assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
  47. soundhw[soundhw_count].name = name;
  48. soundhw[soundhw_count].descr = descr;
  49. soundhw[soundhw_count].isa = 0;
  50. soundhw[soundhw_count].init_pci = init_pci;
  51. soundhw_count++;
  52. }
  53. void deprecated_register_soundhw(const char *name, const char *descr,
  54. int isa, const char *typename)
  55. {
  56. assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
  57. soundhw[soundhw_count].name = name;
  58. soundhw[soundhw_count].descr = descr;
  59. soundhw[soundhw_count].isa = isa;
  60. soundhw[soundhw_count].typename = typename;
  61. soundhw_count++;
  62. }
  63. void show_valid_soundhw(void)
  64. {
  65. struct soundhw *c;
  66. if (soundhw_count) {
  67. printf("Valid sound card names (comma separated):\n");
  68. for (c = soundhw; c->name; ++c) {
  69. printf ("%-11s %s\n", c->name, c->descr);
  70. }
  71. } else {
  72. printf("Machine has no user-selectable audio hardware "
  73. "(it may or may not have always-present audio hardware).\n");
  74. }
  75. }
  76. static struct soundhw *selected = NULL;
  77. static const char *audiodev_id;
  78. void select_soundhw(const char *name, const char *audiodev)
  79. {
  80. struct soundhw *c;
  81. if (selected) {
  82. error_report("only one -soundhw option is allowed");
  83. exit(1);
  84. }
  85. for (c = soundhw; c->name; ++c) {
  86. if (g_str_equal(c->name, name)) {
  87. selected = c;
  88. audiodev_id = audiodev;
  89. break;
  90. }
  91. }
  92. if (!c->name) {
  93. error_report("Unknown sound card name `%s'", name);
  94. show_valid_soundhw();
  95. exit(1);
  96. }
  97. }
  98. void soundhw_init(void)
  99. {
  100. struct soundhw *c = selected;
  101. ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, NULL);
  102. PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
  103. BusState *bus;
  104. if (!c) {
  105. return;
  106. }
  107. if (c->isa) {
  108. if (!isa_bus) {
  109. error_report("ISA bus not available for %s", c->name);
  110. exit(1);
  111. }
  112. bus = BUS(isa_bus);
  113. } else {
  114. if (!pci_bus) {
  115. error_report("PCI bus not available for %s", c->name);
  116. exit(1);
  117. }
  118. bus = BUS(pci_bus);
  119. }
  120. if (c->typename) {
  121. DeviceState *dev = qdev_new(c->typename);
  122. qdev_prop_set_string(dev, "audiodev", audiodev_id);
  123. qdev_realize_and_unref(dev, bus, &error_fatal);
  124. } else {
  125. assert(!c->isa);
  126. c->init_pci(pci_bus, audiodev_id);
  127. }
  128. }