Auto-update from upstream
authorTony Luck <tony.luck@intel.com>
Fri, 23 Jun 2006 20:46:23 +0000 (13:46 -0700)
committerTony Luck <tony.luck@intel.com>
Fri, 23 Jun 2006 20:46:23 +0000 (13:46 -0700)
1  2 
arch/ia64/Kconfig
arch/ia64/pci/pci.c
arch/ia64/sn/pci/tioce_provider.c

diff --combined arch/ia64/Kconfig
@@@ -77,6 -77,7 +77,7 @@@ choic
  config IA64_GENERIC
        bool "generic"
        select ACPI
+       select PCI
        select NUMA
        select ACPI_NUMA
        help
@@@ -273,7 -274,6 +274,6 @@@ config HOTPLUG_CP
  config SCHED_SMT
        bool "SMT scheduler support"
        depends on SMP
-       default off
        help
          Improves the CPU scheduler's decision making when dealing with
          Intel IA64 chips with MultiThreading at a cost of slightly increased
@@@ -449,8 -449,6 +449,8 @@@ config PCI_DOMAIN
        bool
        default PCI
  
 +source "drivers/pci/pcie/Kconfig"
 +
  source "drivers/pci/Kconfig"
  
  source "drivers/pci/hotplug/Kconfig"
diff --combined arch/ia64/pci/pci.c
@@@ -352,7 -352,7 +352,7 @@@ pci_acpi_scan_root(struct acpi_device *
        pxm = acpi_get_pxm(controller->acpi_handle);
  #ifdef CONFIG_NUMA
        if (pxm >= 0)
-               controller->node = pxm_to_nid_map[pxm];
+               controller->node = pxm_to_node(pxm);
  #endif
  
        acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
@@@ -645,31 -645,18 +645,31 @@@ char *ia64_pci_get_legacy_mem(struct pc
  int
  pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma)
  {
 +      unsigned long size = vma->vm_end - vma->vm_start;
 +      pgprot_t prot;
        char *addr;
  
 +      /*
 +       * Avoid attribute aliasing.  See Documentation/ia64/aliasing.txt
 +       * for more details.
 +       */
 +      if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, size))
 +              return -EINVAL;
 +      prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
 +                                  vma->vm_page_prot);
 +      if (pgprot_val(prot) != pgprot_val(pgprot_noncached(vma->vm_page_prot)))
 +              return -EINVAL;
 +
        addr = pci_get_legacy_mem(bus);
        if (IS_ERR(addr))
                return PTR_ERR(addr);
  
        vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT;
 -      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 +      vma->vm_page_prot = prot;
        vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO);
  
        if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
 -                          vma->vm_end - vma->vm_start, vma->vm_page_prot))
 +                          size, vma->vm_page_prot))
                return -EAGAIN;
  
        return 0;
@@@ -3,7 -3,7 +3,7 @@@
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
 - * Copyright (C) 2003-2005 Silicon Graphics, Inc.  All Rights Reserved.
 + * Copyright (C) 2003-2006 Silicon Graphics, Inc.  All Rights Reserved.
   */
  
  #include <linux/types.h>
@@@ -170,7 -170,8 +170,8 @@@ tioce_mmr_war_post(struct tioce_kernel 
        (ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1)
  
  #define ATE_VALID(ate)        ((ate) & (1UL << 63))
- #define ATE_MAKE(addr, ps) (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63))
+ #define ATE_MAKE(addr, ps, msi) \
+       (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63) | ((msi)?(1UL << 62):0))
  
  /*
   * Flavors of ate-based mapping supported by tioce_alloc_map()
   *
   * 63    - must be 1 to indicate d64 mode to CE hardware
   * 62    - barrier bit ... controlled with tioce_dma_barrier()
-  * 61    - 0 since this is not an MSI transaction
+  * 61    - msi bit ... specified through dma_flags
   * 60:54 - reserved, MBZ
   */
  static u64
- tioce_dma_d64(unsigned long ct_addr)
+ tioce_dma_d64(unsigned long ct_addr, int dma_flags)
  {
        u64 bus_addr;
  
        bus_addr = ct_addr | (1UL << 63);
+       if (dma_flags & SN_DMA_MSI)
+               bus_addr |= (1UL << 61);
  
        return bus_addr;
  }
