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