root / hw / char / ipack.c @ 77cbb28a
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 "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, size_t bus_size,
|
28 |
DeviceState *parent, |
29 |
const char *name, uint8_t n_slots, |
30 |
qemu_irq_handler handler) |
31 |
{ |
32 |
qbus_create_inplace(&bus->qbus, TYPE_IPACK_BUS, parent, name); |
33 |
bus->n_slots = n_slots; |
34 |
bus->set_irq = handler; |
35 |
} |
36 |
|
37 |
static int ipack_device_dev_init(DeviceState *qdev) |
38 |
{ |
39 |
IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(qdev)); |
40 |
IPackDevice *dev = IPACK_DEVICE(qdev); |
41 |
IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev); |
42 |
|
43 |
if (dev->slot < 0) { |
44 |
dev->slot = bus->free_slot; |
45 |
} |
46 |
if (dev->slot >= bus->n_slots) {
|
47 |
return -1; |
48 |
} |
49 |
bus->free_slot = dev->slot + 1;
|
50 |
|
51 |
dev->irq = qemu_allocate_irqs(bus->set_irq, dev, 2);
|
52 |
|
53 |
return k->init(dev);
|
54 |
} |
55 |
|
56 |
static int ipack_device_dev_exit(DeviceState *qdev) |
57 |
{ |
58 |
IPackDevice *dev = IPACK_DEVICE(qdev); |
59 |
IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(dev); |
60 |
|
61 |
if (k->exit) {
|
62 |
k->exit(dev); |
63 |
} |
64 |
|
65 |
qemu_free_irqs(dev->irq); |
66 |
|
67 |
return 0; |
68 |
} |
69 |
|
70 |
static Property ipack_device_props[] = {
|
71 |
DEFINE_PROP_INT32("slot", IPackDevice, slot, -1), |
72 |
DEFINE_PROP_END_OF_LIST() |
73 |
}; |
74 |
|
75 |
static void ipack_device_class_init(ObjectClass *klass, void *data) |
76 |
{ |
77 |
DeviceClass *k = DEVICE_CLASS(klass); |
78 |
set_bit(DEVICE_CATEGORY_INPUT, k->categories); |
79 |
k->bus_type = TYPE_IPACK_BUS; |
80 |
k->init = ipack_device_dev_init; |
81 |
k->exit = ipack_device_dev_exit; |
82 |
k->props = ipack_device_props; |
83 |
} |
84 |
|
85 |
const VMStateDescription vmstate_ipack_device = {
|
86 |
.name = "ipack_device",
|
87 |
.version_id = 1,
|
88 |
.minimum_version_id = 1,
|
89 |
.minimum_version_id_old = 1,
|
90 |
.fields = (VMStateField[]) { |
91 |
VMSTATE_INT32(slot, IPackDevice), |
92 |
VMSTATE_END_OF_LIST() |
93 |
} |
94 |
}; |
95 |
|
96 |
static const TypeInfo ipack_device_info = { |
97 |
.name = TYPE_IPACK_DEVICE, |
98 |
.parent = TYPE_DEVICE, |
99 |
.instance_size = sizeof(IPackDevice),
|
100 |
.class_size = sizeof(IPackDeviceClass),
|
101 |
.class_init = ipack_device_class_init, |
102 |
.abstract = true,
|
103 |
}; |
104 |
|
105 |
static const TypeInfo ipack_bus_info = { |
106 |
.name = TYPE_IPACK_BUS, |
107 |
.parent = TYPE_BUS, |
108 |
.instance_size = sizeof(IPackBus),
|
109 |
}; |
110 |
|
111 |
static void ipack_register_types(void) |
112 |
{ |
113 |
type_register_static(&ipack_device_info); |
114 |
type_register_static(&ipack_bus_info); |
115 |
} |
116 |
|
117 |
type_init(ipack_register_types) |