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