summaryrefslogtreecommitdiff
path: root/sys/arch/vax/vsa/vsbus.c
diff options
context:
space:
mode:
authorBrandon Creighton <bjc@cvs.openbsd.org>2000-04-27 00:52:08 +0000
committerBrandon Creighton <bjc@cvs.openbsd.org>2000-04-27 00:52:08 +0000
commite16a128aad347d467be6a1edb2b8e1bede1a01bb (patch)
tree01e64ef20ea8dd7551df226787912d546268068a /sys/arch/vax/vsa/vsbus.c
parent0fa3811974509e434f3ba10d64a560fe329edfc6 (diff)
sync with netbsd; working ncr5380 driver, saner vsbus code
Diffstat (limited to 'sys/arch/vax/vsa/vsbus.c')
-rw-r--r--sys/arch/vax/vsa/vsbus.c755
1 files changed, 233 insertions, 522 deletions
diff --git a/sys/arch/vax/vsa/vsbus.c b/sys/arch/vax/vsa/vsbus.c
index 0137c290cae..d66f4ed6310 100644
--- a/sys/arch/vax/vsa/vsbus.c
+++ b/sys/arch/vax/vsa/vsbus.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: vsbus.c,v 1.3 1997/09/10 12:08:37 maja Exp $ */
-/* $NetBSD: vsbus.c,v 1.6 1997/03/22 23:05:31 ragge Exp $ */
+/* $OpenBSD: vsbus.c,v 1.4 2000/04/27 00:52:07 bjc Exp $ */
+/* $NetBSD: vsbus.c,v 1.20 1999/10/22 21:10:12 ragge Exp $ */
/*
- * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1996, 1999 Ludd, University of Lule}, Sweden.
* All rights reserved.
*
* This code is derived from software contributed to Ludd by Bertram Barth.
@@ -48,6 +48,10 @@
#include <sys/syslog.h>
#include <sys/stat.h>
+#include <vm/vm.h>
+
+#define _VAX_BUS_DMA_PRIVATE
+#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/sid.h>
#include <machine/scb.h>
@@ -57,616 +61,323 @@
#include <machine/uvax.h>
#include <machine/ka410.h>
+#include <machine/ka420.h>
#include <machine/ka43.h>
#include <machine/vsbus.h>
-#define trace(x)
-#define debug(x)
-
-int vsbus_match __P((struct device *, void *, void *));
+int vsbus_match __P((struct device *, struct cfdata *, void *));
void vsbus_attach __P((struct device *, struct device *, void *));
-int vsbus_print __P((void *, const char *));
+int vsbus_print __P((void *, const char *));
+int vsbus_search __P((struct device *, void *, void *));
void ka410_attach __P((struct device *, struct device *, void *));
void ka43_attach __P((struct device *, struct device *, void *));
-struct cfdriver vsbus_cd = {
- NULL, "vsbus", DV_DULL
-};
-struct cfattach vsbus_ca = {
- sizeof(struct device), vsbus_match, vsbus_attach
+struct vax_bus_dma_tag vsbus_bus_dma_tag = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ _bus_dmamap_create,
+ _bus_dmamap_destroy,
+ _bus_dmamap_load,
+ _bus_dmamap_load_mbuf,
+ _bus_dmamap_load_uio,
+ _bus_dmamap_load_raw,
+ _bus_dmamap_unload,
+ _bus_dmamap_sync,
+ _bus_dmamem_alloc,
+ _bus_dmamem_free,
+ _bus_dmamem_map,
+ _bus_dmamem_unmap,
+ _bus_dmamem_mmap,
};
-/*
-void vsbus_intr_register __P((struct confargs *ca, int (*)(void*), void*));
-void vsbus_intr_unregister __P((struct confargs *));
-*/
-
-void vsbus_intr_dispatch __P((int i));
-
-#define VSBUS_MAXDEVS 8
-#define VSBUS_MAXINTR 8
-
-struct confargs *vsbus_devs = NULL;
-
-#ifdef VAX410
-struct confargs ka410_devs[] = {
- /* name intslot intpri intvec intbit ioaddr */
- { "dc", 7, 7, 0x2C0, (1<<7), KA410_SER_BASE,
- 6, 6, 0x2C4, (1<<6), 0x01, },
- { "dc (xmit)", 6, 6, 0x2C4, (1<<6), KA410_SER_BASE, },
- { "le", 5, 5, 0x250, (1<<5), KA410_LAN_BASE,
- KA410_NWA_BASE, 0x00, },
- { "ncr", 1, 1, 0x3F8, (1<<1), KA410_SCS_BASE,
- KA410_SCS_DADR, KA410_SCS_DCNT, KA410_SCS_DDIR,
- KA410_DMA_BASE, KA410_DMA_SIZE, 0x00, 0x07, },
- { "hdc", 0, 0, 0x3FC, (1<<0), KA410_DKC_BASE,
- 0, 0, 0,
- KA410_DMA_BASE, KA410_DMA_SIZE, 0x00, },
-#if 0
- { "dc (recv)", 7, 7, 0x2C0, (1<<7), KA410_SER_BASE, },
- { "dc (xmit)", 6, 6, 0x2C4, (1<<6), KA410_SER_BASE, },
- { "hdc9224", 0, 0, 0x3FC, (1<<0), KA410_DKC_BASE, },
- { "ncr5380", 1, 1, 0x3F8, (1<<1), KA410_SCS_BASE, },
- { "am7990", 5, 5, 0x250, (1<<5), KA410_LAN_BASE, },
- { "NETOPT", 4, 4, 0x254, (1<<4), KA410_LAN_BASE, },
-#endif
- { "" },
+struct cfattach vsbus_ca = {
+ sizeof(struct vsbus_softc), (cfmatch_t)vsbus_match, vsbus_attach
};
-/*
- * It would be better if we could use the (provided) system config
- * information for each CPU instead of this.
- */
-struct confargs ka420_devs[] = {
- { "le", 5, 5, 0x250, (1<<5), KA410_LAN_BASE,
- KA410_NWA_BASE, 0x00, },
- { "ncr", 1, 1, 0x3F8, (1<<1), KA410_SCS_BASE,
- KA410_SCS_DADR, KA410_SCS_DCNT, KA410_SCS_DDIR,
- KA410_DMA_BASE, KA410_DMA_SIZE, 0x00, 0x07, },
- { "ncr", 0, 0, 0x3FC, (1<<0), 0x200C0180,
- 0x200C01A0, 0x200C01C0, 0x200C01C4,
- KA410_DMA_BASE, KA410_DMA_SIZE, 0x00, 0x07, },
- { "" },
+struct cfdriver vsbus_cd = {
+ NULL, "vsbus", DV_DULL
};
-#endif
-#ifdef VAX43
-struct confargs ka43_devs[] = {
- /* name intslot intpri intvec intbit ioaddr */
- { "dc", 7, 7, 0x2C0, (1<<7), KA43_SER_BASE,
- 6, 6, 0x2C4, (1<<6), 0x01, },
- { "dc (xmit)", 6, 6, 0x2C4, (1<<6), KA43_SER_BASE, },
- { "le", 5, 5, 0x250, (1<<5), KA43_LAN_BASE,
- KA43_NWA_BASE, 0x00, },
- { "ncr", 1, 1, 0x3F8, (1<<1), KA43_SC1_BASE,
- KA43_SC1_DADR, KA43_SC1_DCNT, KA43_SC1_DDIR,
- KA43_DMA_BASE, KA43_DMA_SIZE, 0x01, 0x06, },
- { "ncr", 0, 0, 0x3FC, (1<<0), KA43_SC2_BASE,
- KA43_SC2_DADR, KA43_SC2_DCNT, KA43_SC2_DDIR,
- KA43_DMA_BASE, KA43_DMA_SIZE, 0x01, 0x06, },
-#if 0
- { "le (2nd)", 4, 4, 0x254, (1<<4), 0x???, },
- { "NETOPT", 4, 4, 0x254, (1<<4), 0x???, },
-#endif
- { "" },
-};
-#endif
+/* dummy interrupt handler for use during autoconf */
+void
+vsbus_intr(arg)
+ void *arg;
+{
+ return;
+}
int
vsbus_print(aux, name)
void *aux;
const char *name;
{
- struct confargs *ca = aux;
-
- trace(("vsbus_print(%x, %s)\n", ca->ca_name, name));
+ struct vsbus_attach_args *va = aux;
- if (name) {
- printf ("device %s at %s", ca->ca_name, name);
- return (UNSUPP);
- }
- return (UNCONF);
+ printf(" csr 0x%lx vec 0x%x ipl %x maskbit %d", va->va_paddr,
+ va->va_cvec & 511, va->va_br, va->va_maskno - 1);
+ return(UNCONF);
}
int
vsbus_match(parent, cf, aux)
struct device *parent;
- void *cf;
+ struct cfdata *cf;
void *aux;
{
- struct bp_conf *bp = aux;
-
- trace(("vsbus_match: bp->type = \"%s\"\n", bp->type));
-
- if (strcmp(bp->type, "vsbus"))
- return 0;
- /*
- * on machines which can have it, the vsbus is always there
- */
- if ((vax_bustype & VAX_VSBUS) == 0)
- return (0);
-
- return (1);
-}
-
-#if 1 /*------------------------------------------------------------*/
-#if 1
-#define REG(name) short name; short X##name##X;
-#else
-#define REG(name) int name;
-#endif
-static volatile struct {/* base address of DZ-controller: 0x200A0000 */
- REG(csr); /* 00 Csr: control/status register */
- REG(rbuf); /* 04 Rbuf/Lpr: receive buffer/line param reg. */
- REG(tcr); /* 08 Tcr: transmit console register */
- REG(tdr); /* 0C Msr/Tdr: modem status reg/transmit data reg */
- REG(lpr0); /* 10 Lpr0: */
- REG(lpr1); /* 14 Lpr0: */
- REG(lpr2); /* 18 Lpr0: */
- REG(lpr3); /* 1C Lpr0: */
-} *dz = (void*)0x200A0000;
-extern int dzcnrint();
-extern int dzcntint();
-int hardclock_count = 0;
-int
-ka410_consintr_enable()
-{
- vsbus_intr_enable(&ka410_devs[0]);
- vsbus_intr_enable(&ka410_devs[1]);
-}
-
-int
-ka410_consRecv_intr(p)
- void *p;
-{
- /* printf("ka410_consRecv_intr: hc-count=%d\n", hardclock_count); */
- dzcnrint();
- /* printf("gencnrint() returned.\n"); */
- return(0);
-}
-
-int
-ka410_consXmit_intr(p)
- void *p;
-{
- /* printf("ka410_consXmit_intr: hc-count=%d\n", hardclock_count); */
- dzcntint();
- /* printf("gencntint() returned.\n"); */
- return(0);
+ if (vax_bustype == VAX_VSBUS)
+ return 1;
+ return 0;
}
-#endif /*------------------------------------------------------------*/
void
vsbus_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct confargs *ca;
- int i;
+ struct vsbus_softc *sc = (void *)self;
+ int discard;
+ vaddr_t temp;
printf("\n");
- trace (("vsbus_attach()\n"));
switch (vax_boardtype) {
- case VAX_BTYP_420:
- vsbus_devs = ka420_devs;
- break;
-
- case VAX_BTYP_410:
- vsbus_devs = ka410_devs;
- break;
-
- case VAX_BTYP_43:
- case VAX_BTYP_46:
case VAX_BTYP_49:
-#ifdef VAX43
- vsbus_devs = ka43_devs;
-#endif
+ temp = vax_map_physmem(0x25c00000, 1);
+ sc->sc_intreq = (char *)temp + 12;
+ sc->sc_intclr = (char *)temp + 12;
+ sc->sc_intmsk = (char *)temp + 8;
break;
default:
- printf ("unsupported boardtype 0x%x in vsbus_attach()\n",
- vax_boardtype);
- return;
+ temp = vax_map_physmem(VS_REGS, 1);
+ sc->sc_intreq = (char *)temp + 15;
+ sc->sc_intclr = (char *)temp + 15;
+ sc->sc_intmsk = (char *)temp + 12;
+ break;
}
/*
- * first setup interrupt-table, so that devices can register
- * their interrupt-routines...
+ * First: find which interrupts we won't care about.
+ * There are interrupts that interrupt on a periodic basic
+ * that we don't want to interfere with the rest of the
+ * interrupt probing.
*/
- vsbus_intr_setup();
+ *sc->sc_intmsk = 0;
+ *sc->sc_intclr = 0xff;
+ DELAY(1000000); /* Wait a second */
+ sc->sc_mask = discard = *sc->sc_intreq;
+ printf("%s: interrupt mask %x\n", self->dv_xname, discard);
/*
* now check for all possible devices on this "bus"
*/
- for (i=0; i<VSBUS_MAXDEVS; i++) {
- ca = &vsbus_devs[i];
- if (*ca->ca_name == '\0')
- break;
- config_found(self, (void*)ca, vsbus_print);
- }
+ config_search(vsbus_search, self, NULL);
- /*
- * as long as there's no working DZ-driver, we use this dummy
- */
- vsbus_intr_register(&ka410_devs[0], ka410_consRecv_intr, NULL);
- vsbus_intr_register(&ka410_devs[1], ka410_consXmit_intr, NULL);
+ *sc->sc_intmsk = sc->sc_mask ^ discard;
}
-#define VSBUS_MAX_INTR 8 /* 64? */
-/*
- * interrupt service routines are given an int as argument, which is
- * pushed onto stack as LITERAL. Thus the value is between 0-63.
- * This array of 64 might be oversized for now, but it's all which
- * ever will be possible.
- */
-struct vsbus_ivec {
- struct ivec_dsp intr_vec; /* this is referenced in SCB */
- int intr_count; /* keep track of interrupts */
- int intr_flags; /* valid, etc. */
- void (*enab)(int); /* enable interrupt */
- void (*disab)(int); /* disable interrupt */
- void (*prep)(int); /* need pre-processing? */
- int (*handler)(void*); /* isr-routine to call */
- void *hndlarg; /* args to this routine */
- void (*postp)(int); /* need post-processing? */
-} vsbus_ivtab[VSBUS_MAX_INTR];
-
-/*
- *
- */
int
-vsbus_intr_setup()
+vsbus_search(parent, cfd, aux)
+ struct device *parent;
+ void *cfd;
+ void *aux;
{
- int i;
- struct vsbus_ivec *ip;
- extern struct ivec_dsp idsptch; /* subr.s */
-
- for (i=0; i<VSBUS_MAX_INTR; i++) {
- ip = &vsbus_ivtab[i];
- bcopy(&idsptch, &ip->intr_vec, sizeof(struct ivec_dsp));
- ip->intr_vec.pushlarg = i;
- ip->intr_vec.hoppaddr = vsbus_intr_dispatch;
- ip->intr_count = 0;
- ip->intr_flags = 0;
- ip->enab = NULL;
- ip->disab = NULL;
- ip->postp = NULL;
- }
- switch (vax_boardtype) {
- case VAX_BTYP_410:
- case VAX_BTYP_420:
- case VAX_BTYP_43:
- case VAX_BTYP_46:
- case VAX_BTYP_49:
- ka410_intr_setup();
- return(0);
- default:
- printf("unsupported board-type 0x%x in vsbus_intr_setup()\n",
- vax_boardtype);
- return(1);
- }
+ struct vsbus_softc *sc = (void *)parent;
+ struct vsbus_attach_args va;
+ struct cfdata *cf = cfd;
+ int i, vec, br;
+ u_char c;
+
+ va.va_paddr = cf->cf_loc[0];
+ va.va_addr = vax_map_physmem(va.va_paddr, 1);
+ va.va_dmat = &vsbus_bus_dma_tag;
+
+ *sc->sc_intmsk = 0;
+ *sc->sc_intclr = 0xff;
+ scb_vecref(0, 0); /* Clear vector ref */
+
+ va.va_ivec = vsbus_intr;
+ i = (*cf->cf_attach->ca_match) (parent, cf, &va);
+ vax_unmap_physmem(va.va_addr, 1);
+ c = *sc->sc_intreq & ~sc->sc_mask;
+ if (i == 0)
+ goto forgetit;
+ if (i > 10)
+ c = sc->sc_mask; /* Fooling interrupt */
+ else if (c == 0)
+ goto forgetit;
+
+ va.va_maskno = ffs((u_int)c);
+
+ *sc->sc_intmsk = c;
+ DELAY(1000);
+ *sc->sc_intmsk = 0;
+
+ i = scb_vecref(&vec, &br);
+ if (i == 0)
+ goto fail;
+ if (vec == 0)
+ goto fail;
+
+ scb_vecalloc(vec, va.va_ivec, va.va_vecarg, SCB_ISTACK);
+ va.va_br = br;
+ va.va_cvec = vec;
+ va.confargs = aux;
+
+ config_attach(parent, cf, &va, vsbus_print);
+ return 1;
+
+fail:
+ printf("%s%d at %s csr %x %s\n",
+ cf->cf_driver->cd_name, cf->cf_unit, parent->dv_xname,
+ cf->cf_loc[0], (i ? "zero vector" : "didn't interrupt"));
+forgetit:
+ return 0;
}
-int
-vsbus_intr_register(ca, handler, arg)
- struct confargs *ca;
- int (*handler)(void*);
- void *arg;
-{
- /* struct device *dev = arg; */
- int i = ca->ca_intslot;
- struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
- trace (("vsbus_intr_register(%s/%d)\n", ca->ca_name, ca->ca_intslot));
-
- ip->handler = handler;
- ip->hndlarg = arg;
-}
+static volatile struct dma_lock {
+ int dl_locked;
+ int dl_wanted;
+ void *dl_owner;
+ int dl_count;
+} dmalock = { 0, 0, NULL, 0 };
int
-vsbus_intr_enable(ca)
- struct confargs *ca;
+vsbus_lockDMA(ca)
+ struct confargs *ca;
{
- int i = ca->ca_intslot;
- struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
- trace (("vsbus_intr_enable(%s/%d)\n", ca->ca_name, ca->ca_intslot));
+ while (dmalock.dl_locked) {
+ dmalock.dl_wanted++;
+ sleep((caddr_t)&dmalock, PRIBIO); /* PLOCK or PRIBIO ? */
+ dmalock.dl_wanted--;
+ }
+ dmalock.dl_locked++;
+ dmalock.dl_owner = ca;
+
+ /*
+ * no checks yet, no timeouts, nothing...
+ */
- /* XXX check for valid handler etc. !!! */
- if (ip->handler == NULL) {
- printf("interrupts for \"%s\"(%d) not enabled: null-handler\n",
- ca->ca_name, ca->ca_intslot);
- return;
- }
-
- ip->enab(i);
+#ifdef DEBUG
+ if ((++dmalock.dl_count % 1000) == 0)
+ printf("%d locks, owner: %s\n", dmalock.dl_count, ca->ca_name);
+#endif
+ return (0);
}
int
-vsbus_intr_disable(ca)
- struct confargs *ca;
+vsbus_unlockDMA(ca)
+ struct confargs *ca;
{
- int i = ca->ca_intslot;
- struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
- trace (("vsbus_intr_disable(%s/%d)\n", ca->ca_name, i));
-
- ip->disab(i);
+ if (dmalock.dl_locked != 1 || dmalock.dl_owner != ca) {
+ printf("locking-problem: %d, %s\n", dmalock.dl_locked,
+ (dmalock.dl_owner ? dmalock.dl_owner : "null"));
+ dmalock.dl_locked = 0;
+ return (-1);
+ }
+ dmalock.dl_owner = NULL;
+ dmalock.dl_locked = 0;
+ if (dmalock.dl_wanted) {
+ wakeup((caddr_t)&dmalock);
+ }
+ return (0);
}
-int
-vsbus_intr_unregister(ca)
- struct confargs *ca;
-{
- int i = ca->ca_intslot;
- struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
- trace (("vsbus_intr_unregister(%s/%d)\n", ca->ca_name, i));
-
- ip->handler = NULL;
- ip->hndlarg = NULL;
-}
-
-void
-vsbus_intr_dispatch(i)
- register int i;
-{
- register struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
- trace (("vsbus_intr_dispatch(%d)", i));
-
- if (i < VSBUS_MAX_INTR && ip->handler != NULL) {
- ip->intr_count++;
- debug (("intr-count[%d] = %d\n", i, ip->intr_count));
- (ip->handler)(ip->hndlarg);
- if (ip->postp)
- (ip->postp)(i);
- return;
- }
-
- if (i < 0 || i >= VSBUS_MAX_INTR) {
- printf ("stray interrupt %d on vsbus.\n", i);
- return;
- }
-
- if (!ip->handler) {
- printf ("unhandled interrupt %d on vsbus.\n", i);
- return;
- }
-}
/*
- * These addresses are invalid and will be updated/corrected by
- * ka410_intr_setup(), but having them this way helps debugging
+ * Sets a new interrupt mask. Returns the old one.
+ * Works like spl functions.
*/
-static volatile u_char *ka410_intmsk = (void*)KA410_INTMSK;
-static volatile u_char *ka410_intreq = (void*)KA410_INTREQ;
-static volatile u_char *ka410_intclr = (void*)KA410_INTCLR;
-
-static void
-ka410_intr_enable(i)
- int i;
+unsigned char
+vsbus_setmask(mask)
+ unsigned char mask;
{
- trace (("ka410_intr_enable(%d)\n", i));
- *ka410_intmsk |= (1<<i);
-}
-
-static void
-ka410_intr_disable(i)
- int i;
-{
- trace (("ka410_intr_disable(%d)\n", i));
- *ka410_intmsk &= ~(1<<i);
-}
+ struct vsbus_softc *sc = vsbus_cd.cd_devs[0];
+ unsigned char ch;
-static void
-ka410_intr_clear(i)
- int i;
-{
- trace (("ka410_intr_clear(%d)\n", i));
- *ka410_intclr = (1<<i);
-}
-
-ka410_intr_setup()
-{
- int i;
- struct vsbus_ivec *ip;
- void **scbP = (void*)scb;
-
- trace (("ka410_intr_setup()\n"));
-
- ka410_intmsk = (void*)uvax_phys2virt(KA410_INTMSK);
- ka410_intreq = (void*)uvax_phys2virt(KA410_INTREQ);
- ka410_intclr = (void*)uvax_phys2virt(KA410_INTCLR);
-
- *ka410_intmsk = 0; /* disable all interrupts */
- *ka410_intclr = 0xFF; /* clear all old interrupts */
-
- /*
- * insert the VS2000-specific routines into ivec-table...
- */
- for (i=0; i<8; i++) {
- ip = &vsbus_ivtab[i];
- ip->enab = ka410_intr_enable;
- ip->disab = ka410_intr_disable;
- /* ip->postp = ka410_intr_clear; bertram XXX */
- }
- /*
- * ...and register the interrupt-vectors in SCB
- */
- scbP[IVEC_DC/4] = &vsbus_ivtab[0].intr_vec;
- scbP[IVEC_SC/4] = &vsbus_ivtab[1].intr_vec;
- scbP[IVEC_VS/4] = &vsbus_ivtab[2].intr_vec;
- scbP[IVEC_VF/4] = &vsbus_ivtab[3].intr_vec;
- scbP[IVEC_NS/4] = &vsbus_ivtab[4].intr_vec;
- scbP[IVEC_NP/4] = &vsbus_ivtab[5].intr_vec;
- scbP[IVEC_ST/4] = &vsbus_ivtab[6].intr_vec;
- scbP[IVEC_SR/4] = &vsbus_ivtab[7].intr_vec;
+ ch = *sc->sc_intmsk;
+ *sc->sc_intmsk = mask;
+ return ch;
}
/*
- *
- *
+ * Clears the interrupts in mask.
*/
-
-static volatile struct dma_lock {
- int dl_locked;
- int dl_wanted;
- void *dl_owner;
- int dl_count;
-} dmalock = { 0, 0, NULL, 0 };
-
-int
-vsbus_lockDMA(ca)
- struct confargs *ca;
+void
+vsbus_clrintr(mask)
+ unsigned char mask;
{
- while (dmalock.dl_locked) {
- dmalock.dl_wanted++;
- sleep((caddr_t)&dmalock, PRIBIO); /* PLOCK or PRIBIO ? */
- dmalock.dl_wanted--;
- }
- dmalock.dl_locked++;
- dmalock.dl_owner = ca;
-
- /*
- * no checks yet, no timeouts, nothing...
- */
-
-#ifdef DEBUG
- if ((++dmalock.dl_count % 1000) == 0)
- printf("%d locks, owner: %s\n", dmalock.dl_count, ca->ca_name);
-#endif
- return (0);
-}
+ struct vsbus_softc *sc = vsbus_cd.cd_devs[0];
-int
-vsbus_unlockDMA(ca)
- struct confargs *ca;
-{
- if (dmalock.dl_locked != 1 || dmalock.dl_owner != ca) {
- printf("locking-problem: %d, %s\n", dmalock.dl_locked,
- (dmalock.dl_owner ? dmalock.dl_owner : "null"));
- dmalock.dl_locked = 0;
- return (-1);
- }
- dmalock.dl_owner = NULL;
- dmalock.dl_locked = 0;
- if (dmalock.dl_wanted) {
- wakeup((caddr_t)&dmalock);
- }
- return (0);
+ *sc->sc_intclr = mask;
}
-/*----------------------------------------------------------------------*/
-#if 0
/*
- * small set of routines needed for mapping when doing pseudo-DMA,
- * quasi-DMA or virtual-DMA (choose whatever name you like).
- *
- * Once I know how VS3100 is doing real DMA (I hope it does), this
- * should be rewritten to present a general interface...
- *
+ * Copy data from/to a user process' space from the DMA area.
+ * Use the physical memory directly.
*/
-
-extern u_long uVAX_physmap;
-
-u_long
-vsdma_mapin(bp, len)
- struct buf *bp;
+void
+vsbus_copytoproc(p, from, to, len)
+ struct proc *p;
+ caddr_t from, to;
int len;
{
- pt_entry_t *pte; /* pointer to Page-Table-Entry */
- struct pcb *pcb; /* pointer to Process-Controll-Block */
- pt_entry_t *xpte;
- caddr_t addr;
- int pgoff; /* offset into 1st page */
- int pgcnt; /* number of pages needed */
- int pfnum;
- int i;
-
- trace(("mapin(bp=%x, bp->data=%x)\n", bp, bp->b_data));
-
- addr = bp->b_data;
- pgoff = (int)bp->b_data & PGOFSET; /* get starting offset */
- pgcnt = btoc(bp->b_bcount + pgoff) + 1; /* one more than needed */
-
- /*
- * Get a pointer to the pte pointing out the first virtual address.
- * Use different ways in kernel and user space.
- */
- if ((bp->b_flags & B_PHYS) == 0) {
- pte = kvtopte(addr);
- } else {
- pcb = bp->b_proc->p_vmspace->vm_pmap.pm_pcb;
- pte = uvtopte(addr, pcb);
+ struct pte *pte;
+ paddr_t pa;
+
+ pte = uvtopte(TRUNC_PAGE(to), (&p->p_addr->u_pcb));
+ if ((vaddr_t)to & PGOFSET) {
+ int cz = ROUND_PAGE(to) - (vaddr_t)to;
+
+ pa = (pte->pg_pfn << VAX_PGSHIFT) | (NBPG - cz) | KERNBASE;
+ bcopy(from, (caddr_t)pa, min(cz, len));
+ from += cz;
+ to += cz;
+ len -= cz;
+ pte += 8; /* XXX */
}
-
- /*
- * When we are doing DMA to user space, be sure that all pages
- * we want to transfer to are mapped. WHY DO WE NEED THIS???
- * SHOULDN'T THEY ALWAYS BE MAPPED WHEN DOING THIS???
- */
- for (i=0; i<(pgcnt-1); i++) {
- if ((pte + i)->pg_pfn == 0) {
- int rv;
- rv = vm_fault(&bp->b_proc->p_vmspace->vm_map,
- (unsigned)addr + i * NBPG,
- VM_PROT_READ|VM_PROT_WRITE, FALSE);
- if (rv)
- panic("vs-DMA to nonexistent page, %d", rv);
- }
- }
-
- /*
- * now insert new mappings for this memory area into kernel's
- * mapping-table
- */
- xpte = kvtopte(uVAX_physmap);
- while (--pgcnt > 0) {
- pfnum = pte->pg_pfn;
- if (pfnum == 0)
- panic("vsbus: zero entry");
- *(int *)xpte++ = *(int *)pte++;
+ while (len > 0) {
+ pa = (pte->pg_pfn << VAX_PGSHIFT) | KERNBASE;
+ bcopy(from, (caddr_t)pa, min(NBPG, len));
+ from += NBPG;
+ to += NBPG;
+ len -= NBPG;
+ pte += 8; /* XXX */
}
- *(int *)xpte = 0; /* mark last mapped page as invalid! */
-
- debug(("uVAX: 0x%x\n", uVAX_physmap + pgoff));
-
- return (uVAX_physmap + pgoff); /* ??? */
}
-#endif
-/*----------------------------------------------------------------------*/
-/*
- * Here follows some currently(?) unused stuff. Someday this should be removed
- */
-#if 0
-/*
- * Configure devices on VS2000/KA410 directly attached to vsbus
- */
void
-ka410_attach(parent, self, aux)
- struct device *parent;
- struct device *self;
- void *aux;
+vsbus_copyfromproc(p, from, to, len)
+ struct proc *p;
+ caddr_t from, to;
+ int len;
{
- struct confargs *ca;
- int i;
-
- for (i=0; i<KA410_MAXDEVS; i++) {
- ca = &ka410_devs[i];
- if (*ca->ca_name == '\0')
- break;
- config_found(self, (void*)ca, vsbus_print);
+ struct pte *pte;
+ paddr_t pa;
+
+ pte = uvtopte(TRUNC_PAGE(from), (&p->p_addr->u_pcb));
+ if ((vaddr_t)from & PGOFSET) {
+ int cz = ROUND_PAGE(from) - (vaddr_t)from;
+
+ pa = (pte->pg_pfn << VAX_PGSHIFT) | (NBPG - cz) | KERNBASE;
+ bcopy((caddr_t)pa, to, min(cz, len));
+ from += cz;
+ to += cz;
+ len -= cz;
+ pte += 8; /* XXX */
+ }
+ while (len > 0) {
+ pa = (pte->pg_pfn << VAX_PGSHIFT) | KERNBASE;
+ bcopy((caddr_t)pa, to, min(NBPG, len));
+ from += NBPG;
+ to += NBPG;
+ len -= NBPG;
+ pte += 8; /* XXX */
}
- /*
- * as long as there's no real DZ-driver, we used this dummy
- */
- vsbus_intr_register(&ka410_devs[0], ka410_consRecv_intr, NULL);
- vsbus_intr_register(&ka410_devs[1], ka410_consXmit_intr, NULL);
}
-
-#endif