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