Home | History | Annotate | Line # | Download | only in dev
esp.c revision 1.25.2.1
      1  1.25.2.1   bouyer /*	$NetBSD: esp.c,v 1.25.2.1 2000/11/20 20:18:12 bouyer Exp $	*/
      2       1.1      dbj 
      3       1.1      dbj /*-
      4       1.5  mycroft  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
      5       1.1      dbj  * All rights reserved.
      6       1.1      dbj  *
      7       1.1      dbj  * This code is derived from software contributed to The NetBSD Foundation
      8       1.6  mycroft  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
      9       1.6  mycroft  * Simulation Facility, NASA Ames Research Center.
     10       1.1      dbj  *
     11       1.1      dbj  * Redistribution and use in source and binary forms, with or without
     12       1.1      dbj  * modification, are permitted provided that the following conditions
     13       1.1      dbj  * are met:
     14       1.1      dbj  * 1. Redistributions of source code must retain the above copyright
     15       1.1      dbj  *    notice, this list of conditions and the following disclaimer.
     16       1.1      dbj  * 2. Redistributions in binary form must reproduce the above copyright
     17       1.1      dbj  *    notice, this list of conditions and the following disclaimer in the
     18       1.1      dbj  *    documentation and/or other materials provided with the distribution.
     19       1.1      dbj  * 3. All advertising materials mentioning features or use of this software
     20       1.1      dbj  *    must display the following acknowledgement:
     21       1.1      dbj  *	This product includes software developed by the NetBSD
     22       1.1      dbj  *	Foundation, Inc. and its contributors.
     23       1.1      dbj  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24       1.1      dbj  *    contributors may be used to endorse or promote products derived
     25       1.1      dbj  *    from this software without specific prior written permission.
     26       1.1      dbj  *
     27       1.1      dbj  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28       1.1      dbj  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29       1.1      dbj  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30       1.1      dbj  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31       1.1      dbj  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32       1.1      dbj  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33       1.1      dbj  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34       1.1      dbj  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35       1.1      dbj  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36       1.1      dbj  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37       1.1      dbj  * POSSIBILITY OF SUCH DAMAGE.
     38       1.1      dbj  */
     39       1.1      dbj 
     40       1.1      dbj /*
     41       1.1      dbj  * Copyright (c) 1994 Peter Galbavy
     42       1.1      dbj  * All rights reserved.
     43       1.1      dbj  *
     44       1.1      dbj  * Redistribution and use in source and binary forms, with or without
     45       1.1      dbj  * modification, are permitted provided that the following conditions
     46       1.1      dbj  * are met:
     47       1.1      dbj  * 1. Redistributions of source code must retain the above copyright
     48       1.1      dbj  *    notice, this list of conditions and the following disclaimer.
     49       1.1      dbj  * 2. Redistributions in binary form must reproduce the above copyright
     50       1.1      dbj  *    notice, this list of conditions and the following disclaimer in the
     51       1.1      dbj  *    documentation and/or other materials provided with the distribution.
     52       1.1      dbj  * 3. All advertising materials mentioning features or use of this software
     53       1.1      dbj  *    must display the following acknowledgement:
     54       1.1      dbj  *	This product includes software developed by Peter Galbavy
     55       1.1      dbj  * 4. The name of the author may not be used to endorse or promote products
     56       1.1      dbj  *    derived from this software without specific prior written permission.
     57       1.1      dbj  *
     58       1.1      dbj  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     59       1.1      dbj  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     60       1.1      dbj  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     61       1.1      dbj  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     62       1.1      dbj  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     63       1.1      dbj  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     64       1.1      dbj  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65       1.1      dbj  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     66       1.1      dbj  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     67       1.1      dbj  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     68       1.1      dbj  * POSSIBILITY OF SUCH DAMAGE.
     69       1.1      dbj  */
     70       1.1      dbj 
     71       1.1      dbj /*
     72       1.1      dbj  * Based on aic6360 by Jarle Greipsland
     73       1.1      dbj  *
     74       1.1      dbj  * Acknowledgements: Many of the algorithms used in this driver are
     75       1.1      dbj  * inspired by the work of Julian Elischer (julian (at) tfs.com) and
     76       1.1      dbj  * Charles Hannum (mycroft (at) duality.gnu.ai.mit.edu).  Thanks a million!
     77       1.1      dbj  */
     78       1.1      dbj 
     79       1.1      dbj /*
     80       1.1      dbj  * Grabbed from the sparc port at revision 1.73 for the NeXT.
     81       1.1      dbj  * Darrin B. Jewell <dbj (at) netbsd.org>  Sat Jul  4 15:41:32 1998
     82       1.1      dbj  */
     83       1.1      dbj 
     84       1.1      dbj #include <sys/types.h>
     85       1.1      dbj #include <sys/param.h>
     86       1.1      dbj #include <sys/systm.h>
     87       1.1      dbj #include <sys/kernel.h>
     88       1.1      dbj #include <sys/errno.h>
     89       1.1      dbj #include <sys/ioctl.h>
     90       1.1      dbj #include <sys/device.h>
     91       1.1      dbj #include <sys/buf.h>
     92       1.1      dbj #include <sys/proc.h>
     93       1.1      dbj #include <sys/user.h>
     94       1.1      dbj #include <sys/queue.h>
     95       1.1      dbj 
     96       1.1      dbj #include <dev/scsipi/scsi_all.h>
     97       1.1      dbj #include <dev/scsipi/scsipi_all.h>
     98       1.1      dbj #include <dev/scsipi/scsiconf.h>
     99       1.1      dbj #include <dev/scsipi/scsi_message.h>
    100       1.1      dbj 
    101       1.1      dbj #include <machine/bus.h>
    102       1.1      dbj #include <machine/autoconf.h>
    103       1.1      dbj #include <machine/cpu.h>
    104       1.1      dbj 
    105       1.1      dbj #include <dev/ic/ncr53c9xreg.h>
    106       1.1      dbj #include <dev/ic/ncr53c9xvar.h>
    107       1.1      dbj 
    108       1.1      dbj #include <next68k/next68k/isr.h>
    109       1.1      dbj 
    110       1.1      dbj #include <next68k/dev/nextdmareg.h>
    111       1.1      dbj #include <next68k/dev/nextdmavar.h>
    112       1.1      dbj 
    113       1.1      dbj #include "espreg.h"
    114       1.1      dbj #include "espvar.h"
    115       1.1      dbj 
    116      1.20      dbj #ifdef DEBUG
    117       1.4      dbj #define ESP_DEBUG
    118       1.4      dbj #endif
    119       1.4      dbj 
    120       1.4      dbj #ifdef ESP_DEBUG
    121      1.10      dbj int esp_debug = 0;
    122      1.10      dbj #define DPRINTF(x) if (esp_debug) printf x;
    123       1.4      dbj #else
    124       1.4      dbj #define DPRINTF(x)
    125       1.4      dbj #endif
    126       1.4      dbj 
    127       1.4      dbj 
    128       1.1      dbj void	espattach_intio	__P((struct device *, struct device *, void *));
    129       1.1      dbj int	espmatch_intio	__P((struct device *, struct cfdata *, void *));
    130       1.1      dbj 
    131       1.2      dbj /* DMA callbacks */
    132       1.2      dbj bus_dmamap_t esp_dmacb_continue __P((void *arg));
    133       1.2      dbj void esp_dmacb_completed __P((bus_dmamap_t map, void *arg));
    134       1.2      dbj void esp_dmacb_shutdown __P((void *arg));
    135       1.2      dbj 
    136      1.20      dbj #ifdef ESP_DEBUG
    137      1.20      dbj char esp_dma_dump[5*1024] = "";
    138      1.20      dbj struct ncr53c9x_softc *esp_debug_sc = 0;
    139      1.20      dbj void esp_dma_store __P((struct ncr53c9x_softc *sc));
    140      1.20      dbj void esp_dma_print __P((struct ncr53c9x_softc *sc));
    141      1.22      dbj int esp_dma_nest = 0;
    142      1.20      dbj #endif
    143      1.20      dbj 
    144      1.20      dbj 
    145       1.1      dbj /* Linkup to the rest of the kernel */
    146       1.1      dbj struct cfattach esp_ca = {
    147       1.1      dbj 	sizeof(struct esp_softc), espmatch_intio, espattach_intio
    148       1.1      dbj };
    149       1.1      dbj 
    150       1.1      dbj /*
    151       1.1      dbj  * Functions and the switch for the MI code.
    152       1.1      dbj  */
    153       1.1      dbj u_char	esp_read_reg __P((struct ncr53c9x_softc *, int));
    154       1.1      dbj void	esp_write_reg __P((struct ncr53c9x_softc *, int, u_char));
    155       1.1      dbj int	esp_dma_isintr __P((struct ncr53c9x_softc *));
    156       1.1      dbj void	esp_dma_reset __P((struct ncr53c9x_softc *));
    157       1.1      dbj int	esp_dma_intr __P((struct ncr53c9x_softc *));
    158       1.1      dbj int	esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
    159       1.1      dbj 	    size_t *, int, size_t *));
    160       1.1      dbj void	esp_dma_go __P((struct ncr53c9x_softc *));
    161       1.1      dbj void	esp_dma_stop __P((struct ncr53c9x_softc *));
    162       1.1      dbj int	esp_dma_isactive __P((struct ncr53c9x_softc *));
    163       1.1      dbj 
    164       1.1      dbj struct ncr53c9x_glue esp_glue = {
    165       1.1      dbj 	esp_read_reg,
    166       1.1      dbj 	esp_write_reg,
    167       1.1      dbj 	esp_dma_isintr,
    168       1.1      dbj 	esp_dma_reset,
    169       1.1      dbj 	esp_dma_intr,
    170       1.1      dbj 	esp_dma_setup,
    171       1.1      dbj 	esp_dma_go,
    172       1.1      dbj 	esp_dma_stop,
    173       1.1      dbj 	esp_dma_isactive,
    174       1.1      dbj 	NULL,			/* gl_clear_latched_intr */
    175       1.1      dbj };
    176       1.1      dbj 
    177      1.11      dbj #ifdef ESP_DEBUG
    178      1.11      dbj #define XCHR(x) "0123456789abcdef"[(x) & 0xf]
    179      1.11      dbj static void
    180      1.11      dbj esp_hex_dump(unsigned char *pkt, size_t len)
    181      1.11      dbj {
    182      1.11      dbj 	size_t i, j;
    183      1.11      dbj 
    184      1.24      dbj 	printf("00000000 ");
    185      1.11      dbj 	for(i=0; i<len; i++) {
    186      1.11      dbj 		printf("%c%c ", XCHR(pkt[i]>>4), XCHR(pkt[i]));
    187      1.24      dbj 		if ((i+1) % 16 == 8) {
    188      1.24      dbj 			printf(" ");
    189      1.24      dbj 		}
    190      1.11      dbj 		if ((i+1) % 16 == 0) {
    191      1.24      dbj 			printf(" %c", '|');
    192      1.24      dbj 			for(j=0; j<16; j++) {
    193      1.11      dbj 				printf("%c", pkt[i-15+j]>=32 && pkt[i-15+j]<127?pkt[i-15+j]:'.');
    194      1.24      dbj 			}
    195      1.24      dbj 			printf("%c\n%c%c%c%c%c%c%c%c  ", '|',
    196      1.24      dbj 					XCHR((i+1)>>28),XCHR((i+1)>>24),XCHR((i+1)>>20),XCHR((i+1)>>16),
    197      1.24      dbj 					XCHR((i+1)>>12), XCHR((i+1)>>8), XCHR((i+1)>>4), XCHR(i+1));
    198      1.11      dbj 		}
    199      1.11      dbj 	}
    200      1.11      dbj 	printf("\n");
    201      1.11      dbj }
    202      1.11      dbj #endif
    203      1.11      dbj 
    204       1.1      dbj int
    205       1.1      dbj espmatch_intio(parent, cf, aux)
    206       1.1      dbj 	struct device *parent;
    207       1.1      dbj 	struct cfdata *cf;
    208       1.1      dbj 	void *aux;
    209       1.1      dbj {
    210       1.1      dbj   /* should probably probe here */
    211       1.1      dbj   /* Should also probably set up data from config */
    212       1.1      dbj 
    213       1.3      dbj 	return(1);
    214       1.1      dbj }
    215       1.1      dbj 
    216       1.1      dbj void
    217       1.1      dbj espattach_intio(parent, self, aux)
    218       1.1      dbj 	struct device *parent, *self;
    219       1.1      dbj 	void *aux;
    220       1.1      dbj {
    221       1.1      dbj 	struct esp_softc *esc = (void *)self;
    222       1.1      dbj 	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
    223       1.1      dbj 
    224      1.20      dbj #ifdef ESP_DEBUG
    225      1.20      dbj 	esp_debug_sc = sc;
    226      1.20      dbj #endif
    227      1.20      dbj 
    228       1.1      dbj 	esc->sc_bst = NEXT68K_INTIO_BUS_SPACE;
    229       1.1      dbj 	if (bus_space_map(esc->sc_bst, NEXT_P_SCSI,
    230       1.1      dbj 			ESP_DEVICE_SIZE, 0, &esc->sc_bsh)) {
    231       1.3      dbj     panic("\n%s: can't map ncr53c90 registers",
    232       1.1      dbj 				sc->sc_dev.dv_xname);
    233       1.1      dbj 	}
    234       1.1      dbj 
    235       1.1      dbj 	sc->sc_id = 7;
    236       1.1      dbj 	sc->sc_freq = 20;							/* Mhz */
    237       1.1      dbj 
    238       1.1      dbj 	/*
    239       1.1      dbj 	 * Set up glue for MI code early; we use some of it here.
    240       1.1      dbj 	 */
    241       1.1      dbj 	sc->sc_glue = &esp_glue;
    242       1.1      dbj 
    243       1.1      dbj 	/*
    244       1.1      dbj 	 * XXX More of this should be in ncr53c9x_attach(), but
    245       1.1      dbj 	 * XXX should we really poke around the chip that much in
    246       1.1      dbj 	 * XXX the MI code?  Think about this more...
    247       1.1      dbj 	 */
    248       1.1      dbj 
    249       1.1      dbj 	/*
    250       1.1      dbj 	 * It is necessary to try to load the 2nd config register here,
    251       1.1      dbj 	 * to find out what rev the esp chip is, else the ncr53c9x_reset
    252       1.1      dbj 	 * will not set up the defaults correctly.
    253       1.1      dbj 	 */
    254       1.1      dbj 	sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
    255       1.1      dbj 	sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
    256       1.1      dbj 	sc->sc_cfg3 = NCRCFG3_CDB;
    257       1.1      dbj 	NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
    258       1.1      dbj 
    259       1.1      dbj 	if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
    260       1.1      dbj 	    (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
    261       1.1      dbj 		sc->sc_rev = NCR_VARIANT_ESP100;
    262       1.1      dbj 	} else {
    263       1.1      dbj 		sc->sc_cfg2 = NCRCFG2_SCSI2;
    264       1.1      dbj 		NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
    265       1.1      dbj 		sc->sc_cfg3 = 0;
    266       1.1      dbj 		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
    267       1.1      dbj 		sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
    268       1.1      dbj 		NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
    269       1.1      dbj 		if (NCR_READ_REG(sc, NCR_CFG3) !=
    270       1.1      dbj 		    (NCRCFG3_CDB | NCRCFG3_FCLK)) {
    271       1.1      dbj 			sc->sc_rev = NCR_VARIANT_ESP100A;
    272       1.1      dbj 		} else {
    273       1.1      dbj 			/* NCRCFG2_FE enables > 64K transfers */
    274       1.1      dbj 			sc->sc_cfg2 |= NCRCFG2_FE;
    275       1.1      dbj 			sc->sc_cfg3 = 0;
    276       1.1      dbj 			NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
    277       1.1      dbj 			sc->sc_rev = NCR_VARIANT_ESP200;
    278       1.1      dbj 		}
    279       1.1      dbj 	}
    280       1.1      dbj 
    281       1.1      dbj 	/*
    282       1.1      dbj 	 * XXX minsync and maxxfer _should_ be set up in MI code,
    283       1.1      dbj 	 * XXX but it appears to have some dependency on what sort
    284       1.1      dbj 	 * XXX of DMA we're hooked up to, etc.
    285       1.1      dbj 	 */
    286       1.1      dbj 
    287       1.1      dbj 	/*
    288       1.1      dbj 	 * This is the value used to start sync negotiations
    289       1.1      dbj 	 * Note that the NCR register "SYNCTP" is programmed
    290       1.1      dbj 	 * in "clocks per byte", and has a minimum value of 4.
    291       1.1      dbj 	 * The SCSI period used in negotiation is one-fourth
    292       1.1      dbj 	 * of the time (in nanoseconds) needed to transfer one byte.
    293       1.1      dbj 	 * Since the chip's clock is given in MHz, we have the following
    294       1.1      dbj 	 * formula: 4 * period = (1000 / freq) * 4
    295       1.1      dbj 	 */
    296       1.1      dbj 	sc->sc_minsync = 1000 / sc->sc_freq;
    297       1.1      dbj 
    298       1.1      dbj 	/*
    299       1.1      dbj 	 * Alas, we must now modify the value a bit, because it's
    300       1.1      dbj 	 * only valid when can switch on FASTCLK and FASTSCSI bits
    301       1.1      dbj 	 * in config register 3...
    302       1.1      dbj 	 */
    303       1.1      dbj 	switch (sc->sc_rev) {
    304       1.1      dbj 	case NCR_VARIANT_ESP100:
    305       1.1      dbj 		sc->sc_maxxfer = 64 * 1024;
    306       1.1      dbj 		sc->sc_minsync = 0;	/* No synch on old chip? */
    307       1.1      dbj 		break;
    308       1.1      dbj 
    309       1.1      dbj 	case NCR_VARIANT_ESP100A:
    310       1.1      dbj 		sc->sc_maxxfer = 64 * 1024;
    311       1.1      dbj 		/* Min clocks/byte is 5 */
    312       1.1      dbj 		sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
    313       1.1      dbj 		break;
    314       1.1      dbj 
    315       1.1      dbj 	case NCR_VARIANT_ESP200:
    316       1.1      dbj 		sc->sc_maxxfer = 16 * 1024 * 1024;
    317       1.1      dbj 		/* XXX - do actually set FAST* bits */
    318       1.1      dbj 		break;
    319       1.1      dbj 	}
    320       1.1      dbj 
    321       1.3      dbj 	/* @@@ Some ESP_DCTL bits probably need setting */
    322       1.3      dbj 	NCR_WRITE_REG(sc, ESP_DCTL,
    323       1.3      dbj 			ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_RESET);
    324       1.3      dbj 	DELAY(10);
    325      1.22      dbj 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
    326       1.3      dbj 	NCR_WRITE_REG(sc, ESP_DCTL, ESPDCTL_20MHZ | ESPDCTL_INTENB);
    327       1.3      dbj 	DELAY(10);
    328      1.22      dbj 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
    329       1.3      dbj 
    330       1.3      dbj 	/* Set up SCSI DMA */
    331       1.3      dbj 	{
    332       1.3      dbj 		esc->sc_scsi_dma.nd_bst = NEXT68K_INTIO_BUS_SPACE;
    333       1.3      dbj 
    334       1.3      dbj 		if (bus_space_map(esc->sc_scsi_dma.nd_bst, NEXT_P_SCSI_CSR,
    335       1.3      dbj 				sizeof(struct dma_dev),0, &esc->sc_scsi_dma.nd_bsh)) {
    336       1.3      dbj 			panic("\n%s: can't map scsi DMA registers",
    337       1.3      dbj 					sc->sc_dev.dv_xname);
    338       1.3      dbj 		}
    339       1.3      dbj 
    340       1.3      dbj 		esc->sc_scsi_dma.nd_intr = NEXT_I_SCSI_DMA;
    341       1.3      dbj 		esc->sc_scsi_dma.nd_shutdown_cb  = &esp_dmacb_shutdown;
    342       1.3      dbj 		esc->sc_scsi_dma.nd_continue_cb  = &esp_dmacb_continue;
    343       1.3      dbj 		esc->sc_scsi_dma.nd_completed_cb = &esp_dmacb_completed;
    344       1.3      dbj 		esc->sc_scsi_dma.nd_cb_arg       = sc;
    345       1.3      dbj 		nextdma_config(&esc->sc_scsi_dma);
    346       1.3      dbj 		nextdma_init(&esc->sc_scsi_dma);
    347       1.3      dbj 
    348      1.18      dbj #if 0
    349      1.18      dbj 		/* Turn on target selection using the `dma' method */
    350      1.18      dbj 		ncr53c9x_dmaselect = 1;
    351      1.18      dbj #else
    352      1.18      dbj 		ncr53c9x_dmaselect = 0;
    353      1.18      dbj #endif
    354      1.18      dbj 
    355      1.18      dbj 		esc->sc_datain = -1;
    356      1.18      dbj 		esc->sc_dmaaddr = 0;
    357      1.18      dbj 		esc->sc_dmalen  = 0;
    358      1.20      dbj 		esc->sc_dmasize = 0;
    359      1.18      dbj 
    360      1.18      dbj 		esc->sc_loaded = 0;
    361      1.18      dbj 
    362      1.18      dbj 		esc->sc_begin = 0;
    363      1.18      dbj 		esc->sc_begin_size = 0;
    364      1.18      dbj 
    365       1.3      dbj 		{
    366       1.3      dbj 			int error;
    367       1.3      dbj 			if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat,
    368      1.19      dbj 					sc->sc_maxxfer, sc->sc_maxxfer/NBPG, sc->sc_maxxfer,
    369      1.18      dbj 					0, BUS_DMA_ALLOCNOW, &esc->sc_main_dmamap)) != 0) {
    370      1.18      dbj 				panic("%s: can't create main i/o DMA map, error = %d",
    371       1.3      dbj 						sc->sc_dev.dv_xname,error);
    372       1.3      dbj 			}
    373       1.3      dbj 		}
    374      1.18      dbj 		esc->sc_main = 0;
    375      1.18      dbj 		esc->sc_main_size = 0;
    376      1.14      dbj 
    377      1.14      dbj 		{
    378      1.14      dbj 			int error;
    379      1.14      dbj 			if ((error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat,
    380      1.19      dbj 					ESP_DMA_TAILBUFSIZE,
    381      1.19      dbj 					1, ESP_DMA_TAILBUFSIZE,
    382      1.14      dbj 					0, BUS_DMA_ALLOCNOW, &esc->sc_tail_dmamap)) != 0) {
    383      1.14      dbj 				panic("%s: can't create tail i/o DMA map, error = %d",
    384      1.14      dbj 						sc->sc_dev.dv_xname,error);
    385      1.14      dbj 			}
    386      1.14      dbj 		}
    387      1.18      dbj 		esc->sc_tail = 0;
    388      1.18      dbj 		esc->sc_tail_size = 0;
    389      1.18      dbj 
    390       1.3      dbj 	}
    391       1.1      dbj 
    392       1.3      dbj 	/* Establish interrupt channel */
    393  1.25.2.1   bouyer 	isrlink_autovec(ncr53c9x_intr, sc, NEXT_I_IPL(NEXT_I_SCSI), 0);
    394       1.3      dbj 	INTR_ENABLE(NEXT_I_SCSI);
    395       1.4      dbj 
    396       1.4      dbj 	/* register interrupt stats */
    397  1.25.2.1   bouyer 	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
    398  1.25.2.1   bouyer 	    sc->sc_dev.dv_xname, "intr");
    399       1.4      dbj 
    400       1.4      dbj 	/* Do the common parts of attachment. */
    401  1.25.2.1   bouyer 	ncr53c9x_attach(sc, NULL, NULL);
    402       1.1      dbj }
    403       1.1      dbj 
    404       1.1      dbj /*
    405       1.1      dbj  * Glue functions.
    406       1.1      dbj  */
    407       1.1      dbj 
    408       1.1      dbj u_char
    409       1.1      dbj esp_read_reg(sc, reg)
    410       1.1      dbj 	struct ncr53c9x_softc *sc;
    411       1.1      dbj 	int reg;
    412       1.1      dbj {
    413       1.1      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
    414       1.1      dbj 
    415       1.1      dbj 	return(bus_space_read_1(esc->sc_bst, esc->sc_bsh, reg));
    416       1.1      dbj }
    417       1.1      dbj 
    418       1.1      dbj void
    419       1.1      dbj esp_write_reg(sc, reg, val)
    420       1.1      dbj 	struct ncr53c9x_softc *sc;
    421       1.1      dbj 	int reg;
    422       1.1      dbj 	u_char val;
    423       1.1      dbj {
    424       1.1      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
    425       1.1      dbj 
    426       1.1      dbj 	bus_space_write_1(esc->sc_bst, esc->sc_bsh, reg, val);
    427       1.1      dbj }
    428       1.1      dbj 
    429       1.1      dbj int
    430       1.1      dbj esp_dma_isintr(sc)
    431       1.1      dbj 	struct ncr53c9x_softc *sc;
    432       1.1      dbj {
    433       1.4      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
    434       1.4      dbj 
    435       1.4      dbj 	int r = (INTR_OCCURRED(NEXT_I_SCSI));
    436       1.4      dbj 
    437       1.4      dbj 	if (r) {
    438      1.13      dbj 
    439      1.20      dbj 		{
    440      1.23      dbj 			int flushcount;
    441      1.20      dbj 			int s;
    442      1.20      dbj 			s = spldma();
    443      1.20      dbj 
    444      1.23      dbj 			flushcount = 0;
    445      1.23      dbj 
    446      1.22      dbj #ifdef ESP_DEBUG
    447      1.22      dbj 			esp_dma_nest++;
    448      1.22      dbj 
    449  1.25.2.1   bouyer 			if (esp_debug) {
    450  1.25.2.1   bouyer 				char sbuf[256];
    451  1.25.2.1   bouyer 
    452  1.25.2.1   bouyer 				bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),
    453  1.25.2.1   bouyer 						 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
    454  1.25.2.1   bouyer 				printf("esp_dma_isintr = 0x%s\n", sbuf);
    455  1.25.2.1   bouyer 			}
    456  1.25.2.1   bouyer #endif
    457      1.20      dbj 
    458      1.20      dbj 			while (esp_dma_isactive(sc)) {
    459      1.23      dbj 				flushcount++;
    460      1.17      dbj 
    461      1.17      dbj #ifdef DIAGNOSTIC
    462      1.20      dbj 				r = (INTR_OCCURRED(NEXT_I_SCSI));
    463      1.20      dbj 				if (!r) panic("esp intr enabled but dma failed to flush");
    464      1.17      dbj #endif
    465      1.23      dbj #ifdef DIAGNOSTIC
    466      1.23      dbj #if 0
    467      1.23      dbj 				if ((esc->sc_loaded & (ESP_LOADED_TAIL/* |ESP_UNLOADED_MAIN */))
    468      1.23      dbj 						!= (ESP_LOADED_TAIL /* |ESP_UNLOADED_MAIN */)) {
    469      1.23      dbj 					if (esc->sc_datain) {
    470      1.23      dbj 						NCR_WRITE_REG(sc, ESP_DCTL,
    471      1.23      dbj 								ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
    472      1.23      dbj 					} else {
    473      1.23      dbj 						NCR_WRITE_REG(sc, ESP_DCTL,
    474      1.23      dbj 								ESPDCTL_20MHZ | ESPDCTL_INTENB);
    475      1.23      dbj 					}
    476      1.23      dbj 					next_dma_print(&esc->sc_scsi_dma);
    477      1.23      dbj 					esp_dma_print(sc);
    478      1.23      dbj 					printf("%s: unexpected flush: tc=0x%06x\n",
    479      1.23      dbj 							sc->sc_dev.dv_xname,
    480      1.23      dbj 							(((sc->sc_cfg2 & NCRCFG2_FE)
    481      1.23      dbj 									? NCR_READ_REG(sc, NCR_TCH) : 0)<<16)|
    482      1.23      dbj 							(NCR_READ_REG(sc, NCR_TCM)<<8)|
    483      1.23      dbj 							NCR_READ_REG(sc, NCR_TCL));
    484      1.23      dbj 					ncr53c9x_readregs(sc);
    485      1.23      dbj 					printf("%s: readregs[intr=%02x,stat=%02x,step=%02x]\n",
    486      1.23      dbj 							sc->sc_dev.dv_xname,
    487      1.23      dbj 							sc->sc_espintr, sc->sc_espstat, sc->sc_espstep);
    488      1.23      dbj 					panic("%s: flushing flushing non-tail dma\n",
    489      1.23      dbj 							sc->sc_dev.dv_xname);
    490      1.23      dbj 				}
    491      1.23      dbj #endif
    492      1.23      dbj #endif
    493      1.23      dbj 				DPRINTF(("%s: flushing dma, count = %d\n", sc->sc_dev.dv_xname,flushcount));
    494      1.20      dbj 				if (esc->sc_datain) {
    495      1.20      dbj 					NCR_WRITE_REG(sc, ESP_DCTL,
    496      1.20      dbj 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD | ESPDCTL_FLUSH);
    497      1.22      dbj 					DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
    498      1.20      dbj 					NCR_WRITE_REG(sc, ESP_DCTL,
    499      1.20      dbj 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD);
    500      1.20      dbj 				} else {
    501      1.20      dbj 					NCR_WRITE_REG(sc, ESP_DCTL,
    502      1.20      dbj 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_FLUSH);
    503      1.22      dbj 					DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
    504      1.20      dbj 					NCR_WRITE_REG(sc, ESP_DCTL,
    505      1.20      dbj 							ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD);
    506      1.20      dbj 				}
    507      1.22      dbj 				DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
    508      1.20      dbj 
    509      1.20      dbj 				{
    510      1.20      dbj 					int nr;
    511      1.20      dbj 					nr = nextdma_intr(&esc->sc_scsi_dma);
    512      1.20      dbj 					if (nr) {
    513      1.20      dbj 						DPRINTF(("nextma_intr = %d\n",nr));
    514      1.23      dbj #ifdef DIAGNOSTIC
    515      1.23      dbj #if 0
    516      1.23      dbj 						if (flushcount > 16) {
    517      1.23      dbj 							printf("%s: unexpected flushcount %d\n",sc->sc_dev.dv_xname,flushcount);
    518      1.23      dbj 						}
    519      1.23      dbj #endif
    520      1.23      dbj #endif
    521      1.23      dbj #ifdef DIAGNOSTIC
    522      1.23      dbj #if 0
    523      1.23      dbj 						if (esp_dma_isactive(sc)) {
    524      1.23      dbj 							esp_dma_print(sc);
    525      1.23      dbj 							printf("%s: dma still active after a flush with count %d\n",
    526      1.23      dbj 									sc->sc_dev.dv_xname,flushcount);
    527      1.23      dbj 
    528      1.23      dbj 						}
    529      1.23      dbj #endif
    530      1.23      dbj #endif
    531      1.23      dbj 						flushcount = 0;
    532      1.20      dbj 					}
    533      1.16      dbj 				}
    534      1.16      dbj 			}
    535      1.20      dbj 
    536      1.22      dbj #ifdef ESP_DEBUG
    537      1.22      dbj 			esp_dma_nest--;
    538      1.22      dbj #endif
    539      1.22      dbj 
    540      1.20      dbj 			splx(s);
    541      1.13      dbj 		}
    542      1.13      dbj 
    543      1.20      dbj #ifdef DIAGNOSTIC
    544      1.20      dbj 		r = (INTR_OCCURRED(NEXT_I_SCSI));
    545      1.20      dbj 		if (!r) panic("esp intr not enabled after dma flush");
    546      1.20      dbj #endif
    547      1.20      dbj 
    548      1.13      dbj 		/* Clear the DMAMOD bit in the DCTL register, since if this
    549      1.13      dbj 		 * routine returns true, then the ncr53c9x_intr handler will
    550      1.13      dbj 		 * be called and needs access to the scsi registers.
    551      1.13      dbj 		 */
    552      1.13      dbj 		if (esc->sc_datain) {
    553      1.13      dbj 			NCR_WRITE_REG(sc, ESP_DCTL,
    554      1.13      dbj 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
    555      1.13      dbj 		} else {
    556      1.13      dbj 			NCR_WRITE_REG(sc, ESP_DCTL,
    557      1.13      dbj 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
    558      1.13      dbj 		}
    559      1.22      dbj 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
    560      1.13      dbj 
    561       1.4      dbj 	}
    562       1.4      dbj 
    563       1.4      dbj 	return (r);
    564       1.1      dbj }
    565       1.1      dbj 
    566       1.1      dbj void
    567       1.1      dbj esp_dma_reset(sc)
    568       1.1      dbj 	struct ncr53c9x_softc *sc;
    569       1.1      dbj {
    570       1.1      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
    571       1.3      dbj 
    572      1.13      dbj 	DPRINTF(("esp dma reset\n"));
    573      1.13      dbj 
    574      1.13      dbj #ifdef ESP_DEBUG
    575      1.13      dbj 	if (esp_debug) {
    576  1.25.2.1   bouyer 		char sbuf[256];
    577  1.25.2.1   bouyer 
    578  1.25.2.1   bouyer 		bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),
    579  1.25.2.1   bouyer 				 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
    580  1.25.2.1   bouyer 		printf("  *intrstat = 0x%s\n", sbuf);
    581  1.25.2.1   bouyer 
    582  1.25.2.1   bouyer 		bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),
    583  1.25.2.1   bouyer 				 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
    584  1.25.2.1   bouyer 		printf("  *intrmask = 0x%s\n", sbuf);
    585      1.13      dbj 	}
    586      1.13      dbj #endif
    587      1.13      dbj 
    588      1.13      dbj 	/* Clear the DMAMOD bit in the DCTL register: */
    589      1.18      dbj 	NCR_WRITE_REG(sc, ESP_DCTL,
    590      1.18      dbj 			ESPDCTL_20MHZ | ESPDCTL_INTENB);
    591      1.22      dbj 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
    592      1.13      dbj 
    593       1.4      dbj 	nextdma_reset(&esc->sc_scsi_dma);
    594       1.4      dbj 
    595      1.18      dbj 	esc->sc_datain = -1;
    596      1.18      dbj 	esc->sc_dmaaddr = 0;
    597      1.18      dbj 	esc->sc_dmalen  = 0;
    598      1.20      dbj 	esc->sc_dmasize = 0;
    599      1.18      dbj 
    600      1.18      dbj 	esc->sc_loaded = 0;
    601      1.18      dbj 
    602      1.18      dbj 	esc->sc_begin = 0;
    603      1.18      dbj 	esc->sc_begin_size = 0;
    604      1.13      dbj 
    605      1.18      dbj 	if (esc->sc_main_dmamap->dm_mapsize) {
    606      1.18      dbj 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap);
    607      1.13      dbj 	}
    608      1.18      dbj 	esc->sc_main = 0;
    609      1.18      dbj 	esc->sc_main_size = 0;
    610      1.13      dbj 
    611      1.18      dbj 	if (esc->sc_tail_dmamap->dm_mapsize) {
    612      1.18      dbj 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap);
    613      1.18      dbj 	}
    614      1.18      dbj 	esc->sc_tail = 0;
    615      1.18      dbj 	esc->sc_tail_size = 0;
    616       1.1      dbj }
    617       1.1      dbj 
    618       1.1      dbj int
    619       1.1      dbj esp_dma_intr(sc)
    620       1.1      dbj 	struct ncr53c9x_softc *sc;
    621       1.1      dbj {
    622      1.18      dbj #ifdef DIAGNOSTIC
    623      1.18      dbj 	panic("%s: esp_dma_intr shouldn't be invoked.\n", sc->sc_dev.dv_xname);
    624      1.11      dbj #endif
    625      1.11      dbj 
    626      1.18      dbj 	return -1;
    627       1.1      dbj }
    628       1.1      dbj 
    629      1.19      dbj /* it appears that:
    630      1.19      dbj  * addr and len arguments to this need to be kept up to date
    631      1.19      dbj  * with the status of the transfter.
    632      1.19      dbj  * the dmasize of this is the actual length of the transfer
    633      1.19      dbj  * request, which is guaranteed to be less than maxxfer.
    634      1.19      dbj  * (len may be > maxxfer)
    635      1.19      dbj  */
    636      1.19      dbj 
    637       1.1      dbj int
    638       1.1      dbj esp_dma_setup(sc, addr, len, datain, dmasize)
    639       1.1      dbj 	struct ncr53c9x_softc *sc;
    640       1.1      dbj 	caddr_t *addr;
    641       1.1      dbj 	size_t *len;
    642       1.1      dbj 	int datain;
    643       1.1      dbj 	size_t *dmasize;
    644       1.1      dbj {
    645       1.1      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
    646       1.2      dbj 
    647      1.11      dbj #ifdef DIAGNOSTIC
    648      1.20      dbj #ifdef ESP_DEBUG
    649      1.11      dbj 	/* if this is a read DMA, pre-fill the buffer with 0xdeadbeef
    650      1.11      dbj 	 * to identify bogus reads
    651      1.11      dbj 	 */
    652      1.11      dbj 	if (datain) {
    653      1.14      dbj 		int *v = (int *)(*addr);
    654      1.11      dbj 		int i;
    655      1.14      dbj 		for(i=0;i<((*len)/4);i++) v[i] = 0xdeadbeef;
    656      1.18      dbj 		v = (int *)(&(esc->sc_tailbuf[0]));
    657      1.18      dbj 		for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xdeaffeed;
    658      1.23      dbj 	} else {
    659      1.23      dbj 		int *v;
    660      1.23      dbj 		int i;
    661      1.23      dbj 		v = (int *)(&(esc->sc_tailbuf[0]));
    662      1.23      dbj 		for(i=0;i<((sizeof(esc->sc_tailbuf)/4));i++) v[i] = 0xfeeb1eed;
    663      1.11      dbj 	}
    664      1.20      dbj #endif
    665      1.11      dbj #endif
    666      1.11      dbj 
    667      1.14      dbj 	DPRINTF(("esp_dma_setup(0x%08lx,0x%08lx,0x%08lx)\n",*addr,*len,*dmasize));
    668      1.11      dbj 
    669      1.24      dbj #if 0
    670      1.12      dbj #ifdef DIAGNOSTIC /* @@@ this is ok sometimes. verify that we handle it ok
    671      1.12      dbj 									 * and then remove this check
    672      1.12      dbj 									 */
    673      1.14      dbj 	if (*len != *dmasize) {
    674      1.23      dbj 		panic("esp dmalen 0x%lx != size 0x%lx",*len,*dmasize);
    675      1.11      dbj 	}
    676      1.11      dbj #endif
    677      1.24      dbj #endif
    678       1.4      dbj 
    679       1.2      dbj #ifdef DIAGNOSTIC
    680       1.3      dbj 	if ((esc->sc_datain != -1) ||
    681      1.18      dbj 			(esc->sc_main_dmamap->dm_mapsize != 0) ||
    682      1.20      dbj 			(esc->sc_tail_dmamap->dm_mapsize != 0) ||
    683      1.20      dbj 			(esc->sc_dmasize != 0)) {
    684       1.3      dbj 		panic("%s: map already loaded in esp_dma_setup\n"
    685      1.20      dbj 				"\tdatain = %d\n\tmain_mapsize=%d\n\tail_mapsize=%d\n\tdmasize = %d",
    686      1.18      dbj 				sc->sc_dev.dv_xname, esc->sc_datain,
    687      1.20      dbj 				esc->sc_main_dmamap->dm_mapsize,
    688      1.20      dbj 				esc->sc_tail_dmamap->dm_mapsize,
    689      1.20      dbj 				esc->sc_dmasize);
    690       1.2      dbj 	}
    691       1.2      dbj #endif
    692       1.2      dbj 
    693      1.20      dbj 	/* we are sometimes asked to dma zero  bytes, that's easy */
    694      1.24      dbj 	if (*dmasize <= 0) {
    695      1.20      dbj 		return(0);
    696      1.20      dbj 	}
    697      1.20      dbj 
    698      1.14      dbj 	/* Save these in case we have to abort DMA */
    699      1.14      dbj 	esc->sc_datain   = datain;
    700      1.14      dbj 	esc->sc_dmaaddr  = addr;
    701      1.14      dbj 	esc->sc_dmalen   = len;
    702      1.14      dbj 	esc->sc_dmasize  = *dmasize;
    703      1.14      dbj 
    704      1.18      dbj 	esc->sc_loaded = 0;
    705      1.18      dbj 
    706      1.23      dbj #define DMA_SCSI_ALIGNMENT 16
    707      1.23      dbj #define DMA_SCSI_ALIGN(type, addr)	\
    708      1.23      dbj 	((type)(((unsigned)(addr)+DMA_SCSI_ALIGNMENT-1) \
    709      1.23      dbj 		&~(DMA_SCSI_ALIGNMENT-1)))
    710      1.23      dbj #define DMA_SCSI_ALIGNED(addr) \
    711      1.23      dbj 	(((unsigned)(addr)&(DMA_SCSI_ALIGNMENT-1))==0)
    712      1.23      dbj 
    713       1.2      dbj 	{
    714      1.18      dbj 		size_t slop_bgn_size; /* # bytes to be fifo'd at beginning */
    715      1.18      dbj 		size_t slop_end_size; /* # bytes to be transferred in tail buffer */
    716      1.18      dbj 
    717       1.3      dbj 		{
    718      1.13      dbj 			u_long bgn = (u_long)(*esc->sc_dmaaddr);
    719      1.13      dbj 			u_long end = (u_long)(*esc->sc_dmaaddr+esc->sc_dmasize);
    720       1.3      dbj 
    721      1.23      dbj 			slop_bgn_size = DMA_SCSI_ALIGNMENT-(bgn % DMA_SCSI_ALIGNMENT);
    722      1.23      dbj 			if (slop_bgn_size == DMA_SCSI_ALIGNMENT) slop_bgn_size = 0;
    723      1.19      dbj 			slop_end_size = (end % DMA_ENDALIGNMENT);
    724       1.3      dbj 		}
    725       1.3      dbj 
    726      1.23      dbj 		/* Force a minimum slop end size. This ensures that write
    727      1.23      dbj 		 * requests will overrun, as required to get completion interrupts.
    728      1.23      dbj 		 * In addition, since the tail buffer is guaranteed to be mapped
    729      1.23      dbj 		 * in a single dma segment, the overrun won't accidentally
    730      1.23      dbj 		 * end up in its own segment.
    731      1.23      dbj 		 */
    732      1.23      dbj 		if (!esc->sc_datain) {
    733      1.24      dbj #if 0
    734      1.23      dbj 			slop_end_size += ESP_DMA_MAXTAIL;
    735      1.24      dbj #else
    736      1.24      dbj 			slop_end_size += 0x10;
    737      1.24      dbj #endif
    738      1.23      dbj 		}
    739      1.23      dbj 
    740      1.10      dbj 		/* Check to make sure we haven't counted extra slop
    741      1.14      dbj 		 * as would happen for a very short dma buffer, also
    742      1.14      dbj 		 * for short buffers, just stuff the entire thing in the tail
    743      1.14      dbj 		 */
    744      1.18      dbj 		if ((slop_bgn_size+slop_end_size >= esc->sc_dmasize)
    745      1.20      dbj #if 0
    746      1.18      dbj 				|| (esc->sc_dmasize <= ESP_DMA_MAXTAIL)
    747      1.18      dbj #endif
    748      1.18      dbj 				)
    749      1.18      dbj 		{
    750      1.14      dbj  			slop_bgn_size = 0;
    751      1.14      dbj 			slop_end_size = esc->sc_dmasize;
    752      1.18      dbj 		}
    753      1.14      dbj 
    754      1.18      dbj 		/* initialize the fifo buffer */
    755      1.18      dbj 		if (slop_bgn_size) {
    756      1.18      dbj 			esc->sc_begin = *esc->sc_dmaaddr;
    757      1.18      dbj 			esc->sc_begin_size = slop_bgn_size;
    758      1.18      dbj 		} else {
    759      1.18      dbj 			esc->sc_begin = 0;
    760      1.18      dbj 			esc->sc_begin_size = 0;
    761      1.18      dbj 		}
    762      1.18      dbj 
    763      1.18      dbj 		/* Load the normal DMA map */
    764      1.18      dbj 		{
    765      1.18      dbj 			esc->sc_main      = *esc->sc_dmaaddr+slop_bgn_size;
    766      1.18      dbj 			esc->sc_main_size = (esc->sc_dmasize)-(slop_end_size+slop_bgn_size);
    767      1.18      dbj 
    768      1.18      dbj 			if (esc->sc_main_size) {
    769      1.18      dbj 				int error;
    770      1.18      dbj 				error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat,
    771      1.18      dbj 						esc->sc_main_dmamap,
    772      1.18      dbj 						esc->sc_main, esc->sc_main_size,
    773      1.18      dbj 						NULL, BUS_DMA_NOWAIT);
    774      1.18      dbj 				if (error) {
    775      1.18      dbj 					panic("%s: can't load main dma map. error = %d, addr=0x%08x, size=0x%08x",
    776      1.18      dbj 							sc->sc_dev.dv_xname, error,esc->sc_main,esc->sc_main_size);
    777      1.18      dbj 				}
    778      1.23      dbj #if 0
    779      1.19      dbj 				bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
    780      1.19      dbj 						0, esc->sc_main_dmamap->dm_mapsize,
    781      1.19      dbj 						(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
    782      1.23      dbj #endif
    783      1.18      dbj 			} else {
    784      1.18      dbj 				esc->sc_main = 0;
    785      1.18      dbj 			}
    786      1.14      dbj 		}
    787       1.3      dbj 
    788      1.18      dbj 		/* Load the tail DMA map */
    789      1.18      dbj 		if (slop_end_size) {
    790      1.18      dbj 			esc->sc_tail      = DMA_ENDALIGN(caddr_t,esc->sc_tailbuf+slop_end_size)-slop_end_size;
    791      1.18      dbj 			/* If the beginning of the tail is not correctly aligned,
    792      1.18      dbj 			 * we have no choice but to align the start, which might then unalign the end.
    793      1.18      dbj 			 */
    794      1.23      dbj 			esc->sc_tail      = DMA_SCSI_ALIGN(caddr_t,esc->sc_tail);
    795      1.18      dbj 			/* So therefore, we change the tail size to be end aligned again. */
    796      1.18      dbj 			esc->sc_tail_size = DMA_ENDALIGN(caddr_t,esc->sc_tail+slop_end_size)-esc->sc_tail;
    797      1.19      dbj 
    798      1.19      dbj 			/* @@@ next dma overrun lossage */
    799      1.20      dbj 			if (!esc->sc_datain) {
    800      1.21      dbj 				esc->sc_tail_size += ESP_DMA_OVERRUN;
    801      1.20      dbj 			}
    802      1.20      dbj 
    803      1.18      dbj 			{
    804      1.18      dbj 				int error;
    805      1.18      dbj 				error = bus_dmamap_load(esc->sc_scsi_dma.nd_dmat,
    806      1.18      dbj 						esc->sc_tail_dmamap,
    807      1.18      dbj 						esc->sc_tail, esc->sc_tail_size,
    808      1.18      dbj 						NULL, BUS_DMA_NOWAIT);
    809      1.18      dbj 				if (error) {
    810      1.18      dbj 					panic("%s: can't load tail dma map. error = %d, addr=0x%08x, size=0x%08x",
    811      1.18      dbj 							sc->sc_dev.dv_xname, error,esc->sc_tail,esc->sc_tail_size);
    812      1.18      dbj 				}
    813      1.23      dbj #if 0
    814      1.19      dbj 				bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
    815      1.19      dbj 						0, esc->sc_tail_dmamap->dm_mapsize,
    816      1.19      dbj 						(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
    817      1.23      dbj #endif
    818       1.3      dbj 			}
    819       1.3      dbj 		}
    820       1.2      dbj 	}
    821       1.2      dbj 
    822       1.1      dbj 	return (0);
    823       1.1      dbj }
    824       1.1      dbj 
    825      1.20      dbj #ifdef ESP_DEBUG
    826      1.20      dbj /* For debugging */
    827       1.1      dbj void
    828      1.20      dbj esp_dma_store(sc)
    829       1.1      dbj 	struct ncr53c9x_softc *sc;
    830       1.1      dbj {
    831       1.1      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
    832      1.20      dbj 	char *p = &esp_dma_dump[0];
    833      1.20      dbj 
    834      1.20      dbj 	p += sprintf(p,"%s: sc_datain=%d\n",sc->sc_dev.dv_xname,esc->sc_datain);
    835      1.20      dbj 	p += sprintf(p,"%s: sc_loaded=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_loaded);
    836       1.3      dbj 
    837      1.20      dbj 	if (esc->sc_dmaaddr) {
    838      1.20      dbj 		p += sprintf(p,"%s: sc_dmaaddr=0x%08lx\n",sc->sc_dev.dv_xname,*esc->sc_dmaaddr);
    839      1.20      dbj 	} else {
    840      1.20      dbj 		p += sprintf(p,"%s: sc_dmaaddr=NULL\n",sc->sc_dev.dv_xname);
    841      1.20      dbj 	}
    842      1.20      dbj 	if (esc->sc_dmalen) {
    843      1.20      dbj 		p += sprintf(p,"%s: sc_dmalen=0x%08lx\n",sc->sc_dev.dv_xname,*esc->sc_dmalen);
    844      1.20      dbj 	} else {
    845      1.20      dbj 		p += sprintf(p,"%s: sc_dmalen=NULL\n",sc->sc_dev.dv_xname);
    846      1.20      dbj 	}
    847      1.20      dbj 	p += sprintf(p,"%s: sc_dmasize=0x%08x\n",sc->sc_dev.dv_xname,esc->sc_dmasize);
    848      1.19      dbj 
    849      1.20      dbj 	p += sprintf(p,"%s: sc_begin = 0x%08x, sc_begin_size = 0x%08x\n",
    850      1.20      dbj 			sc->sc_dev.dv_xname, esc->sc_begin, esc->sc_begin_size);
    851      1.20      dbj 	p += sprintf(p,"%s: sc_main = 0x%08x, sc_main_size = 0x%08x\n",
    852      1.20      dbj 			sc->sc_dev.dv_xname, esc->sc_main, esc->sc_main_size);
    853      1.19      dbj 	{
    854      1.19      dbj 		int i;
    855      1.19      dbj 		bus_dmamap_t map = esc->sc_main_dmamap;
    856      1.20      dbj 		p += sprintf(p,"%s: sc_main_dmamap. mapsize = 0x%08x, nsegs = %d\n",
    857      1.20      dbj 				sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs);
    858      1.19      dbj 		for(i=0;i<map->dm_nsegs;i++) {
    859      1.20      dbj 			p += sprintf(p,"%s: map->dm_segs[%d]->ds_addr = 0x%08x, len = 0x%08x\n",
    860      1.20      dbj 			sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len);
    861      1.19      dbj 		}
    862      1.19      dbj 	}
    863      1.20      dbj 	p += sprintf(p,"%s: sc_tail = 0x%08x, sc_tail_size = 0x%08x\n",
    864      1.20      dbj 			sc->sc_dev.dv_xname, esc->sc_tail, esc->sc_tail_size);
    865      1.19      dbj 	{
    866      1.19      dbj 		int i;
    867      1.19      dbj 		bus_dmamap_t map = esc->sc_tail_dmamap;
    868      1.20      dbj 		p += sprintf(p,"%s: sc_tail_dmamap. mapsize = 0x%08x, nsegs = %d\n",
    869      1.20      dbj 				sc->sc_dev.dv_xname, map->dm_mapsize, map->dm_nsegs);
    870      1.19      dbj 		for(i=0;i<map->dm_nsegs;i++) {
    871      1.20      dbj 			p += sprintf(p,"%s: map->dm_segs[%d]->ds_addr = 0x%08x, len = 0x%08x\n",
    872      1.20      dbj 			sc->sc_dev.dv_xname, i, map->dm_segs[i].ds_addr, map->dm_segs[i].ds_len);
    873      1.19      dbj 		}
    874      1.19      dbj 	}
    875      1.20      dbj }
    876      1.20      dbj 
    877      1.20      dbj void
    878      1.20      dbj esp_dma_print(sc)
    879      1.20      dbj 	struct ncr53c9x_softc *sc;
    880      1.20      dbj {
    881      1.20      dbj 	esp_dma_store(sc);
    882      1.20      dbj 	printf("%s",esp_dma_dump);
    883      1.20      dbj }
    884      1.20      dbj #endif
    885      1.20      dbj 
    886      1.20      dbj void
    887      1.20      dbj esp_dma_go(sc)
    888      1.20      dbj 	struct ncr53c9x_softc *sc;
    889      1.20      dbj {
    890      1.20      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
    891      1.20      dbj 
    892      1.20      dbj 	DPRINTF(("%s: esp_dma_go(datain = %d)\n",
    893      1.20      dbj 			sc->sc_dev.dv_xname, esc->sc_datain));
    894      1.20      dbj 
    895      1.20      dbj #ifdef ESP_DEBUG
    896      1.20      dbj 	if (esp_debug) esp_dma_print(sc);
    897      1.20      dbj 	else esp_dma_store(sc);
    898      1.19      dbj #endif
    899       1.4      dbj 
    900      1.20      dbj #ifdef ESP_DEBUG
    901      1.11      dbj 	{
    902      1.11      dbj 		int n = NCR_READ_REG(sc, NCR_FFLAG);
    903      1.20      dbj 		DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
    904      1.20      dbj 				sc->sc_dev.dv_xname,
    905      1.20      dbj 				n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5));
    906       1.4      dbj 	}
    907      1.11      dbj #endif
    908       1.4      dbj 
    909      1.23      dbj 	/* zero length dma transfers are boring */
    910      1.20      dbj 	if (esc->sc_dmasize == 0) {
    911      1.20      dbj 		return;
    912      1.20      dbj 	}
    913      1.20      dbj 
    914      1.18      dbj #if defined(DIAGNOSTIC)
    915      1.18      dbj   if ((esc->sc_begin_size == 0) &&
    916      1.18      dbj 			(esc->sc_main_dmamap->dm_mapsize == 0) &&
    917      1.18      dbj 			(esc->sc_tail_dmamap->dm_mapsize == 0)) {
    918      1.20      dbj 		esp_dma_print(sc);
    919      1.18      dbj 		panic("%s: No DMA requested!",sc->sc_dev.dv_xname);
    920      1.18      dbj 	}
    921      1.18      dbj #endif
    922      1.18      dbj 
    923      1.18      dbj 	/* Stuff the fifo with the begin buffer */
    924      1.18      dbj 	if (esc->sc_datain) {
    925       1.4      dbj 		int i;
    926      1.23      dbj 		DPRINTF(("%s: FIFO read of %d bytes:",
    927      1.23      dbj 				sc->sc_dev.dv_xname,esc->sc_begin_size));
    928      1.18      dbj 		for(i=0;i<esc->sc_begin_size;i++) {
    929      1.24      dbj 			esc->sc_begin[i]=NCR_READ_REG(sc, NCR_FIFO);
    930      1.24      dbj 			DPRINTF((" %02x",esc->sc_begin[i]&0xff));
    931       1.4      dbj 		}
    932      1.23      dbj 		DPRINTF(("\n"));
    933       1.4      dbj 	} else {
    934       1.4      dbj 		int i;
    935      1.23      dbj 		DPRINTF(("%s: FIFO write of %d bytes:",
    936      1.23      dbj 				sc->sc_dev.dv_xname,esc->sc_begin_size));
    937      1.18      dbj 		for(i=0;i<esc->sc_begin_size;i++) {
    938      1.18      dbj 			NCR_WRITE_REG(sc, NCR_FIFO, esc->sc_begin[i]);
    939      1.24      dbj 			DPRINTF((" %02x",esc->sc_begin[i]&0xff));
    940       1.4      dbj 		}
    941      1.23      dbj 		DPRINTF(("\n"));
    942      1.11      dbj 	}
    943       1.4      dbj 
    944      1.14      dbj 	/* if we are a dma write cycle, copy the end slop */
    945      1.14      dbj 	if (esc->sc_datain == 0) {
    946      1.18      dbj 		memcpy(esc->sc_tail,
    947      1.18      dbj 				(*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size),
    948      1.18      dbj 				(esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size)));
    949      1.14      dbj 	}
    950      1.17      dbj 
    951      1.23      dbj 	if (esc->sc_main_dmamap->dm_mapsize) {
    952      1.23      dbj 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
    953      1.23      dbj 				0, esc->sc_main_dmamap->dm_mapsize,
    954      1.23      dbj 				(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
    955      1.23      dbj 	}
    956      1.23      dbj 
    957      1.23      dbj 	if (esc->sc_tail_dmamap->dm_mapsize) {
    958      1.23      dbj 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
    959      1.23      dbj 				0, esc->sc_tail_dmamap->dm_mapsize,
    960      1.23      dbj 				(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
    961      1.23      dbj 	}
    962      1.23      dbj 
    963      1.14      dbj 	nextdma_start(&esc->sc_scsi_dma,
    964      1.25      dbj 			(esc->sc_datain ? DMACSR_SETREAD : DMACSR_SETWRITE));
    965      1.12      dbj 
    966      1.14      dbj 	if (esc->sc_datain) {
    967      1.14      dbj 		NCR_WRITE_REG(sc, ESP_DCTL,
    968      1.14      dbj 				ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD | ESPDCTL_DMARD);
    969       1.3      dbj 	} else {
    970      1.14      dbj 		NCR_WRITE_REG(sc, ESP_DCTL,
    971      1.14      dbj 				ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMAMOD);
    972       1.3      dbj 	}
    973      1.22      dbj 	DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
    974       1.1      dbj }
    975       1.1      dbj 
    976       1.1      dbj void
    977       1.1      dbj esp_dma_stop(sc)
    978       1.1      dbj 	struct ncr53c9x_softc *sc;
    979       1.1      dbj {
    980       1.1      dbj 	panic("Not yet implemented");
    981       1.1      dbj }
    982       1.1      dbj 
    983       1.1      dbj int
    984       1.1      dbj esp_dma_isactive(sc)
    985       1.1      dbj 	struct ncr53c9x_softc *sc;
    986       1.1      dbj {
    987       1.1      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
    988      1.11      dbj 	int r = !nextdma_finished(&esc->sc_scsi_dma);
    989      1.11      dbj 	DPRINTF(("esp_dma_isactive = %d\n",r));
    990      1.11      dbj 	return(r);
    991       1.2      dbj }
    992       1.2      dbj 
    993       1.2      dbj /****************************************************************/
    994       1.2      dbj 
    995       1.2      dbj /* Internal dma callback routines */
    996       1.2      dbj bus_dmamap_t
    997       1.2      dbj esp_dmacb_continue(arg)
    998       1.2      dbj 	void *arg;
    999       1.2      dbj {
   1000       1.2      dbj 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
   1001       1.2      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
   1002       1.2      dbj 
   1003      1.18      dbj 	DPRINTF(("%s: dma continue\n",sc->sc_dev.dv_xname));
   1004       1.4      dbj 
   1005       1.2      dbj #ifdef DIAGNOSTIC
   1006       1.2      dbj 	if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) {
   1007       1.2      dbj 		panic("%s: map not loaded in dma continue callback, datain = %d",
   1008       1.2      dbj 				sc->sc_dev.dv_xname,esc->sc_datain);
   1009       1.2      dbj 	}
   1010       1.2      dbj #endif
   1011      1.18      dbj 
   1012      1.18      dbj 	if ((!(esc->sc_loaded & ESP_LOADED_MAIN)) &&
   1013      1.18      dbj 			(esc->sc_main_dmamap->dm_mapsize)) {
   1014      1.18      dbj 			DPRINTF(("%s: Loading main map\n",sc->sc_dev.dv_xname));
   1015      1.19      dbj #if 0
   1016      1.18      dbj 			bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
   1017      1.18      dbj 					0, esc->sc_main_dmamap->dm_mapsize,
   1018      1.14      dbj 					(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
   1019      1.19      dbj #endif
   1020      1.18      dbj 			esc->sc_loaded |= ESP_LOADED_MAIN;
   1021      1.18      dbj 			return(esc->sc_main_dmamap);
   1022      1.18      dbj 	}
   1023      1.18      dbj 
   1024      1.18      dbj 	if ((!(esc->sc_loaded & ESP_LOADED_TAIL)) &&
   1025      1.18      dbj 			(esc->sc_tail_dmamap->dm_mapsize)) {
   1026      1.18      dbj 			DPRINTF(("%s: Loading tail map\n",sc->sc_dev.dv_xname));
   1027      1.19      dbj #if 0
   1028      1.14      dbj 			bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
   1029      1.14      dbj 					0, esc->sc_tail_dmamap->dm_mapsize,
   1030      1.14      dbj 					(esc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
   1031      1.19      dbj #endif
   1032      1.18      dbj 			esc->sc_loaded |= ESP_LOADED_TAIL;
   1033      1.14      dbj 			return(esc->sc_tail_dmamap);
   1034      1.10      dbj 	}
   1035      1.18      dbj 
   1036      1.18      dbj 	DPRINTF(("%s: not loading map\n",sc->sc_dev.dv_xname));
   1037      1.18      dbj 	return(0);
   1038       1.2      dbj }
   1039       1.2      dbj 
   1040      1.14      dbj 
   1041       1.2      dbj void
   1042       1.2      dbj esp_dmacb_completed(map, arg)
   1043       1.2      dbj 	bus_dmamap_t map;
   1044       1.2      dbj 	void *arg;
   1045       1.2      dbj {
   1046       1.2      dbj 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
   1047       1.2      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
   1048       1.2      dbj 
   1049      1.20      dbj 	DPRINTF(("%s: dma completed\n",sc->sc_dev.dv_xname));
   1050       1.4      dbj 
   1051       1.2      dbj #ifdef DIAGNOSTIC
   1052      1.14      dbj 	if ((esc->sc_datain < 0) || (esc->sc_datain > 1)) {
   1053      1.18      dbj 		panic("%s: invalid dma direction in completed callback, datain = %d",
   1054      1.18      dbj 				sc->sc_dev.dv_xname,esc->sc_datain);
   1055       1.2      dbj 	}
   1056      1.23      dbj #endif
   1057      1.23      dbj 
   1058      1.23      dbj 	if (map == esc->sc_main_dmamap) {
   1059      1.23      dbj #ifdef DIAGNOSTIC
   1060      1.23      dbj 		if ((esc->sc_loaded & ESP_UNLOADED_MAIN) ||
   1061      1.23      dbj 				!(esc->sc_loaded & ESP_LOADED_MAIN)) {
   1062      1.23      dbj 			panic("%s: unexpected completed call for main map\n",sc->sc_dev.dv_xname);
   1063      1.23      dbj 		}
   1064      1.23      dbj #endif
   1065      1.23      dbj 		esc->sc_loaded |= ESP_UNLOADED_MAIN;
   1066      1.23      dbj 	} else if (map == esc->sc_tail_dmamap) {
   1067      1.23      dbj #ifdef DIAGNOSTIC
   1068      1.23      dbj 		if ((esc->sc_loaded & ESP_UNLOADED_TAIL) ||
   1069      1.23      dbj 				!(esc->sc_loaded & ESP_LOADED_TAIL)) {
   1070      1.23      dbj 			panic("%s: unexpected completed call for tail map\n",sc->sc_dev.dv_xname);
   1071      1.23      dbj 		}
   1072      1.23      dbj #endif
   1073      1.23      dbj 		esc->sc_loaded |= ESP_UNLOADED_TAIL;
   1074      1.23      dbj 	}
   1075      1.23      dbj #ifdef DIAGNOSTIC
   1076      1.23      dbj 	 else {
   1077      1.14      dbj 		panic("%s: unexpected completed map", sc->sc_dev.dv_xname);
   1078       1.2      dbj 	}
   1079       1.2      dbj #endif
   1080       1.2      dbj 
   1081      1.23      dbj #ifdef ESP_DEBUG
   1082      1.23      dbj 	if (esp_debug) {
   1083      1.23      dbj 		if (map == esc->sc_main_dmamap) {
   1084      1.23      dbj 			printf("%s: completed main map\n",sc->sc_dev.dv_xname);
   1085      1.23      dbj 		} else if (map == esc->sc_tail_dmamap) {
   1086      1.23      dbj 			printf("%s: completed tail map\n",sc->sc_dev.dv_xname);
   1087      1.23      dbj 		}
   1088      1.23      dbj 	}
   1089      1.23      dbj #endif
   1090      1.22      dbj 
   1091      1.22      dbj #if 0
   1092      1.22      dbj 	if ((map == esc->sc_tail_dmamap) ||
   1093      1.22      dbj 			((esc->sc_tail_size == 0) && (map == esc->sc_main_dmamap))) {
   1094      1.22      dbj 
   1095      1.22      dbj 		/* Clear the DMAMOD bit in the DCTL register to give control
   1096      1.22      dbj 		 * back to the scsi chip.
   1097      1.22      dbj 		 */
   1098      1.22      dbj 		if (esc->sc_datain) {
   1099      1.22      dbj 			NCR_WRITE_REG(sc, ESP_DCTL,
   1100      1.22      dbj 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
   1101      1.22      dbj 		} else {
   1102      1.22      dbj 			NCR_WRITE_REG(sc, ESP_DCTL,
   1103      1.22      dbj 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
   1104      1.22      dbj 		}
   1105      1.22      dbj 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
   1106      1.22      dbj 	}
   1107      1.22      dbj #endif
   1108      1.22      dbj 
   1109      1.22      dbj 
   1110      1.19      dbj #if 0
   1111      1.14      dbj 	bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, map,
   1112      1.14      dbj 			0, map->dm_mapsize,
   1113       1.2      dbj 			(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
   1114      1.19      dbj #endif
   1115      1.13      dbj 
   1116       1.2      dbj }
   1117       1.2      dbj 
   1118       1.2      dbj void
   1119       1.2      dbj esp_dmacb_shutdown(arg)
   1120       1.2      dbj 	void *arg;
   1121       1.2      dbj {
   1122       1.2      dbj 	struct ncr53c9x_softc *sc = (struct ncr53c9x_softc *)arg;
   1123       1.2      dbj 	struct esp_softc *esc = (struct esp_softc *)sc;
   1124       1.2      dbj 
   1125      1.20      dbj 	DPRINTF(("%s: dma shutdown\n",sc->sc_dev.dv_xname));
   1126       1.4      dbj 
   1127      1.22      dbj #if 0
   1128      1.22      dbj 	{
   1129      1.22      dbj 		/* Clear the DMAMOD bit in the DCTL register to give control
   1130      1.22      dbj 		 * back to the scsi chip.
   1131      1.22      dbj 		 */
   1132      1.22      dbj 		if (esc->sc_datain) {
   1133      1.22      dbj 			NCR_WRITE_REG(sc, ESP_DCTL,
   1134      1.22      dbj 					ESPDCTL_20MHZ | ESPDCTL_INTENB | ESPDCTL_DMARD);
   1135      1.22      dbj 		} else {
   1136      1.22      dbj 			NCR_WRITE_REG(sc, ESP_DCTL,
   1137      1.22      dbj 					ESPDCTL_20MHZ | ESPDCTL_INTENB);
   1138      1.22      dbj 		}
   1139      1.22      dbj 		DPRINTF(("esp dctl is 0x%02x\n",NCR_READ_REG(sc,ESP_DCTL)));
   1140      1.22      dbj 	}
   1141      1.22      dbj #endif
   1142      1.22      dbj 
   1143      1.22      dbj 	DPRINTF(("%s: esp_dma_nest == %d\n",sc->sc_dev.dv_xname,esp_dma_nest));
   1144      1.22      dbj 
   1145      1.13      dbj 	/* Stuff the end slop into fifo */
   1146       1.3      dbj 
   1147      1.14      dbj #ifdef ESP_DEBUG
   1148      1.14      dbj 	if (esp_debug) {
   1149      1.14      dbj 
   1150      1.13      dbj 		int n = NCR_READ_REG(sc, NCR_FFLAG);
   1151      1.20      dbj 		DPRINTF(("%s: fifo size = %d, seq = 0x%x\n",
   1152      1.20      dbj 				sc->sc_dev.dv_xname,n & NCRFIFO_FF, (n & NCRFIFO_SS)>>5));
   1153      1.13      dbj 	}
   1154      1.13      dbj #endif
   1155      1.12      dbj 
   1156      1.22      dbj 	if (esc->sc_main_dmamap->dm_mapsize) {
   1157      1.22      dbj 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap,
   1158      1.22      dbj 			0, esc->sc_main_dmamap->dm_mapsize,
   1159      1.22      dbj 				(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
   1160      1.22      dbj 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_main_dmamap);
   1161      1.22      dbj 	}
   1162      1.22      dbj 
   1163      1.22      dbj 	if (esc->sc_tail_dmamap->dm_mapsize) {
   1164      1.22      dbj 		bus_dmamap_sync(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap,
   1165      1.22      dbj 			0, esc->sc_tail_dmamap->dm_mapsize,
   1166      1.22      dbj 				(esc->sc_datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
   1167      1.22      dbj 		bus_dmamap_unload(esc->sc_scsi_dma.nd_dmat, esc->sc_tail_dmamap);
   1168      1.22      dbj 	}
   1169      1.22      dbj 
   1170      1.22      dbj 	/* copy the tail dma buffer data for read transfers */
   1171      1.18      dbj 	if (esc->sc_datain == 1) {
   1172      1.18      dbj 		memcpy((*esc->sc_dmaaddr+esc->sc_begin_size+esc->sc_main_size),
   1173      1.18      dbj 				esc->sc_tail,
   1174      1.18      dbj 				(esc->sc_dmasize-(esc->sc_begin_size+esc->sc_main_size)));
   1175       1.4      dbj 	}
   1176      1.13      dbj 
   1177      1.18      dbj #ifdef ESP_DEBUG
   1178      1.18      dbj 	if (esp_debug) {
   1179      1.18      dbj 		printf("%s: dma_shutdown: addr=0x%08lx,len=0x%08lx,size=0x%08lx\n",
   1180      1.18      dbj 				sc->sc_dev.dv_xname,
   1181      1.18      dbj 				*esc->sc_dmaaddr, *esc->sc_dmalen, esc->sc_dmasize);
   1182      1.24      dbj 		if (esp_debug > 10) {
   1183      1.24      dbj 			esp_hex_dump(*(esc->sc_dmaaddr),esc->sc_dmasize);
   1184      1.24      dbj 			printf("%s: tail=0x%08lx,tailbuf=0x%08lx,tail_size=0x%08lx\n",
   1185      1.24      dbj 					sc->sc_dev.dv_xname,
   1186      1.24      dbj 					esc->sc_tail, &(esc->sc_tailbuf[0]), esc->sc_tail_size);
   1187      1.24      dbj 			esp_hex_dump(&(esc->sc_tailbuf[0]),sizeof(esc->sc_tailbuf));
   1188      1.24      dbj 		}
   1189      1.13      dbj 	}
   1190      1.11      dbj #endif
   1191       1.3      dbj 
   1192      1.22      dbj 	*(esc->sc_dmaaddr) += esc->sc_dmasize;
   1193      1.22      dbj 	*(esc->sc_dmalen)  -= esc->sc_dmasize;
   1194      1.22      dbj 
   1195      1.18      dbj 	esc->sc_main = 0;
   1196      1.18      dbj 	esc->sc_main_size = 0;
   1197      1.14      dbj 	esc->sc_tail = 0;
   1198      1.14      dbj 	esc->sc_tail_size = 0;
   1199      1.19      dbj 
   1200      1.19      dbj 	esc->sc_datain = -1;
   1201      1.19      dbj 	esc->sc_dmaaddr = 0;
   1202      1.19      dbj 	esc->sc_dmalen  = 0;
   1203      1.20      dbj 	esc->sc_dmasize = 0;
   1204      1.19      dbj 
   1205      1.19      dbj 	esc->sc_loaded = 0;
   1206      1.19      dbj 
   1207      1.19      dbj 	esc->sc_begin = 0;
   1208      1.19      dbj 	esc->sc_begin_size = 0;
   1209      1.20      dbj 
   1210      1.20      dbj #ifdef ESP_DEBUG
   1211      1.20      dbj 	if (esp_debug) {
   1212  1.25.2.1   bouyer 		char sbuf[256];
   1213  1.25.2.1   bouyer 
   1214  1.25.2.1   bouyer 		bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRSTAT)),
   1215  1.25.2.1   bouyer 				 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
   1216  1.25.2.1   bouyer 		printf("  *intrstat = 0x%s\n", sbuf);
   1217  1.25.2.1   bouyer 
   1218  1.25.2.1   bouyer 		bitmask_snprintf((*(volatile u_long *)IIOV(NEXT_P_INTRMASK)),
   1219  1.25.2.1   bouyer 				 NEXT_INTR_BITS, sbuf, sizeof(sbuf));
   1220  1.25.2.1   bouyer 		printf("  *intrmask = 0x%s\n", sbuf);
   1221      1.20      dbj 	}
   1222      1.20      dbj #endif
   1223       1.1      dbj }
   1224