Commit d14049eaec8d9c4349ae21eb276b70de995fdf68
1 parent
ce62e5ba
Partial IDE DVD emulation, by Filip Navara.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3161 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
74 additions
and
2 deletions
hw/ide.c
| @@ -261,6 +261,7 @@ | @@ -261,6 +261,7 @@ | ||
| 261 | * older drives only. | 261 | * older drives only. |
| 262 | */ | 262 | */ |
| 263 | #define GPCMD_GET_MEDIA_STATUS 0xda | 263 | #define GPCMD_GET_MEDIA_STATUS 0xda |
| 264 | +#define GPCMD_MODE_SENSE_6 0x1a | ||
| 264 | 265 | ||
| 265 | /* Mode page codes for mode sense/set */ | 266 | /* Mode page codes for mode sense/set */ |
| 266 | #define GPMODE_R_W_ERROR_PAGE 0x01 | 267 | #define GPMODE_R_W_ERROR_PAGE 0x01 |
| @@ -1329,10 +1330,14 @@ static void ide_atapi_cmd(IDEState *s) | @@ -1329,10 +1330,14 @@ static void ide_atapi_cmd(IDEState *s) | ||
| 1329 | ASC_MEDIUM_NOT_PRESENT); | 1330 | ASC_MEDIUM_NOT_PRESENT); |
| 1330 | } | 1331 | } |
| 1331 | break; | 1332 | break; |
| 1333 | + case GPCMD_MODE_SENSE_6: | ||
| 1332 | case GPCMD_MODE_SENSE_10: | 1334 | case GPCMD_MODE_SENSE_10: |
| 1333 | { | 1335 | { |
| 1334 | int action, code; | 1336 | int action, code; |
| 1335 | - max_len = ube16_to_cpu(packet + 7); | 1337 | + if (packet[0] == GPCMD_MODE_SENSE_10) |
| 1338 | + max_len = ube16_to_cpu(packet + 7); | ||
| 1339 | + else | ||
| 1340 | + max_len = packet[4]; | ||
| 1336 | action = packet[2] >> 6; | 1341 | action = packet[2] >> 6; |
| 1337 | code = packet[2] & 0x3f; | 1342 | code = packet[2] & 0x3f; |
| 1338 | switch(action) { | 1343 | switch(action) { |
| @@ -1368,7 +1373,7 @@ static void ide_atapi_cmd(IDEState *s) | @@ -1368,7 +1373,7 @@ static void ide_atapi_cmd(IDEState *s) | ||
| 1368 | 1373 | ||
| 1369 | buf[8] = 0x2a; | 1374 | buf[8] = 0x2a; |
| 1370 | buf[9] = 0x12; | 1375 | buf[9] = 0x12; |
| 1371 | - buf[10] = 0x00; | 1376 | + buf[10] = 0x08; |
| 1372 | buf[11] = 0x00; | 1377 | buf[11] = 0x00; |
| 1373 | 1378 | ||
| 1374 | buf[12] = 0x70; | 1379 | buf[12] = 0x70; |
| @@ -1582,6 +1587,50 @@ static void ide_atapi_cmd(IDEState *s) | @@ -1582,6 +1587,50 @@ static void ide_atapi_cmd(IDEState *s) | ||
| 1582 | ide_atapi_cmd_reply(s, 8, 8); | 1587 | ide_atapi_cmd_reply(s, 8, 8); |
| 1583 | } | 1588 | } |
| 1584 | break; | 1589 | break; |
| 1590 | + case GPCMD_READ_DVD_STRUCTURE: | ||
| 1591 | + { | ||
| 1592 | + int media = packet[1]; | ||
| 1593 | + int layer = packet[6]; | ||
| 1594 | + int format = packet[2]; | ||
| 1595 | + int64_t total_sectors; | ||
| 1596 | + | ||
| 1597 | + if (media != 0 || layer != 0) | ||
| 1598 | + { | ||
| 1599 | + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, | ||
| 1600 | + ASC_INV_FIELD_IN_CMD_PACKET); | ||
| 1601 | + } | ||
| 1602 | + | ||
| 1603 | + switch (format) { | ||
| 1604 | + case 0: | ||
| 1605 | + bdrv_get_geometry(s->bs, &total_sectors); | ||
| 1606 | + total_sectors >>= 2; | ||
| 1607 | + | ||
| 1608 | + memset(buf, 0, 2052); | ||
| 1609 | + | ||
| 1610 | + buf[4] = 1; // DVD-ROM, part version 1 | ||
| 1611 | + buf[5] = 0xf; // 120mm disc, maximum rate unspecified | ||
| 1612 | + buf[6] = 0; // one layer, embossed data | ||
| 1613 | + buf[7] = 0; | ||
| 1614 | + | ||
| 1615 | + cpu_to_ube32(buf + 8, 0); | ||
| 1616 | + cpu_to_ube32(buf + 12, total_sectors - 1); | ||
| 1617 | + cpu_to_ube32(buf + 16, total_sectors - 1); | ||
| 1618 | + | ||
| 1619 | + cpu_to_be16wu((uint16_t *)buf, 2048 + 4); | ||
| 1620 | + | ||
| 1621 | + ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4); | ||
| 1622 | + break; | ||
| 1623 | + | ||
| 1624 | + default: | ||
| 1625 | + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, | ||
| 1626 | + ASC_INV_FIELD_IN_CMD_PACKET); | ||
| 1627 | + break; | ||
| 1628 | + } | ||
| 1629 | + } | ||
| 1630 | + break; | ||
| 1631 | + case GPCMD_SET_SPEED: | ||
| 1632 | + ide_atapi_cmd_ok(s); | ||
| 1633 | + break; | ||
| 1585 | case GPCMD_INQUIRY: | 1634 | case GPCMD_INQUIRY: |
| 1586 | max_len = packet[4]; | 1635 | max_len = packet[4]; |
| 1587 | buf[0] = 0x05; /* CD-ROM */ | 1636 | buf[0] = 0x05; /* CD-ROM */ |
| @@ -1597,6 +1646,29 @@ static void ide_atapi_cmd(IDEState *s) | @@ -1597,6 +1646,29 @@ static void ide_atapi_cmd(IDEState *s) | ||
| 1597 | padstr8(buf + 32, 4, QEMU_VERSION); | 1646 | padstr8(buf + 32, 4, QEMU_VERSION); |
| 1598 | ide_atapi_cmd_reply(s, 36, max_len); | 1647 | ide_atapi_cmd_reply(s, 36, max_len); |
| 1599 | break; | 1648 | break; |
| 1649 | + case GPCMD_GET_CONFIGURATION: | ||
| 1650 | + { | ||
| 1651 | + int64_t total_sectors; | ||
| 1652 | + | ||
| 1653 | + /* only feature 0 is supported */ | ||
| 1654 | + if (packet[2] != 0 || packet[3] != 0) { | ||
| 1655 | + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, | ||
| 1656 | + ASC_INV_FIELD_IN_CMD_PACKET); | ||
| 1657 | + break; | ||
| 1658 | + } | ||
| 1659 | + memset(buf, 0, 32); | ||
| 1660 | + bdrv_get_geometry(s->bs, &total_sectors); | ||
| 1661 | + buf[3] = 16; | ||
| 1662 | + buf[7] = total_sectors <= 1433600 ? 0x08 : 0x10; /* current profile */ | ||
| 1663 | + buf[10] = 0x10 | 0x1; | ||
| 1664 | + buf[11] = 0x08; /* size of profile list */ | ||
| 1665 | + buf[13] = 0x10; /* DVD-ROM profile */ | ||
| 1666 | + buf[14] = buf[7] == 0x10; /* (in)active */ | ||
| 1667 | + buf[17] = 0x08; /* CD-ROM profile */ | ||
| 1668 | + buf[18] = buf[7] == 0x08; /* (in)active */ | ||
| 1669 | + ide_atapi_cmd_reply(s, 32, 32); | ||
| 1670 | + break; | ||
| 1671 | + } | ||
| 1600 | default: | 1672 | default: |
| 1601 | ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, | 1673 | ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
| 1602 | ASC_ILLEGAL_OPCODE); | 1674 | ASC_ILLEGAL_OPCODE); |