VirtualBox

Changeset 29030 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
May 4, 2010 2:37:26 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
61070
Message:

AHCI: Implement missing error reporting bits

File:
1 edited

Legend:

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

    r28881 r29030  
    463463     */
    464464    R3PTRTYPE(PAHCIPORTTASKSTATE)   aCachedTasks[AHCI_NR_COMMAND_SLOTS];
     465    /** First task throwing an error. */
     466    R3PTRTYPE(volatile PAHCIPORTTASKSTATE) pTaskErr;
    465467
    466468    uint32_t                        u32Alignment5[4];
     
    38913893    bool fAssertIntr = false;
    38923894    PAHCI pAhci = pAhciPort->CTX_SUFF(pAhci);
     3895    PAHCIPORTTASKSTATE pTaskErr = (PAHCIPORTTASKSTATE)ASMAtomicReadPtr((void * volatile *)&pAhciPort->pTaskErr);
    38933896
    38943897    ahciLog(("%s: Building SDB FIS\n", __FUNCTION__));
     
    38993902        sdbFis[0] = AHCI_CMDFIS_TYPE_SETDEVBITS;
    39003903        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))
    39083924        {
    39093925            /* Error bit is set. */
     
    39203936                fAssertIntr = true;
    39213937        }
    3922 
    3923         /* Update registers. */
    3924         pAhciPort->regTFD = (pAhciPortTaskState->uATARegError << 8) | pAhciPortTaskState->uATARegStatus;
    39253938
    39263939        ASMAtomicOrU32(&pAhciPort->u32QueuedTasksFinished, uFinishedTasks);
     
    48804893                        pAhciPortTaskState->cbTransfer, rcReq));
    48814894        }
     4895        ASMAtomicCmpXchgPtr((void * volatile *)&pAhciPort->pTaskErr, pAhciPortTaskState, NULL);
    48824896    }
    48834897    else
     
    49114925        cOutstandingTasks = ASMAtomicDecU32(&pAhciPort->uActTasksActive);
    49124926        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));
    49144929
    49154930#ifdef RT_STRICT
     
    49184933#endif
    49194934
    4920         if (!cOutstandingTasks || RT_FAILURE(rcReq))
     4935        if (!cOutstandingTasks)
    49214936            ahciSendSDBFis(pAhciPort, 0, pAhciPortTaskState, true);
    49224937    }
     
    51485163            break;
    51495164        }
     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        }
    51505233        /* All not implemented commands go below. */
    51515234        case ATA_SECURITY_FREEZE_LOCK:
    51525235        case ATA_SMART:
    51535236        case ATA_NV_CACHE:
    5154         case ATA_READ_LOG_EXT:
    51555237            pAhciPortTaskState->uATARegError = ABRT_ERR;
    51565238            pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_ERR;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette