1 /* @(#)sector.c 1.18 10/12/19 Copyright 2001-2010 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)sector.c 1.18 10/12/19 Copyright 2001-2010 J. Schilling";
6 #endif
7 /*
8 * Functions needed to use libedc_ecc from cdrecord
9 *
10 * Copyright (c) 2001-2010 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include <schily/mconfig.h>
27 #include <schily/stdio.h>
28 #include <schily/standard.h>
29 #include <schily/utypes.h>
30 #include <schily/time.h>
31 #include <schily/schily.h>
32 #include <schily/nlsdefs.h>
33
34 #include "cdrecord.h"
35 #include "movesect.h"
36
37 #ifdef HAVE_LIB_EDC_ECC
38
39
40 #define LAYER2
41 #define EDC_LAYER2
42 #define ENCODER
43 #define EDC_ENCODER
44 #include <ecc.h>
45
46 #ifdef DO8
47 #define HAVE_NEW_LIB_EDC
48 #endif
49
50 EXPORT int encspeed __PR((BOOL be_verbose));
51 EXPORT void encsectors __PR((track_t *trackp, Uchar *bp, int address, int nsecs));
52 EXPORT void scrsectors __PR((track_t *trackp, Uchar *bp, int address, int nsecs));
53 EXPORT void encodesector __PR((Uchar *sp, int sectype, int address));
54 EXPORT void fillsector __PR((Uchar *sp, int sectype, int address));
55
56 /*
57 * Sector types known by lib libedc_ecc:
58 */
59 #ifdef __comment__
60 /* MMC */
61 #define MODE_0 0 /* -> XX 12+4+2336 (12+4uuu von libedc) */
62 #define MODE_1 1 /* -> 8 12+4+2048+288 (124+4uuu+288 von libedc)*/
63 #define MODE_2 2 /* -> 9 12+4+2336 (12+4uuu von libedc) */
64 #define MODE_2_FORM_1 3 /* -> 10/11 12+4+8+2048+280 (12+4hhhuuu+280 von libedc)*/
65 #define MODE_2_FORM_2 4 /* -> 12 (eher 13!) 12+4+8+2324+4 (12+4hhhuuu+4 von libedc)*/
66 #define AUDIO 5
67 #define UNKNOWN 6
68 #endif
69
70 /*
71 * known sector types
72 */
73 #ifndef EDC_MODE_0
74 #define EDC_MODE_0 MODE_0
75 #endif
76 #ifndef EDC_MODE_1
77 #define EDC_MODE_1 MODE_1
78 #endif
79 #ifndef EDC_MODE_2
80 #define EDC_MODE_2 MODE_2
81 #endif
82 #ifndef EDC_MODE_2_FORM_1
83 #define EDC_MODE_2_FORM_1 MODE_2_FORM_1
84 #endif
85 #ifndef EDC_MODE_2_FORM_2
86 #define EDC_MODE_2_FORM_2 MODE_2_FORM_2
87 #endif
88 #ifndef EDC_AUDIO
89 #define EDC_AUDIO AUDIO
90 #endif
91 #ifndef EDC_UNKNOWN
92 #define EDC_UNKNOWN UNKNOWN
93 #endif
94
95 /*
96 * Compute max sector encoding speed
97 */
98 EXPORT int
encspeed(be_verbose)99 encspeed(be_verbose)
100 BOOL be_verbose;
101 {
102 track_t t[1];
103 Uchar sect[2352];
104 int i;
105 struct timeval tv;
106 struct timeval tv2;
107
108 t[0].sectype = ST_MODE_1;
109
110 /*
111 * Encoding speed is content dependant.
112 * Set up a known non-null pattern in the sector before; to make
113 * the result of this test independant of the current stack content.
114 */
115 for (i = 0; i < 2352; ) {
116 sect[i++] = 'J';
117 sect[i++] = 'S';
118 }
119 gettimeofday(&tv, (struct timezone *)0);
120 for (i = 0; i < 75000; i++) { /* Goes up to 1000x */
121 encsectors(t, sect, 12345, 1);
122 gettimeofday(&tv2, (struct timezone *)0);
123 if (tv2.tv_sec >= (tv.tv_sec+1) &&
124 tv2.tv_usec >= tv.tv_usec)
125 break;
126 }
127 if (be_verbose) {
128 printf(_("Encoding speed : %dx (%d sectors/s) for libedc from %s\n"),
129 (i+74)/75, i,
130 _("Heiko Eissfeldt"));
131 }
132 return ((i+74)/75);
133 }
134
135 /*
136 * Encode sectors according to trackp->sectype
137 */
138 EXPORT void
encsectors(trackp,bp,address,nsecs)139 encsectors(trackp, bp, address, nsecs)
140 track_t *trackp;
141 Uchar *bp;
142 int address;
143 int nsecs;
144 {
145 int sectype = trackp->sectype;
146
147 if ((sectype & ST_MODE_MASK) == ST_MODE_AUDIO)
148 return;
149
150 while (--nsecs >= 0) {
151 encodesector(bp, sectype, address);
152 address++;
153 bp += trackp->secsize;
154 }
155 }
156
157
158 #ifdef CLONE_WRITE
159
160 #define IS_SECHDR(p) ((p)[0] == 0 && \
161 (p)[1] == 0xFF && (p)[2] == 0xFF && \
162 (p)[3] == 0xFF && (p)[4] == 0xFF && \
163 (p)[5] == 0xFF && (p)[6] == 0xFF && \
164 (p)[7] == 0xFF && (p)[8] == 0xFF && \
165 (p)[9] == 0xFF && (p)[10] == 0xFF && \
166 (p)[11] == 0)
167 /*
168 * Scramble data sectors without coding (needed for clone writing)
169 */
170 EXPORT void
scrsectors(trackp,bp,address,nsecs)171 scrsectors(trackp, bp, address, nsecs)
172 track_t *trackp;
173 Uchar *bp;
174 int address;
175 int nsecs;
176 {
177 /*
178 * In Clone write mode, we cannot expect that the sector type
179 * of a "track" which really is a file holding the whole disk
180 * is flagged with something that makes sense.
181 *
182 * For this reason, we check each sector if it's a data sector
183 * and needs scrambling.
184 */
185 while (--nsecs >= 0) {
186 if (IS_SECHDR(bp))
187 scramble_L2(bp);
188 bp += trackp->secsize;
189 }
190 }
191 #else
192 EXPORT void
scrsectors(trackp,bp,address,nsecs)193 scrsectors(trackp, bp, address, nsecs)
194 track_t *trackp;
195 Uchar *bp;
196 int address;
197 int nsecs;
198 {
199 comerrno(EX_BAD, _("Cannot write in clone RAW mode.\n"));
200 }
201 #endif
202
203 /*
204 * Encode one sector according to trackp->sectype
205 */
206 EXPORT void
encodesector(sp,sectype,address)207 encodesector(sp, sectype, address)
208 Uchar *sp;
209 int sectype;
210 int address;
211 {
212 if (address < -150)
213 address += 450150;
214 else
215 address += 150;
216 #define _address address
217
218
219 switch (sectype & ST_MODE_MASK) {
220
221 case ST_MODE_0:
222 do_encode_L2(sp, EDC_MODE_0, _address);
223 break;
224
225 case ST_MODE_1:
226 do_encode_L2(sp, EDC_MODE_1, _address);
227 break;
228
229 case ST_MODE_2:
230 do_encode_L2(sp, EDC_MODE_2, _address);
231 break;
232
233 case ST_MODE_2_FORM_1:
234 sp[16+2] &= ~0x20; /* Form 1 sector */
235 sp[16+4+2] &= ~0x20; /* Form 1 sector 2nd copy */
236 /* FALLTHROUGH */
237
238 case ST_MODE_2_MIXED:
239 do_encode_L2(sp, EDC_MODE_2_FORM_1, _address);
240 break;
241
242 case ST_MODE_2_FORM_2:
243 sp[16+2] |= 0x20; /* Form 2 sector */
244 sp[16+4+2] |= 0x20; /* Form 2 sector 2nd copy */
245
246 do_encode_L2(sp, EDC_MODE_2_FORM_2, _address);
247 break;
248
249 case ST_MODE_AUDIO:
250 return;
251 default:
252 fill2352(sp, '\0');
253 return;
254 }
255 if ((sectype & ST_NOSCRAMBLE) == 0) {
256 scramble_L2(sp);
257 #ifndef EDC_SCRAMBLE_NOSWAP
258 swabbytes(sp, 2352);
259 #endif
260 }
261 }
262
263 /*
264 * Create one zero filles encoded sector (according to trackp->sectype)
265 */
266 EXPORT void
fillsector(sp,sectype,address)267 fillsector(sp, sectype, address)
268 Uchar *sp;
269 int sectype;
270 int address;
271 {
272 fill2352(sp, '\0');
273 encodesector(sp, sectype, address);
274 }
275
276 #endif /* HAVE_LIB_EDC_ECC */
277