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