Add "cache" parameter to "-drive" (Laurent Vivier).
[qemu] / vl.c
diff --git a/vl.c b/vl.c
index a4592f7..14cf4d1 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -109,7 +109,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
 #ifdef _WIN32
 #include <malloc.h>
 #include <sys/timeb.h>
-#include <windows.h>
+#include <mmsystem.h>
 #define getopt_long_only getopt_long
 #define memalign(align, size) malloc(size)
 #endif
@@ -822,6 +822,7 @@ struct qemu_alarm_timer {
 };
 
 #define ALARM_FLAG_DYNTICKS  0x1
+#define ALARM_FLAG_MODIFIED  0x2
 
 static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
 {
@@ -833,6 +834,11 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
     if (!alarm_has_dynticks(t))
         return;
 
+    if (!(t->flags & ALARM_FLAG_MODIFIED))
+        return;
+
+    t->flags &= ~(ALARM_FLAG_MODIFIED);
+
     t->rearm(t);
 }
 
@@ -995,6 +1001,8 @@ void qemu_del_timer(QEMUTimer *ts)
 {
     QEMUTimer **pt, *t;
 
+    alarm_timer->flags |= ALARM_FLAG_MODIFIED;
+
     /* NOTE: this code must be signal safe because
        qemu_timer_expired() can be called from a signal. */
     pt = &active_timers[ts->clock->type];
@@ -1067,7 +1075,6 @@ static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
         /* run the callback (the timer list can be modified) */
         ts->cb(ts->opaque);
     }
-    qemu_rearm_alarm_timer(alarm_timer);
 }
 
 int64_t qemu_get_clock(QEMUClock *clock)
@@ -1119,9 +1126,9 @@ static void timer_save(QEMUFile *f, void *opaque)
     if (cpu_ticks_enabled) {
         hw_error("cannot save state if virtual timers are running");
     }
-    qemu_put_be64s(f, &cpu_ticks_offset);
-    qemu_put_be64s(f, &ticks_per_sec);
-    qemu_put_be64s(f, &cpu_clock_offset);
+    qemu_put_be64(f, cpu_ticks_offset);
+    qemu_put_be64(f, ticks_per_sec);
+    qemu_put_be64(f, cpu_clock_offset);
 }
 
 static int timer_load(QEMUFile *f, void *opaque, int version_id)
@@ -1131,10 +1138,10 @@ static int timer_load(QEMUFile *f, void *opaque, int version_id)
     if (cpu_ticks_enabled) {
         return -EINVAL;
     }
-    qemu_get_be64s(f, &cpu_ticks_offset);
-    qemu_get_be64s(f, &ticks_per_sec);
+    cpu_ticks_offset=qemu_get_be64(f);
+    ticks_per_sec=qemu_get_be64(f);
     if (version_id == 2) {
-        qemu_get_be64s(f, &cpu_clock_offset);
+        cpu_clock_offset=qemu_get_be64(f);
     }
     return 0;
 }
@@ -1186,13 +1193,16 @@ static void host_alarm_handler(int host_signum)
 #endif
         CPUState *env = next_cpu;
 
-        /* stop the currently executing cpu because a timer occured */
-        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+        if (env) {
+            alarm_timer->flags |= ALARM_FLAG_MODIFIED;
+            /* stop the currently executing cpu because a timer occured */
+            cpu_interrupt(env, CPU_INTERRUPT_EXIT);
 #ifdef USE_KQEMU
-        if (env->kqemu_enabled) {
-            kqemu_cpu_interrupt(env);
-        }
+            if (env->kqemu_enabled) {
+                kqemu_cpu_interrupt(env);
+            }
 #endif
+        }
         event_pending = 1;
     }
 }
@@ -4413,7 +4423,8 @@ static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd,
 {
     int so_type=-1, optlen=sizeof(so_type);
 
-    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, &optlen)< 0) {
+    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type,
+        (socklen_t *)&optlen)< 0) {
        fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd);
        return NULL;
     }
