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

📄 fat_ioct.c

📁 UCOS-II在VC++6.0环境下的调试及编译
💻 C
📖 第 1 页 / 共 3 页
字号:
  Description:
  FS internal function. Store information about used/unused clusters
  in a FS_DISKFREE_T data structure.

  Parameters:
  Idx         - Index of device in the device information table 
                referred by FS__pDevInfo.
  Unit        - Unit number.
  pDiskData   - Pointer to a FS_DISKFREE_T data structure.
  
  Return value:
  ==0         - Information is stored in pDiskData.
  <0          - An error has occured.
*/

static int _FS_fat_GetTotalFree(int Idx, FS_u32 Unit, FS_DISKFREE_T *pDiskData) {
  FS_u32 freeclust;
  FS_u32 usedclust;
  FS_u32 totclust;
  FS_u32 fatentry;
  FS_u32 fatsize;
  FS_i32 fatoffs;
  FS_i32 bytespersec;
  FS_i32 cursec;
  FS_i32 fatsec;
  FS_i32 lastsec;
  FS_i32 fatindex;
  int fattype;
  int err;
  char *buffer;
  unsigned char a;
  unsigned char b;
#if (FS_FAT_NOFAT32==0)
  unsigned char c;
  unsigned char d;
#endif
  
  if (!pDiskData) {
    return -1;  /* No pointer to a FS_DISKFREE_T structure */
  }
  buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
  if (!buffer) {
    return -1;
  }
  fattype = FS__fat_which_type(Idx, Unit);
#if (FS_FAT_NOFAT32!=0)
  if (fattype == 2) {
    FS__fat_free(buffer);
    return -1;
  }
#endif /* FS_FAT_NOFAT32!=0 */
  fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz16;
  if (fatsize == 0) {
    fatsize = FS__FAT_aBPBUnit[Idx][Unit].FATSz32;
  }
  bytespersec = (FS_i32)FS__FAT_aBPBUnit[Idx][Unit].BytesPerSec;
  /* Calculate total allocation units on disk */
  totclust = FS__FAT_aBPBUnit[Idx][Unit].TotSec16;
  if (!totclust) {
    totclust = FS__FAT_aBPBUnit[Idx][Unit].TotSec32;
  }
  totclust  -= FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt;
  totclust  -= 2*fatsize;
  usedclust  = FS__FAT_aBPBUnit[Idx][Unit].RootEntCnt;
  usedclust *= 0x20;
  usedclust /= bytespersec;
  totclust  -= usedclust;
  totclust  /= FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
  /* Scan FAT for free and used entries */
  cursec     = 0;
  fatsec     = 0;
  lastsec    = -1;
  fatentry   = 0xffffUL;
  freeclust  = 0;
  usedclust  = 0;
  while (1) {
    if (cursec >= (FS_i32)totclust) {
      break;  /* Last cluster reached */
    }
    if (fatsec >= (FS_i32)fatsize + FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt) {
      break;  /* End of FAT reached */
    }
    if (fattype == 1) {
      fatindex = (cursec + 2) + ((cursec + 2) / 2);    /* FAT12 */
    }
    else if (fattype == 2) {
      fatindex = (cursec + 2) * 4;               /* FAT32 */
    }
    else {
      fatindex = (cursec + 2) * 2;               /* FAT16 */
    }
    fatsec = FS__FAT_aBPBUnit[Idx][Unit].RsvdSecCnt + (fatindex / bytespersec);
    fatoffs = fatindex % bytespersec;
    if (fatsec != lastsec) {
      err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
      if (err < 0) {
        err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec, (void*)buffer);
        if (err < 0) {
          FS__fat_free(buffer);
          return -1;
        }
        /* Try to repair original FAT sector with contents of copy */
        FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec, (void*)buffer);
      }
      lastsec = fatsec;
    }
    if (fattype == 1) {
      if (fatoffs == (bytespersec - 1)) {
        a = buffer[fatoffs];
        err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsec+1, (void*)buffer);
        if (err < 0) {
          err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, fatsize + fatsec + 1, (void*)buffer);
          if (err < 0) {
            FS__fat_free(buffer);
            return -1;
          }
          /* Try to repair original FAT sector with contents of copy */
          FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, fatsec + 1, (void*)buffer);
        }
        lastsec = fatsec + 1;
        b = buffer[0];
      }
      else {
        a = buffer[fatoffs];
        b = buffer[fatoffs + 1];
      }
      if (cursec & 1) {
        fatentry = ((a & 0xf0) >> 4 ) + 16 * b;
      }
      else {
        fatentry = a + 256 * (b & 0x0f);
      }
      fatentry &= 0x0fff;
    }
#if (FS_FAT_NOFAT32==0)
    else if (fattype == 2) {
      a = buffer[fatoffs];
      b = buffer[fatoffs + 1];
      c = buffer[fatoffs + 2];
      d = buffer[fatoffs + 3];
      fatentry = a + 0x100UL * b + 0x10000UL * c + 0x1000000UL * d;
      fatentry &= 0x0fffffffUL;
    }
#endif /* FS_FAT_NOFAT32==0 */
    else {
      a = buffer[fatoffs];
      b = buffer[fatoffs + 1];
      fatentry = a + 256 * b;
      fatentry &= 0xffffUL;
    }
    cursec++;
    if (fatentry == 0) {
      freeclust++;
    }
    else {
      usedclust++;
    }
  }
  FS__fat_free(buffer);
  pDiskData->total_clusters      = totclust;
  pDiskData->avail_clusters      = freeclust;
  pDiskData->sectors_per_cluster = FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
  pDiskData->bytes_per_sector    = (FS_u16)bytespersec;
  return 0;
}

