1 /*
2 * linux/include/linux/hfs_sysdep.h
3 *
4 * Copyright (C) 1996-1997 Paul H. Hargrove
5 * This file may be distributed under the terms of the GNU General Public License.
6 *
7 * This file contains constants, types and inline
8 * functions for various system dependent things.
9 *
10 * "XXX" in a comment is a note to myself to consider changing something.
11 *
12 * In function preconditions the term "valid" applied to a pointer to
13 * a structure means that the pointer is non-NULL and the structure it
14 * points to has all fields initialized to consistent values.
15 */
16
17 #ifndef _HFS_SYSDEP_H
18 #define _HFS_SYSDEP_H
19
20 #include <linux/slab.h>
21 #include <linux/types.h>
22 #include <linux/locks.h>
23 #include <linux/fs.h>
24
25 #include <asm/byteorder.h>
26 #include <asm/unaligned.h>
27
28 extern struct timezone sys_tz;
29
30 #undef offsetof
31 #define offsetof(TYPE, MEMB) ((size_t) &((TYPE *)0)->MEMB)
32
33 /* Typedefs for integer types by size and signedness */
34 typedef __u8 hfs_u8;
35 typedef __u16 hfs_u16;
36 typedef __u32 hfs_u32;
37 typedef __s8 hfs_s8;
38 typedef __s16 hfs_s16;
39 typedef __s32 hfs_s32;
40
41 /* Typedefs for unaligned integer types */
42 typedef unsigned char hfs_byte_t;
43 typedef unsigned char hfs_word_t[2];
44 typedef unsigned char hfs_lword_t[4];
45
46 /* these funny looking things are GCC variable argument macros */
47 #define hfs_warn(format, args...) printk(KERN_WARNING format , ## args)
48 #define hfs_error(format, args...) printk(KERN_ERR format , ## args)
49
50
51 #if defined(DEBUG_ALL) || defined(DEBUG_MEM)
52 extern long int hfs_alloc;
53 #endif
54
hfs_malloc(unsigned int size)55 static inline void *hfs_malloc(unsigned int size) {
56 #if defined(DEBUG_ALL) || defined(DEBUG_MEM)
57 hfs_warn("%ld bytes allocation at %s:%u\n",
58 (hfs_alloc += size), __FILE__, __LINE__);
59 #endif
60 return kmalloc(size, GFP_KERNEL);
61 }
62
hfs_free(void * ptr,unsigned int size)63 static inline void hfs_free(void *ptr, unsigned int size) {
64 kfree(ptr);
65 #if defined(DEBUG_ALL) || defined(DEBUG_MEM)
66 hfs_warn("%ld bytes allocation at %s:%u\n",
67 (hfs_alloc -= ptr ? size : 0), __FILE__, __LINE__);
68 #endif
69 }
70
71
72 /* handle conversion between times.
73 *
74 * NOTE: hfs+ doesn't need this. also, we don't use tz_dsttime as that's
75 * not a good thing to do. instead, we depend upon tz_minuteswest
76 * having the correct daylight savings correction.
77 */
hfs_from_utc(hfs_s32 time)78 static inline hfs_u32 hfs_from_utc(hfs_s32 time)
79 {
80 return time - sys_tz.tz_minuteswest*60;
81 }
82
hfs_to_utc(hfs_u32 time)83 static inline hfs_s32 hfs_to_utc(hfs_u32 time)
84 {
85 return time + sys_tz.tz_minuteswest*60;
86 }
87
hfs_time(void)88 static inline hfs_u32 hfs_time(void) {
89 return htonl(hfs_from_utc(CURRENT_TIME)+2082844800U);
90 }
91
92
93 /*
94 * hfs_wait_queue
95 */
96 typedef wait_queue_head_t hfs_wait_queue;
97
hfs_init_waitqueue(hfs_wait_queue * queue)98 static inline void hfs_init_waitqueue(hfs_wait_queue *queue) {
99 init_waitqueue_head(queue);
100 }
101
hfs_sleep_on(hfs_wait_queue * queue)102 static inline void hfs_sleep_on(hfs_wait_queue *queue) {
103 sleep_on(queue);
104 }
105
hfs_wake_up(hfs_wait_queue * queue)106 static inline void hfs_wake_up(hfs_wait_queue *queue) {
107 wake_up(queue);
108 }
109
hfs_relinquish(void)110 static inline void hfs_relinquish(void) {
111 schedule();
112 }
113
114
115 /*
116 * hfs_sysmdb
117 */
118 typedef struct super_block *hfs_sysmdb;
119
hfs_mdb_dirty(hfs_sysmdb sys_mdb)120 static inline void hfs_mdb_dirty(hfs_sysmdb sys_mdb) {
121 sys_mdb->s_dirt = 1;
122 }
123
hfs_mdb_name(hfs_sysmdb sys_mdb)124 static inline const char *hfs_mdb_name(hfs_sysmdb sys_mdb) {
125 return kdevname(sys_mdb->s_dev);
126 }
127
128
129 /*
130 * hfs_sysentry
131 */
132 typedef struct dentry *hfs_sysentry[4];
133
134 /*
135 * hfs_buffer
136 */
137 typedef struct buffer_head *hfs_buffer;
138
139 #define HFS_BAD_BUFFER NULL
140
141 /* In sysdep.c, since it needs HFS_SECTOR_SIZE */
142 extern hfs_buffer hfs_buffer_get(hfs_sysmdb, int, int);
143
hfs_buffer_ok(hfs_buffer buffer)144 static inline int hfs_buffer_ok(hfs_buffer buffer) {
145 return (buffer != NULL);
146 }
147
hfs_buffer_put(hfs_buffer buffer)148 static inline void hfs_buffer_put(hfs_buffer buffer) {
149 brelse(buffer);
150 }
151
hfs_buffer_dirty(hfs_buffer buffer)152 static inline void hfs_buffer_dirty(hfs_buffer buffer) {
153 mark_buffer_dirty(buffer);
154 }
155
hfs_buffer_sync(hfs_buffer buffer)156 static inline void hfs_buffer_sync(hfs_buffer buffer) {
157 while (buffer_locked(buffer)) {
158 wait_on_buffer(buffer);
159 }
160 if (buffer_dirty(buffer)) {
161 ll_rw_block(WRITE, 1, &buffer);
162 wait_on_buffer(buffer);
163 }
164 }
165
hfs_buffer_data(const hfs_buffer buffer)166 static inline void *hfs_buffer_data(const hfs_buffer buffer) {
167 return buffer->b_data;
168 }
169
170
171 /*
172 * bit operations
173 */
174
175 #undef BITNR
176 #if defined(__BIG_ENDIAN)
177 # define BITNR(X) ((X)^31)
178 # if !defined(__constant_htonl)
179 # define __constant_htonl(x) (x)
180 # endif
181 # if !defined(__constant_htons)
182 # define __constant_htons(x) (x)
183 # endif
184 #elif defined(__LITTLE_ENDIAN)
185 # define BITNR(X) ((X)^7)
186 # if !defined(__constant_htonl)
187 # define __constant_htonl(x) \
188 ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
189 (((unsigned long int)(x) & 0x0000ff00U) << 8) | \
190 (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
191 (((unsigned long int)(x) & 0xff000000U) >> 24)))
192 # endif
193 # if !defined(__constant_htons)
194 # define __constant_htons(x) \
195 ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
196 (((unsigned short int)(x) & 0xff00) >> 8)))
197 # endif
198 #else
199 # error "Don't know if bytes are big- or little-endian!"
200 #endif
201
hfs_clear_bit(int bitnr,hfs_u32 * lword)202 static inline int hfs_clear_bit(int bitnr, hfs_u32 *lword) {
203 return test_and_clear_bit(BITNR(bitnr), lword);
204 }
205
hfs_set_bit(int bitnr,hfs_u32 * lword)206 static inline int hfs_set_bit(int bitnr, hfs_u32 *lword) {
207 return test_and_set_bit(BITNR(bitnr), lword);
208 }
209
hfs_test_bit(int bitnr,const hfs_u32 * lword)210 static inline int hfs_test_bit(int bitnr, const hfs_u32 *lword) {
211 /* the kernel should declare the second arg of test_bit as const */
212 return test_bit(BITNR(bitnr), (void *)lword);
213 }
214
215 #undef BITNR
216
217 /*
218 * HFS structures have fields aligned to 16-bit boundaries.
219 * So, 16-bit get/put are easy while 32-bit get/put need
220 * some care on architectures like the DEC Alpha.
221 *
222 * In what follows:
223 * ns = 16-bit integer in network byte-order w/ 16-bit alignment
224 * hs = 16-bit integer in host byte-order w/ 16-bit alignment
225 * nl = 32-bit integer in network byte-order w/ unknown alignment
226 * hl = 32-bit integer in host byte-order w/ unknown alignment
227 * anl = 32-bit integer in network byte-order w/ 32-bit alignment
228 * ahl = 32-bit integer in host byte-order w/ 32-bit alignment
229 * Example: hfs_get_hl() gets an unaligned 32-bit integer converting
230 * it to host byte-order.
231 */
232 #define hfs_get_hs(addr) ntohs(*((hfs_u16 *)(addr)))
233 #define hfs_get_ns(addr) (*((hfs_u16 *)(addr)))
234 #define hfs_get_hl(addr) ntohl(get_unaligned((hfs_u32 *)(addr)))
235 #define hfs_get_nl(addr) get_unaligned((hfs_u32 *)(addr))
236 #define hfs_get_ahl(addr) ntohl(*((hfs_u32 *)(addr)))
237 #define hfs_get_anl(addr) (*((hfs_u32 *)(addr)))
238 #define hfs_put_hs(val, addr) ((void)(*((hfs_u16 *)(addr)) = ntohs(val)))
239 #define hfs_put_ns(val, addr) ((void)(*((hfs_u16 *)(addr)) = (val)))
240 #define hfs_put_hl(val, addr) put_unaligned(htonl(val), (hfs_u32 *)(addr))
241 #define hfs_put_nl(val, addr) put_unaligned((val), (hfs_u32 *)(addr))
242 #define hfs_put_ahl(val, addr) ((void)(*((hfs_u32 *)(addr)) = ntohl(val)))
243 #define hfs_put_anl(val, addr) ((void)(*((hfs_u32 *)(addr)) = (val)))
244
245 #endif
246