Hi Daniel,

In order to avoid the big impact to the existing HII drivers. There is a latest 
patch to avoid this incompatible change (r15229). Could you try it?

Thanks,
Hot

From: [email protected] [mailto:[email protected]] On Behalf Of Jeff Bobzin
Sent: Thursday, February 13, 2014 6:28 AM
To: Samuelraj, Daniel; [email protected]; [email protected]
Cc: Wang, Jianning; Owens, Christopher; [email protected]
Subject: [uswg] RE: IHV HII implementation and recent Tianocore Browser change

Current UEFI spec does not allow Hii forms to save config data inside Browser 
callback but many (most?) drivers do. This includes iSCSI sample driver in 
Tianocore.
Save is done inside callback is done for several reasons including

1)      Instant action with immediate update to the form

2)      Because some early shipping systems were not calling RouteConfig 
promptly within page-to-page navigation and only called upon final exit so IHV 
had no other way to make pages work dynamically

Spec says config data must be saved in RouteConfig and provides exit codes from 
callback to make that possible.
There is no mechanism defined for callback to tell browser that data was saved 
inside the callback and extra RouteConfig is not required.
New EDK-II reference browser follows spec (with only a few minor issues).
Result is false prompt to save data on final exit.


This is thorny problem without clear solution.
Direction to look for solution is method for IHV to detect "Early Browser" or 
"Latest Browser" on the fly.
IHV can use RouteConfig if they can trust the Browser to follow the rules.

But big burden for IHV to be compatible with both.

---jeff

From: [email protected]<mailto:[email protected]> [mailto:[email protected]] On Behalf Of 
Samuelraj, Daniel
Sent: Wednesday, February 12, 2014 5:05 PM
To: [email protected]<mailto:[email protected]>; 
[email protected]<mailto:[email protected]>
Cc: Wang, Jianning; Owens, Christopher; [email protected]<mailto:[email protected]>
Subject: [uswg] IHV HII implementation and recent Tianocore Browser change
Importance: High

Hi,
Recently we ran into situation where browser vendor/IBV/OEM is using the latest 
Tianocore browser which has some fundamental changes compared to the older one.

What is changed in browser:

*        The new browser caches the varstores when the formset is first loaded.

*        When user exits from the formset, the browser checks for varstore 
changes (compared to the cached varstores).

*        If any change is detected, it will pop up a "Settings Changed" dialog.

This poses a big problem for IHV and their customers. That is, when customer 
navigates to different forms and not making any changes, customer is expecting 
not to see this "Settings Changed" popup.

However, our HII driver will make an appropriate content change for some of the 
forms on-the-fly and will modify the associated varstores as necessary (please 
refer "Use case" section below for additional details). This is necessary for 
RAID Storage Management/Configuration App which need to manage 240 physical 
drives (+enclosures, hot spare, battery etc) and several Virtual drives (RAID 
volumes). Our HII app is driven by user and it utilizes Hii Config Access 
protocol's Callback function heavily.

Questions:
1. How do we address this issue?
2. What is recommended solution that complies with UEFI spec?

Appreciate your response!

Thanks,
Daniel

Use case:

*        User has attached 40 physical drives (PD) to RAID storage controller 
and user gets into HII formset and then into Physical Drive Management form 
where we will list all 40 PDs as clickable goto link (NOTE: this form will be 
populated based on how many PDs user has connected at a given time; that is the 
content of this form will be determined at runtime; because user may hot insert 
or hot remove a drive before clicking on Physical Drive Management goto link 
but after entering into formset...). The form will look as below:

o   PD 0 HDD: SAS:4k: 2TB: Online

o   PD 1 SSD: SATA: 512b: 1TB: Rebuild

o   ...

o   PD 39 Tape: SATA: 4TB

*        From this form user can choose a PD to view additional information (PD 
properties) and / or to perform additional PD operations (like performing 
locate operation, or force drive to offline, or start rebuild, or assign hot 
spare  etc). We need to populate this form based on what PD user chooses to 
operate on.

Apparently the content of these two forms can only be determined during 
run-time and the associated varstores will be modified to reflect the 
information.
--- Begin Message ---
Revision: 15229
          http://sourceforge.net/p/edk2/code/15229
Author:   ydong10
Date:     2014-02-12 01:45:35 +0000 (Wed, 12 Feb 2014)
Log Message:
-----------
Update the logic, only check the value change status for user input action, not 
detect the change caused by Hii driver change through SetBrowserData function.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <[email protected]>
Reviewed-by: Liming Gao <[email protected]>

Modified Paths:
--------------
    trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
    trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
    trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h

