qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v3 1/1] atapi: make change media detection for guest


From: Pavel Hrdina
Subject: [Qemu-devel] [PATCH v3 1/1] atapi: make change media detection for guests easier
Date: Wed, 21 Nov 2012 18:17:29 +0100

If you have a guest with a media in the optical drive and you change the media
the windows guest cannot properly recognize this media change.

Windows needs to detect the sense "NOT_READY with ASC_MEDIUM_NOT_PRESENT"
before we send the sense "UNIT_ATTENTION with ASC_MEDIUM_MAY_HAVE_CHANGED".

v3: remove timeout as it isn't needed anymore

v2: disable debug messages

Signed-off-by: Pavel Hrdina <address@hidden>
---
 hw/ide/atapi.c    | 16 +++++++++++-----
 hw/ide/core.c     | 12 ++++++++++++
 hw/ide/internal.h |  1 +
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 685cbaa..1534afe 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -1124,12 +1124,18 @@ void ide_atapi_cmd(IDEState *s)
      * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
      * states rely on this behavior.
      */
-    if (!s->tray_open && bdrv_is_inserted(s->bs) && s->cdrom_changed) {
-        ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+    if (!(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA) &&
+        !s->tray_open && bdrv_is_inserted(s->bs) && s->cdrom_changed) {
+
+        if (!s->fake_cdrom_eject) {
+            ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+            s->fake_cdrom_eject = 1;
+        } else {
+            ide_atapi_cmd_error(s, UNIT_ATTENTION, 
ASC_MEDIUM_MAY_HAVE_CHANGED);
+            s->fake_cdrom_eject = 0;
+            s->cdrom_changed = 0;
+        }
 
-        s->cdrom_changed = 0;
-        s->sense_key = UNIT_ATTENTION;
-        s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
         return;
     }
 
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 7d6b0fa..013671a 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1851,6 +1851,7 @@ static void ide_reset(IDEState *s)
     s->sense_key = 0;
     s->asc = 0;
     s->cdrom_changed = 0;
+    s->fake_cdrom_eject = 0;
     s->packet_transfer_size = 0;
     s->elementary_transfer_size = 0;
     s->io_buffer_index = 0;
@@ -2143,6 +2144,16 @@ static int transfer_end_table_idx(EndTransferFunc *fn)
     return -1;
 }
 
+static void ide_drive_pre_save(void *opaque)
+{
+    IDEState *s = opaque;
+
+    if (s->cdrom_changed) {
+        s->sense_key = UNIT_ATTENTION;
+        s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
+    }
+}
+
 static int ide_drive_post_load(void *opaque, int version_id)
 {
     IDEState *s = opaque;
@@ -2270,6 +2281,7 @@ const VMStateDescription vmstate_ide_drive = {
     .version_id = 3,
     .minimum_version_id = 0,
     .minimum_version_id_old = 0,
+    .pre_save = ide_drive_pre_save,
     .post_load = ide_drive_post_load,
     .fields      = (VMStateField []) {
         VMSTATE_INT32(mult_sectors, IDEState),
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index bf7d313..5fb2266 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -382,6 +382,7 @@ struct IDEState {
     bool tray_open;
     bool tray_locked;
     uint8_t cdrom_changed;
+    uint8_t fake_cdrom_eject;
     int packet_transfer_size;
     int elementary_transfer_size;
     int io_buffer_index;
-- 
1.7.11.7




reply via email to

[Prev in Thread] Current Thread [Next in Thread]