Home | History | Annotate | Line # | Download | only in dev
nhpib.c revision 1.15
      1  1.15    scottr /*	$NetBSD: nhpib.c,v 1.15 1997/03/31 07:37:30 scottr Exp $	*/
      2   1.5       cgd 
      3   1.1       cgd /*
      4  1.14   thorpej  * Copyright (c) 1996, 1997 Jason R. Thorpe.  All rights reserved.
      5   1.4   mycroft  * Copyright (c) 1982, 1990, 1993
      6   1.4   mycroft  *	The Regents of the University of California.  All rights reserved.
      7   1.1       cgd  *
      8   1.1       cgd  * Redistribution and use in source and binary forms, with or without
      9   1.1       cgd  * modification, are permitted provided that the following conditions
     10   1.1       cgd  * are met:
     11   1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     12   1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     13   1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     14   1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     15   1.1       cgd  *    documentation and/or other materials provided with the distribution.
     16   1.1       cgd  * 3. All advertising materials mentioning features or use of this software
     17   1.1       cgd  *    must display the following acknowledgement:
     18   1.1       cgd  *	This product includes software developed by the University of
     19   1.1       cgd  *	California, Berkeley and its contributors.
     20   1.1       cgd  * 4. Neither the name of the University nor the names of its contributors
     21   1.1       cgd  *    may be used to endorse or promote products derived from this software
     22   1.1       cgd  *    without specific prior written permission.
     23   1.1       cgd  *
     24   1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25   1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26   1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27   1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28   1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29   1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30   1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31   1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32   1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33   1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34   1.1       cgd  * SUCH DAMAGE.
     35   1.1       cgd  *
     36   1.5       cgd  *	@(#)nhpib.c	8.2 (Berkeley) 1/12/94
     37   1.1       cgd  */
     38   1.1       cgd 
     39   1.1       cgd /*
     40   1.1       cgd  * Internal/98624 HPIB driver
     41   1.1       cgd  */
     42   1.1       cgd 
     43   1.4   mycroft #include <sys/param.h>
     44   1.4   mycroft #include <sys/systm.h>
     45   1.6   mycroft #include <sys/kernel.h>
     46   1.4   mycroft #include <sys/buf.h>
     47  1.14   thorpej #include <sys/device.h>
     48  1.14   thorpej 
     49  1.14   thorpej #include <machine/autoconf.h>
     50  1.15    scottr #include <machine/psl.h>
     51  1.14   thorpej 
     52  1.14   thorpej #include <hp300/hp300/isr.h>
     53  1.14   thorpej 
     54  1.14   thorpej #include <hp300/dev/dioreg.h>
     55  1.14   thorpej #include <hp300/dev/diovar.h>
     56  1.14   thorpej #include <hp300/dev/diodevs.h>
     57  1.14   thorpej 
     58  1.14   thorpej #include <hp300/dev/dmavar.h>
     59   1.4   mycroft 
     60   1.4   mycroft #include <hp300/dev/nhpibreg.h>
     61   1.4   mycroft #include <hp300/dev/hpibvar.h>
     62   1.1       cgd 
     63   1.6   mycroft /*
     64   1.6   mycroft  * ODD parity table for listen and talk addresses and secondary commands.
     65   1.6   mycroft  * The TI9914A doesn't produce the parity bit.
     66   1.6   mycroft  */
     67   1.6   mycroft static u_char listnr_par[] = {
     68   1.6   mycroft 	0040,0241,0242,0043,0244,0045,0046,0247,
     69   1.6   mycroft 	0250,0051,0052,0253,0054,0255,0256,0057,
     70   1.6   mycroft 	0260,0061,0062,0263,0064,0265,0266,0067,
     71   1.6   mycroft 	0070,0271,0272,0073,0274,0075,0076,0277,
     72   1.6   mycroft };
     73   1.6   mycroft static u_char talker_par[] = {
     74   1.6   mycroft 	0100,0301,0302,0103,0304,0105,0106,0307,
     75   1.6   mycroft 	0310,0111,0112,0313,0114,0315,0316,0117,
     76   1.6   mycroft 	0320,0121,0122,0323,0124,0325,0326,0127,
     77   1.6   mycroft 	0130,0331,0332,0133,0334,0135,0136,0337,
     78   1.6   mycroft };
     79   1.6   mycroft static u_char sec_par[] = {
     80   1.6   mycroft 	0340,0141,0142,0343,0144,0345,0346,0147,
     81   1.6   mycroft 	0150,0351,0352,0153,0354,0155,0156,0357,
     82   1.6   mycroft 	0160,0361,0362,0163,0364,0165,0166,0367,
     83   1.6   mycroft 	0370,0171,0172,0373,0174,0375,0376,0177
     84   1.6   mycroft };
     85   1.6   mycroft 
     86  1.14   thorpej void	nhpibifc __P((struct nhpibdevice *));
     87  1.14   thorpej void	nhpibreadtimo __P((void *));
     88  1.14   thorpej int	nhpibwait __P((struct nhpibdevice *, int));
     89  1.14   thorpej 
     90  1.14   thorpej void	nhpibreset __P((struct hpibbus_softc *));
     91  1.14   thorpej int	nhpibsend __P((struct hpibbus_softc *, int, int, void *, int));
     92  1.14   thorpej int	nhpibrecv __P((struct hpibbus_softc *, int, int, void *, int));
     93  1.14   thorpej int	nhpibppoll __P((struct hpibbus_softc *));
     94   1.7   thorpej void	nhpibppwatch __P((void *));
     95  1.14   thorpej void	nhpibgo __P((struct hpibbus_softc *, int, int, void *, int, int, int));
     96  1.14   thorpej void	nhpibdone __P((struct hpibbus_softc *));
     97   1.9   thorpej int	nhpibintr __P((void *));
     98   1.7   thorpej 
     99   1.7   thorpej /*
    100   1.7   thorpej  * Our controller ops structure.
    101   1.7   thorpej  */
    102   1.7   thorpej struct	hpib_controller nhpib_controller = {
    103   1.7   thorpej 	nhpibreset,
    104   1.7   thorpej 	nhpibsend,
    105   1.7   thorpej 	nhpibrecv,
    106   1.7   thorpej 	nhpibppoll,
    107   1.7   thorpej 	nhpibppwatch,
    108   1.7   thorpej 	nhpibgo,
    109   1.7   thorpej 	nhpibdone,
    110   1.7   thorpej 	nhpibintr
    111   1.7   thorpej };
    112   1.7   thorpej 
    113  1.14   thorpej struct nhpib_softc {
    114  1.14   thorpej 	struct device sc_dev;		/* generic device glue */
    115  1.14   thorpej 	struct nhpibdevice *sc_regs;	/* device registers */
    116  1.14   thorpej 	struct hpibbus_softc *sc_hpibbus; /* XXX */
    117  1.14   thorpej };
    118  1.14   thorpej 
    119  1.14   thorpej int	nhpibmatch __P((struct device *, struct cfdata *, void *));
    120  1.14   thorpej void	nhpibattach __P((struct device *, struct device *, void *));
    121  1.14   thorpej 
    122  1.14   thorpej struct cfattach nhpib_ca = {
    123  1.14   thorpej 	sizeof(struct nhpib_softc), nhpibmatch, nhpibattach
    124  1.14   thorpej };
    125  1.14   thorpej 
    126  1.14   thorpej struct cfdriver nhpib_cd = {
    127  1.14   thorpej 	NULL, "nhpib", DV_DULL
    128  1.14   thorpej };
    129  1.14   thorpej 
    130   1.7   thorpej int
    131  1.14   thorpej nhpibmatch(parent, match, aux)
    132  1.14   thorpej 	struct device *parent;
    133  1.14   thorpej 	struct cfdata *match;
    134  1.14   thorpej 	void *aux;
    135   1.1       cgd {
    136  1.14   thorpej 	struct dio_attach_args *da = aux;
    137   1.1       cgd 
    138  1.14   thorpej 	/*
    139  1.14   thorpej 	 * Internal HP-IB doesn't always return a device ID,
    140  1.14   thorpej 	 * so we rely on the sysflags.
    141  1.14   thorpej 	 */
    142  1.14   thorpej 	if (da->da_scode == 7 && internalhpib)
    143   1.8   thorpej 		return (1);
    144  1.14   thorpej 
    145  1.14   thorpej 	if (da->da_id == DIO_DEVICE_ID_NHPIB)
    146   1.8   thorpej 		return (1);
    147   1.8   thorpej 
    148  1.14   thorpej 	return (0);
    149   1.8   thorpej }
    150   1.8   thorpej 
    151   1.8   thorpej void
    152  1.14   thorpej nhpibattach(parent, self, aux)
    153  1.14   thorpej 	struct device *parent, *self;
    154  1.14   thorpej 	void *aux;
    155  1.14   thorpej {
    156  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)self;
    157  1.14   thorpej 	struct dio_attach_args *da = aux;
    158  1.14   thorpej 	struct hpibdev_attach_args ha;
    159  1.14   thorpej 	const char *desc;
    160  1.14   thorpej 	int ipl, type = HPIBA;
    161  1.14   thorpej 
    162  1.14   thorpej 	sc->sc_regs = (struct nhpibdevice *)iomap(dio_scodetopa(da->da_scode),
    163  1.14   thorpej 	    da->da_size);
    164  1.14   thorpej 	if (sc->sc_regs == NULL) {
    165  1.14   thorpej 		printf("\n%s: can't map registers\n", self->dv_xname);
    166  1.14   thorpej 		return;
    167  1.14   thorpej 	}
    168   1.8   thorpej 
    169  1.14   thorpej 	ipl = DIO_IPL(sc->sc_regs);
    170   1.8   thorpej 
    171  1.14   thorpej 	if (da->da_scode == 7 && internalhpib)
    172  1.14   thorpej 		desc = DIO_DEVICE_DESC_IHPIB;
    173  1.14   thorpej 	else if (da->da_id == DIO_DEVICE_ID_NHPIB) {
    174  1.14   thorpej 		type = HPIBB;
    175  1.14   thorpej 		desc = DIO_DEVICE_DESC_NHPIB;
    176  1.14   thorpej 	} else
    177  1.14   thorpej 		desc = "unknown HP-IB!";
    178  1.14   thorpej 
    179  1.14   thorpej 	printf(" ipl %d: %s\n", ipl, desc);
    180  1.14   thorpej 
    181  1.14   thorpej 	/* Establish the interrupt handler. */
    182  1.14   thorpej 	(void) isrlink(nhpibintr, sc, ipl, ISRPRI_BIO);
    183  1.14   thorpej 	dmacomputeipl();
    184  1.14   thorpej 
    185  1.14   thorpej 	ha.ha_ops = &nhpib_controller;
    186  1.14   thorpej 	ha.ha_type = type;			/* XXX */
    187  1.14   thorpej 	ha.ha_ba = (type == HPIBA) ? HPIBA_BA :
    188  1.14   thorpej 	    (sc->sc_regs->hpib_csa & CSA_BA);
    189  1.14   thorpej 	ha.ha_softcpp = &sc->sc_hpibbus;	/* XXX */
    190  1.14   thorpej 	(void)config_found(self, &ha, hpibdevprint);
    191   1.1       cgd }
    192   1.1       cgd 
    193   1.7   thorpej void
    194  1.14   thorpej nhpibreset(hs)
    195  1.14   thorpej 	struct hpibbus_softc *hs;
    196   1.1       cgd {
    197  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
    198  1.14   thorpej 	struct nhpibdevice *hd = sc->sc_regs;
    199   1.1       cgd 
    200   1.1       cgd 	hd->hpib_acr = AUX_SSWRST;
    201   1.1       cgd 	hd->hpib_ar = hs->sc_ba;
    202   1.1       cgd 	hd->hpib_lim = LIS_ERR;
    203   1.1       cgd 	hd->hpib_mim = 0;
    204   1.1       cgd 	hd->hpib_acr = AUX_CDAI;
    205   1.1       cgd 	hd->hpib_acr = AUX_CSHDW;
    206   1.1       cgd 	hd->hpib_acr = AUX_SSTD1;
    207   1.1       cgd 	hd->hpib_acr = AUX_SVSTD1;
    208   1.1       cgd 	hd->hpib_acr = AUX_CPP;
    209   1.1       cgd 	hd->hpib_acr = AUX_CHDFA;
    210   1.1       cgd 	hd->hpib_acr = AUX_CHDFE;
    211   1.1       cgd 	hd->hpib_acr = AUX_RHDF;
    212   1.1       cgd 	hd->hpib_acr = AUX_CSWRST;
    213   1.1       cgd 	nhpibifc(hd);
    214   1.1       cgd 	hd->hpib_ie = IDS_IE;
    215   1.6   mycroft 	hd->hpib_data = C_DCL_P;
    216   1.1       cgd 	DELAY(100000);
    217   1.1       cgd }
    218   1.1       cgd 
    219  1.14   thorpej void
    220   1.1       cgd nhpibifc(hd)
    221  1.15    scottr 	struct nhpibdevice *hd;
    222   1.1       cgd {
    223   1.1       cgd 	hd->hpib_acr = AUX_TCA;
    224   1.1       cgd 	hd->hpib_acr = AUX_CSRE;
    225   1.1       cgd 	hd->hpib_acr = AUX_SSIC;
    226   1.1       cgd 	DELAY(100);
    227   1.1       cgd 	hd->hpib_acr = AUX_CSIC;
    228   1.1       cgd 	hd->hpib_acr = AUX_SSRE;
    229   1.1       cgd }
    230   1.1       cgd 
    231   1.7   thorpej int
    232  1.14   thorpej nhpibsend(hs, slave, sec, ptr, origcnt)
    233  1.14   thorpej 	struct hpibbus_softc *hs;
    234  1.14   thorpej 	int slave, sec, origcnt;
    235   1.7   thorpej 	void *ptr;
    236   1.1       cgd {
    237  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
    238  1.14   thorpej 	struct nhpibdevice *hd = sc->sc_regs;
    239  1.14   thorpej 	int cnt = origcnt;
    240   1.7   thorpej 	char *addr = ptr;
    241   1.1       cgd 
    242   1.1       cgd 	hd->hpib_acr = AUX_TCA;
    243   1.6   mycroft 	hd->hpib_data = C_UNL_P;
    244   1.1       cgd 	if (nhpibwait(hd, MIS_BO))
    245   1.1       cgd 		goto senderror;
    246   1.6   mycroft 	hd->hpib_data = talker_par[hs->sc_ba];
    247   1.1       cgd 	hd->hpib_acr = AUX_STON;
    248   1.1       cgd 	if (nhpibwait(hd, MIS_BO))
    249   1.1       cgd 		goto senderror;
    250   1.6   mycroft 	hd->hpib_data = listnr_par[slave];
    251   1.1       cgd 	if (nhpibwait(hd, MIS_BO))
    252   1.1       cgd 		goto senderror;
    253   1.6   mycroft 	if (sec >= 0 || sec == -2) {
    254   1.6   mycroft 		if (sec == -2)		/* selected device clear KLUDGE */
    255   1.6   mycroft 			hd->hpib_data = C_SDC_P;
    256   1.6   mycroft 		else
    257   1.6   mycroft 			hd->hpib_data = sec_par[sec];
    258   1.1       cgd 		if (nhpibwait(hd, MIS_BO))
    259   1.1       cgd 			goto senderror;
    260   1.1       cgd 	}
    261   1.1       cgd 	hd->hpib_acr = AUX_GTS;
    262   1.1       cgd 	if (cnt) {
    263   1.1       cgd 		while (--cnt > 0) {
    264   1.1       cgd 			hd->hpib_data = *addr++;
    265   1.1       cgd 			if (nhpibwait(hd, MIS_BO))
    266   1.1       cgd 				goto senderror;
    267   1.1       cgd 		}
    268   1.1       cgd 		hd->hpib_acr = AUX_EOI;
    269   1.1       cgd 		hd->hpib_data = *addr;
    270   1.1       cgd 		if (nhpibwait(hd, MIS_BO))
    271   1.1       cgd 			goto senderror;
    272   1.1       cgd 		hd->hpib_acr = AUX_TCA;
    273   1.1       cgd #if 0
    274   1.1       cgd 		/*
    275   1.1       cgd 		 * May be causing 345 disks to hang due to interference
    276   1.1       cgd 		 * with PPOLL mechanism.
    277   1.1       cgd 		 */
    278   1.6   mycroft 		hd->hpib_data = C_UNL_P;
    279   1.1       cgd 		(void) nhpibwait(hd, MIS_BO);
    280   1.1       cgd #endif
    281   1.1       cgd 	}
    282   1.1       cgd 	return(origcnt);
    283   1.6   mycroft 
    284   1.1       cgd senderror:
    285   1.1       cgd 	nhpibifc(hd);
    286   1.1       cgd 	return(origcnt - cnt - 1);
    287   1.1       cgd }
    288   1.1       cgd 
    289   1.7   thorpej int
    290  1.14   thorpej nhpibrecv(hs, slave, sec, ptr, origcnt)
    291  1.14   thorpej 	struct hpibbus_softc *hs;
    292  1.14   thorpej 	int slave, sec, origcnt;
    293   1.7   thorpej 	void *ptr;
    294   1.1       cgd {
    295  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
    296  1.14   thorpej 	struct nhpibdevice *hd = sc->sc_regs;
    297  1.14   thorpej 	int cnt = origcnt;
    298   1.7   thorpej 	char *addr = ptr;
    299   1.1       cgd 
    300   1.6   mycroft 	/*
    301   1.6   mycroft 	 * Slave < 0 implies continuation of a previous receive
    302   1.6   mycroft 	 * that probably timed out.
    303   1.6   mycroft 	 */
    304   1.6   mycroft 	if (slave >= 0) {
    305   1.6   mycroft 		hd->hpib_acr = AUX_TCA;
    306   1.6   mycroft 		hd->hpib_data = C_UNL_P;
    307   1.6   mycroft 		if (nhpibwait(hd, MIS_BO))
    308   1.6   mycroft 			goto recverror;
    309   1.6   mycroft 		hd->hpib_data = listnr_par[hs->sc_ba];
    310   1.6   mycroft 		hd->hpib_acr = AUX_SLON;
    311   1.6   mycroft 		if (nhpibwait(hd, MIS_BO))
    312   1.6   mycroft 			goto recverror;
    313   1.6   mycroft 		hd->hpib_data = talker_par[slave];
    314   1.1       cgd 		if (nhpibwait(hd, MIS_BO))
    315   1.1       cgd 			goto recverror;
    316   1.6   mycroft 		if (sec >= 0) {
    317   1.6   mycroft 			hd->hpib_data = sec_par[sec];
    318   1.6   mycroft 			if (nhpibwait(hd, MIS_BO))
    319   1.6   mycroft 				goto recverror;
    320   1.6   mycroft 		}
    321   1.6   mycroft 		hd->hpib_acr = AUX_RHDF;
    322   1.6   mycroft 		hd->hpib_acr = AUX_GTS;
    323   1.1       cgd 	}
    324   1.1       cgd 	if (cnt) {
    325   1.1       cgd 		while (--cnt >= 0) {
    326   1.1       cgd 			if (nhpibwait(hd, MIS_BI))
    327   1.1       cgd 				goto recvbyteserror;
    328   1.1       cgd 			*addr++ = hd->hpib_data;
    329   1.1       cgd 		}
    330   1.1       cgd 		hd->hpib_acr = AUX_TCA;
    331   1.6   mycroft 		hd->hpib_data = (slave == 31) ? C_UNA_P : C_UNT_P;
    332   1.1       cgd 		(void) nhpibwait(hd, MIS_BO);
    333   1.1       cgd 	}
    334   1.1       cgd 	return(origcnt);
    335   1.6   mycroft 
    336   1.1       cgd recverror:
    337   1.1       cgd 	nhpibifc(hd);
    338   1.1       cgd recvbyteserror:
    339   1.1       cgd 	return(origcnt - cnt - 1);
    340   1.1       cgd }
    341   1.1       cgd 
    342   1.7   thorpej void
    343  1.14   thorpej nhpibgo(hs, slave, sec, ptr, count, rw, timo)
    344  1.14   thorpej 	struct hpibbus_softc *hs;
    345  1.14   thorpej 	int slave, sec, count, rw, timo;
    346   1.7   thorpej 	void *ptr;
    347   1.1       cgd {
    348  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
    349  1.14   thorpej 	struct nhpibdevice *hd = sc->sc_regs;
    350   1.7   thorpej 	char *addr = ptr;
    351   1.1       cgd 
    352   1.1       cgd 	hs->sc_flags |= HPIBF_IO;
    353   1.6   mycroft 	if (timo)
    354   1.6   mycroft 		hs->sc_flags |= HPIBF_TIMO;
    355   1.1       cgd 	if (rw == B_READ)
    356   1.1       cgd 		hs->sc_flags |= HPIBF_READ;
    357   1.1       cgd #ifdef DEBUG
    358   1.1       cgd 	else if (hs->sc_flags & HPIBF_READ) {
    359  1.13  christos 		printf("nhpibgo: HPIBF_READ still set\n");
    360   1.1       cgd 		hs->sc_flags &= ~HPIBF_READ;
    361   1.1       cgd 	}
    362   1.1       cgd #endif
    363   1.1       cgd 	hs->sc_count = count;
    364   1.1       cgd 	hs->sc_addr = addr;
    365   1.1       cgd 	if (hs->sc_flags & HPIBF_READ) {
    366   1.1       cgd 		hs->sc_curcnt = count;
    367  1.14   thorpej 		dmago(hs->sc_dq->dq_chan, addr, count, DMAGO_BYTE|DMAGO_READ);
    368  1.14   thorpej 		nhpibrecv(hs, slave, sec, 0, 0);
    369   1.1       cgd 		hd->hpib_mim = MIS_END;
    370   1.1       cgd 	} else {
    371   1.1       cgd 		hd->hpib_mim = 0;
    372   1.1       cgd 		if (count < hpibdmathresh) {
    373   1.1       cgd 			hs->sc_curcnt = count;
    374  1.14   thorpej 			nhpibsend(hs, slave, sec, addr, count);
    375  1.14   thorpej 			nhpibdone(hs);
    376   1.1       cgd 			return;
    377   1.1       cgd 		}
    378   1.1       cgd 		hs->sc_curcnt = --count;
    379  1.14   thorpej 		dmago(hs->sc_dq->dq_chan, addr, count, DMAGO_BYTE);
    380  1.14   thorpej 		nhpibsend(hs, slave, sec, 0, 0);
    381   1.1       cgd 	}
    382  1.14   thorpej 	hd->hpib_ie = IDS_IE | IDS_DMA(hs->sc_dq->dq_chan);
    383   1.1       cgd }
    384   1.1       cgd 
    385   1.6   mycroft /*
    386   1.6   mycroft  * This timeout can only happen if a DMA read finishes DMAing with the read
    387   1.6   mycroft  * still pending (more data in read transaction than the driver was prepared
    388   1.6   mycroft  * to accept).  At the moment, variable-record tape drives are the only things
    389   1.6   mycroft  * capabale of doing this.  We repeat the necessary code from nhpibintr() -
    390   1.6   mycroft  * easier and quicker than calling nhpibintr() for this special case.
    391   1.6   mycroft  */
    392   1.6   mycroft void
    393   1.6   mycroft nhpibreadtimo(arg)
    394   1.6   mycroft 	void *arg;
    395   1.6   mycroft {
    396  1.14   thorpej 	struct hpibbus_softc *hs = arg;
    397  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
    398   1.6   mycroft 	int s = splbio();
    399   1.6   mycroft 
    400   1.6   mycroft 	if (hs->sc_flags & HPIBF_IO) {
    401  1.15    scottr 		struct nhpibdevice *hd = sc->sc_regs;
    402  1.15    scottr 		struct hpibqueue *hq;
    403   1.6   mycroft 
    404   1.6   mycroft 		hd->hpib_mim = 0;
    405   1.6   mycroft 		hd->hpib_acr = AUX_TCA;
    406   1.6   mycroft 		hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
    407  1.14   thorpej 		dmafree(hs->sc_dq);
    408  1.14   thorpej 
    409  1.14   thorpej 		hq = hs->sc_queue.tqh_first;
    410  1.14   thorpej 		(hq->hq_intr)(hq->hq_softc);
    411   1.6   mycroft 	}
    412  1.14   thorpej 	splx(s);
    413   1.6   mycroft }
    414   1.6   mycroft 
    415   1.7   thorpej void
    416  1.14   thorpej nhpibdone(hs)
    417  1.14   thorpej 	struct hpibbus_softc *hs;
    418   1.1       cgd {
    419  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
    420  1.14   thorpej 	struct nhpibdevice *hd = sc->sc_regs;
    421  1.14   thorpej 	int cnt;
    422   1.1       cgd 
    423   1.1       cgd 	cnt = hs->sc_curcnt;
    424   1.1       cgd 	hs->sc_addr += cnt;
    425   1.1       cgd 	hs->sc_count -= cnt;
    426   1.1       cgd 	hs->sc_flags |= HPIBF_DONE;
    427   1.1       cgd 	hd->hpib_ie = IDS_IE;
    428   1.6   mycroft 	if (hs->sc_flags & HPIBF_READ) {
    429   1.6   mycroft 		if ((hs->sc_flags & HPIBF_TIMO) &&
    430   1.6   mycroft 		    (hd->hpib_ids & IDS_IR) == 0)
    431  1.14   thorpej 			timeout(nhpibreadtimo, hs, hz >> 2);
    432   1.6   mycroft 	} else {
    433   1.1       cgd 		if (hs->sc_count == 1) {
    434   1.1       cgd 			(void) nhpibwait(hd, MIS_BO);
    435   1.1       cgd 			hd->hpib_acr = AUX_EOI;
    436   1.1       cgd 			hd->hpib_data = *hs->sc_addr;
    437   1.1       cgd 			hd->hpib_mim = MIS_BO;
    438   1.1       cgd 		}
    439   1.1       cgd #ifdef DEBUG
    440   1.1       cgd 		else if (hs->sc_count)
    441   1.1       cgd 			panic("nhpibdone");
    442   1.1       cgd #endif
    443   1.1       cgd 	}
    444   1.1       cgd }
    445   1.1       cgd 
    446   1.7   thorpej int
    447   1.9   thorpej nhpibintr(arg)
    448   1.9   thorpej 	void *arg;
    449   1.1       cgd {
    450  1.14   thorpej 	struct nhpib_softc *sc = arg;
    451  1.14   thorpej 	struct hpibbus_softc *hs = sc->sc_hpibbus;
    452  1.14   thorpej 	struct nhpibdevice *hd = sc->sc_regs;
    453  1.14   thorpej 	struct hpibqueue *hq;
    454  1.14   thorpej 	int stat0;
    455  1.14   thorpej 	int stat1;
    456   1.1       cgd 
    457   1.1       cgd #ifdef lint
    458   1.1       cgd 	if (stat1 = unit) return(1);
    459   1.1       cgd #endif
    460   1.1       cgd 	if ((hd->hpib_ids & IDS_IR) == 0)
    461   1.1       cgd 		return(0);
    462   1.1       cgd 	stat0 = hd->hpib_mis;
    463   1.1       cgd 	stat1 = hd->hpib_lis;
    464  1.14   thorpej 
    465  1.14   thorpej 	hq = hs->sc_queue.tqh_first;
    466  1.14   thorpej 
    467   1.1       cgd 	if (hs->sc_flags & HPIBF_IO) {
    468   1.1       cgd 		hd->hpib_mim = 0;
    469   1.6   mycroft 		if ((hs->sc_flags & HPIBF_DONE) == 0) {
    470   1.6   mycroft 			hs->sc_flags &= ~HPIBF_TIMO;
    471  1.14   thorpej 			dmastop(hs->sc_dq->dq_chan);
    472   1.6   mycroft 		} else if (hs->sc_flags & HPIBF_TIMO)
    473  1.14   thorpej 			untimeout(nhpibreadtimo, hs);
    474   1.1       cgd 		hd->hpib_acr = AUX_TCA;
    475   1.6   mycroft 		hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
    476  1.14   thorpej 
    477  1.14   thorpej 		dmafree(hs->sc_dq);
    478  1.14   thorpej 		(hq->hq_intr)(hq->hq_softc);
    479   1.1       cgd 	} else if (hs->sc_flags & HPIBF_PPOLL) {
    480   1.1       cgd 		hd->hpib_mim = 0;
    481  1.14   thorpej 		stat0 = nhpibppoll(hs);
    482  1.14   thorpej 		if (stat0 & (0x80 >> hq->hq_slave)) {
    483   1.1       cgd 			hs->sc_flags &= ~HPIBF_PPOLL;
    484  1.14   thorpej 			(hq->hq_intr)(hq->hq_softc);
    485   1.1       cgd 		}
    486   1.1       cgd #ifdef DEBUG
    487   1.1       cgd 		else
    488  1.13  christos 			printf("%s: PPOLL intr bad status %x\n",
    489  1.14   thorpej 			       hs->sc_dev.dv_xname, stat0);
    490   1.1       cgd #endif
    491   1.1       cgd 	}
    492   1.1       cgd 	return(1);
    493   1.1       cgd }
    494   1.1       cgd 
    495   1.7   thorpej int
    496  1.14   thorpej nhpibppoll(hs)
    497  1.14   thorpej 	struct hpibbus_softc *hs;
    498   1.1       cgd {
    499  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
    500  1.14   thorpej 	struct nhpibdevice *hd = sc->sc_regs;
    501  1.14   thorpej 	int ppoll;
    502   1.1       cgd 
    503   1.1       cgd 	hd->hpib_acr = AUX_SPP;
    504   1.1       cgd 	DELAY(25);
    505   1.1       cgd 	ppoll = hd->hpib_cpt;
    506   1.1       cgd 	hd->hpib_acr = AUX_CPP;
    507   1.1       cgd 	return(ppoll);
    508   1.1       cgd }
    509   1.1       cgd 
    510   1.6   mycroft #ifdef DEBUG
    511   1.6   mycroft int nhpibreporttimo = 0;
    512   1.6   mycroft #endif
    513   1.6   mycroft 
    514   1.7   thorpej int
    515   1.1       cgd nhpibwait(hd, x)
    516  1.15    scottr 	struct nhpibdevice *hd;
    517   1.4   mycroft 	int x;
    518   1.1       cgd {
    519  1.15    scottr 	int timo = hpibtimeout;
    520   1.1       cgd 
    521   1.1       cgd 	while ((hd->hpib_mis & x) == 0 && --timo)
    522  1.11   thorpej 		DELAY(1);
    523   1.6   mycroft 	if (timo == 0) {
    524   1.6   mycroft #ifdef DEBUG
    525   1.6   mycroft 		if (nhpibreporttimo)
    526  1.13  christos 			printf("hpib0: %s timo\n", x==MIS_BO?"OUT":"IN");
    527   1.6   mycroft #endif
    528   1.1       cgd 		return(-1);
    529   1.6   mycroft 	}
    530   1.1       cgd 	return(0);
    531   1.1       cgd }
    532   1.1       cgd 
    533   1.4   mycroft void
    534   1.3   mycroft nhpibppwatch(arg)
    535   1.3   mycroft 	void *arg;
    536   1.1       cgd {
    537  1.14   thorpej 	struct hpibbus_softc *hs = arg;
    538  1.14   thorpej 	struct nhpib_softc *sc = (struct nhpib_softc *)hs->sc_dev.dv_parent;
    539   1.4   mycroft 	extern int cold;
    540   1.1       cgd 
    541   1.1       cgd 	if ((hs->sc_flags & HPIBF_PPOLL) == 0)
    542   1.1       cgd 		return;
    543   1.4   mycroft again:
    544  1.14   thorpej 	if (nhpibppoll(hs) & (0x80 >> hs->sc_queue.tqh_first->hq_slave))
    545  1.14   thorpej        		sc->sc_regs->hpib_mim = MIS_BO;
    546   1.4   mycroft 	else if (cold)
    547   1.4   mycroft 		/* timeouts not working yet */
    548   1.4   mycroft 		goto again;
    549   1.1       cgd 	else
    550  1.14   thorpej 		timeout(nhpibppwatch, hs, 1);
    551   1.1       cgd }
    552