mirror of https://gitee.com/openkylin/qemu.git
pci: move ids of config space into PCIDeviceInfo
vender id/device id... in configuration space are read-only registers which are commonly defined for all pci devices. So move those initialization into common place. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
2173a75fb7
commit
113f89df42
46
hw/pci.c
46
hw/pci.c
|
@ -726,10 +726,11 @@ static void pci_config_free(PCIDevice *pci_dev)
|
||||||
/* -1 for devfn means auto assign */
|
/* -1 for devfn means auto assign */
|
||||||
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
||||||
const char *name, int devfn,
|
const char *name, int devfn,
|
||||||
PCIConfigReadFunc *config_read,
|
const PCIDeviceInfo *info)
|
||||||
PCIConfigWriteFunc *config_write,
|
|
||||||
bool is_bridge)
|
|
||||||
{
|
{
|
||||||
|
PCIConfigReadFunc *config_read = info->config_read;
|
||||||
|
PCIConfigWriteFunc *config_write = info->config_write;
|
||||||
|
|
||||||
if (devfn < 0) {
|
if (devfn < 0) {
|
||||||
for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
|
for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
|
||||||
devfn += PCI_FUNC_MAX) {
|
devfn += PCI_FUNC_MAX) {
|
||||||
|
@ -750,13 +751,29 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
||||||
pci_dev->irq_state = 0;
|
pci_dev->irq_state = 0;
|
||||||
pci_config_alloc(pci_dev);
|
pci_config_alloc(pci_dev);
|
||||||
|
|
||||||
if (!is_bridge) {
|
pci_config_set_vendor_id(pci_dev->config, info->vendor_id);
|
||||||
pci_set_default_subsystem_id(pci_dev);
|
pci_config_set_device_id(pci_dev->config, info->device_id);
|
||||||
|
pci_config_set_revision(pci_dev->config, info->revision);
|
||||||
|
pci_config_set_class(pci_dev->config, info->class_id);
|
||||||
|
|
||||||
|
if (!info->is_bridge) {
|
||||||
|
if (info->subsystem_vendor_id || info->subsystem_id) {
|
||||||
|
pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
|
||||||
|
info->subsystem_vendor_id);
|
||||||
|
pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
|
||||||
|
info->subsystem_id);
|
||||||
|
} else {
|
||||||
|
pci_set_default_subsystem_id(pci_dev);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* subsystem_vendor_id/subsystem_id are only for header type 0 */
|
||||||
|
assert(!info->subsystem_vendor_id);
|
||||||
|
assert(!info->subsystem_id);
|
||||||
}
|
}
|
||||||
pci_init_cmask(pci_dev);
|
pci_init_cmask(pci_dev);
|
||||||
pci_init_wmask(pci_dev);
|
pci_init_wmask(pci_dev);
|
||||||
pci_init_w1cmask(pci_dev);
|
pci_init_w1cmask(pci_dev);
|
||||||
if (is_bridge) {
|
if (info->is_bridge) {
|
||||||
pci_init_wmask_bridge(pci_dev);
|
pci_init_wmask_bridge(pci_dev);
|
||||||
}
|
}
|
||||||
if (pci_init_multifunction(bus, pci_dev)) {
|
if (pci_init_multifunction(bus, pci_dev)) {
|
||||||
|
@ -783,17 +800,20 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
|
||||||
pci_config_free(pci_dev);
|
pci_config_free(pci_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: obsolete. eliminate this once all pci devices are qdevifed. */
|
||||||
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
|
PCIDevice *pci_register_device(PCIBus *bus, const char *name,
|
||||||
int instance_size, int devfn,
|
int instance_size, int devfn,
|
||||||
PCIConfigReadFunc *config_read,
|
PCIConfigReadFunc *config_read,
|
||||||
PCIConfigWriteFunc *config_write)
|
PCIConfigWriteFunc *config_write)
|
||||||
{
|
{
|
||||||
PCIDevice *pci_dev;
|
PCIDevice *pci_dev;
|
||||||
|
PCIDeviceInfo info = {
|
||||||
|
.config_read = config_read,
|
||||||
|
.config_write = config_write,
|
||||||
|
};
|
||||||
|
|
||||||
pci_dev = qemu_mallocz(instance_size);
|
pci_dev = qemu_mallocz(instance_size);
|
||||||
pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,
|
pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info);
|
||||||
config_read, config_write,
|
|
||||||
PCI_HEADER_TYPE_NORMAL);
|
|
||||||
if (pci_dev == NULL) {
|
if (pci_dev == NULL) {
|
||||||
hw_error("PCI: can't register device\n");
|
hw_error("PCI: can't register device\n");
|
||||||
}
|
}
|
||||||
|
@ -1643,7 +1663,7 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
||||||
PCIDevice *pci_dev = (PCIDevice *)qdev;
|
PCIDevice *pci_dev = (PCIDevice *)qdev;
|
||||||
PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
|
PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
|
||||||
PCIBus *bus;
|
PCIBus *bus;
|
||||||
int devfn, rc;
|
int rc;
|
||||||
bool is_default_rom;
|
bool is_default_rom;
|
||||||
|
|
||||||
/* initialize cap_present for pci_is_express() and pci_config_size() */
|
/* initialize cap_present for pci_is_express() and pci_config_size() */
|
||||||
|
@ -1652,10 +1672,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
||||||
}
|
}
|
||||||
|
|
||||||
bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
|
bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
|
||||||
devfn = pci_dev->devfn;
|
pci_dev = do_pci_register_device(pci_dev, bus, base->name,
|
||||||
pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
|
pci_dev->devfn, info);
|
||||||
info->config_read, info->config_write,
|
|
||||||
info->is_bridge);
|
|
||||||
if (pci_dev == NULL)
|
if (pci_dev == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (qdev->hotplugged && info->no_hotplug) {
|
if (qdev->hotplugged && info->no_hotplug) {
|
||||||
|
|
7
hw/pci.h
7
hw/pci.h
|
@ -433,6 +433,13 @@ typedef struct {
|
||||||
PCIConfigReadFunc *config_read;
|
PCIConfigReadFunc *config_read;
|
||||||
PCIConfigWriteFunc *config_write;
|
PCIConfigWriteFunc *config_write;
|
||||||
|
|
||||||
|
uint16_t vendor_id;
|
||||||
|
uint16_t device_id;
|
||||||
|
uint8_t revision;
|
||||||
|
uint16_t class_id;
|
||||||
|
uint16_t subsystem_vendor_id; /* only for header type = 0 */
|
||||||
|
uint16_t subsystem_id; /* only for header type = 0 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pci-to-pci bridge or normal device.
|
* pci-to-pci bridge or normal device.
|
||||||
* This doesn't mean pci host switch.
|
* This doesn't mean pci host switch.
|
||||||
|
|
Loading…
Reference in New Issue