Revision 8114e9e8 hw/ide.c

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