VirtualBox

Changeset 80596 in vbox


Ignore:
Timestamp:
Sep 5, 2019 7:12:46 AM (5 years ago)
Author:
vboxsync
Message:

Storage/DevVirtioSCSI.cpp: Added code to incorporate aeichner's changes (see bugref:9440, Comment #72). Tested new response status code and discovered it's more accurate to trust sense over rcReq values. Also changed some logging levels to reinstate the option to get hexdumps (with some filtering)

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/scsi.h

    r80539 r80596  
    238238#define SCSI_ASCQ_UNKNOWN_FORMAT                            0x01
    239239#define SCSI_ASCQ_INCOMPATIBLE_FORMAT                       0x02
     240#define SCSI_ASCQ_COPY_TARGET_DEVICE_DATA_OVERRUN           0x0d
    240241
    241242/** @name SCSI_INQUIRY
  • trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp

    r80589 r80596  
    106106#define CBQUEUENAME(qIdx) RTStrNLen(QUEUENAME(qIdx), sizeof(QUEUENAME(qIdx)))
    107107
     108
    108109#define IS_REQ_QUEUE(qIdx) (qIdx >= VIRTQ_REQ_BASE && qIdx < VIRTIOSCSI_QUEUE_CNT)
    109110/**
     
    463464/**
    464465 * Request structure for IMediaEx (Associated Interfaces implemented by DrvSCSI)
     466 * (NOTE: cbIn, cbOUt, cbDataOut mostly for debugging)
    465467 */
    466468typedef struct VIRTIOSCSIREQ
     
    469471    PVIRTIOSCSITARGET              pTarget;                  /**< Target                                            */
    470472    uint16_t                       qIdx;                     /**< Index of queue this request arrived on            */
     473    size_t                         cbIn;                     /**< Size of input descriptor chain                    */
     474    size_t                         cbOut;                    /**< Size of output descriptor chain                   */
    471475    size_t                         cbPiOut;                  /**< Size of T10 pi in buffer                          */
    472476    uint8_t                       *pbPiOut;                  /**< Address of pi out buffer                          */
    473477    uint8_t                       *pbDataOut;                /**< dataout                                           */
     478    size_t                         cbDataOut;                /**< size of dataout buffer                            */
    474479    size_t                         cbPiIn;                   /**< Size of T10 pi buffer                             */
    475480    uint8_t                       *pbPiIn;                   /**< Address of pi in buffer                           */
     
    477482    uint8_t                       *pbDataIn;                 /**< datain                                            */
    478483    size_t                         cbSense;                  /**< Size of sense buffer                              */
     484    size_t                         uSenseLen;                /**< Receives # bytes written into sense buffer        */
    479485    uint8_t                       *pbSense;                  /**< Pointer to R3 sense buffer                        */
     486    PDMMEDIAEXIOREQSCSITXDIR       enmTxDir;                 /**< Receives transfer direction of I/O req            */
    480487    uint8_t                        uStatus;                  /**< SCSI status code                                  */
    481488    PRTSGBUF                       pInSgBuf;                 /**< Buf vector to return PDM result to VirtIO Guest   */
     
    487494#define SET_LUN_BUF(target, lun, out) \
    488495     out[0] = 0x01;  out[1] = target; out[2] = (lun >> 8) & 0x40;  out[3] = lun & 0xff;  *((uint16_t *)out + 4) = 0;
     496
     497
     498DECLINLINE(bool) isBufZero(uint8_t *pv, size_t cb)
     499{
     500    for (uint32_t i = 0; i < cb; i++)
     501        if (pv[i])
     502            return false;
     503    return true;
     504}
     505
     506DECLINLINE(const char *) virtioGetTxDirText(uint32_t enmTxDir)
     507{
     508    switch (enmTxDir)
     509    {
     510        case PDMMEDIAEXIOREQSCSITXDIR_UNKNOWN:          return "<UNKNOWN>";
     511        case PDMMEDIAEXIOREQSCSITXDIR_FROM_DEVICE:      return "<DEV-TO-GUEST>";
     512        case PDMMEDIAEXIOREQSCSITXDIR_TO_DEVICE:        return "<GUEST-TO-DEV>";
     513        case PDMMEDIAEXIOREQSCSITXDIR_NONE:             return "<NONE>";
     514        default:                                        return "<BAD ENUM>";
     515    }
     516}
    489517
    490518
     
    610638    }
    611639
    612 
     640#define VIRTIO_IN_DIRECTION(pMediaExTxDirEnumValue) \
     641            pMediaExTxDirEnumValue == PDMMEDIAEXIOREQSCSITXDIR_FROM_DEVICE
     642
     643#define VIRTIO_OUT_DIRECTION(pMediaExTxDirEnumValue) \
     644            pMediaExTxDirEnumValue == PDMMEDIAEXIOREQSCSITXDIR_TO_DEVICE
    613645
    614646typedef struct VIRTIOSCSIREQ *PVIRTIOSCSIREQ;
     
    765797
    766798    return VINF_SUCCESS;
    767 
    768 }
     799}
     800
     801/**
     802 * This is called to complete a request immediately
     803 *
     804 * @param pThis     - PDM driver instance state
     805 * @param qIdx      - Queue index
     806 * @param pRespHdr  - Response header
     807 * @param pbSense   - Pointer to sense buffer or NULL if none.
     808 *
     809 * @returns virtual box status code
     810 */
     811static int virtioScsiReqErr(PVIRTIOSCSI pThis, uint16_t qIdx, struct REQ_RESP_HDR *pRespHdr, uint8_t *pbSense)
     812{
     813    uint8_t *abSenseBuf = (uint8_t *)RTMemAllocZ(pThis->virtioScsiConfig.uSenseSize);
     814    AssertReturn(abSenseBuf, VERR_NO_MEMORY);
     815
     816    Log2Func(("   status: %s    response: %s\n",
     817              SCSIStatusText(pRespHdr->uStatus),  virtioGetReqRespText(pRespHdr->uResponse)));
     818
     819    RTSGSEG aReqSegs[2];
     820    aReqSegs[0].cbSeg = sizeof(pRespHdr);
     821    aReqSegs[0].pvSeg = pRespHdr;
     822    aReqSegs[1].cbSeg = pThis->virtioScsiConfig.uSenseSize;
     823    aReqSegs[1].pvSeg = abSenseBuf;
     824
     825    if (pbSense && pRespHdr->uSenseLen)
     826        memcpy(abSenseBuf, pbSense, pRespHdr->uSenseLen);
     827    else
     828        pRespHdr->uSenseLen = 0;
     829
     830    RTSGBUF reqSegBuf;
     831    RTSgBufInit(&reqSegBuf, aReqSegs, RT_ELEMENTS(aReqSegs));
     832
     833    virtioQueuePut(pThis->hVirtio, qIdx, &reqSegBuf, true /* fFence */);
     834    virtioQueueSync(pThis->hVirtio, qIdx);
     835
     836    RTMemFree(abSenseBuf);
     837
     838    Log(("---------------------------------------------------------------------------------\n"));
     839
     840    return VINF_SUCCESS;
     841}
     842
    769843/** TBD: VirtIO 1.0 spec 5.6.6.1.1 requires some request actions on reset that are
    770844 *       not implemented.  Specifically either canceling outstanding I/O or
     
    795869    #define SHOULD_FIX_VSCSI_TO_RETURN_SENSE_LEN 32
    796870    struct REQ_RESP_HDR respHdr = { 0 };
    797     respHdr.uSenseLen = pReq->uStatus == SCSI_STATUS_CHECK_CONDITION ? SHOULD_FIX_VSCSI_TO_RETURN_SENSE_LEN : 0;
     871    respHdr.uSenseLen = pReq->pbSense[2] == SCSI_SENSE_NONE ? 0 : pReq->uSenseLen;
    798872    respHdr.uResidual = cbResidual;
    799873    respHdr.uStatus   = pReq->uStatus;
     
    810884                break;
    811885            }
    812             /* fallthrough */
    813         case SCSI_STATUS_BUSY:
    814             respHdr.uResponse = VIRTIOSCSI_S_BUSY;
    815             break;
    816         case SCSI_STATUS_DATA_UNDEROVER_RUN:
    817             respHdr.uResponse = VIRTIOSCSI_S_OVERRUN;
    818             break;
    819         case SCSI_STATUS_TASK_ABORTED:
    820             respHdr.uResponse = VIRTIOSCSI_S_ABORTED;
    821             break;
    822886        case SCSI_STATUS_CHECK_CONDITION:
    823887            {
     
    838902                        break;
    839903                    case SCSI_SENSE_NOT_READY:
    840                         respHdr.uResponse = VIRTIOSCSI_S_BUSY; /* e.g. try again */
     904                        respHdr.uResponse = VIRTIOSCSI_S_BUSY; /* e.g. re-tryable */
    841905                        break;
    842906                    default:
     
    852916    }
    853917
    854     Log2Func(("status: %s,   response: (%x) %s\n",
    855               SCSIStatusText(pReq->uStatus), respHdr.uResponse, virtioGetReqRespText(respHdr.uResponse)));
     918    Log2Func(("status: (%d) %s,   response: (%d) %s\n",
     919              pReq->uStatus, SCSIStatusText(pReq->uStatus), respHdr.uResponse, virtioGetReqRespText(respHdr.uResponse)));
    856920
    857921    if (RT_FAILURE(rcReq))
    858922        Log2Func(("rcReq:  %s\n", RTErrGetDefine(rcReq)));
    859923
    860     Log3Func(("status:%02x/resp:%02x, xfer=%d, residual: %u, sense (len=%d, alloc=%d)\n",
    861               pReq->uStatus, respHdr.uResponse, cbXfer, cbResidual,
    862               respHdr.uSenseLen, pThis->virtioScsiConfig.uSenseSize));
     924    if (LogIs3Enabled())
     925    {
     926        LogFunc(("cbDataIn = %u, cbDataOut = %u (cbIn = %u, cbOut = %u)\n",
     927                  pReq->cbDataIn, pReq->cbDataOut, pReq->cbIn, pReq->cbOut));
     928        LogFunc(("xfer = %d, residual = %u\n", cbXfer, cbResidual));
     929        LogFunc(("xfer direction: %s, sense written = %d, sense size = %d\n",
     930             virtioGetTxDirText(pReq->enmTxDir), respHdr.uSenseLen, pThis->virtioScsiConfig.uSenseSize));
     931    }
    863932
    864933    if (respHdr.uSenseLen && LogIs2Enabled())
    865934    {
    866         Log2Func(("Sense: %s\n", SCSISenseText(pReq->pbSense[2])));
    867         Log2Func(("Sense Ext3: %s\n", SCSISenseExtText(pReq->pbSense[12], pReq->pbSense[13])));
     935        LogFunc(("Sense: %s\n", SCSISenseText(pReq->pbSense[2])));
     936        LogFunc(("Sense Ext3: %s\n", SCSISenseExtText(pReq->pbSense[12], pReq->pbSense[13])));
     937    }
     938
     939    if (LogIsItEnabled(RTLOGGRPFLAGS_LEVEL_12, LOG_GROUP))
     940    {
     941        size_t cb = RT_MIN(cbXfer, 256);
     942        if (VIRTIO_IN_DIRECTION(pReq->enmTxDir))
     943        {
     944            Log(("datain[256 of %d total bytes xferred]:\n", cbXfer));
     945            if (!isBufZero(pReq->pbDataIn, cb))
     946                VIRTIO_HEX_DUMP(RTLOGGRPFLAGS_LEVEL_12, pReq->pbDataIn,  cb,  0, 0);
     947            else
     948                Log12(("-- %d zeroes --\n", cb));
     949        }
     950        else
     951        if (VIRTIO_OUT_DIRECTION(pReq->enmTxDir))
     952        {
     953            Log(("dataout[256 of %d total bytes xferred]:\n", cbXfer));
     954            if (!isBufZero(pReq->pbDataOut, cb))
     955                VIRTIO_HEX_DUMP(RTLOGGRPFLAGS_LEVEL_12, pReq->pbDataOut, cb, 0, 0);
     956            else
     957                Log12(("-- %d zeroes --\n", cb));
     958        }
    868959    }
    869960
    870961    int cSegs = 0;
    871962
    872 
    873 //    Assert(pReq->cbDataIn >= cbXfer);
    874     Assert(pReq->pbSense != NULL);
    875 
    876     RTSGSEG aReqSegs[4];
    877     aReqSegs[cSegs].pvSeg   = &respHdr;
    878     aReqSegs[cSegs++].cbSeg = sizeof(respHdr);
    879 
    880     aReqSegs[cSegs].pvSeg   = pReq->pbSense;
    881     aReqSegs[cSegs++].cbSeg = pReq->cbSense; /* VirtIO 1.0 spec 5.6.4/5.6.6.1 */
    882 
    883     if (pReq->cbPiIn)
    884     {
    885         aReqSegs[cSegs].pvSeg   = pReq->pbPiIn;
    886         aReqSegs[cSegs++].cbSeg = pReq->cbPiIn;
    887     }
    888     if (pReq->cbDataIn)
    889     {
    890         aReqSegs[cSegs].pvSeg   = pReq->pbDataIn;
    891         aReqSegs[cSegs++].cbSeg = cbXfer;
    892     }
    893     RTSGBUF reqSegBuf;
    894     RTSgBufInit(&reqSegBuf, aReqSegs, cSegs);
    895 
    896     /**
    897      * Fill in the request queue current descriptor chain's IN queue entry/entries
    898      * (phys. memory) with the Req response data in virtual memory.
    899      */
    900     size_t cbReqSgBuf = RTSgBufCalcTotalLength(&reqSegBuf);
    901     size_t cbInSgBuf  = RTSgBufCalcTotalLength(pReq->pInSgBuf);
    902     AssertMsgReturn(cbReqSgBuf <= cbInSgBuf,
    903                    ("Guest expected less req data (space needed: %d, avail: %d)\n", cbReqSgBuf, cbInSgBuf),
    904                    VERR_BUFFER_OVERFLOW);
    905 
    906     /**
    907      * Following doesn't put up memory barrier (fence).
    908      * VirtIO 1.0 Spec requires mem. barrier for ctrl cmds
    909      * but doesn't mention fences in regard to requests. */
    910     virtioQueuePut(pThis->hVirtio, pReq->qIdx, &reqSegBuf, true /* fFence TBD */);
    911     virtioQueueSync(pThis->hVirtio, pReq->qIdx);
    912 
    913     Log(("-----------------------------------------------------------------------------------------\n"));
    914 
     963    if (   (VIRTIO_IN_DIRECTION(pReq->enmTxDir)  && cbXfer > pReq->cbDataIn)
     964        || (VIRTIO_OUT_DIRECTION(pReq->enmTxDir) && cbXfer > pReq->cbDataOut))
     965    {
     966        /** TBD try to figure out optimal sense info to send back besides response of VIRTIOSCSI_S_OVERRUN */
     967        Log2Func((" * * * * Data overrun, returning sense\n"));
     968        uint8_t abSense[] = { RT_BIT(7) | SCSI_SENSE_RESPONSE_CODE_CURR_FIXED,
     969                              0, SCSI_SENSE_ILLEGAL_REQUEST, 0, 0, 0, 0, 10, 0, 0, 0 };
     970        respHdr.uSenseLen = sizeof(abSense);
     971        respHdr.uStatus   = SCSI_STATUS_CHECK_CONDITION;
     972        respHdr.uResponse = VIRTIOSCSI_S_OVERRUN;
     973        respHdr.uResidual = pReq->cbDataIn;
     974        virtioScsiReqErr(pThis, pReq->qIdx, &respHdr, abSense);
     975    }
     976    else
     977    {
     978        Assert(pReq->pbSense != NULL);
     979
     980        RTSGSEG aReqSegs[4];
     981        aReqSegs[cSegs].pvSeg   = &respHdr;
     982        aReqSegs[cSegs++].cbSeg = sizeof(respHdr);
     983
     984        aReqSegs[cSegs].pvSeg   = pReq->pbSense;
     985        aReqSegs[cSegs++].cbSeg = pReq->cbSense; /* VirtIO 1.0 spec 5.6.4/5.6.6.1 */
     986
     987        if (pReq->cbPiIn)
     988        {
     989            aReqSegs[cSegs].pvSeg   = pReq->pbPiIn;
     990            aReqSegs[cSegs++].cbSeg = pReq->cbPiIn;
     991        }
     992        if (pReq->cbDataIn)
     993        {
     994            aReqSegs[cSegs].pvSeg   = pReq->pbDataIn;
     995            aReqSegs[cSegs++].cbSeg = cbXfer;
     996        }
     997        RTSGBUF reqSegBuf;
     998        RTSgBufInit(&reqSegBuf, aReqSegs, cSegs);
     999
     1000        /**
     1001         * Fill in the request queue current descriptor chain's IN queue entry/entries
     1002         * (phys. memory) with the Req response data in virtual memory.
     1003         */
     1004        size_t cbReqSgBuf = RTSgBufCalcTotalLength(&reqSegBuf);
     1005        size_t cbInSgBuf  = RTSgBufCalcTotalLength(pReq->pInSgBuf);
     1006        AssertMsgReturn(cbReqSgBuf <= cbInSgBuf,
     1007                       ("Guest expected less req data (space needed: %d, avail: %d)\n", cbReqSgBuf, cbInSgBuf),
     1008                       VERR_BUFFER_OVERFLOW);
     1009
     1010        virtioQueuePut(pThis->hVirtio, pReq->qIdx, &reqSegBuf, true /* fFence TBD */);
     1011        virtioQueueSync(pThis->hVirtio, pReq->qIdx);
     1012
     1013        Log(("-----------------------------------------------------------------------------------------\n"));
     1014
     1015    }
    9151016    RTMemFree(pReq->pbSense);
    9161017    RTMemFree(pReq->pbDataIn);
     
    9261027}
    9271028
    928 /**
    929  * This is called to complete a request immediately
    930  *
    931  * @param pThis     - PDM driver instance state
    932  * @param qIdx      - Queue index
    933  * @param pRespHdr  - Response header
    934  * @param pbSense   - Pointer to sense buffer or NULL if none.
    935  *
    936  * @returns virtual box status code
    937  */
    938 static int virtioScsiReqFinish(PVIRTIOSCSI pThis, uint16_t qIdx, struct REQ_RESP_HDR *pRespHdr, uint8_t *pbSense)
    939 {
    940     uint8_t *abSenseBuf = (uint8_t *)RTMemAllocZ(pThis->virtioScsiConfig.uSenseSize);
    941     AssertReturn(abSenseBuf, VERR_NO_MEMORY);
    942 
    943     Log2Func(("status: %s    response: %s\n",
    944               SCSIStatusText(pRespHdr->uStatus),  virtioGetReqRespText(pRespHdr->uResponse)));
    945 
    946     RTSGSEG aReqSegs[2];
    947     aReqSegs[0].cbSeg = sizeof(pRespHdr);
    948     aReqSegs[0].pvSeg = pRespHdr;
    949     aReqSegs[1].cbSeg = pThis->virtioScsiConfig.uSenseSize;
    950     aReqSegs[1].pvSeg = abSenseBuf;
    951 
    952     if (pbSense && pRespHdr->uSenseLen)
    953         memcpy(abSenseBuf, pbSense, pRespHdr->uSenseLen);
    954     else
    955         pRespHdr->uSenseLen = 0;
    956 
    957     RTSGBUF reqSegBuf;
    958     RTSgBufInit(&reqSegBuf, aReqSegs, RT_ELEMENTS(aReqSegs));
    959 
    960     virtioQueuePut(pThis->hVirtio, qIdx, &reqSegBuf, true /* fFence */);
    961     virtioQueueSync(pThis->hVirtio, qIdx);
    962 
    963     RTMemFree(abSenseBuf);
    964 
    965     Log(("---------------------------------------------------------------------------------\n"));
    966 
    967     return VINF_SUCCESS;
    968 }
    969 
    9701029static int virtioScsiReqSubmit(PVIRTIOSCSI pThis, uint16_t qIdx, PRTSGBUF pInSgBuf, PRTSGBUF pOutSgBuf)
    9711030{
     
    9751034    size_t cbIn  = RTSgBufCalcTotalLength(pInSgBuf);
    9761035
    977     AssertMsgReturn(cbOut >= sizeof(REQ_CMD_HDR) + pThis->virtioScsiConfig.uCdbSize,
    978                         ("Req too short"), VERR_BUFFER_UNDERFLOW);
    979 
    980     PVIRTIOSCSI_REQ_CMD_T pVirtqReq = (PVIRTIOSCSI_REQ_CMD_T)RTMemAlloc(cbOut);
     1036    /** MAKE THIS NON-ZERO MALLOCING AFTER DEBUG */
     1037    PVIRTIOSCSI_REQ_CMD_T pVirtqReq = (PVIRTIOSCSI_REQ_CMD_T)RTMemAllocZ(cbOut);
    9811038    AssertReturn(pVirtqReq, VERR_NO_MEMORY);
    9821039
     
    9921049    }
    9931050
     1051//    VIRTIO_HEX_DUMP(RTLOGGRPFLAGS_LEVEL_12, (uint8_t *)pVirtqReq,  cbOut,  0, "\npVirtqReq");
     1052
    9941053    uint8_t  uTarget =  pVirtqReq->cmdHdr.uLUN[1];
    9951054    uint32_t uLUN    = (pVirtqReq->cmdHdr.uLUN[2] << 8 | pVirtqReq->cmdHdr.uLUN[3]) & 0x3fff;
     
    9971056    LogFunc(("[%s] (Target: %d LUN: %d)  CDB: %.*Rhxs\n",
    9981057        SCSICmdText(pVirtqReq->uCdb[0]), uTarget, uLUN,
    999         virtioScsiEstimateCdbLen(pVirtqReq->uCdb[0], pThis->virtioScsiConfig.uCdbSize), pVirtqReq->uCdb));
    1000 
    1001     Log3Func(("   id: %RX64, attr: %x, prio: %d, crn: %x\n",
     1058        virtioScsiEstimateCdbLen(pVirtqReq->uCdb[0],
     1059        pThis->virtioScsiConfig.uCdbSize), pVirtqReq->uCdb));
     1060
     1061    Log3Func(("id: %RX64, attr: %x, prio: %d, crn: %x\n",
    10021062        pVirtqReq->cmdHdr.uId, pVirtqReq->cmdHdr.uTaskAttr, pVirtqReq->cmdHdr.uPrio, pVirtqReq->cmdHdr.uCrn));
    10031063
     
    10161076    }
    10171077
    1018     off_t   uDataOutOff = sizeof(REQ_CMD_HDR)  + pThis->virtioScsiConfig.uCdbSize + cbPiHdr;
     1078    off_t   uDataOutOff = sizeof(REQ_CMD_HDR)  + pThis->virtioScsiConfig.uCdbSize   + cbPiHdr;
    10191079    off_t   uDataInOff  = sizeof(REQ_RESP_HDR) + pThis->virtioScsiConfig.uSenseSize + cbPiIn;
    10201080    uint8_t *pbDataOut = (uint8_t *)((uint64_t)pVirtqReq + uDataOutOff);
     
    10321092        respHdr.uResponse = (uTarget > pThis->cTargets) ? VIRTIOSCSI_S_BAD_TARGET : VIRTIOSCSI_S_OK;
    10331093        respHdr.uResidual = cbDataOut + cbDataIn;
    1034         virtioScsiReqFinish(pThis, qIdx, &respHdr, abSense);
     1094        virtioScsiReqErr(pThis, qIdx, &respHdr, abSense);
    10351095        return VINF_SUCCESS;
    10361096    }
     
    10481108        respHdr.uResponse = VIRTIOSCSI_S_TARGET_FAILURE;
    10491109        respHdr.uResidual = cbDataIn + cbDataOut;
    1050         virtioScsiReqFinish(pThis, qIdx, &respHdr, abSense);
     1110        virtioScsiReqErr(pThis, qIdx, &respHdr, abSense);
    10511111        RTMemFree(pVirtqReq);
    10521112        return VINF_SUCCESS;
     
    10741134    pReq->pTarget   = pTarget;
    10751135    pReq->qIdx      = qIdx;
     1136    pReq->cbIn      = cbIn;
     1137    pReq->cbOut     = cbOut;
    10761138    pReq->pbDataOut = pbDataOut;
     1139    pReq->cbDataOut = cbDataOut;
    10771140    pReq->pVirtqReq = pVirtqReq;
    10781141    pReq->pInSgBuf  = pInSgBuf;
     
    10921155    rc = pIMediaEx->pfnIoReqSendScsiCmd(pIMediaEx, pReq->hIoReq, uLUN,
    10931156                                        pVirtqReq->uCdb, pThis->virtioScsiConfig.uCdbSize,
    1094                                         PDMMEDIAEXIOREQSCSITXDIR_UNKNOWN, NULL, cbDataIn,
    1095                                         pReq->pbSense, pReq->cbSense, NULL,
     1157                                        PDMMEDIAEXIOREQSCSITXDIR_UNKNOWN, &pReq->enmTxDir, cbDataIn,
     1158                                        pReq->pbSense, pReq->cbSense, &pReq->uSenseLen,
    10961159                                        &pReq->uStatus, 30 * RT_MS_1SEC);
    10971160
     
    11241187        respHdr.uResponse = VIRTIOSCSI_S_FAILURE;
    11251188        respHdr.uResidual = cbDataIn + cbDataOut;
    1126         virtioScsiReqFinish(pThis, qIdx, &respHdr, abSense);
     1189        virtioScsiReqErr(pThis, qIdx, &respHdr, abSense);
    11271190        RTMemFree(pReq->pbSense);
    11281191        RTMemFree(pReq->pbDataIn);
     
    13361399            if (!fNotificationSent)
    13371400            {
    1338                 Log3Func(("%s worker sleeping...\n", QUEUENAME(qIdx)));
     1401                Log6Func(("%s worker sleeping...\n", QUEUENAME(qIdx)));
    13391402                Assert(ASMAtomicReadBool(&pWorker->fSleeping));
    13401403                rc = SUPSemEventWaitNoResume(pThis->pSupDrvSession, pWorker->hEvtProcess, RT_INDEFINITE_WAIT);
     
    13421405                if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING))
    13431406                    break;
    1344                 Log3Func(("%s worker woken\n", QUEUENAME(qIdx)));
     1407                Log6Func(("%s worker woken\n", QUEUENAME(qIdx)));
    13451408                ASMAtomicWriteBool(&pWorker->fNotified, false);
    13461409            }
    13471410            ASMAtomicWriteBool(&pWorker->fSleeping, false);
    13481411        }
    1349         Log3Func(("fetching next descriptor chain from %s\n", QUEUENAME(qIdx)));
     1412        Log6Func(("fetching next descriptor chain from %s\n", QUEUENAME(qIdx)));
    13501413        rc = virtioQueueGet(pThis->hVirtio, qIdx, true, &pInSgBuf, &pOutSgBuf);
    13511414        if (rc == VERR_NOT_AVAILABLE)
     
    15761639    if (qIdx == CONTROLQ_IDX || IS_REQ_QUEUE(qIdx))
    15771640    {
    1578         Log3Func(("%s has available data\n", QUEUENAME(qIdx)));
     1641        Log6Func(("%s has available data\n", QUEUENAME(qIdx)));
    15791642        /** Wake queue's worker thread up if sleeping */
    15801643        if (!ASMAtomicXchgBool(&pWorker->fNotified, true))
     
    15821645            if (ASMAtomicReadBool(&pWorker->fSleeping))
    15831646            {
    1584                 Log3Func(("waking %s worker.\n", QUEUENAME(qIdx)));
     1647                Log6Func(("waking %s worker.\n", QUEUENAME(qIdx)));
    15851648                int rc = SUPSemEventSignal(pThis->pSupDrvSession, pWorker->hEvtProcess);
    15861649                AssertRC(rc);
     
    21452208        return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi: failed to initialize VirtIO"));
    21462209
    2147 
    21482210    RTStrCopy((char *)pThis->szQueueNames[CONTROLQ_IDX], VIRTIO_MAX_QUEUE_NAME_SIZE, "controlq");
    21492211    RTStrCopy((char *)pThis->szQueueNames[EVENTQ_IDX],   VIRTIO_MAX_QUEUE_NAME_SIZE, "eventq");
     
    21522214            "requestq<%d>", qIdx - VIRTQ_REQ_BASE);
    21532215
    2154     /**
    2155      * Create one worker per incoming-work-related queue (eventq is outgoing status to guest,
    2156      * wherein guest is supposed to keep the queue loaded-up with buffer vectors the host
    2157      * can quickly fill-in send back). Should be light-duty and fast enough to be handled on
    2158      * requestq or controlq thread.  The Linux virtio_scsi driver limits the number of request
    2159      * queues to MIN(<# Guest CPUs>, <Device's req queue max>), so queue count is ultimately
    2160      * constrained from host side at negotiation time and initialization and later through
    2161      * bounds-checking.
    2162      */
    21632216    for (uint16_t qIdx = 0; qIdx < VIRTIOSCSI_QUEUE_CNT; qIdx++)
    21642217    {
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp

    r80575 r80596  
    8181            if (pszDepiction[i] == ' ' && first++)
    8282                pszDepiction[i] = '.';
    83         Log3Func(("%s: Guest %s %s 0x%s\n",
     83        Log6Func(("%s: Guest %s %s 0x%s\n",
    8484                  pszFunc, fWrite ? "wrote" : "read ", pszDepiction, pszFormattedVal));
    8585    }
    8686    else /* odd number or oversized access, ... log inline hex-dump style */
    8787    {
    88         Log3Func(("%s: Guest %s %s%s[%d:%d]: %.*Rhxs\n",
     88        Log6Func(("%s: Guest %s %s%s[%d:%d]: %.*Rhxs\n",
    8989              pszFunc, fWrite ? "wrote" : "read ", pszMember,
    9090              pszIdx, uOffset, uOffset + cb, cb, pv));
     
    199199    uint16_t uDescIdx = pDescChain->uHeadIdx;
    200200
    201     Log3Func(("%s DESC CHAIN: (head) desc_idx=%u [avail_idx=%u]\n",
     201    Log6Func(("%s DESC CHAIN: (head) desc_idx=%u [avail_idx=%u]\n",
    202202            pVirtqProxy->szVirtqName, pDescChain->uHeadIdx, pVirtqProxy->uAvailIdx));
    203203
     
    238238        if (desc.fFlags & VIRTQ_DESC_F_WRITE)
    239239        {
    240             Log3Func(("%s IN  desc_idx=%u seg=%u addr=%RGp cb=%u\n",
     240            Log6Func(("%s IN  desc_idx=%u seg=%u addr=%RGp cb=%u\n",
    241241                QUEUENAME(qIdx), uDescIdx, pDescChain->cSegsIn, desc.pGcPhysBuf, desc.cb));
    242242            cbIn += desc.cb;
     
    245245        else
    246246        {
    247             Log3Func(("%s OUT desc_idx=%u seg=%u addr=%RGp cb=%u\n",
     247            Log6Func(("%s OUT desc_idx=%u seg=%u addr=%RGp cb=%u\n",
    248248                QUEUENAME(qIdx), uDescIdx, pDescChain->cSegsOut, desc.pGcPhysBuf, desc.cb));
    249249            cbOut += desc.cb;
     
    261261
    262262    if (ppInSegs)
    263         *ppInSegs  = &pVirtqProxy->inSgBuf;
     263        *ppInSegs = &pVirtqProxy->inSgBuf;
    264264
    265265    if (ppOutSegs)
    266266        *ppOutSegs = &pVirtqProxy->outSgBuf;
    267267
    268     Log3Func(("%s -- segs OUT: %u (%u bytes)   IN: %u (%u bytes) --\n",
     268    Log6Func(("%s -- segs OUT: %u (%u bytes)   IN: %u (%u bytes) --\n",
    269269              pVirtqProxy->szVirtqName, pDescChain->cSegsOut, cbOut, pDescChain->cSegsIn, cbIn));
    270270
     
    292292    size_t cbRemain = RTSgBufCalcTotalLength(pBufSrc);
    293293    uint16_t uUsedIdx = virtioReadUsedRingIdx(pVirtio, qIdx);
    294     Log3Func(("Copying client data to %s, desc chain (head desc_idx %d)\n",
     294    Log6Func(("Copying client data to %s, desc chain (head desc_idx %d)\n",
    295295               QUEUENAME(qIdx), uUsedIdx));
    296296
     
    328328        size_t cbInSgBuf = RTSgBufCalcTotalLength(pBufDst);
    329329        size_t cbWritten = cbInSgBuf - RTSgBufCalcLengthLeft(pBufDst);
    330         Log2Func(("Copied %u bytes to %u byte buffer, residual=%d\n",
     330        Log2Func((".... Copied %u bytes to %u byte buffer, residual=%d\n",
    331331             cbWritten, cbInSgBuf, cbInSgBuf - cbWritten));
    332332    }
    333     Log3Func(("Write ahead used_idx=%d, %s used_idx=%d\n",
     333    Log6Func(("Write ahead used_idx=%d, %s used_idx=%d\n",
    334334         pVirtqProxy->uUsedIdx,  QUEUENAME(qIdx), uUsedIdx));
    335335
     
    351351
    352352    uint16_t uIdx = virtioReadUsedRingIdx(pVirtio, qIdx);
    353     Log3Func(("Updating %s used_idx from %u to %u\n",
     353    Log6Func(("Updating %s used_idx from %u to %u\n",
    354354              QUEUENAME(qIdx), uIdx, pVirtqProxy->uUsedIdx));
    355355
     
    368368
    369369    PVIRTQ_PROXY_T pVirtqProxy = &pVirtio->virtqProxy[qIdx];
    370     Log3Func(("%s\n", pVirtqProxy->szVirtqName));
     370    Log6Func(("%s\n", pVirtqProxy->szVirtqName));
    371371
    372372
     
    398398                return;
    399399            }
    400             Log3Func(("...skipping interrupt: VIRTIO_F_EVENT_IDX set but threshold not reached\n"));
     400            Log6Func(("...skipping interrupt: VIRTIO_F_EVENT_IDX set but threshold not reached\n"));
    401401        }
    402402        else
     
    408408                return;
    409409            }
    410             Log3Func(("...skipping interrupt. Guest flagged VIRTQ_AVAIL_F_NO_INTERRUPT for queue\n"));
     410            Log6Func(("...skipping interrupt. Guest flagged VIRTQ_AVAIL_F_NO_INTERRUPT for queue\n"));
    411411
    412412        }
     
    456456{
    457457   if (uCause == VIRTIO_ISR_VIRTQ_INTERRUPT)
    458        Log3Func(("reason: buffer added to 'used' ring.\n"));
     458       Log6Func(("reason: buffer added to 'used' ring.\n"));
    459459   else
    460460   if (uCause == VIRTIO_ISR_DEVICE_CONFIG)
    461        Log3Func(("reason: device config change\n"));
     461       Log6Func(("reason: device config change\n"));
    462462
    463463    pVirtio->uISR |= uCause;
     
    642642        {
    643643            pVirtio->uDeviceStatus = *(uint8_t *)pv;
    644             Log3Func(("Guest wrote uDeviceStatus ................ ("));
     644            Log6Func(("Guest wrote uDeviceStatus ................ ("));
    645645            virtioLogDeviceStatus(pVirtio->uDeviceStatus);
    646             Log3((")\n"));
     646            Log6((")\n"));
    647647            if (pVirtio->uDeviceStatus == 0)
    648648                virtioGuestResetted(pVirtio);
     
    659659        else /* Guest READ pCommonCfg->uDeviceStatus */
    660660        {
    661             Log3Func(("Guest read  uDeviceStatus ................ ("));
     661            Log6Func(("Guest read  uDeviceStatus ................ ("));
    662662            *(uint32_t *)pv = pVirtio->uDeviceStatus;
    663663            virtioLogDeviceStatus(pVirtio->uDeviceStatus);
    664             Log3((")\n"));
     664            Log6((")\n"));
    665665        }
    666666    }
     
    764764        {
    765765            ++pVirtio->uConfigGeneration;
    766             Log3Func(("Bumped cfg. generation to %d because %s%s\n",
     766            Log6Func(("Bumped cfg. generation to %d because %s%s\n",
    767767                pVirtio->uConfigGeneration,
    768768                fDevSpecificFieldChanged ? "<dev cfg changed> " : "",
     
    781781    {
    782782        *(uint8_t *)pv = pVirtio->uISR;
    783         Log3Func(("Read and clear ISR\n"));
     783        Log6Func(("Read and clear ISR\n"));
    784784        pVirtio->uISR = 0; /** VirtIO specification requires reads of ISR to clear it */
    785785        virtioLowerInterrupt(pVirtio);
     
    832832    {
    833833        pVirtio->uISR = *(uint8_t *)pv;
    834         Log3Func(("Setting uISR = 0x%02x (virtq interrupt: %d, dev confg interrupt: %d)\n",
     834        Log6Func(("Setting uISR = 0x%02x (virtq interrupt: %d, dev confg interrupt: %d)\n",
    835835              pVirtio->uISR & 0xff,
    836836              pVirtio->uISR & VIRTIO_ISR_VIRTQ_INTERRUPT,
     
    10451045
    10461046    int rc = VINF_SUCCESS;
    1047 
    10481047
    10491048    PVIRTIOSTATE pVirtio = (PVIRTIOSTATE)RTMemAllocZ(sizeof(VIRTIOSTATE));
     
    14631462}
    14641463
     1464 /**
     1465  * Do a hex dump of a buffer.
     1466  *
     1467  * @param   pv       Pointer to array to dump
     1468  * @param   cb       Number of characters to dump
     1469  * @param   uBase    Base address of offset addresses displayed
     1470  * @param   pszTitle Header line/title for the dump
     1471  *
     1472  */
     1473 void virtioHexDump(uint8_t *pv, size_t cb, uint32_t uBase, const char *pszTitle)
     1474 {
     1475     if (pszTitle)
     1476         Log(("%s [%d bytes]:\n", pszTitle, cb));
     1477     for (uint32_t row = 0; row < RT_MAX(1, (cb / 16) + 1); row++)
     1478     {
     1479         uint32_t uAddr = row * 16 + uBase;
     1480         Log(("%x%x%x%x: ", (uAddr >> 12) & 0xf, (uAddr >> 8) & 0xf, (uAddr >> 4) & 0xf, uAddr & 0xf));
     1481         for (int col = 0; col < 16; col++)
     1482         {
     1483            uint32_t idx = row * 16 + col;
     1484            uint8_t u8 = pv[idx];
     1485            if (idx >= cb)
     1486                Log(("-- %s", (col + 1) % 8 ? "" : "  "));
     1487            else
     1488                Log(("%x%x %s", u8 >> 4 & 0xf, u8 & 0xf, (col + 1) % 8 ? "" : "  "));
     1489         }
     1490         for (int col = 0; col < 16; col++)
     1491         {
     1492            uint32_t idx = row * 16 + col;
     1493            uint8_t u8 = pv[idx];
     1494            if (idx >= cb)
     1495                Log((" "));
     1496            else
     1497                Log(("%c", u8 >= 0x20 && u8 <= 0x7e ? u8 : '.'));
     1498         }
     1499         Log(("\n"));
     1500    }
     1501    Log(("\n"));
     1502 }
    14651503
    14661504#endif /* IN_RING3 */
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h

    r80522 r80596  
    4141#define VIRTIOSCSI_REGION_PORT_IO           1                    /**< BAR for PORT I/O (impl specific)         */
    4242#define VIRTIOSCSI_REGION_PCI_CAP           2                    /**< BAR for VirtIO Cap. MMIO (impl specific) */
     43
     44#define VIRTIO_HEX_DUMP(logLevel, pv, cb, base, title) \
     45    do { \
     46        if (LogIsItEnabled(logLevel, LOG_GROUP)) \
     47            virtioHexDump((pv), (cb), (base), (title)); \
     48    } while (0)
    4349
    4450/**
     
    320326                            bool fWrite, bool fHasIndex, uint32_t idx);
    321327
     328/**
     329 * Does a formatted hex dump using Log(()), recommend using VIRTIO_HEX_DUMP() macro to
     330 * control enabling of logging efficiently.
     331 *
     332 * @param   pv          - pointer to buffer to dump contents of
     333 * @param   cb          - count of characters to dump from buffer
     334 * @param   uBase       - base address of per-row address prefixing of hex output
     335 * @param   pszTitle    - Optional title. If present displays title that lists
     336 *                        provided text with value of cb to indicate size next to it.
     337 */
     338void virtioHexDump(uint8_t *pv, size_t cb, uint32_t uBase, const char *pszTitle);
    322339
    323340#endif /* !VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h */
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0_impl.h

    r80527 r80596  
    409409                      pVirtio->pGcPhysQueueAvail[qIdx] + RT_UOFFSETOF(VIRTQ_AVAIL_T, uIdx),
    410410                      &uIdx, sizeof(uIdx));
    411     Log3Func(("%s actual avail_idx=%d\n", pVirtio->virtqProxy[qIdx].szVirtqName, uIdx));
    412411    return uIdx;
    413412}
     
    512511{
    513512    if (status == 0)
    514         Log3(("RESET"));
     513        Log6(("RESET"));
    515514    else
    516515    {
    517516        int primed = 0;
    518517        if (status & VIRTIO_STATUS_ACKNOWLEDGE)
    519             Log3(("ACKNOWLEDGE",   primed++));
     518            Log6(("ACKNOWLEDGE",   primed++));
    520519        if (status & VIRTIO_STATUS_DRIVER)
    521             Log3(("%sDRIVER",      primed++ ? " | " : ""));
     520            Log6(("%sDRIVER",      primed++ ? " | " : ""));
    522521        if (status & VIRTIO_STATUS_FEATURES_OK)
    523             Log3(("%sFEATURES_OK", primed++ ? " | " : ""));
     522            Log6(("%sFEATURES_OK", primed++ ? " | " : ""));
    524523        if (status & VIRTIO_STATUS_DRIVER_OK)
    525             Log3(("%sDRIVER_OK",   primed++ ? " | " : ""));
     524            Log6(("%sDRIVER_OK",   primed++ ? " | " : ""));
    526525        if (status & VIRTIO_STATUS_FAILED)
    527             Log3(("%sFAILED",      primed++ ? " | " : ""));
     526            Log6(("%sFAILED",      primed++ ? " | " : ""));
    528527        if (status & VIRTIO_STATUS_DEVICE_NEEDS_RESET)
    529             Log3(("%sNEEDS_RESET", primed++ ? " | " : ""));
     528            Log6(("%sNEEDS_RESET", primed++ ? " | " : ""));
    530529    }
    531530}
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