update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@893 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
2c0d7733b9
commit
cd1ddef34a
@ -852,6 +852,10 @@ int cmd_mkrd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
|
||||
fmt = g_fmtcmdoutofmemory;
|
||||
goto errout_with_fmt;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_VERBOSE
|
||||
memset(buffer, 0, sectsize * nsectors);
|
||||
#endif
|
||||
dbg("RAMDISK at %p\n", buffer);
|
||||
|
||||
/* Then register the ramdisk */
|
||||
|
@ -289,7 +289,7 @@ static int fat_open(FAR struct file *filep, const char *relpath,
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
|
||||
/* Create a file buffer to support partial sector accesses */
|
||||
|
||||
ff->ff_buffer = (ubyte*)malloc(fs->fs_hwsectorsize);
|
||||
@ -316,6 +316,8 @@ static int fat_open(FAR struct file *filep, const char *relpath,
|
||||
((uint32)DIR_GETFSTCLUSTHI(dirinfo.fd_entry) << 16) |
|
||||
DIR_GETFSTCLUSTLO(dirinfo.fd_entry);
|
||||
|
||||
ff->ff_currentcluster = ff->ff_startcluster;
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus;
|
||||
ff->ff_size = DIR_GETFILESIZE(dirinfo.fd_entry);
|
||||
|
||||
/* Attach the private date to the struct file instance */
|
||||
@ -417,13 +419,13 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen)
|
||||
struct inode *inode;
|
||||
struct fat_mountpt_s *fs;
|
||||
struct fat_file_s *ff;
|
||||
uint32 cluster;
|
||||
unsigned int bytesread;
|
||||
unsigned int readsize;
|
||||
unsigned int nsectors;
|
||||
size_t readsector;
|
||||
size_t bytesleft;
|
||||
sint32 cluster;
|
||||
ubyte *userbuffer = (ubyte*)buffer;
|
||||
int sectorindex;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@ -468,81 +470,38 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen)
|
||||
buflen = bytesleft;
|
||||
}
|
||||
|
||||
/* Loop until either (1) all data has been transferred, or (2) an
|
||||
* error occurs.
|
||||
*/
|
||||
/* Get the first sector to read from. */
|
||||
|
||||
readsize = 0;
|
||||
readsector = ff->ff_currentsector;
|
||||
while (buflen > 0)
|
||||
if (!ff->ff_currentsector)
|
||||
{
|
||||
/* Get offset into the sector where we begin the read */
|
||||
|
||||
int sectorindex = filep->f_pos & SEC_NDXMASK(fs);
|
||||
bytesread = 0;
|
||||
|
||||
/* Check if the current read stream happens to lie on a
|
||||
* sector boundary.
|
||||
/* The current sector can be determined from the current cluster
|
||||
* and the file offset.
|
||||
*/
|
||||
|
||||
if (sectorindex == 0)
|
||||
{
|
||||
/* Try to read another contiguous sector from the cluster */
|
||||
ff->ff_currentsector = fat_cluster2sector(fs, ff->ff_currentcluster)
|
||||
+ (SEC_NSECTORS(fs, filep->f_pos) & CLUS_NDXMASK(fs));
|
||||
fdbg("Start with sector: %d\n", ff->ff_currentsector);
|
||||
}
|
||||
|
||||
ff->ff_sectorsincluster--;
|
||||
/* Loop until either (1) all data has been transferred, or (2) an
|
||||
* error occurs. We assume we start with the current sector
|
||||
* (ff_currentsector) which may be uninitialized.
|
||||
*/
|
||||
|
||||
/* Are there unread sectors remaining in the cluster? */
|
||||
readsize = 0;
|
||||
sectorindex = filep->f_pos & SEC_NDXMASK(fs);
|
||||
|
||||
if (ff->ff_sectorsincluster > 0)
|
||||
{
|
||||
/* Yes.. There are more sectors in this cluster to be read
|
||||
* just increment the current sector number and read.
|
||||
*/
|
||||
|
||||
readsector = ff->ff_currentsector + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. Handle the case of the first sector of the file */
|
||||
|
||||
if (filep->f_pos == 0)
|
||||
{
|
||||
/* Get the first cluster of the file */
|
||||
|
||||
cluster = ff->ff_startcluster;
|
||||
}
|
||||
|
||||
/* But in the general case, we have to find the next cluster
|
||||
* in the FAT.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
cluster = fat_getcluster(fs, ff->ff_currentcluster);
|
||||
}
|
||||
|
||||
/* Verify the cluster number */
|
||||
|
||||
if (cluster < 2 || cluster >= fs->fs_nclusters)
|
||||
{
|
||||
ret = -EINVAL; /* Not the right error */
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Setup to read the first sector from the new cluster */
|
||||
|
||||
ff->ff_currentcluster = cluster;
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus;
|
||||
readsector = fat_cluster2sector(fs, cluster);
|
||||
}
|
||||
}
|
||||
while (buflen > 0)
|
||||
{
|
||||
bytesread = 0;
|
||||
|
||||
/* Check if the user has provided a buffer large enough to
|
||||
* hold one or more complete sectors.
|
||||
* hold one or more complete sectors -AND- the read is
|
||||
* aligned to a sector boundary.
|
||||
*/
|
||||
|
||||
nsectors = buflen / fs->fs_hwsectorsize;
|
||||
if (nsectors > 0)
|
||||
if (nsectors > 0 && sectorindex == 0)
|
||||
{
|
||||
/* Read maximum contiguous sectors directly to the user's
|
||||
* buffer without using our tiny read buffer.
|
||||
@ -563,16 +522,16 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen)
|
||||
|
||||
(void)fat_ffcacheinvalidate(fs, ff);
|
||||
|
||||
/* Read all of the sectors directory into user memory */
|
||||
/* Read all of the sectors directly into user memory */
|
||||
|
||||
ret = fat_hwread(fs, userbuffer, readsector, nsectors);
|
||||
ret = fat_hwread(fs, userbuffer, ff->ff_currentsector, nsectors);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
ff->ff_sectorsincluster -= nsectors - 1;
|
||||
ff->ff_currentsector = readsector + nsectors - 1;
|
||||
ff->ff_sectorsincluster -= nsectors;
|
||||
ff->ff_currentsector += nsectors;
|
||||
bytesread = nsectors * fs->fs_hwsectorsize;
|
||||
}
|
||||
else
|
||||
@ -582,7 +541,7 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen)
|
||||
* it is already there then all is well.
|
||||
*/
|
||||
|
||||
ret = fat_ffcacheread(fs, ff, readsector);
|
||||
ret = fat_ffcacheread(fs, ff, ff->ff_currentsector);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
@ -595,9 +554,13 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen)
|
||||
{
|
||||
bytesread = buflen;
|
||||
}
|
||||
else
|
||||
{
|
||||
ff->ff_sectorsincluster--;
|
||||
ff->ff_currentsector++;
|
||||
}
|
||||
|
||||
memcpy(userbuffer, &ff->ff_buffer[sectorindex], bytesread);
|
||||
ff->ff_currentsector = readsector;
|
||||
}
|
||||
|
||||
/* Set up for the next sector read */
|
||||
@ -606,6 +569,29 @@ static ssize_t fat_read(FAR struct file *filep, char *buffer, size_t buflen)
|
||||
filep->f_pos += bytesread;
|
||||
readsize += bytesread;
|
||||
buflen -= bytesread;
|
||||
sectorindex = filep->f_pos & SEC_NDXMASK(fs);
|
||||
|
||||
/* Check if the current read stream has incremented to the next
|
||||
* cluster boundary
|
||||
*/
|
||||
|
||||
if (ff->ff_sectorsincluster < 1)
|
||||
{
|
||||
/* Find the next cluster in the FAT. */
|
||||
|
||||
cluster = fat_getcluster(fs, cluster);
|
||||
if (cluster < 2 || cluster >= fs->fs_nclusters)
|
||||
{
|
||||
ret = -EINVAL; /* Not the right error */
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Setup to read the first sector from the new cluster */
|
||||
|
||||
ff->ff_currentcluster = cluster;
|
||||
ff->ff_currentsector = fat_cluster2sector(fs, cluster);
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus;
|
||||
}
|
||||
}
|
||||
|
||||
fat_semgive(fs);
|
||||
@ -627,11 +613,11 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
||||
struct fat_mountpt_s *fs;
|
||||
struct fat_file_s *ff;
|
||||
sint32 cluster;
|
||||
size_t writesector;
|
||||
unsigned int byteswritten;
|
||||
unsigned int writesize;
|
||||
unsigned int nsectors;
|
||||
ubyte *userbuffer = (ubyte*)buffer;
|
||||
int sectorindex;
|
||||
int ret;
|
||||
|
||||
/* Sanity checks */
|
||||
@ -671,96 +657,39 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Get the first sector to write to. */
|
||||
|
||||
if (!ff->ff_currentsector)
|
||||
{
|
||||
/* Has the starting cluster been defined? */
|
||||
|
||||
if (ff->ff_startcluster == 0)
|
||||
{
|
||||
/* No.. we have to create a new cluster chain */
|
||||
|
||||
ff->ff_startcluster = fat_createchain(fs);
|
||||
ff->ff_currentcluster = ff->ff_startcluster;
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus;
|
||||
}
|
||||
|
||||
/* The current sector can then be determined from the currentcluster
|
||||
* and the file offset.
|
||||
*/
|
||||
|
||||
ff->ff_currentsector = fat_cluster2sector(fs, ff->ff_currentcluster)
|
||||
+ (SEC_NSECTORS(fs, filep->f_pos) & CLUS_NDXMASK(fs));
|
||||
}
|
||||
|
||||
/* Loop until either (1) all data has been transferred, or (2) an
|
||||
* error occurs.
|
||||
* error occurs. We assume we start with the current sector in
|
||||
* cache (ff_currentsector)
|
||||
*/
|
||||
|
||||
byteswritten = 0;
|
||||
writesector = ff->ff_currentsector;
|
||||
sectorindex = filep->f_pos & SEC_NDXMASK(fs);
|
||||
|
||||
while (buflen > 0)
|
||||
{
|
||||
/* Get offset into the sector where we begin the read */
|
||||
|
||||
int sectorindex = filep->f_pos & SEC_NDXMASK(fs);
|
||||
|
||||
/* Check if the current read stream happens to lie on a
|
||||
* sector boundary.
|
||||
*/
|
||||
|
||||
if (sectorindex == 0)
|
||||
{
|
||||
/* Decrement the number of sectors left in this cluster */
|
||||
|
||||
ff->ff_sectorsincluster--;
|
||||
|
||||
/* Are there unwritten sectors remaining in this cluster */
|
||||
|
||||
if (ff->ff_sectorsincluster > 0)
|
||||
{
|
||||
/* Yes.. There are more sectors in this cluster to be written.
|
||||
* just increment the current sector number and write.
|
||||
*/
|
||||
|
||||
writesector = ff->ff_currentsector + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. Handle the case of the first sector of the file */
|
||||
|
||||
if (filep->f_pos == 0)
|
||||
{
|
||||
/* Check the first cluster of the file. Zero means that
|
||||
* the file is empty -- perhaps the file was truncated or
|
||||
* created when it was opened
|
||||
*/
|
||||
|
||||
if (ff->ff_startcluster == 0)
|
||||
{
|
||||
/* In this case, we have to create a new cluster chain */
|
||||
|
||||
ff->ff_startcluster = fat_createchain(fs);
|
||||
}
|
||||
|
||||
/* Start writing at the first cluster of the file */
|
||||
|
||||
cluster = ff->ff_startcluster;
|
||||
}
|
||||
|
||||
/* But in the general case, we have to extend the current
|
||||
* cluster by one (unless lseek was used to move the file
|
||||
* position back from the end of the file)
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Extend the chain by adding a new cluster after
|
||||
* the last one
|
||||
*/
|
||||
|
||||
cluster = fat_extendchain(fs, ff->ff_currentcluster);
|
||||
}
|
||||
|
||||
/* Verify the cluster number */
|
||||
|
||||
if (cluster < 0)
|
||||
{
|
||||
ret = cluster;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
else if (cluster < 2 || cluster >= fs->fs_nclusters)
|
||||
{
|
||||
ret = -ENOSPC;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Setup to write the first sector from the new cluster */
|
||||
|
||||
ff->ff_currentcluster = cluster;
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus;
|
||||
writesector = fat_cluster2sector(fs, cluster);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if there is unwritten data in the file buffer */
|
||||
|
||||
ret = fat_ffcacheflush(fs, ff);
|
||||
@ -795,16 +724,16 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
||||
|
||||
(void)fat_ffcacheinvalidate(fs, ff);
|
||||
|
||||
/* Write all of the sectors directory from user memory */
|
||||
/* Write all of the sectors directly from user memory */
|
||||
|
||||
ret = fat_hwwrite(fs, userbuffer, writesector, nsectors);
|
||||
ret = fat_hwwrite(fs, userbuffer, ff->ff_currentsector, nsectors);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
ff->ff_sectorsincluster -= nsectors - 1;
|
||||
ff->ff_currentsector = writesector + nsectors - 1;
|
||||
ff->ff_sectorsincluster -= nsectors;
|
||||
ff->ff_currentsector += nsectors;
|
||||
writesize = nsectors * fs->fs_hwsectorsize;
|
||||
ff->ff_bflags |= FFBUFF_MODIFIED;
|
||||
}
|
||||
@ -823,8 +752,7 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
||||
|
||||
if (filep->f_pos < ff->ff_size || sectorindex != 0)
|
||||
{
|
||||
ff->ff_currentsector = writesector;
|
||||
ret = fat_ffcacheread(fs, ff, writesector);
|
||||
ret = fat_ffcacheread(fs, ff, ff->ff_currentsector);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
@ -838,9 +766,13 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
||||
{
|
||||
writesize = buflen;
|
||||
}
|
||||
else
|
||||
{
|
||||
ff->ff_sectorsincluster--;
|
||||
ff->ff_currentsector++;
|
||||
}
|
||||
|
||||
memcpy(&ff->ff_buffer[sectorindex], userbuffer, writesize);
|
||||
ff->ff_currentsector = writesector;
|
||||
ff->ff_bflags |= (FFBUFF_DIRTY|FFBUFF_VALID|FFBUFF_MODIFIED);
|
||||
}
|
||||
|
||||
@ -850,7 +782,40 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
||||
filep->f_pos += writesize;
|
||||
byteswritten += writesize;
|
||||
buflen -= writesize;
|
||||
}
|
||||
sectorindex = filep->f_pos & SEC_NDXMASK(fs);
|
||||
|
||||
/* Check if the current read stream has incremented to the next
|
||||
* cluster boundary
|
||||
*/
|
||||
|
||||
if (ff->ff_sectorsincluster < 1)
|
||||
{
|
||||
/* Extend the current cluster by one (unless lseek was used to
|
||||
* move the file position back from the end of the file)
|
||||
*/
|
||||
|
||||
cluster = fat_extendchain(fs, ff->ff_currentcluster);
|
||||
|
||||
/* Verify the cluster number */
|
||||
|
||||
if (cluster < 0)
|
||||
{
|
||||
ret = cluster;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
else if (cluster < 2 || cluster >= fs->fs_nclusters)
|
||||
{
|
||||
ret = -ENOSPC;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Setup to write the first sector from the new cluster */
|
||||
|
||||
ff->ff_currentcluster = cluster;
|
||||
ff->ff_sectorsincluster = fs->fs_fatsecperclus;
|
||||
ff->ff_currentsector = fat_cluster2sector(fs, cluster);
|
||||
}
|
||||
}
|
||||
|
||||
/* The transfer has completed without error. Update the file size */
|
||||
|
||||
|
@ -162,6 +162,8 @@
|
||||
#define SEC_NDXMASK(f) ((f)->fs_hwsectorsize - 1)
|
||||
#define SEC_NSECTORS(f,n) ((n) / (f)->fs_hwsectorsize)
|
||||
|
||||
#define CLUS_NDXMASK(f) ((f)->fs_fatsecperclus -1)
|
||||
|
||||
/****************************************************************************
|
||||
* File system types */
|
||||
|
||||
@ -515,7 +517,8 @@ struct fat_file_s
|
||||
size_t ff_dirsector; /* Sector containing the directory entry */
|
||||
off_t ff_size; /* Size of the file in bytes */
|
||||
size_t ff_startcluster; /* Start cluster of file on media */
|
||||
size_t ff_currentsector; /* Current sector in the file buffer */
|
||||
size_t ff_currentsector; /* Current sector being operated on */
|
||||
size_t ff_cachesector; /* Current sector in the file buffer */
|
||||
ubyte *ff_buffer; /* File buffer (for partial sector accesses) */
|
||||
};
|
||||
|
||||
@ -578,7 +581,7 @@ EXTERN int fat_hwwrite(struct fat_mountpt_s *fs, ubyte *buffer,
|
||||
|
||||
/* Cluster / cluster chain access helpers */
|
||||
|
||||
EXTERN ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster );
|
||||
EXTERN ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster);
|
||||
EXTERN ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno);
|
||||
EXTERN int fat_putcluster(struct fat_mountpt_s *fs, uint32 clusterno,
|
||||
size_t startsector);
|
||||
|
@ -858,7 +858,7 @@ ssize_t fat_cluster2sector(struct fat_mountpt_s *fs, uint32 cluster )
|
||||
/****************************************************************************
|
||||
* Name: fat_getcluster
|
||||
*
|
||||
* Desciption: Get the cluster start sector into the FAT.
|
||||
* Desciption: Get the next cluster start from the FAT.
|
||||
*
|
||||
* Return: <0: error, 0:cluster unassigned, >=0: start sector of cluster
|
||||
*
|
||||
@ -880,7 +880,7 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno)
|
||||
{
|
||||
size_t fatsector;
|
||||
unsigned int fatoffset;
|
||||
unsigned int startsector;
|
||||
unsigned int cluster;
|
||||
unsigned int fatindex;
|
||||
|
||||
/* FAT12 is more complex because it has 12-bits (1.5 bytes)
|
||||
@ -895,13 +895,14 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno)
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the first, LS byte of the cluster from the FAT */
|
||||
|
||||
fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
startsector = fs->fs_buffer[fatindex];
|
||||
fatindex = fatoffset & SEC_NDXMASK(fs);
|
||||
cluster = fs->fs_buffer[fatindex];
|
||||
|
||||
/* With FAT12, the second byte of the cluster number may lie in
|
||||
* a different sector than the first byte.
|
||||
@ -916,6 +917,7 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno)
|
||||
if (fat_fscacheread(fs, fatsector) < 0)
|
||||
{
|
||||
/* Read error */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -925,21 +927,23 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno)
|
||||
* on the fact that the byte stream is little-endian.
|
||||
*/
|
||||
|
||||
startsector |= (unsigned int)fs->fs_buffer[fatindex] << 8;
|
||||
cluster |= (unsigned int)fs->fs_buffer[fatindex] << 8;
|
||||
|
||||
/* Now, pick out the correct 12 bit cluster start sector value */
|
||||
|
||||
if ((clusterno & 1) != 0)
|
||||
{
|
||||
/* Odd.. take the MS 12-bits */
|
||||
startsector >>= 4;
|
||||
|
||||
cluster >>= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Even.. take the LS 12-bits */
|
||||
startsector &= 0x0fff;
|
||||
|
||||
cluster &= 0x0fff;
|
||||
}
|
||||
return startsector;
|
||||
return cluster;
|
||||
}
|
||||
|
||||
case FSTYPE_FAT16 :
|
||||
@ -967,7 +971,7 @@ ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno)
|
||||
/* Read error */
|
||||
break;
|
||||
}
|
||||
return FAT_GETFAT16(fs->fs_buffer, fatindex) & 0x0fffffff;
|
||||
return FAT_GETFAT32(fs->fs_buffer, fatindex) & 0x0fffffff;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -2198,20 +2202,21 @@ int fat_ffcacheflush(struct fat_mountpt_s *fs, struct fat_file_s *ff)
|
||||
* contents of ff_buffer.
|
||||
*/
|
||||
|
||||
if (ff->ff_bflags && (FFBUFF_DIRTY|FFBUFF_VALID) == (FFBUFF_DIRTY|FFBUFF_VALID))
|
||||
{
|
||||
if (ff->ff_cachesector &&
|
||||
ff->ff_bflags && (FFBUFF_DIRTY|FFBUFF_VALID) == (FFBUFF_DIRTY|FFBUFF_VALID))
|
||||
{
|
||||
/* Write the dirty sector */
|
||||
|
||||
ret = fat_hwwrite(fs, ff->ff_buffer, ff->ff_currentsector, 1);
|
||||
ret = fat_hwwrite(fs, ff->ff_buffer, ff->ff_cachesector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* No longer dirty */
|
||||
/* No longer dirty, but still valid */
|
||||
|
||||
ff->ff_bflags &= ~FFBUFF_DIRTY;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
@ -2228,12 +2233,12 @@ int fat_ffcacheread(struct fat_mountpt_s *fs, struct fat_file_s *ff, size_t sect
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* ff->ff_currentsector holds the current sector that is buffered in
|
||||
/* ff->ff_cachesector holds the current sector that is buffered in
|
||||
* ff->ff_buffer. If the requested sector is the same as this sector, then
|
||||
* we do nothing. Otherwise, we will have to read the new sector.
|
||||
*/
|
||||
|
||||
if (ff->ff_currentsector != sector || (ff->ff_bflags & FFBUFF_VALID) == 0)
|
||||
if (ff->ff_cachesector != sector || (ff->ff_bflags & FFBUFF_VALID) == 0)
|
||||
{
|
||||
/* We will need to read the new sector. First, flush the cached
|
||||
* sector if it is dirty.
|
||||
@ -2255,7 +2260,7 @@ int fat_ffcacheread(struct fat_mountpt_s *fs, struct fat_file_s *ff, size_t sect
|
||||
|
||||
/* Update the cached sector number */
|
||||
|
||||
ff->ff_currentsector = sector;
|
||||
ff->ff_cachesector = sector;
|
||||
ff->ff_bflags |= FFBUFF_VALID;
|
||||
}
|
||||
return OK;
|
||||
|
@ -97,6 +97,7 @@ static inline ssize_t tftp_write(int fd, const ubyte *buf, size_t len)
|
||||
|
||||
/* Handle partial writes */
|
||||
|
||||
nvdbg("Wrote %d bytes to file\n", nbyteswritten);
|
||||
left -= nbyteswritten;
|
||||
buf += nbyteswritten;
|
||||
}
|
||||
@ -186,22 +187,6 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar
|
||||
goto errout_with_fd;
|
||||
}
|
||||
|
||||
/* Send the read request using the well-known port number */
|
||||
|
||||
len = tftp_mkreqpacket(packet, TFTP_RRQ, remote, binary);
|
||||
ret = tftp_sendto(sd, packet, len, &server);
|
||||
if (ret != len)
|
||||
{
|
||||
goto errout_with_sd;
|
||||
}
|
||||
|
||||
/* Subsequent sendto will use the port number selected by the TFTP
|
||||
* server. Setting the server port to zero indicates that we have
|
||||
* not yet received the server port number.
|
||||
*/
|
||||
|
||||
server.sin_port = 0;
|
||||
|
||||
/* Then enter the transfer loop. Loop until the entire file has
|
||||
* been received or until an error occurs.
|
||||
*/
|
||||
@ -219,6 +204,29 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar
|
||||
|
||||
for (retry = 0; retry < TFTP_RETRIES; retry++)
|
||||
{
|
||||
/* Send the read request using the well-known port number before
|
||||
* receiving the first block. Each retry of the first block will
|
||||
* re-send the request.
|
||||
*/
|
||||
|
||||
if (blockno == 1)
|
||||
{
|
||||
len = tftp_mkreqpacket(packet, TFTP_RRQ, remote, binary);
|
||||
server.sin_port = HTONS(CONFIG_NETUTILS_TFTP_PORT);
|
||||
ret = tftp_sendto(sd, packet, len, &server);
|
||||
if (ret != len)
|
||||
{
|
||||
goto errout_with_sd;
|
||||
}
|
||||
|
||||
/* Subsequent sendto will use the port number selected by the TFTP
|
||||
* server in the DATA packet. Setting the server port to zero
|
||||
* here indicates that we have not yet received the server port number.
|
||||
*/
|
||||
|
||||
server.sin_port = 0;
|
||||
}
|
||||
|
||||
/* Get the next packet from the server */
|
||||
|
||||
nbytesrecvd = tftp_recvfrom(sd, packet, TFTP_IOBUFSIZE, &from);
|
||||
@ -284,6 +292,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar
|
||||
/* Write the received data chunk to the file */
|
||||
|
||||
ndatabytes = nbytesrecvd - TFTP_DATAHEADERSIZE;
|
||||
tftp_dumpbuffer("Recvd DATA", packet + TFTP_DATAHEADERSIZE, ndatabytes);
|
||||
if (tftp_write(fd, packet + TFTP_DATAHEADERSIZE, ndatabytes) < 0)
|
||||
{
|
||||
goto errout_with_sd;
|
||||
|
@ -69,6 +69,10 @@
|
||||
# define CONFIG_NETUTILS_TFTP_TIMEOUT 10 /* One second */
|
||||
#endif
|
||||
|
||||
/* Dump received buffers */
|
||||
|
||||
#undef CONFIG_NETUTILS_TFTP_DUMPBUFFERS
|
||||
|
||||
/* Sizes of TFTP messsage headers */
|
||||
|
||||
#define TFTP_ACKHEADERSIZE 4
|
||||
@ -153,4 +157,10 @@ extern int tftp_parseerrpacket(const ubyte *packet);
|
||||
extern ssize_t tftp_recvfrom(int sd, void *buf, size_t len, struct sockaddr_in *from);
|
||||
extern ssize_t tftp_sendto(int sd, const void *buf, size_t len, struct sockaddr_in *to);
|
||||
|
||||
#ifdef CONFIG_NETUTILS_TFTP_DUMPBUFFERS
|
||||
extern void tftp_dumpbuffer(const char *msg, ubyte *buffer, int nbytes);
|
||||
#else
|
||||
# define tftp_dumpbuffer(msg, buffer, nbytes)
|
||||
#endif
|
||||
|
||||
#endif /* __NETUTILS_TFTP_TFTPC_INTERNAL_H */
|
||||
|
@ -241,6 +241,12 @@ ssize_t tftp_recvfrom(int sd, void *buf, size_t len, struct sockaddr_in *from)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* For debugging, it is helpful to start with a clean buffer */
|
||||
|
||||
#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_NET)
|
||||
memset(buf, 0, len);
|
||||
#endif
|
||||
|
||||
/* Receive the packet */
|
||||
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
@ -320,4 +326,52 @@ ssize_t tftp_sendto(int sd, const void *buf, size_t len, struct sockaddr_in *to)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tftp_sendto
|
||||
*
|
||||
* Description:
|
||||
* Dump a buffer of data
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NETUTILS_TFTP_DUMPBUFFERS
|
||||
void tftp_dumpbuffer(const char *msg, ubyte *buffer, int nbytes)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG
|
||||
char line[128];
|
||||
int ch;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
dbg("%s:\n", msg);
|
||||
for (i = 0; i < nbytes; i += 16)
|
||||
{
|
||||
sprintf(line, "%04x: ", i);
|
||||
|
||||
for ( j = 0; j < 16; j++)
|
||||
{
|
||||
if (i + j < nbytes)
|
||||
{
|
||||
sprintf(&line[strlen(line)], "%02x ", buffer[i+j] );
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(&line[strlen(line)], " ");
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0; j < 16; j++)
|
||||
{
|
||||
if (i + j < nbytes)
|
||||
{
|
||||
ch = buffer[i+j];
|
||||
sprintf(&line[strlen(line)], "%c", ch >= 0x20 && ch <= 0x7e ? ch : '.');
|
||||
}
|
||||
}
|
||||
dbg("%s\n", line);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS */
|
||||
|
Loading…
Reference in New Issue
Block a user