Remove extraneous 'order' parameter from qemu_register_reset()

+ Introduce qemu_unregister_reset()

Change-Id: Iad1d6ec9ad534461199dbef5a8ef9a25563b6628
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 4c90148..19378a8 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -257,5 +257,5 @@
             set_kernel_args(info, initrd_size, info->loader_start);
     }
     //info->is_linux = is_linux;
-    qemu_register_reset(main_cpu_reset, 0, env);
+    qemu_register_reset(main_cpu_reset, env);
 }
diff --git a/hw/core/dma.c b/hw/core/dma.c
index 2c38b59..20a53d1 100644
--- a/hw/core/dma.c
+++ b/hw/core/dma.c
@@ -497,7 +497,7 @@
         register_ioport_read (base + ((i + 8) << dshift), 1, 1,
                               read_cont, d);
     }
-    qemu_register_reset(dma_reset, 0, d);
+    qemu_register_reset(dma_reset, d);
     dma_reset(d);
     for (i = 0; i < ARRAY_SIZE (d->regs); ++i) {
         d->regs[i].transfer_handler = dma_phony_handler;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 70a5303..41bf6de 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -90,7 +90,7 @@
     cpu_physical_memory_read(addr, rrd->data, size);
     rrd->addr = addr;
     rrd->size = size;
-    qemu_register_reset(option_rom_reset, 0, rrd);
+    qemu_register_reset(option_rom_reset, rrd);
 }
 
 static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
@@ -919,7 +919,7 @@
             env->cpuid_apic_id = ENV_GET_CPU(env)->cpu_index;
             apic_init(env);
         }
-        qemu_register_reset(main_cpu_reset, 0, env);
+        qemu_register_reset(main_cpu_reset, env);
     }
 #ifndef CONFIG_ANDROID
     vmport_init();
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index 27407f4..bd13d80 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -384,7 +384,7 @@
     vmmouse_init(s->mouse);
 #endif
 #endif
-    qemu_register_reset(kbd_reset, 0, s);
+    qemu_register_reset(kbd_reset, s);
 }
 
 /* Memory mapped interface */
@@ -443,5 +443,5 @@
     vmmouse_init(s->mouse);
 #endif
 #endif
-    qemu_register_reset(kbd_reset, 0, s);
+    qemu_register_reset(kbd_reset, s);
 }
diff --git a/hw/input/ps2.c b/hw/input/ps2.c
index 1bb4373..19e375d 100644
--- a/hw/input/ps2.c
+++ b/hw/input/ps2.c
@@ -534,7 +534,7 @@
     ps2_reset(&s->common);
     vmstate_register(NULL, 0, &vmstate_ps2_kbd, s);
     //qemu_add_kbd_event_handler(ps2_put_keycode, s);
-    qemu_register_reset(ps2_reset, 0, &s->common);
+    qemu_register_reset(ps2_reset, &s->common);
     return s;
 }
 
@@ -567,6 +567,6 @@
     ps2_reset(&s->common);
     vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
     //qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
-    qemu_register_reset(ps2_reset, 0, &s->common);
+    qemu_register_reset(ps2_reset, &s->common);
     return s;
 }
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 76dc3fe..247a05e 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -958,7 +958,7 @@
     s->timer = timer_new(QEMU_CLOCK_VIRTUAL, SCALE_NS, apic_timer, s);
 
     vmstate_register(NULL, s->idx, &vmstate_apic, s);
-    qemu_register_reset(apic_reset, 0, s);
+    qemu_register_reset(apic_reset, s);
 
     local_apics[s->idx] = s;
     return 0;
diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c
index 9023ef8..c9b0a79 100644
--- a/hw/intc/i8259.c
+++ b/hw/intc/i8259.c
@@ -487,7 +487,7 @@
         register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s);
     }
     vmstate_register(NULL, io_addr, &vmstate_i8259, s);
-    qemu_register_reset(pic_reset, 0, s);
+    qemu_register_reset(pic_reset, s);
 }
 
 void pic_info(Monitor *mon)
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 5caecbe..ba48d8e 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -239,7 +239,7 @@
     cpu_register_physical_memory(0xfec00000, 0x1000, io_memory);
 
     vmstate_register(NULL, 0, &vmstate_ioapic, s);
-    qemu_register_reset(ioapic_reset, 0, s);
+    qemu_register_reset(ioapic_reset, s);
 
     return s;
 }
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 21a7bd4..f843f32 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -272,7 +272,7 @@
     fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
 
     vmstate_register(NULL, -1, &vmstate_fw_cfg, s);
-    qemu_register_reset(fw_cfg_reset, 0, s);
+    qemu_register_reset(fw_cfg_reset, s);
     fw_cfg_reset(s);
 
     return s;
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index c396909..def607e 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -345,7 +345,7 @@
         PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic
 
     piix3_reset(d);
-    qemu_register_reset(piix3_reset, 0, d);
+    qemu_register_reset(piix3_reset, d);
     return d->devfn;
 }
 
