parent
5c1f086941
commit
cf7a56fc78
|
@ -90,3 +90,6 @@ obj-y += mtdpart.o
|
|||
obj-y += env.o
|
||||
obj-y += startup.o
|
||||
obj-y += misc.o
|
||||
|
||||
obj-y += cmd_fs.o
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
erase(mem.device, mem.size, mem.start);
|
||||
dev_erase(mem.device, mem.size, mem.start);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -131,9 +131,9 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
|
||||
do {
|
||||
now = min(RW_BUF_SIZE, nbytes);
|
||||
r = read(mem.device, rw_buf, now, offs, RW_SIZE(size));
|
||||
r = dev_read(mem.device, rw_buf, now, offs, RW_SIZE(size));
|
||||
if (r <= 0) {
|
||||
perror("read", r);
|
||||
perror("read");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
count = size;
|
||||
|
||||
if (count == size) {
|
||||
return write(mem.device, (uchar *)&writeval, count, mem.start, RW_SIZE(size));
|
||||
return dev_write(mem.device, (uchar *)&writeval, count, mem.start, RW_SIZE(size));
|
||||
} else {
|
||||
printf("write multiple not yet implemented\n");
|
||||
}
|
||||
|
@ -300,11 +300,11 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
while (count > 0) {
|
||||
now = min(RW_BUF_SIZE, count);
|
||||
|
||||
ret = read(src.device, rw_buf, now, src.start + offset, RW_SIZE(size));
|
||||
ret = dev_read(src.device, rw_buf, now, src.start + offset, RW_SIZE(size));
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
ret = write(dst.device, rw_buf, ret, dst.start + offset, RW_SIZE(size));
|
||||
ret = dev_write(dst.device, rw_buf, ret, dst.start + offset, RW_SIZE(size));
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if (ret < now)
|
||||
|
@ -432,14 +432,19 @@ static void memcpy_sz(void *_dst, void *_src, ulong count, ulong rwsize)
|
|||
|
||||
ssize_t mem_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong rwflags)
|
||||
{
|
||||
memcpy_sz(buf, (void *)(dev->map_base + offset), count, rwflags & RW_SIZE_MASK);
|
||||
return count;
|
||||
ulong size;
|
||||
size = min(count, dev->size - offset);
|
||||
printf("mem_read: dev->map_base: %p size: %d offset: %d\n",dev->map_base, size, offset);
|
||||
memcpy_sz(buf, (void *)(dev->map_base + offset), size, rwflags & RW_SIZE_MASK);
|
||||
return size;
|
||||
}
|
||||
|
||||
ssize_t mem_write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong rwflags)
|
||||
{
|
||||
memcpy_sz((void *)(dev->map_base + offset), buf, count, rwflags & RW_SIZE_MASK);
|
||||
return count;
|
||||
ulong size;
|
||||
size = min(count, dev->size - offset);
|
||||
memcpy_sz((void *)(dev->map_base + offset), buf, size, rwflags & RW_SIZE_MASK);
|
||||
return size;
|
||||
}
|
||||
|
||||
static struct device_d mem_dev = {
|
||||
|
|
|
@ -123,7 +123,7 @@ int add_env_spec(char *spec)
|
|||
|
||||
env_list->next = NULL;
|
||||
|
||||
err = read(info.device, env, env_size, info.start, 0);
|
||||
err = dev_read(info.device, env, env_size, info.start, 0);
|
||||
if (err != env_size)
|
||||
goto err_out;
|
||||
|
||||
|
@ -206,13 +206,13 @@ int saveenv(void)
|
|||
|
||||
*(ulong *)env = crc32(0, env + sizeof(ulong), env_size - sizeof(ulong));
|
||||
|
||||
ret = erase(info.device, info.size, info.start);
|
||||
ret = dev_erase(info.device, info.size, info.start);
|
||||
if (ret) {
|
||||
printf("unable to erase\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
ret = write(info.device, env, info.size, info.start, 0);
|
||||
ret = dev_write(info.device, env, info.size, info.start, 0);
|
||||
if (ret < 0) {
|
||||
printf("unable to write\n");
|
||||
goto err_out;
|
||||
|
|
|
@ -196,14 +196,14 @@ ssize_t part_read(struct device_d *dev, void *buf, size_t count, unsigned long o
|
|||
{
|
||||
struct partition *part = dev->platform_data;
|
||||
|
||||
return read(part->parent, buf, count, offset + part->offset, flags);
|
||||
return dev_read(part->parent, buf, count, offset + part->offset, flags);
|
||||
}
|
||||
|
||||
ssize_t part_write(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
|
||||
{
|
||||
struct partition *part = dev->platform_data;
|
||||
|
||||
return write(part->parent, buf, count, offset + part->offset, flags);
|
||||
return dev_write(part->parent, buf, count, offset + part->offset, flags);
|
||||
}
|
||||
|
||||
struct driver_d part_driver = {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <malloc.h>
|
||||
#include <driver.h>
|
||||
#include <init.h>
|
||||
#include <errno.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <fs.h>
|
||||
|
||||
|
@ -42,49 +43,56 @@
|
|||
#define CRAMINO(x) (CRAMFS_GET_OFFSET(x) ? CRAMFS_GET_OFFSET(x)<<2 : 1)
|
||||
#define OFFSET(x) ((x)->i_ino)
|
||||
|
||||
struct cramfs_super super;
|
||||
struct cramfs_priv {
|
||||
struct cramfs_super super;
|
||||
int curr_block;
|
||||
struct cramfs_inode *inode;
|
||||
char buf[4096];
|
||||
int curr_block_len;
|
||||
};
|
||||
|
||||
static int cramfs_read_super (struct device_d *dev)
|
||||
static int cramfs_read_super (struct device_d *dev, struct cramfs_priv *priv)
|
||||
{
|
||||
unsigned long root_offset;
|
||||
struct cramfs_super *super = &priv->super;
|
||||
|
||||
if (read(dev, &super, sizeof (super), 0, 0) < sizeof (super)) {
|
||||
if (dev_read(dev, super, sizeof (struct cramfs_super), 0, 0) < sizeof (struct cramfs_super)) {
|
||||
printf("read superblock failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Do sanity checks on the superblock */
|
||||
if (super.magic != CRAMFS_32 (CRAMFS_MAGIC)) {
|
||||
if (super->magic != CRAMFS_32 (CRAMFS_MAGIC)) {
|
||||
/* check at 512 byte offset */
|
||||
if (read(dev, &super, sizeof (super), 512, 0) < sizeof (super)) {
|
||||
if (dev_read(dev, super, sizeof (struct cramfs_super), 512, 0) < sizeof (struct cramfs_super)) {
|
||||
printf("read superblock failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (super.magic != CRAMFS_32 (CRAMFS_MAGIC)) {
|
||||
if (super->magic != CRAMFS_32 (CRAMFS_MAGIC)) {
|
||||
printf ("cramfs: wrong magic\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* flags is reused several times, so swab it once */
|
||||
super.flags = CRAMFS_32 (super.flags);
|
||||
super.size = CRAMFS_32 (super.size);
|
||||
super->flags = CRAMFS_32 (super->flags);
|
||||
super->size = CRAMFS_32 (super->size);
|
||||
|
||||
/* get feature flags first */
|
||||
if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
|
||||
if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) {
|
||||
printf ("cramfs: unsupported filesystem features\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check that the root inode is in a sane state */
|
||||
if (!S_ISDIR (CRAMFS_16 (super.root.mode))) {
|
||||
if (!S_ISDIR (CRAMFS_16 (super->root.mode))) {
|
||||
printf ("cramfs: root is not a directory\n");
|
||||
return -1;
|
||||
}
|
||||
root_offset = CRAMFS_GET_OFFSET (&(super.root)) << 2;
|
||||
root_offset = CRAMFS_GET_OFFSET (&(super->root)) << 2;
|
||||
if (root_offset == 0) {
|
||||
printf ("cramfs: empty filesystem");
|
||||
} else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
|
||||
} else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
|
||||
((root_offset != sizeof (struct cramfs_super)) &&
|
||||
(root_offset != 512 + sizeof (struct cramfs_super)))) {
|
||||
printf ("cramfs: bad root offset %lu\n", root_offset);
|
||||
|
@ -153,61 +161,10 @@ static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset,
|
|||
inodeoffset = nextoffset;
|
||||
}
|
||||
|
||||
printf ("can't find corresponding entry\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cramfs_uncompress (unsigned long begin, unsigned long offset,
|
||||
unsigned long loadoffset)
|
||||
{
|
||||
struct cramfs_inode *inode = (struct cramfs_inode *) (begin + offset);
|
||||
unsigned long *block_ptrs = (unsigned long *)
|
||||
(begin + (CRAMFS_GET_OFFSET (inode) << 2));
|
||||
unsigned long curr_block = (CRAMFS_GET_OFFSET (inode) +
|
||||
(((CRAMFS_24 (inode->size)) +
|
||||
4095) >> 12)) << 2;
|
||||
int size, total_size = 0;
|
||||
int i;
|
||||
|
||||
cramfs_uncompress_init ();
|
||||
|
||||
for (i = 0; i < ((CRAMFS_24 (inode->size) + 4095) >> 12); i++) {
|
||||
size = cramfs_uncompress_block ((void *) loadoffset,
|
||||
(void *) (begin + curr_block),
|
||||
(CRAMFS_32 (block_ptrs[i]) -
|
||||
curr_block));
|
||||
if (size < 0)
|
||||
return size;
|
||||
loadoffset += size;
|
||||
total_size += size;
|
||||
curr_block = CRAMFS_32 (block_ptrs[i]);
|
||||
}
|
||||
|
||||
cramfs_uncompress_exit ();
|
||||
return total_size;
|
||||
}
|
||||
|
||||
int cramfs_load (char *loadoffset, struct device_d *dev, const char *filename)
|
||||
{
|
||||
unsigned long offset;
|
||||
char *f;
|
||||
if (cramfs_read_super (dev))
|
||||
return -1;
|
||||
|
||||
f = strdup(filename);
|
||||
offset = cramfs_resolve (dev->map_base,
|
||||
CRAMFS_GET_OFFSET (&(super.root)) << 2,
|
||||
CRAMFS_24 (super.root.size), 0,
|
||||
strtok (f, "/"));
|
||||
|
||||
free(f);
|
||||
|
||||
if (offset <= 0)
|
||||
return offset;
|
||||
|
||||
return cramfs_uncompress (dev->map_base, offset,
|
||||
(unsigned long) loadoffset);
|
||||
}
|
||||
|
||||
static int cramfs_fill_dirent (struct device_d *dev, unsigned long offset, struct dirent *d)
|
||||
{
|
||||
struct cramfs_inode *inode = (struct cramfs_inode *)
|
||||
|
@ -232,8 +189,6 @@ static int cramfs_fill_dirent (struct device_d *dev, unsigned long offset, struc
|
|||
namelen--;
|
||||
}
|
||||
|
||||
d->mode = CRAMFS_16 (inode->mode);
|
||||
d->size = CRAMFS_24 (inode->size);
|
||||
memset(d->name, 0, 256);
|
||||
strncpy(d->name, name, namelen);
|
||||
|
||||
|
@ -250,6 +205,7 @@ struct cramfs_dir {
|
|||
struct dir* cramfs_opendir(struct device_d *_dev, const char *filename)
|
||||
{
|
||||
char *f;
|
||||
struct cramfs_priv *priv = _dev->priv;
|
||||
struct fs_device_d *fsdev = _dev->type_data;
|
||||
struct device_d *dev = fsdev->parent;
|
||||
|
||||
|
@ -259,14 +215,14 @@ struct dir* cramfs_opendir(struct device_d *_dev, const char *filename)
|
|||
|
||||
if (strlen (filename) == 0 || !strcmp (filename, "/")) {
|
||||
/* Root directory. Use root inode in super block */
|
||||
dir->offset = CRAMFS_GET_OFFSET (&(super.root)) << 2;
|
||||
dir->size = CRAMFS_24 (super.root.size);
|
||||
dir->offset = CRAMFS_GET_OFFSET (&(priv->super.root)) << 2;
|
||||
dir->size = CRAMFS_24 (priv->super.root.size);
|
||||
} else {
|
||||
f = strdup(filename);
|
||||
/* Resolve the path */
|
||||
dir->offset = cramfs_resolve (dev->map_base,
|
||||
CRAMFS_GET_OFFSET (&(super.root)) <<
|
||||
2, CRAMFS_24 (super.root.size), 1,
|
||||
CRAMFS_GET_OFFSET (&(priv->super.root)) <<
|
||||
2, CRAMFS_24 (priv->super.root.size), 1,
|
||||
strtok (f, "/"));
|
||||
free(f);
|
||||
if (dir->offset <= 0)
|
||||
|
@ -291,7 +247,7 @@ err_free:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct dirent* cramfs_readdir(struct device_d *_dev, struct dir *_dir)
|
||||
static struct dirent* cramfs_readdir(struct device_d *_dev, struct dir *_dir)
|
||||
{
|
||||
struct fs_device_d *fsdev = _dev->type_data;
|
||||
struct device_d *dev = fsdev->parent;
|
||||
|
@ -311,14 +267,123 @@ struct dirent* cramfs_readdir(struct device_d *_dev, struct dir *_dir)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int cramfs_closedir(struct device_d *dev, struct dir *_dir)
|
||||
static int cramfs_closedir(struct device_d *dev, struct dir *_dir)
|
||||
{
|
||||
struct cramfs_dir *dir = _dir->priv;
|
||||
free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cramfs_info (struct device_d *dev)
|
||||
static int cramfs_open(struct device_d *_dev, FILE *file, const char *filename)
|
||||
{
|
||||
struct cramfs_priv *priv = _dev->priv;
|
||||
struct fs_device_d *fsdev = _dev->type_data;
|
||||
struct device_d *dev = fsdev->parent;
|
||||
char *f;
|
||||
unsigned long offset;
|
||||
|
||||
f = strdup(filename);
|
||||
offset = cramfs_resolve (dev->map_base,
|
||||
CRAMFS_GET_OFFSET (&(priv->super.root)) << 2,
|
||||
CRAMFS_24 (priv->super.root.size), 0,
|
||||
strtok (f, "/"));
|
||||
|
||||
free(f);
|
||||
|
||||
if (offset <= 0)
|
||||
return -ENOENT;
|
||||
|
||||
file->pos = 0;
|
||||
file->inode = (struct cramfs_inode *)(dev->map_base + offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cramfs_close(struct device_d *dev, FILE *f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
|
||||
{
|
||||
struct cramfs_priv *priv = _dev->priv;
|
||||
struct fs_device_d *fsdev = _dev->type_data;
|
||||
struct device_d *dev = fsdev->parent;
|
||||
struct cramfs_inode *inode = (struct cramfs_inode *)f->inode;
|
||||
unsigned int blocknr;
|
||||
int outsize = 0;
|
||||
unsigned long *block_ptrs = (unsigned long *)
|
||||
(dev->map_base + (CRAMFS_GET_OFFSET (inode) << 2));
|
||||
int ofs = f->pos % 4096;
|
||||
|
||||
if (f->pos + size > inode->size)
|
||||
size = inode->size - f->pos;
|
||||
|
||||
while (size) {
|
||||
unsigned long base;
|
||||
int copy;
|
||||
|
||||
blocknr = f->pos >> 12;
|
||||
if (blocknr != priv->curr_block || priv->inode != inode) {
|
||||
if (blocknr)
|
||||
base = CRAMFS_32 (block_ptrs[blocknr - 1]);
|
||||
else
|
||||
base = (CRAMFS_GET_OFFSET(inode) + (((CRAMFS_24 (inode->size)) + 4095) >> 12)) << 2;
|
||||
|
||||
priv->curr_block_len = cramfs_uncompress_block (priv->buf,
|
||||
(void *)(dev->map_base + base), 4096);
|
||||
|
||||
// printf("READ blocknr: %d len %d\n",blocknr,priv->curr_block_len );
|
||||
if (priv->curr_block_len <= 0)
|
||||
break;
|
||||
|
||||
priv->curr_block = blocknr;
|
||||
priv->inode = inode;
|
||||
}
|
||||
|
||||
copy = min(priv->curr_block_len, size);
|
||||
|
||||
memcpy(buf, priv->buf + ofs, copy);
|
||||
ofs = 0;
|
||||
|
||||
f->pos += copy;
|
||||
outsize += copy;
|
||||
size -= copy;
|
||||
buf += copy;
|
||||
}
|
||||
|
||||
return outsize;
|
||||
}
|
||||
|
||||
static int cramfs_stat(struct device_d *_dev, const char *filename, struct stat *stat)
|
||||
{
|
||||
struct cramfs_priv *priv = _dev->priv;
|
||||
struct fs_device_d *fsdev = _dev->type_data;
|
||||
struct device_d *dev = fsdev->parent;
|
||||
struct cramfs_inode *inode;
|
||||
char *f;
|
||||
unsigned long offset;
|
||||
|
||||
f = strdup(filename);
|
||||
offset = cramfs_resolve (dev->map_base,
|
||||
CRAMFS_GET_OFFSET (&(priv->super.root)) << 2,
|
||||
CRAMFS_24 (priv->super.root.size), 1,
|
||||
strtok (f, "/"));
|
||||
|
||||
free(f);
|
||||
|
||||
if (offset < 0)
|
||||
return -ENOENT;
|
||||
|
||||
inode = (struct cramfs_inode *) (dev->map_base + offset);
|
||||
|
||||
stat->st_mode = CRAMFS_16 (inode->mode);
|
||||
stat->st_size = CRAMFS_24 (inode->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
static int cramfs_info (struct device_d *dev)
|
||||
{
|
||||
if (cramfs_read_super (dev))
|
||||
return 0;
|
||||
|
@ -343,32 +408,53 @@ int cramfs_info (struct device_d *dev)
|
|||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int cramfs_probe(struct device_d *dev)
|
||||
{
|
||||
struct fs_device_d *fsdev;
|
||||
|
||||
printf("%s: dev: %p\n",__FUNCTION__, dev);
|
||||
struct cramfs_priv *priv;
|
||||
|
||||
fsdev = dev->type_data;
|
||||
printf("%s: fsdev: %p\n",__FUNCTION__, fsdev);
|
||||
|
||||
if (cramfs_read_super (fsdev->parent)) {
|
||||
priv = malloc(sizeof(struct cramfs_priv));
|
||||
dev->priv = priv;
|
||||
|
||||
if (cramfs_read_super (fsdev->parent, priv)) {
|
||||
printf("no valid cramfs found on %s\n",dev->id);
|
||||
free(priv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->curr_block = -1;
|
||||
|
||||
cramfs_uncompress_init ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cramfs_remove(struct device_d *dev)
|
||||
{
|
||||
struct cramfs_priv *priv = dev->priv;
|
||||
|
||||
cramfs_uncompress_exit ();
|
||||
free(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fs_driver_d cramfs_driver = {
|
||||
.type = FS_TYPE_CRAMFS,
|
||||
.open = cramfs_open,
|
||||
.close = cramfs_close,
|
||||
.read = cramfs_read,
|
||||
.opendir = cramfs_opendir,
|
||||
.readdir = cramfs_readdir,
|
||||
.closedir = cramfs_closedir,
|
||||
.stat = cramfs_stat,
|
||||
.drv = {
|
||||
.type = DEVICE_TYPE_FS,
|
||||
.probe = cramfs_probe,
|
||||
.remove = cramfs_remove,
|
||||
.name = "cramfs",
|
||||
.type_data = &cramfs_driver,
|
||||
}
|
||||
|
|
324
fs/fs.c
324
fs/fs.c
|
@ -1,5 +1,4 @@
|
|||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <fs.h>
|
||||
#include <driver.h>
|
||||
#include <errno.h>
|
||||
|
@ -37,11 +36,35 @@ char *mkmodestr(unsigned long mode, char *str)
|
|||
return str;
|
||||
}
|
||||
|
||||
struct mtab_entry {
|
||||
char path[PATH_MAX];
|
||||
struct mtab_entry *next;
|
||||
struct device_d *dev;
|
||||
};
|
||||
/*
|
||||
* - Remove all multiple slashes
|
||||
* - Remove trailing slashes (except path consists of only
|
||||
* a single slash)
|
||||
* - TODO: illegal characters?
|
||||
*/
|
||||
void normalise_path(char *path)
|
||||
{
|
||||
char *out = path, *in = path;
|
||||
|
||||
while(*in) {
|
||||
if(*in == '/') {
|
||||
*out++ = *in++;
|
||||
while(*in == '/')
|
||||
in++;
|
||||
} else {
|
||||
*out++ = *in++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove trailing slash, but only if
|
||||
* we were given more than a single slash
|
||||
*/
|
||||
if (out > path + 1 && *(out - 1) == '/')
|
||||
*(out - 1) = 0;
|
||||
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
static struct mtab_entry *mtab;
|
||||
|
||||
|
@ -72,30 +95,149 @@ struct mtab_entry *get_mtab_entry_by_path(const char *_path)
|
|||
return match ? match : mtab;
|
||||
}
|
||||
|
||||
FILE files[MAX_FILES];
|
||||
|
||||
FILE *get_file(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 3; i < MAX_FILES; i++) {
|
||||
if (!files[i].used) {
|
||||
files[i].used = 1;
|
||||
files[i].no = i;
|
||||
memset(&files[i], 0, sizeof(FILE));
|
||||
return &files[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void put_file(FILE *f)
|
||||
{
|
||||
files[f->no].used = 0;
|
||||
}
|
||||
|
||||
int open(const char *pathname, int flags)
|
||||
{
|
||||
struct device_d *dev;
|
||||
struct fs_driver_d *fsdrv;
|
||||
struct mtab_entry *e;
|
||||
FILE *f;
|
||||
int ret;
|
||||
|
||||
f = get_file();
|
||||
if (!f) {
|
||||
errno = -EMFILE;
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (!strncmp(pathname, "/dev/", 5)) {
|
||||
dev = get_device_by_id(pathname + 5);
|
||||
f->dev = dev;
|
||||
} else {
|
||||
e = get_mtab_entry_by_path(pathname);
|
||||
if (!e) {
|
||||
errno = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (e != mtab)
|
||||
pathname += strlen(e->path);
|
||||
|
||||
dev = e->dev;
|
||||
|
||||
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||
f->dev = dev;
|
||||
|
||||
ret = fsdrv->open(dev, f, pathname);
|
||||
if (ret) {
|
||||
errno = ret;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
return f->no;
|
||||
|
||||
out:
|
||||
put_file(f);
|
||||
return errno;
|
||||
}
|
||||
|
||||
int read(int fd, void *buf, size_t count)
|
||||
{
|
||||
struct device_d *dev;
|
||||
struct fs_driver_d *fsdrv;
|
||||
FILE *f = &files[fd];
|
||||
|
||||
dev = f->dev;
|
||||
if (dev->type == DEVICE_TYPE_FS) {
|
||||
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||
errno = fsdrv->read(dev, f, buf, count);
|
||||
return errno;
|
||||
} else {
|
||||
errno = dev->driver->read(dev, buf, count, f->pos, 0); /* FIXME: flags */
|
||||
if (errno > 0)
|
||||
f->pos += errno;
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t write(int fd, const void *buf, size_t count)
|
||||
{
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
struct device_d *dev;
|
||||
struct fs_driver_d *fsdrv;
|
||||
FILE *f = &files[fd];
|
||||
|
||||
dev = f->dev;
|
||||
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||
|
||||
put_file(f);
|
||||
return fsdrv->close(dev, f);
|
||||
}
|
||||
|
||||
int mount (struct device_d *dev, char *fsname, char *path)
|
||||
{
|
||||
struct driver_d *drv;
|
||||
struct fs_driver_d *fs_drv;
|
||||
struct mtab_entry *entry;
|
||||
struct fs_device_d *fsdev;
|
||||
struct dir *dir;
|
||||
int ret;
|
||||
|
||||
errno = 0;
|
||||
|
||||
drv = get_driver_by_name(fsname);
|
||||
if (!drv) {
|
||||
printf("no driver for fstype %s\n", fsname);
|
||||
return -EINVAL;
|
||||
errno = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (drv->type != DEVICE_TYPE_FS) {
|
||||
printf("driver %s is no filesystem driver\n");
|
||||
return -EINVAL;
|
||||
errno = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check if path exists */
|
||||
/* TODO */
|
||||
if (mtab) {
|
||||
/* check if path exists and is a directory */
|
||||
if (!(dir = opendir(path))) {
|
||||
errno = -ENOTDIR;
|
||||
goto out;
|
||||
}
|
||||
closedir(dir);
|
||||
} else {
|
||||
/* no mtab, so we only allow to mount on '/' */
|
||||
if (*path != '/' || *(path + 1)) {
|
||||
errno = -ENOTDIR;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
fs_drv = drv->type_data;
|
||||
printf("mount: fs_drv: %p\n", fs_drv);
|
||||
|
||||
if (fs_drv->flags & FS_DRIVER_NO_DEV) {
|
||||
dev = malloc(sizeof(struct device_d));
|
||||
|
@ -104,12 +246,14 @@ int mount (struct device_d *dev, char *fsname, char *path)
|
|||
dev->type = DEVICE_TYPE_FS;
|
||||
if ((ret = register_device(dev))) {
|
||||
free(dev);
|
||||
return ret;
|
||||
errno = ret;
|
||||
goto out;
|
||||
}
|
||||
if (!dev->driver) {
|
||||
/* driver didn't accept the device. Bail out */
|
||||
free(dev);
|
||||
return -EINVAL;
|
||||
errno = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
fsdev = malloc(sizeof(struct fs_device_d));
|
||||
|
@ -120,12 +264,14 @@ int mount (struct device_d *dev, char *fsname, char *path)
|
|||
fsdev->dev.type_data = fsdev;
|
||||
if ((ret = register_device(&fsdev->dev))) {
|
||||
free(fsdev);
|
||||
return ret;
|
||||
errno = ret;
|
||||
goto out;
|
||||
}
|
||||
if (!fsdev->dev.driver) {
|
||||
/* driver didn't accept the device. Bail out */
|
||||
free(fsdev);
|
||||
return -EINVAL;
|
||||
errno = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
dev = &fsdev->dev;
|
||||
}
|
||||
|
@ -144,28 +290,38 @@ int mount (struct device_d *dev, char *fsname, char *path)
|
|||
e = e->next;
|
||||
e->next = entry;
|
||||
}
|
||||
|
||||
printf("mount: mtab->dev: %p\n", mtab->dev);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
return errno;
|
||||
}
|
||||
|
||||
int do_mount (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
int umount(const char *pathname)
|
||||
{
|
||||
struct device_d *dev;
|
||||
int ret = 0;
|
||||
struct mtab_entry *entry = mtab;
|
||||
struct mtab_entry *last = mtab;
|
||||
char *p = strdup(pathname);
|
||||
|
||||
if (argc != 4) {
|
||||
printf ("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
normalise_path(p);
|
||||
|
||||
while(entry && strcmp(p, entry->path)) {
|
||||
last = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
dev = get_device_by_id(argv[1]);
|
||||
free(p);
|
||||
|
||||
if ((ret = mount(dev, argv[2], argv[3]))) {
|
||||
perror("mount", ret);
|
||||
return 1;
|
||||
if (!entry) {
|
||||
errno = -EFAULT;
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (entry == mtab)
|
||||
mtab = mtab->next;
|
||||
else
|
||||
last->next = entry->next;
|
||||
|
||||
unregister_device(entry->dev);
|
||||
free(entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -207,20 +363,59 @@ int closedir(struct dir *dir)
|
|||
return dir->fsdrv->closedir(dir->dev, dir);
|
||||
}
|
||||
|
||||
static int ls(const char *path)
|
||||
int stat(const char *filename, struct stat *s)
|
||||
{
|
||||
struct device_d *dev;
|
||||
struct fs_driver_d *fsdrv;
|
||||
struct mtab_entry *e;
|
||||
char *f = strdup(filename);
|
||||
|
||||
memset(s, 0, sizeof(struct stat));
|
||||
|
||||
normalise_path(f);
|
||||
|
||||
e = get_mtab_entry_by_path(f);
|
||||
if (!e) {
|
||||
errno = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (e != mtab)
|
||||
f += strlen(e->path);
|
||||
|
||||
dev = e->dev;
|
||||
|
||||
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||
|
||||
errno = fsdrv->stat(dev, f, s);
|
||||
out:
|
||||
free(f);
|
||||
return errno;
|
||||
}
|
||||
|
||||
int ls(const char *path)
|
||||
{
|
||||
struct dir *dir;
|
||||
struct dirent *d;
|
||||
char modestr[11];
|
||||
char tmp[PATH_MAX];
|
||||
struct stat s;
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir)
|
||||
if (!dir) {
|
||||
errno = -ENOENT;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
while ((d = readdir(dir))) {
|
||||
unsigned long namelen = strlen(d->name);
|
||||
mkmodestr(d->mode, modestr);
|
||||
printf("%s %8d %*.*s\n",modestr, d->size, namelen, namelen, d->name);
|
||||
sprintf(tmp, "%s/%s", path, d->name);
|
||||
if (stat(tmp, &s)) {
|
||||
perror("stat");
|
||||
return errno;
|
||||
}
|
||||
|
||||
mkmodestr(s.st_mode, modestr);
|
||||
printf("%s %8d %*.*s\n",modestr, s.st_size, namelen, namelen, d->name);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
@ -228,25 +423,6 @@ static int ls(const char *path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int do_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ls(argv[1]);
|
||||
if (ret) {
|
||||
perror("ls", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
ls, 2, 0, do_ls,
|
||||
"ls - list a file or directory\n",
|
||||
"<path> list files on path"
|
||||
);
|
||||
|
||||
int mkdir (const char *pathname)
|
||||
{
|
||||
struct fs_driver_d *fsdrv;
|
||||
|
@ -254,8 +430,11 @@ int mkdir (const char *pathname)
|
|||
struct mtab_entry *e;
|
||||
|
||||
e = get_mtab_entry_by_path(pathname);
|
||||
if (!e)
|
||||
return NULL;
|
||||
if (!e) {
|
||||
errno = -ENOENT;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (e != mtab)
|
||||
pathname += strlen(e->path);
|
||||
|
||||
|
@ -265,37 +444,8 @@ int mkdir (const char *pathname)
|
|||
|
||||
if (fsdrv->mkdir)
|
||||
return fsdrv->mkdir(dev, pathname);
|
||||
|
||||
errno = -EROFS;
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
int do_mkdir (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mkdir(argv[1]);
|
||||
if (ret) {
|
||||
perror("ls", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
mkdir, 2, 0, do_mkdir,
|
||||
"mkdir - create a new directory\n",
|
||||
""
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
mount, 4, 0, do_mount,
|
||||
"mount - mount a filesystem to a device\n",
|
||||
" <device> <type> <path> add a filesystem of type 'type' on the given device"
|
||||
);
|
||||
#if 0
|
||||
U_BOOT_CMD(
|
||||
delfs, 2, 0, do_delfs,
|
||||
"delfs - delete a filesystem from a device\n",
|
||||
""
|
||||
);
|
||||
#endif
|
||||
|
|
89
fs/ramfs.c
89
fs/ramfs.c
|
@ -8,13 +8,6 @@
|
|||
#include <asm-generic/errno.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
struct handle_d {
|
||||
int (*read)(struct handle_d *, ...);
|
||||
int (*write)(struct handle_d *, ...);
|
||||
|
||||
struct device_d *dev;
|
||||
};
|
||||
|
||||
struct data_d {
|
||||
char *data;
|
||||
ulong size;
|
||||
|
@ -32,19 +25,6 @@ struct node_d {
|
|||
struct data_d *data;
|
||||
};
|
||||
|
||||
struct filesystem_d {
|
||||
int (*create)(struct device_d *dev, const char *pathname, mode_t mode);
|
||||
struct handle_d *(*open)(struct device_d *dev, const char *pathname, mode_t mode);
|
||||
int (*remove)(struct device_d *dev, const char *pathname);
|
||||
int (*mknod)(struct device_d *dev, const char *pathname, struct handle_d *handle);
|
||||
int (*ls)(struct device_d *dev, const char *pathname);
|
||||
};
|
||||
|
||||
int create(const char *pathname, ulong mode);
|
||||
struct handle_d *open(const char *pathname, ulong type);
|
||||
int remove(const char *pathname);
|
||||
int mknod(const char *pathname, struct handle_d *handle);
|
||||
|
||||
struct ramfs_priv {
|
||||
struct node_d root;
|
||||
};
|
||||
|
@ -88,36 +68,6 @@ out:
|
|||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* - Remove all multiple slashes
|
||||
* - Remove trailing slashes (except path consists of only
|
||||
* a single slash)
|
||||
* - TODO: illegal characters?
|
||||
*/
|
||||
void normalise_path(char *path)
|
||||
{
|
||||
char *out = path, *in = path;
|
||||
|
||||
while(*in) {
|
||||
if(*in == '/') {
|
||||
*out++ = *in++;
|
||||
while(*in == '/')
|
||||
in++;
|
||||
} else {
|
||||
*out++ = *in++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove trailing slash, but only if
|
||||
* we were given more than a single slash
|
||||
*/
|
||||
if (out > path + 1 && *(out - 1) == '/')
|
||||
*(out - 1) = 0;
|
||||
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
int node_add_child(struct node_d *node, const char *filename, ulong mode)
|
||||
{
|
||||
struct node_d *new_node = malloc(sizeof(struct node_d));
|
||||
|
@ -192,9 +142,9 @@ int ramfs_probe(struct device_d *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct handle_d *ramfs_open(struct device_d *dev, const char *pathname)
|
||||
static int ramfs_open(struct device_d *_dev, FILE *file, const char *filename)
|
||||
{
|
||||
return NULL;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
struct dir* ramfs_opendir(struct device_d *dev, const char *pathname)
|
||||
|
@ -222,7 +172,6 @@ struct dirent* ramfs_readdir(struct device_d *dev, struct dir *dir)
|
|||
{
|
||||
if (dir->node) {
|
||||
strcpy(dir->d.name, dir->node->name);
|
||||
dir->d.mode = dir->node->mode;
|
||||
dir->node = dir->node->next;
|
||||
return &dir->d;
|
||||
}
|
||||
|
@ -235,6 +184,21 @@ int ramfs_closedir(struct device_d *dev, struct dir *dir)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ramfs_stat(struct device_d *dev, const char *filename, struct stat *s)
|
||||
{
|
||||
struct ramfs_priv *priv = dev->priv;
|
||||
struct node_d *node = rlookup(&priv->root, filename);
|
||||
|
||||
if (!node) {
|
||||
errno = -ENOENT;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
s->st_mode = node->mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fs_driver_d ramfs_driver = {
|
||||
.type = FS_TYPE_RAMFS,
|
||||
.create = ramfs_create,
|
||||
|
@ -245,6 +209,7 @@ static struct fs_driver_d ramfs_driver = {
|
|||
.opendir = ramfs_opendir,
|
||||
.readdir = ramfs_readdir,
|
||||
.closedir = ramfs_closedir,
|
||||
.stat = ramfs_stat,
|
||||
|
||||
.flags = FS_DRIVER_NO_DEV,
|
||||
.drv = {
|
||||
|
@ -262,21 +227,3 @@ int ramfs_init(void)
|
|||
|
||||
device_initcall(ramfs_init);
|
||||
|
||||
/* --------- Testing --------- */
|
||||
|
||||
static int do_create ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||
{
|
||||
// int ret;
|
||||
|
||||
printf("create %s\n",argv[1]);
|
||||
// ret = ramfs_create(&ramfs_device, argv[1], S_IFDIR);
|
||||
// perror("create", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
create, 2, 0, do_create,
|
||||
"ls - list a file or directory\n",
|
||||
"<dev:path> list files on device"
|
||||
);
|
||||
|
||||
|
|
|
@ -593,7 +593,7 @@ void vprintf(const char *fmt, va_list args);
|
|||
#define stdin 0
|
||||
#define stdout 1
|
||||
#define stderr 2
|
||||
#define MAX_FILES 3
|
||||
#define MAX_FILES 16
|
||||
|
||||
void fprintf(int file, const char *fmt, ...);
|
||||
void fputs(int file, const char *s);
|
||||
|
|
|
@ -48,6 +48,7 @@ struct driver_d {
|
|||
struct driver_d *next;
|
||||
|
||||
int (*probe) (struct device_d *);
|
||||
int (*remove)(struct device_d *);
|
||||
ssize_t (*read) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
|
||||
ssize_t (*write) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
|
||||
ssize_t (*erase) (struct device_d*, size_t count, unsigned long offset);
|
||||
|
@ -74,13 +75,13 @@ void unregister_device(struct device_d *);
|
|||
struct device_d *device_from_spec_str(const char *str, char **endp);
|
||||
struct device_d *get_device_by_name(char *name);
|
||||
struct device_d *get_device_by_type(ulong type, struct device_d *last);
|
||||
struct device_d *get_device_by_id(char *id);
|
||||
struct device_d *get_device_by_id(const char *id);
|
||||
|
||||
struct driver_d *get_driver_by_name(char *name);
|
||||
|
||||
ssize_t read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
|
||||
ssize_t write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
|
||||
ssize_t erase(struct device_d *dev, size_t count, unsigned long offset);
|
||||
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
|
||||
ssize_t dev_write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
|
||||
ssize_t dev_erase(struct device_d *dev, size_t count, unsigned long offset);
|
||||
|
||||
ssize_t mem_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
|
||||
ssize_t mem_write(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef __ERRNO_H
|
||||
#define __ERRNO_H
|
||||
|
||||
void perror(const char *s, int errno);
|
||||
extern int errno;
|
||||
|
||||
void perror(const char *s);
|
||||
|
||||
#endif /* __ERRNO_H */
|
||||
|
|
43
include/fs.h
43
include/fs.h
|
@ -10,10 +10,9 @@
|
|||
|
||||
struct partition;
|
||||
struct node_d;
|
||||
struct stat;
|
||||
|
||||
struct dirent {
|
||||
unsigned long mode;
|
||||
unsigned long size;
|
||||
char name[256];
|
||||
};
|
||||
|
||||
|
@ -25,20 +24,32 @@ struct dir {
|
|||
void *priv; /* private data for the fs driver */
|
||||
};
|
||||
|
||||
typedef struct filep {
|
||||
struct device_d *dev;
|
||||
ulong pos;
|
||||
char used;
|
||||
int no;
|
||||
void *inode; /* private to the filesystem driver */
|
||||
} FILE;
|
||||
|
||||
#define FS_DRIVER_NO_DEV 1
|
||||
|
||||
struct fs_driver_d {
|
||||
ulong type;
|
||||
char *name;
|
||||
int (*load) (char *dst, struct device_d *dev, const char *filename);
|
||||
int (*probe) (struct device_d *dev);
|
||||
int (*create)(struct device_d *dev, const char *pathname, ulong type);
|
||||
int (*mkdir)(struct device_d *dev, const char *pathname);
|
||||
struct handle_d *(*open)(struct device_d *dev, const char *pathname);
|
||||
|
||||
int (*open)(struct device_d *dev, FILE *f, const char *pathname);
|
||||
int (*close)(struct device_d *dev, FILE *f);
|
||||
int (*read)(struct device_d *dev, FILE *f, void *buf, size_t size);
|
||||
int (*write)(struct device_d *dev, FILE *f, void *buf, size_t size);
|
||||
|
||||
struct dir* (*opendir)(struct device_d *dev, const char *pathname);
|
||||
struct dirent* (*readdir)(struct device_d *dev, struct dir *dir);
|
||||
int (*closedir)(struct device_d *dev, struct dir *dir);
|
||||
int (*stat)(struct device_d *dev, const char *file, struct stat *stat);
|
||||
|
||||
struct driver_d drv;
|
||||
|
||||
|
@ -52,11 +63,29 @@ struct fs_device_d {
|
|||
struct fs_driver_d *driver;
|
||||
};
|
||||
|
||||
int register_filesystem(struct device_d *dev, char *fsname);
|
||||
//int unregister_filesystem(struct device_d *dev);
|
||||
int open(const char *pathname, int flags);
|
||||
int close(int fd);
|
||||
int read(int fd, void *buf, size_t count);
|
||||
ssize_t write(int fd, const void *buf, size_t count);
|
||||
int ls(const char *path);
|
||||
int mkdir (const char *pathname);
|
||||
int mount (struct device_d *dev, char *fsname, char *path);
|
||||
int umount(const char *pathname);
|
||||
|
||||
int register_fs_driver(struct fs_driver_d *new_fs_drv);
|
||||
struct dir *opendir(const char *pathname);
|
||||
struct dirent *readdir(struct dir *dir);
|
||||
int closedir(struct dir *dir);
|
||||
|
||||
char *mkmodestr(unsigned long mode, char *str);
|
||||
|
||||
struct mtab_entry *get_mtab_entry_by_path(const char *path);
|
||||
|
||||
struct mtab_entry {
|
||||
char path[PATH_MAX];
|
||||
struct mtab_entry *next;
|
||||
struct device_d *dev;
|
||||
};
|
||||
|
||||
void normalise_path(char *path);
|
||||
|
||||
#endif /* __FS_H */
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <init.h>
|
||||
#include <malloc.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <errno.h>
|
||||
#include <asm-generic/errno.h>
|
||||
|
||||
int cmd_get_data_size(char* arg, int default_size)
|
||||
|
@ -32,7 +33,7 @@ int cmd_get_data_size(char* arg, int default_size)
|
|||
static struct device_d *first_device = NULL;
|
||||
static struct driver_d *first_driver = NULL;
|
||||
|
||||
struct device_d *get_device_by_id(char *id)
|
||||
struct device_d *get_device_by_id(const char *id)
|
||||
{
|
||||
struct device_d *d;
|
||||
|
||||
|
@ -357,25 +358,28 @@ out:
|
|||
return 0;
|
||||
}
|
||||
|
||||
ssize_t read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
|
||||
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
|
||||
{
|
||||
if (dev->driver->read)
|
||||
return dev->driver->read(dev, buf, count, offset, flags);
|
||||
return -1;
|
||||
errno = -ENOSYS;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
ssize_t write(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
|
||||
ssize_t dev_write(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
|
||||
{
|
||||
if (dev->driver->write)
|
||||
return dev->driver->write(dev, buf, count, offset, flags);
|
||||
return -1;
|
||||
errno = -ENOSYS;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
ssize_t erase(struct device_d *dev, size_t count, unsigned long offset)
|
||||
ssize_t dev_erase(struct device_d *dev, size_t count, unsigned long offset)
|
||||
{
|
||||
if (dev->driver->erase)
|
||||
return dev->driver->erase(dev, count, offset);
|
||||
return -1;
|
||||
errno = -ENOSYS;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int dummy_probe(struct device_d *dev)
|
||||
|
@ -414,7 +418,12 @@ struct param_d* dev_get_param(struct device_d *dev, char *name)
|
|||
{
|
||||
struct param_d *param = get_param_by_name(dev, name);
|
||||
|
||||
if (param && param->get)
|
||||
if (!param) {
|
||||
errno = -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (param->get)
|
||||
return param->get(dev, param);
|
||||
|
||||
return param;
|
||||
|
@ -424,8 +433,10 @@ IPaddr_t dev_get_param_ip(struct device_d *dev, char *name)
|
|||
{
|
||||
struct param_d *param = dev_get_param(dev, name);
|
||||
|
||||
if (!param || param->type != PARAM_TYPE_IPADDR)
|
||||
return -1;
|
||||
if (!param || param->type != PARAM_TYPE_IPADDR) {
|
||||
errno = -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return param->value.val_ip;
|
||||
}
|
||||
|
@ -443,11 +454,15 @@ int dev_set_param(struct device_d *dev, char *name, value_t val)
|
|||
{
|
||||
struct param_d *param = get_param_by_name(dev, name);
|
||||
|
||||
if (!param)
|
||||
if (!param) {
|
||||
errno = -EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (param->flags & PARAM_FLAG_RO)
|
||||
if (param->flags & PARAM_FLAG_RO) {
|
||||
errno = -EACCES;
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (param->set)
|
||||
return param->set(dev, param, val);
|
||||
|
|
|
@ -65,7 +65,7 @@ store_block (unsigned block, uchar * src, unsigned len)
|
|||
ulong offset = block * TFTP_BLOCK_SIZE + TftpBlockWrapOffset;
|
||||
ulong newsize = offset + len;
|
||||
|
||||
write(net_store_mem.device, src, len, net_store_mem.start + offset, 0);
|
||||
dev_write(net_store_mem.device, src, len, net_store_mem.start + offset, 0);
|
||||
|
||||
if (NetBootFileXferSize < newsize)
|
||||
NetBootFileXferSize = newsize;
|
||||
|
|
Loading…
Reference in New Issue