- Timestamp:
- May 6, 2019 3:14:09 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r77580 r78394 1740 1740 if (RT_SUCCESS(rc)) 1741 1741 { 1742 ataR3SetSector(s, iLBA + cSectors); 1742 /* When READ SECTORS etc. finishes, the address in the task 1743 * file register points at the last sector read, not at the next 1744 * sector that would be read. This ensures the registers always 1745 * contain a valid sector address. 1746 */ 1743 1747 if (s->cbElementaryTransfer == s->cbTotalTransfer) 1748 { 1744 1749 s->iSourceSink = ATAFN_SS_NULL; 1750 ataR3SetSector(s, iLBA + cSectors - 1); 1751 } 1752 else 1753 ataR3SetSector(s, iLBA + cSectors); 1754 s->uATARegNSector -= cSectors; 1745 1755 ataR3CmdOK(s, ATA_STAT_SEEK); 1746 1756 } … … 3960 3970 ataR3LockEnter(pCtl); 3961 3971 ataR3CmdOK(s, ATA_STAT_SEEK); 3962 ataHCSetIRQ(s);3963 3972 return false; 3964 3973 } … … 3974 3983 ataR3LockEnter(pCtl); 3975 3984 ataR3CmdOK(s, ATA_STAT_SEEK); 3976 ataHCSetIRQ(s);3977 3985 return false; 3978 3986 } … … 4357 4365 * Device 1 responds to writes (except commands are not executed) but does 4358 4366 * not respond to reads. If Device 1 selected, normal behavior applies. 4359 * See ATAPI-6 clause 9.16.2 and Table 15 in clause 7.1. 4367 * See ATA-6 clause 9.16.2 and Table 15 in clause 7.1. 4368 * 4369 * Note: Task file register writes with BSY=1 and/or DRQ=1 are problematic. 4370 * Newer ATA/ATAPI specifications define that writes with BSY=0 and DRQ=1 4371 * are a "host malfunction" and ignored (see e.g. Table 15 in clause 7.1 of 4372 * the ATA-6 specification). 4373 * However, the results of writes with BSY=1 are "indeterminate", with the 4374 * sole exception of writing the DEVICE RESET command (if supported). We 4375 * choose to ignore the writes when BSY=1. 4376 * 4377 * Note: Ignoring writes to the Device/Head register when BSY=1 or DRQ=1 has the 4378 * convenient side effect that the non-selected device (if any) is guaranteed 4379 * to have BSY=0 and DRQ=0. 4360 4380 */ 4361 4381 … … 4367 4387 { 4368 4388 case 0: 4389 Assert(0); /* This handler is not used for the Data register! */ 4369 4390 break; 4370 4391 case 1: /* feature register */ … … 4410 4431 break; 4411 4432 case 6: /* drive/head */ 4433 if (pCtl->aIfs[pCtl->iAIOIf].uATARegStatus & ATA_STAT_DRQ) 4434 { 4435 Log(("DRQ=1, register write ignored!\n")); 4436 break; 4437 } 4412 4438 pCtl->aIfs[0].uATARegSelect = (val & ~0x10) | 0xa0; 4413 4439 pCtl->aIfs[1].uATARegSelect = (val | 0x10) | 0xa0; … … 4466 4492 4467 4493 4494 /* 4495 * Note: When the BSY bit is set, generally no other bits in the Status register 4496 * are valid and no other registers can be read. Newer ATA specs explicitly define 4497 * (e.g. clause 7.1, table 16 in ATA-6) that if any command block register is 4498 * read with BSY=1, the Status register contents are always returned instead. 4499 */ 4468 4500 static int ataIOPortReadU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t *pu32) 4469 4501 { … … 4502 4534 } 4503 4535 } 4536 4537 /* 4538 * If the device is busy, the Status register is always read, but when reading the 4539 * Status register proper, special semantics apply. See status register handling 4540 * with interrupt clearing and yields below. 4541 * NB: This can't happen for non-present devices as those never become busy. 4542 */ 4543 if (RT_UNLIKELY(s->uATARegStatus & ATA_STAT_BUSY)) 4544 { 4545 Assert(s->pDrvMedia); 4546 if ((addr & 7) != 7) 4547 { 4548 *pu32 = s->uATARegStatus; 4549 Log2(("%s: LUN#%d addr=%#x val=%#04x (BSY=1, returning status!)\n", __FUNCTION__, s->iLUN, addr, *pu32)); 4550 return VINF_SUCCESS; 4551 } 4552 } 4553 4504 4554 fHOB = !!(s->uATARegDevCtl & (1 << 7)); 4505 4555 switch (addr & 7) 4506 4556 { 4557 default:/* only to satisfy certain compilers, all cases are already handled */ 4507 4558 case 0: /* data register */ 4559 Assert(0); /* This handler is not used for the Data register! */ 4508 4560 val = 0xff; 4509 4561 break; … … 4552 4604 val = s->uATARegSelect; 4553 4605 break; 4554 default:4555 4606 case 7: /* primary status */ 4556 4607 {
Note:
See TracChangeset
for help on using the changeset viewer.