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

📄 fdi_recl.c

📁 Flash file system
💻 C
📖 第 1 页 / 共 5 页
字号:
      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));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x300c0000 */);
         break;
      }
      /*
       * write the logical block number of the reclaim block into the spare's
       * block information logical_block_number field
       */
      errors = FlashDevWrite((BYTE_PTR)&block_info.logical_block_number,
                            Rip.spare_block_addr + BOTTOM_OF_UNITS +
                            offsetof(BLOCK_INFO, logical_block_number),
                            mFDI_MemberSize(BLOCK_INFO, logical_block_number));

      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x300d0000 */);
         break;
      }
      /* if we are reclaiming a block because of wear leveling, we want to */
      /* increment more than one because otherwise we could get into a */
      /* situation where we are wear leveling often. Need to give space */
      /* for natural wear leveling to begin again. */

      if ((most_erased_count - block_info.erase_count) > WEARLEVELING_LIMIT)
         block_info.erase_count += RECL_WEARLEVEL_DIFFERENTIAL;
      else
         block_info.erase_count++;     /* increment the erase count before */
      /*
       * write the reclaim block's erase count into the spare's block
       * information physical_erase_count field
       */
      errors = FlashDevWrite((BYTE_PTR) & block_info.erase_count,
                            Rip.spare_block_addr + BOTTOM_OF_UNITS +
                            offsetof(BLOCK_INFO, physical_erase_count),
                            mFDI_MemberSize(BLOCK_INFO, physical_erase_count));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x300e0000 */);
         break;
      }
      /*
       * Prepare to erase the reclaim block by marking the spare block
       * BLK_ERASING.
       */
      /* write the spare block's block information status field to 'erasing' */
      block.status = BLK_ERASING;      /* set the status to 'erasing' */

      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/* | 0x300f0000 */);
         break;
      }
      /*
       * NOTE!!!!: We will update the LogicalBlockTable here so that other
       * processes can use the data in the spare block while the reclaim block
       * is being erased....
       */
#if (CONSISTENT_ACCESS_TIME == TRUE)
      /* wait for DLT access */
      SEM_MTX_WAIT(SEM_LookupTable);
#endif
      SEM_MTX_WAIT(SEM_BlockTable);    /* wait for block table access */


#if (CONSISTENT_ACCESS_TIME == TRUE)
      /* update DLT */
      errors = FlashDevUpdateDLT(Rip.spare_block_addr);
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30150000 */);
         break;
      }
#endif

      /*
       * update the physical_block_number field of the FDI_LogicalBlockTable
       * with the spare's physical block number
       */
      FDI_LogicalBlockTable[this_blk.logical_block].physical_block_number =
       FDI_SpareBlock;
      /*
       * update the free_space field of the FDI_LogicalBlockTable with spare's
       * free space
       */
      FDI_LogicalBlockTable[this_blk.logical_block].free_space = (Rip.spare_free /
                                                              sizeof(DWORD));

      /* initialize the dirty_space field of the FDI_LogicalBlockTable */
      FDI_LogicalBlockTable[this_blk.logical_block].dirty_space =
       (Rip.spare_dirty / sizeof(DWORD));

      /* Set the last_header_offset field of LBT */
      SET_LAST_HEADER_OFFSET(this_blk.logical_block, Rip.spare_header_offset);
      /*
       * assign FDI_SpareBlock global variable to the reclaim block's physical
       * block number
       */
      FDI_SpareBlock = RECL_ReclaimBlock;

      SEM_MTX_POST(SEM_BlockTable);    /* finished with block table access */

#if (CONSISTENT_ACCESS_TIME == TRUE)
      SEM_MTX_POST(SEM_LookupTable);
#endif

      SEM_MTX_WAIT(SEM_WriteInProg);   /* pend on writes in progress */
      SEM_MTX_WAIT(SEM_OpenStream);    /* Take the open stream semaphore */
      for(index =0; index < OPEN_ARRAY_SIZE; index++)
      {
        if(FDI_OpenParam[index].identifier == WORDMAX)
          continue;
        RIP_OpenStreamUpdate(&FDI_OpenParam[index]);
      }
      SEM_MTX_POST(SEM_OpenStream);    /* Give the open stream semaphore */
      SEM_MTX_POST(SEM_WriteInProg);   /* finished blocking writes */

      RECL_SetState(RECL_ERASING);     /* reclaim state flag */
      /*
       * reset these globals to keep the background from using them even when
       * reclaim has finished.
       */
      Rip.recl_in_prog_flag = FALSE;   /* done with the copy phase */
      reclaim_block_addr = Rip.reclaim_block_addr; /* save local copy */
      Rip.reclaim_block_addr = DWORDMAX;
      spare_block_addr = Rip.spare_block_addr;  /* save local copy */
      Rip.spare_block_addr = DWORDMAX;
      Rip.reclaim_header_offset = FIRST_HEADER_OFFSET;

      /*invalidate the reclaim block's integrity */
      block_info.current_state = BLK_INTEGRITY_INVALID;
      errors = FlashDevWrite((BYTE_PTR) & block_info.current_state,
                             reclaim_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, current_state),
                             sizeof(block_info.current_state));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30100000 */);
         break;
      }

      SEM_MTX_POST(SEM_ReclaimInProg); /* finished blocking writes */


      /* ERASE the reclaim block now.... ############################### */
      errors = FlashDevEraseBlock(reclaim_block_addr);
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30110000 */);
         break;
      }

      /* write spare block's block information status field to 'updating' */
      block.status = BLK_UPDATING;     /* set the status to 'updating' */
      errors = FlashDevWrite(&block.status,
                             spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, status),
                             mFDI_MemberSize(BLOCK_INFO, status));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30120000 */);
         break;
      }
      /*
       * update the spare block erase count in the parameter where it is
       * maintained
       */
      errors = WriteData((BYTE_PTR) & block_info.erase_count, 0,
                         ERASE_COUNT_ID, sizeof(DWORD), ERASE_COUNT_TYPE,
                         WRITE_REPLACE);
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30130000 */);
         break;
      }

      /* write the spare block's block information status field to 'write' */
      block.status = BLK_WRITE;        /* set the status to 'write' */
      errors = FlashDevWrite(&block.status,
                             spare_block_addr + BOTTOM_OF_UNITS +
                             offsetof(BLOCK_INFO, status),
                             mFDI_MemberSize(BLOCK_INFO, status));
      if (errors != HW_ERR_NONE)
      {
         FDI_HandleError(errors/* | 0x30140000 */);
         break;
      }

      /* read the reclaim block's block information */

      /*

⌨️ 快捷键说明

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