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:
Isaku Yamahata 2011-05-25 10:57:58 +09:00 committed by Michael S. Tsirkin
parent 2173a75fb7
commit 113f89df42
2 changed files with 39 additions and 14 deletions

View File

@ -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) {

View File

@ -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.