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