Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 19490cea4251de33ed19741087be0c03ff4d2a4f)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision d5f8f19a37dee7c1b854afeae4b99ee5a38287a2)
@@ -36,6 +36,5 @@
  *
  * This driver currently works only with CHS addressing and uses PIO.
- * Currently based on the (now obsolete) ANSI X3.221-1994 (ATA-1) standard.
- * At this point only reading is possible, not writing.
+ * Currently based on the (now obsolete) ATA-1, ATA-2 standards.
  *
  * The driver services a single controller which can have up to two disks
@@ -96,18 +95,4 @@
 		return -1;
 
-	/* Put drives to reset, disable interrupts. */
-	printf("Reset drives... ");
-	fflush(stdout);
-
-	pio_write_8(&ctl->device_control, DCR_SRST);
-	/* FIXME: Find out how to do this properly. */
-	async_usleep(100);
-	pio_write_8(&ctl->device_control, 0);
-
-	do {
-		status = pio_read_8(&cmd->status);
-	} while ((status & SR_BSY) != 0);
-	printf("Done\n");
-
 	(void) drive_identify(0, &disk[0]);
 	(void) drive_identify(1, &disk[1]);
@@ -148,4 +133,5 @@
 	uint16_t data;
 	uint8_t status;
+	uint8_t drv_head;
 	size_t i;
 
@@ -153,11 +139,12 @@
 	fflush(stdout);
 
-	pio_write_8(&cmd->drive_head, ((disk_id != 0) ? DHR_DRV : 0));
-	async_usleep(100);
-	pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
-
-	status = pio_read_8(&cmd->status);
-
+	drv_head = ((disk_id != 0) ? DHR_DRV : 0);
 	d->present = false;
+
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0);
+
+	pio_write_8(&cmd->drive_head, drv_head);
 
 	/*
@@ -165,22 +152,45 @@
 	 * do the right thing to work with real drives.
 	 */
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0);
+
 	if ((status & SR_DRDY) == 0) {
 		printf("None attached.\n");
 		return ENOENT;
 	}
-
-	for (i = 0; i < block_size / 2; i++) {
-		do {
-			status = pio_read_8(&cmd->status);
-		} while ((status & SR_DRDY) == 0);
-
-		data = pio_read_16(&cmd->data_port);
-
-		switch (i) {
-		case 1: d->cylinders = data; break;
-		case 3: d->heads = data; break;
-		case 6: d->sectors = data; break;
+	/***/
+
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0 || (status & SR_DRDY) == 0);
+
+	pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
+
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0);
+
+	/* Read data from the disk buffer. */
+
+	if ((status & SR_DRQ) != 0) {
+//		for (i = 0; i < block_size / 2; i++) {
+//			data = pio_read_16(&cmd->data_port);
+//			((uint16_t *) buf)[i] = data;
+//		}
+
+		for (i = 0; i < block_size / 2; i++) {
+			data = pio_read_16(&cmd->data_port);
+
+			switch (i) {
+			case 1: d->cylinders = data; break;
+			case 3: d->heads = data; break;
+			case 6: d->sectors = data; break;
+			}
 		}
 	}
+
+	if ((status & SR_ERR) != 0)
+		return EIO;
 
 	d->blocks = d->cylinders * d->heads * d->sectors;
@@ -361,21 +371,36 @@
 	/* Program a Read Sectors operation. */
 
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0);
+
 	pio_write_8(&cmd->drive_head, drv_head);
+
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0 || (status & SR_DRDY) == 0);
+
 	pio_write_8(&cmd->sector_count, 1);
 	pio_write_8(&cmd->sector_number, s);
 	pio_write_8(&cmd->cylinder_low, c & 0xff);
 	pio_write_8(&cmd->cylinder_high, c >> 16);
+
 	pio_write_8(&cmd->command, CMD_READ_SECTORS);
 
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0);
+
 	/* Read data from the disk buffer. */
 
-	for (i = 0; i < block_size / 2; i++) {
-		do {
-			status = pio_read_8(&cmd->status);
-		} while ((status & SR_DRDY) == 0);
-
-		data = pio_read_16(&cmd->data_port);
-		((uint16_t *) buf)[i] = data;
-	}
+	if ((status & SR_DRQ) != 0) {
+		for (i = 0; i < block_size / 2; i++) {
+			data = pio_read_16(&cmd->data_port);
+			((uint16_t *) buf)[i] = data;
+		}
+	}
+
+	if ((status & SR_ERR) != 0)
+		return EIO;
 
 	fibril_mutex_unlock(&d->lock);
@@ -415,25 +440,40 @@
 	/* Program a Read Sectors operation. */
 
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0);
+	
 	pio_write_8(&cmd->drive_head, drv_head);
+
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0 || (status & SR_DRDY) == 0);
+
 	pio_write_8(&cmd->sector_count, 1);
 	pio_write_8(&cmd->sector_number, s);
 	pio_write_8(&cmd->cylinder_low, c & 0xff);
 	pio_write_8(&cmd->cylinder_high, c >> 16);
+
 	pio_write_8(&cmd->command, CMD_WRITE_SECTORS);
 
+	do {
+		status = pio_read_8(&cmd->status);
+	} while ((status & SR_BSY) != 0);
+
 	/* Write data to the disk buffer. */
 
-	for (i = 0; i < block_size / 2; i++) {
-		do {
-			status = pio_read_8(&cmd->status);
-		} while ((status & SR_DRDY) == 0);
-
-		pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
+	if ((status & SR_DRQ) != 0) {
+		for (i = 0; i < block_size / 2; i++) {
+			pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
+		}
 	}
 
 	fibril_mutex_unlock(&d->lock);
+
+	if (status & SR_ERR)
+		return EIO;
+
 	return EOK;
 }
-
 
 /**
