1*c7fb772bSthorpej /* $NetBSD: cec.c,v 1.16 2021/08/07 16:19:12 thorpej Exp $ */
29d6ae676Sgmcgarry
39d6ae676Sgmcgarry /*-
49d6ae676Sgmcgarry * Copyright (c) 2003 The NetBSD Foundation, Inc.
59d6ae676Sgmcgarry * All rights reserved.
69d6ae676Sgmcgarry *
79d6ae676Sgmcgarry * This code is derived from software contributed to The NetBSD Foundation
89d6ae676Sgmcgarry * by Gregory McGarry.
99d6ae676Sgmcgarry *
109d6ae676Sgmcgarry * Redistribution and use in source and binary forms, with or without
119d6ae676Sgmcgarry * modification, are permitted provided that the following conditions
129d6ae676Sgmcgarry * are met:
139d6ae676Sgmcgarry * 1. Redistributions of source code must retain the above copyright
149d6ae676Sgmcgarry * notice, this list of conditions and the following disclaimer.
159d6ae676Sgmcgarry * 2. Redistributions in binary form must reproduce the above copyright
169d6ae676Sgmcgarry * notice, this list of conditions and the following disclaimer in the
179d6ae676Sgmcgarry * documentation and/or other materials provided with the distribution.
189d6ae676Sgmcgarry *
199d6ae676Sgmcgarry * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
209d6ae676Sgmcgarry * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
219d6ae676Sgmcgarry * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
229d6ae676Sgmcgarry * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
239d6ae676Sgmcgarry * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
249d6ae676Sgmcgarry * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
259d6ae676Sgmcgarry * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
269d6ae676Sgmcgarry * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
279d6ae676Sgmcgarry * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289d6ae676Sgmcgarry * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
299d6ae676Sgmcgarry * POSSIBILITY OF SUCH DAMAGE.
309d6ae676Sgmcgarry */
319d6ae676Sgmcgarry
329d6ae676Sgmcgarry #include <sys/cdefs.h>
33*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: cec.c,v 1.16 2021/08/07 16:19:12 thorpej Exp $");
349d6ae676Sgmcgarry
359d6ae676Sgmcgarry #include <sys/param.h>
369d6ae676Sgmcgarry #include <sys/systm.h>
379d6ae676Sgmcgarry #include <sys/callout.h>
389d6ae676Sgmcgarry #include <sys/conf.h>
399d6ae676Sgmcgarry #include <sys/device.h>
409d6ae676Sgmcgarry #include <sys/kernel.h>
419d6ae676Sgmcgarry
42a2a38285Sad #include <sys/bus.h>
439d6ae676Sgmcgarry
449d6ae676Sgmcgarry #include <dev/isa/isavar.h>
459d6ae676Sgmcgarry #include <dev/isa/isadmavar.h>
469d6ae676Sgmcgarry
479d6ae676Sgmcgarry #include <dev/gpib/gpibvar.h>
489d6ae676Sgmcgarry
499d6ae676Sgmcgarry #include <dev/ic/nec7210reg.h>
509d6ae676Sgmcgarry
51f3f3dfb3Stsutsui #ifndef DEBUG
529d6ae676Sgmcgarry #define DEBUG
53f3f3dfb3Stsutsui #endif
549d6ae676Sgmcgarry
559d6ae676Sgmcgarry #ifdef DEBUG
569d6ae676Sgmcgarry int cecdebug = 0x1f;
579d6ae676Sgmcgarry #define DPRINTF(flag, str) if (cecdebug & (flag)) printf str
589d6ae676Sgmcgarry #define DBG_FOLLOW 0x01
599d6ae676Sgmcgarry #define DBG_CONFIG 0x02
609d6ae676Sgmcgarry #define DBG_INTR 0x04
619d6ae676Sgmcgarry #define DBG_REPORTTIME 0x08
629d6ae676Sgmcgarry #define DBG_FAIL 0x10
639d6ae676Sgmcgarry #define DBG_WAIT 0x20
649d6ae676Sgmcgarry #else
659d6ae676Sgmcgarry #define DPRINTF(flag, str) /* nothing */
669d6ae676Sgmcgarry #endif
679d6ae676Sgmcgarry
689d6ae676Sgmcgarry #define CEC_IOSIZE 8
699d6ae676Sgmcgarry
709d6ae676Sgmcgarry struct cec_softc {
71cbab9cadSchs device_t sc_dev; /* generic device glue */
729d6ae676Sgmcgarry
739d6ae676Sgmcgarry bus_space_tag_t sc_iot;
749d6ae676Sgmcgarry bus_space_handle_t sc_ioh;
759d6ae676Sgmcgarry isa_chipset_tag_t sc_ic;
769d6ae676Sgmcgarry int sc_drq;
779d6ae676Sgmcgarry void *sc_ih;
789d6ae676Sgmcgarry
799d6ae676Sgmcgarry int sc_myaddr; /* my address */
809d6ae676Sgmcgarry struct gpib_softc *sc_gpib;
819d6ae676Sgmcgarry
829d6ae676Sgmcgarry volatile int sc_flags;
839d6ae676Sgmcgarry #define CECF_IO 0x1
849d6ae676Sgmcgarry #define CECF_PPOLL 0x4
859d6ae676Sgmcgarry #define CECF_READ 0x8
869d6ae676Sgmcgarry #define CECF_TIMO 0x10
879d6ae676Sgmcgarry #define CECF_USEDMA 0x20
889d6ae676Sgmcgarry int sc_ppoll_slave; /* XXX stash our ppoll address */
8988ab7da9Sad callout_t sc_timeout_ch;
909d6ae676Sgmcgarry };
919d6ae676Sgmcgarry
92ab57cc6fScegger int cecprobe(device_t, cfdata_t, void *);
93ab57cc6fScegger void cecattach(device_t, device_t, void *);
949d6ae676Sgmcgarry
95cbab9cadSchs CFATTACH_DECL_NEW(cec, sizeof(struct cec_softc),
969d6ae676Sgmcgarry cecprobe, cecattach, NULL, NULL);
979d6ae676Sgmcgarry
989d6ae676Sgmcgarry void cecreset(void *);
999d6ae676Sgmcgarry int cecpptest(void *, int);
1009d6ae676Sgmcgarry void cecppwatch(void *, int);
1019d6ae676Sgmcgarry void cecppclear(void *);
1029d6ae676Sgmcgarry void cecxfer(void *, int, int, void *, int, int, int);
1039d6ae676Sgmcgarry void cecgo(void *v);
1049d6ae676Sgmcgarry int cecintr(void *);
1059d6ae676Sgmcgarry int cecsendcmds(void *, void *, int);
1069d6ae676Sgmcgarry int cecsenddata(void *, void *, int);
1079d6ae676Sgmcgarry int cecrecvdata(void *, void *, int);
1089d6ae676Sgmcgarry int cecgts(void *);
1099d6ae676Sgmcgarry int cectc(void *, int);
1109d6ae676Sgmcgarry void cecifc(void *);
1119d6ae676Sgmcgarry
1129d6ae676Sgmcgarry static int cecwait(struct cec_softc *, int, int);
1139d6ae676Sgmcgarry static void cectimeout(void *v);
1149d6ae676Sgmcgarry static int nec7210_setaddress(struct cec_softc *, int, int);
1159d6ae676Sgmcgarry static void nec7210_init(struct cec_softc *);
1169d6ae676Sgmcgarry static void nec7210_ifc(struct cec_softc *);
1179d6ae676Sgmcgarry
1189d6ae676Sgmcgarry /*
1199d6ae676Sgmcgarry * Our chipset structure.
1209d6ae676Sgmcgarry */
1219d6ae676Sgmcgarry struct gpib_chipset_tag cec_ic = {
1229d6ae676Sgmcgarry cecreset,
1239d6ae676Sgmcgarry NULL,
1249d6ae676Sgmcgarry NULL,
1259d6ae676Sgmcgarry cecpptest,
1269d6ae676Sgmcgarry cecppwatch,
1279d6ae676Sgmcgarry cecppclear,
1289d6ae676Sgmcgarry cecxfer,
1299d6ae676Sgmcgarry cectc,
1309d6ae676Sgmcgarry cecgts,
1319d6ae676Sgmcgarry cecifc,
1329d6ae676Sgmcgarry cecsendcmds,
1339d6ae676Sgmcgarry cecsenddata,
13416cd2575Scube cecrecvdata,
13516cd2575Scube NULL,
13616cd2575Scube NULL
1379d6ae676Sgmcgarry };
1389d6ae676Sgmcgarry
1399d6ae676Sgmcgarry int cecwtimeout = 0x10000;
1409d6ae676Sgmcgarry int cecdmathresh = 3;
1419d6ae676Sgmcgarry
1429d6ae676Sgmcgarry int
cecprobe(device_t parent,cfdata_t match,void * aux)143ab57cc6fScegger cecprobe(device_t parent, cfdata_t match, void *aux)
1449d6ae676Sgmcgarry {
1459d6ae676Sgmcgarry struct isa_attach_args *ia = aux;
1469d6ae676Sgmcgarry bus_space_tag_t iot = ia->ia_iot;
1479d6ae676Sgmcgarry bus_space_handle_t ioh;
1489d6ae676Sgmcgarry
1499d6ae676Sgmcgarry DPRINTF(DBG_CONFIG, ("cecprobe: called\n"));
1509d6ae676Sgmcgarry
1519d6ae676Sgmcgarry if (ia->ia_nio < 1)
1529d6ae676Sgmcgarry return (0);
1539d6ae676Sgmcgarry if (ia->ia_nirq < 1)
1549d6ae676Sgmcgarry return (0);
1559d6ae676Sgmcgarry if (ia->ia_ndrq < 1)
1569d6ae676Sgmcgarry return (0);
1579d6ae676Sgmcgarry
1589d6ae676Sgmcgarry if (ISA_DIRECT_CONFIG(ia))
1599d6ae676Sgmcgarry return (0);
1609d6ae676Sgmcgarry
1611308c6d7Sdrochner if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
1629d6ae676Sgmcgarry return (0);
1639d6ae676Sgmcgarry
1641308c6d7Sdrochner if (ia->ia_ndrq > 0 && ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ)
1659d6ae676Sgmcgarry ia->ia_ndrq = 0;
1669d6ae676Sgmcgarry
1679d6ae676Sgmcgarry if (bus_space_map(iot, ia->ia_io[0].ir_addr, CEC_IOSIZE, 0, &ioh))
1689d6ae676Sgmcgarry return (0);
1699d6ae676Sgmcgarry
1709d6ae676Sgmcgarry /* XXX insert probe here */
1719d6ae676Sgmcgarry
1729d6ae676Sgmcgarry ia->ia_io[0].ir_size = CEC_IOSIZE;
1739d6ae676Sgmcgarry ia->ia_niomem = 0;
1749d6ae676Sgmcgarry
1759d6ae676Sgmcgarry bus_space_unmap(iot, ioh, CEC_IOSIZE);
1769d6ae676Sgmcgarry
1779d6ae676Sgmcgarry return (1);
1789d6ae676Sgmcgarry }
1799d6ae676Sgmcgarry
1809d6ae676Sgmcgarry void
cecattach(device_t parent,device_t self,void * aux)181ab57cc6fScegger cecattach(device_t parent, device_t self, void *aux)
1829d6ae676Sgmcgarry {
183cbab9cadSchs struct cec_softc *sc = device_private(self);
1849d6ae676Sgmcgarry struct isa_attach_args *ia = aux;
1859d6ae676Sgmcgarry struct gpibdev_attach_args ga;
1869d6ae676Sgmcgarry bus_size_t maxsize;
1879d6ae676Sgmcgarry
1889d6ae676Sgmcgarry printf("\n");
1899d6ae676Sgmcgarry
1909d6ae676Sgmcgarry DPRINTF(DBG_CONFIG, ("cecattach: called\n"));
1919d6ae676Sgmcgarry
192cbab9cadSchs sc->sc_dev = self;
1939d6ae676Sgmcgarry sc->sc_iot = ia->ia_iot;
1949d6ae676Sgmcgarry sc->sc_ic = ia->ia_ic;
1959d6ae676Sgmcgarry
1969d6ae676Sgmcgarry if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, CEC_IOSIZE,
1979d6ae676Sgmcgarry 0, &sc->sc_ioh) != 0) {
198cbab9cadSchs aprint_error_dev(sc->sc_dev, "unable to map I/O space\n");
1999d6ae676Sgmcgarry return;
2009d6ae676Sgmcgarry }
2019d6ae676Sgmcgarry
2029d6ae676Sgmcgarry if (ia->ia_ndrq > 0) {
2039d6ae676Sgmcgarry sc->sc_flags |= CECF_USEDMA;
2049d6ae676Sgmcgarry sc->sc_drq = ia->ia_drq[0].ir_drq;
2059d6ae676Sgmcgarry
2069d6ae676Sgmcgarry (void) isa_drq_alloc(sc->sc_ic, sc->sc_drq);
2079d6ae676Sgmcgarry maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq);
2089d6ae676Sgmcgarry if (isa_dmamap_create(sc->sc_ic, sc->sc_drq,
2099d6ae676Sgmcgarry maxsize, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW)) {
21071fbb921Smsaitoh aprint_error_dev(sc->sc_dev,
21171fbb921Smsaitoh "unable to create map for drq %d\n", sc->sc_drq);
2129d6ae676Sgmcgarry sc->sc_flags &= ~CECF_USEDMA;
2139d6ae676Sgmcgarry }
2149d6ae676Sgmcgarry }
2159d6ae676Sgmcgarry
2169d6ae676Sgmcgarry sc->sc_myaddr = 15; /* XXX */
2179d6ae676Sgmcgarry
2189d6ae676Sgmcgarry cecreset(sc);
2199d6ae676Sgmcgarry (void) nec7210_setaddress(sc, sc->sc_myaddr, -1);
2209d6ae676Sgmcgarry
2219d6ae676Sgmcgarry sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
2229d6ae676Sgmcgarry IST_EDGE, IPL_BIO, cecintr, sc);
2239d6ae676Sgmcgarry if (sc->sc_ih == NULL) {
224cbab9cadSchs aprint_error_dev(sc->sc_dev, "couldn't establish interrupt\n");
2259d6ae676Sgmcgarry return;
2269d6ae676Sgmcgarry }
2279d6ae676Sgmcgarry
22888ab7da9Sad callout_init(&sc->sc_timeout_ch, 0);
2299d6ae676Sgmcgarry
2309d6ae676Sgmcgarry /* attach MI GPIB bus */
2319d6ae676Sgmcgarry cec_ic.cookie = (void *)sc;
2329d6ae676Sgmcgarry ga.ga_ic = &cec_ic;
2339d6ae676Sgmcgarry ga.ga_address = sc->sc_myaddr;
2349d6ae676Sgmcgarry sc->sc_gpib =
2352685996bSthorpej (struct gpib_softc *)config_found(self, &ga, gpibdevprint,
236*c7fb772bSthorpej CFARGS_NONE);
2379d6ae676Sgmcgarry }
2389d6ae676Sgmcgarry
2399d6ae676Sgmcgarry int
cecintr(void * v)2409d6ae676Sgmcgarry cecintr(void *v)
2419d6ae676Sgmcgarry {
2429d6ae676Sgmcgarry struct cec_softc *sc = v;
2439d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
2449d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
2459d6ae676Sgmcgarry u_int8_t stat1, stat2;
2469d6ae676Sgmcgarry
2479d6ae676Sgmcgarry stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
2489d6ae676Sgmcgarry stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
2499d6ae676Sgmcgarry
2509d6ae676Sgmcgarry DPRINTF(DBG_INTR, ("cecintr: sc=%p stat1=0x%x stat2=0x%x\n",
2519d6ae676Sgmcgarry sc, stat1, stat2));
2529d6ae676Sgmcgarry
2539d6ae676Sgmcgarry if (sc->sc_flags & CECF_IO) {
2549d6ae676Sgmcgarry
2559d6ae676Sgmcgarry if (sc->sc_flags & CECF_TIMO)
2569d6ae676Sgmcgarry callout_stop(&sc->sc_timeout_ch);
2579d6ae676Sgmcgarry
2589d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
2599d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
2609d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
2619d6ae676Sgmcgarry sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
2629d6ae676Sgmcgarry if (sc->sc_flags & CECF_USEDMA)
2639d6ae676Sgmcgarry isa_dmadone(sc->sc_ic, sc->sc_drq);
2649d6ae676Sgmcgarry gpibintr(sc->sc_gpib);
2659d6ae676Sgmcgarry
2669d6ae676Sgmcgarry } else if (sc->sc_flags & CECF_PPOLL) {
2679d6ae676Sgmcgarry
2689d6ae676Sgmcgarry if (cecpptest(sc, sc->sc_ppoll_slave)) {
2699d6ae676Sgmcgarry sc->sc_flags &= ~CECF_PPOLL;
2709d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
2719d6ae676Sgmcgarry gpibintr(sc->sc_gpib);
2729d6ae676Sgmcgarry }
2739d6ae676Sgmcgarry
2749d6ae676Sgmcgarry }
2759d6ae676Sgmcgarry return (1);
2769d6ae676Sgmcgarry }
2779d6ae676Sgmcgarry
2789d6ae676Sgmcgarry void
cecreset(void * v)2799d6ae676Sgmcgarry cecreset(void *v)
2809d6ae676Sgmcgarry {
2819d6ae676Sgmcgarry struct cec_softc *sc = v;
2829d6ae676Sgmcgarry u_int8_t cmd;
2839d6ae676Sgmcgarry
2849d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecreset: sc=%p\n", sc));
2859d6ae676Sgmcgarry
2869d6ae676Sgmcgarry nec7210_init(sc);
2879d6ae676Sgmcgarry nec7210_ifc(sc);
2889d6ae676Sgmcgarry /* we're now the system controller */
2899d6ae676Sgmcgarry
2909d6ae676Sgmcgarry /* XXX should be pushed higher */
2919d6ae676Sgmcgarry
2929d6ae676Sgmcgarry /* universal device clear */
2939d6ae676Sgmcgarry cmd = GPIBCMD_DCL;
2949d6ae676Sgmcgarry (void) cecsendcmds(sc, &cmd, 1);
2959d6ae676Sgmcgarry /* delay for devices to clear */
2969d6ae676Sgmcgarry DELAY(100000);
2979d6ae676Sgmcgarry }
2989d6ae676Sgmcgarry
2999d6ae676Sgmcgarry int
cecsendcmds(void * v,void * ptr,int origcnt)3009d6ae676Sgmcgarry cecsendcmds(void *v, void *ptr, int origcnt)
3019d6ae676Sgmcgarry {
3029d6ae676Sgmcgarry struct cec_softc *sc = v;
3039d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
3049d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
3059d6ae676Sgmcgarry int cnt = origcnt;
3069d6ae676Sgmcgarry u_int8_t *addr = ptr;
3079d6ae676Sgmcgarry
3089d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecsendcmds: sc=%p, ptr=%p cnt=%d\n",
3099d6ae676Sgmcgarry sc, ptr, origcnt));
3109d6ae676Sgmcgarry
3119d6ae676Sgmcgarry while (--cnt >= 0) {
3129d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
3139d6ae676Sgmcgarry if (cecwait(sc, 0, ISR2_CO))
3149d6ae676Sgmcgarry return (origcnt - cnt - 1);
3159d6ae676Sgmcgarry }
3169d6ae676Sgmcgarry return (origcnt);
3179d6ae676Sgmcgarry }
3189d6ae676Sgmcgarry
3199d6ae676Sgmcgarry
3209d6ae676Sgmcgarry int
cecrecvdata(void * v,void * ptr,int origcnt)3219d6ae676Sgmcgarry cecrecvdata(void *v, void *ptr, int origcnt)
3229d6ae676Sgmcgarry {
3239d6ae676Sgmcgarry struct cec_softc *sc = v;
3249d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
3259d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
3269d6ae676Sgmcgarry int cnt = origcnt;
3279d6ae676Sgmcgarry u_int8_t *addr = ptr;
3289d6ae676Sgmcgarry
3299d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecrecvdata: sc=%p, ptr=%p cnt=%d\n",
3309d6ae676Sgmcgarry sc, ptr, origcnt));
3319d6ae676Sgmcgarry
3329d6ae676Sgmcgarry /* XXX holdoff on end */
3339d6ae676Sgmcgarry bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_AUXMR, AUXCMD_RHDF);
3349d6ae676Sgmcgarry
3359d6ae676Sgmcgarry if (cnt) {
3369d6ae676Sgmcgarry while (--cnt >= 0) {
3379d6ae676Sgmcgarry if (cecwait(sc, ISR1_DI, 0))
3389d6ae676Sgmcgarry return (origcnt - cnt - 1);
3399d6ae676Sgmcgarry *addr++ = bus_space_read_1(iot, ioh, NEC7210_DIR);
3409d6ae676Sgmcgarry }
3419d6ae676Sgmcgarry }
3429d6ae676Sgmcgarry return (origcnt);
3439d6ae676Sgmcgarry }
3449d6ae676Sgmcgarry
3459d6ae676Sgmcgarry int
cecsenddata(void * v,void * ptr,int origcnt)3469d6ae676Sgmcgarry cecsenddata(void *v, void *ptr, int origcnt)
3479d6ae676Sgmcgarry {
3489d6ae676Sgmcgarry struct cec_softc *sc = v;
3499d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
3509d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
3519d6ae676Sgmcgarry int cnt = origcnt;
3529d6ae676Sgmcgarry u_int8_t *addr = ptr;
3539d6ae676Sgmcgarry
3549d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecdsenddata: sc=%p, ptr=%p cnt=%d\n",
3559d6ae676Sgmcgarry sc, ptr, origcnt));
3569d6ae676Sgmcgarry
3579d6ae676Sgmcgarry if (cnt) {
3589d6ae676Sgmcgarry while (--cnt > 0) {
3599d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
3609d6ae676Sgmcgarry if (cecwait(sc, ISR1_DO, 0))
3619d6ae676Sgmcgarry return (origcnt - cnt - 1);
3629d6ae676Sgmcgarry }
3639d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
3649d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr);
3659d6ae676Sgmcgarry (void) cecwait(sc, ISR1_DO, 0);
3669d6ae676Sgmcgarry }
3679d6ae676Sgmcgarry return (origcnt);
3689d6ae676Sgmcgarry }
3699d6ae676Sgmcgarry
3709d6ae676Sgmcgarry int
cectc(void * v,int sync)3719d6ae676Sgmcgarry cectc(void *v, int sync)
3729d6ae676Sgmcgarry {
3739d6ae676Sgmcgarry struct cec_softc *sc = v;
3749d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
3759d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
3769d6ae676Sgmcgarry u_int8_t adsr;
3779d6ae676Sgmcgarry int timo = cecwtimeout;
3789d6ae676Sgmcgarry
3799d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cectc: sc=%p, sync=%d\n", sc, sync));
3809d6ae676Sgmcgarry
3819d6ae676Sgmcgarry adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
3829d6ae676Sgmcgarry #if 0
3839d6ae676Sgmcgarry if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_CIC) {
3849d6ae676Sgmcgarry DPRINTF(0xff, ("cectc: already CIC\n"));
3859d6ae676Sgmcgarry return (0);
3869d6ae676Sgmcgarry }
3879d6ae676Sgmcgarry #endif
3889d6ae676Sgmcgarry
3899d6ae676Sgmcgarry if (sync) {
3909d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_RHDF);
3919d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCS);
3929d6ae676Sgmcgarry } else {
3939d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
3949d6ae676Sgmcgarry }
3959d6ae676Sgmcgarry
3969d6ae676Sgmcgarry /* wait until ATN is asserted */
3979d6ae676Sgmcgarry for (;;) {
3989d6ae676Sgmcgarry adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
3999d6ae676Sgmcgarry if (--timo == 0) {
4009d6ae676Sgmcgarry DPRINTF(DBG_REPORTTIME, ("cectc: timeout\n"));
4019d6ae676Sgmcgarry return (1);
4029d6ae676Sgmcgarry }
4039d6ae676Sgmcgarry if ((adsr & ADSR_NATN) == 0)
4049d6ae676Sgmcgarry break;
4059d6ae676Sgmcgarry DELAY(1);
4069d6ae676Sgmcgarry }
4079d6ae676Sgmcgarry
4089d6ae676Sgmcgarry return (0);
4099d6ae676Sgmcgarry }
4109d6ae676Sgmcgarry
4119d6ae676Sgmcgarry int
cecgts(void * v)4129d6ae676Sgmcgarry cecgts(void *v)
4139d6ae676Sgmcgarry {
4149d6ae676Sgmcgarry struct cec_softc *sc = v;
4159d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
4169d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
4179d6ae676Sgmcgarry u_int8_t adsr;
4189d6ae676Sgmcgarry int timo = cecwtimeout;
4199d6ae676Sgmcgarry
4209d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecgts: sc=%p\n", sc));
4219d6ae676Sgmcgarry
4229d6ae676Sgmcgarry adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
4239d6ae676Sgmcgarry #if 0
4249d6ae676Sgmcgarry if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_NATN) {
4259d6ae676Sgmcgarry DPRINTF(0xff, ("cecgts: already standby\n"));
4269d6ae676Sgmcgarry return (0);
4279d6ae676Sgmcgarry }
4289d6ae676Sgmcgarry #endif
4299d6ae676Sgmcgarry
4309d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_GTS);
4319d6ae676Sgmcgarry
4329d6ae676Sgmcgarry /* wait unit ATN is released */
4339d6ae676Sgmcgarry for (;;) {
4349d6ae676Sgmcgarry adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
4359d6ae676Sgmcgarry if (--timo == 0) {
4369d6ae676Sgmcgarry DPRINTF(DBG_REPORTTIME, ("cecgts: timeout\n"));
4379d6ae676Sgmcgarry return (1);
4389d6ae676Sgmcgarry }
4399d6ae676Sgmcgarry if ((adsr & ADSR_NATN) == ADSR_NATN)
4409d6ae676Sgmcgarry break;
4419d6ae676Sgmcgarry DELAY(1);
4429d6ae676Sgmcgarry }
4439d6ae676Sgmcgarry
4449d6ae676Sgmcgarry return (0);
4459d6ae676Sgmcgarry }
4469d6ae676Sgmcgarry
4479d6ae676Sgmcgarry int
cecpptest(void * v,int slave)4489d6ae676Sgmcgarry cecpptest(void *v, int slave)
4499d6ae676Sgmcgarry {
4509d6ae676Sgmcgarry struct cec_softc *sc = v;
4519d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
4529d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
4539d6ae676Sgmcgarry int ppoll;
4549d6ae676Sgmcgarry
4559d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecpptest: sc=%p slave=%d\n", sc, slave));
4569d6ae676Sgmcgarry
4579d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
4589d6ae676Sgmcgarry DELAY(25);
4599d6ae676Sgmcgarry ppoll = bus_space_read_1(iot, ioh, NEC7210_CPTR);
4609d6ae676Sgmcgarry DPRINTF(0xff, ("cecpptest: ppoll=%x\n", ppoll));
4619d6ae676Sgmcgarry return ((ppoll & (0x80 >> slave)) != 0);
4629d6ae676Sgmcgarry }
4639d6ae676Sgmcgarry
4649d6ae676Sgmcgarry void
cecppwatch(void * v,int slave)4659d6ae676Sgmcgarry cecppwatch(void *v, int slave)
4669d6ae676Sgmcgarry {
4679d6ae676Sgmcgarry struct cec_softc *sc = v;
4689d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
4699d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
4709d6ae676Sgmcgarry
4719d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecppwatch: sc=%p\n", sc));
4729d6ae676Sgmcgarry
4739d6ae676Sgmcgarry sc->sc_flags |= CECF_PPOLL;
4749d6ae676Sgmcgarry sc->sc_ppoll_slave = slave;
4759d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
4769d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
4779d6ae676Sgmcgarry }
4789d6ae676Sgmcgarry
4799d6ae676Sgmcgarry void
cecppclear(void * v)4809d6ae676Sgmcgarry cecppclear(void *v)
4819d6ae676Sgmcgarry {
4829d6ae676Sgmcgarry struct cec_softc *sc = v;
4839d6ae676Sgmcgarry
4849d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecppclear: sc=%p\n", sc));
4859d6ae676Sgmcgarry
4869d6ae676Sgmcgarry sc->sc_flags &= ~CECF_PPOLL;
4879d6ae676Sgmcgarry bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_IMR2, 0);
4889d6ae676Sgmcgarry }
4899d6ae676Sgmcgarry
4909d6ae676Sgmcgarry void
cecxfer(void * v,int slave,int sec,void * buf,int count,int dir,int timo)4919d6ae676Sgmcgarry cecxfer(void *v, int slave, int sec, void *buf, int count, int dir, int timo)
4929d6ae676Sgmcgarry {
4939d6ae676Sgmcgarry struct cec_softc *sc = v;
4949d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
4959d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
4969d6ae676Sgmcgarry
4979d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW,
4989d6ae676Sgmcgarry ("cecxfer: slave=%d sec=%d buf=%p count=%d dir=%x timo=%d\n",
4999d6ae676Sgmcgarry slave, sec, buf, count, dir, timo));
5009d6ae676Sgmcgarry
5019d6ae676Sgmcgarry sc->sc_flags |= CECF_IO;
5029d6ae676Sgmcgarry if (dir == GPIB_READ)
5039d6ae676Sgmcgarry sc->sc_flags |= CECF_READ;
5049d6ae676Sgmcgarry if (timo) {
5059d6ae676Sgmcgarry sc->sc_flags |= CECF_TIMO;
5069d6ae676Sgmcgarry callout_reset(&sc->sc_timeout_ch, 5*hz, cectimeout, sc);
5079d6ae676Sgmcgarry }
5089d6ae676Sgmcgarry
5099d6ae676Sgmcgarry if (sc->sc_flags & CECF_READ) {
5109d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecxfer: DMA read request\n"));
5119d6ae676Sgmcgarry if ((sc->sc_flags & CECF_USEDMA) != 0) {
5129d6ae676Sgmcgarry isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count, NULL,
5139d6ae676Sgmcgarry DMAMODE_READ | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
5149d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAI);
5159d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
5169d6ae676Sgmcgarry // XXX (void) cecrecv(sc, slave, sec, NULL, 0);
5179d6ae676Sgmcgarry (void) gpibrecv(&cec_ic, slave, sec, NULL, 0);
5189d6ae676Sgmcgarry } else {
5199d6ae676Sgmcgarry /* XXX this doesn't work */
5209d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
5219d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
5229d6ae676Sgmcgarry // XXX (void) cecrecv(sc, slave, sec, buf, count);
5239d6ae676Sgmcgarry (void) gpibrecv(&cec_ic, slave, sec, buf, count);
5249d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
5259d6ae676Sgmcgarry }
5269d6ae676Sgmcgarry } else {
5279d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecxfer: DMA write request\n"));
5289d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
5299d6ae676Sgmcgarry if (count < cecdmathresh ||
5309d6ae676Sgmcgarry (sc->sc_flags & CECF_USEDMA) == 0) {
5319d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
5329d6ae676Sgmcgarry // XXX (void) cecsend(sc, slave, sec, buf, count);
5339d6ae676Sgmcgarry (void) gpibsend(&cec_ic, slave, sec, buf, count);
5349d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
5359d6ae676Sgmcgarry return;
5369d6ae676Sgmcgarry }
5379d6ae676Sgmcgarry /* we send the last byte with EOI set */
5389d6ae676Sgmcgarry isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count-1, NULL,
5399d6ae676Sgmcgarry DMAMODE_WRITE | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
5409d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAO);
5419d6ae676Sgmcgarry // XXX (void) cecsend(sc, slave, sec, NULL, 0);
5429d6ae676Sgmcgarry (void) gpibsend(&cec_ic, slave, sec, NULL, 0);
5439d6ae676Sgmcgarry while (!isa_dmafinished(sc->sc_ic, sc->sc_drq))
5449d6ae676Sgmcgarry DELAY(1);
5459d6ae676Sgmcgarry (void) cecwait(sc, ISR1_DO, 0);
5469d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
5479d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_CDOR, *(char *)buf+count);
5489d6ae676Sgmcgarry /* generate interrupt */
5499d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_DO);
5509d6ae676Sgmcgarry }
5519d6ae676Sgmcgarry }
5529d6ae676Sgmcgarry
5539d6ae676Sgmcgarry void
cecifc(void * v)5549d6ae676Sgmcgarry cecifc(void *v)
5559d6ae676Sgmcgarry {
5569d6ae676Sgmcgarry struct cec_softc *sc = v;
5579d6ae676Sgmcgarry
5589d6ae676Sgmcgarry nec7210_ifc(sc);
5599d6ae676Sgmcgarry }
5609d6ae676Sgmcgarry
5619d6ae676Sgmcgarry static int
nec7210_setaddress(struct cec_softc * sc,int pri,int sec)5629d6ae676Sgmcgarry nec7210_setaddress(struct cec_softc *sc, int pri, int sec)
5639d6ae676Sgmcgarry {
5649d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
5659d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
5669d6ae676Sgmcgarry u_int8_t admr;
5679d6ae676Sgmcgarry
5689d6ae676Sgmcgarry /* assign our primary address */
5699d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_ADDR, (pri & ADDR_MASK));
5709d6ae676Sgmcgarry
5719d6ae676Sgmcgarry admr = ADMR_TRM0 | ADMR_TRM1;
5729d6ae676Sgmcgarry
5739d6ae676Sgmcgarry /* assign our secondary address */
5749d6ae676Sgmcgarry if (sec != -1) {
5759d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_ADDR,
5769d6ae676Sgmcgarry (ADDR_ARS | (sec & ADDR_MASK)));
5779d6ae676Sgmcgarry admr |= ADMR_ADM1;
5789d6ae676Sgmcgarry } else {
5799d6ae676Sgmcgarry /* disable secondary address */
5809d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_ADDR,
5819d6ae676Sgmcgarry (ADDR_ARS | ADDR_DT | ADDR_DL));
5829d6ae676Sgmcgarry admr |= ADMR_ADM0;
5839d6ae676Sgmcgarry }
5849d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_ADMR, admr);
5859d6ae676Sgmcgarry
5869d6ae676Sgmcgarry return (0);
5879d6ae676Sgmcgarry }
5889d6ae676Sgmcgarry
5899d6ae676Sgmcgarry static void
nec7210_init(struct cec_softc * sc)5909d6ae676Sgmcgarry nec7210_init(struct cec_softc *sc)
5919d6ae676Sgmcgarry {
5929d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
5939d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
5949d6ae676Sgmcgarry
5959d6ae676Sgmcgarry /* reset chip */
5969d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CRST);
5979d6ae676Sgmcgarry
5989d6ae676Sgmcgarry /* clear interrupts */
5999d6ae676Sgmcgarry bus_space_read_1(iot, ioh, NEC7210_CPTR);
6009d6ae676Sgmcgarry bus_space_read_1(iot, ioh, NEC7210_ISR1);
6019d6ae676Sgmcgarry bus_space_read_1(iot, ioh, NEC7210_ISR2);
6029d6ae676Sgmcgarry
6039d6ae676Sgmcgarry /* initialise interrupts */
6049d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
6059d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
6069d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_SPMR, 0);
6079d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_EOSR, 0);
6089d6ae676Sgmcgarry
6099d6ae676Sgmcgarry /* set internal clock to 8MHz */
6109d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_ICR | 0x8));
6119d6ae676Sgmcgarry /* parallel poll unconfigure */
6129d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_PPOLL | PPOLL_PPU));
6139d6ae676Sgmcgarry
6149d6ae676Sgmcgarry /* assign our address */
6159d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_ADDR, 0);
6169d6ae676Sgmcgarry /* disable secondary address */
6179d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_ADDR,
6189d6ae676Sgmcgarry (ADDR_ARS | ADDR_DT | ADDR_DL));
6199d6ae676Sgmcgarry
6209d6ae676Sgmcgarry /* setup transceivers */
6219d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_ADMR,
6229d6ae676Sgmcgarry (ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1));
6239d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR,
6249d6ae676Sgmcgarry (AUXMR_REGA | AUX_A_HSNORM));
6259d6ae676Sgmcgarry
6269d6ae676Sgmcgarry /* set INT pin to active high */
6279d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGB);
6289d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGE);
6299d6ae676Sgmcgarry
6309d6ae676Sgmcgarry /* holdoff on end condition */
6319d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_REGA | AUX_A_HLDE));
6329d6ae676Sgmcgarry
6339d6ae676Sgmcgarry /* reconnect to bus */
6349d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_CMD | AUXCMD_IEPON));
6359d6ae676Sgmcgarry }
6369d6ae676Sgmcgarry
6379d6ae676Sgmcgarry /*
6389d6ae676Sgmcgarry * Place all devices on the bus into quiescient state ready for
6399d6ae676Sgmcgarry * remote programming.
6409d6ae676Sgmcgarry * Obviously, we're the system controller upon exit.
6419d6ae676Sgmcgarry */
6429d6ae676Sgmcgarry void
nec7210_ifc(struct cec_softc * sc)6439d6ae676Sgmcgarry nec7210_ifc(struct cec_softc *sc)
6449d6ae676Sgmcgarry {
6459d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
6469d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
6479d6ae676Sgmcgarry
6489d6ae676Sgmcgarry /*XXX*/ bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
6499d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CREN);
6509d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SIFC);
6519d6ae676Sgmcgarry /* wait for devices to enter quiescient state */
6529d6ae676Sgmcgarry DELAY(100);
6539d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CIFC);
6549d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SREN);
6559d6ae676Sgmcgarry }
6569d6ae676Sgmcgarry
6579d6ae676Sgmcgarry static int
cecwait(struct cec_softc * sc,int x1,int x2)6589d6ae676Sgmcgarry cecwait(struct cec_softc *sc, int x1, int x2)
6599d6ae676Sgmcgarry {
6609d6ae676Sgmcgarry int timo = cecwtimeout;
6619d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
6629d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
6639d6ae676Sgmcgarry u_int8_t stat1, stat2;
6649d6ae676Sgmcgarry
6659d6ae676Sgmcgarry DPRINTF(DBG_WAIT, ("cecwait: sc=%p, x1=0x%x x2=0x%x\n", sc, x1, x2));
6669d6ae676Sgmcgarry
6679d6ae676Sgmcgarry for (;;) {
6689d6ae676Sgmcgarry stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
6699d6ae676Sgmcgarry stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
6709d6ae676Sgmcgarry #if 0
6719d6ae676Sgmcgarry if ((stat1 & ISR1_ERR)) {
6729d6ae676Sgmcgarry DPRINTF(DBG_WAIT, ("cecwait: got ERR\n"));
6739d6ae676Sgmcgarry return (1);
6749d6ae676Sgmcgarry }
6759d6ae676Sgmcgarry #endif
6769d6ae676Sgmcgarry if (--timo == 0) {
6779d6ae676Sgmcgarry DPRINTF(DBG_REPORTTIME,
6789d6ae676Sgmcgarry ("cecwait: timeout x1=0x%x x2=0x%x\n", x1, x2));
6799d6ae676Sgmcgarry return (1);
6809d6ae676Sgmcgarry }
6819d6ae676Sgmcgarry if ((stat1 & x1) || (stat2 & x2))
6829d6ae676Sgmcgarry break;
6839d6ae676Sgmcgarry DELAY(1);
6849d6ae676Sgmcgarry }
6859d6ae676Sgmcgarry return (0);
6869d6ae676Sgmcgarry }
6879d6ae676Sgmcgarry
6889d6ae676Sgmcgarry static void
cectimeout(void * v)6899d6ae676Sgmcgarry cectimeout(void *v)
6909d6ae676Sgmcgarry {
6919d6ae676Sgmcgarry struct cec_softc *sc = v;
6929d6ae676Sgmcgarry bus_space_tag_t iot = sc->sc_iot;
6939d6ae676Sgmcgarry bus_space_handle_t ioh = sc->sc_ioh;
6949d6ae676Sgmcgarry int s;
6959d6ae676Sgmcgarry
6969d6ae676Sgmcgarry DPRINTF(DBG_FOLLOW, ("cectimeout: sc=%p\n", sc));
6979d6ae676Sgmcgarry
6989d6ae676Sgmcgarry s = splbio();
6999d6ae676Sgmcgarry if (sc->sc_flags & CECF_IO) {
7009d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
7019d6ae676Sgmcgarry bus_space_write_2(iot, ioh, NEC7210_IMR2, 0);
7029d6ae676Sgmcgarry bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
7039d6ae676Sgmcgarry sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
7049d6ae676Sgmcgarry isa_dmaabort(sc->sc_ic, sc->sc_drq);
705cbab9cadSchs aprint_error_dev(sc->sc_dev, "%s timeout\n",
7069d6ae676Sgmcgarry sc->sc_flags & CECF_READ ? "read" : "write");
7079d6ae676Sgmcgarry gpibintr(sc->sc_gpib);
7089d6ae676Sgmcgarry }
7099d6ae676Sgmcgarry splx(s);
7109d6ae676Sgmcgarry }
711