VirtualBox

Changeset 43640 in vbox


Ignore:
Timestamp:
Oct 15, 2012 12:39:52 PM (12 years ago)
Author:
vboxsync
Message:

VSCSI: Added basic media change support.

Location:
trunk
Files:
7 edited

Legend:

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

    r39566 r43640  
    271271
    272272/**
     273 * Notify virtual SCSI LUN of medium being mounted.
     274 *
     275 * @returns VBox status code.
     276 * @param   hVScsiLun               The virtual SCSI LUN handle to destroy.
     277 */
     278VBOXDDU_DECL(int) VSCSILunMountNotify(VSCSILUN hVScsiLun);
     279
     280/**
     281 * Notify virtual SCSI LUN of medium being unmounted.
     282 *
     283 * @returns VBox status code.
     284 * @param   hVScsiLun               The virtual SCSI LUN handle to destroy.
     285 */
     286VBOXDDU_DECL(int) VSCSILunUnmountNotify(VSCSILUN hVScsiLun);
     287
     288/**
    273289 * Notify a that a I/O request completed.
    274290 *
  • trunk/src/VBox/Devices/Storage/DrvSCSI.cpp

    r43517 r43640  
    668668        return;
    669669
    670     //@todo: Notify of media change? Update media size?
     670    /* Let the LUN know that a medium was mounted. */
     671    VSCSILunMountNotify(pThis->hVScsiLun);
    671672}
    672673
     
    681682    LogFlowFunc(("unmounting LUN#%p\n", pThis->hVScsiLun));
    682683
    683     //@todo: Notify of media change? Report that no media is present?
     684    /* Let the LUN know that the medium was unmounted. */
     685    VSCSILunUnmountNotify(pThis->hVScsiLun);
    684686}
    685687
     
    854856    PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);
    855857    LogFlowFunc(("pDrvIns=%#p pCfg=%#p\n", pDrvIns, pCfg));
     858LogRelFunc(("pDrvIns=%#p pCfg=%#p\n", pDrvIns, pCfg));
    856859    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    857860
     
    966969    rc = VSCSIDeviceLunAttach(pThis->hVScsiDevice, pThis->hVScsiLun, 0);
    967970    AssertMsgReturn(RT_SUCCESS(rc), ("Failed to attached the LUN to the SCSI device\n"), rc);
     971
     972    //@todo: This is a very hacky way of telling the LUN whether a medium was mounted.
     973    // The mount/unmount interface doesn't work in a very sensible manner!
     974    if (pThis->pDrvMount)
     975    {
     976        if (pThis->pDrvBlock->pfnGetSize(pThis->pDrvBlock))
     977        {
     978            rc = VINF_SUCCESS; VSCSILunMountNotify(pThis->hVScsiLun);
     979            AssertMsgReturn(RT_SUCCESS(rc), ("Failed to notify the LUN of media being mounted\n"), rc);
     980        }
     981        else
     982        {
     983            rc = VINF_SUCCESS; VSCSILunUnmountNotify(pThis->hVScsiLun);
     984            AssertMsgReturn(RT_SUCCESS(rc), ("Failed to notify the LUN of media being unmounted\n"), rc);
     985        }
     986    }
    968987
    969988    /* Register statistics counter. */
     
    10541073    PDM_DRVREG_VERSION
    10551074};
    1056 
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp

    r38680 r43640  
    102102        case SCSI_TEST_UNIT_READY:
    103103        {
    104             *prcReq = vscsiReqSenseOkSet(&pVScsiDevice->VScsiSense, pVScsiReq);
     104            if (pVScsiDevice->papVScsiLun[pVScsiReq->iLun]->fReady)
     105                *prcReq = vscsiReqSenseOkSet(&pVScsiDevice->VScsiSense, pVScsiReq);
     106            else
     107                fProcessed = false; /* The LUN will provide details. */
    105108            break;
    106109        }
     
    344347    return VINF_SUCCESS;
    345348}
    346 
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h

    r39515 r43640  
    8686    /** Pointer to the LUN type descriptor. */
    8787    PVSCSILUNDESC        pVScsiLunDesc;
     88    /** Flag indicating whether LUN is ready. */
     89    bool                 fReady;
     90    /** Flag indicating media presence in LUN. */
     91    bool                 fMediaPresent;
    8892    /** Flags of supported features. */
    8993    uint64_t             fFeatures;
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSILun.cpp

    r38844 r43640  
    116116}
    117117
     118/**
     119 * Notify virtual SCSI LUN of media being mounted.
     120 *
     121 * @returns VBox status code.
     122 * @param   hVScsiLun               The virtual SCSI LUN
     123 *                                  mounting the medium.
     124 */
     125VBOXDDU_DECL(int) VSCSILunMountNotify(VSCSILUN hVScsiLun)
     126{
     127    PVSCSILUNINT pVScsiLun = (PVSCSILUNINT)hVScsiLun;
     128
     129    LogFlowFunc(("hVScsiLun=%p\n", hVScsiLun));
     130    AssertPtrReturn(pVScsiLun, VERR_INVALID_HANDLE);
     131    AssertReturn(vscsiIoReqOutstandingCountGet(pVScsiLun) == 0, VERR_VSCSI_LUN_BUSY);
     132
     133    /* Mark the LUN as not ready so that LUN specific code can do its job. */
     134    pVScsiLun->fReady        = false;
     135    pVScsiLun->fMediaPresent = true;
     136
     137    return VINF_SUCCESS;
     138}
     139
     140/**
     141 * Notify virtual SCSI LUN of media being unmounted.
     142 *
     143 * @returns VBox status code.
     144 * @param   hVScsiLun               The virtual SCSI LUN
     145 *                                  mounting the medium.
     146 */
     147VBOXDDU_DECL(int) VSCSILunUnmountNotify(VSCSILUN hVScsiLun)
     148{
     149    PVSCSILUNINT pVScsiLun = (PVSCSILUNINT)hVScsiLun;
     150
     151    LogFlowFunc(("hVScsiLun=%p\n", hVScsiLun));
     152    AssertPtrReturn(pVScsiLun, VERR_INVALID_HANDLE);
     153    AssertReturn(vscsiIoReqOutstandingCountGet(pVScsiLun) == 0, VERR_VSCSI_LUN_BUSY);
     154
     155    pVScsiLun->fReady        = false;
     156    pVScsiLun->fMediaPresent = false;
     157
     158    return VINF_SUCCESS;
     159}
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp

    r43587 r43640  
    153153    int             rc = VINF_SUCCESS;
    154154    int             rcReq = SCSI_STATUS_OK;
    155 
    156     switch(pVScsiReq->pbCDB[0])
    157     {
     155    unsigned        uCmd = pVScsiReq->pbCDB[0];
     156
     157    /*
     158     * GET CONFIGURATION, GET EVENT/STATUS NOTIFICATION, INQUIRY, and REQUEST SENSE commands
     159     * operate even when a unit attention condition exists for initiator; every other command
     160     * needs to report CHECK CONDITION in that case.
     161     */
     162    if (!pVScsiLunMmc->Core.fReady && uCmd != SCSI_INQUIRY)
     163    {
     164        /*
     165         * A note on media changes: As long as a medium is not present, the unit remains in
     166         * the 'not ready' state. Technically the unit becomes 'ready' soon after a medium
     167         * is inserted; however, we internally keep the 'not ready' state until we've had
     168         * a chance to report the UNIT ATTENTION status indicating a media change.
     169         */
     170        if (pVScsiLunMmc->Core.fMediaPresent)
     171        {
     172            rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_UNIT_ATTENTION,
     173                                             SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED, 0x00);
     174            pVScsiLunMmc->Core.fReady = true;
     175        }
     176        else
     177            rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_NOT_READY,
     178                                             SCSI_ASC_MEDIUM_NOT_PRESENT, 0x00);
     179    }
     180    else
     181    {
     182        switch (uCmd)
     183        {
     184        case SCSI_TEST_UNIT_READY:
     185            Assert(!pVScsiLunMmc->Core.fReady); /* Only should get here if LUN isn't ready. */
     186            rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT, 0x00);
     187            break;
     188
    158189        case SCSI_INQUIRY:
    159190        {
     
    373404            //AssertMsgFailed(("Command %#x [%s] not implemented\n", pVScsiReq->pbCDB[0], SCSICmdText(pVScsiReq->pbCDB[0])));
    374405            rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE, 0x00);
     406        }
    375407    }
    376408
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp

    r39566 r43640  
    168168    }
    169169
     170    /* For SBC LUNs, there will be no ready state transitions. */
     171    pVScsiLunSbc->Core.fReady = true;
     172
    170173    return rc;
    171174}
     
    446449                    && cbList >= 8)
    447450                {
    448                     size_t cBlkDesc = vscsiBE2HU16(&abHdr[2]) / 16;
     451                    uint32_t    cBlkDesc = vscsiBE2HU16(&abHdr[2]) / 16;
    449452
    450453                    if (cBlkDesc)
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