Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision 8486c070d3e8193fcd8774597aa3c3438d3ba2c9)
+++ uspace/drv/block/ahci/ahci.c	(revision eb3683ae371634ed19437ce3910888298507a3e3)
@@ -49,10 +49,4 @@
 #define NAME  "ahci"
 
-/** 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) \
 	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) & 0xffffffff))
@@ -60,4 +54,61 @@
 #define HI(ptr) \
 	((uint32_t) (((uint64_t) ((uintptr_t) (ptr))) >> 32))
+
+/** Interrupt pseudocode for a single port
+ *
+ * The interrupt handling works as follows:
+ *
+ * 1. Port interrupt status register is read
+ *    (stored as arg2).
+ * 2. If port interrupt is indicated, then:
+ *    3. Port interrupt status register is cleared.
+ *    4. Global interrupt status register is read
+ *       and cleared (any potential interrupts from
+ *       other ports are reasserted automatically).
+ *    5. Port number is stored as arg1.
+ *    6. The interrupt is accepted.
+ *
+ */
+#define AHCI_PORT_CMDS(port) \
+	{ \
+		/* Read port interrupt status register */ \
+		.cmd = CMD_PIO_READ_32, \
+		.addr = NULL, \
+		.dstarg = 2 \
+	}, \
+	{ \
+		/* Check if port asserted interrupt */ \
+		.cmd = CMD_PREDICATE, \
+		.value = 5, \
+		.srcarg = 2, \
+	}, \
+	{ \
+		/* Clear port interrupt status register */ \
+		.cmd = CMD_PIO_WRITE_A_32, \
+		.addr = NULL, \
+		.srcarg = 2 \
+	}, \
+	{ \
+		/* Read global interrupt status register */ \
+		.cmd = CMD_PIO_READ_32, \
+		.addr = NULL, \
+		.dstarg = 0 \
+	}, \
+	{ \
+		/* Clear global interrupt status register */ \
+		.cmd = CMD_PIO_WRITE_A_32, \
+		.addr = NULL, \
+		.srcarg = 0 \
+	}, \
+	{ \
+		/* Indicate port interrupt assertion */ \
+		.cmd = CMD_LOAD, \
+		.value = (port), \
+		.dstarg = 1 \
+	}, \
+	{ \
+		/* Accept the interrupt */ \
+		.cmd = CMD_ACCEPT \
+	}
 
 static int ahci_get_sata_device_name(ddf_fun_t *, size_t, char *);
@@ -243,5 +294,5 @@
 /*----------------------------------------------------------------------------*/
 
-/** Get and clear AHCI port interrupt state register.
+/** Wait for interrupt event.
  *
  * @param sata SATA device structure.
@@ -250,17 +301,18 @@
  *
  */
-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;
+static ahci_port_is_t ahci_wait_event(sata_dev_t *sata)
+{
+	fibril_mutex_lock(&sata->event_lock);
+	
+	while (sata->event_pxis == 0)
+		fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
+	
+	ahci_port_is_t pxis = sata->event_pxis;
+	sata->event_pxis = 0;
 	
 	if (ahci_port_is_permanent_error(pxis))
 		sata->is_invalid_device = true;
 	
-	fibril_mutex_unlock(&sata->pxis_lock);
+	fibril_mutex_unlock(&sata->event_lock);
 	
 	return pxis;
@@ -275,8 +327,4 @@
 static void ahci_identify_device_cmd(sata_dev_t *sata, void *phys)
 {
-	/* 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;
@@ -308,5 +356,5 @@
 	sata->cmd_header->flags =
 	    AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
-	    AHCI_CMDHDR_FLAGS_2DWCMD; 
+	    AHCI_CMDHDR_FLAGS_2DWCMD;
 	sata->cmd_header->bytesprocessed = 0;
 	
@@ -324,9 +372,5 @@
 static void ahci_identify_packet_device_cmd(sata_dev_t *sata, void *phys)
 {
-	/* Clear interrupt state registers */
-	ahci_get_and_clear_pxis(sata);
-	sata->shadow_pxis.u32 = 0;
-	
-	volatile sata_std_command_frame_t * cmd =
+	volatile sata_std_command_frame_t *cmd =
 	    (sata_std_command_frame_t *) sata->cmd_table;
 	
@@ -355,5 +399,5 @@
 	
 	sata->cmd_header->prdtl = 1;
-	sata->cmd_header->flags = 
+	sata->cmd_header->flags =
 	    AHCI_CMDHDR_FLAGS_CLEAR_BUSY_UPON_OK |
 	    AHCI_CMDHDR_FLAGS_2DWCMD;
@@ -382,18 +426,17 @@
 	void *phys;
 	sata_identify_data_t *idata;
-	dmamem_map_anonymous(512, AS_AREA_READ | AS_AREA_WRITE, 0, &phys,
-	    (void **) &idata);
-	bzero(idata, 512);
+	int rc = dmamem_map_anonymous(SATA_IDENTIFY_DEVICE_BUFFER_LENGTH,
+	    AS_AREA_READ | AS_AREA_WRITE, 0, &phys, (void **) &idata);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Cannot allocate buffer to identify device.");
+		return rc;
+	}
+	
+	bzero(idata, SATA_IDENTIFY_DEVICE_BUFFER_LENGTH);
 	
 	fibril_mutex_lock(&sata->lock);
 	
 	ahci_identify_device_cmd(sata, phys);
-	
-	fibril_mutex_lock(&sata->event_lock);
-	fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
-	fibril_mutex_unlock(&sata->event_lock);
-	
-	ahci_port_is_t pxis = sata->shadow_pxis;
-	sata->shadow_pxis.u32 &= ~pxis.u32;
+	ahci_port_is_t pxis = ahci_wait_event(sata);
 	
 	if (sata->is_invalid_device) {
@@ -405,11 +448,5 @@
 	if (ahci_port_is_tfes(pxis)) {
 		ahci_identify_packet_device_cmd(sata, phys);
-		
-		fibril_mutex_lock(&sata->event_lock);
-		fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
-		fibril_mutex_unlock(&sata->event_lock);
-		
-		pxis = sata->shadow_pxis;
-		sata->shadow_pxis.u32 &= ~pxis.u32;
+		pxis = ahci_wait_event(sata);
 		
 		if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
@@ -441,5 +478,5 @@
 			    "%s: Sector length other than 512 B not supported",
 			    sata->model);
-			goto error; 	
+			goto error;
 		}
 		
@@ -449,5 +486,5 @@
 			    "%s: Sector length other than 512 B not supported",
 			    sata->model);
-			goto error; 	
+			goto error;
 		}
 	}
