Date: Sat, 28 Feb 2009 17:57:21 +0000 (UTC) From: John Birrell <jb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r189183 - projects/jbuild/sys/dev/ppc Message-ID: <200902281757.n1SHvLJC017185@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902281757.n1SHvLJC017185>