int ubifs_set_blk_dev(struct blk_desc *rbdd, disk_partition_t *info) { if (rbdd) { debug("UBIFS cannot be used with normal block devices\n"); return -1; } /* * Should never happen since blk_get_device_part_str() already checks * this, but better safe then sorry. */ if (!ubifs_is_mounted()) { debug("UBIFS not mounted, use ubifsmount to mount volume first!\n"); return -1; } return 0; }
static int ubi_detach(void) { #ifdef CONFIG_CMD_UBIFS /* * Automatically unmount UBIFS partition when user * changes the UBI device. Otherwise the following * UBIFS commands will crash. */ if (ubifs_is_mounted()) cmd_ubifs_umount(); #endif /* * Call ubi_exit() before re-initializing the UBI subsystem */ if (ubi) ubi_exit(); ubi = NULL; return 0; }
int blk_get_device_part_str(const char *ifname, const char *dev_part_str, struct blk_desc **dev_desc, disk_partition_t *info, int allow_whole_dev) { int ret = -1; const char *part_str; char *dup_str = NULL; const char *dev_str; int dev; char *ep; int p; int part; disk_partition_t tmpinfo; #ifdef CONFIG_SANDBOX /* * Special-case a pseudo block device "hostfs", to allow access to the * host's own filesystem. */ if (0 == strcmp(ifname, "hostfs")) { *dev_desc = NULL; info->start = 0; info->size = 0; info->blksz = 0; info->bootable = 0; strcpy((char *)info->type, BOOT_PART_TYPE); strcpy((char *)info->name, "Sandbox host"); #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif #ifdef CONFIG_PARTITION_TYPE_GUID info->type_guid[0] = 0; #endif return 0; } #endif #ifdef CONFIG_CMD_UBIFS /* * Special-case ubi, ubi goes through a mtd, rathen then through * a regular block device. */ if (0 == strcmp(ifname, "ubi")) { if (!ubifs_is_mounted()) { printf("UBIFS not mounted, use ubifsmount to mount volume first!\n"); return -1; } *dev_desc = NULL; memset(info, 0, sizeof(*info)); strcpy((char *)info->type, BOOT_PART_TYPE); strcpy((char *)info->name, "UBI"); #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif return 0; } #endif /* If no dev_part_str, use bootdevice environment variable */ if (!dev_part_str || !strlen(dev_part_str) || !strcmp(dev_part_str, "-")) dev_part_str = getenv("bootdevice"); /* If still no dev_part_str, it's an error */ if (!dev_part_str) { printf("** No device specified **\n"); goto cleanup; } /* Separate device and partition ID specification */ part_str = strchr(dev_part_str, ':'); if (part_str) { dup_str = strdup(dev_part_str); dup_str[part_str - dev_part_str] = 0; dev_str = dup_str; part_str++; } else { dev_str = dev_part_str; } /* Look up the device */ dev = blk_get_device_by_str(ifname, dev_str, dev_desc); if (dev < 0) goto cleanup; /* Convert partition ID string to number */ if (!part_str || !*part_str) { part = PART_UNSPECIFIED; } else if (!strcmp(part_str, "auto")) { part = PART_AUTO; } else { /* Something specified -> use exactly that */ part = (int)simple_strtoul(part_str, &ep, 16); /* * Less than whole string converted, * or request for whole device, but caller requires partition. */ if (*ep || (part == 0 && !allow_whole_dev)) { printf("** Bad partition specification %s %s **\n", ifname, dev_part_str); goto cleanup; } } /* * No partition table on device, * or user requested partition 0 (entire device). */ if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) || (part == 0)) { if (!(*dev_desc)->lba) { printf("** Bad device size - %s %s **\n", ifname, dev_str); goto cleanup; } /* * If user specified a partition ID other than 0, * or the calling command only accepts partitions, * it's an error. */ if ((part > 0) || (!allow_whole_dev)) { printf("** No partition table - %s %s **\n", ifname, dev_str); goto cleanup; } (*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz); info->start = 0; info->size = (*dev_desc)->lba; info->blksz = (*dev_desc)->blksz; info->bootable = 0; strcpy((char *)info->type, BOOT_PART_TYPE); strcpy((char *)info->name, "Whole Disk"); #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif #ifdef CONFIG_PARTITION_TYPE_GUID info->type_guid[0] = 0; #endif ret = 0; goto cleanup; } /* * Now there's known to be a partition table, * not specifying a partition means to pick partition 1. */ if (part == PART_UNSPECIFIED) part = 1; /* * If user didn't specify a partition number, or did specify something * other than "auto", use that partition number directly. */ if (part != PART_AUTO) { ret = part_get_info(*dev_desc, part, info); if (ret) { printf("** Invalid partition %d **\n", part); goto cleanup; } } else { /* * Find the first bootable partition. * If none are bootable, fall back to the first valid partition. */ part = 0; for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { ret = part_get_info(*dev_desc, p, info); if (ret) continue; /* * First valid partition, or new better partition? * If so, save partition ID. */ if (!part || info->bootable) part = p; /* Best possible partition? Stop searching. */ if (info->bootable) break; /* * We now need to search further for best possible. * If we what we just queried was the best so far, * save the info since we over-write it next loop. */ if (part == p) tmpinfo = *info; } /* If we found any acceptable partition */ if (part) { /* * If we searched all possible partition IDs, * return the first valid partition we found. */ if (p == MAX_SEARCH_PARTITIONS + 1) *info = tmpinfo; } else { printf("** No valid partitions found **\n"); ret = -1; goto cleanup; } } if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { printf("** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info->type); ret = -1; goto cleanup; } (*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz); ret = part; goto cleanup; cleanup: free(dup_str); return ret; }
static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { size_t size = 0; ulong addr = 0; int err = 0; if (argc < 2) return CMD_RET_USAGE; if (mtdparts_init() != 0) { printf("Error initializing mtdparts!\n"); return 1; } if (strcmp(argv[1], "part") == 0) { char mtd_dev[16]; struct mtd_device *dev; struct part_info *part; const char *vid_header_offset = NULL; u8 pnum; /* Print current partition */ if (argc == 2) { if (!ubi_dev.selected) { printf("Error, no UBI device/partition selected!\n"); return 1; } printf("Device %d: %s, partition %s\n", ubi_dev.nr, ubi_dev.mtd_info->name, ubi_dev.part_name); return 0; } if (argc < 3) return CMD_RET_USAGE; #ifdef CONFIG_CMD_UBIFS /* * Automatically unmount UBIFS partition when user * changes the UBI device. Otherwise the following * UBIFS commands will crash. */ if (ubifs_is_mounted()) cmd_ubifs_umount(); #endif /* todo: get dev number for NAND... */ ubi_dev.nr = 0; /* * Call ubi_exit() before re-initializing the UBI subsystem */ if (ubi_initialized) { ubi_exit(); del_mtd_partitions(ubi_dev.mtd_info); } /* * Search the mtd device number where this partition * is located */ if (find_dev_and_part(argv[2], &dev, &pnum, &part)) { printf("Partition %s not found!\n", argv[2]); return 1; } sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(dev->id->type), dev->id->num); ubi_dev.mtd_info = get_mtd_device_nm(mtd_dev); if (IS_ERR(ubi_dev.mtd_info)) { printf("Partition %s not found on device %s!\n", argv[2], mtd_dev); return 1; } ubi_dev.selected = 1; if (argc > 3) vid_header_offset = argv[3]; strcpy(ubi_dev.part_name, argv[2]); err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name, vid_header_offset); if (err) { printf("UBI init error %d\n", err); ubi_dev.selected = 0; return err; } ubi = ubi_devices[0]; return 0; } if ((strcmp(argv[1], "part") != 0) && (!ubi_dev.selected)) { printf("Error, no UBI device/partition selected!\n"); return 1; } if (strcmp(argv[1], "info") == 0) { int layout = 0; if (argc > 2 && !strncmp(argv[2], "l", 1)) layout = 1; return ubi_info(layout); } if (strncmp(argv[1], "create", 6) == 0) { int dynamic = 1; /* default: dynamic volume */ /* Use maximum available size */ size = 0; /* E.g., create volume size type */ if (argc == 5) { if (strncmp(argv[4], "s", 1) == 0) dynamic = 0; else if (strncmp(argv[4], "d", 1) != 0) { printf("Incorrect type\n"); return 1; } argc--; } /* E.g., create volume size */ if (argc == 4) { size = simple_strtoul(argv[3], NULL, 16); argc--; } /* Use maximum available size */ if (!size) { size = ubi->avail_pebs * ubi->leb_size; printf("No size specified -> Using max size (%u)\n", size); } /* E.g., create volume */ if (argc == 3) return ubi_create_vol(argv[2], size, dynamic); } if (strncmp(argv[1], "remove", 6) == 0) { /* E.g., remove volume */ if (argc == 3) return ubi_remove_vol(argv[2]); } if (strncmp(argv[1], "write", 5) == 0) { if (argc < 5) { printf("Please see usage\n"); return 1; } addr = simple_strtoul(argv[2], NULL, 16); size = simple_strtoul(argv[4], NULL, 16); return ubi_volume_write(argv[3], (void *)addr, size); } if (strncmp(argv[1], "read", 4) == 0) { size = 0; /* E.g., read volume size */ if (argc == 5) { size = simple_strtoul(argv[4], NULL, 16); argc--; } /* E.g., read volume */ if (argc == 4) { addr = simple_strtoul(argv[2], NULL, 16); argc--; } if (argc == 3) return ubi_volume_read(argv[3], (char *)addr, size); } printf("Please see usage\n"); return 1; }
int ubi_part(char *part_name, const char *vid_header_offset) { int err = 0; char mtd_dev[16]; struct mtd_device *dev; struct part_info *part; u8 pnum; if (mtdparts_init() != 0) { printf("Error initializing mtdparts!\n"); return 1; } #ifdef CONFIG_CMD_UBIFS /* * Automatically unmount UBIFS partition when user * changes the UBI device. Otherwise the following * UBIFS commands will crash. */ if (ubifs_is_mounted()) cmd_ubifs_umount(); #endif /* todo: get dev number for NAND... */ ubi_dev.nr = 0; /* * Call ubi_exit() before re-initializing the UBI subsystem */ if (ubi_initialized) { ubi_exit(); del_mtd_partitions(ubi_dev.mtd_info); } /* * Search the mtd device number where this partition * is located */ if (find_dev_and_part(part_name, &dev, &pnum, &part)) { printf("Partition %s not found!\n", part_name); return 1; } sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(dev->id->type), dev->id->num); ubi_dev.mtd_info = get_mtd_device_nm(mtd_dev); if (IS_ERR(ubi_dev.mtd_info)) { printf("Partition %s not found on device %s!\n", part_name, mtd_dev); return 1; } ubi_dev.selected = 1; strcpy(ubi_dev.part_name, part_name); err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name, vid_header_offset); if (err) { printf("UBI init error %d\n", err); ubi_dev.selected = 0; return err; } ubi = ubi_devices[0]; return 0; }