1#include "usb.h"
2#include "scsiglue.h"
3#include "transport.h"
4
5
6#include "smcommon.h"
7#include "smil.h"
8
9
10
11
12
13
14
15
16static BYTE ecctable[256] = {
170x00, 0x55, 0x56, 0x03, 0x59, 0x0C, 0x0F, 0x5A, 0x5A, 0x0F, 0x0C, 0x59, 0x03,
180x56, 0x55, 0x00, 0x65, 0x30, 0x33, 0x66, 0x3C, 0x69, 0x6A, 0x3F, 0x3F, 0x6A,
190x69, 0x3C, 0x66, 0x33, 0x30, 0x65, 0x66, 0x33, 0x30, 0x65, 0x3F, 0x6A, 0x69,
200x3C, 0x3C, 0x69, 0x6A, 0x3F, 0x65, 0x30, 0x33, 0x66, 0x03, 0x56, 0x55, 0x00,
210x5A, 0x0F, 0x0C, 0x59, 0x59, 0x0C, 0x0F, 0x5A, 0x00, 0x55, 0x56, 0x03, 0x69,
220x3C, 0x3F, 0x6A, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6A, 0x3F,
230x3C, 0x69, 0x0C, 0x59, 0x5A, 0x0F, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00,
240x55, 0x0F, 0x5A, 0x59, 0x0C, 0x0F, 0x5A, 0x59, 0x0C, 0x56, 0x03, 0x00, 0x55,
250x55, 0x00, 0x03, 0x56, 0x0C, 0x59, 0x5A, 0x0F, 0x6A, 0x3F, 0x3C, 0x69, 0x33,
260x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3C, 0x3F, 0x6A, 0x6A, 0x3F,
270x3C, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3C, 0x3F,
280x6A, 0x0F, 0x5A, 0x59, 0x0C, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56,
290x0C, 0x59, 0x5A, 0x0F, 0x0C, 0x59, 0x5A, 0x0F, 0x55, 0x00, 0x03, 0x56, 0x56,
300x03, 0x00, 0x55, 0x0F, 0x5A, 0x59, 0x0C, 0x69, 0x3C, 0x3F, 0x6A, 0x30, 0x65,
310x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6A, 0x3F, 0x3C, 0x69, 0x03, 0x56, 0x55,
320x00, 0x5A, 0x0F, 0x0C, 0x59, 0x59, 0x0C, 0x0F, 0x5A, 0x00, 0x55, 0x56, 0x03,
330x66, 0x33, 0x30, 0x65, 0x3F, 0x6A, 0x69, 0x3C, 0x3C, 0x69, 0x6A, 0x3F, 0x65,
340x30, 0x33, 0x66, 0x65, 0x30, 0x33, 0x66, 0x3C, 0x69, 0x6A, 0x3F, 0x3F, 0x6A,
350x69, 0x3C, 0x66, 0x33, 0x30, 0x65, 0x00, 0x55, 0x56, 0x03, 0x59, 0x0C, 0x0F,
360x5A, 0x5A, 0x0F, 0x0C, 0x59, 0x03, 0x56, 0x55, 0x00
37};
38
39static void trans_result(BYTE, BYTE, BYTE *, BYTE *);
40
41#define BIT7 0x80
42#define BIT6 0x40
43#define BIT5 0x20
44#define BIT4 0x10
45#define BIT3 0x08
46#define BIT2 0x04
47#define BIT1 0x02
48#define BIT0 0x01
49#define BIT1BIT0 0x03
50#define BIT23 0x00800000L
51#define MASK_CPS 0x3f
52#define CORRECTABLE 0x00555554L
53
54
55
56
57
58
59
60static void trans_result(BYTE reg2, BYTE reg3, BYTE *ecc1, BYTE *ecc2)
61{
62 BYTE a;
63 BYTE b;
64 BYTE i;
65
66 a = BIT7; b = BIT7;
67 *ecc1 = *ecc2 = 0;
68 for (i = 0; i < 4; ++i) {
69 if ((reg3&a) != 0)
70 *ecc1 |= b;
71 b = b>>1;
72 if ((reg2&a) != 0)
73 *ecc1 |= b;
74 b = b>>1;
75 a = a>>1;
76 }
77
78 b = BIT7;
79 for (i = 0; i < 4; ++i) {
80 if ((reg3&a) != 0)
81 *ecc2 |= b;
82 b = b>>1;
83 if ((reg2&a) != 0)
84 *ecc2 |= b;
85 b = b>>1;
86 a = a>>1;
87 }
88}
89
90
91
92
93
94
95
96
97
98void calculate_ecc(BYTE *table, BYTE *data, BYTE *ecc1, BYTE *ecc2, BYTE *ecc3)
99{
100 DWORD i;
101 BYTE a;
102 BYTE reg1;
103 BYTE reg2;
104 BYTE reg3;
105
106 reg1 = reg2 = reg3 = 0;
107 for (i = 0; i < 256; ++i) {
108 a = table[data[i]];
109 reg1 ^= (a&MASK_CPS);
110 if ((a&BIT6) != 0) {
111 reg3 ^= (BYTE)i;
112 reg2 ^= ~((BYTE)i);
113 }
114 }
115
116
117
118 trans_result(reg2, reg3, ecc1, ecc2);
119 *ecc1 = ~(*ecc1); *ecc2 = ~(*ecc2);
120 *ecc3 = ((~reg1)<<2)|BIT1BIT0;
121}
122
123
124
125
126
127
128
129
130BYTE correct_data(BYTE *data, BYTE *eccdata, BYTE ecc1, BYTE ecc2, BYTE ecc3)
131{
132 DWORD l;
133 DWORD d;
134 DWORD i;
135 BYTE d1, d2, d3;
136 BYTE a;
137 BYTE add;
138 BYTE b;
139 BYTE bit;
140
141 d1 = ecc1^eccdata[1]; d2 = ecc2^eccdata[0];
142 d3 = ecc3^eccdata[2];
143 d = ((DWORD)d1<<16)
144 +((DWORD)d2<<8)
145 +(DWORD)d3;
146
147 if (d == 0)
148 return 0;
149
150 if (((d^(d>>1))&CORRECTABLE) == CORRECTABLE) {
151 l = BIT23;
152 add = 0;
153 a = BIT7;
154
155 for (i = 0; i < 8; ++i) {
156 if ((d&l) != 0)
157 add |= a;
158 l >>= 2; a >>= 1;
159 }
160
161 bit = 0;
162 b = BIT2;
163 for (i = 0; i < 3; ++i) {
164 if ((d&l) != 0)
165 bit |= b;
166 l >>= 2; b >>= 1;
167 }
168
169 b = BIT0;
170 data[add] ^= (b<<bit);
171 return 1;
172 }
173
174 i = 0;
175 d &= 0x00ffffffL;
176
177 while (d) {
178 if (d&BIT0)
179 ++i;
180 d >>= 1;
181 }
182
183 if (i == 1) {
184 eccdata[1] = ecc1; eccdata[0] = ecc2;
185 eccdata[2] = ecc3;
186 return 2;
187 }
188 return 3;
189}
190
191int _Correct_D_SwECC(BYTE *buf, BYTE *redundant_ecc, BYTE *calculate_ecc)
192{
193 DWORD err;
194
195 err = correct_data(buf, redundant_ecc, *(calculate_ecc + 1),
196 *(calculate_ecc), *(calculate_ecc + 2));
197 if (err == 1)
198 memcpy(calculate_ecc, redundant_ecc, 3);
199
200 if (err == 0 || err == 1 || err == 2)
201 return 0;
202
203 return -1;
204}
205
206void _Calculate_D_SwECC(BYTE *buf, BYTE *ecc)
207{
208 calculate_ecc(ecctable, buf, ecc+1, ecc+0, ecc+2);
209}
210
211
212