Esempio n. 1
0
void
bmac_stop(struct bmac_softc *sc)
{
	struct ifnet *ifp = &sc->arpcom.ac_if;
	int s;

	s = splnet();

	/* timeout */
	timeout_del(&sc->sc_tick_ch);
	mii_down(&sc->sc_mii);

	/* Disable TX/RX. */
	bmac_reset_bits(sc, TXCFG, TxMACEnable);
	bmac_reset_bits(sc, RXCFG, RxMACEnable);

	/* Disable all interrupts. */
	bmac_write_reg(sc, INTDISABLE, NoEventsMask);

	dbdma_stop(sc->sc_txdma);
	dbdma_stop(sc->sc_rxdma);

	ifp->if_flags &= ~(IFF_UP | IFF_RUNNING);
	ifp->if_timer = 0;

	splx(s);
}
Esempio n. 2
0
int
dbdma_allocate_channel(struct resource *dbdma_regs, u_int offset,
                       bus_dma_tag_t parent_dma, int slots, dbdma_channel_t **chan)
{
    int error = 0;
    dbdma_channel_t *channel;

    channel = *chan = malloc(sizeof(struct dbdma_channel), M_DBDMA,
                             M_WAITOK | M_ZERO);

    channel->sc_regs = dbdma_regs;
    channel->sc_off = offset;
    dbdma_stop(channel);

    channel->sc_slots_pa = 0;

    error = bus_dma_tag_create(parent_dma, 16, 0, BUS_SPACE_MAXADDR_32BIT,
                               BUS_SPACE_MAXADDR, NULL, NULL, PAGE_SIZE, 1, PAGE_SIZE, 0, NULL,
                               NULL, &(channel->sc_dmatag));

    error = bus_dmamem_alloc(channel->sc_dmatag,
                             (void **)&channel->sc_slots, BUS_DMA_WAITOK | BUS_DMA_ZERO,
                             &channel->sc_dmamap);

    error = bus_dmamap_load(channel->sc_dmatag, channel->sc_dmamap,
                            channel->sc_slots, PAGE_SIZE, dbdma_phys_callback, channel, 0);

    dbdma_write_reg(channel, CHAN_CMDPTR_HI, 0);

    channel->sc_nslots = slots;

    return (error);
}
Esempio n. 3
0
void
esp_dma_stop(struct ncr53c9x_softc *sc)
{
	struct esp_softc *esc = (struct esp_softc *)sc;

	dbdma_stop(esc->sc_dmareg);
	esc->sc_dmaactive = 0;
}
Esempio n. 4
0
void
dbdma_reset(dbdma_channel_t *chan)
{

    dbdma_stop(chan);
    dbdma_set_current_cmd(chan, 0);
    dbdma_run(chan);
}
int
wdc_obio_dma_finish(void *v, int channel, int drive, int read)
{
	struct wdc_obio_softc *sc = v;

	dbdma_stop(sc->sc_dmareg);
	return 0;
}
Esempio n. 6
0
int
wdc_obio_dma_finish(void *v, int channel, int drive, int force)
{
	struct wdc_obio_softc *sc = v;

	dbdma_stop(sc->sc_dmareg);
	bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap);
	return 0;
}
Esempio n. 7
0
void
esp_dma_stop(struct ncr53c9x_softc *sc)
{
	struct esp_softc *esc = (struct esp_softc *)sc;

	dbdma_stop(esc->sc_dmareg);
	bus_dmamap_unload(esc->sc_dmat, esc->sc_dmamap);
	esc->sc_dmaactive = 0;
}
Esempio n. 8
0
int
dbdma_free_channel(dbdma_channel_t *chan)
{

    dbdma_stop(chan);

    bus_dmamem_free(chan->sc_dmatag, chan->sc_slots, chan->sc_dmamap);
    bus_dma_tag_destroy(chan->sc_dmatag);

    free(chan, M_DBDMA);

    return (0);
}
Esempio n. 9
0
static void
ata_dbdma_reset(device_t dev)
{
	struct ata_dbdma_channel *sc = device_get_softc(dev);

	mtx_lock(&sc->dbdma_mtx);

	dbdma_stop(sc->dbdma);
	dbdma_insert_stop(sc->dbdma, 0);
	sc->next_dma_slot=1;
	dbdma_set_current_cmd(sc->dbdma, 0);

	sc->sc_ch.dma.flags &= ~ATA_DMA_ACTIVE;

	mtx_unlock(&sc->dbdma_mtx);
}
Esempio n. 10
0
/*
 * Pseudo (chained) interrupt from the esp driver to kick the
 * current running DMA transfer. I am replying on espintr() to
 * pickup and clean errors for now
 *
 * return 1 if it was a DMA continue.
 */
