Subversion Repositories shark

Compare Revisions

Regard whitespace Rev 780 → Rev 847

/shark/trunk/drivers/linuxc26/linux_kthread.c
0,0 → 1,35
#include <kernel/func.h>
 
extern int exec_shadow;
 
PID kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
PID p;
SOFT_TASK_MODEL m;
 
soft_task_default_model(m);
soft_task_def_arg(m,(void*)arg);
soft_task_def_met(m, 5000);
soft_task_def_wcet(m, 5000);
soft_task_def_period(m, 25000);
soft_task_def_ctrl_jet(m);
soft_task_def_aperiodic(m);
soft_task_def_usemath(m);
 
p= task_create("linux26", (void*)fn, &m, NULL);
if (p >0) task_activate(p);
 
return p;
}
 
int kill_proc(pid_t pid, int sig, int priv)
{
task_kill(pid);
 
return 0;
}
 
void schedule(void)
{
task_endcycle();
}
/shark/trunk/drivers/linuxc26/include/linux/device.h
393,6 → 393,8
#define dev_dbg(dev, format, arg...) do {} while (0)
#endif
 
#ifdef DEBUG //** for shark usb
 
#define dev_err(dev, format, arg...) \
dev_printk(KERN_ERR , dev , format , ## arg)
#define dev_info(dev, format, arg...) \
400,6 → 402,14
#define dev_warn(dev, format, arg...) \
dev_printk(KERN_WARNING , dev , format , ## arg)
 
#else
 
#define dev_err(dev, format, arg...)
#define dev_info(dev, format, arg...)
#define dev_warn(dev, format, arg...)
 
#endif
 
/* Create alias, so I can be autoloaded. */
#define MODULE_ALIAS_CHARDEV(major,minor) \
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
/shark/trunk/drivers/linuxc26/include/linux/kernel.h
57,10 → 57,8
extern struct notifier_block *panic_notifier_list;
void panic(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2)));
asmlinkage NORET_TYPE void do_exit(long error_code)
ATTRIB_NORET;
NORET_TYPE void complete_and_exit(struct completion *, long)
ATTRIB_NORET;
void do_exit(long error_code);
void complete_and_exit(struct completion *, long);
extern int abs(int);
extern unsigned long simple_strtoul(const char *,char **,unsigned int);
extern long simple_strtol(const char *,char **,unsigned int);
/shark/trunk/drivers/linuxc26/include/linux/usb.h
19,16 → 19,18
#include <linux/completion.h> /* for struct completion */
#include <linux/sched.h> /* for current && schedule_timeout */
 
extern int wait_ms26(unsigned long timeout);
 
static __inline__ void wait_ms(unsigned int ms)
{
if(!in_interrupt()) {
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(1 + ms * HZ / 1000);
wait_ms26(ms);
// if(!in_interrupt()) {
// current->state = TASK_UNINTERRUPTIBLE;
// schedule_timeout(1 + ms * HZ / 1000);
// }
// else
// mdelay(ms);
}
else
mdelay(ms);
}
 
struct usb_device;
 
326,7 → 328,7
static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
{
int actual;
actual = snprintf (buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
actual = snprintf26(buf, size, "usb-%s-%s", dev->bus->bus_name, dev->devpath);
return (actual >= (int)size) ? -1 : actual;
}
 
1038,11 → 1040,16
#define dbg(format, arg...) do {} while (0)
#endif
 
#ifdef DEBUG
#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg)
#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg)
#else
#define err(format, arg...)
#define info(format, arg...)
#define warn(format, arg...)
#endif
 
 
#endif /* __KERNEL__ */
 
#endif
/shark/trunk/drivers/linuxc26/include/linux/wait.h
78,9 → 78,12
list_add_tail(&new->task_list, &head->task_list);
}
 
 
extern void free(void *ptr);
static inline void __remove_wait_queue(wait_queue_head_t *head,
wait_queue_t *old)
{
free(old->task); //** SHARK
list_del(&old->task_list);
}
 
/shark/trunk/drivers/linuxc26/include/linux/sched.h
836,7 → 836,7
 
static inline int signal_pending(struct task_struct *p)
{
return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
return 0; //**unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
}
static inline int need_resched(void)
/shark/trunk/drivers/linuxc26/include/asm/current.h
4,10 → 4,12
#include <linux/thread_info.h>
 
struct task_struct;
extern struct task_struct * get_current26(void);
 
