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