svn commit: r189183 - projects/jbuild/sys/dev/ppc

John Birrell jb at FreeBSD.org
Sat Feb 28 09:57:26 PST 2009


Author: jb
Date: Sat Feb 28 17:57:21 2009
New Revision: 189183
URL: http://svn.freebsd.org/changeset/base/189183

Log:
  MFC

Modified:
  projects/jbuild/sys/dev/ppc/ppc.c
  projects/jbuild/sys/dev/ppc/ppc_acpi.c
  projects/jbuild/sys/dev/ppc/ppc_isa.c
  projects/jbuild/sys/dev/ppc/ppc_pci.c
  projects/jbuild/sys/dev/ppc/ppc_puc.c
  projects/jbuild/sys/dev/ppc/ppcreg.h
  projects/jbuild/sys/dev/ppc/ppcvar.h

Modified: projects/jbuild/sys/dev/ppc/ppc.c
==============================================================================
--- projects/jbuild/sys/dev/ppc/ppc.c	Sat Feb 28 17:57:08 2009	(r189182)
+++ projects/jbuild/sys/dev/ppc/ppc.c	Sat Feb 28 17:57:21 2009	(r189183)
@@ -34,9 +34,11 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/interrupt.h>
 #include <sys/module.h>
 #include <sys/malloc.h>
+#include <sys/mutex.h>
 #include <sys/proc.h>
 
 #include <machine/bus.h>
