ipack.c 3.2 KB

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