• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <linux/slab.h>
2 #include "usb.h"
3 #include "scsiglue.h"
4 #include "transport.h"
5 
6 #include "smcommon.h"
7 #include "smil.h"
8 
9 void   _Set_D_SsfdcRdCmd(BYTE);
10 void   _Set_D_SsfdcRdAddr(BYTE);
11 void   _Set_D_SsfdcRdChip(void);
12 void   _Set_D_SsfdcRdStandby(void);
13 void   _Start_D_SsfdcRdHwECC(void);
14 void   _Stop_D_SsfdcRdHwECC(void);
15 void   _Load_D_SsfdcRdHwECC(BYTE);
16 void   _Set_D_SsfdcWrCmd(BYTE);
17 void   _Set_D_SsfdcWrAddr(BYTE);
18 void   _Set_D_SsfdcWrBlock(void);
19 void   _Set_D_SsfdcWrStandby(void);
20 void   _Start_D_SsfdcWrHwECC(void);
21 void   _Load_D_SsfdcWrHwECC(BYTE);
22 int    _Check_D_SsfdcBusy(WORD);
23 int    _Check_D_SsfdcStatus(void);
24 void   _Reset_D_SsfdcErr(void);
25 void   _Read_D_SsfdcBuf(BYTE *);
26 void   _Write_D_SsfdcBuf(BYTE *);
27 void   _Read_D_SsfdcByte(BYTE *);
28 void   _ReadRedt_D_SsfdcBuf(BYTE *);
29 void   _WriteRedt_D_SsfdcBuf(BYTE *);
30 BYTE   _Check_D_DevCode(BYTE);
31 
32 void   _Set_D_ECCdata(BYTE, BYTE *);
33 void   _Calc_D_ECCdata(BYTE *);
34 
35 
36 struct SSFDCTYPE                Ssfdc;
37 struct ADDRESS                  Media;
38 struct CIS_AREA                 CisArea;
39 
40 static BYTE                            EccBuf[6];
41 extern PBYTE                    SMHostAddr;
42 extern DWORD                    ErrXDCode;
43 
44 extern WORD  ReadBlock;
45 extern WORD  WriteBlock;
46 
47 
48 
49 #define EVEN                    0             /* Even Page for 256byte/page */
50 #define ODD                     1             /* Odd Page for 256byte/page */
51 
52 
53 /* SmartMedia Redundant buffer data Control Subroutine
54  *----- Check_D_DataBlank() --------------------------------------------
55  */
Check_D_DataBlank(BYTE * redundant)56 int Check_D_DataBlank(BYTE *redundant)
57 {
58 	char i;
59 
60 	for (i = 0; i < REDTSIZE; i++)
61 		if (*redundant++ != 0xFF)
62 			return  ERROR;
63 
64 	return SMSUCCESS;
65 }
66 
67 /* ----- Check_D_FailBlock() -------------------------------------------- */
Check_D_FailBlock(BYTE * redundant)68 int Check_D_FailBlock(BYTE *redundant)
69 {
70 	redundant += REDT_BLOCK;
71 
72 	if (*redundant == 0xFF)
73 		return SMSUCCESS;
74 	if (!*redundant)
75 		return ERROR;
76 	if (hweight8(*redundant) < 7)
77 		return ERROR;
78 
79 	return SMSUCCESS;
80 }
81 
82 /* ----- Check_D_DataStatus() ------------------------------------------- */
Check_D_DataStatus(BYTE * redundant)83 int Check_D_DataStatus(BYTE *redundant)
84 {
85 	redundant += REDT_DATA;
86 
87 	if (*redundant == 0xFF)
88 		return SMSUCCESS;
89 	if (!*redundant) {
90 		ErrXDCode = ERR_DataStatus;
91 		return ERROR;
92 	} else
93 		ErrXDCode = NO_ERROR;
94 
95 	if (hweight8(*redundant) < 5)
96 		return ERROR;
97 
98 	return SMSUCCESS;
99 }
100 
101 /* ----- Load_D_LogBlockAddr() ------------------------------------------ */
Load_D_LogBlockAddr(BYTE * redundant)102 int Load_D_LogBlockAddr(BYTE *redundant)
103 {
104 	WORD addr1, addr2;
105 
106 	addr1 = (WORD)*(redundant + REDT_ADDR1H)*0x0100 + (WORD)*(redundant + REDT_ADDR1L);
107 	addr2 = (WORD)*(redundant + REDT_ADDR2H)*0x0100 + (WORD)*(redundant + REDT_ADDR2L);
108 
109 	if (addr1 == addr2)
110 		if ((addr1 & 0xF000) == 0x1000) {
111 			Media.LogBlock = (addr1 & 0x0FFF) / 2;
112 			return SMSUCCESS;
113 		}
114 
115 	if (hweight16((WORD)(addr1^addr2)) != 0x01)
116 		return ERROR;
117 
118 	if ((addr1 & 0xF000) == 0x1000)
119 		if (!(hweight16(addr1) & 0x01)) {
120 			Media.LogBlock = (addr1 & 0x0FFF) / 2;
121 			return SMSUCCESS;
122 		}
123 
124 	if ((addr2 & 0xF000) == 0x1000)
125 		if (!(hweight16(addr2) & 0x01)) {
126 			Media.LogBlock = (addr2 & 0x0FFF) / 2;
127 			return SMSUCCESS;
128 		}
129 
130 	return ERROR;
131 }
132 
133 /* ----- Clr_D_RedundantData() ------------------------------------------ */
Clr_D_RedundantData(BYTE * redundant)134 void Clr_D_RedundantData(BYTE *redundant)
135 {
136 	char i;
137 
138 	for (i = 0; i < REDTSIZE; i++)
139 		*(redundant + i) = 0xFF;
140 }
141 
142 /* ----- Set_D_LogBlockAddr() ------------------------------------------- */
Set_D_LogBlockAddr(BYTE * redundant)143 void Set_D_LogBlockAddr(BYTE *redundant)
144 {
145 	WORD addr;
146 
147 	*(redundant + REDT_BLOCK) = 0xFF;
148 	*(redundant + REDT_DATA) = 0xFF;
149 	addr = Media.LogBlock*2 + 0x1000;
150 
151 	if ((hweight16(addr) % 2))
152 		addr++;
153 
154 	*(redundant + REDT_ADDR1H) = *(redundant + REDT_ADDR2H) = (BYTE)(addr / 0x0100);
155 	*(redundant + REDT_ADDR1L) = *(redundant + REDT_ADDR2L) = (BYTE)addr;
156 }
157 
158 /*----- Set_D_FailBlock() ---------------------------------------------- */
Set_D_FailBlock(BYTE * redundant)159 void Set_D_FailBlock(BYTE *redundant)
160 {
161 	char i;
162 	for (i = 0; i < REDTSIZE; i++)
163 		*redundant++ = (BYTE)((i == REDT_BLOCK) ? 0xF0 : 0xFF);
164 }
165 
166 /* ----- Set_D_DataStaus() ---------------------------------------------- */
Set_D_DataStaus(BYTE * redundant)167 void Set_D_DataStaus(BYTE *redundant)
168 {
169 	redundant += REDT_DATA;
170 	*redundant = 0x00;
171 }
172 
173 /* SmartMedia Function Command Subroutine
174  * 6250 CMD 6
175  */
176 /* ----- Ssfdc_D_Reset() ------------------------------------------------ */
Ssfdc_D_Reset(struct us_data * us)177 void Ssfdc_D_Reset(struct us_data *us)
178 {
179 	return;
180 }
181 
182 /* ----- Ssfdc_D_ReadCisSect() ------------------------------------------ */
Ssfdc_D_ReadCisSect(struct us_data * us,BYTE * buf,BYTE * redundant)183 int Ssfdc_D_ReadCisSect(struct us_data *us, BYTE *buf, BYTE *redundant)
184 {
185 	BYTE zone, sector;
186 	WORD block;
187 
188 	zone = Media.Zone; block = Media.PhyBlock; sector = Media.Sector;
189 	Media.Zone = 0;
190 	Media.PhyBlock = CisArea.PhyBlock;
191 	Media.Sector = CisArea.Sector;
192 
193 	if (Ssfdc_D_ReadSect(us, buf, redundant)) {
194 		Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector;
195 		return ERROR;
196 	}
197 
198 	Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector;
199 	return SMSUCCESS;
200 }
201 
202 /* 6250 CMD 1 */
203 /* ----- Ssfdc_D_ReadSect() --------------------------------------------- */
Ssfdc_D_ReadSect(struct us_data * us,BYTE * buf,BYTE * redundant)204 int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf, BYTE *redundant)
205 {
206 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
207 	int	result;
208 	WORD	addr;
209 
210 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
211 	if (result != USB_STOR_XFER_GOOD) {
212 		printk("Load SM RW Code Fail !!\n");
213 		return USB_STOR_TRANSPORT_ERROR;
214 	}
215 
216 	addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
217 	addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
218 
219 	/* Read sect data */
220 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
221 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
222 	bcb->DataTransferLength	= 0x200;
223 	bcb->Flags			= 0x80;
224 	bcb->CDB[0]			= 0xF1;
225 	bcb->CDB[1]			= 0x02;
226 	bcb->CDB[4]			= (BYTE)addr;
227 	bcb->CDB[3]			= (BYTE)(addr / 0x0100);
228 	bcb->CDB[2]			= Media.Zone / 2;
229 
230 	result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
231 	if (result != USB_STOR_XFER_GOOD)
232 		return USB_STOR_TRANSPORT_ERROR;
233 
234 	/* Read redundant */
235 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
236 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
237 	bcb->DataTransferLength	= 0x10;
238 	bcb->Flags			= 0x80;
239 	bcb->CDB[0]			= 0xF1;
240 	bcb->CDB[1]			= 0x03;
241 	bcb->CDB[4]			= (BYTE)addr;
242 	bcb->CDB[3]			= (BYTE)(addr / 0x0100);
243 	bcb->CDB[2]			= Media.Zone / 2;
244 	bcb->CDB[8]			= 0;
245 	bcb->CDB[9]			= 1;
246 
247 	result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
248 	if (result != USB_STOR_XFER_GOOD)
249 		return USB_STOR_TRANSPORT_ERROR;
250 
251 	return USB_STOR_TRANSPORT_GOOD;
252 }
253 
254 /* ----- Ssfdc_D_ReadBlock() --------------------------------------------- */
Ssfdc_D_ReadBlock(struct us_data * us,WORD count,BYTE * buf,BYTE * redundant)255 int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf, BYTE *redundant)
256 {
257 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
258 	int	result;
259 	WORD	addr;
260 
261 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
262 	if (result != USB_STOR_XFER_GOOD) {
263 		printk("Load SM RW Code Fail !!\n");
264 		return USB_STOR_TRANSPORT_ERROR;
265 	}
266 
267 	addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
268 	addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
269 
270 	/* Read sect data */
271 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
272 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
273 	bcb->DataTransferLength	= 0x200*count;
274 	bcb->Flags			= 0x80;
275 	bcb->CDB[0]			= 0xF1;
276 	bcb->CDB[1]			= 0x02;
277 	bcb->CDB[4]			= (BYTE)addr;
278 	bcb->CDB[3]			= (BYTE)(addr / 0x0100);
279 	bcb->CDB[2]			= Media.Zone / 2;
280 
281 	result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
282 	if (result != USB_STOR_XFER_GOOD)
283 		return USB_STOR_TRANSPORT_ERROR;
284 
285 	/* Read redundant */
286 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
287 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
288 	bcb->DataTransferLength	= 0x10;
289 	bcb->Flags			= 0x80;
290 	bcb->CDB[0]			= 0xF1;
291 	bcb->CDB[1]			= 0x03;
292 	bcb->CDB[4]			= (BYTE)addr;
293 	bcb->CDB[3]			= (BYTE)(addr / 0x0100);
294 	bcb->CDB[2]			= Media.Zone / 2;
295 	bcb->CDB[8]			= 0;
296 	bcb->CDB[9]			= 1;
297 
298 	result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0);
299 	if (result != USB_STOR_XFER_GOOD)
300 		return USB_STOR_TRANSPORT_ERROR;
301 
302 	return USB_STOR_TRANSPORT_GOOD;
303 }
304 
305 
306 /* ----- Ssfdc_D_CopyBlock() -------------------------------------------- */
Ssfdc_D_CopyBlock(struct us_data * us,WORD count,BYTE * buf,BYTE * redundant)307 int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf, BYTE *redundant)
308 {
309 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
310 	int	result;
311 	WORD	ReadAddr, WriteAddr;
312 
313 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
314 	if (result != USB_STOR_XFER_GOOD) {
315 		printk("Load SM RW Code Fail !!\n");
316 		return USB_STOR_TRANSPORT_ERROR;
317 	}
318 
319 	ReadAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks + ReadBlock;
320 	ReadAddr = ReadAddr*(WORD)Ssfdc.MaxSectors;
321 	WriteAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks + WriteBlock;
322 	WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors;
323 
324 	/* Write sect data */
325 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
326 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
327 	bcb->DataTransferLength	= 0x200*count;
328 	bcb->Flags			= 0x00;
329 	bcb->CDB[0]			= 0xF0;
330 	bcb->CDB[1]			= 0x08;
331 	bcb->CDB[7]			= (BYTE)WriteAddr;
332 	bcb->CDB[6]			= (BYTE)(WriteAddr / 0x0100);
333 	bcb->CDB[5]			= Media.Zone / 2;
334 	bcb->CDB[8]			= *(redundant + REDT_ADDR1H);
335 	bcb->CDB[9]			= *(redundant + REDT_ADDR1L);
336 	bcb->CDB[10]		= Media.Sector;
337 
338 	if (ReadBlock != NO_ASSIGN) {
339 		bcb->CDB[4]		= (BYTE)ReadAddr;
340 		bcb->CDB[3]		= (BYTE)(ReadAddr / 0x0100);
341 		bcb->CDB[2]		= Media.Zone / 2;
342 	} else
343 		bcb->CDB[11]	= 1;
344 
345 	result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
346 	if (result != USB_STOR_XFER_GOOD)
347 		return USB_STOR_TRANSPORT_ERROR;
348 
349 	return USB_STOR_TRANSPORT_GOOD;
350 }
351 
352 /* ----- Ssfdc_D_WriteSectForCopy() ------------------------------------- */
Ssfdc_D_WriteSectForCopy(struct us_data * us,BYTE * buf,BYTE * redundant)353 int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant)
354 {
355 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
356 	int	result;
357 	WORD	addr;
358 
359 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
360 	if (result != USB_STOR_XFER_GOOD) {
361 		printk("Load SM RW Code Fail !!\n");
362 		return USB_STOR_TRANSPORT_ERROR;
363 	}
364 
365 
366 	addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
367 	addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
368 
369 	/* Write sect data */
370 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
371 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
372 	bcb->DataTransferLength	= 0x200;
373 	bcb->Flags			= 0x00;
374 	bcb->CDB[0]			= 0xF0;
375 	bcb->CDB[1]			= 0x04;
376 	bcb->CDB[7]			= (BYTE)addr;
377 	bcb->CDB[6]			= (BYTE)(addr / 0x0100);
378 	bcb->CDB[5]			= Media.Zone / 2;
379 	bcb->CDB[8]			= *(redundant + REDT_ADDR1H);
380 	bcb->CDB[9]			= *(redundant + REDT_ADDR1L);
381 
382 	result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0);
383 	if (result != USB_STOR_XFER_GOOD)
384 		return USB_STOR_TRANSPORT_ERROR;
385 
386 	return USB_STOR_TRANSPORT_GOOD;
387 }
388 
389 /* 6250 CMD 5 */
390 /* ----- Ssfdc_D_EraseBlock() ------------------------------------------- */
Ssfdc_D_EraseBlock(struct us_data * us)391 int Ssfdc_D_EraseBlock(struct us_data *us)
392 {
393 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
394 	int	result;
395 	WORD	addr;
396 
397 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
398 	if (result != USB_STOR_XFER_GOOD) {
399 		printk("Load SM RW Code Fail !!\n");
400 		return USB_STOR_TRANSPORT_ERROR;
401 	}
402 
403 	addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
404 	addr = addr*(WORD)Ssfdc.MaxSectors;
405 
406 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
407 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
408 	bcb->DataTransferLength	= 0x200;
409 	bcb->Flags			= 0x80;
410 	bcb->CDB[0]			= 0xF2;
411 	bcb->CDB[1]			= 0x06;
412 	bcb->CDB[7]			= (BYTE)addr;
413 	bcb->CDB[6]			= (BYTE)(addr / 0x0100);
414 	bcb->CDB[5]			= Media.Zone / 2;
415 
416 	result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
417 	if (result != USB_STOR_XFER_GOOD)
418 		return USB_STOR_TRANSPORT_ERROR;
419 
420 	return USB_STOR_TRANSPORT_GOOD;
421 }
422 
423 /* 6250 CMD 2 */
424 /*----- Ssfdc_D_ReadRedtData() ----------------------------------------- */
Ssfdc_D_ReadRedtData(struct us_data * us,BYTE * redundant)425 int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant)
426 {
427 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
428 	int	result;
429 	WORD	addr;
430 	BYTE	*buf;
431 
432 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
433 	if (result != USB_STOR_XFER_GOOD) {
434 		printk("Load SM RW Code Fail !!\n");
435 		return USB_STOR_TRANSPORT_ERROR;
436 	}
437 
438 	addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
439 	addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
440 
441 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
442 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
443 	bcb->DataTransferLength	= 0x10;
444 	bcb->Flags			= 0x80;
445 	bcb->CDB[0]			= 0xF1;
446 	bcb->CDB[1]			= 0x03;
447 	bcb->CDB[4]			= (BYTE)addr;
448 	bcb->CDB[3]			= (BYTE)(addr / 0x0100);
449 	bcb->CDB[2]			= Media.Zone / 2;
450 	bcb->CDB[8]			= 0;
451 	bcb->CDB[9]			= 1;
452 
453 	buf = kmalloc(0x10, GFP_KERNEL);
454 	result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0);
455 	memcpy(redundant, buf, 0x10);
456 	kfree(buf);
457 	if (result != USB_STOR_XFER_GOOD)
458 		return USB_STOR_TRANSPORT_ERROR;
459 
460 	return USB_STOR_TRANSPORT_GOOD;
461 }
462 
463 /* 6250 CMD 4 */
464 /* ----- Ssfdc_D_WriteRedtData() ---------------------------------------- */
Ssfdc_D_WriteRedtData(struct us_data * us,BYTE * redundant)465 int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant)
466 {
467 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
468 	int	result;
469 	WORD                    addr;
470 
471 	result = ENE_LoadBinCode(us, SM_RW_PATTERN);
472 	if (result != USB_STOR_XFER_GOOD) {
473 		printk("Load SM RW Code Fail !!\n");
474 		return USB_STOR_TRANSPORT_ERROR;
475 	}
476 
477 	addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock;
478 	addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector;
479 
480 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
481 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
482 	bcb->DataTransferLength	= 0x10;
483 	bcb->Flags			= 0x80;
484 	bcb->CDB[0]			= 0xF2;
485 	bcb->CDB[1]			= 0x05;
486 	bcb->CDB[7]			= (BYTE)addr;
487 	bcb->CDB[6]			= (BYTE)(addr / 0x0100);
488 	bcb->CDB[5]			= Media.Zone / 2;
489 	bcb->CDB[8]			= *(redundant + REDT_ADDR1H);
490 	bcb->CDB[9]			= *(redundant + REDT_ADDR1L);
491 
492 	result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
493 	if (result != USB_STOR_XFER_GOOD)
494 		return USB_STOR_TRANSPORT_ERROR;
495 
496 	return USB_STOR_TRANSPORT_GOOD;
497 }
498 
499 /* ----- Ssfdc_D_CheckStatus() ------------------------------------------ */
Ssfdc_D_CheckStatus(void)500 int Ssfdc_D_CheckStatus(void)
501 {
502 	return SMSUCCESS;
503 }
504 
505 
506 
507 /* SmartMedia ID Code Check & Mode Set Subroutine
508  * ----- Set_D_SsfdcModel() ---------------------------------------------
509  */
Set_D_SsfdcModel(BYTE dcode)510 int Set_D_SsfdcModel(BYTE dcode)
511 {
512 	switch (_Check_D_DevCode(dcode)) {
513 	case SSFDC1MB:
514 		Ssfdc.Model        = SSFDC1MB;
515 		Ssfdc.Attribute    = FLASH | AD3CYC | BS16 | PS256;
516 		Ssfdc.MaxZones     = 1;
517 		Ssfdc.MaxBlocks    = 256;
518 		Ssfdc.MaxLogBlocks = 250;
519 		Ssfdc.MaxSectors   = 8;
520 		break;
521 	case SSFDC2MB:
522 		Ssfdc.Model        = SSFDC2MB;
523 		Ssfdc.Attribute    = FLASH | AD3CYC | BS16 | PS256;
524 		Ssfdc.MaxZones     = 1;
525 		Ssfdc.MaxBlocks    = 512;
526 		Ssfdc.MaxLogBlocks = 500;
527 		Ssfdc.MaxSectors   = 8;
528 		break;
529 	case SSFDC4MB:
530 		Ssfdc.Model        = SSFDC4MB;
531 		Ssfdc.Attribute    = FLASH | AD3CYC | BS16 | PS512;
532 		Ssfdc.MaxZones     = 1;
533 		Ssfdc.MaxBlocks    = 512;
534 		Ssfdc.MaxLogBlocks = 500;
535 		Ssfdc.MaxSectors   = 16;
536 		break;
537 	case SSFDC8MB:
538 		Ssfdc.Model        = SSFDC8MB;
539 		Ssfdc.Attribute    = FLASH | AD3CYC | BS16 | PS512;
540 		Ssfdc.MaxZones     = 1;
541 		Ssfdc.MaxBlocks    = 1024;
542 		Ssfdc.MaxLogBlocks = 1000;
543 		Ssfdc.MaxSectors   = 16;
544 		break;
545 	case SSFDC16MB:
546 		Ssfdc.Model        = SSFDC16MB;
547 		Ssfdc.Attribute    = FLASH | AD3CYC | BS32 | PS512;
548 		Ssfdc.MaxZones     = 1;
549 		Ssfdc.MaxBlocks    = 1024;
550 		Ssfdc.MaxLogBlocks = 1000;
551 		Ssfdc.MaxSectors   = 32;
552 		break;
553 	case SSFDC32MB:
554 		Ssfdc.Model        = SSFDC32MB;
555 		Ssfdc.Attribute    = FLASH | AD3CYC | BS32 | PS512;
556 		Ssfdc.MaxZones     = 2;
557 		Ssfdc.MaxBlocks    = 1024;
558 		Ssfdc.MaxLogBlocks = 1000;
559 		Ssfdc.MaxSectors   = 32;
560 		break;
561 	case SSFDC64MB:
562 		Ssfdc.Model        = SSFDC64MB;
563 		Ssfdc.Attribute    = FLASH | AD4CYC | BS32 | PS512;
564 		Ssfdc.MaxZones     = 4;
565 		Ssfdc.MaxBlocks    = 1024;
566 		Ssfdc.MaxLogBlocks = 1000;
567 		Ssfdc.MaxSectors   = 32;
568 		break;
569 	case SSFDC128MB:
570 		Ssfdc.Model        = SSFDC128MB;
571 		Ssfdc.Attribute    = FLASH | AD4CYC | BS32 | PS512;
572 		Ssfdc.MaxZones     = 8;
573 		Ssfdc.MaxBlocks    = 1024;
574 		Ssfdc.MaxLogBlocks = 1000;
575 		Ssfdc.MaxSectors   = 32;
576 		break;
577 	case SSFDC256MB:
578 		Ssfdc.Model        = SSFDC256MB;
579 		Ssfdc.Attribute    = FLASH | AD4CYC | BS32 | PS512;
580 		Ssfdc.MaxZones     = 16;
581 		Ssfdc.MaxBlocks    = 1024;
582 		Ssfdc.MaxLogBlocks = 1000;
583 		Ssfdc.MaxSectors   = 32;
584 		break;
585 	case SSFDC512MB:
586 		Ssfdc.Model        = SSFDC512MB;
587 		Ssfdc.Attribute    = FLASH | AD4CYC | BS32 | PS512;
588 		Ssfdc.MaxZones     = 32;
589 		Ssfdc.MaxBlocks    = 1024;
590 		Ssfdc.MaxLogBlocks = 1000;
591 		Ssfdc.MaxSectors   = 32;
592 		break;
593 	case SSFDC1GB:
594 		Ssfdc.Model        = SSFDC1GB;
595 		Ssfdc.Attribute    = FLASH | AD4CYC | BS32 | PS512;
596 		Ssfdc.MaxZones     = 64;
597 		Ssfdc.MaxBlocks    = 1024;
598 		Ssfdc.MaxLogBlocks = 1000;
599 		Ssfdc.MaxSectors   = 32;
600 		break;
601 	case SSFDC2GB:
602 		Ssfdc.Model        = SSFDC2GB;
603 		Ssfdc.Attribute    = FLASH | AD4CYC | BS32 | PS512;
604 		Ssfdc.MaxZones     = 128;
605 		Ssfdc.MaxBlocks    = 1024;
606 		Ssfdc.MaxLogBlocks = 1000;
607 		Ssfdc.MaxSectors   = 32;
608 		break;
609 	default:
610 		Ssfdc.Model = NOSSFDC;
611 		return ERROR;
612 	}
613 
614     return SMSUCCESS;
615 }
616 
617 /* ----- _Check_D_DevCode() --------------------------------------------- */
_Check_D_DevCode(BYTE dcode)618 BYTE _Check_D_DevCode(BYTE dcode)
619 {
620 	switch (dcode) {
621 	case 0x6E:
622 	case 0xE8:
623 	case 0xEC: return SSFDC1MB;   /* 8Mbit (1M) NAND */
624 	case 0x64:
625 	case 0xEA: return SSFDC2MB;   /* 16Mbit (2M) NAND */
626 	case 0x6B:
627 	case 0xE3:
628 	case 0xE5: return SSFDC4MB;   /* 32Mbit (4M) NAND */
629 	case 0xE6: return SSFDC8MB;   /* 64Mbit (8M) NAND */
630 	case 0x73: return SSFDC16MB;  /* 128Mbit (16M)NAND */
631 	case 0x75: return SSFDC32MB;  /* 256Mbit (32M)NAND */
632 	case 0x76: return SSFDC64MB;  /* 512Mbit (64M)NAND */
633 	case 0x79: return SSFDC128MB; /* 1Gbit(128M)NAND */
634 	case 0x71: return SSFDC256MB;
635 	case 0xDC: return SSFDC512MB;
636 	case 0xD3: return SSFDC1GB;
637 	case 0xD5: return SSFDC2GB;
638 	default: return NOSSFDC;
639 	}
640 }
641 
642 
643 
644 
645 /* SmartMedia ECC Control Subroutine
646  * ----- Check_D_ReadError() ----------------------------------------------
647  */
Check_D_ReadError(BYTE * redundant)648 int Check_D_ReadError(BYTE *redundant)
649 {
650 	return SMSUCCESS;
651 }
652 
653 /* ----- Check_D_Correct() ---------------------------------------------- */
Check_D_Correct(BYTE * buf,BYTE * redundant)654 int Check_D_Correct(BYTE *buf, BYTE *redundant)
655 {
656 	return SMSUCCESS;
657 }
658 
659 /* ----- Check_D_CISdata() ---------------------------------------------- */
Check_D_CISdata(BYTE * buf,BYTE * redundant)660 int Check_D_CISdata(BYTE *buf, BYTE *redundant)
661 {
662 	BYTE cis[] = {0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02,
663 		      0xDF, 0x01, 0x20};
664 
665 	int cis_len = sizeof(cis);
666 
667 	if (!IsSSFDCCompliance && !IsXDCompliance)
668 		return SMSUCCESS;
669 
670 	if (!memcmp(redundant + 0x0D, EccBuf, 3))
671 		return memcmp(buf, cis, cis_len);
672 
673 	if (!_Correct_D_SwECC(buf, redundant + 0x0D, EccBuf))
674 		return memcmp(buf, cis, cis_len);
675 
676 	buf += 0x100;
677 	if (!memcmp(redundant + 0x08, EccBuf + 0x03, 3))
678 		return memcmp(buf, cis, cis_len);
679 
680 	if (!_Correct_D_SwECC(buf, redundant + 0x08, EccBuf + 0x03))
681 		return memcmp(buf, cis, cis_len);
682 
683 	return ERROR;
684 }
685 
686 /* ----- Set_D_RightECC() ---------------------------------------------- */
Set_D_RightECC(BYTE * redundant)687 void Set_D_RightECC(BYTE *redundant)
688 {
689     /* Driver ECC Check */
690     return;
691 }
692 
693 
694