Index: uspace/lib/c/generic/device/hw_res.c
===================================================================
--- uspace/lib/c/generic/device/hw_res.c	(revision 2e01b3f1105b1f5750b3f7d726b038336feb514e)
+++ uspace/lib/c/generic/device/hw_res.c	(revision b881226fb046fe137ec28e412cb72b709aeefb61)
@@ -115,4 +115,23 @@
 }
 
+/**
+ * Query remaining bytes in the buffer.
+ * @param channel DMA Channel 1,2,3 for 8 bit transfers, 5,6,7 for 16 bit.
+ * @return Number of bytes remaining in the buffer(>=0) or error code(<0).
+ */
+int hw_res_dma_channel_remain(async_sess_t *sess, unsigned channel)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (exch == NULL)
+		return ENOMEM;
+	sysarg_t remain;
+	const int ret = async_req_2_1(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_DMA_CHANNEL_REMAIN, channel, &remain);
+	async_exchange_end(exch);
+	if (ret == EOK)
+		return remain;
+	return ret;
+}
+
 /** @}
  */
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision 2e01b3f1105b1f5750b3f7d726b038336feb514e)
+++ uspace/lib/c/include/device/hw_res.h	(revision b881226fb046fe137ec28e412cb72b709aeefb61)
@@ -53,4 +53,5 @@
 	HW_RES_ENABLE_INTERRUPT,
 	HW_RES_DMA_CHANNEL_SETUP,
+	HW_RES_DMA_CHANNEL_REMAIN,
 } hw_res_method_t;
 
@@ -116,4 +117,5 @@
 extern int hw_res_dma_channel_setup(async_sess_t *, unsigned int, uint32_t,
     uint16_t, uint8_t);
+extern int hw_res_dma_channel_remain(async_sess_t *, unsigned);
 
 #endif
Index: uspace/lib/drv/generic/remote_hw_res.c
===================================================================
--- uspace/lib/drv/generic/remote_hw_res.c	(revision 2e01b3f1105b1f5750b3f7d726b038336feb514e)
+++ uspace/lib/drv/generic/remote_hw_res.c	(revision b881226fb046fe137ec28e412cb72b709aeefb61)
@@ -46,4 +46,6 @@
 static void remote_hw_res_dma_channel_setup(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
+static void remote_hw_res_dma_channel_remain(ddf_fun_t *, void *, ipc_callid_t,
+    ipc_call_t *);
 
 static remote_iface_func_ptr_t remote_hw_res_iface_ops [] = {
@@ -51,4 +53,5 @@
 	[HW_RES_ENABLE_INTERRUPT] = &remote_hw_res_enable_interrupt,
 	[HW_RES_DMA_CHANNEL_SETUP] = &remote_hw_res_dma_channel_setup,
+	[HW_RES_DMA_CHANNEL_REMAIN] = &remote_hw_res_dma_channel_remain,
 };
 
@@ -117,4 +120,18 @@
 }
 
+static void remote_hw_res_dma_channel_remain(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);
+	uint16_t remain = 0;
+	const int ret = hw_res_ops->dma_channel_remain(fun, channel, &remain);
+	async_answer_1(callid, ret, remain);
+}
 /**
  * @}
Index: uspace/lib/drv/include/ops/hw_res.h
===================================================================
--- uspace/lib/drv/include/ops/hw_res.h	(revision 2e01b3f1105b1f5750b3f7d726b038336feb514e)
+++ uspace/lib/drv/include/ops/hw_res.h	(revision b881226fb046fe137ec28e412cb72b709aeefb61)
@@ -45,4 +45,5 @@
 	bool (*enable_interrupt)(ddf_fun_t *);
 	int (*dma_channel_setup)(ddf_fun_t *, unsigned, uint32_t, uint16_t, uint8_t);
+	int (*dma_channel_remain)(ddf_fun_t *, unsigned, uint16_t *);
 } hw_res_ops_t;
 
