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
--- /dev/null
+
+.if ${COMPILER_TYPE} == "gnu"
+SUBDIR = build
+.endif
+
+.include <bsd.subdir.mk>
--- /dev/null
+.if ${COMPILER_TYPE} == "gnu"
+SUBDIR = ddekit ddekit_usb_client ddekit_usb_server
+.endif
+.include <bsd.subdir.mk>
+
+
--- /dev/null
+.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>
+
--- /dev/null
+.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>
+
--- /dev/null
+.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>
+
+
--- /dev/null
+#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>
--- /dev/null
+#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();
+}
+
--- /dev/null
+#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);
+}
+
--- /dev/null
+#ifndef DDEKIT_DEBUG_MACROS_H
+#define DDEKIT_DEBUG_MACROS_H
+
+#include <ddekit/printf.h>
+#include <ddekit/debug.h>
+
+#endif /* DDEKIT_DEBUG_MACROS_H */
--- /dev/null
+#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();
+ }
+}
--- /dev/null
+#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);
+ }
+}
+
+
--- /dev/null
+#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
--- /dev/null
+#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);
+}
+
--- /dev/null
+#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);
+}
--- /dev/null
+#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);
+}
--- /dev/null
+#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);
+}
--- /dev/null
+/**
+ * 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;
+}
+
--- /dev/null
+/*
+ * @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);
+}
+
--- /dev/null
+#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);
+}
--- /dev/null
+#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);
+}
+
+
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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");
+}
--- /dev/null
+#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
--- /dev/null
+#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();
+}
--- /dev/null
+#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
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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);
+
+}
--- /dev/null
+#include <ddekit/printf.h>
+
+#define WARN_UNIMPL ddekit_printf("WARNING: %s unimplemented!\n", __func__)
# 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"