From e9447f35718439c1affdee3ef69b2fee50c8106c Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 4 May 2010 14:20:59 +0200 Subject: SCSI: Add disk reset handler Ensure that pending requests of an SCSI disk are purged on system reset and also restore max_lba. The latter is no only present in the reset handler as that one is called after init as well. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori --- hw/scsi-disk.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'hw/scsi-disk.c') diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 77cb1daec8..b8d805fb51 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -1010,22 +1010,45 @@ 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)); + if (r->req.aiocb) { + bdrv_aio_cancel(r->req.aiocb); + } 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 +1069,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 +1077,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, -- cgit v1.2.3