VirtualBox

Changeset 80521 in vbox


Ignore:
Timestamp:
Aug 31, 2019 1:35:35 PM (5 years ago)
Author:
vboxsync
Message:

Storage/DevVirtioSCSI.cpp: DrvSCSI (VSCSI) seems to return status information regardless of whether there was a problem or not. Linux considers that an error. See bugref:9440, Comment #60

File:
1 edited

Legend:

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

    r80501 r80521  
    2121*   Header Files                                                                                                                 *
    2222*********************************************************************************************************************************/
    23 #define LOG_GROUP LOG_GROUP_DRV_SCSI
     23//#define LOG_GROUP LOG_GROUP_DRV_SCSI
     24#define LOG_GROUP LOG_GROUP_DEV_VIRTIO
    2425
    2526#include <VBox/vmm/pdmdev.h>
     
    5657/** @} */
    5758
    58 #define VIRTIOSCSI_HOST_SCSI_ALL_FEATURES \
     59
     60#define VIRTIOSCSI_HOST_SCSI_FEATURES_ALL \
    5961            (VIRTIO_SCSI_F_INOUT | VIRTIO_SCSI_F_HOTPLUG | VIRTIO_SCSI_F_CHANGE | VIRTIO_SCSI_F_T10_PI)
    6062
    61 #define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED       0            /**< TBD, support at least hotplug & in/out          */
     63#define VIRTIOSCSI_HOST_SCSI_FEATURES_NONE          0
     64
     65#define VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED \
     66            VIRTIOSCSI_HOST_SCSI_FEATURES_NONE
    6267
    6368/**
     
    6671#define VIRTIOSCSI_REQ_QUEUE_CNT                    1            /**< Number of req queues exposed by dev.            */
    6772#define VIRTIOSCSI_QUEUE_CNT                        VIRTIOSCSI_REQ_QUEUE_CNT + 2
    68 #define VIRTIOSCSI_MAX_TARGETS                      1            /**< Can probably determined from higher layers       */
    69 #define VIRTIOSCSI_MAX_LUN                          16383        /* < VirtIO specification, section 5.6.4             */
     73#define VIRTIOSCSI_MAX_TARGETS                      1            /**< Can probably determined from higher layers      */
     74#define VIRTIOSCSI_MAX_LUN                          1            /* < VirtIO specification, section 5.6.4             */
    7075#define VIRTIOSCSI_MAX_COMMANDS_PER_LUN             1            /* < T.B.D. What is a good value for this?           */
    7176#define VIRTIOSCSI_MAX_SEG_COUNT                    1024         /* < T.B.D. What is a good value for this?           */
    7277#define VIRTIOSCSI_MAX_SECTORS_HINT                 0x10000      /* < VirtIO specification, section 5.6.4             */
    73 #define VIRTIOSCSI_MAX_CHANNEL_HINT                 0            /* < VirtIO specification, section 5.6.4             */
     78#define VIRTIOSCSI_MAX_CHANNEL_HINT                 0            /* < VirtIO specification, section 5.6.4 should be 0 */
    7479#define VIRTIOSCSI_SAVED_STATE_MINOR_VERSION        0x01         /**< SSM version #                                   */
    7580
     
    8085#define VIRTIOSCSI_PCI_CLASS                        0x01         /**< Base class Mass Storage?                        */
    8186
     87
     88#define VIRTIOSCSI_SENSE_SIZE_DEFAULT               96          /**< VirtIO 1.0: 96 on reset, guest can change       */
     89#define VIRTIOSCSI_CDB_SIZE_DEFAULT                 32          /**< VirtIO 1.0: 32 on reset, guest can change       */
     90#define VIRTIOSCSI_PI_BYTES_IN                      1           /**< Value TBD (see section 5.6.6.1)                 */
     91#define VIRTIOSCSI_PI_BYTES_OUT                     1           /**< Value TBD (see section 5.6.6.1)                 */
     92#define VIRTIOSCSI_DATA_OUT                         512         /**< Value TBD (see section 5.6.6.1)                 */
     93
    8294/**
    8395 * VirtIO SCSI Host Device device-specific queue indicies
     
    91103#define VIRTQ_REQ_BASE                              2            /**< Spec-defined base index of request queues       */
    92104
    93 #define QUEUENAME(qIdx) (pThis->szQueueNames[qIdx])        /**< Macro to get queue name from its index          */
     105#define QUEUENAME(qIdx) (pThis->szQueueNames[qIdx])              /**< Macro to get queue name from its index          */
    94106#define CBQUEUENAME(qIdx) RTStrNLen(QUEUENAME(qIdx), sizeof(QUEUENAME(qIdx)))
    95107
     
    144156/** @} */
    145157
     158
     159#pragma pack(1)
     160
    146161/**
    147162 * Device operation: reqestq
    148  *
    149  * The following struct is described in VirtIO 1.0 Specification, section 5.6.6.1
    150  */
    151 #define VIRTIOSCSI_SENSE_SIZE_DEFAULT               96          /**< VirtIO 1.0: 96 on reset, guest can change       */
    152 #define VIRTIOSCSI_CDB_SIZE_DEFAULT                 32          /**< VirtIO 1.0: 32 on reset, guest can change       */
    153 #define VIRTIOSCSI_PI_BYTES_IN                      1           /**< Value TBD (see section 5.6.6.1)                 */
    154 #define VIRTIOSCSI_PI_BYTES_OUT                     1           /**< Value TBD (see section 5.6.6.1)                 */
    155 #define VIRTIOSCSI_DATA_OUT                         512         /**< Value TBD (see section 5.6.6.1)                 */
    156 
    157 #pragma pack(1)
    158 
     163 */
    159164struct REQ_CMD_HDR
    160165{
     
    804809}
    805810
    806 static int virtioScsiScrapReq(PVIRTIOSCSI pThis, uint16_t qIdx, uint32_t rcReq)
     811/**
     812 * This is called to complete a request buffer immediately
     813 *
     814 * @param pThis     - PDM driver instance state
     815 * @param qIdx      - Queue index
     816 * @param rcReq     - VirtualBox code to map to VirtIO response code.
     817 *
     818 * @returns virtual box status code
     819 */
     820static int virtioScsiReqComplete(PVIRTIOSCSI pThis, uint16_t qIdx, uint32_t rcReq)
    807821{
    808822    struct REQ_RESP_HDR respHdr;
     
    815829    RTSGSEG aReqSegs[] = { { &respHdr, sizeof(respHdr) } };
    816830    RTSgBufInit(&reqSegBuf, aReqSegs, 1);
    817     virtioQueuePut(pThis->hVirtio, qIdx, &reqSegBuf, false /* fFence */);
     831    virtioQueuePut(pThis->hVirtio, qIdx, &reqSegBuf, true /* fFence */);
    818832    virtioQueueSync(pThis->hVirtio, qIdx);
    819833    LogFunc(("Response code: %s\n", virtioGetReqRespText(respHdr.uResponse)));
     
    825839    PVIRTIOSCSITARGET pTarget = pReq->pTarget;
    826840    PPDMIMEDIAEX pIMediaEx = pTarget->pDrvMediaEx;
    827     RTSGBUF reqSegBuf;
    828 
    829     Assert(pReq->pbDataIn && pReq->pbSense);
     841
    830842    ASMAtomicDecU32(&pTarget->cReqsInProgress);
    831843
     
    833845    int rc = pIMediaEx->pfnIoReqQueryResidual(pIMediaEx, pReq->hIoReq, &cbResidual);
    834846    AssertRC(rc); Assert(cbResidual == (uint32_t)cbResidual);
     847
     848    /**
     849     * Linux does not want any sense code if there wasn't problem!
     850     */
     851    if (pReq->pbSense[2] == SCSI_SENSE_NONE)
     852        pReq->cbSense = 0;
    835853
    836854    struct REQ_RESP_HDR respHdr;
     
    856874    LogFunc(("Residual: %d\n", cbResidual));
    857875
    858     if (pReq->pbPiIn)
    859     {
    860         RTSGSEG aReqSegs[] = {
    861                 { &respHdr,       sizeof(respHdr) },
    862                 { pReq->pbSense,  pReq->cbSense   },
    863                 { pReq->pbPiIn,   pReq->cbPiIn    },
    864                 { pReq->pbDataIn, pReq->cbDataIn  }
    865         };
    866         RTSgBufInit(&reqSegBuf, aReqSegs, sizeof(aReqSegs) / sizeof(RTSGSEG));
    867     }
    868     else /** Much easier not to include piIn sgbuf than to account for it during copy! */
    869     {
    870         RTSGSEG aReqSegs[] = {
    871                 { &respHdr,       sizeof(respHdr) },
    872                 { pReq->pbSense,  pReq->cbSense   },
    873                 { pReq->pbDataIn, pReq->cbDataIn  }
    874         };
    875         RTSgBufInit(&reqSegBuf, aReqSegs, sizeof(aReqSegs) / sizeof(RTSGSEG));
    876     }
     876    int cSegs = 0;
     877    RTSGSEG aReqSegs[4];
     878    aReqSegs[cSegs].pvSeg = &respHdr;
     879    aReqSegs[cSegs++].cbSeg = sizeof(respHdr);
     880    if (pReq->cbSense)
     881    {
     882        aReqSegs[cSegs].pvSeg = pReq->pbSense;
     883        aReqSegs[cSegs++].cbSeg = pReq->cbSense;
     884    }
     885    if (pReq->cbPiIn)
     886    {
     887        aReqSegs[cSegs].pvSeg = pReq->pbPiIn;
     888        aReqSegs[cSegs++].cbSeg = pReq->cbPiIn;
     889    }
     890    if (pReq->cbDataIn)
     891    {
     892        aReqSegs[cSegs].pvSeg = pReq->pbDataIn;
     893        aReqSegs[cSegs++].cbSeg = pReq->cbDataIn;
     894    }
     895    RTSGBUF reqSegBuf;
     896    RTSgBufInit(&reqSegBuf, aReqSegs, cSegs);
    877897
    878898    /**
     
    890910     * VirtIO 1.0 Spec requires mem. barrier for ctrl cmds
    891911     * but doesn't mention fences in regard to requests. */
    892     virtioQueuePut(pThis->hVirtio, pReq->qIdx, &reqSegBuf, false /* fFence */);
     912    virtioQueuePut(pThis->hVirtio, pReq->qIdx, &reqSegBuf, true /* fFence TBD */);
    893913    virtioQueueSync(pThis->hVirtio, pReq->qIdx);
    894914
     
    963983    if (uTarget >= pThis->cTargets)
    964984    {
    965         virtioScsiScrapReq(pThis, qIdx, VERR_IO_BAD_UNIT);
     985        virtioScsiReqComplete(pThis, qIdx, VERR_IO_BAD_UNIT);
     986        return VINF_SUCCESS;
     987    }
     988    if (uLUN != 0)
     989    {
     990        virtioScsiReqComplete(pThis, qIdx, VERR_IO_BAD_UNIT);
    966991        return VINF_SUCCESS;
    967992    }
     
    10231048            AssertMsgReturn(pReq->pbPiIn, ("Out of memory allocating pi_in buffer"),  VERR_NO_MEMORY);
    10241049        }
    1025         pReq->cbDataIn  = cbDataIn;
    1026         pReq->pbDataIn  = (uint8_t *)RTMemAllocZ(cbDataIn);
    1027         AssertMsgReturn(pReq->pbDataIn, ("Out of memory allocating datain buffer"), VERR_NO_MEMORY);
    1028 
    1029         pReq->cbSense   = cbSense;
    1030         pReq->pbSense   = (uint8_t *)RTMemAllocZ(cbSense);
    1031         pReq->pInSgBuf   = pInSgBuf;
    1032         AssertMsgReturn(pReq->pbSense,  ("Out of memory allocating sense buffer"),  VERR_NO_MEMORY);
     1050
     1051        if (cbDataIn)
     1052        {
     1053            pReq->cbDataIn  = cbDataIn;
     1054            pReq->pbDataIn  = (uint8_t *)RTMemAllocZ(cbDataIn);
     1055            AssertMsgReturn(pReq->pbDataIn, ("Out of memory allocating datain buffer"), VERR_NO_MEMORY);
     1056        }
     1057
     1058        if (cbSense)
     1059        {
     1060            pReq->cbSense   = cbSense;
     1061            pReq->pbSense   = (uint8_t *)RTMemAllocZ(cbSense);
     1062            pReq->pInSgBuf   = pInSgBuf;
     1063            AssertMsgReturn(pReq->pbSense,  ("Out of memory allocating sense buffer"),  VERR_NO_MEMORY);
     1064        }
    10331065
    10341066        LogFunc(("Submitting req (target=%d, LUN=%x) on %s\n", uTarget, uLUN, QUEUENAME(qIdx)));
     
    10401072        if (rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS)
    10411073        {
    1042             virtioScsiScrapReq(pThis, qIdx, rc);
     1074            pIMediaEx->pfnIoReqFree(pIMediaEx, hIoReq);
     1075            virtioScsiReqComplete(pThis, qIdx, rc);
    10431076            return VINF_SUCCESS;
    10441077        }
    10451078    } else {
    1046         virtioScsiScrapReq(pThis, qIdx, VERR_IO_NOT_READY);
     1079        virtioScsiReqComplete(pThis, qIdx, VERR_IO_NOT_READY);
    10471080        return VINF_SUCCESS;
    10481081
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