diff options
Diffstat (limited to 'sys/arch/mac68k/dev')
-rw-r--r-- | sys/arch/mac68k/dev/adb.c | 68 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/adbsys.c | 69 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/adbvar.h | 25 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/asc.c | 49 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/grf.c | 187 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/grf_iv.c | 63 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/grf_mv.c | 130 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/grfvar.h | 70 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/if_ae.c | 80 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/if_sn.c | 205 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/ite.c | 625 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/mac68k5380.c | 293 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/ncr5380.c | 224 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/ncr5380reg.h | 16 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/nubus.c | 127 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/nubus.h | 17 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/rd_root.c | 5 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/scsi.c | 1224 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/scsi96.c | 49 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/ser.c | 2033 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/serreg.h | 52 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/z8530reg.h | 83 |
22 files changed, 1290 insertions, 4404 deletions
diff --git a/sys/arch/mac68k/dev/adb.c b/sys/arch/mac68k/dev/adb.c index 8e75d7df8ab..44e1f721d58 100644 --- a/sys/arch/mac68k/dev/adb.c +++ b/sys/arch/mac68k/dev/adb.c @@ -1,4 +1,4 @@ -/* $NetBSD: adb.c,v 1.5 1995/11/01 04:40:21 briggs Exp $ */ +/* $NetBSD: adb.c,v 1.9 1996/05/05 16:21:20 briggs Exp $ */ /*- * Copyright (C) 1994 Bradley A. Grantham @@ -35,18 +35,22 @@ e* notice, this list of conditions and the following disclaimer in the #include <sys/fcntl.h> #include <sys/select.h> #include <sys/proc.h> +#include <sys/signalvar.h> #include <sys/systm.h> #include <machine/adbsys.h> +#include <machine/autoconf.h> #include <machine/keyboard.h> #include "adbvar.h" +#include "itevar.h" #include "../mac68k/macrom.h" /* * Function declarations. */ -static void adbattach __P((struct device *parent, struct device *dev, void *aux)); +static int adbmatch __P((struct device *, void *, void *)); +static void adbattach __P((struct device *, struct device *, void *)); /* * Global variables. @@ -80,13 +84,23 @@ static int adb_rptinterval = 6; /* ticks between auto-repeat */ static int adb_repeating = -1; /* key that is auto-repeating */ static adb_event_t adb_rptevent;/* event to auto-repeat */ -extern int matchbyname(); +/* Driver definition. -- This should probably be a bus... */ +struct cfattach adb_ca = { + sizeof(struct device), adbmatch, adbattach +}; -/* Driver definition. */ -struct cfdriver adbcd = { - NULL, "adb", matchbyname, adbattach, DV_DULL, sizeof(struct device), +struct cfdriver adb_cd = { + NULL, "adb", DV_DULL }; +static int +adbmatch(pdp, match, auxp) + struct device *pdp; + void *match, *auxp; +{ + return 1; +} + static void adbattach(parent, dev, aux) struct device *parent, *dev; @@ -308,22 +322,34 @@ adb_processevent(event) */ max_byte = event->byte_count; button_bit = 1; - /* Classic Mouse Protocol (up to 2 buttons) */ - for (i = 0; i < 2; i++, button_bit <<= 1) - /* 0 when button down */ - if (!(event->bytes[i] & 0x80)) - buttons |= button_bit; - else - buttons &= ~button_bit; - /* Extended Protocol (up to 6 more buttons) */ - for (mask = 0x80; i < max_byte; - i += (mask == 0x80), button_bit <<= 1) { - /* 0 when button down */ - if (!(event->bytes[i] & mask)) - buttons |= button_bit; + switch (event->hand_id) { + case ADBMS_USPEED: + /* MicroSpeed mouse */ + if (max_byte == 4) + buttons = (~event->bytes[2]) & 0xff; else - buttons &= ~button_bit; - mask = ((mask >> 4) & 0xf) | ((mask & 0xf) << 4); + buttons = (event->bytes[0] & 0x80) ? 0 : 1; + break; + default: + /* Classic Mouse Protocol (up to 2 buttons) */ + for (i = 0; i < 2; i++, button_bit <<= 1) + /* 0 when button down */ + if (!(event->bytes[i] & 0x80)) + buttons |= button_bit; + else + buttons &= ~button_bit; + /* Extended Protocol (up to 6 more buttons) */ + for (mask = 0x80; i < max_byte; + i += (mask == 0x80), button_bit <<= 1) { + /* 0 when button down */ + if (!(event->bytes[i] & mask)) + buttons |= button_bit; + else + buttons &= ~button_bit; + mask = ((mask >> 4) & 0xf) + | ((mask & 0xf) << 4); + } + break; } new_event.u.m.buttons = adb_ms_buttons | buttons; new_event.u.m.dx = ((signed int) (event->bytes[1] & 0x3f)) - diff --git a/sys/arch/mac68k/dev/adbsys.c b/sys/arch/mac68k/dev/adbsys.c index e34a969f9a6..539b32c5483 100644 --- a/sys/arch/mac68k/dev/adbsys.c +++ b/sys/arch/mac68k/dev/adbsys.c @@ -1,4 +1,4 @@ -/* $NetBSD: adbsys.c,v 1.15 1995/09/04 02:50:57 briggs Exp $ */ +/* $NetBSD: adbsys.c,v 1.20 1996/05/08 13:36:41 briggs Exp $ */ /*- * Copyright (C) 1994 Bradley A. Grantham @@ -31,10 +31,11 @@ */ #include <sys/param.h> +#include <sys/systm.h> #include <machine/adbsys.h> +#include <machine/viareg.h> #include "adbvar.h" -#include "../mac68k/via.h" #include "../mac68k/macrom.h" /* from adb.c */ @@ -101,14 +102,49 @@ extdms_init() int adbindex, adbaddr; short cmd; char buffer[9]; - void extdms_complete(); totaladbs = CountADBs(); for (adbindex = 1; adbindex <= totaladbs; adbindex++) { /* Get the ADB information */ adbaddr = GetIndADB(&adbdata, adbindex); if (adbdata.origADBAddr == ADBADDR_MS && - (adbdata.devType == 1 || adbdata.devType == 2)) { + (adbdata.devType == ADBMS_USPEED)) { + /* Found MicroSpeed Mouse Deluxe Mac */ + cmd = ((adbaddr<<4)&0xF0)|0x9; /* listen 1 */ + + /* + * To setup the MicroSpeed, it appears that we can + * send the following command to the mouse and then + * expect data back in the form: + * buffer[0] = 4 (bytes) + * buffer[1], buffer[2] as std. mouse + * buffer[3] = buffer[4] = 0xff when no buttons + * are down. When button N down, bit N is clear. + * buffer[4]'s locking mask enables a + * click to toggle the button down state--sort of + * like the "Easy Access" shift/control/etc. keys. + * buffer[3]'s alternative speed mask enables using + * different speed when the corr. button is down + */ + buffer[0] = 4; + buffer[1] = 0x00; /* Alternative speed */ + buffer[2] = 0x00; /* speed = maximum */ + buffer[3] = 0x10; /* enable extended protocol, + * lower bits = alt. speed mask + * = 0000b + */ + buffer[4] = 0x07; /* Locking mask = 0000b, + * enable buttons = 0111b + */ + extdms_done = 0; + ADBOp((Ptr)buffer, (Ptr)extdms_complete, + (Ptr)&extdms_done, cmd); + while (!extdms_done) + /* busy wait until done */; + } + if (adbdata.origADBAddr == ADBADDR_MS && + ( adbdata.devType == ADBMS_100DPI + || adbdata.devType == ADBMS_200DPI)) { /* found a mouse */ cmd = ((adbaddr << 4) & 0xf0) | 0x3; @@ -135,12 +171,10 @@ adb_init() { ADBDataBlock adbdata; ADBSetInfoBlock adbinfo; - int i, s; int totaladbs; int adbindex, adbaddr; int error; char buffer[9]; - void extdms_complete(); if (!mrg_romready()) { printf("adb: no ROM ADB driver in this kernel for this machine\n"); @@ -161,7 +195,7 @@ adb_init() /* Initialize ADB */ #if defined(MRG_DEBUG) - printf("adb: calling ADBAlternateInit\n"); + printf("adb: calling ADBAlternateInit.\n"); #endif ADBAlternateInit(); @@ -182,15 +216,15 @@ adb_init() /* Print out the glory */ printf("adb: "); switch (adbdata.origADBAddr) { - case 2: + case ADBADDR_MAP: switch (adbdata.devType) { - case 1: + case ADB_STDKBD: printf("keyboard"); break; - case 2: + case ADB_EXTKBD: printf("extended keyboard"); break; - case 12: + case ADB_PBKBD: printf("PowerBook keyboard"); break; default: @@ -199,7 +233,7 @@ adb_init() break; } break; - case 3: + case ADBADDR_REL: extdms_done = 0; /* talk register 3 */ ADBOp((Ptr)buffer, (Ptr)extdms_complete, @@ -207,13 +241,16 @@ adb_init() while (!extdms_done) /* busy-wait until done */; switch (buffer[2]) { - case 1: + case ADBMS_100DPI: printf("100 dpi mouse"); break; - case 2: + case ADBMS_200DPI: printf("200 dpi mouse"); break; - case 4: + case ADBMS_USPEED: + printf("MicroSpeed mouse, default parameters"); + break; + case ADBMS_EXTENDED: extdms_done = 0; /* talk register 1 */ ADBOp((Ptr)buffer, (Ptr)extdms_complete, @@ -239,7 +276,7 @@ adb_init() break; } break; - case 4: + case ADBADDR_ABS: printf("absolute positioning device (tablet?) (%d)", adbdata.devType); break; default: diff --git a/sys/arch/mac68k/dev/adbvar.h b/sys/arch/mac68k/dev/adbvar.h index fc48977e4ad..b51182ef931 100644 --- a/sys/arch/mac68k/dev/adbvar.h +++ b/sys/arch/mac68k/dev/adbvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: adbvar.h,v 1.2 1995/04/21 02:47:44 briggs Exp $ */ +/* $NetBSD: adbvar.h,v 1.3 1996/05/05 06:16:24 briggs Exp $ */ /*- * Copyright (C) 1994 Bradley A. Grantham @@ -41,4 +41,25 @@ typedef struct adb_trace_xlate_s { } adb_trace_xlate_t; extern adb_trace_xlate_t adb_trace_xlations[]; -void adb_asmcomplete(); + +/* adb.c */ +void adb_asmcomplete __P((void)); +void adb_enqevent __P((adb_event_t *event)); +void adb_handoff __P((adb_event_t *event)); +void adb_autorepeat __P((void *keyp)); +void adb_dokeyupdown __P((adb_event_t *event)); +void adb_keymaybemouse __P((adb_event_t *event)); +void adb_processevent __P((adb_event_t *event)); +int adbopen __P((dev_t dev, int flag, int mode, struct proc *p)); +int adbclose __P((dev_t dev, int flag, int mode, struct proc *p)); +int adbread __P((dev_t dev, struct uio *uio, int flag)); +int adbwrite __P((dev_t dev, struct uio *uio, int flag)); +int adbioctl __P((dev_t , int , caddr_t , int , struct proc *)); +int adbselect __P((dev_t dev, int rw, struct proc *p)); + +/* adbsysadm.s */ +void extdms_complete __P((void)); + +/* adbsys.c */ +void adb_complete __P((caddr_t buffer, caddr_t data_area, int adb_command)); +void extdms_init __P((void)); diff --git a/sys/arch/mac68k/dev/asc.c b/sys/arch/mac68k/dev/asc.c index 7d6782b19a0..3afa56ab4f2 100644 --- a/sys/arch/mac68k/dev/asc.c +++ b/sys/arch/mac68k/dev/asc.c @@ -1,4 +1,4 @@ -/* $NetBSD: asc.c,v 1.9 1995/11/01 04:58:21 briggs Exp $ */ +/* $NetBSD: asc.c,v 1.11 1996/05/05 06:16:26 briggs Exp $ */ /*- * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, @@ -46,6 +46,7 @@ #include <sys/device.h> #include <machine/cpu.h> +#include "ascvar.h" /* Global ASC location */ volatile unsigned char *ASCBase = (unsigned char *) 0x14000; @@ -57,27 +58,25 @@ static int bell_length = 10; static int bell_volume = 100; static int bell_ringing = 0; -static int ascprobe __P((struct device *, struct cfdata *, void *)); +static int ascmatch __P((struct device *, void *, void *)); static void ascattach __P((struct device *, struct device *, void *)); -extern int matchbyname __P((struct device *, void *, void *)); -struct cfdriver asccd = -{NULL, "asc", matchbyname, ascattach, -DV_DULL, sizeof(struct device), NULL, 0}; +struct cfattach asc_ca = { + sizeof(struct device), ascmatch, ascattach +}; + +struct cfdriver asc_cd = { + NULL, "asc", DV_DULL, NULL, 0 +}; static int -ascprobe(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; +ascmatch(pdp, match, auxp) + struct device *pdp; + void *match, *auxp; { - if (strcmp(*((char **) aux), asccd.cd_name)) - return 0; - return 1; } - static void ascattach(parent, dev, aux) struct device *parent, *dev; @@ -87,10 +86,10 @@ ascattach(parent, dev, aux) } int -asc_setbellparams( - int freq, - int length, - int volume) +asc_setbellparams(freq, length, volume) + int freq; + int length; + int volume; { /* I only perform these checks for sanity. */ /* I suppose someone might want a bell that rings */ @@ -112,10 +111,10 @@ asc_setbellparams( int -asc_getbellparams( - int *freq, - int *length, - int *volume) +asc_getbellparams(freq, length, volume) + int *freq; + int *length; + int *volume; { *freq = bell_freq; *length = bell_length; @@ -126,8 +125,8 @@ asc_getbellparams( void -asc_bellstop( - int param) +asc_bellstop(param) + int param; { if (bell_ringing > 1000 || bell_ringing < 0) panic("bell got out of synch?????"); @@ -184,4 +183,6 @@ asc_ringbell() } bell_ringing++; timeout((void *) asc_bellstop, 0, bell_length); + + return 0; } diff --git a/sys/arch/mac68k/dev/grf.c b/sys/arch/mac68k/dev/grf.c index 3f9bd41ff00..508935afb19 100644 --- a/sys/arch/mac68k/dev/grf.c +++ b/sys/arch/mac68k/dev/grf.c @@ -1,4 +1,4 @@ -/* $NetBSD: grf.c,v 1.29 1995/09/21 11:13:27 briggs Exp $ */ +/* $NetBSD: grf.c,v 1.33 1996/05/19 22:27:04 scottr Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -57,6 +57,7 @@ #include <sys/mman.h> #include <sys/proc.h> #include <sys/vnode.h> +#include <sys/systm.h> #include <machine/grfioctl.h> #include <machine/cpu.h> @@ -69,6 +70,7 @@ #include <vm/vm_pager.h> #include "nubus.h" +#include "itevar.h" #include "grfvar.h" #include "grf.h" @@ -79,90 +81,61 @@ #define iteoff(u,f) #endif -static int grf_match __P((/*struct device *parent, struct device *dev, - void *aux*/)); -static void grf_attach __P((struct device *parent, struct device *dev, - void *aux)); +int grfmatch __P((struct device *, void *, void *)); +void grfattach __P((struct device *, struct device *, void *)); -static void fake_internal __P((void)); - -extern int grfmv_probe __P((struct grf_softc *gp, nubus_slot *nu)); -extern int grfmv_init __P((struct grf_softc *gp)); -extern int grfmv_mode __P((struct grf_softc *gp, int cmd, void *arg)); -extern caddr_t grfmv_phys __P((struct grf_softc *gp, vm_offset_t addr)); - -extern int grfiv_probe __P((struct grf_softc *gp, nubus_slot *ignore)); -extern int grfiv_init __P((struct grf_softc *gp)); -extern int grfiv_mode __P((struct grf_softc *gp, int cmd, void *arg)); -extern caddr_t grfiv_phys __P((struct grf_softc *gp, vm_offset_t addr)); - -struct cfdriver grfcd = { - NULL, "grf", grf_match, grf_attach, DV_DULL, - sizeof(struct grf_softc) +struct cfdriver grf_cd = { + NULL, "grf", DV_DULL }; -struct grfdev grfdev[] = { -/* DrSW (*gd_probe)() (*gd_init)() (*gd_mode)() gd_desc - (*gd_phys)() */ -{ NUBUS_DRSW_APPLE, grfmv_probe, grfmv_init, grfmv_mode, "QD-compatible", - grfmv_phys }, -{ 0xFF, grfiv_probe, grfiv_init, grfiv_mode, "Internal video", - grfiv_phys }, +struct cfattach grf_ca = { + sizeof(struct grf_softc), grfmatch, grfattach }; -static int ngrfdev=(sizeof(grfdev) / sizeof(grfdev[0])); - #ifdef DEBUG -static int grfdebug = 0xff; #define GDB_DEVNO 0x01 #define GDB_MMAP 0x02 #define GDB_IOMAP 0x04 #define GDB_LOCK 0x08 +static int grfdebug = (GDB_DEVNO|GDB_MMAP|GDB_IOMAP|GDB_LOCK); #endif -static int -grf_match(parent, match, aux) - struct device *parent; - void *match, *aux; +int +grfmatch(parent, match, aux) + struct device *parent; + void *match, *aux; { - struct grf_softc *sc = match; - nubus_slot *nu = (nubus_slot *) aux; - int i, r; - - for (i = 0; i < ngrfdev; i++) { - if ((r = (*grfdev[i].gd_probe)(sc, nu)) > 0) { - sc->g_type = i; - bcopy(aux, &sc->sc_slot, sizeof(nubus_slot)); - return r; - } - } - return 0; + struct grfbus_attach_args *ga = aux; + + return (strcmp(ga->ga_name, "grf") == 0); } -static void -grf_attach(parent, self, aux) +void +grfattach(parent, self, aux) struct device *parent, *self; - void *aux; + void *aux; { - struct grf_softc *sc; + struct grf_softc *sc = (struct grf_softc *)self; + struct grfbus_attach_args *ga = aux; - sc = (struct grf_softc *) self; - - if ((*grfdev[sc->g_type].gd_init)(sc) == 0) { - printf("\n"); - return; - } - sc->g_flags = GF_ALIVE; + printf("\n"); - printf(": %d x %d ", sc->curr_mode.width, sc->curr_mode.height); + /* Load forwarded pointers. */ + sc->sc_grfmode = ga->ga_grfmode; + sc->sc_slot = ga->ga_slot; + sc->sc_mode = ga->ga_mode; + sc->sc_phys = ga->ga_phys; - if (sc->curr_mode.psize == 1) - printf("monochrome"); - else - printf("%d color", 1 << sc->curr_mode.psize); + sc->sc_flags = GF_ALIVE; /* XXX bogus */ - printf(" %s (%s) display\n", - grfdev[sc->g_type].gd_desc, sc->card_name); +#ifdef notyet + /* + * Attach ite semantics to the grf. Change the name, forward + * everything else. + */ + ga->ga_name = "ite"; + (void)config_found(self, ga, grfbusprint); +#endif } /*ARGSUSED*/ @@ -178,12 +151,12 @@ grfopen(dev, flag, mode, p) int error; unit = GRFUNIT(dev); - gp = grfcd.cd_devs[unit]; + gp = grf_cd.cd_devs[unit]; - if (unit >= grfcd.cd_ndevs || (gp->g_flags & GF_ALIVE) == 0) + if (unit >= grf_cd.cd_ndevs || (gp->sc_flags & GF_ALIVE) == 0) return (ENXIO); - if ((gp->g_flags & (GF_OPEN | GF_EXCLUDE)) == (GF_OPEN | GF_EXCLUDE)) + if ((gp->sc_flags & (GF_OPEN | GF_EXCLUDE)) == (GF_OPEN | GF_EXCLUDE)) return (EBUSY); /* @@ -191,14 +164,15 @@ grfopen(dev, flag, mode, p) * XXX: always put in graphics mode. */ error = 0; - if ((gp->g_flags & GF_OPEN) == 0) { - gp->g_flags |= GF_OPEN; + if ((gp->sc_flags & GF_OPEN) == 0) { + gp->sc_flags |= GF_OPEN; error = grfon(dev); } return (error); } /*ARGSUSED*/ +int grfclose(dev, flag, mode, p) dev_t dev; int flag; @@ -207,15 +181,16 @@ grfclose(dev, flag, mode, p) { register struct grf_softc *gp; - gp = grfcd.cd_devs[GRFUNIT(dev)]; + gp = grf_cd.cd_devs[GRFUNIT(dev)]; (void) grfoff(dev); - gp->g_flags &= GF_ALIVE; + gp->sc_flags &= GF_ALIVE; return (0); } /*ARGSUSED*/ +int grfioctl(dev, cmd, data, flag, p) dev_t dev; int cmd; @@ -223,11 +198,13 @@ grfioctl(dev, cmd, data, flag, p) int flag; struct proc *p; { - register struct grf_softc *gp; + struct grf_softc *gp; + struct grfmode *gm; int error; int unit = GRFUNIT(dev); - gp = grfcd.cd_devs[unit]; + gp = grf_cd.cd_devs[unit]; + gm = gp->sc_grfmode; error = 0; switch (cmd) { @@ -236,14 +213,14 @@ grfioctl(dev, cmd, data, flag, p) { struct grfinfo *g; g = (struct grfinfo *) data; bzero(data, sizeof(struct grfinfo)); - g->gd_id = gp->curr_mode.mode_id; - g->gd_fbaddr = gp->curr_mode.fbbase; - g->gd_fbsize = gp->curr_mode.fbsize; - g->gd_colors = 1 << (u_int32_t) gp->curr_mode.psize; - g->gd_planes = gp->curr_mode.psize; - g->gd_fbwidth = g->gd_dwidth = gp->curr_mode.width; - g->gd_fbheight = g->gd_dheight = gp->curr_mode.height; - g->gd_fbrowbytes = gp->curr_mode.rowbytes; + g->gd_id = gm->mode_id; + g->gd_fbaddr = gm->fbbase; + g->gd_fbsize = gm->fbsize; + g->gd_colors = 1 << (u_int32_t) gm->psize; + g->gd_planes = gm->psize; + g->gd_fbwidth = g->gd_dwidth = gm->width; + g->gd_fbheight = g->gd_dheight = gm->height; + g->gd_fbrowbytes = gm->rowbytes; } break; @@ -261,16 +238,16 @@ grfioctl(dev, cmd, data, flag, p) break; case GRFIOCGMODE: - bcopy(&gp->curr_mode, data, sizeof(struct grfmode)); + bcopy(gm, data, sizeof(struct grfmode)); break; case GRFIOCGETMODE: - error = (*grfdev[gp->g_type].gd_mode)(gp, GM_CURRMODE, data); + error = (*gp->sc_mode)(gp, GM_CURRMODE, data); break; case GRFIOCSETMODE: - error = (*grfdev[gp->g_type].gd_mode)(gp, GM_NEWMODE, data); + error = (*gp->sc_mode)(gp, GM_NEWMODE, data); break; case GRFIOCLISTMODES: - error = (*grfdev[gp->g_type].gd_mode)(gp, GM_LISTMODES, data); + error = (*gp->sc_mode)(gp, GM_LISTMODES, data); break; default: @@ -281,6 +258,7 @@ grfioctl(dev, cmd, data, flag, p) } /*ARGSUSED*/ +int grfselect(dev, rw, p) dev_t dev; int rw; @@ -292,6 +270,7 @@ grfselect(dev, rw, p) } /*ARGSUSED*/ +int grfmmap(dev, off, prot) dev_t dev; int off; @@ -300,7 +279,7 @@ grfmmap(dev, off, prot) int unit = GRFUNIT(dev); struct grf_softc *gp; - gp = grfcd.cd_devs[unit]; + gp = grf_cd.cd_devs[unit]; return (grfaddr(gp, off)); } @@ -311,7 +290,7 @@ grfon(dev) int unit = GRFUNIT(dev); struct grf_softc *gp; - gp = grfcd.cd_devs[unit]; + gp = grf_cd.cd_devs[unit]; /* * XXX: iteoff call relies on devices being in same order @@ -320,7 +299,7 @@ grfon(dev) */ iteoff(unit, 3); - return (*grfdev[gp->g_type].gd_mode) (gp, GM_GRFON, NULL); + return (*gp->sc_mode) (gp, GM_GRFON, NULL); } int @@ -331,11 +310,11 @@ grfoff(dev) struct grf_softc *gp; int error; - gp = grfcd.cd_devs[unit]; + gp = grf_cd.cd_devs[unit]; (void) grfunmap(dev, (caddr_t) 0, curproc); - error = (*grfdev[gp->g_type].gd_mode) (gp, GM_GRFOFF, NULL); + error = (*gp->sc_mode) (gp, GM_GRFOFF, NULL); /* XXX: see comment for iteoff above */ iteon(unit, 2); @@ -348,12 +327,11 @@ grfaddr(gp, off) struct grf_softc *gp; register int off; { - register struct grfmode *gm = &gp->curr_mode; + register struct grfmode *gm = gp->sc_grfmode; u_long addr; - if (off < mac68k_round_page(gm->fbsize + gm->fboff) ) { - addr = (u_long) (*grfdev[gp->g_type].gd_phys) (gp, gm->fbbase) - + off; + if (off < mac68k_round_page(gm->fbsize + gm->fboff)) { + addr = (u_long)(*gp->sc_phys)(gp, (vm_offset_t)gm->fbbase)+off; return mac68k_btop(addr); } /* bogus */ @@ -372,31 +350,30 @@ grfmap(dev, addrp, p) int len, error; int flags; - gp = grfcd.cd_devs[GRFUNIT(dev)]; + gp = grf_cd.cd_devs[GRFUNIT(dev)]; #ifdef DEBUG if (grfdebug & GDB_MMAP) - printf("grfmap(%d): addr %x\n", p->p_pid, *addrp); + printf("grfmap(%d): addr %p\n", p->p_pid, *addrp); #endif - len = mac68k_round_page(gp->curr_mode.fbsize + gp->curr_mode.fboff); + len = mac68k_round_page(gp->sc_grfmode->fbsize + gp->sc_grfmode->fboff); flags = MAP_SHARED | MAP_FIXED; *addrp = (caddr_t) mac68k_trunc_page( - NUBUS_VIRT_TO_PHYS((u_int) gp->curr_mode.fbbase)); + NUBUS_SLOT_TO_PADDR(gp->sc_slot->slot)); vn.v_type = VCHR; /* XXX */ vn.v_specinfo = &si; /* XXX */ vn.v_rdev = dev; /* XXX */ error = vm_mmap(&p->p_vmspace->vm_map, (vm_offset_t *) addrp, - (vm_size_t) len, VM_PROT_ALL, VM_PROT_ALL, flags, (caddr_t) & vn, - 0); + (vm_size_t) len, VM_PROT_ALL, VM_PROT_ALL, flags, (caddr_t) &vn, 0); /* Offset into page: */ - *addrp += (unsigned long) gp->curr_mode.fboff & 0xfff; + *addrp += (unsigned long) gp->sc_grfmode->fboff & 0xfff; #ifdef DEBUG if (grfdebug & GDB_MMAP) - printf("grfmap(%d): returning addr %x\n", p->p_pid, *addrp); + printf("grfmap(%d): returning addr %p\n", p->p_pid, *addrp); #endif return (error); @@ -412,17 +389,17 @@ grfunmap(dev, addr, p) vm_size_t size; int rv; - gp = grfcd.cd_devs[GRFUNIT(dev)]; + gp = grf_cd.cd_devs[GRFUNIT(dev)]; #ifdef DEBUG if (grfdebug & GDB_MMAP) - printf("grfunmap(%d): dev %x addr %x\n", p->p_pid, dev, addr); + printf("grfunmap(%d): dev %x addr %p\n", p->p_pid, dev, addr); #endif if (addr == 0) return (EINVAL);/* XXX: how do we deal with this? */ - size = round_page(gp->curr_mode.fbsize); + size = round_page(gp->sc_grfmode->fbsize); rv = vm_deallocate(&p->p_vmspace->vm_map, (vm_offset_t) addr, size); diff --git a/sys/arch/mac68k/dev/grf_iv.c b/sys/arch/mac68k/dev/grf_iv.c index 21907590532..53a98ce5bb0 100644 --- a/sys/arch/mac68k/dev/grf_iv.c +++ b/sys/arch/mac68k/dev/grf_iv.c @@ -1,4 +1,4 @@ -/* $NetBSD: grf_iv.c,v 1.10 1995/08/11 17:48:19 briggs Exp $ */ +/* $NetBSD: grf_iv.c,v 1.12 1996/05/19 22:27:06 scottr Exp $ */ /* * Copyright (c) 1995 Allen Briggs. All rights reserved. @@ -41,6 +41,7 @@ #include <sys/malloc.h> #include <sys/mman.h> #include <sys/proc.h> +#include <sys/systm.h> #include <machine/grfioctl.h> #include <machine/cpu.h> @@ -48,20 +49,29 @@ #include "nubus.h" #include "grfvar.h" -extern int grfiv_probe __P((struct grf_softc *sc, nubus_slot *ignore)); -extern int grfiv_init __P((struct grf_softc *sc)); -extern int grfiv_mode __P((struct grf_softc *sc, int cmd, void *arg)); - extern u_int32_t mac68k_vidlog; extern u_int32_t mac68k_vidphys; extern long videorowbytes; extern long videobitdepth; extern unsigned long videosize; -extern int -grfiv_probe(sc, slotinfo) - struct grf_softc *sc; - nubus_slot *slotinfo; +static int grfiv_mode __P((struct grf_softc *gp, int cmd, void *arg)); +static caddr_t grfiv_phys __P((struct grf_softc *gp, vm_offset_t addr)); +static int grfiv_match __P((struct device *, void *, void *)); +static void grfiv_attach __P((struct device *, struct device *, void *)); + +struct cfdriver intvid_cd = { + NULL, "intvid", DV_DULL +}; + +struct cfattach intvid_ca = { + sizeof(struct grfbus_softc), grfiv_match, grfiv_attach +}; + +static int +grfiv_match(pdp, match, auxp) + struct device *pdp; + void *match, *auxp; { static int internal_video_found = 0; @@ -69,30 +79,22 @@ grfiv_probe(sc, slotinfo) return 0; } - if ( (NUBUS_SLOT_TO_BASE(slotinfo->slot) <= mac68k_vidlog) - && (mac68k_vidlog < NUBUS_SLOT_TO_BASE(slotinfo->slot + 1))) { - internal_video_found++; - return 1; - } - - if (slotinfo->slot == NUBUS_INT_VIDEO_PSUEDO_SLOT) { - internal_video_found++; - return 1; - } - - return 0; + return 1; } -extern int -grfiv_init(sc) - struct grf_softc *sc; +static void +grfiv_attach(parent, self, aux) + struct device *parent, *self; + void *aux; { - struct grfmode *gm; - int i, j; + struct grfbus_softc *sc; + struct grfmode *gm; + + sc = (struct grfbus_softc *) self; sc->card_id = 0; - strcpy(sc->card_name, "Internal video"); + printf(": Internal Video\n"); gm = &(sc->curr_mode); gm->mode_id = 0; @@ -107,10 +109,11 @@ grfiv_init(sc) gm->fbbase = (caddr_t) mac68k_vidlog; gm->fboff = 0; - return 1; + /* Perform common video attachment. */ + grf_establish(sc, grfiv_mode, grfiv_phys); } -extern int +static int grfiv_mode(sc, cmd, arg) struct grf_softc *sc; int cmd; @@ -130,7 +133,7 @@ grfiv_mode(sc, cmd, arg) return EINVAL; } -extern caddr_t +static caddr_t grfiv_phys(gp, addr) struct grf_softc *gp; vm_offset_t addr; diff --git a/sys/arch/mac68k/dev/grf_mv.c b/sys/arch/mac68k/dev/grf_mv.c index a32fabb8bb7..a19390bc3c2 100644 --- a/sys/arch/mac68k/dev/grf_mv.c +++ b/sys/arch/mac68k/dev/grf_mv.c @@ -1,4 +1,4 @@ -/* $NetBSD: grf_mv.c,v 1.7 1995/08/24 04:27:16 briggs Exp $ */ +/* $NetBSD: grf_mv.c,v 1.11 1996/05/19 22:27:07 scottr Exp $ */ /* * Copyright (c) 1995 Allen Briggs. All rights reserved. @@ -40,19 +40,34 @@ #include <sys/malloc.h> #include <sys/mman.h> #include <sys/proc.h> +#include <sys/systm.h> -#include <machine/grfioctl.h> #include <machine/cpu.h> +#include <machine/grfioctl.h> +#include <machine/viareg.h> #include "nubus.h" #include "grfvar.h" -extern int grfmv_probe __P((struct grf_softc *gp, nubus_slot *slot)); -extern int grfmv_init __P((struct grf_softc *gp)); -extern int grfmv_mode __P((struct grf_softc *gp, int cmd, void *arg)); +static void load_image_data __P((caddr_t data, struct image_data *image)); +static void grfmv_intr __P((void *vsc, int slot)); +static int get_vrsrcid __P((nubus_slot *slot)); static char zero = 0; +static int grfmv_mode __P((struct grf_softc *gp, int cmd, void *arg)); +static caddr_t grfmv_phys __P((struct grf_softc *gp, vm_offset_t addr)); +static int grfmv_match __P((struct device *, void *, void *)); +static void grfmv_attach __P((struct device *, struct device *, void *)); + +struct cfdriver macvid_cd = { + NULL, "macvid", DV_DULL +}; + +struct cfattach macvid_ca = { + sizeof(struct grfbus_softc), grfmv_match, grfmv_attach +}; + static void load_image_data(data, image) caddr_t data; @@ -77,15 +92,17 @@ load_image_data(data, image) bcopy(data + 42, &image->planeBytes, 4); } +/*ARGSUSED*/ static void -grfmv_intr(sc, slot) - struct grf_softc *sc; +grfmv_intr(vsc, slot) + void *vsc; int slot; { - struct grf_softc *gp; - caddr_t slotbase; + caddr_t slotbase; + struct grfbus_softc *sc; - slotbase = (caddr_t) NUBUS_SLOT_TO_BASE(slot); + sc = (struct grfbus_softc *) vsc; + slotbase = (caddr_t) sc->sc_slot.virtual_base; slotbase[0xa0000] = zero; } @@ -94,7 +111,6 @@ get_vrsrcid(slot) nubus_slot *slot; { extern u_short mac68k_vrsrc_vec[]; -extern int mac68k_vrsrc_cnt; int i; for (i = 0 ; i < 6 ; i++) @@ -103,16 +119,19 @@ extern int mac68k_vrsrc_cnt; return 0x80; } -extern int -grfmv_probe(sc, slot) - struct grf_softc *sc; - nubus_slot *slot; +static int +grfmv_match(parent, self, aux) + struct device *parent; + void *self, *aux; { - nubus_dir dir, *dirp, dir2, *dirp2; + struct grfbus_softc *sc; + nubus_slot *slot = (nubus_slot *) aux; + nubus_dir dir, *dirp, *dirp2; nubus_dirent dirent, *direntp; nubus_type slottype; int vrsrc; + sc = (struct grfbus_softc *) self; /* XXX: indirect brokenness */ dirp = &dir; direntp = &dirent; nubus_get_main_dir(slot, dirp); @@ -154,61 +173,79 @@ grfmv_probe(sc, slot) sc->card_id = slottype.drhw; + sc->sc_slot = *slot; + /* Need to load display info (and driver?), etc... */ return 1; } -extern int -grfmv_init(sc) - struct grf_softc *sc; +static void +grfmv_attach(parent, self, aux) + struct device *parent, *self; + void *aux; { + struct grfbus_softc *sc; struct image_data image_store, image; + struct grfmode *gm; + char cardname[CARD_NAME_LEN]; nubus_dirent dirent; nubus_dir mode_dir; int mode; - u_long base; + + sc = (struct grfbus_softc *) self; + gm = &sc->curr_mode; mode = NUBUS_RSRC_FIRSTMODE; - if (nubus_find_rsrc(&sc->sc_slot, &sc->board_dir, mode, &dirent) <= 0) - return 0; + if (nubus_find_rsrc(&sc->sc_slot, &sc->board_dir, mode, &dirent) <= 0) { + printf("\n%s: probe failed to get board rsrc.\n", + sc->sc_dev.dv_xname); + return; + } nubus_get_dir_from_rsrc(&sc->sc_slot, &dirent, &mode_dir); - if (nubus_find_rsrc(&sc->sc_slot, &mode_dir, VID_PARAMS, &dirent) <= 0) - return 0; + if (nubus_find_rsrc(&sc->sc_slot, &mode_dir, VID_PARAMS, &dirent) + <= 0) { + printf("\n%s: probe failed to get mode dir.\n", + sc->sc_dev.dv_xname); + return; + } if (nubus_get_ind_data(&sc->sc_slot, &dirent, (caddr_t) &image_store, - sizeof(struct image_data)) <= 0) - return 0; + sizeof(struct image_data)) <= 0) { + printf("\n%s: probe failed to get indirect mode data.\n", + sc->sc_dev.dv_xname); + return; + } load_image_data((caddr_t) &image_store, &image); - base = NUBUS_SLOT_TO_BASE(sc->sc_slot.slot); - - sc->curr_mode.mode_id = mode; - sc->curr_mode.fbbase = (caddr_t) (base + image.offset); - sc->curr_mode.fboff = image.offset; - sc->curr_mode.rowbytes = image.rowbytes; - sc->curr_mode.width = image.right - image.left; - sc->curr_mode.height = image.bottom - image.top; - sc->curr_mode.fbsize = sc->curr_mode.height * sc->curr_mode.rowbytes; - sc->curr_mode.hres = image.hRes; - sc->curr_mode.vres = image.vRes; - sc->curr_mode.ptype = image.pixelType; - sc->curr_mode.psize = image.pixelSize; - - strncpy(sc->card_name, nubus_get_card_name(&sc->sc_slot), + gm->mode_id = mode; + gm->fbbase = (caddr_t) (sc->sc_slot.virtual_base + image.offset); + gm->fboff = image.offset; + gm->rowbytes = image.rowbytes; + gm->width = image.right - image.left; + gm->height = image.bottom - image.top; + gm->fbsize = sc->curr_mode.height * sc->curr_mode.rowbytes; + gm->hres = image.hRes; + gm->vres = image.vRes; + gm->ptype = image.pixelType; + gm->psize = image.pixelSize; + + strncpy(cardname, nubus_get_card_name(&sc->sc_slot), CARD_NAME_LEN); + cardname[CARD_NAME_LEN-1] = '\0'; - sc->card_name[CARD_NAME_LEN-1] = '\0'; + printf(": %s\n", cardname); add_nubus_intr(sc->sc_slot.slot, grfmv_intr, sc); - return 1; + /* Perform common video attachment. */ + grf_establish(sc, grfmv_mode, grfmv_phys); } -extern int +static int grfmv_mode(gp, cmd, arg) struct grf_softc *gp; int cmd; @@ -228,10 +265,11 @@ grfmv_mode(gp, cmd, arg) return EINVAL; } -extern caddr_t +static caddr_t grfmv_phys(gp, addr) struct grf_softc *gp; vm_offset_t addr; { - return (caddr_t) NUBUS_VIRT_TO_PHYS(addr); + return (caddr_t) (NUBUS_SLOT_TO_PADDR(gp->sc_slot->slot) + + (addr - gp->sc_slot->virtual_base)); } diff --git a/sys/arch/mac68k/dev/grfvar.h b/sys/arch/mac68k/dev/grfvar.h index 2679e253478..cd60da3c9af 100644 --- a/sys/arch/mac68k/dev/grfvar.h +++ b/sys/arch/mac68k/dev/grfvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: grfvar.h,v 1.8 1995/07/06 17:13:51 briggs Exp $ */ +/* $NetBSD: grfvar.h,v 1.10 1996/05/19 22:27:10 scottr Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -43,20 +43,47 @@ */ #define CARD_NAME_LEN 64 -/* per display info */ -struct grf_softc { + +/* + * State info, per hardware instance. + */ +struct grfbus_softc { struct device sc_dev; nubus_slot sc_slot; - char card_name[CARD_NAME_LEN]; struct grfmode curr_mode; /* hardware desc(for ioctl) */ - u_int32_t g_flags; /* software flags */ - u_int32_t g_type; /* index into grfdev */ u_int16_t card_id; /* DrHW value for nubus cards */ nubus_dir board_dir; /* Nubus dir for curr board */ - caddr_t g_data; /* device dependent data */ }; +/* + * State info, per grf instance. + */ +struct grf_softc { + struct device sc_dev; /* device glue */ + + int sc_flags; /* software flags */ + struct grfmode *sc_grfmode; /* forwarded ... */ + nubus_slot *sc_slot; + /* mode-change on/off/mode function */ + int (*sc_mode) __P((struct grf_softc *, int, void *)); + /* map virtual addr to physical addr */ + caddr_t (*sc_phys) __P((struct grf_softc *, vm_offset_t)); +}; + +/* + * Attach grf and ite semantics to Mac video hardware. + */ +struct grfbus_attach_args { + char *ga_name; /* name of semantics to attach */ + struct grfmode *ga_grfmode; /* forwarded ... */ + nubus_slot *ga_slot; + int (*ga_mode) __P((struct grf_softc *, int, void *)); + caddr_t (*ga_phys) __P((struct grf_softc *, vm_offset_t)); +}; + +typedef caddr_t (*grf_phys_t) __P((struct grf_softc *gp, vm_offset_t addr)); + /* flags */ #define GF_ALIVE 0x01 #define GF_OPEN 0x02 @@ -65,19 +92,6 @@ struct grf_softc { #define GF_BSDOPEN 0x10 #define GF_HPUXOPEN 0x20 -/* display types - indices into grfdev */ -#define GT_MACVIDEO 0 -#define GT_INTERNALVIDEO 1 - -struct grfdev { - int gd_softid; /* DrSW */ - int (*gd_probe)(); /* probe routine */ - int (*gd_init) (); /* boot time initialization */ - int (*gd_mode) (); /* mode-change on/off/mode function */ - char *gd_desc; /* text description */ - caddr_t (*gd_phys) (); /* map virtual addr to physical addr */ -}; - /* requests to mode routine */ #define GM_GRFON 1 #define GM_GRFOFF 2 @@ -117,3 +131,19 @@ struct image_data { #define VID_TABLE_OFFSET 2 #define VID_PAGE_CNT 3 #define VID_DEV_TYPE 4 + +int grfopen __P((dev_t dev, int flag, int mode, struct proc *p)); +int grfclose __P((dev_t dev, int flag, int mode, struct proc *p)); +int grfioctl __P((dev_t, int, caddr_t, int, struct proc *p)); +int grfselect __P((dev_t dev, int rw, struct proc *p)); +int grfmmap __P((dev_t dev, int off, int prot)); +int grfon __P((dev_t dev)); +int grfoff __P((dev_t dev)); +int grfaddr __P((struct grf_softc *gp, register int off)); +int grfmap __P((dev_t dev, caddr_t *addrp, struct proc *p)); +int grfunmap __P((dev_t dev, caddr_t addr, struct proc *p)); + +void grf_establish __P((struct grfbus_softc *, + int (*)(struct grf_softc *, int, void *), + caddr_t (*)(struct grf_softc *, vm_offset_t))); +int grfbusprint __P((void *, char *)); diff --git a/sys/arch/mac68k/dev/if_ae.c b/sys/arch/mac68k/dev/if_ae.c index 0897e54dfec..c30bdc49a9b 100644 --- a/sys/arch/mac68k/dev/if_ae.c +++ b/sys/arch/mac68k/dev/if_ae.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ae.c,v 1.40 1996/02/02 15:30:56 briggs Exp $ */ +/* $NetBSD: if_ae.c,v 1.46 1996/05/15 03:20:22 briggs Exp $ */ /* * Device driver for National Semiconductor DS8390/WD83C690 based ethernet @@ -51,7 +51,7 @@ #include <net/bpfdesc.h> #endif -#include "../mac68k/via.h" +#include <machine/viareg.h> #include "nubus.h" #include <dev/ic/dp8390reg.h> #include "if_aereg.h" @@ -98,12 +98,15 @@ struct ae_softc { u_char next_packet; /* pointer to next unread RX packet */ }; +static int ae_id_card __P((nubus_slot *slot, struct ae_softc *sc)); +static int ae_size_card_memory __P((struct ae_softc *sc)); + int aeprobe __P((struct device *, void *, void *)); void aeattach __P((struct device *, struct device *, void *)); -void aeintr __P((void *)); +void aeintr __P((void *, int)); int aeioctl __P((struct ifnet *, u_long, caddr_t)); void aestart __P((struct ifnet *)); -void aewatchdog __P(( /* short */ )); +void aewatchdog __P((struct ifnet *)); void aereset __P((struct ae_softc *)); void aeinit __P((struct ae_softc *)); void aestop __P((struct ae_softc *)); @@ -119,10 +122,14 @@ void ae_getmcaf __P((struct arpcom *, u_char *)); static inline void ae_rint __P((struct ae_softc *)); static inline void ae_xmit __P((struct ae_softc *)); static inline caddr_t ae_ring_copy __P(( - /* struct ae_softc *, caddr_t, caddr_t, u_short */ )); + struct ae_softc *, caddr_t, caddr_t, int)); + +struct cfattach ae_ca = { + sizeof(struct ae_softc), aeprobe, aeattach +}; -struct cfdriver aecd = { - NULL, "ae", aeprobe, aeattach, DV_IFNET, sizeof(struct ae_softc) +struct cfdriver ae_cd = { + NULL, "ae", DV_IFNET }; #define ETHER_MIN_LEN 64 @@ -130,7 +137,6 @@ struct cfdriver aecd = { #define ETHER_ADDR_LEN 6 static char zero = 0; -static u_char ones = 0xff; /* * XXX These two should be moved to locore, and maybe changed to use shorts @@ -138,6 +144,10 @@ static u_char ones = 0xff; * which the ethernet cards can't handle. */ +void bszero __P((u_short *addr, int len)); +static inline void word_copy __P((caddr_t a, caddr_t b, int len)); +static inline void byte_copy __P((caddr_t a, caddr_t b, int len)); + void bszero(u_short * addr, int len) { @@ -228,6 +238,7 @@ ae_id_card(slot, sc) } break; default: + printf("Unknown ethernet drsw: %x\n", slottype.drsw); sc->vendor = AE_VENDOR_UNKNOWN; return 0; } @@ -239,13 +250,12 @@ ae_id_card(slot, sc) return 1; } -int +static int ae_size_card_memory(sc) struct ae_softc *sc; { u_short *p; u_short i1, i2, i3, i4; - int size; p = (u_short *) sc->mem_start; @@ -294,15 +304,17 @@ aeprobe(parent, match, aux) sc->regs_rev = 0; - addr = (caddr_t) NUBUS_SLOT_TO_BASE(nu->slot); + addr = (caddr_t) nu->virtual_base; switch (sc->vendor) { case AE_VENDOR_INTERLAN: sc->nic_addr = addr + GC_NIC_OFFSET; sc->rom_addr = addr + GC_ROM_OFFSET; sc->mem_start = addr + GC_DATA_OFFSET; - if ((memsize = ae_size_card_memory(sc)) == 0) + if ((memsize = ae_size_card_memory(sc)) == 0) { + printf("Failed to determine size of RAM.\n"); return 0; + } /* reset the NIC chip */ *((caddr_t) addr + GC_RESET_OFFSET) = (char) zero; @@ -319,8 +331,10 @@ aeprobe(parent, match, aux) sc->nic_addr = addr + AE_NIC_OFFSET; sc->rom_addr = addr + AE_ROM_OFFSET; sc->mem_start = addr + AE_DATA_OFFSET; - if ((memsize = ae_size_card_memory(sc)) == 0) + if ((memsize = ae_size_card_memory(sc)) == 0) { + printf("Failed to determine size of RAM.\n"); return (0); + } /* Get station address from on-board ROM */ for (i = 0; i < ETHER_ADDR_LEN; ++i) @@ -346,8 +360,10 @@ aeprobe(parent, match, aux) sc->rom_addr = addr + FE_ROM_OFFSET; sc->nic_addr = addr + AE_NIC_OFFSET; sc->mem_start = addr + AE_DATA_OFFSET; - if ((memsize = ae_size_card_memory(sc)) == 0) + if ((memsize = ae_size_card_memory(sc)) == 0) { + printf("Failed to determine size of RAM.\n"); return (0); + } /* Get station address from on-board ROM */ for (i = 0; i < ETHER_ADDR_LEN; ++i) @@ -381,7 +397,7 @@ aeprobe(parent, match, aux) for (i = 0; i < memsize; ++i) if (sc->mem_start[i]) { - printf("%s: failed to clear shared memory at %x - check configuration\n", +printf("%s: failed to clear shared memory at %p - check configuration\n", sc->sc_dev.dv_xname, sc->mem_start + i); return (0); @@ -401,16 +417,14 @@ aeattach(parent, self, aux) void *aux; { struct ae_softc *sc = (void *) self; - struct nubus_hw *nu = aux; - struct cfdata *cf = sc->sc_dev.dv_cfdata; struct ifnet *ifp = &sc->sc_arpcom.ac_if; /* Set interface to stopped condition (reset). */ aestop(sc); /* Initialize ifnet structure. */ - ifp->if_unit = sc->sc_dev.dv_unit; - ifp->if_name = aecd.cd_name; + bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); + ifp->if_softc = sc; ifp->if_start = aestart; ifp->if_ioctl = aeioctl; ifp->if_watchdog = aewatchdog; @@ -424,7 +438,7 @@ aeattach(parent, self, aux) /* Print additional info when attached. */ printf(": address %s, ", ether_sprintf(sc->sc_arpcom.ac_enaddr)); - printf("type %s, %dk mem.\n", sc->type_str, sc->mem_size / 1024); + printf("type %s, %ldk mem.\n", sc->type_str, sc->mem_size / 1024); #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); @@ -482,11 +496,12 @@ aestop(sc) * an interrupt after a transmit has been started on it. */ static int aeintr_ctr = 0; + void -aewatchdog(unit) - int unit; +aewatchdog(ifp) + struct ifnet *ifp; { - struct ae_softc *sc = aecd.cd_devs[unit]; + struct ae_softc *sc = ifp->if_softc; #if 1 /* @@ -498,10 +513,11 @@ aewatchdog(unit) i = aeintr_ctr; - (*via2itab[1]) (1); + (*via2itab[1]) ((void *) 1); if (i != aeintr_ctr) { - log(LOG_ERR, "ae%d: device timeout, recovered\n", unit); + log(LOG_ERR, "%s: device timeout, recovered\n", + sc->sc_dev.dv_xname); return; } #endif @@ -521,7 +537,6 @@ aeinit(sc) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; int i; - u_char command; u_char mcaf[8]; /* @@ -674,7 +689,7 @@ void aestart(ifp) struct ifnet *ifp; { - struct ae_softc *sc = aecd.cd_devs[ifp->if_unit]; + struct ae_softc *sc = ifp->if_softc; struct mbuf *m0; caddr_t buffer; int len; @@ -848,8 +863,9 @@ loop: /* Ethernet interface interrupt processor. */ void -aeintr(arg) - void *arg; +aeintr(arg, slot) + void *arg; + int slot; { struct ae_softc *sc = arg; struct ifnet *ifp = &sc->sc_arpcom.ac_if; @@ -1021,7 +1037,7 @@ aeioctl(ifp, cmd, data) u_long cmd; caddr_t data; { - struct ae_softc *sc = aecd.cd_devs[ifp->if_unit]; + struct ae_softc *sc = ifp->if_softc; register struct ifaddr *ifa = (struct ifaddr *) data; struct ifreq *ifr = (struct ifreq *) data; int s, error = 0; @@ -1170,7 +1186,7 @@ static inline caddr_t ae_ring_copy(sc, src, dst, amount) struct ae_softc *sc; caddr_t src, dst; - u_short amount; + int amount; { u_short tmp_amount; @@ -1232,7 +1248,7 @@ aeget(sc, src, total_len) len = MCLBYTES; } m->m_len = len = min(total_len, len); - src = ae_ring_copy(sc, src, mtod(m, caddr_t), len); + src = ae_ring_copy(sc, src, mtod(m, caddr_t), (int) len); total_len -= len; *mp = m; mp = &m->m_next; diff --git a/sys/arch/mac68k/dev/if_sn.c b/sys/arch/mac68k/dev/if_sn.c index 3a6051a1176..d5d2d571957 100644 --- a/sys/arch/mac68k/dev/if_sn.c +++ b/sys/arch/mac68k/dev/if_sn.c @@ -47,7 +47,9 @@ typedef unsigned char uchar; #include <machine/cpu.h> +#include <machine/viareg.h> #include <mac68k/dev/if_sn.h> + #define SWR(a, x) (a) = (x) #define SRD(a) ((a) & 0xffff) @@ -84,9 +86,9 @@ struct sn_stats { struct sn_softc { struct device sc_dev; - struct arpcom sc_ac; -#define sc_if sc_ac.ac_if /* network visible interface */ -#define sc_enaddr sc_ac.ac_enaddr /* hardware ethernet address */ + struct arpcom sc_arpcom; +#define sc_if sc_arpcom.ac_if /* network visible interface */ +#define sc_enaddr sc_arpcom.ac_enaddr /* hardware ethernet address */ struct sonic_reg *sc_csr; /* hardware pointer */ int sc_rxmark; /* position in rx ring for reading buffs */ @@ -105,11 +107,26 @@ struct sn_softc { short sc_iflags; } sn_softc; -int snmatch __P((struct device *, void *, void *)); -void snattach __P((struct device *, struct device *, void *)); +static void snwatchdog __P((struct ifnet *)); +static int snmatch __P((struct device *, void *, void *)); +static void snattach __P((struct device *, struct device *, void *)); +static int sngetaddr __P((struct sn_softc *sc)); +static int sninit __P((struct sn_softc *sc)); +static int snstop __P((struct sn_softc *sc)); +static int sonicput __P((struct sn_softc *sc, struct mbuf *m0)); +static int snintr __P((struct sn_softc *, int)); +static int snioctl __P((struct ifnet *ifp, u_long cmd, caddr_t data)); +static void snstart __P((struct ifnet *ifp)); +static void snreset __P((struct sn_softc *sc)); + +void camdump __P((struct sn_softc *sc)); + +struct cfattach sn_ca = { + sizeof(struct sn_softc), snmatch, snattach +}; -struct cfdriver sncd = { - NULL, "sn", snmatch, snattach, DV_IFNET, sizeof(struct sn_softc) +struct cfdriver sn_cd = { + NULL, "sn", DV_IFNET }; #include <assert.h> @@ -123,49 +140,8 @@ __assert(file, line, failedexpr) failedexpr, file, line); } -void -m_check(m) - struct mbuf *m; -{ - if (m->m_flags & M_EXT) { - assert(m->m_len >= 0); - assert(m->m_len <= m->m_ext.ext_size); - assert(m->m_data >= &m->m_ext.ext_buf[0]); - assert(m->m_data <= &m->m_ext.ext_buf[m->m_ext.ext_size]); - assert(m->m_data + m->m_len <= &m->m_ext.ext_buf[m->m_ext.ext_size]); - } else if (m->m_flags & M_PKTHDR) { - assert(m->m_len >= 0); - assert(m->m_len <= MHLEN); - assert(m->m_data >= m->m_pktdat); - assert(m->m_data <= &m->m_pktdat[MHLEN]); - assert(m->m_data + m->m_len <= &m->m_pktdat[MHLEN]); - } else { - assert(m->m_len >= 0); - assert(m->m_len <= MLEN); - assert(m->m_data >= m->m_dat); - assert(m->m_data <= &m->m_dat[MLEN]); - assert(m->m_data + m->m_len <= &m->m_dat[MLEN]); - } -} - -void -m_checkm(m) - struct mbuf *m; -{ - while (m) { - m_check(m); - m = m->m_next; - } -} - int ethdebug = 0; -int snintr __P((struct sn_softc *)); -int snioctl __P((struct ifnet *ifp, u_long cmd, caddr_t data)); -void snstart __P((struct ifnet *ifp)); -void snwatchdog __P(( /*int unit */ )); -void snreset __P((struct sn_softc *sc)); - /* * SONIC buffers need to be aligned 16 or 32 bit aligned. * These macros calculate and verify alignment. @@ -247,24 +223,11 @@ struct mtd *mtdnext; /* next descriptor to give to chip */ void mtd_free __P((struct mtd *)); struct mtd *mtd_alloc __P((void)); -int sngetaddr __P((struct sn_softc *sc)); -int sninit __P((int unit)); -int snstop __P((int unit)); -int sonicput __P((struct sn_softc *sc, struct mbuf *m0)); - -void camdump __P((struct sn_softc *sc)); - -int +static int snmatch(parent, match, aux) struct device *parent; void *match, *aux; { - struct cfdata *cf = match; - struct confargs *ca = aux; - - if (matchbyname(parent, cf, aux) == 0) - return 0; - if (!mac68k_machine.sonic) return 0; @@ -276,7 +239,7 @@ snmatch(parent, match, aux) * record. System will initialize the interface when it is ready * to accept packets. */ -void +static void snattach(parent, self, aux) struct device *parent, *self; void *aux; @@ -284,15 +247,13 @@ snattach(parent, self, aux) extern unsigned char SONICSPACE; extern unsigned long SONICSPACE_size; struct sn_softc *sc = (void *)self; - struct confargs *ca = aux; struct ifnet *ifp = &sc->sc_if; - struct cfdata *cf = sc->sc_dev.dv_cfdata; int base, p, pp; /* Must allocate extra memory in case we need to round later. */ pp = (DESC_SIZE + NRBA*RBASIZE + 0x10000 + 4 + TBASIZE); if (pp != SONICSPACE_size) { - printf(": SONICSPACE_size (%d) != pp (%d). Punt!\n", + printf(": SONICSPACE_size (%ld) != pp (%d). Punt!\n", SONICSPACE_size, pp); return; } @@ -351,11 +312,8 @@ printf("sonic buffers: rra=0x%x cda=0x%x rda=0x%x tda=0x%x rba=0x%x tba=0x%x\n", p_rra, p_cda, p_rda, p_tda, p_rba, p_tba); #endif - add_nubus_intr(9, snintr, (void *) sc); - enable_nubus_intr(); - - ifp->if_name = "sn"; - ifp->if_unit = sc->sc_dev.dv_unit; + bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); + ifp->if_softc = sc; ifp->if_ioctl = snioctl; ifp->if_start = snstart; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -365,18 +323,21 @@ printf("sonic buffers: rra=0x%x cda=0x%x rda=0x%x tda=0x%x rba=0x%x tba=0x%x\n", #endif if_attach(ifp); ether_ifattach(ifp); + + add_nubus_intr(9, (void (*) __P((void *, int))) snintr, (void *) sc); + enable_nubus_intr(); } -int +static int snioctl(ifp, cmd, data) struct ifnet *ifp; u_long cmd; caddr_t data; { struct ifaddr *ifa; - struct sn_softc *sc = sncd.cd_devs[ifp->if_unit]; + struct sn_softc *sc = ifp->if_softc; int s = splnet(), err = 0; - int temp; + int temp, error; if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) { splx(s); @@ -391,12 +352,12 @@ snioctl(ifp, cmd, data) switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: - (void)sninit(ifp->if_unit); - arp_ifinit(&sc->sc_ac, ifa); + (void)sninit(ifp->if_softc); + arp_ifinit(&sc->sc_arpcom, ifa); break; #endif default: - (void)sninit(ifp->if_unit); + (void)sninit(ifp->if_softc); break; } break; @@ -404,11 +365,11 @@ snioctl(ifp, cmd, data) case SIOCSIFFLAGS: if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) { - snstop(ifp->if_unit); + snstop(ifp->if_softc); ifp->if_flags &= ~IFF_RUNNING; } else if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0) - (void)sninit(ifp->if_unit); + (void)sninit(ifp->if_softc); /* * If the state of the promiscuous bit changes, the interface * must be reset to effect the change. @@ -427,9 +388,11 @@ snioctl(ifp, cmd, data) case SIOCADDMULTI: case SIOCDELMULTI: if(cmd == SIOCADDMULTI) - err = ether_addmulti((struct ifreq *)data, &sc->sc_ac); + err = ether_addmulti((struct ifreq *)data, + &sc->sc_arpcom); else - err = ether_delmulti((struct ifreq *)data, &sc->sc_ac); + err = ether_delmulti((struct ifreq *)data, + &sc->sc_arpcom); if (err == ENETRESET) { /* @@ -454,11 +417,11 @@ snioctl(ifp, cmd, data) * Use trailer local net encapsulation if enough data in first * packet leaves a multiple of 512 bytes of data in remainder. */ -void +static void snstart(ifp) struct ifnet *ifp; { - struct sn_softc *sc = sncd.cd_devs[ifp->if_unit]; + struct sn_softc *sc = ifp->if_softc; struct mbuf *m; int len; @@ -534,22 +497,21 @@ void initialise_tba __P((struct sn_softc *)); * reset and restart the SONIC. Called in case of fatal * hardware/software errors. */ -void +static void snreset(sc) struct sn_softc *sc; { printf("snreset\n"); - snstop(sc->sc_dev.dv_unit); - sninit(sc->sc_dev.dv_unit); + snstop(sc); + sninit(sc); } -int -sninit(unit) - int unit; +static int +sninit(sc) + struct sn_softc *sc; { - struct sn_softc *sc = sncd.cd_devs[unit]; struct sonic_reg *csr = sc->sc_csr; - int s, error; + int s; if (sc->sc_if.if_flags & IFF_RUNNING) /* already running */ @@ -602,10 +564,6 @@ sninit(unit) splx(s); return (0); - -bad: - snstop(sc->sc_dev.dv_unit); - return (error); } /* @@ -613,11 +571,10 @@ bad: * Called on final close of device, or if sninit() fails * part way through. */ -int -snstop(unit) - int unit; +static int +snstop(sc) + struct sn_softc *sc; { - struct sn_softc *sc = sncd.cd_devs[unit]; struct mtd *mtd; int s = splnet(); @@ -628,7 +585,7 @@ snstop(unit) /* free all receive buffers (currently static so nothing to do) */ /* free all pending transmit mbufs */ - while (mtd = mtdhead) { + while ((mtd = mtdhead) != NULL) { mtdhead = mtdhead->mtd_link; mtd->mtd_buf = 0; mtd_free(mtd); @@ -648,21 +605,21 @@ snstop(unit) * In all cases we just reset the chip, and any retransmission * will be handled by higher level protocol timeouts. */ -void -snwatchdog(unit) - int unit; +static void +snwatchdog(ifp) + struct ifnet *ifp; { - struct sn_softc *sc = sncd.cd_devs[unit]; + struct sn_softc *sc = ifp->if_softc; int temp; if (mtdhead && mtdhead->mtd_buf) { /* something still pending for transmit */ if (mtdhead->mtd_txp->status == 0) - log(LOG_ERR, "%s%d: Tx - timeout\n", - sc->sc_if.if_name, sc->sc_if.if_unit); + log(LOG_ERR, "%s: Tx - timeout\n", + sc->sc_dev.dv_xname); else - log(LOG_ERR, "%s%d: Tx - lost interrupt\n", - sc->sc_if.if_name, sc->sc_if.if_unit); + log(LOG_ERR, "%s: Tx - lost interrupt\n", + sc->sc_dev.dv_xname); temp = sc->sc_if.if_flags & IFF_UP; snreset(sc); sc->sc_if.if_flags |= temp; @@ -672,7 +629,7 @@ snwatchdog(unit) /* * stuff packet into sonic (at splnet) */ -int +static int sonicput(sc, m0) struct sn_softc *sc; struct mbuf *m0; @@ -682,7 +639,7 @@ sonicput(sc, m0) struct TXpkt *txp; struct mtd *mtdnew; struct mbuf *m; - int i, len = 0, totlen = 0; + int len = 0, totlen = 0; /* grab the replacement mtd */ if ((mtdnew = mtd_alloc()) == 0) @@ -753,12 +710,11 @@ printf("Padding %d to %d bytes\n", totlen, totlen+pad); * there by the boot when doing a loopback test. Thus we don't * have to fetch it from nv ram. */ -int +static int sngetaddr(sc) struct sn_softc *sc; { - unsigned i, x, y; - char *cp, *ea; + unsigned i; sc->sc_csr->s_cr = CR_RST; wbflush(); @@ -838,7 +794,6 @@ camprogram(sc) { struct sonic_reg *csr; int timeout; - int i; csr = sc->sc_csr; csr->s_cdp = LOWER(p_cda); @@ -972,21 +927,20 @@ void initialise_tba(sc) struct sn_softc *sc; { - int i; - sc->txb_cnt = NTXB; sc->txb_inuse = 0; sc->txb_new = 0; } -int -snintr(sc) +static int +snintr(sc, slot) struct sn_softc *sc; + int slot; { struct sonic_reg *csr = sc->sc_csr; int isr; - while (isr = (csr->s_isr & ISR_ALL)) { + while ((isr = (csr->s_isr & ISR_ALL)) != 0) { printf("snintr: %x.\n", isr); /* scrub the interrupts that we are going to service */ csr->s_isr = isr; @@ -1044,7 +998,7 @@ sonictxint(sc) csr = sc->sc_csr; - while (mtd = mtdhead) { + while ((mtd = mtdhead) != NULL) { if (mtd->mtd_buf == 0) break; @@ -1057,7 +1011,7 @@ sonictxint(sc) struct ether_header *eh; eh = (struct ether_header *) mtd->mtd_buf; - printf("xmit status=0x%x len=%d type=0x%x from %s", + printf("xmit status=0x%lx len=%ld type=0x%x from %s", txp->status, txp->pkt_size, htons(eh->ether_type), @@ -1073,7 +1027,7 @@ sonictxint(sc) /* XXX - Do stats here. */ if ((SRD(txp->status) & TCR_PTX) == 0) { - printf("sonic: Tx packet status=0x%x\n", txp->status); + printf("sonic: Tx packet status=0x%lx\n", txp->status); if (mtdhead != mtdnext) { printf("resubmitting remaining packets\n"); @@ -1099,7 +1053,6 @@ sonicrxint(sc) { struct sonic_reg *csr = sc->sc_csr; struct RXpkt *rxp; - u_long addr; int orra; rxp = &p_rda[sc->sc_rxmark]; @@ -1174,7 +1127,7 @@ sonic_read(sc, rxp) /*extern char *ether_sprintf();*/ struct ether_header *et; struct mbuf *m; - int len, off, i; + int len; caddr_t pkt; /* @@ -1190,7 +1143,7 @@ sonic_read(sc, rxp) et = (struct ether_header *)pkt; if (ethdebug) { - printf("rcvd 0x%x status=0x%x, len=%d type=0x%x from %s", + printf("rcvd 0x%p status=0x%lx, len=%d type=0x%x from %s", et, rxp->status, len, htons(et->ether_type), ether_sprintf(et->ether_shost)); printf(" (to %s)\n", ether_sprintf(et->ether_dhost)); @@ -1213,7 +1166,7 @@ sonic_read(sc, rxp) (et->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */ bcmp(et->ether_dhost, sc->sc_enaddr, sizeof(et->ether_dhost)) != 0) - return; + return (0); } #endif m = sonic_get(sc, et, len); diff --git a/sys/arch/mac68k/dev/ite.c b/sys/arch/mac68k/dev/ite.c index 1ce56c6efa4..434cc491879 100644 --- a/sys/arch/mac68k/dev/ite.c +++ b/sys/arch/mac68k/dev/ite.c @@ -1,4 +1,4 @@ -/* $NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp $ */ +/* $NetBSD: ite.c,v 1.22 1996/05/25 00:56:38 briggs Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -64,7 +64,7 @@ #include <sys/device.h> #include <dev/cons.h> -#include "../mac68k/via.h" +#include <machine/viareg.h> #include <machine/cpu.h> #include <machine/frame.h> @@ -73,10 +73,40 @@ #include <machine/adbsys.h> #include <machine/iteioctl.h> +#include "../mac68k/macrom.h" + +#include "ascvar.h" +#include "itevar.h" + #include "6x10.h" #define CHARWIDTH 6 #define CHARHEIGHT 10 +/* Local function prototypes */ +static inline void putpixel1 __P((int, int, int *, int)); +static void putpixel2 __P((int, int, int *, int)); +static void putpixel4 __P((int, int, int *, int)); +static void putpixel8 __P((int, int, int *, int)); +static void reversepixel1 __P((int, int, int)); +static void writechar __P((char, int, int, int)); +static void drawcursor __P((void)); +static void erasecursor __P((void)); +static void scrollup __P((void)); +static void scrolldown __P((void)); +static void clear_screen __P((int)); +static void clear_line __P((int)); +static void reset_tabs __P((void)); +static void vt100_reset __P((void)); +static void putc_normal __P((char)); +static void putc_esc __P((char)); +static void putc_gotpars __P((char)); +static void putc_getpars __P((char)); +static void putc_square __P((char)); +static void ite_putchar __P((char)); +static int ite_pollforchar __P((void)); +static int itematch __P((struct device *, void *, void *)); +static void iteattach __P((struct device *, struct device *, void *)); + #define dprintf if (0) printf #define ATTR_NONE 0 @@ -97,43 +127,48 @@ enum vt100state_e { ESignore /* Ignore this sequence */ } vt100state = ESnormal; -/* Received from MacBSDBoot, stored by Locore: */ -long videoaddr; -long videorowbytes; -long videobitdepth; -unsigned long videosize; +/* From Booter via locore */ +long videoaddr; +long videorowbytes; +long videobitdepth; +unsigned long videosize; -/* Calculated in itecninit(): */ -static int width, height, scrrows, scrcols; -static void (*putpixel) (int x, int y, int *c, int num); -static void (*reversepixel) (int x, int y, int num); +/* Calculated by itecninit() */ +static int ite_initted = 0; +static int width, height; /* width, height in pixels */ +static int scrcols, scrrows; /* width, height in characters */ +static int screenrowbytes; /* number of visible bytes per row */ -/* VT100 state: */ -#define MAXPARS 16 -static int x = 0, y = 0, savex, savey; -static int par[MAXPARS], numpars, hanging_cursor, attr; +/* VT100 emulation */ +#define MAXPARS 16 /* max number of VT100 op parameters */ +static int par[MAXPARS], numpars; /* parameter array, # of parameters */ +static int x = 0, y = 0; /* current VT100 cursor location */ +static int savex, savey; /* saved cursor location */ +static int hanging_cursor; /* cursor waiting for more output */ +static int attr; /* current video attribute */ +static char tab_stops[255]; /* tab stops */ +static int scrreg_top; /* scroll region */ +static int scrreg_bottom; -/* Our tty: */ -struct tty *ite_tty; +/* For polled ADB mode */ +static int polledkey; +extern int adb_polling; -/* For polled ADB mode: */ -static int polledkey; -extern int adb_polling; +struct tty *ite_tty; /* Our tty */ -/* Misc */ -void itestart(); -static void ite_putchar(char ch); +static void (*putpixel) __P((int x, int y, int *c, int num)); +static void (*reversepixel) __P((int x, int y, int num)); -/* VT100 tab stops & scroll region */ -static char tab_stops[255]; -static int scrreg_top, scrreg_bottom; /* * Bitmap handling functions */ static inline void -putpixel1(int xx, int yy, int *c, int num) +putpixel1(xx, yy, c, num) + int xx, yy; + int *c; + int num; { unsigned int i, mask; unsigned char *sc; @@ -151,7 +186,10 @@ putpixel1(int xx, int yy, int *c, int num) } static void -putpixel2(int xx, int yy, int *c, int num) +putpixel2(xx, yy, c, num) + int xx, yy; + int *c; + int num; { unsigned int i, mask; unsigned char *sc; @@ -169,7 +207,10 @@ putpixel2(int xx, int yy, int *c, int num) } static void -putpixel4(int xx, int yy, int *c, int num) +putpixel4(xx, yy, c, num) + int xx, yy; + int *c; + int num; { unsigned int i, mask; unsigned char *sc; @@ -187,7 +228,10 @@ putpixel4(int xx, int yy, int *c, int num) } static void -putpixel8(int xx, int yy, int *c, int num) +putpixel8(xx, yy, c, num) + int xx, yy; + int *c; + int num; { unsigned char *sc; @@ -201,7 +245,8 @@ putpixel8(int xx, int yy, int *c, int num) } static void -reversepixel1(int xx, int yy, int num) +reversepixel1(xx, yy, num) + int xx, yy, num; { unsigned int mask; unsigned char *sc; @@ -237,9 +282,11 @@ reversepixel1(int xx, int yy, int num) } static void -writechar(char ch, int x, int y, int attr) +writechar(ch, x, y, attr) + char ch; + int x, y, attr; { - int i, j, mask, rev, col[CHARHEIGHT]; + int i, j, mask, rev, col[CHARHEIGHT]; unsigned char *c; ch &= 0x7F; @@ -254,16 +301,14 @@ writechar(char ch, int x, int y, int attr) case 1: for (j = 0; j < CHARWIDTH; j++) { mask = 1 << (CHARWIDTH - 1 - j); - for (i = 0; i < CHARHEIGHT; i++) { + for (i = 0; i < CHARHEIGHT; i++) col[i] = ((c[i] & mask) ? 255 : 0) ^ rev; - } putpixel1(x + j, y, col, CHARHEIGHT); } if (attr & ATTR_UNDER) { col[0] = 255; - for (j = 0; j < CHARWIDTH; j++) { + for (j = 0; j < CHARWIDTH; j++) putpixel1(x + j, y + CHARHEIGHT - 1, col, 1); - } } break; case 2: @@ -271,116 +316,132 @@ writechar(char ch, int x, int y, int attr) case 8: for (j = 0; j < CHARWIDTH; j++) { mask = 1 << (CHARWIDTH - 1 - j); - for (i = 0; i < CHARHEIGHT; i++) { + for (i = 0; i < CHARHEIGHT; i++) col[i] = ((c[i] & mask) ? 255 : 0) ^ rev; - } putpixel(x + j, y, col, CHARHEIGHT); } if (attr & ATTR_UNDER) { col[0] = 255; - for (j = 0; j < CHARWIDTH; j++) { + for (j = 0; j < CHARWIDTH; j++) putpixel(x + j, y + CHARHEIGHT - 1, col, 1); - } } break; } } static void -drawcursor(void) +drawcursor() { - int j, X, Y; + unsigned int j, X, Y; X = x * CHARWIDTH; Y = y * CHARHEIGHT; - for (j = 0; j < CHARWIDTH; j++) { + for (j = 0; j < CHARWIDTH; j++) reversepixel(X + j, Y, CHARHEIGHT); - } } static void -erasecursor(void) +erasecursor() { - int j, X, Y; + unsigned int j, X, Y; X = x * CHARWIDTH; Y = y * CHARHEIGHT; - for (j = 0; j < CHARWIDTH; j++) { + for (j = 0; j < CHARWIDTH; j++) reversepixel(X + j, Y, CHARHEIGHT); - } } static void -scrollup(void) +scrollup() { - unsigned long *from, *to; - int i, linelongs, tocopy, copying; - linelongs = videorowbytes * CHARHEIGHT / 4; - - to = (unsigned long *) videoaddr + ((scrreg_top-1) * linelongs); - from = to + linelongs; - - tocopy = (scrreg_bottom - scrreg_top) * linelongs; - while (tocopy > 0) { - copying = (tocopy > 16383) ? 16383 : tocopy; - bcopy(from, to, copying * 4); - from += copying; - to += copying; - tocopy -= copying; + unsigned char *from, *to; + unsigned int linebytes; + unsigned short i; + + linebytes = videorowbytes * CHARHEIGHT; + to = (unsigned char *) videoaddr + ((scrreg_top - 1) * linebytes); + from = to + linebytes; + + for (i = (scrreg_bottom - scrreg_top) * CHARHEIGHT; i > 0; i--) { + ovbcopy(from, to, screenrowbytes); + from += videorowbytes; + to += videorowbytes; + } + for (i = CHARHEIGHT; i > 0; i--) { + bzero(to, screenrowbytes); + to += videorowbytes; } - to = (unsigned long *) videoaddr; - bzero(to + (scrreg_bottom - 1) * linelongs, linelongs * sizeof(long)); } static void -scrolldown(void) +scrolldown() { - unsigned long *from, *to; - int i, linelongs; - linelongs = videorowbytes * CHARHEIGHT / 4; - - to = (unsigned long *) videoaddr + linelongs * (scrreg_bottom); - from = to - linelongs; - - for (i = (scrreg_bottom - scrreg_top) * linelongs; i > 0; i--) { - *--to = *--from; + unsigned char *from, *to; + unsigned int linebytes; + unsigned short i; + + linebytes = videorowbytes * CHARHEIGHT; + to = (unsigned char *) videoaddr + (scrreg_bottom * linebytes); + from = to - linebytes; + + for (i = (scrreg_bottom - scrreg_top) * CHARHEIGHT; i > 0; i--) { + from -= videorowbytes; + to -= videorowbytes; + ovbcopy(from, to, screenrowbytes); } - for (i = linelongs; i > 0; i--) { - *--to = 0; + for (i = CHARHEIGHT; i > 0; i--) { + to -= videorowbytes; + bzero(to, screenrowbytes); } } static void -clear_screen(int which) +clear_screen(which) + int which; { - unsigned long *p; - int i, linelongs; + unsigned char *p; + unsigned short len, i; - p = (unsigned long *) videoaddr; - linelongs = videorowbytes * CHARHEIGHT / 4; + p = (unsigned char *) videoaddr; switch (which) { case 0: /* To end of screen */ - p += y * linelongs; - i = (scrrows - y) * linelongs; + if (x > 0) { + clear_line(0); + if (y < scrrows) + y++; + x = 0; + } + p += y * videorowbytes * CHARHEIGHT; + len = scrrows - y; break; case 1: /* To start of screen */ - i = y * linelongs; + if (x > 0) { + clear_line(1); + if (y > 0) + y--; + x = 0; + } + len = y; break; case 2: /* Whole screen */ - i = scrrows * linelongs; + len = scrrows; break; } - bzero(p, i * sizeof(long)); + for (i = len * CHARHEIGHT; i > 0; i--) { + bzero(p, screenrowbytes); + p += videorowbytes; + } } static void -clear_line(int which) +clear_line(which) + int which; { - int start, end, i; + int start, end, i; /* * This routine runs extremely slowly. I don't think it's @@ -390,6 +451,7 @@ clear_line(int which) */ switch (which) { + default: case 0: /* To end of line */ start = x; end = scrcols; @@ -404,31 +466,31 @@ clear_line(int which) break; } - for (i = start; i < end; i++) { + for (i = start; i < end; i++) writechar(' ', i, y, ATTR_NONE); - } } + static void -reset_tabs(void) +reset_tabs() { int i; - for (i = 0; i<= scrcols; i++) { + for (i = 0; i<= scrcols; i++) tab_stops[i] = ((i % 8) == 0); - } } static void -vt100_reset(void) +vt100_reset() { - reset_tabs; + reset_tabs(); scrreg_top = 1; scrreg_bottom = scrrows; attr = ATTR_NONE; } static void -putc_normal(char ch) +putc_normal(ch) + char ch; { switch (ch) { case '\a': /* Beep */ @@ -436,24 +498,22 @@ putc_normal(char ch) break; case 127: /* Delete */ case '\b': /* Backspace */ - if (hanging_cursor) { + if (hanging_cursor) hanging_cursor = 0; - } else - if (x > 0) { - x--; - } + else if (x > 0) + x--; break; case '\t': /* Tab */ do { ite_putchar(' '); - } while (tab_stops[x] = 0); + x++; + } while ((tab_stops[x] == 0) && (x < scrcols)); break; case '\n': /* Line feed */ - if (y == scrreg_bottom - 1) { + if (y == scrreg_bottom - 1) scrollup(); - } else { + else y++; - } break; case '\r': /* Carriage return */ x = 0; @@ -467,19 +527,19 @@ putc_normal(char ch) if (ch >= ' ') { if (hanging_cursor) { x = 0; - if (y == scrreg_bottom - 1) { + if (y == scrreg_bottom - 1) scrollup(); - } else { + else y++; - } hanging_cursor = 0; } + writechar(ch, x, y, attr); - if (x == scrcols - 1) { + + if (x == scrcols - 1) hanging_cursor = 1; - } else { + else x++; - } if (x >= scrcols) { /* can we ever get here? */ x = 0; y++; @@ -490,7 +550,8 @@ putc_normal(char ch) } static void -putc_esc(char ch) +putc_esc(ch) + char ch; { vt100state = ESnormal; @@ -499,21 +560,19 @@ putc_esc(char ch) vt100state = ESsquare; break; case 'D': /* Line feed */ - if (y == scrreg_bottom - 1) { + if (y == scrreg_bottom - 1) scrollup(); - } else { + else y++; - } break; case 'H': /* Set tab stop */ tab_stops[x] = 1; break; case 'M': /* Cursor up */ - if (y == scrreg_top - 1) { + if (y == scrreg_top - 1) scrolldown(); - } else { + else y--; - } break; case '>': vt100_reset(); @@ -533,31 +592,30 @@ putc_esc(char ch) } static void -putc_gotpars(char ch) +putc_gotpars(ch) + char ch; { - int i; + int i; vt100state = ESnormal; switch (ch) { case 'A': /* Up */ i = par[0]; do { - if (y == scrreg_top - 1) { + if (y == scrreg_top - 1) scrolldown(); - } else { + else y--; - }; i--; } while (i > 0); break; case 'B': /* Down */ i = par[0]; do { - if (y == scrreg_bottom - 1) { + if (y == scrreg_bottom - 1) scrollup(); - } else { + else y++; - }; i--; } while (i > 0); break; @@ -579,9 +637,8 @@ putc_gotpars(char ch) clear_line(par[0]); break; case 'g': /* Clear tab stops */ - if (numpars >= 1 && par[0] == 3) { + if (numpars >= 1 && par[0] == 3) reset_tabs(); - } break; case 'm': /* Set attribute */ for (i = 0; i < numpars; i++) { @@ -603,22 +660,21 @@ putc_gotpars(char ch) break; case 'r': /* Set scroll region */ /* ensure top < bottom, and both within limits */ - if ((numpars > 0) && (par[0] < scrrows)) { + if ((numpars > 0) && (par[0] < scrrows)) scrreg_top = par[0]; - } else { + else scrreg_top = 1; - } - if ((numpars > 1) && (par[1] <= scrrows) && (par[1] > par[0])) { + if ((numpars > 1) && (par[1] <= scrrows) && (par[1] > par[0])) scrreg_bottom = par[1]; - } else { + else scrreg_bottom = scrrows; - } break; } } static void -putc_getpars(char ch) +putc_getpars(ch) + char ch; { if (ch == '?') { /* Not supported */ @@ -629,27 +685,26 @@ putc_getpars(char ch) /* Not supported */ return; } - if (ch == ';' && numpars < MAXPARS - 1) { + if (ch == ';' && numpars < MAXPARS - 1) numpars++; - } else - if (ch >= '0' && ch <= '9') { - par[numpars] *= 10; - par[numpars] += ch - '0'; - } else { - numpars++; - vt100state = ESgotpars; - putc_gotpars(ch); - } + else if (ch >= '0' && ch <= '9') { + par[numpars] *= 10; + par[numpars] += ch - '0'; + } else { + numpars++; + vt100state = ESgotpars; + putc_gotpars(ch); + } } static void -putc_square(char ch) +putc_square(ch) + char ch; { - int i; + unsigned short i; - for (i = 0; i < MAXPARS; i++) { + for (i = 0; i < MAXPARS; i++) par[i] = 0; - } numpars = 0; vt100state = ESgetpars; @@ -658,10 +713,12 @@ putc_square(char ch) } static void -ite_putchar(char ch) +ite_putchar(ch) + char ch; { switch (vt100state) { - default:vt100state = ESnormal; /* FALLTHROUGH */ + default: + vt100state = ESnormal; /* FALLTHROUGH */ case ESnormal: putc_normal(ch); break; @@ -679,36 +736,25 @@ ite_putchar(char ch) break; } - if (x >= scrcols) { + if (x >= scrcols) x = scrcols - 1; - } - if (x < 0) { + if (x < 0) x = 0; - } - if (y >= scrrows) { + if (y >= scrrows) y = scrrows - 1; - } - if (y < 0) { + if (y < 0) y = 0; - } } + + /* * Keyboard support functions */ static int -ite_dopollkey(int key) +ite_pollforchar() { - polledkey = key; - - return 0; -} - - -static int -ite_pollforchar(void) -{ - int s; + int s; register int intbits; s = splhigh(); @@ -736,30 +782,56 @@ ite_pollforchar(void) return polledkey; } + + /* - * Tty handling functions + * Autoconfig attachment */ +struct cfattach ite_ca = { + sizeof(struct device), itematch, iteattach +}; + +struct cfdriver ite_cd = { + NULL, "ite", DV_TTY +}; + +static int +itematch(pdp, match, auxp) + struct device *pdp; + void *match, *auxp; +{ + return 1; +} + static void -iteattach(struct device * parent, struct device * dev, void *aux) +iteattach(parent, dev, aux) + struct device *parent, *dev; + void *aux; { printf(" (minimal console)\n"); } -extern int matchbyname(); -struct cfdriver itecd = { - NULL, "ite", matchbyname, iteattach, DV_TTY, sizeof(struct device) -}; +/* + * Tty handling functions + */ int -iteopen(dev_t dev, int mode, int devtype, struct proc * p) +iteopen(dev, mode, devtype, p) + dev_t dev; + int mode; + int devtype; + struct proc *p; { register struct tty *tp; register int error; - int first = 0; dprintf("iteopen(): enter(0x%x)\n", (int) dev); + + if (!ite_initted) + return (ENXIO); + if (ite_tty == NULL) tp = ite_tty = ttymalloc(); else @@ -767,6 +839,7 @@ iteopen(dev_t dev, int mode, int devtype, struct proc * p) if ((tp->t_state & (TS_ISOPEN | TS_XCLUDE)) == (TS_ISOPEN | TS_XCLUDE) && p->p_ucred->cr_uid != 0) return (EBUSY); + tp->t_oproc = itestart; tp->t_param = NULL; tp->t_dev = dev; @@ -780,85 +853,109 @@ iteopen(dev_t dev, int mode, int devtype, struct proc * p) tp->t_state = TS_ISOPEN | TS_CARR_ON; ttsetwater(tp); } + error = (*linesw[tp->t_line].l_open) (dev, tp); tp->t_winsize.ws_row = scrrows; tp->t_winsize.ws_col = scrcols; + dprintf("iteopen(): exit(%d)\n", error); return (error); } int -iteclose(dev_t dev, int flag, int mode, struct proc * p) +iteclose(dev, flag, mode, p) + dev_t dev; + int flag; + int mode; + struct proc *p; { dprintf("iteclose: enter (%d)\n", (int) dev); + (*linesw[ite_tty->t_line].l_close) (ite_tty, flag); ttyclose(ite_tty); #if 0 ttyfree(ite_tty); ite_tty = (struct tty *) 0; #endif + dprintf("iteclose: exit\n"); return 0; } int -iteread(dev_t dev, struct uio * uio, int flag) +iteread(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; { dprintf("iteread: enter\n"); return (*linesw[ite_tty->t_line].l_read) (ite_tty, uio, flag); - dprintf("iteread: exit\n"); } int -itewrite(dev_t dev, struct uio * uio, int flag) +itewrite(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; { dprintf("itewrite: enter\n"); return (*linesw[ite_tty->t_line].l_write) (ite_tty, uio, flag); - dprintf("itewrite: exit\n"); } struct tty * itetty(dev) - dev_t dev; + dev_t dev; { return (ite_tty); } int -iteioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc * p) +iteioctl(dev, cmd, addr, flag, p) + dev_t dev; + int cmd; + caddr_t addr; + int flag; + struct proc *p; { register struct tty *tp = ite_tty; - int error; + int error; dprintf("iteioctl: enter(%d, 0x%x)\n", cmd, cmd); + error = (*linesw[tp->t_line].l_ioctl) (tp, cmd, addr, flag, p); if (error >= 0) { dprintf("iteioctl: exit(%d)\n", error); return (error); } + error = ttioctl(tp, cmd, addr, flag, p); if (error >= 0) { dprintf("iteioctl: exit(%d)\n", error); return (error); } + switch (cmd) { - case ITEIOC_RINGBELL:{ + case ITEIOC_RINGBELL: + { asc_ringbell(); return (0); } - case ITEIOC_SETBELL:{ + case ITEIOC_SETBELL: + { struct bellparams *bp = (void *) addr; asc_setbellparams(bp->freq, bp->len, bp->vol); return (0); } - case ITEIOC_GETBELL:{ + case ITEIOC_GETBELL: + { struct bellparams *bp = (void *) addr; asc_getbellparams(&bp->freq, &bp->len, &bp->vol); return (0); } } + dprintf("iteioctl: exit(ENOTTY)\n"); return (ENOTTY); } @@ -867,7 +964,6 @@ void itestart(register struct tty * tp) { register int cc, s; - int hiwat = 0, hadcursor = 0; s = spltty(); if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) { @@ -879,9 +975,8 @@ itestart(register struct tty * tp) cc = tp->t_outq.c_cc; splx(s); erasecursor(); - while (cc-- > 0) { + while (cc-- > 0) ite_putchar(getc(&tp->t_outq)); - } drawcursor(); s = spltty(); @@ -892,14 +987,12 @@ itestart(register struct tty * tp) void itestop(struct tty * tp, int flag) { - int s; + int s; s = spltty(); - if (tp->t_state & TS_BUSY) { - if ((tp->t_state & TS_TTSTOP) == 0) { + if (tp->t_state & TS_BUSY) + if ((tp->t_state & TS_TTSTOP) == 0) tp->t_state |= TS_FLUSH; - } - } splx(s); } @@ -907,65 +1000,60 @@ int ite_intr(adb_event_t * event) { static int shift = 0, control = 0; - int key, press, val, state; - char str[10], *s; + int key, press, val, state; + char str[10], *s; key = event->u.k.key; press = ADBK_PRESS(key); val = ADBK_KEYVAL(key); - if (val == ADBK_SHIFT) { + if (val == ADBK_SHIFT) shift = press; - } else - if (val == ADBK_CONTROL) { - control = press; - } else - if (press) { - switch (val) { - case ADBK_UP: - str[0] = '\e'; - str[1] = 'O'; - str[2] = 'A'; - str[3] = '\0'; - break; - case ADBK_DOWN: - str[0] = '\e'; - str[1] = 'O'; - str[2] = 'B'; - str[3] = '\0'; - break; - case ADBK_RIGHT: - str[0] = '\e'; - str[1] = 'O'; - str[2] = 'C'; - str[3] = '\0'; - break; - case ADBK_LEFT: - str[0] = '\e'; - str[1] = 'O'; - str[2] = 'D'; - str[3] = '\0'; - break; - default: - state = 0; - if (shift) { - state = 1; - } - if (control) { - state = 2; - } - str[0] = keyboard[val][state]; - str[1] = '\0'; - break; - } - if (adb_polling) { - polledkey = str[0]; - } else { - for (s = str; *s; s++) { - (*linesw[ite_tty->t_line].l_rint) (*s, ite_tty); - } - } - } + else if (val == ADBK_CONTROL) + control = press; + else if (press) { + switch (val) { + case ADBK_UP: + str[0] = '\e'; + str[1] = 'O'; + str[2] = 'A'; + str[3] = '\0'; + break; + case ADBK_DOWN: + str[0] = '\e'; + str[1] = 'O'; + str[2] = 'B'; + str[3] = '\0'; + break; + case ADBK_RIGHT: + str[0] = '\e'; + str[1] = 'O'; + str[2] = 'C'; + str[3] = '\0'; + break; + case ADBK_LEFT: + str[0] = '\e'; + str[1] = 'O'; + str[2] = 'D'; + str[3] = '\0'; + break; + default: + state = 0; + if (shift) + state = 1; + if (control) + state = 2; + str[0] = keyboard[val][state]; + str[1] = '\0'; + break; + } + if (adb_polling) + polledkey = str[0]; + else + for (s = str; *s; s++) + (*linesw[ite_tty->t_line].l_rint)(*s, ite_tty); + } + return 0; } /* * Console functions @@ -974,28 +1062,29 @@ ite_intr(adb_event_t * event) int itecnprobe(struct consdev * cp) { - int maj, unit; + int maj, unit; /* locate the major number */ - for (maj = 0; maj < nchrdev; maj++) { - if (cdevsw[maj].d_open == iteopen) { + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == iteopen) break; - } - } - if (maj == nchrdev) { + if (maj == nchrdev) panic("itecnprobe(): did not find iteopen()."); - } + unit = 0; /* hardcode first device as console. */ /* initialize required fields */ cp->cn_dev = makedev(maj, unit); cp->cn_pri = CN_INTERNAL; + + return 0; } int itecninit(struct consdev * cp) { + ite_initted = 1; width = videosize & 0xffff; height = (videosize >> 16) & 0xffff; scrrows = height / CHARHEIGHT; @@ -1008,22 +1097,26 @@ itecninit(struct consdev * cp) case 1: putpixel = putpixel2; reversepixel = reversepixel1; + screenrowbytes = (width + 7) >> 3; break; case 2: putpixel = putpixel2; reversepixel = reversepixel1; + screenrowbytes = (width + 3) >> 2; break; case 4: putpixel = putpixel4; reversepixel = reversepixel1; + screenrowbytes = (width + 1) >> 1; break; case 8: putpixel = putpixel8; reversepixel = reversepixel1; + screenrowbytes = width; break; } - iteon(cp->cn_dev, 0); + return iteon(cp->cn_dev, 0); } int @@ -1032,6 +1125,7 @@ iteon(dev_t dev, int flags) erasecursor(); clear_screen(2); drawcursor(); + return 0; } int @@ -1039,6 +1133,7 @@ iteoff(dev_t dev, int flags) { erasecursor(); clear_screen(2); + return 0; } int @@ -1052,16 +1147,14 @@ itecngetc(dev_t dev) int itecnputc(dev_t dev, int c) { - extern dev_t mac68k_serdev; - int s; - -/* s = splhigh (); */ + extern dev_t mac68k_zsdev; + extern int zscnputc __P((dev_t dev, int c)); erasecursor(); ite_putchar(c); drawcursor(); if (mac68k_machine.serial_boot_echo) - sercnputc(mac68k_serdev, c); + zscnputc(mac68k_zsdev, c); -/* splx (s); */ + return c; } diff --git a/sys/arch/mac68k/dev/mac68k5380.c b/sys/arch/mac68k/dev/mac68k5380.c index 5c4fdca77d4..dd31e1ce67e 100644 --- a/sys/arch/mac68k/dev/mac68k5380.c +++ b/sys/arch/mac68k/dev/mac68k5380.c @@ -1,4 +1,4 @@ -/* $NetBSD: mac68k5380.c,v 1.15 1995/11/01 04:59:03 briggs Exp $ */ +/* $NetBSD: mac68k5380.c,v 1.24 1996/05/25 16:42:24 briggs Exp $ */ /* * Copyright (c) 1995 Allen Briggs @@ -47,11 +47,12 @@ /* * Include the driver definitions */ -#include <mac68k/dev/ncr5380reg.h> +#include "ncr5380reg.h" #include <machine/stdarg.h> +#include <machine/viareg.h> -#include "../mac68k/via.h" +#include "ncr5380var.h" /* * Set the various driver options @@ -66,8 +67,39 @@ #undef DBG_PIO /* Show the polled-I/O process */ #undef DBG_INF /* Show information transfer process */ #define DBG_NOSTATIC /* No static functions, all in DDB trace*/ -#define DBG_PID 15 /* Keep track of driver */ +#define DBG_PID 25 /* Keep track of driver */ +#ifdef DBG_NOSTATIC +# define static +#endif +#ifdef DBG_SEL +# define DBG_SELPRINT(a,b) printf(a,b) +#else +# define DBG_SELPRINT(a,b) +#endif +#ifdef DBG_PIO +# define DBG_PIOPRINT(a,b,c) printf(a,b,c) +#else +# define DBG_PIOPRINT(a,b,c) +#endif +#ifdef DBG_INF +# define DBG_INFPRINT(a,b,c) a(b,c) +#else +# define DBG_INFPRINT(a,b,c) +#endif +#ifdef DBG_PID + /* static char *last_hit = NULL, *olast_hit = NULL; */ + static char *last_hit[DBG_PID]; +# define PID(a) \ + { int i; \ + for (i=0; i< DBG_PID-1; i++) \ + last_hit[i] = last_hit[i+1]; \ + last_hit[DBG_PID-1] = a; } +#else +# define PID(a) +#endif + #undef REAL_DMA /* Use DMA if sensible */ +#define scsi_ipending() (GET_5380_REG(NCR5380_DMSTAT) & SC_IRQ_SET) #define fair_to_keep_dma() 1 #define claimed_dma() 1 #define reconsider_dma() @@ -91,14 +123,21 @@ static volatile u_char *ncr = (volatile u_char *) 0x10000; static volatile u_char *ncr_5380_with_drq = (volatile u_char *) 0x6000; static volatile u_char *ncr_5380_without_drq = (volatile u_char *) 0x12000; -static volatile u_char *scsi_enable = NULL; - #define SCSI_5380 ((struct scsi_5380 *) ncr) #define GET_5380_REG(rnum) SCSI_5380->scsi_5380[((rnum)<<4)] #define SET_5380_REG(rnum,val) (SCSI_5380->scsi_5380[((rnum)<<4)] = (val)) -void ncr5380_irq_intr(void *); -void ncr5380_drq_intr(void *); +static void ncr5380_irq_intr(void *); +static void ncr5380_drq_intr(void *); +static void do_ncr5380_drq_intr __P((void *)); + +static __inline__ void scsi_clr_ipend __P((void)); +static void scsi_mach_init __P((struct ncr_softc *sc)); +static int machine_match __P((struct device *pdp, void *match, + void *auxp, struct cfdriver *cd)); +static __inline__ int pdma_ready __P((void)); +static int transfer_pdma __P((u_char *phasep, u_char *data, + u_long *count)); static __inline__ void scsi_clr_ipend() @@ -106,26 +145,7 @@ scsi_clr_ipend() int tmp; tmp = GET_5380_REG(NCR5380_IRCV); -} - -extern __inline__ void -scsi_ienable() -{ - int s; - - s = splhigh(); - *scsi_enable = 0x80 | (V2IF_SCSIIRQ | V2IF_SCSIDRQ); - splx(s); -} - -extern __inline__ void -scsi_idisable() -{ - int s; - - s = splhigh(); - *scsi_enable = V2IF_SCSIIRQ | V2IF_SCSIDRQ; - splx(s); + scsi_clear_irq(); } static void @@ -144,28 +164,26 @@ scsi_mach_init(sc) ncr_5380_without_drq = (volatile u_char *) (SCSIBase + (u_int) ncr_5380_without_drq); - if (VIA2 == VIA2OFF) + if (VIA2 == VIA2OFF) { scsi_enable = Via1Base + VIA2 * 0x2000 + vIER; - else + scsi_flag = Via1Base + VIA2 * 0x2000 + vIFR; + } else { scsi_enable = Via1Base + VIA2 * 0x2000 + rIER; + scsi_flag = Via1Base + VIA2 * 0x2000 + rIFR; + } mac68k_register_scsi_irq(ncr5380_irq_intr, sc); mac68k_register_scsi_drq(ncr5380_drq_intr, sc); } static int -machine_match(pdp, cdp, auxp, cd) +machine_match(pdp, match, auxp, cd) struct device *pdp; - struct cfdata *cdp; - void *auxp; + void *match, *auxp; struct cfdriver *cd; { - if (matchbyname(pdp, cdp, auxp) == 0) - return 0; if (!mac68k_machine.scsi80) return 0; - if (cdp->cf_unit != 0) - return 0; return 1; } @@ -181,9 +199,6 @@ u_long pending_5380_count; int pdma_5380_sends = 0; int pdma_5380_bytes = 0; -char *pdma_5380_state="", *pdma_5380_prev_state=""; -#define DBG_SET(x) {pdma_5380_prev_state=pdma_5380_state; pdma_5380_state=(x);} - void pdma_stat() { @@ -191,10 +206,8 @@ pdma_stat() pdma_5380_sends, pdma_5380_bytes); printf("pdma_5380_dir = %d\t", pdma_5380_dir); - printf("datap = 0x%x, remainder = %d.\n", + printf("datap = %p, remainder = %ld.\n", pending_5380_data, pending_5380_count); - printf("state: %s\t", pdma_5380_state); - printf("last state: %s\n", pdma_5380_prev_state); scsi_show(); } #endif @@ -203,14 +216,14 @@ void pdma_cleanup(void) { SC_REQ *reqp = connected; - int bytes, s; + int s; s = splbio(); + PID("pdma_cleanup0"); pdma_5380_dir = 0; #if NCR5380_PDMA_DEBUG - DBG_SET("in pdma_cleanup().") pdma_5380_sends++; pdma_5380_bytes+=(reqp->xdata_len - pending_5380_count); #endif @@ -244,13 +257,9 @@ pdma_cleanup(void) /* * Back for more punishment. */ -#if NCR5380_PDMA_DEBUG - pdma_5380_state = "pdma_cleanup() -- going back to run_main()."; -#endif + PID("pdma_cleanup1"); run_main(cur_softc); -#if NCR5380_PDMA_DEBUG - pdma_5380_state = "pdma_cleanup() -- back from run_main()."; -#endif + PID("pdma_cleanup2"); } #endif @@ -262,21 +271,9 @@ pdma_ready() int dmstat, idstat; extern u_char ncr5380_no_parchk; + PID("pdma_ready0"); if (pdma_5380_dir) { -#if NCR5380_PDMA_DEBUG - DBG_SET("got irq interrupt in xfer.") -#endif - /* - * If Mr. IRQ isn't set one might wonder how we got - * here. It does happen, though. - */ - dmstat = GET_5380_REG(NCR5380_DMSTAT); - if (!(dmstat & SC_IRQ_SET)) { -#if NCR5380_PDMA_DEBUG - DBG_SET("irq not set.") -#endif - return 0; - } + PID("pdma_ready1."); /* * For a phase mis-match, ATN is a "don't care," IRQ is 1 and * all other bits in the Bus & Status Register are 0. Also, @@ -284,22 +281,19 @@ extern u_char ncr5380_no_parchk; * REQ. Since we're just checking that this interrupt isn't a * reselection or a reset, we just check for either. */ + dmstat = GET_5380_REG(NCR5380_DMSTAT); idstat = GET_5380_REG(NCR5380_IDSTAT); if ( ((dmstat & (0xff & ~SC_ATN_STAT)) == SC_IRQ_SET) && ((idstat & (SC_S_BSY|SC_S_REQ)) == (SC_S_BSY | SC_S_REQ)) ) { -#if NCR5380_PDMA_DEBUG - DBG_SET("BSY|REQ.") -#endif + PID("pdma_ready2"); pdma_cleanup(); return 1; } else if (PH_IN(reqp->phase) && (dmstat & SC_PAR_ERR)) { if (!(ncr5380_no_parchk & (1 << reqp->targ_id))) /* XXX: Should be parity error ???? */ reqp->xs->error = XS_DRIVER_STUFFUP; -#if NCR5380_PDMA_DEBUG - DBG_SET("PARITY.") -#endif + PID("pdma_ready3"); /* XXX: is this the right reaction? */ pdma_cleanup(); return 1; @@ -317,26 +311,25 @@ extern u_char ncr5380_no_parchk; scsi_show(); panic("Spurious interrupt during PDMA xfer.\n"); } - } + } else + PID("pdma_ready4"); #endif return 0; } -void +static void ncr5380_irq_intr(p) void *p; { - struct ncr_softc *sc = p; + PID("irq"); #if USE_PDMA if (pdma_ready()) { return; } #endif - if (GET_5380_REG(NCR5380_DMSTAT) & SC_IRQ_SET) { - scsi_idisable(); - ncr_ctrl_intr(cur_softc); - } + scsi_idisable(); + ncr_ctrl_intr(cur_softc); } /* @@ -354,43 +347,25 @@ ncr5380_irq_intr(p) * detect and handle the bus error for early termination of a command. * This is usually caused by a disconnecting target. */ -void -ncr5380_drq_intr(p) +static void +do_ncr5380_drq_intr(p) void *p; { #if USE_PDMA extern int *nofault, mac68k_buserr_addr; - struct ncr_softc *sc = p; label_t faultbuf; register int count; volatile u_int32_t *long_drq; u_int32_t *long_data; - volatile u_int8_t *drq; + volatile u_int8_t *drq, tmp_data; u_int8_t *data; - /* - * If we're not ready to xfer data, just return. - */ - if ( !(GET_5380_REG(NCR5380_DMSTAT) & SC_DMA_REQ) - || !pdma_5380_dir) { - return; - } - - /* - * I don't think this should be necessary, but it is - * for writes--at least to some devices. They don't - * let go of PH_DATAOUT until we do pdma_cleanup(). - */ - if (pending_5380_count == 0) { -#if NCR5380_PDMA_DEBUG - DBG_SET("forcing pdma_cleanup().") -#endif - pdma_cleanup(); - return; +#if DBG_PID + if (pdma_5380_dir == 2) { + PID("drq (in)"); + } else { + PID("drq (out)"); } - -#if NCR5380_PDMA_DEBUG - DBG_SET("got drq interrupt.") #endif /* @@ -401,15 +376,12 @@ extern int *nofault, mac68k_buserr_addr; nofault = (int *) &faultbuf; if (setjmp((label_t *) nofault)) { + PID("drq berr"); nofault = (int *) 0; -#if NCR5380_PDMA_DEBUG - DBG_SET("buserr in xfer.") -#endif count = ( (u_long) mac68k_buserr_addr - (u_long) ncr_5380_with_drq); if ((count < 0) || (count > pending_5380_count)) { - printf("pdma %s: count = %d (0x%x) (pending " - "count %d)\n", + printf("pdma %s: cnt = %d (0x%x) (pending cnt %ld)\n", (pdma_5380_dir == 2) ? "in" : "out", count, count, pending_5380_count); panic("something is wrong"); @@ -418,28 +390,22 @@ extern int *nofault, mac68k_buserr_addr; pending_5380_data += count; pending_5380_count -= count; -#if NCR5380_PDMA_DEBUG - DBG_SET("handled bus error in xfer.") -#endif mac68k_buserr_addr = 0; + + PID("end drq early"); + return; } if (pdma_5380_dir == 2) { /* Data In */ int resid; -#if NCR5380_PDMA_DEBUG - DBG_SET("Data in.") -#endif /* * Get the dest address aligned. */ resid = count = min(pending_5380_count, 4 - (((int) pending_5380_data) & 0x3)); if (count && (count < 4)) { -#if NCR5380_PDMA_DEBUG - DBG_SET("Data in (aligning dest).") -#endif data = (u_int8_t *) pending_5380_data; drq = (u_int8_t *) ncr_5380_with_drq; while (count) { @@ -457,50 +423,20 @@ extern int *nofault, mac68k_buserr_addr; while (pending_5380_count) { int dcount; -#if NCR5380_PDMA_DEBUG - DBG_SET("Data in (starting read).") -#endif dcount = count = min(pending_5380_count, MIN_PHYS); long_drq = (volatile u_int32_t *) ncr_5380_with_drq; long_data = (u_int32_t *) pending_5380_data; #define R4 *long_data++ = *long_drq++ - while ( count >= 512 ) { - if (!(GET_5380_REG(NCR5380_DMSTAT) & SC_DMA_REQ)) { - nofault = (int *) 0; - - pending_5380_data += (dcount - count); - pending_5380_count -= (dcount - count); -#if NCR5380_PDMA_DEBUG - DBG_SET("drq low") -#endif - return; - } + while ( count >= 64 ) { R4; R4; R4; R4; R4; R4; R4; R4; R4; R4; R4; R4; R4; R4; R4; R4; /* 64 */ - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; /* 128 */ - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; /* 256 */ - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; - R4; R4; R4; R4; R4; R4; R4; R4; /* 512 */ - count -= 512; + count -= 64; } while (count >= 4) { R4; count -= 4; } #undef R4 -#if NCR5380_PDMA_DEBUG - DBG_SET("Data in (finishing up).") -#endif data = (u_int8_t *) long_data; drq = (u_int8_t *) long_drq; while (count) { @@ -514,18 +450,12 @@ extern int *nofault, mac68k_buserr_addr; } else { int resid; -#if NCR5380_PDMA_DEBUG - DBG_SET("Data out.") -#endif /* * Get the source address aligned. */ resid = count = min(pending_5380_count, 4 - (((int) pending_5380_data) & 0x3)); if (count && (count < 4)) { -#if NCR5380_PDMA_DEBUG - DBG_SET("Data out (aligning dest).") -#endif data = (u_int8_t *) pending_5380_data; drq = (u_int8_t *) ncr_5380_with_drq; while (count) { @@ -543,9 +473,6 @@ extern int *nofault, mac68k_buserr_addr; while (pending_5380_count) { int dcount; -#if NCR5380_PDMA_DEBUG - DBG_SET("Data out (starting write).") -#endif dcount = count = min(pending_5380_count, MIN_PHYS); long_drq = (volatile u_int32_t *) ncr_5380_with_drq; long_data = (u_int32_t *) pending_5380_data; @@ -560,9 +487,6 @@ extern int *nofault, mac68k_buserr_addr; W4; count -= 4; } #undef W4 -#if NCR5380_PDMA_DEBUG - DBG_SET("Data out (cleaning up).") -#endif data = (u_int8_t *) long_data; drq = (u_int8_t *) long_drq; while (count) { @@ -573,6 +497,14 @@ extern int *nofault, mac68k_buserr_addr; pending_5380_count -= dcount; pending_5380_data += dcount; } + PID("write complete"); + + drq = (volatile u_int8_t *) ncr_5380_with_drq; + tmp_data = *drq; + + PID("read a byte?"); + + nofault = (int *) 0; } /* @@ -581,13 +513,23 @@ extern int *nofault, mac68k_buserr_addr; */ nofault = (int *) 0; -#if NCR5380_PDMA_DEBUG - DBG_SET("done in xfer.") -#endif - + PID("end drq"); + return; +#else + return; #endif /* if USE_PDMA */ } +static void +ncr5380_drq_intr(p) + void *p; +{ + while (GET_5380_REG(NCR5380_DMSTAT) & SC_DMA_REQ) { + do_ncr5380_drq_intr(p); + scsi_clear_drq(); + } +} + #if USE_PDMA #define SCSI_TIMEOUT_VAL 10000000 @@ -599,24 +541,19 @@ transfer_pdma(phasep, data, count) u_long *count; { SC_REQ *reqp = connected; - int len = *count, i, scsi_timeout = SCSI_TIMEOUT_VAL; - int s, err; + int len = *count, s, scsi_timeout = SCSI_TIMEOUT_VAL; if (pdma_5380_dir) { panic("ncrscsi: transfer_pdma called when operation already " "pending.\n"); } -#if NCR5380_PDMA_DEBUG - DBG_SET("in transfer_pdma.") -#endif + PID("transfer_pdma0") /* * Don't bother with PDMA if we can't sleep or for small transfers. */ if (reqp->dr_flag & DRIVER_NOINT) { -#if NCR5380_PDMA_DEBUG - DBG_SET("pdma, actually using transfer_pio.") -#endif + PID("pdma, falling back to transfer_pio.") transfer_pio(phasep, data, count, 0); return -1; } @@ -663,10 +600,6 @@ transfer_pdma(phasep, data, count) pending_5380_data = data; pending_5380_count = len; -#if NCR5380_PDMA_DEBUG - DBG_SET("setting up for interrupt.") -#endif - /* * Set the transfer function to be called on DRQ interrupts. * And note that we're waiting. @@ -688,9 +621,7 @@ transfer_pdma(phasep, data, count) break; } -#if NCR5380_PDMA_DEBUG - DBG_SET("wait for interrupt.") -#endif + PID("waiting for interrupt.") /* * Now that we're set up, enable interrupts and drop processor diff --git a/sys/arch/mac68k/dev/ncr5380.c b/sys/arch/mac68k/dev/ncr5380.c index 99a620f23f6..ad0c63c29d8 100644 --- a/sys/arch/mac68k/dev/ncr5380.c +++ b/sys/arch/mac68k/dev/ncr5380.c @@ -1,4 +1,4 @@ -/* $NetBSD: ncr5380.c,v 1.17 1996/01/06 15:56:12 briggs Exp $ */ +/* $NetBSD: ncr5380.c,v 1.29 1996/05/22 17:16:45 briggs Exp $ */ /* * Copyright (c) 1995 Leo Weppelman. @@ -30,38 +30,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#ifdef DBG_NOSTATIC -# define static -#endif -#ifdef DBG_SEL -# define DBG_SELPRINT(a,b) printf(a,b) -#else -# define DBG_SELPRINT(a,b) -#endif -#ifdef DBG_PIO -# define DBG_PIOPRINT(a,b,c) printf(a,b,c) -#else -# define DBG_PIOPRINT(a,b,c) -#endif -#ifdef DBG_INF -# define DBG_INFPRINT(a,b,c) a(b,c) -#else -# define DBG_INFPRINT(a,b,c) -#endif -#ifdef DBG_PID - /* static char *last_hit = NULL, *olast_hit = NULL; */ - static char *last_hit[DBG_PID]; -# define PID(a) \ - { int i; \ - for (i=0; i< DBG_PID-1; i++) \ - last_hit[i] = last_hit[i+1]; \ - last_hit[DBG_PID-1] = a; } \ - /* olast_hit = last_hit; last_hit = a; */ -#else -# define PID(a) -#endif - /* * Bit mask of targets you want debugging to be shown */ @@ -104,9 +72,9 @@ static volatile int main_running = 0; */ static u_char busy; -static void ncr5380_minphys(struct buf *bp); -static int ncr5380_scsi_cmd(struct scsi_xfer *xs); -static int ncr5380_show_scsi_cmd(struct scsi_xfer *xs); +static void ncr5380_minphys __P((struct buf *bp)); +static int ncr5380_scsi_cmd __P((struct scsi_xfer *xs)); +static void ncr5380_show_scsi_cmd __P((struct scsi_xfer *xs)); struct scsi_adapter ncr5380_switch = { ncr5380_scsi_cmd, /* scsi_cmd() */ @@ -228,25 +196,29 @@ extern __inline__ void finish_req(SC_REQ *reqp) */ int ncr_cprint __P((void *auxp, char *)); void ncr_attach __P((struct device *, struct device *, void *)); -int ncr_match __P((struct device *, struct cfdata *, void *)); +int ncr_match __P((struct device *, void *, void *)); /* * Tricks to make driver-name configurable */ -#define CFNAME(n) __CONCAT(n,cd) +#define CFNAME(n) __CONCAT(n,_cd) +#define CANAME(n) __CONCAT(n,_ca) #define CFSTRING(n) __STRING(n) +struct cfattach CANAME(DRNAME) = { + sizeof(struct ncr_softc), ncr_match, ncr_attach +}; + struct cfdriver CFNAME(DRNAME) = { - NULL, CFSTRING(DRNAME), (cfmatch_t)ncr_match, ncr_attach, - DV_DULL, sizeof(struct ncr_softc), NULL, 0 }; + NULL, CFSTRING(DRNAME), DV_DULL +}; int -ncr_match(pdp, cdp, auxp) +ncr_match(pdp, match, auxp) struct device *pdp; -struct cfdata *cdp; -void *auxp; +void *match, *auxp; { - return (machine_match(pdp, cdp, auxp, &CFNAME(DRNAME))); + return (machine_match(pdp, match, auxp, &CFNAME(DRNAME))); } void @@ -332,7 +304,8 @@ ncr5380_scsi_cmd(struct scsi_xfer *xs) * We do not queue RESET commands */ if (flags & SCSI_RESET) { - scsi_reset(xs->sc_link->adapter_softc); + scsi_reset_verbose(xs->sc_link->adapter_softc, + "Got reset-command"); return (COMPLETE); } @@ -355,6 +328,7 @@ ncr5380_scsi_cmd(struct scsi_xfer *xs) reqp->phase = NR_PHASE; reqp->msgout = MSG_NOOP; reqp->status = SCSGOOD; + reqp->message = 0xff; reqp->link = NULL; reqp->xs = xs; reqp->targ_id = xs->sc_link->target; @@ -373,7 +347,7 @@ ncr5380_scsi_cmd(struct scsi_xfer *xs) } if (!(flags & INUSE)) { ncr_tprint(reqp, "scsi_cmd: command not in use.....\n"); - xs->flags |= ~INUSE; + xs->flags |= INUSE; } #ifdef REAL_DMA @@ -439,7 +413,7 @@ ncr5380_minphys(struct buf *bp) } #undef MIN_PHYS -static int +static void ncr5380_show_scsi_cmd(struct scsi_xfer *xs) { u_char *b = (u_char *) xs->cmd; @@ -583,7 +557,7 @@ connected: /* * Let the target guide us through the bus-phases */ - while (information_transfer() == -1) + while (information_transfer(sc) == -1) ; } } @@ -600,8 +574,15 @@ main_exit: */ PID("scsi_main4"); scsi_ienable(); - SET_5380_REG(NCR5380_IDSTAT, SC_HOST_ID); - if (GET_5380_REG(NCR5380_DMSTAT) & SC_IRQ_SET) { + + /* + * If we're not currently connected, enable reselection + * interrupts. + */ + if (!connected) + SET_5380_REG(NCR5380_IDSTAT, SC_HOST_ID); + + if (scsi_ipending()) { if ((itype = check_intr(sc)) != INTR_SPURIOUS) { scsi_idisable(); splx(sps); @@ -667,15 +648,15 @@ ncr_ctrl_intr(sc) struct ncr_softc *sc; { int itype; - int dma_done; - while (GET_5380_REG(NCR5380_DMSTAT) & SC_IRQ_SET) { + while (scsi_ipending()) { scsi_idisable(); if ((itype = check_intr(sc)) != INTR_SPURIOUS) { if (itype == INTR_RESEL) reselect(sc); else { #ifdef REAL_DMA + int dma_done; if (!(dma_done = dma_ready())) { transfer_dma(connected, connected->phase, 0); return; @@ -707,8 +688,8 @@ struct ncr_softc *sc; static int scsi_select(reqp, code) SC_REQ *reqp; +int code; { - u_long timeout; u_char tmp[1]; u_char phase; u_long cnt; @@ -927,7 +908,7 @@ SC_REQ *reqp; transfer_pio(&phase, &msg, &len, 0); } - else scsi_reset(sc); + else scsi_reset_verbose(sc, "Connected to unidentified target"); SET_5380_REG(NCR5380_ICOM, 0); reqp->xs->error = code ? code : XS_DRIVER_STUFFUP; @@ -955,11 +936,12 @@ identify_failed: /* * Return codes: - * -1: quit main, trigger on interrupt - * 0: keep on running main. + * 0: Job has finished or disconnected, find something else + * -1: keep on calling information_transfer() from scsi_main() */ static int -information_transfer() +information_transfer(sc) +struct ncr_softc *sc; { SC_REQ *reqp = connected; u_char tmp, phase; @@ -972,28 +954,48 @@ information_transfer() scsi_clr_ipend(); /* - * We only have a valid SCSI-phase when REQ is asserted. Something - * is deadly wrong when BSY has dropped. + * The SCSI-spec requires BSY to be true while connected to a target, + * loosing it means we lost the target... + * Also REQ needs to be asserted here to indicate that the bus-phase + * is valid. When the target does not supply REQ within a 'reasonable' + * amount of time, it's probably lost in it's own maze of twisting + * passages, we have to reset the bus to free it. */ + if (GET_5380_REG(NCR5380_IDSTAT) & SC_S_BSY) + wait_req_true(); tmp = GET_5380_REG(NCR5380_IDSTAT); - if (!(tmp & SC_S_BSY)) { + + if ((tmp & (SC_S_BSY|SC_S_REQ)) != (SC_S_BSY|SC_S_REQ)) { busy &= ~(1 << reqp->targ_id); connected = NULL; - reqp->xs->error = XS_BUSY; + reqp->xs->error = XS_TIMEOUT; finish_req(reqp); + if (!(tmp & SC_S_REQ)) + scsi_reset_verbose(sc, + "Timeout waiting for phase-change"); PID("info_transf2"); return (0); } - if (tmp & SC_S_REQ) { - phase = (tmp >> 2) & 7; - if (phase != reqp->phase) { - reqp->phase = phase; - DBG_INFPRINT(show_phase, reqp, phase); + phase = (tmp >> 2) & 7; + if (phase != reqp->phase) { + reqp->phase = phase; + DBG_INFPRINT(show_phase, reqp, phase); + } + else { + /* + * Same data-phase. If same error give up + */ + if ((reqp->msgout == MSG_ABORT) + && ((phase == PH_DATAOUT) || (phase == PH_DATAIN))) { + busy &= ~(1 << reqp->targ_id); + connected = NULL; + finish_req(reqp); + scsi_reset_verbose(sc, "Failure to abort command"); + return (0); } } - else return (-1); switch (phase) { case PH_DATAOUT: @@ -1013,6 +1015,17 @@ information_transfer() } case PH_DATAIN: + if (reqp->xdata_len <= 0) { + /* + * Target keeps requesting data. Try to get into + * message-out phase by feeding/taking 100 byte. + */ + ncr_tprint(reqp, "Target requests too much data\n"); + reqp->msgout = MSG_ABORT; + SET_5380_REG(NCR5380_ICOM, SC_A_ATN); + reach_msg_out(sc, 100); + return (-1); + } #ifdef REAL_DMA if (reqp->dr_flag & DRIVER_DMAOK) { int poll = REAL_DMA_POLL|(reqp->dr_flag & DRIVER_NOINT); @@ -1049,7 +1062,8 @@ information_transfer() if (reqp->msgout == MSG_ABORT) { busy &= ~(1 << reqp->targ_id); connected = NULL; - reqp->xs->error = XS_DRIVER_STUFFUP; + if (!reqp->xs->error) + reqp->xs->error = XS_DRIVER_STUFFUP; finish_req(reqp); PID("info_transf4"); return (0); @@ -1194,10 +1208,19 @@ u_int msg; PID("hmessage9"); return (-1); default: - ncr_tprint(reqp, "Unknown message %x\n", msg); + if ((msg & 0x80) && !(msg & 0x18)) { /* IDENTIFY */ + PID("hmessage10"); + ack_message(); + return (0); + } else { + ncr_tprint(reqp, + "Unknown message %x. Rejecting.\n", + msg); + nack_message(reqp, MSG_MESSAGE_REJECT); + } return (-1); } - PID("hmessage10"); + PID("hmessage11"); return (-1); } @@ -1236,7 +1259,7 @@ struct ncr_softc *sc; } if (GET_5380_REG(NCR5380_IDSTAT) & SC_S_SEL) { /* Damn SEL isn't dropping */ - scsi_reset(sc); + scsi_reset_verbose(sc, "Target won't drop SEL during Reselect"); return; } @@ -1263,6 +1286,7 @@ struct ncr_softc *sc; if (len || !MSG_ISIDENTIFY(msg)) { ncr_aprint(sc, "Expecting IDENTIFY, got 0x%x\n", msg); abort = 1; + tmp = NULL; } else { /* @@ -1290,7 +1314,7 @@ struct ncr_softc *sc; SET_5380_REG(NCR5380_ICOM, SC_A_ATN); if (transfer_pio(&phase, &msg, &len, 0) || len) - scsi_reset(sc); + scsi_reset_verbose(sc, "Failure to abort reselection"); } else { connected = tmp; @@ -1496,9 +1520,10 @@ dma_ready() else reqp->dm_cur->dm_addr += bytes_done; if (PH_IN(reqp->phase) && (dmstat & SC_PAR_ERR)) { - if (!(ncr5380_no_parchk & (1 << reqp->targ_id))) - /* XXX: Should be parity error ???? */ - reqp->xs->error = XS_DRIVER_STUFFUP; + if (!(ncr5380_no_parchk & (1 << reqp->targ_id))) { + ncr_tprint(reqp, "parity error in data-phase\n"); + reqp->xs->error = XS_TIMEOUT; + } } /* @@ -1526,7 +1551,7 @@ dma_ready() if (dmstat & SC_BSY_ERR) { if (!reqp->xs->error) - reqp->xs->error = XS_BUSY; + reqp->xs->error = XS_TIMEOUT; finish_req(reqp); PID("dma_ready1"); return (1); @@ -1605,6 +1630,7 @@ u_long len; { u_char phase; u_char data; + u_long n = len; ncr_aprint(sc, "Trying to reach Message-out phase\n"); if ((phase = GET_5380_REG(NCR5380_IDSTAT)) & SC_S_REQ) @@ -1632,32 +1658,31 @@ u_long len; if (!wait_req_false()) break; SET_5380_REG(NCR5380_ICOM, SC_A_ATN); - } while (--len); + } while (--n); if ((phase = GET_5380_REG(NCR5380_IDSTAT)) & SC_S_REQ) { phase = (phase >> 2) & 7; if (phase == PH_MSGOUT) { - ncr_aprint(sc, "Message-out phase reached.\n"); + ncr_aprint(sc, "Message-out phase reached after " + "%ld bytes.\n", len - n); return (0); } } return (-1); } -static void -scsi_reset(sc) -struct ncr_softc *sc; +void +scsi_reset() { SC_REQ *tmp, *next; int sps; - ncr_aprint(sc, "Resetting SCSI-bus\n"); - PID("scsi_reset1"); sps = splbio(); SET_5380_REG(NCR5380_ICOM, SC_A_RST); - delay(1); + delay(100); SET_5380_REG(NCR5380_ICOM, 0); + scsi_clr_ipend(); /* * None of the jobs in the discon_q will ever be reconnected, @@ -1680,7 +1705,7 @@ struct ncr_softc *sc; * doing REAL-DMA. In that case 'dma_ready()' should correctly finish * the job because it detects BSY-loss. */ - if (tmp = connected) { + if ((tmp = connected) != NULL) { if (tmp->dr_flag & DRIVER_IN_DMA) { tmp->xs->error = XS_DRIVER_STUFFUP; #ifdef REAL_DMA @@ -1690,6 +1715,22 @@ struct ncr_softc *sc; } splx(sps); PID("scsi_reset2"); + + /* + * Give the attached devices some time to handle the reset. This + * value is arbitrary but should be relatively long. + */ + delay(100000); +} + +static void +scsi_reset_verbose(sc, why) +struct ncr_softc *sc; +const char *why; +{ + ncr_aprint(sc, "Resetting SCSI-bus (%s)\n", why); + + scsi_reset(); } /* @@ -1850,7 +1891,7 @@ ncr_tprint(SC_REQ *reqp, char *fmt, ...) va_start(ap, fmt); sc_print_addr(reqp->xs->sc_link); - printf("%r", fmt, ap); + printf("%:", fmt, ap); va_end(ap); } @@ -1863,7 +1904,7 @@ ncr_aprint(struct ncr_softc *sc, char *fmt, ...) va_list ap; va_start(ap, fmt); - printf("%s : %r", sc->sc_dev.dv_xname, fmt, ap); + printf("%s : %:", sc->sc_dev.dv_xname, fmt, ap); va_end(ap); } /**************************************************************************** @@ -1895,7 +1936,7 @@ show_request(reqp, qtxt) SC_REQ *reqp; char *qtxt; { - printf("REQ-%s: %d %x[%d] cmd[0]=%x S=%x M=%x R=%x resid=%d dr_flag=%x %s\n", + printf("REQ-%s: %d %p[%ld] cmd[0]=%x S=%x M=%x R=%x resid=%d dr_flag=%x %s\n", qtxt, reqp->targ_id, reqp->xdata_ptr, reqp->xdata_len, reqp->xcmd.opcode, reqp->status, reqp->message, reqp->xs->error, reqp->xs->resid, reqp->dr_flag, @@ -1914,7 +1955,7 @@ show_signals(dmstat, idstat) u_char dmstat, idstat; { u_short tmp, mask; - int i, j, need_pipe; + int j, need_pipe; tmp = idstat | ((dmstat & 3) << 8); printf("Bus signals (%02x/%02x): ", idstat, dmstat & 3); @@ -1930,13 +1971,18 @@ u_char dmstat, idstat; printf("\n"); } +void scsi_show() { SC_REQ *tmp; int sps = splhigh(); u_char idstat, dmstat; +#ifdef DBG_PID int i; +#endif + printf("scsi_show: scsi_main is%s running\n", + main_running ? "" : " not"); for (tmp = issue_q; tmp; tmp = tmp->next) show_request(tmp, "ISSUED"); for (tmp = discon_q; tmp; tmp = tmp->next) diff --git a/sys/arch/mac68k/dev/ncr5380reg.h b/sys/arch/mac68k/dev/ncr5380reg.h index a19f41f3fca..5f941854114 100644 --- a/sys/arch/mac68k/dev/ncr5380reg.h +++ b/sys/arch/mac68k/dev/ncr5380reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: ncr5380reg.h,v 1.5 1995/12/04 02:10:46 briggs Exp $ */ +/* $NetBSD: ncr5380reg.h,v 1.9 1996/05/05 06:16:58 briggs Exp $ */ /* * Copyright (c) 1995 Leo Weppelman. @@ -236,24 +236,24 @@ static int scsi_select __P((SC_REQ *, int)); static int handle_message __P((SC_REQ *, u_int)); static void ack_message __P((void)); static void nack_message __P((SC_REQ *, u_char)); -static int information_transfer __P((void)); +static void finish_req __P((SC_REQ *reqp)); +static int command_size __P((u_char opcode)); +static int information_transfer __P((struct ncr_softc *)); static void reselect __P((struct ncr_softc *)); -static int dma_ready __P((void)); -static void transfer_dma __P((SC_REQ *, u_int, int)); static int check_autosense __P((SC_REQ *, int)); static int reach_msg_out __P((struct ncr_softc *, u_long)); static int check_intr __P((struct ncr_softc *)); -static void scsi_reset __P((struct ncr_softc *)); -static int scsi_dmaok __P((SC_REQ *)); +static void scsi_reset __P((void)); +static void scsi_reset_verbose __P((struct ncr_softc *, const char *)); static void run_main __P((struct ncr_softc *)); static void scsi_main __P((struct ncr_softc *)); static void ncr_ctrl_intr __P((struct ncr_softc *)); -static void ncr_dma_intr __P((struct ncr_softc *)); static void ncr_tprint __P((SC_REQ *, char *, ...)); static void ncr_aprint __P((struct ncr_softc *, char *, ...)); +static void show_data_sense __P((struct scsi_xfer *xs)); static void show_request __P((SC_REQ *, char *)); -static void show_phase __P((SC_REQ *, int)); +/* static void show_phase __P((SC_REQ *, int)); */ static void show_signals __P((u_char, u_char)); #endif /* _NCR5380REG_H */ diff --git a/sys/arch/mac68k/dev/nubus.c b/sys/arch/mac68k/dev/nubus.c index 7b15a53437b..fbcd45f668f 100644 --- a/sys/arch/mac68k/dev/nubus.c +++ b/sys/arch/mac68k/dev/nubus.c @@ -1,4 +1,4 @@ -/* $NetBSD: nubus.c,v 1.15 1996/01/12 04:16:43 briggs Exp $ */ +/* $NetBSD: nubus.c,v 1.23 1996/05/08 15:14:53 scottr Exp $ */ /* * Copyright (c) 1995 Allen Briggs. All rights reserved. @@ -33,69 +33,66 @@ #include <sys/systm.h> #include <sys/device.h> +#include <machine/autoconf.h> #include <machine/cpu.h> #include <vm/vm.h> #include "nubus.h" -#if DEBUG +#ifdef DEBUG static int nubus_debug = 0x01; #define NDB_PROBE 0x1 #define NDB_FOLLOW 0x2 #define NDB_ARITH 0x4 #endif -extern int matchbyname(); - -static int nubusprint __P((void *aux, char *name)); -static void nubusattach __P((struct device *parent, struct device *self, - void *aux)); +static int nubusprint __P((void *, char *)); +static int nubusmatch __P((struct device *, void *, void *)); +static void nubusattach __P((struct device *, struct device *, void *)); static int probe_slot __P((int slot, nubus_slot *fmt)); static u_long IncPtr __P((nubus_slot *fmt, u_long base, long amt)); static u_long nubus_calc_CRC __P((nubus_slot *fmt)); static u_char GetByte __P((nubus_slot *fmt, u_long ptr)); -static u_short GetWord __P((nubus_slot *fmt, u_long ptr)); +#ifdef notyet +/* unused */ static u_short GetWord __P((nubus_slot *fmt, u_long ptr)); +#endif static u_long GetLong __P((nubus_slot *fmt, u_long ptr)); -struct cfdriver nubuscd = { - NULL, "nubus", matchbyname, nubusattach, - DV_DULL, sizeof(struct nubus_softc), 1 +struct cfattach nubus_ca = { + sizeof(struct nubus_softc), nubusmatch, nubusattach +}; + +struct cfdriver nubus_cd = { + NULL, "nubus", DV_DULL, 1 }; +static int +nubusmatch(parent, vcf, aux) + struct device *parent; + void *vcf, *aux; +{ + struct confargs *ca = aux; + + if (ca->ca_bustype != BUS_NUBUS) + return (0); + return(1); +} + static void nubusattach(parent, self, aux) struct device *parent, *self; void *aux; { - extern u_int32_t mac68k_vidlog; nubus_slot fmtblock; int i; printf("\n"); - /* - * Kludge for internal video. - */ - if (mac68k_vidlog) { - int int_video_slot = NUBUS_INT_VIDEO_PSUEDO_SLOT; - - fmtblock.top = NUBUS_SLOT_TO_BASE(int_video_slot); - fmtblock.slot = int_video_slot; - fmtblock.bytelanes = 0x0F; - fmtblock.step = 4; - fmtblock.test_pattern = ~NUBUS_ROM_TEST_PATTERN; - fmtblock.format = 1; - fmtblock.revision_level = 1; - fmtblock.crc = 1; - fmtblock.length = 0; - fmtblock.directory_offset = 0; - config_found(self, &fmtblock, nubusprint); - } - - for ( i = NUBUS_MIN_SLOT; i <= NUBUS_MAX_SLOT; i++) { + for (i = NUBUS_MIN_SLOT; i <= NUBUS_MAX_SLOT; i++) { if (probe_slot(i, &fmtblock)) { + /*config_search(bus_scan, &fmtblock, nubusprint);*/ config_found(self, &fmtblock, nubusprint); } } @@ -107,8 +104,6 @@ nubusprint(aux, name) char *name; { nubus_slot *fmt; - int slot; - char *info; fmt = (nubus_slot *) aux; if (name) { @@ -156,21 +151,23 @@ probe_slot(slot, fmt) nubus_slot *fmt; { caddr_t rom_probe; - u_long hdr; - u_long phys; - u_char data; + vm_offset_t hdr; +#ifdef DEBUG + vm_offset_t pa; +#endif + u_int data; int hdr_size, i; fmt->bytelanes = 0; fmt->slot = (u_long)slot; - rom_probe = (caddr_t) (NUBUS_SLOT_TO_BASE(fmt->slot) + NBMEMSIZE); + rom_probe = (caddr_t) (NUBUS_SLOT_TO_PADDR(fmt->slot) + NBMEMSIZE); #ifdef DEBUG if (nubus_debug & NDB_PROBE) { - phys = pmap_extract(pmap_kernel(), (vm_offset_t)rom_probe-1); - printf("probing slot %d, first probe at 0x%x (phys 0x%x).\n", - slot, rom_probe-1, phys); + pa = pmap_extract(pmap_kernel(), (vm_offset_t) rom_probe - 1); + printf("probing slot %d, first probe at 0x%x (PA 0x%p).\n", + slot, rom_probe - 1, pa); } #endif @@ -178,10 +175,11 @@ probe_slot(slot, fmt) rom_probe--; - if (badbaddr(rom_probe)) + data = bus_peek(BUS_NUBUS, (vm_offset_t) rom_probe, 1); + if (data == -1) continue; - if ((data = *rom_probe) == 0) + if (data == 0) continue; if ( ((((data & 0xf0) >> 4) ^ (data & 0x0f)) == 0x0f) @@ -201,8 +199,8 @@ probe_slot(slot, fmt) #ifdef DEBUG if (nubus_debug & NDB_PROBE) - printf("bytelanes of 0x%x found for slot 0x%x (base 0x%x).\n", - fmt->bytelanes, slot, NUBUS_SLOT_TO_BASE(slot)); + printf("bytelanes of 0x%x found for slot 0x%x.\n", + fmt->bytelanes, slot); #endif hdr_size = 20; @@ -213,7 +211,17 @@ probe_slot(slot, fmt) * would be valid. This is necessary for NUBUS_ROM_offset() * to work. */ - hdr = NUBUS_SLOT_TO_BASE(fmt->slot) + NBMEMSIZE; + hdr = (vm_offset_t) + bus_mapin(BUS_NUBUS,NUBUS_SLOT_TO_PADDR(fmt->slot),NBMEMSIZE); + if (hdr == NULL) { + printf("Failed to map %d bytes for NuBUS slot %d probe. ", + NBMEMSIZE, fmt->slot); + printf("Physical slot address %x\n", + (unsigned int) NUBUS_SLOT_TO_PADDR(fmt->slot)); + } + fmt->virtual_base = hdr; + hdr += NBMEMSIZE; + i = 0x10 | (fmt->bytelanes & 0x0f); while ((i & 1) == 0) { hdr++; @@ -223,7 +231,7 @@ probe_slot(slot, fmt) hdr = IncPtr(fmt, hdr, -hdr_size); #ifdef DEBUG if (nubus_debug & NDB_PROBE) - printf("fmt->top is 0x%x, that minus 0x%x puts us at 0x%x.\n", + printf("fmt->top is 0x%p, that minus 0x%x puts us at 0x%p.\n", fmt->top, hdr_size, hdr); #if 0 for (i=1 ; i < 8 ; i++) { @@ -246,7 +254,7 @@ probe_slot(slot, fmt) hdr = IncPtr(fmt, hdr, 1); fmt->test_pattern = GetLong(fmt, hdr); -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_PROBE) { printf("Directory offset 0x%x\t", fmt->directory_offset); printf("Length 0x%x\t", fmt->length); @@ -366,6 +374,8 @@ GetByte(fmt, ptr) return *(caddr_t)ptr; } +#ifdef notyet +/* Nothing uses this, yet */ static u_short GetWord(fmt, ptr) nubus_slot *fmt; @@ -378,6 +388,7 @@ GetWord(fmt, ptr) s |= GetByte(fmt, ptr); return s; } +#endif static u_long GetLong(fmt, ptr) @@ -400,9 +411,7 @@ nubus_get_main_dir(slot, dir_return) nubus_slot *slot; nubus_dir *dir_return; { - u_long off; - -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("nubus_get_main_dir(0x%x, 0x%x)\n", (u_int) slot, (u_int) dir_return); @@ -422,7 +431,7 @@ nubus_find_rsrc(slot, dir, rsrcid, dirent_return) u_long entry; u_char byte; -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("nubus_find_rsrc(0x%x, 0x%x, 0x%x, 0x%x)\n", (u_int) slot, (u_int) dir, (u_int) rsrcid, @@ -434,7 +443,7 @@ nubus_find_rsrc(slot, dir, rsrcid, dirent_return) entry = dir->curr_ent; do { byte = GetByte(slot, entry); -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("\tFound rsrc 0x%x.\n", byte); #endif @@ -462,7 +471,7 @@ nubus_get_dir_from_rsrc(slot, dirent, dir_return) { u_long loc; -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("nubus_get_dir_from_rsrc(0x%x, 0x%x, 0x%x).\n", (u_int) slot, (u_int) dirent, (u_int) dir_return); @@ -483,7 +492,7 @@ nubus_get_ind_data(slot, dirent, data_return, nbytes) { u_long loc; -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("nubus_get_ind_data(0x%x, 0x%x, 0x%x, %d).\n", (u_int) slot, (u_int) dirent, (u_int) data_return, @@ -510,7 +519,7 @@ nubus_get_c_string(slot, dirent, data_return, max_bytes) { u_long loc; -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("nubus_get_c_string(0x%x, 0x%x, 0x%x, %d).\n", (u_int) slot, (u_int) dirent, (u_int) data_return, @@ -541,7 +550,7 @@ static char str_ret[64]; nubus_dir dir; nubus_dirent ent; -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_FOLLOW) printf("nubus_get_vendor(0x%x, 0x%x).\n", (u_int) slot, rsrc); #endif @@ -570,9 +579,9 @@ static char name_ret[64]; nubus_dir dir; nubus_dirent ent; -#if DEBUG +#ifdef DEBUG if (nubus_debug & NDB_FOLLOW) - printf("nubus_get_card_name(0x%x).\n", (u_long) slot); + printf("nubus_get_card_name(0x%lx).\n", (u_long) slot); #endif nubus_get_main_dir(slot, &dir); diff --git a/sys/arch/mac68k/dev/nubus.h b/sys/arch/mac68k/dev/nubus.h index 2b6ea05b323..05edd16d901 100644 --- a/sys/arch/mac68k/dev/nubus.h +++ b/sys/arch/mac68k/dev/nubus.h @@ -1,4 +1,4 @@ -/* $NetBSD: nubus.h,v 1.12 1996/01/12 04:52:58 briggs Exp $ */ +/* $NetBSD: nubus.h,v 1.14 1996/05/07 03:13:40 briggs Exp $ */ /* * Copyright (c) 1995 Allen Briggs. All rights reserved. @@ -59,13 +59,14 @@ #define NUBUS_TYPE_ETHERNET 0x0001 #define NUBUS_DRSW_3COM 0x0000 #define NUBUS_DRSW_GATOR 0x0103 -#define NUBUS_DRHW_INTERLAN 0x0100 -#define NUBUS_DRHW_KINETICS 0x0106 #define NUBUS_DRSW_ASANTE 0x0104 #define NUBUS_DRSW_TECHWORKS 0x0109 -#define NUBUS_DRHW_SONIC 0x0110 #define NUBUS_DRSW_FARALLON 0x010C #define NUBUS_DRSW_FOCUS 0x011A +#define NUBUS_DRHW_INTERLAN 0x0100 +#define NUBUS_DRHW_KINETICS 0x0106 +#define NUBUS_DRHW_SONIC 0x0110 +#define NUBUS_DRHW_CABLETRON 0x0109 #define NUBUS_CATEGORY_COMMUNICATIONS 0x0006 #define NUBUS_TYPE_RS232 0x0002 @@ -98,6 +99,7 @@ typedef struct _nubus_slot { u_int32_t crc; u_int32_t length; u_int32_t directory_offset; + vm_offset_t virtual_base; } nubus_slot; /* @@ -219,15 +221,10 @@ typedef struct _NUBUS_EXEC_BLOCK { #define NUBUS_MIN_SLOT 0x9 #define NUBUS_MAX_SLOT 0xE -#define NUBUS_INT_VIDEO_PSUEDO_SLOT 0xF #define NUBUS_ROM_TEST_PATTERN 0x5A932BC7 -#define NUBUS_BASE_TO_SLOT(x) (((((x)-NuBusBase) >> 24) & 0x0F) + \ - NUBUS_MIN_SLOT) -#define NUBUS_SLOT_TO_BASE(x) (NuBusBase + \ +#define NUBUS_SLOT_TO_PADDR(x) ( 0xF9000000 + \ ((((x)-NUBUS_MIN_SLOT) & 0xF) << 24)) -#define NUBUS_VIRT_TO_PHYS(x) ((x - NuBusBase) + \ - ((0xF0 | NUBUS_MIN_SLOT) << 24)) struct nubus_softc { struct device sc_dev; diff --git a/sys/arch/mac68k/dev/rd_root.c b/sys/arch/mac68k/dev/rd_root.c index e7ac28a3040..faea4c265fa 100644 --- a/sys/arch/mac68k/dev/rd_root.c +++ b/sys/arch/mac68k/dev/rd_root.c @@ -1,4 +1,4 @@ -/* $NetBSD: rd_root.c,v 1.1 1995/11/21 04:53:20 briggs Exp $ */ +/* $NetBSD: rd_root.c,v 1.3 1996/05/05 06:17:09 briggs Exp $ */ /* * Copyright (c) 1995 Gordon W. Ross @@ -47,9 +47,6 @@ extern int boothowto; int rd_root_size = ROOTBYTES; char rd_root_image[ROOTBYTES] = "|This is the root ramdisk!\n"; -/* - * This is called during autoconfig. - */ void rd_attach_hook(unit, rd) int unit; diff --git a/sys/arch/mac68k/dev/scsi.c b/sys/arch/mac68k/dev/scsi.c deleted file mode 100644 index 2d04207d2c3..00000000000 --- a/sys/arch/mac68k/dev/scsi.c +++ /dev/null @@ -1,1224 +0,0 @@ -/* $NetBSD: scsi.c,v 1.19 1995/09/03 03:39:38 briggs Exp $ */ - -/* - * This driver is obsolete as of 2 September 1995. mac68k5380.c should - * be used instead if at all possible. [briggs 2Sept95] - */ - -/* - * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, - * Michael L. Finch, Bradley A. Grantham, and - * Lawrence A. Kesteloot - * 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 the Alice Group. - * 4. The names of the Alice Group or any of its members may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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. - */ - -#define PSEUDO_DMA 1 - -static int pdebug = 0; - -#include <sys/types.h> -#include <sys/malloc.h> -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/errno.h> -#include <sys/buf.h> -#include <sys/proc.h> -#include <sys/user.h> -#include <sys/device.h> -#include <scsi/scsi_all.h> -#include <scsi/scsi_debug.h> -#include <scsi/scsiconf.h> - -#include "scsi_defs.h" -#define PAD(n) u_char n[15] -#include <machine/scsi_5380.h> -#undef PAD -#define SCI_PHASE_DISC 0 /* sort of ... */ -#define SCI_CLR_INTR(regs) {register int temp = regs->sci_iack;} -#define SCI_ACK(ptr,phase) (ptr)->sci_tcmd = (phase) -#define SCSI_TIMEOUT_VAL 10000000 -#define WAIT_FOR_NOT_REQ(ptr) { \ - int scsi_timeout = SCSI_TIMEOUT_VAL; \ - while ( ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \ - ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \ - ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \ - (--scsi_timeout) ); \ - if (!scsi_timeout) { \ - printf("scsi timeout--WAIT_FOR_NOT_REQ---scsi.c, line %d.\n", \ - __LINE__); \ - goto scsi_timeout_error; \ - } \ -} -#define WAIT_FOR_REQ(ptr) { \ - int scsi_timeout = SCSI_TIMEOUT_VAL; \ - while ( (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \ - (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \ - (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \ - (--scsi_timeout) ); \ - if (!scsi_timeout) { \ - printf("scsi timeout--WAIT_FOR_REQ---scsi.c, line %d.\n", \ - __LINE__); \ - goto scsi_timeout_error; \ - } \ -} -#define WAIT_FOR_BSY(ptr) { \ - int scsi_timeout = SCSI_TIMEOUT_VAL; \ - while ( (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \ - (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \ - (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \ - (--scsi_timeout) ); \ - if (!scsi_timeout) { \ - printf("scsi timeout--WAIT_FOR_BSY---scsi.c, line %d.\n", \ - __LINE__); \ - goto scsi_timeout_error; \ - } \ -} - -#ifdef DDB -int Debugger(); -#else -#define Debugger() panic("Should call Debugger here (mac/dev/scsi.c).") -#endif - -typedef unsigned long int physaddr; -typedef sci_regmap_t sci_padded_regmap_t; - -#define NNCR5380 1 - -struct ncr5380_softc { - struct device sc_dev; - - void *reg_base; - int adapter_target; - struct scsi_link sc_link; -}; -/* From Guide to Mac II family hardware, p. 137 */ -/* These are "adjusted" in the init routine. */ -extern vm_offset_t SCSIBase; -static volatile sci_padded_regmap_t *ncr = (sci_regmap_t *) 0x10000; -static volatile long *sci_4byte_addr = (long *) 0x6000; -static volatile u_char *sci_1byte_addr = (u_char *) 0x12000; - -static unsigned int ncr5380_adapter_info(struct ncr5380_softc * ncr5380); -static void ncr5380_minphys(struct buf * bp); -static int ncr5380_scsi_cmd(struct scsi_xfer * xs); - -static int ncr5380_show_scsi_cmd(struct scsi_xfer * xs); -static int ncr5380_reset_target(int adapter, int target); -static int ncr5380_poll(int adapter, int timeout); -static int ncr5380_send_cmd(struct scsi_xfer * xs); - -extern void ncr5380_intr(int adapter); -extern void spinwait(int); - -static int -scsi_gen(int adapter, int id, int lun, - struct scsi_generic * cmd, int cmdlen, - void *databuf, int datalen); -static int -scsi_group0(int adapter, int id, int lun, - int opcode, int addr, int len, - int flags, caddr_t databuf, int datalen); - -struct scsi_adapter ncr5380_switch = { - ncr5380_scsi_cmd, /* scsi_cmd() */ - ncr5380_minphys, /* scsi_minphys() */ - 0, /* open_target_lu() */ - 0, /* close_target_lu() */ -}; -/* This is copied from julian's bt driver */ -/* "so we have a default dev struct for our link struct." */ -struct scsi_device ncr5380_dev = { - NULL, /* Use default error handler. */ - NULL, /* have a queue, served by this (?) */ - NULL, /* have no async handler. */ - NULL, /* Use default "done" routine. */ -}; - -extern int matchbyname(); -static int ncrprobe(); -static void ncrattach(); - -struct cfdriver ncrscsicd = -{NULL, "ncrscsi", ncrprobe, ncrattach, -DV_DULL, sizeof(struct ncr5380_softc), NULL, 0}; - -static int -ncr_print(aux, name) - void *aux; - char *name; -{ - /* printf("%s: (sc_link = 0x%x)", name, (int) aux); return UNCONF; */ -} - -static int -ncrprobe(parent, match, aux) - struct device *parent; - void *match; - void *aux; -{ - static int probed = 0; - struct ncr5380_softc *ncr5380; - - if (!mac68k_machine.scsi80) { - return 0; - } - ncr5380 = (struct ncr5380_softc *) match; - - if (strcmp(*((char **) aux), ncr5380->sc_dev.dv_xname)) { - return 0; - } - if (!probed) { - /* - * Adjust values based on SCSIBase. - */ - ncr = (volatile sci_regmap_t *) (SCSIBase + (u_int) ncr); - sci_4byte_addr = (volatile long *) - (SCSIBase + (u_int) sci_4byte_addr); - sci_1byte_addr = (volatile u_char *) - (SCSIBase + (u_int) sci_1byte_addr); - probed = 1; - } - return 1; -} - -static void -ncrattach(parent, dev, aux) - struct device *parent, *dev; - void *aux; -{ - int unit = dev->dv_unit; - struct ncr5380_softc *ncr5380; - int r; - - ncr5380 = (struct ncr5380_softc *) dev; - - ncr5380->sc_link.scsibus = unit; - ncr5380->sc_link.adapter_target = 7; - ncr5380->sc_link.adapter = &ncr5380_switch; - ncr5380->sc_link.device = &ncr5380_dev; - ncr5380->sc_link.openings = 1; -#ifdef SCSIDEBUG - ncr5380->sc_link.flags = SDEV_DB1 | SDEV_DB2 /* | SDEV_DB3 | SDEV_DB4 */ ; -#endif - - printf("\n"); - - config_found(dev, &(ncr5380->sc_link), ncr_print); -} - -#define MIN_PHYS 65536 /* BARF!!!! */ -static void -ncr5380_minphys(struct buf * bp) -{ - if (bp->b_bcount > MIN_PHYS) { - printf("Uh-oh... ncr5380_minphys setting bp->b_bcount = %x.\n", MIN_PHYS); - bp->b_bcount = MIN_PHYS; - } - minphys(bp); -} -#undef MIN_PHYS - -static int -ncr5380_scsi_cmd(struct scsi_xfer * xs) -{ - int flags, s, r; - - flags = xs->flags; - if (xs->bp) - flags |= (SCSI_NOSLEEP); - if (flags & ITSDONE) { - printf("Already done?"); - xs->flags &= ~ITSDONE; - } - if (!(flags & INUSE)) { - printf("Not in use?"); - xs->flags |= INUSE; - } - if (flags & SCSI_RESET) { - printf("flags & SCSIRESET.\n"); - s = splbio(); - ncr5380_reset_target(xs->sc_link->scsibus, - xs->sc_link->target); - splx(s); - return (COMPLETE); - } - xs->resid = 0; - r = ncr5380_send_cmd(xs); - xs->flags |= ITSDONE; - scsi_done(xs); -#ifdef SCSIDEBUG - printf("SCSI transfer done.\n"); -#endif /* SCSIDEBUG */ - switch (r) { - case COMPLETE: - case SUCCESSFULLY_QUEUED: - r = SUCCESSFULLY_QUEUED; - if (xs->flags & SCSI_POLL) - r = COMPLETE; - break; - default: - break; - } - return r; -} - -static int -ncr5380_show_scsi_cmd(struct scsi_xfer * xs) -{ - u_char *b = (u_char *) xs->cmd; - int i = 0; - - if (!(xs->flags & SCSI_RESET)) { - printf("ncr5380(%d:%d:%d)-", - xs->sc_link->scsibus, xs->sc_link->target, xs->sc_link->lun); - while (i < xs->cmdlen) { - if (i) - printf(","); - printf("%x", b[i++]); - } - printf("-\n"); - } else { - printf("ncr5380(%d:%d:%d)-RESET-\n", - xs->sc_link->scsibus, xs->sc_link->target, xs->sc_link->lun); - } -} -/* - * Actual chip control. - */ - -extern void -spinwait(int ms) -{ - while (ms--) - delay(1000); -} - -extern void -ncr5380_intr(int adapter) -{ - register volatile sci_padded_regmap_t *regs = ncr; - - SCI_CLR_INTR(regs); - regs->sci_mode = 0x00; -} - -extern int -ncr5380_irq_intr(void) -{ - register volatile sci_padded_regmap_t *regs = ncr; - -/* if (regs->sci_csr != SCI_CSR_PHASE_MATCH) - printf("scsi_irq_intr called (not just phase match -- " - "csr = 0x%x, bus_csr = 0x%x).\n", - regs->sci_csr, regs->sci_bus_csr); - ncr5380_intr(0); */ - return 1; -} - -extern int -ncr5380_drq_intr(void) -{ -/* printf("scsi_drq_intr called.\n"); */ -/* ncr5380_intr(0); */ - return 1; -} - -static int -ncr5380_reset_target(int adapter, int target) -{ - register volatile sci_padded_regmap_t *regs = ncr; - int dummy; - - regs->sci_icmd = SCI_ICMD_TEST; - regs->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST; - spinwait(250); /* 250 ms */ - regs->sci_icmd = 0; - - regs->sci_mode = 0; - regs->sci_tcmd = SCI_PHASE_DISC; - regs->sci_sel_enb = 0; - - SCI_CLR_INTR(regs); - SCI_CLR_INTR(regs); -} - -static int -ncr5380_poll(int adapter, int timeout) -{ -} - -static int -ncr5380_send_cmd(struct scsi_xfer * xs) -{ - int s; - int sense; - -#ifdef SCSIDEBUG - ncr5380_show_scsi_cmd(xs); -#endif - s = splbio(); - sense = scsi_gen(xs->sc_link->scsibus, xs->sc_link->target, - xs->sc_link->lun, xs->cmd, xs->cmdlen, - xs->data, xs->datalen); - splx(s); - if (sense) { - switch (sense) { - case 0x02: /* Check condition */ -/* printf("check cond. target %d.\n", xs->targ);*/ - s = splbio(); - scsi_group0(xs->sc_link->scsibus, - xs->sc_link->target, - xs->sc_link->lun, - 0x3, 0x0, - sizeof(struct scsi_sense_data), - 0, (caddr_t) & (xs->sense), - sizeof(struct scsi_sense_data)); - splx(s); - xs->error = XS_SENSE; - return COMPLETE; - case 0x08: /* Busy */ - xs->error = XS_BUSY; - return COMPLETE; - default: - xs->error = XS_DRIVER_STUFFUP; - return COMPLETE; - } - } - xs->error = XS_NOERROR; - return (COMPLETE); -} - -static int -select_target(register volatile sci_padded_regmap_t * regs, - u_char myid, u_char tid, int with_atn) -{ - register u_char bid, icmd; - int ret = SCSI_RET_RETRY; - - if ((regs->sci_bus_csr & (SCI_BUS_BSY | SCI_BUS_SEL)) && - (regs->sci_bus_csr & (SCI_BUS_BSY | SCI_BUS_SEL)) && - (regs->sci_bus_csr & (SCI_BUS_BSY | SCI_BUS_SEL))) - return ret; - - /* for our purposes.. */ - myid = 1 << myid; - tid = 1 << tid; - - regs->sci_sel_enb = 0; /* myid; we don't want any interrupts. */ - regs->sci_tcmd = 0; /* Get into a harmless state. */ - regs->sci_mode = 0; /* Get into a harmless state. */ - - regs->sci_odata = myid; - regs->sci_mode = SCI_MODE_ARB; -/* regs->sci_mode |= SCI_MODE_ARB; */ - /* AIP might not set if BSY went true after we checked */ - for (bid = 0; bid < 20; bid++) /* 20usec circa */ - if (regs->sci_icmd & SCI_ICMD_AIP) - break; - if ((regs->sci_icmd & SCI_ICMD_AIP) == 0) { - goto lost; - } - delay(3); /* 2.4us arb delay */ - - if (regs->sci_icmd & SCI_ICMD_LST) { - goto lost; - } - regs->sci_mode &= ~SCI_MODE_PAR_CHK; - bid = regs->sci_data; - - if ((bid & ~myid) > myid) { - goto lost; - } - if (regs->sci_icmd & SCI_ICMD_LST) { - goto lost; - } - /* Won arbitration, enter selection phase now */ - icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF | SCI_ICMD_TEST); - icmd |= (with_atn ? (SCI_ICMD_SEL | SCI_ICMD_ATN) : SCI_ICMD_SEL); - icmd |= SCI_ICMD_BSY; - regs->sci_icmd = icmd; - - if (regs->sci_icmd & SCI_ICMD_LST) { - goto nosel; - } - /* XXX a target that violates specs might still drive the bus XXX */ - /* XXX should put our id out, and after the delay check nothi XXX */ - /* XXX ng else is out there. XXX */ - - delay(1); - - regs->sci_tcmd = 0; - regs->sci_odata = myid | tid; - regs->sci_sel_enb = 0; - -/* regs->sci_mode &= ~SCI_MODE_ARB; 2 deskew delays, too */ - regs->sci_mode = 0; /* 2 deskew delays, too */ - - icmd |= SCI_ICMD_DATA; - icmd &= ~(SCI_ICMD_BSY); - - regs->sci_icmd = icmd; - - /* bus settle delay, 400ns */ - delay(1); /* 1us > 400ns ;-) */ - -/* regs->sci_mode |= SCI_MODE_PAR_CHK; */ - - { - register int timeo = 2500; /* 250 msecs in 100 usecs - * chunks */ - while ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) { - if (--timeo > 0) { - delay(100); - } else { - goto nodev; - } - } - } - - icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_SEL); - regs->sci_icmd = icmd; - /* regs->sci_sel_enb = myid;*//* looks like we should NOT have it */ - return SCSI_RET_SUCCESS; -nodev: - ret = SCSI_RET_DEVICE_DOWN; - regs->sci_sel_enb = myid; -nosel: - icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_SEL | SCI_ICMD_ATN); - regs->sci_icmd = icmd; -lost: - regs->sci_mode = 0; - - return ret; -} - -static int -sci_data_out(regs, phase, count, data) - register sci_padded_regmap_t *regs; - unsigned char *data; -{ - register unsigned char icmd; - register int cnt = 0; - - /* ..checks.. */ - - icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF | SCI_ICMD_TEST); -loop: - if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase) - return cnt; - - WAIT_FOR_REQ(regs); - icmd |= SCI_ICMD_DATA; - regs->sci_icmd = icmd; - regs->sci_odata = *data++; - icmd |= SCI_ICMD_ACK; - regs->sci_icmd = icmd; - - icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_ACK); - WAIT_FOR_NOT_REQ(regs); - regs->sci_icmd = icmd; - ++cnt; - if (--count > 0) - goto loop; -scsi_timeout_error: - return cnt; -} - -static int -sci_data_in(regs, phase, count, data) - register sci_padded_regmap_t *regs; - unsigned char *data; -{ - register unsigned char icmd; - register int cnt = 0; - - /* ..checks.. */ - - icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF | SCI_ICMD_TEST); - -loop: - if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase) - return cnt; - - WAIT_FOR_REQ(regs); - *data++ = regs->sci_data; - icmd |= SCI_ICMD_ACK; - regs->sci_icmd = icmd; - - icmd &= ~SCI_ICMD_ACK; - WAIT_FOR_NOT_REQ(regs); - regs->sci_icmd = icmd; - ++cnt; - if (--count > 0) - goto loop; - -scsi_timeout_error: - return cnt; -} - -static int -command_transfer(register volatile sci_padded_regmap_t * regs, - int maxlen, u_char * data, u_char * status, u_char * msg) -{ - int xfer = 0, phase; - -/* printf("command_transfer called for 0x%x.\n", *data); */ - - regs->sci_icmd = 0; - - while (1) { - - WAIT_FOR_REQ(regs); - - phase = SCI_CUR_PHASE(regs->sci_bus_csr); - - switch (phase) { - case SCSI_PHASE_CMD: - SCI_ACK(regs, SCSI_PHASE_CMD); - xfer += sci_data_out(regs, SCSI_PHASE_CMD, - maxlen, data); - return xfer; - case SCSI_PHASE_DATA_IN: - printf("Data in phase in command_transfer?\n"); - return 0; - case SCSI_PHASE_DATA_OUT: - printf("Data out phase in command_transfer?\n"); - return 0; - case SCSI_PHASE_STATUS: - SCI_ACK(regs, SCSI_PHASE_STATUS); - printf("status in command_transfer.\n"); - sci_data_in(regs, SCSI_PHASE_STATUS, - 1, status); - break; - case SCSI_PHASE_MESSAGE_IN: - SCI_ACK(regs, SCSI_PHASE_MESSAGE_IN); - printf("msgin in command_transfer.\n"); - sci_data_in(regs, SCSI_PHASE_MESSAGE_IN, - 1, msg); - break; - case SCSI_PHASE_MESSAGE_OUT: - SCI_ACK(regs, SCSI_PHASE_MESSAGE_OUT); - sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT, - 1, msg); - break; - default: - printf("Unexpected phase 0x%x in " - "command_transfer().\n", phase); - scsi_timeout_error: - return xfer; - break; - } - } -} - -static int -data_transfer(register volatile sci_padded_regmap_t * regs, - int maxlen, u_char * data, u_char * status, u_char * msg) -{ - int retlen = 0, xfer, phase; - - regs->sci_icmd = 0; - - *status = 0; - - while (1) { - - WAIT_FOR_REQ(regs); - - phase = SCI_CUR_PHASE(regs->sci_bus_csr); - - switch (phase) { - case SCSI_PHASE_CMD: - printf("Command phase in data_transfer().\n"); - return retlen; - case SCSI_PHASE_DATA_IN: - SCI_ACK(regs, SCSI_PHASE_DATA_IN); -#if PSEUDO_DMA - xfer = sci_pdma_in(regs, SCSI_PHASE_DATA_IN, - maxlen, data); -#else - xfer = sci_data_in(regs, SCSI_PHASE_DATA_IN, - maxlen, data); -#endif - retlen += xfer; - maxlen -= xfer; - break; - case SCSI_PHASE_DATA_OUT: - SCI_ACK(regs, SCSI_PHASE_DATA_OUT); -#if PSEUDO_DMA - xfer = sci_pdma_out(regs, SCSI_PHASE_DATA_OUT, - maxlen, data); -#else - xfer = sci_data_out(regs, SCSI_PHASE_DATA_OUT, - maxlen, data); -#endif - retlen += xfer; - maxlen -= xfer; - break; - case SCSI_PHASE_STATUS: - SCI_ACK(regs, SCSI_PHASE_STATUS); - sci_data_in(regs, SCSI_PHASE_STATUS, - 1, status); - break; - case SCSI_PHASE_MESSAGE_IN: - SCI_ACK(regs, SCSI_PHASE_MESSAGE_IN); - sci_data_in(regs, SCSI_PHASE_MESSAGE_IN, - 1, msg); - if (*msg == 0) { - return retlen; - } else { - printf("message 0x%x in " - "data_transfer.\n", *msg); - } - break; - case SCSI_PHASE_MESSAGE_OUT: - SCI_ACK(regs, SCSI_PHASE_MESSAGE_OUT); - sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT, - 1, msg); - break; - default: - printf("Unexpected phase 0x%x in " - "data_transfer().\n", phase); - scsi_timeout_error: - return retlen; - break; - } - } -} - -static int -scsi_request(register volatile sci_padded_regmap_t * regs, - int target, int lun, u_char * cmd, int cmdlen, - char *databuf, int datalen, int *sent, int *ret) -{ -/* Returns 0 on success, -1 on internal error, or the status byte */ - int cmd_bytes_sent, r; - u_char stat, msg, c; - - *sent = 0; - - if ((r = select_target(regs, 7, target, 1)) != SCSI_RET_SUCCESS) { - *ret = r; - SCI_CLR_INTR(regs); - switch (r) { - case SCSI_RET_RETRY: - return 0x08; - default: - printf("select_target(target %d, lun %d) failed(%d).\n", - target, lun, r); - case SCSI_RET_DEVICE_DOWN: - return -1; - } - } - c = 0x80 | lun; - - if ((cmd_bytes_sent = command_transfer(regs, cmdlen, - (u_char *) cmd, &stat, &c)) - != cmdlen) { - SCI_CLR_INTR(regs); - *ret = SCSI_RET_COMMAND_FAIL; - printf("Data underrun sending CCB (%d bytes of %d, sent).\n", - cmd_bytes_sent, cmdlen); - return -1; - } - *sent = data_transfer(regs, datalen, (u_char *) databuf, - &stat, &msg); - - *ret = 0; - - return stat; -} - -static int -scsi_gen(int adapter, int id, int lun, struct scsi_generic * cmd, - int cmdlen, void *databuf, int datalen) -{ - register volatile sci_padded_regmap_t *regs = ncr; - int i, j, sent, ret; - - cmd->bytes[0] = ((u_char) lun << 5); - - i = scsi_request(regs, id, lun, (u_char *) cmd, cmdlen, - databuf, datalen, &sent, &ret); - - return i; -} - -static int -scsi_group0(int adapter, int id, int lun, int opcode, int addr, int len, - int flags, caddr_t databuf, int datalen) -{ - register volatile sci_padded_regmap_t *regs = ncr; - unsigned char cmd[6]; - int i, j, sent, ret; - - cmd[0] = opcode; /* Operation code */ - cmd[1] = (lun << 5) | ((addr >> 16) & 0x1F); /* Lun & MSB of addr */ - cmd[2] = (addr >> 8) & 0xFF; /* addr */ - cmd[3] = addr & 0xFF; /* LSB of addr */ - cmd[4] = len; /* Allocation length */ - cmd[5] = flags; /* Link/Flag */ - - i = scsi_request(regs, id, lun, cmd, 6, databuf, datalen, &sent, &ret); - - return i; -} -/* pseudo-dma action */ - -#if PSEUDO_DMA - -#define TIMEOUT 1000000 -#define READY(poll) \ - i = TIMEOUT; \ - while ((regs->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) \ - !=(SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) \ - if ( !(regs->sci_csr & SCI_CSR_PHASE_MATCH) \ - || !(regs->sci_bus_csr & SCI_BUS_BSY) \ - || (i-- < 0) ) { \ - printf("scsi.c: timeout counter = %d, len = %d count=%d (count-len %d).\n", \ - i, len,count,count-len); \ - printf("pdebug = %d, 1=out, 2=in",pdebug); \ - /*dump_regs();*/ \ - if (poll && !(regs->sci_csr & SCI_CSR_PHASE_MATCH)) { \ - regs->sci_icmd &= ~SCI_ICMD_DATA; \ - len--; \ - } else { \ - regs->sci_mode &= ~SCI_MODE_DMA; \ - } \ - return count-len; \ - } - -#define W1 *byte_data = *data++ -#define W4 *long_data = *((long*)data)++ - -sci_pdma_out(regs, phase, count, data) - register volatile sci_padded_regmap_t *regs; - int phase; - int count; - u_char *data; -{ - register volatile long *long_data = sci_4byte_addr; - register volatile u_char *byte_data = sci_1byte_addr; - register int len = count, i; - - pdebug = 1; - - if (count < 128) - return sci_data_out(regs, phase, count, data); - - WAIT_FOR_BSY(regs); - regs->sci_mode |= SCI_MODE_DMA; - regs->sci_icmd |= SCI_ICMD_DATA; - regs->sci_dma_send = 0; - - while (len >= 64) { - READY(1); - W1; - READY(1); - W1; - READY(1); - W1; - READY(1); - W1; - READY(1); - W4; - W4; - W4; - W4; - W4; - W4; - W4; - W4; - W4; - W4; - W4; - W4; - W4; - W4; - W4; - len -= 64; - } - while (len) { - READY(1); - W1; - len--; - } - i = TIMEOUT; - while (((regs->sci_csr & (SCI_CSR_DREQ | SCI_CSR_PHASE_MATCH)) - == SCI_CSR_PHASE_MATCH) && --i); - if (!i) - printf("scsi.c:%d: timeout waiting for SCI_CSR_DREQ.\n", __LINE__); - *byte_data = 0; -scsi_timeout_error: - regs->sci_mode &= ~SCI_MODE_DMA; - return count - len; -} -#undef W1 -#undef W4 - -#define R4 *((long *)data)++ = *long_data -#define R1 *data++ = *byte_data - -sci_pdma_in(regs, phase, count, data) - register volatile sci_padded_regmap_t *regs; - int phase; - int count; - u_char *data; -{ - register volatile long *long_data = sci_4byte_addr; - register volatile u_char *byte_data = sci_1byte_addr; - register int len = count, i; - - pdebug = 2; - if (count < 128) - return sci_data_in(regs, phase, count, data); - -/* printf("Called sci_pdma_in(0x%x, 0x%x, %d, 0x%x.\n", regs, phase, count, data); */ - - WAIT_FOR_BSY(regs); - regs->sci_mode |= SCI_MODE_DMA; - regs->sci_icmd |= SCI_ICMD_DATA; - regs->sci_irecv = 0; - - while (len >= 1024) { - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 128 */ - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 256 */ - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 384 */ - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 512 */ - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 640 */ - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 768 */ - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 896 */ - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 1024 */ - len -= 1024; - } - while (len >= 128) { - READY(0); - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; - R4; /* 128 */ - len -= 128; - } - while (len) { - READY(0); - R1; - len--; - } -scsi_timeout_error: - regs->sci_mode &= ~SCI_MODE_DMA; - return count - len; -} -#undef R4 -#undef R1 -#endif diff --git a/sys/arch/mac68k/dev/scsi96.c b/sys/arch/mac68k/dev/scsi96.c index d6a9abbf303..4adfc02979b 100644 --- a/sys/arch/mac68k/dev/scsi96.c +++ b/sys/arch/mac68k/dev/scsi96.c @@ -1,4 +1,4 @@ -/* $NetBSD: scsi96.c,v 1.13 1995/08/14 03:55:28 briggs Exp $ */ +/* $NetBSD: scsi96.c,v 1.17 1996/05/05 06:17:19 briggs Exp $ */ /* * Copyright (C) 1994 Allen K. Briggs @@ -47,13 +47,11 @@ #include <scsi/scsiconf.h> #include <machine/scsi96reg.h> -#include "../mac68k/via.h" +#include <machine/viareg.h> /* Support for the NCR 53C96 SCSI processor--primarily for '040 Macs. */ -#ifdef DDB -int Debugger(); -#else +#ifndef DDB #define Debugger() panic("Should call Debugger here (mac/dev/scsi96.c).") #endif @@ -78,7 +76,6 @@ struct ncr53c96_softc { } \ } -static unsigned int ncr53c96_adapter_info(struct ncr53c96_softc * ncr53c96); static void ncr53c96_minphys(struct buf * bp); static int ncr53c96_scsi_cmd(struct scsi_xfer * xs); @@ -102,20 +99,25 @@ struct scsi_device ncr53c96_dev = { NULL, /* Use default "done" routine. */ }; -extern int matchbyname(); -static int ncr96probe(); -static void ncr96attach(); +static int ncr96probe __P((struct device *, void *, void *)); +static void ncr96attach __P((struct device *, struct device *, void *)); -struct cfdriver ncr96scsicd = -{NULL, "ncr96scsi", ncr96probe, ncr96attach, -DV_DULL, sizeof(struct ncr53c96_softc), NULL, 0}; +struct cfattach ncr96scsi_ca = { + sizeof(struct ncr53c96_softc), ncr96probe, ncr96attach +}; + +struct cfdriver ncr96scsi_cd = { + NULL, "ncr96scsi", DV_DULL, NULL, 0 +}; +static int ncr96_print __P((void *, char *)); static int ncr96_print(aux, name) void *aux; char *name; { /* printf("%s: (sc_link = 0x%x)", name, (int) aux); return UNCONF; */ + return UNCONF; } static int @@ -125,17 +127,12 @@ ncr96probe(parent, match, aux) void *aux; { static int probed = 0; - struct ncr53c96_softc *ncr53c96; return 0; if (!mac68k_machine.scsi96) { return 0; } - ncr53c96 = (struct ncr53c96_softc *) match; - if (strcmp(*((char **) aux), ncr53c96->sc_dev.dv_xname)) { - return 0; - } if (!probed) { probed = 1; ncr53c96base += SCSIBase; @@ -150,7 +147,6 @@ ncr96attach(parent, dev, aux) { int unit = dev->dv_unit; struct ncr53c96_softc *ncr53c96; - int r; ncr53c96 = (struct ncr53c96_softc *) dev; @@ -280,16 +276,22 @@ ncr53c96_show_scsi_cmd(struct scsi_xfer * xs) xs->sc_link->scsibus, xs->sc_link->target, xs->sc_link->lun); } + return 0; } + /* * Actual chip control. */ +extern void ncr53c96_intr __P((int)); + extern void ncr53c96_intr(int adapter) { } +extern int ncr53c96_irq_intr __P((void)); + extern int ncr53c96_irq_intr(void) { @@ -297,6 +299,7 @@ ncr53c96_irq_intr(void) return 1; } +extern int ncr53c96_drq_intr __P((void)); extern int ncr53c96_drq_intr(void) { @@ -307,11 +310,13 @@ ncr53c96_drq_intr(void) static int ncr53c96_reset_target(int adapter, int target) { +return 0; } static int ncr53c96_poll(int adapter, int timeout) { +return 0; } static int @@ -320,7 +325,7 @@ do_send_cmd(struct scsi_xfer * xs) struct ncr53c96regs *ncr = (struct ncr53c96regs *) ncr53c96base; u_char *cmd; int i, stat, is, intr; - int status, msg, phase; + int msg, phase; xs->resid = 0; i = (int) ncr->statreg; /* clear interrupts */ @@ -352,7 +357,7 @@ do_send_cmd(struct scsi_xfer * xs) "datalen = %d\n", stat, is, intr, xs->datalen); phase = ncr->statreg & NCR96_STAT_PHASE; if (((phase == 0x01) || (phase == 0x00)) && xs->datalen) { - printf("data = 0x%x, datalen = 0x%x.\n", xs->data, xs->datalen); + printf("data = %p, datalen = 0x%x.\n", xs->data, xs->datalen); stat = ncr->statreg; is = ncr->isreg; intr = ncr->instreg; @@ -381,8 +386,8 @@ do_send_cmd(struct scsi_xfer * xs) } intr = ncr->instreg; - printf("\nin loop. stat = 0x%x, intr = 0x%x, cnt = %d. ", - stat, intr, cnt); + printf("\nin loop. stat = 0x%x, intr = 0x%x", + stat, intr); printf("rem... %d.\n", ncr->tcreg_lsb | (ncr->tcreg_msb << 8)); } /* } else { diff --git a/sys/arch/mac68k/dev/ser.c b/sys/arch/mac68k/dev/ser.c deleted file mode 100644 index ba565105d6f..00000000000 --- a/sys/arch/mac68k/dev/ser.c +++ /dev/null @@ -1,2033 +0,0 @@ -/* $NetBSD: ser.c,v 1.34 1996/01/12 04:16:25 briggs Exp $ */ - -/* - * Copyright (c) 1994 Gordon W. Ross - * 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. - * - * @(#)zs.c 8.1 (Berkeley) 7/19/93 - */ - -/* - * Originally a custom driver. - * Hacked by Brad Parker, <brad@fcr.com> - * added CTS input flow control - * added DCD event detection - * added software fifo's - * - * Mac II serial device interface - * - * Information used in this source was gleaned from low-memory - * global variables in MacOS and the Advanced Micro Devices - * 1992 Data Book/Handbook. - * - * Further hacked by Bill Studenmund <wrstuden@loki.stanford.edu> - * merged in much of the sun's SCC code, hence the new - * copyright--there's not much original ser.c code in - * here at all. - * - * Further information from Zilog Serial Communication Controllers - * databook. - */ - - -/* - * Zilog Z8530 (ZSCC) driver. - * - * Runs two tty ports (ttya and ttyb) on zs0, - * and runs a keyboard and mouse on zs1. (at least on a sun it will!) - * - * This driver knows far too much about chip to usage mappings. - */ -#define NZS 1 /* XXX */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/ioctl.h> -#include <sys/tty.h> -#include <sys/proc.h> -#include <sys/conf.h> -#include <sys/file.h> -#include <sys/uio.h> -#include <sys/kernel.h> -#include <sys/syslog.h> -#include <sys/device.h> - -#include <machine/cpu.h> -#include <machine/frame.h> - -#include <dev/cons.h> - -#undef LOCORE -#include "z8530reg.h" -#include "zsvar.h" - -/* Defines for mapping zs onto the mac68k. */ -#undef ZS_DELAY() -#define ZS_DELAY() -#define mon_printf printf -#define splzs spl4 -#define isr_soft_clear(x) -#define isr_soft_request(x) setsoftserial() -#define isr_add_autovect(x, y, z) -#define ZS_CHAN(x) (volatile struct zschan *)(((long)addr)+x*2) -#define ZS_CONS_A (volatile struct zschan *)1 -#define ZS_CONS_B (volatile struct zschan *)2 -/* magic cookies for console stuff. If zsconschan is one of these, we look at sccA all the time */ -#define zsopen seropen -#define zsclose serclose -#define zsioctl serioctl -#define zsread serread -#define zswrite serwrite -#define zsparam serparam -#define zsstart serstart -#define zsstop serstop -#define zstty sertty - -#define ZSMAJOR 12 /* XXX */ - -#define ZSHARD_PRI 4 /* Wired on the CPU board... */ -#define ZSSOFT_PRI 3 /* Want tty pri (4) but this is OK. */ - -#define ZS_KBD 2 /* XXX */ -#define ZS_MOUSE 3 /* XXX */ -#define ZSDEF_CFLAG (CREAD | CS8 | HUPCL ) - -/* - * Below calculation gets us to the chip clock value. - */ -#define PCLK (mac68k_machine.sccClkConst*2) - -#define ZS_HFC (ZSRR0_DCD | ZSRR0_CTS) - -/* - * Software state per found chip. This would be called `zs_softc', - * but the previous driver had a rather different zs_softc.... - */ -struct zsinfo { - struct device zi_dev; /* base device */ - volatile struct zsdevice *zi_zs;/* chip registers */ - struct zs_chanstate zi_cs[2]; /* channel A and B software state */ -}; - -static struct tty *zs_tty[NZS * 2]; /* XXX should be dynamic */ - -extern int matchbyname(); -static void serinit(int); - -/* Definition of the driver for autoconfig. */ -static int zs_match(struct device *, void *, void *); -static void zs_attach(struct device *, struct device *, void *); - -struct cfdriver sercd = { - NULL, "ser", matchbyname, zs_attach, DV_TTY, sizeof(struct zsinfo) -}; - -#define zscd sercd -/* HACK until finished cleaning up configuration stuff */ - -/* Interrupt handlers. */ -int zshard(int); -int zssoft(int); -void zsinit(void); - -struct zs_chanstate *zslist = 0; - -volatile unsigned char *sccA = 0; - -static void serstart __P((register struct tty *)); -static int serparam __P((register struct tty *, register struct termios *)); - -/* Routines called from other code. */ -int zsopen(dev_t, int, int, struct proc *); -int zsclose(dev_t, int, int, struct proc *); -static void zsiopen(struct tty *); -static void zsiclose(struct tty *); -static void zsstart(struct tty *); -void zsstop(struct tty *, int); -static int zsparam(struct tty *, struct termios *); - -/* Routines purely local to this driver. */ -static int zs_getspeed(volatile struct zschan *); -static void zs_reset(volatile struct zschan *, int, int); -static void zs_modem(struct zs_chanstate *, int); -static void zs_loadchannelregs(volatile struct zschan *, u_char *); -static u_char zs_read(volatile struct zschan *, u_char); -static u_char zs_write(volatile struct zschan *, u_char, u_char); -static void zs_restart(struct zs_chanstate *, volatile struct zschan *); - -/* Console stuff. */ -volatile struct zschan *zs_conschan = 0; - -#ifdef KGDB -/* KGDB stuff. Must reboot to change zs_kgdbunit. */ -extern int kgdb_dev, kgdb_rate; -static int zs_kgdb_savedspeed; -static void zs_checkkgdb(int, struct zs_chanstate *, struct tty *); -#endif - -static int initted = 0; -static int serdefaultrate = 9600; - -static int zsinitted = 0; - -extern struct tty *constty; - -#define UNIT(x) minor(x) -/* #define SER_TTY(unit) \ - (((struct ser_softc *) sercd.cd_devs[unit])->sc_tty) */ - -/* - * Console keyboard L1-A processing is done in the hardware interrupt code, - * so we need to duplicate some of the console keyboard decode state. (We - * must not use the regular state as the hardware code keeps ahead of the - * software state: the software state tracks the most recent ring input but - * the hardware state tracks the most recent ZSCC input.) See also kbd.h. - */ -static struct conk_state { /* console keyboard state */ - char conk_id; /* true => ID coming up (console only) */ - char conk_l1; /* true => L1 pressed (console only) */ -} zsconk_state; - -int zshardscope; -int zsshortcuts; /* number of "shortcut" software interrupts */ - -int zssoftpending; /* We have done isr_soft_request() */ - -static struct zsdevice *zsaddr[NZS]; /* XXX, but saves work */ - -/* Default OBIO addresses. */ -/* static int zs_physaddr[NZS] = { OBIO_ZS, OBIO_KEYBD_MS }; not until we have OBIO */ - -static u_char zs_init_reg[16] = { - 0, /* 0: CMD (reset, etc.) */ - ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE, - 0x18 + ZSHARD_PRI, /* IVECT */ - ZSWR3_RX_8 | ZSWR3_RX_ENABLE, - ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP, - /* ZSWR5_TX_8 | ZSWR5_TX_ENABLE | ZSWR5_RTS, */ - ZSWR5_TX_8 | ZSWR5_TX_ENABLE | ZSWR5_RTS | ZSWR5_DTR, - 0, /* 6: TXSYNC/SYNCLO */ - 0, /* 7: RXSYNC/SYNCHI */ - 0, /* 8: alias for data port */ - 0, /* 9: ZSWR9_MASTER_IE (later) */ - 0, /*10: Misc. TX/RX control bits */ - ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD, - 0, /*12: BAUDLO (later) */ - 0, /*13: BAUDHI (later) */ -/* ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA, */ - ZSWR14_BAUD_ENA, -/* ZSWR15_BREAK_IE | ZSWR15_DCD_IE | ZSWR15_CTS_IE, */ - ZSWR15_DCD_IE | ZSWR15_CTS_IE, -}; - -/* Find PROM mappings (for console support). */ -void zs_init() -{ - int i; - - for (i = 0; i < NZS; i++) { - /* zsaddr[i] = (struct zsdevice *) - obio_find_mapping(zs_physaddr[i], OBIO_ZS_SIZE); */ - } -} - -/* - * Match slave number to zs unit number, so that misconfiguration will - * not set up the keyboard as ttya, etc. - */ -static int -zs_match(struct device *parent, void *vcf, void *args) -{ - struct cfdata *cf = vcf; - struct confargs *ca = args; - int unit, x; - void *zsva; - - unit = cf->cf_unit; - if (unit < 0 || unit >= NZS) - return (0); - - zsva = zsaddr[unit]; - if (zsva == NULL) - return (0); - -/* if (ca->ca_paddr == -1) - ca->ca_paddr = zs_physaddr[unit]; - if (ca->ca_intpri == -1) - ca->ca_intpri = ZSHARD_PRI; -*/ - /* This returns -1 on a fault (bus error). */ -/* x = peek_byte(zsva); */ - return (x != -1); -} - -/* - * Attach a found zs. - * - * USE ROM PROPERTIES port-a-ignore-cd AND port-b-ignore-cd FOR - * SOFT CARRIER, AND keyboard PROPERTY FOR KEYBOARD/MOUSE? - */ -static void -zs_attach(struct device *parent, struct device *self, void *args) -{ - struct cfdata *cf; - struct confargs *ca; - register int zs, unit; - register struct zsinfo *zi; - register struct zs_chanstate *cs; - register volatile struct zsdevice *addr; - register struct tty *tp, *ctp; - int softcar; - static int didintr; - - cf = self->dv_cfdata; - zs = self->dv_unit; - ca = args; - -#ifdef DEBUG - printf(" softpri %d\n", ZSSOFT_PRI); -#endif - if (self->dv_unit != 0) {printf("\n"); return;} /* Hack for now */ - - if (!zsinitted) zsinit(); - if (zsaddr[zs] == NULL) - panic("zs_attach: zs%d not mapped\n", zs); - addr = zsaddr[zs]; - - if (!didintr) { - didintr = 1; - /* On the mac, these are not used. */ - isr_add_autovect(zssoft, NULL, ZSSOFT_PRI); - isr_add_autovect(zshard, NULL, ZSHARD_PRI); - } - - if ((zs_conschan == ZS_CONS_A) || (zs_conschan == ZS_CONS_B)) { - volatile struct zsdevice *addr; - addr = (volatile struct zsdevice *)sccA; - zs_conschan = ((zs_conschan == ZS_CONS_A) ? (ZS_CHAN(ZS_CHAN_A)):(ZS_CHAN(ZS_CHAN_B))); - /* the IO mapping won't be changing after here, so we can solidify the address */ - } - - zi = (struct zsinfo *)self; - zi->zi_zs = addr; - unit = zs * 2; - cs = zi->zi_cs; - softcar = cf->cf_flags; - - if(!zs_tty[unit]) - zs_tty[unit] = ttymalloc(); - if(!zs_tty[unit+1]) - zs_tty[unit+1] = ttymalloc(); -#ifdef DEBUG - printf("units are %x, %x\n", zs_tty[unit], zs_tty[unit+1]); -#endif - - /* link into interrupt list with order (A,B) (B=A+1) */ - cs[0].cs_next = &cs[1]; - cs[1].cs_next = zslist; - zslist = cs; - - cs->cs_unit = unit; - cs->cs_zc = ZS_CHAN(ZS_CHAN_A); -#ifdef DEBUG - printf("zs channel a at %x\n",cs->cs_zc); -#endif - cs->cs_speed = zs_getspeed(cs->cs_zc); -#ifdef DEBUG - mon_printf("zs%da speed %d ", zs, cs->cs_speed); -#endif - cs->cs_softcar = softcar & 1; - cs->cs_rr0_mask = 0; /* CTS is broken on the mac */ - cs->cs_SFC = 0; - cs->cs_holdSFC = 0; - cs->cs_tiu = 0; - - tp = zs_tty[unit]; - cs->cs_ttyp = tp; - tp->t_dev = makedev(ZSMAJOR, unit); - tp->t_oproc = zsstart; - tp->t_param = zsparam; - if ((cs->cs_zc == zs_conschan) && (mac68k_machine.serial_console & 0x01)) { -#ifdef DEBUG - printf("We got a console!, unit %d\n",unit); -#endif - /* This unit is the console. */ - cs->cs_consio = 1; - cs->cs_brkabort = /* 1 */ 0; - cs->cs_softcar = 1; - /* Call zsparam so interrupts get enabled. */ - tp->t_ispeed = tp->t_ospeed = cs->cs_speed; - tp->t_iflag = TTYDEF_IFLAG; - tp->t_oflag = TTYDEF_OFLAG; - tp->t_cflag = ZSDEF_CFLAG; - tp->t_lflag = TTYDEF_LFLAG; - (void) zsparam(tp, &tp->t_termios); - } else { - /* Can not run kgdb on the console? */ -#ifdef KGDB - zs_checkkgdb(unit, cs, tp); -#endif - } -#if 0 - /* XXX - Drop carrier here? -gwr */ - zs_modem(cs, cs->cs_softcar ? 1 : 0); -#endif - - if (unit == ZS_KBD) { -#ifdef DEBUG - printf("We got a KBD!, unit %d\n",unit); -#endif - /* - * Keyboard: tell /dev/kbd driver how to talk to us. - */ - tp->t_ispeed = tp->t_ospeed = cs->cs_speed; - tp->t_cflag = CS8; - /* zsparam called by zsiopen */ - /*kbd_serial(tp, zsiopen, zsiclose); HACK */ - cs->cs_conk = 1; /* do L1-A processing */ - } - unit++; - cs++; - - cs->cs_unit = unit; - cs->cs_zc = ZS_CHAN(ZS_CHAN_B); -#ifdef DEBUG - printf("zs channel b at %x\n",cs->cs_zc); -#endif - cs->cs_speed = zs_getspeed(cs->cs_zc); -#ifdef DEBUG - mon_printf("zs%db speed %d\n", zs, cs->cs_speed); -#endif - cs->cs_softcar = softcar & 2; - cs->cs_rr0_mask = 0; /* CTS is broken on the mac */ - cs->cs_SFC = 0; - cs->cs_holdSFC = 0; - cs->cs_tiu = 0; - - tp = zs_tty[unit]; - cs->cs_ttyp = tp; - tp->t_dev = makedev(ZSMAJOR, unit); - tp->t_oproc = zsstart; - tp->t_param = zsparam; - if ((cs->cs_zc == zs_conschan) && (mac68k_machine.serial_console & 0x01)) { -#ifdef DEBUG - printf("We got a console!, unit %d\n",unit); -#endif - /* This unit is the console. */ - cs->cs_consio = 1; - cs->cs_brkabort = 0; - cs->cs_softcar = 1; - tp->t_ispeed = tp->t_ospeed = cs->cs_speed; - tp->t_iflag = TTYDEF_IFLAG; - tp->t_oflag = TTYDEF_OFLAG; - tp->t_cflag = ZSDEF_CFLAG; - tp->t_lflag = TTYDEF_LFLAG; - (void) zsparam(tp, &tp->t_termios); - } else { - /* Can not run kgdb on the console? */ -#ifdef KGDB - zs_checkkgdb(unit, cs, tp); -#endif - } -#if 0 - /* XXX - Drop carrier here? -gwr */ - zs_modem(cs, cs->cs_softcar ? 1 : 0); -#endif - - if (unit == ZS_MOUSE) { -#ifdef DEBUG - printf("We got a mouse!, unit %d\n",unit); -#endif - /* - * Mouse: tell /dev/mouse driver how to talk to us. - */ - tp->t_ispeed = tp->t_ospeed = cs->cs_speed; - tp->t_cflag = CS8; - /* zsparam called by zsiopen */ - /* ms_serial(tp, zsiopen, zsiclose); HACK */ - } - if (mac68k_machine.serial_boot_echo) { - if (self->dv_unit == 0) - printf(" (serial boot echo is on)"); - } - printf("\n"); -} - -/* - * XXX - Temporary hack... - */ -struct tty * -zstty(dev) - dev_t dev; -{ - int unit = minor(dev); - -#ifdef DEBUG - printf("Fetching tty unit %i\n", unit); -#endif - - return (zs_tty[unit]); -} - -/* - * Put a channel in a known state. Interrupts may be left disabled - * or enabled, as desired. (Used only by kgdb) - */ -static void -zs_reset(zc, inten, speed) - volatile struct zschan *zc; - int inten, speed; -{ - int tconst; - u_char reg[16]; - - bcopy(zs_init_reg, reg, 16); - if (inten) { - reg[1] |= ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE; - reg[9] |= ZSWR9_MASTER_IE; - } - - tconst = BPS_TO_TCONST(PCLK , speed); - reg[12] = tconst; - reg[13] = tconst >> 8; - zs_loadchannelregs(zc, reg); -} - -/* - * Console support - */ - -/* - * Used by the kd driver to find out if it can work. - */ -int -zscnprobe_kbd() -{ - if (zsaddr[1] == NULL) { - mon_printf("zscnprobe_kbd: zs1 not yet mapped\n"); - return CN_DEAD; - } - return CN_INTERNAL; -} - -/* - * This is the console probe routine for ttya and ttyb. - */ -static int -zscnprobe(struct consdev *cn, int unit) -{ - int maj; - - if (zsaddr[0] == NULL) { - mon_printf("zscnprobe: zs0 not mapped\n"); - cn->cn_pri = CN_DEAD; - return 0; - } - /* XXX - Also try to make sure it exists? */ - - /* locate the major number */ - for (maj = 0; maj < nchrdev; maj++) - if (cdevsw[maj].d_open == (void*)zsopen) - break; - - cn->cn_dev = makedev(maj, unit); - - /* Use EEPROM console setting to decide "remote" console. */ - /* Note: EE_CONS_TTYA + 1 == EE_CONS_TTYB */ -/* if (ee_console == (EE_CONS_TTYA + unit)) { - cn->cn_pri = CN_REMOTE; - } else { HACK */ - cn->cn_pri = CN_NORMAL; -/* } HACK */ - return (0); -} - -/* This is the constab entry for TTYA. */ -int -zscnprobe_a(struct consdev *cn) -{ - return (zscnprobe(cn, 0)); -} - -/* This is the constab entry for TTYB. */ -int -zscnprobe_b(struct consdev *cn) -{ - return (zscnprobe(cn, 1)); -} - -/* Called by kdcninit() or below. */ -void -zs_set_conschan(unit, ab) - int unit, ab; -{ - volatile struct zsdevice *addr; - -#ifndef mac68k - addr = zsaddr[unit]; - zs_conschan = ((ab == 0) ? (ZS_CHAN(ZS_CHAN_A)):(ZS_CHAN(ZS_CHAN_B))); -#else - zs_conschan = ((ab == 0) ? (ZS_CONS_A) : (ZS_CONS_B)); - /* use tokens for now */ -#endif - -} - -/* Attach as console. Also set zs_conschan */ -int -zscninit(struct consdev *cn) -{ - int ab = minor(cn->cn_dev) & 1; - zs_set_conschan(0, ab); - mon_printf("console on zs0 (tty%c)\n", 'a' + ab); -} - - -/* - * Polled console input putchar. - */ -int -sercngetc(dev) - dev_t dev; -{ - register volatile struct zschan *zc = zs_conschan; - register int s, c, rr0; - - if (zc == NULL) - return (0); - if ((zc == ZS_CONS_A) || (zc == ZS_CONS_B)) { - volatile struct zsdevice *addr; - addr = (volatile struct zsdevice *)sccA; - zc = ((zc == ZS_CONS_A) ? (ZS_CHAN(ZS_CHAN_A)):(ZS_CHAN(ZS_CHAN_B))); - /* if zs_conschan points at one of the magic values, re-direct it to the real chip */ - } - - s = splhigh(); - - /* Wait for a character to arrive. */ - do { - rr0 = zc->zc_csr; - ZS_DELAY(); - } while ((rr0 & ZSRR0_RX_READY) == 0); - - c = zc->zc_data; - ZS_DELAY(); - - splx(s); - - /* - * This is used by the kd driver to read scan codes, - * so don't translate '\r' ==> '\n' here... - */ - return (c); -} - -/* - * Polled console output putchar. - */ -int -sercnputc(dev, c) - dev_t dev; - int c; -{ - register volatile struct zschan *zc = zs_conschan; - register int s, rr0; - register long wait = 0; - - if (zc == NULL) { - s = splhigh(); - /* mon_putchar(c); */ - splx(s); - return (0); - } - s = splhigh(); - if ((zc == ZS_CONS_A) || (zc == ZS_CONS_B)) { - volatile struct zsdevice *addr; - addr = (volatile struct zsdevice *)sccA; - zc = ((zc == ZS_CONS_A) ? (ZS_CHAN(ZS_CHAN_A)):(ZS_CHAN(ZS_CHAN_B))); - /* if zs_conschan points at one of the magic values, re-direct it to the real chip */ - } - - /* Wait for transmitter to become ready. */ - do { - rr0 = zc->zc_csr; - ZS_DELAY(); - } while (((rr0 & ZSRR0_TX_READY) == 0) && (wait ++ < 100000)); - - zc->zc_data = c; - ZS_DELAY(); - splx(s); -} - -#ifdef KGDB -/* - * The kgdb zs port, if any, was altered at boot time (see zs_kgdb_init). - * Pick up the current speed and character size and restore the original - * speed. - */ -static void -zs_checkkgdb(int unit, struct zs_chanstate *cs, struct tty *tp) -{ - - if (kgdb_dev == makedev(ZSMAJOR, unit)) { - tp->t_ispeed = tp->t_ospeed = kgdb_rate; - tp->t_cflag = CS8; - cs->cs_kgdb = 1; - cs->cs_speed = zs_kgdb_savedspeed; - (void) zsparam(tp, &tp->t_termios); - } -} -#endif - -/* - * Compute the current baud rate given a ZSCC channel. - */ -static int -zs_getspeed(zc) - register volatile struct zschan *zc; -{ - register int tconst; - - tconst = ZS_READ(zc, 12); - tconst |= ZS_READ(zc, 13) << 8; -#ifdef DEBUG - printf("Time const is %x \n",tconst); -#endif - return (TCONST_TO_BPS(PCLK , tconst)); -} - - -/* - * Do an internal open. - */ -static void -zsiopen(tp) - struct tty *tp; -{ - - (void) zsparam(tp, &tp->t_termios); - ttsetwater(tp); - tp->t_state = TS_ISOPEN | TS_CARR_ON; -} - -/* - * Do an internal close. Eventually we should shut off the chip when both - * ports on it are closed. - */ -static void -zsiclose(tp) - struct tty *tp; -{ -#ifdef DEBUG - printf("zs internal close.\n"); -#endif - - ttylclose(tp, 0); /* ??? */ - ttyclose(tp); /* ??? */ - tp->t_state = 0; -} - - -/* - * Open a zs serial port. This interface may not be used to open - * the keyboard and mouse ports. (XXX) - */ -int -zsopen(dev, flags, mode, p) - dev_t dev; - int flags; - int mode; - struct proc *p; -{ - register struct tty *tp; - register struct zs_chanstate *cs; - struct zsinfo *zi; - int unit = minor(dev), zs = unit >> 1, error, s; - -#ifdef DEBUG - mon_printf("zs_open to channel at %x\n",cs->cs_zc); -#endif - if (zs >= zscd.cd_ndevs || (zi = zscd.cd_devs[zs]) == NULL || - unit == ZS_KBD || unit == ZS_MOUSE) - return (ENXIO); - cs = &zi->zi_cs[unit & 1]; - tp = cs->cs_ttyp; - s = spltty(); - if ((tp->t_state & TS_ISOPEN) == 0) { - ttychars(tp); - if (tp->t_ispeed == 0) { - tp->t_iflag = TTYDEF_IFLAG; - tp->t_oflag = TTYDEF_OFLAG; - tp->t_cflag = TTYDEF_CFLAG; - tp->t_lflag = TTYDEF_LFLAG; - tp->t_ispeed = tp->t_ospeed = cs->cs_speed; - } - (void) zsparam(tp, &tp->t_termios); - ttsetwater(tp); - } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { - splx(s); - return (EBUSY); - } - error = 0; -#ifdef DEBUG - mon_printf("wait for carrier...\n"); -#endif - for (;;) { - register int rr0; - - /* loop, turning on the device, until carrier present */ - zs_modem(cs, 1); - /* May never get status intr if carrier already on. -gwr */ - rr0 = cs->cs_zc->zc_csr; - ZS_DELAY(); - if (rr0 & ZSRR0_DCD) - tp->t_state |= TS_CARR_ON; - if (cs->cs_softcar) - tp->t_state |= TS_CARR_ON; - if (flags & O_NONBLOCK || tp->t_cflag & CLOCAL || - tp->t_state & TS_CARR_ON) - break; - tp->t_state |= TS_WOPEN; - if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, - ttopen, 0)) { - if (!(tp->t_state & TS_ISOPEN)) { - zs_modem(cs, 0); - tp->t_state &= ~TS_WOPEN; - ttwakeup(tp); - } - splx(s); - return error; - } - } -#ifdef DEBUG - mon_printf("...carrier %s\n", - (tp->t_state & TS_CARR_ON) ? "on" : "off"); -#endif - splx(s); - if (error == 0) - error = linesw[tp->t_line].l_open(dev, tp); - if (error) - zs_modem(cs, 0); - return (error); -} - -/* - * Close a zs serial port. - */ -int -zsclose(dev, flags, mode, p) - dev_t dev; - int flags; - int mode; - struct proc *p; -{ - register struct zs_chanstate *cs; - register struct tty *tp; - struct zsinfo *zi; - int unit = minor(dev), s; - -#ifdef DEBUG - mon_printf("zs_close\n"); -#endif - zi = zscd.cd_devs[unit >> 1]; - cs = &zi->zi_cs[unit & 1]; - tp = cs->cs_ttyp; - linesw[tp->t_line].l_close(tp, flags); -/* printf("My zsclose tty is %x, ",tp); - printf("Stored values are: iflag %x, oflag %x, cflag %x, ospeed %x\n",tp->t_iflag, tp->t_oflag,\ - tp->t_cflag, tp->t_ospeed); */ - if (tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN || - (tp->t_state & TS_ISOPEN) == 0) { - zs_modem(cs, 0); - /* hold low for 1 second */ - (void) tsleep((caddr_t)cs, TTIPRI, ttclos, hz); - } - if (cs->cs_creg[5] & ZSWR5_BREAK) - { - s = splzs(); - cs->cs_preg[5] &= ~ZSWR5_BREAK; - cs->cs_creg[5] &= ~ZSWR5_BREAK; - ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); - splx(s); - } - ttyclose(tp); -#ifdef KGDB - /* Reset the speed if we're doing kgdb on this port */ - if (cs->cs_kgdb) { - tp->t_ispeed = tp->t_ospeed = kgdb_rate; - (void) zsparam(tp, &tp->t_termios); - } -#endif - return (0); -} - -/* - * Read/write zs serial port. - */ -int -zsread(dev, uio, flags) - dev_t dev; - struct uio *uio; - int flags; -{ - register struct tty *tp = zs_tty[minor(dev)]; - - return (linesw[tp->t_line].l_read(tp, uio, flags)); -} - -int -zswrite(dev, uio, flags) - dev_t dev; - struct uio *uio; - int flags; -{ - register struct tty *tp = zs_tty[minor(dev)]; -#ifdef DEBUG - printf("Writing\n"); -#endif - - return (linesw[tp->t_line].l_write(tp, uio, flags)); -} - -/* - * ZS hardware interrupt. Scan all ZS channels. NB: we know here that - * channels are kept in (A,B) pairs. - * - * Do just a little, then get out; set a software interrupt if more - * work is needed. - * - * We deliberately ignore the vectoring Zilog gives us, and match up - * only the number of `reset interrupt under service' operations, not - * the order. - */ -/* ARGSUSED */ -int -zshard(intrarg) - int intrarg; -{ - register struct zs_chanstate *a; -#define b (a + 1) - register volatile struct zschan *zc; - register int rr3, intflags = 0, i; - register long v; - static long zsrint(struct zs_chanstate *, volatile struct zschan *); - static long zsxint(struct zs_chanstate *, volatile struct zschan *); - static long zssint(struct zs_chanstate *, volatile struct zschan *); - - if (!sccA) return; - if (zslist == 0) return; - - for (a = zslist; a != NULL; a = b->cs_next) { - rr3 = ZS_READ(a->cs_zc, 3); - - /* XXX - This should loop to empty the on-chip fifo. */ - if (rr3 & (ZSRR3_IP_A_RX|ZSRR3_IP_A_TX|ZSRR3_IP_A_STAT)) { - intflags |= 2; - zc = a->cs_zc; -#ifdef DEBUG - printf("z %x ",ZS_READ(a->cs_zc,0)); -#endif - i = a->cs_rbput; - if (rr3 & ZSRR3_IP_A_RX && (v = zsrint(a, zc)) != 0) { - a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; - intflags |= 1; - while (ZS_READ(a->cs_zc, 0) & ZSRR0_RX_READY) - if ((v = zsrint(a, zc)) != 0) - a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; - } - if (rr3 & ZSRR3_IP_A_TX && (v = zsxint(a, zc)) != 0) { - a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; - intflags |= 1; - } - if (rr3 & ZSRR3_IP_A_STAT && (v = zssint(a, zc)) != 0) { - a->cs_rbuf[i++ & ZLRB_RING_MASK] = v; - intflags |= 1; - } - a->cs_rbput = i; - } - - /* XXX - This should loop to empty the on-chip fifo. */ - if (rr3 & (ZSRR3_IP_B_RX|ZSRR3_IP_B_TX|ZSRR3_IP_B_STAT)) { - intflags |= 2; - zc = b->cs_zc; -#ifdef DEBUG - printf("zb %x ",ZS_READ(b->cs_zc,0)); -#endif - i = b->cs_rbput; - if (rr3 & ZSRR3_IP_B_RX && (v = zsrint(b, zc)) != 0) { - b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; - intflags |= 1; - while (ZS_READ(b->cs_zc, 0) & ZSRR0_RX_READY) - if ((v = zsrint(b, zc)) != 0) - b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; - } - if (rr3 & ZSRR3_IP_B_TX && (v = zsxint(b, zc)) != 0) { - b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; - intflags |= 1; - } - if (rr3 & ZSRR3_IP_B_STAT && (v = zssint(b, zc)) != 0) { - b->cs_rbuf[i++ & ZLRB_RING_MASK] = v; - intflags |= 1; - } - b->cs_rbput = i; - } - } -#undef b - if (intflags & 1) { - if (zssoftpending == 0) { - /* We are at splzs here, so no need to lock. */ - zssoftpending = ZSSOFT_PRI; - isr_soft_request(ZSSOFT_PRI); - } - } - return (intflags & 2); -} - -static long -zsrint(cs, zc) - register struct zs_chanstate *cs; - register volatile struct zschan *zc; -{ - register long c; - - c = zc->zc_data; - ZS_DELAY(); -#ifdef DEBUG - printf("r%x ",c); -#endif - - if (cs->cs_conk) { - register struct conk_state *conk = &zsconk_state; - -#define KBD_RESET 0 -#define KBD_L1 4 -#define KBD_UP 2 -#define KBD_A 8 - /* - * Check here for console abort function, so that we - * can abort even when interrupts are locking up the - * machine. - */ - if (c == KBD_RESET) { - conk->conk_id = 1; /* ignore next byte */ - conk->conk_l1 = 0; - } else if (conk->conk_id) - conk->conk_id = 0; /* stop ignoring bytes */ - else if (c == KBD_L1) - conk->conk_l1 = 1; /* L1 went down */ - else if (c == (KBD_L1|KBD_UP)) - conk->conk_l1 = 0; /* L1 went up */ - else if (c == KBD_A && conk->conk_l1) { - zsabort(); - /* Debugger done. Send L1-up in case X is running. */ - conk->conk_l1 = 0; - c = (KBD_L1|KBD_UP); - } - } -#ifdef KGDB - /*if (c == FRAME_START && cs->cs_kgdb && - (cs->cs_ttyp->t_state & TS_ISOPEN) == 0) { - zskgdb(cs->cs_unit); - c = 0; - goto clearit; - } */ -#endif - /* compose receive character and status */ - c <<= 8; - c |= ZS_READ(zc, 1); - c = ZRING_MAKE(ZRING_RINT, c); - -clearit: - /* clear receive error & interrupt condition */ - zc->zc_csr = ZSWR0_RESET_ERRORS; - ZS_DELAY(); - zc->zc_csr = ZSWR0_CLR_INTR; - ZS_DELAY(); - return (c); -} - -static long -zsxint(cs, zc) - register struct zs_chanstate *cs; - register volatile struct zschan *zc; -{ - register int i = cs->cs_tbc; - - if (i == 0) { - zc->zc_csr = ZSWR0_RESET_TXINT; - ZS_DELAY(); - zc->zc_csr = ZSWR0_CLR_INTR; - ZS_DELAY(); - if (cs->cs_tiu !=0) { - /* We only want to post a transmitter's empty if we've - actually put something in it. We also get here after zscnputc - outputs a byte, but we shouldn't post to the ring */ - cs->cs_tiu = 0; -#ifdef DEBUG - printf("Td "); -#endif - return (ZRING_MAKE(ZRING_XINT, 0)); - } else {return (0);} - } -#ifdef DEBUGTX - printf(" t%x ",(u_char)*cs->cs_tba); -#endif - if (cs->cs_holdSFC) { - cs->cs_tiu = 0; /* transmitter is no longer in use */ - zc->zc_csr = ZSWR0_RESET_TXINT; - ZS_DELAY(); - zc->zc_csr = ZSWR0_CLR_INTR; - ZS_DELAY(); - return (0); - } - cs->cs_tbc = i - 1; - zc->zc_data = *cs->cs_tba++; - ZS_DELAY(); - zc->zc_csr = ZSWR0_CLR_INTR; - ZS_DELAY(); - return (0); -} - -static long -zssint(cs, zc) - register struct zs_chanstate *cs; - register volatile struct zschan *zc; -{ - register int rr0; - - rr0 = zc->zc_csr; - ZS_DELAY(); - rr0 = zc->zc_csr; - ZS_DELAY(); - zc->zc_csr = ZSWR0_RESET_STATUS; - ZS_DELAY(); - zc->zc_csr = ZSWR0_CLR_INTR; - ZS_DELAY(); - /* - * The chip's hardware flow control is, as noted in zsreg.h, - * busted---if the DCD line goes low the chip shuts off the - * receiver (!). If we want hardware CTS flow control but do - * not have it, and carrier is now on, turn HFC on; if we have - * HFC now but carrier has gone low, turn it off. - */ - /* if (rr0 & ZSRR0_DCD) { - if (cs->cs_ttyp->t_cflag & CCTS_OFLOW && - (cs->cs_creg[3] & ZSWR3_HFC) == 0) { - cs->cs_creg[3] |= ZSWR3_HFC; - ZS_WRITE(zc, 3, cs->cs_creg[3]); - } - } else { - if (cs->cs_creg[3] & ZSWR3_HFC) { - cs->cs_creg[3] &= ~ZSWR3_HFC; - ZS_WRITE(zc, 3, cs->cs_creg[3]); - } - } */ - if (cs->cs_SFC) { - register u_char nhold = \ - (((rr0 ^ cs->cs_rr0_mask) & ZS_HFC)==ZS_HFC) ? 1 : 0; - if (nhold != cs->cs_holdSFC) { /* our holding state has changed */ - cs->cs_holdSFC = nhold; - if ((nhold == 0) && (cs->cs_tbc != 0)) { - /* a character is waiting; send it */ - zs_restart(cs, zc); - } -#ifdef DEBUG - printf(" ntd CTS change, hl %d ",nhold); -#endif - } - } - if ((rr0 & ZSRR0_BREAK) && cs->cs_brkabort) { - /* Wait for end of break to avoid PROM abort. */ - do { - rr0 = zc->zc_csr; - ZS_DELAY(); - } while (rr0 & ZSRR0_BREAK); - zsabort(); - return (0); - } -#ifdef DEBUG - printf(" s%x ",rr0); -#endif - return (ZRING_MAKE(ZRING_SINT, rr0)); -} - -static void -zs_restart(cs, zc) - register struct zs_chanstate *cs; - register volatile struct zschan *zc; -{ - cs->cs_tbc -= 1; - zc->zc_data = *cs->cs_tba++; - ZS_DELAY(); - cs->cs_tiu = 1; -#ifdef DEBUG - printf(" restart tx "); -#endif -} - -zsabort() -{ -#ifdef DDB - Debugger(); -#endif -} - -#ifdef KGDB -/* - * KGDB framing character received: enter kernel debugger. This probably - * should time out after a few seconds to avoid hanging on spurious input. - */ -zskgdb(unit) - int unit; -{ - - printf("zs%d%c: kgdb interrupt\n", unit >> 1, (unit & 1) + 'a'); - kgdb_connect(1); -} -#endif - -/* - * Print out a ring or fifo overrun error message. - */ -static void -zsoverrun(unit, ptime, what) - int unit; - long *ptime; - char *what; -{ - - if (*ptime != time.tv_sec) { - *ptime = time.tv_sec; - log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1, - (unit & 1) + 'a', what); - } -} - -/* - * ZS software interrupt. Scan all channels for deferred interrupts. - */ -int -zssoft(arg) - int arg; -{ - register struct zs_chanstate *cs; - register volatile struct zschan *zc; - register struct linesw *line; - register struct tty *tp; - register int get, n, c, cc, unit, s; - - /* This is not the only ISR on this IPL. */ - if (zssoftpending == 0) - return (0); -#ifdef DEBUG - printf("zs"); -#endif - - /* - * The soft intr. bit will be set by zshard only if - * the variable zssoftpending is zero. The order of - * these next two statements prevents our clearing - * the soft intr bit just after zshard has set it. - */ - isr_soft_clear(ZSSOFT_PRI); - zssoftpending = 0; /* Now zshard may set it again. */ - - for (cs = zslist; cs != NULL; cs = cs->cs_next) { - get = cs->cs_rbget; -again: - n = cs->cs_rbput; /* atomic */ - if (get == n) /* nothing more on this line */ - continue; - unit = cs->cs_unit; /* set up to handle interrupts */ - zc = cs->cs_zc; - tp = cs->cs_ttyp; - if (tp != NULL) line = &linesw[tp->t_line]; - /* - * Compute the number of interrupts in the receive ring. - * If the count is overlarge, we lost some events, and - * must advance to the first valid one. It may get - * overwritten if more data are arriving, but this is - * too expensive to check and gains nothing (we already - * lost out; all we can do at this point is trade one - * kind of loss for another). - */ - n -= get; - if (n > ZLRB_RING_SIZE) { - zsoverrun(unit, &cs->cs_rotime, "ring"); - get += n - ZLRB_RING_SIZE; - n = ZLRB_RING_SIZE; - } - while (--n >= 0) { - /* race to keep ahead of incoming interrupts */ - c = cs->cs_rbuf[get++ & ZLRB_RING_MASK]; - switch (ZRING_TYPE(c)) { - - case ZRING_RINT: - c = ZRING_VALUE(c); - if (c & ZSRR1_DO) - zsoverrun(unit, &cs->cs_fotime, "fifo"); - cc = c >> 8; - if (c & ZSRR1_FE) - cc |= TTY_FE; - if (c & ZSRR1_PE) - cc |= TTY_PE; - /* - * this should be done through - * bstreams XXX gag choke - */ - if (tp != NULL) { - line->l_rint(cc, tp); - } else {printf("tp == NULL!");} - break; - - case ZRING_XINT: - /* - * Transmit done: change registers and resume, - * or clear BUSY. - */ - if (cs->cs_heldchange) { - s = splzs(); - c = zc->zc_csr; - ZS_DELAY(); - if ((c & ZSRR0_DCD) == 0) - cs->cs_preg[3] &= ~ZSWR3_HFC; - bcopy((caddr_t)cs->cs_preg, - (caddr_t)cs->cs_creg, 16); - zs_loadchannelregs(zc, cs->cs_creg); - splx(s); - cs->cs_heldchange = 0; - if (cs->cs_heldtbc && - (tp->t_state & TS_TTSTOP) == 0) { - cs->cs_tbc = cs->cs_heldtbc - 1; - zc->zc_data = *cs->cs_tba++; - ZS_DELAY(); - goto again; - } - } - if (tp != NULL) { - tp->t_state &= ~TS_BUSY; - if (tp->t_state & TS_FLUSH) - tp->t_state &= ~TS_FLUSH; - else - ndflush(&tp->t_outq, cs->cs_tba - - (caddr_t) tp->t_outq.c_cf); - line->l_start(tp); - } else {printf("Trans. tp == NULL!");} - break; - - case ZRING_SINT: - /* - * Status line change. HFC bit is run in - * hardware interrupt, to avoid locking - * at splzs here. - */ - c = ZRING_VALUE(c); - if ((c ^ cs->cs_rr0) & ZSRR0_DCD) { - cc = (c & ZSRR0_DCD) != 0; - if (tp != NULL) if (line->l_modem(tp, cc) == 0) - zs_modem(cs, cc); - } - cs->cs_rr0 = c; - break; - - default: - log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n", - unit >> 1, (unit & 1) + 'a', c); - break; - } - } - cs->cs_rbget = get; - goto again; - } - return (1); -} - -int -zsioctl(dev, cmd, data, flag, p) - dev_t dev; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; -{ - int unit = minor(dev); - struct zsinfo *zi = zscd.cd_devs[unit >> 1]; - register struct zs_chanstate *cs = &zi->zi_cs[unit & 1]; - register struct tty *tp = cs->cs_ttyp; - register int error, s; - -#ifdef DEBUG - printf("My tty in zsioctl is %x, my command is %x, and my zc is %x\n",tp,cmd,cs->cs_zc); -#endif - - error = linesw[tp->t_line].l_ioctl(tp, cmd, data, flag, p); - if (error >= 0) - return (error); - error = ttioctl(tp, cmd, data, flag, p); - if (error >= 0) - return (error); - - switch (cmd) { - - case TIOCSBRK: - s = splzs(); - cs->cs_preg[5] |= ZSWR5_BREAK; - cs->cs_creg[5] |= ZSWR5_BREAK; - ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); - splx(s); - break; - - case TIOCCBRK: - s = splzs(); - cs->cs_preg[5] &= ~ZSWR5_BREAK; - cs->cs_creg[5] &= ~ZSWR5_BREAK; - ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); - splx(s); - break; - - case TIOCGFLAGS: { - int bits = 0; - - if (cs->cs_softcar) - bits |= TIOCFLAG_SOFTCAR; - if (cs->cs_creg[15] & ZSWR15_DCD_IE) - bits |= TIOCFLAG_CLOCAL; - if (cs->cs_creg[3] & ZSWR3_HFC) - bits |= TIOCFLAG_CRTSCTS; - *(int *)data = bits; - break; - } - - case TIOCSFLAGS: { - int userbits, driverbits = 0; - - error = suser(p->p_ucred, &p->p_acflag); - if (error != 0) - return (EPERM); - - userbits = *(int *)data; - - /* - * can have `local' or `softcar', and `rtscts' or `mdmbuf' - * defaulting to software flow control. - */ - if (userbits & TIOCFLAG_SOFTCAR && userbits & TIOCFLAG_CLOCAL) - return(EINVAL); - if (userbits & TIOCFLAG_MDMBUF) /* don't support this (yet?) */ - return(ENXIO); - - s = splzs(); - if ((userbits & TIOCFLAG_SOFTCAR) || - (cs->cs_zc == zs_conschan)) - { - cs->cs_softcar = 1; /* turn on softcar */ - cs->cs_preg[15] &= ~ZSWR15_DCD_IE; /* turn off dcd */ - cs->cs_creg[15] &= ~ZSWR15_DCD_IE; - ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]); - } else if (userbits & TIOCFLAG_CLOCAL) { - cs->cs_softcar = 0; /* turn off softcar */ - cs->cs_preg[15] |= ZSWR15_DCD_IE; /* turn on dcd */ - cs->cs_creg[15] |= ZSWR15_DCD_IE; - ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]); - tp->t_termios.c_cflag |= CLOCAL; - } - if (userbits & TIOCFLAG_CRTSCTS) { - cs->cs_preg[15] |= ZSWR15_CTS_IE; - cs->cs_creg[15] |= ZSWR15_CTS_IE; - ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]); - cs->cs_preg[3] |= ZSWR3_HFC; - cs->cs_creg[3] |= ZSWR3_HFC; - ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]); - tp->t_termios.c_cflag |= CRTSCTS; - } else { - /* no mdmbuf, so we must want software flow control */ - cs->cs_preg[15] &= ~ZSWR15_CTS_IE; - cs->cs_creg[15] &= ~ZSWR15_CTS_IE; - ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]); - cs->cs_preg[3] &= ~ZSWR3_HFC; - cs->cs_creg[3] &= ~ZSWR3_HFC; - ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]); - tp->t_termios.c_cflag &= ~CRTSCTS; - } - splx(s); - break; - } - - case TIOCSDTR: - zs_modem(cs, 1); - break; - case TIOCCDTR: - zs_modem(cs, 0); - break; - - case TIOCMSET: - case TIOCMBIS: - case TIOCMBIC: - case TIOCMGET: - default: - return (ENOTTY); - } - return (0); -} - -/* - * Start or restart transmission. - */ -static void -zsstart(tp) - register struct tty *tp; -{ - register struct zs_chanstate *cs; - register int s, nch; - int unit = minor(tp->t_dev); - struct zsinfo *zi = zscd.cd_devs[unit >> 1]; - - cs = &zi->zi_cs[unit & 1]; - s = spltty(); - - /* - * If currently active or delaying, no need to do anything. - */ - if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) - goto out; - - /* - * If there are sleepers, and output has drained below low - * water mark, awaken. - */ - if (tp->t_outq.c_cc <= tp->t_lowat) { - if (tp->t_state & TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup((caddr_t)&tp->t_outq); - } - selwakeup(&tp->t_wsel); - } -#ifdef DEBUG - printf("stat %x ",ZS_READ(cs->cs_zc,0)); -#endif - - nch = ndqb(&tp->t_outq, 0); /* XXX */ - if (nch) { - register char *p = tp->t_outq.c_cf; - - /* mark busy, enable tx done interrupts, & send first byte */ - tp->t_state |= TS_BUSY; -#ifdef DEBUG - printf(" out w/ %x ",(u_char)*p); -#endif - (void) splzs(); - cs->cs_preg[1] |= ZSWR1_TIE; - cs->cs_creg[1] |= ZSWR1_TIE; - ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]); - cs->cs_tba = p; - cs->cs_tbc = nch; - if ((cs->cs_SFC == 0) || (cs->cs_holdSFC == 0)) - zs_restart(cs, cs->cs_zc); - } else { - /* - * Nothing to send, turn off transmit done interrupts. - * This is useful if something is doing polled output. - */ -#ifdef DEBUG - printf(" off "); -#endif - (void) splzs(); - cs->cs_preg[1] &= ~ZSWR1_TIE; - cs->cs_creg[1] &= ~ZSWR1_TIE; - ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]); - } -out: - splx(s); -} - -/* - * Stop output, e.g., for ^S or output flush. - */ -void -zsstop(tp, flag) - register struct tty *tp; - int flag; -{ - register struct zs_chanstate *cs; - register int s, unit = minor(tp->t_dev); - struct zsinfo *zi = zscd.cd_devs[unit >> 1]; - - cs = &zi->zi_cs[unit & 1]; - s = splzs(); - if (tp->t_state & TS_BUSY) { - /* - * Device is transmitting; must stop it. - */ - cs->cs_tbc = 0; - if ((tp->t_state & TS_TTSTOP) == 0) - tp->t_state |= TS_FLUSH; - } - splx(s); -} - -/* - * Set ZS tty parameters from termios. - */ -static int -zsparam(tp, t) - register struct tty *tp; - register struct termios *t; -{ - int unit = minor(tp->t_dev); - struct zsinfo *zi = zscd.cd_devs[unit >> 1]; - register struct zs_chanstate *cs = &zi->zi_cs[unit & 1]; - register int tmp, tmp5, cflag, s, tmpx; - - /* - * Because PCLK is only run at 4.9 MHz, the fastest we - * can go is 51200 baud (this corresponds to TC=1). - * This is somewhat unfortunate as there is no real - * reason we should not be able to handle higher rates. - */ - tmp = t->c_ospeed; - if (tmp < 0 || (t->c_ispeed && t->c_ispeed != tmp)) - return (EINVAL); - if (tmp == 0) { - /* stty 0 => drop DTR and RTS */ - zs_modem(cs, 0); - return (0); - } - tmp = BPS_TO_TCONST(PCLK , tmp); - if (tmp < 0) - return (EINVAL); - - cflag = t->c_cflag; - tp->t_ispeed = tp->t_ospeed = TCONST_TO_BPS(PCLK , tmp); - tp->t_cflag = cflag; - - /* - * Block interrupts so that state will not - * be altered until we are done setting it up. - */ - s = splzs(); - bcopy(zs_init_reg, cs->cs_preg, 16); - cs->cs_preg[12] = tmp & 255; - cs->cs_preg[13] = tmp >> 8; - cs->cs_preg[1] |= ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE; - cs->cs_preg[9] |= ZSWR9_MASTER_IE; - switch (cflag & CSIZE) { - case CS5: - tmp = ZSWR3_RX_5; - tmp5 = ZSWR5_TX_5; - break; - case CS6: - tmp = ZSWR3_RX_6; - tmp5 = ZSWR5_TX_6; - break; - case CS7: - tmp = ZSWR3_RX_7; - tmp5 = ZSWR5_TX_7; - break; - case CS8: - default: - tmp = ZSWR3_RX_8; - tmp5 = ZSWR5_TX_8; - break; - } - - /* - * Output hardware flow control on the chip is horrendous: if - * carrier detect drops, the receiver is disabled. Hence we - * can only do this when the carrier is on. - */ - tmp |= ZSWR3_RX_ENABLE; - if (cflag & CCTS_OFLOW) { - if (1) { - cs->cs_SFC = 1; - cs->cs_holdSFC = (((cs->cs_zc->zc_csr ^ cs->cs_rr0_mask) & ZS_HFC)==ZS_HFC) ? 1 : 0; - } else { - if (cs->cs_zc->zc_csr & ZSRR0_DCD) - tmp |= ZSWR3_HFC; - ZS_DELAY(); - } - } else { - /* (cs_SFC !=0) && (cs_holdSFC !=0) */ - tmpx = (cs->cs_SFC ? cs->cs_holdSFC : 0); - cs->cs_SFC = 0; - cs->cs_holdSFC = 0; - if (tmpx) - /* we were waiting because of SFC, but now we don't */ - zs_restart(cs, cs->cs_zc); - } - - cs->cs_preg[3] = tmp; - cs->cs_preg[5] = tmp5 | ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;; - - tmp = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB); - if ((cflag & PARODD) == 0) - tmp |= ZSWR4_EVENP; - if (cflag & PARENB) - tmp |= ZSWR4_PARENB; - cs->cs_preg[4] = tmp; - - /* - * If nothing is being transmitted, set up new current values, - * else mark them as pending. - */ - if (cs->cs_heldchange == 0) { - if (cs->cs_ttyp->t_state & TS_BUSY) { - cs->cs_heldtbc = cs->cs_tbc; - cs->cs_tbc = 0; - cs->cs_heldchange = 1; - } else { - bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16); - zs_loadchannelregs(cs->cs_zc, cs->cs_creg); - } - } - splx(s); -#ifdef DEBUG -printf("My zsparam tty is %x, my termios is %x, iflag %x, oflag %x, cflag %x\n", - tp,t, t->c_iflag, t->c_oflag, t->c_cflag); -printf("Stored values are: iflag %x, oflag %x, cflag %x, ospeed %x\n", - tp->t_iflag, tp->t_oflag, tp->t_cflag, tp->t_ospeed); -#endif - return (0); -} - -/* - * Raise or lower modem control (DTR/RTS) signals. If a character is - * in transmission, the change is deferred. - */ -static void -zs_modem(cs, onoff) - struct zs_chanstate *cs; - int onoff; -{ - int s, bis, and; - - if (onoff) { - bis = ZSWR5_DTR | ZSWR5_RTS; - and = ~0; - } else { - bis = 0; - and = ~(ZSWR5_DTR | ZSWR5_RTS); - } - s = splzs(); - cs->cs_preg[5] = (cs->cs_preg[5] | bis) & and; - if (cs->cs_heldchange == 0) { - if (cs->cs_ttyp->t_state & TS_BUSY) { - cs->cs_heldtbc = cs->cs_tbc; - cs->cs_tbc = 0; - cs->cs_heldchange = 1; - } else { - cs->cs_creg[5] = (cs->cs_creg[5] | bis) & and; - ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]); - } - } - splx(s); -} - -/* - * Write the given register set to the given zs channel in the proper order. - * The channel must not be transmitting at the time. The receiver will - * be disabled for the time it takes to write all the registers. - */ -static void -zs_loadchannelregs(zc, reg) - volatile struct zschan *zc; - u_char *reg; -{ - int i; - - zc->zc_csr = ZSM_RESET_ERR; /* reset error condition */ - ZS_DELAY(); - -#if 1 /* XXX - Is this really a good idea? -gwr */ - i = zc->zc_data; /* drain fifo */ - ZS_DELAY(); - i = zc->zc_data; - ZS_DELAY(); - i = zc->zc_data; - ZS_DELAY(); -#endif - - /* baud clock divisor, stop bits, parity */ - ZS_WRITE(zc, 4, reg[4]); - - /* misc. TX/RX control bits */ - ZS_WRITE(zc, 10, reg[10]); - - /* char size, enable (RX/TX) */ - ZS_WRITE(zc, 3, reg[3] & ~ZSWR3_RX_ENABLE); - ZS_WRITE(zc, 5, reg[5] & ~ZSWR5_TX_ENABLE); - - /* interrupt enables: TX, TX, STATUS */ - ZS_WRITE(zc, 1, reg[1]); - - /* interrupt vector */ - ZS_WRITE(zc, 2, reg[2]); - - /* master interrupt control */ - ZS_WRITE(zc, 9, reg[9]); - - /* clock mode control */ - ZS_WRITE(zc, 11, reg[11]); - - /* baud rate (lo/hi) */ - ZS_WRITE(zc, 12, reg[12]); - ZS_WRITE(zc, 13, reg[13]); - - /* Misc. control bits */ - ZS_WRITE(zc, 14, reg[14]); - - /* which lines cause status interrupts */ - ZS_WRITE(zc, 15, reg[15]| 1); - ZS_WRITE(zc, 7, 0); - ZS_WRITE(zc, 15, reg[15]); - - /* char size, enable (RX/TX)*/ - ZS_WRITE(zc, 3, reg[3]); - ZS_WRITE(zc, 5, reg[5]); -#ifdef DEBUG2 - printf("Params %x %x %x %x %x %x %x %x %x %x %x %x %x\n", - reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[9], - reg[10], reg[11], reg[12], reg[13], reg[14], reg[15]); -#endif -} - -static u_char -zs_read(zc, reg) - volatile struct zschan *zc; - u_char reg; -{ - u_char val; - - zc->zc_csr = reg; - ZS_DELAY(); - val = zc->zc_csr; - ZS_DELAY(); - return val; -} - -static u_char -zs_write(zc, reg, val) - volatile struct zschan *zc; - u_char reg, val; -{ - zc->zc_csr = reg; - ZS_DELAY(); - zc->zc_csr = val; - ZS_DELAY(); - return val; -} - -#ifdef KGDB -/* - * Get a character from the given kgdb channel. Called at splhigh(). - * XXX - Add delays, or combine with zscngetc()... - */ -static int -zs_kgdb_getc(arg) - void *arg; -{ - register volatile struct zschan *zc = (volatile struct zschan *)arg; - register int c, rr0; - - do { - rr0 = zc->zc_csr; - ZS_DELAY(); - } while ((rr0 & ZSRR0_RX_READY) == 0); - c = zc->zc_data; - ZS_DELAY(); - return (c); -} - -/* - * Put a character to the given kgdb channel. Called at splhigh(). - */ -static void -zs_kgdb_putc(arg, c) - void *arg; - int c; -{ - register volatile struct zschan *zc = (volatile struct zschan *)arg; - register int c, rr0; - - do { - rr0 = zc->zc_csr; - ZS_DELAY(); - } while ((rr0 & ZSRR0_TX_READY) == 0); - zc->zc_data = c; - ZS_DELAY(); -} - -/* - * Set up for kgdb; called at boot time before configuration. - * KGDB interrupts will be enabled later when zs0 is configured. - */ -void -zs_kgdb_init() -{ - volatile struct zsdevice *addr; - volatile struct zschan *zc; - int unit, zs; - - if (major(kgdb_dev) != ZSMAJOR) - return; - unit = minor(kgdb_dev); - /* - * Unit must be 0 or 1 (zs0). - */ - if ((unsigned)unit >= ZS_KBD) { - printf("zs_kgdb_init: bad minor dev %d\n", unit); - return; - } - zs = unit >> 1; - unit &= 1; - - if (zsaddr[0] == NULL) - panic("kbdb_attach: zs0 not yet mapped"); - addr = zsaddr[0]; - - zc = (unit == 0) ? - &addr->zs_chan[ZS_CHAN_A] : - &addr->zs_chan[ZS_CHAN_B]; - zs_kgdb_savedspeed = zs_getspeed(zc); - printf("zs_kgdb_init: attaching zs%d%c at %d baud\n", - zs, unit + 'a', kgdb_rate); - zs_reset(zc, 1, kgdb_rate); - kgdb_attach(zs_kgdb_getc, zs_kgdb_putc, (void *)zc); -} -#endif /* KGDB */ - -void zsinit(void) -{ - volatile struct zschan *zc; - u_char ch; - - /* get the base address of the chip */ - zsaddr[0] = (struct zsdevice *)sccA; - zsinitted = 1; - - zc=(volatile struct zschan *)zsaddr[0]; - ch=zc->zc_csr; - ch=zc->zc_csr; -} - -static void -serinit(int running_interrupts) -{ - int bcount; - int i, s, spd, im; - - if (!sccA) - panic("sccA offset not set!\n"); - - im=mac68k_machine.serial_console & 0x03; - - /* note: the HACKed routine doesn't do a lot of the pleasantries in the - old mac routine. Oh well. This is still a hacked version */ - /* zs_reset doesn't turn on interrupts! */ - zs_reset((volatile struct zschan *)&sccA[0], - (running_interrupts && (im!=3)), serdefaultrate); - zs_reset((volatile struct zschan *)&sccA[2], - (running_interrupts && (im!=1)), serdefaultrate); - - return; -} - -/* - * Console functions. - */ -dev_t mac68k_serdev; - -sercnprobe(struct consdev * cp) -{ - extern u_long IOBase; - int maj, unit; - - for (maj = 0; maj < nchrdev; maj++) { - if (cdevsw[maj].d_open == seropen) { - break; - } - } - if (maj == nchrdev) { - /* no console entry for us */ - if (mac68k_machine.serial_boot_echo) { - /* major number doesn't really matter. */ - mac68k_serdev = makedev(maj, 0); - mac68k_set_io_offsets(IOBase); - zs_conschan = (volatile struct zschan *)ZS_CONS_B; - serinit(0); - } - return 0; - } - - cp->cn_pri = CN_NORMAL; /* Lower than CN_INTERNAL */ - if (mac68k_machine.serial_console & 0x01) { - cp->cn_pri = CN_REMOTE; /* Higher than CN_INTERNAL */ - mac68k_machine.serial_boot_echo =0; - } - - unit = (mac68k_machine.serial_console & 0x02) ? 1 : 0; - - cp->cn_dev = makedev(maj, unit); - - if (mac68k_machine.serial_boot_echo) { - /* - * at this point, we know that we don't have a serial - * console, but are doing echo - */ - mac68k_set_io_offsets(IOBase); - zs_conschan = (volatile struct zschan *)ZS_CONS_B; - serinit(0); - } - return 0; -} - -sercninit(struct consdev * cp) -{ - extern u_long IOBase; - - mac68k_set_io_offsets(IOBase); - /* - * zsinit(); This is not the right time to zsinit as - * the IO mapping will move. - */ - zscninit(cp); - serinit(0); - printf("Whee! we are the console!\n"); -} diff --git a/sys/arch/mac68k/dev/serreg.h b/sys/arch/mac68k/dev/serreg.h deleted file mode 100644 index 0bc1b912d36..00000000000 --- a/sys/arch/mac68k/dev/serreg.h +++ /dev/null @@ -1,52 +0,0 @@ -/* $NetBSD: serreg.h,v 1.9 1995/04/21 02:48:09 briggs Exp $ */ - -/* - * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, - * Michael L. Finch, Bradley A. Grantham, and - * Lawrence A. Kesteloot - * 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 the Alice Group. - * 4. The names of the Alice Group or any of its members may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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. - * - * Mac II serial device interface - * - * Information used in this source was gleaned from low-memory - * global variables in MacOS and the Advanced Micro Devices - * 1992 Data Book/Handbook. - */ - -/* Gleaned from MacOS */ -extern volatile unsigned char *sccA; - -#define SERBRD(x) (mac68k_machine.sccClkConst / (x) - 2) -#define SCCCNTL(unit) (sccA[2 - ((unit) << 1)]) -#define SCCRDWR(unit) (sccA[6 - ((unit) << 1)]) - -#define SER_DOCNTL(unit, reg, val) \ - {SCCCNTL(unit) = (reg); SCCCNTL(unit) = (val);} -#define SER_STATUS(unit, reg) \ - (SCCCNTL(unit) = (reg), SCCCNTL(unit)) diff --git a/sys/arch/mac68k/dev/z8530reg.h b/sys/arch/mac68k/dev/z8530reg.h index ee44a4f78a9..4cf1554b605 100644 --- a/sys/arch/mac68k/dev/z8530reg.h +++ b/sys/arch/mac68k/dev/z8530reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: z8530reg.h,v 1.1 1995/10/09 12:42:18 briggs Exp $ */ +/* $NetBSD: z8530reg.h,v 1.3 1996/05/18 18:54:23 briggs Exp $ */ /* * Copyright (c) 1992, 1993 @@ -64,38 +64,26 @@ * differently for the two channels. We can, however, ignore this much * of the time. */ -#ifndef LOCORE + +/* + * This file also includes flags for the Z85C30 and Z85230 enhanced scc. + * The CMOS 8530 includes extra SDLC functionality, and is used in a + * number of Macs (often in the Z85C80, an 85C30 combined w/ a SCSI + * controller). -wrs + */ +#if 0 /* Example only! */ +/* + * The layout of this structure is hardware-dependent! + * Define these in some machine-dependent place. + */ struct zschan { -#if (BYTE_ORDER == BIG_ENDIAN) && !defined(atari) -#ifndef mac68k - volatile u_char zc_csr; /* ctrl,status, and indirect access */ - u_char zc_xxx0; - volatile u_char zc_data; /* data */ - u_char zc_xxx1; -#else - volatile u_char zc_csr; /* ctrl,status, and indirect access */ - u_char zc_xxx0; - u_char zc_xxx1; - u_char zc_xxx2; - volatile u_char zc_data; /* data */ - u_char zc_xxx3; - u_char zc_xxx4; - u_char zc_xxx5; -#endif -#else - u_char zc_xxx0; - volatile u_char zc_csr; /* ctrl,status, and indirect access */ - u_char zc_xxx1; - volatile u_char zc_data; /* data */ -#endif + volatile u_char zc_csr; /* ctrl, status, or reg. number */ + volatile u_char zc_data; /* data or numbered register */ }; - -typedef struct zschan zschan; - struct zsdevice { struct zschan zs_chan[2]; }; -#endif +#endif /* Example only! */ /* * Some of the names in this files were chosen to make the hsis driver @@ -119,8 +107,15 @@ struct zsdevice { */ #define ZSRR_IVEC 2 /* interrupt vector (channel 0) */ #define ZSRR_IPEND 3 /* interrupt pending (ch. 0 only) */ +#define ZSRR_TXSYNC 6 /* sync transmit char (monosync mode) */ +#define ZSRR_RXSYNC 7 /* sync receive char (monosync mode) */ +#define ZSRR_SYNCLO 6 /* sync low byte (bisync mode) */ +#define ZSRR_SYNCHI 7 /* sync high byte (bisync mode) */ +#define ZSRR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */ +#define ZSRR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */ #define ZSRR_BAUDLO 12 /* baud rate generator (low half) */ #define ZSRR_BAUDHI 13 /* baud rate generator (high half) */ +#define ZSRR_ENHANCED 14 /* read address of WR7' - yes, it's not 7!*/ #define ZSWR_IVEC 2 /* interrupt vector (shared) */ #define ZSWR_TXSYNC 6 /* sync transmit char (monosync mode) */ @@ -131,6 +126,7 @@ struct zsdevice { #define ZSWR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */ #define ZSWR_BAUDLO 12 /* baud rate generator (low half) */ #define ZSWR_BAUDHI 13 /* baud rate generator (high half) */ +#define ZSWR_ENHANCED 7 /* write address of WR7' */ /* * Registers 0 through 7 may be written with any one of the 8 command @@ -260,6 +256,21 @@ struct zsdevice { #endif /* + * Bits in Write Register 7' (ZSWR_ENHANCED above). This register is + * only available on the 85230. Dispite the fact it contains flags + * and not a single value, the register was named as it is read + * via RR14. Weird. + */ + /* 0x80 unused */ +#define ZSWR7P_EXTEND_READ 0x40 /* modify read map; make most regs readable */ +#define ZSWR7P_TX_FIFO 0x20 /* change level for Tx FIFO empty int */ +#define ZSWR7P_DTR_TIME 0x10 /* modifies deact. speed of /DTR//REQ */ +#define ZSWR7P_RX_FIFO 0x08 /* Rx FIFO int on 1/2 full? */ +#define ZSWR7P_RTS_DEACT 0x04 /* automatically deassert RTS */ +#define ZSWR7P_AUTO_EOM_RESET 0x02 /* automatically reset EMO/Tx Underrun */ +#define ZSWR7P_AUTO_TX_FLAG 0x01 /* Auto send SDLC flag at transmit start */ + +/* * Bits in Write Register 9 (`Master Interrupt Control'). Bits 7 & 6 * are taken as a unit and indicate the type of reset; 00 means no reset * (and is not defined here). @@ -267,7 +278,7 @@ struct zsdevice { #define ZSWR9_HARD_RESET 0xc0 /* force hardware reset */ #define ZSWR9_A_RESET 0x80 /* reset channel A (0) */ #define ZSWR9_B_RESET 0x40 /* reset channel B (1) */ - /* 0x20 unused */ +#define ZSWR9_SOFT_INTAC 0x20 /* Not in NMOS version */ #define ZSWR9_STATUS_HIGH 0x10 /* status in high bits of intr vec */ #define ZSWR9_MASTER_IE 0x08 /* master interrupt enable */ @@ -300,13 +311,13 @@ struct zsdevice { */ #define ZSWR11_XTAL 0x80 /* have xtal between RTxC* and SYNC* */ /* (else have TTL oscil. on RTxC*) */ -#define ZSWR11_RXCLK_RTXC 0x00 /* recv clock taken from TRxC* pin */ +#define ZSWR11_RXCLK_RTXC 0x00 /* recv clock taken from RTxC* pin */ #define ZSWR11_RXCLK_TRXC 0x20 /* recv clock taken from TRxC* pin */ #define ZSWR11_RXCLK_BAUD 0x40 /* recv clock taken from BRG */ #define ZSWR11_RXCLK_DPLL 0x60 /* recv clock taken from DPLL */ -#define ZSWR11_TXCLK_RTXC 0x00 /* xmit clock taken from TRxC* pin */ -#define ZSWR11_TXCLK_TRXC 0x08 /* xmit clock taken from RTxC* pin */ +#define ZSWR11_TXCLK_RTXC 0x00 /* xmit clock taken from RTxC* pin */ +#define ZSWR11_TXCLK_TRXC 0x08 /* xmit clock taken from TRxC* pin */ #define ZSWR11_TXCLK_BAUD 0x10 /* xmit clock taken from BRG */ #define ZSWR11_TXCLK_DPLL 0x18 /* xmit clock taken from DPLL */ @@ -367,15 +378,19 @@ struct zsdevice { * Bits in Write Register 15 (`External/Status Interrupt Control'). * Most of these cause status interrupts whenever the corresponding * bit or pin changes state (i.e., any rising or falling edge). + * + * NOTE: ZSWR15_SDLC_FIFO & ZSWR15_ENABLE_ENHANCED should not be + * set on an NMOS 8530. Also, ZSWR15_ENABLE_ENHANCED is only + * available on the 85230. */ #define ZSWR15_BREAK_IE 0x80 /* enable break/abort status int */ #define ZSWR15_TXUEOM_IE 0x40 /* enable TX underrun/EOM status int */ #define ZSWR15_CTS_IE 0x20 /* enable CTS* pin status int */ #define ZSWR15_SYNCHUNT_IE 0x10 /* enable SYNC* pin/hunt status int */ #define ZSWR15_DCD_IE 0x08 /* enable DCD* pin status int */ - /* 0x04 unused, must be zero */ +#define ZSWR15_SDLC_FIFO 0x04 /* enable SDLC FIFO enhancements */ #define ZSWR15_ZERO_COUNT_IE 0x02 /* enable BRG-counter = 0 status int */ - /* 0x01 unused, must be zero */ +#define ZSWR15_ENABLE_ENHANCED 0x01 /* enable writing WR7' at reg 7 */ /* * Bits in Read Register 0 (`Transmit/Receive Buffer Status and External |