diff options
Diffstat (limited to 'usr.sbin/vmd/ns8250.c')
-rw-r--r-- | usr.sbin/vmd/ns8250.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/usr.sbin/vmd/ns8250.c b/usr.sbin/vmd/ns8250.c index 497e6fad550..44b7e20c5d1 100644 --- a/usr.sbin/vmd/ns8250.c +++ b/usr.sbin/vmd/ns8250.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ns8250.c,v 1.25 2019/12/11 06:45:16 pd Exp $ */ +/* $OpenBSD: ns8250.c,v 1.26 2020/06/16 06:23:51 pd Exp $ */ /* * Copyright (c) 2016 Mike Larkin <mlarkin@openbsd.org> * @@ -55,10 +55,13 @@ static void ratelimit(int fd, short type, void *arg) { /* Set TXRDY and clear "no pending interrupt" */ + mutex_lock(&com1_dev.mutex); com1_dev.regs.iir |= IIR_TXRDY; com1_dev.regs.iir &= ~IIR_NOPEND; + vcpu_assert_pic_irq(com1_dev.vmid, 0, com1_dev.irq); vcpu_deassert_pic_irq(com1_dev.vmid, 0, com1_dev.irq); + mutex_unlock(&com1_dev.mutex); } void @@ -130,21 +133,26 @@ com_rcv_event(int fd, short kind, void *arg) * has become available now will be moved to the com port later. */ if (com1_dev.rcv_pending) { - mutex_unlock(&com1_dev.mutex); - return; + goto end; } if (com1_dev.regs.lsr & LSR_RXRDY) com1_dev.rcv_pending = 1; else { com_rcv(&com1_dev, (uintptr_t)arg, 0); + } - /* If pending interrupt, inject */ - if ((com1_dev.regs.iir & IIR_NOPEND) == 0) { - /* XXX: vcpu_id */ - vcpu_assert_pic_irq((uintptr_t)arg, 0, com1_dev.irq); - vcpu_deassert_pic_irq((uintptr_t)arg, 0, com1_dev.irq); - } +end: + if (com1_dev.regs.ier & IER_ERXRDY) { + com1_dev.regs.iir |= IIR_RXRDY; + com1_dev.regs.iir &= ~IIR_NOPEND; + } + + /* If pending interrupt, inject */ + if ((com1_dev.regs.iir & IIR_NOPEND) == 0) { + /* XXX: vcpu_id */ + vcpu_assert_pic_irq((uintptr_t)arg, 0, com1_dev.irq); + vcpu_deassert_pic_irq((uintptr_t)arg, 0, com1_dev.irq); } mutex_unlock(&com1_dev.mutex); |