int
espdmaintr(struct esp_softc *sc)
{
	struct ncr53c9x_softc *nsc = (struct ncr53c9x_softc *)sc;
	int trans, resid;
	u_long csr = sc->sc_dma_direction;

#if 0
	if (csr & D_ERR_PEND) {
		DMACSR(sc) &= ~D_EN_DMA;	/* Stop DMA */
		DMACSR(sc) |= D_INVALIDATE;
		printf("%s: error: csr=%s\n", device_xname(nsc->sc_dev),
		    bitmask_snprintf(csr, DMACSRBITS, bits, sizeof(bits)));
		return -1;
	}
#endif

	/* This is an "assertion" :) */
	if (sc->sc_dmaactive == 0)
		panic("%s: DMA wasn't active", __func__);

	/* dbdma_flush(sc->sc_dmareg); */

	/* DMA has stopped */
	dbdma_stop(sc->sc_dmareg);
	sc->sc_dmaactive = 0;

	if (sc->sc_dmasize == 0) {
		/* A "Transfer Pad" operation completed */
		NCR_DMA(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
			NCR_READ_REG(nsc, NCR_TCL) |
				(NCR_READ_REG(nsc, NCR_TCM) << 8),
			NCR_READ_REG(nsc, NCR_TCL),
			NCR_READ_REG(nsc, NCR_TCM)));
		return 0;
	}

	resid = 0;
	/*
	 * If a transfer onto the SCSI bus gets interrupted by the device
	 * (e.g. for a SAVEPOINTER message), the data in the FIFO counts
	 * as residual since the ESP counter registers get decremented as
	 * bytes are clocked into the FIFO.
	 */
	if (!(csr & D_WRITE) &&
	    (resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
		NCR_DMA(("dmaintr: empty esp FIFO of %d ", resid));
	}

	if ((nsc->sc_espstat & NCRSTAT_TC) == 0) {
		/*
		 * `Terminal count' is off, so read the residue
		 * out of the ESP counter registers.
		 */
		resid += (NCR_READ_REG(nsc, NCR_TCL) |
			  (NCR_READ_REG(nsc, NCR_TCM) << 8) |
			   ((nsc->sc_cfg2 & NCRCFG2_FE)
				? (NCR_READ_REG(nsc, NCR_TCH) << 16)
				: 0));

		if (resid == 0 && sc->sc_dmasize == 65536 &&
		    (nsc->sc_cfg2 & NCRCFG2_FE) == 0)
			/* A transfer of 64K is encoded as `TCL=TCM=0' */
			resid = 65536;
	}

	trans = sc->sc_dmasize - resid;
	if (trans < 0) {			/* transferred < 0 ? */
#if 0
		/*
		 * This situation can happen in perfectly normal operation
		 * if the ESP is reselected while using DMA to select
		 * another target.  As such, don't print the warning.
		 */
		printf("%s: xfer (%d) > req (%d)\n",
		    device_xname(nsc->sc_dev), trans, sc->sc_dmasize);
#endif
		trans = sc->sc_dmasize;
	}

	NCR_DMA(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
		NCR_READ_REG(nsc, NCR_TCL),
		NCR_READ_REG(nsc, NCR_TCM),
		(nsc->sc_cfg2 & NCRCFG2_FE)
			? NCR_READ_REG(nsc, NCR_TCH) : 0,
		trans, resid));

