lkml.org 
[lkml]   [2012]   [Mar]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    SubjectRe: [git pull] PCI changes (including maintainer change)
    From
    On Thu, Mar 22, 2012 at 2:48 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
    > The following changes since commit
    > 4f262acfde22b63498b5e4f165e53d3bb4e96400:
    >
    >  Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm (2012-03-07 08:33:03 -0800)
    >
    > are available in the git repository at:
    >
    >  git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci linux-next
    >
    > This pull has some good cleanups from Bjorn and Yinghai, as well as
    > some more code from Yinghai to better handle resource re-allocation
    > when enabled.
    >
    > There's also a new initcall_debug feature from Arjan which will print
    > out quirk timing information to help identify slow quirks for fixing or
    > refinement (Yinghai sent in a few patches to do just that once the new
    > debug code landed).
    >
    > Beyond that, I'm handing off PCI maintainership to Bjorn Helgaas.  He's
    > been a core PCI and Linux contributor for some time now, and has kindly
    > volunteered to take over.  I just don't feel I have the time for PCI
    > review and work that it deserves lately (I've taken on some other
    > projects), and haven't been as responsive lately as I'd like, so I
    > approached Bjorn asking if he'd like to manage things.  He's going to
    > give it a try, and I'm confident he'll do at least as well as I have in
    > keeping the tree managed, patches flowing, and keeping things stable.
    >

    There are some merge conflicts. Hope attached patch could help Linus a
    little bit.

    Yinghai
    ---
    arch/mips/pci/pci.c | 6
    arch/powerpc/include/asm/ppc-pci.h | 3
    arch/powerpc/platforms/iseries/pci.c | 919 -----------------------------------
    include/linux/pci.h | 4
    4 files changed, 932 deletions(-)

    Index: linux-2.6/arch/mips/pci/pci.c
    ===================================================================
    --- linux-2.6.orig/arch/mips/pci/pci.c
    +++ linux-2.6/arch/mips/pci/pci.c
    @@ -250,25 +250,19 @@ int pcibios_enable_device(struct pci_dev

    void __devinit pcibios_fixup_bus(struct pci_bus *bus)
    {
    -<<<<<<< HEAD
    /* Propagate hose info into the subordinate devices. */

    -=======
    ->>>>>>> pci/linux-next
    struct pci_dev *dev = bus->self;

    if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
    pci_read_bridge_bases(bus);
    -<<<<<<< HEAD
    pcibios_fixup_device_resources(dev, bus);
    }

    list_for_each_entry(dev, &bus->devices, bus_list) {
    if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
    pcibios_fixup_device_resources(dev, bus);
    -=======
    ->>>>>>> pci/linux-next
    }
    }

    Index: linux-2.6/arch/powerpc/include/asm/ppc-pci.h
    ===================================================================
    --- linux-2.6.orig/arch/powerpc/include/asm/ppc-pci.h
    +++ linux-2.6/arch/powerpc/include/asm/ppc-pci.h
    @@ -45,12 +45,9 @@ extern void init_pci_config_tokens (void
    extern unsigned long get_phb_buid (struct device_node *);
    extern int rtas_setup_phb(struct pci_controller *phb);

    -<<<<<<< HEAD
    extern unsigned long pci_probe_only;

    -=======
    /* ---- EEH internal-use-only related routines ---- */
    ->>>>>>> pci/linux-next
    #ifdef CONFIG_EEH

    void pci_addr_cache_build(void);
    Index: linux-2.6/arch/powerpc/platforms/iseries/pci.c
    ===================================================================
    --- linux-2.6.orig/arch/powerpc/platforms/iseries/pci.c
    +++ /dev/null
    @@ -1,919 +0,0 @@
    -/*
    - * Copyright (C) 2001 Allan Trautman, IBM Corporation
    - * Copyright (C) 2005,2007 Stephen Rothwell, IBM Corp
    - *
    - * iSeries specific routines for PCI.
    - *
    - * Based on code from pci.c and iSeries_pci.c 32bit
    - *
    - * 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
    - * the Free Software Foundation; either version 2 of the License, or
    - * (at your option) any later version.
    - *
    - * This program is distributed in the hope that it will be useful,
    - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    - * GNU General Public License for more details.
    - *
    - * You should have received a copy of the GNU General Public License
    - * along with this program; if not, write to the Free Software
    - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    - */
    -
    -#undef DEBUG
    -
    -#include <linux/jiffies.h>
    -#include <linux/kernel.h>
    -#include <linux/list.h>
    -#include <linux/string.h>
    -#include <linux/slab.h>
    -#include <linux/init.h>
    -#include <linux/pci.h>
    -#include <linux/of.h>
    -#include <linux/ratelimit.h>
    -
    -#include <asm/types.h>
    -#include <asm/io.h>
    -#include <asm/irq.h>
    -#include <asm/prom.h>
    -#include <asm/machdep.h>
    -#include <asm/pci-bridge.h>
    -#include <asm/iommu.h>
    -#include <asm/abs_addr.h>
    -#include <asm/firmware.h>
    -
    -#include <asm/iseries/hv_types.h>
    -#include <asm/iseries/hv_call_xm.h>
    -#include <asm/iseries/mf.h>
    -#include <asm/iseries/iommu.h>
    -
    -#include <asm/ppc-pci.h>
    -
    -#include "irq.h"
    -#include "pci.h"
    -#include "call_pci.h"
    -
    -#define PCI_RETRY_MAX 3
    -static int limit_pci_retries = 1; /* Set Retry Error on. */
    -
    -/*
    - * Table defines
    - * Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space.
    - */
    -#define IOMM_TABLE_MAX_ENTRIES 1024
    -#define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL
    -#define BASE_IO_MEMORY 0xE000000000000000UL
    -#define END_IO_MEMORY 0xEFFFFFFFFFFFFFFFUL
    -
    -static unsigned long max_io_memory = BASE_IO_MEMORY;
    -static long current_iomm_table_entry;
    -
    -/*
    - * Lookup Tables.
    - */
    -static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES];
    -static u64 ds_addr_table[IOMM_TABLE_MAX_ENTRIES];
    -
    -static DEFINE_SPINLOCK(iomm_table_lock);
    -
    -/*
    - * Generate a Direct Select Address for the Hypervisor
    - */
    -static inline u64 iseries_ds_addr(struct device_node *node)
    -{
    - struct pci_dn *pdn = PCI_DN(node);
    - const u32 *sbp = of_get_property(node, "linux,subbus", NULL);
    -
    - return ((u64)pdn->busno << 48) + ((u64)(sbp ? *sbp : 0) << 40)
    - + ((u64)0x10 << 32);
    -}
    -
    -/*
    - * Size of Bus VPD data
    - */
    -#define BUS_VPDSIZE 1024
    -
    -/*
    - * Bus Vpd Tags
    - */
    -#define VPD_END_OF_AREA 0x79
    -#define VPD_ID_STRING 0x82
    -#define VPD_VENDOR_AREA 0x84
    -
    -/*
    - * Mfg Area Tags
    - */
    -#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */
    -#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */
    -#define VPD_SLOT_MAP 0x534D /* "SM" */
    -
    -/*
    - * Structures of the areas
    - */
    -struct mfg_vpd_area {
    - u16 tag;
    - u8 length;
    - u8 data1;
    - u8 data2;
    -};
    -#define MFG_ENTRY_SIZE 3
    -
    -struct slot_map {
    - u8 agent;
    - u8 secondary_agent;
    - u8 phb;
    - char card_location[3];
    - char parms[8];
    - char reserved[2];
    -};
    -#define SLOT_ENTRY_SIZE 16
    -
    -/*
    - * Parse the Slot Area
    - */
    -static void __init iseries_parse_slot_area(struct slot_map *map, int len,
    - HvAgentId agent, u8 *phb, char card[4])
    -{
    - /*
    - * Parse Slot label until we find the one requested
    - */
    - while (len > 0) {
    - if (map->agent == agent) {
    - /*
    - * If Phb wasn't found, grab the entry first one found.
    - */
    - if (*phb == 0xff)
    - *phb = map->phb;
    - /* Found it, extract the data. */
    - if (map->phb == *phb) {
    - memcpy(card, &map->card_location, 3);
    - card[3] = 0;
    - break;
    - }
    - }
    - /* Point to the next Slot */
    - map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);
    - len -= SLOT_ENTRY_SIZE;
    - }
    -}
    -
    -/*
    - * Parse the Mfg Area
    - */
    -static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,
    - HvAgentId agent, u8 *phb, u8 *frame, char card[4])
    -{
    - u16 slot_map_fmt = 0;
    -
    - /* Parse Mfg Data */
    - while (len > 0) {
    - int mfg_tag_len = area->length;
    - /* Frame ID (FI 4649020310 ) */
    - if (area->tag == VPD_FRU_FRAME_ID)
    - *frame = area->data1;
    - /* Slot Map Format (MF 4D46020004 ) */
    - else if (area->tag == VPD_SLOT_MAP_FORMAT)
    - slot_map_fmt = (area->data1 * 256)
    - + area->data2;
    - /* Slot Map (SM 534D90 */
    - else if (area->tag == VPD_SLOT_MAP) {
    - struct slot_map *slot_map;
    -
    - if (slot_map_fmt == 0x1004)
    - slot_map = (struct slot_map *)((char *)area
    - + MFG_ENTRY_SIZE + 1);
    - else
    - slot_map = (struct slot_map *)((char *)area
    - + MFG_ENTRY_SIZE);
    - iseries_parse_slot_area(slot_map, mfg_tag_len,
    - agent, phb, card);
    - }
    - /*
    - * Point to the next Mfg Area
    - * Use defined size, sizeof give wrong answer
    - */
    - area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len
    - + MFG_ENTRY_SIZE);
    - len -= (mfg_tag_len + MFG_ENTRY_SIZE);
    - }
    -}
    -
    -/*
    - * Look for "BUS".. Data is not Null terminated.
    - * PHBID of 0xFF indicates PHB was not found in VPD Data.
    - */
    -static u8 __init iseries_parse_phbid(u8 *area, int len)
    -{
    - while (len > 0) {
    - if ((*area == 'B') && (*(area + 1) == 'U')
    - && (*(area + 2) == 'S')) {
    - area += 3;
    - while (*area == ' ')
    - area++;
    - return *area & 0x0F;
    - }
    - area++;
    - len--;
    - }
    - return 0xff;
    -}
    -
    -/*
    - * Parse out the VPD Areas
    - */
    -static void __init iseries_parse_vpd(u8 *data, int data_len,
    - HvAgentId agent, u8 *frame, char card[4])
    -{
    - u8 phb = 0xff;
    -
    - while (data_len > 0) {
    - int len;
    - u8 tag = *data;
    -
    - if (tag == VPD_END_OF_AREA)
    - break;
    - len = *(data + 1) + (*(data + 2) * 256);
    - data += 3;
    - data_len -= 3;
    - if (tag == VPD_ID_STRING)
    - phb = iseries_parse_phbid(data, len);
    - else if (tag == VPD_VENDOR_AREA)
    - iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,
    - agent, &phb, frame, card);
    - /* Point to next Area. */
    - data += len;
    - data_len -= len;
    - }
    -}
    -
    -static int __init iseries_get_location_code(u16 bus, HvAgentId agent,
    - u8 *frame, char card[4])
    -{
    - int status = 0;
    - int bus_vpd_len = 0;
    - u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
    -
    - if (bus_vpd == NULL) {
    - printk("PCI: Bus VPD Buffer allocation failure.\n");
    - return 0;
    - }
    - bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),
    - BUS_VPDSIZE);
    - if (bus_vpd_len == 0) {
    - printk("PCI: Bus VPD Buffer zero length.\n");
    - goto out_free;
    - }
    - /* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */
    - /* Make sure this is what I think it is */
    - if (*bus_vpd != VPD_ID_STRING) {
    - printk("PCI: Bus VPD Buffer missing starting tag.\n");
    - goto out_free;
    - }
    - iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);
    - status = 1;
    -out_free:
    - kfree(bus_vpd);
    - return status;
    -}
    -
    -/*
    - * Prints the device information.
    - * - Pass in pci_dev* pointer to the device.
    - * - Pass in the device count
    - *
    - * Format:
    - * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
    - * controller
    - */
    -static void __init iseries_device_information(struct pci_dev *pdev,
    - u16 bus, HvSubBusNumber subbus)
    -{
    - u8 frame = 0;
    - char card[4];
    - HvAgentId agent;
    -
    - agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
    - ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
    -
    - if (iseries_get_location_code(bus, agent, &frame, card)) {
    - printk(KERN_INFO "PCI: %s, Vendor %04X Frame%3d, "
    - "Card %4s 0x%04X\n", pci_name(pdev), pdev->vendor,
    - frame, card, (int)(pdev->class >> 8));
    - }
    -}
    -
    -/*
    - * iomm_table_allocate_entry
    - *
    - * Adds pci_dev entry in address translation table
    - *
    - * - Allocates the number of entries required in table base on BAR
    - * size.
    - * - Allocates starting at BASE_IO_MEMORY and increases.
    - * - The size is round up to be a multiple of entry size.
    - * - CurrentIndex is incremented to keep track of the last entry.
    - * - Builds the resource entry for allocated BARs.
    - */
    -static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
    -{
    - struct resource *bar_res = &dev->resource[bar_num];
    - long bar_size = pci_resource_len(dev, bar_num);
    - struct device_node *dn = pci_device_to_OF_node(dev);
    -
    - /*
    - * No space to allocate, quick exit, skip Allocation.
    - */
    - if (bar_size == 0)
    - return;
    - /*
    - * Set Resource values.
    - */
    - spin_lock(&iomm_table_lock);
    - bar_res->start = BASE_IO_MEMORY +
    - IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
    - bar_res->end = bar_res->start + bar_size - 1;
    - /*
    - * Allocate the number of table entries needed for BAR.
    - */
    - while (bar_size > 0 ) {
    - iomm_table[current_iomm_table_entry] = dn;
    - ds_addr_table[current_iomm_table_entry] =
    - iseries_ds_addr(dn) | (bar_num << 24);
    - bar_size -= IOMM_TABLE_ENTRY_SIZE;
    - ++current_iomm_table_entry;
    - }
    - max_io_memory = BASE_IO_MEMORY +
    - IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
    - spin_unlock(&iomm_table_lock);
    -}
    -
    -/*
    - * allocate_device_bars
    - *
    - * - Allocates ALL pci_dev BAR's and updates the resources with the
    - * BAR value. BARS with zero length will have the resources
    - * The HvCallPci_getBarParms is used to get the size of the BAR
    - * space. It calls iomm_table_allocate_entry to allocate
    - * each entry.
    - * - Loops through The Bar resources(0 - 5) including the ROM
    - * is resource(6).
    - */
    -static void __init allocate_device_bars(struct pci_dev *dev)
    -{
    - int bar_num;
    -
    - for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num)
    - iomm_table_allocate_entry(dev, bar_num);
    -}
    -
    -/*
    - * Log error information to system console.
    - * Filter out the device not there errors.
    - * PCI: EADs Connect Failed 0x18.58.10 Rc: 0x00xx
    - * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
    - * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
    - */
    -static void pci_log_error(char *error, int bus, int subbus,
    - int agent, int hv_res)
    -{
    - if (hv_res == 0x0302)
    - return;
    - printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
    - error, bus, subbus, agent, hv_res);
    -}
    -
    -/*
    - * Look down the chain to find the matching Device Device
    - */
    -static struct device_node *find_device_node(int bus, int devfn)
    -{
    - struct device_node *node;
    -
    - for (node = NULL; (node = of_find_all_nodes(node)); ) {
    - struct pci_dn *pdn = PCI_DN(node);
    -
    - if (pdn && (bus == pdn->busno) && (devfn == pdn->devfn))
    - return node;
    - }
    - return NULL;
    -}
    -
    -/*
    - * iSeries_pcibios_fixup_resources
    - *
    - * Fixes up all resources for devices
    - */
    -void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
    -{
    - const u32 *agent;
    - const u32 *sub_bus;
    - unsigned char bus = pdev->bus->number;
    - struct device_node *node;
    - int i;
    -
    - node = pci_device_to_OF_node(pdev);
    - pr_debug("PCI: iSeries %s, pdev %p, node %p\n",
    - pci_name(pdev), pdev, node);
    - if (!node) {
    - printk("PCI: %s disabled, device tree entry not found !\n",
    - pci_name(pdev));
    - for (i = 0; i <= PCI_ROM_RESOURCE; i++)
    - pdev->resource[i].flags = 0;
    - return;
    - }
    - sub_bus = of_get_property(node, "linux,subbus", NULL);
    - agent = of_get_property(node, "linux,agent-id", NULL);
    - if (agent && sub_bus) {
    - u8 irq = iSeries_allocate_IRQ(bus, 0, *sub_bus);
    - int err;
    -
    - err = HvCallXm_connectBusUnit(bus, *sub_bus, *agent, irq);
    - if (err)
    - pci_log_error("Connect Bus Unit",
    - bus, *sub_bus, *agent, err);
    - else {
    - err = HvCallPci_configStore8(bus, *sub_bus,
    - *agent, PCI_INTERRUPT_LINE, irq);
    - if (err)
    - pci_log_error("PciCfgStore Irq Failed!",
    - bus, *sub_bus, *agent, err);
    - else
    - pdev->irq = irq;
    - }
    - }
    -
    - allocate_device_bars(pdev);
    - if (likely(sub_bus))
    - iseries_device_information(pdev, bus, *sub_bus);
    - else
    - printk(KERN_ERR "PCI: Device node %s has missing or invalid "
    - "linux,subbus property\n", node->full_name);
    -}
    -
    -/*
    - * iSeries_pci_final_fixup(void)
    - */
    -void __init iSeries_pci_final_fixup(void)
    -{
    - /* Fix up at the device node and pci_dev relationship */
    - mf_display_src(0xC9000100);
    - iSeries_activate_IRQs();
    - mf_display_src(0xC9000200);
    -}
    -
    -/*
    - * Config space read and write functions.
    - * For now at least, we look for the device node for the bus and devfn
    - * that we are asked to access. It may be possible to translate the devfn
    - * to a subbus and deviceid more directly.
    - */
    -static u64 hv_cfg_read_func[4] = {
    - HvCallPciConfigLoad8, HvCallPciConfigLoad16,
    - HvCallPciConfigLoad32, HvCallPciConfigLoad32
    -};
    -
    -static u64 hv_cfg_write_func[4] = {
    - HvCallPciConfigStore8, HvCallPciConfigStore16,
    - HvCallPciConfigStore32, HvCallPciConfigStore32
    -};
    -
    -/*
    - * Read PCI config space
    - */
    -static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
    - int offset, int size, u32 *val)
    -{
    - struct device_node *node = find_device_node(bus->number, devfn);
    - u64 fn;
    - struct HvCallPci_LoadReturn ret;
    -
    - if (node == NULL)
    - return PCIBIOS_DEVICE_NOT_FOUND;
    - if (offset > 255) {
    - *val = ~0;
    - return PCIBIOS_BAD_REGISTER_NUMBER;
    - }
    -
    - fn = hv_cfg_read_func[(size - 1) & 3];
    - HvCall3Ret16(fn, &ret, iseries_ds_addr(node), offset, 0);
    -
    - if (ret.rc != 0) {
    - *val = ~0;
    - return PCIBIOS_DEVICE_NOT_FOUND; /* or something */
    - }
    -
    - *val = ret.value;
    - return 0;
    -}
    -
    -/*
    - * Write PCI config space
    - */
    -
    -static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
    - int offset, int size, u32 val)
    -{
    - struct device_node *node = find_device_node(bus->number, devfn);
    - u64 fn;
    - u64 ret;
    -
    - if (node == NULL)
    - return PCIBIOS_DEVICE_NOT_FOUND;
    - if (offset > 255)
    - return PCIBIOS_BAD_REGISTER_NUMBER;
    -
    - fn = hv_cfg_write_func[(size - 1) & 3];
    - ret = HvCall4(fn, iseries_ds_addr(node), offset, val, 0);
    -
    - if (ret != 0)
    - return PCIBIOS_DEVICE_NOT_FOUND;
    -
    - return 0;
    -}
    -
    -static struct pci_ops iSeries_pci_ops = {
    - .read = iSeries_pci_read_config,
    - .write = iSeries_pci_write_config
    -};
    -
    -/*
    - * Check Return Code
    - * -> On Failure, print and log information.
    - * Increment Retry Count, if exceeds max, panic partition.
    - *
    - * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
    - * PCI: Device 23.90 ReadL Retry( 1)
    - * PCI: Device 23.90 ReadL Retry Successful(1)
    - */
    -static int check_return_code(char *type, struct device_node *dn,
    - int *retry, u64 ret)
    -{
    - if (ret != 0) {
    - struct pci_dn *pdn = PCI_DN(dn);
    -
    - (*retry)++;
    - printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",
    - type, pdn->busno, pdn->devfn,
    - *retry, (int)ret);
    - /*
    - * Bump the retry and check for retry count exceeded.
    - * If, Exceeded, panic the system.
    - */
    - if (((*retry) > PCI_RETRY_MAX) &&
    - (limit_pci_retries > 0)) {
    - mf_display_src(0xB6000103);
    - panic_timeout = 0;
    - panic("PCI: Hardware I/O Error, SRC B6000103, "
    - "Automatic Reboot Disabled.\n");
    - }
    - return -1; /* Retry Try */
    - }
    - return 0;
    -}
    -
    -/*
    - * Translate the I/O Address into a device node, bar, and bar offset.
    - * Note: Make sure the passed variable end up on the stack to avoid
    - * the exposure of being device global.
    - */
    -static inline struct device_node *xlate_iomm_address(
    - const volatile void __iomem *addr,
    - u64 *dsaptr, u64 *bar_offset, const char *func)
    -{
    - unsigned long orig_addr;
    - unsigned long base_addr;
    - unsigned long ind;
    - struct device_node *dn;
    -
    - orig_addr = (unsigned long __force)addr;
    - if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) {
    - static DEFINE_RATELIMIT_STATE(ratelimit, 60 * HZ, 10);
    -
    - if (__ratelimit(&ratelimit))
    - printk(KERN_ERR
    - "iSeries_%s: invalid access at IO address %p\n",
    - func, addr);
    - return NULL;
    - }
    - base_addr = orig_addr - BASE_IO_MEMORY;
    - ind = base_addr / IOMM_TABLE_ENTRY_SIZE;
    - dn = iomm_table[ind];
    -
    - if (dn != NULL) {
    - *dsaptr = ds_addr_table[ind];
    - *bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE;
    - } else
    - panic("PCI: Invalid PCI IO address detected!\n");
    - return dn;
    -}
    -
    -/*
    - * Read MM I/O Instructions for the iSeries
    - * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
    - * else, data is returned in Big Endian format.
    - */
    -static u8 iseries_readb(const volatile void __iomem *addr)
    -{
    - u64 bar_offset;
    - u64 dsa;
    - int retry = 0;
    - struct HvCallPci_LoadReturn ret;
    - struct device_node *dn =
    - xlate_iomm_address(addr, &dsa, &bar_offset, "read_byte");
    -
    - if (dn == NULL)
    - return 0xff;
    - do {
    - HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0);
    - } while (check_return_code("RDB", dn, &retry, ret.rc) != 0);
    -
    - return ret.value;
    -}
    -
    -static u16 iseries_readw_be(const volatile void __iomem *addr)
    -{
    - u64 bar_offset;
    - u64 dsa;
    - int retry = 0;
    - struct HvCallPci_LoadReturn ret;
    - struct device_node *dn =
    - xlate_iomm_address(addr, &dsa, &bar_offset, "read_word");
    -
    - if (dn == NULL)
    - return 0xffff;
    - do {
    - HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
    - bar_offset, 0);
    - } while (check_return_code("RDW", dn, &retry, ret.rc) != 0);
    -
    - return ret.value;
    -}
    -
    -static u32 iseries_readl_be(const volatile void __iomem *addr)
    -{
    - u64 bar_offset;
    - u64 dsa;
    - int retry = 0;
    - struct HvCallPci_LoadReturn ret;
    - struct device_node *dn =
    - xlate_iomm_address(addr, &dsa, &bar_offset, "read_long");
    -
    - if (dn == NULL)
    - return 0xffffffff;
    - do {
    - HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
    - bar_offset, 0);
    - } while (check_return_code("RDL", dn, &retry, ret.rc) != 0);
    -
    - return ret.value;
    -}
    -
    -/*
    - * Write MM I/O Instructions for the iSeries
    - *
    - */
    -static void iseries_writeb(u8 data, volatile void __iomem *addr)
    -{
    - u64 bar_offset;
    - u64 dsa;
    - int retry = 0;
    - u64 rc;
    - struct device_node *dn =
    - xlate_iomm_address(addr, &dsa, &bar_offset, "write_byte");
    -
    - if (dn == NULL)
    - return;
    - do {
    - rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0);
    - } while (check_return_code("WWB", dn, &retry, rc) != 0);
    -}
    -
    -static void iseries_writew_be(u16 data, volatile void __iomem *addr)
    -{
    - u64 bar_offset;
    - u64 dsa;
    - int retry = 0;
    - u64 rc;
    - struct device_node *dn =
    - xlate_iomm_address(addr, &dsa, &bar_offset, "write_word");
    -
    - if (dn == NULL)
    - return;
    - do {
    - rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0);
    - } while (check_return_code("WWW", dn, &retry, rc) != 0);
    -}
    -
    -static void iseries_writel_be(u32 data, volatile void __iomem *addr)
    -{
    - u64 bar_offset;
    - u64 dsa;
    - int retry = 0;
    - u64 rc;
    - struct device_node *dn =
    - xlate_iomm_address(addr, &dsa, &bar_offset, "write_long");
    -
    - if (dn == NULL)
    - return;
    - do {
    - rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0);
    - } while (check_return_code("WWL", dn, &retry, rc) != 0);
    -}
    -
    -static u16 iseries_readw(const volatile void __iomem *addr)
    -{
    - return le16_to_cpu(iseries_readw_be(addr));
    -}
    -
    -static u32 iseries_readl(const volatile void __iomem *addr)
    -{
    - return le32_to_cpu(iseries_readl_be(addr));
    -}
    -
    -static void iseries_writew(u16 data, volatile void __iomem *addr)
    -{
    - iseries_writew_be(cpu_to_le16(data), addr);
    -}
    -
    -static void iseries_writel(u32 data, volatile void __iomem *addr)
    -{
    - iseries_writel(cpu_to_le32(data), addr);
    -}
    -
    -static void iseries_readsb(const volatile void __iomem *addr, void *buf,
    - unsigned long count)
    -{
    - u8 *dst = buf;
    - while(count-- > 0)
    - *(dst++) = iseries_readb(addr);
    -}
    -
    -static void iseries_readsw(const volatile void __iomem *addr, void *buf,
    - unsigned long count)
    -{
    - u16 *dst = buf;
    - while(count-- > 0)
    - *(dst++) = iseries_readw_be(addr);
    -}
    -
    -static void iseries_readsl(const volatile void __iomem *addr, void *buf,
    - unsigned long count)
    -{
    - u32 *dst = buf;
    - while(count-- > 0)
    - *(dst++) = iseries_readl_be(addr);
    -}
    -
    -static void iseries_writesb(volatile void __iomem *addr, const void *buf,
    - unsigned long count)
    -{
    - const u8 *src = buf;
    - while(count-- > 0)
    - iseries_writeb(*(src++), addr);
    -}
    -
    -static void iseries_writesw(volatile void __iomem *addr, const void *buf,
    - unsigned long count)
    -{
    - const u16 *src = buf;
    - while(count-- > 0)
    - iseries_writew_be(*(src++), addr);
    -}
    -
    -static void iseries_writesl(volatile void __iomem *addr, const void *buf,
    - unsigned long count)
    -{
    - const u32 *src = buf;
    - while(count-- > 0)
    - iseries_writel_be(*(src++), addr);
    -}
    -
    -static void iseries_memset_io(volatile void __iomem *addr, int c,
    - unsigned long n)
    -{
    - volatile char __iomem *d = addr;
    -
    - while (n-- > 0)
    - iseries_writeb(c, d++);
    -}
    -
    -static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
    - unsigned long n)
    -{
    - char *d = dest;
    - const volatile char __iomem *s = src;
    -
    - while (n-- > 0)
    - *d++ = iseries_readb(s++);
    -}
    -
    -static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
    - unsigned long n)
    -{
    - const char *s = src;
    - volatile char __iomem *d = dest;
    -
    - while (n-- > 0)
    - iseries_writeb(*s++, d++);
    -}
    -
    -/* We only set MMIO ops. The default PIO ops will be default
    - * to the MMIO ops + pci_io_base which is 0 on iSeries as
    - * expected so both should work.
    - *
    - * Note that we don't implement the readq/writeq versions as
    - * I don't know of an HV call for doing so. Thus, the default
    - * operation will be used instead, which will fault a the value
    - * return by iSeries for MMIO addresses always hits a non mapped
    - * area. This is as good as the BUG() we used to have there.
    - */
    -static struct ppc_pci_io __initdata iseries_pci_io = {
    - .readb = iseries_readb,
    - .readw = iseries_readw,
    - .readl = iseries_readl,
    - .readw_be = iseries_readw_be,
    - .readl_be = iseries_readl_be,
    - .writeb = iseries_writeb,
    - .writew = iseries_writew,
    - .writel = iseries_writel,
    - .writew_be = iseries_writew_be,
    - .writel_be = iseries_writel_be,
    - .readsb = iseries_readsb,
    - .readsw = iseries_readsw,
    - .readsl = iseries_readsl,
    - .writesb = iseries_writesb,
    - .writesw = iseries_writesw,
    - .writesl = iseries_writesl,
    - .memset_io = iseries_memset_io,
    - .memcpy_fromio = iseries_memcpy_fromio,
    - .memcpy_toio = iseries_memcpy_toio,
    -};
    -
    -/*
    - * iSeries_pcibios_init
    - *
    - * Description:
    - * This function checks for all possible system PCI host bridges that connect
    - * PCI buses. The system hypervisor is queried as to the guest partition
    - * ownership status. A pci_controller is built for any bus which is partially
    - * owned or fully owned by this guest partition.
    - */
    -void __init iSeries_pcibios_init(void)
    -{
    - struct pci_controller *phb;
    - struct device_node *root = of_find_node_by_path("/");
    - struct device_node *node = NULL;
    -
    - /* Install IO hooks */
    - ppc_pci_io = iseries_pci_io;
    -
    - pci_add_flags(PCI_PROBE_ONLY);
    -
    - /* iSeries has no IO space in the common sense, it needs to set
    - * the IO base to 0
    - */
    - pci_io_base = 0;
    -
    - if (root == NULL) {
    - printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
    - "of device tree\n");
    - return;
    - }
    - while ((node = of_get_next_child(root, node)) != NULL) {
    - HvBusNumber bus;
    - const u32 *busp;
    -
    - if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
    - continue;
    -
    - busp = of_get_property(node, "bus-range", NULL);
    - if (busp == NULL)
    - continue;
    - bus = *busp;
    - printk("bus %d appears to exist\n", bus);
    - phb = pcibios_alloc_controller(node);
    - if (phb == NULL)
    - continue;
    - /* All legacy iSeries PHBs are in domain zero */
    - phb->global_number = 0;
    -
    - phb->first_busno = bus;
    - phb->last_busno = bus;
    - phb->ops = &iSeries_pci_ops;
    - phb->io_base_virt = (void __iomem *)_IO_BASE;
    - phb->io_resource.flags = IORESOURCE_IO;
    - phb->io_resource.start = BASE_IO_MEMORY;
    - phb->io_resource.end = END_IO_MEMORY;
    - phb->io_resource.name = "iSeries PCI IO";
    - phb->mem_resources[0].flags = IORESOURCE_MEM;
    - phb->mem_resources[0].start = BASE_IO_MEMORY;
    - phb->mem_resources[0].end = END_IO_MEMORY;
    - phb->mem_resources[0].name = "Series PCI MEM";
    - }
    -
    - of_node_put(root);
    -
    - pci_devs_phb_init();
    -}
    -
    Index: linux-2.6/include/linux/pci.h
    ===================================================================
    --- linux-2.6.orig/include/linux/pci.h
    +++ linux-2.6/include/linux/pci.h
    @@ -947,7 +947,6 @@ int __must_check __pci_register_driver(s
    __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)

    void pci_unregister_driver(struct pci_driver *dev);
    -<<<<<<< HEAD

    /**
    * module_pci_driver() - Helper macro for registering a PCI driver
    @@ -961,10 +960,7 @@ void pci_unregister_driver(struct pci_dr
    module_driver(__pci_driver, pci_register_driver, \
    pci_unregister_driver)

    -void pci_remove_behind_bridge(struct pci_dev *dev);
    -=======
    void pci_stop_and_remove_behind_bridge(struct pci_dev *dev);
    ->>>>>>> pci/linux-next
    struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
    int pci_add_dynid(struct pci_driver *drv,
    unsigned int vendor, unsigned int device,
    \
     
     \ /
      Last update: 2012-03-23 21:01    [W:0.077 / U:1.632 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site