Index: uspace/drv/block/ata_bd/ata_bd.c
===================================================================
--- uspace/drv/block/ata_bd/ata_bd.c	(revision 35b8bfec4fe9165e74e88a84c760fdfb3fffcde9)
+++ uspace/drv/block/ata_bd/ata_bd.c	(revision ef521d4091b277b23a8ea026424ce4b01e0677d9)
@@ -97,4 +97,5 @@
 static int ata_bd_get_block_size(bd_srv_t *, size_t *);
 static int ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
+static int ata_bd_sync_cache(bd_srv_t *, aoff64_t, size_t);
 
 static int ata_rcmd_read(disk_t *disk, uint64_t ba, size_t cnt,
@@ -102,4 +103,5 @@
 static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt,
     const void *buf);
+static int ata_rcmd_flush_cache(disk_t *disk);
 static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id);
 static int ata_identify_dev(disk_t *disk, void *buf);
@@ -129,5 +131,6 @@
 	.write_blocks = ata_bd_write_blocks,
 	.get_block_size = ata_bd_get_block_size,
-	.get_num_blocks = ata_bd_get_num_blocks
+	.get_num_blocks = ata_bd_get_num_blocks,
+	.sync_cache = ata_bd_sync_cache
 };
 
@@ -586,4 +589,16 @@
 }
 
+/** Flush cache. */
+static int ata_bd_sync_cache(bd_srv_t *bd, uint64_t ba, size_t cnt)
+{
+	disk_t *disk = bd_srv_disk(bd);
+
+	/* ATA cannot flush just some blocks, we just flush everything. */
+	(void)ba;
+	(void)cnt;
+
+	return ata_rcmd_flush_cache(disk);
+}
+
 /** PIO data-in command protocol. */
 static int ata_pio_data_in(disk_t *disk, void *obuf, size_t obuf_size,
@@ -639,4 +654,19 @@
 		}
 	}
+
+	if (status & SR_ERR)
+		return EIO;
+
+	return EOK;
+}
+
+/** PIO non-data command protocol. */
+static int ata_pio_nondata(disk_t *disk)
+{
+	ata_ctrl_t *ctrl = disk->ctrl;
+	uint8_t status;
+
+	if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
+		return EIO;
 
 	if (status & SR_ERR)
@@ -1076,4 +1106,44 @@
 	rc = ata_pio_data_out(disk, buf, cnt * disk->block_size,
 	    disk->block_size, cnt);
+
+	fibril_mutex_unlock(&ctrl->lock);
+	return rc;
+}
+
+/** Flush cached data to nonvolatile storage.
+ *
+ * @param disk		Disk
+ *
+ * @return EOK on success, EIO on error.
+ */
+static int ata_rcmd_flush_cache(disk_t *disk)
+{
+	ata_ctrl_t *ctrl = disk->ctrl;
+	uint8_t drv_head;
+	int rc;
+
+	/* New value for Drive/Head register */
+	drv_head =
+	    (disk_dev_idx(disk) != 0) ? DHR_DRV : 0;
+
+	fibril_mutex_lock(&ctrl->lock);
+
+	/* Program a Flush Cache operation. */
+
+	if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
+		fibril_mutex_unlock(&ctrl->lock);
+		return EIO;
+	}
+
+	pio_write_8(&ctrl->cmd->drive_head, drv_head);
+
+	if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
+		fibril_mutex_unlock(&ctrl->lock);
+		return EIO;
+	}
+
+	pio_write_8(&ctrl->cmd->command, CMD_FLUSH_CACHE);
+
+	rc = ata_pio_nondata(disk);
 
 	fibril_mutex_unlock(&ctrl->lock);
Index: uspace/drv/block/ata_bd/ata_hw.h
===================================================================
--- uspace/drv/block/ata_bd/ata_hw.h	(revision 35b8bfec4fe9165e74e88a84c760fdfb3fffcde9)
+++ uspace/drv/block/ata_bd/ata_hw.h	(revision ef521d4091b277b23a8ea026424ce4b01e0677d9)
@@ -136,5 +136,6 @@
 	CMD_PACKET		= 0xA0,
 	CMD_IDENTIFY_PKT_DEV	= 0xA1,
-	CMD_IDENTIFY_DRIVE	= 0xEC
+	CMD_IDENTIFY_DRIVE	= 0xEC,
+	CMD_FLUSH_CACHE		= 0xE7
 };
 