@@ -4827,14 +4838,14 @@ static int drive_add(const char *fmt, ...)
     return nb_drives_opt++;
 }
 
-int drive_get_index(BlockInterfaceType interface, int bus, int unit)
+int drive_get_index(BlockInterfaceType type, int bus, int unit)
 {
     int index;
 
     /* seek interface, bus and unit */
 
     for (index = 0; index < nb_drives; index++)
-        if (drives_table[index].interface == interface &&
+        if (drives_table[index].type == type &&
            drives_table[index].bus == bus &&
            drives_table[index].unit == unit)
         return index;
@@ -4842,14 +4853,14 @@ int drive_get_index(BlockInterfaceType interface, int bus, int unit)
     return -1;
 }
 
-int drive_get_max_bus(BlockInterfaceType interface)
+int drive_get_max_bus(BlockInterfaceType type)
 {
     int max_bus;
     int index;
 
     max_bus = -1;
     for (index = 0; index < nb_drives; index++) {
-        if(drives_table[index].interface == interface &&
+        if(drives_table[index].type == type &&
            drives_table[index].bus > max_bus)
             max_bus = drives_table[index].bus;
     }
@@ -4862,15 +4873,18 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
     char file[1024];
     char devname[128];
     const char *mediastr = "";
-    BlockInterfaceType interface;
+    BlockInterfaceType type;
     enum { MEDIA_DISK, MEDIA_CDROM } media;
     int bus_id, unit_id;
     int cyls, heads, secs, translation;
     BlockDriverState *bdrv;
     int max_devs;
     int index;
+    int cache;
+    int bdrv_flags;
     char *params[] = { "bus", "unit", "if", "index", "cyls", "heads",
-                       "secs", "trans", "media", "snapshot", "file", NULL };
+                       "secs", "trans", "media", "snapshot", "file",
+                       "cache", NULL };
 
     if (check_params(buf, sizeof(buf), params, str) < 0) {
          fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n",
@@ -4884,6 +4898,7 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
     unit_id = -1;
     translation = BIOS_ATA_TRANSLATION_AUTO;
     index = -1;
+    cache = 1;
 
     if (!strcmp(machine->name, "realview") ||
         !strcmp(machine->name, "SS-5") ||
@@ -4891,11 +4906,11 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
         !strcmp(machine->name, "SS-600MP") ||
         !strcmp(machine->name, "versatilepb") ||
         !strcmp(machine->name, "versatileab")) {
-        interface = IF_SCSI;
+        type = IF_SCSI;
         max_devs = MAX_SCSI_DEVS;
         strcpy(devname, "scsi");
     } else {
-        interface = IF_IDE;
+        type = IF_IDE;
         max_devs = MAX_IDE_DEVS;
         strcpy(devname, "ide");
     }
@@ -4922,22 +4937,22 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
     if (get_param_value(buf, sizeof(buf), "if", str)) {
         strncpy(devname, buf, sizeof(devname));
         if (!strcmp(buf, "ide")) {
-           interface = IF_IDE;
+           type = IF_IDE;
             max_devs = MAX_IDE_DEVS;
         } else if (!strcmp(buf, "scsi")) {
-           interface = IF_SCSI;
+           type = IF_SCSI;
             max_devs = MAX_SCSI_DEVS;
         } else if (!strcmp(buf, "floppy")) {
-           interface = IF_FLOPPY;
+           type = IF_FLOPPY;
             max_devs = 0;
         } else if (!strcmp(buf, "pflash")) {
-           interface = IF_PFLASH;
+           type = IF_PFLASH;
             max_devs = 0;
        } else if (!strcmp(buf, "mtd")) {
-           interface = IF_MTD;
+           type = IF_MTD;
             max_devs = 0;
        } else if (!strcmp(buf, "sd")) {
-           interface = IF_SD;
+           type = IF_SD;
             max_devs = 0;
        } else {
             fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
@@ -5026,6 +5041,17 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
        }
     }
 
+    if (get_param_value(buf, sizeof(buf), "cache", str)) {
+        if (!strcmp(buf, "off"))
+            cache = 0;
+        else if (!strcmp(buf, "on"))
+            cache = 1;
+        else {
+           fprintf(stderr, "qemu: invalid cache option\n");
+           return -1;
+        }
+    }
+
     get_param_value(file, sizeof(file), "file", str);
 
     /* compute bus and unit according index */
@@ -5052,7 +5078,7 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
 
     if (unit_id == -1) {
        unit_id = 0;
-       while (drive_get_index(interface, bus_id, unit_id) != -1) {
+       while (drive_get_index(type, bus_id, unit_id) != -1) {
            unit_id++;
            if (max_devs && unit_id >= max_devs) {
                unit_id -= max_devs;
@@ -5073,23 +5099,27 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
      * ignore multiple definitions
      */
 
-    if (drive_get_index(interface, bus_id, unit_id) != -1)
+    if (drive_get_index(type, bus_id, unit_id) != -1)
         return 0;
 
     /* init */
 
-    if (interface == IF_IDE || interface == IF_SCSI)
+    if (type == IF_IDE || type == IF_SCSI)
         mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
-    snprintf(buf, sizeof(buf), max_devs ? "%1$s%4$i%2$s%3$i" : "%s%s%i",
-             devname, mediastr, unit_id, bus_id);
+    if (max_devs)
+        snprintf(buf, sizeof(buf), "%s%i%s%i",
+                 devname, bus_id, mediastr, unit_id);
+    else
+        snprintf(buf, sizeof(buf), "%s%s%i",
+                 devname, mediastr, unit_id);
     bdrv = bdrv_new(buf);
     drives_table[nb_drives].bdrv = bdrv;
-    drives_table[nb_drives].interface = interface;
+    drives_table[nb_drives].type = type;
     drives_table[nb_drives].bus = bus_id;
     drives_table[nb_drives].unit = unit_id;
     nb_drives++;
 
-    switch(interface) {
+    switch(type) {
     case IF_IDE:
     case IF_SCSI:
         switch(media) {
@@ -5116,8 +5146,12 @@ static int drive_init(const char *str, int snapshot, QEMUMachine *machine)
     }
     if (!file[0])
         return 0;
-    if (bdrv_open(bdrv, file, snapshot ? BDRV_O_SNAPSHOT : 0) < 0 ||
-        qemu_key_check(bdrv, file)) {
+    bdrv_flags = 0;
+    if (snapshot)
+        bdrv_flags |= BDRV_O_SNAPSHOT;
+    if (!cache)
+        bdrv_flags |= BDRV_O_DIRECT;
+    if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file)) {
         fprintf(stderr, "qemu: could not open disk image %s\n",
                         file);
         return -1;
@@ -7362,6 +7396,8 @@ void main_loop_wait(int timeout)
     qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
                     qemu_get_clock(rt_clock));
 
+    qemu_rearm_alarm_timer(alarm_timer);
+
     /* Check bottom-halves last in case any of the earlier events triggered
        them.  */
     qemu_bh_poll();
@@ -7463,7 +7499,8 @@ static void help(int exitcode)
            "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
            "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
           "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i]\n"
-           "       [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]\n"
+           "       [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off]"
+           "       [,cache=on|off]\n"
           "                use 'file' as a drive image\n"
            "-mtdblock file  use 'file' as on-board Flash memory image\n"
            "-sd file        use 'file' as SecureDigital card image\n"
@@ -8953,7 +8990,7 @@ int main(int argc, char **argv)
                     s->down_script[0])
                     launch_script(s->down_script, ifname, s->fd);
             }
-    }
+        }
     }
 #endif
     return 0;