On Sat, Dec 09, 2006 at 10:59:46PM +0100, Martin Husemann
wrote:
> Hi folks,
>
> after some hardware troubles I got my "brand
new" Quadra 660AV booting
> NetBSD for the first time.
>
> The 4.0 install kernel fails to attach mc0 at obio, due
to physically non
> contingous memory returned by malloc. See the comment
in obio/if_mc_obio.c
> around line 140.
>
> I can rebuild my own install kernel, as suggest with
only two rx DMA buffers.
> I could even try to convert this driver to bus_dma
>
> But I primarily wonder if this is a common effect, and
wether the install
> kernels should be build with options MC_RXDMABUFS=2 to
work around it.
I think some changes made to the m68k pmap code a while back
caused
malloc to return physically non-contiguous memory... I never
saw that
message before, but I always get it in post-3.x kernels.
Using bus_dma would be great I took a
stab at it a while back, but
I'm not sure if the best way of doing things:
Index: sys/arch/mac68k/dev/if_mc.c
============================================================
=======
RCS file: /cvsroot/src/sys/arch/mac68k/dev/if_mc.c,v
retrieving revision 1.27
diff -u -r1.27 if_mc.c
--- sys/arch/mac68k/dev/if_mc.c 7 Sep 2006 02:40:31
-0000 1.27
+++ sys/arch/mac68k/dev/if_mc.c 10 Dec 2006 19:24:33 -0000
 -411,7
