]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c
OvmfPkg: Modify FDF/DSC files for RamDiskDxe's adding NFIT report feature
[mirror_edk2.git] / MdeModulePkg / Universal / Disk / RamDiskDxe / RamDiskImpl.c
CommitLineData
20752cb8
HW
1/** @file\r
2 HII Config Access protocol implementation of RamDiskDxe driver.\r
3\r
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "RamDiskImpl.h"\r
16\r
17CHAR16 mRamDiskStorageName[] = L"RAM_DISK_CONFIGURATION";\r
18\r
19RAM_DISK_CONFIG_PRIVATE_DATA mRamDiskConfigPrivateDataTemplate = {\r
20 RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE,\r
21 {\r
22 RamDiskExtractConfig,\r
23 RamDiskRouteConfig,\r
24 RamDiskCallback\r
25 }\r
26};\r
27\r
28HII_VENDOR_DEVICE_PATH mRamDiskHiiVendorDevicePath = {\r
29 {\r
30 {\r
31 HARDWARE_DEVICE_PATH,\r
32 HW_VENDOR_DP,\r
33 {\r
34 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
35 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
36 }\r
37 },\r
38 RAM_DISK_FORM_SET_GUID\r
39 },\r
40 {\r
41 END_DEVICE_PATH_TYPE,\r
42 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
43 {\r
44 (UINT8) (END_DEVICE_PATH_LENGTH),\r
45 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
46 }\r
47 }\r
48};\r
49\r
50\r
51/**\r
52 This function publish the RAM disk configuration Form.\r
53\r
54 @param[in, out] ConfigPrivateData\r
55 Points to RAM disk configuration private data.\r
56\r
57 @retval EFI_SUCCESS HII Form is installed successfully.\r
58 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
59 @retval Others Other errors as indicated.\r
60\r
61**/\r
62EFI_STATUS\r
63InstallRamDiskConfigForm (\r
64 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData\r
65 )\r
66{\r
67 EFI_STATUS Status;\r
68 EFI_HII_HANDLE HiiHandle;\r
69 EFI_HANDLE DriverHandle;\r
70 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
71\r
72 DriverHandle = NULL;\r
73 ConfigAccess = &ConfigPrivateData->ConfigAccess;\r
74 Status = gBS->InstallMultipleProtocolInterfaces (\r
75 &DriverHandle,\r
76 &gEfiDevicePathProtocolGuid,\r
77 &mRamDiskHiiVendorDevicePath,\r
78 &gEfiHiiConfigAccessProtocolGuid,\r
79 ConfigAccess,\r
80 NULL\r
81 );\r
82 if (EFI_ERROR (Status)) {\r
83 return Status;\r
84 }\r
85\r
86 ConfigPrivateData->DriverHandle = DriverHandle;\r
87\r
88 //\r
89 // Publish the HII package list\r
90 //\r
91 HiiHandle = HiiAddPackages (\r
92 &gRamDiskFormSetGuid,\r
93 DriverHandle,\r
94 RamDiskDxeStrings,\r
95 RamDiskHiiBin,\r
96 NULL\r
97 );\r
98 if (HiiHandle == NULL) {\r
99 gBS->UninstallMultipleProtocolInterfaces (\r
100 DriverHandle,\r
101 &gEfiDevicePathProtocolGuid,\r
102 &mRamDiskHiiVendorDevicePath,\r
103 &gEfiHiiConfigAccessProtocolGuid,\r
104 ConfigAccess,\r
105 NULL\r
106 );\r
107 return EFI_OUT_OF_RESOURCES;\r
108 }\r
109\r
110 ConfigPrivateData->HiiHandle = HiiHandle;\r
111\r
112 return EFI_SUCCESS;\r
113}\r
114\r
115\r
116/**\r
117 This function removes RAM disk configuration Form.\r
118\r
119 @param[in, out] ConfigPrivateData\r
120 Points to RAM disk configuration private data.\r
121\r
122**/\r
123VOID\r
124UninstallRamDiskConfigForm (\r
125 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData\r
126 )\r
127{\r
128 //\r
129 // Uninstall HII package list\r
130 //\r
131 if (ConfigPrivateData->HiiHandle != NULL) {\r
132 HiiRemovePackages (ConfigPrivateData->HiiHandle);\r
133 ConfigPrivateData->HiiHandle = NULL;\r
134 }\r
135\r
136 //\r
137 // Uninstall HII Config Access Protocol\r
138 //\r
139 if (ConfigPrivateData->DriverHandle != NULL) {\r
140 gBS->UninstallMultipleProtocolInterfaces (\r
141 ConfigPrivateData->DriverHandle,\r
142 &gEfiDevicePathProtocolGuid,\r
143 &mRamDiskHiiVendorDevicePath,\r
144 &gEfiHiiConfigAccessProtocolGuid,\r
145 &ConfigPrivateData->ConfigAccess,\r
146 NULL\r
147 );\r
148 ConfigPrivateData->DriverHandle = NULL;\r
149 }\r
150\r
151 FreePool (ConfigPrivateData);\r
152}\r
153\r
154\r
155/**\r
156 Unregister all registered RAM disks.\r
157\r
158**/\r
159VOID\r
160UnregisterAllRamDisks (\r
161 VOID\r
162 )\r
163{\r
164 LIST_ENTRY *Entry;\r
165 LIST_ENTRY *NextEntry;\r
166 RAM_DISK_PRIVATE_DATA *PrivateData;\r
167\r
168 if (!IsListEmpty(&RegisteredRamDisks)) {\r
169 EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {\r
170 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);\r
171\r
172 gBS->UninstallMultipleProtocolInterfaces (\r
173 PrivateData->Handle,\r
174 &gEfiBlockIoProtocolGuid,\r
175 &PrivateData->BlockIo,\r
216fefa3
HW
176 &gEfiBlockIo2ProtocolGuid,\r
177 &PrivateData->BlockIo2,\r
20752cb8
HW
178 &gEfiDevicePathProtocolGuid,\r
179 (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath,\r
180 NULL\r
181 );\r
182\r
183 RemoveEntryList (&PrivateData->ThisInstance);\r
184\r
185 if (RamDiskCreateHii == PrivateData->CreateMethod) {\r
186 //\r
187 // If a RAM disk is created within HII, then the RamDiskDxe driver\r
188 // driver is responsible for freeing the allocated memory for the\r
189 // RAM disk.\r
190 //\r
191 FreePool ((VOID *)(UINTN) PrivateData->StartingAddr);\r
192 }\r
193\r
20752cb8
HW
194 FreePool (PrivateData->DevicePath);\r
195 FreePool (PrivateData);\r
196 ListEntryNum--;\r
197 }\r
198 }\r
199}\r
200\r
201\r
202/**\r
203 This function allows a caller to extract the current configuration for one\r
204 or more named elements from the target driver.\r
205\r
206 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
207 @param[in] Request A null-terminated Unicode string in\r
208 <ConfigRequest> format.\r
209 @param[out] Progress On return, points to a character in the Request\r
210 string. Points to the string's null terminator if\r
211 request was successful. Points to the most recent\r
212 '&' before the first failing name/value pair (or\r
213 the beginning of the string if the failure is in\r
214 the first name/value pair) if the request was not\r
215 successful.\r
216 @param[out] Results A null-terminated Unicode string in\r
217 <ConfigAltResp> format which has all values filled\r
218 in for the names in the Request string. String to\r
219 be allocated by the called function.\r
220\r
221 @retval EFI_SUCCESS The Results is filled with the requested\r
222 values.\r
223 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
224 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
225 @retval EFI_NOT_FOUND Routing data doesn't match any storage in\r
226 this driver.\r
227\r
228**/\r
229EFI_STATUS\r
230EFIAPI\r
231RamDiskExtractConfig (\r
232 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
233 IN CONST EFI_STRING Request,\r
234 OUT EFI_STRING *Progress,\r
235 OUT EFI_STRING *Results\r
236 )\r
237{\r
238 EFI_STATUS Status;\r
239 UINTN BufferSize;\r
240 RAM_DISK_CONFIGURATION *Configuration;\r
241 EFI_STRING ConfigRequest;\r
242 EFI_STRING ConfigRequestHdr;\r
243 RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;\r
244 UINTN Size;\r
245 BOOLEAN AllocatedRequest;\r
246\r
247 if (Progress == NULL || Results == NULL) {\r
248 return EFI_INVALID_PARAMETER;\r
249 }\r
250\r
251 *Progress = Request;\r
252 if ((Request != NULL) &&\r
253 !HiiIsConfigHdrMatch (Request, &gRamDiskFormSetGuid, mRamDiskStorageName)) {\r
254 return EFI_NOT_FOUND;\r
255 }\r
256\r
257 ConfigRequestHdr = NULL;\r
258 ConfigRequest = NULL;\r
259 AllocatedRequest = FALSE;\r
260 Size = 0;\r
261\r
262 //\r
263 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
264 //\r
265 ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This);\r
266 BufferSize = sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum;\r
267 Configuration = AllocateZeroPool (BufferSize);\r
268 if (Configuration == NULL) {\r
269 return EFI_OUT_OF_RESOURCES;\r
270 }\r
271\r
272 ConfigRequest = Request;\r
273 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
274 //\r
275 // Request has no request element, construct full request string.\r
276 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
277 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
278 //\r
279 ConfigRequestHdr = HiiConstructConfigHdr (\r
280 &gRamDiskFormSetGuid,\r
281 mRamDiskStorageName,\r
282 ConfigPrivate->DriverHandle\r
283 );\r
284 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
285 ConfigRequest = AllocateZeroPool (Size);\r
286 ASSERT (ConfigRequest != NULL);\r
287 AllocatedRequest = TRUE;\r
288 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
289 FreePool (ConfigRequestHdr);\r
290 }\r
291\r
292 Status = gHiiConfigRouting->BlockToConfig (\r
293 gHiiConfigRouting,\r
294 ConfigRequest,\r
295 (UINT8 *) &Configuration,\r
296 BufferSize,\r
297 Results,\r
298 Progress\r
299 );\r
300 //\r
301 // Free the allocated config request string and RAM disk configuration data.\r
302 //\r
303 if (AllocatedRequest) {\r
304 FreePool (ConfigRequest);\r
305 ConfigRequest = NULL;\r
306 }\r
307 FreePool (Configuration);\r
308\r
309 //\r
310 // Set Progress string to the original request string.\r
311 //\r
312 if (Request == NULL) {\r
313 *Progress = NULL;\r
314 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
315 *Progress = Request + StrLen (Request);\r
316 }\r
317\r
318 return Status;\r
319}\r
320\r
321\r
322/**\r
323 This function processes the results of changes in configuration.\r
324\r
325 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
326 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
327 format.\r
328 @param[out] Progress A pointer to a string filled in with the offset of\r
329 the most recent '&' before the first failing\r
330 name/value pair (or the beginning of the string if\r
331 the failure is in the first name/value pair) or\r
332 the terminating NULL if all was successful.\r
333\r
334 @retval EFI_SUCCESS The Results is processed successfully.\r
335 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
336 @retval EFI_NOT_FOUND Routing data doesn't match any storage in\r
337 this driver.\r
338\r
339**/\r
340EFI_STATUS\r
341EFIAPI\r
342RamDiskRouteConfig (\r
343 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
344 IN CONST EFI_STRING Configuration,\r
345 OUT EFI_STRING *Progress\r
346 )\r
347{\r
348 if (Configuration == NULL || Progress == NULL) {\r
349 return EFI_INVALID_PARAMETER;\r
350 }\r
351\r
352 *Progress = Configuration;\r
353 if (!HiiIsConfigHdrMatch (Configuration, &gRamDiskFormSetGuid, mRamDiskStorageName)) {\r
354 return EFI_NOT_FOUND;\r
355 }\r
356\r
357 *Progress = Configuration + StrLen (Configuration);\r
358\r
359 return EFI_SUCCESS;\r
360}\r
361\r
362\r
363/**\r
364 Allocate memory and register the RAM disk created within RamDiskDxe\r
365 driver HII.\r
366\r
367 @param[in] Size If creating raw, size of the RAM disk to create.\r
368 If creating from file, zero.\r
369 @param[in] FileHandle If creating raw, NULL. If creating from file, the\r
370 file handle.\r
371\r
372 @retval EFI_SUCCESS RAM disk is created and registered.\r
373 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to match the\r
374 size required.\r
375\r
376**/\r
377EFI_STATUS\r
378HiiCreateRamDisk (\r
379 IN UINT64 Size,\r
380 IN EFI_FILE_HANDLE FileHandle\r
381 )\r
382{\r
383 EFI_STATUS Status;\r
384 UINTN BufferSize;\r
385 UINT64 StartingAddr;\r
386 EFI_INPUT_KEY Key;\r
387 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
388 RAM_DISK_PRIVATE_DATA *PrivateData;\r
389 EFI_FILE_INFO *FileInformation;\r
390\r
391 FileInformation = NULL;\r
392\r
393 if (FileHandle != NULL) {\r
394 //\r
395 // Create from file.\r
396 //\r
397 FileInformation = FileInfo (FileHandle);\r
398 if (NULL == FileInformation) {\r
399 do {\r
400 CreatePopUp (\r
401 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
402 &Key,\r
403 L"",\r
404 L"Not enough memory to get the file information!",\r
405 L"Press ENTER to continue ...",\r
406 L"",\r
407 NULL\r
408 );\r
409 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
410\r
411 return EFI_OUT_OF_RESOURCES;\r
412 }\r
413\r
414 //\r
415 // Update the size of RAM disk according to the file size.\r
416 //\r
417 Size = FileInformation->FileSize;\r
418 }\r
419\r
420 StartingAddr = (UINTN) AllocatePool ((UINTN) Size);\r
421 if (0 == StartingAddr) {\r
422 do {\r
423 CreatePopUp (\r
424 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
425 &Key,\r
426 L"",\r
427 L"Not enough memory to create the RAM disk!",\r
428 L"Press ENTER to continue ...",\r
429 L"",\r
430 NULL\r
431 );\r
432 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
433\r
434 return EFI_OUT_OF_RESOURCES;\r
435 }\r
436\r
437 if (FileHandle != NULL) {\r
438 //\r
439 // Copy the file content to the RAM disk.\r
440 //\r
441 BufferSize = (UINTN) Size;\r
442 FileHandle->Read (\r
443 FileHandle,\r
444 &BufferSize,\r
445 (VOID *)(UINTN) StartingAddr\r
446 );\r
447 if (BufferSize != FileInformation->FileSize) {\r
448 do {\r
449 CreatePopUp (\r
450 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
451 &Key,\r
452 L"",\r
453 L"File content read error!",\r
454 L"Press ENTER to continue ...",\r
455 L"",\r
456 NULL\r
457 );\r
458 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
459\r
460 return EFI_DEVICE_ERROR;\r
461 }\r
462 }\r
463\r
464 //\r
465 // Register the newly created RAM disk.\r
466 //\r
467 Status = RamDiskRegister (\r
468 StartingAddr,\r
469 Size,\r
470 &gEfiVirtualDiskGuid,\r
471 NULL,\r
472 &DevicePath\r
473 );\r
474 if (EFI_ERROR (Status)) {\r
475 do {\r
476 CreatePopUp (\r
477 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
478 &Key,\r
479 L"",\r
480 L"Fail to register the newly created RAM disk!",\r
481 L"Press ENTER to continue ...",\r
482 L"",\r
483 NULL\r
484 );\r
485 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
486\r
487 return Status;\r
488 }\r
489\r
490 //\r
491 // If RAM disk is created within HII, memory should be freed when the\r
492 // RAM disk is unregisterd.\r
493 //\r
494 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (RegisteredRamDisks.BackLink);\r
495 PrivateData->CreateMethod = RamDiskCreateHii;\r
496\r
497 return EFI_SUCCESS;\r
498}\r
499\r
500\r
501/**\r
502 This function updates the registered RAM disks list on the main form.\r
503\r
504 @param[in, out] ConfigPrivate\r
505 Private data for configurating hii data for RAM\r
506 disks.\r
507\r
508**/\r
509VOID\r
510UpdateMainForm (\r
511 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate\r
512 )\r
513{\r
514 VOID *StartOpCodeHandle;\r
515 VOID *EndOpCodeHandle;\r
516 EFI_IFR_GUID_LABEL *StartLabel;\r
517 EFI_IFR_GUID_LABEL *EndLabel;\r
518 LIST_ENTRY *Entry;\r
519 UINTN Index;\r
520 RAM_DISK_PRIVATE_DATA *PrivateData;\r
521 CHAR16 *String;\r
522 CHAR16 RamDiskStr[128];\r
523 EFI_STRING_ID StringId;\r
20752cb8
HW
524\r
525 //\r
526 // Init OpCode Handle\r
527 //\r
528 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
529 ASSERT (StartOpCodeHandle != NULL);\r
530\r
531 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
532 ASSERT (EndOpCodeHandle != NULL);\r
533\r
534 //\r
535 // Create Hii Extend Label OpCode as the start opcode\r
536 //\r
537 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
538 StartOpCodeHandle,\r
539 &gEfiIfrTianoGuid,\r
540 NULL,\r
541 sizeof (EFI_IFR_GUID_LABEL)\r
542 );\r
543 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
544 StartLabel->Number = MAIN_LABEL_LIST_START;\r
545\r
546 //\r
547 // Create Hii Extend Label OpCode as the end opcode\r
548 //\r
549 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
550 EndOpCodeHandle,\r
551 &gEfiIfrTianoGuid,\r
552 NULL,\r
553 sizeof (EFI_IFR_GUID_LABEL)\r
554 );\r
555 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
556 EndLabel->Number = MAIN_LABEL_LIST_END;\r
557\r
558 Index = 0;\r
20752cb8
HW
559 EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {\r
560 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);\r
561 String = RamDiskStr;\r
562\r
563 UnicodeSPrint (\r
564 String,\r
565 sizeof (RamDiskStr),\r
566 L" RAM Disk %d: [0x%lx, 0x%lx]\n",\r
567 Index,\r
568 PrivateData->StartingAddr,\r
5eae4ff0 569 PrivateData->StartingAddr + PrivateData->Size - 1\r
20752cb8
HW
570 );\r
571\r
572 StringId = HiiSetString (ConfigPrivate->HiiHandle, 0, RamDiskStr, NULL);\r
573 ASSERT (StringId != 0);\r
574\r
575 HiiCreateCheckBoxOpCode (\r
576 StartOpCodeHandle,\r
577 (EFI_QUESTION_ID) (MAIN_CHECKBOX_QUESTION_ID_START + Index),\r
578 RAM_DISK_CONFIGURATION_VARSTORE_ID,\r
579 (UINT16) (RAM_DISK_LIST_VAR_OFFSET + Index),\r
580 StringId,\r
581 STRING_TOKEN (STR_RAM_DISK_LIST_HELP),\r
582 0,\r
583 0,\r
584 NULL\r
585 );\r
586\r
587 Index++;\r
588 }\r
20752cb8
HW
589\r
590 HiiUpdateForm (\r
591 ConfigPrivate->HiiHandle,\r
592 &gRamDiskFormSetGuid,\r
593 MAIN_FORM_ID,\r
594 StartOpCodeHandle,\r
595 EndOpCodeHandle\r
596 );\r
597\r
598 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
599 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
600}\r
601\r
602\r
603/**\r
604 This function processes the results of changes in configuration.\r
605\r
606 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
607 @param[in] Action Specifies the type of action taken by the browser.\r
608 @param[in] QuestionId A unique value which is sent to the original\r
609 exporting driver so that it can identify the type\r
610 of data to expect.\r
611 @param[in] Type The type of value for the question.\r
612 @param[in] Value A pointer to the data being sent to the original\r
613 exporting driver.\r
614 @param[out] ActionRequest On return, points to the action requested by the\r
615 callback function.\r
616\r
617 @retval EFI_SUCCESS The callback successfully handled the action.\r
618 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
619 variable and its data.\r
620 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
621 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
622 callback.\r
623\r
624**/\r
625EFI_STATUS\r
626EFIAPI\r
627RamDiskCallback (\r
628 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
629 IN EFI_BROWSER_ACTION Action,\r
630 IN EFI_QUESTION_ID QuestionId,\r
631 IN UINT8 Type,\r
632 IN EFI_IFR_TYPE_VALUE *Value,\r
633 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
634 )\r
635{\r
636 EFI_STATUS Status;\r
637 UINTN Index;\r
638 RAM_DISK_PRIVATE_DATA *PrivateData;\r
639 RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;\r
640 RAM_DISK_CONFIGURATION *Configuration;\r
641 EFI_DEVICE_PATH_PROTOCOL *FileDevPath;\r
642 EFI_FILE_HANDLE FileHandle;\r
643 LIST_ENTRY *Entry;\r
644 LIST_ENTRY *NextEntry;\r
20752cb8
HW
645\r
646 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
647 return EFI_INVALID_PARAMETER;\r
648 }\r
649\r
650 if (Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
651 Status = EFI_UNSUPPORTED;\r
652 if (QuestionId == CREATE_RAW_SIZE_QUESTION_ID) {\r
653 Value->u64 = EFI_PAGE_SIZE;\r
654 Status = EFI_SUCCESS;\r
655 }\r
656 return Status;\r
657 }\r
658\r
659 if ((Action != EFI_BROWSER_ACTION_CHANGED) &&\r
660 (Action != EFI_BROWSER_ACTION_CHANGING) &&\r
661 (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {\r
662 return EFI_UNSUPPORTED;\r
663 }\r
664\r
665 ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This);\r
666\r
667 //\r
668 // Update the RAM disk list show at the main form first.\r
669 //\r
670 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
671 Status = EFI_UNSUPPORTED;\r
672 if (QuestionId == MAIN_GOTO_FILE_EXPLORER_ID) {\r
673 UpdateMainForm (ConfigPrivate);\r
674 Status = EFI_SUCCESS;\r
675 }\r
676 return Status;\r
677 }\r
678\r
679 //\r
680 // Get Browser data\r
681 //\r
682 Configuration = AllocateZeroPool (sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum);\r
683 if (Configuration == NULL) {\r
684 return EFI_OUT_OF_RESOURCES;\r
685 }\r
686\r
687 Status = EFI_SUCCESS;\r
688\r
689 HiiGetBrowserData (\r
690 &gRamDiskFormSetGuid,\r
691 mRamDiskStorageName,\r
692 sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum,\r
693 (UINT8 *) Configuration\r
694 );\r
695\r
696 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
697 switch (QuestionId) {\r
698 case MAIN_GOTO_FILE_EXPLORER_ID:\r
699 Status = ChooseFile (NULL, NULL, NULL, &FileDevPath);\r
700 if (EFI_ERROR (Status)) {\r
701 break;\r
702 }\r
703\r
704 if (FileDevPath != NULL) {\r
705 //\r
706 // Open the file.\r
707 //\r
708 Status = OpenFileByDevicePath (\r
709 &FileDevPath,\r
710 &FileHandle,\r
711 EFI_FILE_MODE_READ,\r
712 0\r
713 );\r
714 if (EFI_ERROR (Status)) {\r
715 break;\r
716 }\r
717\r
718 //\r
719 // Create from file, RAM disk size is zero. It will be updated\r
720 // according to the file size.\r
721 //\r
722 Status = HiiCreateRamDisk (0, FileHandle);\r
723 if (EFI_ERROR (Status)) {\r
724 break;\r
725 }\r
726\r
727 //\r
728 // Refresh the registered RAM disks list.\r
729 //\r
730 UpdateMainForm (ConfigPrivate);\r
731 }\r
732\r
733 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
734 break;\r
735\r
736 default:\r
737 break;\r
738 }\r
739 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
740 switch (QuestionId) {\r
741 case MAIN_REMOVE_RD_QUESTION_ID:\r
742 //\r
743 // Remove the selected RAM disks\r
744 //\r
745 Index = 0;\r
20752cb8
HW
746 EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {\r
747 if (Configuration->RamDiskList[Index++] != 0) {\r
748 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);\r
749\r
750 RamDiskUnregister (\r
751 (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath\r
752 );\r
753 }\r
754 }\r
20752cb8
HW
755\r
756 UpdateMainForm (ConfigPrivate);\r
757\r
758 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
759 ZeroMem (Configuration->RamDiskList, ListEntryNum);\r
760 break;\r
761\r
762 case CREATE_RAW_SUBMIT_QUESTION_ID:\r
763 //\r
764 // Create raw, FileHandle is NULL.\r
765 //\r
766 Status = HiiCreateRamDisk (Configuration->Size, NULL);\r
767 if (EFI_ERROR (Status)) {\r
768 break;\r
769 }\r
770\r
771 //\r
772 // Refresh the registered RAM disks list.\r
773 //\r
774 UpdateMainForm (ConfigPrivate);\r
775\r
776 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
777 break;\r
778\r
779 case CREATE_RAW_DISCARD_QUESTION_ID:\r
780 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
781 break;\r
782\r
783 default:\r
784 break;\r
785 }\r
786 }\r
787\r
788 if (!EFI_ERROR (Status)) {\r
789 HiiSetBrowserData (\r
790 &gRamDiskFormSetGuid,\r
791 mRamDiskStorageName,\r
792 sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum,\r
793 (UINT8 *) Configuration,\r
794 NULL\r
795 );\r
796 }\r
797 FreePool (Configuration);\r
798\r
799 return EFI_SUCCESS;\r
800}\r