Module Name:    src
Committed By:   skrll
Date:           Mon Mar 25 21:55:12 UTC 2013

Modified Files:
        src/sys/external/bsd/vchiq/dist/interface/vchiq_arm: vchiq_2835_arm.c

Log Message:
Revert commented out create_pagelist/free_pagelist to the original
version and not the broken FreeBSD version.  Should really be deleted
someday soon.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 \
    src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c
diff -u src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c:1.1 src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c:1.2
--- src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c:1.1	Fri Mar  8 12:32:30 2013
+++ src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c	Mon Mar 25 21:55:11 2013
@@ -537,15 +537,15 @@ vchiq_doorbell_irq(int irq, void *dev_id
 #if 0
 static int
 create_pagelist(char __user *buf, size_t count, unsigned short type,
-	lwp_t *l, PAGELIST_T ** ppagelist)
+	struct task_struct *task, PAGELIST_T ** ppagelist)
 {
 	PAGELIST_T *pagelist;
-	paddr_t *pages;
+	struct page **pages;
+	struct page *page;
 	unsigned long *addrs;
 	unsigned int num_pages, offset, i;
-	int pagelist_size;
 	char *addr, *base_addr, *next_addr;
-	int run, addridx, err;
+	int run, addridx, actual_pages;
 
 	offset = (unsigned int)buf & (PAGE_SIZE - 1);
 	num_pages = (count + offset + PAGE_SIZE - 1) / PAGE_SIZE;
@@ -555,10 +555,10 @@ create_pagelist(char __user *buf, size_t
 	/* Allocate enough storage to hold the page pointers and the page
 	** list
 	*/
-	pagelist_size = sizeof(PAGELIST_T) +
+	pagelist = kmalloc(sizeof(PAGELIST_T) +
 		(num_pages * sizeof(unsigned long)) +
-		(num_pages * sizeof(paddr_t));
-	pagelist = malloc(pagelist_size, M_VCPAGELIST, M_WAITOK | M_ZERO);
+		(num_pages * sizeof(pages[0])),
+		GFP_KERNEL);
 
 	vchiq_log_trace(vchiq_arm_log_level,
 		"create_pagelist - %x", (unsigned int)pagelist);
@@ -566,28 +566,27 @@ create_pagelist(char __user *buf, size_t
 		return -ENOMEM;
 
 	addrs = pagelist->addrs;
-	pages = (paddr_t *)(addrs + num_pages);
+	pages = (struct page **)(addrs + num_pages);
 
-	err = uvm_map_pageable(&l->l_proc->p_vmspace->vm_map,
-	    (vaddr_t)buf, (vaddr_t)buf + count, false, 0);
-	if (err == 0) {
-		err = uvm_map_protect(&l->l_proc->p_vmspace->vm_map,
-		    (vaddr_t)buf, (vaddr_t)buf + count,
-		    (type == PAGELIST_READ ? VM_PROT_WRITE : 0) | VM_PROT_READ,
-		    false);
-	}
-	if (err == 0) {
-		for (i = 0; i < num_pages; i++) {
-			pmap_extract(vm_map_pmap(&l->l_proc->p_vmspace->vm_map),
-			    (vaddr_t)buf + (i * PAGE_SIZE), &pages[i]);
-		}
-	}
-
-	if (err != 0) {
-		uvm_map_pageable(&l->l_proc->p_vmspace->vm_map,
-		    (vaddr_t)buf, (vaddr_t)buf + count, true, 0);
-		free(pagelist, M_VCPAGELIST);
-		return (-ENOMEM);
+	down_read(&task->mm->mmap_sem);
+	actual_pages = get_user_pages(task, task->mm,
+		(unsigned long)buf & ~(PAGE_SIZE - 1), num_pages,
+		(type == PAGELIST_READ) /*Write */ , 0 /*Force */ ,
+		pages, NULL /*vmas */);
+	up_read(&task->mm->mmap_sem);
+
+   if (actual_pages != num_pages)
+   {
+      /* This is probably due to the process being killed */
+      while (actual_pages > 0)
+      {
+         actual_pages--;
+         page_cache_release(pages[actual_pages]);
+      }
+      kfree(pagelist);
+      if (actual_pages == 0)
+         actual_pages = -ENOMEM;
+      return actual_pages;
 	}
 
 	pagelist->length = count;
@@ -596,13 +595,13 @@ create_pagelist(char __user *buf, size_t
 
 	/* Group the pages into runs of contiguous pages */
 
-	base_addr = (void *)PHYS_TO_VCBUS(pages[0]);
+	base_addr = VCHIQ_ARM_ADDRESS(page_address(pages[0]));
 	next_addr = base_addr + PAGE_SIZE;
 	addridx = 0;
 	run = 0;
 
 	for (i = 1; i < num_pages; i++) {
-		addr = (void *)PHYS_TO_VCBUS(pages[i]);
+		addr = VCHIQ_ARM_ADDRESS(page_address(pages[i]));
 		if ((addr == next_addr) && (run < (PAGE_SIZE - 1))) {
 			next_addr += PAGE_SIZE;
 			run++;
@@ -626,7 +625,7 @@ create_pagelist(char __user *buf, size_t
 		FRAGMENTS_T *fragments;
 
 		if (down_interruptible(&g_free_fragments_sema) != 0) {
-      			free(pagelist, M_VCPAGELIST);
+			kfree(pagelist);
 			return -EINTR;
 		}
 
@@ -642,7 +641,11 @@ create_pagelist(char __user *buf, size_t
 							 g_fragments_base);
 	}
 
-	cpu_dcache_wbinv_range((vm_offset_t)pagelist, pagelist_size);
+	for (page = virt_to_page(pagelist);
+		page <= virt_to_page(addrs + num_pages - 1); page++) {
+		flush_dcache_page(page);
+	}
+
 	*ppagelist = pagelist;
 
 	return 0;
@@ -651,9 +654,8 @@ create_pagelist(char __user *buf, size_t
 static void
 free_pagelist(PAGELIST_T *pagelist, int actual)
 {
-	paddr_t *pages;
-	unsigned int num_pages;
-	void *page_address;
+	struct page **pages;
+	unsigned int num_pages, i;
 
 	vchiq_log_trace(vchiq_arm_log_level,
 		"free_pagelist - %x, %d", (unsigned int)pagelist, actual);
@@ -662,7 +664,7 @@ free_pagelist(PAGELIST_T *pagelist, int 
 		(pagelist->length + pagelist->offset + PAGE_SIZE - 1) /
 		PAGE_SIZE;
 
-	pages = (paddr_t *)(pagelist->addrs + num_pages);
+	pages = (struct page **)(pagelist->addrs + num_pages);
 
 	/* Deal with any partial cache lines (fragments) */
 	if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) {
@@ -674,34 +676,23 @@ free_pagelist(PAGELIST_T *pagelist, int 
 		tail_bytes = (pagelist->offset + actual) &
 			(CACHE_LINE_SIZE - 1);
 
-		if (actual >= 0) {
-			/* XXXBSD: might be inefficient */
-			//page_address = pmap_mapdev(pages[0], PAGE_SIZE*num_pages);
-			panic("free_pagelist: XXX TODO");
-		}
-		else 
-			page_address = NULL;
 		if ((actual >= 0) && (head_bytes != 0)) {
 			if (head_bytes > actual)
 				head_bytes = actual;
 
-			memcpy((char *)page_address +
+			memcpy((char *)page_address(pages[0]) +
 				pagelist->offset,
 				fragments->headbuf,
 				head_bytes);
 		}
 		if ((actual >= 0) && (head_bytes < actual) &&
 			(tail_bytes != 0)) {
-			memcpy((char *)page_address + PAGE_SIZE*(num_pages - 1) +
-					 ((pagelist->offset + actual) & (PAGE_SIZE -
-								1) & ~(CACHE_LINE_SIZE - 1)),
+			memcpy((char *)page_address(pages[num_pages - 1]) +
+				((pagelist->offset + actual) &
+				(PAGE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)),
 					 fragments->tailbuf, tail_bytes);
 		}
 
-		if (page_address) {
-			panic("free_pagelist: XXX TODO");
-		}
-
 		down(&g_free_fragments_mutex);
 		*(FRAGMENTS_T **) fragments = g_free_fragments;
 		g_free_fragments = fragments;
@@ -709,15 +700,12 @@ free_pagelist(PAGELIST_T *pagelist, int 
 		up(&g_free_fragments_sema);
 	}
 
-#if 0
 	for (i = 0; i < num_pages; i++) {
 		if (pagelist->type != PAGELIST_WRITE)
-			vm_page_dirty(pages[i]);
+			set_page_dirty(pages[i]);
+		page_cache_release(pages[i]);
 	}
 
-	vm_page_unhold_pages(pages, num_pages);
-#endif
-
-	free(pagelist, M_VCPAGELIST);
+	kfree(pagelist);
 }
 #endif

Reply via email to