Esempio n. 1
0
static void
dl_attach (struct device *parent, struct device *self, void *aux)
{
	struct dl_softc *sc = device_private(self);
	struct uba_attach_args *ua = aux;

	sc->sc_iot = ua->ua_iot;
	sc->sc_ioh = ua->ua_ioh;

	/* Tidy up the device */

	DL_WRITE_WORD(DL_UBA_RCSR, DL_RCSR_RXIE);
	DL_WRITE_WORD(DL_UBA_XCSR, DL_XCSR_TXIE);

	/* Initialize our softc structure. Should be done in open? */

	sc->sc_tty = ttymalloc();
	tty_attach(sc->sc_tty);

	/* Now register the TX & RX interrupt handlers */
	uba_intr_establish(ua->ua_icookie, ua->ua_cvec,
		dlxint, sc, &sc->sc_tintrcnt);
	uba_intr_establish(ua->ua_icookie, ua->ua_cvec - 4,
		dlrint, sc, &sc->sc_rintrcnt);
	evcnt_attach_dynamic(&sc->sc_rintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
		device_xname(&sc->sc_dev), "rintr");
	evcnt_attach_dynamic(&sc->sc_tintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
		device_xname(&sc->sc_dev), "tintr");

	printf("\n");
}
Esempio n. 2
0
int
vconsopen(dev_t dev, int flag, int mode, struct proc *p)
{
	struct vcons_softc *sc;
	struct tty *tp;
	int unit = minor(dev);

	if (unit > vcons_cd.cd_ndevs)
		return (ENXIO);
	sc = vcons_cd.cd_devs[unit];
	if (sc == NULL)
		return (ENXIO);

	if (sc->sc_tty)
		tp = sc->sc_tty;
	else
		tp = sc->sc_tty = ttymalloc(0);

	tp->t_oproc = vconsstart;
	tp->t_param = vconsparam;
	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_cflag = TTYDEF_CFLAG;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		ttsetwater(tp);
	} else if ((tp->t_state & TS_XCLUDE) && suser(p, 0))
		return (EBUSY);
	tp->t_state |= TS_CARR_ON;

	return ((*linesw[tp->t_line].l_open)(dev, tp, p));
}
Esempio n. 3
0
void
kminit(void)
{
	km_tty[0] = ttymalloc();
   	km_tty[0]->t_dev = makedev(12, 0);
	initialized = 1;
}
Esempio n. 4
0
void
ucom_attach(struct device *parent, struct device *self, void *aux)
{
	struct ucom_softc *sc = (struct ucom_softc *)self;
	struct ucom_attach_args *uca = aux;
	struct tty *tp;

	if (uca->info != NULL)
		printf(", %s", uca->info);
	printf("\n");

	sc->sc_udev = uca->device;
	sc->sc_iface = uca->iface;
	sc->sc_bulkout_no = uca->bulkout;
	sc->sc_bulkin_no = uca->bulkin;
	sc->sc_uhidev = uca->uhidev;
	sc->sc_ibufsize = uca->ibufsize;
	sc->sc_ibufsizepad = uca->ibufsizepad;
	sc->sc_obufsize = uca->obufsize;
	sc->sc_opkthdrlen = uca->opkthdrlen;
	sc->sc_methods = uca->methods;
	sc->sc_parent = uca->arg;
	sc->sc_portno = uca->portno;

	tp = ttymalloc();
	tp->t_oproc = ucomstart;
	tp->t_param = ucomparam;
	sc->sc_tty = tp;
	sc->sc_cua = 0;

	rw_init(&sc->sc_lock, "ucomlk");

	sc->sc_open = 0;
}
Esempio n. 5
0
/*ARGSUSED*/
int
ptcopen(dev_t dev, int flag, int devtype, struct proc *p)
{
	struct pt_softc *pti;
	struct tty *tp;
	int error;

	if ((error = check_pty(minor(dev))))
		return (error);

	pti = pt_softc[minor(dev)];
	if (!pti->pt_tty) {
		tp = pti->pt_tty = ttymalloc();
	} else
		tp = pti->pt_tty;
	if (tp->t_oproc)
		return (EIO);
	tp->t_oproc = ptsstart;
	(void)(*linesw[tp->t_line].l_modem)(tp, 1);
	tp->t_lflag &= ~EXTPROC;
	pti->pt_flags = 0;
	pti->pt_send = 0;
	pti->pt_ucntl = 0;
	return (0);
}
Esempio n. 6
0
int
dartopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int s, port;
	struct dart_info *dart;
	struct dartsoftc *sc;
	struct tty *tp;

	port = DART_PORT(dev);
	if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS)
		return (ENODEV);
	sc = (struct dartsoftc *)dart_cd.cd_devs[0]; /* the only one */
	dart = &sc->sc_dart[port];

	s = spltty();
	if (dart->tty != NULL)
		tp = dart->tty;
	else
		tp = dart->tty = ttymalloc();

	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 == CONS_PORT) {
			/* 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);
		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;
	splx(s);
	return ((*linesw[tp->t_line].l_open)(dev, tp));
}
Esempio n. 7
0
/*
 * Check if the minor is correct and ensure necessary structures
 * are properly allocated.
 */
int
check_pty(int minor)
{
	struct pt_softc *pti;

	rw_enter_write(&pt_softc_lock);
	if (minor >= npty) {
		struct pt_softc **newpt;
		int newnpty;

		/* check if the requested pty can be granted */
		if (minor >= maxptys)
			goto limit_reached;

		/* grow pty array by powers of two, up to maxptys */
		for (newnpty = npty; newnpty <= minor; newnpty *= 2)
			;

		if (newnpty > maxptys)
			newnpty = maxptys;
		newpt = ptyarralloc(newnpty);

		if (maxptys == npty) {
			goto limit_reached;
		}

		memcpy(newpt, pt_softc, npty * sizeof(struct pt_softc *));
		free(pt_softc, M_DEVBUF);
		pt_softc = newpt;
		npty = newnpty;
	}

	/*
	 * If the entry is not yet allocated, allocate one.
	 */
	if (!pt_softc[minor]) {
		pti = malloc(sizeof(struct pt_softc), M_DEVBUF,
		    M_WAITOK|M_ZERO);
		pti->pt_tty = ttymalloc();
		ptydevname(minor, pti);
		pt_softc[minor] = pti;
	}
	rw_exit_write(&pt_softc_lock);
	return (0);
limit_reached:
	rw_exit_write(&pt_softc_lock);
	tablefull("pty");
	return (ENXIO);
}
Esempio n. 8
0
static int
ofw_dev_open(dev_t dev, int flag, int mode, struct thread *td)
{
	struct	tty *tp;
	int	unit;
	int	error, setuptimeout;

	error = 0;
	setuptimeout = 0;
	unit = minor(dev);

	tp = ofw_tp = dev->si_tty = ttymalloc(ofw_tp);

	tp->t_oproc = ofw_tty_start;
	tp->t_param = ofw_tty_param;
	tp->t_stop = ofw_tty_stop;
	tp->t_dev = dev;

	if ((tp->t_state & TS_ISOPEN) == 0) {
		tp->t_state |= TS_CARR_ON;
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		ttsetwater(tp);

		setuptimeout = 1;
	} else if ((tp->t_state & TS_XCLUDE) && suser(td)) {
		return (EBUSY);
	}

	error = (*linesw[tp->t_line].l_open)(dev, tp);

	if (error == 0 && setuptimeout) {
		polltime = hz / OFW_POLL_HZ;
		if (polltime < 1) {
			polltime = 1;
		}

		ofw_timeouthandle = timeout(ofw_timeout, tp, polltime);
	}

	return (error);
}
Esempio n. 9
0
void
mtty_attach(struct device *parent, struct device *dev, void *args)
{
    struct magma_softc *sc = (struct magma_softc *)parent;
    struct mtty_softc *ms = (struct mtty_softc *)dev;
    int port, chip, chan;

    sc->ms_mtty = ms;
    dprintf((" addr 0x%x", ms));

    for (port = 0, chip = 0, chan = 0;
            port < sc->ms_board->mb_nser; port++) {
        struct mtty_port *mp = &ms->ms_port[port];
        struct tty *tp;

        mp->mp_cd1400 = &sc->ms_cd1400[chip];
        if (mp->mp_cd1400->cd_parmode && chan == 0) {
            /* skip channel 0 if parmode */
            chan = 1;
        }
        mp->mp_channel = chan;

        tp = ttymalloc(0);
        tp->t_oproc = mtty_start;
        tp->t_param = mtty_param;

        mp->mp_tty = tp;

        mp->mp_rbuf = malloc(MTTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT);
        if (mp->mp_rbuf == NULL)
            break;

        mp->mp_rend = mp->mp_rbuf + MTTY_RBUF_SIZE;

        chan = (chan + 1) % CD1400_NO_OF_CHANNELS;
        if (chan == 0)
            chip++;
    }

    ms->ms_nports = port;
    printf(": %d tty%s\n", port, port == 1 ? "" : "s");
}
Esempio n. 10
0
/*ARGSUSED*/
int
ptsopen(dev_t dev, int flag, int devtype, struct proc *p)
{
	struct pt_softc *pti;
	struct tty *tp;
	int error;

	if ((error = check_pty(minor(dev))))
		return (error);

	pti = pt_softc[minor(dev)];
	if (!pti->pt_tty) {
		tp = pti->pt_tty = ttymalloc();
	} else
		tp = pti->pt_tty;
	if ((tp->t_state & TS_ISOPEN) == 0) {
		tp->t_state |= TS_WOPEN;
		ttychars(tp);		/* Set up default chars */
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_cflag = TTYDEF_CFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		ttsetwater(tp);		/* would be done in xxparam() */
	} else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
		return (EBUSY);
	if (tp->t_oproc)			/* Ctrlr still around. */
		tp->t_state |= TS_CARR_ON;
	while ((tp->t_state & TS_CARR_ON) == 0) {
		tp->t_state |= TS_WOPEN;
		if (flag&FNONBLOCK)
			break;
		error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
				 ttopen, 0);
		if (error)
			return (error);
	}
	error = (*linesw[tp->t_line].l_open)(dev, tp);
	ptcwakeup(tp, FREAD|FWRITE);
	return (error);
}
Esempio n. 11
0
static int
dcons_attach_port(int port, char *name, int flags)
{
	struct dcons_softc *dc;
	struct tty *tp;

	dc = &sc[port];
	dc->flags = flags;
	dc->dev = make_dev(&dcons_cdevsw, port,
			UID_ROOT, GID_WHEEL, 0600, name);
	tp = ttymalloc(NULL);

	dc->dev->si_drv1 = (void *)dc;
	dc->dev->si_tty = tp;

	tp->t_oproc = dcons_tty_start;
	tp->t_param = dcons_tty_param;
	tp->t_stop = nottystop;
	tp->t_dev = dc->dev;

	return(0);
}
Esempio n. 12
0
static int
dcons_open(dev_t dev, int flag, int mode, struct THREAD *td)
{
	struct tty *tp;
	int unit, error, s;

	unit = minor(dev);
	if (unit != 0)
		return (ENXIO);

	tp = dev->si_tty = ttymalloc(dev->si_tty);
	tp->t_oproc = dcons_tty_start;
	tp->t_param = dcons_tty_param;
	tp->t_stop = nottystop;
	tp->t_dev = dev;

	error = 0;

	s = spltty();
	if ((tp->t_state & TS_ISOPEN) == 0) {
		tp->t_state |= TS_CARR_ON;
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		ttsetwater(tp);
	} else if ((tp->t_state & TS_XCLUDE) && suser(td)) {
		splx(s);
		return (EBUSY);
	}
	splx(s);

	error = (*linesw[tp->t_line].l_open)(dev, tp);

	return (error);
}
Esempio n. 13
0
int
ucom_attach(struct ucom_softc *sc)
{
	struct tty *tp;
	int unit;

	unit = device_get_unit(sc->sc_dev);

	sc->sc_tty = tp = ttymalloc(sc->sc_tty);
	tp->t_oproc = ucomstart;
	tp->t_param = ucomparam;
	tp->t_stop = ucomstop;

	DPRINTF(("ucom_attach: tty_attach tp = %p\n", tp));

	DPRINTF(("ucom_attach: make_dev: ucom%d\n", unit));

	sc->dev = make_dev(&ucom_cdevsw, unit | UCOM_CALLOUT_MASK,
			UID_UUCP, GID_DIALER, 0660,
			"ucom%d", unit);
	sc->dev->si_tty = tp;

	return (0);
}
Esempio n. 14
0
File: zs.c Progetto: MarginC/kame
int
zstty_attach(device_t dev)
{
	struct zstty_softc *sc;
	struct tty *tp;
	char mode[32];
	int reset;
	int baud;
	int clen;
	char parity;
	int stop;
	char c;

	sc = device_get_softc(dev);
	mtx_init(&sc->sc_mtx, "zstty", NULL, MTX_SPIN);
	sc->sc_dev = dev;
	sc->sc_iput = sc->sc_iget = sc->sc_ibuf;
	sc->sc_oget = sc->sc_obuf;

	tp = ttymalloc(NULL);
	sc->sc_si = make_dev(&zstty_cdevsw, device_get_unit(dev),
	    UID_ROOT, GID_WHEEL, 0600, "%s", device_get_desc(dev));
	sc->sc_si->si_drv1 = sc;
	sc->sc_si->si_tty = tp;
	tp->t_dev = sc->sc_si;
	sc->sc_tty = tp;

	tp->t_oproc = zsttystart;
	tp->t_param = zsttyparam;
	tp->t_stop = zsttystop;
	tp->t_iflag = TTYDEF_IFLAG;
	tp->t_oflag = TTYDEF_OFLAG;
	tp->t_lflag = TTYDEF_LFLAG;
	tp->t_cflag = CREAD | CLOCAL | CS8;
	tp->t_ospeed = TTYDEF_SPEED;
	tp->t_ispeed = TTYDEF_SPEED;

	if (zstty_console(dev, mode, sizeof(mode))) {
		ttychars(tp);
		/* format: 9600,8,n,1,- */
		if (sscanf(mode, "%d,%d,%c,%d,%c", &baud, &clen, &parity,
		    &stop, &c) == 5) {
			tp->t_ospeed = baud;
			tp->t_ispeed = baud;
			tp->t_cflag = CREAD | CLOCAL;
			switch (clen) {
			case 5:
				tp->t_cflag |= CS5;
				break;
			case 6:
				tp->t_cflag |= CS6;
				break;
			case 7:
				tp->t_cflag |= CS7;
				break;
			case 8:
			default:
				tp->t_cflag |= CS8;
				break;
			}

			if (parity == 'e')
				tp->t_cflag |= PARENB;
			else if (parity == 'o')
				tp->t_cflag |= PARENB | PARODD;

			if (stop == 2)
				tp->t_cflag |= CSTOPB;
		}
		device_printf(dev, "console %s\n", mode);
		sc->sc_console = 1;
		zstty_cons = sc;
	} else {
		if ((device_get_unit(dev) & 1) == 0)
			reset = ZSWR9_A_RESET;
		else
			reset = ZSWR9_B_RESET;
		ZS_WRITE_REG(sc, 9, reset);
	}

	return (0);
}
Esempio n. 15
0
void
sacom_attach_subr(struct sacom_softc *sc)
{
    bus_addr_t iobase = sc->sc_baseaddr;
    bus_space_tag_t iot = sc->sc_iot;
    struct tty *tp;

    /* XXX Do we need to disable interrupts here? */

    if (iot == sacomconstag && iobase == sacomconsaddr) {
        sacomconsattached = 1;
        sc->sc_speed = SACOMSPEED(sacomconsrate);

        /* Make sure the console is always "hardwired". */
        delay(10000);			/* wait for output to finish */
        SET(sc->sc_hwflags, COM_HW_CONSOLE);
        SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
    }

    tp = ttymalloc();
    tp->t_oproc = sacomstart;
    tp->t_param = sacomparam;
    tp->t_hwiflow = sacomhwiflow;

    sc->sc_tty = tp;
    sc->sc_rbuf = malloc(SACOM_RING_SIZE << 1, M_DEVBUF, M_NOWAIT);
    sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
    sc->sc_rbavail = SACOM_RING_SIZE;
    if (sc->sc_rbuf == NULL) {
        printf("%s: unable to allocate ring buffer\n",
               sc->sc_dev.dv_xname);
        return;
    }
    sc->sc_ebuf = sc->sc_rbuf + (SACOM_RING_SIZE << 1);
    sc->sc_tbc = 0;

    tty_attach(tp);

    if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
        int maj;

        /* locate the major number */
        maj = cdevsw_lookup_major(&sacom_cdevsw);

        cn_tab->cn_dev = makedev(maj, device_unit(&sc->sc_dev));

        delay(10000); /* XXX */
        printf("%s: console\n", sc->sc_dev.dv_xname);
        delay(10000); /* XXX */
    }


    sc->sc_si = softint_establish(SOFTINT_SERIAL, sacomsoft, sc);

