mirror of https://gitee.com/openkylin/qemu.git
Partial IDE DVD emulation, by Filip Navara.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3161 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
ce62e5ba09
commit
d14049eaec
76
hw/ide.c
76
hw/ide.c
|
@ -261,6 +261,7 @@
|
||||||
* older drives only.
|
* older drives only.
|
||||||
*/
|
*/
|
||||||
#define GPCMD_GET_MEDIA_STATUS 0xda
|
#define GPCMD_GET_MEDIA_STATUS 0xda
|
||||||
|
#define GPCMD_MODE_SENSE_6 0x1a
|
||||||
|
|
||||||
/* Mode page codes for mode sense/set */
|
/* Mode page codes for mode sense/set */
|
||||||
#define GPMODE_R_W_ERROR_PAGE 0x01
|
#define GPMODE_R_W_ERROR_PAGE 0x01
|
||||||
|
@ -1329,10 +1330,14 @@ static void ide_atapi_cmd(IDEState *s)
|
||||||
ASC_MEDIUM_NOT_PRESENT);
|
ASC_MEDIUM_NOT_PRESENT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GPCMD_MODE_SENSE_6:
|
||||||
case GPCMD_MODE_SENSE_10:
|
case GPCMD_MODE_SENSE_10:
|
||||||
{
|
{
|
||||||
int action, code;
|
int action, code;
|
||||||
max_len = ube16_to_cpu(packet + 7);
|
if (packet[0] == GPCMD_MODE_SENSE_10)
|
||||||
|
max_len = ube16_to_cpu(packet + 7);
|
||||||
|
else
|
||||||
|
max_len = packet[4];
|
||||||
action = packet[2] >> 6;
|
action = packet[2] >> 6;
|
||||||
code = packet[2] & 0x3f;
|
code = packet[2] & 0x3f;
|
||||||
switch(action) {
|
switch(action) {
|
||||||
|
@ -1368,7 +1373,7 @@ static void ide_atapi_cmd(IDEState *s)
|
||||||
|
|
||||||
buf[8] = 0x2a;
|
buf[8] = 0x2a;
|
||||||
buf[9] = 0x12;
|
buf[9] = 0x12;
|
||||||
buf[10] = 0x00;
|
buf[10] = 0x08;
|
||||||
buf[11] = 0x00;
|
buf[11] = 0x00;
|
||||||
|
|
||||||
buf[12] = 0x70;
|
buf[12] = 0x70;
|
||||||
|
@ -1582,6 +1587,50 @@ static void ide_atapi_cmd(IDEState *s)
|
||||||
ide_atapi_cmd_reply(s, 8, 8);
|
ide_atapi_cmd_reply(s, 8, 8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GPCMD_READ_DVD_STRUCTURE:
|
||||||
|
{
|
||||||
|
int media = packet[1];
|
||||||
|
int layer = packet[6];
|
||||||
|
int format = packet[2];
|
||||||
|
int64_t total_sectors;
|
||||||
|
|
||||||
|
if (media != 0 || layer != 0)
|
||||||
|
{
|
||||||
|
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
||||||
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case 0:
|
||||||
|
bdrv_get_geometry(s->bs, &total_sectors);
|
||||||
|
total_sectors >>= 2;
|
||||||
|
|
||||||
|
memset(buf, 0, 2052);
|
||||||
|
|
||||||
|
buf[4] = 1; // DVD-ROM, part version 1
|
||||||
|
buf[5] = 0xf; // 120mm disc, maximum rate unspecified
|
||||||
|
buf[6] = 0; // one layer, embossed data
|
||||||
|
buf[7] = 0;
|
||||||
|
|
||||||
|
cpu_to_ube32(buf + 8, 0);
|
||||||
|
cpu_to_ube32(buf + 12, total_sectors - 1);
|
||||||
|
cpu_to_ube32(buf + 16, total_sectors - 1);
|
||||||
|
|
||||||
|
cpu_to_be16wu((uint16_t *)buf, 2048 + 4);
|
||||||
|
|
||||||
|
ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
||||||
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GPCMD_SET_SPEED:
|
||||||
|
ide_atapi_cmd_ok(s);
|
||||||
|
break;
|
||||||
case GPCMD_INQUIRY:
|
case GPCMD_INQUIRY:
|
||||||
max_len = packet[4];
|
max_len = packet[4];
|
||||||
buf[0] = 0x05; /* CD-ROM */
|
buf[0] = 0x05; /* CD-ROM */
|
||||||
|
@ -1597,6 +1646,29 @@ static void ide_atapi_cmd(IDEState *s)
|
||||||
padstr8(buf + 32, 4, QEMU_VERSION);
|
padstr8(buf + 32, 4, QEMU_VERSION);
|
||||||
ide_atapi_cmd_reply(s, 36, max_len);
|
ide_atapi_cmd_reply(s, 36, max_len);
|
||||||
break;
|
break;
|
||||||
|
case GPCMD_GET_CONFIGURATION:
|
||||||
|
{
|
||||||
|
int64_t total_sectors;
|
||||||
|
|
||||||
|
/* only feature 0 is supported */
|
||||||
|
if (packet[2] != 0 || packet[3] != 0) {
|
||||||
|
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
||||||
|
ASC_INV_FIELD_IN_CMD_PACKET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memset(buf, 0, 32);
|
||||||
|
bdrv_get_geometry(s->bs, &total_sectors);
|
||||||
|
buf[3] = 16;
|
||||||
|
buf[7] = total_sectors <= 1433600 ? 0x08 : 0x10; /* current profile */
|
||||||
|
buf[10] = 0x10 | 0x1;
|
||||||
|
buf[11] = 0x08; /* size of profile list */
|
||||||
|
buf[13] = 0x10; /* DVD-ROM profile */
|
||||||
|
buf[14] = buf[7] == 0x10; /* (in)active */
|
||||||
|
buf[17] = 0x08; /* CD-ROM profile */
|
||||||
|
buf[18] = buf[7] == 0x08; /* (in)active */
|
||||||
|
ide_atapi_cmd_reply(s, 32, 32);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
||||||
ASC_ILLEGAL_OPCODE);
|
ASC_ILLEGAL_OPCODE);
|
||||||
|
|
Loading…
Reference in New Issue