VirtualBox

Changeset 24760 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 18, 2009 4:05:27 PM (15 years ago)
Author:
vboxsync
Message:

DevAHCI: A little cleanup.

File:
1 edited

Legend:

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

    r24750 r24760  
    22692269#ifdef IN_RING3
    22702270
    2271 static DECLCALLBACK(int) ahciMMIOMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
     2271static DECLCALLBACK(int) ahciR3MMIOMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
    22722272{
    22732273    PAHCI pThis = PCIDEV_2_PAHCI(pPciDev);
     
    23092309 * Map the legacy I/O port ranges to make Solaris work with the controller.
    23102310 */
    2311 static DECLCALLBACK(int) ahciLegacyFakeIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
     2311static DECLCALLBACK(int) ahciR3LegacyFakeIORangeMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
    23122312{
    23132313    PAHCI pThis = PCIDEV_2_PAHCI(pPciDev);
     
    23542354 * @param   ppLed           Where to store the LED pointer.
    23552355 */
    2356 static DECLCALLBACK(int) ahciStatus_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
     2356static DECLCALLBACK(int) ahciR3Status_QueryStatusLed(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed)
    23572357{
    23582358    PAHCI pAhci = PDMILEDPORTS_2_PAHCI(pInterface);
     
    23742374 * @param   enmInterface        The requested interface identification.
    23752375 */
    2376 static DECLCALLBACK(void *) ahciStatus_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
     2376static DECLCALLBACK(void *) ahciR3Status_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
    23772377{
    23782378    PAHCI pAhci = PDMIBASE_2_PAHCI(pInterface);
     
    23912391 * Query interface method for the AHCI port.
    23922392 */
    2393 static DECLCALLBACK(void *) ahciPortQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
     2393static DECLCALLBACK(void *) ahciR3PortQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
    23942394{
    23952395    PAHCIPort pAhciPort = PDMIBASE_2_PAHCIPORT(pInterface);
     
    24072407            return NULL;
    24082408    }
    2409 }
    2410 
    2411 static DECLCALLBACK(void) ahciRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
    2412 {
    2413     uint32_t i;
    2414     PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
    2415 
    2416     pAhci->pDevInsRC += offDelta;
    2417     pAhci->pHbaCccTimerRC = TMTimerRCPtr(pAhci->pHbaCccTimerR3);
    2418     pAhci->pNotifierQueueRC = PDMQueueRCPtr(pAhci->pNotifierQueueR3);
    2419 
    2420     /* Relocate every port. */
    2421     for (i = 0; i < RT_ELEMENTS(pAhci->ahciPort); i++)
    2422     {
    2423         PAHCIPort pAhciPort = &pAhci->ahciPort[i];
    2424         pAhciPort->pAhciRC += offDelta;
    2425         pAhciPort->pDevInsRC += offDelta;
    2426     }
    2427 
    2428     /* Relocate emulated ATA controllers. */
    2429     for (i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
    2430         ataControllerRelocate(&pAhci->aCts[i], offDelta);
    24312409}
    24322410
     
    57225700}
    57235701
    5724 /**
    5725  * Destroy a driver instance.
     5702/* -=-=-=-=- Helper -=-=-=-=- */
     5703
     5704/**
     5705 * Checks if all asynchronous I/O is finished.
    57265706 *
    5727  * Most VM resources are freed by the VM. This callback is provided so that any non-VM
    5728  * resources can be freed correctly.
    5729  *
    5730  * @param   pDevIns     The device instance data.
    5731  */
    5732 static DECLCALLBACK(int) ahciDestruct(PPDMDEVINS pDevIns)
    5733 {
    5734     PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
    5735     int rc = VINF_SUCCESS;
    5736     unsigned iActPort = 0;
    5737 
    5738     /*
    5739      * At this point the async I/O thread is suspended and will not enter
    5740      * this module again. So, no coordination is needed here and PDM
    5741      * will take care of terminating and cleaning up the thread.
    5742      */
    5743     if (PDMCritSectIsInitialized(&pAhci->lock))
    5744     {
    5745         TMR3TimerDestroy(pAhci->CTX_SUFF(pHbaCccTimer));
    5746 
    5747         Log(("%s: Destruct every port\n", __FUNCTION__));
    5748         for (iActPort = 0; iActPort < pAhci->cPortsImpl; iActPort++)
    5749         {
    5750             PAHCIPort pAhciPort = &pAhci->ahciPort[iActPort];
    5751 
    5752             if (pAhciPort->pAsyncIOThread)
    5753             {
    5754                 /* Destroy the event semaphore. */
    5755                 rc = RTSemEventDestroy(pAhciPort->AsyncIORequestSem);
    5756                 if (RT_FAILURE(rc))
    5757                 {
    5758                     Log(("%s: Destroying event semaphore for port %d failed rc=%Rrc\n", __FUNCTION__, iActPort, rc));
    5759                 }
    5760             }
    5761 
    5762             /* Free all cached tasks. */
    5763             for (uint32_t i = 0; i < AHCI_NR_COMMAND_SLOTS; i++)
    5764             {
    5765                 if (pAhciPort->aCachedTasks[i])
    5766                 {
    5767                     if (pAhciPort->aCachedTasks[i]->pSGListHead)
    5768                         RTMemFree(pAhciPort->aCachedTasks[i]->pSGListHead);
    5769                     if (pAhciPort->aCachedTasks[i]->paSGEntries)
    5770                         RTMemFree(pAhciPort->aCachedTasks[i]->paSGEntries);
    5771 
    5772                     RTMemFree(pAhciPort->aCachedTasks[i]);
    5773                 }
    5774             }
    5775         }
    5776 
    5777         /* Destroy emulated ATA controllers. */
    5778         for (unsigned i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
    5779             ataControllerDestroy(&pAhci->aCts[i]);
    5780 
    5781         PDMR3CritSectDelete(&pAhci->lock);
    5782     }
    5783 
    5784     return rc;
    5785 }
    5786 
    5787 /**
    5788  * Configure the attached device for a port.
    5789  *
    5790  * @returns VBox status code
    5791  * @param   pDevIns     The device instance data.
    5792  * @param   pAhciPort   The port for which the device is to be configured.
    5793  */
    5794 static int ahciConfigureLUN(PPDMDEVINS pDevIns, PAHCIPort pAhciPort)
    5795 {
    5796     int          rc = VINF_SUCCESS;
    5797     PDMBLOCKTYPE enmType;
    5798 
    5799     /*
    5800      * Query the block and blockbios interfaces.
    5801      */
    5802     pAhciPort->pDrvBlock = (PDMIBLOCK *)pAhciPort->pDrvBase->pfnQueryInterface(pAhciPort->pDrvBase, PDMINTERFACE_BLOCK);
    5803     if (!pAhciPort->pDrvBlock)
    5804     {
    5805         AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pAhciPort->iLUN));
    5806         return VERR_PDM_MISSING_INTERFACE;
    5807     }
    5808     pAhciPort->pDrvBlockBios = (PDMIBLOCKBIOS *)pAhciPort->pDrvBase->pfnQueryInterface(pAhciPort->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
    5809     if (!pAhciPort->pDrvBlockBios)
    5810     {
    5811         AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pAhciPort->iLUN));
    5812         return VERR_PDM_MISSING_INTERFACE;
    5813     }
    5814 
    5815     pAhciPort->pDrvMount = (PDMIMOUNT *)pAhciPort->pDrvBase->pfnQueryInterface(pAhciPort->pDrvBase, PDMINTERFACE_MOUNT);
    5816 
    5817     /* Try to get the optional async block interface. */
    5818     pAhciPort->pDrvBlockAsync = (PDMIBLOCKASYNC *)pAhciPort->pDrvBase->pfnQueryInterface(pAhciPort->pDrvBase, PDMINTERFACE_BLOCK_ASYNC);
    5819 
    5820     /*
    5821      * Validate type.
    5822      */
    5823     enmType = pAhciPort->pDrvBlock->pfnGetType(pAhciPort->pDrvBlock);
    5824 
    5825     if (   enmType != PDMBLOCKTYPE_HARD_DISK
    5826         && enmType != PDMBLOCKTYPE_CDROM
    5827         && enmType != PDMBLOCKTYPE_DVD)
    5828     {
    5829         AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd. enmType=%d\n", pAhciPort->iLUN, enmType));
    5830         return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
    5831     }
    5832 
    5833     if (   (enmType == PDMBLOCKTYPE_CDROM || enmType == PDMBLOCKTYPE_DVD)
    5834         && !pAhciPort->pDrvMount)
    5835     {
    5836         AssertMsgFailed(("Internal error: CD/DVD-ROM without a mountable interface\n"));
    5837         return VERR_INTERNAL_ERROR;
    5838     }
    5839     pAhciPort->fATAPI = (enmType == PDMBLOCKTYPE_CDROM || enmType == PDMBLOCKTYPE_DVD);
    5840 
    5841     if (pAhciPort->fATAPI)
    5842     {
    5843         pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / 2048;
    5844         pAhciPort->PCHSGeometry.cCylinders = 0;
    5845         pAhciPort->PCHSGeometry.cHeads     = 0;
    5846         pAhciPort->PCHSGeometry.cSectors   = 0;
    5847         LogRel(("AHCI LUN#%d: CD/DVD, total number of sectors %Ld\n", pAhciPort->iLUN, pAhciPort->cTotalSectors));
    5848     }
    5849     else
    5850     {
    5851         pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / 512;
    5852         rc = pAhciPort->pDrvBlockBios->pfnGetPCHSGeometry(pAhciPort->pDrvBlockBios,
    5853                                                           &pAhciPort->PCHSGeometry);
    5854         if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
    5855         {
    5856             pAhciPort->PCHSGeometry.cCylinders = 0;
    5857             pAhciPort->PCHSGeometry.cHeads     = 16; /*??*/
    5858             pAhciPort->PCHSGeometry.cSectors   = 63; /*??*/
    5859         }
    5860         else if (rc == VERR_PDM_GEOMETRY_NOT_SET)
    5861         {
    5862             pAhciPort->PCHSGeometry.cCylinders = 0; /* autodetect marker */
    5863             rc = VINF_SUCCESS;
    5864         }
    5865         AssertRC(rc);
    5866 
    5867         if (   pAhciPort->PCHSGeometry.cCylinders == 0
    5868             || pAhciPort->PCHSGeometry.cHeads == 0
    5869             || pAhciPort->PCHSGeometry.cSectors == 0)
    5870         {
    5871             uint64_t cCylinders = pAhciPort->cTotalSectors / (16 * 63);
    5872             pAhciPort->PCHSGeometry.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1);
    5873             pAhciPort->PCHSGeometry.cHeads = 16;
    5874             pAhciPort->PCHSGeometry.cSectors = 63;
    5875             /* Set the disk geometry information. Ignore errors. */
    5876             pAhciPort->pDrvBlockBios->pfnSetPCHSGeometry(pAhciPort->pDrvBlockBios,
    5877                                                          &pAhciPort->PCHSGeometry);
    5878             rc = VINF_SUCCESS;
    5879         }
    5880         LogRel(("AHCI: LUN#%d: disk, PCHS=%u/%u/%u, total number of sectors %Ld\n",
    5881                  pAhciPort->iLUN, pAhciPort->PCHSGeometry.cCylinders,
    5882                  pAhciPort->PCHSGeometry.cHeads, pAhciPort->PCHSGeometry.cSectors,
    5883                  pAhciPort->cTotalSectors));
    5884     }
    5885     return rc;
    5886 }
    5887 
    5888 /**
    5889  * Checks if all asynchronous I/O is finished.
     5707 * Used by ahciR3Reset, ahciR3Suspend and ahciR3PowerOff. ahciR3SavePrep makes
     5708 * use of it in strict builds (which is why it's up here).
    58905709 *
    58915710 * @returns true if quiesced, false if busy.
     
    59135732}
    59145733
    5915 static DECLCALLBACK(int) ahciSavePrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     5734/* -=-=-=-=- Saved State -=-=-=-=- */
     5735
     5736/**
     5737 * @copydoc FNDEVSSMSAVEPREP
     5738 */
     5739static DECLCALLBACK(int) ahciR3SavePrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    59165740{
    59175741    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     
    59315755}
    59325756
    5933 static DECLCALLBACK(int) ahciLoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     5757/**
     5758 * @copydoc FNDEVSSMLOADPREP
     5759 */
     5760static DECLCALLBACK(int) ahciR3LoadPrep(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    59345761{
    59355762    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     
    59485775
    59495776/**
    5950  * Callback employed by ahciSuspend and ahciPowerOff..
    5951  *
    5952  * @returns true if we've quiesced, false if we're still working.
    5953  * @param   pDevIns     The device instance.
    5954  */
    5955 static DECLCALLBACK(bool) ahciR3IsAsyncSuspendOrPowerOffDone(PPDMDEVINS pDevIns)
    5956 {
    5957     if (!ahciR3AllAsyncIOIsFinished(pDevIns))
    5958         return false;
    5959 
    5960     PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI);
    5961     ASMAtomicWriteBool(&pThis->fSignalIdle, false);
    5962     return true;
    5963 }
    5964 
    5965 /**
    5966  * Common worker for ahciSuspend and ahciPowerOff.
    5967  */
    5968 static void ahciR3SuspendOrPowerOff(PPDMDEVINS pDevIns)
    5969 {
    5970     PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI);
    5971 
    5972     ASMAtomicWriteBool(&pThis->fSignalIdle, true);
    5973     if (!ahciR3AllAsyncIOIsFinished(pDevIns))
    5974         PDMDevHlpSetAsyncNotification(pDevIns, ahciR3IsAsyncSuspendOrPowerOffDone);
    5975     else
    5976         ASMAtomicWriteBool(&pThis->fSignalIdle, false);
    5977 }
    5978 
    5979 /**
    5980  * Suspend notification.
    5981  *
    5982  * @returns VBox status.
    5983  * @param   pDevIns     The device instance data.
    5984  */
    5985 static DECLCALLBACK(void) ahciSuspend(PPDMDEVINS pDevIns)
    5986 {
    5987     PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
    5988     Log(("%s:\n", __FUNCTION__));
    5989 
    5990     ahciR3SuspendOrPowerOff(pDevIns);
    5991 
    5992     for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
    5993         ataControllerSuspend(&pAhci->aCts[i]);
    5994 }
    5995 
    5996 /**
    5997  * Resume notification.
    5998  *
    5999  * @param   pDevIns     The device instance data.
    6000  */
    6001 static DECLCALLBACK(void) ahciResume(PPDMDEVINS pDevIns)
    6002 {
    6003     PAHCI    pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
    6004 
    6005     Log(("%s:\n", __FUNCTION__));
    6006     for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
    6007         ataControllerResume(&pAhci->aCts[i]);
    6008     return;
    6009 }
    6010 
    6011 /**
    60125777 * @copydoc FNDEVSSMLIVEEXEC
    60135778 */
    6014 static DECLCALLBACK(int) ahciLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
     5779static DECLCALLBACK(int) ahciR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
    60155780{
    60165781    PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI);
     
    60415806 * @copydoc FNDEVSSMSAVEEXEC
    60425807 */
    6043 static DECLCALLBACK(int) ahciSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     5808static DECLCALLBACK(int) ahciR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    60445809{
    60455810    PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI);
     
    60505815
    60515816    /* The config */
    6052     rc = ahciLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
     5817    rc = ahciR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
    60535818    AssertRCReturn(rc, rc);
    60545819
     
    61285893 * @param   uPass           The data pass.
    61295894 */
    6130 static DECLCALLBACK(int) ahciLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     5895static DECLCALLBACK(int) ahciR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    61315896{
    61325897    PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI);
     
    62806045}
    62816046
     6047/* -=-=-=-=- device PDM interface -=-=-=-=- */
     6048
     6049static DECLCALLBACK(void) ahciR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
     6050{
     6051    uint32_t i;
     6052    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     6053
     6054    pAhci->pDevInsRC += offDelta;
     6055    pAhci->pHbaCccTimerRC = TMTimerRCPtr(pAhci->pHbaCccTimerR3);
     6056    pAhci->pNotifierQueueRC = PDMQueueRCPtr(pAhci->pNotifierQueueR3);
     6057
     6058    /* Relocate every port. */
     6059    for (i = 0; i < RT_ELEMENTS(pAhci->ahciPort); i++)
     6060    {
     6061        PAHCIPort pAhciPort = &pAhci->ahciPort[i];
     6062        pAhciPort->pAhciRC += offDelta;
     6063        pAhciPort->pDevInsRC += offDelta;
     6064    }
     6065
     6066    /* Relocate emulated ATA controllers. */
     6067    for (i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
     6068        ataControllerRelocate(&pAhci->aCts[i], offDelta);
     6069}
     6070
     6071/**
     6072 * Destroy a driver instance.
     6073 *
     6074 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
     6075 * resources can be freed correctly.
     6076 *
     6077 * @param   pDevIns     The device instance data.
     6078 */
     6079static DECLCALLBACK(int) ahciR3Destruct(PPDMDEVINS pDevIns)
     6080{
     6081    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     6082    int rc = VINF_SUCCESS;
     6083    unsigned iActPort = 0;
     6084
     6085    /*
     6086     * At this point the async I/O thread is suspended and will not enter
     6087     * this module again. So, no coordination is needed here and PDM
     6088     * will take care of terminating and cleaning up the thread.
     6089     */
     6090    if (PDMCritSectIsInitialized(&pAhci->lock))
     6091    {
     6092        TMR3TimerDestroy(pAhci->CTX_SUFF(pHbaCccTimer));
     6093
     6094        Log(("%s: Destruct every port\n", __FUNCTION__));
     6095        for (iActPort = 0; iActPort < pAhci->cPortsImpl; iActPort++)
     6096        {
     6097            PAHCIPort pAhciPort = &pAhci->ahciPort[iActPort];
     6098
     6099            if (pAhciPort->pAsyncIOThread)
     6100            {
     6101                /* Destroy the event semaphore. */
     6102                rc = RTSemEventDestroy(pAhciPort->AsyncIORequestSem);
     6103                if (RT_FAILURE(rc))
     6104                {
     6105                    Log(("%s: Destroying event semaphore for port %d failed rc=%Rrc\n", __FUNCTION__, iActPort, rc));
     6106                }
     6107            }
     6108
     6109            /* Free all cached tasks. */
     6110            for (uint32_t i = 0; i < AHCI_NR_COMMAND_SLOTS; i++)
     6111            {
     6112                if (pAhciPort->aCachedTasks[i])
     6113                {
     6114                    if (pAhciPort->aCachedTasks[i]->pSGListHead)
     6115                        RTMemFree(pAhciPort->aCachedTasks[i]->pSGListHead);
     6116                    if (pAhciPort->aCachedTasks[i]->paSGEntries)
     6117                        RTMemFree(pAhciPort->aCachedTasks[i]->paSGEntries);
     6118
     6119                    RTMemFree(pAhciPort->aCachedTasks[i]);
     6120                }
     6121            }
     6122        }
     6123
     6124        /* Destroy emulated ATA controllers. */
     6125        for (unsigned i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
     6126            ataControllerDestroy(&pAhci->aCts[i]);
     6127
     6128        PDMR3CritSectDelete(&pAhci->lock);
     6129    }
     6130
     6131    return rc;
     6132}
     6133
     6134/**
     6135 * Configure the attached device for a port.
     6136 *
     6137 * Used by ahciR3Construct and ahciR3Attach.
     6138 *
     6139 * @returns VBox status code
     6140 * @param   pDevIns     The device instance data.
     6141 * @param   pAhciPort   The port for which the device is to be configured.
     6142 */
     6143static int ahciR3ConfigureLUN(PPDMDEVINS pDevIns, PAHCIPort pAhciPort)
     6144{
     6145    int          rc = VINF_SUCCESS;
     6146    PDMBLOCKTYPE enmType;
     6147
     6148    /*
     6149     * Query the block and blockbios interfaces.
     6150     */
     6151    pAhciPort->pDrvBlock = (PDMIBLOCK *)pAhciPort->pDrvBase->pfnQueryInterface(pAhciPort->pDrvBase, PDMINTERFACE_BLOCK);
     6152    if (!pAhciPort->pDrvBlock)
     6153    {
     6154        AssertMsgFailed(("Configuration error: LUN#%d hasn't a block interface!\n", pAhciPort->iLUN));
     6155        return VERR_PDM_MISSING_INTERFACE;
     6156    }
     6157    pAhciPort->pDrvBlockBios = (PDMIBLOCKBIOS *)pAhciPort->pDrvBase->pfnQueryInterface(pAhciPort->pDrvBase, PDMINTERFACE_BLOCK_BIOS);
     6158    if (!pAhciPort->pDrvBlockBios)
     6159    {
     6160        AssertMsgFailed(("Configuration error: LUN#%d hasn't a block BIOS interface!\n", pAhciPort->iLUN));
     6161        return VERR_PDM_MISSING_INTERFACE;
     6162    }
     6163
     6164    pAhciPort->pDrvMount = (PDMIMOUNT *)pAhciPort->pDrvBase->pfnQueryInterface(pAhciPort->pDrvBase, PDMINTERFACE_MOUNT);
     6165
     6166    /* Try to get the optional async block interface. */
     6167    pAhciPort->pDrvBlockAsync = (PDMIBLOCKASYNC *)pAhciPort->pDrvBase->pfnQueryInterface(pAhciPort->pDrvBase, PDMINTERFACE_BLOCK_ASYNC);
     6168
     6169    /*
     6170     * Validate type.
     6171     */
     6172    enmType = pAhciPort->pDrvBlock->pfnGetType(pAhciPort->pDrvBlock);
     6173
     6174    if (   enmType != PDMBLOCKTYPE_HARD_DISK
     6175        && enmType != PDMBLOCKTYPE_CDROM
     6176        && enmType != PDMBLOCKTYPE_DVD)
     6177    {
     6178        AssertMsgFailed(("Configuration error: LUN#%d isn't a disk or cd/dvd. enmType=%d\n", pAhciPort->iLUN, enmType));
     6179        return VERR_PDM_UNSUPPORTED_BLOCK_TYPE;
     6180    }
     6181
     6182    if (   (enmType == PDMBLOCKTYPE_CDROM || enmType == PDMBLOCKTYPE_DVD)
     6183        && !pAhciPort->pDrvMount)
     6184    {
     6185        AssertMsgFailed(("Internal error: CD/DVD-ROM without a mountable interface\n"));
     6186        return VERR_INTERNAL_ERROR;
     6187    }
     6188    pAhciPort->fATAPI = (enmType == PDMBLOCKTYPE_CDROM || enmType == PDMBLOCKTYPE_DVD);
     6189
     6190    if (pAhciPort->fATAPI)
     6191    {
     6192        pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / 2048;
     6193        pAhciPort->PCHSGeometry.cCylinders = 0;
     6194        pAhciPort->PCHSGeometry.cHeads     = 0;
     6195        pAhciPort->PCHSGeometry.cSectors   = 0;
     6196        LogRel(("AHCI LUN#%d: CD/DVD, total number of sectors %Ld\n", pAhciPort->iLUN, pAhciPort->cTotalSectors));
     6197    }
     6198    else
     6199    {
     6200        pAhciPort->cTotalSectors = pAhciPort->pDrvBlock->pfnGetSize(pAhciPort->pDrvBlock) / 512;
     6201        rc = pAhciPort->pDrvBlockBios->pfnGetPCHSGeometry(pAhciPort->pDrvBlockBios,
     6202                                                          &pAhciPort->PCHSGeometry);
     6203        if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
     6204        {
     6205            pAhciPort->PCHSGeometry.cCylinders = 0;
     6206            pAhciPort->PCHSGeometry.cHeads     = 16; /*??*/
     6207            pAhciPort->PCHSGeometry.cSectors   = 63; /*??*/
     6208        }
     6209        else if (rc == VERR_PDM_GEOMETRY_NOT_SET)
     6210        {
     6211            pAhciPort->PCHSGeometry.cCylinders = 0; /* autodetect marker */
     6212            rc = VINF_SUCCESS;
     6213        }
     6214        AssertRC(rc);
     6215
     6216        if (   pAhciPort->PCHSGeometry.cCylinders == 0
     6217            || pAhciPort->PCHSGeometry.cHeads == 0
     6218            || pAhciPort->PCHSGeometry.cSectors == 0)
     6219        {
     6220            uint64_t cCylinders = pAhciPort->cTotalSectors / (16 * 63);
     6221            pAhciPort->PCHSGeometry.cCylinders = RT_MAX(RT_MIN(cCylinders, 16383), 1);
     6222            pAhciPort->PCHSGeometry.cHeads = 16;
     6223            pAhciPort->PCHSGeometry.cSectors = 63;
     6224            /* Set the disk geometry information. Ignore errors. */
     6225            pAhciPort->pDrvBlockBios->pfnSetPCHSGeometry(pAhciPort->pDrvBlockBios,
     6226                                                         &pAhciPort->PCHSGeometry);
     6227            rc = VINF_SUCCESS;
     6228        }
     6229        LogRel(("AHCI: LUN#%d: disk, PCHS=%u/%u/%u, total number of sectors %Ld\n",
     6230                 pAhciPort->iLUN, pAhciPort->PCHSGeometry.cCylinders,
     6231                 pAhciPort->PCHSGeometry.cHeads, pAhciPort->PCHSGeometry.cSectors,
     6232                 pAhciPort->cTotalSectors));
     6233    }
     6234    return rc;
     6235}
     6236
     6237/**
     6238 * Callback employed by ahciR3Suspend and ahciR3PowerOff..
     6239 *
     6240 * @returns true if we've quiesced, false if we're still working.
     6241 * @param   pDevIns     The device instance.
     6242 */
     6243static DECLCALLBACK(bool) ahciR3IsAsyncSuspendOrPowerOffDone(PPDMDEVINS pDevIns)
     6244{
     6245    if (!ahciR3AllAsyncIOIsFinished(pDevIns))
     6246        return false;
     6247
     6248    PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI);
     6249    ASMAtomicWriteBool(&pThis->fSignalIdle, false);
     6250    return true;
     6251}
     6252
     6253/**
     6254 * Common worker for ahciR3Suspend and ahciR3PowerOff.
     6255 */
     6256static void ahciR3SuspendOrPowerOff(PPDMDEVINS pDevIns)
     6257{
     6258    PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI);
     6259
     6260    ASMAtomicWriteBool(&pThis->fSignalIdle, true);
     6261    if (!ahciR3AllAsyncIOIsFinished(pDevIns))
     6262        PDMDevHlpSetAsyncNotification(pDevIns, ahciR3IsAsyncSuspendOrPowerOffDone);
     6263    else
     6264        ASMAtomicWriteBool(&pThis->fSignalIdle, false);
     6265}
     6266
     6267/**
     6268 * Suspend notification.
     6269 *
     6270 * @returns VBox status.
     6271 * @param   pDevIns     The device instance data.
     6272 */
     6273static DECLCALLBACK(void) ahciR3Suspend(PPDMDEVINS pDevIns)
     6274{
     6275    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     6276    Log(("%s:\n", __FUNCTION__));
     6277
     6278    ahciR3SuspendOrPowerOff(pDevIns);
     6279
     6280    for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
     6281        ataControllerSuspend(&pAhci->aCts[i]);
     6282}
     6283
     6284/**
     6285 * Resume notification.
     6286 *
     6287 * @param   pDevIns     The device instance data.
     6288 */
     6289static DECLCALLBACK(void) ahciR3Resume(PPDMDEVINS pDevIns)
     6290{
     6291    PAHCI    pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     6292
     6293    Log(("%s:\n", __FUNCTION__));
     6294    for (uint32_t i = 0; i < RT_ELEMENTS(pAhci->aCts); i++)
     6295        ataControllerResume(&pAhci->aCts[i]);
     6296    return;
     6297}
     6298
    62826299/**
    62836300 * Detach notification.
     
    62906307 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    62916308 */
    6292 static DECLCALLBACK(void) ahciDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     6309static DECLCALLBACK(void) ahciR3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    62936310{
    62946311    PAHCI           pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     
    63336350 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    63346351 */
    6335 static DECLCALLBACK(int)  ahciAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
     6352static DECLCALLBACK(int)  ahciR3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
    63366353{
    63376354    PAHCI       pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     
    63546371    rc = PDMDevHlpDriverAttach(pDevIns, pAhciPort->iLUN, &pAhciPort->IBase, &pAhciPort->pDrvBase, NULL);
    63556372    if (RT_SUCCESS(rc))
    6356         rc = ahciConfigureLUN(pDevIns, pAhciPort);
     6373        rc = ahciR3ConfigureLUN(pDevIns, pAhciPort);
    63576374    else
    63586375        AssertMsgFailed(("Failed to attach LUN#%d. rc=%Rrc\n", pAhciPort->iLUN, rc));
     
    64196436
    64206437/**
    6421  * Callback employed by ahciReset.
     6438 * Callback employed by ahciR3Reset.
    64226439 *
    64236440 * @returns true if we've quiesced, false if we're still working.
     
    64416458 * @param   pDevIns     The device instance data.
    64426459 */
    6443 static DECLCALLBACK(void) ahciReset(PPDMDEVINS pDevIns)
     6460static DECLCALLBACK(void) ahciR3Reset(PPDMDEVINS pDevIns)
    64446461{
    64456462    PAHCI pThis = PDMINS_2_DATA(pDevIns, PAHCI);
     
    64616478 * @param   pDevIns Pointer to the device instance
    64626479 */
    6463 static DECLCALLBACK(void) ahciPowerOff(PPDMDEVINS pDevIns)
     6480static DECLCALLBACK(void) ahciR3PowerOff(PPDMDEVINS pDevIns)
    64646481{
    64656482    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
     
    64846501 *                      iInstance it's expected to be used a bit in this function.
    64856502 */
    6486 static DECLCALLBACK(int) ahciConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
     6503static DECLCALLBACK(int) ahciR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    64876504{
    64886505    PAHCI      pThis = PDMINS_2_DATA(pDevIns, PAHCI);
     
    65986615     * to switch to it which also changes device Id and other things in the PCI configuration space).
    65996616     */
    6600     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 8, PCI_ADDRESS_SPACE_IO, ahciLegacyFakeIORangeMap);
     6617    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 8, PCI_ADDRESS_SPACE_IO, ahciR3LegacyFakeIORangeMap);
    66016618    if (RT_FAILURE(rc))
    66026619        return PDMDEV_SET_ERROR(pDevIns, rc,
    66036620                                N_("AHCI cannot register PCI I/O region"));
    66046621
    6605     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1, 1, PCI_ADDRESS_SPACE_IO, ahciLegacyFakeIORangeMap);
     6622    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1, 1, PCI_ADDRESS_SPACE_IO, ahciR3LegacyFakeIORangeMap);
    66066623    if (RT_FAILURE(rc))
    66076624        return PDMDEV_SET_ERROR(pDevIns, rc,
    66086625                                N_("AHCI cannot register PCI I/O region"));
    66096626
    6610     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2, 8, PCI_ADDRESS_SPACE_IO, ahciLegacyFakeIORangeMap);
     6627    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2, 8, PCI_ADDRESS_SPACE_IO, ahciR3LegacyFakeIORangeMap);
    66116628    if (RT_FAILURE(rc))
    66126629        return PDMDEV_SET_ERROR(pDevIns, rc,
    66136630                                N_("AHCI cannot register PCI I/O region"));
    66146631
    6615     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 3, 1, PCI_ADDRESS_SPACE_IO, ahciLegacyFakeIORangeMap);
     6632    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 3, 1, PCI_ADDRESS_SPACE_IO, ahciR3LegacyFakeIORangeMap);
    66166633    if (RT_FAILURE(rc))
    66176634        return PDMDEV_SET_ERROR(pDevIns, rc,
    66186635                                N_("AHCI cannot register PCI I/O region"));
    66196636
    6620     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ahciLegacyFakeIORangeMap);
     6637    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 4, 0x10, PCI_ADDRESS_SPACE_IO, ahciR3LegacyFakeIORangeMap);
    66216638    if (RT_FAILURE(rc))
    66226639        return PDMDEV_SET_ERROR(pDevIns, rc,
    66236640                                N_("AHCI cannot register PCI I/O region for BMDMA"));
    66246641
    6625     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 5, 4352, PCI_ADDRESS_SPACE_MEM, ahciMMIOMap);
     6642    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 5, 4352, PCI_ADDRESS_SPACE_MEM, ahciR3MMIOMap);
    66266643    if (RT_FAILURE(rc))
    66276644        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    66476664
    66486665    /* Status LUN. */
    6649     pThis->IBase.pfnQueryInterface = ahciStatus_QueryInterface;
    6650     pThis->ILeds.pfnQueryStatusLed = ahciStatus_QueryStatusLed;
     6666    pThis->IBase.pfnQueryInterface = ahciR3Status_QueryInterface;
     6667    pThis->ILeds.pfnQueryStatusLed = ahciR3Status_QueryStatusLed;
    66516668
    66526669    /*
     
    67106727         * Init interfaces.
    67116728         */
    6712         pAhciPort->IBase.pfnQueryInterface           = ahciPortQueryInterface;
     6729        pAhciPort->IBase.pfnQueryInterface           = ahciR3PortQueryInterface;
    67136730        pAhciPort->IPortAsync.pfnTransferCompleteNotify  = ahciTransferCompleteNotify;
    67146731        pAhciPort->IMountNotify.pfnMountNotify       = ahciMountNotify;
     
    67226739        if (RT_SUCCESS(rc))
    67236740        {
    6724             rc = ahciConfigureLUN(pDevIns, pAhciPort);
     6741            rc = ahciR3ConfigureLUN(pDevIns, pAhciPort);
    67256742            if (RT_FAILURE(rc))
    67266743            {
     
    69726989
    69736990    rc = PDMDevHlpSSMRegisterEx(pDevIns, AHCI_SAVED_STATE_VERSION, sizeof(*pThis)+cbTotalBufferSize, NULL,
    6974                                 NULL,         ahciLiveExec, NULL,
    6975                                 ahciSavePrep, ahciSaveExec, NULL,
    6976                                 ahciLoadPrep, ahciLoadExec, NULL);
     6991                                NULL,           ahciR3LiveExec, NULL,
     6992                                ahciR3SavePrep, ahciR3SaveExec, NULL,
     6993                                ahciR3LoadPrep, ahciR3LoadExec, NULL);
    69776994    if (RT_FAILURE(rc))
    69786995        return rc;
     
    70067023    sizeof(AHCI),
    70077024    /* pfnConstruct */
    7008     ahciConstruct,
     7025    ahciR3Construct,
    70097026    /* pfnDestruct */
    7010     ahciDestruct,
     7027    ahciR3Destruct,
    70117028    /* pfnRelocate */
    7012     ahciRelocate,
     7029    ahciR3Relocate,
    70137030    /* pfnIOCtl */
    70147031    NULL,
     
    70167033    NULL,
    70177034    /* pfnReset */
    7018     ahciReset,
     7035    ahciR3Reset,
    70197036    /* pfnSuspend */
    7020     ahciSuspend,
     7037    ahciR3Suspend,
    70217038    /* pfnResume */
    7022     ahciResume,
     7039    ahciR3Resume,
    70237040    /* pfnAttach */
    7024     ahciAttach,
     7041    ahciR3Attach,
    70257042    /* pfnDetach */
    7026     ahciDetach,
     7043    ahciR3Detach,
    70277044    /* pfnQueryInterface. */
    70287045    NULL,
     
    70307047    NULL,
    70317048    /* pfnPowerOff */
    7032     ahciPowerOff,
     7049    ahciR3PowerOff,
    70337050    /* pfnSoftReset */
    70347051    NULL,
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