Path: blob/master/arch/powerpc/platforms/iseries/pci.c
10820 views
/*1* Copyright (C) 2001 Allan Trautman, IBM Corporation2* Copyright (C) 2005,2007 Stephen Rothwell, IBM Corp3*4* iSeries specific routines for PCI.5*6* Based on code from pci.c and iSeries_pci.c 32bit7*8* This program is free software; you can redistribute it and/or modify9* it under the terms of the GNU General Public License as published by10* the Free Software Foundation; either version 2 of the License, or11* (at your option) any later version.12*13* This program is distributed in the hope that it will be useful,14* but WITHOUT ANY WARRANTY; without even the implied warranty of15* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16* GNU General Public License for more details.17*18* You should have received a copy of the GNU General Public License19* along with this program; if not, write to the Free Software20* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA21*/2223#undef DEBUG2425#include <linux/jiffies.h>26#include <linux/kernel.h>27#include <linux/list.h>28#include <linux/string.h>29#include <linux/slab.h>30#include <linux/init.h>31#include <linux/module.h>32#include <linux/pci.h>33#include <linux/of.h>34#include <linux/ratelimit.h>3536#include <asm/types.h>37#include <asm/io.h>38#include <asm/irq.h>39#include <asm/prom.h>40#include <asm/machdep.h>41#include <asm/pci-bridge.h>42#include <asm/iommu.h>43#include <asm/abs_addr.h>44#include <asm/firmware.h>4546#include <asm/iseries/hv_types.h>47#include <asm/iseries/hv_call_xm.h>48#include <asm/iseries/mf.h>49#include <asm/iseries/iommu.h>5051#include <asm/ppc-pci.h>5253#include "irq.h"54#include "pci.h"55#include "call_pci.h"5657#define PCI_RETRY_MAX 358static int limit_pci_retries = 1; /* Set Retry Error on. */5960/*61* Table defines62* Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space.63*/64#define IOMM_TABLE_MAX_ENTRIES 102465#define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL66#define BASE_IO_MEMORY 0xE000000000000000UL67#define END_IO_MEMORY 0xEFFFFFFFFFFFFFFFUL6869static unsigned long max_io_memory = BASE_IO_MEMORY;70static long current_iomm_table_entry;7172/*73* Lookup Tables.74*/75static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES];76static u64 ds_addr_table[IOMM_TABLE_MAX_ENTRIES];7778static DEFINE_SPINLOCK(iomm_table_lock);7980/*81* Generate a Direct Select Address for the Hypervisor82*/83static inline u64 iseries_ds_addr(struct device_node *node)84{85struct pci_dn *pdn = PCI_DN(node);86const u32 *sbp = of_get_property(node, "linux,subbus", NULL);8788return ((u64)pdn->busno << 48) + ((u64)(sbp ? *sbp : 0) << 40)89+ ((u64)0x10 << 32);90}9192/*93* Size of Bus VPD data94*/95#define BUS_VPDSIZE 10249697/*98* Bus Vpd Tags99*/100#define VPD_END_OF_AREA 0x79101#define VPD_ID_STRING 0x82102#define VPD_VENDOR_AREA 0x84103104/*105* Mfg Area Tags106*/107#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */108#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */109#define VPD_SLOT_MAP 0x534D /* "SM" */110111/*112* Structures of the areas113*/114struct mfg_vpd_area {115u16 tag;116u8 length;117u8 data1;118u8 data2;119};120#define MFG_ENTRY_SIZE 3121122struct slot_map {123u8 agent;124u8 secondary_agent;125u8 phb;126char card_location[3];127char parms[8];128char reserved[2];129};130#define SLOT_ENTRY_SIZE 16131132/*133* Parse the Slot Area134*/135static void __init iseries_parse_slot_area(struct slot_map *map, int len,136HvAgentId agent, u8 *phb, char card[4])137{138/*139* Parse Slot label until we find the one requested140*/141while (len > 0) {142if (map->agent == agent) {143/*144* If Phb wasn't found, grab the entry first one found.145*/146if (*phb == 0xff)147*phb = map->phb;148/* Found it, extract the data. */149if (map->phb == *phb) {150memcpy(card, &map->card_location, 3);151card[3] = 0;152break;153}154}155/* Point to the next Slot */156map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);157len -= SLOT_ENTRY_SIZE;158}159}160161/*162* Parse the Mfg Area163*/164static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,165HvAgentId agent, u8 *phb, u8 *frame, char card[4])166{167u16 slot_map_fmt = 0;168169/* Parse Mfg Data */170while (len > 0) {171int mfg_tag_len = area->length;172/* Frame ID (FI 4649020310 ) */173if (area->tag == VPD_FRU_FRAME_ID)174*frame = area->data1;175/* Slot Map Format (MF 4D46020004 ) */176else if (area->tag == VPD_SLOT_MAP_FORMAT)177slot_map_fmt = (area->data1 * 256)178+ area->data2;179/* Slot Map (SM 534D90 */180else if (area->tag == VPD_SLOT_MAP) {181struct slot_map *slot_map;182183if (slot_map_fmt == 0x1004)184slot_map = (struct slot_map *)((char *)area185+ MFG_ENTRY_SIZE + 1);186else187slot_map = (struct slot_map *)((char *)area188+ MFG_ENTRY_SIZE);189iseries_parse_slot_area(slot_map, mfg_tag_len,190agent, phb, card);191}192/*193* Point to the next Mfg Area194* Use defined size, sizeof give wrong answer195*/196area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len197+ MFG_ENTRY_SIZE);198len -= (mfg_tag_len + MFG_ENTRY_SIZE);199}200}201202/*203* Look for "BUS".. Data is not Null terminated.204* PHBID of 0xFF indicates PHB was not found in VPD Data.205*/206static u8 __init iseries_parse_phbid(u8 *area, int len)207{208while (len > 0) {209if ((*area == 'B') && (*(area + 1) == 'U')210&& (*(area + 2) == 'S')) {211area += 3;212while (*area == ' ')213area++;214return *area & 0x0F;215}216area++;217len--;218}219return 0xff;220}221222/*223* Parse out the VPD Areas224*/225static void __init iseries_parse_vpd(u8 *data, int data_len,226HvAgentId agent, u8 *frame, char card[4])227{228u8 phb = 0xff;229230while (data_len > 0) {231int len;232u8 tag = *data;233234if (tag == VPD_END_OF_AREA)235break;236len = *(data + 1) + (*(data + 2) * 256);237data += 3;238data_len -= 3;239if (tag == VPD_ID_STRING)240phb = iseries_parse_phbid(data, len);241else if (tag == VPD_VENDOR_AREA)242iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,243agent, &phb, frame, card);244/* Point to next Area. */245data += len;246data_len -= len;247}248}249250static int __init iseries_get_location_code(u16 bus, HvAgentId agent,251u8 *frame, char card[4])252{253int status = 0;254int bus_vpd_len = 0;255u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);256257if (bus_vpd == NULL) {258printk("PCI: Bus VPD Buffer allocation failure.\n");259return 0;260}261bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),262BUS_VPDSIZE);263if (bus_vpd_len == 0) {264printk("PCI: Bus VPD Buffer zero length.\n");265goto out_free;266}267/* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */268/* Make sure this is what I think it is */269if (*bus_vpd != VPD_ID_STRING) {270printk("PCI: Bus VPD Buffer missing starting tag.\n");271goto out_free;272}273iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);274status = 1;275out_free:276kfree(bus_vpd);277return status;278}279280/*281* Prints the device information.282* - Pass in pci_dev* pointer to the device.283* - Pass in the device count284*285* Format:286* PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet287* controller288*/289static void __init iseries_device_information(struct pci_dev *pdev,290u16 bus, HvSubBusNumber subbus)291{292u8 frame = 0;293char card[4];294HvAgentId agent;295296agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),297ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));298299if (iseries_get_location_code(bus, agent, &frame, card)) {300printk(KERN_INFO "PCI: %s, Vendor %04X Frame%3d, "301"Card %4s 0x%04X\n", pci_name(pdev), pdev->vendor,302frame, card, (int)(pdev->class >> 8));303}304}305306/*307* iomm_table_allocate_entry308*309* Adds pci_dev entry in address translation table310*311* - Allocates the number of entries required in table base on BAR312* size.313* - Allocates starting at BASE_IO_MEMORY and increases.314* - The size is round up to be a multiple of entry size.315* - CurrentIndex is incremented to keep track of the last entry.316* - Builds the resource entry for allocated BARs.317*/318static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)319{320struct resource *bar_res = &dev->resource[bar_num];321long bar_size = pci_resource_len(dev, bar_num);322struct device_node *dn = pci_device_to_OF_node(dev);323324/*325* No space to allocate, quick exit, skip Allocation.326*/327if (bar_size == 0)328return;329/*330* Set Resource values.331*/332spin_lock(&iomm_table_lock);333bar_res->start = BASE_IO_MEMORY +334IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;335bar_res->end = bar_res->start + bar_size - 1;336/*337* Allocate the number of table entries needed for BAR.338*/339while (bar_size > 0 ) {340iomm_table[current_iomm_table_entry] = dn;341ds_addr_table[current_iomm_table_entry] =342iseries_ds_addr(dn) | (bar_num << 24);343bar_size -= IOMM_TABLE_ENTRY_SIZE;344++current_iomm_table_entry;345}346max_io_memory = BASE_IO_MEMORY +347IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;348spin_unlock(&iomm_table_lock);349}350351/*352* allocate_device_bars353*354* - Allocates ALL pci_dev BAR's and updates the resources with the355* BAR value. BARS with zero length will have the resources356* The HvCallPci_getBarParms is used to get the size of the BAR357* space. It calls iomm_table_allocate_entry to allocate358* each entry.359* - Loops through The Bar resources(0 - 5) including the ROM360* is resource(6).361*/362static void __init allocate_device_bars(struct pci_dev *dev)363{364int bar_num;365366for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num)367iomm_table_allocate_entry(dev, bar_num);368}369370/*371* Log error information to system console.372* Filter out the device not there errors.373* PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx374* PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx375* PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx376*/377static void pci_log_error(char *error, int bus, int subbus,378int agent, int hv_res)379{380if (hv_res == 0x0302)381return;382printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",383error, bus, subbus, agent, hv_res);384}385386/*387* Look down the chain to find the matching Device Device388*/389static struct device_node *find_device_node(int bus, int devfn)390{391struct device_node *node;392393for (node = NULL; (node = of_find_all_nodes(node)); ) {394struct pci_dn *pdn = PCI_DN(node);395396if (pdn && (bus == pdn->busno) && (devfn == pdn->devfn))397return node;398}399return NULL;400}401402/*403* iSeries_pcibios_fixup_resources404*405* Fixes up all resources for devices406*/407void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)408{409const u32 *agent;410const u32 *sub_bus;411unsigned char bus = pdev->bus->number;412struct device_node *node;413int i;414415node = pci_device_to_OF_node(pdev);416pr_debug("PCI: iSeries %s, pdev %p, node %p\n",417pci_name(pdev), pdev, node);418if (!node) {419printk("PCI: %s disabled, device tree entry not found !\n",420pci_name(pdev));421for (i = 0; i <= PCI_ROM_RESOURCE; i++)422pdev->resource[i].flags = 0;423return;424}425sub_bus = of_get_property(node, "linux,subbus", NULL);426agent = of_get_property(node, "linux,agent-id", NULL);427if (agent && sub_bus) {428u8 irq = iSeries_allocate_IRQ(bus, 0, *sub_bus);429int err;430431err = HvCallXm_connectBusUnit(bus, *sub_bus, *agent, irq);432if (err)433pci_log_error("Connect Bus Unit",434bus, *sub_bus, *agent, err);435else {436err = HvCallPci_configStore8(bus, *sub_bus,437*agent, PCI_INTERRUPT_LINE, irq);438if (err)439pci_log_error("PciCfgStore Irq Failed!",440bus, *sub_bus, *agent, err);441else442pdev->irq = irq;443}444}445446allocate_device_bars(pdev);447if (likely(sub_bus))448iseries_device_information(pdev, bus, *sub_bus);449else450printk(KERN_ERR "PCI: Device node %s has missing or invalid "451"linux,subbus property\n", node->full_name);452}453454/*455* iSeries_pci_final_fixup(void)456*/457void __init iSeries_pci_final_fixup(void)458{459/* Fix up at the device node and pci_dev relationship */460mf_display_src(0xC9000100);461iSeries_activate_IRQs();462mf_display_src(0xC9000200);463}464465/*466* Config space read and write functions.467* For now at least, we look for the device node for the bus and devfn468* that we are asked to access. It may be possible to translate the devfn469* to a subbus and deviceid more directly.470*/471static u64 hv_cfg_read_func[4] = {472HvCallPciConfigLoad8, HvCallPciConfigLoad16,473HvCallPciConfigLoad32, HvCallPciConfigLoad32474};475476static u64 hv_cfg_write_func[4] = {477HvCallPciConfigStore8, HvCallPciConfigStore16,478HvCallPciConfigStore32, HvCallPciConfigStore32479};480481/*482* Read PCI config space483*/484static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,485int offset, int size, u32 *val)486{487struct device_node *node = find_device_node(bus->number, devfn);488u64 fn;489struct HvCallPci_LoadReturn ret;490491if (node == NULL)492return PCIBIOS_DEVICE_NOT_FOUND;493if (offset > 255) {494*val = ~0;495return PCIBIOS_BAD_REGISTER_NUMBER;496}497498fn = hv_cfg_read_func[(size - 1) & 3];499HvCall3Ret16(fn, &ret, iseries_ds_addr(node), offset, 0);500501if (ret.rc != 0) {502*val = ~0;503return PCIBIOS_DEVICE_NOT_FOUND; /* or something */504}505506*val = ret.value;507return 0;508}509510/*511* Write PCI config space512*/513514static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,515int offset, int size, u32 val)516{517struct device_node *node = find_device_node(bus->number, devfn);518u64 fn;519u64 ret;520521if (node == NULL)522return PCIBIOS_DEVICE_NOT_FOUND;523if (offset > 255)524return PCIBIOS_BAD_REGISTER_NUMBER;525526fn = hv_cfg_write_func[(size - 1) & 3];527ret = HvCall4(fn, iseries_ds_addr(node), offset, val, 0);528529if (ret != 0)530return PCIBIOS_DEVICE_NOT_FOUND;531532return 0;533}534535static struct pci_ops iSeries_pci_ops = {536.read = iSeries_pci_read_config,537.write = iSeries_pci_write_config538};539540/*541* Check Return Code542* -> On Failure, print and log information.543* Increment Retry Count, if exceeds max, panic partition.544*545* PCI: Device 23.90 ReadL I/O Error( 0): 0x1234546* PCI: Device 23.90 ReadL Retry( 1)547* PCI: Device 23.90 ReadL Retry Successful(1)548*/549static int check_return_code(char *type, struct device_node *dn,550int *retry, u64 ret)551{552if (ret != 0) {553struct pci_dn *pdn = PCI_DN(dn);554555(*retry)++;556printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",557type, pdn->busno, pdn->devfn,558*retry, (int)ret);559/*560* Bump the retry and check for retry count exceeded.561* If, Exceeded, panic the system.562*/563if (((*retry) > PCI_RETRY_MAX) &&564(limit_pci_retries > 0)) {565mf_display_src(0xB6000103);566panic_timeout = 0;567panic("PCI: Hardware I/O Error, SRC B6000103, "568"Automatic Reboot Disabled.\n");569}570return -1; /* Retry Try */571}572return 0;573}574575/*576* Translate the I/O Address into a device node, bar, and bar offset.577* Note: Make sure the passed variable end up on the stack to avoid578* the exposure of being device global.579*/580static inline struct device_node *xlate_iomm_address(581const volatile void __iomem *addr,582u64 *dsaptr, u64 *bar_offset, const char *func)583{584unsigned long orig_addr;585unsigned long base_addr;586unsigned long ind;587struct device_node *dn;588589orig_addr = (unsigned long __force)addr;590if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) {591static DEFINE_RATELIMIT_STATE(ratelimit, 60 * HZ, 10);592593if (__ratelimit(&ratelimit))594printk(KERN_ERR595"iSeries_%s: invalid access at IO address %p\n",596func, addr);597return NULL;598}599base_addr = orig_addr - BASE_IO_MEMORY;600ind = base_addr / IOMM_TABLE_ENTRY_SIZE;601dn = iomm_table[ind];602603if (dn != NULL) {604*dsaptr = ds_addr_table[ind];605*bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE;606} else607panic("PCI: Invalid PCI IO address detected!\n");608return dn;609}610611/*612* Read MM I/O Instructions for the iSeries613* On MM I/O error, all ones are returned and iSeries_pci_IoError is cal614* else, data is returned in Big Endian format.615*/616static u8 iseries_readb(const volatile void __iomem *addr)617{618u64 bar_offset;619u64 dsa;620int retry = 0;621struct HvCallPci_LoadReturn ret;622struct device_node *dn =623xlate_iomm_address(addr, &dsa, &bar_offset, "read_byte");624625if (dn == NULL)626return 0xff;627do {628HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0);629} while (check_return_code("RDB", dn, &retry, ret.rc) != 0);630631return ret.value;632}633634static u16 iseries_readw_be(const volatile void __iomem *addr)635{636u64 bar_offset;637u64 dsa;638int retry = 0;639struct HvCallPci_LoadReturn ret;640struct device_node *dn =641xlate_iomm_address(addr, &dsa, &bar_offset, "read_word");642643if (dn == NULL)644return 0xffff;645do {646HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,647bar_offset, 0);648} while (check_return_code("RDW", dn, &retry, ret.rc) != 0);649650return ret.value;651}652653static u32 iseries_readl_be(const volatile void __iomem *addr)654{655u64 bar_offset;656u64 dsa;657int retry = 0;658struct HvCallPci_LoadReturn ret;659struct device_node *dn =660xlate_iomm_address(addr, &dsa, &bar_offset, "read_long");661662if (dn == NULL)663return 0xffffffff;664do {665HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,666bar_offset, 0);667} while (check_return_code("RDL", dn, &retry, ret.rc) != 0);668669return ret.value;670}671672/*673* Write MM I/O Instructions for the iSeries674*675*/676static void iseries_writeb(u8 data, volatile void __iomem *addr)677{678u64 bar_offset;679u64 dsa;680int retry = 0;681u64 rc;682struct device_node *dn =683xlate_iomm_address(addr, &dsa, &bar_offset, "write_byte");684685if (dn == NULL)686return;687do {688rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0);689} while (check_return_code("WWB", dn, &retry, rc) != 0);690}691692static void iseries_writew_be(u16 data, volatile void __iomem *addr)693{694u64 bar_offset;695u64 dsa;696int retry = 0;697u64 rc;698struct device_node *dn =699xlate_iomm_address(addr, &dsa, &bar_offset, "write_word");700701if (dn == NULL)702return;703do {704rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0);705} while (check_return_code("WWW", dn, &retry, rc) != 0);706}707708static void iseries_writel_be(u32 data, volatile void __iomem *addr)709{710u64 bar_offset;711u64 dsa;712int retry = 0;713u64 rc;714struct device_node *dn =715xlate_iomm_address(addr, &dsa, &bar_offset, "write_long");716717if (dn == NULL)718return;719do {720rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0);721} while (check_return_code("WWL", dn, &retry, rc) != 0);722}723724static u16 iseries_readw(const volatile void __iomem *addr)725{726return le16_to_cpu(iseries_readw_be(addr));727}728729static u32 iseries_readl(const volatile void __iomem *addr)730{731return le32_to_cpu(iseries_readl_be(addr));732}733734static void iseries_writew(u16 data, volatile void __iomem *addr)735{736iseries_writew_be(cpu_to_le16(data), addr);737}738739static void iseries_writel(u32 data, volatile void __iomem *addr)740{741iseries_writel(cpu_to_le32(data), addr);742}743744static void iseries_readsb(const volatile void __iomem *addr, void *buf,745unsigned long count)746{747u8 *dst = buf;748while(count-- > 0)749*(dst++) = iseries_readb(addr);750}751752static void iseries_readsw(const volatile void __iomem *addr, void *buf,753unsigned long count)754{755u16 *dst = buf;756while(count-- > 0)757*(dst++) = iseries_readw_be(addr);758}759760static void iseries_readsl(const volatile void __iomem *addr, void *buf,761unsigned long count)762{763u32 *dst = buf;764while(count-- > 0)765*(dst++) = iseries_readl_be(addr);766}767768static void iseries_writesb(volatile void __iomem *addr, const void *buf,769unsigned long count)770{771const u8 *src = buf;772while(count-- > 0)773iseries_writeb(*(src++), addr);774}775776static void iseries_writesw(volatile void __iomem *addr, const void *buf,777unsigned long count)778{779const u16 *src = buf;780while(count-- > 0)781iseries_writew_be(*(src++), addr);782}783784static void iseries_writesl(volatile void __iomem *addr, const void *buf,785unsigned long count)786{787const u32 *src = buf;788while(count-- > 0)789iseries_writel_be(*(src++), addr);790}791792static void iseries_memset_io(volatile void __iomem *addr, int c,793unsigned long n)794{795volatile char __iomem *d = addr;796797while (n-- > 0)798iseries_writeb(c, d++);799}800801static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,802unsigned long n)803{804char *d = dest;805const volatile char __iomem *s = src;806807while (n-- > 0)808*d++ = iseries_readb(s++);809}810811static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,812unsigned long n)813{814const char *s = src;815volatile char __iomem *d = dest;816817while (n-- > 0)818iseries_writeb(*s++, d++);819}820821/* We only set MMIO ops. The default PIO ops will be default822* to the MMIO ops + pci_io_base which is 0 on iSeries as823* expected so both should work.824*825* Note that we don't implement the readq/writeq versions as826* I don't know of an HV call for doing so. Thus, the default827* operation will be used instead, which will fault a the value828* return by iSeries for MMIO addresses always hits a non mapped829* area. This is as good as the BUG() we used to have there.830*/831static struct ppc_pci_io __initdata iseries_pci_io = {832.readb = iseries_readb,833.readw = iseries_readw,834.readl = iseries_readl,835.readw_be = iseries_readw_be,836.readl_be = iseries_readl_be,837.writeb = iseries_writeb,838.writew = iseries_writew,839.writel = iseries_writel,840.writew_be = iseries_writew_be,841.writel_be = iseries_writel_be,842.readsb = iseries_readsb,843.readsw = iseries_readsw,844.readsl = iseries_readsl,845.writesb = iseries_writesb,846.writesw = iseries_writesw,847.writesl = iseries_writesl,848.memset_io = iseries_memset_io,849.memcpy_fromio = iseries_memcpy_fromio,850.memcpy_toio = iseries_memcpy_toio,851};852853/*854* iSeries_pcibios_init855*856* Description:857* This function checks for all possible system PCI host bridges that connect858* PCI buses. The system hypervisor is queried as to the guest partition859* ownership status. A pci_controller is built for any bus which is partially860* owned or fully owned by this guest partition.861*/862void __init iSeries_pcibios_init(void)863{864struct pci_controller *phb;865struct device_node *root = of_find_node_by_path("/");866struct device_node *node = NULL;867868/* Install IO hooks */869ppc_pci_io = iseries_pci_io;870871pci_probe_only = 1;872873/* iSeries has no IO space in the common sense, it needs to set874* the IO base to 0875*/876pci_io_base = 0;877878if (root == NULL) {879printk(KERN_CRIT "iSeries_pcibios_init: can't find root "880"of device tree\n");881return;882}883while ((node = of_get_next_child(root, node)) != NULL) {884HvBusNumber bus;885const u32 *busp;886887if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))888continue;889890busp = of_get_property(node, "bus-range", NULL);891if (busp == NULL)892continue;893bus = *busp;894printk("bus %d appears to exist\n", bus);895phb = pcibios_alloc_controller(node);896if (phb == NULL)897continue;898/* All legacy iSeries PHBs are in domain zero */899phb->global_number = 0;900901phb->first_busno = bus;902phb->last_busno = bus;903phb->ops = &iSeries_pci_ops;904phb->io_base_virt = (void __iomem *)_IO_BASE;905phb->io_resource.flags = IORESOURCE_IO;906phb->io_resource.start = BASE_IO_MEMORY;907phb->io_resource.end = END_IO_MEMORY;908phb->io_resource.name = "iSeries PCI IO";909phb->mem_resources[0].flags = IORESOURCE_MEM;910phb->mem_resources[0].start = BASE_IO_MEMORY;911phb->mem_resources[0].end = END_IO_MEMORY;912phb->mem_resources[0].name = "Series PCI MEM";913}914915of_node_put(root);916917pci_devs_phb_init();918}919920921922