Use bus_dma to get temporary I/O buffers.

This commit is contained in:
ad 2001-09-20 22:09:44 +00:00
parent b959cd4c1f
commit ec1f68e931
2 changed files with 43 additions and 23 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: twe.c,v 1.18 2001/09/16 16:34:38 wiz Exp $ */
/* $NetBSD: twe.c,v 1.19 2001/09/20 22:09:44 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -810,24 +810,37 @@ twe_ccb_free(struct twe_softc *sc, struct twe_ccb *ccb)
int
twe_ccb_map(struct twe_softc *sc, struct twe_ccb *ccb)
{
struct twe_buf *tb;
struct twe_cmd *tc;
int flags, nsegs, i, s, rv;
int flags, nsegs, i, rv;
void *data;
/*
* The data as a whole must be 512-byte aligned.
*/
if (((u_long)ccb->ccb_data & (TWE_ALIGNMENT - 1)) != 0) {
s = splvm();
/* XXX */
ccb->ccb_abuf = uvm_km_kmemalloc(kmem_map, NULL,
ccb->ccb_datasize, UVM_KMF_NOWAIT);
splx(s);
data = (void *)ccb->ccb_abuf;
tb = malloc(sizeof(*ccb->ccb_buf), M_DEVBUF, M_NOWAIT);
rv = bus_dmamem_alloc(sc->sc_dmat, ccb->ccb_datasize,
PAGE_SIZE, 0, tb->tb_segs, TWE_MAX_SEGS, &tb->tb_rseg,
BUS_DMA_NOWAIT);
if (rv != 0)
return (rv);
rv = bus_dmamem_map(sc->sc_dmat, tb->tb_segs, tb->tb_rseg,
ccb->ccb_datasize, &tb->tb_vaddr, BUS_DMA_NOWAIT);
if (rv != 0) {
bus_dmamem_free(sc->sc_dmat, tb->tb_segs, tb->tb_rseg);
return (rv);
}
ccb->ccb_buf = tb;
data = tb->tb_vaddr;
if ((ccb->ccb_flags & TWE_CCB_DATA_OUT) != 0)
memcpy(data, ccb->ccb_data, ccb->ccb_datasize);
} else {
ccb->ccb_abuf = (vaddr_t)0;
tb = NULL;
ccb->ccb_buf = NULL;
data = ccb->ccb_data;
}
@ -839,12 +852,10 @@ twe_ccb_map(struct twe_softc *sc, struct twe_ccb *ccb)
((ccb->ccb_flags & TWE_CCB_DATA_IN) ?
BUS_DMA_READ : BUS_DMA_WRITE));
if (rv != 0) {
if (ccb->ccb_abuf != (vaddr_t)0) {
s = splvm();
/* XXX */
uvm_km_free(kmem_map, ccb->ccb_abuf,
if (tb != NULL) {
bus_dmamem_unmap(sc->sc_dmat, tb->tb_vaddr,
ccb->ccb_datasize);
splx(s);
bus_dmamem_free(sc->sc_dmat, tb->tb_segs, tb->tb_rseg);
}
return (rv);
}
@ -906,7 +917,8 @@ twe_ccb_map(struct twe_softc *sc, struct twe_ccb *ccb)
void
twe_ccb_unmap(struct twe_softc *sc, struct twe_ccb *ccb)
{
int flags, s;
struct twe_buf *tb;
int flags;
if ((ccb->ccb_flags & TWE_CCB_DATA_IN) != 0)
flags = BUS_DMASYNC_POSTREAD;
@ -919,14 +931,15 @@ twe_ccb_unmap(struct twe_softc *sc, struct twe_ccb *ccb)
ccb->ccb_datasize, flags);
bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap_xfer);
if (ccb->ccb_abuf != (vaddr_t)0) {
if (ccb->ccb_buf != NULL) {
tb = ccb->ccb_buf;
if ((ccb->ccb_flags & TWE_CCB_DATA_IN) != 0)
memcpy(ccb->ccb_data, (void *)ccb->ccb_abuf,
memcpy(ccb->ccb_data, tb->tb_vaddr,
ccb->ccb_datasize);
s = splvm();
/* XXX */
uvm_km_free(kmem_map, ccb->ccb_abuf, ccb->ccb_datasize);
splx(s);
bus_dmamem_unmap(sc->sc_dmat, tb->tb_vaddr, ccb->ccb_datasize);
bus_dmamem_free(sc->sc_dmat, tb->tb_segs, tb->tb_rseg);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: twevar.h,v 1.7 2001/03/04 17:50:52 ad Exp $ */
/* $NetBSD: twevar.h,v 1.8 2001/09/20 22:09:44 ad Exp $ */
/*-
* Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@ -78,6 +78,13 @@ struct twe_context {
struct device *tx_dv;
};
/* Temporary buffer. */
struct twe_buf {
bus_dma_segment_t tb_segs[TWE_MAX_SEGS];
int tb_rseg;
caddr_t tb_vaddr;
};
/* Command control block. */
struct twe_ccb {
union {
@ -89,9 +96,9 @@ struct twe_ccb {
int ccb_flags;
void *ccb_data;
int ccb_datasize;
vaddr_t ccb_abuf;
bus_dmamap_t ccb_dmamap_xfer;
struct twe_context ccb_tx;
struct twe_buf *ccb_buf;
};
#define TWE_CCB_DATA_IN 0x01 /* Map describes inbound xfer */
#define TWE_CCB_DATA_OUT 0x02 /* Map describes outbound xfer */