summaryrefslogtreecommitdiff
path: root/sys/arch/sparc/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sparc/dev')
-rw-r--r--sys/arch/sparc/dev/amd7930.c5
-rw-r--r--sys/arch/sparc/dev/amd7930var.h1
-rw-r--r--sys/arch/sparc/dev/bt_subr.c1
-rw-r--r--sys/arch/sparc/dev/btreg.h1
-rw-r--r--sys/arch/sparc/dev/btvar.h1
-rw-r--r--sys/arch/sparc/dev/bwtwo.c45
-rw-r--r--sys/arch/sparc/dev/bwtworeg.h1
-rw-r--r--sys/arch/sparc/dev/cgeight.c30
-rw-r--r--sys/arch/sparc/dev/cgeightreg.h55
-rw-r--r--sys/arch/sparc/dev/cgfour.c30
-rw-r--r--sys/arch/sparc/dev/cgfourteen.c877
-rw-r--r--sys/arch/sparc/dev/cgfourteenreg.h123
-rw-r--r--sys/arch/sparc/dev/cgfourteenvar.h94
-rw-r--r--sys/arch/sparc/dev/cgsix.c44
-rw-r--r--sys/arch/sparc/dev/cgsixreg.h1
-rw-r--r--sys/arch/sparc/dev/cgthree.c47
-rw-r--r--sys/arch/sparc/dev/cgthreereg.h1
-rw-r--r--sys/arch/sparc/dev/cgtwo.c28
-rw-r--r--sys/arch/sparc/dev/cons.c29
-rw-r--r--sys/arch/sparc/dev/dma.c230
-rw-r--r--sys/arch/sparc/dev/dmareg.h14
-rw-r--r--sys/arch/sparc/dev/dmavar.h32
-rw-r--r--sys/arch/sparc/dev/esp.c1913
-rw-r--r--sys/arch/sparc/dev/espreg.h148
-rw-r--r--sys/arch/sparc/dev/espvar.h271
-rw-r--r--sys/arch/sparc/dev/event.c171
-rw-r--r--sys/arch/sparc/dev/event_var.h87
-rw-r--r--sys/arch/sparc/dev/fb.c38
-rw-r--r--sys/arch/sparc/dev/fd.c5
-rw-r--r--sys/arch/sparc/dev/i82586.h1
-rw-r--r--sys/arch/sparc/dev/if_en_sbus.c6
-rw-r--r--sys/arch/sparc/dev/if_ie.c48
-rw-r--r--sys/arch/sparc/dev/if_ie.h1
-rw-r--r--sys/arch/sparc/dev/if_le.c378
-rw-r--r--sys/arch/sparc/dev/if_lereg.h1
-rw-r--r--sys/arch/sparc/dev/if_levar.h6
-rw-r--r--sys/arch/sparc/dev/isp_sbus.c331
-rw-r--r--sys/arch/sparc/dev/kbd.c8
-rw-r--r--sys/arch/sparc/dev/lebuffer.c143
-rw-r--r--sys/arch/sparc/dev/lebuffervar.h (renamed from sys/arch/sparc/dev/cgfourreg.h)39
-rw-r--r--sys/arch/sparc/dev/ms.c12
-rw-r--r--sys/arch/sparc/dev/obio.c266
-rw-r--r--sys/arch/sparc/dev/pfour.c2
-rw-r--r--sys/arch/sparc/dev/pfourreg.h1
-rw-r--r--sys/arch/sparc/dev/power.c4
-rw-r--r--sys/arch/sparc/dev/rcons_font.h1
-rw-r--r--sys/arch/sparc/dev/sbus.c36
-rw-r--r--sys/arch/sparc/dev/sbusreg.h1
-rw-r--r--sys/arch/sparc/dev/sbusvar.h1
-rw-r--r--sys/arch/sparc/dev/si.c114
-rw-r--r--sys/arch/sparc/dev/sireg.h1
-rw-r--r--sys/arch/sparc/dev/tcx.c496
-rw-r--r--sys/arch/sparc/dev/tcxreg.h151
-rw-r--r--sys/arch/sparc/dev/vmereg.h75
-rw-r--r--sys/arch/sparc/dev/xd.c60
-rw-r--r--sys/arch/sparc/dev/xdreg.h1
-rw-r--r--sys/arch/sparc/dev/xdvar.h1
-rw-r--r--sys/arch/sparc/dev/xio.h1
-rw-r--r--sys/arch/sparc/dev/xy.c55
-rw-r--r--sys/arch/sparc/dev/xyreg.h1
-rw-r--r--sys/arch/sparc/dev/xyvar.h1
-rw-r--r--sys/arch/sparc/dev/zs.c98
-rw-r--r--sys/arch/sparc/dev/zsvar.h12
63 files changed, 3683 insertions, 2993 deletions
diff --git a/sys/arch/sparc/dev/amd7930.c b/sys/arch/sparc/dev/amd7930.c
index bb250924af1..998e89f5d1f 100644
--- a/sys/arch/sparc/dev/amd7930.c
+++ b/sys/arch/sparc/dev/amd7930.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: amd7930.c,v 1.8 1997/07/13 21:48:42 angelos Exp $ */
+/* $OpenBSD: amd7930.c,v 1.9 1997/08/08 08:24:37 downsj Exp $ */
/* $NetBSD: amd7930.c,v 1.10 1996/03/31 22:38:29 pk Exp $ */
/*
@@ -304,8 +304,7 @@ amd7930attach(parent, self, args)
pri = ra->ra_intr[0].int_pri;
printf(" pri %d, softpri %d\n", pri, PIL_AUSOFT);
amd = (volatile struct amd7930 *)(ra->ra_vaddr ?
- ra->ra_vaddr : mapiodev(ra->ra_reg, 0, sizeof (*amd),
- ca->ca_bustype));
+ ra->ra_vaddr : mapiodev(ra->ra_reg, 0, sizeof (*amd)));
sc->sc_map.mr_mmr1 = AMD_MMR1_GX | AMD_MMR1_GER |
AMD_MMR1_GR | AMD_MMR1_STG;
diff --git a/sys/arch/sparc/dev/amd7930var.h b/sys/arch/sparc/dev/amd7930var.h
index 2d2e5f28257..8e6cf85e529 100644
--- a/sys/arch/sparc/dev/amd7930var.h
+++ b/sys/arch/sparc/dev/amd7930var.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: amd7930var.h,v 1.3 1997/08/08 08:24:38 downsj Exp $ */
/* $NetBSD: amd7930var.h,v 1.3 1996/02/01 22:32:25 mycroft Exp $ */
/*
diff --git a/sys/arch/sparc/dev/bt_subr.c b/sys/arch/sparc/dev/bt_subr.c
index 2a1df0ad71b..11105ffa29d 100644
--- a/sys/arch/sparc/dev/bt_subr.c
+++ b/sys/arch/sparc/dev/bt_subr.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: bt_subr.c,v 1.3 1997/08/08 08:24:39 downsj Exp $ */
/* $NetBSD: bt_subr.c,v 1.5 1996/03/14 19:44:32 christos Exp $ */
/*
diff --git a/sys/arch/sparc/dev/btreg.h b/sys/arch/sparc/dev/btreg.h
index aa3f5fbc0db..e146117c25b 100644
--- a/sys/arch/sparc/dev/btreg.h
+++ b/sys/arch/sparc/dev/btreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: btreg.h,v 1.3 1997/08/08 08:24:40 downsj Exp $ */
/* $NetBSD: btreg.h,v 1.4 1996/02/27 22:09:21 thorpej Exp $ */
/*
diff --git a/sys/arch/sparc/dev/btvar.h b/sys/arch/sparc/dev/btvar.h
index 68be1189422..e08df3b8b1c 100644
--- a/sys/arch/sparc/dev/btvar.h
+++ b/sys/arch/sparc/dev/btvar.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: btvar.h,v 1.2 1997/08/08 08:24:41 downsj Exp $ */
/* $NetBSD: btvar.h,v 1.2 1994/11/20 20:51:56 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/dev/bwtwo.c b/sys/arch/sparc/dev/bwtwo.c
index f629c0cffa4..e8f1177fea5 100644
--- a/sys/arch/sparc/dev/bwtwo.c
+++ b/sys/arch/sparc/dev/bwtwo.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: bwtwo.c,v 1.13 1996/08/13 08:05:18 downsj Exp $ */
-/* $NetBSD: bwtwo.c,v 1.26 1996/04/01 17:30:15 christos Exp $ */
+/* $OpenBSD: bwtwo.c,v 1.14 1997/08/08 08:24:43 downsj Exp $ */
+/* $NetBSD: bwtwo.c,v 1.33 1997/05/24 20:16:02 pk Exp $ */
/*
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
@@ -105,14 +105,13 @@ struct bwtwo_softc {
/* autoconfiguration driver */
static void bwtwoattach __P((struct device *, struct device *, void *));
static int bwtwomatch __P((struct device *, void *, void *));
-int bwtwoopen __P((dev_t, int, int, struct proc *));
-int bwtwoclose __P((dev_t, int, int, struct proc *));
-int bwtwoioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int bwtwommap __P((dev_t, int, int));
static void bwtwounblank __P((struct device *));
static void bwtwo_set_video __P((struct bwtwo_softc *, int));
static int bwtwo_get_video __P((struct bwtwo_softc *));
+/* cdevsw prototypes */
+cdev_decl(bwtwo);
+
struct cfattach bwtwo_ca = {
sizeof(struct bwtwo_softc), bwtwomatch, bwtwoattach
};
@@ -212,14 +211,13 @@ bwtwoattach(parent, self, args)
* Map the control register.
*/
if (fb->fb_flags & FB_PFOUR) {
- fb->fb_pfour =
- (volatile u_int32_t *)mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(u_int32_t), ca->ca_bustype);
+ fb->fb_pfour = (volatile u_int32_t *)
+ mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
sc->sc_reg = NULL;
} else {
- sc->sc_reg =
- (volatile struct fbcontrol *)mapiodev(ca->ca_ra.ra_reg,
- BWREG_REG, sizeof(struct fbcontrol), ca->ca_bustype);
+ sc->sc_reg = (volatile struct fbcontrol *)
+ mapiodev(ca->ca_ra.ra_reg, BWREG_REG,
+ sizeof(struct fbcontrol));
fb->fb_pfour = NULL;
}
@@ -291,13 +289,13 @@ bwtwoattach(parent, self, args)
#if defined(SUN4)
if (CPU_ISSUN4) {
struct eeprom *eep = (struct eeprom *)eeprom_va;
- int constype = (fb->fb_flags & FB_PFOUR) ? EED_CONS_P4 :
- EED_CONS_BW;
+ int constype = (fb->fb_flags & FB_PFOUR) ? EE_CONS_P4OPT :
+ EE_CONS_BW;
/*
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == constype)
+ if (eep == NULL || eep->eeConsole == constype)
isconsole = (fbconstty != NULL);
else
isconsole = 0;
@@ -316,8 +314,7 @@ bwtwoattach(parent, self, args)
if ((fb->fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
/* this probably cannot happen (on sun4c), but what the heck */
fb->fb_pixels =
- mapiodev(ca->ca_ra.ra_reg, sc->sc_pixeloffset,
- ramsize, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, sc->sc_pixeloffset, ramsize);
}
/* Insure video is enabled */
@@ -326,7 +323,16 @@ bwtwoattach(parent, self, args)
if (isconsole) {
printf(" (console)\n");
#ifdef RASTERCONSOLE
- fbrcons_init(fb);
+#if defined(SUN4)
+ /*
+ * XXX rcons doesn't seem to work properly on the overlay
+ * XXX plane. This is a temporary kludge until someone
+ * XXX fixes it.
+ */
+ if ((fb->fb_flags & FB_PFOUR) == 0 ||
+ (sc->sc_ovtype == BWO_NONE))
+#endif
+ fbrcons_init(fb);
#endif
} else
printf("\n");
@@ -456,8 +462,7 @@ bwtwommap(dev, off, prot)
* I turned on PMAP_NC here to disable the cache as I was
* getting horribly broken behaviour with it on.
*/
- return (REG2PHYS(&sc->sc_phys, sc->sc_pixeloffset + off,
- sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, sc->sc_pixeloffset + off) | PMAP_NC);
}
static int
diff --git a/sys/arch/sparc/dev/bwtworeg.h b/sys/arch/sparc/dev/bwtworeg.h
index 236f4a44929..f773d3c237e 100644
--- a/sys/arch/sparc/dev/bwtworeg.h
+++ b/sys/arch/sparc/dev/bwtworeg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: bwtworeg.h,v 1.3 1997/08/08 08:24:43 downsj Exp $ */
/* $NetBSD: bwtworeg.h,v 1.3 1996/02/27 00:32:39 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/cgeight.c b/sys/arch/sparc/dev/cgeight.c
index b720a24744a..48a1675266e 100644
--- a/sys/arch/sparc/dev/cgeight.c
+++ b/sys/arch/sparc/dev/cgeight.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cgeight.c,v 1.7 1996/08/13 08:05:20 downsj Exp $ */
-/* $NetBSD: cgeight.c,v 1.7 1996/04/01 17:29:57 christos Exp $ */
+/* $OpenBSD: cgeight.c,v 1.8 1997/08/08 08:24:44 downsj Exp $ */
+/* $NetBSD: cgeight.c,v 1.13 1997/05/24 20:16:04 pk Exp $ */
/*
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
@@ -91,14 +91,13 @@ struct cgeight_softc {
/* autoconfiguration driver */
static void cgeightattach(struct device *, struct device *, void *);
static int cgeightmatch(struct device *, void *, void *);
-int cgeightopen __P((dev_t, int, int, struct proc *));
-int cgeightclose __P((dev_t, int, int, struct proc *));
-int cgeightioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgeightmmap __P((dev_t, int, int));
#if defined(SUN4)
static void cgeightunblank __P((struct device *));
#endif
+/* cdevsw prototypes */
+cdev_decl(cgeight);
+
struct cfattach cgeight_ca = {
sizeof(struct cgeight_softc), cgeightmatch, cgeightattach
};
@@ -203,8 +202,8 @@ cgeightattach(parent, self, args)
}
/* Map the pfour register. */
- fb->fb_pfour = (volatile u_int32_t *)mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(u_int32_t), ca->ca_bustype);
+ fb->fb_pfour = (volatile u_int32_t *)
+ mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
@@ -225,7 +224,7 @@ cgeightattach(parent, self, args)
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == EED_CONS_P4)
+ if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT)
isconsole = (fbconstty != NULL);
}
@@ -248,13 +247,14 @@ cgeightattach(parent, self, args)
if (isconsole) {
/* XXX this is kind of a waste */
fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_OVERLAY, ramsize, ca->ca_bustype);
+ PFOUR_COLOR_OFF_OVERLAY, ramsize);
}
#endif
/* Map the Brooktree. */
- sc->sc_fbc = (volatile struct fbcontrol *)mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol), ca->ca_bustype);
+ sc->sc_fbc = (volatile struct fbcontrol *)
+ mapiodev(ca->ca_ra.ra_reg,
+ PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol));
sc->sc_phys = ca->ca_ra.ra_reg[0];
sc->sc_bustype = ca->ca_bustype;
@@ -405,7 +405,7 @@ cgeightmmap(dev, off, prot)
panic("cgeightmap");
if ((u_int)off >= NOOVERLAY) {
- off =- NOOVERLAY;
+ off -= NOOVERLAY;
/*
* X11 maps a huge chunk of the frame buffer; far more than
@@ -426,7 +426,7 @@ cgeightmmap(dev, off, prot)
* in enable plane
*/
poff = (off - START_ENABLE) + PFOUR_COLOR_OFF_ENABLE;
- } else if ((u_int)off < END_COLOR) {
+ } else if ((u_int)off < sc->sc_fb.fb_type.fb_size) {
/*
* in colour plane
*/
@@ -458,7 +458,7 @@ cgeightmmap(dev, off, prot)
* I turned on PMAP_NC here to disable the cache as I was
* getting horribly broken behaviour with it on.
*/
- return (REG2PHYS(&sc->sc_phys, poff, sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, poff) | PMAP_NC);
}
#if defined(SUN4)
diff --git a/sys/arch/sparc/dev/cgeightreg.h b/sys/arch/sparc/dev/cgeightreg.h
deleted file mode 100644
index 1fac1d4227c..00000000000
--- a/sys/arch/sparc/dev/cgeightreg.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* $NetBSD: cgeightreg.h,v 1.4 1994/11/20 20:52:03 deraadt Exp $ */
-
-/*
- * Copyright (c) 1995 Theo de Raadt
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Theo de Raadt.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * cgeight display registers. Much like bwtwo registers, except that
- * there is a Brooktree Video DAC in there (so we also use btreg.h).
- */
-
-/* offsets */
-#define CG8REG_CMAP 0x200000
-#define CG8REG_P4REG 0x300000
-#define CG8REG_OVERLAY 0x400000
-#define CG8REG_ENABLE 0x600000
-#define CG8REG_COLOUR 0x800000
-#define CG8REG_END 0xa00000
-
-/* same, but for gdb */
-struct cgeight_all {
- char ba_nothing[0x200000];
- struct bt_regs ba_btreg; /* Brooktree registers */
- char ba_xxx1[0x100000-sizeof(struct bt_regs)];
- char ba_pfourreg[0x100000];
- char ba_overlay[0x200000];
- char ba_enable[0x200000];
- char ba_color[0x200000];
-};
diff --git a/sys/arch/sparc/dev/cgfour.c b/sys/arch/sparc/dev/cgfour.c
index 279d1cb0fea..4284b1c5781 100644
--- a/sys/arch/sparc/dev/cgfour.c
+++ b/sys/arch/sparc/dev/cgfour.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cgfour.c,v 1.7 1996/08/13 08:05:21 downsj Exp $ */
-/* $NetBSD: cgfour.c,v 1.7 1996/04/01 17:29:58 christos Exp $ */
+/* $OpenBSD: cgfour.c,v 1.8 1997/08/08 08:24:46 downsj Exp $ */
+/* $NetBSD: cgfour.c,v 1.13 1997/05/24 20:16:06 pk Exp $ */
/*
* Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
@@ -95,14 +95,13 @@ struct cgfour_softc {
/* autoconfiguration driver */
static void cgfourattach __P((struct device *, struct device *, void *));
static int cgfourmatch __P((struct device *, void *, void *));
-int cgfouropen __P((dev_t, int, int, struct proc *));
-int cgfourclose __P((dev_t, int, int, struct proc *));
-int cgfourioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgfourmmap __P((dev_t, int, int));
#if defined(SUN4)
static void cgfourunblank __P((struct device *));
#endif
+/* cdevsw prototypes */
+cdev_decl(cgfour);
+
struct cfattach cgfour_ca = {
sizeof(struct cgfour_softc), cgfourmatch, cgfourattach
};
@@ -207,8 +206,8 @@ cgfourattach(parent, self, args)
}
/* Map the pfour register. */
- fb->fb_pfour = (volatile u_int32_t *)mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(u_int32_t), ca->ca_bustype);
+ fb->fb_pfour = (volatile u_int32_t *)
+ mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t));
ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;
@@ -229,7 +228,7 @@ cgfourattach(parent, self, args)
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == EED_CONS_P4)
+ if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT)
isconsole = (fbconstty != NULL);
}
@@ -252,13 +251,14 @@ cgfourattach(parent, self, args)
if (isconsole) {
/* XXX this is kind of a waste */
fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_OVERLAY, ramsize, ca->ca_bustype);
+ PFOUR_COLOR_OFF_OVERLAY, ramsize);
}
#endif
/* Map the Brooktree. */
- sc->sc_fbc = (volatile struct fbcontrol *)mapiodev(ca->ca_ra.ra_reg,
- PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol), ca->ca_bustype);
+ sc->sc_fbc = (volatile struct fbcontrol *)
+ mapiodev(ca->ca_ra.ra_reg,
+ PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol));
sc->sc_phys = ca->ca_ra.ra_reg[0];
sc->sc_bustype = ca->ca_bustype;
@@ -403,7 +403,7 @@ cgfourmmap(dev, off, prot)
panic("cgfourmap");
if ((u_int)off >= NOOVERLAY) {
- off =- NOOVERLAY;
+ off -= NOOVERLAY;
/*
* X11 maps a huge chunk of the frame buffer; far more than
@@ -424,7 +424,7 @@ cgfourmmap(dev, off, prot)
* in enable plane
*/
poff = (off - START_ENABLE) + PFOUR_COLOR_OFF_ENABLE;
- } else if ((u_int)off < END_COLOR) {
+ } else if ((u_int)off < sc->sc_fb.fb_type.fb_size) {
/*
* in colour plane
*/
@@ -432,7 +432,7 @@ cgfourmmap(dev, off, prot)
} else
return (-1);
- return (REG2PHYS(&sc->sc_phys, poff, sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, poff) | PMAP_NC);
}
#if defined(SUN4)
diff --git a/sys/arch/sparc/dev/cgfourteen.c b/sys/arch/sparc/dev/cgfourteen.c
new file mode 100644
index 00000000000..2786bb6a9ff
--- /dev/null
+++ b/sys/arch/sparc/dev/cgfourteen.c
@@ -0,0 +1,877 @@
+/* $OpenBSD: cgfourteen.c,v 1.1 1997/08/08 08:24:48 downsj Exp $ */
+/* $NetBSD: cgfourteen.c,v 1.7 1997/05/24 20:16:08 pk Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * The President and Fellows of Harvard College. All rights reserved.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Harvard University.
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * This product includes software developed by Harvard University and
+ * its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Based on:
+ * NetBSD: cgthree.c,v 1.28 1996/05/31 09:59:22 pk Exp
+ * NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp
+ */
+
+/*
+ * Driver for Campus-II on-board mbus-based video (cgfourteen).
+ * Provides minimum emulation of a Sun cgthree 8-bit framebuffer to
+ * allow X to run.
+ *
+ * Does not handle interrupts, even though they can occur.
+ *
+ * XXX should defer colormap updates to vertical retrace interrupts
+ */
+
+/*
+ * The following is for debugging only; it opens up a security hole
+ * enabled by allowing any user to map the control registers for the
+ * cg14 into their space.
+ */
+#undef CG14_MAP_REGS
+
+/*
+ * The following enables 24-bit operation: when opened, the framebuffer
+ * will switch to 24-bit mode (actually 32-bit mode), and provide a
+ * simple cg8 emulation.
+ *
+ * XXX Note that the code enabled by this define is currently untested/broken.
+ */
+#undef CG14_CG8
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/tty.h>
+#include <sys/conf.h>
+
+#include <vm/vm.h>
+
+#include <machine/fbio.h>
+#include <machine/autoconf.h>
+#include <machine/pmap.h>
+#include <machine/fbvar.h>
+#include <machine/cpu.h>
+#include <machine/conf.h>
+
+#include <sparc/dev/cgfourteenreg.h>
+#include <sparc/dev/cgfourteenvar.h>
+
+/* autoconfiguration driver */
+static void cgfourteenattach(struct device *, struct device *, void *);
+static int cgfourteenmatch(struct device *, void *, void *);
+static void cgfourteenunblank(struct device *);
+
+/* cdevsw prototypes */
+cdev_decl(cgfourteen);
+
+struct cfattach cgfourteen_ca = {
+ sizeof(struct cgfourteen_softc), cgfourteenmatch, cgfourteenattach
+};
+
+struct cfdriver cgfourteen_cd = {
+ NULL, "cgfourteen", DV_DULL
+};
+
+/* frame buffer generic driver */
+static struct fbdriver cgfourteenfbdriver = {
+ cgfourteenunblank, cgfourteenopen, cgfourteenclose, cgfourteenioctl,
+ cgfourteenmmap
+};
+
+extern int fbnode;
+extern struct tty *fbconstty;
+
+static void cg14_set_video __P((struct cgfourteen_softc *, int));
+static int cg14_get_video __P((struct cgfourteen_softc *));
+static int cg14_get_cmap __P((struct fbcmap *, union cg14cmap *, int));
+static int cg14_put_cmap __P((struct fbcmap *, union cg14cmap *, int));
+static void cg14_load_hwcmap __P((struct cgfourteen_softc *, int, int));
+static void cg14_init __P((struct cgfourteen_softc *));
+static void cg14_reset __P((struct cgfourteen_softc *));
+static void cg14_loadomap __P((struct cgfourteen_softc *));/* cursor overlay */
+static void cg14_setcursor __P((struct cgfourteen_softc *));/* set position */
+static void cg14_loadcursor __P((struct cgfourteen_softc *));/* set shape */
+
+/*
+ * Match a cgfourteen.
+ */
+int
+cgfourteenmatch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
+ struct romaux *ra = &ca->ca_ra;
+
+ /*
+ * Mask out invalid flags from the user.
+ */
+ cf->cf_flags &= FB_USERMASK;
+
+ /* Check driver name */
+ if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
+ return (0);
+
+ /*
+ * The cgfourteen is a local-bus video adaptor, accessed directly
+ * via the processor, and not through device space or an external
+ * bus. Thus we look _only_ at the obio bus.
+ * Additionally, these things exist only on the Sun4m.
+ */
+ if (CPU_ISSUN4M && ca->ca_bustype == BUS_OBIO)
+ return(1);
+ return (0);
+}
+
+/*
+ * Attach a display. We need to notice if it is the console, too.
+ */
+void
+cgfourteenattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ register struct cgfourteen_softc *sc = (struct cgfourteen_softc *)self;
+ register struct confargs *ca = args;
+ register int node = 0, ramsize;
+ register u_int32_t *lut;
+ int i, isconsole;
+
+ sc->sc_fb.fb_driver = &cgfourteenfbdriver;
+ sc->sc_fb.fb_device = &sc->sc_dev;
+ sc->sc_fb.fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
+
+ /*
+ * We're emulating a cg3/8, so represent ourselves as one
+ */
+#ifdef CG14_CG8
+ sc->sc_fb.fb_type.fb_type = FBTYPE_MEMCOLOR;
+#else
+ sc->sc_fb.fb_type.fb_type = FBTYPE_SUN3COLOR;
+#endif
+
+ node = ca->ca_ra.ra_node;
+#ifdef CG14_CG8
+ sc->sc_fb.fb_type.fb_depth = 32;
+#else
+ sc->sc_fb.fb_type.fb_depth = 8;
+#endif
+ fb_setsize(&sc->sc_fb, sc->sc_fb.fb_type.fb_depth,
+ 1152, 900, node, ca->ca_bustype);
+
+ ramsize = roundup(sc->sc_fb.fb_type.fb_height * sc->sc_fb.fb_linebytes,
+ NBPG);
+
+ sc->sc_fb.fb_type.fb_cmsize = CG14_CLUT_SIZE;
+ sc->sc_fb.fb_type.fb_size = ramsize;
+
+ /*
+ * Now map in the 8 useful pages of registers
+ */
+ if (ca->ca_ra.ra_len < 0x10000) {
+#ifdef DIAGNOSTIC
+ printf("warning: can't find all cgfourteen registers...\n");
+#endif
+ ca->ca_ra.ra_len = 0x10000;
+ }
+ sc->sc_ctl = (struct cg14ctl *) mapiodev(ca->ca_ra.ra_reg, 0,
+ ca->ca_ra.ra_len);
+
+ sc->sc_hwc = (struct cg14curs *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CURS);
+ sc->sc_dac = (struct cg14dac *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_DAC);
+ sc->sc_xlut = (struct cg14xlut *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_XLUT);
+ sc->sc_clut1 = (struct cg14clut *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CLUT1);
+ sc->sc_clut2 = (struct cg14clut *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CLUT2);
+ sc->sc_clut3 = (struct cg14clut *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CLUT3);
+ sc->sc_clutincr = (u_int *) ((u_int)sc->sc_ctl +
+ CG14_OFFSET_CLUTINCR);
+
+ /*
+ * Stash the physical address of the framebuffer for use by mmap
+ */
+ if (ca->ca_ra.ra_nreg < 2)
+ panic("cgfourteen with only one register set; can't find"
+ " framebuffer");
+ sc->sc_phys = ca->ca_ra.ra_reg[1];
+
+#if defined(DEBUG) && defined(CG14_MAP_REGS)
+ /* Store the physical address of the control registers */
+ sc->sc_regphys = ca->ca_ra.ra_reg[0];
+#endif
+
+ /*
+ * Let the user know that we're here
+ */
+#ifdef CG14_CG8
+ printf(": cgeight emulated at %dx%dx24bpp",
+ sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
+#else
+ printf(": cgthree emulated at %dx%dx8bpp",
+ sc->sc_fb.fb_type.fb_width, sc->sc_fb.fb_type.fb_height);
+#endif
+ /*
+ * Enable the video, but don't change the pixel depth.
+ */
+ cg14_set_video(sc, 1);
+
+ /*
+ * Grab the initial colormap
+ */
+ lut = (u_int32_t *) sc->sc_clut1->clut_lut;
+ for (i = 0; i < CG14_CLUT_SIZE; i++)
+ sc->sc_cmap.cm_chip[i] = lut[i];
+
+ /* See if we're the console */
+ isconsole = node == fbnode && fbconstty != NULL;
+
+ /*
+ * We don't use the raster console since the cg14 is fast enough
+ * already.
+ */
+#ifdef notdef
+ /*
+ * When the ROM has mapped in a cgfourteen display, the address
+ * maps only the video RAM, so in any case we have to map the
+ * registers ourselves. We only need the video RAM if we are
+ * going to print characters via rconsole.
+ */
+ if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
+ /* this probably cannot happen, but what the heck */
+ sc->sc_fb.fb_pixels = mapiodev(ca->ca_ra.ra_reg, CG3REG_MEM,
+ ramsize);
+ }
+#endif /* notdef */
+
+
+ if (isconsole) {
+ printf(" (console)\n");
+#ifdef notdef
+#ifdef RASTERCONSOLE
+ fbrcons_init(&sc->sc_fb);
+#endif
+#endif /* notdef */
+ } else
+ printf("\n");
+
+ /* Attach to /dev/fb */
+ if (node == fbnode)
+ fb_attach(&sc->sc_fb, isconsole);
+}
+
+/*
+ * Keep track of the number of opens made. In the 24-bit driver, we need to
+ * switch to 24-bit mode on the first open, and switch back to 8-bit on
+ * the last close. This kind of nonsense is needed to give screenblank
+ * a fighting chance of working.
+ */
+static int cg14_opens = 0;
+
+int
+cgfourteenopen(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
+ int unit = minor(dev);
+ int s, oldopens;
+
+ if (unit >= cgfourteen_cd.cd_ndevs ||
+ cgfourteen_cd.cd_devs[unit] == NULL)
+ return (ENXIO);
+
+ s = splhigh();
+ oldopens = cg14_opens++;
+ splx(s);
+
+ /* Setup the cg14 as we want it, and save the original PROM state */
+ if (oldopens == 0) /* first open only, to make screenblank work */
+ cg14_init(sc);
+
+ return (0);
+}
+
+int
+cgfourteenclose(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
+ int s, opens;
+
+ s = splhigh();
+ opens = --cg14_opens;
+ if (cg14_opens < 0)
+ opens = cg14_opens = 0;
+ splx(s);
+
+ /*
+ * Restore video state to make the PROM happy, on last close.
+ */
+ if (opens == 0)
+ cg14_reset(sc);
+
+ return (0);
+}
+
+int
+cgfourteenioctl(dev, cmd, data, flags, p)
+ dev_t dev;
+ u_long cmd;
+ register caddr_t data;
+ int flags;
+ struct proc *p;
+{
+ register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
+ register struct fbgattr *fba;
+ union cg14cursor_cmap tcm;
+ int v, error;
+ u_int count;
+
+ switch (cmd) {
+
+ case FBIOGTYPE:
+ *(struct fbtype *)data = sc->sc_fb.fb_type;
+ break;
+
+ case FBIOGATTR:
+ fba = (struct fbgattr *)data;
+ fba->real_type = FBTYPE_MDICOLOR;
+ fba->owner = 0; /* XXX ??? */
+ fba->fbtype = sc->sc_fb.fb_type;
+ fba->sattr.flags = 0;
+ fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
+ fba->sattr.dev_specific[0] = -1;
+ fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
+ fba->emu_types[1] = -1;
+ break;
+
+ case FBIOGETCMAP:
+ return (cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap,
+ CG14_CLUT_SIZE));
+
+ case FBIOPUTCMAP:
+ /* copy to software map */
+#define p ((struct fbcmap *)data)
+#ifdef CG14_CG8
+ p->index &= 0xffffff;
+#endif
+ error = cg14_put_cmap(p, &sc->sc_cmap, CG14_CLUT_SIZE);
+ if (error)
+ return (error);
+ /* now blast them into the chip */
+ /* XXX should use retrace interrupt */
+ cg14_load_hwcmap(sc, p->index, p->count);
+#undef p
+ break;
+
+ case FBIOGVIDEO:
+ *(int *)data = cg14_get_video(sc);
+ break;
+
+ case FBIOSVIDEO:
+ cg14_set_video(sc, *(int *)data);
+ break;
+
+/* these are for both FBIOSCURSOR and FBIOGCURSOR */
+#define p ((struct fbcursor *)data)
+#define cc (&sc->sc_cursor)
+ case FBIOGCURSOR:
+ /* do not quite want everything here... */
+ p->set = FB_CUR_SETALL; /* close enough, anyway */
+ p->enable = cc->cc_enable;
+ p->pos = cc->cc_pos;
+ p->hot = cc->cc_hot;
+ p->size = cc->cc_size;
+
+ /* begin ugh ... can we lose some of this crap?? */
+ if (p->image != NULL) {
+ count = cc->cc_size.y * 32 / NBBY;
+ error = copyout((caddr_t)cc->cc_cplane,
+ (caddr_t)p->image, count);
+ if (error)
+ return (error);
+ error = copyout((caddr_t)cc->cc_eplane,
+ (caddr_t)p->mask, count);
+ if (error)
+ return (error);
+ }
+ if (p->cmap.red != NULL) {
+ error = cg14_get_cmap(&p->cmap,
+ (union cg14cmap *)&cc->cc_color, 2);
+ if (error)
+ return (error);
+ } else {
+ p->cmap.index = 0;
+ p->cmap.count = 2;
+ }
+ /* end ugh */
+ break;
+
+ case FBIOSCURSOR:
+ /*
+ * For setcmap and setshape, verify parameters, so that
+ * we do not get halfway through an update and then crap
+ * out with the software state screwed up.
+ */
+ v = p->set;
+ if (v & FB_CUR_SETCMAP) {
+ /*
+ * This use of a temporary copy of the cursor
+ * colormap is not terribly efficient, but these
+ * copies are small (8 bytes)...
+ */
+ tcm = cc->cc_color;
+ error = cg14_put_cmap(&p->cmap, (union cg14cmap *)&tcm,
+ 2);
+ if (error)
+ return (error);
+ }
+ if (v & FB_CUR_SETSHAPE) {
+ if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)
+ return (EINVAL);
+ count = p->size.y * 32 / NBBY;
+ if (!useracc(p->image, count, B_READ) ||
+ !useracc(p->mask, count, B_READ))
+ return (EFAULT);
+ }
+
+ /* parameters are OK; do it */
+ if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
+ if (v & FB_CUR_SETCUR)
+ cc->cc_enable = p->enable;
+ if (v & FB_CUR_SETPOS)
+ cc->cc_pos = p->pos;
+ if (v & FB_CUR_SETHOT)
+ cc->cc_hot = p->hot;
+ cg14_setcursor(sc);
+ }
+ if (v & FB_CUR_SETCMAP) {
+ cc->cc_color = tcm;
+ cg14_loadomap(sc); /* XXX defer to vertical retrace */
+ }
+ if (v & FB_CUR_SETSHAPE) {
+ cc->cc_size = p->size;
+ count = p->size.y * 32 / NBBY;
+ bzero((caddr_t)cc->cc_eplane, sizeof cc->cc_eplane);
+ bzero((caddr_t)cc->cc_cplane, sizeof cc->cc_cplane);
+ bcopy(p->mask, (caddr_t)cc->cc_eplane, count);
+ bcopy(p->image, (caddr_t)cc->cc_cplane, count);
+ cg14_loadcursor(sc);
+ }
+ break;
+
+#undef cc
+#undef p
+ case FBIOGCURPOS:
+ *(struct fbcurpos *)data = sc->sc_cursor.cc_pos;
+ break;
+
+ case FBIOSCURPOS:
+ sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;
+ cg14_setcursor(sc);
+ break;
+
+ case FBIOGCURMAX:
+ /* max cursor size is 32x32 */
+ ((struct fbcurpos *)data)->x = 32;
+ ((struct fbcurpos *)data)->y = 32;
+ break;
+
+ default:
+ return (ENOTTY);
+ }
+ return (0);
+}
+
+/*
+ * Undo the effect of an FBIOSVIDEO that turns the video off.
+ */
+static void
+cgfourteenunblank(dev)
+ struct device *dev;
+{
+
+ cg14_set_video((struct cgfourteen_softc *)dev, 1);
+}
+
+/*
+ * Return the address that would map the given device at the given
+ * offset, allowing for the given protection, or return -1 for error.
+ *
+ * The cg14 frame buffer can be mapped in either 8-bit or 32-bit mode
+ * starting at the address stored in the PROM. In 8-bit mode, the X
+ * channel is not present, and can be ignored. In 32-bit mode, mapping
+ * at 0K delivers a 32-bpp buffer where the upper 8 bits select the X
+ * channel information. We hardwire the Xlut to all zeroes to insure
+ * that, regardless of this value, direct 24-bit color access will be
+ * used.
+ *
+ * Alternatively, mapping the frame buffer at an offset of 16M seems to
+ * tell the chip to ignore the X channel. XXX where does it get the X value
+ * to use?
+ */
+int
+cgfourteenmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ register struct cgfourteen_softc *sc = cgfourteen_cd.cd_devs[minor(dev)];
+
+#define CG3START (128*1024 + 128*1024)
+#define CG8START (256*1024)
+#define NOOVERLAY (0x04000000)
+
+ if (off & PGOFSET)
+ panic("cgfourteenmmap");
+
+#if defined(DEBUG) && defined(CG14_MAP_REGS) /* XXX: security hole */
+ /*
+ * Map the control registers into user space. Should only be
+ * used for debugging!
+ */
+ if ((u_int)off >= 0x10000000 && (u_int)off < 0x10000000 + 16*4096) {
+ off -= 0x10000000;
+ return (REG2PHYS(&sc->sc_regphys, off, 0) | PMAP_NC);
+ }
+#endif
+
+ if ((u_int)off >= NOOVERLAY)
+ off -= NOOVERLAY;
+#ifdef CG14_CG8
+ else if ((u_int)off >= CG8START) {
+ off -= CG8START;
+ }
+#else
+ else if ((u_int)off >= CG3START)
+ off -= CG3START;
+#endif
+ else
+ off = 0;
+
+ if ((unsigned)off >= sc->sc_fb.fb_type.fb_size *
+ sc->sc_fb.fb_type.fb_depth/8) {
+#ifdef DEBUG
+ printf("\nmmap request out of bounds: request 0x%x, "
+ "bound 0x%x\n", (unsigned) off,
+ (unsigned)sc->sc_fb.fb_type.fb_size);
+#endif
+ return (-1);
+ }
+
+ /*
+ * Use PMAP_NC to disable the cache, since otherwise refresh is
+ * very confused.
+ */
+ return (REG2PHYS(&sc->sc_phys, off) | PMAP_NC);
+}
+
+/*
+ * Miscellaneous helper functions
+ */
+
+/* Initialize the framebuffer, storing away useful state for later reset */
+static void
+cg14_init(sc)
+ struct cgfourteen_softc *sc;
+{
+ register u_int32_t *clut;
+ register u_int8_t *xlut;
+ register int i;
+
+ /*
+ * We stash away the following to restore on close:
+ *
+ * color look-up table 1 (sc->sc_saveclut)
+ * x look-up table (sc->sc_savexlut)
+ * control register (sc->sc_savectl)
+ * cursor control register (sc->sc_savehwc)
+ */
+ sc->sc_savectl = sc->sc_ctl->ctl_mctl;
+ sc->sc_savehwc = sc->sc_hwc->curs_ctl;
+
+ clut = (u_int32_t *) sc->sc_clut1->clut_lut;
+ xlut = (u_int8_t *) sc->sc_xlut->xlut_lut;
+ for (i = 0; i < CG14_CLUT_SIZE; i++) {
+ sc->sc_saveclut.cm_chip[i] = clut[i];
+ sc->sc_savexlut[i] = xlut[i];
+ }
+
+#ifdef CG14_CG8
+ /*
+ * Enable the video, and put in 24 bit mode.
+ */
+ sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_32 |
+ CG14_MCTL_POWERCTL;
+
+ /*
+ * Zero the xlut to enable direct-color mode
+ */
+ bzero(sc->sc_xlut, CG14_CLUT_SIZE);
+#else
+ /*
+ * Enable the video and put it in 8 bit mode
+ */
+ sc->sc_ctl->ctl_mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_8 |
+ CG14_MCTL_POWERCTL;
+#endif
+}
+
+static void
+cg14_reset(sc) /* Restore the state saved on cg14_init */
+ struct cgfourteen_softc *sc;
+{
+ register u_int32_t *clut;
+ register u_int8_t *xlut;
+ register int i;
+
+ /*
+ * We restore the following, saved in cg14_init:
+ *
+ * color look-up table 1 (sc->sc_saveclut)
+ * x look-up table (sc->sc_savexlut)
+ * control register (sc->sc_savectl)
+ * cursor control register (sc->sc_savehwc)
+ *
+ * Note that we don't touch the video enable bits in the
+ * control register; otherwise, screenblank wouldn't work.
+ */
+ sc->sc_ctl->ctl_mctl = (sc->sc_ctl->ctl_mctl & (CG14_MCTL_ENABLEVID |
+ CG14_MCTL_POWERCTL)) |
+ (sc->sc_savectl & ~(CG14_MCTL_ENABLEVID |
+ CG14_MCTL_POWERCTL));
+ sc->sc_hwc->curs_ctl = sc->sc_savehwc;
+
+ clut = (u_int32_t *) sc->sc_clut1->clut_lut;
+ xlut = (u_int8_t *) sc->sc_xlut->xlut_lut;
+ for (i = 0; i < CG14_CLUT_SIZE; i++) {
+ clut[i] = sc->sc_saveclut.cm_chip[i];
+ xlut[i] = sc->sc_savexlut[i];
+ }
+}
+
+/* Enable/disable video display; power down monitor if DPMS-capable */
+static void
+cg14_set_video(sc, enable)
+ struct cgfourteen_softc *sc;
+ int enable;
+{
+ /*
+ * We can only use DPMS to power down the display if the chip revision
+ * is greater than 0.
+ */
+ if (enable) {
+ if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0)
+ sc->sc_ctl->ctl_mctl |= (CG14_MCTL_ENABLEVID |
+ CG14_MCTL_POWERCTL);
+ else
+ sc->sc_ctl->ctl_mctl |= CG14_MCTL_ENABLEVID;
+ } else {
+ if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0)
+ sc->sc_ctl->ctl_mctl &= ~(CG14_MCTL_ENABLEVID |
+ CG14_MCTL_POWERCTL);
+ else
+ sc->sc_ctl->ctl_mctl &= ~CG14_MCTL_ENABLEVID;
+ }
+}
+
+/* Get status of video display */
+static int
+cg14_get_video(sc)
+ struct cgfourteen_softc *sc;
+{
+ return ((sc->sc_ctl->ctl_mctl & CG14_MCTL_ENABLEVID) != 0);
+}
+
+/* Read the software shadow colormap */
+static int
+cg14_get_cmap(p, cm, cmsize)
+ register struct fbcmap *p;
+ union cg14cmap *cm;
+ int cmsize;
+{
+ register u_int i, start, count;
+ register u_char *cp;
+
+ start = p->index;
+ count = p->count;
+ if (start >= cmsize || start + count > cmsize)
+#ifdef DEBUG
+ {
+ printf("putcmaperror: start %d cmsize %d count %d\n",
+ start,cmsize,count);
+#endif
+ return (EINVAL);
+#ifdef DEBUG
+ }
+#endif
+
+ if (!useracc(p->red, count, B_WRITE) ||
+ !useracc(p->green, count, B_WRITE) ||
+ !useracc(p->blue, count, B_WRITE))
+ return (EFAULT);
+ for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
+ p->red[i] = cp[3];
+ p->green[i] = cp[2];
+ p->blue[i] = cp[1];
+ }
+ return (0);
+}
+
+/* Write the software shadow colormap */
+static int
+cg14_put_cmap(p, cm, cmsize)
+ register struct fbcmap *p;
+ union cg14cmap *cm;
+ int cmsize;
+{
+ register u_int i, start, count;
+ register u_char *cp;
+
+ start = p->index;
+ count = p->count;
+ if (start >= cmsize || start + count > cmsize)
+#ifdef DEBUG
+ {
+ printf("putcmaperror: start %d cmsize %d count %d\n",
+ start,cmsize,count);
+#endif
+ return (EINVAL);
+#ifdef DEBUG
+ }
+#endif
+
+ if (!useracc(p->red, count, B_READ) ||
+ !useracc(p->green, count, B_READ) ||
+ !useracc(p->blue, count, B_READ))
+ return (EFAULT);
+ for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
+ cp[3] = p->red[i];
+ cp[2] = p->green[i];
+ cp[1] = p->blue[i];
+ cp[0] = 0; /* no alpha channel */
+ }
+ return (0);
+}
+
+static void
+cg14_load_hwcmap(sc, start, ncolors)
+ register struct cgfourteen_softc *sc;
+ register int start, ncolors;
+{
+ /* XXX switch to auto-increment, and on retrace intr */
+
+ /* Setup pointers to source and dest */
+ register u_int32_t *colp = &sc->sc_cmap.cm_chip[start];
+ volatile register u_int32_t *lutp = &sc->sc_clut1->clut_lut[start];
+
+ /* Copy by words */
+ while (--ncolors >= 0)
+ *lutp++ = *colp++;
+}
+
+/*
+ * Load the cursor (overlay `foreground' and `background') colors.
+ */
+static void
+cg14_setcursor(sc)
+ register struct cgfourteen_softc *sc;
+{
+ /* we need to subtract the hot-spot value here */
+#define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
+
+ sc->sc_hwc->curs_ctl = (sc->sc_cursor.cc_enable ? CG14_CURS_ENABLE : 0);
+ sc->sc_hwc->curs_x = COORD(x);
+ sc->sc_hwc->curs_y = COORD(y);
+
+#undef COORD
+}
+
+static void
+cg14_loadcursor(sc)
+ register struct cgfourteen_softc *sc;
+{
+ register volatile struct cg14curs *hwc;
+ register u_int edgemask, m;
+ register int i;
+
+ /*
+ * Keep the top size.x bits. Here we *throw out* the top
+ * size.x bits from an all-one-bits word, introducing zeros in
+ * the top size.x bits, then invert all the bits to get what
+ * we really wanted as our mask. But this fails if size.x is
+ * 32---a sparc uses only the low 5 bits of the shift count---
+ * so we have to special case that.
+ */
+ edgemask = ~0;
+ if (sc->sc_cursor.cc_size.x < 32)
+ edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);
+ hwc = sc->sc_hwc;
+ for (i = 0; i < 32; i++) {
+ m = sc->sc_cursor.cc_eplane[i] & edgemask;
+ hwc->curs_plane0[i] = m;
+ hwc->curs_plane1[i] = m & sc->sc_cursor.cc_cplane[i];
+ }
+}
+
+static void
+cg14_loadomap(sc)
+ register struct cgfourteen_softc *sc;
+{
+ /* set background color */
+ sc->sc_hwc->curs_color1 = sc->sc_cursor.cc_color.cm_chip[0];
+ /* set foreground color */
+ sc->sc_hwc->curs_color2 = sc->sc_cursor.cc_color.cm_chip[1];
+}
diff --git a/sys/arch/sparc/dev/cgfourteenreg.h b/sys/arch/sparc/dev/cgfourteenreg.h
new file mode 100644
index 00000000000..c0fdb1b5c0a
--- /dev/null
+++ b/sys/arch/sparc/dev/cgfourteenreg.h
@@ -0,0 +1,123 @@
+/* $OpenBSD: cgfourteenreg.h,v 1.1 1997/08/08 08:24:49 downsj Exp $ */
+/* $NetBSD: cgfourteenreg.h,v 1.1 1996/09/30 22:41:02 abrown Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * The President and Fellows of Harvard College. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Harvard University and
+ * its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Register/dac/clut/cursor definitions for cgfourteen frame buffer
+ */
+
+/* Locations of control registers in cg14 register set */
+#define CG14_OFFSET_CURS 0x1000
+#define CG14_OFFSET_DAC 0x2000
+#define CG14_OFFSET_XLUT 0x3000
+#define CG14_OFFSET_CLUT1 0x4000
+#define CG14_OFFSET_CLUT2 0x5000
+#define CG14_OFFSET_CLUT3 0x6000
+#define CG14_OFFSET_CLUTINCR 0xf000
+
+/* Main control register set */
+struct cg14ctl {
+ volatile u_int8_t ctl_mctl; /* main control register */
+#define CG14_MCTL_ENABLEINTR 0x80 /* interrupts */
+#define CG14_MCTL_ENABLEVID 0x40 /* enable video */
+#define CG14_MCTL_PIXMODE_MASK 0x30
+#define CG14_MCTL_PIXMODE_8 0x00 /* data is 16 8-bit pixels */
+#define CG14_MCTL_PIXMODE_16 0x20 /* data is 8 16-bit pixels */
+#define CG14_MCTL_PIXMODE_32 0x30 /* data is 4 32-bit pixels */
+#define CG14_MCTL_PIXMODE_SHIFT 4
+#define CG14_MCTL_TMR 0x0c
+#define CG14_MCTL_ENABLETMR 0x02
+#define CG14_MCTL_rev0RESET 0x01
+#define CG14_MCTL_POWERCTL 0x01
+
+ volatile u_int8_t ctl_ppr; /* packed pixel register */
+ volatile u_int8_t ctl_tmsr0; /* test status reg. 0 */
+ volatile u_int8_t ctl_tmsr1; /* test status reg. 1 */
+ volatile u_int8_t ctl_msr; /* master status register */
+ volatile u_int8_t ctl_fsr; /* fault status register */
+ volatile u_int8_t ctl_rsr; /* revision status register */
+#define CG14_RSR_REVMASK 0xf0 /* mask to get revision */
+#define CG14_RSR_IMPLMASK 0x0f /* mask to get impl. code */
+ volatile u_int8_t ctl_ccr; /* clock control register */
+ /* XXX etc. */
+};
+
+/* Hardware cursor map */
+#define CG14_CURS_SIZE 32
+struct cg14curs {
+ volatile u_int32_t curs_plane0[CG14_CURS_SIZE]; /* plane 0 */
+ volatile u_int32_t curs_plane1[CG14_CURS_SIZE];
+ volatile u_int8_t curs_ctl; /* control register */
+#define CG14_CURS_ENABLE 0x4
+#define CG14_CURS_DOUBLEBUFFER 0x2 /* use X-channel for curs */
+ volatile u_int8_t pad0[3];
+ volatile u_int16_t curs_x; /* x position */
+ volatile u_int16_t curs_y; /* y position */
+ volatile u_int32_t curs_color1; /* color register 1 */
+ volatile u_int32_t curs_color2; /* color register 2 */
+ volatile u_int32_t pad[444]; /* pad to 2KB boundary */
+ volatile u_int32_t curs_plane0incr[CG14_CURS_SIZE]; /* autoincr */
+ volatile u_int32_t curs_plane1incr[CG14_CURS_SIZE]; /* autoincr */
+};
+
+/* DAC */
+struct cg14dac {
+ volatile u_int8_t dac_addr; /* address register */
+ volatile u_int8_t pad0[255];
+ volatile u_int8_t dac_gammalut; /* gamma LUT */
+ volatile u_int8_t pad1[255];
+ volatile u_int8_t dac_regsel; /* register select */
+ volatile u_int8_t pad2[255];
+ volatile u_int8_t dac_mode; /* mode register */
+};
+
+#define CG14_CLUT_SIZE 256
+
+/* XLUT registers */
+struct cg14xlut {
+ volatile u_int8_t xlut_lut[CG14_CLUT_SIZE]; /* the LUT */
+ volatile u_int8_t xlut_lutd[CG14_CLUT_SIZE]; /* ??? */
+ volatile u_int8_t pad0[0x600];
+ volatile u_int8_t xlut_lutinc[CG14_CLUT_SIZE]; /* autoincrLUT*/
+ volatile u_int8_t xlut_lutincd[CG14_CLUT_SIZE];
+};
+
+/* Color Look-Up Table (CLUT) */
+struct cg14clut {
+ volatile u_int32_t clut_lut[CG14_CLUT_SIZE]; /* the LUT */
+ volatile u_int32_t clut_lutd[CG14_CLUT_SIZE]; /* ??? */
+ volatile u_int32_t clut_lutinc[CG14_CLUT_SIZE]; /* autoincr */
+ volatile u_int32_t clut_lutincd[CG14_CLUT_SIZE];
+};
diff --git a/sys/arch/sparc/dev/cgfourteenvar.h b/sys/arch/sparc/dev/cgfourteenvar.h
new file mode 100644
index 00000000000..654945e01bb
--- /dev/null
+++ b/sys/arch/sparc/dev/cgfourteenvar.h
@@ -0,0 +1,94 @@
+/* $OpenBSD: cgfourteenvar.h,v 1.1 1997/08/08 08:24:50 downsj Exp $ */
+/* $NetBSD: cgfourteenvar.h,v 1.1 1996/09/30 22:41:03 abrown Exp $ */
+
+/*
+ * Copyright (c) 1996
+ * The President and Fellows of Harvard College. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Harvard University and
+ * its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Layout of cg14 hardware colormap
+ */
+union cg14cmap {
+ u_char cm_map[256][4]; /* 256 R/G/B/A entries (B is high)*/
+ u_int32_t cm_chip[256]; /* the way the chip gets loaded */
+};
+
+/*
+ * cg14 hardware cursor colormap
+ */
+union cg14cursor_cmap { /* colormap, like bt_cmap, but tiny */
+ u_char cm_map[2][4]; /* 2 R/G/B/A entries */
+ u_int32_t cm_chip[2]; /* 2 chip equivalents */
+};
+
+/*
+ * cg14 hardware cursor status
+ */
+struct cg14_cursor { /* cg14 hardware cursor status */
+ short cc_enable; /* cursor is enabled */
+ struct fbcurpos cc_pos; /* position */
+ struct fbcurpos cc_hot; /* hot-spot */
+ struct fbcurpos cc_size; /* size of mask & image fields */
+ u_int cc_eplane[32]; /* enable plane */
+ u_int cc_cplane[32]; /* color plane */
+ union cg14cursor_cmap cc_color; /* cursor colormap */
+};
+
+/*
+ * per-cg14 variables/state
+ */
+struct cgfourteen_softc {
+ struct device sc_dev; /* base device */
+ struct fbdevice sc_fb; /* frame buffer device */
+
+ struct rom_reg sc_phys; /* phys address of frame buffer */
+#if defined(DEBUG) && defined(CG14_MAP_REGS)
+ struct rom_reg sc_regphys; /* phys addr of fb regs; for debug */
+#endif
+ union cg14cmap sc_cmap; /* current colormap */
+
+ struct cg14_cursor sc_cursor; /* Hardware cursor state */
+
+ union cg14cmap sc_saveclut; /* a place to stash PROM state */
+ u_int8_t sc_savexlut[256];
+ u_int8_t sc_savectl;
+ u_int8_t sc_savehwc;
+
+ struct cg14ctl *sc_ctl; /* various registers */
+ struct cg14curs *sc_hwc;
+ struct cg14dac *sc_dac;
+ struct cg14xlut *sc_xlut;
+ struct cg14clut *sc_clut1;
+ struct cg14clut *sc_clut2;
+ struct cg14clut *sc_clut3;
+ u_int *sc_clutincr;
+};
diff --git a/sys/arch/sparc/dev/cgsix.c b/sys/arch/sparc/dev/cgsix.c
index dd967ebf558..f7cf868f8bb 100644
--- a/sys/arch/sparc/dev/cgsix.c
+++ b/sys/arch/sparc/dev/cgsix.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cgsix.c,v 1.7 1996/08/13 08:05:22 downsj Exp $ */
-/* $NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp $ */
+/* $OpenBSD: cgsix.c,v 1.8 1997/08/08 08:24:51 downsj Exp $ */
+/* $NetBSD: cgsix.c,v 1.32 1997/07/29 09:58:04 fair Exp $ */
/*
* Copyright (c) 1993
@@ -122,12 +122,11 @@ struct cgsix_softc {
/* autoconfiguration driver */
static void cgsixattach __P((struct device *, struct device *, void *));
static int cgsixmatch __P((struct device *, void *, void *));
-int cgsixopen __P((dev_t, int, int, struct proc *));
-int cgsixclose __P((dev_t, int, int, struct proc *));
-int cgsixioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgsixmmap __P((dev_t, int, int));
static void cg6_unblank __P((struct device *));
+/* cdevsw prototypes */
+cdev_decl(cgsix);
+
struct cfattach cgsix_ca = {
sizeof(struct cgsix_softc), cgsixmatch, cgsixattach
};
@@ -186,7 +185,8 @@ cgsixmatch(parent, vcf, aux)
* differently on the cgsix than other pfour framebuffers.
*/
bus_untmp();
- tmp = bus_tmp(ra->ra_paddr + CGSIX_FHC_OFFSET, ca->ca_bustype);
+ tmp = (caddr_t)mapdev(ra->ra_reg, TMPMAP_VA, CGSIX_FHC_OFFSET,
+ NBPG);
if (probeget(tmp, 4) == -1)
return (0);
@@ -231,17 +231,13 @@ cgsixattach(parent, self, args)
sc->sc_physadr = ca->ca_ra.ra_reg[0];
sc->sc_bustype = ca->ca_bustype;
sc->sc_bt = bt = (volatile struct bt_regs *)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_bt_un.un_btregs),
- sizeof *sc->sc_bt, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_bt_un.un_btregs),sizeof *sc->sc_bt);
sc->sc_fhc = (volatile int *)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_fhc_un.un_fhc),
- sizeof *sc->sc_fhc, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_fhc_un.un_fhc), sizeof *sc->sc_fhc);
sc->sc_thc = (volatile struct cg6_thc *)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_thc_un.un_thc),
- sizeof *sc->sc_thc, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_thc_un.un_thc), sizeof *sc->sc_thc);
sc->sc_tec = (volatile struct cg6_tec_xxx *)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_tec_un.un_tec),
- sizeof *sc->sc_tec, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_tec_un.un_tec), sizeof *sc->sc_tec);
switch (ca->ca_bustype) {
case BUS_OBIO:
@@ -292,13 +288,13 @@ cgsixattach(parent, self, args)
#if defined(SUN4)
if (CPU_ISSUN4) {
struct eeprom *eep = (struct eeprom *)eeprom_va;
- int constype = (fb->fb_flags & FB_PFOUR) ? EED_CONS_P4 :
- EED_CONS_COLOR;
+ int constype = (fb->fb_flags & FB_PFOUR) ? EE_CONS_P4OPT :
+ EE_CONS_COLOR;
/*
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == constype)
+ if (eep == NULL || eep->eeConsole == constype)
isconsole = (fbconstty != NULL);
else
isconsole = 0;
@@ -329,8 +325,7 @@ cgsixattach(parent, self, args)
printf(" (console)\n");
#ifdef RASTERCONSOLE
sc->sc_fb.fb_pixels = (caddr_t)
- mapiodev(ca->ca_ra.ra_reg, O(cg6_ram[0]),
- ramsize, ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, O(cg6_ram[0]), ramsize);
fbrcons_init(&sc->sc_fb);
#endif
} else
@@ -535,7 +530,7 @@ cgsixioctl(dev, cmd, data, flags, p)
default:
#ifdef DEBUG
- log(LOG_NOTICE, "cgsixioctl(%lx) (%s[%d])\n", cmd,
+ log(LOG_NOTICE, "cgsixioctl(0x%lx) (%s[%d])\n", cmd,
p->p_comm, p->p_pid);
#endif
return (ENOTTY);
@@ -752,13 +747,14 @@ cgsixmmap(dev, off, prot)
u = off - mo->mo_uaddr;
sz = mo->mo_size ? mo->mo_size : sc->sc_fb.fb_type.fb_size;
if (u < sz)
- return (REG2PHYS(&sc->sc_physadr, u + mo->mo_physoff,
- sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_physadr, u + mo->mo_physoff) |
+ PMAP_NC);
}
#ifdef DEBUG
{
register struct proc *p = curproc; /* XXX */
- log(LOG_NOTICE, "cgsixmmap(%x) (%s[%d])\n", off, p->p_comm, p->p_pid);
+ log(LOG_NOTICE, "cgsixmmap(0x%x) (%s[%d])\n",
+ off, p->p_comm, p->p_pid);
}
#endif
return (-1); /* not a user-map offset */
diff --git a/sys/arch/sparc/dev/cgsixreg.h b/sys/arch/sparc/dev/cgsixreg.h
index d9b90977c85..a8a63d0a082 100644
--- a/sys/arch/sparc/dev/cgsixreg.h
+++ b/sys/arch/sparc/dev/cgsixreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: cgsixreg.h,v 1.3 1997/08/08 08:24:52 downsj Exp $ */
/* $NetBSD: cgsixreg.h,v 1.4 1996/02/27 22:09:31 thorpej Exp $ */
/*
diff --git a/sys/arch/sparc/dev/cgthree.c b/sys/arch/sparc/dev/cgthree.c
index 1599048c61d..b978af5fde4 100644
--- a/sys/arch/sparc/dev/cgthree.c
+++ b/sys/arch/sparc/dev/cgthree.c
@@ -1,4 +1,5 @@
-/* $NetBSD: cgthree.c,v 1.27 1996/04/01 17:30:03 christos Exp $ */
+/* $OpenBSD: cgthree.c,v 1.6 1997/08/08 08:24:53 downsj Exp $ */
+/* $NetBSD: cgthree.c,v 1.33 1997/05/24 20:16:11 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -90,12 +91,11 @@ struct cgthree_softc {
/* autoconfiguration driver */
static void cgthreeattach(struct device *, struct device *, void *);
static int cgthreematch(struct device *, void *, void *);
-int cgthreeopen __P((dev_t, int, int, struct proc *));
-int cgthreeclose __P((dev_t, int, int, struct proc *));
-int cgthreeioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgthreemmap __P((dev_t, int, int));
static void cgthreeunblank(struct device *);
+/* cdevsw prototypes */
+cdev_decl(cgthree);
+
struct cfattach cgthree_ca = {
sizeof(struct cgthree_softc), cgthreematch, cgthreeattach
};
@@ -116,6 +116,20 @@ static void cgthreeloadcmap __P((struct cgthree_softc *, int, int));
static void cgthree_set_video __P((struct cgthree_softc *, int));
static int cgthree_get_video __P((struct cgthree_softc *));
+/* Video control parameters */
+struct cg3_videoctrl {
+ unsigned char sense; /* Monitor sense value */
+ unsigned char vctrl[12];
+} cg3_videoctrl[] = {
+/* Missing entries: sense 0x10, 0x30, 0x50 */
+ { 0x40, /* this happens to be my 19'' 1152x900 gray-scale monitor */
+ {0xbb, 0x2b, 0x3, 0xb, 0xb3, 0x3, 0xaf, 0x2b, 0x2, 0xa, 0xff, 0x1}
+ },
+ { 0x00, /* default? must be last */
+ {0xbb, 0x2b, 0x3, 0xb, 0xb3, 0x3, 0xaf, 0x2b, 0x2, 0xa, 0xff, 0x1}
+ }
+};
+
/*
* Match a cgthree.
*/
@@ -206,11 +220,28 @@ cgthreeattach(parent, self, args)
if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
/* this probably cannot happen, but what the heck */
sc->sc_fb.fb_pixels = mapiodev(ca->ca_ra.ra_reg, CG3REG_MEM,
- ramsize, ca->ca_bustype);
+ ramsize);
}
sc->sc_fbc = (volatile struct fbcontrol *)
mapiodev(ca->ca_ra.ra_reg, CG3REG_REG,
- sizeof(struct fbcontrol), ca->ca_bustype);
+ sizeof(struct fbcontrol));
+
+ /* Transfer video magic to board, if it's not running */
+ if ((sc->sc_fbc->fbc_ctrl & FBC_TIMING) == 0)
+ for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]);
+ i++) {
+ volatile struct fbcontrol *fbc = sc->sc_fbc;
+ if ((fbc->fbc_status & FBS_MSENSE) ==
+ cg3_videoctrl[i].sense) {
+ int j;
+ printf(" setting video ctrl");
+ for (j = 0; j < 12; j++)
+ fbc->fbc_vcontrol[j] =
+ cg3_videoctrl[i].vctrl[j];
+ fbc->fbc_ctrl |= FBC_TIMING;
+ break;
+ }
+ }
sc->sc_phys = ca->ca_ra.ra_reg[0];
sc->sc_bustype = ca->ca_bustype;
@@ -408,5 +439,5 @@ cgthreemmap(dev, off, prot)
* I turned on PMAP_NC here to disable the cache as I was
* getting horribly broken behaviour with it on.
*/
- return (REG2PHYS(&sc->sc_phys, CG3REG_MEM+off, sc->sc_bustype) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, CG3REG_MEM+off) | PMAP_NC);
}
diff --git a/sys/arch/sparc/dev/cgthreereg.h b/sys/arch/sparc/dev/cgthreereg.h
index 073cc52e66c..89811921252 100644
--- a/sys/arch/sparc/dev/cgthreereg.h
+++ b/sys/arch/sparc/dev/cgthreereg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: cgthreereg.h,v 1.3 1997/08/08 08:24:54 downsj Exp $ */
/* $NetBSD: cgthreereg.h,v 1.5 1996/02/27 00:14:17 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/cgtwo.c b/sys/arch/sparc/dev/cgtwo.c
index 8c5dcc8f11a..e682f6b8a26 100644
--- a/sys/arch/sparc/dev/cgtwo.c
+++ b/sys/arch/sparc/dev/cgtwo.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cgtwo.c,v 1.10 1996/08/13 08:05:23 downsj Exp $ */
-/* $NetBSD: cgtwo.c,v 1.16 1996/05/18 12:19:14 mrg Exp $ */
+/* $OpenBSD: cgtwo.c,v 1.11 1997/08/08 08:24:55 downsj Exp $ */
+/* $NetBSD: cgtwo.c,v 1.22 1997/05/24 20:16:12 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -92,14 +92,13 @@ struct cgtwo_softc {
/* autoconfiguration driver */
static void cgtwoattach __P((struct device *, struct device *, void *));
static int cgtwomatch __P((struct device *, void *, void *));
-int cgtwoopen __P((dev_t, int, int, struct proc *));
-int cgtwoclose __P((dev_t, int, int, struct proc *));
-int cgtwoioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int cgtwommap __P((dev_t, int, int));
static void cgtwounblank __P((struct device *));
int cgtwogetcmap __P((struct cgtwo_softc *, struct fbcmap *));
int cgtwoputcmap __P((struct cgtwo_softc *, struct fbcmap *));
+/* cdevsw prototypes */
+cdev_decl(cgtwo);
+
struct cfattach cgtwo_ca = {
sizeof(struct cgtwo_softc), cgtwomatch, cgtwoattach
};
@@ -148,7 +147,7 @@ cgtwomatch(parent, vcf, aux)
/* XXX - Must do our own mapping at CG2_CTLREG_OFF */
bus_untmp();
- tmp = (caddr_t)bus_tmp(ra->ra_paddr + CG2_CTLREG_OFF, ca->ca_bustype);
+ tmp = (caddr_t)mapdev(ra->ra_reg, TMPMAP_VA, CG2_CTLREG_OFF, NBPG);
if (probeget(tmp, 2) != -1)
return 1;
#endif
@@ -207,20 +206,21 @@ cgtwoattach(parent, self, args)
* Assume this is the console if there's no eeprom info
* to be found.
*/
- if (eep == NULL || eep->ee_diag.eed_console == EED_CONS_COLOR)
+ if (eep == NULL || eep->eeConsole == EE_CONS_COLOR)
isconsole = (fbconstty != NULL);
else
isconsole = 0;
}
#endif
sc->sc_phys = ca->ca_ra.ra_reg[0];
+ /* Apparently, the pixels are 32-bit data space */
+ sc->sc_phys.rr_iospace = PMAP_VME32;
sc->sc_bustype = ca->ca_bustype;
if ((sc->sc_fb.fb_pixels = ca->ca_ra.ra_vaddr) == NULL && isconsole) {
/* this probably cannot happen, but what the heck */
- sc->sc_fb.fb_pixels = mapiodev(ca->ca_ra.ra_reg, CG2_PIXMAP_OFF,
- CG2_PIXMAP_SIZE,
- PMAP_VME32/*ca->ca_bustype*/);
+ sc->sc_fb.fb_pixels = mapiodev(&sc->sc_phys, CG2_PIXMAP_OFF,
+ CG2_PIXMAP_SIZE);
}
#ifndef offsetof
#define offsetof(type, member) ((size_t)(&((type *)0)->member))
@@ -229,12 +229,12 @@ cgtwoattach(parent, self, args)
sc->sc_reg = (volatile struct cg2statusreg *)
mapiodev(ca->ca_ra.ra_reg,
CG2_ROPMEM_OFF + offsetof(struct cg2fb, status.reg),
- sizeof(struct cg2statusreg), ca->ca_bustype);
+ sizeof(struct cg2statusreg));
sc->sc_cmap = (volatile u_short *)
mapiodev(ca->ca_ra.ra_reg,
CG2_ROPMEM_OFF + offsetof(struct cg2fb, redmap[0]),
- 3 * CG2_CMSIZE, ca->ca_bustype);
+ 3 * CG2_CMSIZE);
if (isconsole) {
printf(" (console)\n");
@@ -432,5 +432,5 @@ cgtwommap(dev, off, prot)
if ((unsigned)off >= sc->sc_fb.fb_type.fb_size)
return (-1);
- return (REG2PHYS(&sc->sc_phys, off, PMAP_VME32/*sc->sc_bustype*/) | PMAP_NC);
+ return (REG2PHYS(&sc->sc_phys, off) | PMAP_NC);
}
diff --git a/sys/arch/sparc/dev/cons.c b/sys/arch/sparc/dev/cons.c
index 11a1606bae8..fba5c2e4eb1 100644
--- a/sys/arch/sparc/dev/cons.c
+++ b/sys/arch/sparc/dev/cons.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: cons.c,v 1.5 1996/08/13 08:05:24 downsj Exp $ */
-/* $NetBSD: cons.c,v 1.23.4.1 1996/06/02 09:07:53 mrg Exp $ */
+/* $OpenBSD: cons.c,v 1.6 1997/08/08 08:24:56 downsj Exp $ */
+/* $NetBSD: cons.c,v 1.30 1997/07/07 23:30:23 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -70,6 +70,11 @@
#include <machine/autoconf.h>
#include <machine/conf.h>
+#ifdef RASTERCONSOLE
+#include <machine/fbio.h>
+#include <machine/fbvar.h>
+#endif
+
#include "zs.h"
struct tty *constty = 0; /* virtual console output device */
@@ -286,20 +291,30 @@ cnopen(dev, flag, mode, p)
/* output queue doesn't need quoting */
clalloc(&tp->t_outq, 1024, 0);
tty_attach(tp);
+
/*
* get the console struct winsize.
*/
+#ifdef RASTERCONSOLE
+ if (fbconstty) {
+ rows = fbrcons_rows();
+ cols = fbrcons_cols();
+ }
+#endif
+
if (CPU_ISSUN4COR4M) {
int i;
char *prop;
- if ((prop = getpropstring(optionsnode, "screen-#rows"))) {
+ if (rows == 0 &&
+ (prop = getpropstring(optionsnode, "screen-#rows"))) {
i = 0;
while (*prop != '\0')
i = i * 10 + *prop++ - '0';
rows = (unsigned short)i;
}
- if ((prop = getpropstring(optionsnode, "screen-#columns"))) {
+ if (cols == 0 &&
+ (prop = getpropstring(optionsnode, "screen-#columns"))) {
i = 0;
while (*prop != '\0')
i = i * 10 + *prop++ - '0';
@@ -310,8 +325,10 @@ cnopen(dev, flag, mode, p)
struct eeprom *ep = (struct eeprom *)eeprom_va;
if (ep) {
- rows = (u_short)ep->ee_diag.eed_rowsize;
- cols = (u_short)ep->ee_diag.eed_colsize;
+ if (rows == 0)
+ rows = (u_short)ep->eeTtyRows;
+ if (cols == 0)
+ cols = (u_short)ep->eeTtyCols;
}
}
firstopen = 0;
diff --git a/sys/arch/sparc/dev/dma.c b/sys/arch/sparc/dev/dma.c
index 4c961cac690..c01200a20c1 100644
--- a/sys/arch/sparc/dev/dma.c
+++ b/sys/arch/sparc/dev/dma.c
@@ -1,4 +1,5 @@
-/* $NetBSD: dma.c,v 1.28.2.2 1996/07/02 23:46:29 jtc Exp $ */
+/* $OpenBSD: dma.c,v 1.8 1997/08/08 08:24:57 downsj Exp $ */
+/* $NetBSD: dma.c,v 1.45 1997/07/29 09:58:06 fair Exp $ */
/*
* Copyright (c) 1994 Paul Kranenburg. All rights reserved.
@@ -45,19 +46,25 @@
#include <sparc/autoconf.h>
#include <sparc/cpu.h>
+#include <sparc/sparc/cpuvar.h>
+
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+
#include <sparc/dev/sbusvar.h>
#include <sparc/dev/dmareg.h>
#include <sparc/dev/dmavar.h>
-#include <sparc/dev/espreg.h>
#include <sparc/dev/espvar.h>
int dmaprint __P((void *, const char *));
void dmaattach __P((struct device *, struct device *, void *));
int dmamatch __P((struct device *, void *, void *));
-void dma_reset __P((struct dma_softc *));
+void dma_reset __P((struct dma_softc *, int));
+void espdma_reset __P((struct dma_softc *));
+void ledma_reset __P((struct dma_softc *));
void dma_enintr __P((struct dma_softc *));
int dma_isintr __P((struct dma_softc *));
int espdmaintr __P((struct dma_softc *));
@@ -100,7 +107,7 @@ dmamatch(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -131,8 +138,7 @@ dmaattach(parent, self, aux)
if (ca->ca_ra.ra_vaddr == NULL || ca->ca_ra.ra_nvaddrs == 0)
ca->ca_ra.ra_vaddr =
- mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len,
- ca->ca_bustype);
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
sc->sc_regs = (struct dma_regs *) ca->ca_ra.ra_vaddr;
@@ -156,35 +162,24 @@ dmaattach(parent, self, aux)
}
delay(20000); /* manual says we need 20ms delay */
}
-
+
/*
- * Get transfer burst size from PROM and plug it into the controller
- * registers. This is needed on the Sun4m; do others need it too?
- * XXX
+ * Get transfer burst size from PROM and plug it into the
+ * controller registers. This is needed on the Sun4m; do
+ * others need it too?
*/
if (CPU_ISSUN4M) {
+ int sbusburst = ((struct sbus_softc *)parent)->sc_burst;
+ if (sbusburst == 0)
+ sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
+
sc->sc_burst = getpropint(ca->ca_ra.ra_node,"burst-sizes", -1);
- if (sc->sc_burst == -1) {
- /* check parent SBus for burst sizes */
- if (((struct sbus_softc *)parent)->sc_burst == 0)
- sc->sc_burst = SBUS_BURST_32 - 1; /* 1->16 */
- else
- sc->sc_burst =
- ((struct sbus_softc *)parent)->sc_burst;
- }
- sc->sc_regs->csr &= ~D_BURST_SIZE; /* must clear first */
- if (sc->sc_burst & SBUS_BURST_32) {
- sc->sc_regs->csr |= D_BURST_32;
- } else if (sc->sc_burst & SBUS_BURST_16) {
- sc->sc_regs->csr |= D_BURST_16;
- } else if (strcmp(ca->ca_ra.ra_name,"espdma") == 0) {
- /* only espdma supports non-burst */
- sc->sc_regs->csr |= D_BURST_0;
-#ifdef DIAGNOSTIC
- } else {
- printf(" <unknown burst size 0x%x>", sc->sc_burst);
-#endif
- }
+ if (sc->sc_burst == -1)
+ /* take SBus burst sizes */
+ sc->sc_burst = sbusburst;
+
+ /* Clamp at parent's burst sizes */
+ sc->sc_burst &= sbusburst;
}
printf(": rev ");
@@ -193,6 +188,9 @@ dmaattach(parent, self, aux)
case DMAREV_0:
printf("0");
break;
+ case DMAREV_ESC:
+ printf("esc");
+ break;
case DMAREV_1:
printf("1");
break;
@@ -203,19 +201,20 @@ dmaattach(parent, self, aux)
printf("2");
break;
default:
- printf("unknown");
+ printf("unknown (0x%x)", sc->sc_rev);
}
printf("\n");
/* indirect functions */
if (sc->sc_dev.dv_cfdata->cf_attach == &dma_ca) {
+ sc->reset = espdma_reset;
sc->intr = espdmaintr;
} else {
+ sc->reset = ledma_reset;
sc->intr = ledmaintr;
}
sc->enintr = dma_enintr;
sc->isintr = dma_isintr;
- sc->reset = dma_reset;
sc->setup = dma_setup;
sc->go = dma_go;
@@ -272,24 +271,94 @@ espsearch:
}
}
+#define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \
+ int count = 500000; \
+ while ((COND) && --count > 0) DELAY(1); \
+ if (count == 0) { \
+ printf("%s: line %d: CSR = 0x%lx\n", __FILE__, __LINE__, \
+ (SC)->sc_regs->csr); \
+ if (DONTPANIC) \
+ printf(MSG); \
+ else \
+ panic(MSG); \
+ } \
+} while (0)
+
+#define DMA_DRAIN(sc, dontpanic) do { \
+ /* \
+ * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \
+ * and "drain" bits while it is still thinking about a \
+ * request. \
+ * other revs: D_R_PEND bit reads as 0 \
+ */ \
+ DMAWAIT(sc, sc->sc_regs->csr & D_R_PEND, "R_PEND", dontpanic); \
+ /* \
+ * Select drain bit based on revision \
+ * also clears errors and D_TC flag \
+ */ \
+ if (sc->sc_rev == DMAREV_1 || sc->sc_rev == DMAREV_0) \
+ DMACSR(sc) |= D_DRAIN; \
+ else \
+ DMACSR(sc) |= D_INVALIDATE; \
+ /* \
+ * Wait for draining to finish \
+ * rev0 & rev1 call this PACKCNT \
+ */ \
+ DMAWAIT(sc, sc->sc_regs->csr & D_DRAINING, "DRAINING", dontpanic);\
+} while(0)
+
void
-dma_reset(sc)
+dma_reset(sc, isledma)
struct dma_softc *sc;
+ int isledma;
{
- DMAWAIT(sc);
- DMA_DRAIN(sc); /* Drain (DMA rev 1) */
+ DMA_DRAIN(sc, 1);
DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */
- DMAWAIT1(sc); /* let things drain */
DMACSR(sc) |= D_RESET; /* reset DMA */
DELAY(200); /* what should this be ? */
- DMAWAIT1(sc);
+ /*DMAWAIT1(sc); why was this here? */
DMACSR(sc) &= ~D_RESET; /* de-assert reset line */
DMACSR(sc) |= D_INT_EN; /* enable interrupts */
- if (sc->sc_rev > DMAREV_1)
+ if (sc->sc_rev > DMAREV_1 && isledma == 0)
DMACSR(sc) |= D_FASTER;
+
+ switch (sc->sc_rev) {
+ case DMAREV_2:
+ sc->sc_regs->csr &= ~D_BURST_SIZE; /* must clear first */
+ if (sc->sc_burst & SBUS_BURST_32) {
+ DMACSR(sc) |= D_BURST_32;
+ } else if (sc->sc_burst & SBUS_BURST_16) {
+ DMACSR(sc) |= D_BURST_16;
+ } else {
+ DMACSR(sc) |= D_BURST_0;
+ }
+ break;
+ case DMAREV_ESC:
+ DMACSR(sc) |= D_AUTODRAIN; /* Auto-drain */
+ if (sc->sc_burst & SBUS_BURST_32) {
+ DMACSR(sc) &= ~0x800;
+ } else
+ DMACSR(sc) |= 0x800;
+ break;
+ default:
+ }
+
sc->sc_active = 0; /* and of course we aren't */
}
+void
+espdma_reset(sc)
+ struct dma_softc *sc;
+{
+ dma_reset(sc, 0);
+}
+
+void
+ledma_reset(sc)
+ struct dma_softc *sc;
+{
+ dma_reset(sc, 1);
+}
void
dma_enintr(sc)
@@ -321,12 +390,7 @@ dma_setup(sc, addr, len, datain, dmasize)
{
u_long csr;
- /* clear errors and D_TC flag */
- DMAWAIT(sc);
- DMA_DRAIN(sc); /* ? */
- DMAWAIT1(sc);
- DMACSR(sc) |= D_INVALIDATE;
- DMAWAIT1(sc);
+ DMA_DRAIN(sc, 0);
#if 0
DMACSR(sc) &= ~D_INT_EN;
@@ -334,7 +398,7 @@ dma_setup(sc, addr, len, datain, dmasize)
sc->sc_dmaaddr = addr;
sc->sc_dmalen = len;
- ESP_DMA(("%s: start %d@%p,%d\n", sc->sc_dev.dv_xname,
+ NCR_DMA(("%s: start %d@%p,%d\n", sc->sc_dev.dv_xname,
*sc->sc_dmalen, *sc->sc_dmaaddr, datain ? 1 : 0));
/*
@@ -345,7 +409,7 @@ dma_setup(sc, addr, len, datain, dmasize)
*dmasize = sc->sc_dmasize =
min(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
- ESP_DMA(("dma_setup: dmasize = %d\n", sc->sc_dmasize));
+ NCR_DMA(("dma_setup: dmasize = %d\n", sc->sc_dmasize));
/* Program the DMA address */
if (CPU_ISSUN4M && sc->sc_dmasize) {
@@ -361,6 +425,14 @@ dma_setup(sc, addr, len, datain, dmasize)
} else
DMADDR(sc) = *sc->sc_dmaaddr;
+ if (sc->sc_rev == DMAREV_ESC) {
+ /* DMA ESC chip bug work-around */
+ register long bcnt = sc->sc_dmasize;
+ register long eaddr = bcnt + (long)*sc->sc_dmaaddr;
+ if ((eaddr & PGOFSET) != 0)
+ bcnt = roundup(bcnt, NBPG);
+ DMACNT(sc) = bcnt;
+ }
/* Setup DMA control register */
csr = DMACSR(sc);
if (datain)
@@ -394,11 +466,12 @@ int
espdmaintr(sc)
struct dma_softc *sc;
{
+ struct ncr53c9x_softc *nsc = &sc->sc_esp->sc_ncr53c9x;
int trans, resid;
u_long csr;
csr = DMACSR(sc);
- ESP_DMA(("%s: intr: addr %p, csr %b\n", sc->sc_dev.dv_xname,
+ NCR_DMA(("%s: intr: addr %p, csr %b\n", sc->sc_dev.dv_xname,
DMADDR(sc), csr, DMACSRBITS));
if (csr & D_ERR_PEND) {
@@ -406,19 +479,14 @@ espdmaintr(sc)
DMACSR(sc) |= D_INVALIDATE;
printf("%s: error: csr=%b\n", sc->sc_dev.dv_xname,
csr, DMACSRBITS);
- return 0;
+ return -1;
}
/* This is an "assertion" :) */
if (sc->sc_active == 0)
panic("dmaintr: DMA wasn't active");
- /* clear errors and D_TC flag */
- DMAWAIT(sc);
- DMA_DRAIN(sc); /* ? */
- DMAWAIT1(sc);
- DMACSR(sc) |= D_INVALIDATE;
- DMAWAIT1(sc);
+ DMA_DRAIN(sc, 0);
/* DMA has stopped */
DMACSR(sc) &= ~D_EN_DMA;
@@ -426,11 +494,11 @@ espdmaintr(sc)
if (sc->sc_dmasize == 0) {
/* A "Transfer Pad" operation completed */
- ESP_DMA(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
- ESP_READ_REG(sc->sc_esp, ESP_TCL) |
- (ESP_READ_REG(sc->sc_esp, ESP_TCM) << 8),
- ESP_READ_REG(sc->sc_esp, ESP_TCL),
- ESP_READ_REG(sc->sc_esp, ESP_TCM)));
+ NCR_DMA(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
+ NCR_READ_REG(nsc, NCR_TCL) |
+ (NCR_READ_REG(nsc, NCR_TCM) << 8),
+ NCR_READ_REG(nsc, NCR_TCL),
+ NCR_READ_REG(nsc, NCR_TCM)));
return 0;
}
@@ -442,44 +510,50 @@ espdmaintr(sc)
* bytes are clocked into the FIFO.
*/
if (!(csr & D_WRITE) &&
- (resid = (ESP_READ_REG(sc->sc_esp, ESP_FFLAG) & ESPFIFO_FF)) != 0) {
- ESP_DMA(("dmaintr: empty esp FIFO of %d ", resid));
- ESPCMD(sc->sc_esp, ESPCMD_FLUSH);
+ (resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
+ NCR_DMA(("dmaintr: empty esp FIFO of %d ", resid));
}
- if ((sc->sc_esp->sc_espstat & ESPSTAT_TC) == 0) {
+ if ((nsc->sc_espstat & NCRSTAT_TC) == 0) {
/*
* `Terminal count' is off, so read the residue
* out of the ESP counter registers.
*/
- resid += ( ESP_READ_REG(sc->sc_esp, ESP_TCL) |
- (ESP_READ_REG(sc->sc_esp, ESP_TCM) << 8) |
- ((sc->sc_esp->sc_cfg2 & ESPCFG2_FE)
- ? (ESP_READ_REG(sc->sc_esp, ESP_TCH) << 16)
+ resid += (NCR_READ_REG(nsc, NCR_TCL) |
+ (NCR_READ_REG(nsc, NCR_TCM) << 8) |
+ ((nsc->sc_cfg2 & NCRCFG2_FE)
+ ? (NCR_READ_REG(nsc, NCR_TCH) << 16)
: 0));
if (resid == 0 && sc->sc_dmasize == 65536 &&
- (sc->sc_esp->sc_cfg2 & ESPCFG2_FE) == 0)
+ (nsc->sc_cfg2 & NCRCFG2_FE) == 0)
/* A transfer of 64K is encoded as `TCL=TCM=0' */
resid = 65536;
}
trans = sc->sc_dmasize - resid;
if (trans < 0) { /* transferred < 0 ? */
+#if 0
+ /*
+ * This situation can happen in perfectly normal operation
+ * if the ESP is reselected while using DMA to select
+ * another target. As such, don't print the warning.
+ */
printf("%s: xfer (%d) > req (%d)\n",
sc->sc_dev.dv_xname, trans, sc->sc_dmasize);
+#endif
trans = sc->sc_dmasize;
}
- ESP_DMA(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
- ESP_READ_REG(sc->sc_esp, ESP_TCL),
- ESP_READ_REG(sc->sc_esp, ESP_TCM),
- (sc->sc_esp->sc_cfg2 & ESPCFG2_FE)
- ? ESP_READ_REG(sc->sc_esp, ESP_TCH) : 0,
+ NCR_DMA(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
+ NCR_READ_REG(nsc, NCR_TCL),
+ NCR_READ_REG(nsc, NCR_TCM),
+ (nsc->sc_cfg2 & NCRCFG2_FE)
+ ? NCR_READ_REG(nsc, NCR_TCH) : 0,
trans, resid));
if (csr & D_WRITE)
- cache_flush(*sc->sc_dmaaddr, trans);
+ cpuinfo.cache_flush(*sc->sc_dmaaddr, trans);
if (CPU_ISSUN4M && sc->sc_dvmakaddr)
dvma_mapout((vm_offset_t)sc->sc_dvmakaddr,
@@ -490,7 +564,7 @@ espdmaintr(sc)
#if 0 /* this is not normal operation just yet */
if (*sc->sc_dmalen == 0 ||
- sc->sc_esp->sc_phase != sc->sc_esp->sc_prevphase)
+ nsc->sc_phase != nsc->sc_prevphase)
return 0;
/* and again */
@@ -515,11 +589,11 @@ ledmaintr(sc)
csr = DMACSR(sc);
if (csr & D_ERR_PEND) {
- printf("Lance DMA error, see your doctor!\n");
DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */
DMACSR(sc) |= D_INVALIDATE;
printf("%s: error: csr=%b\n", sc->sc_dev.dv_xname,
- (u_int)csr, DMACSRBITS);
+ csr, DMACSRBITS);
+ DMA_RESET(sc);
}
return 1;
}
diff --git a/sys/arch/sparc/dev/dmareg.h b/sys/arch/sparc/dev/dmareg.h
index 3998581845a..c9e575a262f 100644
--- a/sys/arch/sparc/dev/dmareg.h
+++ b/sys/arch/sparc/dev/dmareg.h
@@ -1,4 +1,5 @@
-/* $NetBSD: dmareg.h,v 1.8 1996/04/22 02:34:58 abrown Exp $ */
+/* $OpenBSD: dmareg.h,v 1.4 1997/08/08 08:24:58 downsj Exp $ */
+/* $NetBSD: dmareg.h,v 1.10 1996/11/28 09:37:34 pk Exp $ */
/*
* Copyright (c) 1994 Peter Galbavy. All rights reserved.
@@ -38,19 +39,21 @@ struct dma_regs {
#define D_INT_EN 0x00000010 /* interrupt enable */
#define D_INVALIDATE 0x00000020 /* invalidate fifo */
#define D_SLAVE_ERR 0x00000040 /* slave access size error */
-#define D_DRAIN 0x00000040 /* drain fifo if DMAREV_1 */
+#define D_DRAIN 0x00000040 /* rev0,1,esc: drain fifo */
#define D_RESET 0x00000080 /* reset scsi */
#define D_WRITE 0x00000100 /* 1 = dev -> mem */
#define D_EN_DMA 0x00000200 /* enable DMA requests */
-#define D_R_PEND 0x00000400 /* something only on ver < 2 */
+#define D_R_PEND 0x00000400 /* rev0,1: request pending */
+#define D_ESC_BURST 0x00000800 /* DMA ESC: 16 byte bursts */
#define D_EN_CNT 0x00002000 /* enable byte counter */
#define D_TC 0x00004000 /* terminal count */
#define D_DSBL_CSR_DRN 0x00010000 /* disable fifo drain on csr */
#define D_DSBL_SCSI_DRN 0x00020000 /* disable fifo drain on reg */
#define D_BURST_SIZE 0x000c0000 /* sbus read/write burst size */
#define D_BURST_0 0x00080000 /* no bursts (SCSI-only) */
-#define D_BURST_16 0x00040000 /* 16-byte bursts */
-#define D_BURST_32 0x00000000 /* 32-byte bursts */
+#define D_BURST_16 0x00000000 /* 16-byte bursts */
+#define D_BURST_32 0x00040000 /* 32-byte bursts */
+#define D_AUTODRAIN 0x00040000 /* DMA ESC: Auto-drain */
#define D_DIAG 0x00100000 /* disable fifo drain on addr */
#define D_TWO_CYCLE 0x00200000 /* 2 clocks per transfer */
#define D_FASTER 0x00400000 /* 3 clocks per transfer */
@@ -62,6 +65,7 @@ struct dma_regs {
#define D_NA_LOADED 0x08000000 /* next address loaded */
#define D_DEV_ID 0xf0000000 /* device ID */
#define DMAREV_0 0x00000000 /* Sunray DMA */
+#define DMAREV_ESC 0x40000000 /* DMA ESC array */
#define DMAREV_1 0x80000000 /* 'DMA' */
#define DMAREV_PLUS 0x90000000 /* 'DMA+' */
#define DMAREV_2 0xa0000000 /* 'DMA2' */
diff --git a/sys/arch/sparc/dev/dmavar.h b/sys/arch/sparc/dev/dmavar.h
index 6bc42333a98..57fbbcad5e4 100644
--- a/sys/arch/sparc/dev/dmavar.h
+++ b/sys/arch/sparc/dev/dmavar.h
@@ -1,4 +1,5 @@
-/* $NetBSD: dmavar.h,v 1.8 1996/04/22 02:35:00 abrown Exp $ */
+/* $OpenBSD: dmavar.h,v 1.4 1997/08/08 08:24:59 downsj Exp $ */
+/* $NetBSD: dmavar.h,v 1.11 1996/11/27 21:49:53 pk Exp $ */
/*
* Copyright (c) 1994 Peter Galbavy. All rights reserved.
@@ -35,7 +36,7 @@ struct dma_softc {
struct le_softc *sc_le; /* my ethernet */
struct dma_regs *sc_regs; /* the registers */
int sc_active; /* DMA active ? */
- int sc_rev; /* revision */
+ u_int sc_rev; /* revision */
int sc_node; /* PROM node ID */
int sc_burst; /* DVMA burst size in effect */
caddr_t sc_dvmakaddr; /* DVMA cookies */
@@ -53,32 +54,7 @@ struct dma_softc {
#define DMACSR(sc) (sc->sc_regs->csr)
#define DMADDR(sc) (sc->sc_regs->addr)
-
-/*
- * We are not allowed to touch the DMA "flush" and "drain" bits
- * while it is still thinking about a request (DMA_RP).
- */
-
-/*
- * TIME WAIT (to debug hanging machine problem)
- */
-
-#define TIME_WAIT(COND, MSG, SC) { int count = 500000; \
- while (--count > 0 && (COND)) DELAY(1); \
- if (count == 0) { \
- printf("CSR = %lx\n",\
- SC->sc_regs->csr);\
- panic(MSG); } \
- }
-
-#define DMAWAIT(sc) TIME_WAIT((sc->sc_regs->csr & D_R_PEND), "DMAWAIT", sc)
-#define DMAWAIT1(sc) TIME_WAIT((sc->sc_regs->csr & D_DRAINING), "DMAWAIT1", sc)
-#define DMAREADY(sc) TIME_WAIT((!(sc->sc_regs->csr & D_DMA_ON)), "DMAREADY", sc)
-
-#define DMA_DRAIN(sc) if (sc->sc_rev < DMAREV_2) { \
- DMACSR(sc) |= D_DRAIN; \
- DMAWAIT1(sc); \
- }
+#define DMACNT(sc) (sc->sc_regs->bcnt)
/* DMA engine functions */
#define DMA_ENINTR(r) (((r)->enintr)(r))
diff --git a/sys/arch/sparc/dev/esp.c b/sys/arch/sparc/dev/esp.c
index 5cb9d216931..48c211f8ea2 100644
--- a/sys/arch/sparc/dev/esp.c
+++ b/sys/arch/sparc/dev/esp.c
@@ -1,4 +1,65 @@
-/* $NetBSD: esp.c,v 1.47.2.1 1996/06/12 20:46:52 pk Exp $ */
+/* $OpenBSD: esp.c,v 1.10 1997/08/08 08:25:00 downsj Exp $ */
+/* $NetBSD: esp.c,v 1.68 1997/07/19 21:57:01 pk Exp $ */
+
+/*
+ * Copyright (c) 1997 Jason R. Thorpe.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Jason R. Thorpe.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Charles M. Hannum.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
/*
* Copyright (c) 1994 Peter Galbavy
@@ -58,35 +119,17 @@
#include <machine/cpu.h>
#include <machine/autoconf.h>
+
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+
#include <sparc/dev/sbusvar.h>
#include <sparc/dev/dmareg.h>
#include <sparc/dev/dmavar.h>
-#include <sparc/dev/espreg.h>
#include <sparc/dev/espvar.h>
-int esp_debug = 0; /*ESP_SHOWPHASE|ESP_SHOWMISC|ESP_SHOWTRAC|ESP_SHOWCMDS;*/
-
-/*static*/ void espattach __P((struct device *, struct device *, void *));
-/*static*/ int espmatch __P((struct device *, void *, void *));
-/*static*/ int espprint __P((void *, const char *));
-/*static*/ u_int esp_adapter_info __P((struct esp_softc *));
-/*static*/ void espreadregs __P((struct esp_softc *));
-/*static*/ void espselect __P((struct esp_softc *,
- u_char, u_char, u_char *, u_char));
-/*static*/ void esp_scsi_reset __P((struct esp_softc *));
-/*static*/ void esp_reset __P((struct esp_softc *));
-/*static*/ void esp_init __P((struct esp_softc *, int));
-/*static*/ int esp_scsi_cmd __P((struct scsi_xfer *));
-/*static*/ int esp_poll __P((struct esp_softc *, struct ecb *));
-/*static*/ void esp_sched __P((struct esp_softc *));
-/*static*/ void esp_done __P((struct ecb *));
-/*static*/ void esp_msgin __P((struct esp_softc *));
-/*static*/ void esp_msgout __P((struct esp_softc *));
-/*static*/ int espintr __P((struct esp_softc *));
-/*static*/ void esp_timeout __P((void *arg));
-/*static*/ void esp_abort __P((struct esp_softc *, struct ecb *));
-int esp_stp2cpb __P((struct esp_softc *, int));
-int esp_cpb2stp __P((struct esp_softc *, int));
+void espattach __P((struct device *, struct device *, void *));
+int espmatch __P((struct device *, void *, void *));
/* Linkup to the rest of the kernel */
struct cfattach esp_ca = {
@@ -98,7 +141,7 @@ struct cfdriver esp_cd = {
};
struct scsi_adapter esp_switch = {
- esp_scsi_cmd,
+ ncr53c9x_scsi_cmd,
minphys, /* no max at this level; handled by DMA code */
NULL,
NULL,
@@ -111,22 +154,39 @@ struct scsi_device esp_dev = {
NULL, /* Use default 'done' routine */
};
-int
-espprint(aux, name)
- void *aux;
- const char *name;
-{
- if (name != NULL)
- printf("%s: scsibus ", name);
- return UNCONF;
-}
+/*
+ * Functions and the switch for the MI code.
+ */
+u_char esp_read_reg __P((struct ncr53c9x_softc *, int));
+void esp_write_reg __P((struct ncr53c9x_softc *, int, u_char));
+int esp_dma_isintr __P((struct ncr53c9x_softc *));
+void esp_dma_reset __P((struct ncr53c9x_softc *));
+int esp_dma_intr __P((struct ncr53c9x_softc *));
+int esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
+ size_t *, int, size_t *));
+void esp_dma_go __P((struct ncr53c9x_softc *));
+void esp_dma_stop __P((struct ncr53c9x_softc *));
+int esp_dma_isactive __P((struct ncr53c9x_softc *));
+
+struct ncr53c9x_glue esp_glue = {
+ esp_read_reg,
+ esp_write_reg,
+ esp_dma_isintr,
+ esp_dma_reset,
+ esp_dma_intr,
+ esp_dma_setup,
+ esp_dma_go,
+ esp_dma_stop,
+ esp_dma_isactive,
+ NULL, /* gl_clear_latched_intr */
+};
int
espmatch(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -147,11 +207,17 @@ espattach(parent, self, aux)
void *aux;
{
register struct confargs *ca = aux;
- struct esp_softc *sc = (void *)self;
+ struct esp_softc *esc = (void *)self;
+ struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
struct bootpath *bp;
int dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
/*
+ * Set up glue for MI code early; we use some of it here.
+ */
+ sc->sc_glue = &esp_glue;
+
+ /*
* Make sure things are sane. I don't know if this is ever
* necessary, but it seem to be in all of Torek's code.
*/
@@ -160,25 +226,25 @@ espattach(parent, self, aux)
return;
}
- sc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
- printf(" pri %d", sc->sc_pri);
+ esc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
+ printf(" pri %d", esc->sc_pri);
/*
* Map my registers in, if they aren't already in virtual
* address space.
*/
if (ca->ca_ra.ra_vaddr)
- sc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
+ esc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
else {
- sc->sc_reg = (volatile u_char *)
- mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len, ca->ca_bustype);
+ esc->sc_reg = (volatile u_char *)
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
}
/* Other settings */
- sc->sc_node = ca->ca_ra.ra_node;
+ esc->sc_node = ca->ca_ra.ra_node;
if (ca->ca_bustype == BUS_SBUS) {
- sc->sc_id = getpropint(sc->sc_node, "initiator-id", 7);
- sc->sc_freq = getpropint(sc->sc_node, "clock-frequency", -1);
+ sc->sc_id = getpropint(esc->sc_node, "initiator-id", 7);
+ sc->sc_freq = getpropint(esc->sc_node, "clock-frequency", -1);
} else {
sc->sc_id = 7;
sc->sc_freq = 24000000;
@@ -191,8 +257,8 @@ espattach(parent, self, aux)
sc->sc_freq /= 1000000;
if (dmachild) {
- sc->sc_dma = (struct dma_softc *)parent;
- sc->sc_dma->sc_esp = sc;
+ esc->sc_dma = (struct dma_softc *)parent;
+ esc->sc_dma->sc_esp = esc;
} else {
/*
* find the DMA by poking around the dma device structures
@@ -202,56 +268,68 @@ espattach(parent, self, aux)
* dma actually gets configured, it does the opposing test, and
* if the sc->sc_esp field in it's softc is NULL, then tries to
* find the matching esp driver.
- *
*/
- sc->sc_dma = (struct dma_softc *)
+ esc->sc_dma = (struct dma_softc *)
getdevunit("dma", sc->sc_dev.dv_unit);
/*
* and a back pointer to us, for DMA
*/
- if (sc->sc_dma)
- sc->sc_dma->sc_esp = sc;
- else
+ if (esc->sc_dma)
+ esc->sc_dma->sc_esp = esc;
+ else {
+ printf("\n");
panic("espattach: no dma found");
+ }
}
/*
+ * XXX More of this should be in ncr53c9x_attach(), but
+ * XXX should we really poke around the chip that much in
+ * XXX the MI code? Think about this more...
+ */
+
+ /*
* It is necessary to try to load the 2nd config register here,
- * to find out what rev the esp chip is, else the esp_reset
+ * to find out what rev the esp chip is, else the ncr53c9x_reset
* will not set up the defaults correctly.
*/
- sc->sc_cfg1 = sc->sc_id | ESPCFG1_PARENB;
- sc->sc_cfg2 = ESPCFG2_SCSI2 | ESPCFG2_RPE;
- sc->sc_cfg3 = ESPCFG3_CDB;
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
-
- if ((ESP_READ_REG(sc, ESP_CFG2) & ~ESPCFG2_RSVD) != (ESPCFG2_SCSI2 | ESPCFG2_RPE)) {
- printf(": ESP100");
- sc->sc_rev = ESP100;
+ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
+ sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
+ sc->sc_cfg3 = NCRCFG3_CDB;
+ NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
+
+ if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
+ (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
+ sc->sc_rev = NCR_VARIANT_ESP100;
} else {
- sc->sc_cfg2 = ESPCFG2_SCSI2;
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
+ sc->sc_cfg2 = NCRCFG2_SCSI2;
+ NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
sc->sc_cfg3 = 0;
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- sc->sc_cfg3 = (ESPCFG3_CDB | ESPCFG3_FCLK);
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- if (ESP_READ_REG(sc, ESP_CFG3) != (ESPCFG3_CDB | ESPCFG3_FCLK)) {
- printf(": ESP100A");
- sc->sc_rev = ESP100A;
+ NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
+ sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
+ NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
+ if (NCR_READ_REG(sc, NCR_CFG3) !=
+ (NCRCFG3_CDB | NCRCFG3_FCLK)) {
+ sc->sc_rev = NCR_VARIANT_ESP100A;
} else {
- /* ESPCFG2_FE enables > 64K transfers */
- sc->sc_cfg2 |= ESPCFG2_FE;
+ /* NCRCFG2_FE enables > 64K transfers */
+ sc->sc_cfg2 |= NCRCFG2_FE;
sc->sc_cfg3 = 0;
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- printf(": ESP200");
- sc->sc_rev = ESP200;
+ NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
+ sc->sc_rev = NCR_VARIANT_ESP200;
}
}
/*
+ * XXX minsync and maxxfer _should_ be set up in MI code,
+ * XXX but it appears to have some dependency on what sort
+ * XXX of DMA we're hooked up to, etc.
+ */
+
+ /*
* This is the value used to start sync negotiations
- * Note that the ESP register "SYNCTP" is programmed
+ * Note that the NCR register "SYNCTP" is programmed
* in "clocks per byte", and has a minimum value of 4.
* The SCSI period used in negotiation is one-fourth
* of the time (in nanoseconds) needed to transfer one byte.
@@ -262,78 +340,45 @@ espattach(parent, self, aux)
/*
* Alas, we must now modify the value a bit, because it's
- * only valid when can switch on FASTCLK and FASTSCSI bits
- * in config register 3...
+ * only valid when can switch on FASTCLK and FASTSCSI bits
+ * in config register 3...
*/
switch (sc->sc_rev) {
- case ESP100:
+ case NCR_VARIANT_ESP100:
sc->sc_maxxfer = 64 * 1024;
sc->sc_minsync = 0; /* No synch on old chip? */
break;
- case ESP100A:
+
+ case NCR_VARIANT_ESP100A:
sc->sc_maxxfer = 64 * 1024;
- sc->sc_minsync = esp_cpb2stp(sc, 5); /* Min clocks/byte is 5 */
+ /* Min clocks/byte is 5 */
+ sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
break;
- case ESP200:
+
+ case NCR_VARIANT_ESP200:
sc->sc_maxxfer = 16 * 1024 * 1024;
/* XXX - do actually set FAST* bits */
+ break;
}
- sc->sc_ccf = FREQTOCCF(sc->sc_freq);
-
- /* The value *must not* be == 1. Make it 2 */
- if (sc->sc_ccf == 1)
- sc->sc_ccf = 2;
-
- /*
- * The recommended timeout is 250ms. This register is loaded
- * with a value calculated as follows, from the docs:
- *
- * (timout period) x (CLK frequency)
- * reg = -------------------------------------
- * 8192 x (Clock Conversion Factor)
- *
- * Since CCF has a linear relation to CLK, this generally computes
- * to the constant of 153.
- */
- sc->sc_timeout = ((250 * 1000) * sc->sc_freq) / (8192 * sc->sc_ccf);
-
- /* CCF register only has 3 bits; 0 is actually 8 */
- sc->sc_ccf &= 7;
-
- /* Reset state & bus */
- sc->sc_state = 0;
- esp_init(sc, 1);
-
- printf(" %dMhz, target %d\n", sc->sc_freq, sc->sc_id);
-
/* add me to the sbus structures */
- sc->sc_sd.sd_reset = (void *) esp_reset;
+ esc->sc_sd.sd_reset = (void *) ncr53c9x_reset;
#if defined(SUN4C) || defined(SUN4M)
if (ca->ca_bustype == BUS_SBUS) {
if (dmachild)
- sbus_establish(&sc->sc_sd, sc->sc_dev.dv_parent);
+ sbus_establish(&esc->sc_sd, sc->sc_dev.dv_parent);
else
- sbus_establish(&sc->sc_sd, &sc->sc_dev);
+ sbus_establish(&esc->sc_sd, &sc->sc_dev);
}
#endif /* SUN4C || SUN4M */
/* and the interuppts */
- sc->sc_ih.ih_fun = (void *) espintr;
- sc->sc_ih.ih_arg = sc;
- intr_establish(sc->sc_pri, &sc->sc_ih);
+ esc->sc_ih.ih_fun = (void *) ncr53c9x_intr;
+ esc->sc_ih.ih_arg = sc;
+ intr_establish(esc->sc_pri, &esc->sc_ih);
evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
/*
- * fill in the prototype scsi_link.
- */
- sc->sc_link.adapter_softc = sc;
- sc->sc_link.adapter_target = sc->sc_id;
- sc->sc_link.adapter = &esp_switch;
- sc->sc_link.device = &esp_dev;
- sc->sc_link.openings = 2;
-
- /*
* If the boot path is "esp" at the moment and it's me, then
* walk our pointer to the sub-device, ready for the config
* below.
@@ -352,1622 +397,104 @@ espattach(parent, self, aux)
break;
}
- /*
- * Now try to attach all the sub-devices
- */
- config_found(self, &sc->sc_link, espprint);
-
- bootpath_store(1, NULL);
-}
-
-/*
- * This is the generic esp reset function. It does not reset the SCSI bus,
- * only this controllers, but kills any on-going commands, and also stops
- * and resets the DMA.
- *
- * After reset, registers are loaded with the defaults from the attach
- * routine above.
- */
-void
-esp_reset(sc)
- struct esp_softc *sc;
-{
-
- /* reset DMA first */
- DMA_RESET(sc->sc_dma);
+ /* Do the common parts of attachment. */
+ ncr53c9x_attach(sc, &esp_switch, &esp_dev);
- /* reset SCSI chip */
- ESPCMD(sc, ESPCMD_RSTCHIP);
- ESPCMD(sc, ESPCMD_NOP);
- DELAY(500);
+ /* Turn on target selection using the `dma' method */
+ ncr53c9x_dmaselect = 1;
- /* do these backwards, and fall through */
- switch (sc->sc_rev) {
- case ESP200:
- ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
- case ESP100A:
- ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
- case ESP100:
- ESP_WRITE_REG(sc, ESP_CFG1, sc->sc_cfg1);
- ESP_WRITE_REG(sc, ESP_CCF, sc->sc_ccf);
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_TIMEOUT, sc->sc_timeout);
- break;
- default:
- printf("%s: unknown revision code, assuming ESP100\n",
- sc->sc_dev.dv_xname);
- ESP_WRITE_REG(sc, ESP_CFG1, sc->sc_cfg1);
- ESP_WRITE_REG(sc, ESP_CCF, sc->sc_ccf);
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_TIMEOUT, sc->sc_timeout);
- }
+ bootpath_store(1, NULL);
}
/*
- * Reset the SCSI bus, but not the chip
+ * Glue functions.
*/
-void
-esp_scsi_reset(sc)
- struct esp_softc *sc;
-{
- /* stop DMA first, as the chip will return to Bus Free phase */
- DMACSR(sc->sc_dma) &= ~D_EN_DMA;
-
- printf("esp: resetting SCSI bus\n");
- ESPCMD(sc, ESPCMD_RSTSCSI);
-}
-/*
- * Initialize esp state machine
- */
-void
-esp_init(sc, doreset)
- struct esp_softc *sc;
- int doreset;
+u_char
+esp_read_reg(sc, reg)
+ struct ncr53c9x_softc *sc;
+ int reg;
{
- struct ecb *ecb;
- int r;
+ struct esp_softc *esc = (struct esp_softc *)sc;
- ESP_TRACE(("[ESP_INIT(%d)] ", doreset));
-
- if (sc->sc_state == 0) { /* First time through */
- TAILQ_INIT(&sc->ready_list);
- TAILQ_INIT(&sc->nexus_list);
- TAILQ_INIT(&sc->free_list);
- sc->sc_nexus = NULL;
- ecb = sc->sc_ecb;
- bzero(ecb, sizeof(sc->sc_ecb));
- for (r = 0; r < sizeof(sc->sc_ecb) / sizeof(*ecb); r++) {
- TAILQ_INSERT_TAIL(&sc->free_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QFREE);
- ecb++;
- }
- bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
- } else {
- sc->sc_flags |= ESP_ABORTING;
- sc->sc_state = ESP_IDLE;
- ecb = sc->sc_nexus;
- if (ecb != NULL) {
- ecb->xs->error = XS_TIMEOUT;
- esp_done(ecb);
- sc->sc_nexus = NULL;
- }
- while ((ecb = sc->nexus_list.tqh_first) != NULL) {
- ecb->xs->error = XS_TIMEOUT;
- esp_done(ecb);
- }
- }
-
- /*
- * reset the chip to a known state
- */
- esp_reset(sc);
-
- sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
- for (r = 0; r < 8; r++) {
- struct esp_tinfo *tp = &sc->sc_tinfo[r];
-/* XXX - config flags per target: low bits: no reselect; high bits: no synch */
- int fl = sc->sc_dev.dv_cfdata->cf_flags;
-
- tp->flags = ((sc->sc_minsync && !(fl & (1<<(r+8))))
- ? T_NEGOTIATE : 0) |
- ((fl & (1<<r)) ? T_RSELECTOFF : 0) |
- T_NEED_TO_RESET;
- tp->period = sc->sc_minsync;
- tp->offset = 0;
- }
- sc->sc_flags &= ~ESP_ABORTING;
-
- if (doreset) {
- sc->sc_state = ESP_SBR;
- ESPCMD(sc, ESPCMD_RSTSCSI);
- return;
- }
-
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- return;
+ return (esc->sc_reg[reg * 4]);
}
-/*
- * Read the ESP registers, and save their contents for later use.
- * ESP_STAT, ESP_STEP & ESP_INTR are mostly zeroed out when reading
- * ESP_INTR - so make sure it is the last read.
- *
- * I think that (from reading the docs) most bits in these registers
- * only make sense when he DMA CSR has an interrupt showing. Call only
- * if an interrupt is pending.
- */
void
-espreadregs(sc)
- struct esp_softc *sc;
+esp_write_reg(sc, reg, val)
+ struct ncr53c9x_softc *sc;
+ int reg;
+ u_char val;
{
+ struct esp_softc *esc = (struct esp_softc *)sc;
+ u_char v = val;
- sc->sc_espstat = ESP_READ_REG(sc, ESP_STAT);
- /* Only the stepo bits are of interest */
- sc->sc_espstep = ESP_READ_REG(sc, ESP_STEP) & ESPSTEP_MASK;
- sc->sc_espintr = ESP_READ_REG(sc, ESP_INTR);
-
- /*
- * Determine the SCSI bus phase, return either a real SCSI bus phase
- * or some pseudo phase we use to detect certain exceptions.
- */
-
- sc->sc_phase = (sc->sc_espintr & ESPINTR_DIS)
- ? /* Disconnected */ BUSFREE_PHASE
- : sc->sc_espstat & ESPSTAT_PHASE;
-
- ESP_MISC(("regs[intr=%02x,stat=%02x,step=%02x] ",
- sc->sc_espintr, sc->sc_espstat, sc->sc_espstep));
+ esc->sc_reg[reg * 4] = v;
}
-/*
- * Convert Synchronous Transfer Period to chip register Clock Per Byte value.
- */
int
-esp_stp2cpb(sc, period)
- struct esp_softc *sc;
- int period;
+esp_dma_isintr(sc)
+ struct ncr53c9x_softc *sc;
{
- int v;
- v = (sc->sc_freq * period) / 250;
- if (esp_cpb2stp(sc, v) < period)
- /* Correct round-down error */
- v++;
- return v;
-}
+ struct esp_softc *esc = (struct esp_softc *)sc;
-/*
- * Convert chip register Clock Per Byte value to Synchronous Transfer Period.
- */
-int
-esp_cpb2stp(sc, cpb)
- struct esp_softc *sc;
- int cpb;
-{
- return ((250 * cpb) / sc->sc_freq);
+ return (DMA_ISINTR(esc->sc_dma));
}
-/*
- * Send a command to a target, set the driver state to ESP_SELECTING
- * and let the caller take care of the rest.
- *
- * Keeping this as a function allows me to say that this may be done
- * by DMA instead of programmed I/O soon.
- */
void
-espselect(sc, target, lun, cmd, clen)
- struct esp_softc *sc;
- u_char target, lun;
- u_char *cmd;
- u_char clen;
+esp_dma_reset(sc)
+ struct ncr53c9x_softc *sc;
{
- struct esp_tinfo *ti = &sc->sc_tinfo[target];
- int i;
-
- ESP_TRACE(("[espselect(t%d,l%d,cmd:%x)] ", target, lun, *(u_char *)cmd));
-
- /* new state ESP_SELECTING */
- sc->sc_state = ESP_SELECTING;
-
- ESPCMD(sc, ESPCMD_FLUSH);
-
- /*
- * The docs say the target register is never reset, and I
- * can't think of a better place to set it
- */
- ESP_WRITE_REG(sc, ESP_SELID, target);
- if (ti->flags & T_SYNCMODE) {
- ESP_WRITE_REG(sc, ESP_SYNCOFF, ti->offset);
- ESP_WRITE_REG(sc, ESP_SYNCTP, esp_stp2cpb(sc, ti->period));
- } else {
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_SYNCTP, 0);
- }
-
- /*
- * Who am I. This is where we tell the target that we are
- * happy for it to disconnect etc.
- */
- ESP_WRITE_REG(sc, ESP_FIFO,
- MSG_IDENTIFY(lun, (ti->flags & T_RSELECTOFF)?0:1));
-
- if (ti->flags & T_NEGOTIATE) {
- /* Arbitrate, select and stop after IDENTIFY message */
- ESPCMD(sc, ESPCMD_SELATNS);
- return;
- }
-
- /* Now the command into the FIFO */
- for (i = 0; i < clen; i++)
- ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
-
- /* And get the targets attention */
- ESPCMD(sc, ESPCMD_SELATN);
+ struct esp_softc *esc = (struct esp_softc *)sc;
+ DMA_RESET(esc->sc_dma);
}
-/*
- * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
- */
-
-/*
- * Start a SCSI-command
- * This function is called by the higher level SCSI-driver to queue/run
- * SCSI-commands.
- */
int
-esp_scsi_cmd(xs)
- struct scsi_xfer *xs;
+esp_dma_intr(sc)
+ struct ncr53c9x_softc *sc;
{
- struct scsi_link *sc_link = xs->sc_link;
- struct esp_softc *sc = sc_link->adapter_softc;
- struct ecb *ecb;
- int s, flags;
-
- ESP_TRACE(("[esp_scsi_cmd] "));
- ESP_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
- sc_link->target));
-
- flags = xs->flags;
-
- /* Get a esp command block */
- s = splbio();
- ecb = sc->free_list.tqh_first;
- if (ecb) {
- TAILQ_REMOVE(&sc->free_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QNONE);
- }
- splx(s);
-
- if (ecb == NULL) {
- ESP_MISC(("TRY_AGAIN_LATER"));
- return TRY_AGAIN_LATER;
- }
-
- /* Initialize ecb */
- ecb->xs = xs;
- bcopy(xs->cmd, &ecb->cmd, xs->cmdlen);
- ecb->clen = xs->cmdlen;
- ecb->daddr = xs->data;
- ecb->dleft = xs->datalen;
- ecb->stat = 0;
-
- s = splbio();
- TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QREADY);
- timeout(esp_timeout, ecb, (xs->timeout*hz)/1000);
-
- if (sc->sc_state == ESP_IDLE)
- esp_sched(sc);
-
- splx(s);
-
- if (flags & SCSI_POLL) {
- /* Not allowed to use interrupts, use polling instead */
- return esp_poll(sc, ecb);
- }
-
- ESP_MISC(("SUCCESSFULLY_QUEUED"));
- return SUCCESSFULLY_QUEUED;
+ struct esp_softc *esc = (struct esp_softc *)sc;
+ return (DMA_INTR(esc->sc_dma));
}
-/*
- * Used when interrupt driven I/O isn't allowed, e.g. during boot.
- */
int
-esp_poll(sc, ecb)
- struct esp_softc *sc;
- struct ecb *ecb;
+esp_dma_setup(sc, addr, len, datain, dmasize)
+ struct ncr53c9x_softc *sc;
+ caddr_t *addr;
+ size_t *len;
+ int datain;
+ size_t *dmasize;
{
- struct scsi_xfer *xs = ecb->xs;
- int count = xs->timeout * 100;
+ struct esp_softc *esc = (struct esp_softc *)sc;
- ESP_TRACE(("[esp_poll] "));
- while (count) {
- if (DMA_ISINTR(sc->sc_dma)) {
- espintr(sc);
- }
-#if alternatively
- if (ESP_READ_REG(sc, ESP_STAT) & ESPSTAT_INT)
- espintr(sc);
-#endif
- if (xs->flags & ITSDONE)
- break;
- DELAY(10);
- if (sc->sc_state == ESP_IDLE) {
- ESP_TRACE(("[esp_poll: rescheduling] "));
- esp_sched(sc);
- }
- count--;
- }
-
- if (count == 0) {
- ESP_MISC(("esp_poll: timeout"));
- esp_timeout((caddr_t)ecb);
- }
-
- return COMPLETE;
+ return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
}
-
-/*
- * LOW LEVEL SCSI UTILITIES
- */
-
-/*
- * Schedule a scsi operation. This has now been pulled out of the interrupt
- * handler so that we may call it from esp_scsi_cmd and esp_done. This may
- * save us an unecessary interrupt just to get things going. Should only be
- * called when state == ESP_IDLE and at bio pl.
- */
void
-esp_sched(sc)
- struct esp_softc *sc;
+esp_dma_go(sc)
+ struct ncr53c9x_softc *sc;
{
- struct scsi_link *sc_link;
- struct ecb *ecb;
- int t;
-
- ESP_TRACE(("[esp_sched] "));
- if (sc->sc_state != ESP_IDLE)
- panic("esp_sched: not IDLE (state=%d)", sc->sc_state);
-
- if (sc->sc_flags & ESP_ABORTING)
- return;
-
- /*
- * Find first ecb in ready queue that is for a target/lunit
- * combinations that is not busy.
- */
- for (ecb = sc->ready_list.tqh_first; ecb; ecb = ecb->chain.tqe_next) {
- sc_link = ecb->xs->sc_link;
- t = sc_link->target;
- if (!(sc->sc_tinfo[t].lubusy & (1 << sc_link->lun))) {
- struct esp_tinfo *ti = &sc->sc_tinfo[t];
+ struct esp_softc *esc = (struct esp_softc *)sc;
- if ((ecb->flags & ECB_QBITS) != ECB_QREADY)
- panic("esp: busy entry on ready list");
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QNONE);
- sc->sc_nexus = ecb;
- sc->sc_flags = 0;
- sc->sc_prevphase = INVALID_PHASE;
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- ti->lubusy |= (1<<sc_link->lun);
-/*XXX*/if (sc->sc_msgpriq) {
- printf("esp: message queue not empty: %x!\n", sc->sc_msgpriq);
-}
-/*XXX*/sc->sc_msgpriq = sc->sc_msgout = 0;
- espselect(sc, t, sc_link->lun,
- (u_char *)&ecb->cmd, ecb->clen);
- break;
- } else
- ESP_MISC(("%d:%d busy\n", t, sc_link->lun));
- }
+ DMA_GO(esc->sc_dma);
}
-/*
- * POST PROCESSING OF SCSI_CMD (usually current)
- */
-void
-esp_done(ecb)
- struct ecb *ecb;
-{
- struct scsi_xfer *xs = ecb->xs;
- struct scsi_link *sc_link = xs->sc_link;
- struct esp_softc *sc = sc_link->adapter_softc;
- struct esp_tinfo *ti = &sc->sc_tinfo[sc_link->target];
-
- ESP_TRACE(("[esp_done(error:%x)] ", xs->error));
-
- untimeout(esp_timeout, ecb);
-
- /*
- * Now, if we've come here with no error code, i.e. we've kept the
- * initial XS_NOERROR, and the status code signals that we should
- * check sense, we'll need to set up a request sense cmd block and
- * push the command back into the ready queue *before* any other
- * commands for this target/lunit, else we lose the sense info.
- * We don't support chk sense conditions for the request sense cmd.
- */
- if (xs->error == XS_NOERROR) {
- if ((ecb->flags & ECB_ABORTED) != 0) {
- xs->error = XS_TIMEOUT;
- } else if ((ecb->flags & ECB_CHKSENSE) != 0) {
- xs->error = XS_SENSE;
- } else if ((ecb->stat & ST_MASK) == SCSI_CHECK) {
- struct scsi_sense *ss = (void *)&ecb->cmd;
- ESP_MISC(("requesting sense "));
- /* First, save the return values */
- xs->resid = ecb->dleft;
- xs->status = ecb->stat;
- /* Next, setup a request sense command block */
- bzero(ss, sizeof(*ss));
- ss->opcode = REQUEST_SENSE;
- /*ss->byte2 = sc_link->lun << 5;*/
- ss->length = sizeof(struct scsi_sense_data);
- ecb->clen = sizeof(*ss);
- ecb->daddr = (char *)&xs->sense;
- ecb->dleft = sizeof(struct scsi_sense_data);
- ecb->flags |= ECB_CHKSENSE;
-/*XXX - must take off queue here */
- if (ecb != sc->sc_nexus) {
- panic("%s: esp_sched: floating ecb %p",
- sc->sc_dev.dv_xname, ecb);
- }
- TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QREADY);
- ti->lubusy &= ~(1<<sc_link->lun);
- ti->senses++;
- timeout(esp_timeout, ecb, (xs->timeout*hz)/1000);
- if (sc->sc_nexus == ecb) {
- sc->sc_nexus = NULL;
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- }
- return;
- } else {
- xs->resid = ecb->dleft;
- }
- }
-
- xs->flags |= ITSDONE;
-
-#ifdef ESP_DEBUG
- if (esp_debug & ESP_SHOWMISC) {
- printf("err=0x%02x ",xs->error);
- if (xs->error == XS_SENSE) {
- printf("sense=%2x; ", xs->sense.error_code);
- }
- }
- if ((xs->resid || xs->error > XS_SENSE) && esp_debug & ESP_SHOWMISC) {
- if (xs->resid)
- printf("esp_done: resid=%d\n", xs->resid);
- if (xs->error)
- printf("esp_done: error=%d\n", xs->error);
- }
-#endif
-
- /*
- * Remove the ECB from whatever queue it's on.
- */
- switch (ecb->flags & ECB_QBITS) {
- case ECB_QNONE:
- if (ecb != sc->sc_nexus) {
- panic("%s: floating ecb", sc->sc_dev.dv_xname);
- }
- sc->sc_nexus = NULL;
- sc->sc_state = ESP_IDLE;
- ti->lubusy &= ~(1<<sc_link->lun);
- esp_sched(sc);
- break;
- case ECB_QREADY:
- TAILQ_REMOVE(&sc->ready_list, ecb, chain);
- break;
- case ECB_QNEXUS:
- TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
- ti->lubusy &= ~(1<<sc_link->lun);
- break;
- case ECB_QFREE:
- panic("%s: dequeue: busy ecb on free list",
- sc->sc_dev.dv_xname);
- break;
- default:
- panic("%s: dequeue: unknown queue %d",
- sc->sc_dev.dv_xname, ecb->flags & ECB_QBITS);
- }
-
- /* Put it on the free list, and clear flags. */
- TAILQ_INSERT_HEAD(&sc->free_list, ecb, chain);
- ecb->flags = ECB_QFREE;
-
- ti->cmds++;
- scsi_done(xs);
- return;
-}
-
-/*
- * INTERRUPT/PROTOCOL ENGINE
- */
-
-/*
- * Schedule an outgoing message by prioritizing it, and asserting
- * attention on the bus. We can only do this when we are the initiator
- * else there will be an illegal command interrupt.
- */
-#define esp_sched_msgout(m) \
- do { \
- ESP_MISC(("esp_sched_msgout %d ", m)); \
- ESPCMD(sc, ESPCMD_SETATN); \
- sc->sc_msgpriq |= (m); \
- } while (0)
-
-#define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80)
-#define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
-#define ISEXTMSG(m) ((m) == 1)
-
-/*
- * Get an incoming message as initiator.
- *
- * The SCSI bus must already be in MESSAGE_IN_PHASE and there is a
- * byte in the FIFO
- */
void
-esp_msgin(sc)
- register struct esp_softc *sc;
+esp_dma_stop(sc)
+ struct ncr53c9x_softc *sc;
{
- register int v;
-
- ESP_TRACE(("[esp_msgin(curmsglen:%d)] ", sc->sc_imlen));
-
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) == 0) {
- printf("%s: msgin: no msg byte available\n",
- sc->sc_dev.dv_xname);
- return;
- }
-
- /*
- * Prepare for a new message. A message should (according
- * to the SCSI standard) be transmitted in one single
- * MESSAGE_IN_PHASE. If we have been in some other phase,
- * then this is a new message.
- */
- if (sc->sc_prevphase != MESSAGE_IN_PHASE) {
- sc->sc_flags &= ~ESP_DROP_MSGI;
- sc->sc_imlen = 0;
- }
-
- v = ESP_READ_REG(sc, ESP_FIFO);
- ESP_MISC(("<msgbyte:0x%02x>", v));
-
-#if 0
- if (sc->sc_state == ESP_RESELECTED && sc->sc_imlen == 0) {
- /*
- * Which target is reselecting us? (The ID bit really)
- */
- sc->sc_selid = v;
- sc->sc_selid &= ~(1<<sc->sc_id);
- ESP_MISC(("selid=0x%2x ", sc->sc_selid));
- return;
- }
-#endif
-
- sc->sc_imess[sc->sc_imlen] = v;
-
- /*
- * If we're going to reject the message, don't bother storing
- * the incoming bytes. But still, we need to ACK them.
- */
+ struct esp_softc *esc = (struct esp_softc *)sc;
- if ((sc->sc_flags & ESP_DROP_MSGI)) {
- ESPCMD(sc, ESPCMD_SETATN);
- ESPCMD(sc, ESPCMD_MSGOK);
- printf("<dropping msg byte %x>",
- sc->sc_imess[sc->sc_imlen]);
- return;
- }
-
- if (sc->sc_imlen >= ESP_MAX_MSG_LEN) {
- esp_sched_msgout(SEND_REJECT);
- sc->sc_flags |= ESP_DROP_MSGI;
- } else {
- sc->sc_imlen++;
- /*
- * This testing is suboptimal, but most
- * messages will be of the one byte variety, so
- * it should not effect performance
- * significantly.
- */
- if (sc->sc_imlen == 1 && IS1BYTEMSG(sc->sc_imess[0]))
- goto gotit;
- if (sc->sc_imlen == 2 && IS2BYTEMSG(sc->sc_imess[0]))
- goto gotit;
- if (sc->sc_imlen >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
- sc->sc_imlen == sc->sc_imess[1] + 2)
- goto gotit;
- }
- /* Ack what we have so far */
- ESPCMD(sc, ESPCMD_MSGOK);
- return;
-
-gotit:
- ESP_MSGS(("gotmsg(%x)", sc->sc_imess[0]));
- /*
- * Now we should have a complete message (1 byte, 2 byte
- * and moderately long extended messages). We only handle
- * extended messages which total length is shorter than
- * ESP_MAX_MSG_LEN. Longer messages will be amputated.
- */
- if (sc->sc_state == ESP_HASNEXUS) {
- struct ecb *ecb = sc->sc_nexus;
- struct esp_tinfo *ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
-
- switch (sc->sc_imess[0]) {
- case MSG_CMDCOMPLETE:
- ESP_MSGS(("cmdcomplete "));
- if (sc->sc_dleft < 0) {
- struct scsi_link *sc_link = ecb->xs->sc_link;
- printf("esp: %d extra bytes from %d:%d\n",
- -sc->sc_dleft,
- sc_link->target, sc_link->lun);
- sc->sc_dleft = 0;
- }
- ecb->xs->resid = ecb->dleft = sc->sc_dleft;
- sc->sc_flags |= ESP_BUSFREE_OK;
- break;
-
- case MSG_MESSAGE_REJECT:
- if (esp_debug & ESP_SHOWMSGS)
- printf("%s: our msg rejected by target\n",
- sc->sc_dev.dv_xname);
-#if 1 /* XXX - must remember last message */
-sc_print_addr(ecb->xs->sc_link); printf("MSG_MESSAGE_REJECT>>");
-#endif
- if (sc->sc_flags & ESP_SYNCHNEGO) {
- ti->period = ti->offset = 0;
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- ti->flags &= ~T_NEGOTIATE;
- }
- /* Not all targets understand INITIATOR_DETECTED_ERR */
- if (sc->sc_msgout == SEND_INIT_DET_ERR)
- esp_sched_msgout(SEND_ABORT);
- break;
- case MSG_NOOP:
- ESP_MSGS(("noop "));
- break;
- case MSG_DISCONNECT:
- ESP_MSGS(("disconnect "));
- ti->dconns++;
- sc->sc_flags |= ESP_DISCON;
- sc->sc_flags |= ESP_BUSFREE_OK;
- if ((ecb->xs->sc_link->quirks & SDEV_AUTOSAVE) == 0)
- break;
- /*FALLTHROUGH*/
- case MSG_SAVEDATAPOINTER:
- ESP_MSGS(("save datapointer "));
- ecb->dleft = sc->sc_dleft;
- ecb->daddr = sc->sc_dp;
- break;
- case MSG_RESTOREPOINTERS:
- ESP_MSGS(("restore datapointer "));
- if (!ecb) {
- esp_sched_msgout(SEND_ABORT);
- printf("%s: no DATAPOINTERs to restore\n",
- sc->sc_dev.dv_xname);
- break;
- }
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- break;
- case MSG_PARITY_ERROR:
- printf("%s:target%d: MSG_PARITY_ERROR\n",
- sc->sc_dev.dv_xname,
- ecb->xs->sc_link->target);
- break;
- case MSG_EXTENDED:
- ESP_MSGS(("extended(%x) ", sc->sc_imess[2]));
- switch (sc->sc_imess[2]) {
- case MSG_EXT_SDTR:
- ESP_MSGS(("SDTR period %d, offset %d ",
- sc->sc_imess[3], sc->sc_imess[4]));
- ti->period = sc->sc_imess[3];
- ti->offset = sc->sc_imess[4];
- if (sc->sc_minsync == 0) {
- /* We won't do synch */
- ti->offset = 0;
- esp_sched_msgout(SEND_SDTR);
- } else if (ti->offset == 0) {
- printf("%s:%d: async\n", "esp",
- ecb->xs->sc_link->target);
- ti->offset = 0;
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- } else if (ti->period > 124) {
- printf("%s:%d: async\n", "esp",
- ecb->xs->sc_link->target);
- ti->offset = 0;
- esp_sched_msgout(SEND_SDTR);
- } else {
- int r = 250/ti->period;
- int s = (100*250)/ti->period - 100*r;
- int p;
- p = esp_stp2cpb(sc, ti->period);
- ti->period = esp_cpb2stp(sc, p);
-#ifdef ESP_DEBUG
- sc_print_addr(ecb->xs->sc_link);
-#endif
- if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
- /* Target initiated negotiation */
- if (ti->flags & T_SYNCMODE) {
- ti->flags &= ~T_SYNCMODE;
-#ifdef ESP_DEBUG
- printf("renegotiated ");
-#endif
- }
- ESP_WRITE_REG(sc, ESP_SYNCOFF,
- 0);
- ESP_WRITE_REG(sc, ESP_SYNCTP,
- 0);
- /* Clamp to our maxima */
- if (ti->period < sc->sc_minsync)
- ti->period = sc->sc_minsync;
- if (ti->offset > 15)
- ti->offset = 15;
- esp_sched_msgout(SEND_SDTR);
- } else {
- /* we are sync */
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- ESP_WRITE_REG(sc, ESP_SYNCOFF,
- ti->offset);
- ESP_WRITE_REG(sc, ESP_SYNCTP,
- p);
- ti->flags |= T_SYNCMODE;
- }
-#ifdef ESP_DEBUG
- printf("max sync rate %d.%02dMb/s\n",
- r, s);
-#endif
- }
- ti->flags &= ~T_NEGOTIATE;
- break;
- default: /* Extended messages we don't handle */
- ESPCMD(sc, ESPCMD_SETATN);
- break;
- }
- break;
- default:
- ESP_MSGS(("ident "));
- /* thanks for that ident... */
- if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
- ESP_MISC(("unknown "));
-printf("%s: unimplemented message: %d\n", sc->sc_dev.dv_xname, sc->sc_imess[0]);
- ESPCMD(sc, ESPCMD_SETATN);
- }
- break;
- }
- } else if (sc->sc_state == ESP_RESELECTED) {
- struct scsi_link *sc_link = NULL;
- struct ecb *ecb;
- struct esp_tinfo *ti;
- u_char lunit;
-
- if (MSG_ISIDENTIFY(sc->sc_imess[0])) { /* Identify? */
- ESP_MISC(("searching "));
- /*
- * Search wait queue for disconnected cmd
- * The list should be short, so I haven't bothered with
- * any more sophisticated structures than a simple
- * singly linked list.
- */
- lunit = sc->sc_imess[0] & 0x07;
- for (ecb = sc->nexus_list.tqh_first; ecb;
- ecb = ecb->chain.tqe_next) {
- sc_link = ecb->xs->sc_link;
- if (sc_link->lun == lunit &&
- sc->sc_selid == (1<<sc_link->target)) {
- TAILQ_REMOVE(&sc->nexus_list, ecb,
- chain);
- ECB_SETQ(ecb, ECB_QNONE);
- break;
- }
- }
-
- if (!ecb) { /* Invalid reselection! */
- esp_sched_msgout(SEND_ABORT);
- printf("esp: invalid reselect (idbit=0x%2x)\n",
- sc->sc_selid);
- } else { /* Reestablish nexus */
- /*
- * Setup driver data structures and
- * do an implicit RESTORE POINTERS
- */
- ti = &sc->sc_tinfo[sc_link->target];
- sc->sc_nexus = ecb;
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- sc->sc_tinfo[sc_link->target].lubusy
- |= (1<<sc_link->lun);
- if (ti->flags & T_SYNCMODE) {
- ESP_WRITE_REG(sc, ESP_SYNCOFF,
- ti->offset);
- ESP_WRITE_REG(sc, ESP_SYNCTP,
- esp_stp2cpb(sc, ti->period));
- } else {
- ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
- ESP_WRITE_REG(sc, ESP_SYNCTP, 0);
- }
- ESP_MISC(("... found ecb"));
- sc->sc_state = ESP_HASNEXUS;
- }
- } else {
- printf("%s: bogus reselect (no IDENTIFY) %0x2x\n",
- sc->sc_dev.dv_xname, sc->sc_selid);
- esp_sched_msgout(SEND_DEV_RESET);
- }
- } else { /* Neither ESP_HASNEXUS nor ESP_RESELECTED! */
- printf("%s: unexpected message in; will send DEV_RESET\n",
- sc->sc_dev.dv_xname);
- esp_sched_msgout(SEND_DEV_RESET);
- }
-
- /* Ack last message byte */
- ESPCMD(sc, ESPCMD_MSGOK);
-
- /* Done, reset message pointer. */
- sc->sc_flags &= ~ESP_DROP_MSGI;
- sc->sc_imlen = 0;
+ DMACSR(esc->sc_dma) &= ~D_EN_DMA;
}
-
-/*
- * Send the highest priority, scheduled message
- */
-void
-esp_msgout(sc)
- register struct esp_softc *sc;
-{
- struct esp_tinfo *ti;
- struct ecb *ecb;
- size_t size;
-
- ESP_TRACE(("[esp_msgout(priq:%x, prevphase:%x)]", sc->sc_msgpriq, sc->sc_prevphase));
-
- if (sc->sc_prevphase != MESSAGE_OUT_PHASE) {
- /* Pick up highest priority message */
- sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
- sc->sc_omlen = 1; /* "Default" message len */
- switch (sc->sc_msgout) {
- case SEND_SDTR:
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
- sc->sc_omess[0] = MSG_EXTENDED;
- sc->sc_omess[1] = 3;
- sc->sc_omess[2] = MSG_EXT_SDTR;
- sc->sc_omess[3] = ti->period;
- sc->sc_omess[4] = ti->offset;
- sc->sc_omlen = 5;
- break;
- case SEND_IDENTIFY:
- if (sc->sc_state != ESP_HASNEXUS) {
- printf("esp at line %d: no nexus", __LINE__);
- }
- ecb = sc->sc_nexus;
- sc->sc_omess[0] = MSG_IDENTIFY(ecb->xs->sc_link->lun,0);
- break;
- case SEND_DEV_RESET:
- sc->sc_omess[0] = MSG_BUS_DEV_RESET;
- sc->sc_flags |= ESP_BUSFREE_OK;
- ecb = sc->sc_nexus;
- ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
- ti->flags &= ~T_SYNCMODE;
- ti->flags |= T_NEGOTIATE;
- break;
- case SEND_PARITY_ERROR:
- sc->sc_omess[0] = MSG_PARITY_ERROR;
- break;
- case SEND_ABORT:
- sc->sc_omess[0] = MSG_ABORT;
- sc->sc_flags |= ESP_BUSFREE_OK;
- break;
- case SEND_INIT_DET_ERR:
- sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
- break;
- case SEND_REJECT:
- sc->sc_omess[0] = MSG_MESSAGE_REJECT;
- break;
- default:
- sc->sc_omess[0] = MSG_NOOP;
- break;
- }
- sc->sc_omp = sc->sc_omess;
- }
-
-#if 1
- /* (re)send the message */
- size = min(sc->sc_omlen, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_omp, &sc->sc_omlen, 0, &size);
- /* Program the SCSI counter */
- ESP_WRITE_REG(sc, ESP_TCL, size);
- ESP_WRITE_REG(sc, ESP_TCM, size >> 8);
- if (sc->sc_cfg2 & ESPCFG2_FE) {
- ESP_WRITE_REG(sc, ESP_TCH, size >> 16);
- }
- /* load the count in */
- ESPCMD(sc, ESPCMD_NOP|ESPCMD_DMA);
- ESPCMD(sc, (size==0?ESPCMD_TRPAD:ESPCMD_TRANS)|ESPCMD_DMA);
- DMA_GO(sc->sc_dma);
-#else
- { int i;
- ESPCMD(sc, ESPCMD_FLUSH);
- for (i = 0; i < sc->sc_omlen; i++)
- ESP_WRITE_REG(sc, FIFO, sc->sc_omess[i]);
- ESPCMD(sc, ESPCMD_TRANS);
-#if test_stuck_on_msgout
-printf("<<XXXmsgoutdoneXXX>>");
-#endif
- }
-#endif
-}
-
-/*
- * This is the most critical part of the driver, and has to know
- * how to deal with *all* error conditions and phases from the SCSI
- * bus. If there are no errors and the DMA was active, then call the
- * DMA pseudo-interrupt handler. If this returns 1, then that was it
- * and we can return from here without further processing.
- *
- * Most of this needs verifying.
- */
int
-espintr(sc)
- register struct esp_softc *sc;
+esp_dma_isactive(sc)
+ struct ncr53c9x_softc *sc;
{
- register struct ecb *ecb;
- register struct scsi_link *sc_link;
- struct esp_tinfo *ti;
- int loop;
- size_t size;
-
- ESP_TRACE(("[espintr]"));
-
- /*
- * I have made some (maybe seriously flawed) assumptions here,
- * but basic testing (uncomment the printf() below), show that
- * certainly something happens when this loop is here.
- *
- * The idea is that many of the SCSI operations take very little
- * time, and going away and getting interrupted is too high an
- * overhead to pay. For example, selecting, sending a message
- * and command and then doing some work can be done in one "pass".
- *
- * The DELAY is not variable because I do not understand that the
- * DELAY loop should be fixed-time regardless of CPU speed, but
- * I am *assuming* that the faster SCSI processors get things done
- * quicker (sending a command byte etc), and so there is no
- * need to be too slow.
- *
- * This is a heuristic. It is 2 when at 20Mhz, 2 at 25Mhz and 1
- * at 40Mhz. This needs testing.
- */
- for (loop = 0; 1;loop++, DELAY(50/sc->sc_freq)) {
- /* a feeling of deja-vu */
- if (!DMA_ISINTR(sc->sc_dma))
- return (loop != 0);
-#if 0
- if (loop)
- printf("*");
-#endif
-
- /* and what do the registers say... */
- espreadregs(sc);
-
- sc->sc_intrcnt.ev_count++;
-
- /*
- * At the moment, only a SCSI Bus Reset or Illegal
- * Command are classed as errors. A disconnect is a
- * valid condition, and we let the code check is the
- * "ESP_BUSFREE_OK" flag was set before declaring it
- * and error.
- *
- * Also, the status register tells us about "Gross
- * Errors" and "Parity errors". Only the Gross Error
- * is really bad, and the parity errors are dealt
- * with later
- *
- * TODO
- * If there are too many parity error, go to slow
- * cable mode ?
- */
-
- /* SCSI Reset */
- if (sc->sc_espintr & ESPINTR_SBR) {
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- if (sc->sc_state != ESP_SBR) {
- printf("%s: SCSI bus reset\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 0); /* Restart everything */
- return 1;
- }
-#if 0
- /*XXX*/ printf("<expected bus reset: "
- "[intr %x, stat %x, step %d]>\n",
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
-#endif
- if (sc->sc_nexus)
- panic("%s: nexus in reset state",
- sc->sc_dev.dv_xname);
- sc->sc_state = ESP_IDLE;
- esp_sched(sc);
- return 1;
- }
-
- ecb = sc->sc_nexus;
-
-#define ESPINTR_ERR (ESPINTR_SBR|ESPINTR_ILL)
- if (sc->sc_espintr & ESPINTR_ERR ||
- sc->sc_espstat & ESPSTAT_GE) {
-
- if (sc->sc_espstat & ESPSTAT_GE) {
- /* no target ? */
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- if (sc->sc_state == ESP_HASNEXUS ||
- sc->sc_state == ESP_SELECTING) {
- ecb->xs->error = XS_DRIVER_STUFFUP;
- esp_done(ecb);
- }
- return 1;
- }
-
- if (sc->sc_espintr & ESPINTR_ILL) {
- /* illegal command, out of sync ? */
- printf("%s: illegal command: 0x%x (state %d, phase %x, prevphase %x)\n",
- sc->sc_dev.dv_xname, sc->sc_lastcmd,
- sc->sc_state, sc->sc_phase,
- sc->sc_prevphase);
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- esp_init(sc, 0); /* Restart everything */
- return 1;
- }
- }
-
- /*
- * Call if DMA is active.
- *
- * If DMA_INTR returns true, then maybe go 'round the loop
- * again in case there is no more DMA queued, but a phase
- * change is expected.
- */
- if (DMA_ISACTIVE(sc->sc_dma)) {
- DMA_INTR(sc->sc_dma);
- /* If DMA active here, then go back to work... */
- if (DMA_ISACTIVE(sc->sc_dma))
- return 1;
-
- if (sc->sc_dleft == 0 &&
- (sc->sc_espstat & ESPSTAT_TC) == 0)
- printf("%s: !TC [intr %x, stat %x, step %d]"
- " prevphase %x, resid %x\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr,
- sc->sc_espstat,
- sc->sc_espstep,
- sc->sc_prevphase,
- ecb?ecb->dleft:-1);
- }
-
-#if 0 /* Unreliable on some ESP revisions? */
- if ((sc->sc_espstat & ESPSTAT_INT) == 0) {
- printf("%s: spurious interrupt\n", sc->sc_dev.dv_xname);
- return 1;
- }
-#endif
-
- /*
- * check for less serious errors
- */
- if (sc->sc_espstat & ESPSTAT_PE) {
- printf("%s: SCSI bus parity error\n",
- sc->sc_dev.dv_xname);
- if (sc->sc_prevphase == MESSAGE_IN_PHASE)
- esp_sched_msgout(SEND_PARITY_ERROR);
- else
- esp_sched_msgout(SEND_INIT_DET_ERR);
- }
+ struct esp_softc *esc = (struct esp_softc *)sc;
- if (sc->sc_espintr & ESPINTR_DIS) {
- ESP_MISC(("<DISC [intr %x, stat %x, step %d]>",
- sc->sc_espintr,sc->sc_espstat,sc->sc_espstep));
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- /*
- * This command must (apparently) be issued within
- * 250mS of a disconnect. So here you are...
- */
- ESPCMD(sc, ESPCMD_ENSEL);
- if (sc->sc_state != ESP_IDLE) {
- if ((sc->sc_flags & ESP_SYNCHNEGO)) {
-#ifdef ESP_DEBUG
- if (ecb)
- sc_print_addr(ecb->xs->sc_link);
- printf("sync nego not completed!\n");
-#endif
- sc->sc_flags &= ~ESP_SYNCHNEGO;
- sc->sc_tinfo[ecb->xs->sc_link->target].offset = 0;
- sc->sc_tinfo[ecb->xs->sc_link->target].flags &= ~T_NEGOTIATE;
- }
- /*XXX*/sc->sc_msgpriq = sc->sc_msgout = 0;
-
- /* it may be OK to disconnect */
- if (!(sc->sc_flags & ESP_BUSFREE_OK)) {
- if (sc->sc_state == ESP_HASNEXUS) {
- sc_print_addr(ecb->xs->sc_link);
- printf("disconnect without"
- "warning\n");
- }
- ecb->xs->error = XS_TIMEOUT;
- } else if (sc->sc_flags & ESP_DISCON) {
- TAILQ_INSERT_HEAD(&sc->nexus_list, ecb, chain);
- ECB_SETQ(ecb, ECB_QNEXUS);
- sc->sc_nexus = NULL;
- sc->sc_flags &= ~ESP_DISCON;
- sc->sc_state = ESP_IDLE;
-#if ESP_DEBUG
-if ((esp_debug & 0x10000) && ecb->dleft == 0) {
- printf("%s: silly disconnect (ecb %p [stat %x])\n",
- sc->sc_dev.dv_xname, ecb, ecb->stat);
-}
-#endif
- esp_sched(sc);
- return 1;
- }
-
- esp_done(ecb);
- return 1;
- }
- printf("%s: DISCONNECT in IDLE state!\n",
- sc->sc_dev.dv_xname);
- }
-
- /* did a message go out OK ? This must be broken */
- if (sc->sc_prevphase == MESSAGE_OUT_PHASE &&
- sc->sc_phase != MESSAGE_OUT_PHASE) {
- /* we have sent it */
- if (sc->sc_msgout == SEND_SDTR &&
- (sc->sc_flags & ESP_SYNCHNEGO) == 0) {
- /* We've just accepted new sync parameters */
- sc->sc_tinfo[ecb->xs->sc_link->target].flags |=
- T_SYNCMODE;
-if (ecb) sc_print_addr(ecb->xs->sc_link);else printf("NO nexus: ");
-printf("target put in SYNC mode\n");
- }
- sc->sc_msgpriq &= ~sc->sc_msgout;
- sc->sc_msgout = 0;
- }
-
- switch (sc->sc_state) {
-
- case ESP_SBR:
- printf("%s: waiting for SCSI Bus Reset to happen\n",
- sc->sc_dev.dv_xname);
- return 1;
-
- case ESP_RESELECTED:
- /*
- * we must be continuing a message ?
- */
- if (sc->sc_phase != MESSAGE_IN_PHASE) {
- printf("%s: target didn't identify\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 1);
- return 1;
- }
-printf("<<RESELECT CONT'd>>");
-#if XXXX
- esp_msgin(sc);
- if (sc->sc_state != ESP_HASNEXUS) {
- /* IDENTIFY fail?! */
- printf("%s: identify failed\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 1);
- return 1;
- }
-#endif
- break;
-
- case ESP_IDLE:
-if (sc->sc_flags & ESP_ICCS) printf("[[esp: BUMMER]]");
- case ESP_SELECTING:
-
- if (sc->sc_espintr & ESPINTR_RESEL) {
- /*
- * If we're trying to select a
- * target ourselves, push our command
- * back into the ready list.
- */
- if (sc->sc_state == ESP_SELECTING) {
- ESP_MISC(("backoff selector "));
- sc_link = sc->sc_nexus->xs->sc_link;
- ti = &sc->sc_tinfo[sc_link->target];
- TAILQ_INSERT_HEAD(&sc->ready_list,
- sc->sc_nexus, chain);
- ECB_SETQ(sc->sc_nexus, ECB_QREADY);
- ti->lubusy &= ~(1<<sc_link->lun);
- ecb = sc->sc_nexus = NULL;
- }
- sc->sc_state = ESP_RESELECTED;
- if (sc->sc_phase != MESSAGE_IN_PHASE) {
- /*
- * Things are seriously fucked up.
- * Pull the brakes, i.e. reset
- */
- printf("%s: target didn't identify\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 1);
- return 1;
- }
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) != 2) {
- printf("%s: RESELECT: %d bytes in FIFO!\n",
- sc->sc_dev.dv_xname,
- ESP_READ_REG(sc, ESP_FFLAG) &
- ESPFIFO_FF);
- esp_init(sc, 1);
- return 1;
- }
- sc->sc_selid = ESP_READ_REG(sc, ESP_FIFO);
- sc->sc_selid &= ~(1<<sc->sc_id);
- ESP_MISC(("selid=0x%2x ", sc->sc_selid));
- esp_msgin(sc); /* Handle identify message */
- if (sc->sc_state != ESP_HASNEXUS) {
- /* IDENTIFY fail?! */
- printf("%s: identify failed\n",
- sc->sc_dev.dv_xname);
- esp_init(sc, 1);
- return 1;
- }
- continue; /* ie. next phase expected soon */
- }
-
-#define ESPINTR_DONE (ESPINTR_FC|ESPINTR_BS)
- if ((sc->sc_espintr & ESPINTR_DONE) == ESPINTR_DONE) {
- ecb = sc->sc_nexus;
- if (!ecb)
- panic("esp: not nexus at sc->sc_nexus");
-
- sc_link = ecb->xs->sc_link;
- ti = &sc->sc_tinfo[sc_link->target];
-
- switch (sc->sc_espstep) {
- case 0:
- printf("%s: select timeout/no disconnect\n",
- sc->sc_dev.dv_xname);
- esp_abort(sc, ecb);
- return 1;
- case 1:
- if ((ti->flags & T_NEGOTIATE) == 0) {
- printf("%s: step 1 & !NEG\n",
- sc->sc_dev.dv_xname);
- esp_abort(sc, ecb);
- return 1;
- }
- if (sc->sc_phase != MESSAGE_OUT_PHASE) {
- printf("%s: !MSGOUT\n",
- sc->sc_dev.dv_xname);
- esp_abort(sc, ecb);
- return 1;
- }
- /* Start negotiating */
- ti->period = sc->sc_minsync;
- ti->offset = 15;
- sc->sc_msgpriq = SEND_SDTR;
- sc->sc_flags |= ESP_SYNCHNEGO;
- break;
- case 3:
- /*
- * Grr, this is supposed to mean
- * "target left command phase
- * prematurely". It seems to happen
- * regularly when sync mode is on.
- * Look at FIFO to see if command
- * went out.
- * (Timing problems?)
- */
- if ((ESP_READ_REG(sc, ESP_FFLAG)&ESPFIFO_FF) == 0) {
- /* Hope for the best.. */
- break;
- }
- printf("(%s:%d:%d): selection failed;"
- " %d left in FIFO "
- "[intr %x, stat %x, step %d]\n",
- sc->sc_dev.dv_xname,
- sc_link->target,
- sc_link->lun,
- ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- ESPCMD(sc, ESPCMD_FLUSH);
- sc->sc_flags |= ESP_ABORTING;
- esp_sched_msgout(SEND_ABORT);
- return 1;
- case 2:
- /* Select stuck at Command Phase */
- ESPCMD(sc, ESPCMD_FLUSH);
- case 4:
- /* So far, everything went fine */
- sc->sc_msgpriq = 0;
- break;
- }
-#if 0
-/* Why set msgpriq? (and not raise ATN) */
- if (ecb->xs->flags & SCSI_RESET)
- sc->sc_msgpriq = SEND_DEV_RESET;
- else if (ti->flags & T_NEGOTIATE)
- sc->sc_msgpriq =
- SEND_IDENTIFY | SEND_SDTR;
- else
- sc->sc_msgpriq = SEND_IDENTIFY;
-#endif
- sc->sc_state = ESP_HASNEXUS;
- /*???sc->sc_flags = 0; */
- sc->sc_prevphase = INVALID_PHASE; /* ?? */
- sc->sc_dp = ecb->daddr;
- sc->sc_dleft = ecb->dleft;
- ti->lubusy |= (1<<sc_link->lun);
- break;
- } else {
- printf("%s: unexpected status after select"
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- esp_abort(sc, ecb);
- }
- if (sc->sc_state == ESP_IDLE) {
- printf("%s: stray interrupt\n", sc->sc_dev.dv_xname);
- return 0;
- }
- break;
-
- case ESP_HASNEXUS:
- if (sc->sc_flags & ESP_ICCS) {
- unsigned char msg;
-
- sc->sc_flags &= ~ESP_ICCS;
-
- if (!(sc->sc_espintr & ESPINTR_DONE)) {
- printf("%s: ICCS: "
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) != 2) {
- printf("%s: ICCS: expected 2, got %d "
- ": [intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- ESPCMD(sc, ESPCMD_FLUSH);
- esp_abort(sc, ecb);
- return 1;
- }
- ecb->stat = ESP_READ_REG(sc, ESP_FIFO);
- msg = ESP_READ_REG(sc, ESP_FIFO);
- ESP_PHASE(("<stat:(%x,%x)>", ecb->stat, msg));
- if (msg == MSG_CMDCOMPLETE) {
- sc->sc_flags |= ESP_BUSFREE_OK;
- ecb->xs->resid = ecb->dleft = sc->sc_dleft;
- } else
- printf("%s: STATUS_PHASE: msg %d\n",
- sc->sc_dev.dv_xname, msg);
- ESPCMD(sc, ESPCMD_MSGOK);
- continue; /* ie. wait for disconnect */
- }
- break;
- default:
- panic("%s: invalid state: %d",
- sc->sc_dev.dv_xname,
- sc->sc_state);
- }
-
- /*
- * Driver is now in state ESP_HASNEXUS, i.e. we
- * have a current command working the SCSI bus.
- */
- if (sc->sc_state != ESP_HASNEXUS || ecb == NULL) {
- panic("esp no nexus");
- }
-
- switch (sc->sc_phase) {
- case MESSAGE_OUT_PHASE:
- ESP_PHASE(("MESSAGE_OUT_PHASE "));
- esp_msgout(sc);
- sc->sc_prevphase = MESSAGE_OUT_PHASE;
- break;
- case MESSAGE_IN_PHASE:
- ESP_PHASE(("MESSAGE_IN_PHASE "));
- if (sc->sc_espintr & ESPINTR_BS) {
- ESPCMD(sc, ESPCMD_FLUSH);
- sc->sc_flags |= ESP_WAITI;
- ESPCMD(sc, ESPCMD_TRANS);
- } else if (sc->sc_espintr & ESPINTR_FC) {
- if ((sc->sc_flags & ESP_WAITI) == 0) {
- printf("%s: MSGIN: unexpected FC bit: "
- "[intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- sc->sc_flags &= ~ESP_WAITI;
- esp_msgin(sc);
- } else {
- printf("%s: MSGIN: weird bits: "
- "[intr %x, stat %x, step %x]\n",
- sc->sc_dev.dv_xname,
- sc->sc_espintr, sc->sc_espstat,
- sc->sc_espstep);
- }
- sc->sc_prevphase = MESSAGE_IN_PHASE;
- break;
- case COMMAND_PHASE: {
- /* well, this means send the command again */
- u_char *cmd = (u_char *)&ecb->cmd;
- int i;
-
- ESP_PHASE(("COMMAND_PHASE 0x%02x (%d) ",
- ecb->cmd.opcode, ecb->clen));
- if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
- ESPCMD(sc, ESPCMD_FLUSH);
- DELAY(1);
- }
- /* Now the command into the FIFO */
- for (i = 0; i < ecb->clen; i++)
- ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
- ESPCMD(sc, ESPCMD_TRANS);
- sc->sc_prevphase = COMMAND_PHASE;
- }
- break;
- case DATA_OUT_PHASE:
- ESP_PHASE(("DATA_OUT_PHASE [%d] ", sc->sc_dleft));
- ESPCMD(sc, ESPCMD_FLUSH);
- size = min(sc->sc_dleft, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft,
- 0, &size);
- sc->sc_prevphase = DATA_OUT_PHASE;
- goto setup_xfer;
- case DATA_IN_PHASE:
- ESP_PHASE(("DATA_IN_PHASE "));
- if (sc->sc_rev == ESP100)
- ESPCMD(sc, ESPCMD_FLUSH);
- size = min(sc->sc_dleft, sc->sc_maxxfer);
- DMA_SETUP(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft,
- 1, &size);
- sc->sc_prevphase = DATA_IN_PHASE;
- setup_xfer:
- /* Program the SCSI counter */
- ESP_WRITE_REG(sc, ESP_TCL, size);
- ESP_WRITE_REG(sc, ESP_TCM, size >> 8);
- if (sc->sc_cfg2 & ESPCFG2_FE) {
- ESP_WRITE_REG(sc, ESP_TCH, size >> 16);
- }
- /* load the count in */
- ESPCMD(sc, ESPCMD_NOP|ESPCMD_DMA);
-
- /*
- * Note that if `size' is 0, we've already transceived
- * all the bytes we want but we're still in DATA PHASE.
- * Apparently, the device needs padding. Also, a
- * transfer size of 0 means "maximum" to the chip
- * DMA logic.
- */
- ESPCMD(sc,
- (size==0?ESPCMD_TRPAD:ESPCMD_TRANS)|ESPCMD_DMA);
- DMA_GO(sc->sc_dma);
- return 1;
- case STATUS_PHASE:
- ESP_PHASE(("STATUS_PHASE "));
- sc->sc_flags |= ESP_ICCS;
- ESPCMD(sc, ESPCMD_ICCS);
- sc->sc_prevphase = STATUS_PHASE;
- break;
- case INVALID_PHASE:
- break;
- case BUSFREE_PHASE:
- if (sc->sc_flags & ESP_BUSFREE_OK) {
- /*It's fun the 1st time.. */
- sc->sc_flags &= ~ESP_BUSFREE_OK;
- }
- break;
- default:
- panic("esp: bogus bus phase\n");
- }
- }
- panic("esp: should not get here..");
-}
-
-void
-esp_abort(sc, ecb)
- struct esp_softc *sc;
- struct ecb *ecb;
-{
- if (ecb == sc->sc_nexus) {
- if (sc->sc_state == ESP_HASNEXUS) {
- sc->sc_flags |= ESP_ABORTING;
- esp_sched_msgout(SEND_ABORT);
- }
- } else {
- if (sc->sc_state == ESP_IDLE)
- esp_sched(sc);
- }
-}
-
-void
-esp_timeout(arg)
- void *arg;
-{
- int s = splbio();
- struct ecb *ecb = (struct ecb *)arg;
- struct esp_softc *sc;
- struct scsi_xfer *xs = ecb->xs;
-
- sc = xs->sc_link->adapter_softc;
- sc_print_addr(xs->sc_link);
-again:
- printf("%s: timed out [ecb %p (flags 0x%x, dleft %x, stat %x)], "
- "<state %d, nexus %p, phase(c %x, p %x), resid %x, msg(q %x,o %x) %s>",
- sc->sc_dev.dv_xname,
- ecb, ecb->flags, ecb->dleft, ecb->stat,
- sc->sc_state, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase,
- sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout,
- DMA_ISACTIVE(sc->sc_dma) ? "DMA active" : "");
-#if ESP_DEBUG > 0
- printf("TRACE: %s.", ecb->trace);
-#endif
-
- if (ecb->flags & ECB_ABORTED) {
- /* abort timed out */
- printf(" AGAIN\n");
- esp_init(sc, 1);
- } else {
- /* abort the operation that has timed out */
- printf("\n");
- xs->error = XS_TIMEOUT;
- ecb->flags |= ECB_ABORTED;
- esp_abort(sc, ecb);
- /* 2 secs for the abort */
- if ((xs->flags & SCSI_POLL) == 0)
- timeout(esp_timeout, ecb, 2 * hz);
- else {
- int count = 200000;
- while (count) {
- if (DMA_ISINTR(sc->sc_dma)) {
- espintr(sc);
- }
- if (xs->flags & ITSDONE)
- break;
- DELAY(10);
- --count;
- }
- if (count == 0)
- goto again;
- }
- }
- splx(s);
+ return (DMA_ISACTIVE(esc->sc_dma));
}
diff --git a/sys/arch/sparc/dev/espreg.h b/sys/arch/sparc/dev/espreg.h
deleted file mode 100644
index e08eebcad7c..00000000000
--- a/sys/arch/sparc/dev/espreg.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* $NetBSD: espreg.h,v 1.7 1995/12/18 23:58:39 pk Exp $ */
-
-/*
- * Copyright (c) 1994 Peter Galbavy. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Peter Galbavy.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Register addresses, relative to some base address
- */
-
-#define ESP_TCL 0x00 /* RW - Transfer Count Low */
-#define ESP_TCM 0x01 /* RW - Transfer Count Mid */
-#define ESP_TCH 0x0e /* RW - Transfer Count High */
- /* NOT on 53C90 */
-
-#define ESP_FIFO 0x02 /* RW - FIFO data */
-
-#define ESP_CMD 0x03 /* RW - Command (2 deep) */
-#define ESPCMD_DMA 0x80 /* DMA Bit */
-#define ESPCMD_NOP 0x00 /* No Operation */
-#define ESPCMD_FLUSH 0x01 /* Flush FIFO */
-#define ESPCMD_RSTCHIP 0x02 /* Reset Chip */
-#define ESPCMD_RSTSCSI 0x03 /* Reset SCSI Bus */
-#define ESPCMD_RESEL 0x40 /* Reselect Sequence */
-#define ESPCMD_SELNATN 0x41 /* Select without ATN */
-#define ESPCMD_SELATN 0x42 /* Select with ATN */
-#define ESPCMD_SELATNS 0x43 /* Select with ATN & Stop */
-#define ESPCMD_ENSEL 0x44 /* Enable (Re)Selection */
-#define ESPCMD_DISSEL 0x45 /* Disable (Re)Selection */
-#define ESPCMD_SELATN3 0x46 /* Select with ATN3 */
-#define ESPCMD_RESEL3 0x47 /* Reselect3 Sequence */
-#define ESPCMD_SNDMSG 0x20 /* Send Message */
-#define ESPCMD_SNDSTAT 0x21 /* Send Status */
-#define ESPCMD_SNDDATA 0x22 /* Send Data */
-#define ESPCMD_DISCSEQ 0x23 /* Disconnect Sequence */
-#define ESPCMD_TERMSEQ 0x24 /* Terminate Sequence */
-#define ESPCMD_TCCS 0x25 /* Target Command Comp Seq */
-#define ESPCMD_DISC 0x27 /* Disconnect */
-#define ESPCMD_RECMSG 0x28 /* Receive Message */
-#define ESPCMD_RECCMD 0x29 /* Receive Command */
-#define ESPCMD_RECDATA 0x2a /* Receive Data */
-#define ESPCMD_RECCSEQ 0x2b /* Receive Command Sequence*/
-#define ESPCMD_ABORT 0x04 /* Target Abort DMA */
-#define ESPCMD_TRANS 0x10 /* Transfer Information */
-#define ESPCMD_ICCS 0x11 /* Initiator Cmd Comp Seq */
-#define ESPCMD_MSGOK 0x12 /* Message Accepted */
-#define ESPCMD_TRPAD 0x18 /* Transfer Pad */
-#define ESPCMD_SETATN 0x1a /* Set ATN */
-#define ESPCMD_RSTATN 0x1b /* Reset ATN */
-
-#define ESP_STAT 0x04 /* RO - Status */
-#define ESPSTAT_INT 0x80 /* Interrupt */
-#define ESPSTAT_GE 0x40 /* Gross Error */
-#define ESPSTAT_PE 0x20 /* Parity Error */
-#define ESPSTAT_TC 0x10 /* Terminal Count */
-#define ESPSTAT_VGC 0x08 /* Valid Group Code */
-#define ESPSTAT_PHASE 0x07 /* Phase bits */
-
-#define ESP_SELID 0x04 /* WO - Select/Reselect Bus ID */
-
-#define ESP_INTR 0x05 /* RO - Interrupt */
-#define ESPINTR_SBR 0x80 /* SCSI Bus Reset */
-#define ESPINTR_ILL 0x40 /* Illegal Command */
-#define ESPINTR_DIS 0x20 /* Disconnect */
-#define ESPINTR_BS 0x10 /* Bus Service */
-#define ESPINTR_FC 0x08 /* Function Complete */
-#define ESPINTR_RESEL 0x04 /* Reselected */
-#define ESPINTR_SELATN 0x02 /* Select with ATN */
-#define ESPINTR_SEL 0x01 /* Selected */
-
-#define ESP_TIMEOUT 0x05 /* WO - Select/Reselect Timeout */
-
-#define ESP_STEP 0x06 /* RO - Sequence Step */
-#define ESPSTEP_MASK 0x07 /* the last 3 bits */
-#define ESPSTEP_DONE 0x04 /* command went out */
-
-#define ESP_SYNCTP 0x06 /* WO - Synch Transfer Period */
- /* Default 5 (53C9X) */
-
-#define ESP_FFLAG 0x07 /* RO - FIFO Flags */
-#define ESPFIFO_SS 0xe0 /* Sequence Step (Dup) */
-#define ESPFIFO_FF 0x1f /* Bytes in FIFO */
-
-#define ESP_SYNCOFF 0x07 /* WO - Synch Offset */
- /* 0 = ASYNC */
- /* 1 - 15 = SYNC bytes */
-
-#define ESP_CFG1 0x08 /* RW - Configuration #1 */
-#define ESPCFG1_SLOW 0x80 /* Slow Cable Mode */
-#define ESPCFG1_SRR 0x40 /* SCSI Reset Rep Int Dis */
-#define ESPCFG1_PTEST 0x20 /* Parity Test Mod */
-#define ESPCFG1_PARENB 0x10 /* Enable Parity Check */
-#define ESPCFG1_CTEST 0x08 /* Enable Chip Test */
-#define ESPCFG1_BUSID 0x07 /* Bus ID */
-
-#define ESP_CCF 0x09 /* WO - Clock Conversion Factor */
- /* 0 = 35.01 - 40Mhz */
- /* NEVER SET TO 1 */
- /* 2 = 10Mhz */
- /* 3 = 10.01 - 15Mhz */
- /* 4 = 15.01 - 20Mhz */
- /* 5 = 20.01 - 25Mhz */
- /* 6 = 25.01 - 30Mhz */
- /* 7 = 30.01 - 35Mhz */
-
-#define ESP_TEST 0x0a /* WO - Test (Chip Test Only) */
-
-#define ESP_CFG2 0x0b /* RW - Configuration #2 */
-#define ESPCFG2_RSVD 0xa0 /* reserved */
-#define ESPCFG2_FE 0x40 /* Features Enable */
-#define ESPCFG2_DREQ 0x10 /* DREQ High Impedance */
-#define ESPCFG2_SCSI2 0x08 /* SCSI-2 Enable */
-#define ESPCFG2_BPA 0x04 /* Target Bad Parity Abort */
-#define ESPCFG2_RPE 0x02 /* Register Parity Error */
-#define ESPCFG2_DPE 0x01 /* DMA Parity Error */
-
-/* Config #3 only on 53C9X */
-#define ESP_CFG3 0x0c /* RW - Configuration #3 */
-#define ESPCFG3_RSVD 0xe0 /* reserved */
-#define ESPCFG3_IDM 0x10 /* ID Message Res Check */
-#define ESPCFG3_QTE 0x08 /* Queue Tag Enable */
-#define ESPCFG3_CDB 0x04 /* CDB 10-bytes OK */
-#define ESPCFG3_FSCSI 0x02 /* Fast SCSI */
-#define ESPCFG3_FCLK 0x01 /* Fast Clock (>25Mhz) */
diff --git a/sys/arch/sparc/dev/espvar.h b/sys/arch/sparc/dev/espvar.h
index 8b0b414a08a..32f81278479 100644
--- a/sys/arch/sparc/dev/espvar.h
+++ b/sys/arch/sparc/dev/espvar.h
@@ -1,7 +1,10 @@
-/* $NetBSD: espvar.h,v 1.13 1996/05/16 20:31:30 pk Exp $ */
+/* $OpenBSD: espvar.h,v 1.5 1997/08/08 08:25:02 downsj Exp $ */
+/* $NetBSD: espvar.h,v 1.19 1997/02/27 01:16:21 thorpej Exp $ */
/*
- * Copyright (c) 1994 Peter Galbavy. All rights reserved.
+ * Copyright (c) 1997 Jason R. Thorpe.
+ * All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +15,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by Peter Galbavy.
+ * This product includes software developed for the NetBSD Project
+ * by Jason R. Thorpe.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
@@ -28,273 +32,20 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define ESP_DEBUG 0
-
-#define FREQTOCCF(freq) (((freq + 4) / 5))
-
-/* esp revisions */
-#define ESP100 0x01
-#define ESP100A 0x02
-#define ESP200 0x03
-
-#if 0
-typedef caddr_t physaddr;
-
-struct esp_dma_seg {
- physaddr addr;
- long len;
-};
-#endif
-
-/*
- * ECB. Holds additional information for each SCSI command Comments: We
- * need a separate scsi command block because we may need to overwrite it
- * with a request sense command. Basicly, we refrain from fiddling with
- * the scsi_xfer struct (except do the expected updating of return values).
- * We'll generally update: xs->{flags,resid,error,sense,status} and
- * occasionally xs->retries.
- */
-struct ecb {
- TAILQ_ENTRY(ecb) chain;
- struct scsi_xfer *xs; /* SCSI xfer ctrl block from above */
- int flags; /* Status */
-#define ECB_QNONE 0
-#define ECB_QFREE 1
-#define ECB_QREADY 2
-#define ECB_QNEXUS 3
-#define ECB_QBITS 0x07
-#define ECB_CHKSENSE 0x08
-#define ECB_ABORTED 0x10
-#define ECB_SETQ(e, q) do (e)->flags = ((e)->flags&~ECB_QBITS)|(q); while(0)
- struct scsi_generic cmd; /* SCSI command block */
- int clen;
- char *daddr; /* Saved data pointer */
- int dleft; /* Residue */
- u_char stat; /* SCSI status byte */
-#if ESP_DEBUG > 0
- char trace[1000];
-#endif
-};
-#if ESP_DEBUG > 0
-#define ECB_TRACE(ecb, msg, a, b) do { \
- const char *f = "[" msg "]"; \
- int n = strlen((ecb)->trace); \
- if (n < (sizeof((ecb)->trace)-100)) \
- sprintf((ecb)->trace + n, f, a, b); \
-} while(0)
-#else
-#define ECB_TRACE(ecb, msg, a, b)
-#endif
-
-/*
- * Some info about each (possible) target on the SCSI bus. This should
- * probably have been a "per target+lunit" structure, but we'll leave it at
- * this for now. Is there a way to reliably hook it up to sc->fordriver??
- */
-struct esp_tinfo {
- int cmds; /* #commands processed */
- int dconns; /* #disconnects */
- int touts; /* #timeouts */
- int perrs; /* #parity errors */
- int senses; /* #request sense commands sent */
- ushort lubusy; /* What local units/subr. are busy? */
- u_char flags;
-#define T_NEED_TO_RESET 0x01 /* Should send a BUS_DEV_RESET */
-#define T_NEGOTIATE 0x02 /* (Re)Negotiate synchronous options */
-#define T_BUSY 0x04 /* Target is busy, i.e. cmd in progress */
-#define T_SYNCMODE 0x08 /* sync mode has been negotiated */
-#define T_SYNCHOFF 0x10 /* .. */
-#define T_RSELECTOFF 0x20 /* .. */
- u_char period; /* Period suggestion */
- u_char offset; /* Offset suggestion */
-} tinfo_t;
-
-/* Register a linenumber (for debugging) */
-#define LOGLINE(p)
-
-#define ESP_SHOWECBS 0x01
-#define ESP_SHOWINTS 0x02
-#define ESP_SHOWCMDS 0x04
-#define ESP_SHOWMISC 0x08
-#define ESP_SHOWTRAC 0x10
-#define ESP_SHOWSTART 0x20
-#define ESP_SHOWPHASE 0x40
-#define ESP_SHOWDMA 0x80
-#define ESP_SHOWCCMDS 0x100
-#define ESP_SHOWMSGS 0x200
-
-#ifdef ESP_DEBUG
-extern int esp_debug;
-#define ESP_ECBS(str) do {if (esp_debug & ESP_SHOWECBS) printf str;} while (0)
-#define ESP_MISC(str) do {if (esp_debug & ESP_SHOWMISC) printf str;} while (0)
-#define ESP_INTS(str) do {if (esp_debug & ESP_SHOWINTS) printf str;} while (0)
-#define ESP_TRACE(str) do {if (esp_debug & ESP_SHOWTRAC) printf str;} while (0)
-#define ESP_CMDS(str) do {if (esp_debug & ESP_SHOWCMDS) printf str;} while (0)
-#define ESP_START(str) do {if (esp_debug & ESP_SHOWSTART) printf str;}while (0)
-#define ESP_PHASE(str) do {if (esp_debug & ESP_SHOWPHASE) printf str;}while (0)
-#define ESP_DMA(str) do {if (esp_debug & ESP_SHOWDMA) printf str;}while (0)
-#define ESP_MSGS(str) do {if (esp_debug & ESP_SHOWMSGS) printf str;}while (0)
-#else
-#define ESP_ECBS(str)
-#define ESP_MISC(str)
-#define ESP_INTS(str)
-#define ESP_TRACE(str)
-#define ESP_CMDS(str)
-#define ESP_START(str)
-#define ESP_PHASE(str)
-#define ESP_DMA(str)
-#endif
-
-#define ESP_MAX_MSG_LEN 8
-
struct esp_softc {
- struct device sc_dev; /* us as a device */
+ struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
+
struct sbusdev sc_sd; /* sbus device */
struct intrhand sc_ih; /* intr handler */
- struct evcnt sc_intrcnt; /* intr count */
- struct scsi_link sc_link; /* scsi lint struct */
+
volatile u_char *sc_reg; /* the registers */
struct dma_softc *sc_dma; /* pointer to my dma */
- /* register defaults */
- u_char sc_cfg1; /* Config 1 */
- u_char sc_cfg2; /* Config 2, not ESP100 */
- u_char sc_cfg3; /* Config 3, only ESP200 */
- u_char sc_ccf; /* Clock Conversion */
- u_char sc_timeout;
-
- /* register copies, see espreadregs() */
- u_char sc_espintr;
- u_char sc_espstat;
- u_char sc_espstep;
- u_char sc_espfflags;
-
- /* Lists of command blocks */
- TAILQ_HEAD(ecb_list, ecb) free_list,
- ready_list,
- nexus_list;
-
- struct ecb *sc_nexus; /* current command */
- struct ecb sc_ecb[8]; /* one per target */
- struct esp_tinfo sc_tinfo[8];
-
- /* Data about the current nexus (updated for every cmd switch) */
- caddr_t sc_dp; /* Current data pointer */
- ssize_t sc_dleft; /* Data left to transfer */
-
- /* Adapter state */
- int sc_phase; /* Copy of what bus phase we are in */
- int sc_prevphase; /* Copy of what bus phase we were in */
- u_char sc_state; /* State applicable to the adapter */
- u_char sc_flags;
- u_char sc_selid;
- u_char sc_lastcmd;
-
- /* Message stuff */
- u_char sc_msgpriq; /* One or more messages to send (encoded) */
- u_char sc_msgout; /* What message is on its way out? */
- u_char sc_omess[ESP_MAX_MSG_LEN];
- caddr_t sc_omp; /* Message pointer (for multibyte messages) */
- size_t sc_omlen;
- u_char sc_imess[ESP_MAX_MSG_LEN + 1];
- caddr_t sc_imp; /* Message pointer (for multibyte messages) */
- size_t sc_imlen;
-
- /* hardware/openprom stuff */
+ /* openprom stuff */
int sc_node; /* PROM node ID */
- int sc_freq; /* Freq in HZ */
int sc_pri; /* SBUS priority */
- int sc_id; /* our scsi id */
- int sc_rev; /* esp revision */
- int sc_minsync; /* minimum sync period / 4 */
- int sc_maxxfer; /* maximum transfer size */
};
-/*
- * Macros to read and write the chip's registers.
- */
-#define ESP_READ_REG(sc, reg) \
- ((sc)->sc_reg[(reg) * 4])
-#define ESP_WRITE_REG(sc, reg, val) \
- do { \
- u_char v = (val); \
- (sc)->sc_reg[(reg) * 4] = v; \
- } while (0)
-
-/* values for sc_state */
-#define ESP_IDLE 0x01 /* waiting for something to do */
-#define ESP_TMP_UNAVAIL 0x02 /* Don't accept SCSI commands */
-#define ESP_SELECTING 0x03 /* SCSI command is arbiting */
-#define ESP_RESELECTED 0x04 /* Has been reselected */
-#define ESP_HASNEXUS 0x05 /* Actively using the SCSI bus */
-#define ESP_CLEANING 0x06
-#define ESP_SBR 0x07 /* Expect a SCSI RST because we commanded it */
-
-/* values for sc_flags */
-#define ESP_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */
-#define ESP_DOINGDMA 0x02 /* The FIFO data path is active! */
-#define ESP_BUSFREE_OK 0x04 /* Bus free phase is OK. */
-#define ESP_SYNCHNEGO 0x08 /* Synch negotiation in progress. */
-/*#define ESP_BLOCKED 0x10 * Don't schedule new scsi bus operations */
-#define ESP_DISCON 0x10 /* Target sent DISCONNECT msg */
-#define ESP_ABORTING 0x20 /* Bailing out */
-#define ESP_ICCS 0x40 /* Expect status phase results */
-#define ESP_WAITI 0x80 /* Waiting for non-DMA data to arrive */
-
-/* values for sc_msgout */
-#define SEND_DEV_RESET 0x01
-#define SEND_PARITY_ERROR 0x02
-#define SEND_ABORT 0x04
-#define SEND_REJECT 0x08
-#define SEND_INIT_DET_ERR 0x10
-#define SEND_IDENTIFY 0x20
-#define SEND_SDTR 0x40
-
-/* SCSI Status codes */
-#define ST_GOOD 0x00
-#define ST_CHKCOND 0x02
-#define ST_CONDMET 0x04
-#define ST_BUSY 0x08
-#define ST_INTERMED 0x10
-#define ST_INTERMED_CONDMET 0x14
-#define ST_RESERVATION_CONFLICT 0x18
-#define ST_CMD_TERM 0x22
-#define ST_QUEUE_FULL 0x28
-
-#define ST_MASK 0x3e /* bit 0,6,7 is reserved */
-
-/* phase bits */
-#define IOI 0x01
-#define CDI 0x02
-#define MSGI 0x04
-
-/* Information transfer phases */
-#define DATA_OUT_PHASE (0)
-#define DATA_IN_PHASE (IOI)
-#define COMMAND_PHASE (CDI)
-#define STATUS_PHASE (CDI|IOI)
-#define MESSAGE_OUT_PHASE (MSGI|CDI)
-#define MESSAGE_IN_PHASE (MSGI|CDI|IOI)
-
-#define PHASE_MASK (MSGI|CDI|IOI)
-
-/* Some pseudo phases for getphase()*/
-#define BUSFREE_PHASE 0x100 /* Re/Selection no longer valid */
-#define INVALID_PHASE 0x101 /* Re/Selection valid, but no REQ yet */
-#define PSEUDO_PHASE 0x100 /* "pseudo" bit */
-
-#ifdef ESP_DEBUG
-#define ESPCMD(sc, cmd) do { \
- if (esp_debug & ESP_SHOWCCMDS) \
- printf("<cmd:0x%x>", (unsigned)cmd); \
- sc->sc_lastcmd = cmd; \
- ESP_WRITE_REG(sc, ESP_CMD, cmd); \
-} while (0)
-#else
-#define ESPCMD(sc, cmd) ESP_WRITE_REG(sc, ESP_CMD, cmd)
-#endif
-
#define SAME_ESP(sc, bp, ca) \
((bp->val[0] == ca->ca_slot && bp->val[1] == ca->ca_offset) || \
(bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit))
-
diff --git a/sys/arch/sparc/dev/event.c b/sys/arch/sparc/dev/event.c
deleted file mode 100644
index 3e25c91edb4..00000000000
--- a/sys/arch/sparc/dev/event.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* $NetBSD: event.c,v 1.3 1994/11/20 20:52:13 deraadt Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)event.c 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Internal `Firm_event' interface for the keyboard and mouse drivers.
- */
-
-#include <sys/param.h>
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/vnode.h>
-
-#include <machine/vuid_event.h>
-#include <sparc/dev/event_var.h>
-
-/*
- * Initialize a firm_event queue.
- */
-void
-ev_init(ev)
- register struct evvar *ev;
-{
-
- ev->ev_get = ev->ev_put = 0;
- ev->ev_q = malloc((u_long)EV_QSIZE * sizeof(struct firm_event),
- M_DEVBUF, M_WAITOK);
- bzero((caddr_t)ev->ev_q, EV_QSIZE * sizeof(struct firm_event));
-}
-
-/*
- * Tear down a firm_event queue.
- */
-void
-ev_fini(ev)
- register struct evvar *ev;
-{
-
- free(ev->ev_q, M_DEVBUF);
-}
-
-/*
- * User-level interface: read, select.
- * (User cannot write an event queue.)
- */
-int
-ev_read(ev, uio, flags)
- register struct evvar *ev;
- struct uio *uio;
- int flags;
-{
- int s, n, cnt, error;
-
- /*
- * Make sure we can return at least 1.
- */
- if (uio->uio_resid < sizeof(struct firm_event))
- return (EMSGSIZE); /* ??? */
- s = splev();
- while (ev->ev_get == ev->ev_put) {
- if (flags & IO_NDELAY) {
- splx(s);
- return (EWOULDBLOCK);
- }
- ev->ev_wanted = 1;
- error = tsleep((caddr_t)ev, PEVENT | PCATCH, "firm_event", 0);
- if (error) {
- splx(s);
- return (error);
- }
- }
- /*
- * Move firm_events from tail end of queue (there is at least one
- * there).
- */
- if (ev->ev_put < ev->ev_get)
- cnt = EV_QSIZE - ev->ev_get; /* events in [get..QSIZE) */
- else
- cnt = ev->ev_put - ev->ev_get; /* events in [get..put) */
- splx(s);
- n = howmany(uio->uio_resid, sizeof(struct firm_event));
- if (cnt > n)
- cnt = n;
- error = uiomove((caddr_t)&ev->ev_q[ev->ev_get],
- cnt * sizeof(struct firm_event), uio);
- n -= cnt;
- /*
- * If we do not wrap to 0, used up all our space, or had an error,
- * stop. Otherwise move from front of queue to put index, if there
- * is anything there to move.
- */
- if ((ev->ev_get = (ev->ev_get + cnt) % EV_QSIZE) != 0 ||
- n == 0 || error || (cnt = ev->ev_put) == 0)
- return (error);
- if (cnt > n)
- cnt = n;
- error = uiomove((caddr_t)&ev->ev_q[0],
- cnt * sizeof(struct firm_event), uio);
- ev->ev_get = cnt;
- return (error);
-}
-
-int
-ev_select(ev, rw, p)
- register struct evvar *ev;
- int rw;
- struct proc *p;
-{
- int s = splev();
-
- switch (rw) {
-
- case FREAD:
- /* succeed if there is something to read */
- if (ev->ev_get != ev->ev_put) {
- splx(s);
- return (1);
- }
- selrecord(p, &ev->ev_sel);
- break;
-
- case FWRITE:
- return (1); /* always fails => never blocks */
- }
- splx(s);
- return (0);
-}
diff --git a/sys/arch/sparc/dev/event_var.h b/sys/arch/sparc/dev/event_var.h
deleted file mode 100644
index 8a7b24fec89..00000000000
--- a/sys/arch/sparc/dev/event_var.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* $NetBSD: event_var.h,v 1.2 1994/11/20 20:52:14 deraadt Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)event_var.h 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Internal `Firm_event' interface for the keyboard and mouse drivers.
- * The drivers are expected not to place events in the queue above spltty(),
- * i.e., are expected to run off serial ports.
- */
-
-/* EV_QSIZE should be a power of two so that `%' is fast */
-#define EV_QSIZE 256 /* may need tuning; this uses 2k */
-
-struct evvar {
- u_int ev_get; /* get (read) index (modified synchronously) */
- volatile u_int ev_put; /* put (write) index (modified by interrupt) */
- struct selinfo ev_sel; /* process selecting */
- struct proc *ev_io; /* process that opened queue (can get SIGIO) */
- char ev_wanted; /* wake up on input ready */
- char ev_async; /* send SIGIO on input ready */
- struct firm_event *ev_q;/* circular buffer (queue) of events */
-};
-
-#define splev() spltty()
-
-#define EV_WAKEUP(ev) { \
- selwakeup(&(ev)->ev_sel); \
- if ((ev)->ev_wanted) { \
- (ev)->ev_wanted = 0; \
- wakeup((caddr_t)(ev)); \
- } \
- if ((ev)->ev_async) \
- psignal((ev)->ev_io, SIGIO); \
-}
-
-void ev_init __P((struct evvar *));
-void ev_fini __P((struct evvar *));
-int ev_read __P((struct evvar *, struct uio *, int));
-int ev_select __P((struct evvar *, int, struct proc *));
-
-/*
- * PEVENT is set just above PSOCK, which is just above TTIPRI, on the
- * theory that mouse and keyboard `user' input should be quick.
- */
-#define PEVENT 23
diff --git a/sys/arch/sparc/dev/fb.c b/sys/arch/sparc/dev/fb.c
index 37bf3b10be7..5c7e3c70916 100644
--- a/sys/arch/sparc/dev/fb.c
+++ b/sys/arch/sparc/dev/fb.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: fb.c,v 1.9 1996/08/13 08:05:25 downsj Exp $ */
-/* $NetBSD: fb.c,v 1.18 1996/04/01 17:29:54 christos Exp $ */
+/* $OpenBSD: fb.c,v 1.10 1997/08/08 08:25:04 downsj Exp $ */
+/* $NetBSD: fb.c,v 1.23 1997/07/07 23:30:22 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -299,23 +299,23 @@ fb_setsize(fb, depth, def_width, def_height, node, bustype)
break;
}
} else if (eep != NULL) {
- switch (eep->ee_diag.eed_scrsize) {
- case EED_SCR_1152X900:
+ switch (eep->eeScreenSize) {
+ case EE_SCR_1152X900:
fb->fb_type.fb_width = 1152;
fb->fb_type.fb_height = 900;
break;
- case EED_SCR_1024X1024:
+ case EE_SCR_1024X1024:
fb->fb_type.fb_width = 1024;
fb->fb_type.fb_height = 1024;
break;
- case EED_SCR_1600X1280:
+ case EE_SCR_1600X1280:
fb->fb_type.fb_width = 1600;
fb->fb_type.fb_height = 1280;
break;
- case EED_SCR_1440X1440:
+ case EE_SCR_1440X1440:
fb->fb_type.fb_width = 1440;
fb->fb_type.fb_height = 1440;
break;
@@ -354,12 +354,15 @@ fb_setsize(fb, depth, def_width, def_height, node, bustype)
}
}
+
#ifdef RASTERCONSOLE
#include <machine/kbd.h>
-static int a2int __P((char *, int));
static void fb_bell __P((int));
+#if !(defined(RASTERCONS_FULLSCREEN) || defined(RASTERCONS_SMALLFONT))
+static int a2int __P((char *, int));
+
static int
a2int(cp, deflt)
register char *cp;
@@ -373,6 +376,7 @@ a2int(cp, deflt)
i = i * 10 + *cp++ - '0';
return (i);
}
+#endif
static void
fb_bell(on)
@@ -413,8 +417,8 @@ fbrcons_init(fb)
rc->rc_maxcol = 80;
rc->rc_maxrow = 34;
} else {
- rc->rc_maxcol = eep->ee_diag.eed_colsize;
- rc->rc_maxrow = eep->ee_diag.eed_rowsize;
+ rc->rc_maxcol = eep->eeTtyCols;
+ rc->rc_maxrow = eep->eeTtyRows;
}
}
#endif /* SUN4 */
@@ -439,7 +443,19 @@ fbrcons_init(fb)
/* Hook up virtual console */
v_putc = rcons_cnputc;
}
-#endif
+
+int
+fbrcons_rows()
+{
+ return (devfb ? devfb->fb_rcons.rc_maxrow : 0);
+}
+
+int
+fbrcons_cols()
+{
+ return (devfb ? devfb->fb_rcons.rc_maxcol : 0);
+}
+#endif /* RASTERCONSOLE */
#if defined(SUN4)
/*
diff --git a/sys/arch/sparc/dev/fd.c b/sys/arch/sparc/dev/fd.c
index 456ab415b6e..1643db5b031 100644
--- a/sys/arch/sparc/dev/fd.c
+++ b/sys/arch/sparc/dev/fd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fd.c,v 1.19 1997/06/25 13:04:20 downsj Exp $ */
+/* $OpenBSD: fd.c,v 1.20 1997/08/08 08:25:06 downsj Exp $ */
/* $NetBSD: fd.c,v 1.51 1997/05/24 20:16:19 pk Exp $ */
/*-
@@ -369,8 +369,7 @@ fdcattach(parent, self, aux)
fdc->sc_reg = (caddr_t)ca->ca_ra.ra_vaddr;
else
fdc->sc_reg = (caddr_t)mapiodev(ca->ca_ra.ra_reg, 0,
- ca->ca_ra.ra_len,
- ca->ca_bustype);
+ ca->ca_ra.ra_len);
fdc->sc_state = DEVIDLE;
fdc->sc_istate = ISTATE_IDLE;
diff --git a/sys/arch/sparc/dev/i82586.h b/sys/arch/sparc/dev/i82586.h
index 02cd09ef98f..4c5ead2fec3 100644
--- a/sys/arch/sparc/dev/i82586.h
+++ b/sys/arch/sparc/dev/i82586.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: i82586.h,v 1.2 1997/08/08 08:25:07 downsj Exp $ */
/* $NetBSD: i82586.h,v 1.3 1995/01/27 09:49:55 pk Exp $ */
/*-
diff --git a/sys/arch/sparc/dev/if_en_sbus.c b/sys/arch/sparc/dev/if_en_sbus.c
index 9ba4cd3ca99..499f80901fc 100644
--- a/sys/arch/sparc/dev/if_en_sbus.c
+++ b/sys/arch/sparc/dev/if_en_sbus.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: if_en_sbus.c,v 1.2 1996/06/21 21:37:37 chuck Exp $ */
+/* $OpenBSD: if_en_sbus.c,v 1.3 1997/08/08 08:25:08 downsj Exp $ */
+/* $NetBSD: if_en_sbus.c,v 1.4 1997/05/24 20:16:22 pk Exp $ */
/*
*
@@ -138,8 +139,7 @@ void *aux;
return;
}
- sc->en_base = (caddr_t) mapiodev(ca->ca_ra.ra_reg, 0, 4*1024*1024,
- ca->ca_bustype);
+ sc->en_base = (caddr_t) mapiodev(ca->ca_ra.ra_reg, 0, 4*1024*1024);
if (ca->ca_ra.ra_nintr == 1) {
sc->ipl = ca->ca_ra.ra_intr[0].int_pri;
diff --git a/sys/arch/sparc/dev/if_ie.c b/sys/arch/sparc/dev/if_ie.c
index 3bd3defb91a..d57746dbadc 100644
--- a/sys/arch/sparc/dev/if_ie.c
+++ b/sys/arch/sparc/dev/if_ie.c
@@ -1,4 +1,5 @@
-/* $NetBSD: if_ie.c,v 1.24 1996/05/07 01:28:28 thorpej Exp $ */
+/* $OpenBSD: if_ie.c,v 1.7 1997/08/08 08:25:09 downsj Exp $ */
+/* $NetBSD: if_ie.c,v 1.33 1997/07/29 17:55:38 fair Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995 Charles Hannum.
@@ -413,23 +414,22 @@ iematch(parent, vcf, aux)
if (strcmp(cf->cf_driver->cd_name, ra->ra_name)) /* correct name? */
return (0);
- if (ca->ca_bustype == BUS_SBUS)
- return (0);
-
- if (CPU_ISSUN4) {
- /*
- * XXX need better probe here so we can figure out what we've got
- */
- if (ca->ca_bustype == BUS_OBIO) {
- if (probeget(ra->ra_vaddr, 1) == -1)
- return (0);
- return(1);
- }
- if (probeget(ra->ra_vaddr, 2) == -1)
- return (0);
+ switch (ca->ca_bustype) {
+ case BUS_SBUS:
+ default:
+ return (0);
+ case BUS_OBIO:
+ if (probeget(ra->ra_vaddr, 1) != -1)
+ return (1);
+ break;
+ case BUS_VME16:
+ case BUS_VME32:
+ if (probeget(ra->ra_vaddr, 2) != -1)
+ return (1);
+ break;
}
- return (1);
+ return (0);
}
/*
@@ -530,8 +530,7 @@ ieattach(parent, self, aux)
sc->memcopy = bcopy;
sc->memzero = bzero;
sc->sc_msize = 65536; /* XXX */
- sc->sc_reg = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct ieob),
- ca->ca_bustype);
+ sc->sc_reg = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct ieob));
ieo = (volatile struct ieob *) sc->sc_reg;
/*
@@ -594,8 +593,8 @@ ieattach(parent, self, aux)
sc->memcopy = wcopy;
sc->memzero = wzero;
sc->sc_msize = 65536; /* XXX */
- sc->sc_reg = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct ievme),
- ca->ca_bustype);
+ sc->sc_reg = mapiodev(ca->ca_ra.ra_reg, 0,
+ sizeof(struct ievme));
iev = (volatile struct ievme *) sc->sc_reg;
/* top 12 bits */
rampaddr = (u_long)ca->ca_ra.ra_paddr & 0xfff00000;
@@ -603,7 +602,7 @@ ieattach(parent, self, aux)
rampaddr = rampaddr | ((iev->status & IEVME_HADDR) << 16);
rampaddr -= (u_long)ca->ca_ra.ra_paddr;
sc->sc_maddr = mapiodev(ca->ca_ra.ra_reg, rampaddr,
- sc->sc_msize, ca->ca_bustype);
+ sc->sc_msize);
sc->sc_iobase = sc->sc_maddr;
iev->pectrl = iev->pectrl | IEVME_PARACK; /* clear to start */
@@ -731,7 +730,7 @@ void *v;
volatile struct ievme *iev = (volatile struct ievme *)sc->sc_reg
;
if (iev->status & IEVME_PERR) {
- printf("%s: parity error (ctrl %x @ %02x%04x)\n",
+ printf("%s: parity error (ctrl 0x%x @ 0x%02x%04x)\n",
sc->sc_dev.dv_xname, iev->pectrl,
iev->pectrl & IEVME_HADDR, iev->peaddr);
iev->pectrl = iev->pectrl | IEVME_PARACK;
@@ -1317,7 +1316,8 @@ ie_readframe(sc, num)
#ifdef IEDEBUG
if (sc->sc_debug & IED_READFRAME)
- printf("%s: frame from ether %s type %x\n", sc->sc_dev.dv_xname,
+ printf("%s: frame from ether %s type 0x%x\n",
+ sc->sc_dev.dv_xname,
ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
#endif
@@ -1654,7 +1654,7 @@ run_tdr(sc, cmd)
printf("%s: TDR detected a short %d clocks away\n",
sc->sc_dev.dv_xname, result & IE_TDR_TIME);
else
- printf("%s: TDR returned unknown status %x\n",
+ printf("%s: TDR returned unknown status 0x%x\n",
sc->sc_dev.dv_xname, result);
}
diff --git a/sys/arch/sparc/dev/if_ie.h b/sys/arch/sparc/dev/if_ie.h
index 0008a85417d..b9860155b66 100644
--- a/sys/arch/sparc/dev/if_ie.h
+++ b/sys/arch/sparc/dev/if_ie.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: if_ie.h,v 1.2 1997/08/08 08:25:11 downsj Exp $ */
/* $NetBSD: if_ie.h,v 1.4 1994/12/16 22:01:11 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/dev/if_le.c b/sys/arch/sparc/dev/if_le.c
index 4db240f0f62..b0bf63e56e6 100644
--- a/sys/arch/sparc/dev/if_le.c
+++ b/sys/arch/sparc/dev/if_le.c
@@ -1,6 +1,8 @@
-/* $NetBSD: if_le.c,v 1.35.4.1 1996/07/17 01:46:00 jtc Exp $ */
+/* $OpenBSD: if_le.c,v 1.7 1997/08/08 08:25:12 downsj Exp $ */
+/* $NetBSD: if_le.c,v 1.49 1997/07/07 16:28:44 pk Exp $ */
/*-
+ * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
* Copyright (c) 1996
* The President and Fellows of Harvard College. All rights reserved.
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
@@ -22,6 +24,8 @@
* must display the following acknowledgement:
* This product includes software developed by Aaron Brown and
* Harvard University.
+ * This product includes software developed for the NetBSD Project
+ * by Jason R. Thorpe.
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
@@ -54,10 +58,18 @@
#include <sys/malloc.h>
#include <net/if.h>
+#if defined(__NetBSD__)
+#include <net/if_ether.h>
+#include <net/if_media.h>
+#endif /* __NetBSD__ */
#ifdef INET
#include <netinet/in.h>
+#if defined(__NetBSD__)
+#include <netinet/if_inarp.h>
+#else
#include <netinet/if_ether.h>
+#endif /* __NetBSD__ */
#endif
#include <machine/autoconf.h>
@@ -66,6 +78,7 @@
#include <sparc/dev/sbusvar.h>
#include <sparc/dev/dmareg.h>
#include <sparc/dev/dmavar.h>
+#include <sparc/dev/lebuffervar.h>
#include <dev/ic/am7990reg.h>
#include <dev/ic/am7990var.h>
@@ -73,7 +86,11 @@
#include <sparc/dev/if_lereg.h>
#include <sparc/dev/if_levar.h>
+#if defined(__NetBSD__)
+int lematch __P((struct device *, struct cfdata *, void *));
+#else
int lematch __P((struct device *, void *, void *));
+#endif /* __NetBSD__ */
void leattach __P((struct device *, struct device *, void *));
#if defined(SUN4M) /* XXX */
@@ -89,25 +106,41 @@ myleintr(arg)
if (lesc->sc_dma->sc_regs->csr & D_ERR_PEND)
return ledmaintr(lesc->sc_dma);
- /*
- * XXX There is a bug somewhere in the interrupt code that causes stray
- * ethernet interrupts under high network load. This bug has been
- * impossible to locate, so until it is found, we just ignore stray
- * interrupts, as they do not in fact correspond to dropped packets.
- */
-
- /* return */ am7990_intr(arg);
- return 1;
+ return (am7990_intr(arg));
}
#endif
+#if defined(SUN4M)
+#if defined(__NetBSD__)
+/*
+ * Media types supported by the Sun4m.
+ */
+int lemediasun4m[] = {
+ IFM_ETHER|IFM_10_T,
+ IFM_ETHER|IFM_10_5,
+ IFM_ETHER|IFM_AUTO,
+};
+#define NLEMEDIASUN4M (sizeof(lemediasun4m) / sizeof(lemediasun4m[0]))
+#endif /* __NetBSD__ */
+
+void lesetutp __P((struct am7990_softc *));
+void lesetaui __P((struct am7990_softc *));
+
+int lemediachange __P((struct am7990_softc *));
+#if defined(__NetBSD__)
+void lemediastatus __P((struct am7990_softc *, struct ifmediareq *));
+#endif /* __NetBSD__ */
+#endif /* SUN4M */
+
struct cfattach le_ca = {
sizeof(struct le_softc), lematch, leattach
};
hide void lewrcsr __P((struct am7990_softc *, u_int16_t, u_int16_t));
hide u_int16_t lerdcsr __P((struct am7990_softc *, u_int16_t));
+hide void lehwreset __P((struct am7990_softc *));
hide void lehwinit __P((struct am7990_softc *));
+hide void lenocarrier __P((struct am7990_softc *));
hide void
lewrcsr(sc, port, val)
@@ -115,9 +148,21 @@ lewrcsr(sc, port, val)
u_int16_t port, val;
{
register struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
+#if defined(SUN4M)
+ volatile u_int16_t discard;
+#endif
ler1->ler1_rap = port;
ler1->ler1_rdp = val;
+#if defined(SUN4M)
+ /*
+ * We need to flush the Sbus->Mbus write buffers. This can most
+ * easily be accomplished by reading back the register that we
+ * just wrote (thanks to Chris Torek for this solution).
+ */
+ if (CPU_ISSUN4M)
+ discard = ler1->ler1_rdp;
+#endif
}
hide u_int16_t
@@ -133,6 +178,109 @@ lerdcsr(sc, port)
return (val);
}
+#if defined(SUN4M)
+void
+lesetutp(sc)
+ struct am7990_softc *sc;
+{
+ struct le_softc *lesc = (struct le_softc *)sc;
+
+ lesc->sc_dma->sc_regs->csr |= DE_AUI_TP;
+ delay(20000); /* must not touch le for 20ms */
+}
+
+void
+lesetaui(sc)
+ struct am7990_softc *sc;
+{
+ struct le_softc *lesc = (struct le_softc *)sc;
+
+ lesc->sc_dma->sc_regs->csr &= ~DE_AUI_TP;
+ delay(20000); /* must not touch le for 20ms */
+}
+
+int
+lemediachange(sc)
+ struct am7990_softc *sc;
+{
+#if defined(__NetBSD__)
+ struct ifmedia *ifm = &sc->sc_media;
+
+ if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
+ return (EINVAL);
+
+ /*
+ * Switch to the selected media. If autoselect is
+ * set, we don't really have to do anything. We'll
+ * switch to the other media when we detect loss of
+ * carrier.
+ */
+ switch (IFM_SUBTYPE(ifm->ifm_media)) {
+ case IFM_10_T:
+ lesetutp(sc);
+ break;
+
+ case IFM_10_5:
+ lesetaui(sc);
+ break;
+
+ case IFM_AUTO:
+ break;
+
+ default:
+ return (EINVAL);
+ }
+#else
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+
+ if (ifp->if_flags & IFF_LINK0)
+ lesetutp(sc);
+ else if (ifp->if_flags & IFF_LINK1)
+ lesetaui(sc);
+#endif /* __NetBSD__ */
+ return (0);
+}
+
+#if defined(__NetBSD__)
+void
+lemediastatus(sc, ifmr)
+ struct am7990_softc *sc;
+ struct ifmediareq *ifmr;
+{
+ struct le_softc *lesc = (struct le_softc *)sc;
+
+ if (lesc->sc_dma == NULL)
+ return;
+
+ /*
+ * Notify the world which media we're currently using.
+ */
+ if (lesc->sc_dma->sc_regs->csr & DE_AUI_TP)
+ ifmr->ifm_active = IFM_ETHER|IFM_10_T;
+ else
+ ifmr->ifm_active = IFM_ETHER|IFM_10_5;
+}
+#endif /* __NetBSD__ */
+#endif /* SUN4M */
+
+hide void
+lehwreset(sc)
+ struct am7990_softc *sc;
+{
+#if defined(SUN4M)
+ struct le_softc *lesc = (struct le_softc *)sc;
+
+ /*
+ * Reset DMA channel.
+ */
+ if (CPU_ISSUN4M && lesc->sc_dma) {
+ DMA_RESET(lesc->sc_dma);
+ lesc->sc_dma->sc_regs->en_bar = lesc->sc_laddr & 0xff000000;
+ DMA_ENINTR(lesc->sc_dma);
+ }
+#endif
+}
+
hide void
lehwinit(sc)
struct am7990_softc *sc;
@@ -140,25 +288,100 @@ lehwinit(sc)
#if defined(SUN4M)
struct le_softc *lesc = (struct le_softc *)sc;
+ /*
+ * Make sure we're using the currently-enabled media type.
+ * XXX Actually, this is probably unnecessary, now.
+ */
if (CPU_ISSUN4M && lesc->sc_dma) {
+#if defined(__NetBSD__)
+ switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) {
+ case IFM_10_T:
+ lesetutp(sc);
+ break;
+
+ case IFM_10_5:
+ lesetaui(sc);
+ break;
+ }
+#else
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
if (ifp->if_flags & IFF_LINK0)
- lesc->sc_dma->sc_regs->csr |= DE_AUI_TP;
+ lesetutp(sc);
else if (ifp->if_flags & IFF_LINK1)
- lesc->sc_dma->sc_regs->csr &= ~DE_AUI_TP;
-
- delay(20000); /* must not touch le for 20ms */
+ lesetaui(sc);
+#endif /* __NetBSD__ */
}
#endif
}
+hide void
+lenocarrier(sc)
+ struct am7990_softc *sc;
+{
+#if defined(SUN4M)
+ struct le_softc *lesc = (struct le_softc *)sc;
+#if !defined(__NetBSD__)
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+#endif /* __NetBSD__ */
+
+ if (CPU_ISSUN4M && lesc->sc_dma) {
+ /*
+ * Check if the user has requested a certain cable type, and
+ * if so, honor that request.
+ */
+ printf("%s: lost carrier on ", sc->sc_dev.dv_xname);
+ if (lesc->sc_dma->sc_regs->csr & DE_AUI_TP) {
+ printf("UTP port");
+#if defined(__NetBSD__)
+ switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
+ case IFM_10_5:
+ case IFM_AUTO:
+ printf(", switching to AUI port");
+ lesetaui(sc);
+ }
+#else
+ if (!(ifp->if_flags & IFF_LINK0)) {
+ printf(", switching to AUI port");
+ lesetaui(sc);
+ }
+#endif /* __NetBSD__ */
+ } else {
+ printf("AUI port");
+#if defined(__NetBSD__)
+ switch (IFM_SUBTYPE(sc->sc_media.ifm_media)) {
+ case IFM_10_T:
+ case IFM_AUTO:
+ printf(", switching to UTP port");
+ lesetutp(sc);
+ }
+#else
+ if (!(ifp->if_flags & IFF_LINK1)) {
+ printf(", switching to UTP port");
+ lesetutp(sc);
+ }
+#endif /* __NetBSD__ */
+ }
+ printf("\n");
+ } else
+#endif
+ printf("%s: lost carrier\n", sc->sc_dev.dv_xname);
+}
+
int
-lematch(parent, match, aux)
+#if defined(__NetBSD__)
+lematch(parent, cf, aux)
struct device *parent;
- void *match, *aux;
+ struct cfdata *cf;
+ void *aux;
{
- struct cfdata *cf = match;
+#else
+lematch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+#endif /* __NetBSD__ */
struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -180,9 +403,11 @@ leattach(parent, self, aux)
struct confargs *ca = aux;
int pri;
struct bootpath *bp;
- u_long laddr;
#if defined(SUN4C) || defined(SUN4M)
int sbuschild = strncmp(parent->dv_xname, "sbus", 4) == 0;
+ int lebufchild = strncmp(parent->dv_xname, "lebuffer", 8) == 0;
+ int dmachild = strncmp(parent->dv_xname, "ledma", 5) == 0;
+ struct lebuf_softc *lebuf;
#endif
/* XXX the following declarations should be elsewhere */
@@ -195,31 +420,62 @@ leattach(parent, self, aux)
pri = ca->ca_ra.ra_intr[0].int_pri;
printf(" pri %d", pri);
- lesc->sc_r1 = (struct lereg1 *)mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(struct lereg1),
- ca->ca_bustype);
- sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;
- laddr = (u_long)dvma_malloc(MEMSIZE, &sc->sc_mem, M_NOWAIT);
+ lesc->sc_r1 = (struct lereg1 *)
+ mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct lereg1));
+
+#if defined(SUN4C) || defined(SUN4M)
+ lebuf = NULL;
+ if (lebufchild) {
+ lebuf = (struct lebuf_softc *)parent;
+ } else if (sbuschild) {
+ struct sbus_softc *sbus = (struct sbus_softc *)parent;
+ struct sbusdev *sd;
+
+ /*
+ * Find last "unallocated" lebuffer and pair it with
+ * this `le' device on the assumption that we're on
+ * a pre-historic ROM that doesn't establish le<=>lebuffer
+ * parent-child relationships.
+ */
+ for (sd = sbus->sc_sbdev; sd != NULL; sd = sd->sd_bchain) {
+ if (strncmp("lebuffer", sd->sd_dev->dv_xname, 8) != 0)
+ continue;
+ if (((struct lebuf_softc *)sd->sd_dev)->attached == 0) {
+ lebuf = (struct lebuf_softc *)sd->sd_dev;
+ break;
+ }
+ }
+ }
+ if (lebuf != NULL) {
+ sc->sc_mem = lebuf->sc_buffer;
+ sc->sc_memsize = lebuf->sc_bufsiz;
+ sc->sc_addr = 0; /* Lance view is offset by buffer location */
+ lebuf->attached = 1;
+
+ /* That old black magic... */
+ sc->sc_conf3 = getpropint(ca->ca_ra.ra_node,
+ "busmaster-regval",
+ LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON);
+ } else
+#endif
+ {
+ u_long laddr;
+ laddr = (u_long)dvma_malloc(MEMSIZE, &sc->sc_mem, M_NOWAIT);
#if defined (SUN4M)
- if ((laddr & 0xffffff) >= (laddr & 0xffffff) + MEMSIZE)
- panic("if_le: Lance buffer crosses 16MB boundary");
+ if ((laddr & 0xffffff) >= (laddr & 0xffffff) + MEMSIZE)
+ panic("if_le: Lance buffer crosses 16MB boundary");
#endif
- sc->sc_addr = laddr & 0xffffff;
- sc->sc_memsize = MEMSIZE;
-
- myetheraddr(sc->sc_arpcom.ac_enaddr);
-
- sc->sc_copytodesc = am7990_copytobuf_contig;
- sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
- sc->sc_copytobuf = am7990_copytobuf_contig;
- sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
- sc->sc_zerobuf = am7990_zerobuf_contig;
-
- sc->sc_rdcsr = lerdcsr;
- sc->sc_wrcsr = lewrcsr;
- sc->sc_hwinit = lehwinit;
-
- am7990_config(sc);
+ sc->sc_addr = laddr & 0xffffff;
+ sc->sc_memsize = MEMSIZE;
+ sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON;
+#if defined(SUN4C) || defined(SUN4M)
+ if (dmachild) {
+ lesc->sc_dma = (struct dma_softc *)parent;
+ lesc->sc_dma->sc_le = lesc;
+ lesc->sc_laddr = laddr;
+ }
+#endif
+ }
bp = ca->ca_ra.ra_bp;
switch (ca->ca_bustype) {
@@ -231,12 +487,8 @@ leattach(parent, self, aux)
case BUS_SBUS:
lesc->sc_sd.sd_reset = (void *)am7990_reset;
if (sbuschild) {
- lesc->sc_dma = NULL;
sbus_establish(&lesc->sc_sd, &sc->sc_dev);
} else {
- lesc->sc_dma = (struct dma_softc *)parent;
- lesc->sc_dma->sc_le = lesc;
- lesc->sc_dma->sc_regs->en_bar = laddr & 0xff000000;
/* Assume SBus is grandparent */
sbus_establish(&lesc->sc_sd, parent);
}
@@ -254,16 +506,44 @@ leattach(parent, self, aux)
break;
}
+#if defined(__NetBSD__)
+ myetheraddr(sc->sc_enaddr);
+#else
+ myetheraddr(sc->sc_arpcom.ac_enaddr);
+#endif /* __NetBSD__ */
+
+ sc->sc_copytodesc = am7990_copytobuf_contig;
+ sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
+ sc->sc_copytobuf = am7990_copytobuf_contig;
+ sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
+ sc->sc_zerobuf = am7990_zerobuf_contig;
+
+ sc->sc_rdcsr = lerdcsr;
+ sc->sc_wrcsr = lewrcsr;
+ sc->sc_hwinit = lehwinit;
+ sc->sc_nocarrier = lenocarrier;
+ sc->sc_hwreset = lehwreset;
+
+#if defined(SUN4M) && defined(__NetBSD__)
+ if (CPU_ISSUN4M && lesc->sc_dma) {
+ sc->sc_mediachange = lemediachange;
+ sc->sc_mediastatus = lemediastatus;
+ sc->sc_supmedia = lemediasun4m;
+ sc->sc_nsupmedia = NLEMEDIASUN4M;
+ sc->sc_defaultmedia = IFM_ETHER|IFM_AUTO;
+ }
+#endif
+
+ am7990_config(sc);
+
lesc->sc_ih.ih_fun = am7990_intr;
#if defined(SUN4M) /*XXX*/
- if (CPU_ISSUN4M)
+ if (CPU_ISSUN4M && lesc->sc_dma)
lesc->sc_ih.ih_fun = myleintr;
#endif
lesc->sc_ih.ih_arg = sc;
intr_establish(pri, &lesc->sc_ih);
/* now initialize DMA */
- if (lesc->sc_dma) {
- DMA_ENINTR(lesc->sc_dma);
- }
+ lehwreset(sc);
}
diff --git a/sys/arch/sparc/dev/if_lereg.h b/sys/arch/sparc/dev/if_lereg.h
index 5035566a439..429ba05a831 100644
--- a/sys/arch/sparc/dev/if_lereg.h
+++ b/sys/arch/sparc/dev/if_lereg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: if_lereg.h,v 1.3 1997/08/08 08:25:13 downsj Exp $ */
/* $NetBSD: if_lereg.h,v 1.5 1995/12/10 10:15:07 mycroft Exp $ */
/*-
diff --git a/sys/arch/sparc/dev/if_levar.h b/sys/arch/sparc/dev/if_levar.h
index 934d74c932e..2c73d8405d9 100644
--- a/sys/arch/sparc/dev/if_levar.h
+++ b/sys/arch/sparc/dev/if_levar.h
@@ -1,4 +1,5 @@
-/* $NetBSD: if_levar.h,v 1.5 1996/05/07 01:27:32 thorpej Exp $ */
+/* $OpenBSD: if_levar.h,v 1.3 1997/08/08 08:25:14 downsj Exp $ */
+/* $NetBSD: if_levar.h,v 1.7 1997/04/04 20:29:23 pk Exp $ */
/*-
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
@@ -43,7 +44,7 @@
* Ethernet software status per interface.
*
* Each interface is referenced by a network interface structure,
- * arpcom.ac_if, which the routing code uses to locate the interface.
+ * ethercom.ec_if, which the routing code uses to locate the interface.
* This structure contains the output queue for the interface, its address, ...
*/
struct le_softc {
@@ -53,4 +54,5 @@ struct le_softc {
struct intrhand sc_ih; /* interrupt vectoring */
struct lereg1 *sc_r1; /* LANCE registers */
struct dma_softc *sc_dma; /* pointer to my dma */
+ u_long sc_laddr; /* LANCE DMA address */
};
diff --git a/sys/arch/sparc/dev/isp_sbus.c b/sys/arch/sparc/dev/isp_sbus.c
new file mode 100644
index 00000000000..24fcb5caec2
--- /dev/null
+++ b/sys/arch/sparc/dev/isp_sbus.c
@@ -0,0 +1,331 @@
+/* $OpenBSD: isp_sbus.c,v 1.1 1997/08/08 08:25:15 downsj Exp $ */
+/* $NetBSD: isp_sbus.c,v 1.6 1997/06/08 06:35:45 thorpej Exp $ */
+
+/*
+ * SBus specific probe and attach routines for Qlogic ISP SCSI adapters.
+ *
+ * Copyright (c) 1997 by Matthew Jacob
+ * NASA AMES Research Center
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/queue.h>
+#include <sys/device.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
+#include <machine/autoconf.h>
+#include <sparc/cpu.h>
+#include <sparc/sparc/cpuvar.h>
+#include <sparc/dev/sbusvar.h>
+
+#include <dev/ic/ispreg.h>
+#include <dev/ic/ispvar.h>
+#include <dev/microcode/isp/asm_sbus.h>
+#include <machine/param.h>
+#include <machine/vmparam.h>
+
+
+static u_int16_t isp_sbus_rd_reg __P((struct ispsoftc *, int));
+static void isp_sbus_wr_reg __P((struct ispsoftc *, int, u_int16_t));
+static int isp_sbus_mbxdma __P((struct ispsoftc *));
+static int isp_sbus_dmasetup __P((struct ispsoftc *, struct scsi_xfer *,
+ ispreq_t *, u_int8_t *, u_int8_t));
+static void isp_sbus_dmateardown __P((struct ispsoftc *, struct scsi_xfer *,
+ u_int32_t));
+
+static struct ispmdvec mdvec = {
+ isp_sbus_rd_reg,
+ isp_sbus_wr_reg,
+ isp_sbus_mbxdma,
+ isp_sbus_dmasetup,
+ isp_sbus_dmateardown,
+ NULL,
+ NULL,
+ ISP_RISC_CODE,
+ ISP_CODE_LENGTH,
+ ISP_CODE_ORG,
+ 0
+};
+
+struct isp_sbussoftc {
+ struct ispsoftc sbus_isp;
+ struct intrhand sbus_ih;
+ volatile u_char *sbus_reg;
+ int sbus_node;
+ int sbus_pri;
+ vm_offset_t sbus_kdma_allocs[RQUEST_QUEUE_LEN];
+};
+
+
+static int isp_match __P((struct device *, void *, void *));
+static void isp_sbus_attach __P((struct device *, struct device *, void *));
+struct cfattach isp_sbus_ca = {
+ sizeof (struct isp_sbussoftc), isp_match, isp_sbus_attach
+};
+
+static int
+isp_match(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
+ register struct romaux *ra = &ca->ca_ra;
+
+ if (strcmp(cf->cf_driver->cd_name, ra->ra_name) &&
+ strcmp("SUNW,isp", ra->ra_name) &&
+ strcmp("QLGC,isp", ra->ra_name)) {
+ return (0);
+ }
+ if (ca->ca_bustype == BUS_SBUS)
+ return (1);
+ ra->ra_len = NBPG;
+ return (probeget(ra->ra_vaddr, 1) != -1);
+}
+
+static void
+isp_sbus_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) self;
+
+ if (ca->ca_ra.ra_nintr != 1) {
+ printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
+ return;
+ }
+
+ sbc->sbus_pri = ca->ca_ra.ra_intr[0].int_pri;
+ printf(" pri %d\n", sbc->sbus_pri);
+
+ if (ca->ca_ra.ra_vaddr) {
+ sbc->sbus_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
+ } else {
+ sbc->sbus_reg = (volatile u_char *)
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
+ }
+ sbc->sbus_node = ca->ca_ra.ra_node;
+
+ sbc->sbus_isp.isp_mdvec = &mdvec;
+ isp_reset(&sbc->sbus_isp);
+ if (sbc->sbus_isp.isp_state != ISP_RESETSTATE) {
+ return;
+ }
+ isp_init(&sbc->sbus_isp);
+ if (sbc->sbus_isp.isp_state != ISP_INITSTATE) {
+ isp_uninit(&sbc->sbus_isp);
+ return;
+ }
+ sbc->sbus_ih.ih_fun = (void *) isp_intr;
+ sbc->sbus_ih.ih_arg = sbc;
+ intr_establish(sbc->sbus_pri, &sbc->sbus_ih);
+
+ /*
+ * Do Generic attach now.
+ */
+ isp_attach(&sbc->sbus_isp);
+ if (sbc->sbus_isp.isp_state != ISP_RUNSTATE) {
+ isp_uninit(&sbc->sbus_isp);
+ }
+}
+
+#define SBUS_BIU_REGS_OFF 0x00
+#define SBUS_MBOX_REGS_OFF 0x80
+#define SBUS_SXP_REGS_OFF 0x200
+#define SBUS_RISC_REGS_OFF 0x400
+
+static u_int16_t
+isp_sbus_rd_reg(isp, regoff)
+ struct ispsoftc *isp;
+ int regoff;
+{
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
+
+ int offset;
+ if ((regoff & BIU_BLOCK) != 0) {
+ offset = SBUS_BIU_REGS_OFF;
+ } else if ((regoff & MBOX_BLOCK) != 0) {
+ offset = SBUS_MBOX_REGS_OFF;
+ } else if ((regoff & SXP_BLOCK) != 0) {
+ offset = SBUS_SXP_REGS_OFF;
+ } else {
+ offset = SBUS_RISC_REGS_OFF;
+ }
+ regoff &= 0xff;
+ offset += regoff;
+ return (*((u_int16_t *) &sbc->sbus_reg[offset]));
+}
+
+static void
+isp_sbus_wr_reg (isp, regoff, val)
+ struct ispsoftc *isp;
+ int regoff;
+ u_int16_t val;
+{
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
+ int offset;
+
+ if ((regoff & BIU_BLOCK) != 0) {
+ offset = SBUS_BIU_REGS_OFF;
+ } else if ((regoff & MBOX_BLOCK) != 0) {
+ offset = SBUS_MBOX_REGS_OFF;
+ } else if ((regoff & SXP_BLOCK) != 0) {
+ offset = SBUS_SXP_REGS_OFF;
+ } else {
+ offset = SBUS_RISC_REGS_OFF;
+ }
+ regoff &= 0xff;
+ offset += regoff;
+ *((u_int16_t *) &sbc->sbus_reg[offset]) = val;
+}
+
+static int
+isp_sbus_mbxdma(isp)
+ struct ispsoftc *isp;
+{
+ size_t len;
+
+ /*
+ * NOTE: Since most Sun machines aren't I/O coherent,
+ * map the mailboxes through kdvma space to force them
+ * to be uncached.
+ */
+
+ /*
+ * Allocate and map the request queue.
+ */
+ len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
+ isp->isp_rquest = (volatile caddr_t)malloc(len, M_DEVBUF, M_NOWAIT);
+ if (isp->isp_rquest == 0)
+ return (1);
+ isp->isp_rquest_dma = (u_int32_t)kdvma_mapin((caddr_t)isp->isp_rquest,
+ len, 0);
+ if (isp->isp_rquest_dma == 0)
+ return (1);
+
+ /*
+ * Allocate and map the result queue.
+ */
+ len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
+ isp->isp_result = (volatile caddr_t)malloc(len, M_DEVBUF, M_NOWAIT);
+ if (isp->isp_result == 0)
+ return (1);
+ isp->isp_result_dma = (u_int32_t)kdvma_mapin((caddr_t)isp->isp_result,
+ len, 0);
+ if (isp->isp_result_dma == 0)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * TODO: If kdvma_mapin fails, try using multiple smaller chunks..
+ */
+
+static int
+isp_sbus_dmasetup(isp, xs, rq, iptrp, optr)
+ struct ispsoftc *isp;
+ struct scsi_xfer *xs;
+ ispreq_t *rq;
+ u_int8_t *iptrp;
+ u_int8_t optr;
+{
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
+ vm_offset_t kdvma;
+ int dosleep = (xs->flags & SCSI_NOSLEEP) != 0;
+
+ if (xs->datalen == 0) {
+ rq->req_seg_count = 1;
+ rq->req_flags |= REQFLAG_DATA_IN;
+ return (0);
+ }
+
+ if (rq->req_handle >= RQUEST_QUEUE_LEN) {
+ panic("%s: bad handle (%d) in isp_sbus_dmasetup\n",
+ isp->isp_name, rq->req_handle);
+ /* NOTREACHED */
+ }
+ if (CPU_ISSUN4M) {
+ kdvma = (vm_offset_t)
+ kdvma_mapin((caddr_t)xs->data, xs->datalen, dosleep);
+ if (kdvma == (vm_offset_t) 0) {
+ return (1);
+ }
+ } else {
+ kdvma = (vm_offset_t) xs->data;
+ }
+
+ if (sbc->sbus_kdma_allocs[rq->req_handle] != (vm_offset_t) 0) {
+ panic("%s: kdma handle already allocated\n", isp->isp_name);
+ /* NOTREACHED */
+ }
+ sbc->sbus_kdma_allocs[rq->req_handle] = kdvma;
+ if (xs->flags & SCSI_DATA_IN) {
+ rq->req_flags |= REQFLAG_DATA_IN;
+ } else {
+ rq->req_flags |= REQFLAG_DATA_OUT;
+ }
+ rq->req_dataseg[0].ds_count = xs->datalen;
+ rq->req_dataseg[0].ds_base = (u_int32_t) kdvma;
+ rq->req_seg_count = 1;
+ return (0);
+}
+
+static void
+isp_sbus_dmateardown(isp, xs, handle)
+ struct ispsoftc *isp;
+ struct scsi_xfer *xs;
+ u_int32_t handle;
+{
+ struct isp_sbussoftc *sbc = (struct isp_sbussoftc *) isp;
+ vm_offset_t kdvma;
+
+ if (xs->flags & SCSI_DATA_IN) {
+ cpuinfo.cache_flush(xs->data, xs->datalen - xs->resid);
+ }
+
+ if (handle >= RQUEST_QUEUE_LEN) {
+ panic("%s: bad handle (%d) in isp_sbus_dmateardown\n",
+ isp->isp_name, handle);
+ /* NOTREACHED */
+ }
+ if (sbc->sbus_kdma_allocs[handle] == (vm_offset_t) 0) {
+ panic("%s: kdma handle not already allocated\n", isp->isp_name);
+ /* NOTREACHED */
+ }
+ kdvma = sbc->sbus_kdma_allocs[handle];
+ sbc->sbus_kdma_allocs[handle] = (vm_offset_t) 0;
+ if (CPU_ISSUN4M) {
+ dvma_mapout(kdvma, (vm_offset_t) xs->data, xs->datalen);
+ }
+}
diff --git a/sys/arch/sparc/dev/kbd.c b/sys/arch/sparc/dev/kbd.c
index c4ae36b0aab..9bf291e0a43 100644
--- a/sys/arch/sparc/dev/kbd.c
+++ b/sys/arch/sparc/dev/kbd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: kbd.c,v 1.5 1996/08/11 23:34:01 downsj Exp $ */
-/* $NetBSD: kbd.c,v 1.23 1996/04/01 17:34:34 christos Exp $ */
+/* $OpenBSD: kbd.c,v 1.6 1997/08/08 08:25:16 downsj Exp $ */
+/* $NetBSD: kbd.c,v 1.27 1996/10/13 03:00:01 christos Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -66,7 +66,7 @@
#include <machine/conf.h>
#include <machine/vuid_event.h>
-#include <sparc/dev/event_var.h>
+#include <dev/sun/event_var.h>
#include <machine/kbd.h>
#include <machine/kbio.h>
@@ -326,7 +326,6 @@ kbd_reset(ks)
break;
default:
printf("Unknown keyboard type %d\n", ks->kbd_id);
- break;
}
ks->kbd_leds = 0;
@@ -720,6 +719,7 @@ kbdioctl(dev, cmd, data, flag, p)
*(char *)data = k->k_state.kbd_leds;
return (0);
+
case FIONBIO: /* we will remove this someday (soon???) */
return (0);
diff --git a/sys/arch/sparc/dev/lebuffer.c b/sys/arch/sparc/dev/lebuffer.c
new file mode 100644
index 00000000000..b97675194c6
--- /dev/null
+++ b/sys/arch/sparc/dev/lebuffer.c
@@ -0,0 +1,143 @@
+/* $OpenBSD: lebuffer.c,v 1.1 1997/08/08 08:25:16 downsj Exp $ */
+/* $NetBSD: lebuffer.c,v 1.3 1997/05/24 20:16:28 pk Exp $ */
+
+/*
+ * Copyright (c) 1996 Paul Kranenburg. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Peter Galbavy.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
+#include <sparc/autoconf.h>
+#include <sparc/cpu.h>
+
+#include <sparc/dev/sbusvar.h>
+#include <sparc/dev/lebuffervar.h>
+#include <sparc/dev/dmareg.h>/*XXX*/
+
+int lebufprint __P((void *, const char *));
+void lebufattach __P((struct device *, struct device *, void *));
+
+struct cfattach lebuffer_ca = {
+ sizeof(struct lebuf_softc), matchbyname, lebufattach
+};
+
+struct cfdriver lebuffer_cd = {
+ NULL, "lebuffer", DV_DULL
+};
+
+int
+lebufprint(aux, name)
+ void *aux;
+ const char *name;
+{
+ register struct confargs *ca = aux;
+
+ if (name)
+ printf("[%s at %s]", ca->ca_ra.ra_name, name);
+ printf(" slot 0x%x offset 0x%x", ca->ca_slot, ca->ca_offset);
+ return (UNCONF);
+}
+
+/*
+ * Attach all the sub-devices we can find
+ */
+void
+lebufattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+#if defined(SUN4C) || defined(SUN4M)
+ register struct confargs *ca = aux;
+ struct lebuf_softc *sc = (void *)self;
+ int node;
+ struct confargs oca;
+ char *name;
+ int sbusburst;
+
+ if (ca->ca_ra.ra_vaddr == NULL || ca->ca_ra.ra_nvaddrs == 0)
+ ca->ca_ra.ra_vaddr =
+ mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len);
+
+ /*
+ * This device's "register space" is just a buffer where the
+ * Lance ring-buffers can be stored. Note the buffer's location
+ * and size, so the `le' driver can pick them up.
+ */
+ sc->sc_buffer = (caddr_t)ca->ca_ra.ra_vaddr;
+ sc->sc_bufsiz = ca->ca_ra.ra_len;
+
+ /*
+ * Get transfer burst size from PROM
+ */
+ sbusburst = ((struct sbus_softc *)parent)->sc_burst;
+ if (sbusburst == 0)
+ sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
+
+ sc->sc_burst = getpropint(ca->ca_ra.ra_node, "burst-sizes", -1);
+ if (sc->sc_burst == -1)
+ /* take SBus burst sizes */
+ sc->sc_burst = sbusburst;
+
+ /* Clamp at parent's burst sizes */
+ sc->sc_burst &= sbusburst;
+
+ printf("\n");
+
+ node = sc->sc_node = ca->ca_ra.ra_node;
+
+ if (ca->ca_bustype == BUS_SBUS)
+ sbus_establish(&sc->sc_sd, &sc->sc_dev);
+
+ /* Propagate bootpath */
+ if (ca->ca_ra.ra_bp != NULL)
+ oca.ca_ra.ra_bp = ca->ca_ra.ra_bp + 1;
+ else
+ oca.ca_ra.ra_bp = NULL;
+
+ /* search through children */
+ for (node = firstchild(node); node; node = nextsibling(node)) {
+ name = getpropstring(node, "name");
+ if (!romprop(&oca.ca_ra, name, node))
+ continue;
+
+ sbus_translate(parent, &oca);
+ oca.ca_bustype = BUS_SBUS;
+ (void) config_found(&sc->sc_dev, (void *)&oca, lebufprint);
+ }
+#endif /* SUN4C || SUN4M */
+}
diff --git a/sys/arch/sparc/dev/cgfourreg.h b/sys/arch/sparc/dev/lebuffervar.h
index 9d53b73de6e..edd47c7b8e9 100644
--- a/sys/arch/sparc/dev/cgfourreg.h
+++ b/sys/arch/sparc/dev/lebuffervar.h
@@ -1,9 +1,8 @@
-/* $NetBSD: cgfourreg.h,v 1.4 1994/11/20 20:52:03 deraadt Exp $ */
+/* $OpenBSD: lebuffervar.h,v 1.1 1997/08/08 08:25:18 downsj Exp $ */
+/* $NetBSD: lebuffervar.h,v 1.2 1997/03/10 22:56:54 pk Exp $ */
/*
- * Copyright (c) 1995 Theo de Raadt
- * All rights reserved.
- *
+ * Copyright (c) 1996 Paul Kranenburg. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,7 +13,7 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by Theo de Raadt.
+ * This product includes software developed by Paul Kranenburg.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
@@ -30,25 +29,13 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * cgfour display registers. Much like bwtwo registers, except that
- * there is a Brooktree Video DAC in there (so we also use btreg.h).
- */
-
-/* offsets */
-#define CG4REG_CMAP 0x200000
-#define CG4REG_OVERLAY 0x400000
-#define CG4REG_ENABLE 0x600000
-#define CG4REG_COLOUR 0x800000
-#define CG4REG_END 0xa00000
-
-/* same, but for gdb */
-struct cgfour_all {
- char ba_nothing[0x200000];
- struct bt_regs ba_btreg; /* Brooktree registers */
- char ba_xxx1[0x100000-sizeof(struct bt_regs)];
- char ba_pfourreg[0x100000];
- char ba_overlay[0x200000];
- char ba_enable[0x200000];
- char ba_color[0x200000];
+struct lebuf_softc {
+ struct device sc_dev; /* us as a device */
+ struct sbusdev sc_sd; /* sbus device */
+ u_int sc_rev; /* revision */
+ int sc_node; /* PROM node ID */
+ int sc_burst; /* DVMA burst size in effect */
+ caddr_t sc_buffer; /* VA of the buffer we provide */
+ int sc_bufsiz; /* Size of buffer */
+ int attached; /* 1: in use by `le' device */
};
diff --git a/sys/arch/sparc/dev/ms.c b/sys/arch/sparc/dev/ms.c
index 4bf14f2c9b2..1049fb12e45 100644
--- a/sys/arch/sparc/dev/ms.c
+++ b/sys/arch/sparc/dev/ms.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ms.c,v 1.5 1996/08/11 23:28:12 downsj Exp $ */
-/* $NetBSD: ms.c,v 1.8 1996/04/01 17:29:52 christos Exp $ */
+/* $OpenBSD: ms.c,v 1.6 1997/08/08 08:25:19 downsj Exp $ */
+/* $NetBSD: ms.c,v 1.10 1996/09/12 01:36:18 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -64,7 +64,7 @@
#include <machine/kbd.h>
#include <machine/conf.h>
-#include <sparc/dev/event_var.h>
+#include <dev/sun/event_var.h>
/*
* Mouse state. A Mouse Systems mouse is a fairly simple device,
@@ -255,6 +255,12 @@ msopen(dev, flags, mode, p)
ms_softc.ms_events.ev_io = p;
ev_init(&ms_softc.ms_events); /* may cause sleep */
+ if (CPU_ISSUN4) {
+ /* We need to set the baud rate on the mouse. */
+ ms_softc.ms_mouse->t_ispeed =
+ ms_softc.ms_mouse->t_ospeed = 1200;
+ }
+
(*ms_softc.ms_open)(ms_softc.ms_mouse);
ms_softc.ms_ready = 1; /* start accepting events */
return (0);
diff --git a/sys/arch/sparc/dev/obio.c b/sys/arch/sparc/dev/obio.c
index 2787aa91c01..845d97dddd3 100644
--- a/sys/arch/sparc/dev/obio.c
+++ b/sys/arch/sparc/dev/obio.c
@@ -1,8 +1,9 @@
-/* $NetBSD: obio.c,v 1.24 1996/05/18 12:22:49 mrg Exp $ */
+/* $OpenBSD: obio.c,v 1.7 1997/08/08 08:25:20 downsj Exp $ */
+/* $NetBSD: obio.c,v 1.37 1997/07/29 09:58:11 fair Exp $ */
/*
* Copyright (c) 1993, 1994 Theo de Raadt
- * Copyright (c) 1995 Paul Kranenburg
+ * Copyright (c) 1995, 1997 Paul Kranenburg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,28 +51,42 @@
#include <machine/ctlreg.h>
#include <sparc/sparc/asm.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
#include <sparc/dev/sbusvar.h>
+#include <sparc/dev/vmereg.h>
+
+struct vmebus_softc {
+ struct device sc_dev; /* base device */
+ struct vmebusreg *sc_reg; /* VME control registers */
+ struct vmebusvec *sc_vec; /* VME interrupt vector */
+ struct rom_range *sc_range; /* ROM range property */
+ int sc_nrange;
+};
+struct vmebus_softc *vmebus_sc;/*XXX*/
struct bus_softc {
union {
struct device scu_dev; /* base device */
struct sbus_softc scu_sbus; /* obio is another sbus slot */
+ struct vmebus_softc scu_vme;
} bu;
-#define sc_dev bu.scu_dev
};
+
/* autoconfiguration driver */
static int busmatch __P((struct device *, void *, void *));
static void obioattach __P((struct device *, struct device *, void *));
static void vmesattach __P((struct device *, struct device *, void *));
static void vmelattach __P((struct device *, struct device *, void *));
+static void vmeattach __P((struct device *, struct device *, void *));
int busprint __P((void *, const char *));
+int vmeprint __P((void *, const char *));
static int busattach __P((struct device *, void *, void *, int));
-void * bus_map __P((struct rom_reg *, int, int));
int obio_scan __P((struct device *, void *, void *));
int vmes_scan __P((struct device *, void *, void *));
int vmel_scan __P((struct device *, void *, void *));
+void vmebus_translate __P((struct device *, struct confargs *, int));
int vmeintr __P((void *));
struct cfattach obio_ca = {
@@ -98,6 +113,14 @@ struct cfdriver vmes_cd = {
NULL, "vmes", DV_DULL
};
+struct cfattach vme_ca = {
+ sizeof(struct bus_softc), busmatch, vmeattach
+};
+
+struct cfdriver vme_cd = {
+ NULL, "vme", DV_DULL
+};
+
struct intrhand **vmeints;
@@ -106,7 +129,7 @@ busmatch(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -140,6 +163,17 @@ busprint(args, obio)
return (UNCONF);
}
+int
+vmeprint(args, name)
+ void *args;
+ const char *name;
+{
+ register struct confargs *ca = args;
+
+ if (name)
+ printf("%s at %s", ca->ca_ra.ra_name, name);
+ return (UNCONF);
+}
void
obioattach(parent, self, args)
@@ -154,13 +188,16 @@ obioattach(parent, self, args)
register char *name;
register const char *sp;
const char *const *ssp;
+ int rlen;
extern int autoconf_nzs;
static const char *const special4m[] = {
/* find these first */
"eeprom",
"counter",
+#if 0 /* Not all sun4m's have an `auxio' */
"auxio",
+#endif
"",
/* place device to ignore here */
"interrupt",
@@ -187,7 +224,7 @@ obioattach(parent, self, args)
* There is only one obio bus (it is in fact one of the Sbus slots)
* How about VME?
*/
- if (sc->sc_dev.dv_unit > 0) {
+ if (self->dv_unit > 0) {
printf(" unsupported\n");
return;
}
@@ -199,8 +236,16 @@ obioattach(parent, self, args)
else
oca.ca_ra.ra_bp = NULL;
- sc->bu.scu_sbus.sc_range = ra->ra_range;
- sc->bu.scu_sbus.sc_nrange = ra->ra_nrange;
+ node = ra->ra_node;
+ rlen = getproplen(node, "ranges");
+ if (rlen > 0) {
+ sc->bu.scu_sbus.sc_nrange = rlen / sizeof(struct rom_range);
+ sc->bu.scu_sbus.sc_range =
+ (struct rom_range *)malloc(rlen, M_DEVBUF, M_NOWAIT);
+ if (sc->bu.scu_sbus.sc_range == 0)
+ panic("obio: PROM ranges too large: %d", rlen);
+ (void)getprop(node, "ranges", sc->bu.scu_sbus.sc_range, rlen);
+ }
/*
* Loop through ROM children, fixing any relative addresses
@@ -218,7 +263,7 @@ obioattach(parent, self, args)
sbus_translate(self, &oca);
oca.ca_bustype = BUS_OBIO;
- (void) config_found(&sc->sc_dev, (void *)&oca, busprint);
+ (void) config_found(self, (void *)&oca, busprint);
}
for (node = node0; node; node = nextsibling(node)) {
@@ -237,7 +282,7 @@ obioattach(parent, self, args)
/* Translate into parent address spaces */
sbus_translate(self, &oca);
oca.ca_bustype = BUS_OBIO;
- (void) config_found(&sc->sc_dev, (void *)&oca, busprint);
+ (void) config_found(self, (void *)&oca, busprint);
}
#endif
}
@@ -247,7 +292,8 @@ vmesattach(parent, self, args)
struct device *parent, *self;
void *args;
{
- if (CPU_ISSUN4M || self->dv_unit > 0) {
+ if (self->dv_unit > 0 ||
+ (CPU_ISSUN4M && strncmp(parent->dv_xname, "vme", 3) != 0)) {
printf(" unsupported\n");
return;
}
@@ -267,7 +313,8 @@ vmelattach(parent, self, args)
struct device *parent, *self;
void *args;
{
- if (CPU_ISSUN4M || self->dv_unit > 0) {
+ if (self->dv_unit > 0 ||
+ (CPU_ISSUN4M && strncmp(parent->dv_xname, "vme", 3) != 0)) {
printf(" unsupported\n");
return;
}
@@ -282,14 +329,116 @@ vmelattach(parent, self, args)
bus_untmp();
}
+void
+vmeattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct vmebus_softc *sc = (struct vmebus_softc *)self;
+ struct confargs *ca = aux;
+ register struct romaux *ra = &ca->ca_ra;
+ int node, rlen;
+ struct confargs oca;
+
+ if (!CPU_ISSUN4M || self->dv_unit > 0) {
+ printf(" unsupported\n");
+ return;
+ }
+
+ node = ra->ra_node;
+
+ sc->sc_reg = (struct vmebusreg *)
+ mapdev(&ra->ra_reg[0], 0, 0, ra->ra_reg[0].rr_len);
+ sc->sc_vec = (struct vmebusvec *)
+ mapdev(&ra->ra_reg[1], 0, 0, ra->ra_reg[1].rr_len);
+
+ /*
+ * Get "range" property, though we don't do anything with it yet.
+ */
+ rlen = getproplen(node, "ranges");
+ if (rlen > 0) {
+ sc->sc_nrange = rlen / sizeof(struct rom_range);
+ sc->sc_range =
+ (struct rom_range *)malloc(rlen, M_DEVBUF, M_NOWAIT);
+ if (sc->sc_range == 0)
+ panic("vme: PROM ranges too large: %d", rlen);
+ (void)getprop(node, "ranges", sc->sc_range, rlen);
+ }
+
+ vmebus_sc = sc;
+ printf(": version 0x%x\n",
+ sc->sc_reg->vmebus_cr & VMEBUS_CR_IMPL);
+
+ if (ra->ra_bp != NULL && strcmp(ra->ra_bp->name, "vme") == 0)
+ oca.ca_ra.ra_bp = ra->ra_bp + 1;
+ else
+ oca.ca_ra.ra_bp = NULL;
+
+ oca.ca_ra.ra_name = "vmes";
+ oca.ca_bustype = BUS_MAIN;
+ (void)config_found(self, (void *)&oca, vmeprint);
+
+ oca.ca_ra.ra_name = "vmel";
+ oca.ca_bustype = BUS_MAIN;
+ (void)config_found(self, (void *)&oca, vmeprint);
+}
+
+void
+vmebus_translate(dev, ca, bustype)
+ struct device *dev;
+ struct confargs *ca;
+ int bustype;
+{
+ struct vmebus_softc *sc = (struct vmebus_softc *)dev;
+ register int j;
+ int cspace;
+
+ if (sc->sc_nrange == 0)
+ panic("vmebus: no ranges");
+
+ /*
+ * Find VMEbus modifier based on address space.
+ * XXX - should not be encoded in `ra_paddr'
+ */
+ if (((u_long)ca->ca_ra.ra_paddr & 0xffff0000) == 0xffff0000)
+ cspace = VMEMOD_A16_D_S;
+ else if (((u_long)ca->ca_ra.ra_paddr & 0xff000000) == 0xff000000)
+ cspace = VMEMOD_A24_D_S;
+ else
+ cspace = VMEMOD_A32_D_S;
+
+ cspace |= (bustype == BUS_VME32) ? VMEMOD_D32 : 0;
+
+ /* Translate into parent address spaces */
+ for (j = 0; j < sc->sc_nrange; j++) {
+ if (sc->sc_range[j].cspace == cspace) {
+#if notyet
+ (int)ca->ca_ra.ra_paddr +=
+ sc->sc_range[j].poffset;
+#endif
+ (int)ca->ca_ra.ra_iospace =
+ sc->sc_range[j].pspace;
+ break;
+ }
+ }
+}
+
+int bt2pmt[] = {
+ PMAP_OBIO,
+ PMAP_OBIO,
+ PMAP_VME16,
+ PMAP_VME32,
+ PMAP_OBIO
+};
+
int
-busattach(parent, child, args, bustype)
+busattach(parent, vcf, args, bustype)
struct device *parent;
- void *args, *child;
+ void *vcf, *args;
int bustype;
{
-#if defined(SUN4)
- struct cfdata *cf = child;
+#if defined(SUN4) || defined(SUN4M)
+ register struct cfdata *cf = vcf;
register struct confargs *ca = args;
struct confargs oca;
caddr_t tmp;
@@ -309,24 +458,24 @@ busattach(parent, child, args, bustype)
* XXX: We also assume that 4/[23]00 obio addresses
* must be 0xZYYYYYYY, where (Z != 0)
*/
- if (cpumod == SUN4_100 && (cf->cf_loc[0] & 0xf0000000))
+ if (cpuinfo.cpu_type == CPUTYP_4_100 &&
+ (cf->cf_loc[0] & 0xf0000000))
return 0;
- if (cpumod != SUN4_100 && !(cf->cf_loc[0] & 0xf0000000))
+ if (cpuinfo.cpu_type != CPUTYP_4_100 &&
+ !(cf->cf_loc[0] & 0xf0000000))
return 0;
}
- if (parent->dv_cfdata->cf_driver->cd_indirect) {
- printf(" indirect devices not supported\n");
- return 0;
- }
-
- oca.ca_ra.ra_iospace = -1;
oca.ca_ra.ra_paddr = (void *)cf->cf_loc[0];
oca.ca_ra.ra_len = 0;
oca.ca_ra.ra_nreg = 1;
+ if (CPU_ISSUN4M)
+ vmebus_translate(parent->dv_parent, &oca, bustype);
+ else
+ oca.ca_ra.ra_iospace = bt2pmt[bustype];
+
if (oca.ca_ra.ra_paddr)
- tmp = (caddr_t)bus_tmp(oca.ca_ra.ra_paddr,
- bustype);
+ tmp = (caddr_t)mapdev(oca.ca_ra.ra_reg, TMPMAP_VA, 0, NBPG);
else
tmp = NULL;
oca.ca_ra.ra_vaddr = tmp;
@@ -364,8 +513,7 @@ busattach(parent, child, args, bustype)
*/
if (oca.ca_ra.ra_len)
oca.ca_ra.ra_vaddr =
- bus_map(oca.ca_ra.ra_reg,
- oca.ca_ra.ra_len, oca.ca_bustype);
+ bus_map(oca.ca_ra.ra_reg, oca.ca_ra.ra_len);
config_attach(parent, cf, &oca, busprint);
return 1;
@@ -421,18 +569,19 @@ int
vmeintr(arg)
void *arg;
{
- int level = (int)arg, vec;
+ int pil = (int)arg, level, vec;
struct intrhand *ih;
int i = 0;
-#ifdef DIAGNOSTIC
- if (!CPU_ISSUN4) {
+ level = (pil_to_vme[pil] << 1) | 1;
+
+ if (CPU_ISSUN4) {
+ vec = ldcontrolb((caddr_t)(AC_VMEINTVEC | level));
+ } else if (CPU_ISSUN4M) {
+ vec = vmebus_sc->sc_vec->vmebusvec[level];
+ } else
panic("vme: spurious interrupt");
- }
-#endif
- vec = ldcontrolb((caddr_t)
- (AC_VMEINTVEC | (pil_to_vme[level] << 1) | 1));
if (vec == -1) {
printf("vme: spurious interrupt\n");
return 0;
@@ -451,13 +600,11 @@ vmeintr_establish(vec, level, ih)
{
struct intrhand *ihs;
- if (!CPU_ISSUN4) {
- panic("vmeintr_establish: not supported on cpu-type %d",
- cputyp);
- }
+ if (vmeints == NULL)
+ panic("vmeintr_establish: interrupt vector not allocated");
if (vec == -1)
- panic("vmeintr_establish: uninitialized vec\n");
+ panic("vmeintr_establish: uninitialized vec");
if (vmeints[vec] == NULL)
vmeints[vec] = ih;
@@ -489,28 +636,16 @@ vmeintr_establish(vec, level, ih)
* Else, create a new mapping.
*/
void *
-bus_map(pa, len, bustype)
+bus_map(pa, len)
struct rom_reg *pa;
int len;
- int bustype;
{
- u_long pf = (u_long)(pa->rr_paddr) >> PGSHIFT;
- u_long va, pte;
- int pgtype = -1;
-
- switch (bt2pmt[bustype]) {
- case PMAP_OBIO:
- pgtype = PG_OBIO;
- break;
- case PMAP_VME32:
- pgtype = PG_VME32;
- break;
- case PMAP_VME16:
- pgtype = PG_VME16;
- break;
- }
- if (len <= NBPG) {
+ if (CPU_ISSUN4 && len <= NBPG) {
+ u_long pf = (u_long)(pa->rr_paddr) >> PGSHIFT;
+ int pgtype = PMAP_T2PTE_4(pa->rr_iospace);
+ u_long va, pte;
+
for (va = OLDMON_STARTVADDR; va < OLDMON_ENDVADDR; va += NBPG) {
pte = getpte(va);
if ((pte & PG_V) != 0 && (pte & PG_TYPE) == pgtype &&
@@ -520,21 +655,8 @@ bus_map(pa, len, bustype)
/* note: preserve page offset */
}
}
- return mapiodev(pa, 0, len, bustype);
-}
-
-void *
-bus_tmp(pa, bustype)
- void *pa;
- int bustype;
-{
- vm_offset_t addr = (vm_offset_t)pa & ~PGOFSET;
- int pmtype = bt2pmt[bustype];
- pmap_enter(pmap_kernel(), TMPMAP_VA,
- addr | pmtype | PMAP_NC,
- VM_PROT_READ | VM_PROT_WRITE, 1);
- return ((void *)(TMPMAP_VA | ((u_long) pa & PGOFSET)) );
+ return mapiodev(pa, 0, len);
}
void
diff --git a/sys/arch/sparc/dev/pfour.c b/sys/arch/sparc/dev/pfour.c
index 3ed22d7df5c..c903754515a 100644
--- a/sys/arch/sparc/dev/pfour.c
+++ b/sys/arch/sparc/dev/pfour.c
@@ -1,4 +1,4 @@
-/* $Id: pfour.c,v 1.5 1995/12/15 13:56:26 deraadt Exp $ */
+/* $OpenBSD: pfour.c,v 1.6 1997/08/08 08:25:20 downsj Exp $ */
/*
* Copyright (c) 1995 Theo de Raadt
diff --git a/sys/arch/sparc/dev/pfourreg.h b/sys/arch/sparc/dev/pfourreg.h
index 8ec422c2019..a0ef7094c05 100644
--- a/sys/arch/sparc/dev/pfourreg.h
+++ b/sys/arch/sparc/dev/pfourreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: pfourreg.h,v 1.4 1997/08/08 08:25:21 downsj Exp $ */
/* $NetBSD: pfourreg.h,v 1.1 1996/02/27 22:09:36 thorpej Exp $ */
/*
diff --git a/sys/arch/sparc/dev/power.c b/sys/arch/sparc/dev/power.c
index d083500333f..0255c25c059 100644
--- a/sys/arch/sparc/dev/power.c
+++ b/sys/arch/sparc/dev/power.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: power.c,v 1.3 1997/06/22 22:45:34 downsj Exp $ */
+/* $OpenBSD: power.c,v 1.4 1997/08/08 08:25:22 downsj Exp $ */
/* $NetBSD: power.c,v 1.2 1996/05/16 15:56:56 abrown Exp $ */
/*
@@ -91,7 +91,7 @@ powerattach(parent, self, aux)
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
- power_reg = mapdev(ra->ra_reg, 0, 0, sizeof(long), ca->ca_bustype);
+ power_reg = mapdev(ra->ra_reg, 0, 0, sizeof(long));
power_attached = 1;
diff --git a/sys/arch/sparc/dev/rcons_font.h b/sys/arch/sparc/dev/rcons_font.h
index 3cbc847ea53..292ce909ba0 100644
--- a/sys/arch/sparc/dev/rcons_font.h
+++ b/sys/arch/sparc/dev/rcons_font.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: rcons_font.h,v 1.4 1997/08/08 08:25:25 downsj Exp $ */
/* $NetBSD: rcons_font.h,v 1.3 1995/11/29 22:03:53 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/sbus.c b/sys/arch/sparc/dev/sbus.c
index 0f7ceff3bbf..aee7de7fbf8 100644
--- a/sys/arch/sparc/dev/sbus.c
+++ b/sys/arch/sparc/dev/sbus.c
@@ -1,4 +1,5 @@
-/* $NetBSD: sbus.c,v 1.10 1996/04/22 02:35:03 abrown Exp $ */
+/* $OpenBSD: sbus.c,v 1.5 1997/08/08 08:25:27 downsj Exp $ */
+/* $NetBSD: sbus.c,v 1.17 1997/06/01 22:10:39 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -49,8 +50,10 @@
*/
#include <sys/param.h>
+#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <vm/vm.h>
#include <machine/autoconf.h>
@@ -96,7 +99,7 @@ sbus_match(parent, vcf, aux)
struct device *parent;
void *vcf, *aux;
{
- struct cfdata *cf = vcf;
+ register struct cfdata *cf = vcf;
register struct confargs *ca = aux;
register struct romaux *ra = &ca->ca_ra;
@@ -121,6 +124,7 @@ sbus_attach(parent, self, aux)
register int node;
register char *name;
struct confargs oca;
+ int rlen;
/*
* XXX there is only one Sbus, for now -- do not know how to
@@ -149,8 +153,15 @@ sbus_attach(parent, self, aux)
else
oca.ca_ra.ra_bp = NULL;
- sc->sc_range = ra->ra_range;
- sc->sc_nrange = ra->ra_nrange;
+ rlen = getproplen(node, "ranges");
+ if (rlen > 0) {
+ sc->sc_nrange = rlen / sizeof(struct rom_range);
+ sc->sc_range =
+ (struct rom_range *)malloc(rlen, M_DEVBUF, M_NOWAIT);
+ if (sc->sc_range == 0)
+ panic("sbus: PROM ranges too large: %d", rlen);
+ (void)getprop(node, "ranges", sc->sc_range, rlen);
+ }
/*
* Loop through ROM children, fixing any relative addresses
@@ -183,15 +194,19 @@ sbus_translate(dev, ca)
ca->ca_slot = SBUS_ABS_TO_SLOT(base);
ca->ca_offset = SBUS_ABS_TO_OFFSET(base);
} else {
+ if (!CPU_ISSUN4C)
+ panic("relative sbus addressing not supported");
ca->ca_slot = slot = ca->ca_ra.ra_iospace;
ca->ca_offset = base;
- ca->ca_ra.ra_paddr =
- (void *)SBUS_ADDR(slot, base);
+ ca->ca_ra.ra_paddr = (void *)SBUS_ADDR(slot, base);
+ ca->ca_ra.ra_iospace = PMAP_OBIO;
+
/* Fix any remaining register banks */
for (i = 1; i < ca->ca_ra.ra_nreg; i++) {
base = (int)ca->ca_ra.ra_reg[i].rr_paddr;
ca->ca_ra.ra_reg[i].rr_paddr =
(void *)SBUS_ADDR(slot, base);
+ ca->ca_ra.ra_reg[i].rr_iospace = PMAP_OBIO;
}
}
@@ -237,12 +252,13 @@ sbus_establish(sd, dev)
*/
for (curdev = dev->dv_parent; ; curdev = curdev->dv_parent) {
if (!curdev || !curdev->dv_xname)
- panic("sbus_establish: can't find sbus parent for %s",
- (sd->sd_dev->dv_xname ? sd->sd_dev->dv_xname :
- "<unknown>"));
+ panic("sbus_establish: can't find sbus parent for %s",
+ sd->sd_dev->dv_xname
+ ? sd->sd_dev->dv_xname
+ : "<unknown>" );
if (strncmp(curdev->dv_xname, "sbus", 4) == 0)
- break;
+ break;
}
sc = (struct sbus_softc *) curdev;
diff --git a/sys/arch/sparc/dev/sbusreg.h b/sys/arch/sparc/dev/sbusreg.h
index 74c0b270292..3455f5eb366 100644
--- a/sys/arch/sparc/dev/sbusreg.h
+++ b/sys/arch/sparc/dev/sbusreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: sbusreg.h,v 1.2 1997/08/08 08:25:27 downsj Exp $ */
/* $NetBSD: sbusreg.h,v 1.2 1994/11/20 20:52:26 deraadt Exp $ */
/*
diff --git a/sys/arch/sparc/dev/sbusvar.h b/sys/arch/sparc/dev/sbusvar.h
index 72fa1025523..21fd61967c2 100644
--- a/sys/arch/sparc/dev/sbusvar.h
+++ b/sys/arch/sparc/dev/sbusvar.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: sbusvar.h,v 1.4 1997/08/08 08:25:28 downsj Exp $ */
/* $NetBSD: sbusvar.h,v 1.4 1996/04/22 02:35:05 abrown Exp $ */
/*
diff --git a/sys/arch/sparc/dev/si.c b/sys/arch/sparc/dev/si.c
index 5aa1f4f4946..a96caafb133 100644
--- a/sys/arch/sparc/dev/si.c
+++ b/sys/arch/sparc/dev/si.c
@@ -1,11 +1,13 @@
-/* $NetBSD: si.c,v 1.24 1996/05/13 01:53:45 thorpej Exp $ */
+/* $OpenBSD: si.c,v 1.10 1997/08/08 08:25:29 downsj Exp $ */
+/* $NetBSD: si.c,v 1.37 1997/07/29 09:58:13 fair Exp $ */
-/*
- * Copyright (c) 1995 Jason R. Thorpe
- * Copyright (c) 1995 David Jones, Gordon W. Ross
- * Copyright (c) 1994 Adam Glass
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
* All rights reserved.
*
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Adam Glass, David Jones, Gordon W. Ross, and Jason R. Thorpe.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,23 +16,25 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. The name of the authors may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- * 4. All advertising materials mentioning features or use of this software
+ * 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by
- * Adam Glass, David Jones, Gordon Ross, and Jason R. Thorpe
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
*/
/*
@@ -108,6 +112,7 @@
#include <machine/pmap.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
#ifndef DDB
#define Debugger()
@@ -190,7 +195,7 @@ struct si_softc {
#define SI_DO_RESELECT 0x04 /* Allow disconnect/reselect */
#define SI_OPTIONS_MASK (SI_ENABLE_DMA|SI_DMA_INTR|SI_DO_RESELECT)
#define SI_OPTIONS_BITS "\10\3RESELECT\2DMA_INTR\1DMA"
-int si_options = 0; /* XXX SI_ENABLE_DMA when dma works */
+int si_options = SI_ENABLE_DMA;
int sw_options = SI_ENABLE_DMA;
/* How long to wait for DMA before declaring an error. */
@@ -201,7 +206,6 @@ static void si_attach __P((struct device *, struct device *, void *));
static int si_intr __P((void *));
static void si_reset_adapter __P((struct ncr5380_softc *));
static void si_minphys __P((struct buf *));
-static int si_print __P((void *, const char *));
void si_dma_alloc __P((struct ncr5380_softc *));
void si_dma_free __P((struct ncr5380_softc *));
@@ -259,22 +263,12 @@ struct cfdriver sw_cd = {
};
static int
-si_print(aux, name)
- void *aux;
- const char *name;
-{
- if (name != NULL)
- printf("%s: scsibus ", name);
- return UNCONF;
-}
-
-static int
-si_match(parent, vcf, args)
+si_match(parent, vcf, aux)
struct device *parent;
- void *vcf, *args;
+ void *vcf, *aux;
{
- struct cfdata *cf = vcf;
- struct confargs *ca = args;
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
/* Are we looking for the right thing? */
@@ -296,13 +290,15 @@ si_match(parent, vcf, args)
switch (ca->ca_bustype) {
case BUS_VME16:
/* AFAIK, the `si' can only exist on the vmes. */
- if (strcmp(ra->ra_name, "si") || cpumod == SUN4_100)
+ if (strcmp(ra->ra_name, "si") ||
+ cpuinfo.cpu_type == CPUTYP_4_100)
return (0);
break;
case BUS_OBIO:
/* AFAIK, an `sw' can only exist on the obio. */
- if (strcmp(ra->ra_name, "sw") || cpumod != SUN4_100)
+ if (strcmp(ra->ra_name, "sw") ||
+ cpuinfo.cpu_type != CPUTYP_4_100)
return (0);
break;
@@ -341,17 +337,20 @@ si_attach(parent, self, args)
struct bootpath *bp;
int i;
- /* Pull in the options flags. */
- if (ca->ca_bustype == BUS_OBIO)
- sc->sc_options = sw_options;
+ /*
+ * Pull in the options flags. Allow the user to completely
+ * override the default values.
+ */
+ if ((ncr_sc->sc_dev.dv_cfdata->cf_flags & SI_OPTIONS_MASK) != 0)
+ sc->sc_options =
+ (ncr_sc->sc_dev.dv_cfdata->cf_flags & SI_OPTIONS_MASK);
else
- sc->sc_options = si_options;
- sc->sc_options |=
- (ncr_sc->sc_dev.dv_cfdata->cf_flags & SI_OPTIONS_MASK);
+ sc->sc_options =
+ (ca->ca_bustype == BUS_OBIO) ? sw_options : si_options;
/* Map the controller registers. */
- regs = (struct si_regs *)mapiodev(ra->ra_reg, 0,
- sizeof(struct si_regs), ca->ca_bustype);
+ regs = (struct si_regs *)
+ mapiodev(ra->ra_reg, 0, sizeof(struct si_regs));
/*
* Fill in the prototype scsi_link.
@@ -413,7 +412,7 @@ si_attach(parent, self, args)
}
ncr_sc->sc_flags = 0;
- if (sc->sc_options & SI_DO_RESELECT)
+ if ((sc->sc_options & SI_DO_RESELECT) == 0)
ncr_sc->sc_flags |= NCR5380_PERMIT_RESELECT;
if ((sc->sc_options & SI_DMA_INTR) == 0)
ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
@@ -494,7 +493,7 @@ si_attach(parent, self, args)
bootpath_store(1, bp + 1);
/* Configure sub-devices */
- config_found(self, &(ncr_sc->sc_link), si_print);
+ config_found(self, &(ncr_sc->sc_link), scsiprint);
bootpath_store(1, NULL);
}
@@ -505,7 +504,7 @@ si_minphys(struct buf *bp)
if (bp->b_bcount > MAX_DMA_LEN) {
#ifdef DEBUG
if (si_debug) {
- printf("si_minphys len = %x.\n", MAX_DMA_LEN);
+ printf("si_minphys len = 0x%x.\n", MAX_DMA_LEN);
Debugger();
}
#endif
@@ -658,21 +657,6 @@ si_dma_alloc(ncr_sc)
if (xlen < MIN_DMA_LEN)
panic("si_dma_alloc: xlen=0x%x\n", xlen);
- /*
- * XXX SUN4 doesn't have this limitation?
- * Never attempt single transfers of more than 63k, because
- * our count register may be only 16 bits (an OBIO adapter).
- * This should never happen since already bounded by minphys().
- * XXX - Should just segment these...
- */
- if (xlen > MAX_DMA_LEN) {
- printf("si_dma_alloc: excessive xlen=0x%x\n", xlen);
-#ifdef DEBUG
- Debugger();
-#endif
- ncr_sc->sc_datalen = xlen = MAX_DMA_LEN;
- }
-
/* Find free DMA handle. Guaranteed to find one since we have
as many DMA handles as the driver has processes. */
for (i = 0; i < SCI_OPENINGS; i++) {
@@ -701,7 +685,7 @@ found:
dh->dh_dvma = (long)kdvma_mapin((caddr_t)addr, xlen, 0);
if (dh->dh_dvma == 0) {
/* Can't remap segment */
- printf("si_dma_alloc: can't remap %p/%x, doing PIO\n",
+ printf("si_dma_alloc: can't remap %p/0x%x, doing PIO\n",
dh->dh_addr, dh->dh_maplen);
dh->dh_flags = 0;
return;
diff --git a/sys/arch/sparc/dev/sireg.h b/sys/arch/sparc/dev/sireg.h
index 8f2ab6e40e3..d17fc344b74 100644
--- a/sys/arch/sparc/dev/sireg.h
+++ b/sys/arch/sparc/dev/sireg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: sireg.h,v 1.3 1997/08/08 08:25:30 downsj Exp $ */
/* $NetBSD: sireg.h,v 1.3 1996/01/01 22:40:58 thorpej Exp $ */
/*
diff --git a/sys/arch/sparc/dev/tcx.c b/sys/arch/sparc/dev/tcx.c
new file mode 100644
index 00000000000..608fb4e64c0
--- /dev/null
+++ b/sys/arch/sparc/dev/tcx.c
@@ -0,0 +1,496 @@
+/* $OpenBSD: tcx.c,v 1.1 1997/08/08 08:25:31 downsj Exp $ */
+/* $NetBSD: tcx.c,v 1.8 1997/07/29 09:58:14 fair Exp $ */
+
+/*
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * color display (TCX) driver.
+ *
+ * Does not handle interrupts, even though they can occur.
+ *
+ * XXX should defer colormap updates to vertical retrace interrupts
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <machine/fbio.h>
+#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/tty.h>
+#include <sys/conf.h>
+
+#ifdef DEBUG
+#include <sys/proc.h>
+#include <sys/syslog.h>
+#endif
+
+#include <vm/vm.h>
+
+#include <machine/autoconf.h>
+#include <machine/pmap.h>
+#include <machine/fbvar.h>
+#include <machine/cpu.h>
+#include <machine/conf.h>
+
+#include <sparc/dev/btreg.h>
+#include <sparc/dev/btvar.h>
+#include <sparc/dev/tcxreg.h>
+#include <sparc/dev/sbusvar.h>
+
+#if 0
+union cursor_cmap { /* colormap, like bt_cmap, but tiny */
+ u_char cm_map[2][3]; /* 2 R/G/B entries */
+ u_int cm_chip[2]; /* 2 chip equivalents */
+};
+
+struct tcx_cursor { /* tcx hardware cursor status */
+ short cc_enable; /* cursor is enabled */
+ struct fbcurpos cc_pos; /* position */
+ struct fbcurpos cc_hot; /* hot-spot */
+ struct fbcurpos cc_size; /* size of mask & image fields */
+ u_int cc_bits[2][32]; /* space for mask & image bits */
+ union cursor_cmap cc_color; /* cursor colormap */
+};
+#endif
+
+/* per-display variables */
+struct tcx_softc {
+ struct device sc_dev; /* base device */
+ struct sbusdev sc_sd; /* sbus device */
+ struct fbdevice sc_fb; /* frame buffer device */
+ struct rom_reg sc_physadr[TCX_NREG]; /* phys addr of h/w */
+ int sc_bustype; /* type of bus we live on */
+ volatile struct bt_regs *sc_bt; /* Brooktree registers */
+ volatile struct tcx_thc *sc_thc; /* THC registers */
+ short sc_blanked; /* true if blanked */
+ union bt_cmap sc_cmap; /* Brooktree color map */
+};
+
+/* autoconfiguration driver */
+static void tcxattach __P((struct device *, struct device *, void *));
+static int tcxmatch __P((struct device *, void *, void *));
+static void tcx_unblank __P((struct device *));
+
+/* cdevsw prototypes */
+cdev_decl(tcx);
+
+struct cfattach tcx_ca = {
+ sizeof(struct tcx_softc), tcxmatch, tcxattach
+};
+
+struct cfdriver tcx_cd = {
+ NULL, "tcx", DV_DULL
+};
+
+/* frame buffer generic driver */
+static struct fbdriver tcx_fbdriver = {
+ tcx_unblank, tcxopen, tcxclose, tcxioctl, tcxmmap
+};
+
+extern int fbnode;
+
+static void tcx_reset __P((struct tcx_softc *));
+static void tcx_loadcmap __P((struct tcx_softc *, int, int));
+
+#define OBPNAME "SUNW,tcx"
+/*
+ * Match a tcx.
+ */
+int
+tcxmatch(parent, vcf, aux)
+ struct device *parent;
+ void *vcf, *aux;
+{
+ struct cfdata *cf = vcf;
+ struct confargs *ca = aux;
+ struct romaux *ra = &ca->ca_ra;
+
+ if (strcmp(ra->ra_name, OBPNAME))
+ return (0);
+
+ /*
+ * Mask out invalid flags from the user.
+ */
+ cf->cf_flags &= FB_USERMASK;
+
+ if (ca->ca_bustype == BUS_SBUS)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Attach a display.
+ */
+void
+tcxattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ register struct tcx_softc *sc = (struct tcx_softc *)self;
+ register struct confargs *ca = args;
+ register int node = 0, ramsize, i;
+ register volatile struct bt_regs *bt;
+ struct fbdevice *fb = &sc->sc_fb;
+ int isconsole = 0, sbus = 1;
+ extern struct tty *fbconstty;
+
+ fb->fb_driver = &tcx_fbdriver;
+ fb->fb_device = &sc->sc_dev;
+ fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags;
+
+ /*
+ * XXX - should be set to FBTYPE_TCX.
+ * XXX For CG3 emulation to work in current (96/6) X11 servers,
+ * XXX `fbtype' must point to an "unregocnised" entry.
+ */
+ fb->fb_type.fb_type = FBTYPE_RESERVED3;
+
+ if (ca->ca_ra.ra_nreg != TCX_NREG)
+ panic("tcx: oops");
+
+ /* Copy register address spaces */
+ for (i = 0; i < TCX_NREG; i++)
+ sc->sc_physadr[i] = ca->ca_ra.ra_reg[i];
+
+ /* XXX - fix THC and TEC offsets */
+ sc->sc_physadr[TCX_REG_TEC].rr_paddr += 0x1000;
+ sc->sc_physadr[TCX_REG_THC].rr_paddr += 0x1000;
+
+ sc->sc_bt = bt = (volatile struct bt_regs *)
+ mapiodev(&ca->ca_ra.ra_reg[TCX_REG_CMAP], 0, sizeof *sc->sc_bt);
+ sc->sc_thc = (volatile struct tcx_thc *)
+ mapiodev(&ca->ca_ra.ra_reg[TCX_REG_THC], 0, sizeof *sc->sc_thc);
+
+ switch (ca->ca_bustype) {
+ case BUS_SBUS:
+ node = ca->ca_ra.ra_node;
+ break;
+
+ case BUS_OBIO:
+ default:
+ printf("TCX on bus 0x%x?\n", ca->ca_bustype);
+ return;
+ }
+
+ fb->fb_type.fb_depth = node_has_property(node, "tcx-24-bit")
+ ? 24
+ : (node_has_property(node, "tcx-8-bit")
+ ? 8
+ : 8);
+
+ fb_setsize(fb, fb->fb_type.fb_depth, 1152, 900,
+ node, ca->ca_bustype);
+
+ ramsize = fb->fb_type.fb_height * fb->fb_linebytes;
+ fb->fb_type.fb_cmsize = 256;
+ fb->fb_type.fb_size = ramsize;
+ printf(": %s, %d x %d", OBPNAME,
+ fb->fb_type.fb_width,
+ fb->fb_type.fb_height);
+
+ isconsole = node == fbnode && fbconstty != NULL;
+
+ printf(", id %d, rev %d, sense %d",
+ (sc->sc_thc->thc_config & THC_CFG_FBID) >> THC_CFG_FBID_SHIFT,
+ (sc->sc_thc->thc_config & THC_CFG_REV) >> THC_CFG_REV_SHIFT,
+ (sc->sc_thc->thc_config & THC_CFG_SENSE) >> THC_CFG_SENSE_SHIFT
+ );
+
+ /* reset cursor & frame buffer controls */
+ tcx_reset(sc);
+
+ /* grab initial (current) color map (DOES THIS WORK?) */
+ bt->bt_addr = 0;
+ for (i = 0; i < 256 * 3; i++)
+ ((char *)&sc->sc_cmap)[i] = bt->bt_cmap >> 24;
+
+ /* enable video */
+ sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
+
+ if (isconsole) {
+ printf(" (console)\n");
+ } else
+ printf("\n");
+
+ if (sbus)
+ sbus_establish(&sc->sc_sd, &sc->sc_dev);
+ if (node == fbnode)
+ fb_attach(&sc->sc_fb, isconsole);
+}
+
+int
+tcxopen(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ int unit = minor(dev);
+
+ if (unit >= tcx_cd.cd_ndevs || tcx_cd.cd_devs[unit] == NULL)
+ return (ENXIO);
+ return (0);
+}
+
+int
+tcxclose(dev, flags, mode, p)
+ dev_t dev;
+ int flags, mode;
+ struct proc *p;
+{
+ struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
+
+ tcx_reset(sc);
+ return (0);
+}
+
+int
+tcxioctl(dev, cmd, data, flags, p)
+ dev_t dev;
+ u_long cmd;
+ register caddr_t data;
+ int flags;
+ struct proc *p;
+{
+ register struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
+ int error;
+
+ switch (cmd) {
+
+ case FBIOGTYPE:
+ *(struct fbtype *)data = sc->sc_fb.fb_type;
+ break;
+
+ case FBIOGATTR:
+#define fba ((struct fbgattr *)data)
+ fba->real_type = sc->sc_fb.fb_type.fb_type;
+ fba->owner = 0; /* XXX ??? */
+ fba->fbtype = sc->sc_fb.fb_type;
+ fba->sattr.flags = 0;
+ fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
+ fba->sattr.dev_specific[0] = -1;
+ fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
+ fba->emu_types[1] = FBTYPE_SUN3COLOR;
+ fba->emu_types[2] = -1;
+#undef fba
+ break;
+
+ case FBIOGETCMAP:
+ return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
+
+ case FBIOPUTCMAP:
+ /* copy to software map */
+#define p ((struct fbcmap *)data)
+ error = bt_putcmap(p, &sc->sc_cmap, 256);
+ if (error)
+ return (error);
+ /* now blast them into the chip */
+ /* XXX should use retrace interrupt */
+ tcx_loadcmap(sc, p->index, p->count);
+#undef p
+ break;
+
+ case FBIOGVIDEO:
+ *(int *)data = sc->sc_blanked;
+ break;
+
+ case FBIOSVIDEO:
+ if (*(int *)data)
+ tcx_unblank(&sc->sc_dev);
+ else if (!sc->sc_blanked) {
+ sc->sc_blanked = 1;
+ sc->sc_thc->thc_hcmisc &= ~THC_MISC_VIDEN;
+ /* Put monitor in `power-saving mode' */
+ sc->sc_thc->thc_hcmisc |= THC_MISC_VSYNC_DISABLE;
+ sc->sc_thc->thc_hcmisc |= THC_MISC_HSYNC_DISABLE;
+ }
+ break;
+
+ default:
+#ifdef DEBUG
+ log(LOG_NOTICE, "tcxioctl(0x%lx) (%s[%d])\n", cmd,
+ p->p_comm, p->p_pid);
+#endif
+ return (ENOTTY);
+ }
+ return (0);
+}
+
+/*
+ * Clean up hardware state (e.g., after bootup or after X crashes).
+ */
+static void
+tcx_reset(sc)
+ register struct tcx_softc *sc;
+{
+ register volatile struct bt_regs *bt;
+
+ /* Enable cursor in Brooktree DAC. */
+ bt = sc->sc_bt;
+ bt->bt_addr = 0x06 << 24;
+ bt->bt_ctrl |= 0x03 << 24;
+}
+
+/*
+ * Load a subset of the current (new) colormap into the color DAC.
+ */
+static void
+tcx_loadcmap(sc, start, ncolors)
+ register struct tcx_softc *sc;
+ register int start, ncolors;
+{
+ register volatile struct bt_regs *bt;
+ register u_int *ip, i;
+ register int count;
+
+ ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)]; /* start/4 * 3 */
+ count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
+ bt = sc->sc_bt;
+ bt->bt_addr = BT_D4M4(start) << 24;
+ while (--count >= 0) {
+ i = *ip++;
+ /* hardware that makes one want to pound boards with hammers */
+ bt->bt_cmap = i;
+ bt->bt_cmap = i << 8;
+ bt->bt_cmap = i << 16;
+ bt->bt_cmap = i << 24;
+ }
+}
+
+static void
+tcx_unblank(dev)
+ struct device *dev;
+{
+ struct tcx_softc *sc = (struct tcx_softc *)dev;
+
+ if (sc->sc_blanked) {
+ sc->sc_blanked = 0;
+ sc->sc_thc->thc_hcmisc &= ~THC_MISC_VSYNC_DISABLE;
+ sc->sc_thc->thc_hcmisc &= ~THC_MISC_HSYNC_DISABLE;
+ sc->sc_thc->thc_hcmisc |= THC_MISC_VIDEN;
+ }
+}
+
+/*
+ * Base addresses at which users can mmap() the various pieces of a tcx.
+ */
+#define TCX_USER_RAM 0x00000000
+#define TCX_USER_RAM24 0x01000000
+#define TCX_USER_RAM_COMPAT 0x04000000 /* cg3 emulation */
+#define TCX_USER_STIP 0x10000000
+#define TCX_USER_BLIT 0x20000000
+#define TCX_USER_RDFB32 0x28000000
+#define TCX_USER_RSTIP 0x30000000
+#define TCX_USER_RBLIT 0x38000000
+#define TCX_USER_TEC 0x70001000
+#define TCX_USER_BTREGS 0x70002000
+#define TCX_USER_THC 0x70004000
+#define TCX_USER_DHC 0x70008000
+#define TCX_USER_ALT 0x7000a000
+#define TCX_USER_UART 0x7000c000
+#define TCX_USER_VRT 0x7000e000
+#define TCX_USER_ROM 0x70010000
+
+struct mmo {
+ u_int mo_uaddr; /* user (virtual) address */
+ u_int mo_size; /* size, or 0 for video ram size */
+ u_int mo_bank; /* register bank number */
+};
+
+/*
+ * Return the address that would map the given device at the given
+ * offset, allowing for the given protection, or return -1 for error.
+ *
+ * XXX needs testing against `demanding' applications (e.g., aviator)
+ */
+int
+tcxmmap(dev, off, prot)
+ dev_t dev;
+ int off, prot;
+{
+ register struct tcx_softc *sc = tcx_cd.cd_devs[minor(dev)];
+ register struct mmo *mo;
+ register u_int u, sz;
+ static struct mmo mmo[] = {
+ { TCX_USER_RAM, 0, TCX_REG_DFB8 },
+ { TCX_USER_RAM24, 0, TCX_REG_DFB24 },
+ { TCX_USER_RAM_COMPAT, 0, TCX_REG_DFB8 },
+
+ { TCX_USER_STIP, 1, TCX_REG_STIP },
+ { TCX_USER_BLIT, 1, TCX_REG_BLIT },
+ { TCX_USER_RDFB32, 1, TCX_REG_RDFB32 },
+ { TCX_USER_RSTIP, 1, TCX_REG_RSTIP },
+ { TCX_USER_RBLIT, 1, TCX_REG_RBLIT },
+ { TCX_USER_TEC, 1, TCX_REG_TEC },
+ { TCX_USER_BTREGS, 8192 /* XXX */, TCX_REG_CMAP },
+ { TCX_USER_THC, sizeof(struct tcx_thc), TCX_REG_THC },
+ { TCX_USER_DHC, 1, TCX_REG_DHC },
+ { TCX_USER_ALT, 1, TCX_REG_ALT },
+ { TCX_USER_ROM, 65536, TCX_REG_ROM },
+ };
+#define NMMO (sizeof mmo / sizeof *mmo)
+
+ if (off & PGOFSET)
+ panic("tcxmmap");
+
+ /*
+ * Entries with size 0 map video RAM (i.e., the size in fb data).
+ *
+ * Since we work in pages, the fact that the map offset table's
+ * sizes are sometimes bizarre (e.g., 1) is effectively ignored:
+ * one byte is as good as one page.
+ */
+ for (mo = mmo; mo < &mmo[NMMO]; mo++) {
+ if ((u_int)off < mo->mo_uaddr)
+ continue;
+ u = off - mo->mo_uaddr;
+ sz = mo->mo_size ? mo->mo_size : sc->sc_fb.fb_type.fb_size;
+ if (u < sz)
+ return (REG2PHYS(&sc->sc_physadr[mo->mo_bank], u) |
+ PMAP_NC);
+ }
+#ifdef DEBUG
+ {
+ register struct proc *p = curproc; /* XXX */
+ log(LOG_NOTICE, "tcxmmap(0x%x) (%s[%d])\n", off, p->p_comm, p->p_pid);
+ }
+#endif
+ return (-1); /* not a user-map offset */
+}
diff --git a/sys/arch/sparc/dev/tcxreg.h b/sys/arch/sparc/dev/tcxreg.h
new file mode 100644
index 00000000000..ef48a21955c
--- /dev/null
+++ b/sys/arch/sparc/dev/tcxreg.h
@@ -0,0 +1,151 @@
+/* $OpenBSD: tcxreg.h,v 1.1 1997/08/08 08:25:32 downsj Exp $ */
+/* $NetBSD: tcxreg.h,v 1.1 1996/06/19 13:17:35 pk Exp $ */
+/*
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * A TCX is composed of numerous groups of control registers, all with TLAs:
+ * DHC - ???
+ * TEC - transform engine control?
+ * THC - TEC Hardware Configuration
+ * ROM - a 128Kbyte ROM with who knows what in it.
+ * STIP - ???
+ * RSTIP - Raw ???
+ * BLIT - ???
+ * RBLIT - Raw ???
+ * ALT - ???
+ * colormap - see below
+ * frame buffer memory (video RAM)
+ * possible other stuff
+ *
+ */
+#define TCX_REG_DFB8 0
+#define TCX_REG_DFB24 1
+#define TCX_REG_STIP 2
+#define TCX_REG_BLIT 3
+#define TCX_REG_RDFB32 4
+#define TCX_REG_RSTIP 5
+#define TCX_REG_RBLIT 6
+#define TCX_REG_TEC 7
+#define TCX_REG_CMAP 8
+#define TCX_REG_THC 9
+#define TCX_REG_ROM 10
+#define TCX_REG_DHC 11
+#define TCX_REG_ALT 12
+
+#define TCX_NREG 13
+
+
+/*
+ * The layout of the THC.
+ */
+struct tcx_thc {
+ u_int thc_config;
+ u_int thc_xxx1[31];
+ u_int thc_sensebus;
+ u_int thc_xxx2[3];
+ u_int thc_delay;
+ u_int thc_strapping;
+ u_int thc_xxx3[1];
+ u_int thc_linecount;
+ u_int thc_xxx4[478];
+ u_int thc_hcmisc;
+ u_int thc_xxx5[56];
+ u_int thc_cursoraddr;
+ u_int thc_cursorAdata[32];
+ u_int thc_cursorBdata[32];
+
+};
+/* bits in thc_config ??? */
+#define THC_CFG_FBID 0xf0000000 /* id mask */
+#define THC_CFG_FBID_SHIFT 28
+#define THC_CFG_SENSE 0x07000000 /* sense mask */
+#define THC_CFG_SENSE_SHIFT 24
+#define THC_CFG_REV 0x00f00000 /* revision mask */
+#define THC_CFG_REV_SHIFT 20
+#define THC_CFG_RST 0x00008000 /* reset */
+
+/* bits in thc_hcmisc */
+#define THC_MISC_OPENFLG 0x80000000 /* open flag (what's that?) */
+#define THC_MISC_SWERR_EN 0x20000000 /* enable SW error interrupt */
+#define THC_MISC_VSYNC_LEVEL 0x08000000 /* vsync level when disabled */
+#define THC_MISC_HSYNC_LEVEL 0x04000000 /* hsync level when disabled */
+#define THC_MISC_VSYNC_DISABLE 0x02000000 /* vsync disable */
+#define THC_MISC_HSYNC_DISABLE 0x01000000 /* hsync disable */
+#define THC_MISC_XXX1 0x00ffe000 /* unused */
+#define THC_MISC_RESET 0x00001000 /* ??? */
+#define THC_MISC_XXX2 0x00000800 /* unused */
+#define THC_MISC_VIDEN 0x00000400 /* video enable */
+#define THC_MISC_SYNC 0x00000200 /* not sure what ... */
+#define THC_MISC_VSYNC 0x00000100 /* ... these really are */
+#define THC_MISC_SYNCEN 0x00000080 /* sync enable */
+#define THC_MISC_CURSRES 0x00000040 /* cursor resolution */
+#define THC_MISC_INTEN 0x00000020 /* v.retrace intr enable */
+#define THC_MISC_INTR 0x00000010 /* intr pending / ack bit */
+#define THC_MISC_DACWAIT 0x0000000f /* ??? */
+
+/*
+ * Partial description of TEC.
+ */
+struct tcx_tec {
+ u_int tec_config; /* what's in it? */
+ u_int tec_xxx0[35];
+ u_int tec_delay; /* */
+#define TEC_DELAY_SYNC 0x00000f00
+#define TEC_DELAY_WR_F 0x000000c0
+#define TEC_DELAY_WR_R 0x00000030
+#define TEC_DELAY_SOE_F 0x0000000c
+#define TEC_DELAY_SOE_S 0x00000003
+ u_int tec_strapping; /* */
+#define TEC_STRAP_FIFO_LIMIT 0x00f00000
+#define TEC_STRAP_CACHE_EN 0x00010000
+#define TEC_STRAP_ZERO_OFFSET 0x00008000
+#define TEC_STRAP_REFRSH_DIS 0x00004000
+#define TEC_STRAP_REF_LOAD 0x00001000
+#define TEC_STRAP_REFRSH_PERIOD 0x000003ff
+ u_int tec_hcmisc; /* */
+ u_int tec_linecount; /* */
+ u_int tec_hss; /* */
+ u_int tec_hse; /* */
+ u_int tec_hds; /* */
+ u_int tec_hsedvs; /* */
+ u_int tec_hde; /* */
+ u_int tec_vss; /* */
+ u_int tec_vse; /* */
+ u_int tec_vds; /* */
+ u_int tec_vde; /* */
+};
+
diff --git a/sys/arch/sparc/dev/vmereg.h b/sys/arch/sparc/dev/vmereg.h
new file mode 100644
index 00000000000..5e7eb708ea4
--- /dev/null
+++ b/sys/arch/sparc/dev/vmereg.h
@@ -0,0 +1,75 @@
+/* $OpenBSD: vmereg.h,v 1.1 1997/08/08 08:25:32 downsj Exp $ */
+/* $NetBSD: vmereg.h,v 1.2 1997/06/07 19:10:57 pk Exp $ */
+
+/*
+ * Copyright (c) 1997 Paul Kranenburg
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Kranenburg.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+struct vmebusreg {
+ u_int32_t vmebus_cr; /* VMEbus control register */
+ u_int32_t vmebus_afar; /* VMEbus async fault address */
+ u_int32_t vmebus_afsr; /* VMEbus async fault status */
+};
+
+/* Control Register bits */
+#define VMEBUS_CR_C 0x80000000 /* I/O cache enable */
+#define VMEBUS_CR_S 0x40000000 /* VME slave enable */
+#define VMEBUS_CR_L 0x20000000 /* Loopback enable (diagnostic) */
+#define VMEBUS_CR_R 0x10000000 /* VMEbus reset */
+#define VMEBUS_CR_RSVD 0x0ffffff0 /* reserved */
+#define VMEBUS_CR_IMPL 0x0000000f /* VMEbus interface implementation */
+
+/* Asynchronous Fault Status bits */
+#define VMEBUS_AFSR_SZ 0xe0000000 /* Error transaction size */
+#define VMEBUS_AFSR_SZ4 0 /* 4 byte */
+#define VMEBUS_AFSR_SZ1 1 /* 1 byte */
+#define VMEBUS_AFSR_SZ2 2 /* 2 byte */
+#define VMEBUS_AFSR_SZ32 5 /* 32 byte */
+#define VMEBUS_AFSR_TO 0x10000000 /* VME master access time-out */
+#define VMEBUS_AFSR_BERR 0x08000000 /* VME master got BERR */
+#define VMEBUS_AFSR_WB 0x04000000 /* IOC write-back error (if SZ == 32) */
+ /* Non-IOC write error (id SZ != 32) */
+#define VMEBUS_AFSR_ERR 0x02000000 /* Error summary bit */
+#define VMEBUS_AFSR_S 0x01000000 /* MVME error in supervisor space */
+#define VMEBUS_AFSR_ME 0x00800000 /* Multiple error */
+#define VMEBUS_AFSR_RSVD 0x007fffff /* reserved */
+
+struct vmebusvec {
+ volatile u_int8_t vmebusvec[16];
+};
+
+/* VME address modifiers */
+#define VMEMOD_A16_D_S 0x2d /* 16-bit address, data, supervisor */
+#define VMEMOD_A24_D_S 0x3d /* 24-bit address, data, supervisor */
+#define VMEMOD_A32_D_S 0x0d /* 32-bit address, data, supervisor */
+
+#define VMEMOD_D32 0x40 /* 32-bit access */
+
diff --git a/sys/arch/sparc/dev/xd.c b/sys/arch/sparc/dev/xd.c
index 70caf5e3e48..5bf36fe6db2 100644
--- a/sys/arch/sparc/dev/xd.c
+++ b/sys/arch/sparc/dev/xd.c
@@ -1,4 +1,5 @@
-/* $NetBSD: xd.c,v 1.25 1996/04/22 02:42:06 christos Exp $ */
+/* $OpenBSD: xd.c,v 1.10 1997/08/08 08:25:35 downsj Exp $ */
+/* $NetBSD: xd.c,v 1.37 1997/07/29 09:58:16 fair Exp $ */
/*
*
@@ -36,7 +37,7 @@
* x d . c x y l o g i c s 7 5 3 / 7 0 5 3 v m e / s m d d r i v e r
*
* author: Chuck Cranor <chuck@ccrc.wustl.edu>
- * id: $NetBSD: xd.c,v 1.25 1996/04/22 02:42:06 christos Exp $
+ * id: $NetBSD: xd.c,v 1.37 1997/07/29 09:58:16 fair Exp $
* started: 27-Feb-95
* references: [1] Xylogics Model 753 User's Manual
* part number: 166-753-001, Revision B, May 21, 1988.
@@ -85,6 +86,7 @@
#include <sparc/dev/xdvar.h>
#include <sparc/dev/xio.h>
#include <sparc/sparc/vaddrs.h>
+#include <sparc/sparc/cpuvar.h>
/*
* macros
@@ -346,11 +348,11 @@ xdgetdisklabel(xd, b)
* soft reset to detect the xdc.
*/
-int xdcmatch(parent, match, aux)
+int xdcmatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
struct xdc *xdc;
@@ -359,7 +361,13 @@ int xdcmatch(parent, match, aux)
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
return (0);
- if (CPU_ISSUN4) {
+ switch (ca->ca_bustype) {
+ case BUS_OBIO:
+ case BUS_SBUS:
+ case BUS_VME16:
+ default:
+ return (0);
+ case BUS_VME32:
xdc = (struct xdc *) ra->ra_vaddr;
if (probeget((caddr_t) &xdc->xdc_csr, 1) == -1)
return (0);
@@ -367,8 +375,8 @@ int xdcmatch(parent, match, aux)
XDC_WAIT(xdc, del, XDC_RESETUSEC, XDC_RESET);
if (del <= 0)
return (0);
+ return (1);
}
- return (1);
}
/*
@@ -389,8 +397,7 @@ xdcattach(parent, self, aux)
/* get addressing and intr level stuff from autoconfig and load it
* into our xdc_softc. */
- ca->ca_ra.ra_vaddr = mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(struct xdc), ca->ca_bustype);
+ ca->ca_ra.ra_vaddr = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct xdc));
xdc->xdc = (struct xdc *) ca->ca_ra.ra_vaddr;
pri = ca->ca_ra.ra_intr[0].int_pri;
@@ -463,7 +470,7 @@ xdcattach(parent, self, aux)
XDC_DONE(xdc, rqno, err);
return;
}
- printf(": Xylogics 753/7053, PROM=%x.%02x.%02x\n",
+ printf(": Xylogics 753/7053, PROM=0x%x.%02x.%02x\n",
ctl->eprom_partno, ctl->eprom_lvl, ctl->eprom_rev);
XDC_DONE(xdc, rqno, err);
@@ -514,12 +521,11 @@ xdcattach(parent, self, aux)
* call xdattach!).
*/
int
-xdmatch(parent, match, aux)
+xdmatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
-
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct xdc_attach_args *xa = aux;
/* looking for autoconf wildcard or exact match */
@@ -987,24 +993,28 @@ xdsize(dev)
{
struct xd_softc *xdsc;
- int part, size;
+ int unit, part, size, omask;
- /* valid unit? try an open */
+ /* valid unit? */
+ unit = DISKUNIT(dev);
+ if (unit >= xd_cd.cd_ndevs || (xdsc = xd_cd.cd_devs[unit]) == NULL)
+ return (-1);
- if (xdopen(dev, 0, S_IFBLK, NULL) != 0)
+ part = DISKPART(dev);
+ omask = xdsc->sc_dk.dk_openmask & (1 << part);
+
+ if (omask == 0 && xdopen(dev, 0, S_IFBLK, NULL) != 0)
return (-1);
/* do it */
-
- xdsc = xd_cd.cd_devs[DISKUNIT(dev)];
- part = DISKPART(dev);
if (xdsc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
size = -1; /* only give valid size for swap partitions */
else
- size = xdsc->sc_dk.dk_label->d_partitions[part].p_size;
- if (xdclose(dev, 0, S_IFBLK, NULL) != 0)
- return -1;
- return size;
+ size = xdsc->sc_dk.dk_label->d_partitions[part].p_size *
+ (xdsc->sc_dk.dk_label->d_secsize / DEV_BSIZE);
+ if (omask == 0 && xdclose(dev, 0, S_IFBLK, NULL) != 0)
+ return (-1);
+ return (size);
}
/*
* xdstrategy: buffering system interface to xd.
@@ -1221,7 +1231,7 @@ xdc_rqtopb(iorq, iopb, cmd, subfun)
XDPC_RBC | XDPC_ECC2;
ctrl->throttle = XDC_THROTTLE;
#ifdef sparc
- if (CPU_ISSUN4 && cpumod == SUN4_300)
+ if (CPU_ISSUN4 && cpuinfo.cpu_type == CPUTYP_4_300)
ctrl->delay = XDC_DELAY_4_300;
else
ctrl->delay = XDC_DELAY_SPARC;
diff --git a/sys/arch/sparc/dev/xdreg.h b/sys/arch/sparc/dev/xdreg.h
index c723d018d0d..c2e19564ced 100644
--- a/sys/arch/sparc/dev/xdreg.h
+++ b/sys/arch/sparc/dev/xdreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xdreg.h,v 1.3 1997/08/08 08:25:36 downsj Exp $ */
/* $NetBSD: xdreg.h,v 1.3 1996/03/31 22:38:54 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/xdvar.h b/sys/arch/sparc/dev/xdvar.h
index 294f3a8c84b..c3e35672ba4 100644
--- a/sys/arch/sparc/dev/xdvar.h
+++ b/sys/arch/sparc/dev/xdvar.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xdvar.h,v 1.4 1997/08/08 08:25:37 downsj Exp $ */
/* $NetBSD: xdvar.h,v 1.5 1996/03/31 22:38:56 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/xio.h b/sys/arch/sparc/dev/xio.h
index 1ad5662b6be..c55c733712e 100644
--- a/sys/arch/sparc/dev/xio.h
+++ b/sys/arch/sparc/dev/xio.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xio.h,v 1.3 1997/08/08 08:25:37 downsj Exp $ */
/* $NetBSD: xio.h,v 1.2 1996/03/31 22:38:58 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/xy.c b/sys/arch/sparc/dev/xy.c
index 2841bd9ba84..2dc3413f2fe 100644
--- a/sys/arch/sparc/dev/xy.c
+++ b/sys/arch/sparc/dev/xy.c
@@ -1,4 +1,5 @@
-/* $NetBSD: xy.c,v 1.17 1996/04/22 02:42:04 christos Exp $ */
+/* $OpenBSD: xy.c,v 1.9 1997/08/08 08:25:39 downsj Exp $ */
+/* $NetBSD: xy.c,v 1.26 1997/07/19 21:43:56 pk Exp $ */
/*
*
@@ -36,7 +37,7 @@
* x y . c x y l o g i c s 4 5 0 / 4 5 1 s m d d r i v e r
*
* author: Chuck Cranor <chuck@ccrc.wustl.edu>
- * id: $NetBSD: xy.c,v 1.17 1996/04/22 02:42:04 christos Exp $
+ * id: $NetBSD: xy.c,v 1.26 1997/07/19 21:43:56 pk Exp $
* started: 14-Sep-95
* references: [1] Xylogics Model 753 User's Manual
* part number: 166-753-001, Revision B, May 21, 1988.
@@ -287,11 +288,11 @@ xygetdisklabel(xy, b)
* soft reset to detect the xyc.
*/
-int xycmatch(parent, match, aux)
+int xycmatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct confargs *ca = aux;
struct romaux *ra = &ca->ca_ra;
struct xyc *xyc;
@@ -299,14 +300,20 @@ int xycmatch(parent, match, aux)
if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
return (0);
- if (CPU_ISSUN4) {
+ switch (ca->ca_bustype) {
+ case BUS_OBIO:
+ case BUS_SBUS:
+ case BUS_VME32:
+ default:
+ return (0);
+ case BUS_VME16:
xyc = (struct xyc *) ra->ra_vaddr;
if (probeget((caddr_t) &xyc->xyc_rsetup, 1) == -1)
return (0);
if (xyc_unbusy(xyc, XYC_RESETUSEC) == XY_ERR_FAIL)
return(0);
+ return (1);
}
- return (1);
}
/*
@@ -329,8 +336,7 @@ xycattach(parent, self, aux)
/* get addressing and intr level stuff from autoconfig and load it
* into our xyc_softc. */
- ca->ca_ra.ra_vaddr = mapiodev(ca->ca_ra.ra_reg, 0,
- sizeof(struct xyc), ca->ca_bustype);
+ ca->ca_ra.ra_vaddr = mapiodev(ca->ca_ra.ra_reg, 0, sizeof(struct xyc));
xyc->xyc = (struct xyc *) ca->ca_ra.ra_vaddr;
pri = ca->ca_ra.ra_intr[0].int_pri;
@@ -458,12 +464,11 @@ xycattach(parent, self, aux)
* call xyattach!).
*/
int
-xymatch(parent, match, aux)
+xymatch(parent, vcf, aux)
struct device *parent;
- void *match, *aux;
-
+ void *vcf, *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = vcf;
struct xyc_attach_args *xa = aux;
/* looking for autoconf wildcard or exact match */
@@ -951,24 +956,28 @@ xysize(dev)
{
struct xy_softc *xysc;
- int part, size;
+ int unit, part, size, omask;
- /* valid unit? try an open */
+ /* valid unit? */
+ unit = DISKUNIT(dev);
+ if (unit >= xy_cd.cd_ndevs || (xysc = xy_cd.cd_devs[unit]) == NULL)
+ return (-1);
- if (xyopen(dev, 0, S_IFBLK, NULL) != 0)
+ part = DISKPART(dev);
+ omask = xysc->sc_dk.dk_openmask & (1 << part);
+
+ if (omask == 0 && xyopen(dev, 0, S_IFBLK, NULL) != 0)
return (-1);
/* do it */
-
- xysc = xy_cd.cd_devs[DISKUNIT(dev)];
- part = DISKPART(dev);
if (xysc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
size = -1; /* only give valid size for swap partitions */
else
- size = xysc->sc_dk.dk_label->d_partitions[part].p_size;
- if (xyclose(dev, 0, S_IFBLK, NULL) != 0)
- return -1;
- return size;
+ size = xysc->sc_dk.dk_label->d_partitions[part].p_size *
+ (xysc->sc_dk.dk_label->d_secsize / DEV_BSIZE);
+ if (omask == 0 && xyclose(dev, 0, S_IFBLK, NULL) != 0)
+ return (-1);
+ return (size);
}
/*
diff --git a/sys/arch/sparc/dev/xyreg.h b/sys/arch/sparc/dev/xyreg.h
index 2508bb97a8e..2d8c2704685 100644
--- a/sys/arch/sparc/dev/xyreg.h
+++ b/sys/arch/sparc/dev/xyreg.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xyreg.h,v 1.3 1997/08/08 08:25:40 downsj Exp $ */
/* $NetBSD: xyreg.h,v 1.3 1996/03/31 22:39:02 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/xyvar.h b/sys/arch/sparc/dev/xyvar.h
index e7ec8305980..f6f80cee49d 100644
--- a/sys/arch/sparc/dev/xyvar.h
+++ b/sys/arch/sparc/dev/xyvar.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: xyvar.h,v 1.4 1997/08/08 08:25:41 downsj Exp $ */
/* $NetBSD: xyvar.h,v 1.4 1996/03/31 22:39:04 pk Exp $ */
/*
diff --git a/sys/arch/sparc/dev/zs.c b/sys/arch/sparc/dev/zs.c
index c44f4aefe72..b9cb8b8eb56 100644
--- a/sys/arch/sparc/dev/zs.c
+++ b/sys/arch/sparc/dev/zs.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: zs.c,v 1.14 1997/06/25 13:01:00 downsj Exp $ */
-/* $NetBSD: zs.c,v 1.37.4.1 1996/06/02 09:07:55 mrg Exp $ */
+/* $OpenBSD: zs.c,v 1.15 1997/08/08 08:25:43 downsj Exp $ */
+/* $NetBSD: zs.c,v 1.48 1997/07/29 09:58:18 fair Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -72,21 +72,18 @@
#include <machine/autoconf.h>
#include <machine/conf.h>
#include <machine/cpu.h>
+#include <machine/kbd.h>
#include <sparc/sparc/vaddrs.h>
#include <sparc/sparc/auxreg.h>
-
-
-#include <machine/kbd.h>
#include <dev/ic/z8530reg.h>
-
#include <sparc/dev/zsvar.h>
#ifdef KGDB
#include <machine/remote-sl.h>
#endif
-#define ZSMAJOR 12 /* XXX */
+#define ZSMAJOR 12 /* XXX */
#define ZS_KBD 2 /* XXX */
#define ZS_MOUSE 3 /* XXX */
@@ -113,8 +110,8 @@
struct zs_softc {
struct device sc_dev; /* base device */
volatile struct zsdevice *sc_zs; /* chip registers */
- struct evcnt sc_intrcnt;
- struct zs_chanstate sc_cs[2]; /* channel A/B software state */
+ struct evcnt sc_intrcnt; /* count interrupts */
+ struct zs_chanstate sc_cs[2]; /* chan A/B software state */
};
/* Definition of the driver for autoconfig. */
@@ -154,10 +151,11 @@ static void zs_loadchannelregs __P((volatile struct zschan *, u_char *));
/* Console stuff. */
static struct tty *zs_ctty; /* console `struct tty *' */
static int zs_consin = -1, zs_consout = -1;
+static struct zs_chanstate *zs_conscs = NULL; /*console channel state */
static void zscnputc __P((int)); /* console putc function */
static volatile struct zschan *zs_conschan;
static struct tty *zs_checkcons __P((struct zs_softc *, int,
- struct zs_chanstate *));
+ struct zs_chanstate *));
#ifdef KGDB
/* KGDB stuff. Must reboot to change zs_kgdbunit. */
@@ -176,7 +174,6 @@ static int zssint __P((struct zs_chanstate *, volatile struct zschan *));
void zsabort __P((void));
static void zsoverrun __P((int, long *, char *));
-extern void *findzs __P((int));
static volatile struct zsdevice *zsaddr[NZS]; /* XXX, but saves work */
/*
@@ -272,7 +269,7 @@ zsattach(parent, dev, aux)
if ((addr = zsaddr[zs]) == NULL)
addr = zsaddr[zs] = (volatile struct zsdevice *)findzs(zs);
- if (ca->ca_bustype == BUS_MAIN)
+ if (ca->ca_bustype==BUS_MAIN)
if ((void *)addr != ra->ra_vaddr)
panic("zsattach");
if (ra->ra_nintr != 1) {
@@ -311,11 +308,12 @@ zsattach(parent, dev, aux)
tp->t_dev = makedev(ZSMAJOR, unit);
tp->t_oproc = zsstart;
tp->t_param = zsparam;
+ }
+ cs->cs_ttyp = tp;
#ifdef KGDB
+ if (ctp == NULL)
zs_checkkgdb(unit, cs, tp);
#endif
- }
- cs->cs_ttyp = tp;
if (unit == ZS_KBD) {
/*
* Keyboard: tell /dev/kbd driver how to talk to us.
@@ -329,14 +327,15 @@ zsattach(parent, dev, aux)
if (tp != ctp)
tty_attach(tp);
ringsize = 4096;
+ if (unit == zs_consout)
+ zs_conscs = cs;
}
-
cs->cs_ringmask = ringsize - 1;
cs->cs_rbuf = malloc((u_long)ringsize * sizeof(*cs->cs_rbuf),
M_DEVBUF, M_NOWAIT);
+
unit++;
cs++;
-
cs->cs_unit = unit;
cs->cs_speed = zs_getspeed(&addr->zs_chan[ZS_CHAN_B]);
cs->cs_zc = &addr->zs_chan[ZS_CHAN_B];
@@ -347,11 +346,12 @@ zsattach(parent, dev, aux)
tp->t_dev = makedev(ZSMAJOR, unit);
tp->t_oproc = zsstart;
tp->t_param = zsparam;
+ }
+ cs->cs_ttyp = tp;
#ifdef KGDB
+ if (ctp == NULL)
zs_checkkgdb(unit, cs, tp);
#endif
- }
- cs->cs_ttyp = tp;
if (unit == ZS_MOUSE) {
/*
* Mouse: tell /dev/mouse driver how to talk to us.
@@ -364,6 +364,8 @@ zsattach(parent, dev, aux)
if (tp != ctp)
tty_attach(tp);
ringsize = 4096;
+ if (unit == zs_consout)
+ zs_conscs = cs;
}
cs->cs_ringmask = ringsize - 1;
cs->cs_rbuf = malloc((u_long)ringsize * sizeof(*cs->cs_rbuf),
@@ -439,7 +441,7 @@ zsconsole(tp, unit, out, fnstop)
v_putc = zscnputc;
} else
zs_consin = unit;
- if(fnstop)
+ if (fnstop)
*fnstop = &zsstop;
zs_ctty = tp;
}
@@ -465,6 +467,24 @@ zscnputc(c)
(void) splzs();
while ((zc->zc_csr & ZSRR0_TX_READY) == 0)
ZS_DELAY();
+ /*
+ * If transmitter was busy doing regular tty I/O (ZSWR1_TIE on),
+ * defer our output until the transmit interrupt runs. We still
+ * sync with TX_READY so we can get by with a single-char "queue".
+ */
+ if (zs_conscs != NULL && (zs_conscs->cs_creg[1] & ZSWR1_TIE)) {
+ /*
+ * If previous not yet done, send it now; zsxint()
+ * will field the interrupt for our char, but doesn't
+ * care. We're running at sufficiently high spl for
+ * this to work.
+ */
+ if (zs_conscs->cs_deferred_cc != 0)
+ zc->zc_data = zs_conscs->cs_deferred_cc;
+ zs_conscs->cs_deferred_cc = c;
+ splx(s);
+ return;
+ }
zc->zc_data = c;
ZS_DELAY();
splx(s);
@@ -483,7 +503,7 @@ zs_checkcons(sc, unit, cs)
register struct tty *tp;
char *i, *o;
- if ((tp = zs_ctty) == NULL)
+ if ((tp = zs_ctty) == NULL) /* XXX */
return (0);
i = zs_consin == unit ? "input" : NULL;
o = zs_consout == unit ? "output" : NULL;
@@ -623,7 +643,7 @@ zsopen(dev, flags, mode, p)
return (EBUSY);
}
error = 0;
- while (1) {
+ for (;;) {
register int rr0;
/* loop, turning on the device, until carrier present */
@@ -720,6 +740,7 @@ zsread(dev, uio, flags)
tp = cs->cs_ttyp;
return (linesw[tp->t_line].l_read(tp, uio, flags));
+
}
int
@@ -850,7 +871,7 @@ zshard(intrarg)
raise(0, PIL_TTY);
else
#endif
- ienab_bis(IE_ZSSOFT);
+ ienab_bis(IE_ZSSOFT);
}
return (intflags & ZSHARD_WAS_SERVICED);
}
@@ -860,11 +881,9 @@ zsrint(cs, zc)
register struct zs_chanstate *cs;
register volatile struct zschan *zc;
{
- register u_int c;
+ register u_int c = zc->zc_data;
- c = zc->zc_data;
ZS_DELAY();
-
if (cs->cs_conk) {
register struct conk_state *conk = &zsconk_state;
@@ -922,6 +941,15 @@ zsxint(cs, zc)
{
register int i = cs->cs_tbc;
+ if (cs->cs_deferred_cc != 0) {
+ /* Handle deferred zscnputc() output first */
+ zc->zc_data = cs->cs_deferred_cc;
+ cs->cs_deferred_cc = 0;
+ ZS_DELAY();
+ zc->zc_csr = ZSWR0_CLR_INTR;
+ ZS_DELAY();
+ return (0);
+ }
if (i == 0) {
zc->zc_csr = ZSWR0_RESET_TXINT;
ZS_DELAY();
@@ -1145,7 +1173,7 @@ again:
break;
default:
- log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n",
+ log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (0x%x)\n",
unit >> 1, (unit & 1) + 'a', c);
break;
}
@@ -1166,9 +1194,9 @@ zsioctl(dev, cmd, data, flag, p)
{
int unit = minor(dev);
struct zs_softc *sc = zs_cd.cd_devs[unit >> 1];
- register struct tty *tp = sc->sc_cs[unit & 1].cs_ttyp;
- register int error, s;
register struct zs_chanstate *cs = &sc->sc_cs[unit & 1];
+ register struct tty *tp = cs->cs_ttyp;
+ register int error, s;
error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p);
if (error >= 0)
@@ -1262,14 +1290,8 @@ zsioctl(dev, cmd, data, flag, p)
case TIOCCDTR:
zs_modem(cs, 0);
break;
- case TIOCMGET:
- /* XXX: fixme */
- *(int *)data = TIOCM_CAR | TIOCM_CTS | TIOCM_DTR | TIOCM_RTS;
- return (0);
case TIOCMSET:
- /* XXX: fixme */
- zs_modem(cs, *(int *)data & (TIOCM_DTR|TIOCM_RTS));
- return (0);
+ case TIOCMGET:
case TIOCMBIS:
case TIOCMBIC:
default:
@@ -1396,7 +1418,11 @@ zsparam(tp, t)
return (0);
}
tmp = BPS_TO_TCONST(PCLK / 16, tmp);
- if (tmp < 2)
+#ifdef ALLOW_TC_EQUAL_ZERO
+ if (tmp < 0)
+#else
+ if (tmp < 1)
+#endif
return (EINVAL);
cflag = t->c_cflag;
diff --git a/sys/arch/sparc/dev/zsvar.h b/sys/arch/sparc/dev/zsvar.h
index 8f9274573ee..79b8c6cd2c9 100644
--- a/sys/arch/sparc/dev/zsvar.h
+++ b/sys/arch/sparc/dev/zsvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: zsvar.h,v 1.9 1996/08/12 03:14:50 downsj Exp $ */
-/* $NetBSD: zsvar.h,v 1.8 1996/03/31 22:39:08 pk Exp $ */
+/* $OpenBSD: zsvar.h,v 1.10 1997/08/08 08:25:44 downsj Exp $ */
+/* $NetBSD: zsvar.h,v 1.10 1997/04/14 21:26:28 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -91,9 +91,12 @@ struct zsdevice {
#define ZRING_VALUE(x) ((x) >> 8)
#define ZRING_MAKE(t, v) ((t) | (v) << 8)
+/* forard decl */
+struct zs_softc;
+
struct zs_chanstate {
- struct zs_chanstate *cs_next; /* linked list for zshard() */
- struct zs_softc *cs_sc; /* points to my softc */
+ struct zs_chanstate *cs_next; /* linked list for zshard() */
+ struct zs_softc *cs_sc; /* pointer to softc */
volatile struct zschan *cs_zc; /* points to hardware regs */
int cs_unit; /* unit number */
struct tty *cs_ttyp; /* ### */
@@ -123,6 +126,7 @@ struct zs_chanstate {
char cs_kgdb; /* enter debugger on frame char */
char cs_consio; /* port does /dev/console I/O */
char cs_xxx; /* (spare) */
+ char cs_deferred_cc; /* deferred zscnputc() output */
int cs_speed; /* default baud rate (from ROM) */
/*