summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--board/pcm037/pcm037.c8
-rw-r--r--board/pcm038/pcm038.c20
-rw-r--r--board/scb9328/scb9328.c14
-rw-r--r--commands/mem.c67
-rw-r--r--commands/nand.c144
-rwxr-xr-xcommands/partition.c195
-rw-r--r--common/Makefile1
-rw-r--r--common/partition.c358
-rw-r--r--common/startup.c8
-rw-r--r--drivers/nand/nand.c69
-rw-r--r--drivers/net/miiphy.c52
-rw-r--r--drivers/nor/cfi_flash.c64
-rw-r--r--drivers/nor/cfi_flash_new.c62
-rw-r--r--drivers/spi/mc13783.c13
-rw-r--r--fs/devfs.c230
-rw-r--r--fs/fs.c27
-rw-r--r--include/cfi_flash.h1
-rw-r--r--include/cfi_flash_new.h1
-rw-r--r--include/driver.h85
-rw-r--r--include/linux/mtd/mtd.h3
-rw-r--r--include/miiphy.h1
-rw-r--r--include/nand.h4
-rw-r--r--include/partition.h14
-rw-r--r--lib/driver.c94
24 files changed, 597 insertions, 938 deletions
diff --git a/board/pcm037/pcm037.c b/board/pcm037/pcm037.c
index b1691e8fde..b0160b1e11 100644
--- a/board/pcm037/pcm037.c
+++ b/board/pcm037/pcm037.c
@@ -43,7 +43,6 @@
*/
static struct device_d cfi_dev = {
.name = "cfi_flash",
- .id = "nor0",
.map_base = IMX_CS0_BASE,
.size = 32 * 1024 * 1024, /* area size */
};
@@ -245,10 +244,9 @@ static int imx31_devices_init(void)
* Create partitions that should be
* not touched by any regular user
*/
-#ifdef CONFIG_PARTITION
- dev_add_partition(&cfi_dev, 0x00000, 0x40000, PARTITION_FIXED, "self"); /* ourself */
- dev_add_partition(&cfi_dev, 0x40000, 0x20000, PARTITION_FIXED, "env"); /* environment */
-#endif
+ devfs_add_partition("nor0", 0x00000, 0x40000, PARTITION_FIXED, "self0"); /* ourself */
+ devfs_add_partition("nor0", 0x40000, 0x20000, PARTITION_FIXED, "env0"); /* environment */
+
dev_protect(&cfi_dev, 0x20000, 0, 1);
register_device(&sram_dev);
diff --git a/board/pcm038/pcm038.c b/board/pcm038/pcm038.c
index 2270be7b62..375270b2e1 100644
--- a/board/pcm038/pcm038.c
+++ b/board/pcm038/pcm038.c
@@ -111,9 +111,9 @@ static struct device_d nand_dev = {
static int pcm038_devices_init(void)
{
- struct device_d *nand, *dev;
- char *envdev = "no";
int i;
+ struct device_d *nand;
+ char *envdev = "no";
unsigned int mode[] = {
PD0_AIN_FEC_TXD0,
@@ -192,20 +192,16 @@ static int pcm038_devices_init(void)
nand = get_device_by_path("/dev/nand0");
if (!nand)
break;
- dev = dev_add_partition(nand, 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
- if (!dev)
- break;
- dev_add_bb_dev(dev, "self0");
+ devfs_add_partition("nand0", 0x00000, 0x40000, PARTITION_FIXED, "self_raw");
+ dev_add_bb_dev("self_raw", "self0");
- dev = dev_add_partition(nand, 0x40000, 0x20000, PARTITION_FIXED, "env_raw");
- if (!dev)
- break;
- dev_add_bb_dev(dev, "env0");
+ devfs_add_partition("nand0", 0x40000, 0x20000, PARTITION_FIXED, "env_raw");
+ dev_add_bb_dev("env_raw", "env0");
envdev = "NAND";
break;
default:
- dev_add_partition(&cfi_dev, 0x00000, 0x40000, PARTITION_FIXED, "self");
- dev_add_partition(&cfi_dev, 0x40000, 0x20000, PARTITION_FIXED, "env");
+ devfs_add_partition("nor0", 0x00000, 0x40000, PARTITION_FIXED, "self0");
+ devfs_add_partition("nor0", 0x40000, 0x20000, PARTITION_FIXED, "env0");
dev_protect(&cfi_dev, 0x40000, 0, 1);
envdev = "NOR";
}
diff --git a/board/scb9328/scb9328.c b/board/scb9328/scb9328.c
index 9e54902838..253ca3af31 100644
--- a/board/scb9328/scb9328.c
+++ b/board/scb9328/scb9328.c
@@ -35,20 +35,24 @@
static struct device_d cfi_dev = {
.name = "cfi_flash",
- .id = "nor0",
.map_base = 0x10000000,
.size = 16 * 1024 * 1024,
};
+static struct memory_platform_data sdram_pdata = {
+ .name = "ram0",
+ .flags = DEVFS_RDWR,
+};
+
static struct device_d sdram_dev = {
- .name = "ram",
- .id = "ram0",
+ .name = "mem",
.map_base = 0x08000000,
.size = 16 * 1024 * 1024,
.type = DEVICE_TYPE_DRAM,
+ .platform_data = &sdram_pdata,
};
static struct dm9000_platform_data dm9000_data = {
@@ -93,8 +97,8 @@ static int scb9328_devices_init(void) {
register_device(&sdram_dev);
register_device(&dm9000_dev);
- dev_add_partition(&cfi_dev, 0x00000, 0x20000, PARTITION_FIXED, "self");
- dev_add_partition(&cfi_dev, 0x40000, 0x20000, PARTITION_FIXED, "env");
+ devfs_add_partition("nor0", 0x00000, 0x20000, PARTITION_FIXED, "self0");
+ devfs_add_partition("nor0", 0x40000, 0x20000, PARTITION_FIXED, "env0");
dev_protect(&cfi_dev, 0x20000, 0, 1);
armlinux_set_bootparams((void *)0x08000100);
diff --git a/commands/mem.c b/commands/mem.c
index fae53156fb..ee09ed0303 100644
--- a/commands/mem.c
+++ b/commands/mem.c
@@ -518,44 +518,46 @@ U_BOOT_CMD_START(memcpy)
U_BOOT_CMD_HELP(cmd_memcpy_help)
U_BOOT_CMD_END
-static struct device_d mem_dev = {
- .name = "mem",
- .id = "mem",
- .map_base = 0,
- .size = ~0, /* FIXME: should be 0x100000000, ahem... */
+static struct file_operations memops = {
+ .read = mem_read,
+ .write = mem_write,
+ .memmap = generic_memmap_rw,
+ .lseek = dev_lseek_default,
};
+static int mem_probe(struct device_d *dev)
+{
+ struct memory_platform_data *pdata = dev->platform_data;
+ struct cdev *cdev;
+
+ cdev = xzalloc(sizeof (*cdev));
+ dev->priv = cdev;
+
+ cdev->name = pdata->name;
+ cdev->size = dev->size;
+ cdev->ops = &memops;
+ cdev->dev = dev;
+
+ devfs_create(cdev);
+
+ return 0;
+}
+
static struct driver_d mem_drv = {
.name = "mem",
- .probe = dummy_probe,
- .open = dev_open_default,
- .close = dev_close_default,
- .read = mem_read,
- .write = mem_write,
- .memmap = mem_memmap,
- .lseek = dev_lseek_default,
+ .probe = mem_probe,
};
-static struct driver_d ram_drv = {
- .name = "ram",
- .probe = dummy_probe,
- .open = dev_open_default,
- .close = dev_close_default,
- .read = mem_read,
- .write = mem_write,
- .lseek = dev_lseek_default,
- .memmap = mem_memmap,
- .type = DEVICE_TYPE_DRAM,
+static struct memory_platform_data mem_dev_pdata = {
+ .name = "mem",
+ .flags = DEVFS_RDWR,
};
-static struct driver_d rom_drv = {
- .name = "rom",
- .probe = dummy_probe,
- .open = dev_open_default,
- .close = dev_close_default,
- .read = mem_read,
- .memmap = mem_memmap,
- .lseek = dev_lseek_default,
+static struct device_d mem_dev = {
+ .name = "mem",
+ .map_base = 0,
+ .size = ~0, /* FIXME: should be 0x100000000, ahem... */
+ .platform_data = &mem_dev_pdata,
};
static int mem_init(void)
@@ -566,10 +568,9 @@ static int mem_init(void)
return -1;
}
- register_device(&mem_dev);
register_driver(&mem_drv);
- register_driver(&ram_drv);
- register_driver(&rom_drv);
+ register_device(&mem_dev);
+
return 0;
}
diff --git a/commands/nand.c b/commands/nand.c
index 7bcb0a4e35..9776443829 100644
--- a/commands/nand.c
+++ b/commands/nand.c
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
#include <common.h>
#include <command.h>
#include <fs.h>
@@ -31,40 +30,45 @@
#include <nand.h>
#include <linux/mtd/mtd-abi.h>
#include <fcntl.h>
+#include <libgen.h>
struct nand_bb {
- struct device_d device;
-
- struct device_d *physdev;
-
+ char *devname;
+ char *name;
int open;
struct mtd_info_user info;
+ size_t raw_size;
+ size_t size;
+ int fd;
off_t offset;
+
+ struct cdev cdev;
};
-static ssize_t nand_bb_read(struct device_d *dev, void *buf, size_t count,
+static ssize_t nand_bb_read(struct cdev *cdev, void *buf, size_t count,
unsigned long offset, ulong flags)
{
- struct nand_bb *bb = dev->priv;
+ struct nand_bb *bb = cdev->priv;
int ret, bytes = 0, now;
debug("%s %d %d\n", __func__, offset, count);
while(count) {
- ret = dev_ioctl(bb->physdev, MEMGETBADBLOCK, (void *)bb->offset);
+ ret = ioctl(bb->fd, MEMGETBADBLOCK, (void *)bb->offset);
if (ret < 0)
return ret;
if (ret) {
- debug("skipping bad block at 0x%08x\n", bb->offset);
+ printf("skipping bad block at 0x%08x\n", bb->offset);
bb->offset += bb->info.erasesize;
}
now = min(count, (size_t)(bb->info.erasesize -
(bb->offset % bb->info.erasesize)));
- ret = dev_read(bb->physdev, buf, now, bb->offset, flags);
+ lseek(bb->fd, bb->offset, SEEK_SET);
+ ret = read(bb->fd, buf, now);
if (ret < 0)
return ret;
buf += now;
@@ -76,16 +80,16 @@ static ssize_t nand_bb_read(struct device_d *dev, void *buf, size_t count,
return bytes;
}
-static ssize_t nand_bb_write(struct device_d *dev, const void *buf, size_t count,
+static ssize_t nand_bb_write(struct cdev *cdev, const void *buf, size_t count,
unsigned long offset, ulong flags)
{
- struct nand_bb *bb = dev->priv;
+ struct nand_bb *bb = cdev->priv;
int ret, bytes = 0, now;
- debug("%s %d %d\n", __func__, offset, count);
+ debug("%s offset: 0x%08x count: 0x%08x\n", __func__, offset, count);
while(count) {
- ret = dev_ioctl(bb->physdev, MEMGETBADBLOCK, (void *)bb->offset);
+ ret = ioctl(bb->fd, MEMGETBADBLOCK, (void *)bb->offset);
if (ret < 0)
return ret;
@@ -96,7 +100,8 @@ static ssize_t nand_bb_write(struct device_d *dev, const void *buf, size_t count
now = min(count, (size_t)(bb->info.erasesize -
(bb->offset % bb->info.erasesize)));
- ret = dev_write(bb->physdev, buf, now, bb->offset, flags);
+ lseek(bb->fd, offset, SEEK_SET);
+ ret = write(bb->fd, buf, now);
if (ret < 0)
return ret;
buf += now;
@@ -108,21 +113,21 @@ static ssize_t nand_bb_write(struct device_d *dev, const void *buf, size_t count
return bytes;
}
-static int nand_bb_erase(struct device_d *dev, size_t count, unsigned long offset)
+static int nand_bb_erase(struct cdev *cdev, size_t count, unsigned long offset)
{
- struct nand_bb *bb = dev->priv;
+ struct nand_bb *bb = cdev->priv;
- if (offset != 0 || count != dev->size) {
+ if (offset != 0 || count != bb->raw_size) {
printf("can only erase whole device\n");
return -EINVAL;
}
- return dev_erase(bb->physdev, dev->size, 0);
+ return erase(bb->fd, bb->raw_size, 0);
}
-static int nand_bb_open(struct device_d *dev, struct filep *f)
+static int nand_bb_open(struct cdev *cdev, struct filep *f)
{
- struct nand_bb *bb = dev->priv;
+ struct nand_bb *bb = cdev->priv;
if (bb->open)
return -EBUSY;
@@ -133,9 +138,9 @@ static int nand_bb_open(struct device_d *dev, struct filep *f)
return 0;
}
-static int nand_bb_close(struct device_d *dev, struct filep *f)
+static int nand_bb_close(struct cdev *cdev, struct filep *f)
{
- struct nand_bb *bb = dev->priv;
+ struct nand_bb *bb = cdev->priv;
bb->open = 0;
@@ -147,12 +152,12 @@ static int nand_bb_calc_size(struct nand_bb *bb)
ulong pos = 0;
int ret;
- while (pos < bb->physdev->size) {
- ret = dev_ioctl(bb->physdev, MEMGETBADBLOCK, (void *)pos);
+ while (pos < bb->raw_size) {
+ ret = ioctl(bb->fd, MEMGETBADBLOCK, (void *)pos);
if (ret < 0)
return ret;
if (!ret)
- bb->device.size += bb->info.erasesize;
+ bb->cdev.size += bb->info.erasesize;
pos += bb->info.erasesize;
}
@@ -160,79 +165,67 @@ static int nand_bb_calc_size(struct nand_bb *bb)
return 0;
}
-static int nand_bb_probe(struct device_d *dev)
-{
- struct nand_bb *bb = dev->priv;
- int ret;
-
- ret = dev_ioctl(bb->physdev, MEMGETINFO, &bb->info);
- if (ret)
- return ret;
- return nand_bb_calc_size(bb);
-}
-
-static void nand_bb_remove(struct device_d *dev)
-{
-}
-
-struct driver_d nand_bb_driver = {
- .name = "nand_bb",
- .probe = nand_bb_probe,
- .remove = nand_bb_remove,
+static struct file_operations nand_bb_ops = {
.open = nand_bb_open,
.close = nand_bb_close,
.read = nand_bb_read,
.write = nand_bb_write,
.erase = nand_bb_erase,
- .type = DEVICE_TYPE_NAND_BB,
};
-static int nand_bb_init(void)
-{
- return register_driver(&nand_bb_driver);
-}
-
-device_initcall(nand_bb_init);
-
/**
* Add a bad block aware device ontop of another (NAND) device
* @param[in] dev The device to add a partition on
* @param[in] name Partition name (can be obtained with devinfo command)
* @return The device representing the new partition.
*/
-struct device_d *dev_add_bb_dev(struct device_d *dev, const char *name)
+int dev_add_bb_dev(char *path, const char *name)
{
struct nand_bb *bb;
+ int ret;
+ struct stat s;
bb = xzalloc(sizeof(*bb));
-
+ bb->devname = asprintf("/dev/%s", basename(path));
if (name)
- strcpy(bb->device.id, name);
+ bb->cdev.name = strdup(name);
else
- sprintf(bb->device.id, "%s.bb", dev->id);
- strcpy(bb->device.name, "nand_bb");
- bb->device.priv = bb;
- bb->device.size = 0;
- bb->device.type = DEVICE_TYPE_NAND_BB;
- bb->physdev = dev;
-
- if (register_device(&bb->device))
+ bb->cdev.name = asprintf("%s.bb", basename(path));
+
+ ret = stat(bb->devname, &s);
+ if (ret)
+ goto free_out;
+
+ bb->raw_size = s.st_size;
+
+ bb->fd = open(bb->devname, O_RDWR);
+ if (bb->fd < 0) {
+ ret = -ENODEV;
+ goto free_out;
+ }
+
+ ret = ioctl(bb->fd, MEMGETINFO, &bb->info);
+ if (ret)
goto free_out;
- dev_add_child(dev, &bb->device);
+ nand_bb_calc_size(bb);
+ bb->cdev.ops = &nand_bb_ops;
+ bb->cdev.priv = bb;
- return &bb->device;
+ devfs_create(&bb->cdev);
+
+ return 0;
free_out:
free(bb);
- return 0;
+ return ret;
}
#define NAND_ADD (1 << 0)
#define NAND_DEL (1 << 1)
#define NAND_MARKBAD (1 << 2)
-static int do_nand (cmd_tbl_t *cmdtp, int argc, char *argv[])
+static int do_nand(cmd_tbl_t *cmdtp, int argc, char *argv[])
{
int opt;
struct device_d *dev;
@@ -262,13 +255,7 @@ static int do_nand (cmd_tbl_t *cmdtp, int argc, char *argv[])
if (command & NAND_ADD) {
while (optind < argc) {
- dev = get_device_by_path(argv[optind]);
- if (!dev) {
- printf("no such device: %s\n", argv[optind]);
- return 1;
- }
-
- if (!dev_add_bb_dev(dev, NULL))
+ if (dev_add_bb_dev(argv[optind], NULL))
return 1;
optind++;
@@ -277,17 +264,20 @@ static int do_nand (cmd_tbl_t *cmdtp, int argc, char *argv[])
if (command & NAND_DEL) {
while (optind < argc) {
- dev = get_device_by_path(argv[optind]);
- if (!dev) {
+ struct cdev *cdev;
+ cdev = cdev_by_name(basename(argv[optind]));
+ if (!cdev) {
printf("no such device: %s\n", argv[optind]);
return 1;
}
+ dev = cdev->dev;
if (dev->type != DEVICE_TYPE_NAND_BB) {
printf("not a nand bb device: %s\n", dev);
return 1;
}
bb = dev->priv;
+ close(bb->fd);
unregister_device(dev);
free(bb);
optind++;
diff --git a/commands/partition.c b/commands/partition.c
index 9303987f2a..30f7407175 100755
--- a/commands/partition.c
+++ b/commands/partition.c
@@ -37,99 +37,29 @@
#include <partition.h>
#include <errno.h>
#include <xfuncs.h>
+#include <fs.h>
+#include <linux/stat.h>
+#include <libgen.h>
-static int dev_del_partitions(struct device_d *physdev)
-{
- struct device_d *child, *tmp;
- struct partition *part;
- int ret;
-
- device_for_each_child_safe(physdev, tmp, child) {
- if (child->type != DEVICE_TYPE_PARTITION) {
- printf("not a partition: %s\n", child->id);
- continue;
- }
-
- part = child->type_data;
-
- if (part->flags & PARTITION_FIXED) {
- debug("Skip fixed partition: %s\n", child->id);
- continue;
- }
-
- ret = unregister_device(child);
- if (ret) {
- printf("delete partition `%s' failed: %s\n", child->id, errno_str());
- return errno;
- }
-
- debug("deleted partition: %s\n", child->id);
-
- free(part);
- }
-
- return 0;
-}
-
-static int dev_check_fixed(struct device_d *physdev, struct partition *new_part)
-{
- struct device_d *child;
-
- device_for_each_child(physdev, child) {
- struct partition *part = child->type_data;
-
- debug("check aginst partition: %s -", child->id);
-
- if (!(part->flags & PARTITION_FIXED)) {
- debug(" not fixed, ok\n");
- continue;
- }
-
- if (new_part->offset == part->offset && /* new_part is exactly part */
- ((new_part->device.size==0) || (new_part->device.size == part->device.size)) ) {
- debug(" fixed, but same size, ok\n");
- continue;
- }
-
- if ((new_part->offset >= part->offset &&
- new_part->offset < part->offset + part->device.size) ||
- (new_part->offset + new_part->device.size > part->offset &&
- new_part->offset + new_part->device.size <= part->offset + part->device.size)) {
- printf(
- " failed\n"
- " partition spec %s \n"
- " violates fixed partition %s\n", new_part->name, child->id);
- errno = -EINVAL;
- return errno;
- }
- else
- debug(" fixed and within limit?, ok\n");
- }
-
- return 0;
-}
-
-static int mtd_part_do_parse_one(struct partition *part, const char *partstr,
- char **endp)
+static int mtd_part_do_parse_one(char *devname, const char *partstr,
+ char **endp, unsigned long offset,
+ off_t devsize, size_t *retsize)
{
ulong size;
char *end;
- char buf[MAX_DRIVER_NAME];
+ char buf[PATH_MAX];
+ unsigned long flags = 0;
+ int ret;
- memset(buf, 0, MAX_DRIVER_NAME);
+ memset(buf, 0, PATH_MAX);
if (*partstr == '-') {
- size = part->physdev->size - part->offset;
+ size = devsize - offset;
end = (char *)partstr + 1;
} else {
size = strtoul_suffix(partstr, &end, 0);
}
- if (size + part->offset > part->physdev->size) {
- printf("partition %s end is beyond device\n", part->name);
- return -EINVAL;
- }
-
partstr = end;
if (*partstr == '(') {
@@ -139,98 +69,78 @@ static int mtd_part_do_parse_one(struct partition *part, const char *partstr,
printf("could not find matching ')'\n");
return -EINVAL;
}
- if (end - partstr >= MAX_DRIVER_NAME) {
- printf("device name too long\n");
- return -EINVAL;
- }
- memcpy(part->name, partstr, end - partstr);
+ sprintf(buf, "%s.", devname);
+ memcpy(buf + strlen(buf), partstr, end - partstr);
+
end++;
}
+ if (size + offset > devsize) {
+ printf("%s: partition end is beyond device\n", buf);
+ return -EINVAL;
+ }
+
partstr = end;
if (*partstr == 'r' && *(partstr + 1) == 'o') {
- part->flags |= PARTITION_READONLY;
+ flags |= PARTITION_READONLY;
end = (char *)(partstr + 2);
}
if (endp)
*endp = end;
- strcpy(part->device.name, "partition");
- part->device.size = size;
+ *retsize = size;
- return 0;
+ ret = devfs_add_partition(devname, offset, size, flags, buf);
+ if (ret)
+ printf("cannot create %s: %s\n", buf, strerror(-ret));
+ return ret;
}
static int do_addpart(cmd_tbl_t * cmdtp, int argc, char *argv[])
{
- struct partition *part;
- struct device_d *dev;
+ char *devname;
char *endp;
- int num = 0;
- unsigned long offset;
+ unsigned long offset = 0;
+ off_t devsize;
+ struct stat s;
if (argc != 3) {
printf("Usage:\n %s\n", cmdtp->usage);
return 1;
}
- dev = get_device_by_path(argv[1]);
- if (!dev) {
- printf("no such device: %s\n", argv[1]);
+ if (stat(argv[1], &s)) {
+ perror("addpart");
return 1;
}
+ devsize = s.st_size;
- dev_del_partitions(dev);
-
- offset = 0;
+ devname = basename(argv[1]);
endp = argv[2];
while (1) {
- part = xzalloc(sizeof(struct partition));
-
- part->offset = offset;
- part->physdev = dev;
- part->num = num;
- part->device.map_base = dev->map_base + offset;
- part->device.type_data = part;
- part->device.type = DEVICE_TYPE_PARTITION;
+ size_t size = 0;
- if (mtd_part_do_parse_one(part, endp, &endp))
- goto free_out;
+ if (mtd_part_do_parse_one(devname, endp, &endp, offset, devsize, &size))
+ return 1;
- if (dev_check_fixed(dev, part))
- goto free_out;
-
- sprintf(part->device.id, "%s.%s", dev->id, part->name);
- if (register_device(&part->device))
- goto free_out;
-
- dev_add_child(dev, &part->device);
-
- offset += part->device.size;
- num++;
+ offset += size;
if (!*endp)
break;
if (*endp != ',') {
printf("parse error\n");
- goto err_out;
+ return 1;
}
endp++;
}
return 0;
-
-free_out:
- free(part);
-err_out:
- dev_del_partitions(dev);
- return 1;
}
static const __maybe_unused char cmd_addpart_help[] =
@@ -275,38 +185,33 @@ U_BOOT_CMD_END
static int do_delpart(cmd_tbl_t * cmdtp, int argc, char *argv[])
{
- struct device_d *dev;
-
- if (argc != 2) {
- printf("Usage:\n%s\n", cmdtp->usage);
- return 1;
- }
+ int i, err;
- dev = get_device_by_path(argv[1]);
- if (!dev) {
- printf("no such device: %s\n", argv[1]);
- return 1;
+ for (i = 1; i < argc; i++) {
+ err = devfs_del_partition(basename(argv[i]));
+ if (err) {
+ printf("cannot delete %s: %s\n", argv[i], strerror(-err));
+ break;
+ }
}
- dev_del_partitions(dev);
-
- return 0;
+ return 1;
}
static const __maybe_unused char cmd_delpart_help[] =
-"Usage: delpart <device>\n"
+"Usage: delpart FILE...\n"
"Delete partitions previously added to a device with addpart.\n";
U_BOOT_CMD_START(delpart)
- .maxargs = 2,
+ .maxargs = CONFIG_MAXARGS,
.cmd = do_delpart,
- .usage = "delete a partition table from a device",
+ .usage = "delete partition(s)",
U_BOOT_CMD_HELP(cmd_delpart_help)
U_BOOT_CMD_END
/** @page delpart_command delpart Delete a partition
*
- * Usage is: delpart \<device>
+ * Usage is: delpart \<partions>
*
* Delete a partition previously added to a device with addpart.
*/
diff --git a/common/Makefile b/common/Makefile
index f0555a628e..e6e2efb382 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -12,7 +12,6 @@ obj-y += clock.o
obj-y += command.o
obj-$(CONFIG_CONSOLE_FULL) += console.o
obj-$(CONFIG_CONSOLE_SIMPLE) += console_simple.o
-obj-$(CONFIG_PARTITION) += partition.o
obj-y += env.o
obj-y += startup.o
obj-y += misc.o
diff --git a/common/partition.c b/common/partition.c
deleted file mode 100644
index d374e6c031..0000000000
--- a/common/partition.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * (C) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/**
- * @file
- * @brief Partition handling on top of devices
- */
-
-#include <common.h>
-#include <init.h>
-#include <driver.h>
-#include <malloc.h>
-#include <errno.h>
-#include <partition.h>
-#include <xfuncs.h>
-#include <ioctl.h>
-#include <nand.h>
-#include <linux/mtd/mtd-abi.h>
-
-/**
- * Add one partition on top of a device, as a device.
- * @param[in] dev The device to add a partition on
- * @param[in] offset Start offset of the partition inside the whole device
- * @param[in] size Size of the new partition
- * @param[in] flags FIXME
- * @param[in] name Partition name (can be obtained with devinfo command)
- * @return The device representing the new partition.
- */
-struct device_d *dev_add_partition(struct device_d *dev, unsigned long offset,
- size_t size, int flags, const char *name)
-{
- struct partition *part;
-
- if (offset + size > dev->size)
- return NULL;
-
- part = xzalloc(sizeof(struct partition));
-
- strcpy(part->device.name, "partition");
- part->device.map_base = dev->map_base + offset;
- part->device.size = size;
- part->device.type_data = part;
- part->device.type = DEVICE_TYPE_PARTITION;
- get_free_deviceid(part->device.id, name);
-
- part->offset = offset;
- part->physdev = dev;
- part->flags = flags;
-
- register_device(&part->device);
- dev_add_child(dev, &part->device);
-
- if (part->device.driver)
- return &part->device;
-
- unregister_device(&part->device);
- free(part);
- return 0;
-}
-
-/**
- * Erase partition content.
- * @param[in] dev The partition info as a device
- * @param[in] count Length in bytes to erase
- * @param[in] offset Start offset within the partition
- * @return -1 if no erase feature for this device is available, anything else
- * the erase function returns.
- */
-static int part_erase(struct device_d *dev, size_t count, unsigned long offset)
-{
- struct partition *part = dev->type_data;
-
- if (part->flags & PARTITION_READONLY)
- return -EROFS;
-
- return dev_erase(part->physdev, count, offset + part->offset);
-}
-
-/**
- * Protecting a partition.
- * @param[in] dev The partition info as a device
- * @param[in] count Length in bytes to protect
- * @param[in] offset Start offset within the partition
- * @param[in] prot FIXME
- * @return -1 if FIXME.
- */
-static int part_protect(struct device_d *dev, size_t count, unsigned long offset, int prot)
-{
- struct partition *part = dev->type_data;
-
- return dev_protect(part->physdev, count, offset + part->offset, prot);
-}
-
-/**
- * FIXME.
- * @param[in] dev The partition info as a device
- * @param[in] map FXIME
- * @param[in] flags FIXME
- * @return -1 if FIXME.
- */
-static int part_memmap(struct device_d *dev, void **map, int flags)
-{
- struct partition *part = dev->type_data;
- int ret;
-
- if (part->physdev->driver->memmap) {
- ret = part->physdev->driver->memmap(part->physdev, map, flags);
- if (ret)
- return ret;
- *map = (void *)((unsigned long)*map + part->offset);
- return 0;
- }
-
- return -ENOSYS;
-}
-
-/**
- * FIXME.
- * @param[in] dev The partition info as a device
- * @param[in] buf FXIME
- * @param[in] count FXIME
- * @param[in] offset FXIME
- * @param[in] flags FIXME
- * @return FIXME.
- */
-static ssize_t part_read(struct device_d *dev, void *buf, size_t count,
- unsigned long offset, ulong flags)
-{
- struct partition *part = dev->type_data;
-
- return dev_read(part->physdev, buf, count, offset + part->offset, flags);
-}
-
-/**
- * FIXME.
- * @param[in] dev The partition info as a device
- * @param[in] buf FXIME
- * @param[in] count FXIME
- * @param[in] offset FXIME
- * @param[in] flags FIXME
- * @return FIXME.
- */
-static ssize_t part_write(struct device_d *dev, const void *buf, size_t count,
- unsigned long offset, ulong flags)
-{
- struct partition *part = dev->type_data;
-
- if (part->flags & PARTITION_READONLY)
- return -EROFS;
- else
- return dev_write(part->physdev, buf, count, offset + part->offset, flags);
-}
-
-static off_t part_lseek(struct device_d *dev, off_t ofs)
-{
- struct partition *part = dev->type_data;
-
- return dev_lseek(part->physdev, ofs);
-}
-
-static int part_open(struct device_d *dev, struct filep *f)
-{
- struct partition *part = dev->type_data;
-
- return dev_open(part->physdev, f);
-}
-
-static int part_close(struct device_d *dev, struct filep *f)
-{
- struct partition *part = dev->type_data;
-
- return dev_close(part->physdev, f);
-}
-
-static int part_ioctl(struct device_d *dev, int request,
- void *buf)
-{
- struct partition *part = dev->type_data;
- off_t offset;
-
- switch (request) {
- case MEMSETBADBLOCK:
- case MEMGETBADBLOCK:
- offset = (off_t)buf;
- offset += part->offset;
- return dev_ioctl(part->physdev, request, (void *)offset);
- case MEMGETINFO:
- return dev_ioctl(part->physdev, request, buf);
- }
-
- return -ENOSYS;
-}
-
-/**
- * FIXME.
- * @param[in] dev The partition info as a device
- * @return FIXME.
- */
-static int part_probe(struct device_d *dev)
-{
-#ifdef DEBUG
- struct partition *part = dev->type_data;
-#endif
-
- debug("registering partition %s on device %s (size=0x%08x, name=%s)\n",
- dev->id, part->physdev->id, dev->size, part->name);
- return 0;
-}
-
-/**
- * FIXME.
- * @param[in] dev The partition info as a device
- */
-static void part_remove(struct device_d *dev)
-{
-}
-
-/**
- * Partition driver description
- */
-struct driver_d part_driver = {
- .name = "partition",
- .probe = part_probe,
- .remove = part_remove,
- .open = part_open,
- .close = part_close,
- .ioctl = part_ioctl,
- .read = part_read,
- .write = part_write,
- .lseek = part_lseek,
- .erase = part_erase,
- .protect= part_protect,
- .memmap = part_memmap,
- .type = DEVICE_TYPE_PARTITION,
-};
-
-static int partition_init(void)
-{
- return register_driver(&part_driver);
-}
-
-device_initcall(partition_init);
-
-/**
-@page partitions Partition Handling
-
-Partitions are runtime informartion only, not permanent. So they must be set
-everytime the system starts. The required command can be embedded into the
-default environment.
-
-@note Partitions defined in this way are intended to be used with the kernel
-command line partition parsing feature. In Uboot2 these types of partitions are
-handled in the same way as every other device.
-
-@par The addpart command
-
-What we want:
-
-@verbatim
- device nor0
- |--- partition 0
- |--- partition 1
- |--- partition 2
- |--- partition 3
- `--- partition 4
-@endverbatim
-
-How to get:
-
-@verbatim
-$ addpart /dev/nor0 256k(uboot),128k(env),256k(bla),1024k(blubb),2048k(friesel)
-$ devinfo
- |---nor0.uboot
- |---nor0.env
- |---nor0.bla
- |---nor0.blubb
- |---nor0.friesel
-@endverbatim
-
-@par Partitions with sub partitions:
-
-Partitions are based on devices. And partitions will result into devices. So
-there is a way to create sub partitions on partitions.
-
-What we want:
-
-@verbatim
- device nor0
- |--- partition 0
- |--- partition 1
- |--- partition 2
- |--- partition 3
- `--- partition 4
- |--- partition 0
- `--- partition 1
-@endverbatim
-
-How to get:
-
-@verbatim
-$ addpart /dev/nor0 256k(uboot),128k(env),256k(bla),1M(blubb),2048k(friesel)
-$ devinfo
- |---nor0.uboot
- |---nor0.env
- |---nor0.bla
- |---nor0.blubb
- |---nor0.friesel
-
-$ addpart /dev/nor0.friesel 1024(fussel),1024k(boerks)
-$ devinfo
- |---nor0.uboot
- |---nor0.env
- |---nor0.bla
- |---nor0.blubb
- |---nor0.friesel
- |---nor0.friesel.fussel
- `---nor0.friesel.boerks
-@endverbatim
-
-@par Forwarding partitions to the kernel:
-
-@verbatim
-$ device="nor0"
-$ partitions="256k(uboot),128k(env),256k(bla),1024k(blubb),2048k(friesel)"
-$ addpart /dev/$device:$partitions
-@endverbatim
-
-@par Removing partitions:
-
-As partitions are a logically information only, they can be removed from a
-device at runtime. You can't remove a single partition within others on the
-same device. Only all partitions on the given device can be removed with this
-command.
-
-As sub partitions occure as devices you also can remove sub partitions from
-their parent in this way. Partitions cannot be removed as long as they are
-mounted or have subpartitions.
-
-*/
diff --git a/common/startup.c b/common/startup.c
index 7179f81203..0f67ca43af 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -77,9 +77,13 @@ void early_init (void)
#ifdef CONFIG_DEFAULT_ENVIRONMENT
#include <uboot_default_env.h>
+static struct memory_platform_data default_env_platform_data = {
+ .name = "defaultenv",
+};
+
static struct device_d default_env_dev = {
- .name = "rom",
- .id = "defaultenv",
+ .name = "mem",
+ .platform_data = &default_env_platform_data,
};
static void register_default_env(void)
diff --git a/drivers/nand/nand.c b/drivers/nand/nand.c
index 399d0ad86a..5f5e83a841 100644
--- a/drivers/nand/nand.c
+++ b/drivers/nand/nand.c
@@ -20,7 +20,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-
#include <common.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/mtd.h>
@@ -31,9 +30,9 @@
#include <ioctl.h>
#include <nand.h>
-static ssize_t nand_read(struct device_d *dev, void* buf, size_t count, ulong offset, ulong flags)
+static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count, ulong offset, ulong flags)
{
- struct mtd_info *info = dev->priv;
+ struct mtd_info *info = cdev->priv;
size_t retlen;
int ret;
@@ -41,16 +40,18 @@ static ssize_t nand_read(struct device_d *dev, void* buf, size_t count, ulong o
ret = info->read(info, offset, count, &retlen, buf);
- if(ret)
+ if(ret) {
+ printf("err %d\n", ret);
return ret;
+ }
return retlen;
}
#define NOTALIGNED(x) (x & (info->writesize - 1)) != 0
-static ssize_t nand_write(struct device_d* dev, const void* buf, size_t _count, ulong offset, ulong flags)
+static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count, ulong offset, ulong flags)
{
- struct mtd_info *info = dev->priv;
+ struct mtd_info *info = cdev->priv;
size_t retlen, now;
int ret;
void *wrbuf = NULL;
@@ -86,9 +87,9 @@ out:
return ret ? ret : _count;
}
-static int nand_ioctl(struct device_d *dev, int request, void *buf)
+static int nand_ioctl(struct cdev *cdev, int request, void *buf)
{
- struct mtd_info *info = dev->priv;
+ struct mtd_info *info = cdev->priv;
struct mtd_info_user *user = buf;
switch (request) {
@@ -113,9 +114,9 @@ static int nand_ioctl(struct device_d *dev, int request, void *buf)
return 0;
}
-static ssize_t nand_erase(struct device_d *dev, size_t count, unsigned long offset)
+static ssize_t nand_erase(struct cdev *cdev, size_t count, unsigned long offset)
{
- struct mtd_info *info = dev->priv;
+ struct mtd_info *info = cdev->priv;
struct erase_info erase;
int ret;
@@ -143,6 +144,14 @@ static ssize_t nand_erase(struct device_d *dev, size_t count, unsigned long offs
return 0;
}
+static struct file_operations nand_ops = {
+ .read = nand_read,
+ .write = nand_write,
+ .ioctl = nand_ioctl,
+ .lseek = dev_lseek_default,
+ .erase = nand_erase,
+};
+
static int nand_device_probe(struct device_d *dev)
{
return 0;
@@ -151,13 +160,6 @@ static int nand_device_probe(struct device_d *dev)
static struct driver_d nand_device_driver = {
.name = "nand_device",
.probe = nand_device_probe,
- .read = nand_read,
- .write = nand_write,
- .ioctl = nand_ioctl,
- .open = dev_open_default,
- .close = dev_close_default,
- .lseek = dev_lseek_default,
- .erase = nand_erase,
.type = DEVICE_TYPE_NAND,
};
@@ -170,36 +172,27 @@ static int nand_init(void)
device_initcall(nand_init);
-int add_mtd_device(struct mtd_info *mtd) {
- struct device_d *dev;
- int ret;
-
- dev = xzalloc(sizeof(*dev));
+int add_mtd_device(struct mtd_info *mtd)
+{
+ struct device_d *dev = &mtd->class_dev;
+ char name[MAX_DRIVER_NAME];
- strcpy(dev->name, "nand_device");
- get_free_deviceid(dev->id, "nand");
+ get_free_deviceid(name, "nand");
- dev->size = mtd->size;
- dev->type = DEVICE_TYPE_NAND;
- dev->priv = mtd;
- mtd->dev = dev;
+ mtd->cdev.ops = &nand_ops;
+ mtd->cdev.size = mtd->size;
+ mtd->cdev.name = strdup(name);
+ mtd->cdev.dev = dev;
+ mtd->cdev.priv = mtd;
- ret = register_device(dev);
- if (ret)
- goto out;
+ devfs_create(&mtd->cdev);
return 0;
-
-out:
- free(dev);
- return ret;
}
int del_mtd_device (struct mtd_info *mtd)
{
- unregister_device(mtd->dev);
- free(mtd->dev);
-
+ unregister_device(&mtd->class_dev);
return 0;
}
diff --git a/drivers/net/miiphy.c b/drivers/net/miiphy.c
index ccb274bd0d..b4e6756a93 100644
--- a/drivers/net/miiphy.c
+++ b/drivers/net/miiphy.c
@@ -25,6 +25,7 @@
#include <init.h>
#include <miiphy.h>
#include <clock.h>
+#include <net.h>
int miiphy_restart_aneg(struct miiphy_device *mdev)
{
@@ -84,12 +85,12 @@ int miiphy_wait_aneg(struct miiphy_device *mdev)
start = get_time_ns();
do {
if (is_timeout(start, 5 * SECOND)) {
- printf("%s: Autonegotiation timeout\n", mdev->dev.id);
+ printf("%s: Autonegotiation timeout\n", mdev->cdev.name);
return -1;
}
if (mdev->read(mdev, mdev->address, MII_BMSR, &status)) {
- printf("%s: Autonegotiation failed. status: 0x%04x\n", mdev->dev.id, status);
+ printf("%s: Autonegotiation failed. status: 0x%04x\n", mdev->cdev.name, status);
return -1;
}
} while (!(status & BMSR_LSTATUS));
@@ -115,7 +116,7 @@ int miiphy_print_status(struct miiphy_device *mdev)
if (mdev->read(mdev, mdev->address, MII_LPA, &lpa) != 0)
goto err_out;
- printf("%s: Link is %s", mdev->dev.id,
+ printf("%s: Link is %s", mdev->cdev.name,
bmsr & BMSR_LSTATUS ? "up" : "down");
if (bmcr & BMCR_ANENABLE) {
@@ -130,15 +131,15 @@ int miiphy_print_status(struct miiphy_device *mdev)
return 0;
err_out:
- printf("%s: failed to read\n", mdev->dev.id);
+ printf("%s: failed to read\n", mdev->cdev.name);
return -1;
}
-static ssize_t miiphy_read(struct device_d *dev, void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t miiphy_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
{
int i = count;
uint16_t *buf = _buf;
- struct miiphy_device *mdev = dev->priv;
+ struct miiphy_device *mdev = cdev->priv;
while (i > 1) {
mdev->read(mdev, mdev->address, offset, buf);
@@ -150,11 +151,11 @@ static ssize_t miiphy_read(struct device_d *dev, void *_buf, size_t count, ulong
return count;
}
-static ssize_t miiphy_write(struct device_d *dev, const void *_buf, size_t count, ulong offset, ulong flags)
+static ssize_t miiphy_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
{
int i = count;
const uint16_t *buf = _buf;
- struct miiphy_device *mdev = dev->priv;
+ struct miiphy_device *mdev = cdev->priv;
while (i > 1) {
mdev->write(mdev, mdev->address, offset, *buf);
@@ -166,41 +167,36 @@ static ssize_t miiphy_write(struct device_d *dev, const void *_buf, size_t count
return count;
}
+static struct file_operations miiphy_ops = {
+ .read = miiphy_read,
+ .write = miiphy_write,
+};
+
static int miiphy_probe(struct device_d *dev)
{
+ struct miiphy_device *mdev = dev->priv;
+ char name[MAX_DRIVER_NAME];
+
+ get_free_deviceid(name, "phy");
+ mdev->cdev.name = strdup(name);
+ mdev->cdev.size = 32;
+ mdev->cdev.ops = &miiphy_ops;
+ mdev->cdev.priv = mdev;
+ devfs_create(&mdev->cdev);
return 0;
}
-static void miiphy_remove(struct device_d *dev)
-{
-}
-
int miiphy_register(struct miiphy_device *mdev)
{
- strcpy(mdev->dev.name, "miiphy");
- get_free_deviceid(mdev->dev.id, "phy");
- mdev->dev.type = DEVICE_TYPE_MIIPHY;
mdev->dev.priv = mdev;
- mdev->dev.size = 32;
+ strcpy(mdev->dev.name, "miiphy");
return register_device(&mdev->dev);
}
-void miiphy_unregister(struct miiphy_device *mdev)
-{
- unregister_device(&mdev->dev);
-}
-
static struct driver_d miiphy_drv = {
.name = "miiphy",
.probe = miiphy_probe,
- .remove = miiphy_remove,
- .open = dev_open_default,
- .close = dev_close_default,
- .read = miiphy_read,
- .write = miiphy_write,
- .lseek = dev_lseek_default,
- .type = DEVICE_TYPE_MIIPHY,
};
static int miiphy_init(void)
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 930d4a8504..b38d291415 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -42,6 +42,7 @@
#include <init.h>
#include <malloc.h>
#include <cfi_flash.h>
+#include <errno.h>
#define FLASH_CMD_CFI 0x98
#define FLASH_CMD_READ_ID 0x90
@@ -352,16 +353,16 @@ static int flash_erase_one (flash_info_t * info, long sect)
return rcode;
}
-static int cfi_erase(struct device_d *dev, size_t count, unsigned long offset)
+static int cfi_erase(struct cdev *cdev, size_t count, unsigned long offset)
{
- flash_info_t *finfo = (flash_info_t *)dev->priv;
+ flash_info_t *finfo = (flash_info_t *)cdev->priv;
unsigned long start, end;
int i, ret = 0;
debug("%s: erase 0x%08x (size %d)\n", __FUNCTION__, offset, count);
- start = flash_find_sector(finfo, dev->map_base + offset);
- end = flash_find_sector(finfo, dev->map_base + offset + count - 1);
+ start = flash_find_sector(finfo, cdev->dev->map_base + offset);
+ end = flash_find_sector(finfo, cdev->dev->map_base + offset + count - 1);
for (i = start; i <= end; i++) {
ret = flash_erase_one (finfo, i);
@@ -373,16 +374,16 @@ out:
return ret;
}
-static int cfi_protect(struct device_d *dev, size_t count, unsigned long offset, int prot)
+static int cfi_protect(struct cdev *cdev, size_t count, unsigned long offset, int prot)
{
- flash_info_t *finfo = (flash_info_t *)dev->priv;
+ flash_info_t *finfo = (flash_info_t *)cdev->priv;
unsigned long start, end;
int i, ret = 0;
debug("%s: protect 0x%08x (size %d)\n", __FUNCTION__, offset, count);
- start = flash_find_sector(finfo, dev->map_base + offset);
- end = flash_find_sector(finfo, dev->map_base + offset + count - 1);
+ start = flash_find_sector(finfo, cdev->dev->map_base + offset);
+ end = flash_find_sector(finfo, cdev->dev->map_base + offset + count - 1);
for (i = start; i <= end; i++) {
ret = flash_real_protect (finfo, i, prot);
@@ -394,14 +395,14 @@ out:
return ret;
}
-static ssize_t cfi_write(struct device_d* dev, const void* buf, size_t count, unsigned long offset, ulong flags)
+static ssize_t cfi_write(struct cdev *cdev, const void* buf, size_t count, unsigned long offset, ulong flags)
{
- flash_info_t *finfo = (flash_info_t *)dev->priv;
+ flash_info_t *finfo = (flash_info_t *)cdev->priv;
int ret;
- debug("cfi_write: buf=0x%08x addr=0x%08x count=0x%08x\n",buf, dev->map_base + offset, count);
+ debug("cfi_write: buf=0x%08x addr=0x%08x count=0x%08x\n",buf, cdev->dev->map_base + offset, count);
- ret = write_buff (finfo, buf, dev->map_base + offset, count);
+ ret = write_buff (finfo, buf, cdev->dev->map_base + offset, count);
return ret == 0 ? count : -1;
}
@@ -1437,43 +1438,48 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, const uchar *
}
#endif /* CONFIG_CFI_BUFFER_WRITE */
+struct file_operations cfi_ops = {
+ .read = mem_read,
+ .write = cfi_write,
+ .lseek = dev_lseek_default,
+ .erase = cfi_erase,
+ .protect = cfi_protect,
+ .memmap = generic_memmap_ro,
+};
+
static int cfi_probe (struct device_d *dev)
{
unsigned long size = 0;
- flash_info_t *info = malloc(sizeof(flash_info_t));
+ flash_info_t *info = xzalloc(sizeof(flash_info_t));
+ char name[MAX_DRIVER_NAME];
dev->priv = (void *)info;
- debug ("cfi_probe: %s base: 0x%08x size: 0x%08x\n", dev->name, dev->map_base, dev->size);
+ printf("cfi_probe: %s base: 0x%08x size: 0x%08x\n", dev->name, dev->map_base, dev->size);
/* Init: no FLASHes known */
info->flash_id = FLASH_UNKNOWN;
size += info->size = flash_get_size(info, dev->map_base);
-
- if (dev->size > size) {
- dev_dbg(dev, "limiting size from 0x%08x to 0x%08x\n", dev->size, size);
- dev->size = size;
- }
-
if (info->flash_id == FLASH_UNKNOWN) {
- debug ("## Unknown FLASH on Bank at 0x%08x - Size = 0x%08lx = %ld MB\n",
+ printf ("## Unknown FLASH on Bank at 0x%08x - Size = 0x%08lx = %ld MB\n",
dev->map_base, info->size, info->size << 20);
+ return -ENODEV;
}
+ get_free_deviceid(name, "nor");
+ info->cdev.name = strdup(name);
+ info->cdev.size = info->size;
+ info->cdev.dev = dev;
+ info->cdev.ops = &cfi_ops;
+ info->cdev.priv = info;
+ devfs_create(&info->cdev);
+
return 0;
}
static struct driver_d cfi_driver = {
.name = "cfi_flash",
.probe = cfi_probe,
- .read = mem_read,
- .write = cfi_write,
- .lseek = dev_lseek_default,
- .open = dev_open_default,
- .close = dev_close_default,
- .erase = cfi_erase,
- .protect= cfi_protect,
- .memmap = generic_memmap_ro,
.info = cfi_info,
};
diff --git a/drivers/nor/cfi_flash_new.c b/drivers/nor/cfi_flash_new.c
index b64f057222..f45b97b839 100644
--- a/drivers/nor/cfi_flash_new.c
+++ b/drivers/nor/cfi_flash_new.c
@@ -42,6 +42,7 @@
#include <malloc.h>
#include <cfi_flash_new.h>
#include <asm/io.h>
+#include <errno.h>
/*
* This file implements a Common Flash Interface (CFI) driver for U-Boot.
@@ -348,8 +349,8 @@ static ulong flash_get_size (flash_info_t *info, ulong base)
break;
#endif
default:
- printf("unsopported vendor\n");
- break;
+ printf("unsupported vendor\n");
+ return 0;
}
info->cfi_cmd_set->flash_read_jedec_ids (info);
flash_write_cmd (info, 0, info->cfi_offset, FLASH_CMD_CFI);
@@ -505,16 +506,16 @@ flash_sect_t find_sector (flash_info_t * info, ulong addr)
return sector;
}
-static int cfi_erase(struct device_d *dev, size_t count, unsigned long offset)
+static int cfi_erase(struct cdev *cdev, size_t count, unsigned long offset)
{
- flash_info_t *finfo = (flash_info_t *)dev->priv;
+ flash_info_t *finfo = (flash_info_t *)cdev->priv;
unsigned long start, end;
int i, ret = 0;
printf("%s: erase 0x%08x (size %d)\n", __FUNCTION__, offset, count);
- start = find_sector(finfo, dev->map_base + offset);
- end = find_sector(finfo, dev->map_base + offset + count - 1);
+ start = find_sector(finfo, cdev->dev->map_base + offset);
+ end = find_sector(finfo, cdev->dev->map_base + offset + count - 1);
for (i = start; i <= end; i++) {
ret = finfo->cfi_cmd_set->flash_erase_one(finfo, i);
@@ -658,16 +659,16 @@ static int flash_real_protect (flash_info_t * info, long sector, int prot)
return retcode;
}
-static int cfi_protect(struct device_d *dev, size_t count, unsigned long offset, int prot)
+static int cfi_protect(struct cdev *cdev, size_t count, unsigned long offset, int prot)
{
- flash_info_t *finfo = (flash_info_t *)dev->priv;
+ flash_info_t *finfo = (flash_info_t *)cdev->priv;
unsigned long start, end;
int i, ret = 0;
- debug("%s: protect 0x%08x (size %d)\n", __FUNCTION__, offset, count);
+ printf("%s: protect 0x%08x (size %d)\n", __FUNCTION__, cdev->dev->map_base + offset, count);
- start = find_sector(finfo, dev->map_base + offset);
- end = find_sector(finfo, dev->map_base + offset + count - 1);
+ start = find_sector(finfo, cdev->dev->map_base + offset);
+ end = find_sector(finfo, cdev->dev->map_base + offset + count - 1);
for (i = start; i <= end; i++) {
ret = flash_real_protect (finfo, i, prot);
@@ -679,14 +680,14 @@ out:
return ret;
}
-static ssize_t cfi_write(struct device_d* dev, const void* buf, size_t count, unsigned long offset, ulong flags)
+static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, unsigned long offset, ulong flags)
{
- flash_info_t *finfo = (flash_info_t *)dev->priv;
+ flash_info_t *finfo = (flash_info_t *)cdev->priv;
int ret;
- debug("cfi_write: buf=0x%08x addr=0x%08x count=0x%08x\n",buf, dev->map_base + offset, count);
+ debug("cfi_write: buf=0x%08x addr=0x%08x count=0x%08x\n",buf, cdev->dev->map_base + offset, count);
- ret = write_buff (finfo, buf, dev->map_base + offset, count);
+ ret = write_buff (finfo, buf, cdev->dev->map_base + offset, count);
return ret == 0 ? count : -1;
}
@@ -934,10 +935,20 @@ int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
return retval;
}
+struct file_operations cfi_ops = {
+ .read = mem_read,
+ .write = cfi_write,
+ .lseek = dev_lseek_default,
+ .erase = cfi_erase,
+ .protect = cfi_protect,
+ .memmap = generic_memmap_ro,
+};
+
static int cfi_probe (struct device_d *dev)
{
unsigned long size = 0;
- flash_info_t *info = malloc(sizeof(flash_info_t));
+ flash_info_t *info = xzalloc(sizeof(flash_info_t));
+ char name[MAX_DRIVER_NAME];
dev->priv = (void *)info;
@@ -953,27 +964,26 @@ static int cfi_probe (struct device_d *dev)
}
if (info->flash_id == FLASH_UNKNOWN) {
-#ifndef CFG_FLASH_QUIET_TEST
printf ("## Unknown FLASH on Bank at 0x%08x - Size = 0x%08lx = %ld MB\n",
dev->map_base, info->size, info->size << 20);
-#endif /* CFG_FLASH_QUIET_TEST */
+ return -ENODEV;
}
+ get_free_deviceid(name, "nor");
+ info->cdev.name = strdup(name);
+ info->cdev.size = info->size;
+ info->cdev.dev = dev;
+ info->cdev.ops = &cfi_ops;
+ info->cdev.priv = info;
+ devfs_create(&info->cdev);
+
return 0;
}
static struct driver_d cfi_driver = {
.name = "cfi_flash",
.probe = cfi_probe,
- .read = mem_read,
- .write = cfi_write,
- .lseek = dev_lseek_default,
- .open = dev_open_default,
- .close = dev_close_default,
- .erase = cfi_erase,
.info = cfi_info,
- .protect = cfi_protect,
- .memmap = generic_memmap_ro,
};
static int cfi_init(void)
diff --git a/drivers/spi/mc13783.c b/drivers/spi/mc13783.c
index e9085a2aa9..d57ae5c110 100644
--- a/drivers/spi/mc13783.c
+++ b/drivers/spi/mc13783.c
@@ -206,14 +206,17 @@ static int pmic_probe(struct device_d *dev)
return 0;
}
+static struct file_operations pmic_fops = {
+ .open = dev_open_default,
+ .lseek = dev_lseek_default,
+ .close = dev_close_default,
+ .read = pmic_read,
+ .write = pmic_write,
+};
+
static struct driver_d pmic_driver = {
.name = "mc13783",
.probe = pmic_probe,
- .open = dev_open_default,
- .lseek = dev_lseek_default,
- .close = dev_close_default,
- .read = pmic_read,
- .write = pmic_write,
};
static int pmic_init(void)
diff --git a/fs/devfs.c b/fs/devfs.c
index cd9bed2676..1fa9b5c593 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -29,27 +29,53 @@
#include <errno.h>
#include <xfuncs.h>
#include <linux/stat.h>
+#include <ioctl.h>
+#include <nand.h>
+#include <linux/mtd/mtd-abi.h>
+#include <partition.h>
-static int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
+static LIST_HEAD(cdev_list);
+
+struct cdev *cdev_by_name(const char *filename)
{
- struct device_d *dev = f->inode;
+ struct cdev *cdev;
- return dev_read(dev, buf, size, f->pos, f->flags);
+ list_for_each_entry(cdev, &cdev_list, list) {
+ if (!strcmp(cdev->name, filename))
+ return cdev;
+ }
+ return NULL;
}
-static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size)
+int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
{
- struct device_d *dev = f->inode;
+ struct cdev *cdev = f->inode;
+
+ if (!cdev->ops->read)
+ return -ENOSYS;
- return dev_write(dev, buf, size, f->pos, f->flags);
+ return cdev->ops->read(cdev, buf, size,
+ f->pos + cdev->offset, f->flags);
}
-static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos)
+int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size)
{
- struct device_d *dev = f->inode;
- off_t ret;
+ struct cdev *cdev = f->inode;
- ret = dev_lseek(dev, pos);
+ if (!cdev->ops->write)
+ return -ENOSYS;
+
+ return cdev->ops->write(cdev, buf, size,
+ f->pos + cdev->offset, f->flags);
+}
+
+off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos)
+{
+ struct cdev *cdev = f->inode;
+ off_t ret = -1;
+
+ if (cdev->ops->lseek)
+ ret = cdev->ops->lseek(cdev, pos + cdev->offset);
if (ret != -1)
f->pos = pos;
@@ -57,51 +83,100 @@ static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos)
return ret;
}
-static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset)
+int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset)
{
- struct device_d *dev = f->inode;
+ struct cdev *cdev = f->inode;
+
+ if (!cdev->ops->erase)
+ return -ENOSYS;
- return dev_erase(dev, count, offset);
+ return cdev->ops->erase(cdev, count, offset + cdev->offset);
}
-static int devfs_protect(struct device_d *_dev, FILE *f, size_t count, unsigned long offset, int prot)
+int devfs_protect(struct device_d *_dev, FILE *f, size_t count, unsigned long offset, int prot)
{
- struct device_d *dev = f->inode;
+ struct cdev *cdev = f->inode;
- return dev_protect(dev, count, offset, prot);
+ if (!cdev->ops->protect)
+ return -ENOSYS;
+
+ return cdev->ops->protect(cdev, count, offset + cdev->offset, prot);
}
static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags)
{
- struct device_d *dev = f->inode;
+ struct cdev *cdev = f->inode;
+ int ret = -ENOSYS;
+
+ if (!cdev->ops->memmap)
+ return -EINVAL;
- return dev_memmap(dev, map, flags);
+ ret = cdev->ops->memmap(cdev, map, flags);
+
+ if (!ret)
+ *map = (void *)((unsigned long)*map + cdev->offset);
+
+ return ret;
}
static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
{
- struct device_d *dev = get_device_by_id(filename + 1);
+ struct cdev *cdev;
- if (!dev)
+ cdev = cdev_by_name(filename + 1);
+
+ if (!cdev)
return -ENOENT;
- f->size = dev->size;
- f->inode = dev;
- return dev_open(dev, f);
+ f->size = cdev->size;
+ f->inode = cdev;
+
+ if (cdev->ops->open)
+ return cdev->ops->open(cdev, f);
+
+ return 0;
}
static int devfs_close(struct device_d *_dev, FILE *f)
{
- struct device_d *dev = f->inode;
+ struct cdev *cdev = f->inode;
+
+ if (cdev->ops->close)
+ return cdev->ops->close(cdev, f);
+ return 0;
+}
- return dev_close(dev, f);
+static int partition_ioctl(struct cdev *cdev, int request, void *buf)
+{
+ size_t offset;
+
+ switch (request) {
+ case MEMSETBADBLOCK:
+ case MEMGETBADBLOCK:
+ offset = (off_t)buf;
+ offset += cdev->offset;
+ return cdev->ops->ioctl(cdev, request, (void *)offset);
+ case MEMGETINFO:
+ return cdev->ops->ioctl(cdev, request, buf);
+ default:
+ return -EINVAL;
+ }
}
static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf)
{
- struct device_d *dev = f->inode;
+ struct cdev *cdev = f->inode;
+ int ret = -EINVAL;
- return dev_ioctl(dev, request, buf);
+ if (!cdev->ops->ioctl)
+ goto out;
+
+ if (cdev->flags & DEVFS_IS_PARTITION)
+ ret = partition_ioctl(cdev, request, buf);
+ else
+ ret = cdev->ops->ioctl(cdev, request, buf);
+out:
+ return ret;
}
static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
@@ -117,26 +192,22 @@ static DIR* devfs_opendir(struct device_d *dev, const char *pathname)
dir = xzalloc(sizeof(DIR));
- if (!list_empty(&device_list))
- dir->priv = list_first_entry(&device_list, struct device_d, list);
+ if (!list_empty(&cdev_list))
+ dir->priv = list_first_entry(&cdev_list, struct cdev, list);
return dir;
}
static struct dirent* devfs_readdir(struct device_d *_dev, DIR *dir)
{
- struct device_d *dev = dir->priv;
+ struct cdev *cdev = dir->priv;
- if (!dev)
+ if (!cdev)
return NULL;
- list_for_each_entry_from(dev, &device_list, list) {
- if (!*dev->id)
- continue;
- if (!dev->driver)
- continue;
- strcpy(dir->d.d_name, dev->id);
- dir->priv = list_entry(dev->list.next, struct device_d, list);
+ list_for_each_entry_from(cdev, &cdev_list, list) {
+ strcpy(dir->d.d_name, cdev->name);
+ dir->priv = list_entry(cdev->list.next, struct cdev, list);
return &dir->d;
}
return NULL;
@@ -150,20 +221,17 @@ static int devfs_closedir(struct device_d *dev, DIR *dir)
static int devfs_stat(struct device_d *_dev, const char *filename, struct stat *s)
{
- struct device_d *dev;
+ struct cdev *cdev;
- dev = get_device_by_id(filename + 1);
- if (!dev)
+ cdev = cdev_by_name(filename + 1);
+ if (!cdev)
return -ENOENT;
- if (!dev->driver)
- return -ENXIO;
-
s->st_mode = S_IFCHR;
- s->st_size = dev->size;
- if (dev->driver->write)
+ s->st_size = cdev->size;
+ if (cdev->ops->write)
s->st_mode |= S_IWUSR;
- if (dev->driver->read)
+ if (cdev->ops->read)
s->st_mode |= S_IRUSR;
return 0;
@@ -206,3 +274,71 @@ static int devfs_init(void)
device_initcall(devfs_init);
+int devfs_create(struct cdev *new)
+{
+ struct cdev *cdev;
+
+ cdev = cdev_by_name(new->name);
+ if (cdev)
+ return -EEXIST;
+
+ list_add_tail(&new->list, &cdev_list);
+
+ return 0;
+}
+
+void devfs_remove(struct cdev *cdev)
+{
+ list_del(&cdev->list);
+}
+
+int devfs_add_partition(const char *devname, unsigned long offset, size_t size,
+ int flags, const char *name)
+{
+ struct cdev *cdev, *new;
+
+ cdev = cdev_by_name(name);
+ if (cdev)
+ return -EEXIST;
+
+ cdev = cdev_by_name(devname);
+ if (!cdev)
+ return -ENOENT;
+
+ if (offset + size > cdev->size)
+ return -EINVAL;
+
+ new = xzalloc(sizeof (*new));
+ new->name = strdup(name);
+ new->ops = cdev->ops;
+ new->priv = cdev->priv;
+ new->size = size;
+ new->offset = offset + cdev->offset;
+ new->dev = cdev->dev;
+ new->flags = flags | DEVFS_IS_PARTITION;
+
+ list_add_tail(&new->list, &cdev_list);
+
+ return 0;
+}
+
+int devfs_del_partition(const char *name)
+{
+ struct cdev *cdev;
+
+ cdev = cdev_by_name(name);
+ if (!cdev)
+ return -ENOENT;
+
+ if (!(cdev->flags & DEVFS_IS_PARTITION))
+ return -EINVAL;
+ if (cdev->flags & DEVFS_PARTITION_FIXED)
+ return -EPERM;
+
+ devfs_remove(cdev);
+ free(cdev->name);
+ free(cdev);
+
+ return 0;
+}
+
diff --git a/fs/fs.c b/fs/fs.c
index bc4e9f2c1a..6f278c0e1f 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -943,29 +943,34 @@ static void memcpy_sz(void *_dst, const void *_src, ulong count, ulong rwsize)
}
}
-ssize_t mem_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags)
+ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
{
ulong size;
- size = min(count, dev->size - offset);
+ struct device_d *dev;
+
+ if (!cdev->dev)
+ return -1;
+ dev = cdev->dev;
+
+ size = min((ulong)count, dev->size - offset);
debug("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, flags & O_RWSIZE_MASK);
return size;
}
EXPORT_SYMBOL(mem_read);
-ssize_t mem_write(struct device_d *dev, const void *buf, size_t count, ulong offset, ulong flags)
+ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
{
ulong size;
- size = min(count, dev->size - offset);
+ struct device_d *dev;
+
+ if (!cdev->dev)
+ return -1;
+ dev = cdev->dev;
+
+ size = min((ulong)count, dev->size - offset);
memcpy_sz((void *)(dev->map_base + offset), buf, size, flags & O_RWSIZE_MASK);
return size;
}
EXPORT_SYMBOL(mem_write);
-int mem_memmap(struct device_d *dev, void **map, int flags)
-{
- *map = (void *)dev->map_base;
- return 0;
-}
-EXPORT_SYMBOL(mem_memmap);
-
diff --git a/include/cfi_flash.h b/include/cfi_flash.h
index 22e3fca35c..e461ef14e1 100644
--- a/include/cfi_flash.h
+++ b/include/cfi_flash.h
@@ -32,6 +32,7 @@
typedef struct {
struct driver_d driver;
+ struct cdev cdev;
ulong size; /* total bank size in bytes */
ushort sector_count; /* number of erase units */
ulong flash_id; /* combined device & manufacturer code */
diff --git a/include/cfi_flash_new.h b/include/cfi_flash_new.h
index 5d4bd5b585..2ebe83b455 100644
--- a/include/cfi_flash_new.h
+++ b/include/cfi_flash_new.h
@@ -59,6 +59,7 @@ typedef struct {
ushort cfi_version; /* cfi version */
ushort cfi_offset; /* offset for cfi query */
struct cfi_cmd_set *cfi_cmd_set;
+ struct cdev cdev;
} flash_info_t;
struct cfi_cmd_set {
diff --git a/include/driver.h b/include/driver.h
index b2ab7c25ac..98d54ad3ad 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -98,7 +98,6 @@ struct device_d {
void *type_data; /*! In case this device is a specific device, this pointer
* points to the type specific device, i.e. eth_device
*/
-
struct driver_d *driver; /*! The driver for this device */
struct list_head list; /* The list of all devices */
@@ -133,22 +132,6 @@ struct driver_d {
/*! Called if an instance of a device is gone. */
void (*remove)(struct device_d *);
- /*! Called in response of reading from this device. Required */
- ssize_t (*read) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
-
- /*! Called in response of write to this device. Required */
- ssize_t (*write) (struct device_d*, const void* buf, size_t count, ulong offset, ulong flags);
-
- int (*ioctl) (struct device_d*, int, void *);
-
- off_t (*lseek) (struct device_d*, off_t);
- int (*open) (struct device_d*, struct filep*);
- int (*close) (struct device_d*, struct filep*);
-
- int (*erase) (struct device_d*, size_t count, unsigned long offset);
- int (*protect)(struct device_d*, size_t count, unsigned long offset, int prot);
- int (*memmap)(struct device_d*, void **map, int flags);
-
void (*info) (struct device_d *);
void (*shortinfo) (struct device_d *);
@@ -231,20 +214,14 @@ extern struct list_head driver_list;
*/
struct driver_d *get_driver_by_name(const char *name);
-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, const void *buf, size_t count, ulong offset, ulong flags);
-int dev_open(struct device_d *dev, struct filep *);
-int dev_close(struct device_d *dev, struct filep *);
-int dev_ioctl(struct device_d *dev, int, void *);
-off_t dev_lseek(struct device_d *dev, off_t offset);
-int dev_erase(struct device_d *dev, size_t count, unsigned long offset);
+struct cdev;
+
int dev_protect(struct device_d *dev, size_t count, unsigned long offset, int prot);
-int dev_memmap(struct device_d *dev, void **map, int flags);
/* These are used by drivers which work with direct memory accesses */
-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, const void *buf, size_t count, ulong offset, ulong flags);
-int mem_memmap(struct device_d *dev, void **map, int flags);
+ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags);
+ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags);
+int mem_memmap(struct cdev *cdev, void **map, int flags);
/* Use this if you have nothing to do in your drivers probe function */
int dummy_probe(struct device_d *);
@@ -254,10 +231,10 @@ int dummy_probe(struct device_d *);
*/
void devices_shutdown(void);
-int generic_memmap_ro(struct device_d *dev, void **map, int flags);
-int generic_memmap_rw(struct device_d *dev, void **map, int flags);
+int generic_memmap_ro(struct cdev *dev, void **map, int flags);
+int generic_memmap_rw(struct cdev *dev, void **map, int flags);
-static inline off_t dev_lseek_default(struct device_d *dev, off_t ofs)
+static inline off_t dev_lseek_default(struct cdev *cdev, off_t ofs)
{
return ofs;
}
@@ -312,5 +289,51 @@ struct bus_type {
};
extern struct bus_type platform_bus;
+
+struct file_operations {
+ /*! Called in response of reading from this device. Required */
+ ssize_t (*read)(struct cdev*, void* buf, size_t count, ulong offset, ulong flags);
+
+ /*! Called in response of write to this device. Required */
+ ssize_t (*write)(struct cdev*, const void* buf, size_t count, ulong offset, ulong flags);
+
+ int (*ioctl)(struct cdev*, int, void *);
+ off_t (*lseek)(struct cdev*, off_t);
+ int (*open)(struct cdev*, struct filep*);
+ int (*close)(struct cdev*, struct filep*);
+ int (*erase)(struct cdev*, size_t count, unsigned long offset);
+ int (*protect)(struct cdev*, size_t count, unsigned long offset, int prot);
+ int (*memmap)(struct cdev*, void **map, int flags);
+};
+
+struct cdev {
+ struct file_operations *ops;
+ void *priv;
+ struct device_d *dev;
+ struct list_head list;
+ char *name;
+ unsigned long offset;
+ size_t size;
+ unsigned int flags;
+};
+
+int devfs_create(struct cdev *);
+void devfs_remove(struct cdev *);
+struct cdev *cdev_by_name(const char *filename);
+
+#define DEVFS_PARTITION_FIXED (1 << 0)
+#define DEVFS_PARTITION_READONLY (1 << 1)
+#define DEVFS_IS_PARTITION (1 << 2)
+#define DEVFS_RDWR (1 << 3)
+
+int devfs_add_partition(const char *devname, unsigned long offset, size_t size,
+ int flags, const char *name);
+int devfs_del_partition(const char *name);
+
+struct memory_platform_data {
+ char *name;
+ unsigned int flags;
+};
+
#endif /* DRIVER_H */
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 3a2a1bc299..c6e28e228b 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -9,6 +9,7 @@
#ifndef __MTD_MTD_H__
#define __MTD_MTD_H__
+#include <driver.h>
#include <linux/types.h>
#include <list.h>
#include <linux/mtd/mtd-abi.h>
@@ -199,7 +200,9 @@ struct mtd_info {
int (*get_device) (struct mtd_info *mtd);
void (*put_device) (struct mtd_info *mtd);
+ struct device_d class_dev;
struct device_d *dev;
+ struct cdev cdev;
};
diff --git a/include/miiphy.h b/include/miiphy.h
index 23373e96b2..67f1b1ce98 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -146,6 +146,7 @@ struct miiphy_device {
int flags;
struct eth_device *edev;
+ struct cdev cdev;
};
int miiphy_register(struct miiphy_device *mdev);
diff --git a/include/nand.h b/include/nand.h
index 5121c4d5fc..522a0fc523 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -2,7 +2,9 @@
#ifndef __NAND_H__
#define __NAND_H__
-struct device_d *dev_add_bb_dev(struct device_d *dev, const char *name);
+struct nand_bb;
+
+int dev_add_bb_dev(char *filename, const char *name);
#endif /* __NAND_H__ */
diff --git a/include/partition.h b/include/partition.h
index cdf6368fd4..4eac8de86b 100644
--- a/include/partition.h
+++ b/include/partition.h
@@ -17,20 +17,8 @@ struct partition {
struct device_d device;
char name[16];
+ struct cdev cdev;
};
-#ifdef CONFIG_PARTITION
-struct device_d *dev_add_partition(struct device_d *dev, unsigned long offset,
- size_t size, int flags, const char *name);
-#else
-static inline struct device_d *dev_add_partition(struct device_d *dev,
- unsigned long offset, size_t size, int flags,
- const char *name)
-{
- return 0;
-}
-#endif
-/* FIXME: counterpart missing */
-
#endif /* __PARTITION_H */
diff --git a/lib/driver.c b/lib/driver.c
index 30de8c20ea..2806cc96c2 100644
--- a/lib/driver.c
+++ b/lib/driver.c
@@ -42,6 +42,18 @@ EXPORT_SYMBOL(driver_list);
static LIST_HEAD(active);
+struct device_d *device_by_name(const char *name)
+{
+ struct device_d *dev;
+
+ for_each_device(dev) {
+ if(!strcmp(name, dev->name))
+ return dev;
+ }
+
+ return NULL;
+}
+
struct device_d *get_device_by_id(const char *id)
{
struct device_d *dev;
@@ -217,89 +229,29 @@ struct device_d *get_device_by_path(const char *path)
}
EXPORT_SYMBOL(get_device_by_path);
-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);
- errno = -ENOSYS;
- return -ENOSYS;
-}
-
-ssize_t dev_write(struct device_d *dev, const void *buf, size_t count, unsigned long offset, ulong flags)
-{
- if (dev->driver->write)
- return dev->driver->write(dev, buf, count, offset, flags);
- errno = -ENOSYS;
- return -ENOSYS;
-}
-
-off_t dev_lseek(struct device_d *dev, off_t offset)
-{
- if (dev->driver->lseek)
- return dev->driver->lseek(dev, offset);
- errno = -ENOSYS;
- return -1;
-}
-
-int dev_open(struct device_d *dev, struct filep *f)
-{
- if (dev->driver->open)
- return dev->driver->open(dev, f);
- errno = -ENOSYS;
- return -ENOSYS;
-}
-
-int dev_close(struct device_d *dev, struct filep *f)
-{
- if (dev->driver->close)
- return dev->driver->close(dev, f);
- errno = -ENOSYS;
- return -ENOSYS;
-}
-
-int dev_ioctl(struct device_d *dev, int request, void *buf)
-{
- if (dev->driver->ioctl)
- return dev->driver->ioctl(dev, request, buf);
- errno = -ENOSYS;
- return -ENOSYS;
-}
-
-int dev_erase(struct device_d *dev, size_t count, unsigned long offset)
-{
- if (dev->driver->erase)
- return dev->driver->erase(dev, count, offset);
- errno = -ENOSYS;
- return -ENOSYS;
-}
-
int dev_protect(struct device_d *dev, size_t count, unsigned long offset, int prot)
{
- if (dev->driver->protect)
- return dev->driver->protect(dev, count, offset, prot);
- errno = -ENOSYS;
- return -ENOSYS;
+ printf("%s: currently broken\n", __func__);
+ return -EINVAL;
}
-int dev_memmap(struct device_d *dev, void **map, int flags)
+int generic_memmap_ro(struct cdev *cdev, void **map, int flags)
{
- if (dev->driver->memmap)
- return dev->driver->memmap(dev, map, flags);
- errno = -ENOSYS;
- return -ENOSYS;
-}
+ if (!cdev->dev)
+ return -EINVAL;
-int generic_memmap_ro(struct device_d *dev, void **map, int flags)
-{
if (flags & PROT_WRITE)
return -EACCES;
- *map = (void *)dev->map_base;
+ *map = (void *)cdev->dev->map_base;
return 0;
}
-int generic_memmap_rw(struct device_d *dev, void **map, int flags)
+int generic_memmap_rw(struct cdev *cdev, void **map, int flags)
{
- *map = (void *)dev->map_base;
+ if (!cdev->dev)
+ return -EINVAL;
+
+ *map = (void *)cdev->dev->map_base;
return 0;
}