/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
* Simulation Facility, NASA Ames Research Center; Paul Kranenburg.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(SUN4M)
/*
* We need to flush the Sbus->Mbus write buffers. This can most
* easily be accomplished by reading back the register that we
* just wrote (thanks to Chris Torek for this solution).
*/
(void)bus_space_read_2(t, h, LEREG1_RDP);
#endif
}
/*
* Look for an "unallocated" lebuffer and pair it with
* this `le' device on the assumption that we're on
* a pre-historic ROM that doesn't establish le<=>lebuffer
* parent-child relationships.
*/
lebufcd = config_cfdriver_lookup("lebuffer");
if (lebufcd != NULL) {
int unit;
/* Check all possible lebuffer units */
for (unit = 0; unit < lebufcd->cd_ndevs; unit++) {
device_t lebufdev;
struct lebuf_softc *lebufsc;
/* Check if unit is valid */
lebufdev = device_lookup(lebufcd, unit);
if (lebufdev == NULL)
continue;
/* Check if we have a common sbus parent */
if (parent != device_parent(lebufdev))
continue;
lebufsc = device_private(lebufdev);
/*
* Check if this lebuffer unit is attached
* but unused by its child, if_le_lebuffer.
* XXX: this won't work if lebuffer is configured
* but not le at lebuffer?
*/
if (lebufsc->sc_buffer == 0 || lebufsc->attached != 0)
continue;
/* Assume this lebuffer is my pair */
sc->sc_mem = lebufsc->sc_buffer;
sc->sc_memsize = lebufsc->sc_bufsiz;
/* Lance view is offset by buffer location */
sc->sc_addr = 0;
/* Denote it */
aprint_normal(" (%s)", device_xname(lebufdev));
lebufsc->attached = 1;
/* That old black magic... */
sc->sc_conf3 = prom_getpropint(sa->sa_node,
"busmaster-regval",
LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON);
break;
}
}
if (sc->sc_mem == 0) {
bus_dma_segment_t seg;
int rseg, error;
#ifndef BUS_DMA_24BIT
/* XXX - This flag is not defined on all archs */
#define BUS_DMA_24BIT 0
#endif
/* Get a DMA handle */
if ((error = bus_dmamap_create(dmatag, MEMSIZE, 1, MEMSIZE, 0,
BUS_DMA_NOWAIT | BUS_DMA_24BIT, &lesc->sc_dmamap)) != 0) {
aprint_error(": DMA map create error %d\n", error);
return;
}