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); }
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); }
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; }
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; }
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; }
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; }
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); }
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); }
/* * 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; }
void scsi_curio_dbdma_end(int unit, boolean_t isread) { dbdma_stop(curio_chan); }
/* * 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; }