// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/pci.c * * Extruded from code written by * Dave Rusling (david.rusling@reo.mts.dec.com) * David Mosberger (davidm@cs.arizona.edu)
*/
/* 2.3.x PCI/resources, 1999 Andrea Arcangeli <andrea@suse.de> */
/* * Some string constants used by the various core logics.
*/
constchar *const pci_io_names[] = { "PCI IO bus 0", "PCI IO bus 1", "PCI IO bus 2", "PCI IO bus 3", "PCI IO bus 4", "PCI IO bus 5", "PCI IO bus 6", "PCI IO bus 7"
};
constchar *const pci_mem_names[] = { "PCI mem bus 0", "PCI mem bus 1", "PCI mem bus 2", "PCI mem bus 3", "PCI mem bus 4", "PCI mem bus 5", "PCI mem bus 6", "PCI mem bus 7"
};
constchar pci_hae0_name[] = "HAE0";
/* * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource * assignments.
*/
/* The generic legacy mode IDE fixup in drivers/pci/probe.c doesn't work correctly with the Cypress IDE controller as
it has non-standard register layout. Fix that. */ if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
dev->resource[2].start = dev->resource[3].start = 0;
dev->resource[2].end = dev->resource[3].end = 0;
dev->resource[2].flags = dev->resource[3].flags = 0; if (PCI_FUNC(dev->devfn) == 2) {
dev->resource[0].start = 0x170;
dev->resource[0].end = 0x177;
dev->resource[1].start = 0x376;
dev->resource[1].end = 0x376;
}
}
/* The Cypress bridge responds on the PCI bus in the address range 0xffff0000-0xffffffff (conventional x86 BIOS ROM). There is no way to turn this off. The bridge also supports several extended BIOS ranges (disabled after power-up), and some consoles do turn them on. So if we use a large direct-map window, or a large SG
window, we must avoid the entire 0xfff00000-0xffffffff region. */ if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA) { if (__direct_map_base + __direct_map_size >= 0xfff00000UL)
__direct_map_size = 0xfff00000UL - __direct_map_base; else { struct pci_controller *hose = dev->sysdata; struct pci_iommu_arena *pci = hose->sg_pci; if (pci && pci->dma_base + pci->size >= 0xfff00000UL)
pci->size = 0xfff00000UL - pci->dma_base;
}
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, quirk_cypress);
/* Called for each device after PCI setup is done. */ staticvoid pcibios_fixup_final(struct pci_dev *dev)
{ unsignedintclass = dev->class >> 8;
/* Just declaring that the power-of-ten prefixes are actually the
power-of-two ones doesn't make it true :) */ #define KB 1024 #define MB (1024*KB) #define GB (1024*MB)
if (res->flags & IORESOURCE_IO) { /* Make sure we start at our min on all hoses */ if (start - hose->io_space->start < PCIBIOS_MIN_IO)
start = PCIBIOS_MIN_IO + hose->io_space->start;
/* * Put everything into 0x00-0xff region modulo 0x400
*/ if (start & 0x300)
start = (start + 0x3ff) & ~0x3ff;
} elseif (res->flags & IORESOURCE_MEM) { /* Make sure we start at our min on all hoses */ if (start - hose->mem_space->start < PCIBIOS_MIN_MEM)
start = PCIBIOS_MIN_MEM + hose->mem_space->start;
/* * The following holds at least for the Low Cost * Alpha implementation of the PCI interface: * * In sparse memory address space, the first * octant (16MB) of every 128MB segment is * aliased to the very first 16 MB of the * address space (i.e., it aliases the ISA * memory address space). Thus, we try to * avoid allocating PCI devices in that range. * Can be allocated in 2nd-7th octant only. * Devices that need more than 112MB of * address space must be accessed through * dense memory space only!
*/
/* * If we set up a device for bus mastering, we need to check the latency * timer as certain firmware forgets to set it properly, as seen * on SX164 and LX164 with SRM.
*/ void
pcibios_set_master(struct pci_dev *dev)
{
u8 lat;
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); if (lat >= 16) return;
printk("PCI: Setting latency timer of device %s to 64\n",
pci_name(dev));
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
}
/* from hose or from bus.devfn */ if (which & IOBASE_FROM_HOSE) { for(hose = hose_head; hose; hose = hose->next) if (hose->index == bus) break; if (!hose) return -ENODEV;
} else { /* Special hook for ISA access. */ if (bus == 0 && dfn == 0) {
hose = pci_isa_hose;
} else {
dev = pci_get_domain_bus_and_slot(0, bus, dfn); if (!dev) return -ENODEV;
hose = dev->sysdata;
pci_dev_put(dev);
}
}
switch (which & ~IOBASE_FROM_HOSE) { case IOBASE_HOSE: return hose->index; case IOBASE_SPARSE_MEM: return hose->sparse_mem_base; case IOBASE_DENSE_MEM: return hose->dense_mem_base; case IOBASE_SPARSE_IO: return hose->sparse_io_base; case IOBASE_DENSE_IO: return hose->dense_io_base; case IOBASE_ROOT_BUS: return hose->bus->number;
}
return -EOPNOTSUPP;
}
/* Destroy an __iomem token. Not copied from lib/iomap.c. */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.