PERFORCE change 179638 for review
Jakub Wojciech Klama
jceel at FreeBSD.org
Tue Jun 15 09:13:03 UTC 2010
http://p4web.freebsd.org/@@179638?ac=10
Change 179638 by jceel at jceel on 2010/06/15 09:12:27
* Improved DMAE API to use resources
* Improved DaVinci EDMA3 driver (implemented basic error handling)
Affected files ...
.. //depot/projects/soc2010/jceel_dma/sys/arm/davinci/davinci_edma.c#2 edit
.. //depot/projects/soc2010/jceel_dma/sys/dev/dmae/dmae.c#2 edit
.. //depot/projects/soc2010/jceel_dma/sys/dev/dmae/dmae.h#2 edit
.. //depot/projects/soc2010/jceel_dma/sys/dev/dmae/dmae_cdev.c#2 edit
.. //depot/projects/soc2010/jceel_dma/sys/dev/dmae/dmae_cdev.h#2 edit
Differences ...
==== //depot/projects/soc2010/jceel_dma/sys/arm/davinci/davinci_edma.c#2 (text+ko) ====
@@ -110,6 +110,13 @@
{ -1, 0 }
};
+static const struct dmae_capabilities davinci_edma_caps = {
+ .dc_nchannels = DAVINCI_EDMA_NCHANNELS,
+ .dc_ops = DMAE_COPY,
+ .dc_buffers = DMAEBUF_BLOCK | DMAEBUF_FRAME | DMAEBUF_FIFO,
+ .dc_flags = DMAECAP_REPEAT | DMAECAP_LINK,
+};
+
static int davinci_edma_probe(device_t);
static int davinci_edma_attach(device_t);
static int davinci_edma_setup_channel(device_t, int, struct dmae_transfer *);
@@ -137,7 +144,7 @@
#define davinci_write_edmacc_4(_sc, _reg, _data) \
bus_space_write_4((_sc)->ds_bst, (_sc)->ds_bsh, DAVINCI_EDMACC_BASE + (_reg), (_data))
#define davinci_edma_copydesc(_sc, _desc, _idx) \
- memcpy((uint8_t *)(0xd1c00000 + DAVINCI_EDMA_PARAM(_idx)), (_desc), sizeof(param_desc))
+ memcpy((uint8_t *)(DAVINCI_EDMA_BASE + DAVINCI_EDMA_PARAM(_idx)), (_desc), sizeof(param_desc))
static int
@@ -151,14 +158,15 @@
davinci_edma_attach(device_t dev)
{
struct davinci_edma_softc *sc = device_get_softc(dev);
-
+ int i;
+
sc->ds_dev = dev;
mtx_init(&sc->ds_mtx, "edma", "dma", MTX_DEF);
if (bus_alloc_resources(dev, davinci_edma_spec, sc->ds_res)) {
device_printf(dev, "could not allocate resources\n");
- return (ENXIO);
+ goto out;
}
sc->ds_bst = rman_get_bustag(sc->ds_res[0]);
@@ -169,25 +177,28 @@
NULL, davinci_edma_intr_cc, sc, &sc->ds_intrhand[0])) {
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->ds_res[0]);
device_printf(dev, "cannot setup interrupt handler\n");
- return (ENXIO);
+ goto out;
}
/* EDMACC_ERRINT */
if (bus_setup_intr(dev, sc->ds_res[2], INTR_TYPE_MISC | INTR_MPSAFE,
NULL, davinci_edma_intr_ccerr, sc, &sc->ds_intrhand[1])) {
-
+ device_printf(dev, "cannot setup interrupt handler\n");
+ goto out;
}
/* EDMATC_ERRINT0 */
if (bus_setup_intr(dev, sc->ds_res[3], INTR_TYPE_MISC | INTR_MPSAFE,
NULL, davinci_edma_intr_tcerr0, sc, &sc->ds_intrhand[2])) {
-
+ device_printf(dev, "cannot setup interrupt handler\n");
+ goto out;
}
/* EDMATC_ERRINT1 */
if (bus_setup_intr(dev, sc->ds_res[4], INTR_TYPE_MISC | INTR_MPSAFE,
NULL, davinci_edma_intr_tcerr1, sc, &sc->ds_intrhand[3])) {
-
+ device_printf(dev, "cannot setup interrupt handler\n");
+ goto out;
}
bus_dma_tag_create(
@@ -208,9 +219,20 @@
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_DRAE0, 0xffffffff);
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_DRAEH0, 0xffffffff);
- dmae_register_driver(dev, DAVINCI_EDMA_NCHANNELS, sc->ds_dmatag);
+ dmae_register_driver(dev, &davinci_edma_caps, sc->ds_dmatag);
return (0);
+
+out:
+ for (i = 0; i < 4; i++) {
+ if (sc->ds_intrhand[i] != NULL)
+ bus_teardown_intr(dev, sc->ds_res[i + 1],
+ sc->ds_intrhand[i]);
+ }
+
+ bus_release_resources(dev, davinci_edma_spec, sc->ds_res);
+
+ return (ENXIO);
}
static int
@@ -350,7 +372,6 @@
return (0);
}
-
static void
davinci_edma_intr_cc(void *arg)
{
@@ -377,8 +398,11 @@
KASSERT(ch->dc_status == CHANNEL_ACTIVE, "edma spurious interrupt");
- if (xfer->dt_callback != NULL)
- xfer->dt_callback(1, xfer->dt_callback_arg, xfer);
+ if (xfer->dt_callback != NULL) {
+ xfer->dt_callback(DMAE_TRANSFER_COMPLETED,
+ xfer->dt_callback_arg);
+ }
+
ch->dc_status = 0;
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_ICR, (1 << chno));
@@ -387,15 +411,20 @@
while ((chno = (ffs(iprh) + 31)) != 31) {
ch = &sc->ds_channels[chno];
+ xfer = ch->dc_xfer;
+
KASSERT(ch->dc_status == CHANNEL_ACTIVE, "edma spurious interrupt");
debugf("interrupt on channel %d", chno);
- if (xfer->dt_callback != NULL)
- xfer->dt_callback(1, xfer->dt_callback_arg, xfer);
+ if (xfer->dt_callback != NULL) {
+ xfer->dt_callback(DMAE_TRANSFER_COMPLETED,
+ xfer->dt_callback_arg);
+ }
ch->dc_status = 0;
davinci_write_edmacc_4(sc, DAVINCI_EDMACC_ICRH, (1 << (chno-32)));
+ ipr &= ~(1 << (chno - 32));
}
}
@@ -406,7 +435,51 @@
davinci_edma_intr_ccerr(void *arg)
{
struct davinci_edma_softc *sc = (struct davinci_edma_softc *)arg;
- device_printf(sc->ds_dev, "edma_intr_ccerr\n");
+ struct davinci_edma_channel *ch;
+ struct dmae_transfer *xfer = NULL;
+ uint32_t emr, emrh;
+ int chno;
+
+ emr = davinci_read_edmacc_4(sc, DAVINCI_EDMACC_EMR);
+ emrh = davinci_read_edmacc_4(sc, DAVINCI_EDMACC_EMRH);
+
+ if (emr == 0 && emrh == 0)
+ return;
+
+ while ((chno = (ffs(emr) - 1)) != -1) {
+ ch = &sc->ds_channels[chno];
+ xfer = ch->dc_xfer;
+
+ debugf("error interrupt on channel %d", chno);
+
+ KASSERT(ch->dc_status == CHANNEL_ACTIVE, "edma spurious interrupt");
+
+ if (xfer->dt_callback != NULL) {
+ xfer->dt_callback(DMAE_TRANSFER_ERROR,
+ xfer->dt_callback_arg);
+ }
+
+ ch->dc_status = 0;
+
+ davinci_write_edmacc_4(sc, DAVINCI_EDMACC_EMR, (1 << chno));
+ emr &= ~(1 << chno);
+ }
+
+ while ((chno = (ffs(emrh) + 31)) != 31) {
+ ch = &sc->ds_channels[chno];
+ KASSERT(ch->dc_status == CHANNEL_ACTIVE, "edma spurious interrupt");
+
+ debugf("error interrupt on channel %d", chno);
+
+ if (xfer->dt_callback != NULL) {
+ xfer->dt_callback(DMAE_TRANSFER_ERROR,
+ xfer->dt_callback_arg);
+ }
+
+ ch->dc_status = 0;
+ davinci_write_edmacc_4(sc, DAVINCI_EDMACC_EMRH, (1 << (chno-32)));
+ emr &= ~(1 << (chno - 32));
+ }
}
static void
==== //depot/projects/soc2010/jceel_dma/sys/dev/dmae/dmae.c#2 (text+ko) ====
@@ -59,13 +59,14 @@
LIST_HEAD(, dmae_engine) dmae_engines;
struct mtx dmae_engines_mtx;
-struct dmae_engine *dmae_engine_by_name(const char *);
-void dmae_dmamap_load_cb(void *, bus_dma_segment_t *, int, int);
-void dmae_dmamap_load_cb2(void *, bus_dma_segment_t *, int, bus_size_t, int);
+static struct dmae_engine *dmae_engine_by_name(const char *);
+static struct dmae_engine *dmae_engine_by_res(struct resource *);
+static void dmae_dmamap_load_cb(void *, bus_dma_segment_t *, int, int);
+static void dmae_dmamap_load_cb2(void *, bus_dma_segment_t *, int, bus_size_t, int);
void dmae_init(void *);
static int dmae_check_transfer(struct dmae_transfer *);
-void
+static void
dmae_dmamap_load_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
bus_dma_segment_t *seg = (bus_dma_segment_t *)arg;
@@ -76,7 +77,7 @@
seg->ds_len = segs[0].ds_len;
}
-void
+static void
dmae_dmamap_load_cb2(void *arg, bus_dma_segment_t *segs, int nseg,
bus_size_t mapsize, int error)
{
@@ -104,17 +105,19 @@
}
int
-dmae_register_driver(device_t dev, int nchannels, bus_dma_tag_t dmatag)
+dmae_register_driver(device_t dev, const struct dmae_capabilities *caps,
+ bus_dma_tag_t dmatag)
{
struct dmae_engine *engine;
struct dmae_engine_cdev *cdev;
+ struct resource *rv;
int i;
engine = malloc(sizeof(struct dmae_engine), M_DMAE, M_WAITOK);
engine->de_dev = dev;
engine->de_dmatag = dmatag;
- engine->de_nchannels = nchannels;
+ engine->de_caps = caps;
mtx_lock(&dmae_engines_mtx);
LIST_INSERT_HEAD(&dmae_engines, engine, de_link);
@@ -123,19 +126,20 @@
engine->de_rman.rm_type = RMAN_ARRAY;
engine->de_rman.rm_descr = "DMA engine channels";
engine->de_rman.rm_start = 0;
- engine->de_rman.rm_end = nchannels;
+ engine->de_rman.rm_end = caps->dc_nchannels;
if (rman_init(&engine->de_rman))
panic("cannot init DMA channels rman");
- if (rman_manage_region(&engine->de_rman, 0, nchannels))
+ if (rman_manage_region(&engine->de_rman, 0, caps->dc_nchannels))
panic("cannot init DMA channels rman");
printf("registered new DMA engine: %s\n", device_get_nameunit(dev));
LIST_INIT(&engine->de_cdevs);
- for (i = 0; i < nchannels; i++) {
+ for (i = 0; i < caps->dc_nchannels; i++) {
cdev = malloc(sizeof(*cdev), M_DMAE, M_WAITOK);
- dmae_make_cdev(engine, i, &cdev->dec_cdev);
+ rv = dmae_alloc_channel(device_get_nameunit(engine->de_dev), i);
+ dmae_make_cdev(engine, rv, &cdev->dec_cdev);
LIST_INSERT_HEAD(&engine->de_cdevs, cdev, dec_link);
}
@@ -159,7 +163,7 @@
return (0);
}
-struct dmae_engine *
+static struct dmae_engine *
dmae_engine_by_name(const char *name)
{
struct dmae_engine *engine;
@@ -172,29 +176,44 @@
return (NULL);
}
+static struct dmae_engine *
+dmae_engine_by_res(struct resource *res)
+{
+ struct dmae_engine *engine;
+
+ LIST_FOREACH(engine, &dmae_engines, de_link) {
+ if (rman_is_region_manager(res, &engine->de_rman))
+ return (engine);
+ }
+
+ return (NULL);
+}
+
struct resource *
-dmae_alloc_channel(dmae_engine_t engine, int chno)
+dmae_alloc_channel(const char *name, int chno)
{
struct resource *rv;
+ struct dmae_engine *engine = dmae_engine_by_name(name);
- rv = rman_reserve_resource(&engine->de_rman, chno, chno, 1, RF_ACTIVE, NULL);
+ rv = rman_reserve_resource(&engine->de_rman, chno, chno, 1,
+ RF_ACTIVE, NULL);
- return rv;
+ return (rv);
}
int
-dmae_release_channel(dmae_engine_t engine, struct resource *res)
+dmae_release_channel(struct resource *res)
{
- return (0);
+ return (rman_release_resource(res));
}
void *
-dmae_setup_transfer(struct resource *res, struct dmae_transfer *xfer)
+dmae_program_transfer(struct dmae_transfer *xfer)
{
struct dmae_engine *engine = xfer->dt_engine;
- int channel = rman_get_start(res);
+ int channel = rman_get_start(xfer->dt_res);
- if (rman_get_size(res) != 1)
+ if (rman_get_size(xfer->dt_res) != 1)
return (NULL);
if (engine == NULL)
@@ -206,7 +225,6 @@
if (DMAE_SETUP_CHANNEL(engine->de_dev, channel, xfer))
return (NULL);
- xfer->dt_res = res;
return (xfer);
}
@@ -217,27 +235,32 @@
struct dmae_engine *engine = xfer->dt_engine;
int channel = rman_get_start(xfer->dt_res);
- if (DMAE_START_CHANNEL(engine->de_dev, channel))
- return (ENXIO);
-
- return (0);
+ return (DMAE_START_CHANNEL(engine->de_dev, channel));
}
int
dmae_stop_transfer(void *cookie)
{
- return (0);
+ struct dmae_transfer *xfer = (struct dmae_transfer *)cookie;
+ struct dmae_engine *engine = xfer->dt_engine;
+ int channel = rman_get_start(xfer->dt_res);
+
+ return (DMAE_STOP_CHANNEL(engine->de_dev, channel));
}
struct dmae_transfer *
-dmae_alloc_transfer(dmae_engine_t engine)
-
+dmae_alloc_transfer(struct resource *res)
{
struct dmae_transfer *xfer;
+ struct dmae_engine *engine = dmae_engine_by_res(res);
+ if (engine == NULL)
+ return (NULL);
+
xfer = malloc(sizeof(struct dmae_transfer), M_DMAE, M_WAITOK);
+ xfer->dt_res = res;
+ xfer->dt_engine = engine;
- xfer->dt_engine = engine;
return (xfer);
}
@@ -294,5 +317,55 @@
return (0);
}
+inline void
+dmae_set_transfer_opts(struct dmae_transfer *xfer, int flags)
+{
+ xfer->dt_flags = flags;
+}
+
+inline void
+dmae_set_transfer_link(struct dmae_transfer *xfer, struct dmae_transfer *xfer2)
+{
+ xfer->dt_next = xfer2;
+}
+
+inline void
+dmae_set_transfer_callback(struct dmae_transfer *xfer, dmae_callback_t cb, void *arg)
+{
+ xfer->dt_callback = cb;
+ xfer->dt_callback_arg = arg;
+}
+
+inline void
+dmae_set_transfer_flags(struct dmae_transfer *xfer, int flags)
+{
+ xfer->dt_flags = flags;
+}
+
+inline int
+dmae_get_buffer_layout(struct dmae_transfer *xfer, int buffer)
+{
+ return (xfer->dt_buffers[buffer].db_type);
+}
+
+inline void
+dmae_set_buffer_layout(struct dmae_transfer *xfer, int buffer, int type)
+{
+ xfer->dt_buffers[buffer].db_type = type;
+}
+
+inline void
+dmae_set_buffer_stride(struct dmae_transfer *xfer, int buffer, int stride_width, int stride_spacing)
+{
+ xfer->dt_buffers[buffer].db_stride_width = stride_width;
+ xfer->dt_buffers[buffer].db_stride_spacing = stride_spacing;
+}
+
+inline void
+dmae_set_buffer_fifo_width(struct dmae_transfer *xfer, int buffer, int width)
+{
+ xfer->dt_buffers[buffer].db_fifo_width = width;
+}
+
SYSINIT(dmae, SI_SUB_DRIVERS, SI_ORDER_FIRST, dmae_init, NULL);
==== //depot/projects/soc2010/jceel_dma/sys/dev/dmae/dmae.h#2 (text+ko) ====
@@ -42,16 +42,19 @@
struct dmae_buffer;
typedef struct dmae_engine *dmae_engine_t;
-typedef int (*dmae_callback_t)(int, void *, struct dmae_transfer *);
+typedef struct dmae_transfer *dmae_transfer_t;
+typedef int (*dmae_callback_t)(int status, void *arg);
enum dmae_op {
- DMAE_FILL,
- DMAE_COPY,
- DMAE_XOR,
+ DMAE_FILL = 0x1,
+ DMAE_COPY = 0x2,
+ DMAE_XOR = 0x4,
};
enum dmae_transfer_status {
DMAE_TRANSFER_COMPLETED,
+ DMAE_TRANSFER_COMPLETED_STRIDE,
+ DMAE_TRANSFER_COMPLETED_LINK,
DMAE_TRANSFER_CANCELLED,
DMAE_TRANSFER_ERROR,
};
@@ -59,12 +62,22 @@
struct dmae_engine {
device_t de_dev;
bus_dma_tag_t de_dmatag;
- int de_nchannels;
+ const struct dmae_capabilities *de_caps;
+#define de_nchannels (de_caps->de_nchannels)
struct rman de_rman;
LIST_ENTRY(dmae_engine) de_link;
LIST_HEAD(, dmae_engine_cdev) de_cdevs;
};
+struct dmae_capabilities {
+ uint32_t dc_ops;
+ uint32_t dc_buffers;
+ uint32_t dc_flags;
+#define DMAECAP_REPEAT 0x1
+#define DMAECAP_LINK 0x2
+ int dc_nchannels;
+};
+
struct dmae_engine_cdev {
struct cdev * dec_cdev;
LIST_ENTRY(dmae_engine_cdev) dec_link;
@@ -90,18 +103,18 @@
int dt_type;
int dt_op;
int dt_flags;
-#define DMAE_TRANSFER_EXTTRIG 0x1
-#define DMAE_TRANSFER_REPEAT 0x2
-#define DMAE_TRANSFER_NOINTR 0x4
-#define DMAE_TRANSFER_STRIDE_CALLBACK 0x8
-#define DMAE_TRANSFER_LINK_CALLBACK 0x10
+#define DMAE_TRANSFER_EXTTRIG 0x1 /* transfer is triggered by external source */
+#define DMAE_TRANSFER_REPEAT 0x2 /* repeat transfer until cancel */
+#define DMAE_TRANSFER_NOINTR 0x4 /* don't generate callbacks */
+#define DMAE_TRANSFER_STRIDE_CALLBACK 0x8 /* callback on every stride */
+#define DMAE_TRANSFER_LINK_CALLBACK 0x10 /* callback on every linked transfer */
dmae_callback_t dt_callback;
void * dt_callback_arg;
struct dmae_buffer dt_buffers[8];
+#define dt_dst dt_buffers[0]
+#define dt_src dt_buffers[1]
#define DMAE_BUF_DST 0
#define DMAE_BUF_SRC 1
-#define dt_dst dt_buffers[0]
-#define dt_src dt_buffers[1]
struct dmae_transfer * dt_next;
/* Private fields: */
@@ -110,25 +123,37 @@
};
enum dmae_buffer_type {
- DMAEBUF_BLOCK,
- DMAEBUF_FRAME,
- DMAEBUF_FIFO,
+ DMAEBUF_BLOCK = 0x1,
+ DMAEBUF_FRAME = 0x2,
+ DMAEBUF_FIFO = 0x4,
};
-int dmae_register_driver(device_t, int, bus_dma_tag_t);
+int dmae_register_driver(device_t, const struct dmae_capabilities *, bus_dma_tag_t);
int dmae_unregister_driver(device_t);
-struct resource *dmae_alloc_channel(dmae_engine_t, int);
-int dmae_release_channel(dmae_engine_t, struct resource *);
-struct dmae_transfer *dmae_alloc_transfer(dmae_engine_t);
-void dmae_free_transfer(struct dmae_transfer *);
-void *dmae_setup_transfer(struct resource *, struct dmae_transfer *);
+struct resource *dmae_alloc_channel(const char *name, int);
+int dmae_release_channel(struct resource *);
+
+dmae_transfer_t dmae_alloc_transfer(struct resource *);
+void dmae_free_transfer(dmae_transfer_t);
+void *dmae_program_transfer(dmae_transfer_t);
int dmae_start_transfer(void *);
int dmae_stop_transfer(void *);
-int dmae_setup_buffer_raw(struct dmae_transfer *, int, bus_addr_t, bus_size_t);
-int dmae_setup_buffer_virt(struct dmae_transfer *, int, void *, size_t);
-int dmae_setup_buffer_uio(struct dmae_transfer *, int, struct uio *);
+int dmae_setup_buffer_raw(dmae_transfer_t, int, bus_addr_t, bus_size_t);
+int dmae_setup_buffer_virt(dmae_transfer_t, int, void *, size_t);
+int dmae_setup_buffer_uio(dmae_transfer_t, int, struct uio *);
+
+void dmae_set_transfer_func(dmae_transfer_t, int);
+void dmae_set_transfer_opts(dmae_transfer_t, int);
+void dmae_set_transfer_link(dmae_transfer_t, dmae_transfer_t);
+void dmae_set_transfer_callback(dmae_transfer_t, dmae_callback_t, void *);
+void dmae_set_transfer_flags(dmae_transfer_t, int);
+
+int dmae_get_buffer_layout(dmae_transfer_t, int);
+void dmae_set_buffer_layout(dmae_transfer_t, int, int);
+void dmae_set_buffer_stride(dmae_transfer_t, int, int, int);
+void dmae_set_buffer_fifo_width(dmae_transfer_t, int, int);
#endif /* _SYS_DEV_DMAE_DMAE_H */
==== //depot/projects/soc2010/jceel_dma/sys/dev/dmae/dmae_cdev.c#2 (text+ko) ====
@@ -51,7 +51,7 @@
static d_read_t dmae_cdev_read;
static d_write_t dmae_cdev_write;
-static int dmae_cdev_callback(int, void *, struct dmae_transfer *);
+static int dmae_cdev_callback(int, void *);
enum dmae_cdev_state {
DCS_CLOSED,
@@ -143,7 +143,11 @@
}
if (dcs->dcs_state == DCS_COMPLETED) {
- resp.drp_status = dcs->dcs_status;
+ if (dcs->dcs_status == DMAE_TRANSFER_COMPLETED)
+ resp.drp_status = 0;
+ else
+ resp.drp_status = EIO;
+
ret = uiomove(&resp, sizeof(resp), uio);
if (ret) {
dcs_unlock(dcs);
@@ -193,25 +197,36 @@
length = req.dcr_src.dcb_iov.iov_len;
xfer = dcs->dcs_xfer;
- xfer->dt_callback = &dmae_cdev_callback;
- xfer->dt_callback_arg = dcs;
+
+ /* Set transfer callback */
+ dmae_set_transfer_callback(xfer, &dmae_cdev_callback, dcs);
/* Setup source buffer */
setup_uio(&uiosrc, &req.dcr_src.dcb_iov, uio->uio_td);
dmae_setup_buffer_uio(xfer, DMAE_BUF_SRC, &uiosrc);
- xfer->dt_src.db_type = req.dcr_src.dcb_type;
- xfer->dt_src.db_stride_width = req.dcr_src.dcb_stride_width;
- xfer->dt_src.db_stride_spacing = req.dcr_src.dcb_stride_spacing;
+ dmae_set_buffer_layout(xfer, DMAE_BUF_SRC, req.dcr_src.dcb_type);
+ debugf("SRC buffer type: %d\n", req.dcr_src.dcb_type);
+ if (req.dcr_src.dcb_type == DMAE_CDEVBUF_FRAME) {
+ debugf("setting stride parameters for SRC buffer...\n");
+ dmae_set_buffer_stride(xfer, DMAE_BUF_SRC,
+ req.dcr_src.dcb_stride_width,
+ req.dcr_src.dcb_stride_spacing);
+ }
/* Setup destination buffer */
setup_uio(&uiodst, &req.dcr_dst.dcb_iov, uio->uio_td);
dmae_setup_buffer_uio(xfer, DMAE_BUF_DST, &uiodst);
- xfer->dt_dst.db_type = req.dcr_dst.dcb_type;
- xfer->dt_dst.db_stride_width = req.dcr_dst.dcb_stride_width;
- xfer->dt_dst.db_stride_spacing = req.dcr_dst.dcb_stride_spacing;
+ dmae_set_buffer_layout(xfer, DMAE_BUF_DST, req.dcr_dst.dcb_type);
+ debugf("DST buffer type: %d\n", req.dcr_dst.dcb_type);
+ if (req.dcr_dst.dcb_type == DMAEBUF_FRAME) {
+ debugf("setting stride parameters for DST buffer...\n");
+ dmae_set_buffer_stride(xfer, DMAE_BUF_DST,
+ req.dcr_dst.dcb_stride_width,
+ req.dcr_dst.dcb_stride_spacing);
+ }
/* Setup transfer */
- dcs->dcs_xfercookie = dmae_setup_transfer(dcs->dcs_res, xfer);
+ dcs->dcs_xfercookie = dmae_program_transfer(xfer);
dmae_start_transfer(dcs->dcs_xfercookie);
dcs->dcs_state = DCS_ACTIVE;
@@ -221,7 +236,7 @@
}
static int
-dmae_cdev_callback(int status, void *arg, struct dmae_transfer *xfer)
+dmae_cdev_callback(int status, void *arg)
{
struct dmae_cdev_softc *dcs = arg;
@@ -243,12 +258,10 @@
}
int
-dmae_make_cdev(struct dmae_engine *dmae, int chno, struct cdev **cdev)
+dmae_make_cdev(struct dmae_engine *dmae, struct resource *rv, struct cdev **cdev)
{
struct dmae_cdev_softc *dcs;
- struct resource *rv;
- rv = dmae_alloc_channel(dmae, chno);
if (rv == NULL)
return (ENXIO);
@@ -259,14 +272,14 @@
0600,
"%s.%d",
device_get_nameunit(dmae->de_dev),
- chno);
+ (int)rman_get_start(rv));
dcs = malloc(sizeof(*dcs), M_DMAE, M_WAITOK);
mtx_init(&dcs->dcs_mtx, "dcsmtx", "dmae", MTX_DEF);
dcs->dcs_engine = dmae;
dcs->dcs_state = DCS_CLOSED;
dcs->dcs_res = rv;
- dcs->dcs_xfer = dmae_alloc_transfer(dmae);
+ dcs->dcs_xfer = dmae_alloc_transfer(rv);
(*cdev)->si_drv1 = dcs;
==== //depot/projects/soc2010/jceel_dma/sys/dev/dmae/dmae_cdev.h#2 (text+ko) ====
@@ -29,8 +29,8 @@
#define _SYS_DEV_DMAE_DMAE_CDEV_H
enum dmae_cdev_buftype {
- DMAE_CDEVBUF_BLOCK,
- DMAE_CDEVBUF_FRAME,
+ DMAE_CDEVBUF_BLOCK = 0x1,
+ DMAE_CDEVBUF_FRAME = 0x2,
};
struct dmae_cdev_buffer {
@@ -52,7 +52,7 @@
};
#ifdef _KERNEL
-int dmae_make_cdev(struct dmae_engine *, int, struct cdev **);
+int dmae_make_cdev(struct dmae_engine *, struct resource *, struct cdev **);
#endif /* _KERNEL */
#endif /* _SYS_DEV_DMAE_DMAE_CDEV_H */
More information about the p4-projects
mailing list