linux/arch/ia64/sn/pci/tioca_provider.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 2003-2005 Silicon Graphics, Inc.  All Rights Reserved.
   7 */
   8
   9#include <linux/types.h>
  10#include <linux/interrupt.h>
  11#include <linux/pci.h>
  12#include <linux/bitmap.h>
  13#include <linux/slab.h>
  14#include <asm/sn/sn_sal.h>
  15#include <asm/sn/addrs.h>
  16#include <asm/sn/io.h>
  17#include <asm/sn/pcidev.h>
  18#include <asm/sn/pcibus_provider_defs.h>
  19#include <asm/sn/tioca_provider.h>
  20
  21u32 tioca_gart_found;
  22EXPORT_SYMBOL(tioca_gart_found);        /* used by agp-sgi */
  23
  24LIST_HEAD(tioca_list);
  25EXPORT_SYMBOL(tioca_list);      /* used by agp-sgi */
  26
  27static int tioca_gart_init(struct tioca_kernel *);
  28
  29/**
  30 * tioca_gart_init - Initialize SGI TIOCA GART
  31 * @tioca_common: ptr to common prom/kernel struct identifying the 
  32 *
  33 * If the indicated tioca has devices present, initialize its associated
  34 * GART MMR's and kernel memory.
  35 */
  36static int
  37tioca_gart_init(struct tioca_kernel *tioca_kern)
  38{
  39        u64 ap_reg;
  40        u64 offset;
  41        struct page *tmp;
  42        struct tioca_common *tioca_common;
  43        struct tioca __iomem *ca_base;
  44
  45        tioca_common = tioca_kern->ca_common;
  46        ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
  47
  48        if (list_empty(tioca_kern->ca_devices))
  49                return 0;
  50
  51        ap_reg = 0;
  52
  53        /*
  54         * Validate aperature size
  55         */
  56
  57        switch (CA_APERATURE_SIZE >> 20) {
  58        case 4:
  59                ap_reg |= (0x3ff << CA_GART_AP_SIZE_SHFT);      /* 4MB */
  60                break;
  61        case 8:
  62                ap_reg |= (0x3fe << CA_GART_AP_SIZE_SHFT);      /* 8MB */
  63                break;
  64        case 16:
  65                ap_reg |= (0x3fc << CA_GART_AP_SIZE_SHFT);      /* 16MB */
  66                break;
  67        case 32:
  68                ap_reg |= (0x3f8 << CA_GART_AP_SIZE_SHFT);      /* 32 MB */
  69                break;
  70        case 64:
  71                ap_reg |= (0x3f0 << CA_GART_AP_SIZE_SHFT);      /* 64 MB */
  72                break;
  73        case 128:
  74                ap_reg |= (0x3e0 << CA_GART_AP_SIZE_SHFT);      /* 128 MB */
  75                break;
  76        case 256:
  77                ap_reg |= (0x3c0 << CA_GART_AP_SIZE_SHFT);      /* 256 MB */
  78                break;
  79        case 512:
  80                ap_reg |= (0x380 << CA_GART_AP_SIZE_SHFT);      /* 512 MB */
  81                break;
  82        case 1024:
  83                ap_reg |= (0x300 << CA_GART_AP_SIZE_SHFT);      /* 1GB */
  84                break;
  85        case 2048:
  86                ap_reg |= (0x200 << CA_GART_AP_SIZE_SHFT);      /* 2GB */
  87                break;
  88        case 4096:
  89                ap_reg |= (0x000 << CA_GART_AP_SIZE_SHFT);      /* 4 GB */
  90                break;
  91        default:
  92                printk(KERN_ERR "%s:  Invalid CA_APERATURE_SIZE "
  93                       "0x%lx\n", __func__, (ulong) CA_APERATURE_SIZE);
  94                return -1;
  95        }
  96
  97        /*
  98         * Set up other aperature parameters
  99         */
 100
 101        if (PAGE_SIZE >= 16384) {
 102                tioca_kern->ca_ap_pagesize = 16384;
 103                ap_reg |= CA_GART_PAGE_SIZE;
 104        } else {
 105                tioca_kern->ca_ap_pagesize = 4096;
 106        }
 107
 108        tioca_kern->ca_ap_size = CA_APERATURE_SIZE;
 109        tioca_kern->ca_ap_bus_base = CA_APERATURE_BASE;
 110        tioca_kern->ca_gart_entries =
 111            tioca_kern->ca_ap_size / tioca_kern->ca_ap_pagesize;
 112
 113        ap_reg |= (CA_GART_AP_ENB_AGP | CA_GART_AP_ENB_PCI);
 114        ap_reg |= tioca_kern->ca_ap_bus_base;
 115
 116        /*
 117         * Allocate and set up the GART
 118         */
 119
 120        tioca_kern->ca_gart_size = tioca_kern->ca_gart_entries * sizeof(u64);
 121        tmp =
 122            alloc_pages_node(tioca_kern->ca_closest_node,
 123                             GFP_KERNEL | __GFP_ZERO,
 124                             get_order(tioca_kern->ca_gart_size));
 125
 126        if (!tmp) {
 127                printk(KERN_ERR "%s:  Could not allocate "
 128                       "%llu bytes (order %d) for GART\n",
 129                       __func__,
 130                       tioca_kern->ca_gart_size,
 131                       get_order(tioca_kern->ca_gart_size));
 132                return -ENOMEM;
 133        }
 134
 135        tioca_kern->ca_gart = page_address(tmp);
 136        tioca_kern->ca_gart_coretalk_addr =
 137            PHYS_TO_TIODMA(virt_to_phys(tioca_kern->ca_gart));
 138
 139        /*
 140         * Compute PCI/AGP convenience fields 
 141         */
 142
 143        offset = CA_PCI32_MAPPED_BASE - CA_APERATURE_BASE;
 144        tioca_kern->ca_pciap_base = CA_PCI32_MAPPED_BASE;
 145        tioca_kern->ca_pciap_size = CA_PCI32_MAPPED_SIZE;
 146        tioca_kern->ca_pcigart_start = offset / tioca_kern->ca_ap_pagesize;
 147        tioca_kern->ca_pcigart_base =
 148            tioca_kern->ca_gart_coretalk_addr + offset;
 149        tioca_kern->ca_pcigart =
 150            &tioca_kern->ca_gart[tioca_kern->ca_pcigart_start];
 151        tioca_kern->ca_pcigart_entries =
 152            tioca_kern->ca_pciap_size / tioca_kern->ca_ap_pagesize;
 153        tioca_kern->ca_pcigart_pagemap =
 154            kzalloc(tioca_kern->ca_pcigart_entries / 8, GFP_KERNEL);
 155        if (!tioca_kern->ca_pcigart_pagemap) {
 156                free_pages((unsigned long)tioca_kern->ca_gart,
 157                           get_order(tioca_kern->ca_gart_size));
 158                return -1;
 159        }
 160
 161        offset = CA_AGP_MAPPED_BASE - CA_APERATURE_BASE;
 162        tioca_kern->ca_gfxap_base = CA_AGP_MAPPED_BASE;
 163        tioca_kern->ca_gfxap_size = CA_AGP_MAPPED_SIZE;
 164        tioca_kern->ca_gfxgart_start = offset / tioca_kern->ca_ap_pagesize;
 165        tioca_kern->ca_gfxgart_base =
 166            tioca_kern->ca_gart_coretalk_addr + offset;
 167        tioca_kern->ca_gfxgart =
 168            &tioca_kern->ca_gart[tioca_kern->ca_gfxgart_start];
 169        tioca_kern->ca_gfxgart_entries =
 170            tioca_kern->ca_gfxap_size / tioca_kern->ca_ap_pagesize;
 171
 172        /*
 173         * various control settings:
 174         *      use agp op-combining
 175         *      use GET semantics to fetch memory
 176         *      participate in coherency domain
 177         *      DISABLE GART PREFETCHING due to hw bug tracked in SGI PV930029
 178         */
 179
 180        __sn_setq_relaxed(&ca_base->ca_control1,
 181                        CA_AGPDMA_OP_ENB_COMBDELAY);    /* PV895469 ? */
 182        __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
 183        __sn_setq_relaxed(&ca_base->ca_control2,
 184                        (0x2ull << CA_GART_MEM_PARAM_SHFT));
 185        tioca_kern->ca_gart_iscoherent = 1;
 186        __sn_clrq_relaxed(&ca_base->ca_control2,
 187                        (CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB));
 188
 189        /*
 190         * Unmask GART fetch error interrupts.  Clear residual errors first.
 191         */
 192
 193        writeq(CA_GART_FETCH_ERR, &ca_base->ca_int_status_alias);
 194        writeq(CA_GART_FETCH_ERR, &ca_base->ca_mult_error_alias);
 195        __sn_clrq_relaxed(&ca_base->ca_int_mask, CA_GART_FETCH_ERR);
 196
 197        /*
 198         * Program the aperature and gart registers in TIOCA
 199         */
 200
 201        writeq(ap_reg, &ca_base->ca_gart_aperature);
 202        writeq(tioca_kern->ca_gart_coretalk_addr|1, &ca_base->ca_gart_ptr_table);
 203
 204        return 0;
 205}
 206
 207/**
 208 * tioca_fastwrite_enable - enable AGP FW for a tioca and its functions
 209 * @tioca_kernel: structure representing the CA
 210 *
 211 * Given a CA, scan all attached functions making sure they all support
 212 * FastWrite.  If so, enable FastWrite for all functions and the CA itself.
 213 */
 214
 215void
 216tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
 217{
 218        int cap_ptr;
 219        u32 reg;
 220        struct tioca __iomem *tioca_base;
 221        struct pci_dev *pdev;
 222        struct tioca_common *common;
 223
 224        common = tioca_kern->ca_common;
 225
 226        /*
 227         * Scan all vga controllers on this bus making sure they all
 228         * support FW.  If not, return.
 229         */
 230
 231        list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) {
 232                if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8))
 233                        continue;
 234
 235                cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 236                if (!cap_ptr)
 237                        return; /* no AGP CAP means no FW */
 238
 239                pci_read_config_dword(pdev, cap_ptr + PCI_AGP_STATUS, &reg);
 240                if (!(reg & PCI_AGP_STATUS_FW))
 241                        return; /* function doesn't support FW */
 242        }
 243
 244        /*
 245         * Set fw for all vga fn's
 246         */
 247
 248        list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) {
 249                if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8))
 250                        continue;
 251
 252                cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 253                pci_read_config_dword(pdev, cap_ptr + PCI_AGP_COMMAND, &reg);
 254                reg |= PCI_AGP_COMMAND_FW;
 255                pci_write_config_dword(pdev, cap_ptr + PCI_AGP_COMMAND, reg);
 256        }
 257
 258        /*
 259         * Set ca's fw to match
 260         */
 261
 262        tioca_base = (struct tioca __iomem*)common->ca_common.bs_base;
 263        __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE);
 264}
 265
 266EXPORT_SYMBOL(tioca_fastwrite_enable);  /* used by agp-sgi */
 267
 268/**
 269 * tioca_dma_d64 - create a DMA mapping using 64-bit direct mode
 270 * @paddr: system physical address
 271 *
 272 * Map @paddr into 64-bit CA bus space.  No device context is necessary.
 273 * Bits 53:0 come from the coretalk address.  We just need to mask in the
 274 * following optional bits of the 64-bit pci address:
 275 *
 276 * 63:60 - Coretalk Packet Type -  0x1 for Mem Get/Put (coherent)
 277 *                                 0x2 for PIO (non-coherent)
 278 *                                 We will always use 0x1
 279 * 55:55 - Swap bytes              Currently unused
 280 */
 281static u64
 282tioca_dma_d64(unsigned long paddr)
 283{
 284        dma_addr_t bus_addr;
 285
 286        bus_addr = PHYS_TO_TIODMA(paddr);
 287
 288        BUG_ON(!bus_addr);
 289        BUG_ON(bus_addr >> 54);
 290
 291        /* Set upper nibble to Cache Coherent Memory op */
 292        bus_addr |= (1UL << 60);
 293
 294        return bus_addr;
 295}
 296
 297/**
 298 * tioca_dma_d48 - create a DMA mapping using 48-bit direct mode
 299 * @pdev: linux pci_dev representing the function
 300 * @paddr: system physical address
 301 *
 302 * Map @paddr into 64-bit bus space of the CA associated with @pcidev_info.
 303 *
 304 * The CA agp 48 bit direct address falls out as follows:
 305 *
 306 * When direct mapping AGP addresses, the 48 bit AGP address is
 307 * constructed as follows:
 308 *
 309 * [47:40] - Low 8 bits of the page Node ID extracted from coretalk
 310 *              address [47:40].  The upper 8 node bits are fixed
 311 *              and come from the xxx register bits [5:0]
 312 * [39:38] - Chiplet ID extracted from coretalk address [39:38]
 313 * [37:00] - node offset extracted from coretalk address [37:00]
 314 * 
 315 * Since the node id in general will be non-zero, and the chiplet id
 316 * will always be non-zero, it follows that the device must support
 317 * a dma mask of at least 0xffffffffff (40 bits) to target node 0
 318 * and in general should be 0xffffffffffff (48 bits) to target nodes
 319 * up to 255.  Nodes above 255 need the support of the xxx register,
 320 * and so a given CA can only directly target nodes in the range
 321 * xxx - xxx+255.
 322 */
 323static u64
 324tioca_dma_d48(struct pci_dev *pdev, u64 paddr)
 325{
 326        struct tioca_common *tioca_common;
 327        struct tioca __iomem *ca_base;
 328        u64 ct_addr;
 329        dma_addr_t bus_addr;
 330        u32 node_upper;
 331        u64 agp_dma_extn;
 332        struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
 333
 334        tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
 335        ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
 336
 337        ct_addr = PHYS_TO_TIODMA(paddr);
 338        if (!ct_addr)
 339                return 0;
 340
 341        bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL);
 342        node_upper = ct_addr >> 48;
 343
 344        if (node_upper > 64) {
 345                printk(KERN_ERR "%s:  coretalk addr 0x%p node id out "
 346                       "of range\n", __func__, (void *)ct_addr);
 347                return 0;
 348        }
 349
 350        agp_dma_extn = __sn_readq_relaxed(&ca_base->ca_agp_dma_addr_extn);
 351        if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) {
 352                printk(KERN_ERR "%s:  coretalk upper node (%u) "
 353                       "mismatch with ca_agp_dma_addr_extn (%llu)\n",
 354                       __func__,
 355                       node_upper, (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT));
 356                return 0;
 357        }
 358
 359        return bus_addr;
 360}
 361
 362/**
 363 * tioca_dma_mapped - create a DMA mapping using a CA GART 
 364 * @pdev: linux pci_dev representing the function
 365 * @paddr: host physical address to map
 366 * @req_size: len (bytes) to map
 367 *
 368 * Map @paddr into CA address space using the GART mechanism.  The mapped
 369 * dma_addr_t is guaranteed to be contiguous in CA bus space.
 370 */
 371static dma_addr_t
 372tioca_dma_mapped(struct pci_dev *pdev, unsigned long paddr, size_t req_size)
 373{
 374        int ps, ps_shift, entry, entries, mapsize;
 375        u64 xio_addr, end_xio_addr;
 376        struct tioca_common *tioca_common;
 377        struct tioca_kernel *tioca_kern;
 378        dma_addr_t bus_addr = 0;
 379        struct tioca_dmamap *ca_dmamap;
 380        void *map;
 381        unsigned long flags;
 382        struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
 383
 384        tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
 385        tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private;
 386
 387        xio_addr = PHYS_TO_TIODMA(paddr);
 388        if (!xio_addr)
 389                return 0;
 390
 391        spin_lock_irqsave(&tioca_kern->ca_lock, flags);
 392
 393        /*
 394         * allocate a map struct
 395         */
 396
 397        ca_dmamap = kzalloc(sizeof(struct tioca_dmamap), GFP_ATOMIC);
 398        if (!ca_dmamap)
 399                goto map_return;
 400
 401        /*
 402         * Locate free entries that can hold req_size.  Account for
 403         * unaligned start/length when allocating.
 404         */
 405
 406        ps = tioca_kern->ca_ap_pagesize;        /* will be power of 2 */
 407        ps_shift = ffs(ps) - 1;
 408        end_xio_addr = xio_addr + req_size - 1;
 409
 410        entries = (end_xio_addr >> ps_shift) - (xio_addr >> ps_shift) + 1;
 411
 412        map = tioca_kern->ca_pcigart_pagemap;
 413        mapsize = tioca_kern->ca_pcigart_entries;
 414
 415        entry = bitmap_find_next_zero_area(map, mapsize, 0, entries, 0);
 416        if (entry >= mapsize) {
 417                kfree(ca_dmamap);
 418                goto map_return;
 419        }
 420
 421        bitmap_set(map, entry, entries);
 422
 423        bus_addr = tioca_kern->ca_pciap_base + (entry * ps);
 424
 425        ca_dmamap->cad_dma_addr = bus_addr;
 426        ca_dmamap->cad_gart_size = entries;
 427        ca_dmamap->cad_gart_entry = entry;
 428        list_add(&ca_dmamap->cad_list, &tioca_kern->ca_dmamaps);
 429
 430        if (xio_addr % ps) {
 431                tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr);
 432                bus_addr += xio_addr & (ps - 1);
 433                xio_addr &= ~(ps - 1);
 434                xio_addr += ps;
 435                entry++;
 436        }
 437
 438        while (xio_addr < end_xio_addr) {
 439                tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr);
 440                xio_addr += ps;
 441                entry++;
 442        }
 443
 444        tioca_tlbflush(tioca_kern);
 445
 446map_return:
 447        spin_unlock_irqrestore(&tioca_kern->ca_lock, flags);
 448        return bus_addr;
 449}
 450
 451/**
 452 * tioca_dma_unmap - release CA mapping resources
 453 * @pdev: linux pci_dev representing the function
 454 * @bus_addr: bus address returned by an earlier tioca_dma_map
 455 * @dir: mapping direction (unused)
 456 *
 457 * Locate mapping resources associated with @bus_addr and release them.
 458 * For mappings created using the direct modes (64 or 48) there are no
 459 * resources to release.
 460 */
 461static void
 462tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
 463{
 464        int i, entry;
 465        struct tioca_common *tioca_common;
 466        struct tioca_kernel *tioca_kern;
 467        struct tioca_dmamap *map;
 468        struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
 469        unsigned long flags;
 470
 471        tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
 472        tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private;
 473
 474        /* return straight away if this isn't be a mapped address */
 475
 476        if (bus_addr < tioca_kern->ca_pciap_base ||
 477            bus_addr >= (tioca_kern->ca_pciap_base + tioca_kern->ca_pciap_size))
 478                return;
 479
 480        spin_lock_irqsave(&tioca_kern->ca_lock, flags);
 481
 482        list_for_each_entry(map, &tioca_kern->ca_dmamaps, cad_list)
 483            if (map->cad_dma_addr == bus_addr)
 484                break;
 485
 486        BUG_ON(map == NULL);
 487
 488        entry = map->cad_gart_entry;
 489
 490        for (i = 0; i < map->cad_gart_size; i++, entry++) {
 491                clear_bit(entry, tioca_kern->ca_pcigart_pagemap);
 492                tioca_kern->ca_pcigart[entry] = 0;
 493        }
 494        tioca_tlbflush(tioca_kern);
 495
 496        list_del(&map->cad_list);
 497        spin_unlock_irqrestore(&tioca_kern->ca_lock, flags);
 498        kfree(map);
 499}
 500
 501/**
 502 * tioca_dma_map - map pages for PCI DMA
 503 * @pdev: linux pci_dev representing the function
 504 * @paddr: host physical address to map
 505 * @byte_count: bytes to map
 506 *
 507 * This is the main wrapper for mapping host physical pages to CA PCI space.
 508 * The mapping mode used is based on the devices dma_mask.  As a last resort
 509 * use the GART mapped mode.
 510 */
 511static u64
 512tioca_dma_map(struct pci_dev *pdev, unsigned long paddr, size_t byte_count, int dma_flags)
 513{
 514        u64 mapaddr;
 515
 516        /*
 517         * Not supported for now ...
 518         */
 519        if (dma_flags & SN_DMA_MSI)
 520                return 0;
 521
 522        /*
 523         * If card is 64 or 48 bit addressable, use a direct mapping.  32
 524         * bit direct is so restrictive w.r.t. where the memory resides that
 525         * we don't use it even though CA has some support.
 526         */
 527
 528        if (pdev->dma_mask == ~0UL)
 529                mapaddr = tioca_dma_d64(paddr);
 530        else if (pdev->dma_mask == 0xffffffffffffUL)
 531                mapaddr = tioca_dma_d48(pdev, paddr);
 532        else
 533                mapaddr = 0;
 534
 535        /* Last resort ... use PCI portion of CA GART */
 536
 537        if (mapaddr == 0)
 538                mapaddr = tioca_dma_mapped(pdev, paddr, byte_count);
 539
 540        return mapaddr;
 541}
 542
 543/**
 544 * tioca_error_intr_handler - SGI TIO CA error interrupt handler
 545 * @irq: unused
 546 * @arg: pointer to tioca_common struct for the given CA
 547 *
 548 * Handle a CA error interrupt.  Simply a wrapper around a SAL call which
 549 * defers processing to the SGI prom.
 550 */
 551static irqreturn_t
 552tioca_error_intr_handler(int irq, void *arg)
 553{
 554        struct tioca_common *soft = arg;
 555        struct ia64_sal_retval ret_stuff;
 556        u64 segment;
 557        u64 busnum;
 558        ret_stuff.status = 0;
 559        ret_stuff.v0 = 0;
 560
 561        segment = soft->ca_common.bs_persist_segment;
 562        busnum = soft->ca_common.bs_persist_busnum;
 563
 564        SAL_CALL_NOLOCK(ret_stuff,
 565                        (u64) SN_SAL_IOIF_ERROR_INTERRUPT,
 566                        segment, busnum, 0, 0, 0, 0, 0);
 567
 568        return IRQ_HANDLED;
 569}
 570
 571/**
 572 * tioca_bus_fixup - perform final PCI fixup for a TIO CA bus
 573 * @prom_bussoft: Common prom/kernel struct representing the bus
 574 *
 575 * Replicates the tioca_common pointed to by @prom_bussoft in kernel
 576 * space.  Allocates and initializes a kernel-only area for a given CA,
 577 * and sets up an irq for handling CA error interrupts.
 578 *
 579 * On successful setup, returns the kernel version of tioca_common back to
 580 * the caller.
 581 */
 582static void *
 583tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
 584{
 585        struct tioca_common *tioca_common;
 586        struct tioca_kernel *tioca_kern;
 587        struct pci_bus *bus;
 588
 589        /* sanity check prom rev */
 590
 591        if (is_shub1() && sn_sal_rev() < 0x0406) {
 592                printk
 593                    (KERN_ERR "%s:  SGI prom rev 4.06 or greater required "
 594                     "for tioca support\n", __func__);
 595                return NULL;
 596        }
 597
 598        /*
 599         * Allocate kernel bus soft and copy from prom.
 600         */
 601
 602        tioca_common = kzalloc(sizeof(struct tioca_common), GFP_KERNEL);
 603        if (!tioca_common)
 604                return NULL;
 605
 606        memcpy(tioca_common, prom_bussoft, sizeof(struct tioca_common));
 607        tioca_common->ca_common.bs_base = (unsigned long)
 608                ioremap(REGION_OFFSET(tioca_common->ca_common.bs_base),
 609                        sizeof(struct tioca_common));
 610
 611        /* init kernel-private area */
 612
 613        tioca_kern = kzalloc(sizeof(struct tioca_kernel), GFP_KERNEL);
 614        if (!tioca_kern) {
 615                kfree(tioca_common);
 616                return NULL;
 617        }
 618
 619        tioca_kern->ca_common = tioca_common;
 620        spin_lock_init(&tioca_kern->ca_lock);
 621        INIT_LIST_HEAD(&tioca_kern->ca_dmamaps);
 622        tioca_kern->ca_closest_node =
 623            nasid_to_cnodeid(tioca_common->ca_closest_nasid);
 624        tioca_common->ca_kernel_private = (u64) tioca_kern;
 625
 626        bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment,
 627                tioca_common->ca_common.bs_persist_busnum);
 628        BUG_ON(!bus);
 629        tioca_kern->ca_devices = &bus->devices;
 630
 631        /* init GART */
 632
 633        if (tioca_gart_init(tioca_kern) < 0) {
 634                kfree(tioca_kern);
 635                kfree(tioca_common);
 636                return NULL;
 637        }
 638
 639        tioca_gart_found++;
 640        list_add(&tioca_kern->ca_list, &tioca_list);
 641
 642        if (request_irq(SGI_TIOCA_ERROR,
 643                        tioca_error_intr_handler,
 644                        IRQF_SHARED, "TIOCA error", (void *)tioca_common))
 645                printk(KERN_WARNING
 646                       "%s:  Unable to get irq %d.  "
 647                       "Error interrupts won't be routed for TIOCA bus %d\n",
 648                       __func__, SGI_TIOCA_ERROR,
 649                       (int)tioca_common->ca_common.bs_persist_busnum);
 650
 651        sn_set_err_irq_affinity(SGI_TIOCA_ERROR);
 652
 653        /* Setup locality information */
 654        controller->node = tioca_kern->ca_closest_node;
 655        return tioca_common;
 656}
 657
 658static struct sn_pcibus_provider tioca_pci_interfaces = {
 659        .dma_map = tioca_dma_map,
 660        .dma_map_consistent = tioca_dma_map,
 661        .dma_unmap = tioca_dma_unmap,
 662        .bus_fixup = tioca_bus_fixup,
 663        .force_interrupt = NULL,
 664        .target_interrupt = NULL
 665};
 666
 667/**
 668 * tioca_init_provider - init SN PCI provider ops for TIO CA
 669 */
 670int
 671tioca_init_provider(void)
 672{
 673        sn_pci_provider[PCIIO_ASIC_TYPE_TIOCA] = &tioca_pci_interfaces;
 674        return 0;
 675}
 676