Changeset 29030 in vbox for trunk/src/VBox/Devices
- Timestamp:
- May 4, 2010 2:37:26 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 61070
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r28881 r29030 463 463 */ 464 464 R3PTRTYPE(PAHCIPORTTASKSTATE) aCachedTasks[AHCI_NR_COMMAND_SLOTS]; 465 /** First task throwing an error. */ 466 R3PTRTYPE(volatile PAHCIPORTTASKSTATE) pTaskErr; 465 467 466 468 uint32_t u32Alignment5[4]; … … 3891 3893 bool fAssertIntr = false; 3892 3894 PAHCI pAhci = pAhciPort->CTX_SUFF(pAhci); 3895 PAHCIPORTTASKSTATE pTaskErr = (PAHCIPORTTASKSTATE)ASMAtomicReadPtr((void * volatile *)&pAhciPort->pTaskErr); 3893 3896 3894 3897 ahciLog(("%s: Building SDB FIS\n", __FUNCTION__)); … … 3899 3902 sdbFis[0] = AHCI_CMDFIS_TYPE_SETDEVBITS; 3900 3903 sdbFis[0] |= (fInterrupt ? (1 << 14) : 0); 3901 sdbFis[0] |= pAhciPortTaskState->uATARegError << 24; 3902 sdbFis[0] |= (pAhciPortTaskState->uATARegStatus & 0x77) << 16; /* Some bits are marked as reserved and thus are masked out. */ 3903 sdbFis[1] = uFinishedTasks; 3904 3905 ahciPostFisIntoMemory(pAhciPort, AHCI_CMDFIS_TYPE_SETDEVBITS, (uint8_t *)sdbFis); 3906 3907 if (pAhciPortTaskState->uATARegStatus & ATA_STAT_ERR) 3904 if (RT_UNLIKELY(pTaskErr)) 3905 { 3906 sdbFis[0] = pTaskErr->uATARegError; 3907 sdbFis[0] |= (pTaskErr->uATARegStatus & 0x77) << 16; /* Some bits are marked as reserved and thus are masked out. */ 3908 3909 /* Update registers. */ 3910 pAhciPort->regTFD = (pTaskErr->uATARegError << 8) | pTaskErr->uATARegStatus; 3911 } 3912 else 3913 { 3914 sdbFis[0] = 0; 3915 sdbFis[0] |= (ATA_STAT_READY | ATA_STAT_SEEK) << 16; 3916 pAhciPort->regTFD = ATA_STAT_READY | ATA_STAT_SEEK; 3917 } 3918 3919 sdbFis[1] = pAhciPort->u32QueuedTasksFinished | uFinishedTasks; 3920 3921 ahciPostFisIntoMemory(pAhciPort, AHCI_CMDFIS_TYPE_SETDEVBITS, (uint8_t *)sdbFis); 3922 3923 if (RT_UNLIKELY(pTaskErr)) 3908 3924 { 3909 3925 /* Error bit is set. */ … … 3920 3936 fAssertIntr = true; 3921 3937 } 3922 3923 /* Update registers. */3924 pAhciPort->regTFD = (pAhciPortTaskState->uATARegError << 8) | pAhciPortTaskState->uATARegStatus;3925 3938 3926 3939 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, uFinishedTasks); … … 4880 4893 pAhciPortTaskState->cbTransfer, rcReq)); 4881 4894 } 4895 ASMAtomicCmpXchgPtr((void * volatile *)&pAhciPort->pTaskErr, pAhciPortTaskState, NULL); 4882 4896 } 4883 4897 else … … 4911 4925 cOutstandingTasks = ASMAtomicDecU32(&pAhciPort->uActTasksActive); 4912 4926 ahciLog(("%s: After decrement uActTasksActive=%u\n", __FUNCTION__, cOutstandingTasks)); 4913 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, (1 << pAhciPortTaskState->uTag)); 4927 if (RT_SUCCESS(rcReq) && !ASMAtomicReadPtr((void * volatile *)&pAhciPort->pTaskErr)) 4928 ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, (1 << pAhciPortTaskState->uTag)); 4914 4929 4915 4930 #ifdef RT_STRICT … … 4918 4933 #endif 4919 4934 4920 if (!cOutstandingTasks || RT_FAILURE(rcReq))4935 if (!cOutstandingTasks) 4921 4936 ahciSendSDBFis(pAhciPort, 0, pAhciPortTaskState, true); 4922 4937 } … … 5148 5163 break; 5149 5164 } 5165 case ATA_READ_LOG_EXT: 5166 { 5167 size_t cbLogRead = ((pCmdFis[AHCI_CMDFIS_SECTCEXP] << 8) | pCmdFis[AHCI_CMDFIS_SECTC]) * 512; 5168 unsigned offLogRead = ((pCmdFis[AHCI_CMDFIS_CYLLEXP] << 8) | pCmdFis[AHCI_CMDFIS_CYLL]) * 512; 5169 unsigned iPage = pCmdFis[AHCI_CMDFIS_SECTN]; 5170 5171 LogFlow(("Trying to read %zu bytes starting at offset %u from page %u\n", cbLogRead, offLogRead, iPage)); 5172 5173 uint8_t aBuf[512]; 5174 5175 memset(aBuf, 0, sizeof(aBuf)); 5176 5177 if (offLogRead + cbLogRead <= sizeof(aBuf)) 5178 { 5179 switch (iPage) 5180 { 5181 case 0x10: 5182 { 5183 LogFlow(("Reading error page\n")); 5184 PAHCIPORTTASKSTATE pTaskErr = (PAHCIPORTTASKSTATE)ASMAtomicXchgPtr((void * volatile *)&pAhciPort->pTaskErr, NULL); 5185 if (pTaskErr) 5186 { 5187 aBuf[0] = pTaskErr->fQueued ? (1 << 7) | pTaskErr->uTag : 0; 5188 aBuf[2] = pTaskErr->uATARegStatus; 5189 aBuf[3] = pTaskErr->uATARegError; 5190 aBuf[4] = pTaskErr->cmdFis[AHCI_CMDFIS_SECTN]; 5191 aBuf[5] = pTaskErr->cmdFis[AHCI_CMDFIS_CYLL]; 5192 aBuf[6] = pTaskErr->cmdFis[AHCI_CMDFIS_CYLH]; 5193 aBuf[7] = pTaskErr->cmdFis[AHCI_CMDFIS_HEAD]; 5194 aBuf[8] = pTaskErr->cmdFis[AHCI_CMDFIS_SECTNEXP]; 5195 aBuf[9] = pTaskErr->cmdFis[AHCI_CMDFIS_CYLLEXP]; 5196 aBuf[10] = pTaskErr->cmdFis[AHCI_CMDFIS_CYLHEXP]; 5197 aBuf[12] = pTaskErr->cmdFis[AHCI_CMDFIS_SECTC]; 5198 aBuf[13] = pTaskErr->cmdFis[AHCI_CMDFIS_SECTCEXP]; 5199 5200 /* Calculate checksum */ 5201 uint8_t uChkSum = 0; 5202 for (unsigned i = 0; i < RT_ELEMENTS(aBuf)-1; i++) 5203 uChkSum += aBuf[i]; 5204 5205 aBuf[511] = ~uChkSum; 5206 } 5207 break; 5208 } 5209 } 5210 5211 /* Create scatter gather list. */ 5212 int rc2 = ahciScatterGatherListCreate(pAhciPort, pAhciPortTaskState, false); 5213 if (RT_FAILURE(rc2)) 5214 AssertMsgFailed(("Creating list failed rc=%Rrc\n", rc2)); 5215 5216 /* Copy the buffer. */ 5217 pCmdHdr->u32PRDBC = ahciScatterGatherListCopyFromBuffer(pAhciPortTaskState, &aBuf[offLogRead], cbLogRead); 5218 5219 /* Destroy list. */ 5220 rc2 = ahciScatterGatherListDestroy(pAhciPort, pAhciPortTaskState); 5221 if (RT_FAILURE(rc2)) 5222 AssertMsgFailed(("Freeing list failed rc=%Rrc\n", rc2)); 5223 5224 pAhciPortTaskState->uATARegError = 0; 5225 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK; 5226 5227 /* Write updated command header into memory of the guest. */ 5228 PDMDevHlpPhysWrite(pAhciPort->CTX_SUFF(pDevIns), pAhciPortTaskState->GCPhysCmdHdrAddr, pCmdHdr, sizeof(CmdHdr)); 5229 } 5230 5231 break; 5232 } 5150 5233 /* All not implemented commands go below. */ 5151 5234 case ATA_SECURITY_FREEZE_LOCK: 5152 5235 case ATA_SMART: 5153 5236 case ATA_NV_CACHE: 5154 case ATA_READ_LOG_EXT:5155 5237 pAhciPortTaskState->uATARegError = ABRT_ERR; 5156 5238 pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR;
Note:
See TracChangeset
for help on using the changeset viewer.