Revision 8114e9e8
b/hw/ide.c | ||
---|---|---|
351 | 351 |
#define ASC_ILLEGAL_OPCODE 0x20 |
352 | 352 |
#define ASC_LOGICAL_BLOCK_OOR 0x21 |
353 | 353 |
#define ASC_INV_FIELD_IN_CMD_PACKET 0x24 |
354 |
#define ASC_INCOMPATIBLE_FORMAT 0x30 |
|
354 | 355 |
#define ASC_MEDIUM_NOT_PRESENT 0x3a |
355 | 356 |
#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 |
356 | 357 |
|
... | ... | |
434 | 435 |
int media_changed; |
435 | 436 |
} IDEState; |
436 | 437 |
|
438 |
/* XXX: DVDs that could fit on a CD will be reported as a CD */ |
|
439 |
static inline int media_present(IDEState *s) |
|
440 |
{ |
|
441 |
return (s->nb_sectors > 0); |
|
442 |
} |
|
443 |
|
|
444 |
static inline int media_is_dvd(IDEState *s) |
|
445 |
{ |
|
446 |
return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS); |
|
447 |
} |
|
448 |
|
|
449 |
static inline int media_is_cd(IDEState *s) |
|
450 |
{ |
|
451 |
return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS); |
|
452 |
} |
|
453 |
|
|
437 | 454 |
#define BM_STATUS_DMAING 0x01 |
438 | 455 |
#define BM_STATUS_ERROR 0x02 |
439 | 456 |
#define BM_STATUS_INT 0x04 |
... | ... | |
1364 | 1381 |
return 4; |
1365 | 1382 |
} |
1366 | 1383 |
|
1384 |
static int ide_dvd_read_structure(IDEState *s, int format, |
|
1385 |
const uint8_t *packet, uint8_t *buf) |
|
1386 |
{ |
|
1387 |
switch (format) { |
|
1388 |
case 0x0: /* Physical format information */ |
|
1389 |
{ |
|
1390 |
int layer = packet[6]; |
|
1391 |
uint64_t total_sectors; |
|
1392 |
|
|
1393 |
if (layer != 0) |
|
1394 |
return -ASC_INV_FIELD_IN_CMD_PACKET; |
|
1395 |
|
|
1396 |
bdrv_get_geometry(s->bs, &total_sectors); |
|
1397 |
total_sectors >>= 2; |
|
1398 |
if (total_sectors == 0) |
|
1399 |
return -ASC_MEDIUM_NOT_PRESENT; |
|
1400 |
|
|
1401 |
buf[4] = 1; /* DVD-ROM, part version 1 */ |
|
1402 |
buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ |
|
1403 |
buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */ |
|
1404 |
buf[7] = 0; /* default densities */ |
|
1405 |
|
|
1406 |
/* FIXME: 0x30000 per spec? */ |
|
1407 |
cpu_to_ube32(buf + 8, 0); /* start sector */ |
|
1408 |
cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */ |
|
1409 |
cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */ |
|
1410 |
|
|
1411 |
/* Size of buffer, not including 2 byte size field */ |
|
1412 |
cpu_to_be16wu((uint16_t *)buf, 2048 + 2); |
|
1413 |
|
|
1414 |
/* 2k data + 4 byte header */ |
|
1415 |
return (2048 + 4); |
|
1416 |
} |
|
1417 |
|
|
1418 |
case 0x01: /* DVD copyright information */ |
|
1419 |
buf[4] = 0; /* no copyright data */ |
|
1420 |
buf[5] = 0; /* no region restrictions */ |
|
1421 |
|
|
1422 |
/* Size of buffer, not including 2 byte size field */ |
|
1423 |
cpu_to_be16wu((uint16_t *)buf, 4 + 2); |
|
1424 |
|
|
1425 |
/* 4 byte header + 4 byte data */ |
|
1426 |
return (4 + 4); |
|
1427 |
|
|
1428 |
case 0x03: /* BCA information - invalid field for no BCA info */ |
|
1429 |
return -ASC_INV_FIELD_IN_CMD_PACKET; |
|
1430 |
|
|
1431 |
case 0x04: /* DVD disc manufacturing information */ |
|
1432 |
/* Size of buffer, not including 2 byte size field */ |
|
1433 |
cpu_to_be16wu((uint16_t *)buf, 2048 + 2); |
|
1434 |
|
|
1435 |
/* 2k data + 4 byte header */ |
|
1436 |
return (2048 + 4); |
|
1437 |
|
|
1438 |
case 0xff: |
|
1439 |
/* |
|
1440 |
* This lists all the command capabilities above. Add new ones |
|
1441 |
* in order and update the length and buffer return values. |
|
1442 |
*/ |
|
1443 |
|
|
1444 |
buf[4] = 0x00; /* Physical format */ |
|
1445 |
buf[5] = 0x40; /* Not writable, is readable */ |
|
1446 |
cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4); |
|
1447 |
|
|
1448 |
buf[8] = 0x01; /* Copyright info */ |
|
1449 |
buf[9] = 0x40; /* Not writable, is readable */ |
|
1450 |
cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4); |
|
1451 |
|
|
1452 |
buf[12] = 0x03; /* BCA info */ |
|
1453 |
buf[13] = 0x40; /* Not writable, is readable */ |
|
1454 |
cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4); |
|
1455 |
|
|
1456 |
buf[16] = 0x04; /* Manufacturing info */ |
|
1457 |
buf[17] = 0x40; /* Not writable, is readable */ |
|
1458 |
cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4); |
|
1459 |
|
|
1460 |
/* Size of buffer, not including 2 byte size field */ |
|
1461 |
cpu_to_be16wu((uint16_t *)buf, 16 + 2); |
|
1462 |
|
|
1463 |
/* data written + 4 byte header */ |
|
1464 |
return (16 + 4); |
|
1465 |
|
|
1466 |
default: /* TODO: formats beyond DVD-ROM requires */ |
|
1467 |
return -ASC_INV_FIELD_IN_CMD_PACKET; |
|
1468 |
} |
|
1469 |
} |
|
1470 |
|
|
1367 | 1471 |
static void ide_atapi_cmd(IDEState *s) |
1368 | 1472 |
{ |
1369 | 1473 |
const uint8_t *packet; |
... | ... | |
1651 | 1755 |
case GPCMD_READ_DVD_STRUCTURE: |
1652 | 1756 |
{ |
1653 | 1757 |
int media = packet[1]; |
1654 |
int layer = packet[6]; |
|
1655 |
int format = packet[2]; |
|
1656 |
uint64_t total_sectors; |
|
1657 |
|
|
1658 |
if (media != 0 || layer != 0) |
|
1659 |
{ |
|
1660 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1661 |
ASC_INV_FIELD_IN_CMD_PACKET); |
|
1662 |
} |
|
1663 |
|
|
1664 |
switch (format) { |
|
1665 |
case 0: |
|
1666 |
bdrv_get_geometry(s->bs, &total_sectors); |
|
1667 |
total_sectors >>= 2; |
|
1668 |
if (total_sectors == 0) { |
|
1669 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
|
1670 |
ASC_MEDIUM_NOT_PRESENT); |
|
1671 |
break; |
|
1672 |
} |
|
1758 |
int format = packet[7]; |
|
1759 |
int ret; |
|
1673 | 1760 |
|
1674 |
memset(buf, 0, 2052);
|
|
1761 |
max_len = ube16_to_cpu(packet + 8);
|
|
1675 | 1762 |
|
1676 |
buf[4] = 1; // DVD-ROM, part version 1 |
|
1677 |
buf[5] = 0xf; // 120mm disc, maximum rate unspecified |
|
1678 |
buf[6] = 0; // one layer, embossed data |
|
1679 |
buf[7] = 0; |
|
1763 |
if (format < 0xff) { |
|
1764 |
if (media_is_cd(s)) { |
|
1765 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1766 |
ASC_INCOMPATIBLE_FORMAT); |
|
1767 |
break; |
|
1768 |
} else if (!media_present(s)) { |
|
1769 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1770 |
ASC_INV_FIELD_IN_CMD_PACKET); |
|
1771 |
break; |
|
1772 |
} |
|
1773 |
} |
|
1680 | 1774 |
|
1681 |
cpu_to_ube32(buf + 8, 0); |
|
1682 |
cpu_to_ube32(buf + 12, total_sectors - 1); |
|
1683 |
cpu_to_ube32(buf + 16, total_sectors - 1); |
|
1775 |
memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ? |
|
1776 |
IDE_DMA_BUF_SECTORS * 512 + 4 : max_len); |
|
1684 | 1777 |
|
1685 |
cpu_to_be16wu((uint16_t *)buf, 2048 + 4); |
|
1778 |
switch (format) { |
|
1779 |
case 0x00 ... 0x7f: |
|
1780 |
case 0xff: |
|
1781 |
if (media == 0) { |
|
1782 |
ret = ide_dvd_read_structure(s, format, packet, buf); |
|
1686 | 1783 |
|
1687 |
ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4); |
|
1688 |
break; |
|
1784 |
if (ret < 0) |
|
1785 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret); |
|
1786 |
else |
|
1787 |
ide_atapi_cmd_reply(s, ret, max_len); |
|
1689 | 1788 |
|
1789 |
break; |
|
1790 |
} |
|
1791 |
/* TODO: BD support, fall through for now */ |
|
1792 |
|
|
1793 |
/* Generic disk structures */ |
|
1794 |
case 0x80: /* TODO: AACS volume identifier */ |
|
1795 |
case 0x81: /* TODO: AACS media serial number */ |
|
1796 |
case 0x82: /* TODO: AACS media identifier */ |
|
1797 |
case 0x83: /* TODO: AACS media key block */ |
|
1798 |
case 0x90: /* TODO: List of recognized format layers */ |
|
1799 |
case 0xc0: /* TODO: Write protection status */ |
|
1690 | 1800 |
default: |
1691 | 1801 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
1692 | 1802 |
ASC_INV_FIELD_IN_CMD_PACKET); |
... | ... | |
1741 | 1851 |
/* |
1742 | 1852 |
* the number of sectors from the media tells us which profile |
1743 | 1853 |
* to use as current. 0 means there is no media |
1744 |
* |
|
1745 |
* XXX: fails to detect correctly DVDs with less data burned |
|
1746 |
* than what a CD can hold |
|
1747 | 1854 |
*/ |
1748 |
if (s -> nb_sectors) { |
|
1749 |
if (s -> nb_sectors > CD_MAX_SECTORS) |
|
1750 |
cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM); |
|
1751 |
else |
|
1752 |
cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM); |
|
1753 |
} |
|
1855 |
if (media_is_dvd(s)) |
|
1856 |
cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM); |
|
1857 |
else if (media_is_cd(s)) |
|
1858 |
cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM); |
|
1754 | 1859 |
|
1755 | 1860 |
buf[10] = 0x02 | 0x01; /* persistent and current */ |
1756 | 1861 |
len = 12; /* headers: 8 + 4 */ |
Also available in: Unified diff