mirror of https://github.com/proxmox/mirror_qemu
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
parent
55042b955b
commit
1a4f0c3a06
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue