📄 dc7085.c
字号:
#ifndef lintstatic char *sccsid = "@(#)dc7085.c 4.6 (ULTRIX) 11/9/90";#endif lint/************************************************************************ * * * Copyright (c) 1988,89 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************ * * dc7085.c * * DC7085 SLU console driver * * Modification history * * 13-Sep-90 Joe Szczypek * Added new TURBOchannel console ROM support. osconsole environment * variable now returns 1 slot number is serial line, else 2 slot numbers * if graphics. Use this to determine how to do setup. Note that new * ROMs do not support multiple outputs... * * 4-Aug-90 - Randall Brown * Made modifications to allow the driver to be used on multiple controllers. * Implemented the 'slu' interface for graphics drivers to callback in * to the console driver to access mouse and keyboard. * * 6-Jul-1990 - Kuo-Hsiung Hsieh * Fixed data corrupted problem due to setting break condition * on a transmission line. On DC type of chip, a specific delay * period has to be imposed on the transmission line if the next * thing to transmit is a break condition. Data could be corrupted * even though TRDY bit may say it is ready to send the next character. * * 25-Apr-1990 - Kuo-Hsiung Hsieh * Disable line transmission before cleaning up break bit. * Prevented null character being generated following a break * condition. * * 23-Mar-1990 - Kuo-Hsiung Hsieh * Corrected the improper sequence of closing down the line. * This correction will prevent tty inmaturely turning off * flow control (fails to restart line drive) while there are * still more data in the buffer. ttyclose() should be called * before clearing up any terminal attributes. * * 8-Dec-1989 - Randall Brown * Added full modem support. Used variables to describe register * conditions instead of constants because pmax and 3max have the * bits in different places in certain registers. * * 6-Dec-89 - Randall Brown * * Added the support to allow the device to determine if baudrate is * supported before it is set in the tty data structures. * * 9-Nov-1989 - Randall Brown * In dc_putc(), take the line number as an argument, don't figure it * out from consDev. * * 29-Oct-1989 - Randall Brown * Added support for cons_init. The code from the probe routine is * now in dc_cons_init. Added wbflush() to dc_putc to let data get * to chip to clear interrupt. * * 16-Oct-1989 - Randall Brown * Added autoconfiguration support. * * 11-Jul-1989 - Randall Brown * Changed all sc->dc_tty to dc_tty since the dc_tty[] structure is not * part of the softc structure anymore. * * 15-Aug-89 - Randall Brown * * Changed all references of TCSADFLUSH to TCSAFLUSH * * 21-Jul-89 - Randall Brown * * Moved default open and default close code to tty.c and call it * using tty_def_open() and tty_def_close(). In the close routine, * don't clear the baudrate so that subsequent opens will keep the * present attributes. This only applies to a Berkeley environment. * * 12-Jun-1989 - dws * Added trusted path support. * * 28-Apr-1989 - Randall Brown * Changed a while loop in cn_putc to a DELAY(5). This was to fix a * problem that the system would hang if there was output to the * console and another serial line was active. * * 24-Feb-1989 - Randall Brown * Changed close routine to look at HUPCL in cflag, instead of HUPCLS in * state flag. * * 28-Dec-1988 - Randall Brown * Changed when the break bits were being set in the chip. Previously * they were being set in the ioctl, but this could cause data * corruption because the state of the chip is unknown. The bits are * now set in the transmitter interrupt routine, where the state of the * chip is known. * * 22-Dec-1988 - Randall Brown * Changed the open routine to return ENXIO on the open of /dev/xcons * when the graphic device is not being used. * * 16-Dec-1988 - Randall Brown * Added Pseudo DMA code to the transmit side of the driver. The start * routine sets up the pointers in the pdma struct for the number * of continuous chars in the outq. When a transmitter interrupt is * serviced, the pdma struct is checked to see if there are any more * chars to be output, if not it call dcxint(), to fill in the * pointers again. * * 17-Nov-1988 - Randall Brown * Added modem support. The driver only looks at DSR, and ignores * CD and CTS. Also cleaned up driver so that names are consistent. * Also fixed some problems with byte reads and writes (ie. removed * all byte read and writes, and made them half-word reads and writes) * * 7-Jul-1988 - rsp (Ricky Palmer) * Created file. Contents based on ss.c file. * */#include "../data/dc_data.c"int dcprobe(), dcattach(), dcrint();int dc_dsr_check(), dc_tty_drop(), dc_cd_drop(); /* Modem */u_short dcstd[] = { 0 };struct uba_driver dcdriver = { dcprobe, 0, dcattach, 0, dcstd, "dc", dcinfo };#define GRAPHIC_DEV 0x2 /* pick up from pm header file later */#define LINEMASK 0x03 /* line unit mask *//** The SLU doesn't interrupt on carrier transitions, so* we have to use a timer to watch it.*/char dc_timer = 0; /* timer started? */int dc_base_board = 0; /* defines whether there is a dc controller */ /* on the base board that is used for the graphics */ /* devices *//* * Baud Rate Support * * When the baud rate on the right is specified, the line parameter register * is setup with the appropriate bits as specified in the left column. */#define BAUD_UNSUPPORTED 0 /* Device does not provide this baud rate */#define BAUD_SUPPORTED 1 /* Device does provide this baud rate *//* * PMAX does not support 19.2K, but on 3MAX, * if the BAUD38 bit of the System Control and Status Register is set the * chip can do 38400 baud in which case EXTB would be supported. This bit * applies to all 4 lines such that it is not possible to simultaneously do * 19200 and 38400. To keep things simple, only provide support for 19.2. * * The option card supports 19.2K. The setting of this being supported is * taken care of in the attach routine. */struct baud_support dc_speeds[] = { {0, BAUD_UNSUPPORTED}, /* B0 */ {DC_B50, BAUD_SUPPORTED}, /* B50 */ {DC_B75, BAUD_SUPPORTED}, /* B75 */ {DC_B110, BAUD_SUPPORTED}, /* B110 */ {DC_B134_5, BAUD_SUPPORTED}, /* B134 */ {DC_B150, BAUD_SUPPORTED}, /* B150 */ {0, BAUD_UNSUPPORTED}, /* B200 */ {DC_B300, BAUD_SUPPORTED}, /* B300 */ {DC_B600, BAUD_SUPPORTED}, /* B600 */ {DC_B1200, BAUD_SUPPORTED}, /* B1200 */ {DC_B1800, BAUD_SUPPORTED}, /* B1800 */ {DC_B2400, BAUD_SUPPORTED}, /* B2400 */ {DC_B4800, BAUD_SUPPORTED}, /* B4800 */ {DC_B9600, BAUD_SUPPORTED}, /* B9600 */ {DC_B19200, BAUD_UNSUPPORTED}, /* EXTA */ {0, BAUD_UNSUPPORTED}, /* EXTB */ };extern int consDev;#define DS3100_DC_BASE (PHYS_TO_K1(0x1c000000))#define DS5000_DC_BASE (PHYS_TO_K1(0x1fe00000))#define DC_OPTION_OFFSET 0x80000 /* register offset from beginning of slot */int dcstart(), dcxint(), dcbaudrate();int ttrstrt();void dcsetbreak();/* * Graphics device driver entry points. * Used to call graphics device driver as needed. */extern (*vs_gdopen)();extern (*vs_gdclose)();extern (*vs_gdread)();extern (*vs_gdwrite)();extern (*vs_gdselect)();extern (*vs_gdkint)();extern (*vs_gdioctl)();extern (*vs_gdstop)();extern int (*v_consgetc)();extern int (*v_consputc)();extern int pmcons_init();extern int prom_getenv();extern int rex_getenv(); /* New TURBOchannel interface */extern int cpu;/* minumum delay value for setting a break condition. If we set * a break condition without delaying this minimum interval, we * might corrupt character which is still in the shift register. * The delay values are calculated based on the following equation; * 12 (bits/char) * 256 (hz) / baudrate + 2 (safety factor). */u_char dc_delay[] ={ 0,78,42,30,25,22,0,12,7,5,4,3,2,2,2,0 };#ifdef DEBUGint dcdebug = 0;#define PRINT_SIGNALS() { cprintf("Modem signals: "); \ if (sc->dcmsr&dc_rdsr[2]) cprintf(" DSR2 "); \ if (sc->dcmsr&dc_rcts[2]) cprintf(" CTS2 "); \ if (sc->dcmsr&dc_rcd[2]) cprintf(" CD2 "); \ if (sc->dcmsr&dc_rdsr[3]) cprintf(" DSR3 "); \ if (sc->dcmsr&dc_rcts[3]) cprintf(" CTS3 "); \ if (sc->dcmsr&dc_rcd[3]) cprintf(" CD3 "); \ cprintf("\n"); } \/* cprintf("sc->dcmsr %x : %x\n", &(sc->dcmsr), sc->dcmsr);*/#endif DEBUGdcprobe(reg)int reg;{ /* the intialization is done through dc_cons_init, so * if we have gotten this far we are alive so return a 1 */ return(1);}dcattach(ui) struct uba_device *ui;{ register int ctlr = ui->ui_unit; register struct dc_softc *sc = &dc_softc[ctlr]; register int i; extern dcscan(); dcsoftCAR[ctlr] = 0xff; dcdefaultCAR[ctlr] = 0xff; dc_brk[ctlr] = 0; for (i = 0; i < NDCLINE; i++) { brk_start[(ctlr * NDCLINE) +i] = brk_stop[(ctlr * NDCLINE) +i] = 0; } switch (cpu) { case DS_3100: dc_base_board = 1; dc_modem_ctl = 0; /* PMAX has limited modem control */ /* line 2 definitions */ dc_rdtr[2] = 0x0400; dc_rdsr[2] = 0x0200; dc_xmit[2] = dc_rdsr[2]; dc_rrts[2] = dc_rcts[2] = dc_rcd[2] = 0; dc_modem_line[2] = 1; /* line 3 definitions */ dc_rdtr[3] = 0x0800; dc_rdsr[3] = 0x0001; dc_xmit[3] = dc_rdsr[3]; dc_rrts[3] = dc_rcts[3] = dc_rcd[3] = 0; dc_modem_line[3] = 1; break; case DS_5000: if (ctlr == 0) { dc_base_board = 1; dc_modem_ctl = 1; /* 3max has full modem control */ /* line 2 definitions */ dc_rdtr[2] = 0x0400; dc_rrts[2] = 0x0800; dc_rcd[2] = 0x0400; dc_rdsr[2] = 0x0200; dc_rcts[2] = 0x0100; dc_xmit[2] = dc_rcd[2] | dc_rdsr[2] | dc_rcts[2]; dc_modem_line[2] = 1; /* line 3 definitions */ dc_rdtr[3] = 0x0100; dc_rrts[3] = 0x0200; dc_rcd[3] = 0x0004; dc_rdsr[3] = 0x0002; dc_rcts[3] = 0x0001; dc_xmit[3] = dc_rcd[3] | dc_rdsr[3] | dc_rcts[3]; dc_modem_line[3] = 1; } else { sc->sc_regs = (struct dc_reg *)(ui->ui_addr + DC_OPTION_OFFSET); } dc_speeds[B19200].baud_support = BAUD_SUPPORTED; break; case DS_5000_100: sc->sc_regs = (struct dc_reg *)(ui->ui_addr + DC_OPTION_OFFSET); dc_speeds[B19200].baud_support = BAUD_SUPPORTED; break; default: printf("Unknown cpu type in dcattach()\n"); break; } if (dc_modem_line[2]) { /* this is a base board controller, start modem ctl */ /* clear modem control signals */ sc->dcdtr &= ~(dc_rdtr[2] | dc_rrts[2] | dc_rdtr[3] | dc_rrts[3]); /* Start the modem scan timer */ if (!dc_timer) { timeout(dcscan, (caddr_t)0, hz); dc_timer = 1; } }}dc_cons_init(){ int i, temp_reg; int tmp1; /* ROM debug only */ register struct dc_softc *sc; extern int console_magic; extern int (*vcons_init[])(); int dc_mouse_init(), dc_mouse_putc(), dc_mouse_getc(); int dc_kbd_init(), dc_kbd_putc(), dc_kbd_getc(), dc_putc(); sc = &dc_softc[0]; switch (cpu) { case DS_3100: sc->sc_regs = (struct dc_reg *)DS3100_DC_BASE; break; case DS_5000: sc->sc_regs = (struct dc_reg *)DS5000_DC_BASE; break; default: printf("Unknown cpu type in dc_cons_init()\n"); break; } /* * * Query the prom. The prom can be set such that the user * could use either the alternate tty or the graphics console. * You get the graphics console if the first bit is set in * osconsole. The user sets the console variable */ if (console_magic != 0x30464354) { if ((atoi(prom_getenv("osconsole")) & 0x1) == 1) { slu.mouse_init = dc_mouse_init; slu.mouse_putc = dc_mouse_putc; slu.mouse_getc = dc_mouse_getc; slu.kbd_init = dc_kbd_init; slu.kbd_putc = dc_kbd_putc; slu.kbd_getc = dc_kbd_getc; slu.slu_tty = dc_tty; slu.slu_putc = dc_putc; for( i = 0 ; vcons_init[i] ; i++ ) if ((*vcons_init[i])()) { /* found a virtual console */ consDev = GRAPHIC_DEV; break; } } else { sc->dclpr = (DC_RE | DC_B9600 | BITS8 | 3); /* set up line 3, console line */ sc->dctcr = (DC_TCR_EN_3); /* line 3 transmit enable */ sc->dccsr = (DC_MSE); /* master scan enable */ } } else { if ((strlen(rex_getenv("osconsole"))) > 1) { slu.mouse_init = dc_mouse_init; slu.mouse_putc = dc_mouse_putc; slu.mouse_getc = dc_mouse_getc; slu.kbd_init = dc_kbd_init; slu.kbd_putc = dc_kbd_putc; slu.kbd_getc = dc_kbd_getc; slu.slu_tty = dc_tty; slu.slu_putc = dc_putc; for( i = 0 ; vcons_init[i] ; i++ ) if ((*vcons_init[i])()) { /* found a virtual console */ consDev = GRAPHIC_DEV; break; } } else { sc->dclpr = (DC_RE | DC_B9600 | BITS8 | 3); /* set up line 3, console line */ sc->dctcr = (DC_TCR_EN_3); /* line 3 transmit enable */ sc->dccsr = (DC_MSE); /* master scan enable */ } }}dcopen(dev, flag) dev_t dev;{ register struct dc_softc *sc; register struct tty *tp; register int ctlr, unit; register int maj, error; int inuse; /*hold state of inuse bit while blocked waiting for carr*/ maj = major(dev); unit = minor(dev); ctlr = unit >> 2; /* rpbfix: need to check to see if the board is actually in the system */ sc = &dc_softc[ctlr]; /* * If a diagnostic console is attached to SLU line 3, * don't allow open of the printer port (also line 3). * This could cause lpr to write to the console. * * This is only true of the base board option. */ if (dc_base_board && (ctlr == 0)) if((consDev != GRAPHIC_DEV) && (unit == 3)) return (ENXIO); /* don't allow open of minor device 0 of major device DCMAJOR */ /* if this is a base board option, because it is already */ /* reserved for /dev/console */ if (dc_base_board && (maj != CONSOLEMAJOR) && (unit == 0)) return (ENXIO); /* only allow open of /dev/console of major device 0 */ if ((maj == CONSOLEMAJOR) && (unit != 0)) return (ENXIO); if ((consDev != GRAPHIC_DEV) && (maj == CONSOLEMAJOR) && (unit == 0)) unit |= 3; /* diag console on SLU line 3 */ if (unit >= dc_cnt) return (ENXIO); /* * Call the graphics device open routine * if there is one and the open if for the fancy tube. */ if (dc_base_board && (ctlr == 0)) if (vs_gdopen && (unit <= 1)) { error = (*vs_gdopen)(dev, flag); if (error == 0) dcparam(unit); /* turn on interrupts for kbd and mouse */ return(error); } tp = &dc_tty[unit]; if (tp->t_state&TS_XCLUDE && u.u_uid != 0) { return (EBUSY); } while (tp->t_state&TS_CLOSING) { /* let DTR stay down for awhile */ sleep((caddr_t)&tp->t_rawq, TTIPRI); } tp->t_addr = (caddr_t)tp; tp->t_oproc = dcstart; tp->t_baudrate = dcbaudrate; tty_def_open(tp, dev, flag, (dcsoftCAR[ctlr]&(1<<(unit&LINEMASK)))); if ((tp->t_state & TS_ISOPEN) == 0) { /* * Prevent spurious startups by making the 500ms timer * initially high. */ dcmodem[unit] = MODEM_DSR_START; if((maj == CONSOLEMAJOR) && ((minor(dev)&3) == 0)) { tp->t_cflag &= ~CBAUD; tp->t_cflag |= B9600; /* modem control not supported on console */ tp->t_cflag |= CLOCAL; tp->t_cflag_ext &= ~CBAUD; tp->t_cflag_ext |= B9600; tp->t_flags = ANYP|ECHO|CRMOD; tp->t_iflag |= ICRNL; /* Map CRMOD */ tp->t_oflag |= ONLCR; /* Map CRMOD */ } } dcparam(unit); /* enables interrupts */ (void) spltty(); /* * No modem control provided for lines with softCAR set. * Modem control provided only for lines 2 and 3 of the base board. */ if (dc_modem_line[unit] == 0) tp->t_cflag |= CLOCAL;# ifdef DEBUG if (dcdebug) cprintf("dcopen: UNIT = %x\n",unit);# endif DEBUG if (tp->t_cflag & CLOCAL) { /* * This is a local connection - ignore carrier * receive enable interrupts enabled above via dcparam() */ tp->t_state |= TS_CARR_ON; /* dcscan sets */ sc->dcdtr |= (dc_rdtr[unit] | dc_rrts[unit]); /* * Set state bit to tell tty.c not to assign this line as the * controlling terminal for the process which opens this line. */ if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX)) tp->t_state |= TS_ONOCTTY; (void) spl0(); return ((*linesw[tp->t_line].l_open)(dev, tp)); } /* * this is a modem line */ /* receive enable interrupts enabled above via dcparam() */ sc->dcdtr |= (dc_rdtr[unit] | dc_rrts[unit]); /* * After DSR first comes up we must wait for the other signals * before commencing transmission. */#ifdef DEBUG if (dcdebug) { cprintf("open flag : %x\n", flag); if (flag & (O_NDELAY|O_NONBLOCK)) cprintf("flag & (O_NDELAY|O_NONBLOCK)\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -