summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2011-01-01 16:33:38 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2011-01-01 16:33:38 +0000
commit6380bedcf96c3033168c2098f2d81a055e09da54 (patch)
tree4f9055026d077c0ac632bb9d844171e6d768548e /sys
parent6582538860125c50966502d7ee7d6d6a351d639f (diff)
Fix horribly broken softintr_establish(). The old code was not managing the
linked list of handlers properly. Fixes issues with usb(4) reported by matthieu@. tested by matthieu@, ok jsing@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/hppa/hppa/intr.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/sys/arch/hppa/hppa/intr.c b/sys/arch/hppa/hppa/intr.c
index 292f2467835..4cf7ad594f4 100644
--- a/sys/arch/hppa/hppa/intr.c
+++ b/sys/arch/hppa/hppa/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.36 2010/12/21 14:56:23 claudio Exp $ */
+/* $OpenBSD: intr.c,v 1.37 2011/01/01 16:33:37 kettenis Exp $ */
/*
* Copyright (c) 2002-2004 Michael Shalayeff
@@ -358,22 +358,27 @@ softintr_establish(int pri, void (*handler)(void *), void *arg)
return (NULL);
if (iv->handler) {
- iv->next = malloc(sizeof *iv, M_DEVBUF, M_NOWAIT);
- iv = iv->next;
+ struct hppa_iv *nv;
+
+ nv = malloc(sizeof *iv, M_DEVBUF, M_NOWAIT);
+ if (!nv)
+ return (NULL);
+ while (iv->next)
+ iv = iv->next;
+ iv->next = nv;
+ iv = nv;
} else
imask[pri] |= (1 << irq);
- if (iv != NULL) {
- iv->pri = pri;
- iv->irq = 0;
- iv->bit = 1 << irq;
- iv->flags = HPPA_IV_SOFT;
- iv->handler = (int (*)(void *))handler; /* XXX */
- iv->arg = arg;
- iv->cnt = NULL;
- iv->next = NULL;
- iv->share = NULL;
- }
+ iv->pri = pri;
+ iv->irq = 0;
+ iv->bit = 1 << irq;
+ iv->flags = HPPA_IV_SOFT;
+ iv->handler = (int (*)(void *))handler; /* XXX */
+ iv->arg = arg;
+ iv->cnt = NULL;
+ iv->next = NULL;
+ iv->share = NULL;
return (iv);
}