Made changes to map devices dynamically upon irq registration.

All will be reverted since mapping devices statically is much simpler.
This commit is contained in:
Bahadir Balban
2009-12-11 19:02:10 +02:00
parent 54301e8026
commit 59af5d3794
16 changed files with 248 additions and 64 deletions

View File

@@ -367,6 +367,16 @@ int cap_destroy(struct capability *cap)
if (!(cap_generic_perms(orig) & CAP_CHANGEABLE))
return -ENOCAP;
/*
* Check that it is not a device.
*
* We don't allow devices for now. To do this
* correctly, we need to check if device irq
* is not currently registered.
*/
if (cap_is_devmem(orig))
return -ENOCAP;
cap_list_remove(orig, clist);
free_capability(orig);
return 0;

View File

@@ -13,10 +13,9 @@
#include INC_GLUE(message.h)
#include <l4/lib/wait.h>
#if 0
/*
* Default function that handles userspace
* threaded irqs. Increases notification count and wakes
* threaded irqs. Increases irq count and wakes
* up any waiters.
*
* The increment is a standard read/update/write, and
@@ -36,36 +35,32 @@
*
* FIXME: Instead of UTCB, do it by incrementing a semaphore.
*/
int thread_notify_default(struct irq_desc *desc)
int irq_thread_notify(struct irq_desc *desc)
{
struct utcb *utcb;
int err;
/* Make sure irq thread's utcb is mapped */
if ((err = tcb_check_and_lazy_map_utcb(desc->irq_thread,
if ((err = tcb_check_and_lazy_map_utcb(desc->task,
0)) < 0) {
printk("%s: Irq occured but registered task's utcb "
"is inaccessible. task id=0x%x err=%d\n"
"is inaccessible without a page fault. "
"task id=0x%x err=%d\n"
"Destroying task.", __FUNCTION__,
desc->irq_thread->tid, err);
thread_destroy(desc->irq_thread);
desc->task->tid, err);
thread_destroy(desc->task);
/* FIXME: Deregister and disable irq as well */
}
/* Get thread's utcb */
utcb = (struct utcb *)desc->irq_thread->utcb_address;
utcb = (struct utcb *)desc->task->utcb_address;
/* Atomic increment (See above comments) with no wraparound */
if (utcb->notify[desc->task_notify_slot] != TASK_NOTIFY_MAX)
utcb->notify[desc->task_notify_slot]++;
/*
* Wake up any waiters
*
* NOTE: There's no contention on this queue, if there was,
* we would have to have spin_lock_irq()'s on the wakeup
*/
wake_up(&desc->irq_thread->wqh_notify, WAKEUP_ASYNC);
/* Async wake up any waiter irq threads */
wake_up(&desc->task->wqh_notify, WAKEUP_ASYNC | WAKEUP_IRQ);
return 0;
}
@@ -74,7 +69,9 @@ int thread_notify_default(struct irq_desc *desc)
* Register the given globally unique irq number with the
* current thread with given flags
*/
int irq_control_register(struct ktcb *task, int notify_slot, l4id_t irqnum)
int irq_control_register(struct ktcb *task, int slot, l4id_t irqnum,
unsigned long device_virtual,
struct capability *devcap)
{
int err;
@@ -89,9 +86,8 @@ int irq_control_register(struct ktcb *task, int notify_slot, l4id_t irqnum)
if ((err = tcb_check_and_lazy_map_utcb(current, 1)) < 0)
return err;
/* Register the irq and thread notification handler */
if ((err = irq_register(current, notify_slot, irqnum,
thread_notify_default)) < 0)
/* Register the irq for thread notification */
if ((err = irq_register(current, slot, irqnum, devcap)) < 0)
return err;
return 0;
@@ -101,31 +97,24 @@ int irq_control_register(struct ktcb *task, int notify_slot, l4id_t irqnum)
* Register/deregister device irqs. Optional synchronous and
* asynchronous irq handling.
*/
int sys_irq_control(unsigned int req, int slot, unsigned int flags, l4id_t irqno)
int sys_irq_control(unsigned int req, unsigned int flags, l4id_t irqno)
{
/* Currently a task is allowed to register only for itself */
struct ktcb *task = current;
struct capability *devcap;
int err;
if ((err = cap_irq_check(task, req, flags, irqno)) < 0)
if ((err = cap_irq_check(task, req, flags, irqno, &devcap)) < 0)
return err;
switch (req) {
case IRQ_CONTROL_REGISTER:
irq_control_register(task, flags, irqno);
if ((err = irq_control_register(task, slot, flags,
irqno, devcap)) < 0)
return err;
default:
return -EINVAL;
}
return 0;
}
#endif
/*
* Register/deregister device irqs. Optional synchronous and
* asynchronous irq handling.
*/
int sys_irq_control(unsigned int req, int slot, unsigned int flags, l4id_t irqno)
{
return 0;
}