Index: uspace/srv/bd/gxe_bd/gxe_bd.c
===================================================================
--- uspace/srv/bd/gxe_bd/gxe_bd.c	(revision ae55ee856346e9470ad1cdba0c1e7106ce676727)
+++ uspace/srv/bd/gxe_bd/gxe_bd.c	(revision 3ecc02eac7d067436e7876f91133503ea5412e5e)
@@ -85,5 +85,7 @@
 } gxe_buf_t;
 
-static size_t maxblock_size = 512;
+static const size_t block_size = 512;
+static size_t comm_size;
+
 static uintptr_t dev_physical = 0x13000000;
 static gxe_bd_t *dev;
@@ -96,7 +98,7 @@
 static int gxe_bd_init(void);
 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall);
-static int gxe_bd_read_block(uint64_t offset, size_t block_size, void *buf);
-static int gxe_bd_write_block(uint64_t offset, size_t block_size,
-    const void *buf);
+static int gx_bd_rdwr(ipcarg_t method, off_t offset, off_t size, void *buf);
+static int gxe_bd_read_block(uint64_t offset, size_t size, void *buf);
+static int gxe_bd_write_block(uint64_t offset, size_t size, const void *buf);
 
 int main(int argc, char **argv)
@@ -157,19 +159,19 @@
 	ipc_callid_t callid;
 	ipc_call_t call;
+	ipcarg_t method;
 	int flags;
 	int retval;
-	off_t offset;
-	size_t block_size;
+	off_t idx;
+	off_t size;
 
 	/* Answer the IPC_M_CONNECT_ME_TO call. */
 	ipc_answer_0(iid, EOK);
 
-	if (!ipc_share_out_receive(&callid, &maxblock_size, &flags)) {
+	if (!ipc_share_out_receive(&callid, &comm_size, &flags)) {
 		ipc_answer_0(callid, EHANGUP);
 		return;
 	}
-	maxblock_size = 512;
-
-	fs_va = as_get_mappable_page(maxblock_size);
+
+	fs_va = as_get_mappable_page(comm_size);
 	if (fs_va == NULL) {
 		ipc_answer_0(callid, EHANGUP);
@@ -181,5 +183,6 @@
 	while (1) {
 		callid = async_get_call(&call);
-		switch (IPC_GET_METHOD(call)) {
+		method = IPC_GET_METHOD(call);
+		switch (method) {
 		case IPC_M_PHONE_HUNGUP:
 			/* The other side has hung up. */
@@ -187,12 +190,12 @@
 			return;
 		case BD_READ_BLOCK:
-			offset = IPC_GET_ARG1(call);
-			block_size = IPC_GET_ARG2(call);
-			retval = gxe_bd_read_block(offset, block_size, fs_va);
-			break;
 		case BD_WRITE_BLOCK:
-			offset = IPC_GET_ARG1(call);
-			block_size = IPC_GET_ARG2(call);
-			retval = gxe_bd_write_block(offset, block_size, fs_va);
+			idx = IPC_GET_ARG1(call);
+			size = IPC_GET_ARG2(call);
+			if (size > comm_size) {
+				retval = EINVAL;
+				break;
+			}
+			retval = gx_bd_rdwr(method, idx * size, size, fs_va);
 			break;
 		default:
@@ -204,15 +207,37 @@
 }
 
-static int gxe_bd_read_block(uint64_t offset, size_t block_size, void *buf)
+static int gx_bd_rdwr(ipcarg_t method, off_t offset, off_t size, void *buf)
+{
+	int rc;
+	size_t now;
+
+	while (size > 0) {
+		now = size < block_size ? size : block_size;
+
+		if (method == BD_READ_BLOCK)
+			rc = gxe_bd_read_block(offset, now, buf);
+		else
+			rc = gxe_bd_write_block(offset, now, buf);
+
+		if (rc != EOK)
+			return rc;
+
+		buf += block_size;
+		offset += block_size;
+
+		if (size > block_size)
+			size -= block_size;
+		else
+			size = 0;
+	}
+
+	return EOK;
+}
+
+static int gxe_bd_read_block(uint64_t offset, size_t size, void *buf)
 {
 	uint32_t status;
 	size_t i;
 	uint32_t w;
-
-	if (block_size != maxblock_size) {
-		printf("Failed: bs = %d, mbs = %d\n", block_size,
-		    maxblock_size);
-		return EINVAL;
-	}
 
 	futex_down(&dev_futex);
@@ -227,5 +252,5 @@
 	}
 
-	for (i = 0; i < maxblock_size; i++) {
+	for (i = 0; i < size; i++) {
 		((uint8_t *) buf)[i] = w =
 		    pio_read_8(&devbuf->buffer[i]);
@@ -236,6 +261,5 @@
 }
 
-static int gxe_bd_write_block(uint64_t offset, size_t block_size,
-    const void *buf)
+static int gxe_bd_write_block(uint64_t offset, size_t size, const void *buf)
 {
 	uint32_t status;
@@ -243,11 +267,5 @@
 	uint32_t w;
 
-	if (block_size != maxblock_size) {
-		printf("Failed: bs = %d, mbs = %d\n", block_size,
-		    maxblock_size);
-		return EINVAL;
-	}
-
-	for (i = 0; i < maxblock_size; i++) {
+	for (i = 0; i < size; i++) {
 		pio_write_8(&devbuf->buffer[i], ((const uint8_t *) buf)[i]);
 	}
