Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 54d0ddc60a3a04cab498b3ad83ca5a1f78abb735)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision c145bc2fc737a941e2d7e0c94b3479d3c11bb93d)
@@ -86,5 +86,6 @@
     const void *buf);
 static int drive_identify(int drive_id, disk_t *d);
-static uint8_t wait_status(unsigned set, unsigned n_reset);
+static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
+    unsigned timeout);
 
 int main(int argc, char **argv)
@@ -101,6 +102,17 @@
 		return -1;
 
-	(void) drive_identify(0, &disk[0]);
-	(void) drive_identify(1, &disk[1]);
+	for (i = 0; i < MAX_DISKS; i++) {
+		printf("Identify drive %d... ", i);
+		fflush(stdout);
+
+		rc = drive_identify(i, &disk[i]);
+
+		if (rc == EOK) {
+			printf("%u cylinders, %u heads, %u sectors\n",
+			    disk[i].cylinders, disk[i].heads, disk[i].sectors);
+		} else {
+			printf("Not found.\n");
+		}
+	}
 
 	n_disks = 0;
@@ -295,29 +307,23 @@
 	size_t i;
 
-	printf("Identify drive %d... ", disk_id);
-	fflush(stdout);
-
 	drv_head = ((disk_id != 0) ? DHR_DRV : 0);
 	d->present = false;
 
-	wait_status(0, ~SR_BSY);
+	if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
+		return EIO;
+
 	pio_write_8(&cmd->drive_head, drv_head);
 
 	/*
-	 * Detect if drive is present. This is only temorary.
-	 * We should really try for some time before giving up.
+	 * This is where we would most likely expect a non-existing device to
+	 * show up by not setting SR_DRDY.
 	 */
-	status = wait_status(0, ~SR_BSY);
-
-	if ((status & SR_DRDY) == 0) {
-		printf("None attached.\n");
-		return ENOENT;
-	}
-	/***/
-
-	wait_status(SR_DRDY, ~SR_BSY);
+	if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
+		return EIO;
+
 	pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
 
-	status = wait_status(0, ~SR_BSY);
+	if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
+		return EIO;
 
 	/* Read data from the disk buffer. */
@@ -344,7 +350,4 @@
 
 	d->blocks = d->cylinders * d->heads * d->sectors;
-
-	printf("Geometry: %u cylinders, %u heads, %u sectors\n",
-		d->cylinders, d->heads, d->sectors);
 
 	d->present = true;
@@ -396,8 +399,16 @@
 	/* Program a Read Sectors operation. */
 
-	wait_status(0, ~SR_BSY);
+	if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
+
 	pio_write_8(&cmd->drive_head, drv_head);
 
-	wait_status(SR_DRDY, ~SR_BSY);
+	if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
+
 	pio_write_8(&cmd->sector_count, 1);
 	pio_write_8(&cmd->sector_number, s);
@@ -407,9 +418,12 @@
 	pio_write_8(&cmd->command, CMD_READ_SECTORS);
 
-	status = wait_status(0, ~SR_BSY);
-
-	/* Read data from the disk buffer. */
+	if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
 
 	if ((status & SR_DRQ) != 0) {
+		/* Read data from the device buffer. */
+
 		for (i = 0; i < block_size / 2; i++) {
 			data = pio_read_16(&cmd->data_port);
@@ -464,10 +478,18 @@
 	fibril_mutex_lock(&d->lock);
 
-	/* Program a Read Sectors operation. */
-
-	wait_status(0, ~SR_BSY);
+	/* Program a Write Sectors operation. */
+
+	if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
+
 	pio_write_8(&cmd->drive_head, drv_head);
 
-	wait_status(SR_DRDY, ~SR_BSY);
+	if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
+
 	pio_write_8(&cmd->sector_count, 1);
 	pio_write_8(&cmd->sector_number, s);
@@ -477,9 +499,12 @@
 	pio_write_8(&cmd->command, CMD_WRITE_SECTORS);
 
-	status = wait_status(0, ~SR_BSY);
-
-	/* Write data to the disk buffer. */
+	if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
+		fibril_mutex_unlock(&d->lock);
+		return EIO;
+	}
 
 	if ((status & SR_DRQ) != 0) {
+		/* Write data to the device buffer. */
+
 		for (i = 0; i < block_size / 2; i++) {
 			pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
@@ -495,5 +520,5 @@
 }
 
-/** Wait until some status bits are set and some reset.
+/** Wait until some status bits are set and some are reset.
  *
  * Example: wait_status(SR_DRDY, ~SR_BSY) waits for SR_DRDY to become
@@ -502,15 +527,48 @@
  * @param set		Combination if bits which must be all set.
  * @param n_reset	Negated combination of bits which must be all reset.
- * @return		The last value of status register that was read.
- */
-static uint8_t wait_status(unsigned set, unsigned n_reset)
+ * @param pstatus	Pointer where to store last read status or NULL.
+ * @param timeout	Timeout in 10ms units.
+ *
+ * @return		EOK on success, EIO on timeout.
+ */
+static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
+    unsigned timeout)
 {
 	uint8_t status;
-
-	do {
+	int cnt;
+
+	status = pio_read_8(&cmd->status);
+
+	/*
+	 * This is crude, yet simple. First try with 1us delays
+	 * (most likely the device will respond very fast). If not,
+	 * start trying every 10 ms.
+	 */
+
+	cnt = 100;
+	while ((status & ~n_reset) != 0 || (status & set) != set) {
+		async_usleep(1);
+		--cnt;
+		if (cnt <= 0) break;
+
 		status = pio_read_8(&cmd->status);
-	} while ((status & ~n_reset) != 0 || (status & set) != set);
-
-	return status;
+	}
+
+	cnt = timeout;
+	while ((status & ~n_reset) != 0 || (status & set) != set) {
+		async_usleep(10000);
+		--cnt;
+		if (cnt <= 0) break;
+
+		status = pio_read_8(&cmd->status);
+	}
+
+	if (pstatus)
+		*pstatus = status;
+
+	if (cnt == 0)
+		return EIO;
+
+	return EOK;
 }
 
Index: uspace/srv/bd/ata_bd/ata_bd.h
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.h	(revision 54d0ddc60a3a04cab498b3ad83ca5a1f78abb735)
+++ uspace/srv/bd/ata_bd/ata_bd.h	(revision c145bc2fc737a941e2d7e0c94b3479d3c11bb93d)
@@ -135,4 +135,11 @@
 };
 
+/** Timeout definitions. Unit is 10 ms. */
+enum ata_timeout {
+	TIMEOUT_PROBE	=  100, /*  1 s */
+	TIMEOUT_BSY	=  100, /*  1 s */
+	TIMEOUT_DRDY	= 1000  /* 10 s */
+};
+
 typedef struct {
 	bool present;
