From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42675) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QMNYz-0002IH-HY for qemu-devel@nongnu.org; Tue, 17 May 2011 12:56:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QMNYv-0001Go-EU for qemu-devel@nongnu.org; Tue, 17 May 2011 12:56:05 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:45303) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QMNYu-0001Fg-Ul for qemu-devel@nongnu.org; Tue, 17 May 2011 12:56:01 -0400 From: Isaku Yamahata Date: Wed, 18 May 2011 01:55:18 +0900 Message-Id: In-Reply-To: References: In-Reply-To: References: Subject: [Qemu-devel] [PATCH v2 01/38] pci: move ids of config space into PCIDeviceInfo List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: yamahata@valinux.co.jp, mst@redhat.com 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 --- changes v1 -> v2: - dropped prog_interface, header_type - added assert() for header type = 1 --- hw/pci.c | 46 ++++++++++++++++++++++++++++++++-------------- hw/pci.h | 7 +++++++ 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 0875654..0e97a02 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -726,10 +726,11 @@ static void pci_config_free(PCIDevice *pci_dev) /* -1 for devfn means auto assign */ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, const char *name, int devfn, - PCIConfigReadFunc *config_read, - PCIConfigWriteFunc *config_write, - bool is_bridge) + const PCIDeviceInfo *info) { + PCIConfigReadFunc *config_read = info->config_read; + PCIConfigWriteFunc *config_write = info->config_write; + if (devfn < 0) { for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices); 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_config_alloc(pci_dev); - if (!is_bridge) { - pci_set_default_subsystem_id(pci_dev); + pci_config_set_vendor_id(pci_dev->config, info->vendor_id); + 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_wmask(pci_dev); pci_init_w1cmask(pci_dev); - if (is_bridge) { + if (info->is_bridge) { pci_init_wmask_bridge(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); } +/* TODO: obsolete. eliminate this once all pci devices are qdevifed. */ PCIDevice *pci_register_device(PCIBus *bus, const char *name, int instance_size, int devfn, PCIConfigReadFunc *config_read, PCIConfigWriteFunc *config_write) { PCIDevice *pci_dev; + PCIDeviceInfo info = { + .config_read = config_read, + .config_write = config_write, + }; pci_dev = qemu_mallocz(instance_size); - pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, - config_read, config_write, - PCI_HEADER_TYPE_NORMAL); + pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info); if (pci_dev == NULL) { 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; PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev); PCIBus *bus; - int devfn, rc; + int rc; bool is_default_rom; /* 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)); - devfn = pci_dev->devfn; - pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn, - info->config_read, info->config_write, - info->is_bridge); + pci_dev = do_pci_register_device(pci_dev, bus, base->name, + pci_dev->devfn, info); if (pci_dev == NULL) return -1; if (qdev->hotplugged && info->no_hotplug) { diff --git a/hw/pci.h b/hw/pci.h index c6a6eb6..ce214f4 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -433,6 +433,13 @@ typedef struct { PCIConfigReadFunc *config_read; 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. * This doesn't mean pci host switch. -- 1.7.1.1