X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fdevices%2Fpci_ops.c;h=07da30034ffffeeef29dcadc5797b9cefa30c5be;hb=35e912cef3aac245202694736281aa8475e977f1;hp=a8f09e229d0619004f75ce23bf1a045e7667e2f4;hpb=2b34db8d1de2d63ffa829fe03db0ce2aaba40233;p=coreboot.git diff --git a/src/devices/pci_ops.c b/src/devices/pci_ops.c index a8f09e229..07da30034 100644 --- a/src/devices/pci_ops.c +++ b/src/devices/pci_ops.c @@ -3,6 +3,7 @@ * * Copyright (C) 2004 Linux Networx * (Written by Eric Biederman for Linux Networx) + * Copyright (C) 2009 coresystems GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,52 +25,125 @@ #include #include +/* + * The only consumer of the return value of get_pbus() is ops_pci_bus(). + * ops_pci_bus() can handle being passed NULL and auto-picks working ops. + */ static struct bus *get_pbus(device_t dev) { - struct bus *pbus = dev->bus; - while(pbus && pbus->dev && !ops_pci_bus(pbus)) { + struct bus *pbus = NULL; + + if (!dev) + die("get_pbus: dev is NULL!\n"); + else + pbus = dev->bus; + + while (pbus && pbus->dev && !ops_pci_bus(pbus)) { + if (pbus == pbus->dev->bus) { + printk(BIOS_ALERT, "%s in endless loop looking for a " + "parent bus with ops_pci_bus for %s, breaking " + "out.\n", __func__, dev_path(dev)); + break; + } pbus = pbus->dev->bus; } - if (!pbus || !pbus->dev || !pbus->dev->ops || !pbus->dev->ops->ops_pci_bus) { - printk_alert("%s Cannot find pci bus operations", dev_path(dev)); - die(""); - for(;;); + + if (!pbus || !pbus->dev || !pbus->dev->ops + || !pbus->dev->ops->ops_pci_bus) { + /* This can happen before the device tree is fully set up. */ + + // printk(BIOS_EMERG, "%s: Cannot find PCI bus operations.\n", + // dev_path(dev)); + + pbus = NULL; } + return pbus; } -uint8_t pci_read_config8(device_t dev, unsigned where) +u8 pci_read_config8(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return ops_pci_bus(pbus)->read8(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return ops_pci_bus(pbus)->read8(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -uint16_t pci_read_config16(device_t dev, unsigned where) +u16 pci_read_config16(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return ops_pci_bus(pbus)->read16(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return ops_pci_bus(pbus)->read16(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -uint32_t pci_read_config32(device_t dev, unsigned where) +u32 pci_read_config32(device_t dev, unsigned int where) { struct bus *pbus = get_pbus(dev); - return ops_pci_bus(pbus)->read32(pbus, dev->bus->secondary, dev->path.pci.devfn, where); + return ops_pci_bus(pbus)->read32(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); } -void pci_write_config8(device_t dev, unsigned where, uint8_t val) +void pci_write_config8(device_t dev, unsigned int where, u8 val) { struct bus *pbus = get_pbus(dev); - ops_pci_bus(pbus)->write8(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + ops_pci_bus(pbus)->write8(pbus, dev->bus->secondary, + dev->path.pci.devfn, where, val); } -void pci_write_config16(device_t dev, unsigned where, uint16_t val) +void pci_write_config16(device_t dev, unsigned int where, u16 val) { struct bus *pbus = get_pbus(dev); - ops_pci_bus(pbus)->write16(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + ops_pci_bus(pbus)->write16(pbus, dev->bus->secondary, + dev->path.pci.devfn, where, val); } -void pci_write_config32(device_t dev, unsigned where, uint32_t val) +void pci_write_config32(device_t dev, unsigned int where, u32 val) { struct bus *pbus = get_pbus(dev); - ops_pci_bus(pbus)->write32(pbus, dev->bus->secondary, dev->path.pci.devfn, where, val); + ops_pci_bus(pbus)->write32(pbus, dev->bus->secondary, + dev->path.pci.devfn, where, val); } + +#if CONFIG_MMCONF_SUPPORT +u8 pci_mmio_read_config8(device_t dev, unsigned int where) +{ + struct bus *pbus = get_pbus(dev); + return pci_ops_mmconf.read8(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); +} + +u16 pci_mmio_read_config16(device_t dev, unsigned int where) +{ + struct bus *pbus = get_pbus(dev); + return pci_ops_mmconf.read16(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); +} + +u32 pci_mmio_read_config32(device_t dev, unsigned int where) +{ + struct bus *pbus = get_pbus(dev); + return pci_ops_mmconf.read32(pbus, dev->bus->secondary, + dev->path.pci.devfn, where); +} + +void pci_mmio_write_config8(device_t dev, unsigned int where, u8 val) +{ + struct bus *pbus = get_pbus(dev); + pci_ops_mmconf.write8(pbus, dev->bus->secondary, dev->path.pci.devfn, + where, val); +} + +void pci_mmio_write_config16(device_t dev, unsigned int where, u16 val) +{ + struct bus *pbus = get_pbus(dev); + pci_ops_mmconf.write16(pbus, dev->bus->secondary, dev->path.pci.devfn, + where, val); +} + +void pci_mmio_write_config32(device_t dev, unsigned int where, u32 val) +{ + struct bus *pbus = get_pbus(dev); + pci_ops_mmconf.write32(pbus, dev->bus->secondary, dev->path.pci.devfn, + where, val); +} + +#endif