scsi-disk: implement READ DISC INFORMATION

This command is not necessary for CD-ROM and DVD-ROM, but some versions of
udev trip on its absence.

Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
master
Paolo Bonzini 2012-05-25 12:59:55 +02:00
parent 55042b955b
commit 1a4f0c3a06
2 changed files with 41 additions and 0 deletions

View File

@ -82,6 +82,7 @@
#define GET_EVENT_STATUS_NOTIFICATION 0x4a
#define LOG_SELECT 0x4c
#define LOG_SENSE 0x4d
#define READ_DISC_INFORMATION 0x51
#define RESERVE_TRACK 0x53
#define MODE_SELECT_10 0x55
#define RESERVE_10 0x56

View File

@ -724,6 +724,39 @@ static inline bool media_is_cd(SCSIDiskState *s)
return nb_sectors <= CD_MAX_SECTORS;
}
static int scsi_read_disc_information(SCSIDiskState *s, SCSIDiskReq *r,
uint8_t *outbuf)
{
uint8_t type = r->req.cmd.buf[1] & 7;
if (s->qdev.type != TYPE_ROM) {
return -1;
}
/* Types 1/2 are only defined for Blu-Ray. */
if (type != 0) {
scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
return -1;
}
memset(outbuf, 0, 34);
outbuf[1] = 32;
outbuf[2] = 0xe; /* last session complete, disc finalized */
outbuf[3] = 1; /* first track on disc */
outbuf[4] = 1; /* # of sessions */
outbuf[5] = 1; /* first track of last session */
outbuf[6] = 1; /* last track of last session */
outbuf[7] = 0x20; /* unrestricted use */
outbuf[8] = 0x00; /* CD-ROM or DVD-ROM */
/* 9-10-11: most significant byte corresponding bytes 4-5-6 */
/* 12-23: not meaningful for CD-ROM or DVD-ROM */
/* 24-31: disc bar code */
/* 32: disc application code */
/* 33: number of OPC tables */
return 34;
}
static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
uint8_t *outbuf)
{
@ -1363,6 +1396,12 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
goto illegal_request;
}
break;
case READ_DISC_INFORMATION:
buflen = scsi_read_disc_information(s, r, outbuf);
if (buflen < 0) {
goto illegal_request;
}
break;
case READ_DVD_STRUCTURE:
buflen = scsi_read_dvd_structure(s, r, outbuf);
if (buflen < 0) {
@ -1490,6 +1529,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
case ALLOW_MEDIUM_REMOVAL:
case READ_CAPACITY_10:
case READ_TOC:
case READ_DISC_INFORMATION:
case READ_DVD_STRUCTURE:
case GET_CONFIGURATION:
case GET_EVENT_STATUS_NOTIFICATION: