Merge pull request #91 from geissonator/master

Add patch in to support erepair on OpenPower systems
diff --git a/openpower/package/hostboot/hostboot-0011-eRepair-MBVPD-size-check-for-CDIMM-and-ISDIMM.patch b/openpower/package/hostboot/hostboot-0011-eRepair-MBVPD-size-check-for-CDIMM-and-ISDIMM.patch
new file mode 100644
index 0000000..55c94f0
--- /dev/null
+++ b/openpower/package/hostboot/hostboot-0011-eRepair-MBVPD-size-check-for-CDIMM-and-ISDIMM.patch
@@ -0,0 +1,504 @@
+From 403b5b351e0ee82fa0b7147ea924b455384cf39d Mon Sep 17 00:00:00 2001
+From: Bilicon Patil <bilpatil@in.ibm.com>
+Date: Fri, 5 Dec 2014 07:25:24 -0600
+Subject: [PATCH 2/6] eRepair MBVPD size check for CDIMM and ISDIMM
+
+The eRepair VPD size for DMI Bus is bigger in systems with ISDIMMs because
+the VPD accounts for all the Centaurs. The current check in the code is
+for each Centaur which is applicable for systems with CDIMMs.
+
+The fix also includes a change to do restore of eRepair records noted
+in the VPD when the system had a non-fips830 driver.
+
+Change-Id: Ibaaf98c5be3e26474ee0eede6081f506f4bb7ec3
+RTC: 119532
+Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/14727
+Tested-by: Jenkins Server
+Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
+Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com>
+Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
+(cherry picked from commit db9b6fed621390d10459834300924e0fafd6fa04)
+---
+ .../hwp/bus_training/erepairGetFailedLanesHwp.C    |  194 +++++++++++++++-----
+ .../hwp/bus_training/erepairSetFailedLanesHwp.C    |   73 +++++++-
+ 2 files changed, 215 insertions(+), 52 deletions(-)
+
+diff --git a/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C b/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C
+index a4db160..33ec195 100644
+--- a/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C
++++ b/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C
+@@ -5,7 +5,7 @@
+ /*                                                                        */
+ /* OpenPOWER HostBoot Project                                             */
+ /*                                                                        */
+-/* Contributors Listed Below - COPYRIGHT 2013,2014                        */
++/* Contributors Listed Below - COPYRIGHT 2013,2015                        */
+ /* [+] International Business Machines Corp.                              */
+ /*                                                                        */
+ /*                                                                        */
+@@ -38,6 +38,8 @@
+ 
+ #include <erepairGetFailedLanesHwp.H>
+ 
++using namespace EREPAIR;
++
+ extern "C"
+ {
+ 
+@@ -62,10 +64,10 @@ extern "C"
+  *
+  * @return ReturnCode
+  */
+-fapi::ReturnCode retrieveRepairData(const fapi::Target      &i_tgtHandle,
+-                                    EREPAIR::erepairVpdType i_vpdType,
+-                                    std::vector<uint8_t>    &o_txFailLanes,
+-                                    std::vector<uint8_t>    &o_rxFailLanes);
++fapi::ReturnCode retrieveRepairData(const fapi::Target    &i_tgtHandle,
++                                    erepairVpdType        i_vpdType,
++                                    std::vector<uint8_t>  &o_txFailLanes,
++                                    std::vector<uint8_t>  &o_rxFailLanes);
+ 
+ /**
+  * @brief Function called by the FW Team HWP that parses the data read from
+@@ -92,15 +94,25 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+                                       std::vector<uint8_t> &o_rxFailLanes);
+ 
+ 
++/**
++ * @brief Function to check if the system has Custom DIMM type (CDIMM).
++ *        Attribute ATTR_EFF_CUSTOM_DIMM is read to determine the type.
++ * @param[in] i_tgtHandle   Reference to X-Bus or A-Bus or MCS target
++ * @param[o]  o_customDimm  Return value - ENUM_ATTR_EFF_CUSTOM_DIMM_NO
++ *                                      or ENUM_ATTR_EFF_CUSTOM_DIMM_YES
++ * @return ReturnCode
++ */
++fapi::ReturnCode getDimmType(const fapi::Target &i_tgtHandle,
++                             uint8_t &o_customDimm);
++
+ /******************************************************************************
+  * Accessor HWP
+  *****************************************************************************/
+ 
+-fapi::ReturnCode erepairGetFailedLanesHwp(
+-                                         const fapi::Target      &i_tgtHandle,
+-                                         EREPAIR::erepairVpdType i_vpdType,
+-                                         std::vector<uint8_t>    &o_txFailLanes,
+-                                         std::vector<uint8_t>    &o_rxFailLanes)
++fapi::ReturnCode erepairGetFailedLanesHwp(const fapi::Target  &i_tgtHandle,
++                                          erepairVpdType       i_vpdType,
++                                          std::vector<uint8_t> &o_txFailLanes,
++                                          std::vector<uint8_t> &o_rxFailLanes)
+ {
+     fapi::ReturnCode l_rc;
+     fapi::Target     l_processorTgt;
+@@ -147,15 +159,16 @@ fapi::ReturnCode erepairGetFailedLanesHwp(
+     return l_rc;
+ }
+ 
+-fapi::ReturnCode retrieveRepairData(const fapi::Target      &i_tgtHandle,
+-                                    EREPAIR::erepairVpdType i_vpdType,
+-                                    std::vector<uint8_t>    &o_txFailLanes,
+-                                    std::vector<uint8_t>    &o_rxFailLanes)
++fapi::ReturnCode retrieveRepairData(const fapi::Target   &i_tgtHandle,
++                                    erepairVpdType       i_vpdType,
++                                    std::vector<uint8_t> &o_txFailLanes,
++                                    std::vector<uint8_t> &o_rxFailLanes)
+ {
+     fapi::ReturnCode l_rc;
+     uint8_t          *l_retBuf = NULL;
+     uint32_t         l_bufSize = 0;
+     fapi::Target     l_procTarget;
++    uint8_t          l_customDimm;
+ 
+     FAPI_DBG(">> retrieveRepairData");
+ 
+@@ -165,7 +178,7 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target      &i_tgtHandle,
+         {
+             fapi::MBvpdRecord l_vpdRecord = fapi::MBVPD_RECORD_VEIR;
+ 
+-            if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
++            if(i_vpdType == EREPAIR_VPD_MNFG)
+             {
+                 l_vpdRecord = fapi::MBVPD_RECORD_MER0;
+             }
+@@ -184,12 +197,34 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target      &i_tgtHandle,
+                 break;
+             }
+ 
+-            if((l_bufSize == 0) ||
+-               ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) &&
+-                (l_bufSize > EREPAIR::EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR))||
+-               ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) &&
+-                (l_bufSize > EREPAIR::EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)))
++            // Check whether we have Memory on a CDIMM
++            l_rc = getDimmType(i_tgtHandle, l_customDimm);
++
++            if(l_rc)
++            {
++                FAPI_ERR("Error (0x%x) during DIMM type check",
++                        static_cast<uint32_t> (l_rc));
++                break;
++            }
++
++            if(l_customDimm == fapi::ENUM_ATTR_SPD_CUSTOM_YES)
+             {
++                if((l_bufSize == 0) ||
++                   ((i_vpdType == EREPAIR_VPD_FIELD) &&
++                    (l_bufSize > EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) ||
++                   ((i_vpdType == EREPAIR_VPD_MNFG) &&
++                    (l_bufSize > EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)))
++                {
++                    FAPI_SET_HWP_ERROR(l_rc,
++                                       RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE);
++                    break;
++                }
++            }
++            else if(l_bufSize == 0)
++            {
++                // TODO RTC: 119531. Add upper bound checking for l_bufSize
++                // This size check will depend on whether the Lane eRepair data
++                // is stored on the Planar VPD or on the Riser card VPD.
+                 FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE);
+                 break;
+             }
+@@ -230,7 +265,7 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target      &i_tgtHandle,
+ 
+             fapi::MvpdRecord l_vpdRecord = fapi::MVPD_RECORD_VWML;
+ 
+-            if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
++            if(i_vpdType == EREPAIR_VPD_MNFG)
+             {
+                 l_vpdRecord = fapi::MVPD_RECORD_MER0;
+             }
+@@ -250,10 +285,10 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target      &i_tgtHandle,
+             }
+ 
+             if((l_bufSize == 0) ||
+-               ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) &&
+-                (l_bufSize > EREPAIR::EREPAIR_P8_MODULE_VPD_FIELD_SIZE)) ||
+-               ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) &&
+-                (l_bufSize > EREPAIR::EREPAIR_P8_MODULE_VPD_MNFG_SIZE)))
++               ((i_vpdType == EREPAIR_VPD_FIELD) &&
++                (l_bufSize > EREPAIR_P8_MODULE_VPD_FIELD_SIZE)) ||
++               ((i_vpdType == EREPAIR_VPD_MNFG) &&
++                (l_bufSize > EREPAIR_P8_MODULE_VPD_MNFG_SIZE)))
+             {
+                 FAPI_SET_HWP_ERROR(l_rc,
+                                    RC_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE);
+@@ -323,6 +358,7 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+     fapi::Target     l_mcsTarget;
+     fapi::Target     l_tgtHandle;
+     fapi::ReturnCode l_rc;
++    uint8_t          l_customDimm;
+     fapi::ATTR_CHIP_UNIT_POS_Type l_busNum;
+ 
+     FAPI_DBG(">> determineRepairLanes");
+@@ -394,21 +430,18 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+                 l_fabricBus->interface = (l_temp & 0x0F);
+ #endif
+ 
+-                // Check if we have the correct Processor ID
+-                if(l_chipPosition != l_fabricBus->device.processor_id)
+-                {
+-                    continue;
+-                }
++                // We do not need the check of processor ID because
++                // a MVPD read is specific to a Processor
+ 
+                 // Check if we have the matching the Fabric Bus types
+                 if((l_tgtType == fapi::TARGET_TYPE_ABUS_ENDPOINT) &&
+-                   (l_fabricBus->type != EREPAIR::PROCESSOR_EDI))
++                   (l_fabricBus->type != PROCESSOR_EDI))
+                 {
+                     continue;
+                 }
+ 
+                 if((l_tgtType == fapi::TARGET_TYPE_XBUS_ENDPOINT) &&
+-                   (l_fabricBus->type != EREPAIR::PROCESSOR_EI4))
++                   (l_fabricBus->type != PROCESSOR_EI4))
+                 {
+                     continue;
+                 }
+@@ -428,17 +461,17 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+                 }
+ 
+                 // Check if we have valid fail lane numbers
+-                if(l_fabricBus->failBit == EREPAIR::INVALID_FAIL_LANE_NUMBER)
++                if(l_fabricBus->failBit == INVALID_FAIL_LANE_NUMBER)
+                 {
+                     continue;
+                 }
+ 
+                 // Copy the fail lane numbers in the vectors
+-                if(l_fabricBus->interface == EREPAIR::PBUS_DRIVER)
++                if(l_fabricBus->interface == PBUS_DRIVER)
+                 {
+                     o_txFailLanes.push_back(l_fabricBus->failBit);
+                 }
+-                else if(l_fabricBus->interface == EREPAIR::PBUS_RECEIVER)
++                else if(l_fabricBus->interface == PBUS_RECEIVER)
+                 {
+                     o_rxFailLanes.push_back(l_fabricBus->failBit);
+                 }
+@@ -468,6 +501,19 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+                 l_tgtHandle = l_mcsTarget;
+             }
+ 
++            if(l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP)
++            {
++                // Check whether we have Memory on a CDIMM
++                l_rc = getDimmType(i_tgtHandle, l_customDimm);
++
++                if(l_rc)
++                {
++                    FAPI_ERR("Error (0x%x) during DIMM type check",
++                            static_cast<uint32_t> (l_rc));
++                    break;
++                }
++            }
++
+             // Read Power bus eRepair data and get the failed lane numbers
+             for(l_loop = 0;
+                 l_loop < l_numRepairs;
+@@ -491,14 +537,20 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+                 l_memBus->interface = (l_temp & 0x0F);
+ #endif
+ 
+-                // Check if we have the correct Processor/Centaur ID
+-                if(l_chipPosition != l_memBus->device.proc_centaur_id)
++                // Check if we have the correct Centaur ID
++                // NOTE: We do not prefer to make the check of Centaur ID if the
++                // system is known to have CDIMMs. This check is applicable
++                // only for systems with ISDIMM because in the ISDIMM systems
++                // the Lane eRepair data for multiple Centaurs is maintained in
++                // a common VPD.
++                if((l_customDimm != fapi::ENUM_ATTR_SPD_CUSTOM_YES) &&
++                   (l_chipPosition != l_memBus->device.proc_centaur_id))
+                 {
+                     continue;
+                 }
+ 
+                 // Check if we have the matching the Memory Bus types
+-                if(l_memBus->type != EREPAIR::MEMORY_EDI)
++                if(l_memBus->type != MEMORY_EDI)
+                 {
+                     continue;
+                 }
+@@ -518,7 +570,7 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+                 }
+ 
+                 // Check if we have valid fail lane numbers
+-                if(l_memBus->failBit == EREPAIR::INVALID_FAIL_LANE_NUMBER)
++                if(l_memBus->failBit == INVALID_FAIL_LANE_NUMBER)
+                 {
+                     continue;
+                 }
+@@ -526,22 +578,22 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+                 // Copy the fail lane numbers in the vectors
+                 if(l_tgtType == fapi::TARGET_TYPE_MCS_CHIPLET)
+                 {
+-                   if(l_memBus->interface == EREPAIR::DMI_MCS_DRIVE)
++                   if(l_memBus->interface == DMI_MCS_DRIVE)
+                    {
+                        o_txFailLanes.push_back(l_memBus->failBit);
+                    }
+-                   else if(l_memBus->interface == EREPAIR::DMI_MCS_RECEIVE)
++                   else if(l_memBus->interface == DMI_MCS_RECEIVE)
+                    {
+                        o_rxFailLanes.push_back(l_memBus->failBit);
+                    }
+                 }
+                 else if(l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP)
+                 {
+-                   if(l_memBus->interface == EREPAIR::DMI_MEMBUF_DRIVE)
++                   if(l_memBus->interface == DMI_MEMBUF_DRIVE)
+                    {
+                        o_txFailLanes.push_back(l_memBus->failBit);
+                    }
+-                   else if(l_memBus->interface == EREPAIR::DMI_MEMBUF_RECEIVE)
++                   else if(l_memBus->interface == DMI_MEMBUF_RECEIVE)
+                    {
+                        o_rxFailLanes.push_back(l_memBus->failBit);
+                    }
+@@ -551,10 +603,64 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target   &i_tgtHandle,
+ 
+     }while(0);
+ 
+-    FAPI_INF("<< No.of Fail Lanes: tx: %d, rx: %d",
++    FAPI_INF("<< No.of Fail Lanes: tx: %zd, rx: %zd",
+               o_txFailLanes.size(), o_rxFailLanes.size());
+ 
+     return(l_rc);
+ }
+ 
++fapi::ReturnCode getDimmType(const fapi::Target &i_tgtHandle,
++                             uint8_t &o_customDimm)
++{
++    fapi::ReturnCode          l_rc;
++    std::vector<fapi::Target> l_mbaChiplets;
++    fapi::Target              l_mbaTarget;
++
++    do
++    {
++        // Get the connected MBA chiplet and determine whether we have CDIMM
++        l_rc = fapiGetChildChiplets(i_tgtHandle,
++                                    fapi::TARGET_TYPE_MBA_CHIPLET,
++                                    l_mbaChiplets,
++                                    fapi::TARGET_STATE_FUNCTIONAL);
++        if(l_rc || (0 == l_mbaChiplets.size()))
++        {
++            FAPI_ERR("Error (0x%x) during get child MBA targets",
++                    static_cast<uint32_t> (l_rc));
++            break;
++        }
++
++        l_mbaTarget = l_mbaChiplets[0];
++        std::vector<fapi::Target> l_target_dimm_array;
++
++        l_rc =  fapiGetAssociatedDimms(l_mbaTarget, l_target_dimm_array);
++
++        if(l_rc)
++        {
++            FAPI_ERR("Error (0x%x), from fapiGetAssociatedDimms",
++                    static_cast<uint32_t>(l_rc));
++            break;
++        }
++
++        if(0 != l_target_dimm_array.size())
++        {
++            l_rc = FAPI_ATTR_GET(ATTR_SPD_CUSTOM,
++                    &l_target_dimm_array[0],
++                    o_customDimm);
++            if(l_rc)
++            {
++                FAPI_ERR("Error (0x%x), from FAPI_ATTR_GET",
++                        static_cast<uint32_t>(l_rc));
++                break;
++            }
++        }
++        else
++        {
++            o_customDimm = fapi::ENUM_ATTR_SPD_CUSTOM_NO;
++        }
++    }while(0);
++
++    return l_rc;
++}
++
+ }// endof extern "C"
+diff --git a/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C b/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C
+index a59d9e5..b0724f9 100755
+--- a/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C
++++ b/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C
+@@ -5,7 +5,7 @@
+ /*                                                                        */
+ /* OpenPOWER HostBoot Project                                             */
+ /*                                                                        */
+-/* Contributors Listed Below - COPYRIGHT 2013,2014                        */
++/* Contributors Listed Below - COPYRIGHT 2013,2015                        */
+ /* [+] International Business Machines Corp.                              */
+ /*                                                                        */
+ /*                                                                        */
+@@ -173,6 +173,9 @@ ReturnCode writeRepairDataToVPD(const Target               &i_tgtHandle,
+     uint8_t    *l_retBuf = NULL;
+     uint32_t   l_bufSize = 0;
+     Target     l_procTarget;
++    uint8_t    l_customDimm;
++    std::vector<fapi::Target> l_mbaChiplets;
++    fapi::Target              l_mbaTarget;
+ 
+     FAPI_DBG(">> writeRepairDataToVPD");
+ 
+@@ -202,12 +205,66 @@ ReturnCode writeRepairDataToVPD(const Target               &i_tgtHandle,
+                 break;
+             }
+ 
+-            if((l_bufSize == 0) ||
+-               ((i_vpdType == EREPAIR_VPD_FIELD) &&
+-                (l_bufSize > EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) ||
+-               ((i_vpdType == EREPAIR_VPD_MNFG) &&
+-                (l_bufSize > EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)))
++            // Get the connected MBA chiplet and determine whether we have CDIMM
++            l_rc = fapiGetChildChiplets(i_tgtHandle,
++                                        fapi::TARGET_TYPE_MBA_CHIPLET,
++                                        l_mbaChiplets,
++                                        fapi::TARGET_STATE_FUNCTIONAL);
++
++            if(l_rc || (0 == l_mbaChiplets.size()))
++            {
++                FAPI_ERR("Error (0x%x) during get child MBA targets",
++                         static_cast<uint32_t> (l_rc));
++                break;
++            }
++
++            l_mbaTarget = l_mbaChiplets[0];
++            std::vector<fapi::Target> l_target_dimm_array;
++
++            l_rc =  fapiGetAssociatedDimms(l_mbaTarget, l_target_dimm_array);
++
++            if(l_rc)
++            {
++                FAPI_ERR("Error (0x%x), from fapiGetAssociatedDimms",
++                          static_cast<uint32_t>(l_rc));
++                break;
++            }
++
++            if(0 != l_target_dimm_array.size())
++            {
++                l_rc = FAPI_ATTR_GET(ATTR_SPD_CUSTOM,
++                                     &l_target_dimm_array[0],
++                                     l_customDimm);
++                if(l_rc)
++                {
++                    FAPI_ERR("Error (0x%x), from FAPI_ATTR_GET",
++                             static_cast<uint32_t>(l_rc));
++                    break;
++                }
++            }
++            else
++            {
++                l_customDimm = fapi::ENUM_ATTR_SPD_CUSTOM_NO;
++            }
++
++            if(l_customDimm == fapi::ENUM_ATTR_SPD_CUSTOM_YES)
++            {
++                if((l_bufSize == 0) ||
++                       ((i_vpdType == EREPAIR_VPD_FIELD) &&
++                        (l_bufSize > EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) ||
++                       ((i_vpdType == EREPAIR_VPD_MNFG) &&
++                        (l_bufSize > EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)))
++                {
++                    FAPI_SET_HWP_ERROR(l_rc,
++                                       RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE);
++                    break;
++                }
++            }
++            else if(l_bufSize == 0)
+             {
++                // TODO RTC: 119531. Add upper bound checking for l_bufSize
++                // This size check will depend on whether the Lane eRepair data
++                // is stored on the Planar VPD or on the Riser card VPD.
+                 FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE);
+                 break;
+             }
+@@ -221,7 +278,7 @@ ReturnCode writeRepairDataToVPD(const Target               &i_tgtHandle,
+                 break;
+             }
+ 
+-            // Retrieve the eRepair data from the Centaur FRU VPD
++            // Retrieve the Field eRepair data from the Centaur FRU VPD
+             l_rc = fapiGetMBvpdField(l_vpdRecord,
+                                      MBVPD_KEYWORD_PDI,
+                                      i_tgtHandle,
+@@ -315,7 +372,7 @@ ReturnCode writeRepairDataToVPD(const Target               &i_tgtHandle,
+                 break;
+             }
+ 
+-            // Retrieve the eRepair data from the MVPD
++            // Retrieve the Field eRepair data from the MVPD
+             l_rc = fapiGetMvpdField(l_vpdRecord,
+                                     MVPD_KEYWORD_PDI,
+                                     l_procTarget,
+-- 
+1.7.4.1
+