Date: Wed, 01 Apr 1998 22:19:02 +0000
From: Richard Hirst <richard@sleepie.demon.co.uk>
To: Jes Sorensen <Jes.Sorensen@cern.ch>
CC: linux-m68k@lists.linux-m68k.org
Subject: Re: L68K: VME bus access from user space
References: <Pine.LNX.3.96.980401095307.23949h-100000@mercator.cs.kuleuven.ac.be> <d3d8f26ifc.fsf@valhall.cern.ch>
Sender: owner-linux-m68k@phil.uni-sb.de

> Thats what I did for the Resolver board when I played with this a long
> time ago, however it would be nice to be able to mmap() uncached
> memory in a simpler fashion - maybe a /dev/memnc device or something
> like that would be an idea.
> 
> Jes

Well, here is a patch to 2.1.90 for /dev/memnc, major 1 minor 10 (not
yet registered!).  It would be useful to a few VME users, at least,
if it made it in to the source tree.

Richard

*** linux68k-2.1.90/drivers/char/mem.c	Fri Mar 20 20:30:06 1998
--- linuxvme-2.1.90/drivers/char/mem.c	Wed Apr  1 21:43:15 1998
***************
*** 150,155 ****
--- 150,182 ----
  	return 0;
  }
  
+ static int mmap_memnc(struct file * file, struct vm_area_struct * vma)
+ {
+ 	unsigned long offset = vma->vm_offset;
+ 
+ 	if (offset & ~PAGE_MASK)
+ 		return -ENXIO;
+ #if defined(__mc68000__)
+ 	if (CPU_IS_020_OR_030)
+ 		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
+ 	if (CPU_IS_040_OR_060) {
+ 		pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
+ 		/* Use no-cache mode, serialized */
+ 		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
+ 	}
+ #elif defined(__powerpc__)
+ 	pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
+ #else
+ 	/* What do we have to do here?? */
+ #endif
+ 	if (remap_page_range(vma->vm_start, offset,
vma->vm_end-vma->vm_start,
+ 			     vma->vm_page_prot))
+ 		return -EAGAIN;
+ 	vma->vm_file = file;
+ 	file->f_count++;
+ 	return 0;
+ }
+ 
  /*
   * This function reads the *virtual* memory as seen by the kernel.
   */
***************
*** 417,422 ****
--- 444,462 ----
  	NULL		/* fsync */
  };
  
+ static struct file_operations memnc_fops = {
+ 	NULL,
+ 	NULL,
+ 	NULL,
+ 	NULL,		/* mem_readdir */
+ 	NULL,		/* mem_poll */
+ 	NULL,		/* mem_ioctl */
+ 	mmap_memnc,
+ 	NULL,		/* no special open code */
+ 	NULL,		/* no special release code */
+ 	NULL		/* fsync */
+ };
+ 
  static struct file_operations kmem_fops = {
  	memory_lseek,
  	read_kmem,
***************
*** 506,511 ****
--- 546,554 ----
  			break;
  		case 9:
  			filp->f_op = &urandom_fops;
+ 			break;
+ 		case 10:
+ 			filp->f_op = &memnc_fops;
  			break;
  		default:
  			return -ENXIO;
