1 /* @(#)edc.h 1.3 12/12/02 Copyright 1998-2001 Heiko Eissfeldt */ 2 3 /* 4 * This file contains protected intellectual property. 5 * 6 * Compact disc reed-solomon routines. 7 * Copyright (c) 1998-2001 by Heiko Eissfeldt, heiko@hexco.de 8 * Copyright (c) 2006-2012 by Joerg Schilling 9 */ 10 /* 11 * The contents of this file are subject to the terms of the 12 * Common Development and Distribution License, Version 1.0 only 13 * (the "License"). You may not use this file except in compliance 14 * with the License. 15 * 16 * See the file CDDL.Schily.txt in this distribution for details. 17 * A copy of the CDDL is also available via the Internet at 18 * http://www.opensource.org/licenses/cddl1.txt 19 * 20 * When distributing Covered Code, include this CDDL HEADER in each 21 * file and include the License file CDDL.Schily.txt from this distribution. 22 */ 23 24 #ifdef EDC_DECODER_HACK 25 26 #ifndef min 27 #define min(a, b) ((a) < (b) ? (a) : (b)) 28 #define max(a, b) ((a) > (b) ? (a) : (b)) 29 #endif 30 31 #define DO2(a) a\ 32 a 33 34 #define DO4(a) DO2(a)\ 35 DO2(a) 36 37 #define DO8(a) DO4(a)\ 38 DO4(a) 39 40 #if defined EDC_LAYER1 || defined EDC_LAYER2 41 #define RS_L12_BITS 8 42 #endif 43 44 /* 45 * known sector types 46 */ 47 #define EDC_MODE_0 0 48 #define EDC_MODE_1 1 49 #define EDC_MODE_2 2 50 #define EDC_MODE_2_FORM_1 3 51 #define EDC_MODE_2_FORM_2 4 52 #define EDC_AUDIO 5 53 #define EDC_UNKNOWN 6 54 55 56 typedef struct bcdmsf { 57 unsigned char bcdmsf_min; /* the minute in bcd format */ 58 unsigned char bcdmsf_sec; /* the second in bcd format */ 59 unsigned char bcdmsf_frame; /* the frame in bcd format */ 60 } bcdmsf_t; 61 62 63 #ifdef EDC_LAYER2 64 /* 65 * data sector definitions for RSPC 66 * user data bytes per frame 67 */ 68 #define L2_RAW (1024*2) 69 70 #define L12_MODUL 255 71 #define L12_P_ERRORS 1 72 #define L12_Q_ERRORS 1 73 #define L12_P_LENGTH 43 74 #define L12_Q_LENGTH 26 75 #define L12_P_SKIPPED (L12_MODUL-L12_Q_LENGTH) 76 #define L12_Q_SKIPPED (L12_MODUL-L12_P_LENGTH-2*L12_Q_ERRORS) 77 78 /* 79 * parity bytes for 16 bit units 80 */ 81 #define L2_Q (L12_Q_LENGTH*2*L12_Q_ERRORS*2) 82 #define L2_P (L12_P_LENGTH*2*L12_P_ERRORS*2) 83 84 /* 85 * sector access macros 86 * 87 * col = column address of P layer 88 * dia = diagonal address of Q layer 89 * p = position in column or diagonal 90 * 91 * SECxyz calculate the position in the sector from offset 12, where 92 * x is B for byte access and W for word access 93 * y is P for the P parity layer and Q for the Q parity layer 94 * z is L for the least significant and M for the most significant byte 95 */ 96 /* word macros */ 97 #define SECWP(col, p) (L12_P_LENGTH*(p)+(col)) 98 /* byte macros */ 99 #define SECBPL(col, p) (SECWP(col, p) << 1) 100 #define SECBPM(col, p) (SECBPL(col, p)+1) 101 102 #if defined USE_ARRAY 103 /* word macros */ 104 #define SECWQ(dia, p) (qacc[dia][p] >> 1) 105 #define SECWQLO(dia, p) (qacc[dia][p] >> 1) 106 #define SECWQHI(dia, p) (qacc[dia][p] >> 1) 107 /* byte macros */ 108 #define SECBQLLO(dia, p) (qacc[dia][p]) 109 #define SECBQLHI(dia, p) (qacc[dia][p]) 110 #define SECBQL(dia, p) (qacc[dia][p]) 111 #define SECBQMLO(dia, p) (SECBQLLO(dia, p)+1) 112 #define SECBQMHI(dia, p) (SECBQLHI(dia, p)+1) 113 #define SECBQM(dia, p) (SECBQL(dia, p)+1) 114 #else 115 #define SECWQ(dia, p) (SECWQC(dia, p)) 116 #define SECWQLO(dia, p) (SECWQLOC(dia, p)) 117 #define SECWQHI(dia, p) (SECWQHIC(dia, p)) 118 #define SECBQLLO(dia, p) (SECBQLLOC(dia, p)) 119 #define SECBQLHI(dia, p) (SECBQLHIC(dia, p)) 120 #define SECBQL(dia, p) (SECBQLC(dia, p)) 121 #define SECBQMLO(dia, p) (SECBQMLOC(dia, p)) 122 #define SECBQMHI(dia, p) (SECBQMHIC(dia, p)) 123 #define SECBQM(dia, p) (SECBQMC(dia, p)) 124 #endif 125 /* word macros */ 126 #define SECWQLOC(dia, p) ((unsigned short)(L12_P_LENGTH*((p)+(dia))+(p)) % (unsigned short) (L12_P_LENGTH*L12_Q_LENGTH)) 127 #define SECWQHIC(dia, p) (L12_Q_LENGTH*(p)+(dia)) 128 #define SECWQC(dia, p) ((p) < L12_P_LENGTH ? SECWQLOC(dia, p) : SECWQHIC(dia, p)) 129 /* byte macros */ 130 #define SECBQLLOC(dia, p) (SECWQLOC(dia, p) << 1) 131 #define SECBQLHIC(dia, p) (SECWQHIC(dia, p) << 1) 132 #define SECBQLC(dia, p) ((p) < L12_P_LENGTH ? SECBQLLOC(dia, p) : SECBQLHIC(dia, p)) 133 #define SECBQMLOC(dia, p) (SECBQLLOC(dia, p)+1) 134 #define SECBQMHIC(dia, p) (SECBQLHIC(dia, p)+1) 135 #define SECBQMC(dia, p) (SECBQLC(dia, p)+1) 136 137 138 /* 139 * conversion macros 140 * 141 * Calculate layer coordinates from a (12-byte based) sector offset in words 142 * 143 * POSP calculates the position in the column in the P parity layer 144 * COL calculates the column from the offset 145 * 146 * POSQ calculates the position in the diagonal in the Q parity layer 147 * DIA calculates the diagonal 148 */ 149 /* p parity macros */ 150 #define POSP(off) (unsigned)((unsigned short)(off) / (unsigned short)L12_P_LENGTH) 151 #define COL(off) (unsigned)((unsigned short)(off) % (unsigned short)L12_P_LENGTH) 152 153 /* q parity macros */ 154 #define POSQLO(off) COL(off) 155 #define POSQHI(off) (unsigned)((unsigned short)(off) / (unsigned short)L12_Q_LENGTH) 156 #define POSQ(off) ((unsigned short)(off) < (unsigned short)(L12_P_LENGTH*L12_Q_LENGTH) ? POSQLO(off) : POSQHI(off)) 157 #define DIALO(off) (unsigned)((unsigned short)(POSP(off)-COL(off)+2*L12_Q_LENGTH)%(unsigned short)L12_Q_LENGTH) 158 #define DIAHI(off) (unsigned)((unsigned short)(off) % (unsigned short)L12_Q_LENGTH) 159 #define DIA(off) ((unsigned short)(off) < (unsigned short)(L12_P_LENGTH*L12_Q_LENGTH) ? DIALO(off) : DIAHI(off)) 160 161 #ifdef EDC_ENCODER 162 /* 163 * data sector layer 2 Reed-Solomon Product Code encoder 164 * 165 * encode the given data portion depending on sector type (see 166 * get/set_sector_type() functions). Use the given address for the header. 167 * The returned data is __unscrambled__ and not in F2-frame format (for that 168 * see function scramble_L2()). 169 * 170 * Input parameter: 171 * sectortype 172 * EDC_MODE_0: a 12-byte sync field, a header and 2336 zeros are returned. 173 * EDC_MODE_1: the user data portion (2048 bytes) has to be given 174 * at offset 16 in the inout array. 175 * Sync-, header-, edc-, spare-, p- and q- fields will be added. 176 * EDC_MODE_2: the user data portion (2336 bytes) has to be given 177 * at offset 16 in the inout array. 178 * Sync- and header- fields will be added. 179 * EDC_MODE_2_FORM_1: the user data portion (8 bytes subheader followed 180 * by 2048 bytes data) has to be given at offset 16 181 * in the inout array. 182 * Sync-, header-, edc-, p- and q- fields will be added. 183 * EDC_MODE_2_FORM_2: the user data portion (8 bytes subheader followed 184 * by 2324 bytes data) has to be given at offset 16 185 * in the inout array. 186 * Sync-, header- and edc- fields will be added. 187 * 188 * inout is an array of 2352 or more bytes. 189 * address is a pointer to a bcdmsf_t struct 190 * holding bcd values for minute/second/frame address parts. 191 * 192 */ 193 int do_encode_L2 __PR((unsigned char *inout, int sectortype, bcdmsf_t *address)); 194 #endif 195 196 #ifdef EDC_DECODER 197 198 #define NO_ERRORS 1 199 #define FULLY_CORRECTED 0 200 #define UNCORRECTABLE -1 201 #define WRONG_TYPE -2 202 /* 203 * data sector decoder for MODE 1 and MODE 2 FORM 1 sector types. 204 * Input parameters: 205 * inout: 206 * have_erasures: indicates error positions when > 0 207 * erasures: a value > 0 indicates an error at the corresponding 208 * position in the inout array. 209 * 210 * On output: inout has error corrected data, if correctable. 211 * return values: 212 * -1 uncorrectable 213 * 0 corrected 214 * 1 uncorrected (no correction needed) 215 */ 216 int do_decode_L2 __PR((unsigned char inout[(L2_RAW + L2_Q + L2_P)], 217 int sectortype, int have_erasures, 218 unsigned char erasures[(L2_RAW + L2_Q + L2_P)])); 219 220 /* 221 * calculate the crc checksum depending on the sector type. 222 * 223 * parameters: 224 * input: 225 * inout is the data sector as a byte array at offset 0 226 * type is the sector type (MODE_1, MODE_2_FORM_1 or MODE_2_FORM_2) 227 * 228 * return value: 1, if cyclic redundancy checksum is 0 (no errors) 229 * 0, if errors are present. 230 * 231 */ 232 int crc_check __PR((unsigned char inout[(L2_RAW + L2_Q + L2_P)], int type)); 233 234 235 236 int encode_L2_P __PR((unsigned char *inout)); 237 int encode_L2_Q __PR((unsigned char *inout)); 238 #endif 239 240 extern const unsigned short qacc[26][64]; 241 242 /* 243 * calculates checksum for data sectors 244 */ 245 unsigned int build_edc __PR((unsigned char inout[], unsigned from, unsigned upto)); 246 247 /* 248 * generates f2 frames from otherwise fully formatted sectors (generated by 249 * do_encode_L2()). 250 */ 251 int scramble_L2 __PR((unsigned char *inout)); 252 #endif 253 254 #ifdef EDC_SUBCHANNEL 255 /* 256 * r-w sub channel definitions 257 */ 258 #define RS_SUB_RW_BITS 6 259 260 #define PACKETS_PER_SUBCHANNELFRAME 4 261 #define LSUB_RAW 18 262 #define LSUB_QRAW 2 263 264 /* 265 * 6 bit entities 266 */ 267 #define LSUB_Q 2 268 #define LSUB_P 4 269 270 typedef struct del *edc_sub_delp; 271 272 /* 273 * Create an initialized instance of the subchannel delay line. 274 * 275 * Return a pointer to the initialized delay line object. 276 */ 277 edc_sub_delp create_edc_sub_del __PR((void)); 278 279 #ifdef EDC_ENCODER 280 281 /* 282 * R-W subchannel encoder 283 * input: inout has 96 bytes data, four frames with 24 bytes each. 284 * output: four frames with 2 bytes user data, 2 bytes added Q parity, 285 * 16 bytes user data, 4 bytes added P parity. 286 * 287 * This routine fills the q and p parity fields. 288 * No interleaving is done here. 289 */ 290 int do_encode_sub __PR(( 291 unsigned char inout[(LSUB_RAW + LSUB_Q + LSUB_P) * PACKETS_PER_SUBCHANNELFRAME])); 292 293 294 /* 295 * R-W subchannel interleaver 296 * 297 * Apply after parity code generation. 298 * 299 * input: inout has 96 bytes user data, four frames with 24 bytes each. 300 * output: as above but swapped and interleaved. 301 * 302 * Parameter: 303 * swap : if true, perform low level permutations (swaps) 304 * delay: if true, use low level delay line 305 * delp: pointer to a edc_sub_del struct 306 * (holding the state of the delay line) 307 * this pointer is dereferenced only, if parameter delay is true. 308 */ 309 int 310 packed_to_raw __PR((unsigned char inout[(LSUB_RAW + LSUB_Q + LSUB_P) * PACKETS_PER_SUBCHANNELFRAME], 311 int swap, int delay, edc_sub_delp delp)); 312 313 #endif 314 315 #ifdef EDC_DECODER 316 /* 317 * R-W subchannel deinterleaver 318 * 319 * Apply before correction. 320 * 321 * input: inout has 96 bytes user data, four frames with 24 bytes each. 322 * output: as above but swapped and interleaved (delayed). 323 * 324 * Parameter: 325 * swap : if true, perform permutations (swaps) 326 * delay: if true, use delay line 327 * delp: pointer to a edc_sub_delp struct 328 * (holding the state of the delay line) 329 * this pointer is dereferenced only, if parameter delay is true. 330 */ 331 int 332 raw_to_packed __PR((unsigned char inout[(LSUB_RAW + LSUB_Q + LSUB_P) * PACKETS_PER_SUBCHANNELFRAME], 333 int swap, int delay, edc_sub_delp delp)); 334 335 /* 336 * R-W subchannel decoder 337 * On input: inout: 96 bytes packed user data, four frames with each 24 bytes. 338 * have_erasures: indicates error positions when > 0 339 * erasures: a value > 0 indicates an error at the corresponding 340 * position in the inout array. 341 * 342 * On output: inout has error corrected data, if correctable. 343 * return values: 344 * -1 uncorrectable 345 * 0 corrected 346 * 1 uncorrected (not needed) 347 */ 348 int do_decode_sub __PR(( 349 unsigned char inout[(LSUB_RAW + LSUB_Q + LSUB_P) * PACKETS_PER_SUBCHANNELFRAME], 350 int have_erasures, 351 unsigned char erasures[(LSUB_RAW + LSUB_Q+LSUB_P) *PACKETS_PER_SUBCHANNELFRAME], 352 int results[PACKETS_PER_SUBCHANNELFRAME])); 353 354 int check_sub __PR((unsigned char input[])); 355 356 #endif 357 #endif 358 359 #endif /* EDC_DECODER_HACK */ 360 /* 361 * XXX Remove this if EDC_DECODER_HACK is removed 362 */ 363 int do_decode_L2 __PR((unsigned char inout[(L2_RAW + L2_Q + L2_P)], 364 int sectortype, int have_erasures, 365 unsigned char erasures[(L2_RAW + L2_Q + L2_P)])); 366 int crc_check __PR((unsigned char inout[(L2_RAW + L2_Q + L2_P)], int type)); 367