• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (c) 1999, 2000
4  * Intel Corporation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  *
17  * 3. All advertising materials mentioning features or use of this software must
18  *    display the following acknowledgement:
19  *
20  *    This product includes software developed by Intel Corporation and its
21  *    contributors.
22  *
23  * 4. Neither the name of Intel Corporation or its contributors may be used to
24  *    endorse or promote products derived from this software without specific
25  *    prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30  * DISCLAIMED.  IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR
31  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
34  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  *
38  */
39 #include <Uefi.h>
40 
41 #include <Protocol/BlockIo.h>
42 #include <Protocol/LoadedImage.h>
43 #include <Library/DebugLib.h>
44 #include <Library/BaseMemoryLib.h>
45 #include <Library/UefiDriverEntryPoint.h>
46 #include <Library/UefiBootServicesTableLib.h>
47 #include <Library/UefiLib.h>
48 #include <Library/BaseLib.h>
49 #include <Library/PcdLib.h>
50 #include <Library/MemoryAllocationLib.h>
51 #include <Library/DevicePathLib.h>
52 
53 #include <Guid/RamDiskGuid.h>
54 #include "ramdisk.h"
55 
56 
57 UINT32    GetDiskSize( EFI_HANDLE ImageHandle );
58 
59 /* Embedded version string for VERS utility */
60 //static char v[] = "version_number=1.00 ";
61 
62 /* EFI device path definition */
63 static RAM_DISK_DEVICE_PATH RamDiskDevicePath =
64 {
65   {MESSAGING_DEVICE_PATH,
66   MSG_VENDOR_DP,
67   {sizeof(RAM_DISK_DEVICE_PATH) - END_DEVICE_PATH_LENGTH,
68   0}},
69   RAM_DISK_GUID,
70   {0,0,0,0,0,0,0,0},  // ID assigned below
71   {END_DEVICE_PATH_TYPE,
72   END_ENTIRE_DEVICE_PATH_SUBTYPE,
73   {END_DEVICE_PATH_LENGTH}}
74 };
75 
76 /* Lookup table of total sectors vs. cluster size.
77  * Ramdisk sizes between 0x20D0 (4.1MB) and 0x100000 (512MB) sectors are valid FAT16 drive sizes.
78  */
79 #define MIN_DISK_SIZE  1
80 #define  MAX_DISK_SIZE  512
81 static FAT16TABLE fat16tbl[] =
82 {
83   {0x00000800, 1},  /* 800 sectors * 1 sec/cluster * 512 bytes = 1 M */
84   {0x00001000, 1},  /* 1000 sectors * 1 sec/cluster * 512 bytes = 2 M */
85   {0x00001800, 1},  /* 1800 sectors * 1 sec/cluster * 512 bytes = 3 M */
86   {0x00007FA8, 2},
87   {0x00040000, 4},
88   {0x00080000, 8},
89   {0x00100000,16},
90   {0xFFFFFFFF, 0}
91 };
92 
CopyBOOTSEC(VOID * Start,BOOTSEC * bsc)93 VOID CopyBOOTSEC(VOID* Start,BOOTSEC* bsc)
94 {
95 UINT32 index=0;
96 UINT8* pStart=(UINT8*)Start;
97 
98 CopyMem(&(pStart[index]), &(bsc->BS_jmpBoot[0]), sizeof(bsc->BS_jmpBoot));
99 index+=sizeof(bsc->BS_jmpBoot);
100 
101 CopyMem(&(pStart[index]), &(bsc->BS_OEMName[0]), sizeof(bsc->BS_OEMName));
102 index+=sizeof(bsc->BS_OEMName);
103 
104 CopyMem(&(pStart[index]), &(bsc->BPB_BytsPerSec), sizeof(bsc->BPB_BytsPerSec));
105 index+=sizeof(bsc->BPB_BytsPerSec);
106 
107 CopyMem(&(pStart[index]), &(bsc->BPB_SecPerClus), sizeof(bsc->BPB_SecPerClus));
108 index+=sizeof(bsc->BPB_SecPerClus);
109 
110 CopyMem(&(pStart[index]), &(bsc->BPB_RsvdSecCnt), sizeof(bsc->BPB_RsvdSecCnt));
111 index+=sizeof(bsc->BPB_RsvdSecCnt);
112 
113 CopyMem(&(pStart[index]), &(bsc->BPB_NumFATs), sizeof(bsc->BPB_NumFATs));
114 index+=sizeof(bsc->BPB_NumFATs);
115 
116 CopyMem(&(pStart[index]), &(bsc->BPB_NumFATs), sizeof(bsc->BPB_NumFATs));
117 index+=sizeof(bsc->BPB_NumFATs);
118 
119 CopyMem(&(pStart[index]), &(bsc->BPB_RootEntCnt), sizeof(bsc->BPB_RootEntCnt));
120 index+=sizeof(bsc->BPB_RootEntCnt);
121 
122 CopyMem(&(pStart[index]), &(bsc->BPB_TotSec16), sizeof(bsc->BPB_TotSec16));
123 index+=sizeof(bsc->BPB_TotSec16);
124 
125 CopyMem(&(pStart[index]), &(bsc->BPB_Media), sizeof(bsc->BPB_Media));
126 index+=sizeof(bsc->BPB_Media);
127 
128 CopyMem(&(pStart[index]), &(bsc->BPB_FATSz16), sizeof(bsc->BPB_FATSz16));
129 index+=sizeof(bsc->BPB_FATSz16);
130 
131 CopyMem(&(pStart[index]), &(bsc->BPB_SecPerTrk), sizeof(bsc->BPB_SecPerTrk));
132 index+=sizeof(bsc->BPB_SecPerTrk);
133 
134 CopyMem(&(pStart[index]), &(bsc->BPB_NumHeads), sizeof(bsc->BPB_NumHeads));
135 index+=sizeof(bsc->BPB_NumHeads);
136 
137 CopyMem(&(pStart[index]), &(bsc->BPB_HiddSec), sizeof(bsc->BPB_HiddSec));
138 index+=sizeof(bsc->BPB_HiddSec);
139 
140 CopyMem(&(pStart[index]), &(bsc->BPB_TotSec32), sizeof(bsc->BPB_TotSec32));
141 index+=sizeof(bsc->BPB_TotSec32);
142 
143 CopyMem(&(pStart[index]), &(bsc->BS_DrvNum), sizeof(bsc->BS_DrvNum));
144 index+=sizeof(bsc->BS_DrvNum);
145 
146 CopyMem(&(pStart[index]), &(bsc->BS_Reserved1), sizeof(bsc->BS_Reserved1));
147 index+=sizeof(bsc->BS_Reserved1);
148 
149 CopyMem(&(pStart[index]), &(bsc->BS_BootSig), sizeof(bsc->BS_BootSig));
150 index+=sizeof(bsc->BS_BootSig);
151 
152 CopyMem(&(pStart[index]), &(bsc->BS_VolID), sizeof(bsc->BS_VolID));
153 index+=sizeof(bsc->BS_VolID);
154 
155 CopyMem(&(pStart[index]), &(bsc->BS_VolLab[0]), sizeof(bsc->BS_VolLab));
156 index+=sizeof(bsc->BS_VolLab);
157 
158 CopyMem(&(pStart[index]), &(bsc->BS_FilSysType[0]), sizeof(bsc->BS_FilSysType));
159 index+=sizeof(bsc->BS_FilSysType);
160 
161 CopyMem(&(pStart[index]), &(bsc->BS_Code[0]), sizeof(bsc->BS_Code));
162 index+=sizeof(bsc->BS_Code);
163 
164 CopyMem(&(pStart[index]), &(bsc->BS_Sig), sizeof(bsc->BS_Sig));
165 
166 }
167 
168 
169 
170 /* Helper function to compute cluster size
171  * vs. total sectors on drive.
172  */
size2spc(UINT32 ts)173 STATIC UINT8 size2spc(UINT32 ts)
174 {
175   int i = 0;
176 
177   while(fat16tbl[i].size != 0xFFFFFFFF)
178   {
179     if(ts <= fat16tbl[i].size)
180       return fat16tbl[i].spc;
181     ++i;
182   }
183 
184   return 0;
185 }
186 
TestSize(UINT32 ts)187 UINT8 TestSize(UINT32 ts)
188 {
189   int i = 0;
190 
191   while(fat16tbl[i].size != 0xFFFFFFFF)
192   {
193     if(ts <= fat16tbl[i].size)
194       return fat16tbl[i].spc;
195     ++i;
196   }
197 
198   return 0;
199 }
200 
201 EFI_SYSTEM_TABLE  BackupSystemTable;
202 
203 /*
204  * Entry point for RamDisk driver.
205  */
206 
InitializeRamDiskDriver(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)207 EFI_STATUS InitializeRamDiskDriver(
208   IN EFI_HANDLE       ImageHandle,
209   IN EFI_SYSTEM_TABLE *SystemTable)
210 {
211   EFI_STATUS           Status;
212   RAM_DISK_DEV         *RamDiskDev;
213   UINT32               RamDiskSize;
214   UINT32               NumPages;
215   UINT32               BlockSize;
216   UINT64               DiskId;
217 
218   /*
219    * Make a copy of the system table to workaround load command bug
220    */
221   CopyMem(&BackupSystemTable,SystemTable,sizeof(BackupSystemTable));
222 
223   /*
224    * Initialize EFI library
225    */
226   //InitializeLib(ImageHandle,&BackupSystemTable);
227 
228   /* IA64 compiler is removing version string (unused?) so I use it */
229   //v[0] = 'v';
230 
231   /*
232    *  Set the disk size
233    */
234   RamDiskSize = GetDiskSize(ImageHandle);
235   BlockSize   = 512;
236 
237   /* Allocate storage for ramdisk device info on the heap.
238    */
239   RamDiskDev = AllocateZeroPool(sizeof(RAM_DISK_DEV));
240   if(RamDiskDev == NULL)
241     return EFI_OUT_OF_RESOURCES;
242 
243   /*
244    * Compute the number of 4KB pages needed by the ramdisk and allocate the memory.
245    */
246   NumPages = RamDiskSize / EFI_PAGE_SIZE;
247   if(NumPages % RamDiskSize)
248     NumPages++;
249 
250   Status = gBS->AllocatePages(AllocateAnyPages,EfiBootServicesData,NumPages,&RamDiskDev->Start);
251   if(EFI_ERROR(Status)) {
252     FreePool(RamDiskDev);
253     return Status;
254   }
255 
256   /*
257    * Initialize the ramdisk's device info.
258    */
259   (void)gBS->GetNextMonotonicCount(&DiskId);
260   CopyMem(&RamDiskDevicePath.DiskId, &DiskId, sizeof(DiskId));
261 
262   RamDiskDev->Signature            = PBLOCK_DEVICE_SIGNATURE;
263   RamDiskDev->BlkIo.Revision       = EFI_BLOCK_IO_INTERFACE_REVISION;
264   RamDiskDev->BlkIo.Media          = &RamDiskDev->Media;
265   RamDiskDev->Media.RemovableMedia = FALSE;
266   RamDiskDev->Media.MediaPresent   = TRUE;
267 
268   RamDiskDev->Media.LastBlock        = RamDiskSize/BlockSize - 1;
269   RamDiskDev->Media.BlockSize        = BlockSize;
270   RamDiskDev->Media.LogicalPartition = TRUE;
271   RamDiskDev->Media.ReadOnly         = FALSE;
272   RamDiskDev->Media.WriteCaching     = TRUE;
273 
274   RamDiskDev->BlkIo.ReadBlocks  = RamDiskReadBlocks;
275   RamDiskDev->BlkIo.WriteBlocks = RamDiskWriteBlocks;
276   RamDiskDev->BlkIo.FlushBlocks = RamDiskFlushBlocks;
277 
278   RamDiskDev->DevicePath = DuplicateDevicePath((EFI_DEVICE_PATH*)&RamDiskDevicePath);
279 
280   /*
281    * Build a FAT16 file system on the ramdisk.
282    */
283   FormatRamdisk((VOID*)(UINTN)RamDiskDev->Start,RamDiskSize);
284 
285   /*
286    * Install the device.
287    */
288 
289   Status = gBS->InstallMultipleProtocolInterfaces(
290   &ImageHandle,
291   &gEfiBlockIoProtocolGuid,
292   &RamDiskDev->BlkIo,
293   &gEfiDevicePathProtocolGuid,
294   RamDiskDev->DevicePath,
295   NULL);
296 
297 DEBUG((EFI_D_ERROR,"ramdisk:blckio install. Status=%r\n",Status));
298   return Status;
299 }
300 
301 UINT32
GetDiskSize(EFI_HANDLE ImageHandle)302 GetDiskSize( EFI_HANDLE ImageHandle )
303 {
304   EFI_STATUS      Status;
305   EFI_LOADED_IMAGE  *Image;
306   UINT32        DiskSize = PcdGet32(PcdRamDiskMaxSize);
307 
308   /*
309    * Check load options to see if they want to specify disk size in MBs
310    */
311   Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (void**)&Image);
312   if (!EFI_ERROR(Status)) {
313     if (Image->LoadOptions && Image->LoadOptionsSize) {
314 #define MAX_ARG_SIZE    32
315       CHAR16  Size[ MAX_ARG_SIZE ];
316       CHAR16  *CmdLine = Image->LoadOptions;
317       INT32  CmdLen   = (INT32)Image->LoadOptionsSize;
318 
319       /*
320        * Get past program name
321        */
322       while( CmdLen > 0 && *CmdLine != L' ' ) {
323         CmdLen -= sizeof(CHAR16);
324         CmdLine++;
325       }
326 
327       if ( CmdLen > 0 ) {
328         /*
329          * Make sure we're null terminated
330          */
331         CopyMem( Size, CmdLine, MIN(CmdLen, (INT32)sizeof(Size)));
332         Size[MAX_ARG_SIZE - 1] = 0;
333 
334         /*
335          *  Atoi() will skip any leading white space
336          */
337         DiskSize = (UINT32)StrDecimalToUintn(Size);
338         if (DiskSize == 0)
339           DiskSize = PcdGet32(PcdRamDiskMaxSize);
340         DiskSize = MAX(DiskSize, MIN_DISK_SIZE);
341         DiskSize = MIN(DiskSize, MAX_DISK_SIZE);
342       }
343     }
344   }
345 
346   return (DiskSize * 1024 * 1024);
347 }
348 
349 /* Given a block of memory representing a ramdisk, build a pseudo-boot sector
350  * and initialize the drive.
351  *
352  * Assumes the global boot sector structure g_bs has been filled out with the
353  * static information the boot sector requires.  Also assumes the ramdisk size
354  * is between 4.1MB and 512MB as appropriate for FAT16 file system.
355  */
FormatRamdisk(IN VOID * pStart,IN UINT32 Size)356 STATIC VOID FormatRamdisk(
357   IN VOID*  pStart,
358   IN UINT32 Size)
359 {
360   UINT32 TotalSectors,RootDirSectors,FatSz,tmp1,tmp2;
361   UINT8 *Fat1,*Fat2;
362     BOOTSEC g_bs;
363 
364     g_bs.BS_jmpBoot[0] = 0xeb;
365     g_bs.BS_jmpBoot[1] = 0x0;
366     g_bs.BS_jmpBoot[2] = 0x90;
367     g_bs.BS_OEMName[0] = 'E';
368     g_bs.BS_OEMName[1] = 'F';
369     g_bs.BS_OEMName[2] = 'I';
370     g_bs.BS_OEMName[3] = 'R';
371     g_bs.BS_OEMName[4] = 'D';
372     g_bs.BS_OEMName[5] = 'I';
373     g_bs.BS_OEMName[6] = 'S';
374     g_bs.BS_OEMName[7] = 'K';
375     g_bs.BPB_BytsPerSec = 512;
376     g_bs.BPB_SecPerClus = 0;
377     g_bs.BPB_RsvdSecCnt = 1;
378     g_bs.BPB_NumFATs = 2;
379     g_bs.BPB_RootEntCnt = 512;
380     g_bs.BPB_TotSec16 = 0;
381     g_bs.BPB_Media = 0xF8;
382     g_bs.BPB_FATSz16 = 0;
383     g_bs.BPB_SecPerTrk = 0;
384     g_bs.BPB_NumHeads = 0;
385     g_bs.BPB_HiddSec = 0;
386     g_bs.BPB_TotSec32 = 0;
387     g_bs.BS_DrvNum = 0;
388     g_bs.BS_Reserved1 = 0;
389     g_bs.BS_BootSig = 0x29;
390     g_bs.BS_VolID = 0;
391     g_bs.BS_VolLab[0] = 'N';
392     g_bs.BS_VolLab[1] = 'O';
393     g_bs.BS_VolLab[2] = ' ';
394     g_bs.BS_VolLab[3] = 'N';
395     g_bs.BS_VolLab[4] = 'A';
396     g_bs.BS_VolLab[5] = 'M';
397     g_bs.BS_VolLab[6] = 'E';
398     g_bs.BS_VolLab[7] = ' ';
399     g_bs.BS_VolLab[8] = ' ';
400     g_bs.BS_FilSysType[0] = 'F';
401     g_bs.BS_FilSysType[1] = 'A';
402     g_bs.BS_FilSysType[2] = 'T';
403     g_bs.BS_FilSysType[3] = '1';
404     g_bs.BS_FilSysType[4] = '6';
405     g_bs.BS_FilSysType[5] = ' ';
406     g_bs.BS_FilSysType[6] = ' ';
407     g_bs.BS_FilSysType[7] = ' ';
408   /* The boot signature needs to be filled out */
409   g_bs.BS_Sig = 0xAA55;
410 
411   /* Compute the total sectors and appropriate cluster size */
412   TotalSectors = Size / g_bs.BPB_BytsPerSec;
413   g_bs.BPB_SecPerClus = size2spc(TotalSectors);
414   ASSERT(g_bs.BPB_SecPerClus != 0);
415 
416   /* Compute how many root directory sectors are needed */
417   RootDirSectors = (g_bs.BPB_RootEntCnt * 32 + g_bs.BPB_BytsPerSec - 1) / g_bs.BPB_BytsPerSec;
418 
419   /* Compute how many sectors are required per FAT */
420   tmp1 = TotalSectors - (g_bs.BPB_RsvdSecCnt + RootDirSectors);
421   tmp2 = 256 * g_bs.BPB_SecPerClus + g_bs.BPB_NumFATs;
422   FatSz = (tmp1 + tmp2 - 1) / tmp2;
423   ASSERT(FatSz <= 0xFFFF);
424 
425   /* Store the total sectors and fat size values */
426   if(TotalSectors > 0xFFFF)
427     g_bs.BPB_TotSec32 = TotalSectors;
428   else
429     g_bs.BPB_TotSec16 = (UINT16)TotalSectors;
430 
431   g_bs.BPB_FATSz16 = (UINT16)FatSz;
432 
433   /* The FAT table and root directory need to be all zeroes.
434    * We'll zero the whole drive.
435    */
436   ZeroMem(pStart,Size);
437 
438   /* Write the completed boot sector to the ramdisk */
439   CopyMem(pStart,&g_bs,512);
440 
441   /* Compute the starting offsets of the two FATs */
442   Fat1 = (UINT8*)pStart + g_bs.BPB_RsvdSecCnt * 512;
443   Fat2 = (UINT8*)pStart + (UINTN)(g_bs.BPB_RsvdSecCnt + FatSz) * 512;
444 
445   /* Initialize FAT1 */
446   Fat1[0] = g_bs.BPB_Media;
447   Fat1[1] = 0xFF;
448   Fat1[2] = 0xFF;
449   Fat1[3] = 0xFF;
450 
451   /* Initialize FAT2 */
452   Fat2[0] = g_bs.BPB_Media;
453   Fat2[1] = 0xFF;
454   Fat2[2] = 0xFF;
455   Fat2[3] = 0xFF;
456 }
457 
458 /* Implementation of block I/O read */
RamDiskReadBlocks(IN EFI_BLOCK_IO * This,IN UINT32 MediaId,IN EFI_LBA LBA,IN UINTN BufferSize,OUT VOID * Buffer)459 STATIC EFI_STATUS RamDiskReadBlocks(
460   IN EFI_BLOCK_IO *This,
461   IN UINT32       MediaId,
462   IN EFI_LBA      LBA,
463   IN UINTN        BufferSize,
464   OUT VOID        *Buffer)
465 {
466   EFI_BLOCK_IO_MEDIA   *Media;
467   RAM_DISK_DEV         *RamDiskDev;
468   EFI_PHYSICAL_ADDRESS RamDiskLBA;
469 
470   Media = This->Media;
471 
472   if(BufferSize % Media->BlockSize != 0)
473     return EFI_BAD_BUFFER_SIZE;
474 
475   if(LBA > Media->LastBlock)
476     return EFI_DEVICE_ERROR;
477 
478   if(LBA + BufferSize / Media->BlockSize - 1 > Media->LastBlock)
479     return EFI_DEVICE_ERROR;
480 
481   RamDiskDev = RAM_DISK_FROM_THIS(This);
482   RamDiskLBA = RamDiskDev->Start + MultU64x32(LBA,Media->BlockSize);
483   CopyMem(Buffer,(VOID*)(UINTN)RamDiskLBA,BufferSize);
484 
485   return EFI_SUCCESS;
486 }
487 
488 
489 /* Implementation of block I/O write */
RamDiskWriteBlocks(IN EFI_BLOCK_IO * This,IN UINT32 MediaId,IN EFI_LBA LBA,IN UINTN BufferSize,IN VOID * Buffer)490 STATIC EFI_STATUS RamDiskWriteBlocks(
491   IN EFI_BLOCK_IO *This,
492   IN UINT32       MediaId,
493   IN EFI_LBA      LBA,
494   IN UINTN        BufferSize,
495   IN VOID         *Buffer)
496 {
497   EFI_BLOCK_IO_MEDIA   *Media;
498   RAM_DISK_DEV         *RamDiskDev;
499   EFI_PHYSICAL_ADDRESS RamDiskLBA;
500 
501   Media = This->Media;
502   if(Media->ReadOnly)
503     return EFI_WRITE_PROTECTED;
504 
505   if(BufferSize % Media->BlockSize != 0)
506     return EFI_BAD_BUFFER_SIZE;
507 
508   if(LBA > Media->LastBlock)
509     return EFI_DEVICE_ERROR;
510 
511   if(LBA + BufferSize / Media->BlockSize - 1 > Media->LastBlock)
512     return EFI_DEVICE_ERROR;
513 
514   RamDiskDev = RAM_DISK_FROM_THIS(This);
515   RamDiskLBA = RamDiskDev->Start + MultU64x32(LBA,Media->BlockSize);
516   CopyMem((VOID*)(UINTN)RamDiskLBA,Buffer,BufferSize);
517 
518   return EFI_SUCCESS;
519 }
520 
521 /* Implementation of block I/O flush */
RamDiskFlushBlocks(IN EFI_BLOCK_IO * This)522 STATIC EFI_STATUS RamDiskFlushBlocks(
523   IN EFI_BLOCK_IO *This)
524 {
525   return EFI_SUCCESS;
526 }
527