]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/char/agp/backend.c
agp: Add generic support for graphics dma remapping
[net-next-2.6.git] / drivers / char / agp / backend.c
index 3bd7e503de41caac2e743ac72603e6a4cecdd633..19ac3663acdcce4d5611882ceda98cd063c27d7e 100644 (file)
@@ -152,6 +152,15 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
                bridge->scratch_page_real = phys_to_gart(page_to_phys(page));
                bridge->scratch_page = bridge->driver->mask_memory(bridge,
                                           phys_to_gart(page_to_phys(page)), 0);
+
+               if (bridge->driver->agp_map_page &&
+                   bridge->driver->agp_map_page(phys_to_virt(page_to_phys(page)),
+                                               &bridge->scratch_page_dma)) {
+                       dev_err(&bridge->dev->dev,
+                               "unable to dma-map scratch page\n");
+                       rc = -ENOMEM;
+                       goto err_out_nounmap;
+               }
        }
 
        size_value = bridge->driver->fetch_size();
@@ -191,6 +200,13 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
        return 0;
 
 err_out:
+       if (bridge->driver->needs_scratch_page &&
+           bridge->driver->agp_unmap_page) {
+               void *va = gart_to_virt(bridge->scratch_page_real);
+
+               bridge->driver->agp_unmap_page(va, bridge->scratch_page_dma);
+       }
+err_out_nounmap:
        if (bridge->driver->needs_scratch_page) {
                void *va = gart_to_virt(bridge->scratch_page_real);
 
@@ -221,6 +237,10 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
            bridge->driver->needs_scratch_page) {
                void *va = gart_to_virt(bridge->scratch_page_real);
 
+               if (bridge->driver->agp_unmap_page)
+                       bridge->driver->agp_unmap_page(va,
+                                              bridge->scratch_page_dma);
+
                bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
                bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
        }