Rewrite pmax console-probing code from scratch
as pmax/dev/findcons.c: * Follow the same logic: look for the device the PROM is using. * If it's a framebuffer and we don't have a driver for it, try other * framebuffers in PROM search order. * If no match found, warn user and fall over to serial console. * if no serial console found, go back to PROM. Rework tc/scc.c attach routine to give cleaner initialization semantics. Prune out old 'braindamage' code.
This commit is contained in:
parent
3172e096d3
commit
1c0730217a
|
@ -0,0 +1,496 @@
|
|||
/* $NetBSD: findcons.c,v 1.1 1998/03/24 08:39:02 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Jonathan Stone
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Jonathan Stone for
|
||||
* the NetBSD Project.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: findcons.c,v 1.1 1998/03/24 08:39:02 jonathan Exp $$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <dev/cons.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/termios.h>
|
||||
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
extern int pmax_boardtype; /* Motherboard type */
|
||||
|
||||
/*
|
||||
* Default consdev, for errors or warnings before
|
||||
* consinit runs: use the PROM.
|
||||
*/
|
||||
struct consdev cd;
|
||||
|
||||
#ifndef integrate
|
||||
#define integrate static inline
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Kernel configuration dependencies.
|
||||
*/
|
||||
#include "pm.h"
|
||||
#include "cfb.h"
|
||||
#include "mfb.h"
|
||||
#include "xcfb.h"
|
||||
#include "sfb.h"
|
||||
#include "dc_ds.h"
|
||||
#include "dc_ioasic.h"
|
||||
#include "dtop.h"
|
||||
#include "scc.h"
|
||||
#include "asc.h"
|
||||
#include "tc.h"
|
||||
#include "rasterconsole.h"
|
||||
|
||||
#include <dev/tc/tcvar.h> /* find TC fraembuffer device. */
|
||||
|
||||
#include <machine/pmioctl.h>
|
||||
#include <machine/fbio.h> /* framebuffer decls used below */
|
||||
#include <machine/fbvar.h>
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
#include <pmax/dev/promiovar.h>
|
||||
#include <pmax/dev/lk201var.h>
|
||||
#include <pmax/dev/rconsvar.h>
|
||||
|
||||
/* pmax serial interface */
|
||||
#if (NDC_DS > 0) || (NDC_IOASIC > 0)
|
||||
#include <machine/dc7085cons.h>
|
||||
#include <pmax/dev/dc_cons.h>
|
||||
#include <pmax/dev/dc_ds_cons.h>
|
||||
#include <pmax/dev/dc_ioasic_cons.h>
|
||||
#endif
|
||||
|
||||
/* MAXINE desktop bus keyboard */
|
||||
#if NDTOP > 0
|
||||
#include <pmax/dev/dtopvar.h>
|
||||
#endif
|
||||
|
||||
/* ioasic serial console */
|
||||
#if NSCC > 0
|
||||
#include <pmax/tc/sccvar.h>
|
||||
#endif
|
||||
|
||||
/* ds3100 baseboard framebuffer */
|
||||
#if NPM > 0
|
||||
#include <pmax/dev/pmvar.h>
|
||||
#endif
|
||||
|
||||
/* maxine baseboard framebuffer */
|
||||
#if NXCFB > 0
|
||||
#include <pmax/dev/xcfbvar.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX Major device numbers for possible console devices.
|
||||
*/
|
||||
#define DTOPDEV 15
|
||||
#define DCDEV 16
|
||||
#define SCCDEV 17
|
||||
#define RCONSDEV 85
|
||||
|
||||
/*
|
||||
* forward declarations
|
||||
*/
|
||||
|
||||
/*
|
||||
* device scan functions.
|
||||
* This would use the autoconfigatin hiearchy, except we need
|
||||
* to pick a console early in boot before autoconfig or
|
||||
* malloc are up.
|
||||
*/
|
||||
integrate int dc_ds_kbd __P((int prom_slot));
|
||||
integrate int dc_ioasic_kbd __P((int prom_slot));
|
||||
integrate int scc_kbd __P((int prom_slot));
|
||||
integrate int dtop_kbd __P((int prom_slot));
|
||||
|
||||
integrate int pm_screen __P((int prom_slot));
|
||||
integrate int xcfb_screen __P((int prom_slot));
|
||||
integrate int tc_screen __P((int prom_slot));
|
||||
|
||||
integrate int dc_ds_serial __P((int prom_slot));
|
||||
integrate int dc_ioasic_serial __P((int prom_slot));
|
||||
integrate int scc_serial __P((int prom_slot));
|
||||
|
||||
int find_kbd __P((int prom_slot));
|
||||
int find_screen __P((int prom_slot));
|
||||
int find_serial __P((int prom_slot));
|
||||
void consinit __P((void));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Keyboard physically present and driver configured on 3100?
|
||||
*/
|
||||
int
|
||||
dc_ds_kbd(kbd_slot)
|
||||
int kbd_slot;
|
||||
{
|
||||
|
||||
#if NDC_DS > 0
|
||||
if (pmax_boardtype == DS_PMAX) {
|
||||
cd.cn_getc = LKgetc;
|
||||
lk_divert(dcGetc, makedev(DCDEV, DCKBD_PORT));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Keyboard supported and present on 5000/200?
|
||||
*/
|
||||
int
|
||||
dc_ioasic_kbd(kbd_slot)
|
||||
int kbd_slot;
|
||||
{
|
||||
#if NDC_IOASIC > 0
|
||||
if (kbd_slot == 7) {
|
||||
cd.cn_dev = makedev(DCDEV, DCKBD_PORT);
|
||||
cd.cn_getc = LKgetc;
|
||||
lk_divert(dcGetc, makedev(DCDEV, DCKBD_PORT));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Keyboard configured and physically presnt on 3min, 3maxplus?
|
||||
*/
|
||||
int
|
||||
scc_kbd(kbd_slot)
|
||||
int kbd_slot;
|
||||
{
|
||||
#if NSCC > 0
|
||||
if (kbd_slot == 3) {
|
||||
cd.cn_dev = makedev(SCCDEV, SCCKBD_PORT);
|
||||
lk_divert(sccGetc, makedev(SCCDEV, SCCKBD_PORT));
|
||||
cd.cn_getc = LKgetc;
|
||||
return 1;
|
||||
}
|
||||
#endif /* NSCC */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keyboard physically present and driver configured on MAXINE?
|
||||
*/
|
||||
int
|
||||
dtop_kbd(kbd_slot)
|
||||
int kbd_slot;
|
||||
{
|
||||
if (pmax_boardtype != DS_MAXINE)
|
||||
return 0;
|
||||
#if NDTOP > 0
|
||||
if (kbd_slot == 3) {
|
||||
cd.cn_getc = dtopKBDGetc;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Select appropriate keyboard.
|
||||
*/
|
||||
int
|
||||
find_kbd(kbd)
|
||||
int kbd;
|
||||
{
|
||||
switch(pmax_boardtype) {
|
||||
case DS_PMAX:
|
||||
return (dc_ds_kbd(kbd));
|
||||
break;
|
||||
|
||||
case DS_3MAX:
|
||||
return (dc_ioasic_kbd(kbd));
|
||||
break;
|
||||
|
||||
case DS_3MIN: case DS_3MAXPLUS:
|
||||
/* keyboard on scc? */
|
||||
return (scc_kbd(kbd));
|
||||
break;
|
||||
|
||||
case DS_MAXINE:
|
||||
return (dtop_kbd(kbd));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* No keyboard found. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test if screens configured.
|
||||
*/
|
||||
|
||||
int
|
||||
pm_screen(crtslot)
|
||||
int crtslot;
|
||||
{
|
||||
#if NPM > 0
|
||||
if (pminit(0, 0, 1)) {
|
||||
cd.cn_pri = CN_INTERNAL;
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Look for MAXINE basboard video.
|
||||
* If selected as console, take it.
|
||||
*/
|
||||
int
|
||||
xcfb_screen(crtslot)
|
||||
int crtslot;
|
||||
{
|
||||
if (pmax_boardtype != DS_MAXINE)
|
||||
return 0;
|
||||
|
||||
#if NXCFB > 0
|
||||
if (crtslot == 3 && xcfbinit(NULL, NULL, 0, 0)) {
|
||||
cd.cn_pri = CN_INTERNAL;
|
||||
return(1);
|
||||
} else
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
tc_screen(crtslot)
|
||||
int crtslot;
|
||||
{
|
||||
#if NTC > 0
|
||||
if (tc_findconsole(crtslot)) {
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Look for screen.
|
||||
*/
|
||||
int
|
||||
find_screen(crtslot)
|
||||
int crtslot;
|
||||
{
|
||||
switch(pmax_boardtype) {
|
||||
case DS_PMAX:
|
||||
if (pm_screen(crtslot))
|
||||
return (1);
|
||||
/* no other options on 3100s. */
|
||||
break;
|
||||
|
||||
case DS_MAXINE:
|
||||
if (xcfb_screen(crtslot))
|
||||
return (1);
|
||||
|
||||
/*FALLTHROUGH*/
|
||||
case DS_3MAX:
|
||||
case DS_3MIN:
|
||||
case DS_3MAXPLUS:
|
||||
/* TC option video?*/
|
||||
if (tc_screen(crtslot))
|
||||
return(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* no screen found. */
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
dc_ds_serial(comslot)
|
||||
int comslot;
|
||||
{
|
||||
#if NDC_DS
|
||||
if (comslot == 4)
|
||||
cd.cn_dev = makedev(DCDEV, DCCOMM_PORT);
|
||||
else
|
||||
cd.cn_dev = makedev(DCDEV, DCPRINTER_PORT);
|
||||
return dc_ds_consinit(cd.cn_dev);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dc_ioasic_serial(comslot)
|
||||
int comslot;
|
||||
{
|
||||
#if NDC_IOASIC
|
||||
cd.cn_dev = makedev(DCDEV, DCPRINTER_PORT);
|
||||
return dc_ioasic_consinit(cd.cn_dev);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
scc_serial(comslot)
|
||||
int comslot;
|
||||
{
|
||||
#if NSCC > 0
|
||||
int dev;
|
||||
|
||||
/*
|
||||
* On the 3min and 3maxplus, the default serial-console
|
||||
* port is on the chip at the higher address.
|
||||
* On the MAXINE, there is only serial port, which
|
||||
* configures at the lower address.
|
||||
*/
|
||||
dev = (pmax_boardtype == DS_MAXINE) ? SCCCOMM2_PORT: SCCCOMM3_PORT;
|
||||
|
||||
#ifdef notyet /* no boot-time init entrypoint for scc */
|
||||
cd.cn_dev = makedev(SCCDEV, DCPRINTER_PORT);
|
||||
return dc_ioasic_consinit(cd.cn_dev);
|
||||
|
||||
#else /* !notyet */
|
||||
printf("Using PROM serial output until serial drivers initialized.\n");
|
||||
cd.cn_dev = makedev (SCCDEV, dev);
|
||||
return(1);
|
||||
#endif /* notyet */
|
||||
#endif /* NSCC */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* find a serial console.
|
||||
*/
|
||||
int
|
||||
find_serial(comslot)
|
||||
int comslot;
|
||||
{
|
||||
switch(pmax_boardtype) {
|
||||
case DS_PMAX:
|
||||
return (dc_ds_serial(comslot));
|
||||
break;
|
||||
|
||||
case DS_3MAX:
|
||||
return (dc_ioasic_serial(comslot));
|
||||
break;
|
||||
|
||||
case DS_MAXINE: /* XXX only one serial port */
|
||||
case DS_3MIN:
|
||||
case DS_3MAXPLUS:
|
||||
return (scc_serial(comslot));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Pick a console.
|
||||
* Use the same devices as PROM says, if we have a driver.
|
||||
* if wedont' have a driver for the device the PROM chose,
|
||||
* pick the highest-priority device according to the Owners Guide rules.
|
||||
* If no match, stick with the PROM and hope for the best.
|
||||
*/
|
||||
void
|
||||
consinit()
|
||||
{
|
||||
int prom_using_screen = 0; /* boolean */
|
||||
int kbd = 0; /* prom kbd locator */
|
||||
int crt = 0; /* prom framebuffer locator */
|
||||
|
||||
/* Use copy of PROM console until we find something better. */
|
||||
cd = promcd;
|
||||
cn_tab = &cd;
|
||||
|
||||
/* get PROM's idea of what the console is. */
|
||||
prom_findcons(&kbd, &crt, &prom_using_screen);
|
||||
|
||||
|
||||
/* if the prom is using a screen, try that. */
|
||||
if (prom_using_screen) {
|
||||
if (find_kbd(kbd) && find_screen(crt)) {
|
||||
|
||||
#if NRASTERCONSOLE > 0
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
rcons_indev(&cd);
|
||||
return;
|
||||
#endif /* NRASTERCONSOLE > 0 */
|
||||
|
||||
}
|
||||
|
||||
/* PROM is using fb console, but we have no driver for it. */
|
||||
printf("No supported console device in slot %d. ", crt);
|
||||
printf("Trying serial console.\n");
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If we found a keyboard and framebuffer, wire it up
|
||||
* as an rcons device even if it's not the OS console.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* Otherwise, try a serial port as console. */
|
||||
if (find_serial(kbd)) {
|
||||
cd.cn_pri = CN_REMOTE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nothing worked. Revert to using PROM.
|
||||
* Maybe some device will usurp the console during
|
||||
* autoconfiguration.
|
||||
*/
|
||||
cd = promcd;
|
||||
|
||||
printf("No driver for console device, using prom for console I/O.\n");
|
||||
return;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: autoconf.c,v 1.27 1998/01/09 17:22:47 drochner Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.28 1998/03/24 08:39:02 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -43,7 +43,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.27 1998/01/09 17:22:47 drochner Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.28 1998/03/24 08:39:02 jonathan Exp $");
|
||||
|
||||
/*
|
||||
* Setup the system to run on the current machine.
|
||||
|
@ -71,8 +71,6 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.27 1998/01/09 17:22:47 drochner Exp $
|
|||
|
||||
void dumpconf __P((void)); /* XXX */
|
||||
|
||||
void xconsinit __P((void)); /* XXX console-init continuation */
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* XXX system-dependent, should call through a pointer.
|
||||
|
@ -140,17 +138,6 @@ configure()
|
|||
if (config_rootfound("mainbus", "mainbus") == NULL)
|
||||
panic("no mainbus found");
|
||||
|
||||
#if 0
|
||||
printf("looking for non-PROM console driver\n");
|
||||
#endif
|
||||
|
||||
xconsinit(); /* do kludged-up console init */
|
||||
|
||||
#ifdef DEBUG
|
||||
if (cputype == DS_3MIN)
|
||||
/*FIXME*/ printf("switched to non-PROM console\n");
|
||||
#endif
|
||||
|
||||
initcpu();
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.106 1998/03/12 05:46:21 thorpej Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.107 1998/03/24 08:39:02 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.106 1998/03/12 05:46:21 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.107 1998/03/24 08:39:02 jonathan Exp $");
|
||||
|
||||
/* from: Utah Hdr: machdep.c 1.63 91/04/24 */
|
||||
|
||||
|
@ -110,6 +110,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.106 1998/03/12 05:46:21 thorpej Exp $"
|
|||
#include <pmax/pmax/pmaxtype.h>
|
||||
#include <pmax/pmax/trap.h> /* mboard-specific interrupt fns */
|
||||
#include <pmax/pmax/cons.h>
|
||||
#include <pmax/dev/promiovar.h> /* prom console I/O vector */
|
||||
|
||||
#include "pm.h"
|
||||
#include "cfb.h"
|
||||
|
@ -123,7 +124,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.106 1998/03/12 05:46:21 thorpej Exp $"
|
|||
|
||||
|
||||
extern struct consdev *cn_tab; /* Console I/O table... */
|
||||
extern struct consdev cd;
|
||||
|
||||
|
||||
/* the following is used externally (sysctl_hw) */
|
||||
char machine[] = MACHINE; /* from <machine/param.h> */
|
||||
|
@ -313,7 +314,7 @@ mach_init(argc, argv, code, cv)
|
|||
}
|
||||
|
||||
/* Use PROM console output until we initialize a console driver. */
|
||||
cn_tab = &cd;
|
||||
cn_tab = &promcd;
|
||||
|
||||
/* check for direct boot from DS5000 PROM */
|
||||
if (argc > 0 && strcmp(argv[0], "boot") == 0) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: scc.c,v 1.38 1998/03/24 00:23:56 jonathan Exp $ */
|
||||
/* $NetBSD: scc.c,v 1.39 1998/03/24 08:39:02 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University
|
||||
|
@ -66,7 +66,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: scc.c,v 1.38 1998/03/24 00:23:56 jonathan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: scc.c,v 1.39 1998/03/24 08:39:02 jonathan Exp $");
|
||||
|
||||
#ifdef alpha
|
||||
#include "opt_dec_3000_300.h"
|
||||
|
@ -151,7 +151,6 @@ extern void ttrstrt __P((void *));
|
|||
#if NRASTERCONSOLE > 0
|
||||
#define HAVE_RCONS
|
||||
#endif
|
||||
extern int pending_remcons;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -167,30 +166,14 @@ extern int pending_remcons;
|
|||
#define RASTER_CONSOLE() 1 /* Treat test for cn_screen as true */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Is there a framebuffer console device using this serial driver?
|
||||
* XXX used for ugly special-cased console input that should be redone
|
||||
* more cleanly.
|
||||
* Extract unit (scc chip), channel on chip, and dialin/dialout unit.
|
||||
*/
|
||||
|
||||
#ifdef RCONS_BRAINDAMAGE
|
||||
static inline int
|
||||
raster_console(void)
|
||||
{
|
||||
#if 1
|
||||
return (cn_tab->cn_pri == CN_NORMAL || cn_tab->cn_pri == CN_INTERNAL);
|
||||
#else
|
||||
register int israster =
|
||||
(cn_tab->cn_pri == CN_NORMAL || cn_tab->cn_pri == CN_INTERNAL);
|
||||
printf("israster: %d\n", israster);
|
||||
return israster;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define SCCUNIT(dev) (minor(dev) >> 1)
|
||||
#define SCCUNIT(dev) ((minor(dev) & 0x7ffff) >> 1)
|
||||
#define SCCLINE(dev) (minor(dev) & 0x1)
|
||||
#define SCCDIALOUT(x) (minor(x) & 0x80000)
|
||||
|
||||
|
||||
/* QVSS-compatible in-kernel X input event parser, pointer tracker */
|
||||
void (*sccDivertXInput) __P((int cc)); /* X windows keyboard input routine */
|
||||
|
@ -299,7 +282,12 @@ void scc_kbd_init __P((struct scc_softc *sc, dev_t dev));
|
|||
void scc_mouse_init __P((struct scc_softc *sc, dev_t dev));
|
||||
void scc_tty_init __P((struct scc_softc *sc, dev_t dev));
|
||||
|
||||
static void scc_txintr __P((struct scc_softc *, int, scc_regmap_t *));
|
||||
static void scc_rxintr __P((struct scc_softc *, int, scc_regmap_t *, int));
|
||||
inline
|
||||
static void scc_stintr __P((struct scc_softc *, int, scc_regmap_t *, int));
|
||||
int sccintr __P((void *));
|
||||
|
||||
#ifdef alpha
|
||||
void scc_alphaintr __P((int));
|
||||
#endif
|
||||
|
@ -466,7 +454,10 @@ sccattach(parent, self, aux)
|
|||
|
||||
unit = sc->sc_dv.dv_unit;
|
||||
|
||||
#ifdef pmax
|
||||
sccaddr = (void*)MIPS_PHYS_TO_KSEG1(d->iada_addr);
|
||||
#endif
|
||||
|
||||
#ifdef SPARSE
|
||||
sccaddr = (void *)TC_DENSE_TO_SPARSE((tc_addr_t)sccaddr);
|
||||
#endif
|
||||
|
@ -475,28 +466,25 @@ sccattach(parent, self, aux)
|
|||
ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_TTY,
|
||||
sccintr, (void *)sc);
|
||||
|
||||
/* serial console debugging */
|
||||
#if defined(DEBUG) && defined(HAVE_RCONS) && 0 /*XXX*/
|
||||
if (CONSOLE_ON_UNIT(unit) && (cn_tab->cn_pri == CN_REMOTE)) {
|
||||
DELAY(10000);
|
||||
printf("(attached interrupt, delaying)\n");
|
||||
#ifdef alpha
|
||||
/*
|
||||
* XXX
|
||||
* If is the mandated remote console, point cn_tab at it now,
|
||||
* to make later tests for console-ness MI.
|
||||
*/
|
||||
if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) ||
|
||||
(cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0)) {
|
||||
cn_tab->cn_dev = makedev(SCCDEV, sc->sc_dv.dv_unit * 2);
|
||||
}
|
||||
#endif /* defined(DEBUG) && defined(HAVE_RCONS)*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For a remote console, wait a while for previous output to
|
||||
* complete.
|
||||
* If this is the console, wait a while for any previous
|
||||
* output to complete.
|
||||
*/
|
||||
#ifdef pmax
|
||||
if (CONSOLE_ON_UNIT(unit) && (cn_tab->cn_pri == CN_REMOTE))
|
||||
if (CONSOLE_ON_UNIT(unit))
|
||||
DELAY(10000);
|
||||
#endif
|
||||
|
||||
#ifdef alpha
|
||||
if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) ||
|
||||
(cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0))
|
||||
DELAY(10000);
|
||||
#endif
|
||||
pdp = &sc->scc_pdma[0];
|
||||
|
||||
/* init pseudo DMA structures */
|
||||
|
@ -511,65 +499,42 @@ sccattach(parent, self, aux)
|
|||
pdp++;
|
||||
}
|
||||
/* What's the warning here? Defaulting to softCAR on line 2? */
|
||||
sc->scc_softCAR = sc->sc_dv.dv_cfdata->cf_flags | 0x2; /* XXX */
|
||||
sc->scc_softCAR = sc->sc_dv.dv_cfdata->cf_flags;
|
||||
|
||||
/* reset chip, initialize register-copies in softc */
|
||||
/*
|
||||
* Reset chip, initialize register-copies in softc.
|
||||
* XXX if this was console, no more printf()s until after
|
||||
* scc_tty_init()!
|
||||
*/
|
||||
sccreset(sc);
|
||||
|
||||
|
||||
/*
|
||||
* Special handling for consoles.
|
||||
*/
|
||||
#ifdef pmax
|
||||
if (pending_remcons) {
|
||||
if (CONSOLE_ON_UNIT(unit)) {
|
||||
/*
|
||||
* We were using PROM callbacks for console I/O,
|
||||
* and we just reset the chip under the console.
|
||||
* wire up this driver as console ASAP.
|
||||
*/
|
||||
|
||||
/*XXX*/ /* test for correct unit */
|
||||
DELAY(10000);
|
||||
|
||||
/*
|
||||
* XXX PROM and NetBSD unit numbers swapped
|
||||
* on kn03, maybe kmin?
|
||||
* And what about maxine?
|
||||
*/
|
||||
if (cn_tab->cn_dev == unit && cputype != DS_MAXINE) {
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are using the PROM serial-console routines
|
||||
* as console, now is the time to set up the scc
|
||||
* driver as console.
|
||||
* Re-wire this unit up as console ASAP.
|
||||
*/
|
||||
cn_tab = &scccons;
|
||||
cn_tab->cn_dev = makedev(SCCDEV,
|
||||
sc->sc_dv.dv_unit == 0 ? SCCCOMM2_PORT : SCCCOMM3_PORT);
|
||||
#ifdef notyet
|
||||
scc_consinit(cn_tab->cn_dev, sccaddr);
|
||||
#else
|
||||
scc_tty_init(sc, cn_tab->cn_dev);
|
||||
#endif
|
||||
|
||||
printf(" (In sccattach: cn_dev = 0x%x)", cn_tab->cn_dev);
|
||||
printf(" (Unit = %d)", unit);
|
||||
/* Wire carrier for console. */
|
||||
sc->scc_softCAR |= SCCLINE(cn_tab->cn_dev);
|
||||
scc_tty_init(sc, cn_tab->cn_dev);
|
||||
|
||||
DELAY(20000);
|
||||
|
||||
printf(": console");
|
||||
pending_remcons = 0;
|
||||
/*
|
||||
* XXX We should support configurations where the PROM
|
||||
* console device is a serial console, and a
|
||||
* framebuffer, keyboard, and mouse are present.
|
||||
*/
|
||||
#ifdef BREAKS_X_WITH_REMOTE_CONSOLE
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
#endif /* pmax */
|
||||
printf("\n");
|
||||
|
||||
|
||||
/* Wire up any childre, like keyboards or mice. */
|
||||
#ifdef HAVE_RCONS
|
||||
/* XXX test below may be too inclusive ? */
|
||||
if (cputype != DS_MAXINE) {
|
||||
if (unit == 1) {
|
||||
scc_kbd_init(sc, makedev(SCCDEV, SCCKBD_PORT));
|
||||
|
@ -579,31 +544,6 @@ sccattach(parent, self, aux)
|
|||
}
|
||||
#endif /* HAVE_RCONS */
|
||||
|
||||
#ifdef alpha
|
||||
if (SCCUNIT(cn_tab->cn_dev) == unit) {
|
||||
scc_tty_init(sc,
|
||||
makedev(SCCDEV, (sc->sc_dv.dv_unit == 0 ?
|
||||
SCCCOMM2_PORT : SCCCOMM3_PORT)));
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Unit 1 is the remote console, wire it up now.
|
||||
*/
|
||||
if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) ||
|
||||
(cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0)) {
|
||||
cn_tab = &scccons;
|
||||
cn_tab->cn_dev = makedev(SCCDEV, sc->sc_dv.dv_unit * 2);
|
||||
|
||||
printf(": console\n");
|
||||
|
||||
/* wire carrier for console. */
|
||||
sc->scc_softCAR |= SCCLINE(cn_tab->cn_dev);
|
||||
} else
|
||||
printf("\n");
|
||||
#else /* pmax */
|
||||
printf("\n");
|
||||
#endif /* pmax */
|
||||
}
|
||||
|
||||
|
||||
|
@ -778,6 +718,11 @@ sccopen(dev, flag, mode, p)
|
|||
if (!sc)
|
||||
return (ENXIO);
|
||||
|
||||
#ifdef DEBUG_CARRIER
|
||||
printf("sccopen: line %d %x, dialout %d\n",
|
||||
major(dev), minor(dev), SCCDIALOUT(dev));
|
||||
#endif /* DEBUG_CARRIER */
|
||||
|
||||
line = SCCLINE(dev);
|
||||
if (sc->scc_pdma[line].p_addr == NULL)
|
||||
return (ENXIO);
|
||||
|
@ -789,6 +734,11 @@ sccopen(dev, flag, mode, p)
|
|||
tp->t_oproc = sccstart;
|
||||
tp->t_param = sccparam;
|
||||
tp->t_dev = dev;
|
||||
|
||||
/*
|
||||
* Do the following only for first opens.
|
||||
*/
|
||||
s = spltty();
|
||||
if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
|
||||
ttychars(tp);
|
||||
#ifndef PORTSELECTOR
|
||||
|
@ -806,10 +756,14 @@ sccopen(dev, flag, mode, p)
|
|||
#endif
|
||||
(void) sccparam(tp, &tp->t_termios);
|
||||
ttsetwater(tp);
|
||||
} else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0)
|
||||
return (EBUSY);
|
||||
}
|
||||
else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0) {
|
||||
error = EBUSY;
|
||||
splx(s);
|
||||
goto bad;
|
||||
}
|
||||
(void) sccmctl(dev, DML_DTR, DMSET);
|
||||
s = spltty();
|
||||
|
||||
while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&
|
||||
!(tp->t_state & TS_CARR_ON)) {
|
||||
tp->t_wopen++;
|
||||
|
@ -820,19 +774,21 @@ sccopen(dev, flag, mode, p)
|
|||
break;
|
||||
}
|
||||
splx(s);
|
||||
|
||||
if (error)
|
||||
return (error);
|
||||
goto bad;
|
||||
|
||||
|
||||
error = (*linesw[tp->t_line].l_open)(dev, tp);
|
||||
|
||||
#if defined(HAVE_RCONS) && defined(RCONS_BRAINDAMAGE)
|
||||
/* handle raster console specially */
|
||||
if (tp == scctty(makedev(SCCDEV,SCCKBD_PORT)) &&
|
||||
raster_console() && firstopen) {
|
||||
extern struct tty *fbconstty;
|
||||
tp->t_winsize = fbconstty->t_winsize;
|
||||
}
|
||||
#endif /* old rcons brain-damage */
|
||||
#ifdef DEBUG_CARRIER
|
||||
printf("sccopen: ldisc open %d %x, dialout %d sez %d\n",
|
||||
major(dev), minor(dev), SCCDIALOUT(dev), error);
|
||||
#endif
|
||||
|
||||
if (error)
|
||||
goto bad;
|
||||
bad:
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -1151,6 +1107,143 @@ cold_sccparam(tp, t, sc)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* transmission done interrupts
|
||||
*/
|
||||
static void
|
||||
scc_txintr(sc, chan, regs)
|
||||
struct scc_softc *sc;
|
||||
int chan;
|
||||
scc_regmap_t *regs;
|
||||
{
|
||||
register struct tty *tp = sc->scc_tty[chan];
|
||||
register struct pdma *dp = &sc->scc_pdma[chan];
|
||||
register int cc;
|
||||
|
||||
tp = sc->scc_tty[chan];
|
||||
dp = &sc->scc_pdma[chan];
|
||||
if (dp->p_mem < dp->p_end) {
|
||||
SCC_WRITE_DATA(regs, chan, *dp->p_mem++);
|
||||
#ifdef pmax /* Alpha handles the 1.6 msec settle time in hardware */
|
||||
DELAY(2);
|
||||
#endif
|
||||
tc_mb();
|
||||
} else {
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
if (tp->t_state & TS_FLUSH)
|
||||
tp->t_state &= ~TS_FLUSH;
|
||||
else {
|
||||
ndflush(&tp->t_outq, dp->p_mem -
|
||||
(caddr_t) tp->t_outq.c_cf);
|
||||
dp->p_end = dp->p_mem = tp->t_outq.c_cf;
|
||||
}
|
||||
if (tp->t_line)
|
||||
(*linesw[tp->t_line].l_start)(tp);
|
||||
else
|
||||
sccstart(tp);
|
||||
if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) {
|
||||
SCC_READ_REG(regs, chan, SCC_RR15, cc);
|
||||
cc &= ~ZSWR15_TXUEOM_IE;
|
||||
SCC_WRITE_REG(regs, chan, SCC_WR15, cc);
|
||||
cc = sc->scc_wreg[chan].wr1 & ~ZSWR1_TIE;
|
||||
SCC_WRITE_REG(regs, chan, SCC_WR1, cc);
|
||||
sc->scc_wreg[chan].wr1 = cc;
|
||||
tc_mb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* receive interrupts
|
||||
*/
|
||||
static void
|
||||
scc_rxintr(sc, chan, regs, unit)
|
||||
struct scc_softc *sc;
|
||||
int chan;
|
||||
scc_regmap_t *regs;
|
||||
int unit;
|
||||
{
|
||||
register struct tty *tp = sc->scc_tty[chan];
|
||||
int cc, rr1 = 0, rr2 = 0; /* XXX */
|
||||
|
||||
SCC_READ_DATA(regs, chan, cc);
|
||||
if (rr2 == SCC_RR2_A_RECV_SPECIAL ||
|
||||
rr2 == SCC_RR2_B_RECV_SPECIAL) {
|
||||
SCC_READ_REG(regs, chan, SCC_RR1, rr1);
|
||||
SCC_WRITE_REG(regs, chan, SCC_RR0, ZSWR0_RESET_ERRORS);
|
||||
if (rr1 & ZSRR1_DO) {
|
||||
log(LOG_WARNING, "scc%d,%d: silo overflow\n",
|
||||
unit >> 1, chan);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Keyboard needs special treatment.
|
||||
*/
|
||||
if (tp == scctty(makedev(SCCDEV, SCCKBD_PORT))) {
|
||||
#if defined(DDB) && defined(LK_DO)
|
||||
if (cc == LK_DO) {
|
||||
spl0();
|
||||
Debugger();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
debugChar = cc;
|
||||
#endif
|
||||
if (sccDivertXInput) {
|
||||
(*sccDivertXInput)(cc);
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_RCONS
|
||||
if ((cc = kbdMapChar(cc)) < 0)
|
||||
return;
|
||||
rcons_input(0, cc);
|
||||
#endif
|
||||
/*
|
||||
* Now for mousey
|
||||
*/
|
||||
} else if (tp == scctty(makedev(SCCDEV, SCCMOUSE_PORT)) &&
|
||||
sccMouseButtons) {
|
||||
#ifdef HAVE_RCONS
|
||||
/*XXX*/
|
||||
mouseInput(cc);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (!(tp->t_state & TS_ISOPEN)) {
|
||||
wakeup((caddr_t)&tp->t_rawq);
|
||||
#ifdef PORTSELECTOR
|
||||
if (!(tp->t_state & TS_WOPEN))
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (rr2 == SCC_RR2_A_RECV_SPECIAL ||
|
||||
rr2 == SCC_RR2_B_RECV_SPECIAL) {
|
||||
if (rr1 & ZSRR1_PE)
|
||||
cc |= TTY_PE;
|
||||
if (rr1 & ZSRR1_FE)
|
||||
cc |= TTY_FE;
|
||||
}
|
||||
(*linesw[tp->t_line].l_rint)(cc, tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Modem status interrupts
|
||||
*/
|
||||
static void inline
|
||||
scc_stintr(sc, chan, regs, unit)
|
||||
struct scc_softc *sc;
|
||||
int chan;
|
||||
scc_regmap_t *regs;
|
||||
int unit;
|
||||
{
|
||||
|
||||
SCC_WRITE_REG(regs, chan, SCC_RR0, ZSWR0_RESET_STATUS);
|
||||
scc_modem_intr(unit | chan);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for interrupts from all devices.
|
||||
*/
|
||||
|
@ -1161,136 +1254,60 @@ sccintr(xxxsc)
|
|||
register struct scc_softc *sc = (struct scc_softc *)xxxsc;
|
||||
register int unit = (long)sc->sc_dv.dv_unit;
|
||||
register scc_regmap_t *regs;
|
||||
register struct tty *tp;
|
||||
register struct pdma *dp;
|
||||
register int cc, chan, rr1, rr2, rr3;
|
||||
int overrun = 0;
|
||||
register int rr3;
|
||||
|
||||
rr1 = 0; /* shut up gcc -Wall */
|
||||
regs = (scc_regmap_t *)sc->scc_pdma[0].p_addr;
|
||||
unit <<= 1;
|
||||
for (;;) {
|
||||
SCC_READ_REG(regs, SCC_CHANNEL_B, ZSRR_IVEC, rr2);
|
||||
rr2 = SCC_RR2_STATUS(rr2);
|
||||
/* are we done yet ? */
|
||||
if (rr2 == 6) { /* strange, distinguished value */
|
||||
SCC_READ_REG(regs, SCC_CHANNEL_A, ZSRR_IPEND, rr3);
|
||||
if (rr3 == 0)
|
||||
return 0 ;/* XXX FIXME why ? */
|
||||
}
|
||||
|
||||
SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_RR0, ZSWR0_CLR_INTR);
|
||||
if ((rr2 == SCC_RR2_A_XMIT_DONE) || (rr2 == SCC_RR2_B_XMIT_DONE)) {
|
||||
chan = (rr2 == SCC_RR2_A_XMIT_DONE) ?
|
||||
SCC_CHANNEL_A : SCC_CHANNEL_B;
|
||||
tp = sc->scc_tty[chan];
|
||||
dp = &sc->scc_pdma[chan];
|
||||
if (dp->p_mem < dp->p_end) {
|
||||
SCC_WRITE_DATA(regs, chan, *dp->p_mem++);
|
||||
#ifdef pmax /* Alpha handles the 1.6 msec settle time in hardware */
|
||||
DELAY(2);
|
||||
#endif
|
||||
tc_mb();
|
||||
} else {
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
if (tp->t_state & TS_FLUSH)
|
||||
tp->t_state &= ~TS_FLUSH;
|
||||
else {
|
||||
ndflush(&tp->t_outq, dp->p_mem -
|
||||
(caddr_t) tp->t_outq.c_cf);
|
||||
dp->p_end = dp->p_mem = tp->t_outq.c_cf;
|
||||
}
|
||||
if (tp->t_line)
|
||||
(*linesw[tp->t_line].l_start)(tp);
|
||||
else
|
||||
sccstart(tp);
|
||||
if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) {
|
||||
SCC_READ_REG(regs, chan, SCC_RR15, cc);
|
||||
cc &= ~ZSWR15_TXUEOM_IE;
|
||||
SCC_WRITE_REG(regs, chan, SCC_WR15, cc);
|
||||
cc = sc->scc_wreg[chan].wr1 & ~ZSWR1_TIE;
|
||||
SCC_WRITE_REG(regs, chan, SCC_WR1, cc);
|
||||
sc->scc_wreg[chan].wr1 = cc;
|
||||
tc_mb();
|
||||
}
|
||||
}
|
||||
} else if (rr2 == SCC_RR2_A_RECV_DONE ||
|
||||
rr2 == SCC_RR2_B_RECV_DONE || rr2 == SCC_RR2_A_RECV_SPECIAL ||
|
||||
rr2 == SCC_RR2_B_RECV_SPECIAL) {
|
||||
if (rr2 == SCC_RR2_A_RECV_DONE || rr2 == SCC_RR2_A_RECV_SPECIAL)
|
||||
chan = SCC_CHANNEL_A;
|
||||
else
|
||||
chan = SCC_CHANNEL_B;
|
||||
tp = sc->scc_tty[chan];
|
||||
SCC_READ_DATA(regs, chan, cc);
|
||||
if (rr2 == SCC_RR2_A_RECV_SPECIAL ||
|
||||
rr2 == SCC_RR2_B_RECV_SPECIAL) {
|
||||
SCC_READ_REG(regs, chan, SCC_RR1, rr1);
|
||||
SCC_WRITE_REG(regs, chan, SCC_RR0, ZSWR0_RESET_ERRORS);
|
||||
if ((rr1 & ZSRR1_DO) && overrun == 0) {
|
||||
log(LOG_WARNING, "scc%d,%d: silo overflow\n",
|
||||
unit >> 1, chan);
|
||||
overrun = 1;
|
||||
}
|
||||
/* Note: only channel A has an RR3 */
|
||||
SCC_READ_REG(regs, SCC_CHANNEL_A, ZSRR_IPEND, rr3);
|
||||
|
||||
/*
|
||||
* Clear interrupt first to avoid a race condition.
|
||||
* If a new interrupt condition happens while we are
|
||||
* servicing this one, we will get another interrupt
|
||||
* shortly. We can NOT just sit here in a loop, or
|
||||
* we will cause horrible latency for other devices
|
||||
* on this interrupt level (i.e. sun3x floppy disk).
|
||||
*/
|
||||
|
||||
/*
|
||||
* At elast some, maybe all DECstation chips have modem
|
||||
* leads crosswired: the data comes in one channel and the
|
||||
* bulkead modem signals for that port are wired to the
|
||||
* _other_ channel of the chip. Yes, really.
|
||||
* This code cannot get that right.
|
||||
*/
|
||||
|
||||
/* First look at channel A. */
|
||||
if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
|
||||
SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_RR0, ZSWR0_CLR_INTR);
|
||||
if (rr3 & ZSRR3_IP_A_RX)
|
||||
scc_rxintr(sc, SCC_CHANNEL_A, regs, unit);
|
||||
|
||||
if (rr3 & ZSRR3_IP_A_STAT) {
|
||||
/* XXX swapped channels */
|
||||
scc_stintr(sc, SCC_CHANNEL_A, regs, unit);
|
||||
}
|
||||
|
||||
/*
|
||||
* Keyboard needs special treatment.
|
||||
*/
|
||||
if (tp == scctty(makedev(SCCDEV, SCCKBD_PORT))) {
|
||||
#if defined(DDB) && defined(LK_DO)
|
||||
if (cc == LK_DO) {
|
||||
spl0();
|
||||
Debugger();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
debugChar = cc;
|
||||
#endif
|
||||
if (sccDivertXInput) {
|
||||
(*sccDivertXInput)(cc);
|
||||
continue;
|
||||
}
|
||||
#ifdef HAVE_RCONS
|
||||
if ((cc = kbdMapChar(cc)) < 0)
|
||||
continue;
|
||||
rcons_input(0, cc);
|
||||
#endif
|
||||
/*
|
||||
* Now for mousey
|
||||
*/
|
||||
} else if (tp == scctty(makedev(SCCDEV, SCCMOUSE_PORT)) &&
|
||||
sccMouseButtons) {
|
||||
#ifdef HAVE_RCONS
|
||||
/*XXX*/
|
||||
mouseInput(cc);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (!(tp->t_state & TS_ISOPEN)) {
|
||||
wakeup((caddr_t)&tp->t_rawq);
|
||||
#ifdef PORTSELECTOR
|
||||
if (tp->t_wopen == 0)
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (rr2 == SCC_RR2_A_RECV_SPECIAL ||
|
||||
rr2 == SCC_RR2_B_RECV_SPECIAL) {
|
||||
if (rr1 & ZSRR1_PE)
|
||||
cc |= TTY_PE;
|
||||
if (rr1 & ZSRR1_FE)
|
||||
cc |= TTY_FE;
|
||||
}
|
||||
(*linesw[tp->t_line].l_rint)(cc, tp);
|
||||
} else if ((rr2 == SCC_RR2_A_EXT_STATUS) || (rr2 == SCC_RR2_B_EXT_STATUS)) {
|
||||
chan = (rr2 == SCC_RR2_A_EXT_STATUS) ?
|
||||
SCC_CHANNEL_A : SCC_CHANNEL_B;
|
||||
SCC_WRITE_REG(regs, chan, SCC_RR0, ZSWR0_RESET_STATUS);
|
||||
scc_modem_intr(unit | chan);
|
||||
}
|
||||
if (rr3 & ZSRR3_IP_A_TX)
|
||||
scc_txintr(sc, SCC_CHANNEL_A, regs);
|
||||
}
|
||||
|
||||
/* Now look at channel B. */
|
||||
if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
|
||||
SCC_WRITE_REG(regs, SCC_CHANNEL_B, SCC_RR0, ZSWR0_CLR_INTR);
|
||||
if (rr3 & ZSRR3_IP_B_RX)
|
||||
scc_rxintr(sc, SCC_CHANNEL_B, regs, unit);
|
||||
if (rr3 & ZSRR3_IP_B_STAT) {
|
||||
/* XXX swapped channels */
|
||||
scc_stintr(sc, SCC_CHANNEL_B, regs, unit);
|
||||
}
|
||||
if (rr3 & ZSRR3_IP_B_TX)
|
||||
scc_txintr(sc, SCC_CHANNEL_B, regs);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1320,28 +1337,6 @@ sccstart(tp)
|
|||
if (tp->t_outq.c_cc == 0)
|
||||
goto out;
|
||||
|
||||
#ifdef RCONS_BRAINDAMAGE
|
||||
/* handle console specially */
|
||||
/* XXX raster console output via serial port! */
|
||||
if (tp == scctty(makedev(SCCDEV,SCCKBD_PORT)) && raster_console()) {
|
||||
while (tp->t_outq.c_cc > 0) {
|
||||
cc = getc(&tp->t_outq) & 0x7f;
|
||||
cnputc(cc);
|
||||
}
|
||||
/*
|
||||
* After we flush the output queue we may need to wake
|
||||
* up the process that made the output.
|
||||
*/
|
||||
if (tp->t_outq.c_cc <= tp->t_lowat) {
|
||||
if (tp->t_state & TS_ASLEEP) {
|
||||
tp->t_state &= ~TS_ASLEEP;
|
||||
wakeup((caddr_t)&tp->t_outq);
|
||||
}
|
||||
selwakeup(&tp->t_wsel);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
cc = ndqb(&tp->t_outq, 0);
|
||||
|
||||
tp->t_state |= TS_BUSY;
|
||||
|
@ -1478,11 +1473,24 @@ scc_modem_intr(dev)
|
|||
sc = scc_cd.cd_devs[SCCUNIT(dev)];
|
||||
tp = sc->scc_tty[chan];
|
||||
regs = (scc_regmap_t *)sc->scc_pdma[chan].p_addr;
|
||||
if (chan == SCC_CHANNEL_A)
|
||||
return;
|
||||
s = spltty();
|
||||
|
||||
if (chan == SCC_CHANNEL_A) {
|
||||
#ifdef DEBUG_CARRIER
|
||||
printf("scc_modem_intr: line %d,%d nomodem!\n",
|
||||
SCCUNIT(dev), SCCLINE(dev));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
s = spltty();
|
||||
SCC_READ_REG_ZERO(regs, chan, value);
|
||||
|
||||
#ifdef DEBUG_CARRIER
|
||||
printf("scc_modem_intr: line %d,%d carrier %d softcar %d\n",
|
||||
SCCUNIT(dev), SCCLINE(dev), value & ZSRR0_DCD,
|
||||
sc->scc_softCAR & (1 << chan));
|
||||
#endif
|
||||
|
||||
if (sc->scc_softCAR & (1 << chan))
|
||||
car = 1;
|
||||
else {
|
||||
|
@ -1503,10 +1511,10 @@ scc_modem_intr(dev)
|
|||
/*
|
||||
* The pmax driver follows carrier-detect. The Alpha does not.
|
||||
* On pmax, ignore hups on a console tty.
|
||||
* On alpha, a no-op, for historical reasons. XXXXXX
|
||||
* On alpha, a no-op, for historical reasons.
|
||||
*/
|
||||
#ifdef pmax
|
||||
if (!CONSOLE_ON_UNIT(sc->sc_dv.dv_unit) && !pending_remcons) {
|
||||
if (!CONSOLE_ON_UNIT(sc->sc_dv.dv_unit)) {
|
||||
if (car) {
|
||||
/* carrier present */
|
||||
if (!(tp->t_state & TS_CARR_ON))
|
||||
|
|
Loading…
Reference in New Issue