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