forked from nuttx/nuttx-update
Add ioctl's to support XIP
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@913 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
9ff4834f74
commit
b0d5432f8b
8 changed files with 332 additions and 139 deletions
|
@ -466,4 +466,10 @@
|
|||
* Added support for ROMFS filesystem.
|
||||
* Added a simple test the ROMFS filesystem (examples/romfs)
|
||||
* NSH: Use ROMFS to provide an option for a start-up script at /etc/init.d/rcS
|
||||
* Add definition of BIOC_XIPBASE ioctl and implement in RAM disk block driver.
|
||||
This is a low level requirement for eXecute In Place (XIP) support.
|
||||
* Add a FIOC_MMAP to perform memory mapping of a file and implemented the
|
||||
ioctl command in the ROMFS filesystem. This is a requirement for eXecute
|
||||
In Place (XIP) support.
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<tr align="center" bgcolor="#e4e4e4">
|
||||
<td>
|
||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||
<p>Last Updated: September 11, 2008</p>
|
||||
<p>Last Updated: September 12, 2008</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -1100,6 +1100,11 @@ nuttx-0.3.15 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
|||
* Added support for ROMFS filesystem.
|
||||
* Added a simple test the ROMFS filesystem (examples/romfs)
|
||||
* NSH: Use ROMFS to provide an option for a start-up script at /etc/init.d/rcS
|
||||
* Add definition of BIOC_XIPBASE ioctl and implement in RAM disk block driver.
|
||||
This is a low level requirement for eXecute In Place (XIP) support.
|
||||
* Add a FIOC_MMAP to perform memory mapping of a file and implemented the
|
||||
ioctl command in the ROMFS filesystem. This is a requirement for eXecute
|
||||
In Place (XIP) support.
|
||||
|
||||
pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
||||
|
|
|
@ -82,8 +82,7 @@ struct file_operations g_serialops =
|
|||
|
||||
static int lowconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
*get_errno_ptr() = ENOTTY;
|
||||
return ERROR;
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -82,6 +83,7 @@ static ssize_t rd_write(FAR struct inode *inode, const unsigned char *buffer,
|
|||
size_t start_sector, unsigned int nsectors);
|
||||
#endif
|
||||
static int rd_geometry(FAR struct inode *inode, struct geometry *geometry);
|
||||
static int rd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
|
@ -98,7 +100,7 @@ static const struct block_operations g_bops =
|
|||
NULL, /* write */
|
||||
#endif
|
||||
rd_geometry, /* geometry */
|
||||
NULL /* ioctl */
|
||||
rd_ioctl /* ioctl */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -140,18 +142,16 @@ static ssize_t rd_read(FAR struct inode *inode, unsigned char *buffer,
|
|||
size_t start_sector, unsigned int nsectors)
|
||||
{
|
||||
struct rd_struct_s *dev;
|
||||
if (inode)
|
||||
|
||||
DEBUGASSERT(inode && inode->i_private);
|
||||
dev = (struct rd_struct_s *)inode->i_private;
|
||||
if (start_sector < dev->rd_nsectors &&
|
||||
start_sector + nsectors <= dev->rd_nsectors)
|
||||
{
|
||||
dev = (struct rd_struct_s *)inode->i_private;
|
||||
if (dev &&
|
||||
start_sector < dev->rd_nsectors &&
|
||||
start_sector + nsectors <= dev->rd_nsectors)
|
||||
{
|
||||
memcpy(buffer,
|
||||
&dev->rd_buffer[start_sector * dev->rd_sectsize],
|
||||
nsectors * dev->rd_sectsize);
|
||||
return nsectors;
|
||||
}
|
||||
memcpy(buffer,
|
||||
&dev->rd_buffer[start_sector * dev->rd_sectsize],
|
||||
nsectors * dev->rd_sectsize);
|
||||
return nsectors;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -168,26 +168,22 @@ static ssize_t rd_write(FAR struct inode *inode, const unsigned char *buffer,
|
|||
size_t start_sector, unsigned int nsectors)
|
||||
{
|
||||
struct rd_struct_s *dev;
|
||||
if (inode)
|
||||
|
||||
DEBUGASSERT(inode && inode->i_private);
|
||||
dev = (struct rd_struct_s *)inode->i_private;
|
||||
if (!dev->rd_writeenabled)
|
||||
{
|
||||
dev = (struct rd_struct_s *)inode->i_private;
|
||||
if (dev)
|
||||
{
|
||||
if (!dev->rd_writeenabled)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
else if (start_sector < dev->rd_nsectors &&
|
||||
start_sector + nsectors <= dev->rd_nsectors)
|
||||
{
|
||||
memcpy(&dev->rd_buffer[start_sector * dev->rd_sectsize],
|
||||
buffer,
|
||||
nsectors * dev->rd_sectsize);
|
||||
return nsectors;
|
||||
}
|
||||
}
|
||||
return -EACCES;
|
||||
}
|
||||
return -EINVAL;
|
||||
else if (start_sector < dev->rd_nsectors &&
|
||||
start_sector + nsectors <= dev->rd_nsectors)
|
||||
{
|
||||
memcpy(&dev->rd_buffer[start_sector * dev->rd_sectsize],
|
||||
buffer,
|
||||
nsectors * dev->rd_sectsize);
|
||||
return nsectors;
|
||||
}
|
||||
return -EFBIG;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -201,7 +197,9 @@ static ssize_t rd_write(FAR struct inode *inode, const unsigned char *buffer,
|
|||
static int rd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
||||
{
|
||||
struct rd_struct_s *dev;
|
||||
if (inode && geometry)
|
||||
|
||||
DEBUGASSERT(inode);
|
||||
if (geometry)
|
||||
{
|
||||
dev = (struct rd_struct_s *)inode->i_private;
|
||||
geometry->geo_available = TRUE;
|
||||
|
@ -218,6 +216,31 @@ static int rd_geometry(FAR struct inode *inode, struct geometry *geometry)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rd_geometry
|
||||
*
|
||||
* Description: Return device geometry
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int rd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
|
||||
{
|
||||
struct rd_struct_s *dev ;
|
||||
void **ppv = (void**)arg;
|
||||
|
||||
/* Only one ioctl command is supported */
|
||||
|
||||
DEBUGASSERT(inode && inode->i_private);
|
||||
if (cmd == BIOC_XIPBASE && ppv)
|
||||
{
|
||||
dev = (struct rd_struct_s *)inode->i_private;
|
||||
*ppv = (void*)dev->rd_buffer;
|
||||
return OK;
|
||||
}
|
||||
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs.h>
|
||||
#include <nuttx/ioctl.h>
|
||||
|
||||
#include "fs_romfs.h"
|
||||
|
||||
|
@ -71,6 +72,7 @@ static int romfs_open(FAR struct file *filep, const char *relpath,
|
|||
static int romfs_close(FAR struct file *filep);
|
||||
static ssize_t romfs_read(FAR struct file *filep, char *buffer, size_t buflen);
|
||||
static off_t romfs_seek(FAR struct file *filep, off_t offset, int whence);
|
||||
static int romfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
|
||||
static int romfs_opendir(struct inode *mountpt, const char *relpath,
|
||||
struct internal_dir_s *dir);
|
||||
|
@ -104,7 +106,7 @@ const struct mountpt_operations romfs_operations =
|
|||
romfs_read, /* read */
|
||||
NULL, /* write */
|
||||
romfs_seek, /* seek */
|
||||
NULL, /* ioctl */
|
||||
romfs_ioctl, /* ioctl */
|
||||
NULL, /* sync */
|
||||
|
||||
romfs_opendir, /* opendir */
|
||||
|
@ -135,7 +137,6 @@ static int romfs_open(FAR struct file *filep, const char *relpath,
|
|||
int oflags, mode_t mode)
|
||||
{
|
||||
struct romfs_dirinfo_s dirinfo;
|
||||
struct inode *inode;
|
||||
struct romfs_mountpt_s *rm;
|
||||
struct romfs_file_s *rf;
|
||||
int ret;
|
||||
|
@ -144,12 +145,11 @@ static int romfs_open(FAR struct file *filep, const char *relpath,
|
|||
|
||||
DEBUGASSERT(filep->f_priv == NULL && filep->f_inode != NULL);
|
||||
|
||||
/* Get the mountpoint inode reference from the file structure and the
|
||||
* mountpoint private data from the inode structure
|
||||
/* mountpoint private data from the inode reference from the file
|
||||
* structure
|
||||
*/
|
||||
|
||||
inode = filep->f_inode;
|
||||
rm = (struct romfs_mountpt_s*)inode->i_private;
|
||||
rm = (struct romfs_mountpt_s*)filep->f_inode->i_private;
|
||||
|
||||
DEBUGASSERT(rm != NULL);
|
||||
|
||||
|
@ -211,21 +211,19 @@ static int romfs_open(FAR struct file *filep, const char *relpath,
|
|||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Create a file buffer to support partial sector accesses */
|
||||
|
||||
rf->rf_buffer = (ubyte*)malloc(rm->rm_hwsectorsize);
|
||||
if (!rf->rf_buffer)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_struct;
|
||||
}
|
||||
|
||||
/* Initialize the file private data (only need to initialize non-zero elements) */
|
||||
|
||||
rf->rf_open = TRUE;
|
||||
rf->rf_startoffset = romfs_datastart(rm, dirinfo.rd_dir.fr_curroffset);
|
||||
rf->rf_size = dirinfo.rd_size;
|
||||
rf->rf_cachesector = (uint32)-1;
|
||||
|
||||
/* Confiure a buffering to support access to this file */
|
||||
|
||||
ret = romfs_fileconfigure(rm, rf);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Attach the private date to the struct file instance */
|
||||
|
||||
|
@ -243,12 +241,7 @@ static int romfs_open(FAR struct file *filep, const char *relpath,
|
|||
romfs_semgive(rm);
|
||||
return OK;
|
||||
|
||||
/* Error exits -- goto's are nasty things, but they sure can make error
|
||||
* handling a lot simpler.
|
||||
*/
|
||||
|
||||
errout_with_struct:
|
||||
free(rf);
|
||||
/* Error exits */
|
||||
|
||||
errout_with_semaphore:
|
||||
romfs_semgive(rm);
|
||||
|
@ -261,7 +254,6 @@ errout_with_semaphore:
|
|||
|
||||
static int romfs_close(FAR struct file *filep)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct romfs_mountpt_s *rm;
|
||||
struct romfs_file_s *rf;
|
||||
int ret = OK;
|
||||
|
@ -273,8 +265,7 @@ static int romfs_close(FAR struct file *filep)
|
|||
/* Recover our private data from the struct file instance */
|
||||
|
||||
rf = filep->f_priv;
|
||||
inode = filep->f_inode;
|
||||
rm = inode->i_private;
|
||||
rm = filep->f_inode->i_private;
|
||||
|
||||
DEBUGASSERT(rm != NULL);
|
||||
|
||||
|
@ -289,7 +280,7 @@ static int romfs_close(FAR struct file *filep)
|
|||
* accesses.
|
||||
*/
|
||||
|
||||
if (rf->rf_buffer)
|
||||
if (!rm->rm_xipbase && rf->rf_buffer)
|
||||
{
|
||||
free(rf->rf_buffer);
|
||||
}
|
||||
|
@ -307,7 +298,6 @@ static int romfs_close(FAR struct file *filep)
|
|||
|
||||
static ssize_t romfs_read(FAR struct file *filep, char *buffer, size_t buflen)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct romfs_mountpt_s *rm;
|
||||
struct romfs_file_s *rf;
|
||||
unsigned int bytesread;
|
||||
|
@ -327,8 +317,7 @@ static ssize_t romfs_read(FAR struct file *filep, char *buffer, size_t buflen)
|
|||
/* Recover our private data from the struct file instance */
|
||||
|
||||
rf = filep->f_priv;
|
||||
inode = filep->f_inode;
|
||||
rm = inode->i_private;
|
||||
rm = filep->f_inode->i_private;
|
||||
|
||||
DEBUGASSERT(rm != NULL);
|
||||
|
||||
|
@ -445,7 +434,6 @@ errout_with_semaphore:
|
|||
|
||||
static off_t romfs_seek(FAR struct file *filep, off_t offset, int whence)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct romfs_mountpt_s *rm;
|
||||
struct romfs_file_s *rf;
|
||||
ssize_t position;
|
||||
|
@ -458,12 +446,12 @@ static off_t romfs_seek(FAR struct file *filep, off_t offset, int whence)
|
|||
/* Recover our private data from the struct file instance */
|
||||
|
||||
rf = filep->f_priv;
|
||||
inode = filep->f_inode;
|
||||
rm = inode->i_private;
|
||||
rm = filep->f_inode->i_private;
|
||||
|
||||
DEBUGASSERT(rm != NULL);
|
||||
|
||||
/* Map the offset according to the whence option */
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET: /* The offset is set to offset bytes. */
|
||||
|
@ -516,10 +504,47 @@ errout_with_semaphore:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: romfs_ioctl
|
||||
****************************************************************************/
|
||||
|
||||
static int romfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
struct romfs_mountpt_s *rm;
|
||||
struct romfs_file_s *rf;
|
||||
void **ppv = (void**)arg;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
rf = filep->f_priv;
|
||||
rm = filep->f_inode->i_private;
|
||||
|
||||
DEBUGASSERT(rm != NULL);
|
||||
|
||||
/* Only one ioctl command is supported */
|
||||
|
||||
if (cmd == FIOC_MMAP && rm->rm_xipbase && ppv)
|
||||
{
|
||||
/* Return the address on the media corresponding to the start of
|
||||
* the file.
|
||||
*/
|
||||
|
||||
*ppv = (void*)(rm->rm_xipbase + rf->rf_startoffset);
|
||||
return OK;
|
||||
}
|
||||
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: romfs_opendir
|
||||
*
|
||||
* Description: Open a directory for read access
|
||||
* Description:
|
||||
* Open a directory for read access
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -743,41 +768,37 @@ static int romfs_bind(FAR struct inode *blkdriver, const void *data,
|
|||
|
||||
sem_init(&rm->rm_sem, 0, 0); /* Initialize the semaphore that controls access */
|
||||
rm->rm_blkdriver = blkdriver; /* Save the block driver reference */
|
||||
rm->rm_cachesector = (uint32)-1; /* No sector in the cache */
|
||||
|
||||
/* Get the hardware configuration */
|
||||
/* Get the hardware configuration and setup buffering appropriately */
|
||||
|
||||
ret = romfs_getgeometry(rm);
|
||||
ret = romfs_hwconfigure(rm);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_sem;
|
||||
}
|
||||
|
||||
/* Allocate the device cache buffer */
|
||||
/* Then complete the mount by getting the ROMFS configuratrion from
|
||||
* the ROMF header
|
||||
*/
|
||||
|
||||
rm->rm_buffer = (ubyte*)malloc(rm->rm_hwsectorsize);
|
||||
if (!rm->rm_buffer)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_sem;
|
||||
}
|
||||
|
||||
/* Then complete the mount */
|
||||
|
||||
ret = romfs_mount(rm);
|
||||
ret = romfs_fsconfigure(rm);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_buffer;
|
||||
}
|
||||
|
||||
/* Mounted */
|
||||
/* Mounted! */
|
||||
|
||||
*handle = (void*)rm;
|
||||
romfs_semgive(rm);
|
||||
return OK;
|
||||
|
||||
errout_with_buffer:
|
||||
free(rm->rm_buffer);
|
||||
if (!rm->rm_xipbase)
|
||||
{
|
||||
free(rm->rm_buffer);
|
||||
}
|
||||
|
||||
errout_with_sem:
|
||||
sem_destroy(&rm->rm_sem);
|
||||
free(rm);
|
||||
|
@ -841,7 +862,7 @@ static int romfs_unbind(void *handle, FAR struct inode **blkdriver)
|
|||
|
||||
/* Release the mountpoint private data */
|
||||
|
||||
if (rm->rm_buffer)
|
||||
if (!rm->rm_xipbase && rm->rm_buffer)
|
||||
{
|
||||
free(rm->rm_buffer);
|
||||
}
|
||||
|
|
|
@ -141,7 +141,8 @@ struct romfs_mountpt_s
|
|||
uint32 rm_hwnsectors; /* HW: The number of sectors reported by the hardware */
|
||||
uint32 rm_volsize; /* Size of the ROMFS volume */
|
||||
uint32 rm_cachesector; /* Current sector in the rm_buffer */
|
||||
ubyte *rm_buffer; /* Device sector buffer */
|
||||
ubyte *rm_xipbase; /* Base address of directly accessible media */
|
||||
ubyte *rm_buffer; /* Device sector buffer, allocated if rm_xipbase==0 */
|
||||
};
|
||||
|
||||
/* This structure represents on open file under the mountpoint. An instance
|
||||
|
@ -156,7 +157,7 @@ struct romfs_file_s
|
|||
uint32 rf_startoffset; /* Offset to the start of the file data */
|
||||
uint32 rf_size; /* Size of the file in bytes */
|
||||
uint32 rf_cachesector; /* Current sector in the rf_buffer */
|
||||
ubyte *rf_buffer; /* File sector buffer */
|
||||
ubyte *rf_buffer; /* File sector buffer, allocated if rm_xipbase==0 */
|
||||
};
|
||||
|
||||
/* This structure is used internally for describing the result of
|
||||
|
@ -201,8 +202,10 @@ EXTERN int romfs_hwread(struct romfs_mountpt_s *rm, ubyte *buffer,
|
|||
EXTERN int romfs_devcacheread(struct romfs_mountpt_s *rm, uint32 sector);
|
||||
EXTERN int romfs_filecacheread(struct romfs_mountpt_s *rm,
|
||||
struct romfs_file_s *rf, uint32 sector);
|
||||
EXTERN int romfs_getgeometry(struct romfs_mountpt_s *rm);
|
||||
EXTERN int romfs_mount(struct romfs_mountpt_s *rm);
|
||||
EXTERN int romfs_hwconfigure(struct romfs_mountpt_s *rm);
|
||||
EXTERN int romfs_fsconfigure(struct romfs_mountpt_s *rm);
|
||||
EXTERN int romfs_fileconfigure(struct romfs_mountpt_s *rm,
|
||||
struct romfs_file_s *rf);
|
||||
EXTERN int romfs_checkmount(struct romfs_mountpt_s *rm);
|
||||
EXTERN int romfs_finddirentry(struct romfs_mountpt_s *rm,
|
||||
struct romfs_dirinfo_s *dirinfo,
|
||||
|
|
|
@ -42,12 +42,15 @@
|
|||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/ioctl.h>
|
||||
|
||||
#include "fs_romfs.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -298,14 +301,28 @@ void romfs_semgive(struct romfs_mountpt_s *rm)
|
|||
int romfs_hwread(struct romfs_mountpt_s *rm, ubyte *buffer, uint32 sector,
|
||||
unsigned int nsectors)
|
||||
{
|
||||
struct inode *inode;;
|
||||
ssize_t nsectorsread;
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (rm && rm->rm_blkdriver)
|
||||
/* Check the access mode */
|
||||
|
||||
if (rm->rm_xipbase)
|
||||
{
|
||||
inode = rm->rm_blkdriver;
|
||||
if (inode && inode->u.i_bops && inode->u.i_bops->read)
|
||||
/* In XIP mode, we just copy the requested data */
|
||||
|
||||
memcpy(buffer,
|
||||
rm->rm_xipbase + sector*rm->rm_hwsectorsize,
|
||||
nsectors*rm->rm_hwsectorsize);
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In non-XIP mode, we have to read the data from the device */
|
||||
|
||||
struct inode *inode = rm->rm_blkdriver;
|
||||
ssize_t nsectorsread;
|
||||
|
||||
DEBUGASSERT(inode);
|
||||
if (inode->u.i_bops && inode->u.i_bops->read)
|
||||
{
|
||||
nsectorsread =
|
||||
inode->u.i_bops->read(inode, buffer, sector, nsectors);
|
||||
|
@ -335,24 +352,39 @@ int romfs_devcacheread(struct romfs_mountpt_s *rm, uint32 sector)
|
|||
{
|
||||
int ret;
|
||||
|
||||
/* rm->rm_cachesector holds the current sector that is buffered in
|
||||
* rm->tm_buffer. If the requested sector is the same as this sector, then
|
||||
* we do nothing. Otherwise, we will have to read the new sector.
|
||||
/* rm->rm_cachesector holds the current sector that is buffer in or referenced
|
||||
* by rm->tm_buffer. If the requested sector is the same as this sector,
|
||||
* then we do nothing.
|
||||
*/
|
||||
|
||||
if (rm->rm_cachesector != sector)
|
||||
{
|
||||
ret = romfs_hwread(rm, rm->rm_buffer, sector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
{
|
||||
/* Check the access mode */
|
||||
|
||||
/* Update the cached sector number */
|
||||
if (rm->rm_xipbase)
|
||||
{
|
||||
/* In XIP mode, rf_buffer is just an offset pointer into the device
|
||||
* address space.
|
||||
*/
|
||||
|
||||
rm->rm_cachesector = sector;
|
||||
rm->rm_buffer = rm->rm_xipbase + sector*rm->rm_hwsectorsize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In non-XIP mode, we will have to read the new sector.*/
|
||||
|
||||
ret = romfs_hwread(rm, rm->rm_buffer, sector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the cached sector number */
|
||||
|
||||
rm->rm_cachesector = sector;
|
||||
}
|
||||
return OK;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -367,35 +399,53 @@ int romfs_filecacheread(struct romfs_mountpt_s *rm, struct romfs_file_s *rf, uin
|
|||
{
|
||||
int ret;
|
||||
|
||||
/* rf->rf_cachesector holds the current sector that is buffered in
|
||||
* rf->rf_buffer. If the requested sector is the same as this sector, then
|
||||
* we do nothing. Otherwise, we will have to read the new sector.
|
||||
/* rf->rf_cachesector holds the current sector that is buffer in or referenced
|
||||
* by rf->rf_buffer. If the requested sector is the same as this sector,
|
||||
* then we do nothing.
|
||||
*/
|
||||
|
||||
if (rf->rf_cachesector != sector)
|
||||
{
|
||||
ret = romfs_hwread(rm, rf->rf_buffer, sector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
{
|
||||
/* Check the access mode */
|
||||
|
||||
/* Update the cached sector number */
|
||||
if (rm->rm_xipbase)
|
||||
{
|
||||
/* In XIP mode, rf_buffer is just an offset pointer into the device
|
||||
* address space.
|
||||
*/
|
||||
|
||||
rf->rf_cachesector = sector;
|
||||
rf->rf_buffer = rm->rm_xipbase + sector*rm->rm_hwsectorsize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In non-XIP mode, we will have to read the new sector.*/
|
||||
|
||||
ret = romfs_hwread(rm, rf->rf_buffer, sector, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the cached sector number */
|
||||
|
||||
rf->rf_cachesector = sector;
|
||||
}
|
||||
return OK;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: romfs_getgeometry
|
||||
* Name: romfs_hwconfigure
|
||||
*
|
||||
* Desciption:
|
||||
* Get the geometry of the device (part of the mount operation)
|
||||
* This function is called as part of the ROMFS mount operation It
|
||||
* configures the ROMFS filestem for use on this block driver. This includes
|
||||
* the accounting for the geometry of the device, setting up any XIP modes
|
||||
* of operation, and/or allocating any cache buffers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int romfs_getgeometry(struct romfs_mountpt_s *rm)
|
||||
int romfs_hwconfigure(struct romfs_mountpt_s *rm)
|
||||
{
|
||||
struct inode *inode = rm->rm_blkdriver;
|
||||
struct geometry geo;
|
||||
|
@ -403,10 +453,12 @@ int romfs_getgeometry(struct romfs_mountpt_s *rm)
|
|||
|
||||
/* Get the underlying device geometry */
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!inode || !inode->u.i_bops || !inode->u.i_bops->geometry)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = inode->u.i_bops->geometry(inode, &geo);
|
||||
if (ret != OK)
|
||||
|
@ -423,18 +475,50 @@ int romfs_getgeometry(struct romfs_mountpt_s *rm)
|
|||
|
||||
rm->rm_hwsectorsize = geo.geo_sectorsize;
|
||||
rm->rm_hwnsectors = geo.geo_nsectors;
|
||||
|
||||
/* Determine if block driver supports the XIP mode of operation */
|
||||
|
||||
rm->rm_cachesector = (uint32)-1;
|
||||
|
||||
if (inode->u.i_bops->ioctl)
|
||||
{
|
||||
ret = inode->u.i_bops->ioctl(inode, BIOC_XIPBASE,
|
||||
(unsigned long)&rm->rm_xipbase);
|
||||
if (ret == OK && rm->rm_xipbase)
|
||||
{
|
||||
/* Yes.. Then we will directly access the media (vs.
|
||||
* copying into an allocated sector buffer.
|
||||
*/
|
||||
|
||||
rm->rm_buffer = rm->rm_xipbase;
|
||||
rm->rm_cachesector = 0;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the device cache buffer for normal sector accesses */
|
||||
|
||||
rm->rm_buffer = (ubyte*)malloc(rm->rm_hwsectorsize);
|
||||
if (!rm->rm_buffer)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: romfs_mount
|
||||
* Name: romfs_fsconfigure
|
||||
*
|
||||
* Desciption:
|
||||
* Setup ROMFS on the block driver
|
||||
* This function is called as part of the ROMFS mount operation It
|
||||
* sets up the mount structure to include configuration information contained
|
||||
* in the ROMFS header. This is the place where we actually determine if
|
||||
* the media contains a ROMFS filesystem.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int romfs_mount(struct romfs_mountpt_s *rm)
|
||||
int romfs_fsconfigure(struct romfs_mountpt_s *rm)
|
||||
{
|
||||
const char *name;
|
||||
int ret;
|
||||
|
@ -471,6 +555,46 @@ int romfs_mount(struct romfs_mountpt_s *rm)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: romfs_ffileconfigure
|
||||
*
|
||||
* Desciption:
|
||||
* This function is called as part of the ROMFS file open operation It
|
||||
* sets up the file structure to handle buffer appropriately, depending
|
||||
* upon XIP mode or not.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int romfs_fileconfigure(struct romfs_mountpt_s *rm, struct romfs_file_s *rf)
|
||||
{
|
||||
/* Check if XIP access mode is supported. If so, then we do not need
|
||||
* to allocate anything.
|
||||
*/
|
||||
|
||||
if (rm->rm_xipbase)
|
||||
{
|
||||
/* We'll put a valid address in rf_buffer just in case. */
|
||||
|
||||
rf->rf_cachesector = 0;
|
||||
rf->rf_buffer = rm->rm_xipbase + rf->rf_startoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing in the cache buffer */
|
||||
|
||||
rf->rf_cachesector = (uint32)-1;
|
||||
|
||||
/* Create a file buffer to support partial sector accesses */
|
||||
|
||||
rf->rf_buffer = (ubyte*)malloc(rm->rm_hwsectorsize);
|
||||
if (!rf->rf_buffer)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: romfs_checkmount
|
||||
*
|
||||
|
@ -482,29 +606,29 @@ int romfs_mount(struct romfs_mountpt_s *rm)
|
|||
|
||||
int romfs_checkmount(struct romfs_mountpt_s *rm)
|
||||
{
|
||||
struct romfs_file_s *file;
|
||||
struct inode *inode;
|
||||
struct geometry geo;
|
||||
int ret;
|
||||
|
||||
/* If the fs_mounted flag is FALSE, then we have already handled the loss
|
||||
* of the mount.
|
||||
*/
|
||||
|
||||
if (rm && rm->rm_mounted)
|
||||
DEBUGASSERT(rm && rm->rm_blkdriver);
|
||||
if (rm->rm_mounted)
|
||||
{
|
||||
struct romfs_file_s *file;
|
||||
|
||||
/* We still think the mount is healthy. Check an see if this is
|
||||
* still the case
|
||||
*/
|
||||
|
||||
if (rm->rm_blkdriver)
|
||||
inode = rm->rm_blkdriver;
|
||||
if (inode->u.i_bops && inode->u.i_bops->geometry)
|
||||
{
|
||||
struct inode *inode = rm->rm_blkdriver;
|
||||
if (inode && inode->u.i_bops && inode->u.i_bops->geometry)
|
||||
ret = inode->u.i_bops->geometry(inode, &geo);
|
||||
if (ret == OK && geo.geo_available && !geo.geo_mediachanged)
|
||||
{
|
||||
struct geometry geo;
|
||||
int errcode = inode->u.i_bops->geometry(inode, &geo);
|
||||
if (errcode == OK && geo.geo_available && !geo.geo_mediachanged)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
* defined below:
|
||||
*/
|
||||
|
||||
#define _FIOCBASE (0x8700) /* File system ioctl commands */
|
||||
#define _BIOCBASE (0x8800) /* Block driver ioctl commands */
|
||||
#define _SIOCBASE (0x8900) /* Socket ioctl commandss */
|
||||
|
||||
|
@ -63,14 +64,25 @@
|
|||
|
||||
#define _IOC(type,nr) ((type)|(nr))
|
||||
|
||||
/* NuttX file system ioctl definitions */
|
||||
|
||||
#define _FIOCVALID(c) (_IOC_TYPE(c)==_FIOCBASE)
|
||||
#define _FIOC(nr) _IOC(_FIOCBASE,nr)
|
||||
|
||||
#define FIOC_MMAP _FIOC(0x0001) /* IN: None
|
||||
* OUT: If media is directly acccesible,
|
||||
* return (void*) base address
|
||||
* of file */
|
||||
|
||||
/* NuttX block driver ioctl definitions */
|
||||
|
||||
#define _BIOCVALID(c) (_IOC_TYPE(c)==_BIOCBASE)
|
||||
#define _BIOC(nr) _IOC(_SIOCBASE,nr)
|
||||
#define _BIOC(nr) _IOC(_BIOCBASE,nr)
|
||||
|
||||
#define _BIOC_XIPBASE _BIOC(0x0001) /* IN: None
|
||||
* OUT: If underlying is random acccesible,
|
||||
* return (void*) base address */
|
||||
#define BIOC_XIPBASE _BIOC(0x0001) /* IN: None
|
||||
* OUT: If media is directly acccesible,
|
||||
* return (void*) base address
|
||||
* of device memory */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
|
|
Loading…
Reference in a new issue