xref: /openbmc/linux/drivers/s390/cio/itcw.c (revision 827634ad)
1 /*
2  *  Functions for incremental construction of fcx enabled I/O control blocks.
3  *
4  *    Copyright IBM Corp. 2008
5  *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/types.h>
10 #include <linux/string.h>
11 #include <linux/errno.h>
12 #include <linux/err.h>
13 #include <linux/module.h>
14 #include <asm/fcx.h>
15 #include <asm/itcw.h>
16 
17 /**
18  * struct itcw - incremental tcw helper data type
19  *
20  * This structure serves as a handle for the incremental construction of a
21  * tcw and associated tccb, tsb, data tidaw-list plus an optional interrogate
22  * tcw and associated data. The data structures are contained inside a single
23  * contiguous buffer provided by the user.
24  *
25  * The itcw construction functions take care of overall data integrity:
26  * - reset unused fields to zero
27  * - fill in required pointers
28  * - ensure required alignment for data structures
29  * - prevent data structures to cross 4k-byte boundary where required
30  * - calculate tccb-related length fields
31  * - optionally provide ready-made interrogate tcw and associated structures
32  *
33  * Restrictions apply to the itcws created with these construction functions:
34  * - tida only supported for data address, not for tccb
35  * - only contiguous tidaw-lists (no ttic)
36  * - total number of bytes required per itcw may not exceed 4k bytes
37  * - either read or write operation (may not work with r=0 and w=0)
38  *
39  * Example:
40  * struct itcw *itcw;
41  * void *buffer;
42  * size_t size;
43  *
44  * size = itcw_calc_size(1, 2, 0);
45  * buffer = kmalloc(size, GFP_KERNEL | GFP_DMA);
46  * if (!buffer)
47  *	return -ENOMEM;
48  * itcw = itcw_init(buffer, size, ITCW_OP_READ, 1, 2, 0);
49  * if (IS_ERR(itcw))
50  *	return PTR_ER(itcw);
51  * itcw_add_dcw(itcw, 0x2, 0, NULL, 0, 72);
52  * itcw_add_tidaw(itcw, 0, 0x30000, 20);
53  * itcw_add_tidaw(itcw, 0, 0x40000, 52);
54  * itcw_finalize(itcw);
55  *
56  */
57 struct itcw {
58 	struct tcw *tcw;
59 	struct tcw *intrg_tcw;
60 	int num_tidaws;
61 	int max_tidaws;
62 	int intrg_num_tidaws;
63 	int intrg_max_tidaws;
64 };
65 
66 /**
67  * itcw_get_tcw - return pointer to tcw associated with the itcw
68  * @itcw: address of the itcw
69  *
70  * Return pointer to the tcw associated with the itcw.
71  */
72 struct tcw *itcw_get_tcw(struct itcw *itcw)
73 {
74 	return itcw->tcw;
75 }
76 EXPORT_SYMBOL(itcw_get_tcw);
77 
78 /**
79  * itcw_calc_size - return the size of an itcw with the given parameters
80  * @intrg: if non-zero, add an interrogate tcw
81  * @max_tidaws: maximum number of tidaws to be used for data addressing or zero
82  * if no tida is to be used.
83  * @intrg_max_tidaws: maximum number of tidaws to be used for data addressing
84  * by the interrogate tcw, if specified
85  *
86  * Calculate and return the number of bytes required to hold an itcw with the
87  * given parameters and assuming tccbs with maximum size.
88  *
89  * Note that the resulting size also contains bytes needed for alignment
90  * padding as well as padding to ensure that data structures don't cross a
91  * 4k-boundary where required.
92  */
93 size_t itcw_calc_size(int intrg, int max_tidaws, int intrg_max_tidaws)
94 {
95 	size_t len;
96 	int cross_count;
97 
98 	/* Main data. */
99 	len = sizeof(struct itcw);
100 	len += /* TCW */ sizeof(struct tcw) + /* TCCB */ TCCB_MAX_SIZE +
101 	       /* TSB */ sizeof(struct tsb) +
102 	       /* TIDAL */ max_tidaws * sizeof(struct tidaw);
103 	/* Interrogate data. */
104 	if (intrg) {
105 		len += /* TCW */ sizeof(struct tcw) + /* TCCB */ TCCB_MAX_SIZE +
106 		       /* TSB */ sizeof(struct tsb) +
107 		       /* TIDAL */ intrg_max_tidaws * sizeof(struct tidaw);
108 	}
109 
110 	/* Maximum required alignment padding. */
111 	len += /* Initial TCW */ 63 + /* Interrogate TCCB */ 7;
112 
113 	/* TIDAW lists may not cross a 4k boundary. To cross a
114 	 * boundary we need to add a TTIC TIDAW. We need to reserve
115 	 * one additional TIDAW for a TTIC that we may need to add due
116 	 * to the placement of the data chunk in memory, and a further
117 	 * TIDAW for each page boundary that the TIDAW list may cross
118 	 * due to it's own size.
119 	 */
120 	if (max_tidaws) {
121 		cross_count = 1 + ((max_tidaws * sizeof(struct tidaw) - 1)
122 				   >> PAGE_SHIFT);
123 		len += cross_count * sizeof(struct tidaw);
124 	}
125 	if (intrg_max_tidaws) {
126 		cross_count = 1 + ((intrg_max_tidaws * sizeof(struct tidaw) - 1)
127 				   >> PAGE_SHIFT);
128 		len += cross_count * sizeof(struct tidaw);
129 	}
130 	return len;
131 }
132 EXPORT_SYMBOL(itcw_calc_size);
133 
134 #define CROSS4K(x, l)	(((x) & ~4095) != ((x + l) & ~4095))
135 
136 static inline void *fit_chunk(addr_t *start, addr_t end, size_t len,
137 			      int align, int check_4k)
138 {
139 	addr_t addr;
140 
141 	addr = ALIGN(*start, align);
142 	if (check_4k && CROSS4K(addr, len)) {
143 		addr = ALIGN(addr, 4096);
144 		addr = ALIGN(addr, align);
145 	}
146 	if (addr + len > end)
147 		return ERR_PTR(-ENOSPC);
148 	*start = addr + len;
149 	return (void *) addr;
150 }
151 
152 /**
153  * itcw_init - initialize incremental tcw data structure
154  * @buffer: address of buffer to use for data structures
155  * @size: number of bytes in buffer
156  * @op: %ITCW_OP_READ for a read operation tcw, %ITCW_OP_WRITE for a write
157  * operation tcw
158  * @intrg: if non-zero, add and initialize an interrogate tcw
159  * @max_tidaws: maximum number of tidaws to be used for data addressing or zero
160  * if no tida is to be used.
161  * @intrg_max_tidaws: maximum number of tidaws to be used for data addressing
162  * by the interrogate tcw, if specified
163  *
164  * Prepare the specified buffer to be used as an incremental tcw, i.e. a
165  * helper data structure that can be used to construct a valid tcw by
166  * successive calls to other helper functions. Note: the buffer needs to be
167  * located below the 2G address limit. The resulting tcw has the following
168  * restrictions:
169  *  - no tccb tidal
170  *  - input/output tidal is contiguous (no ttic)
171  *  - total data should not exceed 4k
172  *  - tcw specifies either read or write operation
173  *
174  * On success, return pointer to the resulting incremental tcw data structure,
175  * ERR_PTR otherwise.
176  */
177 struct itcw *itcw_init(void *buffer, size_t size, int op, int intrg,
178 		       int max_tidaws, int intrg_max_tidaws)
179 {
180 	struct itcw *itcw;
181 	void *chunk;
182 	addr_t start;
183 	addr_t end;
184 	int cross_count;
185 
186 	/* Check for 2G limit. */
187 	start = (addr_t) buffer;
188 	end = start + size;
189 	if (end > (1 << 31))
190 		return ERR_PTR(-EINVAL);
191 	memset(buffer, 0, size);
192 	/* ITCW. */
193 	chunk = fit_chunk(&start, end, sizeof(struct itcw), 1, 0);
194 	if (IS_ERR(chunk))
195 		return chunk;
196 	itcw = chunk;
197 	/* allow for TTIC tidaws that may be needed to cross a page boundary */
198 	cross_count = 0;
199 	if (max_tidaws)
200 		cross_count = 1 + ((max_tidaws * sizeof(struct tidaw) - 1)
201 				   >> PAGE_SHIFT);
202 	itcw->max_tidaws = max_tidaws + cross_count;
203 	cross_count = 0;
204 	if (intrg_max_tidaws)
205 		cross_count = 1 + ((intrg_max_tidaws * sizeof(struct tidaw) - 1)
206 				   >> PAGE_SHIFT);
207 	itcw->intrg_max_tidaws = intrg_max_tidaws + cross_count;
208 	/* Main TCW. */
209 	chunk = fit_chunk(&start, end, sizeof(struct tcw), 64, 0);
210 	if (IS_ERR(chunk))
211 		return chunk;
212 	itcw->tcw = chunk;
213 	tcw_init(itcw->tcw, (op == ITCW_OP_READ) ? 1 : 0,
214 		 (op == ITCW_OP_WRITE) ? 1 : 0);
215 	/* Interrogate TCW. */
216 	if (intrg) {
217 		chunk = fit_chunk(&start, end, sizeof(struct tcw), 64, 0);
218 		if (IS_ERR(chunk))
219 			return chunk;
220 		itcw->intrg_tcw = chunk;
221 		tcw_init(itcw->intrg_tcw, 1, 0);
222 		tcw_set_intrg(itcw->tcw, itcw->intrg_tcw);
223 	}
224 	/* Data TIDAL. */
225 	if (max_tidaws > 0) {
226 		chunk = fit_chunk(&start, end, sizeof(struct tidaw) *
227 				  itcw->max_tidaws, 16, 0);
228 		if (IS_ERR(chunk))
229 			return chunk;
230 		tcw_set_data(itcw->tcw, chunk, 1);
231 	}
232 	/* Interrogate data TIDAL. */
233 	if (intrg && (intrg_max_tidaws > 0)) {
234 		chunk = fit_chunk(&start, end, sizeof(struct tidaw) *
235 				  itcw->intrg_max_tidaws, 16, 0);
236 		if (IS_ERR(chunk))
237 			return chunk;
238 		tcw_set_data(itcw->intrg_tcw, chunk, 1);
239 	}
240 	/* TSB. */
241 	chunk = fit_chunk(&start, end, sizeof(struct tsb), 8, 0);
242 	if (IS_ERR(chunk))
243 		return chunk;
244 	tsb_init(chunk);
245 	tcw_set_tsb(itcw->tcw, chunk);
246 	/* Interrogate TSB. */
247 	if (intrg) {
248 		chunk = fit_chunk(&start, end, sizeof(struct tsb), 8, 0);
249 		if (IS_ERR(chunk))
250 			return chunk;
251 		tsb_init(chunk);
252 		tcw_set_tsb(itcw->intrg_tcw, chunk);
253 	}
254 	/* TCCB. */
255 	chunk = fit_chunk(&start, end, TCCB_MAX_SIZE, 8, 0);
256 	if (IS_ERR(chunk))
257 		return chunk;
258 	tccb_init(chunk, TCCB_MAX_SIZE, TCCB_SAC_DEFAULT);
259 	tcw_set_tccb(itcw->tcw, chunk);
260 	/* Interrogate TCCB. */
261 	if (intrg) {
262 		chunk = fit_chunk(&start, end, TCCB_MAX_SIZE, 8, 0);
263 		if (IS_ERR(chunk))
264 			return chunk;
265 		tccb_init(chunk, TCCB_MAX_SIZE, TCCB_SAC_INTRG);
266 		tcw_set_tccb(itcw->intrg_tcw, chunk);
267 		tccb_add_dcw(chunk, TCCB_MAX_SIZE, DCW_CMD_INTRG, 0, NULL,
268 			     sizeof(struct dcw_intrg_data), 0);
269 		tcw_finalize(itcw->intrg_tcw, 0);
270 	}
271 	return itcw;
272 }
273 EXPORT_SYMBOL(itcw_init);
274 
275 /**
276  * itcw_add_dcw - add a dcw to the itcw
277  * @itcw: address of the itcw
278  * @cmd: the dcw command
279  * @flags: flags for the dcw
280  * @cd: address of control data for this dcw or NULL if none is required
281  * @cd_count: number of control data bytes for this dcw
282  * @count: number of data bytes for this dcw
283  *
284  * Add a new dcw to the specified itcw by writing the dcw information specified
285  * by @cmd, @flags, @cd, @cd_count and @count to the tca of the tccb. Return
286  * a pointer to the newly added dcw on success or -%ENOSPC if the new dcw
287  * would exceed the available space.
288  *
289  * Note: the tcal field of the tccb header will be updated to reflect added
290  * content.
291  */
292 struct dcw *itcw_add_dcw(struct itcw *itcw, u8 cmd, u8 flags, void *cd,
293 			 u8 cd_count, u32 count)
294 {
295 	return tccb_add_dcw(tcw_get_tccb(itcw->tcw), TCCB_MAX_SIZE, cmd,
296 			    flags, cd, cd_count, count);
297 }
298 EXPORT_SYMBOL(itcw_add_dcw);
299 
300 /**
301  * itcw_add_tidaw - add a tidaw to the itcw
302  * @itcw: address of the itcw
303  * @flags: flags for the new tidaw
304  * @addr: address value for the new tidaw
305  * @count: count value for the new tidaw
306  *
307  * Add a new tidaw to the input/output data tidaw-list of the specified itcw
308  * (depending on the value of the r-flag and w-flag). Return a pointer to
309  * the new tidaw on success or -%ENOSPC if the new tidaw would exceed the
310  * available space.
311  *
312  * Note: TTIC tidaws are automatically added when needed, so explicitly calling
313  * this interface with the TTIC flag is not supported. The last-tidaw flag
314  * for the last tidaw in the list will be set by itcw_finalize.
315  */
316 struct tidaw *itcw_add_tidaw(struct itcw *itcw, u8 flags, void *addr, u32 count)
317 {
318 	struct tidaw *following;
319 
320 	if (itcw->num_tidaws >= itcw->max_tidaws)
321 		return ERR_PTR(-ENOSPC);
322 	/*
323 	 * Is the tidaw, which follows the one we are about to fill, on the next
324 	 * page? Then we have to insert a TTIC tidaw first, that points to the
325 	 * tidaw on the new page.
326 	 */
327 	following = ((struct tidaw *) tcw_get_data(itcw->tcw))
328 		+ itcw->num_tidaws + 1;
329 	if (itcw->num_tidaws && !((unsigned long) following & ~PAGE_MASK)) {
330 		tcw_add_tidaw(itcw->tcw, itcw->num_tidaws++,
331 			      TIDAW_FLAGS_TTIC, following, 0);
332 		if (itcw->num_tidaws >= itcw->max_tidaws)
333 			return ERR_PTR(-ENOSPC);
334 	}
335 	return tcw_add_tidaw(itcw->tcw, itcw->num_tidaws++, flags, addr, count);
336 }
337 EXPORT_SYMBOL(itcw_add_tidaw);
338 
339 /**
340  * itcw_set_data - set data address and tida flag of the itcw
341  * @itcw: address of the itcw
342  * @addr: the data address
343  * @use_tidal: zero of the data address specifies a contiguous block of data,
344  * non-zero if it specifies a list if tidaws.
345  *
346  * Set the input/output data address of the itcw (depending on the value of the
347  * r-flag and w-flag). If @use_tidal is non-zero, the corresponding tida flag
348  * is set as well.
349  */
350 void itcw_set_data(struct itcw *itcw, void *addr, int use_tidal)
351 {
352 	tcw_set_data(itcw->tcw, addr, use_tidal);
353 }
354 EXPORT_SYMBOL(itcw_set_data);
355 
356 /**
357  * itcw_finalize - calculate length and count fields of the itcw
358  * @itcw: address of the itcw
359  *
360  * Calculate tcw input-/output-count and tccbl fields and add a tcat the tccb.
361  * In case input- or output-tida is used, the tidaw-list must be stored in
362  * continuous storage (no ttic). The tcal field in the tccb must be
363  * up-to-date.
364  */
365 void itcw_finalize(struct itcw *itcw)
366 {
367 	tcw_finalize(itcw->tcw, itcw->num_tidaws);
368 }
369 EXPORT_SYMBOL(itcw_finalize);
370