1
2
3
4
5
6
7
8
9
10
11
12
13#include "qemu/osdep.h"
14#include "hw/virtio/virtio-md-pci.h"
15#include "hw/mem/memory-device.h"
16#include "qapi/error.h"
17#include "qemu/error-report.h"
18
19void virtio_md_pci_pre_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
20{
21 DeviceState *dev = DEVICE(vmd);
22 HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
23 MemoryDeviceState *md = MEMORY_DEVICE(vmd);
24 Error *local_err = NULL;
25
26 if (!bus_handler && dev->hotplugged) {
27
28
29
30
31
32 error_setg(errp, "hotplug of virtio based memory devices not supported"
33 " on this bus.");
34 return;
35 }
36
37
38
39
40 memory_device_pre_plug(md, ms, NULL, &local_err);
41 if (!local_err && bus_handler) {
42 hotplug_handler_pre_plug(bus_handler, dev, &local_err);
43 }
44 error_propagate(errp, local_err);
45}
46
47void virtio_md_pci_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
48{
49 DeviceState *dev = DEVICE(vmd);
50 HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
51 MemoryDeviceState *md = MEMORY_DEVICE(vmd);
52 Error *local_err = NULL;
53
54
55
56
57
58
59 memory_device_plug(md, ms);
60 if (bus_handler) {
61 hotplug_handler_plug(bus_handler, dev, &local_err);
62 if (local_err) {
63 memory_device_unplug(md, ms);
64 }
65 }
66 error_propagate(errp, local_err);
67}
68
69void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms,
70 Error **errp)
71{
72 VirtIOMDPCIClass *vmdc = VIRTIO_MD_PCI_GET_CLASS(vmd);
73 DeviceState *dev = DEVICE(vmd);
74 HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
75 HotplugHandlerClass *hdc;
76 Error *local_err = NULL;
77
78 if (!vmdc->unplug_request_check) {
79 error_setg(errp, "this virtio based memory devices cannot be unplugged");
80 return;
81 }
82
83 if (!bus_handler) {
84 error_setg(errp, "hotunplug of virtio based memory devices not"
85 "supported on this bus");
86 return;
87 }
88
89 vmdc->unplug_request_check(vmd, &local_err);
90 if (local_err) {
91 error_propagate(errp, local_err);
92 return;
93 }
94
95
96
97
98
99 hdc = HOTPLUG_HANDLER_GET_CLASS(bus_handler);
100 if (hdc->unplug_request) {
101 hotplug_handler_unplug_request(bus_handler, dev, &local_err);
102 } else {
103 virtio_md_pci_unplug(vmd, ms, &local_err);
104 if (!local_err) {
105 object_unparent(OBJECT(dev));
106 }
107 }
108}
109
110void virtio_md_pci_unplug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)
111{
112 DeviceState *dev = DEVICE(vmd);
113 HotplugHandler *bus_handler = qdev_get_bus_hotplug_handler(dev);
114 MemoryDeviceState *md = MEMORY_DEVICE(vmd);
115 Error *local_err = NULL;
116
117
118 memory_device_unplug(md, ms);
119
120 if (bus_handler) {
121 hotplug_handler_unplug(bus_handler, dev, &local_err);
122 if (local_err) {
123
124 memory_device_plug(md, ms);
125 error_propagate(errp, local_err);
126 return;
127 }
128 } else {
129
130 warn_report("Unexpected unplug of virtio based memory device");
131 qdev_unrealize(dev);
132 }
133}
134
135static const TypeInfo virtio_md_pci_info = {
136 .name = TYPE_VIRTIO_MD_PCI,
137 .parent = TYPE_VIRTIO_PCI,
138 .instance_size = sizeof(VirtIOMDPCI),
139 .class_size = sizeof(VirtIOMDPCIClass),
140 .abstract = true,
141 .interfaces = (InterfaceInfo[]) {
142 { TYPE_MEMORY_DEVICE },
143 { }
144 },
145};
146
147static void virtio_md_pci_register(void)
148{
149 type_register_static(&virtio_md_pci_info);
150}
151type_init(virtio_md_pci_register)
152