⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdi_recl.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 C
📖 第 1 页 / 共 5 页
字号:
       * count is < the wear leveling limit
       */
      if ((most_erased_count - least_erased_count) > WEARLEVELING_LIMIT)

      #endif /* DATA_STREAM */
      {
         /* assign the reclaim block number to be the least erased block */
         RECL_ReclaimBlock = this_blk.physical_block;
         SEM_MTX_WAIT(SEM_BlockTable);     /* wait for block table access */
         for (block.logical = 0; block.logical < MAX_DATA_BLOCKS;
            block.logical++)
         {
            if (FDI_LogicalBlockTable[block.logical].physical_block_number ==
               RECL_ReclaimBlock)
            {
               this_blk.logical_block = block.logical;
               break;
            }
         }
         SEM_MTX_POST(SEM_BlockTable);

#ifdef TEST_MSGS
         logMsg("WEARLEVELING LIMIT REACHED, least %d, most %d, reclaim %d\n",
                (WORD) least_erased_count, (WORD) most_erased_count,
                RECL_ReclaimBlock, 0, 0, 0);
#endif                                 /* TEST_MSGS */
      }
      /* ELSE did not meet the WEARLEVELING_LIMIT value */
      else
      {
         /* initialize the dirtiest block count to ZERO */
         reclaim.this_count = 0;
         this_blk.logical_block = 0;
         SEM_MTX_WAIT(SEM_BlockTable); /* wait for block table access */
         RECL_ReclaimBlock = FDI_LogicalBlockTable[0].physical_block_number;

         /* DO FOR each block in logical block table */
         for (block.logical = 0; block.logical < MAX_DATA_BLOCKS;
              block.logical++)
         {
            /*
             * read the dirty space field in the logical block table IF the
             * dirty space > the dirtiest block count THEN assign the dirtiest
             * count to the block's dirty_space and assign the
             * RECL_ReclaimBlock to the physical block number
             */
#if (DATA_STREAM == TRUE)
            if ((FDI_LogicalBlockTable[block.logical].dirty_space != 0) &&
                (reclaim.this_count <
                 FDI_LogicalBlockTable[block.logical].dirty_space))
            {
               reclaim.this_count =
                FDI_LogicalBlockTable[block.logical].dirty_space;
               RECL_ReclaimBlock =
                FDI_LogicalBlockTable[block.logical].physical_block_number;

               /* save the reclaim block's logical block number */
               this_blk.logical_block = block.logical;
            }                          /* ENDIF count > dirty_space */
#else
            if ((FDI_LogicalBlockTable[block.logical].dirty_space != 0) &&
                (reclaim.this_count <
                 (FDI_LogicalBlockTable[block.logical].dirty_space +
                  FDI_LogicalBlockTable[block.logical].free_space)))
            {
               reclaim.this_count =
                FDI_LogicalBlockTable[block.logical].free_space +
                FDI_LogicalBlockTable[block.logical].dirty_space;
               RECL_ReclaimBlock =
                FDI_LogicalBlockTable[block.logical].physical_block_number;

               /* save the reclaim block's logical block number */
               this_blk.logical_block = block.logical;
            }                          /* ENDIF count > dirty_space */
#endif
         }                             /* ENDDO FOR each logical block */
         SEM_MTX_POST(SEM_BlockTable); /* finished with block table access */
      }                                /* #ENDIF WEARLEVELING not enabled */
      /*
       * We now have the first addresses of the reclaim block and the spare
       * block
       */
      /* Check to make sure a reclaim really needs to occur. If not, state */
      /* reclaim done and return */
      if (((most_erased_count - least_erased_count) < WEARLEVELING_LIMIT) &&
          (reclaim.this_count == 0))
      {
#ifdef TEST_MSGS
         logMsg("reclaim done, Nothing to reclaim\n", 0, 0, 0, 0, 0, 0);
#endif
         RECL_ReclaimBlock = WORDMAX;
         RECL_SetState(RECL_DONE);
         SEM_POST(RECL_Done);
         continue;
      }


      SEM_MTX_WAIT(SEM_ReclaimInProg); /* Take the ReclaimInProg semaphore */
      /* assign reclaim_addr the first address of the RECL_ReclaimBlock */
      Rip.reclaim_block_addr = BLOCK_ADDRESS(RECL_ReclaimBlock);

      /* assign spare_addr the first address of the FDI_SpareBlock */
      Rip.spare_block_addr = BLOCK_ADDRESS(FDI_SpareBlock);
      RECL_SetState(RECL_BLK_FOUND);   /* state flag */


      /* write the spare block's block information status field to 'recover' */
      block.status = BLK_RECOVER;      /* set the status to 'recover' */
      errors = FlashDevWrite(&block.status,
                             Rip.spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, status),
                             mFDI_MemberSize(BLOCK_INFO, status));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30030000 */);
         break;
      }
      RECL_SetState(RECL_RECOVERING);  /* state flag */

      /* Write BLOCK_INTEGRITY word to the last address in the spare block */

      /* write the spare block's block information current_state field */
      block.state = BLOCK_INTEGRITY;   /* set the current_state */
      errors = FlashDevWrite((BYTE_PTR) & block.state,
                             Rip.spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, current_state),
                             mFDI_MemberSize(BLOCK_INFO, current_state));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30040000 */);
         break;
      }
      /*
       * Read the erase count from the parameter system and write this to the
       * spare block's erase count field in BLOCK_INFO
       */
      /*
       * read the erase_count of the spare block as data identifier
       * NUM_IDENTIFIERS, increment the erase_count and then write into the
       * block information structure.
       */
      errors = ReadModify((BYTE_PTR) & reclaim.this_count,
               (DWORD_PTR)&block.actual, 0, sizeof(DWORD), ERASE_COUNT_ID,
               ERASE_COUNT_TYPE, 1, READ_DATA);
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30050000 */);
         break;
      }

      errors = FlashDevWrite((BYTE_PTR) & reclaim.this_count,
                             Rip.spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, erase_count),
                             mFDI_MemberSize(BLOCK_INFO, erase_count));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30060000 */);
         break;
      }
      /*
       * initialize spare_free to sizeof the block minus the size of the block
       * information structure
       */
      Rip.spare_free = ((BOTTOM_OF_UNITS - sizeof(UNIT_HEADER)) -
         FIRST_HEADER_OFFSET);
      Rip.spare_dirty = 0;
      /* reset the recl_header_mask to zeros */
      MemorySet(Rip.recl_header_mask, 0, HDR_MASK_SIZE);
      /* initialize spare_header_offset and reclaim_header_offset to zero */
      Rip.reclaim_header_offset = FIRST_HEADER_OFFSET;
      Rip.spare_header_offset = FIRST_HEADER_OFFSET;
      reclaim_unit_offset = 0;
      /*
       * initialize spare_unit_offset to block size - sizeof the block
       * information structure
       */
      spare_unit_offset = BOTTOM_OF_UNITS;
      /*
       * Scan through each unit header in the reclaim block and transfer only
       * the valid headers and units to the spare block
       */
      Rip.recl_in_prog_flag = TRUE;
      /*
       * DO WHILE there are unit headers to read, copy only valid headers from
       * the reclaim block to the spare
       */

