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