]> git.proxmox.com Git - mirror_edk2.git/blame - FatPkg/EnhancedFatDxe/Misc.c
Fix a migration bug in Fat driver as the value of lock has been changed from EDK...
[mirror_edk2.git] / FatPkg / EnhancedFatDxe / Misc.c
CommitLineData
b9ec9330
QH
1/*++\r
2\r
25ce9b1f 3Copyright (c) 2005 - 2010, Intel Corporation\r
b9ec9330
QH
4All rights reserved. This program and the accompanying materials are licensed and made available\r
5under the terms and conditions of the BSD License which accompanies this\r
6distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12\r
13Module Name:\r
14\r
15 Misc.c\r
16\r
17Abstract:\r
18\r
19 Miscellaneous functions\r
20\r
21Revision History\r
22\r
23--*/\r
24\r
25#include "Fat.h"\r
26\r
27EFI_STATUS\r
28FatAccessVolumeDirty (\r
29 IN FAT_VOLUME *Volume,\r
30 IN IO_MODE IoMode,\r
31 IN VOID *DirtyValue\r
32 )\r
33/*++\r
34\r
35Routine Description:\r
36\r
37 Set the volume as dirty or not\r
38\r
39Arguments:\r
40\r
41 Volume - FAT file system volume.\r
42 IoMode - The access mode.\r
43 DirtyValue - Set the volume as dirty or not.\r
44\r
45Returns:\r
46\r
47 EFI_SUCCESS - Set the new FAT entry value sucessfully.\r
48 other - An error occurred when operation the FAT entries.\r
49\r
50--*/\r
51{\r
52 UINTN WriteCount;\r
53\r
54 WriteCount = Volume->FatEntrySize;\r
55 return FatDiskIo (Volume, IoMode, Volume->FatPos + WriteCount, WriteCount, DirtyValue);\r
56}\r
57\r
58EFI_STATUS\r
59FatDiskIo (\r
60 IN FAT_VOLUME *Volume,\r
61 IN IO_MODE IoMode,\r
62 IN UINT64 Offset,\r
63 IN UINTN BufferSize,\r
64 IN OUT VOID *Buffer\r
65 )\r
66/*++\r
67\r
68Routine Description:\r
69\r
70 General disk access function\r
71\r
72Arguments:\r
73\r
74 Volume - FAT file system volume.\r
75 IoMode - The access mode (disk read/write or cache access).\r
76 Offset - The starting byte offset to read from.\r
77 BufferSize - Size of Buffer.\r
78 Buffer - Buffer containing read data.\r
79\r
80Returns:\r
81\r
82 EFI_SUCCESS - The operation is performed successfully.\r
83 EFI_VOLUME_CORRUPTED - The accesss is\r
84 Others - The status of read/write the disk\r
85\r
86--*/\r
87{\r
88 EFI_STATUS Status;\r
89 EFI_DISK_IO_PROTOCOL *DiskIo;\r
90 EFI_DISK_READ IoFunction;\r
91\r
92 //\r
93 // Verify the IO is in devices range\r
94 //\r
95 Status = EFI_VOLUME_CORRUPTED;\r
96 if (Offset + BufferSize <= Volume->VolumeSize) {\r
97 if (CACHE_ENABLED (IoMode)) {\r
98 //\r
99 // Access cache\r
100 //\r
101 Status = FatAccessCache (Volume, CACHE_TYPE (IoMode), RAW_ACCESS (IoMode), Offset, BufferSize, Buffer);\r
102 } else {\r
103 //\r
104 // Access disk directly\r
105 //\r
106 DiskIo = Volume->DiskIo;\r
107 IoFunction = (IoMode == READ_DISK) ? DiskIo->ReadDisk : DiskIo->WriteDisk;\r
108 Status = IoFunction (DiskIo, Volume->MediaId, Offset, BufferSize, Buffer);\r
109 }\r
110 }\r
111\r
112 if (EFI_ERROR (Status)) {\r
113 Volume->DiskError = TRUE;\r
114 DEBUG ((EFI_D_INFO, "FatDiskIo: error %r\n", Status));\r
115 }\r
116\r
117 return Status;\r
118}\r
119\r
120VOID\r
121FatAcquireLock (\r
122 VOID\r
123 )\r
124/*++\r
125\r
126Routine Description:\r
127\r
128 Lock the volume.\r
129\r
130Arguments:\r
131\r
132 None.\r
133\r
134Returns:\r
135\r
136 None.\r
137\r
138--*/\r
139{\r
140 EfiAcquireLock (&FatFsLock);\r
141}\r
142\r
25ce9b1f
QH
143EFI_STATUS\r
144FatAcquireLockOrFail (\r
b9ec9330
QH
145 VOID\r
146 )\r
147/*++\r
148\r
149Routine Description:\r
150\r
25ce9b1f
QH
151 Lock the volume.\r
152 If the lock is already in the acquired state, then EFI_ACCESS_DENIED is returned.\r
153 Otherwise, EFI_SUCCESS is returned.\r
b9ec9330
QH
154\r
155Arguments:\r
156\r
157 None.\r
158\r
159Returns:\r
160\r
25ce9b1f
QH
161 EFI_SUCCESS - The volume is locked.\r
162 EFI_ACCESS_DENIED - The volume could not be locked because it is already locked.\r
b9ec9330
QH
163\r
164--*/\r
165{\r
25ce9b1f 166 return EfiAcquireLockOrFail (&FatFsLock);\r
b9ec9330
QH
167}\r
168\r
169VOID\r
170FatReleaseLock (\r
171 VOID\r
172 )\r
173/*++\r
174\r
175Routine Description:\r
176\r
177 Unlock the volume.\r
178\r
179Arguments:\r
180\r
181 Null.\r
182\r
183Returns:\r
184\r
185 None.\r
186\r
187--*/\r
188{\r
189 EfiReleaseLock (&FatFsLock);\r
190}\r
191\r
192VOID\r
193FatFreeDirEnt (\r
194 IN FAT_DIRENT *DirEnt\r
195 )\r
196/*++\r
197\r
198Routine Description:\r
199\r
200 Free directory entry.\r
201\r
202Arguments:\r
203\r
204 DirEnt - The directory entry to be freed.\r
205\r
206Returns:\r
207\r
208 None.\r
209\r
210--*/\r
211{\r
212 if (DirEnt->FileString != NULL) {\r
213 FreePool (DirEnt->FileString);\r
214 }\r
215\r
216 FreePool (DirEnt);\r
217}\r
218\r
219VOID\r
220FatFreeVolume (\r
221 IN FAT_VOLUME *Volume\r
222 )\r
223/*++\r
224\r
225Routine Description:\r
226\r
227 Free volume structure (including the contents of directory cache and disk cache).\r
228\r
229Arguments:\r
230\r
231 Volume - The volume structure to be freed.\r
232\r
233Returns:\r
234\r
235 None.\r
236\r
237--*/\r
238{\r
239 //\r
240 // Free disk cache\r
241 //\r
242 if (Volume->CacheBuffer != NULL) {\r
243 FreePool (Volume->CacheBuffer);\r
244 }\r
245 //\r
246 // Free directory cache\r
247 //\r
248 FatCleanupODirCache (Volume);\r
249 FreePool (Volume);\r
250}\r
251\r
252VOID\r
253FatEfiTimeToFatTime (\r
254 IN EFI_TIME *ETime,\r
255 OUT FAT_DATE_TIME *FTime\r
256 )\r
257/*++\r
258\r
259Routine Description:\r
260\r
261 Translate EFI time to FAT time.\r
262\r
263Arguments:\r
264\r
265 ETime - The time of EFI_TIME.\r
266 FTime - The time of FAT_DATE_TIME.\r
267\r
268Returns:\r
269\r
270 None.\r
271\r
272--*/\r
273{\r
274 //\r
275 // ignores timezone info in source ETime\r
276 //\r
277 if (ETime->Year > 1980) {\r
278 FTime->Date.Year = (UINT16) (ETime->Year - 1980);\r
279 }\r
280\r
281 if (ETime->Year >= 1980 + FAT_MAX_YEAR_FROM_1980) {\r
282 FTime->Date.Year = FAT_MAX_YEAR_FROM_1980;\r
283 }\r
284\r
285 FTime->Date.Month = ETime->Month;\r
286 FTime->Date.Day = ETime->Day;\r
287 FTime->Time.Hour = ETime->Hour;\r
288 FTime->Time.Minute = ETime->Minute;\r
289 FTime->Time.DoubleSecond = (UINT16) (ETime->Second / 2);\r
290}\r
291\r
292VOID\r
293FatFatTimeToEfiTime (\r
294 IN FAT_DATE_TIME *FTime,\r
295 OUT EFI_TIME *ETime\r
296 )\r
297/*++\r
298\r
299Routine Description:\r
300\r
301 Translate Fat time to EFI time.\r
302\r
303Arguments:\r
304\r
305 FTime - The time of FAT_DATE_TIME.\r
306 ETime - The time of EFI_TIME.\r
307\r
308Returns:\r
309\r
310 None.\r
311\r
312--*/\r
313{\r
314 ETime->Year = (UINT16) (FTime->Date.Year + 1980);\r
315 ETime->Month = (UINT8) FTime->Date.Month;\r
316 ETime->Day = (UINT8) FTime->Date.Day;\r
317 ETime->Hour = (UINT8) FTime->Time.Hour;\r
318 ETime->Minute = (UINT8) FTime->Time.Minute;\r
319 ETime->Second = (UINT8) (FTime->Time.DoubleSecond * 2);\r
320 ETime->Nanosecond = 0;\r
321 ETime->TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
322 ETime->Daylight = 0;\r
323}\r
324\r
325VOID\r
326FatGetCurrentFatTime (\r
327 OUT FAT_DATE_TIME *FatNow\r
328 )\r
329/*++\r
330\r
331Routine Description:\r
332\r
333 Get Current FAT time.\r
334\r
335Arguments:\r
336\r
337 FatNow - Current FAT time.\r
338\r
339Returns:\r
340\r
341 None.\r
342\r
343--*/\r
344{\r
345 EFI_TIME Now;\r
346 gRT->GetTime (&Now, NULL);\r
347 FatEfiTimeToFatTime (&Now, FatNow);\r
348}\r
349\r
350BOOLEAN\r
351FatIsValidTime (\r
352 IN EFI_TIME *Time\r
353 )\r
354/*++\r
355\r
356Routine Description:\r
357\r
358 Check whether a time is valid.\r
359\r
360Arguments:\r
361\r
362 Time - The time of EFI_TIME.\r
363\r
364Returns:\r
365\r
366 TRUE - The time is valid.\r
367 FALSE - The time is not valid.\r
368\r
369--*/\r
370{\r
371 static UINT8 MonthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
372 UINTN Day;\r
373 BOOLEAN ValidTime;\r
374\r
375 ValidTime = TRUE;\r
376\r
377 //\r
378 // Check the fields for range problems\r
379 // Fat can only support from 1980\r
380 //\r
381 if (Time->Year < 1980 ||\r
382 Time->Month < 1 ||\r
383 Time->Month > 12 ||\r
384 Time->Day < 1 ||\r
385 Time->Day > 31 ||\r
386 Time->Hour > 23 ||\r
387 Time->Minute > 59 ||\r
388 Time->Second > 59 ||\r
389 Time->Nanosecond > 999999999\r
390 ) {\r
391\r
392 ValidTime = FALSE;\r
393\r
394 } else {\r
395 //\r
396 // Perform a more specific check of the day of the month\r
397 //\r
398 Day = MonthDays[Time->Month - 1];\r
399 if (Time->Month == 2 && IS_LEAP_YEAR (Time->Year)) {\r
400 Day += 1;\r
401 //\r
402 // 1 extra day this month\r
403 //\r
404 }\r
405 if (Time->Day > Day) {\r
406 ValidTime = FALSE;\r
407 }\r
408 }\r
409\r
410 return ValidTime;\r
411}\r