19c16fa79SAlberto Garcia /* 29c16fa79SAlberto Garcia * QEMU IndustryPack emulation 39c16fa79SAlberto Garcia * 49c16fa79SAlberto Garcia * Copyright (C) 2012 Igalia, S.L. 59c16fa79SAlberto Garcia * Author: Alberto Garcia <agarcia@igalia.com> 69c16fa79SAlberto Garcia * 79c16fa79SAlberto Garcia * This code is licensed under the GNU GPL v2 or (at your option) any 89c16fa79SAlberto Garcia * later version. 99c16fa79SAlberto Garcia */ 109c16fa79SAlberto Garcia 1147b43a1fSPaolo Bonzini #include "ipack.h" 129c16fa79SAlberto Garcia 139c16fa79SAlberto Garcia IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot) 149c16fa79SAlberto Garcia { 159c16fa79SAlberto Garcia BusChild *kid; 169c16fa79SAlberto Garcia 179c16fa79SAlberto Garcia QTAILQ_FOREACH(kid, &BUS(bus)->children, sibling) { 189c16fa79SAlberto Garcia DeviceState *qdev = kid->child; 199c16fa79SAlberto Garcia IPackDevice *ip = IPACK_DEVICE(qdev); 209c16fa79SAlberto Garcia if (ip->slot == slot) { 219c16fa79SAlberto Garcia return ip; 229c16fa79SAlberto Garcia } 239c16fa79SAlberto Garcia } 249c16fa79SAlberto Garcia return NULL; 259c16fa79SAlberto Garcia } 269c16fa79SAlberto Garcia 27*77cbb28aSAndreas Färber void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size, 28*77cbb28aSAndreas Färber DeviceState *parent, 299c16fa79SAlberto Garcia const char *name, uint8_t n_slots, 309c16fa79SAlberto Garcia qemu_irq_handler handler) 319c16fa79SAlberto Garcia { 329c16fa79SAlberto Garcia qbus_create_inplace(&bus->qbus, TYPE_IPACK_BUS, parent, name); 339c16fa79SAlberto Garcia bus->n_slots = n_slots; 349c16fa79SAlberto Garcia bus->set_irq = handler; 359c16fa79SAlberto Garcia } 369c16fa79SAlberto Garcia 379c16fa79SAlberto Garcia static int ipack_device_dev_init(DeviceState *qdev) 389c16fa79SAlberto Garcia { 399c16fa79SAlberto Garcia IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(qdev)); 409c16fa79SAlberto Garcia IPackDevice *dev = IPACK_DEVICE(qdev); 419c16fa79SAlberto Garcia IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev); 429c16fa79SAlberto Garcia 439c16fa79SAlberto Garcia if (dev->slot < 0) { 449c16fa79SAlberto Garcia dev->slot = bus->free_slot; 459c16fa79SAlberto Garcia } 469c16fa79SAlberto Garcia if (dev->slot >= bus->n_slots) { 479c16fa79SAlberto Garcia return -1; 489c16fa79SAlberto Garcia } 499c16fa79SAlberto Garcia bus->free_slot = dev->slot + 1; 509c16fa79SAlberto Garcia 519c16fa79SAlberto Garcia dev->irq = qemu_allocate_irqs(bus->set_irq, dev, 2); 529c16fa79SAlberto Garcia 539c16fa79SAlberto Garcia return k->init(dev); 549c16fa79SAlberto Garcia } 559c16fa79SAlberto Garcia 569c16fa79SAlberto Garcia static int ipack_device_dev_exit(DeviceState *qdev) 579c16fa79SAlberto Garcia { 589c16fa79SAlberto Garcia IPackDevice *dev = IPACK_DEVICE(qdev); 599c16fa79SAlberto Garcia IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev); 609c16fa79SAlberto Garcia 619c16fa79SAlberto Garcia if (k->exit) { 629c16fa79SAlberto Garcia k->exit(dev); 639c16fa79SAlberto Garcia } 649c16fa79SAlberto Garcia 659c16fa79SAlberto Garcia qemu_free_irqs(dev->irq); 669c16fa79SAlberto Garcia 679c16fa79SAlberto Garcia return 0; 689c16fa79SAlberto Garcia } 699c16fa79SAlberto Garcia 709c16fa79SAlberto Garcia static Property ipack_device_props[] = { 719c16fa79SAlberto Garcia DEFINE_PROP_INT32("slot", IPackDevice, slot, -1), 729c16fa79SAlberto Garcia DEFINE_PROP_END_OF_LIST() 739c16fa79SAlberto Garcia }; 749c16fa79SAlberto Garcia 759c16fa79SAlberto Garcia static void ipack_device_class_init(ObjectClass *klass, void *data) 769c16fa79SAlberto Garcia { 779c16fa79SAlberto Garcia DeviceClass *k = DEVICE_CLASS(klass); 78125ee0edSMarcel Apfelbaum set_bit(DEVICE_CATEGORY_INPUT, k->categories); 799c16fa79SAlberto Garcia k->bus_type = TYPE_IPACK_BUS; 809c16fa79SAlberto Garcia k->init = ipack_device_dev_init; 819c16fa79SAlberto Garcia k->exit = ipack_device_dev_exit; 829c16fa79SAlberto Garcia k->props = ipack_device_props; 839c16fa79SAlberto Garcia } 849c16fa79SAlberto Garcia 859c16fa79SAlberto Garcia const VMStateDescription vmstate_ipack_device = { 869c16fa79SAlberto Garcia .name = "ipack_device", 879c16fa79SAlberto Garcia .version_id = 1, 889c16fa79SAlberto Garcia .minimum_version_id = 1, 899c16fa79SAlberto Garcia .minimum_version_id_old = 1, 909c16fa79SAlberto Garcia .fields = (VMStateField[]) { 919c16fa79SAlberto Garcia VMSTATE_INT32(slot, IPackDevice), 929c16fa79SAlberto Garcia VMSTATE_END_OF_LIST() 939c16fa79SAlberto Garcia } 949c16fa79SAlberto Garcia }; 959c16fa79SAlberto Garcia 969c16fa79SAlberto Garcia static const TypeInfo ipack_device_info = { 979c16fa79SAlberto Garcia .name = TYPE_IPACK_DEVICE, 989c16fa79SAlberto Garcia .parent = TYPE_DEVICE, 999c16fa79SAlberto Garcia .instance_size = sizeof(IPackDevice), 1009c16fa79SAlberto Garcia .class_size = sizeof(IPackDeviceClass), 1019c16fa79SAlberto Garcia .class_init = ipack_device_class_init, 1029c16fa79SAlberto Garcia .abstract = true, 1039c16fa79SAlberto Garcia }; 1049c16fa79SAlberto Garcia 1059c16fa79SAlberto Garcia static const TypeInfo ipack_bus_info = { 1069c16fa79SAlberto Garcia .name = TYPE_IPACK_BUS, 1079c16fa79SAlberto Garcia .parent = TYPE_BUS, 1089c16fa79SAlberto Garcia .instance_size = sizeof(IPackBus), 1099c16fa79SAlberto Garcia }; 1109c16fa79SAlberto Garcia 1119c16fa79SAlberto Garcia static void ipack_register_types(void) 1129c16fa79SAlberto Garcia { 1139c16fa79SAlberto Garcia type_register_static(&ipack_device_info); 1149c16fa79SAlberto Garcia type_register_static(&ipack_bus_info); 1159c16fa79SAlberto Garcia } 1169c16fa79SAlberto Garcia 1179c16fa79SAlberto Garcia type_init(ipack_register_types) 118