summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/sbus/dma_sbus.c32
-rw-r--r--sys/sparc64/sbus/lsi64854.c135
-rw-r--r--sys/sparc64/sbus/lsi64854var.h15
3 files changed, 85 insertions, 97 deletions
diff --git a/sys/sparc64/sbus/dma_sbus.c b/sys/sparc64/sbus/dma_sbus.c
index 924fa27..4623995 100644
--- a/sys/sparc64/sbus/dma_sbus.c
+++ b/sys/sparc64/sbus/dma_sbus.c
@@ -70,7 +70,6 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
-#include <sys/resource.h>
#include <sys/rman.h>
#include <dev/ofw/ofw_bus.h>
@@ -178,7 +177,7 @@ dma_attach(device_t dev)
char *cabletype;
uint32_t csr;
phandle_t child, node;
- int error, burst, children;
+ int error, i;
dsc = device_get_softc(dev);
lsc = &dsc->sc_lsi64854;
@@ -188,15 +187,13 @@ dma_attach(device_t dev)
dsc->sc_ign = sbus_get_ign(dev);
dsc->sc_slot = sbus_get_slot(dev);
- lsc->sc_rid = 0;
- lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &lsc->sc_rid,
+ i = 0;
+ lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
RF_ACTIVE);
if (lsc->sc_res == NULL) {
device_printf(dev, "cannot allocate resources\n");
return (ENXIO);
}
- lsc->sc_regt = rman_get_bustag(lsc->sc_res);
- lsc->sc_regh = rman_get_bushandle(lsc->sc_res);
if (strcmp(name, "espdma") == 0 || strcmp(name, "dma") == 0)
lsc->sc_channel = L64854_CHANNEL_SCSI;
@@ -246,23 +243,17 @@ dma_attach(device_t dev)
goto fail_lres;
}
- burst = sbus_get_burstsz(dev);
- lsc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
- (burst & SBUS_BURST_16) ? 16 : 0;
+ i = sbus_get_burstsz(dev);
+ lsc->sc_burst = (i & SBUS_BURST_32) ? 32 :
+ (i & SBUS_BURST_16) ? 16 : 0;
lsc->sc_dev = dev;
- error = lsi64854_attach(lsc);
- if (error != 0) {
- device_printf(dev, "lsi64854_attach failed\n");
- goto fail_lpdma;
- }
-
/* Attach children. */
- children = 0;
+ i = 0;
for (child = OF_child(node); child != 0; child = OF_peer(child)) {
if ((ddi = dma_setup_dinfo(dev, dsc, child)) == NULL)
continue;
- if (children != 0) {
+ if (i != 0) {
device_printf(dev,
"<%s>: only one child per DMA channel supported\n",
ddi->ddi_obdinfo.obd_name);
@@ -276,14 +267,13 @@ dma_attach(device_t dev)
continue;
}
device_set_ivars(cdev, ddi);
- children++;
+ i++;
}
return (bus_generic_attach(dev));
- fail_lpdma:
- bus_dma_tag_destroy(lsc->sc_parent_dmat);
fail_lres:
- bus_release_resource(dev, SYS_RES_MEMORY, lsc->sc_rid, lsc->sc_res);
+ bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res),
+ lsc->sc_res);
return (error);
}
diff --git a/sys/sparc64/sbus/lsi64854.c b/sys/sparc64/sbus/lsi64854.c
index 7ee3bc1..94f28ba 100644
--- a/sys/sparc64/sbus/lsi64854.c
+++ b/sys/sparc64/sbus/lsi64854.c
@@ -70,9 +70,9 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
-#include <sys/resource.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/rman.h>
#include <machine/bus.h>
@@ -112,7 +112,7 @@ static int lsi64854_pp_intr(void *);
/*
* Finish attaching this DMA device.
* Front-end must fill in these fields:
- * sc_regs
+ * sc_res
* sc_burst
* sc_channel (one of SCSI, ENET, PP)
* sc_client (one of SCSI, ENET, PP `soft_c' pointers)
@@ -120,12 +120,24 @@ static int lsi64854_pp_intr(void *);
int
lsi64854_attach(struct lsi64854_softc *sc)
{
+ bus_dma_lock_t *lockfunc;
+ struct ncr53c9x_softc *nsc;
+ void *lockfuncarg;
uint32_t csr;
int error;
- /* Indirect functions */
+ lockfunc = NULL;
+ lockfuncarg = NULL;
+
switch (sc->sc_channel) {
case L64854_CHANNEL_SCSI:
+ nsc = sc->sc_client;
+ if (NCR_LOCK_INITIALIZED(nsc) == 0) {
+ device_printf(sc->sc_dev, "mutex not initialized\n");
+ return (ENXIO);
+ }
+ lockfunc = busdma_lock_mutex;
+ lockfuncarg = &nsc->sc_lock;
sc->intr = lsi64854_scsi_intr;
sc->setup = lsi64854_setup;
break;
@@ -141,29 +153,32 @@ lsi64854_attach(struct lsi64854_softc *sc)
}
sc->reset = lsi64854_reset;
- /* Allocate a dmamap */
- error = bus_dma_tag_create(
- sc->sc_parent_dmat, /* parent */
- 1, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MAX_DMA_SZ, /* maxsize */
- 1, /* nsegments */
- MAX_DMA_SZ, /* maxsegsize */
- BUS_DMA_ALLOCNOW, /* flags */
- NULL, NULL, /* lockfunc, lockarg */
- &sc->sc_buffer_dmat);
- if (error != 0) {
- device_printf(sc->sc_dev, "cannot allocate buffer DMA tag\n");
- return (error);
- }
-
- error = bus_dmamap_create(sc->sc_buffer_dmat, 0, &sc->sc_dmamap);
- if (error != 0) {
- device_printf(sc->sc_dev, "DMA map create failed\n");
- bus_dma_tag_destroy(sc->sc_buffer_dmat);
- return (error);
+ if (sc->setup != NULL) {
+ error = bus_dma_tag_create(
+ sc->sc_parent_dmat, /* parent */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MAX_DMA_SZ, /* maxsize */
+ 1, /* nsegments */
+ MAX_DMA_SZ, /* maxsegsize */
+ BUS_DMA_ALLOCNOW, /* flags */
+ lockfunc, lockfuncarg, /* lockfunc, lockfuncarg */
+ &sc->sc_buffer_dmat);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "cannot allocate buffer DMA tag\n");
+ return (error);
+ }
+
+ error = bus_dmamap_create(sc->sc_buffer_dmat, 0,
+ &sc->sc_dmamap);
+ if (error != 0) {
+ device_printf(sc->sc_dev, "DMA map create failed\n");
+ bus_dma_tag_destroy(sc->sc_buffer_dmat);
+ return (error);
+ }
}
csr = L64854_GCSR(sc);
@@ -201,16 +216,20 @@ int
lsi64854_detach(struct lsi64854_softc *sc)
{
- if (sc->setup)
+ if (sc->setup != NULL) {
+ bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
+ (L64854_GCSR(sc) & L64854_WRITE) != 0 ?
+ BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
- bus_dmamap_destroy(sc->sc_buffer_dmat, sc->sc_dmamap);
- bus_dma_tag_destroy(sc->sc_buffer_dmat);
+ bus_dmamap_destroy(sc->sc_buffer_dmat, sc->sc_dmamap);
+ bus_dma_tag_destroy(sc->sc_buffer_dmat);
+ }
return (0);
}
/*
- * DMAWAIT waits while condition is true
+ * DMAWAIT waits while condition is true.
*/
#define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \
int count = 500000; \
@@ -279,11 +298,12 @@ lsi64854_reset(struct lsi64854_softc *sc)
DPRINTF(LDB_ANY, ("%s: csr 0x%x\n", __func__, csr));
- /*
- * XXX is sync needed?
- if (sc->sc_dmamap->dm_nsegs > 0)
+ if (sc->sc_dmasize != 0) {
+ bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
+ (csr & D_WRITE) != 0 ? BUS_DMASYNC_PREREAD :
+ BUS_DMASYNC_PREWRITE);
bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
- */
+ }
if (sc->sc_rev == DMAREV_HME)
L64854_SCSR(sc, csr | D_HW_RESET_FAS366);
@@ -332,7 +352,7 @@ lsi64854_reset(struct lsi64854_softc *sc)
L64854_SCSR(sc, csr);
if (sc->sc_rev == DMAREV_HME) {
- bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR, 0);
+ bus_write_4(sc->sc_res, L64854_REG_ADDR, 0);
sc->sc_dmactl = csr;
}
sc->sc_active = 0;
@@ -352,11 +372,10 @@ lsi64854_map_scsi(void *arg, bus_dma_segment_t *segs, int nseg, int error)
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
sc->sc_datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
- bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR,
- segs[0].ds_addr);
+ bus_write_4(sc->sc_res, L64854_REG_ADDR, segs[0].ds_addr);
}
-#define DMAMAX(a) (MAX_DMA_SZ - ((a) & (MAX_DMA_SZ-1)))
+#define DMAMAX(a) (MAX_DMA_SZ - ((a) & (MAX_DMA_SZ - 1)))
/*
* setup a DMA transfer
*/
@@ -382,7 +401,7 @@ lsi64854_setup(struct lsi64854_softc *sc, caddr_t *addr, size_t *len,
* and we cannot cross a 16Mb boundary.
*/
*dmasize = sc->sc_dmasize =
- ulmin(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
+ ulmin(*dmasize, DMAMAX((size_t)*sc->sc_dmaaddr));
DPRINTF(LDB_ANY, ("%s: dmasize=%ld\n", __func__, (long)sc->sc_dmasize));
@@ -393,12 +412,11 @@ lsi64854_setup(struct lsi64854_softc *sc, caddr_t *addr, size_t *len,
L64854_SCSR(sc, sc->sc_dmactl | L64854_RESET);
L64854_SCSR(sc, sc->sc_dmactl);
- bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_CNT,
- *dmasize);
+ bus_write_4(sc->sc_res, L64854_REG_CNT, *dmasize);
}
/* Program the DMA address */
- if (sc->sc_dmasize)
+ if (sc->sc_dmasize != 0)
if (bus_dmamap_load(sc->sc_buffer_dmat, sc->sc_dmamap,
*sc->sc_dmaaddr, sc->sc_dmasize, lsi64854_map_scsi, sc, 0))
panic("%s: cannot allocate DVMA address", __func__);
@@ -408,8 +426,7 @@ lsi64854_setup(struct lsi64854_softc *sc, caddr_t *addr, size_t *len,
bcnt = sc->sc_dmasize;
if (((bcnt + (long)*sc->sc_dmaaddr) & PAGE_MASK_8K) != 0)
bcnt = roundup(bcnt, PAGE_SIZE_8K);
- bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_CNT,
- bcnt);
+ bus_write_4(sc->sc_res, L64854_REG_CNT, bcnt);
}
/* Setup DMA control register */
@@ -447,8 +464,7 @@ lsi64854_scsi_intr(void *arg)
csr = L64854_GCSR(sc);
DPRINTF(LDB_SCSI, ("%s: addr 0x%x, csr %b\n", __func__,
- bus_space_read_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR), csr,
- DDMACSR_BITS));
+ bus_read_4(sc->sc_res, L64854_REG_ADDR), csr, DDMACSR_BITS));
if (csr & (D_ERR_PEND|D_SLAVE_ERR)) {
device_printf(sc->sc_dev, "error: csr=%b\n", csr, DDMACSR_BITS);
@@ -530,14 +546,12 @@ lsi64854_scsi_intr(void *arg)
(nsc->sc_cfg2 & NCRCFG2_FE) ? NCR_READ_REG(nsc, NCR_TCH) : 0,
trans, resid));
-#if 0 /* XXX */
- if (sc->sc_dmamap->dm_nsegs > 0) {
+ if (sc->sc_dmasize != 0) {
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
(csr & D_WRITE) != 0 ? BUS_DMASYNC_POSTREAD :
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
}
-#endif
*sc->sc_dmalen -= trans;
*sc->sc_dmaaddr += trans;
@@ -604,11 +618,9 @@ lsi64854_map_pp(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap, sc->sc_datain ?
BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
- bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR,
- segs[0].ds_addr);
+ bus_write_4(sc->sc_res, L64854_REG_ADDR, segs[0].ds_addr);
- bus_space_write_4(sc->sc_regt, sc->sc_regh, L64854_REG_CNT,
- sc->sc_dmasize);
+ bus_write_4(sc->sc_res, L64854_REG_CNT, sc->sc_dmasize);
}
/*
@@ -635,12 +647,12 @@ lsi64854_setup_pp(struct lsi64854_softc *sc, caddr_t *addr, size_t *len,
* and we cannot cross a 16Mb boundary.
*/
*dmasize = sc->sc_dmasize =
- ulmin(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
+ ulmin(*dmasize, DMAMAX((size_t)*sc->sc_dmaaddr));
DPRINTF(LDB_PP, ("%s: dmasize=%ld\n", __func__, (long)sc->sc_dmasize));
/* Program the DMA address */
- if (sc->sc_dmasize)
+ if (sc->sc_dmasize != 0)
if (bus_dmamap_load(sc->sc_buffer_dmat, sc->sc_dmamap,
*sc->sc_dmaaddr, sc->sc_dmasize, lsi64854_map_pp, sc, 0))
panic("%s: pp cannot allocate DVMA address", __func__);
@@ -680,12 +692,10 @@ lsi64854_pp_intr(void *arg)
csr = L64854_GCSR(sc);
DPRINTF(LDB_PP, ("%s: addr 0x%x, csr %b\n", __func__,
- bus_space_read_4(sc->sc_regt, sc->sc_regh, L64854_REG_ADDR), csr,
- PDMACSR_BITS));
+ bus_read_4(sc->sc_res, L64854_REG_ADDR), csr, PDMACSR_BITS));
if (csr & (P_ERR_PEND|P_SLAVE_ERR)) {
- resid = bus_space_read_4(sc->sc_regt, sc->sc_regh,
- L64854_REG_CNT);
+ resid = bus_read_4(sc->sc_res, L64854_REG_CNT);
device_printf(sc->sc_dev, "error: resid %d csr=%b\n", resid,
csr, PDMACSR_BITS);
csr &= ~P_EN_DMA; /* Stop DMA */
@@ -699,8 +709,7 @@ lsi64854_pp_intr(void *arg)
if (sc->sc_active != 0) {
DMA_DRAIN(sc, 0);
- resid = bus_space_read_4(sc->sc_regt, sc->sc_regh,
- L64854_REG_CNT);
+ resid = bus_read_4(sc->sc_res, L64854_REG_CNT);
}
/* DMA has stopped */
@@ -714,14 +723,12 @@ lsi64854_pp_intr(void *arg)
*sc->sc_dmalen -= trans;
*sc->sc_dmaaddr += trans;
-#if 0 /* XXX */
- if (sc->sc_dmamap->dm_nsegs > 0) {
+ if (sc->sc_dmasize != 0) {
bus_dmamap_sync(sc->sc_buffer_dmat, sc->sc_dmamap,
(csr & D_WRITE) != 0 ? BUS_DMASYNC_POSTREAD :
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_buffer_dmat, sc->sc_dmamap);
}
-#endif
return (ret != 0);
}
diff --git a/sys/sparc64/sbus/lsi64854var.h b/sys/sparc64/sbus/lsi64854var.h
index 9cdd0e3..f0147e0 100644
--- a/sys/sparc64/sbus/lsi64854var.h
+++ b/sys/sparc64/sbus/lsi64854var.h
@@ -41,10 +41,7 @@
struct lsi64854_softc {
device_t sc_dev;
- int sc_rid;
struct resource *sc_res;
- bus_space_handle_t sc_regh;
- bus_space_tag_t sc_regt;
u_int sc_rev; /* revision */
int sc_burst; /* max suported burst size */
@@ -54,7 +51,7 @@ struct lsi64854_softc {
#define L64854_CHANNEL_PP 3
void *sc_client;
- int sc_active; /* DMA active ? */
+ int sc_active; /* DMA active? */
bus_dmamap_t sc_dmamap; /* DMA map for bus_dma_* */
bus_dma_tag_t sc_parent_dmat;
@@ -73,12 +70,8 @@ struct lsi64854_softc {
int sc_dodrain;
};
-#define L64854_GCSR(sc) \
- (bus_space_read_4((sc)->sc_regt, (sc)->sc_regh, L64854_REG_CSR))
-
-#define L64854_SCSR(sc, csr) \
- bus_space_write_4((sc)->sc_regt, (sc)->sc_regh, L64854_REG_CSR, csr)
-
+#define L64854_GCSR(sc) bus_read_4((sc)->sc_res, L64854_REG_CSR)
+#define L64854_SCSR(sc, csr) bus_write_4((sc)->sc_res, L64854_REG_CSR, csr)
/*
* DMA engine interface functions.
@@ -86,7 +79,6 @@ struct lsi64854_softc {
#define DMA_RESET(sc) (((sc)->reset)(sc))
#define DMA_INTR(sc) (((sc)->intr)(sc))
#define DMA_SETUP(sc, a, l, d, s) (((sc)->setup)(sc, a, l, d, s))
-
#define DMA_ISACTIVE(sc) ((sc)->sc_active)
#define DMA_ENINTR(sc) do { \
@@ -104,6 +96,5 @@ struct lsi64854_softc {
sc->sc_active = 1; \
} while (0)
-
int lsi64854_attach(struct lsi64854_softc *);
int lsi64854_detach(struct lsi64854_softc *);
OpenPOWER on IntegriCloud