}
}
+void pci_device_deassert_intx(PCIDevice *dev)
+{
+ int i;
+ for (i = 0; i < PCI_NUM_PINS; ++i) {
+ qemu_set_irq(dev->irq[i], 0);
+ }
+}
+
/*
* This function is called on #RST and FLR.
* FLR if PCI_EXP_DEVCTL_BCR_FLR is set
dev->irq_state = 0;
pci_update_irq_status(dev);
+ pci_device_deassert_intx(dev);
/* Clear all writeable bits */
pci_word_test_and_clear_mask(dev->config + PCI_COMMAND,
pci_get_word(dev->wmask + PCI_COMMAND) |
}
void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
- const char *name, int devfn_min)
+ const char *name, uint8_t devfn_min)
{
qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
assert(PCI_FUNC(devfn_min) == 0);
vmstate_register(NULL, -1, &vmstate_pcibus, bus);
}
-PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
+PCIBus *pci_bus_new(DeviceState *parent, const char *name, uint8_t devfn_min)
{
PCIBus *bus;
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *irq_opaque, int devfn_min, int nirq)
+ void *irq_opaque, uint8_t devfn_min, int nirq)
{
PCIBus *bus;
return NULL;
}
- *devfnp = slot << 3;
+ *devfnp = PCI_DEVFN(slot, 0);
return pci_find_bus(pci_find_root_bus(dom), bus);
}
PCI_BRIDGE_CTL_FAST_BACK |
PCI_BRIDGE_CTL_DISCARD |
PCI_BRIDGE_CTL_SEC_DISCARD |
- PCI_BRIDGE_CTL_DISCARD_STATUS |
PCI_BRIDGE_CTL_DISCARD_SERR);
/* Below does not do anything as we never set this bit, put here for
* completeness. */
pci_unregister_io_regions(pci_dev);
pci_del_option_rom(pci_dev);
+ qemu_free(pci_dev->romfile);
do_pci_unregister_device(pci_dev);
return 0;
}
return NULL;
}
-PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function)
+PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
{
bus = pci_find_bus(bus, bus_num);
if (!bus)
return NULL;
- return bus->devices[PCI_DEVFN(slot, function)];
+ return bus->devices[devfn];
}
static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
return DO_UPCAST(PCIDevice, qdev, dev);
}
+PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn,
+ bool multifunction,
+ const char *name)
+{
+ DeviceState *dev;
+
+ dev = qdev_try_create(&bus->qbus, name);
+ if (!dev) {
+ return NULL;
+ }
+ qdev_prop_set_uint32(dev, "addr", devfn);
+ qdev_prop_set_bit(dev, "multifunction", multifunction);
+ return DO_UPCAST(PCIDevice, qdev, dev);
+}
+
PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
bool multifunction,
const char *name)
return pci_create_simple_multifunction(bus, devfn, false, name);
}
+PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name)
+{
+ return pci_try_create_multifunction(bus, devfn, false, name);
+}
+
static int pci_find_space(PCIDevice *pdev, uint8_t size)
{
int config_size = pci_config_size(pdev);
if (size < 0) {
error_report("%s: failed to find romfile \"%s\"",
__FUNCTION__, pdev->romfile);
+ qemu_free(path);
return -1;
}
if (size & (size - 1)) {
* 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. */
- int domain_len = strlen("DDDD:00");
- int slot_len = strlen(":SS.F");
+ char domain[] = "DDDD:00";
+ char slot[] = ":SS.F";
+ int domain_len = sizeof domain - 1 /* For '\0' */;
+ int slot_len = sizeof slot - 1 /* For '\0' */;
int path_len;
char *path, *p;
+ int s;
/* Calculate # of slots on path between device and root. */;
slot_depth = 0;
path_len = domain_len + slot_len * slot_depth;
/* Allocate memory, fill in the terminating null byte. */
- path = malloc(path_len + 1 /* For '\0' */);
+ path = qemu_malloc(path_len + 1 /* For '\0' */);
path[path_len] = '\0';
/* First field is the domain. */
- snprintf(path, domain_len, "%04x:00", pci_find_domain(d->bus));
+ s = snprintf(domain, sizeof domain, "%04x:00", pci_find_domain(d->bus));
+ assert(s == domain_len);
+ memcpy(path, domain, domain_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;
- snprintf(p, slot_len, ":%02x.%x", PCI_SLOT(t->devfn), PCI_FUNC(d->devfn));
+ 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;