Changeset 43568 in vbox for trunk/src/VBox/Devices/Storage/DevATA.cpp
- Timestamp:
- Oct 8, 2012 4:34:11 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r43472 r43568 60 60 #include "PIIX3ATABmDma.h" 61 61 #include "ide.h" 62 #include "ATAPIPassthrough.h" 62 63 #include "VBoxDD.h" 63 64 … … 305 306 /** The revision string for SCSI INQUIRY commands. */ 306 307 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; 313 310 314 311 uint8_t abAlignment4[HC_ARCH_BITS == 64 ? 7 : 3]; … … 1161 1158 1162 1159 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 else1201 {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) != 11213 && 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;1274 1160 } 1275 1161 … … 2243 2129 case SCSI_SEND_CUE_SHEET: 2244 2130 { 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)); 2260 2141 break; 2261 2142 } 2262 2143 case SCSI_SYNCHRONIZE_CACHE: 2263 2144 { 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); 2271 2146 break; 2272 2147 } … … 3773 3648 iATAPILBA = ataBE2H_U32(pbPacket + 2); 3774 3649 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; 3776 3654 Log2(("ATAPI PT: lba %d sectors %d sector size %d\n", iATAPILBA, cSectors, s->cbATAPISector)); 3777 3655 cbTransfer = cSectors * s->cbATAPISector; … … 3781 3659 iATAPILBA = ataBE2H_U32(pbPacket + 2); 3782 3660 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; 3784 3665 Log2(("ATAPI PT: lba %d sectors %d sector size %d\n", iATAPILBA, cSectors, s->cbATAPISector)); 3785 3666 cbTransfer = cSectors * s->cbATAPISector; … … 6323 6204 for (uint32_t iIf = 0; iIf < RT_ELEMENTS(pThis->aCts[i].aIfs); iIf++) 6324 6205 { 6325 if (pThis->aCts[i].aIfs[iIf].p bCueSheet)6206 if (pThis->aCts[i].aIfs[iIf].pTrackList) 6326 6207 { 6327 RTMemFree(pThis->aCts[i].aIfs[iIf].pbCueSheet);6328 pThis->aCts[i].aIfs[iIf].p bCueSheet = NULL;6208 ATAPIPassthroughTrackListDestroy(pThis->aCts[i].aIfs[iIf].pTrackList); 6209 pThis->aCts[i].aIfs[iIf].pTrackList = NULL; 6329 6210 } 6330 6211 }
Note:
See TracChangeset
for help on using the changeset viewer.