VirtualBox

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


Ignore:
Timestamp:
Oct 22, 2014 12:13:05 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
96643
Message:

Storage/AHCI: Correct fix for r96392 (AHCI: Update HBA interrupt status register before executing the write)

File:
1 edited

Legend:

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

    r53075 r53115  
    17041704        return rc;
    17051705
    1706 #if 0 /* temporarily disabled for investigation */
    1707     /* Update interrupt status register first. */
     1706    ahci->regHbaIs &= ~(u32Value);
     1707
     1708    /*
     1709     * Update interrupt status register and check for ports who
     1710     * set the interrupt inbetween.
     1711     */
     1712    bool fClear = true;
    17081713    ahci->regHbaIs |= ASMAtomicXchgU32(&ahci->u32PortsInterrupted, 0);
    1709 #endif
    1710 
    1711     if (u32Value > 0)
    1712     {
     1714    if (!ahci->regHbaIs)
     1715    {
     1716        unsigned i = 0;
     1717
     1718        /* Check if the cleared ports have a interrupt status bit set. */
     1719        while ((u32Value > 0) && (i < AHCI_MAX_NR_PORTS_IMPL))
     1720        {
     1721            if (u32Value & 0x01)
     1722            {
     1723                PAHCIPort pAhciPort = &ahci->ahciPort[i];
     1724
     1725                if (pAhciPort->regIE & pAhciPort->regIS)
     1726                {
     1727                    Log(("%s: Interrupt status of port %u set -> Set interrupt again\n", __FUNCTION__, i));
     1728                    ASMAtomicOrU32(&ahci->u32PortsInterrupted, 1 << i);
     1729                    fClear = false;
     1730                    break;
     1731                }
     1732            }
     1733            u32Value >>= 1;
     1734            i++;
     1735        }
     1736    }
     1737    else
     1738        fClear = false;
     1739
     1740    if (fClear)
     1741        ahciHbaClearInterrupt(ahci);
     1742    else
     1743    {
     1744        Log(("%s: Not clearing interrupt: u32PortsInterrupted=%#010x\n", __FUNCTION__, ahci->u32PortsInterrupted));
    17131745        /*
    1714          * Clear the interrupt only if no port has signalled
    1715          * an interrupt and the guest has cleared all set interrupt
    1716          * notification bits.
     1746         * We need to set the interrupt again because the I/O APIC does not set it again even if the
     1747         * line is still high.
     1748         * We need to clear it first because the PCI bus only calls the interrupt controller if the state changes.
    17171749         */
    1718         bool fClear = true;
    1719 
    1720         ahci->regHbaIs &= ~(u32Value);
    1721 
    1722         fClear = !ahci->u32PortsInterrupted && !ahci->regHbaIs;
    1723         if (fClear)
    1724         {
    1725             unsigned i = 0;
    1726 
    1727             /* Check if the cleared ports have a interrupt status bit set. */
    1728             while ((u32Value > 0) && (i < AHCI_MAX_NR_PORTS_IMPL))
    1729             {
    1730                 if (u32Value & 0x01)
    1731                 {
    1732                     PAHCIPort pAhciPort = &ahci->ahciPort[i];
    1733 
    1734                     if (pAhciPort->regIE & pAhciPort->regIS)
    1735                     {
    1736                         Log(("%s: Interrupt status of port %u set -> Set interrupt again\n", __FUNCTION__, i));
    1737                         ASMAtomicOrU32(&ahci->u32PortsInterrupted, 1 << i);
    1738                         fClear = false;
    1739                         break;
    1740                     }
    1741                 }
    1742                 u32Value = u32Value >> 1;
    1743                 i++;
    1744             }
    1745         }
    1746 
    1747         if (fClear)
    1748             ahciHbaClearInterrupt(ahci);
    1749         else
    1750         {
    1751             Log(("%s: Not clearing interrupt: u32PortsInterrupted=%#010x\n", __FUNCTION__, ahci->u32PortsInterrupted));
    1752             /*
    1753              * We need to set the interrupt again because the I/O APIC does not set it again even if the
    1754              * line is still high.
    1755              * We need to clear it first because the PCI bus only calls the interrupt controller if the state changes.
    1756              */
    1757             PDMDevHlpPCISetIrq(ahci->CTX_SUFF(pDevIns), 0, 0);
    1758             PDMDevHlpPCISetIrq(ahci->CTX_SUFF(pDevIns), 0, 1);
    1759         }
     1750        PDMDevHlpPCISetIrq(ahci->CTX_SUFF(pDevIns), 0, 0);
     1751        PDMDevHlpPCISetIrq(ahci->CTX_SUFF(pDevIns), 0, 1);
    17601752    }
    17611753
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