Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision 730dce77253b6e2ff27c35fa1c5ddc07e8cfe838)
+++ uspace/drv/block/ahci/ahci.c	(revision ae3ff9f5b199ff6a59b7eaaee63a16372db21e69)
@@ -49,5 +49,9 @@
 #define NAME  "ahci"
 
-#define AHCI_TIMER_TICKS  1000000000
+/** Number of ticks for watchdog timer. */
+#define AHCI_TIMER_TICKS  800000
+
+/** Number of ticks for timer based interrupt. */
+#define AHCI_TIMER_NO_INTR_TICKS  8000
 
 #define LO(ptr) \
@@ -70,10 +74,10 @@
 static void ahci_sata_devices_create(ahci_dev_t *, ddf_dev_t *);
 static ahci_dev_t *ahci_ahci_create(ddf_dev_t *);
-static void ahci_ahci_init(ahci_dev_t *);
+static void ahci_ahci_hw_start(ahci_dev_t *);
 
 static int ahci_dev_add(ddf_dev_t *);
 
 static void ahci_get_model_name(uint16_t *, char *);
-static int ahci_pciintel_enable_interrupt(int);
+static int ahci_enable_interrupt(int);
 
 static fibril_mutex_t sata_devices_count_lock;
@@ -105,4 +109,13 @@
 };
 
+/** Get SATA device name.
+ *
+ * @param fun                  Device function handling the call.
+ * @param sata_dev_name_length Length of the sata_dev_name buffer.
+ * @param sata_dev_name        Buffer for SATA device name.
+ *
+ * @return EOK.
+ *
+ */
 static int ahci_get_sata_device_name(ddf_fun_t *fun,
     size_t sata_dev_name_length, char *sata_dev_name)
@@ -113,4 +126,12 @@
 }
 
+/** Get Number of blocks in SATA device.
+ *
+ * @param fun    Device function handling the call.
+ * @param blocks Return number of blocks in SATA device.
+ *
+ * @return EOK.
+ *
+ */
 static int ahci_get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks)
 {
@@ -120,4 +141,12 @@
 }
 
+/** Get SATA device block size.
+ *
+ * @param fun        Device function handling the call.
+ * @param block_size Return block size.
+ *
+ * @return EOK.
+ *
+ */
 static int ahci_get_block_size(ddf_fun_t *fun, size_t *block_size)
 {
@@ -127,15 +156,28 @@
 }
 
+/** Read data blocks into SATA device.
+ *
+ * @param fun      Device function handling the call.
+ * @param blocknum Number of first block.
+ * @param count    Number of blocks to read.
+ * @param buf      Buffer for data.
+ *
+ * @return EOK if succeed, error code otherwise
+ *
+ */
 static int ahci_read_blocks(ddf_fun_t *fun, uint64_t blocknum,
     size_t count, void *buf)
 {
-	int rc = EOK;
 	sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
 	
 	void *phys;
 	void *ibuf;
-	
-	dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
+	int rc = dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
 	    0, &phys, (void **) &ibuf);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Cannot allocate read buffer.");
+		return rc;
+	}
+	
 	bzero(buf, sata->block_size);
 	
@@ -157,15 +199,27 @@
 }
 
+/** Write data blocks into SATA device.
+ *
+ * @param fun      Device function handling the call.
+ * @param blocknum Number of first block.
+ * @param count    Number of blocks to write.
+ * @param buf      Buffer with data.
+ *
+ * @return EOK if succeed, error code otherwise
+ *
+ */
 static int ahci_write_blocks(ddf_fun_t *fun, uint64_t blocknum,
     size_t count, void *buf)
 {
-	int rc = EOK;
 	sata_dev_t *sata = (sata_dev_t *) fun->driver_data;
 	
 	void *phys;
 	void *ibuf;
-	
-	dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
+	int rc = dmamem_map_anonymous(sata->block_size, AS_AREA_READ | AS_AREA_WRITE,
 	    0, &phys, (void **) &ibuf);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Cannot allocate write buffer.");
+		return rc;
+	}
 	
 	fibril_mutex_lock(&sata->lock);
@@ -181,4 +235,5 @@
 	fibril_mutex_unlock(&sata->lock);
 	dmamem_unmap_anonymous(ibuf);
+	
 	return rc;
 }
@@ -188,11 +243,45 @@
 /*----------------------------------------------------------------------------*/
 
+/** Get and clear AHCI port interrupt state register.
+ *
+ * @param sata SATA device structure.
+ *
+ * @return Value of interrupt state register.
+ *
+ */
+static ahci_port_is_t ahci_get_and_clear_pxis(sata_dev_t *sata)
+{
+	ahci_port_is_t pxis;
+	
+	fibril_mutex_lock(&sata->pxis_lock);
+	
+	pxis.u32 = sata->ahci->memregs->ports[sata->port_num].pxis;
+	sata->ahci->memregs->ports[sata->port_num].pxis = pxis.u32;
+	
+	if (ahci_port_is_permanent_error(pxis))
+		sata->is_invalid_device = true;
+	
+	fibril_mutex_unlock(&sata->pxis_lock);
+	
+	return pxis;
+}
+
+/** Set AHCI registers for identifying SATA device.
+ *
+ * @param sata SATA device structure.
+ * @param phys Physical address of working buffer.
+ *
+ */
 static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys)
 {
-	volatile std_command_frame_t *cmd =
-	    (std_command_frame_t *) sata->cmd_table;
-	
-	cmd->fis_type = 0x27;
-	cmd->c = 0x80;
+	/* Clear interrupt state registers */
+	ahci_get_and_clear_pxis(sata);
+	sata->shadow_pxis.u32 = 0;
+	
+	volatile sata_std_command_frame_t *cmd =
+	    (sata_std_command_frame_t *) sata->cmd_table;
+	
+	cmd->fis_type = SATA_CMD_FIS_TYPE;
+	cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
 	cmd->command = 0xec;
 	cmd->features = 0;
@@ -212,23 +301,36 @@
 	prdt->data_address_upper = HI(phys);
 	prdt->reserved1 = 0;
-	prdt->dbc = 511;
+	prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH - 1;
 	prdt->reserved2 = 0;
 	prdt->ioc = 0;
 	
 	sata->cmd_header->prdtl = 1;
-	sata->cmd_header->flags = 0x402;
+	sata->cmd_header->flags =
+	    AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
+	    AHCI_CMDHDR_FLAGS_2DWCMD; 
 	sata->cmd_header->bytesprocessed = 0;
 	
+	/* Run command. */
 	sata->port->pxsact |= 1;
 	sata->port->pxci |= 1;
 }
 
