]> Zhao Yanbai Git Server - minix.git/commitdiff
added libddekit
authorDirk Vogt <dirk@minix3.org>
Fri, 25 Feb 2011 12:40:31 +0000 (12:40 +0000)
committerDirk Vogt <dirk@minix3.org>
Fri, 25 Feb 2011 12:40:31 +0000 (12:40 +0000)
31 files changed:
lib/Makefile
lib/libddekit/Makefile [new file with mode: 0644]
lib/libddekit/build/Makefile [new file with mode: 0644]
lib/libddekit/build/ddekit/Makefile [new file with mode: 0644]
lib/libddekit/build/ddekit_usb_client/Makefile [new file with mode: 0644]
lib/libddekit/build/ddekit_usb_server/Makefile [new file with mode: 0644]
lib/libddekit/src/common.h [new file with mode: 0644]
lib/libddekit/src/condvar.c [new file with mode: 0644]
lib/libddekit/src/dde.c [new file with mode: 0644]
lib/libddekit/src/dde.h [new file with mode: 0644]
lib/libddekit/src/debug.h [new file with mode: 0644]
lib/libddekit/src/initcall.c [new file with mode: 0644]
lib/libddekit/src/irq.c [new file with mode: 0644]
lib/libddekit/src/irq.h [new file with mode: 0644]
lib/libddekit/src/lock.c [new file with mode: 0644]
lib/libddekit/src/mem.c [new file with mode: 0644]
lib/libddekit/src/msg_queue.c [new file with mode: 0644]
lib/libddekit/src/panic.c [new file with mode: 0644]
lib/libddekit/src/pci.c [new file with mode: 0644]
lib/libddekit/src/pgtab.c [new file with mode: 0644]
lib/libddekit/src/printf.c [new file with mode: 0644]
lib/libddekit/src/resource.c [new file with mode: 0644]
lib/libddekit/src/semaphore.c [new file with mode: 0644]
lib/libddekit/src/thread.c [new file with mode: 0644]
lib/libddekit/src/thread.h [new file with mode: 0644]
lib/libddekit/src/timer.c [new file with mode: 0644]
lib/libddekit/src/timer.h [new file with mode: 0644]
lib/libddekit/src/usb_client.c [new file with mode: 0644]
lib/libddekit/src/usb_server.c [new file with mode: 0644]
lib/libddekit/src/util.h [new file with mode: 0644]
share/mk/bsd.prog.mk

index 4f7e8ba59bde4f9e2cce4a72cd1c0334e43d2d2d..e1485acec77a227aa5900ef757cb865211180b52 100644 (file)
@@ -2,7 +2,8 @@
 
 SUBDIR= csu libc libcurses libdriver libnetdriver libedit libm libsys \
        libtimers libutil libbz2 libl libhgfs libz libfetch libarchive    \
-       libvtreefs libaudiodriver libmthread libexec libdevman libusb     
+       libvtreefs libaudiodriver libmthread libexec libdevman libusb    \
+        libddekit 
 
 .if ${COMPILER_TYPE} == "ack"
 SUBDIR+= ack/libd ack/libe ack/libfp ack/liby
