9 #include "device-assignment.h"
11 #include "virtio-blk.h"
13 #define PCI_BASE_CLASS_STORAGE 0x01
14 #define PCI_BASE_CLASS_NETWORK 0x02
16 static PCIDevice
*qemu_system_hot_add_nic(const char *opts
, int bus_nr
)
21 pci_bus
= pci_find_bus (bus_nr
);
23 term_printf ("Can't find pci_bus %d\n", bus_nr
);
27 ret
= net_client_init ("nic", opts
);
28 if (ret
< 0 || !nd_table
[ret
].model
)
30 return pci_nic_init (pci_bus
, &nd_table
[ret
], -1, "rtl8139");
33 #ifdef USE_KVM_DEVICE_ASSIGNMENT
34 static PCIDevice
*qemu_system_hot_assign_device(const char *opts
, int bus_nr
)
37 AssignedDevInfo
*adev
;
40 pci_bus
= pci_find_bus(bus_nr
);
42 term_printf ("Can't find pci_bus %d\n", bus_nr
);
45 adev
= add_assigned_device(opts
);
47 term_printf ("Error adding device; check syntax\n");
51 ret
= init_assigned_device(adev
, pci_bus
);
53 term_printf("Failed to assign device\n");
54 free_assigned_device(adev
);
58 term_printf("Registered host PCI device %02x:%02x.%1x "
59 "(\"%s\") as guest device %02x:%02x.%1x\n",
60 adev
->bus
, adev
->dev
, adev
->func
, adev
->name
,
61 pci_bus_num(pci_bus
), (ret
->devfn
>> 3) & 0x1f,
67 #endif /* USE_KVM_DEVICE_ASSIGNMENT */
69 static int add_init_drive(const char *opts
)
71 int drive_opt_idx
, drive_idx
;
74 drive_opt_idx
= drive_add(NULL
, "%s", opts
);
78 drive_idx
= drive_init(&drives_opt
[drive_opt_idx
], 0, current_machine
);
79 if (drive_idx
== -1) {
80 drive_remove(drive_opt_idx
);
87 void drive_hot_add(int pcibus
, const char *devfn_string
, const char *opts
)
89 int drive_idx
, type
, bus
;
94 devfn
= strtoul(devfn_string
, NULL
, 0);
96 dev
= pci_find_device(pcibus
, PCI_SLOT(devfn
));
98 term_printf("no pci device with devfn %d (slot %d)\n", devfn
,
103 drive_idx
= add_init_drive(opts
);
106 type
= drives_table
[drive_idx
].type
;
107 bus
= drive_get_max_bus (type
);
112 lsi_scsi_attach (dev
, drives_table
[drive_idx
].bdrv
,
113 drives_table
[drive_idx
].unit
);
116 term_printf("Can't hot-add drive to type %d\n", type
);
120 term_printf("OK bus %d, unit %d\n", drives_table
[drive_idx
].bus
,
121 drives_table
[drive_idx
].unit
);
125 static PCIDevice
*qemu_system_hot_add_storage(const char *opts
, int bus_nr
)
129 int type
= -1, drive_idx
= -1;
132 pci_bus
= pci_find_bus(bus_nr
);
134 term_printf("Can't find pci_bus %d\n", bus_nr
);
138 if (get_param_value(buf
, sizeof(buf
), "if", opts
)) {
139 if (!strcmp(buf
, "scsi"))
141 else if (!strcmp(buf
, "virtio")) {
145 term_printf("no if= specified\n");
149 if (get_param_value(buf
, sizeof(buf
), "file", opts
)) {
150 drive_idx
= add_init_drive(opts
);
153 } else if (type
== IF_VIRTIO
) {
154 term_printf("virtio requires a backing file/device.\n");
160 opaque
= lsi_scsi_init (pci_bus
, -1);
161 if (opaque
&& drive_idx
>= 0)
162 lsi_scsi_attach (opaque
, drives_table
[drive_idx
].bdrv
,
163 drives_table
[drive_idx
].unit
);
166 opaque
= virtio_blk_init(pci_bus
, drives_table
[drive_idx
].bdrv
);
169 term_printf ("type %s not a hotpluggable PCI device.\n", buf
);
175 #if defined(TARGET_I386) || defined(TARGET_X86_64)
176 void device_hot_add(int pcibus
, const char *type
, const char *opts
)
178 PCIDevice
*dev
= NULL
;
180 if (strcmp(type
, "nic") == 0)
181 dev
= qemu_system_hot_add_nic(opts
, pcibus
);
182 else if (strcmp(type
, "storage") == 0)
183 dev
= qemu_system_hot_add_storage(opts
, pcibus
);
184 #ifdef USE_KVM_DEVICE_ASSIGNMENT
185 else if (strcmp(type
, "host") == 0)
186 dev
= qemu_system_hot_assign_device(opts
, pcibus
);
187 #endif /* USE_KVM_DEVICE_ASSIGNMENT */
189 term_printf("invalid type: %s\n", type
);
192 qemu_system_device_hot_add(pcibus
, PCI_SLOT(dev
->devfn
), 1);
193 term_printf("OK bus %d, slot %d, function %d (devfn %d)\n",
194 pci_bus_num(dev
->bus
), PCI_SLOT(dev
->devfn
),
195 PCI_FUNC(dev
->devfn
), dev
->devfn
);
197 term_printf("failed to add %s\n", opts
);
200 void device_hot_remove(int pcibus
, int slot
)
202 PCIDevice
*d
= pci_find_device(pcibus
, slot
);
205 term_printf("invalid slot %d\n", slot
);
209 qemu_system_device_hot_add(pcibus
, slot
, 0);
213 static void destroy_nic(int slot
)
217 for (i
= 0; i
< MAX_NICS
; i
++)
218 if (nd_table
[i
].used
&&
219 PCI_SLOT(nd_table
[i
].devfn
) == slot
)
220 net_client_uninit(&nd_table
[i
]);
223 static void destroy_bdrvs(int slot
)
226 struct BlockDriverState
*bs
;
228 for (i
= 0; i
<= MAX_DRIVES
; i
++) {
229 bs
= drives_table
[i
].bdrv
;
230 if (bs
&& (PCI_SLOT(bs
->devfn
) == slot
)) {
238 * OS has executed _EJ0 method, we now can remove the device
240 void device_hot_remove_success(int pcibus
, int slot
)
242 PCIDevice
*d
= pci_find_device(pcibus
, slot
);
246 term_printf("invalid slot %d\n", slot
);
250 class_code
= d
->config_read(d
, PCI_CLASS_DEVICE
+1, 1);
252 pci_unregister_device(d
);
255 case PCI_BASE_CLASS_STORAGE
:
258 case PCI_BASE_CLASS_NETWORK
: