PERFORCE change 139921 for review

Oleksandr Tymoshenko gonzo at FreeBSD.org
Sat Apr 12 17:43:27 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=139921

Change 139921 by gonzo at gonzo_jeeves on 2008/04/12 17:42:32

	o We can share interrupts, so don't panic if there are several
	    requests for the same IRQ.
	o Implement PIC-specific mask/unmask functions intead of generic stubs.
	o New IRQ handling logic: take into account FILTER_SCHEDULE_THREAD,
	    reset thread flag before handling new IRQ.
	o Do not map MEM/IOPORT resources on this level - it's up to nexus 
	    device.
	o Minor style(9) fixes

Affected files ...

.. //depot/projects/mips2-jnpr/src/sys/mips/mips32/idt/obio.c#3 edit

Differences ...

==== //depot/projects/mips2-jnpr/src/sys/mips/mips32/idt/obio.c#3 (text+ko) ====

@@ -76,6 +76,30 @@
 static int	obio_teardown_intr(device_t, device_t, struct resource *,
 		    void *);
 
+static void obio_mask_irq(unsigned int irq)
+{
+	int ip_bit, mask, mask_register;
+
+	/* mask IRQ */
+	mask_register = ICU_IRQ_MASK_REG(irq);
+	ip_bit = ICU_IP_BIT(irq);
+
+	mask = ICU_REG_READ(mask_register);
+	ICU_REG_WRITE(mask_register, mask | ip_bit);
+}
+
+static void obio_unmask_irq(unsigned int irq)
+{
+	int ip_bit, mask, mask_register;
+
+	/* unmask IRQ */
+	mask_register = ICU_IRQ_MASK_REG(irq);
+	ip_bit = ICU_IP_BIT(irq);
+
+	mask = ICU_REG_READ(mask_register);
+	ICU_REG_WRITE(mask_register, mask & ~ip_bit);
+}
+
 static int
 obio_probe(device_t dev)
 {
@@ -199,20 +223,9 @@
     struct resource *r)
 {
 
-	/*
-	 * If this is a memory resource, track the direct mapping
-	 * in the uncached MIPS KSEG1 segment.
-	 */
-	if (type == SYS_RES_MEMORY) {
-		void *vaddr;
-
-		vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r));
-		rman_set_virtual(r, vaddr);
-		rman_set_bustag(r, MIPS_BUS_SPACE_MEM);
-		rman_set_bushandle(r, (bus_space_handle_t)vaddr);
-	}
-
-	return (rman_activate_resource(r));
+	/* XXX: should we mask/unmask IRQ here? */
+	return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child,
+		type, rid, r));
 }
 
 static int
@@ -220,7 +233,9 @@
     struct resource *r)
 {
 
-	return (rman_deactivate_resource(r));
+	/* XXX: should we mask/unmask IRQ here? */
+	return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child,
+		type, rid, r));
 }
 
 static int
@@ -259,14 +274,12 @@
 	event = sc->sc_eventstab[irq];
 	if (event == NULL) {
 		error = intr_event_create(&event, (void *)irq, 0,
-		    (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq,
+		    (mask_fn)obio_mask_irq, (mask_fn)obio_unmask_irq,
 		    NULL, NULL,
 		    "obio intr%d:", irq);
 
 		sc->sc_eventstab[irq] = event;
 	}
-	else
-		panic("obio: Can't share IRQs");
 
 	intr_event_add_handler(event, device_get_nameunit(child), filt,
 	    handler, arg, intr_priority(flags), flags, cookiep);
@@ -304,9 +317,8 @@
 	ICU_REG_WRITE(mask_register, mask | ip_bit);
 
 	result = intr_event_remove_handler(cookie);
-	if (!result) {
+	if (!result)
 		sc->sc_eventstab[irq] = NULL;
-	}
 
 	return (result);
 }
@@ -318,9 +330,8 @@
 	struct intr_event *event;
 	struct intr_handler *ih;
 	uint32_t irqstat, ipend, imask, xpend;
-	int irq, thread = 0, group, i;
+	int irq, thread, group, i, ret;
 
-	/* TODO: handle all IRQs */
 	irqstat = 0;
 	irq = 0;
 	for (group = 2; group <= 6; group++) {
@@ -328,6 +339,7 @@
 		imask = ICU_REG_READ(ICU_GROUP_MASK_REG(group));
 		xpend = ipend;
 		ipend &= ~imask;
+
 		while ((i = fls(xpend)) != 0) {
 			xpend &= ~(1 << (i - 1));
 			irq = IP_IRQ(group, i - 1);
@@ -337,23 +349,48 @@
 			ipend &= ~(1 << (i - 1));
 			irq = IP_IRQ(group, i - 1);
 			event = sc->sc_eventstab[irq];
-			if (event && !TAILQ_EMPTY(&event->ie_handlers)) {
-				/* Execute fast handlers. */
-				TAILQ_FOREACH(ih, &event->ie_handlers,
-				    ih_next) {
-					if (ih->ih_filter == NULL)
+			thread = 0;
+#ifndef INTR_FILTER
+			obio_mask_irq(irq);
+#endif
+			if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
+#ifdef INTR_FILTER
+				obio_unmask_irq(irq);
+#endif
+				continue;
+			}
+
+#ifdef INTR_FILTER
+			/* TODO: frame instead of NULL? */
+			intr_event_handle(event, NULL);
+			/* XXX: Log stray IRQs */
+#else
+			/* Execute fast handlers. */
+			TAILQ_FOREACH(ih, &event->ie_handlers,
+			    ih_next) {
+				if (ih->ih_filter == NULL)
+					thread = 1;
+				else
+					ret = ih->ih_filter(ih->ih_argument);
+				/*
+				 * Wrapper handler special case: see
+				 * intr_execute_handlers() in
+				 * i386/intr_machdep.c
+				 */
+				if (!thread) {
+					if (ret == FILTER_SCHEDULE_THREAD)
 						thread = 1;
-					else
-						ih->ih_filter(ih->ih_argument);
 				}
 			}
 
 			/* Schedule thread if needed. */
 			if (thread)
 				intr_event_schedule_thread(event);
-
+			else
+				obio_unmask_irq(irq);
 		}
 	}
+#endif
 #if 0
 	ipend = ICU_REG_READ(ICU_IPEND2);
 	printf("ipend2 = %08x!\n", ipend);


More information about the p4-projects mailing list