hide void mc_reset_rxdma(struct mc_softc *sc) { dbdma_command_t *cmd = sc->sc_rxdmacmd; dbdma_regmap_t *dmareg = sc->sc_rxdma; int i; u_int8_t maccc; /* Disable receiver, reset the DMA channels */ maccc = NIC_GET(sc, MACE_MACCC); NIC_PUT(sc, MACE_MACCC, maccc & ~ENRCV); dbdma_reset(dmareg); for (i = 0; i < MC_RXDMABUFS; i++) { DBDMA_BUILD(cmd, DBDMA_CMD_IN_LAST, 0, ETHERMTU + 22, sc->sc_rxbuf_phys + MC_BUFSIZE * i, DBDMA_INT_ALWAYS, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmd++; } DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS); out32rb(&cmd->d_cmddep, kvtop((void *)sc->sc_rxdmacmd)); cmd++; dbdma_start(dmareg, sc->sc_rxdmacmd); sc->sc_tail = 0; /* Reenable receiver, reenable DMA */ NIC_PUT(sc, MACE_MACCC, maccc); }
hide void mc_reset_txdma(struct mc_softc *sc) { dbdma_command_t *cmd = sc->sc_txdmacmd; dbdma_regmap_t *dmareg = sc->sc_txdma; u_int8_t maccc; /* disable transmitter */ maccc = NIC_GET(sc, MACE_MACCC); NIC_PUT(sc, MACE_MACCC, maccc & ~ENXMT); dbdma_reset(dmareg); DBDMA_BUILD(cmd, DBDMA_CMD_OUT_LAST, 0, 0, sc->sc_txbuf_phys, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmd++; DBDMA_BUILD(cmd, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); out32rb(&dmareg->d_cmdptrhi, 0); out32rb(&dmareg->d_cmdptrlo, kvtop((void *)sc->sc_txdmacmd)); /* restore old value */ NIC_PUT(sc, MACE_MACCC, maccc); }
int wdc_obio_dma_init(void *v, int channel, int drive, void *databuf, size_t datalen, int flags) { struct wdc_obio_softc *sc = v; dbdma_command_t *cmdp; u_int cmd; int i, error; if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, databuf, datalen, NULL, BUS_DMA_NOWAIT)) != 0) return (error); cmdp = sc->sc_dmacmd; cmd = (flags & WDC_DMA_READ) ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE; for (i = 0; i < sc->sc_dmamap->dm_nsegs; i++, cmdp++) { if (i + 1 == sc->sc_dmamap->dm_nsegs) cmd = (flags & WDC_DMA_READ) ? DBDMA_CMD_IN_LAST : DBDMA_CMD_OUT_LAST; DBDMA_BUILD(cmdp, cmd, 0, sc->sc_dmamap->dm_segs[i].ds_len, sc->sc_dmamap->dm_segs[i].ds_addr, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); } DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); return 0; }
void bmac_init_dma(struct bmac_softc *sc) { dbdma_command_t *cmd = sc->sc_rxcmd; int i; dbdma_reset(sc->sc_txdma); dbdma_reset(sc->sc_rxdma); bzero(sc->sc_txcmd, BMAC_TXBUFS * sizeof(dbdma_command_t)); bzero(sc->sc_rxcmd, (BMAC_RXBUFS + 1) * sizeof(dbdma_command_t)); for (i = 0; i < BMAC_RXBUFS; i++) { DBDMA_BUILD(cmd, DBDMA_CMD_IN_LAST, 0, BMAC_BUFLEN, sc->sc_rxbuf_pa + BMAC_BUFLEN * i, DBDMA_INT_ALWAYS, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmd++; } DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS); dbdma_st32(&cmd->d_cmddep, sc->sc_rxdbdma->d_paddr); sc->sc_rxlast = 0; dbdma_start(sc->sc_rxdma, sc->sc_rxdbdma); }
int esp_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr, size_t *len, int datain, size_t *dmasize) { struct esp_softc *esc = (struct esp_softc *)sc; dbdma_command_t *cmdp; u_int cmd; int i, error; cmdp = esc->sc_dmacmd; cmd = datain ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE; esc->sc_dmaaddr = addr; esc->sc_dmalen = len; esc->sc_dmasize = *dmasize; if ((error = bus_dmamap_load(esc->sc_dmat, esc->sc_dmamap, *addr, *dmasize, NULL, BUS_DMA_NOWAIT)) != 0) return (error); for (i = 0; i < esc->sc_dmamap->dm_nsegs; i++, cmdp++) { if (i + 1 == esc->sc_dmamap->dm_nsegs) cmd = datain ? DBDMA_CMD_IN_LAST : DBDMA_CMD_OUT_LAST; DBDMA_BUILD(cmdp, cmd, 0, esc->sc_dmamap->dm_segs[i].ds_len, esc->sc_dmamap->dm_segs[i].ds_addr, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); } DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); esc->sc_dma_direction = datain ? D_WRITE : 0; return 0; }
void mc_reset_rxdma(struct mc_softc *sc) { dbdma_command_t *cmd = sc->sc_rxdmacmd; int i; u_int8_t maccc; /* Disable receiver, reset the DMA channels */ maccc = NIC_GET(sc, MACE_MACCC); NIC_PUT(sc, MACE_MACCC, maccc & ~ENRCV); dbdma_reset(sc->sc_rxdma); bzero(sc->sc_rxdmacmd, 8 * sizeof(dbdma_command_t)); for (i = 0; i < MC_RXDMABUFS; i++) { DBDMA_BUILD(cmd, DBDMA_CMD_IN_LAST, 0, MACE_BUFLEN, sc->sc_rxbuf_pa + MACE_BUFLEN * i, DBDMA_INT_ALWAYS, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmd++; } DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS); dbdma_st32(&cmd->d_cmddep, sc->sc_rxdbdma->d_paddr); cmd++; sc->sc_tail = 0; dbdma_start(sc->sc_rxdma, sc->sc_rxdbdma); /* Reenable receiver, reenable DMA */ NIC_PUT(sc, MACE_MACCC, maccc); }
void bmac_transmit_packet(struct bmac_softc *sc, paddr_t pa, int len) { dbdma_command_t *cmd = sc->sc_txcmd; DBDMA_BUILD(cmd, DBDMA_CMD_OUT_LAST, 0, len, pa, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmd++; DBDMA_BUILD(cmd, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_ALWAYS, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); dbdma_start(sc->sc_txdma, sc->sc_txdbdma); }
void mc_putpacket(struct mc_softc *sc, u_int len) { dbdma_command_t *cmd = sc->sc_txdmacmd; DBDMA_BUILD(cmd, DBDMA_CMD_OUT_LAST, 0, len, sc->sc_txbuf_pa, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmd++; DBDMA_BUILD(cmd, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_ALWAYS, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); dbdma_start(sc->sc_txdma, sc->sc_txdbdma); }
int wdc_obio_dma_init(void *v, int channel, int drive, void *databuf, size_t datalen, int flags) { struct wdc_obio_softc *sc = v; vaddr_t va = (vaddr_t)databuf; dbdma_command_t *cmdp; u_int cmd, offset; int read = flags & WDC_DMA_READ; cmdp = sc->sc_dmacmd; cmd = read ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE; offset = va & PGOFSET; /* if va is not page-aligned, setup the first page */ if (offset != 0) { int rest = PAGE_SIZE - offset; /* the rest of the page */ if (datalen > rest) { /* if continues to next page */ DBDMA_BUILD(cmdp, cmd, 0, rest, vtophys(va), DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); datalen -= rest; va += rest; cmdp++; } } /* now va is page-aligned */ while (datalen > PAGE_SIZE) { DBDMA_BUILD(cmdp, cmd, 0, PAGE_SIZE, vtophys(va), DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); datalen -= PAGE_SIZE; va += PAGE_SIZE; cmdp++; } /* the last page (datalen <= PAGE_SIZE here) */ cmd = read ? DBDMA_CMD_IN_LAST : DBDMA_CMD_OUT_LAST; DBDMA_BUILD(cmdp, cmd, 0, datalen, vtophys(va), DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmdp++; DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); return 0; }
void scsi_curio_dbdma_setup(int unit, vm_offset_t address, vm_size_t len, boolean_t isread) { dbdma_command_t *dmap = scsi_curio_dbdma_commands; DBDMA_BUILD(dmap, isread ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE, 0, len, address, DBDMA_INT_NEVER, DBDMA_BRANCH_NEVER, DBDMA_WAIT_NEVER); dmap++; DBDMA_BUILD(dmap, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_BRANCH_NEVER, DBDMA_WAIT_NEVER); eieio(); /* Make sure things are flushed out.. */ }
hide void mc_putpacket(struct mc_softc *sc, u_int len) { dbdma_command_t *cmd = sc->sc_txdmacmd; DBDMA_BUILD(cmd, DBDMA_CMD_OUT_LAST, 0, len, sc->sc_txbuf_phys, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); dbdma_start(sc->sc_txdma, sc->sc_txdmacmd); }
void xlights_startdma(struct xlights_softc *sc) { dbdma_command_t *cmdp = sc->sc_dmacmd; sc->sc_dmasts = 1; timeout_add(&sc->sc_tmo, 250); DBDMA_BUILD(cmdp, DBDMA_CMD_OUT_LAST, 0, sc->sc_bufmap->dm_segs[0].ds_len, sc->sc_bufmap->dm_segs[0].ds_addr, DBDMA_INT_ALWAYS, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmdp++; DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); dbdma_start(sc->sc_dma, sc->sc_dbdma); }
int esp_dma_setup(struct ncr53c9x_softc *sc, uint8_t **addr, size_t *len, int datain, size_t *dmasize) { struct esp_softc *esc = (struct esp_softc *)sc; dbdma_command_t *cmdp; u_int cmd; u_int va; int count, offset; cmdp = esc->sc_dmacmd; cmd = datain ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE; count = *dmasize; if (count / PAGE_SIZE > 32) panic("%s: transfer size >= 128k", device_xname(sc->sc_dev)); esc->sc_dmaaddr = addr; esc->sc_dmalen = len; esc->sc_dmasize = count; va = (u_int)*esc->sc_dmaaddr; offset = va & PGOFSET; /* if va is not page-aligned, setup the first page */ if (offset != 0) { int rest = PAGE_SIZE - offset; /* the rest of the page */ if (count > rest) { /* if continues to next page */ DBDMA_BUILD(cmdp, cmd, 0, rest, kvtop((void *)va), DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); count -= rest; va += rest; cmdp++; } } /* now va is page-aligned */ while (count > PAGE_SIZE) { DBDMA_BUILD(cmdp, cmd, 0, PAGE_SIZE, kvtop((void *)va), DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); count -= PAGE_SIZE; va += PAGE_SIZE; cmdp++; } /* the last page (count <= PAGE_SIZE here) */ cmd = datain ? DBDMA_CMD_IN_LAST : DBDMA_CMD_OUT_LAST; DBDMA_BUILD(cmdp, cmd , 0, count, kvtop((void *)va), DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); cmdp++; DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); esc->sc_dma_direction = datain ? D_WRITE : 0; return 0; }