From 112ada667b57ec9b9bd1fc0786f5926779cb5b6e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 5 Jul 2007 18:01:38 +0200 Subject: [PATCH] svn_rev_270 WIP FS support --- board/scb9328/scb9328.c | 2 +- common/cmd_bootm.c | 10 +-- common/cmd_flash.c | 9 +-- common/cmd_mem.c | 135 +++++++++++++++++++++++++++------------- common/cmd_net.c | 12 ++-- common/hush.c | 4 +- fs/cramfs/cramfs.c | 2 +- fs/fs.c | 101 +++++++++++++++++++++++------- fs/ramfs.c | 130 ++++++++++++++++++++++++++++++-------- include/driver.h | 4 +- include/fs.h | 16 +++-- lib_generic/misc.c | 123 ++++++++++++++---------------------- net/tftp.c | 5 +- 13 files changed, 358 insertions(+), 195 deletions(-) diff --git a/board/scb9328/scb9328.c b/board/scb9328/scb9328.c index a6092ec59..ec75bf529 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 c3c047fa6..93528510f 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 43c44f281..c1541a80e 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 0a026f6b2..6ce292e42 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #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; - } + fd = open("/dev/mem", O_RDONLY); + if (fd < 0) { + perror("open"); + return 1; + } - 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; - - 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 ((ret = memory_display(rw_buf, start, r, 1))) + goto out; - if (r < now) - return 0; - - 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[]) @@ -491,18 +554,6 @@ U_BOOT_CMD( "[.b, .w, .l] address [# of objects]\n - memory display\n" ); -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", diff --git a/common/cmd_net.c b/common/cmd_net.c index fede091cd..7a2186f06 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include 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 c378f6def..e27520fb8 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 25631a6b7..c8ef7d7ff 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 4ed3e39f4..b43a9e7b3 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,7 +114,47 @@ FILE *get_file(void) void put_file(FILE *f) { - files[f->no].used = 0; + files[f->no].in_use = 0; +} + +static FILE* get_file_by_pathname(const char *pathname) +{ + FILE *f; + + f = get_file(); + if (!f) { + errno = -EMFILE; + return NULL; + } + + if (!strncmp(pathname, "/dev/", 5)) { + 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) @@ -125,16 +165,9 @@ int open(const char *pathname, int flags) FILE *f; int ret; - f = get_file(); - if (!f) { - errno = -EMFILE; - return errno; - } + f = get_file_by_pathname(pathname); - if (!strncmp(pathname, "/dev/", 5)) { - dev = get_device_by_id(pathname + 5); - f->dev = dev; - } else { + 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 d271b27bf..a17315d6f 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -8,33 +8,38 @@ #include #include +#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) +static int ramfs_open(struct device_d *dev, FILE *file, const char *filename) { - return -ENOENT; + 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_read(struct device_d *_dev, FILE *f, void *buf, size_t size) +{ + 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 a37a7cd0b..22860f258 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 @@ -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 22e5fcf07..502a70d59 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 92a8374a1..2aac78f21 100644 --- a/lib_generic/misc.c +++ b/lib_generic/misc.c @@ -7,6 +7,7 @@ #include #include #include +#include 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 beginning given but end, so start is 0 */ + *start = 0; + *size = strtoul_suffix(str + 1, &endp, 0) + 1; + return 0; + } - if (!*str) { - /* no area specification given, use whole device */ - info->size = info->device->size; - info->end = info->size - 1; - goto out; - } + *start = strtoul_suffix(str, &endp, 0); - 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; - } + str = endp; - 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; - } - - str = endp; - info->start = strtoul_suffix(str, &endp, 0); - 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 e58b38030..2de87385e 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -9,6 +9,7 @@ #include #include #include +#include #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;