Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 88743b50b604d7ae773de9d961b292bb34a37cc7)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision 0d247f5e064308de35b22a948ee6b049771527da)
@@ -74,6 +74,9 @@
 #define LEGACY_CTLS 4
 
-/** Physical block size. Should be always 512. */
-static const size_t block_size = 512;
+/**
+ * Size of data returned from Identify Device or Identify Packet Device
+ * command.
+ */
+static const size_t identify_data_size = 512;
 
 /** Size of the communication area. */
@@ -106,7 +109,7 @@
 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt,
     const void *buf);
-static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt,
+static int ata_rcmd_read(int disk_id, uint64_t ba, size_t cnt,
     void *buf);
-static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
+static int ata_rcmd_write(int disk_id, uint64_t ba, size_t cnt,
     const void *buf);
 static int disk_init(disk_t *d, int disk_id);
@@ -116,4 +119,6 @@
     void *obuf, size_t obuf_size);
 static int ata_pcmd_inquiry(int dev_idx, void *obuf, size_t obuf_size);
+static int ata_pcmd_read_12(int dev_idx, uint64_t ba, size_t cnt,
+    void *obuf, size_t obuf_size);
 static void disk_print_summary(disk_t *d);
 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
@@ -323,5 +328,5 @@
 			    IPC_GET_ARG2(call));
 			cnt = IPC_GET_ARG3(call);
-			if (cnt * block_size > comm_size) {
+			if (cnt * disk[disk_id].block_size > comm_size) {
 				retval = ELIMIT;
 				break;
@@ -333,5 +338,5 @@
 			    IPC_GET_ARG2(call));
 			cnt = IPC_GET_ARG3(call);
-			if (cnt * block_size > comm_size) {
+			if (cnt * disk[disk_id].block_size > comm_size) {
 				retval = ELIMIT;
 				break;
@@ -340,5 +345,5 @@
 			break;
 		case BD_GET_BLOCK_SIZE:
-			ipc_answer_1(callid, EOK, block_size);
+			ipc_answer_1(callid, EOK, disk[disk_id].block_size);
 			continue;
 		case BD_GET_NUM_BLOCKS:
@@ -476,4 +481,19 @@
 		if ((inq_buf[0] & 0x1f) != 0x05)
 			printf("Warning: Peripheral device type is not CD-ROM.\n");
+
+		/* XXX Test some reading */
+		uint8_t rdbuf[4096];
+		rc = ata_pcmd_read_12(0, 0, 1, rdbuf, 4096);
+		if (rc != EOK) {
+			printf("read(12) failed\n");
+		} else {
+			printf("read(12) succeeded\n");
+		}
+
+		/* Assume 2k block size for now. */
+		d->block_size = 2048;
+	} else {
+		/* Assume register Read always uses 512-byte blocks. */
+		d->block_size = 512;
 	}
 
@@ -489,5 +509,10 @@
 
 	while (cnt > 0) {
-		rc = ata_bd_read_block(disk_id, ba, 1, buf);
+		if (disk[disk_id].dev_type == ata_reg_dev)
+			rc = ata_rcmd_read(disk_id, ba, 1, buf);
+		else
+			rc = ata_pcmd_read_12(disk_id, ba, 1, buf,
+			    disk[disk_id].block_size);
+
 		if (rc != EOK)
 			return rc;
@@ -495,5 +520,5 @@
 		++ba;
 		--cnt;
-		buf += block_size;
+		buf += disk[disk_id].block_size;
 	}
 
@@ -507,6 +532,9 @@
 	int rc;
 
+	if (disk[disk_id].dev_type != ata_reg_dev)
+		return ENOTSUP;
+
 	while (cnt > 0) {
-		rc = ata_bd_write_block(disk_id, ba, 1, buf);
+		rc = ata_rcmd_write(disk_id, ba, 1, buf);
 		if (rc != EOK)
 			return rc;
@@ -514,5 +542,5 @@
 		++ba;
 		--cnt;
-		buf += block_size;
+		buf += disk[disk_id].block_size;
 	}
 
@@ -560,5 +588,5 @@
 
 	if ((status & SR_DRQ) != 0) {
-		for (i = 0; i < block_size / 2; i++) {
+		for (i = 0; i < identify_data_size / 2; i++) {
 			data = pio_read_16(&cmd->data_port);
 			((uint16_t *) buf)[i] = data;
@@ -607,5 +635,5 @@
 
 	if ((status & SR_DRQ) != 0) {
-		for (i = 0; i < block_size / 2; i++) {
+		for (i = 0; i < identify_data_size / 2; i++) {
 			data = pio_read_16(&cmd->data_port);
 			((uint16_t *) buf)[i] = data;
@@ -686,4 +714,5 @@
 	data_size = (uint16_t) pio_read_8(&cmd->cylinder_low) +
 	    ((uint16_t) pio_read_8(&cmd->cylinder_high) << 8);
+	printf("data_size = %u\n", data_size);
 
 	/* Check whether data fits into output buffer. */
@@ -734,4 +763,32 @@
 }
 
+static int ata_pcmd_read_12(int dev_idx, uint64_t ba, size_t cnt,
+    void *obuf, size_t obuf_size)
+{
+	uint8_t cp[12];
+	int rc;
+
+	if (ba > 0xffffffff)
+		return EINVAL;
+
+	memset(cp, 0, 12);
+	cp[0] = 0xa8; /* Read(12) */
+	cp[2] = (ba >> 24) & 0xff;
+	cp[3] = (ba >> 16) & 0xff;
+	cp[4] = (ba >> 8) & 0xff;
+	cp[5] = ba & 0xff;
+
+	cp[6] = (cnt >> 24) & 0xff;
+	cp[7] = (cnt >> 16) & 0xff;
+	cp[8] = (cnt >> 8) & 0xff;
+	cp[9] = cnt & 0xff;
+
+	rc = ata_cmd_packet(0, cp, 12, obuf, obuf_size);
+	if (rc != EOK)
+		return rc;
+
+	return EOK;
+}
+
 /** Read a physical from the device.
  *
@@ -743,5 +800,5 @@
  * @return EOK on success, EIO on error.
  */
-static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt,
+static int ata_rcmd_read(int disk_id, uint64_t ba, size_t blk_cnt,
     void *buf)
 {
@@ -798,5 +855,5 @@
 		/* Read data from the device buffer. */
 
-		for (i = 0; i < block_size / 2; i++) {
+		for (i = 0; i < disk[disk_id].block_size / 2; i++) {
 			data = pio_read_16(&cmd->data_port);
 			((uint16_t *) buf)[i] = data;
@@ -820,5 +877,5 @@
  * @return EOK on success, EIO on error.
  */
-static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt,
+static int ata_rcmd_write(int disk_id, uint64_t ba, size_t cnt,
     const void *buf)
 {
@@ -874,5 +931,5 @@
 		/* Write data to the device buffer. */
 
-		for (i = 0; i < block_size / 2; i++) {
+		for (i = 0; i < disk[disk_id].block_size / 2; i++) {
 			pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
 		}
Index: uspace/srv/bd/ata_bd/ata_bd.h
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.h	(revision 88743b50b604d7ae773de9d961b292bb34a37cc7)
+++ uspace/srv/bd/ata_bd/ata_bd.h	(revision 0d247f5e064308de35b22a948ee6b049771527da)
@@ -111,4 +111,5 @@
 
 	uint64_t blocks;
+	size_t block_size;
 
 	char model[STR_BOUNDS(40) + 1];
