Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / parisc / kernel / pci-dma.c
index ebbcbf2..a6caf10 100644 (file)
 #include <asm/page.h>  /* get_order */
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
+#include <asm/tlbflush.h>      /* for purge_tlb_*() macros */
 
-#ifdef DEBUG_PCI
-#undef ASSERT
-#define ASSERT(expr) \
-       if(!(expr)) { \
-               printk("\n%s:%d: Assertion " #expr " failed!\n", \
-                               __FILE__, __LINE__); \
-               panic(#expr); \
-       }
-#else
-#define ASSERT(expr)
-#endif
-
-
-static struct proc_dir_entry * proc_gsc_root = NULL;
+static struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
 static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length);
-static unsigned long pcxl_used_bytes = 0;
-static unsigned long pcxl_used_pages = 0;
+static unsigned long pcxl_used_bytes __read_mostly = 0;
+static unsigned long pcxl_used_pages __read_mostly = 0;
 
 extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */
 static spinlock_t   pcxl_res_lock;
@@ -104,7 +92,9 @@ static inline int map_pte_uncached(pte_t * pte,
                if (!pte_none(*pte))
                        printk(KERN_ERR "map_pte_uncached: page already exists\n");
                set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC));
+               purge_tlb_start();
                pdtlb_kernel(orig_vaddr);
+               purge_tlb_end();
                vaddr += PAGE_SIZE;
                orig_vaddr += PAGE_SIZE;
                (*paddr_ptr) += PAGE_SIZE;