+/** Set AHCI registers for identifying packet SATA device.
+ *
+ * @param sata SATA device structure.
+ * @param phys Physical address of working buffer.
+ *
+ */
 static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys)
 {
-	volatile std_command_frame_t *cmd =
-	    (std_command_frame_t *) sata->cmd_table;
-	
-	cmd->fis_type = 0x27;
-	cmd->c = 0x80;
+	/* Clear interrupt state registers */
+	ahci_get_and_clear_pxis(sata);
+	sata->shadow_pxis.u32 = 0;
+	
+	volatile sata_std_command_frame_t * cmd =
+	    (sata_std_command_frame_t *) sata->cmd_table;
+	
+	cmd->fis_type = SATA_CMD_FIS_TYPE;
+	cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
 	cmd->command = 0xa1;
 	cmd->features = 0;
@@ -248,19 +350,29 @@
 	prdt->data_address_upper = HI(phys);
 	prdt->reserved1 = 0;
-	prdt->dbc = 511;
+	prdt->dbc = SATA_IDENTIFY_DEVICE_BUFFER_LENGTH - 1;
 	prdt->reserved2 = 0;
 	prdt->ioc = 0;
 	
 	sata->cmd_header->prdtl = 1;
-	sata->cmd_header->flags = 0x402;
+	sata->cmd_header->flags = 
+	    AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
+	    AHCI_CMDHDR_FLAGS_2DWCMD;
 	sata->cmd_header->bytesprocessed = 0;
 	
+	/* Run command. */
 	sata->port->pxsact |= 1;
 	sata->port->pxci |= 1;
 }
 