diff --git a/lib/libddekit/Makefile b/lib/libddekit/Makefile
new file mode 100644 (file)
index 0000000..a04e906
--- /dev/null
@@ -0,0 +1,6 @@
+
+.if ${COMPILER_TYPE} == "gnu" 
+SUBDIR = build
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/lib/libddekit/build/Makefile b/lib/libddekit/build/Makefile
new file mode 100644 (file)
index 0000000..7015b62
--- /dev/null
@@ -0,0 +1,6 @@
+.if ${COMPILER_TYPE} == "gnu"
+SUBDIR = ddekit ddekit_usb_client ddekit_usb_server
+.endif
+.include <bsd.subdir.mk>
+
+
diff --git a/lib/libddekit/build/ddekit/Makefile b/lib/libddekit/build/ddekit/Makefile
new file mode 100644 (file)
index 0000000..38e8c9a
--- /dev/null
@@ -0,0 +1,11 @@
+.if ${COMPILER_TYPE} == "gnu"
+LIB=           ddekit
+SRC_DIR = /usr/src/lib/libddekit/src 
+VPATH = $(SRC_DIR) 
+
+SRCS = pci.c printf.c mem.c pgtab.c dde.c initcall.c thread.c condvar.c lock.c semaphore.c timer.c panic.c irq.c resource.c msg_queue.c
+
+CFLAGS += -Wall 
+.endif
+.include <bsd.lib.mk>
+
diff --git a/lib/libddekit/build/ddekit_usb_client/Makefile b/lib/libddekit/build/ddekit_usb_client/Makefile
new file mode 100644 (file)
index 0000000..b5f94bf
--- /dev/null
@@ -0,0 +1,9 @@
+.if ${COMPILER_TYPE} == "gnu"
+LIB=           ddekit_usb_client
+SRC_DIR = /usr/src/lib/libddekit/src 
+VPATH = $(SRC_DIR) 
+SRCS = usb_client.c
+CFLAGS += -DDDEBUG=1 -Wall -I../../include
+.endif
+.include <bsd.lib.mk>
+
diff --git a/lib/libddekit/build/ddekit_usb_server/Makefile b/lib/libddekit/build/ddekit_usb_server/Makefile
new file mode 100644 (file)
index 0000000..aaf1d38
--- /dev/null
@@ -0,0 +1,10 @@
+.if ${COMPILER_TYPE} == "gnu"
+LIB=           ddekit_usb_server
+SRC_DIR = /usr/src/lib/libddekit/src 
+VPATH = $(SRC_DIR) 
+SRCS = usb_server.c
+CFLAGS += -DDDEBUG=1 -I../../include -Wall
+.endif
+.include <bsd.lib.mk>
+
+
diff --git a/lib/libddekit/src/common.h b/lib/libddekit/src/common.h
new file mode 100644 (file)
index 0000000..d74ac32
--- /dev/null
@@ -0,0 +1,14 @@
+#define _MINIX
+#define _POSIX_SOURCE
+#include <minix/callnr.h>
+#include <minix/com.h>
+#include <minix/config.h>
+#include <minix/const.h>
+#include <minix/endpoint.h>
+#include <minix/ipc.h>
+#include <minix/syslib.h>
+#include <minix/sysutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
diff --git a/lib/libddekit/src/condvar.c b/lib/libddekit/src/condvar.c
new file mode 100644 (file)
index 0000000..e2d43fb
--- /dev/null
@@ -0,0 +1,119 @@
+#include "common.h"
+
+#include <ddekit/condvar.h> 
+#include <ddekit/lock.h> 
+#include <ddekit/memory.h> 
+
+#ifdef DDEBUG_LEVEL_CONDVAR
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_CONDVAR
+#endif
+
+#include "debug.h"
+#include "util.h"
+#include "thread.h"
+
+struct ddekit_condvar {
+       ddekit_thread_t * wait_queue;
+};
+
+/*****************************************************************************/
+/*      ddekit_condvar_init                                                  */
+/*****************************************************************************/
+PUBLIC ddekit_condvar_t * ddekit_condvar_init(void) { 
+       ddekit_condvar_t *cv;
+       cv = (ddekit_condvar_t *) ddekit_simple_malloc(sizeof(ddekit_condvar_t));
+       DDEBUG_MSG_VERBOSE("cv: %p", cv);
+       return cv;
+}
+
+/*****************************************************************************/
+/*      ddekit_condvar_deinit                                                */
+/*****************************************************************************/
+PUBLIC void ddekit_condvar_deinit(ddekit_condvar_t *cvp) {
+       DDEBUG_MSG_VERBOSE("cv: %p", cvp);
+       ddekit_simple_free(cvp); 
+}
+
+/*****************************************************************************/
+/*      ddekit_condvar_wait                                                  */
+/*****************************************************************************/
+PUBLIC void ddekit_condvar_wait(ddekit_condvar_t *cv, ddekit_lock_t *mp) {
+       
+       DDEBUG_MSG_VERBOSE("wait cv: %p, thread id: %d, name: %s",
+               cv, ddekit_thread_myself()->id,  ddekit_thread_myself()->name);
+
+       ddekit_lock_unlock(mp);
+       
+       if(cv->wait_queue == NULL) {
+                       cv->wait_queue = ddekit_thread_myself();
+       } else {
+               ddekit_thread_t *pos = cv->wait_queue;
+               while(pos->next != NULL) {
+                       pos = pos->next;
+               }
+               pos->next = ddekit_thread_myself();
+       }
+
+       _ddekit_thread_schedule();
+
+       DDEBUG_MSG_VERBOSE("wakeup cv: %p, thread id: %d, name: %s",
+               cv, ddekit_thread_myself()->id,  ddekit_thread_myself()->name);
+
+       ddekit_lock_lock(mp);
+}
+/*****************************************************************************/
+/*      ddekit_condvar_wait_timed                                            */
+/*****************************************************************************/
+PUBLIC int ddekit_condvar_wait_timed
+(ddekit_condvar_t *cvp, ddekit_lock_t *mp, int timo)
+{
+       /* 
+        * Only used by ddefbsd, so not implemented
+        */
+       WARN_UNIMPL;
+       return 0;
+}
+
+
+/*****************************************************************************/
+/*      ddekit_condvar_signal                                                */
+/*****************************************************************************/
+PUBLIC void ddekit_condvar_signal(ddekit_condvar_t *cv) 
+{
+       
+       DDEBUG_MSG_VERBOSE("cv: %p", cv);
+       
+       if(cv->wait_queue) {
+               ddekit_thread_t *th = cv->wait_queue;
+               cv->wait_queue = th->next;
+               th->next = NULL;
+               _ddekit_thread_enqueue(th);
+
+               DDEBUG_MSG_VERBOSE("waking up cv: %p, thread id: %d, name: %s",
+                       cv, th->id, th->name);
+       }
+       ddekit_thread_schedule();
+}
+
+
+/*****************************************************************************/
+/*      ddekit_condvar_broadcast                                             */
+/*****************************************************************************/
+void ddekit_condvar_broadcast(ddekit_condvar_t *cv) { 
+       
+       DDEBUG_MSG_VERBOSE("cv: %p", cv);
+       
+       while (cv->wait_queue) {
+               ddekit_thread_t *th = cv->wait_queue;
+               cv->wait_queue = th->next;
+               th->next = NULL;
+               _ddekit_thread_enqueue(th);
+               
+               DDEBUG_MSG_VERBOSE("waking up cv: %p, thread id: %d, name: %s",
+                       cv, th->id, th->name);
+
+       }
+       ddekit_thread_schedule();
+}
+
diff --git a/lib/libddekit/src/dde.c b/lib/libddekit/src/dde.c
new file mode 100644 (file)
index 0000000..cfb84c7
--- /dev/null
@@ -0,0 +1,138 @@
+#include "common.h"
+#include <ddekit/initcall.h> 
+#include <ddekit/minix/msg_queue.h>
+#include <ddekit/panic.h> 
+#include <ddekit/pci.h> 
+#include <ddekit/semaphore.h> 
+#include <ddekit/timer.h> 
+#include <signal.h>
+
+#include "debug.h" 
+#include "timer.h"  /* _ddekit_timer_interrupt()   */
+#include "thread.h" /* _ddekit_thread_set_myprio() */
+#include "irq.h"
+
+
+static ddekit_sem_t *exit_sem;
+
+unsigned long long jiffies;
+
+void ddekit_pgtab_init(void);
+
+static  ddekit_thread_t *dispatch_th = 0;
+
+
+FORWARD _PROTOTYPE(void dispatcher_thread, (void * unused));
+FORWARD _PROTOTYPE(void ddekit_dispatcher_thread_init, (void));
+
+/****************************************************************************/
+/*      dispatcher_thread                                                   */
+/****************************************************************************/
+PRIVATE void dispatcher_thread(void *unused) {
+
+       /* 
+        * Gets all messages and dispatches them.
+        *
+        * NOTE: this thread runs only when no other ddekit is 
+        *       ready. So please take care that youre threads
+        *       leave some time for the others!
+        */
+       message m;
+       int r;
+       int i;
+
+       _ddekit_thread_set_myprio(0);
+
+       for( ; ; ) {
+
+               /* Trigger a timer interrupt at each loop iteration */
+               _ddekit_timer_update();
+               
+               /* Wait for messages */
+               if ((r = sef_receive(ANY, &m)) != 0) { 
+                               ddekit_panic("ddekit", "sef_receive failed", r);
+               }
+
+               
+               _ddekit_timer_interrupt(); 
+               
+               _ddekit_thread_wakeup_sleeping();
+               
+               if (is_notify(m.m_type)) {
+                       switch (_ENDPOINT_P(m.m_source)) { 
+                               case HARDWARE:
+                                       for     (i =0 ; i < 32 ; i++)
+                                       {
+                                               if(m.NOTIFY_ARG & (1 << i)) 
+                                               {
+                                                       _ddekit_interrupt_trigger(i);
+                                               }
+                                       }
+                                       break;
+                               case CLOCK:
+                                       _ddekit_timer_pending = 0;
+                                       break;
+                               default:
+                                       ddekit_thread_schedule();
+                       }
+
+               } else {
+                       
+                       /* 
+                        * I don't know how to handle this msg,
+                        * but maybe we have a msg queue which can
+                        * handle this msg.
+                        */
+
+                       ddekit_minix_queue_msg(&m);
+               } 
+       }
+}
+
+/****************************************************************************/
+/*      ddekit_dispatcher_thread_init                                       */
+/****************************************************************************/
+PRIVATE void ddekit_dispatcher_thread_init()
+{
+
+       dispatch_th = ddekit_thread_create(dispatcher_thread, NULL, "dispatch");
+
+       ddekit_thread_schedule();
+}
+
+/****************************************************************************/
+/*      ddekit_init                                                         */
+/****************************************************************************/
+PUBLIC void ddekit_init(void)
+{
+       sef_startup();
+
+       ddekit_pgtab_init();
+
+       ddekit_init_threads();
+
+       ddekit_init_irqs();
+
+       ddekit_init_timers();
+       
+       ddekit_dispatcher_thread_init();
+       
+       exit_sem = ddekit_sem_init(0);
+}
+
+/****************************************************************************/
+/*      dispatcher_shutdown                                                 */
+/****************************************************************************/
+void ddekit_shutdown() 
+{
+       ddekit_sem_up(exit_sem);
+}
+
+/****************************************************************************/
+/*  ddekit_minix_wait_exit                                                  */
+/****************************************************************************/
+void ddekit_minix_wait_exit(void)
+{
+       ddekit_sem_down(exit_sem);
+}
+
diff --git a/lib/libddekit/src/dde.h b/lib/libddekit/src/dde.h
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/lib/libddekit/src/debug.h b/lib/libddekit/src/debug.h
new file mode 100644 (file)
index 0000000..f2e5907
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef DDEKIT_DEBUG_MACROS_H
+#define DDEKIT_DEBUG_MACROS_H
+
+#include <ddekit/printf.h>
+#include <ddekit/debug.h>
+
+#endif /* DDEKIT_DEBUG_MACROS_H */
diff --git a/lib/libddekit/src/initcall.c b/lib/libddekit/src/initcall.c
new file mode 100644 (file)
index 0000000..4963b0b
--- /dev/null
@@ -0,0 +1,57 @@
+#include "common.h" 
+
+#include <ddekit/initcall.h>
+
+
+#ifdef DDEKIT_DEBUG_INITCALL
+#undef DDEBUG
+#define DDEBUG DDEKIT_DEBUG_INITCALL
+#endif
+
+#include "debug.h" 
+static struct __ddekit_initcall_s head = {0,0,0};
+
+/****************************************************************************/
+/*        __ddekit_add_initcall                                             */
+/****************************************************************************/
+PUBLIC void __attribute__((used)) 
+__ddekit_add_initcall(struct __ddekit_initcall_s * ic) {
+
+       /* This function is required for the DDEKIT_INITCALL makro */
+        
+       struct __ddekit_initcall_s *i = 0; 
+       
+       DDEBUG_MSG_VERBOSE("adding initcall (%p) to %p with prio %d head at %p",
+       ic, ic->func, ic->prio, &head);  
+
+       for (i = &head; i; i=i->next) 
+       {
+               if (!i->next) { 
+                       i->next = ic;
+                       return;
+               }
+               if (i->next->prio > ic->prio) {
+                       ic->next = i->next;
+                       i->next = ic;
+                       return;
+               }
+       } 
+}
+
+/****************************************************************************/
+/*        ddekit_do_initcalls                                               */
+/****************************************************************************/
+PUBLIC void ddekit_do_initcalls()
+{ 
+       struct __ddekit_initcall_s *i = 0; 
+
+       DDEBUG_MSG_VERBOSE("exectuing initcalls (head at %p, head->next = %p)",
+               &head, head.next);
+       
+       for (i = head.next; i; i=i->next) { 
+               DDEBUG_MSG_VERBOSE("executing initcall: %p with prio %d",
+                  i->func, i->prio); 
+               i->func();
+       }
+}
diff --git a/lib/libddekit/src/irq.c b/lib/libddekit/src/irq.c
new file mode 100644 (file)
index 0000000..c875831
--- /dev/null
@@ -0,0 +1,257 @@
+#include "common.h"
+#include <ddekit/interrupt.h>
+#include <ddekit/memory.h>
+#include <ddekit/semaphore.h>
+#include <ddekit/thread.h>
+
+#ifdef DDEBUG_LEVEL_IRQ
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_IRQ
+#endif
+
+#include "debug.h"
+
+struct ddekit_irq_s { 
+       int irq;
+       int irq_hook;
+       int shared;
+       void(*thread_init)(void *);
+       void(*handler)(void *);
+       void *priv;
+       int enabled;
+       ddekit_thread_t *th;
+       ddekit_sem_t *sem;
+       struct ddekit_irq_s *next; 
+};
+
+static struct ddekit_irq_s *irqs = 0; 
+static ddekit_lock_t lock; 
+
+/******************************************************************************
+ *    Local helpers                                                           *
+ *****************************************************************************/
+
+
+FORWARD _PROTOTYPE( void ddekit_irq_lock, (void));
+FORWARD _PROTOTYPE( void ddekit_irq_unlock, (void));
+FORWARD _PROTOTYPE( struct ddekit_irq_s* find_by_irq, (int irq));
+FORWARD _PROTOTYPE( void ddekit_irq_remove, (struct ddekit_irq_s *irq_s));
+FORWARD _PROTOTYPE( void ddekit_irq_thread, (void *data));
+
+/******************************************************************************
+ *       ddekit_irq_lock                                                      *
+ *****************************************************************************/
+PRIVATE void  ddekit_irq_lock(void)
+{  
+       ddekit_lock_lock(&lock);
+}
+
+/******************************************************************************
+ *       ddekit_irq_unlock                                                    *
+ *****************************************************************************/
+PRIVATE void ddekit_irq_unlock(void)
+{  
+       ddekit_lock_unlock(&lock);
+}
+
+/******************************************************************************
+ *       find_by_irq                                                          *
+ *****************************************************************************/
+PRIVATE struct ddekit_irq_s * find_by_irq(int irq)
+{ 
+       struct ddekit_irq_s * irq_s;
+       ddekit_irq_lock();
+       if (!irqs) {
+               return 0;
+       }
+       
+       irq_s = irqs;
+
+       while(irq_s) {
+               if(irq_s->irq==irq)
+                       break;
+               irq_s = irq_s->next;
+       }
+       
+       ddekit_irq_unlock();
+       return irq_s;
+}
+
+/******************************************************************************
+ *       ddekit_irq_remove                                                    *
+ *****************************************************************************/
+PRIVATE void ddekit_irq_remove(struct ddekit_irq_s *irq_s)
+{ 
+       struct ddekit_irq_s *i;
+
+       ddekit_irq_lock();
+
+       if(!irqs) {
+               ddekit_irq_unlock();
+               return; 
+       }
+       
+       if(irqs==irq_s) {
+               irqs=irq_s->next;
+               ddekit_irq_unlock();
+               return;
+       }
+
+       i = irqs;
+       
+       while(i) {
+               if (i->next == irq_s)  { 
+                       i->next = irq_s->next;
+                       ddekit_irq_unlock();
+                       return;
+               }
+               i = i->next; 
+       }       
+
+       ddekit_irq_unlock();
+}
+
+/******************************************************************************
+ *       ddekit_irq_thread                                                    *
+ *****************************************************************************/
+PRIVATE void ddekit_irq_thread(void *data) 
+{
+       /* For each IRQ line an own thread is started */
+       
+       struct ddekit_irq_s *irq_s = (struct ddekit_irq_s *) data;
+       
+       /* call IRQ thread init function */
+       irq_s->thread_init(irq_s->priv);
+
+       while(1) {
+               
+               /* Wait for IRQs */
+               DDEBUG_MSG_VERBOSE("wating for IRQ %d to occur", irq_s->irq);   
+               ddekit_sem_down(irq_s->sem);
+               DDEBUG_MSG_VERBOSE("executing handler for IRQ %d", irq_s->irq); 
+               irq_s->handler(irq_s->priv);
+               
+       }
+}
+
+
+/******************************************************************************
+ *   DDEKIT public API (include/dde/ddekit)                                   *
+ *****************************************************************************/
+
+/******************************************************************************
+ *       ddekit_interrupt_attach                                              *
+ *****************************************************************************/
+ddekit_thread_t *ddekit_interrupt_attach(int irq, 
+                                         int shared,
+                                         void(*thread_init)(void *),
+                                         void(*handler)(void *),
+                                                                                void *priv)
+{
+       struct ddekit_irq_s *irq_s;
+       char name[32];
+       irq_s = (struct ddekit_irq_s *) 
+                       ddekit_simple_malloc(sizeof(struct ddekit_irq_s));
+
+       irq_s->sem         = ddekit_sem_init(0);
+       irq_s->irq         = irq;
+       irq_s->irq_hook    = irq;
+       irq_s->shared      = shared;
+       irq_s->thread_init = thread_init;
+       irq_s->handler     = handler;
+       irq_s->priv        = priv;
+       irq_s->next        = 0;
+       irq_s->enabled     = 1;
+
+       /* create interrupt thread */
+       snprintf(name, 32, "ddekit_irq_%d",irq);
+       irq_s->th = ddekit_thread_create(ddekit_irq_thread, irq_s, name); 
+
+       /* attach to IRQ */
+       sys_irqsetpolicy(irq,
+                        0, /* not automatically re-enable interupts */
+                        &irq_s->irq_hook);
+
+       /* add to IRQ list */
+       ddekit_irq_lock();
+       irq_s->next = irqs;
+       irqs=irq_s;
+       ddekit_irq_unlock();
+
+       DDEBUG_MSG_INFO("Attached to irq %d (hook: %d)", irq, irq_s->irq_hook);
+
+       return irq_s->th;       
+}
+
+/******************************************************************************
+ *       ddekit_interrupt_detach                                              *
+ *****************************************************************************/
+void ddekit_interrupt_detach(int irq)
+{
+       struct ddekit_irq_s *irq_s;
+
+       irq_s = find_by_irq(irq);
+       
+       sys_irqrmpolicy(&irq_s->irq_hook);
+       
+       ddekit_thread_terminate(irq_s->th);
+       ddekit_irq_remove(irq_s);
+       ddekit_simple_free(irq_s);
+       DDEBUG_MSG_VERBOSE(" IRQ %d", irq);
+}
+
+/******************************************************************************
+ *       ddekit_interrupt_disable                                             *
+ *****************************************************************************/
+void ddekit_interrupt_disable(int irq)
+{
+       struct ddekit_irq_s *irq_s;
+       irq_s = find_by_irq(irq);
+       irq_s->enabled=0;
+       //sys_irqdisable(&irq_s->irq_hook);
+       DDEBUG_MSG_VERBOSE(" IRQ %d", irq);
+}
+
+/******************************************************************************
+ *       ddekit_interrupt_enable                                              *
+ *****************************************************************************/
+void ddekit_interrupt_enable(int irq)
+{
+       struct ddekit_irq_s *irq_s;
+       irq_s = find_by_irq(irq);
+       irq_s->enabled=1;
+       //sys_irqenable(&irq_s->irq_hook);
+       DDEBUG_MSG_VERBOSE(" IRQ %d", irq);
+}
+
+/******************************************************************************
+ *       ddekit_init_irqs                                                     *
+ *****************************************************************************/
+void ddekit_init_irqs()
+{  
+       ddekit_lock_init(&lock);
+} 
+
+/******************************************************************************
+ *   DDEKIT internals (src/irq.h)                                             *
+ *****************************************************************************/
+
+/******************************************************************************
+ *       _ddekit_interrupt_trigger                                            *
+ *****************************************************************************/
+PUBLIC void _ddekit_interrupt_trigger(int irq)
+{  
+       struct ddekit_irq_s *irq_s;
+
+       irq_s = find_by_irq(irq);
+       
+       if (irq_s)      {       
+               DDEBUG_MSG_VERBOSE("Triggering IRQ %d", irq);
+               ddekit_sem_up(irq_s->sem);
+               sys_irqenable(&irq_s->irq_hook);
+       } else {
+               DDEBUG_MSG_WARN("no handler for IRQ %d", irq);
+       }
+}
+
+
diff --git a/lib/libddekit/src/irq.h b/lib/libddekit/src/irq.h
new file mode 100644 (file)
index 0000000..8c9ec1e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef DDEKIT_IRQ_MINIX_H
+#define DDEKIT_IRQ_MINIX_H 1 
+_PROTOTYPE( void ddekit_init_irqs,          (void)         );
+_PROTOTYPE( void _ddekit_interrupt_trigger, (int irq_hook) );
+#endif 
diff --git a/lib/libddekit/src/lock.c b/lib/libddekit/src/lock.c
new file mode 100644 (file)
index 0000000..fecb649
--- /dev/null
@@ -0,0 +1,118 @@
+#include "common.h"
+
+#include <ddekit/assert.h>
+#include <ddekit/memory.h>
+#include <ddekit/semaphore.h>
+
+#ifdef DDEBUG_LEVEL_LOCK
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_LOCK
+#endif
+
+#include "debug.h"
+#include "thread.h"
+
+struct ddekit_lock {
+       ddekit_thread_t *owner;
+       ddekit_thread_t *wait_queue;
+};
+
+
+/******************************************************************************
+ *       ddekit_lock_init_locked                                              *
+ *****************************************************************************/
+PUBLIC void ddekit_lock_init_locked(ddekit_lock_t *mtx) 
+{  
+       (*mtx) = (struct ddekit_lock *)
+               ddekit_simple_malloc(sizeof(struct ddekit_lock));  
+
+       (*mtx)->wait_queue = NULL;
+       (*mtx)->owner      = ddekit_thread_myself(); 
+}
+
+/******************************************************************************
+ *       ddekit_lock_init_unlocked                                            *
+ *****************************************************************************/
+PUBLIC void ddekit_lock_init_unlocked(ddekit_lock_t *mtx) 
+{ 
+       (*mtx) = (struct ddekit_lock *) 
+               ddekit_simple_malloc(sizeof(struct ddekit_lock));  
+       (*mtx)->owner      = NULL; 
+       (*mtx)->wait_queue = NULL;
+}
+
+/******************************************************************************
+ *       ddekit_lock_deinit                                                   *
+ *****************************************************************************/
+PUBLIC void ddekit_lock_deinit  (ddekit_lock_t *mtx)
+{ 
+       ddekit_simple_free(*mtx);
+}
+
+/******************************************************************************
+ *       ddekit_lock_lock                                                     *
+ *****************************************************************************/
+PUBLIC void ddekit_lock_lock (ddekit_lock_t *mtx) 
+{
+       if ((*mtx)->owner == NULL) {
+               (*mtx)->owner = ddekit_thread_myself();  
+       } else {
+
+               if ((*mtx)->wait_queue == NULL) {
+                       (*mtx)->wait_queue = ddekit_thread_myself();
+               } else {        
+                       ddekit_thread_t *pos = (*mtx)->wait_queue;
+                       while(pos->next != NULL) {
+                               pos = pos->next;
+                       }
+                       pos->next = ddekit_thread_myself();
+               }
+
+               _ddekit_thread_schedule();
+
+               if ((*mtx)->owner != NULL) {
+                       _ddekit_print_backtrace((*mtx)->owner);
+                       _ddekit_print_backtrace(ddekit_thread_myself());
+                       ddekit_panic("owner!=NULL: %s (I am %s)\n",
+                           (*mtx)->owner->name, ddekit_thread_myself()->name);
+               }
+
+               (*mtx)->owner =  ddekit_thread_myself();
+       }
+}
+/******************************************************************************
+ *       ddekit_lock_try_lock                                                 *
+ *****************************************************************************/
+PUBLIC int ddekit_lock_try_lock(ddekit_lock_t *mtx) 
+{
+       if ((*mtx)->owner == NULL) {
+               (*mtx)->owner =  ddekit_thread_myself();
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+/******************************************************************************
+ *       ddekit_lock_unlock                                                   *
+ *****************************************************************************/
+PUBLIC void ddekit_lock_unlock  (ddekit_lock_t *mtx) {
+       ddekit_assert((*mtx)->owner != NULL);
+       (*mtx)->owner = NULL;
+       if((*mtx)->wait_queue) {
+               ddekit_thread_t *waiter = (*mtx)->wait_queue;
+               (*mtx)->wait_queue = waiter->next;
+               waiter->next= NULL;
+               _ddekit_thread_enqueue(waiter);
+               ddekit_yield();
+       }
+}  
+
+/******************************************************************************
+ *       ddekit_lock_owner                                                    *
+ *****************************************************************************/
+PUBLIC int ddekit_lock_owner(ddekit_lock_t *mtx) { 
+       return ddekit_thread_get_id((*mtx)->owner);
+}
+
diff --git a/lib/libddekit/src/mem.c b/lib/libddekit/src/mem.c
new file mode 100644 (file)
index 0000000..423b56a
--- /dev/null
@@ -0,0 +1,460 @@
+#include "common.h"
+
+#include <ddekit/lock.h>
+#include <ddekit/memory.h> 
+#include <ddekit/panic.h>
+#include <ddekit/pgtab.h> 
+#include <ddekit/inline.h> 
+#include <ddekit/types.h> 
+
+#ifdef DDEKIT_DEBUG_MEM 
+#undef DDEBUG
+#define DDEBUG DDEKIT_DEBUG_MEM
+#endif
+#include "debug.h"
+#include "util.h"
+
+#define SLAB_SIZE (4096*4)
+
+struct ddekit_slab; 
+
+struct ddekit_slab_slab {
+       struct ddekit_slab * cache; 
+       unsigned long free; 
+       void *objects;
+       void *mem;
+       struct ddekit_slab_slab *next;
+       struct ddekit_slab_slab *prev;
+};
+
+struct ddekit_slab { 
+       ddekit_lock_t lock;
+       void * data;    /* user pointer */
+       int contiguous; /* is it coniguous mem*/
+       unsigned size;  /* the size of he objects */
+       unsigned number; /* the number of objects stored per slab */
+       struct ddekit_slab_slab full;  
+       struct ddekit_slab_slab partial;
+       struct ddekit_slab_slab empty;
+};
+
+FORWARD _PROTOTYPE( void ddekit_slab_lock, (struct ddekit_slab * sc) );
+FORWARD _PROTOTYPE( void ddekit_slab_unlock, (struct ddekit_slab * sc) );
+FORWARD _PROTOTYPE( struct ddekit_slab_slab * ddekit_slab_find_slab,
+                    (struct ddekit_slab * sc, void * obj));
+FORWARD _PROTOTYPE(void ddekit_slab_slab_insert,
+                   (struct ddekit_slab_slab *list,
+                                   struct ddekit_slab_slab *s));
+FORWARD _PROTOTYPE( void ddekit_slab_slab_remove, (struct ddekit_slab_slab *s));
+FORWARD _PROTOTYPE( void ddekit_slab_grow, (struct ddekit_slab * sc));
+FORWARD _PROTOTYPE( void *ddekit_slab_getobj, (struct ddekit_slab_slab *s));
+FORWARD _PROTOTYPE( void ddekit_slab_free_slab,
+                    (struct ddekit_slab_slab * sl, int cont));
+
+/******************************************************************************
+ *       ddekit_simple_malloc                                                 *
+ *****************************************************************************/
+PUBLIC void *ddekit_simple_malloc(unsigned size)
+{  
+       /* Simple memory allocation... malloc and free should be ok... */
+       void * r = malloc(size);
+       if (!r) {
+               ddekit_panic("out of mem?");
+       }
+       DDEBUG_MSG_VERBOSE("%p", r);
+       return r;
+}
+
+/******************************************************************************
+ *       ddekit_simple_free                                                   *
+ *****************************************************************************/
+PUBLIC void ddekit_simple_free(void *p)
+{ 
+       DDEBUG_MSG_VERBOSE("%p", p);
+       free(p);
+}
+
+/******************************************************************************
+ *       ddekit_large_malloc                                                  *
+ *****************************************************************************/
+PUBLIC void *ddekit_large_malloc(int size)
+{  
+       ddekit_addr_t phys;     
+       /* allocate a piece of coniguous memory */
+       void * r = alloc_contig(size, AC_ALIGN4K, &phys);
+       if (!r) {
+               ddekit_panic("out of mem?");
+       }
+       ddekit_pgtab_set_region_with_size(r, phys, size, PTE_TYPE_LARGE);
+       DDEBUG_MSG_VERBOSE("%p, phys: %p, size: %p.",r, phys, size);
+       DDEBUG_MSG_VERBOSE("%p", r);
+       return r; 
+}
+
+/******************************************************************************
+ *       ddekit_large_free                                                    *
+ *****************************************************************************/
+PUBLIC void ddekit_large_free(void *p)
+{  
+       unsigned len;
+       DDEBUG_MSG_VERBOSE("get size of region %x", p); 
+       len= ddekit_pgtab_get_size(p);
+       DDEBUG_MSG_VERBOSE("freeing %x, len %d...", p , len);
+       ddekit_pgtab_clear_region(p, 0); /* type is not used here... */
+       DDEBUG_MSG_VERBOSE("cleared region", p , len);
+       free_contig(p, len);
+       DDEBUG_MSG_VERBOSE("freed mem", p , len);
+       DDEBUG_MSG_VERBOSE("%p", p);
+}
+
+/******************************************************************************
+ *       ddekit_contig_malloc                                                 *
+ *****************************************************************************/
+PUBLIC void *ddekit_contig_malloc(unsigned long size, unsigned long low, 
+                                  unsigned long high, unsigned long aligment,  
+                                  unsigned long boundary)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/******************************************************************************
+ *       ddekit_slab_lock                                                     *
+ *****************************************************************************/
+PRIVATE DDEKIT_INLINE void ddekit_slab_lock(struct ddekit_slab * sc) {
+       ddekit_lock_lock(&sc->lock);
+}
+
+/******************************************************************************
+ *       ddekit_slab_unlock                                                   *
+ *****************************************************************************/
+PRIVATE DDEKIT_INLINE void ddekit_slab_unlock(struct ddekit_slab * sc) {
+       ddekit_lock_unlock(&sc->lock);
+}
+
+/******************************************************************************
+ *       ddekit_slab_find_slab                                                *
+ *****************************************************************************/
+PRIVATE struct ddekit_slab_slab * 
+ddekit_slab_find_slab(struct ddekit_slab * sc, void * obj) 
+{  
+
+       struct ddekit_slab_slab *s;
+
+       for( s = sc->full.next; s!=&sc->full; s = s->next )
+       {
+               if (s->mem <= obj && obj < s->mem+(SLAB_SIZE))
+               {
+                               return s;
+               }
+       } 
+
+       for( s = sc->partial.next; s!=&sc->partial; s = s->next )
+       {
+               if (s->mem <= obj && obj < s->mem+(SLAB_SIZE))
+               {
+                               return s;
+               }
+       }
+
+       return 0; 
+}
+
+/******************************************************************************
+ *       ddekit_slab_slab_insert                                              *
+ *****************************************************************************/
+static void  ddekit_slab_slab_insert(struct ddekit_slab_slab *list,
+                                      struct ddekit_slab_slab *s) 
+{  
+       s->prev          = list; 
+       s->next          = list->next; 
+       list->next->prev = s;
+       list->next       = s;
+} 
+
+/******************************************************************************
+ *       ddekit_slab_slab_remove                                              *
+ *****************************************************************************/
+PRIVATE void ddekit_slab_slab_remove(struct ddekit_slab_slab *s) 
+{  
+       s->next->prev     = s->prev;
+       s->prev->next     = s->next; 
+       s->next = s->prev = 0;
+}
+
+
+/******************************************************************************
+ *       ddekit_slab_grow                                                     *
+ *****************************************************************************/
+PRIVATE void ddekit_slab_grow(struct ddekit_slab *sc) 
+{ 
+       /*
+        * NOTE:
+        * As it doesn't seem to make problems ddekit_slabs are disregarding 
+        * alignment.  However this should be revisited, maybe this leads to
+        * performance degregation somewhere.
+        * Further the ddekit_slab doesn't have to be real slab, as the entries are
+        * initialized in the personalized DDEs. (slab is simple the wrong name.)
+        */
+       int i; 
+       char *p;
+       void **p1;
+       struct ddekit_slab_slab *s;
+       
+       /* allocate slab control structure */
+       
+       s = (struct ddekit_slab_slab *) 
+           ddekit_simple_malloc(sizeof(struct ddekit_slab_slab)); 
+       
+       s->cache = sc;
+
+       if(sc->contiguous)      
+               s->mem = ddekit_large_malloc(SLAB_SIZE);
+       else 
+               s->mem = ddekit_simple_malloc(SLAB_SIZE);
+
+       /* setup the object list */
+
+       s->free = sc->number; 
+
+       /* put obj into list */
+       p1 = s->mem; 
+       *p1 = s->mem; 
+       s->objects =  p1;
+
+       DDEBUG_MSG_VERBOSE("obj size: %d, memory at: %p , first obj: %p, %p ", 
+                           sc->size, s->mem, s->objects);      
+       
+       for (i = 0; i < s->free; i++)
+       {
+               p  = *p1;
+               p1 = (void **) (p + sc->size);
+               
+               if ( i != s->free-1 ) 
+               {
+                       *p1 = p1+1;
+                       DDEBUG_MSG_VERBOSE("%p, %p -> %p", p, p1, *p1);
+               }
+               else
+               { 
+                       *p1 = 0;        
+                       DDEBUG_MSG_VERBOSE("%p, %p -> %p", p, p1, *p1);
+               }
+       } 
+
+       /* add new slab to free list */
+       ddekit_slab_slab_insert(&sc->empty, s);
+} 
+
+
+/******************************************************************************
+ *       ddekit_slab_getobj                                                   *
+ *****************************************************************************/
+PRIVATE void *ddekit_slab_getobj(struct ddekit_slab_slab *s)
+{ 
+       struct ddekit_slab *sc; 
+       void *ret = 0; 
+
+       sc = s->cache; 
+       ret  = s->objects;
+       
+       /* get pointer to next object */
+
+       s->objects = *(void **)((char *) ret + sc->size); 
+       s->free--;
+
+       DDEBUG_MSG_VERBOSE("old: %p new: %p", ret, s->objects);
+
+       /* if no more objects move to full */
+
+       if (!s->free)
+       {
+               ddekit_slab_slab_remove(s);
+               ddekit_slab_slab_insert(&sc->full,s);
+       } 
+       
+       if (s->free == sc->number-1)
+       { 
+               ddekit_slab_slab_remove(s); 
+               ddekit_slab_slab_insert(&sc->partial,s); 
+       }
+
+       return ret;
+}
+
+/******************************************************************************
+ *       ddekit_slab_alloc                                                    *
+ *****************************************************************************/
+PUBLIC void *ddekit_slab_alloc(struct ddekit_slab * sc)
+{ 
+       struct ddekit_slab_slab *s=0; 
+
+       ddekit_slab_lock(sc);
+
+       DDEBUG_MSG_VERBOSE("from slab %p", sc);
+
+       /* first try from partial */  
+       if (sc->partial.next != &sc->partial) { 
+               DDEBUG_MSG_VERBOSE("from slab %p partial (next=%p)", sc,sc->partial.next);
+               s = sc->partial.next; 
+       }
+
+       /* must grow? */
+       if (!s && (sc->empty.next == &sc->empty )){
+               DDEBUG_MSG_VERBOSE("slab %p has to grow", sc);
+               ddekit_slab_grow(sc);
+       }
+
+       /* take from free? */
+       if (!s) { 
+               DDEBUG_MSG_VERBOSE("from slab %p empty", sc);
+               s = sc->empty.next;
+       }
+       
+       ddekit_slab_unlock(sc);
+
+       return ddekit_slab_getobj(s);
+}
+
+/******************************************************************************
+ *       ddekit_slab_free                                                     *
+ *****************************************************************************/
+PUBLIC void ddekit_slab_free(struct ddekit_slab *sc, void* obj)
+{   
+       void **p;       
+
+       struct ddekit_slab_slab *s = 0; 
+
+       ddekit_slab_lock(sc);   
+       /* first find slab the obj came from */ 
+
+       s = ddekit_slab_find_slab(sc, obj);
+       
+       p = (void **)((char *) obj + sc->size);
+       
+       *p= s->objects;
+       s->objects=obj;
+
+       DDEBUG_MSG_VERBOSE("old: %p, new: %p",*p,s->objects );
+
+       s->free++; 
+        
+       if (s->free == sc->number) {
+               ddekit_slab_slab_remove(s); 
+               ddekit_slab_slab_insert(&sc->empty, s);
+       }
+       
+       if (s->free == 1) { 
+               ddekit_slab_slab_remove(s); 
+               ddekit_slab_slab_insert(&sc->partial, s); 
+       }
+
+       ddekit_slab_unlock(sc);
+}
+
+/******************************************************************************
+ *       ddekit_slab_set_data                                                 *
+ *****************************************************************************/
+PUBLIC void ddekit_slab_set_data(struct ddekit_slab * sc, void *data)
+{   
+       ddekit_slab_lock(sc);
+       sc->data = data;
+       ddekit_slab_unlock(sc);
+}
+
+/******************************************************************************
+ *       ddekit_slab_get_data                                                 *
+ *****************************************************************************/
+PUBLIC void *ddekit_slab_get_data (struct ddekit_slab *sc)
+{  
+       void *ret;
+       ddekit_slab_lock(sc);
+       ret=sc->data;
+       ddekit_slab_unlock(sc);
+       return ret;
+}
+
+
+/******************************************************************************
+ *       ddekit_slab_init                                                     *
+ *****************************************************************************/
+PUBLIC struct ddekit_slab * ddekit_slab_init(unsigned size, int contiguous)
+{
+
+       struct ddekit_slab * sc = 0;
+
+       sc = (struct ddekit_slab *)
+           ddekit_simple_malloc(sizeof(struct ddekit_slab));
+
+       sc->data       = 0;
+       sc->contiguous = contiguous;
+       sc->size       = size;
+       sc->number     = SLAB_SIZE/(size+sizeof(void*));
+       
+       if (sc->number == 0) {
+               ddekit_panic("objects too big!");
+       }
+
+       sc->empty.next   = sc->empty.prev   = &sc->empty;
+       sc->partial.next = sc->partial.prev = &sc->partial;  
+       sc->full.next    = sc->full.prev    = &sc->full; 
+
+       ddekit_lock_init(&sc->lock);
+
+       DDEBUG_MSG_VERBOSE("initialzed slab cache %p: size %x, number %d ",
+           sc, sc->size, sc->number);
+
+       DDEBUG_MSG_VERBOSE("partial %p next %p", &sc->partial, sc->partial.next); 
+       return sc ;
+}
+
+
+/******************************************************************************
+ *       ddekit_slab_free_slab                                                *
+ *****************************************************************************/
+PRIVATE void ddekit_slab_free_slab(struct ddekit_slab_slab * sl, int cont) 
+{
+
+       struct ddekit_slab_slab *s,*t;
+       
+       if (!sl) {
+               ddekit_panic("no slab to free!");
+       }
+
+       for ( s = sl->next; s != sl; ) 
+       {
+               DDEBUG_MSG_VERBOSE("cont: %d, %p, s->mem", cont, s->mem);
+               if(cont) 
+               {
+                       ddekit_large_free(s->mem);
+               } 
+               else 
+               {
+                       ddekit_simple_free(s->mem);
+               }
+               t = s;
+               s = s->next;
+               ddekit_simple_free(t);
+       }
+
+}
+
+/******************************************************************************
+ *       ddekit_slab_destroy                                                  *
+ *****************************************************************************/
+PUBLIC void ddekit_slab_destroy(struct ddekit_slab *sc) 
+{
+       DDEBUG_MSG_VERBOSE("%p full", sc);
+       ddekit_slab_free_slab(&sc->full,sc->contiguous);
+       
+       DDEBUG_MSG_VERBOSE("%p empty", sc);
+       ddekit_slab_free_slab(&sc->empty,sc->contiguous);
+       
+       DDEBUG_MSG_VERBOSE("%p partial", sc);
+       ddekit_slab_free_slab(&sc->partial,sc->contiguous);
+       
+       ddekit_lock_deinit(&sc->lock);
+
+       ddekit_simple_free(sc);
+}
diff --git a/lib/libddekit/src/msg_queue.c b/lib/libddekit/src/msg_queue.c
new file mode 100644 (file)
index 0000000..b2eaf20
--- /dev/null
@@ -0,0 +1,155 @@
+#include "common.h"
+
+#include <ddekit/memory.h>
+#include <ddekit/minix/msg_queue.h>
+#include <ddekit/panic.h>
+#include <ddekit/semaphore.h>
+
+#define MESSAGE_QUEUE_SIZE 16
+
+#ifdef DDEBUG_LEVEL_MSG_Q
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_MSG_Q
+#endif
+
+#include "debug.h"
+
+struct ddekit_minix_msg_q {
+       
+       unsigned from, to;
+
+       message messages[MESSAGE_QUEUE_SIZE];
+       ddekit_sem_t *msg_w_sem, *msg_r_sem;
+       int msg_r_pos, msg_w_pos;
+       
+       struct ddekit_minix_msg_q *next;
+};
+
+PRIVATE struct ddekit_minix_msg_q * _list = NULL;
+FORWARD _PROTOTYPE(void _ddekit_minix_queue_msg,
+                   (struct ddekit_minix_msg_q *mq, message *m));
+
+/*****************************************************************************
+ *      ddekit_minix_create_msg_q                                            *
+ ****************************************************************************/
+PUBLIC struct ddekit_minix_msg_q *
+ddekit_minix_create_msg_q(unsigned from, unsigned to)
+{
+       struct ddekit_minix_msg_q *mq =  (struct ddekit_minix_msg_q *)
+           ddekit_simple_malloc(sizeof(struct ddekit_minix_msg_q));
+       
+       mq->from = from;
+       mq->to   = to;
+       mq->msg_w_pos = 0;
+       mq->msg_r_pos = 0;
+
+       mq->msg_r_sem = ddekit_sem_init(0);
+       mq->msg_w_sem = ddekit_sem_init(MESSAGE_QUEUE_SIZE);
+
+       /* TODO: check for overlapping message ranges */
+       mq->next = _list;
+       _list     = mq;
+       
+       DDEBUG_MSG_VERBOSE("created msg_q from %x to %x\n", from , to);
+
+       return mq;      
+}
+
+/*****************************************************************************
+ *      ddekit_minix_deregister_msg_q                                        *
+ ****************************************************************************/
+PUBLIC void ddekit_minix_deregister_msg_q(struct ddekit_minix_msg_q *mq)
+{
+       struct ddekit_minix_msg_q *prev =_list, *it;
+
+       for (it = _list->next; it != NULL ; it = it->next) {
+               if (it == mq) {
+                       prev->next = it->next;
+                       break;
+               }
+               prev=it;
+       }
+
+       ddekit_sem_deinit(mq->msg_r_sem);
+       ddekit_sem_deinit(mq->msg_w_sem);
+
+       ddekit_simple_free(mq);
+
+       DDEBUG_MSG_VERBOSE("destroyed msg_q from \n");
+}
+
+/*****************************************************************************
+ *     _ddekit_minix_queue_msg                                               *
+ ****************************************************************************/
+PRIVATE void 
+_ddekit_minix_queue_msg(struct ddekit_minix_msg_q *mq, message *m)
+{
+       int full;
+       full = ddekit_sem_down_try(mq->msg_w_sem);
+
+       if (full) {
+               /* Our message queue is full... inform the sender. */
+               int result;
+               DDEBUG_MSG_WARN("Receive queue is full. Ommiting ingoing msg.\n");
+
+               m->m_type = TASK_REPLY;
+               m->REP_STATUS = EAGAIN;
+               result = asynsend(m->m_source, m);
+               
+               if (result != 0) {
+                       ddekit_panic("unable to send reply to %d: %d\n",
+                                       m->m_source, result);
+               }
+
+       } else {
+               /* queue the message */
+               memcpy(&mq->messages[mq->msg_w_pos], m, sizeof(message));
+
+               if (++mq->msg_w_pos == MESSAGE_QUEUE_SIZE) {
+                       mq->msg_w_pos = 0;
+               }
+               DDEBUG_MSG_VERBOSE("ddekit_minix_queue_msg: queueing msg %x\n",
+                                   m->m_type);
+               ddekit_sem_up(mq->msg_r_sem);
+       }
+}
+
+/*****************************************************************************
+ *       ddekit_minix_queue_msg                                              *
+ ****************************************************************************/
+void ddekit_minix_queue_msg(message *m) 
+{
+       struct ddekit_minix_msg_q *it, *mq = NULL;
+       
+       for (it = _list; it !=NULL ; it = it->next) {
+               if (m->m_type >= it->from && m->m_type <= it->to) {
+                       mq = it;
+                       break;
+               }
+       }
+       if (mq == NULL) {
+               DDEBUG_MSG_VERBOSE("no q for msgtype %x\n", m->m_type);
+               return;
+       }
+       _ddekit_minix_queue_msg(mq,m);
+}
+
+/*****************************************************************************
+ *        ddekit_minix_rcv                                                   *
+ ****************************************************************************/
+PUBLIC void ddekit_minix_rcv(struct ddekit_minix_msg_q *mq, message *m) 
+{
+       DDEBUG_MSG_VERBOSE("waiting for message");
+       
+       ddekit_sem_down(mq->msg_r_sem);
+
+       memcpy(m, &mq->messages[mq->msg_r_pos], sizeof(message));
+
+       if (++mq->msg_r_pos == MESSAGE_QUEUE_SIZE) {
+               mq->msg_r_pos = 0;
+       }
+       
+       DDEBUG_MSG_VERBOSE("unqueing message");
+       
+       ddekit_sem_up(mq->msg_w_sem);
+}
diff --git a/lib/libddekit/src/panic.c b/lib/libddekit/src/panic.c
new file mode 100644 (file)
index 0000000..bf20415
--- /dev/null
@@ -0,0 +1,34 @@
+#include "common.h"
+#include <ddekit/panic.h>
+#include <ddekit/printf.h>
+
+/****************************************************************************/
+/*      ddekit_panic                                                        */
+/****************************************************************************/
+PUBLIC void ddekit_panic(char *fmt, ...)
+{ 
+       
+       int r;
+    va_list va;
+
+       printf("%c[31;1mPANIC: \033[0m\n",0x1b);
+    va_start(va,fmt);
+    r = vprintf(fmt, va);
+    va_end(va);
+       panic("","",0); 
+
+       while(1)
+               ;
+}
+
+/****************************************************************************/
+/*      ddekit_debug                                                        */
+/****************************************************************************/
+PUBLIC void ddekit_debug(char *fmt, ...)
+{
+    int r; 
+    va_list va;
+    va_start(va,fmt);
+    r = vprintf(fmt, va);
+    va_end(va); 
+}
diff --git a/lib/libddekit/src/pci.c b/lib/libddekit/src/pci.c
new file mode 100644 (file)
index 0000000..aaa01d0
--- /dev/null
@@ -0,0 +1,447 @@
+/**
+ * pci.c
+ * @author: Dirk Vogt
+ * @date: 2010-02-18
+ */
+
+#include "common.h"
+
+#include <ddekit/pci.h>
+#include <ddekit/panic.h>
+#include <minix/syslib.h>
+
+
+#ifdef DDEBUG_LEVEL_PCI
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_PCI
+#endif
+
+#include "util.h"
+#include "debug.h"
+
+#define PCI_MAX_DEVS 32
+
+#define PCI_TAKE_ALL (-1)
+
+struct ddekit_pci_dev {
+       int devind; /* thats how we identify the defice at the pci server */
+       ddekit_uint16_t vid; /* as we get them for                 */
+                            /*   free during iteration store them */
+       ddekit_uint16_t did;
+       int bus;
+       int slot; /* slot should equal index in dev array */
+       int func; /* don't support multiple functionalities yet -> 0 */
+};
+
+struct ddekit_pci_dev pci_devs[PCI_MAX_DEVS];
+
+FORWARD _PROTOTYPE( struct ddekit_pci_dev * ddekit_get_dev_helper,
+                    (int bus, int slot, int func));
+
+/****************************************************************************/
+/*      ddekit_pci_init_only_one                                            */
+/****************************************************************************/
+PUBLIC void ddekit_pci_init_only_one(int skip) 
+{      
+       /*
+        * If skip is not PCI_TAKE_ALL this function will skip skip PCI DEVICES
+        * and than only take on PCI device.
+        */
+
+       int res, count, more, take_all = 0; 
+       
+       if (skip == -1) {
+               take_all = 1;
+       }
+
+       DDEBUG_MSG_INFO("Initializing PCI subsystem...");
+
+       pci_init1("symbol clash");
+
+       /*
+        * Iterate the PCI-bus
+        */
+       
+       more = 1;
+       
+       for (count = 0 ; count < PCI_MAX_DEVS ; count++) {
+               
+               struct ddekit_pci_dev *d = &pci_devs[count];
+               
+               if (more) {
+                       if ( count==0 ) { 
+                               res = pci_first_dev(&d->devind, &d->vid, &d->did);
+                       } else { 
+                               d->devind = pci_devs[count-1].devind; 
+                               res = pci_next_dev(&d->devind, &d->vid, &d->did); 
+                       }
+                       
+                       if (res && d->devind!=0 && (take_all || skip == 0)) {  
+                               
+                               DDEBUG_MSG_VERBOSE("Found pci device: "
+                                                  "(ind: %x, vid: %x, did: %x) "
+                                                                  "mapped to slot %x",
+                                                                  d->devind, d->vid, d->did, count);
+                               d->slot = count;
+                               d->bus  = 0;
+                               d->func = 0;
+                               res = pci_reserve_ok(d->devind);
+                               if (res != 0) {
+                                       ddekit_panic("ddekit_pci_init_only_one: "
+                                                    "pci_reserve_ok failed (%d)\n",res);
+                               }
+                       
+                       } else {   
+                               /* no more PCI devices */
+                               DDEBUG_MSG_VERBOSE("Found %d PCI devices.", count);
+                               d->devind = -1; 
+                               more = 0; 
+                       } /*if (res) */
+               } else { 
+                       d->devind = -1; 
+               }
+               if (!take_all) {
+                       skip--;
+               }
+       } 
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_device_id                                            */
+/****************************************************************************/
+PUBLIC void ddekit_pci_init(void) 
+{      
+       ddekit_pci_init_only_one(DDEKIT_PCI_ANY_ID);
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_device_id                                            */
+/****************************************************************************/
+int ddekit_pci_get_device(int nr, int *bus, int *slot, int *func) 
+{
+       if(nr >= 0  && nr < PCI_MAX_DEVS) {  
+               
+               *bus = 0; 
+               *slot = nr;
+               *func =0;
+
+               return 0;                                       
+       }
+
+       return -1;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_device_id                                            */
+/****************************************************************************/
+PRIVATE struct ddekit_pci_dev * 
+ddekit_get_dev_helper(int bus, int slot, int func)
+{  
+       /*
+        * Used internally to look up devices.
+        * Should make it easier to support multiple buses somewhen
+        */
+       struct ddekit_pci_dev * ret = 0;
+       if (slot >= 0  && slot < PCI_MAX_DEVS) {
+               ret = &pci_devs[slot];
+       }
+       if (ret->devind == -1) {
+               ret = 0;
+       }
+       return ret;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_read                                                     */
+/****************************************************************************/
+PUBLIC int ddekit_pci_read
+(int bus, int slot, int func, int pos, int len, ddekit_uint32_t *val)
+{
+       switch(len) { 
+               case 1: 
+                       return ddekit_pci_readb(bus, slot, func, pos,
+                           (ddekit_uint8_t*)  val);
+               case 2: 
+                       return ddekit_pci_readw(bus, slot, func, pos,
+                           (ddekit_uint16_t*) val); 
+               case 4: 
+                       return ddekit_pci_readl(bus, slot, func, pos, val);
+               default: return -1;
+       }       
+}
+
+/****************************************************************************/
+/*      ddekit_pci_write                                                    */
+/****************************************************************************/
+PUBLIC int ddekit_pci_write
+(int bus, int slot, int func, int pos, int len, ddekit_uint32_t val)
+{
+       switch(len) { 
+               case 1: 
+                       return ddekit_pci_writeb(bus, slot, func, pos,
+                           (ddekit_uint8_t)  val);
+               case 2: 
+                       return ddekit_pci_writew(bus, slot, func, pos,
+                           (ddekit_uint16_t) val); 
+               case 4: 
+                       return ddekit_pci_writel(bus, slot, func, pos, val);
+               default: return -1;
+       }       
+}
+
+/****************************************************************************/
+/*      ddekit_pci_readb                                                    */
+/****************************************************************************/
+PUBLIC int ddekit_pci_readb (int bus, int slot, int func, int pos, ddekit_uint8_t  *val) {
+       struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
+       if (func!=0) {
+               *val=0;
+               return 0;
+       }
+       if (dev) { 
+               *val = pci_attr_r8 (dev->devind, pos);
+               DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
+                   bus, slot, func, pos, *val);
+               return 0; 
+       }
+       return -1;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_readw                                                    */
+/****************************************************************************/
+PUBLIC int ddekit_pci_readw
+(int bus, int slot, int func, int pos, ddekit_uint16_t *val) { 
+       struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
+       if (func!=0) {
+               *val=0;
+               return 0;
+       }
+       if (dev) { 
+               *val = pci_attr_r16 (dev->devind, pos);
+               DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
+                   bus, slot, func, pos, *val);
+               return 0; 
+       }
+       return -1;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_readl                                                    */
+/****************************************************************************/
+PUBLIC int ddekit_pci_readl
+(int bus, int slot, int func, int pos, ddekit_uint32_t *val)  { 
+       struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
+       if (func!=0) {
+               *val=0;
+               return 0;
+       }
+       if (dev) { 
+               *val = pci_attr_r32 (dev->devind, pos);
+               DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
+                   bus, slot, func, pos, *val);
+               return 0; 
+       }
+       return -1;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_writeb                                                   */
+/****************************************************************************/
+PUBLIC int ddekit_pci_writeb
+(int bus, int slot, int func, int pos, ddekit_uint8_t val) { 
+       struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
+       if (dev) { 
+               pci_attr_w8 (dev->devind, pos, val); 
+               DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
+                   bus, slot, func, pos, val);
+               return 0; 
+       }
+       return -1;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_writel                                                   */
+/****************************************************************************/
+PUBLIC int ddekit_pci_writew
+(int bus, int slot, int func, int pos, ddekit_uint16_t val) { 
+       struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
+       if (dev) { 
+               pci_attr_w16 (dev->devind, pos, val);
+               DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",
+                   bus,slot,func,pos, val);
+               return 0; 
+       }
+       return -1;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_writel                                                   */
+/****************************************************************************/
+PUBLIC int ddekit_pci_writel
+(int bus, int slot, int func, int pos, ddekit_uint32_t val) { 
+       struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func);
+       if (dev) { 
+               pci_attr_w32 (dev->devind, pos, val);
+               DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",bus,slot,func,pos, val);
+               return 0; 
+       }
+       return -1;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_find_device                                              */
+/****************************************************************************/
+PUBLIC struct ddekit_pci_dev *ddekit_pci_find_device
+(int *bus, int *slot, int *func, struct ddekit_pci_dev *start)
+{ 
+       int i,search=0;
+
+       if(!start)
+               search = 1;
+
+       for(i=0; i < PCI_MAX_DEVS ; i++) 
+       {
+               /* start searching? */
+               if (search)
+                       search = (&pci_devs[i]==start);
+               else
+               {
+                       struct ddekit_pci_dev * dev = &pci_devs[i];
+                       if ((*slot==dev->slot || *slot == DDEKIT_PCI_ANY_ID)
+                               && (*func==dev->func || *func == DDEKIT_PCI_ANY_ID))
+                       {
+                               return dev;
+                       }
+               }
+       }       
+       return 0;
+}
+
+/*
+ * XXX: Those are neither used be DDEFBSD or DDELinux implement them 
+ *      when you need them  
+ */
+
+/****************************************************************************/
+/*      ddekit_pci_enable_device                                            */
+/****************************************************************************/
+PUBLIC int ddekit_pci_enable_device(struct ddekit_pci_dev *dev)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_disable_device                                           */
+/****************************************************************************/
+PUBLIC int ddekit_pci_disable_device(struct ddekit_pci_dev *dev)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_set_master                                               */
+/****************************************************************************/
+PUBLIC void ddekit_pci_set_master(struct ddekit_pci_dev *dev)
+{
+       WARN_UNIMPL;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_vendor                                               */
+/****************************************************************************/
+PUBLIC unsigned short ddekit_pci_get_vendor(struct ddekit_pci_dev *dev)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_device_id                                            */
+/****************************************************************************/
+PUBLIC unsigned short ddekit_pci_get_device_id(struct ddekit_pci_dev *dev)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_sub_vendor                                           */
+/****************************************************************************/
+PUBLIC unsigned short ddekit_pci_get_sub_vendor(struct ddekit_pci_dev *dev)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_sub_device                                           */
+/****************************************************************************/
+PUBLIC unsigned short ddekit_pci_get_sub_device(struct ddekit_pci_dev *dev) 
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_dev_class                                            */
+/****************************************************************************/
+PUBLIC unsigned ddekit_pci_get_dev_class(struct ddekit_pci_dev *dev) 
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_irq                                                  */
+/****************************************************************************/
+PUBLIC unsigned long 
+ddekit_pci_get_irq(struct ddekit_pci_dev *dev) 
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_name                                                 */
+/****************************************************************************/
+PUBLIC char *ddekit_pci_get_name(struct ddekit_pci_dev *dev)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_slot_name                                            */
+/****************************************************************************/
+PUBLIC char *ddekit_pci_get_slot_name(struct ddekit_pci_dev *dev)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_get_resource                                             */
+/****************************************************************************/
+PUBLIC ddekit_pci_res_t *
+ddekit_pci_get_resource(struct ddekit_pci_dev *dev, unsigned int idx)
+{ 
+       WARN_UNIMPL;
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pci_irq_enable                                               */
+/****************************************************************************/
+PUBLIC int ddekit_pci_irq_enable
+(int bus, int slot, int func, int pin, int *irq)
+{ 
+       /* call not needed */
+#if 0
+       WARN_UNIMPL;
+#endif
+       return 0;
+}
diff --git a/lib/libddekit/src/pgtab.c b/lib/libddekit/src/pgtab.c
new file mode 100644 (file)
index 0000000..f7c70fd
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * @author: Dirk Vogt
+ * @date 2010-02-10 
+ *
+ * This file implements a local pagetable, to prevent IPC on physical 
+ * address lookups. For now it's implement in a signle linked list.
+ *
+ * As soon as the DDE will use a premeptive thread mechanism access to 
+ * the page table has to be sznchronized.
+ */
+#include "common.h"
+
+#include <ddekit/pgtab.h>
+#include <ddekit/memory.h>
+#include <ddekit/lock.h>
+
+#ifdef DDEBUG_LEVEL_PGTAB
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_PGTAB
+#endif
+
+#include "util.h"
+#include "debug.h" 
+
+
+FORWARD _PROTOTYPE( void lock_pgtab, (void));
+FORWARD _PROTOTYPE( void unlock_pgtab, (void));
+FORWARD _PROTOTYPE( struct dde_pgtab_region * allocate_region, (void));
+FORWARD _PROTOTYPE( void free_region, (struct dde_pgtab_region *r));
+FORWARD _PROTOTYPE( void add_region, (struct dde_pgtab_region *r));
+FORWARD _PROTOTYPE( void rm_region, (struct dde_pgtab_region *r));
+FORWARD _PROTOTYPE( struct dde_pgtab_region * find_region_virt, (ddekit_addr_t va));
+FORWARD _PROTOTYPE( struct dde_pgtab_region * find_region_phys, (ddekit_addr_t pa));
+
+struct dde_pgtab_region {  
+       ddekit_addr_t vm_start; 
+       ddekit_addr_t phy_start;
+       unsigned size; 
+       unsigned type; /* do we really have to keep track of the type here? */ 
+       struct dde_pgtab_region *next;
+       struct dde_pgtab_region *prev;
+};
+
+PRIVATE struct dde_pgtab_region  head = {0,0,0,0,&head,&head}; 
+PRIVATE ddekit_lock_t lock;
+
+/*
+ * INTERNAL HELPERS
+ */
+
+/****************************************************************************/
+/*      lock_pgtab                                                          */
+/****************************************************************************/
+PRIVATE void lock_pgtab()
+{
+       ddekit_lock_lock(&lock);
+}
+
+
+/****************************************************************************/
+/*      unlock_pgtab                                                        */
+/****************************************************************************/
+PRIVATE void unlock_pgtab()
+{
+       ddekit_lock_unlock(&lock);
+}
+
+/****************************************************************************/
+/*      dde_pgtab_region                                                    */
+/****************************************************************************/
+PRIVATE struct dde_pgtab_region * allocate_region()
+{ 
+       struct dde_pgtab_region * res;
+
+       res = (struct dde_pgtab_region *) 
+                 ddekit_simple_malloc(sizeof(struct dde_pgtab_region));
+       if (!res)
+       { 
+               DDEBUG_MSG_ERR("Could not allocate region");
+       }
+       return res;
+}
+
+/****************************************************************************/
+/*      free_region                                                         */
+/****************************************************************************/
+PRIVATE void free_region(struct dde_pgtab_region *r)
+{  
+       ddekit_simple_free(r);
+}
+
+/****************************************************************************/
+/*      add_region                                                          */
+/****************************************************************************/
+PRIVATE void add_region (struct dde_pgtab_region *r)
+{ 
+       r->next    = head.next;
+       head.next  = r; 
+       r->prev    = &head;
+
+       if (r->next) {
+       
+               r->next->prev = r;
+
+       }
+} 
+
+/****************************************************************************/
+/*      rm_region                                                           */
+/****************************************************************************/
+PRIVATE void rm_region(struct dde_pgtab_region *r)
+{ 
+       if (r->next) {
+               r->next->prev = r->prev; 
+       }
+       if (r->prev) {
+               r->prev->next = r->next;
+       }
+       r->next = 0;
+       r->prev = 0;
+}
+
+
+/****************************************************************************/
+/*      find_region_virt                                                    */
+/****************************************************************************/
+PRIVATE struct dde_pgtab_region * find_region_virt(ddekit_addr_t va)
+{
+       struct dde_pgtab_region * r;
+       
+       for( r = head.next; r != &head ; r = r->next ) {   
+               
+               if ( (r->vm_start <= va)  && (va < (r->vm_start + r->size) ) )  { 
+                       break; 
+               }
+       }
+       
+       if (r == &head) {
+               DDEBUG_MSG_VERBOSE("No virt->phys mapping found for %x", va);
+               r = 0;
+       }
+       
+       return r;
+}
+
+/****************************************************************************/
+/*      find_region_phys                                                    */
+/****************************************************************************/
+PRIVATE struct dde_pgtab_region * find_region_phys(ddekit_addr_t pa)
+{  
+       struct dde_pgtab_region * r;
+       
+       for( r = head.next; r != &head ; r = r->next ) {                
+               if ( (r->phy_start <= pa)  && (pa < (r->phy_start + r->size) ) )
+                       break;   
+       }
+       
+       if (r == &head) {
+               r=0;
+               DDEBUG_MSG_VERBOSE("No phys->virt mapping found for %x", pa);  
+       }
+       
+       return r;
+} 
+
+/****************************************************************************/
+/*      ddekit_pgtab_do_fo_each_region                                      */
+/****************************************************************************/
+PUBLIC void ddekit_pgtab_do_fo_each_region(void (*func) (unsigned, unsigned)) {
+       struct dde_pgtab_region * r;
+       
+       for( r = head.next; r != &head ; r = r->next ) {   
+               ddekit_printf("%p",r->vm_start);
+               func(r->vm_start, r->size);
+       }
+}
+
+/*
+ * Interface implementation
+ */
+
+/****************************************************************************/
+/*      ddekit_pgtab_set_region                                             */
+/****************************************************************************/
+PUBLIC void ddekit_pgtab_set_region(void *virt, ddekit_addr_t phys, int pages, int type)
+{ 
+       ddekit_pgtab_set_region_with_size(virt, phys, (4096)*pages, type);
+}
+
+/****************************************************************************/
+/*      ddekit_pgtab_set_region_with_size                                   */
+/****************************************************************************/
+PUBLIC void ddekit_pgtab_set_region_with_size(void *virt, ddekit_addr_t phys, int size, int type)
+{
+       struct dde_pgtab_region * r;
+       
+       lock_pgtab();
+
+       r = allocate_region();  
+
+       r->vm_start  = (ddekit_addr_t) virt;
+       r->phy_start = phys;  
+       r->size      = size; 
+       r->type      = type;
+
+       add_region(r);
+
+       unlock_pgtab();
+}
+
+
+/****************************************************************************/
+/*      ddekit_pgtab_clear_region                                           */
+/****************************************************************************/
+PUBLIC void ddekit_pgtab_clear_region(void *virt, int type) {
+       
+       struct dde_pgtab_region *r;
+
+       lock_pgtab();
+
+       r = find_region_virt((ddekit_addr_t)virt);
+
+       if (r)
+       { 
+               rm_region(r);
+               free_region(r);
+       }
+
+       unlock_pgtab();
+       
+}
+
+
+/****************************************************************************/
+/*      ddekit_pgtab_get_physaddr                                           */
+/****************************************************************************/
+PUBLIC ddekit_addr_t ddekit_pgtab_get_physaddr(const void *virt)
+{
+       struct dde_pgtab_region *r;
+       ddekit_addr_t ret = 0;
+       lock_pgtab();
+    r = find_region_virt((ddekit_addr_t)virt);
+       unlock_pgtab();
+       if (r != NULL) { 
+
+               ret =  ((ddekit_addr_t) virt - r->vm_start) + r->phy_start;
+               DDEBUG_MSG_VERBOSE("pa: %p -> %p\n", virt, ret);
+       }
+
+       return ret; 
+}
+
+/****************************************************************************/
+/*      ddekit_pgtab_get_virtaddr                                           */
+/****************************************************************************/
+PUBLIC ddekit_addr_t ddekit_pgtab_get_virtaddr(const ddekit_addr_t physical)
+{
+       struct dde_pgtab_region *r;
+       lock_pgtab();
+    r = find_region_phys((ddekit_addr_t)physical);
+       unlock_pgtab();
+       if (r != NULL)
+       { 
+               return ((ddekit_addr_t) physical - r->phy_start) + r->vm_start;
+       }  
+
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pgtab_get_size                                               */
+/****************************************************************************/
+PUBLIC int ddekit_pgtab_get_type(const void *virt)
+{ 
+       /*
+        * needed for dde fbsd
+        */
+       struct dde_pgtab_region *r;
+
+       lock_pgtab();
+       r = find_region_virt((ddekit_addr_t)virt);
+       unlock_pgtab();
+       return r->type;
+}
+
+
+/****************************************************************************/
+/*      ddekit_pgtab_get_size                                               */
+/****************************************************************************/
+PUBLIC int ddekit_pgtab_get_size(const void *virt) 
+{ 
+       /*
+        * needed for fbsd
+        */
+       struct dde_pgtab_region *r;
+
+       lock_pgtab();
+       r = find_region_virt((ddekit_addr_t)virt);
+       unlock_pgtab();
+       if(r) 
+               return r->size;
+       else
+               return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_pgtab_init                                                   */
+/****************************************************************************/
+PUBLIC void ddekit_pgtab_init() {
+       /* called by ddekit_init() */ 
+       ddekit_lock_init(&lock);
+}
+
diff --git a/lib/libddekit/src/printf.c b/lib/libddekit/src/printf.c
new file mode 100644 (file)
index 0000000..deef59e
--- /dev/null
@@ -0,0 +1,33 @@
+#include "common.h"
+#include <ddekit/printf.h>
+
+/****************************************************************************/
+/*     ddekit_print                                                         */
+/****************************************************************************/
+PUBLIC int ddekit_print(const char* c)
+{
+       return ddekit_printf(c);
+}
+
+/****************************************************************************/
+/*     ddekit_printf                                                        */
+/****************************************************************************/
+PUBLIC int ddekit_printf(const char* fmt, ...)
+{
+       int r;
+       va_list va;
+
+       va_start(va,fmt);
+       r = vprintf(fmt, va);
+       va_end(va);
+       
+       return r;
+}
+
+/****************************************************************************/
+/*     ddekit_vprintf                                                       */
+/****************************************************************************/
+PUBLIC int ddekit_vprintf(const char *fmt, va_list va) 
+{
+       return vprintf(fmt, va);
+}
diff --git a/lib/libddekit/src/resource.c b/lib/libddekit/src/resource.c
new file mode 100644 (file)
index 0000000..ae7e123
--- /dev/null
@@ -0,0 +1,138 @@
+#include "common.h"
+#include <ddekit/panic.h>
+#include <ddekit/resources.h>
+#include <ddekit/pgtab.h>
+
+#include <minix/vm.h>
+
+#ifdef DDEBUG_LEVEL_RESOURCE
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_RESOURCE
+#endif
+
+#include "debug.h"
+#include "util.h"
+
+/****************************************************************************/
+/*      ddekit_release_dma                                                  */
+/****************************************************************************/
+PUBLIC int ddekit_request_dma(int nr) { 
+       WARN_UNIMPL;
+       /* do we stil use isa dma ? imho no.*/ 
+       return -1;
+}
+
+/****************************************************************************/
+/*      ddekit_request_dma                                                  */
+/****************************************************************************/
+PUBLIC int ddekit_release_dma(int nr) { 
+       WARN_UNIMPL;
+       /* do we stil use isa dma ? imho no.*/ 
+       return -1;
+}
+
+/* 
+ * In minix we don't need to explicitly request IO-ports, ...
+ */
+/****************************************************************************/
+/*      ddekit_release/request_io                                           */
+/****************************************************************************/
+PUBLIC int ddekit_request_io (ddekit_addr_t start, ddekit_addr_t count) {
+       return 0;       
+}
+PUBLIC int ddekit_release_io (ddekit_addr_t start, ddekit_addr_t count) { 
+       return 0;
+}
+
+/****************************************************************************/
+/*      ddekit_request_mem                                                  */
+/****************************************************************************/
+PUBLIC int ddekit_request_mem
+(ddekit_addr_t start, ddekit_addr_t size, ddekit_addr_t *vaddr) {
+       
+       *vaddr = (ddekit_addr_t) vm_map_phys(SELF, (void *)start, size);
+       
+       DDEBUG_MSG_VERBOSE("start: %x, size: %d, virt: %x", start, size, *vaddr);
+       
+       if( *vaddr == (ddekit_addr_t) NULL) {
+               ddekit_panic("unable to map IO memory from %p of size %d",
+                   start, size);
+       }
+       return (vaddr==NULL); 
+}
+
+/****************************************************************************/
+/*      ddekit_release_mem                                                  */
+/****************************************************************************/
+PUBLIC int ddekit_release_mem(ddekit_addr_t start, ddekit_addr_t size) 
+{
+       return  vm_unmap_phys(SELF,(void *) start, size );
+}
+
+/****************************************************************************/
+/*      ddekit_inb                                                          */
+/****************************************************************************/
+PUBLIC unsigned char ddekit_inb(ddekit_addr_t port) { 
+       unsigned long ret;
+       if (sys_inb(port, &ret)) {
+               ddekit_panic("sys_inb failed.");
+       }
+       DDEBUG_MSG_VERBOSE("read port %x: %x", port, ret);
+       return (char) ret;
+}
+
+/****************************************************************************/
+/*      ddekit_inw                                                          */
+/****************************************************************************/
+PUBLIC unsigned short ddekit_inw(ddekit_addr_t port) { 
+       unsigned long ret;
+       if (sys_inw(port, &ret)) {
+               ddekit_panic("sys_inw failed.");
+       }
+       DDEBUG_MSG_VERBOSE("read port %x: %x", port, ret);
+       return (short) ret;
+}
+
+/****************************************************************************/
+/*      ddekit_inl                                                          */
+/****************************************************************************/
+PUBLIC unsigned long ddekit_inl(ddekit_addr_t port){ 
+       unsigned long ret; 
+       if (sys_inl(port, &ret)) { 
+               ddekit_panic("sys_outl failed.");
+       }
+       DDEBUG_MSG_VERBOSE("read port %x: %x", port, ret);
+       return ret;
+}
+
+/****************************************************************************/
+/*      ddekit_outb                                                         */
+/****************************************************************************/
+PUBLIC void ddekit_outb(ddekit_addr_t port, unsigned char val) { 
+       if (sys_outb(port,val)) {
+               ddekit_panic("sys_outb failed.");
+       }
+       DDEBUG_MSG_VERBOSE("write port %x: %x", port, val);
+}
+
+/****************************************************************************/
+/*      ddekit_outw                                                         */
+/****************************************************************************/
+PUBLIC void ddekit_outw(ddekit_addr_t port, unsigned short val) {
+       if (sys_outw(port,val)) {
+               ddekit_panic("sys_outw failed.");
+       }
+       DDEBUG_MSG_VERBOSE("write port %x: %x", port, val);
+}
+
+/****************************************************************************/
+/*      ddekit_outl                                                         */
+/****************************************************************************/
+PUBLIC void ddekit_outl(ddekit_addr_t port, unsigned long val) { 
+       if (sys_outl(port,val)) {
+               ddekit_panic("sys_outl failed.");
+       }
+       DDEBUG_MSG_VERBOSE("write port %x: %x", port, val);
+}
+
+
diff --git a/lib/libddekit/src/semaphore.c b/lib/libddekit/src/semaphore.c
new file mode 100644 (file)
index 0000000..61d7866
--- /dev/null
@@ -0,0 +1,111 @@
+#include "common.h"
+#include <ddekit/condvar.h>
+#include <ddekit/lock.h>
+#include <ddekit/memory.h>
+#include <ddekit/panic.h>
+#include <ddekit/semaphore.h>
+
+#ifdef DDEBUG_LEVEL_SEMAPHORE
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_SEMAPHORE
+#endif
+
+#include "debug.h"
+#include "thread.h"
+
+struct ddekit_sem {
+       unsigned count;
+       ddekit_thread_t *wait_queue;
+};
+
+#define SEM_DEBUG(p)                                                  \
+    do {                                                              \
+               DDEBUG_MSG_VERBOSE("%s, %p, %d\n",__func__, sem, sem->count); \
+       } while(0)                                                        
+
+/*****************************************************************************
+ *     ddekit_sem_init                                                       *
+ *************************+**************************************************/
+PUBLIC ddekit_sem_t *ddekit_sem_init(int value)
+{  
+       ddekit_sem_t *sem;
+       
+       sem = (ddekit_sem_t *) ddekit_simple_malloc(sizeof(ddekit_sem_t));
+       
+       sem->count = value;
+       sem->wait_queue = NULL;
+       
+       SEM_DEBUG(p);
+       return sem; 
+}
+
+/*****************************************************************************
+ *     ddekit_sem_deinit                                                     *
+ ****************************************************************************/
+PUBLIC void ddekit_sem_deinit(ddekit_sem_t *sem)
+{
+       SEM_DEBUG(p);
+       ddekit_simple_free(sem);        
+}
+
+/*****************************************************************************
+ *     ddekit_sem_down                                                       *
+ ****************************************************************************/
+PUBLIC void ddekit_sem_down(ddekit_sem_t *sem)
+{
+       SEM_DEBUG(p);
+       if(sem->count == 0) {
+               if(sem->wait_queue == NULL) {
+                       sem->wait_queue = ddekit_thread_myself();
+               } else {
+                       ddekit_thread_t *pos = sem->wait_queue;
+                       while(pos->next != NULL) {
+                               pos = pos->next;
+                       }
+                       pos->next = ddekit_thread_myself();
+               }
+               _ddekit_thread_schedule();
+       } else {
+               sem->count--;
+       }
+}
+
+/*****************************************************************************
+ *     ddekit_sem_down_try                                                   *
+ ****************************************************************************/
+PUBLIC int ddekit_sem_down_try(ddekit_sem_t *sem)
+{
+       if(sem->count == 0) {
+               return -1;
+       }
+       sem->count--;
+       return 0;
+}
+
+/*****************************************************************************
+ *     ddekit_sem_up                                                         *
+ ****************************************************************************/
+PUBLIC void ddekit_sem_up(ddekit_sem_t *sem)
+{   
+       SEM_DEBUG(p);
+       if (sem->wait_queue == NULL) {
+               sem->count++;
+               return;
+       } else {
+               ddekit_thread_t *waiter = sem->wait_queue;
+               sem->wait_queue = waiter->next;
+               waiter->next = NULL;
+               _ddekit_thread_enqueue(waiter);
+               ddekit_thread_schedule();
+       }
+}
+
+/****************************************************************************
+ *     ddekit_sem_down_timed                                                *
+ ***************************************************************************/
+PUBLIC int ddekit_sem_down_timed(ddekit_sem_t *sem, int timo )
+{
+       ddekit_panic("not implemented!");
+       return 0;
+}
+
diff --git a/lib/libddekit/src/thread.c b/lib/libddekit/src/thread.c
new file mode 100644 (file)
index 0000000..dcefa27
--- /dev/null
@@ -0,0 +1,499 @@
+#include "common.h"
+#include <ddekit/assert.h>
+#include <ddekit/condvar.h>
+#include <ddekit/memory.h>
+#include <ddekit/panic.h>
+#include <ddekit/timer.h>
+
+#ifdef DDEBUG_LEVEL_THREAD
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_THREAD
+#endif
+
+#include "debug.h"
+#include "util.h"
+#include "thread.h"
+#include "timer.h"
+
+
+/* Incremented to generate unique thread IDs */
+PRIVATE unsigned id;
+
+PRIVATE ddekit_thread_t *ready_queue[DDEKIT_THREAD_PRIOS];
+
+PRIVATE ddekit_thread_t *sleep_queue;
+
+/* Handle to the running thread, set in _dde_kit_thread_schedule() */
+PRIVATE ddekit_thread_t *current = NULL;
+
+FORWARD _PROTOTYPE( void _ddekit_thread_start, (ddekit_thread_t *th));
+FORWARD _PROTOTYPE( void _ddekit_thread_sleep, (unsigned long until));
+
+/*****************************************************************************
+ *    _ddekit_thread_start                                                   *
+ ****************************************************************************/
+PRIVATE void _ddekit_thread_start(ddekit_thread_t *th)
+{
+       /* entry point of newly created threads */
+       th->fun(th->arg);
+       ddekit_thread_exit();
+}
+
+/*****************************************************************************
+ *    _ddekit_thread_sleep                                                   *
+ ****************************************************************************/
+PRIVATE void _ddekit_thread_sleep(unsigned long until)
+{
+       current->next = sleep_queue;
+       sleep_queue = current;
+       current->sleep_until = until;
+       _ddekit_thread_schedule();
+
+}
+
+/*****************************************************************************
+ *    DDEKIT public thread API (ddekit/thread.h)                             *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *    ddekit_yield                                                           *
+ ****************************************************************************/
+PUBLIC void ddekit_yield()
+{
+       ddekit_thread_schedule();
+}
+
+/*****************************************************************************
+ *    ddekit_thread_schedule                                                 *
+ ****************************************************************************/
+PUBLIC void ddekit_thread_schedule()
+{
+       _ddekit_thread_enqueue(current);
+       _ddekit_thread_schedule();
+}
+
+/*****************************************************************************
+ *    ddekit_thread_create                                                   *
+ ****************************************************************************/
+PUBLIC ddekit_thread_t *
+ddekit_thread_create(void (*fun)(void *), void *arg, const char *name)
+{
+       ddekit_thread_t *th  =  
+         (ddekit_thread_t *) ddekit_simple_malloc(sizeof(ddekit_thread_t));
+
+       strncpy(th->name, name, DDEKIT_THREAD_NAMELEN); 
+       th->name[DDEKIT_THREAD_NAMELEN-1] = 0;
+       
+       th->stack = ddekit_large_malloc(DDEKIT_THREAD_STACKSIZE);
+
+       th->arg = arg;
+       th->fun = fun;
+
+       th->id = id++;
+       th->prio = DDEKIT_THREAD_STDPRIO;
+       th->next = NULL;
+       th->sleep_sem = ddekit_sem_init(0);
+
+       
+       /* setup stack */
+
+       void **ptr = (void **)(th->stack + DDEKIT_THREAD_STACKSIZE);
+       *(--ptr) = th;
+       --ptr;
+       --ptr;
+
+       /* TAKEN FROM P_THREAD (written by david?)*/
+#ifdef __ACK__
+    th->jb[0].__pc = _ddekit_thread_start;
+    th->jb[0].__sp = ptr;
+#else /* !__ACK__ */
+#include <sys/jmp_buf.h>
+#if defined(JB_PC) && defined(JB_SP)
+    /* um, yikes. */
+
+    *((void (**)(void))(&((char *)th->jb)[JB_PC])) =
+           (void *)_ddekit_thread_start;
+
+    *((void **)(&((char *)th->jb)[JB_SP])) = ptr;
+#else
+#error "Unsupported Minix architecture"
+#endif
+#endif /* !__ACK__ */
+
+       DDEBUG_MSG_VERBOSE("created thread %s, stack at: %p\n", name,
+           th->stack + DDEKIT_THREAD_STACKSIZE);
+       _ddekit_thread_enqueue(th);
+
+       return th;
+}
+
+/*****************************************************************************
+ *    ddekit_thread_get_data                                                 *
+ ****************************************************************************/
+PUBLIC void *ddekit_thread_get_data(ddekit_thread_t *thread)
+{
+       return thread->data;
+}
+
+/*****************************************************************************
+ *    ddekit_thread_get_my_data                                              *
+ ****************************************************************************/
+PUBLIC void *ddekit_thread_get_my_data(void)
+{
+       return current->data;
+}
+
+/*****************************************************************************
+ *    ddekit_thread_myself                                                   *
+ ****************************************************************************/
+PUBLIC 
+ddekit_thread_t *ddekit_thread_myself(void)
+{
+       return current;
+}
+
+/*****************************************************************************
+ *    ddekit_thread_setup_myself                                             *
+ ****************************************************************************/
+PUBLIC 
+ddekit_thread_t *ddekit_thread_setup_myself(const char *name) {
+       ddekit_thread_t *th  =  
+         (ddekit_thread_t *) ddekit_simple_malloc(sizeof(ddekit_thread_t));
+
+       strncpy(th->name, name, DDEKIT_THREAD_NAMELEN); 
+       th->name[DDEKIT_THREAD_NAMELEN-1] = 0;
+       th->stack = NULL;
+       th->next = NULL;
+       th->id = id++;
+       th->prio = DDEKIT_THREAD_STDPRIO;
+       th->sleep_sem = ddekit_sem_init(0);
+#if DDEBUG >= 4
+       _ddekit_print_backtrace(th);
+#endif
+       return th;
+}
+
+/*****************************************************************************
+ *    ddekit_thread_set_data                                                 *
+ ****************************************************************************/
+PUBLIC void ddekit_thread_set_data(ddekit_thread_t *thread, void *data)
+{
+       thread->data=data;
+}
+
+/*****************************************************************************
+ *    ddekit_thread_set_my_data                                              *
+ ****************************************************************************/
+PUBLIC void ddekit_thread_set_my_data(void *data) 
+{
+       current->data = data;   
+}
+
+/*****************************************************************************
+ *    ddekit_thread_usleep                                                   *
+ ****************************************************************************/
+void ddekit_thread_usleep(unsigned long usecs)
+{
+       /* 
+        * Cannot use usleep here, because it's implemented in vfs.
+        * Assuming the anyway no finder granularity than system's HZ value
+        * can be reached. So we use dde_kit_thread_msleep for now.
+        */
+
+       /* If no timeout is 0 return immediately */ 
+       if (usecs == 0)
+               return;
+
+       unsigned long to = usecs/1000;
+       
+       /* round up to to possible granularity */
+       
+       if (to == 0)
+               to = 1;
+
+       ddekit_thread_msleep(to);
+}
+
+/*****************************************************************************
+ *    ddekit_thread_nsleep                                                   *
+ ****************************************************************************/
+PUBLIC void ddekit_thread_nsleep(unsigned long nsecs)
+{
+       /* 
+        * Cannot use usleep here, because it's implemented in vfs.
+        * Assuming the anyway no finder granularity than system's HZ value
+        * can be reached. So we use dde_kit_thread_msleep.
+        */
+
+       /* If no timeout is 0 return immediately */ 
+       if (nsecs == 0)
+               return;
+
+       unsigned long to = nsecs/1000;
+       
+       /* round up to to possible granularity */
+       
+       if (to == 0)
+               to = 1;
+
+       ddekit_thread_usleep(to);
+}
+
+/*****************************************************************************
+ *    ddekit_thread_msleep                                                   *
+ ****************************************************************************/
+PUBLIC void ddekit_thread_msleep(unsigned long msecs)
+{
+       unsigned long to;
+       
+       to = (msecs*HZ/1000);
+       
+       if (to == 0) {
+               to = 1;
+       }
+       
+       ddekit_thread_t *th = ddekit_thread_myself();
+       
+       if (th == NULL) {
+               ddekit_panic("th==NULL!");
+       }
+
+       if (th->sleep_sem == NULL) {
+               ddekit_panic("th->sleepsem==NULL! %p %s ", th, th->name);
+       } 
+
+       /* generate a timer interrupt at to */
+       ddekit_add_timer(NULL, NULL, to+jiffies);
+       _ddekit_thread_sleep(to+jiffies);
+}
+
+/*****************************************************************************
+ *    ddekit_thread_sleep                                                   *
+ ****************************************************************************/
+PUBLIC void  ddekit_thread_sleep(ddekit_lock_t *lock)
+{
+       WARN_UNIMPL;
+}
+
+/*****************************************************************************
+ *    ddekit_thread_exit                                                     *
+ ****************************************************************************/
+PUBLIC void  ddekit_thread_exit() 
+{
+       ddekit_sem_down(current->sleep_sem);
+       ddekit_panic("thread running after exit!\n");
+       /* not reached */
+       while(1);
+}
+
+/*****************************************************************************
+ *    ddekit_thread_terminate                                                *
+ ****************************************************************************/
+PUBLIC void  ddekit_thread_terminate(ddekit_thread_t *thread)
+{
+       /* todo */
+}
+
+/*****************************************************************************
+ *    ddekit_thread_get_name                                                 *
+ ****************************************************************************/
+PUBLIC const char *ddekit_thread_get_name(ddekit_thread_t *thread)
+{
+       return thread->name;
+}
+
+/*****************************************************************************
+ *    ddekit_thread_get_id                                                   *
+ ****************************************************************************/
+PUBLIC int ddekit_thread_get_id(ddekit_thread_t *thread)
+{
+       return thread->id;
+}
+
+/*****************************************************************************
+ *    ddekit_init_threads                                                    *
+ ****************************************************************************/
+PUBLIC void ddekit_init_threads(void)
+{
+       int i;
+       
+       for (i =0 ; i < DDEKIT_THREAD_PRIOS ; i++) {
+               ready_queue[i] = NULL;
+       }
+       
+       current = ddekit_thread_setup_myself("main");
+       
+       DDEBUG_MSG_INFO("ddekit thread subsystem initialized");
+}
+
+/*****************************************************************************
+ *   DDEKIT internals (src/thread.h)                                         *
+ *****************************************************************************/
+
+/*****************************************************************************
+ *    _ddekit_thread_schedule                                                *
+ ****************************************************************************/
+PUBLIC void _ddekit_thread_schedule()
+{
+
+       DDEBUG_MSG_VERBOSE("called schedule id: %d name %s, prio: %d",
+               current->id, current->name, current->prio);
+
+       /* get our tcb */
+       ddekit_thread_t * th = current;
+
+#if DDEBUG >= 4
+       _ddekit_print_backtrace(th);
+#endif
+
+       /* save our context */
+       if (_setjmp(th->jb) == 0) {
+       
+               int i;
+
+               /* find a runnable thread */
+
+               current = NULL;
+
+               for (i = DDEKIT_THREAD_PRIOS-1; i >= 0; i--) {
+                       if (ready_queue[i]!=NULL) {
+                               current = ready_queue[i];
+                               ready_queue[i] = current->next;
+                               current->next=NULL;
+                               break;
+                       }
+               }
+
+               if (current == NULL) {
+                       ddekit_panic("No runable threads?!");
+               }
+               
+               DDEBUG_MSG_VERBOSE("switching to id: %d name %s, prio: %d",
+                       current->id, current->name, current->prio);
+#if DDEBUG >= 4
+       _ddekit_print_backtrace(current);
+#endif
+               _longjmp(current->jb, 1);
+       }
+
+}
+
+/*****************************************************************************
+ *    _ddekit_thread_enqueue                                                 *
+ ****************************************************************************/
+PUBLIC void _ddekit_thread_enqueue(ddekit_thread_t *th) 
+{
+       
+       DDEBUG_MSG_VERBOSE("enqueueing thread: id: %d name %s, prio: %d",
+               th->id, th->name, th->prio);
+
+#if DDEBUG >= 4
+       _ddekit_print_backtrace(th);
+#endif
+
+       ddekit_assert(th->next==NULL);
+       
+       if (ready_queue[th->prio] != NULL) {
+               ddekit_thread_t *pos = ready_queue[th->prio];
+               while (pos->next != NULL) {
+                       pos = pos->next;
+               }
+               pos->next = th;
+       } else {
+               ready_queue[th->prio] = th;
+       }
+}
+
+/*****************************************************************************
+ *    _ddekit_thread_set_myprio                                              *
+ ****************************************************************************/
+PUBLIC void _ddekit_thread_set_myprio(int prio)
+{
+       DDEBUG_MSG_VERBOSE("changing thread prio, id: %d name %s, old prio: %d, "
+               "new prio: %d", current->id, current->name, current->prio);
+
+       current->prio = prio;
+       ddekit_thread_schedule();
+}
+
+/*****************************************************************************
+ *    _ddekit_thread_wakeup_sleeping                                         *
+ ****************************************************************************/
+PUBLIC void _ddekit_thread_wakeup_sleeping()
+{
+       ddekit_thread_t *th = sleep_queue;
+       
+       sleep_queue = NULL;
+
+       while (th != NULL) {
+               ddekit_thread_t *th1 = th->next;
+               if (th->sleep_until > jiffies) {
+                       th->next = sleep_queue;
+                       sleep_queue = th;
+               } else {
+                       th->next = NULL;
+                       _ddekit_thread_enqueue(th);
+               }
+               th = th1;
+       }
+
+       ddekit_thread_schedule();
+}
+
+#define FUNC_STACKTRACE(statement)                             \
+{                                                              \
+       reg_t bp, pc, hbp;                                      \
+       extern reg_t get_bp(void);                              \
+                                                               \
+       bp= get_bp();                                           \
+       while(bp)                                               \
+       {                                                       \
+               pc= ((reg_t *)bp)[1];                           \
+               hbp= ((reg_t *)bp)[0];                          \
+               statement;                                      \
+               if (hbp != 0 && hbp <= bp)                      \
+               {                                               \
+                       pc = -1;                                \
+                       statement;                              \
+                       break;                                  \
+               }                                               \
+               bp= hbp;                                        \
+       }                                                       \
+}
+
+/*****************************************************************************
+ *    _ddekit_print_backtrace                                                *
+ ****************************************************************************/
+PUBLIC void _ddekit_print_backtrace(ddekit_thread_t *th)
+{
+       unsigned long bp, pc, hbp;                              
+
+       ddekit_printf("%s: ", th->name);
+
+#ifdef __ACK__
+       bp =th->jb[0].__bp;
+#else /* !__ACK__ */
+#include <sys/jmp_buf.h>
+#if defined(JB_PC) && defined(JB_SP)
+       /* um, yikes. */
+       bp = (unsigned long) *((void **)(&((char *)th->jb)[JB_BP]));
+#else
+#error "Unsupported Minix architecture"
+#endif
+#endif /* !__ACK__ */
+
+       while (bp) {                                                    
+               pc  = ((unsigned long *)bp)[1];                         
+               hbp = ((unsigned long *)bp)[0];
+
+               ddekit_printf("0x%lx ", (unsigned long) pc);
+
+               if (hbp != 0 && hbp <= bp) {    
+                       pc = -1;        
+                       ddekit_printf("0x%lx ", (unsigned long) pc);
+                       break;                                  
+               }                                               
+               bp= hbp;                                        
+       }                                                       
+       ddekit_printf("\n");
+}
diff --git a/lib/libddekit/src/thread.h b/lib/libddekit/src/thread.h
new file mode 100644 (file)
index 0000000..322fa62
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef DDEKIT_SRC_THREAD_H
+#define DDEKIT_SRC_THREAD_H 1
+#include <ddekit/thread.h> 
+#include <ddekit/semaphore.h> 
+#include <setjmp.h>
+
+#define DDEKIT_THREAD_NAMELEN 32
+#define DDEKIT_THREAD_PRIOS 3
+#define DDEKIT_THREAD_STDPRIO 1
+
+#define DDEKIT_THREAD_STACKSIZE (4096*16)
+
+/* This threadlib makes following assumptions:
+ *  No Preemption,
+ *  No signals,
+ *  No blocking syscalls
+ *  Threads cooperate.
+ */
+
+struct ddekit_thread {
+       int id;
+       int prio;
+       void (*fun)(void *);
+       char *stack;
+       void *arg;
+       void *data;
+       unsigned sleep_until;
+       char name[DDEKIT_THREAD_NAMELEN];
+       jmp_buf jb;
+       ddekit_sem_t *sleep_sem;
+       struct ddekit_thread * next;
+};
+
+
+void _ddekit_thread_set_myprio(int prio);
+void _ddekit_thread_enqueue(ddekit_thread_t *th); 
+void _ddekit_thread_schedule();
+void _ddekit_thread_wakeup_sleeping();
+void _ddekit_print_backtrace(ddekit_thread_t *th);
+
+
+#endif
diff --git a/lib/libddekit/src/timer.c b/lib/libddekit/src/timer.c
new file mode 100644 (file)
index 0000000..75e848e
--- /dev/null
@@ -0,0 +1,315 @@
+#include "common.h"
+
+#include <ddekit/memory.h> 
+#include <ddekit/semaphore.h>
+#include <ddekit/thread.h>
+#include <ddekit/timer.h>
+
+#ifdef DDEBUG_LEVEL_TIMER
+#undef DDEBUG
+#define DDEBUG DDEBUG_LEVEL_TIMER
+#endif
+
+#include "debug.h"
+#include "thread.h"
+
+#define DDEBUG_MSG_TIMER(t) \
+       DDEBUG_MSG_VERBOSE("id: %d, exp: %d, fn: %d, now %d", \
+                           (t)->id, (t)->exp, (t)->fn, jiffies)
+
+typedef clock_t myclock_t;
+
+struct ddekit_timer_s { 
+       void (*fn)(void *);
+       void *args;
+       int id;
+       myclock_t exp;  
+       struct ddekit_timer_s * next;
+};
+
+
+PRIVATE ddekit_sem_t *pending_timer_ints;
+
+/* are we currently expecting a alarm notify? */
+int _ddekit_timer_pending = 0;
+
+PUBLIC unsigned long long jiffies;
+PUBLIC unsigned long HZ; 
+
+PRIVATE struct ddekit_timer_s list =  {0,0,-1,1,0}; 
+PRIVATE int _id = 0 ; 
+PRIVATE ddekit_thread_t *th;
+PRIVATE  ddekit_lock_t lock;
+
+FORWARD _PROTOTYPE( void lock_timer, (void));
+FORWARD _PROTOTYPE( void unlock_timer, (void));
+FORWARD _PROTOTYPE( clock_t get_current_clock, (void));
+FORWARD _PROTOTYPE( void remove_timer, (int id));
+FORWARD _PROTOTYPE( int insert_timer, (struct ddekit_timer_s *t));
+FORWARD _PROTOTYPE( struct ddekit_timer_s * get_next, ( myclock_t exp ));
+FORWARD _PROTOTYPE( void ddekit_timer_thread, (void *data));
+
+ /****************************************************************************
+ *    Private funtions                                                       *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *    lock_timer                                                             *
+ ****************************************************************************/
+PRIVATE void lock_timer() 
+{
+       ddekit_lock_lock(&lock);
+}
+
+/*****************************************************************************
+ *    unlock_timer                                                           *
+ ****************************************************************************/
+static void unlock_timer() 
+{
+       ddekit_lock_unlock(&lock);
+}
+
+/*****************************************************************************
+ *    get_current_clock                                                      *
+ ****************************************************************************/
+static myclock_t get_current_clock()
+{ 
+       /* returns the current clock tick */
+       myclock_t ret;
+       getuptime(&ret);
+       return ret;
+}
+
+/*****************************************************************************
+ *    remove_timer                                                           *
+ ****************************************************************************/
+PRIVATE void remove_timer(int id)
+{
+       /* removes a timer from the timer list */
+       struct ddekit_timer_s *l,*m;  
+       
+       lock_timer();
+
+       for (l = &list; l &&  l->next && l->next->id!=id; l = l->next )
+               ;
+
+       if (l && l->next) {
+               m = l->next;
+
+               DDEBUG_MSG_VERBOSE(
+                   "deleting  timer at for tick: %d fn: %p, (now: %d)\n",
+                       m->exp, m->fn, jiffies);
+
+               l->next = m->next;
+               DDEBUG_MSG_TIMER(m);
+
+               ddekit_simple_free(m); 
+       }
+       
+       unlock_timer();
+}
+
+/*****************************************************************************
+ *    insert_timer                                                           *
+ ****************************************************************************/
+PRIVATE int insert_timer(struct ddekit_timer_s *t)
+{ 
+       /* inserts a timer to the timer list */
+       int ret;
+       
+       lock_timer(); 
+       
+       struct ddekit_timer_s *l;
+       
+       for (l = &list; l->next && l->next->exp <= t->exp; l = l->next) {
+                       
+       }
+       
+       t->next = l->next;  
+       l->next = t;
+       
+       t->id   = ret = _id;
+       
+       _id++;
+       
+       if (_id==0) { 
+               DDEBUG_MSG_WARN("Timer ID overflow...");
+       }
+
+       DDEBUG_MSG_TIMER(t);
+
+       unlock_timer();
+
+       return ret;
+}
+
+/*****************************************************************************
+ *    get_next                                                               *
+ ****************************************************************************/
+PRIVATE struct ddekit_timer_s * get_next( myclock_t exp )
+{  
+       /*
+        * this one get the next timer, which's timeout expired,
+        * returns NULL if no timer is pending
+        */
+       struct ddekit_timer_s * ret = 0;
+       lock_timer();
+       if (list.next)
+       { 
+               if (list.next->exp <= exp)
+               { 
+                       ret  = list.next;
+                       list.next = ret->next;
+               }
+       }
+       unlock_timer();
+       return ret;
+}
+
+/*****************************************************************************
+ *    ddekit_timer_thread                                                    *
+ ****************************************************************************/
+PRIVATE void ddekit_timer_thread(void * data)
+{
+       struct ddekit_timer_s * l;
+
+       /* rock around the clock! */ 
+       for ( ; ; )
+       { 
+               /* wait for timer interrupts */
+               ddekit_sem_down(pending_timer_ints);
+               DDEBUG_MSG_VERBOSE("handling timer interrupt");         
+               
+               /* execute all expired timers */
+               while( (l = get_next(jiffies)) != 0 ) { 
+                       DDEBUG_MSG_TIMER(l);
+                       if (l->fn) {
+                               l->fn(l->args);
+                       }
+                       ddekit_simple_free(l);
+               }
+       }
+}
+
+
+ /****************************************************************************
+ *    Public functions (ddekit/timer.h)                                      *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *    ddekit_add_timer                                                       *
+ ****************************************************************************/
+PUBLIC int ddekit_add_timer
+(void (*fn)(void *), void *args, unsigned long timeout)
+{
+       struct ddekit_timer_s *t;
+       
+       t = (struct ddekit_timer_s *) 
+           ddekit_simple_malloc(sizeof(struct ddekit_timer_s ));
+       
+       t->fn   = fn;
+       t->args = args;
+       t->exp = (myclock_t) timeout;
+
+       return insert_timer(t);
+}
+
+/*****************************************************************************
+ *    ddekit_del_timer                                                       *
+ ****************************************************************************/
+PUBLIC int ddekit_del_timer(int timer)
+{ 
+       remove_timer(timer); 
+       return 0;
+}
+
+/*****************************************************************************
+ *    ddekit_timer_pending                                                   *
+ ****************************************************************************/
+PUBLIC int ddekit_timer_pending(int timer)
+{ 
+       int ret=0;
+       struct ddekit_timer_s *t;
+       lock_timer();
+       for (t=list.next; t; t = t->next) { 
+               if (t->id==timer) {  
+                       ret = 1;
+               }
+                       
+       }
+       unlock_timer();
+       return ret;
+}
+
+/*****************************************************************************
+ *    ddekit_init_timers                                                     *
+ ****************************************************************************/
+PUBLIC void ddekit_init_timers(void)
+{
+       static int first_time=0;
+       
+       if (!first_time)
+       {
+               ddekit_lock_init(&lock);
+               jiffies = get_current_clock();
+               HZ = sys_hz(); 
+               pending_timer_ints = ddekit_sem_init(0);        
+               th = ddekit_thread_create(ddekit_timer_thread, 0, "timer");
+               first_time=1;
+               DDEBUG_MSG_INFO("DDEkit timer subsustem initialized");
+       }
+}
+
+/*****************************************************************************
+ *    ddekit_get_timer_thread                                                *
+ ****************************************************************************/
+PUBLIC ddekit_thread_t *ddekit_get_timer_thread(void)
+{ 
+       return th;
+}
+
+/****************************************************************************
+ *    ddekit_internal (src/timer.h)                                         *
+ ****************************************************************************/
+
+/*****************************************************************************
+ *   _ddekit_timer_interrupt                                                 *
+ ****************************************************************************/
+PUBLIC void _ddekit_timer_interrupt(void)
+{
+       jiffies = get_current_clock(); 
+       DDEBUG_MSG_VERBOSE("now: %d", jiffies);
+       ddekit_sem_up(pending_timer_ints);
+}
+
+/*****************************************************************************
+ *    _ddekit_timer_update                                                   *
+ ****************************************************************************/
+PUBLIC void _ddekit_timer_update()
+{
+       lock_timer();
+
+       static myclock_t next_timout;
+       if(list.next)
+       {
+               if(!_ddekit_timer_pending || list.next->exp < next_timout) {
+                       
+                       unsigned to = list.next->exp - jiffies;
+                       
+                       _ddekit_timer_pending = 1;
+                       
+                       if (list.next->exp <= jiffies) {
+                               DDEBUG_MSG_WARN("Timeout lies in past to %d, now: %d",
+                                       list.next->exp, jiffies);
+                               to = 1;
+                       }
+                       
+                       sys_setalarm(to, 0 /* REL */);
+
+                       DDEBUG_MSG_VERBOSE("requesting alarm for clock tick %d , now %d",
+                               list.next->exp, jiffies);
+               }
+               next_timout = list.next->exp;
+       }
+       unlock_timer(); 
+}
diff --git a/lib/libddekit/src/timer.h b/lib/libddekit/src/timer.h
new file mode 100644 (file)
index 0000000..0d7751b
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef DDEKIT_TIMER_MINIX_H
+#define DDEKIT_TIMER_MINIX_H 1 
+
+
+extern unsigned long long jiffies;  
+extern unsigned long HZ;  
+
+void _ddekit_timer_interrupt(void);
+extern int _ddekit_timer_pending;
+void _ddekit_timer_update(void);
+#endif
diff --git a/lib/libddekit/src/usb_client.c b/lib/libddekit/src/usb_client.c
new file mode 100644 (file)
index 0000000..13463db
--- /dev/null
@@ -0,0 +1,223 @@
+#include "common.h"
+#include <ddekit/usb.h>
+#include <ddekit/memory.h>
+#include <ddekit/minix/msg_queue.h>
+#include <minix/usb.h>
+
+struct ddekit_usb_dev {
+       int id;
+       unsigned int interfaces;
+       void *data;
+       struct ddekit_usb_dev *next;
+       struct ddekit_usb_dev *prev;
+};
+
+struct ddekit_usb_dev dev_list_head = {
+       .next = &dev_list_head,
+       .prev = &dev_list_head,
+};
+
+PRIVATE struct ddekit_usb_driver *d_usb_driver;
+
+FORWARD _PROTOTYPE( void _ddekit_usb_completion, (struct usb_urb *mx));
+FORWARD _PROTOTYPE( void _ddekit_usb_connect, 
+                    ( unsigned int dev_id, unsigned int interfaces));
+FORWARD _PROTOTYPE(void  _ddekit_usb_disconnect, (unsigned dev_id));
+
+struct usb_driver mx_usb_driver = {
+       .urb_completion = _ddekit_usb_completion,
+       .connect_device = _ddekit_usb_connect,
+       .disconnect_device = _ddekit_usb_disconnect
+};
+
+/*****************************************************************************
+ *         _ddekit_usb_completion                                            *
+ ****************************************************************************/
+PRIVATE void _ddekit_usb_completion(struct usb_urb *mx_urb)
+{
+
+       struct ddekit_usb_urb *d_urb = (struct ddekit_usb_urb *) mx_urb->priv;
+
+       /* XXX: copy stuff back into d_urb */
+
+       d_urb->status         = mx_urb->status;
+       d_urb->error_count    = mx_urb->interval;
+       d_urb->transfer_flags = mx_urb->error_count;
+       d_urb->actual_length  = mx_urb->actual_length;
+       d_urb->ddekit_priv    = NULL;
+
+       if (mx_urb->type == USB_TRANSFER_CTL) {
+               memcpy(d_urb->setup_packet, mx_urb->setup_packet, 8);
+       }
+
+       if (mx_urb->type == USB_TRANSFER_ISO) {
+               d_urb->start_frame = mx_urb->start_frame;
+               
+               memcpy(d_urb->iso_desc, mx_urb->buffer + d_urb->size,
+                      d_urb->number_of_packets * sizeof(struct usb_iso_packet_desc));
+       }
+       
+       memcpy(d_urb->data, mx_urb->buffer, d_urb->size);
+       
+       /* free mx_urb */
+       ddekit_simple_free(mx_urb);
+
+       /* 'give back' URB */
+       
+
+       d_usb_driver->completion(d_urb->priv);
+}
+
+
+/*****************************************************************************
+ *         _ddekit_usb_connect                                               *
+ ****************************************************************************/
+PRIVATE void _ddekit_usb_connect(unsigned int dev_id, unsigned int interfaces)
+{
+       struct ddekit_usb_dev *d_dev = (struct ddekit_usb_dev *)
+               ddekit_simple_malloc(sizeof(struct ddekit_usb_dev));
+
+       d_dev->data       = NULL;
+       d_dev->id         = dev_id;
+       d_dev->interfaces = interfaces;
+
+       /* add to list */
+
+       d_dev->next = dev_list_head.next; 
+       d_dev->prev = &dev_list_head;
+
+       dev_list_head.next = d_dev; 
+       d_dev->next->prev = d_dev;
+       d_usb_driver->connect(d_dev, interfaces);
+}
+
+/*****************************************************************************
+ *         _ddekit_usb_disconnect                                            *
+ ****************************************************************************/
+PUBLIC void _ddekit_usb_disconnect(unsigned dev_id)
+{
+       /* find dev */
+       struct ddekit_usb_dev *it;
+       struct ddekit_usb_dev *d_dev = NULL;
+
+
+       for (it = dev_list_head.next; it != &dev_list_head; it= it->next) {
+               if (it->id == dev_id) {
+                       d_dev = it;
+                       break;
+               }
+       }
+
+       if (d_dev == NULL) {
+               return;
+       }
+
+       d_usb_driver->disconnect(d_dev);
+}
+
+/*****************************************************************************
+ *         ddekit_usb_dev_set_data                                           *
+ ****************************************************************************/
+PUBLIC int ddekit_usb_dev_set_data(struct ddekit_usb_dev *dev, void *data)
+{
+       dev->data = data;
+       return 0;
+}
+
+/*****************************************************************************
+ *         ddekit_usb_dev_get_data                                           *
+ ****************************************************************************/
+PUBLIC void *ddekit_usb_dev_get_data(struct ddekit_usb_dev *dev)
+{
+       return dev->data;
+}
+
+/*****************************************************************************
+ *         ddekit_usb_submit_urb                                             *
+ ****************************************************************************/
+PUBLIC int ddekit_usb_submit_urb(struct ddekit_usb_urb *d_urb) 
+{
+       int res;
+       unsigned urb_size = USB_URBSIZE(d_urb->size, d_urb->number_of_packets);
+       
+       /* create mx urb out of d_urb */
+       struct usb_urb *mx_urb = (struct usb_urb*) 
+           ddekit_simple_malloc(urb_size);
+       
+       mx_urb->urb_size = urb_size;
+
+       mx_urb->dev_id = d_urb->dev->id;
+       mx_urb->type = d_urb->type;
+       mx_urb->endpoint = d_urb->endpoint;
+       mx_urb->direction = d_urb->direction;
+       mx_urb->interval = d_urb->interval;
+       mx_urb->transfer_flags = d_urb->transfer_flags;
+       mx_urb->size = d_urb->size;
+       mx_urb->priv = d_urb;
+
+       if (mx_urb->type == USB_TRANSFER_CTL) {
+               memcpy(mx_urb->setup_packet, d_urb->setup_packet, 8);
+       }
+
+       if (mx_urb->type == USB_TRANSFER_ISO) {
+               mx_urb->number_of_packets = d_urb->number_of_packets;
+               mx_urb->start_frame = d_urb->start_frame;
+               
+               memcpy(mx_urb->buffer + d_urb->size, d_urb->iso_desc,
+                   d_urb->number_of_packets * sizeof(struct usb_iso_packet_desc));
+       }
+       
+       memcpy(mx_urb->buffer, d_urb->data, d_urb->size);
+
+       d_urb->ddekit_priv = mx_urb;
+
+       /* submit mx_urb */
+       res = usb_send_urb(mx_urb);
+       
+       return res;
+}
+
+/*****************************************************************************
+ *         ddekit_usb_cancle_urb                                             *
+ ****************************************************************************/
+PUBLIC int ddekit_usb_cancle_urb(struct ddekit_usb_urb *d_urb)
+{
+       int res;
+
+       /* get the associated mx_urb */
+       struct usb_urb *mx_urb = (struct usb_urb *) d_urb->ddekit_priv;
+
+       res = usb_cancle_urb(mx_urb);
+
+       return res;
+}
+
+static void _ddekit_usb_thread()
+{ 
+       struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(USB_BASE, 
+                                           USB_BASE + 0x1000);
+       message m;
+
+       while (1) {
+               ddekit_minix_rcv(mq, &m);
+               usb_handle_msg(&mx_usb_driver,&m);
+       }
+
+}
+       
+/*****************************************************************************
+ *         ddekit_usb_init                                             *
+ ****************************************************************************/
+PUBLIC int ddekit_usb_init
+(struct ddekit_usb_driver *drv,
+ ddekit_usb_malloc_fn     *unused,
+ ddekit_usb_free_fn       *_unused) 
+{
+       
+       /* start usb_thread */
+       d_usb_driver =  drv;
+       usb_init("dde");
+       _ddekit_usb_thread();
+       return 0;
+}
+
diff --git a/lib/libddekit/src/usb_server.c b/lib/libddekit/src/usb_server.c
new file mode 100644 (file)
index 0000000..2220497
--- /dev/null
@@ -0,0 +1,805 @@
+#include "common.h"
+
+#include <ddekit/minix/msg_queue.h>
+#include <ddekit/panic.h>
+#include <ddekit/printf.h>
+#include <ddekit/usb.h>
+#include <minix/safecopies.h>
+#include <minix/usb.h>
+#include <minix/usb_ch9.h>
+#include <minix/devman.h>
+
+#define MAX_URBS    10
+
+#define DRIVER_UNUSED 0
+#define DRIVER_ACTIVE 1
+#define DRIVER_BOUND  2
+
+#if 0
+#define DEBUG_MSG(fmt, ...) ddekit_printf("%s : "fmt"\n", __func__, ##__VA_ARGS__ ) 
+#else
+#define DEBUG_MSG(fmt, ...)
+#endif
+
+#undef DDEBUG
+#define DDEBUG 0
+#include "debug.h"
+
+#define MAX_DEVS 256
+#define MAX_DRIVERS 256
+#define OK 0
+
+#define INVAL_DEV (-1)
+
+struct my_context {
+       unsigned urb_id;
+       struct ddekit_usb_urb *d_urb;
+       struct usb_urb *mx_urb;
+       struct minix_usb_driver *drv;
+       gid_t gid;
+};
+
+struct minix_usb_driver {
+       endpoint_t ep;                       /* address of the client */
+
+       int status;                          /* In what state is the client? */
+
+       int dev;                          /* which device is this driver handling */
+       unsigned interfaces;                 /* which interfaces of the device the
+                                               driver is handling */
+       
+       struct ddekit_usb_urb *urbs[MAX_URBS]; /* pending urbs */
+
+       unsigned long urb_id;                        /* generation of driver_local urb_ids */
+};
+
+struct minix_usb_device {
+       struct ddekit_usb_dev *dev;
+       unsigned int interfaces; 
+};
+
+FORWARD _PROTOTYPE( struct minix_usb_driver *find_driver,(endpoint_t ep));
+FORWARD _PROTOTYPE( struct minix_usb_driver *find_unused_driver, (void));
+FORWARD _PROTOTYPE( int add_to_pending_urbs,
+                    (struct minix_usb_driver *drv, struct ddekit_usb_urb *urb));
+FORWARD _PROTOTYPE( int remove_from_pending_urbs,
+                    (struct minix_usb_driver *drv, struct ddekit_usb_urb *urb));
+FORWARD _PROTOTYPE( struct ddekit_usb_urb * find_pending_urb,
+                    (struct minix_usb_driver *drv, unsigned urb_id));
+FORWARD _PROTOTYPE( void register_driver, (message *msg));
+FORWARD _PROTOTYPE( struct ddekit_usb_urb *ddekit_usb_urb_from_mx_urb,
+                    (struct usb_urb *mx_urb));
+FORWARD _PROTOTYPE( void submit_urb, (message *msg));
+FORWARD _PROTOTYPE( void cancle_urb, (message *msg));
+FORWARD _PROTOTYPE( void completion_callback, (void *priv));
+
+FORWARD _PROTOTYPE( void prepare_devman_usbdev,
+                    (struct ddekit_usb_dev * dev, int dev_id,
+                                        unsigned int interfaces, struct devman_usb_dev *dudev));
+FORWARD _PROTOTYPE( void device_disconnect_callback, (struct ddekit_usb_dev * dev));
+FORWARD _PROTOTYPE( int add_acl,
+                    (int dev_id, unsigned interfaces, endpoint_t ep) );
+FORWARD _PROTOTYPE( int del_acl,
+                    (int dev_id, unsigned interaces, endpoint_t ep) );
+FORWARD _PROTOTYPE( int handle_msg, (message *msg));
+FORWARD _PROTOTYPE( void _ddekit_usb_thread, ());
+FORWARD _PROTOTYPE( void device_connect_callback,
+                    (struct ddekit_usb_dev * dev, unsigned int interfaces));
+
+_PROTOTYPE( char *_ddekit_usb_get_manufacturer, (struct ddekit_usb_dev *ddev));
+_PROTOTYPE( char *_ddekit_usb_get_product, (struct ddekit_usb_dev *ddev));
+_PROTOTYPE( char *_ddekit_usb_get_serial, (struct ddekit_usb_dev *ddev));
+_PROTOTYPE( usb_device_descriptor_t *_ddekit_usb_get_device_desc,
+            (struct ddekit_usb_dev *ddev));
+_PROTOTYPE( usb_interface_descriptor_t *_ddekit_usb_get_interface_desc,
+            (struct ddekit_usb_dev *ddev, int inum));
+
+
+PRIVATE ddekit_usb_malloc_fn my_malloc;
+PRIVATE ddekit_usb_free_fn my_free;
+PRIVATE struct minix_usb_driver gbl_drivers[MAX_DRIVERS];
+PRIVATE struct minix_usb_device _devices[MAX_DEVS];
+
+PRIVATE struct ddekit_usb_driver my_driver = {
+       .completion = completion_callback,
+       .connect    = device_connect_callback,
+       .disconnect = device_disconnect_callback,
+};
+
+
+/*****************************************************************************
+ *         find_driver                                                       *
+ ****************************************************************************/
+PRIVATE struct minix_usb_driver *find_driver(endpoint_t ep) 
+{
+       int i;
+       for (i = 0; i < MAX_DRIVERS; i++ ){
+               if (gbl_drivers[i].ep == ep) {
+                       return &gbl_drivers[i];
+               }
+       }
+       return NULL;
+}
+
+/*****************************************************************************
+ *         find_unused_driver                                                *
+ ****************************************************************************/
+PRIVATE struct minix_usb_driver *find_unused_driver() 
+{
+       int i;
+       for (i = 0; i < MAX_DRIVERS; i++ ){
+               if (gbl_drivers[i].status == DRIVER_UNUSED) {
+                       return &gbl_drivers[i];
+               }
+       }
+       return NULL;
+}
+
+/*****************************************************************************
+ *         add_to_pending_urbs                                               *
+ ****************************************************************************/
+PRIVATE int add_to_pending_urbs(struct minix_usb_driver *drv,
+                               struct ddekit_usb_urb *urb)
+{
+       int i;
+
+       for (i = 0; i < MAX_URBS; i++) {
+               if (drv->urbs[i] == NULL) {
+                       drv->urbs[i] = urb;
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+/*****************************************************************************
+ *         remove_from_pending_urbs                                          *
+ ****************************************************************************/
+PRIVATE int remove_from_pending_urbs(struct minix_usb_driver *drv,
+                               struct ddekit_usb_urb *urb)
+{
+       int i;
+
+       for (i = 0; i < MAX_URBS; i++) {
+               if (drv->urbs[i] == urb) {
+                       drv->urbs[i] = NULL;
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+/*****************************************************************************
+ *         find_pending_urb                                                  *
+ ****************************************************************************/
+PRIVATE struct ddekit_usb_urb * find_pending_urb(struct minix_usb_driver *drv,
+                                                unsigned urb_id) 
+{
+       int i;
+
+       for (i = 0; i < MAX_URBS; i++) {
+               if (((struct my_context*)drv->urbs[i]->priv)->urb_id == urb_id) {
+                               return drv->urbs[i];
+               }
+       }
+
+       return NULL;
+}
+
+/*****************************************************************************
+ *         register_driver                                                   *
+ ****************************************************************************/
+PRIVATE void register_driver(message *msg)
+{
+       endpoint_t ep = msg->m_source;
+       struct minix_usb_driver *drv;
+
+       msg->m_type=USB_REPLY;
+
+       if ( (drv = find_driver(ep)) != NULL) {
+               msg->m_type = USB_REPLY;
+               msg->USB_RESULT = OK;
+               send(ep,msg);
+       } else {
+               msg->m_type = USB_REPLY;
+               msg->USB_RESULT = EPERM;
+               send(ep,msg);
+               return; 
+       }
+       
+       DEBUG_MSG("DRIVER %d registered \n"
+                     "Announcing device %d, interfaces 0x%x\n",
+                                 ep,
+                                 drv->dev,
+                                 drv->interfaces);
+
+       /* hand out the device */
+       msg->m_type = USB_ANNOUCE_DEV;
+       msg->USB_DEV_ID     = drv->dev;
+       msg->USB_INTERFACES = drv->interfaces;
+       send(ep, msg);
+}
+
+/*****************************************************************************
+ *         deregister_driver                                                 *
+ ****************************************************************************/
+PRIVATE void deregister_driver(message *msg)
+{
+       endpoint_t ep = msg->m_source;
+       
+       struct minix_usb_driver *drv;
+
+       msg->m_type=USB_REPLY;
+
+       if ( (drv = find_driver(ep)) == NULL) {
+               DEBUG_MSG("Non-registered driver tries to unregister.");
+               return; 
+       } else {
+               /* do not accept requests for this client anymore! */
+               drv->status = DRIVER_UNUSED;
+
+               msg->USB_RESULT = 0;
+               asynsend3(ep, msg, AMF_NOREPLY);
+       }
+}
+
+/*****************************************************************************
+ *         ddekit_usb_urb_from_mx_urb                                        *
+ ****************************************************************************/
+PRIVATE struct ddekit_usb_urb *ddekit_usb_urb_from_mx_urb(struct usb_urb *mx_urb)
+{
+       /*
+        * A helper function that generates (allocates and initializes)
+        * a ddekit_usb_urb.
+        */
+
+       struct ddekit_usb_urb *d_urb = (struct ddekit_usb_urb *)
+               my_malloc(sizeof(struct ddekit_usb_urb));
+
+       if (d_urb == NULL) {
+               return NULL;
+       }
+
+       d_urb->type           = mx_urb->type;
+       d_urb->direction      = mx_urb->direction;
+       d_urb->transfer_flags = mx_urb->transfer_flags;
+       d_urb->size           = mx_urb->size;
+       d_urb->data           = mx_urb->buffer;
+       d_urb->interval       = mx_urb->interval;
+       d_urb->endpoint       = mx_urb->endpoint;
+
+       if (d_urb->type == USB_TRANSFER_CTL) {
+               d_urb->setup_packet = mx_urb->setup_packet;
+       }
+       DEBUG_MSG("setup_package at %p", d_urb->setup_packet);
+
+       if (d_urb->type == USB_TRANSFER_ISO) {
+               d_urb->iso_desc  = (struct ddekit_usb_iso_packet_desc *)
+                   mx_urb->buffer + mx_urb->iso_desc_offset;
+               d_urb->number_of_packets = mx_urb->number_of_packets;
+       }
+
+       return d_urb;
+}
+
+/*****************************************************************************
+ *         submit_urb                                                        *
+ ****************************************************************************/
+PRIVATE void submit_urb(message *msg)
+{
+       /*
+        * submit_urb
+        *
+        * Handles a submit_urb from a minix USB device driver. It copies the 
+        * usb_urb structure containing the buffers and generates and tries to
+        * submit a ddekit_usb_urb. The reference to the ddekit_usb_urb is stored
+        * in the driver structure in order to be able to cancle the URB on the
+        * clients request.
+        */
+       endpoint_t ep = msg->m_source;
+       struct minix_usb_driver *drv;
+
+       /* find driver */
+       if ( (drv = find_driver(ep)) == NULL) {
+               DEBUG_MSG("Non-registered driver tries to send URB.");
+               return; 
+       } else {
+
+               int res;
+               
+               struct usb_urb *mx_urb  = (struct usb_urb*) 
+                   my_malloc(msg->USB_GRANT_SIZE+sizeof(void *));
+
+               if (mx_urb == NULL) {
+                       DEBUG_MSG("Can't allocat mem for mx_urb.");
+                       res = ENOMEM;
+                       goto out;
+               }
+
+               /* copy in URB */
+               res = sys_safecopyfrom(ep, msg->USB_GRANT_ID, 0,
+                   (vir_bytes) &mx_urb->dev_id, msg->USB_GRANT_SIZE, D);
+
+               if (res != 0) {
+                       DEBUG_MSG("sys_safecopyfrom failed ");
+                       my_free(mx_urb);
+                       res = EINVAL;
+                       goto out;
+               }
+               
+               DEBUG_MSG("URB type: %d", mx_urb->type);
+               /* check if urb is valid */
+               if (mx_urb->dev_id >= MAX_DEVS && mx_urb->dev_id < 0) {
+                       DEBUG_MSG("Bogus device ID.");
+                       res = EINVAL;
+                       goto out;
+               }
+               
+               /* create ddekit_usb_urb */
+               struct ddekit_usb_urb *d_urb = ddekit_usb_urb_from_mx_urb(mx_urb);
+               d_urb->dev = _devices[drv->dev].dev;
+               /* submit urb */
+
+               if (!d_urb) {
+                       res = ENOMEM;
+                       goto out;
+               }
+               
+               struct my_context *ctx = (struct my_context *) 
+                   my_malloc(sizeof(struct my_context));
+
+               if(!ctx) {
+                       res = ENOMEM;
+                       goto out;
+               }
+
+               ctx->drv       = drv;
+               ctx->urb_id    = drv->urb_id++;
+               mx_urb->urb_id = ctx->urb_id;
+               ctx->mx_urb    = mx_urb;
+               ctx->d_urb     = d_urb;
+               ctx->gid       = msg->USB_GRANT_ID;
+               
+               DEBUG_MSG("ctx: %p, urb_id: %d, d_urb: %p, mx_urb: %p, drv: %d, gid: %d ",
+                   ctx, ctx->urb_id, ctx->d_urb, ctx->mx_urb, ctx->drv, ctx->gid);
+
+               d_urb->priv = ctx;
+
+               res = add_to_pending_urbs(drv, d_urb);
+       
+               if (res == 0) {
+                       DEBUG_MSG("submitting urb...");
+                       res = ddekit_usb_submit_urb(d_urb);
+                       if(res) {
+                               DEBUG_MSG("submitting urb failed (err: %d)", res);
+                               remove_from_pending_urbs(drv, d_urb);
+                       }
+               }
+       
+out:           
+               /* reply */
+               msg->m_type     = USB_REPLY;
+               msg->USB_URB_ID = mx_urb->urb_id;
+               msg->USB_RESULT = res;
+
+               if(res != 0) {
+               
+                       if (mx_urb != NULL) {
+                               my_free(mx_urb);
+                       }
+                       if (ctx != NULL) {
+                               my_free(ctx);
+                       }
+
+                       if (d_urb != NULL) {
+                               my_free(d_urb);
+                       }
+                       
+               }
+
+               /* send reply */
+               send(ep, msg);
+       }
+}
+
+
+/*
+ * cancle_urb
+ * 
+ * Cancels the submission of an URB identified by a URB_id
+ */
+/*****************************************************************************
+ *         cancle_urb                                                        *
+ ****************************************************************************/
+PRIVATE void cancle_urb(message *msg)
+{
+       endpoint_t ep = msg->m_source;
+
+       struct minix_usb_driver *drv;
+       
+       msg->USB_RESULT = -1;
+       msg->m_type = USB_REPLY;
+
+       /* find driver */
+       if ( (drv = find_driver(ep)) == NULL) {
+               DEBUG_MSG("Non-registered driver tries to cancel URB.");
+               return; 
+       } else {
+               struct ddekit_usb_urb *d_urb = NULL;
+               
+               d_urb = find_pending_urb(drv, msg->USB_URB_ID);
+
+               if (d_urb != NULL) {
+                       ddekit_usb_cancle_urb(d_urb);
+                       msg->USB_RESULT = 0;
+               } else {
+                       DEBUG_MSG("No URB to cancle");
+                       msg->USB_RESULT = ENODEV;
+               }
+       }
+       
+       send(ep, msg);
+}
+
+
+/*****************************************************************************
+ *         completion_callback                                               *
+ ****************************************************************************/
+PRIVATE void completion_callback(void *priv)
+{
+       /*
+        * completion_callback
+        *
+        * This is called by the DDE side. Here the data is copied back to 
+        * the driver and a message is send to inform the driver about the 
+        * completion.
+        */
+       message msg;
+       int res;
+       struct my_context *ctx       = (struct my_context *)priv;
+       struct usb_urb *mx_urb       = ctx->mx_urb;
+       struct ddekit_usb_urb *d_urb = ctx->d_urb;
+       struct minix_usb_driver *drv = ctx->drv;
+
+       DEBUG_MSG("ctx: %p, urb_id: %d, d_urb: %p, mx_urb: %p, drv: %d, gid: %d ",
+                   ctx, ctx->urb_id, ctx->d_urb, ctx->mx_urb, ctx->drv, ctx->gid);
+
+       /* update data in minix URB */
+       mx_urb->status          = d_urb->status;
+       mx_urb->actual_length   = d_urb->actual_length;
+       mx_urb->error_count     = d_urb->error_count; 
+       mx_urb->transfer_flags  = d_urb->transfer_flags;
+       
+       remove_from_pending_urbs(drv, d_urb);
+       
+       /* copy out URB */
+       res = sys_safecopyto(drv->ep, ctx->gid, 0,
+           (vir_bytes) ((char*)mx_urb) + sizeof(void*),
+               mx_urb->urb_size - sizeof(void*), D);
+
+       if (res != 0) {
+               DEBUG_MSG("Copy out failed: %d", res);
+               DEBUG_MSG(" URB ID: %d, Grant-ID: %d, Grant-size: %d", ctx->urb_id,
+                           ctx->gid, mx_urb->urb_size);
+       }
+
+       /* send message to client */
+       msg.m_type     = USB_COMPLETE_URB;
+       msg.USB_URB_ID = ctx->urb_id;
+       asynsend3(drv->ep, &msg, AMF_NOREPLY);
+       
+       /* free stuff */
+       my_free(ctx);
+       my_free(mx_urb);
+       my_free(d_urb);
+}
+
+
+/*****************************************************************************
+ *         prepare_devman_usbdev                                             *
+ ****************************************************************************/
+PRIVATE void prepare_devman_usbdev
+(struct ddekit_usb_dev * dev, int dev_id, unsigned int interfaces,
+ struct devman_usb_dev *dudev)
+{
+       int j; 
+       int intf_count;
+       /* 
+        * currently this is only implemented by stub driver
+        */
+       
+       usb_device_descriptor_t *desc = _ddekit_usb_get_device_desc(dev);
+       
+       dudev->manufacturer = _ddekit_usb_get_manufacturer(dev);
+       dudev->product = _ddekit_usb_get_product(dev);
+       dudev->serial = _ddekit_usb_get_serial(dev);
+
+       dudev->desc = desc;
+       
+       intf_count = 0;
+
+       for (j=0; j < 32; j++) {
+               if (interfaces & (1 << j)) {
+                               dudev->interfaces[intf_count++].desc =
+                                  _ddekit_usb_get_interface_desc(dev, j);
+               }
+       }
+       
+       dudev->intf_count = intf_count;
+       dudev->dev_id     = dev_id;
+}
+
+/*****************************************************************************
+ *         device_connect_callback                                           *
+ ****************************************************************************/
+PRIVATE void 
+device_connect_callback
+(struct ddekit_usb_dev * dev, unsigned int interfaces) {
+       
+       int i, res;
+
+       /* add to device list */
+       for (i=0; i < MAX_DEVS; i++) {
+               if (_devices[i].dev == NULL)
+                       break;
+       }
+
+       if (_devices[i].dev!= NULL) {
+               DEBUG_MSG("Too much devices...");
+       } else {
+               _devices[i].dev = dev;
+               _devices[i].interfaces = (1 << interfaces);
+       }
+
+       struct devman_usb_dev *dudev;
+
+       dudev = devman_usb_device_new(i);
+
+       prepare_devman_usbdev(dev, i, interfaces, dudev);
+       
+       if (dudev == NULL) {
+               /* TODO: ERROR */
+               printf("ERROR: !");
+       }
+
+       ddekit_usb_dev_set_data(dev, dudev);
+
+       res = devman_usb_device_add(dudev);
+       
+       if (res != 0) {
+               /* TODO: Error*/
+               printf("ERROR!");
+       }
+}
+
+/*****************************************************************************
+ *         device_disconnect_callback                                        *
+ ****************************************************************************/
+PRIVATE void device_disconnect_callback(struct ddekit_usb_dev * dev)
+{
+       int i;
+       
+       /* remove ACL entry */
+       for (i = 0; i< MAX_DRIVERS; i++) {
+               if (gbl_drivers[i].dev != INVAL_DEV
+                       && _devices[gbl_drivers[i].dev].dev == dev) {
+                       struct minix_usb_driver *drv = &gbl_drivers[i];
+                       drv->ep     = 0;
+                       drv->status = DRIVER_UNUSED;
+                       drv->dev    = INVAL_DEV;
+               }
+       }
+       
+       for (i=0; i < MAX_DEVS; i++) {
+               if (_devices[i].dev == dev) {
+                       _devices[i].dev = NULL;
+                       _devices[i].interfaces = 0;
+               }
+       }
+
+
+       /* get the devman device */
+       struct devman_usb_dev * dudev = NULL;
+
+       dudev = ddekit_usb_dev_get_data(dev);
+
+       if (dudev == NULL) {
+               /* TODO: error */
+       }
+
+       devman_usb_device_remove(dudev);
+
+       /* free the devman dev */
+       devman_usb_device_delete(dudev);
+}
+
+
+/*****************************************************************************
+ *         add_acl                                                           *
+ ****************************************************************************/
+PRIVATE int add_acl(int dev_id, unsigned interfaces, endpoint_t ep)
+{
+       /*
+        * This functions binds a specific USB interface to a client.
+        */
+       int i;
+       struct minix_usb_driver *drv;
+
+       if (_devices[dev_id].dev == NULL) {
+               /* if no device with that ID */
+               return  ENODEV;
+       } 
+       
+       /* is the device allready given to a client*/
+       for (i = 0; i< MAX_DRIVERS; i++) {
+               if (gbl_drivers[i].status != DRIVER_UNUSED &&
+                       gbl_drivers[i].dev == dev_id) {
+                       printf("devid: %d\n", dev_id);
+                       return EBUSY;
+               }
+       }
+       
+       /* bind device to client */
+       drv = find_unused_driver();
+
+       if (drv == NULL) {
+               return ENOMEM;
+       }
+       
+       drv->status     = DRIVER_BOUND;
+       drv->dev        = dev_id;
+       drv->interfaces = 1 << interfaces;
+       drv->ep         = ep;
+       drv->urb_id     = 0;
+
+       return OK;
+}
+
+/*****************************************************************************
+ *         del_acl                                                           *
+ ****************************************************************************/
+PRIVATE int del_acl(int dev_id, unsigned interfaces, endpoint_t ep)
+{
+       struct minix_usb_driver *drv;
+       int dev, withdraw = 0;
+       message msg;
+
+       /* find driver */
+       drv = find_driver(ep);
+       
+       if (drv == NULL) {
+               return  ENOENT;
+       }
+
+       dev = drv->dev;
+
+       if (drv->status == DRIVER_ACTIVE) {
+               withdraw = 1;
+       }
+
+       drv->ep    = 0;
+       drv->status = DRIVER_UNUSED;
+       drv->dev   = INVAL_DEV;
+       
+       if (withdraw) {
+               msg.m_type     = USB_WITHDRAW_DEV;
+               msg.USB_DEV_ID = dev;
+               asynsend3(ep, &msg, AMF_NOREPLY);
+       }
+
+       return 0;
+}
+
+/*****************************************************************************
+ *         handle_msg                                                        *
+ ****************************************************************************/
+PRIVATE int handle_msg(message *msg)
+{
+       /*
+        * handle_msg 
+        *
+        * The dispatcher for USB related messages.
+        */
+
+       switch(msg->m_type) {
+               case USB_RQ_INIT:
+                       register_driver(msg);
+                       return 1;
+               case USB_RQ_DEINIT:
+                       deregister_driver(msg);
+                       return 1;
+               case USB_RQ_SEND_URB:
+                       submit_urb(msg);
+                       return 1;
+               case USB_RQ_CANCEL_URB:
+                       cancle_urb(msg);
+                       return 1;
+               default:
+                       return 0;
+       }
+}
+
+/*****************************************************************************
+ *         devman_tread                                                      *
+ ****************************************************************************/
+PRIVATE void devman_thread(void *unused)
+{
+       struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(DEVMAN_BASE,
+           DEVMAN_BASE + 0xff);
+       
+       message m;
+       while (1) {
+               ddekit_minix_rcv(mq, &m);
+               devman_handle_msg(&m);
+       }
+}
+
+/*****************************************************************************
+ *         _ddekit_usb_thread                                                *
+ ****************************************************************************/
+PRIVATE void _ddekit_usb_thread(void * unused)
+{ 
+       struct ddekit_minix_msg_q *mq = ddekit_minix_create_msg_q(USB_BASE,
+           USB_BASE + 0xff);
+
+       message m;
+
+       /* create devman thread */
+       ddekit_thread_t * dmth;
+
+       dmth = ddekit_thread_create(devman_thread, NULL, "devman_thread");
+
+       while (1) {
+               ddekit_minix_rcv(mq, &m);
+               handle_msg(&m);
+       }
+}
+
+
+/*****************************************************************************
+ *         bind_cb                                                           *
+ ****************************************************************************/
+PRIVATE int bind_cb (struct devman_usb_bind_cb_data *data, endpoint_t ep)
+{
+       if(data) {
+               return add_acl(data->dev_id, data->interface, ep);
+       } else {
+               printf("warning: missing cb_data!\n");
+               return EINVAL;
+       }
+}
+
+/*****************************************************************************
+ *         unbind_cb                                                         *
+ ****************************************************************************/
+PRIVATE int unbind_cb (struct devman_usb_bind_cb_data *data, endpoint_t ep)
+{
+       if(data) {
+               return del_acl(data->dev_id, data->interface, ep);
+       } else {
+               printf("warning: missing cb_data!\n");
+               return EINVAL;
+       }
+}
+
+/*****************************************************************************
+ *         ddekit_usb_server_init                                            *
+ ****************************************************************************/
+PUBLIC void ddekit_usb_server_init()
+{
+       int i;
+       /*
+        * this function has to be called inside the context of an dedicated
+        * DDELinux thread
+        */
+       devman_usb_init(bind_cb, unbind_cb);    
+       ddekit_usb_init(&my_driver, &my_malloc, &my_free);
+       for (i = 0; i< MAX_DRIVERS; i++) {
+               gbl_drivers[i].dev = DRIVER_UNUSED;
+               gbl_drivers[i].dev = INVAL_DEV;
+       }
+       _ddekit_usb_thread(NULL);
+       
+}
diff --git a/lib/libddekit/src/util.h b/lib/libddekit/src/util.h
new file mode 100644 (file)
index 0000000..b003e19
--- /dev/null
@@ -0,0 +1,3 @@
+#include <ddekit/printf.h>
+
+#define WARN_UNIMPL ddekit_printf("WARNING: %s unimplemented!\n", __func__)
index cc337be9ae07a52c19d1e227b619a9cab81abfdc..52adbfffc79e2f2f4056d2739178333d6efa0fc1 100644 (file)
@@ -59,7 +59,7 @@ MKDEP_SUFFIXES?=      .o .ln
 #      rumpfs_tmpfs rumpfs_udf rumpfs_ufs
 .for _lib in \
        c curses driver netdriver edit end m sys timers util bz2 l hgfs \
-       audiodriver exec devman usb  
+       audiodriver exec ddekit devman usb  
 .ifndef LIB${_lib:tu}
 LIB${_lib:tu}= ${DESTDIR}/usr/lib/lib${_lib}.a
 .if ${COMPILER_TYPE} == "ack"