Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
smilsub.c
Go to the documentation of this file.
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 
11 void _Set_D_SsfdcRdChip(void);
12 void _Set_D_SsfdcRdStandby(void);
13 void _Start_D_SsfdcRdHwECC(void);
14 void _Stop_D_SsfdcRdHwECC(void);
18 void _Set_D_SsfdcWrBlock(void);
19 void _Set_D_SsfdcWrStandby(void);
20 void _Start_D_SsfdcWrHwECC(void);
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 *);
31 
32 void _Set_D_ECCdata(BYTE, BYTE *);
33 void _Calc_D_ECCdata(BYTE *);
34 
35 
37 struct ADDRESS Media;
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  */
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() -------------------------------------------- */
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() ------------------------------------------- */
83 int Check_D_DataStatus(BYTE *redundant)
84 {
85  redundant += REDT_DATA;
86 
87  if (*redundant == 0xFF)
88  return SMSUCCESS;
89  if (!*redundant) {
91  return ERROR;
92  } else
94 
95  if (hweight8(*redundant) < 5)
96  return ERROR;
97 
98  return SMSUCCESS;
99 }
100 
101 /* ----- Load_D_LogBlockAddr() ------------------------------------------ */
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() ------------------------------------------ */
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() ------------------------------------------- */
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() ---------------------------------------------- */
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() ---------------------------------------------- */
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() ------------------------------------------------ */
177 void Ssfdc_D_Reset(struct us_data *us)
178 {
179  return;
180 }
181 
182 /* ----- Ssfdc_D_ReadCisSect() ------------------------------------------ */
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() --------------------------------------------- */
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 
211  if (result != USB_STOR_XFER_GOOD) {
212  printk("Load SM RW Code Fail !!\n");
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));
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)
233 
234  /* Read redundant */
235  memset(bcb, 0, sizeof(struct bulk_cb_wrap));
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)
250 
252 }
253 
254 /* ----- Ssfdc_D_ReadBlock() --------------------------------------------- */
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 
262  if (result != USB_STOR_XFER_GOOD) {
263  printk("Load SM RW Code Fail !!\n");
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));
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)
284 
285  /* Read redundant */
286  memset(bcb, 0, sizeof(struct bulk_cb_wrap));
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)
301 
303 }
304 
305 
306 /* ----- Ssfdc_D_CopyBlock() -------------------------------------------- */
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 
314  if (result != USB_STOR_XFER_GOOD) {
315  printk("Load SM RW Code Fail !!\n");
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));
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)
348 
350 }
351 
352 /* ----- Ssfdc_D_WriteSectForCopy() ------------------------------------- */
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 
360  if (result != USB_STOR_XFER_GOOD) {
361  printk("Load SM RW Code Fail !!\n");
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));
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)
385 
387 }
388 
389 /* 6250 CMD 5 */
390 /* ----- Ssfdc_D_EraseBlock() ------------------------------------------- */
392 {
393  struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
394  int result;
395  WORD addr;
396 
398  if (result != USB_STOR_XFER_GOOD) {
399  printk("Load SM RW Code Fail !!\n");
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));
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 
417  if (result != USB_STOR_XFER_GOOD)
419 
421 }
422 
423 /* 6250 CMD 2 */
424 /*----- Ssfdc_D_ReadRedtData() ----------------------------------------- */
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 
433  if (result != USB_STOR_XFER_GOOD) {
434  printk("Load SM RW Code Fail !!\n");
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));
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)
459 
461 }
462 
463 /* 6250 CMD 4 */
464 /* ----- Ssfdc_D_WriteRedtData() ---------------------------------------- */
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 
472  if (result != USB_STOR_XFER_GOOD) {
473  printk("Load SM RW Code Fail !!\n");
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));
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 
493  if (result != USB_STOR_XFER_GOOD)
495 
497 }
498 
499 /* ----- Ssfdc_D_CheckStatus() ------------------------------------------ */
501 {
502  return SMSUCCESS;
503 }
504 
505 
506 
507 /* SmartMedia ID Code Check & Mode Set Subroutine
508  * ----- Set_D_SsfdcModel() ---------------------------------------------
509  */
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() --------------------------------------------- */
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  */
648 int Check_D_ReadError(BYTE *redundant)
649 {
650  return SMSUCCESS;
651 }
652 
653 /* ----- Check_D_Correct() ---------------------------------------------- */
654 int Check_D_Correct(BYTE *buf, BYTE *redundant)
655 {
656  return SMSUCCESS;
657 }
658 
659 /* ----- Check_D_CISdata() ---------------------------------------------- */
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 
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() ---------------------------------------------- */
687 void Set_D_RightECC(BYTE *redundant)
688 {
689  /* Driver ECC Check */
690  return;
691 }
692 
693