@@ -463,6 +463,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
bs->read_only = 1;
}
+ bs->open_flags = flags;
if (ret < 0) {
qemu_free(bs->opaque);
bs->opaque = NULL;
@@ -1155,9 +1156,11 @@ void bdrv_info(Monitor *mon)
if (bs->removable) {
monitor_printf(mon, " locked=%d", bs->locked);
}
- if (bs->drv) {
+ if (bs->filename[0]) {
monitor_printf(mon, " file=");
monitor_print_filename(mon, bs->filename);
+ }
+ if (bs->drv) {
if (bs->backing_file[0] != '\0') {
monitor_printf(mon, " backing_file=");
monitor_print_filename(mon, bs->backing_file);
@@ -1907,14 +1910,27 @@ int bdrv_eject(BlockDriverState *bs, int eject_flag)
ret = drv->bdrv_eject(bs, eject_flag);
}
if (ret == -ENOTSUP) {
- if (eject_flag)
+ if (eject_flag) {
bdrv_close(bs);
- ret = 0;
+ ret = 0;
+ } else { /* re-insert media */
+ if (bs->filename[0]) {
+ ret = bdrv_open(bs, bs->filename, bs->open_flags);
+ } else {
+ ret = 0;
+ }
+ }
}
-
+
return ret;
}
+
+void bdrv_forget_fname(BlockDriverState *bs)
+{
+ bs->filename[0] = '\0';
+}
+
int bdrv_is_locked(BlockDriverState *bs)
{
return bs->locked;
@@ -147,6 +147,7 @@ int bdrv_media_changed(BlockDriverState *bs);
int bdrv_is_locked(BlockDriverState *bs);
void bdrv_set_locked(BlockDriverState *bs, int locked);
int bdrv_eject(BlockDriverState *bs, int eject_flag);
+void bdrv_forget_fname(BlockDriverState *bs);
void bdrv_set_change_cb(BlockDriverState *bs,
void (*change_cb)(void *opaque), void *opaque);
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
@@ -137,6 +137,7 @@ struct BlockDriverState {
void *opaque;
char filename[1024];
+ int open_flags;
char backing_file[1024]; /* if non zero, the image is a diff of
this file image */
char backing_format[16]; /* if non-zero and backing_file exists */
@@ -35,6 +35,20 @@
#include <hw/ide/internal.h>
+
+static int is_pcommand_abort_on_check(uint8_t pcmd) {
+ int ret = 1;
+
+ if (pcmd == GPCMD_GET_CONFIGURATION ||
+ pcmd == GPCMD_REQUEST_SENSE ||
+ pcmd == GPCMD_INQUIRY) {
+ ret = 0;
+ }
+ return ret;
+}
+
+
+
static int smart_attributes[][5] = {
/* id, flags, val, wrst, thrsh */
{ 0x01, 0x03, 0x64, 0x64, 0x06}, /* raw read */
@@ -1206,12 +1220,11 @@ static void ide_atapi_cmd(IDEState *s)
}
#endif
/* If there's a UNIT_ATTENTION condition pending, only
- REQUEST_SENSE and INQUIRY commands are allowed to complete. */
+ REQUEST_SENSE and INQUIRY commands (and some more) are allowed to complete. */
if (s->sense_key == SENSE_UNIT_ATTENTION &&
- s->io_buffer[0] != GPCMD_REQUEST_SENSE &&
- s->io_buffer[0] != GPCMD_INQUIRY) {
- ide_atapi_cmd_check_status(s);
- return;
+ is_pcommand_abort_on_check(s->io_buffer[0])) {
+ ide_atapi_cmd_check_status(s);
+ return;
}
switch(s->io_buffer[0]) {
case GPCMD_TEST_UNIT_READY:
@@ -1676,9 +1689,11 @@ static void cdrom_change_cb(void *opaque)
bdrv_get_geometry(s->bs, &nb_sectors);
s->nb_sectors = nb_sectors;
- s->sense_key = SENSE_UNIT_ATTENTION;
- s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
- s->cdrom_changed = 1;
+ if (nb_sectors > 0) { /* UNIT_ATTENTION only for insertion/change, not removal */
+ s->sense_key = SENSE_UNIT_ATTENTION;
+ s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED;
+ s->cdrom_changed = 1;
+ }
ide_set_irq(s->bus);
}
@@ -2530,8 +2545,8 @@ static void ide_reset(IDEState *s)
s->lba48 = 0;
/* ATAPI specific */
- s->sense_key = 0;
- s->asc = 0;
+ s->sense_key = SENSE_UNIT_ATTENTION;
+ s->asc = 0x29; /* POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */
s->cdrom_changed = 0;
s->packet_transfer_size = 0;
s->elementary_transfer_size = 0;
@@ -567,6 +567,7 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
}
bdrv_close(bs);
}
+ bdrv_forget_fname(bs); /* "manual" eject forgets the file-name */
return 0;
}
When guest un-eject a cdrom, re-insert the cdrom image (re-open the drive's file). Also, related changes for the un-eject: o enter UNIT ATTENTION state only on change/insert media, not upon removal o minor change in packet command abort when in UNIT ATTENTION state (as per spec) o enter UNIT ATTENTION state upon reset (as per spec) o always print the file-name in info block command (if applicable) Relevant Spec: Mt. Fuji Commands for Multimedia Devices Version 7: ftp://ftp.seagate.com/sff/INF-8090.PDF Signed-off-by: Naphtali Sprei <nsprei@redhat.com> --- block.c | 24 ++++++++++++++++++++---- block.h | 1 + block_int.h | 1 + hw/ide/core.c | 35 +++++++++++++++++++++++++---------- monitor.c | 1 + 5 files changed, 48 insertions(+), 14 deletions(-)