@@ -113,29 +115,30 @@ static char *ppc_epp_protocol[] = { " (E
 /*
  * ppc_ecp_sync()		XXX
  */
-void
+int
 ppc_ecp_sync(device_t dev)
 {
 	int i, r;
 	struct ppc_data *ppc = DEVTOSOFTC(dev);
 
+	PPC_ASSERT_LOCKED(ppc);
 	if (!(ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_dtm & PPB_ECP))
-		return;
+		return 0;
 
 	r = r_ecr(ppc);
 	if ((r & 0xe0) != PPC_ECR_EPP)
-		return;
+		return 0;
 
 	for (i = 0; i < 100; i++) {
 		r = r_ecr(ppc);
 		if (r & 0x1)
-			return;
+			return 0;
 		DELAY(100);
 	}
 
 	device_printf(dev, "ECP sync failed as data still present in FIFO.\n");
 
-	return;
+	return 0;
 }
 
 /*
@@ -474,7 +477,7 @@ ppc_pc873xx_detect(struct ppc_data *ppc,
 
 	    /* First try to change the port address to that requested... */
 
-	    switch(ppc->ppc_base) {
+	    switch (ppc->ppc_base) {
 		case 0x378:
 		val &= 0xfc;
 		break;
@@ -1320,6 +1323,7 @@ ppc_exec_microseq(device_t dev, struct p
 
 #define INCR_PC (mi ++)		/* increment program counter */
 
+	PPC_ASSERT_LOCKED(ppc);
 	mi = *p_msq;
 	for (;;) {
 		switch (mi->opcode) {
@@ -1388,8 +1392,11 @@ ppc_exec_microseq(device_t dev, struct p
 			break;
 
 		case MS_OP_ADELAY:
-			if (mi->arg[0].i)
+			if (mi->arg[0].i) {
+				PPC_UNLOCK(ppc);
 				pause("ppbdelay", mi->arg[0].i * (hz/1000));
+				PPC_LOCK(ppc);
+			}
 			INCR_PC;
 			break;
 
@@ -1521,8 +1528,10 @@ ppcintr(void *arg)
 	 * XXX: If DMA is in progress should we just complete that w/o
 	 * doing this?
 	 */
-	if (ppc->ppc_child_handlers > 0) {
-		intr_event_execute_handlers(curproc, ppc->ppc_intr_event);
+	PPC_LOCK(ppc);
+	if (ppc->ppc_intr_hook != NULL &&
+	    ppc->ppc_intr_hook(ppc->ppc_intr_arg) == 0) {
+		PPC_UNLOCK(ppc);
 		return;
 	}
 
@@ -1536,6 +1545,7 @@ ppcintr(void *arg)
 
 	/* don't use ecp mode with IRQENABLE set */
 	if (ctr & IRQENABLE) {
+		PPC_UNLOCK(ppc);
 		return;
 	}
 
@@ -1550,6 +1560,7 @@ ppcintr(void *arg)
 			ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
 		} else {
 			/* shall be handled by underlying layers XXX */
+			PPC_UNLOCK(ppc);
 			return;
 		}
 	}
@@ -1585,6 +1596,7 @@ ppcintr(void *arg)
 		/* classic interrupt I/O */
 		ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
 	}
+	PPC_UNLOCK(ppc);
 
 	return;
 }
@@ -1601,14 +1613,15 @@ ppc_write(device_t dev, char *buf, int l
 	return (EINVAL);
 }
 
-void
+int
 ppc_reset_epp(device_t dev)
 {
 	struct ppc_data *ppc = DEVTOSOFTC(dev);
 
+	PPC_ASSERT_LOCKED(ppc);
 	ppc_reset_epp_timeout(ppc);
 
-	return;
+	return 0;
 }
 
 int
@@ -1616,6 +1629,7 @@ ppc_setmode(device_t dev, int mode)
 {
 	struct ppc_data *ppc = DEVTOSOFTC(dev);
 
+	PPC_ASSERT_LOCKED(ppc);
 	switch (ppc->ppc_type) {
 	case PPC_TYPE_SMCLIKE:
 		return (ppc_smclike_setmode(ppc, mode));
@@ -1796,9 +1810,10 @@ int
 ppc_attach(device_t dev)
 {
 	struct ppc_data *ppc = DEVTOSOFTC(dev);
-	device_t ppbus;
 	int error;
 
+	mtx_init(&ppc->ppc_lock, device_get_nameunit(dev), "ppc", MTX_DEF);
+
 	device_printf(dev, "%s chipset (%s) in %s mode%s\n",
 		      ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm],
 		      ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
@@ -1809,36 +1824,25 @@ ppc_attach(device_t dev)
 			      ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr);
 
 	if (ppc->res_irq) {
-		/*
-		 * Create an interrupt event to manage the handlers of
-		 * child devices.
-		 */
-		error = intr_event_create(&ppc->ppc_intr_event, ppc, 0, -1,
-		    NULL, NULL, NULL, NULL, "%s:", device_get_nameunit(dev));
-		if (error) {
-			device_printf(dev,
-			    "failed to create interrupt event: %d\n", error);
-			return (error);
-		}
-
 		/* default to the tty mask for registration */	/* XXX */
-		error = bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY,
-		    NULL, ppcintr, ppc, &ppc->intr_cookie);
+		error = bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY |
+		    INTR_MPSAFE, NULL, ppcintr, ppc, &ppc->intr_cookie);
 		if (error) {
 			device_printf(dev,
 			    "failed to register interrupt handler: %d\n",
 			    error);
+			mtx_destroy(&ppc->ppc_lock);
 			return (error);
 		}
 	}
 
 	/* add ppbus as a child of this isa to parallel bridge */
-	ppbus = device_add_child(dev, "ppbus", -1);
+	ppc->ppbus = device_add_child(dev, "ppbus", -1);
 
 	/*
 	 * Probe the ppbus and attach devices found.
 	 */
-	device_probe_and_attach(ppbus);
+	device_probe_and_attach(ppc->ppbus);
 
 	return (0);
 }
@@ -1876,6 +1880,8 @@ ppc_detach(device_t dev)
 				     ppc->res_drq);
 	}
 
+	mtx_destroy(&ppc->ppc_lock);
+
 	return (0);
 }
 
