]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c
MdeModulePkg RamDiskDxe: Install Block I/O 2 Protocol on RAM disk devices
[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 &gEfiBlockIo2ProtocolGuid,
177 &PrivateData->BlockIo2,
178 &gEfiDevicePathProtocolGuid,
179 (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath,
180 NULL
181 );
182
183 RemoveEntryList (&PrivateData->ThisInstance);
184
185 if (RamDiskCreateHii == PrivateData->CreateMethod) {
186 //
187 // If a RAM disk is created within HII, then the RamDiskDxe driver
188 // driver is responsible for freeing the allocated memory for the
189 // RAM disk.
190 //
191 FreePool ((VOID *)(UINTN) PrivateData->StartingAddr);
192 }
193
194
195 gBS->DisconnectController (PrivateData->Handle, NULL, NULL);
196
197 FreePool (PrivateData->DevicePath);
198 FreePool (PrivateData);
199 ListEntryNum--;
200 }
201 }
202 }
203
204
205 /**
206 This function allows a caller to extract the current configuration for one
207 or more named elements from the target driver.
208
209 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
210 @param[in] Request A null-terminated Unicode string in
211 <ConfigRequest> format.
212 @param[out] Progress On return, points to a character in the Request
213 string. Points to the string's null terminator if
214 request was successful. Points to the most recent
215 '&' before the first failing name/value pair (or
216 the beginning of the string if the failure is in
217 the first name/value pair) if the request was not
218 successful.
219 @param[out] Results A null-terminated Unicode string in
220 <ConfigAltResp> format which has all values filled
221 in for the names in the Request string. String to
222 be allocated by the called function.
223
224 @retval EFI_SUCCESS The Results is filled with the requested
225 values.
226 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
227 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
228 @retval EFI_NOT_FOUND Routing data doesn't match any storage in
229 this driver.
230
231 **/
232 EFI_STATUS
233 EFIAPI
234 RamDiskExtractConfig (
235 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
236 IN CONST EFI_STRING Request,
237 OUT EFI_STRING *Progress,
238 OUT EFI_STRING *Results
239 )
240 {
241 EFI_STATUS Status;
242 UINTN BufferSize;
243 RAM_DISK_CONFIGURATION *Configuration;
244 EFI_STRING ConfigRequest;
245 EFI_STRING ConfigRequestHdr;
246 RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;
247 UINTN Size;
248 BOOLEAN AllocatedRequest;
249
250 if (Progress == NULL || Results == NULL) {
251 return EFI_INVALID_PARAMETER;
252 }
253
254 *Progress = Request;
255 if ((Request != NULL) &&
256 !HiiIsConfigHdrMatch (Request, &gRamDiskFormSetGuid, mRamDiskStorageName)) {
257 return EFI_NOT_FOUND;
258 }
259
260 ConfigRequestHdr = NULL;
261 ConfigRequest = NULL;
262 AllocatedRequest = FALSE;
263 Size = 0;
264
265 //
266 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
267 //
268 ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This);
269 BufferSize = sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum;
270 Configuration = AllocateZeroPool (BufferSize);
271 if (Configuration == NULL) {
272 return EFI_OUT_OF_RESOURCES;
273 }
274
275 ConfigRequest = Request;
276 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
277 //
278 // Request has no request element, construct full request string.
279 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
280 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
281 //
282 ConfigRequestHdr = HiiConstructConfigHdr (
283 &gRamDiskFormSetGuid,
284 mRamDiskStorageName,
285 ConfigPrivate->DriverHandle
286 );
287 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
288 ConfigRequest = AllocateZeroPool (Size);
289 ASSERT (ConfigRequest != NULL);
290 AllocatedRequest = TRUE;
291 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
292 FreePool (ConfigRequestHdr);
293 }
294
295 Status = gHiiConfigRouting->BlockToConfig (
296 gHiiConfigRouting,
297 ConfigRequest,
298 (UINT8 *) &Configuration,
299 BufferSize,
300 Results,
301 Progress
302 );
303 //
304 // Free the allocated config request string and RAM disk configuration data.
305 //
306 if (AllocatedRequest) {
307 FreePool (ConfigRequest);
308 ConfigRequest = NULL;
309 }
310 FreePool (Configuration);
311
312 //
313 // Set Progress string to the original request string.
314 //
315 if (Request == NULL) {
316 *Progress = NULL;
317 } else if (StrStr (Request, L"OFFSET") == NULL) {
318 *Progress = Request + StrLen (Request);
319 }
320
321 return Status;
322 }
323
324
325 /**
326 This function processes the results of changes in configuration.
327
328 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
329 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
330 format.
331 @param[out] Progress A pointer to a string filled in with the offset of
332 the most recent '&' before the first failing
333 name/value pair (or the beginning of the string if
334 the failure is in the first name/value pair) or
335 the terminating NULL if all was successful.
336
337 @retval EFI_SUCCESS The Results is processed successfully.
338 @retval EFI_INVALID_PARAMETER Configuration is NULL.
339 @retval EFI_NOT_FOUND Routing data doesn't match any storage in
340 this driver.
341
342 **/
343 EFI_STATUS
344 EFIAPI
345 RamDiskRouteConfig (
346 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
347 IN CONST EFI_STRING Configuration,
348 OUT EFI_STRING *Progress
349 )
350 {
351 if (Configuration == NULL || Progress == NULL) {
352 return EFI_INVALID_PARAMETER;
353 }
354
355 *Progress = Configuration;
356 if (!HiiIsConfigHdrMatch (Configuration, &gRamDiskFormSetGuid, mRamDiskStorageName)) {
357 return EFI_NOT_FOUND;
358 }
359
360 *Progress = Configuration + StrLen (Configuration);
361
362 return EFI_SUCCESS;
363 }
364
365
366 /**
367 Allocate memory and register the RAM disk created within RamDiskDxe
368 driver HII.
369
370 @param[in] Size If creating raw, size of the RAM disk to create.
371 If creating from file, zero.
372 @param[in] FileHandle If creating raw, NULL. If creating from file, the
373 file handle.
374
375 @retval EFI_SUCCESS RAM disk is created and registered.
376 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to match the
377 size required.
378
379 **/
380 EFI_STATUS
381 HiiCreateRamDisk (
382 IN UINT64 Size,
383 IN EFI_FILE_HANDLE FileHandle
384 )
385 {
386 EFI_STATUS Status;
387 UINTN BufferSize;
388 UINT64 StartingAddr;
389 EFI_INPUT_KEY Key;
390 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
391 RAM_DISK_PRIVATE_DATA *PrivateData;
392 EFI_FILE_INFO *FileInformation;
393
394 FileInformation = NULL;
395
396 if (FileHandle != NULL) {
397 //
398 // Create from file.
399 //
400 FileInformation = FileInfo (FileHandle);
401 if (NULL == FileInformation) {
402 do {
403 CreatePopUp (
404 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
405 &Key,
406 L"",
407 L"Not enough memory to get the file information!",
408 L"Press ENTER to continue ...",
409 L"",
410 NULL
411 );
412 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
413
414 return EFI_OUT_OF_RESOURCES;
415 }
416
417 //
418 // Update the size of RAM disk according to the file size.
419 //
420 Size = FileInformation->FileSize;
421 }
422
423 StartingAddr = (UINTN) AllocatePool ((UINTN) Size);
424 if (0 == StartingAddr) {
425 do {
426 CreatePopUp (
427 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
428 &Key,
429 L"",
430 L"Not enough memory to create the RAM disk!",
431 L"Press ENTER to continue ...",
432 L"",
433 NULL
434 );
435 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
436
437 return EFI_OUT_OF_RESOURCES;
438 }
439
440 if (FileHandle != NULL) {
441 //
442 // Copy the file content to the RAM disk.
443 //
444 BufferSize = (UINTN) Size;
445 FileHandle->Read (
446 FileHandle,
447 &BufferSize,
448 (VOID *)(UINTN) StartingAddr
449 );
450 if (BufferSize != FileInformation->FileSize) {
451 do {
452 CreatePopUp (
453 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
454 &Key,
455 L"",
456 L"File content read error!",
457 L"Press ENTER to continue ...",
458 L"",
459 NULL
460 );
461 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
462
463 return EFI_DEVICE_ERROR;
464 }
465 }
466
467 //
468 // Register the newly created RAM disk.
469 //
470 Status = RamDiskRegister (
471 StartingAddr,
472 Size,
473 &gEfiVirtualDiskGuid,
474 NULL,
475 &DevicePath
476 );
477 if (EFI_ERROR (Status)) {
478 do {
479 CreatePopUp (
480 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
481 &Key,
482 L"",
483 L"Fail to register the newly created RAM disk!",
484 L"Press ENTER to continue ...",
485 L"",
486 NULL
487 );
488 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
489
490 return Status;
491 }
492
493 //
494 // If RAM disk is created within HII, memory should be freed when the
495 // RAM disk is unregisterd.
496 //
497 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (RegisteredRamDisks.BackLink);
498 PrivateData->CreateMethod = RamDiskCreateHii;
499
500 return EFI_SUCCESS;
501 }
502
503
504 /**
505 This function updates the registered RAM disks list on the main form.
506
507 @param[in, out] ConfigPrivate
508 Private data for configurating hii data for RAM
509 disks.
510
511 **/
512 VOID
513 UpdateMainForm (
514 IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate
515 )
516 {
517 VOID *StartOpCodeHandle;
518 VOID *EndOpCodeHandle;
519 EFI_IFR_GUID_LABEL *StartLabel;
520 EFI_IFR_GUID_LABEL *EndLabel;
521 LIST_ENTRY *Entry;
522 UINTN Index;
523 RAM_DISK_PRIVATE_DATA *PrivateData;
524 CHAR16 *String;
525 CHAR16 RamDiskStr[128];
526 EFI_STRING_ID StringId;
527 EFI_TPL OldTpl;
528
529 //
530 // Init OpCode Handle
531 //
532 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
533 ASSERT (StartOpCodeHandle != NULL);
534
535 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
536 ASSERT (EndOpCodeHandle != NULL);
537
538 //
539 // Create Hii Extend Label OpCode as the start opcode
540 //
541 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
542 StartOpCodeHandle,
543 &gEfiIfrTianoGuid,
544 NULL,
545 sizeof (EFI_IFR_GUID_LABEL)
546 );
547 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
548 StartLabel->Number = MAIN_LABEL_LIST_START;
549
550 //
551 // Create Hii Extend Label OpCode as the end opcode
552 //
553 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
554 EndOpCodeHandle,
555 &gEfiIfrTianoGuid,
556 NULL,
557 sizeof (EFI_IFR_GUID_LABEL)
558 );
559 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
560 EndLabel->Number = MAIN_LABEL_LIST_END;
561
562 Index = 0;
563 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
564 EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {
565 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
566 String = RamDiskStr;
567
568 UnicodeSPrint (
569 String,
570 sizeof (RamDiskStr),
571 L" RAM Disk %d: [0x%lx, 0x%lx]\n",
572 Index,
573 PrivateData->StartingAddr,
574 PrivateData->StartingAddr + PrivateData->Size
575 );
576
577 StringId = HiiSetString (ConfigPrivate->HiiHandle, 0, RamDiskStr, NULL);
578 ASSERT (StringId != 0);
579
580 HiiCreateCheckBoxOpCode (
581 StartOpCodeHandle,
582 (EFI_QUESTION_ID) (MAIN_CHECKBOX_QUESTION_ID_START + Index),
583 RAM_DISK_CONFIGURATION_VARSTORE_ID,
584 (UINT16) (RAM_DISK_LIST_VAR_OFFSET + Index),
585 StringId,
586 STRING_TOKEN (STR_RAM_DISK_LIST_HELP),
587 0,
588 0,
589 NULL
590 );
591
592 Index++;
593 }
594 gBS->RestoreTPL (OldTpl);
595
596 HiiUpdateForm (
597 ConfigPrivate->HiiHandle,
598 &gRamDiskFormSetGuid,
599 MAIN_FORM_ID,
600 StartOpCodeHandle,
601 EndOpCodeHandle
602 );
603
604 HiiFreeOpCodeHandle (StartOpCodeHandle);
605 HiiFreeOpCodeHandle (EndOpCodeHandle);
606 }
607
608
609 /**
610 This function processes the results of changes in configuration.
611
612 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
613 @param[in] Action Specifies the type of action taken by the browser.
614 @param[in] QuestionId A unique value which is sent to the original
615 exporting driver so that it can identify the type
616 of data to expect.
617 @param[in] Type The type of value for the question.
618 @param[in] Value A pointer to the data being sent to the original
619 exporting driver.
620 @param[out] ActionRequest On return, points to the action requested by the
621 callback function.
622
623 @retval EFI_SUCCESS The callback successfully handled the action.
624 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
625 variable and its data.
626 @retval EFI_DEVICE_ERROR The variable could not be saved.
627 @retval EFI_UNSUPPORTED The specified Action is not supported by the
628 callback.
629
630 **/
631 EFI_STATUS
632 EFIAPI
633 RamDiskCallback (
634 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
635 IN EFI_BROWSER_ACTION Action,
636 IN EFI_QUESTION_ID QuestionId,
637 IN UINT8 Type,
638 IN EFI_IFR_TYPE_VALUE *Value,
639 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
640 )
641 {
642 EFI_STATUS Status;
643 UINTN Index;
644 RAM_DISK_PRIVATE_DATA *PrivateData;
645 RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;
646 RAM_DISK_CONFIGURATION *Configuration;
647 EFI_DEVICE_PATH_PROTOCOL *FileDevPath;
648 EFI_FILE_HANDLE FileHandle;
649 LIST_ENTRY *Entry;
650 LIST_ENTRY *NextEntry;
651 EFI_TPL OldTpl;
652
653 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
654 return EFI_INVALID_PARAMETER;
655 }
656
657 if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
658 Status = EFI_UNSUPPORTED;
659 if (QuestionId == CREATE_RAW_SIZE_QUESTION_ID) {
660 Value->u64 = EFI_PAGE_SIZE;
661 Status = EFI_SUCCESS;
662 }
663 return Status;
664 }
665
666 if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
667 (Action != EFI_BROWSER_ACTION_CHANGING) &&
668 (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {
669 return EFI_UNSUPPORTED;
670 }
671
672 ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This);
673
674 //
675 // Update the RAM disk list show at the main form first.
676 //
677 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
678 Status = EFI_UNSUPPORTED;
679 if (QuestionId == MAIN_GOTO_FILE_EXPLORER_ID) {
680 UpdateMainForm (ConfigPrivate);
681 Status = EFI_SUCCESS;
682 }
683 return Status;
684 }
685
686 //
687 // Get Browser data
688 //
689 Configuration = AllocateZeroPool (sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum);
690 if (Configuration == NULL) {
691 return EFI_OUT_OF_RESOURCES;
692 }
693
694 Status = EFI_SUCCESS;
695
696 HiiGetBrowserData (
697 &gRamDiskFormSetGuid,
698 mRamDiskStorageName,
699 sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum,
700 (UINT8 *) Configuration
701 );
702
703 if (Action == EFI_BROWSER_ACTION_CHANGING) {
704 switch (QuestionId) {
705 case MAIN_GOTO_FILE_EXPLORER_ID:
706 Status = ChooseFile (NULL, NULL, NULL, &FileDevPath);
707 if (EFI_ERROR (Status)) {
708 break;
709 }
710
711 if (FileDevPath != NULL) {
712 //
713 // Open the file.
714 //
715 Status = OpenFileByDevicePath (
716 &FileDevPath,
717 &FileHandle,
718 EFI_FILE_MODE_READ,
719 0
720 );
721 if (EFI_ERROR (Status)) {
722 break;
723 }
724
725 //
726 // Create from file, RAM disk size is zero. It will be updated
727 // according to the file size.
728 //
729 Status = HiiCreateRamDisk (0, FileHandle);
730 if (EFI_ERROR (Status)) {
731 break;
732 }
733
734 //
735 // Refresh the registered RAM disks list.
736 //
737 UpdateMainForm (ConfigPrivate);
738 }
739
740 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
741 break;
742
743 default:
744 break;
745 }
746 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
747 switch (QuestionId) {
748 case MAIN_REMOVE_RD_QUESTION_ID:
749 //
750 // Remove the selected RAM disks
751 //
752 Index = 0;
753 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
754 EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {
755 if (Configuration->RamDiskList[Index++] != 0) {
756 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
757
758 RamDiskUnregister (
759 (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath
760 );
761 }
762 }
763 gBS->RestoreTPL (OldTpl);
764
765 UpdateMainForm (ConfigPrivate);
766
767 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
768 ZeroMem (Configuration->RamDiskList, ListEntryNum);
769 break;
770
771 case CREATE_RAW_SUBMIT_QUESTION_ID:
772 //
773 // Create raw, FileHandle is NULL.
774 //
775 Status = HiiCreateRamDisk (Configuration->Size, NULL);
776 if (EFI_ERROR (Status)) {
777 break;
778 }
779
780 //
781 // Refresh the registered RAM disks list.
782 //
783 UpdateMainForm (ConfigPrivate);
784
785 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
786 break;
787
788 case CREATE_RAW_DISCARD_QUESTION_ID:
789 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
790 break;
791
792 default:
793 break;
794 }
795 }
796
797 if (!EFI_ERROR (Status)) {
798 HiiSetBrowserData (
799 &gRamDiskFormSetGuid,
800 mRamDiskStorageName,
801 sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum,
802 (UINT8 *) Configuration,
803 NULL
804 );
805 }
806 FreePool (Configuration);
807
808 return EFI_SUCCESS;
809 }