+411,7 
u_int len, totlen = 0;
u_char *buff;
- buff = sc->sc_txbuf;
+ buff = sc->sc_txbuf + (sc->sc_txset == 0 ? 0 :
0x800);
for (; m; m = n) {
u_char *data = mtod(m, u_char *);
Index: sys/arch/mac68k/dev/if_mcvar.h
============================================================
=======
RCS file: /cvsroot/src/sys/arch/mac68k/dev/if_mcvar.h,v
retrieving revision 1.11
diff -u -r1.11 if_mcvar.h
--- sys/arch/mac68k/dev/if_mcvar.h 24 Dec 2005 20:07:15
-0000 1.11
+++ sys/arch/mac68k/dev/if_mcvar.h 10 Dec 2006 19:24:33
-0000
 -78,9
+78,12 
bus_space_tag_t sc_regt;
bus_space_handle_t sc_regh;
+ bus_dma_tag_t sc_dmat;
+ bus_dmamap_t sc_dmam_tx, sc_dmam_rx;
+ bus_dma_segment_t sc_dmasegs_tx, sc_dmasegs_rx;
- u_char *sc_txbuf, *sc_rxbuf;
- int sc_txbuf_phys, sc_rxbuf_phys;
+ caddr_t sc_txbuf, sc_rxbuf;
+ bus_addr_t sc_txbuf_phys, sc_rxbuf_phys;
int sc_tail;
int sc_rxset;
int sc_txset, sc_txseti;
Index: sys/arch/mac68k/obio/if_mc_obio.c
============================================================
=======
RCS file: /cvsroot/src/sys/arch/mac68k/obio/if_mc_obio.c,v
retrieving revision 1.15
diff -u -r1.15 if_mc_obio.c
--- sys/arch/mac68k/obio/if_mc_obio.c 11 Dec 2005 12:18:03
-0000 1.15
+++ sys/arch/mac68k/obio/if_mc_obio.c 10 Dec 2006 19:24:34
-0000
 -111,7
+111,7 
struct obio_attach_args *oa = (struct obio_attach_args
*)aux;
struct mc_softc *sc = (void *)self;
u_int8_t myaddr[ETHER_ADDR_LEN];
- int i, noncontig = 0;
+ int rsegs;
sc->sc_regt = oa->oa_tag;
sc->sc_biucc = XMTSP_64;
 -130,38
+130,59 
return;
}
- /* allocate memory for transmit buffer and mark it
non-cacheable */
- sc->sc_txbuf = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK);
- sc->sc_txbuf_phys = kvtop(sc->sc_txbuf);
- physaccess (sc->sc_txbuf,
(caddr_t)sc->sc_txbuf_phys, PAGE_SIZE,
- PG_V | PG_RW | PG_CI);
+ /* allocate memory for transmit and receive DMA buffers */
+ sc->sc_dmat = oa->oa_dmat;
+ if (bus_dmamem_alloc(sc->sc_dmat, 2 * 0x800, 0, 0,
&sc->sc_dmasegs_tx,
+ 1, &rsegs, BUS_DMA_NOWAIT) != 0) {
+ printf(": failed to allocate TX DMA
buffers.n");
+ return;
+ }
- /*
- * allocate memory for receive buffer and mark it
non-cacheable
- * XXX This should use the bus_dma interface, since the
buffer
- * needs to be physically contiguous. However, it seems
that
- * at least on my system, malloc() does allocate
contiguous
- * memory. If it's not, suggest reducing the number of
buffers
- * to 2, which will fit in one 4K page.
- */
- sc->sc_rxbuf = malloc(MC_NPAGES * PAGE_SIZE, M_DEVBUF,
M_WAITOK);
- sc->sc_rxbuf_phys = kvtop(sc->sc_rxbuf);
- for (i = 0; i < MC_NPAGES; i++) {
- int pa;
-
- pa = kvtop(sc->sc_rxbuf + PAGE_SIZE*i);
- physaccess (sc->sc_rxbuf + PAGE_SIZE*i, (caddr_t)pa,
PAGE_SIZE,
- PG_V | PG_RW | PG_CI);
- if (pa != sc->sc_rxbuf_phys + PAGE_SIZE*i)
- noncontig = 1;
+ if (bus_dmamem_map(sc->sc_dmat,
&sc->sc_dmasegs_tx, rsegs, 2 * 0x800,
+ &sc->sc_txbuf, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)
!= 0) {
+ printf(": failed to map TX DMA buffers.n");
+ return;
}
- if (noncontig) {
- printf("%s: receive DMA buffer not contiguous!
"
- "Try compiling with "options
MC_RXDMABUFS=2"n",
- sc->sc_dev.dv_xname);
+ if (bus_dmamem_alloc(sc->sc_dmat, MC_RXDMABUFS * 0x800,
0, 0,
+ &sc->sc_dmasegs_rx, 1, &rsegs, BUS_DMA_NOWAIT)
!= 0) {
+ printf(": failed to allocate RX DMA
buffers.n");
+ return;
+ }
+
+ if (bus_dmamem_map(sc->sc_dmat,
&sc->sc_dmasegs_rx, rsegs,
+ MC_RXDMABUFS * 0x800, &sc->sc_rxbuf,
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) {
+ printf(": failed to map RX DMA buffers.n");
+ return;
+ }
+
+ if (bus_dmamap_create(sc->sc_dmat, 2 * 0x800, 1, 2 *
0x800, 0,
+ BUS_DMA_NOWAIT, &sc->sc_dmam_tx) != 0) {
+ printf(": failed to allocate TX DMA map.n");
return;
}
+
+ if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmam_tx,
sc->sc_txbuf,
+ 2 * 0x800, NULL, BUS_DMA_NOWAIT) != 0) {
+ printf(": failed to map TX DMA mapping.n");
+ return;
+ }
+
+ if (bus_dmamap_create(sc->sc_dmat, MC_RXDMABUFS *
0x800, 1,
+ MC_RXDMABUFS * 0x800, 0, BUS_DMA_NOWAIT,
&sc->sc_dmam_rx) != 0) {
+ printf(": failed to allocate RX DMA map.n");
+ return;
+ }
+
+ if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmam_rx,
sc->sc_rxbuf,
+ MC_RXDMABUFS * 0x800, NULL, BUS_DMA_NOWAIT) != 0) {
+ printf(": failed to map RX DMA mapping.n");
+ return;
+ }
+
+ sc->sc_txbuf_phys = sc->sc_dmasegs_tx.ds_addr;
+ sc->sc_rxbuf_phys = sc->sc_dmasegs_rx.ds_addr;
sc->sc_bus_init = mc_obio_init;
sc->sc_putpacket = mc_obio_put;
 -219,9
+240,15 
hide void
mc_obio_put(struct mc_softc *sc, u_int len)
{
- psc_reg4(PSC_ENETWR_ADDR + sc->sc_txset) =
sc->sc_txbuf_phys;
+ int offset = sc->sc_txset == 0 ? 0 : 0x800;
+
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmam_tx, offset,
0x800,
+ BUS_DMASYNC_PREWRITE);
+ psc_reg4(PSC_ENETWR_ADDR + sc->sc_txset) =
sc->sc_txbuf_phys + offset;
psc_reg4(PSC_ENETWR_LEN + sc->sc_txset) = len;
psc_reg2(PSC_ENETWR_CMD + sc->sc_txset) = 0x9800;
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmam_tx, offset,
0x800,
+ BUS_DMASYNC_POSTWRITE);
sc->sc_txset ^= 0x10;
}
 -279,6
+306,11 
/* Loop through, processing each of the packets */
for (; sc->sc_tail < head; sc->sc_tail++) {
offset = sc->sc_tail * 0x800;
+
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmam_rx,
+ PAGE_SIZE + offset, 0x800,
+ BUS_DMASYNC_PREREAD);
+
sc->sc_rxframe.rx_rcvcnt = sc->sc_rxbuf[offset];
sc->sc_rxframe.rx_rcvsts = sc->sc_rxbuf[offset+2];
sc->sc_rxframe.rx_rntpc = sc->sc_rxbuf[offset+4];
 -286,6
+318,10 
sc->sc_rxframe.rx_frame = sc->sc_rxbuf + offset +
16;
mc_rint(sc);
+
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmam_rx,
+ PAGE_SIZE + offset, 0x800,
+ BUS_DMASYNC_POSTREAD);
}
/*
--
Name: Dave Huang | Mammal, mammal / their names are
called /
INet: khym azeotrope.org | they raise a paw / the bat, the cat
/
FurryMUCK: Dahan | dolphin and dog / koala bear and
hog -- TMBG
Dahan: Hani G Y+C 31 Y++ L+++ W- C++ T++ A+ E+ S++ V++ F-
Q+++ P+ B+ PA+ PL++
|