Index: uspace/lib/c/generic/device/hw_res.c
===================================================================
--- uspace/lib/c/generic/device/hw_res.c	(revision e6def65eb670def5f05126e61250ce88606c3966)
+++ uspace/lib/c/generic/device/hw_res.c	(revision 9991c47fc8c46d0e24bc1c32ff3c50cc3e8b340d)
@@ -84,4 +84,18 @@
 }
 
+int hw_res_dma_channel_setup(async_sess_t *sess,
+    unsigned channel, uint32_t pa, uint16_t size, uint8_t mode)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (exch == NULL)
+		return ENOMEM;
+	uint32_t packed = size | (mode << 16);
+	int ret = async_req_4_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_DMA_CHANNEL_SETUP, channel, pa, packed);
+	async_exchange_end(exch);
+	
+	return ret;
+}
+
 /** @}
  */
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision e6def65eb670def5f05126e61250ce88606c3966)
+++ uspace/lib/c/include/device/hw_res.h	(revision 9991c47fc8c46d0e24bc1c32ff3c50cc3e8b340d)
@@ -43,5 +43,6 @@
 typedef enum {
 	HW_RES_GET_RESOURCE_LIST = 0,
-	HW_RES_ENABLE_INTERRUPT
+	HW_RES_ENABLE_INTERRUPT,
+	HW_RES_DMA_CHANNEL_SETUP,
 } hw_res_method_t;
 
@@ -105,4 +106,15 @@
 extern bool hw_res_enable_interrupt(async_sess_t *);
 
+#define DMA_MODE_WRITE (1 << 2)
+#define DMA_MODE_READ (1 << 3)
+#define DMA_MODE_AUTO (1 << 4)
+#define DMA_MODE_DOWN (1 << 5)
+#define DMA_MODE_SINGLE (1 << 6)
+#define DMA_MODE_BLOCK (1 << 7)
+#define DMA_MODE_ON_DEMAND (0)
+
+extern int hw_res_dma_channel_setup(async_sess_t *,
+    unsigned, uint32_t, uint16_t, uint8_t);
+
 #endif
 
Index: uspace/lib/drv/generic/remote_hw_res.c
===================================================================
--- uspace/lib/drv/generic/remote_hw_res.c	(revision e6def65eb670def5f05126e61250ce88606c3966)
+++ uspace/lib/drv/generic/remote_hw_res.c	(revision 9991c47fc8c46d0e24bc1c32ff3c50cc3e8b340d)
@@ -43,8 +43,11 @@
 static void remote_hw_res_enable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
+static void remote_hw_res_dma_channel_setup(ddf_fun_t *, void *, ipc_callid_t,
+    ipc_call_t *);
 
 static remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
-	&remote_hw_res_get_resource_list,
-	&remote_hw_res_enable_interrupt
+	[HW_RES_GET_RESOURCE_LIST] = &remote_hw_res_get_resource_list,
+	[HW_RES_ENABLE_INTERRUPT] = &remote_hw_res_enable_interrupt,
+	[HW_RES_DMA_CHANNEL_SETUP] = &remote_hw_res_dma_channel_setup,
 };
 
@@ -94,4 +97,23 @@
 }
 
+static void remote_hw_res_dma_channel_setup(ddf_fun_t *fun, void *ops,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	hw_res_ops_t *hw_res_ops = ops;
+
+	if (hw_res_ops->dma_channel_setup == NULL) {
+		async_answer_0(callid, ENOTSUP);
+		return;
+	}
+	const unsigned channel = DEV_IPC_GET_ARG1(*call);
+	const uint32_t address = DEV_IPC_GET_ARG2(*call);
+	const uint16_t size = DEV_IPC_GET_ARG3(*call) & 0xffff;
+	const uint8_t mode = DEV_IPC_GET_ARG3(*call) >> 16;
+
+	const int ret = hw_res_ops->dma_channel_setup(
+	    channel, address, size, mode);
+	async_answer_0(callid, ret);
+}
+
 /**
  * @}
Index: uspace/lib/drv/include/ops/hw_res.h
===================================================================
--- uspace/lib/drv/include/ops/hw_res.h	(revision e6def65eb670def5f05126e61250ce88606c3966)
+++ uspace/lib/drv/include/ops/hw_res.h	(revision 9991c47fc8c46d0e24bc1c32ff3c50cc3e8b340d)
@@ -44,4 +44,5 @@
 	 hw_resource_list_t *(*get_resource_list)(ddf_fun_t *);
 	 bool (*enable_interrupt)(ddf_fun_t *);
+	 int (*dma_channel_setup)(unsigned, uintptr_t, uint16_t, uint8_t);
 } hw_res_ops_t;
 
