From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49414) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ymi8A-0007yU-Hl for qemu-devel@nongnu.org; Mon, 27 Apr 2015 08:27:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ymi85-00053U-6V for qemu-devel@nongnu.org; Mon, 27 Apr 2015 08:27:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58563) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ymi84-00053M-TO for qemu-devel@nongnu.org; Mon, 27 Apr 2015 08:27:17 -0400 Message-ID: <553E2B04.8030703@redhat.com> Date: Mon, 27 Apr 2015 15:26:44 +0300 From: Marcel Apfelbaum MIME-Version: 1.0 References: <1426791181-23831-1-git-send-email-marcel@redhat.com> <1426791181-23831-10-git-send-email-marcel@redhat.com> <20150427130801-mutt-send-email-mst@redhat.com> In-Reply-To: <20150427130801-mutt-send-email-mst@redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH V6 for-2.3 09/26] hw/pci: move pci bus related code to separate files List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Michael S. Tsirkin" Cc: kraxel@redhat.com, quintela@redhat.com, qemu-devel@nongnu.org, agraf@suse.de, alex.williamson@redhat.com, kevin@koconnor.net, hare@suse.de, imammedo@redhat.com, amit.shah@redhat.com, pbonzini@redhat.com, leon.alrae@imgtec.com, aurelien@aurel32.net, rth@twiddle.net On 04/27/2015 02:14 PM, Michael S. Tsirkin wrote: > On Thu, Mar 19, 2015 at 08:52:44PM +0200, Marcel Apfelbaum wrote: >> @@ -2414,7 +1945,6 @@ static const TypeInfo pci_device_type_info = { >> >> static void pci_register_types(void) >> { >> - type_register_static(&pci_bus_info); >> type_register_static(&pcie_bus_info); >> type_register_static(&pci_device_type_info); >> } > > So pcie bus is not moved. This seems pretty inconsistent. There were a lot of code dependencies. I moved the minimum code in order to be able to add code specific to PCIBus. > > >> diff --git a/hw/pci/pci_bus.c b/hw/pci/pci_bus.c >> new file mode 100644 >> index 0000000..d156194 >> --- /dev/null >> +++ b/hw/pci/pci_bus.c >> @@ -0,0 +1,491 @@ >> +/* >> + * PCI Bus >> + * >> + * Copyright (C) 2014 Red Hat Inc > > It's 2015 isn't it? Well, now yes :) > >> + * >> + * Authors: >> + * Marcel Apfelbaum (split out from pci.c) > > You don't become the only Author just by moving code around. > Better drop this line. I was following an example of the latest code movement at that time in QEMU. Anyway, I will remove that line. > > > >> + * >> + * This work is licensed under the terms of the GNU GPL, version 2 or later. >> + * See the COPYING file in the top-level directory. > > The file you are moving this from is GPL only. > You will need to find who contributed this code you are moving > and get ack from them ... I'll keep it as BSD as Paolo suggested. > >> + */ >> +#include "hw/pci/pci.h" >> +#include "hw/pci/pci_bus.h" >> +#include "hw/pci/pci_bridge.h" >> +#include "monitor/monitor.h" >> + >> +typedef struct { >> + uint16_t class; >> + const char *desc; >> + const char *fw_name; >> + uint16_t fw_ign_bits; >> +} pci_class_desc; >> + >> +static const pci_class_desc pci_class_descriptions[] = { >> + { 0x0001, "VGA controller", "display"}, >> + { 0x0100, "SCSI controller", "scsi"}, >> + { 0x0101, "IDE controller", "ide"}, >> + { 0x0102, "Floppy controller", "fdc"}, >> + { 0x0103, "IPI controller", "ipi"}, >> + { 0x0104, "RAID controller", "raid"}, >> + { 0x0106, "SATA controller"}, >> + { 0x0107, "SAS controller"}, >> + { 0x0180, "Storage controller"}, >> + { 0x0200, "Ethernet controller", "ethernet"}, >> + { 0x0201, "Token Ring controller", "token-ring"}, >> + { 0x0202, "FDDI controller", "fddi"}, >> + { 0x0203, "ATM controller", "atm"}, >> + { 0x0280, "Network controller"}, >> + { 0x0300, "VGA controller", "display", 0x00ff}, >> + { 0x0301, "XGA controller"}, >> + { 0x0302, "3D controller"}, >> + { 0x0380, "Display controller"}, >> + { 0x0400, "Video controller", "video"}, >> + { 0x0401, "Audio controller", "sound"}, >> + { 0x0402, "Phone"}, >> + { 0x0403, "Audio controller", "sound"}, >> + { 0x0480, "Multimedia controller"}, >> + { 0x0500, "RAM controller", "memory"}, >> + { 0x0501, "Flash controller", "flash"}, >> + { 0x0580, "Memory controller"}, >> + { 0x0600, "Host bridge", "host"}, >> + { 0x0601, "ISA bridge", "isa"}, >> + { 0x0602, "EISA bridge", "eisa"}, >> + { 0x0603, "MC bridge", "mca"}, >> + { 0x0604, "PCI bridge", "pci-bridge"}, >> + { 0x0605, "PCMCIA bridge", "pcmcia"}, >> + { 0x0606, "NUBUS bridge", "nubus"}, >> + { 0x0607, "CARDBUS bridge", "cardbus"}, >> + { 0x0608, "RACEWAY bridge"}, >> + { 0x0680, "Bridge"}, >> + { 0x0700, "Serial port", "serial"}, >> + { 0x0701, "Parallel port", "parallel"}, >> + { 0x0800, "Interrupt controller", "interrupt-controller"}, >> + { 0x0801, "DMA controller", "dma-controller"}, >> + { 0x0802, "Timer", "timer"}, >> + { 0x0803, "RTC", "rtc"}, >> + { 0x0900, "Keyboard", "keyboard"}, >> + { 0x0901, "Pen", "pen"}, >> + { 0x0902, "Mouse", "mouse"}, >> + { 0x0A00, "Dock station", "dock", 0x00ff}, >> + { 0x0B00, "i386 cpu", "cpu", 0x00ff}, >> + { 0x0c00, "Fireware contorller", "fireware"}, >> + { 0x0c01, "Access bus controller", "access-bus"}, >> + { 0x0c02, "SSA controller", "ssa"}, >> + { 0x0c03, "USB controller", "usb"}, >> + { 0x0c04, "Fibre channel controller", "fibre-channel"}, >> + { 0x0c05, "SMBus"}, >> + { 0, NULL} >> +}; >> + >> +/* Whether a given bus number is in range of the secondary >> + * bus of the given bridge device. */ >> +static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num) >> +{ >> + return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) & >> + PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */ && >> + dev->config[PCI_SECONDARY_BUS] < bus_num && >> + bus_num <= dev->config[PCI_SUBORDINATE_BUS]; >> +} >> + >> +PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num) >> +{ >> + PCIBus *sec; >> + >> + if (!bus) { >> + return NULL; >> + } >> + >> + if (pci_bus_num(bus) == bus_num) { >> + return bus; >> + } >> + >> + /* Consider all bus numbers in range for the host pci bridge. */ >> + if (!pci_bus_is_root(bus) && >> + !pci_secondary_bus_in_range(bus->parent_dev, bus_num)) { >> + return NULL; >> + } >> + >> + /* try child bus */ >> + for (; bus; bus = sec) { >> + QLIST_FOREACH(sec, &bus->child, sibling) { >> + assert(!pci_bus_is_root(sec)); >> + if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) { >> + return sec; >> + } >> + if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) { >> + break; >> + } >> + } >> + } >> + >> + return NULL; >> +} >> + >> +static const pci_class_desc *get_class_desc(int class) >> +{ >> + const pci_class_desc *desc; >> + >> + desc = pci_class_descriptions; >> + while (desc->desc && class != desc->class) { >> + desc++; >> + } >> + >> + return desc; >> +} >> + >> +static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev) >> +{ >> + PciMemoryRegionList *head = NULL, *cur_item = NULL; >> + int i; >> + >> + for (i = 0; i < PCI_NUM_REGIONS; i++) { >> + const PCIIORegion *r = &dev->io_regions[i]; >> + PciMemoryRegionList *region; >> + >> + if (!r->size) { >> + continue; >> + } >> + >> + region = g_malloc0(sizeof(*region)); >> + region->value = g_malloc0(sizeof(*region->value)); >> + >> + if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { >> + region->value->type = g_strdup("io"); >> + } else { >> + region->value->type = g_strdup("memory"); >> + region->value->has_prefetch = true; >> + region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH); >> + region->value->has_mem_type_64 = true; >> + region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64); >> + } >> + >> + region->value->bar = i; >> + region->value->address = r->addr; >> + region->value->size = r->size; >> + >> + /* XXX: waiting for the qapi to support GSList */ >> + if (!cur_item) { >> + head = cur_item = region; >> + } else { >> + cur_item->next = region; >> + cur_item = region; >> + } >> + } >> + >> + return head; >> +} >> + >> +static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus, >> + int bus_num) >> +{ >> + PciBridgeInfo *info; >> + >> + info = g_malloc0(sizeof(*info)); >> + >> + info->bus.number = dev->config[PCI_PRIMARY_BUS]; >> + info->bus.secondary = dev->config[PCI_SECONDARY_BUS]; >> + info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS]; >> + >> + info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range)); >> + info->bus.io_range->base = pci_bridge_get_base(dev, >> + PCI_BASE_ADDRESS_SPACE_IO); >> + info->bus.io_range->limit = >> + pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO); >> + >> + info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range)); >> + info->bus.memory_range->base = >> + pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY); >> + info->bus.memory_range->limit = >> + pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY); >> + >> + info->bus.prefetchable_range = >> + g_malloc0(sizeof(*info->bus.prefetchable_range)); >> + info->bus.prefetchable_range->base = >> + pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); >> + info->bus.prefetchable_range->limit = >> + pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); >> + >> + if (dev->config[PCI_SECONDARY_BUS] != 0) { >> + PCIBus *child_bus = pci_find_bus_nr(bus, dev->config[PCI_SECONDARY_BUS]); >> + if (child_bus) { >> + info->has_devices = true; >> + info->devices = qmp_query_pci_devices(child_bus, >> + dev->config[PCI_SECONDARY_BUS]); >> + } >> + } >> + >> + return info; >> +} >> + >> +static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus, >> + int bus_num) >> +{ >> + const pci_class_desc *desc; >> + PciDeviceInfo *info; >> + uint8_t type; >> + int class; >> + >> + info = g_malloc0(sizeof(*info)); >> + info->bus = bus_num; >> + info->slot = PCI_SLOT(dev->devfn); >> + info->function = PCI_FUNC(dev->devfn); >> + >> + class = pci_get_word(dev->config + PCI_CLASS_DEVICE); >> + info->class_info.q_class = class; >> + desc = get_class_desc(class); >> + if (desc->desc) { >> + info->class_info.has_desc = true; >> + info->class_info.desc = g_strdup(desc->desc); >> + } >> + >> + info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID); >> + info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID); >> + info->regions = qmp_query_pci_regions(dev); >> + info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : ""); >> + >> + if (dev->config[PCI_INTERRUPT_PIN] != 0) { >> + info->has_irq = true; >> + info->irq = dev->config[PCI_INTERRUPT_LINE]; >> + } >> + >> + type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION; >> + if (type == PCI_HEADER_TYPE_BRIDGE) { >> + info->has_pci_bridge = true; >> + info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num); >> + } >> + >> + return info; >> +} >> + >> +PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num) >> +{ >> + PciDeviceInfoList *info, *head = NULL, *cur_item = NULL; >> + PCIDevice *dev; >> + int devfn; >> + >> + for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { >> + dev = bus->devices[devfn]; >> + if (dev) { >> + info = g_malloc0(sizeof(*info)); >> + info->value = qmp_query_pci_device(dev, bus, bus_num); >> + >> + /* XXX: waiting for the qapi to support GSList */ >> + if (!cur_item) { >> + head = cur_item = info; >> + } else { >> + cur_item->next = info; >> + cur_item = info; >> + } >> + } >> + } >> + >> + return head; >> +} >> + >> + >> +static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent) >> +{ >> + PCIDevice *d = (PCIDevice *)dev; >> + const pci_class_desc *desc; >> + char ctxt[64]; >> + PCIIORegion *r; >> + int i, class; >> + >> + class = pci_get_word(d->config + PCI_CLASS_DEVICE); >> + desc = pci_class_descriptions; >> + while (desc->desc && class != desc->class) { >> + desc++; >> + } >> + if (desc->desc) { >> + snprintf(ctxt, sizeof(ctxt), "%s", desc->desc); >> + } else { >> + snprintf(ctxt, sizeof(ctxt), "Class %04x", class); >> + } >> + >> + monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, " >> + "pci id %04x:%04x (sub %04x:%04x)\n", >> + indent, "", ctxt, pci_bus_num(d->bus), >> + PCI_SLOT(d->devfn), PCI_FUNC(d->devfn), >> + pci_get_word(d->config + PCI_VENDOR_ID), >> + pci_get_word(d->config + PCI_DEVICE_ID), >> + pci_get_word(d->config + PCI_SUBSYSTEM_VENDOR_ID), >> + pci_get_word(d->config + PCI_SUBSYSTEM_ID)); >> + for (i = 0; i < PCI_NUM_REGIONS; i++) { >> + r = &d->io_regions[i]; >> + if (!r->size) { >> + continue; >> + } >> + monitor_printf(mon, "%*sbar %d: %s at 0x%"FMT_PCIBUS >> + " [0x%"FMT_PCIBUS"]\n", >> + indent, "", >> + i, r->type & PCI_BASE_ADDRESS_SPACE_IO ? "i/o" : "mem", >> + r->addr, r->addr + r->size - 1); >> + } >> +} >> + >> +static char *pcibus_get_dev_path(DeviceState *dev) >> +{ >> + PCIDevice *d = container_of(dev, PCIDevice, qdev); >> + PCIDevice *t; >> + int slot_depth; >> + /* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function. >> + * 00 is added here to make this format compatible with >> + * domain:Bus:Slot.Func for systems without nested PCI bridges. >> + * Slot.Function list specifies the slot and function numbers for all >> + * devices on the path from root to the specific device. */ >> + const char *root_bus_path; >> + int root_bus_len; >> + char slot[] = ":SS.F"; >> + int slot_len = sizeof slot - 1 /* For '\0' */; >> + int path_len; >> + char *path, *p; >> + int s; >> + >> + root_bus_path = pci_root_bus_path(d); >> + root_bus_len = strlen(root_bus_path); >> + >> + /* Calculate # of slots on path between device and root. */; >> + slot_depth = 0; >> + for (t = d; t; t = t->bus->parent_dev) { >> + ++slot_depth; >> + } >> + >> + path_len = root_bus_len + slot_len * slot_depth; >> + >> + /* Allocate memory, fill in the terminating null byte. */ >> + path = g_malloc(path_len + 1 /* For '\0' */); >> + path[path_len] = '\0'; >> + >> + memcpy(path, root_bus_path, root_bus_len); >> + >> + /* Fill in slot numbers. We walk up from device to root, so need to print >> + * them in the reverse order, last to first. */ >> + p = path + path_len; >> + for (t = d; t; t = t->bus->parent_dev) { >> + p -= slot_len; >> + s = snprintf(slot, sizeof slot, ":%02x.%x", >> + PCI_SLOT(t->devfn), PCI_FUNC(t->devfn)); >> + assert(s == slot_len); >> + memcpy(p, slot, slot_len); >> + } >> + >> + return path; >> +} >> + >> +static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len) >> +{ >> + PCIDevice *d = (PCIDevice *)dev; >> + const char *name = NULL; >> + const pci_class_desc *desc = pci_class_descriptions; >> + int class = pci_get_word(d->config + PCI_CLASS_DEVICE); >> + >> + while (desc->desc && >> + (class & ~desc->fw_ign_bits) != >> + (desc->class & ~desc->fw_ign_bits)) { >> + desc++; >> + } >> + >> + if (desc->desc) { >> + name = desc->fw_name; >> + } >> + >> + if (name) { >> + pstrcpy(buf, len, name); >> + } else { >> + snprintf(buf, len, "pci%04x,%04x", >> + pci_get_word(d->config + PCI_VENDOR_ID), >> + pci_get_word(d->config + PCI_DEVICE_ID)); >> + } >> + >> + return buf; >> +} >> + >> +static char *pcibus_get_fw_dev_path(DeviceState *dev) >> +{ >> + PCIDevice *d = (PCIDevice *)dev; >> + char path[50], name[33]; >> + int off; >> + >> + off = snprintf(path, sizeof(path), "%s@%x", >> + pci_dev_fw_name(dev, name, sizeof name), >> + PCI_SLOT(d->devfn)); >> + if (PCI_FUNC(d->devfn)) { >> + snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn)); >> + } >> + return g_strdup(path); >> +} >> + >> +static const VMStateDescription vmstate_pcibus = { >> + .name = "PCIBUS", >> + .version_id = 1, >> + .minimum_version_id = 1, >> + .fields = (VMStateField[]) { >> + VMSTATE_INT32_EQUAL(nirq, PCIBus), >> + VMSTATE_VARRAY_INT32(irq_count, PCIBus, >> + nirq, 0, vmstate_info_int32, >> + int32_t), >> + VMSTATE_END_OF_LIST() >> + } >> +}; >> + >> +static void pci_bus_realize(BusState *qbus, Error **errp) >> +{ >> + PCIBus *bus = PCI_BUS(qbus); >> + >> + vmstate_register(NULL, -1, &vmstate_pcibus, bus); >> +} >> + >> +static void pci_bus_unrealize(BusState *qbus, Error **errp) >> +{ >> + PCIBus *bus = PCI_BUS(qbus); >> + >> + vmstate_unregister(NULL, &vmstate_pcibus, bus); >> +} >> + >> +/* >> + * Trigger pci bus reset under a given bus. >> + * Called via qbus_reset_all on RST# assert, after the devices >> + * have been reset qdev_reset_all-ed already. >> + */ >> +static void pcibus_reset(BusState *qbus) >> +{ >> + PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus); >> + int i; >> + >> + for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { >> + if (bus->devices[i]) { >> + pci_do_device_reset(bus->devices[i]); >> + } >> + } >> + >> + for (i = 0; i < bus->nirq; i++) { >> + assert(bus->irq_count[i] == 0); >> + } >> +} >> + >> +static void pci_bus_class_init(ObjectClass *klass, void *data) >> +{ >> + BusClass *k = BUS_CLASS(klass); >> + >> + k->print_dev = pcibus_dev_print; >> + k->get_dev_path = pcibus_get_dev_path; >> + k->get_fw_dev_path = pcibus_get_fw_dev_path; >> + k->realize = pci_bus_realize; >> + k->unrealize = pci_bus_unrealize; >> + k->reset = pcibus_reset; >> +} >> + >> +static const TypeInfo pci_bus_info = { >> + .name = TYPE_PCI_BUS, >> + .parent = TYPE_BUS, >> + .instance_size = sizeof(PCIBus), >> + .class_init = pci_bus_class_init, >> +}; >> + >> +static void pci_bus_register_types(void) >> +{ >> + type_register_static(&pci_bus_info); >> +} >> + >> +type_init(pci_bus_register_types) >> diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c >> index 0bb3cdb..f5847bc 100644 >> --- a/hw/ppc/ppc4xx_pci.c >> +++ b/hw/ppc/ppc4xx_pci.c >> @@ -23,6 +23,7 @@ >> #include "hw/ppc/ppc.h" >> #include "hw/ppc/ppc4xx.h" >> #include "hw/pci/pci.h" >> +#include "hw/pci/pci_bus.h" >> #include "hw/pci/pci_host.h" >> #include "exec/address-spaces.h" >> >> diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c >> index d1d0847..8dd2ce3 100644 >> --- a/hw/sh4/r2d.c >> +++ b/hw/sh4/r2d.c >> @@ -30,6 +30,7 @@ >> #include "sysemu/sysemu.h" >> #include "hw/boards.h" >> #include "hw/pci/pci.h" >> +#include "hw/pci/pci_bus.h" >> #include "net/net.h" >> #include "sh7750_regs.h" >> #include "hw/ide.h" >> diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c >> index a2f6d9e..f02e998 100644 >> --- a/hw/sh4/sh_pci.c >> +++ b/hw/sh4/sh_pci.c >> @@ -24,6 +24,7 @@ >> #include "hw/sysbus.h" >> #include "hw/sh4/sh.h" >> #include "hw/pci/pci.h" >> +#include "hw/pci/pci_bus.h" >> #include "hw/pci/pci_host.h" >> #include "qemu/bswap.h" >> #include "exec/address-spaces.h" >> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h >> index be2d9b8..47077cd 100644 >> --- a/include/hw/pci/pci.h >> +++ b/include/hw/pci/pci.h >> @@ -337,8 +337,6 @@ typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); >> typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); >> typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin); >> >> -#define TYPE_PCI_BUS "PCI" >> -#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS) >> #define TYPE_PCIE_BUS "PCIE" >> >> bool pci_bus_is_express(PCIBus *bus); >> @@ -370,6 +368,7 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus); >> void pci_device_set_intx_routing_notifier(PCIDevice *dev, >> PCIINTxRoutingNotifier notifier); >> void pci_device_reset(PCIDevice *dev); >> +void pci_do_device_reset(PCIDevice *dev); > > I don't like it that there are two reset functions now. It always was like that. We need this because of the code movement. > >> >> PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, >> const char *default_model, >> diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h >> index fabaeee..ea427a3 100644 >> --- a/include/hw/pci/pci_bus.h >> +++ b/include/hw/pci/pci_bus.h >> @@ -1,6 +1,8 @@ >> #ifndef QEMU_PCI_BUS_H >> #define QEMU_PCI_BUS_H >> >> +#include "hw/pci/pci.h" >> + >> /* >> * PCI Bus and Bridge datastructures. >> * >> @@ -8,6 +10,12 @@ >> * use accessor functions in pci.h, pci_bridge.h >> */ >> >> +PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num); >> +PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num); >> + >> +#define TYPE_PCI_BUS "PCI" >> +#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS) >> + >> struct PCIBus { >> BusState qbus; >> PCIIOMMUFunc iommu_fn; > > > Can we drop this patch, do refactoring on top later? There are several patches on this series depending on this. Of course I can manually apply them, does it worth it? Thanks, Marcel > >> -- >> 2.1.0