#endif /* FS_FAT_DISKINFO */


/*********************************************************************
*
*             Global functions
*
**********************************************************************
*/

/*********************************************************************
*
*             FS__fat_ioctl
*
  Description:
  FS internal function. Execute device command. The FAT layer checks
  first, if it has to process the command (e.g. format). Any other
  command is passed to the device driver.

  Parameters:
  Idx         - Index of device in the device information table 
                referred by FS__pDevInfo.
  Unit        - Unit number.
  Cmd         - Command to be executed.
  Aux         - Parameter depending on command.
  pBuffer     - Pointer to a buffer used for the command.
  
  Return value:
  Command specific. In general a negative value means an error.
*/

int FS__fat_ioctl(int Idx, FS_u32 Unit, FS_i32 Cmd, FS_i32 Aux, void *pBuffer) {
  int x;
#if ((FS_SUPPORT_SEC_ACCESS) || (FS_FAT_NOFORMAT==0))
  int i;
#endif
#if (FS_FAT_NOFORMAT==0)
  int j;
#endif

  FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_INC_BUSYCNT, 0, (void*)0);  /* Turn on busy signal */
#if (FS_FAT_NOFORMAT==0)
  if (Cmd == FS_CMD_FORMAT_MEDIA) {
    j = 0;
    while (1) {
      if (j >= FS_KNOWNMEDIA_NUM) {
        break;  /* Not a known media */
      }
      if (_FS_wd_format_media_table[j].media_id == Aux) {
        break;  /* Media found in the list */
      }
      j++;
    }	//find the right media
    if (j >= FS_KNOWNMEDIA_NUM) {	//can't find the right media
      FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
      return -1;
    }
    i = FS__lb_status(FS__pDevInfo[Idx].devdriver, Unit);	//get status of device, if ok return 1
    if (i >= 0) {
      x = _FS_fat_format(FS__pDevInfo[Idx].devdriver,
                          Unit,
                          _FS_wd_format_media_table[j].secperclus,
                          _FS_wd_format_media_table[j].rootentcnt,
                          _FS_wd_format_media_table[j].totsec16,
                          _FS_wd_format_media_table[j].totsec32,
                          _FS_wd_format_media_table[j].media,
                          _FS_wd_format_media_table[j].fatsz16,
                          0,
                          _FS_wd_format_media_table[j].secpertrk,
                          _FS_wd_format_media_table[j].numheads,
                          _FS_wd_format_media_table[j].hiddsec,
                          _FS_wd_format_media_table[j].fsystype);
      i = FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_FLUSH_CACHE, 0, (void*)0);
      if (i < 0) {
        x = i;
      }
      else {
        /* Invalidate BPB */
        for (i = 0; i < (int)FS__maxdev; i++) {
          for (j = 0; j < (int)FS__fat_maxunit; j++) {
              FS__FAT_aBPBUnit[i][j].Signature = 0x0000;
          }
        }
      }
    }
    else {
      FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
      return -1;
    }
  }
  else if (Cmd == FS_CMD_FORMAT_AUTO) {
    i = FS__lb_status(FS__pDevInfo[Idx].devdriver, Unit);
    if (i >= 0) {
      x = _FS_FAT_AutoFormat(Idx, Unit);
      i = FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_FLUSH_CACHE, 0, (void*)0);
      if (i < 0) {
        x = i;
      }
    }
    else {
      x = -1;
    }
  }
#else /* FS_FAT_NOFORMAT==0 */
  if (Cmd == FS_CMD_FORMAT_MEDIA) {
    x = -1;  /* Format command is not supported */
  }
#endif /* FS_FAT_NOFORMAT==0 */
#if FS_FAT_DISKINFO
  else if (Cmd == FS_CMD_GET_DISKFREE) {
    i = FS__fat_checkunit(Idx, Unit);
    if (i > 0) {
      x = _FS_fat_GetTotalFree(Idx, Unit, (FS_DISKFREE_T*)pBuffer);
      i = FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_FLUSH_CACHE, 0, (void*)0);
      if (i < 0) {
        x = i;
      }
    }
    else {
      x = -1;
    }
  }
#else /* FS_FAT_DISKINFO==0 */
  else if (Cmd == FS_CMD_GET_DISKFREE) {
    x = -1; /* Diskinfo command not supported */
  }
#endif /* FS_FAT_DISKINFO */
#if FS_SUPPORT_SEC_ACCESS
  else if ((Cmd == FS_CMD_READ_SECTOR) || (Cmd == FS_CMD_WRITE_SECTOR)) {
    if (!pBuffer) {
      FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);
      return -1;
    }
    i = FS__lb_status(FS__pDevInfo[Idx].devdriver, Unit);
    if (i >= 0) {
      if (Cmd == FS_CMD_READ_SECTOR) {
        x = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, Aux, pBuffer);
      }
      else {
        x = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, Aux, pBuffer);
      }
    }
    else {
      x = -1;
    }
  }
#else /* FS_SUPPORT_SEC_ACCESS */
  else if ((Cmd == FS_CMD_READ_SECTOR) || (Cmd == FS_CMD_WRITE_SECTOR)) {
    FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);
    return -1;
  }
#endif /* FS_SUPPORT_SEC_ACCESS */
  else {
    /* Maybe command for driver */
    x = FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, Cmd, Aux, (void*)pBuffer);
  }
  FS__lb_ioctl(FS__pDevInfo[Idx].devdriver, Unit, FS_CMD_DEC_BUSYCNT, 0, (void*)0);  /* Turn off busy signal */
  return x;
}


⌨️ 快捷键说明

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