pci: allow devices being tagged as not hotpluggable.
This patch adds a field to PCIDeviceInfo to tag devices as being not hotpluggable. Any attempt to plug-in or -out such a device will throw an error. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
c574ba5a4c
commit
180c22e18b
10
hw/pci.c
10
hw/pci.c
@ -1624,6 +1624,11 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
|||||||
info->is_bridge);
|
info->is_bridge);
|
||||||
if (pci_dev == NULL)
|
if (pci_dev == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (qdev->hotplugged && info->no_hotplug) {
|
||||||
|
qerror_report(QERR_DEVICE_NO_HOTPLUG, info->qdev.name);
|
||||||
|
do_pci_unregister_device(pci_dev);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
rc = info->init(pci_dev);
|
rc = info->init(pci_dev);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
do_pci_unregister_device(pci_dev);
|
do_pci_unregister_device(pci_dev);
|
||||||
@ -1656,7 +1661,12 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
|||||||
static int pci_unplug_device(DeviceState *qdev)
|
static int pci_unplug_device(DeviceState *qdev)
|
||||||
{
|
{
|
||||||
PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
|
PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
|
||||||
|
PCIDeviceInfo *info = container_of(qdev->info, PCIDeviceInfo, qdev);
|
||||||
|
|
||||||
|
if (info->no_hotplug) {
|
||||||
|
qerror_report(QERR_DEVICE_NO_HOTPLUG, info->qdev.name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
|
return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
|
||||||
PCI_HOTPLUG_DISABLED);
|
PCI_HOTPLUG_DISABLED);
|
||||||
}
|
}
|
||||||
|
3
hw/pci.h
3
hw/pci.h
@ -436,6 +436,9 @@ typedef struct {
|
|||||||
/* pcie stuff */
|
/* pcie stuff */
|
||||||
int is_express; /* is this device pci express? */
|
int is_express; /* is this device pci express? */
|
||||||
|
|
||||||
|
/* device isn't hot-pluggable */
|
||||||
|
int no_hotplug;
|
||||||
|
|
||||||
/* rom bar */
|
/* rom bar */
|
||||||
const char *romfile;
|
const char *romfile;
|
||||||
} PCIDeviceInfo;
|
} PCIDeviceInfo;
|
||||||
|
4
qerror.c
4
qerror.c
@ -100,6 +100,10 @@ static const QErrorStringTable qerror_table[] = {
|
|||||||
.error_fmt = QERR_DEVICE_NO_BUS,
|
.error_fmt = QERR_DEVICE_NO_BUS,
|
||||||
.desc = "Device '%(device)' has no child bus",
|
.desc = "Device '%(device)' has no child bus",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.error_fmt = QERR_DEVICE_NO_HOTPLUG,
|
||||||
|
.desc = "Device '%(device)' does not support hotplugging",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.error_fmt = QERR_DUPLICATE_ID,
|
.error_fmt = QERR_DUPLICATE_ID,
|
||||||
.desc = "Duplicate ID '%(id)' for %(object)",
|
.desc = "Duplicate ID '%(id)' for %(object)",
|
||||||
|
3
qerror.h
3
qerror.h
@ -90,6 +90,9 @@ QError *qobject_to_qerror(const QObject *obj);
|
|||||||
#define QERR_DEVICE_NO_BUS \
|
#define QERR_DEVICE_NO_BUS \
|
||||||
"{ 'class': 'DeviceNoBus', 'data': { 'device': %s } }"
|
"{ 'class': 'DeviceNoBus', 'data': { 'device': %s } }"
|
||||||
|
|
||||||
|
#define QERR_DEVICE_NO_HOTPLUG \
|
||||||
|
"{ 'class': 'DeviceNoHotplug', 'data': { 'device': %s } }"
|
||||||
|
|
||||||
#define QERR_DUPLICATE_ID \
|
#define QERR_DUPLICATE_ID \
|
||||||
"{ 'class': 'DuplicateId', 'data': { 'id': %s, 'object': %s } }"
|
"{ 'class': 'DuplicateId', 'data': { 'id': %s, 'object': %s } }"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user