PageRenderTime 87ms CodeModel.GetById 22ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/block/sun3i_nand/src/logic/logic_ctl.c

https://bitbucket.org/ndreys/linux-sunxi
C | 1436 lines | 796 code | 208 blank | 432 comment | 130 complexity | a38b5ef46dd4db74d4c430c29b9b14e7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * drivers/block/sun3i_nand/src/logic/logic_ctl.c
   3 *
   4 * (C) Copyright 2007-2012
   5 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22
  23#include <linux/module.h>
  24#include "../include/nand_logic.h"
  25
  26struct __NandDriverGlobal_t     NandDriverInfo;
  27struct __LogicArchitecture_t    LogicArchiPar;
  28struct __ZoneTblPstInfo_t       ZoneTblPstInfo[MAX_ZONE_CNT];
  29//define the parameter for manage the cached page
  30static struct __GlobalLogicPageType_t  CachePage;
  31
  32//define the parameter for manage the logical page read and write
  33static struct __LogicCtlPar_t LogicalCtl;
  34
  35/*
  36************************************************************************************************************************
  37*                       CALCLUATE PROCESSING DATA PARAMETER
  38*
  39*Description: Calculate the loigcal pages number and the sector bitmap in the page for the sectors
  40*             that pocessing currently.
  41*
  42*Arguments  : nSectNum      the number of the first sector of the sectors need be processed;
  43*             nSectCnt      the count of the sectors that how many sectors need be processed;
  44*             pHeadPage     the pointer to the paramter of the head page;
  45*             pMidPageCnt   the pointer ot the count of full pages;
  46*             pTailPage     the pointer to the paramter of the tail page.
  47*
  48*Return     : calculate sector parameter result;
  49*               = 0     calculate sector parameter successful;
  50*               < 0     calcualte sector parameter failed.
  51************************************************************************************************************************
  52*/
  53static __s32 _CalculateSectPar(__u32 nSectNum, __u32 nSectCnt, struct __GlobalLogicPageType_t *pHeadPage,
  54                                    __u32 *pMidPageCnt, struct __GlobalLogicPageType_t *pTailPage)
  55{
  56    __u32   tmpSectCnt, tmpBitmap;
  57
  58    LOGICCTL_DBG("[LOGICCTL_DBG]: Calculate logical sectors parameter, Lba:0x%x, Cnt:0x%x\n", nSectNum, nSectCnt);
  59
  60    //initiate the middle page and tail page parameters, because they may be empty
  61    *pMidPageCnt = 0x00;
  62    pTailPage->LogicPageNum = 0xffffffff;
  63    pTailPage->SectorBitmap = 0x00;
  64
  65    //calculate the head page parameter
  66    pHeadPage->LogicPageNum = nSectNum / SECTOR_CNT_OF_LOGIC_PAGE;
  67    tmpSectCnt = nSectCnt + (nSectNum % SECTOR_CNT_OF_LOGIC_PAGE);
  68    tmpBitmap = (FULL_BITMAP_OF_LOGIC_PAGE << (nSectNum % SECTOR_CNT_OF_LOGIC_PAGE));
  69
  70    if(tmpSectCnt > SECTOR_CNT_OF_LOGIC_PAGE)
  71    {
  72        //set the head page bitmap
  73        pHeadPage->SectorBitmap = tmpBitmap & FULL_BITMAP_OF_LOGIC_PAGE;
  74
  75        //calcualte the count of full pages
  76        tmpSectCnt -= SECTOR_CNT_OF_LOGIC_PAGE;
  77        while(tmpSectCnt >= SECTOR_CNT_OF_LOGIC_PAGE)
  78        {
  79            ++*pMidPageCnt;
  80            tmpSectCnt -= SECTOR_CNT_OF_LOGIC_PAGE;
  81        }
  82
  83        //calculate parameter for the tail page
  84        if(tmpSectCnt)
  85        {
  86            //calcualte the tail page sector bitmap
  87            pTailPage->SectorBitmap = FULL_BITMAP_OF_LOGIC_PAGE >> (SECTOR_CNT_OF_LOGIC_PAGE - tmpSectCnt);
  88
  89            //calculate the number of the tail page
  90            pTailPage->LogicPageNum = pHeadPage->LogicPageNum + *pMidPageCnt + 1;
  91        }
  92    }
  93    else
  94    {
  95        //the head page is not a full page, reset the sector bitmap
  96        pHeadPage->SectorBitmap = tmpBitmap & (FULL_BITMAP_OF_LOGIC_PAGE >> (SECTOR_CNT_OF_LOGIC_PAGE - tmpSectCnt));
  97    }
  98
  99    LOGICCTL_DBG("   head page number:0x%x, head page bitmap:0x%x\n", pHeadPage->LogicPageNum, pHeadPage->SectorBitmap);
 100    LOGICCTL_DBG("   the count of middle page:0x%x\n", *pMidPageCnt);
 101    LOGICCTL_DBG("   tail page number:0x%x, tail page bitmap:0x%x\n\n", pTailPage->LogicPageNum, pTailPage->SectorBitmap);
 102
 103    return 0;
 104}
 105
 106
 107/*
 108************************************************************************************************************************
 109*                       CALCLUATE LOGICAL PAGE PARAMETER
 110*
 111*Description: Calculate the parameter for a logical page, the zone number, logic block number and
 112*             and page number in logical block.
 113*
 114*Arguments  : pLogicPage    the pointer to the parameter of the logical page;
 115*             nPage         the number of the global logical page;
 116*             nBitmap       the bitmap of the valid sector in the logical page.
 117*
 118*Return     : calculate page parameter result;
 119*               = 0     calculate page parameter successful;
 120*               < 0     calcualte page parameter failed.
 121************************************************************************************************************************
 122*/
 123static __s32 _CalculateLogicPagePar(struct __LogicPageType_t *pLogicPage, __u32 nPage, __u32 nBitmap)
 124{
 125    __u32   tmpPage, tmpBlk, tmpZone;
 126
 127    tmpPage = nPage % PAGE_CNT_OF_LOGIC_BLK;
 128    tmpBlk = nPage / PAGE_CNT_OF_LOGIC_BLK;
 129    tmpZone = tmpBlk / DATA_BLK_CNT_OF_ZONE;
 130    tmpBlk %= DATA_BLK_CNT_OF_ZONE;
 131
 132    pLogicPage->ZoneNum = tmpZone;
 133    pLogicPage->BlockNum = tmpBlk;
 134    pLogicPage->PageNum = tmpPage;
 135    pLogicPage->SectBitmap = nBitmap;
 136
 137    LOGICCTL_DBG("[LOGICCTL_DBG] The parameter of logical page 0x%x is : zone 0x%x, block 0x%x, page 0x%x\n",
 138                    nPage, tmpZone, tmpBlk, tmpPage);
 139
 140    return 0;
 141}
 142
 143
 144/*
 145************************************************************************************************************************
 146*                       UPDATE USER DATA WITH THE CACHE PAGE
 147*
 148*Description: Update the user data with the cache page, because the number of the page read is
 149*             same as the cached page, so need update the page data.
 150*
 151*Arguments  : nSectBitmap   the bitmap of the valid sectors in the user buffer;
 152*             pBuf          the pointer to he user buffer;
 153*
 154*Return     : update page data result;
 155*               = 0     update page data successful;
 156*               < 0     update page data failed.
 157************************************************************************************************************************
 158*/
 159static __s32 _UpdateReadPageData(__u32 nSectBitmap, void * pBuf)
 160{
 161    __s32   i;
 162    __u8    *tmpSrc = LML_WRITE_PAGE_CACHE, *tmpDst = pBuf;
 163
 164    for(i=0; i<SECTOR_CNT_OF_LOGIC_PAGE; i++)
 165    {
 166        if(nSectBitmap & CachePage.SectorBitmap & (1<<i))
 167        {
 168            MEMCPY(tmpDst, tmpSrc, SECTOR_SIZE);
 169        }
 170
 171        tmpSrc += SECTOR_SIZE;
 172        tmpDst += SECTOR_SIZE;
 173    }
 174
 175    return 0;
 176}
 177
 178
 179/*
 180************************************************************************************************************************
 181*                       MERGE WRITE PAGE DATA WITH CACHE PAGE DATA
 182*
 183*Description: Merge the data of write page with the cached page.
 184*
 185*Arguments  : nPage     the number of the logical page which need write to nand flash;
 186*             nBitmap   the bitmap of the valid sectors in the write page;
 187*             pBuf      the pointer to the page data buffer;
 188*
 189*Return     : merge page data result;
 190*               = 0     merge page data successful;
 191*               < 0     merge page data failed.
 192************************************************************************************************************************
 193*/
 194static __s32 _MergeCachePageData(__u32 nPage, __u32 nBitmap, __u8 *pBuf)
 195{
 196    __s32   i;
 197    __u8    *tmpSrc = pBuf, *tmpDst = LML_WRITE_PAGE_CACHE;
 198
 199    //check if the cache page is valid
 200    if(CachePage.LogicPageNum == 0xffffffff)
 201    {
 202        //cache page is valid, set the logical page number, and reset the sector bitmap to null
 203        CachePage.LogicPageNum = nPage;
 204        CachePage.SectorBitmap = 0;
 205    }
 206
 207    for(i=0; i<SECTOR_CNT_OF_LOGIC_PAGE; i++)
 208    {
 209        if(nBitmap & (1<<i))
 210        {
 211            //the sector of the write page is valid, copy data to the page cache
 212            MEMCPY(tmpDst, tmpSrc, SECTOR_SIZE);
 213        }
 214
 215        tmpSrc += SECTOR_SIZE;
 216        tmpDst += SECTOR_SIZE;
 217    }
 218
 219    //reset the sector bitmap for the cached page
 220    CachePage.SectorBitmap |= nBitmap;
 221
 222    return 0;
 223}
 224
 225
 226/*
 227************************************************************************************************************************
 228*                       WRITE DATA OF PAGE CACHE TO NAND FLASH
 229*
 230*Description: Write the data of page cache to nand flash.
 231*
 232*Arguments  : none.
 233*
 234*Return     : write page cache result;
 235*               = 0     write page cache successful;
 236*               < 0     write page cache failed.
 237************************************************************************************************************************
 238*/
 239static __s32 _WritePageCacheToNand(void)
 240{
 241    __s32   result = 0;
 242    __u32   tmpPage, tmpBitmap;
 243    __u8    *tmpBuf;
 244
 245    tmpPage = CachePage.LogicPageNum;
 246    tmpBitmap = CachePage.SectorBitmap;
 247    tmpBuf = LML_WRITE_PAGE_CACHE;
 248
 249    if(tmpPage != 0xffffffff)
 250    {
 251
 252        if(tmpBitmap != FULL_BITMAP_OF_LOGIC_PAGE)
 253        {
 254            //get the data from logical page to fill the page cache
 255            result = LML_PageRead(tmpPage, tmpBitmap ^ FULL_BITMAP_OF_LOGIC_PAGE, tmpBuf);
 256            if(result < 0)
 257            {
 258                return -1;
 259            }
 260        }
 261
 262        //the data in the page cache is full, write it to nand flash
 263        result = LML_PageWrite(tmpPage, FULL_BITMAP_OF_LOGIC_PAGE, tmpBuf);
 264        if(result < 0)
 265        {
 266            return -1;
 267        }
 268
 269        //clear the buffer page parameter
 270        CachePage.LogicPageNum = 0xffffffff;
 271        CachePage.SectorBitmap = 0x00;
 272    }
 273
 274    return 0;
 275}
 276
 277
 278/*
 279************************************************************************************************************************
 280*                       CALCULATE PHYSICAL OPERATION PARAMETER
 281*
 282*Description: Calculate the paramter for physical operation with the number of zone, number of
 283*             super block and number of page in the super block.
 284*
 285*Arguments  : pPhyPar   the pointer to the physical operation parameter;
 286*             nZone     the number of the zone which the super block blonged to;
 287*             nBlock    the number of the super block;
 288*             nPage     the number of the super page in the super block.
 289*
 290*Return     : calculate parameter result;
 291*               = 0     calculate parameter successful;
 292*               < 0     calcualte parameter failed.
 293************************************************************************************************************************
 294*/
 295#if(0)
 296__s32 LML_CalculatePhyOpPar(struct __PhysicOpPara_t *pPhyPar, __u32 nZone, __u32 nBlock, __u32 nPage)
 297{
 298
 299
 300    __u32   tmpDieNum, tmpBnkNum, tmpBlkNum, tmpPageNum;
 301
 302    LOGICCTL_DBG("[LOGICCTL_DBG] Calculate the physical operation parameters.\n"
 303                 "         ZoneNum:0x%x, BlockNum:0x%x, PageNum: 0x%x\n", nZone, nBlock, nPage);
 304
 305    //calcualte the Die number by the zone number
 306    tmpDieNum = nZone / ZONE_CNT_OF_DIE;
 307
 308    if(SUPPORT_INT_INTERLEAVE && SUPPORT_EXT_INTERLEAVE)
 309    {
 310        //nand flash support internal inter-leave and external iner-leave, the block number is
 311        //same as the virtual block number in the die, the bank number is the virtual page number
 312        //model the inter-leave bank count, and the page number is the virtual page number
 313        //divide the inter-leave bank count
 314        tmpBnkNum = nPage % INTERLEAVE_BANK_CNT;
 315        tmpBlkNum = nBlock;
 316        tmpPageNum = nPage / INTERLEAVE_BANK_CNT;
 317    }
 318
 319    else if(SUPPORT_INT_INTERLEAVE && !SUPPORT_EXT_INTERLEAVE)
 320    {
 321        //nand flash support internal inter-leave but don't support external inter-leave, the block
 322        //number if same as the vitual block number, the bank number is virtual page number model
 323        //inter-leave count and add the chip bank base, the page number is the virtual page number
 324        //divide the inter-leave bank count
 325        tmpBnkNum = (nPage % INTERLEAVE_BANK_CNT) + (tmpDieNum * INTERLEAVE_BANK_CNT);
 326        tmpBlkNum = nBlock;
 327        tmpPageNum = nPage / INTERLEAVE_BANK_CNT;
 328    }
 329
 330    else if(!SUPPORT_INT_INTERLEAVE && SUPPORT_EXT_INTERLEAVE)
 331    {
 332        //nand flash support external inter-leave but don't support internal inter-leave, the block
 333        //number is virtual block number add the die block base, the bank number is the page number
 334        //model the inter-leave bank count, the page number is vitual page number divide the inter-leave
 335        //bank count
 336        tmpBnkNum = nPage % INTERLEAVE_BANK_CNT;
 337        tmpBlkNum = nBlock + (tmpDieNum * (BLOCK_CNT_OF_DIE / PLANE_CNT_OF_DIE));
 338        tmpPageNum = nPage / INTERLEAVE_BANK_CNT;
 339    }
 340
 341    else//(!SUPPORT_INT_INTERLEAVE && !SUPPORT_EXT_INTERLEAVE)
 342    {
 343        //nand flash don't internal inter-leave and extern inter-leave either, the bank number is the
 344        //die number divide the die count of chip, the block number is the virtual block number add
 345        //the die block base in the chip, the page number is same as the virtual page number
 346        tmpBnkNum = tmpDieNum / DIE_CNT_OF_CHIP;
 347        tmpBlkNum = nBlock + (tmpDieNum % DIE_CNT_OF_CHIP) * (BLOCK_CNT_OF_DIE / PLANE_CNT_OF_DIE);
 348        tmpPageNum = nPage;
 349    }
 350
 351    //set the physical operation paramter by the bank number, block number and page number
 352    pPhyPar->BankNum = tmpBnkNum;
 353    pPhyPar->PageNum = tmpPageNum;
 354    pPhyPar->BlkNum = tmpBlkNum;
 355
 356    LOGICCTL_DBG("         Calculate Result: BankNum 0x%x, BlkNum 0x%x, PageNum 0x%x\n", tmpBnkNum, tmpBlkNum, tmpPageNum);
 357
 358    //calculate physical operation parameter successful
 359    return 0;
 360}
 361#elif(1)
 362__s32 LML_CalculatePhyOpPar(struct __PhysicOpPara_t *pPhyPar, __u32 nZone, __u32 nBlock, __u32 nPage)
 363{
 364
 365
 366    __u32   tmpDieNum, tmpBnkNum, tmpBlkNum, tmpPageNum;
 367
 368    LOGICCTL_DBG("[LOGICCTL_DBG] Calculate the physical operation parameters.\n"
 369                 "         ZoneNum:0x%x, BlockNum:0x%x, PageNum: 0x%x\n", nZone, nBlock, nPage);
 370
 371    //calcualte the Die number by the zone number
 372    tmpDieNum = nZone / ZONE_CNT_OF_DIE;
 373
 374    if(SUPPORT_INT_INTERLEAVE && SUPPORT_EXT_INTERLEAVE)
 375    {
 376        //nand flash support internal inter-leave and external iner-leave, the block number is
 377        //same as the virtual block number in the die, the bank number is the virtual page number
 378        //model the inter-leave bank count, and the page number is the virtual page number
 379        //divide the inter-leave bank count
 380        tmpBnkNum = nPage % INTERLEAVE_BANK_CNT + (tmpDieNum * INTERLEAVE_BANK_CNT);
 381        tmpBlkNum = nBlock ;
 382        tmpPageNum = nPage / INTERLEAVE_BANK_CNT;
 383    }
 384
 385    else if(SUPPORT_INT_INTERLEAVE && !SUPPORT_EXT_INTERLEAVE)
 386    {
 387        //nand flash support internal inter-leave but don't support external inter-leave, the block
 388        //number if same as the vitual block number, the bank number is virtual page number model
 389        //inter-leave count and add the chip bank base, the page number is the virtual page number
 390        //divide the inter-leave bank count
 391        tmpBnkNum = (nPage % INTERLEAVE_BANK_CNT) + (tmpDieNum * INTERLEAVE_BANK_CNT);
 392        tmpBlkNum = nBlock;
 393        tmpPageNum = nPage / INTERLEAVE_BANK_CNT;
 394    }
 395
 396    else if(!SUPPORT_INT_INTERLEAVE && SUPPORT_EXT_INTERLEAVE)
 397    {
 398        //nand flash support external inter-leave but don't support internal inter-leave, the block
 399        //number is virtual block number add the die block base, the bank number is the page number
 400        //model the inter-leave bank count, the page number is vitual page number divide the inter-leave
 401        //bank count
 402        //tmpBnkNum = nPage % INTERLEAVE_BANK_CNT + (tmpDieNum * INTERLEAVE_BANK_CNT);
 403        tmpBnkNum = nPage % INTERLEAVE_BANK_CNT + (tmpDieNum/DIE_CNT_OF_CHIP) *INTERLEAVE_BANK_CNT;
 404        tmpBlkNum = nBlock+ ((tmpDieNum % DIE_CNT_OF_CHIP) * (BLOCK_CNT_OF_DIE / PLANE_CNT_OF_DIE));
 405        tmpPageNum = nPage / INTERLEAVE_BANK_CNT;
 406    }
 407
 408    else//(!SUPPORT_INT_INTERLEAVE && !SUPPORT_EXT_INTERLEAVE)
 409    {
 410        //nand flash don't internal inter-leave and extern inter-leave either, the bank number is the
 411        //die number divide the die count of chip, the block number is the virtual block number add
 412        //the die block base in the chip, the page number is same as the virtual page number
 413        tmpBnkNum = tmpDieNum / DIE_CNT_OF_CHIP;
 414        tmpBlkNum = nBlock + (tmpDieNum % DIE_CNT_OF_CHIP) * (BLOCK_CNT_OF_DIE / PLANE_CNT_OF_DIE);
 415        tmpPageNum = nPage;
 416    }
 417
 418    //set the physical operation paramter by the bank number, block number and page number
 419    pPhyPar->BankNum = tmpBnkNum;
 420    pPhyPar->PageNum = tmpPageNum;
 421    pPhyPar->BlkNum = tmpBlkNum;
 422
 423    LOGICCTL_DBG("         Calculate Result: BankNum 0x%x, BlkNum 0x%x, PageNum 0x%x\n", tmpBnkNum, tmpBlkNum, tmpPageNum);
 424
 425    //calculate physical operation parameter successful
 426    return 0;
 427}
 428
 429#endif
 430
 431
 432
 433
 434
 435
 436/*
 437************************************************************************************************************************
 438*                       READ PAGE DATA FROM VIRTUAL BLOCK
 439*
 440*Description: Read page data from virtual block, the block is composed by several physical block.
 441*             It is named super block too.
 442*
 443*Arguments  : pVirtualPage  the pointer to the virtual page paramter;
 444*
 445*Return     : read result;
 446*               = 0     read page data successful;
 447*               < 0     read page data failed.
 448************************************************************************************************************************
 449*/
 450__s32 LML_VirtualPageRead(struct __PhysicOpPara_t *pVirtualPage)
 451{
 452    __s32 i, result;
 453    __u32 tmpBitmap;
 454    __u8  *tmpSpare, *tmpSrcData, *tmpDstData, *tmpSrcPtr[4], *tmpDstPtr[4];
 455    struct __PhysicOpPara_t tmpPhyPage;
 456
 457    tmpPhyPage = *pVirtualPage;
 458    tmpSpare = tmpPhyPage.SDataPtr;
 459    tmpBitmap = tmpPhyPage.SectBitmap;
 460
 461    if(tmpSpare)
 462    {
 463        tmpPhyPage.SDataPtr = LML_SPARE_BUF;
 464
 465        //process the pointer to spare area data
 466        for(i=0; i<2; i++)
 467        {
 468            if(tmpBitmap & (1<<i))
 469            {
 470                tmpSrcPtr[i] = LML_SPARE_BUF + 4 * i;
 471                tmpDstPtr[i] = tmpSpare + 4 * i;
 472            }
 473            else
 474            {
 475                tmpDstPtr[i] = NULL;
 476            }
 477        }
 478
 479        for(i=0; i<2; i++)
 480        {
 481            if(tmpBitmap & (1<<(i + SECTOR_CNT_OF_SINGLE_PAGE)))
 482            {
 483                tmpSrcPtr[i+2] = LML_SPARE_BUF + 4 * (i + SECTOR_CNT_OF_SINGLE_PAGE);
 484                tmpDstPtr[i+2] = tmpSpare + 8 + 4 * i;
 485            }
 486            else
 487            {
 488                tmpDstPtr[i+2] = NULL;
 489            }
 490        }
 491    }
 492    else
 493    {
 494        tmpPhyPage.SDataPtr = NULL;
 495    }
 496
 497    result = PHY_PageRead(&tmpPhyPage);
 498
 499    //process spare area data
 500    if(tmpSpare)
 501    {
 502        //get the spare area data
 503        for(i=0; i<4; i++)
 504        {
 505            if(tmpDstPtr[i] != NULL)
 506            {
 507                tmpSrcData = tmpSrcPtr[i];
 508                tmpDstData = tmpDstPtr[i];
 509
 510                *tmpDstData++ = *tmpSrcData++;
 511                *tmpDstData++ = *tmpSrcData++;
 512                *tmpDstData++ = *tmpSrcData++;
 513                *tmpDstData++ = *tmpSrcData++;
 514            }
 515        }
 516    }
 517
 518	//add in 2010-05-21 by penggang, the logic layer needn't care the ecc error
 519	if(result == -ERR_ECC)
 520		result = 0;
 521
 522    return result;
 523}
 524
 525
 526/*
 527************************************************************************************************************************
 528*                       WRITE PAGE DATA TO VIRTUAL BLOCK
 529*
 530*Description: Write page data to virtual block, the block is composed by several physical block.
 531*             It is named super block too.
 532*
 533*Arguments  : pVirtualPage  the pointer to the virtual page parameter.
 534*
 535*Return     : write result;
 536*               = 0     write page data successful;
 537*               < 0     write page data failed.
 538************************************************************************************************************************
 539*/
 540__s32 LML_VirtualPageWrite( struct __PhysicOpPara_t *pVirtualPage)
 541{
 542    __s32 i, result;
 543    __u32 tmpBitmap;
 544    __u8  *tmpSpare, *tmpSrcData, *tmpDstData, *tmpSrcPtr[4], *tmpDstPtr[4];
 545    struct __PhysicOpPara_t tmpPhyPage;
 546
 547    tmpPhyPage = *pVirtualPage;
 548    tmpSpare = tmpPhyPage.SDataPtr;
 549    //tmpBitmap = tmpPhyPage.SectBitmap;
 550    tmpBitmap = FULL_BITMAP_OF_LOGIC_PAGE;
 551    tmpPhyPage.SDataPtr = LML_SPARE_BUF;
 552
 553    //process spare area data
 554    if(tmpSpare)
 555    {
 556        //process the pointer to spare area data
 557        for(i=0; i<2; i++)
 558        {
 559            if(tmpBitmap & (1<<i))
 560            {
 561                tmpSrcPtr[i] = tmpSpare + 4 * i;
 562                tmpDstPtr[i] = LML_SPARE_BUF + 4 * i;
 563            }
 564            else
 565            {
 566                tmpDstPtr[i] = NULL;
 567            }
 568        }
 569
 570        for(i=0; i<2; i++)
 571        {
 572            if(tmpBitmap & (1<<(i + SECTOR_CNT_OF_SINGLE_PAGE)))
 573            {
 574                tmpSrcPtr[i+2] = tmpSpare + 8 + 4 * i;
 575                tmpDstPtr[i+2] = LML_SPARE_BUF + 4 * (i + SECTOR_CNT_OF_SINGLE_PAGE);
 576            }
 577            else
 578            {
 579                tmpDstPtr[i+2] = NULL;
 580            }
 581        }
 582
 583        MEMSET(LML_SPARE_BUF, 0xff, SECTOR_CNT_OF_SUPER_PAGE * 4);
 584
 585        for(i=0; i<4; i++)
 586        {
 587            tmpSrcData = tmpSrcPtr[i];
 588            tmpDstData = tmpDstPtr[i];
 589
 590            if(tmpDstData != NULL)
 591            {
 592                *tmpDstData++ = *tmpSrcData++;
 593                *tmpDstData++ = *tmpSrcData++;
 594                *tmpDstData++ = *tmpSrcData++;
 595                *tmpDstData++ = *tmpSrcData++;
 596            }
 597        }
 598    }
 599    else
 600    {
 601        MEMSET(LML_SPARE_BUF, 0xff, SECTOR_CNT_OF_SUPER_PAGE * 4);
 602    }
 603
 604    result = PHY_PageWrite(&tmpPhyPage);
 605
 606    return result;
 607}
 608
 609
 610/*
 611************************************************************************************************************************
 612*                       NAND FLASH LOGIC MANAGE LAYER ERASE SUPER BLOCK
 613*
 614*Description: Erase the given super block.
 615*
 616*Arguments  : nZone         the number of the zone which the super block belonged to;
 617*             nSuperBlk     the number of the super block which need be erased.
 618*
 619*Return     : erase result
 620*               = 0     super block erase successful;
 621*               =-1     super block erase failed.
 622************************************************************************************************************************
 623*/
 624__s32 LML_VirtualBlkErase(__u32 nZone, __u32 nSuperBlk)
 625{
 626    __s32 i, result = 0;
 627    struct __PhysicOpPara_t tmpPhyBlk;
 628
 629    #if CFG_SUPPORT_WEAR_LEVELLING
 630
 631    //increase the erase counter of super block
 632    BLK_ERASE_CNTER++;
 633
 634    #endif
 635    //erase every block belonged to different banks
 636    for(i=0; i<INTERLEAVE_BANK_CNT; i++)
 637    {
 638        //calculate the physical operation parameter by te die number, block number and page number
 639        LML_CalculatePhyOpPar(&tmpPhyBlk, nZone, nSuperBlk, i);
 640
 641        PHY_BlockErase(&tmpPhyBlk);
 642    }
 643
 644    //check the result of the block erase
 645    for(i=0; i<INTERLEAVE_BANK_CNT; i++)
 646    {
 647        result = PHY_SynchBank(i, SYNC_BANK_MODE);
 648        if(result < 0)
 649        {
 650        	//the operation of last page write is failed
 651            LOGICCTL_ERR("[LOGICCTL_DBG] erase zone %x block %x bank %x fail\n",
 652            				nZone,nSuperBlk,i);
 653
 654            return -1;
 655        }
 656    }
 657
 658    return 0;
 659}
 660
 661
 662/*
 663************************************************************************************************************************
 664*                       LOGICAL MANAGE LAYER CLOSE WRITE PAGE
 665*
 666*Description: Close last write page, for switch nand flash operation mode.
 667*
 668*Arguments  : none.
 669*
 670*Return     : clase page result;
 671*               = 0     close page successful;
 672*               = -1    close page failed.
 673************************************************************************************************************************
 674*/
 675static __s32 _CloseWritePage(void)
 676{
 677    __s32 result;
 678    struct __PhysicOpPara_t tmpPage;
 679    struct __LogBlkType_t tmpLogBlk;
 680
 681    //check if current mode is write mode
 682    if(LogicalCtl.OpMode == 'w')
 683    {
 684        //calculate the paramter of last page
 685        LML_CalculatePhyOpPar(&tmpPage, LogicalCtl.ZoneNum, LogicalCtl.LogBlkNum.PhyBlkNum, LogicalCtl.LogPageNum);
 686
 687        result = PHY_SynchBank(tmpPage.BankNum, SYNC_BANK_MODE);
 688        if(result < 0)
 689        {
 690            //the operation of last page write is failed
 691            LOGICCTL_DBG("[LOGICCTL_DBG] Write page failed when close write page! Bnk:0x%x, Blk:0x%x, Page:0x%x\n",
 692                            tmpPage.BankNum, tmpPage.BlkNum, tmpPage.PageNum);
 693
 694            //process the bad block
 695            result = LML_BadBlkManage(&LogicalCtl.LogBlkNum, LogicalCtl.ZoneNum, LogicalCtl.LogPageNum + 1, &LogicalCtl.LogBlkNum);
 696            if(result < 0)
 697            {
 698                LOGICCTL_ERR("[LOGICCTL_ERR] Bad block proecess failed when close write page, Err:0x%x\n", result);
 699                return -1;
 700            }
 701
 702            //reset the physical block number of the log block with the new log block
 703            BMM_GetLogBlk(LogicalCtl.LogicBlkNum, &tmpLogBlk);
 704            tmpLogBlk.PhyBlk = LogicalCtl.LogBlkNum;
 705            BMM_SetLogBlk(LogicalCtl.LogicBlkNum, &tmpLogBlk);
 706        }
 707
 708        //wait the nand flash chip ready
 709        PHY_SynchBank(tmpPage.BankNum, SYNC_CHIP_MODE);
 710    }
 711
 712    LogicalCtl.OpMode = 'n';
 713
 714    return 0;
 715}
 716
 717
 718/*
 719************************************************************************************************************************
 720*                       NAND FLASH LOGIC MANAGE LAYER PAGE READ
 721*
 722*Description: Read data from logic disk to buffer based page.
 723*
 724*Arguments  : nPage     the page address which need be read;
 725*             nBitmap   the bitmap of the sectors in the page which need be read data;
 726*             pBuf      the pointer to the buffer where will store the data read out.
 727*
 728*Return     : page read result;
 729*               = 0     read successful;
 730*               > 0     read successful, but need do some process;
 731*               < 0     read failed.
 732************************************************************************************************************************
 733*/
 734__s32 LML_PageRead(__u32 nPage, __u32 nBitmap, void* pBuf)
 735{
 736    __s32 result;
 737    __u32 tmpSuperBlk, tmpSuperPage;
 738    struct __LogicPageType_t tmpLogicPage;
 739    struct __PhysicOpPara_t tmpPhyPage;
 740    struct __LogBlkType_t tmpLogBlk;
 741
 742    _CalculateLogicPagePar(&tmpLogicPage, nPage, nBitmap);
 743
 744    //check if last operation is read, if not, need set to read mode
 745    if(LogicalCtl.OpMode != 'r')
 746    {
 747        if(LogicalCtl.OpMode == 'w')
 748        {
 749            //last operation is write, need close last write logical page, switch to read mode
 750            result = _CloseWritePage();
 751            if(result < 0)
 752            {
 753                LOGICCTL_ERR("[LOGICCTL_ERR] Close write page failed, when read logical page!\n");
 754                return -ERR_LOGICCTL;
 755            }
 756        }
 757
 758        //set operation mode to read
 759        LogicalCtl.OpMode = 'r';
 760    }
 761
 762    //check if access the same zone area as last access
 763    if(tmpLogicPage.ZoneNum != LogicalCtl.ZoneNum)
 764    {
 765        //swap the block mapping table to ram which is need be accessing currently
 766        result = BMM_SwitchMapTbl(tmpLogicPage.ZoneNum);
 767        if(result < 0)
 768        {
 769            LOGICCTL_ERR("[LOGICCTL_ERR] Switch block mapping table failed when read logical page! Err:0x%x\n", result);
 770            return -ERR_MAPPING;
 771        }
 772
 773        //set the zone number that accessing currently
 774        LogicalCtl.ZoneNum = tmpLogicPage.ZoneNum;
 775        //reset the number of logical block
 776        LogicalCtl.LogicBlkNum = 0xffff;
 777    }
 778
 779    //check if accessing the same logical block as last access
 780    if(tmpLogicPage.BlockNum != LogicalCtl.LogicBlkNum)
 781    {
 782        //get the data block number and log block number for read
 783        BMM_GetDataBlk(tmpLogicPage.BlockNum, &LogicalCtl.DataBlkNum);
 784
 785        BMM_GetLogBlk(tmpLogicPage.BlockNum, &tmpLogBlk);
 786        LogicalCtl.LogBlkNum = tmpLogBlk.PhyBlk;
 787
 788        //set the logical block number for logical control parameter
 789        LogicalCtl.LogicBlkNum = tmpLogicPage.BlockNum;
 790    }
 791
 792    //set the number for logical page that accessing currently
 793    LogicalCtl.LogicPageNum = tmpLogicPage.PageNum;
 794
 795    //get the number of log page for read
 796    if(LogicalCtl.LogBlkNum.PhyBlkNum != 0xffff)
 797    {
 798        //get log page with read mode
 799        LogicalCtl.LogPageNum = PMM_GetLogPage(tmpLogicPage.BlockNum, LogicalCtl.LogicPageNum, 'r');
 800    }
 801    else
 802    {
 803        LogicalCtl.LogPageNum = 0xffff;
 804    }
 805
 806    //set the number of super block and super page in the super block for get page data
 807    if(LogicalCtl.LogPageNum != 0xffff)
 808    {
 809        tmpSuperBlk = LogicalCtl.LogBlkNum.PhyBlkNum;
 810        tmpSuperPage = LogicalCtl.LogPageNum;
 811    }
 812    else
 813    {
 814        tmpSuperBlk = LogicalCtl.DataBlkNum.PhyBlkNum;
 815        tmpSuperPage = LogicalCtl.LogicPageNum;
 816    }
 817
 818    //calculate the parameter of physical operation for get page data
 819    LML_CalculatePhyOpPar(&tmpPhyPage, LogicalCtl.ZoneNum, tmpSuperBlk, tmpSuperPage);
 820    tmpPhyPage.SectBitmap = tmpLogicPage.SectBitmap;
 821    tmpPhyPage.MDataPtr = pBuf;
 822    tmpPhyPage.SDataPtr = NULL;
 823
 824    //get data from physical page with the physical operation
 825    result = LML_VirtualPageRead(&tmpPhyPage);
 826    if(result < 0)
 827    {
 828        LOGICCTL_ERR("[LOGICCTL_ERR] Get page data failed when read logical page! Err:0x%x\n ", result);
 829        return -1;
 830    }
 831
 832    return result;
 833}
 834
 835
 836/*
 837************************************************************************************************************************
 838*                       NAND FLASH LOGIC MANAGE LAYER PAGE WRITE
 839*
 840*Description: Write data from buffer to logic area based on page.
 841*
 842*Arguments  : nPage     the page address which need be write;
 843*             nBitmap   the bitmap of sectors in the page which need be write, it is always full;
 844*             pBuf      the pointer to the buffer where is storing the data.
 845*
 846*Return     : write result;
 847*               = 0     write successful;
 848*               > 0     write successful, but need do some process;
 849*               < 0     write failed.
 850************************************************************************************************************************
 851*/
 852__s32 LML_PageWrite(__u32 nPage, __u32 nBitmap, void* pBuf)
 853{
 854    __s32 result;
 855    struct __LogicPageType_t tmpLogicPage;
 856    struct __PhysicOpPara_t tmpPhyPage;
 857    struct __NandUserData_t tmpSpare[2];
 858    struct __LogBlkType_t tmpLogBlk;
 859
 860
 861    //check if the bitmap of valid sectors is full, if not, report error
 862    if(nBitmap != FULL_BITMAP_OF_LOGIC_PAGE)
 863    {
 864        LOGICCTL_ERR("[LOGICCTL_ERR] Sector bitmap is not full when write logical page!\n");
 865        return -ERR_LOGICCTL;
 866    }
 867
 868    //calculate the pamater for the logical page
 869    _CalculateLogicPagePar(&tmpLogicPage, nPage, nBitmap);
 870
 871    //check if access the same zone area as last access
 872    if(tmpLogicPage.ZoneNum != LogicalCtl.ZoneNum)
 873    {
 874        //last operation is write, need close last write logical page, switch to read mode
 875        result = _CloseWritePage();
 876        if(result < 0)
 877        {
 878            LOGICCTL_ERR("[LOGICCTL_ERR] Close write page failed, when write logical page!\n");
 879            return -ERR_LOGICCTL;
 880        }
 881
 882        //swap the block mapping table to ram which is need be accessing currently
 883        result = BMM_SwitchMapTbl(tmpLogicPage.ZoneNum);
 884        if(result < 0)
 885        {
 886            LOGICCTL_ERR("[LOGICCTL_ERR] Switch block mapping table failed when write logical page! Err:0x%x\n", result);
 887            return -ERR_MAPPING;
 888        }
 889
 890        //set the zone number that accessing currently
 891        LogicalCtl.ZoneNum = tmpLogicPage.ZoneNum;
 892        //reset the number of logical block
 893        LogicalCtl.LogicBlkNum = 0xffff;
 894    }
 895
 896    //set dirty flag for block mapping table
 897    BMM_SetDirtyFlag();
 898
 899    //check if accessing the same logical block as last access
 900    if(tmpLogicPage.BlockNum != LogicalCtl.LogicBlkNum)
 901    {
 902        //last operation is write, need close last write logical page, switch to read mode
 903        result = _CloseWritePage();
 904        if(result < 0)
 905        {
 906            LOGICCTL_ERR("[LOGICCTL_ERR] Close write page failed, when write logical page!\n");
 907            return -ERR_LOGICCTL;
 908        }
 909
 910        //set the logical block number for logical control parameter
 911        LogicalCtl.LogicBlkNum = tmpLogicPage.BlockNum;
 912    }
 913
 914    //set the number of the logical page for logical control
 915    LogicalCtl.LogicPageNum = tmpLogicPage.PageNum;
 916
 917    //get log page for write page data, log page is necessary when write logical page
 918    LogicalCtl.LogPageNum = PMM_GetLogPage(LogicalCtl.LogicBlkNum, LogicalCtl.LogicPageNum, 'w');
 919    if(LogicalCtl.LogPageNum == 0xffff)
 920    {
 921        LOGICCTL_ERR("[LOGICCTL_ERR] Get log page failed when write logical page!\n");
 922        return -ERR_MAPPING;
 923    }
 924
 925    //get the data block number and log block number for write
 926    BMM_GetDataBlk(tmpLogicPage.BlockNum, &LogicalCtl.DataBlkNum);
 927
 928    BMM_GetLogBlk(tmpLogicPage.BlockNum, &tmpLogBlk);
 929    LogicalCtl.LogBlkNum = tmpLogBlk.PhyBlk;
 930
 931
 932    //check if the log block is valid, log block is nessesary necessary when write logical page
 933    if(LogicalCtl.LogBlkNum.PhyBlkNum == 0xffff)
 934    {
 935        LOGICCTL_ERR("[LOGICCTL_ERR] Get log block failed when write logical page!\n");
 936        return -ERR_MAPPING;
 937    }
 938
 939    //set spare area data for writing to the spare area of nand flash
 940    if(LogicalCtl.LogPageNum == 0)
 941    {
 942        //log page is the page0 of the super block, the meaning of the page status is log age
 943        LML_CalculatePhyOpPar(&tmpPhyPage, LogicalCtl.ZoneNum, LogicalCtl.DataBlkNum.PhyBlkNum, 0);
 944        tmpPhyPage.SectBitmap = 0x3;
 945        tmpPhyPage.MDataPtr = LML_TEMP_BUF;
 946        tmpPhyPage.SDataPtr = (void *)tmpSpare;
 947        result = LML_VirtualPageRead(&tmpPhyPage);
 948        if(result < 0)
 949        {
 950            LOGICCTL_ERR("[LOGICCTL_ERR] Get log age of data block failed when write logical page, Err:0x%x!\n", result);
 951            return -ERR_PHYSIC;
 952        }
 953
 954        //increase the log age
 955        tmpSpare[0].PageStatus = tmpSpare[0].PageStatus + 1;
 956        tmpSpare[1].PageStatus = tmpSpare[0].PageStatus;
 957    }
 958    else
 959    {
 960        //set page used mark to the spare area data
 961        tmpSpare[0].PageStatus = 0x55;
 962        tmpSpare[1].PageStatus = 0x55;
 963    }
 964    tmpSpare[0].BadBlkFlag = 0xff;
 965    tmpSpare[1].BadBlkFlag = 0xff;
 966    tmpSpare[0].LogicInfo = ((LogicalCtl.ZoneNum % ZONE_CNT_OF_DIE)<<10) | LogicalCtl.LogicBlkNum;
 967    tmpSpare[1].LogicInfo = ((LogicalCtl.ZoneNum % ZONE_CNT_OF_DIE)<<10) | LogicalCtl.LogicBlkNum;
 968    tmpSpare[0].LogicPageNum = LogicalCtl.LogicPageNum;
 969    tmpSpare[1].LogicPageNum = LogicalCtl.LogicPageNum;
 970
 971__TRY_WRITE_PHYSIC_PAGE:
 972    //calculate the parameter for writing page to nand flash
 973    LML_CalculatePhyOpPar(&tmpPhyPage, LogicalCtl.ZoneNum, LogicalCtl.LogBlkNum.PhyBlkNum, LogicalCtl.LogPageNum);
 974    tmpPhyPage.SectBitmap = tmpLogicPage.SectBitmap;
 975    tmpPhyPage.MDataPtr = pBuf;
 976    tmpPhyPage.SDataPtr = (void *)tmpSpare;
 977
 978    #if !CFG_SUPPORT_CHECK_WRITE_SYNCH
 979
 980	if (LogicalCtl.OpMode == 'w')
 981    {
 982    	//synch currently write bank
 983    	result = PHY_SynchBank(tmpPhyPage.BankNum, SYNC_BANK_MODE);
 984    	if(result < 0)
 985    	{
 986        	//the last write operation on current bank is failed, the block is bad, need proccess it
 987        	LOGICCTL_DBG("[LOGICCTL_DBG] Find a bad block when write logical page! bank:0x%x, block:0x%x, page:0x%x\n",
 988                tmpPhyPage.BankNum, tmpPhyPage.BlkNum, tmpPhyPage.PageNum);
 989
 990        	//process the bad block
 991        	result = LML_BadBlkManage(&LogicalCtl.LogBlkNum, LogicalCtl.ZoneNum, LogicalCtl.LogPageNum, &LogicalCtl.LogBlkNum);
 992        	if(result < 0)
 993        	{
 994            	LOGICCTL_ERR("[LOGICCTL_ERR] Bad block proecess failed when write page, Err:0x%x\n", result);
 995            	return -1;
 996        	}
 997
 998        	//reset the physical block number of the log block with the new log block
 999        	BMM_GetLogBlk(LogicalCtl.LogicBlkNum, &tmpLogBlk);
1000        	tmpLogBlk.PhyBlk = LogicalCtl.LogBlkNum;
1001        	BMM_SetLogBlk(LogicalCtl.LogicBlkNum, &tmpLogBlk);
1002
1003        	goto __TRY_WRITE_PHYSIC_PAGE;
1004    	}
1005    }
1006#endif
1007
1008	 result = LML_VirtualPageWrite(&tmpPhyPage);
1009    if(result < 0)
1010    {
1011        LOGICCTL_ERR("[LOGICCTL_ERR] Physical write module failed when write logical page, Err:0x%x!\n", result);
1012        return -ERR_LOGICCTL;
1013    }
1014
1015#if CFG_SUPPORT_CHECK_WRITE_SYNCH
1016
1017    //synch currently write bank
1018    result = PHY_SynchBank(tmpPhyPage.BankNum, SYNC_BANK_MODE);
1019    if(result < 0)
1020    {
1021        //the last write operation on current bank is failed, the block is bad, need proccess it
1022        LOGICCTL_DBG("[LOGICCTL_DBG] Find a bad block when write logical page! bank:0x%x, block:0x%x, page:0x%x\n",
1023                tmpPhyPage.BankNum, tmpPhyPage.BlkNum, tmpPhyPage.PageNum);
1024
1025        //process the bad block
1026        result = LML_BadBlkManage(&LogicalCtl.LogBlkNum, LogicalCtl.ZoneNum, LogicalCtl.LogPageNum, &LogicalCtl.LogBlkNum);
1027        if(result < 0)
1028        {
1029            LOGICCTL_ERR("[LOGICCTL_ERR] Bad block proecess failed when write page, Err:0x$x\n", result);
1030            return -1;
1031        }
1032
1033        //reset the physical block number of the log block with the new log block
1034        BMM_GetLogBlk(LogicalCtl.LogicBlkNum, &tmpLogBlk);
1035        tmpLogBlk.PhyBlk = LogicalCtl.LogBlkNum;
1036        BMM_SetLogBlk(LogicalCtl.LogicBlkNum, &tmpLogBlk);
1037
1038        goto __TRY_WRITE_PHYSIC_PAGE;
1039    }
1040
1041#endif
1042
1043    //set the mode of operation
1044    LogicalCtl.OpMode = 'w';
1045    return 0;
1046}
1047
1048
1049/*
1050************************************************************************************************************************
1051*                       NAND FLASH LOGIC MANAGE LAYER FLUSH PAGE CACHE
1052*
1053*Description: Flush the data in the cache buffer to nand flash.
1054*
1055*Arguments  : none
1056
1057*Return     : flush result;
1058*               = 0     flush successful;
1059*               = -1    flush failed.
1060************************************************************************************************************************
1061*/
1062__s32 LML_FlushPageCache(void)
1063{
1064    __s32   result;
1065
1066    result = _WritePageCacheToNand();
1067    if(result < 0)
1068    {
1069        LOGICCTL_ERR("[LOGICCTL_ERR] Write page cache to nand failed when flush page cache! Error:0x%x\n", result);
1070        return -1;
1071    }
1072
1073    result = _CloseWritePage();
1074    if(result < 0)
1075    {
1076        LOGICCTL_ERR("[LOGICCTL_ERR] Close write page failed when flush page cache! Error:0x%x\n", result);
1077        return -1;
1078    }
1079
1080    return 0;
1081}
1082
1083
1084/*
1085************************************************************************************************************************
1086*                           NAND FLASH LOGIC MANAGE LAYER READ
1087*
1088*Description: Read data from logic disk area to buffer.
1089*
1090*Arguments  : nSectNum      the logic block address on the logic area from where to read;
1091*             nSectorCnt    the size of the data need be read, based on sector;
1092*             pBuf          the pointer to the buffer where will store the data readout of nand.
1093*
1094*Return     : read result;
1095*               = 0     read successful;
1096*               = -1    read failed.
1097************************************************************************************************************************
1098*/
1099__s32 LML_Read(__u32 nSectNum, __u32 nSectorCnt, void* pBuf)
1100{
1101    __s32   i, result;
1102    __u32   tmpMidPageCnt, tmpPageNum, tmpBitmap, tmpPageCnt;
1103    __u8    *tmpBuf;
1104    struct __GlobalLogicPageType_t tmpHeadPage, tmpTailPage;
1105
1106    LOGICCTL_DBG("[LOGICCTL_DBG] LML_Read, sector number:0x%x, sector cnt:0x%x, Buffer:0x%x\n", nSectNum, nSectorCnt, pBuf);
1107
1108		if(((__u32)pBuf)&0x3)
1109	  {
1110	      LOGICCTL_ERR("[LOGICCTL_ERR] LML_Write, invalid bufaddr: 0x%x \n", (__u32)(pBuf));
1111				return -ERR_ADDRBEYOND;
1112	  }
1113
1114    //check if the parameter is valid
1115    if(((nSectNum + nSectorCnt) > LogicalCtl.DiskCap)||(nSectNum>LogicalCtl.DiskCap-1)||(nSectorCnt>LogicalCtl.DiskCap-1))
1116    {
1117        LOGICCTL_ERR("[LOGICCTL_ERR] LML_Read, the addr of read(start:%x, cnt:%x) is beyond the disk volume %x!!!\n",
1118						nSectNum, nSectorCnt,LogicalCtl.DiskCap);
1119        return -ERR_ADDRBEYOND;
1120    }
1121    if(!nSectorCnt)
1122    {
1123        LOGICCTL_DBG("[WARNING] LML_Read, sector count of read is 0!!!\n");
1124        return 0;
1125    }
1126    //calculate logical parameter of the sectors
1127    _CalculateSectPar(nSectNum, nSectorCnt, &tmpHeadPage, &tmpMidPageCnt, &tmpTailPage);
1128
1129    tmpBuf = pBuf;
1130
1131    //calculate the buffer address for page align
1132    for(i=0; i<SECTOR_CNT_OF_LOGIC_PAGE; i++)
1133    {
1134        if(tmpHeadPage.SectorBitmap & (1<<i))
1135        {
1136            break;
1137        }
1138        tmpBuf -= SECTOR_SIZE;
1139    }
1140
1141    tmpPageNum = tmpHeadPage.LogicPageNum;
1142    tmpBitmap = tmpHeadPage.SectorBitmap;
1143
1144    //calculate the whole count the logical pages
1145    tmpPageCnt = 1 + tmpMidPageCnt;
1146    if(tmpTailPage.SectorBitmap)
1147    {
1148        tmpPageCnt++;
1149    }
1150
1151    for(i=0; i<tmpPageCnt; i++)
1152    {
1153        //read data from the logical page
1154        result = LML_PageRead(tmpPageNum, tmpBitmap, tmpBuf);
1155        if(result < 0)
1156        {
1157            //get page data failed!
1158            LOGICCTL_ERR("[LOGICCTL_ERR] LML_Read, read page data faild! the page number:0x%x, sector bitmap:0x%x, buffer:0x%x, "
1159                    "error number:0x%x\n",tmpPageNum, tmpBitmap, (__u32)tmpBuf, result);
1160            return -1;
1161        }
1162
1163        #if CFG_SUPPORT_READ_RECLAIM
1164        if(result == ECC_LIMIT)
1165        {
1166            LML_ReadReclaim(tmpPageNum);
1167        }
1168        #endif
1169
1170        //check if need update the page data with the cache page
1171        if(tmpPageNum == CachePage.LogicPageNum)
1172        {
1173            _UpdateReadPageData(tmpBitmap, tmpBuf);
1174        }
1175
1176        //increase the logical page number and the buffer address
1177        tmpPageNum++;
1178        tmpBuf += SECTOR_SIZE * SECTOR_CNT_OF_LOGIC_PAGE;
1179
1180        //check if read data from the tail page
1181        if(tmpTailPage.SectorBitmap && (i == tmpPageCnt - 2))
1182        {
1183            tmpBitmap = tmpTailPage.SectorBitmap;
1184        }
1185        else
1186        {
1187            tmpBitmap = FULL_BITMAP_OF_LOGIC_PAGE;
1188        }
1189    }
1190
1191    return 0;
1192}
1193EXPORT_SYMBOL(LML_Read);
1194
1195/*
1196extern dump(void * buf, __u32 len, __u8 nbyte, __u8 linelen);
1197
1198void echo_write_data (__u32 nSectNum, __u32 nSectorCnt, void* pBuf)
1199{
1200	__u32 i,j;
1201	__u8 *buf;
1202
1203	for (i = 0,j = nSectNum; i < nSectorCnt; i++,j++)
1204	{
1205		buf = (__u8 *)pBuf + i*512;
1206		PRINT("***********echo data from sector %d***************\n",j);
1207		dump(buf, 16,1, 16);
1208	}
1209
1210	return;
1211
1212}*/
1213
1214/*
1215************************************************************************************************************************
1216*                           NAND FLASH LOGIC MANAGE LAYER WRITE
1217*
1218*Description: Write data from buffer to logic disk area.
1219*
1220*Arguments  : nSectNum      the logic block address on the logic area from where to write;
1221*             nSectorCnt    the size of the data need to be write, based on sector;
1222*             pBuf          the pointer to the buffer where stored the data write to nand flash.
1223*
1224*Return     : write result;
1225*               = 0     write successful;
1226*               = -1    write failed.
1227************************************************************************************************************************
1228*/
1229__s32 LML_Write(__u32 nSectNum, __u32 nSectorCnt, void* pBuf)
1230{
1231    __s32   i, result;
1232    __u32   tmpMidPageCnt, tmpPageNum, tmpBitmap, tmpPageCnt;
1233    __u8    *tmpBuf;
1234    struct __GlobalLogicPageType_t tmpHeadPage, tmpTailPage;
1235
1236	 	if(((__u32)pBuf)&0x3)
1237	  {
1238	      LOGICCTL_ERR("[LOGICCTL_ERR] LML_Write, invalid bufaddr: 0x%x \n", (__u32)(pBuf));
1239				return -ERR_ADDRBEYOND;
1240	  }
1241
1242    if(((nSectNum + nSectorCnt) > LogicalCtl.DiskCap)||(nSectNum>LogicalCtl.DiskCap-1)||(nSectorCnt>LogicalCtl.DiskCap-1))
1243    {
1244        LOGICCTL_ERR("[LOGICCTL_ERR] LML_Write, the addr of write(start:%x, cnt:%x) is beyond the disk volume %x!!!\n",
1245						nSectNum, nSectorCnt,LogicalCtl.DiskCap);
1246				return -ERR_ADDRBEYOND;
1247    }
1248    if(!nSectorCnt)
1249    {
1250        LOGICCTL_DBG("[WARNING] LML_Write, sector count of write is 0!!!\n");
1251        return 0;
1252    }
1253    //calculate the logical parameter for the sectors
1254    _CalculateSectPar(nSectNum, nSectorCnt, &tmpHeadPage, &tmpMidPageCnt, &tmpTailPage);
1255
1256    tmpBuf = pBuf;
1257
1258    //calculate the buffer address for page align
1259    for(i=0; i<SECTOR_CNT_OF_LOGIC_PAGE; i++)
1260    {
1261        if(tmpHeadPage.SectorBitmap & (1<<i))
1262        {
1263            break;
1264        }
1265        tmpBuf -= SECTOR_SIZE;
1266    }
1267
1268    tmpPageNum = tmpHeadPage.LogicPageNum;
1269    tmpBitmap = tmpHeadPage.SectorBitmap;
1270
1271    //calculate the whole count the logical pages
1272    tmpPageCnt = 1 + tmpMidPageCnt;
1273    if(tmpTailPage.SectorBitmap)
1274    {
1275        tmpPageCnt++;
1276    }
1277
1278    for(i=0; i<tmpPageCnt; i++)
1279    {
1280        //check if current write page is same as the cached page
1281        if(tmpPageNum == CachePage.LogicPageNum)
1282        {
1283            //merge current page data with the cached page
1284            _MergeCachePageData(tmpPageNum, tmpBitmap, tmpBuf);
1285        }
1286        else
1287        {
1288            //flush cached page to nand flash
1289            result = _WritePageCacheToNand();
1290            if(result < 0)
1291            {
1292                LOGICCTL_ERR("[LOGICCTL_ERR] Write page cache to nand flash failed!\n");
1293                return -1;
1294            }
1295
1296            if(tmpBitmap == FULL_BITMAP_OF_LOGIC_PAGE)
1297            {
1298                //write the full page to nand flash
1299                result = LML_PageWrite(tmpPageNum, tmpBitmap, tmpBuf);
1300                if(result < 0)
1301                {
1302                    LOGICCTL_ERR("[LOGICCTL_ERR] Write logical page failed! Error:0x%x\n", result);
1303                    return -1;
1304                }
1305            }
1306            else
1307            {
1308                //write page is not full, merge the data to page cache
1309                _MergeCachePageData(tmpPageNum, tmpBitmap, tmpBuf);
1310            }
1311        }
1312
1313        //increase the logical page number and the buffer address
1314        tmpPageNum++;
1315        tmpBuf += SECTOR_SIZE * SECTOR_CNT_OF_LOGIC_PAGE;
1316
1317        //reset the sector bitmap in the logical page
1318        if(tmpTailPage.SectorBitmap && (i == tmpPageCnt - 2))
1319        {
1320            tmpBitmap = tmpTailPage.SectorBitmap;
1321        }
1322        else
1323        {
1324            tmpBitmap = FULL_BITMAP_OF_LOGIC_PAGE;
1325        }
1326    }
1327	 return 0;
1328}
1329EXPORT_SYMBOL(LML_Write);
1330
1331
1332/*
1333************************************************************************************************************************
1334*                           INITIATE NAND FLASH LOGIC MANAGE LAYER
1335*
1336*Description: initiate the logic manage layer for nand flash driver.
1337*
1338*Arguments  : none;
1339*
1340*Return     : intiate result;
1341*               = 0     init successful;
1342*               = -1    init failed.
1343************************************************************************************************************************
1344*/
1345__s32 LML_Init(void)
1346{
1347    __s32   result;
1348
1349    CachePage.LogicPageNum = 0xffffffff;
1350    CachePage.SectorBitmap = 0x00000000;
1351
1352    LogicalCtl.OpMode = 'n';
1353    LogicalCtl.ZoneNum = 0xff;
1354    LogicalCtl.LogicBlkNum = 0xffff;
1355    LogicalCtl.LogicPageNum = 0xffff;
1356    LogicalCtl.LogPageNum = 0xffff;
1357    LogicalCtl.DataBlkNum.BlkEraseCnt = 0xffff;
1358    LogicalCtl.DataBlkNum.PhyBlkNum = 0xffff;
1359    LogicalCtl.LogBlkNum.BlkEraseCnt = 0xffff;
1360    LogicalCtl.LogBlkNum.PhyBlkNum = 0xffff;
1361    LogicalCtl.DiskCap = SECTOR_CNT_OF_SINGLE_PAGE * PAGE_CNT_OF_PHY_BLK * BLOCK_CNT_OF_DIE * \
1362            DIE_CNT_OF_CHIP * NandDriverInfo.NandStorageInfo->ChipCnt  / BLOCK_CNT_OF_ZONE * DATA_BLK_CNT_OF_ZONE;
1363
1364
1365    //request page buffer for process data
1366    NandDriverInfo.PageCachePool->PageCache1 = (__u8 *)MALLOC(SECTOR_CNT_OF_LOGIC_PAGE * SECTOR_SIZE);
1367    if(!NandDriverInfo.PageCachePool->PageCache1)
1368    {
1369        LOGICCTL_ERR("[LOGICCTL_ERR] Request memory for nand flash page cache failed!!");
1370        return -ERR_MALLOC;
1371    }
1372    NandDriverInfo.PageCachePool->PageCache2 = NULL;
1373
1374    //request buffer for process spare area data
1375    MEMSET(LML_SPARE_BUF, 0xff, SECTOR_CNT_OF_SUPER_PAGE * 4);
1376
1377    //init the mapping tabel manage module
1378    result = BMM_InitMapTblCache();
1379    if(result < 0)
1380    {
1381        LOGICCTL_ERR("[LOGICCTL_ERR] Init the mapping table manage module failed! Err:0x%x\n", result);
1382        return -ERR_MAPPING;
1383    }
1384
1385    result = PMM_InitMapTblCache();
1386    if(result < 0)
1387    {
1388        LOGICCTL_ERR("[LOGICCTL_ERR] Init the mapping table manage module failed! Err:0x%x\n", result);
1389        return -ERR_MAPPING;
1390    }
1391
1392    return 0;
1393}
1394
1395
1396/*
1397************************************************************************************************************************
1398*                           NAND FLASH LOGIC MANAGE LAYER EXIT
1399*
1400*Description: exit nand flash logic manage layer.
1401*
1402*Arguments  : none;
1403*
1404*Return     : exit result;
1405*               = 0     exit successfu;
1406*               = -1    exit failed.
1407************************************************************************************************************************
1408*/
1409__s32 LML_Exit(void)
1410{
1411     //flush page cache to nand flash
1412    LML_FlushPageCache();
1413
1414    //write all ma

Large files files are truncated, but you can click here to view the full file