From c5caa015c1e745f3e529be1054523fb9cbfa33c8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Feb 2012 14:12:05 +0100 Subject: [PATCH 049/109] scsi-disk: support DVD profile in GET CONFIGURATION RH-Author: Paolo Bonzini Message-id: <1329919979-20948-49-git-send-email-pbonzini@redhat.com> Patchwork-id: 37529 O-Subject: [RHEL 6.3 qemu-kvm PATCH v2 048/102] scsi-disk: support DVD profile in GET CONFIGURATION Bugzilla: 782029 RH-Acked-by: Laszlo Ersek RH-Acked-by: Orit Wasserman RH-Acked-by: Gerd Hoffmann Upstream used st*_be_p functions, which are not available to common code in RHEL6 qemu. Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf (cherry picked from 430ee2f26f01f146f3757467b3f0b802ad309ff8) --- hw/scsi-disk.c | 51 +++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 43 insertions(+), 8 deletions(-) Signed-off-by: Michal Novotny --- hw/scsi-disk.c | 51 +++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 43 insertions(+), 8 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 7e6b0df..771721d 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -601,6 +601,19 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) return buflen; } +static inline bool media_is_dvd(SCSIDiskState *s) +{ + uint64_t nb_sectors; + if (s->qdev.type != TYPE_ROM) { + return false; + } + if (!bdrv_is_inserted(s->bs)) { + return false; + } + bdrv_get_geometry(s->bs, &nb_sectors); + return nb_sectors > CD_MAX_SECTORS; +} + static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r, uint8_t *outbuf) { @@ -615,17 +628,39 @@ static int scsi_get_event_status_notification(SCSIDiskState *s, return -1; } -static int scsi_get_configuration(SCSIDiskState *s, SCSIDiskReq *r, - uint8_t *outbuf) +static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf) { + int current; + if (s->qdev.type != TYPE_ROM) { return -1; } - memset(outbuf, 0, 8); - /* ??? This should probably return much more information. For now - just return the basic header indicating the CD-ROM profile. */ - outbuf[7] = 8; /* CD-ROM */ - return 8; + current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM; + memset(outbuf, 0, 40); + outbuf[3] = 36; /* Bytes after the data length field */ + outbuf[6] = current >> 8; + outbuf[7] = current; + /* outbuf[8] - outbuf[19]: Feature 0 - Profile list */ + outbuf[10] = 0x03; /* persistent, current */ + outbuf[11] = 8; /* two profiles */ + outbuf[13] = MMC_PROFILE_DVD_ROM; + outbuf[14] = (current == MMC_PROFILE_DVD_ROM); + outbuf[17] = MMC_PROFILE_CD_ROM; + outbuf[18] = (current == MMC_PROFILE_CD_ROM); + /* outbuf[20] - outbuf[31]: Feature 1 - Core feature */ + outbuf[21] = 1; + outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */ + outbuf[23] = 8; + outbuf[27] = 1; /* SCSI */ + outbuf[28] = 1; /* DBE = 1, mandatory */ + /* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */ + outbuf[33] = 3; + outbuf[34] = 0x08 | 0x03; /* version 2, persistent, current */ + outbuf[35] = 4; + outbuf[36] = 0x39; /* tray, load=1, eject=1, unlocked at powerup, lock=1 */ + /* TODO: Random readable, CD read, DVD read, drive serial number, + power management */ + return 40; } static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf) @@ -1058,7 +1093,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) } break; case GET_CONFIGURATION: - buflen = scsi_get_configuration(s, r, outbuf); + buflen = scsi_get_configuration(s, outbuf); if (buflen < 0) { goto illegal_request; } -- 1.7.7.6