diff mbox

SCSI: Add disk reset handler

Message ID 4BC4669E.6040004@siemens.com
State New
Headers show

Commit Message

Jan Kiszka April 13, 2010, 12:42 p.m. UTC
Ensure that pending requests of an SCSI disk are purged on system reset
and also restore max_lba. The latter is now only present in the reset
handler as that one is already automatically called during init.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/scsi-disk.c |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

This should be applied to stable as well. I can provide a corresponding
patch once this one is acceptable.
diff mbox

Patch

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 77cb1da..50d5e9c 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1010,22 +1010,42 @@  static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
     }
 }
 
-static void scsi_destroy(SCSIDevice *dev)
+static void scsi_disk_purge_requests(SCSIDiskState *s)
 {
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
     SCSIDiskReq *r;
 
     while (!QTAILQ_EMPTY(&s->qdev.requests)) {
         r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests));
         scsi_remove_request(r);
     }
+}
+
+static void scsi_disk_reset(DeviceState *dev)
+{
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
+    uint64_t nb_sectors;
+
+    scsi_disk_purge_requests(s);
+
+    bdrv_get_geometry(s->bs, &nb_sectors);
+    nb_sectors /= s->cluster_size;
+    if (nb_sectors) {
+        nb_sectors--;
+    }
+    s->max_lba = nb_sectors;
+}
+
+static void scsi_destroy(SCSIDevice *dev)
+{
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+
+    scsi_disk_purge_requests(s);
     drive_uninit(s->qdev.conf.dinfo);
 }
 
 static int scsi_disk_initfn(SCSIDevice *dev)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
-    uint64_t nb_sectors;
 
     if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
         error_report("scsi-disk: drive property not set");
@@ -1046,11 +1066,6 @@  static int scsi_disk_initfn(SCSIDevice *dev)
     s->cluster_size = s->qdev.blocksize / 512;
 
     s->qdev.type = TYPE_DISK;
-    bdrv_get_geometry(s->bs, &nb_sectors);
-    nb_sectors /= s->cluster_size;
-    if (nb_sectors)
-        nb_sectors--;
-    s->max_lba = nb_sectors;
     qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
     return 0;
 }
@@ -1059,6 +1074,7 @@  static SCSIDeviceInfo scsi_disk_info = {
     .qdev.name    = "scsi-disk",
     .qdev.desc    = "virtual scsi disk or cdrom",
     .qdev.size    = sizeof(SCSIDiskState),
+    .qdev.reset   = scsi_disk_reset,
     .init         = scsi_disk_initfn,
     .destroy      = scsi_destroy,
     .send_command = scsi_send_command,