Fix lost interrupt. (2/2)
+ It is likely to lose sight of interrupt when the interrupt of irq_base that is smaller than the same at the level is generated if PIC_MAXSOURCES is 33 or more.
This commit is contained in:
parent
4edbb19773
commit
8e229474be
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pic.c,v 1.5 2010/08/31 14:23:27 kiyohara Exp $ */
|
||||
/* $NetBSD: pic.c,v 1.6 2010/08/31 14:33:41 kiyohara Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
|
@ -28,7 +28,7 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.5 2010/08/31 14:23:27 kiyohara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.6 2010/08/31 14:33:41 kiyohara Exp $");
|
||||
|
||||
#define _INTR_PRIVATE
|
||||
#include <sys/param.h>
|
||||
|
@ -193,6 +193,7 @@ pic_deliver_irqs(struct pic_softc *pic, int ipl, void *frame)
|
|||
size_t irq_base;
|
||||
#if PIC_MAXSOURCES > 32
|
||||
size_t irq_count;
|
||||
int poi = 0; /* Possibility of interrupting */
|
||||
#endif
|
||||
uint32_t pending_irqs;
|
||||
uint32_t blocked_irqs;
|
||||
|
@ -214,14 +215,20 @@ pic_deliver_irqs(struct pic_softc *pic, int ipl, void *frame)
|
|||
if (pending_irqs == 0) {
|
||||
#if PIC_MAXSOURCES > 32
|
||||
irq_count += 32;
|
||||
if (__predict_true(irq_count >= pic->pic_maxsources))
|
||||
break;
|
||||
irq_base += 32;
|
||||
ipending++;
|
||||
iblocked++;
|
||||
if (irq_base >= pic->pic_maxsources) {
|
||||
if (__predict_true(irq_count >= pic->pic_maxsources)) {
|
||||
if (!poi)
|
||||
/*Interrupt at this level was handled.*/
|
||||
break;
|
||||
irq_base = 0;
|
||||
irq_count = 0;
|
||||
poi = 0;
|
||||
ipending = pic->pic_pending_irqs;
|
||||
iblocked = pic->pic_blocked_irqs;
|
||||
} else {
|
||||
irq_base += 32;
|
||||
ipending++;
|
||||
iblocked++;
|
||||
KASSERT(irq_base <= pic->pic_maxsources);
|
||||
}
|
||||
continue;
|
||||
#else
|
||||
|
@ -240,6 +247,13 @@ pic_deliver_irqs(struct pic_softc *pic, int ipl, void *frame)
|
|||
cpsie(I32_bit);
|
||||
pic_dispatch(is, frame);
|
||||
cpsid(I32_bit);
|
||||
#if PIC_MAXSOURCES > 32
|
||||
/*
|
||||
* There is a possibility of interrupting
|
||||
* from cpsie() to cpsid().
|
||||
*/
|
||||
poi = 1;
|
||||
#endif
|
||||
blocked_irqs |= __BIT(irq);
|
||||
} else {
|
||||
KASSERT(0);
|
||||
|
|
Loading…
Reference in New Issue