static inline struct task_struct * get_current(void)
{
return current_thread_info()->task;
// printk(KERN_DEBUG "File: %s @get_current\n", __FILE__);
return get_current26();
}
#define current get_current()
/shark/trunk/drivers/linuxc26/include/asm/semaphore.h
5,212 → 5,64
 
#ifdef __KERNEL__
 
/*
* SMP- and interrupt-safe semaphores..
*
* (C) Copyright 1996 Linus Torvalds
*
* Modified 1996-12-23 by Dave Grothe <dave@gcom.com> to fix bugs in
* the original code and to make semaphore waits
* interruptible so that processes waiting on
* semaphores can be killed.
* Modified 1999-02-14 by Andrea Arcangeli, split the sched.c helper
* functions in asm/sempahore-helper.h while fixing a
* potential and subtle race discovered by Ulrich Schmid
* in down_interruptible(). Since I started to play here I
* also implemented the `trylock' semaphore operation.
* 1999-07-02 Artur Skawina <skawina@geocities.com>
* Optimized "0(ecx)" -> "(ecx)" (the assembler does not
* do this). Changed calling sequences from push/jmp to
* traditional call/ret.
* Modified 2001-01-01 Andreas Franck <afranck@gmx.de>
* Some hacks to ensure compatibility with recent
* GCC snapshots, to avoid stack corruption when compiling
* with -fomit-frame-pointer. It's not sure if this will
* be fixed in GCC, as our previous implementation was a
* bit dubious.
*
* If you would like to see an analysis of this implementation, please
* ftp to gcom.com and download the file
* /pub/linux/src/semaphore/semaphore-2.0.24.tar.gz.
*
*/
 
#include <asm/system.h>
#include <asm/atomic.h>
#include <linux/wait.h>
#include <linux/rwsem.h>
 
typedef int sem_t; /* sem.h */
int sem_wait(sem_t *sem);
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_post(sem_t *sem);
int sem_trywait(sem_t *s);
 
struct semaphore {
atomic_t count;
int sleepers;
wait_queue_head_t wait;
#ifdef WAITQUEUE_DEBUG
long __magic;
#endif
int init;
int start_value;
sem_t shark_sem;
};
 
#ifdef WAITQUEUE_DEBUG
# define __SEM_DEBUG_INIT(name) \
, (int)&(name).__magic
#else
# define __SEM_DEBUG_INIT(name)
#endif
#define DECLARE_MUTEX(name) struct semaphore name = { .init=0, .start_value=1}
#define DECLARE_MUTEX_LOCKED(name) struct semaphore name= { .init=0, .start_value=0}
 
#define __SEMAPHORE_INITIALIZER(name,count) \
{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
__SEM_DEBUG_INIT(name) }
static inline void down(struct semaphore * sem)
{
/* if (sem->init == 0)
{
sem_init(&sem->shark_sem, 0, sem->start_value);
sem->init = 1;
}
sem_wait(&sem->shark_sem);
*/
}
 
#define __MUTEX_INITIALIZER(name) \
__SEMAPHORE_INITIALIZER(name,1)
 
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
 
static inline void sema_init (struct semaphore *sem, int val)
static inline void up(struct semaphore * sem)
{
/*
* *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
*
* i'd rather use the more flexible initialization above, but sadly
* GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
sem_post(&sem->shark_sem);
*/
atomic_set(&sem->count, val);
sem->sleepers = 0;
init_waitqueue_head(&sem->wait);
#ifdef WAITQUEUE_DEBUG
sem->__magic = (int)&sem->__magic;
#endif
}
 
static inline void init_MUTEX (struct semaphore *sem)
{
sema_init(sem, 1);
/*
sem_init(&sem->shark_sem, 0, 1);
*/
}
 
static inline void init_MUTEX_LOCKED (struct semaphore *sem)
{
sema_init(sem, 0);
}
 
asmlinkage void __down_failed(void /* special register calling convention */);
asmlinkage int __down_failed_interruptible(void /* params in registers */);
asmlinkage int __down_failed_trylock(void /* params in registers */);
asmlinkage void __up_wakeup(void /* special register calling convention */);
 
asmlinkage void __down(struct semaphore * sem);
asmlinkage int __down_interruptible(struct semaphore * sem);
asmlinkage int __down_trylock(struct semaphore * sem);
asmlinkage void __up(struct semaphore * sem);
 
