VirtualBox

Ignore:
Timestamp:
Oct 8, 2012 4:34:11 PM (12 years ago)
Author:
vboxsync
Message:

Storage/DevATA: Use the new common code for ATAPI passthrough track list handling

File:
1 edited

Legend:

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

    r43472 r43568  
    6060#include "PIIX3ATABmDma.h"
    6161#include "ide.h"
     62#include "ATAPIPassthrough.h"
    6263#include "VBoxDD.h"
    6364
     
    305306    /** The revision string for SCSI INQUIRY commands. */
    306307    char                                szInquiryRevision[ATAPI_INQUIRY_REVISION_LENGTH+1];
    307     /** Size of the current CUE sheet in bytes. */
    308     uint32_t                            cbCueSheet;
    309     /** Align pbCueSheet correctly. */
    310     uint32_t                            u32Alignment3;
    311     /** The current CUE Sheet if passthrough is used. */
    312     R3PTRTYPE(uint8_t *)                pbCueSheet;
     308    /** The current tracklist of the loaded medium if passthrough is used. */
     309    R3PTRTYPE(PTRACKLIST)               pTrackList;
    313310
    314311    uint8_t                             abAlignment4[HC_ARCH_BITS == 64 ? 7 : 3];
     
    11611158
    11621159    return iRes;
    1163 }
    1164 
    1165 /**
    1166  * Return the correct sector size from the given LBA.
    1167  *
    1168  * @returns Sector size.
    1169  * @param   s            ATA Device state.
    1170  * @param   iATAPILBA    The LBA.
    1171  */
    1172 static size_t atapiGetSectorSizeFromLba(ATADevState *s, uint32_t iATAPILBA)
    1173 {
    1174     size_t cbATAPISector = 2048;
    1175 
    1176     /*
    1177      * Check if there is a valid CUE Sheet we can use,
    1178      * otherwise we just return the standard sector size.
    1179      */
    1180     if (s->pbCueSheet)
    1181     {
    1182         uint8_t *pbCueSheetEntry = NULL;
    1183         uint8_t iMSF[3];
    1184 
    1185         /*
    1186          * Convert the LBA to the MSF format so we can look it up in the cue sheet.
    1187          * Note that it is possible to have negative LBA values for the Lead-In area.
    1188          * See MMC6 spec chapter 6.46.3.3 for more details.
    1189          */
    1190         LogFlowFunc(("iATAPILBA=%#x (signed: %d unsigned: %u)\n",
    1191                      iATAPILBA, (int32_t)iATAPILBA, iATAPILBA));
    1192 
    1193         if (   iATAPILBA > UINT32_C(0xffff4fa1)
    1194             && (int32_t)iATAPILBA < -150)
    1195         {
    1196             /* Lead-In area, this is always the first entry in the cue sheet. */
    1197             pbCueSheetEntry = s->pbCueSheet;
    1198             LogFlowFunc(("Selected Lead-In area\n"));
    1199         }
    1200         else
    1201         {
    1202             iATAPILBA += 150;
    1203             iMSF[0] = (iATAPILBA / 75) / 60;
    1204             iMSF[1] = (iATAPILBA / 75) % 60;
    1205             iMSF[2] = iATAPILBA % 75;
    1206 
    1207             pbCueSheetEntry = s->pbCueSheet + 8; /* Start after the Lead-in track. */
    1208 
    1209             /* Go through the CUE sheet and find the correct entry. */
    1210             for (unsigned i = 0; i < (s->cbCueSheet / 8) - 2; i++)
    1211             {
    1212                 if (   atapiCmpMSF(&pbCueSheetEntry[5], iMSF) != 1
    1213                     && atapiCmpMSF(&pbCueSheetEntry[8+5], iMSF) == 1)
    1214                     break;
    1215                 pbCueSheetEntry += 8;
    1216             }
    1217             LogFlowFunc(("Selected CUE sheet entry iMin=%u iSec=%u iFrame=%u\n",
    1218                          pbCueSheetEntry[5], pbCueSheetEntry[6], pbCueSheetEntry[7]));
    1219         }
    1220 
    1221         if (pbCueSheetEntry)
    1222         {
    1223             /* Determine size of main data based on the data form field. */
    1224             switch (pbCueSheetEntry[3] & 0x3f)
    1225             {
    1226                 case 0x00: /* CD-DA with data. */
    1227                 case 0x11: /* CD-ROM mode 1 */
    1228                 case 0x13:
    1229                 case 0x21: /* CD-ROM XA, CD-I */
    1230                 case 0x23:
    1231                 case 0x31: /* CD-ROM Mode 2 */
    1232                 case 0x33:
    1233                     cbATAPISector = 2352;
    1234                     break;
    1235                 case 0x01: /* CD-DA without data (used for pauses between tracks). */
    1236                 case 0x14:
    1237                 case 0x24:
    1238                 case 0x34:
    1239                     cbATAPISector = 0;
    1240                     break;
    1241                 case 0x10: /* CD-ROM mode 1 */
    1242                 case 0x12:
    1243                     cbATAPISector = 2048;
    1244                     break;
    1245                 case 0x20: /* CD-ROM XA, CD-I */
    1246                 case 0x22:
    1247                 case 0x30: /* CD-ROM Mode 2 */
    1248                 case 0x32:
    1249                     cbATAPISector = 2336;
    1250                     break;
    1251                 default: /* Reserved, invalid mode. Log and leave default sector size. */
    1252                     LogRel(("ATA: Invalid data form mode %u for current CUE sheet\n",
    1253                             pbCueSheetEntry[3] & 0x3f));
    1254             }
    1255 
    1256             /* Determine size of sub channel data based on data form field. */
    1257             switch ((pbCueSheetEntry[3] & 0xc0) >> 6)
    1258             {
    1259                 case 0x00: /* Sub channel all zeroes, autogenerated by the drive. */
    1260                     break;
    1261                 case 0x01:
    1262                 case 0x03:
    1263                     cbATAPISector += 96;
    1264                     break;
    1265                 default:
    1266                     LogRel(("ATA: Invalid sub-channel data form mode %u for current CUE sheet\n",
    1267                             pbCueSheetEntry[3] & 0xc0));
    1268             }
    1269         }
    1270     }
    1271 
    1272     LogFlowFunc(("cbATAPISector=%zu\n", cbATAPISector));
    1273     return cbATAPISector;
    12741160}
    12751161
     
    22432129            case SCSI_SEND_CUE_SHEET:
    22442130            {
    2245                 /* Save the CUE sheet to determine sector sizes during writes */
    2246                 if (s->pbCueSheet)
    2247                 {
    2248                     s->cbCueSheet = 0;
    2249                     RTMemFree(s->pbCueSheet);
    2250                 }
    2251 
    2252                 s->pbCueSheet = (uint8_t *)RTMemAllocZ(s->cbElementaryTransfer);
    2253                 if (s->pbCueSheet)
    2254                 {
    2255                     s->cbCueSheet = s->cbElementaryTransfer;
    2256                     memcpy(s->pbCueSheet, s->CTX_SUFF(pbIOBuffer), s->cbElementaryTransfer);
    2257                 }
    2258                 else if (s->cErrors++ < MAX_LOG_REL_ERRORS)
    2259                     LogRel(("ATA: Out of memory while saving the CUE sheet, burning disc might fail\n"));
     2131                if (!s->pTrackList)
     2132                    rc = ATAPIPassthroughTrackListCreateEmpty(&s->pTrackList);
     2133
     2134                if (RT_SUCCESS(rc))
     2135                    rc = ATAPIPassthroughTrackListUpdate(s->pTrackList, s->aATAPICmd, s->CTX_SUFF(pbIOBuffer));
     2136
     2137                if (   RT_FAILURE(rc)
     2138                    && 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));
    22602141                break;
    22612142            }
    22622143            case SCSI_SYNCHRONIZE_CACHE:
    22632144            {
    2264                 /* Free the current CUE sheet after session at once recording. */
    2265                 if (s->pbCueSheet)
    2266                 {
    2267                     s->cbCueSheet = 0;
    2268                     RTMemFree(s->pbCueSheet);
    2269                     s->pbCueSheet = NULL;
    2270                 }
     2145                ATAPIPassthroughTrackListClear(s->pTrackList);
    22712146                break;
    22722147            }
     
    37733648            iATAPILBA = ataBE2H_U32(pbPacket + 2);
    37743649            cSectors = ataBE2H_U16(pbPacket + 7);
    3775             s->cbATAPISector = atapiGetSectorSizeFromLba(s, iATAPILBA);
     3650            if (s->pTrackList)
     3651                s->cbATAPISector = ATAPIPassthroughTrackListGetSectorSizeFromLba(s->pTrackList, iATAPILBA);
     3652            else
     3653                s->cbATAPISector = 2048;
    37763654            Log2(("ATAPI PT: lba %d sectors %d sector size %d\n", iATAPILBA, cSectors, s->cbATAPISector));
    37773655            cbTransfer = cSectors * s->cbATAPISector;
     
    37813659            iATAPILBA = ataBE2H_U32(pbPacket + 2);
    37823660            cSectors = ataBE2H_U32(pbPacket + 6);
    3783             s->cbATAPISector = atapiGetSectorSizeFromLba(s, iATAPILBA);
     3661            if (s->pTrackList)
     3662                s->cbATAPISector = ATAPIPassthroughTrackListGetSectorSizeFromLba(s->pTrackList, iATAPILBA);
     3663            else
     3664                s->cbATAPISector = 2048;
    37843665            Log2(("ATAPI PT: lba %d sectors %d sector size %d\n", iATAPILBA, cSectors, s->cbATAPISector));
    37853666            cbTransfer = cSectors * s->cbATAPISector;
     
    63236204        for (uint32_t iIf = 0; iIf < RT_ELEMENTS(pThis->aCts[i].aIfs); iIf++)
    63246205        {
    6325             if (pThis->aCts[i].aIfs[iIf].pbCueSheet)
     6206            if (pThis->aCts[i].aIfs[iIf].pTrackList)
    63266207            {
    6327                 RTMemFree(pThis->aCts[i].aIfs[iIf].pbCueSheet);
    6328                 pThis->aCts[i].aIfs[iIf].pbCueSheet = NULL;
     6208                ATAPIPassthroughTrackListDestroy(pThis->aCts[i].aIfs[iIf].pTrackList);
     6209                pThis->aCts[i].aIfs[iIf].pTrackList = NULL;
    63296210            }
    63306211        }
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