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