summaryrefslogtreecommitdiff
path: root/sys/arch/vax/vsa/vsbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/vax/vsa/vsbus.c')
-rw-r--r--sys/arch/vax/vsa/vsbus.c169
1 files changed, 61 insertions, 108 deletions
diff --git a/sys/arch/vax/vsa/vsbus.c b/sys/arch/vax/vsa/vsbus.c
index 6e2df6f4a8b..43e18bf8584 100644
--- a/sys/arch/vax/vsa/vsbus.c
+++ b/sys/arch/vax/vsa/vsbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vsbus.c,v 1.5 2000/10/11 06:19:19 bjc Exp $ */
+/* $OpenBSD: vsbus.c,v 1.6 2001/02/11 06:34:38 hugh Exp $ */
/* $NetBSD: vsbus.c,v 1.29 2000/06/29 07:14:37 mrg Exp $ */
/*
* Copyright (c) 1996, 1999 Ludd, University of Lule}, Sweden.
@@ -51,7 +51,7 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
-#define _VAX_BUS_DMA_PRIVATE
+#define _VAX_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/sid.h>
@@ -67,15 +67,15 @@
#include <machine/vsbus.h>
-int vsbus_match __P((struct device *, struct cfdata *, 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_search __P((struct device *, void *, void *));
+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 vax_bus_dma_tag vsbus_bus_dma_tag = {
+static struct vax_bus_dma_tag vsbus_bus_dma_tag = {
0,
0,
0,
@@ -131,9 +131,14 @@ vsbus_print(aux, name)
int
vsbus_match(parent, cf, aux)
struct device *parent;
- struct cfdata *cf;
+ struct cfdata *cf;
void *aux;
{
+#if VAX53
+ /* Kludge: VAX53 is... special */
+ if (vax_boardtype == VAX_BTYP_1303 && (int)aux == 1)
+ return 1; /* Hack */
+#endif
if (vax_bustype == VAX_VSBUS)
return 1;
return 0;
@@ -146,14 +151,14 @@ vsbus_attach(parent, self, aux)
{
struct vsbus_softc *sc = (void *)self;
int dbase, dsize;
- int discard;
printf("\n");
sc->sc_dmatag = vsbus_bus_dma_tag;
switch (vax_boardtype) {
-#if VAX49
+#if VAX49 || VAX53
+ case VAX_BTYP_1303:
case VAX_BTYP_49:
sc->sc_vsregs = vax_map_physmem(0x25c00000, 1);
sc->sc_intreq = (char *)sc->sc_vsregs + 12;
@@ -164,16 +169,15 @@ vsbus_attach(parent, self, aux)
#endif
#if VAX46 || VAX48
- case VAX_BTYP_48:
- case VAX_BTYP_46:
- sc->sc_vsregs = vax_map_physmem(VS_REGS, 1);
- sc->sc_intreq = (char *)sc->sc_vsregs + 15;
- sc->sc_intclr = (char *)sc->sc_vsregs + 15;
- sc->sc_intmsk = (char *)sc->sc_vsregs + 12;
- vsbus_dma_init(sc, 32768);
+ case VAX_BTYP_48:
+ case VAX_BTYP_46:
+ sc->sc_vsregs = vax_map_physmem(VS_REGS, 1);
+ sc->sc_intreq = (char *)sc->sc_vsregs + 15;
+ sc->sc_intclr = (char *)sc->sc_vsregs + 15;
+ sc->sc_intmsk = (char *)sc->sc_vsregs + 12;
+ vsbus_dma_init(sc, 32768);
#endif
-
default:
sc->sc_vsregs = vax_map_physmem(VS_REGS, 1);
sc->sc_intreq = (char *)sc->sc_vsregs + 15;
@@ -203,28 +207,28 @@ vsbus_attach(parent, self, aux)
*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);
-
+ sc->sc_mask = *sc->sc_intreq;
+ printf("%s: interrupt mask %x\n", self->dv_xname, sc->sc_mask);
/*
* now check for all possible devices on this "bus"
*/
config_search(vsbus_search, self, NULL);
- *sc->sc_intmsk = sc->sc_mask ^ discard;
+ /* Autoconfig finished, enable interrupts */
+ *sc->sc_intmsk = ~sc->sc_mask;
}
int
vsbus_search(parent, cfd, aux)
- struct device *parent;
- void *cfd;
- void *aux;
+ struct device *parent;
+ void *cfd;
+ void *aux;
{
- struct vsbus_softc *sc = (void *)parent;
- struct vsbus_attach_args va;
- struct cfdata *cf = cfd;
- int i, vec, br;
- u_char c;
+ 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);
@@ -235,10 +239,10 @@ vsbus_search(parent, cfd, aux)
*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)
@@ -246,87 +250,33 @@ vsbus_search(parent, cfd, aux)
else if (c == 0)
goto forgetit;
- va.va_maskno = ffs((u_int)c);
-
*sc->sc_intmsk = c;
DELAY(1000);
*sc->sc_intmsk = 0;
-
+ va.va_maskno = ffs((u_int)c);
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;
va.va_dmaaddr = sc->sc_dmaaddr;
va.va_dmasize = sc->sc_dmasize;
-
+ *sc->sc_intmsk = c; /* Allow interrupts during attach */
config_attach(parent, cf, &va, vsbus_print);
- return 1;
+ *sc->sc_intmsk = 0;
+ return 0;
fail:
- printf("%s%d at %s csr %x %s\n",
+ printf("%s%d at %s csr 0x%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;
}
-#if 0
-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;
-{
- 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);
-}
-
-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);
-}
-#endif
-
-
/*
* Sets a new interrupt mask. Returns the old one.
* Works like spl functions.
@@ -335,9 +285,13 @@ unsigned char
vsbus_setmask(mask)
unsigned char mask;
{
- struct vsbus_softc *sc = vsbus_cd.cd_devs[0];
+ struct vsbus_softc *sc;
unsigned char ch;
+ if (vsbus_cd.cd_ndevs == 0)
+ return 0;
+ sc = vsbus_cd.cd_devs[0];
+
ch = *sc->sc_intmsk;
*sc->sc_intmsk = mask;
return ch;
@@ -350,7 +304,11 @@ void
vsbus_clrintr(mask)
unsigned char mask;
{
- struct vsbus_softc *sc = vsbus_cd.cd_devs[0];
+ struct vsbus_softc *sc;
+
+ if (vsbus_cd.cd_ndevs == 0)
+ return;
+ sc = vsbus_cd.cd_devs[0];
*sc->sc_intclr = mask;
}
@@ -360,18 +318,15 @@ vsbus_clrintr(mask)
* Use the physical memory directly.
*/
void
-vsbus_copytoproc(p, from, to, len)
- struct proc *p;
- caddr_t from, to;
- int len;
+vsbus_copytoproc(struct proc *p, caddr_t from, caddr_t to, int len)
{
struct pte *pte;
paddr_t pa;
- if ((long)to & KERNBASE) { /* In kernel space */
- bcopy(from, to, len);
- return;
- }
+ if ((vaddr_t)to & KERNBASE) { /* In kernel space */
+ bcopy(from, to, len);
+ return;
+ }
pte = uvtopte(TRUNC_PAGE(to), (&p->p_addr->u_pcb));
if ((vaddr_t)to & PGOFSET) {
int cz = ROUND_PAGE(to) - (vaddr_t)to;
@@ -394,18 +349,15 @@ vsbus_copytoproc(p, from, to, len)
}
void
-vsbus_copyfromproc(p, from, to, len)
- struct proc *p;
- caddr_t from, to;
- int len;
+vsbus_copyfromproc(struct proc *p, caddr_t from, caddr_t to, int len)
{
struct pte *pte;
paddr_t pa;
- if ((long)from & KERNBASE) { /* In kernel space */
- bcopy(from, to, len);
- return;
- }
+ if ((vaddr_t)from & KERNBASE) { /* In kernel space */
+ bcopy(from, to, len);
+ return;
+ }
pte = uvtopte(TRUNC_PAGE(from), (&p->p_addr->u_pcb));
if ((vaddr_t)from & PGOFSET) {
int cz = ROUND_PAGE(from) - (vaddr_t)from;
@@ -436,6 +388,7 @@ static int vsbus_active = 0;
void
vsbus_dma_start(struct vsbus_dma *vd)
{
+
SIMPLEQ_INSERT_TAIL(&vsbus_dma, vd, vd_q);
if (vsbus_active == 0)