Revision d14049ea
b/hw/ide.c | ||
---|---|---|
261 | 261 |
* older drives only. |
262 | 262 |
*/ |
263 | 263 |
#define GPCMD_GET_MEDIA_STATUS 0xda |
264 |
#define GPCMD_MODE_SENSE_6 0x1a |
|
264 | 265 |
|
265 | 266 |
/* Mode page codes for mode sense/set */ |
266 | 267 |
#define GPMODE_R_W_ERROR_PAGE 0x01 |
... | ... | |
1329 | 1330 |
ASC_MEDIUM_NOT_PRESENT); |
1330 | 1331 |
} |
1331 | 1332 |
break; |
1333 |
case GPCMD_MODE_SENSE_6: |
|
1332 | 1334 |
case GPCMD_MODE_SENSE_10: |
1333 | 1335 |
{ |
1334 | 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 | 1341 |
action = packet[2] >> 6; |
1337 | 1342 |
code = packet[2] & 0x3f; |
1338 | 1343 |
switch(action) { |
... | ... | |
1368 | 1373 |
|
1369 | 1374 |
buf[8] = 0x2a; |
1370 | 1375 |
buf[9] = 0x12; |
1371 |
buf[10] = 0x00;
|
|
1376 |
buf[10] = 0x08;
|
|
1372 | 1377 |
buf[11] = 0x00; |
1373 | 1378 |
|
1374 | 1379 |
buf[12] = 0x70; |
... | ... | |
1582 | 1587 |
ide_atapi_cmd_reply(s, 8, 8); |
1583 | 1588 |
} |
1584 | 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 | 1634 |
case GPCMD_INQUIRY: |
1586 | 1635 |
max_len = packet[4]; |
1587 | 1636 |
buf[0] = 0x05; /* CD-ROM */ |
... | ... | |
1597 | 1646 |
padstr8(buf + 32, 4, QEMU_VERSION); |
1598 | 1647 |
ide_atapi_cmd_reply(s, 36, max_len); |
1599 | 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 | 1672 |
default: |
1601 | 1673 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
1602 | 1674 |
ASC_ILLEGAL_OPCODE); |
Also available in: Unified diff