VirtualBox

Changeset 88530 in vbox


Ignore:
Timestamp:
Apr 15, 2021 12:05:36 PM (3 years ago)
Author:
vboxsync
Message:

Devices/DevLsiLogicSCSI: Allocate configuration pages once during device construction as the size is known at this point, bugref:9914

File:
1 edited

Legend:

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

    r87164 r88530  
    345345    uint32_t                    u32Padding3;
    346346
     347    /** Critical section protecting the memory regions. */
     348    RTCRITSECT                  CritSectMemRegns;
    347349    /** List of memory regions - PLSILOGICMEMREGN. */
    348350    RTLISTANCHORR3              ListMemRegns;
     
    601603    pThis->u32DiagMemAddr = 0;
    602604
    603     lsilogicR3ConfigurationPagesFree(pThis, pThisCC);
    604605    lsilogicR3InitializeConfigurationPages(pDevIns, pThis, pThisCC);
    605606
    606607    /* Mark that we finished performing the reset. */
    607608    pThis->enmState = LSILOGICSTATE_READY;
     609    return VINF_SUCCESS;
     610}
     611
     612/**
     613 * Allocates the configuration pages based on the device.
     614 *
     615 * @returns nothing.
     616 * @param   pThis    Pointer to the shared LsiLogic device state.
     617 * @param   pThisCC  Pointer to the ring-3 LsiLogic device state.
     618 */
     619static int lsilogicR3ConfigurationPagesAlloc(PLSILOGICSCSI pThis, PLSILOGICSCSICC pThisCC)
     620{
     621    pThisCC->pConfigurationPages = (PMptConfigurationPagesSupported)RTMemAllocZ(sizeof(MptConfigurationPagesSupported));
     622    if (!pThisCC->pConfigurationPages)
     623        return VERR_NO_MEMORY;
     624
     625    if (pThis->enmCtrlType == LSILOGICCTRLTYPE_SCSI_SAS)
     626    {
     627        PMptConfigurationPagesSas pPages = &pThisCC->pConfigurationPages->u.SasPages;
     628
     629        pPages->cbManufacturingPage7 = LSILOGICSCSI_MANUFACTURING7_GET_SIZE(pThis->cPorts);
     630        PMptConfigurationPageManufacturing7 pManufacturingPage7 = (PMptConfigurationPageManufacturing7)RTMemAllocZ(pPages->cbManufacturingPage7);
     631        AssertPtrReturn(pManufacturingPage7, VERR_NO_MEMORY);
     632        pPages->pManufacturingPage7 = pManufacturingPage7;
     633
     634        /* SAS I/O unit page 0 - Port specific information. */
     635        pPages->cbSASIOUnitPage0 = LSILOGICSCSI_SASIOUNIT0_GET_SIZE(pThis->cPorts);
     636        PMptConfigurationPageSASIOUnit0 pSASPage0 = (PMptConfigurationPageSASIOUnit0)RTMemAllocZ(pPages->cbSASIOUnitPage0);
     637        AssertPtrReturn(pSASPage0, VERR_NO_MEMORY);
     638        pPages->pSASIOUnitPage0 = pSASPage0;
     639
     640        /* SAS I/O unit page 1 - Port specific settings. */
     641        pPages->cbSASIOUnitPage1 = LSILOGICSCSI_SASIOUNIT1_GET_SIZE(pThis->cPorts);
     642        PMptConfigurationPageSASIOUnit1 pSASPage1 = (PMptConfigurationPageSASIOUnit1)RTMemAllocZ(pPages->cbSASIOUnitPage1);
     643        AssertPtrReturn(pSASPage1, VERR_NO_MEMORY);
     644        pPages->pSASIOUnitPage1 = pSASPage1;
     645
     646        pPages->cPHYs  = pThis->cPorts;
     647        pPages->paPHYs = (PMptPHY)RTMemAllocZ(pPages->cPHYs * sizeof(MptPHY));
     648        AssertPtrReturn(pPages->paPHYs, VERR_NO_MEMORY);
     649
     650        /* Initialize the PHY configuration */
     651        for (unsigned i = 0; i < pThis->cPorts; i++)
     652        {
     653            /* Settings for present devices. */
     654            if (pThisCC->paDeviceStates[i].pDrvBase)
     655            {
     656                PMptSASDevice pSASDevice = (PMptSASDevice)RTMemAllocZ(sizeof(MptSASDevice));
     657                AssertPtrReturn(pSASDevice, VERR_NO_MEMORY);
     658
     659                /* Link into device list. */
     660                if (!pPages->cDevices)
     661                {
     662                    pPages->pSASDeviceHead = pSASDevice;
     663                    pPages->pSASDeviceTail = pSASDevice;
     664                    pPages->cDevices = 1;
     665                }
     666                else
     667                {
     668                    pSASDevice->pPrev = pPages->pSASDeviceTail;
     669                    pPages->pSASDeviceTail->pNext = pSASDevice;
     670                    pPages->pSASDeviceTail = pSASDevice;
     671                    pPages->cDevices++;
     672                }
     673            }
     674        }
     675    }
     676
    608677    return VINF_SUCCESS;
    609678}
     
    642711            if (pSasPages->pSASIOUnitPage1)
    643712                RTMemFree(pSasPages->pSASIOUnitPage1);
     713
     714            pSasPages->pSASDeviceHead      = NULL;
     715            pSasPages->paPHYs              = NULL;
     716            pSasPages->pManufacturingPage7 = NULL;
     717            pSasPages->pSASIOUnitPage0     = NULL;
     718            pSasPages->pSASIOUnitPage1     = NULL;
    644719        }
    645720
    646721        RTMemFree(pThisCC->pConfigurationPages);
     722        pThisCC->pConfigurationPages = NULL;
    647723    }
    648724}
     
    884960static void lsilogicR3DiagRegDataWrite(PLSILOGICSCSI pThis, PLSILOGICSCSICC pThisCC, uint32_t u32Data)
    885961{
     962    RTCritSectEnter(&pThisCC->CritSectMemRegns);
     963
    886964    PLSILOGICMEMREGN pRegion = lsilogicR3MemRegionFindByAddr(pThisCC, pThis->u32DiagMemAddr);
    887 
    888965    if (pRegion)
    889966    {
     
    9601037    /* Memory access is always 32bit big. */
    9611038    pThis->u32DiagMemAddr += sizeof(uint32_t);
     1039    RTCritSectLeave(&pThisCC->CritSectMemRegns);
    9621040}
    9631041
     
    9721050static void lsilogicR3DiagRegDataRead(PLSILOGICSCSI pThis, PLSILOGICSCSICC pThisCC, uint32_t *pu32Data)
    9731051{
     1052    RTCritSectEnter(&pThisCC->CritSectMemRegns);
     1053
    9741054    PLSILOGICMEMREGN pRegion = lsilogicR3MemRegionFindByAddr(pThisCC, pThis->u32DiagMemAddr);
    975 
    9761055    if (pRegion)
    9771056    {
     
    9901069    /* Memory access is always 32bit big. */
    9911070    pThis->u32DiagMemAddr += sizeof(uint32_t);
     1071    RTCritSectLeave(&pThisCC->CritSectMemRegns);
    9921072}
    9931073
     
    11231203
    11241204            /* Check for a valid firmware image in the IOC memory which was downloaded by the guest earlier and use that. */
     1205            RTCritSectEnter(&pThisCC->CritSectMemRegns);
    11251206            PLSILOGICMEMREGN pRegion = lsilogicR3MemRegionFindByAddr(pThisCC, LSILOGIC_FWIMGHDR_LOAD_ADDRESS);
    11261207            if (pRegion)
     
    11461227                }
    11471228            }
     1229            RTCritSectLeave(&pThisCC->CritSectMemRegns);
    11481230            break;
    11491231        }
     
    34193501
    34203502    /* Manufacturing Page 7 - Connector settings. */
    3421     pPages->cbManufacturingPage7 = LSILOGICSCSI_MANUFACTURING7_GET_SIZE(pThis->cPorts);
    3422     PMptConfigurationPageManufacturing7 pManufacturingPage7 = (PMptConfigurationPageManufacturing7)RTMemAllocZ(pPages->cbManufacturingPage7);
     3503    PMptConfigurationPageManufacturing7 pManufacturingPage7 = pPages->pManufacturingPage7;
    34233504    AssertPtr(pManufacturingPage7);
     3505
    34243506    MPT_CONFIG_PAGE_HEADER_INIT_MANUFACTURING(pManufacturingPage7,
    34253507                                              0, 7,
     
    34313513        pManufacturingPage7->u.fields.Header.u8PageLength = pPages->cbManufacturingPage7 / 4;
    34323514    pManufacturingPage7->u.fields.u8NumPhys = pThis->cPorts;
    3433     pPages->pManufacturingPage7 = pManufacturingPage7;
    34343515
    34353516    /* SAS I/O unit page 0 - Port specific information. */
    3436     pPages->cbSASIOUnitPage0 = LSILOGICSCSI_SASIOUNIT0_GET_SIZE(pThis->cPorts);
    3437     PMptConfigurationPageSASIOUnit0 pSASPage0 = (PMptConfigurationPageSASIOUnit0)RTMemAllocZ(pPages->cbSASIOUnitPage0);
     3517    PMptConfigurationPageSASIOUnit0 pSASPage0 = pPages->pSASIOUnitPage0;
    34383518    AssertPtr(pSASPage0);
    34393519
     
    34453525
    34463526    /* SAS I/O unit page 1 - Port specific settings. */
    3447     pPages->cbSASIOUnitPage1 = LSILOGICSCSI_SASIOUNIT1_GET_SIZE(pThis->cPorts);
    3448     PMptConfigurationPageSASIOUnit1 pSASPage1 = (PMptConfigurationPageSASIOUnit1)RTMemAllocZ(pPages->cbSASIOUnitPage1);
     3527    PMptConfigurationPageSASIOUnit1 pSASPage1 = pPages->pSASIOUnitPage1;
    34493528    AssertPtr(pSASPage1);
    34503529
     
    34553534    pSASPage1->u.fields.u16ControlFlags = 0;
    34563535    pSASPage1->u.fields.u16AdditionalControlFlags = 0;
    3457     pPages->pSASIOUnitPage1 = pSASPage1;
    34583536
    34593537    /* SAS I/O unit page 2 - Port specific information. */
     
    34713549    pPages->SASIOUnitPage3.u.fields.ExtHeader.u16ExtPageLength = sizeof(MptConfigurationPageSASIOUnit3) / 4;
    34723550
    3473     pPages->cPHYs  = pThis->cPorts;
    3474     pPages->paPHYs = (PMptPHY)RTMemAllocZ(pPages->cPHYs * sizeof(MptPHY));
     3551    Assert(pPages->cPHYs == pThis->cPorts);
    34753552    AssertPtr(pPages->paPHYs);
    34763553
    34773554    /* Initialize the PHY configuration */
     3555    PMptSASDevice pSASDevice = pPages->pSASDeviceHead;
    34783556    for (unsigned i = 0; i < pThis->cPorts; i++)
    34793557    {
     
    35243602            uint16_t u16DeviceHandle = lsilogicGetHandle(pThis);
    35253603            SASADDRESS SASAddress;
    3526             PMptSASDevice pSASDevice = (PMptSASDevice)RTMemAllocZ(sizeof(MptSASDevice));
    35273604            AssertPtr(pSASDevice);
    35283605
     
    35823659            pSASDevice->SASDevicePage2.u.fields.SASAddress                 = SASAddress;
    35833660
    3584             /* Link into device list. */
    3585             if (!pPages->cDevices)
    3586             {
    3587                 pPages->pSASDeviceHead = pSASDevice;
    3588                 pPages->pSASDeviceTail = pSASDevice;
    3589                 pPages->cDevices = 1;
    3590             }
    3591             else
    3592             {
    3593                 pSASDevice->pPrev = pPages->pSASDeviceTail;
    3594                 pPages->pSASDeviceTail->pNext = pSASDevice;
    3595                 pPages->pSASDeviceTail = pSASDevice;
    3596                 pPages->cDevices++;
    3597             }
     3661            pSASDevice = pSASDevice->pNext;
    35983662        }
    35993663    }
     
    36113675{
    36123676    /* Initialize the common pages. */
    3613     PMptConfigurationPagesSupported pPages = (PMptConfigurationPagesSupported)RTMemAllocZ(sizeof(MptConfigurationPagesSupported));
    3614     /** @todo r=bird: Missing alloc failure check.   Why do we allocate this
    3615      *        structure? It's fixed size... */
    3616 
    3617     pThisCC->pConfigurationPages = pPages;
    36183677
    36193678    LogFlowFunc(("pThis=%#p\n", pThis));
    36203679
    36213680    /* Clear everything first. */
     3681    AssertPtrReturnVoid(pThisCC->pConfigurationPages);
     3682    PMptConfigurationPagesSupported pPages = pThisCC->pConfigurationPages;
    36223683    memset(pPages, 0, sizeof(MptConfigurationPagesSupported));
    36233684
     
    51485209    PDMDevHlpCritSectDelete(pDevIns, &pThis->ReplyFreeQueueWriteCritSect);
    51495210
     5211    if (RTCritSectIsInitialized(&pThisCC->CritSectMemRegns))
     5212        RTCritSectDelete(&pThisCC->CritSectMemRegns);
     5213
    51505214    RTMemFree(pThisCC->paDeviceStates);
    51515215    pThisCC->paDeviceStates = NULL;
     
    53105374    if (RT_FAILURE(rc))
    53115375        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: cannot create critical section for reply free queue write access"));
     5376
     5377    /*
     5378     * Critical section protecting the memory regions.
     5379     */
     5380    rc = RTCritSectInit(&pThisCC->CritSectMemRegns);
     5381    if (RT_FAILURE(rc))
     5382        return PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: Failed to initialize critical section protecting the memory regions"));
    53125383
    53135384    /*
     
    55345605                              ? "LsiLogic SPI info."
    55355606                              : "LsiLogic SAS info.", lsilogicR3Info);
     5607
     5608    /* Allocate configuration pages. */
     5609    rc = lsilogicR3ConfigurationPagesAlloc(pThis, pThisCC);
     5610    if (RT_FAILURE(rc))
     5611        PDMDEV_SET_ERROR(pDevIns, rc, N_("LsiLogic: Failed to allocate memory for configuration pages"));
    55365612
    55375613    /* Perform hard reset. */
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