/*
* This is ugly, but we want the default case to fall through.
* "__down_failed" is a special asm handler that calls the C
* routine that actually waits. See arch/i386/kernel/semaphore.c
sem_init(&sem->shark_sem, 0, 0);
*/
static inline void down(struct semaphore * sem)
{
#ifdef WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
might_sleep();
__asm__ __volatile__(
"# atomic down operation\n\t"
LOCK "decl %0\n\t" /* --sem->count */
"js 2f\n"
"1:\n"
LOCK_SECTION_START("")
"2:\tcall __down_failed\n\t"
"jmp 1b\n"
LOCK_SECTION_END
:"=m" (sem->count)
:"c" (sem)
:"memory");
}
 
/*
* Interruptible try to acquire a semaphore. If we obtained
* it, return zero. If we were interrupted, returns -EINTR
*/
static inline int down_interruptible(struct semaphore * sem)
{
int result;
 
#ifdef WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
might_sleep();
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
LOCK "decl %1\n\t" /* --sem->count */
"js 2f\n\t"
"xorl %0,%0\n"
"1:\n"
LOCK_SECTION_START("")
"2:\tcall __down_failed_interruptible\n\t"
"jmp 1b\n"
LOCK_SECTION_END
:"=a" (result), "=m" (sem->count)
:"c" (sem)
:"memory");
return result;
}
 
/*
* Non-blockingly attempt to down() a semaphore.
* Returns zero if we acquired it
*/
static inline int down_trylock(struct semaphore * sem)
{
int result;
 
#ifdef WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
 
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
LOCK "decl %1\n\t" /* --sem->count */
"js 2f\n\t"
"xorl %0,%0\n"
"1:\n"
LOCK_SECTION_START("")
"2:\tcall __down_failed_trylock\n\t"
"jmp 1b\n"
LOCK_SECTION_END
:"=a" (result), "=m" (sem->count)
:"c" (sem)
:"memory");
return result;
}
 
return 0;
/*
* Note! This is subtle. We jump to wake people up only if
* the semaphore was negative (== somebody was waiting on it).
* The default case (no contention) will result in NO
* jumps for both down() and up().
return ( sem_trywait(&sem->shark_sem) );
*/
static inline void up(struct semaphore * sem)
{
#ifdef WAITQUEUE_DEBUG
CHECK_MAGIC(sem->__magic);
#endif
__asm__ __volatile__(
"# atomic up operation\n\t"
LOCK "incl %0\n\t" /* ++sem->count */
"jle 2f\n"
"1:\n"
LOCK_SECTION_START("")
"2:\tcall __up_wakeup\n\t"
"jmp 1b\n"
LOCK_SECTION_END
".subsection 0\n"
:"=m" (sem->count)
:"c" (sem)
:"memory");
}
 
#endif
/shark/trunk/drivers/linuxc26/waitqueue.c
0,0 → 1,115
#include <linuxcomp.h>
#include <linux/wait.h>
#include <linux/config.h>
#include <linux/list.h>
 
#include <kernel/types.h>
 
extern int task_activate(PID pid);
extern int exec_shadow;
 
struct task_struct {
PID pid;
int state;
char comm[1024];
};
 
typedef struct task_struct task_t;
 
inline void init_waitqueue_head(wait_queue_head_t *q)
{
q->lock = SPIN_LOCK_UNLOCKED;
INIT_LIST_HEAD(&q->task_list);
}
 
static int try_to_wake_up(task_t * p, unsigned int state, int sync)
{
task_activate(p->pid);
return 0;
}
 
int default_wake_function(wait_queue_t *curr, unsigned mode, int sync)
{
task_t *p = curr->task;
return try_to_wake_up(p, mode, sync);
}
 
void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, int sync)
{
struct list_head *tmp, *next;
 
list_for_each_safe(tmp, next, &q->task_list) {
wait_queue_t *curr;
unsigned flags;
curr = list_entry(tmp, wait_queue_t, task_list);
flags = curr->flags;
curr->func(curr, mode, sync);
}
 
}
 
void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
{
unsigned long flags;
 
spin_lock_irqsave(&q->lock, flags);
__wake_up_common(q, mode, nr_exclusive, 0);
spin_unlock_irqrestore(&q->lock, flags);
}
 
inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
list_add(&new->task_list, &head->task_list);
}
 