+/** Fill device identification in SATA device structure.
+ *
+ * @param sata SATA device structure.
+ *
+ * @return EOK if succeed, error code otherwise.
+ *
+ */
 static int ahci_identify_device(sata_dev_t *sata)
 {
-	if (sata->invalid_device) {
+	if (sata->is_invalid_device) {
 		ddf_msg(LVL_ERROR,
 		    "Identify command device on invalid device");
@@ -269,6 +381,5 @@
 	
 	void *phys;
-	identify_data_t *idata;
-	
+	sata_identify_data_t *idata;
 	dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
 	    (void **) &idata);
@@ -286,5 +397,5 @@
 	sata->shadow_pxis.u32 &= ~pxis.u32;
 	
-	if (sata->invalid_device) {
+	if (sata->is_invalid_device) {
 		ddf_msg(LVL_ERROR,
 		    "Unrecoverable error during ata identify device");
@@ -302,5 +413,5 @@
 		sata->shadow_pxis.u32 &= ~pxis.u32;
 		
-		if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
+		if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
 			ddf_msg(LVL_ERROR,
 			    "Unrecoverable error during ata identify packet device");
@@ -308,7 +419,6 @@
 		}
 		
-		sata->packet_device = true;
-	} else
-		sata->packet_device = false;
+		sata->is_packet_device = true;
+	}
 	
 	ahci_get_model_name(idata->model_name, sata->model);
@@ -318,25 +428,45 @@
 	 * only NCQ FPDMA mode is supported.
 	 */
-	if ((idata->sata_cap & np_cap_ncq) == 0) {
+	if ((idata->sata_cap & sata_np_cap_ncq) == 0) {
 		ddf_msg(LVL_ERROR, "%s: NCQ must be supported", sata->model);
 		goto error;
 	}
 	
-	if (sata->packet_device) {
+	uint16_t logsec = idata->physical_logic_sector_size;
+	if ((logsec & 0xc000) == 0x4000) {
+		/* Length of sector may be larger than 512 B */
+		if (logsec & 0x0100) {
+			/* Size of sector is larger than 512 B */
+			ddf_msg(LVL_ERROR,
+			    "%s: Sector length other than 512 B not supported",
+			    sata->model);
+			goto error; 	
+		}
+		
+		if ((logsec & 0x0200) && ((logsec & 0x000f) != 0)) {
+			/* Physical sectors per logical sector is greather than 1 */
+			ddf_msg(LVL_ERROR,
+			    "%s: Sector length other than 512 B not supported",
+			    sata->model);
+			goto error; 	
+		}
+	}
+	
+	if (sata->is_packet_device) {
 		/*
 		 * Due to QEMU limitation (as of 2012-06-22),
-		 * only NCQ FPDMA mode supported - block size is 512 B,
-		 * not 2048 B!
+		 * only NCQ FPDMA mode supported - block size is
+		 * 512 B, not 2048 B!
 		 */
-		sata->block_size = 512;
+		sata->block_size = SATA_DEFAULT_SECTOR_SIZE;
 		sata->blocks = 0;
 	} else {
-		sata->block_size = 512;
+		sata->block_size = SATA_DEFAULT_SECTOR_SIZE;
 		
-		if ((idata->caps & rd_cap_lba) == 0) {
+		if ((idata->caps & sata_rd_cap_lba) == 0) {
 			ddf_msg(LVL_ERROR, "%s: LBA for NCQ must be supported",
 			    sata->model);
 			goto error;
-		} else if ((idata->cmd_set1 & cs1_addr48) == 0) {
+		} else if ((idata->cmd_set1 & sata_cs1_addr48) == 0) {
 			sata->blocks = (uint32_t) idata->total_lba28_0 |
 			    ((uint32_t) idata->total_lba28_1 << 16);
@@ -351,4 +481,5 @@
 	
 	uint8_t udma_mask = idata->udma & 0x007f;
+	sata->highest_udma_mode = (uint8_t) -1;
 	if (udma_mask == 0) {
 		ddf_msg(LVL_ERROR,
@@ -375,11 +506,22 @@
 }
 
+/** Set AHCI registers for setting SATA device transfer mode.
+ *
+ * @param sata SATA device structure.
+ * @param phys Physical address of working buffer.
+ * @param mode Required mode.
+ *
+ */
 static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode)
 {
-	volatile std_command_frame_t *cmd =
-	    (std_command_frame_t *) sata->cmd_table;
-	
-	cmd->fis_type = 0x27;
-	cmd->c = 0x80;
+	/* Clear interrupt state registers */
+	ahci_get_and_clear_pxis(sata);
+	sata->shadow_pxis.u32 = 0;
+	
+	volatile sata_std_command_frame_t *cmd =
+	    (sata_std_command_frame_t *) sata->cmd_table;
+	
+	cmd->fis_type = SATA_CMD_FIS_TYPE;
+	cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR; 
 	cmd->command = 0xef;
 	cmd->features = 0x03;
@@ -393,5 +535,5 @@
 	cmd->reserved2 = 0;
 	
-	volatile ahci_cmd_prdt_t* prdt =
+	volatile ahci_cmd_prdt_t *prdt =
 	    (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]);
 	
@@ -399,19 +541,29 @@
 	prdt->data_address_upper = HI(phys);
 	prdt->reserved1 = 0;
-	prdt->dbc = 511;
+	prdt->dbc = SATA_SET_FEATURE_BUFFER_LENGTH - 1;
 	prdt->reserved2 = 0;
 	prdt->ioc = 0;
 	
 	sata->cmd_header->prdtl = 1;
-	sata->cmd_header->flags = 0x402;
+	sata->cmd_header->flags =
+	    AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
+	    AHCI_CMDHDR_FLAGS_2DWCMD;
 	sata->cmd_header->bytesprocessed = 0;
 	
+	/* Run command. */
 	sata->port->pxsact |= 1;
 	sata->port->pxci |= 1;
 }
 
+/** Set highest ultra DMA mode supported by SATA device.
+ *
+ * @param sata SATA device structure.
+ *
+ * @return EOK if succeed, error code otherwise
+ *
+ */
 static int ahci_set_highest_ultra_dma_mode(sata_dev_t *sata)
 {
-	if (sata->invalid_device) {
+	if (sata->is_invalid_device) {
 		ddf_msg(LVL_ERROR,
 		    "%s: Setting highest UDMA mode on invalid device",
@@ -420,10 +572,26 @@
 	}
 	
+	if (sata->highest_udma_mode == (uint8_t) -1) {
+		ddf_msg(LVL_ERROR,
+		    "%s: No AHCI UDMA support.", sata->model);
+		return EINTR;
+	}
+	
+	if (sata->highest_udma_mode > 6) {
+		ddf_msg(LVL_ERROR,
+		    "%s: Unknown AHCI UDMA mode.", sata->model);
+		return EINTR;
+	}
+	
 	void *phys;
-	identify_data_t *idata;
-	
-	dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
-	    (void **) &idata);
-	bzero(idata, 512);
+	sata_identify_data_t *idata;
+	int rc = dmamem_map_anonymous(SATA_SET_FEATURE_BUFFER_LENGTH,
+	    AS_AREA_READ | AS_AREA_WRITE, 0, &phys, (void **) &idata);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Cannot allocate buffer for device set mode.");
+		return rc;
+	}
+	
+	bzero(idata, SATA_SET_FEATURE_BUFFER_LENGTH);
 	
 	fibril_mutex_lock(&sata->lock);
@@ -439,5 +607,5 @@
 	sata->shadow_pxis.u32 &= ~pxis.u32;
 	
-	if (sata->invalid_device) {
+	if (sata->is_invalid_device) {
 		ddf_msg(LVL_ERROR,
 		    "%s: Unrecoverable error during set highest UDMA mode",
@@ -464,11 +632,22 @@
 }
 
+/** Set AHCI registers for reading one sector from the SATA device using FPDMA.
+ *
+ * @param sata     SATA device structure.
+ * @param phys     Physical address of buffer for sector data.
+ * @param blocknum Block number to read.
+ *
+ */
 static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
 {
-	volatile ncq_command_frame_t *cmd =
-	    (ncq_command_frame_t *) sata->cmd_table;
-	
-	cmd->fis_type = 0x27;
-	cmd->c = 0x80;
+	/* Clear interrupt state registers */
+	ahci_get_and_clear_pxis(sata);
+	sata->shadow_pxis.u32 = 0;
+	
+	volatile sata_ncq_command_frame_t *cmd =
+	    (sata_ncq_command_frame_t *) sata->cmd_table;
+	
+	cmd->fis_type = SATA_CMD_FIS_TYPE;
+	cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
 	cmd->command = 0x60;
 	cmd->tag = 0;
@@ -503,5 +682,7 @@
 	
 	sata->cmd_header->prdtl = 1;
-	sata->cmd_header->flags = 0x405;
+	sata->cmd_header->flags =
+	    AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
+	    AHCI_CMDHDR_FLAGS_5DWCMD;
 	sata->cmd_header->bytesprocessed = 0;
 	
@@ -510,7 +691,16 @@
 }
 
+/** Read one sector from the SATA device using FPDMA.
+ *
+ * @param sata     SATA device structure.
+ * @param phys     Physical address of buffer for sector data.
+ * @param blocknum Block number to read.
+ *
+ * @return EOK if succeed, error code otherwise
+ *
+ */
 static int ahci_rb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum)
 {
-	if (sata->invalid_device) {
+	if (sata->is_invalid_device) {
 		ddf_msg(LVL_ERROR,
 		    "%s: FPDMA read from invalid device", sata->model);
@@ -527,5 +717,5 @@
 	sata->shadow_pxis.u32 &= ~pxis.u32;
 	
-	if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
+	if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
 		ddf_msg(LVL_ERROR,
 		    "%s: Unrecoverable error during FPDMA read", sata->model);
@@ -536,11 +726,24 @@
 }
 
+/** Set AHCI registers for writing one sector to the SATA device, use FPDMA.
+ *
+ * @param sata     SATA device structure.
+ * @param phys     Physical address of buffer with sector data.
+ * @param blocknum Block number to write.
+ *
+ * @return EOK if succeed, error code otherwise
+ *
+ */
 static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
 {
-	volatile ncq_command_frame_t *cmd =
-	    (ncq_command_frame_t *) sata->cmd_table;
-	
-	cmd->fis_type = 0x27;
-	cmd->c = 0x80;
+	/* Clear interrupt state registers */
+	ahci_get_and_clear_pxis(sata);
+	sata->shadow_pxis.u32 = 0;
+	
+	volatile sata_ncq_command_frame_t * cmd =
+	    (sata_ncq_command_frame_t *) sata->cmd_table;
+	
+	cmd->fis_type = SATA_CMD_FIS_TYPE;
+	cmd->c = SATA_CMD_FIS_COMMAND_INDICATOR;
 	cmd->command = 0x61;
 	cmd->tag = 0;
@@ -575,5 +778,8 @@
 	
 	sata->cmd_header->prdtl = 1;
-	sata->cmd_header->flags = 0x445;
+	sata->cmd_header->flags =
+	    AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
+	    AHCI_CMDHDR_FLAGS_WRITE |
+	    AHCI_CMDHDR_FLAGS_5DWCMD;
 	sata->cmd_header->bytesprocessed = 0;
 	
@@ -582,7 +788,16 @@
 }
 
+/** Write one sector into the SATA device, use FPDMA.
+ *
+ * @param sata     SATA device structure.
+ * @param phys     Physical addres of buffer with sector data.
+ * @param blocknum Block number to write.
+ *
+ * @return EOK if succeed, error code otherwise
+ *
+ */
 static int ahci_wb_fpdma(sata_dev_t *sata, void *phys, uint64_t blocknum)
 {
-	if (sata->invalid_device) {
+	if (sata->is_invalid_device) {
 		ddf_msg(LVL_ERROR,
 		    "%s: FPDMA write to invalid device", sata->model);
@@ -599,5 +814,5 @@
 	sata->shadow_pxis.u32 &= ~pxis.u32;
 	
-	if ((sata->invalid_device) || (ahci_port_is_error(pxis))) {
+	if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
 		ddf_msg(LVL_ERROR,
 		    "%s: Unrecoverable error during FPDMA write", sata->model);
@@ -658,21 +873,18 @@
 	is.u32 = ahci->memregs->ghc.is;
 	ahci->memregs->ghc.is = is.u32;
-	is.u32 = ahci->memregs->ghc.is;
+	
+	if (!is_timer)
+		ahci->is_hw_interrupt = true;
+	else if (is.u32)
+		ahci->is_hw_interrupt = false;
 	
 	uint32_t port_event_flags = 0;
 	uint32_t port_mask = 1;
 	for (unsigned int i = 0; i < 32; i++) {
-		/*
-		 * Get current value of hardware port interrupt state register,
-		 * clear hardware register (write to clear behavior).
-		 */
-		ahci_port_is_t pxis;
-		
-		pxis.u32 = ahci->memregs->ports[i].pxis;
-		ahci->memregs->ports[i].pxis = pxis.u32;
-		
 		sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i];
 		if (sata != NULL) {
-			/* add value to shadow copy of port interrupt state register. */
+			ahci_port_is_t pxis = ahci_get_and_clear_pxis(sata);
+			
+			/* Add value to shadow copy of port interrupt state register. */
 			sata->shadow_pxis.u32 |= pxis.u32;
 			
@@ -681,7 +893,4 @@
 			    (ahci_port_is_error(pxis)))
 				port_event_flags |= port_mask;
-			
-			if (ahci_port_is_permanent_error(pxis))
-				sata->invalid_device = true;
 		}
 		
@@ -704,5 +913,5 @@
 /** AHCI timer interrupt handler.
  *
- * @param arg Pointer to AHCI device.
+ * @param arg AHCI device.
  *
  */
@@ -712,10 +921,17 @@
 	
 	ahci_interrupt_or_timer(ahci, 1);
-	fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
+	
+	if (ahci->is_hw_interrupt)
+		fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
+	else
+		fibril_timer_set(ahci->timer, AHCI_TIMER_NO_INTR_TICKS,
+		    ahci_timer, ahci);
 }
 
 /** AHCI interrupt handler.
  *
- * @param dev Pointer to device driver handler.
+ * @param dev   DDF device structure.
+ * @param iid   The IPC call id.
+ * @param icall The IPC call structure.
  *
  */
@@ -727,5 +943,5 @@
 	
 	/* Enable interrupt. */
-	ahci->memregs->ghc.ghc |= 2;
+	ahci->memregs->ghc.ghc |= AHCI_GHC_GHC_IE;
 }
 
@@ -734,5 +950,12 @@
 /*----------------------------------------------------------------------------*/
 
-static sata_dev_t *ahci_sata_device_allocate(volatile ahci_port_t *port)
+/** Allocate SATA device structure with buffers for hardware.
+ * 
+ * @param port AHCI port structure
+ *
+ * @return SATA device structure if succeed, NULL otherwise.
+ *
+ */
+static sata_dev_t *ahci_sata_allocate(volatile ahci_port_t *port)
 {
 	size_t size = 4096;
@@ -763,5 +986,4 @@
 	rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0,
 	    &phys, &virt_cmd);
-	
 	if (rc != EOK)
 		goto error_cmd;
@@ -775,5 +997,4 @@
 	rc = dmamem_map_anonymous(size, AS_AREA_READ | AS_AREA_WRITE, 0,
 	    &phys, &virt_table);
-	
 	if (rc != EOK)
 		goto error_table;
@@ -793,17 +1014,58 @@
 	free(sata);
 	return NULL;
-	
-	/*
-	 * Deleting of pointers in memory hardware mapped register
-	 * unneccessary, hardware port is not in operational state.
-	 */
-}
-
-static int ahci_sata_device_create(ahci_dev_t *ahci, ddf_dev_t *dev,
+}
+
+/** Initialize and start SATA hardware device.
+ *
+ * @param sata SATA device structure.
+ *
+ */
+static void ahci_sata_hw_start(sata_dev_t *sata)
+{
+	ahci_port_cmd_t pxcmd;
+	
+	pxcmd.u32 = sata->port->pxcmd;
+	
+	/* Frame receiver disabled. */
+	pxcmd.fre = 0;
+	
+	/* Disable process the command list. */
+	pxcmd.st = 0;
+	
+	sata->port->pxcmd = pxcmd.u32;
+	
+	/* Clear interrupt status. */
+	sata->port->pxis = 0xffffffff;
+	
+	/* Clear error status. */
+	sata->port->pxserr = 0xffffffff;
+	
+	/* Enable all interrupts. */
+	sata->port->pxie = 0xffffffff;
+	
+	/* Frame receiver enabled. */
+	pxcmd.fre = 1;
+	
+	/* Enable process the command list. */
+	pxcmd.st = 1;
+	
+	sata->port->pxcmd = pxcmd.u32;
+}
+
+/** Create and initialize connected SATA structure device
+ * 
+ * @param ahci     AHCI device structure.
+ * @param dev      DDF device structure.
+ * @param port     AHCI port structure.
+ * @param port_num Number of AHCI port with existing SATA device.
+ *
+ * @return EOK if succeed, error code otherwise.
+ *
+ */
+static int ahci_sata_create(ahci_dev_t *ahci, ddf_dev_t *dev,
     volatile ahci_port_t *port, unsigned int port_num)
 {
 	ddf_fun_t *fun = NULL;
-	sata_dev_t *sata = ahci_sata_device_allocate(port);
-	
+	sata_dev_t *sata = ahci_sata_allocate(port);
 	if (sata == NULL)
 		return EINTR;
@@ -814,24 +1076,23 @@
 	ahci->sata_devs[port_num] = sata;
 	
+	/* Initialize synchronization structures */
 	fibril_mutex_initialize(&sata->lock);
+	fibril_mutex_initialize(&sata->pxis_lock);
 	fibril_mutex_initialize(&sata->event_lock);
 	fibril_condvar_initialize(&sata->event_condvar);
-	
-	/* Initialize SATA port operational registers. */
-	sata->port->pxis = 0;
-	sata->port->pxie = 0xffffffff;
-	sata->port->pxserr = 0;
-	sata->port->pxcmd |= 0x10;
-	sata->port->pxcmd |= 0x01;
-	
+
+	ahci_sata_hw_start(sata);
+
+	/* Identify device. */
 	if (ahci_identify_device(sata) != EOK)
 		goto error;
 	
+	/* Set required UDMA mode */
 	if (ahci_set_highest_ultra_dma_mode(sata) != EOK)
 		goto error;
 	
-	/* Add sata device to system. */
-	char sata_dev_name[1024];
-	snprintf(sata_dev_name, 1024, "ahci_%u", sata_devices_count);
+	/* Add device to the system */
+	char sata_dev_name[16];
+	snprintf(sata_dev_name, 16, "ahci_%u", sata_devices_count);
 	
 	fibril_mutex_lock(&sata_devices_count_lock);
@@ -856,5 +1117,5 @@
 	
 error:
-	sata->invalid_device = true;
+	sata->is_invalid_device = true;
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
@@ -863,7 +1124,13 @@
 }
 
+/** Create and initialize all SATA structure devices for connected SATA drives.
+ *
+ * @param ahci AHCI device structure.
+ * @param dev  DDF device structure.
+ *
+ */
 static void ahci_sata_devices_create(ahci_dev_t *ahci, ddf_dev_t *dev)
 {
-	for (unsigned int port_num = 0; port_num < 32; port_num++) {
+	for (unsigned int port_num = 0; port_num < AHCI_MAX_PORTS; port_num++) {
 		/* Active ports only */
 		if (!(ahci->memregs->ghc.pi & (1 << port_num)))
@@ -873,11 +1140,20 @@
 		
 		/* Active devices only */
-		if ((port->pxssts & 0x0f) != 3)
+		ahci_port_ssts_t pxssts;
+		pxssts.u32 = port->pxssts;
+		if (pxssts.det != AHCI_PORT_SSTS_DET_ACTIVE)
 			continue;
 		
-		ahci_sata_device_create(ahci, dev, port, port_num);
-	}
-}
-
+		ahci_sata_create(ahci, dev, port, port_num);
+	}
+}
+
+/** Create AHCI device structure, intialize it and register interrupt routine.
+ *  
+ * @param dev DDF device structure.
+ *
+ * @return AHCI device structure if succeed, NULL otherwise.
+ *
+ */
 static ahci_dev_t *ahci_ahci_create(ddf_dev_t *dev)
 {
@@ -889,4 +1165,9 @@
 	
 	ahci->dev = dev;
+
+	/* Create timer for AHCI. */
+	ahci->timer = fibril_timer_create();
+	if (ahci->timer == NULL)
+		goto error_create_timer;
 	
 	hw_res_list_parsed_t hw_res_parsed;
@@ -895,17 +1176,29 @@
 		goto error_get_res_parsed;
 	
+	/* Map AHCI registers. */
+	ahci->memregs = NULL;
+	
+	physmem_map((void *) (size_t) (hw_res_parsed.mem_ranges.ranges[0].address),
+	    AHCI_MEMREGS_PAGES_COUNT, AS_AREA_READ | AS_AREA_WRITE,
+	    (void **) &ahci->memregs);
+	if (ahci->memregs == NULL)
+		goto error_map_registers;
+	
 	/* Register interrupt handler */
 	ahci_ranges[0].base = (size_t) hw_res_parsed.mem_ranges.ranges[0].address;
 	ahci_ranges[0].size = sizeof(ahci_dev_t);
+	
 	ahci_cmds[0].addr =
-	    ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 1;
+	    ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) +
+	    AHCI_GHC_GHC_REGISTER_OFFSET;
 	ahci_cmds[1].addr =
-	    ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) + 2;
+	    ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) +
+	    AHCI_GHC_IS_REGISTER_OFFSET;
 	ahci_cmds[2].addr = ahci_cmds[1].addr;
 	
 	irq_code_t ct;
-	ct.cmdcount = 3;
+	ct.cmdcount = sizeof(ahci_cmds) / sizeof(irq_cmd_t);
 	ct.cmds = ahci_cmds;
-	ct.rangecount = 1;
+	ct.rangecount = sizeof(ahci_ranges) / sizeof(irq_pio_range_t);
 	ct.ranges = ahci_ranges;
 	
@@ -918,32 +1211,48 @@
 	}
 	
-	if (ahci_pciintel_enable_interrupt(hw_res_parsed.irqs.irqs[0]) != EOK) {
+	rc = ahci_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
+	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enable interupt.");
 		goto error_enable_interrupt;
 	}
 	
-	/* Map AHCI register. */
-	physmem_map((void *) (size_t) (hw_res_parsed.mem_ranges.ranges[0].address),
-	    8, AS_AREA_READ | AS_AREA_WRITE, (void **) &ahci->memregs);
 	hw_res_list_parsed_clean(&hw_res_parsed);
-	
-	if (ahci->memregs == NULL)
-		goto error_map_registers;
-	
-	ahci->timer = fibril_timer_create();
-	
 	return ahci;
 	
+error_enable_interrupt:
+	unregister_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0]);
+	
+error_register_interrupt_handler:
+	// FIXME: unmap physical memory
+	
 error_map_registers:
-error_enable_interrupt:
-error_register_interrupt_handler:
 	hw_res_list_parsed_clean(&hw_res_parsed);
+	
 error_get_res_parsed:
+	fibril_timer_destroy(ahci->timer);
+	
+error_create_timer:
+	free(ahci);
 	return NULL;
 }
 
-static void ahci_ahci_init(ahci_dev_t *ahci)
-{
-	/* Enable interrupt and bus mastering */
+/** Initialize and start AHCI hardware device.
+ *
+ * @param ahci AHCI device.
+ *
+ */
+static void ahci_ahci_hw_start(ahci_dev_t *ahci)
+{
+	/* Disable command completion coalescing feature */
+	ahci_ghc_ccc_ctl_t ccc;
+	
+	ccc.u32 = ahci->memregs->ghc.ccc_ctl;
+	ccc.en = 0;
+	ahci->memregs->ghc.ccc_ctl = ccc.u32;	
+	
+	/* Set master latency timer. */
+	pci_config_space_write_8(ahci->dev->parent_sess, AHCI_PCI_MLT, 32);
+	
+	/* Enable PCI interrupt and bus mastering */
 	ahci_pcireg_cmd_t cmd;
 	
@@ -953,22 +1262,21 @@
 	pci_config_space_write_16(ahci->dev->parent_sess, AHCI_PCI_CMD, cmd.u16);
 	
-	/* Set master latency timer */
-	pci_config_space_write_8(ahci->dev->parent_sess, AHCI_PCI_MLT, 32);
-	
-	/* Disable command completion coalescing feature. */
-	ahci_ghc_ccc_ctl_t ccc;
-	ccc.u32 = ahci->memregs->ghc.ccc_ctl;
-	ccc.en = 0;
-	ahci->memregs->ghc.ccc_ctl = ccc.u32;
-	
 	/* Enable AHCI and interrupt. */
 	ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE; 
-	
-	/* Enable timer. */
-	fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
-}
-
+}
+
+/** AHCI device driver initialization
+ *
+ * Create and initialize all SATA structure devices for connected
+ * SATA drives.
+ *
+ * @param dev DDF device structure.
+ *
+ * @return EOK if succeed, error code otherwise.
+ *
+ */
 static int ahci_dev_add(ddf_dev_t *dev)	
 {
+	/* Connect to parent device */
 	dev->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE,
 	    dev->handle, IPC_FLAG_BLOCKING);
@@ -978,11 +1286,20 @@
 	ahci_dev_t *ahci = ahci_ahci_create(dev);
 	if (ahci == NULL)
-		return EINTR;
+		goto error;
 	
 	dev->driver_data = ahci;
-	ahci_ahci_init(ahci);
+	
+	/* Set timer and AHCI hardware start. */
+	fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
+	ahci_ahci_hw_start(ahci);
+	
+	/* Create device structures for sata devices attached to AHCI. */
 	ahci_sata_devices_create(ahci, dev);
 	
 	return EOK;
+	
+error:
+	async_hangup(dev->parent_sess);
+	return EINTR;
 }
 
@@ -991,4 +1308,13 @@
 /*----------------------------------------------------------------------------*/
 
+/** Convert SATA model name
+ *
+ * Convert SATA model name from machine format returned by
+ * identify device command to human readable form.
+ *
+ * @param src Source buffer with device name in machine format.
+ * @param dst Buffer for human readable string, minimum size is 41 chars.
+ *
+ */
 static void ahci_get_model_name(uint16_t *src, char *dst)
 {
@@ -1018,9 +1344,15 @@
 }
 
-static int ahci_pciintel_enable_interrupt(int irq)
+/** Enable interrupt using SERVICE_IRC.
+ *
+ * @param irq Requested irq number.
+ *
+ * @return EOK if succeed, error code otherwise.
+ *
+ */
+static int ahci_enable_interrupt(int irq)
 {
 	async_sess_t *irc_sess = NULL;
 	irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_IRC, 0, 0);
-	
 	if (!irc_sess)
 		return EINTR;
Index: uspace/drv/block/ahci/ahci.h
===================================================================
--- uspace/drv/block/ahci/ahci.h	(revision 730dce77253b6e2ff27c35fa1c5ddc07e8cfe838)
+++ uspace/drv/block/ahci/ahci.h	(revision ae3ff9f5b199ff6a59b7eaaee63a16372db21e69)
@@ -46,5 +46,5 @@
 	
 	/** Pointer to AHCI memory registers. */
-	ahci_memregs_t *memregs;
+	volatile ahci_memregs_t *memregs;
 	
 	/** AHCI device global timer. */
@@ -53,4 +53,7 @@
 	/** Pointers to sata devices. */
 	void *sata_devs[32];
+	
+	/** Device has harware interrupt. */
+	bool is_hw_interrupt; 
 } ahci_dev_t;
 