@@ -124,7 +114,7 @@ static inline int map_pmd_uncached(pmd_t * pmd, unsigned long vaddr,
        if (end > PGDIR_SIZE)
                end = PGDIR_SIZE;
        do {
-               pte_t * pte = pte_alloc_kernel(&init_mm, pmd, vaddr);
+               pte_t * pte = pte_alloc_kernel(pmd, vaddr);
                if (!pte)
                        return -ENOMEM;
                if (map_pte_uncached(pte, orig_vaddr, end - vaddr, paddr_ptr))
@@ -178,8 +168,10 @@ static inline void unmap_uncached_pte(pmd_t * pmd, unsigned long vaddr,
                end = PMD_SIZE;
        do {
                pte_t page = *pte;
-               pte_clear(pte);
+               pte_clear(&init_mm, vaddr, pte);
+               purge_tlb_start();
                pdtlb_kernel(orig_vaddr);
+               purge_tlb_end();
                vaddr += PAGE_SIZE;
                orig_vaddr += PAGE_SIZE;
                pte++;
@@ -255,10 +247,6 @@ pcxl_alloc_range(size_t size)
        u_long mask, flags;
        unsigned int pages_needed = size >> PAGE_SHIFT;
 
-       ASSERT(pages_needed);
-       ASSERT((pages_needed * PAGE_SIZE) < DMA_CHUNK_SIZE);
-       ASSERT(pages_needed < (BITS_PER_LONG - PAGE_SHIFT));
-
        mask = (u_long) -1L;
        mask >>= BITS_PER_LONG - pages_needed;
 
@@ -302,7 +290,7 @@ resource_found:
 
 #define PCXL_FREE_MAPPINGS(idx, m, size) \
                u##size *res_ptr = (u##size *)&(pcxl_res_map[(idx) + (((size >> 3) - 1) & (~((size >> 3) - 1)))]); \
-               ASSERT((*res_ptr & m) == m); \
+               /* BUG_ON((*res_ptr & m) != m); */ \
                *res_ptr &= ~m;
 
 /*
@@ -315,10 +303,6 @@ pcxl_free_range(unsigned long vaddr, size_t size)
        unsigned int res_idx = (vaddr - pcxl_dma_start) >> (PAGE_SHIFT + 3);
        unsigned int pages_mapped = size >> PAGE_SHIFT;
 
-       ASSERT(pages_mapped);
-       ASSERT((pages_mapped * PAGE_SIZE) < DMA_CHUNK_SIZE);
-       ASSERT(pages_mapped < (BITS_PER_LONG - PAGE_SHIFT));
-
        mask = (u_long) -1L;
        mask >>= BITS_PER_LONG - pages_mapped;
 
@@ -349,23 +333,33 @@ pcxl_free_range(unsigned long vaddr, size_t size)
 static int __init
 pcxl_dma_init(void)
 {
-    if (pcxl_dma_start == 0)
-       return 0;
+       if (pcxl_dma_start == 0)
+               return 0;
 
-    spin_lock_init(&pcxl_res_lock);
-    pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
-    pcxl_res_hint = 0;
-    pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
+       spin_lock_init(&pcxl_res_lock);
+       pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
+       pcxl_res_hint = 0;
+       pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
                                            get_order(pcxl_res_size));
-    memset(pcxl_res_map, 0, pcxl_res_size);
-    proc_gsc_root = proc_mkdir("gsc", 0);
-    create_proc_info_entry("dino", 0, proc_gsc_root, pcxl_proc_info);
-    return 0;
+       memset(pcxl_res_map, 0, pcxl_res_size);
+       proc_gsc_root = proc_mkdir("gsc", 0);
+       if (!proc_gsc_root)
+               printk(KERN_WARNING
+                       "pcxl_dma_init: Unable to create gsc /proc dir entry\n");
+       else {
+               struct proc_dir_entry* ent;
+               ent = create_proc_info_entry("pcxl_dma", 0,
+                               proc_gsc_root, pcxl_proc_info);
+               if (!ent)
+                       printk(KERN_WARNING
+                               "pci-dma.c: Unable to create pcxl_dma /proc entry.\n");
+       }
+       return 0;
 }
 
 __initcall(pcxl_dma_init);
 
-static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
+static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)
 {
        unsigned long vaddr;
        unsigned long paddr;
@@ -518,13 +512,13 @@ struct hppa_dma_ops pcxl_dma_ops = {
 };
 
 static void *fail_alloc_consistent(struct device *dev, size_t size,
-                                  dma_addr_t *dma_handle, int flag)
+                                  dma_addr_t *dma_handle, gfp_t flag)
 {
        return NULL;
 }
 
 static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
-                                         dma_addr_t *dma_handle, int flag)
+                                         dma_addr_t *dma_handle, gfp_t flag)
 {
        void *addr = NULL;
 
@@ -561,16 +555,16 @@ struct hppa_dma_ops pcx_dma_ops = {
 
 static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
 {
+#if 0
        u_long i = 0;
        unsigned long *res_ptr = (u_long *)pcxl_res_map;
-       unsigned long total_pages = pcxl_res_size << 3;        /* 8 bits per byte */
+#endif
+       unsigned long total_pages = pcxl_res_size << 3;   /* 8 bits per byte */
 
-       sprintf(buf, "\nDMA Mapping Area size    : %d bytes (%d pages)\n",
-               PCXL_DMA_MAP_SIZE,
-               (pcxl_res_size << 3) ); /* 1 bit per page */
+       sprintf(buf, "\nDMA Mapping Area size    : %d bytes (%ld pages)\n",
+               PCXL_DMA_MAP_SIZE, total_pages);
        
-       sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
-               buf, pcxl_res_size, pcxl_res_size << 3);   /* 8 bits per byte */
+       sprintf(buf, "%sResource bitmap : %d bytes\n", buf, pcxl_res_size);
 
        strcat(buf,  "            total:    free:    used:   % used:\n");
        sprintf(buf, "%sblocks  %8d %8ld %8ld %8ld%%\n", buf, pcxl_res_size,
@@ -580,7 +574,8 @@ static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
        sprintf(buf, "%spages   %8ld %8ld %8ld %8ld%%\n", buf, total_pages,
                total_pages - pcxl_used_pages, pcxl_used_pages,
                (pcxl_used_pages * 100 / total_pages));
-       
+
+#if 0
        strcat(buf, "\nResource bitmap:");
 
        for(; i < (pcxl_res_size / sizeof(u_long)); ++i, ++res_ptr) {
@@ -588,6 +583,7 @@ static int pcxl_proc_info(char *buf, char **start, off_t offset, int len)
                    strcat(buf,"\n   ");
                sprintf(buf, "%s %08lx", buf, *res_ptr);
        }
+#endif
        strcat(buf, "\n");
        return strlen(buf);
 }