Port-arm archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: pic/arm lost blocked irqs
Hi! Adam,
From: KIYOHARA Takashi <kiyohara%kk.iij4u.or.jp@localhost>
Date: Mon, 30 Aug 2010 21:25:31 +0900 (JST)
> From: Adam Hoka <adam.hoka%gmail.com@localhost>
> Date: Mon, 30 Aug 2010 13:48:10 +0200
>
> > i saw hangups in interrupt handling too with the dm9000 driver
> > i have tried to port. maybe it wasnt my mistake then?
>
> That patch of me fixes a bug. However, I happen another bug, too.
> For instance, can you type your keyboard on tip(1)(or cu(1)) of Host
> toward the console of your devkit9000?
>
> My smsh(4) works again with typing keyboard.
Maybe, it is this. ;-)
arm/pic/pic.c:pic_deliver_irqs() --
for (;;) {
pending_irqs = pic_find_pending_irqs_by_ipl(pic, irq_base,
*ipending, ipl);
:
if (pending_irqs == 0) {
irq_count += 32;
if (__predict_true(irq_count >= pic->pic_maxsources))
break;
:
}
:
do {
:
pending_irqs = pic_find_pending_irqs_by_ipl(pic,
irq_base, *ipending, ipl);
} while (pending_irqs);
:
}
:
if (atomic_and_32_nv(&pic->pic_pending_ipls, ~ipl_mask) == 0)
atomic_and_32(&pic_pending_pics, ~__BIT(pic->pic_id));
com uses intr-74 and gpio uses intr between 29 and 34, both IPL_HIGH
(IPL_SERIAL). If gpio interrupts in comintr(intr 74), pic_pending_pics
is cleared, and ipending not cleared.
Index: pic.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/pic/pic.c,v
retrieving revision 1.4
diff -u -r1.4 pic.c
--- pic.c 30 Dec 2008 05:43:14 -0000 1.4
+++ pic.c 30 Aug 2010 13:29:23 -0000
@@ -196,7 +196,7 @@
#endif
uint32_t pending_irqs;
uint32_t blocked_irqs;
- int irq;
+ int irq, dispatched;
bool progress = false;
KASSERT(pic->pic_pending_ipls & ipl_mask);
@@ -206,6 +206,7 @@
irq_count = 0;
#endif
+ dispatched = 0;
for (;;) {
pending_irqs = pic_find_pending_irqs_by_ipl(pic, irq_base,
*ipending, ipl);
@@ -214,14 +215,19 @@
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 (!dispatched)
+ break;
+ irq_base = 0;
+ irq_count = 0;
+ dispatched = 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
@@ -251,6 +257,7 @@
atomic_or_32(iblocked, blocked_irqs);
atomic_or_32(&pic_blocked_pics, __BIT(pic->pic_id));
}
+ dispatched = 1;
}
KASSERT(progress);
In my case, this fix clear that problem. ;-)
Thanks,
--
kiyohara
Home |
Main Index |
Thread Index |
Old Index