@@@ -261,7 -264,7 +264,7 @@@ pcidev_to_tioce(struct pci_dev *pdev, s
   */
  static u64
  tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
-               u64 ct_addr, int len)
+               u64 ct_addr, int len, int dma_flags)
  {
        int i;
        int j;
        int entries;
        int nates;
        u64 pagesize;
+       int msi_capable, msi_wanted;
        u64 *ate_shadow;
        u64 *ate_reg;
        u64 addr;
                ate_reg = ce_mmr->ce_ure_ate3240;
                pagesize = ce_kern->ce_ate3240_pagesize;
                bus_base = TIOCE_M32_MIN;
+               msi_capable = 1;
                break;
        case TIOCE_ATE_M40:
                first = 0;
                ate_reg = ce_mmr->ce_ure_ate40;
                pagesize = MB(64);
                bus_base = TIOCE_M40_MIN;
+               msi_capable = 0;
                break;
        case TIOCE_ATE_M40S:
                /*
                ate_reg = ce_mmr->ce_ure_ate3240;
                pagesize = GB(16);
                bus_base = TIOCE_M40S_MIN;
+               msi_capable = 0;
                break;
        default:
                return 0;
        }
  
+       msi_wanted = dma_flags & SN_DMA_MSI;
+       if (msi_wanted && !msi_capable)
+               return 0;
        nates = ATE_NPAGES(ct_addr, len, pagesize);
        if (nates > entries)
                return 0;
        for (j = 0; j < nates; j++) {
                u64 ate;
  
-               ate = ATE_MAKE(addr, pagesize);
+               ate = ATE_MAKE(addr, pagesize, msi_wanted);
                ate_shadow[i + j] = ate;
                tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate);
                addr += pagesize;
   * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info.
   */
  static u64
- tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr)
+ tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags)
  {
        int dma_ok;
        int port;
        u64 ct_lower;
        dma_addr_t bus_addr;
  
+       if (dma_flags & SN_DMA_MSI)
+               return 0;
        ct_upper = ct_addr & ~0x3fffffffUL;
        ct_lower = ct_addr & 0x3fffffffUL;
  
@@@ -507,7 -521,7 +521,7 @@@ tioce_dma_unmap(struct pci_dev *pdev, d
   */
  static u64
  tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
-                int barrier)
+                int barrier, int dma_flags)
  {
        unsigned long flags;
        u64 ct_addr;
        if (dma_mask < 0x7fffffffUL)
                return 0;
  
-       ct_addr = PHYS_TO_TIODMA(paddr);
+       if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
+               ct_addr = PHYS_TO_TIODMA(paddr);
+       else
+               ct_addr = paddr;
  
        /*
         * If the device can generate 64 bit addresses, create a D64 map.
-        * Since this should never fail, bypass the rest of the checks.
         */
        if (dma_mask == ~0UL) {
-               mapaddr = tioce_dma_d64(ct_addr);
-               goto dma_map_done;
+               mapaddr = tioce_dma_d64(ct_addr, dma_flags);
+               if (mapaddr)
+                       goto dma_map_done;
        }
  
        pcidev_to_tioce(pdev, NULL, &ce_kern, &port);
  
                if (byte_count > MB(64)) {
                        mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
-                                                 port, ct_addr, byte_count);
+                                                 port, ct_addr, byte_count,
+                                                 dma_flags);
                        if (!mapaddr)
                                mapaddr =
                                    tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
-                                                   ct_addr, byte_count);
+                                                   ct_addr, byte_count,
+                                                   dma_flags);
                } else {
                        mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
-                                                 ct_addr, byte_count);
+                                                 ct_addr, byte_count,
+                                                 dma_flags);
                        if (!mapaddr)
                                mapaddr =
                                    tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
-                                                   port, ct_addr, byte_count);
+                                                   port, ct_addr, byte_count,
+                                                   dma_flags);
                }
        }
  
         * 32-bit direct is the next mode to try
         */
        if (!mapaddr && dma_mask >= 0xffffffffUL)
-               mapaddr = tioce_dma_d32(pdev, ct_addr);
+               mapaddr = tioce_dma_d32(pdev, ct_addr, dma_flags);
  
        /*
         * Last resort, try 32-bit ATE-based map.
        if (!mapaddr)
                mapaddr =
                    tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr,
-                                   byte_count);
+                                   byte_count, dma_flags);
  
        spin_unlock_irqrestore(&ce_kern->ce_lock, flags);
  
@@@ -622,9 -643,9 +643,9 @@@ dma_map_done
   * in the address.
   */
  static u64
- tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count)
+ tioce_dma(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
  {
-       return tioce_do_dma_map(pdev, paddr, byte_count, 0);
+       return tioce_do_dma_map(pdev, paddr, byte_count, 0, dma_flags);
  }
  
  /**
   * Simply call tioce_do_dma_map() to create a map with the barrier bit set
   * in the address.
   */ static u64
- tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count)
+ tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
  {
-       return tioce_do_dma_map(pdev, paddr, byte_count, 1);
+       return tioce_do_dma_map(pdev, paddr, byte_count, 1, dma_flags);
  }
  
  /**
@@@ -696,7 -717,7 +717,7 @@@ tioce_reserve_m32(struct tioce_kernel *
        while (ate_index <= last_ate) {
                u64 ate;
  
-               ate = ATE_MAKE(0xdeadbeef, ps);
+               ate = ATE_MAKE(0xdeadbeef, ps, 0);
                ce_kern->ce_ate3240_shadow[ate_index] = ate;
                tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index],
                                 ate);
@@@ -1002,7 -1023,7 +1023,7 @@@ tioce_bus_fixup(struct pcibus_bussoft *
        tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_int_status_alias, ~0ULL);
        tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_error_summary_alias,
                       ~0ULL);
 -      tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_dre_comp_err_addr, ~0ULL);
 +      tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_dre_comp_err_addr, 0ULL);
  
        if (request_irq(SGI_PCIASIC_ERROR,
                        tioce_error_intr_handler,