VirtualBox

Changeset 18193 in vbox for trunk/src/VBox/Devices/Storage


Ignore:
Timestamp:
Mar 24, 2009 3:02:04 PM (16 years ago)
Author:
vboxsync
Message:

ATA: Implement READ DVD STRUCTURE

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r17947 r18193  
    555555static bool atapiRequestSenseSS(ATADevState *);
    556556static bool atapiPassthroughSS(ATADevState *);
     557static bool atapiReadDVDStructureSS(ATADevState *);
    557558
    558559/**
     
    610611    ATAFN_SS_ATAPI_REQUEST_SENSE,
    611612    ATAFN_SS_ATAPI_PASSTHROUGH,
     613    ATAFN_SS_ATAPI_READ_DVD_STRUCTURE,
    612614    ATAFN_SS_MAX
    613615} ATAFNSS;
     
    641643    atapiReadTrackInformationSS,
    642644    atapiRequestSenseSS,
    643     atapiPassthroughSS
     645    atapiPassthroughSS,
     646    atapiReadDVDStructureSS
    644647};
    645648
     
    20082011}
    20092012
     2013/** @todo: Revise ASAP. */
     2014static bool atapiReadDVDStructureSS(ATADevState *s)
     2015{
     2016    uint8_t *buf = s->CTX_SUFF(pbIOBuffer);
     2017    int media = s->aATAPICmd[1];
     2018    int format = s->aATAPICmd[7];
     2019
     2020    uint16_t max_len = ataBE2H_U16(&s->aATAPICmd[8]);
     2021
     2022    memset(buf, 0, max_len);
     2023
     2024    switch (format) {
     2025        case 0x00:
     2026        case 0x01:
     2027        case 0x02:
     2028        case 0x03:
     2029        case 0x04:
     2030        case 0x05:
     2031        case 0x06:
     2032        case 0x07:
     2033        case 0x08:
     2034        case 0x09:
     2035        case 0x0a:
     2036        case 0x0b:
     2037        case 0x0c:
     2038        case 0x0d:
     2039        case 0x0e:
     2040        case 0x0f:
     2041        case 0x10:
     2042        case 0x11:
     2043        case 0x30:
     2044        case 0x31:
     2045        case 0xff:
     2046            if (media == 0)
     2047            {
     2048                int uASC = SCSI_ASC_NONE;
     2049
     2050                switch (format)
     2051                {
     2052                    case 0x0: /* Physical format information */
     2053                        {
     2054                            int layer = s->aATAPICmd[6];
     2055                            uint64_t total_sectors;
     2056
     2057                            if (layer != 0)
     2058                            {
     2059                                uASC = -SCSI_ASC_INV_FIELD_IN_CMD_PACKET;
     2060                                break;
     2061                            }
     2062
     2063                            total_sectors = s->cTotalSectors;
     2064                            total_sectors >>= 2;
     2065                            if (total_sectors == 0)
     2066                            {
     2067                                uASC = -SCSI_ASC_MEDIUM_NOT_PRESENT;
     2068                                break;
     2069                            }
     2070
     2071                            buf[4] = 1;   /* DVD-ROM, part version 1 */
     2072                            buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
     2073                            buf[6] = 1;   /* one layer, read-only (per MMC-2 spec) */
     2074                            buf[7] = 0;   /* default densities */
     2075
     2076                            /* FIXME: 0x30000 per spec? */
     2077                            ataH2BE_U32(buf + 8, 0); /* start sector */
     2078                            ataH2BE_U32(buf + 12, total_sectors - 1); /* end sector */
     2079                            ataH2BE_U32(buf + 16, total_sectors - 1); /* l0 end sector */
     2080
     2081                            /* Size of buffer, not including 2 byte size field */
     2082                            ataH2BE_U32(&buf[0], 2048 + 2);
     2083
     2084                            /* 2k data + 4 byte header */
     2085                            uASC = (2048 + 4);
     2086                        }
     2087                        break;
     2088                    case 0x01: /* DVD copyright information */
     2089                        buf[4] = 0; /* no copyright data */
     2090                        buf[5] = 0; /* no region restrictions */
     2091
     2092                        /* Size of buffer, not including 2 byte size field */
     2093                        ataH2BE_U16(buf, 4 + 2);
     2094
     2095                        /* 4 byte header + 4 byte data */
     2096                        uASC = (4 + 4);
     2097
     2098                    case 0x03: /* BCA information - invalid field for no BCA info */
     2099                        uASC = -SCSI_ASC_INV_FIELD_IN_CMD_PACKET;
     2100                        break;
     2101
     2102                    case 0x04: /* DVD disc manufacturing information */
     2103                        /* Size of buffer, not including 2 byte size field */
     2104                        ataH2BE_U16(buf, 2048 + 2);
     2105
     2106                        /* 2k data + 4 byte header */
     2107                        uASC = (2048 + 4);
     2108                        break;
     2109                    case 0xff:
     2110                        /*
     2111                         * This lists all the command capabilities above.  Add new ones
     2112                         * in order and update the length and buffer return values.
     2113                         */
     2114
     2115                        buf[4] = 0x00; /* Physical format */
     2116                        buf[5] = 0x40; /* Not writable, is readable */
     2117                        ataH2BE_U16((buf + 6), 2048 + 4);
     2118
     2119                        buf[8] = 0x01; /* Copyright info */
     2120                        buf[9] = 0x40; /* Not writable, is readable */
     2121                        ataH2BE_U16((buf + 10), 4 + 4);
     2122
     2123                        buf[12] = 0x03; /* BCA info */
     2124                        buf[13] = 0x40; /* Not writable, is readable */
     2125                        ataH2BE_U16((buf + 14), 188 + 4);
     2126
     2127                        buf[16] = 0x04; /* Manufacturing info */
     2128                        buf[17] = 0x40; /* Not writable, is readable */
     2129                        ataH2BE_U16((buf + 18), 2048 + 4);
     2130
     2131                        /* Size of buffer, not including 2 byte size field */
     2132                        ataH2BE_U16(buf, 16 + 2);
     2133
     2134                        /* data written + 4 byte header */
     2135                        uASC = (16 + 4);
     2136                        break;
     2137                    default: /* TODO: formats beyond DVD-ROM requires */
     2138                        uASC = -SCSI_ASC_INV_FIELD_IN_CMD_PACKET;
     2139                }
     2140
     2141                if (uASC < 0)
     2142                {
     2143                    s->iSourceSink = ATAFN_SS_NULL;
     2144                    atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, -uASC);
     2145                    return false;
     2146                }
     2147                break;
     2148            }
     2149            /* TODO: BD support, fall through for now */
     2150
     2151        /* Generic disk structures */
     2152        case 0x80: /* TODO: AACS volume identifier */
     2153        case 0x81: /* TODO: AACS media serial number */
     2154        case 0x82: /* TODO: AACS media identifier */
     2155        case 0x83: /* TODO: AACS media key block */
     2156        case 0x90: /* TODO: List of recognized format layers */
     2157        case 0xc0: /* TODO: Write protection status */
     2158        default:
     2159            s->iSourceSink = ATAFN_SS_NULL;
     2160            atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST,
     2161                                SCSI_ASC_INV_FIELD_IN_CMD_PACKET);
     2162            return false;
     2163    }
     2164
     2165    s->iSourceSink = ATAFN_SS_NULL;
     2166    atapiCmdOK(s);
     2167    return false;
     2168}
    20102169
    20112170static bool atapiReadSectors(ATADevState *s, uint32_t iATAPILBA, uint32_t cSectors, uint32_t cbSector)
     
    28513010            ataStartTransfer(s, RT_MIN(cbMax, 36), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_INQUIRY, true);
    28523011            break;
     3012        case SCSI_READ_DVD_STRUCTURE:
     3013        {
     3014            /* Only available for ICH6 for now. */
     3015            PCIATAState *pDevice = PDMINS_2_DATA(s->CTX_SUFF(pDevIns), PCIATAState *);
     3016
     3017            if (   (PCIDevGetVendorId(&pDevice->dev) == 0x8086)
     3018                && (PCIDevGetDeviceId(&pDevice->dev) == 0x269e))
     3019            {
     3020                cbMax = ataBE2H_U16(pbPacket + 8);
     3021                ataStartTransfer(s, RT_MIN(cbMax, 4), PDMBLOCKTXDIR_FROM_DEVICE, ATAFN_BT_ATAPI_CMD, ATAFN_SS_ATAPI_READ_DVD_STRUCTURE, true);
     3022            }
     3023            else
     3024            {
     3025                atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
     3026            }
     3027            break;
     3028        }
    28533029        default:
    28543030            atapiCmdErrorSimple(s, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette