fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / sparc / mm / io-unit.c
index 21ca5fe..4ccda77 100644 (file)
@@ -4,13 +4,13 @@
  * Copyright (C) 1997,1998 Jakub Jelinek    (jj@sunsite.mff.cuni.cz)
  */
  
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>     /* pte_offset_map => kmap_atomic */
+#include <linux/bitops.h>
 
 #include <asm/scatterlist.h>
 #include <asm/pgalloc.h>
 #include <asm/io.h>
 #include <asm/io-unit.h>
 #include <asm/mxcc.h>
-#include <asm/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
+#include <asm/dma.h>
+#include <asm/oplib.h>
 
 /* #define IOUNIT_DEBUG */
 #ifdef IOUNIT_DEBUG
@@ -41,9 +42,12 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
        struct linux_prom_registers iommu_promregs[PROMREG_MAX];
        struct resource r;
 
-       iounit = kmalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
+       iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
+       if (!iounit) {
+               prom_printf("SUN4D: Cannot alloc iounit, halting.\n");
+               prom_halt();
+       }
 
-       memset(iounit, 0, sizeof(*iounit));
        iounit->limit[0] = IOUNIT_BMAP1_START;
        iounit->limit[1] = IOUNIT_BMAP2_START;
        iounit->limit[2] = IOUNIT_BMAPM_START;
@@ -51,17 +55,20 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
        iounit->rotor[1] = IOUNIT_BMAP2_START;
        iounit->rotor[2] = IOUNIT_BMAPM_START;
 
-       prom_getproperty(sbi_node, "reg", (void *) iommu_promregs,
-                        sizeof(iommu_promregs));
-       prom_apply_generic_ranges(io_node, 0, iommu_promregs, 3);
-       memset(&r, 0, sizeof(r));
-       r.flags = iommu_promregs[2].which_io;
-       r.start = iommu_promregs[2].phys_addr;
-       xpt = (iopte_t *) sbus_ioremap(&r, 0, PAGE_SIZE * 16, "XPT");
+       xpt = NULL;
+       if(prom_getproperty(sbi_node, "reg", (void *) iommu_promregs,
+                           sizeof(iommu_promregs)) != -1) {
+               prom_apply_generic_ranges(io_node, 0, iommu_promregs, 3);
+               memset(&r, 0, sizeof(r));
+               r.flags = iommu_promregs[2].which_io;
+               r.start = iommu_promregs[2].phys_addr;
+               xpt = (iopte_t *) sbus_ioremap(&r, 0, PAGE_SIZE * 16, "XPT");
+       }
        if(!xpt) panic("Cannot map External Page Table.");
        
        sbus->iommu = (struct iommu_struct *)iounit;
        iounit->page_table = xpt;
+       spin_lock_init(&iounit->lock);
        
        for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t);
             xpt < xptend;)
@@ -195,7 +202,7 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in
                        pte_t *ptep;
                        long i;
 
-                       pgdp = pgd_offset(init_task.mm, addr);
+                       pgdp = pgd_offset(&init_mm, addr);
                        pmdp = pmd_offset(pgdp, addr);
                        ptep = pte_offset_map(pmdp, addr);