Home | History | Annotate | Line # | Download | only in isa
cec.c revision 1.6
      1  1.6        ad /*	$NetBSD: cec.c,v 1.6 2007/07/09 21:00:49 ad Exp $	*/
      2  1.1  gmcgarry 
      3  1.1  gmcgarry /*-
      4  1.1  gmcgarry  * Copyright (c) 2003 The NetBSD Foundation, Inc.
      5  1.1  gmcgarry  * All rights reserved.
      6  1.1  gmcgarry  *
      7  1.1  gmcgarry  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1  gmcgarry  * by Gregory McGarry.
      9  1.1  gmcgarry  *
     10  1.1  gmcgarry  * Redistribution and use in source and binary forms, with or without
     11  1.1  gmcgarry  * modification, are permitted provided that the following conditions
     12  1.1  gmcgarry  * are met:
     13  1.1  gmcgarry  * 1. Redistributions of source code must retain the above copyright
     14  1.1  gmcgarry  *    notice, this list of conditions and the following disclaimer.
     15  1.1  gmcgarry  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  gmcgarry  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  gmcgarry  *    documentation and/or other materials provided with the distribution.
     18  1.1  gmcgarry  * 3. All advertising materials mentioning features or use of this software
     19  1.1  gmcgarry  *    must display the following acknowledgement:
     20  1.1  gmcgarry  *	This product includes software developed by the NetBSD
     21  1.1  gmcgarry  *	Foundation, Inc. and its contributors.
     22  1.1  gmcgarry  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.1  gmcgarry  *    contributors may be used to endorse or promote products derived
     24  1.1  gmcgarry  *    from this software without specific prior written permission.
     25  1.1  gmcgarry  *
     26  1.1  gmcgarry  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.1  gmcgarry  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.1  gmcgarry  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.1  gmcgarry  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.1  gmcgarry  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.1  gmcgarry  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.1  gmcgarry  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.1  gmcgarry  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.1  gmcgarry  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.1  gmcgarry  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.1  gmcgarry  * POSSIBILITY OF SUCH DAMAGE.
     37  1.1  gmcgarry  */
     38  1.1  gmcgarry 
     39  1.1  gmcgarry #include <sys/cdefs.h>
     40  1.6        ad __KERNEL_RCSID(0, "$NetBSD: cec.c,v 1.6 2007/07/09 21:00:49 ad Exp $");
     41  1.1  gmcgarry 
     42  1.1  gmcgarry #include <sys/param.h>
     43  1.1  gmcgarry #include <sys/systm.h>
     44  1.1  gmcgarry #include <sys/callout.h>
     45  1.1  gmcgarry #include <sys/conf.h>
     46  1.1  gmcgarry #include <sys/device.h>
     47  1.1  gmcgarry #include <sys/kernel.h>
     48  1.1  gmcgarry 
     49  1.1  gmcgarry #include <machine/bus.h>
     50  1.1  gmcgarry 
     51  1.1  gmcgarry #include <dev/isa/isavar.h>
     52  1.1  gmcgarry #include <dev/isa/isadmavar.h>
     53  1.1  gmcgarry 
     54  1.1  gmcgarry #include <dev/gpib/gpibvar.h>
     55  1.1  gmcgarry 
     56  1.1  gmcgarry #include <dev/ic/nec7210reg.h>
     57  1.1  gmcgarry 
     58  1.1  gmcgarry #define DEBUG
     59  1.1  gmcgarry 
     60  1.1  gmcgarry #ifdef DEBUG
     61  1.1  gmcgarry int cecdebug = 0x1f;
     62  1.1  gmcgarry #define DPRINTF(flag, str)	if (cecdebug & (flag)) printf str
     63  1.1  gmcgarry #define DBG_FOLLOW	0x01
     64  1.1  gmcgarry #define DBG_CONFIG	0x02
     65  1.1  gmcgarry #define DBG_INTR	0x04
     66  1.1  gmcgarry #define DBG_REPORTTIME	0x08
     67  1.1  gmcgarry #define DBG_FAIL	0x10
     68  1.1  gmcgarry #define DBG_WAIT	0x20
     69  1.1  gmcgarry #else
     70  1.1  gmcgarry #define DPRINTF(flag, str)	/* nothing */
     71  1.1  gmcgarry #endif
     72  1.1  gmcgarry 
     73  1.1  gmcgarry #define CEC_IOSIZE	8
     74  1.1  gmcgarry 
     75  1.1  gmcgarry struct cec_softc {
     76  1.1  gmcgarry 	struct device sc_dev;		/* generic device glue */
     77  1.1  gmcgarry 
     78  1.1  gmcgarry 	bus_space_tag_t sc_iot;
     79  1.1  gmcgarry 	bus_space_handle_t sc_ioh;
     80  1.1  gmcgarry 	isa_chipset_tag_t sc_ic;
     81  1.1  gmcgarry 	int sc_drq;
     82  1.1  gmcgarry 	void *sc_ih;
     83  1.1  gmcgarry 
     84  1.1  gmcgarry 	int sc_myaddr;			/* my address */
     85  1.1  gmcgarry 	struct gpib_softc *sc_gpib;
     86  1.1  gmcgarry 
     87  1.1  gmcgarry 	volatile int sc_flags;
     88  1.1  gmcgarry #define	CECF_IO		0x1
     89  1.1  gmcgarry #define	CECF_PPOLL	0x4
     90  1.1  gmcgarry #define	CECF_READ	0x8
     91  1.1  gmcgarry #define	CECF_TIMO	0x10
     92  1.1  gmcgarry #define CECF_USEDMA	0x20
     93  1.1  gmcgarry 	int sc_ppoll_slave;		/* XXX stash our ppoll address */
     94  1.6        ad 	callout_t sc_timeout_ch;
     95  1.1  gmcgarry };
     96  1.1  gmcgarry 
     97  1.1  gmcgarry int	cecprobe(struct device *, struct cfdata *, void *);
     98  1.1  gmcgarry void	cecattach(struct device *, struct device *, void *);
     99  1.1  gmcgarry 
    100  1.1  gmcgarry CFATTACH_DECL(cec, sizeof(struct cec_softc),
    101  1.1  gmcgarry 	cecprobe, cecattach, NULL, NULL);
    102  1.1  gmcgarry 
    103  1.3     perry void	cecreset(void *);
    104  1.1  gmcgarry int	cecpptest(void *, int);
    105  1.1  gmcgarry void	cecppwatch(void *, int);
    106  1.1  gmcgarry void	cecppclear(void *);
    107  1.1  gmcgarry void	cecxfer(void *, int, int, void *, int, int, int);
    108  1.1  gmcgarry void	cecgo(void *v);
    109  1.1  gmcgarry int	cecintr(void *);
    110  1.1  gmcgarry int	cecsendcmds(void *, void *, int);
    111  1.1  gmcgarry int	cecsenddata(void *, void *, int);
    112  1.1  gmcgarry int	cecrecvdata(void *, void *, int);
    113  1.1  gmcgarry int	cecgts(void *);
    114  1.1  gmcgarry int	cectc(void *, int);
    115  1.1  gmcgarry void	cecifc(void *);
    116  1.1  gmcgarry 
    117  1.1  gmcgarry static int	cecwait(struct cec_softc *, int, int);
    118  1.1  gmcgarry static void	cectimeout(void *v);
    119  1.1  gmcgarry static int	nec7210_setaddress(struct cec_softc *, int, int);
    120  1.1  gmcgarry static void	nec7210_init(struct cec_softc *);
    121  1.1  gmcgarry static void	nec7210_ifc(struct cec_softc *);
    122  1.1  gmcgarry 
    123  1.1  gmcgarry /*
    124  1.1  gmcgarry  * Our chipset structure.
    125  1.1  gmcgarry  */
    126  1.1  gmcgarry struct gpib_chipset_tag cec_ic = {
    127  1.1  gmcgarry 	cecreset,
    128  1.1  gmcgarry 	NULL,
    129  1.1  gmcgarry 	NULL,
    130  1.1  gmcgarry 	cecpptest,
    131  1.1  gmcgarry 	cecppwatch,
    132  1.1  gmcgarry 	cecppclear,
    133  1.1  gmcgarry 	cecxfer,
    134  1.1  gmcgarry 	cectc,
    135  1.1  gmcgarry 	cecgts,
    136  1.1  gmcgarry 	cecifc,
    137  1.1  gmcgarry 	cecsendcmds,
    138  1.1  gmcgarry 	cecsenddata,
    139  1.5      cube 	cecrecvdata,
    140  1.5      cube 	NULL,
    141  1.5      cube 	NULL
    142  1.1  gmcgarry };
    143  1.1  gmcgarry 
    144  1.1  gmcgarry int cecwtimeout = 0x10000;
    145  1.1  gmcgarry int cecdmathresh = 3;
    146  1.1  gmcgarry 
    147  1.1  gmcgarry int
    148  1.1  gmcgarry cecprobe(struct device *parent, struct cfdata *match, void *aux)
    149  1.1  gmcgarry {
    150  1.1  gmcgarry 	struct isa_attach_args *ia = aux;
    151  1.1  gmcgarry 	bus_space_tag_t iot = ia->ia_iot;
    152  1.1  gmcgarry 	bus_space_handle_t ioh;
    153  1.1  gmcgarry 
    154  1.1  gmcgarry 	DPRINTF(DBG_CONFIG, ("cecprobe: called\n"));
    155  1.1  gmcgarry 
    156  1.1  gmcgarry 	if (ia->ia_nio < 1)
    157  1.1  gmcgarry 		return (0);
    158  1.1  gmcgarry 	if (ia->ia_nirq < 1)
    159  1.1  gmcgarry 		return (0);
    160  1.1  gmcgarry 	if (ia->ia_ndrq < 1)
    161  1.1  gmcgarry 		return (0);
    162  1.1  gmcgarry 
    163  1.1  gmcgarry 	if (ISA_DIRECT_CONFIG(ia))
    164  1.1  gmcgarry 		return (0);
    165  1.1  gmcgarry 
    166  1.2  drochner 	if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
    167  1.1  gmcgarry 		return (0);
    168  1.1  gmcgarry 
    169  1.2  drochner 	if (ia->ia_ndrq > 0 && ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ)
    170  1.1  gmcgarry 		ia->ia_ndrq = 0;
    171  1.1  gmcgarry 
    172  1.1  gmcgarry 	if (bus_space_map(iot, ia->ia_io[0].ir_addr, CEC_IOSIZE, 0, &ioh))
    173  1.1  gmcgarry 		return (0);
    174  1.1  gmcgarry 
    175  1.1  gmcgarry 	/* XXX insert probe here */
    176  1.1  gmcgarry 
    177  1.1  gmcgarry 	ia->ia_io[0].ir_size = CEC_IOSIZE;
    178  1.1  gmcgarry 	ia->ia_niomem = 0;
    179  1.1  gmcgarry 
    180  1.1  gmcgarry 	bus_space_unmap(iot, ioh, CEC_IOSIZE);
    181  1.1  gmcgarry 
    182  1.1  gmcgarry 	return (1);
    183  1.1  gmcgarry }
    184  1.1  gmcgarry 
    185  1.1  gmcgarry void
    186  1.1  gmcgarry cecattach(struct device *parent, struct device *self, void *aux)
    187  1.1  gmcgarry {
    188  1.1  gmcgarry 	struct cec_softc *sc = (struct cec_softc *)self;
    189  1.1  gmcgarry 	struct isa_attach_args *ia = aux;
    190  1.1  gmcgarry 	struct gpibdev_attach_args ga;
    191  1.1  gmcgarry 	bus_size_t maxsize;
    192  1.1  gmcgarry 
    193  1.1  gmcgarry 	printf("\n");
    194  1.1  gmcgarry 
    195  1.1  gmcgarry 	DPRINTF(DBG_CONFIG, ("cecattach: called\n"));
    196  1.1  gmcgarry 
    197  1.1  gmcgarry 	sc->sc_iot = ia->ia_iot;
    198  1.1  gmcgarry 	sc->sc_ic = ia->ia_ic;
    199  1.1  gmcgarry 
    200  1.1  gmcgarry 	if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, CEC_IOSIZE,
    201  1.1  gmcgarry 	    0, &sc->sc_ioh) != 0) {
    202  1.1  gmcgarry 		printf("%s: unable to map I/O space\n", sc->sc_dev.dv_xname);
    203  1.1  gmcgarry 		return;
    204  1.1  gmcgarry 	}
    205  1.1  gmcgarry 
    206  1.1  gmcgarry 	if (ia->ia_ndrq > 0) {
    207  1.1  gmcgarry 		sc->sc_flags |= CECF_USEDMA;
    208  1.1  gmcgarry 		sc->sc_drq = ia->ia_drq[0].ir_drq;
    209  1.1  gmcgarry 
    210  1.1  gmcgarry 		(void) isa_drq_alloc(sc->sc_ic, sc->sc_drq);
    211  1.1  gmcgarry 		maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq);
    212  1.1  gmcgarry 		if (isa_dmamap_create(sc->sc_ic, sc->sc_drq,
    213  1.1  gmcgarry 		    maxsize, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW)) {
    214  1.1  gmcgarry 			printf("%s: unable to create map for drq %d\n",
    215  1.1  gmcgarry 			    sc->sc_dev.dv_xname, sc->sc_drq);
    216  1.1  gmcgarry 			sc->sc_flags &= ~CECF_USEDMA;
    217  1.1  gmcgarry 		}
    218  1.1  gmcgarry 	}
    219  1.1  gmcgarry 
    220  1.1  gmcgarry 	sc->sc_myaddr = 15;		/* XXX */
    221  1.1  gmcgarry 
    222  1.1  gmcgarry 	cecreset(sc);
    223  1.1  gmcgarry 	(void) nec7210_setaddress(sc, sc->sc_myaddr, -1);
    224  1.1  gmcgarry 
    225  1.1  gmcgarry 	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
    226  1.1  gmcgarry 	    IST_EDGE, IPL_BIO, cecintr, sc);
    227  1.1  gmcgarry 	if (sc->sc_ih == NULL) {
    228  1.1  gmcgarry 		printf("%s: couldn't establish interrupt\n",
    229  1.1  gmcgarry 		    sc->sc_dev.dv_xname);
    230  1.1  gmcgarry 		return;
    231  1.1  gmcgarry 	}
    232  1.1  gmcgarry 
    233  1.6        ad 	callout_init(&sc->sc_timeout_ch, 0);
    234  1.1  gmcgarry 
    235  1.1  gmcgarry 	/* attach MI GPIB bus */
    236  1.1  gmcgarry 	cec_ic.cookie = (void *)sc;
    237  1.1  gmcgarry 	ga.ga_ic = &cec_ic;
    238  1.1  gmcgarry 	ga.ga_address = sc->sc_myaddr;
    239  1.1  gmcgarry 	sc->sc_gpib =
    240  1.1  gmcgarry 	    (struct gpib_softc *)config_found(self, &ga, gpibdevprint);
    241  1.1  gmcgarry }
    242  1.1  gmcgarry 
    243  1.1  gmcgarry int
    244  1.1  gmcgarry cecintr(void *v)
    245  1.1  gmcgarry {
    246  1.1  gmcgarry 	struct cec_softc *sc = v;
    247  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    248  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    249  1.1  gmcgarry 	u_int8_t stat1, stat2;
    250  1.1  gmcgarry 
    251  1.1  gmcgarry 	stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
    252  1.1  gmcgarry 	stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
    253  1.1  gmcgarry 
    254  1.1  gmcgarry 	DPRINTF(DBG_INTR, ("cecintr: sc=%p stat1=0x%x stat2=0x%x\n",
    255  1.1  gmcgarry 	    sc, stat1, stat2));
    256  1.1  gmcgarry 
    257  1.1  gmcgarry 	if (sc->sc_flags & CECF_IO) {
    258  1.1  gmcgarry 
    259  1.1  gmcgarry 		if (sc->sc_flags & CECF_TIMO)
    260  1.1  gmcgarry 			callout_stop(&sc->sc_timeout_ch);
    261  1.1  gmcgarry 
    262  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
    263  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
    264  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
    265  1.1  gmcgarry 		sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
    266  1.1  gmcgarry 		if (sc->sc_flags & CECF_USEDMA)
    267  1.1  gmcgarry 			isa_dmadone(sc->sc_ic, sc->sc_drq);
    268  1.1  gmcgarry 		gpibintr(sc->sc_gpib);
    269  1.1  gmcgarry 
    270  1.1  gmcgarry 	} else if (sc->sc_flags & CECF_PPOLL) {
    271  1.1  gmcgarry 
    272  1.1  gmcgarry 		if (cecpptest(sc, sc->sc_ppoll_slave)) {
    273  1.1  gmcgarry 			sc->sc_flags &= ~CECF_PPOLL;
    274  1.1  gmcgarry 			bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
    275  1.1  gmcgarry 			gpibintr(sc->sc_gpib);
    276  1.1  gmcgarry 		}
    277  1.1  gmcgarry 
    278  1.1  gmcgarry 	}
    279  1.1  gmcgarry 	return (1);
    280  1.1  gmcgarry }
    281  1.1  gmcgarry 
    282  1.1  gmcgarry void
    283  1.1  gmcgarry cecreset(void *v)
    284  1.1  gmcgarry {
    285  1.1  gmcgarry 	struct cec_softc *sc = v;
    286  1.1  gmcgarry 	u_int8_t cmd;
    287  1.1  gmcgarry 
    288  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cecreset: sc=%p\n", sc));
    289  1.1  gmcgarry 
    290  1.1  gmcgarry 	nec7210_init(sc);
    291  1.1  gmcgarry 	nec7210_ifc(sc);
    292  1.1  gmcgarry 	/* we're now the system controller */
    293  1.1  gmcgarry 
    294  1.1  gmcgarry 	/* XXX should be pushed higher */
    295  1.1  gmcgarry 
    296  1.1  gmcgarry 	/* universal device clear */
    297  1.1  gmcgarry 	cmd = GPIBCMD_DCL;
    298  1.1  gmcgarry 	(void) cecsendcmds(sc, &cmd, 1);
    299  1.1  gmcgarry 	/* delay for devices to clear */
    300  1.1  gmcgarry 	DELAY(100000);
    301  1.1  gmcgarry }
    302  1.1  gmcgarry 
    303  1.1  gmcgarry int
    304  1.1  gmcgarry cecsendcmds(void *v, void *ptr, int origcnt)
    305  1.1  gmcgarry {
    306  1.1  gmcgarry 	struct cec_softc *sc = v;
    307  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    308  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    309  1.1  gmcgarry 	int cnt = origcnt;
    310  1.1  gmcgarry 	u_int8_t *addr = ptr;
    311  1.1  gmcgarry 
    312  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cecsendcmds: sc=%p, ptr=%p cnt=%d\n",
    313  1.1  gmcgarry 	    sc, ptr, origcnt));
    314  1.1  gmcgarry 
    315  1.1  gmcgarry 	while (--cnt >= 0) {
    316  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
    317  1.1  gmcgarry 		if (cecwait(sc, 0, ISR2_CO))
    318  1.1  gmcgarry 			return (origcnt - cnt - 1);
    319  1.1  gmcgarry 	}
    320  1.1  gmcgarry 	return (origcnt);
    321  1.1  gmcgarry }
    322  1.1  gmcgarry 
    323  1.1  gmcgarry 
    324  1.1  gmcgarry int
    325  1.1  gmcgarry cecrecvdata(void *v, void *ptr, int origcnt)
    326  1.1  gmcgarry {
    327  1.1  gmcgarry 	struct cec_softc *sc = v;
    328  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    329  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    330  1.1  gmcgarry 	int cnt = origcnt;
    331  1.1  gmcgarry 	u_int8_t *addr = ptr;
    332  1.1  gmcgarry 
    333  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cecrecvdata: sc=%p, ptr=%p cnt=%d\n",
    334  1.1  gmcgarry 	    sc, ptr, origcnt));
    335  1.1  gmcgarry 
    336  1.1  gmcgarry 	/* XXX holdoff on end */
    337  1.1  gmcgarry 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_AUXMR, AUXCMD_RHDF);
    338  1.1  gmcgarry 
    339  1.1  gmcgarry 	if (cnt) {
    340  1.1  gmcgarry 		while (--cnt >= 0) {
    341  1.1  gmcgarry 			if (cecwait(sc, ISR1_DI, 0))
    342  1.1  gmcgarry 				return (origcnt - cnt - 1);
    343  1.1  gmcgarry 			*addr++ = bus_space_read_1(iot, ioh, NEC7210_DIR);
    344  1.1  gmcgarry 		}
    345  1.1  gmcgarry 	}
    346  1.1  gmcgarry 	return (origcnt);
    347  1.1  gmcgarry }
    348  1.1  gmcgarry 
    349  1.1  gmcgarry int
    350  1.1  gmcgarry cecsenddata(void *v, void *ptr, int origcnt)
    351  1.1  gmcgarry {
    352  1.1  gmcgarry 	struct cec_softc *sc = v;
    353  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    354  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    355  1.1  gmcgarry 	int cnt = origcnt;
    356  1.1  gmcgarry 	u_int8_t *addr = ptr;
    357  1.1  gmcgarry 
    358  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cecdsenddata: sc=%p, ptr=%p cnt=%d\n",
    359  1.1  gmcgarry 	    sc, ptr, origcnt));
    360  1.1  gmcgarry 
    361  1.1  gmcgarry 	if (cnt) {
    362  1.1  gmcgarry 		while (--cnt > 0) {
    363  1.1  gmcgarry 			bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr++);
    364  1.1  gmcgarry 			if (cecwait(sc, ISR1_DO, 0))
    365  1.1  gmcgarry 				return (origcnt - cnt - 1);
    366  1.1  gmcgarry 		}
    367  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
    368  1.3     perry 		bus_space_write_1(iot, ioh, NEC7210_CDOR, *addr);
    369  1.1  gmcgarry 		(void) cecwait(sc, ISR1_DO, 0);
    370  1.1  gmcgarry 	}
    371  1.1  gmcgarry 	return (origcnt);
    372  1.1  gmcgarry }
    373  1.1  gmcgarry 
    374  1.1  gmcgarry int
    375  1.1  gmcgarry cectc(void *v, int sync)
    376  1.1  gmcgarry {
    377  1.1  gmcgarry 	struct cec_softc *sc = v;
    378  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    379  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    380  1.1  gmcgarry 	u_int8_t adsr;
    381  1.1  gmcgarry 	int timo = cecwtimeout;
    382  1.1  gmcgarry 
    383  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cectc: sc=%p, sync=%d\n", sc, sync));
    384  1.1  gmcgarry 
    385  1.1  gmcgarry 	adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
    386  1.1  gmcgarry #if 0
    387  1.1  gmcgarry 	if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_CIC) {
    388  1.1  gmcgarry 		DPRINTF(0xff, ("cectc: already CIC\n"));
    389  1.1  gmcgarry 		return (0);
    390  1.1  gmcgarry 	}
    391  1.1  gmcgarry #endif
    392  1.1  gmcgarry 
    393  1.1  gmcgarry 	if (sync) {
    394  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_RHDF);
    395  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCS);
    396  1.1  gmcgarry 	} else {
    397  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
    398  1.1  gmcgarry 	}
    399  1.1  gmcgarry 
    400  1.1  gmcgarry 	/* wait until ATN is asserted */
    401  1.1  gmcgarry 	for (;;) {
    402  1.1  gmcgarry 		adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
    403  1.1  gmcgarry 		if (--timo == 0) {
    404  1.1  gmcgarry 			DPRINTF(DBG_REPORTTIME, ("cectc: timeout\n"));
    405  1.1  gmcgarry 			return (1);
    406  1.1  gmcgarry 		}
    407  1.1  gmcgarry 		if ((adsr & ADSR_NATN) == 0)
    408  1.1  gmcgarry 			break;
    409  1.1  gmcgarry 		DELAY(1);
    410  1.1  gmcgarry 	}
    411  1.1  gmcgarry 
    412  1.1  gmcgarry 	return (0);
    413  1.1  gmcgarry }
    414  1.1  gmcgarry 
    415  1.1  gmcgarry int
    416  1.1  gmcgarry cecgts(void *v)
    417  1.1  gmcgarry {
    418  1.1  gmcgarry 	struct cec_softc *sc = v;
    419  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    420  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    421  1.1  gmcgarry 	u_int8_t adsr;
    422  1.1  gmcgarry 	int timo = cecwtimeout;
    423  1.1  gmcgarry 
    424  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cecgts: sc=%p\n", sc));
    425  1.1  gmcgarry 
    426  1.1  gmcgarry 	adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
    427  1.1  gmcgarry #if 0
    428  1.1  gmcgarry 	if ((adsr & (ADSR_CIC | ADSR_NATN)) == ADSR_NATN) {
    429  1.1  gmcgarry 		DPRINTF(0xff, ("cecgts: already standby\n"));
    430  1.1  gmcgarry 		return (0);
    431  1.1  gmcgarry 	}
    432  1.1  gmcgarry #endif
    433  1.1  gmcgarry 
    434  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_GTS);
    435  1.1  gmcgarry 
    436  1.1  gmcgarry 	/* wait unit ATN is released */
    437  1.1  gmcgarry 	for (;;) {
    438  1.1  gmcgarry 		adsr = bus_space_read_1(iot, ioh, NEC7210_ADSR);
    439  1.1  gmcgarry 		if (--timo == 0) {
    440  1.1  gmcgarry 			DPRINTF(DBG_REPORTTIME, ("cecgts: timeout\n"));
    441  1.1  gmcgarry 			return (1);
    442  1.1  gmcgarry 		}
    443  1.1  gmcgarry 		if ((adsr & ADSR_NATN) == ADSR_NATN)
    444  1.1  gmcgarry 			break;
    445  1.1  gmcgarry 		DELAY(1);
    446  1.1  gmcgarry 	}
    447  1.1  gmcgarry 
    448  1.1  gmcgarry 	return (0);
    449  1.1  gmcgarry }
    450  1.1  gmcgarry 
    451  1.1  gmcgarry int
    452  1.1  gmcgarry cecpptest(void *v, int slave)
    453  1.1  gmcgarry {
    454  1.1  gmcgarry 	struct cec_softc *sc = v;
    455  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    456  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    457  1.1  gmcgarry 	int ppoll;
    458  1.1  gmcgarry 
    459  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cecpptest: sc=%p slave=%d\n", sc, slave));
    460  1.1  gmcgarry 
    461  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
    462  1.1  gmcgarry 	DELAY(25);
    463  1.1  gmcgarry 	ppoll = bus_space_read_1(iot, ioh, NEC7210_CPTR);
    464  1.1  gmcgarry 	DPRINTF(0xff, ("cecpptest: ppoll=%x\n", ppoll));
    465  1.1  gmcgarry 	return ((ppoll & (0x80 >> slave)) != 0);
    466  1.1  gmcgarry }
    467  1.1  gmcgarry 
    468  1.1  gmcgarry void
    469  1.1  gmcgarry cecppwatch(void *v, int slave)
    470  1.1  gmcgarry {
    471  1.1  gmcgarry 	struct cec_softc *sc = v;
    472  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    473  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    474  1.1  gmcgarry 
    475  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cecppwatch: sc=%p\n", sc));
    476  1.1  gmcgarry 
    477  1.1  gmcgarry 	sc->sc_flags |= CECF_PPOLL;
    478  1.1  gmcgarry 	sc->sc_ppoll_slave = slave;
    479  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
    480  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_EPP);
    481  1.1  gmcgarry }
    482  1.1  gmcgarry 
    483  1.1  gmcgarry void
    484  1.1  gmcgarry cecppclear(void *v)
    485  1.1  gmcgarry {
    486  1.1  gmcgarry 	struct cec_softc *sc = v;
    487  1.1  gmcgarry 
    488  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cecppclear: sc=%p\n", sc));
    489  1.1  gmcgarry 
    490  1.1  gmcgarry 	sc->sc_flags &= ~CECF_PPOLL;
    491  1.1  gmcgarry 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, NEC7210_IMR2, 0);
    492  1.1  gmcgarry }
    493  1.1  gmcgarry 
    494  1.1  gmcgarry void
    495  1.1  gmcgarry cecxfer(void *v, int slave, int sec, void *buf, int count, int dir, int timo)
    496  1.1  gmcgarry {
    497  1.1  gmcgarry 	struct cec_softc *sc = v;
    498  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    499  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    500  1.1  gmcgarry 
    501  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW,
    502  1.1  gmcgarry 	    ("cecxfer: slave=%d sec=%d buf=%p count=%d dir=%x timo=%d\n",
    503  1.1  gmcgarry 	    slave, sec, buf, count, dir, timo));
    504  1.1  gmcgarry 
    505  1.1  gmcgarry 	sc->sc_flags |= CECF_IO;
    506  1.1  gmcgarry 	if (dir == GPIB_READ)
    507  1.1  gmcgarry 		sc->sc_flags |= CECF_READ;
    508  1.1  gmcgarry 	if (timo) {
    509  1.1  gmcgarry 		sc->sc_flags |= CECF_TIMO;
    510  1.1  gmcgarry 		callout_reset(&sc->sc_timeout_ch, 5*hz, cectimeout, sc);
    511  1.1  gmcgarry 	}
    512  1.1  gmcgarry 
    513  1.1  gmcgarry 	if (sc->sc_flags & CECF_READ) {
    514  1.1  gmcgarry 		DPRINTF(DBG_FOLLOW, ("cecxfer: DMA read request\n"));
    515  1.1  gmcgarry 		if ((sc->sc_flags & CECF_USEDMA) != 0) {
    516  1.1  gmcgarry 			isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count, NULL,
    517  1.1  gmcgarry 			    DMAMODE_READ | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
    518  1.1  gmcgarry 			bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAI);
    519  1.1  gmcgarry 			bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
    520  1.1  gmcgarry 			// XXX (void) cecrecv(sc, slave, sec, NULL, 0);
    521  1.1  gmcgarry 			(void) gpibrecv(&cec_ic, slave, sec, NULL, 0);
    522  1.1  gmcgarry 		} else {
    523  1.1  gmcgarry 			/* XXX this doesn't work */
    524  1.1  gmcgarry 			DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
    525  1.1  gmcgarry 			bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_END);
    526  1.1  gmcgarry 			// XXX (void) cecrecv(sc, slave, sec, buf, count);
    527  1.1  gmcgarry 			(void) gpibrecv(&cec_ic, slave, sec, buf, count);
    528  1.1  gmcgarry 			bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
    529  1.1  gmcgarry 		}
    530  1.1  gmcgarry 	} else {
    531  1.1  gmcgarry 		DPRINTF(DBG_FOLLOW, ("cecxfer: DMA write request\n"));
    532  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
    533  1.1  gmcgarry 		if (count < cecdmathresh ||
    534  1.1  gmcgarry 		    (sc->sc_flags & CECF_USEDMA) == 0) {
    535  1.1  gmcgarry 			DPRINTF(DBG_FOLLOW, ("cecxfer: polling instead\n"));
    536  1.1  gmcgarry 			// XXX (void) cecsend(sc, slave, sec, buf, count);
    537  1.1  gmcgarry 			(void) gpibsend(&cec_ic, slave, sec, buf, count);
    538  1.1  gmcgarry 			bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_CO);
    539  1.1  gmcgarry 			return;
    540  1.1  gmcgarry 		}
    541  1.1  gmcgarry 		/* we send the last byte with EOI set */
    542  1.1  gmcgarry 		isa_dmastart(sc->sc_ic, sc->sc_drq, buf, count-1, NULL,
    543  1.1  gmcgarry 		    DMAMODE_WRITE | DMAMODE_DEMAND, BUS_DMA_NOWAIT);
    544  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_IMR2, IMR2_DMAO);
    545  1.1  gmcgarry 		// XXX (void) cecsend(sc, slave, sec, NULL, 0);
    546  1.1  gmcgarry 		(void) gpibsend(&cec_ic, slave, sec, NULL, 0);
    547  1.1  gmcgarry 		while (!isa_dmafinished(sc->sc_ic, sc->sc_drq))
    548  1.1  gmcgarry 			DELAY(1);
    549  1.1  gmcgarry 		(void) cecwait(sc, ISR1_DO, 0);
    550  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SEOI);
    551  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_CDOR, *(char *)buf+count);
    552  1.1  gmcgarry 		/* generate interrupt */
    553  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_IMR1, IMR1_DO);
    554  1.1  gmcgarry 	}
    555  1.1  gmcgarry }
    556  1.1  gmcgarry 
    557  1.1  gmcgarry void
    558  1.1  gmcgarry cecifc(void *v)
    559  1.1  gmcgarry {
    560  1.1  gmcgarry 	struct cec_softc *sc = v;
    561  1.1  gmcgarry 
    562  1.1  gmcgarry 	nec7210_ifc(sc);
    563  1.1  gmcgarry }
    564  1.1  gmcgarry 
    565  1.1  gmcgarry static int
    566  1.1  gmcgarry nec7210_setaddress(struct cec_softc *sc, int pri, int sec)
    567  1.1  gmcgarry {
    568  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    569  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    570  1.1  gmcgarry 	u_int8_t admr;
    571  1.1  gmcgarry 
    572  1.1  gmcgarry 	/* assign our primary address */
    573  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_ADDR, (pri & ADDR_MASK));
    574  1.1  gmcgarry 
    575  1.1  gmcgarry 	admr = ADMR_TRM0 | ADMR_TRM1;
    576  1.1  gmcgarry 
    577  1.1  gmcgarry 	/* assign our secondary address */
    578  1.1  gmcgarry 	if (sec != -1) {
    579  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_ADDR,
    580  1.1  gmcgarry 		    (ADDR_ARS | (sec & ADDR_MASK)));
    581  1.1  gmcgarry 		admr |= ADMR_ADM1;
    582  1.1  gmcgarry 	} else {
    583  1.1  gmcgarry 		/* disable secondary address */
    584  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_ADDR,
    585  1.1  gmcgarry 		    (ADDR_ARS | ADDR_DT | ADDR_DL));
    586  1.1  gmcgarry 		admr |= ADMR_ADM0;
    587  1.1  gmcgarry 	}
    588  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_ADMR, admr);
    589  1.1  gmcgarry 
    590  1.1  gmcgarry 	return (0);
    591  1.1  gmcgarry }
    592  1.1  gmcgarry 
    593  1.1  gmcgarry static void
    594  1.1  gmcgarry nec7210_init(struct cec_softc *sc)
    595  1.1  gmcgarry {
    596  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    597  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    598  1.1  gmcgarry 
    599  1.1  gmcgarry 	/* reset chip */
    600  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CRST);
    601  1.1  gmcgarry 
    602  1.1  gmcgarry 	/* clear interrupts */
    603  1.1  gmcgarry 	bus_space_read_1(iot, ioh, NEC7210_CPTR);
    604  1.1  gmcgarry 	bus_space_read_1(iot, ioh, NEC7210_ISR1);
    605  1.1  gmcgarry 	bus_space_read_1(iot, ioh, NEC7210_ISR2);
    606  1.1  gmcgarry 
    607  1.1  gmcgarry 	/* initialise interrupts */
    608  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
    609  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_IMR2, 0);
    610  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_SPMR, 0);
    611  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_EOSR, 0);
    612  1.1  gmcgarry 
    613  1.1  gmcgarry 	/* set internal clock to 8MHz */
    614  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_ICR | 0x8));
    615  1.1  gmcgarry 	/* parallel poll unconfigure */
    616  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_PPOLL | PPOLL_PPU));
    617  1.1  gmcgarry 
    618  1.1  gmcgarry 	/* assign our address */
    619  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_ADDR, 0);
    620  1.1  gmcgarry 	/* disable secondary address */
    621  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_ADDR,
    622  1.1  gmcgarry 	    (ADDR_ARS | ADDR_DT | ADDR_DL));
    623  1.1  gmcgarry 
    624  1.1  gmcgarry 	/* setup transceivers */
    625  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_ADMR,
    626  1.1  gmcgarry 	    (ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1));
    627  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR,
    628  1.1  gmcgarry 	    (AUXMR_REGA | AUX_A_HSNORM));
    629  1.1  gmcgarry 
    630  1.1  gmcgarry 	/* set INT pin to active high */
    631  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGB);
    632  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXMR_REGE);
    633  1.1  gmcgarry 
    634  1.1  gmcgarry 	/* holdoff on end condition */
    635  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_REGA | AUX_A_HLDE));
    636  1.1  gmcgarry 
    637  1.1  gmcgarry 	/* reconnect to bus */
    638  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, (AUXMR_CMD | AUXCMD_IEPON));
    639  1.1  gmcgarry }
    640  1.1  gmcgarry 
    641  1.1  gmcgarry /*
    642  1.1  gmcgarry  * Place all devices on the bus into quiescient state ready for
    643  1.1  gmcgarry  * remote programming.
    644  1.1  gmcgarry  * Obviously, we're the system controller upon exit.
    645  1.1  gmcgarry  */
    646  1.1  gmcgarry void
    647  1.1  gmcgarry nec7210_ifc(struct cec_softc *sc)
    648  1.1  gmcgarry {
    649  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    650  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    651  1.1  gmcgarry 
    652  1.1  gmcgarry /*XXX*/	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
    653  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CREN);
    654  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SIFC);
    655  1.1  gmcgarry 	/* wait for devices to enter quiescient state */
    656  1.1  gmcgarry 	DELAY(100);
    657  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_CIFC);
    658  1.1  gmcgarry 	bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_SREN);
    659  1.1  gmcgarry }
    660  1.1  gmcgarry 
    661  1.1  gmcgarry static int
    662  1.1  gmcgarry cecwait(struct cec_softc *sc, int x1, int x2)
    663  1.1  gmcgarry {
    664  1.1  gmcgarry 	int timo = cecwtimeout;
    665  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    666  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    667  1.1  gmcgarry 	u_int8_t stat1, stat2;
    668  1.1  gmcgarry 
    669  1.1  gmcgarry 	DPRINTF(DBG_WAIT, ("cecwait: sc=%p, x1=0x%x x2=0x%x\n", sc, x1, x2));
    670  1.1  gmcgarry 
    671  1.1  gmcgarry 	for (;;) {
    672  1.1  gmcgarry 		stat1 = bus_space_read_1(iot, ioh, NEC7210_ISR1);
    673  1.1  gmcgarry 		stat2 = bus_space_read_1(iot, ioh, NEC7210_ISR2);
    674  1.1  gmcgarry #if 0
    675  1.1  gmcgarry 		if ((stat1 & ISR1_ERR)) {
    676  1.1  gmcgarry 			DPRINTF(DBG_WAIT, ("cecwait: got ERR\n"));
    677  1.1  gmcgarry 			return (1);
    678  1.1  gmcgarry 		}
    679  1.1  gmcgarry #endif
    680  1.1  gmcgarry 		if (--timo == 0) {
    681  1.1  gmcgarry 			DPRINTF(DBG_REPORTTIME,
    682  1.1  gmcgarry 			    ("cecwait: timeout x1=0x%x x2=0x%x\n", x1, x2));
    683  1.1  gmcgarry 			return (1);
    684  1.1  gmcgarry 		}
    685  1.1  gmcgarry 		if ((stat1 & x1) || (stat2 & x2))
    686  1.1  gmcgarry 			break;
    687  1.1  gmcgarry 		DELAY(1);
    688  1.1  gmcgarry 	}
    689  1.1  gmcgarry 	return (0);
    690  1.1  gmcgarry }
    691  1.1  gmcgarry 
    692  1.1  gmcgarry static void
    693  1.1  gmcgarry cectimeout(void *v)
    694  1.1  gmcgarry {
    695  1.1  gmcgarry 	struct cec_softc *sc = v;
    696  1.1  gmcgarry 	bus_space_tag_t iot = sc->sc_iot;
    697  1.1  gmcgarry 	bus_space_handle_t ioh = sc->sc_ioh;
    698  1.1  gmcgarry 	int s;
    699  1.1  gmcgarry 
    700  1.1  gmcgarry 	DPRINTF(DBG_FOLLOW, ("cectimeout: sc=%p\n", sc));
    701  1.1  gmcgarry 
    702  1.1  gmcgarry 	s = splbio();
    703  1.1  gmcgarry 	if (sc->sc_flags & CECF_IO) {
    704  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_IMR1, 0);
    705  1.1  gmcgarry 		bus_space_write_2(iot, ioh, NEC7210_IMR2, 0);
    706  1.1  gmcgarry 		bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA);
    707  1.1  gmcgarry 		sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO);
    708  1.1  gmcgarry 		isa_dmaabort(sc->sc_ic, sc->sc_drq);
    709  1.1  gmcgarry 		printf("%s: %s timeout\n", sc->sc_dev.dv_xname,
    710  1.1  gmcgarry 		    sc->sc_flags & CECF_READ ? "read" : "write");
    711  1.1  gmcgarry 		gpibintr(sc->sc_gpib);
    712  1.1  gmcgarry 	}
    713  1.1  gmcgarry 	splx(s);
    714  1.1  gmcgarry }
    715