1 /* $Id$
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-2003 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
26 extern "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  */
34 typedef u64 alenaddr_t;
35 typedef u64 uvaddr_t;
36 
37 typedef struct alenlist_s *alenlist_t;
38 
39 /*
40  * For tracking progress as we walk down an address/length list.
41  */
42 typedef struct alenlist_cursor_s *alenlist_cursor_t;
43 
44 /*
45  * alenlist representation that can be passed via an idl
46  */
47 struct external_alenlist {
48 	alenaddr_t	addr;
49 	size_t		len;
50 };
51 typedef 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.  */
66 extern alenlist_t alenlist_create(unsigned flags);
67 
68 /* Grow/shrink an Address/Length List and FIX its size. */
69 extern int alenlist_grow(alenlist_t, size_t npairs);
70 
71 /* Clear an Address/Length List so that it now describes 0 pairs. */
72 extern 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  */
80 extern alenlist_t
81 alenpair_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  */
88 extern int
89 alenpair_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. */
94 extern 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  */
100 extern void
101 alenlist_done(alenlist_t alenlist);
102 
103 /* Append another Pair to a List */
104 extern 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  */
113 extern int
114 alenlist_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 */
122 extern 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 */
131 extern int alenlist_size(alenlist_t alenlist);
132 
133 /* Concatenate two Lists. */
134 extern 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 */
138 extern alenlist_t alenlist_clone(alenlist_t old,	/* clone this list */
139 				 unsigned flags);
140 
141 
142 /* Allocate and initialize an Address/Length List Cursor */
143 extern alenlist_cursor_t alenlist_cursor_create(alenlist_t alenlist, unsigned flags);
144 
145 /* Free an Address/Length List Cursor */
146 extern 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  */
152 extern int alenlist_cursor_init(alenlist_t alenlist,
153 				size_t offset,
154 				alenlist_cursor_t cursorp);
155 
156 /* Clone an Address/Length List Cursor. */
157 extern 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  */
165 extern 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 */
171 extern 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 */
177 extern 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 */
183 struct buf;
184 extern 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  */
193 struct 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