#if NRND > 0 && defined(RND_COM)
    rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
                      RND_TYPE_TTY, 0);
#endif

    /* if there are no enable/disable functions, assume the device
       is always enabled */
    if (!sc->enable)
        sc->enabled = 1;

    sacom_config(sc);

    SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
Esempio n. 16
0
int
dartopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int s;
	u_int port, chip;
	struct dart_info *dart;
	struct dartsoftc *sc;
	struct tty *tp;

	chip = DART_CHIP(dev);
	port = DART_PORT(dev);
	if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS)
		return (ENODEV);
	sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
	if (sc == NULL)
		return (ENODEV);
	dart = &sc->sc_dart[port];

	s = spltty();
	if (dart->tty != NULL)
		tp = dart->tty;
	else
		tp = dart->tty = ttymalloc(0);

	tp->t_oproc = dartstart;
	tp->t_param = dartparam;
	tp->t_dev = dev;

	if ((tp->t_state & TS_ISOPEN) == 0) {
		ttychars(tp);

		if (tp->t_ispeed == 0) {
			tp->t_iflag = TTYDEF_IFLAG;
			tp->t_oflag = TTYDEF_OFLAG;
			tp->t_lflag = TTYDEF_LFLAG;
			tp->t_ispeed = tp->t_ospeed = B9600;
			if (sc->sc_console && port == CONS_PORT) {
				/* console is 8N1 */
				tp->t_cflag = (CREAD | CS8 | HUPCL);
			} else {
				tp->t_cflag = TTYDEF_CFLAG;
			}
		}

		if (dart->dart_swflags & TIOCFLAG_CLOCAL)
			tp->t_cflag |= CLOCAL;
		if (dart->dart_swflags & TIOCFLAG_CRTSCTS)
			tp->t_cflag |= CRTSCTS;
		if (dart->dart_swflags & TIOCFLAG_MDMBUF)
			tp->t_cflag |= MDMBUF;

		dartparam(tp, &tp->t_termios);
		ttsetwater(tp);

		(void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMSET);
		tp->t_state |= TS_CARR_ON;
	} else if (tp->t_state & TS_XCLUDE && suser(p, 0) != 0) {
		splx(s);
		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;
	splx(s);
	return ((*linesw[tp->t_line].l_open)(dev, tp, p));
}
Esempio n. 17
0
int
com_activate(struct device *self, int act)
{
	struct com_softc *sc = (struct com_softc *)self;
	int s, rv = 0;

	switch (act) {
	case DVACT_SUSPEND:
		if (timeout_del(&sc->sc_dtr_tmo)) {
			/* Make sure DTR gets raised upon resume. */
			SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
		}
		timeout_del(&sc->sc_diag_tmo);
		break;
	case DVACT_RESUME:
		com_resume(sc);
		break;
	case DVACT_DEACTIVATE:
#ifdef KGDB
		if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
#else
		if (sc->sc_hwflags & COM_HW_CONSOLE) {
#endif /* KGDB */
			rv = EBUSY;
			break;
		}

		s = spltty();
		if (sc->disable != NULL && sc->enabled != 0) {
			(*sc->disable)(sc);
			sc->enabled = 0;
		}
		splx(s);
		break;
	}
	return (rv);
}

