VirtualBox

Changeset 66166 in vbox


Ignore:
Timestamp:
Mar 20, 2017 11:09:16 AM (8 years ago)
Author:
vboxsync
Message:

pdmstorageifs.h,DrvVD.cpp: Add region descriptor API for media which can have multiple regions with different properties (tracks with different sector sizes)

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmstorageifs.h

    r65061 r66166  
    203203typedef const PDMMEDIAGEOMETRY *PCPDMMEDIAGEOMETRY;
    204204
     205/**
     206 * Region data forms known to us from various standards.
     207 */
     208typedef enum PDMMEDIAREGIONDATAFORM
     209{
     210    /** Invalid data form. */
     211    PDMMEDIAREGIONDATAFORM_INVALID = 0,
     212    /** Raw data, no standardized format. */
     213    PDMMEDIAREGIONDATAFORM_RAW,
     214    /** CD-DA (audio CD), 2352 bytes of data. */
     215    PDMMEDIAREGIONDATAFORM_CDDA,
     216    /** CDDA data is pause. */
     217    PDMMEDIAREGIONDATAFORM_CDDA_PAUSE,
     218    /** Mode 1 with 2048 bytes sector size. */
     219    PDMMEDIAREGIONDATAFORM_MODE1_2048,
     220    /** Mode 1 with 2352 bytes sector size. */
     221    PDMMEDIAREGIONDATAFORM_MODE1_2352,
     222    /** Mode 1 with 0 bytes sector size (generated by the drive). */
     223    PDMMEDIAREGIONDATAFORM_MODE1_0,
     224    /** XA Mode with 2336 bytes sector size. */
     225    PDMMEDIAREGIONDATAFORM_XA_2336,
     226    /** XA Mode with 2352 bytes sector size. */
     227    PDMMEDIAREGIONDATAFORM_XA_2352,
     228    /** XA Mode with 0 bytes sector size (generated by the drive). */
     229    PDMMEDIAREGIONDATAFORM_XA_0,
     230    /** Mode 2 with 2336 bytes sector size. */
     231    PDMMEDIAREGIONDATAFORM_MODE2_2336,
     232    /** Mode 2 with 2352 bytes sector size. */
     233    PDMMEDIAREGIONDATAFORM_MODE2_2352,
     234    /** Mode 2 with 0 bytes sector size (generated by the drive). */
     235    PDMMEDIAREGIONDATAFORM_MODE2_0
     236} PDMMEDIAREGIONDATAFORM;
     237/** Pointer to a region data form. */
     238typedef PDMMEDIAREGIONDATAFORM *PPDMMEDIAREGIONDATAFORM;
     239
    205240/** Pointer to a media port interface. */
    206241typedef struct PDMIMEDIAPORT *PPDMIMEDIAPORT;
     
    461496    DECLR3CALLBACKMEMBER(int, pfnDiscard,(PPDMIMEDIA pInterface, PCRTRANGE paRanges, unsigned cRanges));
    462497
     498    /**
     499     * Returns the number of regions for the medium.
     500     *
     501     * @returns Number of regions.
     502     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
     503     */
     504    DECLR3CALLBACKMEMBER(uint32_t, pfnGetRegionCount,(PPDMIMEDIA pInterface));
     505
     506    /**
     507     * Queries the properties for the given region.
     508     *
     509     * @returns VBox status code.
     510     * @retval  VERR_NOT_FOUND if the region index is not known.
     511     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
     512     * @param   uRegion         The region index to query the properties of.
     513     * @param   pu64LbaStart    Where to store the starting LBA for the region on success.
     514     * @param   pcBlocks        Where to store the number of blocks for the region on success.
     515     * @param   pcbBlock        Where to store the size of one block in bytes on success.
     516     * @param   penmDataForm    WHere to store the data form for the region on success.
     517     */
     518    DECLR3CALLBACKMEMBER(int, pfnQueryRegionProperties,(PPDMIMEDIA pInterface, uint32_t uRegion, uint64_t *pu64LbaStart,
     519                                                        uint64_t *pcBlocks, uint64_t *pcbBlock,
     520                                                        PPDMMEDIAREGIONDATAFORM penmDataForm));
     521
     522    /**
     523     * Queries the properties for the region covering the given LBA.
     524     *
     525     * @returns VBox status code.
     526     * @retval  VERR_NOT_FOUND if the region index is not known.
     527     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
     528     * @param   u64LbaStart     Where to store the starting LBA for the region on success.
     529     * @param   pcBlocks        Where to store the number of blocks left in this region starting from the given LBA.
     530     * @param   pcbBlock        Where to store the size of one block in bytes on success.
     531     * @param   penmDataForm    WHere to store the data form for the region on success.
     532     */
     533    DECLR3CALLBACKMEMBER(int, pfnQueryRegionPropertiesForLba,(PPDMIMEDIA pInterface, uint64_t u64LbaStart,
     534                                                              uint64_t *pcBlocks, uint64_t *pcbBlock,
     535                                                              PPDMMEDIAREGIONDATAFORM penmDataForm));
     536
    463537} PDMIMEDIA;
    464538/** PDMIMEDIA interface ID. */
    465 #define PDMIMEDIA_IID                           "527246f5-f300-47a7-9ec3-03d8ea8bf9de"
     539#define PDMIMEDIA_IID                           "c2d1d87a-e1ae-4a70-ac85-f2ffe9c5b736"
    466540
    467541
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r65919 r66166  
    364364    /** BIOS LCHS Geometry. */
    365365    PDMMEDIAGEOMETRY        LCHSGeometry;
     366    /** Region list. */
     367    PVDREGIONLIST           pRegionList;
    366368
    367369    /** Cryptographic support
     
    535537}
    536538
     539/**
     540 * Converts from VD region data form enum to the PDM variant.
     541 *
     542 * @returns PDM media region data form.
     543 * @param   enmDataForm         The VD region data form.
     544 */
     545static PDMMEDIAREGIONDATAFORM drvvdVDRegionForm2PdmDataForm(VDREGIONDATAFORM enmDataForm)
     546{
     547    switch (enmDataForm)
     548    {
     549        #define VDDATAFORM2PDM(tag) case VDREGIONDATAFORM_##tag: return PDMMEDIAREGIONDATAFORM_##tag
     550
     551        VDDATAFORM2PDM(INVALID);
     552        VDDATAFORM2PDM(RAW);
     553        VDDATAFORM2PDM(CDDA);
     554        VDDATAFORM2PDM(CDDA_PAUSE);
     555        VDDATAFORM2PDM(MODE1_2048);
     556        VDDATAFORM2PDM(MODE1_2352);
     557        VDDATAFORM2PDM(MODE1_0);
     558        VDDATAFORM2PDM(XA_2336);
     559        VDDATAFORM2PDM(XA_2352);
     560        VDDATAFORM2PDM(XA_0);
     561        VDDATAFORM2PDM(MODE2_2336);
     562        VDDATAFORM2PDM(MODE2_2352);
     563        VDDATAFORM2PDM(MODE2_0);
     564
     565        #undef VDDATAFORM2PDM
     566
     567        default:
     568        {
     569            AssertMsgFailed(("Unknown data form %d! forgot to add it to the switch?\n", enmDataForm));
     570            return PDMMEDIAREGIONDATAFORM_INVALID;
     571        }
     572    }
     573}
    537574
    538575/*********************************************************************************************************************************
     
    24512488}
    24522489
     2490/** @interface_method_impl{PDMIMEDIA,pfnDiscard} */
    24532491static DECLCALLBACK(int) drvvdDiscard(PPDMIMEDIA pInterface, PCRTRANGE paRanges, unsigned cRanges)
    24542492{
     
    24642502    else
    24652503        STAM_REL_COUNTER_INC(&pThis->StatReqsFailed);
     2504
     2505    LogFlowFunc(("returns %Rrc\n", rc));
     2506    return rc;
     2507}
     2508
     2509/** @interface_method_impl{PDMIMEDIA,pfnGetRegionCount} */
     2510static DECLCALLBACK(uint32_t) drvvdGetRegionCount(PPDMIMEDIA pInterface)
     2511{
     2512    LogFlowFunc(("\n"));
     2513    PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
     2514    uint32_t cRegions = 0;
     2515
     2516    if (!pThis->pRegionList)
     2517    {
     2518        int rc = VDQueryRegions(pThis->pDisk, VD_LAST_IMAGE, VD_REGION_LIST_F_LOC_SIZE_BLOCKS,
     2519                                &pThis->pRegionList);
     2520        if (RT_SUCCESS(rc))
     2521            cRegions = pThis->pRegionList->cRegions;
     2522    }
     2523    else
     2524        cRegions = pThis->pRegionList->cRegions;
     2525
     2526    LogFlowFunc(("returns %u\n", cRegions));
     2527    return cRegions;
     2528}
     2529
     2530/** @interface_method_impl{PDMIMEDIA,pfnQueryRegionProperties} */
     2531static DECLCALLBACK(int) drvvdQueryRegionProperties(PPDMIMEDIA pInterface, uint32_t uRegion, uint64_t *pu64LbaStart,
     2532                                                    uint64_t *pcBlocks, uint64_t *pcbBlock,
     2533                                                    PPDMMEDIAREGIONDATAFORM penmDataForm)
     2534{
     2535    LogFlowFunc(("\n"));
     2536    int rc = VINF_SUCCESS;
     2537    PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
     2538
     2539    if (   pThis->pRegionList
     2540        && uRegion < pThis->pRegionList->cRegions)
     2541    {
     2542        PCVDREGIONDESC pRegion = &pThis->pRegionList->aRegions[uRegion];
     2543
     2544        if (pu64LbaStart)
     2545            *pu64LbaStart = pRegion->offRegion;
     2546        if (pcBlocks)
     2547            *pcBlocks = pRegion->cRegionBlocksOrBytes;
     2548        if (pcbBlock)
     2549            *pcbBlock = pRegion->cbBlock;
     2550        if (penmDataForm)
     2551            *penmDataForm = drvvdVDRegionForm2PdmDataForm(pRegion->enmDataForm);
     2552    }
     2553    else
     2554        rc = VERR_NOT_FOUND;
     2555
     2556    LogFlowFunc(("returns %Rrc\n", rc));
     2557    return rc;
     2558}
     2559
     2560/** @interface_method_impl{PDMIMEDIA,pfnQueryRegionPropertiesForLba} */
     2561static DECLCALLBACK(int) drvvdQueryRegionPropertiesForLba(PPDMIMEDIA pInterface, uint64_t u64LbaStart,
     2562                                                          uint64_t *pcBlocks, uint64_t *pcbBlock,
     2563                                                          PPDMMEDIAREGIONDATAFORM penmDataForm)
     2564{
     2565    LogFlowFunc(("\n"));
     2566    int rc = VINF_SUCCESS;
     2567    PVBOXDISK pThis = PDMIMEDIA_2_VBOXDISK(pInterface);
     2568
     2569    if (!pThis->pRegionList)
     2570        rc = VDQueryRegions(pThis->pDisk, VD_LAST_IMAGE, VD_REGION_LIST_F_LOC_SIZE_BLOCKS,
     2571                            &pThis->pRegionList);
     2572
     2573    if (RT_SUCCESS(rc))
     2574    {
     2575        rc = VERR_NOT_FOUND;
     2576
     2577        for (uint32_t i = 0; i < pThis->pRegionList->cRegions; i++)
     2578        {
     2579            PCVDREGIONDESC pRegion = &pThis->pRegionList->aRegions[i];
     2580            if (   pRegion->offRegion <= u64LbaStart
     2581                && pRegion->offRegion + pRegion->cRegionBlocksOrBytes > u64LbaStart)
     2582            {
     2583                uint64_t offRegion = u64LbaStart - pRegion->offRegion;
     2584
     2585                if (pcBlocks)
     2586                    *pcBlocks = pRegion->cRegionBlocksOrBytes - offRegion;
     2587                if (pcbBlock)
     2588                    *pcbBlock = pRegion->cbBlock;
     2589                if (penmDataForm)
     2590                    *penmDataForm = drvvdVDRegionForm2PdmDataForm(pRegion->enmDataForm);
     2591
     2592                rc = VINF_SUCCESS;
     2593            }
     2594        }
     2595    }
     2596    else
     2597        rc = VERR_NOT_FOUND;
    24662598
    24672599    LogFlowFunc(("returns %Rrc\n", rc));
     
    44964628        PDMR3BlkCacheRelease(pThis->pBlkCache);
    44974629        pThis->pBlkCache = NULL;
     4630    }
     4631
     4632    if (RT_VALID_PTR(pThis->pRegionList))
     4633    {
     4634        VDRegionListFree(pThis->pRegionList);
     4635        pThis->pRegionList = NULL;
    44984636    }
    44994637
     
    47524890    pThis->hIoReqCache                  = NIL_RTMEMCACHE;
    47534891    pThis->hIoBufMgr                    = NIL_IOBUFMGR;
     4892    pThis->pRegionList                  = NULL;
    47544893
    47554894    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aIoReqAllocBins); i++)
     
    47574896
    47584897    /* IMedia */
    4759     pThis->IMedia.pfnRead               = drvvdRead;
    4760     pThis->IMedia.pfnReadPcBios         = drvvdReadPcBios;
    4761     pThis->IMedia.pfnWrite              = drvvdWrite;
    4762     pThis->IMedia.pfnFlush              = drvvdFlush;
    4763     pThis->IMedia.pfnMerge              = drvvdMerge;
    4764     pThis->IMedia.pfnSetSecKeyIf        = drvvdSetSecKeyIf;
    4765     pThis->IMedia.pfnGetSize            = drvvdGetSize;
    4766     pThis->IMedia.pfnGetSectorSize      = drvvdGetSectorSize;
    4767     pThis->IMedia.pfnIsReadOnly         = drvvdIsReadOnly;
    4768     pThis->IMedia.pfnIsNonRotational     = drvvdIsNonRotational;
    4769     pThis->IMedia.pfnBiosGetPCHSGeometry = drvvdBiosGetPCHSGeometry;
    4770     pThis->IMedia.pfnBiosSetPCHSGeometry = drvvdBiosSetPCHSGeometry;
    4771     pThis->IMedia.pfnBiosGetLCHSGeometry = drvvdBiosGetLCHSGeometry;
    4772     pThis->IMedia.pfnBiosSetLCHSGeometry = drvvdBiosSetLCHSGeometry;
    4773     pThis->IMedia.pfnBiosIsVisible       = drvvdBiosIsVisible;
    4774     pThis->IMedia.pfnGetType             = drvvdGetType;
    4775     pThis->IMedia.pfnGetUuid             = drvvdGetUuid;
    4776     pThis->IMedia.pfnDiscard             = drvvdDiscard;
    4777     pThis->IMedia.pfnSendCmd             = NULL;
     4898    pThis->IMedia.pfnRead                        = drvvdRead;
     4899    pThis->IMedia.pfnReadPcBios                  = drvvdReadPcBios;
     4900    pThis->IMedia.pfnWrite                       = drvvdWrite;
     4901    pThis->IMedia.pfnFlush                       = drvvdFlush;
     4902    pThis->IMedia.pfnMerge                       = drvvdMerge;
     4903    pThis->IMedia.pfnSetSecKeyIf                 = drvvdSetSecKeyIf;
     4904    pThis->IMedia.pfnGetSize                     = drvvdGetSize;
     4905    pThis->IMedia.pfnGetSectorSize               = drvvdGetSectorSize;
     4906    pThis->IMedia.pfnIsReadOnly                  = drvvdIsReadOnly;
     4907    pThis->IMedia.pfnIsNonRotational             = drvvdIsNonRotational;
     4908    pThis->IMedia.pfnBiosGetPCHSGeometry         = drvvdBiosGetPCHSGeometry;
     4909    pThis->IMedia.pfnBiosSetPCHSGeometry         = drvvdBiosSetPCHSGeometry;
     4910    pThis->IMedia.pfnBiosGetLCHSGeometry         = drvvdBiosGetLCHSGeometry;
     4911    pThis->IMedia.pfnBiosSetLCHSGeometry         = drvvdBiosSetLCHSGeometry;
     4912    pThis->IMedia.pfnBiosIsVisible               = drvvdBiosIsVisible;
     4913    pThis->IMedia.pfnGetType                     = drvvdGetType;
     4914    pThis->IMedia.pfnGetUuid                     = drvvdGetUuid;
     4915    pThis->IMedia.pfnDiscard                     = drvvdDiscard;
     4916    pThis->IMedia.pfnSendCmd                     = NULL;
     4917    pThis->IMedia.pfnGetRegionCount              = drvvdGetRegionCount;
     4918    pThis->IMedia.pfnQueryRegionProperties       = drvvdQueryRegionProperties;
     4919    pThis->IMedia.pfnQueryRegionPropertiesForLba = drvvdQueryRegionPropertiesForLba;
    47784920
    47794921    /* IMount */
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