Changeset 92345 in vbox
- Timestamp:
- Nov 11, 2021 9:07:02 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r91920 r92345 207 207 /** Currently configured number of sectors in a multi-sector transfer. */ 208 208 uint8_t cMultSectors; 209 /** P CHS disk geometry. */209 /** Physical CHS disk geometry (static). */ 210 210 PDMMEDIAGEOMETRY PCHSGeometry; 211 /** Translated CHS disk geometry (variable). */ 212 PDMMEDIAGEOMETRY XCHSGeometry; 211 213 /** Total number of sectors on this disk. */ 212 214 uint64_t cTotalSectors; … … 380 382 381 383 /** Padding the structure to a multiple of 4096 for better I/O buffer alignment. */ 382 uint8_t abAlignment4[7 + 35 44];384 uint8_t abAlignment4[7 + 3528]; 383 385 } ATADEVSTATE; 384 386 AssertCompileMemberAlignment(ATADEVSTATE, cTotalSectors, 8); … … 1359 1361 Assert(uErrorCode); 1360 1362 s->uATARegError = uErrorCode; 1361 ataSetStatusValue(pCtl, s, ATA_STAT_READY | ATA_STAT_ ERR);1363 ataSetStatusValue(pCtl, s, ATA_STAT_READY | ATA_STAT_SEEK | ATA_STAT_ERR); 1362 1364 s->cbTotalTransfer = 0; 1363 1365 s->cbElementaryTransfer = 0; … … 1416 1418 p[52] = RT_H2LE_U16(240); /* DMA transfer cycle */ 1417 1419 p[53] = RT_H2LE_U16(1 | 1 << 1 | 1 << 2); /* words 54-58,64-70,88 valid */ 1418 p[54] = RT_H2LE_U16(RT_MIN(s-> PCHSGeometry.cCylinders, 16383));1419 p[55] = RT_H2LE_U16(s-> PCHSGeometry.cHeads);1420 p[56] = RT_H2LE_U16(s-> PCHSGeometry.cSectors);1421 p[57] = RT_H2LE_U16( RT_MIN(s-> PCHSGeometry.cCylinders, 16383)1422 * s-> PCHSGeometry.cHeads1423 * s-> PCHSGeometry.cSectors);1424 p[58] = RT_H2LE_U16( RT_MIN(s-> PCHSGeometry.cCylinders, 16383)1425 * s-> PCHSGeometry.cHeads1426 * s-> PCHSGeometry.cSectors >> 16);1420 p[54] = RT_H2LE_U16(RT_MIN(s->XCHSGeometry.cCylinders, 16383)); 1421 p[55] = RT_H2LE_U16(s->XCHSGeometry.cHeads); 1422 p[56] = RT_H2LE_U16(s->XCHSGeometry.cSectors); 1423 p[57] = RT_H2LE_U16( RT_MIN(s->XCHSGeometry.cCylinders, 16383) 1424 * s->XCHSGeometry.cHeads 1425 * s->XCHSGeometry.cSectors); 1426 p[58] = RT_H2LE_U16( RT_MIN(s->XCHSGeometry.cCylinders, 16383) 1427 * s->XCHSGeometry.cHeads 1428 * s->XCHSGeometry.cSectors >> 16); 1427 1429 if (s->cMultSectors) 1428 1430 p[59] = RT_H2LE_U16(0x100 | s->cMultSectors); … … 1634 1636 { 1635 1637 /* CHS */ 1636 iLBA = (((uint32_t)s->uATARegHCyl << 8) | s->uATARegLCyl) * s-> PCHSGeometry.cHeads * s->PCHSGeometry.cSectors1637 + (s->uATARegSelect & 0x0f) * s-> PCHSGeometry.cSectors1638 iLBA = (((uint32_t)s->uATARegHCyl << 8) | s->uATARegLCyl) * s->XCHSGeometry.cHeads * s->XCHSGeometry.cSectors 1639 + (s->uATARegSelect & 0x0f) * s->XCHSGeometry.cSectors 1638 1640 + (s->uATARegSector - 1); 1639 1641 LogFlowFunc(("CHS %u/%u/%u -> LBA %llu\n", ((uint32_t)s->uATARegHCyl << 8) | s->uATARegLCyl, s->uATARegSelect & 0x0f, s->uATARegSector, iLBA)); … … 1670 1672 { 1671 1673 /* CHS */ 1672 AssertMsgReturnVoid(s-> PCHSGeometry.cHeads && s->PCHSGeometry.cSectors, ("Device geometry not set!\n"));1673 cyl = iLBA / (s-> PCHSGeometry.cHeads * s->PCHSGeometry.cSectors);1674 r = iLBA % (s-> PCHSGeometry.cHeads * s->PCHSGeometry.cSectors);1674 AssertMsgReturnVoid(s->XCHSGeometry.cHeads && s->XCHSGeometry.cSectors, ("Device geometry not set!\n")); 1675 cyl = iLBA / (s->XCHSGeometry.cHeads * s->XCHSGeometry.cSectors); 1676 r = iLBA % (s->XCHSGeometry.cHeads * s->XCHSGeometry.cSectors); 1675 1677 s->uATARegHCyl = cyl >> 8; 1676 1678 s->uATARegLCyl = cyl; 1677 s->uATARegSelect = (s->uATARegSelect & 0xf0) | ((r / s-> PCHSGeometry.cSectors) & 0x0f);1678 s->uATARegSector = (r % s-> PCHSGeometry.cSectors) + 1;1679 s->uATARegSelect = (s->uATARegSelect & 0xf0) | ((r / s->XCHSGeometry.cSectors) & 0x0f); 1680 s->uATARegSector = (r % s->XCHSGeometry.cSectors) + 1; 1679 1681 LogFlowFunc(("LBA %llu -> CHS %u/%u/%u\n", iLBA, cyl, s->uATARegSelect & 0x0f, s->uATARegSector)); 1680 1682 } … … 4136 4138 static void ataR3ResetDevice(PPDMDEVINS pDevIns, PATACONTROLLER pCtl, PATADEVSTATE s) 4137 4139 { 4140 LogFlowFunc(("\n")); 4138 4141 s->cMultSectors = ATA_MAX_MULT_SECTORS; 4139 4142 s->cNotifiedMediaChange = 0; … … 4143 4146 4144 4147 s->uATARegSelect = 0x20; 4145 ataSetStatusValue(pCtl, s, ATA_STAT_READY );4148 ataSetStatusValue(pCtl, s, ATA_STAT_READY | ATA_STAT_SEEK); 4146 4149 ataR3SetSignature(s); 4147 4150 s->cbTotalTransfer = 0; … … 4156 4159 s->uATATransferMode = ATA_MODE_UDMA | 2; /* PIIX3 supports only up to UDMA2 */ 4157 4160 4161 s->XCHSGeometry = s->PCHSGeometry; /* Restore default CHS translation. */ 4162 4158 4163 s->uATARegFeature = 0; 4159 4164 } … … 4199 4204 RT_NOREF(pDevR3); 4200 4205 LogFlowFunc(("\n")); 4201 LogRel(("ATA: LUN#%d: INITIALIZE DEVICE PARAMETERS: %u logical sectors, %u heads\n", 4202 s->iLUN, s->uATARegNSector, (s->uATARegSelect & 0x0f) + 1)); 4203 ataR3LockLeave(pDevIns, pCtl); 4204 RTThreadSleep(pCtl->msDelayIRQ); 4205 ataR3LockEnter(pDevIns, pCtl); 4206 ataR3CmdOK(pCtl, s, ATA_STAT_SEEK); 4206 4207 /* Technical Note: 4208 * On ST506 type drives with a separate controller, the INITIALIZE DRIVE PARAMETERS command was 4209 * required to inform the controller of drive geometry. The controller needed to know the 4210 * number of heads and sectors per track so that it could correctly advance to the next track 4211 * or cylinder when executing multi-sector commands. Setting a geometry that didn't match the 4212 * drive made very little sense because sectors had fixed CHS addresses. It was at best 4213 * possible to reduce the drive's capacity by limiting the number of heads and/or sectors 4214 * per track. 4215 * 4216 * IDE drives inherently have to know their true geometry, but most of them also support 4217 * programmable translation that can be set through the INITIALIZE DEVICE PARAMETERS command. 4218 * In fact most older IDE drives typically weren't operated using their default (native) geometry, 4219 * and with newer IDE drives that's not even an option. 4220 * 4221 * Up to and including ATA-5, the standard defined a CHS to LBA translation (since ATA-6, CHS 4222 * support is optional): 4223 * 4224 * LBA = (((cyl_num * heads_per_cyl) + head_num) * sectors_per_track) + sector_num - 1 4225 * 4226 * The INITIALIZE DEVICE PARAMETERS command sets the heads_per_cyl and sectors_per_track 4227 * values used in the above formula. 4228 * 4229 * Drives must obviously support an INITIALIZE DRIVE PARAMETERS command matching the drive's 4230 * default CHS translation. Everything else is optional. 4231 * 4232 * We support any geometry with non-zero sectors per track because there's no reason not to; 4233 * this behavior is common in many if not most IDE drives. 4234 */ 4235 4236 PDMMEDIAGEOMETRY Geom = { 0 }; 4237 4238 Geom.cHeads = (s->uATARegSelect & 0x0f) + 1; /* Effective range 1-16. */ 4239 Geom.cSectors = s->uATARegNSector; /* Range 0-255, zero is not valid. */ 4240 4241 if (Geom.cSectors) 4242 { 4243 uint64_t cCylinders = s->cTotalSectors / (Geom.cHeads * Geom.cSectors); 4244 Geom.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1); 4245 4246 s->XCHSGeometry = Geom; 4247 4248 ataR3LockLeave(pDevIns, pCtl); 4249 LogRel(("ATA: LUN#%d: INITIALIZE DEVICE PARAMETERS: %u sectors per track, %u heads\n", 4250 s->iLUN, s->uATARegNSector, (s->uATARegSelect & 0x0f) + 1)); 4251 RTThreadSleep(pCtl->msDelayIRQ); 4252 ataR3LockEnter(pDevIns, pCtl); 4253 ataR3CmdOK(pCtl, s, ATA_STAT_SEEK); 4254 } 4255 else 4256 { 4257 ataR3LockLeave(pDevIns, pCtl); 4258 LogRel(("ATA: LUN#%d: INITIALIZE DEVICE PARAMETERS error (zero sectors per track)!\n", s->iLUN)); 4259 RTThreadSleep(pCtl->msDelayIRQ); 4260 ataR3LockEnter(pDevIns, pCtl); 4261 ataR3CmdError(pCtl, s, ABRT_ERR); 4262 } 4207 4263 return false; 4208 4264 } … … 6961 7017 LogRel(("PIIX3 ATA: LUN#%d: TRIM enabled\n", pIf->iLUN)); 6962 7018 } 7019 /* Initialize the translated geometry. */ 7020 pIf->XCHSGeometry = pIf->PCHSGeometry; 6963 7021 6964 7022 /* … … 7205 7263 pHlp->pfnSSMPutBool(pSSM, pThis->aCts[i].aIfs[j].fIrqPending); 7206 7264 pHlp->pfnSSMPutU8(pSSM, pThis->aCts[i].aIfs[j].cMultSectors); 7207 pHlp->pfnSSMPutU32(pSSM, pThis->aCts[i].aIfs[j]. PCHSGeometry.cCylinders);7208 pHlp->pfnSSMPutU32(pSSM, pThis->aCts[i].aIfs[j]. PCHSGeometry.cHeads);7209 pHlp->pfnSSMPutU32(pSSM, pThis->aCts[i].aIfs[j]. PCHSGeometry.cSectors);7265 pHlp->pfnSSMPutU32(pSSM, pThis->aCts[i].aIfs[j].XCHSGeometry.cCylinders); 7266 pHlp->pfnSSMPutU32(pSSM, pThis->aCts[i].aIfs[j].XCHSGeometry.cHeads); 7267 pHlp->pfnSSMPutU32(pSSM, pThis->aCts[i].aIfs[j].XCHSGeometry.cSectors); 7210 7268 pHlp->pfnSSMPutU32(pSSM, pThis->aCts[i].aIfs[j].cSectorsPerIRQ); 7211 7269 pHlp->pfnSSMPutU64(pSSM, pThis->aCts[i].aIfs[j].cTotalSectors); … … 7387 7445 pHlp->pfnSSMGetBool(pSSM, &pThis->aCts[i].aIfs[j].fIrqPending); 7388 7446 pHlp->pfnSSMGetU8(pSSM, &pThis->aCts[i].aIfs[j].cMultSectors); 7389 pHlp->pfnSSMGetU32(pSSM, &pThis->aCts[i].aIfs[j]. PCHSGeometry.cCylinders);7390 pHlp->pfnSSMGetU32(pSSM, &pThis->aCts[i].aIfs[j]. PCHSGeometry.cHeads);7391 pHlp->pfnSSMGetU32(pSSM, &pThis->aCts[i].aIfs[j]. PCHSGeometry.cSectors);7447 pHlp->pfnSSMGetU32(pSSM, &pThis->aCts[i].aIfs[j].XCHSGeometry.cCylinders); 7448 pHlp->pfnSSMGetU32(pSSM, &pThis->aCts[i].aIfs[j].XCHSGeometry.cHeads); 7449 pHlp->pfnSSMGetU32(pSSM, &pThis->aCts[i].aIfs[j].XCHSGeometry.cSectors); 7392 7450 pHlp->pfnSSMGetU32(pSSM, &pThis->aCts[i].aIfs[j].cSectorsPerIRQ); 7393 7451 pHlp->pfnSSMGetU64(pSSM, &pThis->aCts[i].aIfs[j].cTotalSectors);
Note:
See TracChangeset
for help on using the changeset viewer.