@@ -369,6 +369,6 @@
 
 
     piix4_reset(d);
-    qemu_register_reset(piix4_reset, 0, d);
+    qemu_register_reset(piix4_reset, d);
     return d->devfn;
 }
diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
index 2bd1ef0..25362a0 100644
--- a/hw/timer/i8254.c
+++ b/hw/timer/i8254.c
@@ -497,7 +497,7 @@
 
     register_savevm(NULL, "i8254", base, 1, pit_save, pit_load, pit);
 
-    qemu_register_reset(pit_reset, 0, pit);
+    qemu_register_reset(pit_reset, pit);
     register_ioport_write(base, 4, 1, pit_ioport_write, pit);
     register_ioport_read(base, 3, 1, pit_ioport_read, pit);
 
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 568a0c3..de7f22a 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -638,7 +638,7 @@
                         rtc_load_td,
                         s);
 #endif
-    qemu_register_reset(rtc_reset, 0, s);
+    qemu_register_reset(rtc_reset, s);
 
     return s;
 }
@@ -761,6 +761,6 @@
                         rtc_load_td,
                         s);
 #endif
-    qemu_register_reset(rtc_reset, 0, s);
+    qemu_register_reset(rtc_reset, s);
     return s;
 }
diff --git a/include/hw/hw.h b/include/hw/hw.h
index 21dc8ba..1bb8dee 100644
--- a/include/hw/hw.h
+++ b/include/hw/hw.h
@@ -41,7 +41,8 @@
 
 typedef void QEMUResetHandler(void *opaque);
 
-void qemu_register_reset(QEMUResetHandler *func, int order, void *opaque);
+void qemu_register_reset(QEMUResetHandler *func, void *opaque);
+void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
 
 /* handler to set the boot_device for a specific type of QEMUMachine */
 /* return 0 if success */
diff --git a/kvm-all.c b/kvm-all.c
index 39463c3..a35d799 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -515,7 +515,7 @@
     if (ret < 0)
         goto err;
 
-    qemu_register_reset(kvm_reset_vcpus, INT_MAX, NULL);
+    qemu_register_reset(kvm_reset_vcpus, NULL);
 
     kvm_state = s;
 
diff --git a/target-i386/hax-all.c b/target-i386/hax-all.c
index 42076ae..ff9b7c6 100644
--- a/target-i386/hax-all.c
+++ b/target-i386/hax-all.c
@@ -385,7 +385,7 @@
     qversion.least_version = hax_lest_version;
     hax_notify_qemu_version(hax->vm->fd, &qversion);
     hax_support = 1;
-    qemu_register_reset( hax_reset_vcpu_state, 0, NULL);
+    qemu_register_reset( hax_reset_vcpu_state, NULL);
 
     return 0;
 error:
diff --git a/vl-android.c b/vl-android.c
index fec2fa8..8c8738a 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -1251,13 +1251,13 @@
 /* reset/shutdown handler */
 
 typedef struct QEMUResetEntry {
+    QTAILQ_ENTRY(QEMUResetEntry) entry;
     QEMUResetHandler *func;
     void *opaque;
-    int order;
-    struct QEMUResetEntry *next;
 } QEMUResetEntry;
 
-static QEMUResetEntry *first_reset_entry;
+static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
+    QTAILQ_HEAD_INITIALIZER(reset_handlers);
 static int reset_requested;
 static int shutdown_requested, shutdown_signal = -1;
 static pid_t shutdown_pid;
@@ -1300,30 +1300,41 @@
     return r;
 }
 
-void qemu_register_reset(QEMUResetHandler *func, int order, void *opaque)
+void qemu_register_reset(QEMUResetHandler *func, void *opaque)
 {
-    QEMUResetEntry **pre, *re;
+    QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry));
 
-    pre = &first_reset_entry;
-    while (*pre != NULL && (*pre)->order >= order) {
-        pre = &(*pre)->next;
-    }
-    re = g_malloc0(sizeof(QEMUResetEntry));
     re->func = func;
     re->opaque = opaque;
-    re->order = order;
-    re->next = NULL;
-    *pre = re;
+    QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
+}
+
+void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
+{
+    QEMUResetEntry *re;
+
+    QTAILQ_FOREACH(re, &reset_handlers, entry) {
+        if (re->func == func && re->opaque == opaque) {
+            QTAILQ_REMOVE(&reset_handlers, re, entry);
+            g_free(re);
+            return;
+        }
+    }
+}
+
+void qemu_devices_reset(void)
+{
+    QEMUResetEntry *re, *nre;
+
+    /* reset all devices */
+    QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
+        re->func(re->opaque);
+    }
 }
 
 void qemu_system_reset(void)
 {
-    QEMUResetEntry *re;
-
-    /* reset all devices */
-    for(re = first_reset_entry; re != NULL; re = re->next) {
-        re->func(re->opaque);
-    }
+    qemu_devices_reset();
 }
 
 void qemu_system_reset_request(void)