VirtualBox

Changeset 43572 in vbox for trunk/src


Ignore:
Timestamp:
Oct 8, 2012 5:47:04 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
81216
Message:

Storage/ATAPIPassthrough: Make it possible to read multisession media

Location:
trunk/src/VBox/Devices/Storage
Files:
2 edited

Legend:

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

    r43567 r43572  
    3333/** The track is the lead out track of the medium. */
    3434#define TRACK_FLAGS_LEAD_OUT     RT_BIT_32(2)
     35
     36/** Don't clear already detected tracks on the medium. */
     37#define ATAPI_TRACK_LIST_REALLOCATE_FLAGS_DONT_CLEAR RT_BIT_32(0)
    3538
    3639/**
     
    136139 * @param   pTrackList    The track list to reallocate.
    137140 * @param   cTracks       Number of tracks the list must be able to hold.
    138  */
    139 static int atapiTrackListReallocate(PTRACKLIST pTrackList, unsigned cTracks)
     141 * @param   fFlags        Flags for the reallocation.
     142 */
     143static int atapiTrackListReallocate(PTRACKLIST pTrackList, unsigned cTracks, uint32_t fFlags)
    140144{
    141145    int rc = VINF_SUCCESS;
    142146
    143     ATAPIPassthroughTrackListClear(pTrackList);
     147    if (!(fFlags & ATAPI_TRACK_LIST_REALLOCATE_FLAGS_DONT_CLEAR))
     148        ATAPIPassthroughTrackListClear(pTrackList);
    144149
    145150    if (pTrackList->cTracksMax < cTracks)
     
    172177 * @param   pbCueSheetEntry    CUE sheet entry to use.
    173178 */
    174 static void atapiTrackListEntryCreateFromCueSheetEntry(PTRACK pTrack, uint8_t *pbCueSheetEntry)
     179static void atapiTrackListEntryCreateFromCueSheetEntry(PTRACK pTrack, const uint8_t *pbCueSheetEntry)
    175180{
    176181    TRACKDATAFORM enmTrackDataForm = TRACKDATAFORM_INVALID;
     
    264269 * @param   pvBuf         The CUE sheet.
    265270 */
    266 static int atapiTrackListUpdateFromSendCueSheet(PTRACKLIST pTrackList, uint8_t *pbCDB, void *pvBuf)
     271static int atapiTrackListUpdateFromSendCueSheet(PTRACKLIST pTrackList, const uint8_t *pbCDB, const void *pvBuf)
    267272{
    268273    int rc = VINF_SUCCESS;
     
    272277    AssertReturn(cbCueSheet % 8 == 0 && cTracks, VERR_INVALID_PARAMETER);
    273278
    274     rc = atapiTrackListReallocate(pTrackList, cTracks);
     279    rc = atapiTrackListReallocate(pTrackList, cTracks, 0);
    275280    if (RT_SUCCESS(rc))
    276281    {
    277         uint8_t *pbCueSheet = (uint8_t *)pvBuf;
     282        const uint8_t *pbCueSheet = (uint8_t *)pvBuf;
    278283        PTRACK pTrack = pTrackList->paTracks;
    279284
     
    291296}
    292297
    293 static int atapiTrackListUpdateFromSendDvdStructure(PTRACKLIST pTrackList, uint8_t *pbCDB, void *pvBuf)
     298static int atapiTrackListUpdateFromSendDvdStructure(PTRACKLIST pTrackList, const uint8_t *pbCDB, const void *pvBuf)
    294299{
    295300    return VERR_NOT_IMPLEMENTED;
    296301}
    297302
    298 static int atapiTrackListUpdateFromReadTocPmaAtip(PTRACKLIST pTrackList, uint8_t *pbCDB, void *pvBuf)
     303/**
     304 * Update track list from formatted TOC data.
     305 *
     306 * @returns VBox status code.
     307 * @param   pTrackList    The track list to update.
     308 * @param   fMSF          Flag whether block addresses are in MSF or LBA format.
     309 * @param   pbBuf         Buffer holding the formatted TOC.
     310 * @param   cbBuffer      Size of the buffer.
     311 */
     312static int atapiTrackListUpdateFromFormattedToc(PTRACKLIST pTrackList, uint8_t iTrack,
     313                                                bool fMSF, const uint8_t *pbBuf, size_t cbBuffer)
     314{
     315    int rc = VINF_SUCCESS;
     316    size_t cbToc = atapiBE2H_U16(pbBuf);
     317    uint8_t iTrackFirst = pbBuf[2];
     318    unsigned cTracks;
     319
     320    cbToc -= 2;
     321    pbBuf += 4;
     322    AssertReturn(cbToc % 8 == 0, VERR_INVALID_PARAMETER);
     323
     324    cTracks = cbToc / 8 + iTrackFirst;
     325
     326    rc = atapiTrackListReallocate(pTrackList, cTracks, ATAPI_TRACK_LIST_REALLOCATE_FLAGS_DONT_CLEAR);
     327    if (RT_SUCCESS(rc))
     328    {
     329        PTRACK pTrack = &pTrackList->paTracks[iTrackFirst];
     330
     331        for (unsigned i = iTrackFirst; i < cTracks; i++)
     332        {
     333            if (pbBuf[1] & 0x4)
     334                pTrack->enmMainDataForm = TRACKDATAFORM_MODE1_2048;
     335            else
     336                pTrack->enmMainDataForm = TRACKDATAFORM_CDDA;
     337
     338            pTrack->enmSubChnDataForm = SUBCHNDATAFORM_0;
     339            if (fMSF)
     340                pTrack->iLbaStart = atapiMSF2LBA(&pbBuf[4]);
     341            else
     342                pTrack->iLbaStart = atapiBE2H_U32(&pbBuf[4]);
     343
     344            if (pbBuf[2] != 0xaa)
     345            {
     346                /* Calculate number of sectors from the next entry. */
     347                int64_t iLbaNext;
     348
     349                if (fMSF)
     350                    iLbaNext = atapiMSF2LBA(&pbBuf[4+8]);
     351                else
     352                    iLbaNext = atapiBE2H_U32(&pbBuf[4+8]);
     353
     354                pTrack->cSectors = iLbaNext - pTrack->iLbaStart;
     355            }
     356            else
     357                pTrack->cSectors = 0;
     358
     359            pTrack->fFlags &= ~TRACK_FLAGS_UNDETECTED;
     360            pbBuf += 8;
     361        }
     362    }
     363
     364    return rc;
     365}
     366
     367static int atapiTrackListUpdateFromReadTocPmaAtip(PTRACKLIST pTrackList, const uint8_t *pbCDB, const void *pvBuf)
     368{
     369    int rc = VINF_SUCCESS;
     370    size_t cbBuffer = atapiBE2H_U16(&pbCDB[7]);
     371    bool fMSF = (pbCDB[1] & 0x2) != 0;
     372    uint8_t uFmt = pbCDB[2] & 0xf;
     373    uint8_t iTrack = pbCDB[6];
     374
     375    switch (uFmt)
     376    {
     377        case 0x00:
     378            rc = atapiTrackListUpdateFromFormattedToc(pTrackList, iTrack, fMSF, (uint8_t *)pvBuf, cbBuffer);
     379            break;
     380        case 0x01:
     381        case 0x02:
     382        case 0x03:
     383        case 0x04:
     384        case 0x05:
     385        default:
     386            rc = VERR_INVALID_PARAMETER;
     387    }
     388
     389    return rc;
     390}
     391
     392static int atapiTrackListUpdateFromReadTrackInformation(PTRACKLIST pTrackList, const uint8_t *pbCDB, const void *pvBuf)
    299393{
    300394    return VERR_NOT_IMPLEMENTED;
    301395}
    302396
    303 static int atapiTrackListUpdateFromReadTrackInformation(PTRACKLIST pTrackList, uint8_t *pbCDB, void *pvBuf)
     397static int atapiTrackListUpdateFromReadDvdStructure(PTRACKLIST pTrackList, const uint8_t *pbCDB, const void *pvBuf)
    304398{
    305399    return VERR_NOT_IMPLEMENTED;
    306400}
    307401
    308 static int atapiTrackListUpdateFromReadDvdStructure(PTRACKLIST pTrackList, uint8_t *pbCDB, void *pvBuf)
    309 {
    310     return VERR_NOT_IMPLEMENTED;
    311 }
    312 
    313 static int atapiTrackListUpdateFromReadDiscInformation(PTRACKLIST pTrackList, uint8_t *pbCDB, void *pvBuf)
     402static int atapiTrackListUpdateFromReadDiscInformation(PTRACKLIST pTrackList, const uint8_t *pbCDB, const void *pvBuf)
    314403{
    315404    return VERR_NOT_IMPLEMENTED;
     
    426515}
    427516
    428 DECLHIDDEN(int) ATAPIPassthroughTrackListUpdate(PTRACKLIST pTrackList, uint8_t *pbCDB, void *pvBuf)
     517DECLHIDDEN(int) ATAPIPassthroughTrackListUpdate(PTRACKLIST pTrackList, const uint8_t *pbCDB, const void *pvBuf)
    429518{
    430519    int rc = VINF_SUCCESS;
     
    455544    }
    456545
     546#ifdef LOG_ENABLED
    457547    atapiTrackListDump(pTrackList);
     548#endif
    458549
    459550    return rc;
  • trunk/src/VBox/Devices/Storage/DevATA.cpp

    r43571 r43572  
    102102/* Media track type */
    103103#define ATA_MEDIA_TYPE_UNKNOWN                  0    /**< unknown CD type */
    104 #define ATA_MEDIA_TYPE_DATA                     1    /**< Data CD */
    105 #define ATA_MEDIA_TYPE_CDDA                     2    /**< CD-DA  (audio) CD type */
    106104#define ATA_MEDIA_NO_DISC                    0x70    /**< Door closed, no medium */
    107105
     
    21282126        {
    21292127            case SCSI_SEND_CUE_SHEET:
     2128            case SCSI_READ_TOC_PMA_ATIP:
    21302129            {
    21312130                if (!s->pTrackList)
     
    21372136                if (   RT_FAILURE(rc)
    21382137                    && s->cErrors++ < MAX_LOG_REL_ERRORS)
    2139                     LogRel(("ATA: Error (%Rrc) while updating the tracklist during SEND CUE SHEET, burning the disc might fail\n",
    2140                             rc));
     2138                    LogRel(("ATA: Error (%Rrc) while updating the tracklist during %s, burning the disc might fail\n",
     2139                            rc, s->aATAPICmd[0] == SCSI_SEND_CUE_SHEET ? "SEND CUE SHEET" : "READ TOC/PMA/ATIP"));
    21412140                break;
    21422141            }
     
    21692168                ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 32, "1.0", 4);
    21702169            }
    2171             else if (   s->aATAPICmd[0] == SCSI_READ_TOC_PMA_ATIP
    2172                      && (s->aATAPICmd[2] & 0xf) != 0x05
    2173                      && s->aATAPICmd[6] != 0xaa)
    2174             {
    2175                 /* Set the media type if we can detect it. */
    2176                 uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
    2177 
    2178                 /** @todo: Implemented only for formatted TOC now. */
    2179                 if (   (s->aATAPICmd[2] & 0xf) == 0
    2180                     && cbTransfer >= 6)
    2181                 {
    2182                     uint32_t NewMediaType;
    2183                     uint32_t OldMediaType;
    2184 
    2185                     if (pbBuf[5] & 0x4)
    2186                         NewMediaType = ATA_MEDIA_TYPE_DATA;
    2187                     else
    2188                         NewMediaType = ATA_MEDIA_TYPE_CDDA;
    2189 
    2190                     OldMediaType = ataMediumTypeSet(s, NewMediaType);
    2191 
    2192                     if (OldMediaType != NewMediaType)
    2193                         LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough, detected %s CD\n",
    2194                                 s->iLUN,
    2195                                 NewMediaType == ATA_MEDIA_TYPE_DATA
    2196                                 ? "data"
    2197                                 : "audio"));
    2198                 }
    2199                 else /* Play safe and set to unknown. */
    2200                     ataMediumTypeSet(s, ATA_MEDIA_TYPE_UNKNOWN);
    2201             }
     2170
    22022171            if (cbTransfer)
    22032172                Log3(("ATAPI PT data read (%d): %.*Rhxs\n", cbTransfer, cbTransfer, s->CTX_SUFF(pbIOBuffer)));
     
    35243493            {
    35253494                case 0x0: /* All types. */
    3526                     if (ASMAtomicReadU32(&s->MediaTrackType) == ATA_MEDIA_TYPE_CDDA)
    3527                         s->cbATAPISector = 2352;
     3495                {
     3496                    uint32_t iLbaStart;
     3497
     3498                    if (pbPacket[0] == SCSI_READ_CD)
     3499                        iLbaStart = ataBE2H_U32(&pbPacket[2]);
     3500                    else
     3501                        iLbaStart = ataMSF2LBA(&pbPacket[3]);
     3502
     3503                    if (s->pTrackList)
     3504                        s->cbATAPISector = ATAPIPassthroughTrackListGetSectorSizeFromLba(s->pTrackList, iLbaStart);
    35283505                    else
    35293506                        s->cbATAPISector = 2048; /* Might be incorrect if we couldn't determine the type. */
    35303507                    break;
     3508                }
    35313509                case 0x1: /* CD-DA */
    35323510                    s->cbATAPISector = 2352;
Note: See TracChangeset for help on using the changeset viewer.

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