summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--board/scb9328/scb9328.c2
-rw-r--r--common/cmd_bootm.c10
-rw-r--r--common/cmd_flash.c9
-rw-r--r--common/cmd_mem.c135
-rw-r--r--common/cmd_net.c12
-rw-r--r--common/hush.c4
-rw-r--r--fs/cramfs/cramfs.c2
-rw-r--r--fs/fs.c101
-rw-r--r--fs/ramfs.c130
-rw-r--r--include/driver.h4
-rw-r--r--include/fs.h16
-rw-r--r--lib_generic/misc.c123
-rw-r--r--net/tftp.c5
13 files changed, 358 insertions, 195 deletions
diff --git a/board/scb9328/scb9328.c b/board/scb9328/scb9328.c
index a6092ec59e..ec75bf529b 100644
--- a/board/scb9328/scb9328.c
+++ b/board/scb9328/scb9328.c
@@ -64,7 +64,7 @@ device_initcall(scb9328_devices_init);
static int scb9328_init_env(void)
{
- add_env_spec(env_spec);
+ add_env_spec(env_spec);
return 0;
}
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index c3c047fa6b..93528510ff 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -169,11 +169,11 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
- if (spec_str_to_info(argv[1], &mem)) {
- printf("-ENOPARSE\n");
- return -1;
- }
-
+// if (spec_str_to_info(argv[1], &mem)) {
+// printf("-ENOPARSE\n");
+// return -1;
+// }
+#warning: FIXME: bootm is broken
addr = mem.start + mem.device->map_base;
SHOW_BOOT_PROGRESS (1);
diff --git a/common/cmd_flash.c b/common/cmd_flash.c
index 43c44f2818..c1541a80e9 100644
--- a/common/cmd_flash.c
+++ b/common/cmd_flash.c
@@ -36,7 +36,7 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
-
+# if 0
if (spec_str_to_info(argv[1], &mem)) {
printf("-ENOPARSE\n");
return 1;
@@ -52,7 +52,8 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
dev_erase(mem.device, mem.size, mem.start);
-
+#endif
+#warning: do_flerase is broken
return 0;
}
@@ -75,12 +76,12 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
-
+#if 0
if (spec_str_to_info(argv[2], &mem_info)) {
printf ("-EPARSE\n");
return 1;
}
-
+#endif
// rcode = flash_sect_protect (p, addr_first, addr_last);
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 0a026f6b2a..6ce292e42b 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -34,6 +34,8 @@
#include <malloc.h>
#include <errno.h>
#include <asm-generic/errno.h>
+#include <fs.h>
+#include <fcntl.h>
#ifdef CMD_MEM_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
@@ -103,53 +105,49 @@ int memory_display(char *addr, ulong offs, ulong nbytes, int size)
int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- ulong offs, now;
- ulong nbytes = 0x100;
- struct memarea_info mem;
- int size, r;
+ ulong start;
+ int size, r, now;
int ret = 0;
+ int fd;
if (argc < 2) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
- if (spec_str_to_info(argv[1], &mem)) {
- printf("-ENOPARSE\n");
- return -ENODEV;
- }
-
- if (mem.flags & MEMAREA_SIZE_SPECIFIED)
- nbytes = mem.size;
- else
- nbytes = min((ulong)0x100, mem.size);
-
- if ((size = cmd_get_data_size(argv[0], 4)) < 0)
- return -EINVAL;
+ fd = open("/dev/mem", O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
- offs = mem.start;
+ parse_area_spec(argv[1], &start, &size);
+ if (size == ~0)
+ size = 0x100;
do {
- now = min(RW_BUF_SIZE, nbytes);
- r = dev_read(mem.device, rw_buf, now, offs, RW_SIZE(size));
- if (r <= 0) {
+ now = min(size, RW_BUF_SIZE);
+ r = read(fd, rw_buf, now);
+ if (r < 0) {
perror("read");
return r;
}
+ if (!r)
+ goto out;
- if ((ret = memory_display(rw_buf, offs, r, size)))
- return ret;
-
- if (r < now)
- return 0;
+ if ((ret = memory_display(rw_buf, start, r, 1)))
+ goto out;
- nbytes -= now;
- offs += now;
- } while (nbytes > 0);
+ start += r;
+ size -= r;
+ } while (size);
+out:
+ close(fd);
+printf("closed\n");
return 0;
}
-
+#if 0
int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr, writeval, count;
@@ -192,6 +190,14 @@ int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0;
}
+U_BOOT_CMD(
+ mw, 4, 0, do_mem_mw,
+ "mw - memory write (fill)\n",
+ "[.b, .w, .l] address value [count]\n - write memory\n"
+);
+
+#endif
+
int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr1, addr2, count, ngood;
@@ -260,7 +266,7 @@ int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
ngood == 1 ? "" : "s");
return rcode;
}
-
+#if 0
int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong count, offset, now;
@@ -316,6 +322,63 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0;
}
+U_BOOT_CMD(
+ cp, 4, 0, do_mem_cp,
+ "cp - memory copy\n",
+ "[.b, .w, .l] source target count\n - copy memory\n"
+);
+#endif
+
+int do_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int r, w, ret = 1;
+ int src, dst;
+
+ src = open(argv[1], O_RDONLY);
+ if (src < 0) {
+ perror("open");
+ return 1;
+ }
+
+ if(creat(argv[2], 0)) {
+ perror("create");
+ return 1;
+ }
+
+ dst = open(argv[2], O_WRONLY | O_CREAT);
+ if ( dst < 0) {
+ perror("open");
+ close(src);
+ return 1;
+ }
+
+ while(1) {
+ r = read(src, rw_buf, RW_BUF_SIZE);
+ if (read < 0) {
+ perror("read");
+ goto out;
+ }
+ if (!r)
+ break;
+ w = write(dst, rw_buf, r);
+ if (w < 0) {
+ perror("write");
+ goto out;
+ }
+ }
+ ret = 0;
+out:
+ close(src);
+ close(dst);
+ return ret;
+}
+
+U_BOOT_CMD(
+ cp, 4, 0, do_cp,
+ "cp - memory copy\n",
+ "[.b, .w, .l] source target count\n - copy memory\n"
+);
+
#ifndef CONFIG_CRC32_VERIFY
int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@@ -492,18 +555,6 @@ U_BOOT_CMD(
);
U_BOOT_CMD(
- mw, 4, 0, do_mem_mw,
- "mw - memory write (fill)\n",
- "[.b, .w, .l] address value [count]\n - write memory\n"
-);
-
-U_BOOT_CMD(
- cp, 4, 0, do_mem_cp,
- "cp - memory copy\n",
- "[.b, .w, .l] source target count\n - copy memory\n"
-);
-
-U_BOOT_CMD(
cmp, 4, 0, do_mem_cmp,
"cmp - memory compare\n",
"[.b, .w, .l] addr1 addr2 count\n - compare memory\n"
diff --git a/common/cmd_net.c b/common/cmd_net.c
index fede091cd3..7a2186f067 100644
--- a/common/cmd_net.c
+++ b/common/cmd_net.c
@@ -29,6 +29,9 @@
#include <asm-generic/errno.h>
#include <driver.h>
#include <net.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <errno.h>
extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
@@ -152,7 +155,7 @@ U_BOOT_CMD(
);
#endif /* CONFIG_NET_NFS */
-struct memarea_info net_store_mem;
+int net_store_fd;
static int
netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
@@ -165,9 +168,10 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
return 1;
}
- if (spec_str_to_info(argv[1], &net_store_mem)) {
- printf("-ENOPARSE\n");
- return -ENODEV;
+ net_store_fd = open(argv[1], O_WRONLY | O_CREAT);
+ if (net_store_fd < 0) {
+ perror("open");
+ return 1;
}
copy_filename (BootFile, argv[2], sizeof(BootFile));
diff --git a/common/hush.c b/common/hush.c
index c378f6def7..e27520fb85 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -3088,7 +3088,9 @@ void mapset(const unsigned char *set, int code)
void update_ifs_map(void)
{
/* char *ifs and char map[256] are both globals. */
- ifs = (uchar *)getenv("IFS");
+#warning IFS is broken
+// ifs = (uchar *)getenv("IFS");
+ ifs = NULL;
if (ifs == NULL) ifs=(uchar *)" \t\n";
/* Precompute a list of 'flow through' behavior so it can be treated
* quickly up front. Computation is necessary because of IFS.
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
index 25631a6b74..c8ef7d7ff0 100644
--- a/fs/cramfs/cramfs.c
+++ b/fs/cramfs/cramfs.c
@@ -294,7 +294,7 @@ static int cramfs_open(struct device_d *_dev, FILE *file, const char *filename)
return -ENOENT;
file->pos = 0;
- file->inode = (struct cramfs_inode *)(dev->map_base + offset);
+ file->inode = dev->map_base + offset;
return 0;
}
diff --git a/fs/fs.c b/fs/fs.c
index 4ed3e39f4e..b43a9e7b38 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -102,10 +102,10 @@ 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;
+ if (!files[i].in_use) {
memset(&files[i], 0, sizeof(FILE));
+ files[i].in_use = 1;
+ files[i].no = i;
return &files[i];
}
}
@@ -114,27 +114,60 @@ FILE *get_file(void)
void put_file(FILE *f)
{
- files[f->no].used = 0;
+ files[f->no].in_use = 0;
}
-int open(const char *pathname, int flags)
+static FILE* get_file_by_pathname(const char *pathname)
{
- 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;
+ return NULL;
}
if (!strncmp(pathname, "/dev/", 5)) {
- dev = get_device_by_id(pathname + 5);
- f->dev = dev;
- } else {
+ f->dev = get_device_by_id(pathname + 5);
+ }
+
+ return f;
+}
+
+int creat(const char *pathname, mode_t mode)
+{
+ struct mtab_entry *e;
+ struct device_d *dev;
+ struct fs_driver_d *fsdrv;
+
+ e = get_mtab_entry_by_path(pathname);
+ if (!e) {
+ errno = -ENOENT;
+ return errno;
+ }
+
+ if (e != mtab)
+ pathname += strlen(e->path);
+
+ dev = e->dev;
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+
+ errno = fsdrv->create(dev, pathname, mode);
+
+ return errno;
+}
+
+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_by_pathname(pathname);
+
+ if (!f->dev) {
e = get_mtab_entry_by_path(pathname);
if (!e) {
errno = -ENOENT;
@@ -155,7 +188,7 @@ int open(const char *pathname, int flags)
goto out;
}
}
-
+printf("open: %d\n",f->no);
return f->no;
out:
@@ -170,21 +203,35 @@ int read(int fd, void *buf, size_t count)
FILE *f = &files[fd];
dev = f->dev;
+ printf("READ: dev: %p\n",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;
}
+ if (errno > 0)
+ f->pos += errno;
+ return errno;
}
ssize_t write(int fd, const void *buf, size_t count)
{
- return -EROFS;
+ struct device_d *dev;
+ struct fs_driver_d *fsdrv;
+ FILE *f = &files[fd];
+
+ dev = f->dev;
+ printf("WRITE: dev: %p\n",dev);
+ if (dev->type == DEVICE_TYPE_FS) {
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+ errno = fsdrv->write(dev, f, buf, count);
+ } else {
+ errno = dev->driver->write(dev, buf, count, f->pos, 0); /* FIXME: flags */
+ }
+ if (errno > 0)
+ f->pos += errno;
+ return errno;
}
int close(int fd)
@@ -194,10 +241,14 @@ int close(int fd)
FILE *f = &files[fd];
dev = f->dev;
- fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+
+ if (dev->type == DEVICE_TYPE_FS) {
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+ errno = fsdrv->close(dev, f);
+ }
put_file(f);
- return fsdrv->close(dev, f);
+ return errno;
}
int mount (struct device_d *dev, char *fsname, char *path)
@@ -368,7 +419,8 @@ 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);
+ char *buf = strdup(filename);
+ char *f = buf;
memset(s, 0, sizeof(struct stat));
@@ -386,9 +438,12 @@ int stat(const char *filename, struct stat *s)
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+ if (*f == 0)
+ f = "/";
+
errno = fsdrv->stat(dev, f, s);
out:
- free(f);
+ free(buf);
return errno;
}
diff --git a/fs/ramfs.c b/fs/ramfs.c
index d271b27bf9..a17315d6f2 100644
--- a/fs/ramfs.c
+++ b/fs/ramfs.c
@@ -8,33 +8,38 @@
#include <asm-generic/errno.h>
#include <linux/stat.h>
+#define CHUNK_SIZE 512
+
struct data_d {
char *data;
- ulong size;
struct data_d *next;
};
-struct node_d {
+struct ramfs_inode {
char *name;
- struct node_d *next;
- struct node_d *child;
+ struct ramfs_inode *next;
+ struct ramfs_inode *child;
ulong mode;
struct handle_d *handle;
+ ulong size;
struct data_d *data;
};
struct ramfs_priv {
- struct node_d root;
+ struct ramfs_inode root;
};
/* ---------------------------------------------------------------*/
-struct node_d * __lookup(struct node_d *node, const char *name)
+struct ramfs_inode * __lookup(struct ramfs_inode *node, const char *name)
{
// printf("__lookup: %s in %p\n",name, node);
+ if(node->mode != S_IFDIR)
+ return NULL;
+
node = node->child;
- if (!node || node->mode != S_IFDIR)
+ if (!node)
return NULL;
while (node) {
@@ -45,7 +50,7 @@ struct node_d * __lookup(struct node_d *node, const char *name)
return NULL;
}
-struct node_d* rlookup(struct node_d *node, const char *path)
+struct ramfs_inode* rlookup(struct ramfs_inode *node, const char *path)
{
static char *buf;
char *part;
@@ -68,14 +73,14 @@ out:
return node;
}
-int node_add_child(struct node_d *node, const char *filename, ulong mode)
+int node_add_child(struct ramfs_inode *node, const char *filename, ulong mode)
{
- struct node_d *new_node = malloc(sizeof(struct node_d));
- memset(new_node, 0, sizeof(struct node_d));
+ struct ramfs_inode *new_node = malloc(sizeof(struct ramfs_inode));
+ memset(new_node, 0, sizeof(struct ramfs_inode));
new_node->name = strdup(filename);
new_node->mode = mode;
-// printf("node_add_child: %p -> %p\n", node, new_node);
+ printf("node_add_child: %p -> %p\n", node, new_node);
if (!node->child) {
node->child = new_node;
return 0;
@@ -92,18 +97,18 @@ int node_add_child(struct node_d *node, const char *filename, ulong mode)
/* ---------------------------------------------------------------*/
-int ramfs_create(struct device_d *dev, const char *pathname, ulong mode)
+int ramfs_create(struct device_d *dev, const char *pathname, mode_t mode)
{
struct ramfs_priv *priv = dev->priv;
char *path = strdup(pathname);
char *file;
- struct node_d *node;
+ struct ramfs_inode *node;
normalise_path(path);
if (*path == '/')
path++;
-// printf("after normalise: %s\n",path);
+ printf("ramfs create: %s\n",path);
if ((file = strrchr(path, '/'))) {
*file = 0;
@@ -118,7 +123,7 @@ int ramfs_create(struct device_d *dev, const char *pathname, ulong mode)
if(__lookup(node, file))
return -EEXIST;
-
+printf("CREATE\n");
return node_add_child(node, file, mode);
}
@@ -139,20 +144,87 @@ int ramfs_probe(struct device_d *dev)
priv->root.name = "/";
priv->root.mode = S_IFDIR;
+ printf("root node: %p\n",&priv->root);
+ return 0;
+}
+
+static int ramfs_open(struct device_d *dev, FILE *file, const char *filename)
+{
+ struct ramfs_priv *priv = dev->priv;
+ struct ramfs_inode *node = rlookup(&priv->root, filename);
+
+ if (!node)
+ return -ENOENT;
+
+ file->pos = 0;
+ file->inode = node;
+ return 0;
+}
+
+static int ramfs_close(struct device_d *dev, FILE *f)
+{
return 0;
}
-static int ramfs_open(struct device_d *_dev, FILE *file, const char *filename)
+static int ramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
{
- return -ENOENT;
+ return 0;
+}
+
+struct data_d *ramfs_get_chunk(void)
+{
+ struct data_d *data = malloc(sizeof(struct data_d));
+ data->data = malloc(CHUNK_SIZE);
+ data->next = NULL;
+ return data;
+}
+
+static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size)
+{
+ struct ramfs_inode *node = (struct ramfs_inode *)f->inode;
+ int chunk;
+ struct data_d *data = node->data;
+ int ofs;
+ int outsize = 0;
+ int now;
+
+ chunk = f->pos / CHUNK_SIZE;
+ printf("%s: wrinting to chunk %d\n", __FUNCTION__, chunk);
+
+ if (!node->data)
+ node->data = ramfs_get_chunk();
+
+ while (chunk) {
+ data = data->next;
+ chunk--;
+ }
+
+ ofs = f->pos % CHUNK_SIZE;
+
+ while (size) {
+ if (ofs == CHUNK_SIZE) {
+ printf("get new chunk\n");
+ data->next = ramfs_get_chunk();
+ data = data->next;
+ }
+
+ now = min(size, CHUNK_SIZE - ofs);
+ printf("now: %d data->data: %p buf: %p\n", now, data->data, buf);
+ memcpy(data->data, buf, now);
+ size -= now;
+ buf += now;
+ ofs += now;
+ outsize += now;
+ }
+ return outsize;
}
struct dir* ramfs_opendir(struct device_d *dev, const char *pathname)
{
struct dir *dir;
struct ramfs_priv *priv = dev->priv;
- struct node_d *node = rlookup(&priv->root, pathname);
-
+ struct ramfs_inode *node = rlookup(&priv->root, pathname);
+printf("opendir: %s\n",pathname);
if (!node)
return NULL;
@@ -163,16 +235,18 @@ struct dir* ramfs_opendir(struct device_d *dev, const char *pathname)
if (!dir)
return NULL;
- dir->node = node->child;
+ dir->priv = node->child;
return dir;
}
struct dirent* ramfs_readdir(struct device_d *dev, struct dir *dir)
{
- if (dir->node) {
- strcpy(dir->d.name, dir->node->name);
- dir->node = dir->node->next;
+ struct ramfs_inode *node = dir->priv;
+
+ if (node) {
+ strcpy(dir->d.name, node->name);
+ dir->priv = node->next;
return &dir->d;
}
return NULL;
@@ -187,8 +261,8 @@ int ramfs_closedir(struct device_d *dev, struct dir *dir)
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);
-
+ struct ramfs_inode *node = rlookup(&priv->root, filename);
+printf("%s: %s node: %p\n",__FUNCTION__, filename, node);
if (!node) {
errno = -ENOENT;
return -ENOENT;
@@ -203,6 +277,10 @@ static struct fs_driver_d ramfs_driver = {
.type = FS_TYPE_RAMFS,
.create = ramfs_create,
.open = ramfs_open,
+ .close = ramfs_close,
+
+ .read = ramfs_read,
+ .write = ramfs_write,
.mkdir = ramfs_mkdir,
diff --git a/include/driver.h b/include/driver.h
index a37a7cd0bb..22860f258b 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -10,7 +10,7 @@
#define DEVICE_TYPE_ETHER 1
#define DEVICE_TYPE_STDIO 2
#define DEVICE_TYPE_DRAM 3
-#define DEVICE_TYPE_FS 3
+#define DEVICE_TYPE_FS 4
#define MAX_DEVICE_TYPE 4
#include <param.h>
@@ -50,7 +50,7 @@ struct driver_d {
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 (*write) (struct device_d*, const void* buf, size_t count, ulong offset, ulong flags);
ssize_t (*erase) (struct device_d*, size_t count, unsigned long offset);
void (*info) (struct device_d *);
diff --git a/include/fs.h b/include/fs.h
index 22e5fcf07e..502a70d59f 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -25,11 +25,14 @@ struct dir {
};
typedef struct filep {
- struct device_d *dev;
- ulong pos;
- char used;
+ struct device_d *dev; /* The device this FILE belongs to */
+ ulong pos; /* current position in stream */
+
+ void *inode; /* private to the filesystem driver */
+
+ /* private fields. Mapping between FILE and filedescriptor number */
int no;
- void *inode; /* private to the filesystem driver */
+ char in_use;
} FILE;
#define FS_DRIVER_NO_DEV 1
@@ -38,13 +41,13 @@ struct fs_driver_d {
ulong type;
char *name;
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);
int (*open)(struct device_d *dev, FILE *f, const char *pathname);
+ int (*create)(struct device_d *dev, const char *pathname, mode_t mode);
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);
+ int (*write)(struct device_d *dev, FILE *f, const 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);
@@ -64,6 +67,7 @@ struct fs_device_d {
};
int open(const char *pathname, int flags);
+int creat(const char *pathname, mode_t mode);
int close(int fd);
int read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
diff --git a/lib_generic/misc.c b/lib_generic/misc.c
index 92a8374a16..2aac78f211 100644
--- a/lib_generic/misc.c
+++ b/lib_generic/misc.c
@@ -7,6 +7,7 @@
#include <linux/ctype.h>
#include <errno.h>
#include <asm-generic/errno.h>
+#include <fs.h>
int cmd_get_data_size(char* arg, int default_size)
{
@@ -33,9 +34,14 @@ 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(const char *id)
+struct device_d *get_device_by_id(const char *_id)
{
struct device_d *d;
+ char *id, *colon;
+
+ id = strdup(_id);
+ if ((colon = strchr(id, ':')))
+ *colon = 0;
d = first_device;
@@ -45,6 +51,7 @@ struct device_d *get_device_by_id(const char *id)
d = d->next;
}
+ free(id);
return d;
}
@@ -169,7 +176,7 @@ int register_driver(struct driver_d *new_driver)
return 0;
}
-static char devicename_from_spec_str_buf[MAX_DRIVER_NAME];
+static char devicename_from_spec_str_buf[PATH_MAX];
char *deviceid_from_spec_str(const char *str, char **endp)
{
@@ -263,99 +270,59 @@ unsigned long strtoul_suffix(const char *str, char **endp, int base)
return val;
}
-/*
- * Parse a string representing a memory area and fill in a struct memarea_info.
- */
-int spec_str_to_info(const char *str, struct memarea_info *info)
+int parse_area_spec(const char *str, ulong *start, ulong *size)
{
char *endp;
- memset(info, 0, sizeof(struct memarea_info));
-
- info->device = device_from_spec_str(str, &endp);
- if (!info->device) {
- printf("unknown device: %s\n", deviceid_from_spec_str(str, NULL));
- return -ENODEV;
- }
-
- if (!info->device->driver) {
- printf("no driver associated to device %s\n",deviceid_from_spec_str(str, NULL));
- return -ENODEV;
+ if (*str == '+') {
+ /* no beginning given but size so start is 0 */
+ *start = 0;
+ *size = strtoul_suffix(str + 1, &endp, 0);
+ return 0;
}
- str = endp;
-
- if (!*str) {
- /* no area specification given, use whole device */
- info->size = info->device->size;
- info->end = info->size - 1;
- goto out;
- }
-
- if (*str == '+') {
- /* no beginning given but size so start is 0 */
- info->size = strtoul_suffix(str + 1, &endp, 0);
- info->end = info->size - 1;
- info->flags = MEMAREA_SIZE_SPECIFIED;
- goto out;
- }
+ if (*str == '-') {
+ /* no beginning given but end, so start is 0 */
+ *start = 0;
+ *size = strtoul_suffix(str + 1, &endp, 0) + 1;
+ return 0;
+ }
- if (*str == '-') {
- /* no beginning given but end, so start is 0 */
- info->end = strtoul_suffix(str + 1, &endp, 0);
- info->size = info->end + 1;
- info->flags = MEMAREA_SIZE_SPECIFIED;
- goto out;
- }
+ *start = strtoul_suffix(str, &endp, 0);
- str = endp;
- info->start = strtoul_suffix(str, &endp, 0);
- str = endp;
+ str = endp;
- if (info->start >= info->device->size) {
- printf("Start address is beyond device\n");
- return -1;
- }
-
- if (!*str) {
- /* beginning given, but no size, pad to the and of the device */
- info->end = info->device->size - 1;
- info->size = info->end - info->start + 1;
- goto out;
- }
+ if (!*str) {
+ /* beginning given, but no size, assume maximum size */
+ *size = ~0;
+ return 0;
+ }
if (*str == '-') {
/* beginning and end given */
- info->end = strtoul_suffix(str + 1, NULL, 0);
- info->size = info->end - info->start + 1;
- if (info->end < info->start) {
- printf("end < start\n");
- return -1;
- }
- info->flags = MEMAREA_SIZE_SPECIFIED;
- goto out;
+ *size = strtoul_suffix(str + 1, NULL, 0) + 1;
+ return 0;
}
if (*str == '+') {
/* beginning and size given */
- info->size = strtoul_suffix(str + 1, NULL, 0);
- info->end = info->start + info->size - 1;
- info->flags = MEMAREA_SIZE_SPECIFIED;
- goto out;
+ *size = strtoul_suffix(str + 1, NULL, 0);
+ return 0;
}
-out:
- /* check for device boundaries */
- if (info->end > info->device->size) {
- info->end = info->device->size - 1;
- info->size = info->end - info->start + 1;
- }
-#if 0
- printf("start: 0x%08x\n",info->start);
- printf("size: 0x%08x\n",info->size);
- printf("end: 0x%08x\n",info->end);
-#endif
- return 0;
+ return -1;
+}
+int spec_str_to_info(const char *str, struct memarea_info *info)
+{
+ char *endp;
+
+ info->device = device_from_spec_str(str, &endp);
+ if (!info->device) {
+ printf("unknown device: %s\n", deviceid_from_spec_str(str, NULL));
+ return -ENODEV;
+ }
+
+ return parse_area_spec(endp, &info->start, &info->size);
}
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
diff --git a/net/tftp.c b/net/tftp.c
index e58b38030d..2de87385eb 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -9,6 +9,7 @@
#include <net.h>
#include <driver.h>
#include <clock.h>
+#include <fs.h>
#include "tftp.h"
#include "bootp.h"
@@ -57,7 +58,7 @@ static int TftpState;
static char default_filename[DEFAULT_NAME_LEN];
static char *tftp_filename;
-extern struct memarea_info net_store_mem;
+extern int net_store_fd;
static __inline__ void
store_block (unsigned block, uchar * src, unsigned len)
@@ -65,7 +66,7 @@ store_block (unsigned block, uchar * src, unsigned len)
ulong offset = block * TFTP_BLOCK_SIZE + TftpBlockWrapOffset;
ulong newsize = offset + len;
- dev_write(net_store_mem.device, src, len, net_store_mem.start + offset, 0);
+ write(net_store_fd, src, len);
if (NetBootFileXferSize < newsize)
NetBootFileXferSize = newsize;