Module Name:    src
Committed By:   tsutsui
Date:           Sat Jun 26 01:48:57 UTC 2010

Modified Files:
        src/sys/arch/sun3/dev: zs.c

Log Message:
Pull a similar fix from sparc/dev/zs.c rev 1.119:
 Establish interrupt handlers with proper softc per each zs device
 rather than sharing them among all zs devices and searching softc
 in handlers, to avoid possible recursive lock.


To generate a diff of this commit:
cvs rdiff -u -r1.84 -r1.85 src/sys/arch/sun3/dev/zs.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/sun3/dev/zs.c
diff -u src/sys/arch/sun3/dev/zs.c:1.84 src/sys/arch/sun3/dev/zs.c:1.85
--- src/sys/arch/sun3/dev/zs.c:1.84	Fri Jun 13 13:11:42 2008
+++ src/sys/arch/sun3/dev/zs.c	Sat Jun 26 01:48:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: zs.c,v 1.84 2008/06/13 13:11:42 cegger Exp $	*/
+/*	$NetBSD: zs.c,v 1.85 2010/06/26 01:48:57 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.84 2008/06/13 13:11:42 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.85 2010/06/26 01:48:57 tsutsui Exp $");
 
 #include "opt_kgdb.h"
 
@@ -260,7 +260,6 @@
 	volatile struct zschan *zc;
 	struct zs_chanstate *cs;
 	int s, zs_unit, channel;
-	static int didintr;
 
 	zsc->zsc_dev = self;
 	zs_unit = device_unit(self);
@@ -331,14 +330,9 @@
 	}
 
 	/*
-	 * Now safe to install interrupt handlers.  Note the arguments
-	 * to the interrupt handlers aren't used.  Note, we only do this
-	 * once since both SCCs interrupt at the same level and vector.
+	 * Now safe to install interrupt handlers.
 	 */
-	if (!didintr) {
-		didintr = 1;
-		isr_add_autovect(zshard, NULL, ca->ca_intpri);
-	}
+	isr_add_autovect(zshard, zsc, ca->ca_intpri);
 	zsc->zs_si = softint_establish(SOFTINT_SERIAL,
 	    (void (*)(void *))zsc_intr_soft, zsc);
 	/* XXX; evcnt_attach() ? */
@@ -382,25 +376,18 @@
 
 /*
  * Our ZS chips all share a common, autovectored interrupt,
- * so we have to look at all of them on each interrupt.
+ * but we establish zshard handler per each ZS chip
+ * to avoid holding unnecessary locks in interrupt context.
  */
 static int 
 zshard(void *arg)
 {
-	struct zsc_softc *zsc;
-	int unit, rval, softreq;
+	struct zsc_softc *zsc = arg;
+	int rval;
 
-	rval = 0;
-	for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
-		zsc = device_lookup_private(&zsc_cd, unit);
-		if (zsc == NULL)
-			continue;
-		rval |= zsc_intr_hard(zsc);
-		softreq  = zsc->zsc_cs[0]->cs_softreq;
-		softreq |= zsc->zsc_cs[1]->cs_softreq;
-		if (softreq)
-			softint_schedule(zsc->zs_si);
-	}
+	rval = zsc_intr_hard(zsc);
+	if (zsc->zsc_cs[0]->cs_softreq || zsc->zsc_cs[1]->cs_softreq)
+		softint_schedule(zsc->zs_si);
 
 	return (rval);
 }

Reply via email to