int
comopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int unit = DEVUNIT(dev);
	struct com_softc *sc;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	struct tty *tp;
	int s;
	int error = 0;

	if (unit >= com_cd.cd_ndevs)
		return ENXIO;
	sc = com_cd.cd_devs[unit];
	if (!sc)
		return ENXIO;

#ifdef KGDB
	/*
	 * If this is the kgdb port, no other use is permitted.
	 */
	if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
		return (EBUSY);
#endif /* KGDB */

	s = spltty();
	if (!sc->sc_tty) {
		tp = sc->sc_tty = ttymalloc(1000000);
	} else
		tp = sc->sc_tty;
	splx(s);

	tp->t_oproc = comstart;
	tp->t_param = comparam;
	tp->t_dev = dev;
	if (!ISSET(tp->t_state, TS_ISOPEN)) {
		SET(tp->t_state, TS_WOPEN);
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
#ifdef COM_CONSOLE
		if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
			tp->t_cflag = comconscflag;
			tp->t_ispeed = tp->t_ospeed = comconsrate;
		} else
#endif
		{
			tp->t_cflag = TTYDEF_CFLAG;
			tp->t_ispeed = tp->t_ospeed = comdefaultrate;
		}
		if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
			SET(tp->t_cflag, CLOCAL);
		if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
			SET(tp->t_cflag, CRTSCTS);
		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
			SET(tp->t_cflag, MDMBUF);
		tp->t_lflag = TTYDEF_LFLAG;

		s = spltty();

		sc->sc_initialize = 1;
		comparam(tp, &tp->t_termios);
		ttsetwater(tp);

		sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0];
		sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;
		sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;

		iot = sc->sc_iot;
		ioh = sc->sc_ioh;

		/*
		 * Wake up the sleepy heads.
		 */
		if (!ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
			switch (sc->sc_uarttype) {
			case COM_UART_ST16650:
			case COM_UART_ST16650V2:
				bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
				bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
				bus_space_write_1(iot, ioh, com_ier, 0);
				bus_space_write_1(iot, ioh, com_efr, 0);
				bus_space_write_1(iot, ioh, com_lcr, 0);
				break;
			case COM_UART_TI16750:
				bus_space_write_1(iot, ioh, com_ier, 0);
				break;
			case COM_UART_PXA2X0:
				bus_space_write_1(iot, ioh, com_ier, IER_EUART);
				break;
			}
		}

		if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
			u_int8_t fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST;
			u_int8_t lcr;

			if (tp->t_ispeed <= 1200)
				fifo |= FIFO_TRIGGER_1;
			else if (tp->t_ispeed <= 38400)
				fifo |= FIFO_TRIGGER_4;
			else
				fifo |= FIFO_TRIGGER_8;
			if (sc->sc_uarttype == COM_UART_TI16750) {
				fifo |= FIFO_ENABLE_64BYTE;
				lcr = bus_space_read_1(iot, ioh, com_lcr);
				bus_space_write_1(iot, ioh, com_lcr,
				    lcr | LCR_DLAB);
			}

			/*
			 * (Re)enable and drain FIFOs.
			 *
			 * Certain SMC chips cause problems if the FIFOs are
			 * enabled while input is ready. Turn off the FIFO
			 * if necessary to clear the input. Test the input
			 * ready bit after enabling the FIFOs to handle races
			 * between enabling and fresh input.
			 *
			 * Set the FIFO threshold based on the receive speed.
			 */
			for (;;) {
				bus_space_write_1(iot, ioh, com_fifo, 0);
				delay(100);
				(void) bus_space_read_1(iot, ioh, com_data);
				bus_space_write_1(iot, ioh, com_fifo, fifo |
				    FIFO_RCV_RST | FIFO_XMT_RST);
				delay(100);
				if(!ISSET(bus_space_read_1(iot, ioh,
				    com_lsr), LSR_RXRDY))
					break;
			}
			if (sc->sc_uarttype == COM_UART_TI16750)
				bus_space_write_1(iot, ioh, com_lcr, lcr);
		}

		/* Flush any pending I/O. */
		while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
			(void) bus_space_read_1(iot, ioh, com_data);

		/* You turn me on, baby! */
		sc->sc_mcr = MCR_DTR | MCR_RTS;
		if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
			SET(sc->sc_mcr, MCR_IENABLE);
		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
		sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