@@ -64,13 +67,15 @@
 	
 	/** Port interrupt states shadow registers. */
-	volatile ahci_port_is_t shadow_pxis;
+	ahci_port_is_t shadow_pxis;
 	
 	/** Device in invalid state (disconnected and so on). */
-	volatile bool invalid_device;
+	bool is_invalid_device;
 	
 	/** Pointer to SATA port. */
 	volatile ahci_port_t *port;
+	
 	/** Pointer to command header. */
 	volatile ahci_cmdhdr_t *cmd_header;
+	
 	/** Pointer to command table. */
 	volatile uint32_t *cmd_table;
@@ -78,4 +83,7 @@
 	/** Mutex for single operation on device. */
 	fibril_mutex_t lock;
+	
+	/** Mutex for port interrupt state register manipulation. */
+	fibril_mutex_t pxis_lock;
 	
 	/** Mutex for event signaling condition variable. */
@@ -96,5 +104,5 @@
 	
 	/** Device in invalid state (disconnected and so on). */
-	bool packet_device;
+	bool is_packet_device;
 	
 	/** Highest UDMA mode supported. */
Index: uspace/drv/block/ahci/ahci_hw.h
===================================================================
--- uspace/drv/block/ahci/ahci_hw.h	(revision 730dce77253b6e2ff27c35fa1c5ddc07e8cfe838)
+++ uspace/drv/block/ahci/ahci_hw.h	(revision ae3ff9f5b199ff6a59b7eaaee63a16372db21e69)
@@ -35,4 +35,11 @@
 
 #include <sys/types.h>
