Statistics
| Branch: | Revision:

root / hw / virtio-bus.c @ 0d09e41a

History | View | Annotate | Download (4.7 kB)

1
/*
2
 * VirtioBus
3
 *
4
 *  Copyright (C) 2012 : GreenSocs Ltd
5
 *      http://www.greensocs.com/ , email: info@greensocs.com
6
 *
7
 *  Developed by :
8
 *  Frederic Konrad   <fred.konrad@greensocs.com>
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License along
21
 * with this program; if not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24

    
25
#include "hw/hw.h"
26
#include "qemu/error-report.h"
27
#include "hw/qdev.h"
28
#include "hw/virtio/virtio-bus.h"
29
#include "hw/virtio/virtio.h"
30

    
31
/* #define DEBUG_VIRTIO_BUS */
32

    
33
#ifdef DEBUG_VIRTIO_BUS
34
#define DPRINTF(fmt, ...) \
35
do { printf("virtio_bus: " fmt , ## __VA_ARGS__); } while (0)
36
#else
37
#define DPRINTF(fmt, ...) do { } while (0)
38
#endif
39

    
40
/* Plug the VirtIODevice */
41
int virtio_bus_plug_device(VirtIODevice *vdev)
42
{
43
    DeviceState *qdev = DEVICE(vdev);
44
    BusState *qbus = BUS(qdev_get_parent_bus(qdev));
45
    VirtioBusState *bus = VIRTIO_BUS(qbus);
46
    VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
47
    DPRINTF("%s: plug device.\n", qbus->name);
48

    
49
    bus->vdev = vdev;
50

    
51
    /*
52
     * The lines below will disappear when we drop VirtIOBindings, at the end
53
     * of the series.
54
     */
55
    bus->bindings.notify = klass->notify;
56
    bus->bindings.save_config = klass->save_config;
57
    bus->bindings.save_queue = klass->save_queue;
58
    bus->bindings.load_config = klass->load_config;
59
    bus->bindings.load_queue = klass->load_queue;
60
    bus->bindings.load_done = klass->load_done;
61
    bus->bindings.get_features = klass->get_features;
62
    bus->bindings.query_guest_notifiers = klass->query_guest_notifiers;
63
    bus->bindings.set_guest_notifiers = klass->set_guest_notifiers;
64
    bus->bindings.set_host_notifier = klass->set_host_notifier;
65
    bus->bindings.vmstate_change = klass->vmstate_change;
66
    virtio_bind_device(bus->vdev, &bus->bindings, qbus->parent);
67

    
68
    if (klass->device_plugged != NULL) {
69
        klass->device_plugged(qbus->parent);
70
    }
71

    
72
    return 0;
73
}
74

    
75
/* Reset the virtio_bus */
76
void virtio_bus_reset(VirtioBusState *bus)
77
{
78
    DPRINTF("%s: reset device.\n", qbus->name);
79
    if (bus->vdev != NULL) {
80
        virtio_reset(bus->vdev);
81
    }
82
}
83

    
84
/* Destroy the VirtIODevice */
85
void virtio_bus_destroy_device(VirtioBusState *bus)
86
{
87
    DeviceState *qdev;
88
    BusState *qbus = BUS(bus);
89
    VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
90
    DPRINTF("%s: remove device.\n", qbus->name);
91

    
92
    if (bus->vdev != NULL) {
93
        if (klass->device_unplug != NULL) {
94
            klass->device_unplug(qbus->parent);
95
        }
96
        qdev = DEVICE(bus->vdev);
97
        qdev_free(qdev);
98
        bus->vdev = NULL;
99
    }
100
}
101

    
102
/* Get the device id of the plugged device. */
103
uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus)
104
{
105
    assert(bus->vdev != NULL);
106
    return bus->vdev->device_id;
107
}
108

    
109
/* Get the config_len field of the plugged device. */
110
size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus)
111
{
112
    assert(bus->vdev != NULL);
113
    return bus->vdev->config_len;
114
}
115

    
116
/* Get the features of the plugged device. */
117
uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
118
                                    uint32_t requested_features)
119
{
120
    VirtioDeviceClass *k;
121
    assert(bus->vdev != NULL);
122
    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
123
    assert(k->get_features != NULL);
124
    return k->get_features(bus->vdev, requested_features);
125
}
126

    
127
/* Get bad features of the plugged device. */
128
uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
129
{
130
    VirtioDeviceClass *k;
131
    assert(bus->vdev != NULL);
132
    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
133
    if (k->bad_features != NULL) {
134
        return k->bad_features(bus->vdev);
135
    } else {
136
        return 0;
137
    }
138
}
139

    
140
/* Get config of the plugged device. */
141
void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config)
142
{
143
    VirtioDeviceClass *k;
144
    assert(bus->vdev != NULL);
145
    k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
146
    if (k->get_config != NULL) {
147
        k->get_config(bus->vdev, config);
148
    }
149
}
150

    
151
static const TypeInfo virtio_bus_info = {
152
    .name = TYPE_VIRTIO_BUS,
153
    .parent = TYPE_BUS,
154
    .instance_size = sizeof(VirtioBusState),
155
    .abstract = true,
156
    .class_size = sizeof(VirtioBusClass),
157
};
158

    
159
static void virtio_register_types(void)
160
{
161
    type_register_static(&virtio_bus_info);
162
}
163

    
164
type_init(virtio_register_types)