@@ -488,5 +525,5 @@
 		goto error;
 	} else {
-		for (unsigned int i = 0; i < 7; i++) {
+		for (uint8_t i = 0; i < 7; i++) {
 			if (udma_mask & (1 << i))
 				sata->highest_udma_mode = i;
@@ -515,8 +552,4 @@
 static void ahci_set_mode_cmd(sata_dev_t *sata, void* phys, uint8_t mode)
 {
-	/* 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;
@@ -599,11 +632,5 @@
 	uint8_t mode = 0x40 | (sata->highest_udma_mode & 0x07);
 	ahci_set_mode_cmd(sata, phys, mode);
-	
-	fibril_mutex_lock(&sata->event_lock);
-	fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
-	fibril_mutex_unlock(&sata->event_lock);
-	
-	ahci_port_is_t pxis = sata->shadow_pxis;
-	sata->shadow_pxis.u32 &= ~pxis.u32;
+	ahci_port_is_t pxis = ahci_wait_event(sata);
 	
 	if (sata->is_invalid_device) {
@@ -641,8 +668,4 @@
 static void ahci_rb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
 {
-	/* 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;
@@ -709,11 +732,5 @@
 	
 	ahci_rb_fpdma_cmd(sata, phys, blocknum);
-	
-	fibril_mutex_lock(&sata->event_lock);
-	fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
-	fibril_mutex_unlock(&sata->event_lock);
-	
-	ahci_port_is_t pxis = sata->shadow_pxis;
-	sata->shadow_pxis.u32 &= ~pxis.u32;
+	ahci_port_is_t pxis = ahci_wait_event(sata);
 	
 	if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
@@ -737,9 +754,5 @@
 static void ahci_wb_fpdma_cmd(sata_dev_t *sata, void *phys, uint64_t blocknum)
 {
-	/* Clear interrupt state registers */
-	ahci_get_and_clear_pxis(sata);
-	sata->shadow_pxis.u32 = 0;
-	
-	volatile sata_ncq_command_frame_t * cmd =
+	volatile sata_ncq_command_frame_t *cmd =
 	    (sata_ncq_command_frame_t *) sata->cmd_table;
 	
@@ -767,5 +780,5 @@
 	cmd->lba5 = (blocknum >> 40) & 0xff;
 	
-	volatile ahci_cmd_prdt_t * prdt =
+	volatile ahci_cmd_prdt_t *prdt =
 	    (ahci_cmd_prdt_t *) (&sata->cmd_table[0x20]);
 	
@@ -806,11 +819,5 @@
 	
 	ahci_wb_fpdma_cmd(sata, phys, blocknum);
-	
-	fibril_mutex_lock(&sata->event_lock);
-	fibril_condvar_wait(&sata->event_condvar, &sata->event_lock);
-	fibril_mutex_unlock(&sata->event_lock);
-	
-	ahci_port_is_t pxis = sata->shadow_pxis;
-	sata->shadow_pxis.u32 &= ~pxis.u32;
+	ahci_port_is_t pxis = ahci_wait_event(sata);
 	
 	if ((sata->is_invalid_device) || (ahci_port_is_error(pxis))) {
@@ -824,5 +831,5 @@
 
 /*----------------------------------------------------------------------------*/
-/*-- Interrupts and timer unified handling -----------------------------------*/
+/*-- Interrupts handling -----------------------------------------------------*/
 /*----------------------------------------------------------------------------*/
 
@@ -830,102 +837,42 @@
 	{
 		.base = 0,
-		.size = 32,
+		.size = 0,
 	}
 };
 
 static irq_cmd_t ahci_cmds[] = {
-	{
-		/* Disable interrupt - interrupt is deasserted in qemu 1.0.1 */
-		.cmd = CMD_PIO_WRITE_32,
-		.addr = NULL,
-		.value = AHCI_GHC_GHC_AE
-	},
-	{
-		.cmd = CMD_PIO_READ_32,
-		.addr = NULL,
-		.dstarg = 1
-	},
-	{
-		/* Clear interrupt status register - for vbox and real hw */
-		.cmd = CMD_PIO_WRITE_A_32,
-		.addr = NULL,
-		.srcarg = 1
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
+	AHCI_PORT_CMDS(0),
+	AHCI_PORT_CMDS(1),
+	AHCI_PORT_CMDS(2),
+	AHCI_PORT_CMDS(3),
+	AHCI_PORT_CMDS(4),
+	AHCI_PORT_CMDS(5),
+	AHCI_PORT_CMDS(6),
+	AHCI_PORT_CMDS(7),
+	AHCI_PORT_CMDS(8),
+	AHCI_PORT_CMDS(9),
+	AHCI_PORT_CMDS(10),
+	AHCI_PORT_CMDS(11),
+	AHCI_PORT_CMDS(12),
+	AHCI_PORT_CMDS(13),
+	AHCI_PORT_CMDS(14),
+	AHCI_PORT_CMDS(15),
+	AHCI_PORT_CMDS(16),
+	AHCI_PORT_CMDS(17),
+	AHCI_PORT_CMDS(18),
+	AHCI_PORT_CMDS(19),
+	AHCI_PORT_CMDS(20),
+	AHCI_PORT_CMDS(21),
+	AHCI_PORT_CMDS(22),
+	AHCI_PORT_CMDS(23),
+	AHCI_PORT_CMDS(24),
+	AHCI_PORT_CMDS(25),
+	AHCI_PORT_CMDS(26),
+	AHCI_PORT_CMDS(27),
+	AHCI_PORT_CMDS(28),
+	AHCI_PORT_CMDS(29),
+	AHCI_PORT_CMDS(30),
+	AHCI_PORT_CMDS(31)
 };
-
-/** Unified AHCI interrupt and timer interrupt handler.
- *
- * @param ahci     AHCI device.
- * @param is_timer Indicate timer interrupt.
- *
- */
-static void ahci_interrupt_or_timer(ahci_dev_t *ahci, bool is_timer)
-{
-	/*
-	 * Get current value of hardware interrupt state register,
-	 * clear hardware register (write to clear behavior).
-	 */
-	ahci_ghc_is_t is;
-	
-	is.u32 = ahci->memregs->ghc.is;
-	ahci->memregs->ghc.is = is.u32;
-	
-	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++) {
-		sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i];
-		if (sata != NULL) {
-			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;
-			
-			/* Evaluate port event. */
-			if ((ahci_port_is_end_of_operation(pxis)) ||
-			    (ahci_port_is_error(pxis)))
-				port_event_flags |= port_mask;
-		}
-		
-		port_mask <<= 1;
-	}
-	
-	port_mask = 1;
-	for (unsigned int i = 0; i < 32; i++) {
-		sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[i];
-		if ((port_event_flags & port_mask) && (sata != NULL)) {
-			fibril_mutex_lock(&sata->event_lock);
-			fibril_condvar_signal(&sata->event_condvar);
-			fibril_mutex_unlock(&sata->event_lock);
-		}
-		
-		port_mask <<= 1;
-	}
-}
-
-/** AHCI timer interrupt handler.
- *
- * @param arg AHCI device.
- *
- */
-static void ahci_timer(void *arg)
-{
-	ahci_dev_t *ahci = (ahci_dev_t *) arg;
-	
-	ahci_interrupt_or_timer(ahci, 1);
-	
-	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.
@@ -939,9 +886,24 @@
 {
 	ahci_dev_t *ahci = (ahci_dev_t *) dev->driver_data;
-	
-	ahci_interrupt_or_timer(ahci, 0);
-	
-	/* Enable interrupt. */
-	ahci->memregs->ghc.ghc |= AHCI_GHC_GHC_IE;
+	unsigned int port = IPC_GET_ARG1(*icall);
+	ahci_port_is_t pxis = IPC_GET_ARG2(*icall);
+	
+	if (port >= AHCI_MAX_PORTS)
+		return;
+	
+	sata_dev_t *sata = (sata_dev_t *) ahci->sata_devs[port];
+	if (sata == NULL)
+		return;
+	
+	/* Evaluate port event */
+	if ((ahci_port_is_end_of_operation(pxis)) ||
+	    (ahci_port_is_error(pxis))) {
+		fibril_mutex_lock(&sata->event_lock);
+		
+		sata->event_pxis = pxis;
+		fibril_condvar_signal(&sata->event_condvar);
+		
+		fibril_mutex_unlock(&sata->event_lock);
+	}
 }
 
@@ -951,5 +913,5 @@
 
 /** Allocate SATA device structure with buffers for hardware.
- * 
+ *
  * @param port AHCI port structure
  *
@@ -960,8 +922,8 @@
 {
 	size_t size = 4096;
-	void* phys = NULL;
-	void* virt_fb = NULL;
-	void* virt_cmd = NULL;
-	void* virt_table = NULL;
+	void *phys = NULL;
+	void *virt_fb = NULL;
+	void *virt_cmd = NULL;
+	void *virt_table = NULL;
 	
 	sata_dev_t *sata = malloc(sizeof(sata_dev_t));
@@ -1054,5 +1016,5 @@
 
 /** Create and initialize connected SATA structure device
- * 
+ *
  * @param ahci     AHCI device structure.
  * @param dev      DDF device structure.
@@ -1078,10 +1040,9 @@
 	/* 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);
-
+	
 	ahci_sata_hw_start(sata);
-
+	
 	/* Identify device. */
 	if (ahci_identify_device(sata) != EOK)
@@ -1150,5 +1111,5 @@
 
 /** Create AHCI device structure, intialize it and register interrupt routine.
- *  
+ *
  * @param dev DDF device structure.
  *
@@ -1165,9 +1126,4 @@
 	
 	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;
@@ -1187,13 +1143,20 @@
 	/* 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) +
-	    AHCI_GHC_GHC_REGISTER_OFFSET;
-	ahci_cmds[1].addr =
-	    ((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;
+	ahci_ranges[0].size = sizeof(ahci_memregs_t);
+	
+	for (unsigned int port = 0; port < AHCI_MAX_PORTS; port++) {
+		size_t base = port * 7;
+		
+		ahci_cmds[base].addr =
+		    ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) +
+		    AHCI_PORTS_REGISTERS_OFFSET + port * AHCI_PORT_REGISTERS_SIZE +
+		    AHCI_PORT_IS_REGISTER_OFFSET;
+		ahci_cmds[base + 2].addr = ahci_cmds[base].addr;
+		
+		ahci_cmds[base + 3].addr =
+		    ((uint32_t *) (size_t) hw_res_parsed.mem_ranges.ranges[0].address) +
+		    AHCI_GHC_IS_REGISTER_OFFSET;
+		ahci_cmds[base + 4].addr = ahci_cmds[base + 3].addr;
+	}
 	
 	irq_code_t ct;
@@ -1205,7 +1168,6 @@
 	int rc = register_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0],
 	    ahci_interrupt, &ct);
-	
 	if (rc != EOK) {
-		ddf_msg(LVL_ERROR, "Failed register_interrupt_handler function.");
+		ddf_msg(LVL_ERROR, "Failed registering interrupt handler.");
 		goto error_register_interrupt_handler;
 	}
@@ -1230,7 +1192,4 @@
 	
 error_get_res_parsed:
-	fibril_timer_destroy(ahci->timer);
-	
-error_create_timer:
 	free(ahci);
 	return NULL;
@@ -1249,5 +1208,5 @@
 	ccc.u32 = ahci->memregs->ghc.ccc_ctl;
 	ccc.en = 0;
-	ahci->memregs->ghc.ccc_ctl = ccc.u32;	
+	ahci->memregs->ghc.ccc_ctl = ccc.u32;
 	
 	/* Set master latency timer. */
@@ -1263,5 +1222,5 @@
 	
 	/* Enable AHCI and interrupt. */
-	ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE; 
+	ahci->memregs->ghc.ghc = AHCI_GHC_GHC_AE | AHCI_GHC_GHC_IE;
 }
 
@@ -1290,6 +1249,5 @@
 	dev->driver_data = ahci;
 	
-	/* Set timer and AHCI hardware start. */
-	fibril_timer_set(ahci->timer, AHCI_TIMER_TICKS, ahci_timer, ahci);
+	/* Start AHCI hardware. */
 	ahci_ahci_hw_start(ahci);
 	
Index: uspace/drv/block/ahci/ahci.h
===================================================================
--- uspace/drv/block/ahci/ahci.h	(revision 8486c070d3e8193fcd8774597aa3c3438d3ba2c9)
+++ uspace/drv/block/ahci/ahci.h	(revision eb3683ae371634ed19437ce3910888298507a3e3)
@@ -48,12 +48,6 @@
 	volatile ahci_memregs_t *memregs;
 	
-	/** AHCI device global timer. */
-	fibril_timer_t *timer;
-	
 	/** Pointers to sata devices. */
-	void *sata_devs[32];
-	
-	/** Device has harware interrupt. */
-	bool is_hw_interrupt; 
+	void *sata_devs[AHCI_MAX_PORTS];
 } ahci_dev_t;
 
@@ -63,9 +57,6 @@
 	ahci_dev_t *ahci;
 	
-	/** SATA port number(0-31). */
+	/** SATA port number (0-31). */
 	uint8_t port_num;
-	
-	/** Port interrupt states shadow registers. */
-	ahci_port_is_t shadow_pxis;
 	
 	/** Device in invalid state (disconnected and so on). */
@@ -84,17 +75,19 @@
 	fibril_mutex_t lock;
 	
-	/** Mutex for port interrupt state register manipulation. */
-	fibril_mutex_t pxis_lock;
-	
 	/** Mutex for event signaling condition variable. */
 	fibril_mutex_t event_lock;
+	
 	/** Event signaling condition variable. */
 	fibril_condvar_t event_condvar;
 	
+	/** Event interrupt state. */
+	ahci_port_is_t event_pxis;
+	
 	/** Block device service id. */
-	service_id_t service_id; 
+	service_id_t service_id;
 	
 	/** Number of device data blocks. */
 	uint64_t blocks;
+	
 	/** Size of device data blocks. */
 	size_t block_size;
Index: uspace/drv/block/ahci/ahci_hw.h
===================================================================
--- uspace/drv/block/ahci/ahci_hw.h	(revision 8486c070d3e8193fcd8774597aa3c3438d3ba2c9)
+++ uspace/drv/block/ahci/ahci_hw.h	(revision eb3683ae371634ed19437ce3910888298507a3e3)
@@ -374,7 +374,4 @@
 } 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
@@ -384,13 +381,17 @@
 
 /** AHCI Memory register Interrupt pending register. */
-typedef struct {
-	/** Interrupt pending status, if set, indicates that
-	 * the corresponding port has an interrupt pending.
-	 */
-	uint32_t u32;
-} ahci_ghc_is_t;
+typedef uint32_t ahci_ghc_is_t;
 
 /** AHCI GHC register offset. */
-#define AHCI_GHC_IS_REGISTER_OFFSET  2	
+#define AHCI_GHC_IS_REGISTER_OFFSET  2
+
+/** AHCI ports registers offset. */
+#define AHCI_PORTS_REGISTERS_OFFSET  64
+
+/** AHCI port registers size. */
+#define AHCI_PORT_REGISTERS_SIZE  32
+
+/** AHCI port IS register offset. */
+#define AHCI_PORT_IS_REGISTER_OFFSET  4
 
 /** AHCI Memory register Ports implemented. */
@@ -531,5 +532,5 @@
 	uint32_t ghc;
 	/** Interrupt Status */
-	uint32_t is;
+	ahci_ghc_is_t is;
 	/** Ports Implemented */
 	uint32_t pi;
@@ -603,47 +604,5 @@
 
 /** AHCI Memory register Port x Interrupt Status. */
-typedef union {
-	struct {
-		/** Device to Host Register FIS Interrupt. */
-		unsigned int dhrs : 1;
-		/** PIO Setup FIS Interrupt. */
-		unsigned int pss : 1;
-		/** DMA Setup FIS Interrupt. */
-		unsigned int dss : 1;
-		/** Set Device Bits Interrupt. */
-		unsigned int sdbs : 1;
-		/** Unknown FIS Interrupt. */
-		unsigned int ufs : 1;
-		/** Descriptor Processed. */
-		unsigned int dps : 1;
-		/** Port Connect Change Status. */
-		unsigned int pcs : 1;
-		/** Device Mechanical Presence Status. */
-		unsigned int dmps : 1;
-		/** Reserved. */
-		unsigned int reserved1 : 14;
-		/** PhyRdy Change Status. */
-		unsigned int prcs : 1;
-		/** Incorrect Port Multiplier Status. */
-		unsigned int ipms : 1;
-		/** Overflow Status. */
-		unsigned int ofs : 1;
-		/** Reserved. */
-		unsigned int reserved2 : 1;
-		/** Interface Non-fatal Error Status. */
-		unsigned int infs : 1;
-		/** Interface Fatal Error Status. */
-		unsigned int ifs : 1;
-		/** Host Bus Data Error Status. */
-		unsigned int hbds : 1;
-		/** Host Bus Fatal Error Status. */
-		unsigned int hbfs : 1;
-		/** Task File Error Status. */
-		unsigned int tfes : 1;
-		/** Cold Port Detect Status. */
-		unsigned int cpds : 1;
-	};
-	uint32_t u32;
-} ahci_port_is_t;
+typedef uint32_t ahci_port_is_t;
 
 #define AHCI_PORT_IS_DHRS  (1 << 0)
@@ -700,5 +659,5 @@
 static inline int ahci_port_is_end_of_operation(ahci_port_is_t port_is)
 {
-	return port_is.u32 & AHCI_PORT_END_OF_OPERATION;
+	return port_is & AHCI_PORT_END_OF_OPERATION;
 }
 
@@ -712,5 +671,5 @@
 static inline int ahci_port_is_error(ahci_port_is_t port_is)
 {
-	return port_is.u32 & AHCI_PORT_IS_ERROR;
+	return port_is & AHCI_PORT_IS_ERROR;
 }
 
@@ -724,5 +683,5 @@
 static inline int ahci_port_is_permanent_error(ahci_port_is_t port_is)
 {
-	return port_is.u32 & AHCI_PORT_IS_PERMANENT_ERROR;
+	return port_is & AHCI_PORT_IS_PERMANENT_ERROR;
 }
 
@@ -736,5 +695,5 @@
 static inline int ahci_port_is_tfes(ahci_port_is_t port_is)
 {
-	return port_is.u32 & AHCI_PORT_IS_TFES;
+	return port_is & AHCI_PORT_IS_TFES;
 }
 
@@ -994,5 +953,5 @@
 	uint32_t pxfbu;
 	/** Port x Interrupt Status. */
-	uint32_t pxis;
+	ahci_port_is_t pxis;
 	/** Port x Interrupt Enable. */
 	uint32_t pxie;
@@ -1030,5 +989,5 @@
 	ahci_ghc_t ghc;
 	/** Reserved. */
-	uint32_t reserved[13]; 
+	uint32_t reserved[13];
 	/** Reserved for NVMHCI. */
 	uint32_t reservedfornvmhci[16];
@@ -1036,5 +995,5 @@
 	uint32_t vendorspecificsregs[24];
 	/** Ports. */
-	ahci_port_t ports[32];
+	ahci_port_t ports[AHCI_MAX_PORTS];
 } ahci_memregs_t;
 