+
+/*----------------------------------------------------------------------------*/
+/*-- AHCI standard constants -------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/** AHCI standard 1.3 - maximum ports. */
+#define AHCI_MAX_PORTS  32
 
 /*----------------------------------------------------------------------------*/
@@ -198,7 +205,7 @@
 typedef union {
 	struct {
-		 /** Header layout. */
+		/** Header layout. */
 		unsigned int hl : 7;
-		/** Multi function device. */
+		/** Multi function device flag. */
 		unsigned int mfd : 1;
 	};
@@ -281,6 +288,6 @@
 typedef struct
 {
-	/** Indicates the minimum grant time (in ? microseconds)
-	 * that the device wishes grant asserted.
+	/** Indicates the minimum grant time that the device
+	 * wishes grant asserted.
 	 */
 	uint8_t u8;
@@ -297,4 +304,7 @@
 /*-- AHCI Memory Registers ---------------------------------------------------*/
 /*----------------------------------------------------------------------------*/
+
+/** Number of pages for ahci memory registers. */
+#define AHCI_MEMREGS_PAGES_COUNT  8
 
 /** AHCI Memory register Generic Host Control - HBA Capabilities. */
@@ -364,4 +374,7 @@
 } ahci_ghc_ghc_t;
 
+/** AHCI GHC register offset. */
+#define AHCI_GHC_GHC_REGISTER_OFFSET  1
+
 /** AHCI Enable mask bit. */
 #define AHCI_GHC_GHC_AE  0x80000000
@@ -377,4 +390,7 @@
 	uint32_t u32;
 } ahci_ghc_is_t;
