Resent-Date: Sat, 28 Nov 1998 09:52:39 +0100 (MET)
Date: Sat, 28 Nov 1998 08:52:34 GMT
From: Jesper Skov <jskov@cygnus.co.uk>
To: linux-m68k@lists.linux-m68k.org
Subject: z2ram diff
Resent-From: linux-m68k@phil.uni-sb.de

Below some changes to z2ram, allowing any given mem_list entry to be
used for swap. Handy on APUS where only entry0 is actually used by the
system.

I think I saw a don't-use-Z3-mem option added to Linux/m68k recently,
so this might also be useful for m68k?!?

Jesper

--- /home/jskov/kernel/dist/linux-2.1.130/drivers/block/z2ram.c	Fri Aug 28 20:31:19 1998
+++ z2ram.c	Sat Nov 28 09:23:11 1998
@@ -14,6 +14,8 @@
 **          37     0       Use Zorro II and Chip ram
 **          37     1       Use only Zorro II ram
 **          37     2       Use only Chip ram
+**          37     4-7     Use memory list entry 1-4 (first is 0)
+** ++jskov: support for 1-4th memory list entry.
 **
 ** Permission to use, copy, modify, and distribute this software and its
 ** documentation for any purpose and without fee is hereby granted, provided
@@ -37,23 +39,37 @@
 #include <asm/setup.h>
 #include <asm/bitops.h>
 #include <asm/amigahw.h>
+#ifdef CONFIG_APUS
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#endif
 #include <linux/zorro.h>
 
+
+extern int num_memory;
+extern struct mem_info memory[NUM_MEMINFO];
+
 #define TRUE                  (1)
 #define FALSE                 (0)
 
 #define Z2MINOR_COMBINED      (0)
 #define Z2MINOR_Z2ONLY        (1)
 #define Z2MINOR_CHIPONLY      (2)
+#define Z2MINOR_MEMLIST1      (4)
+#define Z2MINOR_MEMLIST2      (5)
+#define Z2MINOR_MEMLIST3      (6)
+#define Z2MINOR_MEMLIST4      (7)
+#define Z2MINOR_COUNT         (8) /* Move this down when adding a new minor */
 
 #define Z2RAM_CHUNK1024       ( Z2RAM_CHUNKSIZE >> 10 )
 
 static u_long *z2ram_map    = NULL;
 static u_long z2ram_size    = 0;
-static int z2_blocksizes[3] = { 1024, 1024, 1024 };
-static int z2_sizes[3]      = {    0,    0,    0 };
+static int z2_blocksizes[Z2MINOR_COUNT];
+static int z2_sizes[Z2MINOR_COUNT];
 static int z2_count         = 0;
 static int chip_count       = 0;
+static int list_count       = 0;
 static int current_device   = -1;
 
 static void
@@ -166,8 +182,61 @@
     {
 	z2_count   = 0;
 	chip_count = 0;
+	list_count = 0;
 	z2ram_size = 0;
 
+	/* Use a specific list entry. */
+	if (device >= Z2MINOR_MEMLIST1 && device <= Z2MINOR_MEMLIST4) {
+		int index = device - Z2MINOR_MEMLIST1 + 1;
+		unsigned long size, paddr, vaddr;
+
+		if (index >= num_memory) {
+			printk( KERN_ERR DEVICE_NAME
+				": no such entry in z2ram_map\n" );
+			return -ENOMEM;
+		}
+
+		paddr = memory[index].addr;
+		size = memory[index].size & ~(Z2RAM_CHUNKSIZE-1);
+
+#ifdef __powerpc__
+		/* FIXME: ioremap doesn't build correct memory tables. */
+		{
+			extern void* vmalloc (unsigned long);
+			extern void vfree (void*);
+			vfree(vmalloc (size));
+		}
+
+		vaddr = (unsigned long) __ioremap (paddr, size, 
+						   _PAGE_WRITETHRU);
+
+#else
+		vaddr = kernel_map (paddr, size, KERNELMAP_FULL_CACHING,
+				    NULL);
+#endif
+		z2ram_map = 
+			kmalloc((size/Z2RAM_CHUNKSIZE)*sizeof(z2ram_map[0]),
+				GFP_KERNEL);
+		if ( z2ram_map == NULL )
+		{
+		    printk( KERN_ERR DEVICE_NAME
+			": cannot get mem for z2ram_map\n" );
+		    return -ENOMEM;
+		}
+
+		while (size) {
+			z2ram_map[ z2ram_size++ ] = vaddr;
+			size -= Z2RAM_CHUNKSIZE;
+			vaddr += Z2RAM_CHUNKSIZE;
+			list_count++;
+		}
+
+		if ( z2ram_size != 0 )
+		    printk( KERN_INFO DEVICE_NAME
+			": using %iK List Entry %d Memory\n",
+			list_count * Z2RAM_CHUNK1024, index );
+	} else
+
 	switch ( device )
 	{
 	    case Z2MINOR_COMBINED:
@@ -253,12 +322,11 @@
     return 0;
 }
 
-static void 
+static int
 z2_release( struct inode *inode, struct file *filp )
 {
-
     if ( current_device == -1 )
-	return;     
+	return 0;     
 
     sync_dev( inode->i_rdev );
 
@@ -266,7 +334,7 @@
     MOD_DEC_USE_COUNT;
 #endif
 
-    return;
+    return 0;
 }
 
 static struct file_operations z2_fops =
@@ -281,7 +349,10 @@
 	z2_open,                /* open */
 	NULL,			/* flush */
 	z2_release,             /* release */
-	block_fsync             /* fsync */
+	block_fsync,            /* fsync */
+	NULL,			/* fasync */
+	NULL,			/* check_media_change */
+	NULL,			/* revalidate */
 };
 
 __initfunc(int
@@ -297,6 +368,16 @@
 	    MAJOR_NR );
 	return -EBUSY;
     }
+
+    {
+	    /* Initialize size arrays. */
+	    int i;
+
+	    for (i = 0; i < Z2MINOR_COUNT; i++) {
+		    z2_blocksizes[ i ] = 1024;
+		    z2_sizes[ i ] = 0;
+	    }
+    }    
    
     blk_dev[ MAJOR_NR ].request_fn = DEVICE_REQUEST;
     blksize_size[ MAJOR_NR ] = z2_blocksizes;

