ipack.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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_init(IPackBus *bus, size_t bus_size,
  30. DeviceState *parent,
  31. uint8_t n_slots,
  32. qemu_irq_handler handler)
  33. {
  34. qbus_init(bus, bus_size, TYPE_IPACK_BUS, parent, NULL);
  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. qemu_init_irqs(idev->irq, ARRAY_SIZE(idev->irq), bus->set_irq, idev);
  52. k->realize(dev, errp);
  53. }
  54. static void ipack_device_unrealize(DeviceState *dev)
  55. {
  56. IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev);
  57. if (k->unrealize) {
  58. k->unrealize(dev);
  59. return;
  60. }
  61. }
  62. static const Property ipack_device_props[] = {
  63. DEFINE_PROP_INT32("slot", IPackDevice, slot, -1),
  64. };
  65. static void ipack_device_class_init(ObjectClass *klass, void *data)
  66. {
  67. DeviceClass *k = DEVICE_CLASS(klass);
  68. set_bit(DEVICE_CATEGORY_INPUT, k->categories);
  69. k->bus_type = TYPE_IPACK_BUS;
  70. k->realize = ipack_device_realize;
  71. k->unrealize = ipack_device_unrealize;
  72. device_class_set_props(k, ipack_device_props);
  73. }
  74. const VMStateDescription vmstate_ipack_device = {
  75. .name = "ipack_device",
  76. .version_id = 1,
  77. .minimum_version_id = 1,
  78. .fields = (const VMStateField[]) {
  79. VMSTATE_INT32(slot, IPackDevice),
  80. VMSTATE_END_OF_LIST()
  81. }
  82. };
  83. static const TypeInfo ipack_device_info = {
  84. .name = TYPE_IPACK_DEVICE,
  85. .parent = TYPE_DEVICE,
  86. .instance_size = sizeof(IPackDevice),
  87. .class_size = sizeof(IPackDeviceClass),
  88. .class_init = ipack_device_class_init,
  89. .abstract = true,
  90. };
  91. static const TypeInfo ipack_bus_info = {
  92. .name = TYPE_IPACK_BUS,
  93. .parent = TYPE_BUS,
  94. .instance_size = sizeof(IPackBus),
  95. };
  96. static void ipack_register_types(void)
  97. {
  98. type_register_static(&ipack_device_info);
  99. type_register_static(&ipack_bus_info);
  100. }
  101. type_init(ipack_register_types)