VirtualBox

Changeset 34851 in vbox for trunk/src/VBox/Devices/Storage


Ignore:
Timestamp:
Dec 9, 2010 12:45:04 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
68664
Message:

AHCI: Fix ATAPI device detection with Solaris guests. The command shouldn't be cleared in the CI register if it failed. The controller should stop processing commands instead to preserve the CCS field in the CMD register and the bits in CI

File:
1 edited

Legend:

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

    r34433 r34851  
    6464
    6565/** The current saved state version. */
    66 #define AHCI_SAVED_STATE_VERSION                4
     66#define AHCI_SAVED_STATE_VERSION                5
    6767/** Saved state version before ATAPI support was added. */
    6868#define AHCI_SAVED_STATE_VERSION_PRE_ATAPI      3
     
    440440    volatile uint32_t               u32TasksNew;
    441441
     442    /** Current command slot processed.
     443     * Accessed by the guest by reading the CMD register.
     444     * Holds the command slot of the command processed at the moment. */
     445    volatile uint32_t               u32CurrentCommandSlot;
     446
     447#if HC_ARCH_BITS == 64
     448    uint32_t                        u32Alignment2;
     449#endif
     450
    442451    /** Device specific settings (R3 only stuff). */
    443452    /** Pointer to the attached driver's base interface. */
     
    480489    R3PTRTYPE(volatile PAHCIPORTTASKSTATE) pTaskErr;
    481490
     491#if HC_ARCH_BITS == 32
     492    uint32_t                        u32Alignment4;
     493#endif
     494
    482495    /** Release statistics: number of DMA commands. */
    483496    STAMCOUNTER                     StatDMA;
     
    514527    uint32_t                        cErrors;
    515528
    516     uint32_t                        u32Alignment4;
     529    uint32_t                        u32Alignment5;
    517530} AHCIPort;
    518531/** Pointer to the state of an AHCI port. */
     
    12321245             (pAhciPort->regCMD & AHCI_PORT_CMD_PMA) >> 17, (pAhciPort->regCMD & AHCI_PORT_CMD_CPS) >> 16,
    12331246             (pAhciPort->regCMD & AHCI_PORT_CMD_CR) >> 15, (pAhciPort->regCMD & AHCI_PORT_CMD_FR) >> 14,
    1234              (pAhciPort->regCMD & AHCI_PORT_CMD_ISS) >> 13, (pAhciPort->regCMD & AHCI_PORT_CMD_CCS) >> 8,
     1247             (pAhciPort->regCMD & AHCI_PORT_CMD_ISS) >> 13, pAhciPort->u32CurrentCommandSlot,
    12351248             (pAhciPort->regCMD & AHCI_PORT_CMD_FRE) >> 4, (pAhciPort->regCMD & AHCI_PORT_CMD_CLO) >> 3,
    12361249             (pAhciPort->regCMD & AHCI_PORT_CMD_POD) >> 2, (pAhciPort->regCMD & AHCI_PORT_CMD_SUD) >> 1,
    12371250             (pAhciPort->regCMD & AHCI_PORT_CMD_ST)));
    1238     *pu32Value = pAhciPort->regCMD;
     1251    *pu32Value = pAhciPort->regCMD | AHCI_PORT_CMD_CCS_SHIFT(pAhciPort->u32CurrentCommandSlot);
    12391252    return VINF_SUCCESS;
    12401253}
     
    12821295            pAhciPort->regCI = 0;
    12831296            /** Clear current command slot. */
    1284             u32Value &= ~(AHCI_PORT_CMD_CCS_SHIFT(0xff));
     1297            pAhciPort->u32CurrentCommandSlot = 0;
    12851298            u32Value &= ~AHCI_PORT_CMD_CR;
    12861299        }
     
    18741887    pAhciPort->u32TasksFinished = 0;
    18751888    pAhciPort->u32QueuedTasksFinished = 0;
     1889    pAhciPort->u32CurrentCommandSlot = 0;
    18761890
    18771891    pAhciPort->cTasksActive = 0;
     
    45614575            if (pAhciPort->regIE & AHCI_PORT_IE_TFEE)
    45624576                fAssertIntr = true;
     4577            /*
     4578             * Don't mark the command slot as completed because the guest
     4579             * needs it to identify the failed command.
     4580             */
    45634581        }
    4564 
    4565         if (fInterrupt)
     4582        else if (fInterrupt)
    45664583        {
    45674584            ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_DHRS);
     
    45694586            if (pAhciPort->regIE & AHCI_PORT_IE_DHRE)
    45704587                fAssertIntr = true;
     4588
     4589            /* Mark command as completed. */
     4590            ASMAtomicOrU32(&pAhciPort->u32TasksFinished, (1 << pAhciPortTaskState->uTag));
    45714591        }
    4572 
    4573         ASMAtomicOrU32(&pAhciPort->u32TasksFinished, (1 << pAhciPortTaskState->uTag));
    45744592
    45754593        if (fAssertIntr)
     
    57955813                {
    57965814                    pAhciPortTaskState->uATARegError = ABRT_ERR;
    5797                     pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK;
     5815                    pAhciPortTaskState->uATARegStatus = ATA_STAT_READY | ATA_STAT_SEEK  | ATA_STAT_ERR;
    57985816                }
    57995817                break;
     
    61776195            /* Set current command slot */
    61786196            pAhciPortTaskState->uTag = idx;
    6179             pAhciPort->regCMD |= (AHCI_PORT_CMD_CCS_SHIFT(pAhciPortTaskState->uTag));
     6197            ASMAtomicWriteU32(&pAhciPort->u32CurrentCommandSlot, pAhciPortTaskState->uTag);
    61806198
    61816199            ahciPortTaskGetCommandFis(pAhciPort, pAhciPortTaskState);
     
    63596377
    63606378            /* Set current command slot */
    6361             pAhciPort->regCMD |= (AHCI_PORT_CMD_CCS_SHIFT(pAhciPortTaskState->uTag));
     6379            ASMAtomicWriteU32(&pAhciPort->u32CurrentCommandSlot, pAhciPortTaskState->uTag);
    63626380
    63636381            /* Mark the task as processed by the HBA if this is a queued task so that it doesn't occur in the CI register anymore. */
     
    68546872        SSMR3PutU8(pSSM, pThis->ahciPort[i].uATATransferMode);
    68556873        SSMR3PutBool(pSSM, pThis->ahciPort[i].fResetDevice);
    6856 
    6857         /* No need to save but to avoid changing the SSM format they are still written. */
    6858         SSMR3PutU8(pSSM, 0); /* Prev: Write position in the FIFO. */
    6859         SSMR3PutU8(pSSM, 0); /* Prev: Read position in the FIFO. */
    6860 
    68616874        SSMR3PutBool(pSSM, pThis->ahciPort[i].fPoweredOn);
    68626875        SSMR3PutBool(pSSM, pThis->ahciPort[i].fSpunUp);
    68636876        SSMR3PutU32(pSSM, pThis->ahciPort[i].u32TasksFinished);
    68646877        SSMR3PutU32(pSSM, pThis->ahciPort[i].u32QueuedTasksFinished);
     6878        SSMR3PutU32(pSSM, pThis->ahciPort[i].u32CurrentCommandSlot);
    68656879
    68666880        /* ATAPI saved state. */
     
    69917005        for (uint32_t i = 0; i < AHCI_MAX_NR_PORTS_IMPL; i++)
    69927006        {
    6993             uint8_t u8;
    69947007            PAHCIPort pAhciPort = &pThis->ahciPort[i];
    69957008
     
    70217034                SSMR3Skip(pSSM, AHCI_NR_COMMAND_SLOTS * sizeof(uint8_t)); /* no active data here */
    70227035
    7023             SSMR3GetU8(pSSM, &u8);
    7024             SSMR3GetU8(pSSM, &u8);
     7036            if (uVersion <= AHCI_SAVED_STATE_VERSION)
     7037            {
     7038                /* The old positions in the FIFO, not required. */
     7039                SSMR3Skip(pSSM, 2*sizeof(uint8_t));
     7040            }
    70257041            SSMR3GetBool(pSSM, &pThis->ahciPort[i].fPoweredOn);
    70267042            SSMR3GetBool(pSSM, &pThis->ahciPort[i].fSpunUp);
    70277043            SSMR3GetU32(pSSM, (uint32_t *)&pThis->ahciPort[i].u32TasksFinished);
    70287044            SSMR3GetU32(pSSM, (uint32_t *)&pThis->ahciPort[i].u32QueuedTasksFinished);
     7045            SSMR3GetU32(pSSM, (uint32_t *)&pThis->ahciPort[i].u32CurrentCommandSlot);
    70297046
    70307047            if (uVersion > AHCI_SAVED_STATE_VERSION_PRE_ATAPI)
Note: See TracChangeset for help on using the changeset viewer.

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