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