Statistics
| Branch: | Revision:

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)