1*f9228f42Sdholland /* $NetBSD: dl.c,v 1.49 2014/07/25 08:10:38 dholland Exp $ */
215064528Sragge
315064528Sragge /*-
415064528Sragge * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
515064528Sragge * All rights reserved.
615064528Sragge *
715064528Sragge * This code is derived from software contributed to The NetBSD Foundation
815064528Sragge * by Jason R. Thorpe.
915064528Sragge *
1015064528Sragge * Redistribution and use in source and binary forms, with or without
1115064528Sragge * modification, are permitted provided that the following conditions
1215064528Sragge * are met:
1315064528Sragge * 1. Redistributions of source code must retain the above copyright
1415064528Sragge * notice, this list of conditions and the following disclaimer.
1515064528Sragge * 2. Redistributions in binary form must reproduce the above copyright
1615064528Sragge * notice, this list of conditions and the following disclaimer in the
1715064528Sragge * documentation and/or other materials provided with the distribution.
1815064528Sragge *
1915064528Sragge * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2015064528Sragge * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2115064528Sragge * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2215064528Sragge * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2315064528Sragge * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2415064528Sragge * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2515064528Sragge * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2615064528Sragge * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2715064528Sragge * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2815064528Sragge * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2915064528Sragge * POSSIBILITY OF SUCH DAMAGE.
3015064528Sragge */
3115064528Sragge
3215064528Sragge /*
330fada96fSbjh21 * Copyright (c) 1997 Ben Harris. All rights reserved.
3415064528Sragge * Copyright (c) 1982, 1986, 1990, 1992, 1993
3515064528Sragge * The Regents of the University of California. All rights reserved.
3615064528Sragge *
3715064528Sragge * This code is derived from software contributed to Berkeley by
3815064528Sragge * Ralph Campbell and Rick Macklem.
3915064528Sragge *
4015064528Sragge * Redistribution and use in source and binary forms, with or without
4115064528Sragge * modification, are permitted provided that the following conditions
4215064528Sragge * are met:
4315064528Sragge * 1. Redistributions of source code must retain the above copyright
4415064528Sragge * notice, this list of conditions and the following disclaimer.
4515064528Sragge * 2. Redistributions in binary form must reproduce the above copyright
4615064528Sragge * notice, this list of conditions and the following disclaimer in the
4715064528Sragge * documentation and/or other materials provided with the distribution.
48aad01611Sagc * 3. Neither the name of the University nor the names of its contributors
49aad01611Sagc * may be used to endorse or promote products derived from this software
50aad01611Sagc * without specific prior written permission.
51aad01611Sagc *
52aad01611Sagc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53aad01611Sagc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54aad01611Sagc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55aad01611Sagc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56aad01611Sagc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57aad01611Sagc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58aad01611Sagc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59aad01611Sagc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60aad01611Sagc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61aad01611Sagc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62aad01611Sagc * SUCH DAMAGE.
63aad01611Sagc */
64aad01611Sagc
65aad01611Sagc /*
66aad01611Sagc * Copyright (c) 1996 Ken C. Wellsch. All rights reserved.
67aad01611Sagc *
68aad01611Sagc * This code is derived from software contributed to Berkeley by
69aad01611Sagc * Ralph Campbell and Rick Macklem.
70aad01611Sagc *
71aad01611Sagc * Redistribution and use in source and binary forms, with or without
72aad01611Sagc * modification, are permitted provided that the following conditions
73aad01611Sagc * are met:
74aad01611Sagc * 1. Redistributions of source code must retain the above copyright
75aad01611Sagc * notice, this list of conditions and the following disclaimer.
76aad01611Sagc * 2. Redistributions in binary form must reproduce the above copyright
77aad01611Sagc * notice, this list of conditions and the following disclaimer in the
78aad01611Sagc * documentation and/or other materials provided with the distribution.
7915064528Sragge * 3. All advertising materials mentioning features or use of this software
8015064528Sragge * must display the following acknowledgement:
8115064528Sragge * This product includes software developed by the University of
8215064528Sragge * California, Berkeley and its contributors.
8315064528Sragge * 4. Neither the name of the University nor the names of its contributors
8415064528Sragge * may be used to endorse or promote products derived from this software
8515064528Sragge * without specific prior written permission.
8615064528Sragge *
8715064528Sragge * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
8815064528Sragge * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8915064528Sragge * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9015064528Sragge * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
9115064528Sragge * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
9215064528Sragge * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
9315064528Sragge * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9415064528Sragge * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
9515064528Sragge * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
9615064528Sragge * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
9715064528Sragge * SUCH DAMAGE.
9815064528Sragge */
9915064528Sragge
10015064528Sragge /*
10115064528Sragge * dl.c -- Device driver for the DL11 and DLV11 serial cards.
10215064528Sragge *
10315064528Sragge * OS-interface code derived from the dz and dca (hp300) drivers.
10415064528Sragge */
10515064528Sragge
106a3746e00Slukem #include <sys/cdefs.h>
107*f9228f42Sdholland __KERNEL_RCSID(0, "$NetBSD: dl.c,v 1.49 2014/07/25 08:10:38 dholland Exp $");
108a3746e00Slukem
10915064528Sragge #include <sys/param.h>
11015064528Sragge #include <sys/systm.h>
11115064528Sragge #include <sys/ioctl.h>
11215064528Sragge #include <sys/tty.h>
11315064528Sragge #include <sys/proc.h>
11415064528Sragge #include <sys/buf.h>
11515064528Sragge #include <sys/conf.h>
11615064528Sragge #include <sys/file.h>
11715064528Sragge #include <sys/uio.h>
11815064528Sragge #include <sys/kernel.h>
11915064528Sragge #include <sys/syslog.h>
12015064528Sragge #include <sys/device.h>
12166d08528Syamt #include <sys/kauth.h>
12215064528Sragge
123a2a38285Sad #include <sys/bus.h>
12415064528Sragge
125a2692d78Sragge #include <dev/qbus/ubavar.h>
12615064528Sragge
127a2692d78Sragge #include <dev/qbus/dlreg.h>
12815064528Sragge
12915064528Sragge #include "ioconf.h"
13015064528Sragge
13115064528Sragge struct dl_softc {
132cbab9cadSchs device_t sc_dev;
1330bd304e5Smatt struct evcnt sc_rintrcnt;
1340bd304e5Smatt struct evcnt sc_tintrcnt;
13515064528Sragge bus_space_tag_t sc_iot;
13615064528Sragge bus_space_handle_t sc_ioh;
13715064528Sragge struct tty *sc_tty;
13815064528Sragge };
13915064528Sragge
1407cf29912Scegger static int dl_match (device_t, cfdata_t, void *);
1417cf29912Scegger static void dl_attach (device_t, device_t, void *);
1420bd304e5Smatt static void dlrint (void *);
1430bd304e5Smatt static void dlxint (void *);
1440bd304e5Smatt static void dlstart (struct tty *);
1450bd304e5Smatt static int dlparam (struct tty *, struct termios *);
1460bd304e5Smatt static void dlbrk (struct dl_softc *, int);
14715064528Sragge
148cbab9cadSchs CFATTACH_DECL_NEW(dl, sizeof(struct dl_softc),
149b75a007dSthorpej dl_match, dl_attach, NULL, NULL);
15015064528Sragge
15177a6b82bSgehenna dev_type_open(dlopen);
15277a6b82bSgehenna dev_type_close(dlclose);
15377a6b82bSgehenna dev_type_read(dlread);
15477a6b82bSgehenna dev_type_write(dlwrite);
15577a6b82bSgehenna dev_type_ioctl(dlioctl);
15677a6b82bSgehenna dev_type_stop(dlstop);
15777a6b82bSgehenna dev_type_tty(dltty);
15877a6b82bSgehenna dev_type_poll(dlpoll);
15977a6b82bSgehenna
16077a6b82bSgehenna const struct cdevsw dl_cdevsw = {
161a68f9396Sdholland .d_open = dlopen,
162a68f9396Sdholland .d_close = dlclose,
163a68f9396Sdholland .d_read = dlread,
164a68f9396Sdholland .d_write = dlwrite,
165a68f9396Sdholland .d_ioctl = dlioctl,
166a68f9396Sdholland .d_stop = dlstop,
167a68f9396Sdholland .d_tty = dltty,
168a68f9396Sdholland .d_poll = dlpoll,
169a68f9396Sdholland .d_mmap = nommap,
170a68f9396Sdholland .d_kqfilter = ttykqfilter,
171*f9228f42Sdholland .d_discard = nodiscard,
172a68f9396Sdholland .d_flag = D_TTY
17377a6b82bSgehenna };
17477a6b82bSgehenna
17515064528Sragge #define DL_READ_WORD(reg) \
17615064528Sragge bus_space_read_2(sc->sc_iot, sc->sc_ioh, reg)
17715064528Sragge #define DL_WRITE_WORD(reg, val) \
17815064528Sragge bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg, val)
17915064528Sragge #define DL_WRITE_BYTE(reg, val) \
18015064528Sragge bus_space_write_1(sc->sc_iot, sc->sc_ioh, reg, val)
18115064528Sragge
18215064528Sragge /* Autoconfig handles: setup the controller to interrupt, */
18315064528Sragge /* then complete the housecleaning for full operation */
18415064528Sragge
18515064528Sragge static int
dl_match(device_t parent,cfdata_t cf,void * aux)1867cf29912Scegger dl_match (device_t parent, cfdata_t cf, void *aux)
18715064528Sragge {
18815064528Sragge struct uba_attach_args *ua = aux;
18915064528Sragge
19015064528Sragge #ifdef DL_DEBUG
19115064528Sragge printf("Probing for dl at %lo ... ", (long)ua->ua_iaddr);
19215064528Sragge #endif
19315064528Sragge
19415064528Sragge bus_space_write_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR, DL_XCSR_TXIE);
19515064528Sragge if (bus_space_read_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR) !=
19615064528Sragge (DL_XCSR_TXIE | DL_XCSR_TX_READY)) {
19715064528Sragge #ifdef DL_DEBUG
19815064528Sragge printf("failed (step 1; XCSR = %.4b)\n",
19915064528Sragge bus_space_read_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR),
20015064528Sragge DL_XCSR_BITS);
20115064528Sragge #endif
20215064528Sragge return 0;
20315064528Sragge }
20415064528Sragge
20515064528Sragge /*
20615064528Sragge * We have to force an interrupt so the uba driver can work
20715064528Sragge * out where we are. Unfortunately, the only way to make a
20815064528Sragge * DL11 interrupt is to get it to send or receive a
20915064528Sragge * character. We'll send a NUL and hope it doesn't hurt
21015064528Sragge * anything.
21115064528Sragge */
21215064528Sragge
21315064528Sragge bus_space_write_1(ua->ua_iot, ua->ua_ioh, DL_UBA_XBUFL, '\0');
21415064528Sragge #if 0 /* This test seems to fail 2/3 of the time :-( */
21515064528Sragge if (dladdr->dl_xcsr != (DL_XCSR_TXIE)) {
21615064528Sragge #ifdef DL_DEBUG
21715064528Sragge printf("failed (step 2; XCSR = %.4b)\n", dladdr->dl_xcsr,
21815064528Sragge DL_XCSR_BITS);
21915064528Sragge #endif
22015064528Sragge return 0;
22115064528Sragge }
22215064528Sragge #endif
22315064528Sragge DELAY(100000); /* delay 1/10 s for character to transmit */
22415064528Sragge if (bus_space_read_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR) !=
22515064528Sragge (DL_XCSR_TXIE | DL_XCSR_TX_READY)) {
22615064528Sragge #ifdef DL_DEBUG
22715064528Sragge printf("failed (step 3; XCSR = %.4b)\n",
22815064528Sragge bus_space_read_2(ua->ua_iot, ua->ua_ioh, DL_UBA_XCSR),
22915064528Sragge DL_XCSR_BITS);
23015064528Sragge #endif
23115064528Sragge return 0;
23215064528Sragge }
23315064528Sragge
23415064528Sragge
23515064528Sragge /* What else do I need to do? */
23615064528Sragge
23715064528Sragge return 1;
23815064528Sragge
23915064528Sragge }
24015064528Sragge
24115064528Sragge static void
dl_attach(device_t parent,device_t self,void * aux)2427cf29912Scegger dl_attach (device_t parent, device_t self, void *aux)
24315064528Sragge {
244ceb94256Sthorpej struct dl_softc *sc = device_private(self);
245169ac5b3Saugustss struct uba_attach_args *ua = aux;
24615064528Sragge
247cbab9cadSchs sc->sc_dev = self;
24815064528Sragge sc->sc_iot = ua->ua_iot;
24915064528Sragge sc->sc_ioh = ua->ua_ioh;
25015064528Sragge
25115064528Sragge /* Tidy up the device */
25215064528Sragge
25315064528Sragge DL_WRITE_WORD(DL_UBA_RCSR, DL_RCSR_RXIE);
25415064528Sragge DL_WRITE_WORD(DL_UBA_XCSR, DL_XCSR_TXIE);
25515064528Sragge
25615064528Sragge /* Initialize our softc structure. Should be done in open? */
25715064528Sragge
2582626d576Srmind sc->sc_tty = tty_alloc();
25915064528Sragge tty_attach(sc->sc_tty);
26015064528Sragge
2617b17d595Smatt /* Now register the TX & RX interrupt handlers */
2620bd304e5Smatt uba_intr_establish(ua->ua_icookie, ua->ua_cvec,
2630bd304e5Smatt dlxint, sc, &sc->sc_tintrcnt);
2640bd304e5Smatt uba_intr_establish(ua->ua_icookie, ua->ua_cvec - 4,
2650bd304e5Smatt dlrint, sc, &sc->sc_rintrcnt);
2662f85fe7aSmatt evcnt_attach_dynamic(&sc->sc_rintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
267cbab9cadSchs device_xname(sc->sc_dev), "rintr");
2682f85fe7aSmatt evcnt_attach_dynamic(&sc->sc_tintrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
269cbab9cadSchs device_xname(sc->sc_dev), "tintr");
27015064528Sragge
27115064528Sragge printf("\n");
27215064528Sragge }
27315064528Sragge
27415064528Sragge /* Receiver Interrupt Handler */
27515064528Sragge
27615064528Sragge static void
dlrint(void * arg)2772f85fe7aSmatt dlrint(void *arg)
27815064528Sragge {
2797b17d595Smatt struct dl_softc *sc = arg;
28015064528Sragge
28115064528Sragge if (DL_READ_WORD(DL_UBA_RCSR) & DL_RCSR_RX_DONE) {
2822f85fe7aSmatt struct tty *tp = sc->sc_tty;
2832f85fe7aSmatt unsigned c;
2842f85fe7aSmatt int cc;
2852f85fe7aSmatt
28615064528Sragge c = DL_READ_WORD(DL_UBA_RBUF);
28715064528Sragge cc = c & 0xFF;
28815064528Sragge
28915064528Sragge if (!(tp->t_state & TS_ISOPEN)) {
290b18c28f5Sad cv_broadcast(&tp->t_rawcv);
29115064528Sragge return;
29215064528Sragge }
29315064528Sragge
2942f85fe7aSmatt if (c & DL_RBUF_OVERRUN_ERR) {
29515064528Sragge /*
29615064528Sragge * XXX: This should really be logged somwhere
29715064528Sragge * else where we can afford the time.
29815064528Sragge */
29915064528Sragge log(LOG_WARNING, "%s: rx overrun\n",
300cbab9cadSchs device_xname(sc->sc_dev));
3012f85fe7aSmatt }
30215064528Sragge if (c & DL_RBUF_FRAMING_ERR)
30315064528Sragge cc |= TTY_FE;
30415064528Sragge if (c & DL_RBUF_PARITY_ERR)
30515064528Sragge cc |= TTY_PE;
30615064528Sragge
307507aaec0Seeh (*tp->t_linesw->l_rint)(cc, tp);
3082f85fe7aSmatt #if defined(DIAGNOSTIC)
3092f85fe7aSmatt } else {
31015064528Sragge log(LOG_WARNING, "%s: stray rx interrupt\n",
311cbab9cadSchs device_xname(sc->sc_dev));
3122f85fe7aSmatt #endif
3132f85fe7aSmatt }
31415064528Sragge }
31515064528Sragge
31615064528Sragge /* Transmitter Interrupt Handler */
31715064528Sragge
31815064528Sragge static void
dlxint(void * arg)3192f85fe7aSmatt dlxint(void *arg)
32015064528Sragge {
3217b17d595Smatt struct dl_softc *sc = arg;
3222f85fe7aSmatt struct tty *tp = sc->sc_tty;
32315064528Sragge
32415064528Sragge tp->t_state &= ~(TS_BUSY | TS_FLUSH);
325507aaec0Seeh (*tp->t_linesw->l_start)(tp);
32615064528Sragge
32715064528Sragge return;
32815064528Sragge }
32915064528Sragge
33015064528Sragge int
dlopen(dev_t dev,int flag,int mode,struct lwp * l)33195e1ffb1Schristos dlopen(dev_t dev, int flag, int mode, struct lwp *l)
33215064528Sragge {
333169ac5b3Saugustss struct tty *tp;
33415064528Sragge struct dl_softc *sc;
3352f85fe7aSmatt int unit;
33615064528Sragge
33715064528Sragge unit = minor(dev);
33815064528Sragge
339a39050ebSdrochner sc = device_lookup_private(&dl_cd, unit);
340a39050ebSdrochner if (!sc)
34115064528Sragge return ENXIO;
34215064528Sragge
34315064528Sragge tp = sc->sc_tty;
34415064528Sragge if (tp == NULL)
34515064528Sragge return ENODEV;
34615064528Sragge tp->t_oproc = dlstart;
34715064528Sragge tp->t_param = dlparam;
34815064528Sragge tp->t_dev = dev;
34915064528Sragge
350bdc51baeSelad if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
351bdc51baeSelad return (EBUSY);
352bdc51baeSelad
35315064528Sragge if (!(tp->t_state & TS_ISOPEN)) {
35415064528Sragge ttychars(tp);
35515064528Sragge tp->t_iflag = TTYDEF_IFLAG;
35615064528Sragge tp->t_oflag = TTYDEF_OFLAG;
35715064528Sragge /* No modem control, so set CLOCAL. */
35815064528Sragge tp->t_cflag = TTYDEF_CFLAG | CLOCAL;
35915064528Sragge tp->t_lflag = TTYDEF_LFLAG;
36015064528Sragge tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
36115064528Sragge
36215064528Sragge dlparam(tp, &tp->t_termios);
36315064528Sragge ttsetwater(tp);
36415064528Sragge
365bdc51baeSelad }
36615064528Sragge
367507aaec0Seeh return ((*tp->t_linesw->l_open)(dev, tp));
36815064528Sragge }
36915064528Sragge
37015064528Sragge /*ARGSUSED*/
37115064528Sragge int
dlclose(dev_t dev,int flag,int mode,struct lwp * l)37295e1ffb1Schristos dlclose(dev_t dev, int flag, int mode, struct lwp *l)
37315064528Sragge {
374a39050ebSdrochner struct dl_softc *sc = device_lookup_private(&dl_cd, minor(dev));
3752f85fe7aSmatt struct tty *tp = sc->sc_tty;
37615064528Sragge
377507aaec0Seeh (*tp->t_linesw->l_close)(tp, flag);
37815064528Sragge
37915064528Sragge /* Make sure a BREAK state is not left enabled. */
38015064528Sragge dlbrk(sc, 0);
38115064528Sragge
38215064528Sragge return (ttyclose(tp));
38315064528Sragge }
38415064528Sragge
38515064528Sragge int
dlread(dev_t dev,struct uio * uio,int flag)3862f85fe7aSmatt dlread(dev_t dev, struct uio *uio, int flag)
38715064528Sragge {
388a39050ebSdrochner struct dl_softc *sc = device_lookup_private(&dl_cd, minor(dev));
3892f85fe7aSmatt struct tty *tp = sc->sc_tty;
39015064528Sragge
391507aaec0Seeh return ((*tp->t_linesw->l_read)(tp, uio, flag));
39215064528Sragge }
39315064528Sragge
39415064528Sragge int
dlwrite(dev_t dev,struct uio * uio,int flag)3952f85fe7aSmatt dlwrite(dev_t dev, struct uio *uio, int flag)
39615064528Sragge {
397a39050ebSdrochner struct dl_softc *sc = device_lookup_private(&dl_cd, minor(dev));
3982f85fe7aSmatt struct tty *tp = sc->sc_tty;
39915064528Sragge
400507aaec0Seeh return ((*tp->t_linesw->l_write)(tp, uio, flag));
40115064528Sragge }
40215064528Sragge
40315064528Sragge int
dlpoll(dev_t dev,int events,struct lwp * l)40495e1ffb1Schristos dlpoll(dev_t dev, int events, struct lwp *l)
4052963ff5cSscw {
406a39050ebSdrochner struct dl_softc *sc = device_lookup_private(&dl_cd, minor(dev));
4072963ff5cSscw struct tty *tp = sc->sc_tty;
4082963ff5cSscw
40995e1ffb1Schristos return ((*tp->t_linesw->l_poll)(tp, events, l));
4102963ff5cSscw }
4112963ff5cSscw
4122963ff5cSscw int
dlioctl(dev_t dev,unsigned long cmd,void * data,int flag,struct lwp * l)41353524e44Schristos dlioctl(dev_t dev, unsigned long cmd, void *data, int flag, struct lwp *l)
41415064528Sragge {
415a39050ebSdrochner struct dl_softc *sc = device_lookup_private(&dl_cd, minor(dev));
4162f85fe7aSmatt struct tty *tp = sc->sc_tty;
41715064528Sragge int error;
41815064528Sragge
41915064528Sragge
42095e1ffb1Schristos error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
42131144d99Satatat if (error != EPASSTHROUGH)
42215064528Sragge return (error);
42331144d99Satatat
42495e1ffb1Schristos error = ttioctl(tp, cmd, data, flag, l);
42531144d99Satatat if (error != EPASSTHROUGH)
42615064528Sragge return (error);
42715064528Sragge
42815064528Sragge switch (cmd) {
42915064528Sragge
43015064528Sragge case TIOCSBRK:
43115064528Sragge dlbrk(sc, 1);
43215064528Sragge break;
43315064528Sragge
43415064528Sragge case TIOCCBRK:
43515064528Sragge dlbrk(sc, 0);
43615064528Sragge break;
43715064528Sragge
43815064528Sragge case TIOCMGET:
43915064528Sragge /* No modem control, assume they're all low. */
44015064528Sragge *(int *)data = 0;
44115064528Sragge break;
44215064528Sragge
44315064528Sragge default:
44431144d99Satatat return (EPASSTHROUGH);
44515064528Sragge }
44615064528Sragge return (0);
44715064528Sragge }
44815064528Sragge
44915064528Sragge struct tty *
dltty(dev_t dev)4502f85fe7aSmatt dltty(dev_t dev)
45115064528Sragge {
452a39050ebSdrochner struct dl_softc *sc = device_lookup_private(&dl_cd, minor(dev));
45315064528Sragge
45415064528Sragge return sc->sc_tty;
45515064528Sragge }
45615064528Sragge
45715064528Sragge void
dlstop(struct tty * tp,int flag)4582f85fe7aSmatt dlstop(struct tty *tp, int flag)
45915064528Sragge {
4602f85fe7aSmatt int s = spltty();
46115064528Sragge
4622f85fe7aSmatt if ((tp->t_state & (TS_BUSY|TS_TTSTOP)) == TS_BUSY)
46315064528Sragge tp->t_state |= TS_FLUSH;
46415064528Sragge splx(s);
46515064528Sragge }
46615064528Sragge
46715064528Sragge static void
dlstart(struct tty * tp)4682f85fe7aSmatt dlstart(struct tty *tp)
46915064528Sragge {
470a39050ebSdrochner struct dl_softc *sc = device_lookup_private(&dl_cd, minor(tp->t_dev));
4712f85fe7aSmatt int s = spltty();
47215064528Sragge
47315064528Sragge if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
47415064528Sragge goto out;
475dc26833bSad if (!ttypull(tp))
47615064528Sragge goto out;
47715064528Sragge if (DL_READ_WORD(DL_UBA_XCSR) & DL_XCSR_TX_READY) {
47815064528Sragge tp->t_state |= TS_BUSY;
47915064528Sragge DL_WRITE_BYTE(DL_UBA_XBUFL, getc(&tp->t_outq));
48015064528Sragge }
48115064528Sragge out:
48215064528Sragge splx(s);
48315064528Sragge return;
48415064528Sragge }
48515064528Sragge
48615064528Sragge /*ARGSUSED*/
48715064528Sragge static int
dlparam(struct tty * tp,struct termios * t)4882f85fe7aSmatt dlparam(struct tty *tp, struct termios *t)
48915064528Sragge {
49015064528Sragge /*
49115064528Sragge * All this kind of stuff (speed, character format, whatever)
49215064528Sragge * is set by jumpers on the card. Changing it is thus rather
49315064528Sragge * tricky for a mere device driver.
49415064528Sragge */
49515064528Sragge return 0;
49615064528Sragge }
49715064528Sragge
49815064528Sragge static void
dlbrk(struct dl_softc * sc,int state)4992f85fe7aSmatt dlbrk(struct dl_softc *sc, int state)
50015064528Sragge {
50115064528Sragge int s = spltty();
50215064528Sragge
50315064528Sragge if (state) {
50415064528Sragge DL_WRITE_WORD(DL_UBA_XCSR, DL_READ_WORD(DL_UBA_XCSR) |
50515064528Sragge DL_XCSR_TX_BREAK);
50615064528Sragge } else {
50715064528Sragge DL_WRITE_WORD(DL_UBA_XCSR, DL_READ_WORD(DL_UBA_XCSR) &
50815064528Sragge ~DL_XCSR_TX_BREAK);
50915064528Sragge }
51015064528Sragge splx(s);
51115064528Sragge }
512