#ifdef COM_PXA2X0
		if (sc->sc_uarttype == COM_UART_PXA2X0)
			sc->sc_ier |= IER_EUART | IER_ERXTOUT;
#endif  
		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);

		sc->sc_msr = bus_space_read_1(iot, ioh, com_msr);
		if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || DEVCUA(dev) ||
		    ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
			SET(tp->t_state, TS_CARR_ON);
		else
			CLR(tp->t_state, TS_CARR_ON);
#ifdef COM_PXA2X0
		if (sc->sc_uarttype == COM_UART_PXA2X0 &&
		    ISSET(sc->sc_hwflags, COM_HW_SIR)) {
			bus_space_write_1(iot, ioh, com_isr, ISR_RECV);
#ifdef __zaurus__
			scoop_set_irled(1);
#endif
		}
#endif
	} else if (ISSET(tp->t_state, TS_XCLUDE) && suser(p, 0) != 0)
		return EBUSY;
	else
		s = spltty();

	if (DEVCUA(dev)) {
		if (ISSET(tp->t_state, TS_ISOPEN)) {
			/* Ah, but someone already is dialed in... */
			splx(s);
			return EBUSY;
		}
		sc->sc_cua = 1;		/* We go into CUA mode. */
	} else {
		/* tty (not cua) device; wait for carrier if necessary. */
		if (ISSET(flag, O_NONBLOCK)) {
			if (sc->sc_cua) {
				/* Opening TTY non-blocking... but the CUA is busy. */
				splx(s);
				return EBUSY;
			}
		} else {
			while (sc->sc_cua ||
			    (!ISSET(tp->t_cflag, CLOCAL) &&
				!ISSET(tp->t_state, TS_CARR_ON))) {
				SET(tp->t_state, TS_WOPEN);
				error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
				/*
				 * If TS_WOPEN has been reset, that means the cua device
				 * has been closed.  We don't want to fail in that case,
				 * so just go around again.
				 */
				if (error && ISSET(tp->t_state, TS_WOPEN)) {
					CLR(tp->t_state, TS_WOPEN);
					if (!sc->sc_cua && !ISSET(tp->t_state, TS_ISOPEN))
						compwroff(sc);
					splx(s);
					return error;
				}
			}
		}
	}
	splx(s);

	return (*linesw[tp->t_line].l_open)(dev, tp, p);
}
Esempio n. 18
0
void
at91usart_attach_subr(struct at91usart_softc *sc, struct at91bus_attach_args *sa)
{
	struct tty *tp;
	int err;

	printf("\n");

	if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0, &sc->sc_ioh))
		panic("%s: Cannot map registers", device_xname(sc->sc_dev));

	sc->sc_iot = sa->sa_iot;
	sc->sc_hwbase = sa->sa_addr;
	sc->sc_dmat = sa->sa_dmat;
	sc->sc_pid = sa->sa_pid;

	/* allocate fifos */
	err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_rx_fifo, AT91USART_RING_SIZE, BUS_DMA_READ | BUS_DMA_STREAMING);
	if (err)
		panic("%s: cannot allocate rx fifo", device_xname(sc->sc_dev));

	err = at91pdc_alloc_fifo(sc->sc_dmat, &sc->sc_tx_fifo, AT91USART_RING_SIZE, BUS_DMA_WRITE | BUS_DMA_STREAMING);
	if (err)
		panic("%s: cannot allocate tx fifo", device_xname(sc->sc_dev));

	/* initialize uart */
	at91_peripheral_clock(sc->sc_pid, 1);

	at91usart_writereg(sc, US_IDR, -1);
	at91usart_writereg(sc, US_RTOR, 12);	// 12-bit timeout
	at91usart_writereg(sc, US_PDC + PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
	at91_intr_establish(sa->sa_pid, IPL_TTY, INTR_HIGH_LEVEL, at91usart_intr, sc);
	USART_INIT(sc, 115200U);

#ifdef	NOTYET
	if (sc->sc_iot == usart_cn_sc.sc_iot
	    && sc->sc_hwbase == usart_cn_sc.sc_hwbase) {
		usart_cn_sc.sc_attached = 1;
		/* Make sure the console is always "hardwired". */
		delay(10000);	/* wait for output to finish */
		SET(sc->sc_hwflags, COM_HW_CONSOLE);
		SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
		SET(sc->sc_ier, USART_INT_RXRDY);
		USARTREG(USART_IER) = USART_INT_RXRDY; // @@@@@
	}
#endif	// NOTYET

	tp = ttymalloc();
	tp->t_oproc = at91usart_start;
	tp->t_param = at91usart_param;
	tp->t_hwiflow = at91usart_hwiflow;

	sc->sc_tty = tp;

	tty_attach(tp);

#if	NOTYET
	if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&at91usart_cdevsw);

		cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));

		aprint_normal("%s: console (maj %u  min %u  cn_dev %u)\n",
		    device_xname(sc->sc_dev), maj, device_unit(sc->sc_dev),
		    cn_tab->cn_dev);
	}
