VirtualBox

Changeset 42393 in vbox


Ignore:
Timestamp:
Jul 25, 2012 1:47:59 PM (13 years ago)
Author:
vboxsync
Message:

AHCI: Post a PIO setup FIS for PIO data commands

File:
1 edited

Legend:

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

    r42325 r42393  
    185185#define AHCI_CMDFIS_C                     RT_BIT(7) /* Host to device. */
    186186#define AHCI_CMDFIS_I                     RT_BIT(6) /* Device to Host. */
     187#define AHCI_CMDFIS_D                     RT_BIT(5)
    187188
    188189#define AHCI_CMDFIS_CMD                   2
     
    263264/** Task encountered a buffer overflow. */
    264265#define AHCI_REQ_OVERFLOW RT_BIT_32(0)
     266/** Request is a PIO data command, if this flag is not set it either is
     267 * a command which does not transfer data or a DMA command based on the transfer size. */
     268#define AHCI_REQ_PIO_DATA RT_BIT_32(1)
    265269
    266270/**
     
    48664870
    48674871/**
     4872 * Create a PIO setup FIS and post it into the memory area of the guest.
     4873 *
     4874 * @returns nothing.
     4875 * @param   pAhciPort          The port of the SATA controller.
     4876 * @param   pAhciReq           The state of the task.
     4877 * @param   pCmdFis            Pointer to the command FIS from the guest.
     4878 * @param   fInterrupt         If an interrupt should be send to the guest.
     4879 */
     4880static void ahciSendPioSetupFis(PAHCIPort pAhciPort, PAHCIREQ pAhciReq, uint8_t *pCmdFis,
     4881                                bool fInterrupt)
     4882{
     4883    uint8_t abPioSetupFis[20];
     4884    bool fAssertIntr = false;
     4885    PAHCI pAhci = pAhciPort->CTX_SUFF(pAhci);
     4886
     4887    ahciLog(("%s: building PIO setup Fis\n", __FUNCTION__));
     4888
     4889    AssertMsg(   pAhciReq->cbTransfer > 0
     4890              && pAhciReq->cbTransfer <= 65534,
     4891              ("Can't send PIO setup FIS for requests with 0 bytes to transfer or greater than 65534\n"));
     4892
     4893    if (pAhciPort->regCMD & AHCI_PORT_CMD_FRE)
     4894    {
     4895        memset(&abPioSetupFis[0], 0, sizeof(abPioSetupFis));
     4896        abPioSetupFis[AHCI_CMDFIS_TYPE]  = AHCI_CMDFIS_TYPE_PIOSETUP;
     4897        abPioSetupFis[AHCI_CMDFIS_BITS]  = (fInterrupt ? AHCI_CMDFIS_I : 0);
     4898        if (pAhciReq->enmTxDir == AHCITXDIR_READ)
     4899            abPioSetupFis[AHCI_CMDFIS_BITS] |= AHCI_CMDFIS_D;
     4900        abPioSetupFis[AHCI_CMDFIS_STS]   = pAhciReq->uATARegStatus;
     4901        abPioSetupFis[AHCI_CMDFIS_ERR]   = pAhciReq->uATARegError;
     4902        abPioSetupFis[AHCI_CMDFIS_SECTN] = pCmdFis[AHCI_CMDFIS_SECTN];
     4903        abPioSetupFis[AHCI_CMDFIS_CYLL]  = pCmdFis[AHCI_CMDFIS_CYLL];
     4904        abPioSetupFis[AHCI_CMDFIS_CYLH]  = pCmdFis[AHCI_CMDFIS_CYLH];
     4905        abPioSetupFis[AHCI_CMDFIS_HEAD]  = pCmdFis[AHCI_CMDFIS_HEAD];
     4906        abPioSetupFis[AHCI_CMDFIS_SECTNEXP] = pCmdFis[AHCI_CMDFIS_SECTNEXP];
     4907        abPioSetupFis[AHCI_CMDFIS_CYLLEXP]  = pCmdFis[AHCI_CMDFIS_CYLLEXP];
     4908        abPioSetupFis[AHCI_CMDFIS_CYLHEXP]  = pCmdFis[AHCI_CMDFIS_CYLHEXP];
     4909        abPioSetupFis[AHCI_CMDFIS_SECTC]    = pCmdFis[AHCI_CMDFIS_SECTC];
     4910        abPioSetupFis[AHCI_CMDFIS_SECTCEXP] = pCmdFis[AHCI_CMDFIS_SECTCEXP];
     4911
     4912        /* Set transfer count. */
     4913        abPioSetupFis[16] = (pAhciReq->cbTransfer >> 8) & 0xff;
     4914        abPioSetupFis[17] = pAhciReq->cbTransfer & 0xff;
     4915
     4916        /* Update registers. */
     4917        pAhciPort->regTFD = (pAhciReq->uATARegError << 8) | pAhciReq->uATARegStatus;
     4918
     4919        ahciPostFisIntoMemory(pAhciPort, AHCI_CMDFIS_TYPE_PIOSETUP, abPioSetupFis);
     4920
     4921        if (fInterrupt)
     4922        {
     4923            ASMAtomicOrU32(&pAhciPort->regIS, AHCI_PORT_IS_PSS);
     4924            /* Check if we should assert an interrupt */
     4925            if (pAhciPort->regIE & AHCI_PORT_IE_PSE)
     4926                fAssertIntr = true;
     4927        }
     4928
     4929        if (fAssertIntr)
     4930        {
     4931            int rc = ahciHbaSetInterrupt(pAhci, pAhciPort->iLUN, VERR_IGNORED);
     4932            AssertRC(rc);
     4933        }
     4934    }
     4935}
     4936
     4937/**
    48684938 * Build a D2H FIS and post into the memory area of the guest.
    48694939 *
    48704940 * @returns Nothing
    48714941 * @param   pAhciPort          The port of the SATA controller.
    4872  * @param   pAhciReq The state of the task.
     4942 * @param   pAhciReq           The state of the task.
    48734943 * @param   pCmdFis            Pointer to the command FIS from the guest.
    48744944 * @param   fInterrupt         If an interrupt should be send to the guest.
     
    56435713            }
    56445714            else
     5715            {
     5716                /* Post a PIO setup FIS first if this is a PIO command which transfers data. */
     5717                if (pAhciReq->fFlags & AHCI_REQ_PIO_DATA)
     5718                    ahciSendPioSetupFis(pAhciPort, pAhciReq, pAhciReq->cmdFis, false /* fInterrupt */);
    56455719                ahciSendD2HFis(pAhciPort, pAhciReq, pAhciReq->cmdFis, true);
     5720            }
    56465721        }
    56475722    }
     
    57405815                                           &u16Temp[0], sizeof(u16Temp));
    57415816
     5817                pAhciReq->fFlags |= AHCI_REQ_PIO_DATA;
    57425818                pAhciReq->cbTransfer = cbCopied;
    57435819            }
     
    59526028                                           &aBuf[offLogRead], cbLogRead);
    59536029
     6030                pAhciReq->fFlags |= AHCI_REQ_PIO_DATA;
    59546031                pAhciReq->cbTransfer = cbCopied;
    59556032            }
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