Index: uspace/srv/bd/ata_bd/Makefile
===================================================================
--- uspace/srv/bd/ata_bd/Makefile	(revision 96cbd18e89b261c95fc443d94beaaab8cbaa29d5)
+++ 	(revision )
@@ -1,36 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-USPACE_PREFIX = ../../..
-BINARY = ata_bd
-
-SOURCES = \
-	ata_bd.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision 96cbd18e89b261c95fc443d94beaaab8cbaa29d5)
+++ 	(revision )
@@ -1,1143 +1,0 @@
-/*
- * Copyright (c) 2013 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup bd
- * @{
- */
-
-/**
- * @file
- * @brief ATA disk driver
- *
- * This driver supports CHS, 28-bit and 48-bit LBA addressing, as well as
- * PACKET devices. It only uses PIO transfers. There is no support DMA
- * or any other fancy features such as S.M.A.R.T, removable devices, etc.
- *
- * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7
- * standards, as published by the ANSI, NCITS and INCITS standards bodies,
- * which are freely available. This driver contains no vendor-specific
- * code at this moment.
- *
- * The driver services a single controller which can have up to two disks
- * attached.
- */
-
-#include <stdio.h>
-#include <ddi.h>
-#include <async.h>
-#include <as.h>
-#include <bd_srv.h>
-#include <fibril_synch.h>
-#include <stdint.h>
-#include <str.h>
-#include <loc.h>
-#include <sys/types.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <byteorder.h>
-#include <task.h>
-#include <macros.h>
-
-#include "ata_hw.h"
-#include "ata_bd.h"
-
-#define NAME       "ata_bd"
-#define NAMESPACE  "bd"
-
-/** Number of defined legacy controller base addresses. */
-#define LEGACY_CTLS 4
-
-/**
- * Size of data returned from Identify Device or Identify Packet Device
- * command.
- */
-static const size_t identify_data_size = 512;
-
-/** I/O base addresses for legacy (ISA-compatible) controllers. */
-static ata_base_t legacy_base[LEGACY_CTLS] = {
-	{ 0x1f0, 0x3f0 },
-	{ 0x170, 0x370 },
-	{ 0x1e8, 0x3e8 },
-	{ 0x168, 0x368 }
-};
-
-/** Controller */
-static ata_ctrl_t ata_ctrl;
-
-static void print_syntax(void);
-static int ata_bd_init(ata_ctrl_t *ctrl);
-static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
-
-static int ata_bd_open(bd_srvs_t *, bd_srv_t *);
-static int ata_bd_close(bd_srv_t *);
-static int ata_bd_read_blocks(bd_srv_t *, uint64_t ba, size_t cnt, void *buf,
-    size_t);
-static int ata_bd_read_toc(bd_srv_t *, uint8_t session, void *buf, size_t);
-static int ata_bd_write_blocks(bd_srv_t *, uint64_t ba, size_t cnt,
-    const void *buf, size_t);
-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_rcmd_read(disk_t *disk, uint64_t ba, size_t cnt,
-    void *buf);
-static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt,
-    const void *buf);
-static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id);
-static int drive_identify(disk_t *disk, void *buf);
-static int 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);
-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_toc(disk_t *disk, uint8_t ses,
-    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);
-static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc,
-    uint16_t scnt);
-static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset,
-    uint8_t *pstatus, unsigned timeout);
-
-static bd_ops_t ata_bd_ops = {
-	.open = ata_bd_open,
-	.close = ata_bd_close,
-	.read_blocks = ata_bd_read_blocks,
-	.read_toc = ata_bd_read_toc,
-	.write_blocks = ata_bd_write_blocks,
-	.get_block_size = ata_bd_get_block_size,
-	.get_num_blocks = ata_bd_get_num_blocks
-};
-
-static disk_t *bd_srv_disk(bd_srv_t *bd)
-{
-	return (disk_t *)bd->srvs->sarg;
-}
-
-static int disk_dev_idx(disk_t *disk)
-{
-	return (disk->disk_id & 1);
-}
-
-int main(int argc, char **argv)
-{
-	char name[16];
-	int i, rc;
-	int n_disks;
-	unsigned ctl_num;
-	char *eptr;
-	ata_ctrl_t *ctrl = &ata_ctrl;
-
-	printf(NAME ": ATA disk driver\n");
-
-	if (argc > 1) {
-		ctl_num = strtoul(argv[1], &eptr, 0);
-		if (*eptr != '\0' || ctl_num == 0 || ctl_num > 4) {
-			printf("Invalid argument.\n");
-			print_syntax();
-			return -1;
-		}
-	} else {
-		ctl_num = 1;
-	}
-
-	ctrl->cmd_physical = legacy_base[ctl_num - 1].cmd;
-	ctrl->ctl_physical = legacy_base[ctl_num - 1].ctl;
-
-	printf("I/O address %p/%p\n", (void *) ctrl->cmd_physical,
-	    (void *) ctrl->ctl_physical);
-
-	if (ata_bd_init(ctrl) != EOK)
-		return -1;
-
-	for (i = 0; i < MAX_DISKS; i++) {
-		printf("Identify drive %d... ", i);
-		fflush(stdout);
-
-		rc = disk_init(ctrl, &ctrl->disk[i], i);
-
-		if (rc == EOK) {
-			disk_print_summary(&ctrl->disk[i]);
-		} else {
-			printf("Not found.\n");
-		}
-	}
-
-	n_disks = 0;
-
-	for (i = 0; i < MAX_DISKS; i++) {
-		/* Skip unattached drives. */
-		if (ctrl->disk[i].present == false)
-			continue;
-		
-		snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i);
-		rc = loc_service_register(name, &ctrl->disk[i].service_id);
-		if (rc != EOK) {
-			printf(NAME ": Unable to register device %s.\n", name);
-			return rc;
-		}
-		++n_disks;
-	}
-
-	if (n_disks == 0) {
-		printf("No disks detected.\n");
-		return -1;
-	}
-
-	printf("%s: Accepting connections\n", NAME);
-	task_retval(0);
-	async_manager();
-
-	/* Not reached */
-	return 0;
-}
-
-
-static void print_syntax(void)
-{
-	printf("Syntax: " NAME " <controller_number>\n");
-	printf("Controller number = 1..4\n");
-}
-
-/** Print one-line device summary. */
-static void disk_print_summary(disk_t *d)
-{
-	uint64_t mbytes;
-
-	printf("%s: ", d->model);
-
-	if (d->dev_type == ata_reg_dev) {
-		switch (d->amode) {
-		case am_chs:
-			printf("CHS %u cylinders, %u heads, %u sectors",
-			    d->geom.cylinders, d->geom.heads,
-			    d->geom.sectors);
-			break;
-		case am_lba28:
-			printf("LBA-28");
-			break;
-		case am_lba48:
-			printf("LBA-48");
-			break;
-		}
-	} else {
-		printf("PACKET");
-	}
-
-	printf(" %" PRIu64 " blocks", d->blocks);
-
-	mbytes = d->blocks / (2 * 1024);
-	if (mbytes > 0)
-		printf(" %" PRIu64 " MB.", mbytes);
-
-	printf("\n");
-}
-
-/** Register driver and enable device I/O. */
-static int ata_bd_init(ata_ctrl_t *ctrl)
-{
-	async_set_client_connection(ata_bd_connection);
-	int rc = loc_server_register(NAME);
-	if (rc != EOK) {
-		printf("%s: Unable to register driver.\n", NAME);
-		return rc;
-	}
-	
-	void *vaddr;
-	rc = pio_enable((void *) ctrl->cmd_physical, sizeof(ata_cmd_t), &vaddr);
-	if (rc != EOK) {
-		printf("%s: Could not initialize device I/O space.\n", NAME);
-		return rc;
-	}
-	
-	ctrl->cmd = vaddr;
-	
-	rc = pio_enable((void *) ctrl->ctl_physical, sizeof(ata_ctl_t), &vaddr);
-	if (rc != EOK) {
-		printf("%s: Could not initialize device I/O space.\n", NAME);
-		return rc;
-	}
-	
-	ctrl->ctl = vaddr;
-	
-	return EOK;
-}
-
-/** Block device connection handler */
-static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	service_id_t dsid;
-	int i;
-	disk_t *disk;
-
-	/* Get the device service ID. */
-	dsid = IPC_GET_ARG1(*icall);
-
-	/* Determine which disk device is the client connecting to. */
-	disk = NULL;
-	for (i = 0; i < MAX_DISKS; i++)
-		if (ata_ctrl.disk[i].service_id == dsid)
-			disk = &ata_ctrl.disk[i];
-
-	if (disk == NULL || disk->present == false) {
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-
-	bd_conn(iid, icall, &disk->bds);
-}
-
-/** Initialize a disk.
- *
- * Probes for a disk, determines its parameters and initializes
- * the disk structure.
- */
-static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id)
-{
-	identify_data_t idata;
-	uint8_t model[40];
-	ata_inquiry_data_t inq_data;
-	uint16_t w;
-	uint8_t c;
-	uint16_t bc;
-	size_t pos, len;
-	int rc;
-	unsigned i;
-
-	d->ctrl = ctrl;
-	d->disk_id = disk_id;
-	d->present = false;
-	fibril_mutex_initialize(&d->lock);
-
-	bd_srvs_init(&d->bds);
-	d->bds.ops = &ata_bd_ops;
-	d->bds.sarg = d;
-
-	/* Try identify command. */
-	rc = drive_identify(d, &idata);
-	if (rc == EOK) {
-		/* Success. It's a register (non-packet) device. */
-		printf("ATA register-only device found.\n");
-		d->dev_type = ata_reg_dev;
-	} else if (rc == EIO) {
-		/*
-		 * There is something, but not a register device. Check to see
-		 * whether the IDENTIFY command left the packet signature in
-		 * the registers in case this is a packet device.
-		 *
-		 * According to the ATA specification, the LBA low and
-		 * interrupt reason registers should be set to 0x01. However,
-		 * there are many devices that do not follow this and only set
-		 * the byte count registers. So, only check these.
-		 */
-		bc = ((uint16_t)pio_read_8(&ctrl->cmd->cylinder_high) << 8) |
-		    pio_read_8(&ctrl->cmd->cylinder_low);
-
-		if (bc == PDEV_SIGNATURE_BC) {
-			rc = identify_pkt_dev(d, &idata);
-			if (rc == EOK) {
-				/* We have a packet device. */
-				d->dev_type = ata_pkt_dev;
-			} else {
-				return EIO;
-			}
-		} else {
-			/* Nope. Something's there, but not recognized. */
-			return EIO;
-		}
-	} else {
-		/* Operation timed out. That means there is no device there. */
-		return EIO;
-	}
-
-	if (d->dev_type == ata_pkt_dev) {
-		/* Packet device */
-		d->amode = 0;
-
-		d->geom.cylinders = 0;
-		d->geom.heads = 0;
-		d->geom.sectors = 0;
-
-		d->blocks = 0;
-	} else if ((idata.caps & rd_cap_lba) == 0) {
-		/* Device only supports CHS addressing. */
-		d->amode = am_chs;
-
-		d->geom.cylinders = idata.cylinders;
-		d->geom.heads = idata.heads;
-		d->geom.sectors = idata.sectors;
-
-		d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors;
-	} else if ((idata.cmd_set1 & cs1_addr48) == 0) {
-		/* Device only supports LBA-28 addressing. */
-		d->amode = am_lba28;
-
-		d->geom.cylinders = 0;
-		d->geom.heads = 0;
-		d->geom.sectors = 0;
-
-		d->blocks =
-		     (uint32_t) idata.total_lba28_0 | 
-		    ((uint32_t) idata.total_lba28_1 << 16);
-	} else {
-		/* Device supports LBA-48 addressing. */
-		d->amode = am_lba48;
-
-		d->geom.cylinders = 0;
-		d->geom.heads = 0;
-		d->geom.sectors = 0;
-
-		d->blocks =
-		     (uint64_t) idata.total_lba48_0 |
-		    ((uint64_t) idata.total_lba48_1 << 16) |
-		    ((uint64_t) idata.total_lba48_2 << 32) | 
-		    ((uint64_t) idata.total_lba48_3 << 48);
-	}
-
-	/*
-	 * Convert model name to string representation.
-	 */
-	for (i = 0; i < 20; i++) {
-		w = idata.model_name[i];
-		model[2 * i] = w >> 8;
-		model[2 * i + 1] = w & 0x00ff;
-	}
-
-	len = 40;
-	while (len > 0 && model[len - 1] == 0x20)
-		--len;
-
-	pos = 0;
-	for (i = 0; i < len; ++i) {
-		c = model[i];
-		if (c >= 0x80) c = '?';
-
-		chr_encode(c, d->model, &pos, 40);
-	}
-	d->model[pos] = '\0';
-
-	if (d->dev_type == ata_pkt_dev) {
-		/* Send inquiry. */
-		rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data));
-		if (rc != EOK) {
-			printf("Device inquiry failed.\n");
-			d->present = false;
-			return EIO;
-		}
-
-		/* Check device type. */
-		if (INQUIRY_PDEV_TYPE(inq_data.pdev_type) != PDEV_TYPE_CDROM)
-			printf("Warning: Peripheral device type is not CD-ROM.\n");
-
-		/* Assume 2k block size for now. */
-		d->block_size = 2048;
-	} else {
-		/* Assume register Read always uses 512-byte blocks. */
-		d->block_size = 512;
-	}
-
-	d->present = true;
-	return EOK;
-}
-
-static int ata_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
-{
-	return EOK;
-}
-
-static int ata_bd_close(bd_srv_t *bd)
-{
-	return EOK;
-}
-
-/** Read multiple blocks from the device. */
-static int ata_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
-    void *buf, size_t size)
-{
-	disk_t *disk = bd_srv_disk(bd);
-	int rc;
-
-	if (size < cnt * disk->block_size)
-		return EINVAL;
-
-	while (cnt > 0) {
-		if (disk->dev_type == ata_reg_dev) {
-			rc = ata_rcmd_read(disk, ba, 1, buf);
-		} else {
-			rc = ata_pcmd_read_12(disk, ba, 1, buf,
-			    disk->block_size);
-		}
-
-		if (rc != EOK)
-			return rc;
-
-		++ba;
-		--cnt;
-		buf += disk->block_size;
-	}
-
-	return EOK;
-}
-
-/** Read TOC from device. */
-static int ata_bd_read_toc(bd_srv_t *bd, uint8_t session, void *buf, size_t size)
-{
-	disk_t *disk = bd_srv_disk(bd);
-
-	return ata_pcmd_read_toc(disk, session, buf, size);
-}
-
-/** Write multiple blocks to the device. */
-static int ata_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
-    const void *buf, size_t size)
-{
-	disk_t *disk = bd_srv_disk(bd);
-	int rc;
-
-	if (disk->dev_type != ata_reg_dev)
-		return ENOTSUP;
-
-	if (size < cnt * disk->block_size)
-		return EINVAL;
-
-	while (cnt > 0) {
-		rc = ata_rcmd_write(disk, ba, 1, buf);
-		if (rc != EOK)
-			return rc;
-
-		++ba;
-		--cnt;
-		buf += disk->block_size;
-	}
-
-	return EOK;
-}
-
-/** Get device block size. */
-static int ata_bd_get_block_size(bd_srv_t *bd, size_t *rbsize)
-{
-	disk_t *disk = bd_srv_disk(bd);
-
-	*rbsize = disk->block_size;
-	return EOK;
-}
-
-/** Get device number of blocks. */
-static int ata_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
-{
-	disk_t *disk = bd_srv_disk(bd);
-
-	*rnb = disk->blocks;
-	return EOK;
-}
-
-/** Issue IDENTIFY command.
- *
- * Reads @c identify data into the provided buffer. This is used to detect
- * whether an ATA device is present and if so, to determine its parameters.
- *
- * @param disk		Disk
- * @param buf		Pointer to a 512-byte buffer.
- *
- * @return		ETIMEOUT on timeout (this can mean the device is
- *			not present). EIO if device responds with error.
- */
-static int drive_identify(disk_t *disk, void *buf)
-{
-	ata_ctrl_t *ctrl = disk->ctrl;
-	uint16_t data;
-	uint8_t status;
-	uint8_t drv_head;
-	size_t i;
-
-	drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
-
-	if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
-		return ETIMEOUT;
-
-	pio_write_8(&ctrl->cmd->drive_head, drv_head);
-
-	/*
-	 * Do not wait for DRDY to be set in case this is a packet device.
-	 * We determine whether the device is present by waiting for DRQ to be
-	 * set after issuing the command.
-	 */
-	if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
-		return ETIMEOUT;
-
-	pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_DRIVE);
-
-	if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
-		return ETIMEOUT;
-
-	/*
-	 * If ERR is set, this may be a packet device, so return EIO to cause
-	 * the caller to check for one.
-	 */
-	if ((status & SR_ERR) != 0) {
-		return EIO;
-	}
-
-	if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
-		return ETIMEOUT;
-
-	/* Read data from the disk buffer. */
-
-	for (i = 0; i < identify_data_size / 2; i++) {
-		data = pio_read_16(&ctrl->cmd->data_port);
-		((uint16_t *) buf)[i] = data;
-	}
-
-	return EOK;
-}
-
-/** Issue Identify Packet Device command.
- *
- * Reads @c identify data into the provided buffer. This is used to detect
- * whether an ATAPI device is present and if so, to determine its parameters.
- *
- * @param disk		Disk
- * @param buf		Pointer to a 512-byte buffer.
- */
-static int identify_pkt_dev(disk_t *disk, void *buf)
-{
-	ata_ctrl_t *ctrl = disk->ctrl;
-	uint16_t data;
-	uint8_t status;
-	uint8_t drv_head;
-	size_t i;
-
-	drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
-
-	if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
-		return EIO;
-
-	pio_write_8(&ctrl->cmd->drive_head, drv_head);
-
-	/* For ATAPI commands we do not need to wait for DRDY. */
-	if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
-		return EIO;
-
-	pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_PKT_DEV);
-
-	if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
-		return EIO;
-
-	/* Read data from the device buffer. */
-
-	if ((status & SR_DRQ) != 0) {
-		for (i = 0; i < identify_data_size / 2; i++) {
-			data = pio_read_16(&ctrl->cmd->data_port);
-			((uint16_t *) buf)[i] = data;
-		}
-	}
-
-	if ((status & SR_ERR) != 0)
-		return EIO;
-
-	return EOK;
-}
-
-/** Issue packet command (i. e. write a command packet to the device).
- *
- * Only data-in commands are supported (e.g. inquiry, read).
- *
- * @param disk		Disk
- * @param obuf		Buffer for storing data read from device
- * @param obuf_size	Size of obuf in bytes
- *
- * @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)
-{
-	ata_ctrl_t *ctrl = disk->ctrl;
-	size_t i;
-	uint8_t status;
-	uint8_t drv_head;
-	size_t data_size;
-	uint16_t val;
-
-	fibril_mutex_lock(&disk->lock);
-
-	/* New value for Drive/Head register */
-	drv_head =
-	    ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
-
-	if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	pio_write_8(&ctrl->cmd->drive_head, drv_head);
-
-	if (wait_status(ctrl, 0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	/* Byte count <- max. number of bytes we can read in one transfer. */
-	pio_write_8(&ctrl->cmd->cylinder_low, 0xfe);
-	pio_write_8(&ctrl->cmd->cylinder_high, 0xff);
-
-	pio_write_8(&ctrl->cmd->command, CMD_PACKET);
-
-	if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	/* Write command packet. */
-	for (i = 0; i < (cpkt_size + 1) / 2; i++)
-		pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) cpkt)[i]);
-
-	if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	if ((status & SR_DRQ) == 0) {
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	/* Read byte count. */
-	data_size = (uint16_t) pio_read_8(&ctrl->cmd->cylinder_low) +
-	    ((uint16_t) pio_read_8(&ctrl->cmd->cylinder_high) << 8);
-
-	/* Check whether data fits into output buffer. */
-	if (data_size > obuf_size) {
-		/* Output buffer is too small to store data. */
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	/* Read data from the device buffer. */
-	for (i = 0; i < (data_size + 1) / 2; i++) {
-		val = pio_read_16(&ctrl->cmd->data_port);
-		((uint16_t *) obuf)[i] = val;
-	}
-
-	if (status & SR_ERR) {
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	fibril_mutex_unlock(&disk->lock);
-
-	return EOK;
-}
-
-/** Issue ATAPI Inquiry.
- *
- * @param disk		Disk
- * @param obuf		Buffer for storing inquiry data read from device
- * @param obuf_size	Size of obuf in bytes
- *
- * @return EOK on success, EIO on error.
- */
-static int ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size)
-{
-	ata_pcmd_inquiry_t cp;
-	int rc;
-
-	memset(&cp, 0, sizeof(cp));
-
-	cp.opcode = PCMD_INQUIRY;
-	cp.alloc_len = min(obuf_size, 0xff); /* Allocation length */
-
-	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Issue ATAPI read(12) command.
- *
- * Output buffer must be large enough to hold the data, otherwise the
- * function will fail.
- *
- * @param disk		Disk
- * @param ba		Starting block address
- * @param cnt		Number of blocks to read
- * @param obuf		Buffer for storing inquiry data read from device
- * @param obuf_size	Size of obuf in bytes
- *
- * @return EOK on success, EIO on error.
- */
-static int ata_pcmd_read_12(disk_t *disk, uint64_t ba, size_t cnt,
-    void *obuf, size_t obuf_size)
-{
-	ata_pcmd_read_12_t cp;
-	int rc;
-
-	if (ba > UINT32_MAX)
-		return EINVAL;
-
-	memset(&cp, 0, sizeof(cp));
-
-	cp.opcode = PCMD_READ_12;
-	cp.ba = host2uint32_t_be(ba);
-	cp.nblocks = host2uint32_t_be(cnt);
-
-	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size);
-	if (rc != EOK)
-		return rc;
-
-	return EOK;
-}
-
-/** Issue ATAPI read TOC command.
- *
- * Read TOC in 'multi-session' format (first and last session number
- * with last session LBA).
- *
- * http://suif.stanford.edu/~csapuntz/specs/INF-8020.PDF page 171
- *
- * Output buffer must be large enough to hold the data, otherwise the
- * function will fail.
- *
- * @param disk		Disk
- * @param session	Starting session
- * @param obuf		Buffer for storing inquiry data read from device
- * @param obuf_size	Size of obuf in bytes
- *
- * @return EOK on success, EIO on error.
- */
-static int ata_pcmd_read_toc(disk_t *disk, uint8_t session, void *obuf,
-    size_t obuf_size)
-{
-	ata_pcmd_read_toc_t cp;
-	int rc;
-
-	memset(&cp, 0, sizeof(cp));
-
-	cp.opcode = PCMD_READ_TOC;
-	cp.msf = 0;
-	cp.format = 0x01; /* 0x01 = multi-session mode */
-	cp.start = session;
-	cp.size = host2uint16_t_be(obuf_size);
-	cp.oldformat = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */
-	
-	rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size);
-	if (rc != EOK)
-		return rc;
-	
-	return EOK;
-}
-
-/** Read a physical from the device.
- *
- * @param disk		Disk
- * @param ba		Address the first block.
- * @param cnt		Number of blocks to transfer.
- * @param buf		Buffer for holding the data.
- *
- * @return EOK on success, EIO on error.
- */
-static int ata_rcmd_read(disk_t *disk, uint64_t ba, size_t blk_cnt,
-    void *buf)
-{
-	ata_ctrl_t *ctrl = disk->ctrl;
-	size_t i;
-	uint16_t data;
-	uint8_t status;
-	uint8_t drv_head;
-	block_coord_t bc;
-
-	/* Silence warning. */
-	memset(&bc, 0, sizeof(bc));
-
-	/* Compute block coordinates. */
-	if (coord_calc(disk, ba, &bc) != EOK)
-		return EINVAL;
-
-	/* New value for Drive/Head register */
-	drv_head =
-	    ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0) |
-	    ((disk->amode != am_chs) ? DHR_LBA : 0) |
-	    (bc.h & 0x0f);
-
-	fibril_mutex_lock(&disk->lock);
-
-	/* Program a Read Sectors operation. */
-
-	if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&disk->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(&disk->lock);
-		return EIO;
-	}
-
-	/* Program block coordinates into the device. */
-	coord_sc_program(ctrl, &bc, 1);
-
-	pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ?
-	    CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
-
-	if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	if ((status & SR_DRQ) != 0) {
-		/* Read data from the device buffer. */
-
-		for (i = 0; i < disk->block_size / 2; i++) {
-			data = pio_read_16(&ctrl->cmd->data_port);
-			((uint16_t *) buf)[i] = data;
-		}
-	}
-
-	if ((status & SR_ERR) != 0)
-		return EIO;
-
-	fibril_mutex_unlock(&disk->lock);
-	return EOK;
-}
-
-/** Write a physical block to the device.
- *
- * @param disk		Disk
- * @param ba		Address of the first block.
- * @param cnt		Number of blocks to transfer.
- * @param buf		Buffer holding the data to write.
- *
- * @return EOK on success, EIO on error.
- */
-static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt,
-    const void *buf)
-{
-	ata_ctrl_t *ctrl = disk->ctrl;
-	size_t i;
-	uint8_t status;
-	uint8_t drv_head;
-	block_coord_t bc;
-
-	/* Silence warning. */
-	memset(&bc, 0, sizeof(bc));
-
-	/* Compute block coordinates. */
-	if (coord_calc(disk, ba, &bc) != EOK)
-		return EINVAL;
-
-	/* New value for Drive/Head register */
-	drv_head =
-	    ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0) |
-	    ((disk->amode != am_chs) ? DHR_LBA : 0) |
-	    (bc.h & 0x0f);
-
-	fibril_mutex_lock(&disk->lock);
-
-	/* Program a Write Sectors operation. */
-
-	if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&disk->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(&disk->lock);
-		return EIO;
-	}
-
-	/* Program block coordinates into the device. */
-	coord_sc_program(ctrl, &bc, 1);
-
-	pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ?
-	    CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
-
-	if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
-		fibril_mutex_unlock(&disk->lock);
-		return EIO;
-	}
-
-	if ((status & SR_DRQ) != 0) {
-		/* Write data to the device buffer. */
-
-		for (i = 0; i < disk->block_size / 2; i++) {
-			pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) buf)[i]);
-		}
-	}
-
-	fibril_mutex_unlock(&disk->lock);
-
-	if (status & SR_ERR)
-		return EIO;
-
-	return EOK;
-}
-
-/** Calculate block coordinates.
- *
- * Calculates block coordinates in the best coordinate system supported
- * by the device. These can be later programmed into the device using
- * @c coord_sc_program().
- *
- * @return EOK on success or EINVAL if block index is past end of device.
- */
-static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc)
-{
-	uint64_t c;
-	uint64_t idx;
-
-	/* Check device bounds. */
-	if (ba >= d->blocks)
-		return EINVAL;
-
-	bc->amode = d->amode;
-
-	switch (d->amode) {
-	case am_chs:
-		/* Compute CHS coordinates. */
-		c = ba / (d->geom.heads * d->geom.sectors);
-		idx = ba % (d->geom.heads * d->geom.sectors);
-
-		bc->cyl_lo = c & 0xff;
-		bc->cyl_hi = (c >> 8) & 0xff;
-		bc->h      = (idx / d->geom.sectors) & 0x0f;
-		bc->sector = (1 + (idx % d->geom.sectors)) & 0xff;
-		break;
-
-	case am_lba28:
-		/* Compute LBA-28 coordinates. */
-		bc->c0 = ba & 0xff;		/* bits 0-7 */
-		bc->c1 = (ba >> 8) & 0xff;	/* bits 8-15 */
-		bc->c2 = (ba >> 16) & 0xff;	/* bits 16-23 */
-		bc->h  = (ba >> 24) & 0x0f;	/* bits 24-27 */
-		break;
-
-	case am_lba48:
-		/* Compute LBA-48 coordinates. */
-		bc->c0 = ba & 0xff;		/* bits 0-7 */
-		bc->c1 = (ba >> 8) & 0xff;	/* bits 8-15 */
-		bc->c2 = (ba >> 16) & 0xff;	/* bits 16-23 */
-		bc->c3 = (ba >> 24) & 0xff;	/* bits 24-31 */
-		bc->c4 = (ba >> 32) & 0xff;	/* bits 32-39 */
-		bc->c5 = (ba >> 40) & 0xff;	/* bits 40-47 */
-		bc->h  = 0;
-		break;
-	}
-
-	return EOK;
-}
-
-/** Program block coordinates and sector count into ATA registers.
- *
- * Note that bc->h must be programmed separately into the device/head register.
- *
- * @param ctrl		Controller
- * @param bc		Block coordinates
- * @param scnt		Sector count
- */
-static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc,
-    uint16_t scnt)
-{
-	ata_cmd_t *cmd = ctrl->cmd;
-
-	if (bc->amode == am_lba48) {
-		/* Write high-order bits. */
-		pio_write_8(&cmd->sector_count, scnt >> 8);
-		pio_write_8(&cmd->sector_number, bc->c3);
-		pio_write_8(&cmd->cylinder_low, bc->c4);
-		pio_write_8(&cmd->cylinder_high, bc->c5);
-	}
-
-	/* Write low-order bits. */
-	pio_write_8(&cmd->sector_count, scnt & 0x00ff);
-	pio_write_8(&cmd->sector_number, bc->c0);
-	pio_write_8(&cmd->cylinder_low, bc->c1);
-	pio_write_8(&cmd->cylinder_high, bc->c2);
-}
-
-/** Wait until some status bits are set and some are reset.
- *
- * Example: wait_status(ctrl, SR_DRDY, ~SR_BSY, ...) waits for SR_DRDY to become
- * set and SR_BSY to become reset.
- *
- * @param ctrl		Controller
- * @param set		Combination if bits which must be all set.
- * @param n_reset	Negated combination of bits which must be all 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(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset,
-    uint8_t *pstatus, unsigned timeout)
-{
-	uint8_t status;
-	int cnt;
-
-	status = pio_read_8(&ctrl->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(&ctrl->cmd->status);
-	}
-
-	cnt = timeout;
-	while ((status & ~n_reset) != 0 || (status & set) != set) {
-		async_usleep(10000);
-		--cnt;
-		if (cnt <= 0) break;
-
-		status = pio_read_8(&ctrl->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 96cbd18e89b261c95fc443d94beaaab8cbaa29d5)
+++ 	(revision )
@@ -1,144 +1,0 @@
-/*
- * Copyright (c) 2009 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup bd
- * @{
- */
-/** @file ATA driver definitions.
- */
-
-#ifndef __ATA_BD_H__
-#define __ATA_BD_H__
-
-#include <bd_srv.h>
-#include <sys/types.h>
-#include <fibril_synch.h>
-#include <str.h>
-
-/** Base addresses for ATA I/O blocks. */
-typedef struct {
-	uintptr_t cmd;	/**< Command block base address. */
-	uintptr_t ctl;	/**< Control block base address. */
-} ata_base_t;
-
-/** Timeout definitions. Unit is 10 ms. */
-enum ata_timeout {
-	TIMEOUT_PROBE	=  100, /*  1 s */
-	TIMEOUT_BSY	=  100, /*  1 s */
-	TIMEOUT_DRDY	= 1000  /* 10 s */
-};
-
-enum ata_dev_type {
-	ata_reg_dev,	/* Register device (no packet feature set support) */
-	ata_pkt_dev	/* Packet device (supports packet feature set). */
-};
-
-/** Register device block addressing mode. */
-enum rd_addr_mode {
-	am_chs,		/**< CHS block addressing */
-	am_lba28,	/**< LBA-28 block addressing */
-	am_lba48	/**< LBA-48 block addressing */
-};
-
-/** Block coordinates */
-typedef struct {
-	enum rd_addr_mode amode;
-
-	union {
-		/** CHS coordinates */
-		struct {
-			uint8_t sector;
-			uint8_t cyl_lo;
-			uint8_t cyl_hi;
-		};
-		/** LBA coordinates */
-		struct {
-			uint8_t c0;
-			uint8_t c1;
-			uint8_t c2;
-			uint8_t c3;
-			uint8_t c4;
-			uint8_t c5;
-		};
-	};
-
-	/** Lower 4 bits for device/head register */
-	uint8_t h;
-} block_coord_t;
-
-/** ATA device state structure. */
-typedef struct {
-	bool present;
-	struct ata_ctrl *ctrl;
-
-	/** Device type */
-	enum ata_dev_type dev_type;
-
-	/** Addressing mode to use (if register device) */
-	enum rd_addr_mode amode;
-
-	/*
-	 * Geometry. Only valid if operating in CHS mode.
-	 */
-	struct {
-		unsigned heads;
-		unsigned cylinders;
-		unsigned sectors;
-	} geom;
-
-	uint64_t blocks;
-	size_t block_size;
-
-	char model[STR_BOUNDS(40) + 1];
-
-	fibril_mutex_t lock;
-	service_id_t service_id;
-	int disk_id;
-	bd_srvs_t bds;
-} disk_t;
-
-/** ATA controller */
-typedef struct ata_ctrl {
-	/** I/O base address of the command registers */
-	uintptr_t cmd_physical;
-	/** I/O base address of the control registers */
-	uintptr_t ctl_physical;
-
-	/** Command registers */
-	ata_cmd_t *cmd;
-	/** Control registers */
-	ata_ctl_t *ctl;
-
-	/** Per-disk state. */
-	disk_t disk[MAX_DISKS];
-} ata_ctrl_t;
-
-#endif
-
-/** @}
- */
Index: uspace/srv/bd/ata_bd/ata_hw.h
===================================================================
--- uspace/srv/bd/ata_bd/ata_hw.h	(revision 96cbd18e89b261c95fc443d94beaaab8cbaa29d5)
+++ 	(revision )
@@ -1,322 +1,0 @@
-/*
- * Copyright (c) 2009 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup bd
- * @{
- */
-/** @file ATA hardware protocol (registers, data structures).
- */
-
-#ifndef __ATA_HW_H__
-#define __ATA_HW_H__
-
-#include <sys/types.h>
-
-enum {
-	CTL_READ_START  = 0,
-	CTL_WRITE_START = 1,
-};
-
-enum {
-	STATUS_FAILURE = 0
-};
-
-enum {
-	MAX_DISKS	= 2
-};
-
-/** ATA Command Register Block. */
-typedef union {
-	/* Read/Write */
-	struct {
-		uint16_t data_port;
-		uint8_t sector_count;
-		uint8_t sector_number;
-		uint8_t cylinder_low;
-		uint8_t cylinder_high;
-		uint8_t drive_head;
-		uint8_t pad_rw0;
-	};
-
-	/* Read Only */
-	struct {
-		uint8_t pad_ro0;
-		uint8_t error;
-		uint8_t pad_ro1[5];
-		uint8_t status;
-	};
-
-	/* Write Only */
-	struct {
-		uint8_t pad_wo0;
-		uint8_t features;
-		uint8_t pad_wo1[5];
-		uint8_t command;
-	};
-} ata_cmd_t;
-
-typedef union {
-	/* Read */
-	struct {
-		uint8_t pad0[6];
-		uint8_t alt_status;
-		uint8_t drive_address;
-	};
-
-	/* Write */
-	struct {
-		uint8_t pad1[6];
-		uint8_t device_control;
-		uint8_t pad2;
-	};
-} ata_ctl_t;
-
-enum devctl_bits {
-	DCR_SRST	= 0x04, /**< Software Reset */
-	DCR_nIEN	= 0x02  /**< Interrupt Enable (negated) */
-};
-
-enum status_bits {
-	SR_BSY		= 0x80, /**< Busy */
-	SR_DRDY		= 0x40, /**< Drive Ready */
-	SR_DWF		= 0x20, /**< Drive Write Fault */
-	SR_DSC		= 0x10, /**< Drive Seek Complete */
-	SR_DRQ		= 0x08, /**< Data Request */
-	SR_CORR		= 0x04, /**< Corrected Data */
-	SR_IDX		= 0x02, /**< Index */
-	SR_ERR		= 0x01  /**< Error */
-};
-
-enum drive_head_bits {
-	DHR_LBA		= 0x40,	/**< Use LBA addressing mode */
-	DHR_DRV		= 0x10	/**< Select device 1 */
-};
-
-enum error_bits {
-	ER_BBK		= 0x80, /**< Bad Block Detected */
-	ER_UNC		= 0x40, /**< Uncorrectable Data Error */
-	ER_MC		= 0x20, /**< Media Changed */
-	ER_IDNF		= 0x10, /**< ID Not Found */
-	ER_MCR		= 0x08, /**< Media Change Request */
-	ER_ABRT		= 0x04, /**< Aborted Command */
-	ER_TK0NF	= 0x02, /**< Track 0 Not Found */
-	ER_AMNF		= 0x01  /**< Address Mark Not Found */
-};
-
-enum ata_command {
-	CMD_READ_SECTORS	= 0x20,
-	CMD_READ_SECTORS_EXT	= 0x24,
-	CMD_WRITE_SECTORS	= 0x30,
-	CMD_WRITE_SECTORS_EXT	= 0x34,
-	CMD_PACKET		= 0xA0,
-	CMD_IDENTIFY_PKT_DEV	= 0xA1,
-	CMD_IDENTIFY_DRIVE	= 0xEC
-};
-
-/** Data returned from identify device and identify packet device command. */
-typedef struct {
-	uint16_t gen_conf;
-	uint16_t cylinders;
-	uint16_t _res2;
-	uint16_t heads;
-	uint16_t _vs4;
-	uint16_t _vs5;
-	uint16_t sectors;
-	uint16_t _vs7;
-	uint16_t _vs8;
-	uint16_t _vs9;
-
-	uint16_t serial_number[10];
-	uint16_t _vs20;
-	uint16_t _vs21;
-	uint16_t vs_bytes;
-	uint16_t firmware_rev[4];
-	uint16_t model_name[20];
-
-	uint16_t max_rw_multiple;
-	uint16_t _res48;
-	uint16_t caps;		/* Different meaning for packet device */
-	uint16_t _res50;
-	uint16_t pio_timing;
-	uint16_t dma_timing;
-
-	uint16_t validity;
-	uint16_t cur_cyl;
-	uint16_t cur_heads;
-	uint16_t cur_sectors;
-	uint16_t cur_capacity0;
-	uint16_t cur_capacity1;
-	uint16_t mss;
-	uint16_t total_lba28_0;
-	uint16_t total_lba28_1;
-	uint16_t sw_dma;
-	uint16_t mw_dma;
-	uint16_t pio_modes;
-	uint16_t min_mw_dma_cycle;
-	uint16_t rec_mw_dma_cycle;
-	uint16_t min_raw_pio_cycle;
-	uint16_t min_iordy_pio_cycle;
-
-	uint16_t _res69;
-	uint16_t _res70;
-	uint16_t _res71;
-	uint16_t _res72;
-	uint16_t _res73;
-	uint16_t _res74;
-
-	uint16_t queue_depth;
-	uint16_t _res76[1 + 79 - 76];
-	uint16_t version_maj;
-	uint16_t version_min;
-	uint16_t cmd_set0;
-	uint16_t cmd_set1;
-	uint16_t csf_sup_ext;
-	uint16_t csf_enabled0;
-	uint16_t csf_enabled1;
-	uint16_t csf_default;
-	uint16_t udma;
-
-	uint16_t _res89[1 + 99 - 89];
-
-	/* Total number of blocks in LBA-48 addressing */
-	uint16_t total_lba48_0;
-	uint16_t total_lba48_1;
-	uint16_t total_lba48_2;
-	uint16_t total_lba48_3;
-
-	/* Note: more fields are defined in ATA/ATAPI-7 */
-	uint16_t _res104[1 + 127 - 104];
-	uint16_t _vs128[1 + 159 - 128];
-	uint16_t _res160[1 + 255 - 160];
-} identify_data_t;
-
-/** Capability bits for register device. */
-enum ata_regdev_caps {
-	rd_cap_iordy		= 0x0800,
-	rd_cap_iordy_cbd	= 0x0400,
-	rd_cap_lba		= 0x0200,
-	rd_cap_dma		= 0x0100
-};
-
-/** Capability bits for packet device. */
-enum ata_pktdev_caps {
-	pd_cap_ildma		= 0x8000,
-	pd_cap_cmdqueue		= 0x4000,
-	pd_cap_overlap		= 0x2000,
-	pd_cap_need_softreset	= 0x1000,	/* Obsolete (ATAPI-6) */
-	pd_cap_iordy		= 0x0800,
-	pd_cap_iordy_dis	= 0x0400,
-	pd_cap_lba		= 0x0200,	/* Must be on */
-	pd_cap_dma		= 0x0100
-};
-
-/** Bits of @c identify_data_t.cmd_set1 */
-enum ata_cs1 {
-	cs1_addr48	= 0x0400	/**< 48-bit address feature set */
-};
-
-/** ATA packet command codes. */
-enum ata_pkt_command {
-	PCMD_INQUIRY		= 0x12,
-	PCMD_READ_12		= 0xa8,
-	PCMD_READ_TOC		= 0x43
-};
-
-/** ATAPI Inquiry command */
-typedef struct {
-	uint8_t opcode;		/**< Operation code (PCMD_INQUIRY) */
-	uint8_t _res0;
-	uint8_t _res1;
-	uint8_t _res2;
-	uint8_t alloc_len;	/**< Allocation length */
-	uint8_t _res3;
-	uint8_t _res4;
-	uint8_t _res5;
-	uint32_t _res6;
-} __attribute__ ((packed)) ata_pcmd_inquiry_t;
-
-/** ATAPI Read(12) command */
-typedef struct {
-	uint8_t opcode;		/**< Operation code (PCMD_READ_12) */
-	uint8_t _res0;
-	uint32_t ba;		/**< Starting block address */
-	uint32_t nblocks;	/**< Number of blocks to transfer */
-	uint8_t _res1;
-	uint8_t _res2;
-} __attribute__ ((packed)) ata_pcmd_read_12_t;
-
-/** ATAPI Read TOC command */
-typedef struct {
-	uint8_t opcode;		/**< Operation code (PCMD_READ_TOC) */
-	uint8_t msf;            /**< 0x2 = MSF bit set */
-	uint8_t format;         /**< low 3 bits */
-	uint8_t _res0;
-	uint8_t _res1;
-	uint8_t _res2;
-	uint8_t start;          /**< starting track/session number */
-	uint16_t size;		/**< Allocation length */
-	uint8_t oldformat;         /**< high 2 bits */
-	uint8_t _res3;
-	uint8_t _res4;
-} __attribute__ ((packed)) ata_pcmd_read_toc_t;
-
-/** Data returned from Inquiry command (mandatory part) */
-typedef struct {
-	uint8_t pdev_type;	/** Reserved, Peripheral device type */
-	uint8_t rmb;		/** RMB, Reserved */
-	uint8_t std_version;	/** ISO version, ECMA version, ANSI version */
-	uint8_t atapi_ver_rdf;	/** ATAPI version, Response data format */
-	uint8_t additional_len;	/** Additional length */
-	uint8_t _res0;
-	uint8_t _res1;
-	uint8_t _res2;
-	uint8_t vendor_id[8];	/** Vendor ID */
-	uint8_t product_id[8];	/** Product ID */
-	uint8_t product_rev[4];	/** Product revision level */
-} ata_inquiry_data_t;
-
-/** Extract value of ata_inquiry_data_t.pdev_type */
-#define INQUIRY_PDEV_TYPE(val) ((val) & 0x1f)
-
-/** Values for ata_inquiry_data_t.pdev_type */
-enum ata_pdev_type {
-	PDEV_TYPE_CDROM		= 0x05
-};
-
-enum ata_pdev_signature {
-	/**
-	 * Signature put by a packet device in byte count register
-	 * in response to Identify command.
-	 */
-	PDEV_SIGNATURE_BC	= 0xEB14
-};
-
-#endif
-
-/** @}
- */
