1/* $Id: alenlist.h,v 1.1.1.1 2008/10/15 03:29:03 james26_jang Exp $
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License.  See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
8 */
9#ifndef _ASM_IA64_SN_ALENLIST_H
10#define _ASM_IA64_SN_ALENLIST_H
11
12#include <linux/types.h>
13
14/* Definition of Address/Length List */
15
16/*
17 * An Address/Length List is used when setting up for an I/O DMA operation.
18 * A driver creates an Address/Length List that describes to the the DMA
19 * interface where in memory the DMA should go.  The bus interface sets up
20 * mapping registers, if required, and returns a suitable list of "physical
21 * addresses" or "I/O address" to the driver.  The driver then uses these
22 * to set up an appropriate scatter/gather operation(s).
23 */
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29/*
30 * An Address/Length List Address.  It'll get cast to the appropriate type,
31 * and must be big enough to hold the largest possible address in any
32 * supported address space.
33 */
34typedef u64 alenaddr_t;
35typedef u64 uvaddr_t;
36
37typedef struct alenlist_s *alenlist_t;
38
39/*
40 * For tracking progress as we walk down an address/length list.
41 */
42typedef struct alenlist_cursor_s *alenlist_cursor_t;
43
44/*
45 * alenlist representation that can be passed via an idl
46 */
47struct external_alenlist {
48	alenaddr_t	addr;
49	size_t		len;
50};
51typedef struct external_alenlist *external_alenlist_t;
52
53
54/* Return codes from alenlist routines.  */
55#define ALENLIST_FAILURE (-1)
56#define ALENLIST_SUCCESS 0
57
58
59/* Flags to alenlist routines */
60#define AL_NOSLEEP	0x01		/* Do not sleep, waiting for memory */
61#define AL_NOCOMPACT	0x02		/* Do not try to compact adjacent entries */
62#define AL_LEAVE_CURSOR	0x04		/* Do not update cursor */
63
64
65/* Create an Address/Length List, and clear it of all entries.  */
66extern alenlist_t alenlist_create(unsigned flags);
67
68/* Grow/shrink an Address/Length List and FIX its size. */
69extern int alenlist_grow(alenlist_t, size_t npairs);
70
71/* Clear an Address/Length List so that it now describes 0 pairs. */
72extern void alenlist_clear(alenlist_t alenlist);
73
74/*
75 * Convenience function to create an Address/Length List and then append
76 * the specified Address/Length Pair.  Exactly the same as alenlist_create
77 * followed by alenlist_append.  Can be used when a small list (e.g. 1 pair)
78 * is adequate.
79 */
80extern alenlist_t
81alenpair_init(	alenaddr_t address, 			/* init to this address */
82		size_t length);				/* init to this length */
83
84/*
85 * Peek at the head of an Address/Length List.  This does *NOT* update
86 * the internal cursor.
87 */
88extern int
89alenpair_get(	alenlist_t alenlist,		/* in: get from this List */
90		alenaddr_t *address,		/* out: address */
91		size_t *length);		/* out: length */
92
93/* Free the space consumed by an Address/Length List. */
94extern void alenlist_destroy(alenlist_t alenlist);
95
96/*
97 * Indicate that we're done using an Address/Length List.
98 * If we are the last user, destroy the List.
99 */
100extern void
101alenlist_done(alenlist_t alenlist);
102
103/* Append another Pair to a List */
104extern int alenlist_append(alenlist_t alenlist, 	/* append to this list */
105			alenaddr_t address,		/* address to append */
106			size_t length,			/* length to append */
107			unsigned flags);
108
109/*
110 * Replace a Pair in the middle of a List, and return old values.
111 * (not generally useful for drivers; used by bus providers).
112 */
113extern int
114alenlist_replace(	alenlist_t alenlist, 		/* in: replace in this list */
115			alenlist_cursor_t cursorp,	/* inout: which item to replace */
116			alenaddr_t *addrp, 		/* inout: address */
117			size_t *lengthp,		/* inout: length */
118			unsigned flags);
119
120
121/* Get the next Pair from a List */
122extern int alenlist_get(alenlist_t alenlist, 		/* in: get from this list */
123			alenlist_cursor_t cursorp,	/* inout: which item to get */
124			size_t maxlength,		/* in: at most length */
125			alenaddr_t *addr, 		/* out: address */
126			size_t *length,			/* out: length */
127			unsigned flags);
128
129
130/* Return the number of Pairs stored in this List */
131extern int alenlist_size(alenlist_t alenlist);
132
133/* Concatenate two Lists. */
134extern void alenlist_concat(	alenlist_t from, 	/* copy from this list */
135				alenlist_t to);		/* to this list */
136
137/* Create a copy of an Address/Length List */
138extern alenlist_t alenlist_clone(alenlist_t old,	/* clone this list */
139				 unsigned flags);
140
141
142/* Allocate and initialize an Address/Length List Cursor */
143extern alenlist_cursor_t alenlist_cursor_create(alenlist_t alenlist, unsigned flags);
144
145/* Free an Address/Length List Cursor */
146extern void alenlist_cursor_destroy(alenlist_cursor_t cursorp);
147
148/*
149 * Initialize an Address/Length List Cursor in order to walk thru an
150 * Address/Length List from the beginning.
151 */
152extern int alenlist_cursor_init(alenlist_t alenlist,
153				size_t offset,
154				alenlist_cursor_t cursorp);
155
156/* Clone an Address/Length List Cursor. */
157extern int alenlist_cursor_clone(alenlist_t alenlist,
158				alenlist_cursor_t cursorp_in,
159				alenlist_cursor_t cursorp_out);
160
161/*
162 * Return the number of bytes passed so far according to the specified
163 * Address/Length List Cursor.
164 */
165extern size_t alenlist_cursor_offset(alenlist_t alenlist, alenlist_cursor_t cursorp);
166
167
168
169
170/* Convert from a Kernel Virtual Address to a Physical Address/Length List */
171extern alenlist_t kvaddr_to_alenlist(	alenlist_t alenlist,
172					caddr_t kvaddr,
173					size_t length,
174					unsigned flags);
175
176/* Convert from a User Virtual Address to a Physical Address/Length List */
177extern alenlist_t uvaddr_to_alenlist(	alenlist_t alenlist,
178					uvaddr_t vaddr,
179					size_t length,
180					unsigned flags);
181
182/* Convert from a buf struct to a Physical Address/Length List */
183struct buf;
184extern alenlist_t buf_to_alenlist(	alenlist_t alenlist,
185					struct buf *buf,
186					unsigned flags);
187
188
189/*
190 * Tracking position as we walk down an Address/Length List.
191 * This structure is NOT generally for use by device drivers.
192 */
193struct alenlist_cursor_s {
194	struct alenlist_s	*al_alenlist;	/* which list */
195	size_t			al_offset;	/* total bytes passed by cursor */
196	struct alenlist_chunk_s	*al_chunk;	/* which chunk in alenlist */
197	unsigned int		al_index;	/* which pair in chunk */
198	size_t			al_bcount;	/* offset into address/length pair */
199};
200
201#ifdef __cplusplus
202}
203#endif
204
205#endif /* _ASM_IA64_SN_ALENLIST_H */
206