Subversion Repositories HelenOS

Rev

Rev 2131 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2131 Rev 2456
Line 49... Line 49...
49
#include <console/console.h>
49
#include <console/console.h>
50
#include <interrupt.h>
50
#include <interrupt.h>
51
#include <arch/interrupt.h>
51
#include <arch/interrupt.h>
52
#include <sysinfo/sysinfo.h>
52
#include <sysinfo/sysinfo.h>
53
#include <synch/spinlock.h>
53
#include <synch/spinlock.h>
-
 
54
#include <synch/rcu.h>
54
 
55
 
55
#define LSR_DATA_READY  0x01
56
#define LSR_DATA_READY  0x01
56
 
57
 
57
/** Structure representing the ns16550. */
58
/** Structure representing the ns16550. */
58
static ns16550_t ns16550;
59
static ns16550_t ns16550;
Line 84... Line 85...
84
    ns16550_ier_write(&ns16550, IER_ERBFI);     /* enable receiver interrupt */
85
    ns16550_ier_write(&ns16550, IER_ERBFI);     /* enable receiver interrupt */
85
   
86
   
86
    while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY)
87
    while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY)
87
        (void) ns16550_rbr_read(&ns16550);
88
        (void) ns16550_rbr_read(&ns16550);
88
 
89
 
89
    spinlock_lock(&ns16550_irq.lock);
90
    //rcu_read_lock() is not needed, ints are disabled
90
    ns16550_irq.notif_cfg.notify = false;
91
    //rcu: atomic update doesn't need reallocation  
91
    spinlock_unlock(&ns16550_irq.lock);
92
    rcu_dereference_pointer(ns16550_irq.notif_cfg).notify = false;
92
    interrupts_restore(ipl);
93
    interrupts_restore(ipl);
93
}
94
}
94
 
95
 
95
/** Resume the former interrupt vector */
96
/** Resume the former interrupt vector */
96
void ns16550_release(void)
97
void ns16550_release(void)
97
{
98
{
98
    ipl_t ipl = interrupts_disable();
99
    ipl_t ipl = interrupts_disable();
-
 
100
    //rcu: atomic update doesn't need reallocation
99
    spinlock_lock(&ns16550_irq.lock);
101
    spinlock_lock(&ns16550_irq.lock);
100
    if (ns16550_irq.notif_cfg.answerbox)
102
    if (rcu_dereference_pointer(ns16550_irq.notif_cfg).answerbox)
101
        ns16550_irq.notif_cfg.notify = true;
103
        rcu_dereference_pointer(ns16550_irq.notif_cfg).notify = true;
102
    spinlock_unlock(&ns16550_irq.lock);
104
    spinlock_unlock(&ns16550_irq.lock);
103
    interrupts_restore(ipl);
105
    interrupts_restore(ipl);
104
}
106
}
105
 
107
 
106
/** Initialize ns16550.
108
/** Initialize ns16550.
Line 181... Line 183...
181
 
183
 
182
    ipl = interrupts_disable();
184
    ipl = interrupts_disable();
183
    spinlock_lock(&ns16550_irq.lock);
185
    spinlock_lock(&ns16550_irq.lock);
184
 
186
 
185
    if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
187
    if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
186
        if (ns16550_irq.notif_cfg.notify && ns16550_irq.notif_cfg.answerbox) {
188
        if (rcu_dereference_pointer(ns16550_irq.notif_cfg).notify && rcu_dereference_pointer(ns16550_irq.notif_cfg).answerbox) {
187
            /*
189
            /*
188
             * Send IPC notification.
190
             * Send IPC notification.
189
             */
191
             */
190
            ipc_irq_send_notif(&ns16550_irq);
192
            ipc_irq_send_notif(&ns16550_irq);
191
            spinlock_unlock(&ns16550_irq.lock);
193
            spinlock_unlock(&ns16550_irq.lock);