- Implement tree structure for devices
- Use device tree structure to implement partitions - Let devinfo print a nice tree - Introduce 'fixed' partitions which are not removable - Fix mount: It was not possible to mount on a relative path.
This commit is contained in:
parent
98839f8010
commit
3b6d6a45e7
|
@ -42,8 +42,8 @@ static int ipe337_devices_init(void) {
|
|||
|
||||
register_device(&smc911x_dev);
|
||||
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x20000, "self");
|
||||
dev_add_partition(&cfi_dev, 0x20000, 0x20000, "env");
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x20000, PARTITION_FIXED, "self");
|
||||
dev_add_partition(&cfi_dev, 0x20000, 0x20000, PARTITION_FIXED, "env");
|
||||
dev_protect(&cfi_dev, 0x20000, 0, 1);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -75,11 +75,11 @@ static int netx_devices_init(void) {
|
|||
register_device(&netx_eth_dev0);
|
||||
// register_device(&netx_eth_dev1);
|
||||
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x40000, "self");
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x40000, PARTITION_FIXED, "self");
|
||||
dev_protect(&cfi_dev, 0x40000, 0, 1);
|
||||
|
||||
/* Do not overwrite primary env for now */
|
||||
dev_add_partition(&cfi_dev, 0xc0000, 0x80000, "env");
|
||||
dev_add_partition(&cfi_dev, 0xc0000, 0x80000, PARTITION_FIXED, "env");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -113,8 +113,8 @@ static int imx31_devices_init(void)
|
|||
* Create partitions that should be
|
||||
* not touched by any regular user
|
||||
*/
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x20000, "self"); /* ourself */
|
||||
dev_add_partition(&cfi_dev, 0x20000, 0x20000, "env"); /* environment */
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x20000, PARTITION_FIXED, "self"); /* ourself */
|
||||
dev_add_partition(&cfi_dev, 0x20000, 0x20000, PARTITION_FIXED, "env"); /* environment */
|
||||
dev_protect(&cfi_dev, 0x20000, 0, 1);
|
||||
|
||||
register_device(&sram_dev);
|
||||
|
|
|
@ -90,8 +90,8 @@ static int devices_init (void)
|
|||
scratch_dev.size = SCRATCHMEM_SIZE;
|
||||
register_device(&scratch_dev);
|
||||
|
||||
dev_add_partition(&cfi_dev, 0x00f00000, 0x40000, "self");
|
||||
dev_add_partition(&cfi_dev, 0x00f60000, 0x20000, "env");
|
||||
dev_add_partition(&cfi_dev, 0x00f00000, 0x40000, PARTITION_FIXED, "self");
|
||||
dev_add_partition(&cfi_dev, 0x00f60000, 0x20000, PARTITION_FIXED, "env");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -87,8 +87,8 @@ static int pcm038_devices_init(void)
|
|||
register_device(&sdram_dev);
|
||||
register_device(&fec_dev);
|
||||
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x20000, "self");
|
||||
dev_add_partition(&cfi_dev, 0x40000, 0x20000, "env");
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x20000, PARTITION_FIXED, "self");
|
||||
dev_add_partition(&cfi_dev, 0x40000, 0x20000, PARTITION_FIXED, "env");
|
||||
dev_protect(&cfi_dev, 0x20000, 0, 1);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -91,8 +91,8 @@ static int scb9328_devices_init(void) {
|
|||
register_device(&sdram_dev);
|
||||
register_device(&dm9000_dev);
|
||||
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x20000, "self");
|
||||
dev_add_partition(&cfi_dev, 0x40000, 0x20000, "env");
|
||||
dev_add_partition(&cfi_dev, 0x00000, 0x20000, PARTITION_FIXED, "self");
|
||||
dev_add_partition(&cfi_dev, 0x40000, 0x20000, PARTITION_FIXED, "env");
|
||||
dev_protect(&cfi_dev, 0x20000, 0, 1);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -29,25 +29,29 @@
|
|||
#include <errno.h>
|
||||
#include <xfuncs.h>
|
||||
|
||||
static void dev_del_partitions(struct device_d *physdev)
|
||||
static int dev_del_partitions(struct device_d *physdev)
|
||||
{
|
||||
struct device_d *dev;
|
||||
char buf[MAX_DRIVER_NAME];
|
||||
int i = 0;
|
||||
struct device_d *child, *tmp;
|
||||
int ret;
|
||||
|
||||
/* This is lame. Devices should to able to have children */
|
||||
while (1) {
|
||||
sprintf(buf, "%s.%d", physdev->id, i);
|
||||
dev = device_from_spec_str(buf, NULL);
|
||||
if (dev) {
|
||||
struct partition *part = dev->type_data;
|
||||
printf("unregister %s %s\n", dev->name, dev->id);
|
||||
unregister_device(dev);
|
||||
free(part);
|
||||
} else
|
||||
break;
|
||||
i++;
|
||||
device_for_each_child_safe(physdev, tmp, child) {
|
||||
struct partition *part = child->type_data;
|
||||
|
||||
debug("delete partition: %s\n", child->id);
|
||||
|
||||
if (part->flags & PARTITION_FIXED)
|
||||
continue;
|
||||
|
||||
ret = unregister_device(child);
|
||||
if (ret) {
|
||||
printf("delete partition `%s' failed: %s\n", child->id, errno_str());
|
||||
return errno;
|
||||
}
|
||||
|
||||
free(part);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtd_part_do_parse_one(struct partition *part, const char *str,
|
||||
|
@ -92,7 +96,7 @@ static int mtd_part_do_parse_one(struct partition *part, const char *str,
|
|||
str = end;
|
||||
|
||||
if (*str == 'r' && *(str + 1) == 'o') {
|
||||
part->readonly = 1;
|
||||
part->flags |= PARTITION_READONLY;
|
||||
end = (char *)(str + 2);
|
||||
}
|
||||
|
||||
|
@ -113,12 +117,12 @@ static int do_addpart(cmd_tbl_t * cmdtp, int argc, char *argv[])
|
|||
int num = 0;
|
||||
unsigned long offset;
|
||||
|
||||
if (argc != 2) {
|
||||
if (argc != 3) {
|
||||
printf("Usage:\n%s\n", cmdtp->usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dev = device_from_spec_str(argv[1], &endp);
|
||||
dev = get_device_by_path(argv[1]);
|
||||
if (!dev) {
|
||||
printf("no such device: %s\n", argv[1]);
|
||||
return 1;
|
||||
|
@ -128,6 +132,8 @@ static int do_addpart(cmd_tbl_t * cmdtp, int argc, char *argv[])
|
|||
|
||||
offset = 0;
|
||||
|
||||
endp = argv[2];
|
||||
|
||||
while (1) {
|
||||
part = xzalloc(sizeof(struct partition));
|
||||
|
||||
|
@ -138,28 +144,37 @@ static int do_addpart(cmd_tbl_t * cmdtp, int argc, char *argv[])
|
|||
|
||||
if (mtd_part_do_parse_one(part, endp, &endp)) {
|
||||
dev_del_partitions(dev);
|
||||
free(part);
|
||||
return 1;
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
offset += part->device.size;
|
||||
|
||||
part->device.type_data = part;
|
||||
|
||||
sprintf(part->device.id, "%s.%d", dev->id, num);
|
||||
register_device(&part->device);
|
||||
sprintf(part->device.id, "%s.%s", dev->id, part->name);
|
||||
if (register_device(&part->device))
|
||||
goto free_out;
|
||||
|
||||
dev_add_child(dev, &part->device);
|
||||
|
||||
num++;
|
||||
|
||||
if (!*endp)
|
||||
break;
|
||||
|
||||
if (*endp != ',') {
|
||||
printf("parse error\n");
|
||||
return 1;
|
||||
goto err_out;
|
||||
}
|
||||
endp++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
free_out:
|
||||
free(part);
|
||||
err_out:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __maybe_unused char cmd_addpart_help[] =
|
||||
|
@ -175,7 +190,7 @@ static __maybe_unused char cmd_addpart_help[] =
|
|||
"Note That this command has to be reworked and will probably change it's API.";
|
||||
|
||||
U_BOOT_CMD_START(addpart)
|
||||
.maxargs = 2,
|
||||
.maxargs = 3,
|
||||
.cmd = do_addpart,
|
||||
.usage = "add a partition table to a device",
|
||||
U_BOOT_CMD_HELP(cmd_addpart_help)
|
||||
|
@ -190,7 +205,7 @@ static int do_delpart(cmd_tbl_t * cmdtp, int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
dev = device_from_spec_str(argv[1], NULL);
|
||||
dev = get_device_by_path(argv[1]);
|
||||
if (!dev) {
|
||||
printf("no such device: %s\n", argv[1]);
|
||||
return 1;
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
#include <partition.h>
|
||||
#include <xfuncs.h>
|
||||
|
||||
struct device_d *dev_add_partition(struct device_d *dev, unsigned long offset, size_t size, char *name)
|
||||
struct device_d *dev_add_partition(struct device_d *dev, unsigned long offset,
|
||||
size_t size, int flags, const char *name)
|
||||
{
|
||||
struct partition *part;
|
||||
|
||||
|
@ -24,8 +25,10 @@ struct device_d *dev_add_partition(struct device_d *dev, unsigned long offset, s
|
|||
|
||||
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;
|
||||
|
@ -81,15 +84,17 @@ static ssize_t part_write(struct device_d *dev, const void *buf, size_t count, u
|
|||
{
|
||||
struct partition *part = dev->type_data;
|
||||
|
||||
if (part->readonly)
|
||||
return -EROFS;
|
||||
if (part->flags & PARTITION_READONLY)
|
||||
return -EROFS;
|
||||
else
|
||||
return dev_write(part->physdev, buf, count, offset + part->offset, flags);
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
39
fs/fs.c
39
fs/fs.c
|
@ -202,6 +202,11 @@ struct mtab_entry *mtab_next_entry(struct mtab_entry *e)
|
|||
return e->next;
|
||||
}
|
||||
|
||||
const char *fsdev_get_mountpoint(struct fs_device_d *fsdev)
|
||||
{
|
||||
return fsdev->mtab.path;
|
||||
}
|
||||
|
||||
FILE files[MAX_FILES];
|
||||
|
||||
FILE *get_file(void)
|
||||
|
@ -224,7 +229,7 @@ void put_file(FILE *f)
|
|||
files[f->no].in_use = 0;
|
||||
}
|
||||
|
||||
static struct device_d *get_device_by_path(char **path)
|
||||
static struct device_d *get_fs_device_by_path(char **path)
|
||||
{
|
||||
struct device_d *dev;
|
||||
struct mtab_entry *e;
|
||||
|
@ -346,7 +351,7 @@ int unlink(const char *pathname)
|
|||
if (path_check_prereq(pathname, S_IFREG))
|
||||
goto out;
|
||||
|
||||
dev = get_device_by_path(&p);
|
||||
dev = get_fs_device_by_path(&p);
|
||||
if (!dev)
|
||||
goto out;
|
||||
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||
|
@ -386,7 +391,7 @@ int open(const char *pathname, int flags, ...)
|
|||
goto out1;
|
||||
}
|
||||
|
||||
dev = get_device_by_path(&path);
|
||||
dev = get_fs_device_by_path(&path);
|
||||
if (!dev)
|
||||
goto out;
|
||||
|
||||
|
@ -599,7 +604,7 @@ EXPORT_SYMBOL(close);
|
|||
* driver will match. The filesystem driver then grabs the infomation
|
||||
* it needs from the new devices type_data.
|
||||
*/
|
||||
int mount(const char *device, const char *fsname, const char *path)
|
||||
int mount(const char *device, const char *fsname, const char *_path)
|
||||
{
|
||||
struct driver_d *drv;
|
||||
struct fs_driver_d *fs_drv;
|
||||
|
@ -607,11 +612,23 @@ int mount(const char *device, const char *fsname, const char *path)
|
|||
struct fs_device_d *fsdev;
|
||||
struct device_d *dev, *parent_device = 0;
|
||||
int ret;
|
||||
char *path = normalise_path(_path);
|
||||
|
||||
errno = 0;
|
||||
|
||||
debug("mount: %s on %s type %s\n", device, path, fsname);
|
||||
|
||||
if (get_mtab_entry_by_path(path) != mtab) {
|
||||
errno = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strchr(path + 1, '/')) {
|
||||
printf("mounting allowed on first directory level only\n");
|
||||
errno = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
drv = get_driver_by_name(fsname);
|
||||
if (!drv) {
|
||||
errno = -ENODEV;
|
||||
|
@ -663,10 +680,13 @@ int mount(const char *device, const char *fsname, const char *path)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (parent_device)
|
||||
dev_add_child(parent_device, &fsdev->dev);
|
||||
|
||||
dev = &fsdev->dev;
|
||||
|
||||
/* add mtab entry */
|
||||
entry = malloc(sizeof(struct mtab_entry));
|
||||
entry = &fsdev->mtab;
|
||||
sprintf(entry->path, "%s", path);
|
||||
entry->dev = dev;
|
||||
entry->parent_device = parent_device;
|
||||
|
@ -681,6 +701,7 @@ int mount(const char *device, const char *fsname, const char *path)
|
|||
e->next = entry;
|
||||
}
|
||||
out:
|
||||
free(path);
|
||||
return errno;
|
||||
}
|
||||
EXPORT_SYMBOL(mount);
|
||||
|
@ -710,7 +731,7 @@ int umount(const char *pathname)
|
|||
|
||||
unregister_device(entry->dev);
|
||||
free(entry->dev->type_data);
|
||||
free(entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(umount);
|
||||
|
@ -726,7 +747,7 @@ DIR *opendir(const char *pathname)
|
|||
if (path_check_prereq(pathname, S_IFDIR))
|
||||
goto out;
|
||||
|
||||
dev = get_device_by_path(&p);
|
||||
dev = get_fs_device_by_path(&p);
|
||||
if (!dev)
|
||||
goto out;
|
||||
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||
|
@ -809,7 +830,7 @@ int mkdir (const char *pathname, mode_t mode)
|
|||
if (path_check_prereq(pathname, S_UB_DOES_NOT_EXIST))
|
||||
goto out;
|
||||
|
||||
dev = get_device_by_path(&p);
|
||||
dev = get_fs_device_by_path(&p);
|
||||
if (!dev)
|
||||
goto out;
|
||||
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||
|
@ -836,7 +857,7 @@ int rmdir (const char *pathname)
|
|||
if (path_check_prereq(pathname, S_IFDIR | S_UB_IS_EMPTY))
|
||||
goto out;
|
||||
|
||||
dev = get_device_by_path(&p);
|
||||
dev = get_fs_device_by_path(&p);
|
||||
if (!dev)
|
||||
goto out;
|
||||
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
|
||||
|
|
|
@ -37,7 +37,11 @@ struct device_d {
|
|||
|
||||
struct driver_d *driver; /* The driver for this device */
|
||||
|
||||
struct list_head list;
|
||||
struct list_head list; /* The list of all devices */
|
||||
struct list_head children; /* our children */
|
||||
struct list_head sibling;
|
||||
|
||||
struct device_d *parent; /* our parent, NULL if not present */
|
||||
|
||||
unsigned long type;
|
||||
|
||||
|
@ -70,12 +74,30 @@ struct driver_d {
|
|||
#define RW_SIZE(x) (x)
|
||||
#define RW_SIZE_MASK 0x7
|
||||
|
||||
/* Register/unregister devices and drivers. Since we don't have modules
|
||||
* we do not need a driver_unregister function.
|
||||
/* Register devices and drivers.
|
||||
*/
|
||||
int register_driver(struct driver_d *);
|
||||
int register_device(struct device_d *);
|
||||
void unregister_device(struct device_d *);
|
||||
|
||||
/* Unregister a device. This function can fail, e.g. when the device
|
||||
* has children.
|
||||
*/
|
||||
int unregister_device(struct device_d *);
|
||||
|
||||
/* Organize devices in a tree. These functions do _not_ register or
|
||||
* unregister a device. Only registered devices are allowed here.
|
||||
*/
|
||||
int dev_add_child(struct device_d *dev, struct device_d *child);
|
||||
|
||||
/* Iterate over a devices children
|
||||
*/
|
||||
#define device_for_each_child(dev, child) \
|
||||
list_for_each_entry(child, &dev->children, sibling)
|
||||
|
||||
/* Iterate over a devices children - Safe against removal version
|
||||
*/
|
||||
#define device_for_each_child_safe(dev, tmpdev, child) \
|
||||
list_for_each_entry_safe(child, tmpdev, &dev->children, sibling)
|
||||
|
||||
/* Iterate through the devices of a given type. if last is NULL, the
|
||||
* first device of this type is returned. Put this pointer in as
|
||||
|
@ -84,7 +106,7 @@ void unregister_device(struct device_d *);
|
|||
*/
|
||||
struct device_d *get_device_by_type(ulong type, struct device_d *last);
|
||||
struct device_d *get_device_by_id(const char *id);
|
||||
struct device_d *get_first_device(void);
|
||||
struct device_d *get_device_by_path(const char *path);
|
||||
|
||||
/* Find a free device id from the given template. This is archieved by
|
||||
* appending a number to the template. Dynamically created devices should
|
||||
|
@ -92,13 +114,22 @@ struct device_d *get_first_device(void);
|
|||
*/
|
||||
int get_free_deviceid(char *id, char *id_template);
|
||||
|
||||
struct device_d *device_from_spec_str(const char *str, char **endp);
|
||||
char *deviceid_from_spec_str(const char *str, char **endp);
|
||||
|
||||
/* linear list over all available devices
|
||||
*/
|
||||
extern struct list_head device_list;
|
||||
|
||||
/* linear list over all available drivers
|
||||
*/
|
||||
extern struct list_head driver_list;
|
||||
|
||||
/* Iterate over all devices
|
||||
*/
|
||||
#define for_each_device(dev) list_for_each_entry(dev, &device_list, list)
|
||||
|
||||
extern struct list_head driver_list;
|
||||
/* Iterate over all drivers
|
||||
*/
|
||||
#define for_each_driver(drv) list_for_each_entry(drv, &driver_list, list)
|
||||
|
||||
/* Find a driver with the given name. Currently the filesystem implementation
|
||||
|
|
17
include/fs.h
17
include/fs.h
|
@ -76,11 +76,20 @@ struct fs_driver_d {
|
|||
unsigned long flags;
|
||||
};
|
||||
|
||||
struct mtab_entry {
|
||||
char path[PATH_MAX];
|
||||
struct mtab_entry *next;
|
||||
struct device_d *dev;
|
||||
struct device_d *parent_device;
|
||||
};
|
||||
|
||||
struct fs_device_d {
|
||||
struct device_d *parent; /* the device we are associated with */
|
||||
struct device_d dev; /* our own device */
|
||||
|
||||
struct fs_driver_d *driver;
|
||||
|
||||
struct mtab_entry mtab;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -136,13 +145,7 @@ char *mkmodestr(unsigned long mode, char *str);
|
|||
*/
|
||||
struct mtab_entry *get_mtab_entry_by_path(const char *path);
|
||||
struct mtab_entry *mtab_next_entry(struct mtab_entry *entry);
|
||||
|
||||
struct mtab_entry {
|
||||
char path[PATH_MAX];
|
||||
struct mtab_entry *next;
|
||||
struct device_d *dev;
|
||||
struct device_d *parent_device;
|
||||
};
|
||||
const char *fsdev_get_mountpoint(struct fs_device_d *fsdev);
|
||||
|
||||
/*
|
||||
* Read a file into memory. Memory is allocated with malloc and must
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
|
||||
struct device_d;
|
||||
|
||||
#define PARTITION_FIXED (1 << 0)
|
||||
#define PARTITION_READONLY (1 << 1)
|
||||
|
||||
struct partition {
|
||||
int num;
|
||||
|
||||
int readonly;
|
||||
int flags;
|
||||
|
||||
unsigned long offset;
|
||||
|
||||
|
@ -17,7 +20,7 @@ struct partition {
|
|||
};
|
||||
|
||||
struct device_d *dev_add_partition(struct device_d *dev, unsigned long offset,
|
||||
size_t size, char *name);
|
||||
size_t size, int flags, const char *name);
|
||||
/* FIXME: counterpart missing */
|
||||
|
||||
#endif /* __PARTITION_H */
|
||||
|
|
106
lib/driver.c
106
lib/driver.c
|
@ -86,6 +86,7 @@ int register_device(struct device_d *new_device)
|
|||
debug ("register_device: %s\n",new_device->name);
|
||||
|
||||
list_add_tail(&new_device->list, &device_list);
|
||||
INIT_LIST_HEAD(&new_device->children);
|
||||
|
||||
for_each_driver(drv) {
|
||||
if (!match(drv, new_device))
|
||||
|
@ -96,17 +97,37 @@ int register_device(struct device_d *new_device)
|
|||
}
|
||||
EXPORT_SYMBOL(register_device);
|
||||
|
||||
void unregister_device(struct device_d *old_dev)
|
||||
int unregister_device(struct device_d *old_dev)
|
||||
{
|
||||
debug("unregister_device: %s:%s\n",old_dev->name, old_dev->id);
|
||||
|
||||
if (!list_empty(&old_dev->children)) {
|
||||
errno = -EBUSY;
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (old_dev->driver)
|
||||
old_dev->driver->remove(old_dev);
|
||||
|
||||
list_del(&old_dev->list);
|
||||
|
||||
/* remove device from parents child list */
|
||||
if (old_dev->parent)
|
||||
list_del(&old_dev->sibling);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_device);
|
||||
|
||||
int dev_add_child(struct device_d *dev, struct device_d *child)
|
||||
{
|
||||
child->parent = dev;
|
||||
|
||||
list_add_tail(&child->sibling, &dev->children);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct driver_d *get_driver_by_name(const char *name)
|
||||
{
|
||||
struct driver_d *drv;
|
||||
|
@ -132,7 +153,7 @@ int register_driver(struct driver_d *drv)
|
|||
{
|
||||
struct device_d *dev = NULL;
|
||||
|
||||
debug("register_driver: %s\n",new_driver->name);
|
||||
debug("register_driver: %s\n", drv->name);
|
||||
|
||||
list_add_tail(&drv->list, &driver_list);
|
||||
|
||||
|
@ -148,51 +169,17 @@ int register_driver(struct driver_d *drv)
|
|||
}
|
||||
EXPORT_SYMBOL(register_driver);
|
||||
|
||||
static char devicename_from_spec_str_buf[PATH_MAX];
|
||||
|
||||
char *deviceid_from_spec_str(const char *str, char **endp)
|
||||
{
|
||||
char *buf = devicename_from_spec_str_buf;
|
||||
const char *end;
|
||||
int i = 0;
|
||||
|
||||
if (isdigit(*str)) {
|
||||
/* No device name given, use default driver mem */
|
||||
sprintf(buf, "mem");
|
||||
end = str;
|
||||
} else {
|
||||
/* OK, we have a device name, parse it */
|
||||
while (*str) {
|
||||
if (*str == ':') {
|
||||
str++;
|
||||
buf[i] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
buf[i++] = *str++;
|
||||
buf[i] = 0;
|
||||
if (i == MAX_DRIVER_NAME)
|
||||
return NULL;
|
||||
}
|
||||
end = str;
|
||||
}
|
||||
|
||||
if (endp)
|
||||
*endp = (char *)end;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Get a device struct from the beginning of the string. Default to mem if no
|
||||
* device is given, return NULL if a unknown device is given.
|
||||
* If endp is not NULL, this function stores a pointer to the first character
|
||||
* after the device name in *endp.
|
||||
*/
|
||||
struct device_d *device_from_spec_str(const char *str, char **endp)
|
||||
struct device_d *get_device_by_path(const char *path)
|
||||
{
|
||||
char *name;
|
||||
name = deviceid_from_spec_str(str, endp);
|
||||
return get_device_by_id(name);
|
||||
if (strncmp(path, "/dev/", 5))
|
||||
return NULL;
|
||||
|
||||
return get_device_by_id(path + 5);
|
||||
}
|
||||
|
||||
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
|
||||
|
@ -254,6 +241,30 @@ int dummy_probe(struct device_d *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int do_devinfo_subtree(struct device_d *dev, int depth, char edge)
|
||||
{
|
||||
struct device_d *child;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < depth; i++)
|
||||
printf("| ");
|
||||
|
||||
if (*dev->id)
|
||||
printf("%c----%s\n", edge, dev->id);
|
||||
else if (dev->type == DEVICE_TYPE_FS)
|
||||
printf("%c----filesystem: %s\n", edge, fsdev_get_mountpoint((struct fs_device_d *)dev->type_data));
|
||||
|
||||
if (!list_empty(&dev->children)) {
|
||||
device_for_each_child(dev, child) {
|
||||
do_dev_subtree(child, depth + 1,
|
||||
list_is_last(&child->sibling,
|
||||
&dev->children) ? '`' : '|');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_devinfo ( cmd_tbl_t *cmdtp, int argc, char *argv[])
|
||||
{
|
||||
struct device_d *dev;
|
||||
|
@ -264,23 +275,26 @@ static int do_devinfo ( cmd_tbl_t *cmdtp, int argc, char *argv[])
|
|||
printf("devices:\n");
|
||||
|
||||
for_each_device(dev) {
|
||||
printf("%10s: base=0x%08x size=0x%08x (driver %s)\n",
|
||||
dev->id, dev->map_base, dev->size,
|
||||
dev->driver ?
|
||||
dev->driver->name : "none");
|
||||
if (!dev->parent)
|
||||
do_devinfo_subtree(dev, 0, '|');
|
||||
}
|
||||
|
||||
printf("\ndrivers:\n");
|
||||
for_each_driver(drv)
|
||||
printf("%10s\n",drv->name);
|
||||
} else {
|
||||
struct device_d *dev = get_device_by_id(argv[1]);
|
||||
struct device_d *dev = get_device_by_path(argv[1]);
|
||||
|
||||
if (!dev) {
|
||||
printf("no such device: %s\n",argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("base : 0x%08x\nsize : 0x%08x\ndriver: %s\n\n",
|
||||
dev->map_base, dev->size,
|
||||
dev->driver ?
|
||||
dev->driver->name : "none");
|
||||
|
||||
if (dev->driver)
|
||||
dev->driver->info(dev);
|
||||
|
||||
|
|
Loading…
Reference in New Issue