+
+/** AHCI GHC register offset. */
+#define AHCI_GHC_IS_REGISTER_OFFSET  2	
 
 /** AHCI Memory register Ports implemented. */
@@ -427,5 +443,6 @@
 	/** Size of the transmit message buffer area in dwords. */
 	uint16_t sz;
-	/* Offset of the transmit message buffer area in dwords
+	/*
+	 * Offset of the transmit message buffer area in dwords
 	 * from the beginning of ABAR
 	 */
@@ -462,5 +479,5 @@
 		/** Activity LED hardware driven. */
 		unsigned int alhd : 1;
-		/** port multiplier support. */
+		/** Port multiplier support. */
 		unsigned int pm : 1;
 		/** Reserved. */
@@ -509,25 +526,25 @@
 typedef struct
 {
-	/** Host Capabilities. */
+	/** Host Capabilities */
 	uint32_t cap;
-	/** Global Host Control. */
+	/** Global Host Control */
 	uint32_t ghc;
-	/** Interrupt Status. */
+	/** Interrupt Status */
 	uint32_t is;
-	/** Ports Implemented. */
+	/** Ports Implemented */
 	uint32_t pi;
-	/** Version. */
+	/** Version */
 	uint32_t vs;
-	/** Command Completion Coalescing Control. */
+	/** Command Completion Coalescing Control */
 	uint32_t ccc_ctl;
-	/** Command Completion Coalsecing Ports. */
+	/** Command Completion Coalescing Ports */
 	uint32_t ccc_ports;
-	/** Enclosure Management Location. */
+	/** Enclosure Management Location */
 	uint32_t em_loc;
-	/** Enclosure Management Control. */
+	/** Enclosure Management Control */
 	uint32_t em_ctl;
-	/** Host Capabilities Extended. */
+	/** Host Capabilities Extended */
 	uint32_t cap2;
-	/** BIOS/OS Handoff Control and Status. */
+	/** BIOS/OS Handoff Control and Status */
 	uint32_t bohc;
 } ahci_ghc_t;
