linux/drivers/staging/keucr/smilsub.c
<<
>>
Prefs
   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
   9void   _Set_D_SsfdcRdCmd(BYTE);
  10void   _Set_D_SsfdcRdAddr(BYTE);
  11void   _Set_D_SsfdcRdChip(void);
  12void   _Set_D_SsfdcRdStandby(void);
  13void   _Start_D_SsfdcRdHwECC(void);
  14void   _Stop_D_SsfdcRdHwECC(void);
  15void   _Load_D_SsfdcRdHwECC(BYTE);
  16void   _Set_D_SsfdcWrCmd(BYTE);
  17void   _Set_D_SsfdcWrAddr(BYTE);
  18void   _Set_D_SsfdcWrBlock(void);
  19void   _Set_D_SsfdcWrStandby(void);
  20void   _Start_D_SsfdcWrHwECC(void);
  21void   _Load_D_SsfdcWrHwECC(BYTE);
  22int    _Check_D_SsfdcBusy(WORD);
  23int    _Check_D_SsfdcStatus(void);
  24void   _Reset_D_SsfdcErr(void);
  25void   _Read_D_SsfdcBuf(BYTE *);
  26void   _Write_D_SsfdcBuf(BYTE *);
  27void   _Read_D_SsfdcByte(BYTE *);
  28void   _ReadRedt_D_SsfdcBuf(BYTE *);
  29void   _WriteRedt_D_SsfdcBuf(BYTE *);
  30BYTE   _Check_D_DevCode(BYTE);
  31
  32void   _Set_D_ECCdata(BYTE, BYTE *);
  33void   _Calc_D_ECCdata(BYTE *);
  34
  35
  36struct SSFDCTYPE                Ssfdc;
  37struct ADDRESS                  Media;
  38struct CIS_AREA                 CisArea;
  39
  40static BYTE                            EccBuf[6];
  41extern PBYTE                    SMHostAddr;
  42extern DWORD                    ErrXDCode;
  43
  44extern WORD  ReadBlock;
  45extern 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 */
  56int 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() -------------------------------------------- */
  68int 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() ------------------------------------------- */
  83int 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() ------------------------------------------ */
 102int 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() ------------------------------------------ */
 134void 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() ------------------------------------------- */
 143void 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() ---------------------------------------------- */
 159void 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() ---------------------------------------------- */
 167void 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() ------------------------------------------------ */
 177void Ssfdc_D_Reset(struct us_data *us)
 178{
 179        return;
 180}
 181
 182/* ----- Ssfdc_D_ReadCisSect() ------------------------------------------ */
 183int 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() --------------------------------------------- */
 204int 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() --------------------------------------------- */
 255int 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() -------------------------------------------- */
 307int 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() ------------------------------------- */
 353int 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() ------------------------------------------- */
 391int 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() ----------------------------------------- */
 425int 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() ---------------------------------------- */
 465int 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() ------------------------------------------ */
 500int 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 */
 510int 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() --------------------------------------------- */
 618BYTE _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 */
 648int Check_D_ReadError(BYTE *redundant)
 649{
 650        return SMSUCCESS;
 651}
 652
 653/* ----- Check_D_Correct() ---------------------------------------------- */
 654int Check_D_Correct(BYTE *buf, BYTE *redundant)
 655{
 656        return SMSUCCESS;
 657}
 658
 659/* ----- Check_D_CISdata() ---------------------------------------------- */
 660int 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() ---------------------------------------------- */
 687void Set_D_RightECC(BYTE *redundant)
 688{
 689    /* Driver ECC Check */
 690    return;
 691}
 692
 693
 694