diff --git a/Documentation/porting.txt b/Documentation/porting.txt index d59925e..b18957c 100644 --- a/Documentation/porting.txt +++ b/Documentation/porting.txt @@ -34,7 +34,6 @@ static struct device_d scb9328_serial_device = { .name = "imx_serial", - .id = "cs0", .map_base = IMX_UART1_BASE, .size = 4096, }; diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c index 71b0c80..72e4c8d 100644 --- a/arch/sandbox/os/common.c +++ b/arch/sandbox/os/common.c @@ -220,7 +220,7 @@ extern void start_uboot(void); extern void mem_malloc_init(void *start, void *end); -static int add_image(char *str, char *name_template) +static int add_image(char *str, char *name) { char *file; int readonly = 0, map = 1; @@ -257,6 +257,7 @@ } hf->size = s.st_size; + hf->name = strdup(name); if (map) { hf->map_base = (unsigned long)mmap(NULL, hf->size, @@ -266,8 +267,7 @@ printf("warning: mmapping %s failed\n", file); } - - ret = u_boot_register_filedev(hf, name_template); + ret = u_boot_register_filedev(hf); if (ret) goto err_out; return 0; @@ -286,6 +286,8 @@ void *ram; int opt, ret, fd; int malloc_size = 8 * 1024 * 1024; + char str[6]; + int fdno = 0, envno = 0; ram = malloc(malloc_size); if (!ram) { @@ -300,9 +302,11 @@ print_usage(basename(argv[0])); exit(0); case 'i': - ret = add_image(optarg, "fd"); + sprintf(str, "fd%d", fdno); + ret = add_image(optarg, str); if (ret) exit(1); + fdno++; break; case 'm': /* This option is broken. add_image needs malloc, so @@ -312,9 +316,11 @@ malloc_size = strtoul(optarg, NULL, 0); break; case 'e': + sprintf(str, "env%d", envno); ret = add_image(optarg, "env"); if (ret) exit(1); + envno++; break; case 'O': fd = open(optarg, O_WRONLY); diff --git a/board/sandbox/hostfile.c b/board/sandbox/hostfile.c index b6f1dbd..eb3b08f 100644 --- a/board/sandbox/hostfile.c +++ b/board/sandbox/hostfile.c @@ -29,9 +29,14 @@ #include #include -static ssize_t hf_read(struct device_d *dev, void *buf, size_t count, ulong offset, ulong flags) +struct hf_priv { + struct cdev cdev; + struct hf_platform_data *pdata; +}; + +static ssize_t hf_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags) { - struct hf_platform_data *hf = dev->platform_data; + struct hf_platform_data *hf = cdev->priv; int fd = hf->fd; if (linux_lseek(fd, offset) != offset) @@ -40,9 +45,9 @@ return linux_read(fd, buf, count); } -static ssize_t hf_write(struct device_d *dev, const void *buf, size_t count, ulong offset, ulong flags) +static ssize_t hf_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags) { - struct hf_platform_data *hf = dev->platform_data; + struct hf_platform_data *hf = cdev->priv; int fd = hf->fd; if (linux_lseek(fd, offset) != offset) @@ -58,11 +63,30 @@ printf("file: %s\n", hf->filename); } -static struct driver_d hf_drv = { - .name = "hostfile", - .probe = dummy_probe, +static struct file_operations hf_fops = { .read = hf_read, .write = hf_write, +}; + +static int hf_probe(struct device_d *dev) +{ + struct hf_platform_data *hf = dev->platform_data; + struct hf_priv *priv = xzalloc(sizeof(*priv)); + + priv->pdata = hf; + + priv->cdev.name = hf->name; + priv->cdev.size = hf->size; + priv->cdev.ops = &hf_fops; + priv->cdev.priv = hf; + devfs_create(&priv->cdev); + + return 0; +} + +static struct driver_d hf_drv = { + .name = "hostfile", + .probe = hf_probe, .info = hf_info, }; @@ -73,7 +97,7 @@ device_initcall(hf_init); -int u_boot_register_filedev(struct hf_platform_data *hf, char *name_template) +int u_boot_register_filedev(struct hf_platform_data *hf) { struct device_d *dev; @@ -81,10 +105,7 @@ dev->platform_data = hf; - hf = dev->platform_data; - - strcpy(dev->name,"hostfile"); - get_free_deviceid(dev->id, name_template); + strcpy(dev->name, "hostfile"); dev->size = hf->size; dev->map_base = hf->map_base; diff --git a/commands/mount.c b/commands/mount.c index eefcdfa..54260e2 100644 --- a/commands/mount.c +++ b/commands/mount.c @@ -40,7 +40,7 @@ entry = mtab_next_entry(entry); if (entry) { printf("%s on %s type %s\n", - entry->parent_device ? entry->parent_device->id : "none", + entry->parent_device ? entry->parent_device->name : "none", entry->path, entry->dev->name); } diff --git a/commands/net.c b/commands/net.c index 73da615..1b5ca9f 100644 --- a/commands/net.c +++ b/commands/net.c @@ -45,10 +45,10 @@ char tmp[22]; if (NetOurGatewayIP) - dev_set_param_ip(eth_current->dev, "gateway", NetOurGatewayIP); + dev_set_param_ip(ð_current->dev, "gateway", NetOurGatewayIP); if (NetOurSubnetMask) - dev_set_param_ip(eth_current->dev, "netmask", NetOurSubnetMask); + dev_set_param_ip(ð_current->dev, "netmask", NetOurSubnetMask); if (NetOurHostName[0]) @@ -58,10 +58,10 @@ setenv ("rootpath", NetOurRootPath); if (NetOurIP) - dev_set_param_ip(eth_current->dev, "ipaddr", NetOurIP); + dev_set_param_ip(ð_current->dev, "ipaddr", NetOurIP); if (NetServerIP) - dev_set_param_ip(eth_current->dev, "serverip", NetServerIP); + dev_set_param_ip(ð_current->dev, "serverip", NetServerIP); if (NetOurDNSIP) { ip_to_string (NetOurDNSIP, tmp); diff --git a/common/console.c b/common/console.c index c97a4f4..5036c26 100644 --- a/common/console.c +++ b/common/console.c @@ -120,10 +120,14 @@ int console_register(struct console_device *newcdev) { - struct device_d *dev = newcdev->dev; + struct device_d *dev = &newcdev->class_dev; int first = 0; char ch; + strcpy(dev->name, "cs"); + dev->type_data = newcdev->dev->type_data; + register_device(dev); + if (newcdev->setbrg) { newcdev->baudrate_param.set = console_baudrate_set; newcdev->baudrate_param.name = "baudrate"; diff --git a/common/env.c b/common/env.c index 04ca275..edaf388 100644 --- a/common/env.c +++ b/common/env.c @@ -142,7 +142,7 @@ char *par = strchr(devstr, '.'); struct device_d *dev; *par = 0; - dev = get_device_by_id(devstr); + dev = get_device_by_name(devstr); if (dev) { par++; ret = dev_get_param(dev, par); @@ -213,7 +213,7 @@ struct device_d *dev; *par++ = 0; - dev = get_device_by_id(name); + dev = get_device_by_name(name); if (dev) ret = dev_set_param(dev, par, value); else diff --git a/drivers/nand/nand.c b/drivers/nand/nand.c index f90a7ec..2b3dec0 100644 --- a/drivers/nand/nand.c +++ b/drivers/nand/nand.c @@ -152,37 +152,16 @@ .erase = nand_erase, }; -static int nand_device_probe(struct device_d *dev) -{ - return 0; -} - -static struct driver_d nand_device_driver = { - .name = "nand_device", - .probe = nand_device_probe, -}; - -static int nand_init(void) -{ - register_driver(&nand_device_driver); - - return 0; -} - -device_initcall(nand_init); - int add_mtd_device(struct mtd_info *mtd) { - struct device_d *dev = &mtd->class_dev; - char name[MAX_DRIVER_NAME]; - - get_free_deviceid(name, "nand"); + strcpy(mtd->class_dev.name, "nand"); + register_device(&mtd->class_dev); mtd->cdev.ops = &nand_ops; mtd->cdev.size = mtd->size; - mtd->cdev.name = strdup(name); - mtd->cdev.dev = dev; + mtd->cdev.name = asprintf("nand%d", mtd->class_dev.id); mtd->cdev.priv = mtd; + mtd->cdev.dev = &mtd->class_dev; devfs_create(&mtd->cdev); diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c index b38d291..7131aa5 100644 --- a/drivers/nor/cfi_flash.c +++ b/drivers/nor/cfi_flash.c @@ -1451,7 +1451,6 @@ { unsigned long size = 0; flash_info_t *info = xzalloc(sizeof(flash_info_t)); - char name[MAX_DRIVER_NAME]; dev->priv = (void *)info; @@ -1466,8 +1465,7 @@ return -ENODEV; } - get_free_deviceid(name, "nor"); - info->cdev.name = strdup(name); + info->cdev.name = asprintf("nor%d", dev->id); info->cdev.size = info->size; info->cdev.dev = dev; info->cdev.ops = &cfi_ops; diff --git a/drivers/nor/cfi_flash_new.c b/drivers/nor/cfi_flash_new.c index f45b97b..e114bd2 100644 --- a/drivers/nor/cfi_flash_new.c +++ b/drivers/nor/cfi_flash_new.c @@ -948,7 +948,6 @@ { unsigned long size = 0; flash_info_t *info = xzalloc(sizeof(flash_info_t)); - char name[MAX_DRIVER_NAME]; dev->priv = (void *)info; @@ -969,8 +968,7 @@ return -ENODEV; } - get_free_deviceid(name, "nor"); - info->cdev.name = strdup(name); + info->cdev.name = asprintf("nor%d", dev->id); info->cdev.size = info->size; info->cdev.dev = dev; info->cdev.ops = &cfi_ops; diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c index 61fddfa..265e3f5 100644 --- a/drivers/usb/usb.c +++ b/drivers/usb/usb.c @@ -424,7 +424,6 @@ usb_hub_probe(dev, 0); sprintf(dev->dev.name, "usb%d-%d", dev->host->busnum, dev->devnum); - sprintf(dev->dev.id, "usb%d-%d", dev->host->busnum, dev->devnum); print_usb_device(dev); diff --git a/fs/devfs.c b/fs/devfs.c index b8b9fa2..865b9cc 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -47,29 +47,37 @@ return NULL; } -int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) +ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags) { - struct cdev *cdev = f->inode; - if (!cdev->ops->read) return -ENOSYS; - return cdev->ops->read(cdev, buf, size, - f->pos + cdev->offset, f->flags); + return cdev->ops->read(cdev, buf, count, cdev->offset +offset, flags); } -int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size) +ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags) { - struct cdev *cdev = f->inode; - if (!cdev->ops->write) return -ENOSYS; - return cdev->ops->write(cdev, buf, size, - f->pos + cdev->offset, f->flags); + return cdev->ops->write(cdev, buf, count, cdev->offset + offset, flags); } -off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos) +static int devfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) +{ + struct cdev *cdev = f->inode; + + return cdev_read(cdev, buf, size, f->pos, f->flags); +} + +static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size) +{ + struct cdev *cdev = f->inode; + + return cdev_write(cdev, buf, size, f->pos, f->flags); +} + +static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos) { struct cdev *cdev = f->inode; off_t ret = -1; @@ -83,7 +91,7 @@ return ret; } -int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset) +static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset) { struct cdev *cdev = f->inode; @@ -93,7 +101,7 @@ return cdev->ops->erase(cdev, count, offset + cdev->offset); } -int devfs_protect(struct device_d *_dev, FILE *f, size_t count, unsigned long offset, int prot) +static int devfs_protect(struct device_d *_dev, FILE *f, size_t count, unsigned long offset, int prot) { struct cdev *cdev = f->inode; @@ -287,6 +295,8 @@ return -EEXIST; list_add_tail(&new->list, &cdev_list); + if (new->dev) + list_add_tail(&new->devices_list, &new->dev->cdevs); return 0; } @@ -294,6 +304,8 @@ void devfs_remove(struct cdev *cdev) { list_del(&cdev->list); + if (cdev->dev) + list_del(&cdev->devices_list); } int devfs_add_partition(const char *devname, unsigned long offset, size_t size, diff --git a/fs/fs.c b/fs/fs.c index fc7ada0..148e3a3 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -698,16 +698,16 @@ } } + fsdev = xzalloc(sizeof(struct fs_device_d)); if (!fs_drv->flags & FS_DRIVER_NO_DEV) { - parent_device = get_device_by_id(device + 5); - if (!parent_device) { + fsdev->backingstore = strdup(device); + if (!device) { printf("need a device for driver %s\n", fsname); errno = -ENODEV; + free(fsdev); goto out; } } - fsdev = xzalloc(sizeof(struct fs_device_d)); - fsdev->parent = parent_device; sprintf(fsdev->dev.name, "%s", fsname); fsdev->dev.type_data = fsdev; @@ -755,6 +755,7 @@ struct mtab_entry *entry = mtab; struct mtab_entry *last = mtab; char *p = normalise_path(pathname); + struct fs_device_d *fsdev; while(entry && strcmp(p, entry->path)) { last = entry; @@ -774,7 +775,9 @@ last->next = entry->next; unregister_device(entry->dev); - free(entry->dev->type_data); + fsdev = entry->dev->type_data; + free(fsdev->backingstore); + free(fsdev); return 0; } diff --git a/include/asm-sandbox/arch-sandbox/hostfile.h b/include/asm-sandbox/arch-sandbox/hostfile.h index 8362d6b..30f9499 100644 --- a/include/asm-sandbox/arch-sandbox/hostfile.h +++ b/include/asm-sandbox/arch-sandbox/hostfile.h @@ -6,9 +6,10 @@ size_t size; unsigned long map_base; char *filename; + char *name; }; -int u_boot_register_filedev(struct hf_platform_data *hf, char *name_template); +int u_boot_register_filedev(struct hf_platform_data *hf); #endif /* __ASM_ARCH_HOSTFILE_H */ diff --git a/include/console.h b/include/console.h index e6f06bd..e632946 100644 --- a/include/console.h +++ b/include/console.h @@ -26,6 +26,7 @@ #include #include +#include #define CONSOLE_STDIN (1 << 0) #define CONSOLE_STDOUT (1 << 1) @@ -33,6 +34,7 @@ struct console_device { struct device_d *dev; + struct device_d class_dev; int (*tstc)(struct console_device *cdev); void (*putc)(struct console_device *cdev, char c); diff --git a/include/driver.h b/include/driver.h index 8004518..68f744a 100644 --- a/include/driver.h +++ b/include/driver.h @@ -67,7 +67,7 @@ /*! The id is used to uniquely identify a device in the system. The id * will show up under /dev/ as the device's name. Usually this is * something like eth0 or nor0. */ - char id[MAX_DRIVER_NAME]; + int id; /*! FIXME */ unsigned long size; @@ -99,6 +99,8 @@ /*! The parameters for this device. This is used to carry information * of board specific data from the board code to the device driver. */ struct param_d *param; + + struct list_head cdevs; }; /** @brief Describes a driver present in the system */ @@ -165,13 +167,13 @@ */ 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_device_by_path(const char *path); +struct device_d *get_device_by_name(const char *name); /* Find a free device id from the given template. This is archieved by * appending a number to the template. Dynamically created devices should * use this function rather than filling the id field themselves. */ -int get_free_deviceid(char *id, const char *id_template); +int get_free_deviceid(const char *name_template); char *deviceid_from_spec_str(const char *str, char **endp); @@ -294,6 +296,7 @@ void *priv; struct device_d *dev; struct list_head list; + struct list_head devices_list; char *name; unsigned long offset; size_t size; @@ -303,6 +306,8 @@ int devfs_create(struct cdev *); void devfs_remove(struct cdev *); struct cdev *cdev_by_name(const char *filename); +ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags); +ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags); #define DEVFS_PARTITION_FIXED (1 << 0) #define DEVFS_PARTITION_READONLY (1 << 1) diff --git a/include/fs.h b/include/fs.h index e5ecb7d..552c4e9 100644 --- a/include/fs.h +++ b/include/fs.h @@ -88,7 +88,7 @@ }; struct fs_device_d { - struct device_d *parent; /* the device we are associated with */ + char *backingstore; /* the device we are associated with */ struct device_d dev; /* our own device */ struct fs_driver_d *driver; diff --git a/lib/driver.c b/lib/driver.c index f61e2ec..589bd8d 100644 --- a/lib/driver.c +++ b/lib/driver.c @@ -42,42 +42,31 @@ static LIST_HEAD(active); -struct device_d *device_by_name(const char *name) +struct device_d *get_device_by_name(const char *name) { struct device_d *dev; + char devname[MAX_DRIVER_NAME + 3]; for_each_device(dev) { - if(!strcmp(name, dev->name)) + sprintf(devname, "%s%d", dev->name, dev->id); + if(!strcmp(name, devname)) return dev; } return NULL; } -struct device_d *get_device_by_id(const char *id) -{ - struct device_d *dev; - - for_each_device(dev) { - if(!strcmp(id, dev->id)) - return dev; - } - - return NULL; -} - -int get_free_deviceid(char *id, const char *id_template) +int get_free_deviceid(const char *name_template) { int i = 0; + char name[MAX_DRIVER_NAME + 3]; while (1) { - sprintf(id, "%s%d", id_template, i); - if (!get_device_by_id(id)) - return 0; + sprintf(name, "%s%d", name_template, i); + if (!get_device_by_name(name)) + return i; i++; }; - - return -1; } static int match(struct driver_d *drv, struct device_d *dev) @@ -106,10 +95,8 @@ { struct driver_d *drv; - if(*new_device->id && get_device_by_id(new_device->id)) { - printf("device %s already exists\n", new_device->id); - return -EINVAL; - } + new_device->id = get_free_deviceid(new_device->name); + debug ("register_device: %s\n",new_device->name); if (!new_device->bus) { @@ -119,6 +106,7 @@ list_add_tail(&new_device->list, &device_list); INIT_LIST_HEAD(&new_device->children); + INIT_LIST_HEAD(&new_device->cdevs); for_each_driver(drv) { if (!match(drv, new_device)) @@ -175,7 +163,7 @@ static void noinfo(struct device_d *dev) { - printf("no info available for %s\n", dev->id); + printf("no info available for %s\n", dev->name); } static void noshortinfo(struct device_d *dev) @@ -207,28 +195,6 @@ } EXPORT_SYMBOL(register_driver); -/* 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 *get_device_by_path(const char *path) -{ - struct device_d *dev = NULL; - char *npath = normalise_path(path); - - if (strncmp(npath, "/dev/", 5)) - goto out; - - dev = get_device_by_id(npath + 5); - - out: - free(npath); - errno = -ENODEV; - return dev; -} -EXPORT_SYMBOL(get_device_by_path); - int dev_protect(struct device_d *dev, size_t count, unsigned long offset, int prot) { printf("%s: currently broken\n", __func__); @@ -264,13 +230,23 @@ static int do_devinfo_subtree(struct device_d *dev, int depth, char edge) { struct device_d *child; + struct cdev *cdev; int i; for (i = 0; i < depth; i++) printf("| "); - if (*dev->id) - printf("%c----%s\n", edge, dev->id); + printf("%c----%s%d", edge, dev->name, dev->id); + if (!list_empty(&dev->cdevs)) { + printf(" ("); + list_for_each_entry(cdev, &dev->cdevs, devices_list) { + printf("%s", cdev->name); + if (!list_is_last(&cdev->devices_list, &dev->cdevs)) + printf(", "); + } + printf(")"); + } + printf("\n"); if (!list_empty(&dev->children)) { device_for_each_child(dev, child) { @@ -287,10 +263,7 @@ { static char buf[sizeof(unsigned long) * 2]; - if (strlen(dev->id)) - return dev->id; - - sprintf(buf, "0x%08x", dev->map_base); + sprintf(buf, "%s%d", dev->name, dev->id); return buf; } @@ -325,7 +298,7 @@ for_each_driver(drv) printf("%10s\n",drv->name); } else { - struct device_d *dev = get_device_by_path(argv[1]); + struct device_d *dev = get_device_by_name(argv[1]); if (!dev) { printf("no such device: %s\n",argv[1]);