@@ -817,9 +834,9 @@
 		 * Values:
 		 * 7h - fh Reserved,
-		 * 6h Slumber - This shall cause the HBA to request a transition of the
-		 *    interface to the Slumber state,
+		 * 6h Slumber - This shall cause the HBA to request a transition
+		 * of the interface to the Slumber state,
 		 * 3h - 5h Reserved,
-		 * 2h Partial - This shall cause the HBA to request a transition of the
-		 *    interface to the Partial state,
+		 * 2h Partial - This shall cause the HBA to request a transition
+		 * of the interface to the Partial state,
 		 * 1h Active,
 		 * 0h No-Op / Idle.
@@ -856,5 +873,5 @@
 		/** LBA Mid Register */
 		uint8_t lba_mr;
-		/**  LBA High Register */
+		/** LBA High Register */
 		uint8_t lba_hr;
 	};
@@ -876,4 +893,7 @@
 	uint32_t u32;
 } ahci_port_ssts_t;
+
+/** Device detection active status. */
+#define AHCI_PORT_SSTS_DET_ACTIVE  3
 
 /** AHCI Memory register Port x Serial ATA Control (SCR2: SControl). */
@@ -1010,14 +1030,18 @@
 	ahci_ghc_t ghc;
 	/** Reserved. */
-	uint8_t reserved[52];
+	uint32_t reserved[13]; 
 	/** Reserved for NVMHCI. */
-	uint8_t reservedfornvmhci[64];
+	uint32_t reservedfornvmhci[16];
 	/** Vendor Specific registers. */
-	uint8_t vendorspecificsregs[96];
+	uint32_t vendorspecificsregs[24];
 	/** Ports. */
 	ahci_port_t ports[32];
 } ahci_memregs_t;
 
-/** AHCI Command header entry. */
+/** AHCI Command header entry.
+ *
+ * This structure is not an AHCI register.
+ *
+ */
 typedef volatile struct {
 	/** Flags. */
@@ -1033,5 +1057,21 @@
 } ahci_cmdhdr_t;
 
-/** AHCI Command Physical Region Descriptor entry. */
+/** Clear Busy upon R_OK (C) flag. */
+#define AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK  0x0400
+
+/** Write operation flag. */
+#define AHCI_CMDHDR_FLAGS_WRITE  0x0040
+
+/** 2 DW length command flag. */
+#define AHCI_CMDHDR_FLAGS_2DWCMD  0x0002
+
+/** 5 DW length command flag. */
+#define AHCI_CMDHDR_FLAGS_5DWCMD  0x0005
+
+/** AHCI Command Physical Region Descriptor entry.
+ *
+ * This structure is not an AHCI register.
+ *
+ */
 typedef volatile struct {
 	/** Word aligned 32-bit data base address. */
@@ -1045,5 +1085,5 @@
 	/** Reserved */
 	unsigned int reserved2 : 9;
-	/** Interrupt on completion */
+	/** Set Interrupt on each operation completion */
 	unsigned int ioc : 1;
 } ahci_cmd_prdt_t;
Index: uspace/drv/block/ahci/ahci_sata.h
===================================================================
--- uspace/drv/block/ahci/ahci_sata.h	(revision 730dce77253b6e2ff27c35fa1c5ddc07e8cfe838)
+++ uspace/drv/block/ahci/ahci_sata.h	(revision ae3ff9f5b199ff6a59b7eaaee63a16372db21e69)
@@ -36,9 +36,32 @@
 #include <sys/types.h>
 
