Home | History | Annotate | Line # | Download | only in dev
si.c revision 1.12.2.3
      1  1.12.2.3    skrll /*	$NetBSD: si.c,v 1.12.2.3 2004/09/18 14:37:58 skrll Exp $	*/
      2       1.1  tsutsui 
      3       1.1  tsutsui /*
      4       1.1  tsutsui  * Copyright (c) 1996 The NetBSD Foundation, Inc.
      5       1.1  tsutsui  * All rights reserved.
      6       1.1  tsutsui  *
      7       1.1  tsutsui  * This code is derived from software contributed to The NetBSD Foundation
      8       1.1  tsutsui  * by Adam Glass, David Jones, Gordon W. Ross, and Jens A. Nilsson.
      9       1.1  tsutsui  *
     10       1.1  tsutsui  * Redistribution and use in source and binary forms, with or without
     11       1.1  tsutsui  * modification, are permitted provided that the following conditions
     12       1.1  tsutsui  * are met:
     13       1.1  tsutsui  * 1. Redistributions of source code must retain the above copyright
     14       1.1  tsutsui  *    notice, this list of conditions and the following disclaimer.
     15       1.1  tsutsui  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1  tsutsui  *    notice, this list of conditions and the following disclaimer in the
     17       1.1  tsutsui  *    documentation and/or other materials provided with the distribution.
     18       1.1  tsutsui  * 3. All advertising materials mentioning features or use of this software
     19       1.1  tsutsui  *    must display the following acknowledgement:
     20       1.1  tsutsui  *	This product includes software developed by the NetBSD
     21       1.1  tsutsui  *	Foundation, Inc. and its contributors.
     22       1.1  tsutsui  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23       1.1  tsutsui  *    contributors may be used to endorse or promote products derived
     24       1.1  tsutsui  *    from this software without specific prior written permission.
     25       1.1  tsutsui  *
     26       1.1  tsutsui  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27       1.1  tsutsui  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28       1.1  tsutsui  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29       1.1  tsutsui  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30       1.1  tsutsui  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31       1.1  tsutsui  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32       1.1  tsutsui  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33       1.1  tsutsui  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34       1.1  tsutsui  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35       1.1  tsutsui  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36       1.1  tsutsui  * POSSIBILITY OF SUCH DAMAGE.
     37       1.1  tsutsui  */
     38       1.1  tsutsui 
     39       1.1  tsutsui /*
     40       1.1  tsutsui  * This file contains the machine-dependent parts of the Sony CXD1180
     41       1.1  tsutsui  * controller. The machine-independent parts are in ncr5380sbc.c.
     42       1.1  tsutsui  * Written by Izumi Tsutsui.
     43      1.12  tsutsui  *
     44       1.1  tsutsui  * This code is based on arch/vax/vsa/ncr.c and sun3/dev/si.c
     45       1.1  tsutsui  */
     46       1.1  tsutsui 
     47  1.12.2.1    skrll #include <sys/cdefs.h>
     48  1.12.2.3    skrll __KERNEL_RCSID(0, "$NetBSD: si.c,v 1.12.2.3 2004/09/18 14:37:58 skrll Exp $");
     49  1.12.2.1    skrll 
     50       1.1  tsutsui #include <sys/param.h>
     51       1.1  tsutsui #include <sys/systm.h>
     52       1.1  tsutsui #include <sys/device.h>
     53       1.1  tsutsui #include <sys/buf.h>
     54       1.2  tsutsui 
     55       1.2  tsutsui #include <machine/cpu.h>
     56      1.10      chs #include <m68k/cacheops.h>
     57       1.1  tsutsui 
     58       1.1  tsutsui #include <dev/scsipi/scsipi_all.h>
     59       1.1  tsutsui #include <dev/scsipi/scsiconf.h>
     60       1.1  tsutsui 
     61       1.1  tsutsui #include <dev/ic/ncr5380reg.h>
     62       1.1  tsutsui #include <dev/ic/ncr5380var.h>
     63       1.1  tsutsui 
     64       1.1  tsutsui #include <news68k/dev/hbvar.h>
     65       1.1  tsutsui #include <news68k/dev/dmac_0266.h>
     66       1.1  tsutsui 
     67  1.12.2.3    skrll #include "ioconf.h"
     68  1.12.2.3    skrll 
     69       1.1  tsutsui #define MIN_DMA_LEN 128
     70       1.3  tsutsui #define DMAC_BASE	0xe0e80000 /* XXX */
     71  1.12.2.2    skrll #define SI_REGSIZE	8
     72       1.1  tsutsui 
     73       1.1  tsutsui struct si_dma_handle {
     74       1.1  tsutsui 	int	dh_flags;
     75       1.1  tsutsui #define SIDH_BUSY	0x01
     76       1.1  tsutsui #define SIDH_OUT	0x02
     77       1.1  tsutsui 	caddr_t dh_addr;
     78       1.1  tsutsui 	int	dh_len;
     79       1.1  tsutsui };
     80       1.1  tsutsui 
     81       1.1  tsutsui struct si_softc {
     82       1.1  tsutsui 	struct	ncr5380_softc	ncr_sc;
     83       1.1  tsutsui 	int	sc_options;
     84       1.1  tsutsui 	volatile struct dma_regs *sc_regs;
     85       1.1  tsutsui 	struct	si_dma_handle ncr_dma[SCI_OPENINGS];
     86       1.1  tsutsui };
     87       1.1  tsutsui 
     88  1.12.2.3    skrll static void si_attach(struct device *, struct device *, void *);
     89  1.12.2.3    skrll static int  si_match(struct device *, struct cfdata *, void *);
     90      1.11  tsutsui int  si_intr(int);
     91      1.11  tsutsui 
     92  1.12.2.3    skrll static void si_dma_alloc(struct ncr5380_softc *);
     93  1.12.2.3    skrll static void si_dma_free(struct ncr5380_softc *);
     94  1.12.2.3    skrll static void si_dma_setup(struct ncr5380_softc *);
     95  1.12.2.3    skrll static void si_dma_start(struct ncr5380_softc *);
     96  1.12.2.3    skrll static void si_dma_poll(struct ncr5380_softc *);
     97  1.12.2.3    skrll static void si_dma_eop(struct ncr5380_softc *);
     98  1.12.2.3    skrll static void si_dma_stop(struct ncr5380_softc *);
     99       1.1  tsutsui 
    100       1.9  thorpej CFATTACH_DECL(si, sizeof(struct si_softc),
    101       1.9  thorpej     si_match, si_attach, NULL, NULL);
    102       1.1  tsutsui 
    103       1.1  tsutsui /*
    104       1.1  tsutsui  * Options for disconnect/reselect, DMA, and interrupts.
    105       1.1  tsutsui  * By default, allow disconnect/reselect on targets 4-6.
    106       1.1  tsutsui  * Those are normally tapes that really need it enabled.
    107       1.1  tsutsui  * The options are taken from the config file.
    108       1.1  tsutsui  */
    109       1.1  tsutsui #define SI_NO_DISCONNECT	0x000ff
    110       1.1  tsutsui #define SI_NO_PARITY_CHK	0x0ff00
    111       1.1  tsutsui #define SI_FORCE_POLLING	0x10000
    112       1.1  tsutsui #define SI_DISABLE_DMA		0x20000
    113       1.1  tsutsui 
    114       1.1  tsutsui int si_options = 0x0f;
    115       1.1  tsutsui 
    116       1.1  tsutsui 
    117  1.12.2.3    skrll static int
    118  1.12.2.3    skrll si_match(struct device *parent, struct cfdata *cf, void *aux)
    119       1.1  tsutsui {
    120       1.1  tsutsui 	struct hb_attach_args *ha = aux;
    121       1.1  tsutsui 	int addr;
    122       1.1  tsutsui 
    123       1.1  tsutsui 	if (strcmp(ha->ha_name, "si"))
    124       1.1  tsutsui 		return 0;
    125       1.1  tsutsui 
    126       1.3  tsutsui 	addr = IIOV(ha->ha_address);
    127       1.1  tsutsui 
    128       1.1  tsutsui 	if (badaddr((void *)addr, 1))
    129       1.1  tsutsui 		return 0;
    130       1.1  tsutsui 
    131  1.12.2.2    skrll 	ha->ha_size = SI_REGSIZE;
    132  1.12.2.2    skrll 
    133       1.1  tsutsui 	return 1;
    134       1.1  tsutsui }
    135       1.1  tsutsui 
    136       1.1  tsutsui /*
    137       1.1  tsutsui  * Card attach function
    138       1.1  tsutsui  */
    139       1.1  tsutsui 
    140  1.12.2.3    skrll static void
    141  1.12.2.3    skrll si_attach(struct device *parent, struct device *self, void *aux)
    142       1.1  tsutsui {
    143       1.1  tsutsui 	struct si_softc *sc = (struct si_softc *)self;
    144       1.1  tsutsui 	struct ncr5380_softc *ncr_sc = &sc->ncr_sc;
    145       1.1  tsutsui 	struct cfdata *cf = self->dv_cfdata;
    146       1.3  tsutsui 	struct hb_attach_args *ha = aux;
    147  1.12.2.2    skrll 
    148  1.12.2.2    skrll 	ncr_sc->sc_regt = ha->ha_bust;
    149  1.12.2.2    skrll 	if (bus_space_map(ncr_sc->sc_regt, (bus_addr_t)ha->ha_address,
    150  1.12.2.2    skrll 	    ha->ha_size, 0, &ncr_sc->sc_regh) != 0) {
    151  1.12.2.2    skrll 		printf("can't map device space\n");
    152  1.12.2.2    skrll 		return;
    153  1.12.2.2    skrll 	}
    154       1.1  tsutsui 
    155       1.1  tsutsui 	/* Get options from config flags if specified. */
    156       1.1  tsutsui 	if (cf->cf_flags)
    157       1.1  tsutsui 		sc->sc_options = cf->cf_flags;
    158       1.1  tsutsui 	else
    159       1.1  tsutsui 		sc->sc_options = si_options;
    160       1.1  tsutsui 
    161       1.1  tsutsui 	printf(": options=0x%x\n", sc->sc_options);
    162       1.1  tsutsui 
    163       1.1  tsutsui 	ncr_sc->sc_no_disconnect = (sc->sc_options & SI_NO_DISCONNECT);
    164       1.1  tsutsui 	ncr_sc->sc_parity_disable = (sc->sc_options & SI_NO_PARITY_CHK) >> 8;
    165       1.1  tsutsui 	if (sc->sc_options & SI_FORCE_POLLING)
    166       1.1  tsutsui 		ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
    167       1.1  tsutsui 
    168       1.1  tsutsui 	ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
    169       1.1  tsutsui 	ncr_sc->sc_dma_alloc   = si_dma_alloc;
    170       1.1  tsutsui 	ncr_sc->sc_dma_free    = si_dma_free;
    171       1.1  tsutsui 	ncr_sc->sc_dma_poll    = si_dma_poll;
    172       1.1  tsutsui 	ncr_sc->sc_dma_setup   = si_dma_setup;
    173       1.1  tsutsui 	ncr_sc->sc_dma_start   = si_dma_start;
    174       1.1  tsutsui 	ncr_sc->sc_dma_eop     = si_dma_eop;
    175       1.1  tsutsui 	ncr_sc->sc_dma_stop    = si_dma_stop;
    176       1.1  tsutsui 
    177       1.1  tsutsui 	if (sc->sc_options & SI_DISABLE_DMA)
    178       1.1  tsutsui 		/* Override this function pointer. */
    179       1.1  tsutsui 		ncr_sc->sc_dma_alloc = NULL;
    180       1.1  tsutsui 
    181  1.12.2.2    skrll 	ncr_sc->sci_r0 = 0;
    182  1.12.2.2    skrll 	ncr_sc->sci_r1 = 1;
    183  1.12.2.2    skrll 	ncr_sc->sci_r2 = 2;
    184  1.12.2.2    skrll 	ncr_sc->sci_r3 = 3;
    185  1.12.2.2    skrll 	ncr_sc->sci_r4 = 4;
    186  1.12.2.2    skrll 	ncr_sc->sci_r5 = 5;
    187  1.12.2.2    skrll 	ncr_sc->sci_r6 = 6;
    188  1.12.2.2    skrll 	ncr_sc->sci_r7 = 7;
    189       1.5  tsutsui 
    190       1.5  tsutsui 	ncr_sc->sc_rev = NCR_VARIANT_CXD1180;
    191       1.1  tsutsui 
    192       1.1  tsutsui 	ncr_sc->sc_pio_in  = ncr5380_pio_in;
    193       1.1  tsutsui 	ncr_sc->sc_pio_out = ncr5380_pio_out;
    194       1.1  tsutsui 
    195       1.6   bouyer 	ncr_sc->sc_adapter.adapt_minphys = minphys;
    196       1.6   bouyer 	ncr_sc->sc_channel.chan_id = 7;
    197       1.1  tsutsui 
    198       1.1  tsutsui 	/* soft reset DMAC */
    199       1.1  tsutsui 	sc->sc_regs = (void *)IIOV(DMAC_BASE);
    200       1.1  tsutsui 	sc->sc_regs->ctl = DC_CTL_RST;
    201       1.1  tsutsui 
    202       1.4  tsutsui 	ncr5380_attach(ncr_sc);
    203       1.1  tsutsui }
    204       1.1  tsutsui 
    205       1.1  tsutsui int
    206  1.12.2.3    skrll si_intr(int unit)
    207       1.1  tsutsui {
    208       1.1  tsutsui 	struct si_softc *sc;
    209       1.1  tsutsui 
    210       1.1  tsutsui 	if (unit >= si_cd.cd_ndevs)
    211       1.1  tsutsui 		return 0;
    212       1.1  tsutsui 
    213       1.1  tsutsui 	sc = si_cd.cd_devs[unit];
    214       1.1  tsutsui 	(void)ncr5380_intr(&sc->ncr_sc);
    215       1.1  tsutsui 
    216       1.1  tsutsui 	return 0;
    217       1.1  tsutsui }
    218       1.1  tsutsui 
    219       1.1  tsutsui /*
    220       1.1  tsutsui  *  DMA routines for news1700 machines
    221       1.1  tsutsui  */
    222       1.1  tsutsui 
    223  1.12.2.3    skrll static void
    224  1.12.2.3    skrll si_dma_alloc(struct ncr5380_softc *ncr_sc)
    225       1.1  tsutsui {
    226       1.1  tsutsui 	struct si_softc *sc = (struct si_softc *)ncr_sc;
    227       1.1  tsutsui 	struct sci_req *sr = ncr_sc->sc_current;
    228       1.1  tsutsui 	struct scsipi_xfer *xs = sr->sr_xs;
    229       1.1  tsutsui 	struct si_dma_handle *dh;
    230       1.1  tsutsui 	int xlen, i;
    231       1.1  tsutsui 
    232       1.1  tsutsui #ifdef DIAGNOSTIC
    233       1.1  tsutsui 	if (sr->sr_dma_hand != NULL)
    234       1.1  tsutsui 		panic("si_dma_alloc: already have DMA handle");
    235       1.1  tsutsui #endif
    236       1.1  tsutsui 
    237       1.1  tsutsui 	/* Polled transfers shouldn't allocate a DMA handle. */
    238       1.1  tsutsui 	if (sr->sr_flags & SR_IMMED)
    239       1.1  tsutsui 		return;
    240       1.1  tsutsui 
    241       1.1  tsutsui 	xlen = ncr_sc->sc_datalen;
    242       1.1  tsutsui 
    243       1.1  tsutsui 	/* Make sure our caller checked sc_min_dma_len. */
    244       1.1  tsutsui 	if (xlen < MIN_DMA_LEN)
    245       1.7   provos 		panic("si_dma_alloc: len=0x%x", xlen);
    246       1.1  tsutsui 
    247       1.1  tsutsui 	/*
    248       1.1  tsutsui 	 * Find free DMA handle.  Guaranteed to find one since we
    249       1.1  tsutsui 	 * have as many DMA handles as the driver has processes.
    250       1.1  tsutsui 	 * (instances?)
    251       1.1  tsutsui 	 */
    252       1.1  tsutsui 	 for (i = 0; i < SCI_OPENINGS; i++) {
    253       1.1  tsutsui 		if ((sc->ncr_dma[i].dh_flags & SIDH_BUSY) == 0)
    254       1.1  tsutsui 			goto found;
    255       1.1  tsutsui 	}
    256       1.1  tsutsui 	panic("si_dma_alloc(): no free DMA handles");
    257      1.12  tsutsui  found:
    258       1.1  tsutsui 	dh = &sc->ncr_dma[i];
    259       1.1  tsutsui 	dh->dh_flags = SIDH_BUSY;
    260       1.1  tsutsui 	dh->dh_addr = ncr_sc->sc_dataptr;
    261       1.1  tsutsui 	dh->dh_len = xlen;
    262       1.1  tsutsui 
    263       1.1  tsutsui 	/* Remember dest buffer parameters */
    264       1.1  tsutsui 	if (xs->xs_control & XS_CTL_DATA_OUT)
    265       1.1  tsutsui 		dh->dh_flags |= SIDH_OUT;
    266       1.1  tsutsui 
    267       1.1  tsutsui 	sr->sr_dma_hand = dh;
    268       1.1  tsutsui }
    269       1.1  tsutsui 
    270  1.12.2.3    skrll static void
    271  1.12.2.3    skrll si_dma_free(struct ncr5380_softc *ncr_sc)
    272       1.1  tsutsui {
    273       1.1  tsutsui 	struct sci_req *sr = ncr_sc->sc_current;
    274       1.1  tsutsui 	struct si_dma_handle *dh = sr->sr_dma_hand;
    275       1.1  tsutsui 
    276       1.1  tsutsui 	if (dh->dh_flags & SIDH_BUSY)
    277       1.1  tsutsui 		dh->dh_flags = 0;
    278       1.1  tsutsui 	else
    279       1.1  tsutsui 		printf("si_dma_free: free'ing unused buffer\n");
    280       1.1  tsutsui 
    281       1.1  tsutsui 	sr->sr_dma_hand = NULL;
    282       1.1  tsutsui }
    283       1.1  tsutsui 
    284  1.12.2.3    skrll static void
    285  1.12.2.3    skrll si_dma_setup(struct ncr5380_softc *ncr_sc)
    286       1.1  tsutsui {
    287      1.12  tsutsui 
    288       1.1  tsutsui 	/* Do nothing here */
    289       1.1  tsutsui }
    290       1.1  tsutsui 
    291  1.12.2.3    skrll static void
    292  1.12.2.3    skrll si_dma_start(struct ncr5380_softc *ncr_sc)
    293       1.1  tsutsui {
    294       1.1  tsutsui 	struct si_softc *sc = (struct si_softc *)ncr_sc;
    295       1.1  tsutsui 	volatile struct dma_regs *dmac = sc->sc_regs;
    296       1.1  tsutsui 	struct sci_req *sr = ncr_sc->sc_current;
    297       1.1  tsutsui 	struct si_dma_handle *dh = sr->sr_dma_hand;
    298       1.1  tsutsui 	u_int addr, offset, rest;
    299       1.1  tsutsui 	long len;
    300       1.1  tsutsui 	int i;
    301       1.1  tsutsui 
    302       1.1  tsutsui 	/*
    303       1.1  tsutsui 	 * Set the news68k-specific registers.
    304       1.1  tsutsui 	 */
    305       1.1  tsutsui 
    306       1.1  tsutsui 	/* reset DMAC */
    307       1.1  tsutsui 	dmac->ctl = DC_CTL_RST;
    308       1.1  tsutsui 	dmac->ctl = 0;
    309       1.1  tsutsui 
    310       1.1  tsutsui 	addr = (u_int)dh->dh_addr;
    311       1.1  tsutsui 	offset = addr & DMAC_SEG_OFFSET;
    312       1.1  tsutsui 	len = (u_int)dh->dh_len;
    313       1.1  tsutsui 
    314       1.1  tsutsui 	/* set DMA transfer length and offset of first segment */
    315       1.1  tsutsui 	dmac->tcnt = len;
    316       1.1  tsutsui 	dmac->offset = offset;
    317       1.1  tsutsui 
    318       1.1  tsutsui 	/* set first DMA segment address */
    319       1.1  tsutsui 	dmac->tag = 0;
    320       1.1  tsutsui 	dmac->mapent = kvtop((caddr_t)addr) >> DMAC_SEG_SHIFT;
    321       1.1  tsutsui 	rest = DMAC_SEG_SIZE - offset;
    322       1.1  tsutsui 	addr += rest;
    323       1.1  tsutsui 	len -= rest;
    324       1.1  tsutsui 
    325       1.1  tsutsui 	/* set all the rest segments */
    326       1.1  tsutsui 	for (i = 1; len > 0; i++) {
    327       1.1  tsutsui 		dmac->tag = i;
    328       1.1  tsutsui 		dmac->mapent = kvtop((caddr_t)addr) >> DMAC_SEG_SHIFT;
    329       1.1  tsutsui 		len -= DMAC_SEG_SIZE;
    330       1.1  tsutsui 		addr += DMAC_SEG_SIZE;
    331       1.1  tsutsui 	}
    332       1.1  tsutsui 	/* terminate TAG */
    333       1.1  tsutsui 	dmac->tag = 0;
    334       1.1  tsutsui 
    335       1.1  tsutsui 	/*
    336       1.1  tsutsui 	 * Now from the 5380-internal DMA registers.
    337       1.1  tsutsui 	 */
    338       1.1  tsutsui 	if (dh->dh_flags & SIDH_OUT) {
    339       1.1  tsutsui 		NCR5380_WRITE(ncr_sc, sci_tcmd, PHASE_DATA_OUT);
    340       1.1  tsutsui 		NCR5380_WRITE(ncr_sc, sci_icmd, SCI_ICMD_DATA);
    341       1.1  tsutsui 		NCR5380_WRITE(ncr_sc, sci_mode, NCR5380_READ(ncr_sc, sci_mode)
    342       1.1  tsutsui 		    | SCI_MODE_DMA);
    343       1.1  tsutsui 
    344       1.1  tsutsui 		/* set Dir */
    345       1.1  tsutsui 		dmac->ctl = 0;
    346       1.1  tsutsui 
    347       1.1  tsutsui 		/* start DMA */
    348       1.1  tsutsui 		NCR5380_WRITE(ncr_sc, sci_dma_send, 0);
    349       1.1  tsutsui 		dmac->ctl = DC_CTL_ENB;
    350       1.1  tsutsui 	} else {
    351       1.1  tsutsui 		NCR5380_WRITE(ncr_sc, sci_tcmd, PHASE_DATA_IN);
    352       1.1  tsutsui 		NCR5380_WRITE(ncr_sc, sci_icmd, 0);
    353       1.1  tsutsui 		NCR5380_WRITE(ncr_sc, sci_mode, NCR5380_READ(ncr_sc, sci_mode)
    354       1.1  tsutsui 		    | SCI_MODE_DMA);
    355       1.1  tsutsui 
    356       1.1  tsutsui 		/* set Dir */
    357       1.1  tsutsui 		dmac->ctl = DC_CTL_MOD;
    358       1.1  tsutsui 
    359       1.1  tsutsui 		/* start DMA */
    360       1.1  tsutsui 		NCR5380_WRITE(ncr_sc, sci_irecv, 0);
    361       1.1  tsutsui 		dmac->ctl = DC_CTL_MOD | DC_CTL_ENB;
    362       1.1  tsutsui 	}
    363       1.1  tsutsui 	ncr_sc->sc_state |= NCR_DOINGDMA;
    364       1.1  tsutsui }
    365       1.1  tsutsui 
    366       1.1  tsutsui /*
    367       1.1  tsutsui  * When?
    368       1.1  tsutsui  */
    369  1.12.2.3    skrll static void
    370  1.12.2.3    skrll si_dma_poll(struct ncr5380_softc *ncr_sc)
    371       1.1  tsutsui {
    372      1.12  tsutsui 
    373       1.1  tsutsui 	printf("si_dma_poll\n");
    374       1.1  tsutsui }
    375       1.1  tsutsui 
    376       1.1  tsutsui /*
    377      1.12  tsutsui  * news68k (probably) does not use the EOP signal.
    378       1.1  tsutsui  */
    379  1.12.2.3    skrll static void
    380  1.12.2.3    skrll si_dma_eop(struct ncr5380_softc *ncr_sc)
    381       1.1  tsutsui {
    382      1.12  tsutsui 
    383       1.1  tsutsui 	printf("si_dma_eop\n");
    384       1.1  tsutsui }
    385       1.1  tsutsui 
    386  1.12.2.3    skrll static void
    387  1.12.2.3    skrll si_dma_stop(struct ncr5380_softc *ncr_sc)
    388       1.1  tsutsui {
    389       1.1  tsutsui 	struct si_softc *sc = (struct si_softc *)ncr_sc;
    390       1.1  tsutsui 	volatile struct dma_regs *dmac = sc->sc_regs;
    391       1.1  tsutsui 	struct sci_req *sr = ncr_sc->sc_current;
    392       1.1  tsutsui 	struct si_dma_handle *dh = sr->sr_dma_hand;
    393       1.1  tsutsui 	int resid, ntrans, i;
    394       1.1  tsutsui 
    395       1.1  tsutsui 	/* check DMAC interrupt status */
    396       1.1  tsutsui 	if ((dmac->stat & DC_ST_INT) == 0) {
    397       1.1  tsutsui #ifdef DEBUG
    398       1.1  tsutsui 		printf("si_dma_stop: no DMA interrupt");
    399       1.1  tsutsui #endif
    400       1.1  tsutsui 		return; /* XXX */
    401       1.1  tsutsui 	}
    402       1.1  tsutsui 
    403       1.1  tsutsui 	if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) {
    404       1.1  tsutsui #ifdef DEBUG
    405       1.1  tsutsui 		printf("si_dma_stop: dma not running\n");
    406       1.1  tsutsui #endif
    407       1.1  tsutsui 		return;
    408       1.1  tsutsui 	}
    409       1.1  tsutsui 	ncr_sc->sc_state &= ~NCR_DOINGDMA;
    410       1.1  tsutsui 
    411       1.1  tsutsui 	/* OK, have either phase mis-match or end of DMA. */
    412       1.1  tsutsui 	/* Set an impossible phase to prevent data movement? */
    413       1.1  tsutsui 	NCR5380_WRITE(ncr_sc, sci_tcmd, PHASE_INVALID);
    414       1.1  tsutsui 
    415       1.1  tsutsui 	/* Note that timeout may have set the error flag. */
    416       1.1  tsutsui 	if (ncr_sc->sc_state & NCR_ABORTING)
    417       1.1  tsutsui 		goto out;
    418       1.1  tsutsui 
    419       1.1  tsutsui 	/*
    420       1.1  tsutsui 	 * Sometimes the FIFO buffer isn't drained when the
    421       1.1  tsutsui 	 * interrupt is posted. Just loop here and hope that
    422       1.1  tsutsui 	 * it will drain soon.
    423       1.1  tsutsui 	 */
    424       1.1  tsutsui 	for (i = 0; i < 200000; i++) { /* 2 sec */
    425       1.1  tsutsui 		resid = dmac->tcnt;
    426       1.1  tsutsui 		if (resid == 0)
    427       1.1  tsutsui 			break;
    428       1.1  tsutsui 		DELAY(10);
    429       1.1  tsutsui 	}
    430       1.1  tsutsui 
    431       1.1  tsutsui 	if (resid)
    432       1.1  tsutsui 		printf("si_dma_stop: resid=0x%x\n", resid);
    433       1.1  tsutsui 
    434       1.1  tsutsui 	ntrans = dh->dh_len - resid;
    435       1.1  tsutsui 
    436       1.1  tsutsui 	ncr_sc->sc_dataptr += ntrans;
    437       1.1  tsutsui 	ncr_sc->sc_datalen -= ntrans;
    438       1.1  tsutsui 
    439       1.1  tsutsui 	if ((dh->dh_flags & SIDH_OUT) == 0) {
    440       1.1  tsutsui 		PCIA();
    441       1.1  tsutsui 	}
    442       1.1  tsutsui 
    443      1.12  tsutsui  out:
    444       1.1  tsutsui 	NCR5380_WRITE(ncr_sc, sci_mode, NCR5380_READ(ncr_sc, sci_mode) &
    445       1.1  tsutsui 	    ~(SCI_MODE_DMA));
    446       1.1  tsutsui 	NCR5380_WRITE(ncr_sc, sci_icmd, 0);
    447       1.1  tsutsui }
    448