Use bus_dma to get temporary I/O buffers.
This commit is contained in:
parent
b959cd4c1f
commit
ec1f68e931
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue