Index: uspace/drv/audio/sb16/dma_controller.c
===================================================================
--- uspace/drv/audio/sb16/dma_controller.c	(revision ac149d5809dfd45468e67a08ab547c0866fa2457)
+++ uspace/drv/audio/sb16/dma_controller.c	(revision b4857bc44d9f5700e4ce959c502e193a8ff3ff00)
@@ -37,4 +37,5 @@
 #include <libarch/ddi.h>
 
+#include "ddf_log.h"
 #include "dma_controller.h"
 
@@ -76,10 +77,10 @@
 #define DMA_MODE_CHAN_AUTO_FLAG (1 << 4)
 #define DMA_MODE_CHAN_DOWN_FLAG (1 << 5)
-#define DMA_MODE_CHAN_MOD_MASK (0x3)
-#define DMA_MODE_CHAN_MOD_SHIFT (6)
-#define DMA_MODE_CHAN_MOD_DEMAND (0)
-#define DMA_MODE_CHAN_MOD_SINGLE (1)
-#define DMA_MODE_CHAN_MOD_BLOCK (2)
-#define DMA_MODE_CHAN_MOD_CASCADE (3)
+#define DMA_MODE_CHAN_MODE_MASK (0x3)
+#define DMA_MODE_CHAN_MODE_SHIFT (6)
+#define DMA_MODE_CHAN_MODE_DEMAND (0)
+#define DMA_MODE_CHAN_MODE_SINGLE (1)
+#define DMA_MODE_CHAN_MODE_BLOCK (2)
+#define DMA_MODE_CHAN_MODE_CASCADE (3)
 
 	uint8_t flip_flop;
@@ -163,4 +164,6 @@
 } dma_controller_t;
 
+
+/* http://zet.aluzina.org/index.php/8237_DMA_controller#DMA_Channel_Registers */
 static dma_controller_t controller_8237 = {
 	.channels = {
@@ -227,6 +230,18 @@
 		return EIO;
 
-	dma_channel_t dma_channel = controller_8237.channels[channel];
-
+	/* 16 bit transfers are a bit special */
+	ddf_log_debug("Unspoiled address and size: %p(%zu).\n", pa, size);
+	if (channel > 4) {
+		/* Size is the count of 16bit words */
+		assert(size % 2 == 0);
+		size /= 2;
+		/* Address is fun: lower 16bits need to be shifted by 1 */
+		pa = ((pa & 0xffff) >> 1) | (pa & 0xff0000);
+	}
+
+	const dma_channel_t dma_channel = controller_8237.channels[channel];
+
+	ddf_log_debug("Setting channel %u, to address %p(%zu).\n",
+	    channel, pa, size);
 	/* Mask DMA request */
 	uint8_t value = DMA_SINGLE_MASK_CHAN_TO_REG(channel)
@@ -239,12 +254,15 @@
 	/* Low byte */
 	value = pa & 0xff;
+	ddf_log_verbose("Writing address low byte: %hhx.\n", value);
 	pio_write_8(dma_channel.offset_reg_address, value);
 
 	/* High byte */
 	value = (pa >> 8) & 0xff;
+	ddf_log_verbose("Writing address high byte: %hhx.\n", value);
 	pio_write_8(dma_channel.offset_reg_address, value);
 
 	/* Page address - third byte */
 	value = (pa >> 16) & 0xff;
+	ddf_log_verbose("Writing address page byte: %hhx.\n", value);
 	pio_write_8(dma_channel.offset_reg_address, value);
 
@@ -253,9 +271,11 @@
 
 	/* Low byte */
-	value = size & 0xff;
+	value = (size - 1) & 0xff;
+	ddf_log_verbose("Writing size low byte: %hhx.\n", value);
 	pio_write_8(dma_channel.offset_reg_address, value);
 
 	/* High byte */
-	value = (size >> 8) & 0xff;
+	value = ((size - 1) >> 8) & 0xff;
+	ddf_log_verbose("Writing size high byte: %hhx.\n", value);
 	pio_write_8(dma_channel.offset_reg_address, value);
 
@@ -265,5 +285,4 @@
 
 	return EOK;
-
 }
 /*----------------------------------------------------------------------------*/
@@ -291,5 +310,6 @@
 	        << DMA_MODE_CHAN_TRA_SHIFT)
 	    | (auto_mode ? DMA_MODE_CHAN_AUTO_FLAG : 0)
-	    | (mode << DMA_MODE_CHAN_MOD_SHIFT);
+	    | (mode << DMA_MODE_CHAN_MODE_SHIFT);
+	ddf_log_verbose("Setting mode: %hhx.\n", value);
 	pio_write_8(dma_channel.mode_address, value);
 
