Index: uspace/lib/c/arch/sparc64/Makefile.common
===================================================================
--- uspace/lib/c/arch/sparc64/Makefile.common	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/arch/sparc64/Makefile.common	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -27,5 +27,12 @@
 #
 
-GCC_CFLAGS += -mcpu=ultrasparc -m64 -mcmodel=medlow
+ifeq ($(PROCESSOR),sun4v)
+GCC_CFLAGS += -mcpu=niagara -mno-vis
+else
+GCC_CFLAGS += -mcpu=ultrasparc
+endif
+
+GCC_CFLAGS += -m64 -mcmodel=medlow
+
 LFLAGS = -no-check-sections
 
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/generic/async.c	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -2281,14 +2281,35 @@
 bool async_data_read_receive(ipc_callid_t *callid, size_t *size)
 {
+	ipc_call_t data;
+	return async_data_read_receive_call(callid, &data, size);
+}
+
+/** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ
+ * calls so that the user doesn't have to remember the meaning of each IPC
+ * argument.
+ *
+ * So far, this wrapper is to be used from within a connection fibril.
+ *
+ * @param callid Storage for the hash of the IPC_M_DATA_READ.
+ * @param size   Storage for the maximum size. Can be NULL.
+ *
+ * @return True on success, false on failure.
+ *
+ */
+bool async_data_read_receive_call(ipc_callid_t *callid, ipc_call_t *data,
+    size_t *size)
+{
 	assert(callid);
-	
-	ipc_call_t data;
-	*callid = async_get_call(&data);
-	
-	if (IPC_GET_IMETHOD(data) != IPC_M_DATA_READ)
+	assert(data);
+	
+	*callid = async_get_call(data);
+	
+	if (IPC_GET_IMETHOD(*data) != IPC_M_DATA_READ)
 		return false;
 	
 	if (size)
-		*size = (size_t) IPC_GET_ARG2(data);
+		*size = (size_t) IPC_GET_ARG2(*data);
 	
 	return true;
@@ -2385,14 +2406,36 @@
 bool async_data_write_receive(ipc_callid_t *callid, size_t *size)
 {
+	ipc_call_t data;
+	return async_data_write_receive_call(callid, &data, size);
+}
+
+/** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.
+ *
+ * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE
+ * calls so that the user doesn't have to remember the meaning of each IPC
+ * argument.
+ *
+ * So far, this wrapper is to be used from within a connection fibril.
+ *
+ * @param callid Storage for the hash of the IPC_M_DATA_WRITE.
+ * @param data   Storage for the ipc call data.
+ * @param size   Storage for the suggested size. May be NULL.
+ *
+ * @return True on success, false on failure.
+ *
+ */
+bool async_data_write_receive_call(ipc_callid_t *callid, ipc_call_t *data,
+    size_t *size)
+{
 	assert(callid);
-	
-	ipc_call_t data;
-	*callid = async_get_call(&data);
-	
-	if (IPC_GET_IMETHOD(data) != IPC_M_DATA_WRITE)
+	assert(data);
+	
+	*callid = async_get_call(data);
+	
+	if (IPC_GET_IMETHOD(*data) != IPC_M_DATA_WRITE)
 		return false;
 	
 	if (size)
-		*size = (size_t) IPC_GET_ARG2(data);
+		*size = (size_t) IPC_GET_ARG2(*data);
 	
 	return true;
Index: uspace/lib/c/generic/device/hw_res.c
===================================================================
--- uspace/lib/c/generic/device/hw_res.c	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/generic/device/hw_res.c	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -44,4 +44,6 @@
 	
 	async_exch_t *exch = async_exchange_begin(sess);
+	if (exch == NULL)
+		return ENOMEM;
 	int rc = async_req_1_1(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
 	    HW_RES_GET_RESOURCE_LIST, &count);
@@ -77,4 +79,6 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
+	if (exch == NULL)
+		return false;
 	int rc = async_req_1_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
 	    HW_RES_ENABLE_INTERRUPT);
@@ -84,4 +88,50 @@
 }
 
+/**
+ * Setup DMA channel to specified place and mode.
+ * @param channel DMA Channel 1,2,3 for 8 bit transfers, 5,6,7 for 16 bit.
+ * @param pa Physical address of the buffer. Must be < 16MB for 16 bit and < 1MB
+ *           for 8 bit transfers.
+ * @param size DMA buffer size, limited to 64K.
+ * @param mode Mode of the DMA channel:
+ *              - Read or Write
+ *              - Allow automatic reset
+ *              - Use address decrement instead of increment
+ *              - Use SINGLE/BLOCK/ON DEMAND transfer mode
+ * @return Error code.
+ */
+int hw_res_dma_channel_setup(async_sess_t *sess,
+    unsigned channel, uint32_t pa, uint32_t size, uint8_t mode)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	if (exch == NULL)
+		return ENOMEM;
+	const uint32_t packed = (channel & 0xffff) | (mode << 16);
+	const int ret = async_req_4_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE),
+	    HW_RES_DMA_CHANNEL_SETUP, packed, pa, size);
+	async_exchange_end(exch);
+
+	return ret;
+}
+
+/**
+ * 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/generic/device/hw_res_parsed.c
===================================================================
--- uspace/lib/c/generic/device/hw_res_parsed.c	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/generic/device/hw_res_parsed.c	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -38,6 +38,28 @@
 #include <errno.h>
 
-static void hw_res_parse_add_irq(hw_res_list_parsed_t *out, hw_resource_t *res,
-    int flags)
+static void hw_res_parse_add_dma_channel(hw_res_list_parsed_t *out,
+    const hw_resource_t *res, int flags)
+{
+	assert(res);
+	assert((res->type == DMA_CHANNEL_8) || (res->type == DMA_CHANNEL_16));
+	
+	const unsigned channel = (res->type == DMA_CHANNEL_8) ?
+	    res->res.dma_channel.dma8 : res->res.dma_channel.dma16;
+	const size_t count = out->dma_channels.count;
+	const int keep_duplicit = flags & HW_RES_KEEP_DUPLICIT;
+	
+	if (!keep_duplicit) {
+		for (size_t i = 0; i < count; ++i) {
+			if (out->dma_channels.channels[i] == channel)
+				return;
+		}
+	}
+	
+	out->dma_channels.channels[count] = channel;
+	++out->dma_channels.count;
+}
+
+static void hw_res_parse_add_irq(hw_res_list_parsed_t *out,
+    const hw_resource_t *res, int flags)
 {
 	assert(res && (res->type == INTERRUPT));
@@ -59,5 +81,5 @@
 
 static void hw_res_parse_add_io_range(hw_res_list_parsed_t *out,
-    hw_resource_t *res, int flags)
+    const hw_resource_t *res, int flags)
 {
 	assert(res && (res->type == IO_RANGE));
@@ -90,5 +112,5 @@
 
 static void hw_res_parse_add_mem_range(hw_res_list_parsed_t *out,
-    hw_resource_t *res, int flags)
+    const hw_resource_t *res, int flags)
 {
 	assert(res && (res->type == MEM_RANGE));
@@ -132,5 +154,5 @@
  *
  */