#endif	/* NOTYET */

	sc->sc_si = softint_establish(SOFTINT_SERIAL, at91usart_soft, sc);

#if NRND > 0 && defined(RND_COM)
	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
			  RND_TYPE_TTY, 0);
#endif

	/* if there are no enable/disable functions, assume the device
	   is always enabled */
	if (!sc->enable)
		sc->enabled = 1;

	/* XXX configure register */
	/* xxx_config(sc) */

	SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
Esempio n. 19
0
static int
ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
{
	struct tty *tp;
	char buf[32];			/* temporary TTY device name buffer */
	cdev_t dev;

	kprintf("attach tty\n");

	lwkt_gettoken(&tty_token);
	
	kprintf("malloc: ");
	sc->sc_tty = tp = ttymalloc(sc->sc_tty);

	tp->t_oproc = ucom_start;
	tp->t_param = ucom_param;
	tp->t_stop = ucom_stop;
	
	if (tp == NULL) {
		lwkt_reltoken(&tty_token);
		return (ENOMEM);
	}

	/* Check if the client has a custom TTY name */
	buf[0] = '\0';
	if (sc->sc_callback->ucom_tty_name) {
		sc->sc_callback->ucom_tty_name(sc, buf,
		    sizeof(buf), ssc->sc_unit, sc->sc_subunit);
	}
	if (buf[0] == 0) {
		/* Use default TTY name */
		if (ssc->sc_subunits > 1) {
			/* multiple modems in one */
			ksnprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u.%u",
			    ssc->sc_unit, sc->sc_subunit);
		} else {
			/* single modem */
			ksnprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u",
			    ssc->sc_unit);
		}
	}

	dev = make_dev(&ucom_ops, ssc->sc_unit | 0x80, // XXX UCOM_CALLOUT_MASK,
			UID_UUCP, GID_DIALER, 0660,
			buf, ssc->sc_unit);
	dev->si_tty = tp;
	sc->sc_tty = tp;
	dev->si_drv1 = sc;
	
	DPRINTF("ttycreate: %s\n", buf);

	/* Check if this device should be a console */
	if ((ucom_cons_softc == NULL) && 
	    (ssc->sc_unit == ucom_cons_unit) &&
	    (sc->sc_subunit == ucom_cons_subunit)) {

		DPRINTF("unit %d subunit %d is console",
		    ssc->sc_unit, sc->sc_subunit);

		ucom_cons_softc = sc;

		/* XXXDF
		tty_init_console(tp, ucom_cons_baud);
		*/
		tp->t_termios.c_ispeed = ucom_cons_baud;
		tp->t_termios.c_ospeed = ucom_cons_baud;

		UCOM_MTX_LOCK(ucom_cons_softc);
		ucom_cons_rx_low = 0;
		ucom_cons_rx_high = 0;
		ucom_cons_tx_low = 0;
		ucom_cons_tx_high = 0;
		sc->sc_flag |= UCOM_FLAG_CONSOLE;
		
		ucom_open(ucom_cons_softc);
		ucom_param(tp, &tp->t_termios);
		UCOM_MTX_UNLOCK(ucom_cons_softc);
	}

	lwkt_reltoken(&tty_token);
	return (0);
}
Esempio n. 20
0
int
comopen(dev_t dev, int flag, int mode, struct lwp *l)
{
	struct com_softc *sc;
	int iobase;
	struct tty *tp;
	int s;
	int error = 0;

	sc =  device_lookup_private(&xcom_cd, COMUNIT(dev));
	if (!sc)
		return ENXIO;

	if (!sc->sc_tty) {
		tp = sc->sc_tty = ttymalloc();
		tty_attach(tp);
	} else
		tp = sc->sc_tty;

	tp->t_oproc = comstart;
	tp->t_param = comparam;
	tp->t_dev = dev;

	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
		return (EBUSY);

	s = spltty();

	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = TTYDEF_CFLAG;
		if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
			SET(tp->t_cflag, CLOCAL);
		if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
			SET(tp->t_cflag, CRTSCTS);
		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
			SET(tp->t_cflag, MDMBUF);
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = comdefaultrate;

		comparam(tp, &tp->t_termios);
		ttsetwater(tp);

		if (comsopen++ == 0)
			callout_reset(&com_poll_ch, 1, compollin, NULL);

		sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0];
		sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;
		sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;

		iobase = sc->sc_iobase;
#ifdef COM_HAYESP
		/* Setup the ESP board */
		if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
			int hayespbase = sc->sc_hayespbase;

			outb(iobase + com_fifo,
			     FIFO_DMA_MODE|FIFO_ENABLE|
			     FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_8);

			/* Set 16550 compatibility mode */
			outb(hayespbase + HAYESP_CMD1, HAYESP_SETMODE);
			outb(hayespbase + HAYESP_CMD2,
			     HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
			     HAYESP_MODE_SCALE);

			/* Set RTS/CTS flow control */
			outb(hayespbase + HAYESP_CMD1, HAYESP_SETFLOWTYPE);
			outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_RTS);
			outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_CTS);

			/* Set flow control levels */
			outb(hayespbase + HAYESP_CMD1, HAYESP_SETRXFLOW);
			outb(hayespbase + HAYESP_CMD2,
			     HAYESP_HIBYTE(HAYESP_RXHIWMARK));
			outb(hayespbase + HAYESP_CMD2,
			     HAYESP_LOBYTE(HAYESP_RXHIWMARK));
			outb(hayespbase + HAYESP_CMD2,
			     HAYESP_HIBYTE(HAYESP_RXLOWMARK));
			outb(hayespbase + HAYESP_CMD2,
			     HAYESP_LOBYTE(HAYESP_RXLOWMARK));
		} else
#endif
		if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
			/* Set the FIFO threshold based on the receive speed. */
			outb(pio(iobase , com_fifo),
			    FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST |
			    (tp->t_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8));
		/* flush any pending I/O */
		while (ISSET(inb(pio(iobase , com_lsr)), LSR_RXRDY))
			(void) inb(pio(iobase , com_data));
		/* you turn me on, baby */
		sc->sc_mcr = MCR_DTR | MCR_RTS;
		if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
			SET(sc->sc_mcr, MCR_IENABLE | MCR_DRS); /*   */
		outb(pio(iobase , com_mcr), sc->sc_mcr);
		sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
		outb(pio(iobase , com_ier), sc->sc_ier);

		sc->sc_msr = inb(pio(iobase , com_msr));
		if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) ||
		    ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
			SET(tp->t_state, TS_CARR_ON);
		else
			CLR(tp->t_state, TS_CARR_ON);
	}
	splx(s);

	error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK));

	if (!error)
		error = (*tp->t_linesw->l_open)(dev, tp);

	/* XXX cleanup on error */

	return error;
}
Esempio n. 21
0
void
zstty_attach(struct device *parent, struct device *self, void *aux)
{
	struct zsc_softc *zsc = (struct zsc_softc *)parent;
	struct zstty_softc *zst = (struct zstty_softc *)self;
	struct cfdata *cf = self->dv_cfdata;
	struct zsc_attach_args *args = aux;
	struct zs_chanstate *cs;
	struct tty *tp;
	int channel, s, tty_unit;
	dev_t dev;
	const char *i, *o;
	int dtr_on;
	int resetbit;

	timeout_set(&zst->zst_diag_ch, zstty_diag, zst);

	tty_unit = zst->zst_dev.dv_unit;
	channel = args->channel;
	cs = zsc->zsc_cs[channel];
	cs->cs_private = zst;
	cs->cs_ops = &zsops_tty;

	zst->zst_cs = cs;
	zst->zst_swflags = cf->cf_flags;	/* softcar, etc. */
	zst->zst_hwflags = args->hwflags;
	dev = makedev(zs_major, tty_unit);

	if (zst->zst_swflags)
		printf(" flags 0x%x", zst->zst_swflags);

	if (ISSET(zst->zst_hwflags, ZS_HWFLAG_NO_DCD))
		SET(zst->zst_swflags, TIOCFLAG_SOFTCAR);

	/*
	 * Check whether we serve as a console device.
	 * XXX - split console input/output channels aren't
	 *	 supported yet on /dev/console
	 */
	i = o = NULL;
	if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) != 0) {
		i = " input";
		if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
			args->consdev->cn_dev = dev;
			cn_tab->cn_pollc = args->consdev->cn_pollc;
			cn_tab->cn_getc = args->consdev->cn_getc;
		}
		cn_tab->cn_dev = dev;
	}
	if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_OUTPUT) != 0) {
		o = " output";
		if ((args->hwflags & ZS_HWFLAG_USE_CONSDEV) != 0) {
			cn_tab->cn_putc = args->consdev->cn_putc;
		}
		cn_tab->cn_dev = dev;
	}
	if (i != NULL || o != NULL) {
		printf(": console%s", i ? (o ? "" : i) : o);
	}

