📄 sio.c
字号:
/* * Copyright (c) 1992 OMRON Corporation. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * OMRON Corporation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)sio.c 8.1 (Berkeley) 6/10/93 *//* * sio.c -- NEC uPD7201A UART Device Driver * remaked by A.Fujita, NOV-5-1992 */#include "sio.h"#if NSIO > 0#include "bmc.h"#include <sys/param.h>#include <sys/systm.h>#include <sys/ioctl.h>#include <sys/proc.h>#include <sys/tty.h>#include <sys/conf.h>#include <sys/file.h>#include <sys/uio.h>#include <sys/kernel.h>#include <sys/syslog.h>#include <luna68k/dev/device.h>#include <luna68k/dev/sioreg.h>#include <luna68k/dev/siovar.h>struct sio_portc *sio_port_assign();struct sio_portc *sio_port_get();int sioprobe();int sioopen();void siostart();int sioparam();int siointr();struct driver siodriver = { sioprobe, "sio",};struct sio_portc sio_portc[NPORT] = { { -1, -1, 0, (struct siodevice *) 0x51000000, (int (*)()) 0 }, { -1, -1, 1, (struct siodevice *) 0x51000004, (int (*)()) 0 }};struct sio_softc sio_softc[NSIO];int sio_init_done = 0;int siosoftCAR;int sio_active;int sioconsole = -1;int siodefaultrate = TTYDEF_SPEED;int siomajor = 12;struct tty sio_tty[NSIO];struct speedtab siospeedtab[] = { 2400, WR4_BAUD24, 4800, WR4_BAUD48, 9600, WR4_BAUD96,};#define siounit(x) minor(x)extern struct tty *constty;#ifdef KGDB/* * Kernel GDB support */#include <machine/remote-sl.h>extern dev_t kgdb_dev;extern int kgdb_rate;extern int kgdb_debug_init;#endif/* * probe routines */sioprobe(hd) register struct hp_device *hd;{ int unit = hd->hp_unit; register struct sio_softc *sc = &sio_softc[unit]; register struct sio_portc *pc; if (sc->sc_pc != 0) { pc = sc->sc_pc; printf("sio%d: port %d, address 0x%x, intr 0x%x (console)\n", pc->pc_unit, pc->pc_port, pc->pc_addr, pc->pc_intr); return(1); } sc->sc_pc = pc = sio_port_assign(unit, siomajor, unit, siointr); printf("sio%d: port %d, address 0x%x, intr 0x%x\n", pc->pc_unit, pc->pc_port, pc->pc_addr, pc->pc_intr); sio_active |= 1 << unit;#ifdef KGDB if (major(kgdb_dev) == siomajor) {#ifdef notdef if (sioconsole == siounit(kgdb_dev)) { kgdb_dev = NODEV; /* can't debug over console port */ } else {#endif /* * The following could potentially be replaced * by the corresponding code in dcmcnprobe. */ if (kgdb_debug_init) { printf("sio%d: ", siounit(kgdb_dev)); kgdb_connect(1); } else printf("sio%d: kgdb enabled\n", siounit(kgdb_dev));#ifdef notdef }#endif /* end could be replaced */ }#endif siosoftCAR |= 1 << unit; return(1);}struct sio_portc *sio_port_assign(port, major, unit, intr) int port, major, unit; int (*intr)();{ register struct sio_portc *pc; pc = &sio_portc[port]; pc->pc_major = major; pc->pc_intr = intr; pc->pc_unit = unit; return(pc);}struct sio_portc *sio_port_get(port) int port;{ register struct sio_portc *pc; pc = &sio_portc[port]; return(pc);}int sio_port_info(){ printf("sio_port_info[sio.c]:\t{%d} major = %d, unit = %d, intr = 0x%x\n", 0, sio_portc[0].pc_major, sio_portc[0].pc_unit, sio_portc[0].pc_intr); printf("sio_port_info[sio.c]:\t{%d} major = %d, unit = %d, intr = 0x%x\n", 1, sio_portc[1].pc_major, sio_portc[1].pc_unit, sio_portc[1].pc_intr);}/* * entry routines *//* ARGSUSED */#ifdef __STDC__sioopen(dev_t dev, int flag, int mode, struct proc *p)#elsesioopen(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p;#endif{ register struct tty *tp; register int unit; int error = 0; unit = siounit(dev); if (unit >= NSIO || (sio_active & (1 << unit)) == 0) return (ENXIO); tp = &sio_tty[unit]; tp->t_oproc = siostart; tp->t_param = sioparam; tp->t_dev = dev; if ((tp->t_state & TS_ISOPEN) == 0) { tp->t_state |= TS_WOPEN; ttychars(tp); if (tp->t_ispeed == 0) { tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG;/* tp->t_cflag = TTYDEF_CFLAG; */ tp->t_cflag = (CREAD | CS8 | HUPCL); tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = siodefaultrate; } sioparam(tp, &tp->t_termios); ttsetwater(tp); } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) return (EBUSY); (void) siomctl(dev, WR5_DTR | WR5_RTS, DMSET); if ((siosoftCAR & (1 << unit)) || (siomctl(dev, 0, DMGET) & RR0_DCD)) tp->t_state |= TS_CARR_ON; (void) spltty(); while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && (tp->t_state & TS_CARR_ON) == 0) { tp->t_state |= TS_WOPEN; if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, ttopen, 0)) break; } (void) spl0(); if (error == 0) error = (*linesw[tp->t_line].l_open)(dev, tp); return (error);}/*ARGSUSED*/sioclose(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p;{ register struct tty *tp; register int unit; unit = siounit(dev); tp = &sio_tty[unit]; (*linesw[tp->t_line].l_close)(tp, flag); (void) siomctl(dev, WR5_BREAK, DMBIS); if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || (tp->t_state&TS_ISOPEN) == 0) (void) siomctl(dev, 0, DMSET); ttyclose(tp); return (0);} sioread(dev, uio, flag) dev_t dev; struct uio *uio;{ register struct tty *tp = &sio_tty[siounit(dev)]; return ((*linesw[tp->t_line].l_read)(tp, uio, flag));} siowrite(dev, uio, flag) dev_t dev; struct uio *uio;{ register int unit = siounit(dev); register struct tty *tp = &sio_tty[unit]; if ((unit == sioconsole) && constty && (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) tp = constty; return ((*linesw[tp->t_line].l_write)(tp, uio, flag));}/* * Stop output on a line. *//*ARGSUSED*/siostop(tp, flag) register struct tty *tp;{ register int s; s = spltty(); if (tp->t_state & TS_BUSY) { if ((tp->t_state&TS_TTSTOP)==0) tp->t_state |= TS_FLUSH; } splx(s);}sioioctl(dev, cmd, data, flag, p) dev_t dev; int cmd; caddr_t data; int flag; struct proc *p;{ register struct tty *tp; register int unit = siounit(dev); register int error; tp = &sio_tty[unit]; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flag); if (error >= 0) return (error); switch (cmd) { case TIOCSBRK: (void) siomctl(dev, WR5_BREAK, DMBIS); break; case TIOCCBRK: (void) siomctl(dev, WR5_BREAK, DMBIC); break; case TIOCSDTR: (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIS); break; case TIOCCDTR: (void) siomctl(dev, WR5_DTR | WR5_RTS, DMBIC); break; case TIOCMSET: (void) siomctl(dev, *(int *)data, DMSET); break; case TIOCMBIS: (void) siomctl(dev, *(int *)data, DMBIS); break; case TIOCMBIC: (void) siomctl(dev, *(int *)data, DMBIC); break; case TIOCMGET: *(int *)data = siomctl(dev, 0, DMGET); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -