diff --git a/vmm/handler.c b/vmm/handler.c
index 5c0b4852cd2c55fe8bb9217b820acdbcda28bbdc..2c52eff14185c335533a647281d3009c7c280e14 100644
--- a/vmm/handler.c
+++ b/vmm/handler.c
@@ -78,29 +78,35 @@ static state_t *state_check(uint64_t addr, uint8_t size, uint32_t value) {
     for (uint32_t i = 0; i < STATE_MACHINE_NUM + 1; i++) {
 
         // - get next state or first state of one of all state machine available -
-        if (i == 0 && current_state == NULL) continue;
+        state_t *state = (i == 0) ? current_state : STATE_ALL_STARTERS[i - 1];
 
-        state_t *next_state = (i == 0) ? current_state : STATE_ALL_STARTERS[i - 1];
+        if (state == NULL) continue;
 
-        // - check the validity of the next state -
-        switch (next_state->op) {
+        // - check the validity of the retrieving state -
+        switch (state->op) {
 
             case OP_WRITE_EQUAL:
 
-                if (next_state->addr == addr && next_state->size == size && next_state->value == value)
-                    return next_state;
+                if (state->addr == addr && state->size == size && state->value == value)
+                    return state;
             break;
 
             case OP_WRITE_STORE:
             case OP_WRITE_STORE_LOOP:
 
-                if (next_state->addr == addr && next_state->size == size && next_state->callback != NULL)
-                    return next_state;
+                if (state->addr == addr && state->size == size && state->callback != NULL)
+                    return state;
             break;
 
-            case OP_EMUL_END:
             case OP_READ_INJECT:
-                // nothing...
+
+                if (state->addr == addr && state->size == size)
+                    return state;
+            break;
+
+            case OP_EMUL_END:
+
+                return state;
             break;
         }
     }
@@ -108,21 +114,28 @@ static state_t *state_check(uint64_t addr, uint8_t size, uint32_t value) {
     return NULL;
 }
 
-static void state_compute(state_t *state, uint32_t value) {
+static void state_compute(state_t *state, uint32_t value, uint8_t *addr) {
 
+    bool go_next = true;
+
+    // - compute actual operation -
+    if (state->callback != NULL)
+        state->callback(&value);
+
+    // - compute general operation that don't need callback -
     switch (state->op) {
 
         case OP_READ_INJECT:
 
-            injecte_data((uint8_t *)&state->addr, state->size, state->value);
-            printf("PMIO guest read: size=%d port=0x%x [value injected by VMM=0x%x]\n", 
+            injecte_data(addr, state->size, state->value);
+            printf("guest read: size=%d port=0x%lx [value injected by VMM=0x%x]\n",
                    state->size * 8, state->addr, state->value);
         break;
 
         case OP_WRITE_STORE_LOOP:
 
             if (flag_stop_loop == false)
-                current_state = state - 1; // cancled next +1
+                go_next = false;
         break;
 
         case OP_EMUL_END:
@@ -132,11 +145,9 @@ static void state_compute(state_t *state, uint32_t value) {
         break;
     }
 
-    if (state->callback != NULL)
-        state->callback(&value);
-
     // - check and compute last operation -
-    current_state = state + 1;
+    if (go_next) current_state = state + 1;
+
     if (current_state->op == OP_EMUL_END) {
 
         if (current_state->callback != NULL)
@@ -173,7 +184,7 @@ static void wrapper_op_ide(uint8_t *shared_buf, uint8_t *mem) {
     hyper_ide_params_t *p_ide = (hyper_ide_params_t *)shared_buf;
     p_ide->data = p_ide->data + (uint64_t)mem;
 
-    op_callback_ide_condlude(p_ide);
+    op_callback_ide_conclude(p_ide);
 }
 
 // --- FUNCTION ---
@@ -212,12 +223,20 @@ void handle_pmio(struct kvm_run *run, ...) {
 
         } else {
 
-            current_state = state_check(run->io.port, run->io.size, value);
+            current_state = state_check(run->io.port, run->io.size, value); // get and check incoming state
 
             if (current_state != NULL)
-                state_compute(current_state, value);
+                state_compute(current_state, value, (uint8_t *)run + run->io.data_offset);
         }
     }
+    else if (run->io.direction == KVM_EXIT_IO_IN) {
+
+        printf("PMIO guest read: \tport=0x%x \tsize=%d\n", run->io.port, run->io.size * 8);
+        current_state = state_check(run->io.port, run->io.size, 0);
+
+        if (current_state != NULL)
+            state_compute(current_state, current_state->value, (uint8_t *)run + run->io.data_offset);
+    }
 
     va_end(args);
 }
@@ -232,7 +251,15 @@ void handle_mmio(struct kvm_run *run, ...) {
         current_state = state_check(run->mmio.phys_addr, run->mmio.len, value);
 
         if (current_state != NULL)
-            state_compute(current_state, value);
+            state_compute(current_state, value, run->mmio.data);
+    }
+    else if (!run->mmio.is_write) {
+
+        printf("MMIO guest read: \taddr=0x%llx \tlen=%d\n", run->mmio.phys_addr, run->mmio.len * 8);
+        current_state = state_check(run->mmio.phys_addr, run->mmio.len, 0);
+
+        if (current_state != NULL)
+            state_compute(current_state, current_state->value, run->mmio.data);
     }
 }