#ifdef KGDB
	if (zs_check_kgdb(cs, dev)) {
		/*
		 * Allow kgdb to "take over" this port.  Returns true
		 * if this serial port is in-use by kgdb.
		 */
		printf(": kgdb\n");
		/*
		 * This is the kgdb port (exclusive use)
		 * so skip the normal attach code.
		 */
		return;
	}
#endif

#if defined(__sparc__) || defined(__sparc64__)
	if (strcmp(args->type, "keyboard") == 0 ||
	    strcmp(args->type, "mouse") == 0)
		printf(": %s", args->type);
#endif

	printf("\n");

	tp = ttymalloc(0);
	tp->t_dev = dev;
	tp->t_oproc = zsstart;
	tp->t_param = zsparam;
	tp->t_hwiflow = zshwiflow;

	zst->zst_tty = tp;
	zst->zst_rbuf = mallocarray(zstty_rbuf_size, 2, M_DEVBUF, M_WAITOK);
	zst->zst_ebuf = zst->zst_rbuf + (zstty_rbuf_size * 2);
	/* Disable the high water mark. */
	zst->zst_r_hiwat = 0;
	zst->zst_r_lowat = 0;
	zst->zst_rbget = zst->zst_rbput = zst->zst_rbuf;
	zst->zst_rbavail = zstty_rbuf_size;

	/* if there are no enable/disable functions, assume the device
	   is always enabled */
	if (!cs->enable)
		cs->enabled = 1;

	/*
	 * Hardware init
	 */
	dtr_on = 0;
	resetbit = 0;
	if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
		/* Call zsparam similar to open. */
		struct termios t;

		/* Wait a while for previous console output to complete */
		DELAY(10000);

		/* Setup the "new" parameters in t. */
		t.c_ispeed = 0;
		t.c_ospeed = cs->cs_defspeed;
		t.c_cflag = cs->cs_defcflag;

		s = splzs();

		/*
		 * Turn on receiver and status interrupts.
		 * We defer the actual write of the register to zsparam(),
		 * but we must make sure status interrupts are turned on by
		 * the time zsparam() reads the initial rr0 state.
		 */
		SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE);

		splx(s);

		/* Make sure zsparam will see changes. */
		tp->t_ospeed = 0;
		(void)zsparam(tp, &t);

		/* Make sure DTR is on now. */
		dtr_on = 1;
	} else if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_NORESET)) {
		/* Not the console; may need reset. */
		resetbit = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET;
	}

	s = splzs();
	if (resetbit)
		zs_write_reg(cs, 9, resetbit);
	zs_modem(zst, dtr_on);
	splx(s);
}
Esempio n. 22
0
int
iteopen(dev_t dev, int mode, int devtype, struct lwp *l)
{
	struct ite_softc *ip;
	struct tty *tp;
	int error, first, unit;

	unit = ITEUNIT(dev);
	first = 0;

	if (unit >= ite_cd.cd_ndevs)
		return ENXIO;
	ip = getitesp(dev);
	if (ip == NULL)
		return ENXIO;
	if ((ip->flags & ITE_ATTACHED) == 0)
		return ENXIO;

	if (ip->tp == NULL) {
		tp = ip->tp = ttymalloc();
		tty_attach(tp);
	} else
		tp = ip->tp;

	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
		return (EBUSY);
		
	if ((ip->flags & ITE_ACTIVE) == 0) {
		ite_on(dev, 0);
		first = 1;
	}
	tp->t_oproc = itestart;
	tp->t_param = ite_param;
	tp->t_dev = dev;
	if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = TTYDEF_CFLAG;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		tp->t_state = TS_CARR_ON;
		ttsetwater(tp);
	}
	error = ttyopen(tp, 0, mode & O_NONBLOCK);
	if (error)
		goto bad;

	error = tp->t_linesw->l_open(dev, tp);
	if (error)
		goto bad;

	tp->t_winsize.ws_row = ip->rows;
	tp->t_winsize.ws_col = ip->cols;
	kbdenable();
	return (0);
