From 74d61ea29b74dc4c590ff08f8322211b838fc8cb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Feb 2012 14:12:00 +0100 Subject: [PATCH 044/109] scsi-disk: report media changed via unit attention sense codes RH-Author: Paolo Bonzini Message-id: <1329919979-20948-44-git-send-email-pbonzini@redhat.com> Patchwork-id: 37524 O-Subject: [RHEL 6.3 qemu-kvm PATCH v2 043/102] scsi-disk: report media changed via unit attention sense codes Bugzilla: 782029 RH-Acked-by: Laszlo Ersek RH-Acked-by: Orit Wasserman RH-Acked-by: Gerd Hoffmann Building on the previous patch, this one adds a media change callback to scsi-disk. Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf (cherry picked from 8a9c16f69e3ecbcc6e6bc068012986b87412c876) --- hw/scsi-bus.c | 5 +++++ hw/scsi-disk.c | 29 ++++++++++++++++++++++++++++- hw/scsi.h | 2 ++ 3 files changed, 35 insertions(+), 1 deletions(-) Signed-off-by: Michal Novotny --- hw/scsi-bus.c | 5 +++++ hw/scsi-disk.c | 29 ++++++++++++++++++++++++++++- hw/scsi.h | 2 ++ 3 files changed, 35 insertions(+), 1 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index b385213..dd1217b 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -906,6 +906,11 @@ const struct SCSISense sense_code_RESET = { .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00 }; +/* Unit attention, No medium */ +const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM = { + .key = UNIT_ATTENTION, .asc = 0x3a, .ascq = 0x00 +}; + /* Unit attention, Medium may have changed */ const struct SCSISense sense_code_MEDIUM_CHANGED = { .key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00 diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 0e9ced8..914d43c 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -70,6 +70,7 @@ struct SCSIDiskState int cluster_size; uint32_t removable; uint64_t max_lba; + bool media_changed; QEMUBH *bh; char *version; char *serial; @@ -1234,7 +1235,21 @@ static void scsi_destroy(SCSIDevice *dev) static void scsi_cd_change_media_cb(void *opaque, bool load) { - ((SCSIDiskState *)opaque)->tray_open = !load; + SCSIDiskState *s = opaque; + + /* + * When a CD gets changed, we have to report an ejected state and + * then a loaded state to guests so that they detect tray + * open/close and media change events. Guests that do not use + * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close + * states rely on this behavior. + * + * media_changed governs the state machine used for unit attention + * report. media_event is used by GET EVENT STATUS NOTIFICATION. + */ + s->media_changed = load; + s->tray_open = !load; + s->qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM); } static bool scsi_cd_is_tray_open(void *opaque) @@ -1253,6 +1268,15 @@ static const BlockDevOps scsi_cd_block_ops = { .is_medium_locked = scsi_cd_is_medium_locked, }; +static void scsi_disk_unit_attention_reported(SCSIDevice *dev) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + if (s->media_changed) { + s->media_changed = false; + s->qdev.unit_attention = SENSE_CODE(MEDIUM_CHANGED); + } +} + static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); @@ -1363,6 +1387,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .init = scsi_hd_initfn, .destroy = scsi_destroy, .alloc_req = scsi_new_request, + .unit_attention_reported = scsi_disk_unit_attention_reported, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false), @@ -1377,6 +1402,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .init = scsi_cd_initfn, .destroy = scsi_destroy, .alloc_req = scsi_new_request, + .unit_attention_reported = scsi_disk_unit_attention_reported, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_END_OF_LIST(), @@ -1390,6 +1416,7 @@ static SCSIDeviceInfo scsi_disk_info[] = { .init = scsi_disk_initfn, .destroy = scsi_destroy, .alloc_req = scsi_new_request, + .unit_attention_reported = scsi_disk_unit_attention_reported, .qdev.props = (Property[]) { DEFINE_SCSI_DISK_PROPERTIES(), DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false), diff --git a/hw/scsi.h b/hw/scsi.h index afa5994..5c5d069 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -162,6 +162,8 @@ extern const struct SCSISense sense_code_IO_ERROR; extern const struct SCSISense sense_code_I_T_NEXUS_LOSS; /* Command aborted, Logical Unit failure */ extern const struct SCSISense sense_code_LUN_FAILURE; +/* LUN not ready, Medium not present */ +extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM; /* Unit attention, Power on, reset or bus device reset occurred */ extern const struct SCSISense sense_code_RESET; /* Unit attention, Medium may have changed*/ -- 1.7.7.6