+/*----------------------------------------------------------------------------*/
+/*-- SATA Buffer Lengths -----------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/** Default sector size in bytes. */
+#define SATA_DEFAULT_SECTOR_SIZE  512
+
+/** Size for set feature command buffer in bytes. */
+#define SATA_SET_FEATURE_BUFFER_LENGTH  512
+
+/** Size for indentify (packet) device buffer in bytes. */
+#define SATA_IDENTIFY_DEVICE_BUFFER_LENGTH  512
+
+/*----------------------------------------------------------------------------*/
+/*-- SATA Fis Frames ---------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+
+/** Sata FIS Type number. */
+#define SATA_CMD_FIS_TYPE  0x27
+
+/** Sata FIS Type command indicator. */
+#define SATA_CMD_FIS_COMMAND_INDICATOR  0x80
+
 /** Standard Command frame. */
 typedef struct {
-	/** FIS type - always 0x27. */
+	/** FIS type - always SATA_CMD_FIS_TYPE. */
 	unsigned int fis_type : 8;
-	/** Indicate that FIS is a Command - always 0x80. */
+	/** Indicate that FIS is a Command - always SATA_CMD_FIS_COMMAND_INDICATOR. */
 	unsigned int c : 8;
 	/** Command - Identity device - 0xec, Set fetures - 0xef. */
@@ -62,5 +85,5 @@
 	/** Reserved. */
 	unsigned int reserved2 : 32;
-} std_command_frame_t;
+} sata_std_command_frame_t;
 
 /** Command frame for NCQ data operation. */
@@ -68,5 +91,5 @@
 	/** FIS type - always 0x27. */
 	uint8_t fis_type;
-	/** Indicate that FIS is a Command - always 0x80. */
+	/** Indicate that FIS is a Command - always SATA_CMD_FIS_COMMAND_INDICATOR. */
 	uint8_t c;
 	/** Command - FPDMA Read - 0x60, FPDMA Write - 0x61. */
@@ -105,5 +128,9 @@
 	/** Reserved. */
 	uint8_t reserved6;
-} ncq_command_frame_t;
+} sata_ncq_command_frame_t;
+
+/*----------------------------------------------------------------------------*/
+/*-- SATA Identify device ----------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
 
 /** Data returned from identify device and identify packet device command. */
@@ -129,5 +156,5 @@
 	uint16_t max_rw_multiple;
 	uint16_t reserved48;
-	/** Different meaning for packet device. */
+	/* Different meaning for packet device. */
 	uint16_t caps;
 	uint16_t reserved50;
@@ -183,71 +210,73 @@
 	uint16_t total_lba48_3;
 	
+	uint16_t reserved104[1 + 105 - 104];
+	uint16_t physical_logic_sector_size;
 	/* Note: more fields are defined in ATA/ATAPI-7. */
-	uint16_t reserved104[1 + 127 - 104];
-	uint16_t _vs128[1 + 159 - 128];
+	uint16_t reserved107[1 + 127 - 107];
+	uint16_t reserved128[1 + 159 - 128];
 	uint16_t reserved160[1 + 255 - 160];
-} identify_data_t;
+} sata_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
+enum sata_rd_caps {
+	sata_rd_cap_iordy = 0x0800,
+	sata_rd_cap_iordy_cbd = 0x0400,
+	sata_rd_cap_lba = 0x0200,
+	sata_rd_cap_dma = 0x0100
 };
 
 /** Bits of @c identify_data_t.cmd_set1. */
-enum ata_cs1 {
+enum sata_cs1 {
 	/** 48-bit address feature set. */
-	cs1_addr48 = 0x0400
+	sata_cs1_addr48 = 0x0400
 };
 
 /** SATA capatibilities for not packet device - Serial ATA revision 3_1. */
-enum sata_np_cap {
+enum sata_np_caps {
 	/** Supports READ LOG DMA EXT. */
-	np_cap_log_ext = 0x8000,
+	sata_np_cap_log_ext = 0x8000,
 	/** Supports Device Automatic Partial to Slumber transitions. */
-	np_cap_dev_slm = 0x4000,
+	sata_np_cap_dev_slm = 0x4000,
 	/** Supports Host Automatic Partial to Slumber transitions. */
-	np_cap_host_slm = 0x2000,
+	sata_np_cap_host_slm = 0x2000,
 	/** Supports NCQ priority information. */
-	np_cap_ncq_prio = 0x1000,
+	sata_np_cap_ncq_prio = 0x1000,
 	/** Supports Unload while NCQ command outstanding. */
-	np_cap_unload_ncq = 0x0800,
+	sata_np_cap_unload_ncq = 0x0800,
 	/** Supports Phy event counters. */
-	np_cap_phy_ctx = 0x0400,
+	sata_np_cap_phy_ctx = 0x0400,
 	/** Supports recepits of host-initiated interface power management. */
-	np_cap_host_pmngmnt = 0x0200,
+	sata_np_cap_host_pmngmnt = 0x0200,
 	
 	/** Supports NCQ. */
-	np_cap_ncq = 0x0100,
+	sata_np_cap_ncq = 0x0100,
 	
 	/** Supports SATA 3. */
-	np_cap_sata_3 = 0x0008,
+	sata_np_cap_sata_3 = 0x0008,
 	/** Supports SATA 2. */
-	np_cap_sata_2 = 0x0004,
+	sata_np_cap_sata_2 = 0x0004,
 	/** Supports SATA 1. */
-	np_cap_sata_1 = 0x0002
+	sata_np_cap_sata_1 = 0x0002
 };
 
 /** SATA capatibilities for packet device - Serial ATA revision 3_1. */
-enum sata_pt_cap {
+enum sata_pt_caps {
 	/** Supports READ LOG DMA EXT. */
-	pt_cap_log_ext = 0x8000,
+	sata_pt_cap_log_ext = 0x8000,
 	/** Supports Device Automatic Partial to Slumber transitions. */
-	pt_cap_dev_slm = 0x4000,
+	sata_pt_cap_dev_slm = 0x4000,
 	/** Supports Host Automatic Partial to Slumber transitions. */
-	pt_cap_host_slm = 0x2000,
+	sata_pt_cap_host_slm = 0x2000,
 	/** Supports Phy event counters. */
-	pt_cap_phy_ctx = 0x0400,
+	sata_pt_cap_phy_ctx = 0x0400,
 	/** Supports recepits of host-initiated interface power management. */
-	pt_cap_host_pmngmnt = 0x0200,
+	sata_pt_cap_host_pmngmnt = 0x0200,
 	
 	/** Supports SATA 3. */
-	pt_cap_sat_3 = 0x0008,
+	sata_pt_cap_sat_3 = 0x0008,
 	/** Supports SATA 2. */
-	pt_cap_sat_2 = 0x0004,
+	sata_pt_cap_sat_2 = 0x0004,
 	/** Supports SATA 1. */
-	pt_cap_sat_1 = 0x0002
+	sata_pt_cap_sat_1 = 0x0002
 };
 
