]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/s390/cio/itcw.c
Merge tag 'usb-3.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[karo-tx-linux.git] / drivers / s390 / cio / itcw.c
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);