fdi_int.c

来自「FDI Intel开发的FLASH文件系统,功能很强大」· C语言 代码 · 共 1,760 行 · 第 1/5 页

C
1,760
字号
      block_address =
       BLOCK_ADDRESS(FDI_LogicalBlockTable[block_index].physical_block_number);

      /* If it is called from the background, give up the block table sem. */
      if (flag == 0)
      {
         SEM_MTX_POST(SEM_BlockTable);
      }

      unit_index = 0;
      /*
       * Scan all the unit headers in this block until an empty unit header is
       * found or a matching valid sequence table header is found.
       */
      do
      {
         /* Read the unit header information of a unit. */
         hw_status = FlashDevRead((BYTE_PTR) & unit_header_buffer,
                      block_address + FIRST_HEADER_OFFSET +
                      (unit_index * sizeof(UNIT_HEADER)),
                      sizeof(UNIT_HEADER));
         if (hw_status != HW_ERR_NONE)
         {
            return ERR_READ;
         }

         /* Need to fix intermediate states if SearchForIdentifier was called
          * from init and unit header hasn't already been scanned by
          * ScanHeaders.  All references to the unit header status after this
          * will just check left most bit. */
         if ((flag != 0) &&
             ((current_index != unit_index) || (index != block_index)) &&
             (CheckAddr(block_address + FIRST_HEADER_OFFSET +
              (unit_index * sizeof(UNIT_HEADER)), current_index,
              index) == BYTEMAX))
         {
            /* Determine if status is in an intermediate state */
            if ((state_msk = HDR_INTERMEDIATE(unit_header_buffer.status)) != 0)
            {
               #ifdef TEST_MSGS
               logMsg("Intermediate header status found in SearchForIdentifier(), 0x%X\n",
                  unit_header_buffer.status,0,0,0,0,0);
               #endif

               /* Determine the mask needed to push out of intermediate state. */
               unit_header_buffer.status = HDR_FIX_INTERMEDIATE(state_msk,
                                                unit_header_buffer.status);

               /* Push out of intermediate state */
               if ((hw_status =
                     FlashDevWrite((BYTE_PTR)&unit_header_buffer.status,
                                   block_address + FIRST_HEADER_OFFSET +
                                   (unit_index * sizeof(UNIT_HEADER)) +
                                   offsetof(UNIT_HEADER, status),
                                   sizeof(unit_header_buffer.status))) !=
                     HW_ERR_NONE)
               {
                  mDEBUG_CHECK_ERRCODE(hw_status)
                  return ERR_WRITE;
               }
            }
         }

         /* If no more data exists in this block, scan next block. */
         if (HDR_STATE(HDR_EMPTY, unit_header_buffer.status))
         {
            break;
         }

         /* for truncate operation PLR, will invalidate all 'invalidating' units */
         if(trunc_flag)
         {
             if(unit_header_buffer.status == HDR_INVALIDATING)
             {
                 if(flag && CheckAddr(block_address + FIRST_HEADER_OFFSET +
                    (unit_index * sizeof(UNIT_HEADER)), current_index,
                    index) == BYTEMAX)
                 {
                       unit_header_buffer.g_unit_size = WORDMAX;
                 }
                 if((status = WriteUnitHeaderStatus(block_address +
                    FIRST_HEADER_OFFSET + (unit_index *
                    sizeof(UNIT_HEADER)), HDR_INVALID,
                    unit_header_buffer.status,
                    unit_header_buffer.g_unit_size, flag)) != ERR_NONE)
                 {

                    /* Invalidate the unit header. */
                    *invalidating_hdr_addr = DWORDMAX;
                    return status;
                 }
             }
         }
         else

         /* If the new_header_pointer->status is allocated, */
         if (new_header_pointer->status == HDR_ALLOCATED)
         {
            /* If a valid matching identifier of same type exists.  Also check
             * for valid multi instance being returned to cover the case of
             * the multi -> single, multi -> fragment, single -> fragment */
/* E.5.1.781 Begin */
            if (HDR_STATE(HDR_VALID, unit_header_buffer.status) &&
               (unit_header_buffer.identifier ==
               new_header_pointer->identifier) &&
               ((unit_header_buffer.type_attribute ==
               new_header_pointer->type_attribute) ||
               (((unit_header_buffer.type_attribute & ~ATTRIBUTE_MASK) ==
               (new_header_pointer->type_attribute & ~ATTRIBUTE_MASK)) &&
               ((((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) == 
                  ATTR_MULTI_INST) && 
               ((new_header_pointer->type_attribute & ATTRIBUTE_MASK) == 
                  ATTR_SINGL_INST)) ||
               (((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) == 
                  ATTR_MULTI_INST) && 
               ((new_header_pointer->type_attribute & ATTRIBUTE_MASK) == 
                  ATTR_GRP_TABLE)) ||
               (((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) == 
                  ATTR_SINGL_INST) && 
               ((new_header_pointer->type_attribute & ATTRIBUTE_MASK) == 
                  ATTR_GRP_TABLE))))))
/* E.5.1.781 End */
             {
               *invalidating_hdr_addr =  (block_address + FIRST_HEADER_OFFSET +
                       (unit_index * sizeof(UNIT_HEADER)));
               return ERR_NONE;
             }
         }                             /* End of if(
                                        * new_header_pointer->status ==
                                        * ALLOCATED ). */

         /* elseIf the new_header_pointer->status is valid, */
         /* this happens only when SearchForIdentifier is called from
            the background
         */
         else if (new_header_pointer->status == HDR_VALID)
         {
            /* If a valid matching identifier of same type exists. */
            if (HDR_STATE(HDR_VALID, unit_header_buffer.status) &&
                (unit_header_buffer.identifier ==
                 new_header_pointer->identifier) &&
                (NIBBLE_HIGH(unit_header_buffer.type_attribute) ==
                 NIBBLE_HIGH(new_header_pointer->type_attribute)) &&
                ((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) !=
                 ATTR_DATA_FRAG) &&
                ((unit_header_buffer.type_attribute & ATTRIBUTE_MASK) !=
                 ATTR_SEQ_TABLE))
            {
               *invalidating_hdr_addr = (block_address + FIRST_HEADER_OFFSET +
                      (unit_index * sizeof(UNIT_HEADER)));

               return ERR_NONE;
            }
         }                             /* End of if(
                                        * new_header_pointer->status == VALID
                                        * ). */

         /* else If the new_header_pointer->status is allocating or valid hdr */
         else if ((new_header_pointer->status == HDR_ALLOCATING) ||
                  (new_header_pointer->status == HDR_VALID_HDR))

         {
            /*
             * If a matching identifier and type that is marked
             * allocated, invalidate the unit header.
             * The check for HDR_VALID_HDR state will be taken care of in
             * ScanHeaders.
             */
            if ((HDR_STATE(HDR_ALLOCATED, unit_header_buffer.status)) &&
                (unit_header_buffer.identifier ==
                 new_header_pointer->identifier) &&
                (NIBBLE_HIGH(unit_header_buffer.type_attribute) ==
                 NIBBLE_HIGH(new_header_pointer->type_attribute)))
            {
/* E.5.3.877 Start */
               /* 
                * The skip_addr stores the address of unit for which we cannot
                * determine to validate it and invalidate it in future, so here 
                * we skip it and keep it until finish up scanning all headers,
                * then make decision to do appropriate handling
                */
               if((new_header_pointer->status == HDR_VALID_HDR) &&
                  (skip_addr == (block_address + FIRST_HEADER_OFFSET +
                       (unit_index * sizeof(UNIT_HEADER)))))
               {
                  unit_index++;
                  continue;
               }
/* E.5.3.877 End */

               if ( (new_header_pointer->type_attribute & ATTRIBUTE_MASK) !=
                   ATTR_GRP_TABLE )
               {
                   unit_header_buffer.g_unit_size = WORDMAX;
               }
               else
               {
                   if(flag && CheckAddr(block_address + FIRST_HEADER_OFFSET +
                      (unit_index * sizeof(UNIT_HEADER)), current_index,
                      index) == BYTEMAX)
                   {
                      unit_header_buffer.g_unit_size = WORDMAX;
                   }
               }

               /* Invalidate the unit header. */
               if ((status = WriteUnitHeaderStatus((block_address + FIRST_HEADER_OFFSET +
                     (unit_index * sizeof(UNIT_HEADER))),
                     HDR_INVALID, unit_header_buffer.status,
                     unit_header_buffer.g_unit_size, flag)) !=
                     ERR_NONE)
               {
                  *invalidating_hdr_addr = DWORDMAX;
                  return status;
               }
            }

         }                             /* End of if(
                                        * new_header_pointer->status ==
                                        * HDR_ALLOCATING ). */
         /*
          * else If the new_header_pointer->status is invalidating, it means
          * the data is fragmented.
          */
         else if (new_header_pointer->status == HDR_INVALIDATING)
         {
            /*
             * If a matching identifier and type, that is not marked invalid,
             * exists.
             */
            if ((!INVALID_HDR(unit_header_buffer.status)) &&
                (unit_header_buffer.identifier ==
                 new_header_pointer->identifier) &&
                (NIBBLE_HIGH(unit_header_buffer.type_attribute) ==
                 NIBBLE_HIGH(new_header_pointer->type_attribute)))
            {

               if (!HDR_STATE(HDR_INVALIDATING, unit_header_buffer.status))
               {

                  if (NIBBLE_LOW(unit_header_buffer.type_attribute) !=
                      ATTR_GRP_TABLE)
                  {
                     if(flag && CheckAddr(block_address + FIRST_HEADER_OFFSET +
                        (unit_index * sizeof(UNIT_HEADER)), current_index,
                        index) == BYTEMAX)
                     {
                           unit_header_buffer.g_unit_size = WORDMAX;
                     }
                     if((status = WriteUnitHeaderStatus(block_address +
                        FIRST_HEADER_OFFSET + (unit_index *
                        sizeof(UNIT_HEADER)), HDR_INVALID,
                        unit_header_buffer.status,
                        unit_header_buffer.g_unit_size, flag)) != ERR_NONE)
                     {

                        /* Invalidate the unit header. */
                        *invalidating_hdr_addr = DWORDMAX;
                        return status;
                     }
                  }
               }
               else
               {
                  /*
                   * If more than one header is found in an invalidating
                   * state, the media should be reformatted.
                   */
                  if (found == TRUE)
                  {
                     *invalidating_hdr_addr = DWORDMAX;
                     return ERR_FORMAT;
                  }
                  found = TRUE;
                  *invalidating_hdr_addr = block_address + FIRST_HEADER_OFFSET +
                                          (unit_index * sizeof(UNIT_HEADER));
               }

            }

         }                             /* ENDIF status == HDR_INVALIDATING */

         unit_index++;
         /*
          * Until done scanning all the unit headers, validate the unit
          * header.
          */
      } while (!HDR_STATE(HDR_EMPTY, unit_header_buffer.status));
   }                                   /* end of for. */

   return status;

}                                      /* END SearchForIdentifier */

