VirtualBox

Changeset 64654 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Nov 13, 2016 6:00:51 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
111898
Message:

VSCSI,DrvSCSI: Proper residual calculation, save the transfer size from the CDB

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

Legend:

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

    r64441 r64654  
    7373    /** Where to store the SCSI status code. */
    7474    uint8_t                  *pu8ScsiSts;
     75    /** Transfer size determined by the VSCSI layer. */
     76    size_t                   cbXfer;
    7577    /** Start of the request data for the device above us. */
    7678    uint8_t                  abAlloc[1];
     
    786788    PDRVSCSIREQ pReq = (PDRVSCSIREQ)hIoReq;
    787789
    788     *pcbResidual = *pReq->pu8ScsiSts == SCSI_STATUS_OK ? 0 : pReq->cbBuf; /** @todo: Implement properly. */
     790    if (pReq->cbXfer <= pReq->cbBuf)
     791        *pcbResidual = pReq->cbBuf - pReq->cbXfer;
     792    else
     793        *pcbResidual = 0; /* Overflow/Underrun error. */
    789794    return VINF_SUCCESS;
    790795}
     
    796801    PDRVSCSIREQ pReq = (PDRVSCSIREQ)hIoReq;
    797802
    798     *pcbXfer = pReq->cbBuf; /** @todo: Implement properly. */
     803    *pcbXfer = pReq->cbXfer;
    799804    return VINF_SUCCESS;
    800805}
     
    950955
    951956static DECLCALLBACK(void) drvscsiIoReqVScsiReqCompleted(VSCSIDEVICE hVScsiDevice, void *pVScsiDeviceUser,
    952                                                         void *pVScsiReqUser, int rcScsiCode, bool fRedoPossible, int rcReq)
     957                                                        void *pVScsiReqUser, int rcScsiCode, bool fRedoPossible,
     958                                                        int rcReq, size_t cbXfer)
    953959{
    954960    RT_NOREF2(hVScsiDevice, fRedoPossible);
     
    979985
    980986    *pReq->pu8ScsiSts = (uint8_t)rcScsiCode;
     987    pReq->cbXfer      = cbXfer;
    981988    int rc = pThis->pDevMediaExPort->pfnIoReqCompleteNotify(pThis->pDevMediaExPort, (PDMMEDIAEXIOREQ)pReq,
    982989                                                            &pReq->abAlloc[0], rcReq);
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp

    r64412 r64654  
    6767                SCSIINQUIRYDATA ScsiInquiryReply;
    6868
     69                vscsiReqSetXferSize(pVScsiReq, vscsiBE2HU16(&pVScsiReq->pbCDB[3]));
    6970                memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
    7071                ScsiInquiryReply.cbAdditional = 31;
     
    8586             * to return an error.
    8687             */
    87             if (vscsiBE2HU32(&pVScsiReq->pbCDB[6]) < 16)
     88            vscsiReqSetXferSize(pVScsiReq, vscsiBE2HU32(&pVScsiReq->pbCDB[6]));
     89            if (pVScsiReq->cbXfer < 16)
    8890                *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
    8991            else
     
    113115        case SCSI_REQUEST_SENSE:
    114116        {
     117            vscsiReqSetXferSize(pVScsiReq, pVScsiReq->pbCDB[4]);
     118
    115119            /* Descriptor format sense data is not supported and results in an error. */
    116120            if ((pVScsiReq->pbCDB[1] & 0x1) != 0)
     
    179183    pVScsiDevice->pfnVScsiReqCompleted(pVScsiDevice, pVScsiDevice->pvVScsiDeviceUser,
    180184                                       pVScsiReq->pvVScsiReqUser, rcScsiCode, fRedoPossible,
    181                                        rcReq);
     185                                       rcReq, pVScsiReq->cbXfer);
    182186
    183187    RTMemCacheFree(pVScsiDevice->hCacheReq, pVScsiReq);
     
    391395    pVScsiReq->cbSense        = cbSense;
    392396    pVScsiReq->pvVScsiReqUser = pvVScsiReqUser;
     397    pVScsiReq->cbXfer         = 0;
    393398    RTSgBufInit(&pVScsiReq->SgBuf, paSGList, cSGListEntries);
    394399
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h

    r64412 r64654  
    119119    /** Opaque user data associated with this request */
    120120    void                *pvVScsiReqUser;
     121    /** Transfer size determined from the CDB. */
     122    size_t               cbXfer;
    121123} VSCSIREQINT;
    122124
     
    149151            PCRTSGSEG      paSeg;
    150152        } Io;
    151         /** Unmape request. */
     153        /** Unmap request. */
    152154        struct
    153155        {
     
    442444
    443445/**
     446 * Sets the transfer size for the given request.
     447 *
     448 * @returns nothing.
     449 * @param   pVScsiReq     The SCSI request.
     450 * @param   cbXfer        The transfer size for the request.
     451 */
     452DECLINLINE(void) vscsiReqSetXferSize(PVSCSIREQINT pVScsiReq, size_t cbXfer)
     453{
     454    pVScsiReq->cbXfer = cbXfer;
     455}
     456
     457/**
    444458 * Wrapper for the set I/O request allocation size I/O callback.
    445459 *
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp

    r64412 r64654  
    887887                SCSIINQUIRYDATA ScsiInquiryReply;
    888888
     889                vscsiReqSetXferSize(pVScsiReq, vscsiBE2HU16(&pVScsiReq->pbCDB[3]));
    889890                memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
    890891
     
    908909                uint8_t aReply[8];
    909910                memset(aReply, 0, sizeof(aReply));
     911                vscsiReqSetXferSize(pVScsiReq, sizeof(aReply));
    910912
    911913                /*
     
    929931                bool    fValid = false;
    930932
     933                vscsiReqSetXferSize(pVScsiReq, pVScsiReq->pbCDB[4]);
    931934                memset(aReply, 0, sizeof(aReply));
    932935                aReply[0] = 4; /* Reply length 4. */
     
    959962            case SCSI_MODE_SENSE_10:
    960963            {
    961                 size_t cbMax = vscsiBE2HU32(&pVScsiReq->pbCDB[7]);
     964                size_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
     965                vscsiReqSetXferSize(pVScsiReq, cbMax);
    962966                rcReq = vscsiLunMmcModeSense10(pVScsiLunMmc, pVScsiReq, cbMax);
    963967                break;
     
    976980            {
    977981                /** @todo implement!! */
     982                vscsiReqSetXferSize(pVScsiReq, pVScsiReq->pbCDB[4]);
    978983                rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    979984                break;
     
    10121017            {
    10131018                uint8_t uDataMode = pVScsiReq->pbCDB[1] & 0x1f;
     1019
     1020                vscsiReqSetXferSize(pVScsiReq, vscsiBE2HU16(&pVScsiReq->pbCDB[6]));
    10141021
    10151022                switch (uDataMode)
     
    10641071                uint8_t uPageCode = pVScsiReq->pbCDB[2] & 0x3f;
    10651072                uint8_t uSubPageCode = pVScsiReq->pbCDB[3];
     1073
     1074                vscsiReqSetXferSize(pVScsiReq, vscsiBE2HU16(&pVScsiReq->pbCDB[7]));
    10661075
    10671076                switch (uPageCode)
     
    11001109                        vscsiH2BEU32(&aReply[8], pVScsiLunMmc->cbSector);
    11011110                        /* Leave the rest 0 */
     1111
     1112                        vscsiReqSetXferSize(pVScsiReq, sizeof(aReply));
    11021113                        RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
    11031114                        rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
     
    11261137                cbMax  = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
    11271138                fMSF   = (pVScsiReq->pbCDB[1] >> 1) & 1;
     1139
     1140                vscsiReqSetXferSize(pVScsiReq, cbMax);
    11281141                switch (format)
    11291142                {
     
    11451158            {
    11461159                /* Only supporting polled mode at the moment. */
     1160                size_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
     1161
     1162                vscsiReqSetXferSize(pVScsiReq, cbMax);
    11471163                if (pVScsiReq->pbCDB[1] & 0x1)
    1148                 {
    1149                     size_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
    11501164                    rcReq = vscsiLunMmcGetEventStatusNotification(pVScsiLunMmc, pVScsiReq, cbMax);
    1151                 }
    11521165                else
    11531166                    rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
     
    11591172                uint8_t aReply[8];
    11601173
     1174                vscsiReqSetXferSize(pVScsiReq, cbMax);
    11611175                vscsiH2BEU16(&aReply[0], 0);
    11621176                /* no current LBA */
     
    11751189                size_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
    11761190
     1191                vscsiReqSetXferSize(pVScsiReq, cbMax);
    11771192                memset(aReply, '\0', sizeof(aReply));
    11781193                vscsiH2BEU16(&aReply[0], 32);
     
    11951210            case SCSI_READ_TRACK_INFORMATION:
    11961211            {
     1212                size_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
     1213
     1214                vscsiReqSetXferSize(pVScsiReq, cbMax);
    11971215                /* Accept address/number type of 1 only, and only track 1 exists. */
    11981216                if ((pVScsiReq->pbCDB[1] & 0x03) != 1 || vscsiBE2HU32(&pVScsiReq->pbCDB[2]) != 1)
     
    12011219                else
    12021220                {
    1203                     size_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
    12041221                    uint8_t aReply[36];
    12051222                    RT_ZERO(aReply);
     
    12241241            {
    12251242                size_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
     1243                vscsiReqSetXferSize(pVScsiReq, cbMax);
    12261244                rcReq = vscsiLunMmcGetConfiguration(pVScsiLunMmc, pVScsiReq, cbMax);
    12271245                break;
     
    12301248            {
    12311249                size_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[8]);
     1250                vscsiReqSetXferSize(pVScsiReq, cbMax);
    12321251                rcReq = vscsiLunMmcReadDvdStructure(pVScsiLunMmc, pVScsiReq, cbMax);
    12331252                break;
     
    12441263                 __FUNCTION__, uLbaStart, cSectorTransfer));
    12451264
     1265        vscsiReqSetXferSize(pVScsiReq, cSectorTransfer * pVScsiLunMmc->cbSector);
    12461266        if (RT_UNLIKELY(uLbaStart + cSectorTransfer > pVScsiLunMmc->cSectors))
    12471267        {
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp

    r64412 r64654  
    203203        case SCSI_INQUIRY:
    204204        {
     205            vscsiReqSetXferSize(pVScsiReq, vscsiBE2HU16(&pVScsiReq->pbCDB[3]));
     206
    205207            /* Check for EVPD bit. */
    206208            if (pVScsiReq->pbCDB[1] & 0x1)
     
    244246            uint8_t aReply[8];
    245247            memset(aReply, 0, sizeof(aReply));
     248
     249            vscsiReqSetXferSize(pVScsiReq, sizeof(aReply));
    246250
    247251            /*
     
    265269            bool    fValid = false;
    266270
     271            vscsiReqSetXferSize(pVScsiReq, pVScsiReq->pbCDB[4]);
    267272            memset(aReply, 0, sizeof(aReply));
    268273            aReply[0] = 4; /* Reply length 4. */
     
    302307            size_t  cbList = pVScsiReq->pbCDB[4];
    303308
     309            vscsiReqSetXferSize(pVScsiReq, pVScsiReq->pbCDB[4]);
     310
    304311            /* Copy the parameters. */
    305312            cbCopied = RTSgBufCopyToBuf(&pVScsiReq->SgBuf, &abParms[0], sizeof(abParms));
     
    392399        {
    393400            uint8_t uDataMode = pVScsiReq->pbCDB[1] & 0x1f;
     401
     402            vscsiReqSetXferSize(pVScsiReq, vscsiBE2HU16(&pVScsiReq->pbCDB[6]));
    394403
    395404            switch (uDataMode)
     
    423432        case SCSI_START_STOP_UNIT:
    424433        {
     434            vscsiReqSetXferSize(pVScsiReq, 0);
    425435            rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
    426436            break;
     
    430440            uint8_t uPageCode = pVScsiReq->pbCDB[2] & 0x3f;
    431441            uint8_t uSubPageCode = pVScsiReq->pbCDB[3];
     442
     443            vscsiReqSetXferSize(pVScsiReq, vscsiBE2HU16(&pVScsiReq->pbCDB[7]));
    432444
    433445            switch (uPageCode)
     
    468480                    /* Leave the rest 0 */
    469481
     482                    vscsiReqSetXferSize(pVScsiReq, sizeof(aReply));
    470483                    RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
    471484                    rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
     
    486499
    487500                /* Copy the header. */
     501                vscsiReqSetXferSize(pVScsiReq, cbList);
    488502                cbCopied = RTSgBufCopyToBuf(&pVScsiReq->SgBuf, &abHdr[0], sizeof(abHdr));
    489503
     
    546560                 __FUNCTION__, uLbaStart, cSectorTransfer));
    547561
     562        vscsiReqSetXferSize(pVScsiReq, cSectorTransfer * 512);
     563
    548564        if (RT_UNLIKELY(uLbaStart + cSectorTransfer > pVScsiLunSbc->cSectors))
    549565        {
     
    569585        }
    570586    }
    571     else if (pVScsiReq->pbCDB[0] ==  SCSI_SYNCHRONIZE_CACHE)
     587    else if (pVScsiReq->pbCDB[0] == SCSI_SYNCHRONIZE_CACHE)
    572588    {
    573589        /* Enqueue flush */
     590        vscsiReqSetXferSize(pVScsiReq, 0);
    574591        rc = vscsiIoReqFlushEnqueue(pVScsiLun, pVScsiReq);
    575592    }
Note: See TracChangeset for help on using the changeset viewer.

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