Message ID | 1318503845-11473-11-git-send-email-pbonzini@redhat.com |
---|---|
State | New |
Headers | show |
Am 13.10.2011 13:03, schrieb Paolo Bonzini: > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > --- > hw/scsi-disk.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- > 1 files changed, 42 insertions(+), 8 deletions(-) > > diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c > index 837747f..1786c37 100644 > --- a/hw/scsi-disk.c > +++ b/hw/scsi-disk.c > @@ -563,6 +563,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) > { > @@ -577,17 +590,38 @@ 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); Is the memset required at all? I seem to remember that the output buffer was zeroed in generic code. > + stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */ > + /* outbuf[4] - outbuf[19]: Feature 0 - Profile list */ Isn't it outbuf[8] - outbuf[19]? > + stw_be_p(&outbuf[6], current); > + outbuf[10] = 0x03; /* persistent, current */ > + outbuf[11] = 8; /* two profiles */ > + stw_be_p(&outbuf[12], MMC_PROFILE_DVD_ROM); > + outbuf[14] = (current == MMC_PROFILE_DVD_ROM); > + stw_be_p(&outbuf[16], MMC_PROFILE_CD_ROM); > + outbuf[18] = (current == MMC_PROFILE_CD_ROM); > + /* outbuf[20] - outbuf[31]: Feature 1 - Core feature */ > + stw_be_p(&outbuf[20], 1); > + outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */ > + outbuf[23] = 8; > + stl_be_p(&outbuf[24], 1); /* SCSI */ > + outbuf[28] = 1; /* DBE = 1, mandatory */ > + /* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */ > + stw_be_p(&outbuf[32], 3); > + outbuf[34] = 0x08 | 0x03; /* version 2, persistent, current */ MMC-5 doesn't know version 2, so I can't check this. > + 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; > } And some blank lines wouldn't hurt. :-) > > static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf) > @@ -1006,7 +1040,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) > goto illegal_request; > break; > case GET_CONFIGURATION: > - buflen = scsi_get_configuration(s, r, outbuf); > + buflen = scsi_get_configuration(s, outbuf); > if (buflen < 0) > goto illegal_request; > break; Kevin
On 10/17/2011 05:20 PM, Kevin Wolf wrote: >> > + current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM; >> > + memset(outbuf, 0, 40); > Is the memset required at all? I seem to remember that the output buffer > was zeroed in generic code. No, it isn't. >> > + stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */ >> > + /* outbuf[4] - outbuf[19]: Feature 0 - Profile list */ > > Isn't it outbuf[8] - outbuf[19]? Right. Paolo
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 837747f..1786c37 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -563,6 +563,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) { @@ -577,17 +590,38 @@ 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); + stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */ + /* outbuf[4] - outbuf[19]: Feature 0 - Profile list */ + stw_be_p(&outbuf[6], current); + outbuf[10] = 0x03; /* persistent, current */ + outbuf[11] = 8; /* two profiles */ + stw_be_p(&outbuf[12], MMC_PROFILE_DVD_ROM); + outbuf[14] = (current == MMC_PROFILE_DVD_ROM); + stw_be_p(&outbuf[16], MMC_PROFILE_CD_ROM); + outbuf[18] = (current == MMC_PROFILE_CD_ROM); + /* outbuf[20] - outbuf[31]: Feature 1 - Core feature */ + stw_be_p(&outbuf[20], 1); + outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */ + outbuf[23] = 8; + stl_be_p(&outbuf[24], 1); /* SCSI */ + outbuf[28] = 1; /* DBE = 1, mandatory */ + /* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */ + stw_be_p(&outbuf[32], 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) @@ -1006,7 +1040,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) goto illegal_request; break; case GET_CONFIGURATION: - buflen = scsi_get_configuration(s, r, outbuf); + buflen = scsi_get_configuration(s, outbuf); if (buflen < 0) goto illegal_request; break;
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- hw/scsi-disk.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 42 insertions(+), 8 deletions(-)