Module Name:    src
Committed By:   skrll
Date:           Sat Apr 14 10:43:19 UTC 2012

Modified Files:
        src/sys/arch/hp700/dev: apic.c

Log Message:
Sync with the following OpenBSD changes, but do the shared interrupt
reporting differently.  Each cpu and device interrupt gets its own
counter.

revision 1.14
Fix counting of interrupts for devices that attach to elroy(4).  Shared
interrupts would be counted double, once for the interrupting device and
once for the device at the head of the chain.  The handlers would run properly
though.  Avoid this by giving each device its own interrupt counter instead
of using the counter provided by the generic interrupt handling code for the
head of the chain.

revision 1.13
Stop calling shared interrupt handlers as soon as one of them return 1
(positive interrupt was for me), like we do on other architectures.
This is done here, at the elroy(4) driver level, since this is where shared
PCI interrupts are handled.  We could do something similar for dino(4) but
this optimization is probably not very relevant there.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/hp700/dev/apic.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/hp700/dev/apic.c
diff -u src/sys/arch/hp700/dev/apic.c:1.13 src/sys/arch/hp700/dev/apic.c:1.14
--- src/sys/arch/hp700/dev/apic.c:1.13	Tue Apr  3 12:07:26 2012
+++ src/sys/arch/hp700/dev/apic.c	Sat Apr 14 10:43:19 2012
@@ -1,6 +1,6 @@
-/*	$NetBSD: apic.c,v 1.13 2012/04/03 12:07:26 skrll Exp $	*/
+/*	$NetBSD: apic.c,v 1.14 2012/04/14 10:43:19 skrll Exp $	*/
 
-/*	$OpenBSD: apic.c,v 1.7 2007/10/06 23:50:54 krw Exp $	*/
+/*	$OpenBSD: apic.c,v 1.14 2011/05/01 21:59:39 kettenis Exp $	*/
 
 /*
  * Copyright (c) 2005 Michael Shalayeff
@@ -178,53 +178,61 @@ apic_intr_establish(void *v, pci_intr_ha
 	if (aiv == NULL)
 		return NULL;
 
+	cnt = malloc(sizeof(struct evcnt), M_DEVBUF, M_NOWAIT);
+	if (cnt == NULL) {
+		free(aiv, M_DEVBUF);
+		return NULL;
+	}
+
 	aiv->sc = sc;
 	aiv->ih = ih;
 	aiv->handler = handler;
 	aiv->arg = arg;
 	aiv->next = NULL;
-	aiv->cnt = NULL;
-	if (apic_intr_list[irq]) {
-		cnt = malloc(sizeof(struct evcnt), M_DEVBUF, M_NOWAIT);
-		if (cnt == NULL) {
+	aiv->cnt = cnt;
+
+	biv = apic_intr_list[irq];
+	if (biv == NULL) {
+		iv = hp700_intr_establish(pri, apic_intr, aiv, &ir_cpu, irq);
+		if (iv == NULL) {
 			free(aiv, M_DEVBUF);
+			free(cnt, M_DEVBUF);
+
 			return NULL;
 		}
+	}
+
+	snprintf(aiv->aiv_name, sizeof(aiv->aiv_name), "line %d irq %d",
+	    line, irq);
 
-		snprintf(aiv->aiv_name, sizeof(aiv->aiv_name), "line %d irq %d",
-		    line, irq);
+	evcnt_attach_dynamic(cnt, EVCNT_TYPE_INTR, NULL,
+	    device_xname(sc->sc_dv), aiv->aiv_name);
 
-		evcnt_attach_dynamic(cnt, EVCNT_TYPE_INTR, NULL,
-		    device_xname(sc->sc_dv), aiv->aiv_name);
-		biv = apic_intr_list[irq];
+	if (biv) {
 		while (biv->next)
 			biv = biv->next;
 		biv->next = aiv;
-		aiv->cnt = cnt;
 		return arg;
 	}
 
-	iv = hp700_intr_establish(pri, apic_intr, aiv, &ir_cpu, irq);
-	if (iv) {
-		ent0 = (31 - irq) & APIC_ENT0_VEC;
-		ent0 |= apic_get_int_ent0(sc, line);
+	ent0 = (31 - irq) & APIC_ENT0_VEC;
+	ent0 |= apic_get_int_ent0(sc, line);
 #if 0
-		if (cold) {
-			sc->sc_imr |= (1 << irq);
-			ent0 |= APIC_ENT0_MASK;
-		}
+	if (cold) {
+		sc->sc_imr |= (1 << irq);
+		ent0 |= APIC_ENT0_MASK;
+	}
 #endif
-		apic_write(sc->sc_regs, APIC_ENT0(line), APIC_ENT0_MASK);
-		apic_write(sc->sc_regs, APIC_ENT1(line),
-		    ((hpa & 0x0ff00000) >> 4) | ((hpa & 0x000ff000) << 12));
-		apic_write(sc->sc_regs, APIC_ENT0(line), ent0);
-
-		/* Signal EOI. */
-		elroy_write32(&r->apic_eoi,
-		    htole32((31 - irq) & APIC_ENT0_VEC));
+	apic_write(sc->sc_regs, APIC_ENT0(line), APIC_ENT0_MASK);
+	apic_write(sc->sc_regs, APIC_ENT1(line),
+	    ((hpa & 0x0ff00000) >> 4) | ((hpa & 0x000ff000) << 12));
+	apic_write(sc->sc_regs, APIC_ENT0(line), ent0);
 
-		apic_intr_list[irq] = aiv;
-	}
+	/* Signal EOI. */
+	elroy_write32(&r->apic_eoi,
+	    htole32((31 - irq) & APIC_ENT0_VEC));
+
+	apic_intr_list[irq] = aiv;
 
 	return (arg);
 }
@@ -244,11 +252,11 @@ apic_intr(void *v)
 	int claimed = 0;
 
 	while (iv) {
-		if (iv->handler(iv->arg)) {
-			if (iv->cnt)
-				iv->cnt->ev_count++;
-			claimed = 1;
-		}
+		claimed = iv->handler(iv->arg);
+		if (claimed && iv->cnt)
+			iv->cnt->ev_count++;
+		if (claimed)
+			break;
 		iv = iv->next;
 	}
 	/* Signal EOI. */

Reply via email to