Merge branch 'master' into upstream
[pandora-kernel.git] / drivers / char / agp / i460-agp.c
index a2d9e5e..3e76186 100644 (file)
@@ -111,8 +111,10 @@ static int i460_fetch_size (void)
 
        if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
                printk(KERN_ERR PFX
-                      "I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n",
-                      1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT));
+                       "I/O (GART) page-size %luKB doesn't match expected "
+                               "size %luKB\n",
+                       1UL << (i460.io_page_shift - 10),
+                       1UL << (I460_IO_PAGE_SHIFT));
                return 0;
        }
 
@@ -227,10 +229,9 @@ static int i460_configure (void)
         */
        if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) {
                size = current_size->num_entries * sizeof(i460.lp_desc[0]);
-               i460.lp_desc = kmalloc(size, GFP_KERNEL);
+               i460.lp_desc = kzalloc(size, GFP_KERNEL);
                if (!i460.lp_desc)
                        return -ENOMEM;
-               memset(i460.lp_desc, 0, size);
        }
        return 0;
 }
@@ -292,6 +293,9 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem,
        pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n",
                 mem, pg_start, type, mem->memory[0]);
 
+       if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
+               return -EINVAL;
+
        io_pg_start = I460_IOPAGES_PER_KPAGE * pg_start;
 
        temp = agp_bridge->current_size;
@@ -366,13 +370,12 @@ static int i460_alloc_large_page (struct lp_desc *lp)
        }
 
        map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8;
-       lp->alloced_map = kmalloc(map_size, GFP_KERNEL);
+       lp->alloced_map = kzalloc(map_size, GFP_KERNEL);
        if (!lp->alloced_map) {
                free_pages((unsigned long) lpage, order);
                printk(KERN_ERR PFX "Out of memory, we're in trouble...\n");
                return -ENOMEM;
        }
-       memset(lp->alloced_map, 0, map_size);
 
        lp->paddr = virt_to_gart(lpage);
        lp->refcount = 0;
@@ -396,14 +399,17 @@ static int i460_insert_memory_large_io_page (struct agp_memory *mem,
        struct lp_desc *start, *end, *lp;
        void *temp;
 
+       if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES)
+               return -EINVAL;
+
        temp = agp_bridge->current_size;
        num_entries = A_SIZE_8(temp)->num_entries;
 
        /* Figure out what pg_start means in terms of our large GART pages */
-       start           = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE];
-       end             = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE];
-       start_offset    = pg_start % I460_KPAGES_PER_IOPAGE;
-       end_offset      = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE;
+       start = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE];
+       end = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE];
+       start_offset = pg_start % I460_KPAGES_PER_IOPAGE;
+       end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE;
 
        if (end > i460.lp_desc + num_entries) {
                printk(KERN_ERR PFX "Looks like we're out of AGP memory\n");
@@ -458,10 +464,10 @@ static int i460_remove_memory_large_io_page (struct agp_memory *mem,
        num_entries = A_SIZE_8(temp)->num_entries;
 
        /* Figure out what pg_start means in terms of our large GART pages */
-       start           = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE];
-       end             = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE];
-       start_offset    = pg_start % I460_KPAGES_PER_IOPAGE;
-       end_offset      = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE;
+       start = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE];
+       end = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE];
+       start_offset = pg_start % I460_KPAGES_PER_IOPAGE;
+       end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE;
 
        for (i = 0, lp = start; lp <= end; ++lp) {
                for (idx = ((lp == start) ? start_offset : 0);
@@ -516,9 +522,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
 {
        void *page;
 
-       if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
+       if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
                page = agp_generic_alloc_page(agp_bridge);
-       else
+               global_flush_tlb();
+       } else
                /* Returning NULL would cause problems */
                /* AK: really dubious code. */
                page = (void *)~0UL;
@@ -527,8 +534,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
 
 static void i460_destroy_page (void *page)
 {
-       if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
+       if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
                agp_generic_destroy_page(page);
+               global_flush_tlb();
+       }
 }
 
 #endif /* I460_LARGE_IO_PAGES */
@@ -538,7 +547,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
 {
        /* Make sure the returned address is a valid GATT entry */
        return bridge->driver->masks[0].mask
-               | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12);
+               | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
 }
 
 struct agp_bridge_driver intel_i460_driver = {
@@ -569,6 +578,7 @@ struct agp_bridge_driver intel_i460_driver = {
 #endif
        .alloc_by_type          = agp_generic_alloc_by_type,
        .free_by_type           = agp_generic_free_by_type,
+       .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
        .cant_use_aperture      = 1,
 };