2
0

ipack.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * QEMU IndustryPack emulation
  3. *
  4. * Copyright (C) 2012 Igalia, S.L.
  5. * Author: Alberto Garcia <agarcia@igalia.com>
  6. *
  7. * This code is licensed under the GNU GPL v2 or (at your option) any
  8. * later version.
  9. */
  10. #include "ipack.h"
  11. IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
  12. {
  13. BusChild *kid;
  14. QTAILQ_FOREACH(kid, &BUS(bus)->children, sibling) {
  15. DeviceState *qdev = kid->child;
  16. IPackDevice *ip = IPACK_DEVICE(qdev);
  17. if (ip->slot == slot) {
  18. return ip;
  19. }
  20. }
  21. return NULL;
  22. }
  23. void ipack_bus_new_inplace(IPackBus *bus, DeviceState *parent,
  24. const char *name, uint8_t n_slots,
  25. qemu_irq_handler handler)
  26. {
  27. qbus_create_inplace(&bus->qbus, TYPE_IPACK_BUS, parent, name);
  28. bus->n_slots = n_slots;
  29. bus->set_irq = handler;
  30. }
  31. static int ipack_device_dev_init(DeviceState *qdev)
  32. {
  33. IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(qdev));
  34. IPackDevice *dev = IPACK_DEVICE(qdev);
  35. IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);
  36. if (dev->slot < 0) {
  37. dev->slot = bus->free_slot;
  38. }
  39. if (dev->slot >= bus->n_slots) {
  40. return -1;
  41. }
  42. bus->free_slot = dev->slot + 1;
  43. dev->irq = qemu_allocate_irqs(bus->set_irq, dev, 2);
  44. return k->init(dev);
  45. }
  46. static int ipack_device_dev_exit(DeviceState *qdev)
  47. {
  48. IPackDevice *dev = IPACK_DEVICE(qdev);
  49. IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);
  50. if (k->exit) {
  51. k->exit(dev);
  52. }
  53. qemu_free_irqs(dev->irq);
  54. return 0;
  55. }
  56. static Property ipack_device_props[] = {
  57. DEFINE_PROP_INT32("slot", IPackDevice, slot, -1),
  58. DEFINE_PROP_END_OF_LIST()
  59. };
  60. static void ipack_device_class_init(ObjectClass *klass, void *data)
  61. {
  62. DeviceClass *k = DEVICE_CLASS(klass);
  63. k->bus_type = TYPE_IPACK_BUS;
  64. k->init = ipack_device_dev_init;
  65. k->exit = ipack_device_dev_exit;
  66. k->props = ipack_device_props;
  67. }
  68. const VMStateDescription vmstate_ipack_device = {
  69. .name = "ipack_device",
  70. .version_id = 1,
  71. .minimum_version_id = 1,
  72. .minimum_version_id_old = 1,
  73. .fields = (VMStateField[]) {
  74. VMSTATE_INT32(slot, IPackDevice),
  75. VMSTATE_END_OF_LIST()
  76. }
  77. };
  78. static const TypeInfo ipack_device_info = {
  79. .name = TYPE_IPACK_DEVICE,
  80. .parent = TYPE_DEVICE,
  81. .instance_size = sizeof(IPackDevice),
  82. .class_size = sizeof(IPackDeviceClass),
  83. .class_init = ipack_device_class_init,
  84. .abstract = true,
  85. };
  86. static const TypeInfo ipack_bus_info = {
  87. .name = TYPE_IPACK_BUS,
  88. .parent = TYPE_BUS,
  89. .instance_size = sizeof(IPackBus),
  90. };
  91. static void ipack_register_types(void)
  92. {
  93. type_register_static(&ipack_device_info);
  94. type_register_static(&ipack_bus_info);
  95. }
  96. type_init(ipack_register_types)