#if 0
	if (csr & D_WRITE)
		flushcache(*sc->sc_dmaaddr, trans);
#endif

	*sc->sc_dmalen -= trans;
	*sc->sc_dmaaddr += trans;

#if 0	/* this is not normal operation just yet */
	if (*sc->sc_dmalen == 0 ||
	    nsc->sc_phase != nsc->sc_prevphase)
		return 0;

	/* and again */
	dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, DMACSR(sc) & D_WRITE);
	return 1;
#endif
	return 0;
}
Esempio n. 11
0
void
scsi_curio_dbdma_end(int unit, boolean_t isread)
{
	dbdma_stop(curio_chan);
}
Esempio n. 12
0
/*
 * Pseudo (chained) interrupt from the esp driver to kick the
 * current running DMA transfer. I am replying on espintr() to
 * pickup and clean errors for now
 *
 * return 1 if it was a DMA continue.
 */
int
espdmaintr(struct esp_softc *sc)
{
	struct ncr53c9x_softc *nsc = (struct ncr53c9x_softc *)sc;
	int trans, resid;
	u_long csr = sc->sc_dma_direction;

	/* This is an "assertion" :) */
	if (sc->sc_dmaactive == 0)
		panic("dmaintr: DMA wasn't active");

	/* DMA has stopped */
	dbdma_stop(sc->sc_dmareg);
	bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap);
	sc->sc_dmaactive = 0;

	if (sc->sc_dmasize == 0) {
		/* A "Transfer Pad" operation completed */
		NCR_DMA(("dmaintr: discarded %d bytes (tcl=%d, tcm=%d)\n",
		    NCR_READ_REG(nsc, NCR_TCL) |
		    (NCR_READ_REG(nsc, NCR_TCM) << 8),
		    NCR_READ_REG(nsc, NCR_TCL),
		    NCR_READ_REG(nsc, NCR_TCM)));
		return 0;
	}

	resid = 0;
	/*
	 * If a transfer onto the SCSI bus gets interrupted by the device
	 * (e.g. for a SAVEPOINTER message), the data in the FIFO counts
	 * as residual since the ESP counter registers get decremented as
	 * bytes are clocked into the FIFO.
	 */
	if (!(csr & D_WRITE) &&
	    (resid = (NCR_READ_REG(nsc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
		NCR_DMA(("dmaintr: empty esp FIFO of %d ", resid));
	}

	if ((nsc->sc_espstat & NCRSTAT_TC) == 0) {
		/*
		 * `Terminal count' is off, so read the residue
		 * out of the ESP counter registers.
		 */
		resid += (NCR_READ_REG(nsc, NCR_TCL) |
		    (NCR_READ_REG(nsc, NCR_TCM) << 8) |
		    ((nsc->sc_cfg2 & NCRCFG2_FE)
		    ? (NCR_READ_REG(nsc, NCR_TCH) << 16) : 0));

		if (resid == 0 && sc->sc_dmasize == 65536 &&
		    (nsc->sc_cfg2 & NCRCFG2_FE) == 0)
			/* A transfer of 64K is encoded as `TCL=TCM=0' */
			resid = 65536;
	}

	trans = sc->sc_dmasize - resid;
	if (trans < 0) {			/* transferred < 0 ? */
		trans = sc->sc_dmasize;
	}

	NCR_DMA(("dmaintr: tcl=%d, tcm=%d, tch=%d; trans=%d, resid=%d\n",
	    NCR_READ_REG(nsc, NCR_TCL), NCR_READ_REG(nsc, NCR_TCM),
	    (nsc->sc_cfg2 & NCRCFG2_FE) ? NCR_READ_REG(nsc, NCR_TCH) : 0,
	    trans, resid));


	*sc->sc_dmalen -= trans;
	*sc->sc_dmaaddr += trans;

	return 0;
}