#if (PACKET_DATA == TRUE)
      tag_index = WORDMAX;  /* initialization */
#endif /* PACKET_DATA */

      SEM_MTX_POST(SEM_ReclaimInProg); /* Give the ReclaimInProg semaphore */
      do
      {
         SEM_MTX_WAIT(SEM_ReclaimInProg); /* Take the ReclaimInProg semaphore*/
         /* read the next unit header in the reclaim block */
         errors = FlashDevRead((BYTE_PTR) & header,
                               Rip.reclaim_block_addr +
                               Rip.reclaim_header_offset,
                               sizeof(UNIT_HEADER));
         if (errors != HW_ERR_NONE)
         {
            FDI_HandleError(errors/* | 0x30070000 */);
            break;
         }
         if (!HDR_STATE(HDR_EMPTY, header.status))
         {
            /* IF the unit header status is valid */
            if (!INVALID_HDR(header.status))
            {
               setBitMask(Rip.recl_header_mask,
                          (Rip.reclaim_header_offset / sizeof(UNIT_HEADER)));
               /* save the reclaim block's unit offset */
               reclaim_unit_offset = BOTTOM_OF_UNITS -
                TO_BYTES(header.g_unit_offset_bottom);

               /* reclaim unit size in bytes */
               reclaim.unit_size = TO_BYTES(header.g_unit_size);

               /* calculate location of unit in spare block */
               spare_unit_offset -= (reclaim.unit_size);

               /* copy spare_unit_offset into the unit header */
               header.g_unit_offset_bottom = (WORD)((BOTTOM_OF_UNITS -
                                       spare_unit_offset) / UNIT_GRANULARITY);

               SEM_MTX_WAIT(SEM_WriteInProg); /* pend on writes in progress */
               /* write the unit header fields to the spare block */
               errors = FlashDevWrite((BYTE_PTR) & header,
                                      Rip.spare_block_addr +
                                      Rip.spare_header_offset,
                                      sizeof(UNIT_HEADER));
               if (errors != HW_ERR_NONE)
               {
                  FDI_HandleError(errors/* | 0x30080000 */);
                  break;
               }
               /*
                * copy the unit from the reclaim block to the spare block at
                * the new unit_offset value
                */
               errors = FlashDevCopy(Rip.spare_block_addr +
                                     spare_unit_offset,
                                     Rip.reclaim_block_addr +
                                     reclaim_unit_offset,
                                     reclaim.unit_size);
               if (errors != HW_ERR_NONE)
               {
                  FDI_HandleError(errors/* | 0x30090000 */);
                  break;
               }
#if (PACKET_DATA == TRUE)
               if ((header.type_attribute & ATTRIBUTE_MASK) == ATTR_DATA_FRAG
                   && header.identifier == FDI_Pckt.ID
                   && (NIBBLE_HIGH(header.type_attribute)) == FDI_Pckt.type)
               {
                   DWORD  temp_new_address, temp_old_address;
                  /*
                   * compute out the physical addresses of the begining of the
                   * data fragments in reclaiming block and spare block
                   */
                  temp_new_address = Rip.spare_block_addr + spare_unit_offset +
                                     FLASH_START_ADDRESS;
                  temp_old_address = Rip.reclaim_block_addr +
                                     reclaim_unit_offset +
                                     FLASH_START_ADDRESS;

                  if (tag_index == WORDMAX) /* the first time need to scan */
                     tag_index = 0;
                  else
                     tag_index ++;

                  while (tag_index < FDI_Pckt.Count)
                  {
                     if (FDI_Pckt.TagRAMp[tag_index] ==
                         (WORD_PTR)temp_old_address)
                        break;
                     tag_index ++;
                  }

 #ifdef TEST_MSGS
                  logMsg("\nTag-RAM UPDATED, tag-entry: %X, new-offset:%X",
                         tag_index, temp_new_address, 0, 0, 0, 0);
 #endif /* TEST_MSGS */

                  if (tag_index < FDI_Pckt.Count) /* update the entry */
                     FDI_Pckt.TagRAMp[tag_index] = (WORD_PTR)temp_new_address;
                  else /* if no matched in Tag-RAM, report an error */
                  {
                     errors = HW_ERR_SYSTEM;
                     FDI_HandleError(errors);
                     break;
                  }
               }
#endif /* PACKET_DATA */

               SEM_MTX_POST(SEM_WriteInProg); /* finished blocking writes */
               /* subt spare block's free space by unit header and unit_size */
               Rip.spare_free -= (WORD) (sizeof(UNIT_HEADER) +
                                         reclaim.unit_size);
               /*
                * increment spare block's unit header offset by sizeof unit
                * header
                */
               Rip.spare_header_offset += sizeof(UNIT_HEADER);
            }                          /* ENDIF unit header status is valid */
            /* inc reclaim block's unit header offset by sizeof unit header */
            Rip.reclaim_header_offset += sizeof(UNIT_HEADER);
            SEM_MTX_POST(SEM_ReclaimInProg);
         }                             /* ENDIF header.status != HDR_EMPTY */

      } while (!HDR_STATE(HDR_EMPTY, header.status));
      /* ENDDO WHILE status != EMPTY */

      if (errors != HW_ERR_NONE)
      {
         break;
      }
      /*
       * We are done transferring valid unit headers and their associated data
       * units Update the BLOCK_INFO fields of the spare block with
       * information from the reclaim block
       */
      /* read the reclaim block's block information */
      errors = FlashDevRead((BYTE_PTR) & block_info,
                            Rip.reclaim_block_addr + BOTTOM_OF_UNITS,
                            sizeof(BLOCK_INFO));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x300b0000 */);
         break;
      }
      /*
       * write the physical block number of the reclaim block into the spare's
       * block information physical_copy field
       */
      errors = FlashDevWrite((BYTE_PTR) & RECL_ReclaimBlock,
                             Rip.spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, physical_copy),
                             mFDI_MemberSize(BLOCK_INFO, physical_copy));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -