qemu

Форк
0
/
css-bridge.c 
166 строк · 4.8 Кб
1
/*
2
 * css bridge implementation
3
 *
4
 * Copyright 2012,2016 IBM Corp.
5
 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6
 *            Pierre Morel <pmorel@linux.vnet.ibm.com>
7
 *
8
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
9
 * your option) any later version. See the COPYING file in the top-level
10
 * directory.
11
 */
12

13
#include "qemu/osdep.h"
14
#include "qapi/error.h"
15
#include "hw/hotplug.h"
16
#include "hw/qdev-properties.h"
17
#include "hw/sysbus.h"
18
#include "qemu/bitops.h"
19
#include "qemu/module.h"
20
#include "hw/s390x/css.h"
21
#include "ccw-device.h"
22
#include "hw/s390x/css-bridge.h"
23

24
/*
25
 * Invoke device-specific unplug handler, disable the subchannel
26
 * (including sending a channel report to the guest) and remove the
27
 * device from the virtual css bus.
28
 */
29
static void ccw_device_unplug(HotplugHandler *hotplug_dev,
30
                              DeviceState *dev, Error **errp)
31
{
32
    CcwDevice *ccw_dev = CCW_DEVICE(dev);
33
    CCWDeviceClass *k = CCW_DEVICE_GET_CLASS(ccw_dev);
34
    SubchDev *sch = ccw_dev->sch;
35
    Error *err = NULL;
36

37
    if (k->unplug) {
38
        k->unplug(hotplug_dev, dev, &err);
39
        if (err) {
40
            error_propagate(errp, err);
41
            return;
42
        }
43
    }
44

45
    /*
46
     * We should arrive here only for device_del, since we don't support
47
     * direct hot(un)plug of channels.
48
     */
49
    assert(sch != NULL);
50
    /* Subchannel is now disabled and no longer valid. */
51
    sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
52
                                     PMCW_FLAGS_MASK_DNV);
53

54
    css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
55

56
    qdev_unrealize(dev);
57
}
58

59
static void virtual_css_bus_reset_hold(Object *obj, ResetType type)
60
{
61
    /* This should actually be modelled via the generic css */
62
    css_reset();
63
}
64

65
static char *virtual_css_bus_get_dev_path(DeviceState *dev)
66
{
67
    CcwDevice *ccw_dev = CCW_DEVICE(dev);
68
    SubchDev *sch = ccw_dev->sch;
69
    VirtualCssBridge *bridge =
70
        VIRTUAL_CSS_BRIDGE(qdev_get_parent_bus(dev)->parent);
71

72
    /*
73
     * We can't provide a dev path for backward compatibility on
74
     * older machines, as it is visible in the migration stream.
75
     */
76
    return bridge->css_dev_path ?
77
        g_strdup_printf("/%02x.%1x.%04x", sch->cssid, sch->ssid, sch->devno) :
78
        NULL;
79
}
80

81
static void virtual_css_bus_class_init(ObjectClass *klass, void *data)
82
{
83
    BusClass *k = BUS_CLASS(klass);
84
    ResettableClass *rc = RESETTABLE_CLASS(klass);
85

86
    rc->phases.hold = virtual_css_bus_reset_hold;
87
    k->get_dev_path = virtual_css_bus_get_dev_path;
88
}
89

90
static const TypeInfo virtual_css_bus_info = {
91
    .name = TYPE_VIRTUAL_CSS_BUS,
92
    .parent = TYPE_BUS,
93
    .instance_size = sizeof(VirtualCssBus),
94
    .class_init = virtual_css_bus_class_init,
95
};
96

97
VirtualCssBus *virtual_css_bus_init(void)
98
{
99
    BusState *bus;
100
    DeviceState *dev;
101

102
    /* Create bridge device */
103
    dev = qdev_new(TYPE_VIRTUAL_CSS_BRIDGE);
104
    object_property_add_child(qdev_get_machine(), TYPE_VIRTUAL_CSS_BRIDGE,
105
                              OBJECT(dev));
106

107
    /* Create bus on bridge device */
108
    bus = qbus_new(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
109

110
    /* Enable hotplugging */
111
    qbus_set_hotplug_handler(bus, OBJECT(dev));
112

113
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
114

115
    css_register_io_adapters(CSS_IO_ADAPTER_VIRTIO, true, false,
116
                             0, &error_abort);
117

118
    return VIRTUAL_CSS_BUS(bus);
119
 }
120

121
/***************** Virtual-css Bus Bridge Device ********************/
122

123
static Property virtual_css_bridge_properties[] = {
124
    DEFINE_PROP_BOOL("css_dev_path", VirtualCssBridge, css_dev_path,
125
                     true),
126
    DEFINE_PROP_END_OF_LIST(),
127
};
128

129
static bool prop_get_true(Object *obj, Error **errp)
130
{
131
    return true;
132
}
133

134
static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
135
{
136
    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
137
    DeviceClass *dc = DEVICE_CLASS(klass);
138

139
    hc->unplug = ccw_device_unplug;
140
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
141
    device_class_set_props(dc, virtual_css_bridge_properties);
142
    object_class_property_add_bool(klass, "cssid-unrestricted",
143
                                   prop_get_true, NULL);
144
    object_class_property_set_description(klass, "cssid-unrestricted",
145
            "A css device can use any cssid, regardless whether virtual"
146
            " or not (read only, always true)");
147
}
148

149
static const TypeInfo virtual_css_bridge_info = {
150
    .name          = TYPE_VIRTUAL_CSS_BRIDGE,
151
    .parent        = TYPE_SYS_BUS_DEVICE,
152
    .instance_size = sizeof(VirtualCssBridge),
153
    .class_init    = virtual_css_bridge_class_init,
154
    .interfaces = (InterfaceInfo[]) {
155
        { TYPE_HOTPLUG_HANDLER },
156
        { }
157
    }
158
};
159

160
static void virtual_css_register(void)
161
{
162
    type_register_static(&virtual_css_bridge_info);
163
    type_register_static(&virtual_css_bus_info);
164
}
165

166
type_init(virtual_css_register)
167

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.