diff options
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa/gsc/gscbus.c | 291 | ||||
-rw-r--r-- | sys/arch/hppa/gsc/gscbusvar.h | 50 |
2 files changed, 321 insertions, 20 deletions
diff --git a/sys/arch/hppa/gsc/gscbus.c b/sys/arch/hppa/gsc/gscbus.c index 7f6b4723cc2..33826ddb5eb 100644 --- a/sys/arch/hppa/gsc/gscbus.c +++ b/sys/arch/hppa/gsc/gscbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gscbus.c,v 1.1 1998/11/04 17:05:14 mickey Exp $ */ +/* $OpenBSD: gscbus.c,v 1.2 1999/02/25 21:07:48 mickey Exp $ */ /* * Copyright (c) 1998 Michael Shalayeff @@ -30,9 +30,14 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define GSCDEBUG + #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> +#include <sys/malloc.h> +#include <sys/user.h> +#include <sys/mbuf.h> #include <sys/reboot.h> #include <machine/iomod.h> @@ -51,6 +56,26 @@ struct cfdriver gsc_cd = { NULL, "gsc", DV_DULL }; +int gsc_dmamap_create __P((void *, bus_size_t, int, + bus_size_t, bus_size_t, int, bus_dmamap_t *)); +void gsc_dmamap_destroy __P((void *, bus_dmamap_t)); +int gsc_dmamap_load __P((void *, bus_dmamap_t, void *, + bus_size_t, struct proc *, int)); +int gsc_dmamap_load_mbuf __P((void *, bus_dmamap_t, struct mbuf *, int)); +int gsc_dmamap_load_uio __P((void *, bus_dmamap_t, struct uio *, int)); +int gsc_dmamap_load_raw __P((void *, bus_dmamap_t, + bus_dma_segment_t *, int, bus_size_t, int)); +void gsc_dmamap_unload __P((void *, bus_dmamap_t)); +void gsc_dmamap_sync __P((void *, bus_dmamap_t, bus_dmasync_op_t)); + +int gsc_dmamem_alloc __P((void *, bus_size_t, bus_size_t, + bus_size_t, bus_dma_segment_t *, int, int *, int)); +void gsc_dmamem_free __P((void *, bus_dma_segment_t *, int)); +int gsc_dmamem_map __P((void *, bus_dma_segment_t *, + int, size_t, caddr_t *, int)); +void gsc_dmamem_unmap __P((void *, caddr_t, size_t)); +int gsc_dmamem_mmap __P((void *, bus_dma_segment_t *, int, int, int, int)); + int gscmatch(parent, cfdata, aux) struct device *parent; @@ -68,9 +93,269 @@ gscattach(parent, self, aux) struct device *self; void *aux; { - struct gsc_attach_args *ga = aux; + register struct gsc_softc *sc = (struct gsc_softc *)self; + register struct gsc_attach_args *ga = aux; + + sc->sc_iot = ga->ga_iot; + sc->sc_ic = ga->ga_ic; + sc->sc_intrmask = 0; + bzero(sc->sc_intrvs, sizeof(sc->sc_intrvs)); + + printf ("\n"); + + sc->sc_ih = cpu_intr_establish(IPL_HIGH, ga->ga_irq, + gsc_intr, sc, sc->sc_dev.dv_xname); + /* DMA guts */ + sc->sc_dmatag._cookie = sc; + sc->sc_dmatag._dmamap_create = gsc_dmamap_create; + sc->sc_dmatag._dmamap_destroy = gsc_dmamap_destroy; + sc->sc_dmatag._dmamap_load = gsc_dmamap_load; + sc->sc_dmatag._dmamap_load_mbuf = gsc_dmamap_load_mbuf; + sc->sc_dmatag._dmamap_load_uio = gsc_dmamap_load_uio; + sc->sc_dmatag._dmamap_load_raw = gsc_dmamap_load_raw; + sc->sc_dmatag._dmamap_unload = gsc_dmamap_unload; + sc->sc_dmatag._dmamap_sync = gsc_dmamap_sync; - printf("\n"); + sc->sc_dmatag._dmamem_alloc = gsc_dmamem_alloc; + sc->sc_dmatag._dmamem_free = gsc_dmamem_free; + sc->sc_dmatag._dmamem_map = gsc_dmamem_map; + sc->sc_dmatag._dmamem_unmap = gsc_dmamem_unmap; + sc->sc_dmatag._dmamem_mmap = gsc_dmamem_mmap; pdc_scanbus(self, &ga->ga_ca, ga->ga_mod, MAXMODBUS); } + +int +gscprint(aux, pnp) + void *aux; + const char *pnp; +{ + return (UNCONF); +} + + +void * +gsc_intr_establish(sc, pri, irq, handler, arg, name) + struct gsc_softc *sc; + int pri; + int irq; + int (*handler) __P((void *v)); + void *arg; + const char *name; +{ + register struct gscbus_intr *iv; + register u_int32_t mask; + + mask = 1 << irq; + if (sc->sc_intrmask & mask) { +#ifdef GSCDEBUG + printf("%s: attaching irq %d, already occupied\n", + sc->sc_dev.dv_xname, irq); +#endif + return NULL; + } + sc->sc_intrmask |= mask; + iv = &sc->sc_intrvs[irq]; + iv->pri = pri; + iv->handler = handler; + iv->arg = arg; + evcnt_attach(&sc->sc_dev, name, &iv->evcnt); + (sc->sc_ic->gsc_intr_establish)(sc->sc_ic->gsc_dv, mask); +#ifdef GSCDEBUG + printf("gsc_intr_stablish: mask=0x%08x irq=%d iv=%p\n", mask, irq, iv); +#endif + + return &sc->sc_intrvs[irq]; +} + +void +gsc_intr_disestablish(sc, v) + struct gsc_softc *sc; + void *v; +{ + register u_int32_t mask; + + mask = 1 << (sc->sc_intrvs - (struct gscbus_intr *)v); + sc->sc_intrmask &= ~mask; + ((struct gscbus_intr *)v)->handler = NULL; + /* evcnt_detach(); */ + (sc->sc_ic->gsc_intr_disestablish)(sc->sc_ic->gsc_dv, mask); +} + +int +gsc_intr(v) + void *v; +{ + register struct gsc_softc *sc = v; + register struct gscbus_ic *ic = sc->sc_ic; + register u_int32_t mask; + int ret; + +#ifdef GSCDEBUG + printf("gsc_intr(%p)\n", v); +#endif + ret = 0; + while ((mask = (ic->gsc_intr_check)(ic->gsc_dv))) { + register int i; + register struct gscbus_intr *iv; + + i = ffs(mask) - 1; + iv = &sc->sc_intrvs[i]; + +#ifdef GSCDEBUG + printf("gsc_intr: got mask=0x%08x i=%d iv=%p\n", mask, i, iv); +#endif + if (iv->handler) { + int s; +#ifdef GSCDEBUG + printf("gsc_intr: calling %p for irq %d\n", v, i); +#endif + s = splx(iv->pri); + ret += (iv->handler)(iv->arg); + splx(s); + } else + printf("%s: stray interrupt %d\n", + sc->sc_dev.dv_xname, i); + + (ic->gsc_intr_ack)(ic->gsc_dv, 1 << i); + } + + return ret; +} + +int +gsc_dmamap_create(v, size, nseg, maxsegsz, boundary, flags, dmamp) + void *v; + bus_size_t size; + int nseg; + bus_size_t maxsegsz; + bus_size_t boundary; + int flags; + bus_dmamap_t *dmamp; +{ + return 0; +} + +void +gsc_dmamap_destroy(v, map) + void *v; + bus_dmamap_t map; +{ +} + +int +gsc_dmamap_load(v, map, buf, buflen, p, flags) + void *v; + bus_dmamap_t map; + void *buf; + bus_size_t buflen; + struct proc *p; + int flags; +{ + return 0; +} + +int +gsc_dmamap_load_mbuf(v, map, mbuf, flags) + void *v; + bus_dmamap_t map; + struct mbuf *mbuf; + int flags; +{ + return 0; +} + +int +gsc_dmamap_load_uio(v, map, uio, flags) + void *v; + bus_dmamap_t map; + struct uio *uio; + int flags; +{ + return 0; +} + +int +gsc_dmamap_load_raw(v, map, segs, nsegs, size, flags) + void *v; + bus_dmamap_t map; + bus_dma_segment_t *segs; + int nsegs; + bus_size_t size; + int flags; +{ + return 0; +} + +void +gsc_dmamap_unload(v, map) + void *v; + bus_dmamap_t map; +{ + +} + +void +gsc_dmamap_sync(v, map, op) + void *v; + bus_dmamap_t map; + bus_dmasync_op_t op; +{ + +} + +int +gsc_dmamem_alloc(v, size, alignment, boundary, segs, nsegs, rsegs, flags) + void *v; + bus_size_t size; + bus_size_t alignment; + bus_size_t boundary; + bus_dma_segment_t *segs; + int nsegs; + int *rsegs; + int flags; +{ + return 0; +} + +void +gsc_dmamem_free(v, segs, nsegs) + void *v; + bus_dma_segment_t *segs; + int nsegs; +{ + +} + +int +gsc_dmamem_map(v, segs, nsegs, size, kvap, flags) + void *v; + bus_dma_segment_t *segs; + int nsegs; + size_t size; + caddr_t *kvap; + int flags; +{ + return 0; +} + +void +gsc_dmamem_unmap(v, kva, size) + void *v; + caddr_t kva; + size_t size; +{ + +} + +int +gsc_dmamem_mmap(v, segs, nsegs, off, prot, flags) + void *v; + bus_dma_segment_t *segs; + int nsegs; + int off; + int prot; + int flags; +{ + return 0; +} diff --git a/sys/arch/hppa/gsc/gscbusvar.h b/sys/arch/hppa/gsc/gscbusvar.h index df6fb1fd08d..cf210b7fa75 100644 --- a/sys/arch/hppa/gsc/gscbusvar.h +++ b/sys/arch/hppa/gsc/gscbusvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gscbusvar.h,v 1.1 1998/11/04 17:05:15 mickey Exp $ */ +/* $OpenBSD: gscbusvar.h,v 1.2 1999/02/25 21:07:49 mickey Exp $ */ /* * Copyright (c) 1998 Michael Shalayeff @@ -34,34 +34,50 @@ struct gscbus_ic { enum {gsc_unknown = 0, gsc_lasi, gsc_wax, gsc_asp} gsc_type; void *gsc_dv; - void *(*gsc_intr_establish) __P((struct gscbus_ic *ic, int pri, - int (*handler) __P((void *)), void *, - const char *)); - void (*gsc_intr_disestablish) __P((void *v)); - int (*gsc_intack) __P((void *v)); + void (*gsc_intr_establish) __P((void *v, u_int32_t mask)); + void (*gsc_intr_disestablish) __P((void *v, u_int32_t mask)); + u_int32_t (*gsc_intr_check) __P((void *v)); + void (*gsc_intr_ack) __P((void *v, u_int32_t mask)); }; struct gsc_attach_args { struct confargs ga_ca; -#define ga_name ga_ca.ca_name -#define ga_iot ga_ca.ca_iot -#define ga_mod ga_ca.ca_mod -#define ga_type ga_ca.ca_type -#define ga_hpa ga_ca.ca_hpa +#define ga_name ga_ca.ca_name +#define ga_iot ga_ca.ca_iot +#define ga_mod ga_ca.ca_mod +#define ga_type ga_ca.ca_type +#define ga_hpa ga_ca.ca_hpa +#define ga_dmatag ga_ca.ca_dmatag +#define ga_irq ga_ca.ca_irq /*#define ga_pdc_iodc_read ga_ca.ca_pdc_iodc_read */ struct gscbus_ic *ga_ic; /* IC pointer */ }; +struct gscbus_intr { + int pri; + int (*handler) __P((void *)); + void *arg; + struct evcnt evcnt; +}; + struct gsc_softc { struct device sc_dev; + void *sc_ih; bus_space_tag_t sc_iot; struct gscbus_ic *sc_ic; + struct hppa_bus_dma_tag sc_dmatag; + + /* interrupt vectors */ + struct gscbus_intr sc_intrvs[32]; + u_int32_t sc_intrmask; }; -#define gsc_intr_establish(ic,pri,h,c,s) \ - ((ic)->gsc_intr_establish((ic), (pri), (h), (c), (s))) -#define gsc_intr_disestablish(ic,v) \ - (ic)->gsc_intr_disestablish((ic), (v)) -#define gsc_intr_intack(ic,v) \ - ((ic)->gsc_intr_disestablish((ic), (v))) +void *gsc_intr_establish __P((struct gsc_softc *sc, int pri, int irq, + int (*handler) __P((void *v)), void *arg, + const char *name)); +void gsc_intr_disestablish __P((struct gsc_softc *sc, void *v)); +int gsc_intr __P((void *)); + +int gscprint __P((void *, const char *)); + |