diff options
author | 2015-08-28 09:58:54 +0800 | |
---|---|---|
committer | 2015-09-01 12:44:00 +0800 | |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/hw/ipack/ipack.c | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/hw/ipack/ipack.c')
-rw-r--r-- | qemu/hw/ipack/ipack.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/qemu/hw/ipack/ipack.c b/qemu/hw/ipack/ipack.c new file mode 100644 index 000000000..59bfe2869 --- /dev/null +++ b/qemu/hw/ipack/ipack.c @@ -0,0 +1,119 @@ +/* + * QEMU IndustryPack emulation + * + * Copyright (C) 2012 Igalia, S.L. + * Author: Alberto Garcia <agarcia@igalia.com> + * + * This code is licensed under the GNU GPL v2 or (at your option) any + * later version. + */ + +#include "hw/ipack/ipack.h" + +IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot) +{ + BusChild *kid; + + QTAILQ_FOREACH(kid, &BUS(bus)->children, sibling) { + DeviceState *qdev = kid->child; + IPackDevice *ip = IPACK_DEVICE(qdev); + if (ip->slot == slot) { + return ip; + } + } + return NULL; +} + +void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size, + DeviceState *parent, + const char *name, uint8_t n_slots, + qemu_irq_handler handler) +{ + qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, name); + bus->n_slots = n_slots; + bus->set_irq = handler; +} + +static void ipack_device_realize(DeviceState *dev, Error **errp) +{ + IPackDevice *idev = IPACK_DEVICE(dev); + IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(dev)); + IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev); + + if (idev->slot < 0) { + idev->slot = bus->free_slot; + } + if (idev->slot >= bus->n_slots) { + error_setg(errp, "Only %" PRIu8 " slots available.", bus->n_slots); + return; + } + bus->free_slot = idev->slot + 1; + + idev->irq = qemu_allocate_irqs(bus->set_irq, idev, 2); + + k->realize(dev, errp); +} + +static void ipack_device_unrealize(DeviceState *dev, Error **errp) +{ + IPackDevice *idev = IPACK_DEVICE(dev); + IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev); + Error *err = NULL; + + if (k->unrealize) { + k->unrealize(dev, &err); + error_propagate(errp, err); + return; + } + + qemu_free_irqs(idev->irq, 2); +} + +static Property ipack_device_props[] = { + DEFINE_PROP_INT32("slot", IPackDevice, slot, -1), + DEFINE_PROP_END_OF_LIST() +}; + +static void ipack_device_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *k = DEVICE_CLASS(klass); + + set_bit(DEVICE_CATEGORY_INPUT, k->categories); + k->bus_type = TYPE_IPACK_BUS; + k->realize = ipack_device_realize; + k->unrealize = ipack_device_unrealize; + k->props = ipack_device_props; +} + +const VMStateDescription vmstate_ipack_device = { + .name = "ipack_device", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(slot, IPackDevice), + VMSTATE_END_OF_LIST() + } +}; + +static const TypeInfo ipack_device_info = { + .name = TYPE_IPACK_DEVICE, + .parent = TYPE_DEVICE, + .instance_size = sizeof(IPackDevice), + .class_size = sizeof(IPackDeviceClass), + .class_init = ipack_device_class_init, + .abstract = true, +}; + +static const TypeInfo ipack_bus_info = { + .name = TYPE_IPACK_BUS, + .parent = TYPE_BUS, + .instance_size = sizeof(IPackBus), +}; + +static void ipack_register_types(void) +{ + type_register_static(&ipack_device_info); + type_register_static(&ipack_bus_info); +} + +type_init(ipack_register_types) |