Module Name:    src
Committed By:   skrll
Date:           Tue Dec 21 07:11:02 UTC 2021

Modified Files:
        src/sys/arch/arm/pic: pic.c

Log Message:
Fix a bug where pic_establish_intr would fail to call pic_establish_irq
if a free pic__iplsources slot was found, i.e. an interrupt handler at
the same ipl had been disestablished previously.


To generate a diff of this commit:
cvs rdiff -u -r1.77 -r1.78 src/sys/arch/arm/pic/pic.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/pic/pic.c
diff -u src/sys/arch/arm/pic/pic.c:1.77 src/sys/arch/arm/pic/pic.c:1.78
--- src/sys/arch/arm/pic/pic.c:1.77	Tue Dec 21 07:07:32 2021
+++ src/sys/arch/arm/pic/pic.c	Tue Dec 21 07:11:02 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: pic.c,v 1.77 2021/12/21 07:07:32 skrll Exp $	*/
+/*	$NetBSD: pic.c,v 1.78 2021/12/21 07:11:02 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.77 2021/12/21 07:07:32 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.78 2021/12/21 07:11:02 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -754,42 +754,44 @@ pic_establish_intr(struct pic_softc *pic
 	/*
 	 * First try to use an existing slot which is empty.
 	 */
+	bool found = false;
 	for (off = pic_ipl_offset[ipl]; off < pic_ipl_offset[ipl + 1]; off++) {
 		if (pic__iplsources[off] == NULL) {
-			is->is_iplidx = off - pic_ipl_offset[ipl];
-			pic__iplsources[off] = is;
-			goto unblock;
+			found = true;
+			break;
 		}
 	}
 
-	/*
-	 * Move up all the sources by one.
- 	 */
-	if (ipl < NIPL) {
-		off = pic_ipl_offset[ipl + 1];
-		memmove(&pic__iplsources[off + 1], &pic__iplsources[off],
-		    sizeof(pic__iplsources[0]) * (pic_ipl_offset[NIPL] - off));
-	}
+	if (!found) {
+		/*
+		* Move up all the sources by one.
+		*/
+		if (ipl < NIPL) {
+			off = pic_ipl_offset[ipl + 1];
+			memmove(&pic__iplsources[off + 1], &pic__iplsources[off],
+			    sizeof(pic__iplsources[0]) * (pic_ipl_offset[NIPL] - off));
+		}
 
-	/*
-	 * Advance the offset of all IPLs higher than this.  Include an
-	 * extra one as well.  Thus the number of sources per ipl is
-	 * pic_ipl_offset[ipl + 1] - pic_ipl_offset[ipl].
-	 */
-	for (nipl = ipl + 1; nipl <= NIPL; nipl++)
-		pic_ipl_offset[nipl]++;
+		/*
+		* Advance the offset of all IPLs higher than this.  Include an
+		* extra one as well.  Thus the number of sources per ipl is
+		* pic_ipl_offset[ipl + 1] - pic_ipl_offset[ipl].
+		*/
+		for (nipl = ipl + 1; nipl <= NIPL; nipl++)
+			pic_ipl_offset[nipl]++;
+
+		off = pic_ipl_offset[ipl + 1] - 1;
+	}
 
 	/*
-	 * Insert into the previously made position at the end of this IPL's
-	 * sources.
+	 * Insert into the 'found' or the just made slot position at the end
+	 * of this IPL's sources.
 	 */
-	off = pic_ipl_offset[ipl + 1] - 1;
 	is->is_iplidx = off - pic_ipl_offset[ipl];
 	pic__iplsources[off] = is;
 
 	(*pic->pic_ops->pic_establish_irq)(pic, is);
 
-unblock:
 	if (!mp_online || !is->is_mpsafe || !is->is_percpu) {
 		(*pic->pic_ops->pic_unblock_irqs)(pic, is->is_irq & ~0x1f,
 		    __BIT(is->is_irq & 0x1f));

Reply via email to