root / hw / char / ipack.c @ 49ab747f
History | View | Annotate | Download (2.8 kB)
1 |
/*
|
---|---|
2 |
* QEMU IndustryPack emulation
|
3 |
*
|
4 |
* Copyright (C) 2012 Igalia, S.L.
|
5 |
* Author: Alberto Garcia <agarcia@igalia.com>
|
6 |
*
|
7 |
* This code is licensed under the GNU GPL v2 or (at your option) any
|
8 |
* later version.
|
9 |
*/
|
10 |
|
11 |
#include "hw/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) |