@@ -1884,6 +1890,7 @@ ppc_io(device_t ppcdev, int iop, u_char 
 {
 	struct ppc_data *ppc = DEVTOSOFTC(ppcdev);
 
+	PPC_ASSERT_LOCKED(ppc);
 	switch (iop) {
 	case PPB_OUTSB_EPP:
 	    bus_write_multi_1(ppc->res_ioport, PPC_EPP_DATA, addr, cnt);
@@ -1953,8 +1960,38 @@ ppc_read_ivar(device_t bus, device_t dev
 
 	switch (index) {
 	case PPC_IVAR_EPP_PROTO:
+		PPC_ASSERT_LOCKED(ppc);
 		*val = (u_long)ppc->ppc_epp;
 		break;
+	case PPC_IVAR_LOCK:
+		*val = (uintptr_t)&ppc->ppc_lock;
+		break;
+	default:
+		return (ENOENT);
+	}
+
+	return (0);
+}
+
+int
+ppc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val)
+{
+	struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus);
+
+	switch (index) {
+	case PPC_IVAR_INTR_HANDLER:
+		PPC_ASSERT_LOCKED(ppc);
+		if (dev != ppc->ppbus)
+			return (EINVAL);
+		if (val == 0) {
+			ppc->ppc_intr_hook = NULL;
+			break;
+		}
+		if (ppc->ppc_intr_hook != NULL)
+			return (EBUSY);
+		ppc->ppc_intr_hook = (void *)val;
+		ppc->ppc_intr_arg = device_get_softc(dev);
+		break;
 	default:
 		return (ENOENT);
 	}
@@ -2001,47 +2038,4 @@ ppc_release_resource(device_t bus, devic
 	return (EINVAL);
 }
 
-/*
- * If a child wants to add a handler for our IRQ, add it to our interrupt
- * event.  Otherwise, fail the request.
- */
-int
-ppc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
-    driver_filter_t *filt, void (*ihand)(void *), void *arg, void **cookiep)
-{
-	struct ppc_data *ppc = DEVTOSOFTC(bus);
-	int error;
-
-	if (r != ppc->res_irq)
-		return (EINVAL);
-
-	/* We don't allow filters. */
-	if (filt != NULL)
-		return (EINVAL);
-
-	error = intr_event_add_handler(ppc->ppc_intr_event,
-	    device_get_nameunit(child), NULL, ihand, arg, intr_priority(flags),
-	    flags, cookiep);
-	if (error == 0)
-		ppc->ppc_child_handlers++;
-	return (error);
-}
-
-int
-ppc_teardown_intr(device_t bus, device_t child, struct resource *r, void *cookie)
-{
-	struct ppc_data *ppc = DEVTOSOFTC(bus);
-	int error;
-
-	if (r != ppc->res_irq)
-		return (EINVAL);
-
-	KASSERT(intr_handler_source(cookie) == ppc,
-	    ("ppc_teardown_intr: source mismatch"));
-	error = intr_event_remove_handler(cookie);
-	if (error == 0)
-		ppc->ppc_child_handlers--;
-	return (error);
-}
-
 MODULE_DEPEND(ppc, ppbus, 1, 1, 1);

Modified: projects/jbuild/sys/dev/ppc/ppc_acpi.c
==============================================================================
--- projects/jbuild/sys/dev/ppc/ppc_acpi.c	Sat Feb 28 17:57:08 2009	(r189182)
+++ projects/jbuild/sys/dev/ppc/ppc_acpi.c	Sat Feb 28 17:57:21 2009	(r189183)
@@ -63,8 +63,7 @@ static device_method_t ppc_acpi_methods[
 
 	/* bus interface */
 	DEVMETHOD(bus_read_ivar,	ppc_read_ivar),
-	DEVMETHOD(bus_setup_intr,	ppc_setup_intr),
-	DEVMETHOD(bus_teardown_intr,	ppc_teardown_intr),
+	DEVMETHOD(bus_write_ivar,	ppc_write_ivar),
 	DEVMETHOD(bus_alloc_resource,	ppc_alloc_resource),
 	DEVMETHOD(bus_release_resource,	ppc_release_resource),
 

Modified: projects/jbuild/sys/dev/ppc/ppc_isa.c
==============================================================================
--- projects/jbuild/sys/dev/ppc/ppc_isa.c	Sat Feb 28 17:57:08 2009	(r189182)
+++ projects/jbuild/sys/dev/ppc/ppc_isa.c	Sat Feb 28 17:57:21 2009	(r189183)
@@ -32,7 +32,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/module.h>
+#include <sys/mutex.h>
 #include <sys/bus.h>
 #include <machine/bus.h>
 #include <sys/malloc.h>
@@ -56,12 +58,11 @@ static device_method_t ppc_isa_methods[]
 	/* device interface */
 	DEVMETHOD(device_probe,		ppc_isa_probe),
 	DEVMETHOD(device_attach,	ppc_isa_attach),
-	DEVMETHOD(device_detach,	ppc_attach),
+	DEVMETHOD(device_detach,	ppc_detach),
 
 	/* bus interface */
 	DEVMETHOD(bus_read_ivar,	ppc_read_ivar),
-	DEVMETHOD(bus_setup_intr,	ppc_setup_intr),
-	DEVMETHOD(bus_teardown_intr,	ppc_teardown_intr),
+	DEVMETHOD(bus_write_ivar,	ppc_write_ivar),
 	DEVMETHOD(bus_alloc_resource,	ppc_alloc_resource),
 	DEVMETHOD(bus_release_resource,	ppc_release_resource),
 
@@ -143,6 +144,7 @@ ppc_isa_write(device_t dev, char *buf, i
 	int s, error = 0;
 	int spin;
 
+	PPC_ASSERT_LOCKED(ppc);
 	if (!(ppc->ppc_avm & PPB_ECP))
 		return (EINVAL);
 	if (ppc->ppc_dmachan == 0)
@@ -215,7 +217,8 @@ ppc_isa_write(device_t dev, char *buf, i
 	 */
 	do {
 		/* release CPU */
-		error = tsleep(ppc, PPBPRI | PCATCH, "ppcdma", 0);
+		error = mtx_sleep(ppc, &ppc->ppc_lock, PPBPRI | PCATCH,
+		    "ppcdma", 0);
 	} while (error == EWOULDBLOCK);
 
 	splx(s);
@@ -244,7 +247,8 @@ ppc_isa_write(device_t dev, char *buf, i
 #ifdef PPC_DEBUG
 		printf("Z");
 #endif
-		error = tsleep(ppc, PPBPRI | PCATCH, "ppcfifo", hz/100);
+		error = mtx_sleep(ppc, &ppc->ppc_lock, PPBPRI | PCATCH,
+		    "ppcfifo", hz / 100);
 		if (error != EWOULDBLOCK) {
 #ifdef PPC_DEBUG
 			printf("I");

Modified: projects/jbuild/sys/dev/ppc/ppc_pci.c
==============================================================================
--- projects/jbuild/sys/dev/ppc/ppc_pci.c	Sat Feb 28 17:57:08 2009	(r189182)
+++ projects/jbuild/sys/dev/ppc/ppc_pci.c	Sat Feb 28 17:57:21 2009	(r189183)
@@ -53,8 +53,7 @@ static device_method_t ppc_pci_methods[]
 
 	/* bus interface */
 	DEVMETHOD(bus_read_ivar,	ppc_read_ivar),
-	DEVMETHOD(bus_setup_intr,	ppc_setup_intr),
-	DEVMETHOD(bus_teardown_intr,	ppc_teardown_intr),
+	DEVMETHOD(bus_write_ivar,	ppc_write_ivar),
 	DEVMETHOD(bus_alloc_resource,	ppc_alloc_resource),
 	DEVMETHOD(bus_release_resource,	ppc_release_resource),
 
@@ -85,6 +84,7 @@ struct pci_id {
 static struct pci_id pci_ids[] = {
 	{ 0x1020131f, "SIIG Cyber Parallel PCI (10x family)", 0x18 },
 	{ 0x2020131f, "SIIG Cyber Parallel PCI (20x family)", 0x10 },
+	{ 0x05111407, "Lava SP BIDIR Parallel PCI", 0x10 },
 	{ 0x80001407, "Lava Computers 2SP-PCI parallel port", 0x10 },
 	{ 0x84031415, "Oxford Semiconductor OX12PCI840 Parallel port", 0x10 },
 	{ 0x95131415, "Oxford Semiconductor OX16PCI954 Parallel port", 0x10 },

Modified: projects/jbuild/sys/dev/ppc/ppc_puc.c
==============================================================================
--- projects/jbuild/sys/dev/ppc/ppc_puc.c	Sat Feb 28 17:57:08 2009	(r189182)
+++ projects/jbuild/sys/dev/ppc/ppc_puc.c	Sat Feb 28 17:57:21 2009	(r189183)
@@ -55,8 +55,7 @@ static device_method_t ppc_puc_methods[]
 
 	/* bus interface */
 	DEVMETHOD(bus_read_ivar,	ppc_read_ivar),
-	DEVMETHOD(bus_setup_intr,	ppc_setup_intr),
-	DEVMETHOD(bus_teardown_intr,	ppc_teardown_intr),
+	DEVMETHOD(bus_write_ivar,	ppc_write_ivar),
 	DEVMETHOD(bus_alloc_resource,	ppc_alloc_resource),
 	DEVMETHOD(bus_release_resource,	ppc_release_resource),
 

Modified: projects/jbuild/sys/dev/ppc/ppcreg.h
==============================================================================
--- projects/jbuild/sys/dev/ppc/ppcreg.h	Sat Feb 28 17:57:08 2009	(r189182)
+++ projects/jbuild/sys/dev/ppc/ppcreg.h	Sat Feb 28 17:57:21 2009	(r189183)
@@ -29,6 +29,9 @@
 #ifndef __PPCREG_H
 #define __PPCREG_H
 
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+
 /*
  * Parallel Port Chipset type.
  */
@@ -108,10 +111,16 @@ struct ppc_data {
 
 	void *intr_cookie;
 
-	struct intr_event *ppc_intr_event;
-	int ppc_child_handlers;
+	ppc_intr_handler ppc_intr_hook;
+	void *ppc_intr_arg;
+
+	struct mtx ppc_lock;
 };
 
+#define	PPC_LOCK(data)		mtx_lock(&(data)->ppc_lock)
+#define	PPC_UNLOCK(data)	mtx_unlock(&(data)->ppc_lock)
+#define	PPC_ASSERT_LOCKED(data)	mtx_assert(&(data)->ppc_lock, MA_OWNED)
+
 /*
  * Parallel Port Chipset registers.
  */

Modified: projects/jbuild/sys/dev/ppc/ppcvar.h
==============================================================================
--- projects/jbuild/sys/dev/ppc/ppcvar.h	Sat Feb 28 17:57:08 2009	(r189182)
+++ projects/jbuild/sys/dev/ppc/ppcvar.h	Sat Feb 28 17:57:21 2009	(r189183)
@@ -32,6 +32,7 @@ int ppc_probe(device_t dev, int rid);
 int ppc_attach(device_t dev);
 int ppc_detach(device_t dev);
 int ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val);
+int ppc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val);
 
 int ppc_read(device_t, char *, int, int);
 int ppc_write(device_t, char *, int, int);
@@ -39,15 +40,12 @@ int ppc_write(device_t, char *, int, int
 u_char ppc_io(device_t, int, u_char *, int, u_char);
 int ppc_exec_microseq(device_t, struct ppb_microseq **);
 
-int ppc_setup_intr(device_t, device_t, struct resource *, int,
-		driver_filter_t *filt, void (*)(void *), void *, void **);
-int ppc_teardown_intr(device_t, device_t, struct resource *, void *);
 struct resource *ppc_alloc_resource(device_t bus, device_t child, int type,
     int *rid, u_long start, u_long end, u_long count, u_int flags);
 int ppc_release_resource(device_t bus, device_t child, int type, int rid,
     struct resource *r);
-void ppc_reset_epp(device_t);
-void ppc_ecp_sync(device_t);
+int ppc_reset_epp(device_t);
+int ppc_ecp_sync(device_t);
 int ppc_setmode(device_t, int);
 
 extern devclass_t ppc_devclass;


More information about the svn-src-projects mailing list