-int hw_res_list_parse(hw_resource_list_t *hw_resources,
+int hw_res_list_parse(const hw_resource_list_t *hw_resources,
     hw_res_list_parsed_t *out, int flags)
 {
@@ -141,10 +163,16 @@
 	hw_res_list_parsed_clean(out);
 	
-	out->irqs.irqs = malloc(res_count * sizeof(int));
-	out->io_ranges.ranges = malloc(res_count * sizeof(io_range_t));
-	out->mem_ranges.ranges = malloc(res_count * sizeof(mem_range_t));
+	out->irqs.irqs = calloc(res_count, sizeof(int));
+	out->dma_channels.channels = calloc(res_count, sizeof(int));
+	out->io_ranges.ranges = calloc(res_count, sizeof(io_range_t));
+	out->mem_ranges.ranges = calloc(res_count, sizeof(mem_range_t));
+	if (!out->irqs.irqs || !out->dma_channels.channels ||
+	    !out->io_ranges.ranges || !out->mem_ranges.ranges) {
+		hw_res_list_parsed_clean(out);
+		return ENOMEM;
+	}
 	
 	for (size_t i = 0; i < res_count; ++i) {
-		hw_resource_t *resource = &(hw_resources->resources[i]);
+		const hw_resource_t *resource = &(hw_resources->resources[i]);
 		
 		switch (resource->type) {
@@ -158,5 +186,10 @@
 			hw_res_parse_add_mem_range(out, resource, flags);
 			break;
+		case DMA_CHANNEL_8:
+		case DMA_CHANNEL_16:
+			hw_res_parse_add_dma_channel(out, resource, flags);
+			break;
 		default:
+			hw_res_list_parsed_clean(out);
 			return EINVAL;
 		}
Index: uspace/lib/c/generic/futex.c
===================================================================
--- uspace/lib/c/generic/futex.c	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/generic/futex.c	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -35,4 +35,5 @@
 #include <futex.h>
 #include <atomic.h>
+#include <libarch/barrier.h>
 #include <libc.h>
 #include <sys/types.h>
@@ -59,5 +60,10 @@
 int futex_trydown(futex_t *futex)
 {
-	return cas(futex, 1, 0);
+	int rc;
+
+	rc = cas(futex, 1, 0);
+	CS_ENTER_BARRIER();
+
+	return rc;
 }
 
@@ -73,5 +79,9 @@
 int futex_down(futex_t *futex)
 {
-	if ((atomic_signed_t) atomic_predec(futex) < 0)
+	atomic_signed_t nv;
+
+	nv = (atomic_signed_t) atomic_predec(futex);
+	CS_ENTER_BARRIER();
+	if (nv < 0)
 		return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
 	
@@ -89,4 +99,6 @@
 int futex_up(futex_t *futex)
 {
+	CS_LEAVE_BARRIER();
+
 	if ((atomic_signed_t) atomic_postinc(futex) < 0)
 		return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
Index: uspace/lib/c/include/adt/list.h
===================================================================
--- uspace/lib/c/include/adt/list.h	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/include/adt/list.h	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -1,5 +1,5 @@
 /*
  * Copyright (c) 2001-2004 Jakub Jermar
- * Copyright (c) 2011 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -65,5 +65,5 @@
 
 #define list_get_instance(link, type, member) \
-	((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
+	((type *) (((void *)(link)) - list_link_to_void(&(((type *) NULL)->member))))
 
 #define list_foreach(list, iterator) \
@@ -318,4 +318,13 @@
 }
 
+/** Verify that argument type is a pointer to link_t (at compile time).
+ *
+ * This can be used to check argument type in a macro.
+ */
+static inline const void *list_link_to_void(const link_t *link)
+{
+	return link;
+}
+
 extern int list_member(const link_t *, const list_t *);
 extern void list_concat(list_t *, list_t *);
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/include/async.h	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -399,4 +399,5 @@
 extern int async_data_read_start(async_exch_t *, void *, size_t);
 extern bool async_data_read_receive(ipc_callid_t *, size_t *);
+extern bool async_data_read_receive_call(ipc_callid_t *, ipc_call_t *, size_t *);
 extern int async_data_read_finalize(ipc_callid_t, const void *, size_t);
 
@@ -437,4 +438,5 @@
 extern int async_data_write_start(async_exch_t *, const void *, size_t);
 extern bool async_data_write_receive(ipc_callid_t *, size_t *);
+extern bool async_data_write_receive_call(ipc_callid_t *, ipc_call_t *, size_t *);
 extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
 
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/include/device/hw_res.h	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -53,4 +53,5 @@
 	HW_RES_ENABLE_INTERRUPT,
 	HW_RES_DMA_CHANNEL_SETUP,
+	HW_RES_DMA_CHANNEL_REMAIN,
 } hw_res_method_t;
 
@@ -115,5 +116,6 @@
 
 extern int hw_res_dma_channel_setup(async_sess_t *, unsigned int, uint32_t,
-    uint16_t, uint8_t);
+    uint32_t, uint8_t);
+extern int hw_res_dma_channel_remain(async_sess_t *, unsigned);
 
 #endif
Index: uspace/lib/c/include/device/hw_res_parsed.h
===================================================================
--- uspace/lib/c/include/device/hw_res_parsed.h	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/include/device/hw_res_parsed.h	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -139,5 +139,6 @@
 }
 
-extern int hw_res_list_parse(hw_resource_list_t *, hw_res_list_parsed_t *, int);
+extern int hw_res_list_parse(const hw_resource_list_t *,
+    hw_res_list_parsed_t *, int);
 extern int hw_res_get_list_parsed(async_sess_t *, hw_res_list_parsed_t *, int);
 
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -36,4 +36,5 @@
 typedef enum {
 	HW_RES_DEV_IFACE = 0,
+
 	/** Character device interface */
 	CHAR_DEV_IFACE,
@@ -41,4 +42,9 @@
 	/** Graphic device interface */
 	GRAPH_DEV_IFACE,
+
+	/** Audio device mixer interface */
+	AUDIO_MIXER_IFACE,
+	/** Audio device pcm buffer interface */
+	AUDIO_PCM_BUFFER_IFACE,
 	
 	/** Network interface controller interface */
@@ -54,8 +60,11 @@
 	/** Interface provided by USB HID devices. */
 	USBHID_DEV_IFACE,
+
 	/** Interface provided by Real Time Clock devices */
 	CLOCK_DEV_IFACE,
+
 	/** Interface provided by battery powered devices */
 	BATTERY_DEV_IFACE,
+
 	/** Interface provided by AHCI devices. */
 	AHCI_DEV_IFACE,
Index: uspace/lib/c/include/macros.h
===================================================================
--- uspace/lib/c/include/macros.h	(revision 6ad185dcbc744d0932bb7ac850b8e826a4164329)
+++ uspace/lib/c/include/macros.h	(revision f7bb6d1a278f1b4a8dc824581598c48556371dca)
@@ -40,4 +40,5 @@
 #define abs(a)     ((a) >= 0 ? (a) : -(a))
 
+#define ARRAY_SIZE(array)   (sizeof(array) / sizeof(array[0]))
 
 #define KiB2SIZE(kb)  ((kb) << 10)
