diff options
author | Steve Murphree <smurph@cvs.openbsd.org> | 2001-02-01 03:38:24 +0000 |
---|---|---|
committer | Steve Murphree <smurph@cvs.openbsd.org> | 2001-02-01 03:38:24 +0000 |
commit | 8e8d908c6c5754fd0205eb089e6c5822f92d4473 (patch) | |
tree | 29b74cfdddc396e8a0985b07dd1affefefd062bf /sys/arch/mvme88k/dev | |
parent | be6f95e73cf569c2b374d15432a35d294774c196 (diff) |
Major changes to get MVME188 working. More header and code cleanups. The
kernel is tested on MVME188A/2P256 and MVME188A/1P64.
Diffstat (limited to 'sys/arch/mvme88k/dev')
-rw-r--r-- | sys/arch/mvme88k/dev/bugio.c | 65 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/busswitch.c | 4 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/cl.c | 34 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/clock.c | 251 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/dart.c | 1684 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/if_ve.c | 49 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/sclock.c | 182 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/siop.c | 6 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/syscon.c | 114 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/sysconreg.h | 72 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vme.c | 143 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vme.h | 63 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vs.c | 1674 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vsdma.c | 102 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vsreg.h | 80 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vsvar.h | 104 |
16 files changed, 2465 insertions, 2162 deletions
diff --git a/sys/arch/mvme88k/dev/bugio.c b/sys/arch/mvme88k/dev/bugio.c index aee175f7206..24346d014e0 100644 --- a/sys/arch/mvme88k/dev/bugio.c +++ b/sys/arch/mvme88k/dev/bugio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bugio.c,v 1.4 1999/09/27 18:43:21 smurph Exp $ */ +/* $OpenBSD: bugio.c,v 1.5 2001/02/01 03:38:13 smurph Exp $ */ /* Copyright (c) 1998 Steve Murphree, Jr. */ #include <machine/bugio.h> @@ -21,6 +21,7 @@ #define RTC_RD "0x0053" #define RETURN "0x0063" #define BRD_ID "0x0070" +#define FORKMPU "0x0100" #define BUGTRAP "0x01F0" int ossr0, ossr1, ossr2, ossr3; @@ -65,13 +66,13 @@ char buginchr(void) { register int cc; - int ret; + int ret; BUGCTXT(); asm volatile ("or r9,r0," INCHR); asm volatile ("tb0 0,r0,0x1F0"); asm volatile ("or %0,r0,r2" : "=r" (cc) : ); - ret = cc; - OSCTXT(); + ret = cc; + OSCTXT(); return ((char)ret & 0xFF); } @@ -83,7 +84,7 @@ bugoutchr(unsigned char c) bugpcrlf(); return; } - + BUGCTXT(); asm("or r2,r0,%0" : : "r" (cc)); @@ -97,7 +98,7 @@ bugoutchr(unsigned char c) buginstat(void) { - int ret; + register int ret; BUGCTXT(); asm volatile ("or r9,r0," INSTAT); @@ -131,7 +132,7 @@ bugdskrd(struct bugdisk_io *arg) BUGCTXT(); asm("or r9,r0, " DSKRD); - asm("tb0 0,r0,0x1F0"); + asm("tb0 0,r0,0x1F0"); asm("or %0,r0,r2" : "=r" (ret) : ); OSCTXT(); @@ -145,7 +146,7 @@ bugdskwr(struct bugdisk_io *arg) int ret; BUGCTXT(); asm("or r9,r0, " DSKWR); - asm("tb0 0,r0,0x1F0"); + asm("tb0 0,r0,0x1F0"); asm("or %0,r0,r2" : "=r" (ret) : ); OSCTXT(); return ((ret&0x4) == 0x4 ? 1 : 0); @@ -168,6 +169,14 @@ bugdelay(int delay) OSCTXT(); } +bugfork(int cpu, unsigned address) +{ + BUGCTXT(); + asm("or r9,r0, " FORKMPU); + asm("tb0 0,r0,0x1F0"); + OSCTXT(); +} + bugreturn(void) { BUGCTXT(); @@ -196,26 +205,26 @@ bugnetctrl(struct bugniocall *niocall) /* OSCTXT();*/ } -typedef struct netcnfgp { - unsigned int magic; - unsigned int nodemem; - unsigned int bfla; - unsigned int bfea; - unsigned int bfed; - unsigned int bfl; - unsigned int bfbo; - unsigned int tbuffer; - unsigned char cipa[4]; - unsigned char sipa[4]; - unsigned char netmask[4]; - unsigned char broadcast[4]; - unsigned char gipa[4]; - unsigned char bootp_retry; - unsigned char tftp_retry; - unsigned char bootp_ctl; - unsigned char cnfgp_ctl; - unsigned char filename[64]; - unsigned char argfname[64]; +typedef struct netcnfgp { + unsigned int magic; + unsigned int nodemem; + unsigned int bfla; + unsigned int bfea; + unsigned int bfed; + unsigned int bfl; + unsigned int bfbo; + unsigned int tbuffer; + unsigned char cipa[4]; + unsigned char sipa[4]; + unsigned char netmask[4]; + unsigned char broadcast[4]; + unsigned char gipa[4]; + unsigned char bootp_retry; + unsigned char tftp_retry; + unsigned char bootp_ctl; + unsigned char cnfgp_ctl; + unsigned char filename[64]; + unsigned char argfname[64]; } NETCNFGP; struct bugniotcall { diff --git a/sys/arch/mvme88k/dev/busswitch.c b/sys/arch/mvme88k/dev/busswitch.c index 71eb44d9937..e6637439613 100644 --- a/sys/arch/mvme88k/dev/busswitch.c +++ b/sys/arch/mvme88k/dev/busswitch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: busswitch.c,v 1.1 1999/09/27 18:43:22 smurph Exp $ */ +/* $OpenBSD: busswitch.c,v 1.2 2001/02/01 03:38:13 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. @@ -134,7 +134,7 @@ busswitch_scan(parent, child, args) bzero(&oca, sizeof oca); oca.ca_offset = cf->cf_loc[0]; oca.ca_ipl = cf->cf_loc[1]; - if ((oca.ca_offset != (void*)-1) && ISIIOVA(sc->sc_vaddr + oca.ca_offset)) { + if (((int)oca.ca_offset != -1) && ISIIOVA(sc->sc_vaddr + oca.ca_offset)) { oca.ca_vaddr = sc->sc_vaddr + oca.ca_offset; oca.ca_paddr = sc->sc_paddr + oca.ca_offset; } else { diff --git a/sys/arch/mvme88k/dev/cl.c b/sys/arch/mvme88k/dev/cl.c index be0684214b6..06aec3f0659 100644 --- a/sys/arch/mvme88k/dev/cl.c +++ b/sys/arch/mvme88k/dev/cl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cl.c,v 1.6 2000/03/26 23:32:00 deraadt Exp $ */ +/* $OpenBSD: cl.c,v 1.7 2001/02/01 03:38:14 smurph Exp $ */ /* * Copyright (c) 1995 Dale Rahn. All rights reserved. @@ -895,25 +895,25 @@ clstop(tp, flag) int clcnprobe(cp) - struct consdev *cp; +struct consdev *cp; { /* always there ? */ /* serial major */ - int maj; - - /* bomb if it'a a MVME188 */ - if (cputyp == CPU_188){ - cp->cn_pri = CN_DEAD; - return 0; - } - /* locate the major number */ - for (maj = 0; maj < nchrdev; maj++) - if (cdevsw[maj].d_open == clopen) - break; - cp->cn_dev = makedev (maj, 0); - cp->cn_pri = CN_NORMAL; - - return 1; + int maj; + + /* bomb if it'a a MVME188 */ + if (cputyp == CPU_188) { + cp->cn_pri = CN_DEAD; + return 0; + } + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == clopen) + break; + cp->cn_dev = makedev (maj, 0); + cp->cn_pri = CN_NORMAL; + + return 1; } int diff --git a/sys/arch/mvme88k/dev/clock.c b/sys/arch/mvme88k/dev/clock.c index 2609694ac5d..06295289264 100644 --- a/sys/arch/mvme88k/dev/clock.c +++ b/sys/arch/mvme88k/dev/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.6 1999/09/27 18:43:23 smurph Exp $ */ +/* $OpenBSD: clock.c,v 1.7 2001/02/01 03:38:14 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * Copyright (c) 1995 Theo de Raadt @@ -88,10 +88,13 @@ #include <sys/gmon.h> #endif +#include <machine/asm_macro.h> /* for stack_pointer() */ +#include <machine/board.h> /* for register defines */ #include <machine/psl.h> #include <machine/autoconf.h> #include <machine/bugio.h> #include <machine/cpu.h> +#include <machine/mmu.h> /* DMA_CACHE_SYNC, etc... */ #include "pcctwo.h" #if NPCCTWO > 0 #include <mvme88k/dev/pcctworeg.h> @@ -107,17 +110,17 @@ int timerok = 0; u_long delay_factor = 1; -static int clockmatch __P((struct device *, void *, void *)); -static void clockattach __P((struct device *, struct device *, void *)); +static int clockmatch __P((struct device *, void *, void *)); +static void clockattach __P((struct device *, struct device *, void *)); -void sbc_initclock(void); -void m188_initclock(void); -void m188_timer_init __P((unsigned)); +void sbc_initclock(void); +void m188_initclock(void); +void m188_timer_init __P((unsigned)); struct clocksoftc { - struct device sc_dev; - struct intrhand sc_profih; - struct intrhand sc_statih; + struct device sc_dev; + struct intrhand sc_profih; + struct intrhand sc_statih; }; struct cfattach clock_ca = { @@ -128,10 +131,10 @@ struct cfdriver clock_cd = { NULL, "clock", DV_DULL, 0 }; -int sbc_clockintr __P((void *)); -int sbc_statintr __P((void *)); -int m188_clockintr __P((void *)); -int m188_statintr __P((void *)); +int sbc_clockintr __P((void *)); +int sbc_statintr __P((void *)); +int m188_clockintr __P((void *)); +int m188_statintr __P((void *)); int clockbus; u_char prof_reset; @@ -142,8 +145,8 @@ u_char prof_reset; */ int clockmatch(parent, vcf, args) - struct device *parent; - void *vcf, *args; +struct device *parent; +void *vcf, *args; { register struct confargs *ca = args; register struct cfdata *cf = vcf; @@ -160,57 +163,55 @@ clockmatch(parent, vcf, args) ca->ca_ipl = IPL_CLOCK; /* set size to 0 - see pcctwo.c:match for details */ ca->ca_len = 0; - - return (1); } void clockattach(parent, self, args) - struct device *parent, *self; - void *args; +struct device *parent, *self; +void *args; { struct confargs *ca = args; struct clocksoftc *sc = (struct clocksoftc *)self; clockbus = ca->ca_bustype; - - switch (clockbus) { -#if NPCCTWO > 0 - case BUS_PCCTWO: - sc->sc_profih.ih_fn = sbc_clockintr; - sc->sc_profih.ih_arg = 0; - sc->sc_profih.ih_wantframe = 1; - sc->sc_profih.ih_ipl = ca->ca_ipl; - prof_reset = ca->ca_ipl | PCC2_IRQ_IEN | PCC2_IRQ_ICLR; - pcctwointr_establish(PCC2V_TIMER1, &sc->sc_profih); - mdfp.clock_init_func = &sbc_initclock; - printf(": VME1x7"); - break; + + switch (clockbus) { +#if NPCCTWO > 0 + case BUS_PCCTWO: + sc->sc_profih.ih_fn = sbc_clockintr; + sc->sc_profih.ih_arg = 0; + sc->sc_profih.ih_wantframe = 1; + sc->sc_profih.ih_ipl = ca->ca_ipl; + prof_reset = ca->ca_ipl | PCC2_IRQ_IEN | PCC2_IRQ_ICLR; + pcctwointr_establish(PCC2V_TIMER1, &sc->sc_profih); + mdfp.clock_init_func = &sbc_initclock; + printf(": VME1x7"); + break; #endif /* NPCCTWO */ -#if NSYSCON > 0 - case BUS_SYSCON: - sc->sc_profih.ih_fn = m188_clockintr; - sc->sc_profih.ih_arg = 0; - sc->sc_profih.ih_wantframe = 1; - sc->sc_profih.ih_ipl = ca->ca_ipl; - sysconintr_establish(SYSCV_TIMER1, &sc->sc_profih); - mdfp.clock_init_func = &m188_initclock; - printf(": VME188"); - break; +#if NSYSCON > 0 && defined(MVME188) + case BUS_SYSCON: + sc->sc_profih.ih_fn = m188_clockintr; + sc->sc_profih.ih_arg = 0; + sc->sc_profih.ih_wantframe = 1; + sc->sc_profih.ih_ipl = ca->ca_ipl; + sysconintr_establish(SYSCV_TIMER1, &sc->sc_profih); + mdfp.clock_init_func = &m188_initclock; + printf(": VME188"); + break; #endif /* NSYSCON */ - } + } printf("\n"); } -#if NPCCTWO > 0 +#if NPCCTWO > 0 void sbc_initclock(void) { register int statint, minint; -#ifdef DEBUG - printf("SBC clock init\n"); +#ifdef CLOCK_DEBUG + printf("SBC clock init\n"); #endif if (1000000 % hz) { printf("cannot get %d Hz clock; using 100 Hz\n", hz); @@ -223,7 +224,7 @@ sbc_initclock(void) sys_pcc2->pcc2_t1cmp = pcc2_timer_us2lim(tick); sys_pcc2->pcc2_t1count = 0; sys_pcc2->pcc2_t1ctl = PCC2_TCTL_CEN | PCC2_TCTL_COC | - PCC2_TCTL_COVF; + PCC2_TCTL_COVF; sys_pcc2->pcc2_t1irq = prof_reset; } @@ -233,74 +234,99 @@ sbc_initclock(void) */ int sbc_clockintr(arg) - void *arg; +void *arg; { sys_pcc2->pcc2_t1irq = prof_reset; hardclock(arg); #include "bugtty.h" #if NBUGTTY > 0 - bugtty_chkinput(); +/* bugtty_chkinput();*/ #endif /* NBUGTTY */ timerok = 1; - return (1); + return (1); } #endif /* NPCCTWO */ - +int delay(us) - register int us; +register int us; { volatile register int c; unsigned long st; /* * We use the vme system controller for the delay clock. * Do not go to the real timer until vme device is present. - * Or, in the case of MVME188, not at all. + * Or, in the case of MVME188, not at all. */ if (sys_vme2 == NULL || cputyp == CPU_188) { - c = 3 * us; - while (--c > 0); - return(0); + c = 3 * us; + while (--c > 0); + return (0); } - sys_vme2->vme2_irql1 |= (0 << VME2_IRQL1_TIC1SHIFT); - sys_vme2->vme2_t1count = 0; - sys_vme2->vme2_tctl |= (VME2_TCTL1_CEN | VME2_TCTL1_COVF); + sys_vme2->vme2_irql1 |= (0 << VME2_IRQL1_TIC1SHIFT); + sys_vme2->vme2_t1count = 0; + sys_vme2->vme2_tctl |= (VME2_TCTL1_CEN | VME2_TCTL1_COVF); - while (sys_vme2->vme2_t1count < us) + while (sys_vme2->vme2_t1count < us) ; - sys_vme2->vme2_tctl &= ~(VME2_TCTL1_CEN | VME2_TCTL1_COVF); + sys_vme2->vme2_tctl &= ~(VME2_TCTL1_CEN | VME2_TCTL1_COVF); return (0); } #if NSYSCON > 0 int counter = 0; - +#define IST int m188_clockintr(arg) - void *arg; +void *arg; { - volatile int tmp; - /* acknowledge the timer interrupt */ - /* clear the counter/timer output OP3 while we program the DART */ - *((volatile int *) DART_OPCR) = 0x00; + volatile int tmp; + volatile int *dti_stop = (volatile int *)DART_STOPC; + volatile int *dti_start = (volatile int *)DART_STARTC; + volatile int *ist = (volatile int *)MVME188_IST; + register unsigned long sp; + + /* acknowledge the timer interrupt */ + dma_cachectl(0xFFF82000, 0x1000, DMA_CACHE_SYNC_INVAL); + tmp = *dti_stop; + + + /* check kernel stack for overflow */ + sp = stack_pointer(); + if (sp < UADDR + NBPG && sp > UADDR) { + if (*ist & DTI_BIT) { + printf("DTI not clearing!\n"); + } + printf("kernel stack @ 0x%8x\n", sp); + panic("stack overflow eminant!"); + } + +#if 0 + /* clear the counter/timer output OP3 while we program the DART */ + *((volatile int *) DART_OPCR) = 0x00; - /* do the stop counter/timer command */ - tmp = *((volatile int *) DART_STOPC); + /* do the stop counter/timer command */ + tmp = *((volatile int *) DART_STOPC); - /* set counter/timer to counter mode, clock/16 */ - *((volatile int *) DART_ACR) = 0x30; - - *((volatile int *) DART_CTUR) = counter / 256; /* set counter MSB */ - *((volatile int *) DART_CTLR) = counter % 256; /* set counter LSB */ - *((volatile int *) DART_IVR) = SYSCV_TIMER1; /* set interrupt vec */ + /* set counter/timer to counter mode, clock/16 */ + *((volatile int *) DART_ACR) = 0x30; + *((volatile int *) DART_CTUR) = counter / 256; /* set counter MSB */ + *((volatile int *) DART_CTLR) = counter % 256; /* set counter LSB */ + *((volatile int *) DART_IVR) = SYSCV_TIMER1; /* set interrupt vec */ +#endif hardclock(arg); #include "bugtty.h" #if NBUGTTY > 0 - bugtty_chkinput(); +/* bugtty_chkinput(); */ #endif /* NBUGTTY */ - /* give the start counter/timer command */ - tmp = *((volatile int *) DART_STARTC); - *((volatile int *) DART_OPCR) = 0x04; + /* give the start counter/timer command */ + tmp = *dti_start; +#if 0 + *((volatile int *) DART_OPCR) = 0x04; +#endif + if (*ist & DTI_BIT) { + printf("DTI not clearing!\n"); + } return (1); } @@ -309,8 +335,8 @@ m188_initclock(void) { register int statint, minint; -#ifdef DEBUG - printf("VME188 clock init\n"); +#ifdef CLOCK_DEBUG + printf("VME188 clock init\n"); #endif if (1000000 % hz) { printf("cannot get %d Hz clock; using 100 Hz\n", hz); @@ -323,36 +349,39 @@ m188_initclock(void) void m188_timer_init(unsigned period) { - int imr; - - /* make sure the counter range is proper. */ - if ( period < 9 ) - counter = 2; - else if ( period > 284421 ) - counter = 65535; - else - counter = period / 4.34; -#ifdef DEBUG - printf("tick == %d, period == %d\n", tick, period); - printf("timer will interrupt every %d usec\n", (int) (counter * 4.34)); + int imr; + dma_cachectl(0xFFF82000, 0x1000, DMA_CACHE_SYNC_INVAL); + + /* make sure the counter range is proper. */ + if ( period < 9 ) + counter = 2; + else if ( period > 284421 ) + counter = 65535; + else + counter = period / 4.34; +#ifdef CLOCK_DEBUG + printf("tick == %d, period == %d\n", tick, period); + printf("timer will interrupt every %d usec\n", (int) (counter * 4.34)); #endif - /* clear the counter/timer output OP3 while we program the DART */ - *((volatile int *) DART_OPCR) = 0x00; - - /* do the stop counter/timer command */ - imr = *((volatile int *) DART_STOPC); - - /* set counter/timer to counter mode, clock/16 */ - *((volatile int *) DART_ACR) = 0x30; - - *((volatile int *) DART_CTUR) = counter / 256; /* set counter MSB */ - *((volatile int *) DART_CTLR) = counter % 256; /* set counter LSB */ - *((volatile int *) DART_IVR) = SYSCV_TIMER1; /* set interrupt vec */ - /* give the start counter/timer command */ - /* (yes, this is supposed to be a read) */ - imr = *((volatile int *) DART_STARTC); - - /* set the counter/timer output OP3 */ - *((volatile int *) DART_OPCR) = 0x04; + /* clear the counter/timer output OP3 while we program the DART */ + *((volatile int *) DART_OPCR) = 0x00; + + /* do the stop counter/timer command */ + imr = *((volatile int *) DART_STOPC); + + /* set counter/timer to counter mode, clock/16 */ + *((volatile int *) DART_ACR) = 0x30; + + *((volatile int *) DART_CTUR) = counter / 256; /* set counter MSB */ + *((volatile int *) DART_CTLR) = counter % 256; /* set counter LSB */ + *((volatile int *) DART_IVR) = SYSCV_TIMER1; /* set interrupt vec */ + + /* give the start counter/timer command */ + /* (yes, this is supposed to be a read) */ + imr = *((volatile int *) DART_STARTC); + + /* set the counter/timer output OP3 */ + *((volatile int *) DART_OPCR) = 0x04; } #endif /* NSYSCON */ + diff --git a/sys/arch/mvme88k/dev/dart.c b/sys/arch/mvme88k/dev/dart.c index 3592c80186a..c46ae78a9c6 100644 --- a/sys/arch/mvme88k/dev/dart.c +++ b/sys/arch/mvme88k/dev/dart.c @@ -46,32 +46,36 @@ #include <machine/psl.h> #define spldart() splx(IPL_TTY) -#if DDB - #include <machine/db_machdep.h> /* for details on entering kdb */ -extern unsigned char ddb_break_mode, ddb_break_char; +#if defined(DDB) +#include <machine/db_machdep.h> /* for details on entering kdb */ +#define DDB_ENTER_BREAK 0x1 +#define DDB_ENTER_CHAR 0x2 +unsigned char ddb_break_mode = DDB_ENTER_BREAK | DDB_ENTER_CHAR; +unsigned char ddb_break_char = '!'; #endif #if DEBUG - #define dprintf(stuff) /*printf stuff*/ + int dart_debug = 0; + #define dprintf(stuff) if (dart_debug) printf stuff #else #define dprintf(stuff) #endif struct dart_info { - struct tty *tty; - u_char dart_swflags; - struct simplelock t_lock; + struct tty *tty; + u_char dart_swflags; + struct simplelock t_lock; }; struct dartsoftc { - struct device sc_dev; - struct evcnt sc_intrcnt; - union dartreg *dart_reg; - struct dart_info sc_dart[2]; - struct intrhand sc_ih; - int sc_flags; - int sc_ipl; - int sc_vec; + struct device sc_dev; + struct evcnt sc_intrcnt; + union dartreg *dart_reg; + struct dart_info sc_dart[2]; + struct intrhand sc_ih; + int sc_flags; + int sc_ipl; + int sc_vec; }; int dartmatch __P((struct device *parent, void *self, void *aux)); @@ -116,32 +120,33 @@ struct dart_sv_reg dart_sv_reg; /* speed tables */ int dart_speeds[] = { - 0, /* 0 baud, special HUP condition */ - NOBAUD, /* 50 baud, not implemented */ - BD75, /* 75 baud */ - BD110, /* 110 baud */ - BD134, /* 134.5 baud */ - BD150, /* 150 baud */ - NOBAUD, /* 200 baud, not implemented */ - BD300, /* 300 baud */ - BD600, /* 600 baud */ - BD1200, /* 1200 baud */ - BD1800, /* 1800 baud */ - BD2400, /* 2400 baud */ - BD4800, /* 4800 baud */ - BD9600, /* 9600 baud */ - BD19200, /* 19200 baud */ - NOBAUD /* 38400 baud, not implemented */ + 0, /* 0 baud, special HUP condition */ + NOBAUD, /* 50 baud, not implemented */ + BD75, /* 75 baud */ + BD110, /* 110 baud */ + BD134, /* 134.5 baud */ + BD150, /* 150 baud */ + NOBAUD, /* 200 baud, not implemented */ + BD300, /* 300 baud */ + BD600, /* 600 baud */ + BD1200, /* 1200 baud */ + BD1800, /* 1800 baud */ + BD2400, /* 2400 baud */ + BD4800, /* 4800 baud */ + BD9600, /* 9600 baud */ + BD19200, /* 19200 baud */ + NOBAUD /* 38400 baud, not implemented */ }; -struct tty * darttty(dev) +struct tty* +darttty(dev) dev_t dev; { - int port; - struct dartsoftc *sc; - sc = (struct dartsoftc *) dart_cd.cd_devs[0]; - port = DART_PORT(dev); - return sc->sc_dart[port].tty; + int port; + struct dartsoftc *sc; + sc = (struct dartsoftc *) dart_cd.cd_devs[0]; + port = DART_PORT(dev); + return sc->sc_dart[port].tty; } int @@ -149,19 +154,19 @@ dartmatch(parent, vcf, args) struct device *parent; void *vcf, *args; { - struct cfdata *cf = vcf; - struct confargs *ca = args; - union dartreg *addr; - - /* Don't match if wrong cpu */ - if (cputyp != CPU_188) return (0); - ca->ca_vaddr = ca->ca_paddr; /* 1:1 */ - addr = (union dartreg *)ca->ca_vaddr; - if (badvaddr(addr, 2) <= 0) { - printf("==> syscon: failed address check.\n"); - return (0); - } - return (1); + struct cfdata *cf = vcf; + struct confargs *ca = args; + union dartreg *addr; + + /* Don't match if wrong cpu */ + if (cputyp != CPU_188) return (0); + ca->ca_vaddr = ca->ca_paddr; /* 1:1 */ + addr = (union dartreg *)ca->ca_vaddr; + if (badvaddr(addr, 2) <= 0) { + printf("==> dart: failed address check.\n"); + return (0); + } + return (1); } void @@ -170,96 +175,96 @@ struct device *parent; struct device *self; void *aux; { - struct dartsoftc *sc = (struct dartsoftc *)self; - struct confargs *ca = aux; - int i; - union dartreg *addr; /* pointer to DUART regs */ - union dart_pt_io *ptaddr; /* pointer to port regs */ - int port; /* port index */ - - /* set up dual port memory and registers and init*/ - sc->dart_reg = (union dartreg *)ca->ca_vaddr; - sc->sc_ipl = ca->ca_ipl; - ca->ca_vec = SYSCV_SCC; /* hard coded vector */ - sc->sc_vec = ca->ca_vec; - - addr = sc->dart_reg; - - /* save standard initialization */ - dart_sv_reg.sv_mr1[A_PORT] = PARDIS | RXRTS | CL8; - dart_sv_reg.sv_mr2[A_PORT] = /* TXCTS | */ SB1; - dart_sv_reg.sv_csr[A_PORT] = BD9600; - dart_sv_reg.sv_cr[A_PORT] = TXEN | RXEN; - - dart_sv_reg.sv_mr1[B_PORT] = PARDIS | RXRTS | CL8; - dart_sv_reg.sv_mr2[B_PORT] = /* TXCTS | */ SB1; - dart_sv_reg.sv_csr[B_PORT] = BD9600; - dart_sv_reg.sv_cr[B_PORT] = TXEN | RXEN; - - dart_sv_reg.sv_acr = BDSET2 | CCLK16 | IPDCDIB | IPDCDIA; - - /* Start out with Tx and RX interrupts disabled */ - /* Enable input port change interrupt */ - dart_sv_reg.sv_imr = IIPCHG; - - dprintf(("dartattach: resetting port A\n")); - - /* reset port a */ - addr->write.wr_cra = RXRESET | TXDIS | RXDIS; - DELAY_CR; - addr->write.wr_cra = TXRESET | TXDIS | RXDIS; - DELAY_CR; - addr->write.wr_cra = ERRRESET | TXDIS | RXDIS; - DELAY_CR; - addr->write.wr_cra = BRKINTRESET | TXDIS | RXDIS; - DELAY_CR; - addr->write.wr_cra = MRRESET | TXDIS | RXDIS; - - dprintf(("dartattach: resetting port B\n")); - - /* reset port b */ - addr->write.wr_crb = RXRESET | TXDIS | RXDIS; - DELAY_CR; - addr->write.wr_crb = TXRESET | TXDIS | RXDIS; - DELAY_CR; - addr->write.wr_crb = ERRRESET | TXDIS | RXDIS; - DELAY_CR; - addr->write.wr_crb = BRKINTRESET | TXDIS | RXDIS; - DELAY_CR; - addr->write.wr_crb = MRRESET | TXDIS | RXDIS; - DELAY_CR; - - /* initialize ports */ - for (port = 0, ptaddr = (union dart_pt_io *)addr; - port < MAXPORTS; - port++, ptaddr++) { - dprintf(("dartattach: init port %c\n", 'A' + port)); - ptaddr->write.wr_mr = dart_sv_reg.sv_mr1[port]; - ptaddr->write.wr_mr = dart_sv_reg.sv_mr2[port]; - ptaddr->write.wr_csr = dart_sv_reg.sv_csr[port]; - ptaddr->write.wr_cr = dart_sv_reg.sv_cr [port]; - } - - dprintf(("dartattach: init common regs\n")); - - /* initialize common register of a DUART */ - addr->write.wr_oprset = OPDTRA | OPRTSA | OPDTRB | OPRTSB; - - addr->write.wr_ctur = SLCTIM>>8; - addr->write.wr_ctlr = SLCTIM & 0xFF; - addr->write.wr_acr = dart_sv_reg.sv_acr; - addr->write.wr_imr = dart_sv_reg.sv_imr; - addr->write.wr_opcr = OPSET; - addr->write.wr_ivr = sc->sc_vec; - - /* enable interrupts */ - sc->sc_ih.ih_fn = dartintr; - sc->sc_ih.ih_arg = sc; - sc->sc_ih.ih_ipl = ca->ca_ipl; - sc->sc_ih.ih_wantframe = 0; - - intr_establish(ca->ca_vec, &sc->sc_ih); - evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt); + struct dartsoftc *sc = (struct dartsoftc *)self; + struct confargs *ca = aux; + int i; + union dartreg *addr; /* pointer to DUART regs */ + union dart_pt_io *ptaddr; /* pointer to port regs */ + int port; /* port index */ + + /* set up dual port memory and registers and init*/ + sc->dart_reg = (union dartreg *)ca->ca_vaddr; + sc->sc_ipl = ca->ca_ipl = IPL_TTY; /* always... hard coded ipl */ + ca->ca_vec = SYSCV_SCC; /* hard coded vector */ + sc->sc_vec = ca->ca_vec; + + addr = sc->dart_reg; + + /* save standard initialization */ + dart_sv_reg.sv_mr1[A_PORT] = PARDIS | RXRTS | CL8; + dart_sv_reg.sv_mr2[A_PORT] = /* TXCTS | */ SB1; + dart_sv_reg.sv_csr[A_PORT] = BD9600; + dart_sv_reg.sv_cr[A_PORT] = TXEN | RXEN; + + dart_sv_reg.sv_mr1[B_PORT] = PARDIS | RXRTS | CL8; + dart_sv_reg.sv_mr2[B_PORT] = /* TXCTS | */ SB1; + dart_sv_reg.sv_csr[B_PORT] = BD9600; + dart_sv_reg.sv_cr[B_PORT] = TXEN | RXEN; + + dart_sv_reg.sv_acr = BDSET2 | CCLK16 | IPDCDIB | IPDCDIA; + + /* Start out with Tx and RX interrupts disabled */ + /* Enable input port change interrupt */ + dart_sv_reg.sv_imr = IIPCHG; + + dprintf(("dartattach: resetting port A\n")); + + /* reset port a */ + addr->write.wr_cra = RXRESET | TXDIS | RXDIS; + DELAY_CR; + addr->write.wr_cra = TXRESET | TXDIS | RXDIS; + DELAY_CR; + addr->write.wr_cra = ERRRESET | TXDIS | RXDIS; + DELAY_CR; + addr->write.wr_cra = BRKINTRESET | TXDIS | RXDIS; + DELAY_CR; + addr->write.wr_cra = MRRESET | TXDIS | RXDIS; + + dprintf(("dartattach: resetting port B\n")); + + /* reset port b */ + addr->write.wr_crb = RXRESET | TXDIS | RXDIS; + DELAY_CR; + addr->write.wr_crb = TXRESET | TXDIS | RXDIS; + DELAY_CR; + addr->write.wr_crb = ERRRESET | TXDIS | RXDIS; + DELAY_CR; + addr->write.wr_crb = BRKINTRESET | TXDIS | RXDIS; + DELAY_CR; + addr->write.wr_crb = MRRESET | TXDIS | RXDIS; + DELAY_CR; + + /* initialize ports */ + for (port = 0, ptaddr = (union dart_pt_io *)addr; + port < MAXPORTS; + port++, ptaddr++) { + dprintf(("dartattach: init port %c\n", 'A' + port)); + ptaddr->write.wr_mr = dart_sv_reg.sv_mr1[port]; + ptaddr->write.wr_mr = dart_sv_reg.sv_mr2[port]; + ptaddr->write.wr_csr = dart_sv_reg.sv_csr[port]; + ptaddr->write.wr_cr = dart_sv_reg.sv_cr [port]; + } + + dprintf(("dartattach: init common regs\n")); + + /* initialize common register of a DUART */ + addr->write.wr_oprset = OPDTRA | OPRTSA | OPDTRB | OPRTSB; + + addr->write.wr_ctur = SLCTIM>>8; + addr->write.wr_ctlr = SLCTIM & 0xFF; + addr->write.wr_acr = dart_sv_reg.sv_acr; + addr->write.wr_imr = dart_sv_reg.sv_imr; + addr->write.wr_opcr = OPSET; + addr->write.wr_ivr = sc->sc_vec; + + /* enable interrupts */ + sc->sc_ih.ih_fn = dartintr; + sc->sc_ih.ih_arg = sc; + sc->sc_ih.ih_ipl = ca->ca_ipl; + sc->sc_ih.ih_wantframe = 0; + + intr_establish(ca->ca_vec, &sc->sc_ih); + evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt); printf("\n"); } @@ -270,65 +275,68 @@ void dartstart(tp) struct tty *tp; { - dev_t dev; - struct dartsoftc *sc; - int s, cnt; - union dart_pt_io *ptaddr; - union dartreg *addr; - int port; - int c; - - dev = tp->t_dev; - port = DART_PORT(dev); - sc = (struct dartsoftc *) dart_cd.cd_devs[0]; - - if ((tp->t_state & TS_ISOPEN) == 0) - return; - - addr = sc->dart_reg; - ptaddr = (union dart_pt_io *)addr + port; - - if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) - goto out; - - /* - if (tp->t_outq.c_cc <= TTLOWAT(tp)) { - ttwakeup(tp); - } - */ - - if (tp->t_outq.c_cc != 0) { - - tp->t_state |= TS_BUSY; - - /* load transmitter until it is full */ - while (ptaddr->read.rd_sr & TXRDY) { - c = getc(&tp->t_outq); - - if (tp->t_flags & CS8 || c <= 0177) { - - dprintf(("dartstart: writing char \"%c\" (0x%02x)\n", - c & 0xff, c % 0xff)); - ptaddr->write.wr_tb = c & 0xff; - - dprintf(("dartstart: enabling Tx int\n")); - if (port == A_PORT) - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | ITXRDYA; - else - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | ITXRDYB; - addr -> write.wr_imr = dart_sv_reg.sv_imr; - } else { - tp->t_state &= ~TS_BUSY; - dprintf(("dartxint: timing out char \"%c\" (0x%02x)\n", - c & 0xff, c % 0xff)); - ttrstrt(tp); - tp->t_state |= TS_TIMEOUT; - } - } - } - - out: - return; + dev_t dev; + struct dartsoftc *sc; + int s, cnt; + union dart_pt_io *ptaddr; + union dartreg *addr; + int port; + int c; + + dev = tp->t_dev; + port = DART_PORT(dev); + sc = (struct dartsoftc *) dart_cd.cd_devs[0]; + + if ((tp->t_state & TS_ISOPEN) == 0) + return; + + addr = sc->dart_reg; + ptaddr = (union dart_pt_io *)addr + port; + + if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) + goto out; + + /* + if (tp->t_outq.c_cc <= TTLOWAT(tp)) { + ttwakeup(tp); + } + */ + + if (tp->t_outq.c_cc != 0) { + + tp->t_state |= TS_BUSY; + + /* load transmitter until it is full */ + while (ptaddr->read.rd_sr & TXRDY) { + c = getc(&tp->t_outq); + + if (tp->t_flags & CS8 || c <= 0177) { + + dprintf(("dartstart: writing char \"%c\" (0x%02x)\n", + c & 0xff, c % 0xff)); + ptaddr->write.wr_tb = c & 0xff; + + dprintf(("dartstart: enabling Tx int\n")); + if (port == A_PORT) + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | ITXRDYA; + else + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | ITXRDYB; + addr -> write.wr_imr = dart_sv_reg.sv_imr; + } else { + tp->t_state &= ~TS_BUSY; + dprintf(("dartxint: timing out char \"%c\" (0x%02x)\n", + c & 0xff, c % 0xff)); +#if 1 + timeout_add(&tp->t_rstrt_to, 1); +#else + ttrstrt(tp); +#endif + tp->t_state |= TS_TIMEOUT; + } + } + } +out: + return; } /* @@ -339,13 +347,13 @@ dartstop(tp, flag) struct tty *tp; int flag; { - int s; + int s; - if (tp->t_state & TS_BUSY) { - if ((tp->t_state & TS_TTSTOP) == 0) - tp->t_state |= TS_FLUSH; - } - return 0; + if (tp->t_state & TS_BUSY) { + if ((tp->t_state & TS_TTSTOP) == 0) + tp->t_state |= TS_FLUSH; + } + return 0; } #define HANDLE_FLAG(_FLAG_, _PORT_, _AFLAG_, _BFLAG_) \ @@ -373,108 +381,111 @@ dev_t dev; int flags; int how; { - union dartreg *addr; - int port; - unsigned int dcdstate; - int newflags = 0; - struct dart_info *dart; - struct dartsoftc *sc; - - if (port = DART_PORT(dev) > 1) { - return (ENODEV); - } - sc = (struct dartsoftc *) dart_cd.cd_devs[0]; - dart = &sc->sc_dart[port]; - addr = sc->dart_reg; - - /* special case: set or clear break */ - if (flags & TIOCSBRK) { - dartbreak(port, 1); - flags &= ~TIOCSBRK; - } - if (flags & TIOCCBRK) { - dartbreak(port, 0); - flags &= ~TIOCCBRK; - } - - HANDLE_FLAG(TIOCM_DTR, port, OPDTRA, OPDTRB); - HANDLE_FLAG(TIOCM_RTS, port, OPRTSA, OPRTSB); + union dartreg *addr; + int port; + unsigned int dcdstate; + int newflags = 0; + struct dart_info *dart; + struct dartsoftc *sc; + + if (port = DART_PORT(dev) > 1) { + return (ENODEV); + } + sc = (struct dartsoftc *) dart_cd.cd_devs[0]; + dart = &sc->sc_dart[port]; + addr = sc->dart_reg; + + /* special case: set or clear break */ + if (flags & TIOCSBRK) { + dartbreak(port, 1); + flags &= ~TIOCSBRK; + } + if (flags & TIOCCBRK) { + dartbreak(port, 0); + flags &= ~TIOCCBRK; + } + + HANDLE_FLAG(TIOCM_DTR, port, OPDTRA, OPDTRB); + HANDLE_FLAG(TIOCM_RTS, port, OPRTSA, OPRTSB); #if 0 - if (flags) { - printf("dartmctl: currently only BRK, DTR and RTS supported\n"); - printf("dartmctl: op=%s flags left = 0x%b\n", - HOW2STR(how), flags, FLAGSTRING); - panic("dartmctl"); - } + if (flags) { + printf("dartmctl: currently only BRK, DTR and RTS supported\n"); + printf("dartmctl: op=%s flags left = 0x%b\n", + HOW2STR(how), flags, FLAGSTRING); + panic("dartmctl"); + } #endif - dprintf(("dartmctl: action=%s flags=0x%x\n", - HOW2STR(how), newflags)); - - switch (how) { - case DMSET: - addr->write.wr_oprset = newflags; - addr->write.wr_oprreset = ~newflags; - break; - case DMBIS: - addr->write.wr_oprset = newflags; - break; - case DMBIC: - addr->write.wr_oprreset = newflags; - break; - case DMGET: - panic("dartmctl: DMGET not supported (yet)\n"); - break; - } - - /* read DCD input */ - /* input is inverted at port */ - dcdstate = !(addr->read.rd_ip & ((port == A_PORT) ? IPDCDA : IPDCDB)); - - dprintf(("dartmctl: DCD is %s\n", dcdstate ? "up" : "down")); - - return dcdstate; + dprintf(("dartmctl: action=%s flags=0x%x\n", + HOW2STR(how), newflags)); + + switch (how) { + case DMSET: + addr->write.wr_oprset = newflags; + addr->write.wr_oprreset = ~newflags; + break; + case DMBIS: + addr->write.wr_oprset = newflags; + break; + case DMBIC: + addr->write.wr_oprreset = newflags; + break; + case DMGET: + panic("dartmctl: DMGET not supported (yet)\n"); + break; + } + + /* read DCD input */ + /* input is inverted at port */ + dcdstate = !(addr->read.rd_ip & ((port == A_PORT) ? IPDCDA : IPDCDB)); + + dprintf(("dartmctl: DCD is %s\n", dcdstate ? "up" : "down")); + + return dcdstate; } /* * To be called at spltty - tty already locked. */ void -dartbreak(dev_t dev, int state) +dartbreak(dev, state) +dev_t dev; +int state; { - union dartreg *addr; - union dart_pt_io *ptaddr; - int port; - struct dart_info *dart; - struct dartsoftc *sc; - - dprintf(("dartbreak: break %s\n", (state == 1) ? "on" : "off")); - - port = DART_PORT(dev); - sc = (struct dartsoftc *) dart_cd.cd_devs[0]; - dart = &sc->sc_dart[port]; - addr = sc->dart_reg; - - ptaddr = (union dart_pt_io *) addr + port; - - if (state == 1) { - /* the duart must be enabled with a dummy byte, - to prevent the transmitter empty interrupt */ - ptaddr->write.wr_cr = BRKSTART|TXEN; - ptaddr->write.wr_tb = 0; - } else { - ptaddr->write.wr_cr = BRKSTOP; /* stop a break*/ - } - - return; + union dartreg *addr; + union dart_pt_io *ptaddr; + int port; + struct dart_info *dart; + struct dartsoftc *sc; + + dprintf(("dartbreak: break %s\n", (state == 1) ? "on" : "off")); + + port = DART_PORT(dev); + sc = (struct dartsoftc *) dart_cd.cd_devs[0]; + dart = &sc->sc_dart[port]; + addr = sc->dart_reg; + + ptaddr = (union dart_pt_io *) addr + port; + + if (state == 1) { + /* the duart must be enabled with a dummy byte, + to prevent the transmitter empty interrupt */ + ptaddr->write.wr_cr = BRKSTART|TXEN; + ptaddr->write.wr_tb = 0; + } else { + ptaddr->write.wr_cr = BRKSTOP; /* stop a break*/ + } + + return; } -int dartioctl (dev, cmd, data, flag, p) - dev_t dev; - int cmd; - caddr_t data; - int flag; - struct proc *p; +int +dartioctl (dev, cmd, data, flag, p) +dev_t dev; +int cmd; +caddr_t data; +int flag; +struct proc *p; { int error; int port; @@ -555,304 +566,308 @@ dartparam(tp, t) struct tty *tp; struct termios *t; { - union dartreg *addr; - union dart_pt_io *ptaddr; - int flags; - int port; - int speeds; - unsigned char mr1, mr2; - struct dart_info *dart; - struct dartsoftc *sc; - dev_t dev; - - dprintf(("dartparam: setting param for dev %d\n", dev)); - - dev = tp->t_dev; - if (port = DART_PORT(dev) > 1) { - return (ENODEV); - } - - sc = (struct dartsoftc *) dart_cd.cd_devs[0]; - dart = &sc->sc_dart[port]; - addr = sc->dart_reg; - ptaddr = (union dart_pt_io *) addr + port; - tp->t_ispeed = t->c_ispeed; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = t->c_cflag; - - flags = tp->t_flags; - - /* Reset to make global changes*/ - /* disable Tx and Rx */ - dprintf(("dartparam: disabling Tx and Rx int\n")); - - if (port == A_PORT) - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr & ~(ITXRDYA | IRXRDYA); - else - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr & ~(ITXRDYB | IRXRDYB); - addr -> write.wr_imr = dart_sv_reg.sv_imr; - - /* hang up on zero baud rate */ - if (tp->t_ispeed == 0) { - dprintf(("dartparam: ispeed == 0 -> HUP\n")); - dartmctl(tp, HUPCL, DMSET); - return; - } else { - /* set baudrate */ - speeds = dart_speeds[(unsigned char)tp->t_ispeed]; - if (speeds == NOBAUD) - speeds = dart_sv_reg.sv_csr[port]; - ptaddr->write.wr_csr = speeds; - dart_sv_reg.sv_csr[port] = speeds; - dprintf(("dartparam: baudrate set param = %d\n", speeds)); - } - - /* get saved mode registers and clear set up parameters */ - mr1 = dart_sv_reg.sv_mr1[port]; - mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK); - - mr2 = dart_sv_reg.sv_mr2[port]; - mr2 &= ~SBMASK; - - /* set up character size */ - if (flags & CS8) { - mr1 |= CL8; - dprintf(("dartparam: PASS8\n")); - } else if (tp->t_ispeed == B134) { - mr1 |= CL6; - dprintf(("dartparam: CS6\n")); - } else { - mr1 |= CL7; - dprintf(("dartparam: CS7\n")); - } - - /* set up stop bits */ - if (tp->t_ospeed == B110) { - mr2 |= SB2; - dprintf(("dartparam: two stop bits\n")); - } else { - mr2 |= SB1; - dprintf(("dartparam: one stop bit\n")); - } - - /* set up parity */ - if (((flags & PARENB) != PARENB) && - (flags & PARENB)) { - mr1 |= PAREN; - if (flags & PARODD) { - mr1 |= ODDPAR; - dprintf(("dartparam: odd parity\n")); - } else { - mr1 |= EVENPAR; - dprintf(("dartparam: even parity\n")); - } - } else { - mr1 |= PARDIS; - dprintf(("dartparam: no parity\n")); - } - - if ((dart_sv_reg.sv_mr1[port] != mr1) - || (dart_sv_reg.sv_mr2[port] != mr2)) { - /* write mode registers to duart */ - ptaddr->write.wr_cr = MRRESET; - ptaddr->write.wr_mr = mr1; - ptaddr->write.wr_mr = mr2; - - /* save changed mode registers */ - dart_sv_reg.sv_mr1[port] = mr1; - dart_sv_reg.sv_mr2[port] = mr2; - } - - /* enable transmitter? */ - if (tp->t_state & TS_BUSY) { - dprintf(("dartparam: reenabling Tx int\n")); - - if (port == A_PORT) - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | ITXRDYA; - else - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | ITXRDYB; - addr -> write.wr_imr = dart_sv_reg.sv_imr; - } else { - dprintf(("dartparam: not enabling Tx\n")); - } - - /* re-enable the receiver */ - dprintf(("dartparam: reenabling Rx int\n")); - - DELAY_CR; - if (port == A_PORT) - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | IRXRDYA; - else - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | IRXRDYB; - addr -> write.wr_imr = dart_sv_reg.sv_imr; - - return 0; + union dartreg *addr; + union dart_pt_io *ptaddr; + int flags; + int port; + int speeds; + unsigned char mr1, mr2; + struct dart_info *dart; + struct dartsoftc *sc; + dev_t dev; + + dprintf(("dartparam: setting param for dev %d\n", dev)); + + dev = tp->t_dev; + if (port = DART_PORT(dev) > 1) { + return (ENODEV); + } + + sc = (struct dartsoftc *) dart_cd.cd_devs[0]; + dart = &sc->sc_dart[port]; + addr = sc->dart_reg; + ptaddr = (union dart_pt_io *) addr + port; + tp->t_ispeed = t->c_ispeed; + tp->t_ospeed = t->c_ospeed; + tp->t_cflag = t->c_cflag; + + flags = tp->t_flags; + + /* Reset to make global changes*/ + /* disable Tx and Rx */ + dprintf(("dartparam: disabling Tx and Rx int\n")); + + if (port == A_PORT) + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr & ~(ITXRDYA | IRXRDYA); + else + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr & ~(ITXRDYB | IRXRDYB); + addr -> write.wr_imr = dart_sv_reg.sv_imr; + + /* hang up on zero baud rate */ + if (tp->t_ispeed == 0) { + dprintf(("dartparam: ispeed == 0 -> HUP\n")); + dartmctl(tp, HUPCL, DMSET); + return; + } else { + /* set baudrate */ + speeds = dart_speeds[(unsigned char)tp->t_ispeed]; + if (speeds == NOBAUD) + speeds = dart_sv_reg.sv_csr[port]; + ptaddr->write.wr_csr = speeds; + dart_sv_reg.sv_csr[port] = speeds; + dprintf(("dartparam: baudrate set param = %d\n", speeds)); + } + + /* get saved mode registers and clear set up parameters */ + mr1 = dart_sv_reg.sv_mr1[port]; + mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK); + + mr2 = dart_sv_reg.sv_mr2[port]; + mr2 &= ~SBMASK; + + /* set up character size */ + if (flags & CS8) { + mr1 |= CL8; + dprintf(("dartparam: PASS8\n")); + } else if (tp->t_ispeed == B134) { + mr1 |= CL6; + dprintf(("dartparam: CS6\n")); + } else { + mr1 |= CL7; + dprintf(("dartparam: CS7\n")); + } + + /* set up stop bits */ + if (tp->t_ospeed == B110) { + mr2 |= SB2; + dprintf(("dartparam: two stop bits\n")); + } else { + mr2 |= SB1; + dprintf(("dartparam: one stop bit\n")); + } + + /* set up parity */ + if (((flags & PARENB) != PARENB) && + (flags & PARENB)) { + mr1 |= PAREN; + if (flags & PARODD) { + mr1 |= ODDPAR; + dprintf(("dartparam: odd parity\n")); + } else { + mr1 |= EVENPAR; + dprintf(("dartparam: even parity\n")); + } + } else { + mr1 |= PARDIS; + dprintf(("dartparam: no parity\n")); + } + + if ((dart_sv_reg.sv_mr1[port] != mr1) + || (dart_sv_reg.sv_mr2[port] != mr2)) { + /* write mode registers to duart */ + ptaddr->write.wr_cr = MRRESET; + ptaddr->write.wr_mr = mr1; + ptaddr->write.wr_mr = mr2; + + /* save changed mode registers */ + dart_sv_reg.sv_mr1[port] = mr1; + dart_sv_reg.sv_mr2[port] = mr2; + } + + /* enable transmitter? */ + if (tp->t_state & TS_BUSY) { + dprintf(("dartparam: reenabling Tx int\n")); + + if (port == A_PORT) + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | ITXRDYA; + else + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | ITXRDYB; + addr -> write.wr_imr = dart_sv_reg.sv_imr; + } else { + dprintf(("dartparam: not enabling Tx\n")); + } + + /* re-enable the receiver */ + dprintf(("dartparam: reenabling Rx int\n")); + + DELAY_CR; + if (port == A_PORT) + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | IRXRDYA; + else + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr | IRXRDYB; + addr -> write.wr_imr = dart_sv_reg.sv_imr; + + return 0; } void dartmodemtrans(sc, ip, ipcr) - struct dartsoftc *sc; - unsigned int ip; - unsigned int ipcr; +struct dartsoftc *sc; +unsigned int ip; +unsigned int ipcr; { - unsigned int dcdstate; - struct tty *tp; - int port; - struct dart_info *dart; - - dprintf(("dartmodemtrans: ip=0x%x ipcr=0x%x\n", - ip, ipcr)); - - /* input is inverted at port!!! */ - if (ipcr & IPCRDCDA) { - port = A_PORT; - dcdstate = !(ip & IPDCDA); - } else if (ipcr & IPCRDCDB) { - port = B_PORT; - dcdstate = !(ip & IPDCDB); - } else { - printf("dartmodemtrans: unknown transition:\n"); - printf("dartmodemtrans: ip=0x%x ipcr=0x%x\n", - ip, ipcr); - panic("dartmodemtrans"); - } - dart = &sc->sc_dart[port]; - tp = dart->tty; - - dprintf(("dartmodemtrans: tp=0x%x new DCD state: %s\n", - tp, dcdstate ? "UP" : "DOWN")); - (void) ttymodem(tp, dcdstate); + unsigned int dcdstate; + struct tty *tp; + int port; + struct dart_info *dart; + + dprintf(("dartmodemtrans: ip=0x%x ipcr=0x%x\n", + ip, ipcr)); + + /* input is inverted at port!!! */ + if (ipcr & IPCRDCDA) { + port = A_PORT; + dcdstate = !(ip & IPDCDA); + } else if (ipcr & IPCRDCDB) { + port = B_PORT; + dcdstate = !(ip & IPDCDB); + } else { + printf("dartmodemtrans: unknown transition:\n"); + printf("dartmodemtrans: ip=0x%x ipcr=0x%x\n", + ip, ipcr); + panic("dartmodemtrans"); + } + dart = &sc->sc_dart[port]; + tp = dart->tty; + + dprintf(("dartmodemtrans: tp=0x%x new DCD state: %s\n", + tp, dcdstate ? "UP" : "DOWN")); + (void) ttymodem(tp, dcdstate); } -int dartopen (dev, flag, mode, p) +int +dartopen (dev, flag, mode, p) dev_t dev; int flag; int mode; struct proc *p; { - int s, port; - struct dart_info *dart; - struct dartsoftc *sc; - struct tty *tp; - - if (port = DART_PORT(dev) > 1) { - return (ENODEV); - } - sc = (struct dartsoftc *) dart_cd.cd_devs[0]; - dart = &sc->sc_dart[port]; - s = spldart(); - - if (dart->tty) { - tp = dart->tty; - } else { - tp = dart->tty = ttymalloc(); - simple_lock_init(&dart->t_lock); - } - - simple_lock(&dart->t_lock); - tp->t_oproc = dartstart; - tp->t_param = dartparam; - tp->t_dev = dev; - - if ((tp->t_state & TS_ISOPEN) == 0) { - ttychars(tp); - tp->t_iflag = TTYDEF_IFLAG; - tp->t_oflag = TTYDEF_OFLAG; - tp->t_lflag = TTYDEF_LFLAG; - tp->t_ispeed = tp->t_ospeed = B9600; - dartparam(tp, &tp->t_termios); - if (port == 0) { - /* console is 8N1 */ - tp->t_cflag = (CREAD | CS8 | HUPCL); - } else { - tp->t_cflag = TTYDEF_CFLAG; - } - ttsetwater(tp); - (void)dartmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET); - tp->t_state |= TS_CARR_ON; - } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { - splx(s); - simple_unlock(&dart->t_lock); - return (EBUSY); - } - /* - * Reset the tty pointer, as there could have been a dialout - * use of the tty with a dialin open waiting. - */ - tp->t_dev = dev; - simple_unlock(&dart->t_lock); - splx(s); - return ((*linesw[tp->t_line].l_open)(dev, tp)); + int s, port; + struct dart_info *dart; + struct dartsoftc *sc; + struct tty *tp; + + if (port = DART_PORT(dev) > 1) { + return (ENODEV); + } + sc = (struct dartsoftc *) dart_cd.cd_devs[0]; + dart = &sc->sc_dart[port]; + s = spldart(); + + if (dart->tty) { + tp = dart->tty; + } else { + tp = dart->tty = ttymalloc(); + simple_lock_init(&dart->t_lock); + } + + simple_lock(&dart->t_lock); + tp->t_oproc = dartstart; + tp->t_param = dartparam; + tp->t_dev = dev; + + if ((tp->t_state & TS_ISOPEN) == 0) { + ttychars(tp); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = B9600; + dartparam(tp, &tp->t_termios); + if (port == 0) { + /* console is 8N1 */ + tp->t_cflag = (CREAD | CS8 | HUPCL); + } else { + tp->t_cflag = TTYDEF_CFLAG; + } + ttsetwater(tp); + (void)dartmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET); + tp->t_state |= TS_CARR_ON; + } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { + splx(s); + simple_unlock(&dart->t_lock); + return (EBUSY); + } + /* + * Reset the tty pointer, as there could have been a dialout + * use of the tty with a dialin open waiting. + */ + tp->t_dev = dev; + simple_unlock(&dart->t_lock); + splx(s); + return ((*linesw[tp->t_line].l_open)(dev, tp)); } -int dartclose (dev, flag, mode, p) +int +dartclose (dev, flag, mode, p) dev_t dev; int flag; int mode; struct proc *p; { - int unit, channel; - struct tty *tp; - struct dart_info *dart; - struct dartsoftc *sc; - int s, port; - - if (port = DART_PORT(dev) > 1) { - return (ENODEV); - } - sc = (struct dartsoftc *) dart_cd.cd_devs[0]; - dart = &sc->sc_dart[port]; - tp = dart->tty; - (*linesw[tp->t_line].l_close)(tp, flag); - - s = spldart(); - ttyclose(tp); - splx(s); - return 0; + int unit, channel; + struct tty *tp; + struct dart_info *dart; + struct dartsoftc *sc; + int s, port; + + if (port = DART_PORT(dev) > 1) { + return (ENODEV); + } + sc = (struct dartsoftc *) dart_cd.cd_devs[0]; + dart = &sc->sc_dart[port]; + tp = dart->tty; + (*linesw[tp->t_line].l_close)(tp, flag); + + s = spldart(); + ttyclose(tp); + splx(s); + return 0; } -int dartread (dev, uio, flag) +int +dartread (dev, uio, flag) dev_t dev; struct uio *uio; int flag; { - int unit, port; - struct tty *tp; - struct dart_info *dart; - struct dartsoftc *sc; - - if (port = DART_PORT(dev) > 1) { - return (ENODEV); - } - sc = (struct dartsoftc *) dart_cd.cd_devs[0]; - dart = &sc->sc_dart[port]; - tp = dart->tty; - - if (!tp) - return ENXIO; - return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); + int unit, port; + struct tty *tp; + struct dart_info *dart; + struct dartsoftc *sc; + + if (port = DART_PORT(dev) > 1) { + return (ENODEV); + } + sc = (struct dartsoftc *) dart_cd.cd_devs[0]; + dart = &sc->sc_dart[port]; + tp = dart->tty; + + if (!tp) + return ENXIO; + return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); } -int dartwrite (dev, uio, flag) +int +dartwrite(dev, uio, flag) dev_t dev; struct uio *uio; int flag; { - int port; - struct tty *tp; - struct dart_info *dart; - struct dartsoftc *sc; - - if (port = DART_PORT(dev) > 1) { - return (ENODEV); - } - sc = (struct dartsoftc *)dart_cd.cd_devs[0]; - dart = &sc->sc_dart[port]; - - tp = dart->tty; - if (!tp) - return ENXIO; - return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); + int port; + struct tty *tp; + struct dart_info *dart; + struct dartsoftc *sc; + + if (port = DART_PORT(dev) > 1) { + return (ENODEV); + } + sc = (struct dartsoftc *)dart_cd.cd_devs[0]; + dart = &sc->sc_dart[port]; + + tp = dart->tty; + if (!tp) + return ENXIO; + return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); } void @@ -860,88 +875,88 @@ dartrint(sc, port) struct dartsoftc *sc; int port; { - union dartreg *addr; - union dart_pt_io *ptaddr; - struct tty *tp; - unsigned char data, sr; - struct dart_info *dart; - - dart = &sc->sc_dart[port]; - addr = sc->dart_reg; - - /* read status reg */ - ptaddr = (union dart_pt_io *) addr + port; - - dprintf(("dartrint: Rx int dev %d\n", dev)); - - tp = dart->tty; - - dprintf(("dartrint: ptaddr = 0x%08x from uart at 0x%08x\n", - ptaddr, addr)); - - while ((sr = ptaddr->read.rd_sr) & RXRDY) { - dprintf(("dartrint: sr = 0x%08x\n", sr)); + union dartreg *addr; + union dart_pt_io *ptaddr; + struct tty *tp; + unsigned char data, sr; + struct dart_info *dart; - data = ptaddr->read.rd_rb; /* read data and reset receiver */ + dart = &sc->sc_dart[port]; + addr = sc->dart_reg; - dprintf(("dartrint: read char \"%c\" (0x%02x) tp = 0x%x\n", - data, data, tp)); + /* read status reg */ + ptaddr = (union dart_pt_io *) addr + port; - if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0){ - return; - } + dprintf(("dartrint: Rx int port %d\n", port)); - if (sr & RBRK) { - dprintf(("dartrint: BREAK detected\n")); - /* - data = tp->t_breakc; - ttyinput(data, tp); - */ - /* clear break state */ - ptaddr->write.wr_cr = BRKINTRESET; - DELAY_CR; - ptaddr->write.wr_cr = ERRRESET; + tp = dart->tty; -#if DDB_XXX - if (ddb_break_mode & DDB_ENTER_BREAK) { - dprintf(("dartrint: break detected - entering debugger\n")); - gimmeabreak(); - } + dprintf(("dartrint: ptaddr = 0x%08x from uart at 0x%08x\n", + ptaddr, addr)); + + while ((sr = ptaddr->read.rd_sr) & RXRDY) { + dprintf(("dartrint: sr = 0x%08x\n", sr)); + + data = ptaddr->read.rd_rb; /* read data and reset receiver */ + + dprintf(("dartrint: read char \"%c\" (0x%02x) tp = 0x%x\n", + data, data, tp)); + + if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0) { + return; + } + + if (sr & RBRK) { + dprintf(("dartrint: BREAK detected\n")); + /* + data = tp->t_breakc; + ttyinput(data, tp); + */ + /* clear break state */ + ptaddr->write.wr_cr = BRKINTRESET; + DELAY_CR; + ptaddr->write.wr_cr = ERRRESET; + +#if defined(DDB) + if (ddb_break_mode & DDB_ENTER_BREAK) { + dprintf(("dartrint: break detected - entering debugger\n")); + gimmeabreak(); + } #endif - } else { - if (sr & (FRERR|PERR|ROVRN)) { /* errors */ - if (sr & ROVRN) - printf("dart0: receiver overrun port %c\n", 'A' + port); - if (sr & FRERR) - printf("dart0: framing error port %c\n", 'A' + port); - if (sr & PERR) - printf("dart0: parity error port %c\n", 'A' + port); - dprintf(("dartrint: error received\n")); - /* clear error state */ - ptaddr->write.wr_cr = ERRRESET; - } else { - /* no errors */ -#if DDB_XXX - if ((ddb_break_mode & DDB_ENTER_CHAR) && (ddb_break_char == data)) { - dprintf(("dartrint: ddb_break_char detected - entering debugger\n")); - gimmeabreak(); - } else + } else { + if (sr & (FRERR|PERR|ROVRN)) { /* errors */ + if (sr & ROVRN) + printf("dart0: receiver overrun port %c\n", 'A' + port); + if (sr & FRERR) + printf("dart0: framing error port %c\n", 'A' + port); + if (sr & PERR) + printf("dart0: parity error port %c\n", 'A' + port); + dprintf(("dartrint: error received\n")); + /* clear error state */ + ptaddr->write.wr_cr = ERRRESET; + } else { + /* no errors */ +#if defined(DDB) + if ((ddb_break_mode & DDB_ENTER_CHAR) && (ddb_break_char == data)) { + dprintf(("dartrint: ddb_break_char detected - entering debugger\n")); + gimmeabreak(); + } else #endif - { - if (tp->t_ispeed == B134) /* CS6 */ - data &= 077; + { + if (tp->t_ispeed == B134) /* CS6 */ + data &= 077; #if 0 /* XXX ??? */ - else if (tp->t_flags & (RAW|LITOUT|PASS8)) /*CS8*/ - ; + else if (tp->t_flags & (RAW|LITOUT|PASS8)) /*CS8*/ + ; #endif - else - data &= 0177; /* CS7 */ - ttyinput(data, tp); - } - } - } - } - dprintf(("dartrint: ready\n")); + else + data &= 0177; /* CS7 */ + ttyinput(data, tp); + } + } + } + } + dprintf(("dartrint: ready\n")); } void @@ -949,106 +964,106 @@ dartxint(sc, port) struct dartsoftc *sc; int port; { - struct tty *tp; - struct dart_info *dart; - union dartreg *addr; - dev_t dev; + struct tty *tp; + struct dart_info *dart; + union dartreg *addr; + dev_t dev; - dart = &sc->sc_dart[port]; - addr = sc->dart_reg; + dart = &sc->sc_dart[port]; + addr = sc->dart_reg; - tp = dart->tty; + tp = dart->tty; - simple_lock(&dart->t_lock); + simple_lock(&dart->t_lock); - if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0) - goto out; + if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0) + goto out; - if (tp->t_state & TS_FLUSH) - tp->t_state &= ~TS_FLUSH; + if (tp->t_state & TS_FLUSH) + tp->t_state &= ~TS_FLUSH; - if (tp->t_state & TS_BUSY) { - tp->t_state &= ~TS_BUSY; - dprintf(("dartxint: starting output\n")); - dartstart(tp); - if (tp->t_state & TS_BUSY) { - dprintf(("dartxint: ready - Tx left enabled\n")); - simple_unlock(&dart->t_lock); - return; - } - } - out: + if (tp->t_state & TS_BUSY) { + tp->t_state &= ~TS_BUSY; + dprintf(("dartxint: starting output\n")); + dartstart(tp); + if (tp->t_state & TS_BUSY) { + dprintf(("dartxint: ready - Tx left enabled\n")); + simple_unlock(&dart->t_lock); + return; + } + } + out: - /* disable transmitter */ - if (port == 0) - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr & ~ITXRDYA; - else - dart_sv_reg.sv_imr = dart_sv_reg.sv_imr & ~ITXRDYB; + /* disable transmitter */ + if (port == 0) + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr & ~ITXRDYA; + else + dart_sv_reg.sv_imr = dart_sv_reg.sv_imr & ~ITXRDYB; - addr->write.wr_imr = dart_sv_reg.sv_imr; + addr->write.wr_imr = dart_sv_reg.sv_imr; - simple_unlock(&dart->t_lock); + simple_unlock(&dart->t_lock); - dprintf(("dartxint: ready - Tx disabled\n")); + dprintf(("dartxint: ready - Tx disabled\n")); - return; + return; } int dartintr(sc) struct dartsoftc *sc; { - unsigned char isr; - unsigned char sr; - int port; - union dartreg *addr; - - /* read interrupt status register and mask with imr */ - addr = sc->dart_reg; - - isr = addr->read.rd_isr; - isr &= dart_sv_reg.sv_imr; - - if (isr) { /* interrupt from this duart */ - if (isr & IIPCHG) { - unsigned int ip = addr->read.rd_ip; - unsigned int ipcr = addr->read.rd_ipcr; - dartmodemtrans(sc, ip, ipcr); - return 0; - } - - if (isr & (IRXRDYA | ITXRDYA)) - port = 0; - else - if (isr & (IRXRDYB | ITXRDYB)) - port = 1; - else { - printf("dartintr: spurious interrupt, isr 0x%08x\n", isr); - panic("dartintr"); - } - - dprintf(("dartintr: interrupt from port %d, isr 0x%08x\n", - port, isr)); - - if (isr & (IRXRDYA | IRXRDYB)) { - dprintf(("dartintr: Rx interrupt\n")); - dartrint(sc, port); - } - if (isr & (ITXRDYA | ITXRDYB)) { - dprintf(("dartintr: Tx interrupt\n")); - dartxint(sc, port); - } - if (((port == A_PORT) && (isr & IBRKA)) - || ((port == B_PORT) && (isr & IBRKB))) { - union dart_pt_io *ptaddr = - (union dart_pt_io *)addr + port; - - dprintf(("dartintr: clearing end of BREAK state\n")); - ptaddr->write.wr_cr = BRKINTRESET; - } - } - dprintf(("dartintr: ready\n")); - return 1; + unsigned char isr; + unsigned char sr; + int port; + union dartreg *addr; + + /* read interrupt status register and mask with imr */ + addr = sc->dart_reg; + + isr = addr->read.rd_isr; + isr &= dart_sv_reg.sv_imr; + + if (isr) { /* interrupt from this duart */ + if (isr & IIPCHG) { + unsigned int ip = addr->read.rd_ip; + unsigned int ipcr = addr->read.rd_ipcr; + dartmodemtrans(sc, ip, ipcr); + return 0; + } + + if (isr & (IRXRDYA | ITXRDYA)) + port = 0; + else + if (isr & (IRXRDYB | ITXRDYB)) + port = 1; + else { + printf("dartintr: spurious interrupt, isr 0x%08x\n", isr); + panic("dartintr"); + } + + dprintf(("dartintr: interrupt from port %d, isr 0x%08x\n", + port, isr)); + + if (isr & (IRXRDYA | IRXRDYB)) { + dprintf(("dartintr: Rx interrupt\n")); + dartrint(sc, port); + } + if (isr & (ITXRDYA | ITXRDYB)) { + dprintf(("dartintr: Tx interrupt\n")); + dartxint(sc, port); + } + if (((port == A_PORT) && (isr & IBRKA)) + || ((port == B_PORT) && (isr & IBRKB))) { + union dart_pt_io *ptaddr = + (union dart_pt_io *)addr + port; + + dprintf(("dartintr: clearing end of BREAK state\n")); + ptaddr->write.wr_cr = BRKINTRESET; + } + } + dprintf(("dartintr: ready\n")); + return 1; } /* @@ -1060,27 +1075,27 @@ int dartcnprobe(cp) struct consdev *cp; { - int maj; - - if (cputyp != CPU_188){ - cp->cn_pri = CN_DEAD; - return 0; - } - /* locate the major number */ - for (maj = 0; maj < nchrdev; maj++) - if (cdevsw[maj].d_open == dartopen) - break; - - cp->cn_dev = makedev(maj, 0); - cp->cn_pri = CN_NORMAL; - return (1); + int maj; + + if (cputyp != CPU_188) { + cp->cn_pri = CN_DEAD; + return 0; + } + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == dartopen) + break; + + cp->cn_dev = makedev(maj, 0); + cp->cn_pri = CN_NORMAL; + return (1); } int dartcninit(cp) struct consdev *cp; { - /* Nothing to do */ + /* Nothing to do */ } int @@ -1088,103 +1103,136 @@ dartcnputc(dev, c) dev_t dev; char c; { - union dartreg *addr; - union dart_pt_io *ptaddr; - m88k_psr_type psr; - - addr = (union dartreg *) MVME188_DUART; - - ptaddr = (union dart_pt_io *) addr + ((dev & 1) ? 1 : 0); + union dartreg *addr; + union dart_pt_io *ptaddr; + m88k_psr_type psr; + int s; + int port; - psr = disable_interrupts_return_psr(); + port = DART_PORT(dev); - /* Assume first port initialized if we get here. */ - /* Assume the bug initializes the port */ + addr = (union dartreg *) MVME188_DUART; - /* inhibit interrupts on the chip */ - addr->write.wr_imr = dart_sv_reg.sv_imr & ~ITXRDYA; - /* make sure transmitter is enabled */ - DELAY_CR; - ptaddr->write.wr_cr = TXEN; +#if 1 + ptaddr = (union dart_pt_io *) addr + port; +#else + ptaddr = (union dart_pt_io *) addr + ((dev & 1) ? 1 : 0); +#endif - /* If the character is a line feed(\n) */ - /* then follow it with carriage return (\r) */ - for (;;) { - while (!(ptaddr->read.rd_sr & TXRDY)) - ; - ptaddr->write.wr_tb = c; - if (c != '\n') - break; - c = '\r'; - } +#if 1 + s = spldart(); +#else + psr = disable_interrupts_return_psr(); +#endif - /* wait for transmitter to empty */ - while (!(ptaddr->read.rd_sr & TXEMT)) - ; + /* Assume first port initialized if we get here. */ + /* Assume the bug initializes the port */ + + /* inhibit interrupts on the chip */ + addr->write.wr_imr = dart_sv_reg.sv_imr & ~ITXRDYA; + /* make sure transmitter is enabled */ + DELAY_CR; + ptaddr->write.wr_cr = TXEN; + + /* If the character is a line feed(\n) */ + /* then follow it with carriage return (\r) */ + for (;;) { + while (!(ptaddr->read.rd_sr & TXRDY)) + ; + ptaddr->write.wr_tb = c; + if (c != '\n') + break; + c = '\r'; + } - /* restore the previous state */ - addr->write.wr_imr = dart_sv_reg.sv_imr; - DELAY_CR; - ptaddr->write.wr_cr = dart_sv_reg.sv_cr[0]; + /* wait for transmitter to empty */ + while (!(ptaddr->read.rd_sr & TXEMT)) + ; - set_psr(psr); + /* restore the previous state */ + addr->write.wr_imr = dart_sv_reg.sv_imr; + DELAY_CR; + ptaddr->write.wr_cr = dart_sv_reg.sv_cr[0]; - return; +#if 1 + splx(s); +#else + set_psr(psr); +#endif + return; } int dartcngetc(dev) dev_t dev; { - union dartreg *addr; /* pointer to DUART regs */ - union dart_pt_io *ptaddr; /* pointer to port regs */ - unsigned char sr; /* status reg of port a/b */ - int c; /* received character */ - m88k_psr_type psr; - char buf[] = "char x"; - - psr = disable_interrupts_return_psr(); - - addr = (union dartreg *) DART_BASE; - ptaddr = (union dart_pt_io *) addr + ((dev & 1) ? 1 : 0); - - /* enable receiver */ - ptaddr->write.wr_cr = RXEN; - - do { - /* read status reg */ - sr = ptaddr->read.rd_sr; - - /* receiver interrupt handler*/ - if (sr & RXRDY) { - /* read character from port */ - c = ptaddr->read.rd_rb; - - /* check break condition */ - if (sr & RBRK) { - /* clear break state */ - ptaddr->write.wr_cr = BRKINTRESET; - DELAY_CR; - ptaddr->write.wr_cr = ERRRESET; - set_psr(psr); - return c; - } - - if (sr & (FRERR|PERR|ROVRN)) { - /* clear error state */ - ptaddr->write.wr_cr = ERRRESET; - DELAY_CR; - ptaddr->write.wr_cr = BRKINTRESET; - } else { - buf[5] = (char) c; - - set_psr(psr); - return (c & 0x7f); - } - } - } while (-1); - - set_psr(psr); - - return -1; + union dartreg *addr; /* pointer to DUART regs */ + union dart_pt_io *ptaddr; /* pointer to port regs */ + unsigned char sr; /* status reg of port a/b */ + int c; /* received character */ + int s; + int port; + m88k_psr_type psr; + char buf[] = "char x"; + + port = DART_PORT(dev); +#if 1 + s = spldart(); +#else + psr = disable_interrupts_return_psr(); +#endif + addr = (union dartreg *) DART_BASE; +#if 1 + ptaddr = (union dart_pt_io *) addr + port; +#else + ptaddr = (union dart_pt_io *) addr + ((dev & 1) ? 1 : 0); +#endif + /* enable receiver */ + ptaddr->write.wr_cr = RXEN; + + do { + /* read status reg */ + sr = ptaddr->read.rd_sr; + + /* receiver interrupt handler*/ + if (sr & RXRDY) { + /* read character from port */ + c = ptaddr->read.rd_rb; + + /* check break condition */ + if (sr & RBRK) { + /* clear break state */ + ptaddr->write.wr_cr = BRKINTRESET; + DELAY_CR; + ptaddr->write.wr_cr = ERRRESET; +#if 1 + splx(s); +#else + set_psr(psr); +#endif + return c; + } + + if (sr & (FRERR|PERR|ROVRN)) { + /* clear error state */ + ptaddr->write.wr_cr = ERRRESET; + DELAY_CR; + ptaddr->write.wr_cr = BRKINTRESET; + } else { + buf[5] = (char) c; +#if 1 + splx(s); +#else + set_psr(psr); +#endif + return (c & 0x7f); + } + } + } while (-1); +#if 1 + splx(s); +#else + set_psr(psr); +#endif + return -1; } diff --git a/sys/arch/mvme88k/dev/if_ve.c b/sys/arch/mvme88k/dev/if_ve.c index 502be8e6143..ec724fdb277 100644 --- a/sys/arch/mvme88k/dev/if_ve.c +++ b/sys/arch/mvme88k/dev/if_ve.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ve.c,v 1.1 1999/05/29 04:41:43 smurph Exp $ */ +/* $OpenBSD: if_ve.c,v 1.2 2001/02/01 03:38:14 smurph Exp $ */ /*- * Copyright (c) 1999 Steve Murphree, Jr. * Copyright (c) 1982, 1992, 1993 @@ -73,6 +73,7 @@ #include <machine/autoconf.h> #include <machine/cpu.h> #include <machine/bugio.h> +#include <machine/mmu.h> /* DMA_CACHE_SYNC, etc... */ #include <mvme88k/dev/if_vereg.h> #include <mvme88k/dev/if_vevar.h> @@ -109,17 +110,17 @@ hide void ve_shutdown __P((void *)); * This structure contains the output queue for the interface, its address, ... */ struct ve_softc { - struct vam7990_softc sc_am7990; /* glue to MI code */ - struct intrhand sc_ih; /* interrupt vectoring */ - struct vereg1 *sc_r1; /* LANCE registers */ - u_short csr; /* Control/Status reg image */ - u_long board_addr; - struct evcnt sc_intrcnt; - struct evcnt sc_errcnt; - struct vme2reg *sc_vme2; - u_char sc_ipl; - u_char sc_vec; - int sc_flags; + struct vam7990_softc sc_am7990; /* glue to MI code */ + struct intrhand sc_ih; /* interrupt vectoring */ + struct vereg1 *sc_r1; /* LANCE registers */ + u_short csr; /* Control/Status reg image */ + u_long board_addr; + struct evcnt sc_intrcnt; + struct evcnt sc_errcnt; + struct vme2reg *sc_vme2; + u_char sc_ipl; + u_char sc_vec; + int sc_flags; }; struct cfdriver ve_cd = { @@ -232,7 +233,7 @@ ve_ackint(sc) struct vam7990_softc *sc; { register struct vereg1 *reg1 = ((struct ve_softc *)sc)->sc_r1; - ENABLE_INTR; + ENABLE_INTR; } int @@ -326,7 +327,7 @@ veattach(parent, self, aux) sc->sc_wrcsr = vewrcsr; sc->sc_hwreset = vereset; sc->sc_hwinit = NULL; - vereset(sc); + vereset(sc); ve_config(sc); @@ -384,7 +385,7 @@ ve_config(sc) sc->sc_memsize = 262144; switch (sc->sc_memsize) { - case 8192: + case 8192: sc->sc_nrbuf = 4; sc->sc_ntbuf = 1; break; @@ -896,9 +897,9 @@ ve_intr(arg) return (0); /* clear the interrupting condition */ - (*sc->sc_wrcsr)(sc, LE_CSR0, - isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR | - LE_C0_RINT | LE_C0_TINT | LE_C0_IDON)); + (*sc->sc_wrcsr)(sc, LE_CSR0, + isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | + LE_C0_MERR | LE_C0_RINT | LE_C0_TINT | LE_C0_IDON)); if (isr & LE_C0_ERR) { if (isr & LE_C0_BABL) { #ifdef LEDEBUG @@ -942,7 +943,7 @@ ve_intr(arg) ve_rint(sc); if (isr & LE_C0_TINT) ve_tint(sc); - ve_ackint(sc); + ve_ackint(sc); return (1); } @@ -1308,6 +1309,9 @@ ve_copytobuf_contig(sc, from, boff, len) int boff, len; { volatile caddr_t buf = sc->sc_mem; + volatile caddr_t phys = (caddr_t)sc->sc_addr; + dma_cachectl((vm_offset_t)phys + boff, len, DMA_CACHE_SYNC); + dma_cachectl((vm_offset_t)buf + boff, len, DMA_CACHE_SYNC); /* * Just call bcopy() to do the work. @@ -1322,7 +1326,9 @@ ve_copyfrombuf_contig(sc, to, boff, len) int boff, len; { volatile caddr_t buf = sc->sc_mem; - + volatile caddr_t phys = (caddr_t)sc->sc_addr; + dma_cachectl((vm_offset_t)phys + boff, len, DMA_CACHE_SYNC_INVAL); + dma_cachectl((vm_offset_t)buf + boff, len, DMA_CACHE_SYNC_INVAL); /* * Just call bcopy() to do the work. */ @@ -1335,6 +1341,9 @@ ve_zerobuf_contig(sc, boff, len) int boff, len; { volatile caddr_t buf = sc->sc_mem; + volatile caddr_t phys = (caddr_t)sc->sc_addr; + dma_cachectl((vm_offset_t)phys + boff, len, DMA_CACHE_SYNC); + dma_cachectl((vm_offset_t)buf + boff, len, DMA_CACHE_SYNC); /* * Just let bzero() do the work diff --git a/sys/arch/mvme88k/dev/sclock.c b/sys/arch/mvme88k/dev/sclock.c index fcc0ea7a398..f00541d0136 100644 --- a/sys/arch/mvme88k/dev/sclock.c +++ b/sys/arch/mvme88k/dev/sclock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sclock.c,v 1.1 1999/09/27 18:43:25 smurph Exp $ */ +/* $OpenBSD: sclock.c,v 1.2 2001/02/01 03:38:14 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * @@ -86,6 +86,7 @@ #include <sys/gmon.h> #endif +#include <machine/board.h> #include <machine/psl.h> #include <machine/autoconf.h> #include <machine/bugio.h> @@ -113,13 +114,13 @@ struct simplelock cio_lock; int statvar = 8192; int statmin; /* statclock interval - 1/2*variance */ -static int sclockmatch __P((struct device *, void *, void *)); -static void sclockattach __P((struct device *, struct device *, void *)); +static int sclockmatch __P((struct device *, void *, void *)); +static void sclockattach __P((struct device *, struct device *, void *)); -void sbc_initstatclock __P((void)); -void m188_initstatclock __P((void)); -void m188_cio_init __P((unsigned)); -void write_cio __P((unsigned, unsigned)); +void sbc_initstatclock __P((void)); +void m188_initstatclock __P((void)); +void m188_cio_init __P((unsigned)); +void write_cio __P((unsigned, unsigned)); struct sclocksoftc { struct device sc_dev; @@ -134,8 +135,8 @@ struct cfdriver sclock_cd = { NULL, "sclock", DV_DULL, 0 }; -int sbc_statintr __P((void *)); -int m188_statintr __P((void *)); +int sbc_statintr __P((void *)); +int m188_statintr __P((void *)); int sclockbus; u_char stat_reset; @@ -146,8 +147,8 @@ u_char stat_reset; */ int sclockmatch(parent, vcf, args) - struct device *parent; - void *vcf, *args; +struct device *parent; +void *vcf, *args; { register struct confargs *ca = args; register struct cfdata *cf = vcf; @@ -169,40 +170,40 @@ sclockmatch(parent, vcf, args) void sclockattach(parent, self, args) - struct device *parent, *self; - void *args; +struct device *parent, *self; +void *args; { struct confargs *ca = args; struct sclocksoftc *sc = (struct sclocksoftc *)self; sclockbus = ca->ca_bustype; - - switch (sclockbus) { + + switch (sclockbus) { #if NPCCTWO > 0 - case BUS_PCCTWO: - sc->sc_statih.ih_fn = sbc_statintr; - sc->sc_statih.ih_arg = 0; - sc->sc_statih.ih_wantframe = 1; - sc->sc_statih.ih_ipl = ca->ca_ipl; - stat_reset = ca->ca_ipl | PCC2_IRQ_IEN | PCC2_IRQ_ICLR; - pcctwointr_establish(PCC2V_TIMER2, &sc->sc_statih); - mdfp.statclock_init_func = &sbc_initstatclock; - printf(": VME1x7"); - break; + case BUS_PCCTWO: + sc->sc_statih.ih_fn = sbc_statintr; + sc->sc_statih.ih_arg = 0; + sc->sc_statih.ih_wantframe = 1; + sc->sc_statih.ih_ipl = ca->ca_ipl; + stat_reset = ca->ca_ipl | PCC2_IRQ_IEN | PCC2_IRQ_ICLR; + pcctwointr_establish(PCC2V_TIMER2, &sc->sc_statih); + mdfp.statclock_init_func = &sbc_initstatclock; + printf(": VME1x7"); + break; #endif /* NPCCTWO */ #if NSYSCON > 0 - case BUS_SYSCON: - sc->sc_statih.ih_fn = m188_statintr; - sc->sc_statih.ih_arg = 0; - sc->sc_statih.ih_wantframe = 1; - sc->sc_statih.ih_ipl = ca->ca_ipl; - sysconintr_establish(SYSCV_TIMER2, &sc->sc_statih); - mdfp.statclock_init_func = &m188_initstatclock; - printf(": VME188"); - break; + case BUS_SYSCON: + sc->sc_statih.ih_fn = m188_statintr; + sc->sc_statih.ih_arg = 0; + sc->sc_statih.ih_wantframe = 1; + sc->sc_statih.ih_ipl = ca->ca_ipl; + sysconintr_establish(SYSCV_TIMER2, &sc->sc_statih); + mdfp.statclock_init_func = &m188_initstatclock; + printf(": VME188"); + break; #endif /* NSYSCON */ - } - printf("\n"); + } + printf("\n"); } #if NPCCTWO > 0 @@ -211,8 +212,8 @@ sbc_initstatclock(void) { register int statint, minint; -#ifdef DEBUG - printf("SBC statclock init\n"); +#ifdef CLOCK_DEBUG + printf("SBC statclock init\n"); #endif if (stathz == 0) stathz = hz; @@ -232,7 +233,7 @@ sbc_initstatclock(void) sys_pcc2->pcc2_t2cmp = pcc2_timer_us2lim(statint); sys_pcc2->pcc2_t2count = 0; sys_pcc2->pcc2_t2ctl = PCC2_TCTL_CEN | PCC2_TCTL_COC | - PCC2_TCTL_COVF; + PCC2_TCTL_COVF; sys_pcc2->pcc2_t2irq = stat_reset; statmin = statint - (statvar >> 1); @@ -240,7 +241,7 @@ sbc_initstatclock(void) int sbc_statintr(cap) - void *cap; +void *cap; { register u_long newint, r, var; @@ -274,13 +275,14 @@ sbc_statintr(cap) int m188_statintr(cap) - void *cap; +void *cap; { register u_long newint, r, var; + volatile int *ist = (volatile int *)MVME188_IST; - CIO_LOCK; + CIO_LOCK; statclock((struct clockframe *)cap); - write_cio(CIO_CSR1, CIO_GCB|CIO_CIP); /* Ack the interrupt */ + write_cio(CIO_CSR1, CIO_GCB|CIO_CIP); /* Ack the interrupt */ /* * Compute new randomized interval. The intervals are uniformly @@ -292,12 +294,17 @@ m188_statintr(cap) r = random() & (var - 1); } while (r == 0); newint = statmin + r; -/* printf("newint = %d, 0x%x\n", newint, newint);*/ + /* + printf("newint = %d, 0x%x\n", newint, newint); + */ write_cio(CIO_CT1MSB, (newint & 0xFF00) >> 8); /* Load time constant CTC #1 */ write_cio(CIO_CT1LSB, newint & 0xFF); - /* force a trigger event */ - write_cio(CIO_CSR1, CIO_GCB|CIO_TCB|CIO_IE); /* Start CTC #1 running */ - CIO_UNLOCK; + /* force a trigger event */ + write_cio(CIO_CSR1, CIO_GCB|CIO_TCB|CIO_IE); /* Start CTC #1 running */ + if (*ist & DTI_BIT) { + printf("CIOI not clearing!\n"); + } + CIO_UNLOCK; return (1); } @@ -306,8 +313,8 @@ m188_initstatclock(void) { register int statint, minint; -#ifdef DEBUG - printf("VME188 clock init\n"); +#ifdef CLOCK_DEBUG + printf("VME188 clock init\n"); #endif simple_lock_init(&cio_lock); if (stathz == 0) @@ -322,8 +329,8 @@ m188_initstatclock(void) minint = statint / 2 + 100; while (statvar > minint) statvar >>= 1; - m188_cio_init(statint); - statmin = statint - (statvar >> 1); + m188_cio_init(statint); + statmin = statint - (statvar >> 1); } #define CIO_CNTRL 0xFFF8300C @@ -334,11 +341,19 @@ write_cio(reg, val) unsigned reg,val; { int s, i; + volatile int *cio_ctrl = (volatile int *)CIO_CNTRL; + s = splclock(); - /* Select register */ - *((volatile int *) CIO_CTRL) = (reg & 0xFF); - /* Write the value */ - *((volatile int *) CIO_CTRL) = (val & 0xFF); + CIO_LOCK; + + i = *cio_ctrl; /* goto state 1 */ + *cio_ctrl = 0; /* take CIO out of RESET */ + i = *cio_ctrl; /* reset CIO state machine */ + + *cio_ctrl = (reg & 0xFF); /* Select register */ + *cio_ctrl = (val & 0xFF); /* Write the value */ + + CIO_UNLOCK; splx(s); } @@ -348,18 +363,21 @@ read_cio(reg) unsigned reg; { int c; - int s, i; - volatile int *port = (volatile int *)CIO_CNTRL; - + int s, i; + volatile int *cio_ctrl = (volatile int *)CIO_CNTRL; + s = splclock(); + CIO_LOCK; + /* Select register */ - *port = (char)(reg&0xFF); + *cio_ctrl = (char)(reg&0xFF); /* Delay for a short time to allow 8536 to settle */ - for(i=0;i<100;i++); + for (i=0;i<100;i++); /* read the value */ - c = *port; + c = *cio_ctrl; + CIO_UNLOCK; splx(s); - return((u_char)c&0xFF); + return ((u_char)c&0xFF); } /* @@ -372,41 +390,41 @@ void m188_cio_init(unsigned p) { long i; - short period; + short period; - CIO_LOCK; + CIO_LOCK; - period = p & 0xFFFF; - - /* Initialize 8536 CTC */ + period = p & 0xFFFF; + + /* Initialize 8536 CTC */ /* Start by forcing chip into known state */ (void) read_cio(CIO_MICR); write_cio(CIO_MICR, CIO_MICR_RESET); /* Reset the CTC */ - for(i=0;i < 1000L; i++) /* Loop to delay */ + for (i=0;i < 1000L; i++) /* Loop to delay */ ; /* Clear reset and start init seq. */ - write_cio(CIO_MICR, 0x00); + write_cio(CIO_MICR, 0x00); /* Wait for chip to come ready */ - while((read_cio(CIO_MICR)) != (char) CIO_MICR_RJA) + while ((read_cio(CIO_MICR)) != (char) CIO_MICR_RJA) ; - /* init Z8036 */ + /* init Z8036 */ write_cio(CIO_MICR, CIO_MICR_MIE | CIO_MICR_NV | CIO_MICR_RJA | CIO_MICR_DLC); write_cio(CIO_CTMS1, CIO_CTMS_CSC); /* Continuous count */ - write_cio(CIO_PDCB, 0xFF); /* set port B to input */ - - write_cio(CIO_CT1MSB, (period & 0xFF00) >> 8); /* Load time constant CTC #1 */ + write_cio(CIO_PDCB, 0xFF); /* set port B to input */ + + /* Load time constant CTC #1 */ + write_cio(CIO_CT1MSB, (period & 0xFF00) >> 8); write_cio(CIO_CT1LSB, period & 0xFF); - - /* enable counter 1 */ - write_cio(CIO_MCCR, CIO_MCCR_CT1E | CIO_MCCR_PBE); - /* enable interrupts and start */ + /* enable counter 1 */ + write_cio(CIO_MCCR, CIO_MCCR_CT1E | CIO_MCCR_PBE); + + /* enable interrupts and start */ /*write_cio(CIO_IVR, SYSCV_TIMER2);*/ - write_cio(CIO_CSR1, CIO_GCB|CIO_TCB|CIO_IE); /* Start CTC #1 running */ - - CIO_UNLOCK; -} + write_cio(CIO_CSR1, CIO_GCB|CIO_TCB|CIO_IE); /* Start CTC #1 running */ + CIO_UNLOCK; +} #endif /* NSYSCON */ diff --git a/sys/arch/mvme88k/dev/siop.c b/sys/arch/mvme88k/dev/siop.c index fe0c95e5a43..7b3c06174c1 100644 --- a/sys/arch/mvme88k/dev/siop.c +++ b/sys/arch/mvme88k/dev/siop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: siop.c,v 1.4 2001/01/13 05:18:58 smurph Exp $ */ +/* $OpenBSD: siop.c,v 1.5 2001/02/01 03:38:15 smurph Exp $ */ /* * Copyright (c) 1994 Michael L. Hitch @@ -229,9 +229,9 @@ siop_scsicmd(xs) slp = xs->sc_link; sc = slp->adapter_softc; flags = xs->flags; - xs->error = XS_NOERROR; + xs->error = XS_NOERROR; - /* XXXX ?? */ + /* XXXX ?? */ if (flags & SCSI_DATA_UIO) panic("siop: scsi data uio requested"); diff --git a/sys/arch/mvme88k/dev/syscon.c b/sys/arch/mvme88k/dev/syscon.c index 9b052d66ad1..8056a228db3 100644 --- a/sys/arch/mvme88k/dev/syscon.c +++ b/sys/arch/mvme88k/dev/syscon.c @@ -1,5 +1,5 @@ -/* $OpenBSD: syscon.c,v 1.2 2000/03/26 23:32:00 deraadt Exp $ */ +/* $OpenBSD: syscon.c,v 1.3 2001/02/01 03:38:15 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -79,9 +79,10 @@ struct sysconsoftc { void *sc_vaddr; /* Utility I/O space */ void *sc_paddr; struct sysconreg *sc_syscon; /* the actual registers */ - struct intrhand sc_abih; /* `abort' switch */ - struct intrhand sc_acih; /* `ac fial' */ - struct intrhand sc_sfih; /* `sys fial' */ + struct intrhand sc_abih; /* `abort' switch */ + struct intrhand sc_acih; /* `ac fial' */ + struct intrhand sc_sfih; /* `sys fial' */ + struct intrhand sc_m188ih; /* `m188 interrupt' */ }; void sysconattach __P((struct device *, struct device *, void *)); @@ -90,6 +91,7 @@ void setupiackvectors __P((void)); int sysconabort __P((struct frame *frame)); int sysconacfail __P((struct frame *frame)); int sysconsysfail __P((struct frame *frame)); +int sysconm188 __P((struct frame *frame)); struct cfattach syscon_ca = { sizeof(struct sysconsoftc), sysconmatch, sysconattach @@ -103,8 +105,8 @@ struct sysconreg *sys_syscon = NULL; int sysconmatch(parent, vcf, args) - struct device *parent; - void *vcf, *args; +struct device *parent; +void *vcf, *args; { struct cfdata *cf = vcf; struct confargs *ca = args; @@ -112,16 +114,16 @@ sysconmatch(parent, vcf, args) /* Don't match if wrong cpu */ if (cputyp != CPU_188) return (0); - /* Uh, MVME188 better have on of these, so always match if it - * is a MVME188... */ - syscon = (struct sysconreg *)(IIOV(ca->ca_paddr)); + /* Uh, MVME188 better have on of these, so always match if it + * is a MVME188... */ + syscon = (struct sysconreg *)(IIOV(ca->ca_paddr)); return (1); } int syscon_print(args, bus) - void *args; - const char *bus; +void *args; +const char *bus; { struct confargs *ca = args; @@ -134,8 +136,8 @@ syscon_print(args, bus) int syscon_scan(parent, child, args) - struct device *parent; - void *child, *args; +struct device *parent; +void *child, *args; { struct cfdata *cf = child; struct sysconsoftc *sc = (struct sysconsoftc *)parent; @@ -143,14 +145,14 @@ syscon_scan(parent, child, args) struct confargs oca; if (parent->dv_cfdata->cf_driver->cd_indirect) { - printf(" indirect devices not supported\n"); - return 0; - } + printf(" indirect devices not supported\n"); + return 0; + } bzero(&oca, sizeof oca); oca.ca_offset = cf->cf_loc[0]; oca.ca_ipl = cf->cf_loc[1]; - if ((oca.ca_offset != (void*)-1) && ISIIOVA(sc->sc_vaddr + oca.ca_offset)) { + if (((int)oca.ca_offset != -1) && ISIIOVA(sc->sc_vaddr + oca.ca_offset)) { oca.ca_vaddr = sc->sc_vaddr + oca.ca_offset; oca.ca_paddr = sc->sc_paddr + oca.ca_offset; } else { @@ -167,9 +169,10 @@ syscon_scan(parent, child, args) } void + sysconattach(parent, self, args) - struct device *parent, *self; - void *args; +struct device *parent, *self; +void *args; { struct confargs *ca = args; struct sysconsoftc *sc = (struct sysconsoftc *)self; @@ -189,61 +192,74 @@ sysconattach(parent, self, args) printf(": rev %d\n", 1); - /* - * pseudo driver, abort interrupt handler - */ - sc->sc_abih.ih_fn = sysconabort; - sc->sc_abih.ih_arg = 0; - sc->sc_abih.ih_ipl = IPL_ABORT; - sc->sc_abih.ih_wantframe = 1; - sc->sc_acih.ih_fn = sysconacfail; - sc->sc_acih.ih_arg = 0; - sc->sc_acih.ih_ipl = IPL_ABORT; - sc->sc_acih.ih_wantframe = 1; - sc->sc_sfih.ih_fn = sysconsysfail; - sc->sc_sfih.ih_arg = 0; - sc->sc_sfih.ih_ipl = IPL_ABORT; - sc->sc_sfih.ih_wantframe = 1; - - intr_establish(SYSCV_ABRT, &sc->sc_abih); - intr_establish(SYSCV_ACF, &sc->sc_acih); - intr_establish(SYSCV_SYSF, &sc->sc_sfih); + /* + * pseudo driver, abort interrupt handler + */ + sc->sc_abih.ih_fn = sysconabort; + sc->sc_abih.ih_arg = 0; + sc->sc_abih.ih_ipl = IPL_ABORT; + sc->sc_abih.ih_wantframe = 1; + sc->sc_acih.ih_fn = sysconacfail; + sc->sc_acih.ih_arg = 0; + sc->sc_acih.ih_ipl = IPL_ABORT; + sc->sc_acih.ih_wantframe = 1; + sc->sc_sfih.ih_fn = sysconsysfail; + sc->sc_sfih.ih_arg = 0; + sc->sc_sfih.ih_ipl = IPL_ABORT; + sc->sc_sfih.ih_wantframe = 1; + sc->sc_m188ih.ih_fn = sysconm188; + sc->sc_m188ih.ih_arg = 0; + sc->sc_m188ih.ih_ipl = IPL_ABORT; + sc->sc_m188ih.ih_wantframe = 1; + + intr_establish(SYSCV_ABRT, &sc->sc_abih); + intr_establish(SYSCV_ACF, &sc->sc_acih); + intr_establish(SYSCV_SYSF, &sc->sc_sfih); + intr_establish(M188_IVEC, &sc->sc_m188ih); config_search(syscon_scan, self, args); } int sysconintr_establish(vec, ih) - int vec; - struct intrhand *ih; +int vec; +struct intrhand *ih; { return (intr_establish(vec, ih)); } int sysconabort(frame) - struct frame *frame; +struct frame *frame; { - ISR_RESET_NMI; - nmihand(frame); + ISR_RESET_NMI; + nmihand(frame); return (1); } int sysconsysfail(frame) - struct frame *frame; +struct frame *frame; { - ISR_RESET_SYSFAIL; - nmihand(frame); + ISR_RESET_SYSFAIL; + nmihand(frame); return (1); } int sysconacfail(frame) - struct frame *frame; +struct frame *frame; +{ + ISR_RESET_ACFAIL; + nmihand(frame); + return (1); +} + +int +sysconm188(frame) +struct frame *frame; { - ISR_RESET_ACFAIL; - nmihand(frame); + printf("MVME188 interrupting?\n"); return (1); } diff --git a/sys/arch/mvme88k/dev/sysconreg.h b/sys/arch/mvme88k/dev/sysconreg.h index bcf4739371f..568ab09a2bc 100644 --- a/sys/arch/mvme88k/dev/sysconreg.h +++ b/sys/arch/mvme88k/dev/sysconreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysconreg.h,v 1.1 1999/09/27 18:43:25 smurph Exp $ */ +/* $OpenBSD: sysconreg.h,v 1.2 2001/02/01 03:38:15 smurph Exp $ */ /* * Memory map for SYSCON found in mvme188 board set. @@ -11,37 +11,37 @@ #include <machine/board.h> struct sysconreg { - volatile unsigned int *ien0; - volatile unsigned int *ien1; - volatile unsigned int *ien2; - volatile unsigned int *ien3; - volatile unsigned int *ienall; - volatile unsigned int *ist; - volatile unsigned int *setswi; - volatile unsigned int *clrswi; - volatile unsigned int *istate; - volatile unsigned int *clrint; - volatile unsigned char *global0; - volatile unsigned char *global1; - volatile unsigned char *global2; - volatile unsigned char *global3; - volatile unsigned int *ucsr; - volatile unsigned int *glbres; - volatile unsigned int *ccsr; - volatile unsigned int *error; - volatile unsigned int *pcnfa; - volatile unsigned int *pcnfb; - volatile unsigned int *extad; - volatile unsigned int *extam; - volatile unsigned int *whoami; - volatile unsigned int *wmad; - volatile unsigned int *rmad; - volatile unsigned int *wvad; - volatile unsigned int *rvad; - volatile unsigned int *cio_portc; - volatile unsigned int *cio_portb; - volatile unsigned int *cio_porta; - volatile unsigned int *cio_ctrl; + volatile unsigned int *ien0; + volatile unsigned int *ien1; + volatile unsigned int *ien2; + volatile unsigned int *ien3; + volatile unsigned int *ienall; + volatile unsigned int *ist; + volatile unsigned int *setswi; + volatile unsigned int *clrswi; + volatile unsigned int *istate; + volatile unsigned int *clrint; + volatile unsigned char *global0; + volatile unsigned char *global1; + volatile unsigned char *global2; + volatile unsigned char *global3; + volatile unsigned int *ucsr; + volatile unsigned int *glbres; + volatile unsigned int *ccsr; + volatile unsigned int *error; + volatile unsigned int *pcnfa; + volatile unsigned int *pcnfb; + volatile unsigned int *extad; + volatile unsigned int *extam; + volatile unsigned int *whoami; + volatile unsigned int *wmad; + volatile unsigned int *rmad; + volatile unsigned int *wvad; + volatile unsigned int *rvad; + volatile unsigned int *cio_portc; + volatile unsigned int *cio_portb; + volatile unsigned int *cio_porta; + volatile unsigned int *cio_ctrl; }; extern struct sysconreg *sys_syscon; @@ -49,10 +49,10 @@ extern struct sysconreg *sys_syscon; /* * Vectors we use */ -#define SYSCV_ABRT 0x110 -#define SYSCV_SYSF 0x111 -#define SYSCV_ACF 0x112 -#define SYSCV_SCC 0x55 +#define SYSCV_ABRT 0x52 +#define SYSCV_SYSF 0x53 +#define SYSCV_ACF 0x54 +#define SYSCV_SCC 0x55 #define SYSCV_TIMER4 0x56 #define SYSCV_TIMER3 0x57 #define SYSCV_TIMER2 0x58 diff --git a/sys/arch/mvme88k/dev/vme.c b/sys/arch/mvme88k/dev/vme.c index cb5c4726620..b3498243929 100644 --- a/sys/arch/mvme88k/dev/vme.c +++ b/sys/arch/mvme88k/dev/vme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vme.c,v 1.6 2001/01/14 20:25:22 smurph Exp $ */ +/* $OpenBSD: vme.c,v 1.7 2001/02/01 03:38:15 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * Copyright (c) 1995 Theo de Raadt @@ -65,8 +65,11 @@ int vme2chip_init __P((struct vmesoftc *sc)); u_long vme2chip_map __P((u_long base, int len, int dwidth)); int vme2abort __P((struct frame *frame)); int sysconabort __P((struct frame *frame)); +int intr_findvec __P((int start, int end)); static int vmebustype; +static int vmevecbase; + struct vme2reg *sys_vme2 = NULL; struct cfattach vme_ca = { @@ -259,7 +262,7 @@ vmescan(parent, child, args, bustype) oca.ca_vec = cf->cf_loc[2]; oca.ca_ipl = cf->cf_loc[3]; if (oca.ca_ipl > 0 && oca.ca_vec == -1) - oca.ca_vec = intr_findvec(255, 0); + oca.ca_vec = vme_findvec(); if (oca.ca_len == -1) oca.ca_len = 4096; @@ -284,15 +287,15 @@ vmescan(parent, child, args, bustype) void vmeattach(parent, self, args) - struct device *parent, *self; - void *args; +struct device *parent, *self; +void *args; { struct vmesoftc *sc = (struct vmesoftc *)self; struct confargs *ca = args; struct vme1reg *vme1; struct vme2reg *vme2; int scon; - char sconc; + char sconc; /* XXX any initialization to do? */ @@ -303,27 +306,38 @@ vmeattach(parent, self, args) #if NPCCTWO > 0 case BUS_PCCTWO: vme2 = (struct vme2reg *)sc->sc_vaddr; + /* Sanity check that the Bug is set up right */ + if (VME2_GET_VBR1(vme2) >= 0xF0) { + panic("Correct the VME Vector Base Registers in the Bug ROM.\nSuggested values are 0x60 for VME Vec0 and 0x70 for VME Vec1."); + } + vmevecbase = VME2_GET_VBR1(vme2) + 0x10; scon = (vme2->vme2_tctl & VME2_TCTL_SCON); - printf(": %ssystem controller\n", scon ? "" : "not "); - if (scon) sys_vme2 = vme2; + printf(": vector base 0x%x, %ssystem controller\n", vmevecbase, scon ? "" : "not "); + if (scon) sys_vme2 = vme2; vme2chip_init(sc); break; #endif #if NSYSCON > 0 case BUS_SYSCON: - vme2 = (struct vme2reg *)sc->sc_vaddr; - sconc = *(char *)GLOBAL1; - sconc &= M188_SYSCON; + vmevecbase = 0x80; /* Hard coded for MVME188 */ + sconc = *(char *)GLOBAL1; + sconc &= M188_SYSCON; printf(": %ssystem controller\n", scon ? "" : "not "); vmesyscon_init(sc); break; #endif } - while (config_found(self, NULL, NULL)) ; } +/* find a VME vector based on what is in NVRAM settings. */ +int +vme_findvec(void) +{ + return(intr_findvec(vmevecbase, 0xFF)); +} + /* * On the VMEbus, only one cpu may be configured to respond to any * particular vme ipl. Therefore, it wouldn't make sense to globally @@ -336,6 +350,17 @@ vmeattach(parent, self, args) * Obviously no check is made to see if another cpu is using that * interrupt. If you share you will lose. */ + +/* + * All VME bus devices will use a vector starting with VBR1 + 0x10 + * and determined by intr_findvec(). (in machdep.c) vmeintr_establish() + * should be called with the 'vec' argument = 0 to 'auto vector' a + * VME device. + * + * The 8 SW interrupters will start with VBR1. The rest will start + * with VBR0< 4) & 0xFF. + */ + int vmeintr_establish(vec, ih) int vec; @@ -350,8 +375,6 @@ vmeintr_establish(vec, ih) #endif int x; - x = (intr_establish(vec, ih)); - switch (vmebustype) { #if NPCCTWO > 0 case BUS_PCCTWO: @@ -363,13 +386,10 @@ vmeintr_establish(vec, ih) #if NSYSCON > 0 case BUS_SYSCON: syscon = (struct sysconreg *)sc->sc_vaddr; - /* - syscon->vme2_irqen = vme2->vme2_irqen | - VMES_IRQ_VME(ih->ih_ipl); - */ break; #endif } + x = (intr_establish(vec, ih)); return (x); } @@ -388,28 +408,28 @@ vme2chip_init(sc) printf("%s: using BUG parameters\n", sc->sc_dev.dv_xname); /* setup a A32D16 space */ printf("%s: 1phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n", - sc->sc_dev.dv_xname, - vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000, - vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000); + sc->sc_dev.dv_xname, + vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000, + vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000); /* setup a A32D32 space */ printf("%s: 2phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n", - sc->sc_dev.dv_xname, - vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000, - vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000); + sc->sc_dev.dv_xname, + vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000, + vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000); /* setup a A24D16 space */ printf("%s: 3phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n", - sc->sc_dev.dv_xname, - vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000, - vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000); + sc->sc_dev.dv_xname, + vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000, + vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000); /* setup a XXXXXX space */ printf("%s: 4phys 0x%08x-0x%08x to VME 0x%08x-0x%08x\n", - sc->sc_dev.dv_xname, - vme2->vme2_master4 << 16, vme2->vme2_master4 & 0xffff0000, - vme2->vme2_master4 << 16 + vme2->vme2_master4mod << 16, - vme2->vme2_master4 & 0xffff0000 + vme2->vme2_master4 & 0xffff0000); + sc->sc_dev.dv_xname, + vme2->vme2_master4 << 16, vme2->vme2_master4 & 0xffff0000, + vme2->vme2_master4 << 16 + vme2->vme2_master4mod << 16, + vme2->vme2_master4 & 0xffff0000 + vme2->vme2_master4 & 0xffff0000); /* * Map the VME irq levels to the cpu levels 1:1. * This is rather inflexible, but much easier. @@ -423,7 +443,20 @@ vme2chip_init(sc) printf("%s: vme2_irql4 = 0x%08x\n", sc->sc_dev.dv_xname, vme2->vme2_irql4); */ - if (vmebustype == BUS_PCCTWO){ + + /* Enable the reset switch */ + vme2->vme2_tctl |= VME2_TCTL_RSWE; + /* Set Watchdog timeout to about 1 minute */ + vme2->vme2_tcr |= VME2_TCR_64S; + /* Enable VMEChip2 Interrupts */ + vme2->vme2_vbr |= VME2_IOCTL1_MIEN; + /* + * Map the Software VME irq levels to the cpu level 7. + */ + vme2->vme2_irql3 = (7 << VME2_IRQL3_SW7SHIFT) | (7 << VME2_IRQL3_SW6SHIFT) | + (7 << VME2_IRQL3_SW5SHIFT) | (7 << VME2_IRQL3_SW4SHIFT) | + (7 << VME2_IRQL3_SW3SHIFT) | (7 << VME2_IRQL3_SW2SHIFT) | + (7 << VME2_IRQL3_SW1SHIFT) | (7 << VME2_IRQL3_SW0SHIFT); /* * pseudo driver, abort interrupt handler */ @@ -433,15 +466,14 @@ vme2chip_init(sc) sc->sc_abih.ih_wantframe = 1; intr_establish(110, &sc->sc_abih); vme2->vme2_irqen |= VME2_IRQ_AB; - } - vme2->vme2_irqen = vme2->vme2_irqen | VME2_IRQ_ACF; + vme2->vme2_irqen |= VME2_IRQ_ACF; } #endif /* NPCCTWO */ #if NSYSCON > 0 int vmesyscon_init(sc) - struct vmesoftc *sc; +struct vmesoftc *sc; { struct sysconreg *syscon = (struct sysconreg *)sc->sc_vaddr; u_long ctl, addr, vasize; @@ -453,22 +485,22 @@ vmesyscon_init(sc) ctl = vme2->vme2_masterctl; printf("%s: using BUG parameters\n", sc->sc_dev.dv_xname); printf("%s: 1phys 0x%08x-0x%08x to VME 0x%08x-0x%08x master\n", - sc->sc_dev.dv_xname, - vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000, - vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000); + sc->sc_dev.dv_xname, + vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000, + vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000); printf("%s: 2phys 0x%08x-0x%08x to VME 0x%08x-0x%08x slave\n", - sc->sc_dev.dv_xname, - vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000, - vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000); - - /* - * pseudo driver, abort interrupt handler - */ - sc->sc_abih.ih_fn = sysconabort; - sc->sc_abih.ih_arg = 0; - sc->sc_abih.ih_ipl = IPL_NMI; - sc->sc_abih.ih_wantframe = 1; - intr_establish(110, &sc->sc_abih); + sc->sc_dev.dv_xname, + vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000, + vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000); + + /* + * pseudo driver, abort interrupt handler + */ + sc->sc_abih.ih_fn = sysconabort; + sc->sc_abih.ih_arg = 0; + sc->sc_abih.ih_ipl = IPL_NMI; + sc->sc_abih.ih_wantframe = 1; + intr_establish(110, &sc->sc_abih); #endif /* TODO */ } #endif /* NSYSCON */ @@ -505,11 +537,24 @@ vme2abort(frame) { struct vmesoftc *sc = (struct vmesoftc *) vme_cd.cd_devs[0]; struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vaddr; + int rc = 0; + if (vme2->vme2_irqstat & VME2_IRQ_AB) { + vme2->vme2_irqclr = VME2_IRQ_AB; + nmihand(frame); + rc = 1; + } + if (vme2->vme2_irqstat & VME2_IRQ_AB) { + vme2->vme2_irqclr = VME2_IRQ_AB; + nmihand(frame); + rc = 1; + } +#if 0 if (vme2->vme2_irqstat & VME2_IRQ_AB == 0) { printf("%s: abort irq not set\n", sc->sc_dev.dv_xname); return (0); } +#endif vme2->vme2_irqclr = VME2_IRQ_AB; nmihand(frame); return (1); diff --git a/sys/arch/mvme88k/dev/vme.h b/sys/arch/mvme88k/dev/vme.h index d143d53f791..98c64ddeaa6 100644 --- a/sys/arch/mvme88k/dev/vme.h +++ b/sys/arch/mvme88k/dev/vme.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vme.h,v 1.3 1999/05/29 04:41:44 smurph Exp $ */ +/* $OpenBSD: vme.h,v 1.4 2001/02/01 03:38:15 smurph Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -30,9 +30,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if 0 -#include <machine/cpu.h> -#endif +#ifndef __MVEME88K_DEV_VME_H__ +#define __MVEME88K_DEV_VME_H__ + struct vmesoftc { struct device sc_dev; void * sc_vaddr; @@ -222,7 +222,22 @@ struct vme2reg { /*40*/ volatile u_long vme2_dmacount; /*44*/ volatile u_long vme2_dmatable; /*48*/ volatile u_long vme2_dmastat; -/*4c*/ volatile u_long vme2_vmejunk; +/*4c*/ volatile u_long vme2_tcr; +#define VME2_TCR_1MS (1 << 8) /* Watchdog 1 ms */ +#define VME2_TCR_2MS (2 << 8) /* Watchdog 2 ms */ +#define VME2_TCR_4MS (3 << 8) /* Watchdog 4 ms */ +#define VME2_TCR_8MS (4 << 8) /* Watchdog 8 ms */ +#define VME2_TCR_16MS (5 << 8) /* Watchdog 16 ms */ +#define VME2_TCR_32MS (6 << 8) /* Watchdog 32 ms */ +#define VME2_TCR_64MS (7 << 8) /* Watchdog 64 ms */ +#define VME2_TCR_128MS (8 << 8) /* Watchdog 128 ms */ +#define VME2_TCR_256MS (9 << 8) /* Watchdog 256 ms */ +#define VME2_TCR_512MS (10 << 8) /* Watchdog 512 ms */ +#define VME2_TCR_1S (11 << 8) /* Watchdog 1 s */ +#define VME2_TCR_4S (12 << 8) /* Watchdog 4 s */ +#define VME2_TCR_16S (13 << 8) /* Watchdog 16 s */ +#define VME2_TCR_32S (14 << 8) /* Watchdog 32 s */ +#define VME2_TCR_64S (15 << 8) /* Watchdog 64 s */ /*50*/ volatile u_long vme2_t1cmp; /*54*/ volatile u_long vme2_t1count; /*58*/ volatile u_long vme2_t2cmp; @@ -232,9 +247,25 @@ struct vme2reg { #define VME2_TCTL1_COC 0x02 #define VME2_TCTL1_COVF 0x04 #define VME2_TCTL1_OVF 0xf0 -#define VME2_TCTL_SCON 0x40000000 /* we are SCON */ -#define VME2_TCTL_SYSFAIL 0x20000000 /* light SYSFAIL led */ +#define VME2_TCTL2_CEN (0x01 << 8) +#define VME2_TCTL2_COC (0x02 << 8) +#define VME2_TCTL2_COVF (0x04 << 8) +#define VME2_TCTL2_OVF (0xf0 << 8) +#define VME2_TCTL_WDEN 0x00010000 /* Watchdog Enable */ +#define VME2_TCTL_WDRSE 0x00020000 /* Watchdog Reset Enable */ +#define VME2_TCTL_WDSL 0x00040000 /* local or system reset */ +#define VME2_TCTL_WDBFE 0x00080000 /* Watchdog Board Fail Enable */ +#define VME2_TCTL_WDTO 0x00100000 /* Watchdog Timeout Status */ +#define VME2_TCTL_WDCC 0x00200000 /* Watchdog Clear Counter */ +#define VME2_TCTL_WDCS 0x00400000 /* Watchdog Clear Timeout */ #define VME2_TCTL_SRST 0x00800000 /* system reset */ +#define VME2_TCTL_RSWE 0x01000000 /* Reset Switch Enable */ +#define VME2_TCTL_BDFLO 0x02000000 /* Assert Board Fail */ +#define VME2_TCTL_CPURS 0x04000000 /* Clear Power-up Reset bit */ +#define VME2_TCTL_PURS 0x08000000 /* Power-up Reset bit */ +#define VME2_TCTL_BDFLI 0x10000000 /* Board Fail Status*/ +#define VME2_TCTL_SYSFAIL 0x20000000 /* light SYSFAIL led */ +#define VME2_TCTL_SCON 0x40000000 /* we are SCON */ /*64*/ volatile u_long vme2_prescale; /*68*/ volatile u_long vme2_irqstat; /*6c*/ volatile u_long vme2_irqen; @@ -264,6 +295,7 @@ struct vme2reg { #define VME2_IRQ_SW2 0x00000400 #define VME2_IRQ_SW1 0x00000200 #define VME2_IRQ_SW0 0x00000100 +#define VME2_IRQ_SW(x) ((1 << (x))) << 8) #define VME2_IRQ_SPARE 0x00000080 #define VME2_IRQ_VME7 0x00000040 #define VME2_IRQ_VME6 0x00000020 @@ -311,8 +343,13 @@ struct vme2reg { #define VME2_IRQL4_VME1SHIFT 0 /*88*/ volatile u_long vme2_vbr; #define VME2_SYSFAIL (1 << 22) +#define VME2_IOCTL1_MIEN (1 << 23) #define VME2_VBR_0SHIFT 28 #define VME2_VBR_1SHIFT 24 +#define VME2_SET_VBR0(x) ((x) << VME2_VBR_0SHIFT) +#define VME2_SET_VBR1(x) ((x) << VME2_VBR_1SHIFT) +#define VME2_GET_VBR0(x) ((((x)->vme2_vbr >> 28) & 0xf) << 4) +#define VME2_GET_VBR1(x) ((((x)->vme2_vbr >> 24) & 0xf) << 4) #define VME2_VBR_GPOXXXX 0x00ffffff /*8c*/ volatile u_long vme2_misc; #define VME2_MISC_MPIRQEN 0x00000080 /* do not set */ @@ -336,8 +373,10 @@ struct vme2reg { #define VME2_A16BASE 0xffff0000UL #define VME2_A24BASE 0xff000000UL -void * vmepmap __P((struct vmesoftc *sc, void * vmeaddr, int len, - int bustype)); -void * vmemap __P((struct vmesoftc *sc, void * vmeaddr, int len, - int bustype)); -int vmerw __P((struct vmesoftc *sc, struct uio *uio, int flags, int bus)); +void * vmepmap __P((struct vmesoftc *sc, void * vmeaddr, int len, int bustype)); +void * vmemap __P((struct vmesoftc *sc, void * vmeaddr, int len, int bustype)); +int vmerw __P((struct vmesoftc *sc, struct uio *uio, int flags, int bus)); +int vmeintr_establish __P((int vec, struct intrhand *ih)); +int vme_findvec __P((void)); + +#endif __MVEME88K_DEV_VME_H__ diff --git a/sys/arch/mvme88k/dev/vs.c b/sys/arch/mvme88k/dev/vs.c index 5c5e44b991d..d63ae1ba75e 100644 --- a/sys/arch/mvme88k/dev/vs.c +++ b/sys/arch/mvme88k/dev/vs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vs.c,v 1.2 1999/09/27 18:43:25 smurph Exp $ */ +/* $OpenBSD: vs.c,v 1.3 2001/02/01 03:38:16 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. @@ -57,12 +57,14 @@ #define PAGESIZE 4096 #include <mvme88k/dev/vsreg.h> #include <mvme88k/dev/vsvar.h> - #include "machine/mmu.h" + #include <mvme88k/dev/vme.h> /* vme_findvec() */ + #include <machine/mmu.h> /* DMA_CACHE_SYNC, etc... */ #define ROUND_PAGE m88k_round_page #define TRUNC_PAGE m88k_trunc_page #else #include <mvme68k/dev/vsreg.h> #include <mvme68k/dev/vsvar.h> + #include <mvme68k/dev/vme.h> /* vme_findvec() */ #define ROUND_PAGE m68k_round_page #define TRUNC_PAGE m68k_trunc_page #endif /* MVME187 */ @@ -71,15 +73,19 @@ int vs_checkintr __P((struct vs_softc *, struct scsi_xfer *, int *)); int vs_chksense __P((struct scsi_xfer *)); void vs_reset __P((struct vs_softc *)); void vs_resync __P((struct vs_softc *)); -void vs_initialize __P((struct vs_softc *)); -int vs_intr __P((struct vs_softc *)); +int vs_initialize __P((struct vs_softc *)); +int vs_nintr __P((struct vs_softc *)); +int vs_eintr __P((struct vs_softc *)); int vs_poll __P((struct vs_softc *, struct scsi_xfer *)); -void vs_scsidone __P((struct scsi_xfer *, int)); +void vs_scsidone __P((struct vs_softc *, struct scsi_xfer *, int)); M328_CQE * vs_getcqe __P((struct vs_softc *)); M328_IOPB * vs_getiopb __P((struct vs_softc *)); +static __inline__ void vs_clear_return_info __P((struct vs_softc *)); + extern int cold; extern u_int kvtop(); + /* * 16 bit 's' memory functions. MVME328 is a D16 board. * We must program with that in mind or else... @@ -94,39 +100,40 @@ extern u_int kvtop(); */ void -scopy(void *src, void *dst, unsigned short cnt) +vs_copy(src, dst, cnt) +void *src; +void *dst; +unsigned short cnt; { - register unsigned short volatile *x, *y, z; + register unsigned short volatile *x, *y, z; - z = cnt >> 1; - x = (unsigned short *) src; - y = (unsigned short *) dst; + z = cnt >> 1; + x = (unsigned short *) src; + y = (unsigned short *) dst; - while (z--) { - *y++ = *x++; - } + while (z--) { + *y++ = *x++; + } } void -szero(void *src, u_long cnt) +vs_zero(src, cnt) +void *src; +u_long cnt; { - register unsigned short *source; - register unsigned short zero = 0; - register unsigned short z; + register unsigned short *source; + register unsigned short zero = 0; + register unsigned short z; - source = (unsigned short *) src; - z = cnt >> 1; + source = (unsigned short *) src; + z = cnt >> 1; - while (z--) { - *source++ = zero; - } - return; + while (z--) { + *source++ = zero; + } + return; } - - - - /* * default minphys routine for MVME328 based controllers */ @@ -134,38 +141,39 @@ void vs_minphys(bp) struct buf *bp; { - /* - * No max transfer at this level. - */ - minphys(bp); + /* + * No max transfer at this level. + */ + minphys(bp); } -int do_vspoll(sc, to) +int +do_vspoll(sc, to) struct vs_softc *sc; int to; { - int i; - if (to <= 0 ) to = 50000; - /* use cmd_wait values? */ - i = 50000; - /*spl0();*/ - while (!(CRSW & (M_CRSW_CRBV | M_CRSW_CC))) { - if (--i <= 0) { -#ifdef DEBUG - printf ("waiting: timeout %d crsw 0x%x\n", to, CRSW); + int i; + if (to <= 0 ) to = 50000; + /* use cmd_wait values? */ + i = 10000; + /*spl0();*/ + while (!(CRSW & (M_CRSW_CRBV | M_CRSW_CC))) { + if (--i <= 0) { +#ifdef SDEBUG2 + printf ("waiting: timeout %d crsw 0x%x\n", to, CRSW); #endif - i = 50000; - --to; - if (to <= 0) { - /*splx(s);*/ - vs_reset(sc); - vs_resync(sc); - printf ("timed out: timeout %d crsw 0x%x\n", to, CRSW); - return 1; - } - } - } - return 0; + i = 50000; + --to; + if (to <= 0) { + /*splx(s);*/ + vs_reset(sc); + vs_resync(sc); + printf ("timed out: timeout %d crsw 0x%x\n", to, CRSW); + return 1; + } + } + } + return 0; } int @@ -173,520 +181,525 @@ vs_poll(sc, xs) struct vs_softc *sc; struct scsi_xfer *xs; { - M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB; - M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; - M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; - M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; - M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB; - M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; - M328_CQE *cqep; - M328_IOPB *iopb; - int i; - int status; - int s; - int to; - - /*s = splbio();*/ - to = xs->timeout / 1000; - for (;;) { - if (do_vspoll(sc, to)) break; - if (vs_checkintr(sc, xs, &status)) { - vs_scsidone(xs, status); - } - if (CRSW & M_CRSW_ER) - CRB_CLR_ER(CRSW); - CRB_CLR_DONE(CRSW); - if (xs->flags & ITSDONE) break; - } - return (COMPLETE); + M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB; + M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; + M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB; + M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; + M328_CQE *cqep; + M328_IOPB *iopb; + int i; + int status; + int s; + int to; + + /*s = splbio();*/ + to = xs->timeout / 1000; + for (;;) { + if (do_vspoll(sc, to)) { + xs->error = XS_SELTIMEOUT; + xs->status = -1; + xs->flags |= ITSDONE; + /* clear the return information */ + vs_clear_return_info(sc); + if (xs->flags & SCSI_POLL) + return (COMPLETE); + break; + } + if (vs_checkintr(sc, xs, &status)) { + vs_scsidone(sc, xs, status); + } + if (CRSW & M_CRSW_ER) + CRB_CLR_ER(CRSW); + CRB_CLR_DONE(CRSW); + if (xs->flags & ITSDONE) break; + } + /* clear the return information */ + vs_clear_return_info(sc); + return (COMPLETE); } -void thaw_queue(sc, target) +void +thaw_queue(sc, target) struct vs_softc *sc; u_int8_t target; { - u_short t; - t = target << 8; - t |= 0x0001; - THAW_REG = t; - /* loop until thawed */ - while (THAW_REG & 0x01); + u_short t; + t = target << 8; + t |= 0x0001; + THAW_REG = t; + /* loop until thawed */ + while (THAW_REG & 0x01); } void -vs_scsidone (xs, stat) +vs_scsidone (sc, xs, stat) +struct vs_softc *sc; struct scsi_xfer *xs; int stat; { - struct scsi_link *slp = xs->sc_link; - struct vs_softc *sc = slp->adapter_softc; - M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; - xs->status = stat; - while (xs->status == SCSI_CHECK) { - vs_chksense(xs); - thaw_queue(sc, slp->target + 1); - } - xs->flags |= ITSDONE; - /*sc->sc_tinfo[slp->target].cmds++;*/ - if (CRSW & M_CRSW_ER) - CRB_CLR_ER(CRSW); - CRB_CLR_DONE(CRSW); - thaw_queue(sc, slp->target + 1); - szero(riopb, sizeof(M328_IOPB)); - scsi_done(xs); + int tgt; + struct scsi_link *slp = xs->sc_link; + xs->status = stat; + + while (xs->status == SCSI_CHECK) { + vs_chksense(xs); + tgt = xs->sc_link->target + 1; + thaw_queue(sc, tgt); + } + + tgt = xs->sc_link->target + 1; + xs->flags |= ITSDONE; + /*sc->sc_tinfo[slp->target].cmds++;*/ + + /* thaw all work queues */ + thaw_queue(sc, tgt); + scsi_done(xs); } int vs_scsicmd(xs) struct scsi_xfer *xs; { - struct scsi_link *slp = xs->sc_link; - struct vs_softc *sc = slp->adapter_softc; - int flags, s, i; - unsigned long buf, len; - u_short iopb_len; - M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; - M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; - M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; - M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB; - M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; - M328_CQE *cqep; - M328_IOPB *iopb; - M328_CMD *m328_cmd; - - /* If the target doesn't exist, abort */ - if (!sc->sc_tinfo[slp->target].avail) { - xs->error = XS_SELTIMEOUT; - xs->status = -1; - xs->flags |= ITSDONE; - scsi_done(xs); - } - - slp->quirks |= SDEV_NOLUNS; - flags = xs->flags; + struct scsi_link *slp = xs->sc_link; + struct vs_softc *sc = slp->adapter_softc; + int flags, s, i; + unsigned long buf, len; + u_short iopb_len; + M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; + M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB; + M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; + M328_CQE *cqep; + M328_IOPB *iopb; + M328_CMD *m328_cmd; + + slp->quirks |= SDEV_NOLUNS; + flags = xs->flags; + #ifdef SDEBUG - printf("scsi_cmd() "); - if (xs->cmd->opcode == 0) { - printf("TEST_UNIT_READY "); - } else if (xs->cmd->opcode == REQUEST_SENSE) { - printf("REQUEST_SENSE "); - } else if (xs->cmd->opcode == INQUIRY) { - printf("INQUIRY "); - } else if (xs->cmd->opcode == MODE_SELECT) { - printf("MODE_SELECT "); - } else if (xs->cmd->opcode == MODE_SENSE) { - printf("MODE_SENSE "); - } else if (xs->cmd->opcode == START_STOP) { - printf("START_STOP "); - } else if (xs->cmd->opcode == RESERVE) { - printf("RESERVE "); - } else if (xs->cmd->opcode == RELEASE) { - printf("RELEASE "); - } else if (xs->cmd->opcode == PREVENT_ALLOW) { - printf("PREVENT_ALLOW "); - } else if (xs->cmd->opcode == POSITION_TO_ELEMENT) { - printf("POSITION_TO_EL "); - } else if (xs->cmd->opcode == CHANGE_DEFINITION) { - printf("CHANGE_DEF "); - } else if (xs->cmd->opcode == MODE_SENSE_BIG) { - printf("MODE_SENSE_BIG "); - } else if (xs->cmd->opcode == MODE_SELECT_BIG) { - printf("MODE_SELECT_BIG "); - } else if (xs->cmd->opcode == 0x25) { - printf("READ_CAPACITY "); - } else if (xs->cmd->opcode == 0x08) { - printf("READ_COMMAND "); - } + printf("scsi_cmd() "); + if (xs->cmd->opcode == 0) { + printf("TEST_UNIT_READY "); + } else if (xs->cmd->opcode == REQUEST_SENSE) { + printf("REQUEST_SENSE "); + } else if (xs->cmd->opcode == INQUIRY) { + printf("INQUIRY "); + } else if (xs->cmd->opcode == MODE_SELECT) { + printf("MODE_SELECT "); + } else if (xs->cmd->opcode == MODE_SENSE) { + printf("MODE_SENSE "); + } else if (xs->cmd->opcode == START_STOP) { + printf("START_STOP "); + } else if (xs->cmd->opcode == RESERVE) { + printf("RESERVE "); + } else if (xs->cmd->opcode == RELEASE) { + printf("RELEASE "); + } else if (xs->cmd->opcode == PREVENT_ALLOW) { + printf("PREVENT_ALLOW "); + } else if (xs->cmd->opcode == POSITION_TO_ELEMENT) { + printf("POSITION_TO_EL "); + } else if (xs->cmd->opcode == CHANGE_DEFINITION) { + printf("CHANGE_DEF "); + } else if (xs->cmd->opcode == MODE_SENSE_BIG) { + printf("MODE_SENSE_BIG "); + } else if (xs->cmd->opcode == MODE_SELECT_BIG) { + printf("MODE_SELECT_BIG "); + } else if (xs->cmd->opcode == 0x25) { + printf("READ_CAPACITY "); + } else if (xs->cmd->opcode == 0x08) { + printf("READ_COMMAND "); + } #endif - if (flags & SCSI_POLL) { - cqep = mc; - iopb = miopb; - } else { - cqep = vs_getcqe(sc); - iopb = vs_getiopb(sc); - } - if (cqep == NULL) { - xs->error = XS_DRIVER_STUFFUP; - return (TRY_AGAIN_LATER); - } - -/* s = splbio();*/ - iopb_len = sizeof(M328_short_IOPB) + xs->cmdlen; - szero(iopb, sizeof(M328_IOPB)); - - scopy(xs->cmd, &iopb->iopb_SCSI[0], xs->cmdlen); - iopb->iopb_CMD = IOPB_SCSI; -#if 0 - LV(iopb->iopb_BUFF, kvtop(xs->data)); - LV(iopb->iopb_LENGTH, xs->datalen); -#endif - iopb->iopb_UNIT = slp->lun << 3; - iopb->iopb_UNIT |= slp->target; - iopb->iopb_NVCT = (u_char)sc->sc_nvec; - iopb->iopb_EVCT = (u_char)sc->sc_evec; - - /* - * Since the 187 doesn't support cache snooping, we have - * to flush the cache for a write and flush with inval for - * a read, prior to starting the IO. - */ - if (xs->flags & SCSI_DATA_IN) { /* read */ -#if defined(MVME187) - dma_cachectl((vm_offset_t)xs->data, xs->datalen, - DMA_CACHE_SYNC_INVAL); + if (flags & SCSI_POLL) { + cqep = mc; + iopb = miopb; + } else { + cqep = vs_getcqe(sc); + iopb = vs_getiopb(sc); + } + if (cqep == NULL) { + xs->error = XS_DRIVER_STUFFUP; + return (TRY_AGAIN_LATER); + } + + iopb_len = sizeof(M328_short_IOPB) + xs->cmdlen; + vs_zero(iopb, sizeof(M328_IOPB)); + + vs_copy(xs->cmd, &iopb->iopb_SCSI[0], xs->cmdlen); + iopb->iopb_CMD = IOPB_SCSI; + iopb->iopb_UNIT = slp->lun << 3; + iopb->iopb_UNIT |= slp->target; + iopb->iopb_NVCT = (u_char)sc->sc_nvec; + iopb->iopb_EVCT = (u_char)sc->sc_evec; + + /* + * Since the 187 doesn't support cache snooping, we have + * to flush the cache for a write and flush with inval for + * a read, prior to starting the IO. + */ + if (xs->flags & SCSI_DATA_IN) { /* read */ +#if defined(MVME187) || defined(MVME188) || defined(MVME197) + dma_cachectl((vm_offset_t)xs->data, xs->datalen, + DMA_CACHE_SYNC_INVAL); #endif - iopb->iopb_OPTION |= OPT_READ; - } else { /* write */ -#if defined(MVME187) - dma_cachectl((vm_offset_t)xs->data, xs->datalen, - DMA_CACHE_SYNC); + iopb->iopb_OPTION |= OPT_READ; + } else { /* write */ +#if defined(MVME187) || defined(MVME188) || defined(MVME197) + dma_cachectl((vm_offset_t)xs->data, xs->datalen, + DMA_CACHE_SYNC); #endif - iopb->iopb_OPTION |= OPT_WRITE; - } - - if (flags & SCSI_POLL) { - iopb->iopb_OPTION |= OPT_INTDIS; - iopb->iopb_LEVEL = 0; - } else { - iopb->iopb_OPTION |= OPT_INTEN; - iopb->iopb_LEVEL = sc->sc_ipl; - } - iopb->iopb_ADDR = ADDR_MOD; - - /* - * Wait until we can use the command queue entry. - * Should only have to wait if the master command - * queue entry is busy. - */ - while (cqep->cqe_QECR & M_QECR_GO); - - cqep->cqe_IOPB_ADDR = OFF(iopb); - cqep->cqe_IOPB_LENGTH = iopb_len; - if (flags & SCSI_POLL) { - cqep->cqe_WORK_QUEUE = slp->target + 1; - } else { - cqep->cqe_WORK_QUEUE = slp->target + 1; - } - - MALLOC(m328_cmd, M328_CMD*, sizeof(M328_CMD), M_DEVBUF, M_WAITOK); - - m328_cmd->xs = xs; - if (xs->datalen) { - m328_cmd->top_sg_list = vs_build_memory_structure(xs, iopb); - } else { - m328_cmd->top_sg_list = (M328_SG)0; - } - - LV(cqep->cqe_CTAG, m328_cmd); - - if (crb->crb_CRSW & M_CRSW_AQ) { - cqep->cqe_QECR = M_QECR_AA; - } - VL(buf, iopb->iopb_BUFF); - VL(len, iopb->iopb_LENGTH); + iopb->iopb_OPTION |= OPT_WRITE; + } + + if (flags & SCSI_POLL) { + iopb->iopb_OPTION |= OPT_INTDIS; + iopb->iopb_LEVEL = 0; + } else { + iopb->iopb_OPTION |= OPT_INTEN; + iopb->iopb_LEVEL = sc->sc_ipl; + } + iopb->iopb_ADDR = ADDR_MOD; + + /* + * Wait until we can use the command queue entry. + * Should only have to wait if the master command + * queue entry is busy and we are polling. + */ + while (cqep->cqe_QECR & M_QECR_GO); + + cqep->cqe_IOPB_ADDR = OFF(iopb); + cqep->cqe_IOPB_LENGTH = iopb_len; + if (flags & SCSI_POLL) { + cqep->cqe_WORK_QUEUE = 0; + } else { + cqep->cqe_WORK_QUEUE = slp->target + 1; + } + + MALLOC(m328_cmd, M328_CMD*, sizeof(M328_CMD), M_DEVBUF, M_WAITOK); + + m328_cmd->xs = xs; + if (xs->datalen) { + m328_cmd->top_sg_list = vs_build_memory_structure(xs, iopb); + } else { + m328_cmd->top_sg_list = (M328_SG)0; + } + + LV(cqep->cqe_CTAG, m328_cmd); + + if (crb->crb_CRSW & M_CRSW_AQ) { + cqep->cqe_QECR = M_QECR_AA; + } + VL(buf, iopb->iopb_BUFF); + VL(len, iopb->iopb_LENGTH); #ifdef SDEBUG - printf("tgt %d lun %d buf %x len %d wqn %d ipl %d\n", slp->target, - slp->lun, buf, len, cqep->cqe_WORK_QUEUE, iopb->iopb_LEVEL); + printf("tgt %d lun %d buf %x len %d wqn %d ipl %d crsw 0x%x\n", + slp->target, slp->lun, buf, len, cqep->cqe_WORK_QUEUE, + iopb->iopb_LEVEL, crb->crb_CRSW); #endif - cqep->cqe_QECR |= M_QECR_GO; - - if (flags & SCSI_POLL) { - /* poll for the command to complete */ -/* splx(s);*/ - vs_poll(sc, xs); - return (COMPLETE); - } -/* splx(s);*/ - return (SUCCESSFULLY_QUEUED); + cqep->cqe_QECR |= M_QECR_GO; + + if (flags & SCSI_POLL) { + /* poll for the command to complete */ + vs_poll(sc, xs); + return (COMPLETE); + } + return (SUCCESSFULLY_QUEUED); } int vs_chksense(xs) struct scsi_xfer *xs; { - int flags, s, i; - struct scsi_link *slp = xs->sc_link; - struct vs_softc *sc = slp->adapter_softc; - struct scsi_sense *ss; - M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; - M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; - M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB; - - /* ack and clear the error */ - CRB_CLR_DONE(CRSW); - CRB_CLR_ER(CRSW); - xs->status = 0; - - szero(miopb, sizeof(M328_IOPB)); - /* This is a command, so point to it */ - ss = (void *)&miopb->iopb_SCSI[0]; - szero(ss, sizeof(*ss)); - ss->opcode = REQUEST_SENSE; - ss->byte2 = slp->lun << 5; - ss->length = sizeof(struct scsi_sense_data); - - miopb->iopb_CMD = IOPB_SCSI; - miopb->iopb_OPTION = OPT_READ; - miopb->iopb_NVCT = (u_char)sc->sc_nvec; - miopb->iopb_EVCT = (u_char)sc->sc_evec; - miopb->iopb_LEVEL = 0; /*sc->sc_ipl;*/ - miopb->iopb_ADDR = ADDR_MOD; - LV(miopb->iopb_BUFF, kvtop(&xs->sense)); - LV(miopb->iopb_LENGTH, sizeof(struct scsi_sense_data)); - - szero(mc, sizeof(M328_CQE)); - mc->cqe_IOPB_ADDR = OFF(miopb); - mc->cqe_IOPB_LENGTH = sizeof(M328_short_IOPB) + sizeof(struct scsi_sense); - mc->cqe_WORK_QUEUE = 0; - mc->cqe_QECR = M_QECR_GO; - /* poll for the command to complete */ - s = splbio(); - do_vspoll(sc, 0); - /* - if (xs->cmd->opcode != PREVENT_ALLOW) { - xs->error = XS_SENSE; - } - */ - xs->status = riopb->iopb_STATUS >> 8; + int flags, s, i; + struct scsi_link *slp = xs->sc_link; + struct vs_softc *sc = slp->adapter_softc; + struct scsi_sense *ss; + M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + M328_IOPB *miopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB; + + /* ack and clear the error */ + CRB_CLR_ER(CRSW); + CRB_CLR_DONE(CRSW); + xs->status = 0; + + vs_zero(miopb, sizeof(M328_IOPB)); + /* This is a command, so point to it */ + ss = (void *)&miopb->iopb_SCSI[0]; + vs_zero(ss, sizeof(*ss)); + ss->opcode = REQUEST_SENSE; + ss->byte2 = slp->lun << 5; + ss->length = sizeof(struct scsi_sense_data); + + miopb->iopb_CMD = IOPB_SCSI; + miopb->iopb_OPTION = OPT_READ; + miopb->iopb_NVCT = (u_char)sc->sc_nvec; + miopb->iopb_EVCT = (u_char)sc->sc_evec; + miopb->iopb_LEVEL = 0; /*sc->sc_ipl;*/ + miopb->iopb_ADDR = ADDR_MOD; + LV(miopb->iopb_BUFF, kvtop(&xs->sense)); + LV(miopb->iopb_LENGTH, sizeof(struct scsi_sense_data)); + + vs_zero(mc, sizeof(M328_CQE)); + mc->cqe_IOPB_ADDR = OFF(miopb); + mc->cqe_IOPB_LENGTH = sizeof(M328_short_IOPB) + + sizeof(struct scsi_sense); + mc->cqe_WORK_QUEUE = 0; + mc->cqe_QECR = M_QECR_GO; + /* poll for the command to complete */ + s = splbio(); + do_vspoll(sc, 0); + /* + if (xs->cmd->opcode != PREVENT_ALLOW) { + xs->error = XS_SENSE; + } + */ + xs->status = riopb->iopb_STATUS >> 8; #ifdef SDEBUG - scsi_print_sense(xs, 2); + scsi_print_sense(xs, 2); #endif - splx(s); + splx(s); } M328_CQE * vs_getcqe(sc) struct vs_softc *sc; { - M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; - M328_CQE *cqep; + M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; + M328_CQE *cqep; - cqep = (M328_CQE *)&sc->sc_vsreg->sh_CQE[mcsb->mcsb_QHDP]; + cqep = (M328_CQE *)&sc->sc_vsreg->sh_CQE[mcsb->mcsb_QHDP]; - if (cqep->cqe_QECR & M_QECR_GO) - return NULL; /* Hopefully, this will never happen */ - mcsb->mcsb_QHDP++; - if (mcsb->mcsb_QHDP == NUM_CQE) mcsb->mcsb_QHDP = 0; - szero(cqep, sizeof(M328_CQE)); - return cqep; + if (cqep->cqe_QECR & M_QECR_GO) + return NULL; /* Hopefully, this will never happen */ + mcsb->mcsb_QHDP++; + if (mcsb->mcsb_QHDP == NUM_CQE) mcsb->mcsb_QHDP = 0; + vs_zero(cqep, sizeof(M328_CQE)); + return cqep; } M328_IOPB * vs_getiopb(sc) struct vs_softc *sc; { - M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; - M328_IOPB *iopb; - int slot; - - if (mcsb->mcsb_QHDP == 0) { - slot = NUM_CQE; - } else { - slot = mcsb->mcsb_QHDP - 1; - } - iopb = (M328_IOPB *)&sc->sc_vsreg->sh_IOPB[slot]; - szero(iopb, sizeof(M328_IOPB)); - return iopb; + M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; + M328_IOPB *iopb; + int slot; + + if (mcsb->mcsb_QHDP == 0) { + slot = NUM_CQE; + } else { + slot = mcsb->mcsb_QHDP - 1; + } + iopb = (M328_IOPB *)&sc->sc_vsreg->sh_IOPB[slot]; + vs_zero(iopb, sizeof(M328_IOPB)); + return iopb; } -void +int vs_initialize(sc) struct vs_softc *sc; { - M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB; - M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; - M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; - M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; - M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; - M328_IOPB *iopb; - M328_WQCF *wiopb = (M328_WQCF *)&sc->sc_vsreg->sh_MCE_IOPB; - u_short i, crsw; - int failed = 0; - - CRB_CLR_DONE(CRSW); - szero(cib, sizeof(M328_CIB)); - mcsb->mcsb_QHDP = 0; - sc->sc_qhp = 0; - cib->cib_NCQE = 10; - cib->cib_BURST = 0; - cib->cib_NVECT = sc->sc_ipl << 8; - cib->cib_NVECT |= sc->sc_nvec; - cib->cib_EVECT = sc->sc_ipl << 8; - cib->cib_EVECT |= sc->sc_evec; - cib->cib_PID = 0x07; - cib->cib_SID = 0x00; - cib->cib_CRBO = OFF(crb); - cib->cib_SELECT_msw = HI(SELECTION_TIMEOUT); - cib->cib_SELECT_lsw = LO(SELECTION_TIMEOUT); - cib->cib_WQ0TIMO_msw = HI(4); - cib->cib_WQ0TIMO_lsw = LO(4); - cib->cib_VMETIMO_msw = 0; /*HI(VME_BUS_TIMEOUT);*/ - cib->cib_VMETIMO_lsw = 0; /*LO(VME_BUS_TIMEOUT);*/ - cib->cib_SBRIV = sc->sc_ipl << 8; - cib->cib_SBRIV |= sc->sc_evec; - cib->cib_SOF0 = 0x15; - cib->cib_SRATE0 = 100/4; - cib->cib_SOF1 = 0x0; - cib->cib_SRATE1 = 0x0; - - iopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB; - szero(iopb, sizeof(M328_IOPB)); - iopb->iopb_CMD = CNTR_INIT; - iopb->iopb_OPTION = 0; - iopb->iopb_NVCT = (u_char)sc->sc_nvec; - iopb->iopb_EVCT = (u_char)sc->sc_evec; - iopb->iopb_LEVEL = 0; /*sc->sc_ipl;*/ - iopb->iopb_ADDR = SHIO_MOD; - LV(iopb->iopb_BUFF, OFF(cib)); - LV(iopb->iopb_LENGTH, sizeof(M328_CIB)); - - szero(mc, sizeof(M328_CQE)); - mc->cqe_IOPB_ADDR = OFF(iopb); - mc->cqe_IOPB_LENGTH = sizeof(M328_IOPB); - mc->cqe_WORK_QUEUE = 0; - mc->cqe_QECR = M_QECR_GO; - /* poll for the command to complete */ - do_vspoll(sc, 0); - CRB_CLR_DONE(CRSW); - - /* initialize work queues */ - for (i=1; i<8; i++) { - szero(wiopb, sizeof(M328_IOPB)); - wiopb->wqcf_CMD = CNTR_INIT_WORKQ; - wiopb->wqcf_OPTION = 0; - wiopb->wqcf_NVCT = (u_char)sc->sc_nvec; - wiopb->wqcf_EVCT = (u_char)sc->sc_evec; - wiopb->wqcf_ILVL = 0; /*sc->sc_ipl;*/ - wiopb->wqcf_WORKQ = i; - wiopb->wqcf_WOPT = (WQO_FOE | WQO_INIT); - wiopb->wqcf_SLOTS = JAGUAR_MAX_Q_SIZ; - LV(wiopb->wqcf_CMDTO, 2); - - szero(mc, sizeof(M328_CQE)); - mc->cqe_IOPB_ADDR = OFF(wiopb); - mc->cqe_IOPB_LENGTH = sizeof(M328_IOPB); - mc->cqe_WORK_QUEUE = 0; - mc->cqe_QECR = M_QECR_GO; - /* poll for the command to complete */ - do_vspoll(sc, 0); - if (CRSW & M_CRSW_ER) { - /*printf("\nerror: queue %d status = 0x%x\n", i, riopb->iopb_STATUS);*/ - /*failed = 1;*/ - CRB_CLR_ER(CRSW); - } - CRB_CLR_DONE(CRSW); - delay(500); - } - /* start queue mode */ - CRSW = 0; - mcsb->mcsb_MCR |= M_MCR_SQM; - crsw = CRSW; - do_vspoll(sc, 0); - if (CRSW & M_CRSW_ER) { - printf("error: status = 0x%x\n", riopb->iopb_STATUS); - CRB_CLR_ER(CRSW); - } - CRB_CLR_DONE(CRSW); - - if (failed) { - printf(": failed!\n"); - return; - } - /* reset SCSI bus */ - vs_reset(sc); - /* sync all devices */ - vs_resync(sc); - printf(": target %d\n", sc->sc_link.adapter_target); + M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB; + M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; + M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; + M328_IOPB *iopb; + M328_WQCF *wiopb = (M328_WQCF *)&sc->sc_vsreg->sh_MCE_IOPB; + u_short i, crsw; + int failed = 0; + + CRB_CLR_DONE(CRSW); + vs_zero(cib, sizeof(M328_CIB)); + mcsb->mcsb_QHDP = 0; + sc->sc_qhp = 0; + cib->cib_NCQE = 10; + cib->cib_BURST = 0; + cib->cib_NVECT = sc->sc_ipl << 8; + cib->cib_NVECT |= sc->sc_nvec; + cib->cib_EVECT = sc->sc_ipl << 8; + cib->cib_EVECT |= sc->sc_evec; + cib->cib_PID = 0x07; + cib->cib_SID = 0x00; + cib->cib_CRBO = OFF(crb); + cib->cib_SELECT_msw = HI(SELECTION_TIMEOUT); + cib->cib_SELECT_lsw = LO(SELECTION_TIMEOUT); + cib->cib_WQ0TIMO_msw = HI(4); + cib->cib_WQ0TIMO_lsw = LO(4); + cib->cib_VMETIMO_msw = 0; /*HI(VME_BUS_TIMEOUT);*/ + cib->cib_VMETIMO_lsw = 0; /*LO(VME_BUS_TIMEOUT);*/ + cib->cib_ERR_FLGS = M_ERRFLGS_RIN | M_ERRFLGS_RSE; + cib->cib_SBRIV = sc->sc_ipl << 8; + cib->cib_SBRIV |= sc->sc_evec; + cib->cib_SOF0 = 0x15; + cib->cib_SRATE0 = 100/4; + cib->cib_SOF1 = 0x0; + cib->cib_SRATE1 = 0x0; + + iopb = (M328_IOPB *)&sc->sc_vsreg->sh_MCE_IOPB; + vs_zero(iopb, sizeof(M328_IOPB)); + iopb->iopb_CMD = CNTR_INIT; + iopb->iopb_OPTION = 0; + iopb->iopb_NVCT = (u_char)sc->sc_nvec; + iopb->iopb_EVCT = (u_char)sc->sc_evec; + iopb->iopb_LEVEL = 0; /*sc->sc_ipl;*/ + iopb->iopb_ADDR = SHIO_MOD; + LV(iopb->iopb_BUFF, OFF(cib)); + LV(iopb->iopb_LENGTH, sizeof(M328_CIB)); + + vs_zero(mc, sizeof(M328_CQE)); + mc->cqe_IOPB_ADDR = OFF(iopb); + mc->cqe_IOPB_LENGTH = sizeof(M328_IOPB); + mc->cqe_WORK_QUEUE = 0; + mc->cqe_QECR = M_QECR_GO; + /* poll for the command to complete */ + do_vspoll(sc, 0); + CRB_CLR_DONE(CRSW); + + /* initialize work queues */ + for (i=1; i<8; i++) { + vs_zero(wiopb, sizeof(M328_IOPB)); + wiopb->wqcf_CMD = CNTR_INIT_WORKQ; + wiopb->wqcf_OPTION = 0; + wiopb->wqcf_NVCT = (u_char)sc->sc_nvec; + wiopb->wqcf_EVCT = (u_char)sc->sc_evec; + wiopb->wqcf_ILVL = 0; /*sc->sc_ipl;*/ + wiopb->wqcf_WORKQ = i; + wiopb->wqcf_WOPT = (WQO_FOE | WQO_INIT); + wiopb->wqcf_SLOTS = JAGUAR_MAX_Q_SIZ; + LV(wiopb->wqcf_CMDTO, 4); /* 1 second */ + + vs_zero(mc, sizeof(M328_CQE)); + mc->cqe_IOPB_ADDR = OFF(wiopb); + mc->cqe_IOPB_LENGTH = sizeof(M328_IOPB); + mc->cqe_WORK_QUEUE = 0; + mc->cqe_QECR = M_QECR_GO; + /* poll for the command to complete */ + do_vspoll(sc, 0); + if (CRSW & M_CRSW_ER) { + /*printf("\nerror: queue %d status = 0x%x\n", i, riopb->iopb_STATUS);*/ + /*failed = 1;*/ + CRB_CLR_ER(CRSW); + } + CRB_CLR_DONE(CRSW); + delay(500); + } + /* start queue mode */ + CRSW = 0; + mcsb->mcsb_MCR |= M_MCR_SQM; + crsw = CRSW; + do_vspoll(sc, 0); + if (CRSW & M_CRSW_ER) { + printf("error: status = 0x%x\n", riopb->iopb_STATUS); + CRB_CLR_ER(CRSW); + } + CRB_CLR_DONE(CRSW); + + if (failed) { + printf(": failed!\n"); + return (1); + } + /* reset SCSI bus */ + vs_reset(sc); + /* sync all devices */ + vs_resync(sc); + printf(": target %d\n", sc->sc_link.adapter_target); + return (0); /* success */ } void vs_resync(sc) struct vs_softc *sc; { - M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; - M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; - M328_DRCF *devreset = (M328_DRCF *)&sc->sc_vsreg->sh_MCE_IOPB; - u_short i; - - for (i=0; i<7; i++) { - szero(devreset, sizeof(M328_DRCF)); - devreset->drcf_CMD = CNTR_DEV_REINIT; - devreset->drcf_OPTION = 0x00; /* no interrupts yet... */ - devreset->drcf_NVCT = sc->sc_nvec; - devreset->drcf_EVCT = sc->sc_evec; - devreset->drcf_ILVL = 0; - devreset->drcf_UNIT = i; - - szero(mc, sizeof(M328_CQE)); - mc->cqe_IOPB_ADDR = OFF(devreset); - mc->cqe_IOPB_LENGTH = sizeof(M328_DRCF); - mc->cqe_WORK_QUEUE = 0; - mc->cqe_QECR = M_QECR_GO; - /* poll for the command to complete */ - do_vspoll(sc, 0); - if (riopb->iopb_STATUS) { - sc->sc_tinfo[i].avail = 0; - } else { - sc->sc_tinfo[i].avail = 1; - } - if (CRSW & M_CRSW_ER) { - CRB_CLR_ER(CRSW); - } - CRB_CLR_DONE(CRSW); - } + M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + M328_DRCF *devreset = (M328_DRCF *)&sc->sc_vsreg->sh_MCE_IOPB; + u_short i; + for (i=0; i<7; i++) { + vs_zero(devreset, sizeof(M328_DRCF)); + devreset->drcf_CMD = CNTR_DEV_REINIT; + devreset->drcf_OPTION = 0x00; /* no interrupts yet... */ + devreset->drcf_NVCT = sc->sc_nvec; + devreset->drcf_EVCT = sc->sc_evec; + devreset->drcf_ILVL = 0; + devreset->drcf_UNIT = i; + + vs_zero(mc, sizeof(M328_CQE)); + mc->cqe_IOPB_ADDR = OFF(devreset); + mc->cqe_IOPB_LENGTH = sizeof(M328_DRCF); + mc->cqe_WORK_QUEUE = 0; + mc->cqe_QECR = M_QECR_GO; + /* poll for the command to complete */ + do_vspoll(sc, 0); + if (riopb->iopb_STATUS) { +#ifdef SDEBUG + printf("status: %x\n", riopb->iopb_STATUS); +#endif + sc->sc_tinfo[i].avail = 0; + } else { + sc->sc_tinfo[i].avail = 1; + } + if (CRSW & M_CRSW_ER) { + CRB_CLR_ER(CRSW); + } + CRB_CLR_DONE(CRSW); + } } void vs_reset(sc) struct vs_softc *sc; { - struct vsreg * rp; - u_int s; - u_char i; - struct iopb_reset* iopr; - struct cqe *cqep; - struct iopb_scsi *iopbs; - struct scsi_sense *ss; - M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB; - M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; - M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; - M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; - M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; - M328_SRCF *reset = (M328_SRCF *)&sc->sc_vsreg->sh_MCE_IOPB; - M328_IOPB *iopb; - - szero(reset, sizeof(M328_SRCF)); - reset->srcf_CMD = IOPB_RESET; - reset->srcf_OPTION = 0x00; /* no interrupts yet... */ - reset->srcf_NVCT = sc->sc_nvec; - reset->srcf_EVCT = sc->sc_evec; - reset->srcf_ILVL = 0; - reset->srcf_BUSID = 0; - s = splbio(); - - szero(mc, sizeof(M328_CQE)); - mc->cqe_IOPB_ADDR = OFF(reset); - mc->cqe_IOPB_LENGTH = sizeof(M328_SRCF); - mc->cqe_WORK_QUEUE = 0; - mc->cqe_QECR = M_QECR_GO; - /* poll for the command to complete */ - while (1) { - do_vspoll(sc, 0); - /* ack & clear scsi error condition cause by reset */ - if (CRSW & M_CRSW_ER) { - CRB_CLR_ER(CRSW); - CRB_CLR_DONE(CRSW); - riopb->iopb_STATUS = 0; - break; - } - CRB_CLR_DONE(CRSW); - } - /* thaw all work queues */ - thaw_queue(sc, 0xFF); - splx (s); + struct vsreg * rp; + u_int s; + u_char i; + struct iopb_reset* iopr; + struct cqe *cqep; + struct iopb_scsi *iopbs; + struct scsi_sense *ss; + M328_CIB *cib = (M328_CIB *)&sc->sc_vsreg->sh_CIB; + M328_CQE *mc = (M328_CQE*)&sc->sc_vsreg->sh_MCE; + M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + M328_MCSB *mcsb = (M328_MCSB *)&sc->sc_vsreg->sh_MCSB; + M328_SRCF *reset = (M328_SRCF *)&sc->sc_vsreg->sh_MCE_IOPB; + M328_IOPB *iopb; + + vs_zero(reset, sizeof(M328_SRCF)); + reset->srcf_CMD = IOPB_RESET; + reset->srcf_OPTION = 0x00; /* no interrupts yet... */ + reset->srcf_NVCT = sc->sc_nvec; + reset->srcf_EVCT = sc->sc_evec; + reset->srcf_ILVL = 0; + reset->srcf_BUSID = 0; + s = splbio(); + + vs_zero(mc, sizeof(M328_CQE)); + mc->cqe_IOPB_ADDR = OFF(reset); + mc->cqe_IOPB_LENGTH = sizeof(M328_SRCF); + mc->cqe_WORK_QUEUE = 0; + mc->cqe_QECR = M_QECR_GO; + /* poll for the command to complete */ + while (1) { + do_vspoll(sc, 0); + /* ack & clear scsi error condition cause by reset */ + if (CRSW & M_CRSW_ER) { + CRB_CLR_ER(CRSW); + CRB_CLR_DONE(CRSW); + riopb->iopb_STATUS = 0; + break; + } + CRB_CLR_DONE(CRSW); + } + /* thaw all work queues */ + thaw_queue(sc, 0xFF); + splx (s); } - /* * Process an interrupt from the MVME328 * We'll generally update: xs->{flags,resid,error,sense,status} and @@ -699,134 +712,233 @@ struct vs_softc *sc; struct scsi_xfer *xs; int *status; { - struct vsreg * rp = sc->sc_vsreg; - int target = -1; - int lun = -1; - M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; - M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; - struct scsi_generic *cmd; - u_long buf; - u_long len; - u_char error; - - target = xs->sc_link->target; - lun = xs->sc_link->lun; - cmd = (struct scsi_generic *)&riopb->iopb_SCSI[0]; - - VL(buf, riopb->iopb_BUFF); - VL(len, riopb->iopb_LENGTH); - *status = riopb->iopb_STATUS >> 8; - error = riopb->iopb_STATUS & 0xFF; + struct vsreg * rp = sc->sc_vsreg; + int target = -1; + int lun = -1; + M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + struct scsi_generic *cmd; + u_long buf; + u_long len; + u_char error; + + target = xs->sc_link->target; + lun = xs->sc_link->lun; + cmd = (struct scsi_generic *)&riopb->iopb_SCSI[0]; + + VL(buf, riopb->iopb_BUFF); + VL(len, riopb->iopb_LENGTH); + *status = riopb->iopb_STATUS >> 8; + error = riopb->iopb_STATUS & 0xFF; #ifdef SDEBUG - printf("scsi_chk() "); - - if (xs->cmd->opcode == 0) { - printf("TEST_UNIT_READY "); - } else if (xs->cmd->opcode == REQUEST_SENSE) { - printf("REQUEST_SENSE "); - } else if (xs->cmd->opcode == INQUIRY) { - printf("INQUIRY "); - } else if (xs->cmd->opcode == MODE_SELECT) { - printf("MODE_SELECT "); - } else if (xs->cmd->opcode == MODE_SENSE) { - printf("MODE_SENSE "); - } else if (xs->cmd->opcode == START_STOP) { - printf("START_STOP "); - } else if (xs->cmd->opcode == RESERVE) { - printf("RESERVE "); - } else if (xs->cmd->opcode == RELEASE) { - printf("RELEASE "); - } else if (xs->cmd->opcode == PREVENT_ALLOW) { - printf("PREVENT_ALLOW "); - } else if (xs->cmd->opcode == POSITION_TO_ELEMENT) { - printf("POSITION_TO_EL "); - } else if (xs->cmd->opcode == CHANGE_DEFINITION) { - printf("CHANGE_DEF "); - } else if (xs->cmd->opcode == MODE_SENSE_BIG) { - printf("MODE_SENSE_BIG "); - } else if (xs->cmd->opcode == MODE_SELECT_BIG) { - printf("MODE_SELECT_BIG "); - } else if (xs->cmd->opcode == 0x25) { - printf("READ_CAPACITY "); - } else if (xs->cmd->opcode == 0x08) { - printf("READ_COMMAND "); - } - - printf("tgt %d lun %d buf %x len %d status %x ", target, lun, buf, len, riopb->iopb_STATUS); - - if (CRSW & M_CRSW_EX) { - printf("[ex]"); - } - if (CRSW & M_CRSW_QMS) { - printf("[qms]"); - } - if (CRSW & M_CRSW_SC) { - printf("[sc]"); - } - if (CRSW & M_CRSW_SE) { - printf("[se]"); - } - if (CRSW & M_CRSW_AQ) { - printf("[aq]"); - } - if (CRSW & M_CRSW_ER) { - printf("[er]"); - } - printf("\n"); + printf("scsi_chk() "); + + if (xs->cmd->opcode == 0) { + printf("TEST_UNIT_READY "); + } else if (xs->cmd->opcode == REQUEST_SENSE) { + printf("REQUEST_SENSE "); + } else if (xs->cmd->opcode == INQUIRY) { + printf("INQUIRY "); + } else if (xs->cmd->opcode == MODE_SELECT) { + printf("MODE_SELECT "); + } else if (xs->cmd->opcode == MODE_SENSE) { + printf("MODE_SENSE "); + } else if (xs->cmd->opcode == START_STOP) { + printf("START_STOP "); + } else if (xs->cmd->opcode == RESERVE) { + printf("RESERVE "); + } else if (xs->cmd->opcode == RELEASE) { + printf("RELEASE "); + } else if (xs->cmd->opcode == PREVENT_ALLOW) { + printf("PREVENT_ALLOW "); + } else if (xs->cmd->opcode == POSITION_TO_ELEMENT) { + printf("POSITION_TO_EL "); + } else if (xs->cmd->opcode == CHANGE_DEFINITION) { + printf("CHANGE_DEF "); + } else if (xs->cmd->opcode == MODE_SENSE_BIG) { + printf("MODE_SENSE_BIG "); + } else if (xs->cmd->opcode == MODE_SELECT_BIG) { + printf("MODE_SELECT_BIG "); + } else if (xs->cmd->opcode == 0x25) { + printf("READ_CAPACITY "); + } else if (xs->cmd->opcode == 0x08) { + printf("READ_COMMAND "); + } + + printf("tgt %d lun %d buf %x len %d status %x ", target, lun, buf, len, riopb->iopb_STATUS); + + if (CRSW & M_CRSW_EX) { + printf("[ex]"); + } + if (CRSW & M_CRSW_QMS) { + printf("[qms]"); + } + if (CRSW & M_CRSW_SC) { + printf("[sc]"); + } + if (CRSW & M_CRSW_SE) { + printf("[se]"); + } + if (CRSW & M_CRSW_AQ) { + printf("[aq]"); + } + if (CRSW & M_CRSW_ER) { + printf("[er]"); + } + printf("\n"); #endif - if (len != xs->datalen) { - xs->resid = xs->datalen - len; - } else { - xs->resid = 0; - } - - if (error == SCSI_SELECTION_TO) { - xs->error = XS_SELTIMEOUT; - xs->status = -1; - *status = -1; - } - return 1; + if (len != xs->datalen) { + xs->resid = xs->datalen - len; + } else { + xs->resid = 0; + } + + if (error == SCSI_SELECTION_TO) { + xs->error = XS_SELTIMEOUT; + xs->status = -1; + *status = -1; + } + return 1; } +/* normal interrupt routine */ int -vs_intr (sc) +vs_nintr(sc) register struct vs_softc *sc; { - M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; - struct scsi_xfer *xs; - M328_CMD *m328_cmd; - unsigned long loc; - int status; - int s; - s = splbio(); - /* Got a valid interrupt on this device */ - - VL(loc, crb->crb_CTAG); + M328_CRB *crb = (M328_CRB *)&sc->sc_vsreg->sh_CRB; + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + M328_CMD *m328_cmd; + struct scsi_xfer *xs; + int status; + int s; + + if ((CRSW & CONTROLLER_ERROR) == CONTROLLER_ERROR) + return(vs_eintr(sc)); + + s = splbio(); + /* Got a valid interrupt on this device */ + sc->sc_intrcnt_n.ev_count++; + + VL((unsigned long)m328_cmd, crb->crb_CTAG); #ifdef SDEBUG - printf("Interrupt!!! "); - printf("loc == 0x%x\n", loc); + printf("Interrupt!!! "); + printf("m328_cmd == 0x%x\n", m328_cmd); #endif - /* - * If this is a controller error, there won't be a m328_cmd - * pointer in the CTAG feild. Bad things happen if you try - * to point to address 0. Controller error should be handeled - * in vsdma.c I'll change this soon - steve. - */ - if (loc) { - m328_cmd = (M328_CMD *)loc; - xs = m328_cmd->xs; - if (m328_cmd->top_sg_list) { - vs_dealloc_scatter_gather(m328_cmd->top_sg_list); - m328_cmd->top_sg_list = (M328_SG)0; - } - - FREE(m328_cmd, M_DEVBUF); /* free the command tag */ - if (vs_checkintr (sc, xs, &status)) { - vs_scsidone(xs, status); - } - } - splx(s); + /* + * If this is a controller error, there won't be a m328_cmd + * pointer in the CTAG feild. Bad things happen if you try + * to point to address 0. Controller error should be handeled + * in vsdma.c I'll change this soon - steve. + */ + if (m328_cmd) { + xs = m328_cmd->xs; + if (m328_cmd->top_sg_list) { + vs_dealloc_scatter_gather(m328_cmd->top_sg_list); + m328_cmd->top_sg_list = (M328_SG)0; + } + FREE(m328_cmd, M_DEVBUF); /* free the command tag */ + if (vs_checkintr(sc, xs, &status)) { + vs_scsidone(sc, xs, status); + } + } + /* ack the interrupt */ + if (CRSW & M_CRSW_ER) + CRB_CLR_ER(CRSW); + CRB_CLR_DONE(CRSW); + /* clear the return information */ + vs_clear_return_info(sc); + splx(s); + return (1); +} + +int +vs_eintr(sc) +register struct vs_softc *sc; +{ + M328_CEVSB *crb = (M328_CEVSB *)&sc->sc_vsreg->sh_CRB; + M328_CMD *m328_cmd; + struct scsi_xfer *xs; + int crsw = crb->cevsb_CRSW; + int type = crb->cevsb_TYPE; + int length = crb->cevsb_IOPB_LENGTH; + int wq = crb->cevsb_WORK_QUEUE; + int ecode = crb->cevsb_ERROR; + int status, s; + + s = splbio(); + + /* Got a valid interrupt on this device */ + sc->sc_intrcnt_e.ev_count++; + + VL((unsigned long)m328_cmd, crb->cevsb_CTAG); +#ifdef SDEBUG + printf("Error Interrupt!!! "); + printf("m328_cmd == 0x%x\n", m328_cmd); +#endif + xs = m328_cmd->xs; + + if (crsw & M_CRSW_RST) { + printf("%s: SCSI Bus Reset!\n", vs_name(sc)); + /* clear the return information */ + vs_clear_return_info(sc); + splx(s); + return(1); + } + switch (ecode) { + case CEVSB_ERR_TYPE: + printf("%s: IOPB Type error!\n", vs_name(sc)); + break; + case CEVSB_ERR_TO: + printf("%s: Timeout!\n", vs_name(sc)); + xs->error = XS_SELTIMEOUT; + xs->status = -1; + xs->flags |= ITSDONE; + status = -1; + scsi_done(xs); + break; + case CEVSB_ERR_TR: /* Target Reconnect, no IOPB */ + printf("%s: Target Reconnect error!\n", vs_name(sc)); + break; + case CEVSB_ERR_OF: /* Overflow */ + printf("%s: Overflow error!\n", vs_name(sc)); + break; + case CEVSB_ERR_BD: /* Bad direction */ + printf("%s: Bad Direction!\n", vs_name(sc)); + break; + case CEVSB_ERR_NR: /* Non-Recoverabl Error */ + printf("%s: Non-Recoverable error!\n", vs_name(sc)); + break; + case CESVB_ERR_PANIC: /* Board Painc!!! */ + printf("%s: Board Painc!!!\n", vs_name(sc)); + break; + default: + printf("%s: Uh oh!... Error 0x%x\n", vs_name(sc), ecode); + Debugger(); + } +#ifdef SDEBUG + printf("%s: crsw = 0x%x iopb_type = %d iopb_len = %d wq = %d error = 0x%x\n", + vs_name(sc), crsw, type, length, wq, ecode); +#endif + if (CRSW & M_CRSW_ER) + CRB_CLR_ER(CRSW); + CRB_CLR_DONE(CRSW); + thaw_queue(sc, 0xFF); + /* clear the return information */ + vs_clear_return_info(sc); + splx(s); + return(1); +} + +static __inline__ void +vs_clear_return_info(sc) +register struct vs_softc *sc; +{ + M328_IOPB *riopb = (M328_IOPB *)&sc->sc_vsreg->sh_RET_IOPB; + M328_CEVSB *crb = (M328_CEVSB *)&sc->sc_vsreg->sh_CRB; + vs_zero(riopb, sizeof(M328_IOPB)); + vs_zero(crb, sizeof(M328_CEVSB)); } /* @@ -836,190 +948,190 @@ register struct vs_softc *sc; M328_SG vs_alloc_scatter_gather(void) { - M328_SG sg; + M328_SG sg; - MALLOC(sg, M328_SG, sizeof(struct m328_sg), M_DEVBUF, M_WAITOK); - assert ( sg ); - if ( !sg ) { - panic ("Memory for scatter_gather_list not available"); - } - bzero(sg, sizeof(struct m328_sg)); + MALLOC(sg, M328_SG, sizeof(struct m328_sg), M_DEVBUF, M_WAITOK); + assert ( sg ); + if ( !sg ) { + panic ("Memory for scatter_gather_list not available"); + } + bzero(sg, sizeof(struct m328_sg)); - return (sg); + return (sg); } void -vs_dealloc_scatter_gather(M328_SG sg) +vs_dealloc_scatter_gather(sg) +M328_SG sg; { - register int i; - - if (sg->level > 0) { - for (i=0; sg->down[i] && i<MAX_SG_ELEMENTS; i++) { - vs_dealloc_scatter_gather(sg->down[i]); - } - } - FREE(sg, M_DEVBUF); + register int i; + + if (sg->level > 0) { + for (i=0; sg->down[i] && i<MAX_SG_ELEMENTS; i++) { + vs_dealloc_scatter_gather(sg->down[i]); + } + } + FREE(sg, M_DEVBUF); } void -vs_link_sg_element(sg_list_element_t * element, - register vm_offset_t phys_add, - register int len) +vs_link_sg_element(element, phys_add, len) +sg_list_element_t *element; +register vm_offset_t phys_add; +register int len; { - element->count.bytes = len; - LV(element->address, phys_add); - element->link = 0; /* FALSE */ - element->transfer_type = NORMAL_TYPE; - element->memory_type = LONG_TRANSFER; - element->address_modifier = 0xD; + element->count.bytes = len; + LV(element->address, phys_add); + element->link = 0; /* FALSE */ + element->transfer_type = NORMAL_TYPE; + element->memory_type = LONG_TRANSFER; + element->address_modifier = 0xD; } void -vs_link_sg_list(sg_list_element_t * list, - register vm_offset_t phys_add, - register int elements) +vs_link_sg_list(list, phys_add, elements) +sg_list_element_t *list; +register vm_offset_t phys_add; +register int elements; { - list->count.scatter.gather = elements; - LV(list->address, phys_add); - list->link = 1; /* TRUE */ - list->transfer_type = NORMAL_TYPE; - list->memory_type = LONG_TRANSFER; - list->address_modifier = 0xD; + list->count.scatter.gather = elements; + LV(list->address, phys_add); + list->link = 1; /* TRUE */ + list->transfer_type = NORMAL_TYPE; + list->memory_type = LONG_TRANSFER; + list->address_modifier = 0xD; } - M328_SG vs_build_memory_structure(xs, iopb) struct scsi_xfer *xs; -M328_IOPB *iopb; /* the iopb */ +M328_IOPB *iopb; /* the iopb */ { - M328_SG sg; - vm_offset_t starting_point_virt, starting_point_phys, point_virt, - point1_phys, point2_phys, virt; - unsigned len; - int level; - - sg = (M328_SG)0; /* Hopefully we need no scatter/gather list */ - - /* - * We have the following things: - * virt the virtuell address of the contiguous virtual memory block - * len the lenght of the contiguous virtual memory block - * starting_point_virt the virtual address of the contiguous *physical* memory block - * starting_point_phys the *physical* address of the contiguous *physical* memory block - * point_virt the pointer to the virtual memory we are checking at the moment - * point1_phys the pointer to the *physical* memory we are checking at the moment - * point2_phys the pointer to the *physical* memory we are checking at the moment - */ - - level = 0; - virt = starting_point_virt = (vm_offset_t)xs->data; - point1_phys = starting_point_phys = kvtop(xs->data); - len = xs->datalen; - /* - * Check if we need scatter/gather - */ - - if (len > PAGESIZE) { - for (level = 0, point_virt = ROUND_PAGE(starting_point_virt+1); - /* if we do already scatter/gather we have to stay in the loop and jump */ - point_virt < virt + (vm_offset_t)len || sg ; - point_virt += PAGESIZE) { /* out later */ - - point2_phys = kvtop(point_virt); - - if ((point2_phys - TRUNC_PAGE(point1_phys) - PAGESIZE) || /* physical memory is not contiguous */ - (point_virt - starting_point_virt >= MAX_SG_BLOCK_SIZE && sg)) { /* we only can access (1<<16)-1 bytes in scatter/gather_mode */ - if (point_virt - starting_point_virt >= MAX_SG_BLOCK_SIZE) { /* We were walking too far for one scatter/gather block ... */ - assert( MAX_SG_BLOCK_SIZE > PAGESIZE ); - point_virt = TRUNC_PAGE(starting_point_virt+MAX_SG_BLOCK_SIZE-1); /* So go back to the beginning of the last matching page */ - /* and gererate the physadress of this location for the next time. */ - point2_phys = kvtop(point_virt); - } - - if (!sg) { - /* We allocate our fist scatter/gather list */ - sg = vs_alloc_scatter_gather(); - } + M328_SG sg; + vm_offset_t starting_point_virt, starting_point_phys, point_virt, + point1_phys, point2_phys, virt; + unsigned len; + int level; + + sg = (M328_SG)0; /* Hopefully we need no scatter/gather list */ + + /* + * We have the following things: + * virt the virtuell address of the contiguous virtual memory block + * len the lenght of the contiguous virtual memory block + * starting_point_virt the virtual address of the contiguous *physical* memory block + * starting_point_phys the *physical* address of the contiguous *physical* memory block + * point_virt the pointer to the virtual memory we are checking at the moment + * point1_phys the pointer to the *physical* memory we are checking at the moment + * point2_phys the pointer to the *physical* memory we are checking at the moment + */ + + level = 0; + virt = starting_point_virt = (vm_offset_t)xs->data; + point1_phys = starting_point_phys = kvtop(xs->data); + len = xs->datalen; + /* + * Check if we need scatter/gather + */ + + if (len > PAGESIZE) { + for (level = 0, point_virt = ROUND_PAGE(starting_point_virt+1); + /* if we do already scatter/gather we have to stay in the loop and jump */ + point_virt < virt + (vm_offset_t)len || sg ; + point_virt += PAGESIZE) { /* out later */ + + point2_phys = kvtop(point_virt); + + if ((point2_phys - TRUNC_PAGE(point1_phys) - PAGESIZE) || /* physical memory is not contiguous */ + (point_virt - starting_point_virt >= MAX_SG_BLOCK_SIZE && sg)) { /* we only can access (1<<16)-1 bytes in scatter/gather_mode */ + if (point_virt - starting_point_virt >= MAX_SG_BLOCK_SIZE) { /* We were walking too far for one scatter/gather block ... */ + assert( MAX_SG_BLOCK_SIZE > PAGESIZE ); + point_virt = TRUNC_PAGE(starting_point_virt+MAX_SG_BLOCK_SIZE-1); /* So go back to the beginning of the last matching page */ + /* and gererate the physadress of this location for the next time. */ + point2_phys = kvtop(point_virt); + } + + if (!sg) { + /* We allocate our fist scatter/gather list */ + sg = vs_alloc_scatter_gather(); + } #if 1 /* broken firmware */ - if (sg->elements >= MAX_SG_ELEMENTS) { - vs_dealloc_scatter_gather(sg); - return (NULL); - } + if (sg->elements >= MAX_SG_ELEMENTS) { + vs_dealloc_scatter_gather(sg); + return (NULL); + } #else /* if the firmware will ever get fixed */ - while (sg->elements >= MAX_SG_ELEMENTS) { - if (!sg->up) { /* If the list full in this layer ? */ - sg->up = vs_alloc_scatter_gather(); - sg->up->level = sg->level+1; - sg->up->down[0] = sg; - sg->up->elements = 1; - } - /* link this full list also in physical memory */ - vs_link_sg_list(&(sg->up->list[sg->up->elements-1]), - kvtop((vm_offset_t)sg->list), - sg->elements); - sg = sg->up; /* Climb up */ - } - while (sg->level) { /* As long as we are not a the base level */ - register int i; - - i = sg->elements; - /* We need a new element */ - sg->down[i] = vs_alloc_scatter_gather(); - sg->down[i]->level = sg->level - 1; - sg->down[i]->up = sg; - sg->elements++; - sg = sg->down[i]; /* Climb down */ - } + while (sg->elements >= MAX_SG_ELEMENTS) { + if (!sg->up) { /* If the list full in this layer ? */ + sg->up = vs_alloc_scatter_gather(); + sg->up->level = sg->level+1; + sg->up->down[0] = sg; + sg->up->elements = 1; + } + /* link this full list also in physical memory */ + vs_link_sg_list(&(sg->up->list[sg->up->elements-1]), + kvtop((vm_offset_t)sg->list), + sg->elements); + sg = sg->up; /* Climb up */ + } + while (sg->level) { /* As long as we are not a the base level */ + register int i; + + i = sg->elements; + /* We need a new element */ + sg->down[i] = vs_alloc_scatter_gather(); + sg->down[i]->level = sg->level - 1; + sg->down[i]->up = sg; + sg->elements++; + sg = sg->down[i]; /* Climb down */ + } #endif /* 1 */ - - if (point_virt < virt+(vm_offset_t)len) { - /* linking element */ - vs_link_sg_element(&(sg->list[sg->elements]), - starting_point_phys, - point_virt-starting_point_virt); - sg->elements++; - } else { - /* linking last element */ - vs_link_sg_element(&(sg->list[sg->elements]), - starting_point_phys, - (vm_offset_t)(virt+len)-starting_point_virt); - sg->elements++; - break; /* We have now collected all blocks */ - } - starting_point_virt = point_virt; - starting_point_phys = point2_phys; - } - point1_phys = point2_phys; - } - } - - /* - * Climb up along the right side of the tree until we reach the top. - */ - - if (sg) { - while (sg->up) { - /* link this list also in physical memory */ - vs_link_sg_list(&(sg->up->list[sg->up->elements-1]), - kvtop((vm_offset_t)sg->list), - sg->elements); - sg = sg->up; /* Climb up */ - } - - iopb->iopb_OPTION |= M_OPT_SG; - iopb->iopb_ADDR |= M_ADR_SG_LINK; - LV(iopb->iopb_BUFF, kvtop((vm_offset_t)sg->list)); - LV(iopb->iopb_LENGTH, sg->elements); - LV(iopb->iopb_SGTTL, len); - } else { - /* no scatter/gather neccessary */ - LV(iopb->iopb_BUFF, starting_point_phys); - LV(iopb->iopb_LENGTH, len); - } - return (sg); + if (point_virt < virt+(vm_offset_t)len) { + /* linking element */ + vs_link_sg_element(&(sg->list[sg->elements]), + starting_point_phys, + point_virt-starting_point_virt); + sg->elements++; + } else { + /* linking last element */ + vs_link_sg_element(&(sg->list[sg->elements]), + starting_point_phys, + (vm_offset_t)(virt+len)-starting_point_virt); + sg->elements++; + break; /* We have now collected all blocks */ + } + starting_point_virt = point_virt; + starting_point_phys = point2_phys; + } + point1_phys = point2_phys; + } + } + + /* + * Climb up along the right side of the tree until we reach the top. + */ + + if (sg) { + while (sg->up) { + /* link this list also in physical memory */ + vs_link_sg_list(&(sg->up->list[sg->up->elements-1]), + kvtop((vm_offset_t)sg->list), + sg->elements); + sg = sg->up; /* Climb up */ + } + + iopb->iopb_OPTION |= M_OPT_SG; + iopb->iopb_ADDR |= M_ADR_SG_LINK; + LV(iopb->iopb_BUFF, kvtop((vm_offset_t)sg->list)); + LV(iopb->iopb_LENGTH, sg->elements); + LV(iopb->iopb_SGTTL, len); + } else { + /* no scatter/gather neccessary */ + LV(iopb->iopb_BUFF, starting_point_phys); + LV(iopb->iopb_LENGTH, len); + } + return (sg); } - diff --git a/sys/arch/mvme88k/dev/vsdma.c b/sys/arch/mvme88k/dev/vsdma.c index ce15c791b55..1b7819f780a 100644 --- a/sys/arch/mvme88k/dev/vsdma.c +++ b/sys/arch/mvme88k/dev/vsdma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vsdma.c,v 1.2 1999/09/27 18:43:26 smurph Exp $ */ +/* $OpenBSD: vsdma.c,v 1.3 2001/02/01 03:38:16 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * All rights reserved. @@ -51,20 +51,19 @@ #include <mvme88k/dev/vsreg.h> #include <mvme88k/dev/vsvar.h> #include <mvme88k/dev/vme.h> -#include "machine/mmu.h" #else #include <mvme68k/dev/vsreg.h> #include <mvme68k/dev/vsvar.h> #include <mvme68k/dev/vme.h> #endif /* defined(MVME187) */ -int vsmatch __P((struct device *, void *, void *)); -void vsattach __P((struct device *, struct device *, void *)); -int vsprint __P((void *auxp, char *)); -void vs_initialize __P((struct vs_softc *)); -int vs_intr __P((struct vs_softc *)); -int vs_nintr __P((struct vs_softc *)); -int vs_eintr __P((struct vs_softc *)); +int vsmatch __P((struct device *, void *, void *)); +void vsattach __P((struct device *, struct device *, void *)); +int vsprint __P((void *auxp, char *)); +int vs_initialize __P((struct vs_softc *)); +int vs_intr __P((struct vs_softc *)); +int vs_nintr __P((struct vs_softc *)); +int vs_eintr __P((struct vs_softc *)); struct scsi_adapter vs_scsiswitch = { vs_scsicmd, @@ -81,37 +80,31 @@ struct scsi_device vs_scsidev = { }; struct cfattach vs_ca = { - sizeof(struct vs_softc), vsmatch, vsattach, + sizeof(struct vs_softc), vsmatch, vsattach, }; - + struct cfdriver vs_cd = { - NULL, "vs", DV_DULL, 0 + NULL, "vs", DV_DULL, 0 }; int vsmatch(pdp, vcf, args) - struct device *pdp; - void *vcf, *args; +struct device *pdp; +void *vcf, *args; { struct cfdata *cf = vcf; struct confargs *ca = args; if (!badvaddr(ca->ca_vaddr, 1)) { - /* - if (ca->ca_vec & 0x03) { - printf("vs: bad vector 0x%x\n", ca->ca_vec); - return (0); - } - */ - return(1); - } else { + return (1); + } else { return (0); - } + } } void vsattach(parent, self, auxp) - struct device *parent, *self; - void *auxp; +struct device *parent, *self; +void *auxp; { struct vs_softc *sc = (struct vs_softc *)self; struct confargs *ca = auxp; @@ -122,9 +115,10 @@ vsattach(parent, self, auxp) sc->sc_vsreg = rp = ca->ca_vaddr; sc->sc_ipl = ca->ca_ipl; - sc->sc_nvec = ca->ca_vec + 0; - sc->sc_evec = ca->ca_vec + 1; - sc->sc_link.adapter_softc = sc; + sc->sc_nvec = ca->ca_vec; + /* get the next available vector for the error interrupt func. */ + sc->sc_evec = vme_findvec(); + sc->sc_link.adapter_softc = sc; sc->sc_link.adapter_target = 7; sc->sc_link.adapter = &vs_scsiswitch; sc->sc_link.device = &vs_scsidev; @@ -133,28 +127,28 @@ vsattach(parent, self, auxp) sc->sc_ih_n.ih_fn = vs_nintr; sc->sc_ih_n.ih_arg = sc; sc->sc_ih_n.ih_ipl = ca->ca_ipl; - - - sc->sc_ih_e.ih_fn = vs_eintr; + + sc->sc_ih_e.ih_fn = vs_eintr; sc->sc_ih_e.ih_arg = sc; sc->sc_ih_e.ih_ipl = ca->ca_ipl; - - vs_initialize(sc); + + if (vs_initialize(sc)) + return; vmeintr_establish(sc->sc_nvec, &sc->sc_ih_n); vmeintr_establish(sc->sc_evec, &sc->sc_ih_e); - evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt_n); - evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt_e); + evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt_n); + evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt_e); /* * attach all scsi units on us, watching for boot device * (see dk_establish). */ tmp = bootpart; - if (ca->ca_paddr != bootaddr) - bootpart = -1; /* invalid flag to dk_establish */ + if (ca->ca_paddr != bootaddr) + bootpart = -1; /* invalid flag to dk_establish */ config_found(self, &sc->sc_link, scsiprint); - bootpart = tmp; /* restore old value */ + bootpart = tmp; /* restore old value */ } /* @@ -162,38 +156,10 @@ vsattach(parent, self, auxp) */ int vsprint(auxp, pnp) - void *auxp; - char *pnp; +void *auxp; +char *pnp; { if (pnp == NULL) return (UNCONF); return (QUIET); } - -/* normal interrupt function */ -int -vs_nintr(sc) - struct vs_softc *sc; -{ -#ifdef SDEBUG - printf("Normal Interrupt!!!\n"); -#endif - vs_intr(sc); - sc->sc_intrcnt_n.ev_count++; - return (1); -} - -/* error interrupt function */ -int -vs_eintr(sc) - struct vs_softc *sc; -{ -#ifdef SDEBUG - printf("Error Interrupt!!!\n"); -#endif - vs_intr(sc); - sc->sc_intrcnt_e.ev_count++; - return (1); -} - - diff --git a/sys/arch/mvme88k/dev/vsreg.h b/sys/arch/mvme88k/dev/vsreg.h index 8adac5f60fe..386ef0e15eb 100644 --- a/sys/arch/mvme88k/dev/vsreg.h +++ b/sys/arch/mvme88k/dev/vsreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vsreg.h,v 1.2 1999/09/27 18:43:26 smurph Exp $ */ +/* $OpenBSD: vsreg.h,v 1.3 2001/02/01 03:38:16 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * Copyright (c) 1990 The Regents of the University of California. @@ -162,53 +162,6 @@ typedef struct mcsb /**************** END Master Control Status Block (MCSB) *******************/ -/**************** Scater/Gather Stuff *******************/ - -typedef struct { - union { - unsigned short bytes :16; - #define MAX_SG_BLOCK_SIZE (1<<16) /* the size *has* to be always *smaller* */ - struct { - unsigned short :8; - unsigned short gather :8; - } scatter; - } count; - LONGV address; - unsigned short link :1; - unsigned short :3; - unsigned short transfer_type :2; - /* 0x0 is reserved */ - #define SHORT_TREANSFER 0x1 - #define LONG_TRANSFER 0x2 - #define SCATTER_GATTER_LIST_IN_SHORT_IO 0x3 - unsigned short memory_type :2; - #define NORMAL_TYPE 0x0 - #define BLOCK_MODE 0x1 - /* 0x2 is reserved */ - /* 0x3 is reserved */ - unsigned short address_modifier :8; -}sg_list_element_t; - -typedef sg_list_element_t * scatter_gather_list_t; - -#define MAX_SG_ELEMENTS 64 - -struct m328_sg { - struct m328_sg *up; - int elements; - int level; - struct m328_sg *down[MAX_SG_ELEMENTS]; - sg_list_element_t list[MAX_SG_ELEMENTS]; -}; - -typedef struct m328_sg *M328_SG; - -typedef struct { - struct scsi_xfer *xs; - M328_SG top_sg_list; -} M328_CMD; -/**************** END Scater/Gather Stuff *******************/ - /**************** Host Semaphore Block (HSB) *******************/ typedef struct hsb @@ -344,6 +297,10 @@ typedef struct cqe #define CRB_CLR_DONE(crsw) ((crsw) = 0) #define CRB_CLR_ER(crsw) ((crsw) &= ~M_CRSW_ER) +#define CRB_CLR_SC(crsw) ((crsw) &= ~M_CRSW_SC) +#define CRB_CLR_SE(crsw) ((crsw) &= ~M_CRSW_SE) +#define CRB_CLR_RST(crsw) ((crsw) &= ~M_CRSW_RST) +#define CRB_CLR(crsw) ((crsw) &= ~(x)) typedef struct crb { /* Command Response Block */ @@ -358,9 +315,9 @@ typedef struct crb /**************** END Command Response Block (CRB) *******************/ /*********** Controller Error Vector Status Block (CEVSB) **************/ - -typedef struct cevsb -{ /* Command Response Block */ +#define CONTROLLER_ERROR 0x0085 +#define NR_SCSI_ERROR 0x0885 +typedef struct cevsb { /* Command Response Block */ volatile u_short cevsb_CRSW; /* Command Response Status Word */ volatile u_char cevsb_TYPE; /* IOPB type */ volatile u_char cevsb_RES0; /* Reserved byte */ @@ -370,6 +327,13 @@ typedef struct cevsb volatile u_short cevsb_RES1; /* Reserved word */ volatile u_char cevsb_RES2; /* Reserved byte */ volatile u_char cevsb_ERROR; /* error code */ +#define CEVSB_ERR_TYPE 0xC0 /* IOPB type error */ +#define CEVSB_ERR_TO 0xC1 /* IOPB timeout error */ +#define CEVSB_ERR_TR 0x82 /* Target Reconnect, no IOPB */ +#define CEVSB_ERR_OF 0x83 /* Overflow */ +#define CEVSB_ERR_BD 0x84 /* Bad direction */ +#define CEVSB_ERR_NR 0x86 /* Non-Recoverabl Error */ +#define CESVB_ERR_PANIC 0xFF /* Board Painc!!! */ volatile u_short cevsb_AUXERR; /* COUGAR error code */ } M328_CEVSB; @@ -739,18 +703,4 @@ typedef struct ipsg #define D64_MOD ( (TT_D64 << 10) | (MEMTYPE << 8) | ADRM_EXT_S_D64 ) #define SHIO_MOD ( (TT_NORMAL << 10) | (MEMT_SHIO << 8) | ADRM_SHT_N_IO) -/* - * Scatter/gather functions - */ - -M328_SG vs_alloc_scatter_gather __P((void)); -void vs_dealloc_scatter_gather __P((M328_SG sg)); -void vs_link_scatter_gather_element __P((sg_list_element_t *element, - register vm_offset_t phys_add, - register int len)); -void vs_link_scatter_gather_list __P((sg_list_element_t *list, - register vm_offset_t phys_add, - register int elements)); -M328_SG vs_build_memory_structure __P((struct scsi_xfer *xs, M328_IOPB *iopb)); - #endif /* _M328REG_H_ */ diff --git a/sys/arch/mvme88k/dev/vsvar.h b/sys/arch/mvme88k/dev/vsvar.h index e645971095c..56440eb28c3 100644 --- a/sys/arch/mvme88k/dev/vsvar.h +++ b/sys/arch/mvme88k/dev/vsvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vsvar.h,v 1.1 1999/05/29 04:41:44 smurph Exp $ */ +/* $OpenBSD: vsvar.h,v 1.2 2001/02/01 03:38:16 smurph Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. * Copyright (c) 1990 The Regents of the University of California. @@ -48,6 +48,55 @@ #define LO(x) (u_short)((unsigned long)x & 0x0000FFFF) #define HI(x) (u_short)((unsigned long)x >> 16) #define OFF(x) (u_short)((long)kvtop(x) - (long)kvtop(sc->sc_vsreg)) +#define vs_name(sc) (sc)->sc_dev.dv_xname + +/**************** Scater/Gather Stuff *******************/ + +typedef struct { + union { + unsigned short bytes :16; + #define MAX_SG_BLOCK_SIZE (1<<16) /* the size *has* to be always *smaller* */ + struct { + unsigned short :8; + unsigned short gather :8; + } scatter; + } count; + LONGV address; + unsigned short link :1; + unsigned short :3; + unsigned short transfer_type :2; + /* 0x0 is reserved */ + #define SHORT_TREANSFER 0x1 + #define LONG_TRANSFER 0x2 + #define SCATTER_GATTER_LIST_IN_SHORT_IO 0x3 + unsigned short memory_type :2; + #define NORMAL_TYPE 0x0 + #define BLOCK_MODE 0x1 + /* 0x2 is reserved */ + /* 0x3 is reserved */ + unsigned short address_modifier :8; +} sg_list_element_t; + +typedef sg_list_element_t * scatter_gather_list_t; + +#define MAX_SG_ELEMENTS 64 + +struct m328_sg { + struct m328_sg *up; + int elements; + int level; + struct m328_sg *down[MAX_SG_ELEMENTS]; + sg_list_element_t list[MAX_SG_ELEMENTS]; +}; + +typedef struct m328_sg *M328_SG; + +typedef struct { + struct scsi_xfer *xs; + M328_SG top_sg_list; +} M328_CMD; + +/**************** END Scater/Gather Stuff *******************/ struct vs_tinfo { int cmds; /* #commands processed */ @@ -56,32 +105,32 @@ struct vs_tinfo { int perrs; /* #parity errors */ int senses; /* #request sense commands sent */ ushort lubusy; /* What local units/subr. are busy? */ - u_char flags; - u_char period; /* Period suggestion */ - u_char offset; /* Offset suggestion */ - int avail; /* Is there a device there */ + u_char flags; + u_char period; /* Period suggestion */ + u_char offset; /* Offset suggestion */ + int avail; /* Is there a device there */ } tinfo_t; -struct vs_softc { - struct device sc_dev; - struct intrhand sc_ih_e; - struct intrhand sc_ih_n; - struct evcnt sc_intrcnt_e; - struct evcnt sc_intrcnt_n; +struct vs_softc { + struct device sc_dev; + struct intrhand sc_ih_e; + struct intrhand sc_ih_n; + struct evcnt sc_intrcnt_e; + struct evcnt sc_intrcnt_n; u_short sc_ipl; - u_short sc_evec; - u_short sc_nvec; - struct scsi_link sc_link; /* proto for sub devices */ - u_long sc_chnl; /* channel 0 or 1 for dual bus cards */ - u_long sc_qhp; /* Command queue head pointer */ - struct vsreg *sc_vsreg; + u_short sc_evec; + u_short sc_nvec; + struct scsi_link sc_link; /* proto for sub devices */ + u_long sc_chnl; /* channel 0 or 1 for dual bus cards */ + u_long sc_qhp; /* Command queue head pointer */ + struct vsreg *sc_vsreg; #define SIOP_NACB 8 struct vs_tinfo sc_tinfo[8]; - u_char sc_flags; - u_char sc_sien; - u_char sc_dien; + u_char sc_flags; + u_char sc_sien; + u_char sc_dien; u_char sc_minsync; - struct map *hus_map; + struct map *hus_map; /* one for each target */ struct syncpar { u_char state; @@ -128,5 +177,18 @@ struct vs_softc { void vs_minphys __P((struct buf *bp)); int vs_scsicmd __P((struct scsi_xfer *)); +/* + * Scatter/gather functions + */ + +M328_SG vs_alloc_scatter_gather __P((void)); +void vs_dealloc_scatter_gather __P((M328_SG sg)); +void vs_link_scatter_gather_element __P((sg_list_element_t *element, + register vm_offset_t phys_add, + register int len)); +void vs_link_scatter_gather_list __P((sg_list_element_t *list, + register vm_offset_t phys_add, + register int elements)); +M328_SG vs_build_memory_structure __P((struct scsi_xfer *xs, M328_IOPB *iopb)); #endif /* _M328VAR_H */ |