VirtualBox

Changeset 56426 in vbox


Ignore:
Timestamp:
Jun 15, 2015 11:12:18 AM (10 years ago)
Author:
vboxsync
Message:

Storage/VBoxSCSI: Fix write support regression and cleanup saved state handling, moving it to a single place instead of doing it in the device emulation

Location:
trunk/src/VBox/Devices/Storage
Files:
4 edited

Legend:

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

    r56413 r56426  
    32193219    SSMR3PutBool  (pSSM, pBusLogic->fStrictRoundRobinMode);
    32203220    SSMR3PutBool  (pSSM, pBusLogic->fExtendedLunCCBFormat);
    3221     /* Now the data for the BIOS interface. */
    3222     SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.regIdentify);
    3223     SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.uTargetDevice);
    3224     SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.uTxDir);
    3225     SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.cbCDB);
    3226     SSMR3PutMem   (pSSM, pBusLogic->VBoxSCSI.abCDB, sizeof(pBusLogic->VBoxSCSI.abCDB));
    3227     SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.iCDB);
    3228     SSMR3PutU32   (pSSM, pBusLogic->VBoxSCSI.cbBuf);
    3229     SSMR3PutU32   (pSSM, pBusLogic->VBoxSCSI.iBuf);
    3230     SSMR3PutBool  (pSSM, pBusLogic->VBoxSCSI.fBusy);
    3231     SSMR3PutU8    (pSSM, pBusLogic->VBoxSCSI.enmState);
    3232     if (pBusLogic->VBoxSCSI.cbBuf)
    3233         SSMR3PutMem(pSSM, pBusLogic->VBoxSCSI.pbBuf, pBusLogic->VBoxSCSI.cbBuf);
     3221
     3222    vboxscsiR3SaveExec(&pBusLogic->VBoxSCSI, pSSM);
    32343223
    32353224    /*
     
    33323321    SSMR3GetBool  (pSSM, &pBusLogic->fStrictRoundRobinMode);
    33333322    SSMR3GetBool  (pSSM, &pBusLogic->fExtendedLunCCBFormat);
    3334     /* Now the data for the BIOS interface. */
    3335     SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.regIdentify);
    3336     SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.uTargetDevice);
    3337     SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.uTxDir);
    3338     SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.cbCDB);
    3339     SSMR3GetMem (pSSM, pBusLogic->VBoxSCSI.abCDB, sizeof(pBusLogic->VBoxSCSI.abCDB));
    3340     SSMR3GetU8  (pSSM, &pBusLogic->VBoxSCSI.iCDB);
    3341     SSMR3GetU32 (pSSM, &pBusLogic->VBoxSCSI.cbBuf);
    3342     SSMR3GetU32 (pSSM, &pBusLogic->VBoxSCSI.iBuf);
    3343     SSMR3GetBool(pSSM, (bool *)&pBusLogic->VBoxSCSI.fBusy);
    3344     SSMR3GetU8  (pSSM, (uint8_t *)&pBusLogic->VBoxSCSI.enmState);
    3345     if (pBusLogic->VBoxSCSI.cbBuf)
    3346     {
    3347         pBusLogic->VBoxSCSI.pbBuf = (uint8_t *)RTMemAllocZ(pBusLogic->VBoxSCSI.cbBuf);
    3348         if (!pBusLogic->VBoxSCSI.pbBuf)
    3349         {
    3350             LogRel(("BusLogic: Out of memory during restore.\n"));
    3351             return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY,
    3352                                     N_("BusLogic: Out of memory during restore\n"));
    3353         }
    3354         SSMR3GetMem(pSSM, pBusLogic->VBoxSCSI.pbBuf, pBusLogic->VBoxSCSI.cbBuf);
     3323
     3324    rc = vboxscsiR3LoadExec(&pBusLogic->VBoxSCSI, pSSM);
     3325    if (RT_FAILURE(rc))
     3326    {
     3327        LogRel(("BusLogic: Failed to restore BIOS state: %Rrc.\n", rc));
     3328        return PDMDEV_SET_ERROR(pDevIns, rc,
     3329                                N_("BusLogic: Failed to restore BIOS state\n"));
    33553330    }
    33563331
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r56413 r56426  
    44904490        AssertMsgFailed(("Invalid controller type %d\n", pThis->enmCtrlType));
    44914491
    4492     /* Now the data for the BIOS interface. */
    4493     SSMR3PutU8    (pSSM, pThis->VBoxSCSI.regIdentify);
    4494     SSMR3PutU8    (pSSM, pThis->VBoxSCSI.uTargetDevice);
    4495     SSMR3PutU8    (pSSM, pThis->VBoxSCSI.uTxDir);
    4496     SSMR3PutU8    (pSSM, pThis->VBoxSCSI.cbCDB);
    4497     SSMR3PutMem   (pSSM, pThis->VBoxSCSI.abCDB, sizeof(pThis->VBoxSCSI.abCDB));
    4498     SSMR3PutU8    (pSSM, pThis->VBoxSCSI.iCDB);
    4499     SSMR3PutU32   (pSSM, pThis->VBoxSCSI.cbBuf);
    4500     SSMR3PutU32   (pSSM, pThis->VBoxSCSI.iBuf);
    4501     SSMR3PutBool  (pSSM, pThis->VBoxSCSI.fBusy);
    4502     SSMR3PutU8    (pSSM, pThis->VBoxSCSI.enmState);
    4503     if (pThis->VBoxSCSI.cbBuf)
    4504         SSMR3PutMem(pSSM, pThis->VBoxSCSI.pbBuf, pThis->VBoxSCSI.cbBuf);
    4505 
     4492    vboxscsiR3SaveExec(&pThis->VBoxSCSI, pSSM);
    45064493    return SSMR3PutU32(pSSM, ~0);
    45074494}
     
    48334820    }
    48344821
    4835     /* Now the data for the BIOS interface. */
    4836     SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.regIdentify);
    4837     SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.uTargetDevice);
    4838     SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.uTxDir);
    4839     SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.cbCDB);
    4840     SSMR3GetMem (pSSM, pThis->VBoxSCSI.abCDB, sizeof(pThis->VBoxSCSI.abCDB));
    4841     SSMR3GetU8  (pSSM, &pThis->VBoxSCSI.iCDB);
    4842     SSMR3GetU32 (pSSM, &pThis->VBoxSCSI.cbBuf);
    4843     SSMR3GetU32 (pSSM, &pThis->VBoxSCSI.iBuf);
    4844     SSMR3GetBool(pSSM, (bool *)&pThis->VBoxSCSI.fBusy);
    4845     SSMR3GetU8  (pSSM, (uint8_t *)&pThis->VBoxSCSI.enmState);
    4846     if (pThis->VBoxSCSI.cbBuf)
    4847     {
    4848         pThis->VBoxSCSI.pbBuf = (uint8_t *)RTMemAllocZ(pThis->VBoxSCSI.cbBuf);
    4849         if (!pThis->VBoxSCSI.pbBuf)
    4850         {
    4851             LogRel(("LsiLogic: Out of memory during restore.\n"));
    4852             return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY,
    4853                                     N_("LsiLogic: Out of memory during restore\n"));
    4854         }
    4855         SSMR3GetMem(pSSM, pThis->VBoxSCSI.pbBuf, pThis->VBoxSCSI.cbBuf);
     4822    rc = vboxscsiR3LoadExec(&pThis->VBoxSCSI, pSSM);
     4823    if (RT_FAILURE(rc))
     4824    {
     4825        LogRel(("LsiLogic: Failed to restore BIOS state: %Rrc.\n", rc));
     4826        return PDMDEV_SET_ERROR(pDevIns, rc,
     4827                                N_("LsiLogic: Failed to restore BIOS state\n"));
    48564828    }
    48574829
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp

    r56425 r56426  
    105105            /* If we're not in the 'command ready' state, there may not even be a buffer yet. */
    106106            if (   pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY
    107                 && pVBoxSCSI->cbBuf > 0)
     107                && pVBoxSCSI->cbBufLeft > 0)
    108108            {
    109109                AssertMsg(pVBoxSCSI->pbBuf, ("pBuf is NULL\n"));
     
    111111                uVal = pVBoxSCSI->pbBuf[pVBoxSCSI->iBuf];
    112112                pVBoxSCSI->iBuf++;
    113                 pVBoxSCSI->cbBuf--;
     113                pVBoxSCSI->cbBufLeft--;
    114114
    115115                /* When the guest reads the last byte from the data in buffer, clear
    116116                   everything and reset command buffer. */
    117                 if (pVBoxSCSI->cbBuf == 0)
     117                if (pVBoxSCSI->cbBufLeft == 0)
    118118                    vboxscsiReset(pVBoxSCSI, false /*fEverything*/);
    119119            }
     
    203203                    Log(("%s: Command ready for processing\n", __FUNCTION__));
    204204                    pVBoxSCSI->enmState = VBOXSCSISTATE_COMMAND_READY;
     205                    pVBoxSCSI->cbBufLeft = pVBoxSCSI->cbBuf;
    205206                    if (pVBoxSCSI->uTxDir == VBOXSCSI_TXDIR_TO_DEVICE)
    206207                    {
     
    231232                vboxscsiReset(pVBoxSCSI, true /*fEverything*/);
    232233            }
    233             else if (pVBoxSCSI->cbBuf > 0)
     234            else if (pVBoxSCSI->cbBufLeft > 0)
    234235            {
    235236                pVBoxSCSI->pbBuf[pVBoxSCSI->iBuf++] = uVal;
    236                 pVBoxSCSI->cbBuf--;
    237                 if (pVBoxSCSI->cbBuf == 0)
     237                pVBoxSCSI->cbBufLeft--;
     238                if (pVBoxSCSI->cbBufLeft == 0)
    238239                {
    239240                    rc = VERR_MORE_DATA;
     
    367368    int rc = VINF_SUCCESS;
    368369    uint32_t cbTransfer = *pcTransfers * cb;
    369     if (pVBoxSCSI->cbBuf > 0) /* Think cbBufLeft, not cbBuf! */
     370    if (pVBoxSCSI->cbBufLeft > 0)
    370371    {
    371372        Assert(cbTransfer <= pVBoxSCSI->cbBuf);
     
    380381
    381382        /* Advance current buffer position. */
    382         pVBoxSCSI->iBuf  += cbTransfer;
    383         pVBoxSCSI->cbBuf -= cbTransfer;
     383        pVBoxSCSI->iBuf      += cbTransfer;
     384        pVBoxSCSI->cbBufLeft -= cbTransfer;
    384385
    385386        /* When the guest reads the last byte from the data in buffer, clear
    386387           everything and reset command buffer. */
    387         if (pVBoxSCSI->cbBuf == 0)
     388        if (pVBoxSCSI->cbBufLeft == 0)
    388389            vboxscsiReset(pVBoxSCSI, false /*fEverything*/);
    389390    }
     
    419420     */
    420421    int rc = VINF_SUCCESS;
    421     if (pVBoxSCSI->cbBuf > 0) /* Think cbBufLeft, not cbBuf! */
    422     {
    423         uint32_t cbTransfer = *pcTransfers * cb;
    424         if (cbTransfer > pVBoxSCSI->cbBuf) /* Think cbBufLeft, not cbBuf! */
    425         {
    426             /** @todo the non-string version of the code would cause a reset here. */
    427             cbTransfer = pVBoxSCSI->cbBuf;
    428         }
     422    if (pVBoxSCSI->cbBufLeft > 0)
     423    {
     424        uint32_t cbTransfer = RT_MIN(*pcTransfers * cb, pVBoxSCSI->cbBufLeft);
    429425
    430426        /* Copy the data and adance the buffer position. */
    431427        memcpy(pVBoxSCSI->pbBuf + pVBoxSCSI->iBuf, pbSrc, cbTransfer);
    432         pVBoxSCSI->iBuf  += cbTransfer;
    433         pVBoxSCSI->cbBuf -= cbTransfer;
     428        pVBoxSCSI->iBuf      += cbTransfer;
     429        pVBoxSCSI->cbBufLeft -= cbTransfer;
    434430
    435431        /* If we've reached the end, tell the caller to submit the command. */
    436         if (pVBoxSCSI->cbBuf == 0)
     432        if (pVBoxSCSI->cbBufLeft == 0)
    437433        {
    438434            ASMAtomicXchgBool(&pVBoxSCSI->fBusy, true);
     
    459455    }
    460456}
     457
     458DECLHIDDEN(int) vboxscsiR3LoadExec(PVBOXSCSI pVBoxSCSI, PSSMHANDLE pSSM)
     459{
     460    SSMR3GetU8  (pSSM, &pVBoxSCSI->regIdentify);
     461    SSMR3GetU8  (pSSM, &pVBoxSCSI->uTargetDevice);
     462    SSMR3GetU8  (pSSM, &pVBoxSCSI->uTxDir);
     463    SSMR3GetU8  (pSSM, &pVBoxSCSI->cbCDB);
     464    SSMR3GetMem (pSSM, &pVBoxSCSI->abCDB[0], sizeof(pVBoxSCSI->abCDB));
     465    SSMR3GetU8  (pSSM, &pVBoxSCSI->iCDB);
     466    SSMR3GetU32 (pSSM, &pVBoxSCSI->cbBufLeft);
     467    SSMR3GetU32 (pSSM, &pVBoxSCSI->iBuf);
     468    SSMR3GetBool(pSSM, (bool *)&pVBoxSCSI->fBusy);
     469    SSMR3GetU8  (pSSM, (uint8_t *)&pVBoxSCSI->enmState);
     470
     471    /*
     472     * Old saved states only save the size of the buffer left to read/write.
     473     * To avoid changing the saved state version we can just calculate the original
     474     * buffer size from the offset and remaining size.
     475     */
     476    pVBoxSCSI->cbBuf = pVBoxSCSI->cbBufLeft + pVBoxSCSI->iBuf;
     477
     478    if (pVBoxSCSI->cbBuf)
     479    {
     480        pVBoxSCSI->pbBuf = (uint8_t *)RTMemAllocZ(pVBoxSCSI->cbBuf);
     481        if (!pVBoxSCSI->pbBuf)
     482            return VERR_NO_MEMORY;
     483
     484        SSMR3GetMem(pSSM, pVBoxSCSI->pbBuf, pVBoxSCSI->cbBuf);
     485    }
     486
     487    return VINF_SUCCESS;
     488}
     489
     490DECLHIDDEN(int) vboxscsiR3SaveExec(PVBOXSCSI pVBoxSCSI, PSSMHANDLE pSSM)
     491{
     492    SSMR3PutU8    (pSSM, pVBoxSCSI->regIdentify);
     493    SSMR3PutU8    (pSSM, pVBoxSCSI->uTargetDevice);
     494    SSMR3PutU8    (pSSM, pVBoxSCSI->uTxDir);
     495    SSMR3PutU8    (pSSM, pVBoxSCSI->cbCDB);
     496    SSMR3PutMem   (pSSM, pVBoxSCSI->abCDB, sizeof(pVBoxSCSI->abCDB));
     497    SSMR3PutU8    (pSSM, pVBoxSCSI->iCDB);
     498    SSMR3PutU32   (pSSM, pVBoxSCSI->cbBufLeft);
     499    SSMR3PutU32   (pSSM, pVBoxSCSI->iBuf);
     500    SSMR3PutBool  (pSSM, pVBoxSCSI->fBusy);
     501    SSMR3PutU8    (pSSM, pVBoxSCSI->enmState);
     502
     503    /*
     504     * Old saved states only save the size of the buffer left to read/write.
     505     * To avoid changing the saved state version we can just calculate the original
     506     * buffer size from the offset and remaining size.
     507     */
     508    pVBoxSCSI->cbBuf = pVBoxSCSI->cbBufLeft + pVBoxSCSI->iBuf;
     509
     510    if (pVBoxSCSI->cbBuf)
     511        SSMR3PutMem(pSSM, pVBoxSCSI->pbBuf, pVBoxSCSI->cbBuf);
     512
     513    return VINF_SUCCESS;
     514}
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.h

    r56413 r56426  
    111111    /** Pointer to the buffer holding the data. */
    112112    R3PTRTYPE(uint8_t *) pbBuf;
    113     /** Size of the buffer in bytes.
    114      *
    115      * @todo r=bird: Misleading docs and member name.  This is actually not the
    116      *               buffer size, it's the number of bytes left to read/write in the
    117      *               buffer.  It is decremented when the guest (BIOS) accesses
    118      *               the buffer data. */
     113    /** Size of the buffer in bytes. */
    119114    uint32_t             cbBuf;
     115    /** The number of bytes left to read/write in the
     116     *  buffer.  It is decremented when the guest (BIOS) accesses
     117     *  the buffer data. */
     118    uint32_t             cbBufLeft;
    120119    /** Current position in the buffer (offBuf if you like). */
    121120    uint32_t             iBuf;
     
    146145int vboxscsiReadString(PPDMDEVINS pDevIns, PVBOXSCSI pVBoxSCSI, uint8_t iRegister,
    147146                       uint8_t *pbDst, uint32_t *pcTransfers, unsigned cb);
     147
     148DECLHIDDEN(int) vboxscsiR3LoadExec(PVBOXSCSI pVBoxSCSI, PSSMHANDLE pSSM);
     149DECLHIDDEN(int) vboxscsiR3SaveExec(PVBOXSCSI pVBoxSCSI, PSSMHANDLE pSSM);
    148150RT_C_DECLS_END
    149151#endif /* IN_RING3 */
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