void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
{
unsigned long flags;
 
wait->flags &= ~WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
__add_wait_queue(q, wait);
spin_unlock_irqrestore(&q->lock, flags);
}
 
void remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
{
unsigned long flags;
 
spin_lock_irqsave(&q->lock, flags);
__remove_wait_queue(q, wait);
spin_unlock_irqrestore(&q->lock, flags);
}
 
inline int waitqueue_active(wait_queue_head_t *q)
{
return !list_empty(&q->task_list);
}
 
inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
{
q->flags = 0;
q->task = p;
q->func = default_wake_function;
}
 
extern void * malloc(size_t size);
 
struct task_struct * get_current26(void)
{
struct task_struct *tsp;
tsp = malloc(sizeof(struct task_struct));
if (!tsp)
{
printk(KERN_DEBUG "@get_current26 out of memory!!!\n");
//
// sys_abort?
//
}
tsp->pid = exec_shadow;
 
// printk(KERN_DEBUG "File: %s Pid=%d\n", __FILE__, tsp->pid);
return tsp;
}
/shark/trunk/drivers/linuxc26/vsprintf.c
743,3 → 743,27
}
 
EXPORT_SYMBOL(sscanf26);
 
/**
* strlcpy - Copy a %NUL terminated string into a sized buffer
* @dest: Where to copy the string to
* @src: Where to copy the string from
* @size: size of destination buffer
*
* Compatible with *BSD: the result is always a valid
* NUL-terminated string that fits in the buffer (unless,
* of course, the buffer size is zero). It does not pad
* out the result like strncpy() does.
*/
size_t strlcpy(char *dest, const char *src, size_t size)
{
size_t ret = strlen(src);
if (size) {
size_t len = (ret >= size) ? size-1 : ret;
memcpy(dest, src, len);
dest[len] = '\0';
}
return ret;
}
EXPORT_SYMBOL(strlcpy);
/shark/trunk/drivers/linuxc26/linuxcomp.c
322,14 → 322,37
vfree((void *)dma_handle);
}
 
extern void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, int sync);
 
void init_completion(struct completion *x) {
x->done = 0;
init_waitqueue_head(&x->wait);
}
 
void complete(struct completion *c) {
void complete(struct completion *x)
{
x->done++;
__wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, 0);
}
 