/* E.5.3.877 Start */
/*
 *############################################################################
 *### LookForAllocatedFrag
 *###
 *### DESCRIPTION:
 *### Look for an allocated fragment with the same id, type, it could be the new
 *### fragment created during truncate, we will keep this fragment until fully
 *### recovered flash, then invalidated it
 *###
 *### PARAMETERS:
 *###    IN:
 *###         UNIT_HEADER *new_header_pointer
 *###         DWORD_PTR   invalidating_hdr_addr
 *###
 *###    OUT:
 *###        DWORD: address of the previous valid unit header
 *###
 *### RETURNS:
 *###        ERR_CODE: error code
 *###
 */
ERR_CODE
LookForAllocatedFrag(UNIT_HEADER *new_header_pointer,
                     DWORD_PTR hdr_addr_ptr,
                     WORD_PTR size_ptr,
                     WORD current_index,
                     WORD index)
{
   UNIT_HEADER unit_header_buffer;        /* buffer to store unit header info */
   DWORD       block_address;
   WORD        unit_index;
   WORD        block_index;
   WORD        state_msk;                 /* mask to fix intermediate state */
   ERR_CODE    status = ERR_NONE;
   HW_ERROR    hw_status = HW_ERR_NONE;

   *hdr_addr_ptr = DWORDMAX;
   *size_ptr = WORDMAX;

   for (block_index = 0; block_index < MAX_DATA_BLOCKS; block_index++)
   {

      block_address =
       BLOCK_ADDRESS(FDI_LogicalBlockTable[block_index].physical_block_number);

      unit_index = 0;
      
      /*
       * Scan all the unit headers in this block until an empty unit header is
       * found or a matching valid sequence table header is found.
       */
      do
      {
         /* Read the unit header information of a unit. */
         hw_status = FlashDevRead((BYTE_PTR) & unit_header_buffer,
                      block_address + FIRST_HEADER_OFFSET +
                      (unit_index * sizeof(UNIT_HEADE

⌨️ 快捷键说明

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