Modified: trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c    
2014-02-12 01:35:42 UTC (rev 15228)
+++ trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c    
2014-02-12 01:45:35 UTC (rev 15229)
@@ -1,7 +1,7 @@
 /** @file
 Utility functions for UI presentation.

-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -964,7 +964,100 @@
 }

 /**
+  Update the ValueChanged status for questions in this form.

+  @param  FormSet                FormSet data structure.
+  @param  Form                   Form data structure.
+
+**/
+VOID
+UpdateStatementStatusForForm (
+  IN FORM_BROWSER_FORMSET             *FormSet,
+  IN FORM_BROWSER_FORM                *Form
+  )
+{
+  LIST_ENTRY                  *Link;
+  FORM_BROWSER_STATEMENT      *Question;
+
+  Link = GetFirstNode (&Form->StatementListHead);
+  while (!IsNull (&Form->StatementListHead, Link)) {
+    Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+    Link = GetNextNode (&Form->StatementListHead, Link);
+
+    IsQuestionValueChanged(FormSet, Form, Question, GetSetValueWithBuffer);
+  }
+}
+
+/**
+  Update the ValueChanged status for questions in this formset.
+
+  @param  FormSet                FormSet data structure.
+
+**/
+VOID
+UpdateStatementStatusForFormSet (
+  IN FORM_BROWSER_FORMSET                *FormSet
+  )
+{
+  LIST_ENTRY                  *Link;
+  FORM_BROWSER_FORM           *Form;
+
+  Link = GetFirstNode (&FormSet->FormListHead);
+  while (!IsNull (&FormSet->FormListHead, Link)) {
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);
+    Link = GetNextNode (&FormSet->FormListHead, Link);
+
+    UpdateStatementStatusForForm (FormSet, Form);
+  }
+}
+
+/**
+  Update the ValueChanged status for questions.
+
+  @param  FormSet                FormSet data structure.
+  @param  Form                   Form data structure.
+  @param  SettingScope           Setting Scope for Default action.
+
+**/
+VOID
+UpdateStatementStatus (
+  IN FORM_BROWSER_FORMSET             *FormSet,
+  IN FORM_BROWSER_FORM                *Form,
+  IN BROWSER_SETTING_SCOPE            SettingScope
+  )
+{
+  LIST_ENTRY                  *Link;
+  FORM_BROWSER_FORMSET        *LocalFormSet;
+
+  switch (SettingScope) {
+  case SystemLevel:
+    Link = GetFirstNode (&gBrowserFormSetList);
+    while (!IsNull (&gBrowserFormSetList, Link)) {
+      LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+      Link = GetNextNode (&gBrowserFormSetList, Link);
+      if (!ValidateFormSet(LocalFormSet)) {
+        continue;
+      }
+
+      UpdateStatementStatusForFormSet (LocalFormSet);
+    }
+    break;
+
+  case FormSetLevel:
+    UpdateStatementStatusForFormSet (FormSet);
+    break;
+
+  case FormLevel:
+    UpdateStatementStatusForForm (FormSet, Form);
+    break;
+
+  default:
+    break;
+  }
+}
+
+/**
+
   Process the action request in user input.

   @param Action                  The user input action request info.
@@ -998,6 +1091,7 @@

   if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
     ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, 
DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);
+    UpdateStatementStatus (gCurrentSelection->FormSet, 
gCurrentSelection->Form, gBrowserSettingScope);
   }

   if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {
@@ -1618,6 +1712,7 @@
       // Reset Question to default value specified by DefaultId
       //
       Status = ExtractDefault (gCurrentSelection->FormSet, NULL, 
Statement->DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE);
+      UpdateStatementStatus (gCurrentSelection->FormSet, NULL, FormSetLevel);
       break;

     default:
@@ -2493,6 +2588,11 @@
       } else if (Statement->Operand != EFI_IFR_PASSWORD_OP) {
         SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, 
Statement, GetSetValueWithEditBuffer);
       }
+
+      //
+      // Verify whether question value has checked, update the ValueChanged 
flag in Question.
+      //
+      IsQuestionValueChanged(gCurrentSelection->FormSet, 
gCurrentSelection->Form, Statement, GetSetValueWithBuffer);
     }

     //

Modified: trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c   2014-02-12 
01:35:42 UTC (rev 15228)
+++ trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c   2014-02-12 
01:45:35 UTC (rev 15229)
@@ -1787,14 +1787,6 @@
         //
         CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, 
StorageWidth);
       }
-      //
-      // Check whether question value has been changed.
-      //
-      if (CompareMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, 
Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth) != 0) {
-        Question->ValueChanged = TRUE;
-      } else {
-        Question->ValueChanged = FALSE;
-      }
     } else {
       if (IsString) {
         //
@@ -1831,14 +1823,6 @@
       if (EFI_ERROR (Status)) {
         return Status;
       }
-      //
-      // Check whether question value has been changed.
-      //
-      if (StrCmp (Node->Value, Node->EditValue) != 0) {
-        Question->ValueChanged = TRUE;
-      } else {
-        Question->ValueChanged = FALSE;
-      }
     }
   } else if (SetValueTo == GetSetValueWithHiiDriver) {
     //
@@ -3453,6 +3437,8 @@
     FreePool (BackUpBuffer);
   }

+  Question->ValueChanged = ValueChanged;
+
   return ValueChanged;
 }

@@ -3534,11 +3520,6 @@
       Status = ProcessCallBackFunction(Selection, FormSet, Form, Question, 
EFI_BROWSER_ACTION_RETRIEVE, TRUE);
     }

-    //
-    // Update Question Value changed flag.
-    //
-    Question->ValueChanged = IsQuestionValueChanged(FormSet, Form, Question, 
GetSetValueWithBuffer);
-
     Link = GetNextNode (&Form->StatementListHead, Link);
   }

@@ -4175,6 +4156,94 @@
 }

 /**
+  Get Value changed status from old question.
+
+  @param  NewFormSet                FormSet data structure.
+  @param  OldQuestion               Old question which has value changed.
+
+**/
+VOID
+SyncStatusForQuestion (
+  IN OUT FORM_BROWSER_FORMSET             *NewFormSet,
+  IN     FORM_BROWSER_STATEMENT           *OldQuestion
+  )
+{
+  LIST_ENTRY                  *Link;
+  LIST_ENTRY                  *QuestionLink;
+  FORM_BROWSER_FORM           *Form;
+  FORM_BROWSER_STATEMENT      *Question;
+
+  //
+  // For each form in one formset.
+  //
+  Link = GetFirstNode (&NewFormSet->FormListHead);
+  while (!IsNull (&NewFormSet->FormListHead, Link)) {
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);
+    Link = GetNextNode (&NewFormSet->FormListHead, Link);
+
+    //
+    // for each question in one form.
+    //
+    QuestionLink = GetFirstNode (&Form->StatementListHead);
+    while (!IsNull (&Form->StatementListHead, QuestionLink)) {
+      Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);
+      QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);
+
+      if (Question->QuestionId == OldQuestion->QuestionId) {
+        Question->ValueChanged = TRUE;
+        return;
+      }
+    }
+  }
+}
+
+/**
+  Get Value changed status from old formset.
+
+  @param  NewFormSet                FormSet data structure.
+  @param  OldFormSet                FormSet data structure.
+
+**/
+VOID
+SyncStatusForFormSet (
+  IN OUT FORM_BROWSER_FORMSET             *NewFormSet,
+  IN     FORM_BROWSER_FORMSET             *OldFormSet
+  )
+{
+  LIST_ENTRY                  *Link;
+  LIST_ENTRY                  *QuestionLink;
+  FORM_BROWSER_FORM           *Form;
+  FORM_BROWSER_STATEMENT      *Question;
+
+  //
+  // For each form in one formset.
+  //
+  Link = GetFirstNode (&OldFormSet->FormListHead);
+  while (!IsNull (&OldFormSet->FormListHead, Link)) {
+    Form = FORM_BROWSER_FORM_FROM_LINK (Link);
+    Link = GetNextNode (&OldFormSet->FormListHead, Link);
+
+    //
+    // for each question in one form.
+    //
+    QuestionLink = GetFirstNode (&Form->StatementListHead);
+    while (!IsNull (&Form->StatementListHead, QuestionLink)) {
+      Question = FORM_BROWSER_STATEMENT_FROM_LINK (QuestionLink);
+      QuestionLink = GetNextNode (&Form->StatementListHead, QuestionLink);
+
+      if (!Question->ValueChanged) {
+        continue;
+      }
+
+      //
+      // Find the same question in new formset and update the value changed 
flag.
+      //
+      SyncStatusForQuestion (NewFormSet, Question);
+    }
+  }
+}
+
+/**
   Get current setting of Questions.

   @param  FormSet                FormSet data structure.
@@ -4195,6 +4264,7 @@
   //
   OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);
   if (OldFormSet != NULL) {
+    SyncStatusForFormSet (FormSet, OldFormSet);
     RemoveEntryList (&OldFormSet->Link);
     DestroyFormSet (OldFormSet);
   }
@@ -5000,6 +5070,7 @@
     if (EFI_ERROR (Status)) {
       return Status;
     }
+    UpdateStatementStatus (FormSet, Form, gBrowserSettingScope);
   }

   //

Modified: trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h   2014-02-12 
01:35:42 UTC (rev 15228)
+++ trunk/edk2/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h   2014-02-12 
01:45:35 UTC (rev 15229)
@@ -1,7 +1,7 @@
 /** @file
 Private MACRO, structure and function definitions for Setup Browser module.

-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -713,6 +713,35 @@
   );

 /**
+  Validate the FormSet. If the formset is not validate, remove it from the 
list.
+
+  @param  FormSet                The input FormSet which need to validate.
+
+  @retval TRUE                   The handle is validate.
+  @retval FALSE                  The handle is invalidate.
+
+**/
+BOOLEAN
+ValidateFormSet (
+  FORM_BROWSER_FORMSET    *FormSet
+  );
+
+/**
+  Update the ValueChanged status for questions.
+
+  @param  FormSet                FormSet data structure.
+  @param  Form                   Form data structure.
+  @param  SettingScope           Setting Scope for Default action.
+
+**/
+VOID
+UpdateStatementStatus (
+  IN FORM_BROWSER_FORMSET             *FormSet,
+  IN FORM_BROWSER_FORM                *Form,
+  IN BROWSER_SETTING_SCOPE            SettingScope
+  );
+
+/**
   Get Question's current Value.

   @param  FormSet                FormSet data structure.

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

--- End Message ---
------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to