void wait_for_completion(struct completion *c) {
void wait_for_completion(struct completion *x) {
spin_lock_irq(&x->wait.lock);
if (!x->done) {
DECLARE_WAITQUEUE(wait, current);
 
wait.flags |= WQ_FLAG_EXCLUSIVE;
__add_wait_queue_tail(&x->wait, &wait);
do {
__set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(&x->wait.lock);
schedule();
spin_lock_irq(&x->wait.lock);
} while (!x->done);
__remove_wait_queue(&x->wait, &wait);
}
x->done--;
spin_unlock_irq(&x->wait.lock);
}
 
struct device legacy_bus = {
.bus_id = "legacy",
365,31 → 388,21
 
}
 
void *kern_alloc_aligned(size_t size, DWORD flags,
int align_bits, DWORD align_ofs);
 
void * vmalloc_32(size_t size)
{
void *mem;
unsigned long diff;
mem = malloc(size+12);
mem = kern_alloc_aligned(size, 0, 12, 0);
diff = (unsigned long)((((unsigned long)mem/4)+1)*4-(unsigned long)mem);
return mem;
*(unsigned long *)(mem+diff) = (diff | 0x80000000);
 
return (mem+diff+4);
}
 
void vfree(void *addr) {
 
if (addr == NULL || *(unsigned long *)(addr-4) == 0) return;
 
if ((*(unsigned long *)(addr-4) & 0x80000000) == 0x80000000) {
free(addr-(*(unsigned long *)(addr-4) & 0x7FFFFFFF)-4);
*(unsigned long *)(addr-4) = 0;
return;
}
 
free(addr);
 
return;
418,3 → 431,43
return 0;
 
}
 
struct page *mem_map = 0x0000;
 
int schedule_work(struct work_struct *work) { return 0;}
void flush_scheduled_work(void) { }
void daemonize(const char *name, ...) { }
int allow_signal(int sig) {return 0; }
void yield(void) { }
 
void do_exit(long code) { }
void complete_and_exit(struct completion *comp, long code)
{
if (comp)
complete(comp);
do_exit(code);
}
 
inline void * ioremap_nocache(unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
 
 
#define NULL_TIMESPEC(t) ((t)->tv_sec = (t)->tv_nsec = 0)
 
int wait_ms26(unsigned long msec)
{
struct timespec t1, t2;
int nsec;
 
t1.tv_sec = msec/1000;
nsec = (msec % 1000) * 1000000;
t1.tv_nsec = nsec;
NULL_TIMESPEC(&t2);
nanosleep(&t1, &t2);
 
return 0;
}
 
/shark/trunk/drivers/linuxc26/int.c
6,8 → 6,34
 
extern void *int_arg_table[MAX_INT_TABLE];
extern void *int_func_table[MAX_INT_TABLE];
int intr_count = 0;
 
#define MAX_IRQS 16
 
#ifndef NIL
#define NIL -1 /*+ integer unvalid value +*/
#endif
 
struct int_handler {
void (*func)(int, void *dev_id, struct pt_regs *);
void *data;
int flags;
struct int_handler *next;
};
 
static struct irq_handler_list {
struct int_handler *handlers;
} irq_list[MAX_IRQS];
 
void init_linux_irq();
extern void fast_call_intr(int no);
extern void* malloc(int size);
extern void free(void *ptr);
extern int handler_set(int no, void (*fast)(int), int pi, BYTE lock);
extern int handler_remove(int no);
 
unsigned long intr_count = 0;
static int init = 0;
 
/*
* Generic Linux interrupt handler.
*/
14,31 → 40,100
void linux_intr(int irq)
{
struct pt_regs regs;
struct int_handler *ihp;
// irq_mask(irq);
 
intr_count++;
if (int_func_table[irq] != NULL)
(* (void (*)(int, void *dev_id, struct pt_regs *))int_func_table[irq])(irq, int_arg_table[irq], &regs);
ihp=irq_list[irq].handlers;
while (ihp) {
(*ihp->func)(irq, ihp->data, &regs);
ihp=ihp->next;
}
intr_count--;
// irq_unmask(irq);
}
 
void add_list(struct int_handler** headp, struct int_handler *ihp)
{
if (*headp == NULL) {
*headp=ihp;
return;
}
ihp->next=*headp;
*headp=ihp;
}
 
#define USE_IRQ_SERVER
 
/*
* Attach a handler to an IRQ.
*/
int request_irq(unsigned int irq, void (*handler)(int, void *dev_id, struct pt_regs *), unsigned long flags, const char *device, void *dev_id)
{
shark_handler_set(irq, (void *)(handler), dev_id);
struct int_handler *ihp;
 
if (init == 0)
init_linux_irq();
 
ihp=malloc(sizeof(struct int_handler));
if (ihp == NULL)
return -ENOMEM;
 
if (irq_list[irq].handlers == NULL)
{
//* Warning: check if irq is used from somebody that doesn't share!
#ifdef USE_IRQ_SERVER
shark_handler_set(irq, NULL, NULL);
#else
handler_set(irq, linux_intr, NIL, TRUE);
#endif
}
ihp->func = handler;
ihp->flags = flags;
ihp->data = dev_id;
ihp->next = NULL;
add_list(&irq_list[irq].handlers, ihp);
 
return 0;
}
 
/*
* Deallocate an irq.
* Deallocate an irq
*/
void free_irq(unsigned int irq, void *a)
void free_irq(unsigned int irq, void *dev_id)
{
struct int_handler **headp, *ihp;
 
shark_handler_remove(irq);
headp=&irq_list[irq].handlers;
while (*headp)
{
ihp=*headp;
if (ihp->data == dev_id)
{
*headp=ihp->next;
free(ihp);
break;
}
headp=&ihp->next;
}
 
if (irq_list[irq].handlers == NULL)
{
handler_remove(irq);
}
}
 
void init_linux_irq()
{
int i;
 
for (i=0; i<MAX_IRQS; i++)
{
irq_list[i].handlers = NULL;
}
init=1;
}
/shark/trunk/drivers/linuxc26/makefile
11,7 → 11,7
OBJS_PATH = $(BASE)/drivers/linuxc26
 
OBJS = bus.o linuxcomp.o core.o driver.o vsprintf.o interface.o kobject.o\
shark_linuxc26.o shark_glue.o class.o videodev.o\
shark_linuxc26.o shark_glue.o class.o videodev.o linux_kthread.o waitqueue.o\
int.o timer.o cmdline.o video-buf.o shark_videodev.o
 
C_OPT += -I../linuxc26/include