bad:
	if (first)
		ite_off(dev, 0);
	return (error);
}
Esempio n. 23
0
int
imxuartopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int unit = DEVUNIT(dev);
	struct imxuart_softc *sc;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	struct tty *tp;
	int s;
	int error = 0;

	if (unit >= imxuart_cd.cd_ndevs)
		return ENXIO;
	sc = imxuart_cd.cd_devs[unit];
	if (sc == NULL)
		return ENXIO;

	s = spltty();
	if (sc->sc_tty == NULL)
		tp = sc->sc_tty = ttymalloc(0);
	else
		tp = sc->sc_tty;

	splx(s);

	tp->t_oproc = imxuart_start;
	tp->t_param = imxuart_param;
	tp->t_dev = dev;

	if (!ISSET(tp->t_state, TS_ISOPEN)) {
		SET(tp->t_state, TS_WOPEN);
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;

		if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
			tp->t_cflag = imxuartconscflag;
		else
			tp->t_cflag = TTYDEF_CFLAG;
		if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
			SET(tp->t_cflag, CLOCAL);
		if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
			SET(tp->t_cflag, CRTSCTS);
		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
			SET(tp->t_cflag, MDMBUF);
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = imxuartdefaultrate;

		s = spltty();

		sc->sc_initialize = 1;
		imxuart_param(tp, &tp->t_termios);
		ttsetwater(tp);
		sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0];
		sc->sc_ibufhigh = sc->sc_ibuf + IMXUART_IHIGHWATER;
		sc->sc_ibufend = sc->sc_ibuf + IMXUART_IBUFSIZE;

		iot = sc->sc_iot;
		ioh = sc->sc_ioh;

		sc->sc_ucr1 = bus_space_read_2(iot, ioh, IMXUART_UCR1);
		sc->sc_ucr2 = bus_space_read_2(iot, ioh, IMXUART_UCR2);
		sc->sc_ucr3 = bus_space_read_2(iot, ioh, IMXUART_UCR3);
		sc->sc_ucr4 = bus_space_read_2(iot, ioh, IMXUART_UCR4);

		/* interrupt after one char on tx/rx */
		/* reference frequency divider: 1 */
		bus_space_write_2(iot, ioh, IMXUART_UFCR,
		    1 << IMXUART_FCR_TXTL_SH |
		    5 << IMXUART_FCR_RFDIV_SH |
		    1 << IMXUART_FCR_RXTL_SH);

		bus_space_write_2(iot, ioh, IMXUART_UBIR,
		    (imxuartdefaultrate / 100) - 1);

		/* formula: clk / (rfdiv * 1600) */
		bus_space_write_2(iot, ioh, IMXUART_UBMR,
		    (imxccm_get_uartclk() * 1000) / 1600);

		SET(sc->sc_ucr1, IMXUART_CR1_EN|IMXUART_CR1_RRDYEN);
		SET(sc->sc_ucr2, IMXUART_CR2_TXEN|IMXUART_CR2_RXEN);
		bus_space_write_2(iot, ioh, IMXUART_UCR1, sc->sc_ucr1);
		bus_space_write_2(iot, ioh, IMXUART_UCR2, sc->sc_ucr2);

		/* sc->sc_mcr = MCR_DTR | MCR_RTS;  XXX */
		SET(sc->sc_ucr3, IMXUART_CR3_DSR); /* XXX */
		bus_space_write_2(iot, ioh, IMXUART_UCR3, sc->sc_ucr3);

		SET(tp->t_state, TS_CARR_ON); /* XXX */


	} else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
		return EBUSY;
	else
		s = spltty();

	if (DEVCUA(dev)) {
		if (ISSET(tp->t_state, TS_ISOPEN)) {
			splx(s);
			return EBUSY;
		}
		sc->sc_cua = 1;
	} else {
		/* tty (not cua) device; wait for carrier if necessary */
		if (ISSET(flag, O_NONBLOCK)) {
			if (sc->sc_cua) {
				/* Opening TTY non-blocking... but the CUA is busy */
				splx(s);
				return EBUSY;
			}
		} else {
			while (sc->sc_cua ||
			    (!ISSET(tp->t_cflag, CLOCAL) &&
				!ISSET(tp->t_state, TS_CARR_ON))) {
				SET(tp->t_state, TS_WOPEN);
				error = ttysleep(tp, &tp->t_rawq,
				    TTIPRI | PCATCH, ttopen, 0);
				/*
				 * If TS_WOPEN has been reset, that means the
				 * cua device has been closed.  We don't want
				 * to fail in that case,
				 * so just go around again.
				 */
				if (error && ISSET(tp->t_state, TS_WOPEN)) {
					CLR(tp->t_state, TS_WOPEN);
					if (!sc->sc_cua && !ISSET(tp->t_state,
					    TS_ISOPEN))
						imxuart_pwroff(sc);
					splx(s);
					return error;
				}
			}
		}
	}
	splx(s);
	return (*linesw[tp->t_line].l_open)(dev,tp,p);
}
Esempio n. 24
0
int
viocon_port_create(struct viocon_softc *sc, int portidx)
{
	struct virtio_softc *vsc = sc->sc_virtio;
	int rxidx, txidx, allocsize, nsegs;
	char name[6];
	struct viocon_port *vp;
	caddr_t kva;
	struct tty *tp;

	vp = malloc(sizeof(*vp), M_DEVBUF, M_WAITOK|M_CANFAIL|M_ZERO);
	if (vp == NULL)
		return ENOMEM;
	sc->sc_ports[portidx] = vp;
	vp->vp_sc = sc;
	DBGPRINT("vp: %p\n", vp);

	if (portidx == 0)
		rxidx = 0;
	else
		rxidx = 2 * (portidx + 1);
	txidx = rxidx + 1;

	snprintf(name, sizeof(name), "p%drx", portidx);
	if (virtio_alloc_vq(vsc, &vsc->sc_vqs[rxidx], rxidx, BUFSIZE, 1,
	    name) != 0) {
		printf("\nCan't alloc %s virtqueue\n", name);
		goto err;
	}
	vp->vp_rx = &vsc->sc_vqs[rxidx];
	vp->vp_rx->vq_done = viocon_rx_intr;
	vp->vp_si = softintr_establish(IPL_TTY, viocon_rx_soft, vp);
	DBGPRINT("rx: %p\n", vp->vp_rx);

	snprintf(name, sizeof(name), "p%dtx", portidx);
	if (virtio_alloc_vq(vsc, &vsc->sc_vqs[txidx], txidx, BUFSIZE, 1,
	    name) != 0) {
		printf("\nCan't alloc %s virtqueue\n", name);
		goto err;
	}
	vp->vp_tx = &vsc->sc_vqs[txidx];
	vp->vp_tx->vq_done = viocon_tx_intr;
	DBGPRINT("tx: %p\n", vp->vp_tx);

	vsc->sc_nvqs += 2;

	allocsize = (vp->vp_rx->vq_num + vp->vp_tx->vq_num) * BUFSIZE;

	if (bus_dmamap_create(vsc->sc_dmat, allocsize, 1, allocsize, 0,
	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &vp->vp_dmamap) != 0)
		goto err;
	if (bus_dmamem_alloc(vsc->sc_dmat, allocsize, 8, 0, &vp->vp_dmaseg,
	    1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0)
		goto err;
	if (bus_dmamem_map(vsc->sc_dmat, &vp->vp_dmaseg, nsegs,
	    allocsize, &kva, BUS_DMA_NOWAIT) != 0)
		goto err;
	if (bus_dmamap_load(vsc->sc_dmat, vp->vp_dmamap, kva,
	    allocsize, NULL, BUS_DMA_NOWAIT) != 0)
		goto err;
	vp->vp_rx_buf = (unsigned char *)kva;
	/*
	 * XXX use only a small circular tx buffer instead of many BUFSIZE buffers?
	 */
	vp->vp_tx_buf = vp->vp_rx_buf + vp->vp_rx->vq_num * BUFSIZE;

	if (vsc->sc_features & VIRTIO_CONSOLE_F_SIZE) {
		vp->vp_cols = virtio_read_device_config_2(vsc,
		    VIRTIO_CONSOLE_COLS);
		vp->vp_rows = virtio_read_device_config_2(vsc,
		    VIRTIO_CONSOLE_ROWS);
	}

	tp = ttymalloc(1000000);
	tp->t_oproc = vioconstart;
	tp->t_param = vioconparam;
	tp->t_hwiflow = vioconhwiflow;
	tp->t_dev = (sc->sc_dev.dv_unit << 4) | portidx;
	vp->vp_tty = tp;
	DBGPRINT("tty: %p\n", tp);

	virtio_start_vq_intr(vsc, vp->vp_rx);
	virtio_start_vq_intr(vsc, vp->vp_tx);

	return 0;
err:
	panic("%s failed", __func__);
	return -1;
}
Esempio n. 25
0
void
sabtty_attach(struct device *parent, struct device *self, void *aux)
{
	struct sabtty_softc *sc = (struct sabtty_softc *)self;
	struct sabtty_attach_args *sa = aux;
	int r;
	int maj;
	int is_kgdb = 0;

#ifdef KGDB
	is_kgdb = sab_kgdb_check(sc);
#endif

	if (!is_kgdb) {
		sc->sc_tty = ttymalloc();
		if (sc->sc_tty == NULL) {
			aprint_normal(": failed to allocate tty\n");
			return;
		}
		tty_attach(sc->sc_tty);
		sc->sc_tty->t_oproc = sabtty_start;
		sc->sc_tty->t_param = sabtty_param;
	}

	sc->sc_parent = (struct sab_softc *)parent;
	sc->sc_bt = sc->sc_parent->sc_bt;
	sc->sc_portno = sa->sbt_portno;
	sc->sc_rend = sc->sc_rbuf + SABTTY_RBUF_SIZE;

	switch (sa->sbt_portno) {
	case 0:	/* port A */
		sc->sc_pvr_dtr = SAB_PVR_DTR_A;
		sc->sc_pvr_dsr = SAB_PVR_DSR_A;
		r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
		    SAB_CHAN_A, SAB_CHANLEN, &sc->sc_bh);
		break;
	case 1:	/* port B */
		sc->sc_pvr_dtr = SAB_PVR_DTR_B;
		sc->sc_pvr_dsr = SAB_PVR_DSR_B;
		r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
		    SAB_CHAN_B, SAB_CHANLEN, &sc->sc_bh);
		break;
	default:
		aprint_normal(": invalid channel: %u\n", sa->sbt_portno);
		return;
	}
	if (r != 0) {
		aprint_normal(": failed to allocate register subregion\n");
		return;
	}

	sabtty_console_flags(sc);

	if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
		struct termios t;
		const char *acc;

		/* Let residual prom output drain */
		DELAY(100000);

		switch (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
		case SABTTYF_CONS_IN:
			acc = "input";
			break;
		case SABTTYF_CONS_OUT:
			acc = "output";
			break;
		case SABTTYF_CONS_IN|SABTTYF_CONS_OUT:
		default:
			acc = "i/o";
			break;
		}

		t.c_ispeed= 0;
		t.c_ospeed = 9600;
		t.c_cflag = CREAD | CS8 | HUPCL;
		sc->sc_tty->t_ospeed = 0;
		sabttyparam(sc, sc->sc_tty, &t);

		if (sc->sc_flags & SABTTYF_CONS_IN) {
			sabtty_cons_input = sc;
			cn_tab->cn_pollc = sab_cnpollc;
			cn_tab->cn_getc = sab_cngetc;
			maj = cdevsw_lookup_major(&sabtty_cdevsw);
			cn_tab->cn_dev = makedev(maj, device_unit(self));
			shutdownhook_establish(sabtty_shutdown, sc);
			cn_init_magic(&sabtty_cnm_state);
			cn_set_magic("\047\001"); /* default magic is BREAK */
		}

		if (sc->sc_flags & SABTTYF_CONS_OUT) {
			sabtty_tec_wait(sc);
			sabtty_cons_output = sc;
			cn_tab->cn_putc = sab_cnputc;
			maj = cdevsw_lookup_major(&sabtty_cdevsw);
			cn_tab->cn_dev = makedev(maj, device_unit(self));
		}
		aprint_normal(": console %s", acc);
	} else {
		/* Not a console... */
		sabtty_reset(sc);

#ifdef KGDB
		if (is_kgdb) {
			sab_kgdb_init(sc);
			aprint_normal(": kgdb");
		}
#endif
	}

	aprint_normal("\n");
}
Esempio n. 26
0
void
sbscn_attach_channel(struct sbscn_softc *sc, int chan, int intr)
{
	struct sbscn_channel *ch = &sc->sc_channels[chan];
	u_long chan_addr;
	struct tty *tp;

	ch->ch_sc = sc;
	ch->ch_num = chan;

	chan_addr = sc->sc_addr + (0x100 * chan);
	ch->ch_base = (void *)MIPS_PHYS_TO_KSEG1(chan_addr);
	ch->ch_isr_base =
	    (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x220 + (0x20 * chan));
	ch->ch_imr_base =
	    (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x230 + (0x20 * chan));
#ifdef XXXCGDnotyet
	ch->ch_inchg_base =
	    (void *)MIPS_PHYS_TO_KSEG1(sc->sc_addr + 0x2d0 + (0x10 * chan));
#endif

	ch->ch_i_dcd = ch->ch_i_dcd_pin = 0 /* XXXCGD */;
	ch->ch_i_cts = ch->ch_i_cts_pin = 0 /* XXXCGD */;
	ch->ch_i_dsr = ch->ch_i_dsr_pin = 0 /* XXXCGD */;
	ch->ch_i_ri = ch->ch_i_ri_pin = 0 /* XXXCGD */;
	ch->ch_i_mask =
	    ch->ch_i_dcd | ch->ch_i_cts | ch->ch_i_dsr | ch->ch_i_ri;
	ch->ch_o_dtr = ch->ch_o_dtr_pin = 0 /* XXXCGD */;
	ch->ch_o_rts = ch->ch_o_rts_pin = 0 /* XXXCGD */;
	ch->ch_o_mask = ch->ch_o_dtr | ch->ch_o_rts;

	ch->ch_intrhand = cpu_intr_establish(intr, IPL_SERIAL, sbscn_intr, ch);
	callout_init(&ch->ch_diag_callout, 0);

	/* Disable interrupts before configuring the device. */
	ch->ch_imr = 0;
	WRITE_REG(ch->ch_imr_base, ch->ch_imr);

	if (sbscn_cons_present &&
	    sbscn_cons_addr == chan_addr && sbscn_cons_chan == chan) {
		sbscn_cons_attached = 1;

		/* Make sure the console is always "hardwired". */
		delay(1000);			/* wait for output to finish */
		SET(ch->ch_hwflags, SBSCN_HW_CONSOLE);
		SET(ch->ch_swflags, TIOCFLAG_SOFTCAR);
	}

	tp = ttymalloc();
	tp->t_oproc = sbscn_start;
	tp->t_param = sbscn_param;
	tp->t_hwiflow = sbscn_hwiflow;

	ch->ch_tty = tp;
	ch->ch_rbuf = malloc(sbscn_rbuf_size << 1, M_DEVBUF, M_NOWAIT);
	if (ch->ch_rbuf == NULL) {
		printf("%s: channel %d: unable to allocate ring buffer\n",
		    sc->sc_dev.dv_xname, chan);
		return;
	}
	ch->ch_ebuf = ch->ch_rbuf + (sbscn_rbuf_size << 1);

	tty_attach(tp);

	if (ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE)) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&sbscn_cdevsw);

		cn_tab->cn_dev = makedev(maj,
		    (device_unit(&sc->sc_dev) << 1) + chan);

		printf("%s: channel %d: console\n", sc->sc_dev.dv_xname, chan);
	}

#ifdef KGDB
	/*
	 * Allow kgdb to "take over" this port.  If this is
	 * the kgdb device, it has exclusive use.
	 */
	if (sbscn_kgdb_present &&
	    sbscn_kgdb_addr == chan_addr && sbscn_kgdb_chan == chan) {
		sbscn_kgdb_attached = 1;

		SET(sc->sc_hwflags, SBSCN_HW_KGDB);
		printf("%s: channel %d: kgdb\n", sc->sc_dev.dv_xname, chan);
	}
#endif

	ch->ch_si = softint_establish(SOFTINT_SERIAL, sbscn_soft, ch);

#if NRND > 0 && defined(RND_SBSCN)
	rnd_attach_source(&ch->ch_rnd_source, sc->sc_dev.dv_xname,
			  RND_TYPE_TTY, 0);
#endif

	sbscn_config(ch);

	SET(ch->ch_hwflags, SBSCN_HW_DEV_OK);
}