Index: uspace/drv/block/ata_bd/ata_bd.c
===================================================================
--- uspace/drv/block/ata_bd/ata_bd.c	(revision 39bcc9955086903b554e287d7e7ec03dfe6b2f56)
+++ uspace/drv/block/ata_bd/ata_bd.c	(revision c2844735370bbfe56e50ad23b5c4bde202e8ed4f)
@@ -54,4 +54,5 @@
 #include <bd_srv.h>
 #include <fibril_synch.h>
+#include <scsi/sbc.h>
 #include <stdint.h>
 #include <str.h>
@@ -103,8 +104,11 @@
 static int ata_identify_pkt_dev(disk_t *disk, void *buf);
 static int ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size,
-    void *obuf, size_t obuf_size);
-static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size);
+    void *obuf, size_t obuf_size, size_t *rcvd_size);
+static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size,
+    size_t *rcvd_size);
 static int ata_pcmd_read_12(disk_t *disk, uint64_t ba, size_t cnt,
     void *obuf, size_t obuf_size);
+static int ata_pcmd_read_capacity(disk_t *disk, uint64_t *nblocks,
+    size_t *block_size);
 static int ata_pcmd_read_toc(disk_t *disk, uint8_t ses,
     void *obuf, size_t obuf_size);
@@ -340,7 +344,10 @@
 	uint8_t model[40];
 	ata_inquiry_data_t inq_data;
+	size_t isize;
 	uint16_t w;
 	uint8_t c;
 	uint16_t bc;
+	uint64_t nblocks;
+	size_t block_size;
 	size_t pos, len;
 	int rc;
@@ -457,6 +464,6 @@
 	if (d->dev_type == ata_pkt_dev) {
 		/* Send inquiry. */
-		rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data));
-		if (rc != EOK) {
+		rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data), &isize);
+		if (rc != EOK || isize < sizeof(inq_data)) {
 			ddf_msg(LVL_ERROR, "Device inquiry failed.");
 			d->present = false;
@@ -468,6 +475,13 @@
 			ddf_msg(LVL_WARN, "Peripheral device type is not CD-ROM.");
 
-		/* Assume 2k block size for now. */
-		d->block_size = 2048;
+		rc = ata_pcmd_read_capacity(d, &nblocks, &block_size);
+		if (rc != EOK) {
+			ddf_msg(LVL_ERROR, "Read capacity command failed.");
+			d->present = false;
+			return EIO;
+		}
+
+		d->blocks = nblocks;
+		d->block_size = block_size;
 	} else {
 		/* Assume register Read always uses 512-byte blocks. */
@@ -722,9 +736,10 @@
  * @param obuf		Buffer for storing data read from device
  * @param obuf_size	Size of obuf in bytes
+ * @param rcvd_size	Place to store number of bytes read or @c NULL
  *
  * @return EOK on success, EIO on error.
  */
 static int ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size,
-    void *obuf, size_t obuf_size)
+    void *obuf, size_t obuf_size, size_t *rcvd_size)
 {
 	ata_ctrl_t *ctrl = disk->ctrl;
@@ -800,4 +815,6 @@
 		return EIO;
 
+	if (rcvd_size != NULL)
+		*rcvd_size = data_size;
 	return EOK;
 }
@@ -811,5 +828,6 @@
  * @return EOK on success, EIO on error.
  */
-static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size)
+static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size,
+    size_t *rcvd_size)
 {
 	ata_pcmd_inquiry_t cp;
@@ -821,7 +839,39 @@
 	cp.alloc_len = min(obuf_size, 0xff); /* Allocation length */
 
-	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size);
+	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size, rcvd_size);
 	if (rc != EOK)
 		return rc;
+
+	return EOK;
+}
+
+/** Issue ATAPI read capacity(10) command.
+ *
+ * @param disk		Disk
+ * @param nblocks	Place to store number of blocks
+ * @param block_size	Place to store block size
+ *
+ * @return EOK on success, EIO on error.
+ */
+static int ata_pcmd_read_capacity(disk_t *disk, uint64_t *nblocks,
+    size_t *block_size)
+{
+	scsi_cdb_read_capacity_10_t cdb;
+	scsi_read_capacity_10_data_t data;
+	size_t rsize;
+	int rc;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
+
+	rc = ata_cmd_packet(disk, &cdb, sizeof(cdb), &data, sizeof(data), &rsize);
+	if (rc != EOK)
+		return rc;
+
+	if (rsize != sizeof(data))
+		return EIO;
+
+	*nblocks = uint32_t_be2host(data.last_lba) + 1;
+	*block_size = uint32_t_be2host(data.block_size);
 
 	return EOK;
@@ -856,5 +906,5 @@
 	cp.nblocks = host2uint32_t_be(cnt);
 
-	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size);
+	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size, NULL);
 	if (rc != EOK)
 		return rc;
@@ -895,5 +945,5 @@
 	cp.oldformat = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */
 	
-	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size);
+	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size, NULL);
 	if (rc != EOK)
 		return rc;
