fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / ia64 / hp / common / sba_iommu.c
index b8db6e3..ce49fe3 100644 (file)
@@ -19,7 +19,6 @@
 **
 */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -76,7 +75,7 @@
 ** If a device prefetches beyond the end of a valid pdir entry, it will cause
 ** a hard failure, ie. MCA.  Version 3.0 and later of the zx1 LBA should
 ** disconnect on 4k boundaries and prevent such issues.  If the device is
-** particularly agressive, this option will keep the entire pdir valid such
+** particularly aggressive, this option will keep the entire pdir valid such
 ** that prefetching will hit a valid address.  This could severely impact
 ** error containment, and is therefore off by default.  The page that is
 ** used for spill-over is poisoned, so that should help debugging somewhat.
 */
 #define DELAYED_RESOURCE_CNT   64
 
+#define PCI_DEVICE_ID_HP_SX2000_IOC    0x12ec
+
 #define ZX1_IOC_ID     ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP)
 #define ZX2_IOC_ID     ((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP)
 #define REO_IOC_ID     ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP)
 #define SX1000_IOC_ID  ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP)
+#define SX2000_IOC_ID  ((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP)
 
 #define ZX1_IOC_OFFSET 0x1000  /* ACPI reports SBA, we want IOC */
 
@@ -256,10 +258,10 @@ static u64 prefetch_spill_page;
 
 /*
 ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up
-** (or rather not merge) DMA's into managable chunks.
+** (or rather not merge) DMAs into manageable chunks.
 ** On parisc, this is more of the software/tuning constraint
-** rather than the HW. I/O MMU allocation alogorithms can be
-** faster with smaller size is (to some degree).
+** rather than the HW. I/O MMU allocation algorithms can be
+** faster with smaller sizes (to some degree).
 */
 #define DMA_CHUNK_SIZE  (BITS_PER_LONG*iovp_size)
 
@@ -1073,7 +1075,7 @@ void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, int dir)
  * See Documentation/DMA-mapping.txt
  */
 void *
-sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
 {
        struct ioc *ioc;
        void *addr;
@@ -1670,15 +1672,13 @@ ioc_sac_init(struct ioc *ioc)
         * SAC (single address cycle) addressable, so allocate a
         * pseudo-device to enforce that.
         */
-       sac = kmalloc(sizeof(*sac), GFP_KERNEL);
+       sac = kzalloc(sizeof(*sac), GFP_KERNEL);
        if (!sac)
                panic(PFX "Couldn't allocate struct pci_dev");
-       memset(sac, 0, sizeof(*sac));
 
-       controller = kmalloc(sizeof(*controller), GFP_KERNEL);
+       controller = kzalloc(sizeof(*controller), GFP_KERNEL);
        if (!controller)
                panic(PFX "Couldn't allocate struct pci_controller");
-       memset(controller, 0, sizeof(*controller));
 
        controller->iommu = ioc;
        sac->sysdata = controller;
@@ -1726,6 +1726,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = {
        { ZX1_IOC_ID, "zx1", ioc_zx1_init },
        { ZX2_IOC_ID, "zx2", NULL },
        { SX1000_IOC_ID, "sx1000", NULL },
+       { SX2000_IOC_ID, "sx2000", NULL },
 };
 
 static struct ioc * __init
@@ -1734,12 +1735,10 @@ ioc_init(u64 hpa, void *handle)
        struct ioc *ioc;
        struct ioc_iommu *info;
 
-       ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
+       ioc = kzalloc(sizeof(*ioc), GFP_KERNEL);
        if (!ioc)
                return NULL;
 
-       memset(ioc, 0, sizeof(*ioc));
-
        ioc->next = ioc_list;
        ioc_list = ioc;
 
@@ -1954,7 +1953,7 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
        if (pxm < 0)
                return;
 
-       node = pxm_to_nid_map[pxm];
+       node = pxm_to_node(pxm);
 
        if (node >= MAX_NUMNODES || !node_online(node))
                return;
@@ -1995,7 +1994,7 @@ acpi_sba_ioc_add(struct acpi_device *device)
                if (!iovp_shift)
                        iovp_shift = min(PAGE_SHIFT, 16);
        }
-       ACPI_MEM_FREE(dev_info);
+       kfree(dev_info);
 
        /*
         * default anything not caught above or specified on cmdline to 4k
@@ -2024,9 +2023,40 @@ static struct acpi_driver acpi_sba_ioc_driver = {
 static int __init
 sba_init(void)
 {
+       if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb"))
+               return 0;
+
        acpi_bus_register_driver(&acpi_sba_ioc_driver);
-       if (!ioc_list)
+       if (!ioc_list) {
+#ifdef CONFIG_IA64_GENERIC
+               extern int swiotlb_late_init_with_default_size (size_t size);
+
+               /*
+                * If we didn't find something sba_iommu can claim, we
+                * need to setup the swiotlb and switch to the dig machvec.
+                */
+               if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
+                       panic("Unable to find SBA IOMMU or initialize "
+                             "software I/O TLB: Try machvec=dig boot option");
+               machvec_init("dig");
+#else
+               panic("Unable to find SBA IOMMU: Try a generic or DIG kernel");
+#endif
                return 0;
+       }
+
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
+       /*
+        * hpzx1_swiotlb needs to have a fairly small swiotlb bounce
+        * buffer setup to support devices with smaller DMA masks than
+        * sba_iommu can handle.
+        */
+       if (ia64_platform_is("hpzx1_swiotlb")) {
+               extern void hwsw_init(void);
+
+               hwsw_init();
+       }
+#endif
 
 #ifdef CONFIG_PCI
        {
@@ -2044,18 +2074,6 @@ sba_init(void)
 
 subsys_initcall(sba_init); /* must be initialized after ACPI etc., but before any drivers... */
 
-extern void dig_setup(char**);
-/*
- * MAX_DMA_ADDRESS needs to be setup prior to paging_init to do any good,
- * so we use the platform_setup hook to fix it up.
- */
-void __init
-sba_setup(char **cmdline_p)
-{
-       MAX_DMA_ADDRESS = ~0UL;
-       dig_setup(cmdline_p);
-}
-
 static int __init
 nosbagart(char *str)
 {