1 #include <linux/slab.h>
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
);
32 void _Set_D_ECCdata(BYTE
, BYTE
*);
33 void _Calc_D_ECCdata(BYTE
*);
36 struct keucr_media_info Ssfdc
;
37 struct keucr_media_address Media
;
38 struct keucr_media_area CisArea
;
40 static BYTE EccBuf
[6];
41 extern PBYTE SMHostAddr
;
42 extern DWORD ErrXDCode
;
44 extern WORD ReadBlock
;
45 extern WORD WriteBlock
;
49 #define EVEN 0 /* Even Page for 256byte/page */
50 #define ODD 1 /* Odd Page for 256byte/page */
53 /* SmartMedia Redundant buffer data Control Subroutine
54 *----- Check_D_DataBlank() --------------------------------------------
56 int Check_D_DataBlank(BYTE
*redundant
)
60 for (i
= 0; i
< REDTSIZE
; i
++)
61 if (*redundant
++ != 0xFF)
67 /* ----- Check_D_FailBlock() -------------------------------------------- */
68 int Check_D_FailBlock(BYTE
*redundant
)
70 redundant
+= REDT_BLOCK
;
72 if (*redundant
== 0xFF)
76 if (hweight8(*redundant
) < 7)
82 /* ----- Check_D_DataStatus() ------------------------------------------- */
83 int Check_D_DataStatus(BYTE
*redundant
)
85 redundant
+= REDT_DATA
;
87 if (*redundant
== 0xFF)
90 ErrXDCode
= ERR_DataStatus
;
95 if (hweight8(*redundant
) < 5)
101 /* ----- Load_D_LogBlockAddr() ------------------------------------------ */
102 int Load_D_LogBlockAddr(BYTE
*redundant
)
106 addr1
= (WORD
)*(redundant
+ REDT_ADDR1H
)*0x0100 +
107 (WORD
)*(redundant
+ REDT_ADDR1L
);
108 addr2
= (WORD
)*(redundant
+ REDT_ADDR2H
)*0x0100 +
109 (WORD
)*(redundant
+ REDT_ADDR2L
);
112 if ((addr1
& 0xF000) == 0x1000) {
113 Media
.LogBlock
= (addr1
& 0x0FFF) / 2;
117 if (hweight16((WORD
)(addr1
^addr2
)) != 0x01)
120 if ((addr1
& 0xF000) == 0x1000)
121 if (!(hweight16(addr1
) & 0x01)) {
122 Media
.LogBlock
= (addr1
& 0x0FFF) / 2;
126 if ((addr2
& 0xF000) == 0x1000)
127 if (!(hweight16(addr2
) & 0x01)) {
128 Media
.LogBlock
= (addr2
& 0x0FFF) / 2;
135 /* ----- Clr_D_RedundantData() ------------------------------------------ */
136 void Clr_D_RedundantData(BYTE
*redundant
)
140 for (i
= 0; i
< REDTSIZE
; i
++)
141 *(redundant
+ i
) = 0xFF;
144 /* ----- Set_D_LogBlockAddr() ------------------------------------------- */
145 void Set_D_LogBlockAddr(BYTE
*redundant
)
149 *(redundant
+ REDT_BLOCK
) = 0xFF;
150 *(redundant
+ REDT_DATA
) = 0xFF;
151 addr
= Media
.LogBlock
*2 + 0x1000;
153 if ((hweight16(addr
) % 2))
156 *(redundant
+ REDT_ADDR1H
) = *(redundant
+ REDT_ADDR2H
) =
157 (BYTE
)(addr
/ 0x0100);
158 *(redundant
+ REDT_ADDR1L
) = *(redundant
+ REDT_ADDR2L
) = (BYTE
)addr
;
161 /*----- Set_D_FailBlock() ---------------------------------------------- */
162 void Set_D_FailBlock(BYTE
*redundant
)
165 for (i
= 0; i
< REDTSIZE
; i
++)
166 *redundant
++ = (BYTE
)((i
== REDT_BLOCK
) ? 0xF0 : 0xFF);
169 /* ----- Set_D_DataStaus() ---------------------------------------------- */
170 void Set_D_DataStaus(BYTE
*redundant
)
172 redundant
+= REDT_DATA
;
176 /* SmartMedia Function Command Subroutine
179 /* ----- Ssfdc_D_Reset() ------------------------------------------------ */
180 void Ssfdc_D_Reset(struct us_data
*us
)
185 /* ----- Ssfdc_D_ReadCisSect() ------------------------------------------ */
186 int Ssfdc_D_ReadCisSect(struct us_data
*us
, BYTE
*buf
, BYTE
*redundant
)
191 zone
= Media
.Zone
; block
= Media
.PhyBlock
; sector
= Media
.Sector
;
193 Media
.PhyBlock
= CisArea
.PhyBlock
;
194 Media
.Sector
= CisArea
.Sector
;
196 if (Ssfdc_D_ReadSect(us
, buf
, redundant
)) {
198 Media
.PhyBlock
= block
;
199 Media
.Sector
= sector
;
203 Media
.Zone
= zone
; Media
.PhyBlock
= block
; Media
.Sector
= sector
;
208 /* ----- Ssfdc_D_ReadSect() --------------------------------------------- */
209 int Ssfdc_D_ReadSect(struct us_data
*us
, BYTE
*buf
, BYTE
*redundant
)
211 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
215 result
= ENE_LoadBinCode(us
, SM_RW_PATTERN
);
216 if (result
!= USB_STOR_XFER_GOOD
) {
217 dev_err(&us
->pusb_dev
->dev
,
218 "Failed to load SmartMedia read/write code\n");
219 return USB_STOR_TRANSPORT_ERROR
;
222 addr
= (WORD
)Media
.Zone
*Ssfdc
.MaxBlocks
+ Media
.PhyBlock
;
223 addr
= addr
*(WORD
)Ssfdc
.MaxSectors
+ Media
.Sector
;
226 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
227 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
228 bcb
->DataTransferLength
= 0x200;
232 bcb
->CDB
[4] = (BYTE
)addr
;
233 bcb
->CDB
[3] = (BYTE
)(addr
/ 0x0100);
234 bcb
->CDB
[2] = Media
.Zone
/ 2;
236 result
= ENE_SendScsiCmd(us
, FDIR_READ
, buf
, 0);
237 if (result
!= USB_STOR_XFER_GOOD
)
238 return USB_STOR_TRANSPORT_ERROR
;
241 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
242 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
243 bcb
->DataTransferLength
= 0x10;
247 bcb
->CDB
[4] = (BYTE
)addr
;
248 bcb
->CDB
[3] = (BYTE
)(addr
/ 0x0100);
249 bcb
->CDB
[2] = Media
.Zone
/ 2;
253 result
= ENE_SendScsiCmd(us
, FDIR_READ
, redundant
, 0);
254 if (result
!= USB_STOR_XFER_GOOD
)
255 return USB_STOR_TRANSPORT_ERROR
;
257 return USB_STOR_TRANSPORT_GOOD
;
260 /* ----- Ssfdc_D_ReadBlock() --------------------------------------------- */
261 int Ssfdc_D_ReadBlock(struct us_data
*us
, WORD count
, BYTE
*buf
,
264 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
268 result
= ENE_LoadBinCode(us
, SM_RW_PATTERN
);
269 if (result
!= USB_STOR_XFER_GOOD
) {
270 dev_err(&us
->pusb_dev
->dev
,
271 "Failed to load SmartMedia read/write code\n");
272 return USB_STOR_TRANSPORT_ERROR
;
275 addr
= (WORD
)Media
.Zone
*Ssfdc
.MaxBlocks
+ Media
.PhyBlock
;
276 addr
= addr
*(WORD
)Ssfdc
.MaxSectors
+ Media
.Sector
;
279 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
280 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
281 bcb
->DataTransferLength
= 0x200*count
;
285 bcb
->CDB
[4] = (BYTE
)addr
;
286 bcb
->CDB
[3] = (BYTE
)(addr
/ 0x0100);
287 bcb
->CDB
[2] = Media
.Zone
/ 2;
289 result
= ENE_SendScsiCmd(us
, FDIR_READ
, buf
, 0);
290 if (result
!= USB_STOR_XFER_GOOD
)
291 return USB_STOR_TRANSPORT_ERROR
;
294 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
295 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
296 bcb
->DataTransferLength
= 0x10;
300 bcb
->CDB
[4] = (BYTE
)addr
;
301 bcb
->CDB
[3] = (BYTE
)(addr
/ 0x0100);
302 bcb
->CDB
[2] = Media
.Zone
/ 2;
306 result
= ENE_SendScsiCmd(us
, FDIR_READ
, redundant
, 0);
307 if (result
!= USB_STOR_XFER_GOOD
)
308 return USB_STOR_TRANSPORT_ERROR
;
310 return USB_STOR_TRANSPORT_GOOD
;
314 /* ----- Ssfdc_D_CopyBlock() -------------------------------------------- */
315 int Ssfdc_D_CopyBlock(struct us_data
*us
, WORD count
, BYTE
*buf
,
318 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
320 WORD ReadAddr
, WriteAddr
;
322 result
= ENE_LoadBinCode(us
, SM_RW_PATTERN
);
323 if (result
!= USB_STOR_XFER_GOOD
) {
324 dev_err(&us
->pusb_dev
->dev
,
325 "Failed to load SmartMedia read/write code\n");
326 return USB_STOR_TRANSPORT_ERROR
;
329 ReadAddr
= (WORD
)Media
.Zone
*Ssfdc
.MaxBlocks
+ ReadBlock
;
330 ReadAddr
= ReadAddr
*(WORD
)Ssfdc
.MaxSectors
;
331 WriteAddr
= (WORD
)Media
.Zone
*Ssfdc
.MaxBlocks
+ WriteBlock
;
332 WriteAddr
= WriteAddr
*(WORD
)Ssfdc
.MaxSectors
;
334 /* Write sect data */
335 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
336 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
337 bcb
->DataTransferLength
= 0x200*count
;
341 bcb
->CDB
[7] = (BYTE
)WriteAddr
;
342 bcb
->CDB
[6] = (BYTE
)(WriteAddr
/ 0x0100);
343 bcb
->CDB
[5] = Media
.Zone
/ 2;
344 bcb
->CDB
[8] = *(redundant
+ REDT_ADDR1H
);
345 bcb
->CDB
[9] = *(redundant
+ REDT_ADDR1L
);
346 bcb
->CDB
[10] = Media
.Sector
;
348 if (ReadBlock
!= NO_ASSIGN
) {
349 bcb
->CDB
[4] = (BYTE
)ReadAddr
;
350 bcb
->CDB
[3] = (BYTE
)(ReadAddr
/ 0x0100);
351 bcb
->CDB
[2] = Media
.Zone
/ 2;
355 result
= ENE_SendScsiCmd(us
, FDIR_WRITE
, buf
, 0);
356 if (result
!= USB_STOR_XFER_GOOD
)
357 return USB_STOR_TRANSPORT_ERROR
;
359 return USB_STOR_TRANSPORT_GOOD
;
362 /* ----- Ssfdc_D_WriteSectForCopy() ------------------------------------- */
363 int Ssfdc_D_WriteSectForCopy(struct us_data
*us
, BYTE
*buf
, BYTE
*redundant
)
365 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
369 result
= ENE_LoadBinCode(us
, SM_RW_PATTERN
);
370 if (result
!= USB_STOR_XFER_GOOD
) {
371 dev_err(&us
->pusb_dev
->dev
,
372 "Failed to load SmartMedia read/write code\n");
373 return USB_STOR_TRANSPORT_ERROR
;
377 addr
= (WORD
)Media
.Zone
*Ssfdc
.MaxBlocks
+ Media
.PhyBlock
;
378 addr
= addr
*(WORD
)Ssfdc
.MaxSectors
+ Media
.Sector
;
380 /* Write sect data */
381 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
382 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
383 bcb
->DataTransferLength
= 0x200;
387 bcb
->CDB
[7] = (BYTE
)addr
;
388 bcb
->CDB
[6] = (BYTE
)(addr
/ 0x0100);
389 bcb
->CDB
[5] = Media
.Zone
/ 2;
390 bcb
->CDB
[8] = *(redundant
+ REDT_ADDR1H
);
391 bcb
->CDB
[9] = *(redundant
+ REDT_ADDR1L
);
393 result
= ENE_SendScsiCmd(us
, FDIR_WRITE
, buf
, 0);
394 if (result
!= USB_STOR_XFER_GOOD
)
395 return USB_STOR_TRANSPORT_ERROR
;
397 return USB_STOR_TRANSPORT_GOOD
;
401 /* ----- Ssfdc_D_EraseBlock() ------------------------------------------- */
402 int Ssfdc_D_EraseBlock(struct us_data
*us
)
404 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
408 result
= ENE_LoadBinCode(us
, SM_RW_PATTERN
);
409 if (result
!= USB_STOR_XFER_GOOD
) {
410 dev_err(&us
->pusb_dev
->dev
,
411 "Failed to load SmartMedia read/write code\n");
412 return USB_STOR_TRANSPORT_ERROR
;
415 addr
= (WORD
)Media
.Zone
*Ssfdc
.MaxBlocks
+ Media
.PhyBlock
;
416 addr
= addr
*(WORD
)Ssfdc
.MaxSectors
;
418 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
419 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
420 bcb
->DataTransferLength
= 0x200;
424 bcb
->CDB
[7] = (BYTE
)addr
;
425 bcb
->CDB
[6] = (BYTE
)(addr
/ 0x0100);
426 bcb
->CDB
[5] = Media
.Zone
/ 2;
428 result
= ENE_SendScsiCmd(us
, FDIR_READ
, NULL
, 0);
429 if (result
!= USB_STOR_XFER_GOOD
)
430 return USB_STOR_TRANSPORT_ERROR
;
432 return USB_STOR_TRANSPORT_GOOD
;
436 /*----- Ssfdc_D_ReadRedtData() ----------------------------------------- */
437 int Ssfdc_D_ReadRedtData(struct us_data
*us
, BYTE
*redundant
)
439 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
444 result
= ENE_LoadBinCode(us
, SM_RW_PATTERN
);
445 if (result
!= USB_STOR_XFER_GOOD
) {
446 dev_err(&us
->pusb_dev
->dev
,
447 "Failed to load SmartMedia read/write code\n");
448 return USB_STOR_TRANSPORT_ERROR
;
451 addr
= (WORD
)Media
.Zone
*Ssfdc
.MaxBlocks
+ Media
.PhyBlock
;
452 addr
= addr
*(WORD
)Ssfdc
.MaxSectors
+ Media
.Sector
;
454 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
455 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
456 bcb
->DataTransferLength
= 0x10;
460 bcb
->CDB
[4] = (BYTE
)addr
;
461 bcb
->CDB
[3] = (BYTE
)(addr
/ 0x0100);
462 bcb
->CDB
[2] = Media
.Zone
/ 2;
466 buf
= kmalloc(0x10, GFP_KERNEL
);
467 result
= ENE_SendScsiCmd(us
, FDIR_READ
, buf
, 0);
468 memcpy(redundant
, buf
, 0x10);
470 if (result
!= USB_STOR_XFER_GOOD
)
471 return USB_STOR_TRANSPORT_ERROR
;
473 return USB_STOR_TRANSPORT_GOOD
;
477 /* ----- Ssfdc_D_WriteRedtData() ---------------------------------------- */
478 int Ssfdc_D_WriteRedtData(struct us_data
*us
, BYTE
*redundant
)
480 struct bulk_cb_wrap
*bcb
= (struct bulk_cb_wrap
*) us
->iobuf
;
484 result
= ENE_LoadBinCode(us
, SM_RW_PATTERN
);
485 if (result
!= USB_STOR_XFER_GOOD
) {
486 dev_err(&us
->pusb_dev
->dev
,
487 "Failed to load SmartMedia read/write code\n");
488 return USB_STOR_TRANSPORT_ERROR
;
491 addr
= (WORD
)Media
.Zone
*Ssfdc
.MaxBlocks
+ Media
.PhyBlock
;
492 addr
= addr
*(WORD
)Ssfdc
.MaxSectors
+ Media
.Sector
;
494 memset(bcb
, 0, sizeof(struct bulk_cb_wrap
));
495 bcb
->Signature
= cpu_to_le32(US_BULK_CB_SIGN
);
496 bcb
->DataTransferLength
= 0x10;
500 bcb
->CDB
[7] = (BYTE
)addr
;
501 bcb
->CDB
[6] = (BYTE
)(addr
/ 0x0100);
502 bcb
->CDB
[5] = Media
.Zone
/ 2;
503 bcb
->CDB
[8] = *(redundant
+ REDT_ADDR1H
);
504 bcb
->CDB
[9] = *(redundant
+ REDT_ADDR1L
);
506 result
= ENE_SendScsiCmd(us
, FDIR_READ
, NULL
, 0);
507 if (result
!= USB_STOR_XFER_GOOD
)
508 return USB_STOR_TRANSPORT_ERROR
;
510 return USB_STOR_TRANSPORT_GOOD
;
513 /* ----- Ssfdc_D_CheckStatus() ------------------------------------------ */
514 int Ssfdc_D_CheckStatus(void)
521 /* SmartMedia ID Code Check & Mode Set Subroutine
522 * ----- Set_D_SsfdcModel() ---------------------------------------------
524 int Set_D_SsfdcModel(BYTE dcode
)
526 switch (_Check_D_DevCode(dcode
)) {
528 Ssfdc
.Model
= SSFDC1MB
;
529 Ssfdc
.Attribute
= FLASH
| AD3CYC
| BS16
| PS256
;
531 Ssfdc
.MaxBlocks
= 256;
532 Ssfdc
.MaxLogBlocks
= 250;
533 Ssfdc
.MaxSectors
= 8;
536 Ssfdc
.Model
= SSFDC2MB
;
537 Ssfdc
.Attribute
= FLASH
| AD3CYC
| BS16
| PS256
;
539 Ssfdc
.MaxBlocks
= 512;
540 Ssfdc
.MaxLogBlocks
= 500;
541 Ssfdc
.MaxSectors
= 8;
544 Ssfdc
.Model
= SSFDC4MB
;
545 Ssfdc
.Attribute
= FLASH
| AD3CYC
| BS16
| PS512
;
547 Ssfdc
.MaxBlocks
= 512;
548 Ssfdc
.MaxLogBlocks
= 500;
549 Ssfdc
.MaxSectors
= 16;
552 Ssfdc
.Model
= SSFDC8MB
;
553 Ssfdc
.Attribute
= FLASH
| AD3CYC
| BS16
| PS512
;
555 Ssfdc
.MaxBlocks
= 1024;
556 Ssfdc
.MaxLogBlocks
= 1000;
557 Ssfdc
.MaxSectors
= 16;
560 Ssfdc
.Model
= SSFDC16MB
;
561 Ssfdc
.Attribute
= FLASH
| AD3CYC
| BS32
| PS512
;
563 Ssfdc
.MaxBlocks
= 1024;
564 Ssfdc
.MaxLogBlocks
= 1000;
565 Ssfdc
.MaxSectors
= 32;
568 Ssfdc
.Model
= SSFDC32MB
;
569 Ssfdc
.Attribute
= FLASH
| AD3CYC
| BS32
| PS512
;
571 Ssfdc
.MaxBlocks
= 1024;
572 Ssfdc
.MaxLogBlocks
= 1000;
573 Ssfdc
.MaxSectors
= 32;
576 Ssfdc
.Model
= SSFDC64MB
;
577 Ssfdc
.Attribute
= FLASH
| AD4CYC
| BS32
| PS512
;
579 Ssfdc
.MaxBlocks
= 1024;
580 Ssfdc
.MaxLogBlocks
= 1000;
581 Ssfdc
.MaxSectors
= 32;
584 Ssfdc
.Model
= SSFDC128MB
;
585 Ssfdc
.Attribute
= FLASH
| AD4CYC
| BS32
| PS512
;
587 Ssfdc
.MaxBlocks
= 1024;
588 Ssfdc
.MaxLogBlocks
= 1000;
589 Ssfdc
.MaxSectors
= 32;
592 Ssfdc
.Model
= SSFDC256MB
;
593 Ssfdc
.Attribute
= FLASH
| AD4CYC
| BS32
| PS512
;
595 Ssfdc
.MaxBlocks
= 1024;
596 Ssfdc
.MaxLogBlocks
= 1000;
597 Ssfdc
.MaxSectors
= 32;
600 Ssfdc
.Model
= SSFDC512MB
;
601 Ssfdc
.Attribute
= FLASH
| AD4CYC
| BS32
| PS512
;
603 Ssfdc
.MaxBlocks
= 1024;
604 Ssfdc
.MaxLogBlocks
= 1000;
605 Ssfdc
.MaxSectors
= 32;
608 Ssfdc
.Model
= SSFDC1GB
;
609 Ssfdc
.Attribute
= FLASH
| AD4CYC
| BS32
| PS512
;
611 Ssfdc
.MaxBlocks
= 1024;
612 Ssfdc
.MaxLogBlocks
= 1000;
613 Ssfdc
.MaxSectors
= 32;
616 Ssfdc
.Model
= SSFDC2GB
;
617 Ssfdc
.Attribute
= FLASH
| AD4CYC
| BS32
| PS512
;
618 Ssfdc
.MaxZones
= 128;
619 Ssfdc
.MaxBlocks
= 1024;
620 Ssfdc
.MaxLogBlocks
= 1000;
621 Ssfdc
.MaxSectors
= 32;
624 Ssfdc
.Model
= NOSSFDC
;
631 /* ----- _Check_D_DevCode() --------------------------------------------- */
632 BYTE
_Check_D_DevCode(BYTE dcode
)
637 case 0xEC: return SSFDC1MB
; /* 8Mbit (1M) NAND */
639 case 0xEA: return SSFDC2MB
; /* 16Mbit (2M) NAND */
642 case 0xE5: return SSFDC4MB
; /* 32Mbit (4M) NAND */
643 case 0xE6: return SSFDC8MB
; /* 64Mbit (8M) NAND */
644 case 0x73: return SSFDC16MB
; /* 128Mbit (16M)NAND */
645 case 0x75: return SSFDC32MB
; /* 256Mbit (32M)NAND */
646 case 0x76: return SSFDC64MB
; /* 512Mbit (64M)NAND */
647 case 0x79: return SSFDC128MB
; /* 1Gbit(128M)NAND */
648 case 0x71: return SSFDC256MB
;
649 case 0xDC: return SSFDC512MB
;
650 case 0xD3: return SSFDC1GB
;
651 case 0xD5: return SSFDC2GB
;
652 default: return NOSSFDC
;
659 /* SmartMedia ECC Control Subroutine
660 * ----- Check_D_ReadError() ----------------------------------------------
662 int Check_D_ReadError(BYTE
*redundant
)
667 /* ----- Check_D_Correct() ---------------------------------------------- */
668 int Check_D_Correct(BYTE
*buf
, BYTE
*redundant
)
673 /* ----- Check_D_CISdata() ---------------------------------------------- */
674 int Check_D_CISdata(BYTE
*buf
, BYTE
*redundant
)
676 BYTE cis
[] = {0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02,
679 int cis_len
= sizeof(cis
);
681 if (!IsSSFDCCompliance
&& !IsXDCompliance
)
684 if (!memcmp(redundant
+ 0x0D, EccBuf
, 3))
685 return memcmp(buf
, cis
, cis_len
);
687 if (!_Correct_D_SwECC(buf
, redundant
+ 0x0D, EccBuf
))
688 return memcmp(buf
, cis
, cis_len
);
691 if (!memcmp(redundant
+ 0x08, EccBuf
+ 0x03, 3))
692 return memcmp(buf
, cis
, cis_len
);
694 if (!_Correct_D_SwECC(buf
, redundant
+ 0x08, EccBuf
+ 0x03))
695 return memcmp(buf
, cis
, cis_len
);
700 /* ----- Set_D_RightECC() ---------------------------------------------- */
701 void Set_D_RightECC(BYTE
*redundant
)
703 /* Driver ECC Check */