1*c7fb772bSthorpej /* $NetBSD: dt.c,v 1.16 2021/08/07 16:19:02 thorpej Exp $ */
29aa9b8ebSad
39aa9b8ebSad /*-
49aa9b8ebSad * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
59aa9b8ebSad * All rights reserved.
69aa9b8ebSad *
79aa9b8ebSad * This code is derived from software contributed to The NetBSD Foundation
89aa9b8ebSad * by Andrew Doran.
99aa9b8ebSad *
109aa9b8ebSad * Redistribution and use in source and binary forms, with or without
119aa9b8ebSad * modification, are permitted provided that the following conditions
129aa9b8ebSad * are met:
139aa9b8ebSad * 1. Redistributions of source code must retain the above copyright
149aa9b8ebSad * notice, this list of conditions and the following disclaimer.
159aa9b8ebSad * 2. Redistributions in binary form must reproduce the above copyright
169aa9b8ebSad * notice, this list of conditions and the following disclaimer in the
179aa9b8ebSad * documentation and/or other materials provided with the distribution.
189aa9b8ebSad *
199aa9b8ebSad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
209aa9b8ebSad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
219aa9b8ebSad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
229aa9b8ebSad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
239aa9b8ebSad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
249aa9b8ebSad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
259aa9b8ebSad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
269aa9b8ebSad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
279aa9b8ebSad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289aa9b8ebSad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
299aa9b8ebSad * POSSIBILITY OF SUCH DAMAGE.
309aa9b8ebSad */
319aa9b8ebSad
329aa9b8ebSad /*-
339aa9b8ebSad * Copyright (c) 1992, 1993
349aa9b8ebSad * The Regents of the University of California. All rights reserved.
359aa9b8ebSad *
369aa9b8ebSad * This code is derived from software contributed to Berkeley by
379aa9b8ebSad * Ralph Campbell and Rick Macklem.
389aa9b8ebSad *
399aa9b8ebSad * Redistribution and use in source and binary forms, with or without
409aa9b8ebSad * modification, are permitted provided that the following conditions
419aa9b8ebSad * are met:
429aa9b8ebSad * 1. Redistributions of source code must retain the above copyright
439aa9b8ebSad * notice, this list of conditions and the following disclaimer.
449aa9b8ebSad * 2. Redistributions in binary form must reproduce the above copyright
459aa9b8ebSad * notice, this list of conditions and the following disclaimer in the
469aa9b8ebSad * documentation and/or other materials provided with the distribution.
479aa9b8ebSad * 3. Neither the name of the University nor the names of its contributors
489aa9b8ebSad * may be used to endorse or promote products derived from this software
499aa9b8ebSad * without specific prior written permission.
509aa9b8ebSad *
519aa9b8ebSad * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
529aa9b8ebSad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
539aa9b8ebSad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
549aa9b8ebSad * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
559aa9b8ebSad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
569aa9b8ebSad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
579aa9b8ebSad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
589aa9b8ebSad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
599aa9b8ebSad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
609aa9b8ebSad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
619aa9b8ebSad * SUCH DAMAGE.
629aa9b8ebSad *
639aa9b8ebSad * @(#)dtop.c 8.2 (Berkeley) 11/30/93
649aa9b8ebSad */
659aa9b8ebSad
669aa9b8ebSad /*
679aa9b8ebSad * Mach Operating System
689aa9b8ebSad * Copyright (c) 1991,1990,1989 Carnegie Mellon University
699aa9b8ebSad * All Rights Reserved.
709aa9b8ebSad *
719aa9b8ebSad * Permission to use, copy, modify and distribute this software and its
729aa9b8ebSad * documentation is hereby granted, provided that both the copyright
739aa9b8ebSad * notice and this permission notice appear in all copies of the
749aa9b8ebSad * software, derivative works or modified versions, and any portions
759aa9b8ebSad * thereof, and that both notices appear in supporting documentation.
769aa9b8ebSad *
779aa9b8ebSad * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
789aa9b8ebSad * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
799aa9b8ebSad * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
809aa9b8ebSad *
819aa9b8ebSad * Carnegie Mellon requests users of this software to return to
829aa9b8ebSad *
839aa9b8ebSad * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
849aa9b8ebSad * School of Computer Science
859aa9b8ebSad * Carnegie Mellon University
869aa9b8ebSad * Pittsburgh PA 15213-3890
879aa9b8ebSad *
889aa9b8ebSad * any improvements or extensions that they make and grant Carnegie the
899aa9b8ebSad * rights to redistribute these changes.
909aa9b8ebSad */
919aa9b8ebSad /*
929aa9b8ebSad * Author: Alessandro Forin, Carnegie Mellon University
939aa9b8ebSad *
949aa9b8ebSad * Hardware-level operations for the Desktop serial line
959aa9b8ebSad * bus (i2c aka ACCESS).
969aa9b8ebSad */
979aa9b8ebSad /************************************************************
989aa9b8ebSad Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
999aa9b8ebSad and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
1009aa9b8ebSad
1019aa9b8ebSad All Rights Reserved
1029aa9b8ebSad
1039aa9b8ebSad Permission to use, copy, modify, and distribute this software and its
1049aa9b8ebSad documentation for any purpose and without fee is hereby granted,
1059aa9b8ebSad provided that the above copyright notice appear in all copies and that
1069aa9b8ebSad both that copyright notice and this permission notice appear in
1079aa9b8ebSad supporting documentation, and that the names of Digital or MIT not be
1089aa9b8ebSad used in advertising or publicity pertaining to distribution of the
1099aa9b8ebSad software without specific, written prior permission.
1109aa9b8ebSad
1119aa9b8ebSad DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1129aa9b8ebSad ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1139aa9b8ebSad DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1149aa9b8ebSad ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1159aa9b8ebSad WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1169aa9b8ebSad ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
1179aa9b8ebSad SOFTWARE.
1189aa9b8ebSad
1199aa9b8ebSad ********************************************************/
1209aa9b8ebSad
121520489e1Sad /*
122520489e1Sad * ACCESS.bus device support for the Personal DECstation. This code handles
123520489e1Sad * only the keyboard and mouse, and will likely not work if other ACCESS.bus
124520489e1Sad * devices are physically attached to the system.
125520489e1Sad *
126520489e1Sad * Since we do not know how to drive the hardware (the only reference being
127520489e1Sad * Mach), we can't identify which devices are connected to the system by
128520489e1Sad * sending idenfication requests. With only a mouse and keyboard attached
129520489e1Sad * to the system, we do know which two slave addresses will be in use.
130520489e1Sad * However, we don't know which is the mouse, and which is the keyboard.
131520489e1Sad * So, we resort to inspecting device reports and making an educated guess
132520489e1Sad * as to which is which.
133520489e1Sad */
134520489e1Sad
1359aa9b8ebSad #include <sys/cdefs.h>
136*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: dt.c,v 1.16 2021/08/07 16:19:02 thorpej Exp $");
1379aa9b8ebSad
1389aa9b8ebSad #include <sys/param.h>
1399aa9b8ebSad #include <sys/systm.h>
1409aa9b8ebSad #include <sys/tty.h>
1419aa9b8ebSad #include <sys/proc.h>
1429aa9b8ebSad #include <sys/conf.h>
1439aa9b8ebSad #include <sys/file.h>
1449aa9b8ebSad #include <sys/kernel.h>
1459aa9b8ebSad #include <sys/device.h>
146d206c345Sthorpej #include <sys/kmem.h>
14746ed8f7dSad #include <sys/intr.h>
1489aa9b8ebSad
1499aa9b8ebSad #include <dev/dec/lk201.h>
1509aa9b8ebSad
1519aa9b8ebSad #include <dev/tc/tcvar.h>
1529aa9b8ebSad #include <dev/tc/ioasicreg.h>
1539aa9b8ebSad #include <dev/tc/ioasicvar.h>
1549aa9b8ebSad
1559aa9b8ebSad #include <pmax/pmax/maxine.h>
1569aa9b8ebSad
1579aa9b8ebSad #include <pmax/tc/dtreg.h>
1589aa9b8ebSad #include <pmax/tc/dtvar.h>
1599aa9b8ebSad
1609aa9b8ebSad #define DT_BUF_CNT 16
1619aa9b8ebSad #define DT_ESC_CHAR 0xf8
162520489e1Sad #define DT_XMT_OK 0xfb
1639aa9b8ebSad #define DT_MAX_POLL 0x70000 /* about half a sec */
1649aa9b8ebSad
1659aa9b8ebSad #define DT_GET_BYTE(data) (((*(data)) >> 8) & 0xff)
1669aa9b8ebSad #define DT_PUT_BYTE(data,c) { *(data) = (c) << 8; wbflush(); }
1679aa9b8ebSad
1689aa9b8ebSad #define DT_RX_AVAIL(poll) ((*(poll) & 1) != 0)
1699aa9b8ebSad #define DT_TX_AVAIL(poll) ((*(poll) & 2) != 0)
1709aa9b8ebSad
17103335d0bStsutsui int dt_match(device_t, cfdata_t, void *);
17203335d0bStsutsui void dt_attach(device_t, device_t, void *);
1739aa9b8ebSad int dt_intr(void *);
1749aa9b8ebSad int dt_print(void *, const char *);
1759aa9b8ebSad void dt_strvis(uint8_t *, char *, int);
176520489e1Sad void dt_dispatch(void *);
1779aa9b8ebSad
1789aa9b8ebSad int dt_kbd_addr = DT_ADDR_KBD;
179520489e1Sad struct dt_device dt_kbd_dv;
180520489e1Sad int dt_ms_addr = DT_ADDR_MOUSE;
181520489e1Sad struct dt_device dt_ms_dv;
1829aa9b8ebSad struct dt_state dt_state;
1839aa9b8ebSad
18403335d0bStsutsui CFATTACH_DECL_NEW(dt, sizeof(struct dt_softc),
1859aa9b8ebSad dt_match, dt_attach, NULL, NULL);
1869aa9b8ebSad
1879aa9b8ebSad int
dt_match(device_t parent,cfdata_t cf,void * aux)18803335d0bStsutsui dt_match(device_t parent, cfdata_t cf, void *aux)
1899aa9b8ebSad {
1909aa9b8ebSad struct ioasicdev_attach_args *d;
1919aa9b8ebSad
1929aa9b8ebSad d = aux;
1939aa9b8ebSad
1949aa9b8ebSad if (strcmp(d->iada_modname, "dtop") != 0)
1959aa9b8ebSad return (0);
1969aa9b8ebSad
19753524e44Schristos if (badaddr((void *)(d->iada_addr), 2))
1989aa9b8ebSad return (0);
1999aa9b8ebSad
2009aa9b8ebSad return (1);
2019aa9b8ebSad }
2029aa9b8ebSad
2039aa9b8ebSad void
dt_attach(device_t parent,device_t self,void * aux)20403335d0bStsutsui dt_attach(device_t parent, device_t self, void *aux)
2059aa9b8ebSad {
2069aa9b8ebSad struct ioasicdev_attach_args *d;
2079aa9b8ebSad struct dt_attach_args dta;
2089aa9b8ebSad struct dt_softc *sc;
2099aa9b8ebSad struct dt_msg *msg;
2109aa9b8ebSad int i;
2119aa9b8ebSad
2129aa9b8ebSad d = aux;
21303335d0bStsutsui sc = device_private(self);
21403335d0bStsutsui sc->sc_dev = self;
2159aa9b8ebSad
2169aa9b8ebSad dt_cninit();
2179aa9b8ebSad
218d206c345Sthorpej msg = kmem_alloc(sizeof(*msg) * DT_BUF_CNT, KM_SLEEP);
21946ed8f7dSad sc->sc_sih = softint_establish(SOFTINT_SERIAL, dt_dispatch, sc);
220520489e1Sad if (sc->sc_sih == NULL) {
22103335d0bStsutsui printf("%s: memory exhausted\n", device_xname(self));
222d206c345Sthorpej kmem_free(msg, sizeof(*msg) * DT_BUF_CNT);
223204cdd3fSmaxv return;
224520489e1Sad }
225520489e1Sad
226520489e1Sad SIMPLEQ_INIT(&sc->sc_queue);
2279aa9b8ebSad SLIST_INIT(&sc->sc_free);
2289aa9b8ebSad for (i = 0; i < DT_BUF_CNT; i++, msg++)
2299aa9b8ebSad SLIST_INSERT_HEAD(&sc->sc_free, msg, chain.slist);
2309aa9b8ebSad
2319aa9b8ebSad ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_TTY, dt_intr, sc);
2329aa9b8ebSad printf("\n");
2339aa9b8ebSad
234520489e1Sad dta.dta_addr = DT_ADDR_KBD;
235*c7fb772bSthorpej config_found(self, &dta, dt_print, CFARGS_NONE);
236520489e1Sad dta.dta_addr = DT_ADDR_MOUSE;
237*c7fb772bSthorpej config_found(self, &dta, dt_print, CFARGS_NONE);
2389aa9b8ebSad }
2399aa9b8ebSad
2409aa9b8ebSad void
dt_cninit(void)2419aa9b8ebSad dt_cninit(void)
2429aa9b8ebSad {
2439aa9b8ebSad
2449aa9b8ebSad dt_state.ds_poll = (volatile u_int *)
2459aa9b8ebSad MIPS_PHYS_TO_KSEG1(XINE_REG_INTR);
2469aa9b8ebSad dt_state.ds_data = (volatile u_int *)
2479aa9b8ebSad MIPS_PHYS_TO_KSEG1(XINE_PHYS_TC_3_START + 0x280000);
2489aa9b8ebSad }
2499aa9b8ebSad
2509aa9b8ebSad int
dt_print(void * aux,const char * pnp)2519aa9b8ebSad dt_print(void *aux, const char *pnp)
2529aa9b8ebSad {
2539aa9b8ebSad
2549aa9b8ebSad return (QUIET);
2559aa9b8ebSad }
2569aa9b8ebSad
2579aa9b8ebSad int
dt_establish_handler(struct dt_softc * sc,struct dt_device * dtdv,void * arg,void (* hdlr)(void *,struct dt_msg *))258520489e1Sad dt_establish_handler(struct dt_softc *sc, struct dt_device *dtdv,
25903335d0bStsutsui void *arg, void (*hdlr)(void *, struct dt_msg *))
2609aa9b8ebSad {
2619aa9b8ebSad
26203335d0bStsutsui dtdv->dtdv_arg = arg;
263520489e1Sad dtdv->dtdv_handler = hdlr;
2649aa9b8ebSad return (0);
2659aa9b8ebSad }
2669aa9b8ebSad
2679aa9b8ebSad int
dt_intr(void * cookie)2689aa9b8ebSad dt_intr(void *cookie)
2699aa9b8ebSad {
2709aa9b8ebSad struct dt_softc *sc;
2719aa9b8ebSad struct dt_msg *msg, *pend;
2729aa9b8ebSad
2739aa9b8ebSad sc = cookie;
2749aa9b8ebSad
2759aa9b8ebSad switch (dt_msg_get(&sc->sc_msg, 1)) {
2769aa9b8ebSad case DT_GET_ERROR:
2779aa9b8ebSad /*
2789aa9b8ebSad * Ugh! The most common occurrence of a data overrun is upon
2799aa9b8ebSad * a key press and the result is a software generated "stuck
2809aa9b8ebSad * key". All I can think to do is fake an "all keys up"
2819aa9b8ebSad * whenever a data overrun occurs.
2829aa9b8ebSad */
2839aa9b8ebSad sc->sc_msg.src = dt_kbd_addr;
284520489e1Sad sc->sc_msg.ctl = DT_CTL(1, 0, 0);
2859aa9b8ebSad sc->sc_msg.body[0] = DT_KBD_EMPTY;
2869aa9b8ebSad #ifdef DIAGNOSTIC
2879aa9b8ebSad printf("%s: data overrun or stray interrupt\n",
28803335d0bStsutsui device_xname(sc->sc_dev));
2899aa9b8ebSad #endif
2909aa9b8ebSad break;
2919aa9b8ebSad
2929aa9b8ebSad case DT_GET_DONE:
2939aa9b8ebSad break;
2949aa9b8ebSad
2959aa9b8ebSad case DT_GET_NOTYET:
2969aa9b8ebSad return (1);
2979aa9b8ebSad }
2989aa9b8ebSad
2999aa9b8ebSad if ((msg = SLIST_FIRST(&sc->sc_free)) == NULL) {
30003335d0bStsutsui printf("%s: input overflow\n", device_xname(sc->sc_dev));
3019aa9b8ebSad return (1);
3029aa9b8ebSad }
3039aa9b8ebSad SLIST_REMOVE_HEAD(&sc->sc_free, chain.slist);
3049aa9b8ebSad memcpy(msg, &sc->sc_msg, sizeof(*msg));
3059aa9b8ebSad
306520489e1Sad pend = SIMPLEQ_FIRST(&sc->sc_queue);
307520489e1Sad SIMPLEQ_INSERT_TAIL(&sc->sc_queue, msg, chain.simpleq);
3089aa9b8ebSad if (pend == NULL)
30946ed8f7dSad softint_schedule(sc->sc_sih);
3109aa9b8ebSad
3119aa9b8ebSad return (1);
3129aa9b8ebSad }
3139aa9b8ebSad
314520489e1Sad void
dt_dispatch(void * cookie)315520489e1Sad dt_dispatch(void *cookie)
316520489e1Sad {
317520489e1Sad struct dt_softc *sc;
318520489e1Sad struct dt_msg *msg;
3193eeb49f1Smhitch int s;
320520489e1Sad struct dt_device *dtdv;
321520489e1Sad
322520489e1Sad sc = cookie;
323520489e1Sad msg = NULL;
324520489e1Sad
325520489e1Sad for (;;) {
326520489e1Sad s = spltty();
3273eeb49f1Smhitch if (msg != NULL)
328520489e1Sad SLIST_INSERT_HEAD(&sc->sc_free, msg, chain.slist);
329520489e1Sad msg = SIMPLEQ_FIRST(&sc->sc_queue);
330520489e1Sad if (msg != NULL)
331520489e1Sad SIMPLEQ_REMOVE_HEAD(&sc->sc_queue, chain.simpleq);
332520489e1Sad splx(s);
333520489e1Sad if (msg == NULL)
334520489e1Sad break;
335520489e1Sad
3363eeb49f1Smhitch if (msg->src != DT_ADDR_MOUSE && msg->src != DT_ADDR_KBD) {
337520489e1Sad printf("%s: message from unknown dev 0x%x\n",
33803335d0bStsutsui device_xname(sc->sc_dev), sc->sc_msg.src);
339520489e1Sad dt_msg_dump(msg);
340520489e1Sad continue;
341520489e1Sad }
342520489e1Sad if (DT_CTL_P(msg->ctl) != 0) {
343520489e1Sad printf("%s: received control message\n",
34403335d0bStsutsui device_xname(sc->sc_dev));
345520489e1Sad dt_msg_dump(msg);
346520489e1Sad continue;
347520489e1Sad }
348520489e1Sad
349520489e1Sad /*
3503eeb49f1Smhitch * 1. Mouse should have no more than eight buttons, so first
3513eeb49f1Smhitch * 8 bits of body will be zero.
352520489e1Sad * 2. Mouse should always send full locator report.
3533eeb49f1Smhitch * Note: my mouse does not send 'z' data, so the size
3543eeb49f1Smhitch * did not match the size of struct dt_locator_msg - mhitch
355520489e1Sad * 3. Keyboard should never report all-up (0x00) in
356520489e1Sad * a packet with size > 1.
357520489e1Sad */
3583eeb49f1Smhitch if (DT_CTL_LEN(msg->ctl) >= 6 &&
3593eeb49f1Smhitch msg->body[0] == 0 && msg->src != dt_ms_addr) {
3603eeb49f1Smhitch dt_kbd_addr = dt_ms_addr;
3613eeb49f1Smhitch dt_ms_addr = msg->src;
3623eeb49f1Smhitch } else if (DT_CTL_LEN(msg->ctl) < 6 && msg->body[0] != 0 &&
3633eeb49f1Smhitch msg->src != dt_kbd_addr) {
3643eeb49f1Smhitch dt_ms_addr = dt_kbd_addr;
3653eeb49f1Smhitch dt_kbd_addr = msg->src;
366520489e1Sad }
367520489e1Sad
3683eeb49f1Smhitch if (msg->src == dt_kbd_addr)
3693eeb49f1Smhitch dtdv = &dt_kbd_dv;
3703eeb49f1Smhitch else
3713eeb49f1Smhitch dtdv = &dt_ms_dv;
3723eeb49f1Smhitch
373520489e1Sad if (dtdv->dtdv_handler != NULL)
37403335d0bStsutsui (*dtdv->dtdv_handler)(dtdv->dtdv_arg, msg);
375520489e1Sad }
376520489e1Sad }
377520489e1Sad
3789aa9b8ebSad int
dt_msg_get(struct dt_msg * msg,int intr)3799aa9b8ebSad dt_msg_get(struct dt_msg *msg, int intr)
3809aa9b8ebSad {
3819aa9b8ebSad volatile u_int *poll, *data;
3829aa9b8ebSad uint8_t c;
383abacafe4Sjmc int max_polls;
3849aa9b8ebSad
3859aa9b8ebSad poll = dt_state.ds_poll;
3869aa9b8ebSad data = dt_state.ds_data;
3879aa9b8ebSad
3889aa9b8ebSad /*
3899aa9b8ebSad * The interface does not hand us the first byte, which is our
3909aa9b8ebSad * address and cannot ever be anything else but 0x50.
3919aa9b8ebSad */
3929aa9b8ebSad if (dt_state.ds_state == 0) {
3939aa9b8ebSad dt_state.ds_escaped = 0;
3949aa9b8ebSad dt_state.ds_ptr = 0;
3959aa9b8ebSad }
3969aa9b8ebSad
3979aa9b8ebSad for (;;) {
398abacafe4Sjmc max_polls = DT_MAX_POLL;
3999aa9b8ebSad
4009aa9b8ebSad while (!DT_RX_AVAIL(poll)) {
4019aa9b8ebSad if (intr)
4029aa9b8ebSad return (DT_GET_NOTYET);
403abacafe4Sjmc if (max_polls-- <= 0)
4049aa9b8ebSad break;
4059aa9b8ebSad DELAY(1);
4069aa9b8ebSad }
4079aa9b8ebSad
408abacafe4Sjmc if (max_polls <= 0) {
4099aa9b8ebSad if (dt_state.ds_state != 0) {
4109aa9b8ebSad dt_state.ds_bad_pkts++;
4119aa9b8ebSad dt_state.ds_state = 0;
4129aa9b8ebSad }
4139aa9b8ebSad return (DT_GET_ERROR);
4149aa9b8ebSad }
4159aa9b8ebSad
4169aa9b8ebSad c = DT_GET_BYTE(data);
4179aa9b8ebSad
4189aa9b8ebSad if (dt_state.ds_escaped) {
4199aa9b8ebSad switch (c) {
4209aa9b8ebSad case 0xe8:
4219aa9b8ebSad case 0xe9:
4229aa9b8ebSad case 0xea:
4239aa9b8ebSad case 0xeb:
4249aa9b8ebSad c += 0x10;
4259aa9b8ebSad break;
4269aa9b8ebSad }
4279aa9b8ebSad if (c == 'O') {
4289aa9b8ebSad dt_state.ds_bad_pkts++;
4299aa9b8ebSad dt_state.ds_state = 0;
4309aa9b8ebSad return (DT_GET_ERROR);
4319aa9b8ebSad }
4329aa9b8ebSad dt_state.ds_escaped = 0;
4339aa9b8ebSad } else if (c == DT_ESC_CHAR) {
4349aa9b8ebSad dt_state.ds_escaped = 1;
4359aa9b8ebSad continue;
4369aa9b8ebSad }
4379aa9b8ebSad
4389aa9b8ebSad if (dt_state.ds_state == 0) {
4399aa9b8ebSad msg->src = c;
4409aa9b8ebSad dt_state.ds_state = 1;
4419aa9b8ebSad } else if (dt_state.ds_state == 1) {
442520489e1Sad msg->ctl = c;
4439aa9b8ebSad dt_state.ds_state = 2;
444520489e1Sad dt_state.ds_len = DT_CTL_LEN(msg->ctl) + 1;
4459aa9b8ebSad if (dt_state.ds_len > sizeof(msg->body))
4469aa9b8ebSad printf("dt_msg_get: msg truncated: %d\n",
4479aa9b8ebSad dt_state.ds_len);
4489aa9b8ebSad } else /* if (dt_state.ds_state == 2) */ {
4499aa9b8ebSad if (dt_state.ds_ptr < sizeof(msg->body))
4509aa9b8ebSad msg->body[dt_state.ds_ptr++] = c;
4519aa9b8ebSad if (dt_state.ds_ptr >= dt_state.ds_len)
4529aa9b8ebSad break;
4539aa9b8ebSad }
4549aa9b8ebSad }
4559aa9b8ebSad
4569aa9b8ebSad msg->dst = DT_ADDR_HOST;
4579aa9b8ebSad dt_state.ds_state = 0;
4589aa9b8ebSad return (DT_GET_DONE);
4599aa9b8ebSad }
4609aa9b8ebSad
4619aa9b8ebSad void
dt_msg_dump(struct dt_msg * msg)462520489e1Sad dt_msg_dump(struct dt_msg *msg)
4639aa9b8ebSad {
464520489e1Sad int i, l;
4659aa9b8ebSad
466520489e1Sad l = DT_CTL_LEN(msg->ctl);
467520489e1Sad
468520489e1Sad printf("hdr: dst=%02x src=%02x p=%02x sub=%02x len=%02x\n",
469520489e1Sad msg->dst, msg->src, DT_CTL_P(msg->ctl), DT_CTL_SUBADDR(msg->ctl),
470520489e1Sad l);
471520489e1Sad
472520489e1Sad printf("body: ");
473520489e1Sad for (i = 0; i < l && i < 20; i++)
474520489e1Sad printf("%02x ", msg->body[i]);
475520489e1Sad if (i < l) {
476520489e1Sad printf("\n");
477520489e1Sad for (; i < l; i++)
478520489e1Sad printf("%02x ", msg->body[i]);
4799aa9b8ebSad }
480520489e1Sad printf("\n");
4819aa9b8ebSad }
482