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