1 /* Some of the source code in this file came from "linux/fs/fat/misc.c". */
5 * Written 1992,1993 by Werner Almesberger
6 * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980
7 * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
11 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 /************************************************************************/
30 /* PROJECT : exFAT & FAT12/16/32 File System */
31 /* FILE : exfat_oal.c */
32 /* PURPOSE : exFAT OS Adaptation Layer */
33 /* (Semaphore Functions & Real-Time Clock Functions) */
35 /*----------------------------------------------------------------------*/
38 /*----------------------------------------------------------------------*/
39 /* REVISION HISTORY (Ver 0.9) */
41 /* - 2010.11.15 [Joosun Hahn] : first writing */
43 /************************************************************************/
45 #include <linux/semaphore.h>
46 #include <linux/time.h>
48 #include "exfat_config.h"
49 #include "exfat_global.h"
50 #include "exfat_api.h"
51 #include "exfat_oal.h"
53 /*======================================================================*/
55 /* SEMAPHORE FUNCTIONS */
57 /*======================================================================*/
61 INT32
sm_init(struct semaphore
*sm
)
65 } /* end of sm_init */
67 INT32
sm_P(struct semaphore
*sm
)
73 void sm_V(struct semaphore
*sm
)
79 /*======================================================================*/
81 /* REAL-TIME CLOCK FUNCTIONS */
83 /*======================================================================*/
85 extern struct timezone sys_tz
;
88 * The epoch of FAT timestamp is 1980.
90 * date: 0 - 4: day (1 - 31)
91 * date: 5 - 8: month (1 - 12)
92 * date: 9 - 15: year (0 - 127) from 1980
93 * time: 0 - 4: sec (0 - 29) 2sec counts
94 * time: 5 - 10: min (0 - 59)
95 * time: 11 - 15: hour (0 - 23)
97 #define UNIX_SECS_1980 315532800L
99 #if BITS_PER_LONG == 64
100 #define UNIX_SECS_2108 4354819200L
102 /* days between 1.1.70 and 1.1.80 (2 leap days) */
103 #define DAYS_DELTA_DECADE (365 * 10 + 2)
104 /* 120 (2100 - 1980) isn't leap year */
105 #define NO_LEAP_YEAR_2100 (120)
106 #define IS_LEAP_YEAR(y) (!((y) & 3) && (y) != NO_LEAP_YEAR_2100)
108 #define SECS_PER_MIN (60)
109 #define SECS_PER_HOUR (60 * SECS_PER_MIN)
110 #define SECS_PER_DAY (24 * SECS_PER_HOUR)
112 #define MAKE_LEAP_YEAR(leap_year, year) \
114 if (unlikely(year > NO_LEAP_YEAR_2100)) \
115 leap_year = ((year + 3) / 4) - 1; \
117 leap_year = ((year + 3) / 4); \
120 /* Linear day numbers of the respective 1sts in non-leap years. */
121 static time_t accum_days_in_year
[] = {
122 /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
123 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0,
126 TIMESTAMP_T
*tm_current(TIMESTAMP_T
*tp
)
128 struct timespec ts
= CURRENT_TIME_SEC
;
129 time_t second
= ts
.tv_sec
;
130 time_t day
, leap_day
, month
, year
;
132 second
-= sys_tz
.tz_minuteswest
* SECS_PER_MIN
;
134 /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
135 if (second
< UNIX_SECS_1980
) {
144 #if BITS_PER_LONG == 64
145 if (second
>= UNIX_SECS_2108
) {
156 day
= second
/ SECS_PER_DAY
- DAYS_DELTA_DECADE
;
159 MAKE_LEAP_YEAR(leap_day
, year
);
160 if (year
* 365 + leap_day
> day
)
163 MAKE_LEAP_YEAR(leap_day
, year
);
165 day
-= year
* 365 + leap_day
;
167 if (IS_LEAP_YEAR(year
) && day
== accum_days_in_year
[3]) {
170 if (IS_LEAP_YEAR(year
) && day
> accum_days_in_year
[3])
172 for (month
= 1; month
< 12; month
++) {
173 if (accum_days_in_year
[month
+ 1] > day
)
177 day
-= accum_days_in_year
[month
];
179 tp
->sec
= second
% SECS_PER_MIN
;
180 tp
->min
= (second
/ SECS_PER_MIN
) % 60;
181 tp
->hour
= (second
/ SECS_PER_HOUR
) % 24;
187 } /* end of tm_current */
189 /* end of exfat_oal.c */