xref: /minix3/lib/libc/citrus/modules/citrus_mapper_zone.c (revision 2fe8fb192fe7e8720e3e7a77f928da545e872a6a)
1*2fe8fb19SBen Gras /*	$NetBSD: citrus_mapper_zone.c,v 1.4 2003/07/12 15:39:21 tshiozak Exp $	*/
2*2fe8fb19SBen Gras 
3*2fe8fb19SBen Gras /*-
4*2fe8fb19SBen Gras  * Copyright (c)2003 Citrus Project,
5*2fe8fb19SBen Gras  * All rights reserved.
6*2fe8fb19SBen Gras  *
7*2fe8fb19SBen Gras  * Redistribution and use in source and binary forms, with or without
8*2fe8fb19SBen Gras  * modification, are permitted provided that the following conditions
9*2fe8fb19SBen Gras  * are met:
10*2fe8fb19SBen Gras  * 1. Redistributions of source code must retain the above copyright
11*2fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer.
12*2fe8fb19SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
13*2fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer in the
14*2fe8fb19SBen Gras  *    documentation and/or other materials provided with the distribution.
15*2fe8fb19SBen Gras  *
16*2fe8fb19SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*2fe8fb19SBen Gras  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*2fe8fb19SBen Gras  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*2fe8fb19SBen Gras  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*2fe8fb19SBen Gras  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*2fe8fb19SBen Gras  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*2fe8fb19SBen Gras  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*2fe8fb19SBen Gras  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*2fe8fb19SBen Gras  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*2fe8fb19SBen Gras  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*2fe8fb19SBen Gras  * SUCH DAMAGE.
27*2fe8fb19SBen Gras  */
28*2fe8fb19SBen Gras 
29*2fe8fb19SBen Gras #include <sys/cdefs.h>
30*2fe8fb19SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
31*2fe8fb19SBen Gras __RCSID("$NetBSD: citrus_mapper_zone.c,v 1.4 2003/07/12 15:39:21 tshiozak Exp $");
32*2fe8fb19SBen Gras #endif /* LIBC_SCCS and not lint */
33*2fe8fb19SBen Gras 
34*2fe8fb19SBen Gras #include <assert.h>
35*2fe8fb19SBen Gras #include <errno.h>
36*2fe8fb19SBen Gras #include <stdio.h>
37*2fe8fb19SBen Gras #include <stdlib.h>
38*2fe8fb19SBen Gras #include <string.h>
39*2fe8fb19SBen Gras #include <sys/queue.h>
40*2fe8fb19SBen Gras 
41*2fe8fb19SBen Gras #include "citrus_namespace.h"
42*2fe8fb19SBen Gras #include "citrus_types.h"
43*2fe8fb19SBen Gras #include "citrus_bcs.h"
44*2fe8fb19SBen Gras #include "citrus_module.h"
45*2fe8fb19SBen Gras #include "citrus_region.h"
46*2fe8fb19SBen Gras #include "citrus_memstream.h"
47*2fe8fb19SBen Gras #include "citrus_mmap.h"
48*2fe8fb19SBen Gras #include "citrus_hash.h"
49*2fe8fb19SBen Gras #include "citrus_mapper.h"
50*2fe8fb19SBen Gras #include "citrus_mapper_zone.h"
51*2fe8fb19SBen Gras 
52*2fe8fb19SBen Gras /* ---------------------------------------------------------------------- */
53*2fe8fb19SBen Gras 
54*2fe8fb19SBen Gras _CITRUS_MAPPER_DECLS(mapper_zone);
55*2fe8fb19SBen Gras _CITRUS_MAPPER_DEF_OPS(mapper_zone);
56*2fe8fb19SBen Gras 
57*2fe8fb19SBen Gras 
58*2fe8fb19SBen Gras /* ---------------------------------------------------------------------- */
59*2fe8fb19SBen Gras 
60*2fe8fb19SBen Gras struct _zone {
61*2fe8fb19SBen Gras 	u_int32_t z_begin;
62*2fe8fb19SBen Gras 	u_int32_t z_end;
63*2fe8fb19SBen Gras };
64*2fe8fb19SBen Gras 
65*2fe8fb19SBen Gras struct _citrus_mapper_zone {
66*2fe8fb19SBen Gras 	struct _zone	mz_row;
67*2fe8fb19SBen Gras 	struct _zone	mz_col;
68*2fe8fb19SBen Gras 	int		mz_col_bits;
69*2fe8fb19SBen Gras 	int32_t		mz_row_offset;
70*2fe8fb19SBen Gras 	int32_t		mz_col_offset;
71*2fe8fb19SBen Gras };
72*2fe8fb19SBen Gras 
73*2fe8fb19SBen Gras struct _parse_state {
74*2fe8fb19SBen Gras 	enum { S_BEGIN, S_OFFSET }	ps_state;
75*2fe8fb19SBen Gras 	union {
76*2fe8fb19SBen Gras 		u_int32_t	u_imm;
77*2fe8fb19SBen Gras 		int32_t		s_imm;
78*2fe8fb19SBen Gras 		struct _zone	zone;
79*2fe8fb19SBen Gras 	} u;
80*2fe8fb19SBen Gras #define ps_u_imm	u.u_imm
81*2fe8fb19SBen Gras #define ps_s_imm	u.s_imm
82*2fe8fb19SBen Gras #define ps_zone		u.zone
83*2fe8fb19SBen Gras 	int ps_top;
84*2fe8fb19SBen Gras };
85*2fe8fb19SBen Gras 
86*2fe8fb19SBen Gras int
_citrus_mapper_zone_mapper_getops(struct _citrus_mapper_ops * ops,size_t lenops,uint32_t expected_version)87*2fe8fb19SBen Gras _citrus_mapper_zone_mapper_getops(struct _citrus_mapper_ops *ops,
88*2fe8fb19SBen Gras 				  size_t lenops, uint32_t expected_version)
89*2fe8fb19SBen Gras {
90*2fe8fb19SBen Gras 	if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
91*2fe8fb19SBen Gras 		return EINVAL;
92*2fe8fb19SBen Gras 
93*2fe8fb19SBen Gras 	memcpy(ops, &_citrus_mapper_zone_mapper_ops,
94*2fe8fb19SBen Gras 	       sizeof(_citrus_mapper_zone_mapper_ops));
95*2fe8fb19SBen Gras 
96*2fe8fb19SBen Gras 	return 0;
97*2fe8fb19SBen Gras }
98*2fe8fb19SBen Gras 
99*2fe8fb19SBen Gras #define BUFSIZE 20
100*2fe8fb19SBen Gras #define T_ERR	0x100
101*2fe8fb19SBen Gras #define T_IMM	0x101
102*2fe8fb19SBen Gras 
103*2fe8fb19SBen Gras static int
get_imm(struct _memstream * ms,struct _parse_state * ps)104*2fe8fb19SBen Gras get_imm(struct _memstream *ms, struct _parse_state *ps)
105*2fe8fb19SBen Gras {
106*2fe8fb19SBen Gras 	int sign = 0;
107*2fe8fb19SBen Gras 	int c, i;
108*2fe8fb19SBen Gras 	char buf[BUFSIZE+1], *p;
109*2fe8fb19SBen Gras 
110*2fe8fb19SBen Gras 	for (i=0; i<BUFSIZE; i++) {
111*2fe8fb19SBen Gras retry:
112*2fe8fb19SBen Gras 		c = _memstream_peek(ms);
113*2fe8fb19SBen Gras 		if (i==0) {
114*2fe8fb19SBen Gras 			if (sign == 0 && (c == '+' || c == '-')) {
115*2fe8fb19SBen Gras 				sign = c;
116*2fe8fb19SBen Gras 				_memstream_getc(ms);
117*2fe8fb19SBen Gras 				goto retry;
118*2fe8fb19SBen Gras 			} else if (!_bcs_isdigit(c))
119*2fe8fb19SBen Gras 				break;
120*2fe8fb19SBen Gras 		} else if (!_bcs_isxdigit(c))
121*2fe8fb19SBen Gras 			if (!(i==1 && c == 'x'))
122*2fe8fb19SBen Gras 				break;
123*2fe8fb19SBen Gras 		buf[i] = _memstream_getc(ms);
124*2fe8fb19SBen Gras 	}
125*2fe8fb19SBen Gras 	buf[i] = '\0';
126*2fe8fb19SBen Gras 	ps->ps_u_imm = strtoul(buf, &p, 0);
127*2fe8fb19SBen Gras 	if ((p-buf) != i)
128*2fe8fb19SBen Gras 		return T_ERR;
129*2fe8fb19SBen Gras 	if (sign == '-')
130*2fe8fb19SBen Gras 		ps->ps_u_imm = (unsigned long)-(long)ps->ps_u_imm;
131*2fe8fb19SBen Gras 	return T_IMM;
132*2fe8fb19SBen Gras }
133*2fe8fb19SBen Gras 
134*2fe8fb19SBen Gras static int
get_tok(struct _memstream * ms,struct _parse_state * ps)135*2fe8fb19SBen Gras get_tok(struct _memstream *ms, struct _parse_state *ps)
136*2fe8fb19SBen Gras {
137*2fe8fb19SBen Gras 	int c;
138*2fe8fb19SBen Gras 
139*2fe8fb19SBen Gras loop:
140*2fe8fb19SBen Gras 	c = _memstream_peek(ms);
141*2fe8fb19SBen Gras 	if (c==0x00)
142*2fe8fb19SBen Gras 		return EOF;
143*2fe8fb19SBen Gras 	if (_bcs_isspace(c)) {
144*2fe8fb19SBen Gras 		_memstream_getc(ms);
145*2fe8fb19SBen Gras 		goto loop;
146*2fe8fb19SBen Gras 	}
147*2fe8fb19SBen Gras 
148*2fe8fb19SBen Gras 	switch (ps->ps_state) {
149*2fe8fb19SBen Gras 	case S_BEGIN:
150*2fe8fb19SBen Gras 		switch (c) {
151*2fe8fb19SBen Gras 		case ':':
152*2fe8fb19SBen Gras 		case '-':
153*2fe8fb19SBen Gras 		case '/':
154*2fe8fb19SBen Gras 			_memstream_getc(ms);
155*2fe8fb19SBen Gras 			return c;
156*2fe8fb19SBen Gras 		case '0':
157*2fe8fb19SBen Gras 		case '1':
158*2fe8fb19SBen Gras 		case '2':
159*2fe8fb19SBen Gras 		case '3':
160*2fe8fb19SBen Gras 		case '4':
161*2fe8fb19SBen Gras 		case '5':
162*2fe8fb19SBen Gras 		case '6':
163*2fe8fb19SBen Gras 		case '7':
164*2fe8fb19SBen Gras 		case '8':
165*2fe8fb19SBen Gras 		case '9':
166*2fe8fb19SBen Gras 			return get_imm(ms, ps);
167*2fe8fb19SBen Gras 		}
168*2fe8fb19SBen Gras 		break;
169*2fe8fb19SBen Gras 	case S_OFFSET:
170*2fe8fb19SBen Gras 		switch (c) {
171*2fe8fb19SBen Gras 		case '/':
172*2fe8fb19SBen Gras 			_memstream_getc(ms);
173*2fe8fb19SBen Gras 			return c;
174*2fe8fb19SBen Gras 		case '+':
175*2fe8fb19SBen Gras 		case '-':
176*2fe8fb19SBen Gras 		case '0':
177*2fe8fb19SBen Gras 		case '1':
178*2fe8fb19SBen Gras 		case '2':
179*2fe8fb19SBen Gras 		case '3':
180*2fe8fb19SBen Gras 		case '4':
181*2fe8fb19SBen Gras 		case '5':
182*2fe8fb19SBen Gras 		case '6':
183*2fe8fb19SBen Gras 		case '7':
184*2fe8fb19SBen Gras 		case '8':
185*2fe8fb19SBen Gras 		case '9':
186*2fe8fb19SBen Gras 			return get_imm(ms, ps);
187*2fe8fb19SBen Gras 		}
188*2fe8fb19SBen Gras 		break;
189*2fe8fb19SBen Gras 	}
190*2fe8fb19SBen Gras 	return T_ERR;
191*2fe8fb19SBen Gras }
192*2fe8fb19SBen Gras 
193*2fe8fb19SBen Gras static int
parse_zone(struct _memstream * ms,struct _parse_state * ps,struct _zone * z)194*2fe8fb19SBen Gras parse_zone(struct _memstream *ms, struct _parse_state *ps, struct _zone *z)
195*2fe8fb19SBen Gras {
196*2fe8fb19SBen Gras 	if (get_tok(ms, ps) != T_IMM)
197*2fe8fb19SBen Gras 		return -1;
198*2fe8fb19SBen Gras 	z->z_begin = ps->ps_u_imm;
199*2fe8fb19SBen Gras 	if (get_tok(ms, ps) != '-')
200*2fe8fb19SBen Gras 		return -1;
201*2fe8fb19SBen Gras 	if (get_tok(ms, ps) != T_IMM)
202*2fe8fb19SBen Gras 		return -1;
203*2fe8fb19SBen Gras 	z->z_end = ps->ps_u_imm;
204*2fe8fb19SBen Gras 
205*2fe8fb19SBen Gras 	if (z->z_begin > z->z_end)
206*2fe8fb19SBen Gras 		return -1;
207*2fe8fb19SBen Gras 
208*2fe8fb19SBen Gras 	return 0;
209*2fe8fb19SBen Gras }
210*2fe8fb19SBen Gras 
211*2fe8fb19SBen Gras static int
check_rowcol(struct _zone * z,int32_t ofs,uint32_t maxval)212*2fe8fb19SBen Gras check_rowcol(struct _zone *z, int32_t ofs, uint32_t maxval)
213*2fe8fb19SBen Gras {
214*2fe8fb19SBen Gras 	u_int32_t remain;
215*2fe8fb19SBen Gras 
216*2fe8fb19SBen Gras 	if (maxval != 0 && z->z_end >= maxval)
217*2fe8fb19SBen Gras 		return -1;
218*2fe8fb19SBen Gras 
219*2fe8fb19SBen Gras 	if (ofs > 0) {
220*2fe8fb19SBen Gras 		if (maxval == 0) {
221*2fe8fb19SBen Gras 			/* this should 0x100000000 - z->z_end */
222*2fe8fb19SBen Gras 			if (z->z_end == 0) {
223*2fe8fb19SBen Gras 				remain = 0xFFFFFFFF;
224*2fe8fb19SBen Gras 			} else {
225*2fe8fb19SBen Gras 				remain = 0xFFFFFFFF - z->z_end + 1;
226*2fe8fb19SBen Gras 			}
227*2fe8fb19SBen Gras 		} else
228*2fe8fb19SBen Gras 			remain = maxval - z->z_end;
229*2fe8fb19SBen Gras 		if ((u_int32_t)ofs > remain)
230*2fe8fb19SBen Gras 			return -1;
231*2fe8fb19SBen Gras 	} else if (ofs < 0) {
232*2fe8fb19SBen Gras 		if (z->z_begin < (u_int32_t)-ofs)
233*2fe8fb19SBen Gras 			return -1;
234*2fe8fb19SBen Gras 	}
235*2fe8fb19SBen Gras 
236*2fe8fb19SBen Gras 	return 0;
237*2fe8fb19SBen Gras }
238*2fe8fb19SBen Gras 
239*2fe8fb19SBen Gras static int
parse_var(struct _citrus_mapper_zone * mz,struct _memstream * ms)240*2fe8fb19SBen Gras parse_var(struct _citrus_mapper_zone *mz, struct _memstream *ms)
241*2fe8fb19SBen Gras {
242*2fe8fb19SBen Gras 	struct _parse_state ps;
243*2fe8fb19SBen Gras 	int ret, isrc;
244*2fe8fb19SBen Gras 	uint32_t rowmax, colmax;
245*2fe8fb19SBen Gras 
246*2fe8fb19SBen Gras 	ps.ps_state = S_BEGIN;
247*2fe8fb19SBen Gras 
248*2fe8fb19SBen Gras 	if (parse_zone(ms, &ps, &mz->mz_col))
249*2fe8fb19SBen Gras 		return -1;
250*2fe8fb19SBen Gras 
251*2fe8fb19SBen Gras 	ret = get_tok(ms, &ps);
252*2fe8fb19SBen Gras 	if (ret == '/') {
253*2fe8fb19SBen Gras 		/* rowzone / colzone / bits */
254*2fe8fb19SBen Gras 		isrc = 1;
255*2fe8fb19SBen Gras 		mz->mz_row = mz->mz_col;
256*2fe8fb19SBen Gras 
257*2fe8fb19SBen Gras 		if (parse_zone(ms, &ps, &mz->mz_col))
258*2fe8fb19SBen Gras 			return -1;
259*2fe8fb19SBen Gras 		if (get_tok(ms, &ps) != '/')
260*2fe8fb19SBen Gras 			return -1;
261*2fe8fb19SBen Gras 		if (get_tok(ms, &ps) != T_IMM)
262*2fe8fb19SBen Gras 			return -1;
263*2fe8fb19SBen Gras 		mz->mz_col_bits = ps.ps_u_imm;
264*2fe8fb19SBen Gras 		if (mz->mz_col_bits<0 || mz->mz_col_bits>32)
265*2fe8fb19SBen Gras 			return -1;
266*2fe8fb19SBen Gras 		ret = get_tok(ms, &ps);
267*2fe8fb19SBen Gras 	} else {
268*2fe8fb19SBen Gras 		/* colzone */
269*2fe8fb19SBen Gras 		isrc = 0;
270*2fe8fb19SBen Gras 		mz->mz_col_bits = 32;
271*2fe8fb19SBen Gras 		mz->mz_row.z_begin = mz->mz_row.z_end = 0;
272*2fe8fb19SBen Gras 	}
273*2fe8fb19SBen Gras 	if (ret == ':') {
274*2fe8fb19SBen Gras 		/* offset */
275*2fe8fb19SBen Gras 		ps.ps_state = S_OFFSET;
276*2fe8fb19SBen Gras 		if (get_tok(ms, &ps) != T_IMM)
277*2fe8fb19SBen Gras 			return -1;
278*2fe8fb19SBen Gras 		mz->mz_col_offset = ps.ps_s_imm;
279*2fe8fb19SBen Gras 		if (isrc) {
280*2fe8fb19SBen Gras 			/* row/col */
281*2fe8fb19SBen Gras 			mz->mz_row_offset = mz->mz_col_offset;
282*2fe8fb19SBen Gras 			if (get_tok(ms, &ps) != '/')
283*2fe8fb19SBen Gras 				return -1;
284*2fe8fb19SBen Gras 			if (get_tok(ms, &ps) != T_IMM)
285*2fe8fb19SBen Gras 				return -1;
286*2fe8fb19SBen Gras 			mz->mz_col_offset = ps.ps_s_imm;
287*2fe8fb19SBen Gras 		} else
288*2fe8fb19SBen Gras 			mz->mz_row_offset = 0;
289*2fe8fb19SBen Gras 		ret = get_tok(ms, &ps);
290*2fe8fb19SBen Gras 	}
291*2fe8fb19SBen Gras 	if (ret != EOF)
292*2fe8fb19SBen Gras 		return -1;
293*2fe8fb19SBen Gras 
294*2fe8fb19SBen Gras 	/* sanity check */
295*2fe8fb19SBen Gras 	if (mz->mz_col_bits==32)
296*2fe8fb19SBen Gras 		colmax = 0;
297*2fe8fb19SBen Gras 	else
298*2fe8fb19SBen Gras 		colmax = 1 << mz->mz_col_bits;
299*2fe8fb19SBen Gras 	if (mz->mz_col_bits==0)
300*2fe8fb19SBen Gras 		rowmax = 0;
301*2fe8fb19SBen Gras 	else
302*2fe8fb19SBen Gras 		rowmax = 1 << (32-mz->mz_col_bits);
303*2fe8fb19SBen Gras 	if (check_rowcol(&mz->mz_col, mz->mz_col_offset, colmax))
304*2fe8fb19SBen Gras 		return -1;
305*2fe8fb19SBen Gras 	if (check_rowcol(&mz->mz_row, mz->mz_row_offset, rowmax))
306*2fe8fb19SBen Gras 		return -1;
307*2fe8fb19SBen Gras 
308*2fe8fb19SBen Gras 	return 0;
309*2fe8fb19SBen Gras }
310*2fe8fb19SBen Gras 
311*2fe8fb19SBen Gras static int
312*2fe8fb19SBen Gras /*ARGSUSED*/
_citrus_mapper_zone_mapper_init(struct _citrus_mapper_area * __restrict ma,struct _citrus_mapper * __restrict cm,const char * __restrict dir,const void * __restrict var,size_t lenvar,struct _citrus_mapper_traits * __restrict mt,size_t lenmt)313*2fe8fb19SBen Gras _citrus_mapper_zone_mapper_init(struct _citrus_mapper_area *__restrict ma,
314*2fe8fb19SBen Gras 				struct _citrus_mapper * __restrict cm,
315*2fe8fb19SBen Gras 				const char * __restrict dir,
316*2fe8fb19SBen Gras 				const void * __restrict var, size_t lenvar,
317*2fe8fb19SBen Gras 				struct _citrus_mapper_traits * __restrict mt,
318*2fe8fb19SBen Gras 				size_t lenmt)
319*2fe8fb19SBen Gras {
320*2fe8fb19SBen Gras 	struct _citrus_mapper_zone *mz;
321*2fe8fb19SBen Gras 	struct _memstream ms;
322*2fe8fb19SBen Gras 	struct _region r;
323*2fe8fb19SBen Gras 
324*2fe8fb19SBen Gras 	_DIAGASSERT(cm && dir && mt);
325*2fe8fb19SBen Gras 
326*2fe8fb19SBen Gras 	if (lenmt<sizeof(*mt))
327*2fe8fb19SBen Gras 		return EINVAL;
328*2fe8fb19SBen Gras 
329*2fe8fb19SBen Gras 	mz = malloc(sizeof(*mz));
330*2fe8fb19SBen Gras 	if (mz == NULL)
331*2fe8fb19SBen Gras 		return errno;
332*2fe8fb19SBen Gras 
333*2fe8fb19SBen Gras 	mz->mz_col.z_begin = mz->mz_col.z_end = 0;
334*2fe8fb19SBen Gras 	mz->mz_row.z_begin = mz->mz_row.z_end = 0;
335*2fe8fb19SBen Gras 	mz->mz_col_bits = 0;
336*2fe8fb19SBen Gras 	mz->mz_row_offset = 0;
337*2fe8fb19SBen Gras 	mz->mz_col_offset = 0;
338*2fe8fb19SBen Gras 
339*2fe8fb19SBen Gras 	_region_init(&r, (void *)var, lenvar);
340*2fe8fb19SBen Gras 	_memstream_bind(&ms, &r);
341*2fe8fb19SBen Gras 	if (parse_var(mz, &ms)) {
342*2fe8fb19SBen Gras 		free(mz);
343*2fe8fb19SBen Gras 		return EINVAL;
344*2fe8fb19SBen Gras 	}
345*2fe8fb19SBen Gras 	cm->cm_closure = mz;
346*2fe8fb19SBen Gras 	mt->mt_src_max = mt->mt_dst_max = 1;	/* 1:1 converter */
347*2fe8fb19SBen Gras 	mt->mt_state_size = 0;			/* stateless */
348*2fe8fb19SBen Gras 
349*2fe8fb19SBen Gras 	return 0;
350*2fe8fb19SBen Gras }
351*2fe8fb19SBen Gras 
352*2fe8fb19SBen Gras static void
353*2fe8fb19SBen Gras /*ARGSUSED*/
_citrus_mapper_zone_mapper_uninit(struct _citrus_mapper * cm)354*2fe8fb19SBen Gras _citrus_mapper_zone_mapper_uninit(struct _citrus_mapper *cm)
355*2fe8fb19SBen Gras {
356*2fe8fb19SBen Gras }
357*2fe8fb19SBen Gras 
358*2fe8fb19SBen Gras static int
359*2fe8fb19SBen Gras /*ARGSUSED*/
_citrus_mapper_zone_mapper_convert(struct _citrus_mapper * __restrict cm,_citrus_index_t * __restrict dst,_citrus_index_t src,void * __restrict ps)360*2fe8fb19SBen Gras _citrus_mapper_zone_mapper_convert(struct _citrus_mapper * __restrict cm,
361*2fe8fb19SBen Gras 				   _citrus_index_t * __restrict dst,
362*2fe8fb19SBen Gras 				   _citrus_index_t src, void * __restrict ps)
363*2fe8fb19SBen Gras {
364*2fe8fb19SBen Gras 	u_int32_t row, col;
365*2fe8fb19SBen Gras 	struct _citrus_mapper_zone *mz = cm->cm_closure;
366*2fe8fb19SBen Gras 
367*2fe8fb19SBen Gras 	if (mz->mz_col_bits == 32) {
368*2fe8fb19SBen Gras 		col = src;
369*2fe8fb19SBen Gras 		row = 0;
370*2fe8fb19SBen Gras 		if (col < mz->mz_col.z_begin || col > mz->mz_col.z_end)
371*2fe8fb19SBen Gras 			return _CITRUS_MAPPER_CONVERT_NONIDENTICAL;
372*2fe8fb19SBen Gras 		if (mz->mz_col_offset>0)
373*2fe8fb19SBen Gras 			col += (u_int32_t)mz->mz_col_offset;
374*2fe8fb19SBen Gras 		else
375*2fe8fb19SBen Gras 			col -= (u_int32_t)-mz->mz_col_offset;
376*2fe8fb19SBen Gras 		*dst = col;
377*2fe8fb19SBen Gras 	} else {
378*2fe8fb19SBen Gras 		col = src & (((u_int32_t)1<<mz->mz_col_bits)-1);
379*2fe8fb19SBen Gras 		row = src >> mz->mz_col_bits;
380*2fe8fb19SBen Gras 		if (row < mz->mz_row.z_begin || row > mz->mz_row.z_end ||
381*2fe8fb19SBen Gras 		    col < mz->mz_col.z_begin || col > mz->mz_col.z_end)
382*2fe8fb19SBen Gras 			return _CITRUS_MAPPER_CONVERT_NONIDENTICAL;
383*2fe8fb19SBen Gras 		if (mz->mz_col_offset>0)
384*2fe8fb19SBen Gras 			col += (u_int32_t)mz->mz_col_offset;
385*2fe8fb19SBen Gras 		else
386*2fe8fb19SBen Gras 			col -= (u_int32_t)-mz->mz_col_offset;
387*2fe8fb19SBen Gras 		if (mz->mz_row_offset>0)
388*2fe8fb19SBen Gras 			row += (u_int32_t)mz->mz_row_offset;
389*2fe8fb19SBen Gras 		else
390*2fe8fb19SBen Gras 			row -= (u_int32_t)-mz->mz_row_offset;
391*2fe8fb19SBen Gras 		*dst = col | (row << mz->mz_col_bits);
392*2fe8fb19SBen Gras 	}
393*2fe8fb19SBen Gras 	return _CITRUS_MAPPER_CONVERT_SUCCESS;
394*2fe8fb19SBen Gras }
395*2fe8fb19SBen Gras 
396*2fe8fb19SBen Gras static void
397*2fe8fb19SBen Gras /*ARGSUSED*/
_citrus_mapper_zone_mapper_init_state(struct _citrus_mapper * __restrict cm,void * __restrict ps)398*2fe8fb19SBen Gras _citrus_mapper_zone_mapper_init_state(struct _citrus_mapper * __restrict cm,
399*2fe8fb19SBen Gras 				      void * __restrict ps)
400*2fe8fb19SBen Gras {
401*2fe8fb19SBen Gras }
402