|
Message
From: cvs at opencores.org<cvs@o...>
Date: Fri Jun 23 21:03:51 CEST 2006
Subject: [cvs-checkins] MODIFIED: mb-jpeg ...
Date: 00/06/06 23:21:03 Added: mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src xilfatfs_alloc.c xilfatfs_bufcache.c xilfatfs_chdir.c xilfatfs_close.c xilfatfs_direct.c xilfatfs_directory.c xilfatfs_fat.c xilfatfs_fat12.c xilfatfs_fat16.c xilfatfs_fat32.c xilfatfs_filespec.c xilfatfs_filestatus.c xilfatfs_mkdir.c xilfatfs_open.c xilfatfs_part.c xilfatfs_read.c xilfatfs_readdisk.c xilfatfs_standalone-utils.c xilfatfs_stats.c xilfatfs_sysace.c xilfatfs_sysace_stdio.c xilfatfs_wd.c xilfatfs_write.c Log: Updated to EDK8.1 Revision Changes Path 1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_alloc.c http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_alloc.c?rev=1.1&content-type=text/x-cvsweb-markup Index: xilfatfs_alloc.c =================================================================== ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2004 Xilinx, Inc. All rights reserved. // // Xilinx, Inc. // // XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A // COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS // ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR // STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION // IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE // FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. // XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO // THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO // ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE // FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS FOR A PARTICULAR PURPOSE. // //////////////////////////////////////////////////////////////////////////////// #include <string.h> #include "alloc.h" #include "fat.h" /* Create and release WDs */ static WorkingDirectory wd_buf[MAXWD]; static int wd_init_flag = 1; WorkingDirectory * malloc_wd(const char *name) { int i; /* Do initialization because MBlaze seems not to initialize statics per K&R */ if(wd_init_flag) { wd_init_flag = 0; for(i=0; i<MAXWD; i++ ) wd_buf[i].name[0] = 0; } for(i=0; i<MAXWD; i++) if(wd_buf[i].name[0] == 0) { strncpy(wd_buf[i].name, name, MAXFILENAMESIZE); return wd_buf + i; } return 0; } void free_wd(WorkingDirectory *wd) { wd->name[0] = 0; } static FileStatus fs_buf[MAXFILES]; static int fs_init_flag = 1; FileStatus * malloc_fs(void) { int i; if(fs_init_flag) { fs_init_flag = 0; for(i=0; i<MAXFILES; i++) fs_buf[i].reserved = 0; } for(i=0; i<MAXFILES; i++) if( fs_buf[i].reserved == 0 ) { fs_buf[i].reserved = 1; return fs_buf + i; } return 0; } void
free_fs(FileStatus *fs)
{
fs->reserved = 0;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_bufcache.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_bufcache.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_bufcache.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include "xparameters.h"
#include "sysace.h"
#include "bufcache.h"
#include "util.h"
struct bufcache_status_s {
unsigned char valid;
unsigned char dirty;
int sector;
};
#define N_BUFCACHE_ENTRIES ((XILFATFS_BUFCACHE_SIZE/SECTORSIZE))
struct bufcache_status_s bc_status[N_BUFCACHE_ENTRIES];
unsigned char bc[XILFATFS_BUFCACHE_SIZE];
int bc_replace_index;
int (*ll_write)(UINT32 sector, BYTE *buf);
/* return the index of sector in buffer cache if present,
* -1 if sector not in buffer cache
*/
int is_buffered(unsigned int sector)
{
int i;
for (i = 0; i < N_BUFCACHE_ENTRIES; i++)
if (bc_status[i].valid && bc_status[i].sector == sector)
return i;
return -1;
}
/* get a free entry in the buffer cache */
int bc_get_free_entry()
{
int i;
for (i = 0; i < N_BUFCACHE_ENTRIES; i++)
if (!bc_status[i].valid)
return i;
return -1;
}
/* find free space by replacing an entry */
int sequential_replace()
{
int cur_index = bc_replace_index;
bc_replace_index = (bc_replace_index + 1)%N_BUFCACHE_ENTRIES;
if (!bc_status[cur_index].valid) {
/* current entry to be replaced is not in use */
return cur_index;
}
if (bc_status[cur_index].dirty) {
/* sync the current entry to disk */
int n = (*ll_write)(bc_status[cur_index].sector,
(bc+cur_index*SECTORSIZE));
if (n != SECTORSIZE) {
/* fatal - cannot be synced */
return -1;
}
bc_status[cur_index].dirty = 0;
}
return cur_index;
}
/* initialize buffer cache.
* use the low level write function (*ll_write_fn) when required to sync to disk
* should be called before any other function to bufcache
*/
void init_bufcache(int (*ll_write_fn)(UINT32 sector, BYTE *buf))
{
memset(bc_status, 0, sizeof (bc_status));
bc_replace_index = 0;
ll_write = ll_write_fn;
}
/* update buffer cache with data for @sector */
int update_bufcache(int sector, unsigned char *sector_buf, int dirty)
{
int index = is_buffered(sector);
if (index < 0) /* if not buffered */
index = bc_get_free_entry();
if (index < 0) { /* not buffered, and no free entry in the cache */
index = sequential_replace(); /* replace something */
if (index < 0)
return -1;
}
bc_status[index].valid = 1;
bc_status[index].dirty = dirty;
bc_status[index].sector = sector;
memcpy(bc + index*SECTORSIZE, sector_buf, SECTORSIZE);
return SECTORSIZE;
}
/* read data for @sector from buffer cache */
int read_bufcache(int sector, unsigned char *sector_buf)
{
int n = is_buffered(sector);
if (n < 0)
return -1;
memcpy(sector_buf, bc + n*SECTORSIZE, SECTORSIZE);
return SECTORSIZE;
}
/* sync dirty entries to the disk */
int sync_bufcache()
{
int i, error = 0;
for (i = 0; i < N_BUFCACHE_ENTRIES; i++)
if (bc_status[i].valid && bc_status[i].dirty) {
if ((*ll_write)(bc_status[i].sector, bc + i*SECTORSIZE) != SECTORSIZE)
error = 1;
bc_status[i].dirty = 0;
}
return -error;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_chdir.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_chdir.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_chdir.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include "fat.h"
#include "filespec.h"
#include "directory.h"
#include "util.h"
/* Limited to 8 character filenames */
int sysace_chdir(const char *path)
{
WorkingDirectory *wd;
int partition;
wd = build_working_directory_stack(path, 1, 0);
if (wd) {
/* This is a valid directory path */
partition = wd->pi->PartitionNum;
if (cwd[partition])
delete_working_directory_stack(cwd[partition]);
cwd[partition] = wd;
DefaultPartition = partition;
return 0;
}
return -1;
}
#ifdef GET_CWD
#define GETDCWDBUFSIZE 100
char *my_getdcwd(int drive, char *path, int pathsize)
{
int length, level;
int i, j;
char *s, *buf_t;
char buf[GETDCWDBUFSIZE];
WorkingDirectory *wd;
if (drive == 0) {
/* Use the default drive */
drive = DefaultPartition;
} else
drive -= 1;
if (drive < 0 || drive >= MAXPARTITION)
return 0;
if (cwd[drive] == 0) {
/* Set the default */
cwd[drive] =
build_working_directory_stack(DIRSEPSTRING, 1, 0);
if (cwd[drive] == 0)
return 0;
}
/* Determine the total length needed */
level = 0;
length = 3; /* Drive specification, terminating 0 */
wd = cwd[drive];
while (wd) {
length += strlen(wd->name);
++level;
wd = wd->parent;
}
if (level > 2)
length += level - 2; /* Allow for separating characters */
if (path) {
/* Use the users buffer */
if (pathsize < length)
return 0;
s = path;
} else {
if (GETDCWDBUFSIZE < length)
return 0;
s = buf;
}
/* Drive letter */
s[0] = 'a' + drive;
s[1] = ':';
/* terminate the string */
i = length;
s[--i] = 0;
wd = cwd[drive];
while (wd) {
j = strlen(wd->name);
/* Copy the directory name */
while (j > 0) {
if (i < 2) { /* Something went wrong - we re about to run out of room */
return 0;
}
s[--i] = wd->name[--j];
}
/* Add separator. Note that root and 2nd level directory do not need separators. */
if (level > 2)
s[--i] = DIRSEPCHAR;
--level;
wd = wd->parent;
}
if (i != 2) {
/* Something went wrong - at this point there should be space remaining for
* the drive spec (2 characters). */
return 0;
}
if (s == path)
return path;
/* Make a new string - user is responsible for free()ing this string */
buf_t = (char *)malloc(strlen(buf) + 1);
if (!buf_t)
return 0;
return strcpy(buf_t, buf);
}
#endif /*GET_CWD */
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_close.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_close.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_close.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include "sysace_stdio.h"
#include "filestatus.h"
#include "bufcache.h"
int sysace_fclose(SYSACE_FILE *stream)
{
if (stream == 0)
return 0;
/* sync the buffer cache to the disk */
sync_bufcache();
return delete_file_status((FileStatus *) stream);
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_direct.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_direct.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_direct.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
/* All functions have been moved to other files */
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_directory.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_directory.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_directory.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <ctype.h>
#include <string.h>
#include "fat.h"
#include "filespec.h"
#include "alloc.h"
#include "directory.h"
int dir_name_compare(const char *a, const char *b, int n)
{
char ac, bc;
int an = strlen(a);
while (an > 0 && *a) {
ac = tolower(*a);
bc = tolower(*b);
if (ac < bc)
return -1;
if (ac > bc)
return 1;
++a;
++b;
--n;
--an;
}
while (n > 0) { /* finished text chars now check for trailing spaces */
if (*b != ' ')
return -1;
++b;
--n;
}
if (n == 0)
return 0;
if (*b)
return 1;
return 0;
}
/* Locate the named file or directory in the specified working directory
* The name is not hierarchical. Set ext = NULL to find a directory.
* Set ext = name = NULL to find an free entry
*/
int find_in_directory(WorkingDirectory *wd, const char *name,
const char *ext, UINT32 * firstcluster,
UINT32 * filesize, UINT32 *de_sector, UINT32 *de_offset)
{
BYTE buf[SECTORSIZE];
int bufcount;
int is_sub_dir = 0;
UINT32 sector;
UINT32 filecount;
UINT32 nsectors;
UINT32 cluster;
DirectoryEntry *de;
if (wd->pi->FatType != FAT32 && wd->parent == 0) {
/* Root directory */
filecount = wd->v.root.DirCount * DIRENT_SIZE;
sector = wd->v.root.StartSector;
nsectors = filecount / SECTORSIZE;
cluster = 0;
} else {
/* Child directory || FAT32
* (In Fat32 root & child are treated similarly) */
cluster = wd->v.child.FirstCluster;
sector = starting_sector(cluster, wd->pi);
nsectors = wd->pi->SectorsPerCluster;
filecount = nsectors * SECTORSIZE;
is_sub_dir = 1;
if (sector == 0) {
/* FAT problem ? */
return 0;
}
}
/* Keep going until the whole directory has been read.
* Note: it is necessary to check filecount in the inner
* loops as well because we can hit end-of-file anywhere
* within a cluster. */
while (filecount) {
/* Keep going until the whole root or cluster has been read */
while (nsectors && filecount) {
/* Get the current sector */
if (read_sector(sector, buf) != SECTORSIZE)
return 0;
bufcount = 0;
++sector;
--nsectors;
while ((bufcount < SECTORSIZE) && filecount) {
/* Process a single directory entry */
filecount -= DIRENT_SIZE;
if (filecount < 0) {
/* This is some wierd error, both filesize and
* SECTORSIZE should be an integer multiple of DIRENT_SIZE.
*/
return 0;
}
de = (DirectoryEntry *) (buf + bufcount);
switch (de->Name[0]) {
case 0x00: /* This, and all subsequent entries are empty */
if (!name) { /* we are looking for a free entry */
*de_sector = sector - 1;
*de_offset = bufcount;
return 1;
}
return 0;
break;
case 0xe5: /* This entry is empty, but there may be more after it */
if (!name) { /* we are looking for a free entry */
*de_sector = sector - 1;
*de_offset = bufcount;
return 1;
}
break;
case 0x05: /* escaped Kanji character */
de->Name[0] = 0xe5;
/* fall through to default case ... */
default:
if (!name) /* we are looking for a free entry */
break; /* and this is not it.. */
if ((de->Attributes & ATTR_LONG_NAME_MASK) ==
ATTR_LONG_NAME) {
/* This is a long file name */
break;
}
/* Must be a file, directory or volume ID */
switch (de->Attributes & (ATTR_DIRECTORY | ATTR_VOLUME_ID)) {
case 0x00: /* This entry is a file */
if (ext) { /* Here if we are looking for a file */
if (!dir_name_compare(name, (char *) (de->Name), 8)
&& !dir_name_compare(ext, (char *) (de->Extension), 3)) {
if (wd->pi->FatType == FAT32) {
/* first cluster is a 32 bit entry for FAT32 */
*firstcluster = make_UINT32
(de->FirstClusterOfFile_hi[1],
de->FirstClusterOfFile_hi[0],
de->FirstClusterOfFile[1],
de->FirstClusterOfFile[0]);
} else {
*firstcluster = (UINT32)make_UINT16
(de->FirstClusterOfFile[1],
de->FirstClusterOfFile[0]);
}
*filesize = make_UINT32(de->FileSize[3],
de->FileSize[2],
de->FileSize[1],
de->FileSize[0]);
*de_sector = sector - 1;
*de_offset = bufcount;
return 1;
}
}
break;
case ATTR_DIRECTORY: /* This entry is a directory */
if (ext == 0) {
if (!dir_name_compare(name, (char *) (de->Name), 8)) {
if (wd->pi->FatType == FAT32) {
/* first cluster is a 32 bit entry for FAT32 */
*firstcluster = make_UINT32
(de->FirstClusterOfFile_hi[1],
de->FirstClusterOfFile_hi[0],
de->FirstClusterOfFile[1],
de->FirstClusterOfFile[0]);
} else {
*firstcluster = (UINT32)make_UINT16
(de->FirstClusterOfFile[1],
de->FirstClusterOfFile[0]);
}
*filesize = make_UINT32(de->FileSize[3],
de->FileSize[2],
de->FileSize[1],
de->FileSize[0]);
*de_sector = sector - 1;
*de_offset = bufcount;
return 1;
}
}
break;
case ATTR_VOLUME_ID: /* Volume ID */
break;
default: /* Bad directory */
return 0;
}
}
bufcount += DIRENT_SIZE;
}
}
/* Finished with root or current cluster. If this is not the
* root, then move to the next cluster. */
/* Root directory (in FAT12/16) has one continuous list of sectors */
if (wd->pi->FatType != FAT32 && wd->parent == 0)
return 0;
/* If this is a child directory go to next cluster */
cluster = next_cluster(cluster, wd->pi);
if (cluster == BAD_CLUSTER) {
/* FAT problem ? */
return 0;
}
if (is_sub_dir) {
/* reset filesize to read another clusters worth of directory entries */
filecount = (wd->pi->SectorsPerCluster * SECTORSIZE);
}
if ((sector = starting_sector(cluster, wd->pi)) == 0) {
/* FAT problem ? */
return 0;
}
nsectors = wd->pi->SectorsPerCluster;
} /* while(filesize) */
/* Never found it */
return 0;
}
void update_de_filesize(DirectoryEntry *de, UINT32 filesize)
{
write_UINT32(de->FileSize, filesize);
}
void update_de_firstcluster(DirectoryEntry *de, UINT32 firstcluster, PartitionInfo *pi)
{
UINT16 f_lo, f_hi;
f_lo = (UINT16)(firstcluster & 0xFFFF);
f_hi = (UINT16)(firstcluster >> 16);
write_UINT16(de->FirstClusterOfFile, f_lo);
if (pi->FatType == FAT32)
write_UINT16(de->FirstClusterOfFile_hi, f_hi);
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_fat.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_fat.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_fat.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include "fat.h"
#include "directory.h"
#include "util.h"
/* given a cluster, look into the FAT to find the next
* cluster in the link list */
UINT32 next_cluster(UINT32 cluster, PartitionInfo * pi)
{
if (cluster < 2)
return BAD_CLUSTER;
return pi->op->next_cluster(cluster, pi);
}
/* return the first sector corresponding to a cluster */
UINT32 starting_sector(UINT32 cluster, PartitionInfo * pi)
{
if (cluster == 0)
return 0;
return (((cluster - 2) * (UINT32) pi->SectorsPerCluster) +
pi->DataSector);
}
/* next_cluster_generic: given a cluster number, return the
* cluster that is next in this cluster chain by looking
* into the FAT data structure for this partition
*
* generic for FAT16 & FAT32
*/
UINT32 next_cluster_generic(UINT32 cluster, PartitionInfo * pi)
{
BYTE buf[SECTORSIZE];
UINT32 TempNextCluster;
UINT32 Fat0SectorNum;
UINT32 Fat1SectorNum;
int NextClusterPosition;
if (!pi->op->is_valid_cluster(cluster, pi))
return BAD_CLUSTER;
Fat0SectorNum = pi->op->get_fat_sector_for_cluster(cluster, pi);
NextClusterPosition = pi->op->get_fat_offset_for_cluster(cluster, pi);
if (read_sector(Fat0SectorNum, buf) != SECTORSIZE)
return BAD_CLUSTER;
TempNextCluster = pi->op->get_next_cluster(buf + NextClusterPosition, pi);
/* check for FAT misMatch !!! */
if (pi->NumberOfFats > 1) {
Fat1SectorNum = Fat0SectorNum + pi->SectorsPerFat;
if (read_sector(Fat1SectorNum, buf) != SECTORSIZE)
return BAD_CLUSTER;
if (TempNextCluster != pi->op->get_next_cluster(buf + NextClusterPosition, pi))
return BAD_CLUSTER; /* FAT tables don't match bail */
}
return (TempNextCluster);
}
/* Follow the cluster chain in FAT16/32 and free all allotted
* clusters.
*/
int free_cluster_chain_generic(UINT32 cluster, PartitionInfo *pi)
{
UINT32 sector_in_buf = 0;
UINT32 sector, offset;
int modified = 0; /* denotes if the sector_in_buf has been modified */
char buf[SECTORSIZE];
while (!pi->op->is_eoc(cluster, pi)) {
sector = pi->op->get_fat_sector_for_cluster(cluster, pi);
if (sector != sector_in_buf) { /* have to read in a new sector from FAT */
/* write to disk if the old sector was modified */
if (modified) {
if (write_sector(sector_in_buf, buf) != SECTORSIZE)
return -1;
/* update FAT 2 */
if (pi->NumberOfFats > 1)
if (write_sector(sector_in_buf + pi->SectorsPerFat, buf)
!= SECTORSIZE)
return -1;
modified = 0;
}
/* read in the new sector */
if (read_sector(sector, buf) != SECTORSIZE)
return -1;
sector_in_buf = sector;
}
offset = pi->op->get_fat_offset_for_cluster(cluster, pi);
/* obtain the current value & reset it to zero */
cluster = pi->op->get_next_cluster(buf + offset, pi);
pi->op->set_next_cluster(buf + offset, 0, pi);
modified = 1;
}
if (modified) {
if (write_sector(sector_in_buf, buf) != SECTORSIZE)
return -1;
/* update FAT 2 */
if (pi->NumberOfFats > 1)
if (write_sector(sector_in_buf + pi->SectorsPerFat, buf)
!= SECTORSIZE)
return -1;
modified = 0;
}
return 0;
}
/* truncate a file to size 0: done by following the cluster chain
* and freeing all allotted clsuters for this file
*/
int truncate_file(UINT32 cluster, PartitionInfo *pi)
{
if (cluster < 2)
return -1;
return pi->op->free_cluster_chain(cluster, pi);
}
/* find a free cluster, set the next entry of that cluster to EOC
* and return that cluster.
* A request to allocate_one_cluster automatically sets the entry
* in FAT for that cluster to point to EOC. This is because we want
* to reduce the # of read and write calls to the disk
*/
UINT32 allocate_one_cluster_generic(PartitionInfo *pi)
{
BYTE buf[SECTORSIZE];
int FatEntrySize;
UINT32 cluster = 0, sector, i;
UINT32 eoc;
if (pi->FatType == FAT16) {
FatEntrySize = 2;
eoc = FAT16_EOC;
} else if (pi->FatType == FAT32) {
FatEntrySize = 4;
eoc = FAT32_EOC;
} else { /* works only for FAT16/32 */
return 0;
}
for (sector = pi->FatSector;
sector < pi->FatSector + pi->SectorsPerFat;
sector++) {
/* read in the sector */
if (read_sector(sector, buf) != SECTORSIZE)
return 0;
/* find if an entry is free */
for (i = 0; i < SECTORSIZE; i+= FatEntrySize) {
UINT32 cluster_val = pi->op->get_next_cluster(buf + i, pi);
if (cluster_val == 0) { /* this cluster is free */
BYTE buf2[SECTORSIZE];
UINT32 cluster_val_2;
if (read_sector(sector + pi->SectorsPerFat, buf2) != SECTORSIZE)
return 0;
cluster_val_2 = pi->op->get_next_cluster(buf2 + i, pi);
if (cluster_val_2 != cluster_val)
return 0; /* FAT mismatch */
/* write EOC as the entry for this cluster
* in both the FATs */
pi->op->set_next_cluster(buf2 + i, eoc, pi);
if (write_sector(sector + pi->SectorsPerFat, buf2) != SECTORSIZE)
return 0;
pi->op->set_next_cluster(buf + i, eoc, pi);
if (write_sector(sector, buf) != SECTORSIZE)
return 0;
return cluster;
}
cluster++;
}
}
return 0;
}
int link_cluster_generic(UINT32 from_cluster, UINT32 to_cluster, PartitionInfo *pi)
{
UINT32 sector = pi->op->get_fat_sector_for_cluster(from_cluster, pi);
UINT32 offset = pi->op->get_fat_offset_for_cluster(from_cluster, pi);
BYTE buf[SECTORSIZE];
if (read_sector(sector, buf) != SECTORSIZE)
return -1;
/* set the next cluster for from_cluster to to_cluster */
pi->op->set_next_cluster(buf + offset, to_cluster, pi);
if (write_sector(sector, buf) != SECTORSIZE)
return -1;
return 0;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_fat12.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_fat12.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_fat12.c
===================================================================
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
/////////////////////////////////////////////////////////////////////////////
#include "fat.h"
#include "directory.h"
#include "util.h"
/* given the cluster #, find the sector in the partition where
* the FAT entry for that cluster is present
*/
UINT32 get_fat12_sector_for_cluster(UINT32 cluster, PartitionInfo *pi)
{
/* Each FAT entry takes 1.5 bytes in FAT 12 */
return ((cluster + cluster/2) / SECTORSIZE) + pi->FatSector;
}
/* given the cluster #, find the offset in the sector in the partition where
* the FAT entry for that cluster is present
*/
UINT32 get_fat12_offset_for_cluster(UINT32 cluster, PartitionInfo *pi)
{
return ((cluster + cluster/2) % SECTORSIZE);
}
/* given the address (fat_entry) where the FAT entry for a cluster
* is present, return the next cluster for that entry
*/
UINT32 get_next_cluster_fat12(BYTE *fat_entry, PartitionInfo *pi, UINT32 cluster)
{
UINT32 tmp_next_cluster;
/* We need 12 bits from the 2 bytes - so first read in the 2 bytes */
tmp_next_cluster = (UINT32) make_UINT16(*(fat_entry + 1), *(fat_entry));
if (cluster & 0x1) /* if cluster is odd, we take the higher 12 bits */
tmp_next_cluster >>= 4;
else /* else we take the lower 12 bits */
tmp_next_cluster &= 0xFFF;
return tmp_next_cluster;
}
/* given the address (fat_entry) where the FAT entry for a cluster
* is present, set the next cluster entry to next_cluster
*/
void set_next_cluster_fat12(BYTE *fat_entry,
UINT32 next_cluster,
PartitionInfo *pi,
UINT32 cluster)
{
UINT16 old_entry = make_UINT16(*(fat_entry+1), *(fat_entry));
UINT32 new_entry;
if (cluster & 0x1) { /* if cluster is odd, we need to update the higher 12 bits */
new_entry = (next_cluster << 4) | (old_entry & 0xF);
write_UINT16(fat_entry, new_entry);
} else { /* else write the lower order 12 bits */
new_entry = (next_cluster & 0xFFF) | (old_entry & 0xF000);
write_UINT16(fat_entry, new_entry);
}
}
/* find if this is the end of cluster mark */
int is_eoc_fat12(UINT32 cluster, PartitionInfo *pi)
{
return (cluster >= FAT12_EOC);
}
int is_valid_cluster_fat12(UINT32 cluster, PartitionInfo *pi)
{
return (cluster < MAX_FAT12_CLUSTERS);
}
/* next_cluster_fat12: given a cluster number, return the
* cluster that is next in this cluster chain by looking
* into the FAT data structure for this partition
*
* For FAT12, each entry in the FAT is 1.5 bytes = 12 bits.
* This results in two complications:
* 1. A single FAT entry may span two sectors.
* 2. After reading in 16 bits, 12 bits must be extracted
* depending on whether the cluster # is even or odd.
*/
UINT32 next_cluster_fat12(UINT32 cluster, PartitionInfo * pi)
{
BYTE buf[SECTORSIZE*2];
UINT32 TempNextCluster;
UINT32 Fat0SectorNum;
UINT32 Fat1SectorNum;
int NextClusterPosition;
if (cluster > MAX_FAT12_CLUSTERS)
return BAD_CLUSTER;
Fat0SectorNum = pi->op->get_fat_sector_for_cluster(cluster, pi);
NextClusterPosition = pi->op->get_fat_offset_for_cluster(cluster, pi);
if (read_sector(Fat0SectorNum, buf) != SECTORSIZE)
return BAD_CLUSTER;
/* Additionally (as compared to FAT 16/32 we have to see if the entry
* spans a sector boundary, and if so read in the next sector.
*/
if (NextClusterPosition == SECTORSIZE - 1)
if (read_sector(Fat0SectorNum + 1, buf + SECTORSIZE) != SECTORSIZE)
return BAD_CLUSTER;
TempNextCluster = get_next_cluster_fat12(buf + NextClusterPosition, pi, cluster);
/* check for FAT misMatch !!! */
if (pi->NumberOfFats > 1) {
UINT32 FAT1_TempNextCluster = 0;
Fat1SectorNum = Fat0SectorNum + pi->SectorsPerFat;
if (read_sector(Fat1SectorNum, buf) != SECTORSIZE)
return 0;
if (NextClusterPosition == SECTORSIZE - 1)
if (read_sector(Fat0SectorNum + 1, buf + SECTORSIZE) != SECTORSIZE)
return BAD_CLUSTER;
FAT1_TempNextCluster = get_next_cluster_fat12(buf + NextClusterPosition, pi, cluster);
if (TempNextCluster != FAT1_TempNextCluster)
return BAD_CLUSTER; /* FAT tables don't match bail */
}
return (TempNextCluster);
}
/* Follow the cluster chain in FAT12 and free all allotted clusters. */
int free_cluster_chain_fat12(UINT32 cluster, PartitionInfo *pi)
{
UINT32 sector_in_buf = 0;
UINT32 sector, offset, old_cluster;
int modified = 0; /* denotes if the sector_in_buf has been modified */
int used_second_sector = 0; /* denotes if a 2nd sector was read & modified */
char buf[SECTORSIZE*2];
while (!pi->op->is_eoc(cluster, pi)) {
sector = pi->op->get_fat_sector_for_cluster(cluster, pi);
debug_xil_printf("%d: cluster: %d is at sector: %d\n\r", __LINE__,
(int)cluster, (int)sector);
if (sector != sector_in_buf) { /* have to read in a new sector from FAT */
/* write to disk if the old sector was modified */
if (modified) {
if (write_sector(sector_in_buf, buf) != SECTORSIZE)
return -1;
/* update FAT 2 */
if (pi->NumberOfFats > 1)
if (write_sector(sector_in_buf + pi->SectorsPerFat, buf)
!= SECTORSIZE)
return -1;
/* if the writes had spanned 2 sectors, then write out
* the 2nd sector too
*/
if (used_second_sector) {
if (write_sector(sector_in_buf,
buf + SECTORSIZE) != SECTORSIZE)
return -1;
/* update FAT 2 */
if (pi->NumberOfFats > 1)
if (write_sector(sector_in_buf + pi->SectorsPerFat,
buf + SECTORSIZE) != SECTORSIZE)
return -1;
used_second_sector = 0;
}
debug_xil_printf("written modified sec %d\n", (unsigned int)sector_in_buf);
modified = 0;
}
debug_xil_printf("%s @ %d, reading in new sector\n\r",
__FUNCTION__, __LINE__);
/* read in the new sector */
if (read_sector(sector, buf) != SECTORSIZE)
return -1;
sector_in_buf = sector;
}
offset = pi->op->get_fat_offset_for_cluster(cluster, pi);
if (offset == SECTORSIZE - 1) { /* FAT entry spans sector boundary */
if (read_sector(sector, buf + SECTORSIZE) != SECTORSIZE)
return 0;
used_second_sector = 1;
}
/* obtain the current value & reset it to zero */
old_cluster = cluster;
cluster = get_next_cluster_fat12(buf + offset, pi, cluster);
set_next_cluster_fat12(buf + offset, 0, pi, old_cluster);
modified = 1;
}
if (modified) {
if (write_sector(sector_in_buf, buf) != SECTORSIZE)
return -1;
/* update FAT 2 */
if (pi->NumberOfFats > 1)
if (write_sector(sector_in_buf + pi->SectorsPerFat, buf)
!= SECTORSIZE)
return -1;
/* if the writes had spanned 2 sectors, then write out
* the 2nd sector too
*/
if (used_second_sector) {
if (write_sector(sector_in_buf,
buf + SECTORSIZE) != SECTORSIZE)
return -1;
/* update FAT 2 */
if (pi->NumberOfFats > 1)
if (write_sector(sector_in_buf + pi->SectorsPerFat,
buf + SECTORSIZE) != SECTORSIZE)
return -1;
used_second_sector = 0;
}
debug_xil_printf("written modified sec %d\n", (unsigned int)sector_in_buf);
modified = 0;
}
return 0;
}
int link_cluster_fat12(UINT32 from_cluster, UINT32 to_cluster, PartitionInfo *pi)
{
UINT32 sector = pi->op->get_fat_sector_for_cluster(from_cluster, pi);
UINT32 offset = pi->op->get_fat_offset_for_cluster(from_cluster, pi);
BYTE buf[SECTORSIZE*2];
if (read_sector(sector, buf) != SECTORSIZE)
return -1;
if (offset == SECTORSIZE - 1) {
/* read in next sector if this FAT entry spans two sectors */
if (read_sector(sector + 1, buf + SECTORSIZE) != SECTORSIZE)
return -1;
}
/* set the next cluster for from_cluster to to_cluster */
set_next_cluster_fat12(buf + offset, to_cluster, pi, from_cluster);
if (write_sector(sector, buf) != SECTORSIZE)
return -1;
if (offset == SECTORSIZE - 1)
if (write_sector(sector + 1, buf + SECTORSIZE) != SECTORSIZE)
return -1;
/* update 2nd FAT if present */
if (pi->NumberOfFats > 1) {
if (write_sector(sector + pi->SectorsPerFat, buf) != SECTORSIZE)
return -1;
if (offset == SECTORSIZE - 1)
if (write_sector(sector + 1 + pi->SectorsPerFat, buf + SECTORSIZE)
!= SECTORSIZE)
return -1;
}
return 0;
}
/* find a free cluster, set the next entry of that cluster to EOC
* and return that cluster.
*/
UINT32 allocate_one_cluster_fat12(PartitionInfo *pi)
{
UINT32 cluster = 0;
for (cluster = 2;
cluster < (pi->TotalSectors/pi->SectorsPerCluster);
cluster++)
if (next_cluster(cluster, pi) == 0) {
link_cluster_fat12(cluster, FAT12_EOC, pi);
return cluster;
}
return 0;
}
fat_ops fat12_ops = {
get_fat12_sector_for_cluster,
get_fat12_offset_for_cluster,
0,
0,
is_eoc_fat12,
is_valid_cluster_fat12,
next_cluster_fat12,
free_cluster_chain_fat12,
allocate_one_cluster_fat12,
link_cluster_fat12,
};
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_fat16.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_fat16.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_fat16.c
===================================================================
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
/////////////////////////////////////////////////////////////////////////////
#include "fat.h"
#include "directory.h"
#include "util.h"
UINT32 get_fat16_sector_for_cluster(UINT32 cluster, PartitionInfo *pi)
{
/* Each FAT entry takes 2 bytes in FAT 16 */
return ((cluster * 2) / SECTORSIZE) + pi->FatSector;
}
UINT32 get_fat16_offset_for_cluster(UINT32 cluster, PartitionInfo *pi)
{
/* Each FAT entry takes 2 bytes in FAT 16 */
return ((cluster * 2) % SECTORSIZE);
}
UINT32 get_next_cluster_fat16(BYTE *fat_entry, PartitionInfo *pi)
{
return (UINT32)(0xffff & make_UINT16(*(fat_entry + 1), *(fat_entry)));
}
void set_next_cluster_fat16(BYTE *fat_entry, UINT32 next_cluster, PartitionInfo *pi)
{
write_UINT16(fat_entry, next_cluster);
}
int is_eoc_fat16(UINT32 cluster, PartitionInfo *pi)
{
return (cluster >= FAT16_EOC);
}
int is_valid_cluster_fat16(UINT32 cluster, PartitionInfo *pi)
{
return (cluster < MAX_FAT16_CLUSTERS);
}
fat_ops fat16_ops = {
get_fat16_sector_for_cluster,
get_fat16_offset_for_cluster,
get_next_cluster_fat16,
set_next_cluster_fat16,
is_eoc_fat16,
is_valid_cluster_fat16,
next_cluster_generic,
free_cluster_chain_generic,
allocate_one_cluster_generic,
link_cluster_generic,
};
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_fat32.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_fat32.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_fat32.c
===================================================================
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
/////////////////////////////////////////////////////////////////////////////
#include "fat.h"
#include "directory.h"
#include "util.h"
/* given the cluster #, find the sector in the partition where
* the FAT entry for that cluster is present
*/
UINT32 get_fat32_sector_for_cluster(UINT32 cluster, PartitionInfo *pi)
{
/* Each FAT entry takes 4 bytes in FAT 32 */
return ((cluster * 4) / SECTORSIZE) + pi->FatSector;
}
UINT32 get_fat32_offset_for_cluster(UINT32 cluster, PartitionInfo *pi)
{
/* Each FAT entry takes 4 bytes in FAT 32 */
return ((cluster * 4) % SECTORSIZE);
}
UINT32 get_next_cluster_fat32(BYTE *fat_entry, PartitionInfo *pi)
{
return 0x0FFFFFFF & make_UINT32(*(fat_entry + 3),
*(fat_entry + 2),
*(fat_entry + 1),
*(fat_entry));
}
void set_next_cluster_fat32(BYTE *fat_entry, UINT32 next_cluster, PartitionInfo *pi)
{
UINT32 old_entry;
/* extract the higher order 4 bits from old entry */
old_entry = 0xf0000000 & make_UINT32(*(fat_entry + 3),
*(fat_entry + 2),
*(fat_entry + 1),
*(fat_entry));
next_cluster &= 0x0fffffff;
next_cluster |= old_entry;
write_UINT32(fat_entry, next_cluster);
}
int is_eoc_fat32(UINT32 cluster, PartitionInfo *pi)
{
return (cluster >= FAT32_EOC);
}
int is_valid_cluster_fat32(UINT32 cluster, PartitionInfo *pi)
{
return (cluster < MAX_FAT32_CLUSTERS);
}
fat_ops fat32_ops = {
get_fat32_sector_for_cluster,
get_fat32_offset_for_cluster,
get_next_cluster_fat32,
set_next_cluster_fat32,
is_eoc_fat32,
is_valid_cluster_fat32,
next_cluster_generic,
free_cluster_chain_generic,
allocate_one_cluster_generic,
link_cluster_generic,
};
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_filespec.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_filespec.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_filespec.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <ctype.h>
#include "filespec.h"
/* Routines to parse out path names. The only characters that are
* checked for are \ (backslash), . (period) and : (colon). The
* rest are treated as valid characters for names.
*
* Examine path to see if it starts with a directory name.
* If so, copy it to buf and return number of characters
* consumed. If buf is too short, 0 is returned. The is_dir
* flags says that we expect this to be a directory specifier, i.e.
* a trailing name with no file extension is a directory name,
* not a file name. The root flag says that this might be the root
* directory, i.e if it starts with backslash, return just that.
*/
static int find_dir(const char *path, char *buf, int length, int is_dir,
int root)
{
int i = 0;
int relative = 0;
if (root && path[0] == DIRSEPCHAR) {
/* This is the root */
if (length < 2)
return 0;
buf[0] = DIRSEPCHAR;
buf[1] = 0;
return 1;
}
while (i < length) {
if (path[i] == 0) {
/* End of string - could be a directory or a file
* name that has no extension */
if (is_dir) {
/* Last field is a directory */
buf[i] = 0;
return i;
} else {
/* Last field is a file */
return 0;
}
}
if (path[i] == DIRSEPCHAR) {
if (i > 0) {
/* hierarchy separator */
buf[i] = 0;
return i + 1; /* eat the directory separator too */
} else
return 0;
}
/* Look for bad characters */
if (path[i] == '.') {
if (i == 0)
relative = 1;
else if (i > 1 || !relative)
return 0;
}
if (path[i] == ':')
return 0;
/* Keep copying - so far so good */
buf[i] = path[i];
++i;
}
/* Never found the end of this name */
return 0;
}
/* Examine path to see if it starts with a device spec.
* If so, copy it to buf and return the number of chars
* consumed. If buf is too short, 0 is returned.
* Device spec can be a DOS style (e.g. a:) or network
* style (e.g. \\server).
*/
static int find_device(const char *path, char *buf, int length)
{
char c;
int i;
/* look for server form */
if (path[0] == DIRSEPCHAR && path[1] == DIRSEPCHAR) {
/* Find the server name - it looks just like a directory name */
i = 0;
while (i < length) {
if (path[i + 2] == 0 || path[i + 2] == DIRSEPCHAR) {
/* hit end of server name */
buf[i] = 0;
return i + 2; /* eat the double backslash too */
}
/* Watch for illegal characters */
if (path[i + 2] == '.' || path[i + 2] == ':')
return 0;
buf[i] = path[i + 2];
++i;
}
return 0;
}
/* Must be a plain old DOS disk (letter colon) */
if (length < 2 || path[0] == 0 || path[1] != ':')
return 0;
c = tolower(path[0]);
if (c < 'a' || c > 'z')
return 0;
/* It was a device */
buf[0] = c;
buf[1] = 0;
return 2;
}
/* Examine path to see if it starts with a file name.
* If so, copy it to buf and return number of characters
* consumed. If buf is too short, 0 is returned. The is_dir
* flags says that we expect this to be a directory specifier, i.e.
* a trailing name with no file extension is a directory name,
* not a file name.
*/
static int find_file(const char *path, char *buf, int length, int is_dir)
{
int i = 0;
/* Do not apply file name rules if this is known to be a directory path */
if (is_dir)
return 0;
while (i < length) {
if (path[i] == 0) {
/* End of string - file has no extension */
buf[i] = 0;
return i;
}
if (path[i] == '.') {
/* Hit the file extension */
buf[i] = 0;
return i;
}
/* Look for bad characters */
if (path[i] == DIRSEPCHAR || path[i] == ':')
return 0;
/* Keep copying - so far so good */
buf[i] = path[i];
++i;
}
/* Never found the end of this name */
return 0;
}
static int find_ext(const char *path, char *buf, int length)
{
int i = 0;
/* Must start with a dot */
if (path[0] != '.')
return 0;
while (i < length) {
/* 3 character max */
if (i > 3)
return 0;
if (path[i + 1] == 0) {
buf[i] = 0;
return i + 1;
}
/* Look for bad characters */
if (path[i + 1] == '.' || path[i + 1] == DIRSEPCHAR
|| path[i + 1] == ':')
return 0;
/* Keep copying - so far so good */
buf[i] = path[i + 1];
++i;
}
/* Never found the end of this name */
return 0;
}
/* Find the next field in the path. Returns the number of characters
* consumed by this field. The field type pointed to by type should
* Be set initially to 'START' and will be updated after the field
* has been found. The identified field will be stored in buf (up to l
* characters) - if it does not fit, there will be an error.
* The flag is_dir says that the path is a directory path, i.e. the
* last field will be treated as a directory, not a file with no
* extension.
*/
int parse_path(const char *path, char *buf, int length,
int is_dir, field_type * type)
{
int i = 0;
switch (*type) {
case PATH_START:
/* String cannot be empty */
if (*path == 0) {
*type = PATH_ERROR;
break;
}
/* Can start with device, directory or file */
if ((i = find_device(path, buf, length)) > 0)
*type = DEVICE_NAME;
else if ((i = find_dir(path, buf, length, is_dir, 1)) > 0)
*type = DIR_NAME;
else if ((i = find_file(path, buf, length, is_dir)) > 0)
*type = FILE_NAME;
else
*type = PATH_ERROR;
break;
case DEVICE_NAME:
/* String cannot be empty if we are looking for a file name */
if (*path == 0) {
if (!is_dir)
*type = PATH_ERROR;
else
*type = PATH_DONE;
break;
}
/* Device can be followed by directory or file */
if ((i = find_dir(path, buf, length, is_dir, 1)) > 0)
*type = DIR_NAME;
else if ((i = find_file(path, buf, length, is_dir)) > 0)
*type = FILE_NAME;
else
*type = PATH_ERROR;
break;
case DIR_NAME:
/* String cannot be empty if we are looking for a file name */
if (*path == 0) {
if (!is_dir)
*type = PATH_ERROR;
else
*type = PATH_DONE;
break;
}
/* Directory can be followed by directory or file */
if ((i = find_dir(path, buf, length, is_dir, 0)) > 0)
*type = DIR_NAME;
else if ((i = find_file(path, buf, length, is_dir)) > 0)
*type = FILE_NAME;
else
*type = PATH_ERROR;
break;
case FILE_NAME:
if (*path == 0)
*type = PATH_DONE;
else if ((i = find_ext(path, buf, length)) > 0)
*type = FILE_EXT;
else
*type = PATH_ERROR;
break;
case FILE_EXT:
if (*path == 0)
*type = PATH_DONE;
else
*type = PATH_ERROR;
break;
default:
*type = PATH_ERROR;
break;
}
return i;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_filestatus.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_filestatus.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_filestatus.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include "filestatus.h"
#include "alloc.h"
/* global static for linked list start pointer */
static FileStatus *FileListHead = 0;
/* find the filestatus corresponding to a given stream */
FileStatus *find_file_status(SYSACE_FILE *stream)
{
FileStatus *fs;
for (fs = FileListHead; fs; fs = fs->next)
if (fs == stream)
return fs;
return 0;
}
/* Create a new FILEINFO and add to list.
* Fail if file is already open for write
*/
FileStatus *create_file_status(WorkingDirectory * wd,
BYTE read, BYTE write)
{
FileStatus *ps;
/* See it this file is already opened */
for (ps = FileListHead; ps; ps = ps->next) {
if (ps->wd->v.child.FirstCluster ==
wd->v.child.FirstCluster && (write || ps->write))
return 0;
}
if ((ps = malloc_fs()) == 0)
return 0;
ps->wd = wd;
ps->read = read;
ps->write = write;
ps->CurrentCluster = wd->v.child.FirstCluster;
ps->PositionInCluster = 0;
ps->PositionInFile = 0;
ps->next = FileListHead;
FileListHead = ps;
return ps;
}
int delete_file_status(FileStatus * status)
{
FileStatus *ps;
/* First unlink this item */
if (FileListHead == status) {
/* It's the first item, just step over it */
FileListHead = status->next;
} else {
/* It's further down the list - keep looking */
for (ps = FileListHead; ps; ps = ps->next) {
if (ps->next == status) {
/* found it - remove from list */
ps->next = status->next;
/* Stop search */
break;
}
}
if (ps == 0) {
/* Went through whole list and it wasn't there!! */
return -1;
}
}
delete_working_directory_stack(status->wd);
free_fs(status);
return 0;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_mkdir.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_mkdir.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_mkdir.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include "fat.h"
#include "filespec.h"
#include "directory.h"
#include "util.h"
DirectoryEntry dotdot_entry[2];
int sysace_mkdir(const char *path)
{
WorkingDirectory *wd = build_working_directory_stack(path, 1, 1);
if (wd) { /* create dir succeeded */
delete_working_directory_stack(wd);
sync_bufcache();
return 0;
} else
return -1;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_open.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_open.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_open.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include "sysace_stdio.h"
#include "fat.h"
#include "filestatus.h"
SYSACE_FILE *sysace_fopen(const char *file, const char *mode)
{
BYTE read = 0;
BYTE write = 0;
WorkingDirectory *wd;
FileStatus *ps;
/* only "r" and "w" modes are supported */
if (!strcmp(mode, "r"))
read = 1;
else if (!strcmp(mode, "w"))
write = 1;
else
return 0;
/* create a working directory stack for the file */
if ((wd = build_working_directory_stack(file, 0, write)) == 0)
return 0;
if ((ps = create_file_status(wd, read, write)) == 0) {
delete_working_directory_stack(wd);
return 0;
}
return (SYSACE_FILE *) ps;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_part.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_part.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_part.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <ctype.h>
#include <string.h>
#include "fat.h"
#include "directory.h"
#include "util.h"
/* The partition info buffers can be statically allocated.
* Never free a pi !
*/
static PartitionInfo pibuf[MAXPARTITION];
/* Make a new PartitionInfo structure and populate it */
PartitionInfo *get_partition_info(int partition)
{
BYTE buf[SECTORSIZE];
MasterBootRecord *mbr;
PartitionEntry *pe;
PartitionBootRecord *pbr;
UINT16 total16;
UINT32 total32;
UINT16 reserved;
UINT32 partitionSize, rootSize, dataClusters, dataOffset, fatSize;
PartitionInfo *pi;
static int sysace_initialized = 0;
if (partition < 0 || partition >= MAXPARTITION)
return 0;
pi = pibuf + partition;
pi->PartitionNum = partition;
if (!sysace_initialized) { /* initialize sysace the first time around */
if (init_ace() < 0)
return 0;
sysace_initialized = 1;
}
/* Master Boot Record is always sector 0 */
if (read_sector(0, buf) != SECTORSIZE)
return 0;
mbr = (MasterBootRecord *) buf;
/* Check Signature */
if (mbr->Signature[0] != 0x55 || mbr->Signature[1] != 0xaa)
return 0;
/* Point to the Relevant Partition Entry */
pe = &(mbr->PartitionEntry[partition]);
pi->StartSector =
make_UINT32(pe->PartitionSector[3], pe->PartitionSector[2],
pe->PartitionSector[1], pe->PartitionSector[0]);
partitionSize =
make_UINT32(pe->TotalSectors[3], pe->TotalSectors[2],
pe->TotalSectors[1], pe->TotalSectors[0]);
/* Read the Partition Boot Record */
if (read_sector(pi->StartSector, buf) != SECTORSIZE)
return 0;
pbr = (PartitionBootRecord *) buf;
/* Determine the total number of sectors in this partition
* It may be specified in 16 or 32 bits */
total16 =
make_UINT16(pbr->BPB.TotalSectors16[1],
pbr->BPB.TotalSectors16[0]);
total32 =
make_UINT32(pbr->BPB.TotalSectors32[3],
pbr->BPB.TotalSectors32[2],
pbr->BPB.TotalSectors32[1],
pbr->BPB.TotalSectors32[0]);
if (total16) {
if (total32 != 0 && total32 != total16)
return 0;
pi->TotalSectors = (UINT32) total16;
} else {
if (total32 == 0)
return 0;
pi->TotalSectors = total32;
}
if (pi->TotalSectors > partitionSize)
return 0;
pi->BytesPerSector = make_UINT16(pbr->BPB.BytesPerSector[1],
pbr->BPB.BytesPerSector[0]);
/* Check against compile-time constants
* currently allow only 512 bytes per sec */
if (pi->BytesPerSector != SECTORSIZE)
return 0;
pi->SectorsPerCluster = pbr->BPB.SectorsPerCluster;
if (pi->SectorsPerCluster == 0) {
/* Protect division later on! */
return 0;
}
/* sanity check for SectorsPerCluster:
* should be a power of 2
* should be <= 128
* should be such that bytes per cluster <= 32k (MAX_BYTES_PER_CLUSTER)
*/
if (pi->SectorsPerCluster & (pi->SectorsPerCluster - 1))
return 0;
if (pi->SectorsPerCluster > 128)
return 0;
if (pi->SectorsPerCluster * pi->BytesPerSector > MAX_BYTES_PER_CLUSTER)
return 0;
reserved = make_UINT16(pbr->BPB.ReservedSector[1],
pbr->BPB.ReservedSector[0]);
pi->NumberOfFats = pbr->BPB.NumberOfFats;
pi->RootDirCount = make_UINT16(pbr->BPB.RootDirCount[1],
pbr->BPB.RootDirCount[0]);
pi->SectorsPerFat = (UINT32) make_UINT16(pbr->BPB.SectorsPerFat[1],
pbr->BPB.SectorsPerFat[0]);
if (pi->SectorsPerFat == 0) {
/* check if the fat32 entry is present
* if not then this is invalid FAT
*/
pi->SectorsPerFat = make_UINT32(pbr->BPB.SectorsPerFat_32[3],
pbr->BPB.SectorsPerFat_32[2],
pbr->BPB.SectorsPerFat_32[1],
pbr->BPB.SectorsPerFat_32[0]);
if (pi->SectorsPerFat == 0)
return 0;
}
/* Determine the FAT type based on the # of data clusters */
rootSize =
((pi->RootDirCount << LOG2_DIRENT_SIZE) + SECTORSIZE -
1) / SECTORSIZE;
fatSize = pi->SectorsPerFat * pi->NumberOfFats;
dataOffset = reserved + fatSize + rootSize;
dataClusters =
(pi->TotalSectors - dataOffset) / pi->SectorsPerCluster;
if (dataClusters < MAX_FAT12_CLUSTERS) {
debug_print("FAT12 PARTITION\n\r");
pi->FatType = FAT12;
#ifdef CONFIG_FAT12
pi->op = &fat12_ops;
#else
pi->op = NULL;
#endif
} else if (dataClusters < MAX_FAT16_CLUSTERS) {
debug_print("FAT16 PARTITION\n\r");
pi->FatType = FAT16;
pi->op = &fat16_ops;
} else {
pi->FatType = FAT32;
debug_print("FaT32 PARTITION\n\r");
pi->op = &fat32_ops;
}
/* more consistency checks */
switch (pi->FatType) {
case FAT12:
case FAT16:
if (reserved != 1)
return 0;
/* pi->RootDirCount * 32 should be an even multiple
* of BytesPerSector */
if ((pi->RootDirCount * 32) % pi->BytesPerSector)
return 0;
if (((pi->RootDirCount * 32) / pi->BytesPerSector) % 2)
return 0;
break;
case FAT32:
if (pi->RootDirCount != 0)
return 0;
break;
default:
return 0;
}
pi->FatSector = pi->StartSector + reserved;
pi->RootDirSector = pi->FatSector + fatSize;
pi->DataSector = pi->RootDirSector + rootSize;
if (pi->FatType == FAT32) {
pi->RootCluster = make_UINT32(pbr->BPB.RootCluster[3],
pbr->BPB.RootCluster[2],
pbr->BPB.RootCluster[1],
pbr->BPB.RootCluster[0]);
}
return pi;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_read.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_read.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_read.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include "filestatus.h"
#include "sysace_stdio.h"
#include "fat.h"
#if defined( DUMMY_DISK )
static char *dummy_data = "Are we there yet?\n";
#endif
int read_from_file(FileStatus * fs, char *buf, int count)
{
int readcount, n;
int remaining;
BYTE sectorbuf[SECTORSIZE];
UINT32 sector;
UINT32 filesize;
UINT32 nsectors;
UINT32 sector_offset;
int byte_offset;
/* Safety check */
if (fs == 0 || !fs->read || count < 0)
return 0;
filesize = fs->wd->v.child.FileSize;
if (fs->PositionInFile >= filesize)
return 0;
readcount = 0;
/* Compute number of bytes left to read - may be limited
* by size of users buf or by file size */
remaining = filesize - fs->PositionInFile;
if (count < remaining)
remaining = count;
while (fs->PositionInFile < filesize) {
/* Which sector of this cluster did we leave off at last time ? */
sector_offset = fs->PositionInCluster / SECTORSIZE;
/* Which byte of that sector did we leave off at last time ? */
byte_offset = fs->PositionInCluster % SECTORSIZE;
/* Sector address to start reading this time */
sector = starting_sector(fs->CurrentCluster, fs->wd->pi);
if (sector == 0) {
/* FAT problem ? */
return 0;
}
sector += sector_offset;
/* How many sectors left to read in this cluster */
nsectors = fs->wd->pi->SectorsPerCluster - sector_offset;
while (nsectors) {
if (read_sector(sector, sectorbuf) != SECTORSIZE)
return -1;
if (remaining <= (SECTORSIZE - byte_offset)) {
/* End of file or end of buffer occurs in this sector
* Read what's left and quit */
memcpy(buf + readcount,
(char *) (sectorbuf + byte_offset),
remaining);
fs->PositionInFile += remaining;
fs->PositionInCluster += remaining;
return (remaining + readcount);
}
/* End of file is beyond this sector */
n = SECTORSIZE - byte_offset;
memcpy(buf + readcount,
(char *) (sectorbuf + byte_offset), n);
fs->PositionInFile += n;
fs->PositionInCluster += n;
readcount += n;
remaining -= n;
/* Point to start of next sector in cluster */
byte_offset = 0;
sector += 1;
nsectors -= 1;
} /* end of while */
/* Done with that cluster, advance to the next one */
fs->CurrentCluster = next_cluster(fs->CurrentCluster, fs->wd->pi);
if (fs->CurrentCluster == BAD_CLUSTER) {
/* Bad cluster address - this means that there is a FAT problem,
* because we should have dtected that this was the last cluster
* based on filesize. The file system is hosed. */
return 0;
}
/* We are at the start of this new cluster */
fs->PositionInCluster = 0;
}
return readcount;
}
int sysace_fread(void *buffer, int size, int count, SYSACE_FILE *stream)
{
FileStatus *fs = find_file_status(stream);
if (fs == 0)
return -1;
return read_from_file(fs, (char *) buffer, size * count);
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_readdisk.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_readdisk.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_readdisk.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
/* All functions have been moved to other files */
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_standalone-utils.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_standalone-utils.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_standalone-utils.c
===================================================================
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
/////////////////////////////////////////////////////////////////////////////
/* Define the same functions present in sysace.c & sysace_stdio.c
* only these now work on a file (virtualized disk) rather than
* the compact flash
*/
#include <stdio.h>
#include <sysace.h>
/* pointer to the virtual disk */
FILE *disk_fp;
char *diskpath = "../cfdisk";
int init_ace()
{
disk_fp = fopen(diskpath, "r+");
if (!disk_fp) {
printf("%s: Error opening virtual disk: %s\n", __FUNCTION__, diskpath);
return -1;
}
return 0;
}
int read_sector(UINT32 sector, BYTE *sector_buf)
{
/* fseek to the correct position & return the sector */
if (fseek(disk_fp, sector * SECTORSIZE, SEEK_SET) < 0) {
printf("error while seeking..\n");
return -1;
}
return fread(sector_buf, 1, SECTORSIZE, disk_fp);
}
int write_sector(UINT32 sector, BYTE *sector_buf)
{
/* fseek to the correct position & write the sector */
if (fseek(disk_fp, sector * SECTORSIZE, SEEK_SET) < 0) {
printf("error while seeking..\n");
return -1;
}
return fwrite(sector_buf, 1, SECTORSIZE, disk_fp);
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_stats.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_stats.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_stats.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include "stats.h"
#include "util.h"
unsigned int xilfatfs_stats_read;
unsigned int xilfatfs_stats_write;
void init_xilfatfs_stats()
{
xilfatfs_stats_read = 0;
xilfatfs_stats_write = 0;
}
void dump_xilfatfs_stats()
{
xil_printf("# of sysace reads: %d\n\r", xilfatfs_stats_read);
xil_printf("# of sysace writes: %d\n\r", xilfatfs_stats_write);
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_sysace.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_sysace.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_sysace.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include "xparameters.h"
#include "sysace.h"
#include "xsysace_l.h"
#include "xsysace.h"
#include "xstatus.h"
#include "xbasic_types.h"
#include "xio.h"
#include "bufcache.h"
#include "stats.h"
static Xuint32 sysace_base_addr = 0;
int read_sector_cf(UINT32 sector, BYTE *pSectorBuffer)
{
xilfatfs_stats_read++;
return XSysAce_ReadSector(sysace_base_addr,
sector, pSectorBuffer);
}
int write_sector_cf(UINT32 sector, BYTE *pSectorBuffer)
{
xilfatfs_stats_write++;
return XSysAce_WriteSector(sysace_base_addr,
sector, pSectorBuffer);
}
/***** initalize system ace for reading and writing *****/
int init_ace()
{
XSysAce Ace;
XStatus Result;
XStatus status_init;
/* This code assumes only one systemace interface in the build and its Device ID is 0*/
status_init = XSysAce_Initialize(&Ace, 0);
sysace_base_addr = Ace.BaseAddress;
while ((Result = XSysAce_Lock(&Ace, XFALSE)) != XST_SUCCESS)
;
XSysAce_RegWrite32(sysace_base_addr + XSA_CR_OFFSET,
XSA_CR_FORCECFGMODE_MASK);
init_bufcache(write_sector_cf);
return (int) (status_init);
}
int read_sector(UINT32 sector, BYTE *sector_buf)
{
if (is_buffered(sector) < 0) { /* sector not buffered */
int n = read_sector_cf(sector, sector_buf);
if (n == SECTORSIZE) { /* if valid data read */
if (update_bufcache(sector, sector_buf, 0) < 0)
return -1;
}
return n;
} else { /* sector already present in buffer */
return read_bufcache(sector, sector_buf);
}
}
int write_sector(UINT32 sector, BYTE *sector_buf)
{
return update_bufcache(sector, sector_buf, 1);
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_sysace_stdio.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_sysace_stdio.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_sysace_stdio.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
/* All functions have been moved to other files */
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_wd.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_wd.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_wd.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <ctype.h>
#include <string.h>
#include "fat.h"
#include "filespec.h"
#include "alloc.h"
#include "directory.h"
#include "util.h"
/* Defaults to all zeros */
WorkingDirectory *cwd[MAXPARTITION] = { 0 };
int DefaultPartition = 0;
void delete_working_directory_stack(WorkingDirectory * wd)
{
WorkingDirectory *parent;
while (wd) {
parent = wd->parent;
free_wd(wd);
wd = parent;
}
return;
}
#define WD_BUFSIZE 10
#define WD_EXT_BUFSIZE 5
WorkingDirectory *_build_working_directory_stack(const char *path,
int is_dir, int create)
{
char buf[WD_BUFSIZE];
char ext_buf[WD_EXT_BUFSIZE];
field_type type = PATH_START;
WorkingDirectory *wd = 0;
WorkingDirectory *child;
int i = 0;
int partition = DefaultPartition;
#if defined(CONFIG_WRITE) && defined(CONFIG_DIR_SUPPORT)
char leaf_buf[WD_BUFSIZE];
#endif
while (type != PATH_DONE) {
i += parse_path(path + i, buf, WD_BUFSIZE, is_dir, &type);
switch (type) {
case DEVICE_NAME:
/* Cannot support server spec */
if (strlen(buf) > 1) {
delete_working_directory_stack(wd);
return 0;
}
/* interpret drive letter */
if ((partition = tolower(buf[0]) - 'a') < 0
|| partition >= MAXPARTITION) {
delete_working_directory_stack(wd);
return 0;
}
break;
case DIR_NAME:
if (wd == 0 && !strcmp(buf, DIRSEPSTRING)) {
/* The specification is absolute - this is the root directory */
if ((wd = make_root_directory(partition)) == 0)
return 0;
break;
}
if (wd == 0) {
/* This is a relative pathname - see if there is a CWD for this partition.
* If not, default to the root directory for the partition. Then duplicate
* the default stack so that the child can be appended. */
if (cwd[partition] == 0)
cwd[partition] =
make_root_directory(partition);
if (cwd[partition] == 0)
return 0;
wd = copy_directory_stack(cwd[partition]);
if (wd == 0)
return 0;
}
/* Add the child directory to the path */
if ((child = make_child_directory(buf, NULL, wd)) == 0) {
#if defined(CONFIG_WRITE) && defined(CONFIG_DIR_SUPPORT)
if ((!is_dir) || (is_dir && !create))
#endif
{
delete_working_directory_stack(wd);
return 0;
}
}
#if defined(CONFIG_WRITE) && defined(CONFIG_DIR_SUPPORT)
/* request to create a directory */
if (is_dir && create && (child == 0)) {
/* create only if we are at the leaf */
parse_path(path + i, leaf_buf, WD_BUFSIZE, is_dir, &type);
if (type != PATH_DONE) {
/* we are not at the leaf, but couldn't go further
* so invalid path */
return 0;
} else /* we are at the leaf, so we need to create the directory */
return create_file_entry(buf, "", wd, ATTR_DIRECTORY);
}
#endif
wd = child;
break;
case FILE_NAME:
/* Buf contains a filename - now see if there is an extension there */
parse_path(path + i, ext_buf, WD_EXT_BUFSIZE,
is_dir, &type);
if (type == PATH_DONE) { /* The extension is empty */
ext_buf[0] = 0;
} else if (type != FILE_EXT) { /* There was an error */
delete_working_directory_stack(wd);
return 0;
}
if (wd == 0) { /* There is no directory, so copy over the cwd */
if (cwd[partition] == 0)
cwd[partition] = make_root_directory(partition);
if (cwd[partition] == 0)
return 0;
wd = copy_directory_stack(cwd[partition]);
if (wd == 0)
return 0;
}
/* See if this file exists */
if ((child = make_child_directory(buf, ext_buf, wd)) == 0) {
#ifdef CONFIG_WRITE
if (!create) /* no such file, and no request to create one */
#endif
{
delete_working_directory_stack(wd);
return 0;
}
}
/* if this is a request to create an entry, then
* create an entry if none exists
*/
#ifdef CONFIG_WRITE
if (create && child == 0) {
/* search for a free directory entry
* make a new entry with size 0
*/
child = create_file_entry(buf, ext_buf, wd, 0);
}
#endif
return child;
case PATH_DONE:
return wd;
default:
/* Error condition */
delete_working_directory_stack(wd);
return 0;
}
}
return wd;
}
WorkingDirectory *build_working_directory_stack(const char *path,
int is_dir, int write)
{
WorkingDirectory *wd = NULL;
if (write == 0) /* create for read mode */
return _build_working_directory_stack(path, is_dir, 0);
#ifdef CONFIG_WRITE
/* when created in write mode, the file has to be
* truncated if already present
* created if absent
*/
wd = _build_working_directory_stack(path, is_dir, 1);
if (!wd)
return 0;
if (is_dir)
return wd;
/* if this is a pre-existing file (size != 0), then truncate it */
if (wd->v.child.FileSize != 0) {
debug_xil_printf("File already exists..size = %d\n\r",
(unsigned int)wd->v.child.FileSize);
if (truncate_file(wd->v.child.FirstCluster, wd->pi) < 0)
return 0;
/* change filesize to 0.
* the directory entry is not changed yet
*/
wd->v.child.FileSize = 0;
debug_xil_printf("%s @ %d, file truncated\n\r", __FUNCTION__, __LINE__);
} else {
debug_print("File doesn't exist (Created now) or size 0.\n\r");
}
#endif
return wd;
}
void set_child_details(WorkingDirectory *wd, UINT32 firstcluster,
UINT32 filesize, UINT32 de_sector, UINT32 de_offset,
WorkingDirectory *parent)
{
wd->v.child.FirstCluster = firstcluster;
wd->v.child.FileSize = filesize;
wd->v.child.DirLocation.sector = de_sector;
wd->v.child.DirLocation.offset = de_offset;
wd->parent = parent;
wd->pi = parent->pi;
}
WorkingDirectory *make_child_directory(const char *name, const char *ext,
WorkingDirectory * parent)
{
WorkingDirectory *wd;
UINT32 firstcluster;
UINT32 filesize;
UINT32 de_sector;
UINT32 de_offset;
/* find if child is present in given parent directory */
if (!find_in_directory(parent, name, ext, &firstcluster,
&filesize, &de_sector, &de_offset))
return 0;
/* create child wd */
if ((wd = malloc_wd(name)) == 0)
return 0;
set_child_details(wd, firstcluster, filesize, de_sector,
de_offset, parent);
return wd;
}
void set_root_details(WorkingDirectory *wd, PartitionInfo *pi)
{
switch(pi->FatType) {
case FAT12:
case FAT16:
wd->v.root.StartSector = pi->RootDirSector;
wd->v.root.DirCount = pi->RootDirCount;
return;
case FAT32:
wd->v.child.FirstCluster = pi->RootCluster;
return;
}
}
WorkingDirectory *make_root_directory(int partition)
{
WorkingDirectory *wd;
PartitionInfo *pi;
if ((pi = get_partition_info(partition)) == 0)
return 0;
if ((wd = malloc_wd(DIRSEPSTRING)) == 0)
return 0;
wd->parent = 0;
wd->pi = pi;
/* copy over the information about root directory */
set_root_details(wd, pi);
return wd;
}
#ifdef CONFIG_WRITE
/* names are truncated to 8.3 format when writing */
void initialize_de(DirectoryEntry *de,
char *name,
char *ext,
UINT32 firstcluster,
UINT32 filesize,
PartitionInfo *pi,
BYTE attrib)
{
int i;
for (i = 0; i < 8; i++) {
if (*name) {
de->Name[i] = toupper(*name);
name++;
} else
de->Name[i] = ' ';
}
for (i = 0; i < 3; i++) {
if (*ext) {
de->Extension[i] = toupper(*ext);
ext++;
} else
de->Extension[i] = ' ';
}
de->Attributes = attrib;
memset(de->Reserved, 0, 8);
memset(de->Date, 0, 2);
update_de_firstcluster(de, firstcluster, pi);
update_de_filesize(de, filesize);
return;
}
#endif
WorkingDirectory *copy_directory_stack(WorkingDirectory * stack)
{
WorkingDirectory *src, *dest, *first, *previous;
first = 0;
previous = 0;
src = stack;
/* Copy child directories */
while (src) {
dest = malloc_wd(src->name);
if (dest == 0) {
delete_working_directory_stack(first);
return 0;
}
if (first == 0)
first = dest;
if (previous)
previous->parent = dest;
dest->parent = 0;
dest->pi = src->pi;
if (src->parent || src->pi->FatType == FAT32) {
/* Child directory */
dest->v.child.FirstCluster = src->v.child.FirstCluster;
dest->v.child.FileSize = src->v.child.FileSize;
} else {
/* Root directory */
dest->v.root.StartSector = src->v.root.StartSector;
dest->v.root.DirCount = src->v.root.DirCount;
}
src = src->parent;
previous = dest;
}
return first;
}
1.1 mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_write.c
http://www.opencores.org/cvsweb.shtml/mb-jpeg/microblaze_0/libsrc/xilfatfs_v1_00_a/src/src/xilfatfs_write.c?rev=1.1&content-type=text/x-cvsweb-markup
Index: xilfatfs_write.c
===================================================================
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
//
// Xilinx, Inc.
//
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE.
//
////////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include "alloc.h"
#include "fat.h"
#include "filestatus.h"
#include "sysace.h"
#include "sysace_stdio.h"
#include "util.h"
/* write_to_file:
* Write from the current position in chunks of sectors.
* Update the file size in the directory entry
* Update FAT if a new cluster is added
*/
int write_to_file(FileStatus *fs, char *buf, int count)
{
int writecount, n;
int remaining;
BYTE sectorbuf[SECTORSIZE], dir_buf[SECTORSIZE];
UINT32 sector;
UINT32 nsectors;
UINT32 sector_offset;
UINT32 filesize;
int byte_offset;
PartitionInfo *pi = fs->wd->pi;
UINT32 next_cluster;
DirectoryEntry *de;
/* Safety check */
if (fs == 0 || !fs->write || count <= 0)
return 0;
filesize = fs->wd->v.child.FileSize;
debug_xil_printf("Original file size: %d\n\r", (int)filesize);
writecount = 0; /* written til now */
remaining = count; /* remaining left to write */
/* read directory entry for this file. the directory entry
* is updated at the end with the new file size
*/
if (read_sector(fs->wd->v.child.DirLocation.sector, dir_buf) != SECTORSIZE)
return -1;
de = (DirectoryEntry *) (dir_buf + fs->wd->v.child.DirLocation.offset);
/* if this is the first byte of the file, then the firstcluster
* entry for it should be set in its directory entry
*/
if (filesize == 0) {
fs->wd->v.child.FirstCluster = pi->op->allocate_one_cluster(pi);
if (fs->wd->v.child.FirstCluster == 0)
return 0; /* out of space */
fs->CurrentCluster = fs->wd->v.child.FirstCluster;
fs->PositionInCluster = fs->PositionInFile = 0;
/* set the first cluster entry in the directory entry */
debug_xil_printf("First cluster set to: %d\n\r", (int)fs->CurrentCluster);
update_de_firstcluster(de, fs->CurrentCluster, pi);
}
/* if we are currently in the middle of a sector, then read in
* the contents before writing into it.
*/
/* Which byte of that sector did we leave off at last time ? */
byte_offset = fs->PositionInCluster % SECTORSIZE;
if (byte_offset) {
debug_xil_printf("%s @ %d: byte_offset = %d\n\r", __FUNCTION__,
__LINE__, byte_offset);
/* Which secto |