VirtualBox

Changeset 43474 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 30, 2012 11:31:15 AM (12 years ago)
Author:
vboxsync
Message:

VBOXSCSI: Extended to allow larger than 64K transfers.

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

Legend:

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

    r40676 r43474  
    9898        case 1:
    9999        {
    100             if (pVBoxSCSI->cbBuf > 0)
     100            /* If we're not in the 'command ready' state, there may not even be a buffer yet. */
     101            if ((pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY) && pVBoxSCSI->cbBuf > 0)
    101102            {
    102103                AssertMsg(pVBoxSCSI->pBuf, ("pBuf is NULL\n"));
     104                Assert(pVBoxSCSI->enmState == VBOXSCSISTATE_COMMAND_READY);
     105                Assert(!pVBoxSCSI->fBusy);
    103106                uVal = pVBoxSCSI->pBuf[pVBoxSCSI->iBuf];
    104107                pVBoxSCSI->iBuf++;
     
    163166                else
    164167                {
    165                     pVBoxSCSI->enmState = VBOXSCSISTATE_READ_CDB_SIZE;
     168                    pVBoxSCSI->enmState = VBOXSCSISTATE_READ_CDB_SIZE_BUFHI;
    166169                    pVBoxSCSI->uTxDir = uVal;
    167170                }
    168171            }
    169             else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_CDB_SIZE)
    170             {
    171                 if (uVal > VBOXSCSI_CDB_SIZE_MAX)
     172            else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_CDB_SIZE_BUFHI)
     173            {
     174                uint8_t     cbCDB = uVal & 0x0F;
     175
     176                if (cbCDB > VBOXSCSI_CDB_SIZE_MAX)
    172177                    vboxscsiReset(pVBoxSCSI);
    173178                else
    174179                {
    175                     pVBoxSCSI->enmState = VBOXSCSISTATE_READ_BUFFER_SIZE_LOW;
    176                     pVBoxSCSI->cbCDB = uVal;
     180                    pVBoxSCSI->enmState = VBOXSCSISTATE_READ_BUFFER_SIZE_LSB;
     181                    pVBoxSCSI->cbCDB = cbCDB;
     182                    pVBoxSCSI->cbBuf = (uVal & 0xF0) << 12;     /* Bits 16-19 of buffer size. */
    177183                }
    178184            }
    179             else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_BUFFER_SIZE_LOW)
    180             {
    181                 pVBoxSCSI->enmState = VBOXSCSISTATE_READ_BUFFER_SIZE_HIGH;
    182                 pVBoxSCSI->cbBuf = uVal;
    183             }
    184             else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_BUFFER_SIZE_HIGH)
     185            else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_BUFFER_SIZE_LSB)
     186            {
     187                pVBoxSCSI->enmState = VBOXSCSISTATE_READ_BUFFER_SIZE_MID;
     188                pVBoxSCSI->cbBuf |= uVal;                       /* Bits 0-7 of buffer size. */
     189            }
     190            else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_BUFFER_SIZE_MID)
    185191            {
    186192                pVBoxSCSI->enmState = VBOXSCSISTATE_READ_COMMAND;
    187                 pVBoxSCSI->cbBuf |= (((uint16_t)uVal) << 8);
     193                pVBoxSCSI->cbBuf |= (((uint16_t)uVal) << 8);    /* Bits 8-15 of buffer size. */
    188194            }
    189195            else if (pVBoxSCSI->enmState == VBOXSCSISTATE_READ_COMMAND)
     
    351357        return VINF_SUCCESS;
    352358
    353     int rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVMCPU(pDevIns), GCDst, pVBoxSCSI->pBuf, cbTransfer);
     359    /* Also ignore attempts to read more data than is available. */
     360    Assert(cbTransfer <= pVBoxSCSI->cbBuf);
     361    if (cbTransfer > pVBoxSCSI->cbBuf)
     362        cbTransfer = pVBoxSCSI->cbBuf;  /* Ignore excess data (not supposed to happen). */
     363
     364    int rc = PGMPhysSimpleDirtyWriteGCPtr(PDMDevHlpGetVMCPU(pDevIns), GCDst, pVBoxSCSI->pBuf + pVBoxSCSI->iBuf, cbTransfer);
    354365    AssertRC(rc);
    355366
     
    357368    *pcTransfer = 0;
    358369
    359     RTMemFree(pVBoxSCSI->pBuf);
    360     pVBoxSCSI->pBuf  = NULL;
    361     pVBoxSCSI->cbBuf = 0;
    362     pVBoxSCSI->cbCDB = 0;
    363     pVBoxSCSI->iCDB  = 0;
    364     pVBoxSCSI->iBuf  = 0;
    365     pVBoxSCSI->uTargetDevice = 0;
    366     pVBoxSCSI->enmState = VBOXSCSISTATE_NO_COMMAND;
    367     memset(pVBoxSCSI->aCDB, 0, sizeof(pVBoxSCSI->aCDB));
     370    /* Advance current buffer position. */
     371    pVBoxSCSI->iBuf  += cbTransfer;
     372    pVBoxSCSI->cbBuf -= cbTransfer;
     373
     374    if (pVBoxSCSI->cbBuf == 0)
     375    {
     376        /** The guest read the last byte from the data in buffer.
     377         *  Clear everything and reset command buffer.
     378         */
     379        RTMemFree(pVBoxSCSI->pBuf);
     380        pVBoxSCSI->pBuf  = NULL;
     381        pVBoxSCSI->cbCDB = 0;
     382        pVBoxSCSI->iCDB  = 0;
     383        pVBoxSCSI->iBuf  = 0;
     384        pVBoxSCSI->uTargetDevice = 0;
     385        pVBoxSCSI->enmState = VBOXSCSISTATE_NO_COMMAND;
     386        memset(pVBoxSCSI->aCDB, 0, sizeof(pVBoxSCSI->aCDB));
     387    }
    368388
    369389    return rc;
     
    383403        return VINF_SUCCESS;
    384404
    385     Assert(cbTransfer == pVBoxSCSI->cbBuf);
     405    Assert(cbTransfer <= pVBoxSCSI->cbBuf);
    386406    if (cbTransfer > pVBoxSCSI->cbBuf)
    387407        cbTransfer = pVBoxSCSI->cbBuf;  /* Ignore excess data (not supposed to happen). */
    388408
    389     int rc = PDMDevHlpPhysReadGCVirt(pDevIns, pVBoxSCSI->pBuf, GCSrc, cbTransfer);
     409    int rc = PDMDevHlpPhysReadGCVirt(pDevIns, pVBoxSCSI->pBuf + pVBoxSCSI->iBuf, GCSrc, cbTransfer);
    390410    AssertRC(rc);
     411
     412    /* Advance current buffer position. */
     413    pVBoxSCSI->iBuf  += cbTransfer;
     414    pVBoxSCSI->cbBuf -= cbTransfer;
    391415
    392416    *pGCPtrSrc = (RTGCPTR)((RTGCUINTPTR)GCSrc + cbTransfer);
     
    409433    }
    410434}
    411 
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.h

    r35346 r43474  
    7171    VBOXSCSISTATE_NO_COMMAND            = 0x00,
    7272    VBOXSCSISTATE_READ_TXDIR            = 0x01,
    73     VBOXSCSISTATE_READ_CDB_SIZE         = 0x02,
    74     VBOXSCSISTATE_READ_BUFFER_SIZE_LOW  = 0x03,
    75     VBOXSCSISTATE_READ_BUFFER_SIZE_HIGH = 0x04,
     73    VBOXSCSISTATE_READ_CDB_SIZE_BUFHI   = 0x02,
     74    VBOXSCSISTATE_READ_BUFFER_SIZE_LSB  = 0x03,
     75    VBOXSCSISTATE_READ_BUFFER_SIZE_MID = 0x04,
    7676    VBOXSCSISTATE_READ_COMMAND          = 0x05,
    7777    VBOXSCSISTATE_COMMAND_READY         = 0x06
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