Revision e00387d5 hw/pci/pci.c
b/hw/pci/pci.c | ||
---|---|---|
786 | 786 |
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev); |
787 | 787 |
PCIConfigReadFunc *config_read = pc->config_read; |
788 | 788 |
PCIConfigWriteFunc *config_write = pc->config_write; |
789 |
AddressSpace *dma_as; |
|
789 | 790 |
|
790 | 791 |
if (devfn < 0) { |
791 | 792 |
for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices); |
... | ... | |
801 | 802 |
PCI_SLOT(devfn), PCI_FUNC(devfn), name, bus->devices[devfn]->name); |
802 | 803 |
return NULL; |
803 | 804 |
} |
805 |
|
|
804 | 806 |
pci_dev->bus = bus; |
805 |
if (bus->dma_context_fn) {
|
|
806 |
pci_dev->dma = bus->dma_context_fn(bus, bus->dma_context_opaque, devfn);
|
|
807 |
if (bus->iommu_fn) {
|
|
808 |
dma_as = bus->iommu_fn(bus, bus->iommu_opaque, devfn);
|
|
807 | 809 |
} else { |
808 |
/* FIXME: Make dma_context_fn use MemoryRegions instead, so this path is |
|
809 |
* taken unconditionally */ |
|
810 | 810 |
/* FIXME: inherit memory region from bus creator */ |
811 |
memory_region_init_alias(&pci_dev->bus_master_enable_region, "bus master", |
|
812 |
get_system_memory(), 0, |
|
813 |
memory_region_size(get_system_memory())); |
|
814 |
memory_region_set_enabled(&pci_dev->bus_master_enable_region, false); |
|
815 |
address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region); |
|
816 |
pci_dev->dma = g_new(DMAContext, 1); |
|
817 |
dma_context_init(pci_dev->dma, &pci_dev->bus_master_as); |
|
811 |
dma_as = &address_space_memory; |
|
818 | 812 |
} |
819 | 813 |
|
814 |
memory_region_init_alias(&pci_dev->bus_master_enable_region, "bus master", |
|
815 |
dma_as->root, 0, memory_region_size(dma_as->root)); |
|
816 |
memory_region_set_enabled(&pci_dev->bus_master_enable_region, false); |
|
817 |
address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region); |
|
818 |
pci_dev->dma = g_new(DMAContext, 1); |
|
819 |
dma_context_init(pci_dev->dma, &pci_dev->bus_master_as); |
|
820 |
|
|
820 | 821 |
pci_dev->devfn = devfn; |
821 | 822 |
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); |
822 | 823 |
pci_dev->irq_state = 0; |
... | ... | |
870 | 871 |
pci_dev->bus->devices[pci_dev->devfn] = NULL; |
871 | 872 |
pci_config_free(pci_dev); |
872 | 873 |
|
873 |
if (!pci_dev->bus->dma_context_fn) { |
|
874 |
address_space_destroy(&pci_dev->bus_master_as); |
|
875 |
memory_region_destroy(&pci_dev->bus_master_enable_region); |
|
876 |
g_free(pci_dev->dma); |
|
877 |
pci_dev->dma = NULL; |
|
878 |
} |
|
874 |
address_space_destroy(&pci_dev->bus_master_as); |
|
875 |
memory_region_destroy(&pci_dev->bus_master_enable_region); |
|
876 |
g_free(pci_dev->dma); |
|
877 |
pci_dev->dma = NULL; |
|
879 | 878 |
} |
880 | 879 |
|
881 | 880 |
static void pci_unregister_io_regions(PCIDevice *pci_dev) |
... | ... | |
2232 | 2231 |
k->props = pci_props; |
2233 | 2232 |
} |
2234 | 2233 |
|
2235 |
void pci_setup_iommu(PCIBus *bus, PCIDMAContextFunc fn, void *opaque)
|
|
2234 |
void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque)
|
|
2236 | 2235 |
{ |
2237 |
bus->dma_context_fn = fn;
|
|
2238 |
bus->dma_context_opaque = opaque;
|
|
2236 |
bus->iommu_fn = fn;
|
|
2237 |
bus->iommu_opaque = opaque;
|
|
2239 | 2238 |
} |
2240 | 2239 |
|
2241 | 2240 |
static const TypeInfo pci_device_type_info = { |
Also available in: Unified diff