diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/cio_mem_mgr.c rtai-24.1.9-cio-1.3/cio_mem_mgr/cio_mem_mgr.c
--- rtai-24.1.9/cio_mem_mgr/cio_mem_mgr.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/cio_mem_mgr.c	2007-06-19 15:40:07.000000000 +0200
@@ -0,0 +1,1149 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+//      Copyright (©) 2001 Christian Charreyre (CIO Informatique Industrielle),
+//
+// Authors:             Christian Charreyre (CIO Informatique Industrielle)
+//
+// Original date:       Wed 16 May 2001
+//
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+//
+// Dynamic Memory Management for Real Time Linux, with possibility to allocate
+// and free memory after entering the reat time task (rt_task_init).
+//
+// Based on the original rt-mem-mgr and shmem memory allocators found in the
+//	RTAI distribution
+//
+///////////////////////////////////////////////////////////////////////////////
+static char id_rt_mem_mgr_c[] __attribute__ ((unused)) = "@(#)$Id: cio_mem_mgr.c,v 1.3 2002/01/04 16:31:50 stevep Exp $";
+
+/* CIO-DCH RTAI-CT must be undefined here only for this source */
+#undef __NO_VERSION__
+/* END CIO-DCH RTAI-CT must be undefined here only for this source */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#ifndef CONFIG_RTAI_MM_VMALLOC
+  #include <linux/slab.h>
+#else
+  #include <linux/vmalloc.h>
+  #include "../shmem/kvmem.h"
+#endif
+#include <linux/errno.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/wrapper.h>
+
+#ifdef CONFIG_PROC_FS
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+#endif
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <asm/rtai.h>
+#include <rtai_shm.h>
+#include <rtai_proc_fs.h>
+#include <rtai_fifos.h>
+#include <rt_mem_mgr.h>
+
+#include "cio_mem_mgr.h"
+#include <rtai_trace.h>
+
+//#if LINUX_EXT_VERSION_CODE < KERNEL_EXT_VERSION(2,4,0,4)
+//#include "rtai_bttv.h"
+//#else
+#include "kvmem.h"
+#include "kvmem.c"
+//#endif
+
+// ------------------------------< definitions >-------------------------------
+
+#ifdef DEBUG
+static int closable;
+static int echo;
+#endif
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define OVERHEAD (sizeof(struct chkhdr) + sizeof(struct blkhdr))
+
+#define MINSIZE PAGE_SIZE
+#define MAX_SLOTS            256  	// Set it according to your needs.
+#define MAX_SLOTS_PROC	64	// Max number of blocks displayed in one interface
+#define MAX_OWNERS           4*MAX_SLOTS // avrg 4 simultaneous users per slot!
+#define CIO_SHM_MISC_MINOR  253 // The same minor used to mknod for major 10.
+
+/* The two lines below could go into a structure. It is preferred
+   to keep them distinct to recall that a vmarea pertains only to
+   processes allocated/mmaped areas, and not to module ones. */
+
+static unsigned long long name_pid_list[MAX_OWNERS + 1] = { 0LL, };
+static struct vm_area_struct *vmarea[MAX_OWNERS + 1]   = { 0, };
+
+static struct { void *adr; unsigned long name, size, count; } shm_list[MAX_SLOTS + 1] = { {0, 0, 0, 0}, };
+
+static unsigned long owner_max = 0;
+static unsigned long slot_max = 0;
+
+//#ifdef __SMP__
+//static spinlock_t shm_lock = SPIN_LOCK_UNLOCKED;
+//#endif
+
+#define NAME(x) ((unsigned long *)(&(x)))[0]
+#define PID(x)  ((unsigned long *)(&(x)))[1]
+
+// Chunk of contiguous memory.
+struct chkhdr {
+  void *chk_addr;                    // Address of chunk.
+  struct chkhdr *next_chk;           // 0 if none.
+  unsigned int chk_limit;            // Size of chunk.
+  struct blkhdr *free_list;          // 1st free object in chunk, NULL if none.
+  char dummy[MINSIZE - 16];
+  char data[0];
+};
+
+
+// Block header for management within a chunk.
+struct blkhdr {
+  void *chk_addr;                    // Address of owner chunk.
+  struct blkhdr *next_free;          // SELF if not free, NULL if end of list.
+  unsigned int free_size;
+  char dummy[MINSIZE-12];
+  char data[0];
+};
+
+enum mem_cmd { chk_alloc, chk_free };
+
+
+
+// ----------------------------------------------------------------------------
+//      Local Definitions.
+// ----------------------------------------------------------------------------
+static void *alloc_in_chk(unsigned int size, struct chkhdr *chk);
+void rt_mmgr_dump(void);
+
+// ----------------------------------------------------------------------------
+//      Package Global Data.
+// ----------------------------------------------------------------------------
+char cio_mem_mgr_version[] = "1.3";
+unsigned int granularity = 0x200000;
+//int low_chk_ref = 1;
+unsigned int low_data_mark = 0x2000; // Enough to allocate a dynamic task.
+int extra_chks;
+unsigned int max_allocated = 0;
+unsigned int total_available = 0;
+unsigned int kmalloc_calls = 0;
+unsigned int kfree_calls = 0;
+unsigned int memory_leak = 0;
+unsigned int memory_overhead = 0;
+int sysrq_cmd_err = 0;
+int cio_mem_mgr_init_done = 0;
+struct chkhdr *chk_list = NULL;
+struct { int srq, no_chk; spinlock_t srq_lock; } alloc_sysrq;
+struct { int srq, no_chk; spinlock_t srq_lock; } free_sysrq;
+spinlock_t rt_mem_lock;
+
+
+// ----------------------------------------------------------------------------
+
+#ifdef __CIO_SHM_USE_VECTOR
+static struct desc_struct sidt;
+
+
+// -----------------------< Name management section >------------------------
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
+static void cio_shm_handler(void)
+{
+                 __asm__ __volatile__ (" \
+	cld; pushl %es; pushl %ds; pushl %ebp;\n\t \
+	pushl %edi; pushl %esi; pushl %ecx;\n\t \
+	pushl %ebx; pushl %edx; pushl %eax;\n\t \
+	movl $" STR(__KERNEL_DS) ",%ebx; mov %bx,%ds; mov %bx,%es");
+
+	__asm__ __volatile__ ("call "SYMBOL_NAME_STR(cio_handler));
+
+	__asm__ __volatile__ (" \
+	addl $8,%esp; popl %ebx; popl %ecx; popl %esi;\n\t \
+	popl %edi; popl %ebp; popl %ds; popl %es; iret");         
+}
+#endif // __CIO_SHM_USE_VECTOR
+
+
+static inline int registr(unsigned long long name_pid)
+{
+	int owner;
+	for (owner = 1; owner <= MAX_OWNERS; owner++) {
+		if (!name_pid_list[owner]) {
+			name_pid_list[owner] = name_pid;
+			vmarea[owner] = (struct vm_area_struct *)(PID(name_pid) | 0xF0000000);
+			if (owner > owner_max)
+				owner_max = owner;
+			return owner;
+		}
+	}
+	return 0;
+}
+
+static inline int deregistr(unsigned long long name_pid)
+{
+	int owner;
+	for (owner = 1; owner <= MAX_OWNERS; owner++) {
+		if (name_pid_list[owner] == name_pid) {
+			name_pid_list[owner] = 0LL;
+			vmarea[owner] = 0;
+			return owner;
+		}
+	}
+	return 0;
+}
+
+static inline int there_is_not_and_reg(unsigned long long name_pid)
+{
+	int owner;
+  	char *func __attribute__ ((unused)) = "there_is_not_and_reg";
+
+ 	DBG("%s - name 0x%p, pid 0x%p\n", func, NAME(name_pid), PID(name_pid));
+	for (owner = 1; owner <= MAX_OWNERS; owner++) {
+		if (name_pid_list[owner] == name_pid) {
+			return 0;
+		}
+	}
+	return registr(name_pid);
+}
+
+static inline int find_name(unsigned long name)
+{
+	int slot;
+	for (slot = 1; slot <= MAX_SLOTS; slot++) {
+		if (shm_list[slot].name == name) {
+			return slot;
+		}
+	}
+	return 0;
+}
+
+static inline int find_name_and_reg(unsigned long name, unsigned long pid)
+{
+	int slot;
+	unsigned long long name_pid;
+  	char *func __attribute__ ((unused)) = "find_name_and_reg";
+ 	
+ 	DBG("%s - name 0x%x, pid 0x%p\n", func, name, pid);
+	for (slot = 1; slot <= MAX_SLOTS; slot++) {
+		if (shm_list[slot].name == name) {
+			NAME(name_pid) = name;
+			PID(name_pid)  = pid;
+			return there_is_not_and_reg(name_pid) ? slot : 0;
+		}
+	}
+	return 0;
+}
+
+static inline int find_free_slot_and_reg(unsigned long name, unsigned long pid)
+{
+	int slot;
+	unsigned long long name_pid;
+  	char *func __attribute__ ((unused)) = "find_free_slot_and_reg";
+
+ 	DBG("%s - name 0x%x, pid 0x%p\n", func, name, pid);
+	for (slot = 1; slot <= MAX_SLOTS; slot++) {
+		if (!shm_list[slot].name) {
+			NAME(name_pid) = name;
+			PID(name_pid)  = pid;
+			return there_is_not_and_reg(name_pid) ? slot : 0;
+		}
+	}
+	return 0;
+}
+
+static inline int find_name_and_drg(unsigned long name, unsigned long pid)
+{
+	int slot;
+	unsigned long long name_pid;
+	for (slot = 1; slot <= MAX_SLOTS; slot++) {
+		if (shm_list[slot].name == name) {
+			NAME(name_pid) = name;
+			PID(name_pid)  = pid;
+			return deregistr(name_pid) ? slot : 0;
+		}
+	}
+	return 0;
+}
+
+
+// -----------------------< Memory management section >------------------------
+void *cio_kmalloc_f(int name, unsigned int size, unsigned long pid)
+{
+
+  unsigned long flags;
+  void *mem_ptr = NULL;
+  struct chkhdr *chk_list_ptr;
+  char *func __attribute__ ((unused)) = "cio_kmalloc_f";
+  int slot;
+
+  DBG("%s - Try to allocate 0x%x bytes from process 0x%x with name 0x%x.\n", func, size, pid, name);
+
+  if (size <= 0) {
+     return NULL;
+  }
+  
+  TRACE_RTAI_SHM(TRACE_RTAI_EV_CIO_SHM_KMALLOC, name, size, pid);
+  
+  size = (size + (MINSIZE - 1)) & ~(MINSIZE - 1);   // Round size to multiple of MINSIZE
+
+  if(size > granularity - OVERHEAD) {
+    DBG("%s - Cannot allocate %d bytes, too large.\n", func, size);
+    DBG("\n");
+    return(NULL);
+  }
+
+//	spin_lock_irqsave(&shm_lock, flags);
+	if ((slot = find_name_and_reg(name, pid))) {
+		shm_list[slot].count++;
+		MOD_INC_USE_COUNT;
+		mem_ptr = shm_list[slot].adr;
+//		spin_unlock_irqrestore(&shm_lock, flags);
+		if (size >  shm_list[slot].size)	{
+    			DBG("%s - Too big size for name 0x%x - Return 0x0\n", func, name);
+      			return (NULL);
+      		}
+		DBG("%s - Name 0x%x already allocated - Return @ %p.\n", func, name, mem_ptr);
+		return mem_ptr;
+	}
+
+//      Check if there is enough space to allocate requested size
+  if((total_available - (memory_leak + memory_overhead) - (size + sizeof(struct blkhdr))) <= 0) {
+      DBG("%s - No space left in chunk, try to increase granularity.\n", func);
+      return (NULL);
+  }  // End if
+
+  chk_list_ptr = chk_list;
+  flags = rt_spin_lock_irqsave(&rt_mem_lock);
+  chk_list_ptr = chk_list;
+
+  if(chk_list_ptr->free_list != NULL) {
+  		if((mem_ptr = alloc_in_chk(size, chk_list_ptr)) != NULL) {
+			if ((slot = find_free_slot_and_reg(name, pid))) {
+				DBG("%s - Name 0x%x registered in slot %d - @ %p\n", func, name, slot, mem_ptr);
+				memset(mem_ptr, 0, size);
+				shm_list[slot].name  = name;
+				shm_list[slot].adr   = mem_ptr;
+				shm_list[slot].size  = size;
+				shm_list[slot].count = 1;
+				if (slot > slot_max)
+					slot_max = slot;
+				
+				MOD_INC_USE_COUNT;
+				rt_spin_unlock_irqrestore(flags, &rt_mem_lock);
+				return mem_ptr;
+			}
+   		mem_ptr = NULL;
+      }  // End if - Allocated a block okay.
+
+      DBG("%s - Insufficient free memory in chunk %p, or name and pid already registered\n",
+                               func, chk_list_ptr);
+  }  // End if - Chunk is not full
+
+
+
+  rt_spin_unlock_irqrestore(flags, &rt_mem_lock);
+  return(mem_ptr);
+
+}  // End function - rt_malloc
+
+
+void cio_kfree_f(int name, unsigned long pid)
+{
+
+  unsigned int flags;
+  struct chkhdr *chk_ptr;
+  struct blkhdr *blk_ptr, *cur_blk_ptr, *prev_blk_ptr;
+  char *func __attribute__ ((unused)) = "cio_kfree_f";
+  void *addr;
+  int slot;
+  
+  	TRACE_RTAI_SHM(TRACE_RTAI_EV_CIO_SHM_KFREE, name, 0, pid);
+
+        if ((slot = find_name_and_drg(name, pid)))
+        {
+                MOD_DEC_USE_COUNT;
+                if ((--shm_list[slot].count) > 0)
+                {   // There is still links on address
+                         return;
+                }
+
+        }
+        else
+        {                                                                          // Name not found
+                DBG("%s - Attempt to free corrupt heap (name = 0x%x)\n", func, name);
+        }
+
+        addr =  shm_list[slot].adr;
+        shm_list[slot] = shm_list[0];
+
+// Get the block and chunk headers for the block.
+  blk_ptr = (struct blkhdr *)(addr - sizeof(struct blkhdr));
+  chk_ptr = blk_ptr->chk_addr;
+
+// Make sure that it is valid block.
+  if(blk_ptr->chk_addr != chk_ptr->chk_addr ||
+     blk_ptr->next_free != blk_ptr ||
+     ((unsigned)(blk_ptr->free_size) == 0) ||
+     ((unsigned)(blk_ptr->free_size) > (granularity - OVERHEAD)) ||
+     (unsigned)(blk_ptr->free_size) % MINSIZE != 0)
+  {
+    DBG("%s - Attempt to free corrupt heap at 0x%p.\n", func, addr);
+  }
+  else
+  {
+    DBG("%s - Request to free block at 0x%p from chunk 0x%p.\n",
+                                                       func, addr, chk_ptr);
+    DBG("%s - 1st free block in chunk is 0x%p\n", func, chk_ptr->free_list);
+    flags = rt_spin_lock_irqsave(&rt_mem_lock);
+    cur_blk_ptr = chk_ptr->free_list;
+    prev_blk_ptr = NULL;
+
+// Find a previous free block to link into the free list.
+    while(cur_blk_ptr != NULL && cur_blk_ptr->data < (char *)addr)
+    {
+      prev_blk_ptr = cur_blk_ptr;
+      cur_blk_ptr = cur_blk_ptr->next_free;
+    }  // End while loop - find previous free block
+    DBG("%s - Exit from while loop - cur_blk_ptr 0x%p prev_blk_ptr 0x%p\n",
+                                             func, cur_blk_ptr, prev_blk_ptr);
+    memory_leak -= blk_ptr->free_size;
+
+// If the previous free block is contiguous merge them.
+    if((prev_blk_ptr != NULL) && ((struct blkhdr *)(prev_blk_ptr->data +
+                                      prev_blk_ptr->free_size) == blk_ptr))
+    {
+
+      prev_blk_ptr->free_size += blk_ptr->free_size + sizeof(struct blkhdr);
+      blk_ptr = prev_blk_ptr;
+      memory_overhead -= sizeof(struct blkhdr);
+      DBG("%s - Merging free block with previous block at 0x%p.\n",
+                                                          func, prev_blk_ptr);
+
+    // Or, insert a new free block.
+    }
+    else if(prev_blk_ptr != NULL)
+    {
+      blk_ptr->next_free = prev_blk_ptr->next_free;
+      prev_blk_ptr->next_free = blk_ptr;
+
+    // Or, add first free block.
+    }
+    else
+    {
+      blk_ptr->next_free = chk_ptr->free_list;
+      chk_ptr->free_list = blk_ptr;
+    }  // End if else - previous block is not contiguous
+
+// If the following free block is contiguous merge them.
+    if((struct blkhdr *)(blk_ptr->data + blk_ptr->free_size)
+                                         == blk_ptr->next_free)
+    {
+
+      DBG("%s - Merging free block with following block at 0x%p.\n",
+                                             func, blk_ptr->next_free);
+      memory_overhead -= sizeof(struct blkhdr);
+      blk_ptr->free_size += blk_ptr->next_free->free_size +
+                                                    sizeof(struct blkhdr);
+      blk_ptr->next_free = blk_ptr->next_free->next_free;
+
+    }  // End if - following block is free
+
+    rt_spin_unlock_irqrestore(flags, &rt_mem_lock);
+  }  // End if else - Valid block to free
+
+}  // End function - rt_free
+
+
+// This function tries to find size free bytes in the current chunk.
+static void *alloc_in_chk(unsigned int size, struct chkhdr *chk)
+{
+
+  void *mem_ptr = NULL;
+  struct blkhdr *cur, *prev = NULL, *next;
+  char *func __attribute__ ((unused)) = "alloc_in_chk";
+
+  cur = chk->free_list;
+  DBG("%s - Allocating block of %d bytes at %p - Remaining size 0x%x - Next free 0x%p\n",
+  				func, size, cur->data, cur->free_size, cur->next_free);
+
+  for(; cur != NULL; prev = cur, cur = cur->next_free)
+  {
+
+// Check the free block is large enough.
+    if(cur->free_size >= size)
+    {
+
+      DBG("%s - Allocating block at %p\n", func, cur->data);
+
+// Calculate the next free block in the chunk.
+      if(cur->free_size - size >= sizeof(struct blkhdr) + MINSIZE)
+      {
+        next = (struct blkhdr *)(cur->data + size);
+        next->chk_addr = chk->chk_addr;
+        next->next_free = cur->next_free;
+        next->free_size = cur->free_size - (size + sizeof(struct blkhdr));
+        memory_overhead += sizeof(struct blkhdr);
+      }
+      else
+      {
+
+// We get here if there isn't enough free contiguous free
+// memory left in this chunk for another block.
+        next = cur->next_free;  // NB: This is NULL for last block in list
+        DBG("%s - No space left in chunk 0x%p\ncur->free_size = 0x%x - size = 0x%x, limit = 0x%x\n",
+        			func, chk, cur->free_size, size, sizeof(struct blkhdr) + MINSIZE);
+      }  // End if else - determine next free block
+
+// Remove the block from the free list.
+      if(prev == NULL)
+      {
+        chk->free_list = next;
+      }
+      else
+      {
+        prev->next_free = next;
+      }  // End if else - First time through the loop.
+
+      DBG("%s - Next free block at %p\n", func, next);
+      cur->next_free = cur;
+      cur->free_size = size;
+      mem_ptr = cur->data;
+      break;
+    }  // End if - free block large enough
+  }
+
+  if(mem_ptr != NULL)
+  {
+    memory_leak += size;
+    if(memory_leak > max_allocated)
+    {
+      max_allocated = memory_leak;
+    }
+  }
+  return(mem_ptr);
+
+}  // End function - alloc_in_chk
+
+
+// ---------------------< End memory management section >----------------------
+// -----------------------< Process services section >------------------------
+long long cio_handler(unsigned int srq, unsigned long name);
+
+static int cio_shm_f_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	return cio_handler(cmd,arg);
+}
+long long cio_handler(unsigned int srq, unsigned long name)
+{
+	static void cio_shm_vm_close(struct vm_area_struct *vma);
+	int owner, slot;
+	long long name_pid;
+	char *func __attribute__ ((unused)) = "cio_handler";
+	
+	DBG("%s - Request %d received\n",   func, srq);
+	
+	switch (srq) {
+		case 1:
+		   TRACE_RTAI_SHM(TRACE_RTAI_EV_CIO_SHM_MALLOC, name, srq, current->pid);
+			if (cio_kmalloc_f(((unsigned long *)name)[0], ((unsigned long *)name)[1], current->pid)) {
+				return shm_list[find_name(((unsigned long *)name)[0])].size;
+			}
+			return 0;
+		case 2:
+			NAME(name_pid) = name;
+			PID(name_pid)  = current->pid;
+		   TRACE_RTAI_SHM(TRACE_RTAI_EV_CIO_SHM_GET_SIZE, name, srq, current->pid);
+			for (owner = 1; owner <= MAX_OWNERS; owner++) {
+				if (name_pid_list[owner] == name_pid) {
+					if (vmarea[owner] && (vmarea[owner]->vm_ops)->close == cio_shm_vm_close) {
+						vmarea[owner]->vm_ops = 0;
+						if ((slot = find_name(name))) {
+							DBG("%s - Request 2 returns size 0x%x\n",   func, shm_list[slot].size);
+							return shm_list[slot].size;
+						}
+					}
+					DBG("%s - VMAREA NOT FOUND FOR AN EXISTING NAME_PID AT UNMAP REQUEST.\n", func);
+					return 0;
+				}
+			}
+			return 0;
+		case 3:
+		        TRACE_RTAI_SHM(TRACE_RTAI_EV_CIO_SHM_FREE, name, srq, current->pid);
+			DBG("%s - Free bloc named 0x%x for pid 0x%x\n",   func, name, current->pid);
+			cio_kfree_f(name, current->pid);
+			return 0;
+#ifdef DEBUG
+// all what's below, in this function, is just for testing
+
+		case 4:
+			if ((slot = find_name(name))) {
+			return shm_list[slot].count > 1 ? shm_list[slot].size : - shm_list[slot].size;
+			}
+			return 0;
+		case 5:
+			if ((slot = find_name(name))) {
+				int *adr;
+				adr = shm_list[slot].adr;
+				DBG("ECHO FOR %lx FROM SHM MODULE %d\n", name, adr[0]);
+				echo += 2;
+				memset(shm_list[slot].adr, echo, shm_list[slot].size);
+				DBG("SHM MODULE WILL CHANGE %lx TO %d\n", name, adr[0]);
+
+				slot = find_name(0xaaaa);
+				adr = shm_list[slot].adr;
+				DBG("ECHO FOR %x FROM SHM MODULE %d\n", 0xaaaa, adr[0]);
+				echo += 2;
+				memset(shm_list[slot].adr, echo, shm_list[slot].size);
+				DBG("SHM MODULE WILL CHANGE %x TO %d\n", 0xaaaa, adr[0]);
+			}
+			return 0;
+		case 6:
+			return closable;
+		case 7:
+			return (closable = 1);
+		case 8:
+			return (closable = 0);
+#endif
+
+	}
+	return 0;
+}
+
+static void cio_shm_vm_close(struct vm_area_struct *vma)
+{
+	char *func __attribute__ ((unused)) = "cio_shm_vm_close";
+	int owner, slot;
+	for (owner = 1; owner <= MAX_OWNERS; owner++) {
+		if (vmarea[owner] == vma && PID(name_pid_list[owner]) == current->pid) {
+			if((slot = find_name(NAME(name_pid_list[owner])))) {
+				if (shm_list[slot].count == 1) {
+					DBG("%s - DELETING AREA 0x%lx AT KERNEL REQUEST (pid = 0x%x).\n", func, shm_list[slot].name, current->pid);
+				} else {
+					DBG("%s - UNMAPPING AREA 0x%lx AT KERNEL REQUEST (pid = 0x%x).\n", func, shm_list[slot].name, current->pid);
+				}
+				cio_kfree_f(shm_list[slot].name, current->pid);
+				return;
+			}
+			DBG("%s - NO AREA NAME FOUND FOR AN EXISTING PID_VMA AT KERNEL UNMAP REQUEST (name = 0x%x, pid = 0x%x).\n", func, NAME(name_pid_list[owner]), current->pid);
+			return;
+		}
+	}
+	DBG("%s - NO PID_VMA FOUND AT KERNEL UNMAP REQUEST (vma = %p, pid = 0x%x).\n", func, vma, current->pid);
+	return;
+}
+
+struct vm_operations_struct cio_shm_vm_ops = { close: cio_shm_vm_close } ;
+
+static int cio_shm_mmap(struct file *file, struct vm_area_struct *vma)
+{
+  char *func __attribute__ ((unused)) = "cio_shm_mmap";
+	int owner, slot;
+
+        DBG("%s - Entering mmap function - Pid = 0x%x\n", func, current->pid);
+	for (owner = 1; owner <= MAX_OWNERS; owner++) {
+		if (PID(name_pid_list[owner]) == current->pid && vmarea[owner] == ((struct vm_area_struct *)(current->pid | 0xF0000000))) {
+			if((slot = find_name(NAME(name_pid_list[owner])))) {
+				vmarea[owner] = vma;
+        			DBG("%s - Vma 0x%x registered at owner slot %d\n", func, vma, owner);
+				if(!vma->vm_ops) {
+					vma->vm_ops = &cio_shm_vm_ops;
+				}
+				DBG("%s - Found block of size 0x%x at @ 0x%x\n", func, shm_list[slot].size, shm_list[slot].adr);
+				DBG("%s - vma->vm_ops = 0x%x and  cio_shm_vm_ops = 0x%x\n", func, vma->vm_ops, &cio_shm_vm_ops);
+				return rvmmap(shm_list[slot].adr, shm_list[slot].size, vma);
+			}
+			DBG("%s - NO AREA NAME FOUND FOR A MAPPABLE PID AT MMAPP REQUEST.\n", func);
+			DBG("%s - Leaving mmap function because found no area name\n", func);
+			return -EFAULT;
+		}
+	}
+	DBG("%s - NO MAPPABLE PID FOUND AT MMAPP REQUEST.\n", func);
+	DBG("%s - Leaving mmap function because found no mappable pid\n", func);
+	return -EFAULT;
+}
+
+static int cio_shm_f_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int cio_shm_f_close(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static struct file_operations cio_shm_fops =
+	{ 
+//#if LINUX_EXT_VERSION_CODE >= KERNEL_EXT_VERSION(2,4,0,4)
+	owner:		THIS_MODULE,
+//#endif
+
+	mmap:cio_shm_mmap, 
+	open: cio_shm_f_open, 
+	release: cio_shm_f_close,
+	ioctl: cio_shm_f_ioctl
+	};
+
+static struct miscdevice cio_shm_dev =
+	{ CIO_SHM_MISC_MINOR, "CIO_SHM", &cio_shm_fops, NULL, NULL };
+
+
+// ------------------------< proc filesystem section >-------------------------
+#ifdef CONFIG_PROC_FS
+
+static int chunk_read_proc(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+{
+  PROC_PRINT_VARS;
+  int i = 0;
+  struct chkhdr *chk_ptr;
+  struct blkhdr *blk_ptr, *last;
+  char free[5];
+
+
+  PROC_PRINT("\nCIO  Dynamic Memory Management Chunk Status\n");
+  PROC_PRINT("-------------------------------------------\n\n");
+  PROC_PRINT("Block header Free Data address Block size\n");
+  PROC_PRINT("-----------------------------------------\n");
+
+  for (i=0; i< MAX_SLOTS; i++)
+  {
+    if (shm_list[i].adr)
+    {
+  		blk_ptr = (struct blkhdr *)(shm_list[i].adr - (sizeof(struct blkhdr)));
+  		chk_ptr = (struct chkhdr *)blk_ptr->chk_addr;
+  		(void *)last = (void *)chk_ptr + (chk_ptr->chk_limit - sizeof(struct blkhdr) - MINSIZE);
+
+
+	 do {
+
+		if(blk_ptr == blk_ptr->next_free) {
+      	strncpy(free, "Used", strlen("Used")+1);
+    	} else { // End if - Don't display free blocks.
+      	strncpy(free, "Free", strlen("Free")+1);
+    	}
+
+   		PROC_PRINT("0x%p   %s  0x%p   0x%x\n",
+                        blk_ptr, free, &blk_ptr->data, blk_ptr->free_size);
+
+    	(void *)blk_ptr = (void *)blk_ptr + sizeof(struct blkhdr) +
+                                              blk_ptr->free_size;
+
+  		} while(blk_ptr < last); // End do loop - display all allocated blocks in the chunk.
+
+    }
+  }
+
+  PROC_PRINT_DONE;
+
+}       // End function - chunk_read_proc
+
+
+
+
+static int block_read_proc(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+//char *buf, char **start, off_t offset, int len, int unused, int iProc)
+{
+  PROC_PRINT_VARS;
+
+  int i = 0;
+  struct chkhdr *chk_ptr;
+  char strName [ 16 ];
+  int iProc;
+  
+  iProc = (int)data;
+
+  PROC_PRINT("\nCIO Dynamic Memory Management Blocks Status\n");
+  PROC_PRINT(  "-------------------------------------------\n\n");
+
+  PROC_PRINT("Max. slot reached : %ld\n\n", slot_max);
+
+  PROC_PRINT("Chunk Size    Address    1st free block  Remaining\n");
+  PROC_PRINT("--------------------------------------------------\n");
+
+  for(chk_ptr = chk_list; chk_ptr != NULL; chk_ptr = chk_ptr->next_chk) {
+/*    if(chk_ptr->free_list == NULL) { // Needed to avoid possible Oops :-(
+      chk_free = 0;
+    } else {
+      chk_free = chk_ptr->free_list->free_size;
+    }  */
+    PROC_PRINT("%-5d %-5d 0x%-8p 0x%-15p %d\n",
+                   i,
+                   chk_ptr->chk_limit,
+                   chk_ptr->chk_addr,
+                   chk_ptr->free_list,
+                   total_available - memory_leak - memory_overhead);
+    i += 1;
+  } // End for loop - Display data for all chunks.
+
+  PROC_PRINT("\n\nSlot  Name       Name   Size       Address   Count\n");
+  PROC_PRINT(    "--------------------------------------------------\n");
+  for (i=iProc*MAX_SLOTS_PROC;  ( i< (iProc+1)*MAX_SLOTS_PROC) && (i<MAX_SLOTS) ; i++)
+  {
+  		if (shm_list[i].name != 0)
+     		num2nam(shm_list[i].name, strName);
+     	else
+     		strcpy (strName, "      ");
+
+     	PROC_PRINT("%-4d  0x%-8p %-6s 0x%-8p 0x%-8p %-4ld\n",
+                   i,
+                   (void*)shm_list[i].name,
+                   strName,
+                   (void*)shm_list[i].size,
+                   shm_list[i].adr,
+                   shm_list[i].count);
+
+  }
+
+  PROC_PRINT_DONE;
+
+}       // End function - block_read_proc
+
+static int block_read_proc_0(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+{
+	return( block_read_proc( page, start, off, count, eof, (void *)0 ) );
+}
+
+static int block_read_proc_1(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+{
+	return( block_read_proc( page, start, off, count, eof, (void *)1 ) );
+}
+
+static int block_read_proc_2(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+{
+	return( block_read_proc( page, start, off, count, eof, (void *)2 ) );
+}
+
+static int block_read_proc_3(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+{
+	return( block_read_proc( page, start, off, count, eof, (void *)3 ) );
+}
+
+static int owner_read_proc(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+{
+  PROC_PRINT_VARS;
+
+  int i = 0;
+  char strName [ 16 ];
+
+  PROC_PRINT("\nCIO  Dynamic Memory Management Owners Status\n");
+  PROC_PRINT(  "--------------------------------------------\n\n");
+
+  PROC_PRINT("Max. owner reached : %ld\n\n", owner_max);
+
+  PROC_PRINT("\n\nOwner Name       Name   Pid      VMA\n");
+  PROC_PRINT(    "------------------------------------\n");
+
+  for (i=0; i< MAX_OWNERS; i++)
+  {
+		if (NAME(name_pid_list[i]) != 0 || PID(name_pid_list[i]))  {
+     		if ( NAME(name_pid_list[i]) != 0 )
+     			num2nam(NAME(name_pid_list[i]), strName);
+			else
+				strcpy(strName, "      ");
+     		
+     		PROC_PRINT("%-5d 0x%-8p %-6s 0x%-8p 0x%-8p\n",
+     						i,
+				     		(void*)NAME(name_pid_list[i]),
+				     		strName,
+				     		(void*)PID(name_pid_list[i]),
+				     		vmarea[i]);
+		}
+  }
+
+  PROC_PRINT_DONE;
+
+}       // End function - owner_read_proc
+
+static struct proc_dir_entry *proc_cio_mem_mgr;
+static struct proc_dir_entry *proc_block;
+static struct proc_dir_entry *proc_owner;
+static struct proc_dir_entry *proc_chunk;
+
+static int cio_mem_mgr_proc_register(void)
+{
+	proc_cio_mem_mgr = create_proc_entry("cio_memory_manager", S_IFDIR, rtai_proc_root);
+    if (!proc_cio_mem_mgr) {
+		printk("Unable to initialize /proc/rtai/cio_memory_manager\n");
+                return(-1);
+    }
+	proc_cio_mem_mgr->owner = THIS_MODULE;
+	
+	proc_block = create_proc_entry("block0", S_IFREG|S_IRUGO|S_IWUSR, proc_cio_mem_mgr);
+	proc_block->read_proc = block_read_proc_0;
+	proc_block = create_proc_entry("block1", S_IFREG|S_IRUGO|S_IWUSR, proc_cio_mem_mgr);
+	proc_block->read_proc = block_read_proc_1;
+	proc_block = create_proc_entry("block2", S_IFREG|S_IRUGO|S_IWUSR, proc_cio_mem_mgr);
+	proc_block->read_proc = block_read_proc_2;
+	proc_block = create_proc_entry("block3", S_IFREG|S_IRUGO|S_IWUSR, proc_cio_mem_mgr);
+	proc_block->read_proc = block_read_proc_3;
+
+	proc_owner = create_proc_entry("owner", S_IFREG|S_IRUGO|S_IWUSR, proc_cio_mem_mgr);
+	proc_owner->read_proc = owner_read_proc;
+	proc_chunk = create_proc_entry("chunk", S_IFREG|S_IRUGO|S_IWUSR, proc_cio_mem_mgr);
+	proc_chunk->read_proc = chunk_read_proc;
+
+	return 0;
+}       /* End function - rtai_proc_register */
+
+
+static void cio_mem_mgr_proc_unregister(void)
+{
+	remove_proc_entry("block0", proc_cio_mem_mgr);
+	remove_proc_entry("block1", proc_cio_mem_mgr);
+	remove_proc_entry("block2", proc_cio_mem_mgr);
+	remove_proc_entry("block3", proc_cio_mem_mgr);
+
+	remove_proc_entry("chunk", proc_cio_mem_mgr);
+	remove_proc_entry("owner", proc_cio_mem_mgr);
+	remove_proc_entry("cio_memory_manager", rtai_proc_root);
+}       /* End function - rtai_proc_unregister */
+
+
+// --------------------< end of proc filesystem section >--------------------
+#endif  // CONFIG_PROC_FS
+
+// ------------------------< Debug functions section >------------------------
+
+// This function displays the allocation details of a chunk.
+// The chunk to be displayed is determined from the address
+// of a data block within the chunk.
+void display_chunk(void *addr)
+{
+  struct chkhdr *chk_ptr;
+  struct blkhdr *blk_ptr, *last;
+  char free[5];
+  char *func __attribute__ ((unused)) = "display_chunk";
+
+
+  blk_ptr = (struct blkhdr *)(addr - (sizeof(struct blkhdr)));
+  chk_ptr = (struct chkhdr *)blk_ptr->chk_addr;
+  (void *)last = (void *)chk_ptr + (chk_ptr->chk_limit - sizeof(struct blkhdr)
+                                                                 - MINSIZE);
+
+  DBG("\n\n%s - Allocation for chunk: 0x%p\n", func, chk_ptr);
+  DBG("----------------------------------------------------\n");
+  blk_ptr = (struct blkhdr *)chk_ptr->data;
+  do {
+
+    if(blk_ptr == blk_ptr->next_free) {
+      strncpy(free, "Used", strlen("Used")+1);
+    } else { // End if - Don't display free blocks.
+      strncpy(free, "Free", strlen("Free")+1);
+    }
+
+    DBG("%s - Block header 0x%p, Status %s, data address 0x%p, block size %d\n",
+                        func, blk_ptr, free, &blk_ptr->data, blk_ptr->free_size);
+
+    (void *)blk_ptr = (void *)blk_ptr + sizeof(struct blkhdr) +
+                                              blk_ptr->free_size;
+
+  } while(blk_ptr < last); // End do loop - display all allocated blocks in the chunk.
+  DBG("----------------------------------------------------\n");
+
+}  // End function - display_chunk
+
+
+
+void cio_mem_mgr_stats(void)
+{
+  printk("==== CIO memory manager max allocated: %u bytes.\n", max_allocated);
+  printk("==== CIO memory manager kmalloc()'s:   %u\n", kmalloc_calls);
+  printk("==== CIO memory manager kfree()'s:     %u\n", kfree_calls);
+  printk("==== CIO memory manager overhead:      %u bytes.\n", memory_overhead);
+  printk("==== CIO memory manager leaks:         %u bytes.\n", memory_leak);
+
+}  // End function - cio_mem_mgr_stats
+
+
+
+
+// --------------------< End of debug functions section >---------------------
+
+
+// ----------------------------------------------------------------------------
+// Module Initialisation/Finalisation
+// ----------------------------------------------------------------------------
+int __cio_mem_init(void)
+{
+
+//  int i;
+  struct chkhdr *chk_ptr; //, *chk_list_ptr;
+  struct blkhdr *blk_ptr;
+
+// Stop the initialization function from being called more than once.
+// Useful when this is used as an object module and not a stand alone
+// kernel module.
+  if(cio_mem_mgr_init_done != 0) {
+    return(0);
+  }
+
+// Allocate "low water" memory chunks, initialise them, and
+// insert them into the chunk list.
+
+   chk_ptr = (struct chkhdr *)rtai_kmalloc(nam2num("CIOMEM"), granularity);
+    if(chk_ptr == NULL ) {
+      printk("cio_mem_mgr - Initial memory allocation failure.\n");
+      return(-ENOMEM);
+    }
+    else {
+    	printk("cio_mem_mgr - Initial memory allocation succeeded at 0x%p\n",
+    			chk_ptr);
+    }
+
+
+    if (misc_register(&cio_shm_dev) < 0) {
+		printk("***** COULD NOT REGISTER CIO SHARED MEMORY DEVICE *****\n");
+		return -EBUSY;
+	}
+
+#ifdef __CIO_SHM_USE_VECTOR
+    sidt = rt_set_full_intr_vect(CIO_SHM_VECTOR, 15, 3, cio_shm_handler);
+#endif 
+
+    kmalloc_calls++;
+    total_available += granularity;
+    memory_overhead += OVERHEAD;
+    chk_ptr->chk_addr = (void *)chk_ptr;
+    chk_ptr->chk_limit = granularity;
+    chk_ptr->next_chk = NULL;
+    blk_ptr = chk_ptr->free_list = (struct blkhdr *)chk_ptr->data;
+    blk_ptr->next_free = NULL;
+    blk_ptr->free_size = chk_ptr->chk_limit - OVERHEAD;
+    blk_ptr->chk_addr = (void *)chk_ptr;
+
+    chk_list = chk_ptr;
+
+#ifdef ZDEBUG
+    printk("cio_mem_mgr - Allocated chunk, Address: %p, size: %d\n",
+           chk_ptr->chk_addr, chk_ptr->chk_limit);
+#endif
+
+// Register the proc system for this module.
+#ifdef CONFIG_PROC_FS
+        cio_mem_mgr_proc_register();
+#endif
+
+  spin_lock_init(&rt_mem_lock);
+  cio_mem_mgr_init_done = 1;
+
+  printk("\n\n==== CIO memory manager v%s Loaded. ====\n\n", cio_mem_mgr_version);
+  return(0);
+
+} // End function - init_module
+
+
+// -----------------------------------------------------------------------------
+void __cio_mem_end(void)
+{
+
+  int oldsize;
+  struct chkhdr *chk_ptr;
+  void *tmp_chkptr;
+
+  chk_ptr = chk_list;
+    oldsize = chk_ptr->chk_limit;
+    tmp_chkptr = chk_ptr->chk_addr;
+    chk_ptr = chk_ptr->next_chk;
+    kfree_calls++;
+    total_available -= granularity;
+    memory_overhead -= OVERHEAD;
+    rtai_kfree(nam2num("CIOMEM"));
+#ifdef ZDEBUG
+    printk("cio_mem_mgr - Freed chunk, Address: %p, size: %d\n",
+                                                   tmp_chkptr, oldsize);
+#endif
+
+// Unregister the proc system for this module.
+#ifdef CONFIG_PROC_FS
+        cio_mem_mgr_proc_unregister();
+#endif
+
+#ifdef __CIO_SHM_USE_VECTOR
+  rt_reset_full_intr_vect(CIO_SHM_VECTOR, sidt);
+#endif
+
+  misc_deregister(&cio_shm_dev);
+
+  cio_mem_mgr_stats();
+  printk("\n\n==== CIO memory manager v%s Unloaded. ====\n\n", cio_mem_mgr_version);
+
+} // End function - cleanup_module
+
+#ifdef CONFIG_RTAI_DYN_MM_MODULE
+int init_module(void)
+{
+	return __cio_mem_init();
+}
+
+void cleanup_module(void)
+{
+	__cio_mem_end();
+}
+
+int cio_mem_init(void)
+{
+	return 0;
+}
+
+void cio_mem_cleanup(void)
+{
+
+}
+#else
+int cio_mem_init(void)
+{
+	return __cio_mem_init();
+}
+
+void cio_mem_cleanup(void)
+{
+	__cio_mem_end();
+}
+#endif
+
+#ifdef CONFIG_RTAI_DYN_MM
+MODULE_PARM(granularity,"i");
+#endif
+
+
+// ---------------------------------< eof >------------------------------------
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/cio_mem_mgr.h rtai-24.1.9-cio-1.3/cio_mem_mgr/cio_mem_mgr.h
--- rtai-24.1.9/cio_mem_mgr/cio_mem_mgr.h	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/cio_mem_mgr.h	2002-07-29 17:50:15.000000000 +0200
@@ -0,0 +1,179 @@
+#ifndef _CIO_MEM_MGR_H_
+#define _CIO_MEM_MGR_H_
+//////////////////////////////////////////////////////////////////////////////
+//
+//      Copyright (©) 2001 Christian Charreyre (CIO Informatique Industrielle),
+//                         All rights reserved
+//
+// Authors:             Christian Charreyre (CIO Informatique Industrielle)
+//
+// Original date:       Wed 16 May 2001
+//
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+//
+// Dynamic Memory Management for Real Time Linux, with possibility to allocate
+// and free memory after entering the reat time task (rt_task_init).
+//
+// Based on the original rt-mem-mgr and shmem memory allocators found in the
+//	RTAI distribution
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+// ----------------------------------------------------------------------------
+
+extern void *cio_kmalloc_f(int name, unsigned int size, unsigned long pid);
+#define cio_kmalloc(x, y)  cio_kmalloc_f((x), (y), (unsigned long)(&(__this_module)))
+extern void cio_kfree_f(int name, unsigned long pid);
+#define cio_kfree(x)    cio_kfree_f((x), (unsigned long)(&(__this_module)))
+extern void display_chunk(void *addr);
+extern int rt_mem_init(void);
+extern void rt_mem_end(void);
+
+#undef DBG
+#ifdef ZDEBUG
+#define DBG(fmt, args...) rt_printk("<%s %d> " fmt, __FILE__, __LINE__ ,##args)
+#else
+#define DBG(fmt, args...)
+#endif
+
+#define __CIO_SHM_USE_VECTOR 1
+
+#define CIO_SHM_VECTOR      0xFF
+#define REAL_SIZE(x) (((x) - 1) & PAGE_MASK) + PAGE_SIZE
+
+#ifndef __KERNEL__
+#include <asm/page.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#ifndef __CIO_SHM_USE_VECTOR
+static inline long long cio_shmrq(int srq, unsigned int whatever)
+{
+	int fd;
+	int ret;
+
+	fd = open("/dev/cio_shm",O_RDWR);
+	if(fd<0)return fd;
+
+	ret = ioctl(fd,srq,whatever);
+
+	close(fd);
+	return ret;
+}
+#else
+static inline long long cio_shmrq(int srq, unsigned int whatever)
+{
+
+ 	long long retval;
+
+	__asm__ __volatile__ ("int $0xFF"
+	: "=A" (retval) : "a" (srq), "d" (whatever) );
+	return retval;
+}
+#endif
+
+static void *cio_malloc(int name, unsigned int size)
+{
+	void *adr = 0;
+	int hook;
+	struct { unsigned long name, size; } arg;
+	if (size <= 0) {
+		return 0;
+	}
+	if ((hook = open("/dev/cio_shm", O_RDWR)) < 0) {
+		fprintf(stderr, "cio_malloc: cannot open /dev/cio_shm: %s\n",
+					     strerror(errno));
+		return 0;
+	}
+	arg.name = name;
+	arg.size = size;
+	if (!(size = cio_shmrq(1, (unsigned long)(&arg)))) {
+		close(hook);
+		return 0;
+	}
+	adr = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED|MAP_FILE, hook, 0);
+#ifdef DEBUG
+	if ((size = cio_shmrq(4, name)) < 0) {
+		printf("REAL ALLOCATION OF %d BYTES FOR %lx.\n", -size, name);
+	} else {
+		printf("JUST A REMAP OF %d BYTES FOR %lx.\n", size, name);
+	}
+#endif
+
+	close(hook);
+
+	return adr;
+}
+
+static inline void cio_free(int name, void *adr)
+{
+	char *func __attribute__ ((unused)) = "cio_free";
+	int size;
+
+#ifdef ZDEBUG
+	printf("%s - Entering function with adr 0x%x\n", func, adr);
+#endif
+	size = cio_shmrq(2, name);
+#ifdef ZDEBUG
+	printf("%s - Received size is 0x%x\n", func, size);
+#endif
+
+	if (size && adr) {
+#ifdef ZDEBUG
+		printf("%s - Try to unmap address 0x%x with size 0x%x\n", func, adr, size);
+#endif
+#ifdef DEBUG
+		{       
+			int lsize;
+			if ((lsize = cio_shmrq(4, name)) < 0) {
+				printf("FREED %d BYTES OF %lx.\n", -lsize, name);
+			} else {
+				printf("UNMAPPED %d BYTES OF %lx.\n", lsize, name);
+			}       
+		}       
+#endif
+		munmap(adr, size);
+		cio_shmrq(3, name);
+	}
+}
+
+#ifdef DEBUG
+static inline void cio_check(unsigned long name)
+{
+	cio_shmrq(5, name);
+}
+
+static inline int cio_is_closable(void)
+{
+	return cio_shmrq(6, 0);
+}
+
+static inline void cio_make_closable(void)
+{
+	cio_shmrq(7, 0);
+}
+
+static inline void cio_not_closable(void)
+{
+	cio_shmrq(8, 0);
+}
+#endif /* DEBUG */
+
+#endif //  __KERNEL__
+// ---------------------------------< eof >------------------------------------
+#endif  // _CIO_MEM_MGR_H_
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/Makefile rtai-24.1.9-cio-1.3/cio_mem_mgr/Makefile
--- rtai-24.1.9/cio_mem_mgr/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/Makefile	2007-07-11 18:00:33.000000000 +0200
@@ -0,0 +1,87 @@
+##############################################################################
+##
+##      Copyright (©) 2000 Zentropic Computing, All rights reserved
+##      Authors:             Steve Papacharalambous (stevep@zentropix.com)
+##      Original date:       Tue 15 Feb 2000
+##
+##      Id:                  @(#)$Id: Makefile,v 1.6 2001/03/30 23:27:25 pierrec Exp $
+##
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+##
+##
+## Dynamic Memory Management for Real Time Linux.
+##
+###############################################################################
+
+OBJS = cio_mem_mgr.o
+
+# Uncomment this line to enable proc interface (/proc/rtai/cio_memory_manager)
+EXTRA_CFLAGS += -DCONFIG_PROC_FS
+
+# Uncomment this line to enable debug comments
+#EXTRA_CFLAGS += -DZDEBUG
+
+# Comment this line to disable module configuration
+EXTRA_CFLAGS += -DCONFIG_RTAI_DYN_MM_MODULE
+
+all: modules
+
+modules: links $(OBJS) subdirs
+
+subdirs : 
+	make -C test
+
+include ./Rules.make
+-include .depend
+
+INCLUDE  = -I$(LINUXDIR)/include -I../include -I.
+CFLAGS  += $(EXTRA_CFLAGS) $(INCLUDE)
+
+$(OBJS:.o=.d) :
+	$(CC) $(CFLAGS) $(INCLUDE) -M $(patsubst %.d, %.c, $@) > $@
+
+DEPFILES = $(strip $(OBJS:.o=.d))
+
+.depend : $(DEPFILES) 
+	echo "#Automatically created by Makefile" > /tmp/.depend 
+	cat /tmp/.depend $(DEPFILES) > .depend
+
+links : 
+	if [ ! -L kvmem.c ]; then \
+		rm -f kvmem.c; \
+		ln -s ../shmem/kvmem.c; \
+        fi
+	if [ ! -L kvmem.h ]; then \
+		rm -f kvmem.h; \
+		ln -s ../shmem/kvmem.h; \
+        fi
+	if [ ! -L ../include/cio_mem_mgr.h ]; then \
+		cd ../include; \
+		rm -f cio_mem_mgr.h; \
+		ln -s ../cio_mem_mgr/cio_mem_mgr.h; \
+        fi
+	if [ ! -L ../modules/cio_mem_mgr.o ]; then \
+		cd ../modules; \
+		rm -f cio_mem_mgr.o; \
+		ln -s ../cio_mem_mgr/cio_mem_mgr.o; \
+        fi
+	
+clean:
+	rm -f ./*.d *.o .depend .*.o.flags *~ kvmem.c kvmem.h
+	make -C test clean
+
+subclean: clean
+
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/README rtai-24.1.9-cio-1.3/cio_mem_mgr/README
--- rtai-24.1.9/cio_mem_mgr/README	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/README	2007-06-19 15:42:39.000000000 +0200
@@ -0,0 +1,105 @@
+Dynamic Memory Management for RTAI, implementing shared memory between 
+======================================================================
+processes and RT tasks.
+=======================
+
+Copyright (©) 2001 Christian Charreyre (CIO Informatique Industrielle)
+
+Authors:           Christian Charreyre (CIO Informatique Industrielle)
+
+Original date:       Wed 16 May 2001
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+
+-----------------------------------------------------------------------------
+
+This package contains an implementation of dynamic memory management for RTAI.
+Allocated memory can be shared between RT tasks and Linux processes, and can 
+be allocated or deallocated even after entering the real time task 
+(rt_task_init).
+This allows real time tasks to allocate and free memory safely whilst
+executing in the real time domain, and to share this memory with Linux 
+processes.
+This package is a mix of sh_mem package and rt_mem_mgr packages already 
+existing in RTAI.
+To use it, make a device whose minor number is 253 and major number is 10 :
+
+mknod -m 666 /dev/cio_shm c 10 253
+
+This package is no more useful in newest versions of RTAI (3.0 and later)
+because an unified allocator has been built, but in industrial applications
+one can still use old versions, so feel free to use it instead of swapping
+versions if you just need such and allocator.
+
+-----------------------------------------------------------------------------
+
+Configuration Parameters.
+-------------------------
+
+Size of the unique memory chunk used for dynamic memory allocation can be 
+changed to suit application requirements.  To change the default size, set 
+to 2 MBytes, modify the global variable "granularity" and re-compile the 
+package, or use the module parameter when loading the module.
+
+-----------------------------------------------------------------------------
+
+Limitations.
+------------
+
+This module has been built and tested with kernel 2.4.18 and RTAI 24.1.9.
+You may perhaps use it with different versions but we have not tested it.
+
+-----------------------------------------------------------------------------
+
+Memory Manager API.
+-------------------
+
+The API calls for the memory menager are listed below:
+
+From the Linux side :
+
+void *cio_malloc(int name, unsigned int size);
+void cio_free(int name, void *addr);
+
+NB: cio_malloc returns NULL if an error occured.
+	
+From the RT task side :
+
+void *cio_kmalloc(int name, unsigned int size);
+void cio_kfree(int name);
+
+NB: cio_kmalloc returns NULL if an error occured.
+
+-----------------------------------------------------------------------------
+
+TODO.
+-----
+
+
+-----------------------------------------------------------------------------
+
+Acknowledgements.
+-----------------
+
+- Paolo Mantegazza (mantegazza@aero.polimi.it) for the RTAI package and the
+  shmem module
+
+- Victor Yodaiken (yodaiken@fsmlabs.com) and Micheal Baranbanov 
+  (baraban@fsmlabs.com) for the RTLinux project.
+
+- Pierre Cloutier (Poseidon Controls Inc.) and Steve Papacharalambous 
+  (Zentropic Computing Inc.) for the rt_mem_mgr module.
+	  
+-----------------------------------------------------------------------------
\ Pas de fin de ligne à la fin du fichier.
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/Rules.make rtai-24.1.9-cio-1.3/cio_mem_mgr/Rules.make
--- rtai-24.1.9/cio_mem_mgr/Rules.make	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/Rules.make	2002-07-29 17:50:15.000000000 +0200
@@ -0,0 +1,129 @@
+# A lot of this was taken from the Linux Rules.make: seh
+
+#
+# User configuration section
+#
+CONFIG_DYN_MM = y
+#CONFIG_CHECK  = y
+#CONFIG_SOFT_FP = y
+INSRT = $(TOPDIR)/utils/insrt
+RMRT  = $(TOPDIR)/utils/rmrt
+
+ifndef LINUXDIR
+LINUXDIR:=/usr/src/linux
+else
+LINUXDIR:=$(shell (cd $(LINUXDIR);pwd))
+endif
+
+-include $(LINUXDIR)/.config
+
+ifdef CONFIG_SMP
+	CONFIG_APIC = y
+endif
+# End of user configuration section
+
+VERSION      = 24
+PATCHLEVEL   = 1
+SUBLEVEL     = 9
+EXTRAVERSION = -5g
+
+RTAIRELEASE  = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+RTAIHOME = ..
+
+ARCH        := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+
+# standard CFLAGS
+HPATH           = $(TOPDIR)/include
+HOSTCC          = gcc
+HOSTCFLAGS      = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+CROSS_COMPILE   =
+
+# Include the make variables (CC, etc...)
+AS              = $(CROSS_COMPILE)as
+LD              = $(CROSS_COMPILE)ld
+CC              = $(CROSS_COMPILE)gcc
+CPP             = $(CC) -E
+MODFLAGS        = -DMODULE
+
+CPPFLAGS := -I$(HPATH) -I$(LINUXDIR)/include  -I. -I$(RTAIHOME)/include 
+CFLAGS   := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce -pipe
+AFLAGS   := -D__ASSEMBLY__ $(CPPFLAGS)
+
+K_CFLAGS  = -D__KERNEL__    -D__NO_VERSION__        -DMODULE
+CFLAGS   += $(K_CFLAGS)
+
+ifdef CONFIG_SMP
+	CFLAGS += -D__SMP__
+endif
+
+ifdef CONFIG_SOFT_FP
+	CFLAGS += -msoft-float
+endif
+
+export  VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION RTAIRELEASE ARCH \
+        TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
+        CPP MODFLAGS PERL LINUXDIR CPPFLAGS CFLAGS AFLAGS \
+	INSTALL_MOD_PATH
+
+.PHONY: dummy sub_dirs $(SUB_DIRS)
+
+%.s: %.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -S $< -o $@
+
+%.i: %.c
+	$(CPP) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) $< > $@
+
+%.o: %.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c -o $@ $<
+	@ ( \
+            echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@))))' ; \
+            echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
+            echo 'endif' \
+        ) > $(dir $@)/.$(notdir $@).flags
+
+%.o: %.s
+	$(AS) $(ASFLAGS) $(EXTRA_ASFLAGS) -o $@ $<
+
+# make a userspace executable
+%: %.c
+	$(CC) $(CPPFLAGS) -g -o $@ $<
+
+linux_config: 
+	@if [ ! -s $(LINUXDIR)/.config ] ; then \
+	echo "You need to configure your Linux kernel before building RTAI." ;\
+	exit 1 ; \
+	fi
+
+ifndef CONFIG_RTHAL
+	@echo;\
+	echo "!!! ATTENTION: IMPORTANT KERNEL CONFIG PARAMETER MISSING !!!";\
+	echo "To build RTAI, you must first select:";\
+	echo "Processor type and features -> Real-Time Hardware Abstraction Layer";\
+	echo "when configuring your Linux kernel.";\
+	echo
+	@sleep 5
+endif
+
+$(MAKE_SUB_DIRS):
+	mkdir $@
+
+sub_dirs: $(SUB_DIRS)
+$(SUB_DIRS):
+	$(MAKE) -C $@
+
+# This make dependencies quickly
+fastdep: dummy
+	$(TOPDIR)/scripts/mkdep $(wildcard *.[chS]) > .depend
+ifdef SUB_DIRS
+	$(MAKE) $(patsubst %,_sfdep_%,$(SUB_DIRS)) _FASTDEP_SUB_DIRS="$(SUB_DIRS)"
+endif
+
+ifdef _FASTDEP_SUB_DIRS
+$(patsubst %,_sfdep_%,$(_FASTDEP_SUB_DIRS)):
+	$(MAKE) -C $(patsubst _sfdep_%,%,$@) fastdep
+endif
+
+-include .depend
+-include $(TOPDIR)/.hdepend
+
+
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/test/Makefile rtai-24.1.9-cio-1.3/cio_mem_mgr/test/Makefile
--- rtai-24.1.9/cio_mem_mgr/test/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/test/Makefile	2007-07-11 18:09:27.000000000 +0200
@@ -0,0 +1,16 @@
+
+MI_OBJS      := rt_mem_test.o rt_mem_test2.o
+
+A_TARG       := proc_test
+
+EXTRA_CFLAGS += -DZDEBUG
+
+ifdef TOPDIR
+include $(TOPDIR)/Rules.make
+else
+all:
+	make -C ../.. modules SUBDIRS=cio_mem_mgr/test
+endif
+
+clean:
+	rm -f *.d .depend *.o $(A_TARG) *~
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/test/Makefile.old rtai-24.1.9-cio-1.3/cio_mem_mgr/test/Makefile.old
--- rtai-24.1.9/cio_mem_mgr/test/Makefile.old	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/test/Makefile.old	2007-06-19 18:40:19.000000000 +0200
@@ -0,0 +1,41 @@
+MI_OBJS = rt_mem_test.o rt_mem_test2.o proc_test.o
+A_TARG = proc_test
+TARGS  = $(OBJS) $(PROC)
+
+# Uncomment this line to build as a separate module
+#EXTRA_CFLAGS += $(MODFLAGS)
+
+# Uncomment this line to enable debug comments
+EXTRA_CFLAGS += -DZDEBUG -I../../include -I..
+
+INCLUDE  = -I$(LINUXDIR)/include -I../../include -I..
+CFLAGS  += $(EXTRA_CFLAGS) $(INCLUDE)
+
+CFLAGS_rt_mem_test.o = $(MODFLAGS)
+CFLAGS_rt_mem_test2.o = $(MODFLAGS)
+CFLAGS_proc_test.o = $(INCLUDE)
+
+include ../../Rules.make
+-include .depend
+
+modules : all
+
+all : .depend rt_mem_test.o rt_mem_test2.o proc_test
+
+$(OBJS:.o=.d) :
+	$(CPP) $(CFLAGS) $(INCLUDE) -MMD $(patsubst %.d, %.c, $@) > $@
+
+DEPFILES = $(strip $(OBJS:.o=.d))
+
+.depend : $(DEPFILES)
+	echo "#Automatically created by Makefile" > /tmp/.depend
+	cat /tmp/.depend $(DEPFILES) > .depend
+
+proc_test.o: proc_test.c
+	$(CC) $(INCLUDE) -c $<
+
+proc_test: proc_test.o
+	$(CC) -o $@ $<
+
+clean :
+	rm -f $(TARGS) .depend
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/test/proc_test.c rtai-24.1.9-cio-1.3/cio_mem_mgr/test/proc_test.c
--- rtai-24.1.9/cio_mem_mgr/test/proc_test.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/test/proc_test.c	2002-07-29 17:50:35.000000000 +0200
@@ -0,0 +1,66 @@
+//
+// This process program can be used with rt_mem_test.o module to test allocation and freeing
+// of shared memories.
+// The test is described at the beginning of rt_mem_test.c
+//
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "cio_mem_mgr.h"
+
+#define MEMSIZE 0x4000
+
+
+main()
+{
+	unsigned int mem_size1 = 0x4000 - 3;
+	unsigned int mem_size2 = 0x123;
+	unsigned int mem_size3 = 0x400;
+	int *mem_ptr1 = NULL;
+	int *mem_ptr2 = NULL;
+	int *mem_ptr3 = NULL;
+	char *next;
+
+	printf("\nALLOCATING 0x%x bytes for name 0x%x IN PROCESS\n", mem_size1, 0xaaaa);
+	mem_ptr1 = cio_malloc(0xaaaa, mem_size1);
+
+	printf("THE VALUE OF 0x%x (@ 0x%x) IS 0x%x\n",  0xaaaa, mem_ptr1, mem_ptr1[0]);
+	
+	mem_ptr1[0] ++;								// Step 1 (value = 2)
+	printf("Type <RC> to go to next step : ");
+	scanf("%c", &next);
+	
+	mem_ptr1[0] ++;								// Step 2 (value = 3)
+	printf("\nALLOCATING 0x%x bytes for name 0x%x IN PROCESS\n", mem_size2, 0xaaab);
+	mem_ptr2 = cio_malloc(0xaaab, mem_size2);
+
+	printf("THE VALUE OF 0x%x (@ 0x%x) IS 0x%x\n",  0xaaab, mem_ptr2, mem_ptr2[0]);
+	printf("Type <RC> to go to next step : ");
+	scanf("%c", &next);
+	
+	mem_ptr1[0] ++;								// Step 3 (value = 4)
+	printf("\nALLOCATING 0x%x bytes for name 0x%x IN PROCESS\n", mem_size3, 0xaaac);
+	mem_ptr3 = cio_malloc(0xaaac, mem_size3);
+
+	printf("THE VALUE OF 0x%x (@ 0x%x) IS 0x%x\n",  0xaaac, mem_ptr3, mem_ptr3[0]);
+	printf("Type <RC> to go to next step, then Ctrl C to exit process : ");
+	scanf("%c", &next);
+	
+	mem_ptr1[0] ++;								// Step 4 (value = 5)
+	printf("\nFREEING 0x%x IN PROCESS\n", 0xaaac);
+	cio_free(0xaaac, mem_ptr3);
+	printf("\nFREEING 0x%x IN PROCESS\n", 0xaaab);
+	cio_free(0xaaab, mem_ptr2);
+	while(1)
+	{
+		sleep(5);
+		printf("Current value of step is %d\n", mem_ptr1[0]);
+		mem_ptr1[0]++;							// Endless loop, to check that mem_ptr3 is automatically
+	}											// freed when the process is killed by Ctrl C
+
+	printf("Exiting process\n");
+}
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/test/rt_mem_test2.c rtai-24.1.9-cio-1.3/cio_mem_mgr/test/rt_mem_test2.c
--- rtai-24.1.9/cio_mem_mgr/test/rt_mem_test2.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/test/rt_mem_test2.c	2007-06-20 18:28:00.000000000 +0200
@@ -0,0 +1,192 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+//      Copyright (©) 2000 Pierre Cloutier (Poseidon Controls Inc.),
+//                         Steve Papacharalambous (Lineo Inc.),
+//                         All rights reserved
+//
+// Authors:             Pierre Cloutier (pcloutier@poseidoncontrols.com)
+//                      Steve Papacharalambous (stevep@lineo.com)
+//
+// Original date:       Wed 23 Feb 2000
+//
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+//
+// Dynamic Memory Management simple test program for Real Time Linux.
+//
+// This test can be used with rt_mem_test.o module.
+// This module replaces proc_test process and makes step advance automatically.
+// In order to verify everything is OK, look at the traces from rt_mem_test.o
+// using dmesg.
+// If everything is OK, the second value seen by rt_mem_test.o must be 0xefefefef,
+// and the first one must increment regularly from 1 to 5.
+// Finally, every area must be successfully freed by rt_mem_test.o when first value
+// reaches 5, and by rt_mem_test2.o when count reaches 6.
+//
+///////////////////////////////////////////////////////////////////////////////
+static char id_rt_mem_test_c[] __attribute__ ((unused)) = "@(#)$Id: rt_mem_test.c,v 1.3 2000/11/19 01:45:34 stevep Exp $";
+
+#undef __NO_VERSION__
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+#include <linux/errno.h>
+
+#include <rtai.h>
+#include <rtai_shm.h>
+#include <rtai_sched.h>
+#include <rtai_fifos.h>
+#include "cio_mem_mgr.h"
+
+
+// ------------------------------< definitions >-------------------------------
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define TICK_PERIOD 2000000000
+
+#define STACK_SIZE 2000
+
+#undef DBG
+#ifdef ZDEBUG
+#define DBG(fmt, args...)  rt_printk("<%s %d> " fmt, __FILE__, __LINE__ ,##args)
+#else
+#define DBG(fmt, args...)
+#endif
+
+// ----------------------------------------------------------------------------
+//      Local Definitions.
+// ----------------------------------------------------------------------------
+
+
+// ----------------------------------------------------------------------------
+//      Package Global Data.
+// ----------------------------------------------------------------------------
+RT_TASK mem_thread2;
+
+
+// ----------------------------------------------------------------------------
+void mem_alloc2(int t)
+{
+
+  unsigned int mem_size1 = 0x4000 - 3;
+  unsigned int mem_size2 = 0x123;
+  unsigned int mem_size3 = 0x400;
+  int *mem_ptr1 = NULL;
+  int *mem_ptr2 = NULL;
+  int *mem_ptr3 = NULL;
+  static int count = 0;
+
+  while (1)
+  {
+    if (mem_ptr1 == NULL)
+	{
+  		DBG("mem_alloc - Request 0x%x bytes at name : 0x%x.\n", mem_size1, 0xaaaa);
+  		mem_ptr1 = cio_kmalloc(0xaaaa, mem_size1);
+  		if(mem_ptr1 == NULL) {
+    		DBG("mem_alloc - Error Allocating 0x%x bytes.\n", mem_size1);
+  		} else {
+    		DBG("mem_alloc - Allocated 0x%x bytes, address: 0x%x.\n", mem_size1, mem_ptr1);
+  		}
+
+  		DBG("mem_alloc - Request 0x%x bytes at name : 0x%x.\n", mem_size2, 0xaaab);
+  		mem_ptr2 = cio_kmalloc(0xaaab, mem_size2);
+  		if(mem_ptr2 == NULL) {
+    		DBG("mem_alloc - Error Allocating 0x%x bytes.\n", mem_size2);
+  		} else {
+    		DBG("mem_alloc - Allocated 0x%x bytes, address: 0x%x.\n", mem_size2, mem_ptr2);
+  		}
+
+  		*mem_ptr2 = 0xefefefef;
+
+  		DBG("mem_alloc - Request 0x%x bytes at name : 0x%x.\n", mem_size3, 0xaaac);
+  		mem_ptr3 = cio_kmalloc(0xaaac, mem_size3);
+  		if(mem_ptr3 == NULL) {
+    		DBG("mem_alloc - Error Allocating 0x%x bytes.\n", mem_size3);
+  		} else {
+    		DBG("mem_alloc - Allocated 0x%x bytes, address: 0x%x.\n", mem_size3, mem_ptr3);
+  		}
+	}
+
+	mem_ptr1[0] ++;
+	
+    if(count == 6) {
+    	cio_kfree(0xaaaa);
+    	cio_kfree(0xaaab);
+    	cio_kfree(0xaaac);
+    }
+
+//  display_chunk(mem_ptr1);
+//  rt_task_suspend(rt_whoami());
+
+    count++;
+    rt_task_wait_period();
+  }
+
+}  // End function - mem_alloc
+
+
+// ----------------------------------------------------------------------------
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Module Initialisation/Finalisation
+//
+///////////////////////////////////////////////////////////////////////////////
+int init_module(void)
+{
+
+  int r_c = 0;
+  RTIME tick_period;
+
+  if((r_c = rt_task_init(&mem_thread2, mem_alloc2, 0,
+                          STACK_SIZE, 2, 1, 0)) < 0) {
+
+    printk("rt_mem_test2 - Error creating mem_thread: %d\n", r_c);
+  }
+
+#ifdef ZDEBUG
+  printk("rt_mem_test2 - Created memory allocation thread.\n");
+#endif
+
+  rt_set_periodic_mode();
+  tick_period = start_rt_timer(nano2count(TICK_PERIOD));
+  if((r_c = rt_task_make_periodic(&mem_thread2, rt_get_time()
+                                   + (2 * tick_period), tick_period)) < 0) {
+
+    printk("rt_mem_test2 - Error making mem_thread periodic: %d\n", r_c);
+  }
+
+  return(r_c);
+
+} // End function - init_module
+
+
+// -----------------------------------------------------------------------------
+void cleanup_module(void)
+{
+
+  stop_rt_timer();
+  rt_busy_sleep(10000000);
+  rt_task_delete(&mem_thread2);
+
+
+} // End function - cleanup_module
+
+
+// ---------------------------------< eof >------------------------------------
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/test/rt_mem_test.c rtai-24.1.9-cio-1.3/cio_mem_mgr/test/rt_mem_test.c
--- rtai-24.1.9/cio_mem_mgr/test/rt_mem_test.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/test/rt_mem_test.c	2002-07-29 17:50:35.000000000 +0200
@@ -0,0 +1,194 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+//      Copyright (©) 2000 Pierre Cloutier (Poseidon Controls Inc.),
+//                         Steve Papacharalambous (Lineo Inc.),
+//                         All rights reserved
+//
+// Authors:             Pierre Cloutier (pcloutier@poseidoncontrols.com)
+//                      Steve Papacharalambous (stevep@lineo.com)
+//
+// Original date:       Wed 23 Feb 2000
+//
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+//
+// Dynamic Memory Management simple test program for Real Time Linux.
+//
+// To use this test, insmod rt_mem_test.o
+// This must create 3 memory areas. Then run ./proc_test and check if values are correct for
+// area 2 and 3. Enter RC until proc_test tells type Ctrl C. At each step, check values in chunk, owner
+// and blocks proc interface. Check also that values seen from proc_test are correct (using dmesg).
+// Finally, check that after Ctrl C, last area is successfully freed by the system.
+//
+///////////////////////////////////////////////////////////////////////////////
+static char id_rt_mem_test_c[] __attribute__ ((unused)) = "@(#)$Id: rt_mem_test.c,v 1.3 2000/11/19 01:45:34 stevep Exp $";
+
+#undef __NO_VERSION__
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+#include <linux/errno.h>
+
+#include <rtai.h>
+#include <rtai_shm.h>
+#include <rtai_sched.h>
+#include <rtai_fifos.h>
+#include "cio_mem_mgr.h"
+
+
+// ------------------------------< definitions >-------------------------------
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define TICK_PERIOD 1000000000
+
+#define STACK_SIZE 2000
+
+#undef DBG
+#ifdef ZDEBUG
+#define DBG(fmt, args...)  rt_printk("<%s %d> " fmt, __FILE__, __LINE__ ,##args)
+#else
+#define DBG(fmt, args...)
+#endif
+
+// ----------------------------------------------------------------------------
+//      Local Definitions.
+// ----------------------------------------------------------------------------
+
+
+// ----------------------------------------------------------------------------
+//      Package Global Data.
+// ----------------------------------------------------------------------------
+RT_TASK mem_thread;
+
+
+// ----------------------------------------------------------------------------
+void mem_alloc(int t)
+{
+
+  unsigned int mem_size1 = 0x4000 - 3;
+  unsigned int mem_size2 = 0x123;
+  unsigned int mem_size3 = 0x400;
+  int *mem_ptr1 = NULL;
+  int *mem_ptr2 = NULL;
+  int *mem_ptr3 = NULL;
+  static int count = 0;
+
+  while (1)
+  {
+    if (count == 0)
+    {
+	  DBG("mem_alloc - Request 0x%x bytes at name : 0x%x.\n", mem_size1, 0xaaaa);
+	  mem_ptr1 = cio_kmalloc(0xaaaa, mem_size1);
+	  if(mem_ptr1 == NULL) {
+		DBG("mem_alloc - Error Allocating 0x%x bytes.\n", mem_size1);
+	  } else {
+		DBG("mem_alloc - Allocated 0x%x bytes, address: 0x%x.\n", mem_size1, mem_ptr1);
+	  *mem_ptr1 = 1;
+      }
+	
+
+	  DBG("mem_alloc - Request 0x%x bytes at name : 0x%x.\n", mem_size2, 0xaaab);
+	  mem_ptr2 = cio_kmalloc(0xaaab, mem_size2);
+	  if(mem_ptr2 == NULL) {
+		DBG("mem_alloc - Error Allocating 0x%x bytes.\n", mem_size2);
+	  } else {
+		DBG("mem_alloc - Allocated 0x%x bytes, address: 0x%x.\n", mem_size2, mem_ptr2);
+	    *mem_ptr2 = 0xaaabbaaa;
+  	  }
+	
+	  DBG("mem_alloc - Request 0x%x bytes at name : 0x%x.\n", mem_size3, 0xaaac);
+	  mem_ptr3 = cio_kmalloc(0xaaac, mem_size3);
+	  if(mem_ptr3 == NULL) {
+		DBG("mem_alloc - Error Allocating 0x%x bytes.\n", mem_size3);
+	  } else {
+		DBG("mem_alloc - Allocated 0x%x bytes, address: 0x%x.\n", mem_size3, mem_ptr3);
+	    *mem_ptr3 = 0xaaaccaaa;
+	  }
+    }
+  
+    DBG("mem_alloc - Allocated areas first int value is %x %x %x\n", *mem_ptr1, *mem_ptr2, *mem_ptr3);
+  
+    if (*mem_ptr1 == 5)
+    {
+		DBG("mem_alloc - Freeing allocated areas\n");
+		cio_kfree(0xaaaa);
+		cio_kfree(0xaaab);
+ 		cio_kfree(0xaaac);
+		rt_task_suspend(rt_whoami());	// To avoid double free of same area
+    }
+
+	  
+//  display_chunk(mem_ptr1);
+//  rt_task_suspend(rt_whoami());
+    count++;
+    rt_task_wait_period();
+  }
+
+}  // End function - mem_alloc
+
+
+// ----------------------------------------------------------------------------
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Module Initialisation/Finalisation
+//
+///////////////////////////////////////////////////////////////////////////////
+int init_module(void)
+{
+
+  int r_c = 0;
+  RTIME tick_period;
+
+  if((r_c = rt_task_init(&mem_thread, mem_alloc, 0,
+                          STACK_SIZE, 2, 1, 0)) < 0) {
+
+    printk("rt_mem_test - Error creating mem_thread: %d\n", r_c);
+  }
+
+#ifdef ZDEBUG
+  printk("rt_mem_test - Created memory allocation thread.\n");
+#endif
+
+  rt_set_periodic_mode();
+  tick_period = start_rt_timer(nano2count(TICK_PERIOD));
+  if((r_c = rt_task_make_periodic(&mem_thread, rt_get_time()
+                                   + (2 * tick_period), tick_period)) < 0) {
+
+    printk("rt_mem_test - Error making mem_thread periodic: %d\n", r_c);
+  }
+
+  return(r_c);
+
+} // End function - init_module
+
+
+// -----------------------------------------------------------------------------
+void cleanup_module(void)
+{
+
+  stop_rt_timer();
+  rt_busy_sleep(10000000);
+  rt_task_delete(&mem_thread);
+
+
+} // End function - cleanup_module
+
+
+// ---------------------------------< eof >------------------------------------
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/test/run rtai-24.1.9-cio-1.3/cio_mem_mgr/test/run
--- rtai-24.1.9/cio_mem_mgr/test/run	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/test/run	2002-07-29 17:50:35.000000000 +0200
@@ -0,0 +1,9 @@
+#! /bin/bash
+sync
+insmod ../../modules/rtai.o
+insmod ../../modules/rtai_fifos.o
+insmod ../../modules/rtai_shm.o
+insmod ../cio_mem_mgr.o
+insmod ../../modules/rtai_sched.o
+insmod rt_mem_test.o
+insmod rt_mem_test2.o
Les fichiers rtai-24.1.9/cio_mem_mgr/test/try et rtai-24.1.9-cio-1.3/cio_mem_mgr/test/try sont différents.
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/test/try.c rtai-24.1.9-cio-1.3/cio_mem_mgr/test/try.c
--- rtai-24.1.9/cio_mem_mgr/test/try.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/test/try.c	2007-06-19 18:26:06.000000000 +0200
@@ -0,0 +1,233 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+//      Copyright (©) 2001 Christian Charreyre (CIO Informatique Industrielle),
+//                         All rights reserved
+//
+// Authors:             Christian Charreyre (CIO Informatique Industrielle)
+//
+// Original date:       Wed 16 May 2001
+//
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+//
+// Dynamic Memory Management for Real Time Linux, with possibility to allocate
+// and free memory after entering the reat time task (rt_task_init).
+//
+// Based on the original rt-mem-mgr and shmem memory allocators found in the
+//	RTAI distribution
+//
+///////////////////////////////////////////////////////////////////////////////
+static char id_rt_mem_mgr_c[] __attribute__ ((unused)) = "@(#)$Id: cio_mem_mgr.c,v 1.1 2001/05/16 16:31:50 stevep Exp $";
+
+/* CIO-DCH RTAI-CT must be undefined here only for this source */
+#undef __NO_VERSION__
+/* END CIO-DCH RTAI-CT must be undefined here only for this source */
+/*#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#ifndef CONFIG_RTAI_MM_VMALLOC
+  #include <linux/malloc.h>
+#else
+  #include <linux/vmalloc.h>
+  #include "../shmem/kvmem.h"
+#endif
+#include <linux/errno.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/wrapper.h>
+
+#ifdef CONFIG_PROC_FS
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+#endif
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <asm/rtai.h>
+#include <rtai_shm.h>
+#include <rtai_proc_fs.h>
+#include <rtai_fifos.h>
+#include <rt_mem_mgr.h>
+
+#include <cio_mem_mgr.h>
+#include <rtai_trace.h>
+
+//#if LINUX_EXT_VERSION_CODE < KERNEL_EXT_VERSION(2,4,0,4)
+//#include "rtai_bttv.h"
+//#else
+#include "kvmem.h"
+#include "kvmem.c"
+//#endif*/
+
+// ------------------------------< definitions >-------------------------------
+
+#ifdef DEBUG
+static int closable;
+static int echo;
+#endif
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define OVERHEAD (sizeof(struct chkhdr) + sizeof(struct blkhdr))
+
+#define MINSIZE PAGE_SIZE
+#define MAX_SLOTS            256  	// Set it according to your needs.
+#define MAX_SLOTS_PROC	64	// Max number of blocks displayed in one interface
+#define MAX_OWNERS           4*MAX_SLOTS // avrg 4 simultaneous users per slot!
+#define CIO_SHM_MISC_MINOR  253 // The same minor used to mknod for major 10.
+
+/* The two lines below could go into a structure. It is preferred
+   to keep them distinct to recall that a vmarea pertains only to
+   processes allocated/mmaped areas, and not to module ones. */
+
+static unsigned long long name_pid_list[MAX_OWNERS + 1] = { 0LL, };
+static struct vm_area_struct *vmarea[MAX_OWNERS + 1]   = { 0, };
+
+static struct { void *adr; unsigned long name, size, count; } shm_list[MAX_SLOTS + 1] = { {0, 0, 0, 0}, };
+
+static unsigned long owner_max = 0;
+static unsigned long slot_max = 0;
+
+//#ifdef __SMP__
+//static spinlock_t shm_lock = SPIN_LOCK_UNLOCKED;
+//#endif
+
+#define NAME(x) ((unsigned long *)(&(x)))[0]
+#define PID(x)  ((unsigned long *)(&(x)))[1]
+
+#define PAGE_SIZE 4096
+
+// Chunk of contiguous memory.
+struct chkhdr {
+  void *chk_addr;                    // Address of chunk.
+  struct chkhdr *next_chk;           // 0 if none.
+  unsigned int chk_limit;            // Size of chunk.
+  struct blkhdr *free_list;          // 1st free object in chunk, NULL if none.
+  char dummy[MINSIZE - 16];
+  char data[0];
+};
+
+
+// Block header for management within a chunk.
+struct blkhdr {
+  void *chk_addr;                    // Address of owner chunk.
+  struct blkhdr *next_free;          // SELF if not free, NULL if end of list.
+  unsigned int free_size;
+  char dummy[MINSIZE-12];
+  char data[0];
+};
+
+enum mem_cmd { chk_alloc, chk_free };
+
+#define DBG(fmt, args...) printf("<%s %d> " fmt, __FILE__, __LINE__ ,##args)
+
+// ----------------------------------------------------------------------------
+//      Local Definitions.
+// ----------------------------------------------------------------------------
+static void *alloc_in_chk(unsigned int size, struct chkhdr *chk);
+void rt_mmgr_dump(void);
+
+// ----------------------------------------------------------------------------
+//      Package Global Data.
+// ----------------------------------------------------------------------------
+char cio_mem_mgr_version[] = "1.2";
+unsigned int granularity = 0x200000;
+//int low_chk_ref = 1;
+unsigned int low_data_mark = 0x2000; // Enough to allocate a dynamic task.
+int extra_chks;
+unsigned int max_allocated = 0;
+unsigned int total_available = 0;
+unsigned int kmalloc_calls = 0;
+unsigned int kfree_calls = 0;
+unsigned int memory_leak = 0;
+unsigned int memory_overhead = 0;
+int sysrq_cmd_err = 0;
+int cio_mem_mgr_init_done = 0;
+struct chkhdr *chk_list = NULL;
+//struct { int srq, no_chk; spinlock_t srq_lock; } alloc_sysrq;
+//struct { int srq, no_chk; spinlock_t srq_lock; } free_sysrq;
+//spinlock_t rt_mem_lock;
+
+
+
+static inline int registr(unsigned long long name_pid)
+{
+	int owner;
+	for (owner = 1; owner <= MAX_OWNERS; owner++) {
+		if (!name_pid_list[owner]) {
+			name_pid_list[owner] = name_pid;
+			vmarea[owner] = (struct vm_area_struct *)(PID(name_pid) | 0xF0000000);
+			if (owner > owner_max)
+				owner_max = owner;
+			return owner;
+		}
+	}
+	return 0;
+}
+
+
+
+static inline int there_is_not_and_reg(unsigned long long name_pid)
+{
+	int owner;
+  	char *func __attribute__ ((unused)) = "there_is_not_and_reg";
+
+ 	DBG("%s - name 0x%p, pid 0x%p\n", func, NAME(name_pid), PID(name_pid));
+	for (owner = 1; owner <= MAX_OWNERS; owner++) {
+		if (name_pid_list[owner] == name_pid) {
+			return 0;
+		}
+	}
+	return registr(name_pid);
+}
+
+
+
+
+static inline int find_free_slot_and_reg(unsigned long name, unsigned long pid)
+{
+	int slot;
+	unsigned long long name_pid;
+  	char *func __attribute__ ((unused)) = "find_free_slot_and_reg";
+
+ 	DBG("%s - name 0x%x, pid 0x%p\n", func, name, pid);
+	for (slot = 1; slot <= MAX_SLOTS; slot++) {
+		if (!shm_list[slot].name) {
+			NAME(name_pid) = name;
+			PID(name_pid)  = pid;
+			return there_is_not_and_reg(name_pid) ? slot : 0;
+		}
+	}
+	return 0;
+}
+
+int main (int argc, char **argv)
+
+{
+	DBG("Process id is 0x%x\n", getpid());
+	find_free_slot_and_reg(0xabcd, getpid());
+}
+
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/cio_mem_mgr/test/unload rtai-24.1.9-cio-1.3/cio_mem_mgr/test/unload
--- rtai-24.1.9/cio_mem_mgr/test/unload	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/cio_mem_mgr/test/unload	2002-07-29 17:50:35.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/bash
+sync
+rmmod rt_mem_test2 rt_mem_test cio_mem_mgr
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/cio_mbx/Makefile rtai-24.1.9-cio-1.3/examples/cio_mbx/Makefile
--- rtai-24.1.9/examples/cio_mbx/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/cio_mbx/Makefile	2002-07-29 17:50:26.000000000 +0200
@@ -0,0 +1,19 @@
+
+MI_OBJS	+= task_mbx.o task2_mbx.o
+BI_OBJS += proc_mbx.o proc2_mbx.o
+B_TARG += proc_mbx proc2_mbx
+EXTRA_USER_CFLAGS += -I../../lxrt
+EXTRA_CFLAGS += -I../../lxrt
+
+ifdef TOPDIR
+include $(TOPDIR)/Rules.make
+else
+all:
+	make -C ../.. modules SUBDIRS=examples/cio_mbx
+clean:
+	make -C ../.. subclean SUBDIRS=examples/cio_mbx
+endif
+
+ex_mbx.c:	rt_process.c
+	ln -sf $< $@
+
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/cio_mbx/proc2_mbx.c rtai-24.1.9-cio-1.3/examples/cio_mbx/proc2_mbx.c
--- rtai-24.1.9/examples/cio_mbx/proc2_mbx.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/cio_mbx/proc2_mbx.c	2002-07-29 17:50:26.000000000 +0200
@@ -0,0 +1,109 @@
+/*
+COPYRIGHT (C) 1999  Paolo Mantegazza (mantegazza@aero.polimi.it)
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+*/
+
+/*
+This example demonstrates the use of CIO RTAI mailboxes.  It has
+one task (task2_mbx.c) and one process (this file) that exchange messages
+on mailboxes.
+Mailboxes are created by process and linked to by task.
+Process prints what happens on console. Task prints what happens
+by rt_printk. Use dmesg to see it.
+Process send 11223344 to task. When receiving it, task sends back
+cccccccc to process.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+#define KEEP_STATIC_INLINE
+#include <rtai_lxrt_user.h>
+#include <rtai_lxrt.h>
+//#include <rtai_sched.h>
+
+
+#define TIMEOUT     1000000
+
+#define SLEEP_TIME  100000
+
+#define STACK_SIZE  2000
+
+#define CIO_MBX	// Use CIO mailbox version
+
+static MBX *smbx;
+static MBX *rmbx;
+RT_TASK *mtsk;
+
+static unsigned long name[2] = { 0x11223344, 0x55667788 };
+
+unsigned long msg, status;
+
+int main(void)
+{
+	char junk;
+
+ 	if (!(mtsk = rt_task_init(nam2num("MTSK"), 0, 0, 0))) {
+		printf("CANNOT INIT MASTER TASK\n");
+		exit(1);
+	}
+	printf("MASTER TASK INIT: name = %lx, address = %p.\n", nam2num("MTSK"), mtsk);
+
+	printf("MASTER TASK STARTS THE ONESHOT TIMER\n");
+	rt_set_oneshot_mode();
+	start_rt_timer(nano2count(10000000));
+
+	printf("MASTER TASK MAKES ITSELF PERIODIC WITH A PERIOD OF 1 ms\n");
+	rt_task_make_periodic(mtsk, rt_get_time(), nano2count(1000000));
+	rt_sleep(nano2count(1000000000));
+
+	mlockall(MCL_CURRENT | MCL_FUTURE);
+
+#ifdef CIO_MBX
+	smbx = cio_mbx_init(nam2num("SMB1"), 5, nam2num("SBU1")); //5
+	rmbx = cio_mbx_init(nam2num("RMB1"), 5, nam2num("RBU1")); //1
+#else
+	smbx = rt_mbx_init(nam2num("SMB1"), 5); //5
+	rmbx = rt_mbx_init(nam2num("RMB1"), 5); //1
+#endif
+
+	printf("Mailboxes created. Rmbx = 0x%x, Smbx = 0x%x\nType <return> to exchange messages > ", rmbx, smbx);
+	scanf("%c", &junk);
+
+        status = rt_mbx_send(smbx, &name[0], sizeof(name[0]));
+	printf("Message %x sent in mailbox - status is %ld\n", name[0], status);
+	status = rt_mbx_receive_timed(rmbx, &msg, sizeof(msg), nano2count(1000000000));
+	printf("Received %x in mailbox - status is %ld\n", msg, status);
+	printf("Type <return> to delete mailboxes > ");
+	scanf("%c", &junk);
+
+#ifdef CIO_MBX
+	cio_mbx_delete(smbx, /*nam2num("SMB1"), */ nam2num("SBU1")); //5
+	cio_mbx_delete(rmbx, /*nam2num("RMB1"),  */ nam2num("RBU1")); //1
+#else
+	rt_mbx_delete(smbx); //5
+	rt_mbx_delete(rmbx); //1
+#endif
+	exit(0);
+}
+
+
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/cio_mbx/proc_mbx.c rtai-24.1.9-cio-1.3/examples/cio_mbx/proc_mbx.c
--- rtai-24.1.9/examples/cio_mbx/proc_mbx.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/cio_mbx/proc_mbx.c	2002-07-29 17:50:26.000000000 +0200
@@ -0,0 +1,95 @@
+/*
+COPYRIGHT (C) 1999  Paolo Mantegazza (mantegazza@aero.polimi.it)
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+*/
+
+/*
+This example demonstrates the use of CIO RTAI mailboxes.  It has
+one task and one process that exchange messages on mailboxes.
+Mailboxes are created by task (task_mbx.c) and linked to by process (this file).
+Process prints what happens on console. Task prints what happens
+by rt_printk. Use dmesg to see it.
+Process send 11223344 to task. When receiving it, task sends back
+cccccccc to process.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+#define KEEP_STATIC_INLINE
+#include <rtai_lxrt_user.h>
+#include <rtai_lxrt.h>
+
+
+#define TIMEOUT     1000000
+
+#define SLEEP_TIME  100000
+
+#define STACK_SIZE  2000
+
+static MBX *smbx;
+static MBX *rmbx;
+RT_TASK *mtsk;
+
+static unsigned long name[2] = { 0x11223344, 0x55667788 };
+
+unsigned long msg;
+
+int main(void)
+{
+	char c;
+
+ 	if (!(mtsk = rt_task_init(nam2num("MTSK"), 0, 0, 0))) {
+		printf("CANNOT INIT MASTER TASK\n");
+		exit(1);
+	}
+	printf("MASTER TASK INIT: name = %lx, address = %p.\n", nam2num("MTSK"), mtsk);
+
+	printf("MASTER TASK STARTS THE ONESHOT TIMER\n");
+	rt_set_oneshot_mode();
+	start_rt_timer(nano2count(10000000));
+
+	printf("MASTER TASK MAKES ITSELF PERIODIC WITH A PERIOD OF 1 ms\n");
+	rt_task_make_periodic(mtsk, rt_get_time(), nano2count(1000000));
+	rt_sleep(nano2count(1000000000));
+
+        if (!(rmbx = rt_get_adr(nam2num("SMB1")))) {
+                printf("CANNOT FIND MAILBOX SMB1\n");
+                exit(1);
+        }
+        if (!(smbx = rt_get_adr(nam2num("RMB1")))) {
+                printf("CANNOT FIND MAILBOX RMB1\n");
+                exit(1);
+        }
+	mlockall(MCL_CURRENT | MCL_FUTURE);
+
+	printf("Mailboxes created. Rmbx = %x, Smbx = %x\nType <return> to exchange messages > ", rmbx, smbx);
+	scanf("%c", &c);
+        rt_mbx_send(smbx, &name[0], sizeof(name[0]));
+	printf("Message %x sent in mailbox\n", name[0]);
+	rt_mbx_receive_timed(rmbx,&msg, sizeof(msg), nano2count(1000000000));
+	printf("Received %x in mailbox\n", msg);
+
+	exit(0);
+}
+
+
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/cio_mbx/README rtai-24.1.9-cio-1.3/examples/cio_mbx/README
--- rtai-24.1.9/examples/cio_mbx/README	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/cio_mbx/README	2002-07-29 17:50:26.000000000 +0200
@@ -0,0 +1,11 @@
+****** CIO_MBX EXAMPLE ******
+
+This example demonstrates the use of CIO RTAI mailboxes.
+It has one process and one task that exchange messages on mailboxes.
+Just run it for some time, look at what the process prints on console
+and the task prints by rt_printk (use dmesg).
+
+To use it just type:
+
+make
+./run or ./run2
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/cio_mbx/run rtai-24.1.9-cio-1.3/examples/cio_mbx/run
--- rtai-24.1.9/examples/cio_mbx/run	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/cio_mbx/run	2002-07-29 17:50:26.000000000 +0200
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cat <<-EOF
+
+This example demonstrates the use of CIO RTAI mailboxes.  It has
+one task and one process that exchange messages on mailboxes.
+Mailboxes are created by task and linked to by process.
+Process prints what happens on console. Task prints what happens
+by rt_printk. Use dmesg to see it.
+Process send 11223344 to task. When receiving it, task sends back
+cccccccc to process.
+
+EOF
+echo -n "Type <return> to start test > "
+read junk
+
+sync
+../../scripts/rt_modprobe task_mbx.o
+
+./proc_mbx
+
+echo -n "Type <return> to remove modules > "
+read junk
+
+sync
+../../scripts/rt_rmmod task_mbx
+
+echo -n "Type <return> to leave this test > "
+read junk
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/cio_mbx/run2 rtai-24.1.9-cio-1.3/examples/cio_mbx/run2
--- rtai-24.1.9/examples/cio_mbx/run2	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/cio_mbx/run2	2002-07-29 17:50:26.000000000 +0200
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+cat <<-EOF
+
+This example demonstrates the use of CIO RTAI mailboxes.  It has
+one task and one process that exchange messages on mailboxes.
+Mailboxes are created by process and linked to by task.
+Process prints what happens on console. Task prints what happens
+by rt_printk. Use dmesg to see it.
+Process send 11223344 to task. When receiving it, task sends back
+cccccccc to process.
+
+EOF
+echo -n "Type <return> to start test > "
+read junk
+
+sync
+../../scripts/rt_modprobe task2_mbx.o
+
+./proc2_mbx
+
+echo -n "Type <return> to remove modules > "
+read junk
+
+sync
+../../scripts/rt_rmmod task2_mbx
+
+echo -n "Type <return> to leave this test > "
+read junk
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/cio_mbx/task2_mbx.c rtai-24.1.9-cio-1.3/examples/cio_mbx/task2_mbx.c
--- rtai-24.1.9/examples/cio_mbx/task2_mbx.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/cio_mbx/task2_mbx.c	2002-07-29 17:50:26.000000000 +0200
@@ -0,0 +1,152 @@
+/*
+COPYRIGHT (C) 1999  Paolo Mantegazza (mantegazza@aero.polimi.it)
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+*/
+
+/*
+This example demonstrates the use of CIO RTAI mailboxes.  It has
+one task (this file) and one process (proc2_mbx.c) that exchange messages
+on mailboxes.
+Mailboxes are created by process and linked to by task.
+Process prints what happens on console. Task prints what happens
+by rt_printk. Use dmesg to see it.
+Process send 11223344 to task. When receiving it, task sends back
+cccccccc to process.
+*/
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <rtai.h>
+#include <rtai_sched.h>
+#include <rtai_nam2num.h>
+#include <registry.h>
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
+
+#define MBX_TYPE  RES_Q
+//#define MBX_TYPE  FIFO_Q
+//#define MBX_TYPE  PRIO_Q
+
+#define TIMEOUT     1000000
+
+#define SLEEP_TIME  100000
+
+#define STACK_SIZE  2000
+
+#define CIO_MBX
+
+static volatile int cpu_used[NR_RT_CPUS];
+static volatile int premature;
+
+static RT_TASK btask;
+
+static MBX *smbx;
+static MBX *rmbx;
+
+static int bstat;
+
+
+static void bfun(int t)
+{
+	unsigned long msg, status;
+	unsigned long name = 0xcccccccc;
+	unsigned long counter1 = 10;
+
+	while ((!(smbx = rt_get_adr( nam2num("RMB1") ) ) || !(rmbx = rt_get_adr(nam2num( "SMB1" ) ) ) ) &&  (counter1 > 0 )) {
+
+		rt_printk("<%s %d> Before sleep in waiting loop\n", __FILE__, __LINE__);
+
+                rt_sleep(nano2count(1000000000));
+                rt_printk("<%s %d> Wait for mbx %d \n", __FILE__, __LINE__, counter1);
+                counter1--;
+	}
+
+	if (counter1 == 0)  {
+		rt_printk("<%s %d> Mailboxes not found \n", __FILE__, __LINE__);
+		goto prem;
+	}
+
+	while (1) {
+		cpu_used[hard_cpu_id()]++;
+
+		msg = 0LL;
+		bstat = 'r';
+		status = rt_mbx_receive(rmbx, &msg, sizeof(msg));
+		rt_printk("<%s %d> %x received in mailbox - status is %d.\n",
+						__FILE__, __LINE__, msg, status);
+		if (msg == 0x11223344) {
+			t = 0;
+		} else {
+			rt_printk("<%s %d> SERVER RECEIVED AN UNKNOWN MSG: 0x%x, STAT: %c.\n", __FILE__, __LINE__, msg, bstat);
+			t = 0;
+			goto prem;
+		}
+		bstat = '0';
+		status = rt_mbx_send(smbx, &name, sizeof(name));
+		rt_printk("<%s %d> %x sent in mailbox - status is %d.\n",
+					__FILE__, __LINE__, name, status);
+	}
+prem:
+	premature = 1;
+	rt_printk("<%s %d> SERVER TASK ENDS PREMATURELY.\n", __FILE__, __LINE__);
+}
+
+int init_module(void)
+{
+/*#ifdef CIO_MBX
+	cio_mbx_init(&smbx, 8, nam2num("SBU1")); //5
+	cio_mbx_init(&rmbx, 8, nam2num("RBU1")); //1
+#else
+	rt_mbx_init(&smbx, 8); //5
+	rt_mbx_init(&rmbx, 8); //1
+#endif
+	rt_register(nam2num("SMB1"), &smbx, IS_MBX, 0);
+	rt_register(nam2num("RMB1"), &rmbx, IS_MBX, 0);*/
+	rt_task_init(&btask, bfun, 0, STACK_SIZE, 0, 0, 0);
+	rt_set_oneshot_mode();
+	start_rt_timer(nano2count(SLEEP_TIME));
+	rt_task_resume(&btask);
+	return 0;
+}
+
+void cleanup_module(void)
+{
+//	int cpuid;
+
+	stop_rt_timer();
+/*#ifdef CIO_MBX
+	cio_mbx_delete(&smbx, nam2num("SBU1"));
+	cio_mbx_delete(&rmbx, nam2num("RBU1"));
+#else
+	rt_drg_on_adr(&smbx);
+	rt_drg_on_adr(&rmbx);
+	rt_mbx_delete(&smbx);
+	rt_mbx_delete(&rmbx);
+#endif*/
+	rt_task_delete(&btask);
+/*	printk("\n\nCPU USE SUMMARY (AVRG WAIT TIME):\n");
+	for (cpuid = 0; cpuid < NR_RT_CPUS; cpuid++) {
+		printk("# %d -> %d (%d)\n", cpuid, cpu_used[cpuid], meant[cpuid]);
+	}
+	printk("END OF CPU USE SUMMARY\n\n");
+	if (premature) {
+		printk("\n\nPREMATURE END\n");
+	}*/
+}
+
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/cio_mbx/task_mbx.c rtai-24.1.9-cio-1.3/examples/cio_mbx/task_mbx.c
--- rtai-24.1.9/examples/cio_mbx/task_mbx.c	1970-01-01 01:00:00.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/cio_mbx/task_mbx.c	2002-07-29 17:50:26.000000000 +0200
@@ -0,0 +1,126 @@
+/*
+COPYRIGHT (C) 1999  Paolo Mantegazza (mantegazza@aero.polimi.it)
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+*/
+
+/*
+This example demonstrates the use of CIO RTAI mailboxes.  It has
+one task and one process that exchange messages on mailboxes.
+Mailboxes are created by task (this file) and linked to by process (proc_mbx.c).
+Process prints what happens on console. Task prints what happens
+by rt_printk. Use dmesg to see it.
+Process send 11223344 to task. When receiving it, task sends back
+cccccccc to process.
+*/
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <rtai.h>
+#include <rtai_sched.h>
+#include <rtai_nam2num.h>
+#include <registry.h>
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
+
+#define MBX_TYPE  RES_Q
+//#define MBX_TYPE  FIFO_Q
+//#define MBX_TYPE  PRIO_Q
+
+#define TIMEOUT     1000000
+
+#define SLEEP_TIME  100000
+
+#define STACK_SIZE  2000
+
+#define CIO_MBX
+
+static volatile int cpu_used[NR_RT_CPUS];
+static volatile int premature;
+
+static RT_TASK btask;
+
+static MBX smbx;
+static MBX rmbx;
+
+static int mstat[2];
+static int bstat;
+
+static void bfun(int t)
+{
+	unsigned long msg;
+	unsigned long name = 0xcccccccc;
+
+	while (1) {
+		cpu_used[hard_cpu_id()]++;
+
+		msg = 0LL;
+		bstat = 'r';
+		rt_mbx_receive(&rmbx, &msg, sizeof(msg));
+		rt_printk("<%s %d> %x received in mailbox.\n", __FILE__, __LINE__, msg);
+		if (msg == 0x11223344) {
+			t = 0;
+		} else {
+			rtai_print_to_screen("SERVER RECEIVED AN UNKNOWN MSG: %x%x, STAT: %c %c %c.\n", ((int *)&msg)[1], ((int *)&msg)[0], mstat[0], mstat[1], bstat);
+			t = 0;
+			goto prem;
+		}
+		bstat = '0';
+		rt_mbx_send(&smbx, &name, sizeof(name));
+		rt_printk("<%s %d> %x sent in mailbox.\n", __FILE__, __LINE__, name);
+	}
+prem:
+	premature = 1;
+	rtai_print_to_screen("SERVER TASK ENDS PREMATURELY.\n");
+}
+
+int init_module(void)
+{
+#ifdef CIO_MBX
+	cio_mbx_init(&smbx, 8, nam2num("SBU1")); //5
+	cio_mbx_init(&rmbx, 8, nam2num("RBU1")); //1
+#else
+	rt_mbx_init(&smbx, 8); //5
+	rt_mbx_init(&rmbx, 8); //1
+#endif
+	rt_register(nam2num("SMB1"), &smbx, IS_MBX, 0);
+	rt_register(nam2num("RMB1"), &rmbx, IS_MBX, 0);
+	rt_task_init(&btask, bfun, 0, STACK_SIZE, 0, 0, 0);
+	rt_set_oneshot_mode();
+	start_rt_timer(nano2count(SLEEP_TIME));
+	rt_task_resume(&btask);
+	return 0;
+}
+
+void cleanup_module(void)
+{
+//	int cpuid;
+
+	stop_rt_timer();
+#ifdef CIO_MBX
+	cio_mbx_delete(&smbx, nam2num("SBU1"));
+	cio_mbx_delete(&rmbx, nam2num("RBU1"));
+#else
+	rt_drg_on_adr(&smbx);
+	rt_drg_on_adr(&rmbx);
+	rt_mbx_delete(&smbx);
+	rt_mbx_delete(&rmbx);
+#endif
+	rt_task_delete(&btask);
+}
+
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/EXAMPLES.INDEX rtai-24.1.9-cio-1.3/examples/EXAMPLES.INDEX
--- rtai-24.1.9/examples/EXAMPLES.INDEX	2002-01-04 14:33:38.000000000 +0100
+++ rtai-24.1.9-cio-1.3/examples/EXAMPLES.INDEX	2002-07-29 17:50:10.000000000 +0200
@@ -2,24 +2,26 @@
 
 edf: a simple check of Early Deadline First (EDF) scheduling.
 
-fastick: simulate a higher frequency Linux tick for a task communicating with 
+fastick: simulate a higher frequency Linux tick for a task communicating with
          a real time task or an interrupt handler through a fifo.
 
-fp: demonstrates the support of floating point operations in real-time tasks 
+fp: demonstrates the support of floating point operations in real-time tasks
     by calculating a sine in a real time tasks that preempts a user process
     carrying out floating point operations.
 
 frank: examples of fifos programming.
 
-jepplin: semaphores and message queues (in fact RTAI mailboxes). 
+jepplin: semaphores and message queues (in fact RTAI mailboxes).
 
-jitter_free_sw: NTASKS realtime tasks running periodically in oneshot mode, 
+jitter_free_sw: NTASKS realtime tasks running periodically in oneshot mode,
                 produce a rectangular wave on the parallel port. It anticipates
                 the square wave transition times, then keeps polling on the
                 timer to get a very precise switch.
 
 lockcpu: reserve a CPU only to real time tasks.
 
+cio_mbx : demonstrates the use of CIO mailboxes
+
 mbx: demonstrates the use of RTAI mailboxes.
 
 mbx_del: demonstrates how tasks waiting on a mailbox are released when it is
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/examples/Makefile rtai-24.1.9-cio-1.3/examples/Makefile
--- rtai-24.1.9/examples/Makefile	2002-04-03 22:42:11.000000000 +0200
+++ rtai-24.1.9-cio-1.3/examples/Makefile	2002-07-29 17:50:10.000000000 +0200
@@ -1,7 +1,7 @@
 
 # list of all examples
 examples := buslokchk condtest edf fastick fp frank jepplin \
-  jitter_free_sw lockcpu mbx mbx_del msg_clock msgsw namedstuff \
+  jitter_free_sw lockcpu mbx mbx_del cio_mbx msg_clock msgsw namedstuff \
   parport preempt prioinher res_sem resumefromintr rr sem_clock \
   sound stress sw switches sysreq tasktimer timer xmsgsw zentr_preempt
 
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/include/rtai_lxrt.h rtai-24.1.9-cio-1.3/include/rtai_lxrt.h
--- rtai-24.1.9/include/rtai_lxrt.h	2002-04-15 09:23:43.000000000 +0200
+++ rtai-24.1.9-cio-1.3/include/rtai_lxrt.h	2002-07-29 17:50:06.000000000 +0200
@@ -202,6 +202,9 @@
 #define DELETE_DEREGISTER	1022
 #define FORCE_TASK_SOFT  	1023
 
+#define CIO_MBX_INIT		1100
+#define CIO_MBX_DELETE		1101
+
 #define FORCE_SOFT 0x80000000
 
 struct rt_fun_entry { unsigned long long type; void *fun; };
@@ -232,9 +235,21 @@
 int  set_rt_fun_ext_index(struct rt_fun_entry *fun, int idx);
 void reset_rt_fun_ext_index( struct rt_fun_entry *fun, int idx);
 
+
+#include <rtai_sched.h>
+
+
+
 //#ifdef LXRT_MODULE
 #ifdef MODULE
 
+//extern int cio_mbx_init_f(MBX *mbx, int size, int name, unsigned long pid);
+//#define cio_mbx_init(m, s, n)  cio_mbx_init_f((m), (s), (n), (unsigned long)(&(__this_module)))
+extern int cio_typed_mbx_init_f(MBX *mbx, int size, int qtype, int name, unsigned long pid);
+#define cio_typed_mbx_init(m, s, t, n)  cio_typed_mbx_init_f((m), (s), (t), (n), (unsigned long)(&(__this_module)))
+extern int cio_mbx_delete_f(MBX *mbx, int name, unsigned long pid);
+#define cio_mbx_delete(m, n)  cio_mbx_delete_f((m), (n), (unsigned long)(&(__this_module)))
+
 #include <asm/rtai_lxrt.h>
 
 /*
@@ -780,6 +795,22 @@
 	return rtai_lxrt(BIDX, SIZARG, MBX_DELETE, &arg).i[LOW];
 }
 
+DECLARE void *cio_typed_mbx_init(int name, int size, int qtype, int buffer_name)
+{
+	struct { int name; int size; int qtype; int buffer_name; } arg = { name, size, qtype, buffer_name };
+	return rtai_lxrt(BIDX, SIZARG, CIO_MBX_INIT, &arg).v[LOW];
+}
+
+#define cio_mbx_init(name, size, buffer_name) cio_typed_mbx_init(name, size, FIFO_Q, buffer_name)
+
+DECLARE int cio_mbx_delete(MBX *mbx,/* int name,*/ int buffer_name)
+{
+	struct { MBX *mbx;/* int name;*/ int buffer_name; } arg = { mbx, /*name,*/ buffer_name };
+	//printf("cio_mbx_delete - Call rtai_lxrt for mailbox at %p with buffer name 0x%x\n", mbx, buffer_name);
+	return rtai_lxrt(BIDX, SIZARG, CIO_MBX_DELETE, &arg).i[LOW];
+}
+
+
 DECLARE int rt_mbx_send(MBX *mbx, void *msg, int msg_size)
 {
 	struct { MBX *mbx; char *msg; int msg_size; } arg = { (MBX *)mbx, (char *)msg, msg_size };
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/include/rtai_sched.h rtai-24.1.9-cio-1.3/include/rtai_sched.h
--- rtai-24.1.9/include/rtai_sched.h	2002-04-16 18:28:24.000000000 +0200
+++ rtai-24.1.9-cio-1.3/include/rtai_sched.h	2002-07-29 19:33:10.000000000 +0200
@@ -372,6 +372,14 @@
 
 extern int rt_mbx_delete(MBX *mbx);
 
+extern int cio_mbx_init_f(MBX *mbx, int size, int buffer_name, unsigned long pid);
+#define cio_mbx_init(x, y, z)  cio_mbx_init_f((x), (y), (z), \
+					(unsigned long)(&(__this_module)))
+
+extern int cio_mbx_delete_f(MBX *mbx, int buffer_name, unsigned long pid);
+#define cio_mbx_delete(x, y)  cio_mbx_delete_f((x), (y), \
+					(unsigned long)(&(__this_module)))
+
 extern int rt_mbx_send(MBX *mbx, void *msg, int msg_size);
 
 extern int rt_mbx_send_wp(MBX *mbx, void *msg, int msg_size);
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/lxrt/lxrt.c rtai-24.1.9-cio-1.3/lxrt/lxrt.c
--- rtai-24.1.9/lxrt/lxrt.c	2002-04-15 09:23:30.000000000 +0200
+++ rtai-24.1.9-cio-1.3/lxrt/lxrt.c	2002-07-29 17:50:14.000000000 +0200
@@ -47,6 +47,7 @@
 #include <rtai_lxrt.h>
 #include <rtai_trace.h>
 #include "rtai_lxk.h"
+#include "cio_mem_mgr.h"
 
 #ifdef CONFIG_PROC_FS
 #include <linux/stat.h>
@@ -784,10 +785,14 @@
 #define ar   ((unsigned long *)arg)
 #define MANYARGS ar[0],ar[1],ar[2],ar[3],ar[4],ar[5],ar[6],ar[7],ar[8],ar[9]
 
+	char *func __attribute__ ((unused)) = "lxrt_handler";
+
 	union {unsigned long name; RT_TASK *rt_task; SEM *sem; MBX *mbx; } arg0;
 	int srq;
 	RT_TASK *task;
 
+	DBG("%s - Entering LXRT handler\n", func);
+
 //	if (current != CURRENT) {
 //		rt_printk("(HDLR) CURRENT (%d) != current (%d).\n", current->pid, CURRENT->pid);
 //	}
@@ -804,6 +809,7 @@
 	}
 
 	srq = SRQ(lxsrq);
+	DBG("%s - SRQ is %d\n", func, srq);
 	if (srq < MAX_LXRT_FUN) {
 		int idx;
 		unsigned long long type;
@@ -822,6 +828,7 @@
 			return 0;
 		}
 
+		DBG("%s - Function found for SRQ %d\n", func, srq);
 #ifdef ALLOW_SYSW
 		if ((task = current->this_rt_task[0]) && task->pstate) {
 			task->pstate = 0;
@@ -833,7 +840,9 @@
 #endif
    
 		if ((type = funcm[srq].type)) {
-			if (!rt_is_linux()) { 
+			DBG("%s - Before rt_is_linux test for SRQ %d\n", func, srq);
+			if (!rt_is_linux()) {
+				DBG("%s - After rt_is_linux test for SRQ %d - Not case\n", func, srq);
 				// Any type 1 can now reenter.
 				// Buuut, you cannot rt_sleep() or do anything
 				// that would cause a switch back to Linux
@@ -841,10 +850,12 @@
 				return ((long long (*)(unsigned long, ...))funcm[srq].fun)(MANYARGS);
 			} else {
 			        int net_rpc;
+				DBG("%s - After rt_is_linux test for SRQ %d - Else case\n", func, srq);
 			        net_rpc = idx == 2 && !srq;
 				return __lxrt_resume(funcm[srq].fun, NARG(lxsrq), (int *)arg, net_rpc ? ((long long *)((int *)arg + 2))[0] : type, current->this_rt_task[0], net_rpc);
 			}
 		} else {
+			DBG("%s - Direct execution for SRQ %d\n", func, srq);
 			return ((long long (*)(unsigned long, ...))funcm[srq].fun)(MANYARGS);
 	        }
 	}
@@ -892,13 +903,21 @@
 		}
 
 		case MBX_INIT: {
+			DBG("%s - Init mailbox request for name 0x%x\n",
+						func, arg0.name);
 			if (rt_get_adr(arg0.name)) {
+			DBG("%s - Mailbox for name 0x%x already exists\n",
+						func, arg0.name);
 				return 0;
 			}
 			if ((arg0.mbx = rt_malloc(sizeof(MBX)))) {
 				struct arg { int name; int size; int qtype; };
+				DBG("%s - Mailbox structure allocated for name 0x%x\n",
+						func, arg0.name);
 				rt_typed_mbx_init(arg0.mbx, larg->size, larg->qtype);
 				if (rt_register(larg->name, arg0.mbx, IS_MBX, current)) {
+				DBG("%s - Mailbox for name 0x%x registered\n",
+						func, arg0.name);
 					return arg0.name;
 				} else {
 					rt_free(arg0.mbx);
@@ -907,6 +926,22 @@
 			return 0;
 		}
 
+		case CIO_MBX_INIT: {
+			if (rt_get_adr(arg0.name)) {
+				return 0;
+			}
+			if ((arg0.mbx = cio_kmalloc(arg0.name, sizeof(MBX)))) {
+				struct arg { int name; int size; int qtype; int buffer_name; };
+				if (cio_typed_mbx_init(arg0.mbx, larg->size, larg->qtype, larg->buffer_name) == 0 &&
+					rt_register(larg->name, arg0.mbx, IS_MBX, current)) {
+					return arg0.name;
+				} else {
+					cio_kfree(arg0.name);
+				}
+			}
+			return 0;
+		}
+
 		case MBX_DELETE: {
 			if (rt_mbx_delete(arg0.mbx)) {
 				return -EFAULT;
@@ -914,7 +949,21 @@
 			rt_free(arg0.mbx);
 			return rt_drg_on_adr(arg0.mbx);
 		}
-#ifdef HARD_LXRT	
+
+		case CIO_MBX_DELETE: {
+			struct arg { MBX *mbx;/* int name;*/ int buffer_name; } ;
+			DBG("%s - Delete mailbox request at @ 0x%p\n",
+						func, arg0.mbx);
+			DBG("%s - Name is 0x%x - Buffer name is 0x%x\n",
+						func,/* larg->name*/ rt_get_name (arg0.mbx) , larg->buffer_name);
+			if (cio_mbx_delete(arg0.mbx, larg->buffer_name)) {
+				return -EFAULT;
+			}
+			cio_kfree( rt_get_name (arg0.mbx) /*larg->name*/);
+			return rt_drg_on_adr(arg0.mbx);
+		}
+
+#ifdef HARD_LXRT
 		case MAKE_HARD_RT: {
 			if (!(task = current->this_rt_task[0]) || task->is_hard){
 				 return 0;
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/lxrt/resumefromintr/run rtai-24.1.9-cio-1.3/lxrt/resumefromintr/run
--- rtai-24.1.9/lxrt/resumefromintr/run	2001-10-31 18:57:59.000000000 +0100
+++ rtai-24.1.9-cio-1.3/lxrt/resumefromintr/run	2002-07-29 17:50:33.000000000 +0200
@@ -5,6 +5,8 @@
 rmmod rtai
 sync
 insmod ../../modules/rtai.o
+insmod ../../modules/rtai_shm.o
+insmod ../../modules/cio_mem_mgr.o
 insmod ../../modules/rtai_sched.o
 insmod ../rtai_lxrt.o
 insmod ./handler.o
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/Makefile rtai-24.1.9-cio-1.3/Makefile
--- rtai-24.1.9/Makefile	2002-04-08 17:05:55.000000000 +0200
+++ rtai-24.1.9-cio-1.3/Makefile	2007-06-19 15:44:01.000000000 +0200
@@ -1,7 +1,7 @@
 VERSION = 24
 PATCHLEVEL = 1
 SUBLEVEL = 9
-EXTRAVERSION =
+EXTRAVERSION = -cio-1.3
 
 PROJECT = RTAI
 project = rtai
@@ -24,7 +24,8 @@
 	   fifos latency_calibration examples tasklets mups_examples \
 	   tbx posix watchdog testing trace rt_com libm leds rtnet libsf
 else
-SUBDIRS := rtaidir rt_mem_mgr shmem smpscheduler mupscheduler upscheduler \
+SUBDIRS := rtaidir rt_mem_mgr cio_mem_mgr shmem smpscheduler mupscheduler \
+	   upscheduler \
 	   fifos latency_calibration examples lxrt tasklets mups_examples \
 	   tbx posix watchdog testing trace rt_com_lxrt rt_com libm net_rpc \
 	   leds rtnet bits libsf fifos_lxrt
@@ -71,6 +72,7 @@
 
 dev:
 	-mknod -m 666 /dev/rtai_shm c 10 254
+	-mknod -m 666 /dev/cio_shm c 10 253
 	-mknod -m 666 /dev/rtf0 c 150 0
 	-mknod -m 666 /dev/rtf1 c 150 1
 	-mknod -m 666 /dev/rtf2 c 150 2
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/Makefile.modbuild rtai-24.1.9-cio-1.3/Makefile.modbuild
--- rtai-24.1.9/Makefile.modbuild	2002-04-04 02:27:15.000000000 +0200
+++ rtai-24.1.9-cio-1.3/Makefile.modbuild	2007-06-19 16:48:14.000000000 +0200
@@ -45,9 +45,9 @@
 # Include the make variables (CC, etc...)
 #
 
-#AS              = $(CROSS_COMPILE)as
-#LD              = $(CROSS_COMPILE)ld
-#CC              = $(CROSS_COMPILE)gcc
+AS              = $(CROSS_COMPILE)as
+LD              = $(CROSS_COMPILE)ld
+CC              = $(CROSS_COMPILE)gcc
 CXX             = $(CROSS_COMPILE)g++
 CPP             = $(CC) -E
 AR              = $(CROSS_COMPILE)ar
Les fichiers rtai-24.1.9/rt_com_lxrt/hello_world2_lxrt et rtai-24.1.9-cio-1.3/rt_com_lxrt/hello_world2_lxrt sont différents.
Les fichiers rtai-24.1.9/rt_com_lxrt/hello_world_lxrt et rtai-24.1.9-cio-1.3/rt_com_lxrt/hello_world_lxrt sont différents.
Les fichiers rtai-24.1.9/rt_com_lxrt/testcomlxrt et rtai-24.1.9-cio-1.3/rt_com_lxrt/testcomlxrt sont différents.
Les fichiers rtai-24.1.9/scripts/mkdep et rtai-24.1.9-cio-1.3/scripts/mkdep sont différents.
diff -uNr --exclude=.depend --exclude='ex_*.c' rtai-24.1.9/upscheduler/rtai_sched.c.ml rtai-24.1.9-cio-1.3/upscheduler/rtai_sched.c.ml
--- rtai-24.1.9/upscheduler/rtai_sched.c.ml	2002-04-04 02:38:45.000000000 +0200
+++ rtai-24.1.9-cio-1.3/upscheduler/rtai_sched.c.ml	2002-07-29 17:50:13.000000000 +0200
@@ -58,6 +58,7 @@
 #include <asm/rtai_sched.h>
 #include <rtai_sched.h>
 #include <rtai_trace.h>
+#include "cio_mem_mgr.h"
 
 MODULE_LICENSE("GPL");
 
@@ -2686,12 +2687,35 @@
 	return 0;
 }
 
+int cio_typed_mbx_init_f(MBX *mbx, int size, int qtype, int buffer_name, unsigned long pid)
+{
+	char *func __attribute__ ((unused)) = "cio_typed_mbx_init_f";
+
+ 	DBG("%s - Init mailbox at @ 0x%p of size %d with buffer name 0x%x\n",
+ 						func, mbx, size, buffer_name);
+
+	if (!(mbx->bufadr = cio_kmalloc_f(buffer_name, size, pid))) {
+		return -ENOMEM;
+	}
+	TRACE_RTAI_MBX(TRACE_RTAI_EV_MBX_INIT, mbx, size, 0);
+	rt_typed_sem_init(&(mbx->sndsem), 1, qtype & 3 ? qtype : BIN_SEM | qtype);
+	rt_typed_sem_init(&(mbx->rcvsem), 1, qtype & 3 ? qtype : BIN_SEM | qtype);
+	mbx->magic = RT_MBX_MAGIC;
+	mbx->size = mbx->frbs = size;
+	mbx->waiting_task = mbx->owndby = 0;
+	mbx->fbyte = mbx->lbyte = mbx->avbs = 0;
+	return 0;
+}
 
 int rt_mbx_init(MBX *mbx, int size)
 {
 	return rt_typed_mbx_init(mbx, size, PRIO_Q);
 }
 
+int cio_mbx_init_f(MBX *mbx, int size, int buffer_name, unsigned long pid)
+{
+	return cio_typed_mbx_init_f(mbx, size, PRIO_Q, buffer_name, pid);
+}
 
 int rt_mbx_delete(MBX *mbx)
 {
@@ -2706,10 +2730,32 @@
 	while (mbx->waiting_task) {
 		mbx_signal(mbx);
 	}
-	sched_free(mbx->bufadr); 
+	sched_free(mbx->bufadr);
 	return 0;
 }
 
+int cio_mbx_delete_f(MBX *mbx, int buffer_name, unsigned long pid)
+{
+	char *func __attribute__ ((unused)) = "cio_mbx_delete_f";
+
+	CHK_MBX_MAGIC;
+
+	DBG("%s - Delete mailbox at @ 0x%p with buffer name 0x%x\n",
+						func, mbx, buffer_name);
+
+        TRACE_RTAI_MBX(TRACE_RTAI_EV_MBX_DELETE, mbx, 0, 0);
+
+	mbx->magic = 0;
+	if (rt_sem_delete(&(mbx->sndsem)) || rt_sem_delete(&(mbx->rcvsem))) {
+		DBG("%s - Error in semaphores deletion\n", func);
+		return -EFAULT;
+	}
+	while (mbx->waiting_task) {
+		mbx_signal(mbx);
+	}
+	cio_kfree_f(buffer_name, pid);
+	return 0;
+}
 
 int rt_mbx_send(MBX *mbx, void *msg, int msg_size)
 {

