mirror of https://github.com/xqemu/xqemu.git
scsi-disk: report media changed via unit attention sense codes
Building on the previous patch, this one adds a media change callback to scsi-disk. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
3653d8c40e
commit
8a9c16f69e
|
@ -847,6 +847,11 @@ const struct SCSISense sense_code_RESET = {
|
||||||
.key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00
|
.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 */
|
/* Unit attention, Medium may have changed */
|
||||||
const struct SCSISense sense_code_MEDIUM_CHANGED = {
|
const struct SCSISense sense_code_MEDIUM_CHANGED = {
|
||||||
.key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00
|
.key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00
|
||||||
|
|
|
@ -71,6 +71,7 @@ struct SCSIDiskState
|
||||||
int cluster_size;
|
int cluster_size;
|
||||||
uint32_t removable;
|
uint32_t removable;
|
||||||
uint64_t max_lba;
|
uint64_t max_lba;
|
||||||
|
bool media_changed;
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
char *version;
|
char *version;
|
||||||
char *serial;
|
char *serial;
|
||||||
|
@ -1198,7 +1199,21 @@ static void scsi_destroy(SCSIDevice *dev)
|
||||||
|
|
||||||
static void scsi_cd_change_media_cb(void *opaque, bool load)
|
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)
|
static bool scsi_cd_is_tray_open(void *opaque)
|
||||||
|
@ -1217,6 +1232,15 @@ static const BlockDevOps scsi_cd_block_ops = {
|
||||||
.is_medium_locked = scsi_cd_is_medium_locked,
|
.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)
|
static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
|
||||||
{
|
{
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
|
||||||
|
@ -1329,6 +1353,7 @@ static SCSIDeviceInfo scsi_disk_info[] = {
|
||||||
.init = scsi_hd_initfn,
|
.init = scsi_hd_initfn,
|
||||||
.destroy = scsi_destroy,
|
.destroy = scsi_destroy,
|
||||||
.alloc_req = scsi_new_request,
|
.alloc_req = scsi_new_request,
|
||||||
|
.unit_attention_reported = scsi_disk_unit_attention_reported,
|
||||||
.qdev.props = (Property[]) {
|
.qdev.props = (Property[]) {
|
||||||
DEFINE_SCSI_DISK_PROPERTIES(),
|
DEFINE_SCSI_DISK_PROPERTIES(),
|
||||||
DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
|
DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
|
||||||
|
@ -1343,6 +1368,7 @@ static SCSIDeviceInfo scsi_disk_info[] = {
|
||||||
.init = scsi_cd_initfn,
|
.init = scsi_cd_initfn,
|
||||||
.destroy = scsi_destroy,
|
.destroy = scsi_destroy,
|
||||||
.alloc_req = scsi_new_request,
|
.alloc_req = scsi_new_request,
|
||||||
|
.unit_attention_reported = scsi_disk_unit_attention_reported,
|
||||||
.qdev.props = (Property[]) {
|
.qdev.props = (Property[]) {
|
||||||
DEFINE_SCSI_DISK_PROPERTIES(),
|
DEFINE_SCSI_DISK_PROPERTIES(),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
@ -1356,6 +1382,7 @@ static SCSIDeviceInfo scsi_disk_info[] = {
|
||||||
.init = scsi_disk_initfn,
|
.init = scsi_disk_initfn,
|
||||||
.destroy = scsi_destroy,
|
.destroy = scsi_destroy,
|
||||||
.alloc_req = scsi_new_request,
|
.alloc_req = scsi_new_request,
|
||||||
|
.unit_attention_reported = scsi_disk_unit_attention_reported,
|
||||||
.qdev.props = (Property[]) {
|
.qdev.props = (Property[]) {
|
||||||
DEFINE_SCSI_DISK_PROPERTIES(),
|
DEFINE_SCSI_DISK_PROPERTIES(),
|
||||||
DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
|
DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
|
||||||
|
|
|
@ -161,6 +161,8 @@ extern const struct SCSISense sense_code_IO_ERROR;
|
||||||
extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
|
extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
|
||||||
/* Command aborted, Logical Unit failure */
|
/* Command aborted, Logical Unit failure */
|
||||||
extern const struct SCSISense sense_code_LUN_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 */
|
/* Unit attention, Power on, reset or bus device reset occurred */
|
||||||
extern const struct SCSISense sense_code_RESET;
|
extern const struct SCSISense sense_code_RESET;
|
||||||
/* Unit attention, Medium may have changed*/
|
/* Unit attention, Medium may have changed*/
|
||||||
|
|
Loading…
Reference in New Issue